1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
23 #include "pluginbitmaps/card_deck.h"
24 #include "pluginbitmaps/card_back.h"
25 #include "lib/display_text.h"
26 #include "lib/highscore.h"
27 #include "lib/playback_control.h"
32 #define SCORE_FILE PLUGIN_GAMES_DATA_DIR "/blackjack.score"
33 #define SAVE_FILE PLUGIN_GAMES_DATA_DIR "/blackjack.save"
36 /* final game return status */
39 BJ_QUIT_WITHOUT_SAVING
,
45 #if CONFIG_KEYPAD == RECORDER_PAD
46 #define BJACK_SELECT_NAME "PLAY"
47 #define BJACK_STAY_NAME "F1"
48 #define BJACK_QUIT_NAME "OFF"
49 #define BJACK_DOUBLE_NAME "F2"
50 #define BJACK_SELECT BUTTON_PLAY
51 #define BJACK_QUIT BUTTON_OFF
52 #define BJACK_MAX (BUTTON_ON|BUTTON_UP)
53 #define BJACK_MIN (BUTTON_ON|BUTTON_DOWN)
54 #define BJACK_STAY BUTTON_F1
55 #define BJACK_DOUBLEDOWN BUTTON_F2
56 #define BJACK_UP BUTTON_UP
57 #define BJACK_DOWN BUTTON_DOWN
58 #define BJACK_RIGHT BUTTON_RIGHT
59 #define BJACK_LEFT BUTTON_LEFT
61 #elif CONFIG_KEYPAD == ONDIO_PAD
62 #define BJACK_SELECT_NAME "MENU"
63 #define BJACK_STAY_NAME "RIGHT"
64 #define BJACK_QUIT_NAME "OFF"
65 #define BJACK_DOUBLE_NAME "UP"
66 #define BJACK_SELECT BUTTON_MENU
67 #define BJACK_QUIT BUTTON_OFF
68 #define BJACK_STAY BUTTON_RIGHT
69 #define BJACK_DOUBLEDOWN BUTTON_UP
70 #define BJACK_UP BUTTON_UP
71 #define BJACK_DOWN BUTTON_DOWN
72 #define BJACK_RIGHT BUTTON_RIGHT
73 #define BJACK_LEFT BUTTON_LEFT
75 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
76 #define BJACK_SELECT_NAME "PLAY"
77 #define BJACK_STAY_NAME ">>|"
78 #define BJACK_QUIT_NAME "POWER"
79 #define BJACK_DOUBLE_NAME "|<<"
80 #define BJACK_SELECT BUTTON_PLAY
81 #define BJACK_QUIT BUTTON_POWER
82 #define BJACK_STAY BUTTON_FF
83 #define BJACK_DOUBLEDOWN BUTTON_REW
84 #define BJACK_UP BUTTON_SCROLL_UP
85 #define BJACK_DOWN BUTTON_SCROLL_DOWN
86 #define BJACK_RIGHT BUTTON_RIGHT
87 #define BJACK_LEFT BUTTON_LEFT
89 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
90 (CONFIG_KEYPAD == IRIVER_H300_PAD)
91 #define BJACK_SELECT_NAME "ON"
92 #define BJACK_STAY_NAME "REC"
93 #define BJACK_QUIT_NAME "OFF"
94 #define BJACK_DOUBLE_NAME "SELECT"
95 #define BJACK_SELECT BUTTON_ON
96 #define BJACK_QUIT BUTTON_OFF
97 #define BJACK_STAY BUTTON_REC
98 #define BJACK_DOUBLEDOWN BUTTON_SELECT
99 #define BJACK_UP BUTTON_UP
100 #define BJACK_DOWN BUTTON_DOWN
101 #define BJACK_RIGHT BUTTON_RIGHT
102 #define BJACK_LEFT BUTTON_LEFT
104 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
105 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
106 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
107 #define BJACK_SELECT_NAME "SELECT"
108 #define BJACK_STAY_NAME "RIGHT"
109 #define BJACK_RESUME_NAME "PLAY"
110 #define BJACK_QUIT_NAME "MENU"
111 #define BJACK_DOUBLE_NAME "LEFT"
112 #define BJACK_SELECT BUTTON_SELECT
113 #define BJACK_QUIT BUTTON_MENU
114 #define BJACK_STAY BUTTON_RIGHT
115 #define BJACK_DOUBLEDOWN BUTTON_LEFT
116 #define BJACK_UP BUTTON_SCROLL_FWD
117 #define BJACK_DOWN BUTTON_SCROLL_BACK
118 #define BJACK_RIGHT BUTTON_RIGHT
119 #define BJACK_LEFT BUTTON_LEFT
121 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
122 #define BJACK_SELECT_NAME "SELECT"
123 #define BJACK_STAY_NAME "REC"
124 #define BJACK_QUIT_NAME "POWER"
125 #define BJACK_DOUBLE_NAME "PLAY"
126 #define BJACK_SELECT BUTTON_SELECT
127 #define BJACK_QUIT BUTTON_POWER
128 #define BJACK_MAX (BUTTON_PLAY|BUTTON_UP)
129 #define BJACK_MIN (BUTTON_PLAY|BUTTON_DOWN)
130 #define BJACK_STAY BUTTON_REC
131 #define BJACK_DOUBLEDOWN BUTTON_PLAY
132 #define BJACK_UP BUTTON_UP
133 #define BJACK_DOWN BUTTON_DOWN
134 #define BJACK_RIGHT BUTTON_RIGHT
135 #define BJACK_LEFT BUTTON_LEFT
137 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
138 #define BJACK_SELECT_NAME "MODE"
139 #define BJACK_STAY_NAME "MODE"
140 #define BJACK_QUIT_NAME "PLAY"
141 #define BJACK_DOUBLE_NAME "SELECT"
142 #define BJACK_SELECT BUTTON_MODE
143 #define BJACK_QUIT BUTTON_PLAY
144 #define BJACK_MAX (BUTTON_EQ|BUTTON_UP)
145 #define BJACK_MIN (BUTTON_EQ|BUTTON_DOWN)
146 #define BJACK_STAY BUTTON_MODE
147 #define BJACK_DOUBLEDOWN BUTTON_SELECT
148 #define BJACK_UP BUTTON_UP
149 #define BJACK_DOWN BUTTON_DOWN
150 #define BJACK_RIGHT BUTTON_RIGHT
151 #define BJACK_LEFT BUTTON_LEFT
153 #elif CONFIG_KEYPAD == GIGABEAT_PAD
154 #define BJACK_SELECT_NAME "SELECT"
155 #define BJACK_STAY_NAME "VOL-"
156 #define BJACK_QUIT_NAME "POWER"
157 #define BJACK_DOUBLE_NAME "A"
158 #define BJACK_SELECT BUTTON_SELECT
159 #define BJACK_QUIT BUTTON_POWER
160 #define BJACK_MAX BUTTON_VOL_UP
161 #define BJACK_MIN BUTTON_VOL_DOWN
162 #define BJACK_STAY BUTTON_VOL_DOWN
163 #define BJACK_DOUBLEDOWN BUTTON_A
164 #define BJACK_UP BUTTON_UP
165 #define BJACK_DOWN BUTTON_DOWN
166 #define BJACK_RIGHT BUTTON_RIGHT
167 #define BJACK_LEFT BUTTON_LEFT
169 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
170 (CONFIG_KEYPAD == SANSA_CONNECT_PAD)
171 #define BJACK_SELECT_NAME "SELECT"
172 #define BJACK_STAY_NAME "RIGHT"
173 #define BJACK_QUIT_NAME "POWER"
174 #define BJACK_DOUBLE_NAME "LEFT"
175 #define BJACK_SELECT BUTTON_SELECT
176 #define BJACK_QUIT BUTTON_POWER
177 #define BJACK_MAX BUTTON_UP
178 #define BJACK_MIN BUTTON_DOWN
179 #define BJACK_STAY BUTTON_RIGHT
180 #define BJACK_DOUBLEDOWN BUTTON_LEFT
181 #define BJACK_UP BUTTON_SCROLL_FWD
182 #define BJACK_DOWN BUTTON_SCROLL_BACK
183 #define BJACK_RIGHT BUTTON_RIGHT
184 #define BJACK_LEFT BUTTON_LEFT
186 #elif CONFIG_KEYPAD == SANSA_FUZE_PAD
187 #define BJACK_SELECT_NAME "SELECT"
188 #define BJACK_STAY_NAME "RIGHT"
189 #define BJACK_QUIT_NAME "HOME"
190 #define BJACK_DOUBLE_NAME "LEFT"
191 #define BJACK_SELECT BUTTON_SELECT
192 #define BJACK_QUIT (BUTTON_HOME|BUTTON_REPEAT)
193 #define BJACK_MAX BUTTON_UP
194 #define BJACK_MIN BUTTON_DOWN
195 #define BJACK_STAY BUTTON_RIGHT
196 #define BJACK_DOUBLEDOWN BUTTON_LEFT
197 #define BJACK_UP BUTTON_SCROLL_FWD
198 #define BJACK_DOWN BUTTON_SCROLL_BACK
199 #define BJACK_RIGHT BUTTON_RIGHT
200 #define BJACK_LEFT BUTTON_LEFT
202 #elif CONFIG_KEYPAD == SANSA_C200_PAD
203 #define BJACK_SELECT_NAME "SELECT"
204 #define BJACK_STAY_NAME "RIGHT"
205 #define BJACK_QUIT_NAME "POWER"
206 #define BJACK_DOUBLE_NAME "LEFT"
207 #define BJACK_SELECT BUTTON_SELECT
208 #define BJACK_QUIT BUTTON_POWER
209 #define BJACK_MAX BUTTON_VOL_UP
210 #define BJACK_MIN BUTTON_VOL_DOWN
211 #define BJACK_STAY BUTTON_RIGHT
212 #define BJACK_DOUBLEDOWN BUTTON_LEFT
213 #define BJACK_UP BUTTON_UP
214 #define BJACK_DOWN BUTTON_DOWN
215 #define BJACK_RIGHT BUTTON_RIGHT
216 #define BJACK_LEFT BUTTON_LEFT
218 #elif CONFIG_KEYPAD == SANSA_CLIP_PAD
219 #define BJACK_SELECT_NAME "SELECT"
220 #define BJACK_STAY_NAME "RIGHT"
221 #define BJACK_QUIT_NAME "POWER"
222 #define BJACK_DOUBLE_NAME "LEFT"
223 #define BJACK_SELECT BUTTON_SELECT
224 #define BJACK_QUIT BUTTON_POWER
225 #define BJACK_MAX BUTTON_VOL_UP
226 #define BJACK_MIN BUTTON_VOL_DOWN
227 #define BJACK_STAY BUTTON_RIGHT
228 #define BJACK_DOUBLEDOWN BUTTON_LEFT
229 #define BJACK_UP BUTTON_UP
230 #define BJACK_DOWN BUTTON_DOWN
231 #define BJACK_RIGHT BUTTON_RIGHT
232 #define BJACK_LEFT BUTTON_LEFT
234 #elif CONFIG_KEYPAD == SANSA_M200_PAD
235 #define BJACK_SELECT_NAME "SELECT"
236 #define BJACK_STAY_NAME "RIGHT"
237 #define BJACK_QUIT_NAME "POWER"
238 #define BJACK_DOUBLE_NAME "LEFT"
239 #define BJACK_SELECT (BUTTON_SELECT | BUTTON_REL)
240 #define BJACK_QUIT BUTTON_POWER
241 #define BJACK_MAX BUTTON_VOL_UP
242 #define BJACK_MIN BUTTON_VOL_DOWN
243 #define BJACK_STAY BUTTON_RIGHT
244 #define BJACK_DOUBLEDOWN BUTTON_LEFT
245 #define BJACK_UP BUTTON_UP
246 #define BJACK_DOWN BUTTON_DOWN
247 #define BJACK_RIGHT BUTTON_RIGHT
248 #define BJACK_LEFT BUTTON_LEFT
250 #elif CONFIG_KEYPAD == TATUNG_TPJ1022_PAD
251 #define BJACK_SELECT_NAME "MAIN"
252 #define BJACK_STAY_NAME "MENU"
253 #define BJACK_QUIT_NAME "POWER"
254 #define BJACK_DOUBLE_NAME "DOWN"
255 #define BJACK_SELECT BUTTON_MAIN
256 #define BJACK_QUIT BUTTON_POWER
257 #define BJACK_MAX (BUTTON_REC|BUTTON_UP)
258 #define BJACK_MIN (BUTTON_REC|BUTTON_DOWN)
259 #define BJACK_STAY BUTTON_MENU
260 #define BJACK_DOUBLEDOWN BUTTON_DOWN
261 #define BJACK_UP BUTTON_UP
262 #define BJACK_DOWN BUTTON_DOWN
263 #define BJACK_RIGHT BUTTON_RIGHT
264 #define BJACK_LEFT BUTTON_LEFT
266 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
267 #define BJACK_SELECT_NAME "PLAY"
268 #define BJACK_STAY_NAME "VOL-"
269 #define BJACK_QUIT_NAME "BACK"
270 #define BJACK_DOUBLE_NAME "SELECT"
271 #define BJACK_SELECT BUTTON_PLAY
272 #define BJACK_QUIT BUTTON_BACK
273 #define BJACK_MAX BUTTON_VOL_UP
274 #define BJACK_MIN BUTTON_VOL_DOWN
275 #define BJACK_STAY BUTTON_VOL_DOWN
276 #define BJACK_DOUBLEDOWN BUTTON_SELECT
277 #define BJACK_UP BUTTON_UP
278 #define BJACK_DOWN BUTTON_DOWN
279 #define BJACK_RIGHT BUTTON_RIGHT
280 #define BJACK_LEFT BUTTON_LEFT
282 #elif CONFIG_KEYPAD == MROBE100_PAD
283 #define BJACK_SELECT_NAME "SELECT"
284 #define BJACK_STAY_NAME "DISPLAY"
285 #define BJACK_QUIT_NAME "POWER"
286 #define BJACK_DOUBLE_NAME "DOWN"
287 #define BJACK_SELECT BUTTON_SELECT
288 #define BJACK_QUIT BUTTON_POWER
289 #define BJACK_MAX BUTTON_MENU
290 #define BJACK_MIN BUTTON_DISPLAY
291 #define BJACK_STAY BUTTON_DISPLAY
292 #define BJACK_DOUBLEDOWN BUTTON_DOWN
293 #define BJACK_UP BUTTON_UP
294 #define BJACK_DOWN BUTTON_DOWN
295 #define BJACK_RIGHT BUTTON_RIGHT
296 #define BJACK_LEFT BUTTON_LEFT
298 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
299 #define BJACK_SELECT_NAME "RC","PLAY"
300 #define BJACK_STAY_NAME "RC", ">>|"
301 #define BJACK_QUIT_NAME "RC_REC"
302 #define BJACK_DOUBLE_NAME "RC_REW"
303 #define BJACK_SELECT BUTTON_RC_PLAY
304 #define BJACK_QUIT BUTTON_RC_REC
305 #define BJACK_STAY BUTTON_RC_FF
306 #define BJACK_DOUBLEDOWN BUTTON_RC_REW
307 #define BJACK_UP BUTTON_RC_VOL_UP
308 #define BJACK_DOWN BUTTON_RC_VOL_DOWN
309 #define BJACK_RIGHT BUTTON_RC_FF
310 #define BJACK_LEFT BUTTON_RC_REW
312 #elif CONFIG_KEYPAD == COWON_D2_PAD
313 #define BJACK_QUIT_NAME "POWER"
314 #define BJACK_DOUBLE_NAME "-"
315 #define BJACK_QUIT BUTTON_POWER
316 #define BJACK_DOUBLEDOWN BUTTON_MINUS
318 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
319 #define BJACK_SELECT_NAME "SELECT"
320 #define BJACK_STAY_NAME "PLAY"
321 #define BJACK_QUIT_NAME "POWER"
322 #define BJACK_DOUBLE_NAME "CUSTOM"
323 #define BJACK_SELECT BUTTON_SELECT
324 #define BJACK_QUIT BUTTON_POWER
325 #define BJACK_STAY BUTTON_PLAY
326 #define BJACK_MAX (BUTTON_CUSTOM|BUTTON_UP)
327 #define BJACK_MIN (BUTTON_CUSTOM|BUTTON_DOWN)
328 #define BJACK_DOUBLEDOWN BUTTON_CUSTOM
329 #define BJACK_UP BUTTON_UP
330 #define BJACK_DOWN BUTTON_DOWN
331 #define BJACK_RIGHT BUTTON_RIGHT
332 #define BJACK_LEFT BUTTON_LEFT
334 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
335 #define BJACK_SELECT_NAME "SELECT"
336 #define BJACK_STAY_NAME "VOL-"
337 #define BJACK_QUIT_NAME "POWER"
338 #define BJACK_DOUBLE_NAME "MENU"
339 #define BJACK_SELECT BUTTON_SELECT
340 #define BJACK_QUIT BUTTON_POWER
341 #define BJACK_MAX BUTTON_VOL_UP
342 #define BJACK_MIN BUTTON_VOL_DOWN
343 #define BJACK_STAY BUTTON_VOL_DOWN
344 #define BJACK_DOUBLEDOWN BUTTON_MENU
345 #define BJACK_UP BUTTON_UP
346 #define BJACK_DOWN BUTTON_DOWN
347 #define BJACK_RIGHT BUTTON_RIGHT
348 #define BJACK_LEFT BUTTON_LEFT
350 #elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD
351 #define BJACK_SELECT_NAME "PLAY"
352 #define BJACK_STAY_NAME "VOL-"
353 #define BJACK_QUIT_NAME "POWER"
354 #define BJACK_DOUBLE_NAME "MENU"
355 #define BJACK_SELECT BUTTON_PLAY
356 #define BJACK_QUIT BUTTON_POWER
357 #define BJACK_MAX BUTTON_VOL_UP
358 #define BJACK_MIN BUTTON_VOL_DOWN
359 #define BJACK_STAY BUTTON_VOL_DOWN
360 #define BJACK_DOUBLEDOWN BUTTON_MENU
361 #define BJACK_UP BUTTON_UP
362 #define BJACK_DOWN BUTTON_DOWN
363 #define BJACK_RIGHT BUTTON_RIGHT
364 #define BJACK_LEFT BUTTON_LEFT
366 #elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
367 #define BJACK_SELECT_NAME "MENU"
368 #define BJACK_STAY_NAME "VOL-"
369 #define BJACK_QUIT_NAME "POWER"
370 #define BJACK_DOUBLE_NAME "PLAY"
371 #define BJACK_SELECT BUTTON_MENU
372 #define BJACK_QUIT BUTTON_POWER
373 #define BJACK_MAX BUTTON_VOL_UP
374 #define BJACK_MIN BUTTON_VOL_DOWN
375 #define BJACK_STAY BUTTON_VOL_DOWN
376 #define BJACK_DOUBLEDOWN BUTTON_PLAY
377 #define BJACK_UP BUTTON_UP
378 #define BJACK_DOWN BUTTON_DOWN
379 #define BJACK_RIGHT BUTTON_NEXT
380 #define BJACK_LEFT BUTTON_PREV
382 #elif CONFIG_KEYPAD == ONDAVX747_PAD
383 #define BJACK_QUIT_NAME "POWER"
384 #define BJACK_DOUBLE_NAME "Vol-"
385 #define BJACK_QUIT BUTTON_POWER
386 #define BJACK_DOUBLEDOWN BUTTON_VOL_DOWN
388 #elif CONFIG_KEYPAD == ONDAVX777_PAD
389 #define BJACK_QUIT_NAME "POWER"
390 #define BJACK_QUIT BUTTON_POWER
392 #elif CONFIG_KEYPAD == MROBE500_PAD
393 #define BJACK_QUIT_NAME "POWER"
394 #define BJACK_QUIT BUTTON_POWER
396 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
397 #define BJACK_SELECT_NAME "PLAY"
398 #define BJACK_STAY_NAME "RECORD"
399 #define BJACK_QUIT_NAME "REW"
400 #define BJACK_DOUBLE_NAME "FFWD"
401 #define BJACK_SELECT BUTTON_PLAY
402 #define BJACK_QUIT BUTTON_REW
403 #define BJACK_STAY BUTTON_REC
404 #define BJACK_DOUBLEDOWN BUTTON_FFWD
405 #define BJACK_UP BUTTON_UP
406 #define BJACK_DOWN BUTTON_DOWN
407 #define BJACK_RIGHT BUTTON_RIGHT
408 #define BJACK_LEFT BUTTON_LEFT
410 #elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
411 #define BJACK_SELECT_NAME "OK"
412 #define BJACK_STAY_NAME "CANCEL"
413 #define BJACK_QUIT_NAME "REC"
414 #define BJACK_DOUBLE_NAME "MENU"
415 #define BJACK_SELECT BUTTON_OK
416 #define BJACK_QUIT BUTTON_REC
417 #define BJACK_STAY BUTTON_CANCEL
418 #define BJACK_DOUBLEDOWN BUTTON_MENU
419 #define BJACK_UP BUTTON_UP
420 #define BJACK_DOWN BUTTON_DOWN
421 #define BJACK_RIGHT BUTTON_NEXT
422 #define BJACK_LEFT BUTTON_PREV
424 #elif CONFIG_KEYPAD == MPIO_HD200_PAD
425 #define BJACK_SELECT_NAME "FUNC"
426 #define BJACK_STAY_NAME "VOL +"
427 #define BJACK_RESUME_NAME "PLAY"
428 #define BJACK_QUIT_NAME "REC+PLAY"
429 #define BJACK_DOUBLE_NAME "VOL -"
430 #define BJACK_SELECT BUTTON_FUNC
431 #define BJACK_QUIT (BUTTON_REC|BUTTON_PLAY)
432 #define BJACK_STAY BUTTON_VOL_UP
433 #define BJACK_DOUBLEDOWN BUTTON_VOL_DOWN
434 #define BJACK_UP BUTTON_REW
435 #define BJACK_DOWN BUTTON_FF
436 #define BJACK_RIGHT BUTTON_VOL_UP
437 #define BJACK_LEFT BUTTON_VOL_DOWN
439 #elif CONFIG_KEYPAD == MPIO_HD300_PAD
440 #define BJACK_SELECT_NAME "ENTER"
441 #define BJACK_STAY_NAME "PLAY"
442 #define BJACK_RESUME_NAME ""
443 #define BJACK_QUIT_NAME "Long MENU"
444 #define BJACK_DOUBLE_NAME "REC"
445 #define BJACK_SELECT BUTTON_ENTER
446 #define BJACK_QUIT (BUTTON_MENU|BUTTON_REPEAT)
447 #define BJACK_STAY BUTTON_PLAY
448 #define BJACK_DOUBLEDOWN BUTTON_REC
449 #define BJACK_UP BUTTON_UP
450 #define BJACK_DOWN BUTTON_DOWN
451 #define BJACK_RIGHT BUTTON_FF
452 #define BJACK_LEFT BUTTON_REW
454 #elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
455 #define BJACK_SELECT_NAME "SELECT"
456 #define BJACK_STAY_NAME "PLAYPAUSE"
457 #define BJACK_RESUME_NAME ""
458 #define BJACK_QUIT_NAME "POWER"
459 #define BJACK_DOUBLE_NAME "BACK"
460 #define BJACK_SELECT BUTTON_SELECT
461 #define BJACK_QUIT BUTTON_POWER
462 #define BJACK_MAX BUTTON_BOTTOMRIGHT
463 #define BJACK_MIN BUTTON_BOTTOMLEFT
464 #define BJACK_STAY BUTTON_BACK
465 #define BJACK_DOUBLEDOWN BUTTON_PLAYPAUSE
466 #define BJACK_UP BUTTON_UP
467 #define BJACK_DOWN BUTTON_DOWN
468 #define BJACK_RIGHT BUTTON_RIGHT
469 #define BJACK_LEFT BUTTON_LEFT
471 #elif CONFIG_KEYPAD == SAMSUNG_YPR0_PAD
472 #define BJACK_SELECT_NAME "SELECT"
473 #define BJACK_STAY_NAME "MENU"
474 #define BJACK_QUIT_NAME "BACK"
475 #define BJACK_DOUBLE_NAME "USER"
476 #define BJACK_SELECT BUTTON_SELECT
477 #define BJACK_QUIT BUTTON_BACK
478 #define BJACK_MAX (BUTTON_LEFT|BUTTON_UP)
479 #define BJACK_MIN (BUTTON_RIGHT|BUTTON_DOWN)
480 #define BJACK_STAY BUTTON_MENU
481 #define BJACK_DOUBLEDOWN BUTTON_USER
482 #define BJACK_UP BUTTON_UP
483 #define BJACK_DOWN BUTTON_DOWN
484 #define BJACK_RIGHT BUTTON_RIGHT
485 #define BJACK_LEFT BUTTON_LEFT
487 #elif CONFIG_KEYPAD == HM60X_PAD
488 #define BJACK_SELECT_NAME "SELECT"
489 #define BJACK_STAY_NAME "UP+POWER"
490 #define BJACK_QUIT_NAME "POWER"
491 #define BJACK_DOUBLE_NAME "DOWN+POWER"
492 #define BJACK_SELECT BUTTON_SELECT
493 #define BJACK_QUIT BUTTON_POWER
494 #define BJACK_STAY (BUTTON_UP|BUTTON_POWER)
495 #define BJACK_DOUBLEDOWN (BUTTON_DOWN|BUTTON_POWER)
496 #define BJACK_UP BUTTON_UP
497 #define BJACK_DOWN BUTTON_DOWN
498 #define BJACK_RIGHT BUTTON_RIGHT
499 #define BJACK_LEFT BUTTON_LEFT
501 #elif CONFIG_KEYPAD == HM801_PAD
502 #define BJACK_SELECT_NAME "SELECT"
503 #define BJACK_STAY_NAME "PLAY"
504 #define BJACK_QUIT_NAME "POWER"
505 #define BJACK_DOUBLE_NAME "PREV"
506 #define BJACK_SELECT BUTTON_SELECT
507 #define BJACK_QUIT BUTTON_POWER
508 #define BJACK_STAY BUTTON_PLAY
509 #define BJACK_DOUBLEDOWN BUTTON_PREV
510 #define BJACK_UP BUTTON_UP
511 #define BJACK_DOWN BUTTON_DOWN
512 #define BJACK_RIGHT BUTTON_RIGHT
513 #define BJACK_LEFT BUTTON_LEFT
516 #error No keymap defined!
519 #ifdef HAVE_TOUCHSCREEN
520 #ifndef BJACK_DOUBLEDOWN
521 #define BJACK_DOUBLEDOWN BUTTON_MIDLEFT
522 #define BJACK_DOUBLE_NAME "BUTTON_MIDLEFT"
525 #define BJACK_SELECT BUTTON_CENTER
526 #define BJACK_SELECT_NAME "BUTTON_CENTER"
529 #define BJACK_MAX BUTTON_TOPRIGHT
532 #define BJACK_MIN BUTTON_TOPLEFT
535 #define BJACK_STAY BUTTON_BOTTOMLEFT
536 #define BJACK_STAY_NAME "BUTTON_BOTTOMLEFT"
539 #define BJACK_UP BUTTON_TOPMIDDLE
542 #define BJACK_DOWN BUTTON_BOTTOMMIDDLE
545 #define BJACK_RIGHT BUTTON_MIDRIGHT
548 #define BJACK_LEFT BUTTON_MIDLEFT
553 #ifdef HAVE_LCD_COLOR
554 #define BG_COLOR LCD_RGBPACK(0,157,0)
555 #define FG_COLOR LCD_WHITE
557 #define BG_COLOR LCD_WHITE
558 #define FG_COLOR LCD_BLACK
561 #define CARD_WIDTH BMPWIDTH_card_back
562 #define CARD_HEIGHT BMPHEIGHT_card_back
564 /* This is the max amount of cards onscreen before condensing */
565 #define MAX_CARDS LCD_WIDTH/(CARD_WIDTH+4)
567 extern const fb_data card_deck
[];
568 extern const fb_data card_back
[];
570 #define NEXT_CARD bj->player_cards[done][bj->num_player_cards[done]]
572 /* dealer and player card positions */
573 unsigned int dealer_x
, dealer_y
, player_x
, player_y
;
575 typedef struct card
{
576 unsigned int value
; /* Card's value in Blackjack */
577 unsigned int num
; /* Value on card face 0-12 (0=Ace, 1=2, 11=Q) */
578 unsigned int suit
; /* 0:Spades, 1:Hearts, 2: Clubs; 3: Diamonds */
582 typedef struct game_context
{
583 struct card player_cards
[2][22]; /* 22 Cards means the deal was all aces */
584 struct card dealer_cards
[22]; /* That is the worst-case scenario */
585 unsigned int player_total
;
586 unsigned int dealer_total
;
587 signed int player_money
;
588 unsigned int num_player_cards
[2];
589 unsigned int num_dealer_cards
;
590 unsigned int current_bet
;
591 unsigned int split_status
; /* 0 = split hasn't been asked, *
592 * 1 = split did not occur *
593 * 2 = split occurred *
594 * 3 = split occurred and 1st hand done */
597 bool asked_insurance
;
600 static bool resume
= false;
601 static bool resume_file
= false;
602 static struct highscore highscores
[NUM_SCORES
];
604 /*****************************************************************************
605 * blackjack_init() initializes blackjack data structures.
606 ******************************************************************************/
607 static void blackjack_init(struct game_context
* bj
) {
608 /* seed the rand generator */
609 rb
->srand(*rb
->current_tick
);
611 /* reset card positions */
613 dealer_y
= LCD_HEIGHT
/4 - CARD_HEIGHT
/2;
615 player_y
= LCD_HEIGHT
- LCD_HEIGHT
/4 - CARD_HEIGHT
/2;
617 /* check for resumed game */
621 bj
->player_total
= 0;
622 bj
->dealer_total
= 0;
623 bj
->num_player_cards
[0] = 2;
624 bj
->num_player_cards
[1] = 0;
625 bj
->num_dealer_cards
= 2;
626 bj
->end_hand
= false;
627 bj
->split_status
= 0;
628 bj
->is_blackjack
= false;
629 bj
->asked_insurance
= false;
632 /*****************************************************************************
633 * blackjack_drawtable() draws the table and some text.
634 ******************************************************************************/
635 static void blackjack_drawtable(struct game_context
* bj
) {
636 unsigned int w
, h
, y_loc
;
640 rb
->lcd_getstringsize("Bet", &w
, &h
);
641 rb
->lcd_putsxy(LCD_WIDTH
- w
, 2*h
+ 1, "Bet");
642 rb
->snprintf(str
, 9, "$%d", bj
->current_bet
);
643 rb
->lcd_getstringsize(str
, &w
, &h
);
644 rb
->lcd_putsxy(LCD_WIDTH
- w
, 3*h
+ 1, str
);
645 y_loc
= LCD_HEIGHT
/2;
647 rb
->lcd_getstringsize("Bet", &w
, &h
);
648 rb
->lcd_putsxy(LCD_WIDTH
- w
, 5*h
/ 2, "Bet");
649 rb
->snprintf(str
, 9, "$%d", bj
->current_bet
);
650 rb
->lcd_getstringsize(str
, &w
, &h
);
651 rb
->lcd_putsxy(LCD_WIDTH
- w
, 7*h
/ 2, str
);
652 rb
->lcd_hline(0, LCD_WIDTH
, LCD_HEIGHT
/2);
653 y_loc
= LCD_HEIGHT
/2 + h
;
656 rb
->lcd_putsxy(0,0, "Dealer");
657 rb
->lcd_getstringsize("Player", &w
, &h
);
658 rb
->lcd_putsxy(0, y_loc
, "Player");
659 rb
->lcd_getstringsize("Total", &w
, &h
);
660 rb
->lcd_putsxy(LCD_WIDTH
- w
, y_loc
, "Total");
661 rb
->lcd_getstringsize("Money", &w
, &h
);
662 rb
->lcd_putsxy(LCD_WIDTH
- w
, 0, "Money");
663 rb
->snprintf(str
, 9, "$%d", bj
->player_money
- bj
->current_bet
);
664 rb
->lcd_getstringsize(str
, &w
, &h
);
665 rb
->lcd_putsxy(LCD_WIDTH
- w
, h
+ 1, str
);
666 rb
->snprintf(str
, 3, "%d", bj
->player_total
);
667 rb
->lcd_getstringsize(str
, &w
, &h
);
668 rb
->lcd_putsxy(LCD_WIDTH
- w
, y_loc
+ h
, str
);
671 /*****************************************************************************
672 * find_value() is passed a card and returns its blackjack value.
673 ******************************************************************************/
674 static unsigned int find_value(unsigned int number
) {
675 unsigned int thisValue
;
677 thisValue
= 11; /* Aces get a value of 11 at first */
678 else if (number
< 10)
679 thisValue
= number
+ 1;
681 thisValue
= 10; /* Anything 10 or higher gets a value of 10 */
686 /*****************************************************************************
687 * draw_card() draws a card to the screen.
688 ******************************************************************************/
689 static void draw_card(struct card temp_card
, bool shown
,
690 unsigned int x
, unsigned int y
) {
692 rb
->lcd_bitmap_part(card_deck
, CARD_WIDTH
*temp_card
.num
,
693 CARD_HEIGHT
*temp_card
.suit
,
694 STRIDE( SCREEN_MAIN
, BMPWIDTH_card_deck
,
695 BMPHEIGHT_card_deck
),
696 x
+1, y
+1, CARD_WIDTH
, CARD_HEIGHT
);
698 rb
->lcd_bitmap(card_back
, x
+1, y
+1,CARD_WIDTH
, CARD_HEIGHT
);
700 rb
->lcd_set_foreground(LCD_BLACK
);
705 rb
->lcd_hline(x
+2, x
+CARD_WIDTH
-1, y
);
706 rb
->lcd_hline(x
+2, x
+CARD_WIDTH
-1, y
+CARD_HEIGHT
+1);
707 rb
->lcd_vline(x
, y
+2, y
+CARD_HEIGHT
-3);
708 rb
->lcd_vline(x
+CARD_WIDTH
+1, y
+2, y
+CARD_HEIGHT
-1);
709 rb
->lcd_drawpixel(x
+1, y
+1);
710 rb
->lcd_drawpixel(x
+1, y
+CARD_HEIGHT
);
711 rb
->lcd_drawpixel(x
+CARD_WIDTH
, y
+1);
712 rb
->lcd_drawpixel(x
+CARD_WIDTH
, y
+CARD_HEIGHT
);
714 rb
->lcd_hline(x
+1, x
+CARD_WIDTH
, y
);
715 rb
->lcd_hline(x
+1, x
+CARD_WIDTH
, y
+CARD_HEIGHT
+1);
716 rb
->lcd_vline(x
, y
+1, y
+CARD_HEIGHT
);
717 rb
->lcd_vline(x
+CARD_WIDTH
+1, y
+1, y
+CARD_HEIGHT
);
721 rb
->lcd_set_foreground(FG_COLOR
);
725 /*****************************************************************************
726 * new_card() initializes a new card and gives it values.
727 ******************************************************************************/
728 static struct card
new_card(void) {
729 struct card new_card
;
730 new_card
.suit
= rb
->rand()%4; /* Random number 0-3 */
731 new_card
.num
= rb
->rand()%13; /* Random number 0-12 */
732 new_card
.value
= find_value(new_card
.num
);
733 new_card
.is_soft_ace
= (new_card
.num
== 0);
737 /*****************************************************************************
738 * deal_init_card() deals and draws to the screen the player's and dealer's
740 ******************************************************************************/
741 static void deal_init_cards(struct game_context
* bj
) {
742 bj
->dealer_cards
[0] = new_card();
743 bj
->dealer_total
+= bj
->dealer_cards
[0].value
;
745 draw_card(bj
->dealer_cards
[0], false, dealer_x
, dealer_y
);
747 bj
->dealer_cards
[1] = new_card();
748 bj
->dealer_total
+= bj
->dealer_cards
[1].value
;
749 draw_card(bj
->dealer_cards
[1], true, dealer_x
+ CARD_WIDTH
+ 4, dealer_y
);
751 bj
->player_cards
[0][0] = new_card();
752 bj
->player_total
+= bj
->player_cards
[0][0].value
;
753 draw_card(bj
->player_cards
[0][0], true, player_x
, player_y
);
754 player_x
+= CARD_WIDTH
+ 4;
756 bj
->player_cards
[0][1] = new_card();
757 bj
->player_total
+= bj
->player_cards
[0][1].value
;
758 draw_card(bj
->player_cards
[0][1], true, player_x
, player_y
);
759 player_x
+= CARD_WIDTH
+ 4;
762 /*****************************************************************************
763 * redraw_board() redraws all the cards and the board
764 ******************************************************************************/
765 static void redraw_board(struct game_context
* bj
) {
766 unsigned int i
, n
, upper_bound
;
767 rb
->lcd_clear_display();
769 blackjack_drawtable(bj
);
772 upper_bound
= bj
->split_status
> 1 ? 2 : 1;
774 for (i
= 0; i
< bj
->num_dealer_cards
; i
++) {
776 draw_card(bj
->dealer_cards
[0], false, dealer_x
, dealer_y
);
778 /* increment i so the dealer's first card isn't displayed */
780 dealer_x
+= CARD_WIDTH
+ 4;
782 draw_card(bj
->dealer_cards
[i
], true, dealer_x
, dealer_y
);
784 if (bj
->num_dealer_cards
> MAX_CARDS
-1)
787 dealer_x
+= CARD_WIDTH
+ 4;
790 for (n
= 0; n
< upper_bound
; n
++) {
791 for (i
= 0; i
< bj
->num_player_cards
[n
]; i
++) {
792 draw_card(bj
->player_cards
[n
][i
], true, player_x
, player_y
);
793 if (bj
->split_status
>1 || bj
->num_player_cards
[n
]>MAX_CARDS
)
796 player_x
+= CARD_WIDTH
+ 4;
798 if (bj
->split_status
> 1)
799 player_x
= LCD_WIDTH
/2 + 4;
803 /*****************************************************************************
804 * update_total updates the player's total
805 ******************************************************************************/
806 static void update_total(struct game_context
* bj
) {
809 rb
->snprintf(total
, 3, "%d", bj
->player_total
);
810 rb
->lcd_getstringsize(total
, &w
, &h
);
814 rb
->lcd_putsxy(LCD_WIDTH
- w
, LCD_HEIGHT
/2 + h
, total
);
815 rb
->lcd_update_rect(LCD_WIDTH
- w
, LCD_HEIGHT
/2 + h
, w
, h
);
819 /*****************************************************************************
820 * check_for_aces() is passed an array of cards and returns where an ace is
821 * located. Otherwise, returns -1.
822 ******************************************************************************/
823 static signed int check_for_aces(struct card temp_cards
[], unsigned int size
) {
825 for(i
= 0; i
< size
; i
++) {
826 if (temp_cards
[i
].is_soft_ace
)
832 /*****************************************************************************
833 * check_totals() compares player and dealer totals.
834 * 0: bust 1: loss, 2: push, 3: win, 4: blackjack, 5: something's not right...
835 ******************************************************************************/
836 static unsigned int check_totals(struct game_context
* bj
) {
838 if (bj
->player_total
> 21)
840 else if (bj
->player_total
== 21 && bj
->is_blackjack
) {
841 if (bj
->dealer_total
== 21 && bj
->num_dealer_cards
== 2)
846 else if (bj
->player_total
== bj
->dealer_total
)
848 else if (bj
->dealer_total
> 21 && bj
->player_total
< 22)
850 else if (bj
->dealer_total
> bj
->player_total
)
852 else if (bj
->player_total
> bj
->dealer_total
)
860 /*****************************************************************************
861 * finish_dealer() draws cards for the dealer until he has 17 or more.
862 ******************************************************************************/
863 static void finish_dealer(struct game_context
* bj
) {
866 if (bj
->dealer_total
> 16 && bj
->dealer_total
< 22)
869 while (bj
->dealer_total
< 17) {
870 bj
->dealer_cards
[bj
->num_dealer_cards
] = new_card();
871 bj
->dealer_total
+= bj
->dealer_cards
[bj
->num_dealer_cards
].value
;
872 bj
->num_dealer_cards
++;
875 while (bj
->dealer_total
> 21) {
876 temp
= check_for_aces(bj
->dealer_cards
, bj
->num_dealer_cards
);
878 bj
->dealer_cards
[temp
].is_soft_ace
= false;
879 bj
->dealer_total
-= 10;
886 /*****************************************************************************
887 * finish_game() completes the game once player's turn is over.
888 ******************************************************************************/
889 static void finish_game(struct game_context
* bj
) {
890 unsigned int rValue
, w
, h
;
895 } while (bj
->dealer_total
< 17);
898 rValue
= check_totals(bj
);
901 rb
->snprintf(str
, sizeof(str
), " Bust! ");
902 bj
->player_money
-= bj
->current_bet
;
904 else if (rValue
== 1) {
905 rb
->snprintf(str
, sizeof(str
), " Sorry, you lost. ");
906 bj
->player_money
-= bj
->current_bet
;
908 else if (rValue
== 2) {
909 rb
->snprintf(str
, sizeof(str
), " Push ");
911 else if (rValue
== 3) {
912 rb
->snprintf(str
, sizeof(str
), " You won! ");
913 bj
->player_money
+= bj
->current_bet
;
916 rb
->snprintf(str
, sizeof(str
), " Blackjack! ");
917 bj
->player_money
+= bj
->current_bet
* 3 / 2;
919 rb
->lcd_getstringsize(str
, &w
, &h
);
922 rb
->lcd_set_drawmode(DRMODE_BG
+DRMODE_INVERSEVID
);
923 rb
->lcd_fillrect(0, LCD_HEIGHT
/2, LCD_WIDTH
, LCD_HEIGHT
/2);
924 rb
->lcd_set_drawmode(DRMODE_SOLID
);
925 rb
->lcd_putsxy(LCD_WIDTH
/2 - w
/2, LCD_HEIGHT
/2 + h
, str
);
926 rb
->snprintf(str
, 12, "You have %d", bj
->player_total
);
927 rb
->lcd_getstringsize(str
, &w
, &h
);
928 rb
->lcd_putsxy(LCD_WIDTH
/2 - w
/2, LCD_HEIGHT
/2, str
);
930 rb
->lcd_putsxy(LCD_WIDTH
/2 - w
/2, LCD_HEIGHT
/2 - h
/2, str
);
935 /*****************************************************************************
936 * blackjack_loadgame() loads the saved game and returns load success.
937 ******************************************************************************/
938 static bool blackjack_loadgame(struct game_context
* bj
) {
943 fd
= rb
->open(SAVE_FILE
, O_RDONLY
);
944 if(fd
< 0) return false;
946 /* read in saved game */
947 if(rb
->read(fd
, bj
, sizeof(struct game_context
))
948 == (long)sizeof(struct game_context
))
958 /*****************************************************************************
959 * blackjack_savegame() saves the current game state.
960 ******************************************************************************/
961 static void blackjack_savegame(struct game_context
* bj
) {
966 /* write out the game state to the save file */
967 fd
= rb
->open(SAVE_FILE
, O_WRONLY
|O_CREAT
, 0666);
970 rb
->write(fd
, bj
, sizeof(struct game_context
));
974 /*****************************************************************************
975 * blackjack_get_yes_no() gets a yes/no answer from the user
976 ******************************************************************************/
977 static unsigned int blackjack_get_yes_no(char message
[20]) {
979 unsigned int w
, h
, b
, choice
= 0;
980 bool breakout
= false;
981 char message_yes
[24], message_no
[24];
983 rb
->strcpy(message_yes
, message
);
984 rb
->strcpy(message_no
, message
);
985 rb
->strcat(message_yes
, " Yes");
986 rb
->strcat(message_no
, " No");
987 rb
->lcd_getstringsize(message_yes
, &w
, &h
);
988 const char *stg
[] = {message_yes
, message_no
};
996 #ifdef HAVE_LCD_COLOR
997 rb
->lcd_fillrect(LCD_WIDTH
/2 - w
/2, LCD_HEIGHT
/2 + b
, w
+1, h
+3);
998 rb
->lcd_set_foreground(LCD_BLACK
);
999 rb
->lcd_set_background(LCD_WHITE
);
1001 rb
->lcd_set_drawmode(DRMODE_BG
+DRMODE_INVERSEVID
);
1002 rb
->lcd_fillrect(LCD_WIDTH
/2 - w
/2, LCD_HEIGHT
/2 + b
, w
+1, h
+3);
1003 rb
->lcd_set_drawmode(DRMODE_SOLID
);
1005 rb
->lcd_drawrect(LCD_WIDTH
/2 - w
/2 - 1, LCD_HEIGHT
/2 + b
- 1, w
+3, h
+4);
1008 rb
->lcd_putsxy(LCD_WIDTH
/2 - w
/2, LCD_HEIGHT
/2 + b
+1, stg
[choice
]);
1009 rb
->lcd_update_rect(LCD_WIDTH
/2 - w
/2 - 1, LCD_HEIGHT
/2 + b
-1,
1011 button
= rb
->button_get(true);
1015 case (BJACK_LEFT
|BUTTON_REPEAT
):
1017 case (BJACK_RIGHT
|BUTTON_REPEAT
):
1020 case BJACK_SELECT
: breakout
= true;
1022 case BJACK_QUIT
: breakout
= true;
1029 rb
->lcd_set_foreground(FG_COLOR
);
1030 rb
->lcd_set_background(BG_COLOR
);
1035 /*****************************************************************************
1036 * blackjack_get_amount() gets an amount from the player to be used
1037 ******************************************************************************/
1038 static signed int blackjack_get_amount(char message
[20], signed int lower_limit
,
1039 signed int upper_limit
,
1042 bool breakout
= false, changed
= false;
1046 rb
->lcd_getstringsize("A", &w
, &h
); /* find the size of one character */
1048 if (start
> upper_limit
)
1049 amount
= upper_limit
;
1050 else if (start
< lower_limit
)
1051 amount
= lower_limit
;
1056 rb
->lcd_set_background(LCD_WHITE
);
1057 rb
->lcd_set_foreground(LCD_BLACK
);
1060 #if LCD_HEIGHT <= 64
1061 rb
->lcd_clear_display();
1062 rb
->lcd_puts(0, 1, message
);
1063 rb
->lcd_putsf(0, 2, "$%d", amount
);
1064 rb
->lcd_puts(0, 3, "RIGHT: +1");
1065 rb
->lcd_puts(0, 4, "LEFT: -1");
1066 rb
->lcd_puts(0, 5, "UP: +10");
1067 rb
->lcd_puts(0, 6, "DOWN: -10");
1070 rb
->lcd_set_drawmode(DRMODE_BG
+DRMODE_INVERSEVID
);
1071 rb
->lcd_fillrect(LCD_WIDTH
/2 - 9*w
- 1, LCD_HEIGHT
/2 - 4*h
- 3,
1073 rb
->lcd_set_drawmode(DRMODE_SOLID
);
1074 rb
->lcd_drawrect(LCD_WIDTH
/2 - 9*w
- 1, LCD_HEIGHT
/2 - 4*h
- 3,
1076 rb
->lcd_putsxy(LCD_WIDTH
/2 - 9*w
, LCD_HEIGHT
/2 - 4*h
- 1, message
);
1077 rb
->lcd_putsxyf(LCD_WIDTH
/2 - 9*w
, LCD_HEIGHT
/2 - 3*h
, "$%d", amount
);
1078 #if (CONFIG_KEYPAD == IPOD_4G_PAD) || \
1079 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
1080 (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
1081 (CONFIG_KEYPAD == SANSA_E200_PAD) || \
1082 (CONFIG_KEYPAD == SANSA_FUZE_PAD) || \
1083 (CONFIG_KEYPAD == SANSA_CONNECT_PAD) || \
1084 (CONFIG_KEYPAD == MPIO_HD300_PAD)
1085 rb
->lcd_putsxy(LCD_WIDTH
/2 - 9*w
, LCD_HEIGHT
/2 - h
-2, " >>|: +1");
1086 rb
->lcd_putsxy(LCD_WIDTH
/2 - 9*w
, LCD_HEIGHT
/2 - 1, " |<<: -1");
1087 rb
->lcd_putsxy(LCD_WIDTH
/2 - 9*w
, LCD_HEIGHT
/2 + h
, "SCROLL+: +10");
1088 rb
->lcd_putsxy(LCD_WIDTH
/2 - 9*w
, LCD_HEIGHT
/2 + 2*h
+ 1, "SCROLL-: -10");
1089 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
1090 rb
->lcd_putsxy(LCD_WIDTH
/2 - 9*w
, LCD_HEIGHT
/2 - h
-2, "RIGHT: +1");
1091 rb
->lcd_putsxy(LCD_WIDTH
/2 - 9*w
, LCD_HEIGHT
/2 - 1, "LEFT: -1");
1092 rb
->lcd_putsxy(LCD_WIDTH
/2 - 9*w
, LCD_HEIGHT
/2 + h
, "SCROLL+: +10");
1093 rb
->lcd_putsxy(LCD_WIDTH
/2 - 9*w
, LCD_HEIGHT
/2 + 2*h
+ 1, "SCROLL-: -10");
1095 rb
->lcd_putsxy(LCD_WIDTH
/2 - 9*w
, LCD_HEIGHT
/2 - h
-2, "RIGHT: +1");
1096 rb
->lcd_putsxy(LCD_WIDTH
/2 - 9*w
, LCD_HEIGHT
/2 - 1, "LEFT: -1");
1097 rb
->lcd_putsxy(LCD_WIDTH
/2 - 9*w
, LCD_HEIGHT
/2 + h
, "UP: +10");
1098 rb
->lcd_putsxy(LCD_WIDTH
/2 - 9*w
, LCD_HEIGHT
/2 + 2*h
+ 1, "DOWN: -10");
1100 rb
->lcd_update_rect(LCD_WIDTH
/2 - 9*w
- 1, LCD_HEIGHT
/2 - 4*h
- 3,
1105 button
= rb
->button_get(true);
1109 case (BJACK_UP
|BUTTON_REPEAT
):
1110 if (amount
+ 10 < upper_limit
+ 1) {
1116 case (BJACK_DOWN
|BUTTON_REPEAT
):
1117 if (amount
- 10 > lower_limit
- 1) {
1123 case (BJACK_RIGHT
|BUTTON_REPEAT
):
1124 if (amount
+ 1 < upper_limit
+ 1) {
1130 case (BJACK_LEFT
|BUTTON_REPEAT
):
1131 if (amount
- 1 > lower_limit
- 1) {
1138 amount
= upper_limit
;
1144 amount
= lower_limit
;
1158 #if LCD_HEIGHT <= 64
1159 rb
->lcd_putsf(0, 2, "$%d", amount
);
1162 rb
->lcd_set_drawmode(DRMODE_BG
+DRMODE_INVERSEVID
);
1163 rb
->lcd_fillrect(LCD_WIDTH
/2 - 9*w
, LCD_HEIGHT
/2 - 3*h
, 5*w
, h
);
1164 rb
->lcd_set_drawmode(DRMODE_SOLID
);
1165 rb
->lcd_putsxyf(LCD_WIDTH
/2 - 9*w
, LCD_HEIGHT
/2 - 3*h
, "$%d", amount
);
1166 rb
->lcd_update_rect(LCD_WIDTH
/2 - 9*w
, LCD_HEIGHT
/2 - 3*h
, 5*w
, h
);
1173 rb
->lcd_set_foreground(FG_COLOR
);
1174 rb
->lcd_set_background(BG_COLOR
);
1176 rb
->lcd_clear_display();
1180 /*****************************************************************************
1181 * blackjack_get_bet() gets the player's bet.
1182 ******************************************************************************/
1183 static void blackjack_get_bet(struct game_context
* bj
) {
1184 bj
->current_bet
= blackjack_get_amount("Please enter a bet", 10,
1185 bj
->player_money
, bj
->current_bet
);
1188 /*****************************************************************************
1189 * double_down() returns one final card then finishes the game
1190 ******************************************************************************/
1191 static void double_down(struct game_context
* bj
) {
1192 bj
->current_bet
*= 2;
1193 bj
->player_cards
[0][bj
->num_player_cards
[0]] = new_card();
1194 bj
->player_total
+= bj
->player_cards
[0][bj
->num_player_cards
[0]].value
;
1195 bj
->num_player_cards
[0]++;
1198 /*****************************************************************************
1199 * split() checks if the player wants to split and acts accordingly.
1200 * When bj->split_status is 1, no split occurred. 2 means the player split and 3
1201 * means a split has already occurred and the first hand is done.
1202 ******************************************************************************/
1203 static void split(struct game_context
* bj
) {
1204 if (blackjack_get_yes_no("Split?") != 0)
1205 bj
->split_status
= 1;
1207 bj
->split_status
= 2;
1208 bj
->current_bet
*= 2;
1209 bj
->num_player_cards
[0] = 1;
1210 bj
->num_player_cards
[1] = 1;
1211 bj
->player_cards
[1][0] = bj
->player_cards
[0][1];
1212 bj
->player_total
= bj
->player_cards
[0][0].value
;
1216 /*****************************************************************************
1217 * insurance() see if the player wants to buy insurance and how much.
1218 ******************************************************************************/
1219 static unsigned int insurance(struct game_context
* bj
) {
1220 unsigned int insurance
, max_amount
;
1222 insurance
= blackjack_get_yes_no("Buy Insurance?");
1223 bj
->asked_insurance
= true;
1224 max_amount
= bj
->current_bet
< (unsigned int)bj
->player_money
?
1225 bj
->current_bet
/2 : (unsigned int)bj
->player_money
;
1226 if (insurance
!= 0) return 0;
1228 insurance
= blackjack_get_amount("How much?", 0, max_amount
, 0);
1233 /*****************************************************************************
1234 * play_again() checks to see if the player wants to keep playing.
1235 ******************************************************************************/
1236 static unsigned int play_again(void) {
1237 return blackjack_get_yes_no("Play Again?");
1240 /*****************************************************************************
1241 * blackjack_help() displays help text.
1242 ******************************************************************************/
1243 static bool blackjack_help(void) {
1244 static char *help_text
[] = {
1245 "Blackjack", "", "Aim", "",
1246 "Try", "to", "get", "as", "close", "to", "21", "without", "going",
1247 "over", "or", "simply", "beat", "out", "the", "dealer", "for", "the",
1248 "best", "hand.", "", "",
1250 BJACK_SELECT_NAME
, ":", "hit", "/", "select", "",
1251 BJACK_STAY_NAME
, ":", "stay", "",
1252 BJACK_DOUBLE_NAME
, ":", "double", "down", "",
1253 BJACK_QUIT_NAME
, ":", "go", "to", "menu", "",
1255 static struct style_text formation
[]={
1256 { 0, TEXT_CENTER
|TEXT_UNDERLINE
},
1262 rb
->lcd_setfont(FONT_UI
);
1263 #ifdef HAVE_LCD_COLOR
1264 rb
->lcd_set_background(LCD_BLACK
);
1265 rb
->lcd_set_foreground(LCD_WHITE
);
1267 if (display_text(ARRAYLEN(help_text
), help_text
, formation
, NULL
, true))
1269 rb
->lcd_setfont(FONT_SYSFIXED
);
1274 static int blackjack_menu_cb(int action
, const struct menu_item_ex
*this_item
)
1276 int i
= ((intptr_t)this_item
);
1277 if(action
== ACTION_REQUEST_MENUITEM
1278 && !resume
&& (i
==0 || i
==5))
1279 return ACTION_EXIT_MENUITEM
;
1283 /*****************************************************************************
1284 * blackjack_menu() is the initial menu at the start of the game.
1285 ******************************************************************************/
1286 static unsigned int blackjack_menu(void) {
1288 bool breakout
= false;
1290 MENUITEM_STRINGLIST(menu
, "BlackJack Menu", blackjack_menu_cb
,
1291 "Resume Game", "Start New Game",
1292 "High Scores", "Help",
1294 "Quit without Saving", "Quit");
1297 switch(rb
->do_menu(&menu
, &selection
, NULL
, false)) {
1301 rb
->remove(SAVE_FILE
);
1302 resume_file
= false;
1309 highscore_show(-1, highscores
, NUM_SCORES
, false);
1312 if(blackjack_help())
1316 if (playback_control(NULL
))
1320 return BJ_QUIT_WITHOUT_SAVING
;
1325 return BJ_QUIT_WITHOUT_SAVING
;
1327 case MENU_ATTACHED_USB
:
1338 /*****************************************************************************
1339 * blackjack() is the main game subroutine, it returns the final game status.
1340 ******************************************************************************/
1341 static int blackjack(struct game_context
* bj
) {
1343 unsigned int w
, h
, temp_var
, done
= 0, todo
= 1;
1345 bool breakout
= false;
1346 bool dbl_down
= false;
1348 /********************
1350 ********************/
1351 temp_var
= blackjack_menu();
1356 rb
->lcd_set_background(BG_COLOR
);
1357 rb
->lcd_set_foreground(FG_COLOR
);
1360 /********************
1362 ********************/
1365 /********************
1367 ********************/
1369 resume_file
= false;
1370 /* check for resumed game */
1374 if (bj
->split_status
== 2) {
1376 player_x
= bj
->num_player_cards
[0] * 10 + 4;
1378 else if (bj
->split_status
== 3) {
1379 player_x
= bj
->num_player_cards
[1] * 10 + LCD_WIDTH
/2 + 4;
1385 bj
->player_money
= 1000;
1386 bj
->current_bet
= 10;
1387 blackjack_get_bet(bj
);
1388 if (bj
->current_bet
== 0)
1390 rb
->lcd_clear_display();
1391 deal_init_cards(bj
);
1392 blackjack_drawtable(bj
);
1400 if(bj
->player_total
== 21 && bj
->num_player_cards
[0] == 2) {
1401 bj
->is_blackjack
= true;
1402 bj
->end_hand
= true;
1405 else if(bj
->dealer_cards
[1].is_soft_ace
&& !breakout
&&
1406 !bj
->asked_insurance
) {
1407 temp_var
= insurance(bj
);
1408 if (bj
->dealer_total
== 21) {
1409 rb
->splash(HZ
, "Dealer has blackjack");
1410 bj
->player_money
+= temp_var
;
1411 bj
->end_hand
= true;
1417 rb
->splash(HZ
, "Dealer does not have blackjack");
1418 bj
->player_money
-= temp_var
;
1424 if(!bj
->end_hand
&& bj
->split_status
== 0 &&
1425 bj
->player_cards
[0][0].num
== bj
->player_cards
[0][1].num
) {
1428 rb
->lcd_update_rect(0, LCD_HEIGHT
/2, LCD_WIDTH
, LCD_HEIGHT
/2);
1429 if (bj
->split_status
== 2) {
1431 player_x
= bj
->num_player_cards
[0] * 10 + 4;
1435 while(!bj
->end_hand
&& done
< todo
) {
1436 button
= rb
->button_get(true);
1440 NEXT_CARD
= new_card();
1441 bj
->player_total
+= NEXT_CARD
.value
;
1442 draw_card(NEXT_CARD
, true, player_x
, player_y
);
1443 bj
->num_player_cards
[done
]++;
1444 if (bj
->num_player_cards
[done
] == MAX_CARDS
+ 1) {
1446 rb
->lcd_update_rect(0, LCD_HEIGHT
/2, LCD_WIDTH
,
1449 else if (bj
->num_player_cards
[done
]>MAX_CARDS
|| todo
> 1) {
1450 rb
->lcd_update_rect(player_x
, player_y
, CARD_WIDTH
+2,
1455 rb
->lcd_update_rect(player_x
, player_y
, CARD_WIDTH
+2,
1457 player_x
+= CARD_WIDTH
+ 4;
1463 bj
->end_hand
= true;
1465 case BJACK_DOUBLEDOWN
:
1466 if ((signed int)bj
->current_bet
* 2 <
1467 bj
->player_money
+ 1 &&
1468 bj
->num_player_cards
[0]==2 && todo
==1) {
1471 if (bj
->player_total
< 22) {
1472 bj
->end_hand
= true;
1476 else if((signed int)bj
->current_bet
* 2 >
1478 rb
->splash(HZ
, "Not enough money to double down.");
1489 while (bj
->player_total
> 21 && !bj
->end_hand
) {
1490 temp
= check_for_aces(bj
->player_cards
[done
],
1491 bj
->num_player_cards
[done
]);
1493 bj
->player_cards
[done
][temp
].is_soft_ace
= false;
1494 bj
->player_total
-= 10;
1497 bj
->end_hand
= true;
1502 bj
->end_hand
= true;
1509 temp
= bj
->player_total
;
1510 bj
->player_total
= temp_var
;
1513 rb
->lcd_getstringsize(" Split 1 ", &w
, &h
);
1514 rb
->lcd_putsxy(LCD_WIDTH
/2-w
/2, LCD_HEIGHT
/2-3*h
/2,
1516 rb
->lcd_update_rect(LCD_WIDTH
/2-w
/2, LCD_HEIGHT
/2-3*h
/2,
1518 bj
->current_bet
/= 2;
1519 rb
->lcd_update_rect(LCD_WIDTH
/2-w
/2, LCD_HEIGHT
/2-3*h
/2,
1522 bj
->player_total
= temp_var
;
1524 rb
->lcd_getstringsize(" Split 2 ", &w
, &h
);
1525 rb
->lcd_putsxy(LCD_WIDTH
/2-w
/2, LCD_HEIGHT
/2-3*h
/2,
1527 rb
->lcd_update_rect(LCD_WIDTH
/2-w
/2, LCD_HEIGHT
/2-3*h
/2,
1532 bj
->end_hand
= false;
1533 bj
->split_status
= 3;
1534 temp_var
= bj
->player_total
;
1535 bj
->player_total
= bj
->player_cards
[1][0].value
;
1547 if (bj
->player_money
< 10) {
1552 if (bj
->end_hand
) { /* If hand is over */
1553 if (play_again() != 0) /* User wants to quit */
1555 else { /* User keeps playing */
1557 temp
= bj
->current_bet
;
1558 bj
->current_bet
= 0;
1561 bj
->current_bet
= temp
;
1563 bj
->current_bet
/= 2;
1569 blackjack_get_bet(bj
);
1570 if (bj
->current_bet
== 0)
1572 deal_init_cards(bj
);
1573 blackjack_drawtable(bj
);
1582 /*****************************************************************************
1583 * plugin entry point.
1584 ******************************************************************************/
1585 enum plugin_status
plugin_start(const void* parameter
)
1587 struct game_context bj
;
1593 rb
->lcd_set_backdrop(NULL
);
1596 /* load high scores */
1597 highscore_load(SCORE_FILE
, highscores
, NUM_SCORES
);
1598 resume
= blackjack_loadgame(&bj
);
1599 resume_file
= resume
;
1601 rb
->lcd_setfont(FONT_SYSFIXED
);
1604 switch(blackjack(&bj
)){
1606 rb
->splash(HZ
, "Not enough money to continue");
1607 /* fall through to BJ_END */
1610 if(!resume
&& bj
.player_money
> 10) {
1611 /* There is no level, so store -1 to blank column */
1612 int position
= highscore_update(bj
.player_money
, -1, "",
1613 highscores
, NUM_SCORES
);
1617 rb
->splash(HZ
*2, "New High Score");
1618 highscore_show(position
, highscores
, NUM_SCORES
, false);
1624 highscore_save(SCORE_FILE
, highscores
, NUM_SCORES
);
1625 return PLUGIN_USB_CONNECTED
;
1628 rb
->splash(HZ
*1, "Saving game...");
1629 blackjack_savegame(&bj
);
1632 case BJ_QUIT_WITHOUT_SAVING
:
1640 highscore_save(SCORE_FILE
, highscores
, NUM_SCORES
);