summaryrefslogtreecommitdiff
path: root/apps/plugins/jewels.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/jewels.c')
-rw-r--r--apps/plugins/jewels.c433
1 files changed, 127 insertions, 306 deletions
diff --git a/apps/plugins/jewels.c b/apps/plugins/jewels.c
index 6bf5fcf8ac..ae69e0ade5 100644
--- a/apps/plugins/jewels.c
+++ b/apps/plugins/jewels.c
@@ -330,59 +330,6 @@ enum game_type {
330 GAME_TYPE_PUZZLE 330 GAME_TYPE_PUZZLE
331}; 331};
332 332
333/* menu values */
334#define FONT_HEIGHT 8
335#define MAX_MITEMS 6
336#define MENU_WIDTH 100
337
338/* menu results */
339enum menu_result {
340 MRES_NONE,
341 MRES_NEW,
342 MRES_PUZZLE,
343 MRES_SAVE,
344 MRES_RESUME,
345 MRES_SCORES,
346 MRES_HELP,
347 MRES_QUIT,
348 MRES_PLAYBACK,
349 MRES_EXIT
350};
351
352/* menu commands */
353enum menu_cmd {
354 MCMD_NONE,
355 MCMD_NEXT,
356 MCMD_PREV,
357 MCMD_SELECT
358};
359
360/* menus */
361struct jewels_menu {
362 char *title;
363 bool hasframe;
364 int selected;
365 int itemcnt;
366 struct jewels_menuitem {
367 char *text;
368 enum menu_result res;
369 } items[MAX_MITEMS];
370} bjmenu[] = {
371 {"Jewels", false, 0, 6,
372 {{"New Game", MRES_NEW},
373 {"Puzzle", MRES_PUZZLE},
374 {"Resume Saved Game", MRES_RESUME},
375 {"High Scores", MRES_SCORES},
376 {"Help", MRES_HELP},
377 {"Quit", MRES_QUIT}}},
378 {"Menu", true, 0, 5,
379 {{"Audio Playback", MRES_PLAYBACK },
380 {"Resume Game", MRES_RESUME},
381 {"Save Game", MRES_SAVE},
382 {"End Game", MRES_QUIT},
383 {"Exit Jewels", MRES_EXIT}}}
384};
385
386/* external bitmaps */ 333/* external bitmaps */
387extern const fb_data jewels[]; 334extern const fb_data jewels[];
388 335
@@ -677,73 +624,6 @@ static void jewels_drawboard(struct game_context* bj) {
677} 624}
678 625
679/***************************************************************************** 626/*****************************************************************************
680* jewels_showmenu() displays the chosen menu after performing the chosen
681* menu command.
682******************************************************************************/
683static enum menu_result jewels_showmenu(struct jewels_menu* menu,
684 enum menu_cmd cmd) {
685 int i;
686 int w, h;
687 int firstline;
688 int adj;
689 int extraline = LCD_HEIGHT <= ((menu->itemcnt+2)*FONT_HEIGHT) ? 0 : 1;
690
691 /* handle menu command */
692 switch(cmd) {
693 case MCMD_NEXT:
694 menu->selected = (menu->selected+1)%menu->itemcnt;
695 break;
696
697 case MCMD_PREV:
698 menu->selected = (menu->selected-1+menu->itemcnt)%menu->itemcnt;
699 break;
700
701 case MCMD_SELECT:
702 return menu->items[menu->selected].res;
703
704 default:
705 break;
706 }
707
708 /* clear menu area */
709 firstline = (LCD_HEIGHT/FONT_HEIGHT-(menu->itemcnt+3))/2;
710
711 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
712 rb->lcd_fillrect((LCD_WIDTH-MENU_WIDTH)/2, firstline*FONT_HEIGHT,
713 MENU_WIDTH, (menu->itemcnt+3)*FONT_HEIGHT);
714 rb->lcd_set_drawmode(DRMODE_SOLID);
715
716 if(menu->hasframe) {
717 rb->lcd_drawrect((LCD_WIDTH-MENU_WIDTH)/2-1, firstline*FONT_HEIGHT-1,
718 MENU_WIDTH+2, (menu->itemcnt+3)*FONT_HEIGHT+2);
719 rb->lcd_hline((LCD_WIDTH-MENU_WIDTH)/2-1,
720 (LCD_WIDTH-MENU_WIDTH)/2-1+MENU_WIDTH+2,
721 (firstline+1)*FONT_HEIGHT);
722 }
723
724 /* draw menu items */
725 rb->lcd_getstringsize(menu->title, &w, &h);
726 rb->lcd_putsxy((LCD_WIDTH-w)/2, firstline*FONT_HEIGHT, menu->title);
727
728 for(i=0; i<menu->itemcnt; i++) {
729 if(i == menu->selected) {
730 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
731 }
732 rb->lcd_putsxy((LCD_WIDTH-MENU_WIDTH)/2,
733 (firstline+i+1+extraline)*FONT_HEIGHT,
734 menu->items[i].text);
735 if(i == menu->selected) {
736 rb->lcd_set_drawmode(DRMODE_SOLID);
737 }
738 }
739
740 adj = (firstline == 0 ? 0 : 1);
741 rb->lcd_update_rect((LCD_WIDTH-MENU_WIDTH)/2-1, firstline*FONT_HEIGHT-adj,
742 MENU_WIDTH+2, (menu->itemcnt+3)*FONT_HEIGHT+2*adj);
743 return MRES_NONE;
744}
745
746/*****************************************************************************
747* jewels_putjewels() makes the jewels fall to fill empty spots and adds 627* jewels_putjewels() makes the jewels fall to fill empty spots and adds
748* new random jewels at the empty spots at the top of each row. 628* new random jewels at the empty spots at the top of each row.
749******************************************************************************/ 629******************************************************************************/
@@ -1457,18 +1337,36 @@ static void jewels_callback(void* param) {
1457} 1337}
1458 1338
1459/***************************************************************************** 1339/*****************************************************************************
1340* jewels_displayscores() displays the high scores
1341******************************************************************************/
1342static char * scores_get_name(int selected_item, void * data,
1343 char * buffer, size_t buffer_len)
1344{
1345 struct game_context* bj = (struct game_context*)data;
1346 rb->snprintf(buffer, buffer_len, "#%02d: %d",
1347 selected_item+1, bj->highscores[selected_item]);
1348 return buffer;
1349}
1350static void jewels_displayscores(struct game_context* bj)
1351{
1352 struct simplelist_info info;
1353 rb->simplelist_info_init(&info, "High Scores", NUM_SCORES, (void*)bj);
1354 info.hide_selection = true;
1355 info.get_name = scores_get_name;
1356 rb->simplelist_show_list(&info);
1357}
1358
1359
1360/*****************************************************************************
1460* jewels_main() is the main game subroutine, it returns the final game status. 1361* jewels_main() is the main game subroutine, it returns the final game status.
1461******************************************************************************/ 1362******************************************************************************/
1462static int jewels_main(struct game_context* bj) { 1363static int jewels_main(struct game_context* bj) {
1463 int i, j;
1464 int w, h; 1364 int w, h;
1465 int button; 1365 int button;
1366 struct viewport vp[NB_SCREENS];
1466 char str[18]; 1367 char str[18];
1467 bool startgame = false; 1368 bool inmenu = true;
1468 bool inmenu = false;
1469 bool selected = false; 1369 bool selected = false;
1470 enum menu_cmd cmd = MCMD_NONE;
1471 enum menu_result res;
1472 1370
1473 /* the cursor coordinates */ 1371 /* the cursor coordinates */
1474 int x=0, y=0; 1372 int x=0, y=0;
@@ -1479,67 +1377,47 @@ static int jewels_main(struct game_context* bj) {
1479 /******************** 1377 /********************
1480 * menu * 1378 * menu *
1481 ********************/ 1379 ********************/
1482 rb->lcd_clear_display(); 1380 MENUITEM_STRINGLIST(main_menu,"Jewels",NULL,
1483 1381 "New Game", "Puzzle", "Resume Saved Game",
1484 while(!startgame) { 1382 "High Scores", "Help", "Quit");
1485 res = jewels_showmenu(&bjmenu[0], cmd); 1383 FOR_NB_SCREENS(h)
1486 cmd = MCMD_NONE; 1384 {
1487 1385 rb->viewport_set_defaults(&vp[h], h);
1488 rb->snprintf(str, 18, "High Score: %d", bj->highscores[0]); 1386#if (LCD_DEPTH >= 16) || defined(LCD_REMOTE_DEPTH) && (LCD_REMOTE_DEPTH >= 16)
1489 rb->lcd_getstringsize(str, &w, &h); 1387 if (rb->screens[h]->depth >= 16)
1490 rb->lcd_putsxy((LCD_WIDTH-w)/2, LCD_HEIGHT-8, str); 1388 {
1491 rb->lcd_update(); 1389 vp->bg_pattern = LCD_RGBPACK(49, 26, 26);
1390 vp->fg_pattern = LCD_RGBPACK(210, 181, 181);
1391 }
1392#endif
1393 }
1492 1394
1493 rb->yield(); 1395 while(inmenu) {
1494 1396
1495 switch(res) { 1397 switch (rb->do_menu(&main_menu, NULL, vp, true)) {
1496 case MRES_NEW: 1398 case 0:
1497 startgame = true; 1399 inmenu = false;
1498 bj->type = GAME_TYPE_NORMAL; 1400 bj->type = GAME_TYPE_NORMAL;
1499 continue; 1401 break;
1500 1402
1501 case MRES_PUZZLE: 1403 case 1:
1502 startgame = true; 1404 inmenu = false;
1503 bj->type = GAME_TYPE_PUZZLE; 1405 bj->type = GAME_TYPE_PUZZLE;
1504 continue; 1406 break;
1505 1407
1506 case MRES_RESUME: 1408 case 2:
1507 if(!jewels_loadgame(bj)) { 1409 if(!jewels_loadgame(bj)) {
1508 rb->splash(HZ*2, "Nothing to resume"); 1410 rb->splash(HZ*2, "Nothing to resume");
1509 rb->lcd_clear_display();
1510 } else { 1411 } else {
1511 startgame = true; 1412 inmenu = false;
1512 }
1513 continue;
1514
1515 case MRES_SCORES:
1516 rb->lcd_clear_display();
1517
1518 /* room for a title? */
1519 j = 0;
1520 if(LCD_HEIGHT-NUM_SCORES*8 >= 8) {
1521 rb->snprintf(str, 12, "%s", "High Scores");
1522 rb->lcd_getstringsize(str, &w, &h);
1523 rb->lcd_putsxy((LCD_WIDTH-w)/2, 0, str);
1524 j = 2;
1525 }
1526
1527 /* print high scores */
1528 for(i=0; i<NUM_SCORES; i++) {
1529 rb->snprintf(str, 11, "#%02d: %d", i+1, bj->highscores[i]);
1530 rb->lcd_puts(0, i+j, str);
1531 } 1413 }
1414 break;
1532 1415
1533 rb->lcd_update(); 1416 case 3:
1534 while(true) { 1417 jewels_displayscores(bj);
1535 button = rb->button_get(true); 1418 break;
1536 if(button != BUTTON_NONE && !(button&BUTTON_REL)) break;
1537 rb->yield();
1538 }
1539 rb->lcd_clear_display();
1540 continue;
1541 1419
1542 case MRES_HELP: 1420 case 4:
1543 /* welcome screen to display key bindings */ 1421 /* welcome screen to display key bindings */
1544 rb->lcd_clear_display(); 1422 rb->lcd_clear_display();
1545 rb->snprintf(str, 5, "%s", "Help"); 1423 rb->snprintf(str, 5, "%s", "Help");
@@ -1694,54 +1572,17 @@ static int jewels_main(struct game_context* bj) {
1694 if(button != BUTTON_NONE && !(button&BUTTON_REL)) break; 1572 if(button != BUTTON_NONE && !(button&BUTTON_REL)) break;
1695 } 1573 }
1696 rb->lcd_clear_display(); 1574 rb->lcd_clear_display();
1697 continue;
1698
1699 case MRES_QUIT:
1700 return BJ_QUIT;
1701
1702 default:
1703 break; 1575 break;
1704 }
1705 1576
1706 /* handle menu button presses */ 1577 case 5:
1707 button = rb->button_get(true);
1708 switch(button){
1709#ifdef JEWELS_SCROLLWHEEL
1710 case JEWELS_PREV:
1711 case (JEWELS_PREV|BUTTON_REPEAT):
1712#endif
1713 case JEWELS_UP:
1714 case (JEWELS_UP|BUTTON_REPEAT):
1715 cmd = MCMD_PREV;
1716 break;
1717
1718#ifdef JEWELS_SCROLLWHEEL
1719 case JEWELS_NEXT:
1720 case (JEWELS_NEXT|BUTTON_REPEAT):
1721#endif
1722 case JEWELS_DOWN:
1723 case (JEWELS_DOWN|BUTTON_REPEAT):
1724 cmd = MCMD_NEXT;
1725 break;
1726
1727 case JEWELS_SELECT:
1728 case JEWELS_RIGHT:
1729 cmd = MCMD_SELECT;
1730 break;
1731
1732#ifdef JEWELS_CANCEL
1733#ifdef JEWELS_RC_CANCEL
1734 case JEWELS_RC_CANCEL:
1735#endif
1736 case JEWELS_CANCEL:
1737 return BJ_QUIT; 1578 return BJ_QUIT;
1738#endif 1579
1580 case MENU_ATTACHED_USB:
1581 jewels_callback(bj);
1582 return BJ_USB;
1739 1583
1740 default: 1584 default:
1741 if(rb->default_event_handler_ex(button, jewels_callback, 1585 return BJ_QUIT;
1742 (void*) bj) == SYS_USB_CONNECTED)
1743 return BJ_USB;
1744 break;
1745 } 1586 }
1746 } 1587 }
1747 1588
@@ -1771,162 +1612,142 @@ static int jewels_main(struct game_context* bj) {
1771 /********************** 1612 /**********************
1772 * play * 1613 * play *
1773 **********************/ 1614 **********************/
1615 MENUITEM_STRINGLIST(ingame_menu,"Menu",NULL,
1616 "Audio Playback", "Resume Game",
1617 "Save Game", "End Game", "Exit Jewels");
1618
1619 selected = false;
1774 while(true) { 1620 while(true) {
1775 int no_movesavail = false; 1621 bool no_movesavail = false;
1776
1777 if(!inmenu) {
1778 /* refresh the board */
1779 jewels_drawboard(bj);
1780
1781 /* display the cursor */
1782 if(selected) {
1783 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
1784 rb->lcd_fillrect(x*TILE_WIDTH, y*TILE_HEIGHT+YOFS,
1785 TILE_WIDTH, TILE_HEIGHT);
1786 rb->lcd_set_drawmode(DRMODE_SOLID);
1787 } else {
1788 rb->lcd_drawrect(x*TILE_WIDTH, y*TILE_HEIGHT+YOFS,
1789 TILE_WIDTH, TILE_HEIGHT);
1790 }
1791 rb->lcd_update_rect(x*TILE_WIDTH, y*TILE_HEIGHT+YOFS,
1792 TILE_WIDTH, TILE_HEIGHT);
1793 } else {
1794 res = jewels_showmenu(&bjmenu[1], cmd);
1795 cmd = MCMD_NONE;
1796 switch(res) {
1797 case MRES_RESUME:
1798 inmenu = false;
1799 selected = false;
1800 continue;
1801 1622
1802 case MRES_PLAYBACK: 1623 while(inmenu) {
1624 switch (rb->do_menu(&ingame_menu, NULL, vp, true)) {
1625 case 0:
1803 playback_control(NULL); 1626 playback_control(NULL);
1804 rb->lcd_setfont(FONT_SYSFIXED);
1805 inmenu = false; 1627 inmenu = false;
1806 selected = false;
1807 break; 1628 break;
1808 1629
1809 case MRES_SAVE: 1630 case 1:
1631 inmenu = false;
1632 break;
1633
1634 case 2:
1810 rb->splash(HZ, "Saving game..."); 1635 rb->splash(HZ, "Saving game...");
1811 jewels_savegame(bj); 1636 jewels_savegame(bj);
1812 return BJ_END; 1637 return BJ_END;
1813 1638
1814 case MRES_QUIT: 1639 case 3:
1815 return BJ_END; 1640 return BJ_END;
1816 1641
1817 case MRES_EXIT: 1642 case 4:
1818 return BJ_QUIT_FROM_GAME; 1643 return BJ_QUIT_FROM_GAME;
1819 1644
1645 case MENU_ATTACHED_USB:
1646 jewels_callback(bj);
1647 return BJ_USB;
1648
1820 default: 1649 default:
1650 inmenu = false;
1821 break; 1651 break;
1822 } 1652 }
1823 } 1653 }
1824 1654
1655 /* refresh the board */
1656 jewels_drawboard(bj);
1657
1658 /* display the cursor */
1659 if(selected) {
1660 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
1661 rb->lcd_fillrect(x*TILE_WIDTH, y*TILE_HEIGHT+YOFS,
1662 TILE_WIDTH, TILE_HEIGHT);
1663 rb->lcd_set_drawmode(DRMODE_SOLID);
1664 } else {
1665 rb->lcd_drawrect(x*TILE_WIDTH, y*TILE_HEIGHT+YOFS,
1666 TILE_WIDTH, TILE_HEIGHT);
1667 }
1668 rb->lcd_update_rect(x*TILE_WIDTH, y*TILE_HEIGHT+YOFS,
1669 TILE_WIDTH, TILE_HEIGHT);
1670
1825 /* handle game button presses */ 1671 /* handle game button presses */
1826 rb->yield(); 1672 rb->yield();
1827 button = rb->button_get(true); 1673 button = rb->button_get(true);
1828 switch(button){ 1674 switch(button){
1829 case JEWELS_LEFT: /* move cursor left */ 1675 case JEWELS_LEFT: /* move cursor left */
1830 case (JEWELS_LEFT|BUTTON_REPEAT): 1676 case (JEWELS_LEFT|BUTTON_REPEAT):
1831 if(!inmenu) { 1677 if(selected) {
1832 if(selected) { 1678 bj->score += jewels_swapjewels(bj, x, y, SWAP_LEFT);
1833 bj->score += jewels_swapjewels(bj, x, y, SWAP_LEFT); 1679 selected = false;
1834 selected = false; 1680 if (!jewels_movesavail(bj)) no_movesavail = true;
1835 if (!jewels_movesavail(bj)) no_movesavail = true; 1681 } else {
1836 } else { 1682 x = (x+BJ_WIDTH-1)%BJ_WIDTH;
1837 x = (x+BJ_WIDTH-1)%BJ_WIDTH;
1838 }
1839 } 1683 }
1840 break; 1684 break;
1841 1685
1842 case JEWELS_RIGHT: /* move cursor right */ 1686 case JEWELS_RIGHT: /* move cursor right */
1843 case (JEWELS_RIGHT|BUTTON_REPEAT): 1687 case (JEWELS_RIGHT|BUTTON_REPEAT):
1844 if(!inmenu) { 1688 if(selected) {
1845 if(selected) { 1689 bj->score += jewels_swapjewels(bj, x, y, SWAP_RIGHT);
1846 bj->score += jewels_swapjewels(bj, x, y, SWAP_RIGHT); 1690 selected = false;
1847 selected = false; 1691 if (!jewels_movesavail(bj)) no_movesavail = true;
1848 if (!jewels_movesavail(bj)) no_movesavail = true;
1849 } else {
1850 x = (x+1)%BJ_WIDTH;
1851 }
1852 } else { 1692 } else {
1853 cmd = MCMD_SELECT; 1693 x = (x+1)%BJ_WIDTH;
1854 } 1694 }
1855 break; 1695 break;
1856 1696
1857 case JEWELS_DOWN: /* move cursor down */ 1697 case JEWELS_DOWN: /* move cursor down */
1858 case (JEWELS_DOWN|BUTTON_REPEAT): 1698 case (JEWELS_DOWN|BUTTON_REPEAT):
1859 if(!inmenu) { 1699 if(selected) {
1860 if(selected) { 1700 bj->score += jewels_swapjewels(bj, x, y, SWAP_DOWN);
1861 bj->score += jewels_swapjewels(bj, x, y, SWAP_DOWN); 1701 selected = false;
1862 selected = false; 1702 if (!jewels_movesavail(bj)) no_movesavail = true;
1863 if (!jewels_movesavail(bj)) no_movesavail = true;
1864 } else {
1865 y = (y+1)%(BJ_HEIGHT-1);
1866 }
1867 } else { 1703 } else {
1868 cmd = MCMD_NEXT; 1704 y = (y+1)%(BJ_HEIGHT-1);
1869 } 1705 }
1870 break; 1706 break;
1871 1707
1872 case JEWELS_UP: /* move cursor up */ 1708 case JEWELS_UP: /* move cursor up */
1873 case (JEWELS_UP|BUTTON_REPEAT): 1709 case (JEWELS_UP|BUTTON_REPEAT):
1874 if(!inmenu) { 1710 if(selected) {
1875 if(selected) { 1711 bj->score += jewels_swapjewels(bj, x, y, SWAP_UP);
1876 bj->score += jewels_swapjewels(bj, x, y, SWAP_UP); 1712 selected = false;
1877 selected = false; 1713 if (!jewels_movesavail(bj)) no_movesavail = true;
1878 if (!jewels_movesavail(bj)) no_movesavail = true;
1879 } else {
1880 y = (y+(BJ_HEIGHT-1)-1)%(BJ_HEIGHT-1);
1881 }
1882 } else { 1714 } else {
1883 cmd = MCMD_PREV; 1715 y = (y+(BJ_HEIGHT-1)-1)%(BJ_HEIGHT-1);
1884 } 1716 }
1885 break; 1717 break;
1886 1718
1887#ifdef JEWELS_SCROLLWHEEL 1719#ifdef JEWELS_SCROLLWHEEL
1888 case JEWELS_PREV: /* scroll backwards */ 1720 case JEWELS_PREV: /* scroll backwards */
1889 case (JEWELS_PREV|BUTTON_REPEAT): 1721 case (JEWELS_PREV|BUTTON_REPEAT):
1890 if(!inmenu) { 1722 if(!selected) {
1891 if(!selected) { 1723 if(x == 0) {
1892 if(x == 0) { 1724 y = (y+(BJ_HEIGHT-1)-1)%(BJ_HEIGHT-1);
1893 y = (y+(BJ_HEIGHT-1)-1)%(BJ_HEIGHT-1);
1894 }
1895 x = (x+BJ_WIDTH-1)%BJ_WIDTH;
1896 } 1725 }
1897 } else { 1726 x = (x+BJ_WIDTH-1)%BJ_WIDTH;
1898 cmd = MCMD_PREV;
1899 } 1727 }
1900 break; 1728 break;
1901 1729
1902 case JEWELS_NEXT: /* scroll forwards */ 1730 case JEWELS_NEXT: /* scroll forwards */
1903 case (JEWELS_NEXT|BUTTON_REPEAT): 1731 case (JEWELS_NEXT|BUTTON_REPEAT):
1904 if(!inmenu) { 1732 if(!selected) {
1905 if(!selected) { 1733 if(x == BJ_WIDTH-1) {
1906 if(x == BJ_WIDTH-1) { 1734 y = (y+1)%(BJ_HEIGHT-1);
1907 y = (y+1)%(BJ_HEIGHT-1);
1908 }
1909 x = (x+1)%BJ_WIDTH;
1910 } 1735 }
1911 } else { 1736 x = (x+1)%BJ_WIDTH;
1912 cmd = MCMD_NEXT;
1913 } 1737 }
1914 break; 1738 break;
1915#endif 1739#endif
1916 1740
1917 case JEWELS_SELECT: /* toggle selected */ 1741 case JEWELS_SELECT: /* toggle selected */
1918 if(!inmenu) { 1742 selected = !selected;
1919 selected = !selected;
1920 } else {
1921 cmd = MCMD_SELECT;
1922 }
1923 break; 1743 break;
1924 1744
1925#ifdef JEWELS_MENU 1745#ifdef JEWELS_MENU
1926 case JEWELS_MENU: 1746 case JEWELS_MENU:
1927#endif 1747#endif
1928 case (JEWELS_SELECT|BUTTON_REPEAT): /* show menu */ 1748 case (JEWELS_SELECT|BUTTON_REPEAT): /* show menu */
1929 if(!inmenu) inmenu = true; 1749 inmenu = true;
1750 selected = false;
1930 break; 1751 break;
1931 1752
1932#ifdef JEWELS_CANCEL 1753#ifdef JEWELS_CANCEL