summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/plugins/maze.c410
-rw-r--r--docs/CREDITS1
2 files changed, 219 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 */
diff --git a/docs/CREDITS b/docs/CREDITS
index 08880ba4ac..aa8b5be059 100644
--- a/docs/CREDITS
+++ b/docs/CREDITS
@@ -399,6 +399,7 @@ Maciej Adamczak
399Tomer Shalev 399Tomer Shalev
400Thibaut Girka 400Thibaut Girka
401Rasmus Ry 401Rasmus Ry
402William Poetra Yoga Hadisoeseno
402 403
403The libmad team 404The libmad team
404The wavpack team 405The wavpack team