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"
32 #if (CONFIG_KEYPAD == IPOD_4G_PAD) || \
33 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
34 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
36 #define ROCKBLOX_OFF (BUTTON_MENU | BUTTON_SELECT)
37 #define ROCKBLOX_ROTATE_RIGHT BUTTON_SCROLL_BACK
38 #define ROCKBLOX_ROTATE_RIGHT2 (BUTTON_MENU | BUTTON_REL)
39 #define ROCKBLOX_ROTATE_LEFT BUTTON_SCROLL_FWD
40 #define ROCKBLOX_LEFT BUTTON_LEFT
41 #define ROCKBLOX_RIGHT BUTTON_RIGHT
42 #define ROCKBLOX_DOWN BUTTON_PLAY
43 #define ROCKBLOX_RESTART (BUTTON_SELECT | BUTTON_PLAY)
44 #define ROCKBLOX_DROP (BUTTON_SELECT | BUTTON_REL)
46 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
47 (CONFIG_KEYPAD == IRIVER_H300_PAD)
49 #define ROCKBLOX_OFF BUTTON_OFF
50 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
51 #define ROCKBLOX_ROTATE_LEFT BUTTON_SELECT
52 #define ROCKBLOX_DOWN BUTTON_DOWN
53 #define ROCKBLOX_LEFT BUTTON_LEFT
54 #define ROCKBLOX_RIGHT BUTTON_RIGHT
55 #define ROCKBLOX_DROP BUTTON_MODE
56 #define ROCKBLOX_RESTART BUTTON_ON
58 #define ROCKBLOX_RC_OFF BUTTON_RC_STOP
60 #elif CONFIG_KEYPAD == RECORDER_PAD
62 #define ROCKBLOX_OFF BUTTON_OFF
63 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
64 #define ROCKBLOX_ROTATE_LEFT BUTTON_PLAY
65 #define ROCKBLOX_DOWN BUTTON_DOWN
66 #define ROCKBLOX_LEFT BUTTON_LEFT
67 #define ROCKBLOX_RIGHT BUTTON_RIGHT
68 #define ROCKBLOX_DROP BUTTON_ON
69 #define ROCKBLOX_RESTART BUTTON_F1
71 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
73 #define ROCKBLOX_OFF BUTTON_OFF
74 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
75 #define ROCKBLOX_ROTATE_LEFT BUTTON_SELECT
76 #define ROCKBLOX_DOWN BUTTON_DOWN
77 #define ROCKBLOX_LEFT BUTTON_LEFT
78 #define ROCKBLOX_RIGHT BUTTON_RIGHT
79 #define ROCKBLOX_DROP BUTTON_ON
80 #define ROCKBLOX_RESTART BUTTON_F1
82 #elif CONFIG_KEYPAD == PLAYER_PAD
84 #define ROCKBLOX_OFF_PRE BUTTON_STOP
85 #define ROCKBLOX_OFF (BUTTON_STOP|BUTTON_REL)
86 #define ROCKBLOX_ROTATE_RIGHT BUTTON_PLAY
87 #define ROCKBLOX_ROTATE_LEFT (BUTTON_ON|BUTTON_PLAY)
88 #define ROCKBLOX_DOWN BUTTON_MENU
89 #define ROCKBLOX_LEFT BUTTON_LEFT
90 #define ROCKBLOX_RIGHT BUTTON_RIGHT
91 #define ROCKBLOX_DROP_PRE BUTTON_ON
92 #define ROCKBLOX_DROP (BUTTON_ON|BUTTON_REL)
93 #define ROCKBLOX_RESTART (BUTTON_STOP|BUTTON_MENU)
95 #elif CONFIG_KEYPAD == ONDIO_PAD
97 #define ROCKBLOX_OFF_PRE BUTTON_OFF
98 #define ROCKBLOX_OFF (BUTTON_OFF|BUTTON_REL)
99 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
100 #define ROCKBLOX_ROTATE_LEFT (BUTTON_MENU|BUTTON_UP)
101 #define ROCKBLOX_DOWN BUTTON_DOWN
102 #define ROCKBLOX_LEFT BUTTON_LEFT
103 #define ROCKBLOX_RIGHT BUTTON_RIGHT
104 #define ROCKBLOX_DROP_PRE BUTTON_MENU
105 #define ROCKBLOX_DROP (BUTTON_MENU|BUTTON_REL)
106 #define ROCKBLOX_RESTART (BUTTON_OFF|BUTTON_MENU)
108 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
110 #define ROCKBLOX_OFF BUTTON_POWER
111 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
112 #define ROCKBLOX_ROTATE_LEFT BUTTON_SELECT
113 #define ROCKBLOX_DOWN BUTTON_DOWN
114 #define ROCKBLOX_LEFT BUTTON_LEFT
115 #define ROCKBLOX_RIGHT BUTTON_RIGHT
116 #define ROCKBLOX_DROP BUTTON_REC
117 #define ROCKBLOX_RESTART BUTTON_PLAY
119 #elif CONFIG_KEYPAD == SANSA_E200_PAD
121 #define ROCKBLOX_OFF BUTTON_POWER
122 #define ROCKBLOX_ROTATE_RIGHT BUTTON_SCROLL_BACK
123 #define ROCKBLOX_ROTATE_RIGHT2 BUTTON_UP
124 #define ROCKBLOX_ROTATE_LEFT BUTTON_SCROLL_FWD
125 #define ROCKBLOX_DOWN BUTTON_DOWN
126 #define ROCKBLOX_LEFT BUTTON_LEFT
127 #define ROCKBLOX_RIGHT BUTTON_RIGHT
128 #define ROCKBLOX_DROP BUTTON_SELECT
129 #define ROCKBLOX_RESTART BUTTON_REC
131 #elif CONFIG_KEYPAD == SANSA_FUZE_PAD
133 #define ROCKBLOX_OFF (BUTTON_HOME|BUTTON_REPEAT)
134 #define ROCKBLOX_ROTATE_RIGHT BUTTON_SCROLL_BACK
135 #define ROCKBLOX_ROTATE_RIGHT2 BUTTON_UP
136 #define ROCKBLOX_ROTATE_LEFT BUTTON_SCROLL_FWD
137 #define ROCKBLOX_DOWN BUTTON_DOWN
138 #define ROCKBLOX_LEFT BUTTON_LEFT
139 #define ROCKBLOX_RIGHT BUTTON_RIGHT
140 #define ROCKBLOX_DROP (BUTTON_SELECT | BUTTON_REL)
141 #define ROCKBLOX_RESTART (BUTTON_SELECT | BUTTON_UP)
144 #elif CONFIG_KEYPAD == SANSA_C200_PAD
146 #define ROCKBLOX_OFF BUTTON_POWER
147 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
148 #define ROCKBLOX_ROTATE_RIGHT2 BUTTON_VOL_DOWN
149 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOL_UP
150 #define ROCKBLOX_DOWN BUTTON_DOWN
151 #define ROCKBLOX_LEFT BUTTON_LEFT
152 #define ROCKBLOX_RIGHT BUTTON_RIGHT
153 #define ROCKBLOX_DROP BUTTON_SELECT
154 #define ROCKBLOX_RESTART BUTTON_REC
156 #elif CONFIG_KEYPAD == SANSA_CLIP_PAD
158 #define ROCKBLOX_OFF BUTTON_POWER
159 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
160 #define ROCKBLOX_ROTATE_RIGHT2 BUTTON_VOL_DOWN
161 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOL_UP
162 #define ROCKBLOX_DOWN BUTTON_DOWN
163 #define ROCKBLOX_LEFT BUTTON_LEFT
164 #define ROCKBLOX_RIGHT BUTTON_RIGHT
165 #define ROCKBLOX_DROP BUTTON_SELECT
166 #define ROCKBLOX_RESTART BUTTON_HOME
168 #elif CONFIG_KEYPAD == SANSA_M200_PAD
170 #define ROCKBLOX_OFF BUTTON_POWER
171 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
172 #define ROCKBLOX_ROTATE_RIGHT2 BUTTON_VOL_DOWN
173 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOL_UP
174 #define ROCKBLOX_DOWN BUTTON_DOWN
175 #define ROCKBLOX_LEFT BUTTON_LEFT
176 #define ROCKBLOX_RIGHT BUTTON_RIGHT
177 #define ROCKBLOX_RESTART (BUTTON_SELECT | BUTTON_UP)
178 #define ROCKBLOX_DROP (BUTTON_SELECT | BUTTON_REL)
180 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
182 #define ROCKBLOX_OFF BUTTON_POWER
183 #define ROCKBLOX_ROTATE_RIGHT BUTTON_SCROLL_UP
184 #define ROCKBLOX_ROTATE_LEFT BUTTON_REW
185 #define ROCKBLOX_DOWN BUTTON_SCROLL_DOWN
186 #define ROCKBLOX_LEFT BUTTON_LEFT
187 #define ROCKBLOX_RIGHT BUTTON_RIGHT
188 #define ROCKBLOX_DROP BUTTON_FF
189 #define ROCKBLOX_RESTART BUTTON_PLAY
191 #elif CONFIG_KEYPAD == GIGABEAT_PAD
193 #define ROCKBLOX_OFF BUTTON_POWER
194 #define ROCKBLOX_ROTATE_RIGHT BUTTON_VOL_DOWN
195 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOL_UP
196 #define ROCKBLOX_ROTATE BUTTON_UP
197 #define ROCKBLOX_DOWN BUTTON_DOWN
198 #define ROCKBLOX_LEFT BUTTON_LEFT
199 #define ROCKBLOX_RIGHT BUTTON_RIGHT
200 #define ROCKBLOX_DROP BUTTON_SELECT
201 #define ROCKBLOX_RESTART BUTTON_A
203 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
205 #define ROCKBLOX_OFF BUTTON_PLAY
206 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
207 #define ROCKBLOX_ROTATE_LEFT BUTTON_SELECT
208 #define ROCKBLOX_DOWN BUTTON_DOWN
209 #define ROCKBLOX_LEFT BUTTON_LEFT
210 #define ROCKBLOX_RIGHT BUTTON_RIGHT
211 #define ROCKBLOX_DROP BUTTON_MODE
212 #define ROCKBLOX_RESTART BUTTON_EQ
214 #elif CONFIG_KEYPAD == MROBE500_PAD
215 #define ROCKBLOX_OFF BUTTON_POWER
217 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
218 #define ROCKBLOX_OFF BUTTON_BACK
219 #define ROCKBLOX_ROTATE_RIGHT BUTTON_VOL_DOWN
220 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOL_UP
221 #define ROCKBLOX_ROTATE BUTTON_UP
222 #define ROCKBLOX_DOWN BUTTON_DOWN
223 #define ROCKBLOX_LEFT BUTTON_LEFT
224 #define ROCKBLOX_RIGHT BUTTON_RIGHT
225 #define ROCKBLOX_DROP BUTTON_SELECT
226 #define ROCKBLOX_RESTART BUTTON_PLAY
228 #elif CONFIG_KEYPAD == MROBE100_PAD
230 #define ROCKBLOX_OFF BUTTON_POWER
231 #define ROCKBLOX_ROTATE_RIGHT BUTTON_MENU
232 #define ROCKBLOX_ROTATE_LEFT BUTTON_PLAY
233 #define ROCKBLOX_ROTATE BUTTON_UP
234 #define ROCKBLOX_DOWN BUTTON_DOWN
235 #define ROCKBLOX_LEFT BUTTON_LEFT
236 #define ROCKBLOX_RIGHT BUTTON_RIGHT
237 #define ROCKBLOX_DROP BUTTON_SELECT
238 #define ROCKBLOX_RESTART BUTTON_DISPLAY
240 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
242 #define ROCKBLOX_OFF BUTTON_RC_REC
243 #define ROCKBLOX_ROTATE_RIGHT BUTTON_RC_VOL_DOWN
244 #define ROCKBLOX_ROTATE_LEFT BUTTON_RC_VOL_UP
245 #define ROCKBLOX_DOWN BUTTON_RC_MENU
246 #define ROCKBLOX_LEFT BUTTON_RC_REW
247 #define ROCKBLOX_RIGHT BUTTON_RC_FF
248 #define ROCKBLOX_DROP BUTTON_RC_PLAY
249 #define ROCKBLOX_RESTART BUTTON_RC_MODE
251 #elif CONFIG_KEYPAD == COWON_D2_PAD
252 #define ROCKBLOX_OFF BUTTON_POWER
253 #define ROCKBLOX_RESTART BUTTON_MENU
255 #elif CONFIG_KEYPAD == IAUDIO67_PAD
257 #define ROCKBLOX_OFF BUTTON_POWER
258 #define ROCKBLOX_ROTATE_RIGHT BUTTON_VOLDOWN
259 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOLUP
260 #define ROCKBLOX_DOWN BUTTON_STOP
261 #define ROCKBLOX_LEFT BUTTON_LEFT
262 #define ROCKBLOX_RIGHT BUTTON_RIGHT
263 #define ROCKBLOX_DROP BUTTON_PLAY
264 #define ROCKBLOX_RESTART BUTTON_MENU
266 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
267 #define ROCKBLOX_OFF BUTTON_BACK
268 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
269 #define ROCKBLOX_ROTATE_LEFT BUTTON_PLAY
270 #define ROCKBLOX_DOWN BUTTON_DOWN
271 #define ROCKBLOX_LEFT BUTTON_LEFT
272 #define ROCKBLOX_RIGHT BUTTON_RIGHT
273 #define ROCKBLOX_DROP BUTTON_SELECT
274 #define ROCKBLOX_RESTART BUTTON_CUSTOM
276 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
278 #define ROCKBLOX_OFF BUTTON_POWER
279 #define ROCKBLOX_ROTATE_RIGHT BUTTON_VOL_DOWN
280 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOL_UP
281 #define ROCKBLOX_ROTATE BUTTON_UP
282 #define ROCKBLOX_DOWN BUTTON_DOWN
283 #define ROCKBLOX_LEFT BUTTON_LEFT
284 #define ROCKBLOX_RIGHT BUTTON_RIGHT
285 #define ROCKBLOX_DROP BUTTON_SELECT
286 #define ROCKBLOX_RESTART BUTTON_MENU
288 # elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
290 #define ROCKBLOX_OFF BUTTON_POWER
291 #define ROCKBLOX_ROTATE_RIGHT BUTTON_VOL_DOWN
292 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOL_UP
293 #define ROCKBLOX_ROTATE BUTTON_UP
294 #define ROCKBLOX_DOWN BUTTON_DOWN
295 #define ROCKBLOX_LEFT BUTTON_PREV
296 #define ROCKBLOX_RIGHT BUTTON_NEXT
297 #define ROCKBLOX_DROP BUTTON_PLAY
298 #define ROCKBLOX_RESTART BUTTON_MENU
300 #elif CONFIG_KEYPAD == ONDAVX747_PAD
301 #define ROCKBLOX_OFF BUTTON_POWER
302 #define ROCKBLOX_RESTART BUTTON_MENU
303 #elif CONFIG_KEYPAD == ONDAVX777_PAD
304 #define ROCKBLOX_OFF BUTTON_POWER
306 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
308 #define ROCKBLOX_OFF (BUTTON_REC|BUTTON_PLAY)
309 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
310 #define ROCKBLOX_ROTATE_LEFT BUTTON_DOWN
311 #define ROCKBLOX_DOWN BUTTON_REW
312 #define ROCKBLOX_LEFT BUTTON_LEFT
313 #define ROCKBLOX_RIGHT BUTTON_RIGHT
314 #define ROCKBLOX_DROP BUTTON_FFWD
315 #define ROCKBLOX_RESTART (BUTTON_REC|BUTTON_REW)
317 #elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
319 #define ROCKBLOX_OFF BUTTON_REC
320 #define ROCKBLOX_ROTATE_RIGHT BUTTON_PLAY
321 #define ROCKBLOX_ROTATE_LEFT BUTTON_MENU
322 #define ROCKBLOX_DOWN BUTTON_DOWN
323 #define ROCKBLOX_LEFT BUTTON_PREV
324 #define ROCKBLOX_RIGHT BUTTON_NEXT
325 #define ROCKBLOX_DROP BUTTON_OK
326 #define ROCKBLOX_RESTART BUTTON_CANCEL
329 #error No keymap defined!
332 #ifdef HAVE_TOUCHSCREEN
334 #define ROCKBLOX_OFF BUTTON_TOPLEFT
336 #ifndef ROCKBLOX_ROTATE_RIGHT
337 #define ROCKBLOX_ROTATE_RIGHT BUTTON_BOTTOMRIGHT
339 #ifndef ROCKBLOX_ROTATE_LEFT
340 #define ROCKBLOX_ROTATE_LEFT BUTTON_BOTTOMLEFT
342 #ifndef ROCKBLOX_DOWN
343 #define ROCKBLOX_DOWN BUTTON_BOTTOMMIDDLE
345 #ifndef ROCKBLOX_LEFT
346 #define ROCKBLOX_LEFT BUTTON_MIDLEFT
348 #ifndef ROCKBLOX_RIGHT
349 #define ROCKBLOX_RIGHT BUTTON_MIDRIGHT
351 #ifndef ROCKBLOX_DROP
352 #define ROCKBLOX_DROP BUTTON_CENTER
354 #ifndef ROCKBLOX_RESTART
355 #define ROCKBLOX_RESTART BUTTON_TOPRIGHT
360 #define EMPTY_BLOCK 7
362 #define BOARD_WIDTH 10
364 #ifdef HAVE_LCD_BITMAP
366 #define BOARD_HEIGHT 20
368 #if (LCD_WIDTH == 640) && (LCD_HEIGHT == 480)
370 #define BLOCK_WIDTH 24
371 #define BLOCK_HEIGHT 24
381 #elif (LCD_WIDTH == 480) && (LCD_HEIGHT == 640)
383 #define BLOCK_WIDTH 30
384 #define BLOCK_HEIGHT 30
387 #define PREVIEW_X 342
388 #define PREVIEW_Y 482
394 #elif (LCD_WIDTH == 320) && (LCD_HEIGHT == 240)
396 #define BLOCK_WIDTH 12
397 #define BLOCK_HEIGHT 12
407 #elif (LCD_WIDTH == 240) && ((LCD_HEIGHT == 320) || (LCD_HEIGHT == 400))
409 #define BLOCK_WIDTH 15
410 #define BLOCK_HEIGHT 15
413 #define PREVIEW_X 171
414 #define PREVIEW_Y 241
419 #define HIGH_LABEL_X 172
420 #define HIGH_SCORE_Y 163
421 #define HIGH_LEVEL_Y 172
423 #elif (LCD_WIDTH == 220) && (LCD_HEIGHT == 176)
425 #define BLOCK_WIDTH 8
426 #define BLOCK_HEIGHT 8
429 #define PREVIEW_X 158
430 #define PREVIEW_Y 130
436 #elif (LCD_WIDTH == 176) && (LCD_HEIGHT == 132)
438 #define BLOCK_WIDTH 6
439 #define BLOCK_HEIGHT 6
442 #define PREVIEW_X 126
443 #define PREVIEW_Y 102
449 #elif (LCD_WIDTH == 176) && (LCD_HEIGHT == 220)
451 /* no room for the space in the highscore list */
454 #define BLOCK_WIDTH 10
455 #define BLOCK_HEIGHT 10
458 #define PREVIEW_X 124
459 #define PREVIEW_Y 174
464 #define HIGH_SCORE_Y 119
465 #define HIGH_LEVEL_Y 126
466 #define HIGH_LABEL_X 114
468 #elif (LCD_WIDTH == 160) && (LCD_HEIGHT == 128)
471 #define BLOCK_WIDTH 6
472 #define BLOCK_HEIGHT 6
475 #define PREVIEW_X 114
476 #define PREVIEW_Y 100
482 #elif (LCD_WIDTH == 138) && (LCD_HEIGHT == 110)
484 #define BLOCK_WIDTH 5
485 #define BLOCK_HEIGHT 5
495 #elif (LCD_WIDTH == 132) && (LCD_HEIGHT == 80)
497 #define BLOCK_WIDTH 4
498 #define BLOCK_HEIGHT 4
508 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 128)
510 #define BLOCK_WIDTH 6
511 #define BLOCK_HEIGHT 6
515 #define PREVIEW_Y 100
521 /* NOTE: This is for the GoGear SA9200 and is only
522 temporary until I can get better coordinates! */
523 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 160)
525 #define BLOCK_WIDTH 6
526 #define BLOCK_HEIGHT 6
530 #define PREVIEW_Y 100
536 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 96)
538 #define BLOCK_WIDTH 4
539 #define BLOCK_HEIGHT 4
549 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 64)
551 #define BLOCK_WIDTH 3
552 #define BLOCK_HEIGHT 3
562 #elif (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
564 #define BLOCK_WIDTH 4
565 #define BLOCK_HEIGHT 3
579 #define LEVEL_X LABEL_X
583 #define LINES_X LABEL_X
586 #define MYLCD(fn) rb->lcd_ ## fn
588 extern const fb_data rockblox_background
[];
590 #else /* HAVE_LCD_CHARCELLS */
592 #define BOARD_HEIGHT 14
594 #define BLOCK_WIDTH 1
595 #define BLOCK_HEIGHT 1
601 #define MYLCD(fn) pgfx_ ## fn
608 /* <<Explanation on Rockblox shapes>>
611 %% - O has 1 orientation
614 %% %% - Z has 2 orientations
618 %% %% - S has 2 orientations
622 % %%%% - I has 2 orientations
626 % % % %%% - L has 4 orientations
630 % % % %%% - J has 4 orientations
634 %% % %% % - T has 4 orientations
638 /* c=current f=figure o=orientation n=next */
639 static struct _rockblox_status
650 short board
[BOARD_HEIGHT
][BOARD_WIDTH
]; /* 20 rows of 10 blocks */
654 static void draw_next_block(void);
655 static void new_block(void);
657 #ifdef HAVE_SCROLLWHEEL
658 int wheel_events
= 0, last_wheel_event
= 0;
659 bool wheel_enabled
= false;
662 static const short scoring
[4] = { /* scoring for each number of lines */
663 #if BOARD_HEIGHT == 20
664 40 /* single */ , 100 /* double */ , 300 /* triple */ , 1200 /* rockblox */
665 #elif BOARD_HEIGHT == 14 /* Player special values */
666 60 /* single */ , 150 /* double */ , 500 /* triple */ , 2000 /* rockblox */
673 unsigned short color
[3]; /* color of figure (light,middle,shadow) */
675 unsigned short max_or
; /* max orientations */
676 signed short shapeX
[4], shapeY
[4]; /* implementation of figures */
679 /* array of figures */
680 figures
[BLOCKS_NUM
] = {
684 {LCD_RGBPACK (153, 255, 255), LCD_RGBPACK(0, 255, 255),
685 LCD_RGBPACK(0,153,153)},
687 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
696 {LCD_RGBPACK (255, 153, 128), LCD_RGBPACK (255, 0, 0),
697 LCD_RGBPACK (153, 0, 0)},
699 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
708 {LCD_RGBPACK (153, 255, 153), LCD_RGBPACK (0, 255, 0),
709 LCD_RGBPACK (0, 153, 0)},
711 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
720 {LCD_RGBPACK (153, 153, 255), LCD_RGBPACK (0, 0, 255),
721 LCD_RGBPACK (0, 0, 153)},
723 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
732 {LCD_RGBPACK (255, 255, 153), LCD_RGBPACK (255, 255, 0),
733 LCD_RGBPACK (153, 153, 0)},
735 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
744 {LCD_RGBPACK (255, 153, 255), LCD_RGBPACK (255, 0, 255),
745 LCD_RGBPACK (153, 0, 153)},
747 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
756 {LCD_RGBPACK (204, 204, 204), LCD_RGBPACK (153, 153, 153),
757 LCD_RGBPACK (85, 85, 85)},
759 {LCD_WHITE
, LCD_LIGHTGRAY
, LCD_DARKGRAY
},
767 bool resume_file
= false;
769 /* Rockbox File System only supports full filenames inc dir */
770 #define HIGH_SCORE PLUGIN_GAMES_DIR "/rockblox.score"
771 #define RESUME_FILE PLUGIN_GAMES_DIR "/rockblox.resume"
772 #define MAX_HIGH_SCORES 5
774 /* Default High Scores... */
775 struct highscore highest
[MAX_HIGH_SCORES
];
777 /* get random number from (0) to (range-1) */
778 static int t_rand (int range
)
780 return rb
->rand () % range
;
783 static inline void show_game_over (void)
785 rb
->splash(HZ
,"Game over!");
788 /* init the board array to have no blocks */
789 static void init_board (void)
792 for (i
= 0; i
< BOARD_WIDTH
; i
++)
793 for (j
= 0; j
< BOARD_HEIGHT
; j
++)
794 rockblox_status
.board
[j
][i
] = EMPTY_BLOCK
;
797 /* show the score, level and lines */
798 static void show_details (void)
800 char str
[25]; /* for strings */
802 #ifdef HAVE_LCD_BITMAP
804 rb
->lcd_set_foreground (LCD_BLACK
);
805 rb
->lcd_set_background (LCD_WHITE
);
807 rb
->snprintf (str
, sizeof (str
), "%d", rockblox_status
.score
);
808 rb
->lcd_putsxy (LABEL_X
, SCORE_Y
, str
);
809 rb
->snprintf (str
, sizeof (str
), "%d", rockblox_status
.level
);
810 rb
->lcd_putsxy (LEVEL_X
, LEVEL_Y
, str
);
811 rb
->snprintf (str
, sizeof (str
), "%d", rockblox_status
.lines
);
812 rb
->lcd_putsxy (LINES_X
, LINES_Y
, str
);
813 #else /* HAVE_LCD_CHARCELLS */
814 rb
->snprintf (str
, sizeof (str
), "L%d/%d", rockblox_status
.level
,
815 rockblox_status
.lines
);
816 rb
->lcd_puts (5, 0, str
);
817 rb
->snprintf (str
, sizeof (str
), "S%d", rockblox_status
.score
);
818 rb
->lcd_puts (5, 1, str
);
823 static void show_highscores (void)
826 char str
[25]; /* for strings */
828 for (i
= 0; i
<MAX_HIGH_SCORES
; i
++)
830 rb
->snprintf (str
, sizeof (str
), "%06d" _SPACE
"L%1d",
831 highest
[i
].score
, highest
[i
].level
);
832 rb
->lcd_putsxy (HIGH_LABEL_X
, HIGH_SCORE_Y
+ (10 * i
), str
);
837 static void load_game(void)
843 fd
= rb
->open(RESUME_FILE
, O_RDONLY
);
846 if (rb
->read(fd
, &rockblox_status
, sizeof(struct _rockblox_status
))
847 < (ssize_t
)sizeof(struct _rockblox_status
))
849 rb
->splash(HZ
/2, "Loading Rockblox resume info failed");
860 static void dump_resume(void)
864 fd
= rb
->open(RESUME_FILE
, O_WRONLY
|O_CREAT
);
868 if (rb
->write(fd
, &rockblox_status
, sizeof(struct _rockblox_status
))
878 rb
->splash(HZ
/2, "Writing Rockblox resume info failed");
882 static void init_rockblox (bool resume
)
888 rb
->snprintf(score_name
, sizeof(score_name
), "%04d%02d%02d %02d%02d%02d",
889 tm
->tm_year
+ 1900, tm
->tm_mon
+ 1, tm
->tm_mday
,
890 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
892 #ifdef HAVE_LCD_BITMAP
893 rb
->lcd_bitmap (rockblox_background
, 0, 0, LCD_WIDTH
, LCD_HEIGHT
);
894 #else /* HAVE_LCD_CHARCELLS */
896 pgfx_display_block (3, 0, 3, 1);
897 pgfx_display_block (4, 0, 3, 0);
898 pgfx_clear_display();
899 pgfx_fillrect (3, 0, 2, 14);
900 pgfx_fillrect (15, 7, 2, 7);
905 rockblox_status
.level
= 1;
906 rockblox_status
.lines
= 0;
907 rockblox_status
.score
= 0;
908 rockblox_status
.nf
= t_rand(BLOCKS_NUM
);
920 static inline int level_speed(int level
)
922 #if BOARD_HEIGHT == 20
923 return (5*HZ
) / (level
+ 9);
924 #elif BOARD_HEIGHT == 14
925 return (7*HZ
) / (level
+ 9);
929 static int getRelativeX (int figure
, int square
, int orientation
)
931 switch (orientation
) {
933 return figures
[figure
].shapeX
[square
];
935 return figures
[figure
].shapeY
[square
];
937 return -figures
[figure
].shapeX
[square
];
939 return -figures
[figure
].shapeY
[square
];
945 static int getRelativeY (int figure
, int square
, int orientation
)
947 switch (orientation
) {
949 return figures
[figure
].shapeY
[square
];
951 return -figures
[figure
].shapeX
[square
];
953 return -figures
[figure
].shapeY
[square
];
955 return figures
[figure
].shapeX
[square
];
961 /* redraw the while board on the screen */
962 static void refresh_board (void)
964 int i
, j
, x
, y
, block
;
967 rb
->lcd_set_foreground (LCD_BLACK
);
969 MYLCD(set_drawmode
) (DRMODE_SOLID
| DRMODE_INVERSEVID
);
972 MYLCD(fillrect
) (BOARD_X
, BOARD_Y
, BOARD_WIDTH
* BLOCK_WIDTH
,
973 BOARD_HEIGHT
* BLOCK_HEIGHT
);
976 MYLCD(set_drawmode
) (DRMODE_SOLID
);
979 for (i
= 0; i
< BOARD_WIDTH
; i
++)
980 for (j
= 0; j
< BOARD_HEIGHT
; j
++) {
981 block
= rockblox_status
.board
[j
][i
];
982 if (block
!= EMPTY_BLOCK
) {
983 #ifdef HAVE_LCD_BITMAP
986 rb
->lcd_set_foreground (figures
[block
].color
[1]);
988 rb
->lcd_fillrect (BOARD_X
+ i
* BLOCK_WIDTH
,
989 BOARD_Y
+ j
* BLOCK_HEIGHT
,
990 BLOCK_WIDTH
, BLOCK_HEIGHT
);
993 rb
->lcd_set_foreground (figures
[block
].color
[0]);
995 rb
->lcd_vline (BOARD_X
+ i
* BLOCK_WIDTH
,
996 BOARD_Y
+ j
* BLOCK_HEIGHT
,
997 BOARD_Y
+ (j
+ 1) * BLOCK_HEIGHT
- 2);
998 rb
->lcd_hline (BOARD_X
+ i
* BLOCK_WIDTH
,
999 BOARD_X
+ (i
+ 1) * BLOCK_WIDTH
- 2,
1000 BOARD_Y
+ j
* BLOCK_HEIGHT
);
1002 /* shadow drawing */
1003 rb
->lcd_set_foreground (figures
[block
].color
[2]);
1005 rb
->lcd_vline (BOARD_X
+ (i
+ 1) * BLOCK_WIDTH
- 1,
1006 BOARD_Y
+ j
* BLOCK_HEIGHT
+ 1,
1007 BOARD_Y
+ (j
+ 1) * BLOCK_HEIGHT
- 1);
1008 rb
->lcd_hline (BOARD_X
+ i
* BLOCK_WIDTH
+ 1,
1009 BOARD_X
+ (i
+ 1) * BLOCK_WIDTH
- 1,
1010 BOARD_Y
+ (j
+ 1) * BLOCK_HEIGHT
- 1);
1011 #else /* HAVE_LCD_CHARCELLS */
1012 pgfx_drawpixel (BOARD_X
+ i
, BOARD_Y
+ j
);
1017 for (i
= 0; i
< 4; i
++) {
1018 x
= getRelativeX (rockblox_status
.cf
, i
, rockblox_status
.co
)
1019 + rockblox_status
.cx
;
1020 y
= getRelativeY (rockblox_status
.cf
, i
, rockblox_status
.co
)
1021 + rockblox_status
.cy
;
1022 #ifdef HAVE_LCD_BITMAP
1024 /* middle drawing */
1025 rb
->lcd_set_foreground (figures
[rockblox_status
.cf
].color
[1]);
1027 rb
->lcd_fillrect (BOARD_X
+ x
* BLOCK_WIDTH
,
1028 BOARD_Y
+ y
* BLOCK_HEIGHT
,
1029 BLOCK_WIDTH
, BLOCK_HEIGHT
);
1032 rb
->lcd_set_foreground (figures
[rockblox_status
.cf
].color
[0]);
1034 rb
->lcd_vline (BOARD_X
+ x
* BLOCK_WIDTH
, BOARD_Y
+ y
* BLOCK_HEIGHT
,
1035 BOARD_Y
+ (y
+ 1) * BLOCK_HEIGHT
- 2);
1036 rb
->lcd_hline (BOARD_X
+ x
* BLOCK_WIDTH
,
1037 BOARD_X
+ (x
+ 1) * BLOCK_WIDTH
- 2,
1038 BOARD_Y
+ y
* BLOCK_HEIGHT
);
1040 /* shadow drawing */
1041 rb
->lcd_set_foreground (figures
[rockblox_status
.cf
].color
[2]);
1043 rb
->lcd_vline (BOARD_X
+ (x
+ 1) * BLOCK_WIDTH
- 1,
1044 BOARD_Y
+ y
* BLOCK_HEIGHT
+ 1,
1045 BOARD_Y
+ (y
+ 1) * BLOCK_HEIGHT
- 1);
1046 rb
->lcd_hline (BOARD_X
+ x
* BLOCK_WIDTH
+ 1,
1047 BOARD_X
+ (x
+ 1) * BLOCK_WIDTH
- 1,
1048 BOARD_Y
+ (y
+ 1) * BLOCK_HEIGHT
- 1);
1049 #else /* HAVE_LCD_CHARCELLS */
1050 pgfx_drawpixel (BOARD_X
+ x
, BOARD_Y
+ y
);
1056 static bool canMoveTo (int x
, int y
, int newOrientation
)
1059 for (i
= 0; i
< 4; i
++) {
1060 ry
= getRelativeY (rockblox_status
.cf
, i
, newOrientation
) + y
;
1061 rx
= getRelativeX (rockblox_status
.cf
, i
, newOrientation
) + x
;
1062 if ((rx
< 0 || rx
>= BOARD_WIDTH
) ||
1063 (ry
< 0 || ry
>= BOARD_HEIGHT
) ||
1064 (rockblox_status
.board
[ry
][rx
] != EMPTY_BLOCK
))
1070 /* draws the preview of next block in the preview window */
1071 static void draw_next_block (void)
1074 /* clear preview window first */
1076 rb
->lcd_set_foreground (LCD_BLACK
);
1077 #elif LCD_DEPTH == 1
1078 MYLCD(set_drawmode
) (DRMODE_SOLID
| DRMODE_INVERSEVID
);
1082 MYLCD(fillrect
) (PREVIEW_X
, PREVIEW_Y
, BLOCK_WIDTH
* 4, BLOCK_HEIGHT
* 4);
1085 MYLCD(set_drawmode
) (DRMODE_SOLID
);
1088 /* draw the lightgray rectangles */
1090 rb
->lcd_set_foreground (LCD_RGBPACK (40, 40, 40));
1091 #elif LCD_DEPTH == 2
1092 rb
->lcd_set_foreground (LCD_DARKGRAY
);
1096 for (rx
= 0; rx
< 4; rx
++)
1097 for (ry
= 0; ry
< 4; ry
++)
1098 rb
->lcd_drawrect (PREVIEW_X
+ rx
* BLOCK_WIDTH
,
1099 PREVIEW_Y
+ ry
* BLOCK_HEIGHT
, BLOCK_WIDTH
,
1103 /* draw the figure */
1104 for (i
= 0; i
< 4; i
++) {
1105 rx
= getRelativeX (rockblox_status
.nf
, i
, 0) + 2;
1106 ry
= getRelativeY (rockblox_status
.nf
, i
, 0) + 2;
1107 #ifdef HAVE_LCD_BITMAP
1109 rb
->lcd_set_foreground (figures
[rockblox_status
.nf
].color
[1]); /* middle drawing */
1111 rb
->lcd_fillrect (PREVIEW_X
+ rx
* BLOCK_WIDTH
,
1112 PREVIEW_Y
+ ry
* BLOCK_HEIGHT
,
1113 BLOCK_WIDTH
, BLOCK_HEIGHT
);
1115 rb
->lcd_set_foreground (figures
[rockblox_status
.nf
].color
[0]); /* light drawing */
1117 rb
->lcd_vline (PREVIEW_X
+ rx
* BLOCK_WIDTH
,
1118 PREVIEW_Y
+ ry
* BLOCK_HEIGHT
,
1119 PREVIEW_Y
+ (ry
+ 1) * BLOCK_HEIGHT
- 2);
1120 rb
->lcd_hline (PREVIEW_X
+ rx
* BLOCK_WIDTH
,
1121 PREVIEW_X
+ (rx
+ 1) * BLOCK_WIDTH
- 2,
1122 PREVIEW_Y
+ ry
* BLOCK_HEIGHT
);
1124 rb
->lcd_set_foreground (figures
[rockblox_status
.nf
].color
[2]); /* shadow drawing */
1126 rb
->lcd_vline (PREVIEW_X
+ (rx
+ 1) * BLOCK_WIDTH
- 1,
1127 PREVIEW_Y
+ ry
* BLOCK_HEIGHT
+ 1,
1128 PREVIEW_Y
+ (ry
+ 1) * BLOCK_HEIGHT
- 1);
1129 rb
->lcd_hline (PREVIEW_X
+ rx
* BLOCK_WIDTH
+ 1,
1130 PREVIEW_X
+ (rx
+ 1) * BLOCK_WIDTH
- 1,
1131 PREVIEW_Y
+ (ry
+ 1) * BLOCK_HEIGHT
- 1);
1132 #else /* HAVE_LCD_CHARCELLS */
1133 pgfx_drawpixel (PREVIEW_X
+ rx
, PREVIEW_Y
+ ry
);
1139 /* move the block to a relative location */
1140 static void move_block (int x
, int y
, int o
)
1142 if (canMoveTo (rockblox_status
.cx
+ x
, rockblox_status
.cy
+ y
, o
)) {
1143 rockblox_status
.cy
+= y
;
1144 rockblox_status
.cx
+= x
;
1145 rockblox_status
.co
= o
;
1149 /* try to add a new block to play with (return true if gameover) */
1150 static void new_block (void)
1152 rockblox_status
.cy
= 1;
1153 rockblox_status
.cx
= 5;
1154 rockblox_status
.cf
= rockblox_status
.nf
;
1155 rockblox_status
.co
= 0; /* start at the same orientation all time */
1156 rockblox_status
.nf
= t_rand (BLOCKS_NUM
);
1157 rockblox_status
.gameover
= !canMoveTo (rockblox_status
.cx
,
1158 rockblox_status
.cy
, rockblox_status
.co
);
1164 /* check for filled rockblox_status.lines and do what necessary */
1165 static int check_lines (void)
1171 for (j
= 0; j
< BOARD_HEIGHT
; j
++) {
1172 for (i
= 0; ((i
< BOARD_WIDTH
) &&
1173 (rockblox_status
.board
[j
][i
] != EMPTY_BLOCK
)); i
++);
1174 if (i
== BOARD_WIDTH
) { /* woo hoo, we have a line */
1176 for (y
= j
; y
> 0; y
--)
1178 for (i
= 0; i
< BOARD_WIDTH
; i
++)
1180 rockblox_status
.board
[y
][i
] = rockblox_status
.board
[y
- 1][i
];
1189 /* moves down the figure and returns true if gameover */
1190 static void move_down (void)
1194 if (!canMoveTo (rockblox_status
.cx
, rockblox_status
.cy
+ 1, rockblox_status
.co
)) {
1195 /* save figure to board */
1196 for (i
= 0; i
< 4; i
++) {
1197 rx
= getRelativeX (rockblox_status
.cf
, i
, rockblox_status
.co
) + rockblox_status
.cx
;
1198 ry
= getRelativeY (rockblox_status
.cf
, i
, rockblox_status
.co
) + rockblox_status
.cy
;
1199 rockblox_status
.board
[ry
][rx
] = rockblox_status
.cf
;
1201 /* check if formed some lines */
1204 /* the original scoring from "http://en.wikipedia.org/wiki/Rockblox" */
1205 rockblox_status
.score
+= scoring
[l
- 1] * rockblox_status
.level
;
1206 rockblox_status
.lines
+= l
;
1207 rockblox_status
.level
= (int) rockblox_status
.lines
/ 10 + 1;
1213 /* generate a new figure */
1216 move_block (0, 1, rockblox_status
.co
);
1219 static bool rockblox_help(void)
1223 #define WORDS (sizeof help_text / sizeof (char*))
1224 char *help_text
[] = {
1225 "Rockblox", "", "Aim", "", "Make", "the", "falling", "blocks", "of", "different",
1226 "shapes", "form", "full", "rows.", "Whenever", "a", "row", "is", "completed,", "it",
1227 "will", "be", "cleared", "away", "and", "you", "gain", "points."
1230 static struct style_text formation
[]={
1231 { 0, TEXT_CENTER
|TEXT_UNDERLINE
},
1235 #ifdef HAVE_LCD_BITMAP
1236 rb
->lcd_setfont(FONT_UI
);
1238 #ifdef HAVE_LCD_COLOR
1239 rb
->lcd_set_background(LCD_BLACK
);
1240 rb
->lcd_set_foreground(LCD_WHITE
);
1242 if (display_text(WORDS
, help_text
, formation
, NULL
))
1245 button
= rb
->button_get(true);
1246 if ( rb
->default_event_handler( button
) == SYS_USB_CONNECTED
)
1248 } while( ( button
== BUTTON_NONE
)
1249 || ( button
& (BUTTON_REL
|BUTTON_REPEAT
) ) );
1250 #ifdef HAVE_LCD_BITMAP
1251 rb
->lcd_setfont(FONT_SYSFIXED
);
1256 static int rockblox_menu_cb(int action
, const struct menu_item_ex
*this_item
)
1258 int i
= ((intptr_t)this_item
);
1259 if(action
== ACTION_REQUEST_MENUITEM
1260 && !resume
&& (i
==0 || i
==5))
1261 return ACTION_EXIT_MENUITEM
;
1265 static int rockblox_menu(void)
1269 MENUITEM_STRINGLIST(main_menu
, "Rockblox Menu", rockblox_menu_cb
,
1270 "Resume Game", "Start New Game",
1271 "Help", "High Scores", "Playback Control",
1272 "Quit without Saving", "Quit");
1274 rb
->button_clear_queue();
1276 switch (rb
->do_menu(&main_menu
, &selected
, NULL
, false)) {
1279 rb
->remove(RESUME_FILE
);
1280 init_rockblox(true);
1283 init_rockblox(false);
1286 if (rockblox_help())
1290 #ifdef HAVE_LCD_BITMAP
1291 highscore_show(MAX_HIGH_SCORES
, highest
, MAX_HIGH_SCORES
, true);
1293 rb
->splashf(2*HZ
, "High Score: %d", highest
[0].score
);
1297 if (playback_control(NULL
))
1304 rb
->splash(HZ
*1, "Saving game ...");
1308 case MENU_ATTACHED_USB
:
1318 static int rockblox_loop (void)
1321 int lastbutton
= BUTTON_NONE
;
1322 long next_down_tick
= *rb
->current_tick
+ level_speed(rockblox_status
.level
);
1324 if (rockblox_menu()) {
1328 resume_file
= false;
1331 #ifdef HAS_BUTTON_HOLD
1332 if (rb
->button_hold ()) {
1333 /* Turn on backlight timeout (revert to settings) */
1334 backlight_use_settings(); /* backlight control in lib/helper.c */
1335 rb
->splash(0, "Paused");
1336 while (rb
->button_hold ())
1339 /* Turn off backlight timeout */
1340 backlight_force_on(); /* backlight control in lib/helper.c */
1342 /* get rid of the splash text */
1343 rb
->lcd_bitmap (rockblox_background
, 0, 0, LCD_WIDTH
, LCD_HEIGHT
);
1353 button
= rb
->button_get_w_tmo (MAX(next_down_tick
- *rb
->current_tick
, 1));
1355 #ifdef ROCKBLOX_RC_OFF
1356 case ROCKBLOX_RC_OFF
:
1359 #ifdef ROCKBLOX_OFF_PRE
1360 if (lastbutton
!= ROCKBLOX_OFF_PRE
)
1367 #if defined(ROCKBLOX_ROTATE)
1368 case ROCKBLOX_ROTATE
:
1370 case ROCKBLOX_ROTATE_RIGHT
:
1371 case ROCKBLOX_ROTATE_RIGHT
| BUTTON_REPEAT
:
1372 #ifdef HAVE_SCROLLWHEEL
1373 /* if the wheel is disabled, add an event to the stack. */
1374 if(wheel_enabled
== false)
1377 /* if it's enabled, go ahead and rotate.. */
1380 move_block (0, 0, (rockblox_status
.co
+ 1) % figures
[rockblox_status
.cf
].max_or
);
1383 case ROCKBLOX_ROTATE_LEFT
:
1384 case ROCKBLOX_ROTATE_LEFT
| BUTTON_REPEAT
:
1385 #ifdef HAVE_SCROLLWHEEL
1386 if(wheel_enabled
== false)
1392 (rockblox_status
.co
+ figures
[rockblox_status
.cf
].max_or
-
1393 1) % figures
[rockblox_status
.cf
].max_or
);
1396 #ifdef ROCKBLOX_ROTATE_RIGHT2
1397 case ROCKBLOX_ROTATE_RIGHT2
:
1398 move_block (0, 0, (rockblox_status
.co
+ 1) % figures
[rockblox_status
.cf
].max_or
);
1403 case ROCKBLOX_DOWN
| BUTTON_REPEAT
:
1404 move_block (0, 1, rockblox_status
.co
);
1407 case ROCKBLOX_RIGHT
:
1408 case ROCKBLOX_RIGHT
| BUTTON_REPEAT
:
1409 move_block (1, 0, rockblox_status
.co
);
1413 case ROCKBLOX_LEFT
| BUTTON_REPEAT
:
1414 move_block (-1, 0, rockblox_status
.co
);
1418 #ifdef ROCKBLOX_DROP_PRE
1419 if (lastbutton
!= ROCKBLOX_DROP_PRE
)
1422 while (canMoveTo (rockblox_status
.cx
, rockblox_status
.cy
+ 1, rockblox_status
.co
))
1423 move_block (0, 1, rockblox_status
.co
);
1425 #ifdef ROCKBLOX_RESTART
1426 case ROCKBLOX_RESTART
:
1427 rb
->splash (HZ
* 1, "Restarting...");
1428 init_rockblox (false);
1433 if (rb
->default_event_handler (button
) == SYS_USB_CONNECTED
)
1434 return PLUGIN_USB_CONNECTED
;
1437 if (button
!= BUTTON_NONE
)
1438 lastbutton
= button
;
1440 #ifdef HAVE_SCROLLWHEEL
1441 /* check if we should enable the scroll wheel, if events
1442 * begin to stack up... */
1443 if(wheel_enabled
== false)
1445 /* stopped rotating the wheel, reset the count */
1446 if(wheel_events
== last_wheel_event
)
1448 last_wheel_event
= 0;
1451 /* rotated the wheel a while constantly, enable it. */
1452 else if(wheel_events
> 3)
1454 wheel_enabled
= true;
1457 /* this evens out the last event and the "current" event.
1458 * if we get an event next time through button reading, it will
1459 * remain ahead of last_event. if we don't, they'll end up equaling
1460 * each other.. thus, the scroll count will be reset. */
1461 if(wheel_enabled
== false && wheel_events
> last_wheel_event
)
1466 if (TIME_AFTER(*rb
->current_tick
, next_down_tick
)) {
1468 next_down_tick
+= level_speed(rockblox_status
.level
);
1469 if (TIME_AFTER(*rb
->current_tick
, next_down_tick
))
1470 /* restart time "raster" when we had to wait longer than usual
1471 * (pause, game restart etc) */
1472 next_down_tick
= *rb
->current_tick
+ level_speed(rockblox_status
.level
);
1475 if (rockblox_status
.gameover
) {
1477 rb
->lcd_set_foreground (LCD_BLACK
);
1490 enum plugin_status
plugin_start (const void *parameter
)
1495 rb
->srand (*rb
->current_tick
);
1497 /* Load HighScore if any */
1498 highscore_load(HIGH_SCORE
, highest
, MAX_HIGH_SCORES
);
1501 rb
->lcd_set_backdrop(NULL
);
1504 #ifdef HAVE_LCD_BITMAP
1505 rb
->lcd_setfont (FONT_SYSFIXED
);
1507 if (!pgfx_init(4, 2))
1509 rb
->splash(HZ
*2, "Old LCD :(");
1513 /* Turn off backlight timeout */
1514 backlight_force_on(); /* backlight control in lib/helper.c */
1516 resume_file
= resume
;
1517 while(!rockblox_loop()) {
1519 int position
= highscore_update(rockblox_status
.score
, rockblox_status
.level
, "", highest
,
1521 if (position
== 0) {
1522 rb
->splash(HZ
*2, "New High Score");
1524 if (position
!= -1) {
1525 #ifdef HAVE_LCD_BITMAP
1526 highscore_show(position
, highest
, MAX_HIGH_SCORES
, true);
1528 rb
->splashf(2*HZ
, "High Score: %d", highest
[position
].score
);
1534 #ifndef HAVE_LCD_BITMAP
1537 /* Save user's HighScore */
1538 highscore_save(HIGH_SCORE
, highest
, MAX_HIGH_SCORES
);
1539 backlight_use_settings(); /* backlight control in lib/helper.c */