diff options
author | Tom Ross <midgey@rockbox.org> | 2007-01-16 21:05:15 +0000 |
---|---|---|
committer | Tom Ross <midgey@rockbox.org> | 2007-01-16 21:05:15 +0000 |
commit | 913fea27fcecd907e9432f6c87970cd08b8aea28 (patch) | |
tree | 143c3401d2b7b655e68e1edd0c7758f37d50d00d /apps | |
parent | 285aa1b0a633616bfb3b289535a60786390e4d59 (diff) | |
download | rockbox-913fea27fcecd907e9432f6c87970cd08b8aea28.tar.gz rockbox-913fea27fcecd907e9432f6c87970cd08b8aea28.zip |
t! Initial version of a Blackjack plugin for bitmap-screen targets. Also includes the changes to the manual. Cross your fingers...
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12030 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/plugins/SOURCES | 1 | ||||
-rw-r--r-- | apps/plugins/blackjack.c | 1442 |
2 files changed, 1443 insertions, 0 deletions
diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES index f00ac71bed..72fdf7454e 100644 --- a/apps/plugins/SOURCES +++ b/apps/plugins/SOURCES | |||
@@ -43,6 +43,7 @@ jpeg.c | |||
43 | mandelbrot.c | 43 | mandelbrot.c |
44 | plasma.c | 44 | plasma.c |
45 | 45 | ||
46 | blackjack.c | ||
46 | bounce.c | 47 | bounce.c |
47 | #ifndef SANSA_E200 | 48 | #ifndef SANSA_E200 |
48 | bubbles.c | 49 | bubbles.c |
diff --git a/apps/plugins/blackjack.c b/apps/plugins/blackjack.c new file mode 100644 index 0000000000..775fc8c834 --- /dev/null +++ b/apps/plugins/blackjack.c | |||
@@ -0,0 +1,1442 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: blackjack.c,v 1.6 2006/11/21 20:528:13 midgey34 Exp $ | ||
9 | * | ||
10 | * Copyright (C) 2006 Tom Ross (midgey34@gmail.com) | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "plugin.h" | ||
21 | #include "solitaire_deck.h" | ||
22 | #include "solitaire_cardback.h" | ||
23 | |||
24 | PLUGIN_HEADER | ||
25 | |||
26 | /* save files */ | ||
27 | #define SCORE_FILE PLUGIN_DIR "/blackjack.score" | ||
28 | #define SAVE_FILE PLUGIN_DIR "/blackjack.save" | ||
29 | |||
30 | #define NUM_SCORES LCD_HEIGHT/8-2 | ||
31 | |||
32 | /* final game return status */ | ||
33 | #define BJ_END 3 | ||
34 | #define BJ_USB 2 | ||
35 | #define BJ_QUIT 1 | ||
36 | #define BJ_LOSE 0 | ||
37 | |||
38 | #if CONFIG_KEYPAD == RECORDER_PAD | ||
39 | #define BJACK_START BUTTON_ON | ||
40 | #define BJACK_QUIT BUTTON_OFF | ||
41 | #define BJACK_MAX (BUTTON_ON|BUTTON_UP) | ||
42 | #define BJACK_MIN (BUTTON_ON|BUTTON_DOWN) | ||
43 | #define BJACK_HIT BUTTON_F1 | ||
44 | #define BJACK_STAY BUTTON_F2 | ||
45 | #define BJACK_DOUBLEDOWN BUTTON_F3 | ||
46 | #define BJACK_SCORES BUTTON_RIGHT | ||
47 | #define BJACK_RESUME BUTTON_PLAY | ||
48 | #define BJACK_UP BUTTON_UP | ||
49 | #define BJACK_DOWN BUTTON_DOWN | ||
50 | #define BJACK_RIGHT BUTTON_RIGHT | ||
51 | #define BJACK_LEFT BUTTON_LEFT | ||
52 | |||
53 | #elif CONFIG_KEYPAD == ONDIO_PAD | ||
54 | #define BJACK_START BUTTON_MENU | ||
55 | #define BJACK_QUIT BUTTON_OFF | ||
56 | #define BJACK_MAX (BUTTON_MENU|BUTTON_UP) | ||
57 | #define BJACK_MIN (BUTTON_MENU|BUTTON_DOWN) | ||
58 | #define BJACK_HIT BUTTON_LEFT | ||
59 | #define BJACK_STAY BUTTON_RIGHT | ||
60 | #define BJACK_DOUBLEDOWN BUTTON_UP | ||
61 | #define BJACK_SCORES BUTTON_UP | ||
62 | #define BJACK_RESUME BUTTON_DOWN | ||
63 | #define BJACK_UP BUTTON_UP | ||
64 | #define BJACK_DOWN BUTTON_DOWN | ||
65 | #define BJACK_RIGHT BUTTON_RIGHT | ||
66 | #define BJACK_LEFT BUTTON_LEFT | ||
67 | |||
68 | #elif CONFIG_KEYPAD == IRIVER_H10_PAD | ||
69 | #define BJACK_START BUTTON_PLAY | ||
70 | #define BJACK_QUIT BUTTON_POWER | ||
71 | #define BJACK_MAX (BUTTON_PLAY|BUTTON_SCROLL_UP) | ||
72 | #define BJACK_MIN (BUTTON_PLAY|BUTTON_SCROLL_DOWN) | ||
73 | #define BJACK_HIT BUTTON_PLAY | ||
74 | #define BJACK_STAY BUTTON_FF | ||
75 | #define BJACK_DOUBLEDOWN BUTTON_REW | ||
76 | #define BJACK_SCORES BUTTON_LEFT | ||
77 | #define BJACK_RESUME BUTTON_RIGHT | ||
78 | #define BJACK_UP BUTTON_SCROLL_UP | ||
79 | #define BJACK_DOWN BUTTON_SCROLL_DOWN | ||
80 | #define BJACK_RIGHT BUTTON_RIGHT | ||
81 | #define BJACK_LEFT BUTTON_LEFT | ||
82 | |||
83 | #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ | ||
84 | (CONFIG_KEYPAD == IRIVER_H300_PAD) | ||
85 | #define BJACK_START BUTTON_ON | ||
86 | #define BJACK_QUIT BUTTON_OFF | ||
87 | #define BJACK_MAX (BUTTON_ON|BUTTON_UP) | ||
88 | #define BJACK_MIN (BUTTON_ON|BUTTON_DOWN) | ||
89 | #define BJACK_HIT BUTTON_ON | ||
90 | #define BJACK_STAY BUTTON_REC | ||
91 | #define BJACK_DOUBLEDOWN BUTTON_SELECT | ||
92 | #define BJACK_SCORES BUTTON_SELECT | ||
93 | #define BJACK_RESUME BUTTON_MODE | ||
94 | #define BJACK_UP BUTTON_UP | ||
95 | #define BJACK_DOWN BUTTON_DOWN | ||
96 | #define BJACK_RIGHT BUTTON_RIGHT | ||
97 | #define BJACK_LEFT BUTTON_LEFT | ||
98 | |||
99 | #elif (CONFIG_KEYPAD == IPOD_3G_PAD) || \ | ||
100 | (CONFIG_KEYPAD == IPOD_4G_PAD) | ||
101 | #define BJACK_START BUTTON_SELECT | ||
102 | #define BJACK_QUIT BUTTON_MENU | ||
103 | #define BJACK_MAX (BUTTON_SELECT|BUTTON_SCROLL_FWD) | ||
104 | #define BJACK_MIN (BUTTON_SELECT|BUTTON_SCROLL_BACK) | ||
105 | #define BJACK_HIT BUTTON_SELECT | ||
106 | #define BJACK_STAY BUTTON_RIGHT | ||
107 | #define BJACK_DOUBLEDOWN BUTTON_LEFT | ||
108 | #define BJACK_SCORES BUTTON_RIGHT | ||
109 | #define BJACK_RESUME BUTTON_PLAY | ||
110 | #define BJACK_UP BUTTON_SCROLL_FWD | ||
111 | #define BJACK_DOWN BUTTON_SCROLL_BACK | ||
112 | #define BJACK_RIGHT BUTTON_RIGHT | ||
113 | #define BJACK_LEFT BUTTON_LEFT | ||
114 | |||
115 | #elif CONFIG_KEYPAD == IAUDIO_X5_PAD | ||
116 | #define BJACK_START BUTTON_PLAY | ||
117 | #define BJACK_QUIT BUTTON_POWER | ||
118 | #define BJACK_MAX (BUTTON_PLAY|BUTTON_UP) | ||
119 | #define BJACK_MIN (BUTTON_PLAY|BUTTON_DOWN) | ||
120 | #define BJACK_HIT BUTTON_SELECT | ||
121 | #define BJACK_STAY BUTTON_REC | ||
122 | #define BJACK_DOUBLEDOWN BUTTON_PLAY | ||
123 | #define BJACK_SCORES BUTTON_RIGHT | ||
124 | #define BJACK_RESUME BUTTON_DOWN | ||
125 | #define BJACK_UP BUTTON_UP | ||
126 | #define BJACK_DOWN BUTTON_DOWN | ||
127 | #define BJACK_RIGHT BUTTON_RIGHT | ||
128 | #define BJACK_LEFT BUTTON_LEFT | ||
129 | |||
130 | #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD | ||
131 | #define BJACK_START BUTTON_MODE | ||
132 | #define BJACK_QUIT BUTTON_PLAY | ||
133 | #define BJACK_MAX (BUTTON_EQ|BUTTON_UP) | ||
134 | #define BJACK_MIN (BUTTON_EQ|BUTTON_DOWN) | ||
135 | #define BJACK_HIT BUTTON_EQ | ||
136 | #define BJACK_STAY BUTTON_MODE | ||
137 | #define BJACK_DOUBLEDOWN BUTTON_SELECT | ||
138 | #define BJACK_SCORES BUTTON_SELECT | ||
139 | #define BJACK_RESUME (BUTTON_EQ|BUTTON_MODE) | ||
140 | #define BJACK_UP BUTTON_UP | ||
141 | #define BJACK_DOWN BUTTON_DOWN | ||
142 | #define BJACK_RIGHT BUTTON_RIGHT | ||
143 | #define BJACK_LEFT BUTTON_LEFT | ||
144 | |||
145 | #elif CONFIG_KEYPAD == GIGABEAT_PAD | ||
146 | #define BJACK_START BUTTON_POWER | ||
147 | #define BJACK_QUIT BUTTON_A | ||
148 | #define BJACK_MAX BUTTON_VOL_UP | ||
149 | #define BJACK_MIN BUTTON_VOL_DOWN | ||
150 | #define BJACK_HIT BUTTON_VOL_UP | ||
151 | #define BJACK_STAY BUTTON_VOL_DOWN | ||
152 | #define BJACK_DOUBLEDOWN BUTTON_SELECT | ||
153 | #define BJACK_SCORES BUTTON_RIGHT | ||
154 | #define BJACK_RESUME BUTTON_MENU | ||
155 | #define BJACK_UP BUTTON_UP | ||
156 | #define BJACK_DOWN BUTTON_DOWN | ||
157 | #define BJACK_RIGHT BUTTON_RIGHT | ||
158 | #define BJACK_LEFT BUTTON_LEFT | ||
159 | |||
160 | #elif CONFIG_KEYPAD == SANSA_E200_PAD | ||
161 | #define BJACK_START BUTTON_SELECT | ||
162 | #define BJACK_QUIT BUTTON_POWER | ||
163 | #define BJACK_MAX (BUTTON_REC|BUTTON_UP) | ||
164 | #define BJACK_MIN (BUTTON_REC|BUTTON_DOWN) | ||
165 | #define BJACK_HIT BUTTON_SELECT | ||
166 | #define BJACK_STAY BUTTON_RIGHT | ||
167 | #define BJACK_DOUBLEDOWN BUTTON_LEFT | ||
168 | #define BJACK_SCORES BUTTON_UP | ||
169 | #define BJACK_RESUME BUTTON_REC | ||
170 | #define BJACK_UP BUTTON_SCROLL_UP | ||
171 | #define BJACK_DOWN BUTTON_SCROLL_DOWN | ||
172 | #define BJACK_RIGHT BUTTON_RIGHT | ||
173 | #define BJACK_LEFT BUTTON_LEFT | ||
174 | |||
175 | #elif CONFIG_KEYPAD == ELIO_TPJ1022_PAD | ||
176 | #define BJACK_START BUTTON_MAIN | ||
177 | #define BJACK_QUIT BUTTON_POWER | ||
178 | #define BJACK_MAX (BUTTON_REC|BUTTON_UP) | ||
179 | #define BJACK_MIN (BUTTON_REC|BUTTON_DOWN) | ||
180 | #define BJACK_HIT BUTTON_MAIN | ||
181 | #define BJACK_STAY BUTTON_MENU | ||
182 | #define BJACK_DOUBLEDOWN BUTTON_DOWN | ||
183 | #define BJACK_SCORES BUTTON_UP | ||
184 | #define BJACK_RESUME BUTTON_FF | ||
185 | #define BJACK_UP BUTTON_UP | ||
186 | #define BJACK_DOWN BUTTON_DOWN | ||
187 | #define BJACK_RIGHT BUTTON_RIGHT | ||
188 | #define BJACK_LEFT BUTTON_LEFT | ||
189 | |||
190 | #else | ||
191 | #error BLACKJACK: Unsupported keypad | ||
192 | #endif | ||
193 | |||
194 | #ifdef HAVE_LCD_COLOR | ||
195 | #define BG_COLOR LCD_RGBPACK(0,157,0) | ||
196 | #define FG_COLOR LCD_WHITE | ||
197 | #elif LCD_DEPTH > 1 | ||
198 | #define BG_COLOR LCD_WHITE | ||
199 | #define FG_COLOR LCD_BLACK | ||
200 | #endif | ||
201 | |||
202 | #define CARD_WIDTH BMPWIDTH_solitaire_cardback | ||
203 | #define CARD_HEIGHT BMPHEIGHT_solitaire_cardback | ||
204 | |||
205 | /* This is the max amount of cards onscreen before condensing */ | ||
206 | #define MAX_CARDS LCD_WIDTH/(CARD_WIDTH+4) | ||
207 | |||
208 | extern const fb_data solitaire_deck[]; | ||
209 | extern const fb_data solitaire_cardback[]; | ||
210 | |||
211 | #define NEXT_CARD bj->player_cards[done][bj->num_player_cards[done]] | ||
212 | |||
213 | /* global rockbox api */ | ||
214 | static struct plugin_api* rb; | ||
215 | |||
216 | /* dealer and player card positions */ | ||
217 | unsigned int dealer_x, dealer_y, player_x, player_y; | ||
218 | |||
219 | typedef struct card { | ||
220 | unsigned int value; /* Card's value in Blackjack */ | ||
221 | unsigned int num; /* Value on card face 0-12 (0=Ace, 1=2, 11=Q) */ | ||
222 | unsigned int suit; /* 0:Spades, 1:Hearts, 2: Clubs; 3: Diamonds */ | ||
223 | bool is_soft_ace; | ||
224 | } card; | ||
225 | |||
226 | typedef struct game_context { | ||
227 | struct card player_cards[2][22]; /* 22 Cards means the deal was all aces */ | ||
228 | struct card dealer_cards[22]; /* That is the worst-case scenario */ | ||
229 | unsigned int player_total; | ||
230 | unsigned int dealer_total; | ||
231 | signed int player_money; | ||
232 | unsigned int num_player_cards[2]; | ||
233 | unsigned int num_dealer_cards; | ||
234 | unsigned int current_bet; | ||
235 | unsigned int split_status; /* 0 = split hasn't been asked, * | ||
236 | * 1 = split did not occur * | ||
237 | * 2 = split occurred * | ||
238 | * 3 = split occurred and 1st hand done */ | ||
239 | bool is_blackjack; | ||
240 | bool end_hand; | ||
241 | bool asked_insurance; | ||
242 | signed short highscores[NUM_SCORES]; | ||
243 | bool resume; | ||
244 | bool dirty; | ||
245 | } game_context; | ||
246 | |||
247 | /***************************************************************************** | ||
248 | * blackjack_init() initializes blackjack data structures. | ||
249 | ******************************************************************************/ | ||
250 | static void blackjack_init(struct game_context* bj) { | ||
251 | /* seed the rand generator */ | ||
252 | rb->srand(*rb->current_tick); | ||
253 | |||
254 | /* reset card positions */ | ||
255 | dealer_x = 4; | ||
256 | dealer_y = LCD_HEIGHT/4 - CARD_HEIGHT/2; | ||
257 | player_x = 4; | ||
258 | player_y = LCD_HEIGHT - LCD_HEIGHT/4 - CARD_HEIGHT/2; | ||
259 | |||
260 | /* check for resumed game */ | ||
261 | if(bj->resume) return; | ||
262 | |||
263 | /* reset scoring */ | ||
264 | bj->player_total = 0; | ||
265 | bj->dealer_total = 0; | ||
266 | bj->num_player_cards[0] = 2; | ||
267 | bj->num_player_cards[1] = 0; | ||
268 | bj->num_dealer_cards = 2; | ||
269 | bj->end_hand = false; | ||
270 | bj->split_status = 0; | ||
271 | bj->is_blackjack = false; | ||
272 | bj->asked_insurance = false; | ||
273 | } | ||
274 | |||
275 | /***************************************************************************** | ||
276 | * blackjack_drawtable() draws the table and some text. | ||
277 | ******************************************************************************/ | ||
278 | static void blackjack_drawtable(struct game_context* bj) { | ||
279 | unsigned int w, h, y_loc; | ||
280 | char str[10]; | ||
281 | |||
282 | #if LCD_HEIGHT <= 64 | ||
283 | rb->lcd_getstringsize("Bet", &w, &h); | ||
284 | rb->lcd_putsxy(LCD_WIDTH - w, 2*h + 1, "Bet"); | ||
285 | rb->snprintf(str, 9, "$%d", bj->current_bet); | ||
286 | rb->lcd_getstringsize(str, &w, &h); | ||
287 | rb->lcd_putsxy(LCD_WIDTH - w, 3*h + 1, str); | ||
288 | y_loc = LCD_HEIGHT/2; | ||
289 | #else | ||
290 | rb->lcd_getstringsize("Bet", &w, &h); | ||
291 | rb->lcd_putsxy(LCD_WIDTH - w, 5*h / 2, "Bet"); | ||
292 | rb->snprintf(str, 9, "$%d", bj->current_bet); | ||
293 | rb->lcd_getstringsize(str, &w, &h); | ||
294 | rb->lcd_putsxy(LCD_WIDTH - w, 7*h / 2, str); | ||
295 | rb->lcd_hline(0, LCD_WIDTH, LCD_HEIGHT/2); | ||
296 | y_loc = LCD_HEIGHT/2 + h; | ||
297 | #endif | ||
298 | |||
299 | rb->lcd_putsxy(0,0, "Dealer"); | ||
300 | rb->lcd_getstringsize("Player", &w, &h); | ||
301 | rb->lcd_putsxy(0, y_loc, "Player"); | ||
302 | rb->lcd_getstringsize("Total", &w, &h); | ||
303 | rb->lcd_putsxy(LCD_WIDTH - w, y_loc, "Total"); | ||
304 | rb->lcd_getstringsize("Money", &w, &h); | ||
305 | rb->lcd_putsxy(LCD_WIDTH - w, 0, "Money"); | ||
306 | rb->snprintf(str, 9, "$%d", bj->player_money - bj->current_bet); | ||
307 | rb->lcd_getstringsize(str, &w, &h); | ||
308 | rb->lcd_putsxy(LCD_WIDTH - w, h + 1, str); | ||
309 | rb->snprintf(str, 3, "%d", bj->player_total); | ||
310 | rb->lcd_getstringsize(str, &w, &h); | ||
311 | rb->lcd_putsxy(LCD_WIDTH - w, y_loc + h, str); | ||
312 | } | ||
313 | |||
314 | /***************************************************************************** | ||
315 | * find_value() is passed a card and returns its blackjack value. | ||
316 | ******************************************************************************/ | ||
317 | static unsigned int find_value(unsigned int number) { | ||
318 | unsigned int thisValue; | ||
319 | if (number == 0) | ||
320 | thisValue = 11; /* Aces get a value of 11 at first */ | ||
321 | else if (number < 10) | ||
322 | thisValue = number + 1; | ||
323 | else | ||
324 | thisValue = 10; /* Anything 10 or higher gets a value of 10 */ | ||
325 | |||
326 | return thisValue; | ||
327 | } | ||
328 | |||
329 | /***************************************************************************** | ||
330 | * draw_card() draws a card to the screen. | ||
331 | ******************************************************************************/ | ||
332 | static void draw_card(struct card temp_card, bool shown, unsigned int x, | ||
333 | unsigned int y) { | ||
334 | if(shown) | ||
335 | rb->lcd_bitmap_part(solitaire_deck, CARD_WIDTH*temp_card.num, | ||
336 | CARD_HEIGHT*temp_card.suit, BMPWIDTH_solitaire_deck, | ||
337 | x+1, y+1, CARD_WIDTH, CARD_HEIGHT); | ||
338 | else | ||
339 | rb->lcd_bitmap(solitaire_cardback, x+1, y+1,CARD_WIDTH, CARD_HEIGHT); | ||
340 | #if LCD_DEPTH > 1 | ||
341 | rb->lcd_set_foreground(LCD_BLACK); | ||
342 | #endif | ||
343 | |||
344 | /* Print outlines */ | ||
345 | #if CARD_WIDTH >= 26 | ||
346 | rb->lcd_hline(x+2, x+CARD_WIDTH-1, y); | ||
347 | rb->lcd_hline(x+2, x+CARD_WIDTH-1, y+CARD_HEIGHT+1); | ||
348 | rb->lcd_vline(x, y+2, y+CARD_HEIGHT-3); | ||
349 | rb->lcd_vline(x+CARD_WIDTH+1, y+2, y+CARD_HEIGHT-1); | ||
350 | rb->lcd_drawpixel(x+1, y+1); | ||
351 | rb->lcd_drawpixel(x+1, y+CARD_HEIGHT); | ||
352 | rb->lcd_drawpixel(x+CARD_WIDTH, y+1); | ||
353 | rb->lcd_drawpixel(x+CARD_WIDTH, y+CARD_HEIGHT); | ||
354 | #else | ||
355 | rb->lcd_hline(x+1, x+CARD_WIDTH, y); | ||
356 | rb->lcd_hline(x+1, x+CARD_WIDTH, y+CARD_HEIGHT+1); | ||
357 | rb->lcd_vline(x, y+1, y+CARD_HEIGHT); | ||
358 | rb->lcd_vline(x+CARD_WIDTH+1, y+1, y+CARD_HEIGHT); | ||
359 | #endif | ||
360 | |||
361 | #if LCD_DEPTH > 1 | ||
362 | rb->lcd_set_foreground(FG_COLOR); | ||
363 | #endif | ||
364 | } | ||
365 | |||
366 | /***************************************************************************** | ||
367 | * new_card() initializes a new card and gives it values. | ||
368 | ******************************************************************************/ | ||
369 | static struct card new_card(void) { | ||
370 | struct card new_card; | ||
371 | new_card.suit = rb->rand()%4; /* Random number 0-3 */ | ||
372 | new_card.num = rb->rand()%13; /* Random number 0-12 */ | ||
373 | new_card.value = find_value(new_card.num); | ||
374 | new_card.is_soft_ace = new_card.num == 0 ? true : false; | ||
375 | return new_card; | ||
376 | } | ||
377 | |||
378 | /***************************************************************************** | ||
379 | * deal_init_card() deals and draws to the screen the player's and dealer's | ||
380 | * initial cards. | ||
381 | ******************************************************************************/ | ||
382 | static void deal_init_cards(struct game_context* bj) { | ||
383 | bj->dealer_cards[0] = new_card(); | ||
384 | bj->dealer_total += bj->dealer_cards[0].value; | ||
385 | |||
386 | draw_card(bj->dealer_cards[0], false, dealer_x, dealer_y); | ||
387 | |||
388 | bj->dealer_cards[1] = new_card(); | ||
389 | bj->dealer_total += bj->dealer_cards[1].value; | ||
390 | draw_card(bj->dealer_cards[1], true, dealer_x + CARD_WIDTH + 4, dealer_y); | ||
391 | |||
392 | bj->player_cards[0][0] = new_card(); | ||
393 | bj->player_total += bj->player_cards[0][0].value; | ||
394 | draw_card(bj->player_cards[0][0], true, player_x, player_y); | ||
395 | player_x += CARD_WIDTH + 4; | ||
396 | |||
397 | bj->player_cards[0][1] = new_card(); | ||
398 | bj->player_total += bj->player_cards[0][1].value; | ||
399 | draw_card(bj->player_cards[0][1], true, player_x, player_y); | ||
400 | player_x += CARD_WIDTH + 4; | ||
401 | } | ||
402 | |||
403 | /***************************************************************************** | ||
404 | * redraw_board() redraws all the cards and the board | ||
405 | ******************************************************************************/ | ||
406 | static void redraw_board(struct game_context* bj) { | ||
407 | unsigned int i, n, upper_bound; | ||
408 | rb->lcd_clear_display(); | ||
409 | |||
410 | blackjack_drawtable(bj); | ||
411 | player_x = 4; | ||
412 | dealer_x = 4; | ||
413 | upper_bound = bj->split_status > 1 ? 2 : 1; | ||
414 | |||
415 | for (i = 0; i < bj->num_dealer_cards; i++) { | ||
416 | if (!bj->end_hand) { | ||
417 | draw_card(bj->dealer_cards[0], false, dealer_x, dealer_y); | ||
418 | |||
419 | /* increment i so the dealer's first card isn't displayed */ | ||
420 | i++; | ||
421 | dealer_x += CARD_WIDTH + 4; | ||
422 | } | ||
423 | draw_card(bj->dealer_cards[i], true, dealer_x, dealer_y); | ||
424 | |||
425 | if (bj->num_dealer_cards > MAX_CARDS-1) | ||
426 | dealer_x += 10; | ||
427 | else | ||
428 | dealer_x += CARD_WIDTH + 4; | ||
429 | } | ||
430 | |||
431 | for (n = 0; n < upper_bound; n++) { | ||
432 | for (i = 0; i < bj->num_player_cards[n]; i++) { | ||
433 | draw_card(bj->player_cards[n][i], true, player_x, player_y); | ||
434 | if (bj->split_status>1 || bj->num_player_cards[n]>MAX_CARDS) | ||
435 | player_x += 10; | ||
436 | else | ||
437 | player_x += CARD_WIDTH + 4; | ||
438 | } | ||
439 | if (bj->split_status > 1) | ||
440 | player_x = LCD_WIDTH/2 + 4; | ||
441 | } | ||
442 | } | ||
443 | |||
444 | /***************************************************************************** | ||
445 | * update_total updates the player's total | ||
446 | ******************************************************************************/ | ||
447 | static void update_total(struct game_context* bj) { | ||
448 | char total[3]; | ||
449 | unsigned int w, h; | ||
450 | rb->snprintf(total, 3, "%d", bj->player_total); | ||
451 | rb->lcd_getstringsize(total, &w, &h); | ||
452 | #if LCD_HEIGHT > 64 | ||
453 | h *= 2; | ||
454 | #endif | ||
455 | rb->lcd_putsxy(LCD_WIDTH - w, LCD_HEIGHT/2 + h, total); | ||
456 | rb->lcd_update_rect(LCD_WIDTH - w, LCD_HEIGHT/2 + h, w, h); | ||
457 | } | ||
458 | |||
459 | |||
460 | /***************************************************************************** | ||
461 | * check_for_aces() is passed an array of cards and returns where an ace is | ||
462 | * located. Otherwise, returns -1. | ||
463 | ******************************************************************************/ | ||
464 | static signed int check_for_aces(struct card temp_cards[], | ||
465 | unsigned int size) { | ||
466 | unsigned int i; | ||
467 | for(i = 0; i < size; i++) { | ||
468 | if (temp_cards[i].is_soft_ace == true) | ||
469 | return i; | ||
470 | } | ||
471 | return -1; | ||
472 | } | ||
473 | |||
474 | /***************************************************************************** | ||
475 | * check_totals() compares player and dealer totals. | ||
476 | * 0: bust 1: loss, 2: push, 3: win, 4: blackjack, 5: something's not right... | ||
477 | ******************************************************************************/ | ||
478 | static unsigned int check_totals(struct game_context* bj) | ||
479 | { | ||
480 | unsigned int temp; | ||
481 | if (bj->player_total > 21) | ||
482 | temp = 0; | ||
483 | else if (bj->player_total == 21 && bj->is_blackjack) | ||
484 | if (bj->dealer_total == 21 && bj->num_dealer_cards == 2) | ||
485 | temp = 2; | ||
486 | else | ||
487 | temp = 4; | ||
488 | else if (bj->player_total == bj->dealer_total) | ||
489 | temp = 2; | ||
490 | else if (bj->dealer_total > 21 && bj->player_total < 22) | ||
491 | temp = 3; | ||
492 | else if (bj->dealer_total > bj->player_total) | ||
493 | temp = 1; | ||
494 | else if (bj->player_total > bj->dealer_total) | ||
495 | temp = 3; | ||
496 | else | ||
497 | temp = 5; | ||
498 | |||
499 | return temp; | ||
500 | } | ||
501 | |||
502 | /***************************************************************************** | ||
503 | * finish_dealer() draws cards for the dealer until he has 17 or more. | ||
504 | ******************************************************************************/ | ||
505 | static void finish_dealer(struct game_context* bj) { | ||
506 | signed int temp = 0; | ||
507 | |||
508 | if (bj->dealer_total > 16 && bj->dealer_total < 22) | ||
509 | return; | ||
510 | |||
511 | while (bj->dealer_total < 17) { | ||
512 | bj->dealer_cards[bj->num_dealer_cards] = new_card(); | ||
513 | bj->dealer_total += bj->dealer_cards[bj->num_dealer_cards].value; | ||
514 | bj->num_dealer_cards++; | ||
515 | } | ||
516 | |||
517 | while (bj->dealer_total > 21) { | ||
518 | temp = check_for_aces(bj->dealer_cards, bj->num_dealer_cards); | ||
519 | if(temp != -1) { | ||
520 | bj->dealer_cards[temp].is_soft_ace = false; | ||
521 | bj->dealer_total -= 10; | ||
522 | } | ||
523 | else | ||
524 | return; | ||
525 | } | ||
526 | } | ||
527 | |||
528 | /***************************************************************************** | ||
529 | * finish_game() completes the game once player's turn is over. | ||
530 | ******************************************************************************/ | ||
531 | static void finish_game(struct game_context* bj) { | ||
532 | unsigned int rValue, w, h; | ||
533 | char str[19]; | ||
534 | |||
535 | do { | ||
536 | finish_dealer(bj); | ||
537 | } while (bj->dealer_total < 17); | ||
538 | |||
539 | redraw_board(bj); | ||
540 | rValue = check_totals(bj); | ||
541 | |||
542 | if (rValue == 0) { | ||
543 | rb->snprintf(str, sizeof(str), " Bust! "); | ||
544 | bj->player_money -= bj->current_bet; | ||
545 | } | ||
546 | else if (rValue == 1) { | ||
547 | rb->snprintf(str, sizeof(str), " Sorry, you lost. "); | ||
548 | bj->player_money -= bj->current_bet; | ||
549 | } | ||
550 | else if (rValue == 2) { | ||
551 | rb->snprintf(str, sizeof(str), " Push "); | ||
552 | } | ||
553 | else if (rValue == 3) { | ||
554 | rb->snprintf(str, sizeof(str), " You won! "); | ||
555 | bj->player_money+= bj->current_bet; | ||
556 | } | ||
557 | else { | ||
558 | rb->snprintf(str, sizeof(str), " Blackjack! "); | ||
559 | bj->player_money += bj->current_bet * 3 / 2; | ||
560 | } | ||
561 | rb->lcd_getstringsize(str, &w, &h); | ||
562 | |||
563 | #if LCD_HEIGHT <= 64 | ||
564 | rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID); | ||
565 | rb->lcd_fillrect(0, LCD_HEIGHT/2, LCD_WIDTH, LCD_HEIGHT/2); | ||
566 | rb->lcd_set_drawmode(DRMODE_SOLID); | ||
567 | rb->lcd_putsxy(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + h, str); | ||
568 | rb->snprintf(str, 12, "You have %d", bj->player_total); | ||
569 | rb->lcd_getstringsize(str, &w, &h); | ||
570 | rb->lcd_putsxy(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2, str); | ||
571 | #else | ||
572 | rb->lcd_putsxy(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 - h/2, str); | ||
573 | #endif | ||
574 | rb->lcd_update(); | ||
575 | } | ||
576 | |||
577 | /***************************************************************************** | ||
578 | * blackjack_recordscore() inserts a high score into the high scores list and | ||
579 | * returns the high score position. | ||
580 | ******************************************************************************/ | ||
581 | static unsigned int blackjack_recordscore(struct game_context* bj) { | ||
582 | unsigned int i; | ||
583 | unsigned int position = 0; | ||
584 | signed short current, temp; | ||
585 | |||
586 | /* calculate total score */ | ||
587 | current = bj->player_money; | ||
588 | if(current <= 10) return 0; | ||
589 | |||
590 | /* insert the current score into the high scores */ | ||
591 | for(i=0; i<NUM_SCORES; i++) { | ||
592 | if(current >= bj->highscores[i]) { | ||
593 | if(!position) { | ||
594 | position = i+1; | ||
595 | bj->dirty = true; | ||
596 | } | ||
597 | temp = bj->highscores[i]; | ||
598 | bj->highscores[i] = current; | ||
599 | current = temp; | ||
600 | } | ||
601 | } | ||
602 | |||
603 | return position; | ||
604 | } | ||
605 | |||
606 | /***************************************************************************** | ||
607 | * blackjack_loadscores() loads the high scores saved file. | ||
608 | ******************************************************************************/ | ||
609 | static void blackjack_loadscores(struct game_context* bj) { | ||
610 | signed int fd; | ||
611 | |||
612 | bj->dirty = false; | ||
613 | |||
614 | /* clear high scores */ | ||
615 | rb->memset(bj->highscores, 0, sizeof(bj->highscores)); | ||
616 | |||
617 | /* open scores file */ | ||
618 | fd = rb->open(SCORE_FILE, O_RDONLY); | ||
619 | if(fd < 0) return; | ||
620 | |||
621 | /* read in high scores */ | ||
622 | if(rb->read(fd, bj->highscores, sizeof(bj->highscores)) <= 0) { | ||
623 | /* scores are bad, reset */ | ||
624 | rb->memset(bj->highscores, 0, sizeof(bj->highscores)); | ||
625 | } | ||
626 | |||
627 | rb->close(fd); | ||
628 | } | ||
629 | |||
630 | /***************************************************************************** | ||
631 | * blackjack_savescores() saves the high scores saved file. | ||
632 | ******************************************************************************/ | ||
633 | static void blackjack_savescores(struct game_context* bj) { | ||
634 | unsigned int fd; | ||
635 | |||
636 | /* write out the high scores to the save file */ | ||
637 | fd = rb->open(SCORE_FILE, O_WRONLY|O_CREAT); | ||
638 | rb->write(fd, bj->highscores, sizeof(bj->highscores)); | ||
639 | rb->close(fd); | ||
640 | bj->dirty = false; | ||
641 | } | ||
642 | |||
643 | /***************************************************************************** | ||
644 | * blackjack_loadgame() loads the saved game and returns load success. | ||
645 | ******************************************************************************/ | ||
646 | static bool blackjack_loadgame(struct game_context* bj) { | ||
647 | signed int fd; | ||
648 | bool loaded = false; | ||
649 | |||
650 | /* open game file */ | ||
651 | fd = rb->open(SAVE_FILE, O_RDONLY); | ||
652 | if(fd < 0) return loaded; | ||
653 | |||
654 | /* read in saved game */ | ||
655 | while(true) { | ||
656 | if(rb->read(fd, &bj->player_money, sizeof(bj->player_money)) <= 0) break; | ||
657 | if(rb->read(fd, &bj->player_total, sizeof(bj->player_total)) <= 0) break; | ||
658 | if(rb->read(fd, &bj->dealer_total, sizeof(bj->dealer_total)) <= 0) break; | ||
659 | if(rb->read(fd, &bj->num_player_cards, sizeof(bj->num_player_cards))<=0) | ||
660 | break; | ||
661 | if(rb->read(fd, &bj->num_dealer_cards, sizeof(bj->num_dealer_cards))<=0) | ||
662 | break; | ||
663 | if(rb->read(fd, &bj->current_bet, sizeof(bj->current_bet)) <= 0) break; | ||
664 | if(rb->read(fd, &bj->is_blackjack, sizeof(bj->is_blackjack)) <= 0) break; | ||
665 | if(rb->read(fd, &bj->split_status, sizeof(bj->split_status)) <= 0) break; | ||
666 | if(rb->read(fd, &bj->asked_insurance, sizeof(bj->asked_insurance)) <= 0) | ||
667 | break; | ||
668 | if(rb->read(fd, &bj->end_hand, sizeof(bj->end_hand)) <= 0) break; | ||
669 | if(rb->read(fd, &bj->player_cards, sizeof(bj->player_cards)) <= 0) break; | ||
670 | if(rb->read(fd, &bj->dealer_cards, sizeof(bj->dealer_cards)) <= 0) break; | ||
671 | bj->resume = true; | ||
672 | loaded = true; | ||
673 | break; | ||
674 | } | ||
675 | |||
676 | rb->close(fd); | ||
677 | |||
678 | /* delete saved file */ | ||
679 | rb->remove(SAVE_FILE); | ||
680 | return loaded; | ||
681 | } | ||
682 | |||
683 | /***************************************************************************** | ||
684 | * blackjack_savegame() saves the current game state. | ||
685 | ******************************************************************************/ | ||
686 | static void blackjack_savegame(struct game_context* bj) { | ||
687 | unsigned int fd; | ||
688 | |||
689 | /* write out the game state to the save file */ | ||
690 | fd = rb->open(SAVE_FILE, O_WRONLY|O_CREAT); | ||
691 | rb->write(fd, &bj->player_money, sizeof(bj->player_money)); | ||
692 | rb->write(fd, &bj->player_total, sizeof(bj->player_total)); | ||
693 | rb->write(fd, &bj->dealer_total, sizeof(bj->dealer_total)); | ||
694 | rb->write(fd, &bj->num_player_cards, sizeof(bj->num_player_cards)); | ||
695 | rb->write(fd, &bj->num_dealer_cards, sizeof(bj->num_dealer_cards)); | ||
696 | rb->write(fd, &bj->current_bet, sizeof(bj->current_bet)); | ||
697 | rb->write(fd, &bj->is_blackjack, sizeof(bj->is_blackjack)); | ||
698 | rb->write(fd, &bj->split_status, sizeof(bj->split_status)); | ||
699 | rb->write(fd, &bj->asked_insurance, sizeof(bj->asked_insurance)); | ||
700 | rb->write(fd, &bj->end_hand, sizeof(bj->end_hand)); | ||
701 | rb->write(fd, &bj->player_cards, sizeof(bj->player_cards)); | ||
702 | rb->write(fd, &bj->dealer_cards, sizeof(bj->dealer_cards)); | ||
703 | rb->close(fd); | ||
704 | |||
705 | bj->resume = true; | ||
706 | } | ||
707 | |||
708 | /***************************************************************************** | ||
709 | * blackjack_callback() is the default event handler callback which is called | ||
710 | * on usb connect and shutdown. | ||
711 | ******************************************************************************/ | ||
712 | static void blackjack_callback(void* param) { | ||
713 | struct game_context* bj = (struct game_context*) param; | ||
714 | if(bj->dirty) { | ||
715 | rb->splash(HZ, true, "Saving high scores..."); | ||
716 | blackjack_savescores(bj); | ||
717 | } | ||
718 | } | ||
719 | |||
720 | /***************************************************************************** | ||
721 | * blackjack_get_yes_no() gets a yes/no answer from the user | ||
722 | ******************************************************************************/ | ||
723 | static unsigned int blackjack_get_yes_no(char message[20]) { | ||
724 | int button; | ||
725 | unsigned int w, h, b, choice = 0; | ||
726 | bool breakout = false; | ||
727 | char message_yes[24], message_no[24]; | ||
728 | |||
729 | rb->strcpy(message_yes, message); | ||
730 | rb->strcpy(message_no, message); | ||
731 | rb->strcat(message_yes, " Yes"); | ||
732 | rb->strcat(message_no, " No"); | ||
733 | rb->lcd_getstringsize(message_yes, &w, &h); | ||
734 | const char *stg[] = {message_yes, message_no}; | ||
735 | |||
736 | #if LCD_HEIGHT <= 64 | ||
737 | b = 2*h+1; | ||
738 | #else | ||
739 | b = h-1; | ||
740 | #endif | ||
741 | |||
742 | #ifdef HAVE_LCD_COLOR | ||
743 | rb->lcd_fillrect(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + b, w+1, h+3); | ||
744 | rb->lcd_set_foreground(LCD_BLACK); | ||
745 | rb->lcd_set_background(LCD_WHITE); | ||
746 | #else | ||
747 | rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID); | ||
748 | rb->lcd_fillrect(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + b, w+1, h+3); | ||
749 | rb->lcd_set_drawmode(DRMODE_SOLID); | ||
750 | #endif | ||
751 | rb->lcd_drawrect(LCD_WIDTH/2 - w/2 - 1, LCD_HEIGHT/2 + b - 1, w+3, h+4); | ||
752 | |||
753 | while(!breakout) { | ||
754 | rb->lcd_putsxy(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + b +1, stg[choice]); | ||
755 | rb->lcd_update_rect(LCD_WIDTH/2 - w/2 - 1, LCD_HEIGHT/2 + b -1, | ||
756 | w+3, h+4); | ||
757 | button = rb->button_get(true); | ||
758 | |||
759 | switch(button) { | ||
760 | case BJACK_LEFT: | ||
761 | case (BJACK_LEFT|BUTTON_REPEAT): | ||
762 | case BJACK_RIGHT: | ||
763 | case (BJACK_RIGHT|BUTTON_REPEAT): | ||
764 | choice ^= 1; | ||
765 | break; | ||
766 | case BJACK_START: breakout = true; | ||
767 | break; | ||
768 | case BJACK_QUIT: breakout = true; | ||
769 | choice = BJ_QUIT; | ||
770 | break; | ||
771 | } | ||
772 | } | ||
773 | |||
774 | #if LCD_DEPTH > 1 | ||
775 | rb->lcd_set_foreground(FG_COLOR); | ||
776 | rb->lcd_set_background(BG_COLOR); | ||
777 | #endif | ||
778 | return choice; | ||
779 | } | ||
780 | |||
781 | /***************************************************************************** | ||
782 | * blackjack_get_amount() gets an amount from the player to be used | ||
783 | ******************************************************************************/ | ||
784 | static signed int blackjack_get_amount(char message[20], signed int lower_limit, | ||
785 | signed int upper_limit, | ||
786 | signed int start) { | ||
787 | int button; | ||
788 | char str[6]; | ||
789 | bool changed = false; | ||
790 | unsigned int w, h; | ||
791 | signed int amount; | ||
792 | |||
793 | rb->lcd_getstringsize("A", &w, &h); /* find the size of one character */ | ||
794 | |||
795 | if (start > upper_limit) | ||
796 | amount = upper_limit; | ||
797 | else if (start < lower_limit) | ||
798 | amount = lower_limit; | ||
799 | else | ||
800 | amount = start; | ||
801 | |||
802 | #if LCD_DEPTH > 1 | ||
803 | rb->lcd_set_background(LCD_WHITE); | ||
804 | rb->lcd_set_foreground(LCD_BLACK); | ||
805 | #endif | ||
806 | |||
807 | #if LCD_HEIGHT <= 64 | ||
808 | rb->lcd_clear_display(); | ||
809 | rb->lcd_puts(0, 1, message); | ||
810 | rb->snprintf(str, 9, "$%d", amount); | ||
811 | rb->lcd_puts(0, 2, str); | ||
812 | rb->lcd_puts(0, 3, "RIGHT: +1"); | ||
813 | rb->lcd_puts(0, 4, "LEFT: -1"); | ||
814 | rb->lcd_puts(0, 5, "UP: +10"); | ||
815 | rb->lcd_puts(0, 6, "DOWN: -10"); | ||
816 | rb->lcd_update(); | ||
817 | #else | ||
818 | rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID); | ||
819 | rb->lcd_fillrect(LCD_WIDTH/2 - 9*w - 1, LCD_HEIGHT/2 - 4*h - 3, 37*w / 2, | ||
820 | 8*h -3); | ||
821 | rb->lcd_set_drawmode(DRMODE_SOLID); | ||
822 | rb->lcd_drawrect(LCD_WIDTH/2 - 9*w - 1, LCD_HEIGHT/2 - 4*h - 3, 37*w / 2, | ||
823 | 8*h -3); | ||
824 | rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 4*h - 1, message); | ||
825 | rb->snprintf(str, 9, "$%d", amount); | ||
826 | rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, str); | ||
827 | #if (CONFIG_KEY == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD) | ||
828 | rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - h-2, " >>|: +1"); | ||
829 | rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 1, " |<<: -1"); | ||
830 | rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + h, "SCROLL+: +10"); | ||
831 | rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + 2*h + 1, "SCROLL-: -10"); | ||
832 | #elif CONFIG_KEYPAD == IRIVER_H10_PAD | ||
833 | rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - h-2, "RIGHT: +1"); | ||
834 | rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 1, "LEFT: -1"); | ||
835 | rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + h, "SCROLL+: +10"); | ||
836 | rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + 2*h + 1, "SCROLL-: -10"); | ||
837 | #else | ||
838 | rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - h-2, "RIGHT: +1"); | ||
839 | rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 1, "LEFT: -1"); | ||
840 | rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + h, "UP: +10"); | ||
841 | rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + 2*h + 1, "DOWN: -10"); | ||
842 | #endif | ||
843 | rb->lcd_update_rect(LCD_WIDTH/2 - 9*w - 2, LCD_HEIGHT/2 - 9*h/2, 37*w/2 + 1, | ||
844 | 8*h-2); | ||
845 | #endif | ||
846 | |||
847 | while(true) { | ||
848 | button = rb->button_get(true); | ||
849 | |||
850 | switch(button) { | ||
851 | case BJACK_UP: | ||
852 | case (BJACK_UP|BUTTON_REPEAT): | ||
853 | if (amount + 10 < upper_limit + 1) { | ||
854 | amount += 10; | ||
855 | changed = true; | ||
856 | } | ||
857 | break; | ||
858 | case BJACK_DOWN: | ||
859 | case (BJACK_DOWN|BUTTON_REPEAT): | ||
860 | if (amount - 10 > lower_limit - 1) { | ||
861 | amount -= 10; | ||
862 | changed = true; | ||
863 | } | ||
864 | break; | ||
865 | case BJACK_RIGHT: | ||
866 | case (BJACK_RIGHT|BUTTON_REPEAT): | ||
867 | if (amount + 1 < upper_limit + 1) { | ||
868 | amount++; | ||
869 | changed = true; | ||
870 | } | ||
871 | break; | ||
872 | case BJACK_LEFT: | ||
873 | case (BJACK_LEFT|BUTTON_REPEAT): | ||
874 | if (amount - 1 > lower_limit - 1) { | ||
875 | amount--; | ||
876 | changed = true; | ||
877 | } | ||
878 | break; | ||
879 | case BJACK_MAX : | ||
880 | amount = upper_limit; | ||
881 | changed = true; | ||
882 | break; | ||
883 | case BJACK_MIN : | ||
884 | amount = lower_limit; | ||
885 | changed = true; | ||
886 | break; | ||
887 | case BJACK_QUIT: | ||
888 | return 0; | ||
889 | case BJACK_START: | ||
890 | #if LCD_DEPTH > 1 | ||
891 | rb->lcd_set_foreground(FG_COLOR); | ||
892 | rb->lcd_set_background(BG_COLOR); | ||
893 | #endif | ||
894 | rb->lcd_clear_display(); | ||
895 | return amount; | ||
896 | } | ||
897 | |||
898 | if(changed) { | ||
899 | rb->snprintf(str, 9, "$%d", amount); | ||
900 | #if LCD_HEIGHT <= 64 | ||
901 | rb->lcd_puts(0, 2, str); | ||
902 | rb->lcd_update(); | ||
903 | #else | ||
904 | rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID); | ||
905 | rb->lcd_fillrect(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, 5*w, h); | ||
906 | rb->lcd_set_drawmode(DRMODE_SOLID); | ||
907 | rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, str); | ||
908 | rb->lcd_update_rect(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, 5*w, h); | ||
909 | #endif | ||
910 | changed = false; | ||
911 | } | ||
912 | } | ||
913 | } | ||
914 | |||
915 | /***************************************************************************** | ||
916 | * blackjack_get_bet() gets the player's bet. | ||
917 | ******************************************************************************/ | ||
918 | static void blackjack_get_bet(struct game_context* bj) { | ||
919 | bj->current_bet = blackjack_get_amount("Please enter a bet", 10, | ||
920 | bj->player_money, bj->current_bet); | ||
921 | } | ||
922 | |||
923 | /***************************************************************************** | ||
924 | * double_down() returns one final card then finishes the game | ||
925 | ******************************************************************************/ | ||
926 | static void double_down(struct game_context* bj) { | ||
927 | bj->current_bet *= 2; | ||
928 | bj->player_cards[0][bj->num_player_cards[0]] = new_card(); | ||
929 | bj->player_total += bj->player_cards[0][bj->num_player_cards[0]].value; | ||
930 | bj->num_player_cards[0]++; | ||
931 | } | ||
932 | |||
933 | /***************************************************************************** | ||
934 | * split() checks if the player wants to split and acts accordingly. | ||
935 | * When bj->split_status is 1, no split occurred. 2 means the player split and 3 | ||
936 | * means a split has already occurred and the first hand is done. | ||
937 | ******************************************************************************/ | ||
938 | static void split(struct game_context* bj) { | ||
939 | if (blackjack_get_yes_no("Split?") == 1) | ||
940 | bj->split_status = 1; | ||
941 | else { | ||
942 | bj->split_status = 2; | ||
943 | bj->current_bet *= 2; | ||
944 | bj->num_player_cards[0] = 1; | ||
945 | bj->num_player_cards[1] = 1; | ||
946 | bj->player_cards[1][0] = bj->player_cards[0][1]; | ||
947 | bj->player_total = bj->player_cards[0][0].value; | ||
948 | } | ||
949 | } | ||
950 | |||
951 | /***************************************************************************** | ||
952 | * insurance() see if the player wants to buy insurance and how much. | ||
953 | ******************************************************************************/ | ||
954 | static unsigned int insurance(struct game_context* bj) { | ||
955 | unsigned int insurance, max_amount; | ||
956 | |||
957 | insurance = blackjack_get_yes_no("Buy Insurance?"); | ||
958 | bj->asked_insurance = true; | ||
959 | max_amount = bj->current_bet < (unsigned int)bj->player_money ? | ||
960 | bj->current_bet/2 : (unsigned int)bj->player_money; | ||
961 | if (insurance == 1) return 0; | ||
962 | |||
963 | insurance = blackjack_get_amount("How much?", 0, max_amount, 0); | ||
964 | redraw_board(bj); | ||
965 | return insurance; | ||
966 | } | ||
967 | |||
968 | /***************************************************************************** | ||
969 | * play_again() checks to see if the player wants to keep playing. | ||
970 | ******************************************************************************/ | ||
971 | static unsigned int play_again(void) { | ||
972 | return blackjack_get_yes_no("Play Again?"); | ||
973 | } | ||
974 | |||
975 | /***************************************************************************** | ||
976 | * blackjack_menu() is the initial menu at the start of the game. | ||
977 | ******************************************************************************/ | ||
978 | static unsigned int blackjack_menu(struct game_context* bj) { | ||
979 | int button; | ||
980 | char *title = "Blackjack"; | ||
981 | char str[18]; | ||
982 | unsigned int i, w, h; | ||
983 | bool breakout = false; | ||
984 | bool showscores = false; | ||
985 | |||
986 | while(true){ | ||
987 | #if LCD_DEPTH > 1 | ||
988 | rb->lcd_set_background(BG_COLOR); | ||
989 | rb->lcd_set_foreground(FG_COLOR); | ||
990 | #endif | ||
991 | rb->lcd_clear_display(); | ||
992 | |||
993 | if(!showscores) { | ||
994 | /* welcome screen to display key bindings */ | ||
995 | rb->lcd_getstringsize(title, &w, &h); | ||
996 | rb->lcd_putsxy((LCD_WIDTH-w)/2, 0, title); | ||
997 | |||
998 | #if CONFIG_KEYPAD == RECORDER_PAD | ||
999 | rb->lcd_puts(0, 1, "ON: start"); | ||
1000 | rb->lcd_puts(0, 2, "OFF: exit"); | ||
1001 | rb->lcd_puts(0, 3, "F1: hit"); | ||
1002 | rb->lcd_puts(0, 4, "F2: stay"); | ||
1003 | rb->lcd_puts(0, 5, "F3: double down"); | ||
1004 | rb->lcd_puts(0, 6, "PLAY: save/resume"); | ||
1005 | rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]); | ||
1006 | rb->lcd_puts(0, 7, str); | ||
1007 | #elif CONFIG_KEYPAD == ONDIO_PAD | ||
1008 | rb->lcd_puts(0, 1, "MENU: start"); | ||
1009 | rb->lcd_puts(0, 2, "OFF: exit"); | ||
1010 | rb->lcd_puts(0, 3, "LEFT: hit"); | ||
1011 | rb->lcd_puts(0, 4, "RIGHT: stay"); | ||
1012 | rb->lcd_puts(0, 5, "UP: double down"); | ||
1013 | rb->lcd_puts(0, 6, "DOWN: save/resume"); | ||
1014 | rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]); | ||
1015 | rb->lcd_puts(0, 7, str); | ||
1016 | #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD) | ||
1017 | rb->lcd_puts(0, 2, "PLAY to start & to hit"); | ||
1018 | rb->lcd_puts(0, 3, "STOP to exit"); | ||
1019 | rb->lcd_puts(0, 4, "REC to stay"); | ||
1020 | rb->lcd_puts(0, 5, "NAVI to double down "); | ||
1021 | rb->lcd_puts(0, 6, " & to view highscores"); | ||
1022 | rb->lcd_puts(0, 7, "AB to save/resume"); | ||
1023 | rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]); | ||
1024 | rb->lcd_puts(0, 8, str); | ||
1025 | #elif CONFIG_KEYPAD == IRIVER_H10_PAD | ||
1026 | rb->lcd_puts(0, 2, "PLAY to start & hit"); | ||
1027 | rb->lcd_puts(0, 3, "POWER to exit"); | ||
1028 | rb->lcd_puts(0, 4, ">>| to stay"); | ||
1029 | rb->lcd_puts(0, 5, "|<< to double down"); | ||
1030 | rb->lcd_puts(0, 6, "LEFT to view scores"); | ||
1031 | rb->lcd_puts(0, 7, "RIGHT to save/resume"); | ||
1032 | rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]); | ||
1033 | rb->lcd_puts(0, 8, str); | ||
1034 | |||
1035 | #elif (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD) | ||
1036 | #if LCD_WIDTH >=176 | ||
1037 | rb->lcd_puts(0, 2, "SELECT to start & to hit"); | ||
1038 | rb->lcd_puts(0, 3, "MENU to exit"); | ||
1039 | rb->lcd_puts(0, 4, ">>| to stay & to view highscores"); | ||
1040 | rb->lcd_puts(0, 5, "|<< to double down"); | ||
1041 | rb->lcd_puts(0, 6, "PLAY to save/resume"); | ||
1042 | rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]); | ||
1043 | rb->lcd_puts(0, 7, str); | ||
1044 | #else | ||
1045 | rb->lcd_puts(0, 2, "SELECT to start & to "); | ||
1046 | rb->lcd_puts(0, 3, " hit"); | ||
1047 | rb->lcd_puts(0, 4, "MENU to exit"); | ||
1048 | rb->lcd_puts(0, 5, ">>| to stay & to view "); | ||
1049 | rb->lcd_puts(0, 6, " highscores"); | ||
1050 | rb->lcd_puts(0, 7, "|<< to double down"); | ||
1051 | rb->lcd_puts(0, 8, "PLAY to save/resume"); | ||
1052 | rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]); | ||
1053 | rb->lcd_puts(0, 9, str); | ||
1054 | #endif | ||
1055 | #elif CONFIG_KEYPAD == IAUDIO_X5_PAD | ||
1056 | rb->lcd_puts(0, 2, "PLAY to start to hit"); | ||
1057 | rb->lcd_puts(0, 3, "POWER to exit"); | ||
1058 | rb->lcd_puts(0, 4, "SELECT to hit"); | ||
1059 | rb->lcd_puts(0, 5, "REC to stay"); | ||
1060 | rb->lcd_puts(0, 6, "PLAY to double down"); | ||
1061 | rb->lcd_puts(0, 7, "RIGHT to view highscores "); | ||
1062 | rb->lcd_puts(0, 8, "DOWN to save/resume"); | ||
1063 | rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]); | ||
1064 | rb->lcd_puts(0, 9, str); | ||
1065 | #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD | ||
1066 | rb->lcd_puts(0, 2, "AB to start & to"); | ||
1067 | rb->lcd_puts(0, 3, " stay"); | ||
1068 | rb->lcd_puts(0, 4, "EQ to hit"); | ||
1069 | rb->lcd_puts(0, 5, "PLAY to exit"); | ||
1070 | rb->lcd_puts(0, 6, "CLICK to double down"); | ||
1071 | rb->lcd_puts(0, 7, "& to view highscores"); | ||
1072 | rb->lcd_puts(0, 8, "AB+EQ to save/resume"); | ||
1073 | rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]); | ||
1074 | rb->lcd_puts(0, 9, str); | ||
1075 | #elif CONFIG_KEYPAD == GIGABEAT_PAD | ||
1076 | rb->lcd_puts(0, 2, "POWER to start"); | ||
1077 | rb->lcd_puts(0, 3, "A to exit"); | ||
1078 | rb->lcd_puts(0, 4, "VOL+ to hit"); | ||
1079 | rb->lcd_puts(0, 5, "VOL- to stay"); | ||
1080 | rb->lcd_puts(0, 6, "CENTER to double down"); | ||
1081 | rb->lcd_puts(0, 6, "RIGHT to view highscores "); | ||
1082 | rb->lcd_puts(0, 8, "MENU to save/resume"); | ||
1083 | rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]); | ||
1084 | rb->lcd_puts(0, 9, str); | ||
1085 | #elif (CONFIG_KEYPAD == SANSA_E200_PAD) | ||
1086 | rb->lcd_puts(0, 2, "SELECT to start & to hit"); | ||
1087 | rb->lcd_puts(0, 3, "POWER to exit"); | ||
1088 | rb->lcd_puts(0, 4, "RIGHT to stay"); | ||
1089 | rb->lcd_puts(0, 5, "LEFT to double down"); | ||
1090 | rb->lcd_puts(0, 6, "REC to save/resume"); | ||
1091 | rb->lcd_puts(0, 7, "UP to view scores"); | ||
1092 | rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]); | ||
1093 | rb->lcd_puts(0, 8, str); | ||
1094 | |||
1095 | #endif | ||
1096 | } else { | ||
1097 | rb->snprintf(str, 12, "%s", "High Scores"); | ||
1098 | rb->lcd_getstringsize(str, &w, &h); | ||
1099 | rb->lcd_putsxy((LCD_WIDTH-w)/2, 0, str); | ||
1100 | |||
1101 | /* print high scores */ | ||
1102 | for(i=0; i<NUM_SCORES; i++) { | ||
1103 | rb->snprintf(str, 14, "#%02d: $%d", i+1, bj->highscores[i]); | ||
1104 | rb->lcd_puts(0, i+1, str); | ||
1105 | } | ||
1106 | } | ||
1107 | |||
1108 | rb->lcd_update(); | ||
1109 | |||
1110 | /* handle menu button presses */ | ||
1111 | button = rb->button_get(true); | ||
1112 | |||
1113 | switch(button) { | ||
1114 | case BJACK_START: /* start playing */ | ||
1115 | breakout = true; | ||
1116 | break; | ||
1117 | |||
1118 | case BJACK_QUIT: /* quit program */ | ||
1119 | if(showscores) { | ||
1120 | showscores = 0; | ||
1121 | break; | ||
1122 | } | ||
1123 | return BJ_QUIT; | ||
1124 | |||
1125 | case BJACK_RESUME:/* resume game */ | ||
1126 | if(!blackjack_loadgame(bj)) { | ||
1127 | rb->splash(HZ*2, true, "Nothing to resume"); | ||
1128 | } else { | ||
1129 | rb->splash(HZ*2, true, "Loading..."); | ||
1130 | breakout = true; | ||
1131 | } | ||
1132 | break; | ||
1133 | |||
1134 | case BJACK_SCORES:/* toggle high scores */ | ||
1135 | showscores = !showscores; | ||
1136 | break; | ||
1137 | |||
1138 | default: | ||
1139 | if(rb->default_event_handler_ex(button, blackjack_callback, | ||
1140 | (void*) bj) == SYS_USB_CONNECTED) | ||
1141 | return BJ_USB; | ||
1142 | break; | ||
1143 | } | ||
1144 | |||
1145 | if(breakout) break; | ||
1146 | } | ||
1147 | |||
1148 | return(0); | ||
1149 | } | ||
1150 | |||
1151 | /***************************************************************************** | ||
1152 | * blackjack() is the main game subroutine, it returns the final game status. | ||
1153 | ******************************************************************************/ | ||
1154 | static int blackjack(struct game_context* bj) { | ||
1155 | int button; | ||
1156 | unsigned int w, h, temp_var, done = 0, todo = 1; | ||
1157 | signed int temp; | ||
1158 | bool breakout = false; | ||
1159 | bool dbl_down = false; | ||
1160 | |||
1161 | /* don't resume by default */ | ||
1162 | bj->resume = false; | ||
1163 | |||
1164 | /******************** | ||
1165 | * menu * | ||
1166 | ********************/ | ||
1167 | temp_var = blackjack_menu(bj); | ||
1168 | if (temp_var == BJ_QUIT || temp_var == BJ_USB) | ||
1169 | return temp_var; | ||
1170 | |||
1171 | |||
1172 | /******************** | ||
1173 | * init * | ||
1174 | ********************/ | ||
1175 | blackjack_init(bj); | ||
1176 | bj->current_bet=10; | ||
1177 | |||
1178 | /******************** | ||
1179 | * play * | ||
1180 | ********************/ | ||
1181 | |||
1182 | /* check for resumed game */ | ||
1183 | if(bj->resume) { | ||
1184 | bj->resume = false; | ||
1185 | redraw_board(bj); | ||
1186 | if (bj->split_status == 2) { | ||
1187 | todo=2; | ||
1188 | player_x = bj->num_player_cards[0] * 10 + 4; | ||
1189 | } | ||
1190 | else if (bj->split_status == 3) { | ||
1191 | player_x = bj->num_player_cards[1] * 10 + LCD_WIDTH/2 + 4; | ||
1192 | todo=2; | ||
1193 | done=1; | ||
1194 | } | ||
1195 | |||
1196 | } | ||
1197 | else { | ||
1198 | bj->player_money = 1000; | ||
1199 | blackjack_get_bet(bj); | ||
1200 | if (bj->current_bet == 0) | ||
1201 | return BJ_QUIT; | ||
1202 | rb->lcd_clear_display(); | ||
1203 | deal_init_cards(bj); | ||
1204 | blackjack_drawtable(bj); | ||
1205 | } | ||
1206 | |||
1207 | rb->lcd_update(); | ||
1208 | |||
1209 | breakout = false; | ||
1210 | |||
1211 | while(true){ | ||
1212 | if(bj->player_total == 21 && bj->num_player_cards[0] == 2) { | ||
1213 | bj->is_blackjack = true; | ||
1214 | bj->end_hand = true; | ||
1215 | finish_game(bj); | ||
1216 | } | ||
1217 | else if(bj->dealer_cards[1].is_soft_ace && !breakout && | ||
1218 | !bj->asked_insurance) { | ||
1219 | temp_var = insurance(bj); | ||
1220 | if (bj->dealer_total == 21) { | ||
1221 | rb->splash(HZ, true, "Dealer has blackjack"); | ||
1222 | bj->player_money += temp_var; | ||
1223 | bj->end_hand = true; | ||
1224 | breakout = true; | ||
1225 | redraw_board(bj); | ||
1226 | finish_game(bj); | ||
1227 | } | ||
1228 | else { | ||
1229 | rb->splash(HZ, true, "Dealer does not have blackjack"); | ||
1230 | bj->player_money -= temp_var; | ||
1231 | breakout = true; | ||
1232 | redraw_board(bj); | ||
1233 | rb->lcd_update(); | ||
1234 | } | ||
1235 | } | ||
1236 | if(bj->split_status == 0 && | ||
1237 | bj->player_cards[0][0].num == bj->player_cards[0][1].num) { | ||
1238 | split(bj); | ||
1239 | redraw_board(bj); | ||
1240 | rb->lcd_update_rect(0, LCD_HEIGHT/2, LCD_WIDTH, LCD_HEIGHT/2); | ||
1241 | if (bj->split_status == 2) { | ||
1242 | todo++; | ||
1243 | player_x = bj->num_player_cards[0] * 10 + 4; | ||
1244 | } | ||
1245 | } | ||
1246 | |||
1247 | while(done < todo) { | ||
1248 | button = rb->button_get(true); | ||
1249 | |||
1250 | switch(button) { | ||
1251 | case BJACK_HIT: | ||
1252 | NEXT_CARD = new_card(); | ||
1253 | bj->player_total += NEXT_CARD.value; | ||
1254 | draw_card(NEXT_CARD, true, player_x, player_y); | ||
1255 | bj->num_player_cards[done]++; | ||
1256 | if (bj->num_player_cards[done] == MAX_CARDS + 1) { | ||
1257 | redraw_board(bj); | ||
1258 | rb->lcd_update_rect(0, LCD_HEIGHT/2, LCD_WIDTH, | ||
1259 | LCD_HEIGHT/2); | ||
1260 | } | ||
1261 | else if (bj->num_player_cards[done]>MAX_CARDS || todo > 1) { | ||
1262 | rb->lcd_update_rect(player_x, player_y, CARD_WIDTH+2, | ||
1263 | CARD_HEIGHT+2); | ||
1264 | player_x += 10; | ||
1265 | } | ||
1266 | else { | ||
1267 | rb->lcd_update_rect(player_x, player_y, CARD_WIDTH+2, | ||
1268 | CARD_HEIGHT+2); | ||
1269 | player_x += CARD_WIDTH + 4; | ||
1270 | } | ||
1271 | update_total(bj); | ||
1272 | |||
1273 | break; | ||
1274 | case BJACK_STAY: | ||
1275 | bj->end_hand = true; | ||
1276 | break; | ||
1277 | case BJACK_DOUBLEDOWN: | ||
1278 | if ((signed int)bj->current_bet * 2 < bj->player_money + 1 && | ||
1279 | bj->num_player_cards[0]==2 && todo==1) { | ||
1280 | double_down(bj); | ||
1281 | dbl_down = true; | ||
1282 | if (bj->player_total < 22) { | ||
1283 | bj->end_hand = true; | ||
1284 | finish_game(bj); | ||
1285 | } | ||
1286 | } | ||
1287 | else if((signed int)bj->current_bet * 2 > bj->player_money) { | ||
1288 | rb->splash(HZ, true, "Not enough money to double down."); | ||
1289 | redraw_board(bj); | ||
1290 | rb->lcd_update(); | ||
1291 | } | ||
1292 | break; | ||
1293 | case BJACK_RESUME: /* save and end game */ | ||
1294 | rb->splash(HZ, true, "Saving game..."); | ||
1295 | blackjack_savegame(bj); | ||
1296 | /* fall through to BJACK_QUIT */ | ||
1297 | |||
1298 | case BJACK_QUIT: | ||
1299 | return BJ_END; | ||
1300 | } | ||
1301 | |||
1302 | while (bj->player_total > 21 && !bj->end_hand) { | ||
1303 | temp = check_for_aces(bj->player_cards[done], | ||
1304 | bj->num_player_cards[done]); | ||
1305 | if(temp != -1) { | ||
1306 | bj->player_cards[done][temp].is_soft_ace = false; | ||
1307 | bj->player_total -= 10; | ||
1308 | update_total(bj); | ||
1309 | if (dbl_down) { | ||
1310 | bj->end_hand = true; | ||
1311 | finish_game(bj); | ||
1312 | } | ||
1313 | } | ||
1314 | else | ||
1315 | bj->end_hand = true; | ||
1316 | } | ||
1317 | |||
1318 | if (bj->end_hand) { | ||
1319 | done++; | ||
1320 | if(todo > 1) { | ||
1321 | if (done == 2) { | ||
1322 | temp = bj->player_total; | ||
1323 | bj->player_total = temp_var; | ||
1324 | temp_var = temp; | ||
1325 | finish_game(bj); | ||
1326 | rb->lcd_getstringsize(" Split 1 ", &w, &h); | ||
1327 | rb->lcd_putsxy(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2, | ||
1328 | " Split 1 "); | ||
1329 | rb->lcd_update_rect(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2, | ||
1330 | w,h); | ||
1331 | bj->current_bet /= 2; | ||
1332 | rb->lcd_update_rect(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2, | ||
1333 | w,h); | ||
1334 | rb->sleep(HZ*2); | ||
1335 | bj->player_total = temp_var; | ||
1336 | finish_game(bj); | ||
1337 | rb->lcd_getstringsize(" Split 2 ", &w, &h); | ||
1338 | rb->lcd_putsxy(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2, | ||
1339 | " Split 2 "); | ||
1340 | rb->lcd_update_rect(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2, | ||
1341 | w,h); | ||
1342 | rb->sleep(HZ*2); | ||
1343 | } | ||
1344 | else { | ||
1345 | bj->end_hand = false; | ||
1346 | bj->split_status = 3; | ||
1347 | temp_var = bj->player_total; | ||
1348 | bj->player_total = bj->player_cards[1][0].value; | ||
1349 | update_total(bj); | ||
1350 | redraw_board(bj); | ||
1351 | player_x += 10; | ||
1352 | rb->lcd_update(); | ||
1353 | } | ||
1354 | } | ||
1355 | else | ||
1356 | finish_game(bj); | ||
1357 | } | ||
1358 | } | ||
1359 | |||
1360 | if (bj->player_money < 10) { | ||
1361 | rb->sleep(HZ); | ||
1362 | return BJ_LOSE; | ||
1363 | } | ||
1364 | |||
1365 | if (bj->end_hand) { /* If hand is over */ | ||
1366 | if (play_again() != 0) /* User wants to quit */ | ||
1367 | return BJ_END; | ||
1368 | else { /* User keeps playing */ | ||
1369 | breakout = false; | ||
1370 | redraw_board(bj); | ||
1371 | if(dbl_down) { | ||
1372 | bj->current_bet /= 2; | ||
1373 | dbl_down = false; | ||
1374 | } | ||
1375 | done = 0; | ||
1376 | todo = 1; | ||
1377 | blackjack_init(bj); | ||
1378 | blackjack_get_bet(bj); | ||
1379 | if (bj->current_bet == 0) | ||
1380 | return BJ_END; | ||
1381 | deal_init_cards(bj); | ||
1382 | blackjack_drawtable(bj); | ||
1383 | rb->lcd_update(); | ||
1384 | } | ||
1385 | } | ||
1386 | } | ||
1387 | /* Never reached */ | ||
1388 | return PLUGIN_OK; | ||
1389 | } | ||
1390 | |||
1391 | /***************************************************************************** | ||
1392 | * plugin entry point. | ||
1393 | ******************************************************************************/ | ||
1394 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) { | ||
1395 | struct game_context bj; | ||
1396 | bool exit = false; | ||
1397 | unsigned int position; | ||
1398 | char str[19]; | ||
1399 | |||
1400 | (void)parameter; | ||
1401 | rb = api; | ||
1402 | |||
1403 | /* load high scores */ | ||
1404 | blackjack_loadscores(&bj); | ||
1405 | |||
1406 | rb->lcd_setfont(FONT_SYSFIXED); | ||
1407 | |||
1408 | while(!exit) { | ||
1409 | switch(blackjack(&bj)){ | ||
1410 | case BJ_LOSE: | ||
1411 | rb->splash(HZ, true, "Not enough money to continue"); | ||
1412 | /* fall through to BJ_END */ | ||
1413 | |||
1414 | case BJ_END: | ||
1415 | if(!bj.resume) { | ||
1416 | if((position = blackjack_recordscore(&bj))) { | ||
1417 | rb->snprintf(str, 19, "New high score #%d!", position); | ||
1418 | rb->splash(HZ*2, true, str); | ||
1419 | } | ||
1420 | } | ||
1421 | break; | ||
1422 | |||
1423 | case BJ_USB: | ||
1424 | rb->lcd_setfont(FONT_UI); | ||
1425 | return PLUGIN_USB_CONNECTED; | ||
1426 | |||
1427 | case BJ_QUIT: | ||
1428 | if(bj.dirty) { | ||
1429 | rb->splash(HZ, true, "Saving high scores..."); | ||
1430 | blackjack_savescores(&bj); | ||
1431 | } | ||
1432 | exit = true; | ||
1433 | break; | ||
1434 | |||
1435 | default: | ||
1436 | break; | ||
1437 | } | ||
1438 | } | ||
1439 | |||
1440 | rb->lcd_setfont(FONT_UI); | ||
1441 | return PLUGIN_OK; | ||
1442 | } | ||