1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Originally by Joshua Oreman, improved by Prashant Varanasi
11 * Ported to Rockbox by Ben Basha (Paprica)
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
19 ****************************************************************************/
23 #include "configfile.h"
30 - Make original speed and further increases in speed depend more on screen size
31 - attempt to make the tunnels get narrower as the game goes on
32 - make the chopper look better, maybe a picture, and scale according
34 - use textures for the color screens for background and terrain,
35 eg stars on background
36 - allow choice of different levels [later: different screen themes]
37 - better high score handling, improved screen etc.
40 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
42 #define QUIT BUTTON_OFF
43 #define ACTION BUTTON_UP
44 #define ACTION2 BUTTON_SELECT
45 #define ACTIONTEXT "SELECT"
47 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
48 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
49 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
51 #define QUIT BUTTON_MENU
52 #define ACTION BUTTON_SELECT
53 #define ACTIONTEXT "SELECT"
55 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD /* grayscale at the moment */
57 #define QUIT BUTTON_POWER
58 #define ACTION BUTTON_UP
59 #define ACTION2 BUTTON_SELECT
60 #define ACTIONTEXT "SELECT"
62 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
63 #define QUIT BUTTON_POWER
64 #define ACTION BUTTON_RIGHT
65 #define ACTIONTEXT "RIGHT"
67 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
68 (CONFIG_KEYPAD == SANSA_C200_PAD)
69 #define QUIT BUTTON_POWER
70 #define ACTION BUTTON_SELECT
71 #define ACTIONTEXT "SELECT"
73 #elif CONFIG_KEYPAD == GIGABEAT_PAD
74 #define QUIT BUTTON_MENU
75 #define ACTION BUTTON_SELECT
76 #define ACTIONTEXT "SELECT"
78 #elif CONFIG_KEYPAD == RECORDER_PAD
79 #define QUIT BUTTON_OFF
80 #define ACTION BUTTON_PLAY
81 #define ACTIONTEXT "PLAY"
83 #elif CONFIG_KEYPAD == ONDIO_PAD
84 #define QUIT BUTTON_OFF
85 #define ACTION BUTTON_UP
86 #define ACTION2 BUTTON_MENU
87 #define ACTIONTEXT "UP"
89 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
90 #define QUIT BUTTON_BACK
91 #define ACTION BUTTON_SELECT
92 #define ACTION2 BUTTON_MENU
93 #define ACTIONTEXT "SELECT"
95 #elif CONFIG_KEYPAD == MROBE100_PAD
96 #define QUIT BUTTON_POWER
97 #define ACTION BUTTON_SELECT
98 #define ACTIONTEXT "SELECT"
100 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
101 #define QUIT BUTTON_RC_REC
102 #define ACTION BUTTON_RC_PLAY
103 #define ACTION2 BUTTON_RC_MODE
104 #define ACTIONTEXT "PLAY"
106 #elif CONFIG_KEYPAD == COWOND2_PAD
107 #define QUIT BUTTON_POWER
108 #define ACTION BUTTON_UP
109 #define ACTION2 BUTTON_MENU
110 #define ACTIONTEXT "UP"
113 #error No keymap defined!
116 static struct plugin_api
* rb
;
118 #define NUMBER_OF_BLOCKS 8
119 #define NUMBER_OF_PARTICLES 3
120 #define MAX_TERRAIN_NODES 15
122 #define LEVEL_MODE_NORMAL 0
123 #define LEVEL_MODE_STEEP 1
126 #define CYCLETIME 100
127 #define SCALE(x) ((x)==1 ? (x) : ((x) >> 1))
135 /*Chopper's local variables to track the terrain position etc*/
136 static int chopCounter
;
137 static int iRotorOffset
;
140 static int iPlayerPosX
;
141 static int iPlayerPosY
;
142 static int iCameraPosX
;
143 static int iPlayerSpeedX
;
144 static int iPlayerSpeedY
;
145 static int iLastBlockPlacedPosX
;
146 static int iGravityTimerCountdown
;
147 static int iPlayerAlive
;
148 static int iLevelMode
;
149 static int blockh
,blockw
;
150 static int highscore
;
153 #define CFG_FILE "chopper.cfg"
154 #define MAX_POINTS 50000
155 static struct configdata config
[] =
157 {TYPE_INT
, 0, MAX_POINTS
, &highscore
, "highscore", NULL
, NULL
}
190 struct CTerrainNode mNodes
[MAX_TERRAIN_NODES
];
192 int iLastNodePlacedPosX
;
195 struct CBlock mBlocks
[NUMBER_OF_BLOCKS
];
196 struct CParticle mParticles
[NUMBER_OF_PARTICLES
];
198 struct CTerrain mGround
;
199 struct CTerrain mRoof
;
201 /*Function declarations*/
202 static void chopDrawParticle(struct CParticle
*mParticle
);
203 static void chopDrawBlock(struct CBlock
*mBlock
);
204 static void chopRenderTerrain(struct CTerrain
*ter
);
205 void chopper_load(bool newgame
);
206 void cleanup_chopper(void);
208 static void chopDrawPlayer(int x
,int y
) /* These are SCREEN coords, not world!*/
212 rb
->lcd_set_foreground(LCD_RGBPACK(50,50,200));
214 rb
->lcd_set_foreground(LCD_DARKGRAY
);
216 rb
->lcd_fillrect(SCALE(x
+6), SCALE(y
+2), SCALE(12), SCALE(9));
217 rb
->lcd_fillrect(SCALE(x
-3), SCALE(y
+6), SCALE(20), SCALE(3));
220 rb
->lcd_set_foreground(LCD_RGBPACK(50,50,50));
222 rb
->lcd_set_foreground(LCD_DARKGRAY
);
224 rb
->lcd_fillrect(SCALE(x
+10), SCALE(y
), SCALE(2), SCALE(3));
225 rb
->lcd_fillrect(SCALE(x
+10), SCALE(y
), SCALE(1), SCALE(3));
228 rb
->lcd_set_foreground(LCD_RGBPACK(40,40,100));
230 rb
->lcd_set_foreground(LCD_BLACK
);
232 rb
->lcd_drawline(SCALE(x
), SCALE(y
+iRotorOffset
), SCALE(x
+20),
233 SCALE(y
-iRotorOffset
));
236 rb
->lcd_set_foreground(LCD_RGBPACK(20,20,50));
238 rb
->lcd_set_foreground(LCD_BLACK
);
240 rb
->lcd_fillrect(SCALE(x
- 2), SCALE(y
+ 5), SCALE(2), SCALE(5));
244 static void chopClearTerrain(struct CTerrain
*ter
)
246 ter
->iNodesCount
= 0;
250 int iR(int low
,int high
)
252 return low
+rb
->rand()%(high
-low
+1);
255 static void chopCopyTerrain(struct CTerrain
*src
, struct CTerrain
*dest
,
256 int xOffset
,int yOffset
)
260 while(i
< src
->iNodesCount
)
262 dest
->mNodes
[i
].x
= src
->mNodes
[i
].x
+ xOffset
;
263 dest
->mNodes
[i
].y
= src
->mNodes
[i
].y
+ yOffset
;
268 dest
->iNodesCount
= src
->iNodesCount
;
269 dest
->iLastNodePlacedPosX
= src
->iLastNodePlacedPosX
;
273 static void chopAddTerrainNode(struct CTerrain
*ter
, int x
, int y
)
277 if(ter
->iNodesCount
+ 1 >= MAX_TERRAIN_NODES
)
279 /* DEBUGF("ERROR: Not enough nodes!\n"); */
285 i
= ter
->iNodesCount
- 1;
287 ter
->mNodes
[i
].x
= x
;
290 ter
->iLastNodePlacedPosX
= x
;
294 static void chopTerrainNodeDeleteAndShift(struct CTerrain
*ter
,int nodeIndex
)
298 while( i
< ter
->iNodesCount
)
300 ter
->mNodes
[i
- 1] = ter
->mNodes
[i
];
309 int chopUpdateTerrainRecycling(struct CTerrain
*ter
)
314 while(i
< ter
->iNodesCount
)
317 if( iCameraPosX
> ter
->mNodes
[i
].x
)
320 chopTerrainNodeDeleteAndShift(ter
,i
);
322 iNewNodePos
= ter
->iLastNodePlacedPosX
+ 50;
328 if(iLevelMode
== LEVEL_MODE_STEEP
)
331 chopAddTerrainNode(ter
,iNewNodePos
,g
- iR(-v
,v
));
343 int chopTerrainHeightAtPoint(struct CTerrain
*ter
, int pX
)
346 int iNodeIndexOne
=0,iNodeIndexTwo
=0, h
, terY1
, terY2
, terX1
, terX2
, a
, b
;
350 for(i
=1;i
<MAX_TERRAIN_NODES
;i
++)
352 if(ter
->mNodes
[i
].x
> pX
)
354 iNodeIndexOne
= i
- 1;
360 iNodeIndexTwo
= iNodeIndexOne
+ 1;
361 terY1
= ter
->mNodes
[iNodeIndexOne
].y
;
362 terY2
= ter
->mNodes
[iNodeIndexTwo
].y
;
365 terX2
= ter
->mNodes
[iNodeIndexTwo
].x
- ter
->mNodes
[iNodeIndexOne
].x
;
367 pX
-= ter
->mNodes
[iNodeIndexOne
].x
;
380 int chopPointInTerrain(struct CTerrain
*ter
, int pX
, int pY
, int iTestType
)
382 int h
= chopTerrainHeightAtPoint(ter
, pX
);
390 static void chopAddBlock(int x
,int y
,int sx
,int sy
, int indexOverride
)
394 if(indexOverride
< 0)
396 while(mBlocks
[i
].bIsActive
&& i
< NUMBER_OF_BLOCKS
)
398 if(i
==NUMBER_OF_BLOCKS
)
400 DEBUGF("No blocks!\n");
407 mBlocks
[i
].bIsActive
= 1;
408 mBlocks
[i
].iWorldX
= x
;
409 mBlocks
[i
].iWorldY
= y
;
410 mBlocks
[i
].iSizeX
= sx
;
411 mBlocks
[i
].iSizeY
= sy
;
413 iLastBlockPlacedPosX
= x
;
416 static void chopAddParticle(int x
,int y
,int sx
,int sy
)
420 while(mParticles
[i
].bIsActive
&& i
< NUMBER_OF_PARTICLES
)
423 if(i
==NUMBER_OF_PARTICLES
)
426 mParticles
[i
].bIsActive
= 1;
427 mParticles
[i
].iWorldX
= x
;
428 mParticles
[i
].iWorldY
= y
;
429 mParticles
[i
].iSpeedX
= sx
;
430 mParticles
[i
].iSpeedY
= sy
;
433 static void chopGenerateBlockIfNeeded(void)
436 int DistSpeedX
= iPlayerSpeedX
* 5;
437 if(DistSpeedX
<200) DistSpeedX
= 200;
439 while(i
< NUMBER_OF_BLOCKS
)
441 if(!mBlocks
[i
].bIsActive
)
445 iX
= iLastBlockPlacedPosX
+ (350-DistSpeedX
);
449 sY
= blockh
+ iR(1,blockh
/3);
451 chopAddBlock(iX
,iY
,sX
,sY
,i
);
459 static int chopBlockCollideWithPlayer(struct CBlock
*mBlock
)
461 int px
= iPlayerPosX
;
462 int py
= iPlayerPosY
;
464 int x
= mBlock
->iWorldX
-17;
465 int y
= mBlock
->iWorldY
-11;
467 int x2
= x
+ mBlock
->iSizeX
+17;
468 int y2
= y
+ mBlock
->iSizeY
+11;
481 static int chopBlockOffscreen(struct CBlock
*mBlock
)
483 if(mBlock
->iWorldX
+ mBlock
->iSizeX
< iCameraPosX
)
489 static int chopParticleOffscreen(struct CParticle
*mParticle
)
491 if (mParticle
->iWorldX
< iCameraPosX
|| mParticle
->iWorldY
< 0 ||
492 mParticle
->iWorldY
> iScreenY
|| mParticle
->iWorldX
> iCameraPosX
+
501 static void chopKillPlayer(void)
505 for (i
= 0; i
< NUMBER_OF_PARTICLES
; i
++) {
506 mParticles
[i
].bIsActive
= 0;
507 chopAddParticle(iPlayerPosX
+ iR(0,20), iPlayerPosY
+ iR(0,20),
513 if (iPlayerAlive
== 0) {
514 rb
->lcd_set_drawmode(DRMODE_FG
);
516 rb
->lcd_set_foreground(LCD_LIGHTGRAY
);
518 rb
->splash(HZ
, "Game Over");
520 if (score
> highscore
) {
523 rb
->snprintf(scoretext
, sizeof(scoretext
), "New High Score: %d",
525 rb
->splash(HZ
*2, scoretext
);
528 rb
->splash(HZ
/4, "Press " ACTIONTEXT
" to continue");
531 rb
->lcd_set_drawmode(DRMODE_SOLID
);
534 button
= rb
->button_get(true);
541 button
= rb
->button_get(true);
542 if (button
== (ACTION
| BUTTON_REL
)
544 || button
== (ACTION2
| BUTTON_REL
)
559 static void chopDrawTheWorld(void)
563 while(i
< NUMBER_OF_BLOCKS
)
565 if(mBlocks
[i
].bIsActive
)
567 if(chopBlockOffscreen(&mBlocks
[i
]) == 1)
568 mBlocks
[i
].bIsActive
= 0;
570 chopDrawBlock(&mBlocks
[i
]);
578 while(i
< NUMBER_OF_PARTICLES
)
580 if(mParticles
[i
].bIsActive
)
582 if(chopParticleOffscreen(&mParticles
[i
]) == 1)
583 mParticles
[i
].bIsActive
= 0;
585 chopDrawParticle(&mParticles
[i
]);
591 chopRenderTerrain(&mGround
);
592 chopRenderTerrain(&mRoof
);
596 static void chopDrawParticle(struct CParticle
*mParticle
)
599 int iPosX
= (mParticle
->iWorldX
- iCameraPosX
);
600 int iPosY
= (mParticle
->iWorldY
);
602 rb
->lcd_set_foreground(LCD_RGBPACK(192,192,192));
604 rb
->lcd_set_foreground(LCD_LIGHTGRAY
);
606 rb
->lcd_fillrect(SCALE(iPosX
), SCALE(iPosY
), SCALE(3), SCALE(3));
610 static void chopDrawScene(void)
615 rb
->lcd_set_background(LCD_BLACK
);
617 rb
->lcd_set_background(LCD_WHITE
);
619 rb
->lcd_clear_display();
622 chopDrawPlayer(iPlayerPosX
- iCameraPosX
, iPlayerPosY
);
624 score
= -20 + iPlayerPosX
/3;
627 rb
->lcd_set_drawmode(DRMODE_COMPLEMENT
);
629 rb
->lcd_set_drawmode(DRMODE_FG
);
633 rb
->lcd_set_foreground(LCD_BLACK
);
635 rb
->lcd_set_foreground(LCD_WHITE
);
639 rb
->snprintf(s
, sizeof(s
), "Dist: %d", score
);
641 rb
->snprintf(s
, sizeof(s
), "Distance: %d", score
);
643 rb
->lcd_getstringsize(s
, &w
, NULL
);
644 rb
->lcd_putsxy(2, 2, s
);
645 if (score
< highscore
)
649 rb
->snprintf(s
, sizeof(s
), "Hi: %d", highscore
);
651 rb
->snprintf(s
, sizeof(s
), "Best: %d", highscore
);
653 rb
->lcd_getstringsize(s
, &w2
, NULL
);
654 if (LCD_WIDTH
- 2 - w2
> w
+ 2)
655 rb
->lcd_putsxy(LCD_WIDTH
- 2 - w2
, 2, s
);
657 rb
->lcd_set_drawmode(DRMODE_SOLID
);
662 static int chopMenu(int menunum
)
664 int result
= (menunum
==0)?0:1;
666 bool menu_quit
= false;
668 static const struct opt_items levels
[2] = {
673 MENUITEM_STRINGLIST(menu
,"Chopper Menu",NULL
,"Start New Game","Resume Game",
676 #ifdef HAVE_LCD_COLOR
677 rb
->lcd_set_foreground(LCD_WHITE
);
678 rb
->lcd_set_background(LCD_BLACK
);
680 rb
->lcd_set_foreground(LCD_BLACK
);
681 rb
->lcd_set_background(LCD_WHITE
);
684 rb
->lcd_clear_display();
687 switch(rb
->do_menu(&menu
, &result
, NULL
, false))
689 case 0: /* Start New Game */
694 case 1: /* Resume Game */
698 } else if(menunum
==0){
699 rb
->splash(HZ
, "No game to resume");
703 rb
->set_option("Level", &iLevelMode
, INT
, levels
, 2, NULL
);
709 case MENU_ATTACHED_USB
:
711 res
= PLUGIN_USB_CONNECTED
;
715 rb
->lcd_clear_display();
719 static int chopGameLoop(void)
721 int move_button
, ret
;
723 int end
, i
=0, bdelay
=0, last_button
=BUTTON_NONE
;
725 if (chopUpdateTerrainRecycling(&mGround
) == 1)
726 /* mirror the sky if we've changed the ground */
727 chopCopyTerrain(&mGround
, &mRoof
, 0, - ( (iScreenY
* 3) / 4));
737 end
= *rb
->current_tick
+ (CYCLETIME
* HZ
) / 1000;
739 if(chopUpdateTerrainRecycling(&mGround
) == 1)
740 /* mirror the sky if we've changed the ground */
741 chopCopyTerrain(&mGround
, &mRoof
, 0, - ( (iScreenY
* 3) / 4));
743 iRotorOffset
= iR(-1,1);
745 /* We need to have this here so particles move when we're dead */
747 for (i
=0; i
< NUMBER_OF_PARTICLES
; i
++)
748 if(mParticles
[i
].bIsActive
== 1)
750 mParticles
[i
].iWorldX
+= mParticles
[i
].iSpeedX
;
751 mParticles
[i
].iWorldY
+= mParticles
[i
].iSpeedY
;
754 /* Redraw the main window: */
758 iGravityTimerCountdown
--;
760 if(iGravityTimerCountdown
<= 0)
762 iGravityTimerCountdown
= 3;
763 chopAddParticle(iPlayerPosX
, iPlayerPosY
+5, 0, 0);
766 if(iLevelMode
== LEVEL_MODE_NORMAL
)
767 chopGenerateBlockIfNeeded();
770 move_button
=rb
->button_status();
771 if (rb
->button_get(false) == QUIT
) {
776 last_button
= BUTTON_NONE
;
777 move_button
= BUTTON_NONE
;
780 switch (move_button
) {
785 if (last_button
!= ACTION
787 && last_button
!= ACTION2
796 if (last_button
== ACTION
798 || last_button
== ACTION2
805 if (rb
->default_event_handler(move_button
) == SYS_USB_CONNECTED
)
806 return PLUGIN_USB_CONNECTED
;
809 last_button
= move_button
;
812 iPlayerSpeedY
= bdelay
;
814 } else if (bdelay
> 0) {
815 iPlayerSpeedY
= bdelay
;
819 iCameraPosX
= iPlayerPosX
- 25;
820 iPlayerPosX
+= iPlayerSpeedX
;
821 iPlayerPosY
+= iPlayerSpeedY
;
824 /* increase speed as we go along */
825 if (chopCounter
== 100){
830 if (iPlayerPosY
> iScreenY
-10 || iPlayerPosY
< -5 ||
831 chopPointInTerrain(&mGround
, iPlayerPosX
, iPlayerPosY
+ 10, 0) ||
832 chopPointInTerrain(&mRoof
, iPlayerPosX
,iPlayerPosY
, 1))
841 for (i
=0; i
< NUMBER_OF_BLOCKS
; i
++)
842 if(mBlocks
[i
].bIsActive
== 1)
843 if(chopBlockCollideWithPlayer(&mBlocks
[i
])) {
851 if (end
> *rb
->current_tick
)
852 rb
->sleep(end
-*rb
->current_tick
);
860 static void chopDrawBlock(struct CBlock
*mBlock
)
862 int iPosX
= (mBlock
->iWorldX
- iCameraPosX
);
863 int iPosY
= (mBlock
->iWorldY
);
865 rb
->lcd_set_foreground(LCD_RGBPACK(100,255,100));
867 rb
->lcd_set_foreground(LCD_BLACK
);
869 rb
->lcd_fillrect(SCALE(iPosX
), SCALE(iPosY
), SCALE(mBlock
->iSizeX
),
870 SCALE(mBlock
->iSizeY
));
874 static void chopRenderTerrain(struct CTerrain
*ter
)
882 if(ter
->mNodes
[0].y
< (LCD_HEIGHT
*SIZE
)/2)
885 ay
=(LCD_HEIGHT
*SIZE
);
887 while(i
< ter
->iNodesCount
&& oldx
< iScreenX
)
890 int x
= ter
->mNodes
[i
-1].x
- iCameraPosX
;
891 int y
= ter
->mNodes
[i
-1].y
;
893 int x2
= ter
->mNodes
[i
].x
- iCameraPosX
;
894 int y2
= ter
->mNodes
[i
].y
;
896 rb
->lcd_set_foreground(LCD_RGBPACK(100,255,100));
898 rb
->lcd_set_foreground(LCD_DARKGRAY
);
901 rb
->lcd_drawline(SCALE(x
), SCALE(y
), SCALE(x2
), SCALE(y2
));
903 xlcd_filltriangle(SCALE(x
), SCALE(y
), SCALE(x2
), SCALE(y2
),
904 SCALE(x2
), SCALE(ay
));
905 xlcd_filltriangle(SCALE(x
), SCALE(ay
), SCALE(x2
), SCALE(y2
),
906 SCALE(x2
), SCALE(ay
));
909 xlcd_filltriangle(SCALE(x
), SCALE(ay
), SCALE(x
), SCALE(y
),
910 SCALE(x2
), SCALE(y2
/ 2));
912 xlcd_filltriangle(SCALE(x
), SCALE(ay
), SCALE(x
), SCALE(y
),
913 SCALE(x2
), SCALE((LCD_HEIGHT
*SIZE
) -
914 ((LCD_HEIGHT
*SIZE
) - y2
) / 2));
923 void chopper_load(bool newgame
)
930 iScreenX
= LCD_WIDTH
* SIZE
;
931 iScreenY
= LCD_HEIGHT
* SIZE
;
932 blockh
= iScreenY
/ 5;
933 blockw
= iScreenX
/ 20;
939 iPlayerPosY
= (iScreenY
* 4) / 10;
940 iLastBlockPlacedPosX
= 0;
941 iGravityTimerCountdown
= 2;
947 for (i
=0; i
< NUMBER_OF_PARTICLES
; i
++)
948 mParticles
[i
].bIsActive
= 0;
950 for (i
=0; i
< NUMBER_OF_BLOCKS
; i
++)
951 mBlocks
[i
].bIsActive
= 0;
954 chopClearTerrain(&mGround
);
956 for (i
=0; i
< MAX_TERRAIN_NODES
; i
++)
957 chopAddTerrainNode(&mGround
,i
* 30,g
- iR(0,20));
959 if (chopUpdateTerrainRecycling(&mGround
) == 1)
960 /* mirror the sky if we've changed the ground */
961 chopCopyTerrain(&mGround
, &mRoof
, 0, - ( (iScreenY
* 3) / 4));
963 iLevelMode
= LEVEL_MODE_NORMAL
;
964 if (iLevelMode
== LEVEL_MODE_NORMAL
)
965 /* make it a bit more exciting, cause it's easy terrain... */
969 /* this is the plugin entry point */
970 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
)
976 rb
->lcd_setfont(FONT_SYSFIXED
);
978 rb
->lcd_set_backdrop(NULL
);
980 #ifdef HAVE_LCD_COLOR
981 rb
->lcd_set_background(LCD_BLACK
);
982 rb
->lcd_set_foreground(LCD_WHITE
);
985 /* Turn off backlight timeout */
986 backlight_force_on(rb
); /* backlight control in lib/helper.c */
988 rb
->srand( *rb
->current_tick
);
992 configfile_load(CFG_FILE
, config
, 1, 0);
995 ret
= chopGameLoop();
997 configfile_save(CFG_FILE
, config
, 1, 0);
999 rb
->lcd_setfont(FONT_UI
);
1000 /* Turn on backlight timeout (revert to settings) */
1001 backlight_use_settings(rb
); /* backlight control in lib/helper.c */