diff options
Diffstat (limited to 'apps/plugins/rockblox1d.c')
-rw-r--r-- | apps/plugins/rockblox1d.c | 283 |
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 | |||
23 | PLUGIN_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 | |||
140 | static const struct plugin_api* rb; /* global api struct pointer */ | ||
141 | |||
142 | void 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 | |||
153 | enum 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 | ||