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.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727/**************************************************************************** __________ __ ___.* Open \______ \ ____ ____ | | _\_ |__ _______ ___* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \* \/ \/ \/ \/ \/** Copyright (C) 2005 Adam Boot** Color graphics from Frozen Bubble (http://www.frozen-bubble.org/)** 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 "fixedpoint.h"
#include "lib/xlcd.h"#include "lib/pluginlib_actions.h"#include "lib/playback_control.h"#include "lib/highscore.h"
/* files */#define SCORE_FILE PLUGIN_GAMES_DATA_DIR "/bubbles.score"#define SAVE_FILE PLUGIN_GAMES_DATA_DIR "/bubbles.save"#define DATA_FILE PLUGIN_GAMES_DATA_DIR "/bubbles.data"
/* final game return status */enum { BB_LOSE, BB_QUIT_WITHOUT_SAVING, BB_QUIT, BB_USB, BB_END, BB_WIN, BB_NONE,};
/* play board dimension */#define BB_HEIGHT 12#define BB_WIDTH 8#define BB_LEVEL_HEIGHT 10
/* various amounts */#define NUM_SCORES 5#define NUM_LEVELS 100#define NUM_QUEUE 2#define NUM_BUBBLES 8#define MIN_ANGLE -76#define MAX_ANGLE 76#define NUM_COMPRESS 9#define MAX_SHOTTIME 1000
/* keyboard layouts */
#ifdef HAVE_SCROLLWHEEL/* sansas use the wheel instead of left/right if available */#define BUBBLES_LEFT PLA_SCROLL_BACK#define BUBBLES_LEFT_REP PLA_SCROLL_BACK_REPEAT#define BUBBLES_RIGHT PLA_SCROLL_FWD#define BUBBLES_RIGHT_REP PLA_SCROLL_FWD_REPEAT#else#define BUBBLES_LEFT PLA_LEFT#define BUBBLES_LEFT_REP PLA_LEFT_REPEAT#define BUBBLES_RIGHT PLA_RIGHT#define BUBBLES_RIGHT_REP PLA_RIGHT_REPEAT#endif
#define ANGLE_STEP 2#define ANGLE_STEP_REP 6
#define BUBBLES_QUIT1 PLA_EXIT
/* these are better off shooting with up */#if (CONFIG_KEYPAD == SAMSUNG_YH820_PAD) \ || (CONFIG_KEYPAD == SAMSUNG_YH92X_PAD) \ || (CONFIG_KEYPAD == IRIVER_H10_PAD)#define SHOOT_WITH_UP#endif
#ifdef SHOOT_WITH_UP#define BUBBLES_FIRE PLA_UP#define BUBBLES_FIRE_REPEAT PLA_UP_REPEAT#define BUBBLES_PAUSE PLA_SELECT#define BUBBLES_QUIT2 PLA_CANCEL#elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) \ || (CONFIG_KEYPAD == IPOD_3G_PAD) \ || (CONFIG_KEYPAD == IPOD_4G_PAD)#define BUBBLES_FIRE PLA_SELECT#define BUBBLES_FIRE_REPEAT PLA_SELECT_REPEAT#define BUBBLES_PAUSE PLA_DOWN#define BUBBLES_QUIT2 PLA_UP#else#define BUBBLES_FIRE PLA_SELECT#define BUBBLES_FIRE_REPEAT PLA_SELECT_REPEAT#define BUBBLES_PAUSE PLA_UP#define BUBBLES_QUIT2 PLA_CANCEL#endif
/* external bitmaps */#ifdef HAVE_LCD_COLOR#include "pluginbitmaps/bubbles_background.h"#endif#include "pluginbitmaps/bubbles_bubble.h"#include "pluginbitmaps/bubbles_emblem.h"
#define BUBBLE_WIDTH BMPWIDTH_bubbles_bubble#define BUBBLE_HEIGHT BMPHEIGHT_bubbles_bubble#define EMBLEM_WIDTH BMPWIDTH_bubbles_emblem#define EMBLEM_HEIGHT (BMPHEIGHT_bubbles_emblem/8)
/* bubbles will consume height of ROW_HEIGHT*(BB_HEIGHT-1)+BUBBLE_HEIGHT*3/2 *//* 44x44 bubbles (m:robe 500) */#if (LCD_WIDTH == 640) && (LCD_HEIGHT == 480)#define XOFS 144#define MAX_FPS 40
/* custom text positioning */#define LEVEL_TXT_X 58#define LEVEL_TXT_WIDTH 32#define LEVEL_TXT_Y 8#define SCORE_TXT_X 58#define SCORE_TXT_WIDTH 32#define SCORE_TXT_Y 62#define NEXT_BB_X 58#define NEXT_BB_WIDTH 32#define NEXT_BB_Y 402
#elif (LCD_WIDTH == 480) && (LCD_HEIGHT >= 640)#define XOFS 128#define MAX_FPS 40
/* 22x22 bubbles (Sony PSP) */#elif (LCD_WIDTH == 480) && (LCD_HEIGHT == 272)#define XOFS 152#define YOFS 29#define MAX_FPS 60
/* custom text positioning */#define LEVEL_TXT_X 38#define LEVEL_TXT_WIDTH 55#define LEVEL_TXT_Y 34#define SCORE_TXT_X 38#define SCORE_TXT_WIDTH 55#define SCORE_TXT_Y 104#define NEXT_BB_X 390#define NEXT_BB_WIDTH 35#define NEXT_BB_Y 116
#elif (LCD_WIDTH == 360) && (LCD_HEIGHT == 640)#define XOFS 86#define YOFS 220#define SCORE_TXT_X 28#define SCORE_TXT_WIDTH 32#define SCORE_TXT_Y 48#define LEVEL_TXT_X 27#define LEVEL_TXT_WIDTH 32#define LEVEL_TXT_Y 5#define MAX_FPS 40
#elif (LCD_WIDTH == 360) && (LCD_HEIGHT == 400)#define XOFS 86#define YOFS 100#define SCORE_TXT_X 28#define SCORE_TXT_WIDTH 32#define SCORE_TXT_Y 48#define LEVEL_TXT_X 27#define LEVEL_TXT_WIDTH 32#define LEVEL_TXT_Y 5#define MAX_FPS 40
/* 22x22 bubbles (iPod Video) */#elif (LCD_HEIGHT == 240) && (LCD_WIDTH == 320)#define XOFS 72#define MAX_FPS 40
/* custom text positioning */#define NEXT_BB_X 20#define NEXT_BB_WIDTH 32#define NEXT_BB_Y 200
/* 22x22 bubbles: the 320x240 layout, centred (Samsung YP-CP3) */#elif (LCD_HEIGHT == 240) && (LCD_WIDTH == 400)#define LAYOUT_X ((LCD_WIDTH - 320) / 2)#define XOFS (LAYOUT_X + 72)#define MAX_FPS 40
/* the 320x240 text positions, which centre on its left panel */#define LEVEL_TXT_X LAYOUT_X#define LEVEL_TXT_WIDTH 72#define LEVEL_TXT_Y 2#define SCORE_TXT_X LAYOUT_X#define SCORE_TXT_WIDTH 72#define SCORE_TXT_Y 29#define NEXT_BB_X (LAYOUT_X + 20)#define NEXT_BB_WIDTH 32#define NEXT_BB_Y 200
/* 22x22 bubbles (Gigabeat, Onda VX747) */#elif ((LCD_HEIGHT == 320) || (LCD_HEIGHT == 400)) && (LCD_WIDTH == 240)#define XOFS 64#define MAX_FPS 30
/* custom text positioning */#define LEVEL_TXT_X 21#define LEVEL_TXT_WIDTH 32#define LEVEL_TXT_Y 2#define SCORE_TXT_X 20#define SCORE_TXT_WIDTH 32#define SCORE_TXT_Y 29#define NEXT_BB_X 20#define NEXT_BB_WIDTH 32#define NEXT_BB_Y 200
/* 22x22 bubbles (Anbernic RG Nano) */#elif (LCD_HEIGHT == 240) && (LCD_WIDTH == 240)#define XOFS 64#define MAX_FPS 40
/* custom text positioning */#define SCORE_TXT_X 12#define SCORE_TXT_WIDTH 32#define SCORE_TXT_Y 29#define LEVEL_TXT_X 12#define LEVEL_TXT_WIDTH 32#define LEVEL_TXT_Y 2#define NEXT_BB_X 12#define NEXT_BB_WIDTH 32#define NEXT_BB_Y 200
/* 16x16 bubbles (H300, iPod Color, HDD6330) */#elif (LCD_HEIGHT == 176) && (LCD_WIDTH == 220)#define XOFS 46#define MAX_FPS 30
/* 16x16 bubbles (Sansa E200) */#elif (LCD_HEIGHT == 220) && (LCD_WIDTH == 176)#define XOFS 24#define MAX_FPS 30#define YOFS 45
/* custom text positioning */#define LEVEL_TXT_X 24#define LEVEL_TXT_WIDTH 31#define LEVEL_TXT_Y 5#define SCORE_TXT_X 58#define SCORE_TXT_WIDTH 31#define SCORE_TXT_Y 5#define NEXT_BB_X 112#define NEXT_BB_WIDTH 31#define NEXT_BB_Y 3
/* 12x12 bubbles (iPod Nano) */#elif (LCD_HEIGHT == 132) && (LCD_WIDTH == 176)#define XOFS 40#define MAX_FPS 40
/* 12x12 bubbles (H100, H10, iAudio X5, HDD1630, iPod 3G, iPod 4G grayscale) */#elif (LCD_HEIGHT == 128) && ((LCD_WIDTH == 160) || (LCD_WIDTH == 128))#define XOFS 33#define MAX_FPS 30
/* 12x12 bubbles (GoGear SA9200) */#elif (LCD_HEIGHT == 160) && (LCD_WIDTH == 128)#define XOFS 16#define YOFS 32#define ROW_HEIGHT 10#define ROW_INDENT 6#define MAX_FPS 30
/* custom text positioning */#define LEVEL_TXT_X 2#define LEVEL_TXT_WIDTH 31#define LEVEL_TXT_Y 3#define SCORE_TXT_X 34#define SCORE_TXT_WIDTH 31#define SCORE_TXT_Y 3#define NEXT_BB_X 81#define NEXT_BB_WIDTH 31#define NEXT_BB_Y 2
/* 10x10 bubbles (iPod Mini) */#elif (LCD_HEIGHT == 110) && (LCD_WIDTH == 138)#define XOFS 33#define MAX_FPS 30
/* 9x9 bubbles (iAudio M3, Samsung YH-820) */#elif (LCD_HEIGHT == 96) && (LCD_WIDTH == 128)#define XOFS 29#define MAX_FPS 30
/* 8x8 bubbles (Sansa C200) */#elif ((LCD_HEIGHT == 80) && (LCD_WIDTH == 132))#define XOFS 45#define ROW_HEIGHT 6#define MAX_FPS 30
/* 7x7 bubbles (Sansa Clip/m200) */#elif (LCD_HEIGHT == 64 && LCD_WIDTH == 128)#define XOFS 33#define ROW_HEIGHT 5#define MAX_FPS 30
/* 8x7 bubbles (Archos recorder, Ondio) */#elif (LCD_HEIGHT == 64) && (LCD_WIDTH == 112)#define XOFS 33#define ROW_HEIGHT 5#define MAX_FPS 20
/* 7x7 bubbles (Sansa Clip Zip) */#elif (LCD_HEIGHT == 96 && LCD_WIDTH == 96)#define XOFS 33#define ROW_HEIGHT 5#define MAX_FPS 30
/* custom text positioning */#define LEVEL_TXT_X 1#define LEVEL_TXT_WIDTH 31#define LEVEL_TXT_Y 4#define SCORE_TXT_X 1#define SCORE_TXT_WIDTH 31#define SCORE_TXT_Y 31#define NEXT_BB_X 1#define NEXT_BB_WIDTH 31#define NEXT_BB_Y 72
#else #error BUBBLES: Unsupported LCD type#endif
#if !defined(ROW_HEIGHT)#define ROW_HEIGHT (BUBBLE_WIDTH-(BUBBLE_WIDTH-EMBLEM_WIDTH)/2)#endif
#if !defined(ROW_INDENT)#define ROW_INDENT (BUBBLE_WIDTH/2)#endif
#define TEXT_LINES (LCD_HEIGHT/8)
#ifndef YOFS#define YOFS 0#endif
/* shot position */#define SHOTX XOFS+ROW_INDENT+BUBBLE_WIDTH*3#define SHOTY (YOFS+ROW_HEIGHT*(BB_HEIGHT-1)+BUBBLE_HEIGHT/2)
/* collision distance squared */#define MIN_DISTANCE ((BUBBLE_WIDTH*8)/10)*((BUBBLE_HEIGHT*8)/10)
/* levels */char level[NUM_LEVELS][BB_LEVEL_HEIGHT][BB_WIDTH] = { {{ 6, 6, 4, 4, 2, 2, 3, 3}, { 6, 6, 4, 4, 2, 2, 3, -1}, { 2, 2, 3, 3, 6, 6, 4, 4}, { 2, 3, 3, 6, 6, 4, 4, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 7, 7, 7, 7, 7, 7, -1}, {-1, 1, 1, 1, 1, 1, -1, -1}, {-1, -1, 2, 2, 2, 2, -1, -1}, {-1, -1, -1, 2, -1, -1, -1, -1}, {-1, -1, -1, 2, 2, -1, -1, -1}, {-1, -1, -1, 5, -1, -1, -1, -1}, {-1, -1, -1, 5, 5, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, 7, -1, -1, 7, -1, -1}, {-1, -1, 7, 1, 7, -1, -1, -1}, {-1, -1, -1, 1, 2, -1, -1, -1}, {-1, -1, 1, 2, 1, -1, -1, -1}, {-1, -1, -1, 2, 5, -1, -1, -1}, {-1, -1, 3, 5, 3, -1, -1, -1}, {-1, -1, -1, 5, 3, -1, -1, -1}, {-1, -1, -1, 3, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, 0, 0, -1, -1, -1}, {-1, -1, 5, 0, 1, -1, -1, -1}, {-1, -1, 3, 5, 1, 6, -1, -1}, {-1, 4, 3, -1, 6, 7, -1, -1}, {-1, 7, 4, -1, -1, 7, 4, -1}, { 6, 7, -1, -1, -1, 4, 3, -1}, { 1, 6, -1, -1, -1, -1, 3, 5}, { 1, -1, -1, -1, -1, -1, 5, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, 0, 0, 0, 0, -1, -1}, {-1, 0, 1, 1, 1, 0, -1, -1}, {-1, 0, 1, 0, 0, 1, 0, -1}, {-1, 0, 1, 1, 1, 0, -1, -1}, {-1, -1, 0, 0, 0, 0, -1, -1}, {-1, -1, 7, -1, 7, -1, -1, -1}, {-1, -1, 7, 7, 7, 7, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 4, 4, 4, 6, 6, 6, -1}, { 4, -1, -1, -1, -1, -1, 6, -1}, {-1, 4, -1, -1, -1, -1, 6, -1}, { 4, 2, 3, 1, 2, 3, 6, -1}, {-1, 3, 1, 2, 3, 1, 2, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 4, 4, 4, 6, 6, 6, -1}, { 4, -1, -1, -1, -1, -1, 6, -1}, {-1, 4, -1, -1, -1, -1, 6, -1}, { 4, 2, 3, 1, 2, 3, 6, -1}, {-1, 3, 1, 2, 3, 1, 2, -1}, {-1, 2, 3, 1, 2, 3, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 0, 0, -1, -1, 2, 2, -1}, {-1, 5, -1, -1, -1, 3, -1, -1}, {-1, 0, -1, -1, -1, 6, -1, -1}, {-1, 3, -1, -1, -1, 0, -1, -1}, {-1, 4, -1, -1, -1, 5, -1, -1}, {-1, 2, -1, -1, -1, 3, -1, -1}, {-1, 2, -1, -1, -1, 1, -1, -1}, {-1, 3, -1, -1, -1, 4, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 3, -1, -1, -1, -1, -1, -1, 3}, { 6, 3, 2, 4, 6, 3, 2, -1}, { 4, -1, -1, -1, -1, -1, -1, 4}, { 2, 4, 6, 3, 2, 4, 6, -1}, {-1, -1, -1, 6, -1, -1, -1, -1}, {-1, -1, -1, 3, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 2, -1, 1, -1, 1, -1, 2}, { 1, 2, -1, 2, 1, -1, 1, -1}, { 1, -1, 1, -1, 2, -1, 2, -1}, { 2, 1, -1, 1, 2, -1, 2, -1}, {-1, 2, -1, 2, -1, 2, -1, 2}, { 1, 2, -1, 2, 1, -1, 1, -1}, { 1, -1, 1, -1, 2, -1, 1, -1}, { 2, 2, -1, 1, 1, -1, 2, -1}, {-1, 2, -1, 1, -1, 1, -1, 1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 7, 7, -1, -1, 5, 5, -1}, { 1, -1, -1, -1, -1, -1, 4, -1}, { 2, 1, -1, -1, -1, -1, 4, 3}, { 2, -1, -1, -1, -1, -1, 3, -1}, { 1, 2, -1, -1, -1, -1, 3, 4}, { 1, -1, -1, -1, -1, -1, 4, -1}, { 7, 1, -1, -1, -1, -1, 4, 5}, { 7, 7, -1, -1, -1, 5, 5, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 7, 7, -1, -1, -1, -1, 5, 5}, { 1, 5, -1, -1, -1, 7, 4, -1}, { 2, 1, -1, -1, -1, -1, 4, 3}, { 2, -1, -1, -1, -1, -1, 3, -1}, { 1, 5, -1, -1, -1, -1, 7, 4}, { 1, -1, -1, -1, -1, -1, 4, -1}, { 7, 1, -1, -1, -1, -1, 4, 5}, { 7, 5, -1, -1, -1, 7, 5, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, 0, 0, -1, -1, -1}, {-1, -1, 5, 0, 1, -1, -1, -1}, {-1, -1, 3, 5, 1, 6, -1, -1}, {-1, 4, 3, 2, 6, 2, -1, -1}, {-1, 7, 4, 7, 2, 2, 4, -1}, { 6, 7, 7, 3, 3, 4, 3, -1}, { 1, 6, 1, 1, 1, 3, 3, 5}, { 1, 1, -1, -1, -1, -1, 5, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, 0, -1, -1, 0, -1, -1}, {-1, 3, 3, -1, 3, 3, -1, -1}, {-1, 0, 2, 0, 0, 2, 0, -1}, {-1, 3, 3, -1, 3, 3, -1, -1}, {-1, -1, 0, -1, -1, 0, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, 1, 1, -1, -1, -1}, {-1, -1, 2, 2, 2, -1, -1, -1}, {-1, -1, 3, 3, 3, 3, -1, -1}, {-1, 4, 4, 4, 4, 4, -1, -1}, {-1, 5, 5, 5, 5, 5, 5, -1}, {-1, -1, -1, 6, -1, -1, -1, -1}, {-1, -1, -1, 7, 7, -1, -1, -1}, {-1, -1, -1, 0, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, 2, 5, -1, -1, -1}, {-1, 4, 3, -1, -1, -1, -1, -1}, { 6, 7, -1, 5, 2, -1, -1, -1}, {-1, -1, -1, -1, 3, 4, -1, -1}, {-1, -1, -1, 2, 5, -1, 7, 6}, {-1, 4, 3, -1, -1, -1, -1, -1}, { 6, 7, -1, 5, 2, -1, -1, -1}, {-1, -1, -1, -1, 3, 4, -1, -1}, {-1, -1, -1, -1, -1, -1, 7, 6}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, 5, 5, -1, -1, -1}, {-1, -1, -1, 3, -1, -1, -1, -1}, {-1, -1, -1, 1, -1, -1, -1, -1}, {-1, -1, -1, 7, -1, -1, -1, -1}, {-1, -1, -1, 2, -1, -1, -1, -1}, {-1, -1, -1, 4, -1, -1, -1, -1}, {-1, -1, -1, 5, -1, -1, -1, -1}, {-1, -1, -1, 3, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, 0, 1, -1, -1, -1}, {-1, -1, 0, 2, 7, 7, -1, -1}, {-1, -1, -1, 0, 1, 7, -1, -1}, {-1, 0, 0, 0, 0, -1, -1, -1}, {-1, 0, 0, 0, 1, 1, -1, -1}, { 0, 0, 0, 1, 1, 1, -1, -1}, {-1, 0, 0, 1, 1, 1, -1, -1}, {-1, 0, 0, 0, 7, 7, -1, -1}, {-1, -1, 7, 7, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 1, -1, -1, -1, -1, -1, -1}, { 1, -1, -1, -1, -1, -1, -1, -1}, {-1, 2, 3, 4, 7, 6, 5, -1}, {-1, -1, -1, -1, -1, -1, 1, -1}, {-1, -1, -1, -1, -1, -1, 1, -1}, {-1, 2, 3, 4, 7, 6, -1, -1}, {-1, 1, -1, -1, -1, -1, -1, -1}, { 1, -1, -1, -1, -1, -1, -1, -1}, {-1, 2, 3, 4, 7, 6, 5, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 6, -1, -1, -1, -1, -1, -1}, { 5, -1, -1, -1, -1, -1, -1, -1}, { 2, 3, 4, 7, 6, 5, 2, 3}, {-1, -1, -1, -1, -1, -1, 4, -1}, {-1, -1, -1, -1, -1, -1, 7, -1}, {-1, 4, 3, 2, 5, 6, -1, -1}, {-1, 7, -1, -1, -1, -1, -1, -1}, { 6, -1, -1, -1, -1, -1, -1, -1}, { 5, 2, 3, 4, 7, 6, 5, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 3, 2, 1, 0, 0, 1, 2, 3}, { 3, 2, 1, 0, 1, 2, 3, -1}, { 4, 3, 2, 1, 1, 2, 3, 4}, { 4, 3, 2, 1, 2, 3, 4, -1}, { 5, 4, 3, 2, 2, 3, 4, 5}, { 5, 4, 3, 2, 3, 4, 5, -1}, { 6, 5, 4, 3, 3, 4, 5, 6}, { 6, 5, 4, 3, 4, 5, 6, -1}, { 7, 6, 5, 4, 4, 5, 6, 7}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, 5, 5, -1, -1, -1}, {-1, -1, -1, 3, -1, -1, -1, -1}, {-1, -1, -1, 2, 4, -1, -1, -1}, {-1, -1, -1, 6, -1, -1, -1, -1}, {-1, -1, -1, 2, 4, -1, -1, -1}, {-1, 2, -1, 5, -1, 4, -1, -1}, { 1, 0, 1, 0, 1, 0, 1, 0}, { 3, -1, 3, -1, 2, -1, 6, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, -1, 1, -1, -1, -1}, { 7, 4, 3, 5, -1, -1, -1, -1}, { 6, -1, -1, 1, -1, -1, -1, -1}, {-1, -1, -1, 5, 3, 4, 7, -1}, { 6, -1, -1, -1, 1, -1, -1, 6}, { 7, 4, 3, 5, -1, -1, -1, -1}, {-1, -1, -1, 1, -1, -1, -1, 6}, {-1, -1, -1, 5, 3, 4, 7, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, -1, 7, 3, 6, -1}, {-1, -1, 3, 7, 3, 6, 3, -1}, {-1, -1, 5, 7, 3, 6, 3, -1}, {-1, 6, 7, 3, 6, 7, -1, -1}, {-1, 7, 7, 3, 6, 1, -1, -1}, { 3, 7, 3, 6, 3, -1, -1, -1}, { 5, 6, 2, 7, 1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 5, -1, -1, -1, -1, -1, -1, 5}, { 5, -1, 6, 6, 6, -1, 5, -1}, {-1, 5, 4, -1, -1, 4, 5, -1}, {-1, 3, -1, -1, -1, 3, -1, -1}, {-1, 6, 0, -1, -1, 0, 6, -1}, {-1, 3, -1, -1, -1, 3, -1, -1}, {-1, -1, 4, -1, -1, 4, -1, -1}, {-1, -1, 6, 6, 6, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 7, 0, -1, -1, 0, 7, -1}, { 7, -1, 0, -1, 0, -1, 7, -1}, { 7, 1, -1, 0, 0, -1, 1, 7}, { 7, 1, 2, 0, 2, 1, 7, -1}, { 7, 6, 3, 2, 2, 3, 6, 7}, { 7, -1, 3, 2, 3, -1, 7, -1}, {-1, 7, 7, 3, 3, 7, 7, -1}, {-1, -1, -1, 3, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 3, -1, 1, -1, 7, -1, 6}, { 5, -1, 7, -1, 7, -1, 6, -1}, { 6, -1, 0, -1, 5, -1, 3, -1}, {-1, 2, -1, 1, -1, 5, -1, -1}, {-1, 4, -1, 3, -1, 4, -1, -1}, { 2, -1, 3, -1, 2, -1, -1, -1}, {-1, -1, 4, -1, 6, -1, -1, -1}, {-1, -1, -1, 5, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, -1, 1, -1, -1, -1}, {-1, -1, -1, -1, 3, -1, -1, -1}, { 6, 1, 3, 1, 2, 1, 4, 1}, {-1, -1, -1, -1, 6, -1, -1, -1}, {-1, -1, -1, 4, 1, -1, -1, -1}, {-1, -1, 1, -1, 3, -1, -1, -1}, {-1, -1, -1, 2, 1, -1, -1, -1}, {-1, -1, -1, -1, 4, -1, -1, -1}, {-1, -1, -1, 6, 1, -1, -1, -1}, {-1, -1, -1, 6, -1, -1, -1, -1}}, {{-1, -1, -1, 5, 4, -1, -1, -1}, {-1, -1, 4, 1, 0, -1, -1, -1}, {-1, -1, -1, 2, 3, -1, -1, -1}, {-1, 1, 4, -1, 2, 2, -1, -1}, {-1, 3, 1, 2, 5, 1, 4, -1}, {-1, 4, 2, -1, 0, 4, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, -1, 1, -1, -1, -1}, {-1, -1, -1, 1, -1, -1, -1, -1}, {-1, 2, -1, -1, 1, -1, 5, -1}, { 5, -1, -1, 1, -1, -1, 0, -1}, {-1, 6, -1, -1, 1, -1, 4, -1}, {-1, 0, -1, 1, -1, 5, -1, -1}, {-1, -1, 5, 5, 0, 1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, 6, 3, -1, -1, -1}, {-1, -1, 3, 2, 6, -1, -1, -1}, {-1, -1, 2, 6, 3, 2, -1, -1}, {-1, 6, 3, 2, 6, 3, -1, -1}, {-1, 3, 2, 6, 3, 2, 6, -1}, { 2, 6, 3, 2, 6, 3, 2, -1}, { 6, 3, 2, 6, 3, 2, 6, 3}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 6, 6, 6, 6, 6, 6, 6, 6}, { 4, -1, -1, -1, -1, -1, -1, -1}, {-1, 3, 2, 5, 7, 6, 4, 3}, {-1, 5, -1, -1, -1, -1, -1, -1}, {-1, -1, 7, 6, 4, 3, 2, 5}, {-1, -1, 4, -1, -1, -1, -1, -1}, {-1, -1, -1, 3, 2, 5, 7, 6}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 1, -1, 7, -1, -1, 6, -1, 2}, { 6, -1, 1, -1, 6, 1, 3, -1}, {-1, 4, -1, 7, 2, -1, 7, -1}, { 2, 7, -1, -1, -1, 4, -1, -1}, { 6, -1, 3, 5, 0, 2, -1, 7}, { 1, -1, -1, -1, -1, -1, 1, -1}, {-1, 1, 4, 5, 7, 5, 1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 6, 6, 6, -1, -1, 6, 6, 6}, {-1, -1, 6, -1, 6, -1, -1, -1}, {-1, -1, 2, 3, 3, 2, -1, -1}, {-1, 3, -1, 5, -1, 3, -1, -1}, {-1, -1, 5, 3, 3, 5, -1, -1}, {-1, -1, 6, 1, 6, -1, -1, -1}, {-1, 4, 2, -1, -1, 2, 4, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, 5, 5, -1, -1, -1}, {-1, -1, 5, -1, -1, -1, -1, -1}, {-1, 3, 4, 6, 6, -1, -1, 5}, { 3, 3, 4, 6, 5, -1, 5, -1}, { 3, 2, 3, 6, 6, 5, 5, -1}, { 3, 3, 4, 6, 5, -1, 5, -1}, {-1, 3, 4, 6, 6, -1, -1, 5}, {-1, -1, 5, -1, -1, -1, -1, -1}, {-1, -1, -1, 5, 5, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 1, -1, -1, -1, -1, -1, -1, 1}, { 1, -1, 2, 2, 2, -1, 1, -1}, {-1, 1, 2, 3, 3, 2, 1, -1}, { 6, 2, 3, -1, 3, 2, 6, -1}, { 6, 2, 3, -1, -1, 3, 2, 6}, { 6, 2, 3, -1, 3, 2, 6, -1}, { 3, 3, 3, 7, 7, 3, 3, 3}, { 0, 5, 0, 2, 0, 5, 0, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, 7, 7, 7, -1, -1, -1}, {-1, 7, 2, 2, 7, -1, -1, -1}, {-1, 7, 5, 5, 5, 7, -1, -1}, { 7, 7, 7, 7, 7, 7, -1, -1}, {-1, -1, 6, -1, 6, -1, -1, -1}, {-1, 6, -1, -1, 6, -1, -1, -1}, {-1, 6, 4, 4, -1, 6, 4, 4}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 3, 3, -1, 3, 3, 3, -1}, { 3, 7, 5, 4, 6, 5, 3, -1}, { 1, 3, 3, 3, -1, 3, 3, 1}, { 2, 1, 2, 1, 2, 1, 2, -1}, { 1, 3, 3, -1, 3, 3, 3, 1}, { 3, 5, 6, 4, 5, 7, 3, -1}, { 2, 3, 3, 3, -1, 3, 3, 2}, { 1, 1, 2, 2, 2, 1, 1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 6, 5, -1, -1, -1, -1, -1}, { 3, 1, 3, -1, -1, -1, -1, -1}, {-1, 5, 6, -1, -1, -1, -1, -1}, {-1, -1, 5, 3, -1, -1, -1, -1}, {-1, -1, 6, 1, 6, -1, -1, -1}, {-1, -1, 3, 5, -1, -1, -1, -1}, {-1, -1, -1, -1, 3, 6, -1, -1}, {-1, -1, -1, 5, 6, 5, -1, -1}, {-1, -1, -1, -1, 6, 3, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 6, 3, 7, 4, 5, 1, 6, 3}, { 5, 1, 6, 3, 7, 4, 5, -1}, { 6, 3, 7, 4, 5, 1, 6, 3}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, -1, -1, -1, 4, 4}, {-1, -1, 7, 7, 7, 4, 4, -1}, {-1, -1, -1, -1, -1, -1, 4, 4}, {-1, 1, -1, -1, -1, 7, -1, -1}, {-1, 1, 1, -1, -1, 7, -1, -1}, { 3, 3, 3, -1, 7, -1, -1, -1}, { 3, -1, 2, 3, 3, 3, -1, 3}, {-1, 2, -1, 3, -1, 3, 3, -1}, {-1, 2, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, 4, -1, -1, -1, -1, -1}, {-1, 7, 4, -1, -1, -1, -1, -1}, {-1, -1, 7, 4, -1, -1, -1, -1}, {-1, 4, 7, 4, -1, -1, -1, -1}, { 1, 1, 1, 1, 1, 1, 1, -1}, { 1, 2, 1, 2, 1, 1, -1, -1}, { 2, 2, 2, 2, 2, 2, 2, 2}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 0, -1, -1, -1, -1, -1, -1, 6}, { 6, 1, 4, 3, 7, 5, 0, -1}, { 0, -1, -1, -1, -1, -1, -1, 6}, { 6, 1, 4, 3, 7, 5, 0, -1}, { 0, -1, -1, -1, -1, -1, -1, 6}, { 6, 1, 4, 3, 7, 5, 0, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 3, 3, 4, 6, 6, 4, 3, 3}, { 0, 3, 4, 6, 4, 3, 1, -1}, { 5, 1, 3, 4, 4, 3, 0, 1}, { 0, 1, 3, 4, 3, 1, 0, -1}, { 2, 1, 6, 3, 3, 0, 0, 1}, { 0, 3, 4, 3, 6, 1, 5, -1}, { 6, 1, 2, 6, 4, 0, 0, 2}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 6, 6, -1, -1, -1, -1, 4, 4}, { 4, 0, -1, -1, -1, 3, 6, -1}, { 0, 6, -1, -1, -1, -1, 4, 2}, { 7, -1, -1, -1, -1, -1, 7, -1}, { 4, 4, -1, -1, -1, -1, 5, 6}, { 6, 4, 7, 7, 5, 6, 4, -1}, {-1, 7, 6, 4, 6, 4, 7, -1}, {-1, 0, -1, 7, -1, 7, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 5, -1, -1, -1, -1, 4, -1}, {-1, 5, -1, -1, -1, 4, -1, -1}, {-1, -1, 5, 6, 6, 4, -1, -1}, {-1, -1, 2, -1, 2, -1, -1, -1}, { 0, 0, 6, -1, -1, 6, 1, 1}, {-1, -1, 2, -1, 2, -1, -1, -1}, {-1, -1, 7, 6, 6, 3, -1, -1}, {-1, 7, -1, -1, -1, 3, -1, -1}, {-1, 7, -1, -1, -1, -1, 3, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 6, -1, -1, -1, -1, 2, -1}, { 1, 7, 1, 1, 1, 3, 1, -1}, {-1, -1, 4, 1, 1, 4, -1, -1}, {-1, 1, 3, 1, 7, 1, -1, -1}, {-1, -1, -1, 2, 6, -1, -1, -1}, {-1, -1, 1, 5, 1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 7, 7, 7, 7, 7, 7, 7, 7}, { 7, -1, -1, -1, -1, -1, 7, -1}, { 7, -1, -1, 2, 0, 5, 2, 2}, { 7, -1, -1, -1, 0, 3, 6, -1}, { 7, -1, -1, -1, -1, -1, 4, 0}, { 5, 5, -1, -1, -1, -1, -1, -1}, { 4, 3, 6, 2, -1, -1, -1, -1}, { 0, 2, 0, 4, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, 1, -1, -1, 1, -1, -1}, {-1, 4, -1, -1, 5, -1, -1, -1}, {-1, 7, -1, -1, 1, 1, 1, -1}, { 6, -1, -1, -1, -1, 7, -1, -1}, { 1, 1, 1, 1, -1, 4, -1, -1}, {-1, -1, 5, -1, -1, -1, -1, -1}, {-1, -1, 0, -1, -1, -1, -1, -1}, {-1, 3, -1, -1, -1, -1, -1, -1}, {-1, 1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 7, 7, -1, -1, 7, 7, -1}, { 6, -1, 4, -1, 4, -1, 6, -1}, { 5, -1, -1, 3, 3, -1, -1, 5}, { 6, -1, -1, -1, -1, -1, 6, -1}, {-1, 7, -1, -1, -1, -1, 7, -1}, {-1, 4, -1, -1, -1, 4, -1, -1}, {-1, -1, 3, -1, -1, 3, -1, -1}, {-1, -1, 2, -1, 2, -1, -1, -1}, {-1, -1, -1, 5, 5, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 0, 0, -1, -1, 0, 0, -1}, { 7, 4, 6, 6, 6, 4, 3, -1}, { 5, 6, 6, 6, 2, 6, 6, 3}, { 7, 4, 6, 6, 6, 4, 3, -1}, {-1, 0, 0, -1, -1, 0, 0, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, -1, -1, 7, 7, 7}, {-1, -1, -1, -1, 2, 7, 7, -1}, {-1, 0, 7, 7, 7, -1, 7, 7}, { 6, 7, 7, 7, -1, -1, -1, -1}, { 6, -1, -1, -1, 7, 7, 7, 7}, { 6, -1, -1, -1, -1, -1, -1, -1}, { 4, 2, 2, 2, 4, -1, 3, -1}, { 4, 4, 4, 4, 3, 3, 3, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 4, -1, -1, 7, -1, 6, -1, 7}, { 7, 6, 7, -1, -1, 7, 4, -1}, {-1, -1, 7, -1, -1, 7, -1, -1}, {-1, 0, 0, 0, 0, 0, 3, -1}, {-1, -1, 0, 2, 2, 0, 6, 4}, {-1, -1, 0, 0, 0, 1, 3, -1}, {-1, -1, -1, 0, 0, -1, 3, 4}, {-1, -1, -1, 6, -1, 5, 6, -1}, {-1, -1, -1, -1, -1, -1, 1, 0}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 5, -1, -1, -1, -1, 5, -1}, { 0, -1, -1, 0, -1, -1, 0, -1}, { 0, 0, 0, 2, 2, 0, 0, 0}, { 0, -1, -1, 0, -1, -1, 0, -1}, {-1, 7, -1, 3, -1, -1, 7, -1}, {-1, -1, 3, 6, -1, -1, -1, -1}, {-1, -1, -1, 6, -1, -1, -1, -1}, {-1, 3, 6, -1, -1, -1, -1, -1}, {-1, 3, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, 6, 5, -1, -1, -1}, {-1, -1, 2, 6, 3, -1, -1, -1}, {-1, -1, 5, 4, 7, 1, -1, -1}, {-1, 6, 2, 2, 3, 4, -1, -1}, {-1, -1, 3, 7, 3, 6, -1, -1}, {-1, -1, 1, 3, 2, -1, -1, -1}, {-1, -1, -1, 4, 5, -1, -1, -1}, {-1, -1, -1, 4, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 7, 7, -1, 2, 2, -1, 6, 6}, { 6, -1, -1, 6, -1, -1, 3, -1}, { 2, -1, -1, 1, -1, -1, 2, -1}, { 5, -1, -1, 3, -1, -1, 2, -1}, { 1, -1, -1, 2, -1, -1, 1, -1}, { 5, -1, -1, 2, -1, -1, 2, -1}, { 6, -1, -1, 1, -1, -1, 7, -1}, { 5, -1, -1, 5, -1, -1, 4, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, 6, 6, -1, -1, -1}, {-1, 0, 4, 4, 4, 0, -1, -1}, {-1, -1, -1, 6, 6, -1, -1, -1}, {-1, -1, 2, 7, 2, -1, -1, -1}, {-1, -1, -1, 6, 6, -1, -1, -1}, {-1, 0, 5, 5, 5, 0, -1, -1}, {-1, -1, -1, 3, 3, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, 4, 1, 3, -1, -1, -1}, {-1, 1, -1, -1, 1, -1, -1, -1}, {-1, -1, 4, 1, 3, 4, 1, -1}, {-1, 1, 3, 4, -1, -1, 4, -1}, {-1, 3, -1, -1, 3, 4, 1, -1}, {-1, 1, 3, 4, 1, 3, -1, -1}, {-1, -1, 4, 1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 6, 4, -1, 3, 2, 5, -1}, { 0, -1, -1, -1, -1, -1, 1, -1}, {-1, 2, 3, 5, -1, 4, 6, -1}, { 0, -1, -1, -1, -1, -1, 1, -1}, {-1, 4, 6, -1, 2, 5, 3, -1}, { 0, -1, -1, -1, -1, -1, 1, -1}, {-1, 5, 2, 3, -1, 4, 6, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, 6, 6, -1, -1, -1}, {-1, -1, 7, 6, 4, -1, -1, -1}, {-1, 2, 1, 7, 4, 1, 3, -1}, { 2, 1, 1, 1, 1, 1, 3, -1}, {-1, 2, 2, 2, 3, 3, 3, -1}, {-1, -1, -1, 5, -1, -1, -1, -1}, {-1, -1, -1, 2, 3, -1, -1, -1}, {-1, -1, -1, 5, -1, -1, -1, -1}, {-1, -1, 2, 2, 3, 3, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 4, -1, 5, -1, -1, 3, -1, 6}, { 2, -1, 3, -1, 2, -1, 4, -1}, { 4, -1, -1, 1, 0, -1, -1, 6}, { 6, -1, 2, 3, 5, -1, 4, -1}, { 4, -1, -1, 0, 1, -1, -1, 6}, { 2, -1, 5, -1, 3, -1, 4, -1}, { 4, -1, 3, -1, -1, 2, -1, 6}, { 6, -1, -1, -1, -1, -1, 4, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 2, 6, 0, 5, 5, 1, 3, 4}, { 1, -1, -1, 2, -1, -1, 0, -1}, { 4, -1, -1, 3, 6, -1, -1, 2}, {-1, -1, -1, 0, -1, -1, -1, -1}, {-1, -1, -1, 1, 4, -1, -1, -1}, {-1, -1, -1, 2, -1, -1, -1, -1}, {-1, -1, -1, 6, 3, -1, -1, -1}, {-1, -1, -1, 5, -1, -1, -1, -1}, {-1, -1, -1, 4, 1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, -1, 5, 1, 1, 3}, { 0, 5, 1, 0, 5, 3, 3, -1}, { 5, 1, 0, 5, 1, 0, 5, 1}, { 0, 5, 1, 0, 5, 1, 6, -1}, {-1, -1, -1, -1, 1, 6, 5, 1}, {-1, -1, -1, -1, 5, 1, 6, -1}, {-1, -1, -1, -1, 1, 0, 5, 1}, {-1, -1, -1, -1, 5, 1, 0, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 0, 7, 3, -1, -1, 2, 2}, {-1, 0, 7, 3, -1, -1, 2, -1}, {-1, 0, 7, 3, -1, -1, 2, 2}, {-1, 0, 7, 3, -1, 3, 1, -1}, {-1, 0, 7, 3, -1, 6, 4, 5}, {-1, 0, 7, 3, -1, 7, 0, -1}, {-1, 0, 7, 3, -1, 2, 3, 4}, {-1, 0, 7, 3, -1, 5, 6, -1}, {-1, -1, -1, -1, -1, 7, 0, 1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, 7, 7, 7, 7, -1}, { 3, 4, 5, -1, -1, -1, 7, -1}, { 2, -1, -1, -1, -1, -1, -1, 3}, { 7, -1, -1, -1, -1, -1, 4, -1}, { 7, -1, -1, -1, 3, 4, 5, 6}, { 7, -1, -1, 2, 0, 1, 2, -1}, { 6, -1, -1, -1, 3, 4, 5, 6}, { 0, 1, -1, -1, -1, -1, -1, -1}, { 2, 3, 4, -1, -1, -1, -1, -1}, { 5, 6, 0, -1, -1, -1, -1, -1}}, {{-1, 7, -1, -1, -1, -1, 2, -1}, { 1, 1, -1, -1, -1, 3, 3, -1}, {-1, 2, -1, -1, -1, -1, 4, -1}, { 3, 3, -1, -1, -1, 5, 5, -1}, {-1, 4, -1, -1, -1, -1, 6, -1}, { 5, 5, -1, -1, -1, 1, 1, -1}, {-1, 6, -1, -1, -1, -1, 7, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 4, -1, -1, -1, -1, 4, -1}, { 2, -1, -1, 1, -1, -1, 2, -1}, { 5, -1, -1, 0, 0, -1, -1, 5}, { 5, -1, -1, 1, -1, -1, 6, -1}, {-1, 4, 2, 7, 7, 5, 4, -1}, {-1, -1, -1, 6, -1, -1, -1, -1}, {-1, -1, -1, 3, 3, -1, -1, -1}, {-1, -1, -1, 7, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 1, -1, -1, 2, 3, 4, -1}, { 2, -1, -1, 3, 0, 4, -1, -1}, { 4, -1, -1, 2, 3, 1, -1, -1}, { 3, -1, 4, 3, 0, -1, -1, -1}, { 4, -1, -1, 2, 5, 1, -1, -1}, { 3, -1, 4, 5, 0, 4, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 2, -1, -1, 1, 1, -1, -1, 2}, { 2, -1, 3, 3, 3, -1, 2, -1}, {-1, 2, -1, 4, 4, -1, 2, -1}, {-1, 7, 7, 0, 7, 7, -1, -1}, {-1, -1, -1, 4, 4, -1, -1, -1}, {-1, -1, 5, 7, 5, -1, -1, -1}, { 6, 3, 2, 6, 4, 2, 3, 6}, { 5, -1, -1, -1, -1, -1, 1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 4, 2, 3, 5, 7, 1, 3, 6}, { 1, -1, -1, 1, -1, -1, 1, -1}, { 3, 0, 1, 3, 2, 4, 3, 5}, { 4, -1, -1, 4, -1, -1, 4, -1}, {-1, 5, -1, -1, 5, -1, -1, 5}, { 0, 3, 2, 0, 4, 5, 0, -1}, {-1, 6, -1, -1, 6, -1, -1, 6}, { 7, -1, -1, 7, -1, -1, 7, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 5, 4, -1, 1, 1, -1, -1}, { 5, -1, 4, 1, -1, 1, -1, -1}, { 0, -1, -1, -1, -1, -1, 0, -1}, { 0, 6, 4, -1, -1, 4, 2, -1}, {-1, 4, 3, 5, 2, 6, 3, 6}, {-1, 2, 6, -1, -1, 5, 4, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, 6, 6, -1, -1, -1}, {-1, -1, 5, 5, 4, -1, -1, -1}, {-1, -1, 1, 6, 6, 4, -1, -1}, {-1, 1, 7, 2, 5, 3, -1, -1}, {-1, 2, 7, 2, 1, 5, 3, -1}, { 2, 1, 3, 1, 4, 2, 7, -1}, {-1, 3, 1, 3, 4, 2, 7, -1}, {-1, 3, 5, 5, 6, 6, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, 7, 3, -1, -1, -1, -1}, {-1, 1, 7, 6, -1, -1, -1, -1}, {-1, 3, 7, 5, 1, 5, -1, -1}, { 7, 7, 0, 2, 4, 0, 4, -1}, { 7, 1, 4, 6, 5, 6, 5, 7}, { 1, 7, 7, 1, 7, 7, 1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, 1, -1, -1, 1, -1, -1}, {-1, 5, 6, 1, 5, 6, -1, -1}, {-1, 1, 1, 2, 2, 1, 1, -1}, { 4, 7, 1, 0, 1, 7, 4, -1}, {-1, 3, 7, 5, 7, 5, 3, -1}, {-1, 1, 1, 1, 1, 1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 4, -1, -1, -1, 5, -1, -1, 4}, { 6, 6, 7, 6, -1, 4, 5, -1}, { 4, 2, 7, 5, 2, 2, 6, 4}, {-1, -1, 4, 1, -1, 5, 2, -1}, {-1, 5, 2, 7, 7, -1, 7, 4}, { 4, 6, 5, 4, -1, 4, 2, -1}, {-1, -1, -1, 4, -1, 4, 1, -1}, { 0, 0, 0, 5, -1, -1, -1, -1}, {-1, -1, -1, -1, 0, 0, 0, 0}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 1, -1, -1, -1, 0, 0, -1, -1}, { 2, -1, -1, 0, 1, 0, -1, -1}, { 3, -1, -1, 0, 2, 2, 0, -1}, { 4, -1, 0, 1, 1, 1, 0, -1}, { 5, -1, -1, 0, 4, 4, 0, -1}, { 6, -1, -1, 4, 4, 4, -1, -1}, { 7, -1, -1, -1, 4, 4, -1, -1}, {-1, -1, -1, 0, 1, 0, -1, -1}, {-1, -1, -1, 0, 1, 1, 0, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, 3, -1, -1, 1, 7, -1}, {-1, 7, 4, -1, -1, 4, 3, -1}, { 1, -1, -1, 0, 2, 0, -1, -1}, { 5, 4, -1, 3, -1, -1, -1, -1}, { 4, -1, 3, 6, 1, 1, 6, -1}, {-1, 1, -1, -1, 4, -1, 1, -1}, {-1, 7, 5, -1, -1, -1, 3, -1}, {-1, -1, 3, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 1, -1, -1, -1, 1, -1, -1, -1}, { 2, -1, -1, -1, 2, -1, -1, -1}, {-1, 3, -1, -1, 3, 3, -1, -1}, {-1, 4, -1, 4, -1, 4, -1, -1}, {-1, 5, -1, -1, 5, 5, -1, -1}, { 6, -1, -1, 7, 1, 7, -1, -1}, { 7, -1, -1, -1, 6, 6, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 2, -1, -1, 6, -1, 2, 5, 1}, { 5, -1, 4, -1, 4, -1, 4, -1}, { 6, -1, -1, 3, -1, -1, -1, 3}, { 4, 2, 0, -1, -1, -1, 5, -1}, {-1, -1, -1, 6, -1, 3, 6, -1}, {-1, -1, 5, -1, 5, -1, -1, -1}, {-1, -1, -1, 3, -1, 4, 2, 5}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 6, -1, -1, -1, 4, -1, -1, 3}, { 0, 3, -1, -1, 6, -1, 0, -1}, {-1, -1, 7, -1, 1, -1, 3, -1}, { 7, -1, 4, 7, -1, 2, -1, -1}, { 5, 2, 3, 2, 1, 6, -1, 3}, {-1, -1, 0, 4, 3, 5, 4, -1}, {-1, 7, 6, -1, -1, 0, -1, -1}, { 4, 3, -1, -1, -1, 4, 2, -1}, { 0, -1, -1, -1, -1, -1, 6, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 6, 1, 2, 5, 1, 6, 3, 0}, {-1, -1, -1, -1, -1, -1, 4, -1}, { 0, 5, 2, 7, 1, 6, 2, -1}, { 3, -1, -1, -1, -1, -1, -1, -1}, { 6, 7, 6, 4, 0, 5, 2, 6}, {-1, -1, -1, -1, -1, -1, 1, -1}, { 6, 1, 4, 0, 6, 2, 3, -1}, { 0, -1, -1, -1, -1, -1, -1, -1}, {-1, 0, 4, 5, 3, 7, 6, 0}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, 0, 1, -1, -1, -1}, {-1, -1, 0, 7, 0, -1, -1, -1}, {-1, -1, 1, 2, 2, 0, -1, -1}, {-1, 0, 7, 0, 7, 0, -1, -1}, {-1, 6, -1, 7, 7, -1, 6, -1}, { 4, 1, 6, 6, 6, 4, 1, -1}, {-1, 5, -1, 7, 7, -1, 5, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, 5, 6, -1, -1, -1}, {-1, -1, 3, 3, 3, -1, -1, -1}, {-1, -1, 7, 5, 3, 7, -1, -1}, {-1, 3, -1, 6, -1, 3, -1, -1}, { 2, -1, -1, 3, 7, -1, -1, 1}, { 2, 2, -1, 3, -1, 1, 1, -1}, {-1, 0, 2, 5, 6, 1, 0, -1}, {-1, -1, -1, 3, -1, -1, -1, -1}, {-1, -1, -1, 3, 7, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 6, -1, -1, -1, -1, 2, -1}, {-1, 2, 6, 0, 6, 0, -1, -1}, {-1, 0, -1, -1, -1, -1, -1, -1}, { 6, -1, -1, -1, -1, -1, -1, -1}, {-1, 3, 3, 2, 0, 6, 0, 0}, {-1, 6, -1, -1, -1, -1, 0, -1}, {-1, -1, -1, 6, 0, 2, 6, -1}, {-1, 2, 0, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 0, 7, -1, -1, -1, -1, -1, -1}, { 1, 5, -1, -1, -1, -1, -1, -1}, { 7, 2, 5, -1, -1, -1, -1, -1}, { 6, 3, 4, -1, -1, -1, -1, -1}, { 5, 5, 4, 4, -1, -1, -1, -1}, { 3, 3, 5, 3, -1, -1, -1, -1}, { 1, 2, 2, 5, 3, -1, -1, -1}, { 1, 0, 0, 7, 6, -1, -1, -1}, { 3, 3, 5, 5, 7, 6, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, 2, 6, 6, 2, -1, -1}, {-1, 2, 1, 1, 0, 2, -1, -1}, {-1, 2, 3, 2, 2, 0, 2, -1}, { 2, 3, 2, 5, 2, 7, 2, -1}, { 2, 4, 2, 5, 2, 7, 2, 0}, { 2, 4, 2, 6, 6, 2, 0, -1}, {-1, 2, 5, 2, 2, 2, 7, 2}, {-1, 2, 5, 6, 6, 7, 2, -1}, {-1, -1, 2, 2, 2, 2, 2, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, 0, -1, -1, 0, -1, -1}, { 1, 0, 0, 1, 0, 0, 1, -1}, { 1, 7, 7, 5, 5, 7, 7, 1}, { 3, 2, -1, 2, -1, 2, 3, -1}, { 3, 7, -1, 6, 6, -1, 7, 3}, { 7, -1, -1, 6, -1, -1, 7, -1}, { 4, 4, 5, -1, -1, 5, 4, 4}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 6, 3, -1, -1, 3, 6, -1}, { 6, -1, 2, -1, 2, -1, 6, -1}, { 2, -1, 0, 1, 1, 0, -1, 2}, { 5, 0, -1, 7, -1, 0, 5, -1}, {-1, 5, -1, 6, 6, -1, 5, -1}, { 7, 1, 4, -1, 4, 1, 7, -1}, { 7, -1, 4, -1, -1, 4, -1, 7}, { 2, 0, -1, -1, -1, 0, 2, -1}, {-1, 2, -1, -1, -1, -1, 2, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 6, 1, -1, -1, -1, -1, 4, 0}, { 2, 7, 5, 5, 5, 7, 3, -1}, { 6, 1, -1, -1, -1, -1, 4, 0}, { 2, 5, 7, 7, 7, 5, 3, -1}, { 6, 1, -1, -1, -1, -1, 4, 0}, { 2, 0, 6, 6, 6, 0, 3, -1}, { 6, 1, -1, -1, -1, -1, 4, 0}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 5, -1, -1, 1, 1, -1, -1, 5}, { 5, -1, 4, -1, 4, -1, 5, -1}, {-1, 2, 4, -1, -1, 4, 2, -1}, { 7, 2, -1, -1, -1, 2, 7, -1}, { 0, -1, 0, 4, 4, 0, -1, 0}, { 7, 2, -1, -1, -1, 2, 7, -1}, {-1, 2, 3, -1, -1, 3, 2, -1}, { 5, -1, 3, -1, 3, -1, 5, -1}, { 5, -1, -1, 6, 6, -1, -1, 5}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 2, 2, -1, -1, -1, -1, 5, 5}, { 5, -1, -1, -1, -1, -1, 2, -1}, { 5, -1, -1, -1, -1, -1, -1, 2}, { 1, -1, 1, 5, 1, -1, 3, -1}, { 5, 2, 5, 3, 1, 2, 5, 2}, { 2, 0, 5, -1, 2, 0, 5, -1}, {-1, 3, 7, -1, -1, 3, 7, -1}, {-1, -1, 2, 0, 5, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 0, 6, 5, 2, 3, 4, 1, 7}, {-1, -1, -1, -1, 1, -1, -1, -1}, {-1, -1, -1, 1, 1, -1, -1, -1}, {-1, -1, 1, -1, -1, -1, -1, -1}, { 7, 1, 4, 3, 2, 5, 6, 0}, {-1, -1, -1, -1, 1, -1, -1, -1}, {-1, -1, -1, 1, 1, -1, -1, -1}, {-1, -1, 1, -1, -1, -1, -1, -1}, { 0, 6, 5, 2, 3, 4, 1, 7}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, 1, -1, -1, 1, -1, -1}, {-1, 2, 4, -1, 2, 4, -1, -1}, {-1, 2, 3, 6, 5, 3, 2, -1}, {-1, 6, 5, -1, 6, 5, -1, -1}, {-1, -1, -1, 7, 7, -1, -1, -1}, {-1, -1, -1, 7, -1, -1, -1, -1}, { 1, -1, -1, 7, 7, -1, -1, 3}, { 2, -1, -1, 7, -1, -1, 2, -1}, {-1, 3, 4, 5, 6, 4, 1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 1, -1, -1, 2, 2, -1, -1, 2}, { 1, 3, 7, 3, 7, 4, 2, -1}, {-1, 1, 6, -1, -1, 6, 2, -1}, { 6, -1, 7, 3, 7, -1, 6, -1}, {-1, 4, 2, -1, -1, 1, 3, -1}, {-1, -1, 2, 6, 1, -1, -1, -1}, {-1, 4, 3, 3, 4, 4, 3, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, -1, -1, 5, 6, -1, -1, -1}, {-1, -1, -1, 3, -1, -1, -1, -1}, {-1, -1, -1, 1, 2, -1, -1, -1}, {-1, -1, -1, 4, -1, -1, -1, -1}, {-1, -1, -1, 5, 7, -1, -1, -1}, {-1, -1, -1, 2, -1, -1, -1, -1}, { 6, 5, 4, 3, 2, 1, 7, 5}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{-1, 0, -1, 1, -1, 2, -1, -1}, {-1, 4, -1, 5, -1, 6, -1, -1}, {-1, 7, -1, 0, -1, 2, -1, -1}, {-1, 6, -1, 3, -1, 6, -1, -1}, {-1, 1, -1, 1, -1, 2, -1, -1}, {-1, 3, -1, 5, -1, 0, -1, -1}, {-1, 2, -1, 4, -1, 6, -1, -1}, {-1, 3, -1, 6, -1, 7, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 1, 1, 2, 2, 3, 3, 4, 4}, { 5, 5, 6, 7, 6, 5, 5, -1}, { 6, 4, 3, 3, 2, 2, 1, 6}, { 4, 6, 5, 7, 6, 3, 1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 7, 4, -1, 1, 2, -1, 4, 7}, { 5, 5, -1, 2, -1, 4, 4, -1}, {-1, 5, -1, 7, 7, -1, 4, -1}, { 1, 0, 6, 7, 6, 0, 2, -1}, {-1, 2, -1, 5, 3, -1, 1, -1}, { 1, 1, -1, -1, -1, 2, 2, -1}, { 6, 1, 4, -1, -1, 4, 2, 6}, { 5, 3, -1, -1, -1, 3, 5, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 1, 5, 1, 0, 0, 1, 5, 1}, { 1, 2, 5, -1, 5, 2, 1, -1}, { 3, 6, 1, 2, 2, 1, 6, 3}, { 4, 3, 4, -1, 4, 3, 4, -1}, { 3, 4, 6, 5, 5, 6, 4, 3}, { 0, 2, 3, -1, 3, 2, 0, -1}, { 2, 3, 1, 5, 5, 1, 3, 2}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}, {{ 3, 0, 2, 7, 5, 7, 6, 5}, { 6, -1, 1, -1, 2, -1, 1, -1}, {-1, 6, 4, 0, 3, 4, 5, -1}, {-1, 5, -1, 1, -1, 4, -1, -1}, {-1, 7, 3, 5, 6, 5, 3, -1}, { 1, -1, 2, -1, 4, -1, 2, -1}, { 6, 4, 4, 6, 6, 5, 5, 1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}, {-1, -1, -1, -1, -1, -1, -1, -1}}};
/* the tile struct * type is the bubble number 0-7 * fallx is the x axis movement for the falling bubble * fallvel is the initial upward velocity for the falling bubble * ingroup denotes a bubble that is part of a group to be removed * anchored denotes a bubble that is anchored to the ceiling */struct tile { int type; int fallx; int fallvel; bool ingroup; bool anchored; bool delete;};
/* the game context struct * score is the current score * level is the current level * angle is the current cannon direction * shots is the number of shots fired since last compression * compress is the height of the compressor * onboardcnt is the number of unique bubbles on the playing board * onboard is the unique bubbles on the playing board * nextinq is the pointer to the next bubble in the firing queue * queue is the circular buffer of bubbles to be fired * elapsedlvl is level elapsed time in 1/100s of seconds * elapsedshot is the shot elapsed time in 1/100s of seconds * startedshot is when the current shot began * playboard is the game playing board */struct game_context { unsigned int score; unsigned int level; int angle; int shots; int compress; int onboardcnt; int onboard[NUM_BUBBLES]; int nextinq; int queue[NUM_QUEUE]; long elapsedlvl; long elapsedshot; long startedshot; struct tile playboard[BB_HEIGHT][BB_WIDTH];};
static struct highscore highscores[NUM_SCORES];
/* used to denote available resume info */static bool resume = false;static bool resume_file = false;static unsigned int highlevel = 0; /* the highest level beaten */static unsigned int last_highlevel = 0;
static void bubbles_init(struct game_context* bb);static bool bubbles_nextlevel(struct game_context* bb);static void bubbles_getonboard(struct game_context* bb);static void bubbles_drawboard(struct game_context* bb);static int bubbles_fire(struct game_context* bb);static bool bubbles_collision(struct game_context* bb, int y, int x, int nearrow, int nearcol);static bool bubbles_ingroup(struct game_context* bb, int row, int col);static int bubbles_searchgroup(struct game_context* bb, int row, int col);static int bubbles_remove(struct game_context* bb);static void bubbles_anchored(struct game_context* bb, int row, int col);static int bubbles_fall(struct game_context* bb);static int bubbles_checklevel(struct game_context* bb);static void bubbles_recordscore(struct game_context* bb);static bool bubbles_loadgame(struct game_context* bb);static void bubbles_savegame(struct game_context* bb);static inline void bubbles_setcolors(void);static void bubbles_callback(void* param);static int bubbles_handlebuttons(struct game_context* bb, bool animblock, int timeout);static int bubbles(struct game_context* bb);
/****************************************************************************** bubbles_init() initializes bubbles data structures.******************************************************************************/static void bubbles_init(struct game_context* bb) { bubbles_setcolors(); /* seed the rand generator */
/* check for resumed game */ if (resume) { resume = false; return; }
bb->score = 0; bubbles_nextlevel(bb);}
/****************************************************************************** bubbles_nextlevel() sets up the game for the next level, returns false if* there are no more levels.******************************************************************************/static bool bubbles_nextlevel(struct game_context* bb) { int i, j, pos;
bb->level++;
/* check if there are no more levels */ if(bb->level > NUM_LEVELS) return false;
/* save highest level */ if (bb->level-1 > highlevel) highlevel = bb->level-1;
/* set up the play board */ rb->memset(bb->playboard, 0, sizeof(bb->playboard)); for(i=0; i<BB_LEVEL_HEIGHT; i++) { for(j=0; j<BB_WIDTH; j++) { pos = (int)level[bb->level-1][i][j]; if(pos >=0 && pos < NUM_BUBBLES) { bb->playboard[i][j].type = pos; } else { bb->playboard[i][j].type = -1; } } } for(i=BB_LEVEL_HEIGHT; i<BB_HEIGHT; i++) { for(j=0; j<BB_WIDTH; j++) { bb->playboard[i][j].type = -1; } }
/* fill first bubbles in shot queue */ bubbles_getonboard(bb); for(i=0; i<NUM_QUEUE; i++) { bb->queue[i] = bb->onboard[rb->rand()%bb->onboardcnt]; }
bb->angle = 0; bb->shots = 0; bb->compress = 0; bb->nextinq = 0; bb->elapsedlvl = 0; bb->elapsedshot = 0;
return true;}
/****************************************************************************** bubbles_getonboard() determines which bubble types are on the play board.******************************************************************************/static void bubbles_getonboard(struct game_context* bb) { int i, j, k; bool found;
bb->onboardcnt = 0; rb->memset(bb->onboard, -1, sizeof(bb->onboard));
for(i=0; i<BB_HEIGHT; i++) { for(j=0; j<BB_WIDTH; j++) { if(bb->playboard[i][j].type >= 0) { found = false;
for(k=0; k<bb->onboardcnt; k++) { if(bb->playboard[i][j].type == bb->onboard[k]) { found = true; break; } }
if(!found) { bb->onboard[bb->onboardcnt] = bb->playboard[i][j].type; bb->onboardcnt++; }
if(bb->onboardcnt == NUM_BUBBLES) return; } } }}
/****************************************************************************** bubbles_drawboard() draws the game board to the buffer but does not update* the lcd.******************************************************************************/static void bubbles_drawboard(struct game_context* bb) { int i, j; int w1, w2, h; int colmax, indent; int tipx, tipy; bool evenline = false; char *level = "Level"; char *score = "Score"; char *next = "Next"; char *hurry = "HURRY!"; char str[11];
/* clear screen */ rb->lcd_clear_display();#if ((LCD_HEIGHT >= 128) && (LCD_WIDTH <= 320)) || \ ((LCD_WIDTH == 132) && (LCD_HEIGHT == 80)) || \ ((LCD_WIDTH == 400) && (LCD_HEIGHT == 240)) h = rb->font_get(FONT_SYSFIXED)->height + 1;#elif (LCD_WIDTH == 640) && (LCD_HEIGHT == 480) h = rb->font_get(FONT_SYSFIXED)->height + 6;#else int font = rb->screens[SCREEN_MAIN]->getuifont(); h = rb->font_get(font)->height + 1;#endif /* draw background */#ifdef HAVE_LCD_COLOR#ifdef LAYOUT_X /* the layout's background, centred */ rb->lcd_bitmap(bubbles_background, LAYOUT_X, 0, LCD_WIDTH - 2 * LAYOUT_X, LCD_HEIGHT);#else rb->lcd_bitmap(bubbles_background, 0, 0, LCD_WIDTH, LCD_HEIGHT);#endif#endif
/* display play board */ for(i=0; i<BB_HEIGHT; i++) { colmax = BB_WIDTH; if(evenline) { colmax--; indent = ROW_INDENT; } else { indent = 0; } evenline = !evenline;
for(j=0; j<colmax; j++) { if(bb->playboard[i][j].type >= 0 && !bb->playboard[i][j].delete) { rb->lcd_bitmap_part(bubbles_emblem, 0, EMBLEM_HEIGHT*bb->playboard[i][j].type, STRIDE( SCREEN_MAIN, BMPWIDTH_bubbles_emblem, BMPHEIGHT_bubbles_emblem), XOFS+indent+BUBBLE_WIDTH*j+(BUBBLE_WIDTH-EMBLEM_WIDTH)/2, YOFS+ROW_HEIGHT*i+(BUBBLE_HEIGHT-EMBLEM_HEIGHT)/2+bb->compress*ROW_HEIGHT, EMBLEM_WIDTH, EMBLEM_HEIGHT); rb->lcd_set_drawmode(DRMODE_FG); rb->lcd_mono_bitmap((const unsigned char *)bubbles_bubble, XOFS+indent+BUBBLE_WIDTH*j, YOFS+ROW_HEIGHT*i+bb->compress*ROW_HEIGHT, BUBBLE_WIDTH, BUBBLE_HEIGHT); rb->lcd_set_drawmode(DRMODE_SOLID); } } }
/* display bubble to be shot */ rb->lcd_bitmap_part(bubbles_emblem, 0, EMBLEM_HEIGHT*bb->queue[bb->nextinq], STRIDE( SCREEN_MAIN, BMPWIDTH_bubbles_emblem, BMPHEIGHT_bubbles_emblem), SHOTX+(BUBBLE_WIDTH-EMBLEM_WIDTH)/2, SHOTY+(BUBBLE_HEIGHT-EMBLEM_HEIGHT)/2, EMBLEM_WIDTH, EMBLEM_HEIGHT); rb->lcd_set_drawmode(DRMODE_FG); rb->lcd_mono_bitmap((const unsigned char *)bubbles_bubble, SHOTX, SHOTY, BUBBLE_WIDTH, BUBBLE_HEIGHT); rb->lcd_set_drawmode(DRMODE_SOLID);
/* display next bubble to be shot */#ifndef NEXT_BB_X rb->lcd_bitmap_part(bubbles_emblem, 0, EMBLEM_HEIGHT*bb->queue[(bb->nextinq+1)%NUM_QUEUE], STRIDE( SCREEN_MAIN, BMPWIDTH_bubbles_emblem, BMPHEIGHT_bubbles_emblem), XOFS/2-BUBBLE_WIDTH/2+(BUBBLE_WIDTH-EMBLEM_WIDTH)/2, SHOTY+(BUBBLE_HEIGHT-EMBLEM_HEIGHT)/2, EMBLEM_WIDTH, EMBLEM_HEIGHT); rb->lcd_set_drawmode(DRMODE_FG); rb->lcd_mono_bitmap((const unsigned char *)bubbles_bubble, XOFS/2-BUBBLE_WIDTH/2, SHOTY, BUBBLE_WIDTH, BUBBLE_HEIGHT); rb->lcd_set_drawmode(DRMODE_SOLID);#else rb->lcd_bitmap_part(bubbles_emblem, 0, EMBLEM_HEIGHT*bb->queue[(bb->nextinq+1)%NUM_QUEUE], STRIDE( SCREEN_MAIN, BMPWIDTH_bubbles_emblem, BMPHEIGHT_bubbles_emblem), NEXT_BB_X + NEXT_BB_WIDTH/2-BUBBLE_WIDTH/2+(BUBBLE_WIDTH-EMBLEM_WIDTH)/2, NEXT_BB_Y + (BUBBLE_HEIGHT-EMBLEM_HEIGHT)/2 + h, EMBLEM_WIDTH, EMBLEM_HEIGHT); rb->lcd_set_drawmode(DRMODE_FG); rb->lcd_mono_bitmap((const unsigned char *)bubbles_bubble, NEXT_BB_X + NEXT_BB_WIDTH/2-BUBBLE_WIDTH/2, NEXT_BB_Y + h, BUBBLE_WIDTH, BUBBLE_HEIGHT); rb->lcd_set_drawmode(DRMODE_SOLID);#endif
/* draw bounding lines */#ifndef HAVE_LCD_COLOR rb->lcd_vline(XOFS-1, 0, LCD_HEIGHT); rb->lcd_vline(XOFS+BUBBLE_WIDTH*BB_WIDTH, 0, LCD_HEIGHT);#endif rb->lcd_hline(XOFS, XOFS+BUBBLE_WIDTH*BB_WIDTH-1, YOFS+bb->compress*ROW_HEIGHT-1); rb->lcd_hline(XOFS, XOFS+BUBBLE_WIDTH*BB_WIDTH-1, YOFS+ROW_HEIGHT*(BB_HEIGHT-2)+BUBBLE_HEIGHT);
/* draw arrow */ tipx = SHOTX+BUBBLE_WIDTH/2+(((fp14_sin(bb->angle)>>4)*BUBBLE_WIDTH*3/2)>>10); tipy = SHOTY+BUBBLE_HEIGHT/2-(((fp14_cos(bb->angle)>>4)*BUBBLE_HEIGHT*3/2)>>10);
rb->lcd_drawline(SHOTX+BUBBLE_WIDTH/2+(((fp14_sin(bb->angle)>>4)*BUBBLE_WIDTH/2)>>10), SHOTY+BUBBLE_HEIGHT/2-(((fp14_cos(bb->angle)>>4)*BUBBLE_HEIGHT/2)>>10), tipx, tipy); xlcd_filltriangle(tipx, tipy, tipx+(((fp14_sin(bb->angle-135)>>4)*BUBBLE_WIDTH/3)>>10), tipy-(((fp14_cos(bb->angle-135)>>4)*BUBBLE_HEIGHT/3)>>10), tipx+(((fp14_sin(bb->angle+135)>>4)*BUBBLE_WIDTH/3)>>10), tipy-(((fp14_cos(bb->angle+135)>>4)*BUBBLE_HEIGHT/3)>>10));
/* draw text */ rb->snprintf(str, 4, "%d", bb->level); rb->lcd_getstringsize(level, &w1, NULL); rb->lcd_getstringsize(str, &w2, NULL);#ifndef LEVEL_TXT_X rb->lcd_putsxy(XOFS/2-w1/2, 2, level); rb->lcd_putsxy(XOFS/2-w2/2, 2+h, str);#else rb->lcd_putsxy(LEVEL_TXT_X+(LEVEL_TXT_WIDTH/2-w1/2), LEVEL_TXT_Y, level); rb->lcd_putsxy(LEVEL_TXT_X+(LEVEL_TXT_WIDTH/2-w2/2), LEVEL_TXT_Y+h, str);#endif
rb->snprintf(str, 10, "%d", bb->score); rb->lcd_getstringsize(score, &w1,NULL); rb->lcd_getstringsize(str, &w2, NULL);#ifndef SCORE_TXT_X rb->lcd_putsxy(XOFS/2-w1/2, 29, score); rb->lcd_putsxy(XOFS/2-w2/2, 29+h, str);#else rb->lcd_putsxy(SCORE_TXT_X+(SCORE_TXT_WIDTH/2-w1/2), SCORE_TXT_Y, score); rb->lcd_putsxy(SCORE_TXT_X+(SCORE_TXT_WIDTH/2-w2/2), SCORE_TXT_Y+h, str);#endif
rb->lcd_getstringsize(next, &w1, NULL);#ifndef NEXT_BB_X rb->lcd_putsxy(XOFS/2-w1/2, SHOTY-h, next);#else rb->lcd_putsxy(NEXT_BB_X+(NEXT_BB_WIDTH/2-w1/2), NEXT_BB_Y, next);#endif
if(bb->elapsedshot >= (MAX_SHOTTIME*7)/10) { rb->lcd_getstringsize(hurry, &w1, &h); /* screen is too small for the message to be centered (Clip Zip) */ #if (LCD_WIDTH <= 96) rb->lcd_putsxy(LCD_WIDTH/2-w1/2+LCD_WIDTH/6, LCD_HEIGHT/2-h/2, hurry); #else rb->lcd_putsxy(LCD_WIDTH/2-w1/2, LCD_HEIGHT/2-h/2, hurry); #endif }}
/****************************************************************************** bubbles_fire() fires the current bubble, reloads the cannon, attaches* bubble to playboard, removes appropriate bubbles, and advances the* the compressor.******************************************************************************/static int bubbles_fire(struct game_context* bb) { int bubblecur; long shotxinc, shotyinc; long shotxofs, shotyofs; int shotxdirec = 1; long tempxofs, tempyofs; int nearrow, nearcol; int lastrow = BB_HEIGHT-1; int lastcol = (BB_WIDTH-1)/2; int buttonres; long lasttick, currenttick;
/* get current bubble */ bubblecur = bb->queue[bb->nextinq]; shotxinc = ((fp14_sin(bb->angle)>>4)*BUBBLE_WIDTH)/3; shotyinc = ((-1*(fp14_cos(bb->angle)>>4))*BUBBLE_HEIGHT)/3; shotxofs = shotyofs = 0;
/* advance the queue */ bb->queue[bb->nextinq] = bb->onboard[rb->rand()%bb->onboardcnt]; bb->nextinq = (bb->nextinq+1)%NUM_QUEUE; bubbles_drawboard(bb); rb->lcd_update_rect(0, 0, XOFS, LCD_HEIGHT);
/* move the bubble across the play board */ lasttick = *rb->current_tick;
while(true) { /* move the bubble one step */ shotyofs += shotyinc; shotxofs += shotxinc*shotxdirec;
/* check for bounce off sides */ if(SHOTX+(shotxofs>>10) < XOFS) { shotxofs += 2*((XOFS<<10)-(((SHOTX)<<10)+shotxofs)); shotxdirec *= -1; } else if(SHOTX+(shotxofs>>10) > XOFS+(BB_WIDTH-1)*BUBBLE_WIDTH) { shotxofs -= 2*((((SHOTX)<<10)+shotxofs)- ((XOFS<<10)+(((BB_WIDTH-1)*BUBBLE_WIDTH)<<10))); shotxdirec *= -1; }
tempxofs = shotxofs>>10; tempyofs = shotyofs>>10;
/* display shot */ bubbles_drawboard(bb); rb->lcd_bitmap_part(bubbles_emblem, 0, EMBLEM_HEIGHT*bubblecur, STRIDE( SCREEN_MAIN, BMPWIDTH_bubbles_emblem, BMPHEIGHT_bubbles_emblem), SHOTX+tempxofs+(BUBBLE_WIDTH-EMBLEM_WIDTH)/2, SHOTY+tempyofs+(BUBBLE_HEIGHT-EMBLEM_HEIGHT)/2, EMBLEM_WIDTH, EMBLEM_HEIGHT); rb->lcd_set_drawmode(DRMODE_FG); rb->lcd_mono_bitmap((const unsigned char *)bubbles_bubble, SHOTX+tempxofs, SHOTY+tempyofs, BUBBLE_WIDTH, BUBBLE_HEIGHT); rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_update_rect(XOFS, 0, BB_WIDTH*BUBBLE_WIDTH, LCD_HEIGHT);
/* find nearest position */ nearrow = ((SHOTY+tempyofs)- (YOFS+bb->compress*ROW_HEIGHT)+ (ROW_HEIGHT/2))/ROW_HEIGHT; if(nearrow >= BB_HEIGHT) nearrow = BB_HEIGHT-1;
if(nearrow%2) { /* odd row */ nearcol = ((SHOTX+tempxofs)- (XOFS+ROW_INDENT)+ (BUBBLE_WIDTH/2))/BUBBLE_WIDTH; if(nearcol >= BB_WIDTH-1) nearcol = BB_WIDTH-2; } else { /* even row */ nearcol = ((SHOTX+tempxofs)-XOFS+(BUBBLE_WIDTH/2))/BUBBLE_WIDTH; if(nearcol >= BB_WIDTH) nearcol = BB_WIDTH-1; } if(nearcol < 0) nearcol = 0;
/* if nearest position is occupied attach to last position */ if(bb->playboard[nearrow][nearcol].type >= 0) { bb->playboard[lastrow][lastcol].type = bubblecur; break; }
/* save last position */ lastrow = nearrow; lastcol = nearcol;
/* if collision with neighbor then attach shot */ if(bubbles_collision(bb, YOFS+SHOTY+tempyofs, SHOTX+tempxofs, nearrow, nearcol)) { bb->playboard[nearrow][nearcol].type = bubblecur; break; }
/* if at top then attach shot to the ceiling */ if(nearrow == 0 && SHOTY+tempyofs <= YOFS+bb->compress*ROW_HEIGHT) { bb->playboard[nearrow][nearcol].type = bubblecur; break; }
/* handle button events */ buttonres = bubbles_handlebuttons(bb, true, 0); if(buttonres != BB_NONE) return buttonres;
/* framerate limiting */ currenttick = *rb->current_tick; if(currenttick-lasttick < HZ/MAX_FPS) { rb->sleep((HZ/MAX_FPS)-(currenttick-lasttick)); } else { rb->yield(); } lasttick = currenttick; }
bubbles_drawboard(bb); rb->lcd_update();
/* clear appropriate bubbles from playing board */ if(bubbles_ingroup(bb, lastrow, lastcol)) { buttonres = bubbles_remove(bb); if(buttonres != BB_NONE) return buttonres; }
/* update shots and compress amount */ bb->shots++; if(bb->shots >= NUM_COMPRESS) { bb->shots = 0; bb->compress++; }
return BB_NONE;}
/****************************************************************************** bubbles_collision() determines if a fired bubble has collided with another* bubble.******************************************************************************/static bool bubbles_collision(struct game_context* bb, int y, int x, int nearrow, int nearcol) { int nx, ny; int adj = nearrow%2;
/* check neighbors */ if(nearcol-1 >= 0) { if(bb->playboard[nearrow][nearcol-1].type >= 0) { nx = XOFS+(nearrow%2 ? ROW_INDENT : 0)+BUBBLE_WIDTH*(nearcol-1); ny = YOFS+ROW_HEIGHT*nearrow+bb->compress*ROW_HEIGHT; if((x-nx)*(x-nx)+(y-ny)*(y-ny) < MIN_DISTANCE) return true; } }
if(nearcol-1+adj >= 0) { if(nearrow-1 >= 0) { if(bb->playboard[nearrow-1][nearcol-1+adj].type >= 0) { nx = XOFS+((nearrow-1)%2 ? ROW_INDENT : 0)+ BUBBLE_WIDTH*(nearcol-1+adj); ny = YOFS+ROW_HEIGHT*(nearrow-1)+bb->compress*ROW_HEIGHT; if((x-nx)*(x-nx)+(y-ny)*(y-ny) < MIN_DISTANCE) return true; } }
if(nearrow+1 < BB_HEIGHT) { if(bb->playboard[nearrow+1][nearcol-1+adj].type >= 0) { nx = XOFS+((nearrow+1)%2 ? ROW_INDENT : 0)+ BUBBLE_WIDTH*(nearcol-1+adj); ny = YOFS+ROW_HEIGHT*(nearrow+1)+bb->compress*ROW_HEIGHT; if((x-nx)*(x-nx)+(y-ny)*(y-ny) < MIN_DISTANCE) return true; } } }
if(nearcol+adj >= 0) { if(nearrow-1 >= 0) { if(bb->playboard[nearrow-1][nearcol+adj].type >= 0) { nx = XOFS+((nearrow-1)%2 ? ROW_INDENT : 0)+ BUBBLE_WIDTH*(nearcol+adj); ny = YOFS+ROW_HEIGHT*(nearrow-1)+bb->compress*ROW_HEIGHT; if((x-nx)*(x-nx)+(y-ny)*(y-ny) < MIN_DISTANCE) return true; } }
if(nearrow+1 < BB_HEIGHT) { if(bb->playboard[nearrow+1][nearcol+adj].type >= 0) { nx = XOFS+((nearrow+1)%2 ? ROW_INDENT : 0)+ BUBBLE_WIDTH*(nearcol+adj); ny = YOFS+ROW_HEIGHT*(nearrow+1)+bb->compress*ROW_HEIGHT; if((x-nx)*(x-nx)+(y-ny)*(y-ny) < MIN_DISTANCE) return true; } } }
if(nearcol+1 < BB_WIDTH-adj) { if(bb->playboard[nearrow][nearcol+1].type >= 0) { nx = XOFS+(nearrow%2 ? ROW_INDENT : 0)+BUBBLE_WIDTH*(nearcol+1); ny = YOFS+ROW_HEIGHT*nearrow+bb->compress*ROW_HEIGHT; if((x-nx)*(x-nx)+(y-ny)*(y-ny) < MIN_DISTANCE) return true; } }
return false;}
/****************************************************************************** bubbles_ingroup() marks all bubbles that form the current group.******************************************************************************/static bool bubbles_ingroup(struct game_context* bb, int row, int col) { int i, j; int count;
count = bubbles_searchgroup(bb, row, col);
/* unmark group if too small */ if(count < 3) { for(i=0; i<BB_HEIGHT; i++) { for(j=0; j<BB_WIDTH; j++) { bb->playboard[i][j].ingroup = false; } }
return false; }
return true;}
/****************************************************************************** bubbles_searchgroup() return the size of the group of bubbles of the same* type that the current bubble belongs to.******************************************************************************/static int bubbles_searchgroup(struct game_context* bb, int row, int col) { int i, adj; int myrow, mycol, mytype; int count = 0;
struct coord { int row; int col; } search[(2*BB_WIDTH-1)*(BB_HEIGHT/2)];
/* search initial bubble */ bb->playboard[row][col].ingroup = true; search[count].row = row; search[count].col = col; count++;
/* breadth-first search neighbors */ for(i=0; i<count; i++) { myrow = search[i].row; mycol = search[i].col; mytype = bb->playboard[myrow][mycol].type; adj = myrow%2;
if(mycol-1 >= 0) { if(bb->playboard[myrow][mycol-1].type == mytype && !bb->playboard[myrow][mycol-1].ingroup) { bb->playboard[myrow][mycol-1].ingroup = true; search[count].row = myrow; search[count].col = mycol-1; count++; } }
if(mycol-1+adj >= 0) { if(myrow-1 >= 0) { if(bb->playboard[myrow-1][mycol-1+adj].type == mytype && !bb->playboard[myrow-1][mycol-1+adj].ingroup) { bb->playboard[myrow-1][mycol-1+adj].ingroup = true; search[count].row = myrow-1; search[count].col = mycol-1+adj; count++; } }
if(myrow+1 < BB_HEIGHT) { if(bb->playboard[myrow+1][mycol-1+adj].type == mytype && !bb->playboard[myrow+1][mycol-1+adj].ingroup) { bb->playboard[myrow+1][mycol-1+adj].ingroup = true; search[count].row = myrow+1; search[count].col = mycol-1+adj; count++; } } }
if(mycol+adj >= 0) { if(myrow-1 >= 0) { if(bb->playboard[myrow-1][mycol+adj].type == mytype && !bb->playboard[myrow-1][mycol+adj].ingroup) { bb->playboard[myrow-1][mycol+adj].ingroup = true; search[count].row = myrow-1; search[count].col = mycol+adj; count++; } }
if(myrow+1 < BB_HEIGHT) { if(bb->playboard[myrow+1][mycol+adj].type == mytype && !bb->playboard[myrow+1][mycol+adj].ingroup) { bb->playboard[myrow+1][mycol+adj].ingroup = true; search[count].row = myrow+1; search[count].col = mycol+adj; count++; } } }
if(mycol+1 < BB_WIDTH-adj) { if(bb->playboard[myrow][mycol+1].type == mytype && !bb->playboard[myrow][mycol+1].ingroup) { bb->playboard[myrow][mycol+1].ingroup = true; search[count].row = myrow; search[count].col = mycol+1; count++; } } }
return count;}
/****************************************************************************** bubbles_remove() removes all bubbles in the current group and all* unanchored bubbles from the play board.******************************************************************************/static int bubbles_remove(struct game_context* bb) { int i, j; int buttonres;
/* determine all anchored bubbles */ for(j=0; j<BB_WIDTH; j++) { if(bb->playboard[0][j].type >= 0 && !bb->playboard[0][j].ingroup) { bubbles_anchored(bb, 0, j); } }
/* mark bubbles to be deleted */ for(i=0; i<BB_HEIGHT; i++) { for(j=0; j<BB_WIDTH; j++) { if(bb->playboard[i][j].type >= 0 && (!bb->playboard[i][j].anchored || bb->playboard[i][j].ingroup)) { bb->playboard[i][j].delete = true; } } }
/* animate falling bubbles */ buttonres = bubbles_fall(bb); if(buttonres != BB_NONE) return buttonres;
/* remove bubbles */ for(i=0; i<BB_HEIGHT; i++) { for(j=0; j<BB_WIDTH; j++) { if(bb->playboard[i][j].delete) { bb->playboard[i][j].ingroup = false; bb->playboard[i][j].type = -1; bb->playboard[i][j].delete = false; } else { bb->playboard[i][j].anchored = false; } } }
bubbles_getonboard(bb);
return BB_NONE;}
/****************************************************************************** bubbles_anchored() marks all bubbles that are anchored in some way to the* current bubble.******************************************************************************/static void bubbles_anchored(struct game_context* bb, int row, int col) { int i, adj; int myrow, mycol; int count = 0;
struct coord { int row; int col; } search[(2*BB_WIDTH-1)*(BB_HEIGHT/2)];
/* search initial bubble */ bb->playboard[row][col].anchored = true; search[count].row = row; search[count].col = col; count++;
/* breadth-first search neighbors */ for(i=0; i<count; i++) { myrow = search[i].row; mycol = search[i].col; adj = myrow%2;
if(mycol-1 >= 0) { if(bb->playboard[myrow][mycol-1].type >= 0 && !bb->playboard[myrow][mycol-1].ingroup && !bb->playboard[myrow][mycol-1].anchored) { bb->playboard[myrow][mycol-1].anchored = true; search[count].row = myrow; search[count].col = mycol-1; count++; } }
if(mycol-1+adj >= 0) { if(myrow-1 >= 0) { if(bb->playboard[myrow-1][mycol-1+adj].type >= 0 && !bb->playboard[myrow-1][mycol-1+adj].ingroup && !bb->playboard[myrow-1][mycol-1+adj].anchored) { bb->playboard[myrow-1][mycol-1+adj].anchored = true; search[count].row = myrow-1; search[count].col = mycol-1+adj; count++; } }
if(myrow+1 < BB_HEIGHT) { if(bb->playboard[myrow+1][mycol-1+adj].type >= 0 && !bb->playboard[myrow+1][mycol-1+adj].ingroup && !bb->playboard[myrow+1][mycol-1+adj].anchored) { bb->playboard[myrow+1][mycol-1+adj].anchored = true; search[count].row = myrow+1; search[count].col = mycol-1+adj; count++; } } }
if(mycol+adj >= 0) { if(myrow-1 >= 0) { if(bb->playboard[myrow-1][mycol+adj].type >= 0 && !bb->playboard[myrow-1][mycol+adj].ingroup && !bb->playboard[myrow-1][mycol+adj].anchored) { bb->playboard[myrow-1][mycol+adj].anchored = true; search[count].row = myrow-1; search[count].col = mycol+adj; count++; } }
if(myrow+1 < BB_HEIGHT) { if(bb->playboard[myrow+1][mycol+adj].type >= 0 && !bb->playboard[myrow+1][mycol+adj].ingroup && !bb->playboard[myrow+1][mycol+adj].anchored) { bb->playboard[myrow+1][mycol+adj].anchored = true; search[count].row = myrow+1; search[count].col = mycol+adj; count++; } } }
if(mycol+1 < BB_WIDTH-adj) { if(bb->playboard[myrow][mycol+1].type >= 0 && !bb->playboard[myrow][mycol+1].ingroup && !bb->playboard[myrow][mycol+1].anchored) { bb->playboard[myrow][mycol+1].anchored = true; search[count].row = myrow; search[count].col = mycol+1; count++; } } }}
/****************************************************************************** bubbles_fall() makes removed bubbles fall from the screen.******************************************************************************/static int bubbles_fall(struct game_context* bb) { int i, j; int count; int indent; int xofs, yofs; int buttonres; bool onscreen; long lasttick, currenttick;
/* give all falling bubbles an x axis movement */ for(i=0; i<BB_HEIGHT; i++) { for(j=0; j<BB_WIDTH; j++) { if(bb->playboard[i][j].delete) { bb->playboard[i][j].fallx = rb->rand()%25 - 12; bb->playboard[i][j].fallvel = rb->rand()%5 + 6; } } }
/* draw bubbles falling off the screen * follows y=x^2-8x scaled to bubble size */ lasttick = *rb->current_tick;
for(count=1; ;count++) { onscreen = false; bubbles_drawboard(bb);
for(i=0; i<BB_HEIGHT; i++) { for(j=0; j<BB_WIDTH; j++) { if(bb->playboard[i][j].delete) { indent = (i%2 ? ROW_INDENT : 0); xofs = ((bb->playboard[i][j].fallx*count)*BUBBLE_WIDTH)/48; yofs = ((count*count - bb->playboard[i][j].fallvel*count)* BUBBLE_HEIGHT)/20;
/* draw bubble if it is still on the screen */ if(YOFS+ROW_HEIGHT*i+bb->compress*ROW_HEIGHT+yofs <= LCD_HEIGHT) { onscreen = true;
rb->lcd_bitmap_part(bubbles_emblem, 0, EMBLEM_HEIGHT*bb->playboard[i][j].type, STRIDE( SCREEN_MAIN, BMPWIDTH_bubbles_emblem, BMPHEIGHT_bubbles_emblem), XOFS+indent+BUBBLE_WIDTH*j+ (BUBBLE_WIDTH-EMBLEM_WIDTH)/2+xofs, YOFS+ROW_HEIGHT*i+(BUBBLE_HEIGHT-EMBLEM_HEIGHT)/2+ bb->compress*ROW_HEIGHT+yofs, EMBLEM_WIDTH, EMBLEM_HEIGHT); rb->lcd_set_drawmode(DRMODE_FG); rb->lcd_mono_bitmap( (const unsigned char *)bubbles_bubble, XOFS+indent+BUBBLE_WIDTH*j+xofs, YOFS+ROW_HEIGHT*i+bb->compress*ROW_HEIGHT+yofs, BUBBLE_WIDTH, BUBBLE_HEIGHT); rb->lcd_set_drawmode(DRMODE_SOLID); } } } }
rb->lcd_update();
/* break out if all bubbles are off the screen */ if(!onscreen) break;
/* handle button events */ buttonres = bubbles_handlebuttons(bb, true, 0); if(buttonres != BB_NONE) return buttonres;
/* framerate limiting */ currenttick = *rb->current_tick; if(currenttick-lasttick < HZ/MAX_FPS) { rb->sleep((HZ/MAX_FPS)-(currenttick-lasttick)); } else { rb->yield(); } lasttick = currenttick; }
return BB_NONE;}
/****************************************************************************** bubbles_checklevel() checks the state of the playboard for a win or loss.******************************************************************************/static int bubbles_checklevel(struct game_context* bb) { int i, j; int points; char str[13];
bubbles_drawboard(bb); rb->lcd_update();
/* check for bubbles below cut off point */ for(i=0; i<=bb->compress; i++) { for(j=0; j<BB_WIDTH; j++) { if(bb->playboard[BB_HEIGHT-1-i][j].type >= 0) return BB_LOSE; } }
/* check for bubbles above cut off point */ for(i=0; i<BB_HEIGHT-1-bb->compress; i++) { for(j=0; j<BB_WIDTH; j++) { if(bb->playboard[i][j].type >= 0) return BB_NONE; } }
/* level complete, record score */ points = 100 - bb->elapsedlvl/100; if(points > 0) { bb->score += points; } else { points = 0; }
rb->snprintf(str, 12, "%d points", points); rb->splash(HZ, str);
/* advance to the next level */ if(!bubbles_nextlevel(bb)) { return BB_WIN; }
bubbles_drawboard(bb); rb->lcd_update(); rb->snprintf(str, 12, "Level %d", bb->level); rb->splash(HZ, str); bubbles_drawboard(bb); rb->lcd_update();
return BB_NONE;}
/****************************************************************************** bubbles_recordscore() inserts a high score into the high scores list and* returns the high score position.******************************************************************************/static void bubbles_recordscore(struct game_context* bb) {
int position;
position = highscore_update(bb->score, bb->level-1, "", highscores, NUM_SCORES); if (position != -1) { if (position == 0) rb->splash(HZ*2, "New High Score"); highscore_show(position, highscores, NUM_SCORES, true); }}
/****************************************************************************** bubbles_loaddata() loads highest level beaten.******************************************************************************/static void bubbles_loaddata(void) { int fd;
last_highlevel = highlevel = 0; /* open data file */ fd = rb->open(DATA_FILE, O_RDONLY); if (fd < 0) return;
/* read in saved game */ if (rb->read(fd, &highlevel, sizeof(highlevel)) < (long)sizeof(highlevel)) { highlevel = 0; } if (highlevel >= NUM_LEVELS) highlevel = NUM_LEVELS-1; last_highlevel = highlevel;
rb->close(fd);}
/****************************************************************************** bubbles_savedata() saves the current game state.******************************************************************************/static void bubbles_savedata(void) { int fd;
if (last_highlevel >= highlevel) /* no need to save */ return;
fd = rb->open(DATA_FILE, O_WRONLY|O_CREAT, 0666); if (fd < 0) return;
rb->write(fd, &highlevel, sizeof(highlevel));
rb->close(fd);}
/****************************************************************************** bubbles_loadgame() loads the saved game and returns load success.******************************************************************************/static bool bubbles_loadgame(struct game_context* bb) { int fd;
bool ret = true; /* open game file */ fd = rb->open(SAVE_FILE, O_RDONLY); if(fd < 0) return false;
/* read in saved game */ if(rb->read(fd, bb, sizeof(struct game_context)) < (long)sizeof(struct game_context)) { ret = false; }
rb->close(fd);
return ret;}
/****************************************************************************** bubbles_savegame() saves the current game state.******************************************************************************/static void bubbles_savegame(struct game_context* bb) { int fd;
if (!resume) /* nothing to save */ return; /* write out the game state to the save file */ fd = rb->open(SAVE_FILE, O_WRONLY|O_CREAT, 0666); if (fd < 0) { rb->splash(HZ/2, "Failed to save game"); return; } if (rb->write(fd, bb, sizeof(struct game_context)) <= 0) { rb->splash(HZ/2, "Failed to save game"); }
rb->close(fd);}
/****************************************************************************** bubbles_setcolors() set the foreground and background colors.******************************************************************************/static inline void bubbles_setcolors(void) {#ifdef HAVE_LCD_COLOR rb->lcd_set_background(LCD_RGBPACK(181,181,222)); rb->lcd_set_foreground(LCD_BLACK);#endif}
/****************************************************************************** bubbles_callback() is the default event handler callback which is called* on usb connect and shutdown.******************************************************************************/static void bubbles_callback(void* param) { (void) param; highscore_save(SCORE_FILE, highscores, NUM_SCORES);}
/****************************************************************************** bubbles_handlebuttons() handles button events during a game.******************************************************************************/static int bubbles_handlebuttons(struct game_context* bb, bool animblock, int timeout) { int button; int buttonres; long start; const struct button_mapping *plugin_contexts[] = { pla_main_ctx,#ifdef HAVE_REMOTE_LCD pla_remote_ctx,#endif };
if (timeout < 0) timeout = 0; button = pluginlib_getaction(timeout,plugin_contexts,ARRAYLEN(plugin_contexts));#if defined(HAS_BUTTON_HOLD) && !defined(HAVE_REMOTE_LCD_AS_MAIN) /* FIXME: Should probably check remote hold here */ if (rb->button_hold()) button = BUBBLES_PAUSE;#endif
switch(button){ case BUBBLES_LEFT_REP: if(bb->angle > MIN_ANGLE) bb->angle -= ANGLE_STEP_REP; break; case BUBBLES_LEFT: /* change angle to the left */ if(bb->angle > MIN_ANGLE) bb->angle -= ANGLE_STEP; break;
case BUBBLES_RIGHT_REP: if(bb->angle < MAX_ANGLE) bb->angle += ANGLE_STEP_REP; break; case BUBBLES_RIGHT: /* change angle to the right */ if(bb->angle < MAX_ANGLE) bb->angle += ANGLE_STEP; break;
case BUBBLES_FIRE: /* fire the shot */ case BUBBLES_FIRE_REPEAT: if(!animblock) { bb->elapsedlvl += bb->elapsedshot; bb->elapsedshot = 0; buttonres = bubbles_fire(bb); if(buttonres != BB_NONE) return buttonres; buttonres = bubbles_checklevel(bb); if(buttonres != BB_NONE) return buttonres; bb->startedshot = *rb->current_tick; } break;
case BUBBLES_PAUSE: /* pause the game */ start = *rb->current_tick; rb->splash(0, "Paused");
while(pluginlib_getaction(TIMEOUT_BLOCK,plugin_contexts, ARRAYLEN(plugin_contexts)) != BUBBLES_PAUSE); bb->startedshot += *rb->current_tick-start; bubbles_drawboard(bb); rb->lcd_update(); break;
case BUBBLES_QUIT1: case BUBBLES_QUIT2: /* end the game */ if(!animblock) { resume = true; return BB_END; } break;
case ACTION_UNKNOWN: case ACTION_NONE: /* no button pressed */ break;
default: if(rb->default_event_handler_ex(button, bubbles_callback, (void*) bb) == SYS_USB_CONNECTED) return BB_USB; break; }
return BB_NONE;}
static int bubbles_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)) return ACTION_EXIT_MENUITEM; return action;}
/****************************************************************************** bubbles_menu() is the initial menu at the start of the game.******************************************************************************/static int bubbles_menu(struct game_context* bb) { static unsigned int startlevel = 0; int selected = 0; bool startgame = false;
MENUITEM_STRINGLIST(menu,"Bubbles",bubbles_menu_cb, "Resume Game", "Start New Game", "Level", "High Scores", "Playback Control", "Quit without Saving", "Quit");
while(!startgame){ switch (rb->do_menu(&menu, &selected, NULL, false)) { case 0: /* resume game */ startgame = true; if(resume_file) rb->remove(SAVE_FILE); resume_file = false; break; case 1: /* new game */ bb->level = startlevel; startgame = true; resume = false; resume_file = false; break; case 2: /* choose level */ startlevel++; rb->set_int("Choose start level", "", UNIT_INT, &startlevel, NULL, 1, 1, highlevel+1, NULL); startlevel--; break; case 3: /* High scores */ highscore_show(-1, highscores, NUM_SCORES, true); break; case 4: /* Playback Control */ playback_control(NULL); break; case 5: /* quit but don't save */ return BB_QUIT_WITHOUT_SAVING; case 6: /* save and quit */ return BB_QUIT; case MENU_ATTACHED_USB: bubbles_callback(bb); return BB_USB; } } return 0;}
/****************************************************************************** bubbles() is the main game subroutine, it returns the final game status.******************************************************************************/static int bubbles(struct game_context* bb) { int buttonres; long timeout;
/******************** * menu * ********************/ buttonres = bubbles_menu(bb); if(buttonres != 0) return buttonres;
/******************** * init * ********************/ bubbles_init(bb); bubbles_drawboard(bb); rb->lcd_update();
/********************** * play * **********************/ bb->startedshot = *rb->current_tick;
while(true) { /* refresh the board */ bubbles_drawboard(bb); rb->lcd_update();
/* manange idle framerate */ bb->elapsedshot = *rb->current_tick-bb->startedshot;
if(MAX_SHOTTIME-bb->elapsedshot < HZ/2) { timeout = MAX_SHOTTIME-bb->elapsedshot; } else { timeout = HZ/2; }
/* handle button events */ buttonres = bubbles_handlebuttons(bb, false, timeout); if(buttonres != BB_NONE) return buttonres;
/* handle timing */ bb->elapsedshot = *rb->current_tick-bb->startedshot;
if(bb->elapsedshot > MAX_SHOTTIME) { bb->elapsedlvl += bb->elapsedshot; bb->elapsedshot = 0; buttonres = bubbles_fire(bb); if(buttonres != BB_NONE) return buttonres; buttonres = bubbles_checklevel(bb); if(buttonres != BB_NONE) return buttonres; bb->startedshot = *rb->current_tick; } }}
/****************************************************************************** plugin entry point.******************************************************************************/enum plugin_status plugin_start(const void* parameter) { static struct game_context bb; bool exit = false; enum plugin_status ret = PLUGIN_OK;
(void)parameter;
/* load files */ resume = bubbles_loadgame(&bb); resume_file = resume; bubbles_loaddata(); highscore_load(SCORE_FILE, highscores, NUM_SCORES); rb->lcd_clear_display();
/* start app */#if LCD_DEPTH > 1 rb->lcd_set_backdrop(NULL);#endif rb->lcd_setfont(FONT_SYSFIXED);
while(!exit) { switch(bubbles(&bb)){ case BB_WIN: rb->splash(HZ*2, "You Win!"); /* record high level */ highlevel = NUM_LEVELS-1; /* record high score */ bubbles_recordscore(&bb); break;
case BB_LOSE: resume = false; rb->splash(HZ*2, "Game Over"); /* record high score */ bubbles_recordscore(&bb); /* fall through to BB_END */
case BB_END: break;
case BB_USB: ret = PLUGIN_USB_CONNECTED; exit = true; break;
case BB_QUIT: rb->splash(HZ/3, "Saving game data ..."); bubbles_savegame(&bb); bubbles_savedata(); highscore_save(SCORE_FILE, highscores, NUM_SCORES); /* fall through */
case BB_QUIT_WITHOUT_SAVING: exit = true; break;
default: break; } } rb->lcd_setfont(FONT_UI); return ret;}