diff options
Diffstat (limited to 'apps/plugins')
-rw-r--r-- | apps/plugins/xobox.c | 136 |
1 files changed, 65 insertions, 71 deletions
diff --git a/apps/plugins/xobox.c b/apps/plugins/xobox.c index a13844570b..08665abbf2 100644 --- a/apps/plugins/xobox.c +++ b/apps/plugins/xobox.c | |||
@@ -163,6 +163,7 @@ PLUGIN_HEADER | |||
163 | #define QIX LCD_WHITE | 163 | #define QIX LCD_WHITE |
164 | #define UNCHECKED 0 | 164 | #define UNCHECKED 0 |
165 | #define CHECKED 1 | 165 | #define CHECKED 1 |
166 | #define PAINTED -1 | ||
166 | #define PIC_QIX 0 | 167 | #define PIC_QIX 0 |
167 | #define PIC_PLAYER 1 | 168 | #define PIC_PLAYER 1 |
168 | 169 | ||
@@ -180,8 +181,8 @@ static int difficulty = 75; /* Percentage of screen that needs to be filled | |||
180 | static struct plugin_api *rb; | 181 | static struct plugin_api *rb; |
181 | static bool quit = false; | 182 | static bool quit = false; |
182 | 183 | ||
183 | static unsigned int board[BOARD_H][BOARD_W], | 184 | static unsigned int board[BOARD_H][BOARD_W]; |
184 | testboard[BOARD_H][BOARD_W], boardcopy[BOARD_H][BOARD_W]; | 185 | static int testboard[BOARD_H][BOARD_W]; |
185 | 186 | ||
186 | /* | 187 | /* |
187 | 00011000 0x18 - 11100111 0xe7 | 188 | 00011000 0x18 - 11100111 0xe7 |
@@ -333,25 +334,10 @@ static void init_board (void) | |||
333 | BOARD_Y + t_rand (((BOARD_H - 6) * CUBE_SIZE) - 2 * CUBE_SIZE) + | 334 | BOARD_Y + t_rand (((BOARD_H - 6) * CUBE_SIZE) - 2 * CUBE_SIZE) + |
334 | 3 * CUBE_SIZE; | 335 | 3 * CUBE_SIZE; |
335 | 336 | ||
336 | switch( t_rand (12) ) { | 337 | const int angle_table[] = { |
337 | #define ANGLE_CASE(a,b) \ | 338 | MOVE_UUR, MOVE_UR, MOVE_URR, MOVE_DRR, MOVE_DR, MOVE_DDR, |
338 | case a: \ | 339 | MOVE_UUL, MOVE_UL, MOVE_ULL, MOVE_DLL, MOVE_DL, MOVE_DDL }; |
339 | qixes[j].angle = MOVE_ ## b; \ | 340 | qixes[j].angle = angle_table[t_rand (12)]; |
340 | break; | ||
341 | ANGLE_CASE(0,UR); | ||
342 | ANGLE_CASE(1,URR); | ||
343 | ANGLE_CASE(2,DRR); | ||
344 | ANGLE_CASE(3,DR); | ||
345 | ANGLE_CASE(4,DDR); | ||
346 | ANGLE_CASE(5,DDL); | ||
347 | ANGLE_CASE(6,DL); | ||
348 | ANGLE_CASE(7,DLL); | ||
349 | ANGLE_CASE(8,ULL); | ||
350 | ANGLE_CASE(9,UL); | ||
351 | ANGLE_CASE(10,UUL); | ||
352 | ANGLE_CASE(11,UUR); | ||
353 | #undef ANGLE_CASE | ||
354 | } | ||
355 | } | 341 | } |
356 | /*black_qix.velocity=1; | 342 | /*black_qix.velocity=1; |
357 | black_qix.x=BOARD_X+(BOARD_W*CUBE_SIZE)/2-CUBE_SIZE/2; | 343 | black_qix.x=BOARD_X+(BOARD_W*CUBE_SIZE)/2-CUBE_SIZE/2; |
@@ -433,46 +419,48 @@ static void refresh_board (void) | |||
433 | rb->lcd_update (); | 419 | rb->lcd_update (); |
434 | } | 420 | } |
435 | 421 | ||
436 | static inline int infested_area (int i, int j) | 422 | static inline int infested_area (int i, int j, int v) |
437 | { | 423 | { |
438 | struct pos p; | 424 | struct pos p; |
439 | p.x = i; | 425 | p.x = i; |
440 | p.y = j; | 426 | p.y = j; |
441 | emptyStack (); | 427 | emptyStack (); |
442 | init_testboard (); | ||
443 | if (!push (&p)) | 428 | if (!push (&p)) |
444 | return -1; | 429 | return -1; |
445 | while (pop (&p)) { | 430 | while (pop (&p)) { |
446 | testboard[p.y][p.x] = CHECKED; | 431 | if (testboard[p.y][p.x] == v) continue; |
447 | if ((boardcopy[p.y][p.x] == QIX)) | 432 | if (testboard[p.y][p.x] > UNCHECKED) |
448 | return 1; | 433 | return 1; /* This area was previously flagged as infested */ |
434 | testboard[p.y][p.x] = v; | ||
435 | if (board[p.y][p.x] == QIX) | ||
436 | return 1; /* Infested area */ | ||
449 | { | 437 | { |
450 | struct pos p1 = { p.x+1, p.y }; | 438 | struct pos p1 = { p.x+1, p.y }; |
451 | if ((p1.x < BOARD_W) && (testboard[p1.y][p1.x] == UNCHECKED)) | 439 | if ((p1.x < BOARD_W) |
452 | if (board[p1.y][p1.x] != FILLED) | 440 | && (board[p1.y][p1.x] != FILLED) |
453 | if (!push (&p1)) | 441 | && (!push (&p1))) |
454 | return -1; | 442 | return -1; |
455 | } | 443 | } |
456 | { | 444 | { |
457 | struct pos p1 = { p.x-1, p.y }; | 445 | struct pos p1 = { p.x-1, p.y }; |
458 | if ((p1.x >= 0) && (testboard[p1.y][p1.x] == UNCHECKED)) | 446 | if ((p1.x >= 0) |
459 | if (board[p1.y][p1.x] != FILLED) | 447 | && (board[p1.y][p1.x] != FILLED) |
460 | if (!push (&p1)) | 448 | && (!push (&p1))) |
461 | return -1; | 449 | return -1; |
462 | } | 450 | } |
463 | { | 451 | { |
464 | struct pos p1 = { p.x, p.y+1 }; | 452 | struct pos p1 = { p.x, p.y+1 }; |
465 | if ((p1.y < BOARD_H) && (testboard[p1.y][p1.x] == UNCHECKED)) | 453 | if ((p1.y < BOARD_H) |
466 | if (board[p1.y][p1.x] != FILLED) | 454 | && (board[p1.y][p1.x] != FILLED) |
467 | if (!push (&p1)) | 455 | && (!push (&p1))) |
468 | return -1; | 456 | return -1; |
469 | } | 457 | } |
470 | { | 458 | { |
471 | struct pos p1 = { p.x, p.y-1 }; | 459 | struct pos p1 = { p.x, p.y-1 }; |
472 | if ((p1.y >= 0) && (testboard[p1.y][p1.x] == UNCHECKED)) | 460 | if ((p1.y >= 0) |
473 | if (board[p1.y][p1.x] != FILLED) | 461 | && (board[p1.y][p1.x] != FILLED) |
474 | if (!push (&p1)) | 462 | && (!push (&p1))) |
475 | return -1; | 463 | return -1; |
476 | } | 464 | } |
477 | } | 465 | } |
478 | return 0; | 466 | return 0; |
@@ -483,43 +471,43 @@ static inline int fill_area (int i, int j) | |||
483 | struct pos p; | 471 | struct pos p; |
484 | p.x = i; | 472 | p.x = i; |
485 | p.y = j; | 473 | p.y = j; |
474 | int v = testboard[p.y][p.x]; | ||
486 | emptyStack (); | 475 | emptyStack (); |
487 | init_testboard (); | ||
488 | if (!push (&p)) | 476 | if (!push (&p)) |
489 | return -1; | 477 | return -1; |
490 | while (pop (&p)) { | 478 | while (pop (&p)) { |
491 | board[p.y][p.x] = FILLED; | 479 | board[p.y][p.x] = FILLED; |
492 | testboard[p.y][p.x] = CHECKED; | 480 | testboard[p.y][p.x] = PAINTED; |
493 | { | 481 | { |
494 | struct pos p1 = { p.x+1, p.y }; | 482 | struct pos p1 = { p.x+1, p.y }; |
495 | if ((p1.x < BOARD_W) && (testboard[p1.y][p1.x] == UNCHECKED)) | 483 | if ((p1.x < BOARD_W) |
496 | if (board[p1.y][p1.x] == EMPTIED) | 484 | && (testboard[p1.y][p1.x] == v) |
497 | if (!push (&p1)) | 485 | && (!push (&p1))) |
498 | return -1; | 486 | return -1; |
499 | } | 487 | } |
500 | { | 488 | { |
501 | struct pos p1 = { p.x-1, p.y }; | 489 | struct pos p1 = { p.x-1, p.y }; |
502 | if ((p1.x >= 0) && (testboard[p1.y][p1.x] == UNCHECKED)) | 490 | if ((p1.x >= 0) |
503 | if (board[p1.y][p1.x] == EMPTIED) | 491 | && (testboard[p1.y][p1.x] == v) |
504 | if (!push (&p1)) | 492 | && (!push (&p1))) |
505 | return -1; | 493 | return -1; |
506 | } | 494 | } |
507 | { | 495 | { |
508 | struct pos p1 = { p.x, p.y+1 }; | 496 | struct pos p1 = { p.x, p.y+1 }; |
509 | if ((p1.y < BOARD_H) && (testboard[p1.y][p1.x] == UNCHECKED)) | 497 | if ((p1.y < BOARD_H) |
510 | if (board[p1.y][p1.x] == EMPTIED) | 498 | && (testboard[p1.y][p1.x] == v) |
511 | if (!push (&p1)) | 499 | && (!push (&p1))) |
512 | return -1; | 500 | return -1; |
513 | } | 501 | } |
514 | { | 502 | { |
515 | struct pos p1 = { p.x, p.y-1 }; | 503 | struct pos p1 = { p.x, p.y-1 }; |
516 | if ((p1.y >= 0) && (testboard[p1.y][p1.x] == UNCHECKED)) | 504 | if ((p1.y >= 0) |
517 | if (board[p1.y][p1.x] == EMPTIED) | 505 | && (testboard[p1.y][p1.x] == v) |
518 | if (!push (&p1)) | 506 | && (!push (&p1))) |
519 | return -1; | 507 | return -1; |
520 | } | 508 | } |
521 | } | 509 | } |
522 | return 1; | 510 | return 0; |
523 | } | 511 | } |
524 | 512 | ||
525 | 513 | ||
@@ -535,24 +523,30 @@ static void complete_trail (int fill) | |||
535 | else | 523 | else |
536 | board[j][i] = EMPTIED; | 524 | board[j][i] = EMPTIED; |
537 | } | 525 | } |
538 | /*boardcopy[j][i] = board[j][i];*/ | ||
539 | } | 526 | } |
540 | rb->memcpy( boardcopy[j], board[j], BOARD_W * sizeof( int ) ); | ||
541 | } | 527 | } |
542 | 528 | ||
543 | if (fill) { | 529 | if (fill) { |
530 | int v = CHECKED; | ||
544 | for (i = 0; i < player.level + STARTING_QIXES; i++) /* add qixes to board */ | 531 | for (i = 0; i < player.level + STARTING_QIXES; i++) /* add qixes to board */ |
545 | boardcopy[pos(qixes[i].y - BOARD_Y)] | 532 | board[pos(qixes[i].y - BOARD_Y)] |
546 | [pos(qixes[i].x - BOARD_X)] = QIX; | 533 | [pos(qixes[i].x - BOARD_X)] = QIX; |
547 | 534 | ||
548 | init_testboard(); | 535 | init_testboard(); |
549 | for (j = 1; j < BOARD_H - 1; j++) | 536 | for (j = 1; j < BOARD_H - 1; j++) { |
550 | for (i = 0; i < BOARD_W - 0; i++) | 537 | for (i = 0; i < BOARD_W - 0; i++) { |
551 | if (board[j][i] != FILLED && testboard[j][i] != CHECKED /* testboard[i][j] == CHECKED means that this is part of an infested area tested on the previous run */ ) { | 538 | if (board[j][i] != FILLED) { |
552 | ret = infested_area (i, j); | 539 | ret = infested_area (i, j, v); |
553 | if (ret < 0 || ( ret == 0 && fill_area (i, j) < 0 ) ) | 540 | if (ret < 0 || ( ret == 0 && fill_area (i, j) ) ) |
554 | quit = true; | 541 | quit = true; |
542 | v++; | ||
555 | } | 543 | } |
544 | } | ||
545 | } | ||
546 | |||
547 | for (i = 0; i < player.level + STARTING_QIXES; i++) /* add qixes to board */ | ||
548 | board[pos(qixes[i].y - BOARD_Y)] | ||
549 | [pos(qixes[i].x - BOARD_X)] = EMPTIED; | ||
556 | percentage_cache = percentage(); | 550 | percentage_cache = percentage(); |
557 | } | 551 | } |
558 | 552 | ||
@@ -609,7 +603,7 @@ static void die (void) | |||
609 | 603 | ||
610 | /* returns true if the (side) of the block -***- | 604 | /* returns true if the (side) of the block -***- |
611 | starting from (newx,newy) has any filled pixels * * | 605 | starting from (newx,newy) has any filled pixels * * |
612 | -***- | 606 | -***- |
613 | */ | 607 | */ |
614 | static inline bool line_check_lt (int newx, int newy) | 608 | static inline bool line_check_lt (int newx, int newy) |
615 | { | 609 | { |