summaryrefslogtreecommitdiff
path: root/apps/plugins/rockblox1d.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/rockblox1d.c')
-rw-r--r--apps/plugins/rockblox1d.c283
1 files changed, 283 insertions, 0 deletions
diff --git a/apps/plugins/rockblox1d.c b/apps/plugins/rockblox1d.c
new file mode 100644
index 0000000000..58a1e863f7
--- /dev/null
+++ b/apps/plugins/rockblox1d.c
@@ -0,0 +1,283 @@
1/*****************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// __ \_/ ___\| |/ /| __ \ / __ \ \/ /
5 * Jukebox | | ( (__) ) \___| ( | \_\ ( (__) ) (
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 - 2008 Alexander Papst
11 * Idea from http://www.tetris1d.org
12 *
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.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21#include "plugin.h"
22
23PLUGIN_HEADER
24
25#ifdef HAVE_LCD_BITMAP
26
27#if CONFIG_KEYPAD == RECORDER_PAD
28#define ONEDROCKBLOX_DOWN BUTTON_PLAY
29#define ONEDROCKBLOX_QUIT BUTTON_OFF
30
31#elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
32#define ONEDROCKBLOX_DOWN BUTTON_SELECT
33#define ONEDROCKBLOX_QUIT BUTTON_OFF
34
35#elif CONFIG_KEYPAD == ONDIO_PAD
36#define ONEDROCKBLOX_DOWN BUTTON_RIGHT
37#define ONEDROCKBLOX_QUIT BUTTON_OFF
38
39#elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
40#define ONEDROCKBLOX_DOWN BUTTON_SELECT
41#define ONEDROCKBLOX_QUIT BUTTON_POWER
42
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)
48
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
53
54#elif (CONFIG_KEYPAD == GIGABEAT_PAD)
55#define ONEDROCKBLOX_DOWN BUTTON_SELECT
56#define ONEDROCKBLOX_QUIT BUTTON_POWER
57
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
62
63#elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
64#define ONEDROCKBLOX_DOWN BUTTON_PLAY
65#define ONEDROCKBLOX_QUIT BUTTON_POWER
66
67#elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
68#define ONEDROCKBLOX_DOWN BUTTON_SELECT
69#define ONEDROCKBLOX_QUIT BUTTON_BACK
70
71#elif (CONFIG_KEYPAD == MROBE100_PAD)
72#define ONEDROCKBLOX_DOWN BUTTON_SELECT
73#define ONEDROCKBLOX_QUIT BUTTON_POWER
74
75#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
76#define ONEDROCKBLOX_DOWN BUTTON_RC_PLAY
77#define ONEDROCKBLOX_QUIT BUTTON_RC_REC
78
79#elif (CONFIG_KEYPAD == COWOND2_PAD)
80#define ONEDROCKBLOX_DOWN BUTTON_SELECT
81#define ONEDROCKBLOX_QUIT BUTTON_POWER
82
83#else
84#error No keymap defined!
85#endif
86
87#define mrand(max) (short)(rb->rand()%max)
88
89#define TILES 11
90
91/**********
92** Lots of defines for the drawing stuff :-)
93** The most ugly way i could think of...
94*/
95
96#if (LCD_WIDTH > LCD_HEIGHT)
97 /* Any screens larger than the minis LCD */
98#if (LCD_WIDTH > 132)
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))
104 /* Score box */
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)
111#else
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))
117 /* Score box */
118# define SCORE_X (int)(((CENTER_X+WIDTH+4) + (LCD_WIDTH-(CENTER_X+WIDTH+4))/2)-(f_width/2))
119# define SCORE_Y 16
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))
124#endif
125#else
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))
130# define CENTER_Y 2
131 /* Score box */
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)
138#endif
139
140static const struct plugin_api* rb; /* global api struct pointer */
141
142void draw_brick(int pos, int length) {
143 int i = pos;
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);
147
148 for (i = pos; i < length + pos; ++i) {
149 if (i >= 0) rb->lcd_fillrect(CENTER_X, CENTER_Y+i+(WIDTH*i), WIDTH, WIDTH);
150 }
151}
152
153enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter)
154{
155 int i;
156 int f_width, f_height;
157 int score_x;
158
159 bool quit = false;
160 int button;
161
162 int cycletime = 300;
163 int end;
164
165 int pos_cur_brick = 0;
166 int type_cur_brick = 0;
167 int type_next_brick = 0;
168
169 unsigned long int score = 34126;
170 char score_buf[10];
171
172 rb = api;
173 (void)parameter;
174
175#if LCD_DEPTH > 1
176 rb->lcd_set_backdrop(NULL);
177 rb->lcd_set_background(LCD_BLACK);
178 rb->lcd_set_foreground(LCD_WHITE);
179#endif
180
181 rb->lcd_setfont(FONT_SYSFIXED);
182
183 rb->lcd_getstringsize("100000000", &f_width, &f_height);
184
185 rb->lcd_clear_display();
186
187 /***********
188 ** Draw EVERYTHING
189 */
190
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));
197
198 /* Score box */
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");
202#else
203 rb->lcd_hline(0, LCD_WIDTH, SCORE_Y-5);
204 rb->lcd_putsxy(2, SCORE_Y-6-f_height, "score");
205#endif
206 score_x = SCORE_X;
207
208 /* Next box */
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");
213#else
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");
216#endif
217
218 /***********
219 ** GAMELOOP
220 */
221 rb->srand( *rb->current_tick );
222
223 type_cur_brick = 2 + mrand(3);
224 type_next_brick = 2 + mrand(3);
225
226 do {
227 end = *rb->current_tick + (cycletime * HZ) / 1000;
228
229 draw_brick(pos_cur_brick, type_cur_brick);
230
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);
235
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,
239 WIDTH, WIDTH);
240 }
241
242 /* Score box */
243 rb->snprintf(score_buf, sizeof(score_buf), "%8ld0", score);
244 rb->lcd_putsxy(score_x, SCORE_Y, score_buf);
245
246 rb->lcd_update();
247
248 button = rb->button_status();
249
250 switch(button) {
251 case ONEDROCKBLOX_DOWN:
252 case (ONEDROCKBLOX_DOWN|BUTTON_REPEAT):
253 cycletime = 100;
254 break;
255 case ONEDROCKBLOX_QUIT:
256 quit = true;
257 break;
258 default:
259 cycletime = 300;
260 if(rb->default_event_handler(button) == SYS_USB_CONNECTED) {
261 quit = true;
262 }
263 }
264
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;
270 } else {
271 ++pos_cur_brick;
272 }
273
274 if (end > *rb->current_tick)
275 rb->sleep(end-*rb->current_tick);
276 else
277 rb->yield();
278
279 } while (!quit);
280
281 return PLUGIN_OK;
282}
283#endif