summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/recorder/sokoban.c119
1 files changed, 40 insertions, 79 deletions
diff --git a/apps/recorder/sokoban.c b/apps/recorder/sokoban.c
index 5e4148c2e1..d28e32f430 100644
--- a/apps/recorder/sokoban.c
+++ b/apps/recorder/sokoban.c
@@ -34,6 +34,8 @@
34#include "screens.h" 34#include "screens.h"
35#include "font.h" 35#include "font.h"
36#include "file.h" 36#include "file.h"
37#include "misc.h"
38#include "debug.h"
37 39
38#ifdef SIMULATOR 40#ifdef SIMULATOR
39#include <stdio.h> 41#include <stdio.h>
@@ -255,40 +257,29 @@ static void init_boards(void)
255 257
256static int get_level_count(void) 258static int get_level_count(void)
257{ 259{
258 int i = 0;
259 int fd = 0; 260 int fd = 0;
260 int nread = 0; 261 int len, lastlen = 0;
261 char buffer[ROWS * COLS * 2]; 262 char buffer[COLS + 3]; /* COLS plus CR/LF and \0 */
262 263
263 if ((fd = open(LEVELS_FILE, O_RDONLY)) < 0) { 264 if ((fd = open(LEVELS_FILE, O_RDONLY)) < 0) {
264 splash(0, 0, true, "Unable to open %s", LEVELS_FILE); 265 splash(0, 0, true, "Unable to open %s", LEVELS_FILE);
265 return -1; 266 return -1;
266 } 267 }
267 268
268 do { 269 while(1) {
269 if ((nread = read(fd, buffer, sizeof(buffer))) < 0) { 270 len = read_line(fd, buffer, sizeof(buffer));
270 splash(0, 0, true, "Reading %s failed.", LEVELS_FILE); 271 if(len <= 0)
271 close(fd); 272 break;
272 return -1;
273 }
274
275 for (i = 0; i < (nread - 1); i++) {
276 if (buffer[i] == '\n' && buffer[i+1] == '\n') {
277 273
278 while (isspace(buffer[i])) 274 /* Two short lines in a row means new level */
279 i++; 275 if(len < 3 && lastlen < 3)
276 current_info.max_level++;
280 277
281 current_info.max_level++; 278 lastlen = len;
282 } 279 }
283 }
284 280
285 if (buffer[i] == '\n' && buffer[i-1] != '\n') 281 DEBUGF("%d levels loaded\n", current_info.max_level);
286 lseek(fd, -1, SEEK_CUR);
287
288 } while (nread == sizeof(buffer));
289
290 close(fd); 282 close(fd);
291
292 return 0; 283 return 0;
293} 284}
294 285
@@ -297,73 +288,42 @@ static int get_level(char *level, int level_size)
297 int fd = 0, i = 0; 288 int fd = 0, i = 0;
298 int nread = 0; 289 int nread = 0;
299 int count = 0; 290 int count = 0;
300 int offset = 0; 291 int len, lastlen = 0;
301 int level_ct = 0; 292 int level_ct = 1;
302 unsigned char buffer[SOKOBAN_LEVEL_SIZE * 2]; 293 unsigned char buffer[SOKOBAN_LEVEL_SIZE * 2];
303 bool level_found = false; 294 bool level_found = false;
304 int prevnewl=2; /* previous newlines in a row */
305
306 /* Lets not reparse the full file if we can avoid it */
307 if (current_info.loaded_level > current_info.level.level)
308 offset = 0;
309 295
310 /* open file */ 296 /* open file */
311 if ((fd = open(LEVELS_FILE, O_RDONLY)) < 0) 297 if ((fd = open(LEVELS_FILE, O_RDONLY)) < 0)
312 return -1; 298 return -1;
313 299
314 /* go where we left off */ 300 /* Lets not reparse the full file if we can avoid it */
315 offset = current_info.level_offset; 301 if (current_info.loaded_level < current_info.level.level) {
316 if(offset) 302 lseek(fd, current_info.level_offset, SEEK_SET);
317 if (lseek(fd, offset, SEEK_SET) < 0) { 303 level_ct = current_info.loaded_level;
318 close(fd); 304 }
319 return -1;
320 }
321
322 while (!level_found) {
323 nread = read(fd, buffer, sizeof(buffer));
324 if (nread < SOKOBAN_LEVEL_SIZE) {
325 close(fd);
326 return -1;
327 }
328 305
329 /* we search for the first character that isn't a newline */ 306 if(current_info.level.level > 1) {
330 for (i = 0; i < nread; i++) { 307 while(!level_found) {
331 /* skip and count all newlines */ 308 len = read_line(fd, buffer, SOKOBAN_LEVEL_SIZE);
332 while((buffer[i] == '\n' || buffer[i] == '\r') && (i < nread)) { 309 if(len <= 0) {
333 prevnewl++; 310 close(fd);
334 i++; 311 return -1;
335 } 312 }
336 313
337 /* end of buffer? */ 314 /* Two short lines in a row means new level */
338 if(i == nread) 315 if(len < 3 && lastlen < 3) {
339 break;
340
341 /* start of new level? */
342 if((prevnewl>1) && (buffer[i] != '\n' && buffer[i] != '\r')) {
343 prevnewl=0; /* none now */
344 level_ct++; 316 level_ct++;
345 317 if(level_ct == current_info.level.level)
346 if (level_ct == current_info.level.level) { 318 level_found = true;
347 level_found = true;
348 offset += i;
349 break;
350 }
351 } 319 }
352 320 lastlen = len;
353 /* skip all non-newlines */
354 while((buffer[i] != '\n' && buffer[i] != '\r') && (i < nread))
355 i++;
356 } 321 }
357 if(!level_found) 322 }
358 offset += nread;
359 }
360
361 if (!level_found)
362 return -1;
363
364 /* now seek back to the exact start position */
365 lseek(fd, offset, SEEK_SET);
366 323
324 /* Remember the current offset */
325 current_info.level_offset = lseek(fd, 0, SEEK_CUR);
326
367 /* read a full buffer chunk from here */ 327 /* read a full buffer chunk from here */
368 nread = read(fd, buffer, sizeof(buffer)-1); 328 nread = read(fd, buffer, sizeof(buffer)-1);
369 if (nread < 0) 329 if (nread < 0)
@@ -851,14 +811,15 @@ static bool sokoban_loop(void)
851 811
852 lcd_clear_display(); 812 lcd_clear_display();
853 813
854 if (current_info.level.level == current_info.max_level) { 814 if (current_info.level.level > current_info.max_level) {
855 lcd_putsxy(10, 20, str(LANG_SOKOBAN_WIN)); 815 lcd_putsxy(10, 20, str(LANG_SOKOBAN_WIN));
856 816
857 for (i = 0; i < 30000 ; i++) { 817 for (i = 0; i < 30000 ; i++) {
858 lcd_invertrect(0, 0, 111, 63); 818 lcd_invertrect(0, 0, 111, 63);
859 lcd_update(); 819 lcd_update();
860 820
861 if (button_get(false)) 821 button = button_get(false);
822 if (button && ((button & BUTTON_REL) != BUTTON_REL))
862 break; 823 break;
863 } 824 }
864 825