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_HDD6330_PAD
292 #define ROCKBLOX_OFF BUTTON_POWER
293 #define ROCKBLOX_ROTATE_CCW BUTTON_PREV
294 #define ROCKBLOX_ROTATE_CW BUTTON_NEXT
295 #define ROCKBLOX_ROTATE BUTTON_UP
296 #define ROCKBLOX_DOWN BUTTON_DOWN
297 #define ROCKBLOX_LEFT BUTTON_LEFT
298 #define ROCKBLOX_RIGHT BUTTON_RIGHT
299 #define ROCKBLOX_DROP BUTTON_PLAY
300 #define ROCKBLOX_RESTART BUTTON_MENU
302 # elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
304 #define ROCKBLOX_OFF BUTTON_POWER
305 #define ROCKBLOX_ROTATE_CCW BUTTON_VOL_DOWN
306 #define ROCKBLOX_ROTATE_CW BUTTON_VOL_UP
307 #define ROCKBLOX_ROTATE BUTTON_UP
308 #define ROCKBLOX_DOWN BUTTON_DOWN
309 #define ROCKBLOX_LEFT BUTTON_PREV
310 #define ROCKBLOX_RIGHT BUTTON_NEXT
311 #define ROCKBLOX_DROP BUTTON_PLAY
312 #define ROCKBLOX_RESTART BUTTON_MENU
314 #elif CONFIG_KEYPAD == ONDAVX747_PAD
315 #define ROCKBLOX_OFF BUTTON_POWER
316 #define ROCKBLOX_RESTART BUTTON_MENU
317 #elif CONFIG_KEYPAD == ONDAVX777_PAD
318 #define ROCKBLOX_OFF BUTTON_POWER
320 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
322 #define ROCKBLOX_OFF (BUTTON_REC|BUTTON_PLAY)
323 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
324 #define ROCKBLOX_ROTATE_CW BUTTON_DOWN
325 #define ROCKBLOX_DOWN BUTTON_REW
326 #define ROCKBLOX_LEFT BUTTON_LEFT
327 #define ROCKBLOX_RIGHT BUTTON_RIGHT
328 #define ROCKBLOX_DROP BUTTON_FFWD
329 #define ROCKBLOX_RESTART (BUTTON_REC|BUTTON_REW)
331 #elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
333 #define ROCKBLOX_OFF BUTTON_REC
334 #define ROCKBLOX_ROTATE_CCW BUTTON_PLAY
335 #define ROCKBLOX_ROTATE_CW BUTTON_MENU
336 #define ROCKBLOX_DOWN BUTTON_DOWN
337 #define ROCKBLOX_LEFT BUTTON_PREV
338 #define ROCKBLOX_RIGHT BUTTON_NEXT
339 #define ROCKBLOX_DROP BUTTON_OK
340 #define ROCKBLOX_RESTART BUTTON_CANCEL
342 #elif CONFIG_KEYPAD == MPIO_HD200_PAD
343 #define ROCKBLOX_OFF (BUTTON_REC|BUTTON_PLAY)
344 #define ROCKBLOX_ROTATE_CCW BUTTON_REW
345 #define ROCKBLOX_ROTATE_CW BUTTON_FF
346 #define ROCKBLOX_DOWN BUTTON_FUNC
347 #define ROCKBLOX_LEFT BUTTON_VOL_DOWN
348 #define ROCKBLOX_RIGHT BUTTON_VOL_UP
349 #define ROCKBLOX_DROP BUTTON_PLAY
350 #define ROCKBLOX_RESTART BUTTON_REC
352 #elif CONFIG_KEYPAD == MPIO_HD300_PAD
353 #define ROCKBLOX_OFF (BUTTON_REC|BUTTON_REPEAT)
354 #define ROCKBLOX_ROTATE_CCW BUTTON_REW
355 #define ROCKBLOX_ROTATE_CW BUTTON_FF
356 #define ROCKBLOX_DOWN BUTTON_DOWN
357 #define ROCKBLOX_LEFT BUTTON_MENU
358 #define ROCKBLOX_RIGHT BUTTON_ENTER
359 #define ROCKBLOX_DROP BUTTON_PLAY
360 #define ROCKBLOX_RESTART BUTTON_REC
363 #error No keymap defined!
366 #ifdef HAVE_TOUCHSCREEN
368 #define ROCKBLOX_OFF BUTTON_TOPLEFT
370 #ifdef ROCKBLOX_ROTATE_CCW
371 #define ROCKBLOX_ROTATE_CCW2 BUTTON_BOTTOMLEFT
373 #define ROCKBLOX_ROTATE_CCW BUTTON_BOTTOMLEFT
375 #ifdef ROCKBLOX_ROTATE_CW
376 #define ROCKBLOX_ROTATE_CW2 BUTTON_BOTTOMRIGHT
378 #define ROCKBLOX_ROTATE_CW BUTTON_BOTTOMRIGHT
379 #define ROCKBLOX_ROTATE_CW2 BUTTON_TOPMIDDLE
381 #ifndef ROCKBLOX_DOWN
382 #define ROCKBLOX_DOWN BUTTON_BOTTOMMIDDLE
384 #ifndef ROCKBLOX_LEFT
385 #define ROCKBLOX_LEFT BUTTON_MIDLEFT
387 #ifndef ROCKBLOX_RIGHT
388 #define ROCKBLOX_RIGHT BUTTON_MIDRIGHT
390 #ifndef ROCKBLOX_DROP
391 #define ROCKBLOX_DROP BUTTON_CENTER
393 #ifndef ROCKBLOX_RESTART
394 #define ROCKBLOX_RESTART BUTTON_TOPRIGHT
399 #define EMPTY_BLOCK 7
401 #define BOARD_WIDTH 10
403 #ifdef HAVE_LCD_BITMAP
405 #define BOARD_HEIGHT 20
407 #if (LCD_WIDTH == 640) && (LCD_HEIGHT == 480)
409 #define BLOCK_WIDTH 24
410 #define BLOCK_HEIGHT 24
420 #elif (LCD_WIDTH == 480) && (LCD_HEIGHT == 640)
422 #define BLOCK_WIDTH 30
423 #define BLOCK_HEIGHT 30
426 #define PREVIEW_X 342
427 #define PREVIEW_Y 482
433 #elif (LCD_WIDTH == 320) && (LCD_HEIGHT == 240)
435 #define BLOCK_WIDTH 12
436 #define BLOCK_HEIGHT 12
446 #elif (LCD_WIDTH == 240) && ((LCD_HEIGHT == 320) || (LCD_HEIGHT == 400))
448 #define BLOCK_WIDTH 15
449 #define BLOCK_HEIGHT 15
452 #define PREVIEW_X 171
453 #define PREVIEW_Y 241
458 #define HIGH_LABEL_X 172
459 #define HIGH_SCORE_Y 163
460 #define HIGH_LEVEL_Y 172
462 #elif (LCD_WIDTH == 220) && (LCD_HEIGHT == 176)
464 #define BLOCK_WIDTH 8
465 #define BLOCK_HEIGHT 8
468 #define PREVIEW_X 158
469 #define PREVIEW_Y 130
475 #elif (LCD_WIDTH == 176) && (LCD_HEIGHT == 132)
477 #define BLOCK_WIDTH 6
478 #define BLOCK_HEIGHT 6
481 #define PREVIEW_X 126
482 #define PREVIEW_Y 102
488 #elif (LCD_WIDTH == 176) && (LCD_HEIGHT == 220)
490 /* no room for the space in the highscore list */
493 #define BLOCK_WIDTH 10
494 #define BLOCK_HEIGHT 10
497 #define PREVIEW_X 124
498 #define PREVIEW_Y 174
503 #define HIGH_SCORE_Y 119
504 #define HIGH_LEVEL_Y 126
505 #define HIGH_LABEL_X 114
507 #elif (LCD_WIDTH == 160) && (LCD_HEIGHT == 128)
510 #define BLOCK_WIDTH 6
511 #define BLOCK_HEIGHT 6
514 #define PREVIEW_X 114
515 #define PREVIEW_Y 100
521 #elif (LCD_WIDTH == 138) && (LCD_HEIGHT == 110)
523 #define BLOCK_WIDTH 5
524 #define BLOCK_HEIGHT 5
534 #elif (LCD_WIDTH == 132) && (LCD_HEIGHT == 80)
536 #define BLOCK_WIDTH 4
537 #define BLOCK_HEIGHT 4
547 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 128)
549 #define BLOCK_WIDTH 6
550 #define BLOCK_HEIGHT 6
554 #define PREVIEW_Y 100
560 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 160)
562 #define BLOCK_WIDTH 7
563 #define BLOCK_HEIGHT 7
567 #define PREVIEW_Y 111
569 #define SCORE_Y (2+16)
570 #define LEVEL_Y (36+16)
571 #define LINES_Y (70+16)
573 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 96)
575 #define BLOCK_WIDTH 4
576 #define BLOCK_HEIGHT 4
586 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 64)
588 #define BLOCK_WIDTH 3
589 #define BLOCK_HEIGHT 3
599 #elif (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
601 #define BLOCK_WIDTH 4
602 #define BLOCK_HEIGHT 3
616 #define LEVEL_X LABEL_X
620 #define LINES_X LABEL_X
623 extern const fb_data rockblox_background
[];
625 #else /* HAVE_LCD_CHARCELLS */
627 #define BOARD_HEIGHT 14
629 #define BLOCK_WIDTH 1
630 #define BLOCK_HEIGHT 1
641 /* <<Explanation on Rockblox shapes>>
644 %% - O has 1 orientation
647 %% %% - Z has 2 orientations
651 %% %% - S has 2 orientations
655 % %%%% - I has 2 orientations
659 % % % %%% - L has 4 orientations
663 % % % %%% - J has 4 orientations
667 %% % %% % - T has 4 orientations
671 /* c=current f=figure o=orientation n=next */
672 static struct _rockblox_status
683 short board
[BOARD_HEIGHT
][BOARD_WIDTH
]; /* 20 rows of 10 blocks */
687 static void draw_next_block(void);
688 static void new_block(void);
690 #ifdef HAVE_SCROLLWHEEL
691 int wheel_events
= 0, last_wheel_event
= 0;
692 bool wheel_enabled
= false;
695 static const short scoring
[4] = { /* scoring for each number of lines */
696 #if BOARD_HEIGHT == 20
697 40 /* single */ , 100 /* double */ , 300 /* triple */ , 1200 /* rockblox */
698 #elif BOARD_HEIGHT == 14 /* Player special values */
699 60 /* single */ , 150 /* double */ , 500 /* triple */ , 2000 /* rockblox */
706 unsigned short color
[3]; /* color of figure (light,middle,shadow) */
708 unsigned short max_or
; /* max orientations */
709 signed short shapeX
[4], shapeY
[4]; /* implementation of figures */
712 /* array of figures */
713 figures
[BLOCKS_NUM
] = {
717 {LCD_RGBPACK (153, 255, 255), LCD_RGBPACK(0, 255, 255),
718 LCD_RGBPACK(0,153,153)},
720 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
729 {LCD_RGBPACK (255, 153, 128), LCD_RGBPACK (255, 0, 0),
730 LCD_RGBPACK (153, 0, 0)},
732 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
741 {LCD_RGBPACK (153, 255, 153), LCD_RGBPACK (0, 255, 0),
742 LCD_RGBPACK (0, 153, 0)},
744 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
753 {LCD_RGBPACK (153, 153, 255), LCD_RGBPACK (0, 0, 255),
754 LCD_RGBPACK (0, 0, 153)},
756 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
765 {LCD_RGBPACK (255, 255, 153), LCD_RGBPACK (255, 255, 0),
766 LCD_RGBPACK (153, 153, 0)},
768 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
777 {LCD_RGBPACK (255, 153, 255), LCD_RGBPACK (255, 0, 255),
778 LCD_RGBPACK (153, 0, 153)},
780 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
789 {LCD_RGBPACK (204, 204, 204), LCD_RGBPACK (153, 153, 153),
790 LCD_RGBPACK (85, 85, 85)},
792 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
800 bool resume_file
= false;
802 /* Rockbox File System only supports full filenames inc dir */
803 #define SCORE_FILE PLUGIN_GAMES_DIR "/rockblox.score"
804 #define RESUME_FILE PLUGIN_GAMES_DIR "/rockblox.resume"
807 /* Default High Scores... */
808 struct highscore highscores
[NUM_SCORES
];
810 /* get random number from (0) to (range-1) */
811 static int t_rand (int range
)
813 return rb
->rand () % range
;
816 static inline void show_game_over (void)
818 rb
->splash(HZ
,"Game over!");
821 /* init the board array to have no blocks */
822 static void init_board (void)
825 for (i
= 0; i
< BOARD_WIDTH
; i
++)
826 for (j
= 0; j
< BOARD_HEIGHT
; j
++)
827 rockblox_status
.board
[j
][i
] = EMPTY_BLOCK
;
830 /* show the score, level and lines */
831 static void show_details (void)
833 #ifdef HAVE_LCD_BITMAP
835 rb
->lcd_set_foreground (LCD_BLACK
);
836 rb
->lcd_set_background (LCD_WHITE
);
838 rb
->lcd_putsxyf (LABEL_X
, SCORE_Y
, "%d", rockblox_status
.score
);
839 rb
->lcd_putsxyf (LEVEL_X
, LEVEL_Y
, "%d", rockblox_status
.level
);
840 rb
->lcd_putsxyf (LINES_X
, LINES_Y
, "%d", rockblox_status
.lines
);
841 #else /* HAVE_LCD_CHARCELLS */
842 rb
->lcd_putsf (5, 0, "L%d/%d", rockblox_status
.level
,
843 rockblox_status
.lines
);
844 rb
->lcd_putsf (5, 1, "S%d", rockblox_status
.score
);
849 static void show_highscores (void)
853 for (i
= 0; i
<NUM_SCORES
; i
++)
854 rb
->lcd_putsxyf (HIGH_LABEL_X
, HIGH_SCORE_Y
+ (10 * i
),
855 "%06d" _SPACE
"L%1d", highscores
[i
].score
, highscores
[i
].level
);
859 static void load_game(void)
865 fd
= rb
->open(RESUME_FILE
, O_RDONLY
);
868 if (rb
->read(fd
, &rockblox_status
, sizeof(struct _rockblox_status
))
869 < (ssize_t
)sizeof(struct _rockblox_status
))
871 rb
->splash(HZ
/2, "Loading Rockblox resume info failed");
882 static void dump_resume(void)
886 fd
= rb
->open(RESUME_FILE
, O_WRONLY
|O_CREAT
, 0666);
890 if (rb
->write(fd
, &rockblox_status
, sizeof(struct _rockblox_status
))
900 rb
->splash(HZ
/2, "Writing Rockblox resume info failed");
904 static void init_rockblox (bool resume
)
910 rb
->snprintf(score_name
, sizeof(score_name
), "%04d%02d%02d %02d%02d%02d",
911 tm
->tm_year
+ 1900, tm
->tm_mon
+ 1, tm
->tm_mday
,
912 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
914 #ifdef HAVE_LCD_BITMAP
915 rb
->lcd_bitmap (rockblox_background
, 0, 0, LCD_WIDTH
, LCD_HEIGHT
);
916 #else /* HAVE_LCD_CHARCELLS */
918 pgfx_display_block (3, 0, 3, 1);
919 pgfx_display_block (4, 0, 3, 0);
920 rb
->lcd_puts(4, 1, " ");
921 pgfx_clear_display();
922 pgfx_fillrect (3, 0, 2, 14);
923 pgfx_fillrect (15, 7, 2, 7);
928 rockblox_status
.level
= 1;
929 rockblox_status
.lines
= 0;
930 rockblox_status
.score
= 0;
931 rockblox_status
.nf
= t_rand(BLOCKS_NUM
);
943 static inline int level_speed(int level
)
945 #if BOARD_HEIGHT == 20
946 return (5*HZ
) / (level
+ 9);
947 #elif BOARD_HEIGHT == 14
948 return (7*HZ
) / (level
+ 9);
952 static int getRelativeX (int figure
, int square
, int orientation
)
954 switch (orientation
) {
956 return figures
[figure
].shapeX
[square
];
958 return figures
[figure
].shapeY
[square
];
960 return -figures
[figure
].shapeX
[square
];
962 return -figures
[figure
].shapeY
[square
];
968 static int getRelativeY (int figure
, int square
, int orientation
)
970 switch (orientation
) {
972 return figures
[figure
].shapeY
[square
];
974 return -figures
[figure
].shapeX
[square
];
976 return -figures
[figure
].shapeY
[square
];
978 return figures
[figure
].shapeX
[square
];
984 /* redraw the while board on the screen */
985 static void refresh_board (void)
987 int i
, j
, x
, y
, block
;
990 rb
->lcd_set_foreground (LCD_BLACK
);
992 mylcd_set_drawmode (DRMODE_SOLID
| DRMODE_INVERSEVID
);
995 mylcd_fillrect (BOARD_X
, BOARD_Y
, BOARD_WIDTH
* BLOCK_WIDTH
,
996 BOARD_HEIGHT
* BLOCK_HEIGHT
);
999 mylcd_set_drawmode (DRMODE_SOLID
);
1002 for (i
= 0; i
< BOARD_WIDTH
; i
++)
1003 for (j
= 0; j
< BOARD_HEIGHT
; j
++) {
1004 block
= rockblox_status
.board
[j
][i
];
1005 if (block
!= EMPTY_BLOCK
) {
1006 #ifdef HAVE_LCD_BITMAP
1008 /* middle drawing */
1009 rb
->lcd_set_foreground (figures
[block
].color
[1]);
1011 rb
->lcd_fillrect (BOARD_X
+ i
* BLOCK_WIDTH
,
1012 BOARD_Y
+ j
* BLOCK_HEIGHT
,
1013 BLOCK_WIDTH
, BLOCK_HEIGHT
);
1016 rb
->lcd_set_foreground (figures
[block
].color
[0]);
1018 rb
->lcd_vline (BOARD_X
+ i
* BLOCK_WIDTH
,
1019 BOARD_Y
+ j
* BLOCK_HEIGHT
,
1020 BOARD_Y
+ (j
+ 1) * BLOCK_HEIGHT
- 2);
1021 rb
->lcd_hline (BOARD_X
+ i
* BLOCK_WIDTH
,
1022 BOARD_X
+ (i
+ 1) * BLOCK_WIDTH
- 2,
1023 BOARD_Y
+ j
* BLOCK_HEIGHT
);
1025 /* shadow drawing */
1026 rb
->lcd_set_foreground (figures
[block
].color
[2]);
1028 rb
->lcd_vline (BOARD_X
+ (i
+ 1) * BLOCK_WIDTH
- 1,
1029 BOARD_Y
+ j
* BLOCK_HEIGHT
+ 1,
1030 BOARD_Y
+ (j
+ 1) * BLOCK_HEIGHT
- 1);
1031 rb
->lcd_hline (BOARD_X
+ i
* BLOCK_WIDTH
+ 1,
1032 BOARD_X
+ (i
+ 1) * BLOCK_WIDTH
- 1,
1033 BOARD_Y
+ (j
+ 1) * BLOCK_HEIGHT
- 1);
1034 #else /* HAVE_LCD_CHARCELLS */
1035 pgfx_drawpixel (BOARD_X
+ i
, BOARD_Y
+ j
);
1040 for (i
= 0; i
< 4; i
++) {
1041 x
= getRelativeX (rockblox_status
.cf
, i
, rockblox_status
.co
)
1042 + rockblox_status
.cx
;
1043 y
= getRelativeY (rockblox_status
.cf
, i
, rockblox_status
.co
)
1044 + rockblox_status
.cy
;
1045 #ifdef HAVE_LCD_BITMAP
1047 /* middle drawing */
1048 rb
->lcd_set_foreground (figures
[rockblox_status
.cf
].color
[1]);
1050 rb
->lcd_fillrect (BOARD_X
+ x
* BLOCK_WIDTH
,
1051 BOARD_Y
+ y
* BLOCK_HEIGHT
,
1052 BLOCK_WIDTH
, BLOCK_HEIGHT
);
1055 rb
->lcd_set_foreground (figures
[rockblox_status
.cf
].color
[0]);
1057 rb
->lcd_vline (BOARD_X
+ x
* BLOCK_WIDTH
, BOARD_Y
+ y
* BLOCK_HEIGHT
,
1058 BOARD_Y
+ (y
+ 1) * BLOCK_HEIGHT
- 2);
1059 rb
->lcd_hline (BOARD_X
+ x
* BLOCK_WIDTH
,
1060 BOARD_X
+ (x
+ 1) * BLOCK_WIDTH
- 2,
1061 BOARD_Y
+ y
* BLOCK_HEIGHT
);
1063 /* shadow drawing */
1064 rb
->lcd_set_foreground (figures
[rockblox_status
.cf
].color
[2]);
1066 rb
->lcd_vline (BOARD_X
+ (x
+ 1) * BLOCK_WIDTH
- 1,
1067 BOARD_Y
+ y
* BLOCK_HEIGHT
+ 1,
1068 BOARD_Y
+ (y
+ 1) * BLOCK_HEIGHT
- 1);
1069 rb
->lcd_hline (BOARD_X
+ x
* BLOCK_WIDTH
+ 1,
1070 BOARD_X
+ (x
+ 1) * BLOCK_WIDTH
- 1,
1071 BOARD_Y
+ (y
+ 1) * BLOCK_HEIGHT
- 1);
1072 #else /* HAVE_LCD_CHARCELLS */
1073 pgfx_drawpixel (BOARD_X
+ x
, BOARD_Y
+ y
);
1079 static bool canMoveTo (int x
, int y
, int newOrientation
)
1082 for (i
= 0; i
< 4; i
++) {
1083 ry
= getRelativeY (rockblox_status
.cf
, i
, newOrientation
) + y
;
1084 rx
= getRelativeX (rockblox_status
.cf
, i
, newOrientation
) + x
;
1085 if ((rx
< 0 || rx
>= BOARD_WIDTH
) ||
1086 (ry
< 0 || ry
>= BOARD_HEIGHT
) ||
1087 (rockblox_status
.board
[ry
][rx
] != EMPTY_BLOCK
))
1093 /* draws the preview of next block in the preview window */
1094 static void draw_next_block (void)
1097 /* clear preview window first */
1099 rb
->lcd_set_foreground (LCD_BLACK
);
1100 #elif LCD_DEPTH == 1
1101 mylcd_set_drawmode (DRMODE_SOLID
| DRMODE_INVERSEVID
);
1105 mylcd_fillrect (PREVIEW_X
, PREVIEW_Y
, BLOCK_WIDTH
* 4, BLOCK_HEIGHT
* 4);
1108 mylcd_set_drawmode (DRMODE_SOLID
);
1111 /* draw the lightgray rectangles */
1113 rb
->lcd_set_foreground (LCD_RGBPACK (40, 40, 40));
1114 #elif LCD_DEPTH == 2
1115 rb
->lcd_set_foreground (LCD_DARKGRAY
);
1119 for (rx
= 0; rx
< 4; rx
++)
1120 for (ry
= 0; ry
< 4; ry
++)
1121 rb
->lcd_drawrect (PREVIEW_X
+ rx
* BLOCK_WIDTH
,
1122 PREVIEW_Y
+ ry
* BLOCK_HEIGHT
, BLOCK_WIDTH
,
1126 /* draw the figure */
1127 for (i
= 0; i
< 4; i
++) {
1128 rx
= getRelativeX (rockblox_status
.nf
, i
, 0) + 2;
1129 ry
= getRelativeY (rockblox_status
.nf
, i
, 0) + 2;
1130 #ifdef HAVE_LCD_BITMAP
1132 rb
->lcd_set_foreground (figures
[rockblox_status
.nf
].color
[1]); /* middle drawing */
1134 rb
->lcd_fillrect (PREVIEW_X
+ rx
* BLOCK_WIDTH
,
1135 PREVIEW_Y
+ ry
* BLOCK_HEIGHT
,
1136 BLOCK_WIDTH
, BLOCK_HEIGHT
);
1138 rb
->lcd_set_foreground (figures
[rockblox_status
.nf
].color
[0]); /* light drawing */
1140 rb
->lcd_vline (PREVIEW_X
+ rx
* BLOCK_WIDTH
,
1141 PREVIEW_Y
+ ry
* BLOCK_HEIGHT
,
1142 PREVIEW_Y
+ (ry
+ 1) * BLOCK_HEIGHT
- 2);
1143 rb
->lcd_hline (PREVIEW_X
+ rx
* BLOCK_WIDTH
,
1144 PREVIEW_X
+ (rx
+ 1) * BLOCK_WIDTH
- 2,
1145 PREVIEW_Y
+ ry
* BLOCK_HEIGHT
);
1147 rb
->lcd_set_foreground (figures
[rockblox_status
.nf
].color
[2]); /* shadow drawing */
1149 rb
->lcd_vline (PREVIEW_X
+ (rx
+ 1) * BLOCK_WIDTH
- 1,
1150 PREVIEW_Y
+ ry
* BLOCK_HEIGHT
+ 1,
1151 PREVIEW_Y
+ (ry
+ 1) * BLOCK_HEIGHT
- 1);
1152 rb
->lcd_hline (PREVIEW_X
+ rx
* BLOCK_WIDTH
+ 1,
1153 PREVIEW_X
+ (rx
+ 1) * BLOCK_WIDTH
- 1,
1154 PREVIEW_Y
+ (ry
+ 1) * BLOCK_HEIGHT
- 1);
1155 #else /* HAVE_LCD_CHARCELLS */
1156 pgfx_drawpixel (PREVIEW_X
+ rx
, PREVIEW_Y
+ ry
);
1162 /* move the block to a relative location */
1163 static void move_block (int x
, int y
, int o
)
1165 if (canMoveTo (rockblox_status
.cx
+ x
, rockblox_status
.cy
+ y
, o
)) {
1166 rockblox_status
.cy
+= y
;
1167 rockblox_status
.cx
+= x
;
1168 rockblox_status
.co
= o
;
1172 /* try to add a new block to play with (return true if gameover) */
1173 static void new_block (void)
1175 rockblox_status
.cy
= 1;
1176 rockblox_status
.cx
= 5;
1177 rockblox_status
.cf
= rockblox_status
.nf
;
1178 rockblox_status
.co
= 0; /* start at the same orientation all time */
1179 rockblox_status
.nf
= t_rand (BLOCKS_NUM
);
1180 rockblox_status
.gameover
= !canMoveTo (rockblox_status
.cx
,
1181 rockblox_status
.cy
, rockblox_status
.co
);
1187 /* check for filled rockblox_status.lines and do what necessary */
1188 static int check_lines (void)
1194 for (j
= 0; j
< BOARD_HEIGHT
; j
++) {
1195 for (i
= 0; ((i
< BOARD_WIDTH
) &&
1196 (rockblox_status
.board
[j
][i
] != EMPTY_BLOCK
)); i
++);
1197 if (i
== BOARD_WIDTH
) { /* woo hoo, we have a line */
1199 for (y
= j
; y
> 0; y
--)
1201 for (i
= 0; i
< BOARD_WIDTH
; i
++)
1203 rockblox_status
.board
[y
][i
] = rockblox_status
.board
[y
- 1][i
];
1212 /* moves down the figure and returns true if gameover */
1213 static void move_down (void)
1217 if (!canMoveTo (rockblox_status
.cx
, rockblox_status
.cy
+ 1, rockblox_status
.co
)) {
1218 /* save figure to board */
1219 for (i
= 0; i
< 4; i
++) {
1220 rx
= getRelativeX (rockblox_status
.cf
, i
, rockblox_status
.co
) + rockblox_status
.cx
;
1221 ry
= getRelativeY (rockblox_status
.cf
, i
, rockblox_status
.co
) + rockblox_status
.cy
;
1222 rockblox_status
.board
[ry
][rx
] = rockblox_status
.cf
;
1224 /* check if formed some lines */
1227 /* the original scoring from "http://en.wikipedia.org/wiki/Rockblox" */
1228 rockblox_status
.score
+= scoring
[l
- 1] * rockblox_status
.level
;
1229 rockblox_status
.lines
+= l
;
1230 rockblox_status
.level
= (int) rockblox_status
.lines
/ 10 + 1;
1236 /* generate a new figure */
1239 move_block (0, 1, rockblox_status
.co
);
1242 static bool rockblox_help(void)
1244 static char *help_text
[] = {
1245 "Rockblox", "", "Aim", "",
1246 "Make", "the", "falling", "blocks", "of",
1247 "different", "shapes", "form", "full", "rows.",
1248 "Whenever", "a", "row", "is", "completed,",
1249 "it", "will", "be", "cleared", "away",
1250 "and", "you", "gain", "points."
1252 static struct style_text formation
[]={
1253 { 0, TEXT_CENTER
|TEXT_UNDERLINE
},
1258 #ifdef HAVE_LCD_BITMAP
1259 rb
->lcd_setfont(FONT_UI
);
1261 #ifdef HAVE_LCD_COLOR
1262 rb
->lcd_set_background(LCD_BLACK
);
1263 rb
->lcd_set_foreground(LCD_WHITE
);
1265 if (display_text(ARRAYLEN(help_text
), help_text
, formation
, NULL
, true))
1267 #ifdef HAVE_LCD_BITMAP
1268 rb
->lcd_setfont(FONT_SYSFIXED
);
1274 static int rockblox_menu_cb(int action
, const struct menu_item_ex
*this_item
)
1276 int i
= ((intptr_t)this_item
);
1277 if(action
== ACTION_REQUEST_MENUITEM
1278 && !resume
&& (i
==0 || i
==5))
1279 return ACTION_EXIT_MENUITEM
;
1283 static int rockblox_menu(void)
1287 MENUITEM_STRINGLIST(main_menu
, "Rockblox Menu", rockblox_menu_cb
,
1288 "Resume Game", "Start New Game",
1289 "Help", "High Scores", "Playback Control",
1290 "Quit without Saving", "Quit");
1292 rb
->button_clear_queue();
1294 switch (rb
->do_menu(&main_menu
, &selected
, NULL
, false)) {
1297 rb
->remove(RESUME_FILE
);
1298 init_rockblox(true);
1301 init_rockblox(false);
1304 if (rockblox_help())
1308 highscore_show(-1, highscores
, NUM_SCORES
, true);
1311 if (playback_control(NULL
))
1318 rb
->splash(HZ
*1, "Saving game ...");
1322 case MENU_ATTACHED_USB
:
1332 static int rockblox_loop (void)
1335 int lastbutton
= BUTTON_NONE
;
1336 long next_down_tick
= *rb
->current_tick
+ level_speed(rockblox_status
.level
);
1338 if (rockblox_menu()) {
1342 resume_file
= false;
1345 #ifdef HAS_BUTTON_HOLD
1346 if (rb
->button_hold ()) {
1347 /* Turn on backlight timeout (revert to settings) */
1348 backlight_use_settings();
1349 rb
->splash(0, "Paused");
1350 while (rb
->button_hold ())
1353 /* Turn off backlight timeout */
1354 backlight_ignore_timeout();
1356 /* get rid of the splash text */
1357 rb
->lcd_bitmap (rockblox_background
, 0, 0, LCD_WIDTH
, LCD_HEIGHT
);
1367 button
= rb
->button_get_w_tmo (MAX(next_down_tick
- *rb
->current_tick
, 1));
1369 #ifdef ROCKBLOX_RC_OFF
1370 case ROCKBLOX_RC_OFF
:
1373 #ifdef ROCKBLOX_OFF_PRE
1374 if (lastbutton
!= ROCKBLOX_OFF_PRE
)
1381 #if defined(ROCKBLOX_ROTATE)
1382 case ROCKBLOX_ROTATE
:
1384 case ROCKBLOX_ROTATE_CCW
:
1385 case ROCKBLOX_ROTATE_CCW
| BUTTON_REPEAT
:
1386 #ifdef HAVE_SCROLLWHEEL
1387 /* if the wheel is disabled, add an event to the stack. */
1388 if(wheel_enabled
== false)
1391 /* if it's enabled, go ahead and rotate.. */
1394 #ifdef ROCKBLOX_ROTATE_CCW2
1396 case ROCKBLOX_ROTATE_CCW2
:
1398 move_block (0, 0, (rockblox_status
.co
+ 1) % figures
[rockblox_status
.cf
].max_or
);
1401 case ROCKBLOX_ROTATE_CW
:
1402 case ROCKBLOX_ROTATE_CW
| BUTTON_REPEAT
:
1403 #ifdef HAVE_SCROLLWHEEL
1404 if(wheel_enabled
== false)
1409 #ifdef ROCKBLOX_ROTATE_CW2
1411 case ROCKBLOX_ROTATE_CW2
:
1414 (rockblox_status
.co
+ figures
[rockblox_status
.cf
].max_or
-
1415 1) % figures
[rockblox_status
.cf
].max_or
);
1419 case ROCKBLOX_DOWN
| BUTTON_REPEAT
:
1420 move_block (0, 1, rockblox_status
.co
);
1423 case ROCKBLOX_RIGHT
:
1424 case ROCKBLOX_RIGHT
| BUTTON_REPEAT
:
1425 move_block (1, 0, rockblox_status
.co
);
1429 case ROCKBLOX_LEFT
| BUTTON_REPEAT
:
1430 move_block (-1, 0, rockblox_status
.co
);
1434 #ifdef ROCKBLOX_DROP_PRE
1435 if (lastbutton
!= ROCKBLOX_DROP_PRE
)
1438 while (canMoveTo (rockblox_status
.cx
, rockblox_status
.cy
+ 1, rockblox_status
.co
))
1439 move_block (0, 1, rockblox_status
.co
);
1441 #ifdef ROCKBLOX_RESTART
1442 case ROCKBLOX_RESTART
:
1443 rb
->splash (HZ
* 1, "Restarting...");
1444 init_rockblox (false);
1449 if (rb
->default_event_handler (button
) == SYS_USB_CONNECTED
)
1450 return PLUGIN_USB_CONNECTED
;
1453 if (button
!= BUTTON_NONE
)
1454 lastbutton
= button
;
1456 #ifdef HAVE_SCROLLWHEEL
1457 /* check if we should enable the scroll wheel, if events
1458 * begin to stack up... */
1459 if(wheel_enabled
== false)
1461 /* stopped rotating the wheel, reset the count */
1462 if(wheel_events
== last_wheel_event
)
1464 last_wheel_event
= 0;
1467 /* rotated the wheel a while constantly, enable it. */
1468 else if(wheel_events
> 3)
1470 wheel_enabled
= true;
1473 /* this evens out the last event and the "current" event.
1474 * if we get an event next time through button reading, it will
1475 * remain ahead of last_event. if we don't, they'll end up equaling
1476 * each other.. thus, the scroll count will be reset. */
1477 if(wheel_enabled
== false && wheel_events
> last_wheel_event
)
1482 if (TIME_AFTER(*rb
->current_tick
, next_down_tick
)) {
1484 next_down_tick
+= level_speed(rockblox_status
.level
);
1485 if (TIME_AFTER(*rb
->current_tick
, next_down_tick
))
1486 /* restart time "raster" when we had to wait longer than usual
1487 * (pause, game restart etc) */
1488 next_down_tick
= *rb
->current_tick
+ level_speed(rockblox_status
.level
);
1491 if (rockblox_status
.gameover
) {
1493 rb
->lcd_set_foreground (LCD_BLACK
);
1506 enum plugin_status
plugin_start (const void *parameter
)
1511 rb
->srand (*rb
->current_tick
);
1513 /* Load HighScore if any */
1514 highscore_load(SCORE_FILE
, highscores
, NUM_SCORES
);
1517 rb
->lcd_set_backdrop(NULL
);
1520 #ifdef HAVE_LCD_BITMAP
1521 rb
->lcd_setfont (FONT_SYSFIXED
);
1523 if (!pgfx_init(4, 2))
1525 rb
->splash(HZ
*2, "Old LCD :(");
1529 /* Turn off backlight timeout */
1530 backlight_ignore_timeout();
1532 resume_file
= resume
;
1533 while(!rockblox_loop()) {
1535 int position
= highscore_update(rockblox_status
.score
,
1536 rockblox_status
.level
, "",
1537 highscores
, NUM_SCORES
);
1538 if (position
!= -1) {
1540 rb
->splash(HZ
*2, "New High Score");
1541 highscore_show(position
, highscores
, NUM_SCORES
, true);
1546 #ifndef HAVE_LCD_BITMAP
1549 /* Save user's HighScore */
1550 highscore_save(SCORE_FILE
, highscores
, NUM_SCORES
);
1551 backlight_use_settings();