diff options
Diffstat (limited to 'apps/plugins/sokoban.c')
-rw-r--r-- | apps/plugins/sokoban.c | 205 |
1 files changed, 145 insertions, 60 deletions
diff --git a/apps/plugins/sokoban.c b/apps/plugins/sokoban.c index 976f552dbd..a9ac711b67 100644 --- a/apps/plugins/sokoban.c +++ b/apps/plugins/sokoban.c | |||
@@ -33,8 +33,9 @@ extern const fb_data sokoban_tiles[]; | |||
33 | 33 | ||
34 | #define SOKOBAN_TITLE "Sokoban" | 34 | #define SOKOBAN_TITLE "Sokoban" |
35 | 35 | ||
36 | #define SOKOBAN_LEVELS_FILE PLUGIN_DIR "/sokobanlevels.sok" | 36 | #define SOKOBAN_LEVELS_FILE PLUGIN_DIR "/sokoban.levels" |
37 | #define SOKOBAN_SAVE_FILE PLUGIN_DIR "/sokobansave.sok" | 37 | #define SOKOBAN_SAVE_FILE PLUGIN_DIR "/sokoban.save" |
38 | #define SOKOBAN_SAVE_FOLDER "/games" | ||
38 | 39 | ||
39 | /* Magnify is the number of pixels for each block. | 40 | /* Magnify is the number of pixels for each block. |
40 | * Set dynamically so all targets can support levels | 41 | * Set dynamically so all targets can support levels |
@@ -112,6 +113,7 @@ extern const fb_data sokoban_tiles[]; | |||
112 | #define SOKOBAN_LEVEL_DOWN BUTTON_F1 | 113 | #define SOKOBAN_LEVEL_DOWN BUTTON_F1 |
113 | #define SOKOBAN_LEVEL_REPEAT BUTTON_F2 | 114 | #define SOKOBAN_LEVEL_REPEAT BUTTON_F2 |
114 | #define SOKOBAN_LEVEL_UP BUTTON_F3 | 115 | #define SOKOBAN_LEVEL_UP BUTTON_F3 |
116 | #define SOKOBAN_PAUSE BUTTON_PLAY | ||
115 | #define BUTTON_SAVE BUTTON_ON | 117 | #define BUTTON_SAVE BUTTON_ON |
116 | #define BUTTON_SAVE_NAME "ON" | 118 | #define BUTTON_SAVE_NAME "ON" |
117 | 119 | ||
@@ -125,6 +127,7 @@ extern const fb_data sokoban_tiles[]; | |||
125 | #define SOKOBAN_LEVEL_DOWN (BUTTON_MENU | BUTTON_LEFT) | 127 | #define SOKOBAN_LEVEL_DOWN (BUTTON_MENU | BUTTON_LEFT) |
126 | #define SOKOBAN_LEVEL_REPEAT (BUTTON_MENU | BUTTON_UP) | 128 | #define SOKOBAN_LEVEL_REPEAT (BUTTON_MENU | BUTTON_UP) |
127 | #define SOKOBAN_LEVEL_UP (BUTTON_MENU | BUTTON_RIGHT) | 129 | #define SOKOBAN_LEVEL_UP (BUTTON_MENU | BUTTON_RIGHT) |
130 | #define SOKOBAN_PAUSE BUTTON_MENU | ||
128 | #define BUTTON_SAVE BUTTON_MENU | 131 | #define BUTTON_SAVE BUTTON_MENU |
129 | #define BUTTON_SAVE_NAME "MENU" | 132 | #define BUTTON_SAVE_NAME "MENU" |
130 | 133 | ||
@@ -138,10 +141,11 @@ extern const fb_data sokoban_tiles[]; | |||
138 | #define SOKOBAN_LEVEL_DOWN (BUTTON_ON | BUTTON_DOWN) | 141 | #define SOKOBAN_LEVEL_DOWN (BUTTON_ON | BUTTON_DOWN) |
139 | #define SOKOBAN_LEVEL_REPEAT BUTTON_ON | 142 | #define SOKOBAN_LEVEL_REPEAT BUTTON_ON |
140 | #define SOKOBAN_LEVEL_UP (BUTTON_ON | BUTTON_UP) | 143 | #define SOKOBAN_LEVEL_UP (BUTTON_ON | BUTTON_UP) |
144 | #define SOKOBAN_PAUSE BUTTON_ON | ||
141 | #define BUTTON_SAVE BUTTON_MODE | 145 | #define BUTTON_SAVE BUTTON_MODE |
142 | #define BUTTON_SAVE_NAME "MODE" | 146 | #define BUTTON_SAVE_NAME "MODE" |
143 | 147 | ||
144 | #define SOKOBAN_RC_QUIT BUTTON_RC_STOP | 148 | #define SOKOBAN_RC_MENU BUTTON_RC_STOP |
145 | 149 | ||
146 | #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ | 150 | #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ |
147 | (CONFIG_KEYPAD == IPOD_3G_PAD) | 151 | (CONFIG_KEYPAD == IPOD_3G_PAD) |
@@ -153,19 +157,21 @@ extern const fb_data sokoban_tiles[]; | |||
153 | #define SOKOBAN_REDO (BUTTON_SELECT | BUTTON_PLAY) | 157 | #define SOKOBAN_REDO (BUTTON_SELECT | BUTTON_PLAY) |
154 | #define SOKOBAN_LEVEL_DOWN (BUTTON_SELECT | BUTTON_LEFT) | 158 | #define SOKOBAN_LEVEL_DOWN (BUTTON_SELECT | BUTTON_LEFT) |
155 | #define SOKOBAN_LEVEL_UP (BUTTON_SELECT | BUTTON_RIGHT) | 159 | #define SOKOBAN_LEVEL_UP (BUTTON_SELECT | BUTTON_RIGHT) |
160 | #define SOKOBAN_PAUSE BUTTON_SELECT | ||
156 | #define BUTTON_SAVE BUTTON_SELECT | 161 | #define BUTTON_SAVE BUTTON_SELECT |
157 | #define BUTTON_SAVE_NAME "SELECT" | 162 | #define BUTTON_SAVE_NAME "SELECT" |
158 | 163 | ||
159 | /* FIXME: if/when simultaneous button presses work for X5, | 164 | /* FIXME: if/when simultaneous button presses work for X5/M5, |
160 | * add redo & level repeat */ | 165 | * add level up/down */ |
161 | #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD | 166 | #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD |
162 | #define SOKOBAN_UP BUTTON_UP | 167 | #define SOKOBAN_UP BUTTON_UP |
163 | #define SOKOBAN_DOWN BUTTON_DOWN | 168 | #define SOKOBAN_DOWN BUTTON_DOWN |
164 | #define SOKOBAN_MENU BUTTON_POWER | 169 | #define SOKOBAN_MENU BUTTON_POWER |
165 | #define SOKOBAN_UNDO_PRE BUTTON_SELECT | 170 | #define SOKOBAN_UNDO_PRE BUTTON_SELECT |
166 | #define SOKOBAN_UNDO (BUTTON_SELECT | BUTTON_REL) | 171 | #define SOKOBAN_UNDO (BUTTON_SELECT | BUTTON_REL) |
167 | #define SOKOBAN_LEVEL_DOWN BUTTON_REC | 172 | #define SOKOBAN_LEVEL_REPEAT BUTTON_REC |
168 | #define SOKOBAN_LEVEL_UP BUTTON_PLAY | 173 | #define SOKOBAN_REDO BUTTON_PLAY |
174 | #define SOKOBAN_PAUSE BUTTON_PLAY | ||
169 | #define BUTTON_SAVE BUTTON_SELECT | 175 | #define BUTTON_SAVE BUTTON_SELECT |
170 | #define BUTTON_SAVE_NAME "SELECT" | 176 | #define BUTTON_SAVE_NAME "SELECT" |
171 | 177 | ||
@@ -179,6 +185,7 @@ extern const fb_data sokoban_tiles[]; | |||
179 | #define SOKOBAN_LEVEL_DOWN (BUTTON_PLAY | BUTTON_SCROLL_DOWN) | 185 | #define SOKOBAN_LEVEL_DOWN (BUTTON_PLAY | BUTTON_SCROLL_DOWN) |
180 | #define SOKOBAN_LEVEL_REPEAT (BUTTON_PLAY | BUTTON_RIGHT) | 186 | #define SOKOBAN_LEVEL_REPEAT (BUTTON_PLAY | BUTTON_RIGHT) |
181 | #define SOKOBAN_LEVEL_UP (BUTTON_PLAY | BUTTON_SCROLL_UP) | 187 | #define SOKOBAN_LEVEL_UP (BUTTON_PLAY | BUTTON_SCROLL_UP) |
188 | #define SOKOBAN_PAUSE BUTTON_PLAY | ||
182 | #define BUTTON_SAVE BUTTON_PLAY | 189 | #define BUTTON_SAVE BUTTON_PLAY |
183 | #define BUTTON_SAVE_NAME "PLAY" | 190 | #define BUTTON_SAVE_NAME "PLAY" |
184 | 191 | ||
@@ -191,6 +198,7 @@ extern const fb_data sokoban_tiles[]; | |||
191 | #define SOKOBAN_LEVEL_DOWN BUTTON_VOL_DOWN | 198 | #define SOKOBAN_LEVEL_DOWN BUTTON_VOL_DOWN |
192 | #define SOKOBAN_LEVEL_REPEAT BUTTON_MENU | 199 | #define SOKOBAN_LEVEL_REPEAT BUTTON_MENU |
193 | #define SOKOBAN_LEVEL_UP BUTTON_VOL_UP | 200 | #define SOKOBAN_LEVEL_UP BUTTON_VOL_UP |
201 | #define SOKOBAN_PAUSE BUTTON_SELECT | ||
194 | #define BUTTON_SAVE BUTTON_SELECT | 202 | #define BUTTON_SAVE BUTTON_SELECT |
195 | #define BUTTON_SAVE_NAME "SELECT" | 203 | #define BUTTON_SAVE_NAME "SELECT" |
196 | 204 | ||
@@ -204,6 +212,7 @@ extern const fb_data sokoban_tiles[]; | |||
204 | #define SOKOBAN_LEVEL_DOWN (BUTTON_SELECT | BUTTON_DOWN) | 212 | #define SOKOBAN_LEVEL_DOWN (BUTTON_SELECT | BUTTON_DOWN) |
205 | #define SOKOBAN_LEVEL_REPEAT (BUTTON_SELECT | BUTTON_RIGHT) | 213 | #define SOKOBAN_LEVEL_REPEAT (BUTTON_SELECT | BUTTON_RIGHT) |
206 | #define SOKOBAN_LEVEL_UP (BUTTON_SELECT | BUTTON_UP) | 214 | #define SOKOBAN_LEVEL_UP (BUTTON_SELECT | BUTTON_UP) |
215 | #define SOKOBAN_PAUSE BUTTON_SELECT | ||
207 | #define BUTTON_SAVE BUTTON_SELECT | 216 | #define BUTTON_SAVE BUTTON_SELECT |
208 | #define BUTTON_SAVE_NAME "SELECT" | 217 | #define BUTTON_SAVE_NAME "SELECT" |
209 | 218 | ||
@@ -218,7 +227,7 @@ extern const fb_data sokoban_tiles[]; | |||
218 | 227 | ||
219 | /* Level data & stats */ | 228 | /* Level data & stats */ |
220 | struct LevelInfo { | 229 | struct LevelInfo { |
221 | short index; /* Level index (level number - 1) */ | 230 | int index; /* Level index (level number - 1) */ |
222 | int moves; /* Moves & pushes for the stats */ | 231 | int moves; /* Moves & pushes for the stats */ |
223 | int pushes; | 232 | int pushes; |
224 | short boxes_to_go; /* Number of unplaced boxes remaining in level */ | 233 | short boxes_to_go; /* Number of unplaced boxes remaining in level */ |
@@ -294,7 +303,7 @@ static void get_delta(char direction, short *d_r, short *d_c) | |||
294 | } | 303 | } |
295 | } | 304 | } |
296 | 305 | ||
297 | static void undo(void) | 306 | static bool undo(void) |
298 | { | 307 | { |
299 | char undo; | 308 | char undo; |
300 | short r, c; | 309 | short r, c; |
@@ -304,7 +313,7 @@ static void undo(void) | |||
304 | 313 | ||
305 | /* If no more undos or we've wrapped all the way around, quit */ | 314 | /* If no more undos or we've wrapped all the way around, quit */ |
306 | if (undo_info.count == 0 || undo_info.current - 1 == undo_info.max) | 315 | if (undo_info.count == 0 || undo_info.current - 1 == undo_info.max) |
307 | return; | 316 | return false; |
308 | 317 | ||
309 | /* Move to previous undo in the list */ | 318 | /* Move to previous undo in the list */ |
310 | if (undo_info.current == 0 && undo_info.count > 1) | 319 | if (undo_info.current == 0 && undo_info.count > 1) |
@@ -356,7 +365,7 @@ static void undo(void) | |||
356 | 365 | ||
357 | current_info.level.moves--; | 366 | current_info.level.moves--; |
358 | 367 | ||
359 | return; | 368 | return true; |
360 | } | 369 | } |
361 | 370 | ||
362 | static void add_undo(char undo) | 371 | static void add_undo(char undo) |
@@ -844,9 +853,22 @@ static void draw_level(void) | |||
844 | static bool save(char *filename, bool solution) | 853 | static bool save(char *filename, bool solution) |
845 | { | 854 | { |
846 | int fd; | 855 | int fd; |
856 | char *loc; | ||
857 | DIR *dir; | ||
858 | char dirname[MAX_PATH]; | ||
847 | 859 | ||
848 | rb->splash(0, "Saving..."); | 860 | rb->splash(0, "Saving..."); |
849 | 861 | ||
862 | /* Create dir if it doesn't exist */ | ||
863 | if ((loc = rb->strrchr(filename, '/')) != NULL) { | ||
864 | rb->strncpy(dirname, filename, loc - filename); | ||
865 | dirname[loc - filename] = '\0'; | ||
866 | if(!(dir = rb->opendir(dirname))) | ||
867 | rb->mkdir(dirname); | ||
868 | else | ||
869 | rb->closedir(dir); | ||
870 | } | ||
871 | |||
850 | if (filename[0] == '\0' || | 872 | if (filename[0] == '\0' || |
851 | (fd = rb->open(filename, O_WRONLY|O_CREAT|O_TRUNC)) < 0) { | 873 | (fd = rb->open(filename, O_WRONLY|O_CREAT|O_TRUNC)) < 0) { |
852 | rb->splash(HZ*2, "Unable to open %s", filename); | 874 | rb->splash(HZ*2, "Unable to open %s", filename); |
@@ -874,11 +896,13 @@ static bool save(char *filename, bool solution) | |||
874 | static bool load(char *filename, bool silent) | 896 | static bool load(char *filename, bool silent) |
875 | { | 897 | { |
876 | int fd; | 898 | int fd; |
877 | int i = 0, n; | 899 | int i, n; |
878 | int len; | 900 | int len; |
879 | bool play_solution; | ||
880 | int button; | 901 | int button; |
881 | int step_delay = HZ/4; | 902 | bool play_solution; |
903 | bool paused = false; | ||
904 | unsigned short speed = 2; | ||
905 | int delay[] = {HZ/2, HZ/3, HZ/4, HZ/6, HZ/8, HZ/12, HZ/16, HZ/25}; | ||
882 | 906 | ||
883 | if (filename[0] == '\0' || (fd = rb->open(filename, O_RDONLY)) < 0) { | 907 | if (filename[0] == '\0' || (fd = rb->open(filename, O_RDONLY)) < 0) { |
884 | if (!silent) | 908 | if (!silent) |
@@ -934,11 +958,12 @@ static bool load(char *filename, bool silent) | |||
934 | n = n*10 + buf[i] - '0'; | 958 | n = n*10 + buf[i] - '0'; |
935 | current_info.level.index = n - 1; | 959 | current_info.level.index = n - 1; |
936 | 960 | ||
937 | /* Get current undo index */ | 961 | /* Get undo index */ |
938 | for (n = 0, i++; buf[i] >= '0' && buf[i] <= '9' && i < 21; i++) | 962 | for (n = 0, i++; buf[i] >= '0' && buf[i] <= '9' && i < 21; i++) |
939 | n = n*10 + buf[i] - '0'; | 963 | n = n*10 + buf[i] - '0'; |
940 | if (n > len) | 964 | if (n > len) |
941 | n = len; | 965 | n = len; |
966 | undo_info.max = len; | ||
942 | 967 | ||
943 | if (current_info.level.index < 0) { | 968 | if (current_info.level.index < 0) { |
944 | if (!silent) | 969 | if (!silent) |
@@ -958,40 +983,78 @@ static bool load(char *filename, bool silent) | |||
958 | if (play_solution) { | 983 | if (play_solution) { |
959 | rb->lcd_clear_display(); | 984 | rb->lcd_clear_display(); |
960 | update_screen(); | 985 | update_screen(); |
961 | rb->sleep(2*step_delay); | 986 | rb->sleep(2*delay[speed]); |
962 | 987 | ||
963 | /* Replay solution until the end or quit button is pressed */ | 988 | /* Replay solution until menu button is pressed */ |
964 | for (i = 0; i < len; i++) { | 989 | i = 0; |
965 | if (!move(undo_info.history[i], true)) { | 990 | while (true) { |
966 | n = i; | 991 | if (i < len) { |
967 | break; | 992 | if (!move(undo_info.history[i], true)) { |
968 | } | 993 | n = i; |
994 | break; | ||
995 | } | ||
996 | rb->lcd_clear_display(); | ||
997 | update_screen(); | ||
998 | i++; | ||
999 | } else | ||
1000 | paused = true; | ||
969 | 1001 | ||
970 | rb->lcd_clear_display(); | 1002 | rb->sleep(delay[speed]); |
971 | update_screen(); | ||
972 | rb->sleep(step_delay); | ||
973 | 1003 | ||
974 | /* Ignore keypresses except for quit & changing speed */ | 1004 | while ((button = rb->button_get(false)) || paused) { |
975 | while ((button = rb->button_get(false)) != BUTTON_NONE) { | ||
976 | switch (button) { | 1005 | switch (button) { |
977 | case SOKOBAN_MENU: | 1006 | case SOKOBAN_MENU: |
978 | /* Pretend the level is complete so we'll quit */ | 1007 | /* Pretend the level is complete so we'll quit */ |
979 | current_info.level.boxes_to_go = 0; | 1008 | current_info.level.boxes_to_go = 0; |
980 | return true; | 1009 | return true; |
981 | 1010 | ||
1011 | case SOKOBAN_PAUSE: | ||
1012 | /* Toggle pause state */ | ||
1013 | paused = !paused; | ||
1014 | break; | ||
1015 | |||
1016 | case BUTTON_LEFT: | ||
1017 | case BUTTON_LEFT | BUTTON_REPEAT: | ||
1018 | /* Go back one move */ | ||
1019 | if (paused) { | ||
1020 | if (undo()) | ||
1021 | i--; | ||
1022 | rb->lcd_clear_display(); | ||
1023 | update_screen(); | ||
1024 | } | ||
1025 | break; | ||
1026 | |||
1027 | case BUTTON_RIGHT: | ||
1028 | case BUTTON_RIGHT | BUTTON_REPEAT: | ||
1029 | /* Go forward one move */ | ||
1030 | if (paused) { | ||
1031 | if (redo()) | ||
1032 | i++; | ||
1033 | rb->lcd_clear_display(); | ||
1034 | update_screen(); | ||
1035 | } | ||
1036 | break; | ||
1037 | |||
982 | case SOKOBAN_UP: | 1038 | case SOKOBAN_UP: |
983 | if (step_delay > HZ/12) | 1039 | case SOKOBAN_UP | BUTTON_REPEAT: |
984 | step_delay = 5*step_delay/6; | 1040 | /* Speed up */ |
1041 | if (speed < sizeof(delay)/sizeof(int) - 1) | ||
1042 | speed++; | ||
985 | break; | 1043 | break; |
986 | 1044 | ||
987 | case SOKOBAN_DOWN: | 1045 | case SOKOBAN_DOWN: |
988 | if (step_delay < 3*HZ/4) | 1046 | case SOKOBAN_DOWN | BUTTON_REPEAT: |
989 | step_delay = 6*step_delay/5; | 1047 | /* Slow down */ |
1048 | if (speed > 0) | ||
1049 | speed--; | ||
990 | } | 1050 | } |
1051 | |||
1052 | if (paused) | ||
1053 | rb->sleep(HZ/33); | ||
991 | } | 1054 | } |
992 | } | 1055 | } |
993 | 1056 | ||
994 | /* If level complete, wait for keypress before quitting */ | 1057 | /* If level is complete, wait for keypress before quitting */ |
995 | if (current_info.level.boxes_to_go == 0) | 1058 | if (current_info.level.boxes_to_go == 0) |
996 | rb->button_get(true); | 1059 | rb->button_get(true); |
997 | 1060 | ||
@@ -1008,7 +1071,6 @@ static bool load(char *filename, bool silent) | |||
1008 | rb->lcd_clear_display(); | 1071 | rb->lcd_clear_display(); |
1009 | } | 1072 | } |
1010 | 1073 | ||
1011 | undo_info.max = len; | ||
1012 | undo_info.current = n; | 1074 | undo_info.current = n; |
1013 | } | 1075 | } |
1014 | 1076 | ||
@@ -1022,9 +1084,10 @@ static int sokoban_menu(void) | |||
1022 | int i; | 1084 | int i; |
1023 | bool menu_quit; | 1085 | bool menu_quit; |
1024 | int start_selected = 0; | 1086 | int start_selected = 0; |
1087 | int prev_level = current_info.level.index; | ||
1025 | 1088 | ||
1026 | MENUITEM_STRINGLIST(menu, "Sokoban Menu", NULL, | 1089 | MENUITEM_STRINGLIST(menu, "Sokoban Menu", NULL, |
1027 | "Resume", "Audio Playback", "Keys", | 1090 | "Resume", "Select Level", "Audio Playback", "Keys", |
1028 | "Load Default Level Set", "Quit Without Saving", | 1091 | "Load Default Level Set", "Quit Without Saving", |
1029 | "Save Progress & Quit"); | 1092 | "Save Progress & Quit"); |
1030 | 1093 | ||
@@ -1036,12 +1099,25 @@ static int sokoban_menu(void) | |||
1036 | case 0: /* Resume */ | 1099 | case 0: /* Resume */ |
1037 | break; | 1100 | break; |
1038 | 1101 | ||
1039 | case 1: /* Audio playback control */ | 1102 | case 1: /* Select level */ |
1103 | current_info.level.index++; | ||
1104 | rb->set_int("Select Level", "", UNIT_INT, | ||
1105 | ¤t_info.level.index, NULL, 1, 1, | ||
1106 | current_info.max_level, NULL); | ||
1107 | current_info.level.index--; | ||
1108 | if (prev_level != current_info.level.index) { | ||
1109 | init_undo(); | ||
1110 | draw_level(); | ||
1111 | } else | ||
1112 | menu_quit = false; | ||
1113 | break; | ||
1114 | |||
1115 | case 2: /* Audio playback control */ | ||
1040 | playback_control(rb); | 1116 | playback_control(rb); |
1041 | menu_quit = false; | 1117 | menu_quit = false; |
1042 | break; | 1118 | break; |
1043 | 1119 | ||
1044 | case 2: /* Keys */ | 1120 | case 3: /* Keys */ |
1045 | FOR_NB_SCREENS(i) | 1121 | FOR_NB_SCREENS(i) |
1046 | rb->screens[i]->clear_display(); | 1122 | rb->screens[i]->clear_display(); |
1047 | rb->lcd_setfont(SOKOBAN_FONT); | 1123 | rb->lcd_setfont(SOKOBAN_FONT); |
@@ -1079,8 +1155,8 @@ static int sokoban_menu(void) | |||
1079 | #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD | 1155 | #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD |
1080 | rb->lcd_putsxy(3, 6, "[POWER] Menu"); | 1156 | rb->lcd_putsxy(3, 6, "[POWER] Menu"); |
1081 | rb->lcd_putsxy(3, 16, "[SELECT] Undo"); | 1157 | rb->lcd_putsxy(3, 16, "[SELECT] Undo"); |
1082 | rb->lcd_putsxy(3, 26, "[REC] Previous Level"); | 1158 | rb->lcd_putsxy(3, 26, "[PLAY] Redo"); |
1083 | rb->lcd_putsxy(3, 36, "[PLAY] Next Level"); | 1159 | rb->lcd_putsxy(3, 36, "[REC] Restart Level"); |
1084 | #elif CONFIG_KEYPAD == IRIVER_H10_PAD | 1160 | #elif CONFIG_KEYPAD == IRIVER_H10_PAD |
1085 | rb->lcd_putsxy(3, 6, "[POWER] Menu"); | 1161 | rb->lcd_putsxy(3, 6, "[POWER] Menu"); |
1086 | rb->lcd_putsxy(3, 16, "[REW] Undo"); | 1162 | rb->lcd_putsxy(3, 16, "[REW] Undo"); |
@@ -1117,17 +1193,17 @@ static int sokoban_menu(void) | |||
1117 | menu_quit = false; | 1193 | menu_quit = false; |
1118 | break; | 1194 | break; |
1119 | 1195 | ||
1120 | case 3: /* Load default levelset */ | 1196 | case 4: /* Load default levelset */ |
1121 | init_boards(); | 1197 | init_boards(); |
1122 | if (!read_levels(true)) | 1198 | if (!read_levels(true)) |
1123 | return 4; | 1199 | return 5; /* Quit */ |
1124 | load_level(); | 1200 | load_level(); |
1125 | break; | 1201 | break; |
1126 | 1202 | ||
1127 | case 4: /* Quit */ | 1203 | case 5: /* Quit */ |
1128 | break; | 1204 | break; |
1129 | 1205 | ||
1130 | case 5: /* Save & quit */ | 1206 | case 6: /* Save & quit */ |
1131 | save(SOKOBAN_SAVE_FILE, false); | 1207 | save(SOKOBAN_SAVE_FILE, false); |
1132 | rb->reload_directory(); | 1208 | rb->reload_directory(); |
1133 | } | 1209 | } |
@@ -1163,13 +1239,13 @@ static bool sokoban_loop(void) | |||
1163 | 1239 | ||
1164 | switch(button) | 1240 | switch(button) |
1165 | { | 1241 | { |
1166 | #ifdef SOKOBAN_RC_QUIT | 1242 | #ifdef SOKOBAN_RC_MENU |
1167 | case SOKOBAN_RC_QUIT: | 1243 | case SOKOBAN_RC_MENU: |
1168 | #endif | 1244 | #endif |
1169 | case SOKOBAN_MENU: | 1245 | case SOKOBAN_MENU: |
1170 | switch (sokoban_menu()) { | 1246 | switch (sokoban_menu()) { |
1171 | case 4: /* Quit */ | 1247 | case 5: /* Quit */ |
1172 | case 5: /* Save & quit */ | 1248 | case 6: /* Save & quit */ |
1173 | return PLUGIN_OK; | 1249 | return PLUGIN_OK; |
1174 | } | 1250 | } |
1175 | update_screen(); | 1251 | update_screen(); |
@@ -1292,7 +1368,7 @@ static bool sokoban_loop(void) | |||
1292 | rb->button_clear_queue(); | 1368 | rb->button_clear_queue(); |
1293 | 1369 | ||
1294 | /* Display for 4 seconds or until new keypress */ | 1370 | /* Display for 4 seconds or until new keypress */ |
1295 | for (i = 0; i < 75; i++) { | 1371 | for (i = 0; i < 80; i++) { |
1296 | rb->sleep(HZ/20); | 1372 | rb->sleep(HZ/20); |
1297 | button = rb->button_get(false); | 1373 | button = rb->button_get(false); |
1298 | if (button && !(button & BUTTON_REL) && | 1374 | if (button && !(button & BUTTON_REL) && |
@@ -1302,16 +1378,25 @@ static bool sokoban_loop(void) | |||
1302 | 1378 | ||
1303 | if (button == BUTTON_SAVE) { | 1379 | if (button == BUTTON_SAVE) { |
1304 | if (undo_info.count < MAX_UNDOS) { | 1380 | if (undo_info.count < MAX_UNDOS) { |
1305 | /* Default filename to current levelset plus | 1381 | /* Set filename to current levelset plus level number |
1306 | * level number and .sok extension */ | 1382 | * and .sok extension. Use SAVE_FOLDER if using the |
1307 | loc = rb->strrchr(buffered_boards.filename, '.'); | 1383 | * default levelset, since it's in a hidden folder. */ |
1308 | if (loc != NULL) | 1384 | if (rb->strcmp(buffered_boards.filename, |
1309 | *loc = '\0'; | 1385 | SOKOBAN_LEVELS_FILE) == 0) { |
1310 | rb->snprintf(buf, sizeof(buf), "%s.%d.sok", | 1386 | rb->snprintf(buf, sizeof(buf), |
1311 | buffered_boards.filename, | 1387 | "%s/sokoban.%d.sok", |
1312 | current_info.level.index + 1); | 1388 | SOKOBAN_SAVE_FOLDER, |
1313 | if (loc != NULL) | 1389 | current_info.level.index + 1); |
1314 | *loc = '.'; | 1390 | } else { |
1391 | if ((loc = rb->strrchr(buffered_boards.filename, | ||
1392 | '.')) != NULL) | ||
1393 | *loc = '\0'; | ||
1394 | rb->snprintf(buf, sizeof(buf), "%s.%d.sok", | ||
1395 | buffered_boards.filename, | ||
1396 | current_info.level.index + 1); | ||
1397 | if (loc != NULL) | ||
1398 | *loc = '.'; | ||
1399 | } | ||
1315 | 1400 | ||
1316 | if (!rb->kbd_input(buf, MAX_PATH)) | 1401 | if (!rb->kbd_input(buf, MAX_PATH)) |
1317 | save(buf, true); | 1402 | save(buf, true); |
@@ -1355,8 +1440,8 @@ static bool sokoban_loop(void) | |||
1355 | current_info.level.index = 0; | 1440 | current_info.level.index = 0; |
1356 | 1441 | ||
1357 | switch (sokoban_menu()) { | 1442 | switch (sokoban_menu()) { |
1358 | case 4: /* Quit */ | 1443 | case 5: /* Quit */ |
1359 | case 5: /* Save & quit */ | 1444 | case 6: /* Save & quit */ |
1360 | return PLUGIN_OK; | 1445 | return PLUGIN_OK; |
1361 | } | 1446 | } |
1362 | } | 1447 | } |