Don't objcopy simulator plugins.
[kugel-rb.git] / apps / plugins / rockblox1d.c
blobb0fa6919b45b9f971df819ec55b34b936247d38f
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
27 #ifdef HAVE_LCD_BITMAP
29 #if CONFIG_KEYPAD == RECORDER_PAD
30 #define ONEDROCKBLOX_DOWN BUTTON_PLAY
31 #define ONEDROCKBLOX_QUIT BUTTON_OFF
33 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
34 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
35 #define ONEDROCKBLOX_QUIT BUTTON_OFF
37 #elif CONFIG_KEYPAD == ONDIO_PAD
38 #define ONEDROCKBLOX_DOWN BUTTON_RIGHT
39 #define ONEDROCKBLOX_QUIT BUTTON_OFF
41 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
42 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
43 #define ONEDROCKBLOX_QUIT BUTTON_POWER
45 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
46 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
47 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
48 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
49 #define ONEDROCKBLOX_QUIT (BUTTON_SELECT | BUTTON_MENU)
51 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
52 (CONFIG_KEYPAD == IRIVER_H300_PAD)
53 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
54 #define ONEDROCKBLOX_QUIT BUTTON_OFF
56 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
57 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
58 #define ONEDROCKBLOX_QUIT BUTTON_POWER
60 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
61 (CONFIG_KEYPAD == SANSA_C200_PAD)
62 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
63 #define ONEDROCKBLOX_QUIT BUTTON_POWER
65 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
66 #define ONEDROCKBLOX_DOWN BUTTON_PLAY
67 #define ONEDROCKBLOX_QUIT BUTTON_POWER
69 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
70 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
71 #define ONEDROCKBLOX_QUIT BUTTON_BACK
73 #elif (CONFIG_KEYPAD == MROBE100_PAD)
74 #define ONEDROCKBLOX_DOWN BUTTON_SELECT
75 #define ONEDROCKBLOX_QUIT BUTTON_POWER
77 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
78 #define ONEDROCKBLOX_DOWN BUTTON_RC_PLAY
79 #define ONEDROCKBLOX_QUIT BUTTON_RC_REC
81 #elif (CONFIG_KEYPAD == COWOND2_PAD)
82 #define ONEDROCKBLOX_DOWN BUTTON_MENU
83 #define ONEDROCKBLOX_QUIT BUTTON_POWER
85 #elif CONFIG_KEYPAD == IAUDIO67_PAD
86 #define ONEDROCKBLOX_DOWN BUTTON_MENU
87 #define ONEDROCKBLOX_QUIT BUTTON_POWER
89 #else
90 #error No keymap defined!
91 #endif
93 #define mrand(max) (short)(rb->rand()%max)
95 #define TILES 11
97 /**********
98 ** Lots of defines for the drawing stuff :-)
99 ** The most ugly way i could think of...
102 #if (LCD_WIDTH > LCD_HEIGHT)
103 /* Any screens larger than the minis LCD */
104 #if (LCD_WIDTH > 132)
105 /* Max size of one block */
106 # define WIDTH (int)((LCD_HEIGHT * 0.85) / TILES)
107 /* Align the playing filed centered */
108 # define CENTER_X (int)(LCD_WIDTH/2-(WIDTH/2))
109 # define CENTER_Y (int)(LCD_HEIGHT/2-((WIDTH*TILES+TILES)/2))
110 /* Score box */
111 # define SCORE_X (int)(((CENTER_X+WIDTH+4) + (LCD_WIDTH-(CENTER_X+WIDTH+4))/2)-(f_width/2))
112 # define SCORE_Y (int)((LCD_HEIGHT/2)-(f_height/2))
113 /* Max. size of bricks is 4 blocks */
114 # define NEXT_H (WIDTH*4+3)
115 # define NEXT_X (int)(CENTER_X/2-WIDTH/2)
116 # define NEXT_Y (int)(LCD_HEIGHT/2-NEXT_H/2)
117 #else
118 /* Max size of one block */
119 # define WIDTH (int)((LCD_HEIGHT * 0.85) / TILES)
120 /* Align the playing left centered */
121 # define CENTER_X (int)(LCD_WIDTH*0.2)
122 # define CENTER_Y (int)(LCD_HEIGHT/2-((WIDTH*TILES+TILES)/2))
123 /* Score box */
124 # define SCORE_X (int)(((CENTER_X+WIDTH+4) + (LCD_WIDTH-(CENTER_X+WIDTH+4))/2)-(f_width/2))
125 # define SCORE_Y 16
126 /* Max. size of bricks is 4 blocks */
127 # define NEXT_H (WIDTH*4+3)
128 # define NEXT_X (score_x+f_width+7)
129 # define NEXT_Y (int)(LCD_HEIGHT-((4*WIDTH)+13))
130 #endif
131 #else
132 /* Max size of one block */
133 # define WIDTH (int)((LCD_HEIGHT * 0.8) / TILES)
134 /* Align the playing filed centered */
135 # define CENTER_X (int)(LCD_WIDTH/2-(WIDTH/2))
136 # define CENTER_Y 2
137 /* Score box */
138 # define SCORE_X (int)((LCD_WIDTH/2)-(f_width/2))
139 # define SCORE_Y (LCD_HEIGHT-(f_height+2))
140 /* Max. size of bricks is 4 blocks */
141 # define NEXT_H (WIDTH*4+3)
142 # define NEXT_X (int)(CENTER_X/2-WIDTH/2)
143 # define NEXT_Y (int)((LCD_HEIGHT * 0.8)/2-NEXT_H/2)
144 #endif
146 static const struct plugin_api* rb; /* global api struct pointer */
148 void draw_brick(int pos, int length) {
149 int i = pos;
150 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
151 rb->lcd_fillrect(CENTER_X, CENTER_Y, WIDTH, WIDTH * TILES + TILES);
152 rb->lcd_set_drawmode(DRMODE_SOLID);
154 for (i = pos; i < length + pos; ++i) {
155 if (i >= 0) rb->lcd_fillrect(CENTER_X, CENTER_Y+i+(WIDTH*i), WIDTH, WIDTH);
159 enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter)
161 int i;
162 int f_width, f_height;
163 int score_x;
165 bool quit = false;
166 int button;
168 int cycletime = 300;
169 int end;
171 int pos_cur_brick = 0;
172 int type_cur_brick = 0;
173 int type_next_brick = 0;
175 unsigned long int score = 34126;
176 char score_buf[10];
178 rb = api;
179 (void)parameter;
181 #if LCD_DEPTH > 1
182 rb->lcd_set_backdrop(NULL);
183 rb->lcd_set_background(LCD_BLACK);
184 rb->lcd_set_foreground(LCD_WHITE);
185 #endif
187 rb->lcd_setfont(FONT_SYSFIXED);
189 rb->lcd_getstringsize("100000000", &f_width, &f_height);
191 rb->lcd_clear_display();
193 /***********
194 ** Draw EVERYTHING
197 /* Playing filed box */
198 rb->lcd_vline(CENTER_X-2, CENTER_Y, CENTER_Y + (WIDTH*TILES+TILES));
199 rb->lcd_vline(CENTER_X + WIDTH + 1, CENTER_Y,
200 CENTER_Y + (WIDTH*TILES+TILES));
201 rb->lcd_hline(CENTER_X-2, CENTER_X + WIDTH + 1,
202 CENTER_Y + (WIDTH*TILES+TILES));
204 /* Score box */
205 #if (LCD_WIDTH > LCD_HEIGHT)
206 rb->lcd_drawrect(SCORE_X-4, SCORE_Y-5, f_width+8, f_height+9);
207 rb->lcd_putsxy(SCORE_X-4, SCORE_Y-6-f_height, "score");
208 #else
209 rb->lcd_hline(0, LCD_WIDTH, SCORE_Y-5);
210 rb->lcd_putsxy(2, SCORE_Y-6-f_height, "score");
211 #endif
212 score_x = SCORE_X;
214 /* Next box */
215 rb->lcd_getstringsize("next", &f_width, NULL);
216 #if (LCD_WIDTH > LCD_HEIGHT) && !(LCD_WIDTH > 132)
217 rb->lcd_drawrect(NEXT_X-5, NEXT_Y-5, WIDTH+10, NEXT_H+10);
218 rb->lcd_putsxy(score_x-4, NEXT_Y-5, "next");
219 #else
220 rb->lcd_drawrect(NEXT_X-5, NEXT_Y-5, WIDTH+10, NEXT_H+10);
221 rb->lcd_putsxy(NEXT_X-5, NEXT_Y-5-f_height-1, "next");
222 #endif
224 /***********
225 ** GAMELOOP
227 rb->srand( *rb->current_tick );
229 type_cur_brick = 2 + mrand(3);
230 type_next_brick = 2 + mrand(3);
232 do {
233 end = *rb->current_tick + (cycletime * HZ) / 1000;
235 draw_brick(pos_cur_brick, type_cur_brick);
237 /* Draw next brick */
238 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
239 rb->lcd_fillrect(NEXT_X, NEXT_Y, WIDTH, WIDTH * 4 + 4);
240 rb->lcd_set_drawmode(DRMODE_SOLID);
242 for (i = 0; i < type_next_brick; ++i) {
243 rb->lcd_fillrect(NEXT_X,
244 NEXT_Y + ((type_next_brick % 2) ? (int)(WIDTH/2) : ((type_next_brick == 2) ? (WIDTH+1) : 0)) + (WIDTH*i) + i,
245 WIDTH, WIDTH);
248 /* Score box */
249 rb->snprintf(score_buf, sizeof(score_buf), "%8ld0", score);
250 rb->lcd_putsxy(score_x, SCORE_Y, score_buf);
252 rb->lcd_update();
254 button = rb->button_status();
256 switch(button) {
257 case ONEDROCKBLOX_DOWN:
258 case (ONEDROCKBLOX_DOWN|BUTTON_REPEAT):
259 cycletime = 100;
260 break;
261 case ONEDROCKBLOX_QUIT:
262 quit = true;
263 break;
264 default:
265 cycletime = 300;
266 if(rb->default_event_handler(button) == SYS_USB_CONNECTED) {
267 quit = true;
271 if ((pos_cur_brick + type_cur_brick) > 10) {
272 type_cur_brick = type_next_brick;
273 type_next_brick = 2 + mrand(3);
274 score += (type_cur_brick - 1) * 2;
275 pos_cur_brick = 1 - type_cur_brick;
276 } else {
277 ++pos_cur_brick;
280 if (end > *rb->current_tick)
281 rb->sleep(end-*rb->current_tick);
282 else
283 rb->yield();
285 } while (!quit);
287 return PLUGIN_OK;
289 #endif