Fix typo in german translation.
[maemo-rb.git] / apps / plugins / rockblox.c
blob8db4a3497fdbdd09dfa06326fcb497a0538c5b9b
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/display_text.h"
25 #include "lib/helper.h"
26 #include "lib/highscore.h"
27 #include "lib/playback_control.h"
28 #include "lib/playergfx.h"
29 #include "lib/mylcd.h"
33 #if (CONFIG_KEYPAD == IPOD_4G_PAD) || \
34 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
35 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
37 #define ROCKBLOX_OFF (BUTTON_MENU | BUTTON_SELECT)
38 #define ROCKBLOX_ROTATE_CCW BUTTON_SCROLL_BACK
39 #define ROCKBLOX_ROTATE_CCW2 (BUTTON_MENU | BUTTON_REL)
40 #define ROCKBLOX_ROTATE_CW BUTTON_SCROLL_FWD
41 #define ROCKBLOX_LEFT BUTTON_LEFT
42 #define ROCKBLOX_RIGHT BUTTON_RIGHT
43 #define ROCKBLOX_DOWN BUTTON_PLAY
44 #define ROCKBLOX_RESTART (BUTTON_SELECT | BUTTON_PLAY)
45 #define ROCKBLOX_DROP (BUTTON_SELECT | BUTTON_REL)
47 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
48 (CONFIG_KEYPAD == IRIVER_H300_PAD)
50 #define ROCKBLOX_OFF BUTTON_OFF
51 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
52 #define ROCKBLOX_ROTATE_CW BUTTON_SELECT
53 #define ROCKBLOX_DOWN BUTTON_DOWN
54 #define ROCKBLOX_LEFT BUTTON_LEFT
55 #define ROCKBLOX_RIGHT BUTTON_RIGHT
56 #define ROCKBLOX_DROP BUTTON_MODE
57 #define ROCKBLOX_RESTART BUTTON_ON
59 #define ROCKBLOX_RC_OFF BUTTON_RC_STOP
61 #elif CONFIG_KEYPAD == RECORDER_PAD
63 #define ROCKBLOX_OFF BUTTON_OFF
64 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
65 #define ROCKBLOX_ROTATE_CW BUTTON_PLAY
66 #define ROCKBLOX_DOWN BUTTON_DOWN
67 #define ROCKBLOX_LEFT BUTTON_LEFT
68 #define ROCKBLOX_RIGHT BUTTON_RIGHT
69 #define ROCKBLOX_DROP BUTTON_ON
70 #define ROCKBLOX_RESTART BUTTON_F1
72 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
74 #define ROCKBLOX_OFF BUTTON_OFF
75 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
76 #define ROCKBLOX_ROTATE_CW BUTTON_SELECT
77 #define ROCKBLOX_DOWN BUTTON_DOWN
78 #define ROCKBLOX_LEFT BUTTON_LEFT
79 #define ROCKBLOX_RIGHT BUTTON_RIGHT
80 #define ROCKBLOX_DROP BUTTON_ON
81 #define ROCKBLOX_RESTART BUTTON_F1
83 #elif CONFIG_KEYPAD == PLAYER_PAD
85 #define ROCKBLOX_OFF_PRE BUTTON_STOP
86 #define ROCKBLOX_OFF (BUTTON_STOP|BUTTON_REL)
87 #define ROCKBLOX_ROTATE_CCW BUTTON_PLAY
88 #define ROCKBLOX_ROTATE_CW (BUTTON_ON|BUTTON_PLAY)
89 #define ROCKBLOX_DOWN BUTTON_MENU
90 #define ROCKBLOX_LEFT BUTTON_LEFT
91 #define ROCKBLOX_RIGHT BUTTON_RIGHT
92 #define ROCKBLOX_DROP_PRE BUTTON_ON
93 #define ROCKBLOX_DROP (BUTTON_ON|BUTTON_REL)
94 #define ROCKBLOX_RESTART (BUTTON_STOP|BUTTON_MENU)
96 #elif CONFIG_KEYPAD == ONDIO_PAD
98 #define ROCKBLOX_OFF_PRE BUTTON_OFF
99 #define ROCKBLOX_OFF (BUTTON_OFF|BUTTON_REL)
100 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
101 #define ROCKBLOX_ROTATE_CW (BUTTON_MENU|BUTTON_UP)
102 #define ROCKBLOX_DOWN BUTTON_DOWN
103 #define ROCKBLOX_LEFT BUTTON_LEFT
104 #define ROCKBLOX_RIGHT BUTTON_RIGHT
105 #define ROCKBLOX_DROP_PRE BUTTON_MENU
106 #define ROCKBLOX_DROP (BUTTON_MENU|BUTTON_REL)
107 #define ROCKBLOX_RESTART (BUTTON_OFF|BUTTON_MENU)
109 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
111 #define ROCKBLOX_OFF BUTTON_POWER
112 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
113 #define ROCKBLOX_ROTATE_CW BUTTON_SELECT
114 #define ROCKBLOX_DOWN BUTTON_DOWN
115 #define ROCKBLOX_LEFT BUTTON_LEFT
116 #define ROCKBLOX_RIGHT BUTTON_RIGHT
117 #define ROCKBLOX_DROP BUTTON_REC
118 #define ROCKBLOX_RESTART BUTTON_PLAY
120 #elif CONFIG_KEYPAD == SANSA_E200_PAD
122 #define ROCKBLOX_OFF BUTTON_POWER
123 #define ROCKBLOX_ROTATE_CCW BUTTON_SCROLL_BACK
124 #define ROCKBLOX_ROTATE_CCW2 BUTTON_UP
125 #define ROCKBLOX_ROTATE_CW BUTTON_SCROLL_FWD
126 #define ROCKBLOX_DOWN BUTTON_DOWN
127 #define ROCKBLOX_LEFT BUTTON_LEFT
128 #define ROCKBLOX_RIGHT BUTTON_RIGHT
129 #define ROCKBLOX_DROP BUTTON_SELECT
130 #define ROCKBLOX_RESTART BUTTON_REC
132 #elif CONFIG_KEYPAD == SANSA_FUZE_PAD
134 #define ROCKBLOX_OFF (BUTTON_HOME|BUTTON_REPEAT)
135 #define ROCKBLOX_ROTATE_CCW BUTTON_SCROLL_BACK
136 #define ROCKBLOX_ROTATE_CCW2 BUTTON_UP
137 #define ROCKBLOX_ROTATE_CW BUTTON_SCROLL_FWD
138 #define ROCKBLOX_DOWN BUTTON_DOWN
139 #define ROCKBLOX_LEFT BUTTON_LEFT
140 #define ROCKBLOX_RIGHT BUTTON_RIGHT
141 #define ROCKBLOX_DROP (BUTTON_SELECT | BUTTON_REL)
142 #define ROCKBLOX_RESTART (BUTTON_SELECT | BUTTON_UP)
145 #elif CONFIG_KEYPAD == SANSA_C200_PAD
147 #define ROCKBLOX_OFF BUTTON_POWER
148 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
149 #define ROCKBLOX_ROTATE_CCW2 BUTTON_VOL_DOWN
150 #define ROCKBLOX_ROTATE_CW BUTTON_VOL_UP
151 #define ROCKBLOX_DOWN BUTTON_DOWN
152 #define ROCKBLOX_LEFT BUTTON_LEFT
153 #define ROCKBLOX_RIGHT BUTTON_RIGHT
154 #define ROCKBLOX_DROP BUTTON_SELECT
155 #define ROCKBLOX_RESTART BUTTON_REC
157 #elif CONFIG_KEYPAD == SANSA_CLIP_PAD
159 #define ROCKBLOX_OFF BUTTON_POWER
160 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
161 #define ROCKBLOX_ROTATE_CCW2 BUTTON_VOL_DOWN
162 #define ROCKBLOX_ROTATE_CW BUTTON_VOL_UP
163 #define ROCKBLOX_DOWN BUTTON_DOWN
164 #define ROCKBLOX_LEFT BUTTON_LEFT
165 #define ROCKBLOX_RIGHT BUTTON_RIGHT
166 #define ROCKBLOX_DROP BUTTON_SELECT
167 #define ROCKBLOX_RESTART BUTTON_HOME
169 #elif CONFIG_KEYPAD == SANSA_M200_PAD
171 #define ROCKBLOX_OFF BUTTON_POWER
172 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
173 #define ROCKBLOX_ROTATE_CCW2 BUTTON_VOL_DOWN
174 #define ROCKBLOX_ROTATE_CW BUTTON_VOL_UP
175 #define ROCKBLOX_DOWN BUTTON_DOWN
176 #define ROCKBLOX_LEFT BUTTON_LEFT
177 #define ROCKBLOX_RIGHT BUTTON_RIGHT
178 #define ROCKBLOX_RESTART (BUTTON_SELECT | BUTTON_UP)
179 #define ROCKBLOX_DROP (BUTTON_SELECT | BUTTON_REL)
181 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
183 #define ROCKBLOX_OFF BUTTON_POWER
184 #define ROCKBLOX_ROTATE_CCW BUTTON_SCROLL_UP
185 #define ROCKBLOX_ROTATE_CW BUTTON_REW
186 #define ROCKBLOX_DOWN BUTTON_SCROLL_DOWN
187 #define ROCKBLOX_LEFT BUTTON_LEFT
188 #define ROCKBLOX_RIGHT BUTTON_RIGHT
189 #define ROCKBLOX_DROP BUTTON_FF
190 #define ROCKBLOX_RESTART BUTTON_PLAY
192 #elif CONFIG_KEYPAD == GIGABEAT_PAD
194 #define ROCKBLOX_OFF BUTTON_POWER
195 #define ROCKBLOX_ROTATE_CCW BUTTON_VOL_DOWN
196 #define ROCKBLOX_ROTATE_CW BUTTON_VOL_UP
197 #define ROCKBLOX_ROTATE BUTTON_UP
198 #define ROCKBLOX_DOWN BUTTON_DOWN
199 #define ROCKBLOX_LEFT BUTTON_LEFT
200 #define ROCKBLOX_RIGHT BUTTON_RIGHT
201 #define ROCKBLOX_DROP BUTTON_SELECT
202 #define ROCKBLOX_RESTART BUTTON_A
204 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
206 #define ROCKBLOX_OFF BUTTON_PLAY
207 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
208 #define ROCKBLOX_ROTATE_CW BUTTON_SELECT
209 #define ROCKBLOX_DOWN BUTTON_DOWN
210 #define ROCKBLOX_LEFT BUTTON_LEFT
211 #define ROCKBLOX_RIGHT BUTTON_RIGHT
212 #define ROCKBLOX_DROP BUTTON_MODE
213 #define ROCKBLOX_RESTART BUTTON_EQ
215 #elif CONFIG_KEYPAD == MROBE500_PAD
216 #define ROCKBLOX_OFF BUTTON_POWER
218 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
219 #define ROCKBLOX_OFF BUTTON_BACK
220 #define ROCKBLOX_ROTATE_CCW BUTTON_VOL_DOWN
221 #define ROCKBLOX_ROTATE_CW BUTTON_VOL_UP
222 #define ROCKBLOX_ROTATE BUTTON_UP
223 #define ROCKBLOX_DOWN BUTTON_DOWN
224 #define ROCKBLOX_LEFT BUTTON_LEFT
225 #define ROCKBLOX_RIGHT BUTTON_RIGHT
226 #define ROCKBLOX_DROP BUTTON_SELECT
227 #define ROCKBLOX_RESTART BUTTON_PLAY
229 #elif CONFIG_KEYPAD == MROBE100_PAD
231 #define ROCKBLOX_OFF BUTTON_POWER
232 #define ROCKBLOX_ROTATE_CCW BUTTON_MENU
233 #define ROCKBLOX_ROTATE_CW BUTTON_PLAY
234 #define ROCKBLOX_ROTATE BUTTON_UP
235 #define ROCKBLOX_DOWN BUTTON_DOWN
236 #define ROCKBLOX_LEFT BUTTON_LEFT
237 #define ROCKBLOX_RIGHT BUTTON_RIGHT
238 #define ROCKBLOX_DROP BUTTON_SELECT
239 #define ROCKBLOX_RESTART BUTTON_DISPLAY
241 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
243 #define ROCKBLOX_OFF BUTTON_RC_REC
244 #define ROCKBLOX_ROTATE_CCW BUTTON_RC_VOL_DOWN
245 #define ROCKBLOX_ROTATE_CW BUTTON_RC_VOL_UP
246 #define ROCKBLOX_DOWN BUTTON_RC_MENU
247 #define ROCKBLOX_LEFT BUTTON_RC_REW
248 #define ROCKBLOX_RIGHT BUTTON_RC_FF
249 #define ROCKBLOX_DROP BUTTON_RC_PLAY
250 #define ROCKBLOX_RESTART BUTTON_RC_MODE
252 #elif CONFIG_KEYPAD == COWON_D2_PAD
254 #define ROCKBLOX_OFF BUTTON_POWER
255 #define ROCKBLOX_RESTART BUTTON_MENU
257 #elif CONFIG_KEYPAD == IAUDIO67_PAD
259 #define ROCKBLOX_OFF BUTTON_POWER
260 #define ROCKBLOX_ROTATE_CCW BUTTON_VOLDOWN
261 #define ROCKBLOX_ROTATE_CW BUTTON_VOLUP
262 #define ROCKBLOX_DOWN BUTTON_STOP
263 #define ROCKBLOX_LEFT BUTTON_LEFT
264 #define ROCKBLOX_RIGHT BUTTON_RIGHT
265 #define ROCKBLOX_DROP BUTTON_PLAY
266 #define ROCKBLOX_RESTART BUTTON_MENU
268 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
269 #define ROCKBLOX_OFF BUTTON_BACK
270 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
271 #define ROCKBLOX_ROTATE_CW BUTTON_PLAY
272 #define ROCKBLOX_DOWN BUTTON_DOWN
273 #define ROCKBLOX_LEFT BUTTON_LEFT
274 #define ROCKBLOX_RIGHT BUTTON_RIGHT
275 #define ROCKBLOX_DROP BUTTON_SELECT
276 #define ROCKBLOX_RESTART BUTTON_CUSTOM
278 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
280 #define ROCKBLOX_OFF BUTTON_POWER
281 #define ROCKBLOX_ROTATE_CCW BUTTON_VOL_DOWN
282 #define ROCKBLOX_ROTATE_CW BUTTON_VOL_UP
283 #define ROCKBLOX_ROTATE BUTTON_UP
284 #define ROCKBLOX_DOWN BUTTON_DOWN
285 #define ROCKBLOX_LEFT BUTTON_LEFT
286 #define ROCKBLOX_RIGHT BUTTON_RIGHT
287 #define ROCKBLOX_DROP BUTTON_SELECT
288 #define ROCKBLOX_RESTART BUTTON_MENU
290 #elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD
292 #define ROCKBLOX_OFF BUTTON_POWER
293 #define ROCKBLOX_ROTATE_CCW BUTTON_PREV
294 #define ROCKBLOX_ROTATE_CW BUTTON_NEXT
295 #define ROCKBLOX_ROTATE BUTTON_UP
296 #define ROCKBLOX_DOWN BUTTON_DOWN
297 #define ROCKBLOX_LEFT BUTTON_LEFT
298 #define ROCKBLOX_RIGHT BUTTON_RIGHT
299 #define ROCKBLOX_DROP BUTTON_PLAY
300 #define ROCKBLOX_RESTART BUTTON_MENU
302 # elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
304 #define ROCKBLOX_OFF BUTTON_POWER
305 #define ROCKBLOX_ROTATE_CCW BUTTON_VOL_DOWN
306 #define ROCKBLOX_ROTATE_CW BUTTON_VOL_UP
307 #define ROCKBLOX_ROTATE BUTTON_UP
308 #define ROCKBLOX_DOWN BUTTON_DOWN
309 #define ROCKBLOX_LEFT BUTTON_PREV
310 #define ROCKBLOX_RIGHT BUTTON_NEXT
311 #define ROCKBLOX_DROP BUTTON_PLAY
312 #define ROCKBLOX_RESTART BUTTON_MENU
314 #elif CONFIG_KEYPAD == ONDAVX747_PAD
315 #define ROCKBLOX_OFF BUTTON_POWER
316 #define ROCKBLOX_RESTART BUTTON_MENU
317 #elif CONFIG_KEYPAD == ONDAVX777_PAD
318 #define ROCKBLOX_OFF BUTTON_POWER
320 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
322 #define ROCKBLOX_OFF (BUTTON_REC|BUTTON_PLAY)
323 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
324 #define ROCKBLOX_ROTATE_CW BUTTON_DOWN
325 #define ROCKBLOX_DOWN BUTTON_REW
326 #define ROCKBLOX_LEFT BUTTON_LEFT
327 #define ROCKBLOX_RIGHT BUTTON_RIGHT
328 #define ROCKBLOX_DROP BUTTON_FFWD
329 #define ROCKBLOX_RESTART (BUTTON_REC|BUTTON_REW)
331 #elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
333 #define ROCKBLOX_OFF BUTTON_REC
334 #define ROCKBLOX_ROTATE_CCW BUTTON_PLAY
335 #define ROCKBLOX_ROTATE_CW BUTTON_MENU
336 #define ROCKBLOX_DOWN BUTTON_DOWN
337 #define ROCKBLOX_LEFT BUTTON_PREV
338 #define ROCKBLOX_RIGHT BUTTON_NEXT
339 #define ROCKBLOX_DROP BUTTON_OK
340 #define ROCKBLOX_RESTART BUTTON_CANCEL
342 #elif CONFIG_KEYPAD == MPIO_HD200_PAD
343 #define ROCKBLOX_OFF (BUTTON_REC|BUTTON_PLAY)
344 #define ROCKBLOX_ROTATE_CCW BUTTON_REW
345 #define ROCKBLOX_ROTATE_CW BUTTON_FF
346 #define ROCKBLOX_DOWN BUTTON_FUNC
347 #define ROCKBLOX_LEFT BUTTON_VOL_DOWN
348 #define ROCKBLOX_RIGHT BUTTON_VOL_UP
349 #define ROCKBLOX_DROP BUTTON_PLAY
350 #define ROCKBLOX_RESTART BUTTON_REC
352 #elif CONFIG_KEYPAD == MPIO_HD300_PAD
353 #define ROCKBLOX_OFF (BUTTON_MENU|BUTTON_REPEAT)
354 #define ROCKBLOX_ROTATE_CCW BUTTON_UP
355 #define ROCKBLOX_ROTATE_CW BUTTON_DOWN
356 #define ROCKBLOX_DOWN (BUTTON_ENTER | BUTTON_REL)
357 #define ROCKBLOX_LEFT BUTTON_REW
358 #define ROCKBLOX_RIGHT BUTTON_FF
359 #define ROCKBLOX_DROP BUTTON_PLAY
360 #define ROCKBLOX_RESTART BUTTON_REC
362 #elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
363 #define ROCKBLOX_OFF_PRE BUTTON_POWER
364 #define ROCKBLOX_OFF BUTTON_POWER|BUTTON_REL
365 #define ROCKBLOX_ROTATE_CW BUTTON_BOTTOMRIGHT
366 #define ROCKBLOX_ROTATE_CCW BUTTON_BOTTOMLEFT
367 #define ROCKBLOX_DOWN BUTTON_SELECT
368 #define ROCKBLOX_LEFT BUTTON_LEFT
369 #define ROCKBLOX_RIGHT BUTTON_RIGHT
370 #define ROCKBLOX_DROP_PRE BUTTON_DOWN
371 #define ROCKBLOX_DROP BUTTON_DOWN|BUTTON_REL
372 #define ROCKBLOX_RESTART BUTTON_BACK|BUTTON_REPEAT
373 #define ROCKBLOX_ROTATE_CCW2 BUTTON_VOL_UP
374 #define ROCKBLOX_ROTATE_CW2 BUTTON_VOL_DOWN
376 #elif CONFIG_KEYPAD == SANSA_CONNECT_PAD
377 #define ROCKBLOX_OFF BUTTON_POWER
378 #define ROCKBLOX_ROTATE_CW BUTTON_NEXT
379 #define ROCKBLOX_ROTATE_CCW BUTTON_PREV
380 #define ROCKBLOX_DOWN BUTTON_DOWN
381 #define ROCKBLOX_LEFT BUTTON_LEFT
382 #define ROCKBLOX_RIGHT BUTTON_RIGHT
383 #define ROCKBLOX_DROP BUTTON_SELECT
384 #define ROCKBLOX_RESTART BUTTON_VOL_DOWN
386 #elif CONFIG_KEYPAD == SAMSUNG_YPR0_PAD
388 #define ROCKBLOX_OFF BUTTON_BACK
389 #define ROCKBLOX_ROTATE_CCW BUTTON_POWER
390 #define ROCKBLOX_ROTATE_CW BUTTON_MENU
391 #define ROCKBLOX_ROTATE BUTTON_UP
392 #define ROCKBLOX_DOWN BUTTON_DOWN
393 #define ROCKBLOX_LEFT BUTTON_LEFT
394 #define ROCKBLOX_RIGHT BUTTON_RIGHT
395 #define ROCKBLOX_DROP BUTTON_SELECT
396 #define ROCKBLOX_RESTART BUTTON_USER
398 #elif CONFIG_KEYPAD == HM60X_PAD
400 #define ROCKBLOX_OFF BUTTON_POWER
401 #define ROCKBLOX_ROTATE_CCW (BUTTON_LEFT|BUTTON_POWER)
402 #define ROCKBLOX_ROTATE_CW (BUTTON_RIGHT|BUTTON_POWER)
403 #define ROCKBLOX_ROTATE BUTTON_UP
404 #define ROCKBLOX_DOWN BUTTON_DOWN
405 #define ROCKBLOX_LEFT BUTTON_LEFT
406 #define ROCKBLOX_RIGHT BUTTON_RIGHT
407 #define ROCKBLOX_DROP BUTTON_SELECT
408 #define ROCKBLOX_RESTART (BUTTON_DOWN|BUTTON_POWER)
410 #elif CONFIG_KEYPAD == HM801_PAD
412 #define ROCKBLOX_OFF BUTTON_POWER
413 #define ROCKBLOX_ROTATE_CCW BUTTON_PREV
414 #define ROCKBLOX_ROTATE_CW BUTTON_NEXT
415 #define ROCKBLOX_ROTATE BUTTON_UP
416 #define ROCKBLOX_DOWN BUTTON_DOWN
417 #define ROCKBLOX_LEFT BUTTON_LEFT
418 #define ROCKBLOX_RIGHT BUTTON_RIGHT
419 #define ROCKBLOX_DROP BUTTON_SELECT
420 #define ROCKBLOX_RESTART BUTTON_PLAY
422 #else
423 #error No keymap defined!
424 #endif
426 #ifdef HAVE_TOUCHSCREEN
427 #ifndef ROCKBLOX_OFF
428 #define ROCKBLOX_OFF BUTTON_TOPLEFT
429 #endif
430 #ifdef ROCKBLOX_ROTATE_CCW
431 #define ROCKBLOX_ROTATE_CCW2 BUTTON_BOTTOMLEFT
432 #else
433 #define ROCKBLOX_ROTATE_CCW BUTTON_BOTTOMLEFT
434 #endif
435 #ifdef ROCKBLOX_ROTATE_CW
436 #define ROCKBLOX_ROTATE_CW2 BUTTON_BOTTOMRIGHT
437 #else
438 #define ROCKBLOX_ROTATE_CW BUTTON_BOTTOMRIGHT
439 #define ROCKBLOX_ROTATE_CW2 BUTTON_TOPMIDDLE
440 #endif
441 #ifndef ROCKBLOX_DOWN
442 #define ROCKBLOX_DOWN BUTTON_BOTTOMMIDDLE
443 #endif
444 #ifndef ROCKBLOX_LEFT
445 #define ROCKBLOX_LEFT BUTTON_MIDLEFT
446 #endif
447 #ifndef ROCKBLOX_RIGHT
448 #define ROCKBLOX_RIGHT BUTTON_MIDRIGHT
449 #endif
450 #ifndef ROCKBLOX_DROP
451 #define ROCKBLOX_DROP BUTTON_CENTER
452 #endif
453 #ifndef ROCKBLOX_RESTART
454 #define ROCKBLOX_RESTART BUTTON_TOPRIGHT
455 #endif
456 #endif
458 #define BLOCKS_NUM 7
459 #define EMPTY_BLOCK 7
461 #define BOARD_WIDTH 10
463 #ifdef HAVE_LCD_BITMAP
465 #define BOARD_HEIGHT 20
467 #if (LCD_WIDTH == 640) && (LCD_HEIGHT == 480)
469 #define BLOCK_WIDTH 24
470 #define BLOCK_HEIGHT 24
471 #define BOARD_X 172
472 #define BOARD_Y 0
473 #define PREVIEW_X 24
474 #define PREVIEW_Y 22
475 #define LABEL_X 482
476 #define SCORE_Y 50
477 #define LEVEL_Y 140
478 #define LINES_Y 210
480 #elif (LCD_WIDTH == 480) && (LCD_HEIGHT == 640)
482 #define BLOCK_WIDTH 30
483 #define BLOCK_HEIGHT 30
484 #define BOARD_X 14
485 #define BOARD_Y 2
486 #define PREVIEW_X 342
487 #define PREVIEW_Y 482
488 #define LABEL_X 344
489 #define SCORE_Y 58
490 #define LEVEL_Y 142
491 #define LINES_Y 218
493 #elif (LCD_WIDTH == 320) && (LCD_HEIGHT == 240)
495 #define BLOCK_WIDTH 12
496 #define BLOCK_HEIGHT 12
497 #define BOARD_X 86
498 #define BOARD_Y 0
499 #define PREVIEW_X 12
500 #define PREVIEW_Y 11
501 #define LABEL_X 242
502 #define SCORE_Y 25
503 #define LEVEL_Y 70
504 #define LINES_Y 105
506 #elif (LCD_WIDTH == 240) && ((LCD_HEIGHT == 320) || (LCD_HEIGHT == 400))
508 #define BLOCK_WIDTH 15
509 #define BLOCK_HEIGHT 15
510 #define BOARD_X 7
511 #define BOARD_Y 1
512 #define PREVIEW_X 171
513 #define PREVIEW_Y 241
514 #define LABEL_X 172
515 #define SCORE_Y 29
516 #define LEVEL_Y 71
517 #define LINES_Y 109
518 #define HIGH_LABEL_X 172
519 #define HIGH_SCORE_Y 163
520 #define HIGH_LEVEL_Y 172
522 #elif (LCD_WIDTH == 220) && (LCD_HEIGHT == 176)
524 #define BLOCK_WIDTH 8
525 #define BLOCK_HEIGHT 8
526 #define BOARD_X 27
527 #define BOARD_Y 5
528 #define PREVIEW_X 158
529 #define PREVIEW_Y 130
530 #define LABEL_X 147
531 #define SCORE_Y 20
532 #define LEVEL_Y 65
533 #define LINES_Y 100
535 #elif (LCD_WIDTH == 176) && (LCD_HEIGHT == 132)
537 #define BLOCK_WIDTH 6
538 #define BLOCK_HEIGHT 6
539 #define BOARD_X 25
540 #define BOARD_Y 1
541 #define PREVIEW_X 126
542 #define PREVIEW_Y 102
543 #define LABEL_X 112
544 #define SCORE_Y 17
545 #define LEVEL_Y 49
546 #define LINES_Y 81
548 #elif (LCD_WIDTH == 176) && (LCD_HEIGHT == 220)
550 /* no room for the space in the highscore list */
551 #define _SPACE ""
553 #define BLOCK_WIDTH 10
554 #define BLOCK_HEIGHT 10
555 #define BOARD_X 6
556 #define BOARD_Y 10
557 #define PREVIEW_X 124
558 #define PREVIEW_Y 174
559 #define LABEL_X 117
560 #define SCORE_Y 18
561 #define LEVEL_Y 52
562 #define LINES_Y 85
563 #define HIGH_SCORE_Y 119
564 #define HIGH_LEVEL_Y 126
565 #define HIGH_LABEL_X 114
567 #elif (LCD_WIDTH == 160) && (LCD_HEIGHT == 128)
570 #define BLOCK_WIDTH 6
571 #define BLOCK_HEIGHT 6
572 #define BOARD_X 22
573 #define BOARD_Y 3
574 #define PREVIEW_X 114
575 #define PREVIEW_Y 100
576 #define LABEL_X 101
577 #define SCORE_Y 17
578 #define LEVEL_Y 49
579 #define LINES_Y 82
581 #elif (LCD_WIDTH == 138) && (LCD_HEIGHT == 110)
583 #define BLOCK_WIDTH 5
584 #define BLOCK_HEIGHT 5
585 #define BOARD_X 14
586 #define BOARD_Y 0
587 #define PREVIEW_X 98
588 #define PREVIEW_Y 88
589 #define LABEL_X 80
590 #define SCORE_Y 15
591 #define LEVEL_Y 45
592 #define LINES_Y 74
594 #elif (LCD_WIDTH == 132) && (LCD_HEIGHT == 80)
596 #define BLOCK_WIDTH 4
597 #define BLOCK_HEIGHT 4
598 #define BOARD_X 10
599 #define BOARD_Y 0
600 #define PREVIEW_X 89
601 #define PREVIEW_Y 61
602 #define LABEL_X 78
603 #define SCORE_Y 10
604 #define LEVEL_Y 30
605 #define LINES_Y 50
607 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 128)
609 #define BLOCK_WIDTH 6
610 #define BLOCK_HEIGHT 6
611 #define BOARD_X 4
612 #define BOARD_Y 3
613 #define PREVIEW_X 84
614 #define PREVIEW_Y 100
615 #define LABEL_X 71
616 #define SCORE_Y 17
617 #define LEVEL_Y 49
618 #define LINES_Y 82
620 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 160)
622 #define BLOCK_WIDTH 7
623 #define BLOCK_HEIGHT 7
624 #define BOARD_X 4
625 #define BOARD_Y 5
626 #define PREVIEW_X 88
627 #define PREVIEW_Y 111
628 #define LABEL_X 82
629 #define SCORE_Y (2+16)
630 #define LEVEL_Y (36+16)
631 #define LINES_Y (70+16)
633 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 96)
635 #define BLOCK_WIDTH 4
636 #define BLOCK_HEIGHT 4
637 #define BOARD_X 14
638 #define BOARD_Y 2
639 #define PREVIEW_X 89
640 #define PREVIEW_Y 76
641 #define LABEL_X 70
642 #define SCORE_Y 14
643 #define LEVEL_Y 39
644 #define LINES_Y 64
646 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 64)
648 #define BLOCK_WIDTH 3
649 #define BLOCK_HEIGHT 3
650 #define BOARD_X 9
651 #define BOARD_Y 3
652 #define PREVIEW_X 53
653 #define PREVIEW_Y 5
654 #define LABEL_X 70
655 #define SCORE_Y 32
656 #define LEVEL_Y 13
657 #define LINES_Y 51
659 #elif (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
661 #define BLOCK_WIDTH 4
662 #define BLOCK_HEIGHT 3
663 #define BOARD_X 9
664 #define BOARD_Y 3
665 #define PREVIEW_X 59
666 #define PREVIEW_Y 5
667 #define LABEL_X 59
668 #define SCORE_Y 32
669 #define LEVEL_Y 13
670 #define LEVEL_X 78
671 #define LINES_Y 51
673 #elif (LCD_WIDTH == 96) && (LCD_HEIGHT == 96)
675 #define BLOCK_WIDTH 4
676 #define BLOCK_HEIGHT 4
677 #define BOARD_X 5
678 #define BOARD_Y 4
679 #define PREVIEW_X 64
680 #define PREVIEW_Y 76
681 #define LABEL_X 59
682 #define SCORE_Y 15
683 #define SCORE_X 58
684 #define LEVEL_Y 39
685 #define LEVEL_X 58
686 #define LINES_Y 62
687 #define LINES_X 58
688 #endif
690 #ifndef LEVEL_X
691 #define LEVEL_X LABEL_X
692 #endif
694 #ifndef LINES_X
695 #define LINES_X LABEL_X
696 #endif
698 extern const fb_data rockblox_background[];
700 #else /* HAVE_LCD_CHARCELLS */
702 #define BOARD_HEIGHT 14
704 #define BLOCK_WIDTH 1
705 #define BLOCK_HEIGHT 1
706 #define BOARD_X 5
707 #define BOARD_Y 0
708 #define PREVIEW_X 15
709 #define PREVIEW_Y 1
711 #endif
713 #ifndef _SPACE
714 #define _SPACE " "
715 #endif
716 /* <<Explanation on Rockblox shapes>>
719 %% - O has 1 orientation
721 %% %
722 %% %% - Z has 2 orientations
725 %% %
726 %% %% - S has 2 orientations
730 % %%%% - I has 2 orientations
733 % %%
734 % % % %%% - L has 4 orientations
735 %% %%% % %
737 % %%
738 % % % %%% - J has 4 orientations
739 %% %%% % %
741 % % %%%
742 %% % %% % - T has 4 orientations
743 % %%% %
746 /* c=current f=figure o=orientation n=next */
747 static struct _rockblox_status
749 int gameover;
750 int lines;
751 int level;
752 int score;
753 int cx;
754 int cy;
755 int cf;
756 int co;
757 int nf;
758 short board[BOARD_HEIGHT][BOARD_WIDTH]; /* 20 rows of 10 blocks */
759 } rockblox_status;
761 /* prototypes */
762 static void draw_next_block(void);
763 static void new_block(void);
765 #ifdef HAVE_SCROLLWHEEL
766 int wheel_events = 0, last_wheel_event = 0;
767 bool wheel_enabled = false;
768 #endif
770 static const short scoring[4] = { /* scoring for each number of lines */
771 #if BOARD_HEIGHT == 20
772 40 /* single */ , 100 /* double */ , 300 /* triple */ , 1200 /* rockblox */
773 #elif BOARD_HEIGHT == 14 /* Player special values */
774 60 /* single */ , 150 /* double */ , 500 /* triple */ , 2000 /* rockblox */
775 #endif
778 struct figure
780 #if LCD_DEPTH >= 2
781 unsigned short color[3]; /* color of figure (light,middle,shadow) */
782 #endif
783 unsigned short max_or; /* max orientations */
784 signed short shapeX[4], shapeY[4]; /* implementation of figures */
787 /* array of figures */
788 figures[BLOCKS_NUM] = {
789 /* O */
791 #if LCD_DEPTH >= 16
792 {LCD_RGBPACK (153, 255, 255), LCD_RGBPACK(0, 255, 255),
793 LCD_RGBPACK(0,153,153)},
794 #elif LCD_DEPTH == 2
795 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
796 #endif
798 {-1, 0, -1, 0},
799 {0, 0, 1, 1}
801 /* I */
803 #if LCD_DEPTH >= 16
804 {LCD_RGBPACK (255, 153, 128), LCD_RGBPACK (255, 0, 0),
805 LCD_RGBPACK (153, 0, 0)},
806 #elif LCD_DEPTH == 2
807 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
808 #endif
810 {-2, -1, 0, 1},
811 {0, 0, 0, 0}
813 /* 'Z' */
815 #if LCD_DEPTH >= 16
816 {LCD_RGBPACK (153, 255, 153), LCD_RGBPACK (0, 255, 0),
817 LCD_RGBPACK (0, 153, 0)},
818 #elif LCD_DEPTH == 2
819 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
820 #endif
822 {0, 1, -1, 0},
823 {0, 0, 1, 1}
825 /* 'S' */
827 #if LCD_DEPTH >= 16
828 {LCD_RGBPACK (153, 153, 255), LCD_RGBPACK (0, 0, 255),
829 LCD_RGBPACK (0, 0, 153)},
830 #elif LCD_DEPTH == 2
831 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
832 #endif
834 {-1, 0, 0, 1},
835 {0, 0, 1, 1}
837 /* 'L' */
839 #if LCD_DEPTH >= 16
840 {LCD_RGBPACK (255, 255, 153), LCD_RGBPACK (255, 255, 0),
841 LCD_RGBPACK (153, 153, 0)},
842 #elif LCD_DEPTH == 2
843 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
844 #endif
846 {-1, 0, 1, 1},
847 {0, 0, 0, 1}
849 /* 'J' */
851 #if LCD_DEPTH >= 16
852 {LCD_RGBPACK (255, 153, 255), LCD_RGBPACK (255, 0, 255),
853 LCD_RGBPACK (153, 0, 153)},
854 #elif LCD_DEPTH == 2
855 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
856 #endif
858 {-1, 0, 1, -1},
859 {0, 0, 0, 1}
861 /* 'T' */
863 #if LCD_DEPTH >= 16
864 {LCD_RGBPACK (204, 204, 204), LCD_RGBPACK (153, 153, 153),
865 LCD_RGBPACK (85, 85, 85)},
866 #elif LCD_DEPTH == 2
867 {LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
868 #endif
870 {-1, 0, 1, 0},
871 {0, 0, 0, 1}
874 bool resume = false;
875 bool resume_file = false;
877 /* Rockbox File System only supports full filenames inc dir */
878 #define SCORE_FILE PLUGIN_GAMES_DATA_DIR "/rockblox.score"
879 #define RESUME_FILE PLUGIN_GAMES_DATA_DIR "/rockblox.resume"
880 #define NUM_SCORES 5
882 /* Default High Scores... */
883 struct highscore highscores[NUM_SCORES];
885 /* get random number from (0) to (range-1) */
886 static int t_rand (int range)
888 return rb->rand () % range;
891 static inline void show_game_over (void)
893 rb->splash(HZ,"Game over!");
896 /* init the board array to have no blocks */
897 static void init_board (void)
899 int i, j;
900 for (i = 0; i < BOARD_WIDTH; i++)
901 for (j = 0; j < BOARD_HEIGHT; j++)
902 rockblox_status.board[j][i] = EMPTY_BLOCK;
905 /* show the score, level and lines */
906 static void show_details (void)
908 #ifdef HAVE_LCD_BITMAP
909 #if LCD_DEPTH >= 2
910 rb->lcd_set_foreground (LCD_BLACK);
911 rb->lcd_set_background (LCD_WHITE);
912 #endif
913 rb->lcd_putsxyf (LABEL_X, SCORE_Y, "%d", rockblox_status.score);
914 rb->lcd_putsxyf (LEVEL_X, LEVEL_Y, "%d", rockblox_status.level);
915 rb->lcd_putsxyf (LINES_X, LINES_Y, "%d", rockblox_status.lines);
916 #else /* HAVE_LCD_CHARCELLS */
917 rb->lcd_putsf (5, 0, "L%d/%d", rockblox_status.level,
918 rockblox_status.lines);
919 rb->lcd_putsf (5, 1, "S%d", rockblox_status.score);
920 #endif
923 #ifdef HIGH_SCORE_Y
924 static void show_highscores (void)
926 int i;
928 for (i = 0; i<NUM_SCORES; i++)
929 rb->lcd_putsxyf (HIGH_LABEL_X, HIGH_SCORE_Y + (10 * i),
930 "%06d" _SPACE "L%1d", highscores[i].score, highscores[i].level);
932 #endif
934 static void load_game(void)
936 int fd;
938 resume = false;
940 fd = rb->open(RESUME_FILE, O_RDONLY);
941 if (fd < 0) return;
943 if (rb->read(fd, &rockblox_status, sizeof(struct _rockblox_status))
944 < (ssize_t)sizeof(struct _rockblox_status))
946 rb->splash(HZ/2, "Loading Rockblox resume info failed");
947 } else {
948 resume = true;
951 rb->close(fd);
953 return;
956 static void dump_resume(void)
958 int fd;
960 fd = rb->open(RESUME_FILE, O_WRONLY|O_CREAT, 0666);
961 if (fd < 0)
962 goto fail;
964 if (rb->write(fd, &rockblox_status, sizeof(struct _rockblox_status))
965 <= 0)
967 rb->close(fd);
968 goto fail;
970 rb->close(fd);
971 return;
973 fail:
974 rb->splash(HZ/2, "Writing Rockblox resume info failed");
975 return;
978 static void init_rockblox (bool resume)
980 char score_name[50];
981 struct tm* tm;
983 tm = rb->get_time();
984 rb->snprintf(score_name, sizeof(score_name), "%04d%02d%02d %02d%02d%02d",
985 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
986 tm->tm_hour, tm->tm_min, tm->tm_sec);
988 #ifdef HAVE_LCD_BITMAP
989 rb->lcd_bitmap (rockblox_background, 0, 0, LCD_WIDTH, LCD_HEIGHT);
990 #else /* HAVE_LCD_CHARCELLS */
991 pgfx_display (0, 0);
992 pgfx_display_block (3, 0, 3, 1);
993 pgfx_display_block (4, 0, 3, 0);
994 rb->lcd_puts(4, 1, " ");
995 pgfx_clear_display();
996 pgfx_fillrect (3, 0, 2, 14);
997 pgfx_fillrect (15, 7, 2, 7);
998 pgfx_update();
999 #endif
1000 if (!resume)
1002 rockblox_status.level = 1;
1003 rockblox_status.lines = 0;
1004 rockblox_status.score = 0;
1005 rockblox_status.nf = t_rand(BLOCKS_NUM);
1006 init_board ();
1007 new_block ();
1009 draw_next_block();
1011 show_details ();
1012 #ifdef HIGH_SCORE_Y
1013 show_highscores ();
1014 #endif
1017 static inline int level_speed(int level)
1019 #if BOARD_HEIGHT == 20
1020 return (5*HZ) / (level + 9);
1021 #elif BOARD_HEIGHT == 14
1022 return (7*HZ) / (level + 9);
1023 #endif
1026 static int getRelativeX (int figure, int square, int orientation)
1028 switch (orientation) {
1029 case 0:
1030 return figures[figure].shapeX[square];
1031 case 1:
1032 return figures[figure].shapeY[square];
1033 case 2:
1034 return -figures[figure].shapeX[square];
1035 case 3:
1036 return -figures[figure].shapeY[square];
1037 default:
1038 return 0;
1042 static int getRelativeY (int figure, int square, int orientation)
1044 switch (orientation) {
1045 case 0:
1046 return figures[figure].shapeY[square];
1047 case 1:
1048 return -figures[figure].shapeX[square];
1049 case 2:
1050 return -figures[figure].shapeY[square];
1051 case 3:
1052 return figures[figure].shapeX[square];
1053 default:
1054 return 0;
1058 /* redraw the while board on the screen */
1059 static void refresh_board (void)
1061 int i, j, x, y, block;
1063 #if LCD_DEPTH >= 2
1064 rb->lcd_set_foreground (LCD_BLACK);
1065 #elif LCD_DEPTH == 1
1066 mylcd_set_drawmode (DRMODE_SOLID | DRMODE_INVERSEVID);
1067 #endif
1069 mylcd_fillrect (BOARD_X, BOARD_Y, BOARD_WIDTH * BLOCK_WIDTH,
1070 BOARD_HEIGHT * BLOCK_HEIGHT);
1072 #if LCD_DEPTH == 1
1073 mylcd_set_drawmode (DRMODE_SOLID);
1074 #endif
1076 for (i = 0; i < BOARD_WIDTH; i++)
1077 for (j = 0; j < BOARD_HEIGHT; j++) {
1078 block = rockblox_status.board[j][i];
1079 if (block != EMPTY_BLOCK) {
1080 #ifdef HAVE_LCD_BITMAP
1081 #if LCD_DEPTH >= 2
1082 /* middle drawing */
1083 rb->lcd_set_foreground (figures[block].color[1]);
1084 #endif
1085 rb->lcd_fillrect (BOARD_X + i * BLOCK_WIDTH,
1086 BOARD_Y + j * BLOCK_HEIGHT,
1087 BLOCK_WIDTH, BLOCK_HEIGHT);
1088 #if LCD_DEPTH >= 2
1089 /* light drawing */
1090 rb->lcd_set_foreground (figures[block].color[0]);
1091 #endif
1092 rb->lcd_vline (BOARD_X + i * BLOCK_WIDTH,
1093 BOARD_Y + j * BLOCK_HEIGHT,
1094 BOARD_Y + (j + 1) * BLOCK_HEIGHT - 2);
1095 rb->lcd_hline (BOARD_X + i * BLOCK_WIDTH,
1096 BOARD_X + (i + 1) * BLOCK_WIDTH - 2,
1097 BOARD_Y + j * BLOCK_HEIGHT);
1098 #if LCD_DEPTH >= 2
1099 /* shadow drawing */
1100 rb->lcd_set_foreground (figures[block].color[2]);
1101 #endif
1102 rb->lcd_vline (BOARD_X + (i + 1) * BLOCK_WIDTH - 1,
1103 BOARD_Y + j * BLOCK_HEIGHT + 1,
1104 BOARD_Y + (j + 1) * BLOCK_HEIGHT - 1);
1105 rb->lcd_hline (BOARD_X + i * BLOCK_WIDTH + 1,
1106 BOARD_X + (i + 1) * BLOCK_WIDTH - 1,
1107 BOARD_Y + (j + 1) * BLOCK_HEIGHT - 1);
1108 #else /* HAVE_LCD_CHARCELLS */
1109 pgfx_drawpixel (BOARD_X + i, BOARD_Y + j);
1110 #endif
1114 for (i = 0; i < 4; i++) {
1115 x = getRelativeX (rockblox_status.cf, i, rockblox_status.co)
1116 + rockblox_status.cx;
1117 y = getRelativeY (rockblox_status.cf, i, rockblox_status.co)
1118 + rockblox_status.cy;
1119 #ifdef HAVE_LCD_BITMAP
1120 #if LCD_DEPTH >= 2
1121 /* middle drawing */
1122 rb->lcd_set_foreground (figures[rockblox_status.cf].color[1]);
1123 #endif
1124 rb->lcd_fillrect (BOARD_X + x * BLOCK_WIDTH,
1125 BOARD_Y + y * BLOCK_HEIGHT,
1126 BLOCK_WIDTH, BLOCK_HEIGHT);
1127 #if LCD_DEPTH >= 2
1128 /* light drawing */
1129 rb->lcd_set_foreground (figures[rockblox_status.cf].color[0]);
1130 #endif
1131 rb->lcd_vline (BOARD_X + x * BLOCK_WIDTH, BOARD_Y + y * BLOCK_HEIGHT,
1132 BOARD_Y + (y + 1) * BLOCK_HEIGHT - 2);
1133 rb->lcd_hline (BOARD_X + x * BLOCK_WIDTH,
1134 BOARD_X + (x + 1) * BLOCK_WIDTH - 2,
1135 BOARD_Y + y * BLOCK_HEIGHT);
1136 #if LCD_DEPTH >= 2
1137 /* shadow drawing */
1138 rb->lcd_set_foreground (figures[rockblox_status.cf].color[2]);
1139 #endif
1140 rb->lcd_vline (BOARD_X + (x + 1) * BLOCK_WIDTH - 1,
1141 BOARD_Y + y * BLOCK_HEIGHT + 1,
1142 BOARD_Y + (y + 1) * BLOCK_HEIGHT - 1);
1143 rb->lcd_hline (BOARD_X + x * BLOCK_WIDTH + 1,
1144 BOARD_X + (x + 1) * BLOCK_WIDTH - 1,
1145 BOARD_Y + (y + 1) * BLOCK_HEIGHT - 1);
1146 #else /* HAVE_LCD_CHARCELLS */
1147 pgfx_drawpixel (BOARD_X + x, BOARD_Y + y);
1148 #endif
1150 mylcd_update ();
1153 static bool canMoveTo (int x, int y, int newOrientation)
1155 int i, rx, ry;
1156 for (i = 0; i < 4; i++) {
1157 ry = getRelativeY (rockblox_status.cf, i, newOrientation) + y;
1158 rx = getRelativeX (rockblox_status.cf, i, newOrientation) + x;
1159 if ((rx < 0 || rx >= BOARD_WIDTH) ||
1160 (ry < 0 || ry >= BOARD_HEIGHT) ||
1161 (rockblox_status.board[ry][rx] != EMPTY_BLOCK))
1162 return false;
1164 return true;
1167 /* draws the preview of next block in the preview window */
1168 static void draw_next_block (void)
1170 int i, rx, ry;
1171 /* clear preview window first */
1172 #if LCD_DEPTH >= 2
1173 rb->lcd_set_foreground (LCD_BLACK);
1174 #elif LCD_DEPTH == 1
1175 mylcd_set_drawmode (DRMODE_SOLID | DRMODE_INVERSEVID);
1176 #endif
1178 /* 4x4 */
1179 mylcd_fillrect (PREVIEW_X, PREVIEW_Y, BLOCK_WIDTH * 4, BLOCK_HEIGHT * 4);
1181 #if LCD_DEPTH == 1
1182 mylcd_set_drawmode (DRMODE_SOLID);
1183 #endif
1185 /* draw the lightgray rectangles */
1186 #if LCD_DEPTH >= 16
1187 rb->lcd_set_foreground (LCD_RGBPACK (40, 40, 40));
1188 #elif LCD_DEPTH == 2
1189 rb->lcd_set_foreground (LCD_DARKGRAY);
1190 #endif
1192 #if LCD_DEPTH >= 2
1193 for (rx = 0; rx < 4; rx++)
1194 for (ry = 0; ry < 4; ry++)
1195 rb->lcd_drawrect (PREVIEW_X + rx * BLOCK_WIDTH,
1196 PREVIEW_Y + ry * BLOCK_HEIGHT, BLOCK_WIDTH,
1197 BLOCK_HEIGHT);
1198 #endif
1200 /* draw the figure */
1201 for (i = 0; i < 4; i++) {
1202 rx = getRelativeX (rockblox_status.nf, i, 0) + 2;
1203 ry = getRelativeY (rockblox_status.nf, i, 0) + 2;
1204 #ifdef HAVE_LCD_BITMAP
1205 #if LCD_DEPTH >= 2
1206 rb->lcd_set_foreground (figures[rockblox_status.nf].color[1]); /* middle drawing */
1207 #endif
1208 rb->lcd_fillrect (PREVIEW_X + rx * BLOCK_WIDTH,
1209 PREVIEW_Y + ry * BLOCK_HEIGHT,
1210 BLOCK_WIDTH, BLOCK_HEIGHT);
1211 #if LCD_DEPTH >= 2
1212 rb->lcd_set_foreground (figures[rockblox_status.nf].color[0]); /* light drawing */
1213 #endif
1214 rb->lcd_vline (PREVIEW_X + rx * BLOCK_WIDTH,
1215 PREVIEW_Y + ry * BLOCK_HEIGHT,
1216 PREVIEW_Y + (ry + 1) * BLOCK_HEIGHT - 2);
1217 rb->lcd_hline (PREVIEW_X + rx * BLOCK_WIDTH,
1218 PREVIEW_X + (rx + 1) * BLOCK_WIDTH - 2,
1219 PREVIEW_Y + ry * BLOCK_HEIGHT);
1220 #if LCD_DEPTH >= 2
1221 rb->lcd_set_foreground (figures[rockblox_status.nf].color[2]); /* shadow drawing */
1222 #endif
1223 rb->lcd_vline (PREVIEW_X + (rx + 1) * BLOCK_WIDTH - 1,
1224 PREVIEW_Y + ry * BLOCK_HEIGHT + 1,
1225 PREVIEW_Y + (ry + 1) * BLOCK_HEIGHT - 1);
1226 rb->lcd_hline (PREVIEW_X + rx * BLOCK_WIDTH + 1,
1227 PREVIEW_X + (rx + 1) * BLOCK_WIDTH - 1,
1228 PREVIEW_Y + (ry + 1) * BLOCK_HEIGHT - 1);
1229 #else /* HAVE_LCD_CHARCELLS */
1230 pgfx_drawpixel (PREVIEW_X + rx, PREVIEW_Y + ry);
1231 #endif
1236 /* move the block to a relative location */
1237 static void move_block (int x, int y, int o)
1239 if (canMoveTo (rockblox_status.cx + x, rockblox_status.cy + y, o)) {
1240 rockblox_status.cy += y;
1241 rockblox_status.cx += x;
1242 rockblox_status.co = o;
1246 /* try to add a new block to play with (return true if gameover) */
1247 static void new_block (void)
1249 rockblox_status.cy = 1;
1250 rockblox_status.cx = 5;
1251 rockblox_status.cf = rockblox_status.nf;
1252 rockblox_status.co = 0; /* start at the same orientation all time */
1253 rockblox_status.nf = t_rand (BLOCKS_NUM);
1254 rockblox_status.gameover = !canMoveTo (rockblox_status.cx,
1255 rockblox_status.cy, rockblox_status.co);
1257 draw_next_block ();
1261 /* check for filled rockblox_status.lines and do what necessary */
1262 static int check_lines (void)
1265 int i, j, y;
1266 int rockblox = 0;
1268 for (j = 0; j < BOARD_HEIGHT; j++) {
1269 for (i = 0; ((i < BOARD_WIDTH) &&
1270 (rockblox_status.board[j][i] != EMPTY_BLOCK)); i++);
1271 if (i == BOARD_WIDTH) { /* woo hoo, we have a line */
1272 rockblox++;
1273 for (y = j; y > 0; y--)
1275 for (i = 0; i < BOARD_WIDTH; i++)
1276 { /* fall line */
1277 rockblox_status.board[y][i] = rockblox_status.board[y - 1][i];
1283 return rockblox;
1286 /* moves down the figure and returns true if gameover */
1287 static void move_down (void)
1289 int l, i, rx, ry;
1291 if (!canMoveTo (rockblox_status.cx, rockblox_status.cy + 1, rockblox_status.co)) {
1292 /* save figure to board */
1293 for (i = 0; i < 4; i++) {
1294 rx = getRelativeX (rockblox_status.cf, i, rockblox_status.co) + rockblox_status.cx;
1295 ry = getRelativeY (rockblox_status.cf, i, rockblox_status.co) + rockblox_status.cy;
1296 rockblox_status.board[ry][rx] = rockblox_status.cf;
1298 /* check if formed some lines */
1299 l = check_lines ();
1300 if (l) {
1301 /* the original scoring from "http://en.wikipedia.org/wiki/Rockblox" */
1302 rockblox_status.score += scoring[l - 1] * rockblox_status.level;
1303 rockblox_status.lines += l;
1304 rockblox_status.level = (int) rockblox_status.lines / 10 + 1;
1307 /* show details */
1308 show_details ();
1310 /* generate a new figure */
1311 new_block ();
1312 } else
1313 move_block (0, 1, rockblox_status.co);
1316 static bool rockblox_help(void)
1318 static char *help_text[] = {
1319 "Rockblox", "", "Aim", "",
1320 "Make", "the", "falling", "blocks", "of",
1321 "different", "shapes", "form", "full", "rows.",
1322 "Whenever", "a", "row", "is", "completed,",
1323 "it", "will", "be", "cleared", "away",
1324 "and", "you", "gain", "points."
1326 static struct style_text formation[]={
1327 { 0, TEXT_CENTER|TEXT_UNDERLINE },
1328 { 2, C_RED },
1329 LAST_STYLE_ITEM
1332 #ifdef HAVE_LCD_BITMAP
1333 rb->lcd_setfont(FONT_UI);
1334 #endif
1335 #ifdef HAVE_LCD_COLOR
1336 rb->lcd_set_background(LCD_BLACK);
1337 rb->lcd_set_foreground(LCD_WHITE);
1338 #endif
1339 if (display_text(ARRAYLEN(help_text), help_text, formation, NULL, true))
1340 return true;
1341 #ifdef HAVE_LCD_BITMAP
1342 rb->lcd_setfont(FONT_SYSFIXED);
1343 #endif
1345 return false;
1348 static int rockblox_menu_cb(int action, const struct menu_item_ex *this_item)
1350 int i = ((intptr_t)this_item);
1351 if(action == ACTION_REQUEST_MENUITEM
1352 && !resume && (i==0 || i==5))
1353 return ACTION_EXIT_MENUITEM;
1354 return action;
1357 static int rockblox_menu(void)
1359 int selected = 0;
1361 MENUITEM_STRINGLIST(main_menu, "Rockblox Menu", rockblox_menu_cb,
1362 "Resume Game", "Start New Game",
1363 "Help", "High Scores", "Playback Control",
1364 "Quit without Saving", "Quit");
1366 rb->button_clear_queue();
1367 while (true) {
1368 switch (rb->do_menu(&main_menu, &selected, NULL, false)) {
1369 case 0:
1370 if(resume_file)
1371 rb->remove(RESUME_FILE);
1372 init_rockblox(true);
1373 return 0;
1374 case 1:
1375 init_rockblox(false);
1376 return 0;
1377 case 2:
1378 if (rockblox_help())
1379 return 1;
1380 break;
1381 case 3:
1382 highscore_show(-1, highscores, NUM_SCORES, true);
1383 break;
1384 case 4:
1385 if (playback_control(NULL))
1386 return 1;
1387 break;
1388 case 5:
1389 return 1;
1390 case 6:
1391 if (resume) {
1392 rb->splash(HZ*1, "Saving game ...");
1393 dump_resume();
1395 return 1;
1396 case MENU_ATTACHED_USB:
1397 return 1;
1398 default:
1399 return 1;
1400 break;
1406 static int rockblox_loop (void)
1408 int button;
1409 #if defined(ROCKBLOX_OFF_PRE) || defined(ROCKBLOX_DROP_PRE)
1410 int lastbutton = BUTTON_NONE;
1411 #endif
1412 long next_down_tick = *rb->current_tick + level_speed(rockblox_status.level);
1414 if (rockblox_menu()) {
1415 return 1;
1417 resume = false;
1418 resume_file = false;
1420 while (1) {
1421 #ifdef HAS_BUTTON_HOLD
1422 if (rb->button_hold ()) {
1423 /* Turn on backlight timeout (revert to settings) */
1424 backlight_use_settings();
1425 rb->splash(0, "Paused");
1426 while (rb->button_hold ())
1427 rb->sleep(HZ/10);
1429 /* Turn off backlight timeout */
1430 backlight_ignore_timeout();
1432 /* get rid of the splash text */
1433 rb->lcd_bitmap (rockblox_background, 0, 0, LCD_WIDTH, LCD_HEIGHT);
1434 show_details ();
1435 #ifdef HIGH_SCORE_Y
1436 show_highscores ();
1437 #endif
1438 draw_next_block ();
1439 refresh_board ();
1441 #endif
1443 button = rb->button_get_w_tmo (MAX(next_down_tick - *rb->current_tick, 1));
1444 switch (button) {
1445 #ifdef ROCKBLOX_RC_OFF
1446 case ROCKBLOX_RC_OFF:
1447 #endif
1448 case ROCKBLOX_OFF:
1449 #ifdef ROCKBLOX_OFF_PRE
1450 if (lastbutton != ROCKBLOX_OFF_PRE)
1451 break;
1452 #endif
1453 resume = true;
1454 return 0;
1455 break;
1457 #if defined(ROCKBLOX_ROTATE)
1458 case ROCKBLOX_ROTATE:
1459 #endif
1460 case ROCKBLOX_ROTATE_CCW:
1461 case ROCKBLOX_ROTATE_CCW | BUTTON_REPEAT:
1462 #ifdef HAVE_SCROLLWHEEL
1463 /* if the wheel is disabled, add an event to the stack. */
1464 if(wheel_enabled == false)
1465 wheel_events++;
1467 /* if it's enabled, go ahead and rotate.. */
1468 if(wheel_enabled)
1469 #endif
1470 #ifdef ROCKBLOX_ROTATE_CCW2
1471 /* fallback */
1472 case ROCKBLOX_ROTATE_CCW2:
1473 #endif
1474 move_block (0, 0, (rockblox_status.co + 1) % figures[rockblox_status.cf].max_or);
1475 break;
1477 case ROCKBLOX_ROTATE_CW:
1478 case ROCKBLOX_ROTATE_CW | BUTTON_REPEAT:
1479 #ifdef HAVE_SCROLLWHEEL
1480 if(wheel_enabled == false)
1481 wheel_events++;
1483 if(wheel_enabled)
1484 #endif
1485 #ifdef ROCKBLOX_ROTATE_CW2
1486 /* fallback */
1487 case ROCKBLOX_ROTATE_CW2:
1488 #endif
1489 move_block (0, 0,
1490 (rockblox_status.co + figures[rockblox_status.cf].max_or -
1491 1) % figures[rockblox_status.cf].max_or);
1492 break;
1494 case ROCKBLOX_DOWN:
1495 case ROCKBLOX_DOWN | BUTTON_REPEAT:
1496 move_block (0, 1, rockblox_status.co);
1497 break;
1499 case ROCKBLOX_RIGHT:
1500 case ROCKBLOX_RIGHT | BUTTON_REPEAT:
1501 move_block (1, 0, rockblox_status.co);
1502 break;
1504 case ROCKBLOX_LEFT:
1505 case ROCKBLOX_LEFT | BUTTON_REPEAT:
1506 move_block (-1, 0, rockblox_status.co);
1507 break;
1509 case ROCKBLOX_DROP:
1510 #ifdef ROCKBLOX_DROP_PRE
1511 if (lastbutton != ROCKBLOX_DROP_PRE)
1512 break;
1513 #endif
1514 while (canMoveTo (rockblox_status.cx, rockblox_status.cy + 1, rockblox_status.co))
1515 move_block (0, 1, rockblox_status.co);
1516 break;
1517 #ifdef ROCKBLOX_RESTART
1518 case ROCKBLOX_RESTART:
1519 rb->splash (HZ * 1, "Restarting...");
1520 init_rockblox (false);
1521 break;
1522 #endif
1524 default:
1525 if (rb->default_event_handler (button) == SYS_USB_CONNECTED)
1526 return PLUGIN_USB_CONNECTED;
1527 break;
1529 #if defined(ROCKBLOX_OFF_PRE) || defined(ROCKBLOX_DROP_PRE)
1530 if (button != BUTTON_NONE)
1531 lastbutton = button;
1532 #endif
1534 #ifdef HAVE_SCROLLWHEEL
1535 /* check if we should enable the scroll wheel, if events
1536 * begin to stack up... */
1537 if(wheel_enabled == false)
1539 /* stopped rotating the wheel, reset the count */
1540 if(wheel_events == last_wheel_event)
1542 last_wheel_event = 0;
1543 wheel_events = 0;
1545 /* rotated the wheel a while constantly, enable it. */
1546 else if(wheel_events > 3)
1548 wheel_enabled = true;
1551 /* this evens out the last event and the "current" event.
1552 * if we get an event next time through button reading, it will
1553 * remain ahead of last_event. if we don't, they'll end up equaling
1554 * each other.. thus, the scroll count will be reset. */
1555 if(wheel_enabled == false && wheel_events > last_wheel_event)
1556 last_wheel_event++;
1558 #endif
1560 if (TIME_AFTER(*rb->current_tick, next_down_tick)) {
1561 move_down ();
1562 next_down_tick += level_speed(rockblox_status.level);
1563 if (TIME_AFTER(*rb->current_tick, next_down_tick))
1564 /* restart time "raster" when we had to wait longer than usual
1565 * (pause, game restart etc) */
1566 next_down_tick = *rb->current_tick + level_speed(rockblox_status.level);
1569 if (rockblox_status.gameover) {
1570 #if LCD_DEPTH >= 2
1571 rb->lcd_set_foreground (LCD_BLACK);
1572 #endif
1573 show_game_over();
1574 resume = false;
1575 return 0;
1578 refresh_board ();
1581 return 0;
1584 enum plugin_status plugin_start (const void *parameter)
1587 (void) parameter;
1589 rb->srand (*rb->current_tick);
1591 /* Load HighScore if any */
1592 highscore_load(SCORE_FILE, highscores, NUM_SCORES);
1594 #if LCD_DEPTH > 1
1595 rb->lcd_set_backdrop(NULL);
1596 #endif
1598 #ifdef HAVE_LCD_BITMAP
1599 rb->lcd_setfont (FONT_SYSFIXED);
1600 #else
1601 if (!pgfx_init(4, 2))
1603 rb->splash(HZ*2, "Old LCD :(");
1604 return PLUGIN_OK;
1606 #endif
1607 /* Turn off backlight timeout */
1608 backlight_ignore_timeout();
1609 load_game();
1610 resume_file = resume;
1611 while(!rockblox_loop()) {
1612 if(!resume) {
1613 int position = highscore_update(rockblox_status.score,
1614 rockblox_status.level, "",
1615 highscores, NUM_SCORES);
1616 if (position != -1) {
1617 if (position == 0)
1618 rb->splash(HZ*2, "New High Score");
1619 highscore_show(position, highscores, NUM_SCORES, true);
1624 #ifndef HAVE_LCD_BITMAP
1625 pgfx_release();
1626 #endif
1627 /* Save user's HighScore */
1628 highscore_save(SCORE_FILE, highscores, NUM_SCORES);
1629 backlight_use_settings();
1631 return PLUGIN_OK;