summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/maze.c410
1 files changed, 218 insertions, 192 deletions
diff --git a/apps/plugins/maze.c b/apps/plugins/maze.c
index 7f0c058708..f7751ceb48 100644
--- a/apps/plugins/maze.c
+++ b/apps/plugins/maze.c
@@ -31,15 +31,15 @@
31 */ 31 */
32 32
33#include "plugin.h" 33#include "plugin.h"
34#include "pluginlib_actions.h"
35#include "helper.h" 34#include "helper.h"
36 35
37PLUGIN_HEADER 36PLUGIN_HEADER
38 37
38/* key assignments */
39
39#if (CONFIG_KEYPAD == IPOD_4G_PAD) || \ 40#if (CONFIG_KEYPAD == IPOD_4G_PAD) || \
40 (CONFIG_KEYPAD == IPOD_3G_PAD) || \ 41 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
41 (CONFIG_KEYPAD == IPOD_1G2G_PAD) 42 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
42# undef __PLUGINLIB_ACTIONS_H__
43# define MAZE_NEW (BUTTON_SELECT | BUTTON_REPEAT) 43# define MAZE_NEW (BUTTON_SELECT | BUTTON_REPEAT)
44# define MAZE_NEW_PRE BUTTON_SELECT 44# define MAZE_NEW_PRE BUTTON_SELECT
45# define MAZE_QUIT (BUTTON_SELECT | BUTTON_MENU) 45# define MAZE_QUIT (BUTTON_SELECT | BUTTON_MENU)
@@ -54,6 +54,7 @@ PLUGIN_HEADER
54# define MAZE_RDOWN (BUTTON_PLAY | BUTTON_REPEAT) 54# define MAZE_RDOWN (BUTTON_PLAY | BUTTON_REPEAT)
55 55
56#else 56#else
57# include "pluginlib_actions.h"
57# define MAZE_NEW PLA_START 58# define MAZE_NEW PLA_START
58# define MAZE_QUIT PLA_QUIT 59# define MAZE_QUIT PLA_QUIT
59# define MAZE_SOLVE PLA_FIRE 60# define MAZE_SOLVE PLA_FIRE
@@ -65,29 +66,29 @@ PLUGIN_HEADER
65# define MAZE_RLEFT PLA_LEFT_REPEAT 66# define MAZE_RLEFT PLA_LEFT_REPEAT
66# define MAZE_RUP PLA_UP_REPEAT 67# define MAZE_RUP PLA_UP_REPEAT
67# define MAZE_RDOWN PLA_DOWN_REPEAT 68# define MAZE_RDOWN PLA_DOWN_REPEAT
69static const struct button_mapping *plugin_contexts[]
70= {generic_directions, generic_actions};
68 71
69#endif 72#endif
70 73
71/* propertie bits of the cell */ 74/* cell property bits */
72#define WALL_N 0x00000001 75#define WALL_N 0x0001
73#define WALL_E 0x00000002 76#define WALL_E 0x0002
74#define WALL_S 0x00000004 77#define WALL_S 0x0004
75#define WALL_W 0x00000008 78#define WALL_W 0x0008
76#define WALL_ALL 0x0000000F 79#define WALL_ALL (WALL_N | WALL_E | WALL_S | WALL_W)
77 80#define PATH 0x0010
78#define BORDER_N 0x00000010 81
79#define BORDER_E 0x00000020 82/* border tests */
80#define BORDER_S 0x00000040 83#define BORDER_N(y) ((y) == 0)
81#define BORDER_W 0x00000080 84#define BORDER_E(x) ((x) == MAZE_WIDTH-1)
82#define PATH 0x00000100 85#define BORDER_S(y) ((y) == MAZE_HEIGHT-1)
83 86#define BORDER_W(x) ((x) == 0)
87
88/* the API */
84static const struct plugin_api* rb; 89static const struct plugin_api* rb;
85 90
86#ifdef __PLUGINLIB_ACTIONS_H__ 91// we can and should change this to make square boxes
87const struct button_mapping *plugin_contexts[]
88= {generic_directions, generic_actions};
89#endif
90
91#if ( LCD_WIDTH == 112 ) 92#if ( LCD_WIDTH == 112 )
92#define MAZE_WIDTH 16 93#define MAZE_WIDTH 16
93#define MAZE_HEIGHT 12 94#define MAZE_HEIGHT 12
@@ -99,82 +100,41 @@ const struct button_mapping *plugin_contexts[]
99#define MAZE_HEIGHT 24 100#define MAZE_HEIGHT 24
100#endif 101#endif
101 102
102struct coord_stack
103{
104 int data[MAZE_WIDTH*MAZE_HEIGHT];
105 int stp;
106};
107
108void coord_stack_init(struct coord_stack* stack)
109{
110 stack->stp=0;
111}
112
113void coord_stack_push(struct coord_stack* stack, int x, int y)
114{
115 stack->data[stack->stp] = ((x<<8)|y);
116 stack->stp++;
117}
118
119void coord_stack_get(struct coord_stack* stack, int index, int* x, int* y)
120{
121 *y = stack->data[index];
122 *y &= 0xff;
123 *x = (stack->data[index])>>8;
124}
125
126void coord_stack_pop(struct coord_stack* stack, int* x, int* y)
127{
128 stack->stp--;
129 coord_stack_get(stack, stack->stp, x, y);
130}
131
132int coord_stack_count(struct coord_stack* stack)
133{
134 return(stack->stp);
135}
136
137struct maze 103struct maze
138{ 104{
105 int show_path;
139 int solved; 106 int solved;
140 int player_x; 107 int player_x;
141 int player_y; 108 int player_y;
142 unsigned short maze[MAZE_WIDTH][MAZE_HEIGHT]; 109 uint8_t maze[MAZE_WIDTH][MAZE_HEIGHT];
143}; 110};
144 111
145void maze_init(struct maze* maze) 112static void maze_init(struct maze* maze)
146{ 113{
147 int x, y; 114 int x, y;
148 rb->memset(maze->maze, 0, sizeof(maze->maze)); 115
116 /* initialize the properties */
117 maze->show_path = false;
149 maze->solved = false; 118 maze->solved = false;
150 maze->player_x = 0; 119 maze->player_x = 0;
151 maze->player_y = 0; 120 maze->player_y = 0;
152 121
122 /* all walls are up */
153 for(y=0; y<MAZE_HEIGHT; y++){ 123 for(y=0; y<MAZE_HEIGHT; y++){
154 for(x=0; x<MAZE_WIDTH; x++){ 124 for(x=0; x<MAZE_WIDTH; x++){
155 125 maze->maze[x][y] = WALL_ALL;
156 /* all walls are up */
157 maze->maze[x][y] |= WALL_ALL | PATH;
158
159 /* setup borders */
160 if(x == 0)
161 maze->maze[x][y]|= BORDER_W;
162 if(y == 0)
163 maze->maze[x][y]|= BORDER_N;
164 if(x == MAZE_WIDTH-1)
165 maze->maze[x][y]|= BORDER_E;
166 if(y == MAZE_HEIGHT-1)
167 maze->maze[x][y]|= BORDER_S;
168 } 126 }
169 } 127 }
170} 128}
171 129
172void maze_draw(struct maze* maze, struct screen* display) 130static void maze_draw(struct maze* maze, struct screen* display)
173{ 131{
174 int x, y; 132 int x, y;
175 int wx, wy; 133 int wx, wy;
176 int point_width, point_height, point_offset_x, point_offset_y; 134 int point_width, point_height, point_offset_x, point_offset_y;
177 unsigned short cell; 135 uint8_t cell;
136
137 /* calculate the size variables */
178 138
179 wx = (int) display->lcdwidth / MAZE_WIDTH; 139 wx = (int) display->lcdwidth / MAZE_WIDTH;
180 wy = (int) display->lcdheight / MAZE_HEIGHT; 140 wy = (int) display->lcdheight / MAZE_HEIGHT;
@@ -195,14 +155,14 @@ void maze_draw(struct maze* maze, struct screen* display)
195 point_offset_y=1; 155 point_offset_y=1;
196 } 156 }
197 157
158 /* start drawing */
159
198 display->clear_display(); 160 display->clear_display();
199 161
162 /* draw the walls */
200 for(y=0; y<MAZE_HEIGHT; y++){ 163 for(y=0; y<MAZE_HEIGHT; y++){
201 for(x=0; x<MAZE_WIDTH; x++){ 164 for(x=0; x<MAZE_WIDTH; x++){
202
203 cell = maze->maze[x][y]; 165 cell = maze->maze[x][y];
204
205 /* draw walls */
206 if(cell & WALL_N) 166 if(cell & WALL_N)
207 display->hline(x*wx, x*wx+wx, y*wy); 167 display->hline(x*wx, x*wx+wx, y*wy);
208 if(cell & WALL_E) 168 if(cell & WALL_E)
@@ -211,18 +171,11 @@ void maze_draw(struct maze* maze, struct screen* display)
211 display->hline(x*wx, x*wx+wx, y*wy+wy); 171 display->hline(x*wx, x*wx+wx, y*wy+wy);
212 if(cell & WALL_W) 172 if(cell & WALL_W)
213 display->vline(x*wx, y*wy, y*wy+wy); 173 display->vline(x*wx, y*wy, y*wy+wy);
214
215 if(cell & BORDER_N)
216 display->hline(x*wx, x*wx+wx, y*wy);
217 if(cell & BORDER_E)
218 display->vline(x*wx+wx, y*wy, y*wy+wy);
219 if(cell & BORDER_S)
220 display->hline(x*wx, x*wx+wx, y*wy+wy);
221 if(cell & BORDER_W)
222 display->vline(x*wx, y*wy, y*wy+wy);
223 } 174 }
224 } 175 }
225 if(maze->solved){ 176
177 /* draw the path */
178 if(maze->show_path){
226#if LCD_DEPTH >= 16 179#if LCD_DEPTH >= 16
227 if(display->depth>=16) 180 if(display->depth>=16)
228 display->set_foreground(LCD_RGBPACK(127,127,127)); 181 display->set_foreground(LCD_RGBPACK(127,127,127));
@@ -231,6 +184,8 @@ void maze_draw(struct maze* maze, struct screen* display)
231 if(display->depth==2) 184 if(display->depth==2)
232 display->set_foreground(1); 185 display->set_foreground(1);
233#endif 186#endif
187
188 /* highlight the path */
234 for(y=0; y<MAZE_HEIGHT; y++){ 189 for(y=0; y<MAZE_HEIGHT; y++){
235 for(x=0; x<MAZE_WIDTH; x++){ 190 for(x=0; x<MAZE_WIDTH; x++){
236 cell = maze->maze[x][y]; 191 cell = maze->maze[x][y];
@@ -240,6 +195,32 @@ void maze_draw(struct maze* maze, struct screen* display)
240 point_width, point_height); 195 point_width, point_height);
241 } 196 }
242 } 197 }
198
199 /* link the cells in the path together */
200 for(y=0; y<MAZE_HEIGHT; y++){
201 for(x=0; x<MAZE_WIDTH; x++){
202 cell = maze->maze[x][y];
203 if(cell & PATH){
204 if(!(cell & WALL_N) && (maze->maze[x][y-1] & PATH))
205 display->fillrect(x*wx+point_offset_x,
206 y*wy,
207 point_width, wy-point_height);
208 if(!(cell & WALL_E) && (maze->maze[x+1][y] & PATH))
209 display->fillrect(x*wx+wx-point_offset_x,
210 y*wy+point_offset_y,
211 wx-point_width, point_height);
212 if(!(cell & WALL_S) && (maze->maze[x][y+1] & PATH))
213 display->fillrect(x*wx+point_offset_x,
214 y*wy+wy-point_offset_y,
215 point_width, wy-point_height);
216 if(!(cell & WALL_W) && (maze->maze[x-1][y] & PATH))
217 display->fillrect(x*wx,
218 y*wy+point_offset_y,
219 wx-point_width, point_height);
220 }
221 }
222 }
223
243#if LCD_DEPTH >= 16 224#if LCD_DEPTH >= 16
244 if(display->depth>=16) 225 if(display->depth>=16)
245 display->set_foreground(LCD_RGBPACK(0,0,0)); 226 display->set_foreground(LCD_RGBPACK(0,0,0));
@@ -258,64 +239,90 @@ void maze_draw(struct maze* maze, struct screen* display)
258 display->drawline((MAZE_WIDTH-1)*wx,(MAZE_HEIGHT-1)*wy+wy, 239 display->drawline((MAZE_WIDTH-1)*wx,(MAZE_HEIGHT-1)*wy+wy,
259 (MAZE_WIDTH-1)*wx+wx, (MAZE_HEIGHT-1)*wy); 240 (MAZE_WIDTH-1)*wx+wx, (MAZE_HEIGHT-1)*wy);
260 241
261
262 /* draw current position */ 242 /* draw current position */
263 display->fillrect(maze->player_x*wx+point_offset_x, 243 display->fillrect(maze->player_x*wx+point_offset_x,
264 maze->player_y*wy+point_offset_y, 244 maze->player_y*wy+point_offset_y,
265 point_width, point_height); 245 point_width, point_height);
266 246
247 /* update the display */
267 display->update(); 248 display->update();
268} 249}
269 250
270 251
271int maze_pick_random_neighbour_cell_with_walls(struct maze* maze, 252struct coord_stack
253{
254 uint8_t x[MAZE_WIDTH*MAZE_HEIGHT];
255 uint8_t y[MAZE_WIDTH*MAZE_HEIGHT];
256 int stp;
257};
258
259static void coord_stack_init(struct coord_stack* stack)
260{
261 rb->memset(stack->x, 0, sizeof(stack->x));
262 rb->memset(stack->y, 0, sizeof(stack->y));
263 stack->stp = 0;
264}
265
266static void coord_stack_push(struct coord_stack* stack, int x, int y)
267{
268 stack->x[stack->stp] = x;
269 stack->y[stack->stp] = y;
270 stack->stp++;
271}
272
273static void coord_stack_pop(struct coord_stack* stack, int* x, int* y)
274{
275 stack->stp--;
276 *x = stack->x[stack->stp];
277 *y = stack->y[stack->stp];
278}
279
280static int maze_pick_random_neighbour_cell_with_walls(struct maze* maze,
272 int x, int y, int *pnx, int *pny) 281 int x, int y, int *pnx, int *pny)
273{ 282{
283 int n, i;
284 int px[4], py[4];
274 285
275 int ncount = 0; 286 n = 0;
276 struct coord_stack neighbours;
277 unsigned short current_cell=maze->maze[x][y];
278 287
279 coord_stack_init(&neighbours); 288 /* look for neighbours with all walls set up */
280 /* look for neighbour cells with walls */
281 289
282 /* north */ 290 if(!BORDER_N(y) && ((maze->maze[x][y-1] & WALL_ALL) == WALL_ALL)){
283 if(!(current_cell & BORDER_N)){ 291 px[n] = x;
284 if((maze->maze[x][y-1] & WALL_ALL) == WALL_ALL){ 292 py[n] = y-1;
285 coord_stack_push(&neighbours, x, y-1); 293 n++;
286 }
287 } 294 }
288 295
289 /* west */ 296 if(!BORDER_E(x) && ((maze->maze[x+1][y] & WALL_ALL) == WALL_ALL)){
290 if(!(current_cell & BORDER_W)){ 297 px[n] = x+1;
291 if((maze->maze[x-1][y] & WALL_ALL) == WALL_ALL){ 298 py[n] = y;
292 coord_stack_push(&neighbours, x-1, y); 299 n++;
293 }
294 } 300 }
295 301
296 /* east */ 302 if(!BORDER_S(y) && ((maze->maze[x][y+1] & WALL_ALL) == WALL_ALL)){
297 if(!(current_cell & BORDER_E)){ 303 px[n] = x;
298 if((maze->maze[x+1][y] & WALL_ALL) == WALL_ALL){ 304 py[n] = y+1;
299 coord_stack_push(&neighbours, x+1, y); 305 n++;
300 }
301 } 306 }
302 307
303 /* south */ 308 if(!BORDER_W(x) && ((maze->maze[x-1][y] & WALL_ALL) == WALL_ALL)){
304 if(!(current_cell & BORDER_S)){ 309 px[n] = x-1;
305 if((maze->maze[x][y+1] & WALL_ALL) == WALL_ALL){ 310 py[n] = y;
306 coord_stack_push(&neighbours, x, y+1); 311 n++;
307 } 312 }
313
314 /* then choose one */
315 if (n > 0){
316 i = rb->rand() % n;
317 *pnx = px[i];
318 *pny = py[i];
308 } 319 }
309 320
310 /* randomly select neighbour cell with walls */ 321 return n;
311 ncount=coord_stack_count(&neighbours);
312 if(ncount!=0)
313 coord_stack_get(&neighbours, rb->rand()%ncount, pnx, pny);
314 return ncount;
315} 322}
316 323
317/* Removes the wall between the cell (x,y) and the cell (nx,ny) */ 324/* Removes the wall between the cell (x,y) and the cell (nx,ny) */
318void maze_remove_wall(struct maze* maze, int x, int y, int nx, int ny) 325static void maze_remove_wall(struct maze* maze, int x, int y, int nx, int ny)
319{ 326{
320 /* where is our neighbour? */ 327 /* where is our neighbour? */
321 328
@@ -346,7 +353,7 @@ void maze_remove_wall(struct maze* maze, int x, int y, int nx, int ny)
346 } 353 }
347} 354}
348 355
349void maze_generate(struct maze* maze) 356static void maze_generate(struct maze* maze)
350{ 357{
351 int total_cells = MAZE_WIDTH * MAZE_HEIGHT; 358 int total_cells = MAZE_WIDTH * MAZE_HEIGHT;
352 int visited_cells; 359 int visited_cells;
@@ -369,106 +376,120 @@ void maze_generate(struct maze* maze)
369 /* pop from stack */ 376 /* pop from stack */
370 coord_stack_pop(&done_cells, &x, &y); 377 coord_stack_pop(&done_cells, &x, &y);
371 } else { 378 } else {
379 /* remove the wall */
372 maze_remove_wall(maze, x, y, nx, ny); 380 maze_remove_wall(maze, x, y, nx, ny);
373 381 /* save our position on the stack */
374 /* save position on the stack */
375 coord_stack_push(&done_cells, x, y); 382 coord_stack_push(&done_cells, x, y);
376 383 /* move to the next cell */
377 /* current cell = neighbour cell */
378 x=nx; 384 x=nx;
379 y=ny; 385 y=ny;
380 386 /* keep track of visited cells count */
381 visited_cells++; 387 visited_cells++;
382 } 388 }
383 } 389 }
384} 390}
385 391
386 392
387void maze_solve(struct maze* maze) 393static void maze_solve(struct maze* maze)
388{ 394{
389 int x, y; 395 int x, y;
390 int dead_ends = 1; 396 int dead_ends = 1;
391 unsigned short cell; 397 uint8_t cell;
392 unsigned short w; 398 uint8_t wall;
393 unsigned short solved_maze[MAZE_WIDTH][MAZE_HEIGHT]; 399 uint8_t solved_maze[MAZE_WIDTH][MAZE_HEIGHT];
400
401 /* toggle the visibility of the path */
402 maze->show_path = ~(maze->show_path);
394 403
395 maze->solved = ~(maze->solved); 404 /* no need to solve the maze if already solved */
405 if (maze->solved)
406 return;
396 407
397 /* copy maze for solving */ 408 /* work on a copy of the maze */
398 rb->memcpy(solved_maze, maze->maze, 409 rb->memcpy(solved_maze, maze->maze, sizeof(maze->maze));
399 (MAZE_HEIGHT*MAZE_WIDTH*sizeof(maze->maze[0][0])));
400 410
411 /* remove walls on start and end point */
412 solved_maze[0][0] &= ~WALL_N;
413 solved_maze[MAZE_WIDTH-1][MAZE_HEIGHT-1] &= ~WALL_S;
401 414
402 /* remove some borders and walls on start and end point */ 415 /* first, mark all the cells as reachable */
403 solved_maze[0][0] &= ~(WALL_N|BORDER_N); 416 for(y=0; y<MAZE_HEIGHT; y++){
404 solved_maze[MAZE_WIDTH-1][MAZE_HEIGHT-1] &= ~(WALL_S|BORDER_S); 417 for(x=0; x<MAZE_WIDTH; x++){
418 solved_maze[x][y] |= PATH;
419 }
420 }
405 421
422 /* start solving */
406 while(dead_ends){ 423 while(dead_ends){
424 /* solve by blocking off dead ends -- backward approach */
407 dead_ends = 0; 425 dead_ends = 0;
408 /* scan for dead ends */ 426 /* scan for dead ends */
409 for(y=0; y<MAZE_HEIGHT; y++){ 427 for(y=0; y<MAZE_HEIGHT; y++){
410 rb->yield(); 428 rb->yield();
411 for(x=0; x<MAZE_WIDTH; x++){ 429 for(x=0; x<MAZE_WIDTH; x++){
412 cell = solved_maze[x][y]; 430 cell = solved_maze[x][y];
413 w = ~cell & 0x000f; 431 wall = cell & WALL_ALL;
414 if(w == WALL_N || 432 if((wall == (WALL_E | WALL_S | WALL_W)) ||
415 w == WALL_E || 433 (wall == (WALL_N | WALL_S | WALL_W)) ||
416 w == WALL_S || 434 (wall == (WALL_N | WALL_E | WALL_W)) ||
417 w == WALL_W){ 435 (wall == (WALL_N | WALL_E | WALL_S))){
418 /* found dead end, clear path bit and fill it up */ 436 /* found dead end, clear path bit and set all its walls */
419 maze->maze[x][y] &= ~PATH; 437 solved_maze[x][y] &= ~PATH;
420 solved_maze[x][y] |= WALL_ALL; 438 solved_maze[x][y] |= WALL_ALL;
421 /* don't forget the neighbours */ 439 /* don't forget the neighbours */
422 if(!(cell & BORDER_N)) 440 if(!BORDER_S(y))
423 solved_maze[x][y-1]|=WALL_S; 441 solved_maze[x][y+1] |= WALL_N;
424 if(!(cell & BORDER_E)) 442 if(!BORDER_W(x))
425 solved_maze[x+1][y]|=WALL_W; 443 solved_maze[x-1][y] |= WALL_E;
426 if(!(cell & BORDER_S)) 444 if(!BORDER_N(y))
427 solved_maze[x][y+1]|=WALL_N; 445 solved_maze[x][y-1] |= WALL_S;
428 if(!(cell & BORDER_W)) 446 if(!BORDER_E(x))
429 solved_maze[x-1][y]|=WALL_E; 447 solved_maze[x+1][y] |= WALL_W;
430 dead_ends++; 448 dead_ends++;
431 } 449 }
432 } 450 }
433 } 451 }
434 } 452 }
435}
436 453
437void maze_move_player_down(struct maze* maze) 454 /* copy all the path bits to the maze */
438{ 455 for(y=0; y<MAZE_HEIGHT; y++){
439 unsigned short cell=maze->maze[maze->player_x][maze->player_y]; 456 for(x=0; x<MAZE_WIDTH; x++){
440 if( !(cell & WALL_S) && 457 maze->maze[x][y] |= solved_maze[x][y] & PATH;
441 !(cell & BORDER_S)){ 458 }
442 maze->player_y++;
443 } 459 }
460
461 /* mark the maze as solved */
462 maze->solved = true;
444} 463}
445 464
446void maze_move_player_up(struct maze* maze) 465static void maze_move_player_up(struct maze* maze)
447{ 466{
448 unsigned short cell=maze->maze[maze->player_x][maze->player_y]; 467 uint8_t cell = maze->maze[maze->player_x][maze->player_y];
449 if( !(cell & WALL_N) && 468 if(!BORDER_N(maze->player_y) && !(cell & WALL_N))
450 !(cell & BORDER_N)){
451 maze->player_y--; 469 maze->player_y--;
452 }
453} 470}
454 471
455void maze_move_player_left(struct maze* maze) 472static void maze_move_player_right(struct maze* maze)
456{ 473{
457 unsigned short cell=maze->maze[maze->player_x][maze->player_y]; 474 uint8_t cell = maze->maze[maze->player_x][maze->player_y];
458 if( !(cell & WALL_W) && 475 if(!BORDER_E(maze->player_x) && !(cell & WALL_E))
459 !(cell & BORDER_W)){ 476 maze->player_x++;
460 maze->player_x--;
461 }
462} 477}
463 478
464void maze_move_player_right(struct maze* maze) 479static void maze_move_player_down(struct maze* maze)
465{ 480{
466 unsigned short cell=maze->maze[maze->player_x][maze->player_y]; 481 uint8_t cell = maze->maze[maze->player_x][maze->player_y];
467 if( !(cell & WALL_E) && 482 if(!BORDER_S(maze->player_y) && !(cell & WALL_S))
468 !(cell & BORDER_E)){ 483 maze->player_y++;
469 maze->player_x++;
470 }
471} 484}
485
486static void maze_move_player_left(struct maze* maze)
487{
488 uint8_t cell = maze->maze[maze->player_x][maze->player_y];
489 if(!BORDER_W(maze->player_x) && !(cell & WALL_W))
490 maze->player_x--;
491}
492
472/**********************************/ 493/**********************************/
473/* this is the plugin entry point */ 494/* this is the plugin entry point */
474/**********************************/ 495/**********************************/
@@ -483,20 +504,26 @@ enum plugin_status plugin_start(const struct plugin_api* api, const void* parame
483 504
484 /* Turn off backlight timeout */ 505 /* Turn off backlight timeout */
485 backlight_force_on(rb); /* backlight control in lib/helper.c */ 506 backlight_force_on(rb); /* backlight control in lib/helper.c */
486 507
508 /* Seed the RNG */
509 rb->srand(*rb->current_tick);
510
487 FOR_NB_SCREENS(i) 511 FOR_NB_SCREENS(i)
488 rb->screens[i]->set_viewport(NULL); 512 rb->screens[i]->set_viewport(NULL);
489 513
514 /* Draw the background */
490#if LCD_DEPTH > 1 515#if LCD_DEPTH > 1
491 rb->lcd_set_backdrop(NULL); 516 rb->lcd_set_backdrop(NULL);
492#if LCD_DEPTH >= 16 517#if LCD_DEPTH >= 16
493 rb->lcd_set_foreground( LCD_RGBPACK( 0, 0, 0)); 518 rb->lcd_set_foreground(LCD_RGBPACK( 0, 0, 0));
494 rb->lcd_set_background(LCD_RGBPACK(182, 198, 229)); /* rockbox blue */ 519 rb->lcd_set_background(LCD_RGBPACK(182, 198, 229)); /* rockbox blue */
495#elif LCD_DEPTH == 2 520#elif LCD_DEPTH == 2
496 rb->lcd_set_foreground(0); 521 rb->lcd_set_foreground(0);
497 rb->lcd_set_background(LCD_DEFAULT_BG); 522 rb->lcd_set_background(LCD_DEFAULT_BG);
498#endif 523#endif
499#endif 524#endif
525
526 /* Initialize and draw the maze */
500 maze_init(&maze); 527 maze_init(&maze);
501 maze_generate(&maze); 528 maze_generate(&maze);
502 FOR_NB_SCREENS(i) 529 FOR_NB_SCREENS(i)
@@ -524,30 +551,30 @@ enum plugin_status plugin_start(const struct plugin_api* api, const void* parame
524 FOR_NB_SCREENS(i) 551 FOR_NB_SCREENS(i)
525 maze_draw(&maze, rb->screens[i]); 552 maze_draw(&maze, rb->screens[i]);
526 break; 553 break;
527 case MAZE_RIGHT:
528 case MAZE_RRIGHT:
529 maze_move_player_right(&maze);
530 FOR_NB_SCREENS(i)
531 maze_draw(&maze, rb->screens[i]);
532 break;
533 case MAZE_LEFT:
534 case MAZE_RLEFT:
535 maze_move_player_left(&maze);
536 FOR_NB_SCREENS(i)
537 maze_draw(&maze, rb->screens[i]);
538 break;
539 case MAZE_UP: 554 case MAZE_UP:
540 case MAZE_RUP: 555 case MAZE_RUP:
541 maze_move_player_up(&maze); 556 maze_move_player_up(&maze);
542 FOR_NB_SCREENS(i) 557 FOR_NB_SCREENS(i)
543 maze_draw(&maze, rb->screens[i]); 558 maze_draw(&maze, rb->screens[i]);
544 break; 559 break;
560 case MAZE_RIGHT:
561 case MAZE_RRIGHT:
562 maze_move_player_right(&maze);
563 FOR_NB_SCREENS(i)
564 maze_draw(&maze, rb->screens[i]);
565 break;
545 case MAZE_DOWN: 566 case MAZE_DOWN:
546 case MAZE_RDOWN: 567 case MAZE_RDOWN:
547 maze_move_player_down(&maze); 568 maze_move_player_down(&maze);
548 FOR_NB_SCREENS(i) 569 FOR_NB_SCREENS(i)
549 maze_draw(&maze, rb->screens[i]); 570 maze_draw(&maze, rb->screens[i]);
550 break; 571 break;
572 case MAZE_LEFT:
573 case MAZE_RLEFT:
574 maze_move_player_left(&maze);
575 FOR_NB_SCREENS(i)
576 maze_draw(&maze, rb->screens[i]);
577 break;
551 case MAZE_QUIT: 578 case MAZE_QUIT:
552 /* quit plugin */ 579 /* quit plugin */
553 quit=1; 580 quit=1;
@@ -561,8 +588,7 @@ enum plugin_status plugin_start(const struct plugin_api* api, const void* parame
561 } 588 }
562 if( button != BUTTON_NONE ) 589 if( button != BUTTON_NONE )
563 lastbutton = button; 590 lastbutton = button;
564 if(!quit) 591
565 rb->yield(); /* BUG alert: always yielding causes data abort */
566 } 592 }
567 /* Turn on backlight timeout (revert to settings) */ 593 /* Turn on backlight timeout (revert to settings) */
568 backlight_use_settings(rb); /* backlight control in lib/helper.c */ 594 backlight_use_settings(rb); /* backlight control in lib/helper.c */