summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/plugins/sokoban.c78
1 files changed, 43 insertions, 35 deletions
diff --git a/apps/plugins/sokoban.c b/apps/plugins/sokoban.c
index feddeb1778..c3d97adfa4 100644
--- a/apps/plugins/sokoban.c
+++ b/apps/plugins/sokoban.c
@@ -99,12 +99,13 @@ PLUGIN_HEADER
99#endif 99#endif
100 100
101#ifdef HAVE_LCD_COLOR 101#ifdef HAVE_LCD_COLOR
102#define WALL_COLOR LCD_RGBPACK(16,20,180) /* Color of the walls */ 102#define WALL_COLOR LCD_RGBPACK(16,20,180) /* Color of the walls */
103#define FREE_TARGET_COLOR LCD_RGBPACK(251,158,25) /* Color of a 'target' without a block on top */ 103#define FREE_TARGET_COLOR LCD_RGBPACK(251,158,25) /* Color of a 'target' without a block on top */
104#define USED_TARGET_COLOR LCD_RGBPACK(255,255,255) /* Color of a 'target' with a block on top */ 104#define USED_TARGET_COLOR LCD_RGBPACK(255,255,255) /* Color of a 'target' with a block on top */
105#define FREE_BLOCK_COLOR LCD_RGBPACK(22,130,53) /* Color of a block when it's not on a 'target' */ 105#define FREE_BLOCK_COLOR LCD_RGBPACK(22,130,53) /* Color of a block when it's not on a 'target' */
106#define USED_BLOCK_COLOR LCD_RGBPACK(22,130,53) /* Color of a block when it is on a 'target' */ 106#define USED_BLOCK_COLOR LCD_RGBPACK(22,130,53) /* Color of a block when it is on a 'target' */
107#define CHAR_COLOR LCD_BLACK /* Color of the 'character' */ 107#define CHAR_COLOR LCD_BLACK /* Color of the 'character' */
108#define BG_COLOR LCD_RGBPACK(181,199,231) /* Background color. Default Rockbox light blue. */
108 109
109#elif LCD_DEPTH > 1 110#elif LCD_DEPTH > 1
110#define MEDIUM_GRAY LCD_BRIGHTNESS(127) 111#define MEDIUM_GRAY LCD_BRIGHTNESS(127)
@@ -122,8 +123,8 @@ static void init_boards(void);
122static void update_screen(void); 123static void update_screen(void);
123static bool sokoban_loop(void); 124static bool sokoban_loop(void);
124 125
125/* The Location, Undo and LevelInfo structs are OO-flavored. 126/* The Location, Undo and LevelInfo structs are OO-flavored.
126 * (oooh!-flavored as Schnueff puts it.) It makes more you have to know, 127 * (oooh!-flavored as Schnueff puts it.) It makes more you have to know,
127 * but the overall data layout becomes more manageable. */ 128 * but the overall data layout becomes more manageable. */
128 129
129/* We use the same three values in 2 structs. Makeing them a struct 130/* We use the same three values in 2 structs. Makeing them a struct
@@ -193,7 +194,7 @@ static void undo(void)
193 194
194 /* Update board info */ 195 /* Update board info */
195 undo = &undo_info.history[undo_info.current]; 196 undo = &undo_info.history[undo_info.current];
196 197
197 rb->memcpy(&current_info.level, &undo->level, sizeof(undo->level)); 198 rb->memcpy(&current_info.level, &undo->level, sizeof(undo->level));
198 rb->memcpy(&current_info.player, &undo->location[0], sizeof(undo->location[0])); 199 rb->memcpy(&current_info.player, &undo->location[0], sizeof(undo->location[0]));
199 200
@@ -218,7 +219,7 @@ static void undo(void)
218 } else { 219 } else {
219 undo_info.current--; 220 undo_info.current--;
220 } 221 }
221 222
222 undo_info.count--; 223 undo_info.count--;
223 224
224 return; 225 return;
@@ -235,7 +236,7 @@ static void add_undo(int button)
235 return; 236 return;
236 237
237 if (undo_info.count != 0) { 238 if (undo_info.count != 0) {
238 if (undo_info.current < (MAX_UNDOS - 1)) 239 if (undo_info.current < (MAX_UNDOS - 1))
239 undo_info.current++; 240 undo_info.current++;
240 else 241 else
241 undo_info.current = 0; 242 undo_info.current = 0;
@@ -250,8 +251,8 @@ static void add_undo(int button)
250 /* Store our player info */ 251 /* Store our player info */
251 rb->memcpy(&undo->location[0], &current_info.player, sizeof(undo->location[0])); 252 rb->memcpy(&undo->location[0], &current_info.player, sizeof(undo->location[0]));
252 253
253 /* Now we need to store upto 2 blocks that may be affected. 254 /* Now we need to store upto 2 blocks that may be affected.
254 * If player.spot is NULL, then there is no info stored 255 * If player.spot is NULL, then there is no info stored
255 * for that block */ 256 * for that block */
256 257
257 row = current_info.player.row; 258 row = current_info.player.row;
@@ -264,13 +265,13 @@ static void add_undo(int button)
264 switch (button) { 265 switch (button) {
265 case BUTTON_LEFT: 266 case BUTTON_LEFT:
266 col--; 267 col--;
267 if (col < 0) 268 if (col < 0)
268 storable = false; 269 storable = false;
269 break; 270 break;
270 271
271 case BUTTON_RIGHT: 272 case BUTTON_RIGHT:
272 col++; 273 col++;
273 if (col >= COLS) 274 if (col >= COLS)
274 storable = false; 275 storable = false;
275 break; 276 break;
276 277
@@ -279,7 +280,7 @@ static void add_undo(int button)
279 if (row < 0) 280 if (row < 0)
280 storable = false; 281 storable = false;
281 break; 282 break;
282 283
283 case SOKOBAN_DOWN: 284 case SOKOBAN_DOWN:
284 row++; 285 row++;
285 if (row >= ROWS) 286 if (row >= ROWS)
@@ -299,7 +300,7 @@ static void add_undo(int button)
299 } 300 }
300 } 301 }
301 302
302 if (undo_info.count < MAX_UNDOS) 303 if (undo_info.count < MAX_UNDOS)
303 undo_info.count++; 304 undo_info.count++;
304} 305}
305 306
@@ -313,13 +314,13 @@ static void init_boards(void)
313 current_info.player.spot = ' '; 314 current_info.player.spot = ' ';
314 current_info.max_level = 0; 315 current_info.max_level = 0;
315 current_info.loaded_level = 0; 316 current_info.loaded_level = 0;
316 317
317 buffered_boards.low = 0; 318 buffered_boards.low = 0;
318 319
319 init_undo(); 320 init_undo();
320} 321}
321 322
322static int read_levels(int initialize_count) 323static int read_levels(int initialize_count)
323{ 324{
324 int fd = 0; 325 int fd = 0;
325 int len; 326 int len;
@@ -333,15 +334,15 @@ static int read_levels(int initialize_count)
333 endpoint = current_info.level.level - MAX_BUFFERED_BOARDS; 334 endpoint = current_info.level.level - MAX_BUFFERED_BOARDS;
334 335
335 if (endpoint < 0) endpoint = 0; 336 if (endpoint < 0) endpoint = 0;
336 337
337 buffered_boards.low = endpoint; 338 buffered_boards.low = endpoint;
338 endpoint += MAX_BUFFERED_BOARDS; 339 endpoint += MAX_BUFFERED_BOARDS;
339 340
340 if ((fd = rb->open(LEVELS_FILE, O_RDONLY)) < 0) { 341 if ((fd = rb->open(LEVELS_FILE, O_RDONLY)) < 0) {
341 rb->splash(0, true, "Unable to open %s", LEVELS_FILE); 342 rb->splash(0, true, "Unable to open %s", LEVELS_FILE);
342 return -1; 343 return -1;
343 } 344 }
344 345
345 do { 346 do {
346 len = rb->read_line(fd, buffer, sizeof(buffer)); 347 len = rb->read_line(fd, buffer, sizeof(buffer));
347 if (len >= 3) { 348 if (len >= 3) {
@@ -380,7 +381,7 @@ static int read_levels(int initialize_count)
380 } 381 }
381 return 0; 382 return 0;
382} 383}
383 384
384/* return non-zero on error */ 385/* return non-zero on error */
385static void load_level(void) 386static void load_level(void)
386{ 387{
@@ -388,7 +389,7 @@ static void load_level(void)
388 int r = 0; 389 int r = 0;
389 int index = current_info.level.level - buffered_boards.low - 1; 390 int index = current_info.level.level - buffered_boards.low - 1;
390 struct Board *level; 391 struct Board *level;
391 392
392 if (index < 0 || index >= MAX_BUFFERED_BOARDS) { 393 if (index < 0 || index >= MAX_BUFFERED_BOARDS) {
393 read_levels(false); 394 read_levels(false);
394 index=index<0?MAX_BUFFERED_BOARDS-1:0; 395 index=index<0?MAX_BUFFERED_BOARDS-1:0;
@@ -403,7 +404,7 @@ static void load_level(void)
403 for (r = 0; r < ROWS; r++) { 404 for (r = 0; r < ROWS; r++) {
404 for (c = 0; c < COLS; c++) { 405 for (c = 0; c < COLS; c++) {
405 current_info.board[r][c] = level->spaces[r][c]; 406 current_info.board[r][c] = level->spaces[r][c];
406 407
407 if (current_info.board[r][c] == '.') 408 if (current_info.board[r][c] == '.')
408 current_info.level.boxes_to_go++; 409 current_info.level.boxes_to_go++;
409 410
@@ -416,7 +417,7 @@ static void load_level(void)
416} 417}
417#define STAT_WIDTH (LCD_WIDTH-(COLS * magnify)) 418#define STAT_WIDTH (LCD_WIDTH-(COLS * magnify))
418 419
419static void update_screen(void) 420static void update_screen(void)
420{ 421{
421 int b = 0, c = 0; 422 int b = 0, c = 0;
422 int rows = 0, cols = 0; 423 int rows = 0, cols = 0;
@@ -429,7 +430,7 @@ static void update_screen(void)
429#else 430#else
430 int magnify = 4; 431 int magnify = 4;
431#endif 432#endif
432 433
433 /* load the board to the screen */ 434 /* load the board to the screen */
434 for (rows=0 ; rows < ROWS ; rows++) { 435 for (rows=0 ; rows < ROWS ; rows++) {
435 for (cols = 0 ; cols < COLS ; cols++) { 436 for (cols = 0 ; cols < COLS ; cols++) {
@@ -488,16 +489,16 @@ static void update_screen(void)
488#endif 489#endif
489 rb->lcd_drawline(c, b+middle, c+max, b+middle); 490 rb->lcd_drawline(c, b+middle, c+max, b+middle);
490 rb->lcd_drawline(c+middle, b, c+middle, b+max-ldelta); 491 rb->lcd_drawline(c+middle, b, c+middle, b+max-ldelta);
491 rb->lcd_drawline(c+max-middle, b, 492 rb->lcd_drawline(c+max-middle, b,
492 c+max-middle, b+max-ldelta); 493 c+max-middle, b+max-ldelta);
493 rb->lcd_drawline(c+middle, b+max-ldelta, 494 rb->lcd_drawline(c+middle, b+max-ldelta,
494 c+middle-ldelta, b+max); 495 c+middle-ldelta, b+max);
495 rb->lcd_drawline(c+max-middle, b+max-ldelta, 496 rb->lcd_drawline(c+max-middle, b+max-ldelta,
496 c+max-middle+ldelta, b+max); 497 c+max-middle+ldelta, b+max);
497 } 498 }
498 break; 499 break;
499 500
500 case '%': /* this is a box on a home spot */ 501 case '%': /* this is a box on a home spot */
501 502
502#ifdef HAVE_LCD_COLOR 503#ifdef HAVE_LCD_COLOR
503 rb->lcd_set_foreground(USED_BLOCK_COLOR); 504 rb->lcd_set_foreground(USED_BLOCK_COLOR);
@@ -549,7 +550,7 @@ static bool sokoban_loop(void)
549 current_info.level.level = 1; 550 current_info.level.level = 1;
550 551
551 load_level(); 552 load_level();
552 update_screen(); 553 update_screen();
553 554
554 while (1) { 555 while (1) {
555 moved = true; 556 moved = true;
@@ -561,10 +562,13 @@ static bool sokoban_loop(void)
561 562
562 add_undo(button); 563 add_undo(button);
563 564
564 switch(button) 565 switch(button)
565 { 566 {
566 case SOKOBAN_QUIT: 567 case SOKOBAN_QUIT:
567 /* get out of here */ 568 /* get out of here */
569#ifdef HAVE_LCD_COLOR /* reset background color */
570 rb->lcd_set_background(rb->global_settings->bg_color);
571#endif
568 return PLUGIN_OK; 572 return PLUGIN_OK;
569 573
570 case SOKOBAN_UNDO: 574 case SOKOBAN_UNDO:
@@ -877,7 +881,7 @@ static bool sokoban_loop(void)
877 moved = false; 881 moved = false;
878 break; 882 break;
879 } 883 }
880 884
881 if (button != BUTTON_NONE) 885 if (button != BUTTON_NONE)
882 lastbutton = button; 886 lastbutton = button;
883 887
@@ -898,7 +902,7 @@ static bool sokoban_loop(void)
898 902
899 if (current_info.level.level > current_info.max_level) { 903 if (current_info.level.level > current_info.max_level) {
900 /* Center "You WIN!!" on all screen sizes */ 904 /* Center "You WIN!!" on all screen sizes */
901 rb->lcd_putsxy(LCD_WIDTH/2 - 27,(LCD_HEIGHT/2) - 4 , 905 rb->lcd_putsxy(LCD_WIDTH/2 - 27,(LCD_HEIGHT/2) - 4 ,
902 "You WIN!!"); 906 "You WIN!!");
903 907
904 rb->lcd_set_drawmode(DRMODE_COMPLEMENT); 908 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
@@ -934,10 +938,14 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
934 938
935 (void)(parameter); 939 (void)(parameter);
936 rb = api; 940 rb = api;
937 941
938 rb->lcd_setfont(FONT_SYSFIXED); 942 rb->lcd_setfont(FONT_SYSFIXED);
939 rb->lcd_getstringsize(SOKOBAN_TITLE, &w, &h); 943 rb->lcd_getstringsize(SOKOBAN_TITLE, &w, &h);
940 944
945#ifdef HAVE_LCD_COLOR
946 rb->lcd_set_background(BG_COLOR);
947#endif
948
941 /* Get horizontel centering for text */ 949 /* Get horizontel centering for text */
942 len = w; 950 len = w;
943 if (len%2 != 0) 951 if (len%2 != 0)