1 /*****************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// __ \_/ ___\| |/ /| __ \ / __ \ \/ /
5 * Jukebox | | ( (__) ) \___| ( | \_\ ( (__) ) (
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 - 2008 Alexander Papst
11 * Idea from http://www.tetris1d.org
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
19 ****************************************************************************/
25 #ifdef HAVE_LCD_BITMAP
27 #if CONFIG_KEYPAD == RECORDER_PAD
28 #define ONEDROCKBLOX_DOWN BUTTON_PLAY
29 #define ONEDROCKBLOX_QUIT BUTTON_OFF
31 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
32 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
33 #define ONEDROCKBLOX_QUIT BUTTON_OFF
35 #elif CONFIG_KEYPAD == ONDIO_PAD
36 #define ONEDROCKBLOX_DOWN BUTTON_RIGHT
37 #define ONEDROCKBLOX_QUIT BUTTON_OFF
39 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
40 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
41 #define ONEDROCKBLOX_QUIT BUTTON_POWER
43 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
44 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
45 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
46 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
47 #define ONEDROCKBLOX_QUIT (BUTTON_SELECT | BUTTON_MENU)
49 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
50 (CONFIG_KEYPAD == IRIVER_H300_PAD)
51 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
52 #define ONEDROCKBLOX_QUIT BUTTON_OFF
54 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
55 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
56 #define ONEDROCKBLOX_QUIT BUTTON_POWER
58 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
59 (CONFIG_KEYPAD == SANSA_C200_PAD)
60 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
61 #define ONEDROCKBLOX_QUIT BUTTON_POWER
63 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
64 #define ONEDROCKBLOX_DOWN BUTTON_PLAY
65 #define ONEDROCKBLOX_QUIT BUTTON_POWER
67 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
68 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
69 #define ONEDROCKBLOX_QUIT BUTTON_BACK
71 #elif (CONFIG_KEYPAD == MROBE100_PAD)
72 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
73 #define ONEDROCKBLOX_QUIT BUTTON_POWER
75 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
76 #define ONEDROCKBLOX_DOWN BUTTON_RC_PLAY
77 #define ONEDROCKBLOX_QUIT BUTTON_RC_REC
79 #elif (CONFIG_KEYPAD == COWOND2_PAD)
80 #define ONEDROCKBLOX_DOWN BUTTON_MENU
81 #define ONEDROCKBLOX_QUIT BUTTON_POWER
84 #error No keymap defined!
87 #define mrand(max) (short)(rb->rand()%max)
92 ** Lots of defines for the drawing stuff :-)
93 ** The most ugly way i could think of...
96 #if (LCD_WIDTH > LCD_HEIGHT)
97 /* Any screens larger than the minis LCD */
99 /* Max size of one block */
100 # define WIDTH (int)((LCD_HEIGHT * 0.85) / TILES)
101 /* Align the playing filed centered */
102 # define CENTER_X (int)(LCD_WIDTH/2-(WIDTH/2))
103 # define CENTER_Y (int)(LCD_HEIGHT/2-((WIDTH*TILES+TILES)/2))
105 # define SCORE_X (int)(((CENTER_X+WIDTH+4) + (LCD_WIDTH-(CENTER_X+WIDTH+4))/2)-(f_width/2))
106 # define SCORE_Y (int)((LCD_HEIGHT/2)-(f_height/2))
107 /* Max. size of bricks is 4 blocks */
108 # define NEXT_H (WIDTH*4+3)
109 # define NEXT_X (int)(CENTER_X/2-WIDTH/2)
110 # define NEXT_Y (int)(LCD_HEIGHT/2-NEXT_H/2)
112 /* Max size of one block */
113 # define WIDTH (int)((LCD_HEIGHT * 0.85) / TILES)
114 /* Align the playing left centered */
115 # define CENTER_X (int)(LCD_WIDTH*0.2)
116 # define CENTER_Y (int)(LCD_HEIGHT/2-((WIDTH*TILES+TILES)/2))
118 # define SCORE_X (int)(((CENTER_X+WIDTH+4) + (LCD_WIDTH-(CENTER_X+WIDTH+4))/2)-(f_width/2))
120 /* Max. size of bricks is 4 blocks */
121 # define NEXT_H (WIDTH*4+3)
122 # define NEXT_X (score_x+f_width+7)
123 # define NEXT_Y (int)(LCD_HEIGHT-((4*WIDTH)+13))
126 /* Max size of one block */
127 # define WIDTH (int)((LCD_HEIGHT * 0.8) / TILES)
128 /* Align the playing filed centered */
129 # define CENTER_X (int)(LCD_WIDTH/2-(WIDTH/2))
132 # define SCORE_X (int)((LCD_WIDTH/2)-(f_width/2))
133 # define SCORE_Y (LCD_HEIGHT-(f_height+2))
134 /* Max. size of bricks is 4 blocks */
135 # define NEXT_H (WIDTH*4+3)
136 # define NEXT_X (int)(CENTER_X/2-WIDTH/2)
137 # define NEXT_Y (int)((LCD_HEIGHT * 0.8)/2-NEXT_H/2)
140 static const struct plugin_api
* rb
; /* global api struct pointer */
142 void draw_brick(int pos
, int length
) {
144 rb
->lcd_set_drawmode(DRMODE_BG
|DRMODE_INVERSEVID
);
145 rb
->lcd_fillrect(CENTER_X
, CENTER_Y
, WIDTH
, WIDTH
* TILES
+ TILES
);
146 rb
->lcd_set_drawmode(DRMODE_SOLID
);
148 for (i
= pos
; i
< length
+ pos
; ++i
) {
149 if (i
>= 0) rb
->lcd_fillrect(CENTER_X
, CENTER_Y
+i
+(WIDTH
*i
), WIDTH
, WIDTH
);
153 enum plugin_status
plugin_start(const struct plugin_api
* api
, const void* parameter
)
156 int f_width
, f_height
;
165 int pos_cur_brick
= 0;
166 int type_cur_brick
= 0;
167 int type_next_brick
= 0;
169 unsigned long int score
= 34126;
176 rb
->lcd_set_backdrop(NULL
);
177 rb
->lcd_set_background(LCD_BLACK
);
178 rb
->lcd_set_foreground(LCD_WHITE
);
181 rb
->lcd_setfont(FONT_SYSFIXED
);
183 rb
->lcd_getstringsize("100000000", &f_width
, &f_height
);
185 rb
->lcd_clear_display();
191 /* Playing filed box */
192 rb
->lcd_vline(CENTER_X
-2, CENTER_Y
, CENTER_Y
+ (WIDTH
*TILES
+TILES
));
193 rb
->lcd_vline(CENTER_X
+ WIDTH
+ 1, CENTER_Y
,
194 CENTER_Y
+ (WIDTH
*TILES
+TILES
));
195 rb
->lcd_hline(CENTER_X
-2, CENTER_X
+ WIDTH
+ 1,
196 CENTER_Y
+ (WIDTH
*TILES
+TILES
));
199 #if (LCD_WIDTH > LCD_HEIGHT)
200 rb
->lcd_drawrect(SCORE_X
-4, SCORE_Y
-5, f_width
+8, f_height
+9);
201 rb
->lcd_putsxy(SCORE_X
-4, SCORE_Y
-6-f_height
, "score");
203 rb
->lcd_hline(0, LCD_WIDTH
, SCORE_Y
-5);
204 rb
->lcd_putsxy(2, SCORE_Y
-6-f_height
, "score");
209 rb
->lcd_getstringsize("next", &f_width
, NULL
);
210 #if (LCD_WIDTH > LCD_HEIGHT) && !(LCD_WIDTH > 132)
211 rb
->lcd_drawrect(NEXT_X
-5, NEXT_Y
-5, WIDTH
+10, NEXT_H
+10);
212 rb
->lcd_putsxy(score_x
-4, NEXT_Y
-5, "next");
214 rb
->lcd_drawrect(NEXT_X
-5, NEXT_Y
-5, WIDTH
+10, NEXT_H
+10);
215 rb
->lcd_putsxy(NEXT_X
-5, NEXT_Y
-5-f_height
-1, "next");
221 rb
->srand( *rb
->current_tick
);
223 type_cur_brick
= 2 + mrand(3);
224 type_next_brick
= 2 + mrand(3);
227 end
= *rb
->current_tick
+ (cycletime
* HZ
) / 1000;
229 draw_brick(pos_cur_brick
, type_cur_brick
);
231 /* Draw next brick */
232 rb
->lcd_set_drawmode(DRMODE_BG
|DRMODE_INVERSEVID
);
233 rb
->lcd_fillrect(NEXT_X
, NEXT_Y
, WIDTH
, WIDTH
* 4 + 4);
234 rb
->lcd_set_drawmode(DRMODE_SOLID
);
236 for (i
= 0; i
< type_next_brick
; ++i
) {
237 rb
->lcd_fillrect(NEXT_X
,
238 NEXT_Y
+ ((type_next_brick
% 2) ? (int)(WIDTH
/2) : ((type_next_brick
== 2) ? (WIDTH
+1) : 0)) + (WIDTH
*i
) + i
,
243 rb
->snprintf(score_buf
, sizeof(score_buf
), "%8ld0", score
);
244 rb
->lcd_putsxy(score_x
, SCORE_Y
, score_buf
);
248 button
= rb
->button_status();
251 case ONEDROCKBLOX_DOWN
:
252 case (ONEDROCKBLOX_DOWN
|BUTTON_REPEAT
):
255 case ONEDROCKBLOX_QUIT
:
260 if(rb
->default_event_handler(button
) == SYS_USB_CONNECTED
) {
265 if ((pos_cur_brick
+ type_cur_brick
) > 10) {
266 type_cur_brick
= type_next_brick
;
267 type_next_brick
= 2 + mrand(3);
268 score
+= (type_cur_brick
- 1) * 2;
269 pos_cur_brick
= 1 - type_cur_brick
;
274 if (end
> *rb
->current_tick
)
275 rb
->sleep(end
-*rb
->current_tick
);