New plugin: FFT, A frequency analyzer plugin
[kugel-rb.git] / apps / plugins / rockblox1d.c
blob245035bad353b07b9a098b7f83adfb5ad4f91de3
1 /*****************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// __ \_/ ___\| |/ /| __ \ / __ \ \/ /
5 * Jukebox | | ( (__) ) \___| ( | \_\ ( (__) ) (
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
23 #include "plugin.h"
25 PLUGIN_HEADER
28 #ifdef HAVE_LCD_BITMAP
30 #if CONFIG_KEYPAD == RECORDER_PAD
31 #define ONEDROCKBLOX_DOWN BUTTON_PLAY
32 #define ONEDROCKBLOX_QUIT BUTTON_OFF
34 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
35 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
36 #define ONEDROCKBLOX_QUIT BUTTON_OFF
38 #elif CONFIG_KEYPAD == ONDIO_PAD
39 #define ONEDROCKBLOX_DOWN BUTTON_RIGHT
40 #define ONEDROCKBLOX_QUIT BUTTON_OFF
42 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
43 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
44 #define ONEDROCKBLOX_QUIT BUTTON_POWER
46 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
47 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
48 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
49 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
50 #define ONEDROCKBLOX_QUIT (BUTTON_SELECT | BUTTON_MENU)
52 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
53 (CONFIG_KEYPAD == IRIVER_H300_PAD)
54 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
55 #define ONEDROCKBLOX_QUIT BUTTON_OFF
57 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
58 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
59 #define ONEDROCKBLOX_QUIT BUTTON_POWER
61 #elif CONFIG_KEYPAD == SANSA_E200_PAD || \
62 CONFIG_KEYPAD == SANSA_C200_PAD || \
63 CONFIG_KEYPAD == SANSA_CLIP_PAD || \
64 CONFIG_KEYPAD == SANSA_M200_PAD
65 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
66 #define ONEDROCKBLOX_QUIT BUTTON_POWER
68 #elif CONFIG_KEYPAD == SANSA_FUZE_PAD
69 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
70 #define ONEDROCKBLOX_QUIT BUTTON_HOME
72 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
73 #define ONEDROCKBLOX_DOWN BUTTON_PLAY
74 #define ONEDROCKBLOX_QUIT BUTTON_POWER
76 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
77 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
78 #define ONEDROCKBLOX_QUIT BUTTON_BACK
80 #elif (CONFIG_KEYPAD == MROBE100_PAD)
81 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
82 #define ONEDROCKBLOX_QUIT BUTTON_POWER
84 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
85 #define ONEDROCKBLOX_DOWN BUTTON_RC_PLAY
86 #define ONEDROCKBLOX_QUIT BUTTON_RC_REC
88 #elif (CONFIG_KEYPAD == COWON_D2_PAD)
89 #define ONEDROCKBLOX_DOWN BUTTON_MENU
90 #define ONEDROCKBLOX_QUIT BUTTON_POWER
92 #elif CONFIG_KEYPAD == IAUDIO67_PAD
93 #define ONEDROCKBLOX_DOWN BUTTON_MENU
94 #define ONEDROCKBLOX_QUIT BUTTON_POWER
96 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
97 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
98 #define ONEDROCKBLOX_QUIT BUTTON_BACK
100 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
101 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
102 #define ONEDROCKBLOX_QUIT BUTTON_POWER
104 #elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
105 #define ONEDROCKBLOX_DOWN BUTTON_PLAY
106 #define ONEDROCKBLOX_QUIT BUTTON_POWER
108 #elif (CONFIG_KEYPAD == ONDAVX747_PAD)
109 #define ONEDROCKBLOX_DOWN BUTTON_MENU
110 #define ONEDROCKBLOX_QUIT BUTTON_POWER
112 #elif (CONFIG_KEYPAD == SAMSUNG_YH_PAD)
113 #define ONEDROCKBLOX_DOWN BUTTON_DOWN
114 #define ONEDROCKBLOX_QUIT BUTTON_PLAY
116 #elif defined(HAVE_TOUCHSCREEN)
118 #define ONEDROCKBLOX_DOWN BUTTON_BOTTOMMIDDLE
119 #define ONEDROCKBLOX_QUIT BUTTON_POWER
121 #else
122 #error No keymap defined!
123 #endif
125 #define mrand(max) (short)(rb->rand()%max)
127 #define TILES 11
129 /**********
130 ** Lots of defines for the drawing stuff :-)
131 ** The most ugly way i could think of...
134 #if (LCD_WIDTH > LCD_HEIGHT)
135 /* Any screens larger than the minis LCD */
136 #if (LCD_WIDTH > 132)
137 /* Max size of one block */
138 # define WIDTH (int)((LCD_HEIGHT * 0.85) / TILES)
139 /* Align the playing filed centered */
140 # define CENTER_X (int)(LCD_WIDTH/2-(WIDTH/2))
141 # define CENTER_Y (int)(LCD_HEIGHT/2-((WIDTH*TILES+TILES)/2))
142 /* Score box */
143 # define SCORE_X (int)(((CENTER_X+WIDTH+4) + (LCD_WIDTH-(CENTER_X+WIDTH+4))/2)-(f_width/2))
144 # define SCORE_Y (int)((LCD_HEIGHT/2)-(f_height/2))
145 /* Max. size of bricks is 4 blocks */
146 # define NEXT_H (WIDTH*4+3)
147 # define NEXT_X (int)(CENTER_X/2-WIDTH/2)
148 # define NEXT_Y (int)(LCD_HEIGHT/2-NEXT_H/2)
149 #else
150 /* Max size of one block */
151 # define WIDTH (int)((LCD_HEIGHT * 0.85) / TILES)
152 /* Align the playing left centered */
153 # define CENTER_X (int)(LCD_WIDTH*0.2)
154 # define CENTER_Y (int)(LCD_HEIGHT/2-((WIDTH*TILES+TILES)/2))
155 /* Score box */
156 # define SCORE_X (int)(((CENTER_X+WIDTH+4) + (LCD_WIDTH-(CENTER_X+WIDTH+4))/2)-(f_width/2))
157 # define SCORE_Y 16
158 /* Max. size of bricks is 4 blocks */
159 # define NEXT_H (WIDTH*4+3)
160 # define NEXT_X (score_x+f_width+7)
161 # define NEXT_Y (int)(LCD_HEIGHT-((4*WIDTH)+13))
162 #endif
163 #else
164 /* Max size of one block */
165 # define WIDTH (int)((LCD_HEIGHT * 0.8) / TILES)
166 /* Align the playing filed centered */
167 # define CENTER_X (int)(LCD_WIDTH/2-(WIDTH/2))
168 # define CENTER_Y 2
169 /* Score box */
170 # define SCORE_X (int)((LCD_WIDTH/2)-(f_width/2))
171 # define SCORE_Y (LCD_HEIGHT-(f_height+2))
172 /* Max. size of bricks is 4 blocks */
173 # define NEXT_H (WIDTH*4+3)
174 # define NEXT_X (int)(CENTER_X/2-WIDTH/2)
175 # define NEXT_Y (int)((LCD_HEIGHT * 0.8)/2-NEXT_H/2)
176 #endif
178 void draw_brick(int pos, int length) {
179 int i = pos;
180 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
181 rb->lcd_fillrect(CENTER_X, CENTER_Y, WIDTH, WIDTH * TILES + TILES);
182 rb->lcd_set_drawmode(DRMODE_SOLID);
184 for (i = pos; i < length + pos; ++i) {
185 if (i >= 0) rb->lcd_fillrect(CENTER_X, CENTER_Y+i+(WIDTH*i), WIDTH, WIDTH);
189 enum plugin_status plugin_start(const void* parameter)
191 int i;
192 int f_width, f_height;
193 int score_x;
195 bool quit = false;
196 int button;
198 int cycletime = 300;
199 int end;
201 int pos_cur_brick = 0;
202 int type_cur_brick = 0;
203 int type_next_brick = 0;
205 unsigned long int score = 34126;
206 char score_buf[10];
208 (void)parameter;
210 #if LCD_DEPTH > 1
211 rb->lcd_set_backdrop(NULL);
212 rb->lcd_set_background(LCD_BLACK);
213 rb->lcd_set_foreground(LCD_WHITE);
214 #endif
216 rb->lcd_setfont(FONT_SYSFIXED);
218 rb->lcd_getstringsize("100000000", &f_width, &f_height);
220 rb->lcd_clear_display();
222 /***********
223 ** Draw EVERYTHING
226 /* Playing filed box */
227 rb->lcd_vline(CENTER_X-2, CENTER_Y, CENTER_Y + (WIDTH*TILES+TILES));
228 rb->lcd_vline(CENTER_X + WIDTH + 1, CENTER_Y,
229 CENTER_Y + (WIDTH*TILES+TILES));
230 rb->lcd_hline(CENTER_X-2, CENTER_X + WIDTH + 1,
231 CENTER_Y + (WIDTH*TILES+TILES));
233 /* Score box */
234 #if (LCD_WIDTH > LCD_HEIGHT)
235 rb->lcd_drawrect(SCORE_X-4, SCORE_Y-5, f_width+8, f_height+9);
236 rb->lcd_putsxy(SCORE_X-4, SCORE_Y-6-f_height, "score");
237 #else
238 rb->lcd_hline(0, LCD_WIDTH, SCORE_Y-5);
239 rb->lcd_putsxy(2, SCORE_Y-6-f_height, "score");
240 #endif
241 score_x = SCORE_X;
243 /* Next box */
244 rb->lcd_getstringsize("next", &f_width, NULL);
245 #if (LCD_WIDTH > LCD_HEIGHT) && !(LCD_WIDTH > 132)
246 rb->lcd_drawrect(NEXT_X-5, NEXT_Y-5, WIDTH+10, NEXT_H+10);
247 rb->lcd_putsxy(score_x-4, NEXT_Y-5, "next");
248 #else
249 rb->lcd_drawrect(NEXT_X-5, NEXT_Y-5, WIDTH+10, NEXT_H+10);
250 rb->lcd_putsxy(NEXT_X-5, NEXT_Y-5-f_height-1, "next");
251 #endif
253 /***********
254 ** GAMELOOP
256 rb->srand( *rb->current_tick );
258 type_cur_brick = 2 + mrand(3);
259 type_next_brick = 2 + mrand(3);
261 do {
262 end = *rb->current_tick + (cycletime * HZ) / 1000;
264 draw_brick(pos_cur_brick, type_cur_brick);
266 /* Draw next brick */
267 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
268 rb->lcd_fillrect(NEXT_X, NEXT_Y, WIDTH, WIDTH * 4 + 4);
269 rb->lcd_set_drawmode(DRMODE_SOLID);
271 for (i = 0; i < type_next_brick; ++i) {
272 rb->lcd_fillrect(NEXT_X,
273 NEXT_Y + ((type_next_brick % 2) ? (int)(WIDTH/2) : ((type_next_brick == 2) ? (WIDTH+1) : 0)) + (WIDTH*i) + i,
274 WIDTH, WIDTH);
277 /* Score box */
278 rb->snprintf(score_buf, sizeof(score_buf), "%8ld0", score);
279 rb->lcd_putsxy(score_x, SCORE_Y, score_buf);
281 rb->lcd_update();
283 button = rb->button_status();
285 switch(button) {
286 case ONEDROCKBLOX_DOWN:
287 case (ONEDROCKBLOX_DOWN|BUTTON_REPEAT):
288 cycletime = 100;
289 break;
290 case ONEDROCKBLOX_QUIT:
291 quit = true;
292 break;
293 default:
294 cycletime = 300;
295 if(rb->default_event_handler(button) == SYS_USB_CONNECTED) {
296 quit = true;
300 if ((pos_cur_brick + type_cur_brick) > 10) {
301 type_cur_brick = type_next_brick;
302 type_next_brick = 2 + mrand(3);
303 score += (type_cur_brick - 1) * 2;
304 pos_cur_brick = 1 - type_cur_brick;
305 } else {
306 ++pos_cur_brick;
309 if (TIME_BEFORE(*rb->current_tick, end))
310 rb->sleep(end-*rb->current_tick);
311 else
312 rb->yield();
314 } while (!quit);
316 return PLUGIN_OK;
318 #endif