Something went wrong. Try again.
A modern, network-enabled music player platform built on Rockbox technology. rockboxd.tsiry-sandratraina.com
rust deno navidrome airplay libadwaita zig mpris snapcast mpd rockbox audio subsonic
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * * Copyright (C) 2006 Tom Ross * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/
#include "plugin.h"#include "pluginbitmaps/card_deck.h"#include "pluginbitmaps/card_back.h"#include "lib/display_text.h"#include "lib/highscore.h"#include "lib/playback_control.h"
/* save files */#define SCORE_FILE PLUGIN_GAMES_DATA_DIR "/blackjack.score"#define SAVE_FILE PLUGIN_GAMES_DATA_DIR "/blackjack.save"#define NUM_SCORES 5
/* final game return status */enum { BJ_LOSE, BJ_QUIT_WITHOUT_SAVING, BJ_QUIT, BJ_USB, BJ_END,};
#if CONFIG_KEYPAD == IRIVER_H10_PAD#define BJACK_SELECT_NAME "PLAY"#define BJACK_STAY_NAME ">>|"#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "|<<"#define BJACK_SELECT BUTTON_PLAY#define BJACK_QUIT BUTTON_POWER#define BJACK_STAY BUTTON_FF#define BJACK_DOUBLEDOWN BUTTON_REW#define BJACK_UP BUTTON_SCROLL_UP#define BJACK_DOWN BUTTON_SCROLL_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ (CONFIG_KEYPAD == IRIVER_H300_PAD)#define BJACK_SELECT_NAME "ON"#define BJACK_STAY_NAME "REC"#define BJACK_QUIT_NAME "OFF"#define BJACK_DOUBLE_NAME "SELECT"#define BJACK_SELECT BUTTON_ON#define BJACK_QUIT BUTTON_OFF#define BJACK_STAY BUTTON_REC#define BJACK_DOUBLEDOWN BUTTON_SELECT#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ (CONFIG_KEYPAD == IPOD_3G_PAD) || \ (CONFIG_KEYPAD == IPOD_1G2G_PAD)#define BJACK_SELECT_NAME "SELECT"#define BJACK_STAY_NAME "RIGHT"#define BJACK_RESUME_NAME "PLAY"#define BJACK_QUIT_NAME "MENU"#define BJACK_DOUBLE_NAME "LEFT"#define BJACK_SELECT BUTTON_SELECT#define BJACK_QUIT BUTTON_MENU#define BJACK_STAY BUTTON_RIGHT#define BJACK_DOUBLEDOWN BUTTON_LEFT#define BJACK_UP BUTTON_SCROLL_FWD#define BJACK_DOWN BUTTON_SCROLL_BACK#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD#define BJACK_SELECT_NAME "SELECT"#define BJACK_STAY_NAME "REC"#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "PLAY"#define BJACK_SELECT BUTTON_SELECT#define BJACK_QUIT BUTTON_POWER#define BJACK_MAX (BUTTON_PLAY|BUTTON_UP)#define BJACK_MIN (BUTTON_PLAY|BUTTON_DOWN)#define BJACK_STAY BUTTON_REC#define BJACK_DOUBLEDOWN BUTTON_PLAY#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == GIGABEAT_PAD#define BJACK_SELECT_NAME "SELECT"#define BJACK_STAY_NAME "VOL-"#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "A"#define BJACK_SELECT BUTTON_SELECT#define BJACK_QUIT BUTTON_POWER#define BJACK_MAX BUTTON_VOL_UP#define BJACK_MIN BUTTON_VOL_DOWN#define BJACK_STAY BUTTON_VOL_DOWN#define BJACK_DOUBLEDOWN BUTTON_A#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ (CONFIG_KEYPAD == SANSA_CONNECT_PAD)#define BJACK_SELECT_NAME "SELECT"#define BJACK_STAY_NAME "RIGHT"#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "LEFT"#define BJACK_SELECT BUTTON_SELECT#define BJACK_QUIT BUTTON_POWER#define BJACK_MAX BUTTON_UP#define BJACK_MIN BUTTON_DOWN#define BJACK_STAY BUTTON_RIGHT#define BJACK_DOUBLEDOWN BUTTON_LEFT#define BJACK_UP BUTTON_SCROLL_FWD#define BJACK_DOWN BUTTON_SCROLL_BACK#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == SANSA_FUZE_PAD#define BJACK_SELECT_NAME "SELECT"#define BJACK_STAY_NAME "RIGHT"#define BJACK_QUIT_NAME "HOME"#define BJACK_DOUBLE_NAME "LEFT"#define BJACK_SELECT BUTTON_SELECT#define BJACK_QUIT (BUTTON_HOME|BUTTON_REPEAT)#define BJACK_MAX BUTTON_UP#define BJACK_MIN BUTTON_DOWN#define BJACK_STAY BUTTON_RIGHT#define BJACK_DOUBLEDOWN BUTTON_LEFT#define BJACK_UP BUTTON_SCROLL_FWD#define BJACK_DOWN BUTTON_SCROLL_BACK#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == SANSA_C200_PAD || CONFIG_KEYPAD == SANSA_CLIP_PAD#define BJACK_SELECT_NAME "SELECT"#define BJACK_STAY_NAME "RIGHT"#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "LEFT"#define BJACK_SELECT BUTTON_SELECT#define BJACK_QUIT BUTTON_POWER#define BJACK_MAX BUTTON_VOL_UP#define BJACK_MIN BUTTON_VOL_DOWN#define BJACK_STAY BUTTON_RIGHT#define BJACK_DOUBLEDOWN BUTTON_LEFT#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == SANSA_M200_PAD#define BJACK_SELECT_NAME "SELECT"#define BJACK_STAY_NAME "RIGHT"#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "LEFT"#define BJACK_SELECT (BUTTON_SELECT | BUTTON_REL)#define BJACK_QUIT BUTTON_POWER#define BJACK_MAX BUTTON_VOL_UP#define BJACK_MIN BUTTON_VOL_DOWN#define BJACK_STAY BUTTON_RIGHT#define BJACK_DOUBLEDOWN BUTTON_LEFT#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == GIGABEAT_S_PAD#define BJACK_SELECT_NAME "PLAY"#define BJACK_STAY_NAME "VOL-"#define BJACK_QUIT_NAME "BACK"#define BJACK_DOUBLE_NAME "SELECT"#define BJACK_SELECT BUTTON_PLAY#define BJACK_QUIT BUTTON_BACK#define BJACK_MAX BUTTON_VOL_UP#define BJACK_MIN BUTTON_VOL_DOWN#define BJACK_STAY BUTTON_VOL_DOWN#define BJACK_DOUBLEDOWN BUTTON_SELECT#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == MROBE100_PAD#define BJACK_SELECT_NAME "SELECT"#define BJACK_STAY_NAME "DISPLAY"#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "DOWN"#define BJACK_SELECT BUTTON_SELECT#define BJACK_QUIT BUTTON_POWER#define BJACK_MAX BUTTON_MENU#define BJACK_MIN BUTTON_DISPLAY#define BJACK_STAY BUTTON_DISPLAY#define BJACK_DOUBLEDOWN BUTTON_DOWN#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == IAUDIO_M3_PAD#define BJACK_SELECT_NAME "RC","PLAY"#define BJACK_STAY_NAME "RC", ">>|"#define BJACK_QUIT_NAME "RC_REC"#define BJACK_DOUBLE_NAME "RC_REW"#define BJACK_SELECT BUTTON_RC_PLAY#define BJACK_QUIT BUTTON_RC_REC#define BJACK_STAY BUTTON_RC_FF#define BJACK_DOUBLEDOWN BUTTON_RC_REW#define BJACK_UP BUTTON_RC_VOL_UP#define BJACK_DOWN BUTTON_RC_VOL_DOWN#define BJACK_RIGHT BUTTON_RC_FF#define BJACK_LEFT BUTTON_RC_REW
#elif CONFIG_KEYPAD == COWON_D2_PAD#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "-"#define BJACK_QUIT BUTTON_POWER#define BJACK_DOUBLEDOWN BUTTON_MINUS
#elif CONFIG_KEYPAD == CREATIVE_ZENXFI3_PAD#define BJACK_SELECT_NAME "PLAY"#define BJACK_STAY_NAME "MENU"#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "BACK"#define BJACK_SELECT BUTTON_PLAY#define BJACK_QUIT BUTTON_POWER#define BJACK_MAX BUTTON_VOL_UP#define BJACK_MIN BUTTON_VOL_DOWN#define BJACK_STAY BUTTON_MENU#define BJACK_DOUBLEDOWN BUTTON_BACK#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_MENU#define BJACK_LEFT BUTTON_BACK
#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD#define BJACK_SELECT_NAME "SELECT"#define BJACK_STAY_NAME "VOL-"#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "MENU"#define BJACK_SELECT BUTTON_SELECT#define BJACK_QUIT BUTTON_POWER#define BJACK_MAX BUTTON_VOL_UP#define BJACK_MIN BUTTON_VOL_DOWN#define BJACK_STAY BUTTON_VOL_DOWN#define BJACK_DOUBLEDOWN BUTTON_MENU#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD#define BJACK_SELECT_NAME "PLAY"#define BJACK_STAY_NAME "VOL-"#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "MENU"#define BJACK_SELECT BUTTON_PLAY#define BJACK_QUIT BUTTON_POWER#define BJACK_MAX BUTTON_VOL_UP#define BJACK_MIN BUTTON_VOL_DOWN#define BJACK_STAY BUTTON_VOL_DOWN#define BJACK_DOUBLEDOWN BUTTON_MENU#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD#define BJACK_SELECT_NAME "MENU"#define BJACK_STAY_NAME "VOL-"#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "PLAY"#define BJACK_SELECT BUTTON_MENU#define BJACK_QUIT BUTTON_POWER#define BJACK_MAX BUTTON_VOL_UP#define BJACK_MIN BUTTON_VOL_DOWN#define BJACK_STAY BUTTON_VOL_DOWN#define BJACK_DOUBLEDOWN BUTTON_PLAY#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_NEXT#define BJACK_LEFT BUTTON_PREV
#elif CONFIG_KEYPAD == ONDAVX747_PAD#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "Vol-"#define BJACK_QUIT BUTTON_POWER#define BJACK_DOUBLEDOWN BUTTON_VOL_DOWN
#elif CONFIG_KEYPAD == ONDAVX777_PAD#define BJACK_QUIT_NAME "POWER"#define BJACK_QUIT BUTTON_POWER
#elif CONFIG_KEYPAD == MROBE500_PAD#define BJACK_QUIT_NAME "POWER"#define BJACK_QUIT BUTTON_POWER
#elif (CONFIG_KEYPAD == SAMSUNG_YH820_PAD) || \ (CONFIG_KEYPAD == SAMSUNG_YH92X_PAD)#define BJACK_SELECT_NAME "PLAY"#define BJACK_STAY_NAME "FFWD"#define BJACK_QUIT_NAME "LONG REW"#define BJACK_DOUBLE_NAME "REW"#define BJACK_SELECT BUTTON_PLAY#define BJACK_QUIT (BUTTON_REW|BUTTON_REPEAT)#define BJACK_STAY BUTTON_FFWD#define BJACK_DOUBLEDOWN (BUTTON_REW|BUTTON_REL)#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == PBELL_VIBE500_PAD#define BJACK_SELECT_NAME "OK"#define BJACK_STAY_NAME "CANCEL"#define BJACK_QUIT_NAME "REC"#define BJACK_DOUBLE_NAME "MENU"#define BJACK_SELECT BUTTON_OK#define BJACK_QUIT BUTTON_REC#define BJACK_STAY BUTTON_CANCEL#define BJACK_DOUBLEDOWN BUTTON_MENU#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_NEXT#define BJACK_LEFT BUTTON_PREV
#elif CONFIG_KEYPAD == MPIO_HD200_PAD#define BJACK_SELECT_NAME "FUNC"#define BJACK_STAY_NAME "VOL +"#define BJACK_RESUME_NAME "PLAY"#define BJACK_QUIT_NAME "REC+PLAY"#define BJACK_DOUBLE_NAME "VOL -"#define BJACK_SELECT BUTTON_FUNC#define BJACK_QUIT (BUTTON_REC|BUTTON_PLAY)#define BJACK_STAY BUTTON_VOL_UP#define BJACK_DOUBLEDOWN BUTTON_VOL_DOWN#define BJACK_UP BUTTON_REW#define BJACK_DOWN BUTTON_FF#define BJACK_RIGHT BUTTON_VOL_UP#define BJACK_LEFT BUTTON_VOL_DOWN
#elif CONFIG_KEYPAD == MPIO_HD300_PAD#define BJACK_SELECT_NAME "ENTER"#define BJACK_STAY_NAME "PLAY"#define BJACK_RESUME_NAME ""#define BJACK_QUIT_NAME "Long MENU"#define BJACK_DOUBLE_NAME "REC"#define BJACK_SELECT BUTTON_ENTER#define BJACK_QUIT (BUTTON_MENU|BUTTON_REPEAT)#define BJACK_STAY BUTTON_PLAY#define BJACK_DOUBLEDOWN BUTTON_REC#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_FF#define BJACK_LEFT BUTTON_REW
#elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD#define BJACK_SELECT_NAME "SELECT"#define BJACK_STAY_NAME "PLAYPAUSE"#define BJACK_RESUME_NAME ""#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "BACK"#define BJACK_SELECT BUTTON_SELECT#define BJACK_QUIT BUTTON_POWER#define BJACK_MAX BUTTON_BOTTOMRIGHT#define BJACK_MIN BUTTON_BOTTOMLEFT#define BJACK_STAY BUTTON_BACK#define BJACK_DOUBLEDOWN BUTTON_PLAYPAUSE#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == SAMSUNG_YPR0_PAD#define BJACK_SELECT_NAME "SELECT"#define BJACK_STAY_NAME "MENU"#define BJACK_QUIT_NAME "BACK"#define BJACK_DOUBLE_NAME "USER"#define BJACK_SELECT BUTTON_SELECT#define BJACK_QUIT BUTTON_BACK#define BJACK_MAX (BUTTON_LEFT|BUTTON_UP)#define BJACK_MIN (BUTTON_RIGHT|BUTTON_DOWN)#define BJACK_STAY BUTTON_MENU#define BJACK_DOUBLEDOWN BUTTON_USER#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == HM60X_PAD#define BJACK_SELECT_NAME "SELECT"#define BJACK_STAY_NAME "UP+POWER"#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "DOWN+POWER"#define BJACK_SELECT BUTTON_SELECT#define BJACK_QUIT BUTTON_POWER#define BJACK_STAY (BUTTON_UP|BUTTON_POWER)#define BJACK_DOUBLEDOWN (BUTTON_DOWN|BUTTON_POWER)#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == HM801_PAD#define BJACK_SELECT_NAME "SELECT"#define BJACK_STAY_NAME "PLAY"#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "PREV"#define BJACK_SELECT BUTTON_SELECT#define BJACK_QUIT BUTTON_POWER#define BJACK_STAY BUTTON_PLAY#define BJACK_DOUBLEDOWN BUTTON_PREV#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == SONY_NWZ_PAD#define BJACK_SELECT BUTTON_PLAY#define BJACK_QUIT BUTTON_BACK#define BJACK_STAY (BUTTON_POWER|BUTTON_PLAY)#define BJACK_DOUBLEDOWN (BUTTON_POWER|BUTTON_DOWN)#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT#define BJACK_SELECT_NAME "Play"#define BJACK_STAY_NAME "Option+Play"#define BJACK_QUIT_NAME "Back"#define BJACK_DOUBLE_NAME "Option+Down"
#elif CONFIG_KEYPAD == CREATIVE_ZEN_PAD#define BJACK_SELECT BUTTON_SELECT#define BJACK_QUIT BUTTON_BACK#define BJACK_STAY BUTTON_PLAYPAUSE#define BJACK_DOUBLEDOWN BUTTON_SHORTCUT#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT#define BJACK_SELECT_NAME "Select"#define BJACK_STAY_NAME "Play/Pause"#define BJACK_QUIT_NAME "Back"#define BJACK_DOUBLE_NAME "Shortcut"
#elif CONFIG_KEYPAD == DX50_PAD#define BJACK_QUIT BUTTON_POWER#define BJACK_DOUBLEDOWN BUTTON_RIGHT#define BJACK_SELECT BUTTON_PLAY#define BJACK_QUIT BUTTON_POWER#define BJACK_STAY BUTTON_LEFT#define BJACK_UP BUTTON_VOL_UP#define BJACK_DOWN BUTTON_VOL_DOWN#define BJACK_LEFT BUTTON_LEFT#define BJACK_SELECT_NAME "Play"#define BJACK_STAY_NAME "Left"#define BJACK_QUIT_NAME "Power"#define BJACK_DOUBLE_NAME "Right"
#elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD#define BJACK_QUIT BUTTON_POWER#define BJACK_QUIT_NAME "Power"
#elif CONFIG_KEYPAD == AGPTEK_ROCKER_PAD#define BJACK_SELECT BUTTON_SELECT#define BJACK_QUIT BUTTON_POWER#define BJACK_STAY (BUTTON_VOLUP|BUTTON_SELECT)#define BJACK_DOUBLEDOWN (BUTTON_VOLUP|BUTTON_DOWN)#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT#define BJACK_SELECT_NAME "Select"#define BJACK_STAY_NAME "Option+Select"#define BJACK_QUIT_NAME "Volume up"#define BJACK_DOUBLE_NAME "Option+Down"
#elif CONFIG_KEYPAD == XDUOO_X3_PAD || CONFIG_KEYPAD == XDUOO_X3II_PAD || CONFIG_KEYPAD == XDUOO_X20_PAD#define BJACK_SELECT_NAME "PLAY"#define BJACK_STAY_NAME "NEXT"#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "PREV"#define BJACK_SELECT BUTTON_PLAY#define BJACK_QUIT BUTTON_POWER#define BJACK_MAX BUTTON_VOL_UP#define BJACK_MIN BUTTON_VOL_DOWN#define BJACK_STAY BUTTON_NEXT#define BJACK_DOUBLEDOWN BUTTON_PREV#define BJACK_UP BUTTON_HOME#define BJACK_DOWN BUTTON_OPTION#define BJACK_RIGHT BUTTON_NEXT#define BJACK_LEFT BUTTON_PREV
#elif CONFIG_KEYPAD == IHIFI_770_PAD || CONFIG_KEYPAD == IHIFI_800_PAD#define BJACK_SELECT_NAME "PLAY"#define BJACK_STAY_NAME "NEXT"#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "PREV"#define BJACK_SELECT BUTTON_PLAY#define BJACK_QUIT BUTTON_POWER#define BJACK_MAX BUTTON_VOL_UP#define BJACK_MIN BUTTON_VOL_DOWN#define BJACK_STAY BUTTON_NEXT#define BJACK_DOUBLEDOWN BUTTON_PREV#define BJACK_UP BUTTON_HOME#define BJACK_DOWN (BUTTON_POWER | BUTTON_HOME)#define BJACK_RIGHT BUTTON_NEXT#define BJACK_LEFT BUTTON_PREV
#elif CONFIG_KEYPAD == EROSQ_PAD#define BJACK_SELECT_NAME "PLAY"#define BJACK_STAY_NAME "NEXT"#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "PREV"#define BJACK_SELECT BUTTON_PLAY#define BJACK_QUIT BUTTON_POWER#define BJACK_MAX BUTTON_VOL_UP#define BJACK_MIN BUTTON_VOL_DOWN#define BJACK_STAY BUTTON_MENU#define BJACK_DOUBLEDOWN BUTTON_BACK#define BJACK_UP BUTTON_PREV#define BJACK_DOWN BUTTON_NEXT#define BJACK_RIGHT BUTTON_SCROLL_FWD#define BJACK_LEFT BUTTON_SCROLL_BACK
#elif CONFIG_KEYPAD == FIIO_M3K_PAD#define BJACK_SELECT_NAME "SELECT"#define BJACK_STAY_NAME "PLAY"#define BJACK_QUIT_NAME "POWER"#define BJACK_DOUBLE_NAME "MENU"#define BJACK_SELECT BUTTON_SELECT#define BJACK_QUIT BUTTON_POWER#define BJACK_MAX BUTTON_VOL_UP#define BJACK_MIN BUTTON_VOL_DOWN#define BJACK_STAY BUTTON_PLAY#define BJACK_DOUBLEDOWN BUTTON_MENU#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == MA_PAD#define BJACK_SELECT_NAME "PLAY"#define BJACK_STAY_NAME "BACK"#define BJACK_QUIT_NAME "BACK+MENU"#define BJACK_DOUBLE_NAME "MENU"#define BJACK_SELECT BUTTON_PLAY#define BJACK_QUIT (BUTTON_BACK|BUTTON_MENU)#define BJACK_MAX (BUTTON_UP|BUTTON_MENU)#define BJACK_MIN (BUTTON_DOWN|BUTTON_MENU)#define BJACK_STAY BUTTON_BACK#define BJACK_DOUBLEDOWN BUTTON_MENU#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD#define BJACK_QUIT BUTTON_POWER#define BJACK_QUIT_NAME "QUIT"
#elif CONFIG_KEYPAD == RG_NANO_PAD#define BJACK_SELECT_NAME "A"#define BJACK_STAY_NAME "Y"#define BJACK_QUIT_NAME "START"#define BJACK_DOUBLE_NAME "R"#define BJACK_SELECT BUTTON_A#define BJACK_QUIT BUTTON_START#define BJACK_MAX BUTTON_X#define BJACK_MIN BUTTON_B#define BJACK_STAY BUTTON_Y#define BJACK_DOUBLEDOWN BUTTON_R#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == N3DS_PAD#define BJACK_SELECT_NAME "A"#define BJACK_STAY_NAME "X"#define BJACK_QUIT_NAME "B"#define BJACK_DOUBLE_NAME "Y"#define BJACK_SELECT BUTTON_SELECT#define BJACK_QUIT BUTTON_BACK#define BJACK_MAX (BUTTON_LEFT|BUTTON_UP)#define BJACK_MIN (BUTTON_RIGHT|BUTTON_DOWN)#define BJACK_STAY BUTTON_MENU#define BJACK_DOUBLEDOWN BUTTON_USER#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == ECHO_R1_PAD#define BJACK_SELECT_NAME "A"#define BJACK_STAY_NAME "X"#define BJACK_QUIT_NAME "B"#define BJACK_DOUBLE_NAME "Y"#define BJACK_SELECT BUTTON_A#define BJACK_QUIT BUTTON_POWER#define BJACK_MAX BUTTON_B#define BJACK_MIN BUTTON_Y#define BJACK_STAY BUTTON_X#define BJACK_DOUBLEDOWN BUTTON_START#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == PSP_PAD#define BJACK_SELECT_NAME "Cross"#define BJACK_STAY_NAME "Triangle"#define BJACK_QUIT_NAME "Circle"#define BJACK_DOUBLE_NAME "Square"#define BJACK_SELECT BUTTON_SELECT#define BJACK_QUIT BUTTON_BACK#define BJACK_MAX (BUTTON_LEFT|BUTTON_UP)#define BJACK_MIN (BUTTON_RIGHT|BUTTON_DOWN)#define BJACK_STAY BUTTON_MENU#define BJACK_DOUBLEDOWN BUTTON_USER#define BJACK_UP BUTTON_UP#define BJACK_DOWN BUTTON_DOWN#define BJACK_RIGHT BUTTON_RIGHT#define BJACK_LEFT BUTTON_LEFT
#else#error No keymap defined!#endif
#ifdef HAVE_TOUCHSCREEN#ifndef BJACK_DOUBLEDOWN#define BJACK_DOUBLEDOWN BUTTON_MIDLEFT#define BJACK_DOUBLE_NAME "BUTTON_MIDLEFT"#endif#ifndef BJACK_SELECT#define BJACK_SELECT BUTTON_CENTER#define BJACK_SELECT_NAME "BUTTON_CENTER"#endif#ifndef BJACK_MAX#define BJACK_MAX BUTTON_TOPRIGHT#endif#ifndef BJACK_MIN#define BJACK_MIN BUTTON_TOPLEFT#endif#ifndef BJACK_STAY#define BJACK_STAY BUTTON_BOTTOMLEFT#define BJACK_STAY_NAME "BUTTON_BOTTOMLEFT"#endif#ifndef BJACK_UP#define BJACK_UP BUTTON_TOPMIDDLE#endif#ifndef BJACK_DOWN#define BJACK_DOWN BUTTON_BOTTOMMIDDLE#endif#ifndef BJACK_RIGHT#define BJACK_RIGHT BUTTON_MIDRIGHT#endif#ifndef BJACK_LEFT#define BJACK_LEFT BUTTON_MIDLEFT#endif
#endif
#ifdef HAVE_LCD_COLOR#define BG_COLOR LCD_RGBPACK(0,157,0)#define FG_COLOR LCD_WHITE#elif LCD_DEPTH > 1#define BG_COLOR LCD_WHITE#define FG_COLOR LCD_BLACK#endif
#define CARD_WIDTH BMPWIDTH_card_back#define CARD_HEIGHT BMPHEIGHT_card_back
/* This is the max amount of cards onscreen before condensing */#define MAX_CARDS LCD_WIDTH/(CARD_WIDTH+4)
extern const fb_data card_deck[];extern const fb_data card_back[];
#define NEXT_CARD bj->player_cards[done][bj->num_player_cards[done]]
/* dealer and player card positions */unsigned int dealer_x, dealer_y, player_x, player_y;
typedef struct card { unsigned int value; /* Card's value in Blackjack */ unsigned int num; /* Value on card face 0-12 (0=Ace, 1=2, 11=Q) */ unsigned int suit; /* 0:Spades, 1:Hearts, 2: Clubs; 3: Diamonds */ bool is_soft_ace;} card;
typedef struct game_context { struct card player_cards[2][22]; /* 22 Cards means the deal was all aces */ struct card dealer_cards[22]; /* That is the worst-case scenario */ unsigned int player_total; unsigned int dealer_total; signed int player_money; unsigned int num_player_cards[2]; unsigned int num_dealer_cards; unsigned int current_bet; unsigned int split_status; /* 0 = split hasn't been asked, * * 1 = split did not occur * * 2 = split occurred * * 3 = split occurred and 1st hand done */ bool is_blackjack; bool end_hand; bool asked_insurance;} game_context;
static bool resume = false;static bool resume_file = false;static struct highscore highscores[NUM_SCORES];
/****************************************************************************** blackjack_init() initializes blackjack data structures.******************************************************************************/static void blackjack_init(struct game_context* bj) { /* seed the rand generator */
/* reset card positions */ dealer_x = 4; dealer_y = LCD_HEIGHT/4 - CARD_HEIGHT/2; player_x = 4; player_y = LCD_HEIGHT - LCD_HEIGHT/4 - CARD_HEIGHT/2;
/* check for resumed game */ if(resume) return;
/* reset scoring */ bj->player_total = 0; bj->dealer_total = 0; bj->num_player_cards[0] = 2; bj->num_player_cards[1] = 0; bj->num_dealer_cards = 2; bj->end_hand = false; bj->split_status = 0; bj->is_blackjack = false; bj->asked_insurance = false;}
/****************************************************************************** blackjack_drawtable() draws the table and some text.******************************************************************************/static void blackjack_drawtable(struct game_context* bj) { unsigned int w, h, y_loc; char str[10];
#if LCD_HEIGHT <= 64 || LCD_WIDTH <= 96 rb->lcd_getstringsize("Bet", &w, &h); rb->lcd_putsxy(LCD_WIDTH - w, 2*h + 1, "Bet"); rb->snprintf(str, 9, "$%d", bj->current_bet); rb->lcd_getstringsize(str, &w, &h); rb->lcd_putsxy(LCD_WIDTH - w, 3*h + 1, str); y_loc = LCD_HEIGHT/2;#else rb->lcd_getstringsize("Bet", &w, &h); rb->lcd_putsxy(LCD_WIDTH - w, 5*h / 2, "Bet"); rb->snprintf(str, 9, "$%d", bj->current_bet); rb->lcd_getstringsize(str, &w, &h); rb->lcd_putsxy(LCD_WIDTH - w, 7*h / 2, str); rb->lcd_hline(0, LCD_WIDTH, LCD_HEIGHT/2); y_loc = LCD_HEIGHT/2 + h;#endif
rb->lcd_putsxy(0,0, "Dealer"); rb->lcd_getstringsize("Player", &w, &h); rb->lcd_putsxy(0, y_loc, "Player"); rb->lcd_getstringsize("Total", &w, &h); rb->lcd_putsxy(LCD_WIDTH - w, y_loc, "Total"); rb->lcd_getstringsize("Money", &w, &h); rb->lcd_putsxy(LCD_WIDTH - w, 0, "Money"); rb->snprintf(str, 9, "$%d", bj->player_money - bj->current_bet); rb->lcd_getstringsize(str, &w, &h); rb->lcd_putsxy(LCD_WIDTH - w, h + 1, str); rb->snprintf(str, 3, "%d", bj->player_total); rb->lcd_getstringsize(str, &w, &h); rb->lcd_putsxy(LCD_WIDTH - w, y_loc + h, str);}
/****************************************************************************** find_value() is passed a card and returns its blackjack value.******************************************************************************/static unsigned int find_value(unsigned int number) { unsigned int thisValue; if (number == 0) thisValue = 11; /* Aces get a value of 11 at first */ else if (number < 10) thisValue = number + 1; else thisValue = 10; /* Anything 10 or higher gets a value of 10 */
return thisValue;}
/****************************************************************************** draw_card() draws a card to the screen.******************************************************************************/static void draw_card(struct card temp_card, bool shown, unsigned int x, unsigned int y) { if(shown) rb->lcd_bitmap_part(card_deck, CARD_WIDTH*temp_card.num, CARD_HEIGHT*temp_card.suit, STRIDE( SCREEN_MAIN, BMPWIDTH_card_deck, BMPHEIGHT_card_deck), x+1, y+1, CARD_WIDTH, CARD_HEIGHT); else rb->lcd_bitmap(card_back, x+1, y+1,CARD_WIDTH, CARD_HEIGHT);#if LCD_DEPTH > 1 rb->lcd_set_foreground(LCD_BLACK);#endif
/* Print outlines */#if CARD_WIDTH >= 26 rb->lcd_hline(x+2, x+CARD_WIDTH-1, y); rb->lcd_hline(x+2, x+CARD_WIDTH-1, y+CARD_HEIGHT+1); rb->lcd_vline(x, y+2, y+CARD_HEIGHT-3); rb->lcd_vline(x+CARD_WIDTH+1, y+2, y+CARD_HEIGHT-1); rb->lcd_drawpixel(x+1, y+1); rb->lcd_drawpixel(x+1, y+CARD_HEIGHT); rb->lcd_drawpixel(x+CARD_WIDTH, y+1); rb->lcd_drawpixel(x+CARD_WIDTH, y+CARD_HEIGHT);#else rb->lcd_hline(x+1, x+CARD_WIDTH, y); rb->lcd_hline(x+1, x+CARD_WIDTH, y+CARD_HEIGHT+1); rb->lcd_vline(x, y+1, y+CARD_HEIGHT); rb->lcd_vline(x+CARD_WIDTH+1, y+1, y+CARD_HEIGHT);#endif
#if LCD_DEPTH > 1 rb->lcd_set_foreground(FG_COLOR);#endif}
/****************************************************************************** new_card() initializes a new card and gives it values.******************************************************************************/static struct card new_card(void) { struct card new_card; new_card.suit = rb->rand()%4; /* Random number 0-3 */ new_card.num = rb->rand()%13; /* Random number 0-12 */ new_card.value = find_value(new_card.num); new_card.is_soft_ace = (new_card.num == 0); return new_card;}
/****************************************************************************** deal_init_card() deals and draws to the screen the player's and dealer's* initial cards.******************************************************************************/static void deal_init_cards(struct game_context* bj) { bj->dealer_cards[0] = new_card(); bj->dealer_total += bj->dealer_cards[0].value;
draw_card(bj->dealer_cards[0], false, dealer_x, dealer_y);
bj->dealer_cards[1] = new_card(); bj->dealer_total += bj->dealer_cards[1].value; draw_card(bj->dealer_cards[1], true, dealer_x + CARD_WIDTH + 4, dealer_y);
bj->player_cards[0][0] = new_card(); bj->player_total += bj->player_cards[0][0].value; draw_card(bj->player_cards[0][0], true, player_x, player_y); player_x += CARD_WIDTH + 4;
bj->player_cards[0][1] = new_card(); bj->player_total += bj->player_cards[0][1].value; draw_card(bj->player_cards[0][1], true, player_x, player_y); player_x += CARD_WIDTH + 4;}
/****************************************************************************** redraw_board() redraws all the cards and the board******************************************************************************/static void redraw_board(struct game_context* bj) { unsigned int i, n, upper_bound; rb->lcd_clear_display();
blackjack_drawtable(bj); player_x = 4; dealer_x = 4; upper_bound = bj->split_status > 1 ? 2 : 1;
for (i = 0; i < bj->num_dealer_cards; i++) { if (!bj->end_hand) { draw_card(bj->dealer_cards[0], false, dealer_x, dealer_y);
/* increment i so the dealer's first card isn't displayed */ i++; dealer_x += CARD_WIDTH + 4; } draw_card(bj->dealer_cards[i], true, dealer_x, dealer_y);
if (bj->num_dealer_cards > MAX_CARDS-1) dealer_x += 10; else dealer_x += CARD_WIDTH + 4; }
for (n = 0; n < upper_bound; n++) { for (i = 0; i < bj->num_player_cards[n]; i++) { draw_card(bj->player_cards[n][i], true, player_x, player_y); if (bj->split_status>1 || bj->num_player_cards[n]>MAX_CARDS) player_x += 10; else player_x += CARD_WIDTH + 4; } if (bj->split_status > 1) player_x = LCD_WIDTH/2 + 4; }}
/****************************************************************************** update_total updates the player's total******************************************************************************/static void update_total(struct game_context* bj) { char total[3]; unsigned int w, h; rb->snprintf(total, 3, "%d", bj->player_total); rb->lcd_getstringsize(total, &w, &h);#if LCD_HEIGHT > 64 && LCD_WIDTH > 96 h *= 2;#endif rb->lcd_putsxy(LCD_WIDTH - w, LCD_HEIGHT/2 + h, total); rb->lcd_update_rect(LCD_WIDTH - w, LCD_HEIGHT/2 + h, w, h);}
/****************************************************************************** check_for_aces() is passed an array of cards and returns where an ace is* located. Otherwise, returns -1.******************************************************************************/static signed int check_for_aces(struct card temp_cards[], unsigned int size) { unsigned int i; for(i = 0; i < size; i++) { if (temp_cards[i].is_soft_ace) return i; } return -1;}
/****************************************************************************** check_totals() compares player and dealer totals.* 0: bust 1: loss, 2: push, 3: win, 4: blackjack, 5: something's not right...******************************************************************************/static unsigned int check_totals(struct game_context* bj) { unsigned int temp; if (bj->player_total > 21) temp = 0; else if (bj->player_total == 21 && bj->is_blackjack) { if (bj->dealer_total == 21 && bj->num_dealer_cards == 2) temp = 2; else temp = 4; } else if (bj->player_total == bj->dealer_total) temp = 2; else if (bj->dealer_total > 21 && bj->player_total < 22) temp = 3; else if (bj->dealer_total > bj->player_total) temp = 1; else if (bj->player_total > bj->dealer_total) temp = 3; else temp = 5;
return temp;}
/****************************************************************************** finish_dealer() draws cards for the dealer until he has 17 or more.******************************************************************************/static void finish_dealer(struct game_context* bj) { signed int temp = 0;
if (bj->dealer_total > 16 && bj->dealer_total < 22) return;
while (bj->dealer_total < 17) { bj->dealer_cards[bj->num_dealer_cards] = new_card(); bj->dealer_total += bj->dealer_cards[bj->num_dealer_cards].value; bj->num_dealer_cards++; }
while (bj->dealer_total > 21) { temp = check_for_aces(bj->dealer_cards, bj->num_dealer_cards); if(temp != -1) { bj->dealer_cards[temp].is_soft_ace = false; bj->dealer_total -= 10; } else return; }}
/****************************************************************************** finish_game() completes the game once player's turn is over.******************************************************************************/static void finish_game(struct game_context* bj) { unsigned int rValue, w, h; char str[19];
do { finish_dealer(bj); } while (bj->dealer_total < 17);
redraw_board(bj); rValue = check_totals(bj);
if (rValue == 0) { rb->snprintf(str, sizeof(str), " Bust! "); bj->player_money -= bj->current_bet; } else if (rValue == 1) { rb->snprintf(str, sizeof(str), " Sorry, you lost. "); bj->player_money -= bj->current_bet; } else if (rValue == 2) { rb->snprintf(str, sizeof(str), " Push "); } else if (rValue == 3) { rb->snprintf(str, sizeof(str), " You won! "); bj->player_money+= bj->current_bet; } else { rb->snprintf(str, sizeof(str), " Blackjack! "); bj->player_money += bj->current_bet * 3 / 2; } rb->lcd_getstringsize(str, &w, &h);
#if LCD_HEIGHT <= 64 || LCD_WIDTH <= 96 rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID); rb->lcd_fillrect(0, LCD_HEIGHT/2, LCD_WIDTH, LCD_HEIGHT/2); rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_putsxy(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + h, str); rb->snprintf(str, 12, "You have %d", bj->player_total); rb->lcd_getstringsize(str, &w, &h); rb->lcd_putsxy(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2, str);#else rb->lcd_putsxy(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 - h/2, str);#endif rb->lcd_update();}
/****************************************************************************** blackjack_loadgame() loads the saved game and returns load success.******************************************************************************/static bool blackjack_loadgame(struct game_context* bj) { signed int fd; bool loaded = false;
/* open game file */ fd = rb->open(SAVE_FILE, O_RDONLY); if(fd < 0) return false;
/* read in saved game */ if(rb->read(fd, bj, sizeof(struct game_context)) == (long)sizeof(struct game_context)) { loaded = true; }
rb->close(fd);
return loaded;}
/****************************************************************************** blackjack_savegame() saves the current game state.******************************************************************************/static void blackjack_savegame(struct game_context* bj) { int fd;
if(!resume) return; /* write out the game state to the save file */ fd = rb->open(SAVE_FILE, O_WRONLY|O_CREAT, 0666); if(fd < 0) return; rb->write(fd, bj, sizeof(struct game_context)); rb->close(fd);}
/****************************************************************************** blackjack_get_yes_no() gets a yes/no answer from the user******************************************************************************/static unsigned int blackjack_get_yes_no(const char *message) { int button; unsigned int w, h, b, choice = 0; bool breakout = false; char message_yes[24], message_no[24];
rb->strcpy(message_yes, message); rb->strcpy(message_no, message); rb->strcat(message_yes, " Yes"); rb->strcat(message_no, " No"); rb->lcd_getstringsize(message_yes, &w, &h); const char *stg[] = {message_yes, message_no};
#if LCD_HEIGHT <= 64 || LCD_WIDTH <= 96 b = 2*h+1;#else b = h-1;#endif
#ifdef HAVE_LCD_COLOR rb->lcd_fillrect(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + b, w+1, h+3); rb->lcd_set_foreground(LCD_BLACK); rb->lcd_set_background(LCD_WHITE);#else rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID); rb->lcd_fillrect(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + b, w+1, h+3); rb->lcd_set_drawmode(DRMODE_SOLID);#endif rb->lcd_drawrect(LCD_WIDTH/2 - w/2 - 1, LCD_HEIGHT/2 + b - 1, w+3, h+4);
while(!breakout) { rb->lcd_putsxy(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + b +1, stg[choice]); rb->lcd_update_rect(LCD_WIDTH/2 - w/2 - 1, LCD_HEIGHT/2 + b -1, w+3, h+4); button = rb->button_get(true);
switch(button) { case BJACK_LEFT: case (BJACK_LEFT|BUTTON_REPEAT): case BJACK_RIGHT: case (BJACK_RIGHT|BUTTON_REPEAT): choice ^= 1; break; case BJACK_SELECT: breakout = true; break; case BJACK_QUIT: breakout = true; choice = 1; break; } }
#if LCD_DEPTH > 1 rb->lcd_set_foreground(FG_COLOR); rb->lcd_set_background(BG_COLOR);#endif return choice;}
/****************************************************************************** blackjack_get_amount() gets an amount from the player to be used******************************************************************************/static signed int blackjack_get_amount(const char *message, signed int lower_limit, signed int upper_limit, signed int start) { int button; bool breakout = false, changed = false; unsigned int w, h; signed int amount;
rb->lcd_getstringsize("A", &w, &h); /* find the size of one character */
if (start > upper_limit) amount = upper_limit; else if (start < lower_limit) amount = lower_limit; else amount = start;
#if LCD_DEPTH > 1 rb->lcd_set_background(LCD_WHITE); rb->lcd_set_foreground(LCD_BLACK);#endif
#if LCD_HEIGHT <= 64 || LCD_WIDTH <= 96 rb->lcd_clear_display(); rb->lcd_puts(0, 1, message); rb->lcd_putsf(0, 2, "$%d", amount); rb->lcd_puts(0, 3, "RIGHT: +1"); rb->lcd_puts(0, 4, "LEFT: -1"); rb->lcd_puts(0, 5, "UP: +10"); rb->lcd_puts(0, 6, "DOWN: -10"); rb->lcd_update();#else rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID); rb->lcd_fillrect(LCD_WIDTH/2 - 9*w - 1, LCD_HEIGHT/2 - 4*h - 3, 37*w / 2, 8*h -3); rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_drawrect(LCD_WIDTH/2 - 9*w - 1, LCD_HEIGHT/2 - 4*h - 3, 37*w / 2, 8*h -3); rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 4*h - 1, message); rb->lcd_putsxyf(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, "$%d", amount);#if (CONFIG_KEYPAD == IPOD_4G_PAD) || \ (CONFIG_KEYPAD == IPOD_3G_PAD) || \ (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \ (CONFIG_KEYPAD == SANSA_E200_PAD) || \ (CONFIG_KEYPAD == SANSA_FUZE_PAD) || \ (CONFIG_KEYPAD == SANSA_CONNECT_PAD) || \ (CONFIG_KEYPAD == MPIO_HD300_PAD) rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - h-2, " >>|: +1"); rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 1, " |<<: -1"); rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + h, "SCROLL+: +10"); rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + 2*h + 1, "SCROLL-: -10");#elif CONFIG_KEYPAD == IRIVER_H10_PAD rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - h-2, "RIGHT: +1"); rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 1, "LEFT: -1"); rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + h, "SCROLL+: +10"); rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + 2*h + 1, "SCROLL-: -10");#else rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - h-2, "RIGHT: +1"); rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 1, "LEFT: -1"); rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + h, "UP: +10"); rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + 2*h + 1, "DOWN: -10");#endif rb->lcd_update_rect(LCD_WIDTH/2 - 9*w - 1, LCD_HEIGHT/2 - 4*h - 3, 37*w / 2, 8*h -3);#endif
while(!breakout) { button = rb->button_get(true);
switch(button) { case BJACK_UP: case (BJACK_UP|BUTTON_REPEAT): if (amount + 10 < upper_limit + 1) { amount += 10; changed = true; } break; case BJACK_DOWN: case (BJACK_DOWN|BUTTON_REPEAT): if (amount - 10 > lower_limit - 1) { amount -= 10; changed = true; } break; case BJACK_RIGHT: case (BJACK_RIGHT|BUTTON_REPEAT): if (amount + 1 < upper_limit + 1) { amount++; changed = true; } break; case BJACK_LEFT: case (BJACK_LEFT|BUTTON_REPEAT): if (amount - 1 > lower_limit - 1) { amount--; changed = true; } break;#ifdef BJACK_MAX case BJACK_MAX : amount = upper_limit; changed = true; break;#endif#ifdef BJACK_MIN case BJACK_MIN : amount = lower_limit; changed = true; break;#endif case BJACK_QUIT: breakout = true; amount = 0; break; case BJACK_SELECT: breakout = true; break; }
if(changed) {#if LCD_HEIGHT <= 64 || LCD_WIDTH <= 96 rb->lcd_putsf(0, 2, "$%d", amount); rb->lcd_update();#else rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID); rb->lcd_fillrect(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, 5*w, h); rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_putsxyf(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, "$%d", amount); rb->lcd_update_rect(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, 5*w, h);#endif changed = false; } }
#if LCD_DEPTH > 1 rb->lcd_set_foreground(FG_COLOR); rb->lcd_set_background(BG_COLOR);#endif rb->lcd_clear_display(); return amount;}
/****************************************************************************** blackjack_get_bet() gets the player's bet.******************************************************************************/static void blackjack_get_bet(struct game_context* bj) {#if LCD_WIDTH <= 96 static const char msg[] = "Enter a bet";#else static const char msg[] = "Please enter a bet";#endif bj->current_bet = blackjack_get_amount(msg, 10, bj->player_money, bj->current_bet);}
/****************************************************************************** double_down() returns one final card then finishes the game******************************************************************************/static void double_down(struct game_context* bj) { bj->current_bet *= 2; bj->player_cards[0][bj->num_player_cards[0]] = new_card(); bj->player_total += bj->player_cards[0][bj->num_player_cards[0]].value; bj->num_player_cards[0]++;}
/****************************************************************************** split() checks if the player wants to split and acts accordingly.* When bj->split_status is 1, no split occurred. 2 means the player split and 3* means a split has already occurred and the first hand is done.******************************************************************************/static void split(struct game_context* bj) { if (blackjack_get_yes_no("Split?") != 0) bj->split_status = 1; else { bj->split_status = 2; bj->current_bet *= 2; bj->num_player_cards[0] = 1; bj->num_player_cards[1] = 1; bj->player_cards[1][0] = bj->player_cards[0][1]; bj->player_total = bj->player_cards[0][0].value; }}
/****************************************************************************** insurance() see if the player wants to buy insurance and how much.******************************************************************************/static unsigned int insurance(struct game_context* bj) { unsigned int insurance, max_amount;
insurance = blackjack_get_yes_no("Buy Insurance?"); bj->asked_insurance = true; max_amount = bj->current_bet/2 < (unsigned int)bj->player_money-bj->current_bet ? bj->current_bet/2 : (unsigned int)bj->player_money-bj->current_bet; if (insurance != 0) return 0;
insurance = blackjack_get_amount("How much?", 0, max_amount, 0); redraw_board(bj); return insurance;}
/****************************************************************************** play_again() checks to see if the player wants to keep playing.******************************************************************************/static unsigned int play_again(void) { return blackjack_get_yes_no("Play Again?");}
/****************************************************************************** blackjack_help() displays help text.******************************************************************************/static bool blackjack_help(void) { static char *help_text[] = { "Blackjack", "", "Aim", "", "Try", "to", "get", "as", "close", "to", "21", "without", "going", "over", "or", "simply", "beat", "out", "the", "dealer", "for", "the", "best", "hand.", "", "", "Controls", "", BJACK_SELECT_NAME, ":", "hit", "/", "select", "", BJACK_STAY_NAME, ":", "stay", "", BJACK_DOUBLE_NAME, ":", "double", "down", "", BJACK_QUIT_NAME, ":", "go", "to", "menu", "", }; static struct style_text formation[]={ { 0, TEXT_CENTER|TEXT_UNDERLINE }, { 2, C_RED }, { 26, C_RED }, LAST_STYLE_ITEM };
rb->lcd_setfont(FONT_UI);#ifdef HAVE_LCD_COLOR rb->lcd_set_background(LCD_BLACK); rb->lcd_set_foreground(LCD_WHITE);#endif if (display_text(ARRAYLEN(help_text), help_text, formation, NULL, true)) return true; rb->lcd_setfont(FONT_SYSFIXED);
return false;}
static int blackjack_menu_cb(int action, const struct menu_item_ex *this_item, struct gui_synclist *this_list){ (void)this_list; int i = ((intptr_t)this_item); if(action == ACTION_REQUEST_MENUITEM && !resume && (i==0 || i==5)) return ACTION_EXIT_MENUITEM; return action;}
/****************************************************************************** blackjack_menu() is the initial menu at the start of the game.******************************************************************************/static unsigned int blackjack_menu(void) { int selection = 0; bool breakout = false;
MENUITEM_STRINGLIST(menu, "Blackjack", blackjack_menu_cb, "Resume Game", "Start New Game", "High Scores", "Help", "Playback Control", "Quit without Saving", "Quit");
while(!breakout) { switch(rb->do_menu(&menu, &selection, NULL, false)) { case 0: breakout = true; if(resume_file) rb->remove(SAVE_FILE); resume_file = false; break; case 1: breakout = true; resume = false; break; case 2: highscore_show(-1, highscores, NUM_SCORES, false); break; case 3: if(blackjack_help()) return BJ_USB; break; case 4: if (playback_control(NULL)) return BJ_USB; break; case 5: return BJ_QUIT_WITHOUT_SAVING; case 6: if (resume) return BJ_QUIT; else return BJ_QUIT_WITHOUT_SAVING;
case MENU_ATTACHED_USB: return BJ_USB;
default: break; } }
return 0;}
/****************************************************************************** blackjack() is the main game subroutine, it returns the final game status.******************************************************************************/static int blackjack(struct game_context* bj) { int button; unsigned int w, h, temp_var, done = 0, todo = 1; signed int temp; bool breakout = false; bool dbl_down = false;
/******************** * menu * ********************/ temp_var = blackjack_menu(); if (temp_var != 0) return temp_var;
#if LCD_DEPTH > 1 rb->lcd_set_background(BG_COLOR); rb->lcd_set_foreground(FG_COLOR);#endif
/******************** * init * ********************/ blackjack_init(bj);
/******************** * play * ********************/
resume_file = false; /* check for resumed game */ if(resume) { resume = false; redraw_board(bj); if (bj->split_status == 2) { todo=2; player_x = bj->num_player_cards[0] * 10 + 4; } else if (bj->split_status == 3) { player_x = bj->num_player_cards[1] * 10 + LCD_WIDTH/2 + 4; todo=2; done=1; } } else { bj->player_money = 1000; bj->current_bet = 10; blackjack_get_bet(bj); if (bj->current_bet == 0) return -1; rb->lcd_clear_display(); deal_init_cards(bj); blackjack_drawtable(bj); }
rb->lcd_update();
breakout = false;
while(true){ if(bj->player_total == 21 && bj->num_player_cards[0] == 2) { bj->is_blackjack = true; bj->end_hand = true; finish_game(bj); } else if(bj->dealer_cards[1].is_soft_ace && !breakout && !bj->asked_insurance) { temp_var = insurance(bj); if (bj->dealer_total == 21) { rb->splash(HZ, "Dealer has blackjack"); bj->player_money += temp_var * 2; bj->end_hand = true; breakout = true; redraw_board(bj); finish_game(bj); } else { rb->splash(HZ, "Dealer does not have blackjack"); bj->player_money -= temp_var; breakout = true; redraw_board(bj); rb->lcd_update(); } } if(!bj->end_hand && bj->split_status == 0 && bj->player_cards[0][0].num == bj->player_cards[0][1].num) { if((signed int)bj->current_bet * 2 <= bj->player_money) { split(bj); redraw_board(bj); rb->lcd_update_rect(0, LCD_HEIGHT/2, LCD_WIDTH, LCD_HEIGHT/2); if (bj->split_status == 2) { todo++; player_x = bj->num_player_cards[0] * 10 + 4; } } else { rb->splash(HZ, "Not enough money to split."); redraw_board(bj); rb->lcd_update(); } }
while(!bj->end_hand && done < todo) { button = rb->button_get(true);
switch(button) { case BJACK_SELECT: NEXT_CARD = new_card(); bj->player_total += NEXT_CARD.value; draw_card(NEXT_CARD, true, player_x, player_y); bj->num_player_cards[done]++; if (bj->num_player_cards[done] == MAX_CARDS + 1) { redraw_board(bj); rb->lcd_update_rect(0, LCD_HEIGHT/2, LCD_WIDTH, LCD_HEIGHT/2); } else if (bj->num_player_cards[done]>MAX_CARDS || todo > 1) { rb->lcd_update_rect(player_x, player_y, CARD_WIDTH+2, CARD_HEIGHT+2); player_x += 10; } else { rb->lcd_update_rect(player_x, player_y, CARD_WIDTH+2, CARD_HEIGHT+2); player_x += CARD_WIDTH + 4; } update_total(bj);
break; case BJACK_STAY: bj->end_hand = true; break; case BJACK_DOUBLEDOWN: if ((signed int)bj->current_bet * 2 < bj->player_money + 1 && bj->num_player_cards[0]==2 && todo==1) { double_down(bj); dbl_down = true; if (bj->player_total < 22) bj->end_hand = true; } else if((signed int)bj->current_bet * 2 > bj->player_money){ rb->splash(HZ, "Not enough money to double down."); redraw_board(bj); rb->lcd_update(); } break;
case BJACK_QUIT: resume = true; return BJ_END; }
while (bj->player_total > 21 && !bj->end_hand) { temp = check_for_aces(bj->player_cards[done], bj->num_player_cards[done]); if(temp != -1) { bj->player_cards[done][temp].is_soft_ace = false; bj->player_total -= 10; update_total(bj); if (dbl_down) bj->end_hand = true; } else bj->end_hand = true; }
if (bj->end_hand) { done++; if(todo > 1) { if (done == 2) { temp = bj->player_total; bj->player_total = temp_var; temp_var = temp; bj->current_bet /= 2; finish_game(bj); rb->lcd_getstringsize(" Split 1 ", &w, &h); rb->lcd_putsxy(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2, " Split 1 "); rb->lcd_update_rect(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2, w,h); rb->lcd_update_rect(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2, w,h); rb->sleep(HZ*2); bj->player_total = temp_var; finish_game(bj); rb->lcd_getstringsize(" Split 2 ", &w, &h); rb->lcd_putsxy(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2, " Split 2 "); rb->lcd_update_rect(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2, w,h); rb->sleep(HZ*2); } else { bj->end_hand = false; bj->split_status = 3; temp_var = bj->player_total; bj->player_total = bj->player_cards[1][0].value; update_total(bj); redraw_board(bj); player_x += 10; rb->lcd_update(); } } else finish_game(bj); } }
if (bj->player_money < 10) { rb->sleep(HZ); return BJ_LOSE; }
if (bj->end_hand) { /* If hand is over */ if (play_again() != 0) /* User wants to quit */ return BJ_END; else { /* User keeps playing */ breakout = false; temp = bj->current_bet; bj->current_bet = 0; redraw_board(bj); rb->lcd_update(); bj->current_bet = temp; if(dbl_down) { bj->current_bet /= 2; dbl_down = false; } done = 0; todo = 1; blackjack_init(bj); blackjack_get_bet(bj); if (bj->current_bet == 0) return BJ_END; deal_init_cards(bj); blackjack_drawtable(bj); rb->lcd_update(); } } } /* Never reached */ return PLUGIN_OK;}
/****************************************************************************** plugin entry point.******************************************************************************/enum plugin_status plugin_start(const void* parameter){ struct game_context bj; bool exit = false;
(void)parameter;
#if LCD_DEPTH > 1 rb->lcd_set_backdrop(NULL);#endif
/* load high scores */ highscore_load(SCORE_FILE, highscores, NUM_SCORES); resume = blackjack_loadgame(&bj); resume_file = resume;
rb->lcd_setfont(FONT_SYSFIXED);
while(!exit) { switch(blackjack(&bj)){ case BJ_LOSE: rb->splash(HZ, "Not enough money to continue"); /* fall through to BJ_END */
case BJ_END: if(!resume && bj.player_money > 10) { /* There is no level, so store -1 to blank column */ int position = highscore_update(bj.player_money, -1, "", highscores, NUM_SCORES); if (position != -1) { if (position==0) rb->splash(HZ*2, "New High Score"); highscore_show(position, highscores, NUM_SCORES, false); } } break;
case BJ_USB: highscore_save(SCORE_FILE, highscores, NUM_SCORES); return PLUGIN_USB_CONNECTED;
case BJ_QUIT: rb->splash(HZ*1, "Saving game..."); blackjack_savegame(&bj); /* fall through */
case BJ_QUIT_WITHOUT_SAVING: exit = true; break;
default: break; } } highscore_save(SCORE_FILE, highscores, NUM_SCORES); return PLUGIN_OK;}