* Fix plugin keymaps for VX777
[kugel-rb.git] / apps / plugins / rockblox.c
blob0314a7c5163061add8a85f96a87d1d05ec35ff43
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
289 #elif CONFIG_KEYPAD == ONDAVX777_PAD
290 #define ROCKBLOX_OFF BUTTON_POWER
292 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
294 #define ROCKBLOX_OFF (BUTTON_REC|BUTTON_PLAY)
295 #define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
296 #define ROCKBLOX_ROTATE_LEFT BUTTON_DOWN
297 #define ROCKBLOX_DOWN BUTTON_REW
298 #define ROCKBLOX_LEFT BUTTON_LEFT
299 #define ROCKBLOX_RIGHT BUTTON_RIGHT
300 #define ROCKBLOX_DROP BUTTON_FFWD
301 #define ROCKBLOX_RESTART (BUTTON_REC|BUTTON_REW)
303 #else
304 #error No keymap defined!
305 #endif
307 #ifdef HAVE_TOUCHSCREEN
308 #ifndef ROCKBLOX_OFF
309 #define ROCKBLOX_OFF BUTTON_TOPLEFT
310 #endif
311 #ifndef ROCKBLOX_ROTATE_RIGHT
312 #define ROCKBLOX_ROTATE_RIGHT BUTTON_BOTTOMRIGHT
313 #endif
314 #ifndef ROCKBLOX_ROTATE_LEFT
315 #define ROCKBLOX_ROTATE_LEFT BUTTON_BOTTOMLEFT
316 #endif
317 #ifndef ROCKBLOX_DOWN
318 #define ROCKBLOX_DOWN BUTTON_BOTTOMMIDDLE
319 #endif
320 #ifndef ROCKBLOX_LEFT
321 #define ROCKBLOX_LEFT BUTTON_MIDLEFT
322 #endif
323 #ifndef ROCKBLOX_RIGHT
324 #define ROCKBLOX_RIGHT BUTTON_MIDRIGHT
325 #endif
326 #ifndef ROCKBLOX_DROP
327 #define ROCKBLOX_DROP BUTTON_CENTER
328 #endif
329 #ifndef ROCKBLOX_RESTART
330 #define ROCKBLOX_RESTART BUTTON_TOPRIGHT
331 #endif
332 #endif
334 #define BLOCKS_NUM 7
335 #define EMPTY_BLOCK 7
337 #define BOARD_WIDTH 10
339 #ifdef HAVE_LCD_BITMAP
341 #define BOARD_HEIGHT 20
343 #if (LCD_WIDTH == 640) && (LCD_HEIGHT == 480)
345 #define BLOCK_WIDTH 24
346 #define BLOCK_HEIGHT 24
347 #define BOARD_X 172
348 #define BOARD_Y 0
349 #define PREVIEW_X 24
350 #define PREVIEW_Y 22
351 #define LABEL_X 482
352 #define SCORE_Y 50
353 #define LEVEL_Y 140
354 #define LINES_Y 210
356 #elif (LCD_WIDTH == 480) && (LCD_HEIGHT == 640)
358 #define BLOCK_WIDTH 30
359 #define BLOCK_HEIGHT 30
360 #define BOARD_X 14
361 #define BOARD_Y 2
362 #define PREVIEW_X 342
363 #define PREVIEW_Y 482
364 #define LABEL_X 344
365 #define SCORE_Y 58
366 #define LEVEL_Y 142
367 #define LINES_Y 218
369 #elif (LCD_WIDTH == 320) && (LCD_HEIGHT == 240)
371 #define BLOCK_WIDTH 12
372 #define BLOCK_HEIGHT 12
373 #define BOARD_X 86
374 #define BOARD_Y 0
375 #define PREVIEW_X 12
376 #define PREVIEW_Y 11
377 #define LABEL_X 242
378 #define SCORE_Y 25
379 #define LEVEL_Y 70
380 #define LINES_Y 105
382 #elif (LCD_WIDTH == 240) && ((LCD_HEIGHT == 320) || (LCD_HEIGHT == 400))
384 #define BLOCK_WIDTH 15
385 #define BLOCK_HEIGHT 15
386 #define BOARD_X 7
387 #define BOARD_Y 1
388 #define PREVIEW_X 171
389 #define PREVIEW_Y 241
390 #define LABEL_X 172
391 #define SCORE_Y 29
392 #define LEVEL_Y 71
393 #define LINES_Y 109
394 #define HIGH_LABEL_X 172
395 #define HIGH_SCORE_Y 163
396 #define HIGH_LEVEL_Y 172
398 #elif (LCD_WIDTH == 220) && (LCD_HEIGHT == 176)
400 #define BLOCK_WIDTH 8
401 #define BLOCK_HEIGHT 8
402 #define BOARD_X 27
403 #define BOARD_Y 5
404 #define PREVIEW_X 158
405 #define PREVIEW_Y 130
406 #define LABEL_X 147
407 #define SCORE_Y 20
408 #define LEVEL_Y 65
409 #define LINES_Y 100
411 #elif (LCD_WIDTH == 176) && (LCD_HEIGHT == 132)
413 #define BLOCK_WIDTH 6
414 #define BLOCK_HEIGHT 6
415 #define BOARD_X 25
416 #define BOARD_Y 1
417 #define PREVIEW_X 126
418 #define PREVIEW_Y 102
419 #define LABEL_X 112
420 #define SCORE_Y 17
421 #define LEVEL_Y 49
422 #define LINES_Y 81
424 #elif (LCD_WIDTH == 176) && (LCD_HEIGHT == 220)
426 /* no room for the space in the highscore list */
427 #define _SPACE ""
429 #define BLOCK_WIDTH 10
430 #define BLOCK_HEIGHT 10
431 #define BOARD_X 6
432 #define BOARD_Y 10
433 #define PREVIEW_X 124
434 #define PREVIEW_Y 174
435 #define LABEL_X 117
436 #define SCORE_Y 18
437 #define LEVEL_Y 52
438 #define LINES_Y 85
439 #define HIGH_SCORE_Y 119
440 #define HIGH_LEVEL_Y 126
441 #define HIGH_LABEL_X 114
443 #elif (LCD_WIDTH == 160) && (LCD_HEIGHT == 128)
446 #define BLOCK_WIDTH 6
447 #define BLOCK_HEIGHT 6
448 #define BOARD_X 22
449 #define BOARD_Y 3
450 #define PREVIEW_X 114
451 #define PREVIEW_Y 100
452 #define LABEL_X 101
453 #define SCORE_Y 17
454 #define LEVEL_Y 49
455 #define LINES_Y 82
457 #elif (LCD_WIDTH == 138) && (LCD_HEIGHT == 110)
459 #define BLOCK_WIDTH 5
460 #define BLOCK_HEIGHT 5
461 #define BOARD_X 14
462 #define BOARD_Y 0
463 #define PREVIEW_X 98
464 #define PREVIEW_Y 88
465 #define LABEL_X 80
466 #define SCORE_Y 15
467 #define LEVEL_Y 45
468 #define LINES_Y 74
470 #elif (LCD_WIDTH == 132) && (LCD_HEIGHT == 80)
472 #define BLOCK_WIDTH 4
473 #define BLOCK_HEIGHT 4
474 #define BOARD_X 10
475 #define BOARD_Y 0
476 #define PREVIEW_X 89
477 #define PREVIEW_Y 61
478 #define LABEL_X 78
479 #define SCORE_Y 10
480 #define LEVEL_Y 30
481 #define LINES_Y 50
483 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 128)
485 #define BLOCK_WIDTH 6
486 #define BLOCK_HEIGHT 6
487 #define BOARD_X 4
488 #define BOARD_Y 3
489 #define PREVIEW_X 84
490 #define PREVIEW_Y 100
491 #define LABEL_X 71
492 #define SCORE_Y 17
493 #define LEVEL_Y 49
494 #define LINES_Y 82
496 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 96)
498 #define BLOCK_WIDTH 4
499 #define BLOCK_HEIGHT 4
500 #define BOARD_X 14
501 #define BOARD_Y 2
502 #define PREVIEW_X 89
503 #define PREVIEW_Y 76
504 #define LABEL_X 70
505 #define SCORE_Y 14
506 #define LEVEL_Y 39
507 #define LINES_Y 64
509 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 64)
511 #define BLOCK_WIDTH 3
512 #define BLOCK_HEIGHT 3
513 #define BOARD_X 9
514 #define BOARD_Y 3
515 #define PREVIEW_X 53
516 #define PREVIEW_Y 5
517 #define LABEL_X 70
518 #define SCORE_Y 32
519 #define LEVEL_Y 13
520 #define LINES_Y 51
522 #elif (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
524 #define BLOCK_WIDTH 4
525 #define BLOCK_HEIGHT 3
526 #define BOARD_X 9
527 #define BOARD_Y 3
528 #define PREVIEW_X 59
529 #define PREVIEW_Y 5
530 #define LABEL_X 59
531 #define SCORE_Y 32
532 #define LEVEL_Y 13
533 #define LEVEL_X 78
534 #define LINES_Y 51
536 #endif
538 #ifndef LEVEL_X
539 #define LEVEL_X LABEL_X
540 #endif
542 #ifndef LINES_X
543 #define LINES_X LABEL_X
544 #endif
546 #define MYLCD(fn) rb->lcd_ ## fn
548 extern const fb_data rockblox_background[];
550 #else /* HAVE_LCD_CHARCELLS */
552 #define BOARD_HEIGHT 14
554 #define BLOCK_WIDTH 1
555 #define BLOCK_HEIGHT 1
556 #define BOARD_X 5
557 #define BOARD_Y 0
558 #define PREVIEW_X 15
559 #define PREVIEW_Y 1
561 #define MYLCD(fn) pgfx_ ## fn
563 #endif
565 #ifndef _SPACE
566 #define _SPACE " "
567 #endif
568 /* <<Explanation on Rockblox shapes>>
571 %% - O has 1 orientation
573 %% %
574 %% %% - Z has 2 orientations
577 %% %
578 %% %% - S has 2 orientations
582 % %%%% - I has 2 orientations
585 % %%
586 % % % %%% - L has 4 orientations
587 %% %%% % %
589 % %%
590 % % % %%% - J has 4 orientations
591 %% %%% % %
593 % % %%%
594 %% % %% % - T has 4 orientations
595 % %%% %
598 /* c=current f=figure o=orientation n=next */
599 static struct _rockblox_status
601 int gameover;
602 int lines;
603 int level;
604 int score;
605 int cx;
606 int cy;
607 int cf;
608 int co;
609 int nf;
610 short board[BOARD_HEIGHT][BOARD_WIDTH]; /* 20 rows of 10 blocks */
611 } rockblox_status;
613 /* prototypes */
614 static void draw_next_block(void);
615 static void new_block(void);
617 #ifdef HAVE_SCROLLWHEEL
618 int wheel_events = 0, last_wheel_event = 0;
619 bool wheel_enabled = false;
620 #endif
622 static const short scoring[4] = { /* scoring for each number of lines */
623 #if BOARD_HEIGHT == 20
624 40 /* single */ , 100 /* double */ , 300 /* triple */ , 1200 /* rockblox */
625 #elif BOARD_HEIGHT == 14 /* Player special values */
626 60 /* single */ , 150 /* double */ , 500 /* triple */ , 2000 /* rockblox */
627 #endif
630 struct figure
632 #if LCD_DEPTH >= 2
633 unsigned short color[3]; /* color of figure (light,middle,shadow) */
634 #endif
635 unsigned short max_or; /* max orientations */
636 signed short shapeX[4], shapeY[4]; /* implementation of figures */
639 /* array of figures */
640 figures[BLOCKS_NUM] = {
641 /* O */
643 #if LCD_DEPTH >= 16
644 {LCD_RGBPACK (153, 255, 255), LCD_RGBPACK(0, 255, 255),
645 LCD_RGBPACK(0,153,153)},
646 #elif LCD_DEPTH == 2
647 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
648 #endif
650 {-1, 0, -1, 0},
651 {0, 0, 1, 1}
653 /* I */
655 #if LCD_DEPTH >= 16
656 {LCD_RGBPACK (255, 153, 128), LCD_RGBPACK (255, 0, 0),
657 LCD_RGBPACK (153, 0, 0)},
658 #elif LCD_DEPTH == 2
659 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
660 #endif
662 {-2, -1, 0, 1},
663 {0, 0, 0, 0}
665 /* 'Z' */
667 #if LCD_DEPTH >= 16
668 {LCD_RGBPACK (153, 255, 153), LCD_RGBPACK (0, 255, 0),
669 LCD_RGBPACK (0, 153, 0)},
670 #elif LCD_DEPTH == 2
671 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
672 #endif
674 {0, 1, -1, 0},
675 {0, 0, 1, 1}
677 /* 'S' */
679 #if LCD_DEPTH >= 16
680 {LCD_RGBPACK (153, 153, 255), LCD_RGBPACK (0, 0, 255),
681 LCD_RGBPACK (0, 0, 153)},
682 #elif LCD_DEPTH == 2
683 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
684 #endif
686 {-1, 0, 0, 1},
687 {0, 0, 1, 1}
689 /* 'L' */
691 #if LCD_DEPTH >= 16
692 {LCD_RGBPACK (255, 255, 153), LCD_RGBPACK (255, 255, 0),
693 LCD_RGBPACK (153, 153, 0)},
694 #elif LCD_DEPTH == 2
695 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
696 #endif
698 {-1, 0, 1, 1},
699 {0, 0, 0, 1}
701 /* 'J' */
703 #if LCD_DEPTH >= 16
704 {LCD_RGBPACK (255, 153, 255), LCD_RGBPACK (255, 0, 255),
705 LCD_RGBPACK (153, 0, 153)},
706 #elif LCD_DEPTH == 2
707 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
708 #endif
710 {-1, 0, 1, -1},
711 {0, 0, 0, 1}
713 /* 'T' */
715 #if LCD_DEPTH >= 16
716 {LCD_RGBPACK (204, 204, 204), LCD_RGBPACK (153, 153, 153),
717 LCD_RGBPACK (85, 85, 85)},
718 #elif LCD_DEPTH == 2
719 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
720 #endif
722 {-1, 0, 1, 0},
723 {0, 0, 0, 1}
727 /* Rockbox File System only supports full filenames inc dir */
728 #define HIGH_SCORE PLUGIN_GAMES_DIR "/rockblox.score"
729 #define RESUME_FILE PLUGIN_GAMES_DIR "/rockblox.resume"
730 #define MAX_HIGH_SCORES 5
732 /* Default High Scores... */
733 struct highscore highest[MAX_HIGH_SCORES];
735 /* get random number from (0) to (range-1) */
736 static int t_rand (int range)
738 return rb->rand () % range;
741 static inline void show_game_over (void)
743 rb->splash(HZ,"Game over!");
746 /* init the board array to have no blocks */
747 static void init_board (void)
749 int i, j;
750 for (i = 0; i < BOARD_WIDTH; i++)
751 for (j = 0; j < BOARD_HEIGHT; j++)
752 rockblox_status.board[j][i] = EMPTY_BLOCK;
755 /* show the score, level and lines */
756 static void show_details (void)
758 char str[25]; /* for strings */
760 #ifdef HAVE_LCD_BITMAP
761 #if LCD_DEPTH >= 2
762 rb->lcd_set_foreground (LCD_BLACK);
763 rb->lcd_set_background (LCD_WHITE);
764 #endif
765 rb->snprintf (str, sizeof (str), "%d", rockblox_status.score);
766 rb->lcd_putsxy (LABEL_X, SCORE_Y, str);
767 rb->snprintf (str, sizeof (str), "%d", rockblox_status.level);
768 rb->lcd_putsxy (LEVEL_X, LEVEL_Y, str);
769 rb->snprintf (str, sizeof (str), "%d", rockblox_status.lines);
770 rb->lcd_putsxy (LINES_X, LINES_Y, str);
771 #else /* HAVE_LCD_CHARCELLS */
772 rb->snprintf (str, sizeof (str), "L%d/%d", rockblox_status.level,
773 rockblox_status.lines);
774 rb->lcd_puts (5, 0, str);
775 rb->snprintf (str, sizeof (str), "S%d", rockblox_status.score);
776 rb->lcd_puts (5, 1, str);
777 #endif
780 #ifdef HIGH_SCORE_Y
781 static void show_highscores (void)
783 int i;
784 char str[25]; /* for strings */
786 for (i = 0; i<MAX_HIGH_SCORES; i++)
788 rb->snprintf (str, sizeof (str), "%06d" _SPACE "L%1d",
789 highest[i].score, highest[i].level);
790 rb->lcd_putsxy (HIGH_LABEL_X, HIGH_SCORE_Y + (10 * i), str);
793 #endif
795 /* Returns >0 on successful read AND if the game wasn't over, else 0 */
796 static int load_resume(void)
798 int fd;
799 fd = rb->open(RESUME_FILE, O_RDONLY);
800 if (fd < 0)
801 return 0;
803 if (rb->read(fd, &rockblox_status, sizeof(struct _rockblox_status))
804 < (ssize_t)sizeof(struct _rockblox_status))
806 rb->splash(HZ/2, "Loading Rockblox resume info failed");
807 return 0;
810 rb->close(fd);
812 if (rockblox_status.gameover)
813 show_game_over();
815 return !rockblox_status.gameover;
818 /* Returns >0 on success, else 0 */
819 static int dump_resume(void)
821 int fd;
823 fd = rb->open(RESUME_FILE, O_WRONLY|O_CREAT);
824 if (fd < 0)
825 goto fail;
827 if (rb->write(fd, &rockblox_status, sizeof(struct _rockblox_status))
828 <= 0)
830 rb->close(fd);
831 goto fail;
833 rb->close(fd);
834 return 1;
836 fail:
837 rb->splash(HZ/2, "Writing Rockblox resume info failed");
838 return 0;
840 static void init_rockblox (bool resume)
842 char score_name[50];
843 struct tm* tm;
845 tm = rb->get_time();
846 rb->snprintf(score_name, sizeof(score_name), "%04d%02d%02d %02d%02d%02d",
847 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
848 tm->tm_hour, tm->tm_min, tm->tm_sec);
850 highscore_update(rockblox_status.score, rockblox_status.level,
851 score_name, highest, MAX_HIGH_SCORES);
853 #ifdef HAVE_LCD_BITMAP
854 rb->lcd_bitmap (rockblox_background, 0, 0, LCD_WIDTH, LCD_HEIGHT);
855 #else /* HAVE_LCD_CHARCELLS */
856 pgfx_display (0, 0);
857 pgfx_display_block (3, 0, 3, 1);
858 pgfx_display_block (4, 0, 3, 0);
859 pgfx_clear_display();
860 pgfx_fillrect (3, 0, 2, 14);
861 pgfx_fillrect (15, 7, 2, 7);
862 pgfx_update();
863 #endif
864 if (!resume || !load_resume())
866 rockblox_status.level = 1;
867 rockblox_status.lines = 0;
868 rockblox_status.score = 0;
869 rockblox_status.nf = t_rand(BLOCKS_NUM);
870 init_board ();
871 new_block ();
873 draw_next_block();
875 show_details ();
876 #ifdef HIGH_SCORE_Y
877 show_highscores ();
878 #endif
881 static inline int level_speed(int level)
883 #if BOARD_HEIGHT == 20
884 return (5*HZ) / (level + 9);
885 #elif BOARD_HEIGHT == 14
886 return (7*HZ) / (level + 9);
887 #endif
890 static int getRelativeX (int figure, int square, int orientation)
892 switch (orientation) {
893 case 0:
894 return figures[figure].shapeX[square];
895 case 1:
896 return figures[figure].shapeY[square];
897 case 2:
898 return -figures[figure].shapeX[square];
899 case 3:
900 return -figures[figure].shapeY[square];
901 default:
902 return 0;
906 static int getRelativeY (int figure, int square, int orientation)
908 switch (orientation) {
909 case 0:
910 return figures[figure].shapeY[square];
911 case 1:
912 return -figures[figure].shapeX[square];
913 case 2:
914 return -figures[figure].shapeY[square];
915 case 3:
916 return figures[figure].shapeX[square];
917 default:
918 return 0;
922 /* redraw the while board on the screen */
923 static void refresh_board (void)
925 int i, j, x, y, block;
927 #if LCD_DEPTH >= 2
928 rb->lcd_set_foreground (LCD_BLACK);
929 #elif LCD_DEPTH == 1
930 MYLCD(set_drawmode) (DRMODE_SOLID | DRMODE_INVERSEVID);
931 #endif
933 MYLCD(fillrect) (BOARD_X, BOARD_Y, BOARD_WIDTH * BLOCK_WIDTH,
934 BOARD_HEIGHT * BLOCK_HEIGHT);
936 #if LCD_DEPTH == 1
937 MYLCD(set_drawmode) (DRMODE_SOLID);
938 #endif
940 for (i = 0; i < BOARD_WIDTH; i++)
941 for (j = 0; j < BOARD_HEIGHT; j++) {
942 block = rockblox_status.board[j][i];
943 if (block != EMPTY_BLOCK) {
944 #ifdef HAVE_LCD_BITMAP
945 #if LCD_DEPTH >= 2
946 /* middle drawing */
947 rb->lcd_set_foreground (figures[block].color[1]);
948 #endif
949 rb->lcd_fillrect (BOARD_X + i * BLOCK_WIDTH,
950 BOARD_Y + j * BLOCK_HEIGHT,
951 BLOCK_WIDTH, BLOCK_HEIGHT);
952 #if LCD_DEPTH >= 2
953 /* light drawing */
954 rb->lcd_set_foreground (figures[block].color[0]);
955 #endif
956 rb->lcd_vline (BOARD_X + i * BLOCK_WIDTH,
957 BOARD_Y + j * BLOCK_HEIGHT,
958 BOARD_Y + (j + 1) * BLOCK_HEIGHT - 2);
959 rb->lcd_hline (BOARD_X + i * BLOCK_WIDTH,
960 BOARD_X + (i + 1) * BLOCK_WIDTH - 2,
961 BOARD_Y + j * BLOCK_HEIGHT);
962 #if LCD_DEPTH >= 2
963 /* shadow drawing */
964 rb->lcd_set_foreground (figures[block].color[2]);
965 #endif
966 rb->lcd_vline (BOARD_X + (i + 1) * BLOCK_WIDTH - 1,
967 BOARD_Y + j * BLOCK_HEIGHT + 1,
968 BOARD_Y + (j + 1) * BLOCK_HEIGHT - 1);
969 rb->lcd_hline (BOARD_X + i * BLOCK_WIDTH + 1,
970 BOARD_X + (i + 1) * BLOCK_WIDTH - 1,
971 BOARD_Y + (j + 1) * BLOCK_HEIGHT - 1);
972 #else /* HAVE_LCD_CHARCELLS */
973 pgfx_drawpixel (BOARD_X + i, BOARD_Y + j);
974 #endif
978 for (i = 0; i < 4; i++) {
979 x = getRelativeX (rockblox_status.cf, i, rockblox_status.co)
980 + rockblox_status.cx;
981 y = getRelativeY (rockblox_status.cf, i, rockblox_status.co)
982 + rockblox_status.cy;
983 #ifdef HAVE_LCD_BITMAP
984 #if LCD_DEPTH >= 2
985 /* middle drawing */
986 rb->lcd_set_foreground (figures[rockblox_status.cf].color[1]);
987 #endif
988 rb->lcd_fillrect (BOARD_X + x * BLOCK_WIDTH,
989 BOARD_Y + y * BLOCK_HEIGHT,
990 BLOCK_WIDTH, BLOCK_HEIGHT);
991 #if LCD_DEPTH >= 2
992 /* light drawing */
993 rb->lcd_set_foreground (figures[rockblox_status.cf].color[0]);
994 #endif
995 rb->lcd_vline (BOARD_X + x * BLOCK_WIDTH, BOARD_Y + y * BLOCK_HEIGHT,
996 BOARD_Y + (y + 1) * BLOCK_HEIGHT - 2);
997 rb->lcd_hline (BOARD_X + x * BLOCK_WIDTH,
998 BOARD_X + (x + 1) * BLOCK_WIDTH - 2,
999 BOARD_Y + y * BLOCK_HEIGHT);
1000 #if LCD_DEPTH >= 2
1001 /* shadow drawing */
1002 rb->lcd_set_foreground (figures[rockblox_status.cf].color[2]);
1003 #endif
1004 rb->lcd_vline (BOARD_X + (x + 1) * BLOCK_WIDTH - 1,
1005 BOARD_Y + y * BLOCK_HEIGHT + 1,
1006 BOARD_Y + (y + 1) * BLOCK_HEIGHT - 1);
1007 rb->lcd_hline (BOARD_X + x * BLOCK_WIDTH + 1,
1008 BOARD_X + (x + 1) * BLOCK_WIDTH - 1,
1009 BOARD_Y + (y + 1) * BLOCK_HEIGHT - 1);
1010 #else /* HAVE_LCD_CHARCELLS */
1011 pgfx_drawpixel (BOARD_X + x, BOARD_Y + y);
1012 #endif
1014 MYLCD(update) ();
1017 static bool canMoveTo (int x, int y, int newOrientation)
1019 int i, rx, ry;
1020 for (i = 0; i < 4; i++) {
1021 ry = getRelativeY (rockblox_status.cf, i, newOrientation) + y;
1022 rx = getRelativeX (rockblox_status.cf, i, newOrientation) + x;
1023 if ((rx < 0 || rx >= BOARD_WIDTH) ||
1024 (ry < 0 || ry >= BOARD_HEIGHT) ||
1025 (rockblox_status.board[ry][rx] != EMPTY_BLOCK))
1026 return false;
1028 return true;
1031 /* draws the preview of next block in the preview window */
1032 static void draw_next_block (void)
1034 int i, rx, ry;
1035 /* clear preview window first */
1036 #if LCD_DEPTH >= 2
1037 rb->lcd_set_foreground (LCD_BLACK);
1038 #elif LCD_DEPTH == 1
1039 MYLCD(set_drawmode) (DRMODE_SOLID | DRMODE_INVERSEVID);
1040 #endif
1042 /* 4x4 */
1043 MYLCD(fillrect) (PREVIEW_X, PREVIEW_Y, BLOCK_WIDTH * 4, BLOCK_HEIGHT * 4);
1045 #if LCD_DEPTH == 1
1046 MYLCD(set_drawmode) (DRMODE_SOLID);
1047 #endif
1049 /* draw the lightgray rectangles */
1050 #if LCD_DEPTH >= 16
1051 rb->lcd_set_foreground (LCD_RGBPACK (40, 40, 40));
1052 #elif LCD_DEPTH == 2
1053 rb->lcd_set_foreground (LCD_DARKGRAY);
1054 #endif
1056 #if LCD_DEPTH >= 2
1057 for (rx = 0; rx < 4; rx++)
1058 for (ry = 0; ry < 4; ry++)
1059 rb->lcd_drawrect (PREVIEW_X + rx * BLOCK_WIDTH,
1060 PREVIEW_Y + ry * BLOCK_HEIGHT, BLOCK_WIDTH,
1061 BLOCK_HEIGHT);
1062 #endif
1064 /* draw the figure */
1065 for (i = 0; i < 4; i++) {
1066 rx = getRelativeX (rockblox_status.nf, i, 0) + 2;
1067 ry = getRelativeY (rockblox_status.nf, i, 0) + 2;
1068 #ifdef HAVE_LCD_BITMAP
1069 #if LCD_DEPTH >= 2
1070 rb->lcd_set_foreground (figures[rockblox_status.nf].color[1]); /* middle drawing */
1071 #endif
1072 rb->lcd_fillrect (PREVIEW_X + rx * BLOCK_WIDTH,
1073 PREVIEW_Y + ry * BLOCK_HEIGHT,
1074 BLOCK_WIDTH, BLOCK_HEIGHT);
1075 #if LCD_DEPTH >= 2
1076 rb->lcd_set_foreground (figures[rockblox_status.nf].color[0]); /* light drawing */
1077 #endif
1078 rb->lcd_vline (PREVIEW_X + rx * BLOCK_WIDTH,
1079 PREVIEW_Y + ry * BLOCK_HEIGHT,
1080 PREVIEW_Y + (ry + 1) * BLOCK_HEIGHT - 2);
1081 rb->lcd_hline (PREVIEW_X + rx * BLOCK_WIDTH,
1082 PREVIEW_X + (rx + 1) * BLOCK_WIDTH - 2,
1083 PREVIEW_Y + ry * BLOCK_HEIGHT);
1084 #if LCD_DEPTH >= 2
1085 rb->lcd_set_foreground (figures[rockblox_status.nf].color[2]); /* shadow drawing */
1086 #endif
1087 rb->lcd_vline (PREVIEW_X + (rx + 1) * BLOCK_WIDTH - 1,
1088 PREVIEW_Y + ry * BLOCK_HEIGHT + 1,
1089 PREVIEW_Y + (ry + 1) * BLOCK_HEIGHT - 1);
1090 rb->lcd_hline (PREVIEW_X + rx * BLOCK_WIDTH + 1,
1091 PREVIEW_X + (rx + 1) * BLOCK_WIDTH - 1,
1092 PREVIEW_Y + (ry + 1) * BLOCK_HEIGHT - 1);
1093 #else /* HAVE_LCD_CHARCELLS */
1094 pgfx_drawpixel (PREVIEW_X + rx, PREVIEW_Y + ry);
1095 #endif
1100 /* move the block to a relative location */
1101 static void move_block (int x, int y, int o)
1103 if (canMoveTo (rockblox_status.cx + x, rockblox_status.cy + y, o)) {
1104 rockblox_status.cy += y;
1105 rockblox_status.cx += x;
1106 rockblox_status.co = o;
1110 /* try to add a new block to play with (return true if gameover) */
1111 static void new_block (void)
1113 rockblox_status.cy = 1;
1114 rockblox_status.cx = 5;
1115 rockblox_status.cf = rockblox_status.nf;
1116 rockblox_status.co = 0; /* start at the same orientation all time */
1117 rockblox_status.nf = t_rand (BLOCKS_NUM);
1118 rockblox_status.gameover = !canMoveTo (rockblox_status.cx,
1119 rockblox_status.cy, rockblox_status.co);
1121 draw_next_block ();
1125 /* check for filled rockblox_status.lines and do what necessary */
1126 static int check_lines (void)
1129 int i, j, y;
1130 int rockblox = 0;
1132 for (j = 0; j < BOARD_HEIGHT; j++) {
1133 for (i = 0; ((i < BOARD_WIDTH) &&
1134 (rockblox_status.board[j][i] != EMPTY_BLOCK)); i++);
1135 if (i == BOARD_WIDTH) { /* woo hoo, we have a line */
1136 rockblox++;
1137 for (y = j; y > 0; y--)
1139 for (i = 0; i < BOARD_WIDTH; i++)
1140 { /* fall line */
1141 rockblox_status.board[y][i] = rockblox_status.board[y - 1][i];
1147 return rockblox;
1150 /* moves down the figure and returns true if gameover */
1151 static void move_down (void)
1153 int l, i, rx, ry;
1155 if (!canMoveTo (rockblox_status.cx, rockblox_status.cy + 1, rockblox_status.co)) {
1156 /* save figure to board */
1157 for (i = 0; i < 4; i++) {
1158 rx = getRelativeX (rockblox_status.cf, i, rockblox_status.co) + rockblox_status.cx;
1159 ry = getRelativeY (rockblox_status.cf, i, rockblox_status.co) + rockblox_status.cy;
1160 rockblox_status.board[ry][rx] = rockblox_status.cf;
1162 /* check if formed some lines */
1163 l = check_lines ();
1164 if (l) {
1165 /* the original scoring from "http://en.wikipedia.org/wiki/Rockblox" */
1166 rockblox_status.score += scoring[l - 1] * rockblox_status.level;
1167 rockblox_status.lines += l;
1168 rockblox_status.level = (int) rockblox_status.lines / 10 + 1;
1171 /* show details */
1172 show_details ();
1174 /* generate a new figure */
1175 new_block ();
1176 } else
1177 move_block (0, 1, rockblox_status.co);
1180 static int rockblox_loop (void)
1182 int button;
1183 int lastbutton = BUTTON_NONE;
1184 long next_down_tick = *rb->current_tick + level_speed(rockblox_status.level);
1186 while (1) {
1187 #ifdef HAS_BUTTON_HOLD
1188 if (rb->button_hold ()) {
1189 /* Turn on backlight timeout (revert to settings) */
1190 backlight_use_settings(); /* backlight control in lib/helper.c */
1191 rb->splash(0, "Paused");
1192 while (rb->button_hold ())
1193 rb->sleep(HZ/10);
1195 /* Turn off backlight timeout */
1196 backlight_force_on(); /* backlight control in lib/helper.c */
1198 /* get rid of the splash text */
1199 rb->lcd_bitmap (rockblox_background, 0, 0, LCD_WIDTH, LCD_HEIGHT);
1200 show_details ();
1201 #ifdef HIGH_SCORE_Y
1202 show_highscores ();
1203 #endif
1204 draw_next_block ();
1205 refresh_board ();
1207 #endif
1209 button = rb->button_get_w_tmo (MAX(next_down_tick - *rb->current_tick, 1));
1210 switch (button) {
1211 #ifdef ROCKBLOX_RC_OFF
1212 case ROCKBLOX_RC_OFF:
1213 #endif
1214 case ROCKBLOX_OFF:
1215 #ifdef ROCKBLOX_OFF_PRE
1216 if (lastbutton != ROCKBLOX_OFF_PRE)
1217 break;
1218 #endif
1219 return PLUGIN_OK;
1221 #if defined(ROCKBLOX_ROTATE)
1222 case ROCKBLOX_ROTATE:
1223 #endif
1224 case ROCKBLOX_ROTATE_RIGHT:
1225 case ROCKBLOX_ROTATE_RIGHT | BUTTON_REPEAT:
1226 #ifdef HAVE_SCROLLWHEEL
1227 /* if the wheel is disabled, add an event to the stack. */
1228 if(wheel_enabled == false)
1229 wheel_events++;
1231 /* if it's enabled, go ahead and rotate.. */
1232 if(wheel_enabled)
1233 #endif
1234 move_block (0, 0, (rockblox_status.co + 1) % figures[rockblox_status.cf].max_or);
1235 break;
1237 case ROCKBLOX_ROTATE_LEFT:
1238 case ROCKBLOX_ROTATE_LEFT | BUTTON_REPEAT:
1239 #ifdef HAVE_SCROLLWHEEL
1240 if(wheel_enabled == false)
1241 wheel_events++;
1243 if(wheel_enabled)
1244 #endif
1245 move_block (0, 0,
1246 (rockblox_status.co + figures[rockblox_status.cf].max_or -
1247 1) % figures[rockblox_status.cf].max_or);
1248 break;
1250 #ifdef ROCKBLOX_ROTATE_RIGHT2
1251 case ROCKBLOX_ROTATE_RIGHT2:
1252 move_block (0, 0, (rockblox_status.co + 1) % figures[rockblox_status.cf].max_or);
1253 break;
1254 #endif
1256 case ROCKBLOX_DOWN:
1257 case ROCKBLOX_DOWN | BUTTON_REPEAT:
1258 move_block (0, 1, rockblox_status.co);
1259 break;
1261 case ROCKBLOX_RIGHT:
1262 case ROCKBLOX_RIGHT | BUTTON_REPEAT:
1263 move_block (1, 0, rockblox_status.co);
1264 break;
1266 case ROCKBLOX_LEFT:
1267 case ROCKBLOX_LEFT | BUTTON_REPEAT:
1268 move_block (-1, 0, rockblox_status.co);
1269 break;
1271 case ROCKBLOX_DROP:
1272 #ifdef ROCKBLOX_DROP_PRE
1273 if (lastbutton != ROCKBLOX_DROP_PRE)
1274 break;
1275 #endif
1276 while (canMoveTo (rockblox_status.cx, rockblox_status.cy + 1, rockblox_status.co))
1277 move_block (0, 1, rockblox_status.co);
1278 break;
1279 #ifdef ROCKBLOX_RESTART
1280 case ROCKBLOX_RESTART:
1281 rb->splash (HZ * 1, "Restarting...");
1282 init_rockblox (false);
1283 break;
1284 #endif
1286 default:
1287 if (rb->default_event_handler (button) == SYS_USB_CONNECTED)
1288 return PLUGIN_USB_CONNECTED;
1289 break;
1291 if (button != BUTTON_NONE)
1292 lastbutton = button;
1294 #ifdef HAVE_SCROLLWHEEL
1295 /* check if we should enable the scroll wheel, if events
1296 * begin to stack up... */
1297 if(wheel_enabled == false)
1299 /* stopped rotating the wheel, reset the count */
1300 if(wheel_events == last_wheel_event)
1302 last_wheel_event = 0;
1303 wheel_events = 0;
1305 /* rotated the wheel a while constantly, enable it. */
1306 else if(wheel_events > 3)
1308 wheel_enabled = true;
1311 /* this evens out the last event and the "current" event.
1312 * if we get an event next time through button reading, it will
1313 * remain ahead of last_event. if we don't, they'll end up equaling
1314 * each other.. thus, the scroll count will be reset. */
1315 if(wheel_enabled == false && wheel_events > last_wheel_event)
1316 last_wheel_event++;
1318 #endif
1320 if (TIME_AFTER(*rb->current_tick, next_down_tick)) {
1321 move_down ();
1322 next_down_tick += level_speed(rockblox_status.level);
1323 if (TIME_AFTER(*rb->current_tick, next_down_tick))
1324 /* restart time "raster" when we had to wait longer than usual
1325 * (pause, game restart etc) */
1326 next_down_tick = *rb->current_tick + level_speed(rockblox_status.level);
1329 if (rockblox_status.gameover) {
1330 #if LCD_DEPTH >= 2
1331 rb->lcd_set_foreground (LCD_BLACK);
1332 #endif
1333 show_game_over();
1334 init_rockblox (false);
1337 refresh_board ();
1340 return PLUGIN_OK;
1343 enum plugin_status plugin_start (const void *parameter)
1345 int ret;
1347 (void) parameter;
1349 rb->srand (*rb->current_tick);
1351 /* Load HighScore if any */
1352 highscore_load(HIGH_SCORE, highest, MAX_HIGH_SCORES);
1354 #if LCD_DEPTH > 1
1355 rb->lcd_set_backdrop(NULL);
1356 #endif
1358 #ifdef HAVE_LCD_BITMAP
1359 rb->lcd_setfont (FONT_SYSFIXED);
1360 #else
1361 if (!pgfx_init(4, 2))
1363 rb->splash(HZ*2, "Old LCD :(");
1364 return PLUGIN_OK;
1366 #endif
1367 /* Turn off backlight timeout */
1368 backlight_force_on(); /* backlight control in lib/helper.c */
1370 init_rockblox (true);
1371 ret = rockblox_loop ();
1373 #ifndef HAVE_LCD_BITMAP
1374 pgfx_release();
1375 #endif
1376 /* Save user's HighScore */
1377 highscore_save(HIGH_SCORE, highest, MAX_HIGH_SCORES);
1378 backlight_use_settings(); /* backlight control in lib/helper.c */
1380 dump_resume();
1382 return ret;