1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 1999 Mattis Wadman (nappe@sudac.org)
12 * Heavily modified for embedded use by Björn Stenberg (bjorn@haxx.se)
14 * All files in this archive are subject to the GNU General Public License.
15 * See the file COPYING in the source tree root for full license agreement.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
23 #ifdef HAVE_LCD_BITMAP
27 #if (CONFIG_KEYPAD == IPOD_4G_PAD) || \
28 (CONFIG_KEYPAD == IPOD_3G_PAD)
29 #define ROCKBLOX_OFF BUTTON_MENU
30 #define ROCKBLOX_UP BUTTON_SCROLL_BACK
31 #define ROCKBLOX_DOWN BUTTON_SCROLL_FWD
32 #define ROCKBLOX_LEFT BUTTON_LEFT
33 #define ROCKBLOX_RIGHT BUTTON_RIGHT
34 #elif (CONFIG_KEYPAD == IAUDIO_X5_PAD)
35 #define ROCKBLOX_OFF BUTTON_POWER
36 #define ROCKBLOX_UP BUTTON_UP
37 #define ROCKBLOX_DOWN BUTTON_DOWN
38 #define ROCKBLOX_LEFT BUTTON_LEFT
39 #define ROCKBLOX_RIGHT BUTTON_RIGHT
40 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
41 #define ROCKBLOX_OFF BUTTON_A
42 #define ROCKBLOX_UP BUTTON_UP
43 #define ROCKBLOX_DOWN BUTTON_DOWN
44 #define ROCKBLOX_LEFT BUTTON_LEFT
45 #define ROCKBLOX_RIGHT BUTTON_RIGHT
47 #define ROCKBLOX_OFF BUTTON_OFF
48 #define ROCKBLOX_UP BUTTON_UP
49 #define ROCKBLOX_DOWN BUTTON_DOWN
50 #define ROCKBLOX_LEFT BUTTON_LEFT
51 #define ROCKBLOX_RIGHT BUTTON_RIGHT
54 static const int start_x
= 5;
55 static const int start_y
= 5;
56 static const int max_x
= 4 * 17;
57 static const int max_y
= 3 * 10;
58 static const short level_speeds
[10] = {
59 1000, 900, 800, 700, 600, 500, 400, 300, 250, 200
61 static const int blocks
= 7;
62 static const int block_frames
[7] = {1,2,2,2,4,4,4};
64 static int current_x
, current_y
, current_f
, current_b
;
65 static int level
, score
;
66 static int next_b
, next_f
;
68 static char virtual[LCD_WIDTH
* LCD_HEIGHT
];
69 static struct plugin_api
* rb
;
72 block_data is built up the following way
74 first array index specifies the block number
75 second array index specifies the rotation of the block
76 third array index specifies:
77 0: x-coordinates of pixels
78 1: y-coordinates of pixels
79 fourth array index specifies the coordinate of a pixel
81 each block consists of four pixels whose relative coordinates are given
85 static const char block_data
[7][4][2][4] =
91 {{0,1,1,2},{1,1,0,0}},
95 {{0,1,1,2},{0,0,1,1}},
99 {{1,1,1,1},{0,1,2,3}},
100 {{0,1,2,3},{2,2,2,2}}
103 {{1,1,1,2},{2,1,0,0}},
104 {{0,1,2,2},{1,1,1,2}},
105 {{0,1,1,1},{2,2,1,0}},
106 {{0,0,1,2},{0,1,1,1}}
109 {{0,1,1,1},{0,0,1,2}},
110 {{0,1,2,2},{1,1,1,0}},
111 {{1,1,1,2},{0,1,2,2}},
112 {{0,0,1,2},{2,1,1,1}}
115 {{1,0,1,2},{0,1,1,1}},
116 {{2,1,1,1},{1,0,1,2}},
117 {{1,0,1,2},{2,1,1,1}},
118 {{0,1,1,1},{1,0,1,2}}
122 static int t_rand(int range
)
124 return *rb
->current_tick
% range
;
127 static void draw_frame(int fstart_x
,int fstop_x
,int fstart_y
,int fstop_y
)
129 rb
->lcd_drawline(fstart_x
, fstart_y
, fstop_x
, fstart_y
);
130 rb
->lcd_drawline(fstart_x
, fstop_y
, fstop_x
, fstop_y
);
132 rb
->lcd_drawline(fstart_x
, fstart_y
, fstart_x
, fstop_y
);
133 rb
->lcd_drawline(fstop_x
, fstart_y
, fstop_x
, fstop_y
);
135 rb
->lcd_drawline(fstart_x
- 1, fstart_y
+ 1, fstart_x
- 1, fstop_y
+ 1);
136 rb
->lcd_drawline(fstart_x
- 1, fstop_y
+ 1, fstop_x
- 1, fstop_y
+ 1);
139 static void draw_block(int x
, int y
, int block
, int frame
, bool clear
)
146 rb
->lcd_set_drawmode(DRMODE_SOLID
|DRMODE_INVERSEVID
);
147 for (a
= 0; a
< 3; a
++)
148 for (b
= 0; b
< 4; b
++)
149 rb
->lcd_drawpixel(start_x
+ x
+ block_data
[block
][frame
][1][i
] * 4 - b
,
150 start_y
+ y
+ block_data
[block
][frame
][0][i
] * 3 + a
);
151 rb
->lcd_set_drawmode(DRMODE_SOLID
);
155 for (a
= 0; a
< 3; a
++)
156 for (b
= 0; b
< 4; b
++)
157 rb
->lcd_drawpixel(start_x
+x
+block_data
[block
][frame
][1][i
] * 4 - b
,
158 start_y
+y
+block_data
[block
][frame
][0][i
] * 3 + a
);
163 static void to_virtual(void)
167 for(i
= 0; i
< 4; i
++)
168 for (a
= 0; a
< 3; a
++)
169 for (b
= 0; b
< 4; b
++)
171 (current_y
+ block_data
[current_b
][current_f
][0][i
] * 3 + a
) *
172 max_x
+ current_x
+ block_data
[current_b
][current_f
][1][i
] *
173 4 - b
) = current_b
+ 1;
176 static bool block_touch (int x
, int y
)
179 for (a
= 0; a
< 4; a
++)
180 for (b
= 0; b
< 3; b
++)
181 if (*(virtual + (y
+ b
) * max_x
+ (x
- a
)) != 0)
186 static bool gameover(void)
189 int frame
, block
, y
, x
;
196 for(i
= 0; i
< 4; i
++){
197 /* Do we have blocks touching? */
198 if(block_touch(x
+ block_data
[block
][frame
][1][i
] * 4,
199 y
+ block_data
[block
][frame
][0][i
] * 3))
201 /* Are we at the top of the frame? */
202 if(x
+ block_data
[block
][frame
][1][i
] * 4 >= max_x
- 16)
212 static bool valid_position(int x
, int y
, int block
, int frame
)
216 if ((y
+ block_data
[block
][frame
][0][i
] * 3 > max_y
- 3) ||
217 (x
+ block_data
[block
][frame
][1][i
] * 4 > max_x
- 4) ||
218 (y
+ block_data
[block
][frame
][0][i
] * 3 < 0) ||
219 (x
+ block_data
[block
][frame
][1][i
] * 4 < 4) ||
220 block_touch (x
+ block_data
[block
][frame
][1][i
] * 4,
221 y
+ block_data
[block
][frame
][0][i
] * 3))
228 static void from_virtual(void)
232 for(y
= 0; y
< max_y
; y
++)
233 for(x
= 1; x
< max_x
- 1; x
++)
234 if(*(virtual + (y
* max_x
) + x
) != 0)
236 rb
->lcd_drawpixel(start_x
+ x
, start_y
+ y
);
240 rb
->lcd_set_drawmode(DRMODE_SOLID
|DRMODE_INVERSEVID
);
241 rb
->lcd_drawpixel(start_x
+ x
, start_y
+ y
);
242 rb
->lcd_set_drawmode(DRMODE_SOLID
);
246 static void move_block(int x
,int y
,int f
)
248 int last_frame
= current_f
;
252 if(current_f
> block_frames
[current_b
]-1)
255 current_f
= block_frames
[current_b
]-1;
258 if(valid_position(current_x
+ x
, current_y
+ y
, current_b
, current_f
))
260 draw_block(current_x
,current_y
,current_b
,last_frame
,true);
263 draw_block(current_x
,current_y
,current_b
,current_f
,false);
267 current_f
= last_frame
;
270 static void new_block(void)
274 current_x
= max_x
- 16;
276 next_b
= t_rand(blocks
);
277 next_f
= t_rand(block_frames
[next_b
]);
279 rb
->lcd_drawline (max_x
+ 7, start_y
- 1, max_x
+ 29, start_y
- 1);
280 rb
->lcd_drawline (max_x
+ 29, start_y
, max_x
+ 29, start_y
+ 14);
281 rb
->lcd_drawline (max_x
+ 29, start_y
+ 14, max_x
+ 7, start_y
+ 14);
282 rb
->lcd_drawline (max_x
+ 7, start_y
+ 14, max_x
+ 7, start_y
- 1);
283 rb
->lcd_drawline (max_x
+ 6, start_y
+ 15, max_x
+ 6, start_y
);
284 rb
->lcd_drawline (max_x
+ 6, start_y
+ 15, max_x
+ 28, start_y
+ 15);
286 draw_block(max_x
+ 9, start_y
- 4, current_b
, current_f
, true);
287 draw_block(max_x
+ 9, start_y
- 4, next_b
, next_f
, false);
288 if(!valid_position(current_x
, current_y
, current_b
, current_f
))
290 draw_block(current_x
, current_y
, current_b
, current_f
, false);
294 draw_block(current_x
, current_y
, current_b
, current_f
, false);
297 static int check_lines(void)
302 for(x
= 0; x
< max_x
; x
++)
305 for(y
= 0; y
< max_y
; y
++)
307 if(*(virtual + y
* max_x
+ x
) == 0)
318 for(i
= x
; i
< max_x
- 1; i
++)
319 for (j
= 0; j
< max_y
; j
++)
320 *(virtual + j
* max_x
+ i
)=*(virtual + j
* max_x
+ (i
+ 1));
322 x
--; /* re-check this line */
329 static void move_down(void)
334 if(!valid_position(current_x
- 4, current_y
, current_b
, current_f
))
341 level
= (int)lines
/10;
348 rb
->snprintf(s
, sizeof(s
), "%d Rows - Level %d", lines
, level
);
349 rb
->lcd_putsxy(2, 42, s
);
358 static int game_loop(void)
365 while(count
* 300 < level_speeds
[level
])
367 button
= rb
->button_get_w_tmo(HZ
/10);
374 case ROCKBLOX_UP
| BUTTON_REPEAT
:
379 case ROCKBLOX_DOWN
| BUTTON_REPEAT
:
384 case ROCKBLOX_RIGHT
| BUTTON_REPEAT
:
389 case ROCKBLOX_LEFT
| BUTTON_REPEAT
:
394 if (rb
->default_event_handler(button
) == SYS_USB_CONNECTED
)
395 return PLUGIN_USB_CONNECTED
;
404 rb
->lcd_set_drawmode(DRMODE_SOLID
|DRMODE_INVERSEVID
);
405 rb
->lcd_fillrect(0, 52, LCD_WIDTH
, LCD_HEIGHT
- 52);
406 rb
->lcd_set_drawmode(DRMODE_SOLID
);
407 rb
->lcd_putsxy(2, 52, "You lose!");
419 static void init_rockblox(void)
421 rb
->memset(&virtual, 0, sizeof(virtual));
434 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
)
441 /* Lets use the default font */
442 rb
->lcd_setfont(FONT_SYSFIXED
);
446 draw_frame(start_x
, start_x
+ max_x
- 1, start_y
- 1, start_y
+ max_y
);
447 rb
->lcd_putsxy(2, 42, "0 Rows - Level 0");
450 next_b
= t_rand(blocks
);
451 next_f
= t_rand(block_frames
[next_b
]);
455 rb
->lcd_setfont(FONT_UI
);