Prepare new maemo release
[maemo-rb.git] / apps / plugins / rockblox1d.c
blob6a2b013c44cd9a8ba6d797f7cd653281ee24deac
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"
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)
35 #define TILES 11
37 /**********
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 */
44 #if (LCD_WIDTH > 132)
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))
50 /* Score box */
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)
57 #else
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))
63 /* Score box */
64 # define SCORE_X (int)(((CENTER_X+WIDTH+4) + (LCD_WIDTH-(CENTER_X+WIDTH+4))/2)-(f_width/2))
65 # define SCORE_Y 16
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))
70 #endif
71 #else
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))
76 # define CENTER_Y 2
77 /* Score box */
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)
84 #endif
86 static void draw_brick(int pos, int length) {
87 int i = pos;
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)
99 int i;
100 int f_width, f_height;
101 int score_x;
103 bool quit = false;
104 int button;
106 int cycletime = 300;
107 int end;
109 int pos_cur_brick = 0;
110 int type_cur_brick = 0;
111 int type_next_brick = 0;
113 unsigned long int score = 34126;
115 (void)parameter;
117 #if LCD_DEPTH > 1
118 rb->lcd_set_backdrop(NULL);
119 rb->lcd_set_background(LCD_BLACK);
120 rb->lcd_set_foreground(LCD_WHITE);
121 #endif
123 rb->lcd_setfont(FONT_SYSFIXED);
125 rb->lcd_getstringsize("100000000", &f_width, &f_height);
127 rb->lcd_clear_display();
129 /***********
130 ** Draw EVERYTHING
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));
140 /* Score box */
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");
144 #else
145 rb->lcd_hline(0, LCD_WIDTH, SCORE_Y-5);
146 rb->lcd_putsxy(2, SCORE_Y-6-f_height, "score");
147 #endif
148 score_x = SCORE_X;
150 /* Next box */
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");
155 #else
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");
158 #endif
160 /***********
161 ** GAMELOOP
163 rb->srand( *rb->current_tick );
165 type_cur_brick = 2 + mrand(3);
166 type_next_brick = 2 + mrand(3);
168 do {
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,
181 WIDTH, WIDTH);
184 /* Score box */
185 rb->lcd_putsxyf(score_x, SCORE_Y, "%8ld0", score);
187 rb->lcd_update();
189 /*We get button from PLA this way */
190 button = pluginlib_getaction(TIMEOUT_NOBLOCK, plugin_contexts,
191 ARRAYLEN(plugin_contexts));
193 switch(button) {
194 case ONEDROCKBLOX_DOWN:
195 case ONEDROCKBLOX_DOWN_REPEAT:
196 cycletime = 100;
197 break;
198 case ONEDROCKBLOX_QUIT:
199 case ONEDROCKBLOX_QUIT2:
200 quit = true;
201 break;
202 default:
203 cycletime = 300;
204 if(rb->default_event_handler(button) == SYS_USB_CONNECTED) {
205 quit = true;
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;
214 } else {
215 ++pos_cur_brick;
218 if (TIME_BEFORE(*rb->current_tick, end))
219 rb->sleep(end-*rb->current_tick);
220 else
221 rb->yield();
223 } while (!quit);
225 return PLUGIN_OK;