diff options
author | Antoine Cellerier <dionoea@videolan.org> | 2006-08-02 22:17:21 +0000 |
---|---|---|
committer | Antoine Cellerier <dionoea@videolan.org> | 2006-08-02 22:17:21 +0000 |
commit | 5e2a9a19cf97129580b5567527824ce89078d3fd (patch) | |
tree | ddef6df574bb6d3d4878eca97a4930d6fb6c03b1 /apps | |
parent | c00c94e1a4f2099aadc2569c1300125396ad5203 (diff) | |
download | rockbox-5e2a9a19cf97129580b5567527824ce89078d3fd.tar.gz rockbox-5e2a9a19cf97129580b5567527824ce89078d3fd.zip |
Cleanup solitaire code a bit. A side effect is that it should now be possible to play on small LCD screens like the recorder's (which had become impossible since revision 1.20).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10422 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/plugins/solitaire.c | 1615 |
1 files changed, 815 insertions, 800 deletions
diff --git a/apps/plugins/solitaire.c b/apps/plugins/solitaire.c index a9a0d5c762..e85872ee2a 100644 --- a/apps/plugins/solitaire.c +++ b/apps/plugins/solitaire.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2004-2006 dionoea (Antoine Cellerier) | 10 | * Copyright (C) 2004-2006 Antoine Cellerier <dionoea @t videolan d.t org> |
11 | * | 11 | * |
12 | * All files in this archive are subject to the GNU General Public License. | 12 | * All files in this archive are subject to the GNU General Public License. |
13 | * See the file COPYING in the source tree root for full license agreement. | 13 | * See the file COPYING in the source tree root for full license agreement. |
@@ -36,253 +36,246 @@ use F3 to put card on top of the remains' stack on one of the 4 final stacks | |||
36 | #include "button.h" | 36 | #include "button.h" |
37 | #include "lcd.h" | 37 | #include "lcd.h" |
38 | 38 | ||
39 | |||
40 | #ifdef HAVE_LCD_BITMAP | 39 | #ifdef HAVE_LCD_BITMAP |
41 | 40 | ||
42 | PLUGIN_HEADER | 41 | PLUGIN_HEADER |
43 | 42 | ||
44 | /* here is a global api struct pointer. while not strictly necessary, | ||
45 | it's nice not to have to pass the api pointer in all function calls | ||
46 | in the plugin */ | ||
47 | static struct plugin_api* rb; | 43 | static struct plugin_api* rb; |
48 | |||
49 | #define min(a,b) (a<b?a:b) | 44 | #define min(a,b) (a<b?a:b) |
50 | 45 | ||
46 | /** | ||
47 | * Key definitions | ||
48 | */ | ||
51 | 49 | ||
52 | /* variable button definitions */ | ||
53 | #if CONFIG_KEYPAD == RECORDER_PAD | ||
54 | #define SOL_QUIT BUTTON_OFF | ||
55 | #define SOL_UP BUTTON_UP | ||
56 | #define SOL_DOWN BUTTON_DOWN | ||
57 | #define SOL_LEFT BUTTON_LEFT | ||
58 | #define SOL_RIGHT BUTTON_RIGHT | ||
59 | #define SOL_MOVE BUTTON_ON | ||
60 | #define SOL_DRAW BUTTON_F2 | ||
61 | #define SOL_REM2CUR BUTTON_PLAY | ||
62 | #define SOL_CUR2STACK BUTTON_F1 | ||
63 | #define SOL_REM2STACK BUTTON_F3 | ||
64 | #define SOL_MENU_RUN BUTTON_RIGHT | ||
65 | #define SOL_MENU_RUN2 BUTTON_PLAY | ||
66 | #define SOL_MENU_INFO BUTTON_F1 | ||
67 | #define SOL_MENU_INFO2 BUTTON_F2 | ||
68 | #define SOL_MENU_INFO3 BUTTON_F3 | ||
69 | |||
70 | #elif CONFIG_KEYPAD == ONDIO_PAD | ||
71 | #define SOL_QUIT BUTTON_OFF | ||
72 | #define SOL_UP_PRE BUTTON_UP | ||
73 | #define SOL_UP (BUTTON_UP | BUTTON_REL) | ||
74 | #define SOL_DOWN_PRE BUTTON_DOWN | ||
75 | #define SOL_DOWN (BUTTON_DOWN | BUTTON_REL) | ||
76 | #define SOL_LEFT_PRE BUTTON_LEFT | ||
77 | #define SOL_LEFT (BUTTON_LEFT | BUTTON_REL) | ||
78 | #define SOL_RIGHT_PRE BUTTON_RIGHT | ||
79 | #define SOL_RIGHT (BUTTON_RIGHT | BUTTON_REL) | ||
80 | #define SOL_MOVE_PRE BUTTON_MENU | ||
81 | #define SOL_MOVE (BUTTON_MENU | BUTTON_REL) | ||
82 | #define SOL_DRAW_PRE BUTTON_MENU | ||
83 | #define SOL_DRAW (BUTTON_MENU | BUTTON_REPEAT) | ||
84 | #define SOL_REM2CUR_PRE BUTTON_LEFT | ||
85 | #define SOL_REM2CUR (BUTTON_LEFT | BUTTON_REPEAT) | ||
86 | #define SOL_CUR2STACK_PRE BUTTON_RIGHT | ||
87 | #define SOL_CUR2STACK (BUTTON_RIGHT | BUTTON_REPEAT) | ||
88 | #define SOL_REM2STACK_PRE BUTTON_UP | ||
89 | #define SOL_REM2STACK (BUTTON_UP | BUTTON_REPEAT) | ||
90 | #define SOL_MENU_RUN BUTTON_RIGHT | ||
91 | #define SOL_MENU_INFO BUTTON_MENU | ||
92 | |||
93 | #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ | ||
94 | (CONFIG_KEYPAD == IRIVER_H300_PAD) | ||
95 | #define SOL_QUIT BUTTON_OFF | ||
96 | #define SOL_UP BUTTON_UP | ||
97 | #define SOL_DOWN BUTTON_DOWN | ||
98 | #define SOL_LEFT BUTTON_LEFT | ||
99 | #define SOL_RIGHT BUTTON_RIGHT | ||
100 | #define SOL_MOVE_PRE BUTTON_SELECT | ||
101 | #define SOL_MOVE (BUTTON_SELECT | BUTTON_REL) | ||
102 | #define SOL_DRAW BUTTON_MODE | ||
103 | #define SOL_REM2CUR (BUTTON_LEFT | BUTTON_ON) | ||
104 | #define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_REPEAT) | ||
105 | #define SOL_REM2STACK (BUTTON_RIGHT | BUTTON_ON) | ||
106 | #define SOL_MENU_RUN BUTTON_SELECT | ||
107 | #define SOL_MENU_RUN2 BUTTON_RIGHT | ||
108 | #define SOL_MENU_INFO BUTTON_MODE | ||
109 | #define SOL_OPT BUTTON_ON | ||
110 | #define SOL_REM BUTTON_REC | ||
111 | |||
112 | #define SOL_RC_QUIT BUTTON_RC_STOP | ||
113 | |||
114 | #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ | ||
115 | (CONFIG_KEYPAD == IPOD_3G_PAD) | ||
116 | #define SOL_QUIT (BUTTON_SELECT | BUTTON_MENU) | ||
117 | #define SOL_UP BUTTON_MENU | ||
118 | #define SOL_DOWN BUTTON_PLAY | ||
119 | #define SOL_LEFT BUTTON_LEFT | ||
120 | #define SOL_RIGHT BUTTON_RIGHT | ||
121 | #define SOL_MOVE BUTTON_SELECT | ||
122 | #define SOL_DRAW (BUTTON_SELECT | BUTTON_PLAY) | ||
123 | #define SOL_REM2CUR (BUTTON_SELECT | BUTTON_LEFT) | ||
124 | #define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_RIGHT) | ||
125 | #define SOL_REM2STACK (BUTTON_LEFT | BUTTON_RIGHT) | ||
126 | #define SOL_MENU_RUN BUTTON_SELECT | ||
127 | #define SOL_MENU_INFO (BUTTON_PLAY | BUTTON_MENU) | ||
128 | |||
129 | #elif (CONFIG_KEYPAD == IAUDIO_X5_PAD) | ||
130 | #define SOL_QUIT BUTTON_POWER | ||
131 | #define SOL_UP BUTTON_UP | ||
132 | #define SOL_DOWN BUTTON_DOWN | ||
133 | #define SOL_LEFT BUTTON_LEFT | ||
134 | #define SOL_RIGHT BUTTON_RIGHT | ||
135 | #define SOL_MOVE BUTTON_SELECT | ||
136 | #define SOL_DRAW BUTTON_PLAY | ||
137 | #define SOL_REM2CUR (BUTTON_REC | BUTTON_LEFT) | ||
138 | #define SOL_CUR2STACK (BUTTON_REC | BUTTON_UP) | ||
139 | #define SOL_REM2STACK (BUTTON_REC | BUTTON_DOWN) | ||
140 | #define SOL_MENU_RUN BUTTON_SELECT | ||
141 | #define SOL_MENU_INFO BUTTON_PLAY | ||
142 | |||
143 | #elif (CONFIG_KEYPAD == GIGABEAT_PAD) | ||
144 | #define SOL_QUIT BUTTON_A | ||
145 | #define SOL_UP BUTTON_UP | ||
146 | #define SOL_DOWN BUTTON_DOWN | ||
147 | #define SOL_LEFT BUTTON_LEFT | ||
148 | #define SOL_RIGHT BUTTON_RIGHT | ||
149 | #define SOL_MOVE_PRE BUTTON_SELECT | ||
150 | #define SOL_MOVE (BUTTON_SELECT | BUTTON_REL) | ||
151 | #define SOL_DRAW BUTTON_MENU | ||
152 | #define SOL_REM2CUR (BUTTON_LEFT | BUTTON_POWER) | ||
153 | #define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_REPEAT) | ||
154 | #define SOL_REM2STACK (BUTTON_RIGHT | BUTTON_POWER) | ||
155 | #define SOL_MENU_RUN BUTTON_SELECT | ||
156 | #define SOL_MENU_RUN2 BUTTON_RIGHT | ||
157 | #define SOL_MENU_INFO BUTTON_MENU | ||
158 | #endif | ||
159 | |||
160 | /* common help definitions */ | ||
161 | #define HELP_SOL_UP "UP: Move the cursor up in the column." | ||
162 | #define HELP_SOL_DOWN "DOWN: Move the cursor down in the column." | ||
163 | #define HELP_SOL_LEFT "LEFT: Move the cursor to the previous column." | ||
164 | #define HELP_SOL_RIGHT "RIGHT: Move the cursor to the next column." | ||
165 | |||
166 | /* variable help definitions */ | ||
167 | #if CONFIG_KEYPAD == RECORDER_PAD | 50 | #if CONFIG_KEYPAD == RECORDER_PAD |
168 | #define HELP_SOL_MOVE "ON: Select cards, Move cards, reveal hidden cards ..." | 51 | # define SOL_QUIT BUTTON_OFF |
169 | #define HELP_SOL_DRAW "F2: Un-select a card if it was selected. Else, draw 3 new cards out of the remains' stack." | 52 | # define SOL_UP BUTTON_UP |
170 | #define HELP_SOL_REM2CUR "PLAY: Put the card on top of the remains' stack on top of the cursor." | 53 | # define SOL_DOWN BUTTON_DOWN |
171 | #define HELP_SOL_CUR2STACK "F1: Put the card under the cursor on one of the 4 final stacks." | 54 | # define SOL_LEFT BUTTON_LEFT |
172 | #define HELP_SOL_REM2STACK "F3: Put the card on top of the remains' stack on one of the 4 final stacks." | 55 | # define SOL_RIGHT BUTTON_RIGHT |
56 | # define SOL_MOVE BUTTON_ON | ||
57 | # define SOL_DRAW BUTTON_F2 | ||
58 | # define SOL_REM2CUR BUTTON_PLAY | ||
59 | # define SOL_CUR2STACK BUTTON_F1 | ||
60 | # define SOL_REM2STACK BUTTON_F3 | ||
61 | # define SOL_MENU_RUN BUTTON_RIGHT | ||
62 | # define SOL_MENU_RUN2 BUTTON_PLAY | ||
63 | # define HK_MOVE "ON" | ||
64 | # define HK_DRAW "F2" | ||
65 | # define HK_REM2CUR "PLAY" | ||
66 | # define HK_CUR2STACK "F1" | ||
67 | # define HK_REM2STACK "F3" | ||
173 | 68 | ||
174 | #elif CONFIG_KEYPAD == ONDIO_PAD | 69 | #elif CONFIG_KEYPAD == ONDIO_PAD |
175 | #define HELP_SOL_MOVE "MODE: Select cards, Move cards, reveal hidden cards ..." | 70 | # define SOL_QUIT BUTTON_OFF |
176 | #define HELP_SOL_DRAW "MODE..: Un-select a card if it was selected. Else, draw 3 new cards out of the remains' stack." | 71 | # define SOL_UP_PRE BUTTON_UP |
177 | #define HELP_SOL_REM2CUR "LEFT..: Put the card on top of the remains' stack on top of the cursor." | 72 | # define SOL_UP (BUTTON_UP | BUTTON_REL) |
178 | #define HELP_SOL_CUR2STACK "RIGHT..: Put the card under the cursor on one of the 4 final stacks." | 73 | # define SOL_DOWN_PRE BUTTON_DOWN |
179 | #define HELP_SOL_REM2STACK "UP..: Put the card on top of the remains' stack on one of the 4 final stacks." | 74 | # define SOL_DOWN (BUTTON_DOWN | BUTTON_REL) |
75 | # define SOL_LEFT_PRE BUTTON_LEFT | ||
76 | # define SOL_LEFT (BUTTON_LEFT | BUTTON_REL) | ||
77 | # define SOL_RIGHT_PRE BUTTON_RIGHT | ||
78 | # define SOL_RIGHT (BUTTON_RIGHT | BUTTON_REL) | ||
79 | # define SOL_MOVE_PRE BUTTON_MENU | ||
80 | # define SOL_MOVE (BUTTON_MENU | BUTTON_REL) | ||
81 | # define SOL_DRAW_PRE BUTTON_MENU | ||
82 | # define SOL_DRAW (BUTTON_MENU | BUTTON_REPEAT) | ||
83 | # define SOL_REM2CUR_PRE BUTTON_LEFT | ||
84 | # define SOL_REM2CUR (BUTTON_LEFT | BUTTON_REPEAT) | ||
85 | # define SOL_CUR2STACK_PRE BUTTON_RIGHT | ||
86 | # define SOL_CUR2STACK (BUTTON_RIGHT | BUTTON_REPEAT) | ||
87 | # define SOL_REM2STACK_PRE BUTTON_UP | ||
88 | # define SOL_REM2STACK (BUTTON_UP | BUTTON_REPEAT) | ||
89 | # define SOL_MENU_RUN BUTTON_RIGHT | ||
90 | # define HK_MOVE "MODE" | ||
91 | # define HK_DRAW "MODE.." | ||
92 | # define HK_REM2CUR "LEFT.." | ||
93 | # define HK_CUR2STACK "RIGHT.." | ||
94 | # define HK_REM2STACK "UP.." | ||
180 | 95 | ||
181 | #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ | 96 | #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ |
182 | (CONFIG_KEYPAD == IRIVER_H300_PAD) | 97 | (CONFIG_KEYPAD == IRIVER_H300_PAD) |
183 | #define HELP_SOL_MOVE "SELECT: Select cards, Move cards, reveal hidden cards ..." | 98 | # define SOL_QUIT BUTTON_OFF |
184 | #define HELP_SOL_DRAW "REC: Un-select a card if it was selected. Else, draw 3 new cards out of the remains' stack." | 99 | # define SOL_UP BUTTON_UP |
185 | #define HELP_SOL_REM2CUR "PLAY+LEFT: Put the card on top of the remains' stack on top of the cursor." | 100 | # define SOL_DOWN BUTTON_DOWN |
186 | #define HELP_SOL_CUR2STACK "SELECT..: Put the card under the cursor on one of the 4 final stacks." | 101 | # define SOL_LEFT BUTTON_LEFT |
187 | #define HELP_SOL_REM2STACK "PLAY+RIGHT: Put the card on top of the remains' stack on one of the 4 final stacks." | 102 | # define SOL_RIGHT BUTTON_RIGHT |
103 | # define SOL_MOVE_PRE BUTTON_SELECT | ||
104 | # define SOL_MOVE (BUTTON_SELECT | BUTTON_REL) | ||
105 | # define SOL_DRAW BUTTON_MODE | ||
106 | # define SOL_REM2CUR (BUTTON_LEFT | BUTTON_ON) | ||
107 | # define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_REPEAT) | ||
108 | # define SOL_REM2STACK (BUTTON_RIGHT | BUTTON_ON) | ||
109 | # define SOL_MENU_RUN BUTTON_SELECT | ||
110 | # define SOL_MENU_RUN2 BUTTON_RIGHT | ||
111 | # define SOL_OPT BUTTON_ON | ||
112 | # define SOL_REM BUTTON_REC | ||
113 | # define SOL_RC_QUIT BUTTON_RC_STOP | ||
114 | # define HK_MOVE "SELECT" | ||
115 | # define HK_DRAW "REC" | ||
116 | # define HK_REM2CUR "PLAY+LEFT" | ||
117 | # define HK_CUR2STACK "SELECT" | ||
118 | # define HK_REM2STACK "PLAY+RIGHT" | ||
188 | 119 | ||
189 | #elif (CONFIG_KEYPAD == IPOD_4G_PAD) ||(CONFIG_KEYPAD == IPOD_3G_PAD) | 120 | #elif (CONFIG_KEYPAD == IPOD_4G_PAD) ||(CONFIG_KEYPAD == IPOD_3G_PAD) |
190 | #define HELP_SOL_MOVE "SELECT: Select cards, Move cards, reveal hidden cards ..." | 121 | # define SOL_QUIT (BUTTON_SELECT | BUTTON_MENU) |
191 | #define HELP_SOL_DRAW "SELECT+PLAY: Un-select a card if it was selected. Else, draw 3 new cards out of the remains' stack." | 122 | # define SOL_UP BUTTON_MENU |
192 | #define HELP_SOL_REM2CUR "SELECT+LEFT: Put the card on top of the remains' stack on top of the cursor." | 123 | # define SOL_DOWN BUTTON_PLAY |
193 | #define HELP_SOL_CUR2STACK "SELECT+RIGHT..: Put the card under the cursor on one of the 4 final stacks." | 124 | # define SOL_LEFT BUTTON_LEFT |
194 | #define HELP_SOL_REM2STACK "LEFT+RIGHT: Put the card on top of the remains' stack on one of the 4 final stacks." | 125 | # define SOL_RIGHT BUTTON_RIGHT |
126 | # define SOL_MOVE BUTTON_SELECT | ||
127 | # define SOL_DRAW (BUTTON_SELECT | BUTTON_PLAY) | ||
128 | # define SOL_REM2CUR (BUTTON_SELECT | BUTTON_LEFT) | ||
129 | # define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_RIGHT) | ||
130 | # define SOL_REM2STACK (BUTTON_LEFT | BUTTON_RIGHT) | ||
131 | # define SOL_MENU_RUN BUTTON_SELECT | ||
132 | # define HK_MOVE "SELECT" | ||
133 | # define HK_DRAW "SELECT+PLAY" | ||
134 | # define HK_REM2CUR "SELECT+LEFT" | ||
135 | # define HK_CUR2STACK "SELECT+RIGHT.." | ||
136 | # define HK_REM2STACK "LEFT+RIGHT" | ||
195 | 137 | ||
196 | #elif (CONFIG_KEYPAD == IAUDIO_X5_PAD) | 138 | #elif (CONFIG_KEYPAD == IAUDIO_X5_PAD) |
197 | #define HELP_SOL_MOVE "MENU: Select cards, Move cards, reveal hidden cards ..." | 139 | # define SOL_QUIT BUTTON_POWER |
198 | #define HELP_SOL_DRAW "PLAY: Un-select a card if it was selected. Else, draw 3 new cards out of the remains' stack." | 140 | # define SOL_UP BUTTON_UP |
199 | #define HELP_SOL_REM2CUR "REC+LEFT: Put the card on top of the remains' stack on top of the cursor." | 141 | # define SOL_DOWN BUTTON_DOWN |
200 | #define HELP_SOL_CUR2STACK "REC+UP..: Put the card under the cursor on one of the 4 final stacks." | 142 | # define SOL_LEFT BUTTON_LEFT |
201 | #define HELP_SOL_REM2STACK "REC+DOWN: Put the card on top of the remains' stack on one of the 4 final stacks." | 143 | # define SOL_RIGHT BUTTON_RIGHT |
144 | # define SOL_MOVE BUTTON_SELECT | ||
145 | # define SOL_DRAW BUTTON_PLAY | ||
146 | # define SOL_REM2CUR (BUTTON_REC | BUTTON_LEFT) | ||
147 | # define SOL_CUR2STACK (BUTTON_REC | BUTTON_UP) | ||
148 | # define SOL_REM2STACK (BUTTON_REC | BUTTON_DOWN) | ||
149 | # define SOL_MENU_RUN BUTTON_SELECT | ||
150 | # define HK_MOVE "MENU" | ||
151 | # define HK_DRAW "PLAY" | ||
152 | # define HK_REM2CUR "REC+LEFT" | ||
153 | # define HK_CUR2STACK "REC+UP.." | ||
154 | # define HK_REM2STACK "REC+DOWN" | ||
202 | 155 | ||
203 | #elif (CONFIG_KEYPAD == GIGABEAT_PAD) | 156 | #elif (CONFIG_KEYPAD == GIGABEAT_PAD) |
204 | #define HELP_SOL_MOVE "SELECT: Select cards, Move cards, reveal hidden cards ..." | 157 | # define SOL_QUIT BUTTON_A |
205 | #define HELP_SOL_DRAW "MENU: Un-select a card if it was selected. Else, draw 3 new cards out of the remains' stack." | 158 | # define SOL_UP BUTTON_UP |
206 | #define HELP_SOL_REM2CUR "POWER+LEFT: Put the card on top of the remains' stack on top of the cursor." | 159 | # define SOL_DOWN BUTTON_DOWN |
207 | #define HELP_SOL_CUR2STACK "SELECT..: Put the card under the cursor on one of the 4 final stacks." | 160 | # define SOL_LEFT BUTTON_LEFT |
208 | #define HELP_SOL_REM2STACK "POWER+RIGHT: Put the card on top of the remains' stack on one of the 4 final stacks." | 161 | # define SOL_RIGHT BUTTON_RIGHT |
162 | # define SOL_MOVE_PRE BUTTON_SELECT | ||
163 | # define SOL_MOVE (BUTTON_SELECT | BUTTON_REL) | ||
164 | # define SOL_DRAW BUTTON_MENU | ||
165 | # define SOL_REM2CUR (BUTTON_LEFT | BUTTON_POWER) | ||
166 | # define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_REPEAT) | ||
167 | # define SOL_REM2STACK (BUTTON_RIGHT | BUTTON_POWER) | ||
168 | # define SOL_MENU_RUN BUTTON_SELECT | ||
169 | # define SOL_MENU_RUN2 BUTTON_RIGHT | ||
170 | # define HK_MOVE "SELECT" | ||
171 | # define HK_DRAW "MENU" | ||
172 | # define HK_REM2CUR "POWER+LEFT" | ||
173 | # define HK_CUR2STACK "SELECT.." | ||
174 | # define HK_REM2STACK "POWER+RIGHT" | ||
209 | 175 | ||
210 | #endif | ||
211 | |||
212 | #if LCD_DEPTH>1 | ||
213 | static const unsigned colors[4] = { | ||
214 | #ifdef HAVE_LCD_COLOR | ||
215 | LCD_BLACK, LCD_RGBPACK(255, 0, 0), LCD_BLACK, LCD_RGBPACK(255, 0, 0) | ||
216 | #else | 176 | #else |
217 | LCD_BLACK, LCD_BRIGHTNESS(127), LCD_BLACK, LCD_BRIGHTNESS(127) | 177 | # error "Unknown keypad" |
218 | #endif | ||
219 | }; | ||
220 | #endif | 178 | #endif |
221 | 179 | ||
222 | #define BMPHEIGHT_c 10 | 180 | /** |
223 | #define BMPWIDTH_c 8 | 181 | * Help strings |
182 | */ | ||
183 | |||
184 | #define HELP_SOL_UP "UP: Move the cursor up in the column." | ||
185 | #define HELP_SOL_DOWN "DOWN: Move the cursor down in the column." | ||
186 | #define HELP_SOL_LEFT "LEFT: Move the cursor to the previous column." | ||
187 | #define HELP_SOL_RIGHT "RIGHT: Move the cursor to the next column." | ||
188 | #define HELP_SOL_MOVE HK_MOVE \ | ||
189 | ": Select cards, Move cards, reveal hidden cards ..." | ||
190 | #define HELP_SOL_DRAW HK_DRAW \ | ||
191 | ": Un-select a card if it was selected. " \ | ||
192 | "Else, draw 3 new cards out of the remains' stack." | ||
193 | #define HELP_SOL_REM2CUR HK_REM2CUR \ | ||
194 | ": Put the card on top of the remains' stack on top of the cursor." | ||
195 | #define HELP_SOL_CUR2STACK HK_CUR2STACK \ | ||
196 | ": Put the card under the cursor on one of the 4 final stacks." | ||
197 | #define HELP_SOL_REM2STACK HK_REM2STACK \ | ||
198 | ": Put the card on top of the remains' stack on one of the 4 final stacks." | ||
199 | |||
200 | /** | ||
201 | * Misc constants, graphics and other defines | ||
202 | */ | ||
224 | 203 | ||
225 | #ifdef HAVE_LCD_COLOR | 204 | /* size of a card on the screen */ |
226 | #if (LCD_WIDTH >= 220) && (LCD_HEIGHT >= 176) | 205 | #if (LCD_WIDTH >= 220) && (LCD_HEIGHT >= 176) |
227 | #define BMPHEIGHT_CARDBACK 33 | 206 | # define CARD_WIDTH 27 |
228 | #define BMPWIDTH_CARDBACK 26 | 207 | # define CARD_HEIGHT 34 |
208 | #elif LCD_HEIGHT > 64 | ||
209 | # define CARD_WIDTH 19 | ||
210 | # define CARD_HEIGHT 24 | ||
229 | #else | 211 | #else |
230 | #define BMPHEIGHT_CARDBACK 24 | 212 | # define CARD_WIDTH 14 |
231 | #define BMPWIDTH_CARDBACK 18 | 213 | # define CARD_HEIGHT 10 |
232 | #endif | 214 | #endif |
233 | 215 | ||
234 | extern const fb_data solitaire_cardback[]; | 216 | /* where the cards start */ |
217 | #define CARD_START ( CARD_HEIGHT + 4 ) | ||
218 | |||
219 | #if LCD_HEIGHT > 64 | ||
220 | # define NUMBER_HEIGHT 10 | ||
221 | # define NUMBER_WIDTH 8 | ||
222 | # define NUMBER_STRIDE 8 | ||
223 | # define SUIT_HEIGHT 10 | ||
224 | # define SUIT_WIDTH 8 | ||
225 | # define SUIT_STRIDE 8 | ||
226 | #else | ||
227 | # define NUMBER_HEIGHT 6 | ||
228 | # define NUMBER_WIDTH 6 | ||
229 | # define NUMBER_STRIDE 6 | ||
230 | # define SUIT_HEIGHT 6 | ||
231 | # define SUIT_WIDTH 6 | ||
232 | # define SUIT_STRIDE 6 | ||
235 | #endif | 233 | #endif |
236 | 234 | ||
237 | static const unsigned char suitsi[4][30] = { | 235 | #define SUITI_HEIGHT 16 |
238 | {0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x07, 0x0f, 0x1f, 0x1f, 0x0f, 0x7f, 0x7f, 0x7f, 0x0f, 0x1f, 0x1f, 0x0f, 0x07, 0x00}, | 236 | #define SUITI_WIDTH 15 |
239 | {0x00, 0xf0, 0xf8, 0xfc, 0xfe, 0xfc, 0xf8, 0xf0, 0xf8, 0xfc, 0xfe, 0xfc, 0xf8, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00, 0x00}, | 237 | #define SUITI_STRIDE 16 |
240 | {0x00, 0xc0, 0xe0, 0xe0, 0xfc, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfc, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x03, 0x07, 0x07, 0x0f, 0x0f, 0x7f, 0x7f, 0x7f, 0x0f, 0x0f, 0x07, 0x07, 0x03, 0x00}, | 238 | |
241 | {0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0xf8, 0xfe, 0xfe, 0xf8, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x1f, 0x7f, 0x7f, 0x1f, 0x07, 0x01, 0x00, 0x00, 0x00}, | 239 | |
242 | }; | 240 | #define draw_number( num, x, y ) \ |
243 | static const unsigned char suits[4][16] = { | 241 | rb->lcd_bitmap_part( numbers, 0, num * NUMBER_HEIGHT, NUMBER_STRIDE, \ |
244 | /* Spades */ | 242 | x, y, NUMBER_WIDTH, NUMBER_HEIGHT ); |
245 | {0x00, 0x78, 0x3c, 0xfe, 0xfe, 0x3c, 0x78, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00},/* ........ */ | 243 | extern const fb_data solitaire_numbers[]; |
246 | /* Hearts */ | 244 | #define numbers solitaire_numbers |
247 | {0x00, 0x3c, 0x7e, 0xfc, 0xf8, 0xfc, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00},/* ........ */ | 245 | |
248 | /* Clubs */ | 246 | #define draw_suit( num, x, y ) \ |
249 | {0x00, 0x70, 0x34, 0xfe, 0xfe, 0x34, 0x70, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00},/* ........ */ | 247 | rb->lcd_bitmap_part( suits, 0, num * SUIT_HEIGHT, SUIT_STRIDE, \ |
250 | /* Diamonds */ | 248 | x, y, SUIT_WIDTH, SUIT_HEIGHT ); |
251 | {0x00, 0x70, 0xfc, 0xfe, 0xfe, 0xfc, 0x70, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00} /* ........ */ | 249 | extern const fb_data solitaire_suits[]; |
252 | }; | 250 | #define suits solitaire_suits |
253 | 251 | ||
254 | static unsigned char numbers[13][16] = { | 252 | #if ( CARD_HEIGHT < SUITI_HEIGHT + 1 ) || ( CARD_WIDTH < SUITI_WIDTH + 1 ) |
255 | /* Ace */ | 253 | # undef SUITI_HEIGHT |
256 | {0x00, 0xf0, 0xfc, 0x7e, 0x36, 0x7e, 0xfc, 0xf0, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01}, | 254 | # undef SUITI_WIDTH |
257 | /* 2 */ | 255 | # define SUITI_HEIGHT SUIT_HEIGHT |
258 | {0x00, 0x8c, 0xce, 0xe6, 0xf6, 0xbe, 0x9c, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00}, /* ........ */ | 256 | # define SUITI_WIDTH SUIT_WIDTH |
259 | /* 3 */ | 257 | # define draw_suiti( num, x, y ) draw_suit( num, x, y ) |
260 | {0x00, 0xcc, 0x86, 0xb6, 0xb6, 0xfe, 0xdc, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}, /* ........ */ | 258 | #else |
261 | /* 4 */ | 259 | # define draw_suiti( num, x, y ) \ |
262 | {0x00, 0x3e, 0x3e, 0x30, 0xfe, 0xfe, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00}, /* ........ */ | 260 | rb->lcd_bitmap_part( suitsi, 0, num * SUITI_HEIGHT, SUITI_STRIDE, \ |
263 | /* 5 */ | 261 | x, y, SUITI_WIDTH, SUITI_HEIGHT ); |
264 | {0x00, 0xbe, 0xbe, 0xb6, 0xb6, 0xf6, 0xe6, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}, /* ........ */ | 262 | extern const fb_data solitaire_suitsi[]; |
265 | /* 6 */ | 263 | # define suitsi solitaire_suitsi |
266 | {0x00, 0xfc, 0xfe, 0xb6, 0xb6, 0xf6, 0xe4, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}, /* ........ */ | 264 | #endif |
267 | /* 7 */ | ||
268 | {0x00, 0x86, 0xc6, 0x66, 0x36, 0x1e, 0x0e, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ........ */ | ||
269 | /* 8 */ | ||
270 | {0x00, 0xdc, 0xfe, 0xb6, 0xb6, 0xfe, 0xdc, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}, /* ........ */ | ||
271 | /* 9 */ | ||
272 | {0x00, 0x9c, 0xbe, 0xb6, 0xb6, 0xfe, 0xfc, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}, /* ........ */ | ||
273 | /* 10 */ | ||
274 | {0x00, 0x18, 0x0c, 0xfe, 0x00, 0xfc, 0x86, 0xfc, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00}, /* ........ */ | ||
275 | /* Jack */ | ||
276 | {0x00, 0xe6, 0xc6, 0x86, 0xfe, 0xfe, 0x06, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00}, /* ........ */ | ||
277 | /* Queen */ | ||
278 | {0x00, 0x7c, 0xfe, 0xc6, 0xe6, 0xfe, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00}, /* ........ */ | ||
279 | /* King */ | ||
280 | {0x00, 0xfe, 0xfe, 0x38, 0x7c, 0xee, 0xc6, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00} /* ........ */ | ||
281 | }; | ||
282 | |||
283 | 265 | ||
284 | #define FILENAME "sol.cfg" | 266 | #ifdef HAVE_LCD_COLOR |
267 | # if (LCD_WIDTH >= 220) && (LCD_HEIGHT >= 176) | ||
268 | # define CARDBACK_HEIGHT 33 | ||
269 | # define CARDBACK_WIDTH 26 | ||
270 | # else | ||
271 | # define CARDBACK_HEIGHT 24 | ||
272 | # define CARDBACK_WIDTH 18 | ||
273 | # endif | ||
274 | |||
275 | extern const fb_data solitaire_cardback[]; | ||
276 | #endif | ||
285 | 277 | ||
278 | #define CONFIG_FILENAME "sol.cfg" | ||
286 | 279 | ||
287 | #define NOT_A_CARD 255 | 280 | #define NOT_A_CARD 255 |
288 | 281 | ||
@@ -292,76 +285,155 @@ static unsigned char numbers[13][16] = { | |||
292 | /* number of suits */ | 285 | /* number of suits */ |
293 | #define SUITS 4 | 286 | #define SUITS 4 |
294 | 287 | ||
288 | #define NUM_CARDS ( CARDS_PER_SUIT * SUITS ) | ||
289 | |||
295 | /* number of columns */ | 290 | /* number of columns */ |
296 | #define COL_NUM 7 | 291 | #define COL_NUM 7 |
297 | 292 | ||
298 | /* pseudo column numbers to be used for cursor coordinates */ | 293 | /* pseudo column numbers to be used for cursor coordinates */ |
299 | /* columns COL_NUM t COL_NUM + SUITS - 1 correspond to the final stacks */ | 294 | /* columns COL_NUM to COL_NUM + SUITS - 1 correspond to the final stacks */ |
300 | #define STACKS_COL COL_NUM | 295 | #define STACKS_COL COL_NUM |
301 | /* column COL_NUM + SUITS corresponds to the remains' stack */ | 296 | /* column COL_NUM + SUITS corresponds to the remains' stack */ |
302 | #define REM_COL (STACKS_COL + SUITS) | 297 | #define REM_COL (STACKS_COL + SUITS) |
303 | 298 | ||
304 | #define NOT_A_COL 255 | 299 | #define NOT_A_COL 255 |
305 | 300 | ||
301 | /* background color */ | ||
302 | #define BACKGROUND_COLOR LCD_RGBPACK(0,157,0) | ||
306 | 303 | ||
307 | /* size of a card on the screen */ | 304 | #if LCD_DEPTH > 1 && !defined( LCD_WHITE ) |
308 | #if (LCD_WIDTH >= 220) && (LCD_HEIGHT >= 176) | 305 | # define LCD_WHITE LCD_DEFAULT_BG |
309 | #define CARD_WIDTH 26 | ||
310 | #define CARD_HEIGHT 34 | ||
311 | #else | ||
312 | #define CARD_WIDTH 18 | ||
313 | #define CARD_HEIGHT 24 | ||
314 | #endif | ||
315 | |||
316 | /* where the cards start */ | ||
317 | #define CARD_START CARD_HEIGHT +4 | ||
318 | |||
319 | #if (LCD_WIDTH >= 220) && (LCD_HEIGHT >= 176) | ||
320 | #define KNOWN_CARD 23 | ||
321 | #define NOT_KNOWN_CARD 30 | ||
322 | #else | ||
323 | #define KNOWN_CARD 13 | ||
324 | #define NOT_KNOWN_CARD 20 | ||
325 | #endif | 306 | #endif |
326 | 307 | ||
327 | /* background color */ | 308 | typedef struct |
328 | #define background_color LCD_RGBPACK(0,157,0) | 309 | { |
329 | |||
330 | typedef struct card { | ||
331 | unsigned char suit : 2; | 310 | unsigned char suit : 2; |
332 | unsigned char num : 4; | 311 | unsigned char num : 4; |
333 | unsigned char known : 1; | 312 | unsigned char known : 1; |
334 | unsigned char used : 1;/* this is what is used when dealing cards */ | 313 | unsigned char used : 1;/* this is what is used when dealing cards */ |
335 | unsigned char next; | 314 | unsigned char next; |
336 | } card; | 315 | } card_t; |
337 | 316 | ||
338 | unsigned char next_random_card(card *deck){ | ||
339 | unsigned char i,r; | ||
340 | 317 | ||
341 | r = rb->rand()%(SUITS * CARDS_PER_SUIT)+1; | 318 | /** |
342 | i = 0; | 319 | * LCD card drawing routines |
320 | */ | ||
321 | |||
322 | static void draw_cursor( int x, int y ) | ||
323 | { | ||
324 | rb->lcd_set_drawmode( DRMODE_COMPLEMENT ); | ||
325 | rb->lcd_fillrect( x+1, y+1, CARD_WIDTH-1, CARD_HEIGHT-1 ); | ||
326 | rb->lcd_set_drawmode( DRMODE_SOLID ); | ||
327 | } | ||
343 | 328 | ||
344 | while(r>0){ | 329 | /* Draw a card's border, select it if it's selected and draw the cursor |
345 | i = (i + 1)%(SUITS * CARDS_PER_SUIT); | 330 | * is the cursor is currently over the card */ |
346 | if(!deck[i].used) r--; | 331 | static void draw_card_ext( int x, int y, bool selected, bool cursor ) |
332 | { | ||
333 | #if LCD_DEPTH > 1 | ||
334 | rb->lcd_set_foreground( LCD_BLACK ); | ||
335 | #endif | ||
336 | /* draw a rectangle omiting the corner pixels, which is why we don't | ||
337 | * use drawrect */ | ||
338 | rb->lcd_drawline( x+1, y, x+CARD_WIDTH-1, y ); | ||
339 | rb->lcd_drawline( x+1, y+CARD_HEIGHT, x+CARD_WIDTH-1, y+CARD_HEIGHT ); | ||
340 | rb->lcd_drawline( x, y+1, x, y+CARD_HEIGHT-1 ); | ||
341 | rb->lcd_drawline( x+CARD_WIDTH, y+1, x+CARD_WIDTH, y+CARD_HEIGHT-1 ); | ||
342 | |||
343 | if( selected ) | ||
344 | { | ||
345 | rb->lcd_drawrect( x+1, y+1, CARD_WIDTH-1, CARD_HEIGHT-1 ); | ||
347 | } | 346 | } |
347 | if( cursor ) | ||
348 | { | ||
349 | draw_cursor( x, y ); | ||
350 | } | ||
351 | } | ||
348 | 352 | ||
349 | deck[i].used = 1; | 353 | /* Draw a card's inner graphics */ |
354 | static void draw_card( card_t card, int x, int y, | ||
355 | bool selected, bool cursor, bool leftstyle ) | ||
356 | { | ||
357 | #ifndef HAVE_LCD_COLOR | ||
358 | /* On Black&White or Greyscale LCDs we don't have a card back. | ||
359 | * We thus need to clear the card area even if the card isn't | ||
360 | * known. */ | ||
361 | #if LCD_DEPTH > 1 | ||
362 | rb->lcd_set_foreground( LCD_WHITE ); | ||
363 | #else | ||
364 | rb->lcd_set_drawmode( DRMODE_SOLID|DRMODE_INVERSEVID ); | ||
365 | #endif | ||
366 | rb->lcd_fillrect( x+1, y+1, CARD_WIDTH-1, CARD_HEIGHT-1 ); | ||
367 | #if LCD_DEPTH == 1 | ||
368 | rb->lcd_set_drawmode( DRMODE_SOLID ); | ||
369 | #endif | ||
370 | #endif | ||
371 | if( card.known ) | ||
372 | { | ||
373 | #ifdef HAVE_LCD_COLOR | ||
374 | /* On Color LCDs we have a card back so we only need to clear | ||
375 | * the card area when it's known*/ | ||
376 | rb->lcd_set_foreground( LCD_WHITE ); | ||
377 | rb->lcd_fillrect( x+1, y+1, CARD_WIDTH-1, CARD_HEIGHT-1 ); | ||
378 | #endif | ||
379 | draw_number( card.num, x+1, y+1 ); | ||
380 | if( leftstyle ) | ||
381 | { | ||
382 | draw_suit( card.suit, x+1, y+2+NUMBER_HEIGHT ); | ||
383 | } | ||
384 | else | ||
385 | { | ||
386 | draw_suit( card.suit, x+2+NUMBER_WIDTH, y+1 ); | ||
387 | } | ||
388 | } | ||
389 | #ifdef HAVE_LCD_COLOR | ||
390 | else | ||
391 | { | ||
392 | rb->lcd_bitmap( solitaire_cardback, x+1, y+1, | ||
393 | CARDBACK_WIDTH, CARDBACK_HEIGHT ); | ||
394 | } | ||
395 | #endif | ||
350 | 396 | ||
351 | return i; | 397 | draw_card_ext( x, y, selected, cursor ); |
398 | } | ||
399 | |||
400 | /* Draw an empty stack */ | ||
401 | static void draw_empty_stack( int s, int x, int y, bool cursor ) | ||
402 | { | ||
403 | #if LCD_DEPTH > 1 | ||
404 | rb->lcd_set_foreground( LCD_WHITE ); | ||
405 | #else | ||
406 | rb->lcd_set_drawmode( DRMODE_SOLID|DRMODE_INVERSEVID ); | ||
407 | #endif | ||
408 | rb->lcd_fillrect( x+1, y+1, CARD_WIDTH-1, CARD_HEIGHT-1 ); | ||
409 | #if LCD_DEPTH == 1 | ||
410 | rb->lcd_set_drawmode( DRMODE_SOLID ); | ||
411 | #endif | ||
412 | draw_suiti( s, x+(CARD_WIDTH-SUITI_WIDTH)/2, | ||
413 | y+(CARD_HEIGHT-SUITI_HEIGHT)/2 ); | ||
414 | |||
415 | draw_card_ext( x, y, false, cursor ); | ||
352 | } | 416 | } |
353 | 417 | ||
354 | #define HELP_QUIT 0 | 418 | /** |
355 | #define HELP_USB 1 | 419 | * Help |
420 | * | ||
421 | * TODO: the help menu should just list the key definitions. Asking the | ||
422 | * user to try all possible keys/key combos is just counter | ||
423 | * productive. | ||
424 | */ | ||
425 | |||
426 | enum help { HELP_QUIT, HELP_USB }; | ||
356 | 427 | ||
357 | /* help for the not so intuitive interface */ | 428 | /* help for the not so intuitive interface */ |
358 | int solitaire_help(void){ | 429 | enum help solitaire_help( void ) |
430 | { | ||
359 | 431 | ||
360 | int button; | 432 | int button; |
361 | int lastbutton = BUTTON_NONE; | 433 | int lastbutton = BUTTON_NONE; |
362 | 434 | ||
363 | while(1){ | 435 | while( true ) |
364 | 436 | { | |
365 | rb->lcd_clear_display(); | 437 | rb->lcd_clear_display(); |
366 | 438 | ||
367 | #if CONFIG_KEYPAD == RECORDER_PAD | 439 | #if CONFIG_KEYPAD == RECORDER_PAD |
@@ -388,82 +460,85 @@ int solitaire_help(void){ | |||
388 | rb->lcd_putsxy(20, 48, "All actions can be"); | 460 | rb->lcd_putsxy(20, 48, "All actions can be"); |
389 | rb->lcd_putsxy(20, 56, "done using the"); | 461 | rb->lcd_putsxy(20, 56, "done using the"); |
390 | rb->lcd_putsxy(20, 64, "joystick and RECORD."); | 462 | rb->lcd_putsxy(20, 64, "joystick and RECORD."); |
463 | #else | ||
464 | //# warning "Add help strings for other keypads" | ||
391 | #endif | 465 | #endif |
392 | 466 | ||
393 | rb->lcd_update(); | 467 | rb->lcd_update(); |
394 | 468 | ||
395 | button = rb->button_get(true); | 469 | button = rb->button_get( true ); |
396 | switch(button){ | 470 | switch( button ) |
471 | { | ||
397 | case SOL_UP: | 472 | case SOL_UP: |
398 | #ifdef SOL_UP_PRE | 473 | #ifdef SOL_UP_PRE |
399 | if(lastbutton != SOL_UP_PRE) | 474 | if( lastbutton != SOL_UP_PRE ) |
400 | break; | 475 | break; |
401 | #endif | 476 | #endif |
402 | rb->splash(HZ*2, true, HELP_SOL_UP); | 477 | rb->splash( HZ*2, true, HELP_SOL_UP ); |
403 | break; | 478 | break; |
404 | 479 | ||
405 | case SOL_DOWN: | 480 | case SOL_DOWN: |
406 | #ifdef SOL_DOWN_PRE | 481 | #ifdef SOL_DOWN_PRE |
407 | if(lastbutton != SOL_DOWN_PRE) | 482 | if( lastbutton != SOL_DOWN_PRE ) |
408 | break; | 483 | break; |
409 | #endif | 484 | #endif |
410 | rb->splash(HZ*2, true, HELP_SOL_DOWN); | 485 | rb->splash( HZ*2, true, HELP_SOL_DOWN ); |
411 | break; | 486 | break; |
412 | 487 | ||
413 | case SOL_LEFT: | 488 | case SOL_LEFT: |
414 | #ifdef SOL_LEFT_PRE | 489 | #ifdef SOL_LEFT_PRE |
415 | if(lastbutton != SOL_LEFT_PRE) | 490 | if( lastbutton != SOL_LEFT_PRE ) |
416 | break; | 491 | break; |
417 | #endif | 492 | #endif |
418 | rb->splash(HZ*2, true, HELP_SOL_LEFT); | 493 | rb->splash( HZ*2, true, HELP_SOL_LEFT ); |
419 | break; | 494 | break; |
420 | 495 | ||
421 | case SOL_RIGHT: | 496 | case SOL_RIGHT: |
422 | #ifdef SOL_RIGHT_PRE | 497 | #ifdef SOL_RIGHT_PRE |
423 | if(lastbutton != SOL_RIGHT_PRE) | 498 | if( lastbutton != SOL_RIGHT_PRE ) |
424 | break; | 499 | break; |
425 | #endif | 500 | #endif |
426 | rb->splash(HZ*2, true, HELP_SOL_RIGHT); | 501 | rb->splash( HZ*2, true, HELP_SOL_RIGHT ); |
427 | break; | 502 | break; |
428 | 503 | ||
429 | case SOL_MOVE: | 504 | case SOL_MOVE: |
430 | #ifdef SOL_MOVE_PRE | 505 | #ifdef SOL_MOVE_PRE |
431 | if(lastbutton != SOL_MOVE_PRE) | 506 | if( lastbutton != SOL_MOVE_PRE ) |
432 | break; | 507 | break; |
433 | #endif | 508 | #endif |
434 | rb->splash(HZ*2, true, HELP_SOL_MOVE); | 509 | rb->splash( HZ*2, true, HELP_SOL_MOVE ); |
435 | break; | 510 | break; |
436 | 511 | ||
437 | case SOL_DRAW: | 512 | case SOL_DRAW: |
438 | #ifdef SOL_DRAW_PRE | 513 | #ifdef SOL_DRAW_PRE |
439 | if(lastbutton != SOL_DRAW_PRE) | 514 | if( lastbutton != SOL_DRAW_PRE ) |
440 | break; | 515 | break; |
441 | #endif | 516 | #endif |
442 | rb->splash(HZ*2, true, HELP_SOL_DRAW); | 517 | rb->splash( HZ*2, true, HELP_SOL_DRAW ); |
443 | break; | 518 | break; |
444 | 519 | ||
445 | case SOL_CUR2STACK: | 520 | case SOL_CUR2STACK: |
446 | #ifdef SOL_CUR2STACK_PRE | 521 | #ifdef SOL_CUR2STACK_PRE |
447 | if(lastbutton != SOL_CUR2STACK_PRE) | 522 | if( lastbutton != SOL_CUR2STACK_PRE ) |
448 | break; | 523 | break; |
449 | #endif | 524 | #endif |
450 | rb->splash(HZ*2, true, HELP_SOL_CUR2STACK); | 525 | rb->splash( HZ*2, true, HELP_SOL_CUR2STACK ); |
451 | break; | 526 | break; |
452 | 527 | ||
453 | case SOL_REM2STACK: | 528 | case SOL_REM2STACK: |
454 | #ifdef SOL_REM2STACK_PRE | 529 | #ifdef SOL_REM2STACK_PRE |
455 | if(lastbutton != SOL_REM2STACK_PRE) | 530 | if( lastbutton != SOL_REM2STACK_PRE ) |
456 | break; | 531 | break; |
457 | #endif | 532 | #endif |
458 | rb->splash(HZ*2, true, HELP_SOL_REM2STACK); | 533 | rb->splash( HZ*2, true, HELP_SOL_REM2STACK ); |
459 | break; | 534 | break; |
460 | 535 | ||
461 | case SOL_REM2CUR: | 536 | case SOL_REM2CUR: |
462 | #ifdef SOL_REM2CUR_PRE | 537 | #ifdef SOL_REM2CUR_PRE |
463 | if(lastbutton != SOL_REM2CUR_PRE) | 538 | if( lastbutton != SOL_REM2CUR_PRE ) |
464 | break; | 539 | break; |
465 | #endif | 540 | #endif |
466 | rb->splash(HZ*2, true, HELP_SOL_REM2CUR); | 541 | rb->splash( HZ*2, true, HELP_SOL_REM2CUR ); |
467 | break; | 542 | break; |
468 | #ifdef SOL_RC_QUIT | 543 | #ifdef SOL_RC_QUIT |
469 | case SOL_RC_QUIT: | 544 | case SOL_RC_QUIT: |
@@ -472,48 +547,40 @@ int solitaire_help(void){ | |||
472 | return HELP_QUIT; | 547 | return HELP_QUIT; |
473 | 548 | ||
474 | default: | 549 | default: |
475 | if(rb->default_event_handler(button) == SYS_USB_CONNECTED) | 550 | if( rb->default_event_handler( button ) == SYS_USB_CONNECTED ) |
476 | return HELP_USB; | 551 | return HELP_USB; |
477 | break; | 552 | break; |
478 | } | 553 | } |
479 | if(button != BUTTON_NONE) | 554 | if( button != BUTTON_NONE ) |
480 | lastbutton = button; | 555 | lastbutton = button; |
481 | } | 556 | } |
482 | } | 557 | } |
558 | |||
559 | /** | ||
560 | * Custom menu / options | ||
561 | * | ||
562 | * TODO: use rockbox api menus instead | ||
563 | */ | ||
564 | |||
483 | #define CFGFILE_VERSION 0 | 565 | #define CFGFILE_VERSION 0 |
484 | int draw_type; | 566 | int draw_type; |
485 | 567 | ||
486 | |||
487 | unsigned char change_draw(unsigned char draw){ | ||
488 | if (draw == 0) | ||
489 | return 1; | ||
490 | else | ||
491 | return 0; | ||
492 | } | ||
493 | static struct configdata config[] = { | 568 | static struct configdata config[] = { |
494 | { TYPE_INT, 0, 1, &draw_type, "draw_type", NULL, NULL } | 569 | { TYPE_INT, 0, 1, &draw_type, "draw_type", NULL, NULL } |
495 | }; | 570 | }; |
496 | 571 | ||
497 | /* menu return codes */ | 572 | /* menu return codes */ |
498 | #define MENU_RESUME 0 | 573 | enum { MENU_RESUME, MENU_RESTART, MENU_OPT, |
499 | #define MENU_RESTART 1 | 574 | MENU_HELP, MENU_QUIT, MENU_USB }; |
500 | #define MENU_HELP 3 | 575 | #define MENU_LENGTH MENU_USB |
501 | #define MENU_QUIT 4 | ||
502 | #define MENU_USB 5 | ||
503 | #define MENU_OPT 2 | ||
504 | |||
505 | /* menu item number */ | ||
506 | #define MENU_LENGTH 5 | ||
507 | 576 | ||
508 | /* different menu behaviors */ | 577 | /* different menu behaviors */ |
578 | enum { MENU_BEFOREGAME, MENU_BEFOREGAMEOP, MENU_DURINGGAME }; | ||
509 | 579 | ||
510 | #define MENU_BEFOREGAME 0 | 580 | /** |
511 | #define MENU_BEFOREGAMEOP 1 | 581 | * The menu |
512 | #define MENU_DURINGGAME 2 | 582 | * text displayed changes depending on the context */ |
513 | unsigned char when; | 583 | int solitaire_menu( unsigned char context ) |
514 | /* the menu */ | ||
515 | /* text displayed changes depending on the 'when' parameter */ | ||
516 | int solitaire_menu(unsigned char when_n) | ||
517 | { | 584 | { |
518 | static char menu[3][MENU_LENGTH][17] = | 585 | static char menu[3][MENU_LENGTH][17] = |
519 | { { "Start Game", | 586 | { { "Start Game", |
@@ -535,34 +602,42 @@ int solitaire_menu(unsigned char when_n) | |||
535 | 602 | ||
536 | 603 | ||
537 | int i; | 604 | int i; |
538 | int cursor=0; | 605 | int cursor = 0; |
539 | int button; | 606 | int button; |
607 | |||
540 | int fh; | 608 | int fh; |
541 | when=when_n; | 609 | rb->lcd_getstringsize( menu[0][0], NULL, &fh ); |
542 | rb->lcd_getstringsize("A", NULL, &fh); | ||
543 | fh++; | 610 | fh++; |
544 | 611 | ||
545 | if(when != MENU_BEFOREGAMEOP && when!=MENU_BEFOREGAME && when!=MENU_DURINGGAME) | 612 | if( context != MENU_BEFOREGAMEOP |
546 | when = MENU_DURINGGAME; | 613 | && context != MENU_BEFOREGAME |
614 | && context != MENU_DURINGGAME ) | ||
615 | { | ||
616 | context = MENU_DURINGGAME; | ||
617 | } | ||
547 | 618 | ||
548 | while(1){ | 619 | while( true ) |
620 | { | ||
549 | 621 | ||
550 | rb->lcd_clear_display(); | 622 | rb->lcd_clear_display(); |
551 | rb->lcd_putsxy(20, 1, "Solitaire"); | 623 | rb->lcd_putsxy( 20, 1, "Solitaire" ); |
552 | 624 | ||
553 | for(i = 0; i<MENU_LENGTH; i++){ | 625 | for( i = 0; i<MENU_LENGTH; i++ ) |
554 | rb->lcd_putsxy(1, 17+fh*i, menu[when][i]); | 626 | { |
555 | if(cursor == i) { | 627 | rb->lcd_putsxy( 1, 17+fh*i, menu[context][i] ); |
556 | rb->lcd_set_drawmode(DRMODE_COMPLEMENT); | 628 | if( cursor == i ) |
557 | rb->lcd_fillrect(0,17+fh*i, LCD_WIDTH, fh); | 629 | { |
558 | rb->lcd_set_drawmode(DRMODE_SOLID); | 630 | rb->lcd_set_drawmode( DRMODE_COMPLEMENT ); |
631 | rb->lcd_fillrect( 0, 17+fh*i, LCD_WIDTH, fh ); | ||
632 | rb->lcd_set_drawmode( DRMODE_SOLID ); | ||
559 | } | 633 | } |
560 | } | 634 | } |
561 | 635 | ||
562 | rb->lcd_update(); | 636 | rb->lcd_update(); |
563 | 637 | ||
564 | button = rb->button_get(true); | 638 | button = rb->button_get( true ); |
565 | switch(button){ | 639 | switch( button ) |
640 | { | ||
566 | case SOL_UP: | 641 | case SOL_UP: |
567 | cursor = (cursor + MENU_LENGTH - 1)%MENU_LENGTH; | 642 | cursor = (cursor + MENU_LENGTH - 1)%MENU_LENGTH; |
568 | break; | 643 | break; |
@@ -578,7 +653,8 @@ int solitaire_menu(unsigned char when_n) | |||
578 | #ifdef SOL_MENU_RUN2 | 653 | #ifdef SOL_MENU_RUN2 |
579 | case SOL_MENU_RUN2: | 654 | case SOL_MENU_RUN2: |
580 | #endif | 655 | #endif |
581 | switch(cursor){ | 656 | switch( cursor ) |
657 | { | ||
582 | case MENU_RESUME: | 658 | case MENU_RESUME: |
583 | case MENU_RESTART: | 659 | case MENU_RESTART: |
584 | case MENU_OPT: | 660 | case MENU_OPT: |
@@ -586,20 +662,12 @@ int solitaire_menu(unsigned char when_n) | |||
586 | return cursor; | 662 | return cursor; |
587 | 663 | ||
588 | case MENU_HELP: | 664 | case MENU_HELP: |
589 | if(solitaire_help() == HELP_USB) | 665 | if( solitaire_help() == HELP_USB ) |
590 | return MENU_USB; | 666 | return MENU_USB; |
591 | break; | 667 | break; |
592 | } | 668 | } |
593 | break; | 669 | break; |
594 | 670 | ||
595 | case SOL_MENU_INFO: | ||
596 | #if defined(SOL_MENU_INFO2) && defined(SOL_MENU_INFO3) | ||
597 | case SOL_MENU_INFO2: | ||
598 | case SOL_MENU_INFO3: | ||
599 | #endif | ||
600 | rb->splash(HZ, true, "Solitaire for Rockbox by dionoea"); | ||
601 | break; | ||
602 | |||
603 | #ifdef SOL_OPT | 671 | #ifdef SOL_OPT |
604 | case SOL_OPT: | 672 | case SOL_OPT: |
605 | return MENU_OPT; | 673 | return MENU_OPT; |
@@ -612,13 +680,17 @@ int solitaire_menu(unsigned char when_n) | |||
612 | return MENU_QUIT; | 680 | return MENU_QUIT; |
613 | 681 | ||
614 | default: | 682 | default: |
615 | if(rb->default_event_handler(button) == SYS_USB_CONNECTED) | 683 | if( rb->default_event_handler( button ) == SYS_USB_CONNECTED ) |
616 | return MENU_USB; | 684 | return MENU_USB; |
617 | break; | 685 | break; |
618 | } | 686 | } |
619 | } | 687 | } |
620 | } | 688 | } |
621 | 689 | ||
690 | /** | ||
691 | * Global variables | ||
692 | */ | ||
693 | |||
622 | /* player's cursor */ | 694 | /* player's cursor */ |
623 | unsigned char cur_card; | 695 | unsigned char cur_card; |
624 | /* player's cursor column num */ | 696 | /* player's cursor column num */ |
@@ -628,7 +700,7 @@ unsigned char cur_col; | |||
628 | unsigned char sel_card; | 700 | unsigned char sel_card; |
629 | 701 | ||
630 | /* the deck */ | 702 | /* the deck */ |
631 | card deck[SUITS * CARDS_PER_SUIT]; | 703 | card_t deck[ NUM_CARDS ]; |
632 | 704 | ||
633 | /* the remaining cards */ | 705 | /* the remaining cards */ |
634 | unsigned char rem; | 706 | unsigned char rem; |
@@ -638,51 +710,84 @@ unsigned char coun_rem; | |||
638 | /* the 7 game columns */ | 710 | /* the 7 game columns */ |
639 | unsigned char cols[COL_NUM]; | 711 | unsigned char cols[COL_NUM]; |
640 | 712 | ||
641 | int CARDS_PER_DRAW; | 713 | int cards_per_draw; |
642 | /* the 4 final stacks */ | 714 | /* the 4 final stacks */ |
643 | unsigned char stacks[SUITS]; | 715 | unsigned char stacks[SUITS]; |
644 | 716 | ||
717 | /** | ||
718 | * Card handling routines | ||
719 | */ | ||
720 | |||
721 | unsigned char next_random_card( card_t *deck ) | ||
722 | { | ||
723 | unsigned char i,r; | ||
724 | |||
725 | r = rb->rand()%(NUM_CARDS)+1; | ||
726 | i = 0; | ||
727 | |||
728 | while( r>0 ) | ||
729 | { | ||
730 | i = (i + 1)%(NUM_CARDS); | ||
731 | if( !deck[i].used ) r--; | ||
732 | } | ||
733 | |||
734 | deck[i].used = 1; | ||
735 | |||
736 | return i; | ||
737 | } | ||
738 | |||
739 | |||
645 | /* initialize the game */ | 740 | /* initialize the game */ |
646 | void solitaire_init(void){ | 741 | void solitaire_init( void ) |
742 | { | ||
647 | 743 | ||
648 | unsigned char c; | 744 | unsigned char c; |
649 | int i,j; | 745 | int i, j; |
650 | #if LCD_DEPTH>1 | 746 | |
651 | rb->lcd_set_foreground(LCD_BLACK); | 747 | /* number of cards that are drawn on the remains' stack (by pressing F2) */ |
652 | #ifdef HAVE_LCD_COLOR | 748 | if( draw_type == 0 ) |
653 | rb->lcd_set_background(background_color); | 749 | { |
654 | #endif | 750 | cards_per_draw = 3; |
655 | #endif | ||
656 | /* number of cards that are drawn on the remains' stack (by pressing F2) */ | ||
657 | if(draw_type == 0) { | ||
658 | CARDS_PER_DRAW =3; | ||
659 | } else { | ||
660 | CARDS_PER_DRAW=1; | ||
661 | } | 751 | } |
752 | else | ||
753 | { | ||
754 | cards_per_draw = 1; | ||
755 | } | ||
756 | |||
662 | /* init deck */ | 757 | /* init deck */ |
663 | for(i=0;i<SUITS;i++){ | 758 | for( i=0; i<SUITS; i++ ) |
664 | for(j=0;j<CARDS_PER_SUIT;j++){ | 759 | { |
665 | deck[i*CARDS_PER_SUIT+j].suit = i; | 760 | for( j=0; j<CARDS_PER_SUIT; j++ ) |
666 | deck[i*CARDS_PER_SUIT+j].num = j; | 761 | { |
667 | deck[i*CARDS_PER_SUIT+j].known = 1; | 762 | #define card deck[i*CARDS_PER_SUIT+j] |
668 | deck[i*CARDS_PER_SUIT+j].used = 0; | 763 | card.suit = i; |
669 | deck[i*CARDS_PER_SUIT+j].next = NOT_A_CARD; | 764 | card.num = j; |
765 | card.known = 1; | ||
766 | card.used = 0; | ||
767 | card.next = NOT_A_CARD; | ||
768 | #undef card | ||
670 | } | 769 | } |
671 | } | 770 | } |
672 | 771 | ||
673 | /* deal the cards ... */ | 772 | /* deal the cards ... */ |
674 | /* ... in the columns */ | 773 | /* ... in the columns */ |
675 | for(i=0; i<COL_NUM; i++){ | 774 | for( i=0; i<COL_NUM; i++ ) |
775 | { | ||
676 | c = NOT_A_CARD; | 776 | c = NOT_A_CARD; |
677 | for(j=0; j<=i; j++){ | 777 | for( j=0; j<=i; j++ ) |
678 | if(c == NOT_A_CARD){ | 778 | { |
679 | cols[i] = next_random_card(deck); | 779 | if( c == NOT_A_CARD ) |
780 | { | ||
781 | cols[i] = next_random_card( deck ); | ||
680 | c = cols[i]; | 782 | c = cols[i]; |
681 | } else { | 783 | } |
682 | deck[c].next = next_random_card(deck); | 784 | else |
785 | { | ||
786 | deck[c].next = next_random_card( deck ); | ||
683 | c = deck[c].next; | 787 | c = deck[c].next; |
684 | } | 788 | } |
685 | if(j<i) deck[c].known = 0; | 789 | if( j < i ) |
790 | deck[c].known = 0; | ||
686 | } | 791 | } |
687 | } | 792 | } |
688 | 793 | ||
@@ -690,15 +795,17 @@ void solitaire_init(void){ | |||
690 | rem = next_random_card(deck); | 795 | rem = next_random_card(deck); |
691 | c = rem; | 796 | c = rem; |
692 | 797 | ||
693 | for(i=1; i<SUITS * CARDS_PER_SUIT - COL_NUM * (COL_NUM + 1)/2; i++){ | 798 | for( i=1; i < NUM_CARDS - COL_NUM * (COL_NUM + 1)/2; i++ ) |
694 | deck[c].next = next_random_card(deck); | 799 | { |
800 | deck[c].next = next_random_card( deck ); | ||
695 | c = deck[c].next; | 801 | c = deck[c].next; |
696 | } | 802 | } |
697 | 803 | ||
698 | /* we now finished dealing the cards. The game can start ! (at last) */ | 804 | /* we now finished dealing the cards. The game can start ! (at last) */ |
699 | 805 | ||
700 | /* init the stack */ | 806 | /* init the stack */ |
701 | for(i = 0; i<SUITS; i++){ | 807 | for( i = 0; i<SUITS; i++ ) |
808 | { | ||
702 | stacks[i] = NOT_A_CARD; | 809 | stacks[i] = NOT_A_CARD; |
703 | } | 810 | } |
704 | 811 | ||
@@ -716,24 +823,29 @@ void solitaire_init(void){ | |||
716 | } | 823 | } |
717 | 824 | ||
718 | /* find the column number in which 'card' can be found */ | 825 | /* find the column number in which 'card' can be found */ |
719 | unsigned char find_card_col(unsigned char card){ | 826 | unsigned char find_card_col( unsigned char card ) |
827 | { | ||
720 | int i; | 828 | int i; |
721 | unsigned char c; | 829 | unsigned char c; |
722 | 830 | ||
723 | if(card == NOT_A_CARD) return NOT_A_COL; | 831 | if( card == NOT_A_CARD ) return NOT_A_COL; |
724 | 832 | ||
725 | for(i=0; i<COL_NUM; i++){ | 833 | for( i=0; i<COL_NUM; i++ ) |
834 | { | ||
726 | c = cols[i]; | 835 | c = cols[i]; |
727 | while(c!=NOT_A_CARD){ | 836 | while( c != NOT_A_CARD ) |
728 | if(c == card) return i; | 837 | { |
838 | if( c == card ) return i; | ||
729 | c = deck[c].next; | 839 | c = deck[c].next; |
730 | } | 840 | } |
731 | } | 841 | } |
732 | 842 | ||
733 | for(i=0; i<SUITS; i++){ | 843 | for( i=0; i<SUITS; i++ ) |
844 | { | ||
734 | c = stacks[i]; | 845 | c = stacks[i]; |
735 | while(c!=NOT_A_CARD){ | 846 | while( c != NOT_A_CARD ) |
736 | if(c == card) return STACKS_COL + i; | 847 | { |
848 | if( c == card ) return STACKS_COL + i; | ||
737 | c = deck[c].next; | 849 | c = deck[c].next; |
738 | } | 850 | } |
739 | } | 851 | } |
@@ -743,41 +855,49 @@ unsigned char find_card_col(unsigned char card){ | |||
743 | 855 | ||
744 | /* find the card preceding 'card' */ | 856 | /* find the card preceding 'card' */ |
745 | /* if it doesn't exist, return NOT_A_CARD */ | 857 | /* if it doesn't exist, return NOT_A_CARD */ |
746 | unsigned char find_prev_card(unsigned char card){ | 858 | unsigned char find_prev_card( unsigned char card ){ |
747 | int i; | 859 | int i; |
748 | 860 | ||
749 | for(i=0; i<SUITS*CARDS_PER_SUIT; i++){ | 861 | for( i=0; i < NUM_CARDS; i++ ) |
750 | if(deck[i].next == card) return i; | 862 | { |
863 | if( deck[i].next == card ) return i; | ||
751 | } | 864 | } |
752 | 865 | ||
753 | return NOT_A_CARD; | 866 | return NOT_A_CARD; |
754 | } | 867 | } |
755 | 868 | ||
756 | /* find the last card of a given column */ | 869 | /* find the last card of a given column */ |
757 | unsigned char find_last_card(unsigned char col){ | 870 | unsigned char find_last_card( unsigned char col ) |
871 | { | ||
758 | unsigned char c; | 872 | unsigned char c; |
759 | 873 | ||
760 | if(col < COL_NUM){ | 874 | if( col < COL_NUM ) |
875 | { | ||
761 | c = cols[col]; | 876 | c = cols[col]; |
762 | } else if(col < REM_COL){ | 877 | } |
878 | else if( col < REM_COL ) | ||
879 | { | ||
763 | c = stacks[col - STACKS_COL]; | 880 | c = stacks[col - STACKS_COL]; |
764 | } else { | 881 | } |
882 | else | ||
883 | { | ||
765 | c = rem; | 884 | c = rem; |
766 | } | 885 | } |
767 | 886 | ||
768 | if(c == NOT_A_CARD) | 887 | if(c == NOT_A_CARD) |
769 | return c; | 888 | return c; |
770 | else { | 889 | else |
771 | while(deck[c].next != NOT_A_CARD){ | 890 | { |
891 | while(deck[c].next != NOT_A_CARD) | ||
772 | c = deck[c].next; | 892 | c = deck[c].next; |
773 | } | ||
774 | return c; | 893 | return c; |
775 | } | 894 | } |
776 | } | 895 | } |
777 | 896 | ||
778 | #define MOVE_OK 0 | 897 | enum move { MOVE_OK, MOVE_NOT_OK }; |
779 | #define MOVE_NOT_OK 1 | 898 | |
780 | unsigned char move_card(unsigned char dest_col, unsigned char src_card){ | 899 | enum move move_card( unsigned char dest_col, unsigned char src_card ) |
900 | { | ||
781 | /* the column on which to take src_card */ | 901 | /* the column on which to take src_card */ |
782 | unsigned char src_col; | 902 | unsigned char src_col; |
783 | 903 | ||
@@ -788,82 +908,95 @@ unsigned char move_card(unsigned char dest_col, unsigned char src_card){ | |||
788 | unsigned char src_card_prev; | 908 | unsigned char src_card_prev; |
789 | 909 | ||
790 | /* you can't move no card (at least, it doesn't have any consequence) */ | 910 | /* you can't move no card (at least, it doesn't have any consequence) */ |
791 | if(src_card == NOT_A_CARD) return MOVE_NOT_OK; | 911 | if( src_card == NOT_A_CARD ) return MOVE_NOT_OK; |
792 | /* you can't put a card back on the remains' stack */ | 912 | /* you can't put a card back on the remains' stack */ |
793 | if(dest_col == REM_COL) return MOVE_NOT_OK; | 913 | if( dest_col == REM_COL ) return MOVE_NOT_OK; |
794 | 914 | ||
795 | src_col = find_card_col(src_card); | 915 | src_col = find_card_col( src_card ); |
796 | dest_card = find_last_card(dest_col); | 916 | dest_card = find_last_card( dest_col ); |
797 | src_card_prev = find_prev_card(src_card); | 917 | src_card_prev = find_prev_card( src_card ); |
798 | 918 | ||
799 | /* you can't move more than one card at a time from the final stack */ | 919 | /* you can't move more than one card at a time from the final stack */ |
800 | /* to the rest of the game */ | 920 | /* to the rest of the game */ |
801 | if(src_col >= COL_NUM && src_col < REM_COL | 921 | if( src_col >= COL_NUM && src_col < REM_COL |
802 | && deck[src_card].next != NOT_A_CARD){ | 922 | && deck[src_card].next != NOT_A_CARD ) |
923 | { | ||
803 | return MOVE_NOT_OK; | 924 | return MOVE_NOT_OK; |
804 | } | 925 | } |
805 | 926 | ||
806 | /* if we (that means dest) are on one of the 7 columns ... */ | 927 | /* if we (that means dest) are on one of the 7 columns ... */ |
807 | if(dest_col < COL_NUM){ | 928 | if( dest_col < COL_NUM ) |
929 | { | ||
808 | /* ... check is we are on an empty color and that the src is a king */ | 930 | /* ... check is we are on an empty color and that the src is a king */ |
809 | if(dest_card == NOT_A_CARD | 931 | if( dest_card == NOT_A_CARD |
810 | && deck[src_card].num == CARDS_PER_SUIT - 1){ | 932 | && deck[src_card].num == CARDS_PER_SUIT - 1 ) |
933 | { | ||
811 | /* this is a winning combination */ | 934 | /* this is a winning combination */ |
812 | cols[dest_col] = src_card; | 935 | cols[dest_col] = src_card; |
813 | } | 936 | } |
814 | /* ... or check if the cards follow one another and have same suit */ | 937 | /* ... or check if the cards follow one another and have same suit */ |
815 | else if((deck[dest_card].suit + deck[src_card].suit)%2==1 | 938 | else if(( deck[dest_card].suit + deck[src_card].suit)%2==1 |
816 | && deck[dest_card].num == deck[src_card].num + 1){ | 939 | && deck[dest_card].num == deck[src_card].num + 1 ) |
940 | { | ||
817 | /* this is a winning combination */ | 941 | /* this is a winning combination */ |
818 | deck[dest_card].next = src_card; | 942 | deck[dest_card].next = src_card; |
819 | } | 943 | } |
820 | /* ... or, humpf, well that's not good news */ | 944 | /* ... or, humpf, well that's not good news */ |
821 | else { | 945 | else |
946 | { | ||
822 | /* this is not a winning combination */ | 947 | /* this is not a winning combination */ |
823 | return MOVE_NOT_OK; | 948 | return MOVE_NOT_OK; |
824 | } | 949 | } |
825 | } | 950 | } |
826 | /* if we are on one of the 4 final stacks ... */ | 951 | /* if we are on one of the 4 final stacks ... */ |
827 | else if(dest_col < REM_COL){ | 952 | else if( dest_col < REM_COL ) |
953 | { | ||
828 | /* ... check if we are on an empty stack, that the src is an | 954 | /* ... check if we are on an empty stack, that the src is an |
829 | * ace and that this is the good final stack */ | 955 | * ace and that this is the good final stack */ |
830 | if(dest_card == NOT_A_CARD | 956 | if( dest_card == NOT_A_CARD |
831 | && deck[src_card].num == 0 | 957 | && deck[src_card].num == 0 |
832 | && deck[src_card].suit == dest_col - STACKS_COL){ | 958 | && deck[src_card].suit == dest_col - STACKS_COL ) |
959 | { | ||
833 | /* this is a winning combination */ | 960 | /* this is a winning combination */ |
834 | stacks[dest_col - STACKS_COL] = src_card; | 961 | stacks[dest_col - STACKS_COL] = src_card; |
835 | } | 962 | } |
836 | /* ... or check if the cards follow one another, have the same | 963 | /* ... or check if the cards follow one another, have the same |
837 | * suit and {that src has no .next element or is from the remains' | 964 | * suit and {that src has no .next element or is from the remains' |
838 | * stack} */ | 965 | * stack} */ |
839 | else if(deck[dest_card].suit == deck[src_card].suit | 966 | else if( deck[dest_card].suit == deck[src_card].suit |
840 | && deck[dest_card].num + 1 == deck[src_card].num | 967 | && deck[dest_card].num + 1 == deck[src_card].num |
841 | && (deck[src_card].next == NOT_A_CARD || src_col == REM_COL) ){ | 968 | && (deck[src_card].next == NOT_A_CARD || src_col == REM_COL) ) |
969 | { | ||
842 | /* this is a winning combination */ | 970 | /* this is a winning combination */ |
843 | deck[dest_card].next = src_card; | 971 | deck[dest_card].next = src_card; |
844 | } | 972 | } |
845 | /* ... or, well that's not good news */ | 973 | /* ... or, well that's not good news */ |
846 | else { | 974 | else |
975 | { | ||
847 | /* this is not a winnong combination */ | 976 | /* this is not a winnong combination */ |
848 | return MOVE_NOT_OK; | 977 | return MOVE_NOT_OK; |
849 | } | 978 | } |
850 | } | 979 | } |
851 | /* if we are on the remains' stack */ | 980 | /* if we are on the remains' stack */ |
852 | else { | 981 | else |
982 | { | ||
853 | /* you can't move a card back to the remains' stack */ | 983 | /* you can't move a card back to the remains' stack */ |
854 | return MOVE_NOT_OK; | 984 | return MOVE_NOT_OK; |
855 | } | 985 | } |
856 | 986 | ||
857 | /* if the src card is from the remains' stack, we don't want to take | 987 | /* if the src card is from the remains' stack, we don't want to take |
858 | * the following cards */ | 988 | * the following cards */ |
859 | if(src_col == REM_COL){ | 989 | if( src_col == REM_COL ) |
990 | { | ||
860 | /* if src card is the first card from the stack */ | 991 | /* if src card is the first card from the stack */ |
861 | if(src_card_prev == NOT_A_CARD){ | 992 | if( src_card_prev == NOT_A_CARD ) |
993 | { | ||
862 | rem = deck[src_card].next; | 994 | rem = deck[src_card].next; |
863 | coun_rem = coun_rem-1; | 995 | coun_rem = coun_rem-1; |
864 | } | 996 | } |
865 | /* if src card is not the first card from the stack */ | 997 | /* if src card is not the first card from the stack */ |
866 | else { | 998 | else |
999 | { | ||
867 | deck[src_card_prev].next = deck[src_card].next; | 1000 | deck[src_card_prev].next = deck[src_card].next; |
868 | } | 1001 | } |
869 | deck[src_card].next = NOT_A_CARD; | 1002 | deck[src_card].next = NOT_A_CARD; |
@@ -871,14 +1004,21 @@ unsigned char move_card(unsigned char dest_col, unsigned char src_card){ | |||
871 | coun_rem = coun_rem-1; | 1004 | coun_rem = coun_rem-1; |
872 | } | 1005 | } |
873 | /* if the src card is from somewhere else, just take everything */ | 1006 | /* if the src card is from somewhere else, just take everything */ |
874 | else { | 1007 | else |
875 | if(src_card_prev == NOT_A_CARD){ | 1008 | { |
876 | if(src_col < COL_NUM){ | 1009 | if( src_card_prev == NOT_A_CARD ) |
1010 | { | ||
1011 | if( src_col < COL_NUM ) | ||
1012 | { | ||
877 | cols[src_col] = NOT_A_CARD; | 1013 | cols[src_col] = NOT_A_CARD; |
878 | } else { | 1014 | } |
1015 | else | ||
1016 | { | ||
879 | stacks[src_col - STACKS_COL] = NOT_A_CARD; | 1017 | stacks[src_col - STACKS_COL] = NOT_A_CARD; |
880 | } | 1018 | } |
881 | } else { | 1019 | } |
1020 | else | ||
1021 | { | ||
882 | deck[src_card_prev].next = NOT_A_CARD; | 1022 | deck[src_card_prev].next = NOT_A_CARD; |
883 | } | 1023 | } |
884 | } | 1024 | } |
@@ -887,11 +1027,11 @@ unsigned char move_card(unsigned char dest_col, unsigned char src_card){ | |||
887 | return MOVE_OK; | 1027 | return MOVE_OK; |
888 | } | 1028 | } |
889 | 1029 | ||
1030 | /** | ||
1031 | * The main game loop | ||
1032 | */ | ||
890 | 1033 | ||
891 | 1034 | enum { SOLITAIRE_WIN, SOLITAIRE_QUIT, SOLITAIRE_USB }; | |
892 | #define SOLITAIRE_WIN 0 | ||
893 | #define SOLITAIRE_QUIT 1 | ||
894 | #define SOLITAIRE_USB 2 | ||
895 | 1035 | ||
896 | #if ( LCD_WIDTH > ( CARD_WIDTH * 8 ) ) | 1036 | #if ( LCD_WIDTH > ( CARD_WIDTH * 8 ) ) |
897 | # define BIG_SCREEN 1 | 1037 | # define BIG_SCREEN 1 |
@@ -900,416 +1040,254 @@ unsigned char move_card(unsigned char dest_col, unsigned char src_card){ | |||
900 | #endif | 1040 | #endif |
901 | #define LCD_WIDTH2 (LCD_WIDTH - BIG_SCREEN) | 1041 | #define LCD_WIDTH2 (LCD_WIDTH - BIG_SCREEN) |
902 | 1042 | ||
903 | /* the game */ | 1043 | int solitaire( void ) |
904 | int solitaire(void){ | 1044 | { |
905 | 1045 | ||
906 | int i,j,x; | 1046 | int i,j; |
907 | int button, lastbutton = 0; | 1047 | int button, lastbutton = 0; |
908 | unsigned char c,h,prevcard; | 1048 | unsigned char c,h,prevcard; |
909 | int biggest_col_length; | 1049 | int biggest_col_length; |
910 | 1050 | ||
911 | configfile_init(rb); | 1051 | configfile_init(rb); |
912 | configfile_load(FILENAME, config, 1, 0); | 1052 | configfile_load(CONFIG_FILENAME, config, 1, 0); |
913 | 1053 | ||
914 | rb->srand( *rb->current_tick ); | 1054 | rb->srand( *rb->current_tick ); |
915 | switch(solitaire_menu(draw_type==0?MENU_BEFOREGAME:MENU_BEFOREGAMEOP)) { | 1055 | switch( solitaire_menu( draw_type == 0 ? MENU_BEFOREGAME |
916 | case MENU_QUIT: | 1056 | : MENU_BEFOREGAMEOP ) ) |
1057 | { | ||
1058 | case MENU_QUIT: | ||
917 | return SOLITAIRE_QUIT; | 1059 | return SOLITAIRE_QUIT; |
918 | 1060 | ||
919 | case MENU_USB: | 1061 | case MENU_USB: |
920 | return SOLITAIRE_USB; | 1062 | return SOLITAIRE_USB; |
921 | case MENU_OPT: | 1063 | |
922 | draw_type=change_draw(draw_type); | 1064 | case MENU_OPT: |
923 | configfile_save(FILENAME, config, 1, 0); | 1065 | draw_type = (draw_type+1)%2; |
924 | when=draw_type==0?MENU_BEFOREGAME:MENU_BEFOREGAMEOP; | 1066 | configfile_save(CONFIG_FILENAME, config, 1, 0); |
925 | return 0; | 1067 | return 0; |
926 | } | 1068 | } |
1069 | solitaire_init(); | ||
1070 | |||
1071 | while( true ) | ||
1072 | { | ||
1073 | |||
927 | #if LCD_DEPTH>1 | 1074 | #if LCD_DEPTH>1 |
928 | rb->lcd_set_foreground(LCD_BLACK); | 1075 | rb->lcd_set_foreground(LCD_BLACK); |
929 | #ifdef HAVE_LCD_COLOR | 1076 | #ifdef HAVE_LCD_COLOR |
930 | rb->lcd_set_background(background_color); | 1077 | rb->lcd_set_background(BACKGROUND_COLOR); |
931 | #else | ||
932 | rb->lcd_set_background(LCD_DEFAULT_BG); | ||
933 | #endif | 1078 | #endif |
934 | #endif | 1079 | #endif |
935 | solitaire_init(); | ||
936 | |||
937 | while(true){ | ||
938 | |||
939 | rb->lcd_clear_display(); | 1080 | rb->lcd_clear_display(); |
940 | 1081 | ||
1082 | #if LCD_DEPTH > 1 | ||
1083 | rb->lcd_set_foreground(LCD_BLACK); | ||
1084 | rb->lcd_set_background(LCD_WHITE); | ||
1085 | #endif | ||
1086 | |||
941 | /* get the biggest column length so that display can be "optimized" */ | 1087 | /* get the biggest column length so that display can be "optimized" */ |
942 | biggest_col_length = 0; | 1088 | biggest_col_length = 0; |
943 | 1089 | ||
944 | for(i=0;i<COL_NUM;i++){ | 1090 | for(i=0;i<COL_NUM;i++) |
1091 | { | ||
945 | j = 0; | 1092 | j = 0; |
946 | c = cols[i]; | 1093 | c = cols[i]; |
947 | while(c != NOT_A_CARD){ | 1094 | while( c != NOT_A_CARD ) |
1095 | { | ||
948 | j++; | 1096 | j++; |
949 | c = deck[c].next; | 1097 | c = deck[c].next; |
950 | } | 1098 | } |
951 | if(j>biggest_col_length) biggest_col_length = j; | 1099 | if( j > biggest_col_length ) biggest_col_length = j; |
952 | } | 1100 | } |
953 | 1101 | ||
954 | /* check if there are cards remaining in the game. */ | 1102 | /* check if there are cards remaining in the game. */ |
955 | /* if there aren't any, that means you won :) */ | 1103 | /* if there aren't any, that means you won :) */ |
956 | if(biggest_col_length == 0 && rem == NOT_A_CARD){ | 1104 | if( biggest_col_length == 0 && rem == NOT_A_CARD ) |
957 | rb->splash(HZ*2, true, "You Won :)"); | 1105 | { |
1106 | rb->splash( HZ*2, true, "You Won :)" ); | ||
958 | return SOLITAIRE_WIN; | 1107 | return SOLITAIRE_WIN; |
959 | } | 1108 | } |
960 | 1109 | ||
961 | /* draw the columns */ | 1110 | /* draw the columns */ |
962 | for(i=0;i<COL_NUM;i++){ | 1111 | for( i = 0; i < COL_NUM; i++ ) |
1112 | { | ||
963 | c = cols[i]; | 1113 | c = cols[i]; |
964 | j = CARD_START; | 1114 | j = CARD_START; |
965 | while(true){ | 1115 | while( true ) |
966 | if(c==NOT_A_CARD) { | 1116 | { |
1117 | if( c == NOT_A_CARD ) | ||
1118 | { | ||
967 | /* draw the cursor on empty columns */ | 1119 | /* draw the cursor on empty columns */ |
968 | if(cur_col == i){ | 1120 | if( cur_col == i ) |
969 | rb->lcd_set_drawmode(DRMODE_COMPLEMENT); | 1121 | { |
970 | rb->lcd_fillrect(1+i*(LCD_WIDTH-2)/COL_NUM+1, j+1, CARD_WIDTH-1, CARD_HEIGHT-1); | 1122 | draw_cursor( 1+i*(LCD_WIDTH - 2)/COL_NUM, j+1 ); |
971 | } | 1123 | } |
972 | break; | 1124 | break; |
973 | } | 1125 | } |
974 | /* clear the card's spot */ | ||
975 | 1126 | ||
976 | rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); | 1127 | draw_card( deck[c], 1+i*(LCD_WIDTH - 2)/COL_NUM, j+1, |
977 | rb->lcd_fillrect(1+i*(LCD_WIDTH - 2)/COL_NUM, j+1, CARD_WIDTH, CARD_HEIGHT-1); | 1128 | c == sel_card, c == cur_card, false ); |
978 | rb->lcd_set_drawmode(DRMODE_SOLID); | 1129 | |
979 | /* known card */ | 1130 | h = c; |
980 | if(deck[c].known == 1){ | 1131 | c = deck[c].next; |
981 | #if LCD_DEPTH>1 | 1132 | if( c == NOT_A_CARD ) break; |
982 | #ifdef HAVE_LCD_COLOR | 1133 | |
983 | rb->lcd_set_foreground(LCD_WHITE); | 1134 | /* This is where we change the spacing between cards so that |
984 | rb->lcd_set_background(LCD_WHITE); | 1135 | * they don't overflow out of the LCD */ |
985 | #else | 1136 | if( h == cur_card ) |
986 | rb->lcd_set_foreground(LCD_DEFAULT_BG); | 1137 | j += SUIT_HEIGHT+2; |
987 | rb->lcd_set_background(LCD_DEFAULT_BG); | 1138 | else |
988 | #endif | 1139 | j += min( SUIT_HEIGHT+2, |
989 | #endif | 1140 | (LCD_HEIGHT - CARD_START - CARD_HEIGHT)/biggest_col_length ); |
990 | rb->lcd_fillrect(1+i*(LCD_WIDTH - 2)/COL_NUM+1, j+1, CARD_WIDTH-1, CARD_HEIGHT-1); | ||
991 | #if LCD_DEPTH>1 | ||
992 | rb->lcd_set_foreground(colors[deck[c].suit]); | ||
993 | #endif | ||
994 | rb->lcd_mono_bitmap(numbers[deck[c].num], 1+i*(LCD_WIDTH - 2)/COL_NUM+1, j+1, BMPWIDTH_c, BMPHEIGHT_c); | ||
995 | rb->lcd_mono_bitmap(suits[deck[c].suit], 1+i*(LCD_WIDTH - 2)/COL_NUM+ BMPWIDTH_c +2, j+1, BMPWIDTH_c, BMPHEIGHT_c); | ||
996 | #if LCD_DEPTH>1 | ||
997 | rb->lcd_set_foreground(LCD_BLACK); | ||
998 | #ifdef HAVE_LCD_COLOR | ||
999 | rb->lcd_set_background(background_color); | ||
1000 | #endif | ||
1001 | #endif | ||
1002 | } else { | ||
1003 | #ifdef HAVE_LCD_COLOR | ||
1004 | rb->lcd_bitmap(solitaire_cardback, | ||
1005 | 1+i*(LCD_WIDTH - 2)/COL_NUM+1, j+1, | ||
1006 | BMPWIDTH_CARDBACK, BMPHEIGHT_CARDBACK); | ||
1007 | #endif | ||
1008 | } | ||
1009 | /* draw top line of the card */ | ||
1010 | rb->lcd_drawline(1+i*(LCD_WIDTH - 2)/COL_NUM+1,j,1+i*(LCD_WIDTH - 2)/COL_NUM+CARD_WIDTH-1,j); | ||
1011 | /* selected card */ | ||
1012 | if(c == sel_card && sel_card != NOT_A_CARD){ | ||
1013 | rb->lcd_drawrect(1+i*(LCD_WIDTH - 2)/COL_NUM+1, j+1, CARD_WIDTH-1, CARD_HEIGHT-1); | ||
1014 | } | ||
1015 | /* cursor (or not) */ | ||
1016 | if(c == cur_card){ | ||
1017 | rb->lcd_set_drawmode(DRMODE_COMPLEMENT); | ||
1018 | rb->lcd_fillrect(1+i*(LCD_WIDTH - 2)/COL_NUM+1, j+1, CARD_WIDTH-1, CARD_HEIGHT-1); | ||
1019 | rb->lcd_set_drawmode(DRMODE_SOLID); | ||
1020 | /* go to the next card */ | ||
1021 | c = deck[c].next; | ||
1022 | if(c == NOT_A_CARD) break; | ||
1023 | else { | ||
1024 | if(deck[c].known == 0) { | ||
1025 | j += CARD_HEIGHT - NOT_KNOWN_CARD; | ||
1026 | } else { | ||
1027 | j += CARD_HEIGHT - KNOWN_CARD; | ||
1028 | } | ||
1029 | } | ||
1030 | } else { | ||
1031 | /* go to the next card */ | ||
1032 | h = c; | ||
1033 | c = deck[c].next; | ||
1034 | if(c == NOT_A_CARD) break; | ||
1035 | if(c!=NOT_A_CARD) { | ||
1036 | if(deck[h].known == 0) { | ||
1037 | /*changeeee*/ j += CARD_HEIGHT - NOT_KNOWN_CARD; | ||
1038 | } else { | ||
1039 | j += min(CARD_HEIGHT - KNOWN_CARD, (LCD_HEIGHT - CARD_START - CARD_HEIGHT)/biggest_col_length); | ||
1040 | } | ||
1041 | } | ||
1042 | } | ||
1043 | } | ||
1044 | if(cols[i]!=NOT_A_CARD){ | ||
1045 | /* draw line to the left of the column */ | ||
1046 | rb->lcd_drawline(1+i*(LCD_WIDTH - 2)/COL_NUM,CARD_START,1+i*(LCD_WIDTH - 2)/COL_NUM,j+CARD_HEIGHT-1); | ||
1047 | /* draw line to the right of the column */ | ||
1048 | rb->lcd_drawline(1+i*(LCD_WIDTH - 2)/COL_NUM+CARD_WIDTH,CARD_START,1+i*(LCD_WIDTH - 2)/COL_NUM+CARD_WIDTH,j+CARD_HEIGHT-1); | ||
1049 | /* draw bottom of the last card */ | ||
1050 | rb->lcd_drawline(1+i*(LCD_WIDTH - 2)/COL_NUM+1,j+CARD_HEIGHT,1+i*(LCD_WIDTH - 2)/COL_NUM+CARD_WIDTH-1,j+CARD_HEIGHT); | ||
1051 | } | 1141 | } |
1052 | } | 1142 | } |
1053 | #if LCD_DEPTH>1 | ||
1054 | rb->lcd_set_foreground(LCD_BLACK); | ||
1055 | #ifdef HAVE_LCD_COLOR | ||
1056 | rb->lcd_set_background(background_color); | ||
1057 | #endif | ||
1058 | #endif | ||
1059 | rb->lcd_set_drawmode(DRMODE_SOLID); | ||
1060 | /* draw the stacks */ | ||
1061 | for(i=0; i<SUITS; i++){ | ||
1062 | c = stacks[i]; | ||
1063 | if(c!=NOT_A_CARD){ | ||
1064 | while(deck[c].next != NOT_A_CARD){ | ||
1065 | c = deck[c].next; | ||
1066 | } | ||
1067 | } | ||
1068 | 1143 | ||
1069 | if(c != NOT_A_CARD) { | 1144 | /* draw the stacks */ |
1070 | #if LCD_DEPTH>1 | 1145 | for( i=0; i<SUITS; i++ ) |
1071 | #ifdef HAVE_LCD_COLOR | 1146 | { |
1072 | rb->lcd_set_foreground(LCD_WHITE); | 1147 | c = find_last_card( STACKS_COL + i ); |
1073 | rb->lcd_set_background(LCD_WHITE); | 1148 | |
1074 | #else | 1149 | if( c != NOT_A_CARD ) |
1075 | rb->lcd_set_foreground(LCD_DEFAULT_BG); | 1150 | { |
1076 | rb->lcd_set_background(LCD_DEFAULT_BG); | 1151 | draw_card( deck[c], |
1077 | #endif | 1152 | LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+1, 2, |
1078 | #endif | 1153 | c == sel_card, cur_col == STACKS_COL + i, false ); |
1079 | rb->lcd_fillrect(LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+1, 2, CARD_WIDTH-1, CARD_HEIGHT-1); | ||
1080 | #if LCD_DEPTH>1 | ||
1081 | rb->lcd_set_foreground(colors[i]); | ||
1082 | #endif | ||
1083 | rb->lcd_mono_bitmap(numbers[deck[c].num], LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+1, 2, BMPWIDTH_c, BMPHEIGHT_c); | ||
1084 | rb->lcd_mono_bitmap(suits[deck[c].suit], LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+10, 2, BMPWIDTH_c, BMPHEIGHT_c); | ||
1085 | } else { | ||
1086 | #if LCD_DEPTH>1 | ||
1087 | #ifdef HAVE_LCD_COLOR | ||
1088 | rb->lcd_set_foreground(LCD_WHITE); | ||
1089 | rb->lcd_set_background(LCD_WHITE); | ||
1090 | #else | ||
1091 | rb->lcd_set_foreground(LCD_DEFAULT_BG); | ||
1092 | rb->lcd_set_background(LCD_DEFAULT_BG); | ||
1093 | #endif | ||
1094 | #endif | ||
1095 | rb->lcd_fillrect(LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+1, 2, CARD_WIDTH-1, CARD_HEIGHT-1); | ||
1096 | #if LCD_DEPTH>1 | ||
1097 | rb->lcd_set_foreground(colors[i]); | ||
1098 | #endif | ||
1099 | #ifdef HAVE_LCD_COLOR | ||
1100 | rb->lcd_mono_bitmap(suitsi[i], LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+(CARD_WIDTH/2-7), CARD_HEIGHT/2-7, 15, 16); | ||
1101 | #endif | ||
1102 | } | ||
1103 | #if LCD_DEPTH>1 | ||
1104 | rb->lcd_set_foreground(LCD_BLACK); | ||
1105 | #ifdef HAVE_LCD_COLOR | ||
1106 | rb->lcd_set_background(background_color); | ||
1107 | #endif | ||
1108 | #endif | ||
1109 | /* draw a selected card */ | ||
1110 | if(c != NOT_A_CARD) { | ||
1111 | if(sel_card == c){ | ||
1112 | rb->lcd_drawrect(LCD_WIDTH2 -(CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+1, 2, CARD_WIDTH-1, CARD_HEIGHT-1); | ||
1113 | } | ||
1114 | } | 1154 | } |
1115 | rb->lcd_drawline(LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+1, 1,LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+CARD_WIDTH,1); | 1155 | else |
1116 | rb->lcd_drawline(LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2 ,2,LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2,CARD_HEIGHT); | 1156 | { |
1117 | rb->lcd_drawline(LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+1,CARD_HEIGHT+1,LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+CARD_WIDTH - 1,CARD_HEIGHT+1); | 1157 | draw_empty_stack( i, |
1118 | #if BIG_SCREEN | 1158 | LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+1, 2, |
1119 | rb->lcd_drawline(LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+CARD_WIDTH,2,LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+CARD_WIDTH,CARD_HEIGHT); | 1159 | cur_col == STACKS_COL + i ); |
1120 | #endif | ||
1121 | /* draw the cursor on one of the stacks */ | ||
1122 | if(cur_col == STACKS_COL + i){ | ||
1123 | rb->lcd_set_drawmode(DRMODE_COMPLEMENT); | ||
1124 | rb->lcd_fillrect(LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+1, 2, CARD_WIDTH-1, CARD_HEIGHT-1); | ||
1125 | rb->lcd_set_drawmode(DRMODE_SOLID); | ||
1126 | } | 1160 | } |
1127 | } | 1161 | } |
1128 | 1162 | ||
1129 | /* draw the remains */ | 1163 | /* draw the remains */ |
1130 | 1164 | if( rem != NOT_A_CARD ) | |
1131 | 1165 | { | |
1132 | if(rem != NOT_A_CARD) { | 1166 | coun_rem = coun_rem>2 ? coun_rem=2 : coun_rem; |
1133 | coun_rem = coun_rem>2?coun_rem=2:coun_rem; | 1167 | if( cur_rem != NOT_A_CARD |
1134 | if(cur_rem != NOT_A_CARD && find_prev_card(cur_rem) != NOT_A_CARD && CARDS_PER_DRAW != 1) { | 1168 | && find_prev_card(cur_rem) != NOT_A_CARD |
1135 | j = (coun_rem)*(BMPWIDTH_c+2); | 1169 | && cards_per_draw != 1 ) |
1136 | for(i=0;i<=coun_rem;i++) { | 1170 | { |
1137 | if (i>0 && i<3){ | 1171 | j = 0; |
1138 | #if LCD_DEPTH>1 | 1172 | prevcard = cur_rem; |
1139 | #ifdef HAVE_LCD_COLOR | 1173 | for( i = 0; i < coun_rem; i++ ) |
1140 | rb->lcd_set_foreground(LCD_WHITE); | 1174 | prevcard = find_prev_card(prevcard); |
1141 | rb->lcd_set_background(LCD_WHITE); | 1175 | for( i = 0; i <= coun_rem; i++ ) |
1142 | #else | 1176 | { |
1143 | rb->lcd_set_foreground(LCD_DEFAULT_BG); | 1177 | draw_card( deck[prevcard], CARD_WIDTH+4+j+1, 2, |
1144 | rb->lcd_set_background(LCD_DEFAULT_BG); | 1178 | sel_card == prevcard, cur_card == prevcard, |
1145 | #endif | 1179 | i < coun_rem ); |
1146 | #endif | 1180 | prevcard = deck[prevcard].next; |
1147 | rb->lcd_fillrect(CARD_WIDTH+4+j+1, 2, BMPWIDTH_c+1, CARD_HEIGHT-1); | 1181 | j += NUMBER_WIDTH+2; |
1148 | #if LCD_DEPTH>1 | ||
1149 | rb->lcd_set_foreground(LCD_BLACK); | ||
1150 | #endif | ||
1151 | rb->lcd_drawline(CARD_WIDTH+4+j+1,1,CARD_WIDTH+4+j+BMPWIDTH_c+2,1); /* top line */ | ||
1152 | rb->lcd_drawline(CARD_WIDTH+4+j+1,CARD_HEIGHT+1,CARD_WIDTH+4+j+BMPWIDTH_c+2,CARD_HEIGHT+1); /* bottom line */ | ||
1153 | rb->lcd_drawline(CARD_WIDTH+4+j,2,CARD_WIDTH+4+j,CARD_HEIGHT); /* right line */ | ||
1154 | |||
1155 | |||
1156 | prevcard = cur_rem; | ||
1157 | for(x=0;i>x;x++) | ||
1158 | prevcard = find_prev_card(prevcard); | ||
1159 | #if LCD_DEPTH>1 | ||
1160 | rb->lcd_set_foreground(colors[deck[prevcard].suit]); | ||
1161 | #ifdef HAVE_LCD_COLOR | ||
1162 | rb->lcd_set_background(LCD_WHITE); | ||
1163 | #endif | ||
1164 | #endif | ||
1165 | rb->lcd_mono_bitmap(numbers[deck[prevcard].num], CARD_WIDTH+4+j+1, 3, BMPWIDTH_c, BMPHEIGHT_c); | ||
1166 | rb->lcd_mono_bitmap(suits[deck[prevcard].suit], CARD_WIDTH+4+j+1, 4+BMPHEIGHT_c, BMPWIDTH_c, BMPHEIGHT_c); | ||
1167 | |||
1168 | |||
1169 | } | ||
1170 | j -= BMPWIDTH_c+2; | ||
1171 | } | ||
1172 | } | ||
1173 | #if LCD_DEPTH>1 | ||
1174 | rb->lcd_set_foreground(LCD_BLACK); | ||
1175 | #endif | ||
1176 | if(CARDS_PER_DRAW==1 || cur_rem==NOT_A_CARD) | ||
1177 | j=0; | ||
1178 | else | ||
1179 | j=(coun_rem)*(BMPWIDTH_c+2); | ||
1180 | if(cur_rem != NOT_A_CARD){ | ||
1181 | rb->lcd_drawline(CARD_WIDTH+4+j+1,1,CARD_WIDTH+4+j+CARD_WIDTH-1,1); /* top line */ | ||
1182 | rb->lcd_drawline(CARD_WIDTH+4+j,2,CARD_WIDTH+4+j,CARD_HEIGHT); /* left line */ | ||
1183 | rb->lcd_drawline(CARD_WIDTH+4+j+1,CARD_HEIGHT+1,CARD_WIDTH+4+j+CARD_WIDTH - 1,CARD_HEIGHT+1); /* bottom line */ | ||
1184 | rb->lcd_drawline(CARD_WIDTH+4+j+CARD_WIDTH,2,CARD_WIDTH+4+j+CARD_WIDTH,CARD_HEIGHT); /* right line */ | ||
1185 | } | ||
1186 | |||
1187 | rb->lcd_drawline(2,1,CARD_WIDTH+1,1); /* top line */ | ||
1188 | rb->lcd_drawline(1,2,1,CARD_HEIGHT); /* left line */ | ||
1189 | rb->lcd_drawline(2,CARD_HEIGHT+1,CARD_WIDTH + 1,CARD_HEIGHT+1); /* bottom line */ | ||
1190 | rb->lcd_drawline(CARD_WIDTH+2,2,CARD_WIDTH+2,CARD_HEIGHT); /* right line */ | ||
1191 | |||
1192 | if(cur_rem != NOT_A_CARD){ | ||
1193 | #if LCD_DEPTH>1 | ||
1194 | #ifdef HAVE_LCD_COLOR | ||
1195 | rb->lcd_set_foreground(LCD_WHITE); | ||
1196 | rb->lcd_set_background(LCD_WHITE); | ||
1197 | #else | ||
1198 | rb->lcd_set_foreground(LCD_DEFAULT_BG); | ||
1199 | rb->lcd_set_background(LCD_DEFAULT_BG); | ||
1200 | #endif | ||
1201 | #endif | ||
1202 | rb->lcd_fillrect(CARD_WIDTH+4+j+1, 2, CARD_WIDTH-1, CARD_HEIGHT-1); | ||
1203 | #if LCD_DEPTH>1 | ||
1204 | rb->lcd_set_foreground(colors[deck[cur_rem].suit]); | ||
1205 | #endif | ||
1206 | rb->lcd_mono_bitmap(numbers[deck[cur_rem].num], CARD_WIDTH+4+j+1, 3, BMPWIDTH_c, BMPHEIGHT_c); | ||
1207 | rb->lcd_mono_bitmap(suits[deck[cur_rem].suit], CARD_WIDTH+4+j+10, 3, BMPWIDTH_c, BMPHEIGHT_c); | ||
1208 | /* draw a selected card */ | ||
1209 | #if LCD_DEPTH>1 | ||
1210 | rb->lcd_set_foreground(LCD_BLACK); | ||
1211 | #ifdef HAVE_LCD_COLOR | ||
1212 | rb->lcd_set_background(background_color); | ||
1213 | #endif | ||
1214 | #endif | ||
1215 | if(sel_card == cur_rem){ | ||
1216 | rb->lcd_drawrect(CARD_WIDTH+4+j+1, 2,CARD_WIDTH-1, CARD_HEIGHT-1); | ||
1217 | } | ||
1218 | } | ||
1219 | if(rem != NOT_A_CARD){ | ||
1220 | #ifdef HAVE_LCD_COLOR | ||
1221 | rb->lcd_bitmap(solitaire_cardback, 2, 2, | ||
1222 | BMPWIDTH_CARDBACK, BMPHEIGHT_CARDBACK); | ||
1223 | #endif | ||
1224 | } | 1182 | } |
1225 | } | 1183 | } |
1184 | else if( cur_rem == NOT_A_CARD && cur_col == REM_COL ) | ||
1185 | { | ||
1186 | draw_cursor( CARD_WIDTH+4+1, 2 ); | ||
1187 | } | ||
1226 | 1188 | ||
1227 | 1189 | if( ( prevcard == NOT_A_CARD && rem != NOT_A_CARD ) | |
1228 | /* draw the cursor */ | 1190 | || deck[prevcard].next != NOT_A_CARD ) |
1229 | if(cur_col == REM_COL && rem != NOT_A_CARD){ | 1191 | { |
1230 | rb->lcd_set_drawmode(DRMODE_COMPLEMENT); | 1192 | /* gruik ! (we want to display a card back) */ |
1231 | rb->lcd_fillrect(CARD_WIDTH+4+j+1, 2,CARD_WIDTH-1, CARD_HEIGHT-1); | 1193 | deck[rem].known = false; |
1232 | rb->lcd_set_drawmode(DRMODE_SOLID); | 1194 | draw_card( deck[rem], 2, 2, false, false, false ); |
1233 | } else if(cur_col == REM_COL && rem == NOT_A_CARD) { | 1195 | deck[rem].known = true; |
1234 | rb->lcd_set_drawmode(DRMODE_COMPLEMENT); | 1196 | } |
1235 | rb->lcd_fillrect(CARD_WIDTH+4+1, 2,CARD_WIDTH-1, CARD_HEIGHT-1); | ||
1236 | rb->lcd_set_drawmode(DRMODE_SOLID); | ||
1237 | } | 1197 | } |
1238 | 1198 | ||
1239 | |||
1240 | rb->lcd_update(); | 1199 | rb->lcd_update(); |
1241 | 1200 | ||
1242 | /* what to do when a key is pressed ... */ | 1201 | /* what to do when a key is pressed ... */ |
1243 | button = rb->button_get(true); | 1202 | button = rb->button_get( true ); |
1244 | switch(button){ | 1203 | switch( button ) |
1245 | 1204 | { | |
1246 | /* move cursor to the last card of the previous column */ | 1205 | /* move cursor to the last card of the previous column |
1247 | /* or to the previous final stack */ | 1206 | * or to the previous final stack |
1248 | /* or to the remains stack */ | 1207 | * or to the remains stack */ |
1249 | case SOL_RIGHT: | 1208 | case SOL_RIGHT: |
1250 | #ifdef SOL_RIGHT_PRE | 1209 | #ifdef SOL_RIGHT_PRE |
1251 | if(lastbutton != SOL_RIGHT_PRE) | 1210 | if( lastbutton != SOL_RIGHT_PRE ) |
1252 | break; | 1211 | break; |
1253 | #endif | 1212 | #endif |
1254 | if(cur_col >= COL_NUM){ | 1213 | if( cur_col >= COL_NUM ) |
1214 | { | ||
1255 | cur_col = 0; | 1215 | cur_col = 0; |
1256 | } else if(cur_col == COL_NUM - 1){ | 1216 | } |
1217 | else if( cur_col == COL_NUM - 1 ) | ||
1218 | { | ||
1257 | cur_col = REM_COL; | 1219 | cur_col = REM_COL; |
1258 | } else { | 1220 | } |
1221 | else | ||
1222 | { | ||
1259 | cur_col = (cur_col+1)%(REM_COL+1); | 1223 | cur_col = (cur_col+1)%(REM_COL+1); |
1260 | } | 1224 | } |
1261 | if(cur_col == REM_COL){ | 1225 | if(cur_col == REM_COL) |
1226 | { | ||
1262 | cur_card = cur_rem; | 1227 | cur_card = cur_rem; |
1263 | break; | 1228 | break; |
1264 | } | 1229 | } |
1265 | cur_card = find_last_card(cur_col); | 1230 | cur_card = find_last_card( cur_col ); |
1266 | break; | 1231 | break; |
1267 | 1232 | ||
1268 | /* move cursor to the last card of the next column */ | 1233 | /* move cursor to the last card of the next column |
1269 | /* or to the next final stack */ | 1234 | * or to the next final stack |
1270 | /* or to the remains stack */ | 1235 | * or to the remains stack */ |
1271 | case SOL_LEFT: | 1236 | case SOL_LEFT: |
1272 | #ifdef SOL_LEFT_PRE | 1237 | #ifdef SOL_LEFT_PRE |
1273 | if(lastbutton != SOL_LEFT_PRE) | 1238 | if( lastbutton != SOL_LEFT_PRE ) |
1274 | break; | 1239 | break; |
1275 | #endif | 1240 | #endif |
1276 | if(cur_col == 0){ | 1241 | if( cur_col == 0 ) |
1242 | { | ||
1277 | cur_col = REM_COL; | 1243 | cur_col = REM_COL; |
1278 | } else if(cur_col >= COL_NUM) { | 1244 | } |
1245 | else if( cur_col >= COL_NUM ) | ||
1246 | { | ||
1279 | cur_col = COL_NUM - 1; | 1247 | cur_col = COL_NUM - 1; |
1280 | } else { | 1248 | } |
1249 | else | ||
1250 | { | ||
1281 | cur_col = (cur_col + REM_COL)%(REM_COL+1); | 1251 | cur_col = (cur_col + REM_COL)%(REM_COL+1); |
1282 | } | 1252 | } |
1283 | if(cur_col == REM_COL){ | 1253 | if( cur_col == REM_COL ) |
1254 | { | ||
1284 | cur_card = cur_rem; | 1255 | cur_card = cur_rem; |
1285 | break; | 1256 | break; |
1286 | } | 1257 | } |
1287 | cur_card = find_last_card(cur_col); | 1258 | cur_card = find_last_card( cur_col ); |
1288 | break; | 1259 | break; |
1289 | 1260 | ||
1290 | /* move cursor to card that's bellow */ | 1261 | /* move cursor to card that's bellow */ |
1291 | case SOL_DOWN: | 1262 | case SOL_DOWN: |
1292 | #ifdef SOL_DOWN_PRE | 1263 | #ifdef SOL_DOWN_PRE |
1293 | if(lastbutton != SOL_DOWN_PRE) | 1264 | if( lastbutton != SOL_DOWN_PRE ) |
1294 | break; | 1265 | break; |
1295 | #endif | 1266 | #endif |
1296 | if(cur_col >= COL_NUM) { | 1267 | if( cur_col >= COL_NUM ) |
1268 | { | ||
1297 | cur_col = (cur_col - COL_NUM + 1)%(SUITS + 1) + COL_NUM; | 1269 | cur_col = (cur_col - COL_NUM + 1)%(SUITS + 1) + COL_NUM; |
1298 | if(cur_col == REM_COL){ | 1270 | if( cur_col == REM_COL ) |
1271 | { | ||
1299 | cur_card = cur_rem; | 1272 | cur_card = cur_rem; |
1300 | } | 1273 | } |
1301 | else { | 1274 | else |
1302 | cur_card = find_last_card(cur_col); | 1275 | { |
1276 | cur_card = find_last_card( cur_col ); | ||
1303 | } | 1277 | } |
1304 | break; | 1278 | break; |
1305 | } | 1279 | } |
1306 | if(cur_card == NOT_A_CARD) break; | 1280 | if( cur_card == NOT_A_CARD ) break; |
1307 | if(deck[cur_card].next != NOT_A_CARD){ | 1281 | if( deck[cur_card].next != NOT_A_CARD ) |
1282 | { | ||
1308 | cur_card = deck[cur_card].next; | 1283 | cur_card = deck[cur_card].next; |
1309 | } else { | 1284 | } |
1285 | else | ||
1286 | { | ||
1310 | cur_card = cols[cur_col]; | 1287 | cur_card = cols[cur_col]; |
1311 | while(deck[cur_card].known == 0 | 1288 | while( deck[ cur_card].known == 0 |
1312 | && deck[cur_card].next != NOT_A_CARD){ | 1289 | && deck[cur_card].next != NOT_A_CARD ) |
1290 | { | ||
1313 | cur_card = deck[cur_card].next; | 1291 | cur_card = deck[cur_card].next; |
1314 | } | 1292 | } |
1315 | } | 1293 | } |
@@ -1318,36 +1296,42 @@ int solitaire(void){ | |||
1318 | /* move cursor to card that's above */ | 1296 | /* move cursor to card that's above */ |
1319 | case SOL_UP: | 1297 | case SOL_UP: |
1320 | #ifdef SOL_UP_PRE | 1298 | #ifdef SOL_UP_PRE |
1321 | if(lastbutton != SOL_UP_PRE) | 1299 | if( lastbutton != SOL_UP_PRE ) |
1322 | break; | 1300 | break; |
1323 | #endif | 1301 | #endif |
1324 | if(cur_col >= COL_NUM) { | 1302 | if( cur_col >= COL_NUM ) |
1303 | { | ||
1325 | cur_col = (cur_col - COL_NUM + SUITS)%(SUITS + 1) + COL_NUM; | 1304 | cur_col = (cur_col - COL_NUM + SUITS)%(SUITS + 1) + COL_NUM; |
1326 | if(cur_col == REM_COL){ | 1305 | if( cur_col == REM_COL ) |
1306 | { | ||
1327 | cur_card = cur_rem; | 1307 | cur_card = cur_rem; |
1328 | } else { | 1308 | } |
1329 | cur_card = find_last_card(cur_col); | 1309 | else |
1310 | { | ||
1311 | cur_card = find_last_card( cur_col ); | ||
1330 | } | 1312 | } |
1331 | break; | 1313 | break; |
1332 | } | 1314 | } |
1333 | if(cur_card == NOT_A_CARD) break; | 1315 | if( cur_card == NOT_A_CARD ) break; |
1334 | do{ | 1316 | do { |
1335 | cur_card = find_prev_card(cur_card); | 1317 | cur_card = find_prev_card( cur_card ); |
1336 | if(cur_card == NOT_A_CARD){ | 1318 | if( cur_card == NOT_A_CARD ) |
1337 | cur_card = find_last_card(cur_col); | 1319 | { |
1320 | cur_card = find_last_card( cur_col ); | ||
1338 | } | 1321 | } |
1339 | } while (deck[cur_card].next != NOT_A_CARD | 1322 | } while( deck[cur_card].next != NOT_A_CARD |
1340 | && deck[cur_card].known == 0); | 1323 | && deck[cur_card].known == 0 ); |
1341 | break; | 1324 | break; |
1342 | 1325 | ||
1343 | /* Try to put card under cursor on one of the stacks */ | 1326 | /* Try to put card under cursor on one of the stacks */ |
1344 | case SOL_CUR2STACK: | 1327 | case SOL_CUR2STACK: |
1345 | #ifdef SOL_CUR2STACK_PRE | 1328 | #ifdef SOL_CUR2STACK_PRE |
1346 | if(lastbutton != SOL_CUR2STACK_PRE) | 1329 | if( lastbutton != SOL_CUR2STACK_PRE ) |
1347 | break; | 1330 | break; |
1348 | #endif | 1331 | #endif |
1349 | if(cur_card != NOT_A_CARD){ | 1332 | if( cur_card != NOT_A_CARD ) |
1350 | move_card(deck[cur_card].suit + STACKS_COL, cur_card); | 1333 | { |
1334 | move_card( deck[cur_card].suit + STACKS_COL, cur_card ); | ||
1351 | sel_card = NOT_A_CARD; | 1335 | sel_card = NOT_A_CARD; |
1352 | } | 1336 | } |
1353 | break; | 1337 | break; |
@@ -1355,116 +1339,141 @@ int solitaire(void){ | |||
1355 | /* Move cards arround, Uncover cards, ... */ | 1339 | /* Move cards arround, Uncover cards, ... */ |
1356 | case SOL_MOVE: | 1340 | case SOL_MOVE: |
1357 | #ifdef SOL_MOVE_PRE | 1341 | #ifdef SOL_MOVE_PRE |
1358 | if(lastbutton != SOL_MOVE_PRE) | 1342 | if( lastbutton != SOL_MOVE_PRE ) |
1359 | break; | 1343 | break; |
1360 | #endif | 1344 | #endif |
1361 | 1345 | ||
1362 | if(sel_card == NOT_A_CARD) { | 1346 | if( sel_card == NOT_A_CARD ) |
1363 | if(cur_card != NOT_A_CARD) { | 1347 | { |
1364 | /* reveal a hidden card */ | 1348 | if( cur_card != NOT_A_CARD ) |
1365 | if(deck[cur_card].next == NOT_A_CARD && deck[cur_card].known==0){ | 1349 | { |
1350 | if( deck[cur_card].next == NOT_A_CARD | ||
1351 | && deck[cur_card].known == 0 ) | ||
1352 | { | ||
1353 | /* reveal a hidden card */ | ||
1366 | deck[cur_card].known = 1; | 1354 | deck[cur_card].known = 1; |
1367 | } else if(cur_col == REM_COL && cur_rem == NOT_A_CARD) { | 1355 | } |
1356 | else if( cur_col == REM_COL && cur_rem == NOT_A_CARD ) | ||
1357 | { | ||
1368 | break; | 1358 | break; |
1369 | /* select a card */ | 1359 | } |
1370 | } else { | 1360 | else |
1361 | { | ||
1362 | /* select a card */ | ||
1371 | sel_card = cur_card; | 1363 | sel_card = cur_card; |
1372 | } | 1364 | } |
1373 | } | 1365 | } |
1374 | /* unselect card or try putting card on one of the 4 stacks */ | 1366 | } |
1375 | } else if(sel_card == cur_card) { | 1367 | else if( sel_card == cur_card ) |
1376 | move_card(deck[sel_card].suit + COL_NUM, sel_card); | 1368 | { |
1369 | /* unselect card or try putting card on | ||
1370 | * one of the 4 stacks */ | ||
1371 | move_card( deck[sel_card].suit + COL_NUM, sel_card ); | ||
1377 | sel_card = NOT_A_CARD; | 1372 | sel_card = NOT_A_CARD; |
1378 | if( cur_col == REM_COL ) | 1373 | if( cur_col == REM_COL ) |
1379 | { | 1374 | { |
1380 | cur_card = cur_rem; | 1375 | cur_card = cur_rem; |
1381 | } | 1376 | } |
1382 | /* try moving cards */ | 1377 | } |
1383 | } else { | 1378 | else |
1384 | if(move_card(cur_col, sel_card) == MOVE_OK){ | 1379 | { |
1380 | /* try moving cards */ | ||
1381 | if( move_card( cur_col, sel_card ) == MOVE_OK ) | ||
1382 | { | ||
1385 | sel_card = NOT_A_CARD; | 1383 | sel_card = NOT_A_CARD; |
1386 | } | 1384 | } |
1387 | } | 1385 | } |
1388 | break; | 1386 | break; |
1389 | 1387 | ||
1390 | /* If the card on the top of the remains can be put where */ | 1388 | /* If the card on the top of the remains can be put where |
1391 | /* the cursor is, go ahead */ | 1389 | * the cursor is, go ahead */ |
1392 | case SOL_REM2CUR: | 1390 | case SOL_REM2CUR: |
1393 | #ifdef SOL_REM2CUR_PRE | 1391 | #ifdef SOL_REM2CUR_PRE |
1394 | if(lastbutton != SOL_REM2CUR_PRE) | 1392 | if( lastbutton != SOL_REM2CUR_PRE ) |
1395 | break; | 1393 | break; |
1396 | #endif | 1394 | #endif |
1397 | coun_rem = coun_rem-1; | 1395 | coun_rem = coun_rem-1; |
1398 | move_card(cur_col, cur_rem); | 1396 | move_card( cur_col, cur_rem ); |
1399 | sel_card = NOT_A_CARD; | 1397 | sel_card = NOT_A_CARD; |
1400 | break; | 1398 | break; |
1401 | 1399 | ||
1402 | /* If the card on top of the remains can be put on one */ | 1400 | /* If the card on top of the remains can be put on one |
1403 | /* of the stacks, do so */ | 1401 | * of the stacks, do so */ |
1404 | case SOL_REM2STACK: | 1402 | case SOL_REM2STACK: |
1405 | #ifdef SOL_REM2STACK_PRE | 1403 | #ifdef SOL_REM2STACK_PRE |
1406 | if(lastbutton != SOL_REM2STACK_PRE) | 1404 | if( lastbutton != SOL_REM2STACK_PRE ) |
1407 | break; | 1405 | break; |
1408 | #endif | 1406 | #endif |
1409 | if(cur_rem != NOT_A_CARD){ | 1407 | if( cur_rem != NOT_A_CARD ) |
1410 | move_card(deck[cur_rem].suit + COL_NUM, cur_rem); | 1408 | { |
1409 | move_card( deck[cur_rem].suit + COL_NUM, cur_rem ); | ||
1411 | sel_card = NOT_A_CARD; | 1410 | sel_card = NOT_A_CARD; |
1412 | coun_rem = coun_rem-1; | 1411 | coun_rem = coun_rem-1; |
1413 | } | 1412 | } |
1414 | break; | 1413 | break; |
1415 | 1414 | ||
1416 | |||
1417 | #ifdef SOL_REM | 1415 | #ifdef SOL_REM |
1418 | case SOL_REM: | 1416 | case SOL_REM: |
1419 | if(sel_card != NOT_A_CARD){ | 1417 | if( sel_card != NOT_A_CARD ) |
1418 | { | ||
1420 | /* unselect selected card */ | 1419 | /* unselect selected card */ |
1421 | sel_card = NOT_A_CARD; | 1420 | sel_card = NOT_A_CARD; |
1422 | break; | 1421 | break; |
1423 | } | 1422 | } |
1424 | if(rem != NOT_A_CARD && cur_rem != NOT_A_CARD) { | 1423 | if( rem != NOT_A_CARD && cur_rem != NOT_A_CARD ) |
1425 | sel_card=cur_rem; | 1424 | { |
1426 | break; | 1425 | sel_card=cur_rem; |
1426 | break; | ||
1427 | } | 1427 | } |
1428 | break; | 1428 | break; |
1429 | #endif | 1429 | #endif |
1430 | 1430 | ||
1431 | /* unselect selected card or ... */ | 1431 | /* unselect selected card or ... |
1432 | /* draw new cards from the remains of the deck */ | 1432 | * draw new cards from the remains of the deck */ |
1433 | case SOL_DRAW: | 1433 | case SOL_DRAW: |
1434 | #ifdef SOL_DRAW_PRE | 1434 | #ifdef SOL_DRAW_PRE |
1435 | if(lastbutton != SOL_DRAW_PRE) | 1435 | if( lastbutton != SOL_DRAW_PRE ) |
1436 | break; | 1436 | break; |
1437 | #endif | 1437 | #endif |
1438 | if(sel_card != NOT_A_CARD){ | 1438 | if( sel_card != NOT_A_CARD ) |
1439 | { | ||
1439 | /* unselect selected card */ | 1440 | /* unselect selected card */ |
1440 | sel_card = NOT_A_CARD; | 1441 | sel_card = NOT_A_CARD; |
1441 | break; | 1442 | break; |
1442 | } | 1443 | } |
1443 | if(rem != NOT_A_CARD) { | 1444 | if( rem != NOT_A_CARD ) |
1445 | { | ||
1444 | int cur_rem_old = cur_rem; | 1446 | int cur_rem_old = cur_rem; |
1445 | coun_rem = 0; | 1447 | coun_rem = 0; |
1446 | /* draw new cards form the remains of the deck */ | 1448 | /* draw new cards form the remains of the deck */ |
1447 | if(cur_rem == NOT_A_CARD){ /*if the cursor card is null*/ | 1449 | if( cur_rem == NOT_A_CARD ) |
1450 | { | ||
1451 | /*if the cursor card is null*/ | ||
1448 | cur_rem = rem; | 1452 | cur_rem = rem; |
1449 | i = CARDS_PER_DRAW - 1; | 1453 | i = cards_per_draw - 1; |
1450 | } else { | 1454 | } |
1451 | i = CARDS_PER_DRAW; | 1455 | else |
1456 | { | ||
1457 | i = cards_per_draw; | ||
1452 | } | 1458 | } |
1453 | 1459 | ||
1454 | while(i>0 && deck[cur_rem].next != NOT_A_CARD){ | 1460 | while( i > 0 && deck[cur_rem].next != NOT_A_CARD ) |
1461 | { | ||
1455 | cur_rem = deck[cur_rem].next; | 1462 | cur_rem = deck[cur_rem].next; |
1456 | i--; | 1463 | i--; |
1457 | coun_rem = coun_rem +1; | 1464 | coun_rem = coun_rem +1; |
1458 | } | 1465 | } |
1459 | /* test if any cards are really left on */ | 1466 | /* test if any cards are really left on |
1460 | /* the remains' stack */ | 1467 | * the remains' stack */ |
1461 | if(i == CARDS_PER_DRAW){ | 1468 | if( i == cards_per_draw ) |
1469 | { | ||
1462 | cur_rem = NOT_A_CARD; | 1470 | cur_rem = NOT_A_CARD; |
1463 | coun_rem = 0; | 1471 | coun_rem = 0; |
1464 | } | 1472 | } |
1465 | /* if cursor was on remains' stack when new cards were | 1473 | /* if cursor was on remains' stack when new cards were |
1466 | * drawn, put cursor on top of remains' stack */ | 1474 | * drawn, put cursor on top of remains' stack */ |
1467 | if(cur_col == REM_COL && cur_card == cur_rem_old) { | 1475 | if( cur_col == REM_COL && cur_card == cur_rem_old ) |
1476 | { | ||
1468 | cur_card = cur_rem; | 1477 | cur_card = cur_rem; |
1469 | sel_card = NOT_A_CARD; | 1478 | sel_card = NOT_A_CARD; |
1470 | } | 1479 | } |
@@ -1476,10 +1485,11 @@ int solitaire(void){ | |||
1476 | case SOL_RC_QUIT: | 1485 | case SOL_RC_QUIT: |
1477 | #endif | 1486 | #endif |
1478 | case SOL_QUIT: | 1487 | case SOL_QUIT: |
1479 | #if LCD_DEPTH>1 | 1488 | #if LCD_DEPTH > 1 |
1480 | rb->lcd_set_background(LCD_DEFAULT_BG); | 1489 | rb->lcd_set_background( LCD_DEFAULT_BG ); |
1481 | #endif | 1490 | #endif |
1482 | switch(solitaire_menu(MENU_DURINGGAME)){ | 1491 | switch( solitaire_menu( MENU_DURINGGAME ) ) |
1492 | { | ||
1483 | case MENU_QUIT: | 1493 | case MENU_QUIT: |
1484 | return SOLITAIRE_QUIT; | 1494 | return SOLITAIRE_QUIT; |
1485 | 1495 | ||
@@ -1490,44 +1500,49 @@ int solitaire(void){ | |||
1490 | solitaire_init(); | 1500 | solitaire_init(); |
1491 | break; | 1501 | break; |
1492 | } | 1502 | } |
1503 | break; | ||
1504 | |||
1493 | default: | 1505 | default: |
1494 | if(rb->default_event_handler(button) == SYS_USB_CONNECTED) | 1506 | if( rb->default_event_handler( button ) == SYS_USB_CONNECTED ) |
1495 | return SOLITAIRE_USB; | 1507 | return SOLITAIRE_USB; |
1496 | break; | 1508 | break; |
1497 | } | 1509 | } |
1498 | 1510 | ||
1499 | if(button != BUTTON_NONE) | 1511 | if( button != BUTTON_NONE ) |
1500 | lastbutton = button; | 1512 | lastbutton = button; |
1501 | 1513 | ||
1502 | /* fix incoherences concerning cur_col and cur_card */ | 1514 | /* fix incoherences concerning cur_col and cur_card */ |
1503 | c = find_card_col(cur_card); | 1515 | c = find_card_col( cur_card ); |
1504 | if(c != NOT_A_COL && c != cur_col) | 1516 | if( c != NOT_A_COL && c != cur_col ) |
1505 | cur_card = find_last_card(cur_col); | 1517 | cur_card = find_last_card( cur_col ); |
1506 | 1518 | ||
1507 | if(cur_card == NOT_A_CARD && find_last_card(cur_col) != NOT_A_CARD) | 1519 | if( cur_card == NOT_A_CARD |
1508 | cur_card = find_last_card(cur_col); | 1520 | && find_last_card( cur_col ) != NOT_A_CARD ) |
1521 | cur_card = find_last_card( cur_col ); | ||
1509 | } | 1522 | } |
1510 | } | 1523 | } |
1511 | 1524 | ||
1512 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | 1525 | /** |
1526 | * Plugin entry point | ||
1527 | */ | ||
1528 | |||
1529 | enum plugin_status plugin_start( struct plugin_api* api, void* parameter ) | ||
1513 | { | 1530 | { |
1514 | int result; | 1531 | int result; |
1515 | 1532 | ||
1516 | /* plugin init */ | 1533 | /* plugin init */ |
1517 | (void)parameter; | 1534 | (void)parameter; |
1518 | rb = api; | 1535 | rb = api; |
1519 | /* end of plugin init */ | ||
1520 | /* Welcome to Solitaire ! */ | ||
1521 | 1536 | ||
1522 | rb->splash(HZ, true, "Welcome to Solitaire !"); | 1537 | rb->splash( HZ, true, "Welcome to Solitaire!" ); |
1523 | 1538 | ||
1524 | /* play the game :) */ | 1539 | /* play the game :) |
1525 | /* Keep playing if a game was won (that means display the menu after */ | 1540 | * Keep playing if a game was won (that means display the menu after |
1526 | /* winning instead of quiting) */ | 1541 | * winning instead of quiting) */ |
1527 | while((result = solitaire()) == SOLITAIRE_WIN); | 1542 | while( ( result = solitaire() ) == SOLITAIRE_WIN ); |
1528 | 1543 | ||
1529 | /* Exit the plugin */ | 1544 | /* Exit the plugin */ |
1530 | return (result == SOLITAIRE_USB) ? PLUGIN_USB_CONNECTED : PLUGIN_OK; | 1545 | return ( result == SOLITAIRE_USB ) ? PLUGIN_USB_CONNECTED : PLUGIN_OK; |
1531 | } | 1546 | } |
1532 | 1547 | ||
1533 | #endif | 1548 | #endif |