A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 1770 lines 63 kB view raw
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}