A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Tom Ross
11 *
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.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "plugin.h"
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"
28
29
30
31/* save files */
32#define SCORE_FILE PLUGIN_GAMES_DATA_DIR "/blackjack.score"
33#define SAVE_FILE PLUGIN_GAMES_DATA_DIR "/blackjack.save"
34#define NUM_SCORES 5
35
36/* final game return status */
37enum {
38 BJ_LOSE,
39 BJ_QUIT_WITHOUT_SAVING,
40 BJ_QUIT,
41 BJ_USB,
42 BJ_END,
43};
44
45#if CONFIG_KEYPAD == IRIVER_H10_PAD
46#define BJACK_SELECT_NAME "PLAY"
47#define BJACK_STAY_NAME ">>|"
48#define BJACK_QUIT_NAME "POWER"
49#define BJACK_DOUBLE_NAME "|<<"
50#define BJACK_SELECT BUTTON_PLAY
51#define BJACK_QUIT BUTTON_POWER
52#define BJACK_STAY BUTTON_FF
53#define BJACK_DOUBLEDOWN BUTTON_REW
54#define BJACK_UP BUTTON_SCROLL_UP
55#define BJACK_DOWN BUTTON_SCROLL_DOWN
56#define BJACK_RIGHT BUTTON_RIGHT
57#define BJACK_LEFT BUTTON_LEFT
58
59#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
60 (CONFIG_KEYPAD == IRIVER_H300_PAD)
61#define BJACK_SELECT_NAME "ON"
62#define BJACK_STAY_NAME "REC"
63#define BJACK_QUIT_NAME "OFF"
64#define BJACK_DOUBLE_NAME "SELECT"
65#define BJACK_SELECT BUTTON_ON
66#define BJACK_QUIT BUTTON_OFF
67#define BJACK_STAY BUTTON_REC
68#define BJACK_DOUBLEDOWN BUTTON_SELECT
69#define BJACK_UP BUTTON_UP
70#define BJACK_DOWN BUTTON_DOWN
71#define BJACK_RIGHT BUTTON_RIGHT
72#define BJACK_LEFT BUTTON_LEFT
73
74#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
75 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
76 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
77#define BJACK_SELECT_NAME "SELECT"
78#define BJACK_STAY_NAME "RIGHT"
79#define BJACK_RESUME_NAME "PLAY"
80#define BJACK_QUIT_NAME "MENU"
81#define BJACK_DOUBLE_NAME "LEFT"
82#define BJACK_SELECT BUTTON_SELECT
83#define BJACK_QUIT BUTTON_MENU
84#define BJACK_STAY BUTTON_RIGHT
85#define BJACK_DOUBLEDOWN BUTTON_LEFT
86#define BJACK_UP BUTTON_SCROLL_FWD
87#define BJACK_DOWN BUTTON_SCROLL_BACK
88#define BJACK_RIGHT BUTTON_RIGHT
89#define BJACK_LEFT BUTTON_LEFT
90
91#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
92#define BJACK_SELECT_NAME "SELECT"
93#define BJACK_STAY_NAME "REC"
94#define BJACK_QUIT_NAME "POWER"
95#define BJACK_DOUBLE_NAME "PLAY"
96#define BJACK_SELECT BUTTON_SELECT
97#define BJACK_QUIT BUTTON_POWER
98#define BJACK_MAX (BUTTON_PLAY|BUTTON_UP)
99#define BJACK_MIN (BUTTON_PLAY|BUTTON_DOWN)
100#define BJACK_STAY BUTTON_REC
101#define BJACK_DOUBLEDOWN BUTTON_PLAY
102#define BJACK_UP BUTTON_UP
103#define BJACK_DOWN BUTTON_DOWN
104#define BJACK_RIGHT BUTTON_RIGHT
105#define BJACK_LEFT BUTTON_LEFT
106
107#elif CONFIG_KEYPAD == GIGABEAT_PAD
108#define BJACK_SELECT_NAME "SELECT"
109#define BJACK_STAY_NAME "VOL-"
110#define BJACK_QUIT_NAME "POWER"
111#define BJACK_DOUBLE_NAME "A"
112#define BJACK_SELECT BUTTON_SELECT
113#define BJACK_QUIT BUTTON_POWER
114#define BJACK_MAX BUTTON_VOL_UP
115#define BJACK_MIN BUTTON_VOL_DOWN
116#define BJACK_STAY BUTTON_VOL_DOWN
117#define BJACK_DOUBLEDOWN BUTTON_A
118#define BJACK_UP BUTTON_UP
119#define BJACK_DOWN BUTTON_DOWN
120#define BJACK_RIGHT BUTTON_RIGHT
121#define BJACK_LEFT BUTTON_LEFT
122
123#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
124 (CONFIG_KEYPAD == SANSA_CONNECT_PAD)
125#define BJACK_SELECT_NAME "SELECT"
126#define BJACK_STAY_NAME "RIGHT"
127#define BJACK_QUIT_NAME "POWER"
128#define BJACK_DOUBLE_NAME "LEFT"
129#define BJACK_SELECT BUTTON_SELECT
130#define BJACK_QUIT BUTTON_POWER
131#define BJACK_MAX BUTTON_UP
132#define BJACK_MIN BUTTON_DOWN
133#define BJACK_STAY BUTTON_RIGHT
134#define BJACK_DOUBLEDOWN BUTTON_LEFT
135#define BJACK_UP BUTTON_SCROLL_FWD
136#define BJACK_DOWN BUTTON_SCROLL_BACK
137#define BJACK_RIGHT BUTTON_RIGHT
138#define BJACK_LEFT BUTTON_LEFT
139
140#elif CONFIG_KEYPAD == SANSA_FUZE_PAD
141#define BJACK_SELECT_NAME "SELECT"
142#define BJACK_STAY_NAME "RIGHT"
143#define BJACK_QUIT_NAME "HOME"
144#define BJACK_DOUBLE_NAME "LEFT"
145#define BJACK_SELECT BUTTON_SELECT
146#define BJACK_QUIT (BUTTON_HOME|BUTTON_REPEAT)
147#define BJACK_MAX BUTTON_UP
148#define BJACK_MIN BUTTON_DOWN
149#define BJACK_STAY BUTTON_RIGHT
150#define BJACK_DOUBLEDOWN BUTTON_LEFT
151#define BJACK_UP BUTTON_SCROLL_FWD
152#define BJACK_DOWN BUTTON_SCROLL_BACK
153#define BJACK_RIGHT BUTTON_RIGHT
154#define BJACK_LEFT BUTTON_LEFT
155
156#elif CONFIG_KEYPAD == SANSA_C200_PAD || CONFIG_KEYPAD == SANSA_CLIP_PAD
157#define BJACK_SELECT_NAME "SELECT"
158#define BJACK_STAY_NAME "RIGHT"
159#define BJACK_QUIT_NAME "POWER"
160#define BJACK_DOUBLE_NAME "LEFT"
161#define BJACK_SELECT BUTTON_SELECT
162#define BJACK_QUIT BUTTON_POWER
163#define BJACK_MAX BUTTON_VOL_UP
164#define BJACK_MIN BUTTON_VOL_DOWN
165#define BJACK_STAY BUTTON_RIGHT
166#define BJACK_DOUBLEDOWN BUTTON_LEFT
167#define BJACK_UP BUTTON_UP
168#define BJACK_DOWN BUTTON_DOWN
169#define BJACK_RIGHT BUTTON_RIGHT
170#define BJACK_LEFT BUTTON_LEFT
171
172#elif CONFIG_KEYPAD == SANSA_M200_PAD
173#define BJACK_SELECT_NAME "SELECT"
174#define BJACK_STAY_NAME "RIGHT"
175#define BJACK_QUIT_NAME "POWER"
176#define BJACK_DOUBLE_NAME "LEFT"
177#define BJACK_SELECT (BUTTON_SELECT | BUTTON_REL)
178#define BJACK_QUIT BUTTON_POWER
179#define BJACK_MAX BUTTON_VOL_UP
180#define BJACK_MIN BUTTON_VOL_DOWN
181#define BJACK_STAY BUTTON_RIGHT
182#define BJACK_DOUBLEDOWN BUTTON_LEFT
183#define BJACK_UP BUTTON_UP
184#define BJACK_DOWN BUTTON_DOWN
185#define BJACK_RIGHT BUTTON_RIGHT
186#define BJACK_LEFT BUTTON_LEFT
187
188#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
189#define BJACK_SELECT_NAME "PLAY"
190#define BJACK_STAY_NAME "VOL-"
191#define BJACK_QUIT_NAME "BACK"
192#define BJACK_DOUBLE_NAME "SELECT"
193#define BJACK_SELECT BUTTON_PLAY
194#define BJACK_QUIT BUTTON_BACK
195#define BJACK_MAX BUTTON_VOL_UP
196#define BJACK_MIN BUTTON_VOL_DOWN
197#define BJACK_STAY BUTTON_VOL_DOWN
198#define BJACK_DOUBLEDOWN BUTTON_SELECT
199#define BJACK_UP BUTTON_UP
200#define BJACK_DOWN BUTTON_DOWN
201#define BJACK_RIGHT BUTTON_RIGHT
202#define BJACK_LEFT BUTTON_LEFT
203
204#elif CONFIG_KEYPAD == MROBE100_PAD
205#define BJACK_SELECT_NAME "SELECT"
206#define BJACK_STAY_NAME "DISPLAY"
207#define BJACK_QUIT_NAME "POWER"
208#define BJACK_DOUBLE_NAME "DOWN"
209#define BJACK_SELECT BUTTON_SELECT
210#define BJACK_QUIT BUTTON_POWER
211#define BJACK_MAX BUTTON_MENU
212#define BJACK_MIN BUTTON_DISPLAY
213#define BJACK_STAY BUTTON_DISPLAY
214#define BJACK_DOUBLEDOWN BUTTON_DOWN
215#define BJACK_UP BUTTON_UP
216#define BJACK_DOWN BUTTON_DOWN
217#define BJACK_RIGHT BUTTON_RIGHT
218#define BJACK_LEFT BUTTON_LEFT
219
220#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
221#define BJACK_SELECT_NAME "RC","PLAY"
222#define BJACK_STAY_NAME "RC", ">>|"
223#define BJACK_QUIT_NAME "RC_REC"
224#define BJACK_DOUBLE_NAME "RC_REW"
225#define BJACK_SELECT BUTTON_RC_PLAY
226#define BJACK_QUIT BUTTON_RC_REC
227#define BJACK_STAY BUTTON_RC_FF
228#define BJACK_DOUBLEDOWN BUTTON_RC_REW
229#define BJACK_UP BUTTON_RC_VOL_UP
230#define BJACK_DOWN BUTTON_RC_VOL_DOWN
231#define BJACK_RIGHT BUTTON_RC_FF
232#define BJACK_LEFT BUTTON_RC_REW
233
234#elif CONFIG_KEYPAD == COWON_D2_PAD
235#define BJACK_QUIT_NAME "POWER"
236#define BJACK_DOUBLE_NAME "-"
237#define BJACK_QUIT BUTTON_POWER
238#define BJACK_DOUBLEDOWN BUTTON_MINUS
239
240#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
241#define BJACK_SELECT_NAME "SELECT"
242#define BJACK_STAY_NAME "PLAY"
243#define BJACK_QUIT_NAME "POWER"
244#define BJACK_DOUBLE_NAME "CUSTOM"
245#define BJACK_SELECT BUTTON_SELECT
246#define BJACK_QUIT BUTTON_POWER
247#define BJACK_STAY BUTTON_PLAY
248#define BJACK_MAX (BUTTON_CUSTOM|BUTTON_UP)
249#define BJACK_MIN (BUTTON_CUSTOM|BUTTON_DOWN)
250#define BJACK_DOUBLEDOWN BUTTON_CUSTOM
251#define BJACK_UP BUTTON_UP
252#define BJACK_DOWN BUTTON_DOWN
253#define BJACK_RIGHT BUTTON_RIGHT
254#define BJACK_LEFT BUTTON_LEFT
255
256#elif CONFIG_KEYPAD == CREATIVE_ZENXFI3_PAD
257#define BJACK_SELECT_NAME "PLAY"
258#define BJACK_STAY_NAME "MENU"
259#define BJACK_QUIT_NAME "POWER"
260#define BJACK_DOUBLE_NAME "BACK"
261#define BJACK_SELECT BUTTON_PLAY
262#define BJACK_QUIT BUTTON_POWER
263#define BJACK_MAX BUTTON_VOL_UP
264#define BJACK_MIN BUTTON_VOL_DOWN
265#define BJACK_STAY BUTTON_MENU
266#define BJACK_DOUBLEDOWN BUTTON_BACK
267#define BJACK_UP BUTTON_UP
268#define BJACK_DOWN BUTTON_DOWN
269#define BJACK_RIGHT BUTTON_MENU
270#define BJACK_LEFT BUTTON_BACK
271
272#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
273#define BJACK_SELECT_NAME "SELECT"
274#define BJACK_STAY_NAME "VOL-"
275#define BJACK_QUIT_NAME "POWER"
276#define BJACK_DOUBLE_NAME "MENU"
277#define BJACK_SELECT BUTTON_SELECT
278#define BJACK_QUIT BUTTON_POWER
279#define BJACK_MAX BUTTON_VOL_UP
280#define BJACK_MIN BUTTON_VOL_DOWN
281#define BJACK_STAY BUTTON_VOL_DOWN
282#define BJACK_DOUBLEDOWN BUTTON_MENU
283#define BJACK_UP BUTTON_UP
284#define BJACK_DOWN BUTTON_DOWN
285#define BJACK_RIGHT BUTTON_RIGHT
286#define BJACK_LEFT BUTTON_LEFT
287
288#elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD
289#define BJACK_SELECT_NAME "PLAY"
290#define BJACK_STAY_NAME "VOL-"
291#define BJACK_QUIT_NAME "POWER"
292#define BJACK_DOUBLE_NAME "MENU"
293#define BJACK_SELECT BUTTON_PLAY
294#define BJACK_QUIT BUTTON_POWER
295#define BJACK_MAX BUTTON_VOL_UP
296#define BJACK_MIN BUTTON_VOL_DOWN
297#define BJACK_STAY BUTTON_VOL_DOWN
298#define BJACK_DOUBLEDOWN BUTTON_MENU
299#define BJACK_UP BUTTON_UP
300#define BJACK_DOWN BUTTON_DOWN
301#define BJACK_RIGHT BUTTON_RIGHT
302#define BJACK_LEFT BUTTON_LEFT
303
304#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
305#define BJACK_SELECT_NAME "MENU"
306#define BJACK_STAY_NAME "VOL-"
307#define BJACK_QUIT_NAME "POWER"
308#define BJACK_DOUBLE_NAME "PLAY"
309#define BJACK_SELECT BUTTON_MENU
310#define BJACK_QUIT BUTTON_POWER
311#define BJACK_MAX BUTTON_VOL_UP
312#define BJACK_MIN BUTTON_VOL_DOWN
313#define BJACK_STAY BUTTON_VOL_DOWN
314#define BJACK_DOUBLEDOWN BUTTON_PLAY
315#define BJACK_UP BUTTON_UP
316#define BJACK_DOWN BUTTON_DOWN
317#define BJACK_RIGHT BUTTON_NEXT
318#define BJACK_LEFT BUTTON_PREV
319
320#elif CONFIG_KEYPAD == ONDAVX747_PAD
321#define BJACK_QUIT_NAME "POWER"
322#define BJACK_DOUBLE_NAME "Vol-"
323#define BJACK_QUIT BUTTON_POWER
324#define BJACK_DOUBLEDOWN BUTTON_VOL_DOWN
325
326#elif CONFIG_KEYPAD == ONDAVX777_PAD
327#define BJACK_QUIT_NAME "POWER"
328#define BJACK_QUIT BUTTON_POWER
329
330#elif CONFIG_KEYPAD == MROBE500_PAD
331#define BJACK_QUIT_NAME "POWER"
332#define BJACK_QUIT BUTTON_POWER
333
334#elif (CONFIG_KEYPAD == SAMSUNG_YH820_PAD) || \
335 (CONFIG_KEYPAD == SAMSUNG_YH92X_PAD)
336#define BJACK_SELECT_NAME "PLAY"
337#define BJACK_STAY_NAME "FFWD"
338#define BJACK_QUIT_NAME "LONG REW"
339#define BJACK_DOUBLE_NAME "REW"
340#define BJACK_SELECT BUTTON_PLAY
341#define BJACK_QUIT (BUTTON_REW|BUTTON_REPEAT)
342#define BJACK_STAY BUTTON_FFWD
343#define BJACK_DOUBLEDOWN (BUTTON_REW|BUTTON_REL)
344#define BJACK_UP BUTTON_UP
345#define BJACK_DOWN BUTTON_DOWN
346#define BJACK_RIGHT BUTTON_RIGHT
347#define BJACK_LEFT BUTTON_LEFT
348
349#elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
350#define BJACK_SELECT_NAME "OK"
351#define BJACK_STAY_NAME "CANCEL"
352#define BJACK_QUIT_NAME "REC"
353#define BJACK_DOUBLE_NAME "MENU"
354#define BJACK_SELECT BUTTON_OK
355#define BJACK_QUIT BUTTON_REC
356#define BJACK_STAY BUTTON_CANCEL
357#define BJACK_DOUBLEDOWN BUTTON_MENU
358#define BJACK_UP BUTTON_UP
359#define BJACK_DOWN BUTTON_DOWN
360#define BJACK_RIGHT BUTTON_NEXT
361#define BJACK_LEFT BUTTON_PREV
362
363#elif CONFIG_KEYPAD == MPIO_HD200_PAD
364#define BJACK_SELECT_NAME "FUNC"
365#define BJACK_STAY_NAME "VOL +"
366#define BJACK_RESUME_NAME "PLAY"
367#define BJACK_QUIT_NAME "REC+PLAY"
368#define BJACK_DOUBLE_NAME "VOL -"
369#define BJACK_SELECT BUTTON_FUNC
370#define BJACK_QUIT (BUTTON_REC|BUTTON_PLAY)
371#define BJACK_STAY BUTTON_VOL_UP
372#define BJACK_DOUBLEDOWN BUTTON_VOL_DOWN
373#define BJACK_UP BUTTON_REW
374#define BJACK_DOWN BUTTON_FF
375#define BJACK_RIGHT BUTTON_VOL_UP
376#define BJACK_LEFT BUTTON_VOL_DOWN
377
378#elif CONFIG_KEYPAD == MPIO_HD300_PAD
379#define BJACK_SELECT_NAME "ENTER"
380#define BJACK_STAY_NAME "PLAY"
381#define BJACK_RESUME_NAME ""
382#define BJACK_QUIT_NAME "Long MENU"
383#define BJACK_DOUBLE_NAME "REC"
384#define BJACK_SELECT BUTTON_ENTER
385#define BJACK_QUIT (BUTTON_MENU|BUTTON_REPEAT)
386#define BJACK_STAY BUTTON_PLAY
387#define BJACK_DOUBLEDOWN BUTTON_REC
388#define BJACK_UP BUTTON_UP
389#define BJACK_DOWN BUTTON_DOWN
390#define BJACK_RIGHT BUTTON_FF
391#define BJACK_LEFT BUTTON_REW
392
393#elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
394#define BJACK_SELECT_NAME "SELECT"
395#define BJACK_STAY_NAME "PLAYPAUSE"
396#define BJACK_RESUME_NAME ""
397#define BJACK_QUIT_NAME "POWER"
398#define BJACK_DOUBLE_NAME "BACK"
399#define BJACK_SELECT BUTTON_SELECT
400#define BJACK_QUIT BUTTON_POWER
401#define BJACK_MAX BUTTON_BOTTOMRIGHT
402#define BJACK_MIN BUTTON_BOTTOMLEFT
403#define BJACK_STAY BUTTON_BACK
404#define BJACK_DOUBLEDOWN BUTTON_PLAYPAUSE
405#define BJACK_UP BUTTON_UP
406#define BJACK_DOWN BUTTON_DOWN
407#define BJACK_RIGHT BUTTON_RIGHT
408#define BJACK_LEFT BUTTON_LEFT
409
410#elif CONFIG_KEYPAD == SAMSUNG_YPR0_PAD
411#define BJACK_SELECT_NAME "SELECT"
412#define BJACK_STAY_NAME "MENU"
413#define BJACK_QUIT_NAME "BACK"
414#define BJACK_DOUBLE_NAME "USER"
415#define BJACK_SELECT BUTTON_SELECT
416#define BJACK_QUIT BUTTON_BACK
417#define BJACK_MAX (BUTTON_LEFT|BUTTON_UP)
418#define BJACK_MIN (BUTTON_RIGHT|BUTTON_DOWN)
419#define BJACK_STAY BUTTON_MENU
420#define BJACK_DOUBLEDOWN BUTTON_USER
421#define BJACK_UP BUTTON_UP
422#define BJACK_DOWN BUTTON_DOWN
423#define BJACK_RIGHT BUTTON_RIGHT
424#define BJACK_LEFT BUTTON_LEFT
425
426#elif CONFIG_KEYPAD == HM60X_PAD
427#define BJACK_SELECT_NAME "SELECT"
428#define BJACK_STAY_NAME "UP+POWER"
429#define BJACK_QUIT_NAME "POWER"
430#define BJACK_DOUBLE_NAME "DOWN+POWER"
431#define BJACK_SELECT BUTTON_SELECT
432#define BJACK_QUIT BUTTON_POWER
433#define BJACK_STAY (BUTTON_UP|BUTTON_POWER)
434#define BJACK_DOUBLEDOWN (BUTTON_DOWN|BUTTON_POWER)
435#define BJACK_UP BUTTON_UP
436#define BJACK_DOWN BUTTON_DOWN
437#define BJACK_RIGHT BUTTON_RIGHT
438#define BJACK_LEFT BUTTON_LEFT
439
440#elif CONFIG_KEYPAD == HM801_PAD
441#define BJACK_SELECT_NAME "SELECT"
442#define BJACK_STAY_NAME "PLAY"
443#define BJACK_QUIT_NAME "POWER"
444#define BJACK_DOUBLE_NAME "PREV"
445#define BJACK_SELECT BUTTON_SELECT
446#define BJACK_QUIT BUTTON_POWER
447#define BJACK_STAY BUTTON_PLAY
448#define BJACK_DOUBLEDOWN BUTTON_PREV
449#define BJACK_UP BUTTON_UP
450#define BJACK_DOWN BUTTON_DOWN
451#define BJACK_RIGHT BUTTON_RIGHT
452#define BJACK_LEFT BUTTON_LEFT
453
454#elif CONFIG_KEYPAD == SONY_NWZ_PAD
455#define BJACK_SELECT BUTTON_PLAY
456#define BJACK_QUIT BUTTON_BACK
457#define BJACK_STAY (BUTTON_POWER|BUTTON_PLAY)
458#define BJACK_DOUBLEDOWN (BUTTON_POWER|BUTTON_DOWN)
459#define BJACK_UP BUTTON_UP
460#define BJACK_DOWN BUTTON_DOWN
461#define BJACK_RIGHT BUTTON_RIGHT
462#define BJACK_LEFT BUTTON_LEFT
463#define BJACK_SELECT_NAME "Play"
464#define BJACK_STAY_NAME "Option+Play"
465#define BJACK_QUIT_NAME "Back"
466#define BJACK_DOUBLE_NAME "Option+Down"
467
468#elif CONFIG_KEYPAD == CREATIVE_ZEN_PAD
469#define BJACK_SELECT BUTTON_SELECT
470#define BJACK_QUIT BUTTON_BACK
471#define BJACK_STAY BUTTON_PLAYPAUSE
472#define BJACK_DOUBLEDOWN BUTTON_SHORTCUT
473#define BJACK_UP BUTTON_UP
474#define BJACK_DOWN BUTTON_DOWN
475#define BJACK_RIGHT BUTTON_RIGHT
476#define BJACK_LEFT BUTTON_LEFT
477#define BJACK_SELECT_NAME "Select"
478#define BJACK_STAY_NAME "Play/Pause"
479#define BJACK_QUIT_NAME "Back"
480#define BJACK_DOUBLE_NAME "Shortcut"
481
482#elif CONFIG_KEYPAD == DX50_PAD
483#define BJACK_QUIT BUTTON_POWER
484#define BJACK_DOUBLEDOWN BUTTON_RIGHT
485#define BJACK_SELECT BUTTON_PLAY
486#define BJACK_QUIT BUTTON_POWER
487#define BJACK_STAY BUTTON_LEFT
488#define BJACK_UP BUTTON_VOL_UP
489#define BJACK_DOWN BUTTON_VOL_DOWN
490#define BJACK_LEFT BUTTON_LEFT
491#define BJACK_SELECT_NAME "Play"
492#define BJACK_STAY_NAME "Left"
493#define BJACK_QUIT_NAME "Power"
494#define BJACK_DOUBLE_NAME "Right"
495
496#elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD
497#define BJACK_QUIT BUTTON_POWER
498#define BJACK_QUIT_NAME "Power"
499
500#elif CONFIG_KEYPAD == AGPTEK_ROCKER_PAD
501#define BJACK_SELECT BUTTON_SELECT
502#define BJACK_QUIT BUTTON_POWER
503#define BJACK_STAY (BUTTON_VOLUP|BUTTON_SELECT)
504#define BJACK_DOUBLEDOWN (BUTTON_VOLUP|BUTTON_DOWN)
505#define BJACK_UP BUTTON_UP
506#define BJACK_DOWN BUTTON_DOWN
507#define BJACK_RIGHT BUTTON_RIGHT
508#define BJACK_LEFT BUTTON_LEFT
509#define BJACK_SELECT_NAME "Select"
510#define BJACK_STAY_NAME "Option+Select"
511#define BJACK_QUIT_NAME "Volume up"
512#define BJACK_DOUBLE_NAME "Option+Down"
513
514#elif CONFIG_KEYPAD == XDUOO_X3_PAD || CONFIG_KEYPAD == XDUOO_X3II_PAD || CONFIG_KEYPAD == XDUOO_X20_PAD
515#define BJACK_SELECT_NAME "PLAY"
516#define BJACK_STAY_NAME "NEXT"
517#define BJACK_QUIT_NAME "POWER"
518#define BJACK_DOUBLE_NAME "PREV"
519#define BJACK_SELECT BUTTON_PLAY
520#define BJACK_QUIT BUTTON_POWER
521#define BJACK_MAX BUTTON_VOL_UP
522#define BJACK_MIN BUTTON_VOL_DOWN
523#define BJACK_STAY BUTTON_NEXT
524#define BJACK_DOUBLEDOWN BUTTON_PREV
525#define BJACK_UP BUTTON_HOME
526#define BJACK_DOWN BUTTON_OPTION
527#define BJACK_RIGHT BUTTON_NEXT
528#define BJACK_LEFT BUTTON_PREV
529
530#elif CONFIG_KEYPAD == FIIO_M3K_LINUX_PAD
531#define BJACK_SELECT_NAME "PLAY"
532#define BJACK_STAY_NAME "NEXT"
533#define BJACK_QUIT_NAME "POWER"
534#define BJACK_DOUBLE_NAME "PREV"
535#define BJACK_SELECT BUTTON_PLAY
536#define BJACK_QUIT BUTTON_POWER
537#define BJACK_MAX BUTTON_VOL_UP
538#define BJACK_MIN BUTTON_VOL_DOWN
539#define BJACK_STAY BUTTON_NEXT
540#define BJACK_DOUBLEDOWN BUTTON_PREV
541#define BJACK_UP BUTTON_HOME
542#define BJACK_DOWN BUTTON_OPTION
543#define BJACK_RIGHT BUTTON_NEXT
544#define BJACK_LEFT BUTTON_PREV
545
546#elif CONFIG_KEYPAD == IHIFI_770_PAD || CONFIG_KEYPAD == IHIFI_800_PAD
547#define BJACK_SELECT_NAME "PLAY"
548#define BJACK_STAY_NAME "NEXT"
549#define BJACK_QUIT_NAME "POWER"
550#define BJACK_DOUBLE_NAME "PREV"
551#define BJACK_SELECT BUTTON_PLAY
552#define BJACK_QUIT BUTTON_POWER
553#define BJACK_MAX BUTTON_VOL_UP
554#define BJACK_MIN BUTTON_VOL_DOWN
555#define BJACK_STAY BUTTON_NEXT
556#define BJACK_DOUBLEDOWN BUTTON_PREV
557#define BJACK_UP BUTTON_HOME
558#define BJACK_DOWN (BUTTON_POWER | BUTTON_HOME)
559#define BJACK_RIGHT BUTTON_NEXT
560#define BJACK_LEFT BUTTON_PREV
561
562#elif CONFIG_KEYPAD == EROSQ_PAD
563#define BJACK_SELECT_NAME "PLAY"
564#define BJACK_STAY_NAME "NEXT"
565#define BJACK_QUIT_NAME "POWER"
566#define BJACK_DOUBLE_NAME "PREV"
567#define BJACK_SELECT BUTTON_PLAY
568#define BJACK_QUIT BUTTON_POWER
569#define BJACK_MAX BUTTON_VOL_UP
570#define BJACK_MIN BUTTON_VOL_DOWN
571#define BJACK_STAY BUTTON_MENU
572#define BJACK_DOUBLEDOWN BUTTON_BACK
573#define BJACK_UP BUTTON_PREV
574#define BJACK_DOWN BUTTON_NEXT
575#define BJACK_RIGHT BUTTON_SCROLL_FWD
576#define BJACK_LEFT BUTTON_SCROLL_BACK
577
578#elif CONFIG_KEYPAD == FIIO_M3K_PAD
579#define BJACK_SELECT_NAME "SELECT"
580#define BJACK_STAY_NAME "PLAY"
581#define BJACK_QUIT_NAME "POWER"
582#define BJACK_DOUBLE_NAME "MENU"
583#define BJACK_SELECT BUTTON_SELECT
584#define BJACK_QUIT BUTTON_POWER
585#define BJACK_MAX BUTTON_VOL_UP
586#define BJACK_MIN BUTTON_VOL_DOWN
587#define BJACK_STAY BUTTON_PLAY
588#define BJACK_DOUBLEDOWN BUTTON_MENU
589#define BJACK_UP BUTTON_UP
590#define BJACK_DOWN BUTTON_DOWN
591#define BJACK_RIGHT BUTTON_RIGHT
592#define BJACK_LEFT BUTTON_LEFT
593
594#elif CONFIG_KEYPAD == MA_PAD
595#define BJACK_SELECT_NAME "PLAY"
596#define BJACK_STAY_NAME "BACK"
597#define BJACK_QUIT_NAME "BACK+MENU"
598#define BJACK_DOUBLE_NAME "MENU"
599#define BJACK_SELECT BUTTON_PLAY
600#define BJACK_QUIT (BUTTON_BACK|BUTTON_MENU)
601#define BJACK_MAX (BUTTON_UP|BUTTON_MENU)
602#define BJACK_MIN (BUTTON_DOWN|BUTTON_MENU)
603#define BJACK_STAY BUTTON_BACK
604#define BJACK_DOUBLEDOWN BUTTON_MENU
605#define BJACK_UP BUTTON_UP
606#define BJACK_DOWN BUTTON_DOWN
607#define BJACK_RIGHT BUTTON_RIGHT
608#define BJACK_LEFT BUTTON_LEFT
609
610
611#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
612#define BJACK_QUIT BUTTON_POWER
613#define BJACK_QUIT_NAME "QUIT"
614
615#elif CONFIG_KEYPAD == RG_NANO_PAD
616#define BJACK_SELECT_NAME "A"
617#define BJACK_STAY_NAME "Y"
618#define BJACK_QUIT_NAME "START"
619#define BJACK_DOUBLE_NAME "R"
620#define BJACK_SELECT BUTTON_A
621#define BJACK_QUIT BUTTON_START
622#define BJACK_MAX BUTTON_X
623#define BJACK_MIN BUTTON_B
624#define BJACK_STAY BUTTON_Y
625#define BJACK_DOUBLEDOWN BUTTON_R
626#define BJACK_UP BUTTON_UP
627#define BJACK_DOWN BUTTON_DOWN
628#define BJACK_RIGHT BUTTON_RIGHT
629#define BJACK_LEFT BUTTON_LEFT
630
631#else
632#error No keymap defined!
633#endif
634
635#ifdef HAVE_TOUCHSCREEN
636#ifndef BJACK_DOUBLEDOWN
637#define BJACK_DOUBLEDOWN BUTTON_MIDLEFT
638#define BJACK_DOUBLE_NAME "BUTTON_MIDLEFT"
639#endif
640#ifndef BJACK_SELECT
641#define BJACK_SELECT BUTTON_CENTER
642#define BJACK_SELECT_NAME "BUTTON_CENTER"
643#endif
644#ifndef BJACK_MAX
645#define BJACK_MAX BUTTON_TOPRIGHT
646#endif
647#ifndef BJACK_MIN
648#define BJACK_MIN BUTTON_TOPLEFT
649#endif
650#ifndef BJACK_STAY
651#define BJACK_STAY BUTTON_BOTTOMLEFT
652#define BJACK_STAY_NAME "BUTTON_BOTTOMLEFT"
653#endif
654#ifndef BJACK_UP
655#define BJACK_UP BUTTON_TOPMIDDLE
656#endif
657#ifndef BJACK_DOWN
658#define BJACK_DOWN BUTTON_BOTTOMMIDDLE
659#endif
660#ifndef BJACK_RIGHT
661#define BJACK_RIGHT BUTTON_MIDRIGHT
662#endif
663#ifndef BJACK_LEFT
664#define BJACK_LEFT BUTTON_MIDLEFT
665#endif
666
667#endif
668
669#ifdef HAVE_LCD_COLOR
670#define BG_COLOR LCD_RGBPACK(0,157,0)
671#define FG_COLOR LCD_WHITE
672#elif LCD_DEPTH > 1
673#define BG_COLOR LCD_WHITE
674#define FG_COLOR LCD_BLACK
675#endif
676
677#define CARD_WIDTH BMPWIDTH_card_back
678#define CARD_HEIGHT BMPHEIGHT_card_back
679
680/* This is the max amount of cards onscreen before condensing */
681#define MAX_CARDS LCD_WIDTH/(CARD_WIDTH+4)
682
683extern const fb_data card_deck[];
684extern const fb_data card_back[];
685
686#define NEXT_CARD bj->player_cards[done][bj->num_player_cards[done]]
687
688/* dealer and player card positions */
689unsigned int dealer_x, dealer_y, player_x, player_y;
690
691typedef struct card {
692 unsigned int value; /* Card's value in Blackjack */
693 unsigned int num; /* Value on card face 0-12 (0=Ace, 1=2, 11=Q) */
694 unsigned int suit; /* 0:Spades, 1:Hearts, 2: Clubs; 3: Diamonds */
695 bool is_soft_ace;
696} card;
697
698typedef struct game_context {
699 struct card player_cards[2][22]; /* 22 Cards means the deal was all aces */
700 struct card dealer_cards[22]; /* That is the worst-case scenario */
701 unsigned int player_total;
702 unsigned int dealer_total;
703 signed int player_money;
704 unsigned int num_player_cards[2];
705 unsigned int num_dealer_cards;
706 unsigned int current_bet;
707 unsigned int split_status; /* 0 = split hasn't been asked, *
708 * 1 = split did not occur *
709 * 2 = split occurred *
710 * 3 = split occurred and 1st hand done */
711 bool is_blackjack;
712 bool end_hand;
713 bool asked_insurance;
714} game_context;
715
716static bool resume = false;
717static bool resume_file = false;
718static struct highscore highscores[NUM_SCORES];
719
720/*****************************************************************************
721* blackjack_init() initializes blackjack data structures.
722******************************************************************************/
723static void blackjack_init(struct game_context* bj) {
724 /* seed the rand generator */
725 rb->srand(*rb->current_tick);
726
727 /* reset card positions */
728 dealer_x = 4;
729 dealer_y = LCD_HEIGHT/4 - CARD_HEIGHT/2;
730 player_x = 4;
731 player_y = LCD_HEIGHT - LCD_HEIGHT/4 - CARD_HEIGHT/2;
732
733 /* check for resumed game */
734 if(resume) return;
735
736 /* reset scoring */
737 bj->player_total = 0;
738 bj->dealer_total = 0;
739 bj->num_player_cards[0] = 2;
740 bj->num_player_cards[1] = 0;
741 bj->num_dealer_cards = 2;
742 bj->end_hand = false;
743 bj->split_status = 0;
744 bj->is_blackjack = false;
745 bj->asked_insurance = false;
746}
747
748/*****************************************************************************
749* blackjack_drawtable() draws the table and some text.
750******************************************************************************/
751static void blackjack_drawtable(struct game_context* bj) {
752 unsigned int w, h, y_loc;
753 char str[10];
754
755#if LCD_HEIGHT <= 64 || LCD_WIDTH <= 96
756 rb->lcd_getstringsize("Bet", &w, &h);
757 rb->lcd_putsxy(LCD_WIDTH - w, 2*h + 1, "Bet");
758 rb->snprintf(str, 9, "$%d", bj->current_bet);
759 rb->lcd_getstringsize(str, &w, &h);
760 rb->lcd_putsxy(LCD_WIDTH - w, 3*h + 1, str);
761 y_loc = LCD_HEIGHT/2;
762#else
763 rb->lcd_getstringsize("Bet", &w, &h);
764 rb->lcd_putsxy(LCD_WIDTH - w, 5*h / 2, "Bet");
765 rb->snprintf(str, 9, "$%d", bj->current_bet);
766 rb->lcd_getstringsize(str, &w, &h);
767 rb->lcd_putsxy(LCD_WIDTH - w, 7*h / 2, str);
768 rb->lcd_hline(0, LCD_WIDTH, LCD_HEIGHT/2);
769 y_loc = LCD_HEIGHT/2 + h;
770#endif
771
772 rb->lcd_putsxy(0,0, "Dealer");
773 rb->lcd_getstringsize("Player", &w, &h);
774 rb->lcd_putsxy(0, y_loc, "Player");
775 rb->lcd_getstringsize("Total", &w, &h);
776 rb->lcd_putsxy(LCD_WIDTH - w, y_loc, "Total");
777 rb->lcd_getstringsize("Money", &w, &h);
778 rb->lcd_putsxy(LCD_WIDTH - w, 0, "Money");
779 rb->snprintf(str, 9, "$%d", bj->player_money - bj->current_bet);
780 rb->lcd_getstringsize(str, &w, &h);
781 rb->lcd_putsxy(LCD_WIDTH - w, h + 1, str);
782 rb->snprintf(str, 3, "%d", bj->player_total);
783 rb->lcd_getstringsize(str, &w, &h);
784 rb->lcd_putsxy(LCD_WIDTH - w, y_loc + h, str);
785}
786
787/*****************************************************************************
788* find_value() is passed a card and returns its blackjack value.
789******************************************************************************/
790static unsigned int find_value(unsigned int number) {
791 unsigned int thisValue;
792 if (number == 0)
793 thisValue = 11; /* Aces get a value of 11 at first */
794 else if (number < 10)
795 thisValue = number + 1;
796 else
797 thisValue = 10; /* Anything 10 or higher gets a value of 10 */
798
799 return thisValue;
800}
801
802/*****************************************************************************
803* draw_card() draws a card to the screen.
804******************************************************************************/
805static void draw_card(struct card temp_card, bool shown,
806 unsigned int x, unsigned int y) {
807 if(shown)
808 rb->lcd_bitmap_part(card_deck, CARD_WIDTH*temp_card.num,
809 CARD_HEIGHT*temp_card.suit,
810 STRIDE( SCREEN_MAIN, BMPWIDTH_card_deck,
811 BMPHEIGHT_card_deck),
812 x+1, y+1, CARD_WIDTH, CARD_HEIGHT);
813 else
814 rb->lcd_bitmap(card_back, x+1, y+1,CARD_WIDTH, CARD_HEIGHT);
815#if LCD_DEPTH > 1
816 rb->lcd_set_foreground(LCD_BLACK);
817#endif
818
819 /* Print outlines */
820#if CARD_WIDTH >= 26
821 rb->lcd_hline(x+2, x+CARD_WIDTH-1, y);
822 rb->lcd_hline(x+2, x+CARD_WIDTH-1, y+CARD_HEIGHT+1);
823 rb->lcd_vline(x, y+2, y+CARD_HEIGHT-3);
824 rb->lcd_vline(x+CARD_WIDTH+1, y+2, y+CARD_HEIGHT-1);
825 rb->lcd_drawpixel(x+1, y+1);
826 rb->lcd_drawpixel(x+1, y+CARD_HEIGHT);
827 rb->lcd_drawpixel(x+CARD_WIDTH, y+1);
828 rb->lcd_drawpixel(x+CARD_WIDTH, y+CARD_HEIGHT);
829#else
830 rb->lcd_hline(x+1, x+CARD_WIDTH, y);
831 rb->lcd_hline(x+1, x+CARD_WIDTH, y+CARD_HEIGHT+1);
832 rb->lcd_vline(x, y+1, y+CARD_HEIGHT);
833 rb->lcd_vline(x+CARD_WIDTH+1, y+1, y+CARD_HEIGHT);
834#endif
835
836#if LCD_DEPTH > 1
837 rb->lcd_set_foreground(FG_COLOR);
838#endif
839}
840
841/*****************************************************************************
842* new_card() initializes a new card and gives it values.
843******************************************************************************/
844static struct card new_card(void) {
845 struct card new_card;
846 new_card.suit = rb->rand()%4; /* Random number 0-3 */
847 new_card.num = rb->rand()%13; /* Random number 0-12 */
848 new_card.value = find_value(new_card.num);
849 new_card.is_soft_ace = (new_card.num == 0);
850 return new_card;
851}
852
853/*****************************************************************************
854* deal_init_card() deals and draws to the screen the player's and dealer's
855* initial cards.
856******************************************************************************/
857static void deal_init_cards(struct game_context* bj) {
858 bj->dealer_cards[0] = new_card();
859 bj->dealer_total += bj->dealer_cards[0].value;
860
861 draw_card(bj->dealer_cards[0], false, dealer_x, dealer_y);
862
863 bj->dealer_cards[1] = new_card();
864 bj->dealer_total += bj->dealer_cards[1].value;
865 draw_card(bj->dealer_cards[1], true, dealer_x + CARD_WIDTH + 4, dealer_y);
866
867 bj->player_cards[0][0] = new_card();
868 bj->player_total += bj->player_cards[0][0].value;
869 draw_card(bj->player_cards[0][0], true, player_x, player_y);
870 player_x += CARD_WIDTH + 4;
871
872 bj->player_cards[0][1] = new_card();
873 bj->player_total += bj->player_cards[0][1].value;
874 draw_card(bj->player_cards[0][1], true, player_x, player_y);
875 player_x += CARD_WIDTH + 4;
876}
877
878/*****************************************************************************
879* redraw_board() redraws all the cards and the board
880******************************************************************************/
881static void redraw_board(struct game_context* bj) {
882 unsigned int i, n, upper_bound;
883 rb->lcd_clear_display();
884
885 blackjack_drawtable(bj);
886 player_x = 4;
887 dealer_x = 4;
888 upper_bound = bj->split_status > 1 ? 2 : 1;
889
890 for (i = 0; i < bj->num_dealer_cards; i++) {
891 if (!bj->end_hand) {
892 draw_card(bj->dealer_cards[0], false, dealer_x, dealer_y);
893
894 /* increment i so the dealer's first card isn't displayed */
895 i++;
896 dealer_x += CARD_WIDTH + 4;
897 }
898 draw_card(bj->dealer_cards[i], true, dealer_x, dealer_y);
899
900 if (bj->num_dealer_cards > MAX_CARDS-1)
901 dealer_x += 10;
902 else
903 dealer_x += CARD_WIDTH + 4;
904 }
905
906 for (n = 0; n < upper_bound; n++) {
907 for (i = 0; i < bj->num_player_cards[n]; i++) {
908 draw_card(bj->player_cards[n][i], true, player_x, player_y);
909 if (bj->split_status>1 || bj->num_player_cards[n]>MAX_CARDS)
910 player_x += 10;
911 else
912 player_x += CARD_WIDTH + 4;
913 }
914 if (bj->split_status > 1)
915 player_x = LCD_WIDTH/2 + 4;
916 }
917}
918
919/*****************************************************************************
920* update_total updates the player's total
921******************************************************************************/
922static void update_total(struct game_context* bj) {
923 char total[3];
924 unsigned int w, h;
925 rb->snprintf(total, 3, "%d", bj->player_total);
926 rb->lcd_getstringsize(total, &w, &h);
927#if LCD_HEIGHT > 64 && LCD_WIDTH > 96
928 h *= 2;
929#endif
930 rb->lcd_putsxy(LCD_WIDTH - w, LCD_HEIGHT/2 + h, total);
931 rb->lcd_update_rect(LCD_WIDTH - w, LCD_HEIGHT/2 + h, w, h);
932}
933
934
935/*****************************************************************************
936* check_for_aces() is passed an array of cards and returns where an ace is
937* located. Otherwise, returns -1.
938******************************************************************************/
939static signed int check_for_aces(struct card temp_cards[], unsigned int size) {
940 unsigned int i;
941 for(i = 0; i < size; i++) {
942 if (temp_cards[i].is_soft_ace)
943 return i;
944 }
945 return -1;
946}
947
948/*****************************************************************************
949* check_totals() compares player and dealer totals.
950* 0: bust 1: loss, 2: push, 3: win, 4: blackjack, 5: something's not right...
951******************************************************************************/
952static unsigned int check_totals(struct game_context* bj) {
953 unsigned int temp;
954 if (bj->player_total > 21)
955 temp = 0;
956 else if (bj->player_total == 21 && bj->is_blackjack) {
957 if (bj->dealer_total == 21 && bj->num_dealer_cards == 2)
958 temp = 2;
959 else
960 temp = 4;
961 }
962 else if (bj->player_total == bj->dealer_total)
963 temp = 2;
964 else if (bj->dealer_total > 21 && bj->player_total < 22)
965 temp = 3;
966 else if (bj->dealer_total > bj->player_total)
967 temp = 1;
968 else if (bj->player_total > bj->dealer_total)
969 temp = 3;
970 else
971 temp = 5;
972
973 return temp;
974}
975
976/*****************************************************************************
977* finish_dealer() draws cards for the dealer until he has 17 or more.
978******************************************************************************/
979static void finish_dealer(struct game_context* bj) {
980 signed int temp = 0;
981
982 if (bj->dealer_total > 16 && bj->dealer_total < 22)
983 return;
984
985 while (bj->dealer_total < 17) {
986 bj->dealer_cards[bj->num_dealer_cards] = new_card();
987 bj->dealer_total += bj->dealer_cards[bj->num_dealer_cards].value;
988 bj->num_dealer_cards++;
989 }
990
991 while (bj->dealer_total > 21) {
992 temp = check_for_aces(bj->dealer_cards, bj->num_dealer_cards);
993 if(temp != -1) {
994 bj->dealer_cards[temp].is_soft_ace = false;
995 bj->dealer_total -= 10;
996 }
997 else
998 return;
999 }
1000}
1001
1002/*****************************************************************************
1003* finish_game() completes the game once player's turn is over.
1004******************************************************************************/
1005static void finish_game(struct game_context* bj) {
1006 unsigned int rValue, w, h;
1007 char str[19];
1008
1009 do {
1010 finish_dealer(bj);
1011 } while (bj->dealer_total < 17);
1012
1013 redraw_board(bj);
1014 rValue = check_totals(bj);
1015
1016 if (rValue == 0) {
1017 rb->snprintf(str, sizeof(str), " Bust! ");
1018 bj->player_money -= bj->current_bet;
1019 }
1020 else if (rValue == 1) {
1021 rb->snprintf(str, sizeof(str), " Sorry, you lost. ");
1022 bj->player_money -= bj->current_bet;
1023 }
1024 else if (rValue == 2) {
1025 rb->snprintf(str, sizeof(str), " Push ");
1026 }
1027 else if (rValue == 3) {
1028 rb->snprintf(str, sizeof(str), " You won! ");
1029 bj->player_money+= bj->current_bet;
1030 }
1031 else {
1032 rb->snprintf(str, sizeof(str), " Blackjack! ");
1033 bj->player_money += bj->current_bet * 3 / 2;
1034 }
1035 rb->lcd_getstringsize(str, &w, &h);
1036
1037#if LCD_HEIGHT <= 64 || LCD_WIDTH <= 96
1038 rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID);
1039 rb->lcd_fillrect(0, LCD_HEIGHT/2, LCD_WIDTH, LCD_HEIGHT/2);
1040 rb->lcd_set_drawmode(DRMODE_SOLID);
1041 rb->lcd_putsxy(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + h, str);
1042 rb->snprintf(str, 12, "You have %d", bj->player_total);
1043 rb->lcd_getstringsize(str, &w, &h);
1044 rb->lcd_putsxy(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2, str);
1045#else
1046 rb->lcd_putsxy(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 - h/2, str);
1047#endif
1048 rb->lcd_update();
1049}
1050
1051/*****************************************************************************
1052* blackjack_loadgame() loads the saved game and returns load success.
1053******************************************************************************/
1054static bool blackjack_loadgame(struct game_context* bj) {
1055 signed int fd;
1056 bool loaded = false;
1057
1058 /* open game file */
1059 fd = rb->open(SAVE_FILE, O_RDONLY);
1060 if(fd < 0) return false;
1061
1062 /* read in saved game */
1063 if(rb->read(fd, bj, sizeof(struct game_context))
1064 == (long)sizeof(struct game_context))
1065 {
1066 loaded = true;
1067 }
1068
1069 rb->close(fd);
1070
1071 return loaded;
1072}
1073
1074/*****************************************************************************
1075* blackjack_savegame() saves the current game state.
1076******************************************************************************/
1077static void blackjack_savegame(struct game_context* bj) {
1078 int fd;
1079
1080 if(!resume)
1081 return;
1082 /* write out the game state to the save file */
1083 fd = rb->open(SAVE_FILE, O_WRONLY|O_CREAT, 0666);
1084 if(fd < 0)
1085 return;
1086 rb->write(fd, bj, sizeof(struct game_context));
1087 rb->close(fd);
1088}
1089
1090/*****************************************************************************
1091* blackjack_get_yes_no() gets a yes/no answer from the user
1092******************************************************************************/
1093static unsigned int blackjack_get_yes_no(const char *message) {
1094 int button;
1095 unsigned int w, h, b, choice = 0;
1096 bool breakout = false;
1097 char message_yes[24], message_no[24];
1098
1099 rb->strcpy(message_yes, message);
1100 rb->strcpy(message_no, message);
1101 rb->strcat(message_yes, " Yes");
1102 rb->strcat(message_no, " No");
1103 rb->lcd_getstringsize(message_yes, &w, &h);
1104 const char *stg[] = {message_yes, message_no};
1105
1106#if LCD_HEIGHT <= 64 || LCD_WIDTH <= 96
1107 b = 2*h+1;
1108#else
1109 b = h-1;
1110#endif
1111
1112#ifdef HAVE_LCD_COLOR
1113 rb->lcd_fillrect(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + b, w+1, h+3);
1114 rb->lcd_set_foreground(LCD_BLACK);
1115 rb->lcd_set_background(LCD_WHITE);
1116#else
1117 rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID);
1118 rb->lcd_fillrect(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + b, w+1, h+3);
1119 rb->lcd_set_drawmode(DRMODE_SOLID);
1120#endif
1121 rb->lcd_drawrect(LCD_WIDTH/2 - w/2 - 1, LCD_HEIGHT/2 + b - 1, w+3, h+4);
1122
1123 while(!breakout) {
1124 rb->lcd_putsxy(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + b +1, stg[choice]);
1125 rb->lcd_update_rect(LCD_WIDTH/2 - w/2 - 1, LCD_HEIGHT/2 + b -1,
1126 w+3, h+4);
1127 button = rb->button_get(true);
1128
1129 switch(button) {
1130 case BJACK_LEFT:
1131 case (BJACK_LEFT|BUTTON_REPEAT):
1132 case BJACK_RIGHT:
1133 case (BJACK_RIGHT|BUTTON_REPEAT):
1134 choice ^= 1;
1135 break;
1136 case BJACK_SELECT: breakout = true;
1137 break;
1138 case BJACK_QUIT: breakout = true;
1139 choice = 1;
1140 break;
1141 }
1142 }
1143
1144#if LCD_DEPTH > 1
1145 rb->lcd_set_foreground(FG_COLOR);
1146 rb->lcd_set_background(BG_COLOR);
1147#endif
1148 return choice;
1149}
1150
1151/*****************************************************************************
1152* blackjack_get_amount() gets an amount from the player to be used
1153******************************************************************************/
1154static signed int blackjack_get_amount(const char *message,
1155 signed int lower_limit,
1156 signed int upper_limit,
1157 signed int start) {
1158 int button;
1159 bool breakout = false, changed = false;
1160 unsigned int w, h;
1161 signed int amount;
1162
1163 rb->lcd_getstringsize("A", &w, &h); /* find the size of one character */
1164
1165 if (start > upper_limit)
1166 amount = upper_limit;
1167 else if (start < lower_limit)
1168 amount = lower_limit;
1169 else
1170 amount = start;
1171
1172#if LCD_DEPTH > 1
1173 rb->lcd_set_background(LCD_WHITE);
1174 rb->lcd_set_foreground(LCD_BLACK);
1175#endif
1176
1177#if LCD_HEIGHT <= 64 || LCD_WIDTH <= 96
1178 rb->lcd_clear_display();
1179 rb->lcd_puts(0, 1, message);
1180 rb->lcd_putsf(0, 2, "$%d", amount);
1181 rb->lcd_puts(0, 3, "RIGHT: +1");
1182 rb->lcd_puts(0, 4, "LEFT: -1");
1183 rb->lcd_puts(0, 5, "UP: +10");
1184 rb->lcd_puts(0, 6, "DOWN: -10");
1185 rb->lcd_update();
1186#else
1187 rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID);
1188 rb->lcd_fillrect(LCD_WIDTH/2 - 9*w - 1, LCD_HEIGHT/2 - 4*h - 3,
1189 37*w / 2, 8*h -3);
1190 rb->lcd_set_drawmode(DRMODE_SOLID);
1191 rb->lcd_drawrect(LCD_WIDTH/2 - 9*w - 1, LCD_HEIGHT/2 - 4*h - 3,
1192 37*w / 2, 8*h -3);
1193 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 4*h - 1, message);
1194 rb->lcd_putsxyf(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, "$%d", amount);
1195#if (CONFIG_KEYPAD == IPOD_4G_PAD) || \
1196 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
1197 (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
1198 (CONFIG_KEYPAD == SANSA_E200_PAD) || \
1199 (CONFIG_KEYPAD == SANSA_FUZE_PAD) || \
1200 (CONFIG_KEYPAD == SANSA_CONNECT_PAD) || \
1201 (CONFIG_KEYPAD == MPIO_HD300_PAD)
1202 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - h-2, " >>|: +1");
1203 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 1, " |<<: -1");
1204 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + h, "SCROLL+: +10");
1205 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + 2*h + 1, "SCROLL-: -10");
1206#elif CONFIG_KEYPAD == IRIVER_H10_PAD
1207 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - h-2, "RIGHT: +1");
1208 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 1, "LEFT: -1");
1209 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + h, "SCROLL+: +10");
1210 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + 2*h + 1, "SCROLL-: -10");
1211#else
1212 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - h-2, "RIGHT: +1");
1213 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 1, "LEFT: -1");
1214 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + h, "UP: +10");
1215 rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + 2*h + 1, "DOWN: -10");
1216#endif
1217 rb->lcd_update_rect(LCD_WIDTH/2 - 9*w - 1, LCD_HEIGHT/2 - 4*h - 3,
1218 37*w / 2, 8*h -3);
1219#endif
1220
1221 while(!breakout) {
1222 button = rb->button_get(true);
1223
1224 switch(button) {
1225 case BJACK_UP:
1226 case (BJACK_UP|BUTTON_REPEAT):
1227 if (amount + 10 < upper_limit + 1) {
1228 amount += 10;
1229 changed = true;
1230 }
1231 break;
1232 case BJACK_DOWN:
1233 case (BJACK_DOWN|BUTTON_REPEAT):
1234 if (amount - 10 > lower_limit - 1) {
1235 amount -= 10;
1236 changed = true;
1237 }
1238 break;
1239 case BJACK_RIGHT:
1240 case (BJACK_RIGHT|BUTTON_REPEAT):
1241 if (amount + 1 < upper_limit + 1) {
1242 amount++;
1243 changed = true;
1244 }
1245 break;
1246 case BJACK_LEFT:
1247 case (BJACK_LEFT|BUTTON_REPEAT):
1248 if (amount - 1 > lower_limit - 1) {
1249 amount--;
1250 changed = true;
1251 }
1252 break;
1253#ifdef BJACK_MAX
1254 case BJACK_MAX :
1255 amount = upper_limit;
1256 changed = true;
1257 break;
1258#endif
1259#ifdef BJACK_MIN
1260 case BJACK_MIN :
1261 amount = lower_limit;
1262 changed = true;
1263 break;
1264#endif
1265 case BJACK_QUIT:
1266 breakout = true;
1267 amount = 0;
1268 break;
1269 case BJACK_SELECT:
1270 breakout = true;
1271 break;
1272 }
1273
1274 if(changed) {
1275#if LCD_HEIGHT <= 64 || LCD_WIDTH <= 96
1276 rb->lcd_putsf(0, 2, "$%d", amount);
1277 rb->lcd_update();
1278#else
1279 rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID);
1280 rb->lcd_fillrect(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, 5*w, h);
1281 rb->lcd_set_drawmode(DRMODE_SOLID);
1282 rb->lcd_putsxyf(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, "$%d", amount);
1283 rb->lcd_update_rect(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, 5*w, h);
1284#endif
1285 changed = false;
1286 }
1287 }
1288
1289#if LCD_DEPTH > 1
1290 rb->lcd_set_foreground(FG_COLOR);
1291 rb->lcd_set_background(BG_COLOR);
1292#endif
1293 rb->lcd_clear_display();
1294 return amount;
1295}
1296
1297/*****************************************************************************
1298* blackjack_get_bet() gets the player's bet.
1299******************************************************************************/
1300static void blackjack_get_bet(struct game_context* bj) {
1301#if LCD_WIDTH <= 96
1302 static const char msg[] = "Enter a bet";
1303#else
1304 static const char msg[] = "Please enter a bet";
1305#endif
1306 bj->current_bet = blackjack_get_amount(msg, 10,
1307 bj->player_money, bj->current_bet);
1308}
1309
1310/*****************************************************************************
1311* double_down() returns one final card then finishes the game
1312******************************************************************************/
1313static void double_down(struct game_context* bj) {
1314 bj->current_bet *= 2;
1315 bj->player_cards[0][bj->num_player_cards[0]] = new_card();
1316 bj->player_total += bj->player_cards[0][bj->num_player_cards[0]].value;
1317 bj->num_player_cards[0]++;
1318}
1319
1320/*****************************************************************************
1321* split() checks if the player wants to split and acts accordingly.
1322* When bj->split_status is 1, no split occurred. 2 means the player split and 3
1323* means a split has already occurred and the first hand is done.
1324******************************************************************************/
1325static void split(struct game_context* bj) {
1326 if (blackjack_get_yes_no("Split?") != 0)
1327 bj->split_status = 1;
1328 else {
1329 bj->split_status = 2;
1330 bj->current_bet *= 2;
1331 bj->num_player_cards[0] = 1;
1332 bj->num_player_cards[1] = 1;
1333 bj->player_cards[1][0] = bj->player_cards[0][1];
1334 bj->player_total = bj->player_cards[0][0].value;
1335 }
1336}
1337
1338/*****************************************************************************
1339* insurance() see if the player wants to buy insurance and how much.
1340******************************************************************************/
1341static unsigned int insurance(struct game_context* bj) {
1342 unsigned int insurance, max_amount;
1343
1344 insurance = blackjack_get_yes_no("Buy Insurance?");
1345 bj->asked_insurance = true;
1346 max_amount = bj->current_bet/2 < (unsigned int)bj->player_money-bj->current_bet ?
1347 bj->current_bet/2 : (unsigned int)bj->player_money-bj->current_bet;
1348 if (insurance != 0) return 0;
1349
1350 insurance = blackjack_get_amount("How much?", 0, max_amount, 0);
1351 redraw_board(bj);
1352 return insurance;
1353}
1354
1355/*****************************************************************************
1356* play_again() checks to see if the player wants to keep playing.
1357******************************************************************************/
1358static unsigned int play_again(void) {
1359 return blackjack_get_yes_no("Play Again?");
1360}
1361
1362/*****************************************************************************
1363* blackjack_help() displays help text.
1364******************************************************************************/
1365static bool blackjack_help(void) {
1366 static char *help_text[] = {
1367 "Blackjack", "", "Aim", "",
1368 "Try", "to", "get", "as", "close", "to", "21", "without", "going",
1369 "over", "or", "simply", "beat", "out", "the", "dealer", "for", "the",
1370 "best", "hand.", "", "",
1371 "Controls", "",
1372 BJACK_SELECT_NAME, ":", "hit", "/", "select", "",
1373 BJACK_STAY_NAME, ":", "stay", "",
1374 BJACK_DOUBLE_NAME, ":", "double", "down", "",
1375 BJACK_QUIT_NAME, ":", "go", "to", "menu", "",
1376 };
1377 static struct style_text formation[]={
1378 { 0, TEXT_CENTER|TEXT_UNDERLINE },
1379 { 2, C_RED },
1380 { 26, C_RED },
1381 LAST_STYLE_ITEM
1382 };
1383
1384 rb->lcd_setfont(FONT_UI);
1385#ifdef HAVE_LCD_COLOR
1386 rb->lcd_set_background(LCD_BLACK);
1387 rb->lcd_set_foreground(LCD_WHITE);
1388#endif
1389 if (display_text(ARRAYLEN(help_text), help_text, formation, NULL, true))
1390 return true;
1391 rb->lcd_setfont(FONT_SYSFIXED);
1392
1393 return false;
1394}
1395
1396static int blackjack_menu_cb(int action,
1397 const struct menu_item_ex *this_item,
1398 struct gui_synclist *this_list)
1399{
1400 (void)this_list;
1401 int i = ((intptr_t)this_item);
1402 if(action == ACTION_REQUEST_MENUITEM
1403 && !resume && (i==0 || i==5))
1404 return ACTION_EXIT_MENUITEM;
1405 return action;
1406}
1407
1408/*****************************************************************************
1409* blackjack_menu() is the initial menu at the start of the game.
1410******************************************************************************/
1411static unsigned int blackjack_menu(void) {
1412 int selection = 0;
1413 bool breakout = false;
1414
1415 MENUITEM_STRINGLIST(menu, "BlackJack Menu", blackjack_menu_cb,
1416 "Resume Game", "Start New Game",
1417 "High Scores", "Help",
1418 "Playback Control",
1419 "Quit without Saving", "Quit");
1420
1421 while(!breakout) {
1422 switch(rb->do_menu(&menu, &selection, NULL, false)) {
1423 case 0:
1424 breakout = true;
1425 if(resume_file)
1426 rb->remove(SAVE_FILE);
1427 resume_file = false;
1428 break;
1429 case 1:
1430 breakout = true;
1431 resume = false;
1432 break;
1433 case 2:
1434 highscore_show(-1, highscores, NUM_SCORES, false);
1435 break;
1436 case 3:
1437 if(blackjack_help())
1438 return BJ_USB;
1439 break;
1440 case 4:
1441 if (playback_control(NULL))
1442 return BJ_USB;
1443 break;
1444 case 5:
1445 return BJ_QUIT_WITHOUT_SAVING;
1446 case 6:
1447 if (resume)
1448 return BJ_QUIT;
1449 else
1450 return BJ_QUIT_WITHOUT_SAVING;
1451
1452 case MENU_ATTACHED_USB:
1453 return BJ_USB;
1454
1455 default:
1456 break;
1457 }
1458 }
1459
1460 return 0;
1461}
1462
1463/*****************************************************************************
1464* blackjack() is the main game subroutine, it returns the final game status.
1465******************************************************************************/
1466static int blackjack(struct game_context* bj) {
1467 int button;
1468 unsigned int w, h, temp_var, done = 0, todo = 1;
1469 signed int temp;
1470 bool breakout = false;
1471 bool dbl_down = false;
1472
1473 /********************
1474 * menu *
1475 ********************/
1476 temp_var = blackjack_menu();
1477 if (temp_var != 0)
1478 return temp_var;
1479
1480#if LCD_DEPTH > 1
1481 rb->lcd_set_background(BG_COLOR);
1482 rb->lcd_set_foreground(FG_COLOR);
1483#endif
1484
1485 /********************
1486 * init *
1487 ********************/
1488 blackjack_init(bj);
1489
1490 /********************
1491 * play *
1492 ********************/
1493
1494 resume_file = false;
1495 /* check for resumed game */
1496 if(resume) {
1497 resume = false;
1498 redraw_board(bj);
1499 if (bj->split_status == 2) {
1500 todo=2;
1501 player_x = bj->num_player_cards[0] * 10 + 4;
1502 }
1503 else if (bj->split_status == 3) {
1504 player_x = bj->num_player_cards[1] * 10 + LCD_WIDTH/2 + 4;
1505 todo=2;
1506 done=1;
1507 }
1508 }
1509 else {
1510 bj->player_money = 1000;
1511 bj->current_bet = 10;
1512 blackjack_get_bet(bj);
1513 if (bj->current_bet == 0)
1514 return -1;
1515 rb->lcd_clear_display();
1516 deal_init_cards(bj);
1517 blackjack_drawtable(bj);
1518 }
1519
1520 rb->lcd_update();
1521
1522 breakout = false;
1523
1524 while(true){
1525 if(bj->player_total == 21 && bj->num_player_cards[0] == 2) {
1526 bj->is_blackjack = true;
1527 bj->end_hand = true;
1528 finish_game(bj);
1529 }
1530 else if(bj->dealer_cards[1].is_soft_ace && !breakout &&
1531 !bj->asked_insurance) {
1532 temp_var = insurance(bj);
1533 if (bj->dealer_total == 21) {
1534 rb->splash(HZ, "Dealer has blackjack");
1535 bj->player_money += temp_var * 2;
1536 bj->end_hand = true;
1537 breakout = true;
1538 redraw_board(bj);
1539 finish_game(bj);
1540 }
1541 else {
1542 rb->splash(HZ, "Dealer does not have blackjack");
1543 bj->player_money -= temp_var;
1544 breakout = true;
1545 redraw_board(bj);
1546 rb->lcd_update();
1547 }
1548 }
1549 if(!bj->end_hand && bj->split_status == 0 &&
1550 bj->player_cards[0][0].num == bj->player_cards[0][1].num) {
1551 if((signed int)bj->current_bet * 2 <= bj->player_money) {
1552 split(bj);
1553 redraw_board(bj);
1554 rb->lcd_update_rect(0, LCD_HEIGHT/2, LCD_WIDTH, LCD_HEIGHT/2);
1555 if (bj->split_status == 2) {
1556 todo++;
1557 player_x = bj->num_player_cards[0] * 10 + 4;
1558 }
1559 }
1560 else {
1561 rb->splash(HZ, "Not enough money to split.");
1562 redraw_board(bj);
1563 rb->lcd_update();
1564 }
1565 }
1566
1567 while(!bj->end_hand && done < todo) {
1568 button = rb->button_get(true);
1569
1570 switch(button) {
1571 case BJACK_SELECT:
1572 NEXT_CARD = new_card();
1573 bj->player_total += NEXT_CARD.value;
1574 draw_card(NEXT_CARD, true, player_x, player_y);
1575 bj->num_player_cards[done]++;
1576 if (bj->num_player_cards[done] == MAX_CARDS + 1) {
1577 redraw_board(bj);
1578 rb->lcd_update_rect(0, LCD_HEIGHT/2, LCD_WIDTH,
1579 LCD_HEIGHT/2);
1580 }
1581 else if (bj->num_player_cards[done]>MAX_CARDS || todo > 1) {
1582 rb->lcd_update_rect(player_x, player_y, CARD_WIDTH+2,
1583 CARD_HEIGHT+2);
1584 player_x += 10;
1585 }
1586 else {
1587 rb->lcd_update_rect(player_x, player_y, CARD_WIDTH+2,
1588 CARD_HEIGHT+2);
1589 player_x += CARD_WIDTH + 4;
1590 }
1591 update_total(bj);
1592
1593 break;
1594 case BJACK_STAY:
1595 bj->end_hand = true;
1596 break;
1597 case BJACK_DOUBLEDOWN:
1598 if ((signed int)bj->current_bet * 2 <
1599 bj->player_money + 1 &&
1600 bj->num_player_cards[0]==2 && todo==1) {
1601 double_down(bj);
1602 dbl_down = true;
1603 if (bj->player_total < 22)
1604 bj->end_hand = true;
1605 }
1606 else if((signed int)bj->current_bet * 2 >
1607 bj->player_money){
1608 rb->splash(HZ, "Not enough money to double down.");
1609 redraw_board(bj);
1610 rb->lcd_update();
1611 }
1612 break;
1613
1614 case BJACK_QUIT:
1615 resume = true;
1616 return BJ_END;
1617 }
1618
1619 while (bj->player_total > 21 && !bj->end_hand) {
1620 temp = check_for_aces(bj->player_cards[done],
1621 bj->num_player_cards[done]);
1622 if(temp != -1) {
1623 bj->player_cards[done][temp].is_soft_ace = false;
1624 bj->player_total -= 10;
1625 update_total(bj);
1626 if (dbl_down)
1627 bj->end_hand = true;
1628 }
1629 else
1630 bj->end_hand = true;
1631 }
1632
1633 if (bj->end_hand) {
1634 done++;
1635 if(todo > 1) {
1636 if (done == 2) {
1637 temp = bj->player_total;
1638 bj->player_total = temp_var;
1639 temp_var = temp;
1640 bj->current_bet /= 2;
1641 finish_game(bj);
1642 rb->lcd_getstringsize(" Split 1 ", &w, &h);
1643 rb->lcd_putsxy(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2,
1644 " Split 1 ");
1645 rb->lcd_update_rect(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2,
1646 w,h);
1647 rb->lcd_update_rect(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2,
1648 w,h);
1649 rb->sleep(HZ*2);
1650 bj->player_total = temp_var;
1651 finish_game(bj);
1652 rb->lcd_getstringsize(" Split 2 ", &w, &h);
1653 rb->lcd_putsxy(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2,
1654 " Split 2 ");
1655 rb->lcd_update_rect(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2,
1656 w,h);
1657 rb->sleep(HZ*2);
1658 }
1659 else {
1660 bj->end_hand = false;
1661 bj->split_status = 3;
1662 temp_var = bj->player_total;
1663 bj->player_total = bj->player_cards[1][0].value;
1664 update_total(bj);
1665 redraw_board(bj);
1666 player_x += 10;
1667 rb->lcd_update();
1668 }
1669 }
1670 else
1671 finish_game(bj);
1672 }
1673 }
1674
1675 if (bj->player_money < 10) {
1676 rb->sleep(HZ);
1677 return BJ_LOSE;
1678 }
1679
1680 if (bj->end_hand) { /* If hand is over */
1681 if (play_again() != 0) /* User wants to quit */
1682 return BJ_END;
1683 else { /* User keeps playing */
1684 breakout = false;
1685 temp = bj->current_bet;
1686 bj->current_bet = 0;
1687 redraw_board(bj);
1688 rb->lcd_update();
1689 bj->current_bet = temp;
1690 if(dbl_down) {
1691 bj->current_bet /= 2;
1692 dbl_down = false;
1693 }
1694 done = 0;
1695 todo = 1;
1696 blackjack_init(bj);
1697 blackjack_get_bet(bj);
1698 if (bj->current_bet == 0)
1699 return BJ_END;
1700 deal_init_cards(bj);
1701 blackjack_drawtable(bj);
1702 rb->lcd_update();
1703 }
1704 }
1705 }
1706 /* Never reached */
1707 return PLUGIN_OK;
1708}
1709
1710/*****************************************************************************
1711* plugin entry point.
1712******************************************************************************/
1713enum plugin_status plugin_start(const void* parameter)
1714{
1715 struct game_context bj;
1716 bool exit = false;
1717
1718 (void)parameter;
1719
1720#if LCD_DEPTH > 1
1721 rb->lcd_set_backdrop(NULL);
1722#endif
1723
1724 /* load high scores */
1725 highscore_load(SCORE_FILE, highscores, NUM_SCORES);
1726 resume = blackjack_loadgame(&bj);
1727 resume_file = resume;
1728
1729 rb->lcd_setfont(FONT_SYSFIXED);
1730
1731 while(!exit) {
1732 switch(blackjack(&bj)){
1733 case BJ_LOSE:
1734 rb->splash(HZ, "Not enough money to continue");
1735 /* fall through to BJ_END */
1736
1737 case BJ_END:
1738 if(!resume && bj.player_money > 10) {
1739 /* There is no level, so store -1 to blank column */
1740 int position = highscore_update(bj.player_money, -1, "",
1741 highscores, NUM_SCORES);
1742 if (position != -1)
1743 {
1744 if (position==0)
1745 rb->splash(HZ*2, "New High Score");
1746 highscore_show(position, highscores, NUM_SCORES, false);
1747 }
1748 }
1749 break;
1750
1751 case BJ_USB:
1752 highscore_save(SCORE_FILE, highscores, NUM_SCORES);
1753 return PLUGIN_USB_CONNECTED;
1754
1755 case BJ_QUIT:
1756 rb->splash(HZ*1, "Saving game...");
1757 blackjack_savegame(&bj);
1758 /* fall through */
1759
1760 case BJ_QUIT_WITHOUT_SAVING:
1761 exit = true;
1762 break;
1763
1764 default:
1765 break;
1766 }
1767 }
1768 highscore_save(SCORE_FILE, highscores, NUM_SCORES);
1769 return PLUGIN_OK;
1770}