Resume feature for Rockblox by dumping the state upon exiting and loading it when...
[kugel-rb.git] / apps / plugins / rockblox.c
blob368ad6bc7e4f1c3c47be3c9add1395a86a7e5c95
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
23 #include "plugin.h"
24 #include "lib/highscore.h"
25 #include "lib/playergfx.h"
26 #include "lib/helper.h"
28 PLUGIN_HEADER
30 #if (CONFIG_KEYPAD == IPOD_4G_PAD) || \
31 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
32 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
34 #define ROCKBLOX_OFF (BUTTON_MENU | BUTTON_SELECT)
35 #define ROCKBLOX_ROTATE_RIGHT BUTTON_SCROLL_BACK
36 #define ROCKBLOX_ROTATE_RIGHT2 (BUTTON_MENU | BUTTON_REL)
37 #define ROCKBLOX_ROTATE_LEFT BUTTON_SCROLL_FWD
38 #define ROCKBLOX_LEFT BUTTON_LEFT
39 #define ROCKBLOX_RIGHT BUTTON_RIGHT
40 #define ROCKBLOX_DOWN BUTTON_PLAY
41 #define ROCKBLOX_RESTART (BUTTON_SELECT | BUTTON_PLAY)
42 #define ROCKBLOX_DROP (BUTTON_SELECT | BUTTON_REL)
44 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
45 (CONFIG_KEYPAD == IRIVER_H300_PAD)
47 #define ROCKBLOX_OFF BUTTON_OFF
48 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
49 #define ROCKBLOX_ROTATE_LEFT BUTTON_SELECT
50 #define ROCKBLOX_DOWN BUTTON_DOWN
51 #define ROCKBLOX_LEFT BUTTON_LEFT
52 #define ROCKBLOX_RIGHT BUTTON_RIGHT
53 #define ROCKBLOX_DROP BUTTON_MODE
54 #define ROCKBLOX_RESTART BUTTON_ON
56 #define ROCKBLOX_RC_OFF BUTTON_RC_STOP
58 #elif CONFIG_KEYPAD == RECORDER_PAD
60 #define ROCKBLOX_OFF BUTTON_OFF
61 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
62 #define ROCKBLOX_ROTATE_LEFT BUTTON_PLAY
63 #define ROCKBLOX_DOWN BUTTON_DOWN
64 #define ROCKBLOX_LEFT BUTTON_LEFT
65 #define ROCKBLOX_RIGHT BUTTON_RIGHT
66 #define ROCKBLOX_DROP BUTTON_ON
67 #define ROCKBLOX_RESTART BUTTON_F1
69 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
71 #define ROCKBLOX_OFF BUTTON_OFF
72 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
73 #define ROCKBLOX_ROTATE_LEFT BUTTON_SELECT
74 #define ROCKBLOX_DOWN BUTTON_DOWN
75 #define ROCKBLOX_LEFT BUTTON_LEFT
76 #define ROCKBLOX_RIGHT BUTTON_RIGHT
77 #define ROCKBLOX_DROP BUTTON_ON
78 #define ROCKBLOX_RESTART BUTTON_F1
80 #elif CONFIG_KEYPAD == PLAYER_PAD
82 #define ROCKBLOX_OFF BUTTON_STOP
83 #define ROCKBLOX_ROTATE_RIGHT BUTTON_PLAY
84 #define ROCKBLOX_ROTATE_LEFT (BUTTON_ON|BUTTON_PLAY)
85 #define ROCKBLOX_DOWN BUTTON_MENU
86 #define ROCKBLOX_LEFT BUTTON_LEFT
87 #define ROCKBLOX_RIGHT BUTTON_RIGHT
88 #define ROCKBLOX_DROP_PRE BUTTON_ON
89 #define ROCKBLOX_DROP (BUTTON_ON|BUTTON_REL)
90 #define ROCKBLOX_RESTART (BUTTON_STOP|BUTTON_MENU)
92 #elif CONFIG_KEYPAD == ONDIO_PAD
94 #define ROCKBLOX_OFF BUTTON_OFF
95 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
96 #define ROCKBLOX_ROTATE_LEFT (BUTTON_MENU|BUTTON_UP)
97 #define ROCKBLOX_DOWN BUTTON_DOWN
98 #define ROCKBLOX_LEFT BUTTON_LEFT
99 #define ROCKBLOX_RIGHT BUTTON_RIGHT
100 #define ROCKBLOX_DROP_PRE BUTTON_MENU
101 #define ROCKBLOX_DROP (BUTTON_MENU|BUTTON_REL)
102 #define ROCKBLOX_RESTART (BUTTON_OFF|BUTTON_MENU)
104 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
106 #define ROCKBLOX_OFF BUTTON_POWER
107 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
108 #define ROCKBLOX_ROTATE_LEFT BUTTON_SELECT
109 #define ROCKBLOX_DOWN BUTTON_DOWN
110 #define ROCKBLOX_LEFT BUTTON_LEFT
111 #define ROCKBLOX_RIGHT BUTTON_RIGHT
112 #define ROCKBLOX_DROP BUTTON_REC
113 #define ROCKBLOX_RESTART BUTTON_PLAY
115 #elif CONFIG_KEYPAD == SANSA_E200_PAD
117 #define ROCKBLOX_OFF BUTTON_POWER
118 #define ROCKBLOX_ROTATE_RIGHT BUTTON_SCROLL_BACK
119 #define ROCKBLOX_ROTATE_RIGHT2 BUTTON_UP
120 #define ROCKBLOX_ROTATE_LEFT BUTTON_SCROLL_FWD
121 #define ROCKBLOX_DOWN BUTTON_DOWN
122 #define ROCKBLOX_LEFT BUTTON_LEFT
123 #define ROCKBLOX_RIGHT BUTTON_RIGHT
124 #define ROCKBLOX_DROP BUTTON_SELECT
125 #define ROCKBLOX_RESTART BUTTON_REC
127 #elif CONFIG_KEYPAD == SANSA_FUZE_PAD
129 #define ROCKBLOX_OFF (BUTTON_HOME|BUTTON_REPEAT)
130 #define ROCKBLOX_ROTATE_RIGHT BUTTON_SCROLL_BACK
131 #define ROCKBLOX_ROTATE_RIGHT2 BUTTON_UP
132 #define ROCKBLOX_ROTATE_LEFT BUTTON_SCROLL_FWD
133 #define ROCKBLOX_DOWN BUTTON_DOWN
134 #define ROCKBLOX_LEFT BUTTON_LEFT
135 #define ROCKBLOX_RIGHT BUTTON_RIGHT
136 #define ROCKBLOX_DROP (BUTTON_SELECT | BUTTON_REL)
137 #define ROCKBLOX_RESTART (BUTTON_SELECT | BUTTON_UP)
140 #elif CONFIG_KEYPAD == SANSA_C200_PAD
142 #define ROCKBLOX_OFF BUTTON_POWER
143 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
144 #define ROCKBLOX_ROTATE_RIGHT2 BUTTON_VOL_DOWN
145 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOL_UP
146 #define ROCKBLOX_DOWN BUTTON_DOWN
147 #define ROCKBLOX_LEFT BUTTON_LEFT
148 #define ROCKBLOX_RIGHT BUTTON_RIGHT
149 #define ROCKBLOX_DROP BUTTON_SELECT
150 #define ROCKBLOX_RESTART BUTTON_REC
152 #elif CONFIG_KEYPAD == SANSA_CLIP_PAD
154 #define ROCKBLOX_OFF BUTTON_POWER
155 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
156 #define ROCKBLOX_ROTATE_RIGHT2 BUTTON_VOL_DOWN
157 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOL_UP
158 #define ROCKBLOX_DOWN BUTTON_DOWN
159 #define ROCKBLOX_LEFT BUTTON_LEFT
160 #define ROCKBLOX_RIGHT BUTTON_RIGHT
161 #define ROCKBLOX_DROP BUTTON_SELECT
162 #define ROCKBLOX_RESTART BUTTON_HOME
164 #elif CONFIG_KEYPAD == SANSA_M200_PAD
166 #define ROCKBLOX_OFF BUTTON_POWER
167 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
168 #define ROCKBLOX_ROTATE_RIGHT2 BUTTON_VOL_DOWN
169 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOL_UP
170 #define ROCKBLOX_DOWN BUTTON_DOWN
171 #define ROCKBLOX_LEFT BUTTON_LEFT
172 #define ROCKBLOX_RIGHT BUTTON_RIGHT
173 #define ROCKBLOX_RESTART (BUTTON_SELECT | BUTTON_UP)
174 #define ROCKBLOX_DROP (BUTTON_SELECT | BUTTON_REL)
176 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
178 #define ROCKBLOX_OFF BUTTON_POWER
179 #define ROCKBLOX_ROTATE_RIGHT BUTTON_SCROLL_UP
180 #define ROCKBLOX_ROTATE_LEFT BUTTON_REW
181 #define ROCKBLOX_DOWN BUTTON_SCROLL_DOWN
182 #define ROCKBLOX_LEFT BUTTON_LEFT
183 #define ROCKBLOX_RIGHT BUTTON_RIGHT
184 #define ROCKBLOX_DROP BUTTON_FF
185 #define ROCKBLOX_RESTART BUTTON_PLAY
187 #elif CONFIG_KEYPAD == GIGABEAT_PAD
189 #define ROCKBLOX_OFF BUTTON_POWER
190 #define ROCKBLOX_ROTATE_RIGHT BUTTON_VOL_DOWN
191 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOL_UP
192 #define ROCKBLOX_ROTATE BUTTON_UP
193 #define ROCKBLOX_DOWN BUTTON_DOWN
194 #define ROCKBLOX_LEFT BUTTON_LEFT
195 #define ROCKBLOX_RIGHT BUTTON_RIGHT
196 #define ROCKBLOX_DROP BUTTON_SELECT
197 #define ROCKBLOX_RESTART BUTTON_A
199 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
201 #define ROCKBLOX_OFF BUTTON_PLAY
202 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
203 #define ROCKBLOX_ROTATE_LEFT BUTTON_SELECT
204 #define ROCKBLOX_DOWN BUTTON_DOWN
205 #define ROCKBLOX_LEFT BUTTON_LEFT
206 #define ROCKBLOX_RIGHT BUTTON_RIGHT
207 #define ROCKBLOX_DROP BUTTON_MODE
208 #define ROCKBLOX_RESTART BUTTON_EQ
210 #elif CONFIG_KEYPAD == MROBE500_PAD
211 #define ROCKBLOX_OFF BUTTON_POWER
213 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
214 #define ROCKBLOX_OFF BUTTON_BACK
215 #define ROCKBLOX_ROTATE_RIGHT BUTTON_VOL_DOWN
216 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOL_UP
217 #define ROCKBLOX_ROTATE BUTTON_UP
218 #define ROCKBLOX_DOWN BUTTON_DOWN
219 #define ROCKBLOX_LEFT BUTTON_LEFT
220 #define ROCKBLOX_RIGHT BUTTON_RIGHT
221 #define ROCKBLOX_DROP BUTTON_SELECT
222 #define ROCKBLOX_RESTART BUTTON_PLAY
224 #elif CONFIG_KEYPAD == MROBE100_PAD
226 #define ROCKBLOX_OFF BUTTON_POWER
227 #define ROCKBLOX_ROTATE_RIGHT BUTTON_MENU
228 #define ROCKBLOX_ROTATE_LEFT BUTTON_PLAY
229 #define ROCKBLOX_ROTATE BUTTON_UP
230 #define ROCKBLOX_DOWN BUTTON_DOWN
231 #define ROCKBLOX_LEFT BUTTON_LEFT
232 #define ROCKBLOX_RIGHT BUTTON_RIGHT
233 #define ROCKBLOX_DROP BUTTON_SELECT
234 #define ROCKBLOX_RESTART BUTTON_DISPLAY
236 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
238 #define ROCKBLOX_OFF BUTTON_RC_REC
239 #define ROCKBLOX_ROTATE_RIGHT BUTTON_RC_VOL_DOWN
240 #define ROCKBLOX_ROTATE_LEFT BUTTON_RC_VOL_UP
241 #define ROCKBLOX_DOWN BUTTON_RC_MENU
242 #define ROCKBLOX_LEFT BUTTON_RC_REW
243 #define ROCKBLOX_RIGHT BUTTON_RC_FF
244 #define ROCKBLOX_DROP BUTTON_RC_PLAY
245 #define ROCKBLOX_RESTART BUTTON_RC_MODE
247 #elif CONFIG_KEYPAD == COWOND2_PAD
248 #define ROCKBLOX_OFF BUTTON_POWER
249 #define ROCKBLOX_RESTART BUTTON_MENU
251 #elif CONFIG_KEYPAD == IAUDIO67_PAD
253 #define ROCKBLOX_OFF BUTTON_POWER
254 #define ROCKBLOX_ROTATE_RIGHT BUTTON_VOLDOWN
255 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOLUP
256 #define ROCKBLOX_DOWN BUTTON_STOP
257 #define ROCKBLOX_LEFT BUTTON_LEFT
258 #define ROCKBLOX_RIGHT BUTTON_RIGHT
259 #define ROCKBLOX_DROP BUTTON_PLAY
260 #define ROCKBLOX_RESTART BUTTON_MENU
262 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
263 #define ROCKBLOX_OFF BUTTON_BACK
264 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
265 #define ROCKBLOX_ROTATE_LEFT BUTTON_PLAY
266 #define ROCKBLOX_DOWN BUTTON_DOWN
267 #define ROCKBLOX_LEFT BUTTON_LEFT
268 #define ROCKBLOX_RIGHT BUTTON_RIGHT
269 #define ROCKBLOX_DROP BUTTON_SELECT
270 #define ROCKBLOX_RESTART BUTTON_CUSTOM
272 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
274 #define ROCKBLOX_OFF BUTTON_POWER
275 #define ROCKBLOX_ROTATE_RIGHT BUTTON_VOL_DOWN
276 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOL_UP
277 #define ROCKBLOX_ROTATE BUTTON_UP
278 #define ROCKBLOX_DOWN BUTTON_DOWN
279 #define ROCKBLOX_LEFT BUTTON_LEFT
280 #define ROCKBLOX_RIGHT BUTTON_RIGHT
281 #define ROCKBLOX_DROP BUTTON_SELECT
282 #define ROCKBLOX_RESTART BUTTON_MENU
284 #elif CONFIG_KEYPAD == ONDAVX747_PAD
285 #define ROCKBLOX_OFF BUTTON_POWER
286 #define ROCKBLOX_RESTART BUTTON_MENU
288 #else
289 #error No keymap defined!
290 #endif
292 #ifdef HAVE_TOUCHSCREEN
293 #ifndef ROCKBLOX_OFF
294 #define ROCKBLOX_OFF BUTTON_TOPLEFT
295 #endif
296 #ifndef ROCKBLOX_ROTATE_RIGHT
297 #define ROCKBLOX_ROTATE_RIGHT BUTTON_BOTTOMRIGHT
298 #endif
299 #ifndef ROCKBLOX_ROTATE_LEFT
300 #define ROCKBLOX_ROTATE_LEFT BUTTON_BOTTOMLEFT
301 #endif
302 #ifndef ROCKBLOX_DOWN
303 #define ROCKBLOX_DOWN BUTTON_BOTTOMMIDDLE
304 #endif
305 #ifndef ROCKBLOX_LEFT
306 #define ROCKBLOX_LEFT BUTTON_MIDLEFT
307 #endif
308 #ifndef ROCKBLOX_RIGHT
309 #define ROCKBLOX_RIGHT BUTTON_MIDRIGHT
310 #endif
311 #ifndef ROCKBLOX_DROP
312 #define ROCKBLOX_DROP BUTTON_CENTER
313 #endif
314 #ifndef ROCKBLOX_RESTART
315 #define ROCKBLOX_RESTART BUTTON_TOPRIGHT
316 #endif
317 #endif
319 #define BLOCKS_NUM 7
320 #define EMPTY_BLOCK 7
322 #define BOARD_WIDTH 10
324 #ifdef HAVE_LCD_BITMAP
326 #define BOARD_HEIGHT 20
328 #if (LCD_WIDTH == 640) && (LCD_HEIGHT == 480)
330 #define BLOCK_WIDTH 30
331 #define BLOCK_HEIGHT 30
332 #define BOARD_X 14
333 #define BOARD_Y 2
334 #define PREVIEW_X 342
335 #define PREVIEW_Y 482
336 #define LABEL_X 344
337 #define SCORE_Y 58
338 #define LEVEL_Y 142
339 #define LINES_Y 218
340 #define HIGH_LABEL_X 344
341 #define HIGH_SCORE_Y 326
342 #define HIGH_LEVEL_Y 344
344 #elif (LCD_WIDTH == 480) && (LCD_HEIGHT == 640)
346 #define BLOCK_WIDTH 30
347 #define BLOCK_HEIGHT 30
348 #define BOARD_X 14
349 #define BOARD_Y 2
350 #define PREVIEW_X 342
351 #define PREVIEW_Y 482
352 #define LABEL_X 344
353 #define SCORE_Y 58
354 #define LEVEL_Y 142
355 #define LINES_Y 218
356 #define HIGH_LABEL_X 344
357 #define HIGH_SCORE_Y 326
358 #define HIGH_LEVEL_Y 344
360 #elif (LCD_WIDTH == 320) && (LCD_HEIGHT == 240)
362 #define BLOCK_WIDTH 12
363 #define BLOCK_HEIGHT 12
364 #define BOARD_X 86
365 #define BOARD_Y 0
366 #define PREVIEW_X 12
367 #define PREVIEW_Y 11
368 #define LABEL_X 242
369 #define SCORE_Y 25
370 #define LEVEL_Y 70
371 #define LINES_Y 105
373 #elif (LCD_WIDTH == 240) && ((LCD_HEIGHT == 320) || (LCD_HEIGHT == 400))
375 #define BLOCK_WIDTH 15
376 #define BLOCK_HEIGHT 15
377 #define BOARD_X 7
378 #define BOARD_Y 1
379 #define PREVIEW_X 171
380 #define PREVIEW_Y 241
381 #define LABEL_X 172
382 #define SCORE_Y 29
383 #define LEVEL_Y 71
384 #define LINES_Y 109
385 #define HIGH_LABEL_X 172
386 #define HIGH_SCORE_Y 163
387 #define HIGH_LEVEL_Y 172
389 #elif (LCD_WIDTH == 220) && (LCD_HEIGHT == 176)
391 #define BLOCK_WIDTH 8
392 #define BLOCK_HEIGHT 8
393 #define BOARD_X 27
394 #define BOARD_Y 5
395 #define PREVIEW_X 158
396 #define PREVIEW_Y 130
397 #define LABEL_X 147
398 #define SCORE_Y 20
399 #define LEVEL_Y 65
400 #define LINES_Y 100
402 #elif (LCD_WIDTH == 176) && (LCD_HEIGHT == 132)
404 #define BLOCK_WIDTH 6
405 #define BLOCK_HEIGHT 6
406 #define BOARD_X 25
407 #define BOARD_Y 1
408 #define PREVIEW_X 126
409 #define PREVIEW_Y 102
410 #define LABEL_X 112
411 #define SCORE_Y 17
412 #define LEVEL_Y 49
413 #define LINES_Y 81
415 #elif (LCD_WIDTH == 176) && (LCD_HEIGHT == 220)
417 /* no room for the space in the highscore list */
418 #define _SPACE ""
420 #define BLOCK_WIDTH 10
421 #define BLOCK_HEIGHT 10
422 #define BOARD_X 6
423 #define BOARD_Y 10
424 #define PREVIEW_X 124
425 #define PREVIEW_Y 174
426 #define LABEL_X 117
427 #define SCORE_Y 18
428 #define LEVEL_Y 52
429 #define LINES_Y 85
430 #define HIGH_SCORE_Y 119
431 #define HIGH_LEVEL_Y 126
432 #define HIGH_LABEL_X 114
434 #elif (LCD_WIDTH == 160) && (LCD_HEIGHT == 128)
437 #define BLOCK_WIDTH 6
438 #define BLOCK_HEIGHT 6
439 #define BOARD_X 22
440 #define BOARD_Y 3
441 #define PREVIEW_X 114
442 #define PREVIEW_Y 100
443 #define LABEL_X 101
444 #define SCORE_Y 17
445 #define LEVEL_Y 49
446 #define LINES_Y 82
448 #elif (LCD_WIDTH == 138) && (LCD_HEIGHT == 110)
450 #define BLOCK_WIDTH 5
451 #define BLOCK_HEIGHT 5
452 #define BOARD_X 14
453 #define BOARD_Y 0
454 #define PREVIEW_X 98
455 #define PREVIEW_Y 88
456 #define LABEL_X 80
457 #define SCORE_Y 15
458 #define LEVEL_Y 45
459 #define LINES_Y 74
461 #elif (LCD_WIDTH == 132) && (LCD_HEIGHT == 80)
463 #define BLOCK_WIDTH 4
464 #define BLOCK_HEIGHT 4
465 #define BOARD_X 10
466 #define BOARD_Y 0
467 #define PREVIEW_X 89
468 #define PREVIEW_Y 61
469 #define LABEL_X 78
470 #define SCORE_Y 10
471 #define LEVEL_Y 30
472 #define LINES_Y 50
474 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 128)
476 #define BLOCK_WIDTH 6
477 #define BLOCK_HEIGHT 6
478 #define BOARD_X 4
479 #define BOARD_Y 3
480 #define PREVIEW_X 84
481 #define PREVIEW_Y 100
482 #define LABEL_X 71
483 #define SCORE_Y 17
484 #define LEVEL_Y 49
485 #define LINES_Y 82
487 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 96)
489 #define BLOCK_WIDTH 4
490 #define BLOCK_HEIGHT 4
491 #define BOARD_X 14
492 #define BOARD_Y 2
493 #define PREVIEW_X 89
494 #define PREVIEW_Y 76
495 #define LABEL_X 70
496 #define SCORE_Y 14
497 #define LEVEL_Y 39
498 #define LINES_Y 64
500 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 64)
502 #define BLOCK_WIDTH 3
503 #define BLOCK_HEIGHT 3
504 #define BOARD_X 9
505 #define BOARD_Y 3
506 #define PREVIEW_X 53
507 #define PREVIEW_Y 5
508 #define LABEL_X 70
509 #define SCORE_Y 32
510 #define LEVEL_Y 13
511 #define LINES_Y 51
513 #elif (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
515 #define BLOCK_WIDTH 4
516 #define BLOCK_HEIGHT 3
517 #define BOARD_X 9
518 #define BOARD_Y 3
519 #define PREVIEW_X 59
520 #define PREVIEW_Y 5
521 #define LABEL_X 59
522 #define SCORE_Y 32
523 #define LEVEL_Y 13
524 #define LEVEL_X 78
525 #define LINES_Y 51
527 #endif
529 #ifndef LEVEL_X
530 #define LEVEL_X LABEL_X
531 #endif
533 #ifndef LINES_X
534 #define LINES_X LABEL_X
535 #endif
537 #define MYLCD(fn) rb->lcd_ ## fn
539 extern const fb_data rockblox_background[];
541 #else /* HAVE_LCD_CHARCELLS */
543 #define BOARD_HEIGHT 14
545 #define BLOCK_WIDTH 1
546 #define BLOCK_HEIGHT 1
547 #define BOARD_X 5
548 #define BOARD_Y 0
549 #define PREVIEW_X 15
550 #define PREVIEW_Y 1
552 #define MYLCD(fn) pgfx_ ## fn
554 #endif
556 #ifndef _SPACE
557 #define _SPACE " "
558 #endif
559 /* <<Explanation on Rockblox shapes>>
562 %% - O has 1 orientation
564 %% %
565 %% %% - Z has 2 orientations
568 %% %
569 %% %% - S has 2 orientations
573 % %%%% - I has 2 orientations
576 % %%
577 % % % %%% - L has 4 orientations
578 %% %%% % %
580 % %%
581 % % % %%% - J has 4 orientations
582 %% %%% % %
584 % % %%%
585 %% % %% % - T has 4 orientations
586 % %%% %
589 /* c=current f=figure o=orientation n=next */
590 static struct _rockblox_status
592 int gameover;
593 int lines;
594 int level;
595 int score;
596 int cx;
597 int cy;
598 int cf;
599 int co;
600 int nf;
601 short board[BOARD_HEIGHT][BOARD_WIDTH]; /* 20 rows of 10 blocks */
602 } rockblox_status;
604 /* prototypes */
605 static void draw_next_block(void);
606 static void new_block(void);
608 #ifdef HAVE_SCROLLWHEEL
609 int wheel_events = 0, last_wheel_event = 0;
610 bool wheel_enabled = false;
611 #endif
613 static const short scoring[4] = { /* scoring for each number of lines */
614 #if BOARD_HEIGHT == 20
615 40 /* single */ , 100 /* double */ , 300 /* triple */ , 1200 /* rockblox */
616 #elif BOARD_HEIGHT == 14 /* Player special values */
617 60 /* single */ , 150 /* double */ , 500 /* triple */ , 2000 /* rockblox */
618 #endif
621 struct figure
623 #if LCD_DEPTH >= 2
624 unsigned short color[3]; /* color of figure (light,middle,shadow) */
625 #endif
626 unsigned short max_or; /* max orientations */
627 signed short shapeX[4], shapeY[4]; /* implementation of figures */
630 /* array of figures */
631 figures[BLOCKS_NUM] = {
632 /* O */
634 #if LCD_DEPTH >= 16
635 {LCD_RGBPACK (153, 255, 255), LCD_RGBPACK(0, 255, 255),
636 LCD_RGBPACK(0,153,153)},
637 #elif LCD_DEPTH == 2
638 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
639 #endif
641 {-1, 0, -1, 0},
642 {0, 0, 1, 1}
644 /* I */
646 #if LCD_DEPTH >= 16
647 {LCD_RGBPACK (255, 153, 128), LCD_RGBPACK (255, 0, 0),
648 LCD_RGBPACK (153, 0, 0)},
649 #elif LCD_DEPTH == 2
650 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
651 #endif
653 {-2, -1, 0, 1},
654 {0, 0, 0, 0}
656 /* 'Z' */
658 #if LCD_DEPTH >= 16
659 {LCD_RGBPACK (153, 255, 153), LCD_RGBPACK (0, 255, 0),
660 LCD_RGBPACK (0, 153, 0)},
661 #elif LCD_DEPTH == 2
662 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
663 #endif
665 {0, 1, -1, 0},
666 {0, 0, 1, 1}
668 /* 'S' */
670 #if LCD_DEPTH >= 16
671 {LCD_RGBPACK (153, 153, 255), LCD_RGBPACK (0, 0, 255),
672 LCD_RGBPACK (0, 0, 153)},
673 #elif LCD_DEPTH == 2
674 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
675 #endif
677 {-1, 0, 0, 1},
678 {0, 0, 1, 1}
680 /* 'L' */
682 #if LCD_DEPTH >= 16
683 {LCD_RGBPACK (255, 255, 153), LCD_RGBPACK (255, 255, 0),
684 LCD_RGBPACK (153, 153, 0)},
685 #elif LCD_DEPTH == 2
686 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
687 #endif
689 {-1, 0, 1, 1},
690 {0, 0, 0, 1}
692 /* 'J' */
694 #if LCD_DEPTH >= 16
695 {LCD_RGBPACK (255, 153, 255), LCD_RGBPACK (255, 0, 255),
696 LCD_RGBPACK (153, 0, 153)},
697 #elif LCD_DEPTH == 2
698 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
699 #endif
701 {-1, 0, 1, -1},
702 {0, 0, 0, 1}
704 /* 'T' */
706 #if LCD_DEPTH >= 16
707 {LCD_RGBPACK (204, 204, 204), LCD_RGBPACK (153, 153, 153),
708 LCD_RGBPACK (85, 85, 85)},
709 #elif LCD_DEPTH == 2
710 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
711 #endif
713 {-1, 0, 1, 0},
714 {0, 0, 0, 1}
718 /* Rockbox File System only supports full filenames inc dir */
719 #define HIGH_SCORE PLUGIN_GAMES_DIR "/rockblox.score"
720 #define RESUME_FILE PLUGIN_GAMES_DIR "/rockblox.resume"
721 #define MAX_HIGH_SCORES 5
723 /* Default High Scores... */
724 struct highscore Highest[MAX_HIGH_SCORES];
726 /* get random number from (0) to (range-1) */
727 static int t_rand (int range)
729 return rb->rand () % range;
732 static inline void show_game_over (void)
734 rb->splash(HZ,"Game over!");
737 /* init the board array to have no blocks */
738 static void init_board (void)
740 int i, j;
741 for (i = 0; i < BOARD_WIDTH; i++)
742 for (j = 0; j < BOARD_HEIGHT; j++)
743 rockblox_status.board[j][i] = EMPTY_BLOCK;
746 /* show the score, level and lines */
747 static void show_details (void)
749 char str[25]; /* for strings */
751 #ifdef HAVE_LCD_BITMAP
752 #if LCD_DEPTH >= 2
753 rb->lcd_set_foreground (LCD_BLACK);
754 rb->lcd_set_background (LCD_WHITE);
755 #endif
756 rb->snprintf (str, sizeof (str), "%d", rockblox_status.score);
757 rb->lcd_putsxy (LABEL_X, SCORE_Y, str);
758 rb->snprintf (str, sizeof (str), "%d", rockblox_status.level);
759 rb->lcd_putsxy (LEVEL_X, LEVEL_Y, str);
760 rb->snprintf (str, sizeof (str), "%d", rockblox_status.lines);
761 rb->lcd_putsxy (LINES_X, LINES_Y, str);
762 #else /* HAVE_LCD_CHARCELLS */
763 rb->snprintf (str, sizeof (str), "L%d/%d", rockblox_status.level,
764 rockblox_status.lines);
765 rb->lcd_puts (5, 0, str);
766 rb->snprintf (str, sizeof (str), "S%d", rockblox_status.score);
767 rb->lcd_puts (5, 1, str);
768 #endif
771 #ifdef HIGH_SCORE_Y
772 static void show_highscores (void)
774 int i;
775 char str[25]; /* for strings */
777 for (i = MAX_HIGH_SCORES-1; i>=0; i--)
779 rb->snprintf (str, sizeof (str), "%06d" _SPACE "L%1d",Highest[i].score, Highest[i].level);
780 rb->lcd_putsxy (HIGH_LABEL_X, HIGH_SCORE_Y + (10 * ((MAX_HIGH_SCORES-1) - i)), str);
783 #endif
785 /* Returns >0 on successful read AND if the game wasn't over, else 0 */
786 static int load_resume(void)
788 int fd;
789 fd = rb->open(RESUME_FILE, O_RDONLY);
790 if (fd < 0)
791 return 0;
793 if (rb->read(fd, &rockblox_status, sizeof(struct _rockblox_status))
794 < (ssize_t)sizeof(struct _rockblox_status))
796 rb->splash(HZ/2, "Loading Rockblox resume info failed");
797 return 0;
800 rb->close(fd);
802 if (rockblox_status.gameover)
803 show_game_over();
805 return !rockblox_status.gameover;
808 /* Returns >0 on success, else 0 */
809 static int dump_resume(void)
811 int fd;
813 fd = rb->open(RESUME_FILE, O_WRONLY|O_CREAT);
814 if (fd <= 0)
815 goto fail;
817 if (rb->write(fd, &rockblox_status, sizeof(struct _rockblox_status))
818 <= 0)
820 rb->close(fd);
821 goto fail;
823 rb->close(fd);
824 return 1;
826 fail:
827 rb->splash(HZ/2, "Writing Rockblox resume info failed");
828 return 0;
830 static void init_rockblox (bool resume)
832 highscore_update(rockblox_status.score, rockblox_status.level, Highest,
833 MAX_HIGH_SCORES);
834 #ifdef HAVE_LCD_BITMAP
835 rb->lcd_bitmap (rockblox_background, 0, 0, LCD_WIDTH, LCD_HEIGHT);
836 #else /* HAVE_LCD_CHARCELLS */
837 pgfx_display (0, 0);
838 pgfx_display_block (3, 0, 3, 1);
839 pgfx_display_block (4, 0, 3, 0);
840 pgfx_clear_display();
841 pgfx_fillrect (3, 0, 2, 14);
842 pgfx_fillrect (15, 7, 2, 7);
843 pgfx_update();
844 #endif
845 if (!resume || !load_resume())
847 rockblox_status.level = 1;
848 rockblox_status.lines = 0;
849 rockblox_status.score = 0;
850 rockblox_status.nf = t_rand(BLOCKS_NUM);
851 init_board ();
852 new_block ();
854 draw_next_block();
856 show_details ();
857 #ifdef HIGH_SCORE_Y
858 show_highscores ();
859 #endif
862 static inline int level_speed(int level)
864 #if BOARD_HEIGHT == 20
865 return (5*HZ) / (level + 9);
866 #elif BOARD_HEIGHT == 14
867 return (7*HZ) / (level + 9);
868 #endif
871 static int getRelativeX (int figure, int square, int orientation)
873 switch (orientation) {
874 case 0:
875 return figures[figure].shapeX[square];
876 case 1:
877 return figures[figure].shapeY[square];
878 case 2:
879 return -figures[figure].shapeX[square];
880 case 3:
881 return -figures[figure].shapeY[square];
882 default:
883 return 0;
887 static int getRelativeY (int figure, int square, int orientation)
889 switch (orientation) {
890 case 0:
891 return figures[figure].shapeY[square];
892 case 1:
893 return -figures[figure].shapeX[square];
894 case 2:
895 return -figures[figure].shapeY[square];
896 case 3:
897 return figures[figure].shapeX[square];
898 default:
899 return 0;
903 /* redraw the while board on the screen */
904 static void refresh_board (void)
906 int i, j, x, y, block;
908 #if LCD_DEPTH >= 2
909 rb->lcd_set_foreground (LCD_BLACK);
910 #elif LCD_DEPTH == 1
911 MYLCD(set_drawmode) (DRMODE_SOLID | DRMODE_INVERSEVID);
912 #endif
914 MYLCD(fillrect) (BOARD_X, BOARD_Y, BOARD_WIDTH * BLOCK_WIDTH,
915 BOARD_HEIGHT * BLOCK_HEIGHT);
917 #if LCD_DEPTH == 1
918 MYLCD(set_drawmode) (DRMODE_SOLID);
919 #endif
921 for (i = 0; i < BOARD_WIDTH; i++)
922 for (j = 0; j < BOARD_HEIGHT; j++) {
923 block = rockblox_status.board[j][i];
924 if (block != EMPTY_BLOCK) {
925 #ifdef HAVE_LCD_BITMAP
926 #if LCD_DEPTH >= 2
927 /* middle drawing */
928 rb->lcd_set_foreground (figures[block].color[1]);
929 #endif
930 rb->lcd_fillrect (BOARD_X + i * BLOCK_WIDTH,
931 BOARD_Y + j * BLOCK_HEIGHT,
932 BLOCK_WIDTH, BLOCK_HEIGHT);
933 #if LCD_DEPTH >= 2
934 /* light drawing */
935 rb->lcd_set_foreground (figures[block].color[0]);
936 #endif
937 rb->lcd_vline (BOARD_X + i * BLOCK_WIDTH,
938 BOARD_Y + j * BLOCK_HEIGHT,
939 BOARD_Y + (j + 1) * BLOCK_HEIGHT - 2);
940 rb->lcd_hline (BOARD_X + i * BLOCK_WIDTH,
941 BOARD_X + (i + 1) * BLOCK_WIDTH - 2,
942 BOARD_Y + j * BLOCK_HEIGHT);
943 #if LCD_DEPTH >= 2
944 /* shadow drawing */
945 rb->lcd_set_foreground (figures[block].color[2]);
946 #endif
947 rb->lcd_vline (BOARD_X + (i + 1) * BLOCK_WIDTH - 1,
948 BOARD_Y + j * BLOCK_HEIGHT + 1,
949 BOARD_Y + (j + 1) * BLOCK_HEIGHT - 1);
950 rb->lcd_hline (BOARD_X + i * BLOCK_WIDTH + 1,
951 BOARD_X + (i + 1) * BLOCK_WIDTH - 1,
952 BOARD_Y + (j + 1) * BLOCK_HEIGHT - 1);
953 #else /* HAVE_LCD_CHARCELLS */
954 pgfx_drawpixel (BOARD_X + i, BOARD_Y + j);
955 #endif
959 for (i = 0; i < 4; i++) {
960 x = getRelativeX (rockblox_status.cf, i, rockblox_status.co)
961 + rockblox_status.cx;
962 y = getRelativeY (rockblox_status.cf, i, rockblox_status.co)
963 + rockblox_status.cy;
964 #ifdef HAVE_LCD_BITMAP
965 #if LCD_DEPTH >= 2
966 /* middle drawing */
967 rb->lcd_set_foreground (figures[rockblox_status.cf].color[1]);
968 #endif
969 rb->lcd_fillrect (BOARD_X + x * BLOCK_WIDTH,
970 BOARD_Y + y * BLOCK_HEIGHT,
971 BLOCK_WIDTH, BLOCK_HEIGHT);
972 #if LCD_DEPTH >= 2
973 /* light drawing */
974 rb->lcd_set_foreground (figures[rockblox_status.cf].color[0]);
975 #endif
976 rb->lcd_vline (BOARD_X + x * BLOCK_WIDTH, BOARD_Y + y * BLOCK_HEIGHT,
977 BOARD_Y + (y + 1) * BLOCK_HEIGHT - 2);
978 rb->lcd_hline (BOARD_X + x * BLOCK_WIDTH,
979 BOARD_X + (x + 1) * BLOCK_WIDTH - 2,
980 BOARD_Y + y * BLOCK_HEIGHT);
981 #if LCD_DEPTH >= 2
982 /* shadow drawing */
983 rb->lcd_set_foreground (figures[rockblox_status.cf].color[2]);
984 #endif
985 rb->lcd_vline (BOARD_X + (x + 1) * BLOCK_WIDTH - 1,
986 BOARD_Y + y * BLOCK_HEIGHT + 1,
987 BOARD_Y + (y + 1) * BLOCK_HEIGHT - 1);
988 rb->lcd_hline (BOARD_X + x * BLOCK_WIDTH + 1,
989 BOARD_X + (x + 1) * BLOCK_WIDTH - 1,
990 BOARD_Y + (y + 1) * BLOCK_HEIGHT - 1);
991 #else /* HAVE_LCD_CHARCELLS */
992 pgfx_drawpixel (BOARD_X + x, BOARD_Y + y);
993 #endif
995 MYLCD(update) ();
998 static bool canMoveTo (int x, int y, int newOrientation)
1000 int i, rx, ry;
1001 for (i = 0; i < 4; i++) {
1002 ry = getRelativeY (rockblox_status.cf, i, newOrientation) + y;
1003 rx = getRelativeX (rockblox_status.cf, i, newOrientation) + x;
1004 if ((rx < 0 || rx >= BOARD_WIDTH) ||
1005 (ry < 0 || ry >= BOARD_HEIGHT) ||
1006 (rockblox_status.board[ry][rx] != EMPTY_BLOCK))
1007 return false;
1009 return true;
1012 /* draws the preview of next block in the preview window */
1013 static void draw_next_block (void)
1015 int i, rx, ry;
1016 /* clear preview window first */
1017 #if LCD_DEPTH >= 2
1018 rb->lcd_set_foreground (LCD_BLACK);
1019 #elif LCD_DEPTH == 1
1020 MYLCD(set_drawmode) (DRMODE_SOLID | DRMODE_INVERSEVID);
1021 #endif
1023 /* 4x4 */
1024 MYLCD(fillrect) (PREVIEW_X, PREVIEW_Y, BLOCK_WIDTH * 4, BLOCK_HEIGHT * 4);
1026 #if LCD_DEPTH == 1
1027 MYLCD(set_drawmode) (DRMODE_SOLID);
1028 #endif
1030 /* draw the lightgray rectangles */
1031 #if LCD_DEPTH >= 16
1032 rb->lcd_set_foreground (LCD_RGBPACK (40, 40, 40));
1033 #elif LCD_DEPTH == 2
1034 rb->lcd_set_foreground (LCD_DARKGRAY);
1035 #endif
1037 #if LCD_DEPTH >= 2
1038 for (rx = 0; rx < 4; rx++)
1039 for (ry = 0; ry < 4; ry++)
1040 rb->lcd_drawrect (PREVIEW_X + rx * BLOCK_WIDTH,
1041 PREVIEW_Y + ry * BLOCK_HEIGHT, BLOCK_WIDTH,
1042 BLOCK_HEIGHT);
1043 #endif
1045 /* draw the figure */
1046 for (i = 0; i < 4; i++) {
1047 rx = getRelativeX (rockblox_status.nf, i, 0) + 2;
1048 ry = getRelativeY (rockblox_status.nf, i, 0) + 2;
1049 #ifdef HAVE_LCD_BITMAP
1050 #if LCD_DEPTH >= 2
1051 rb->lcd_set_foreground (figures[rockblox_status.nf].color[1]); /* middle drawing */
1052 #endif
1053 rb->lcd_fillrect (PREVIEW_X + rx * BLOCK_WIDTH,
1054 PREVIEW_Y + ry * BLOCK_HEIGHT,
1055 BLOCK_WIDTH, BLOCK_HEIGHT);
1056 #if LCD_DEPTH >= 2
1057 rb->lcd_set_foreground (figures[rockblox_status.nf].color[0]); /* light drawing */
1058 #endif
1059 rb->lcd_vline (PREVIEW_X + rx * BLOCK_WIDTH,
1060 PREVIEW_Y + ry * BLOCK_HEIGHT,
1061 PREVIEW_Y + (ry + 1) * BLOCK_HEIGHT - 2);
1062 rb->lcd_hline (PREVIEW_X + rx * BLOCK_WIDTH,
1063 PREVIEW_X + (rx + 1) * BLOCK_WIDTH - 2,
1064 PREVIEW_Y + ry * BLOCK_HEIGHT);
1065 #if LCD_DEPTH >= 2
1066 rb->lcd_set_foreground (figures[rockblox_status.nf].color[2]); /* shadow drawing */
1067 #endif
1068 rb->lcd_vline (PREVIEW_X + (rx + 1) * BLOCK_WIDTH - 1,
1069 PREVIEW_Y + ry * BLOCK_HEIGHT + 1,
1070 PREVIEW_Y + (ry + 1) * BLOCK_HEIGHT - 1);
1071 rb->lcd_hline (PREVIEW_X + rx * BLOCK_WIDTH + 1,
1072 PREVIEW_X + (rx + 1) * BLOCK_WIDTH - 1,
1073 PREVIEW_Y + (ry + 1) * BLOCK_HEIGHT - 1);
1074 #else /* HAVE_LCD_CHARCELLS */
1075 pgfx_drawpixel (PREVIEW_X + rx, PREVIEW_Y + ry);
1076 #endif
1081 /* move the block to a relative location */
1082 static void move_block (int x, int y, int o)
1084 if (canMoveTo (rockblox_status.cx + x, rockblox_status.cy + y, o)) {
1085 rockblox_status.cy += y;
1086 rockblox_status.cx += x;
1087 rockblox_status.co = o;
1091 /* try to add a new block to play with (return true if gameover) */
1092 static void new_block (void)
1094 rockblox_status.cy = 1;
1095 rockblox_status.cx = 5;
1096 rockblox_status.cf = rockblox_status.nf;
1097 rockblox_status.co = 0; /* start at the same orientation all time */
1098 rockblox_status.nf = t_rand (BLOCKS_NUM);
1099 rockblox_status.gameover = !canMoveTo (rockblox_status.cx,
1100 rockblox_status.cy, rockblox_status.co);
1102 draw_next_block ();
1106 /* check for filled rockblox_status.lines and do what necessary */
1107 static int check_lines (void)
1110 int i, j, y;
1111 int rockblox = 0;
1113 for (j = 0; j < BOARD_HEIGHT; j++) {
1114 for (i = 0; ((i < BOARD_WIDTH) &&
1115 (rockblox_status.board[j][i] != EMPTY_BLOCK)); i++);
1116 if (i == BOARD_WIDTH) { /* woo hoo, we have a line */
1117 rockblox++;
1118 for (y = j; y > 0; y--)
1120 for (i = 0; i < BOARD_WIDTH; i++)
1121 { /* fall line */
1122 rockblox_status.board[y][i] = rockblox_status.board[y - 1][i];
1128 return rockblox;
1131 /* moves down the figure and returns true if gameover */
1132 static void move_down (void)
1134 int l, i, rx, ry;
1136 if (!canMoveTo (rockblox_status.cx, rockblox_status.cy + 1, rockblox_status.co)) {
1137 /* save figure to board */
1138 for (i = 0; i < 4; i++) {
1139 rx = getRelativeX (rockblox_status.cf, i, rockblox_status.co) + rockblox_status.cx;
1140 ry = getRelativeY (rockblox_status.cf, i, rockblox_status.co) + rockblox_status.cy;
1141 rockblox_status.board[ry][rx] = rockblox_status.cf;
1143 /* check if formed some lines */
1144 l = check_lines ();
1145 if (l) {
1146 /* the original scoring from "http://en.wikipedia.org/wiki/Rockblox" */
1147 rockblox_status.score += scoring[l - 1] * rockblox_status.level;
1148 rockblox_status.lines += l;
1149 rockblox_status.level = (int) rockblox_status.lines / 10 + 1;
1152 /* show details */
1153 show_details ();
1155 /* generate a new figure */
1156 new_block ();
1157 } else
1158 move_block (0, 1, rockblox_status.co);
1161 static int rockblox_loop (void)
1163 int button;
1164 int lastbutton = BUTTON_NONE;
1165 long next_down_tick = *rb->current_tick + level_speed(rockblox_status.level);
1167 while (1) {
1168 #ifdef HAS_BUTTON_HOLD
1169 if (rb->button_hold ()) {
1170 /* Turn on backlight timeout (revert to settings) */
1171 backlight_use_settings(); /* backlight control in lib/helper.c */
1172 rb->splash(0, "Paused");
1173 while (rb->button_hold ())
1174 rb->sleep(HZ/10);
1176 /* Turn off backlight timeout */
1177 backlight_force_on(); /* backlight control in lib/helper.c */
1179 /* get rid of the splash text */
1180 rb->lcd_bitmap (rockblox_background, 0, 0, LCD_WIDTH, LCD_HEIGHT);
1181 show_details ();
1182 #ifdef HIGH_SCORE_Y
1183 show_highscores ();
1184 #endif
1185 draw_next_block ();
1186 refresh_board ();
1188 #endif
1190 button = rb->button_get_w_tmo (MAX(next_down_tick - *rb->current_tick, 1));
1191 switch (button) {
1192 #ifdef ROCKBLOX_RC_OFF
1193 case ROCKBLOX_RC_OFF:
1194 #endif
1195 case ROCKBLOX_OFF:
1196 return PLUGIN_OK;
1198 #if defined(ROCKBLOX_ROTATE)
1199 case ROCKBLOX_ROTATE:
1200 #endif
1201 case ROCKBLOX_ROTATE_RIGHT:
1202 case ROCKBLOX_ROTATE_RIGHT | BUTTON_REPEAT:
1203 #ifdef HAVE_SCROLLWHEEL
1204 /* if the wheel is disabled, add an event to the stack. */
1205 if(wheel_enabled == false)
1206 wheel_events++;
1208 /* if it's enabled, go ahead and rotate.. */
1209 if(wheel_enabled)
1210 #endif
1211 move_block (0, 0, (rockblox_status.co + 1) % figures[rockblox_status.cf].max_or);
1212 break;
1214 case ROCKBLOX_ROTATE_LEFT:
1215 case ROCKBLOX_ROTATE_LEFT | BUTTON_REPEAT:
1216 #ifdef HAVE_SCROLLWHEEL
1217 if(wheel_enabled == false)
1218 wheel_events++;
1220 if(wheel_enabled)
1221 #endif
1222 move_block (0, 0,
1223 (rockblox_status.co + figures[rockblox_status.cf].max_or -
1224 1) % figures[rockblox_status.cf].max_or);
1225 break;
1227 #ifdef ROCKBLOX_ROTATE_RIGHT2
1228 case ROCKBLOX_ROTATE_RIGHT2:
1229 move_block (0, 0, (rockblox_status.co + 1) % figures[rockblox_status.cf].max_or);
1230 break;
1231 #endif
1233 case ROCKBLOX_DOWN:
1234 case ROCKBLOX_DOWN | BUTTON_REPEAT:
1235 move_block (0, 1, rockblox_status.co);
1236 break;
1238 case ROCKBLOX_RIGHT:
1239 case ROCKBLOX_RIGHT | BUTTON_REPEAT:
1240 move_block (1, 0, rockblox_status.co);
1241 break;
1243 case ROCKBLOX_LEFT:
1244 case ROCKBLOX_LEFT | BUTTON_REPEAT:
1245 move_block (-1, 0, rockblox_status.co);
1246 break;
1248 case ROCKBLOX_DROP:
1249 #ifdef ROCKBLOX_DROP_PRE
1250 if (lastbutton != ROCKBLOX_DROP_PRE)
1251 break;
1252 #endif
1253 while (canMoveTo (rockblox_status.cx, rockblox_status.cy + 1, rockblox_status.co))
1254 move_block (0, 1, rockblox_status.co);
1255 break;
1256 #ifdef ROCKBLOX_RESTART
1257 case ROCKBLOX_RESTART:
1258 rb->splash (HZ * 1, "Restarting...");
1259 init_rockblox (false);
1260 break;
1261 #endif
1263 default:
1264 if (rb->default_event_handler (button) == SYS_USB_CONNECTED)
1265 return PLUGIN_USB_CONNECTED;
1266 break;
1268 if (button != BUTTON_NONE)
1269 lastbutton = button;
1271 #ifdef HAVE_SCROLLWHEEL
1272 /* check if we should enable the scroll wheel, if events
1273 * begin to stack up... */
1274 if(wheel_enabled == false)
1276 /* stopped rotating the wheel, reset the count */
1277 if(wheel_events == last_wheel_event)
1279 last_wheel_event = 0;
1280 wheel_events = 0;
1282 /* rotated the wheel a while constantly, enable it. */
1283 else if(wheel_events > 3)
1285 wheel_enabled = true;
1288 /* this evens out the last event and the "current" event.
1289 * if we get an event next time through button reading, it will
1290 * remain ahead of last_event. if we don't, they'll end up equaling
1291 * each other.. thus, the scroll count will be reset. */
1292 if(wheel_enabled == false && wheel_events > last_wheel_event)
1293 last_wheel_event++;
1295 #endif
1297 if (TIME_AFTER(*rb->current_tick, next_down_tick)) {
1298 move_down ();
1299 next_down_tick += level_speed(rockblox_status.level);
1300 if (TIME_AFTER(*rb->current_tick, next_down_tick))
1301 /* restart time "raster" when we had to wait longer than usual
1302 * (pause, game restart etc) */
1303 next_down_tick = *rb->current_tick + level_speed(rockblox_status.level);
1306 if (rockblox_status.gameover) {
1307 #if LCD_DEPTH >= 2
1308 rb->lcd_set_foreground (LCD_BLACK);
1309 #endif
1310 show_game_over();
1311 init_rockblox (false);
1314 refresh_board ();
1317 return PLUGIN_OK;
1320 enum plugin_status plugin_start (const void *parameter)
1322 int ret;
1324 (void) parameter;
1326 rb->srand (*rb->current_tick);
1328 /* Load HighScore if any */
1329 highscore_load(HIGH_SCORE,Highest,MAX_HIGH_SCORES);
1331 #if LCD_DEPTH > 1
1332 rb->lcd_set_backdrop(NULL);
1333 #endif
1335 #ifdef HAVE_LCD_BITMAP
1336 rb->lcd_setfont (FONT_SYSFIXED);
1337 #else
1338 if (!pgfx_init(4, 2))
1340 rb->splash(HZ*2, "Old LCD :(");
1341 return PLUGIN_OK;
1343 #endif
1344 /* Turn off backlight timeout */
1345 backlight_force_on(); /* backlight control in lib/helper.c */
1347 init_rockblox (true);
1348 ret = rockblox_loop ();
1350 #ifndef HAVE_LCD_BITMAP
1351 pgfx_release();
1352 #endif
1353 /* Save user's HighScore */
1354 highscore_save(HIGH_SCORE,Highest,MAX_HIGH_SCORES);
1355 backlight_use_settings(); /* backlight control in lib/helper.c */
1357 dump_resume();
1359 return ret;