Don't force double-buffering for sd devices. They apparently are not faster with...
[kugel-rb.git] / apps / plugins / rockblox.c
blob7aaf26fe03b49aed02e0ec515bad125e12cce361
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_PRE BUTTON_STOP
83 #define ROCKBLOX_OFF (BUTTON_STOP|BUTTON_REL)
84 #define ROCKBLOX_ROTATE_RIGHT BUTTON_PLAY
85 #define ROCKBLOX_ROTATE_LEFT (BUTTON_ON|BUTTON_PLAY)
86 #define ROCKBLOX_DOWN BUTTON_MENU
87 #define ROCKBLOX_LEFT BUTTON_LEFT
88 #define ROCKBLOX_RIGHT BUTTON_RIGHT
89 #define ROCKBLOX_DROP_PRE BUTTON_ON
90 #define ROCKBLOX_DROP (BUTTON_ON|BUTTON_REL)
91 #define ROCKBLOX_RESTART (BUTTON_STOP|BUTTON_MENU)
93 #elif CONFIG_KEYPAD == ONDIO_PAD
95 #define ROCKBLOX_OFF_PRE BUTTON_OFF
96 #define ROCKBLOX_OFF (BUTTON_OFF|BUTTON_REL)
97 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
98 #define ROCKBLOX_ROTATE_LEFT (BUTTON_MENU|BUTTON_UP)
99 #define ROCKBLOX_DOWN BUTTON_DOWN
100 #define ROCKBLOX_LEFT BUTTON_LEFT
101 #define ROCKBLOX_RIGHT BUTTON_RIGHT
102 #define ROCKBLOX_DROP_PRE BUTTON_MENU
103 #define ROCKBLOX_DROP (BUTTON_MENU|BUTTON_REL)
104 #define ROCKBLOX_RESTART (BUTTON_OFF|BUTTON_MENU)
106 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
108 #define ROCKBLOX_OFF BUTTON_POWER
109 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
110 #define ROCKBLOX_ROTATE_LEFT BUTTON_SELECT
111 #define ROCKBLOX_DOWN BUTTON_DOWN
112 #define ROCKBLOX_LEFT BUTTON_LEFT
113 #define ROCKBLOX_RIGHT BUTTON_RIGHT
114 #define ROCKBLOX_DROP BUTTON_REC
115 #define ROCKBLOX_RESTART BUTTON_PLAY
117 #elif CONFIG_KEYPAD == SANSA_E200_PAD
119 #define ROCKBLOX_OFF BUTTON_POWER
120 #define ROCKBLOX_ROTATE_RIGHT BUTTON_SCROLL_BACK
121 #define ROCKBLOX_ROTATE_RIGHT2 BUTTON_UP
122 #define ROCKBLOX_ROTATE_LEFT BUTTON_SCROLL_FWD
123 #define ROCKBLOX_DOWN BUTTON_DOWN
124 #define ROCKBLOX_LEFT BUTTON_LEFT
125 #define ROCKBLOX_RIGHT BUTTON_RIGHT
126 #define ROCKBLOX_DROP BUTTON_SELECT
127 #define ROCKBLOX_RESTART BUTTON_REC
129 #elif CONFIG_KEYPAD == SANSA_FUZE_PAD
131 #define ROCKBLOX_OFF (BUTTON_HOME|BUTTON_REPEAT)
132 #define ROCKBLOX_ROTATE_RIGHT BUTTON_SCROLL_BACK
133 #define ROCKBLOX_ROTATE_RIGHT2 BUTTON_UP
134 #define ROCKBLOX_ROTATE_LEFT BUTTON_SCROLL_FWD
135 #define ROCKBLOX_DOWN BUTTON_DOWN
136 #define ROCKBLOX_LEFT BUTTON_LEFT
137 #define ROCKBLOX_RIGHT BUTTON_RIGHT
138 #define ROCKBLOX_DROP (BUTTON_SELECT | BUTTON_REL)
139 #define ROCKBLOX_RESTART (BUTTON_SELECT | BUTTON_UP)
142 #elif CONFIG_KEYPAD == SANSA_C200_PAD
144 #define ROCKBLOX_OFF BUTTON_POWER
145 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
146 #define ROCKBLOX_ROTATE_RIGHT2 BUTTON_VOL_DOWN
147 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOL_UP
148 #define ROCKBLOX_DOWN BUTTON_DOWN
149 #define ROCKBLOX_LEFT BUTTON_LEFT
150 #define ROCKBLOX_RIGHT BUTTON_RIGHT
151 #define ROCKBLOX_DROP BUTTON_SELECT
152 #define ROCKBLOX_RESTART BUTTON_REC
154 #elif CONFIG_KEYPAD == SANSA_CLIP_PAD
156 #define ROCKBLOX_OFF BUTTON_POWER
157 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
158 #define ROCKBLOX_ROTATE_RIGHT2 BUTTON_VOL_DOWN
159 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOL_UP
160 #define ROCKBLOX_DOWN BUTTON_DOWN
161 #define ROCKBLOX_LEFT BUTTON_LEFT
162 #define ROCKBLOX_RIGHT BUTTON_RIGHT
163 #define ROCKBLOX_DROP BUTTON_SELECT
164 #define ROCKBLOX_RESTART BUTTON_HOME
166 #elif CONFIG_KEYPAD == SANSA_M200_PAD
168 #define ROCKBLOX_OFF BUTTON_POWER
169 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
170 #define ROCKBLOX_ROTATE_RIGHT2 BUTTON_VOL_DOWN
171 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOL_UP
172 #define ROCKBLOX_DOWN BUTTON_DOWN
173 #define ROCKBLOX_LEFT BUTTON_LEFT
174 #define ROCKBLOX_RIGHT BUTTON_RIGHT
175 #define ROCKBLOX_RESTART (BUTTON_SELECT | BUTTON_UP)
176 #define ROCKBLOX_DROP (BUTTON_SELECT | BUTTON_REL)
178 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
180 #define ROCKBLOX_OFF BUTTON_POWER
181 #define ROCKBLOX_ROTATE_RIGHT BUTTON_SCROLL_UP
182 #define ROCKBLOX_ROTATE_LEFT BUTTON_REW
183 #define ROCKBLOX_DOWN BUTTON_SCROLL_DOWN
184 #define ROCKBLOX_LEFT BUTTON_LEFT
185 #define ROCKBLOX_RIGHT BUTTON_RIGHT
186 #define ROCKBLOX_DROP BUTTON_FF
187 #define ROCKBLOX_RESTART BUTTON_PLAY
189 #elif CONFIG_KEYPAD == GIGABEAT_PAD
191 #define ROCKBLOX_OFF BUTTON_POWER
192 #define ROCKBLOX_ROTATE_RIGHT BUTTON_VOL_DOWN
193 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOL_UP
194 #define ROCKBLOX_ROTATE BUTTON_UP
195 #define ROCKBLOX_DOWN BUTTON_DOWN
196 #define ROCKBLOX_LEFT BUTTON_LEFT
197 #define ROCKBLOX_RIGHT BUTTON_RIGHT
198 #define ROCKBLOX_DROP BUTTON_SELECT
199 #define ROCKBLOX_RESTART BUTTON_A
201 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
203 #define ROCKBLOX_OFF BUTTON_PLAY
204 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
205 #define ROCKBLOX_ROTATE_LEFT BUTTON_SELECT
206 #define ROCKBLOX_DOWN BUTTON_DOWN
207 #define ROCKBLOX_LEFT BUTTON_LEFT
208 #define ROCKBLOX_RIGHT BUTTON_RIGHT
209 #define ROCKBLOX_DROP BUTTON_MODE
210 #define ROCKBLOX_RESTART BUTTON_EQ
212 #elif CONFIG_KEYPAD == MROBE500_PAD
213 #define ROCKBLOX_OFF BUTTON_POWER
215 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
216 #define ROCKBLOX_OFF BUTTON_BACK
217 #define ROCKBLOX_ROTATE_RIGHT BUTTON_VOL_DOWN
218 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOL_UP
219 #define ROCKBLOX_ROTATE BUTTON_UP
220 #define ROCKBLOX_DOWN BUTTON_DOWN
221 #define ROCKBLOX_LEFT BUTTON_LEFT
222 #define ROCKBLOX_RIGHT BUTTON_RIGHT
223 #define ROCKBLOX_DROP BUTTON_SELECT
224 #define ROCKBLOX_RESTART BUTTON_PLAY
226 #elif CONFIG_KEYPAD == MROBE100_PAD
228 #define ROCKBLOX_OFF BUTTON_POWER
229 #define ROCKBLOX_ROTATE_RIGHT BUTTON_MENU
230 #define ROCKBLOX_ROTATE_LEFT BUTTON_PLAY
231 #define ROCKBLOX_ROTATE BUTTON_UP
232 #define ROCKBLOX_DOWN BUTTON_DOWN
233 #define ROCKBLOX_LEFT BUTTON_LEFT
234 #define ROCKBLOX_RIGHT BUTTON_RIGHT
235 #define ROCKBLOX_DROP BUTTON_SELECT
236 #define ROCKBLOX_RESTART BUTTON_DISPLAY
238 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
240 #define ROCKBLOX_OFF BUTTON_RC_REC
241 #define ROCKBLOX_ROTATE_RIGHT BUTTON_RC_VOL_DOWN
242 #define ROCKBLOX_ROTATE_LEFT BUTTON_RC_VOL_UP
243 #define ROCKBLOX_DOWN BUTTON_RC_MENU
244 #define ROCKBLOX_LEFT BUTTON_RC_REW
245 #define ROCKBLOX_RIGHT BUTTON_RC_FF
246 #define ROCKBLOX_DROP BUTTON_RC_PLAY
247 #define ROCKBLOX_RESTART BUTTON_RC_MODE
249 #elif CONFIG_KEYPAD == COWOND2_PAD
250 #define ROCKBLOX_OFF BUTTON_POWER
251 #define ROCKBLOX_RESTART BUTTON_MENU
253 #elif CONFIG_KEYPAD == IAUDIO67_PAD
255 #define ROCKBLOX_OFF BUTTON_POWER
256 #define ROCKBLOX_ROTATE_RIGHT BUTTON_VOLDOWN
257 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOLUP
258 #define ROCKBLOX_DOWN BUTTON_STOP
259 #define ROCKBLOX_LEFT BUTTON_LEFT
260 #define ROCKBLOX_RIGHT BUTTON_RIGHT
261 #define ROCKBLOX_DROP BUTTON_PLAY
262 #define ROCKBLOX_RESTART BUTTON_MENU
264 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
265 #define ROCKBLOX_OFF BUTTON_BACK
266 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
267 #define ROCKBLOX_ROTATE_LEFT BUTTON_PLAY
268 #define ROCKBLOX_DOWN BUTTON_DOWN
269 #define ROCKBLOX_LEFT BUTTON_LEFT
270 #define ROCKBLOX_RIGHT BUTTON_RIGHT
271 #define ROCKBLOX_DROP BUTTON_SELECT
272 #define ROCKBLOX_RESTART BUTTON_CUSTOM
274 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
276 #define ROCKBLOX_OFF BUTTON_POWER
277 #define ROCKBLOX_ROTATE_RIGHT BUTTON_VOL_DOWN
278 #define ROCKBLOX_ROTATE_LEFT BUTTON_VOL_UP
279 #define ROCKBLOX_ROTATE BUTTON_UP
280 #define ROCKBLOX_DOWN BUTTON_DOWN
281 #define ROCKBLOX_LEFT BUTTON_LEFT
282 #define ROCKBLOX_RIGHT BUTTON_RIGHT
283 #define ROCKBLOX_DROP BUTTON_SELECT
284 #define ROCKBLOX_RESTART BUTTON_MENU
286 #elif CONFIG_KEYPAD == ONDAVX747_PAD
287 #define ROCKBLOX_OFF BUTTON_POWER
288 #define ROCKBLOX_RESTART BUTTON_MENU
290 #else
291 #error No keymap defined!
292 #endif
294 #ifdef HAVE_TOUCHSCREEN
295 #ifndef ROCKBLOX_OFF
296 #define ROCKBLOX_OFF BUTTON_TOPLEFT
297 #endif
298 #ifndef ROCKBLOX_ROTATE_RIGHT
299 #define ROCKBLOX_ROTATE_RIGHT BUTTON_BOTTOMRIGHT
300 #endif
301 #ifndef ROCKBLOX_ROTATE_LEFT
302 #define ROCKBLOX_ROTATE_LEFT BUTTON_BOTTOMLEFT
303 #endif
304 #ifndef ROCKBLOX_DOWN
305 #define ROCKBLOX_DOWN BUTTON_BOTTOMMIDDLE
306 #endif
307 #ifndef ROCKBLOX_LEFT
308 #define ROCKBLOX_LEFT BUTTON_MIDLEFT
309 #endif
310 #ifndef ROCKBLOX_RIGHT
311 #define ROCKBLOX_RIGHT BUTTON_MIDRIGHT
312 #endif
313 #ifndef ROCKBLOX_DROP
314 #define ROCKBLOX_DROP BUTTON_CENTER
315 #endif
316 #ifndef ROCKBLOX_RESTART
317 #define ROCKBLOX_RESTART BUTTON_TOPRIGHT
318 #endif
319 #endif
321 #define BLOCKS_NUM 7
322 #define EMPTY_BLOCK 7
324 #define BOARD_WIDTH 10
326 #ifdef HAVE_LCD_BITMAP
328 #define BOARD_HEIGHT 20
330 #if (LCD_WIDTH == 640) && (LCD_HEIGHT == 480)
332 #define BLOCK_WIDTH 30
333 #define BLOCK_HEIGHT 30
334 #define BOARD_X 14
335 #define BOARD_Y 2
336 #define PREVIEW_X 342
337 #define PREVIEW_Y 482
338 #define LABEL_X 344
339 #define SCORE_Y 58
340 #define LEVEL_Y 142
341 #define LINES_Y 218
342 #define HIGH_LABEL_X 344
343 #define HIGH_SCORE_Y 326
344 #define HIGH_LEVEL_Y 344
346 #elif (LCD_WIDTH == 480) && (LCD_HEIGHT == 640)
348 #define BLOCK_WIDTH 30
349 #define BLOCK_HEIGHT 30
350 #define BOARD_X 14
351 #define BOARD_Y 2
352 #define PREVIEW_X 342
353 #define PREVIEW_Y 482
354 #define LABEL_X 344
355 #define SCORE_Y 58
356 #define LEVEL_Y 142
357 #define LINES_Y 218
358 #define HIGH_LABEL_X 344
359 #define HIGH_SCORE_Y 326
360 #define HIGH_LEVEL_Y 344
362 #elif (LCD_WIDTH == 320) && (LCD_HEIGHT == 240)
364 #define BLOCK_WIDTH 12
365 #define BLOCK_HEIGHT 12
366 #define BOARD_X 86
367 #define BOARD_Y 0
368 #define PREVIEW_X 12
369 #define PREVIEW_Y 11
370 #define LABEL_X 242
371 #define SCORE_Y 25
372 #define LEVEL_Y 70
373 #define LINES_Y 105
375 #elif (LCD_WIDTH == 240) && ((LCD_HEIGHT == 320) || (LCD_HEIGHT == 400))
377 #define BLOCK_WIDTH 15
378 #define BLOCK_HEIGHT 15
379 #define BOARD_X 7
380 #define BOARD_Y 1
381 #define PREVIEW_X 171
382 #define PREVIEW_Y 241
383 #define LABEL_X 172
384 #define SCORE_Y 29
385 #define LEVEL_Y 71
386 #define LINES_Y 109
387 #define HIGH_LABEL_X 172
388 #define HIGH_SCORE_Y 163
389 #define HIGH_LEVEL_Y 172
391 #elif (LCD_WIDTH == 220) && (LCD_HEIGHT == 176)
393 #define BLOCK_WIDTH 8
394 #define BLOCK_HEIGHT 8
395 #define BOARD_X 27
396 #define BOARD_Y 5
397 #define PREVIEW_X 158
398 #define PREVIEW_Y 130
399 #define LABEL_X 147
400 #define SCORE_Y 20
401 #define LEVEL_Y 65
402 #define LINES_Y 100
404 #elif (LCD_WIDTH == 176) && (LCD_HEIGHT == 132)
406 #define BLOCK_WIDTH 6
407 #define BLOCK_HEIGHT 6
408 #define BOARD_X 25
409 #define BOARD_Y 1
410 #define PREVIEW_X 126
411 #define PREVIEW_Y 102
412 #define LABEL_X 112
413 #define SCORE_Y 17
414 #define LEVEL_Y 49
415 #define LINES_Y 81
417 #elif (LCD_WIDTH == 176) && (LCD_HEIGHT == 220)
419 /* no room for the space in the highscore list */
420 #define _SPACE ""
422 #define BLOCK_WIDTH 10
423 #define BLOCK_HEIGHT 10
424 #define BOARD_X 6
425 #define BOARD_Y 10
426 #define PREVIEW_X 124
427 #define PREVIEW_Y 174
428 #define LABEL_X 117
429 #define SCORE_Y 18
430 #define LEVEL_Y 52
431 #define LINES_Y 85
432 #define HIGH_SCORE_Y 119
433 #define HIGH_LEVEL_Y 126
434 #define HIGH_LABEL_X 114
436 #elif (LCD_WIDTH == 160) && (LCD_HEIGHT == 128)
439 #define BLOCK_WIDTH 6
440 #define BLOCK_HEIGHT 6
441 #define BOARD_X 22
442 #define BOARD_Y 3
443 #define PREVIEW_X 114
444 #define PREVIEW_Y 100
445 #define LABEL_X 101
446 #define SCORE_Y 17
447 #define LEVEL_Y 49
448 #define LINES_Y 82
450 #elif (LCD_WIDTH == 138) && (LCD_HEIGHT == 110)
452 #define BLOCK_WIDTH 5
453 #define BLOCK_HEIGHT 5
454 #define BOARD_X 14
455 #define BOARD_Y 0
456 #define PREVIEW_X 98
457 #define PREVIEW_Y 88
458 #define LABEL_X 80
459 #define SCORE_Y 15
460 #define LEVEL_Y 45
461 #define LINES_Y 74
463 #elif (LCD_WIDTH == 132) && (LCD_HEIGHT == 80)
465 #define BLOCK_WIDTH 4
466 #define BLOCK_HEIGHT 4
467 #define BOARD_X 10
468 #define BOARD_Y 0
469 #define PREVIEW_X 89
470 #define PREVIEW_Y 61
471 #define LABEL_X 78
472 #define SCORE_Y 10
473 #define LEVEL_Y 30
474 #define LINES_Y 50
476 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 128)
478 #define BLOCK_WIDTH 6
479 #define BLOCK_HEIGHT 6
480 #define BOARD_X 4
481 #define BOARD_Y 3
482 #define PREVIEW_X 84
483 #define PREVIEW_Y 100
484 #define LABEL_X 71
485 #define SCORE_Y 17
486 #define LEVEL_Y 49
487 #define LINES_Y 82
489 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 96)
491 #define BLOCK_WIDTH 4
492 #define BLOCK_HEIGHT 4
493 #define BOARD_X 14
494 #define BOARD_Y 2
495 #define PREVIEW_X 89
496 #define PREVIEW_Y 76
497 #define LABEL_X 70
498 #define SCORE_Y 14
499 #define LEVEL_Y 39
500 #define LINES_Y 64
502 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 64)
504 #define BLOCK_WIDTH 3
505 #define BLOCK_HEIGHT 3
506 #define BOARD_X 9
507 #define BOARD_Y 3
508 #define PREVIEW_X 53
509 #define PREVIEW_Y 5
510 #define LABEL_X 70
511 #define SCORE_Y 32
512 #define LEVEL_Y 13
513 #define LINES_Y 51
515 #elif (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
517 #define BLOCK_WIDTH 4
518 #define BLOCK_HEIGHT 3
519 #define BOARD_X 9
520 #define BOARD_Y 3
521 #define PREVIEW_X 59
522 #define PREVIEW_Y 5
523 #define LABEL_X 59
524 #define SCORE_Y 32
525 #define LEVEL_Y 13
526 #define LEVEL_X 78
527 #define LINES_Y 51
529 #endif
531 #ifndef LEVEL_X
532 #define LEVEL_X LABEL_X
533 #endif
535 #ifndef LINES_X
536 #define LINES_X LABEL_X
537 #endif
539 #define MYLCD(fn) rb->lcd_ ## fn
541 extern const fb_data rockblox_background[];
543 #else /* HAVE_LCD_CHARCELLS */
545 #define BOARD_HEIGHT 14
547 #define BLOCK_WIDTH 1
548 #define BLOCK_HEIGHT 1
549 #define BOARD_X 5
550 #define BOARD_Y 0
551 #define PREVIEW_X 15
552 #define PREVIEW_Y 1
554 #define MYLCD(fn) pgfx_ ## fn
556 #endif
558 #ifndef _SPACE
559 #define _SPACE " "
560 #endif
561 /* <<Explanation on Rockblox shapes>>
564 %% - O has 1 orientation
566 %% %
567 %% %% - Z has 2 orientations
570 %% %
571 %% %% - S has 2 orientations
575 % %%%% - I has 2 orientations
578 % %%
579 % % % %%% - L has 4 orientations
580 %% %%% % %
582 % %%
583 % % % %%% - J has 4 orientations
584 %% %%% % %
586 % % %%%
587 %% % %% % - T has 4 orientations
588 % %%% %
591 /* c=current f=figure o=orientation n=next */
592 static struct _rockblox_status
594 int gameover;
595 int lines;
596 int level;
597 int score;
598 int cx;
599 int cy;
600 int cf;
601 int co;
602 int nf;
603 short board[BOARD_HEIGHT][BOARD_WIDTH]; /* 20 rows of 10 blocks */
604 } rockblox_status;
606 /* prototypes */
607 static void draw_next_block(void);
608 static void new_block(void);
610 #ifdef HAVE_SCROLLWHEEL
611 int wheel_events = 0, last_wheel_event = 0;
612 bool wheel_enabled = false;
613 #endif
615 static const short scoring[4] = { /* scoring for each number of lines */
616 #if BOARD_HEIGHT == 20
617 40 /* single */ , 100 /* double */ , 300 /* triple */ , 1200 /* rockblox */
618 #elif BOARD_HEIGHT == 14 /* Player special values */
619 60 /* single */ , 150 /* double */ , 500 /* triple */ , 2000 /* rockblox */
620 #endif
623 struct figure
625 #if LCD_DEPTH >= 2
626 unsigned short color[3]; /* color of figure (light,middle,shadow) */
627 #endif
628 unsigned short max_or; /* max orientations */
629 signed short shapeX[4], shapeY[4]; /* implementation of figures */
632 /* array of figures */
633 figures[BLOCKS_NUM] = {
634 /* O */
636 #if LCD_DEPTH >= 16
637 {LCD_RGBPACK (153, 255, 255), LCD_RGBPACK(0, 255, 255),
638 LCD_RGBPACK(0,153,153)},
639 #elif LCD_DEPTH == 2
640 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
641 #endif
643 {-1, 0, -1, 0},
644 {0, 0, 1, 1}
646 /* I */
648 #if LCD_DEPTH >= 16
649 {LCD_RGBPACK (255, 153, 128), LCD_RGBPACK (255, 0, 0),
650 LCD_RGBPACK (153, 0, 0)},
651 #elif LCD_DEPTH == 2
652 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
653 #endif
655 {-2, -1, 0, 1},
656 {0, 0, 0, 0}
658 /* 'Z' */
660 #if LCD_DEPTH >= 16
661 {LCD_RGBPACK (153, 255, 153), LCD_RGBPACK (0, 255, 0),
662 LCD_RGBPACK (0, 153, 0)},
663 #elif LCD_DEPTH == 2
664 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
665 #endif
667 {0, 1, -1, 0},
668 {0, 0, 1, 1}
670 /* 'S' */
672 #if LCD_DEPTH >= 16
673 {LCD_RGBPACK (153, 153, 255), LCD_RGBPACK (0, 0, 255),
674 LCD_RGBPACK (0, 0, 153)},
675 #elif LCD_DEPTH == 2
676 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
677 #endif
679 {-1, 0, 0, 1},
680 {0, 0, 1, 1}
682 /* 'L' */
684 #if LCD_DEPTH >= 16
685 {LCD_RGBPACK (255, 255, 153), LCD_RGBPACK (255, 255, 0),
686 LCD_RGBPACK (153, 153, 0)},
687 #elif LCD_DEPTH == 2
688 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
689 #endif
691 {-1, 0, 1, 1},
692 {0, 0, 0, 1}
694 /* 'J' */
696 #if LCD_DEPTH >= 16
697 {LCD_RGBPACK (255, 153, 255), LCD_RGBPACK (255, 0, 255),
698 LCD_RGBPACK (153, 0, 153)},
699 #elif LCD_DEPTH == 2
700 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
701 #endif
703 {-1, 0, 1, -1},
704 {0, 0, 0, 1}
706 /* 'T' */
708 #if LCD_DEPTH >= 16
709 {LCD_RGBPACK (204, 204, 204), LCD_RGBPACK (153, 153, 153),
710 LCD_RGBPACK (85, 85, 85)},
711 #elif LCD_DEPTH == 2
712 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
713 #endif
715 {-1, 0, 1, 0},
716 {0, 0, 0, 1}
720 /* Rockbox File System only supports full filenames inc dir */
721 #define HIGH_SCORE PLUGIN_GAMES_DIR "/rockblox.score"
722 #define RESUME_FILE PLUGIN_GAMES_DIR "/rockblox.resume"
723 #define MAX_HIGH_SCORES 5
725 /* Default High Scores... */
726 struct highscore Highest[MAX_HIGH_SCORES];
728 /* get random number from (0) to (range-1) */
729 static int t_rand (int range)
731 return rb->rand () % range;
734 static inline void show_game_over (void)
736 rb->splash(HZ,"Game over!");
739 /* init the board array to have no blocks */
740 static void init_board (void)
742 int i, j;
743 for (i = 0; i < BOARD_WIDTH; i++)
744 for (j = 0; j < BOARD_HEIGHT; j++)
745 rockblox_status.board[j][i] = EMPTY_BLOCK;
748 /* show the score, level and lines */
749 static void show_details (void)
751 char str[25]; /* for strings */
753 #ifdef HAVE_LCD_BITMAP
754 #if LCD_DEPTH >= 2
755 rb->lcd_set_foreground (LCD_BLACK);
756 rb->lcd_set_background (LCD_WHITE);
757 #endif
758 rb->snprintf (str, sizeof (str), "%d", rockblox_status.score);
759 rb->lcd_putsxy (LABEL_X, SCORE_Y, str);
760 rb->snprintf (str, sizeof (str), "%d", rockblox_status.level);
761 rb->lcd_putsxy (LEVEL_X, LEVEL_Y, str);
762 rb->snprintf (str, sizeof (str), "%d", rockblox_status.lines);
763 rb->lcd_putsxy (LINES_X, LINES_Y, str);
764 #else /* HAVE_LCD_CHARCELLS */
765 rb->snprintf (str, sizeof (str), "L%d/%d", rockblox_status.level,
766 rockblox_status.lines);
767 rb->lcd_puts (5, 0, str);
768 rb->snprintf (str, sizeof (str), "S%d", rockblox_status.score);
769 rb->lcd_puts (5, 1, str);
770 #endif
773 #ifdef HIGH_SCORE_Y
774 static void show_highscores (void)
776 int i;
777 char str[25]; /* for strings */
779 for (i = MAX_HIGH_SCORES-1; i>=0; i--)
781 rb->snprintf (str, sizeof (str), "%06d" _SPACE "L%1d",Highest[i].score, Highest[i].level);
782 rb->lcd_putsxy (HIGH_LABEL_X, HIGH_SCORE_Y + (10 * ((MAX_HIGH_SCORES-1) - i)), str);
785 #endif
787 /* Returns >0 on successful read AND if the game wasn't over, else 0 */
788 static int load_resume(void)
790 int fd;
791 fd = rb->open(RESUME_FILE, O_RDONLY);
792 if (fd < 0)
793 return 0;
795 if (rb->read(fd, &rockblox_status, sizeof(struct _rockblox_status))
796 < (ssize_t)sizeof(struct _rockblox_status))
798 rb->splash(HZ/2, "Loading Rockblox resume info failed");
799 return 0;
802 rb->close(fd);
804 if (rockblox_status.gameover)
805 show_game_over();
807 return !rockblox_status.gameover;
810 /* Returns >0 on success, else 0 */
811 static int dump_resume(void)
813 int fd;
815 fd = rb->open(RESUME_FILE, O_WRONLY|O_CREAT);
816 if (fd < 0)
817 goto fail;
819 if (rb->write(fd, &rockblox_status, sizeof(struct _rockblox_status))
820 <= 0)
822 rb->close(fd);
823 goto fail;
825 rb->close(fd);
826 return 1;
828 fail:
829 rb->splash(HZ/2, "Writing Rockblox resume info failed");
830 return 0;
832 static void init_rockblox (bool resume)
834 highscore_update(rockblox_status.score, rockblox_status.level, Highest,
835 MAX_HIGH_SCORES);
836 #ifdef HAVE_LCD_BITMAP
837 rb->lcd_bitmap (rockblox_background, 0, 0, LCD_WIDTH, LCD_HEIGHT);
838 #else /* HAVE_LCD_CHARCELLS */
839 pgfx_display (0, 0);
840 pgfx_display_block (3, 0, 3, 1);
841 pgfx_display_block (4, 0, 3, 0);
842 pgfx_clear_display();
843 pgfx_fillrect (3, 0, 2, 14);
844 pgfx_fillrect (15, 7, 2, 7);
845 pgfx_update();
846 #endif
847 if (!resume || !load_resume())
849 rockblox_status.level = 1;
850 rockblox_status.lines = 0;
851 rockblox_status.score = 0;
852 rockblox_status.nf = t_rand(BLOCKS_NUM);
853 init_board ();
854 new_block ();
856 draw_next_block();
858 show_details ();
859 #ifdef HIGH_SCORE_Y
860 show_highscores ();
861 #endif
864 static inline int level_speed(int level)
866 #if BOARD_HEIGHT == 20
867 return (5*HZ) / (level + 9);
868 #elif BOARD_HEIGHT == 14
869 return (7*HZ) / (level + 9);
870 #endif
873 static int getRelativeX (int figure, int square, int orientation)
875 switch (orientation) {
876 case 0:
877 return figures[figure].shapeX[square];
878 case 1:
879 return figures[figure].shapeY[square];
880 case 2:
881 return -figures[figure].shapeX[square];
882 case 3:
883 return -figures[figure].shapeY[square];
884 default:
885 return 0;
889 static int getRelativeY (int figure, int square, int orientation)
891 switch (orientation) {
892 case 0:
893 return figures[figure].shapeY[square];
894 case 1:
895 return -figures[figure].shapeX[square];
896 case 2:
897 return -figures[figure].shapeY[square];
898 case 3:
899 return figures[figure].shapeX[square];
900 default:
901 return 0;
905 /* redraw the while board on the screen */
906 static void refresh_board (void)
908 int i, j, x, y, block;
910 #if LCD_DEPTH >= 2
911 rb->lcd_set_foreground (LCD_BLACK);
912 #elif LCD_DEPTH == 1
913 MYLCD(set_drawmode) (DRMODE_SOLID | DRMODE_INVERSEVID);
914 #endif
916 MYLCD(fillrect) (BOARD_X, BOARD_Y, BOARD_WIDTH * BLOCK_WIDTH,
917 BOARD_HEIGHT * BLOCK_HEIGHT);
919 #if LCD_DEPTH == 1
920 MYLCD(set_drawmode) (DRMODE_SOLID);
921 #endif
923 for (i = 0; i < BOARD_WIDTH; i++)
924 for (j = 0; j < BOARD_HEIGHT; j++) {
925 block = rockblox_status.board[j][i];
926 if (block != EMPTY_BLOCK) {
927 #ifdef HAVE_LCD_BITMAP
928 #if LCD_DEPTH >= 2
929 /* middle drawing */
930 rb->lcd_set_foreground (figures[block].color[1]);
931 #endif
932 rb->lcd_fillrect (BOARD_X + i * BLOCK_WIDTH,
933 BOARD_Y + j * BLOCK_HEIGHT,
934 BLOCK_WIDTH, BLOCK_HEIGHT);
935 #if LCD_DEPTH >= 2
936 /* light drawing */
937 rb->lcd_set_foreground (figures[block].color[0]);
938 #endif
939 rb->lcd_vline (BOARD_X + i * BLOCK_WIDTH,
940 BOARD_Y + j * BLOCK_HEIGHT,
941 BOARD_Y + (j + 1) * BLOCK_HEIGHT - 2);
942 rb->lcd_hline (BOARD_X + i * BLOCK_WIDTH,
943 BOARD_X + (i + 1) * BLOCK_WIDTH - 2,
944 BOARD_Y + j * BLOCK_HEIGHT);
945 #if LCD_DEPTH >= 2
946 /* shadow drawing */
947 rb->lcd_set_foreground (figures[block].color[2]);
948 #endif
949 rb->lcd_vline (BOARD_X + (i + 1) * BLOCK_WIDTH - 1,
950 BOARD_Y + j * BLOCK_HEIGHT + 1,
951 BOARD_Y + (j + 1) * BLOCK_HEIGHT - 1);
952 rb->lcd_hline (BOARD_X + i * BLOCK_WIDTH + 1,
953 BOARD_X + (i + 1) * BLOCK_WIDTH - 1,
954 BOARD_Y + (j + 1) * BLOCK_HEIGHT - 1);
955 #else /* HAVE_LCD_CHARCELLS */
956 pgfx_drawpixel (BOARD_X + i, BOARD_Y + j);
957 #endif
961 for (i = 0; i < 4; i++) {
962 x = getRelativeX (rockblox_status.cf, i, rockblox_status.co)
963 + rockblox_status.cx;
964 y = getRelativeY (rockblox_status.cf, i, rockblox_status.co)
965 + rockblox_status.cy;
966 #ifdef HAVE_LCD_BITMAP
967 #if LCD_DEPTH >= 2
968 /* middle drawing */
969 rb->lcd_set_foreground (figures[rockblox_status.cf].color[1]);
970 #endif
971 rb->lcd_fillrect (BOARD_X + x * BLOCK_WIDTH,
972 BOARD_Y + y * BLOCK_HEIGHT,
973 BLOCK_WIDTH, BLOCK_HEIGHT);
974 #if LCD_DEPTH >= 2
975 /* light drawing */
976 rb->lcd_set_foreground (figures[rockblox_status.cf].color[0]);
977 #endif
978 rb->lcd_vline (BOARD_X + x * BLOCK_WIDTH, BOARD_Y + y * BLOCK_HEIGHT,
979 BOARD_Y + (y + 1) * BLOCK_HEIGHT - 2);
980 rb->lcd_hline (BOARD_X + x * BLOCK_WIDTH,
981 BOARD_X + (x + 1) * BLOCK_WIDTH - 2,
982 BOARD_Y + y * BLOCK_HEIGHT);
983 #if LCD_DEPTH >= 2
984 /* shadow drawing */
985 rb->lcd_set_foreground (figures[rockblox_status.cf].color[2]);
986 #endif
987 rb->lcd_vline (BOARD_X + (x + 1) * BLOCK_WIDTH - 1,
988 BOARD_Y + y * BLOCK_HEIGHT + 1,
989 BOARD_Y + (y + 1) * BLOCK_HEIGHT - 1);
990 rb->lcd_hline (BOARD_X + x * BLOCK_WIDTH + 1,
991 BOARD_X + (x + 1) * BLOCK_WIDTH - 1,
992 BOARD_Y + (y + 1) * BLOCK_HEIGHT - 1);
993 #else /* HAVE_LCD_CHARCELLS */
994 pgfx_drawpixel (BOARD_X + x, BOARD_Y + y);
995 #endif
997 MYLCD(update) ();
1000 static bool canMoveTo (int x, int y, int newOrientation)
1002 int i, rx, ry;
1003 for (i = 0; i < 4; i++) {
1004 ry = getRelativeY (rockblox_status.cf, i, newOrientation) + y;
1005 rx = getRelativeX (rockblox_status.cf, i, newOrientation) + x;
1006 if ((rx < 0 || rx >= BOARD_WIDTH) ||
1007 (ry < 0 || ry >= BOARD_HEIGHT) ||
1008 (rockblox_status.board[ry][rx] != EMPTY_BLOCK))
1009 return false;
1011 return true;
1014 /* draws the preview of next block in the preview window */
1015 static void draw_next_block (void)
1017 int i, rx, ry;
1018 /* clear preview window first */
1019 #if LCD_DEPTH >= 2
1020 rb->lcd_set_foreground (LCD_BLACK);
1021 #elif LCD_DEPTH == 1
1022 MYLCD(set_drawmode) (DRMODE_SOLID | DRMODE_INVERSEVID);
1023 #endif
1025 /* 4x4 */
1026 MYLCD(fillrect) (PREVIEW_X, PREVIEW_Y, BLOCK_WIDTH * 4, BLOCK_HEIGHT * 4);
1028 #if LCD_DEPTH == 1
1029 MYLCD(set_drawmode) (DRMODE_SOLID);
1030 #endif
1032 /* draw the lightgray rectangles */
1033 #if LCD_DEPTH >= 16
1034 rb->lcd_set_foreground (LCD_RGBPACK (40, 40, 40));
1035 #elif LCD_DEPTH == 2
1036 rb->lcd_set_foreground (LCD_DARKGRAY);
1037 #endif
1039 #if LCD_DEPTH >= 2
1040 for (rx = 0; rx < 4; rx++)
1041 for (ry = 0; ry < 4; ry++)
1042 rb->lcd_drawrect (PREVIEW_X + rx * BLOCK_WIDTH,
1043 PREVIEW_Y + ry * BLOCK_HEIGHT, BLOCK_WIDTH,
1044 BLOCK_HEIGHT);
1045 #endif
1047 /* draw the figure */
1048 for (i = 0; i < 4; i++) {
1049 rx = getRelativeX (rockblox_status.nf, i, 0) + 2;
1050 ry = getRelativeY (rockblox_status.nf, i, 0) + 2;
1051 #ifdef HAVE_LCD_BITMAP
1052 #if LCD_DEPTH >= 2
1053 rb->lcd_set_foreground (figures[rockblox_status.nf].color[1]); /* middle drawing */
1054 #endif
1055 rb->lcd_fillrect (PREVIEW_X + rx * BLOCK_WIDTH,
1056 PREVIEW_Y + ry * BLOCK_HEIGHT,
1057 BLOCK_WIDTH, BLOCK_HEIGHT);
1058 #if LCD_DEPTH >= 2
1059 rb->lcd_set_foreground (figures[rockblox_status.nf].color[0]); /* light drawing */
1060 #endif
1061 rb->lcd_vline (PREVIEW_X + rx * BLOCK_WIDTH,
1062 PREVIEW_Y + ry * BLOCK_HEIGHT,
1063 PREVIEW_Y + (ry + 1) * BLOCK_HEIGHT - 2);
1064 rb->lcd_hline (PREVIEW_X + rx * BLOCK_WIDTH,
1065 PREVIEW_X + (rx + 1) * BLOCK_WIDTH - 2,
1066 PREVIEW_Y + ry * BLOCK_HEIGHT);
1067 #if LCD_DEPTH >= 2
1068 rb->lcd_set_foreground (figures[rockblox_status.nf].color[2]); /* shadow drawing */
1069 #endif
1070 rb->lcd_vline (PREVIEW_X + (rx + 1) * BLOCK_WIDTH - 1,
1071 PREVIEW_Y + ry * BLOCK_HEIGHT + 1,
1072 PREVIEW_Y + (ry + 1) * BLOCK_HEIGHT - 1);
1073 rb->lcd_hline (PREVIEW_X + rx * BLOCK_WIDTH + 1,
1074 PREVIEW_X + (rx + 1) * BLOCK_WIDTH - 1,
1075 PREVIEW_Y + (ry + 1) * BLOCK_HEIGHT - 1);
1076 #else /* HAVE_LCD_CHARCELLS */
1077 pgfx_drawpixel (PREVIEW_X + rx, PREVIEW_Y + ry);
1078 #endif
1083 /* move the block to a relative location */
1084 static void move_block (int x, int y, int o)
1086 if (canMoveTo (rockblox_status.cx + x, rockblox_status.cy + y, o)) {
1087 rockblox_status.cy += y;
1088 rockblox_status.cx += x;
1089 rockblox_status.co = o;
1093 /* try to add a new block to play with (return true if gameover) */
1094 static void new_block (void)
1096 rockblox_status.cy = 1;
1097 rockblox_status.cx = 5;
1098 rockblox_status.cf = rockblox_status.nf;
1099 rockblox_status.co = 0; /* start at the same orientation all time */
1100 rockblox_status.nf = t_rand (BLOCKS_NUM);
1101 rockblox_status.gameover = !canMoveTo (rockblox_status.cx,
1102 rockblox_status.cy, rockblox_status.co);
1104 draw_next_block ();
1108 /* check for filled rockblox_status.lines and do what necessary */
1109 static int check_lines (void)
1112 int i, j, y;
1113 int rockblox = 0;
1115 for (j = 0; j < BOARD_HEIGHT; j++) {
1116 for (i = 0; ((i < BOARD_WIDTH) &&
1117 (rockblox_status.board[j][i] != EMPTY_BLOCK)); i++);
1118 if (i == BOARD_WIDTH) { /* woo hoo, we have a line */
1119 rockblox++;
1120 for (y = j; y > 0; y--)
1122 for (i = 0; i < BOARD_WIDTH; i++)
1123 { /* fall line */
1124 rockblox_status.board[y][i] = rockblox_status.board[y - 1][i];
1130 return rockblox;
1133 /* moves down the figure and returns true if gameover */
1134 static void move_down (void)
1136 int l, i, rx, ry;
1138 if (!canMoveTo (rockblox_status.cx, rockblox_status.cy + 1, rockblox_status.co)) {
1139 /* save figure to board */
1140 for (i = 0; i < 4; i++) {
1141 rx = getRelativeX (rockblox_status.cf, i, rockblox_status.co) + rockblox_status.cx;
1142 ry = getRelativeY (rockblox_status.cf, i, rockblox_status.co) + rockblox_status.cy;
1143 rockblox_status.board[ry][rx] = rockblox_status.cf;
1145 /* check if formed some lines */
1146 l = check_lines ();
1147 if (l) {
1148 /* the original scoring from "http://en.wikipedia.org/wiki/Rockblox" */
1149 rockblox_status.score += scoring[l - 1] * rockblox_status.level;
1150 rockblox_status.lines += l;
1151 rockblox_status.level = (int) rockblox_status.lines / 10 + 1;
1154 /* show details */
1155 show_details ();
1157 /* generate a new figure */
1158 new_block ();
1159 } else
1160 move_block (0, 1, rockblox_status.co);
1163 static int rockblox_loop (void)
1165 int button;
1166 int lastbutton = BUTTON_NONE;
1167 long next_down_tick = *rb->current_tick + level_speed(rockblox_status.level);
1169 while (1) {
1170 #ifdef HAS_BUTTON_HOLD
1171 if (rb->button_hold ()) {
1172 /* Turn on backlight timeout (revert to settings) */
1173 backlight_use_settings(); /* backlight control in lib/helper.c */
1174 rb->splash(0, "Paused");
1175 while (rb->button_hold ())
1176 rb->sleep(HZ/10);
1178 /* Turn off backlight timeout */
1179 backlight_force_on(); /* backlight control in lib/helper.c */
1181 /* get rid of the splash text */
1182 rb->lcd_bitmap (rockblox_background, 0, 0, LCD_WIDTH, LCD_HEIGHT);
1183 show_details ();
1184 #ifdef HIGH_SCORE_Y
1185 show_highscores ();
1186 #endif
1187 draw_next_block ();
1188 refresh_board ();
1190 #endif
1192 button = rb->button_get_w_tmo (MAX(next_down_tick - *rb->current_tick, 1));
1193 switch (button) {
1194 #ifdef ROCKBLOX_RC_OFF
1195 case ROCKBLOX_RC_OFF:
1196 #endif
1197 case ROCKBLOX_OFF:
1198 #ifdef ROCKBLOX_OFF_PRE
1199 if (lastbutton != ROCKBLOX_OFF_PRE)
1200 break;
1201 #endif
1202 return PLUGIN_OK;
1204 #if defined(ROCKBLOX_ROTATE)
1205 case ROCKBLOX_ROTATE:
1206 #endif
1207 case ROCKBLOX_ROTATE_RIGHT:
1208 case ROCKBLOX_ROTATE_RIGHT | BUTTON_REPEAT:
1209 #ifdef HAVE_SCROLLWHEEL
1210 /* if the wheel is disabled, add an event to the stack. */
1211 if(wheel_enabled == false)
1212 wheel_events++;
1214 /* if it's enabled, go ahead and rotate.. */
1215 if(wheel_enabled)
1216 #endif
1217 move_block (0, 0, (rockblox_status.co + 1) % figures[rockblox_status.cf].max_or);
1218 break;
1220 case ROCKBLOX_ROTATE_LEFT:
1221 case ROCKBLOX_ROTATE_LEFT | BUTTON_REPEAT:
1222 #ifdef HAVE_SCROLLWHEEL
1223 if(wheel_enabled == false)
1224 wheel_events++;
1226 if(wheel_enabled)
1227 #endif
1228 move_block (0, 0,
1229 (rockblox_status.co + figures[rockblox_status.cf].max_or -
1230 1) % figures[rockblox_status.cf].max_or);
1231 break;
1233 #ifdef ROCKBLOX_ROTATE_RIGHT2
1234 case ROCKBLOX_ROTATE_RIGHT2:
1235 move_block (0, 0, (rockblox_status.co + 1) % figures[rockblox_status.cf].max_or);
1236 break;
1237 #endif
1239 case ROCKBLOX_DOWN:
1240 case ROCKBLOX_DOWN | BUTTON_REPEAT:
1241 move_block (0, 1, rockblox_status.co);
1242 break;
1244 case ROCKBLOX_RIGHT:
1245 case ROCKBLOX_RIGHT | BUTTON_REPEAT:
1246 move_block (1, 0, rockblox_status.co);
1247 break;
1249 case ROCKBLOX_LEFT:
1250 case ROCKBLOX_LEFT | BUTTON_REPEAT:
1251 move_block (-1, 0, rockblox_status.co);
1252 break;
1254 case ROCKBLOX_DROP:
1255 #ifdef ROCKBLOX_DROP_PRE
1256 if (lastbutton != ROCKBLOX_DROP_PRE)
1257 break;
1258 #endif
1259 while (canMoveTo (rockblox_status.cx, rockblox_status.cy + 1, rockblox_status.co))
1260 move_block (0, 1, rockblox_status.co);
1261 break;
1262 #ifdef ROCKBLOX_RESTART
1263 case ROCKBLOX_RESTART:
1264 rb->splash (HZ * 1, "Restarting...");
1265 init_rockblox (false);
1266 break;
1267 #endif
1269 default:
1270 if (rb->default_event_handler (button) == SYS_USB_CONNECTED)
1271 return PLUGIN_USB_CONNECTED;
1272 break;
1274 if (button != BUTTON_NONE)
1275 lastbutton = button;
1277 #ifdef HAVE_SCROLLWHEEL
1278 /* check if we should enable the scroll wheel, if events
1279 * begin to stack up... */
1280 if(wheel_enabled == false)
1282 /* stopped rotating the wheel, reset the count */
1283 if(wheel_events == last_wheel_event)
1285 last_wheel_event = 0;
1286 wheel_events = 0;
1288 /* rotated the wheel a while constantly, enable it. */
1289 else if(wheel_events > 3)
1291 wheel_enabled = true;
1294 /* this evens out the last event and the "current" event.
1295 * if we get an event next time through button reading, it will
1296 * remain ahead of last_event. if we don't, they'll end up equaling
1297 * each other.. thus, the scroll count will be reset. */
1298 if(wheel_enabled == false && wheel_events > last_wheel_event)
1299 last_wheel_event++;
1301 #endif
1303 if (TIME_AFTER(*rb->current_tick, next_down_tick)) {
1304 move_down ();
1305 next_down_tick += level_speed(rockblox_status.level);
1306 if (TIME_AFTER(*rb->current_tick, next_down_tick))
1307 /* restart time "raster" when we had to wait longer than usual
1308 * (pause, game restart etc) */
1309 next_down_tick = *rb->current_tick + level_speed(rockblox_status.level);
1312 if (rockblox_status.gameover) {
1313 #if LCD_DEPTH >= 2
1314 rb->lcd_set_foreground (LCD_BLACK);
1315 #endif
1316 show_game_over();
1317 init_rockblox (false);
1320 refresh_board ();
1323 return PLUGIN_OK;
1326 enum plugin_status plugin_start (const void *parameter)
1328 int ret;
1330 (void) parameter;
1332 rb->srand (*rb->current_tick);
1334 /* Load HighScore if any */
1335 highscore_load(HIGH_SCORE,Highest,MAX_HIGH_SCORES);
1337 #if LCD_DEPTH > 1
1338 rb->lcd_set_backdrop(NULL);
1339 #endif
1341 #ifdef HAVE_LCD_BITMAP
1342 rb->lcd_setfont (FONT_SYSFIXED);
1343 #else
1344 if (!pgfx_init(4, 2))
1346 rb->splash(HZ*2, "Old LCD :(");
1347 return PLUGIN_OK;
1349 #endif
1350 /* Turn off backlight timeout */
1351 backlight_force_on(); /* backlight control in lib/helper.c */
1353 init_rockblox (true);
1354 ret = rockblox_loop ();
1356 #ifndef HAVE_LCD_BITMAP
1357 pgfx_release();
1358 #endif
1359 /* Save user's HighScore */
1360 highscore_save(HIGH_SCORE,Highest,MAX_HIGH_SCORES);
1361 backlight_use_settings(); /* backlight control in lib/helper.c */
1363 dump_resume();
1365 return ret;