1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 Eli Sherer
12 * Heavily modified for embedded use by Björn Stenberg (bjorn@haxx.se)
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
24 #include "lib/display_text.h"
25 #include "lib/helper.h"
26 #include "lib/highscore.h"
27 #include "lib/playback_control.h"
28 #include "lib/playergfx.h"
29 #include "lib/mylcd.h"
33 #if (CONFIG_KEYPAD == IPOD_4G_PAD) || \
34 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
35 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
37 #define ROCKBLOX_OFF (BUTTON_MENU | BUTTON_SELECT)
38 #define ROCKBLOX_ROTATE_CCW BUTTON_SCROLL_BACK
39 #define ROCKBLOX_ROTATE_CCW2 (BUTTON_MENU | BUTTON_REL)
40 #define ROCKBLOX_ROTATE_CW BUTTON_SCROLL_FWD
41 #define ROCKBLOX_LEFT BUTTON_LEFT
42 #define ROCKBLOX_RIGHT BUTTON_RIGHT
43 #define ROCKBLOX_DOWN BUTTON_PLAY
44 #define ROCKBLOX_RESTART (BUTTON_SELECT | BUTTON_PLAY)
45 #define ROCKBLOX_DROP (BUTTON_SELECT | BUTTON_REL)
47 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
48 (CONFIG_KEYPAD == IRIVER_H300_PAD)
50 #define ROCKBLOX_OFF BUTTON_OFF
51 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
52 #define ROCKBLOX_ROTATE_CW BUTTON_SELECT
53 #define ROCKBLOX_DOWN BUTTON_DOWN
54 #define ROCKBLOX_LEFT BUTTON_LEFT
55 #define ROCKBLOX_RIGHT BUTTON_RIGHT
56 #define ROCKBLOX_DROP BUTTON_MODE
57 #define ROCKBLOX_RESTART BUTTON_ON
59 #define ROCKBLOX_RC_OFF BUTTON_RC_STOP
61 #elif CONFIG_KEYPAD == RECORDER_PAD
63 #define ROCKBLOX_OFF BUTTON_OFF
64 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
65 #define ROCKBLOX_ROTATE_CW BUTTON_PLAY
66 #define ROCKBLOX_DOWN BUTTON_DOWN
67 #define ROCKBLOX_LEFT BUTTON_LEFT
68 #define ROCKBLOX_RIGHT BUTTON_RIGHT
69 #define ROCKBLOX_DROP BUTTON_ON
70 #define ROCKBLOX_RESTART BUTTON_F1
72 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
74 #define ROCKBLOX_OFF BUTTON_OFF
75 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
76 #define ROCKBLOX_ROTATE_CW BUTTON_SELECT
77 #define ROCKBLOX_DOWN BUTTON_DOWN
78 #define ROCKBLOX_LEFT BUTTON_LEFT
79 #define ROCKBLOX_RIGHT BUTTON_RIGHT
80 #define ROCKBLOX_DROP BUTTON_ON
81 #define ROCKBLOX_RESTART BUTTON_F1
83 #elif CONFIG_KEYPAD == PLAYER_PAD
85 #define ROCKBLOX_OFF_PRE BUTTON_STOP
86 #define ROCKBLOX_OFF (BUTTON_STOP|BUTTON_REL)
87 #define ROCKBLOX_ROTATE_CCW BUTTON_PLAY
88 #define ROCKBLOX_ROTATE_CW (BUTTON_ON|BUTTON_PLAY)
89 #define ROCKBLOX_DOWN BUTTON_MENU
90 #define ROCKBLOX_LEFT BUTTON_LEFT
91 #define ROCKBLOX_RIGHT BUTTON_RIGHT
92 #define ROCKBLOX_DROP_PRE BUTTON_ON
93 #define ROCKBLOX_DROP (BUTTON_ON|BUTTON_REL)
94 #define ROCKBLOX_RESTART (BUTTON_STOP|BUTTON_MENU)
96 #elif CONFIG_KEYPAD == ONDIO_PAD
98 #define ROCKBLOX_OFF_PRE BUTTON_OFF
99 #define ROCKBLOX_OFF (BUTTON_OFF|BUTTON_REL)
100 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
101 #define ROCKBLOX_ROTATE_CW (BUTTON_MENU|BUTTON_UP)
102 #define ROCKBLOX_DOWN BUTTON_DOWN
103 #define ROCKBLOX_LEFT BUTTON_LEFT
104 #define ROCKBLOX_RIGHT BUTTON_RIGHT
105 #define ROCKBLOX_DROP_PRE BUTTON_MENU
106 #define ROCKBLOX_DROP (BUTTON_MENU|BUTTON_REL)
107 #define ROCKBLOX_RESTART (BUTTON_OFF|BUTTON_MENU)
109 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
111 #define ROCKBLOX_OFF BUTTON_POWER
112 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
113 #define ROCKBLOX_ROTATE_CW BUTTON_SELECT
114 #define ROCKBLOX_DOWN BUTTON_DOWN
115 #define ROCKBLOX_LEFT BUTTON_LEFT
116 #define ROCKBLOX_RIGHT BUTTON_RIGHT
117 #define ROCKBLOX_DROP BUTTON_REC
118 #define ROCKBLOX_RESTART BUTTON_PLAY
120 #elif CONFIG_KEYPAD == SANSA_E200_PAD
122 #define ROCKBLOX_OFF BUTTON_POWER
123 #define ROCKBLOX_ROTATE_CCW BUTTON_SCROLL_BACK
124 #define ROCKBLOX_ROTATE_CCW2 BUTTON_UP
125 #define ROCKBLOX_ROTATE_CW BUTTON_SCROLL_FWD
126 #define ROCKBLOX_DOWN BUTTON_DOWN
127 #define ROCKBLOX_LEFT BUTTON_LEFT
128 #define ROCKBLOX_RIGHT BUTTON_RIGHT
129 #define ROCKBLOX_DROP BUTTON_SELECT
130 #define ROCKBLOX_RESTART BUTTON_REC
132 #elif CONFIG_KEYPAD == SANSA_FUZE_PAD
134 #define ROCKBLOX_OFF (BUTTON_HOME|BUTTON_REPEAT)
135 #define ROCKBLOX_ROTATE_CCW BUTTON_SCROLL_BACK
136 #define ROCKBLOX_ROTATE_CCW2 BUTTON_UP
137 #define ROCKBLOX_ROTATE_CW BUTTON_SCROLL_FWD
138 #define ROCKBLOX_DOWN BUTTON_DOWN
139 #define ROCKBLOX_LEFT BUTTON_LEFT
140 #define ROCKBLOX_RIGHT BUTTON_RIGHT
141 #define ROCKBLOX_DROP (BUTTON_SELECT | BUTTON_REL)
142 #define ROCKBLOX_RESTART (BUTTON_SELECT | BUTTON_UP)
145 #elif CONFIG_KEYPAD == SANSA_C200_PAD
147 #define ROCKBLOX_OFF BUTTON_POWER
148 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
149 #define ROCKBLOX_ROTATE_CCW2 BUTTON_VOL_DOWN
150 #define ROCKBLOX_ROTATE_CW BUTTON_VOL_UP
151 #define ROCKBLOX_DOWN BUTTON_DOWN
152 #define ROCKBLOX_LEFT BUTTON_LEFT
153 #define ROCKBLOX_RIGHT BUTTON_RIGHT
154 #define ROCKBLOX_DROP BUTTON_SELECT
155 #define ROCKBLOX_RESTART BUTTON_REC
157 #elif CONFIG_KEYPAD == SANSA_CLIP_PAD
159 #define ROCKBLOX_OFF BUTTON_POWER
160 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
161 #define ROCKBLOX_ROTATE_CCW2 BUTTON_VOL_DOWN
162 #define ROCKBLOX_ROTATE_CW BUTTON_VOL_UP
163 #define ROCKBLOX_DOWN BUTTON_DOWN
164 #define ROCKBLOX_LEFT BUTTON_LEFT
165 #define ROCKBLOX_RIGHT BUTTON_RIGHT
166 #define ROCKBLOX_DROP BUTTON_SELECT
167 #define ROCKBLOX_RESTART BUTTON_HOME
169 #elif CONFIG_KEYPAD == SANSA_M200_PAD
171 #define ROCKBLOX_OFF BUTTON_POWER
172 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
173 #define ROCKBLOX_ROTATE_CCW2 BUTTON_VOL_DOWN
174 #define ROCKBLOX_ROTATE_CW BUTTON_VOL_UP
175 #define ROCKBLOX_DOWN BUTTON_DOWN
176 #define ROCKBLOX_LEFT BUTTON_LEFT
177 #define ROCKBLOX_RIGHT BUTTON_RIGHT
178 #define ROCKBLOX_RESTART (BUTTON_SELECT | BUTTON_UP)
179 #define ROCKBLOX_DROP (BUTTON_SELECT | BUTTON_REL)
181 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
183 #define ROCKBLOX_OFF BUTTON_POWER
184 #define ROCKBLOX_ROTATE_CCW BUTTON_SCROLL_UP
185 #define ROCKBLOX_ROTATE_CW BUTTON_REW
186 #define ROCKBLOX_DOWN BUTTON_SCROLL_DOWN
187 #define ROCKBLOX_LEFT BUTTON_LEFT
188 #define ROCKBLOX_RIGHT BUTTON_RIGHT
189 #define ROCKBLOX_DROP BUTTON_FF
190 #define ROCKBLOX_RESTART BUTTON_PLAY
192 #elif CONFIG_KEYPAD == GIGABEAT_PAD
194 #define ROCKBLOX_OFF BUTTON_POWER
195 #define ROCKBLOX_ROTATE_CCW BUTTON_VOL_DOWN
196 #define ROCKBLOX_ROTATE_CW BUTTON_VOL_UP
197 #define ROCKBLOX_ROTATE BUTTON_UP
198 #define ROCKBLOX_DOWN BUTTON_DOWN
199 #define ROCKBLOX_LEFT BUTTON_LEFT
200 #define ROCKBLOX_RIGHT BUTTON_RIGHT
201 #define ROCKBLOX_DROP BUTTON_SELECT
202 #define ROCKBLOX_RESTART BUTTON_A
204 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
206 #define ROCKBLOX_OFF BUTTON_PLAY
207 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
208 #define ROCKBLOX_ROTATE_CW BUTTON_SELECT
209 #define ROCKBLOX_DOWN BUTTON_DOWN
210 #define ROCKBLOX_LEFT BUTTON_LEFT
211 #define ROCKBLOX_RIGHT BUTTON_RIGHT
212 #define ROCKBLOX_DROP BUTTON_MODE
213 #define ROCKBLOX_RESTART BUTTON_EQ
215 #elif CONFIG_KEYPAD == MROBE500_PAD
216 #define ROCKBLOX_OFF BUTTON_POWER
218 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
219 #define ROCKBLOX_OFF BUTTON_BACK
220 #define ROCKBLOX_ROTATE_CCW BUTTON_VOL_DOWN
221 #define ROCKBLOX_ROTATE_CW BUTTON_VOL_UP
222 #define ROCKBLOX_ROTATE BUTTON_UP
223 #define ROCKBLOX_DOWN BUTTON_DOWN
224 #define ROCKBLOX_LEFT BUTTON_LEFT
225 #define ROCKBLOX_RIGHT BUTTON_RIGHT
226 #define ROCKBLOX_DROP BUTTON_SELECT
227 #define ROCKBLOX_RESTART BUTTON_PLAY
229 #elif CONFIG_KEYPAD == MROBE100_PAD
231 #define ROCKBLOX_OFF BUTTON_POWER
232 #define ROCKBLOX_ROTATE_CCW BUTTON_MENU
233 #define ROCKBLOX_ROTATE_CW BUTTON_PLAY
234 #define ROCKBLOX_ROTATE BUTTON_UP
235 #define ROCKBLOX_DOWN BUTTON_DOWN
236 #define ROCKBLOX_LEFT BUTTON_LEFT
237 #define ROCKBLOX_RIGHT BUTTON_RIGHT
238 #define ROCKBLOX_DROP BUTTON_SELECT
239 #define ROCKBLOX_RESTART BUTTON_DISPLAY
241 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
243 #define ROCKBLOX_OFF BUTTON_RC_REC
244 #define ROCKBLOX_ROTATE_CCW BUTTON_RC_VOL_DOWN
245 #define ROCKBLOX_ROTATE_CW BUTTON_RC_VOL_UP
246 #define ROCKBLOX_DOWN BUTTON_RC_MENU
247 #define ROCKBLOX_LEFT BUTTON_RC_REW
248 #define ROCKBLOX_RIGHT BUTTON_RC_FF
249 #define ROCKBLOX_DROP BUTTON_RC_PLAY
250 #define ROCKBLOX_RESTART BUTTON_RC_MODE
252 #elif CONFIG_KEYPAD == COWON_D2_PAD
254 #define ROCKBLOX_OFF BUTTON_POWER
255 #define ROCKBLOX_RESTART BUTTON_MENU
257 #elif CONFIG_KEYPAD == IAUDIO67_PAD
259 #define ROCKBLOX_OFF BUTTON_POWER
260 #define ROCKBLOX_ROTATE_CCW BUTTON_VOLDOWN
261 #define ROCKBLOX_ROTATE_CW BUTTON_VOLUP
262 #define ROCKBLOX_DOWN BUTTON_STOP
263 #define ROCKBLOX_LEFT BUTTON_LEFT
264 #define ROCKBLOX_RIGHT BUTTON_RIGHT
265 #define ROCKBLOX_DROP BUTTON_PLAY
266 #define ROCKBLOX_RESTART BUTTON_MENU
268 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
269 #define ROCKBLOX_OFF BUTTON_BACK
270 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
271 #define ROCKBLOX_ROTATE_CW BUTTON_PLAY
272 #define ROCKBLOX_DOWN BUTTON_DOWN
273 #define ROCKBLOX_LEFT BUTTON_LEFT
274 #define ROCKBLOX_RIGHT BUTTON_RIGHT
275 #define ROCKBLOX_DROP BUTTON_SELECT
276 #define ROCKBLOX_RESTART BUTTON_CUSTOM
278 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
280 #define ROCKBLOX_OFF BUTTON_POWER
281 #define ROCKBLOX_ROTATE_CCW BUTTON_VOL_DOWN
282 #define ROCKBLOX_ROTATE_CW BUTTON_VOL_UP
283 #define ROCKBLOX_ROTATE BUTTON_UP
284 #define ROCKBLOX_DOWN BUTTON_DOWN
285 #define ROCKBLOX_LEFT BUTTON_LEFT
286 #define ROCKBLOX_RIGHT BUTTON_RIGHT
287 #define ROCKBLOX_DROP BUTTON_SELECT
288 #define ROCKBLOX_RESTART BUTTON_MENU
290 # elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
292 #define ROCKBLOX_OFF BUTTON_POWER
293 #define ROCKBLOX_ROTATE_CCW BUTTON_VOL_DOWN
294 #define ROCKBLOX_ROTATE_CW BUTTON_VOL_UP
295 #define ROCKBLOX_ROTATE BUTTON_UP
296 #define ROCKBLOX_DOWN BUTTON_DOWN
297 #define ROCKBLOX_LEFT BUTTON_PREV
298 #define ROCKBLOX_RIGHT BUTTON_NEXT
299 #define ROCKBLOX_DROP BUTTON_PLAY
300 #define ROCKBLOX_RESTART BUTTON_MENU
302 #elif CONFIG_KEYPAD == ONDAVX747_PAD
303 #define ROCKBLOX_OFF BUTTON_POWER
304 #define ROCKBLOX_RESTART BUTTON_MENU
305 #elif CONFIG_KEYPAD == ONDAVX777_PAD
306 #define ROCKBLOX_OFF BUTTON_POWER
308 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
310 #define ROCKBLOX_OFF (BUTTON_REC|BUTTON_PLAY)
311 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
312 #define ROCKBLOX_ROTATE_CW BUTTON_DOWN
313 #define ROCKBLOX_DOWN BUTTON_REW
314 #define ROCKBLOX_LEFT BUTTON_LEFT
315 #define ROCKBLOX_RIGHT BUTTON_RIGHT
316 #define ROCKBLOX_DROP BUTTON_FFWD
317 #define ROCKBLOX_RESTART (BUTTON_REC|BUTTON_REW)
319 #elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
321 #define ROCKBLOX_OFF BUTTON_REC
322 #define ROCKBLOX_ROTATE_CCW BUTTON_PLAY
323 #define ROCKBLOX_ROTATE_CW BUTTON_MENU
324 #define ROCKBLOX_DOWN BUTTON_DOWN
325 #define ROCKBLOX_LEFT BUTTON_PREV
326 #define ROCKBLOX_RIGHT BUTTON_NEXT
327 #define ROCKBLOX_DROP BUTTON_OK
328 #define ROCKBLOX_RESTART BUTTON_CANCEL
330 #elif CONFIG_KEYPAD == MPIO_HD200_PAD
331 #define ROCKBLOX_OFF (BUTTON_REC|BUTTON_PLAY)
332 #define ROCKBLOX_ROTATE_CCW BUTTON_REW
333 #define ROCKBLOX_ROTATE_CW BUTTON_FF
334 #define ROCKBLOX_DOWN BUTTON_FUNC
335 #define ROCKBLOX_LEFT BUTTON_VOL_DOWN
336 #define ROCKBLOX_RIGHT BUTTON_VOL_UP
337 #define ROCKBLOX_DROP BUTTON_PLAY
338 #define ROCKBLOX_RESTART BUTTON_REC
341 #error No keymap defined!
344 #ifdef HAVE_TOUCHSCREEN
346 #define ROCKBLOX_OFF BUTTON_TOPLEFT
348 #ifdef ROCKBLOX_ROTATE_CCW
349 #define ROCKBLOX_ROTATE_CCW2 BUTTON_BOTTOMLEFT
351 #define ROCKBLOX_ROTATE_CCW BUTTON_BOTTOMLEFT
353 #ifdef ROCKBLOX_ROTATE_CW
354 #define ROCKBLOX_ROTATE_CW2 BUTTON_BOTTOMRIGHT
356 #define ROCKBLOX_ROTATE_CW BUTTON_BOTTOMRIGHT
357 #define ROCKBLOX_ROTATE_CW2 BUTTON_TOPMIDDLE
359 #ifndef ROCKBLOX_DOWN
360 #define ROCKBLOX_DOWN BUTTON_BOTTOMMIDDLE
362 #ifndef ROCKBLOX_LEFT
363 #define ROCKBLOX_LEFT BUTTON_MIDLEFT
365 #ifndef ROCKBLOX_RIGHT
366 #define ROCKBLOX_RIGHT BUTTON_MIDRIGHT
368 #ifndef ROCKBLOX_DROP
369 #define ROCKBLOX_DROP BUTTON_CENTER
371 #ifndef ROCKBLOX_RESTART
372 #define ROCKBLOX_RESTART BUTTON_TOPRIGHT
377 #define EMPTY_BLOCK 7
379 #define BOARD_WIDTH 10
381 #ifdef HAVE_LCD_BITMAP
383 #define BOARD_HEIGHT 20
385 #if (LCD_WIDTH == 640) && (LCD_HEIGHT == 480)
387 #define BLOCK_WIDTH 24
388 #define BLOCK_HEIGHT 24
398 #elif (LCD_WIDTH == 480) && (LCD_HEIGHT == 640)
400 #define BLOCK_WIDTH 30
401 #define BLOCK_HEIGHT 30
404 #define PREVIEW_X 342
405 #define PREVIEW_Y 482
411 #elif (LCD_WIDTH == 320) && (LCD_HEIGHT == 240)
413 #define BLOCK_WIDTH 12
414 #define BLOCK_HEIGHT 12
424 #elif (LCD_WIDTH == 240) && ((LCD_HEIGHT == 320) || (LCD_HEIGHT == 400))
426 #define BLOCK_WIDTH 15
427 #define BLOCK_HEIGHT 15
430 #define PREVIEW_X 171
431 #define PREVIEW_Y 241
436 #define HIGH_LABEL_X 172
437 #define HIGH_SCORE_Y 163
438 #define HIGH_LEVEL_Y 172
440 #elif (LCD_WIDTH == 220) && (LCD_HEIGHT == 176)
442 #define BLOCK_WIDTH 8
443 #define BLOCK_HEIGHT 8
446 #define PREVIEW_X 158
447 #define PREVIEW_Y 130
453 #elif (LCD_WIDTH == 176) && (LCD_HEIGHT == 132)
455 #define BLOCK_WIDTH 6
456 #define BLOCK_HEIGHT 6
459 #define PREVIEW_X 126
460 #define PREVIEW_Y 102
466 #elif (LCD_WIDTH == 176) && (LCD_HEIGHT == 220)
468 /* no room for the space in the highscore list */
471 #define BLOCK_WIDTH 10
472 #define BLOCK_HEIGHT 10
475 #define PREVIEW_X 124
476 #define PREVIEW_Y 174
481 #define HIGH_SCORE_Y 119
482 #define HIGH_LEVEL_Y 126
483 #define HIGH_LABEL_X 114
485 #elif (LCD_WIDTH == 160) && (LCD_HEIGHT == 128)
488 #define BLOCK_WIDTH 6
489 #define BLOCK_HEIGHT 6
492 #define PREVIEW_X 114
493 #define PREVIEW_Y 100
499 #elif (LCD_WIDTH == 138) && (LCD_HEIGHT == 110)
501 #define BLOCK_WIDTH 5
502 #define BLOCK_HEIGHT 5
512 #elif (LCD_WIDTH == 132) && (LCD_HEIGHT == 80)
514 #define BLOCK_WIDTH 4
515 #define BLOCK_HEIGHT 4
525 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 128)
527 #define BLOCK_WIDTH 6
528 #define BLOCK_HEIGHT 6
532 #define PREVIEW_Y 100
538 /* NOTE: This is for the GoGear SA9200 and is only
539 temporary until I can get better coordinates! */
540 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 160)
542 #define BLOCK_WIDTH 6
543 #define BLOCK_HEIGHT 6
547 #define PREVIEW_Y 100
553 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 96)
555 #define BLOCK_WIDTH 4
556 #define BLOCK_HEIGHT 4
566 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 64)
568 #define BLOCK_WIDTH 3
569 #define BLOCK_HEIGHT 3
579 #elif (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
581 #define BLOCK_WIDTH 4
582 #define BLOCK_HEIGHT 3
596 #define LEVEL_X LABEL_X
600 #define LINES_X LABEL_X
603 extern const fb_data rockblox_background
[];
605 #else /* HAVE_LCD_CHARCELLS */
607 #define BOARD_HEIGHT 14
609 #define BLOCK_WIDTH 1
610 #define BLOCK_HEIGHT 1
621 /* <<Explanation on Rockblox shapes>>
624 %% - O has 1 orientation
627 %% %% - Z has 2 orientations
631 %% %% - S has 2 orientations
635 % %%%% - I has 2 orientations
639 % % % %%% - L has 4 orientations
643 % % % %%% - J has 4 orientations
647 %% % %% % - T has 4 orientations
651 /* c=current f=figure o=orientation n=next */
652 static struct _rockblox_status
663 short board
[BOARD_HEIGHT
][BOARD_WIDTH
]; /* 20 rows of 10 blocks */
667 static void draw_next_block(void);
668 static void new_block(void);
670 #ifdef HAVE_SCROLLWHEEL
671 int wheel_events
= 0, last_wheel_event
= 0;
672 bool wheel_enabled
= false;
675 static const short scoring
[4] = { /* scoring for each number of lines */
676 #if BOARD_HEIGHT == 20
677 40 /* single */ , 100 /* double */ , 300 /* triple */ , 1200 /* rockblox */
678 #elif BOARD_HEIGHT == 14 /* Player special values */
679 60 /* single */ , 150 /* double */ , 500 /* triple */ , 2000 /* rockblox */
686 unsigned short color
[3]; /* color of figure (light,middle,shadow) */
688 unsigned short max_or
; /* max orientations */
689 signed short shapeX
[4], shapeY
[4]; /* implementation of figures */
692 /* array of figures */
693 figures
[BLOCKS_NUM
] = {
697 {LCD_RGBPACK (153, 255, 255), LCD_RGBPACK(0, 255, 255),
698 LCD_RGBPACK(0,153,153)},
700 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
709 {LCD_RGBPACK (255, 153, 128), LCD_RGBPACK (255, 0, 0),
710 LCD_RGBPACK (153, 0, 0)},
712 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
721 {LCD_RGBPACK (153, 255, 153), LCD_RGBPACK (0, 255, 0),
722 LCD_RGBPACK (0, 153, 0)},
724 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
733 {LCD_RGBPACK (153, 153, 255), LCD_RGBPACK (0, 0, 255),
734 LCD_RGBPACK (0, 0, 153)},
736 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
745 {LCD_RGBPACK (255, 255, 153), LCD_RGBPACK (255, 255, 0),
746 LCD_RGBPACK (153, 153, 0)},
748 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
757 {LCD_RGBPACK (255, 153, 255), LCD_RGBPACK (255, 0, 255),
758 LCD_RGBPACK (153, 0, 153)},
760 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
769 {LCD_RGBPACK (204, 204, 204), LCD_RGBPACK (153, 153, 153),
770 LCD_RGBPACK (85, 85, 85)},
772 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
780 bool resume_file
= false;
782 /* Rockbox File System only supports full filenames inc dir */
783 #define SCORE_FILE PLUGIN_GAMES_DIR "/rockblox.score"
784 #define RESUME_FILE PLUGIN_GAMES_DIR "/rockblox.resume"
787 /* Default High Scores... */
788 struct highscore highscores
[NUM_SCORES
];
790 /* get random number from (0) to (range-1) */
791 static int t_rand (int range
)
793 return rb
->rand () % range
;
796 static inline void show_game_over (void)
798 rb
->splash(HZ
,"Game over!");
801 /* init the board array to have no blocks */
802 static void init_board (void)
805 for (i
= 0; i
< BOARD_WIDTH
; i
++)
806 for (j
= 0; j
< BOARD_HEIGHT
; j
++)
807 rockblox_status
.board
[j
][i
] = EMPTY_BLOCK
;
810 /* show the score, level and lines */
811 static void show_details (void)
813 #ifdef HAVE_LCD_BITMAP
815 rb
->lcd_set_foreground (LCD_BLACK
);
816 rb
->lcd_set_background (LCD_WHITE
);
818 rb
->lcd_putsxyf (LABEL_X
, SCORE_Y
, "%d", rockblox_status
.score
);
819 rb
->lcd_putsxyf (LEVEL_X
, LEVEL_Y
, "%d", rockblox_status
.level
);
820 rb
->lcd_putsxyf (LINES_X
, LINES_Y
, "%d", rockblox_status
.lines
);
821 #else /* HAVE_LCD_CHARCELLS */
822 rb
->lcd_putsf (5, 0, "L%d/%d", rockblox_status
.level
,
823 rockblox_status
.lines
);
824 rb
->lcd_putsf (5, 1, "S%d", rockblox_status
.score
);
829 static void show_highscores (void)
833 for (i
= 0; i
<NUM_SCORES
; i
++)
834 rb
->lcd_putsxyf (HIGH_LABEL_X
, HIGH_SCORE_Y
+ (10 * i
),
835 "%06d" _SPACE
"L%1d", highscores
[i
].score
, highscores
[i
].level
);
839 static void load_game(void)
845 fd
= rb
->open(RESUME_FILE
, O_RDONLY
);
848 if (rb
->read(fd
, &rockblox_status
, sizeof(struct _rockblox_status
))
849 < (ssize_t
)sizeof(struct _rockblox_status
))
851 rb
->splash(HZ
/2, "Loading Rockblox resume info failed");
862 static void dump_resume(void)
866 fd
= rb
->open(RESUME_FILE
, O_WRONLY
|O_CREAT
, 0666);
870 if (rb
->write(fd
, &rockblox_status
, sizeof(struct _rockblox_status
))
880 rb
->splash(HZ
/2, "Writing Rockblox resume info failed");
884 static void init_rockblox (bool resume
)
890 rb
->snprintf(score_name
, sizeof(score_name
), "%04d%02d%02d %02d%02d%02d",
891 tm
->tm_year
+ 1900, tm
->tm_mon
+ 1, tm
->tm_mday
,
892 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
894 #ifdef HAVE_LCD_BITMAP
895 rb
->lcd_bitmap (rockblox_background
, 0, 0, LCD_WIDTH
, LCD_HEIGHT
);
896 #else /* HAVE_LCD_CHARCELLS */
898 pgfx_display_block (3, 0, 3, 1);
899 pgfx_display_block (4, 0, 3, 0);
900 rb
->lcd_puts(4, 1, " ");
901 pgfx_clear_display();
902 pgfx_fillrect (3, 0, 2, 14);
903 pgfx_fillrect (15, 7, 2, 7);
908 rockblox_status
.level
= 1;
909 rockblox_status
.lines
= 0;
910 rockblox_status
.score
= 0;
911 rockblox_status
.nf
= t_rand(BLOCKS_NUM
);
923 static inline int level_speed(int level
)
925 #if BOARD_HEIGHT == 20
926 return (5*HZ
) / (level
+ 9);
927 #elif BOARD_HEIGHT == 14
928 return (7*HZ
) / (level
+ 9);
932 static int getRelativeX (int figure
, int square
, int orientation
)
934 switch (orientation
) {
936 return figures
[figure
].shapeX
[square
];
938 return figures
[figure
].shapeY
[square
];
940 return -figures
[figure
].shapeX
[square
];
942 return -figures
[figure
].shapeY
[square
];
948 static int getRelativeY (int figure
, int square
, int orientation
)
950 switch (orientation
) {
952 return figures
[figure
].shapeY
[square
];
954 return -figures
[figure
].shapeX
[square
];
956 return -figures
[figure
].shapeY
[square
];
958 return figures
[figure
].shapeX
[square
];
964 /* redraw the while board on the screen */
965 static void refresh_board (void)
967 int i
, j
, x
, y
, block
;
970 rb
->lcd_set_foreground (LCD_BLACK
);
972 mylcd_set_drawmode (DRMODE_SOLID
| DRMODE_INVERSEVID
);
975 mylcd_fillrect (BOARD_X
, BOARD_Y
, BOARD_WIDTH
* BLOCK_WIDTH
,
976 BOARD_HEIGHT
* BLOCK_HEIGHT
);
979 mylcd_set_drawmode (DRMODE_SOLID
);
982 for (i
= 0; i
< BOARD_WIDTH
; i
++)
983 for (j
= 0; j
< BOARD_HEIGHT
; j
++) {
984 block
= rockblox_status
.board
[j
][i
];
985 if (block
!= EMPTY_BLOCK
) {
986 #ifdef HAVE_LCD_BITMAP
989 rb
->lcd_set_foreground (figures
[block
].color
[1]);
991 rb
->lcd_fillrect (BOARD_X
+ i
* BLOCK_WIDTH
,
992 BOARD_Y
+ j
* BLOCK_HEIGHT
,
993 BLOCK_WIDTH
, BLOCK_HEIGHT
);
996 rb
->lcd_set_foreground (figures
[block
].color
[0]);
998 rb
->lcd_vline (BOARD_X
+ i
* BLOCK_WIDTH
,
999 BOARD_Y
+ j
* BLOCK_HEIGHT
,
1000 BOARD_Y
+ (j
+ 1) * BLOCK_HEIGHT
- 2);
1001 rb
->lcd_hline (BOARD_X
+ i
* BLOCK_WIDTH
,
1002 BOARD_X
+ (i
+ 1) * BLOCK_WIDTH
- 2,
1003 BOARD_Y
+ j
* BLOCK_HEIGHT
);
1005 /* shadow drawing */
1006 rb
->lcd_set_foreground (figures
[block
].color
[2]);
1008 rb
->lcd_vline (BOARD_X
+ (i
+ 1) * BLOCK_WIDTH
- 1,
1009 BOARD_Y
+ j
* BLOCK_HEIGHT
+ 1,
1010 BOARD_Y
+ (j
+ 1) * BLOCK_HEIGHT
- 1);
1011 rb
->lcd_hline (BOARD_X
+ i
* BLOCK_WIDTH
+ 1,
1012 BOARD_X
+ (i
+ 1) * BLOCK_WIDTH
- 1,
1013 BOARD_Y
+ (j
+ 1) * BLOCK_HEIGHT
- 1);
1014 #else /* HAVE_LCD_CHARCELLS */
1015 pgfx_drawpixel (BOARD_X
+ i
, BOARD_Y
+ j
);
1020 for (i
= 0; i
< 4; i
++) {
1021 x
= getRelativeX (rockblox_status
.cf
, i
, rockblox_status
.co
)
1022 + rockblox_status
.cx
;
1023 y
= getRelativeY (rockblox_status
.cf
, i
, rockblox_status
.co
)
1024 + rockblox_status
.cy
;
1025 #ifdef HAVE_LCD_BITMAP
1027 /* middle drawing */
1028 rb
->lcd_set_foreground (figures
[rockblox_status
.cf
].color
[1]);
1030 rb
->lcd_fillrect (BOARD_X
+ x
* BLOCK_WIDTH
,
1031 BOARD_Y
+ y
* BLOCK_HEIGHT
,
1032 BLOCK_WIDTH
, BLOCK_HEIGHT
);
1035 rb
->lcd_set_foreground (figures
[rockblox_status
.cf
].color
[0]);
1037 rb
->lcd_vline (BOARD_X
+ x
* BLOCK_WIDTH
, BOARD_Y
+ y
* BLOCK_HEIGHT
,
1038 BOARD_Y
+ (y
+ 1) * BLOCK_HEIGHT
- 2);
1039 rb
->lcd_hline (BOARD_X
+ x
* BLOCK_WIDTH
,
1040 BOARD_X
+ (x
+ 1) * BLOCK_WIDTH
- 2,
1041 BOARD_Y
+ y
* BLOCK_HEIGHT
);
1043 /* shadow drawing */
1044 rb
->lcd_set_foreground (figures
[rockblox_status
.cf
].color
[2]);
1046 rb
->lcd_vline (BOARD_X
+ (x
+ 1) * BLOCK_WIDTH
- 1,
1047 BOARD_Y
+ y
* BLOCK_HEIGHT
+ 1,
1048 BOARD_Y
+ (y
+ 1) * BLOCK_HEIGHT
- 1);
1049 rb
->lcd_hline (BOARD_X
+ x
* BLOCK_WIDTH
+ 1,
1050 BOARD_X
+ (x
+ 1) * BLOCK_WIDTH
- 1,
1051 BOARD_Y
+ (y
+ 1) * BLOCK_HEIGHT
- 1);
1052 #else /* HAVE_LCD_CHARCELLS */
1053 pgfx_drawpixel (BOARD_X
+ x
, BOARD_Y
+ y
);
1059 static bool canMoveTo (int x
, int y
, int newOrientation
)
1062 for (i
= 0; i
< 4; i
++) {
1063 ry
= getRelativeY (rockblox_status
.cf
, i
, newOrientation
) + y
;
1064 rx
= getRelativeX (rockblox_status
.cf
, i
, newOrientation
) + x
;
1065 if ((rx
< 0 || rx
>= BOARD_WIDTH
) ||
1066 (ry
< 0 || ry
>= BOARD_HEIGHT
) ||
1067 (rockblox_status
.board
[ry
][rx
] != EMPTY_BLOCK
))
1073 /* draws the preview of next block in the preview window */
1074 static void draw_next_block (void)
1077 /* clear preview window first */
1079 rb
->lcd_set_foreground (LCD_BLACK
);
1080 #elif LCD_DEPTH == 1
1081 mylcd_set_drawmode (DRMODE_SOLID
| DRMODE_INVERSEVID
);
1085 mylcd_fillrect (PREVIEW_X
, PREVIEW_Y
, BLOCK_WIDTH
* 4, BLOCK_HEIGHT
* 4);
1088 mylcd_set_drawmode (DRMODE_SOLID
);
1091 /* draw the lightgray rectangles */
1093 rb
->lcd_set_foreground (LCD_RGBPACK (40, 40, 40));
1094 #elif LCD_DEPTH == 2
1095 rb
->lcd_set_foreground (LCD_DARKGRAY
);
1099 for (rx
= 0; rx
< 4; rx
++)
1100 for (ry
= 0; ry
< 4; ry
++)
1101 rb
->lcd_drawrect (PREVIEW_X
+ rx
* BLOCK_WIDTH
,
1102 PREVIEW_Y
+ ry
* BLOCK_HEIGHT
, BLOCK_WIDTH
,
1106 /* draw the figure */
1107 for (i
= 0; i
< 4; i
++) {
1108 rx
= getRelativeX (rockblox_status
.nf
, i
, 0) + 2;
1109 ry
= getRelativeY (rockblox_status
.nf
, i
, 0) + 2;
1110 #ifdef HAVE_LCD_BITMAP
1112 rb
->lcd_set_foreground (figures
[rockblox_status
.nf
].color
[1]); /* middle drawing */
1114 rb
->lcd_fillrect (PREVIEW_X
+ rx
* BLOCK_WIDTH
,
1115 PREVIEW_Y
+ ry
* BLOCK_HEIGHT
,
1116 BLOCK_WIDTH
, BLOCK_HEIGHT
);
1118 rb
->lcd_set_foreground (figures
[rockblox_status
.nf
].color
[0]); /* light drawing */
1120 rb
->lcd_vline (PREVIEW_X
+ rx
* BLOCK_WIDTH
,
1121 PREVIEW_Y
+ ry
* BLOCK_HEIGHT
,
1122 PREVIEW_Y
+ (ry
+ 1) * BLOCK_HEIGHT
- 2);
1123 rb
->lcd_hline (PREVIEW_X
+ rx
* BLOCK_WIDTH
,
1124 PREVIEW_X
+ (rx
+ 1) * BLOCK_WIDTH
- 2,
1125 PREVIEW_Y
+ ry
* BLOCK_HEIGHT
);
1127 rb
->lcd_set_foreground (figures
[rockblox_status
.nf
].color
[2]); /* shadow drawing */
1129 rb
->lcd_vline (PREVIEW_X
+ (rx
+ 1) * BLOCK_WIDTH
- 1,
1130 PREVIEW_Y
+ ry
* BLOCK_HEIGHT
+ 1,
1131 PREVIEW_Y
+ (ry
+ 1) * BLOCK_HEIGHT
- 1);
1132 rb
->lcd_hline (PREVIEW_X
+ rx
* BLOCK_WIDTH
+ 1,
1133 PREVIEW_X
+ (rx
+ 1) * BLOCK_WIDTH
- 1,
1134 PREVIEW_Y
+ (ry
+ 1) * BLOCK_HEIGHT
- 1);
1135 #else /* HAVE_LCD_CHARCELLS */
1136 pgfx_drawpixel (PREVIEW_X
+ rx
, PREVIEW_Y
+ ry
);
1142 /* move the block to a relative location */
1143 static void move_block (int x
, int y
, int o
)
1145 if (canMoveTo (rockblox_status
.cx
+ x
, rockblox_status
.cy
+ y
, o
)) {
1146 rockblox_status
.cy
+= y
;
1147 rockblox_status
.cx
+= x
;
1148 rockblox_status
.co
= o
;
1152 /* try to add a new block to play with (return true if gameover) */
1153 static void new_block (void)
1155 rockblox_status
.cy
= 1;
1156 rockblox_status
.cx
= 5;
1157 rockblox_status
.cf
= rockblox_status
.nf
;
1158 rockblox_status
.co
= 0; /* start at the same orientation all time */
1159 rockblox_status
.nf
= t_rand (BLOCKS_NUM
);
1160 rockblox_status
.gameover
= !canMoveTo (rockblox_status
.cx
,
1161 rockblox_status
.cy
, rockblox_status
.co
);
1167 /* check for filled rockblox_status.lines and do what necessary */
1168 static int check_lines (void)
1174 for (j
= 0; j
< BOARD_HEIGHT
; j
++) {
1175 for (i
= 0; ((i
< BOARD_WIDTH
) &&
1176 (rockblox_status
.board
[j
][i
] != EMPTY_BLOCK
)); i
++);
1177 if (i
== BOARD_WIDTH
) { /* woo hoo, we have a line */
1179 for (y
= j
; y
> 0; y
--)
1181 for (i
= 0; i
< BOARD_WIDTH
; i
++)
1183 rockblox_status
.board
[y
][i
] = rockblox_status
.board
[y
- 1][i
];
1192 /* moves down the figure and returns true if gameover */
1193 static void move_down (void)
1197 if (!canMoveTo (rockblox_status
.cx
, rockblox_status
.cy
+ 1, rockblox_status
.co
)) {
1198 /* save figure to board */
1199 for (i
= 0; i
< 4; i
++) {
1200 rx
= getRelativeX (rockblox_status
.cf
, i
, rockblox_status
.co
) + rockblox_status
.cx
;
1201 ry
= getRelativeY (rockblox_status
.cf
, i
, rockblox_status
.co
) + rockblox_status
.cy
;
1202 rockblox_status
.board
[ry
][rx
] = rockblox_status
.cf
;
1204 /* check if formed some lines */
1207 /* the original scoring from "http://en.wikipedia.org/wiki/Rockblox" */
1208 rockblox_status
.score
+= scoring
[l
- 1] * rockblox_status
.level
;
1209 rockblox_status
.lines
+= l
;
1210 rockblox_status
.level
= (int) rockblox_status
.lines
/ 10 + 1;
1216 /* generate a new figure */
1219 move_block (0, 1, rockblox_status
.co
);
1222 static bool rockblox_help(void)
1224 static char *help_text
[] = {
1225 "Rockblox", "", "Aim", "",
1226 "Make", "the", "falling", "blocks", "of",
1227 "different", "shapes", "form", "full", "rows.",
1228 "Whenever", "a", "row", "is", "completed,",
1229 "it", "will", "be", "cleared", "away",
1230 "and", "you", "gain", "points."
1232 static struct style_text formation
[]={
1233 { 0, TEXT_CENTER
|TEXT_UNDERLINE
},
1238 #ifdef HAVE_LCD_BITMAP
1239 rb
->lcd_setfont(FONT_UI
);
1241 #ifdef HAVE_LCD_COLOR
1242 rb
->lcd_set_background(LCD_BLACK
);
1243 rb
->lcd_set_foreground(LCD_WHITE
);
1245 if (display_text(ARRAYLEN(help_text
), help_text
, formation
, NULL
, true))
1247 #ifdef HAVE_LCD_BITMAP
1248 rb
->lcd_setfont(FONT_SYSFIXED
);
1254 static int rockblox_menu_cb(int action
, const struct menu_item_ex
*this_item
)
1256 int i
= ((intptr_t)this_item
);
1257 if(action
== ACTION_REQUEST_MENUITEM
1258 && !resume
&& (i
==0 || i
==5))
1259 return ACTION_EXIT_MENUITEM
;
1263 static int rockblox_menu(void)
1267 MENUITEM_STRINGLIST(main_menu
, "Rockblox Menu", rockblox_menu_cb
,
1268 "Resume Game", "Start New Game",
1269 "Help", "High Scores", "Playback Control",
1270 "Quit without Saving", "Quit");
1272 rb
->button_clear_queue();
1274 switch (rb
->do_menu(&main_menu
, &selected
, NULL
, false)) {
1277 rb
->remove(RESUME_FILE
);
1278 init_rockblox(true);
1281 init_rockblox(false);
1284 if (rockblox_help())
1288 highscore_show(-1, highscores
, NUM_SCORES
, true);
1291 if (playback_control(NULL
))
1298 rb
->splash(HZ
*1, "Saving game ...");
1302 case MENU_ATTACHED_USB
:
1312 static int rockblox_loop (void)
1315 int lastbutton
= BUTTON_NONE
;
1316 long next_down_tick
= *rb
->current_tick
+ level_speed(rockblox_status
.level
);
1318 if (rockblox_menu()) {
1322 resume_file
= false;
1325 #ifdef HAS_BUTTON_HOLD
1326 if (rb
->button_hold ()) {
1327 /* Turn on backlight timeout (revert to settings) */
1328 backlight_use_settings(); /* backlight control in lib/helper.c */
1329 rb
->splash(0, "Paused");
1330 while (rb
->button_hold ())
1333 /* Turn off backlight timeout */
1334 backlight_force_on(); /* backlight control in lib/helper.c */
1336 /* get rid of the splash text */
1337 rb
->lcd_bitmap (rockblox_background
, 0, 0, LCD_WIDTH
, LCD_HEIGHT
);
1347 button
= rb
->button_get_w_tmo (MAX(next_down_tick
- *rb
->current_tick
, 1));
1349 #ifdef ROCKBLOX_RC_OFF
1350 case ROCKBLOX_RC_OFF
:
1353 #ifdef ROCKBLOX_OFF_PRE
1354 if (lastbutton
!= ROCKBLOX_OFF_PRE
)
1361 #if defined(ROCKBLOX_ROTATE)
1362 case ROCKBLOX_ROTATE
:
1364 case ROCKBLOX_ROTATE_CCW
:
1365 case ROCKBLOX_ROTATE_CCW
| BUTTON_REPEAT
:
1366 #ifdef HAVE_SCROLLWHEEL
1367 /* if the wheel is disabled, add an event to the stack. */
1368 if(wheel_enabled
== false)
1371 /* if it's enabled, go ahead and rotate.. */
1374 #ifdef ROCKBLOX_ROTATE_CCW2
1376 case ROCKBLOX_ROTATE_CCW2
:
1378 move_block (0, 0, (rockblox_status
.co
+ 1) % figures
[rockblox_status
.cf
].max_or
);
1381 case ROCKBLOX_ROTATE_CW
:
1382 case ROCKBLOX_ROTATE_CW
| BUTTON_REPEAT
:
1383 #ifdef HAVE_SCROLLWHEEL
1384 if(wheel_enabled
== false)
1389 #ifdef ROCKBLOX_ROTATE_CW2
1391 case ROCKBLOX_ROTATE_CW2
:
1394 (rockblox_status
.co
+ figures
[rockblox_status
.cf
].max_or
-
1395 1) % figures
[rockblox_status
.cf
].max_or
);
1399 case ROCKBLOX_DOWN
| BUTTON_REPEAT
:
1400 move_block (0, 1, rockblox_status
.co
);
1403 case ROCKBLOX_RIGHT
:
1404 case ROCKBLOX_RIGHT
| BUTTON_REPEAT
:
1405 move_block (1, 0, rockblox_status
.co
);
1409 case ROCKBLOX_LEFT
| BUTTON_REPEAT
:
1410 move_block (-1, 0, rockblox_status
.co
);
1414 #ifdef ROCKBLOX_DROP_PRE
1415 if (lastbutton
!= ROCKBLOX_DROP_PRE
)
1418 while (canMoveTo (rockblox_status
.cx
, rockblox_status
.cy
+ 1, rockblox_status
.co
))
1419 move_block (0, 1, rockblox_status
.co
);
1421 #ifdef ROCKBLOX_RESTART
1422 case ROCKBLOX_RESTART
:
1423 rb
->splash (HZ
* 1, "Restarting...");
1424 init_rockblox (false);
1429 if (rb
->default_event_handler (button
) == SYS_USB_CONNECTED
)
1430 return PLUGIN_USB_CONNECTED
;
1433 if (button
!= BUTTON_NONE
)
1434 lastbutton
= button
;
1436 #ifdef HAVE_SCROLLWHEEL
1437 /* check if we should enable the scroll wheel, if events
1438 * begin to stack up... */
1439 if(wheel_enabled
== false)
1441 /* stopped rotating the wheel, reset the count */
1442 if(wheel_events
== last_wheel_event
)
1444 last_wheel_event
= 0;
1447 /* rotated the wheel a while constantly, enable it. */
1448 else if(wheel_events
> 3)
1450 wheel_enabled
= true;
1453 /* this evens out the last event and the "current" event.
1454 * if we get an event next time through button reading, it will
1455 * remain ahead of last_event. if we don't, they'll end up equaling
1456 * each other.. thus, the scroll count will be reset. */
1457 if(wheel_enabled
== false && wheel_events
> last_wheel_event
)
1462 if (TIME_AFTER(*rb
->current_tick
, next_down_tick
)) {
1464 next_down_tick
+= level_speed(rockblox_status
.level
);
1465 if (TIME_AFTER(*rb
->current_tick
, next_down_tick
))
1466 /* restart time "raster" when we had to wait longer than usual
1467 * (pause, game restart etc) */
1468 next_down_tick
= *rb
->current_tick
+ level_speed(rockblox_status
.level
);
1471 if (rockblox_status
.gameover
) {
1473 rb
->lcd_set_foreground (LCD_BLACK
);
1486 enum plugin_status
plugin_start (const void *parameter
)
1491 rb
->srand (*rb
->current_tick
);
1493 /* Load HighScore if any */
1494 highscore_load(SCORE_FILE
, highscores
, NUM_SCORES
);
1497 rb
->lcd_set_backdrop(NULL
);
1500 #ifdef HAVE_LCD_BITMAP
1501 rb
->lcd_setfont (FONT_SYSFIXED
);
1503 if (!pgfx_init(4, 2))
1505 rb
->splash(HZ
*2, "Old LCD :(");
1509 /* Turn off backlight timeout */
1510 backlight_force_on(); /* backlight control in lib/helper.c */
1512 resume_file
= resume
;
1513 while(!rockblox_loop()) {
1515 int position
= highscore_update(rockblox_status
.score
,
1516 rockblox_status
.level
, "",
1517 highscores
, NUM_SCORES
);
1518 if (position
!= -1) {
1520 rb
->splash(HZ
*2, "New High Score");
1521 highscore_show(position
, highscores
, NUM_SCORES
, true);
1526 #ifndef HAVE_LCD_BITMAP
1529 /* Save user's HighScore */
1530 highscore_save(SCORE_FILE
, highscores
, NUM_SCORES
);
1531 backlight_use_settings(); /* backlight control in lib/helper.c */