summaryrefslogtreecommitdiff
path: root/apps/plugins/sokoban.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/sokoban.c')
-rw-r--r--apps/plugins/sokoban.c160
1 files changed, 56 insertions, 104 deletions
diff --git a/apps/plugins/sokoban.c b/apps/plugins/sokoban.c
index bc5bf42e8d..9459f1e869 100644
--- a/apps/plugins/sokoban.c
+++ b/apps/plugins/sokoban.c
@@ -22,53 +22,30 @@
22#include "plugin.h" 22#include "plugin.h"
23#include "lib/playback_control.h" 23#include "lib/playback_control.h"
24 24
25#ifdef HAVE_LCD_BITMAP
26
27PLUGIN_HEADER 25PLUGIN_HEADER
28 26
29#if LCD_DEPTH >= 2 && ((LCD_HEIGHT >= 96 && LCD_WIDTH >= 152) || \
30 (LCD_HEIGHT >= 121 && LCD_WIDTH >= 120))
31extern const fb_data sokoban_tiles[];
32#endif
33
34#define SOKOBAN_TITLE "Sokoban" 27#define SOKOBAN_TITLE "Sokoban"
35 28
36#define SOKOBAN_LEVELS_FILE PLUGIN_GAMES_DIR "/sokoban.levels" 29#define SOKOBAN_LEVELS_FILE PLUGIN_GAMES_DIR "/sokoban.levels"
37#define SOKOBAN_SAVE_FILE PLUGIN_GAMES_DIR "/sokoban.save" 30#define SOKOBAN_SAVE_FILE PLUGIN_GAMES_DIR "/sokoban.save"
38#define SOKOBAN_SAVE_FOLDER "/games" 31#define SOKOBAN_SAVE_FOLDER "/games"
39 32
40/* Magnify is the number of pixels for each block. 33#include "sokoban_tiles.h"
34#define SOKOBAN_TILESIZE BMPWIDTH_sokoban_tiles
35/* SOKOBAN_TILESIZE is the number of pixels for each block.
41 * Set dynamically so all targets can support levels 36 * Set dynamically so all targets can support levels
42 * that fill their entire screen, less the stat box. 37 * that fill their entire screen, less the stat box.
43 * 16 rows & 20 cols minimum */ 38 * 16 rows & 20 cols minimum */
44#if (LCD_HEIGHT >= 224) && (LCD_WIDTH >= 320) 39#if LCD_WIDTH > LCD_HEIGHT /* horizontal layout*/
45#define MAGNIFY 14 40#define ROWS (LCD_HEIGHT/SOKOBAN_TILESIZE)
46#define ROWS (LCD_HEIGHT/MAGNIFY) 41#if (LCD_WIDTH+4) >= (20*SOKOBAN_TILESIZE+40) /* wide or narrow stats box */
47#define COLS ((LCD_WIDTH-40)/MAGNIFY) 42#define COLS ((LCD_WIDTH-40)/SOKOBAN_TILESIZE)
48#elif (LCD_HEIGHT >= 249) && (LCD_WIDTH >= 280)
49#define MAGNIFY 14
50#define ROWS ((LCD_HEIGHT-25)/MAGNIFY)
51#define COLS (LCD_WIDTH/MAGNIFY)
52#elif (LCD_HEIGHT >= 144) && (LCD_WIDTH >= 220)
53#define MAGNIFY 9
54#define ROWS (LCD_HEIGHT/MAGNIFY)
55#define COLS ((LCD_WIDTH-40)/MAGNIFY)
56#elif (LCD_HEIGHT >= 169) && (LCD_WIDTH+4 >= 180) /* plus 4 for sansa */
57#define MAGNIFY 9
58#define ROWS ((LCD_HEIGHT-25)/MAGNIFY)
59#define COLS ((LCD_WIDTH+4)/MAGNIFY)
60#elif (LCD_HEIGHT >= 96) && (LCD_WIDTH >= 160)
61#define MAGNIFY 6
62#define ROWS (LCD_HEIGHT/MAGNIFY)
63#define COLS ((LCD_WIDTH-40)/MAGNIFY)
64#elif (LCD_HEIGHT >= 121) && (LCD_WIDTH >= 120)
65#define MAGNIFY 6
66#define ROWS ((LCD_HEIGHT-25)/MAGNIFY)
67#define COLS (LCD_WIDTH/MAGNIFY)
68#else 43#else
69#define MAGNIFY 4 44#define COLS ((LCD_WIDTH-32)/SOKOBAN_TILESIZE)
70#define ROWS 16 45#endif
71#define COLS 20 46#else /* vertical layout*/
47#define ROWS ((LCD_HEIGHT-25)/SOKOBAN_TILESIZE)
48#define COLS (LCD_WIDTH/SOKOBAN_TILESIZE)
72#endif 49#endif
73 50
74/* Use either all but 16k of the plugin buffer for level data 51/* Use either all but 16k of the plugin buffer for level data
@@ -233,6 +210,22 @@ extern const fb_data sokoban_tiles[];
233#define BUTTON_SAVE BUTTON_SELECT 210#define BUTTON_SAVE BUTTON_SELECT
234#define BUTTON_SAVE_NAME "SELECT" 211#define BUTTON_SAVE_NAME "SELECT"
235 212
213#elif CONFIG_KEYPAD == SANSA_C200_PAD
214#define SOKOBAN_LEFT BUTTON_LEFT
215#define SOKOBAN_RIGHT BUTTON_RIGHT
216#define SOKOBAN_UP BUTTON_UP
217#define SOKOBAN_DOWN BUTTON_DOWN
218#define SOKOBAN_MENU BUTTON_POWER
219#define SOKOBAN_UNDO_PRE BUTTON_SELECT
220#define SOKOBAN_UNDO (BUTTON_SELECT | BUTTON_REL)
221#define SOKOBAN_REDO BUTTON_REC
222#define SOKOBAN_LEVEL_DOWN BUTTON_VOL_DOWN
223#define SOKOBAN_LEVEL_REPEAT (BUTTON_SELECT | BUTTON_RIGHT)
224#define SOKOBAN_LEVEL_UP BUTTON_VOL_UP
225#define SOKOBAN_PAUSE BUTTON_SELECT
226#define BUTTON_SAVE BUTTON_SELECT
227#define BUTTON_SAVE_NAME "SELECT"
228
236#elif CONFIG_KEYPAD == GIGABEAT_S_PAD 229#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
237#define SOKOBAN_LEFT BUTTON_LEFT 230#define SOKOBAN_LEFT BUTTON_LEFT
238#define SOKOBAN_RIGHT BUTTON_RIGHT 231#define SOKOBAN_RIGHT BUTTON_RIGHT
@@ -797,15 +790,7 @@ static void update_screen(void)
797 int c, r; 790 int c, r;
798 int rows, cols; 791 int rows, cols;
799 792
800#if LCD_DEPTH < 2 || ((LCD_HEIGHT < 96 || LCD_WIDTH < 152) && \ 793#if LCD_WIDTH - (COLS*SOKOBAN_TILESIZE) < 32
801 (LCD_HEIGHT < 121 || LCD_WIDTH < 120))
802 int i, j;
803 int max = MAGNIFY - 1;
804 int middle = max/2;
805 int ldelta = (middle + 1)/2;
806#endif
807
808#if LCD_WIDTH - (COLS*MAGNIFY) < 32
809#define STAT_HEIGHT 25 794#define STAT_HEIGHT 25
810#define STAT_X (LCD_WIDTH - 120)/2 795#define STAT_X (LCD_WIDTH - 120)/2
811#define STAT_Y (LCD_HEIGHT - STAT_HEIGHT) 796#define STAT_Y (LCD_HEIGHT - STAT_HEIGHT)
@@ -825,10 +810,10 @@ static void update_screen(void)
825 rb->lcd_drawrect(STAT_X + 37, STAT_Y, 39, STAT_HEIGHT); 810 rb->lcd_drawrect(STAT_X + 37, STAT_Y, 39, STAT_HEIGHT);
826 rb->lcd_drawrect(STAT_X + 75, STAT_Y, 45, STAT_HEIGHT); 811 rb->lcd_drawrect(STAT_X + 75, STAT_Y, 45, STAT_HEIGHT);
827#else 812#else
828#if LCD_WIDTH - (COLS*MAGNIFY) > 40 813#if LCD_WIDTH - (COLS*SOKOBAN_TILESIZE) > 40
829#define STAT_X (LCD_WIDTH - 40) 814#define STAT_X (LCD_WIDTH - 40)
830#else 815#else
831#define STAT_X COLS*MAGNIFY 816#define STAT_X COLS*SOKOBAN_TILESIZE
832#endif 817#endif
833#if LCD_HEIGHT >= 70 818#if LCD_HEIGHT >= 70
834#define STAT_Y (LCD_HEIGHT - 70)/2 819#define STAT_Y (LCD_HEIGHT - 70)/2
@@ -861,87 +846,56 @@ static void update_screen(void)
861 /* load the board to the screen */ 846 /* load the board to the screen */
862 for (rows = 0; rows < ROWS; rows++) { 847 for (rows = 0; rows < ROWS; rows++) {
863 for (cols = 0; cols < COLS; cols++) { 848 for (cols = 0; cols < COLS; cols++) {
864 c = cols*MAGNIFY + 849 c = cols*SOKOBAN_TILESIZE +
865 (BOARD_WIDTH - current_info.level.width*MAGNIFY)/2; 850 (BOARD_WIDTH - current_info.level.width*SOKOBAN_TILESIZE)/2;
866 r = rows*MAGNIFY + 851 r = rows*SOKOBAN_TILESIZE +
867 (BOARD_HEIGHT - current_info.level.height*MAGNIFY)/2; 852 (BOARD_HEIGHT - current_info.level.height*SOKOBAN_TILESIZE)/2;
868 853
869 switch(current_info.board[rows][cols]) { 854 switch(current_info.board[rows][cols]) {
870 case 'X': /* blank space outside of level */ 855 case 'X': /* blank space outside of level */
871 break; 856 break;
872 857
873#if LCD_DEPTH >= 2 && ((LCD_HEIGHT >= 96 && LCD_WIDTH >= 152) || \
874 (LCD_HEIGHT >= 121 && LCD_WIDTH >= 120))
875 case ' ': /* floor */ 858 case ' ': /* floor */
876 rb->lcd_bitmap_part(sokoban_tiles, 0, 0*MAGNIFY, MAGNIFY, 859 rb->lcd_bitmap_part(sokoban_tiles, 0, 0*SOKOBAN_TILESIZE,
877 c, r, MAGNIFY, MAGNIFY); 860 SOKOBAN_TILESIZE, c, r, SOKOBAN_TILESIZE,
861 SOKOBAN_TILESIZE);
878 break; 862 break;
879 863
880 case '#': /* wall */ 864 case '#': /* wall */
881 rb->lcd_bitmap_part(sokoban_tiles, 0, 1*MAGNIFY, MAGNIFY, 865 rb->lcd_bitmap_part(sokoban_tiles, 0, 1*SOKOBAN_TILESIZE,
882 c, r, MAGNIFY, MAGNIFY); 866 SOKOBAN_TILESIZE, c, r, SOKOBAN_TILESIZE,
867 SOKOBAN_TILESIZE);
883 break; 868 break;
884 869
885 case '$': /* box */ 870 case '$': /* box */
886 rb->lcd_bitmap_part(sokoban_tiles, 0, 2*MAGNIFY, MAGNIFY, 871 rb->lcd_bitmap_part(sokoban_tiles, 0, 2*SOKOBAN_TILESIZE,
887 c, r, MAGNIFY, MAGNIFY); 872 SOKOBAN_TILESIZE, c, r, SOKOBAN_TILESIZE,
873 SOKOBAN_TILESIZE);
888 break; 874 break;
889 875
890 case '*': /* box on goal */ 876 case '*': /* box on goal */
891 rb->lcd_bitmap_part(sokoban_tiles, 0, 3*MAGNIFY, MAGNIFY, 877 rb->lcd_bitmap_part(sokoban_tiles, 0, 3*SOKOBAN_TILESIZE,
892 c, r, MAGNIFY, MAGNIFY); 878 SOKOBAN_TILESIZE, c, r, SOKOBAN_TILESIZE,
879 SOKOBAN_TILESIZE);
893 break; 880 break;
894 881
895 case '.': /* goal */ 882 case '.': /* goal */
896 rb->lcd_bitmap_part(sokoban_tiles, 0, 4*MAGNIFY, MAGNIFY, 883 rb->lcd_bitmap_part(sokoban_tiles, 0, 4*SOKOBAN_TILESIZE,
897 c, r, MAGNIFY, MAGNIFY); 884 SOKOBAN_TILESIZE, c, r, SOKOBAN_TILESIZE,
885 SOKOBAN_TILESIZE);
898 break; 886 break;
899 887
900 case '@': /* player */ 888 case '@': /* player */
901 rb->lcd_bitmap_part(sokoban_tiles, 0, 5*MAGNIFY, MAGNIFY, 889 rb->lcd_bitmap_part(sokoban_tiles, 0, 5*SOKOBAN_TILESIZE,
902 c, r, MAGNIFY, MAGNIFY); 890 SOKOBAN_TILESIZE, c, r, SOKOBAN_TILESIZE,
903 break; 891 SOKOBAN_TILESIZE);
904
905 case '+': /* player on goal */
906 rb->lcd_bitmap_part(sokoban_tiles, 0, 6*MAGNIFY, MAGNIFY,
907 c, r, MAGNIFY, MAGNIFY);
908 break;
909#else
910 case '#': /* wall */
911 for (i = c; i < c + MAGNIFY; i++)
912 for (j = r; j < r + MAGNIFY; j++)
913 if ((i ^ j) & 1)
914 rb->lcd_drawpixel(i, j);
915 break;
916
917 case '$': /* box */
918 rb->lcd_drawrect(c, r, MAGNIFY, MAGNIFY);
919 break; 892 break;
920 893
921 case '*': /* box on goal */
922 rb->lcd_drawrect(c, r, MAGNIFY, MAGNIFY);
923 rb->lcd_drawrect(c + MAGNIFY/2 - 1, r + MAGNIFY/2 - 1,
924 MAGNIFY/2, MAGNIFY/2);
925 break;
926
927 case '.': /* goal */
928 rb->lcd_drawrect(c + MAGNIFY/2 - 1, r + MAGNIFY/2 - 1,
929 MAGNIFY/2, MAGNIFY/2);
930 break;
931
932 case '@': /* player */
933 case '+': /* player on goal */ 894 case '+': /* player on goal */
934 rb->lcd_drawline(c, r + middle, c + max, r + middle); 895 rb->lcd_bitmap_part(sokoban_tiles, 0, 6*SOKOBAN_TILESIZE,
935 rb->lcd_drawline(c + middle, r, c + middle, 896 SOKOBAN_TILESIZE, c, r, SOKOBAN_TILESIZE,
936 r + max - ldelta); 897 SOKOBAN_TILESIZE);
937 rb->lcd_drawline(c + max - middle, r, c + max - middle,
938 r + max - ldelta);
939 rb->lcd_drawline(c + middle, r + max - ldelta,
940 c + middle - ldelta, r + max);
941 rb->lcd_drawline(c + max - middle, r + max - ldelta,
942 c + max - middle + ldelta, r + max);
943 break; 898 break;
944#endif
945 } 899 }
946 } 900 }
947 } 901 }
@@ -1617,5 +1571,3 @@ enum plugin_status plugin_start(const struct plugin_api* api, const void* parame
1617 1571
1618 return sokoban_loop(); 1572 return sokoban_loop();
1619} 1573}
1620
1621#endif