1 /*****************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// __ \_/ ___\| |/ /| __ \ / __ \ \/ /
5 * Jukebox | | ( (__) ) \___| ( | \_\ ( (__) ) (
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 - 2008 Alexander Papst
11 * Idea from http://www.tetris1d.org
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
24 #include "lib/pluginlib_actions.h"
26 /* this set the context to use with PLA */
27 static const struct button_mapping
*plugin_contexts
[] = { pla_main_ctx
};
28 #define ONEDROCKBLOX_DOWN PLA_DOWN
29 #define ONEDROCKBLOX_DOWN_REPEAT PLA_DOWN_REPEAT
30 #define ONEDROCKBLOX_QUIT PLA_EXIT
31 #define ONEDROCKBLOX_QUIT2 PLA_CANCEL
33 #define mrand(max) (short)(rb->rand()%max)
38 ** Lots of defines for the drawing stuff :-)
39 ** The most ugly way i could think of...
42 #if (LCD_WIDTH > LCD_HEIGHT)
43 /* Any screens larger than the minis LCD */
45 /* Max size of one block */
46 # define WIDTH (int)((LCD_HEIGHT * 0.85) / TILES)
47 /* Align the playing filed centered */
48 # define CENTER_X (int)(LCD_WIDTH/2-(WIDTH/2))
49 # define CENTER_Y (int)(LCD_HEIGHT/2-((WIDTH*TILES+TILES)/2))
51 # define SCORE_X (int)(((CENTER_X+WIDTH+4) + (LCD_WIDTH-(CENTER_X+WIDTH+4))/2)-(f_width/2))
52 # define SCORE_Y (int)((LCD_HEIGHT/2)-(f_height/2))
53 /* Max. size of bricks is 4 blocks */
54 # define NEXT_H (WIDTH*4+3)
55 # define NEXT_X (int)(CENTER_X/2-WIDTH/2)
56 # define NEXT_Y (int)(LCD_HEIGHT/2-NEXT_H/2)
58 /* Max size of one block */
59 # define WIDTH (int)((LCD_HEIGHT * 0.85) / TILES)
60 /* Align the playing left centered */
61 # define CENTER_X (int)(LCD_WIDTH*0.2)
62 # define CENTER_Y (int)(LCD_HEIGHT/2-((WIDTH*TILES+TILES)/2))
64 # define SCORE_X (int)(((CENTER_X+WIDTH+4) + (LCD_WIDTH-(CENTER_X+WIDTH+4))/2)-(f_width/2))
66 /* Max. size of bricks is 4 blocks */
67 # define NEXT_H (WIDTH*4+3)
68 # define NEXT_X (score_x+f_width+7)
69 # define NEXT_Y (int)(LCD_HEIGHT-((4*WIDTH)+13))
72 /* Max size of one block */
73 # define WIDTH (int)((LCD_HEIGHT * 0.8) / TILES)
74 /* Align the playing filed centered */
75 # define CENTER_X (int)(LCD_WIDTH/2-(WIDTH/2))
78 # define SCORE_X (int)((LCD_WIDTH/2)-(f_width/2))
79 # define SCORE_Y (LCD_HEIGHT-(f_height+2))
80 /* Max. size of bricks is 4 blocks */
81 # define NEXT_H (WIDTH*4+3)
82 # define NEXT_X (int)(CENTER_X/2-WIDTH/2)
83 # define NEXT_Y (int)((LCD_HEIGHT * 0.8)/2-NEXT_H/2)
86 static void draw_brick(int pos
, int length
) {
88 rb
->lcd_set_drawmode(DRMODE_BG
|DRMODE_INVERSEVID
);
89 rb
->lcd_fillrect(CENTER_X
, CENTER_Y
, WIDTH
, WIDTH
* TILES
+ TILES
);
90 rb
->lcd_set_drawmode(DRMODE_SOLID
);
92 for (i
= pos
; i
< length
+ pos
; ++i
) {
93 if (i
>= 0) rb
->lcd_fillrect(CENTER_X
, CENTER_Y
+i
+(WIDTH
*i
), WIDTH
, WIDTH
);
97 enum plugin_status
plugin_start(const void* parameter
)
100 int f_width
, f_height
;
109 int pos_cur_brick
= 0;
110 int type_cur_brick
= 0;
111 int type_next_brick
= 0;
113 unsigned long int score
= 34126;
118 rb
->lcd_set_backdrop(NULL
);
119 rb
->lcd_set_background(LCD_BLACK
);
120 rb
->lcd_set_foreground(LCD_WHITE
);
123 rb
->lcd_setfont(FONT_SYSFIXED
);
125 rb
->lcd_getstringsize("100000000", &f_width
, &f_height
);
127 rb
->lcd_clear_display();
133 /* Playing filed box */
134 rb
->lcd_vline(CENTER_X
-2, CENTER_Y
, CENTER_Y
+ (WIDTH
*TILES
+TILES
));
135 rb
->lcd_vline(CENTER_X
+ WIDTH
+ 1, CENTER_Y
,
136 CENTER_Y
+ (WIDTH
*TILES
+TILES
));
137 rb
->lcd_hline(CENTER_X
-2, CENTER_X
+ WIDTH
+ 1,
138 CENTER_Y
+ (WIDTH
*TILES
+TILES
));
141 #if (LCD_WIDTH > LCD_HEIGHT)
142 rb
->lcd_drawrect(SCORE_X
-4, SCORE_Y
-5, f_width
+8, f_height
+9);
143 rb
->lcd_putsxy(SCORE_X
-4, SCORE_Y
-6-f_height
, "score");
145 rb
->lcd_hline(0, LCD_WIDTH
, SCORE_Y
-5);
146 rb
->lcd_putsxy(2, SCORE_Y
-6-f_height
, "score");
151 rb
->lcd_getstringsize("next", &f_width
, NULL
);
152 #if (LCD_WIDTH > LCD_HEIGHT) && !(LCD_WIDTH > 132)
153 rb
->lcd_drawrect(NEXT_X
-5, NEXT_Y
-5, WIDTH
+10, NEXT_H
+10);
154 rb
->lcd_putsxy(score_x
-4, NEXT_Y
-5, "next");
156 rb
->lcd_drawrect(NEXT_X
-5, NEXT_Y
-5, WIDTH
+10, NEXT_H
+10);
157 rb
->lcd_putsxy(NEXT_X
-5, NEXT_Y
-5-f_height
-1, "next");
163 rb
->srand( *rb
->current_tick
);
165 type_cur_brick
= 2 + mrand(3);
166 type_next_brick
= 2 + mrand(3);
169 end
= *rb
->current_tick
+ (cycletime
* HZ
) / 1000;
171 draw_brick(pos_cur_brick
, type_cur_brick
);
173 /* Draw next brick */
174 rb
->lcd_set_drawmode(DRMODE_BG
|DRMODE_INVERSEVID
);
175 rb
->lcd_fillrect(NEXT_X
, NEXT_Y
, WIDTH
, WIDTH
* 4 + 4);
176 rb
->lcd_set_drawmode(DRMODE_SOLID
);
178 for (i
= 0; i
< type_next_brick
; ++i
) {
179 rb
->lcd_fillrect(NEXT_X
,
180 NEXT_Y
+ ((type_next_brick
% 2) ? (int)(WIDTH
/2) : ((type_next_brick
== 2) ? (WIDTH
+1) : 0)) + (WIDTH
*i
) + i
,
185 rb
->lcd_putsxyf(score_x
, SCORE_Y
, "%8ld0", score
);
189 /*We get button from PLA this way */
190 button
= pluginlib_getaction(TIMEOUT_NOBLOCK
, plugin_contexts
,
191 ARRAYLEN(plugin_contexts
));
194 case ONEDROCKBLOX_DOWN
:
195 case ONEDROCKBLOX_DOWN_REPEAT
:
198 case ONEDROCKBLOX_QUIT
:
199 case ONEDROCKBLOX_QUIT2
:
204 if(rb
->default_event_handler(button
) == SYS_USB_CONNECTED
) {
209 if ((pos_cur_brick
+ type_cur_brick
) > 10) {
210 type_cur_brick
= type_next_brick
;
211 type_next_brick
= 2 + mrand(3);
212 score
+= (type_cur_brick
- 1) * 2;
213 pos_cur_brick
= 1 - type_cur_brick
;
218 if (TIME_BEFORE(*rb
->current_tick
, end
))
219 rb
->sleep(end
-*rb
->current_tick
);