use lib display text to display help messages (FS#10099).
[kugel-rb.git] / apps / plugins / blackjack.c
blob391cd9739489e39b3f1a1ca8c866e10d13ad4c81
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2006 Tom Ross
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "plugin.h"
23 #include "pluginbitmaps/card_deck.h"
24 #include "pluginbitmaps/card_back.h"
26 PLUGIN_HEADER
28 /* save files */
29 #define SCORE_FILE PLUGIN_GAMES_DIR "/blackjack.score"
30 #define SAVE_FILE PLUGIN_GAMES_DIR "/blackjack.save"
32 #define NUM_SCORES LCD_HEIGHT/8-2
34 /* final game return status */
35 #define BJ_END 3
36 #define BJ_USB 2
37 #define BJ_QUIT 1
38 #define BJ_LOSE 0
40 #if CONFIG_KEYPAD == RECORDER_PAD
41 #define BJACK_START BUTTON_ON
42 #define BJACK_QUIT BUTTON_OFF
43 #define BJACK_MAX (BUTTON_ON|BUTTON_UP)
44 #define BJACK_MIN (BUTTON_ON|BUTTON_DOWN)
45 #define BJACK_HIT BUTTON_F1
46 #define BJACK_STAY BUTTON_F2
47 #define BJACK_DOUBLEDOWN BUTTON_F3
48 #define BJACK_SCORES BUTTON_RIGHT
49 #define BJACK_RESUME BUTTON_PLAY
50 #define BJACK_UP BUTTON_UP
51 #define BJACK_DOWN BUTTON_DOWN
52 #define BJACK_RIGHT BUTTON_RIGHT
53 #define BJACK_LEFT BUTTON_LEFT
55 #elif CONFIG_KEYPAD == ONDIO_PAD
56 #define BJACK_START BUTTON_MENU
57 #define BJACK_QUIT BUTTON_OFF
58 #define BJACK_MAX (BUTTON_MENU|BUTTON_UP)
59 #define BJACK_MIN (BUTTON_MENU|BUTTON_DOWN)
60 #define BJACK_HIT BUTTON_LEFT
61 #define BJACK_STAY BUTTON_RIGHT
62 #define BJACK_DOUBLEDOWN BUTTON_UP
63 #define BJACK_SCORES BUTTON_UP
64 #define BJACK_RESUME BUTTON_DOWN
65 #define BJACK_UP BUTTON_UP
66 #define BJACK_DOWN BUTTON_DOWN
67 #define BJACK_RIGHT BUTTON_RIGHT
68 #define BJACK_LEFT BUTTON_LEFT
70 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
71 #define BJACK_START BUTTON_PLAY
72 #define BJACK_QUIT BUTTON_POWER
73 #define BJACK_MAX (BUTTON_PLAY|BUTTON_SCROLL_UP)
74 #define BJACK_MIN (BUTTON_PLAY|BUTTON_SCROLL_DOWN)
75 #define BJACK_HIT BUTTON_PLAY
76 #define BJACK_STAY BUTTON_FF
77 #define BJACK_DOUBLEDOWN BUTTON_REW
78 #define BJACK_SCORES BUTTON_LEFT
79 #define BJACK_RESUME BUTTON_RIGHT
80 #define BJACK_UP BUTTON_SCROLL_UP
81 #define BJACK_DOWN BUTTON_SCROLL_DOWN
82 #define BJACK_RIGHT BUTTON_RIGHT
83 #define BJACK_LEFT BUTTON_LEFT
85 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
86 (CONFIG_KEYPAD == IRIVER_H300_PAD)
87 #define BJACK_START BUTTON_ON
88 #define BJACK_QUIT BUTTON_OFF
89 #define BJACK_MAX (BUTTON_ON|BUTTON_UP)
90 #define BJACK_MIN (BUTTON_ON|BUTTON_DOWN)
91 #define BJACK_HIT BUTTON_ON
92 #define BJACK_STAY BUTTON_REC
93 #define BJACK_DOUBLEDOWN BUTTON_SELECT
94 #define BJACK_SCORES BUTTON_SELECT
95 #define BJACK_RESUME BUTTON_MODE
96 #define BJACK_UP BUTTON_UP
97 #define BJACK_DOWN BUTTON_DOWN
98 #define BJACK_RIGHT BUTTON_RIGHT
99 #define BJACK_LEFT BUTTON_LEFT
101 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
102 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
103 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
104 #define BJACK_START BUTTON_SELECT
105 #define BJACK_QUIT BUTTON_MENU
106 #define BJACK_MAX (BUTTON_SELECT|BUTTON_SCROLL_FWD)
107 #define BJACK_MIN (BUTTON_SELECT|BUTTON_SCROLL_BACK)
108 #define BJACK_HIT BUTTON_SELECT
109 #define BJACK_STAY BUTTON_RIGHT
110 #define BJACK_DOUBLEDOWN BUTTON_LEFT
111 #define BJACK_SCORES BUTTON_RIGHT
112 #define BJACK_RESUME BUTTON_PLAY
113 #define BJACK_UP BUTTON_SCROLL_FWD
114 #define BJACK_DOWN BUTTON_SCROLL_BACK
115 #define BJACK_RIGHT BUTTON_RIGHT
116 #define BJACK_LEFT BUTTON_LEFT
118 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
119 #define BJACK_START BUTTON_PLAY
120 #define BJACK_QUIT BUTTON_POWER
121 #define BJACK_MAX (BUTTON_PLAY|BUTTON_UP)
122 #define BJACK_MIN (BUTTON_PLAY|BUTTON_DOWN)
123 #define BJACK_HIT BUTTON_SELECT
124 #define BJACK_STAY BUTTON_REC
125 #define BJACK_DOUBLEDOWN BUTTON_PLAY
126 #define BJACK_SCORES BUTTON_RIGHT
127 #define BJACK_RESUME BUTTON_DOWN
128 #define BJACK_UP BUTTON_UP
129 #define BJACK_DOWN BUTTON_DOWN
130 #define BJACK_RIGHT BUTTON_RIGHT
131 #define BJACK_LEFT BUTTON_LEFT
133 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
134 #define BJACK_START BUTTON_MODE
135 #define BJACK_QUIT BUTTON_PLAY
136 #define BJACK_MAX (BUTTON_EQ|BUTTON_UP)
137 #define BJACK_MIN (BUTTON_EQ|BUTTON_DOWN)
138 #define BJACK_HIT BUTTON_EQ
139 #define BJACK_STAY BUTTON_MODE
140 #define BJACK_DOUBLEDOWN BUTTON_SELECT
141 #define BJACK_SCORES BUTTON_SELECT
142 #define BJACK_RESUME (BUTTON_EQ|BUTTON_MODE)
143 #define BJACK_UP BUTTON_UP
144 #define BJACK_DOWN BUTTON_DOWN
145 #define BJACK_RIGHT BUTTON_RIGHT
146 #define BJACK_LEFT BUTTON_LEFT
148 #elif CONFIG_KEYPAD == GIGABEAT_PAD
149 #define BJACK_START BUTTON_A
150 #define BJACK_QUIT BUTTON_POWER
151 #define BJACK_MAX BUTTON_VOL_UP
152 #define BJACK_MIN BUTTON_VOL_DOWN
153 #define BJACK_HIT BUTTON_VOL_UP
154 #define BJACK_STAY BUTTON_VOL_DOWN
155 #define BJACK_DOUBLEDOWN BUTTON_SELECT
156 #define BJACK_SCORES BUTTON_RIGHT
157 #define BJACK_RESUME BUTTON_MENU
158 #define BJACK_UP BUTTON_UP
159 #define BJACK_DOWN BUTTON_DOWN
160 #define BJACK_RIGHT BUTTON_RIGHT
161 #define BJACK_LEFT BUTTON_LEFT
163 #elif CONFIG_KEYPAD == SANSA_E200_PAD
164 #define BJACK_START BUTTON_SELECT
165 #define BJACK_QUIT BUTTON_POWER
166 #define BJACK_MAX (BUTTON_REC|BUTTON_UP)
167 #define BJACK_MIN (BUTTON_REC|BUTTON_DOWN)
168 #define BJACK_HIT BUTTON_SELECT
169 #define BJACK_STAY BUTTON_RIGHT
170 #define BJACK_DOUBLEDOWN BUTTON_LEFT
171 #define BJACK_SCORES BUTTON_UP
172 #define BJACK_RESUME BUTTON_DOWN
173 #define BJACK_UP BUTTON_SCROLL_FWD
174 #define BJACK_DOWN BUTTON_SCROLL_BACK
175 #define BJACK_RIGHT BUTTON_RIGHT
176 #define BJACK_LEFT BUTTON_LEFT
178 #elif CONFIG_KEYPAD == SANSA_FUZE_PAD
179 #define BJACK_START BUTTON_SELECT
180 #define BJACK_QUIT (BUTTON_HOME|BUTTON_REPEAT)
181 #define BJACK_MAX (BUTTON_SELECT|BUTTON_UP)
182 #define BJACK_MIN (BUTTON_SELECT|BUTTON_DOWN)
183 #define BJACK_HIT (BUTTON_SELECT|BUTTON_REL)
184 #define BJACK_STAY BUTTON_RIGHT
185 #define BJACK_DOUBLEDOWN BUTTON_LEFT
186 #define BJACK_SCORES BUTTON_DOWN
187 #define BJACK_RESUME BUTTON_UP
188 #define BJACK_UP BUTTON_SCROLL_FWD
189 #define BJACK_DOWN BUTTON_SCROLL_BACK
190 #define BJACK_RIGHT BUTTON_RIGHT
191 #define BJACK_LEFT BUTTON_LEFT
194 #elif CONFIG_KEYPAD == SANSA_C200_PAD
195 #define BJACK_START BUTTON_SELECT
196 #define BJACK_QUIT BUTTON_POWER
197 #define BJACK_MAX BUTTON_VOL_UP
198 #define BJACK_MIN BUTTON_VOL_DOWN
199 #define BJACK_HIT BUTTON_SELECT
200 #define BJACK_STAY BUTTON_RIGHT
201 #define BJACK_DOUBLEDOWN BUTTON_LEFT
202 #define BJACK_SCORES BUTTON_REC
203 #define BJACK_RESUME BUTTON_DOWN
204 #define BJACK_UP BUTTON_UP
205 #define BJACK_DOWN BUTTON_DOWN
206 #define BJACK_RIGHT BUTTON_RIGHT
207 #define BJACK_LEFT BUTTON_LEFT
209 #elif CONFIG_KEYPAD == SANSA_CLIP_PAD
210 #define BJACK_START BUTTON_SELECT
211 #define BJACK_QUIT BUTTON_POWER
212 #define BJACK_MAX BUTTON_VOL_UP
213 #define BJACK_MIN BUTTON_VOL_DOWN
214 #define BJACK_HIT BUTTON_SELECT
215 #define BJACK_STAY BUTTON_RIGHT
216 #define BJACK_DOUBLEDOWN BUTTON_LEFT
217 #define BJACK_SCORES BUTTON_HOME
218 #define BJACK_RESUME BUTTON_DOWN
219 #define BJACK_UP BUTTON_UP
220 #define BJACK_DOWN BUTTON_DOWN
221 #define BJACK_RIGHT BUTTON_RIGHT
222 #define BJACK_LEFT BUTTON_LEFT
224 #elif CONFIG_KEYPAD == SANSA_M200_PAD
225 #define BJACK_START (BUTTON_SELECT | BUTTON_REL)
226 #define BJACK_QUIT BUTTON_POWER
227 #define BJACK_MAX BUTTON_VOL_UP
228 #define BJACK_MIN BUTTON_VOL_DOWN
229 #define BJACK_HIT (BUTTON_SELECT | BUTTON_REL)
230 #define BJACK_STAY BUTTON_RIGHT
231 #define BJACK_DOUBLEDOWN BUTTON_LEFT
232 #define BJACK_SCORES (BUTTON_SELECT | BUTTON_UP)
233 #define BJACK_RESUME BUTTON_DOWN
234 #define BJACK_UP BUTTON_UP
235 #define BJACK_DOWN BUTTON_DOWN
236 #define BJACK_RIGHT BUTTON_RIGHT
237 #define BJACK_LEFT BUTTON_LEFT
239 #elif CONFIG_KEYPAD == ELIO_TPJ1022_PAD
240 #define BJACK_START BUTTON_MAIN
241 #define BJACK_QUIT BUTTON_POWER
242 #define BJACK_MAX (BUTTON_REC|BUTTON_UP)
243 #define BJACK_MIN (BUTTON_REC|BUTTON_DOWN)
244 #define BJACK_HIT BUTTON_MAIN
245 #define BJACK_STAY BUTTON_MENU
246 #define BJACK_DOUBLEDOWN BUTTON_DOWN
247 #define BJACK_SCORES BUTTON_UP
248 #define BJACK_RESUME BUTTON_FF
249 #define BJACK_UP BUTTON_UP
250 #define BJACK_DOWN BUTTON_DOWN
251 #define BJACK_RIGHT BUTTON_RIGHT
252 #define BJACK_LEFT BUTTON_LEFT
254 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
255 #define BJACK_START BUTTON_PLAY
256 #define BJACK_QUIT BUTTON_BACK
257 #define BJACK_MAX BUTTON_VOL_UP
258 #define BJACK_MIN BUTTON_VOL_DOWN
259 #define BJACK_HIT BUTTON_VOL_UP
260 #define BJACK_STAY BUTTON_VOL_DOWN
261 #define BJACK_DOUBLEDOWN BUTTON_SELECT
262 #define BJACK_SCORES BUTTON_RIGHT
263 #define BJACK_RESUME BUTTON_MENU
264 #define BJACK_UP BUTTON_UP
265 #define BJACK_DOWN BUTTON_DOWN
266 #define BJACK_RIGHT BUTTON_RIGHT
267 #define BJACK_LEFT BUTTON_LEFT
269 #elif CONFIG_KEYPAD == MROBE100_PAD
271 #define BJACK_START BUTTON_SELECT
272 #define BJACK_QUIT BUTTON_POWER
273 #define BJACK_MAX BUTTON_MENU
274 #define BJACK_MIN BUTTON_DISPLAY
275 #define BJACK_HIT BUTTON_MENU
276 #define BJACK_STAY BUTTON_DISPLAY
277 #define BJACK_DOUBLEDOWN BUTTON_DOWN
278 #define BJACK_SCORES BUTTON_RIGHT
279 #define BJACK_RESUME BUTTON_PLAY
280 #define BJACK_UP BUTTON_UP
281 #define BJACK_DOWN BUTTON_DOWN
282 #define BJACK_RIGHT BUTTON_RIGHT
283 #define BJACK_LEFT BUTTON_LEFT
285 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
287 #define BJACK_START BUTTON_RC_PLAY
288 #define BJACK_QUIT BUTTON_RC_REC
289 #define BJACK_MAX (BUTTON_RC_PLAY|BUTTON_RC_VOL_UP)
290 #define BJACK_MIN (BUTTON_RC_PLAY|BUTTON_RC_VOL_DOWN)
291 #define BJACK_HIT BUTTON_RC_PLAY
292 #define BJACK_STAY BUTTON_RC_FF
293 #define BJACK_DOUBLEDOWN BUTTON_RC_REW
294 #define BJACK_SCORES BUTTON_RC_MENU
295 #define BJACK_RESUME BUTTON_RC_MODE
296 #define BJACK_UP BUTTON_RC_VOL_UP
297 #define BJACK_DOWN BUTTON_RC_VOL_DOWN
298 #define BJACK_RIGHT BUTTON_RC_FF
299 #define BJACK_LEFT BUTTON_RC_REW
301 #elif CONFIG_KEYPAD == COWOND2_PAD
302 #define BJACK_QUIT BUTTON_POWER
303 #define BJACK_DOUBLEDOWN BUTTON_MINUS
304 #define BJACK_SCORES BUTTON_MENU
306 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
307 #define BJACK_START BUTTON_SELECT
308 #define BJACK_QUIT BUTTON_BACK
309 #define BJACK_MAX (BUTTON_CUSTOM|BUTTON_UP)
310 #define BJACK_MIN (BUTTON_CUSTOM|BUTTON_DOWN)
311 #define BJACK_HIT BUTTON_UP
312 #define BJACK_STAY BUTTON_DOWN
313 #define BJACK_DOUBLEDOWN BUTTON_CUSTOM
314 #define BJACK_SCORES BUTTON_RIGHT
315 #define BJACK_RESUME BUTTON_MENU
316 #define BJACK_UP BUTTON_UP
317 #define BJACK_DOWN BUTTON_DOWN
318 #define BJACK_RIGHT BUTTON_RIGHT
319 #define BJACK_LEFT BUTTON_LEFT
321 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
322 #define BJACK_START BUTTON_MENU
323 #define BJACK_QUIT BUTTON_POWER
324 #define BJACK_MAX BUTTON_VOL_UP
325 #define BJACK_MIN BUTTON_VOL_DOWN
326 #define BJACK_HIT BUTTON_VOL_UP
327 #define BJACK_STAY BUTTON_VOL_DOWN
328 #define BJACK_DOUBLEDOWN BUTTON_SELECT
329 #define BJACK_SCORES BUTTON_RIGHT
330 #define BJACK_RESUME BUTTON_VIEW
331 #define BJACK_UP BUTTON_UP
332 #define BJACK_DOWN BUTTON_DOWN
333 #define BJACK_RIGHT BUTTON_RIGHT
334 #define BJACK_LEFT BUTTON_LEFT
336 #elif CONFIG_KEYPAD == ONDAVX747_PAD
337 #define BJACK_QUIT BUTTON_POWER
338 #define BJACK_DOUBLEDOWN BUTTON_VOL_DOWN
339 #define BJACK_SCORES BUTTON_MENU
341 #elif CONFIG_KEYPAD == MROBE500_PAD
342 #define BJACK_QUIT BUTTON_POWER
344 #else
345 #error No keymap defined!
346 #endif
348 #ifdef HAVE_TOUCHSCREEN
349 #ifndef BJACK_DOUBLEDOWN
350 #define BJACK_DOUBLEDOWN BUTTON_MIDLEFT
351 #endif
352 #ifndef BJACK_SCORES
353 #define BJACK_SCORES BUTTON_MIDRIGHT
354 #endif
355 #ifndef BJACK_START
356 #define BJACK_START BUTTON_CENTER
357 #endif
358 #ifndef BJACK_HIT
359 #define BJACK_HIT BUTTON_CENTER
360 #endif
361 #ifndef BJACK_MAX
362 #define BJACK_MAX BUTTON_TOPRIGHT
363 #endif
364 #ifndef BJACK_MIN
365 #define BJACK_MIN BUTTON_TOPLEFT
366 #endif
367 #ifndef BJACK_RESUME
368 #define BJACK_RESUME BUTTON_BOTTOMRIGHT
369 #endif
370 #ifndef BJACK_STAY
371 #define BJACK_STAY BUTTON_BOTTOMLEFT
372 #endif
373 #ifndef BJACK_UP
374 #define BJACK_UP BUTTON_TOPMIDDLE
375 #endif
376 #ifndef BJACK_DOWN
377 #define BJACK_DOWN BUTTON_BOTTOMMIDDLE
378 #endif
379 #ifndef BJACK_RIGHT
380 #define BJACK_RIGHT BUTTON_MIDRIGHT
381 #endif
382 #ifndef BJACK_LEFT
383 #define BJACK_LEFT BUTTON_MIDLEFT
384 #endif
386 #endif
388 #ifdef HAVE_LCD_COLOR
389 #define BG_COLOR LCD_RGBPACK(0,157,0)
390 #define FG_COLOR LCD_WHITE
391 #elif LCD_DEPTH > 1
392 #define BG_COLOR LCD_WHITE
393 #define FG_COLOR LCD_BLACK
394 #endif
396 #define CARD_WIDTH BMPWIDTH_card_back
397 #define CARD_HEIGHT BMPHEIGHT_card_back
399 /* This is the max amount of cards onscreen before condensing */
400 #define MAX_CARDS LCD_WIDTH/(CARD_WIDTH+4)
402 extern const fb_data card_deck[];
403 extern const fb_data card_back[];
405 #define NEXT_CARD bj->player_cards[done][bj->num_player_cards[done]]
407 /* dealer and player card positions */
408 unsigned int dealer_x, dealer_y, player_x, player_y;
410 typedef struct card {
411 unsigned int value; /* Card's value in Blackjack */
412 unsigned int num; /* Value on card face 0-12 (0=Ace, 1=2, 11=Q) */
413 unsigned int suit; /* 0:Spades, 1:Hearts, 2: Clubs; 3: Diamonds */
414 bool is_soft_ace;
415 } card;
417 typedef struct game_context {
418 struct card player_cards[2][22]; /* 22 Cards means the deal was all aces */
419 struct card dealer_cards[22]; /* That is the worst-case scenario */
420 unsigned int player_total;
421 unsigned int dealer_total;
422 signed int player_money;
423 unsigned int num_player_cards[2];
424 unsigned int num_dealer_cards;
425 unsigned int current_bet;
426 unsigned int split_status; /* 0 = split hasn't been asked, *
427 * 1 = split did not occur *
428 * 2 = split occurred *
429 * 3 = split occurred and 1st hand done */
430 bool is_blackjack;
431 bool end_hand;
432 bool asked_insurance;
433 signed short highscores[NUM_SCORES];
434 bool resume;
435 bool dirty;
436 } game_context;
438 /*****************************************************************************
439 * blackjack_init() initializes blackjack data structures.
440 ******************************************************************************/
441 static void blackjack_init(struct game_context* bj) {
442 /* seed the rand generator */
443 rb->srand(*rb->current_tick);
445 /* reset card positions */
446 dealer_x = 4;
447 dealer_y = LCD_HEIGHT/4 - CARD_HEIGHT/2;
448 player_x = 4;
449 player_y = LCD_HEIGHT - LCD_HEIGHT/4 - CARD_HEIGHT/2;
451 /* check for resumed game */
452 if(bj->resume) return;
454 /* reset scoring */
455 bj->player_total = 0;
456 bj->dealer_total = 0;
457 bj->num_player_cards[0] = 2;
458 bj->num_player_cards[1] = 0;
459 bj->num_dealer_cards = 2;
460 bj->end_hand = false;
461 bj->split_status = 0;
462 bj->is_blackjack = false;
463 bj->asked_insurance = false;
466 /*****************************************************************************
467 * blackjack_drawtable() draws the table and some text.
468 ******************************************************************************/
469 static void blackjack_drawtable(struct game_context* bj) {
470 unsigned int w, h, y_loc;
471 char str[10];
473 #if LCD_HEIGHT <= 64
474 rb->lcd_getstringsize("Bet", &w, &h);
475 rb->lcd_putsxy(LCD_WIDTH - w, 2*h + 1, "Bet");
476 rb->snprintf(str, 9, "$%d", bj->current_bet);
477 rb->lcd_getstringsize(str, &w, &h);
478 rb->lcd_putsxy(LCD_WIDTH - w, 3*h + 1, str);
479 y_loc = LCD_HEIGHT/2;
480 #else
481 rb->lcd_getstringsize("Bet", &w, &h);
482 rb->lcd_putsxy(LCD_WIDTH - w, 5*h / 2, "Bet");
483 rb->snprintf(str, 9, "$%d", bj->current_bet);
484 rb->lcd_getstringsize(str, &w, &h);
485 rb->lcd_putsxy(LCD_WIDTH - w, 7*h / 2, str);
486 rb->lcd_hline(0, LCD_WIDTH, LCD_HEIGHT/2);
487 y_loc = LCD_HEIGHT/2 + h;
488 #endif
490 rb->lcd_putsxy(0,0, "Dealer");
491 rb->lcd_getstringsize("Player", &w, &h);
492 rb->lcd_putsxy(0, y_loc, "Player");
493 rb->lcd_getstringsize("Total", &w, &h);
494 rb->lcd_putsxy(LCD_WIDTH - w, y_loc, "Total");
495 rb->lcd_getstringsize("Money", &w, &h);
496 rb->lcd_putsxy(LCD_WIDTH - w, 0, "Money");
497 rb->snprintf(str, 9, "$%d", bj->player_money - bj->current_bet);
498 rb->lcd_getstringsize(str, &w, &h);
499 rb->lcd_putsxy(LCD_WIDTH - w, h + 1, str);
500 rb->snprintf(str, 3, "%d", bj->player_total);
501 rb->lcd_getstringsize(str, &w, &h);
502 rb->lcd_putsxy(LCD_WIDTH - w, y_loc + h, str);
505 /*****************************************************************************
506 * find_value() is passed a card and returns its blackjack value.
507 ******************************************************************************/
508 static unsigned int find_value(unsigned int number) {
509 unsigned int thisValue;
510 if (number == 0)
511 thisValue = 11; /* Aces get a value of 11 at first */
512 else if (number < 10)
513 thisValue = number + 1;
514 else
515 thisValue = 10; /* Anything 10 or higher gets a value of 10 */
517 return thisValue;
520 /*****************************************************************************
521 * draw_card() draws a card to the screen.
522 ******************************************************************************/
523 static void draw_card(struct card temp_card, bool shown, unsigned int x,
524 unsigned int y) {
525 if(shown)
526 rb->lcd_bitmap_part(card_deck, CARD_WIDTH*temp_card.num,
527 CARD_HEIGHT*temp_card.suit, BMPWIDTH_card_deck,
528 x+1, y+1, CARD_WIDTH, CARD_HEIGHT);
529 else
530 rb->lcd_bitmap(card_back, x+1, y+1,CARD_WIDTH, CARD_HEIGHT);
531 #if LCD_DEPTH > 1
532 rb->lcd_set_foreground(LCD_BLACK);
533 #endif
535 /* Print outlines */
536 #if CARD_WIDTH >= 26
537 rb->lcd_hline(x+2, x+CARD_WIDTH-1, y);
538 rb->lcd_hline(x+2, x+CARD_WIDTH-1, y+CARD_HEIGHT+1);
539 rb->lcd_vline(x, y+2, y+CARD_HEIGHT-3);
540 rb->lcd_vline(x+CARD_WIDTH+1, y+2, y+CARD_HEIGHT-1);
541 rb->lcd_drawpixel(x+1, y+1);
542 rb->lcd_drawpixel(x+1, y+CARD_HEIGHT);
543 rb->lcd_drawpixel(x+CARD_WIDTH, y+1);
544 rb->lcd_drawpixel(x+CARD_WIDTH, y+CARD_HEIGHT);
545 #else
546 rb->lcd_hline(x+1, x+CARD_WIDTH, y);
547 rb->lcd_hline(x+1, x+CARD_WIDTH, y+CARD_HEIGHT+1);
548 rb->lcd_vline(x, y+1, y+CARD_HEIGHT);
549 rb->lcd_vline(x+CARD_WIDTH+1, y+1, y+CARD_HEIGHT);
550 #endif
552 #if LCD_DEPTH > 1
553 rb->lcd_set_foreground(FG_COLOR);
554 #endif
557 /*****************************************************************************
558 * new_card() initializes a new card and gives it values.
559 ******************************************************************************/
560 static struct card new_card(void) {
561 struct card new_card;
562 new_card.suit = rb->rand()%4; /* Random number 0-3 */
563 new_card.num = rb->rand()%13; /* Random number 0-12 */
564 new_card.value = find_value(new_card.num);
565 new_card.is_soft_ace = new_card.num == 0 ? true : false;
566 return new_card;
569 /*****************************************************************************
570 * deal_init_card() deals and draws to the screen the player's and dealer's
571 * initial cards.
572 ******************************************************************************/
573 static void deal_init_cards(struct game_context* bj) {
574 bj->dealer_cards[0] = new_card();
575 bj->dealer_total += bj->dealer_cards[0].value;
577 draw_card(bj->dealer_cards[0], false, dealer_x, dealer_y);
579 bj->dealer_cards[1] = new_card();
580 bj->dealer_total += bj->dealer_cards[1].value;
581 draw_card(bj->dealer_cards[1], true, dealer_x + CARD_WIDTH + 4, dealer_y);
583 bj->player_cards[0][0] = new_card();
584 bj->player_total += bj->player_cards[0][0].value;
585 draw_card(bj->player_cards[0][0], true, player_x, player_y);
586 player_x += CARD_WIDTH + 4;
588 bj->player_cards[0][1] = new_card();
589 bj->player_total += bj->player_cards[0][1].value;
590 draw_card(bj->player_cards[0][1], true, player_x, player_y);
591 player_x += CARD_WIDTH + 4;
594 /*****************************************************************************
595 * redraw_board() redraws all the cards and the board
596 ******************************************************************************/
597 static void redraw_board(struct game_context* bj) {
598 unsigned int i, n, upper_bound;
599 rb->lcd_clear_display();
601 blackjack_drawtable(bj);
602 player_x = 4;
603 dealer_x = 4;
604 upper_bound = bj->split_status > 1 ? 2 : 1;
606 for (i = 0; i < bj->num_dealer_cards; i++) {
607 if (!bj->end_hand) {
608 draw_card(bj->dealer_cards[0], false, dealer_x, dealer_y);
610 /* increment i so the dealer's first card isn't displayed */
611 i++;
612 dealer_x += CARD_WIDTH + 4;
614 draw_card(bj->dealer_cards[i], true, dealer_x, dealer_y);
616 if (bj->num_dealer_cards > MAX_CARDS-1)
617 dealer_x += 10;
618 else
619 dealer_x += CARD_WIDTH + 4;
622 for (n = 0; n < upper_bound; n++) {
623 for (i = 0; i < bj->num_player_cards[n]; i++) {
624 draw_card(bj->player_cards[n][i], true, player_x, player_y);
625 if (bj->split_status>1 || bj->num_player_cards[n]>MAX_CARDS)
626 player_x += 10;
627 else
628 player_x += CARD_WIDTH + 4;
630 if (bj->split_status > 1)
631 player_x = LCD_WIDTH/2 + 4;
635 /*****************************************************************************
636 * update_total updates the player's total
637 ******************************************************************************/
638 static void update_total(struct game_context* bj) {
639 char total[3];
640 unsigned int w, h;
641 rb->snprintf(total, 3, "%d", bj->player_total);
642 rb->lcd_getstringsize(total, &w, &h);
643 #if LCD_HEIGHT > 64
644 h *= 2;
645 #endif
646 rb->lcd_putsxy(LCD_WIDTH - w, LCD_HEIGHT/2 + h, total);
647 rb->lcd_update_rect(LCD_WIDTH - w, LCD_HEIGHT/2 + h, w, h);
651 /*****************************************************************************
652 * check_for_aces() is passed an array of cards and returns where an ace is
653 * located. Otherwise, returns -1.
654 ******************************************************************************/
655 static signed int check_for_aces(struct card temp_cards[],
656 unsigned int size) {
657 unsigned int i;
658 for(i = 0; i < size; i++) {
659 if (temp_cards[i].is_soft_ace == true)
660 return i;
662 return -1;
665 /*****************************************************************************
666 * check_totals() compares player and dealer totals.
667 * 0: bust 1: loss, 2: push, 3: win, 4: blackjack, 5: something's not right...
668 ******************************************************************************/
669 static unsigned int check_totals(struct game_context* bj)
671 unsigned int temp;
672 if (bj->player_total > 21)
673 temp = 0;
674 else if (bj->player_total == 21 && bj->is_blackjack)
675 if (bj->dealer_total == 21 && bj->num_dealer_cards == 2)
676 temp = 2;
677 else
678 temp = 4;
679 else if (bj->player_total == bj->dealer_total)
680 temp = 2;
681 else if (bj->dealer_total > 21 && bj->player_total < 22)
682 temp = 3;
683 else if (bj->dealer_total > bj->player_total)
684 temp = 1;
685 else if (bj->player_total > bj->dealer_total)
686 temp = 3;
687 else
688 temp = 5;
690 return temp;
693 /*****************************************************************************
694 * finish_dealer() draws cards for the dealer until he has 17 or more.
695 ******************************************************************************/
696 static void finish_dealer(struct game_context* bj) {
697 signed int temp = 0;
699 if (bj->dealer_total > 16 && bj->dealer_total < 22)
700 return;
702 while (bj->dealer_total < 17) {
703 bj->dealer_cards[bj->num_dealer_cards] = new_card();
704 bj->dealer_total += bj->dealer_cards[bj->num_dealer_cards].value;
705 bj->num_dealer_cards++;
708 while (bj->dealer_total > 21) {
709 temp = check_for_aces(bj->dealer_cards, bj->num_dealer_cards);
710 if(temp != -1) {
711 bj->dealer_cards[temp].is_soft_ace = false;
712 bj->dealer_total -= 10;
714 else
715 return;
719 /*****************************************************************************
720 * finish_game() completes the game once player's turn is over.
721 ******************************************************************************/
722 static void finish_game(struct game_context* bj) {
723 unsigned int rValue, w, h;
724 char str[19];
726 do {
727 finish_dealer(bj);
728 } while (bj->dealer_total < 17);
730 redraw_board(bj);
731 rValue = check_totals(bj);
733 if (rValue == 0) {
734 rb->snprintf(str, sizeof(str), " Bust! ");
735 bj->player_money -= bj->current_bet;
737 else if (rValue == 1) {
738 rb->snprintf(str, sizeof(str), " Sorry, you lost. ");
739 bj->player_money -= bj->current_bet;
741 else if (rValue == 2) {
742 rb->snprintf(str, sizeof(str), " Push ");
744 else if (rValue == 3) {
745 rb->snprintf(str, sizeof(str), " You won! ");
746 bj->player_money+= bj->current_bet;
748 else {
749 rb->snprintf(str, sizeof(str), " Blackjack! ");
750 bj->player_money += bj->current_bet * 3 / 2;
752 rb->lcd_getstringsize(str, &w, &h);
754 #if LCD_HEIGHT <= 64
755 rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID);
756 rb->lcd_fillrect(0, LCD_HEIGHT/2, LCD_WIDTH, LCD_HEIGHT/2);
757 rb->lcd_set_drawmode(DRMODE_SOLID);
758 rb->lcd_putsxy(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + h, str);
759 rb->snprintf(str, 12, "You have %d", bj->player_total);
760 rb->lcd_getstringsize(str, &w, &h);
761 rb->lcd_putsxy(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2, str);
762 #else
763 rb->lcd_putsxy(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 - h/2, str);
764 #endif
765 rb->lcd_update();
768 /*****************************************************************************
769 * blackjack_recordscore() inserts a high score into the high scores list and
770 * returns the high score position.
771 ******************************************************************************/
772 static unsigned int blackjack_recordscore(struct game_context* bj) {
773 unsigned int i;
774 unsigned int position = 0;
775 signed short current, temp;
777 /* calculate total score */
778 current = bj->player_money;
779 if(current <= 10) return 0;
781 /* insert the current score into the high scores */
782 for(i=0; i<NUM_SCORES; i++) {
783 if(current >= bj->highscores[i]) {
784 if(!position) {
785 position = i+1;
786 bj->dirty = true;
788 temp = bj->highscores[i];
789 bj->highscores[i] = current;
790 current = temp;
794 return position;
797 /*****************************************************************************
798 * blackjack_loadscores() loads the high scores saved file.
799 ******************************************************************************/
800 static void blackjack_loadscores(struct game_context* bj) {
801 signed int fd;
803 bj->dirty = false;
805 /* clear high scores */
806 rb->memset(bj->highscores, 0, sizeof(bj->highscores));
808 /* open scores file */
809 fd = rb->open(SCORE_FILE, O_RDONLY);
810 if(fd < 0) return;
812 /* read in high scores */
813 if(rb->read(fd, bj->highscores, sizeof(bj->highscores)) <= 0) {
814 /* scores are bad, reset */
815 rb->memset(bj->highscores, 0, sizeof(bj->highscores));
818 rb->close(fd);
821 /*****************************************************************************
822 * blackjack_savescores() saves the high scores saved file.
823 ******************************************************************************/
824 static void blackjack_savescores(struct game_context* bj) {
825 unsigned int fd;
827 /* write out the high scores to the save file */
828 fd = rb->open(SCORE_FILE, O_WRONLY|O_CREAT);
829 rb->write(fd, bj->highscores, sizeof(bj->highscores));
830 rb->close(fd);
831 bj->dirty = false;
834 /*****************************************************************************
835 * blackjack_loadgame() loads the saved game and returns load success.
836 ******************************************************************************/
837 static bool blackjack_loadgame(struct game_context* bj) {
838 signed int fd;
839 bool loaded = false;
841 /* open game file */
842 fd = rb->open(SAVE_FILE, O_RDONLY);
843 if(fd < 0) return loaded;
845 /* read in saved game */
846 while(true) {
847 if(rb->read(fd, &bj->player_money, sizeof(bj->player_money)) <= 0) break;
848 if(rb->read(fd, &bj->player_total, sizeof(bj->player_total)) <= 0) break;
849 if(rb->read(fd, &bj->dealer_total, sizeof(bj->dealer_total)) <= 0) break;
850 if(rb->read(fd, &bj->num_player_cards, sizeof(bj->num_player_cards))<=0)
851 break;
852 if(rb->read(fd, &bj->num_dealer_cards, sizeof(bj->num_dealer_cards))<=0)
853 break;
854 if(rb->read(fd, &bj->current_bet, sizeof(bj->current_bet)) <= 0) break;
855 if(rb->read(fd, &bj->is_blackjack, sizeof(bj->is_blackjack)) <= 0) break;
856 if(rb->read(fd, &bj->split_status, sizeof(bj->split_status)) <= 0) break;
857 if(rb->read(fd, &bj->asked_insurance, sizeof(bj->asked_insurance)) <= 0)
858 break;
859 if(rb->read(fd, &bj->end_hand, sizeof(bj->end_hand)) <= 0) break;
860 if(rb->read(fd, &bj->player_cards, sizeof(bj->player_cards)) <= 0) break;
861 if(rb->read(fd, &bj->dealer_cards, sizeof(bj->dealer_cards)) <= 0) break;
862 bj->resume = true;
863 loaded = true;
864 break;
867 rb->close(fd);
869 /* delete saved file */
870 rb->remove(SAVE_FILE);
871 return loaded;
874 /*****************************************************************************
875 * blackjack_savegame() saves the current game state.
876 ******************************************************************************/
877 static void blackjack_savegame(struct game_context* bj) {
878 unsigned int fd;
880 /* write out the game state to the save file */
881 fd = rb->open(SAVE_FILE, O_WRONLY|O_CREAT);
882 rb->write(fd, &bj->player_money, sizeof(bj->player_money));
883 rb->write(fd, &bj->player_total, sizeof(bj->player_total));
884 rb->write(fd, &bj->dealer_total, sizeof(bj->dealer_total));
885 rb->write(fd, &bj->num_player_cards, sizeof(bj->num_player_cards));
886 rb->write(fd, &bj->num_dealer_cards, sizeof(bj->num_dealer_cards));
887 rb->write(fd, &bj->current_bet, sizeof(bj->current_bet));
888 rb->write(fd, &bj->is_blackjack, sizeof(bj->is_blackjack));
889 rb->write(fd, &bj->split_status, sizeof(bj->split_status));
890 rb->write(fd, &bj->asked_insurance, sizeof(bj->asked_insurance));
891 rb->write(fd, &bj->end_hand, sizeof(bj->end_hand));
892 rb->write(fd, &bj->player_cards, sizeof(bj->player_cards));
893 rb->write(fd, &bj->dealer_cards, sizeof(bj->dealer_cards));
894 rb->close(fd);
896 bj->resume = true;
899 /*****************************************************************************
900 * blackjack_callback() is the default event handler callback which is called
901 * on usb connect and shutdown.
902 ******************************************************************************/
903 static void blackjack_callback(void* param) {
904 struct game_context* bj = (struct game_context*) param;
905 if(bj->dirty) {
906 rb->splash(HZ, "Saving high scores...");
907 blackjack_savescores(bj);
911 /*****************************************************************************
912 * blackjack_get_yes_no() gets a yes/no answer from the user
913 ******************************************************************************/
914 static unsigned int blackjack_get_yes_no(char message[20]) {
915 int button;
916 unsigned int w, h, b, choice = 0;
917 bool breakout = false;
918 char message_yes[24], message_no[24];
920 rb->strcpy(message_yes, message);
921 rb->strcpy(message_no, message);
922 rb->strcat(message_yes, " Yes");
923 rb->strcat(message_no, " No");
924 rb->lcd_getstringsize(message_yes, &w, &h);
925 const char *stg[] = {message_yes, message_no};
927 #if LCD_HEIGHT <= 64
928 b = 2*h+1;
929 #else
930 b = h-1;
931 #endif
933 #ifdef HAVE_LCD_COLOR
934 rb->lcd_fillrect(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + b, w+1, h+3);
935 rb->lcd_set_foreground(LCD_BLACK);
936 rb->lcd_set_background(LCD_WHITE);
937 #else
938 rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID);
939 rb->lcd_fillrect(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + b, w+1, h+3);
940 rb->lcd_set_drawmode(DRMODE_SOLID);
941 #endif
942 rb->lcd_drawrect(LCD_WIDTH/2 - w/2 - 1, LCD_HEIGHT/2 + b - 1, w+3, h+4);
944 while(!breakout) {
945 rb->lcd_putsxy(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + b +1, stg[choice]);
946 rb->lcd_update_rect(LCD_WIDTH/2 - w/2 - 1, LCD_HEIGHT/2 + b -1,
947 w+3, h+4);
948 button = rb->button_get(true);
950 switch(button) {
951 case BJACK_LEFT:
952 case (BJACK_LEFT|BUTTON_REPEAT):
953 case BJACK_RIGHT:
954 case (BJACK_RIGHT|BUTTON_REPEAT):
955 choice ^= 1;
956 break;
957 case BJACK_START: breakout = true;
958 break;
959 case BJACK_QUIT: breakout = true;
960 choice = BJ_QUIT;
961 break;
965 #if LCD_DEPTH > 1
966 rb->lcd_set_foreground(FG_COLOR);
967 rb->lcd_set_background(BG_COLOR);
968 #endif
969 return choice;
972 /*****************************************************************************
973 * blackjack_get_amount() gets an amount from the player to be used
974 ******************************************************************************/
975 static signed int blackjack_get_amount(char message[20], signed int lower_limit,
976 signed int upper_limit,
977 signed int start) {
978 int button;
979 char str[6];
980 bool changed = false;
981 unsigned int w, h;
982 signed int amount;
984 rb->lcd_getstringsize("A", &w, &h); /* find the size of one character */
986 if (start > upper_limit)
987 amount = upper_limit;
988 else if (start < lower_limit)
989 amount = lower_limit;
990 else
991 amount = start;
993 #if LCD_DEPTH > 1
994 rb->lcd_set_background(LCD_WHITE);
995 rb->lcd_set_foreground(LCD_BLACK);
996 #endif
998 #if LCD_HEIGHT <= 64
999 rb->lcd_clear_display();
1000 rb->lcd_puts(0, 1, message);
1001 rb->snprintf(str, 9, "$%d", amount);
1002 rb->lcd_puts(0, 2, str);
1003 rb->lcd_puts(0, 3, "RIGHT: +1");
1004 rb->lcd_puts(0, 4, "LEFT: -1");
1005 rb->lcd_puts(0, 5, "UP: +10");
1006 rb->lcd_puts(0, 6, "DOWN: -10");
1007 rb->lcd_update();
1008 #else
1009 rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID);
1010 rb->lcd_fillrect(LCD_WIDTH/2 - 9*w - 1, LCD_HEIGHT/2 - 4*h - 3, 37*w / 2,
1011 8*h -3);
1012 rb->lcd_set_drawmode(DRMODE_SOLID);
1013 rb->lcd_drawrect(LCD_WIDTH/2 - 9*w - 1, LCD_HEIGHT/2 - 4*h - 3, 37*w / 2,
1014 8*h -3);
1015 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 4*h - 1, message);
1016 rb->snprintf(str, 9, "$%d", amount);
1017 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, str);
1018 #if (CONFIG_KEYPAD == IPOD_4G_PAD) || \
1019 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
1020 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
1021 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - h-2, " >>|: +1");
1022 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 1, " |<<: -1");
1023 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + h, "SCROLL+: +10");
1024 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + 2*h + 1, "SCROLL-: -10");
1025 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
1026 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - h-2, "RIGHT: +1");
1027 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 1, "LEFT: -1");
1028 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + h, "SCROLL+: +10");
1029 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + 2*h + 1, "SCROLL-: -10");
1030 #else
1031 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - h-2, "RIGHT: +1");
1032 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 1, "LEFT: -1");
1033 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + h, "UP: +10");
1034 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + 2*h + 1, "DOWN: -10");
1035 #endif
1036 rb->lcd_update_rect(LCD_WIDTH/2 - 9*w - 2, LCD_HEIGHT/2 - 9*h/2, 37*w/2 + 1,
1037 8*h-2);
1038 #endif
1040 while(true) {
1041 button = rb->button_get(true);
1043 switch(button) {
1044 case BJACK_UP:
1045 case (BJACK_UP|BUTTON_REPEAT):
1046 if (amount + 10 < upper_limit + 1) {
1047 amount += 10;
1048 changed = true;
1050 break;
1051 case BJACK_DOWN:
1052 case (BJACK_DOWN|BUTTON_REPEAT):
1053 if (amount - 10 > lower_limit - 1) {
1054 amount -= 10;
1055 changed = true;
1057 break;
1058 case BJACK_RIGHT:
1059 case (BJACK_RIGHT|BUTTON_REPEAT):
1060 if (amount + 1 < upper_limit + 1) {
1061 amount++;
1062 changed = true;
1064 break;
1065 case BJACK_LEFT:
1066 case (BJACK_LEFT|BUTTON_REPEAT):
1067 if (amount - 1 > lower_limit - 1) {
1068 amount--;
1069 changed = true;
1071 break;
1072 case BJACK_MAX :
1073 amount = upper_limit;
1074 changed = true;
1075 break;
1076 case BJACK_MIN :
1077 amount = lower_limit;
1078 changed = true;
1079 break;
1080 case BJACK_QUIT:
1081 return 0;
1082 case BJACK_START:
1083 #if LCD_DEPTH > 1
1084 rb->lcd_set_foreground(FG_COLOR);
1085 rb->lcd_set_background(BG_COLOR);
1086 #endif
1087 rb->lcd_clear_display();
1088 return amount;
1091 if(changed) {
1092 rb->snprintf(str, 9, "$%d", amount);
1093 #if LCD_HEIGHT <= 64
1094 rb->lcd_puts(0, 2, str);
1095 rb->lcd_update();
1096 #else
1097 rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID);
1098 rb->lcd_fillrect(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, 5*w, h);
1099 rb->lcd_set_drawmode(DRMODE_SOLID);
1100 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, str);
1101 rb->lcd_update_rect(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, 5*w, h);
1102 #endif
1103 changed = false;
1108 /*****************************************************************************
1109 * blackjack_get_bet() gets the player's bet.
1110 ******************************************************************************/
1111 static void blackjack_get_bet(struct game_context* bj) {
1112 bj->current_bet = blackjack_get_amount("Please enter a bet", 10,
1113 bj->player_money, bj->current_bet);
1116 /*****************************************************************************
1117 * double_down() returns one final card then finishes the game
1118 ******************************************************************************/
1119 static void double_down(struct game_context* bj) {
1120 bj->current_bet *= 2;
1121 bj->player_cards[0][bj->num_player_cards[0]] = new_card();
1122 bj->player_total += bj->player_cards[0][bj->num_player_cards[0]].value;
1123 bj->num_player_cards[0]++;
1126 /*****************************************************************************
1127 * split() checks if the player wants to split and acts accordingly.
1128 * When bj->split_status is 1, no split occurred. 2 means the player split and 3
1129 * means a split has already occurred and the first hand is done.
1130 ******************************************************************************/
1131 static void split(struct game_context* bj) {
1132 if (blackjack_get_yes_no("Split?") == 1)
1133 bj->split_status = 1;
1134 else {
1135 bj->split_status = 2;
1136 bj->current_bet *= 2;
1137 bj->num_player_cards[0] = 1;
1138 bj->num_player_cards[1] = 1;
1139 bj->player_cards[1][0] = bj->player_cards[0][1];
1140 bj->player_total = bj->player_cards[0][0].value;
1144 /*****************************************************************************
1145 * insurance() see if the player wants to buy insurance and how much.
1146 ******************************************************************************/
1147 static unsigned int insurance(struct game_context* bj) {
1148 unsigned int insurance, max_amount;
1150 insurance = blackjack_get_yes_no("Buy Insurance?");
1151 bj->asked_insurance = true;
1152 max_amount = bj->current_bet < (unsigned int)bj->player_money ?
1153 bj->current_bet/2 : (unsigned int)bj->player_money;
1154 if (insurance == 1) return 0;
1156 insurance = blackjack_get_amount("How much?", 0, max_amount, 0);
1157 redraw_board(bj);
1158 return insurance;
1161 /*****************************************************************************
1162 * play_again() checks to see if the player wants to keep playing.
1163 ******************************************************************************/
1164 static unsigned int play_again(void) {
1165 return blackjack_get_yes_no("Play Again?");
1168 /*****************************************************************************
1169 * blackjack_menu() is the initial menu at the start of the game.
1170 ******************************************************************************/
1171 static unsigned int blackjack_menu(struct game_context* bj) {
1172 int button;
1173 char *title = "Blackjack";
1174 char str[18];
1175 unsigned int i, w, h;
1176 bool breakout = false;
1177 bool showscores = false;
1179 while(true){
1180 #if LCD_DEPTH > 1
1181 rb->lcd_set_background(BG_COLOR);
1182 rb->lcd_set_foreground(FG_COLOR);
1183 #endif
1184 rb->lcd_clear_display();
1186 if(!showscores) {
1187 /* welcome screen to display key bindings */
1188 rb->lcd_getstringsize(title, &w, &h);
1189 rb->lcd_putsxy((LCD_WIDTH-w)/2, 0, title);
1191 #if CONFIG_KEYPAD == RECORDER_PAD
1192 rb->lcd_puts(0, 1, "ON: start");
1193 rb->lcd_puts(0, 2, "OFF: exit");
1194 rb->lcd_puts(0, 3, "F1: hit");
1195 rb->lcd_puts(0, 4, "F2: stay");
1196 rb->lcd_puts(0, 5, "F3: double down");
1197 rb->lcd_puts(0, 6, "PLAY: save/resume");
1198 rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]);
1199 rb->lcd_puts(0, 7, str);
1200 #elif CONFIG_KEYPAD == ONDIO_PAD
1201 rb->lcd_puts(0, 1, "MENU: start");
1202 rb->lcd_puts(0, 2, "OFF: exit");
1203 rb->lcd_puts(0, 3, "LEFT: hit");
1204 rb->lcd_puts(0, 4, "RIGHT: stay");
1205 rb->lcd_puts(0, 5, "UP: double down");
1206 rb->lcd_puts(0, 6, "DOWN: save/resume");
1207 rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]);
1208 rb->lcd_puts(0, 7, str);
1209 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
1210 rb->lcd_puts(0, 2, "PLAY to start & to hit");
1211 rb->lcd_puts(0, 3, "STOP to exit");
1212 rb->lcd_puts(0, 4, "REC to stay");
1213 rb->lcd_puts(0, 5, "NAVI to double down ");
1214 rb->lcd_puts(0, 6, " & to view highscores");
1215 rb->lcd_puts(0, 7, "AB to save/resume");
1216 rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]);
1217 rb->lcd_puts(0, 8, str);
1218 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
1219 rb->lcd_puts(0, 2, "PLAY to start & hit");
1220 rb->lcd_puts(0, 3, "POWER to exit");
1221 rb->lcd_puts(0, 4, ">>| to stay");
1222 rb->lcd_puts(0, 5, "|<< to double down");
1223 rb->lcd_puts(0, 6, "LEFT to view scores");
1224 rb->lcd_puts(0, 7, "RIGHT to save/resume");
1225 rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]);
1226 rb->lcd_puts(0, 8, str);
1228 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
1229 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
1230 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
1231 #if LCD_WIDTH >=176
1232 rb->lcd_puts(0, 2, "SELECT to start & to hit");
1233 rb->lcd_puts(0, 3, "MENU to exit");
1234 rb->lcd_puts(0, 4, ">>| to stay & to view highscores");
1235 rb->lcd_puts(0, 5, "|<< to double down");
1236 rb->lcd_puts(0, 6, "PLAY to save/resume");
1237 rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]);
1238 rb->lcd_puts(0, 7, str);
1239 #else
1240 rb->lcd_puts(0, 2, "SELECT to start & to ");
1241 rb->lcd_puts(0, 3, " hit");
1242 rb->lcd_puts(0, 4, "MENU to exit");
1243 rb->lcd_puts(0, 5, ">>| to stay & to view ");
1244 rb->lcd_puts(0, 6, " highscores");
1245 rb->lcd_puts(0, 7, "|<< to double down");
1246 rb->lcd_puts(0, 8, "PLAY to save/resume");
1247 rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]);
1248 rb->lcd_puts(0, 9, str);
1249 #endif
1250 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
1251 rb->lcd_puts(0, 2, "PLAY to start to hit");
1252 rb->lcd_puts(0, 3, "POWER to exit");
1253 rb->lcd_puts(0, 4, "SELECT to hit");
1254 rb->lcd_puts(0, 5, "REC to stay");
1255 rb->lcd_puts(0, 6, "PLAY to double down");
1256 rb->lcd_puts(0, 7, "RIGHT to view highscores ");
1257 rb->lcd_puts(0, 8, "DOWN to save/resume");
1258 rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]);
1259 rb->lcd_puts(0, 9, str);
1260 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
1261 rb->lcd_puts(0, 2, "AB to start & to");
1262 rb->lcd_puts(0, 3, " stay");
1263 rb->lcd_puts(0, 4, "EQ to hit");
1264 rb->lcd_puts(0, 5, "PLAY to exit");
1265 rb->lcd_puts(0, 6, "CLICK to double down");
1266 rb->lcd_puts(0, 7, "& to view highscores");
1267 rb->lcd_puts(0, 8, "AB+EQ to save/resume");
1268 rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]);
1269 rb->lcd_puts(0, 9, str);
1270 #elif CONFIG_KEYPAD == GIGABEAT_PAD
1271 rb->lcd_puts(0, 2, "A to start");
1272 rb->lcd_puts(0, 3, "POWER to exit");
1273 rb->lcd_puts(0, 4, "VOL+ to hit");
1274 rb->lcd_puts(0, 5, "VOL- to stay");
1275 rb->lcd_puts(0, 6, "SELECT to double down");
1276 rb->lcd_puts(0, 7, "RIGHT to view highscores ");
1277 rb->lcd_puts(0, 8, "MENU to save/resume");
1278 rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]);
1279 rb->lcd_puts(0, 9, str);
1280 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
1281 rb->lcd_puts(0, 2, "PLAY to start");
1282 rb->lcd_puts(0, 3, "BACK to exit");
1283 rb->lcd_puts(0, 4, "VOL+ to hit");
1284 rb->lcd_puts(0, 5, "VOL- to stay");
1285 rb->lcd_puts(0, 6, "SELECT to double down");
1286 rb->lcd_puts(0, 7, "RIGHT to view highscores ");
1287 rb->lcd_puts(0, 8, "MENU to save/resume");
1288 rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]);
1289 rb->lcd_puts(0, 9, str);
1290 #elif CONFIG_KEYPAD == MROBE100_PAD
1291 rb->lcd_puts(0, 2, "SELECT to start");
1292 rb->lcd_puts(0, 3, "POWER to exit");
1293 rb->lcd_puts(0, 4, "MENU to hit");
1294 rb->lcd_puts(0, 5, "DISPLAY to stay");
1295 rb->lcd_puts(0, 6, "DOWN to double down");
1296 rb->lcd_puts(0, 7, "RIGHT to view highscores ");
1297 rb->lcd_puts(0, 8, "PLAY to save/resume");
1298 rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]);
1299 rb->lcd_puts(0, 9, str);
1300 #elif (CONFIG_KEYPAD == SANSA_E200_PAD)
1301 rb->lcd_puts(0, 2, "SELECT to start & to hit");
1302 rb->lcd_puts(0, 3, "POWER to exit");
1303 rb->lcd_puts(0, 4, "RIGHT to stay");
1304 rb->lcd_puts(0, 5, "LEFT to double down");
1305 rb->lcd_puts(0, 6, "REC to save/resume");
1306 rb->lcd_puts(0, 7, "UP to view scores");
1307 rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]);
1308 rb->lcd_puts(0, 8, str);
1309 #elif (CONFIG_KEYPAD == SANSA_C200_PAD)
1310 rb->lcd_puts(0, 2, "SELECT to start & to hit");
1311 rb->lcd_puts(0, 3, "POWER to exit");
1312 rb->lcd_puts(0, 4, "RIGHT to stay");
1313 rb->lcd_puts(0, 5, "LEFT to double down");
1314 rb->lcd_puts(0, 6, "DOWN to save/resume");
1315 rb->lcd_puts(0, 7, "REC to view scores");
1316 rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]);
1317 rb->lcd_puts(0, 9, str);
1318 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
1319 rb->lcd_puts(0, 2, "PLAY to start & to");
1320 rb->lcd_puts(0, 3, " hit");
1321 rb->lcd_puts(0, 4, "REC to exit");
1322 rb->lcd_puts(0, 5, "FF to stay");
1323 rb->lcd_puts(0, 6, "REW to double down");
1324 rb->lcd_puts(0, 7, "MODE to save/resume");
1325 rb->lcd_puts(0, 8, "MENU to view scores");
1326 rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]);
1327 rb->lcd_puts(0, 10, str);
1328 #elif CONFIG_KEYPAD == COWOND2_PAD
1329 rb->lcd_puts(0, 6, "POWER to exit");
1330 rb->lcd_puts(0, 7, "MINUS to double down");
1331 rb->lcd_puts(0, 8, "MENU to view scores");
1332 rb->snprintf(str, 21, "High Score: $%d", bj->highscores[0]);
1333 rb->lcd_puts(0, 10, str);
1334 #endif
1336 #ifdef HAVE_TOUCHSCREEN
1337 rb->lcd_puts(0, 2, "LCD CENTRE to start & to hit");
1338 rb->lcd_puts(0, 3, "LCD BOTTOMLEFT to stay");
1339 rb->lcd_puts(0, 4, "LCD BOTTOMRIGHT to save/resume");
1340 #endif
1341 } else {
1342 rb->snprintf(str, 12, "%s", "High Scores");
1343 rb->lcd_getstringsize(str, &w, &h);
1344 rb->lcd_putsxy((LCD_WIDTH-w)/2, 0, str);
1346 /* print high scores */
1347 for(i=0; i<NUM_SCORES; i++) {
1348 rb->snprintf(str, 14, "#%02d: $%d", i+1, bj->highscores[i]);
1349 rb->lcd_puts(0, i+1, str);
1353 rb->lcd_update();
1355 /* handle menu button presses */
1356 button = rb->button_get(true);
1358 switch(button) {
1359 case BJACK_START: /* start playing */
1360 breakout = true;
1361 break;
1363 case BJACK_QUIT: /* quit program */
1364 if(showscores) {
1365 showscores = 0;
1366 break;
1368 return BJ_QUIT;
1370 case BJACK_RESUME:/* resume game */
1371 if(!blackjack_loadgame(bj)) {
1372 rb->splash(HZ*2, "Nothing to resume");
1373 } else {
1374 rb->splash(HZ*2, "Loading...");
1375 breakout = true;
1377 break;
1379 case BJACK_SCORES:/* toggle high scores */
1380 showscores = !showscores;
1381 break;
1383 default:
1384 if(rb->default_event_handler_ex(button, blackjack_callback,
1385 (void*) bj) == SYS_USB_CONNECTED)
1386 return BJ_USB;
1387 break;
1390 if(breakout) break;
1393 return(0);
1396 /*****************************************************************************
1397 * blackjack() is the main game subroutine, it returns the final game status.
1398 ******************************************************************************/
1399 static int blackjack(struct game_context* bj) {
1400 int button;
1401 unsigned int w, h, temp_var, done = 0, todo = 1;
1402 signed int temp;
1403 bool breakout = false;
1404 bool dbl_down = false;
1406 /* don't resume by default */
1407 bj->resume = false;
1409 /********************
1410 * menu *
1411 ********************/
1412 temp_var = blackjack_menu(bj);
1413 if (temp_var == BJ_QUIT || temp_var == BJ_USB)
1414 return temp_var;
1417 /********************
1418 * init *
1419 ********************/
1420 blackjack_init(bj);
1421 bj->current_bet=10;
1423 /********************
1424 * play *
1425 ********************/
1427 /* check for resumed game */
1428 if(bj->resume) {
1429 bj->resume = false;
1430 redraw_board(bj);
1431 if (bj->split_status == 2) {
1432 todo=2;
1433 player_x = bj->num_player_cards[0] * 10 + 4;
1435 else if (bj->split_status == 3) {
1436 player_x = bj->num_player_cards[1] * 10 + LCD_WIDTH/2 + 4;
1437 todo=2;
1438 done=1;
1442 else {
1443 bj->player_money = 1000;
1444 blackjack_get_bet(bj);
1445 if (bj->current_bet == 0)
1446 return BJ_QUIT;
1447 rb->lcd_clear_display();
1448 deal_init_cards(bj);
1449 blackjack_drawtable(bj);
1452 rb->lcd_update();
1454 breakout = false;
1456 while(true){
1457 if(bj->player_total == 21 && bj->num_player_cards[0] == 2) {
1458 bj->is_blackjack = true;
1459 bj->end_hand = true;
1460 finish_game(bj);
1462 else if(bj->dealer_cards[1].is_soft_ace && !breakout &&
1463 !bj->asked_insurance) {
1464 temp_var = insurance(bj);
1465 if (bj->dealer_total == 21) {
1466 rb->splash(HZ, "Dealer has blackjack");
1467 bj->player_money += temp_var;
1468 bj->end_hand = true;
1469 breakout = true;
1470 redraw_board(bj);
1471 finish_game(bj);
1473 else {
1474 rb->splash(HZ, "Dealer does not have blackjack");
1475 bj->player_money -= temp_var;
1476 breakout = true;
1477 redraw_board(bj);
1478 rb->lcd_update();
1481 if(!bj->end_hand && bj->split_status == 0 &&
1482 bj->player_cards[0][0].num == bj->player_cards[0][1].num) {
1483 split(bj);
1484 redraw_board(bj);
1485 rb->lcd_update_rect(0, LCD_HEIGHT/2, LCD_WIDTH, LCD_HEIGHT/2);
1486 if (bj->split_status == 2) {
1487 todo++;
1488 player_x = bj->num_player_cards[0] * 10 + 4;
1492 while(!bj->end_hand && done < todo) {
1493 button = rb->button_get(true);
1495 switch(button) {
1496 case BJACK_HIT:
1497 NEXT_CARD = new_card();
1498 bj->player_total += NEXT_CARD.value;
1499 draw_card(NEXT_CARD, true, player_x, player_y);
1500 bj->num_player_cards[done]++;
1501 if (bj->num_player_cards[done] == MAX_CARDS + 1) {
1502 redraw_board(bj);
1503 rb->lcd_update_rect(0, LCD_HEIGHT/2, LCD_WIDTH,
1504 LCD_HEIGHT/2);
1506 else if (bj->num_player_cards[done]>MAX_CARDS || todo > 1) {
1507 rb->lcd_update_rect(player_x, player_y, CARD_WIDTH+2,
1508 CARD_HEIGHT+2);
1509 player_x += 10;
1511 else {
1512 rb->lcd_update_rect(player_x, player_y, CARD_WIDTH+2,
1513 CARD_HEIGHT+2);
1514 player_x += CARD_WIDTH + 4;
1516 update_total(bj);
1518 break;
1519 case BJACK_STAY:
1520 bj->end_hand = true;
1521 break;
1522 case BJACK_DOUBLEDOWN:
1523 if ((signed int)bj->current_bet * 2 < bj->player_money + 1 &&
1524 bj->num_player_cards[0]==2 && todo==1) {
1525 double_down(bj);
1526 dbl_down = true;
1527 if (bj->player_total < 22) {
1528 bj->end_hand = true;
1529 finish_game(bj);
1532 else if((signed int)bj->current_bet * 2 > bj->player_money) {
1533 rb->splash(HZ, "Not enough money to double down.");
1534 redraw_board(bj);
1535 rb->lcd_update();
1537 break;
1538 case BJACK_RESUME: /* save and end game */
1539 rb->splash(HZ, "Saving game...");
1540 blackjack_savegame(bj);
1541 /* fall through to BJACK_QUIT */
1543 case BJACK_QUIT:
1544 return BJ_END;
1547 while (bj->player_total > 21 && !bj->end_hand) {
1548 temp = check_for_aces(bj->player_cards[done],
1549 bj->num_player_cards[done]);
1550 if(temp != -1) {
1551 bj->player_cards[done][temp].is_soft_ace = false;
1552 bj->player_total -= 10;
1553 update_total(bj);
1554 if (dbl_down) {
1555 bj->end_hand = true;
1556 finish_game(bj);
1559 else
1560 bj->end_hand = true;
1563 if (bj->end_hand) {
1564 done++;
1565 if(todo > 1) {
1566 if (done == 2) {
1567 temp = bj->player_total;
1568 bj->player_total = temp_var;
1569 temp_var = temp;
1570 finish_game(bj);
1571 rb->lcd_getstringsize(" Split 1 ", &w, &h);
1572 rb->lcd_putsxy(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2,
1573 " Split 1 ");
1574 rb->lcd_update_rect(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2,
1575 w,h);
1576 bj->current_bet /= 2;
1577 rb->lcd_update_rect(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2,
1578 w,h);
1579 rb->sleep(HZ*2);
1580 bj->player_total = temp_var;
1581 finish_game(bj);
1582 rb->lcd_getstringsize(" Split 2 ", &w, &h);
1583 rb->lcd_putsxy(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2,
1584 " Split 2 ");
1585 rb->lcd_update_rect(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2,
1586 w,h);
1587 rb->sleep(HZ*2);
1589 else {
1590 bj->end_hand = false;
1591 bj->split_status = 3;
1592 temp_var = bj->player_total;
1593 bj->player_total = bj->player_cards[1][0].value;
1594 update_total(bj);
1595 redraw_board(bj);
1596 player_x += 10;
1597 rb->lcd_update();
1600 else
1601 finish_game(bj);
1605 if (bj->player_money < 10) {
1606 rb->sleep(HZ);
1607 return BJ_LOSE;
1610 if (bj->end_hand) { /* If hand is over */
1611 if (play_again() != 0) /* User wants to quit */
1612 return BJ_END;
1613 else { /* User keeps playing */
1614 breakout = false;
1615 redraw_board(bj);
1616 if(dbl_down) {
1617 bj->current_bet /= 2;
1618 dbl_down = false;
1620 done = 0;
1621 todo = 1;
1622 blackjack_init(bj);
1623 blackjack_get_bet(bj);
1624 if (bj->current_bet == 0)
1625 return BJ_END;
1626 deal_init_cards(bj);
1627 blackjack_drawtable(bj);
1628 rb->lcd_update();
1632 /* Never reached */
1633 return PLUGIN_OK;
1636 /*****************************************************************************
1637 * plugin entry point.
1638 ******************************************************************************/
1639 enum plugin_status plugin_start(const void* parameter)
1641 struct game_context bj;
1642 bool exit = false;
1643 unsigned int position;
1644 char str[19];
1646 (void)parameter;
1648 #if LCD_DEPTH > 1
1649 rb->lcd_set_backdrop(NULL);
1650 #endif
1652 /* load high scores */
1653 blackjack_loadscores(&bj);
1655 rb->lcd_setfont(FONT_SYSFIXED);
1657 while(!exit) {
1658 switch(blackjack(&bj)){
1659 case BJ_LOSE:
1660 rb->splash(HZ, "Not enough money to continue");
1661 /* fall through to BJ_END */
1663 case BJ_END:
1664 if(!bj.resume) {
1665 if((position = blackjack_recordscore(&bj))) {
1666 rb->snprintf(str, 19, "New high score #%d!", position);
1667 rb->splash(HZ*2, str);
1670 break;
1672 case BJ_USB:
1673 rb->lcd_setfont(FONT_UI);
1674 return PLUGIN_USB_CONNECTED;
1676 case BJ_QUIT:
1677 if(bj.dirty) {
1678 rb->splash(HZ, "Saving high scores...");
1679 blackjack_savescores(&bj);
1681 exit = true;
1682 break;
1684 default:
1685 break;
1689 rb->lcd_setfont(FONT_UI);
1690 return PLUGIN_OK;