From 8848a001bf529a3e06710b80b928094e48f25aa8 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Mon, 12 Jul 2010 15:57:31 +0200 Subject: [PATCH] rnd-20100712-1-src * added level selection screen (when clicking on main menu level number) --- ChangeLog | 3 + src/conf_fnt.c | 16 +++ src/conf_gfx.c | 13 ++ src/conf_gfx.h | 221 +++++++++++++++-------------- src/conf_var.c | 16 +++ src/conftime.h | 2 +- src/events.c | 28 +++- src/files.c | 326 +++++++++++++++++++++++++++++++++++-------- src/files.h | 1 + src/game_em/cave.c | 5 +- src/game_em/export.h | 2 +- src/game_em/global.h | 1 - src/game_sp/export.h | 2 +- src/game_sp/file.c | 6 +- src/init.c | 1 + src/libgame/setup.c | 2 +- src/libgame/setup.h | 1 + src/libgame/system.h | 8 +- src/main.c | 1 + src/main.h | 50 +++---- src/screens.c | 160 +++++++++++++++++++-- src/screens.h | 3 +- 22 files changed, 654 insertions(+), 214 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6a2e7abc..2e74f2f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2010-07-12 + * added level selection screen (when clicking on main menu level number) + 2010-06-24 * added alternative game mode for playing with half size playfield tiles * fixed another memory violation bug in the native Supaplex game engine diff --git a/src/conf_fnt.c b/src/conf_fnt.c index f23bd997..c0ba77e6 100644 --- a/src/conf_fnt.c +++ b/src/conf_fnt.c @@ -83,6 +83,10 @@ font_to_graphic[] = FONT_TEXT_1, GFX_SPECIAL_ARG_LEVELS, IMG_FONT_TEXT_1_LEVELS }, + { + FONT_TEXT_1, GFX_SPECIAL_ARG_LEVELNR, + IMG_FONT_TEXT_1_LEVELNR + }, { FONT_TEXT_1, GFX_SPECIAL_ARG_SETUP, IMG_FONT_TEXT_1_SETUP @@ -119,6 +123,10 @@ font_to_graphic[] = FONT_TEXT_2, GFX_SPECIAL_ARG_LEVELS, IMG_FONT_TEXT_2_LEVELS }, + { + FONT_TEXT_2, GFX_SPECIAL_ARG_LEVELNR, + IMG_FONT_TEXT_2_LEVELNR + }, { FONT_TEXT_2, GFX_SPECIAL_ARG_SETUP, IMG_FONT_TEXT_2_SETUP @@ -143,6 +151,10 @@ font_to_graphic[] = FONT_TEXT_3, GFX_SPECIAL_ARG_LEVELS, IMG_FONT_TEXT_3_LEVELS }, + { + FONT_TEXT_3, GFX_SPECIAL_ARG_LEVELNR, + IMG_FONT_TEXT_3_LEVELNR + }, { FONT_TEXT_3, GFX_SPECIAL_ARG_SETUP, IMG_FONT_TEXT_3_SETUP @@ -171,6 +183,10 @@ font_to_graphic[] = FONT_TEXT_4, GFX_SPECIAL_ARG_LEVELS, IMG_FONT_TEXT_4_LEVELS }, + { + FONT_TEXT_4, GFX_SPECIAL_ARG_LEVELNR, + IMG_FONT_TEXT_4_LEVELNR + }, { FONT_TEXT_4, GFX_SPECIAL_ARG_SETUP, IMG_FONT_TEXT_4_SETUP diff --git a/src/conf_gfx.c b/src/conf_gfx.c index 259f7317..c7ea0459 100644 --- a/src/conf_gfx.c +++ b/src/conf_gfx.c @@ -4929,6 +4929,8 @@ struct ConfigInfo image_config[] = { "font.text_1.LEVELS.y", "0" }, { "font.text_1.LEVELS.width", "16" }, { "font.text_1.LEVELS.height", "32" }, + { "font.text_1.LEVELNR", UNDEFINED_FILENAME }, + { "font.text_1.LEVELNR.clone_from", "font.text_1.LEVELS" }, { "font.text_1.SETUP", UNDEFINED_FILENAME }, { "font.text_1.SETUP.clone_from", "font.text_1.LEVELS" }, { "font.text_1.PREVIEW", "RocksFontEM.pcx" }, @@ -4962,6 +4964,8 @@ struct ConfigInfo image_config[] = { "font.text_2.LEVELS.y", "160" }, { "font.text_2.LEVELS.width", "16" }, { "font.text_2.LEVELS.height", "32" }, + { "font.text_2.LEVELNR", UNDEFINED_FILENAME }, + { "font.text_2.LEVELNR.clone_from", "font.text_2.LEVELS" }, { "font.text_2.SETUP", UNDEFINED_FILENAME }, { "font.text_2.SETUP.clone_from", "font.text_2.LEVELS" }, { "font.text_2.PREVIEW", "RocksFontEM.pcx" }, @@ -4989,6 +4993,8 @@ struct ConfigInfo image_config[] = { "font.text_3.LEVELS.y", "320" }, { "font.text_3.LEVELS.width", "16" }, { "font.text_3.LEVELS.height", "32" }, + { "font.text_3.LEVELNR", UNDEFINED_FILENAME }, + { "font.text_3.LEVELNR.clone_from", "font.text_3.LEVELS" }, { "font.text_3.SETUP", UNDEFINED_FILENAME }, { "font.text_3.SETUP.clone_from", "font.text_3.LEVELS" }, { "font.text_3.PREVIEW", "RocksFontEM.pcx" }, @@ -5018,6 +5024,8 @@ struct ConfigInfo image_config[] = { "font.text_4.LEVELS.y", "480" }, { "font.text_4.LEVELS.width", "16" }, { "font.text_4.LEVELS.height", "32" }, + { "font.text_4.LEVELNR", UNDEFINED_FILENAME }, + { "font.text_4.LEVELNR.clone_from", "font.text_4.LEVELS" }, { "font.text_4.SETUP", UNDEFINED_FILENAME }, { "font.text_4.SETUP.clone_from", "font.text_4.LEVELS" }, { "font.text_4.SCORES", "RocksFontMedium.pcx" }, @@ -5174,6 +5182,7 @@ struct ConfigInfo image_config[] = { "background.TITLE", UNDEFINED_FILENAME }, { "background.MAIN", UNDEFINED_FILENAME }, { "background.LEVELS", UNDEFINED_FILENAME }, + { "background.LEVELNR", UNDEFINED_FILENAME }, { "background.SCORES", UNDEFINED_FILENAME }, { "background.EDITOR", UNDEFINED_FILENAME }, { "background.INFO", UNDEFINED_FILENAME }, @@ -5497,6 +5506,7 @@ struct ConfigInfo image_config[] = { "border.draw_masked.TITLE", "false" }, { "border.draw_masked.MAIN", "false" }, { "border.draw_masked.LEVELS", "false" }, + { "border.draw_masked.LEVELNR", "false" }, { "border.draw_masked.SCORES", "false" }, { "border.draw_masked.EDITOR", "false" }, { "border.draw_masked.INFO", "false" }, @@ -5557,6 +5567,8 @@ struct ConfigInfo image_config[] = { "menu.draw_yoffset.MAIN", "0" }, { "menu.draw_xoffset.LEVELS", "0" }, { "menu.draw_yoffset.LEVELS", "0" }, + { "menu.draw_xoffset.LEVELNR", "0" }, + { "menu.draw_yoffset.LEVELNR", "0" }, { "menu.draw_xoffset.SCORES", "0" }, { "menu.draw_yoffset.SCORES", "0" }, { "menu.draw_xoffset.EDITOR", "0" }, @@ -5608,6 +5620,7 @@ struct ConfigInfo image_config[] = { "menu.list_size", "-1" }, { "menu.list_size.LEVELS", "-1" }, + { "menu.list_size.LEVELNR", "-1" }, { "menu.list_size.SCORES", "-1" }, { "menu.list_size.INFO", "-1" }, { "menu.list_size.SETUP", "-1" }, diff --git a/src/conf_gfx.h b/src/conf_gfx.h index 9340cc2b..32ae13ba 100644 --- a/src/conf_gfx.h +++ b/src/conf_gfx.h @@ -1747,114 +1747,119 @@ #define IMG_FONT_TEXT_1 1726 #define IMG_FONT_TEXT_1_MAIN 1727 #define IMG_FONT_TEXT_1_LEVELS 1728 -#define IMG_FONT_TEXT_1_SETUP 1729 -#define IMG_FONT_TEXT_1_PREVIEW 1730 -#define IMG_FONT_TEXT_1_SCORES 1731 -#define IMG_FONT_TEXT_1_ACTIVE_SCORES 1732 -#define IMG_FONT_TEXT_1_PANEL 1733 -#define IMG_FONT_TEXT_1_DOOR 1734 -#define IMG_FONT_TEXT_2 1735 -#define IMG_FONT_TEXT_2_MAIN 1736 -#define IMG_FONT_TEXT_2_LEVELS 1737 -#define IMG_FONT_TEXT_2_SETUP 1738 -#define IMG_FONT_TEXT_2_PREVIEW 1739 -#define IMG_FONT_TEXT_2_SCORES 1740 -#define IMG_FONT_TEXT_2_ACTIVE_SCORES 1741 -#define IMG_FONT_TEXT_3 1742 -#define IMG_FONT_TEXT_3_LEVELS 1743 -#define IMG_FONT_TEXT_3_SETUP 1744 -#define IMG_FONT_TEXT_3_PREVIEW 1745 -#define IMG_FONT_TEXT_3_SCORES 1746 -#define IMG_FONT_TEXT_3_ACTIVE_SCORES 1747 -#define IMG_FONT_TEXT_4 1748 -#define IMG_FONT_TEXT_4_MAIN 1749 -#define IMG_FONT_TEXT_4_LEVELS 1750 -#define IMG_FONT_TEXT_4_SETUP 1751 -#define IMG_FONT_TEXT_4_SCORES 1752 -#define IMG_FONT_TEXT_4_ACTIVE_SCORES 1753 -#define IMG_FONT_ENVELOPE_1 1754 -#define IMG_FONT_ENVELOPE_2 1755 -#define IMG_FONT_ENVELOPE_3 1756 -#define IMG_FONT_ENVELOPE_4 1757 -#define IMG_FONT_INPUT_1 1758 -#define IMG_FONT_INPUT_1_MAIN 1759 -#define IMG_FONT_INPUT_1_ACTIVE 1760 -#define IMG_FONT_INPUT_1_ACTIVE_MAIN 1761 -#define IMG_FONT_INPUT_1_ACTIVE_SETUP 1762 -#define IMG_FONT_INPUT_2 1763 -#define IMG_FONT_INPUT_2_ACTIVE 1764 -#define IMG_FONT_OPTION_OFF 1765 -#define IMG_FONT_OPTION_ON 1766 -#define IMG_FONT_VALUE_1 1767 -#define IMG_FONT_VALUE_2 1768 -#define IMG_FONT_VALUE_OLD 1769 -#define IMG_FONT_LEVEL_NUMBER 1770 -#define IMG_FONT_LEVEL_NUMBER_ACTIVE 1771 -#define IMG_FONT_TAPE_RECORDER 1772 -#define IMG_FONT_GAME_INFO 1773 -#define IMG_FONT_INFO_ELEMENTS 1774 -#define IMG_FONT_INFO_LEVELSET 1775 -#define IMG_GLOBAL_BORDER 1776 -#define IMG_GLOBAL_DOOR 1777 -#define IMG_GLOBAL_BUSY 1778 -#define IMG_EDITOR_ELEMENT_BORDER 1779 -#define IMG_EDITOR_ELEMENT_BORDER_INPUT 1780 -#define IMG_EDITOR_CASCADE_LIST 1781 -#define IMG_EDITOR_CASCADE_LIST_ACTIVE 1782 -#define IMG_BACKGROUND 1783 -#define IMG_BACKGROUND_TITLE_INITIAL 1784 -#define IMG_BACKGROUND_TITLE 1785 -#define IMG_BACKGROUND_MAIN 1786 -#define IMG_BACKGROUND_LEVELS 1787 -#define IMG_BACKGROUND_SCORES 1788 -#define IMG_BACKGROUND_EDITOR 1789 -#define IMG_BACKGROUND_INFO 1790 -#define IMG_BACKGROUND_INFO_ELEMENTS 1791 -#define IMG_BACKGROUND_INFO_MUSIC 1792 -#define IMG_BACKGROUND_INFO_CREDITS 1793 -#define IMG_BACKGROUND_INFO_PROGRAM 1794 -#define IMG_BACKGROUND_INFO_VERSION 1795 -#define IMG_BACKGROUND_INFO_LEVELSET 1796 -#define IMG_BACKGROUND_SETUP 1797 -#define IMG_BACKGROUND_PLAYING 1798 -#define IMG_BACKGROUND_DOOR 1799 -#define IMG_BACKGROUND_TAPE 1800 -#define IMG_BACKGROUND_PANEL 1801 -#define IMG_BACKGROUND_TITLESCREEN_INITIAL_1 1802 -#define IMG_BACKGROUND_TITLESCREEN_INITIAL_2 1803 -#define IMG_BACKGROUND_TITLESCREEN_INITIAL_3 1804 -#define IMG_BACKGROUND_TITLESCREEN_INITIAL_4 1805 -#define IMG_BACKGROUND_TITLESCREEN_INITIAL_5 1806 -#define IMG_BACKGROUND_TITLESCREEN_1 1807 -#define IMG_BACKGROUND_TITLESCREEN_2 1808 -#define IMG_BACKGROUND_TITLESCREEN_3 1809 -#define IMG_BACKGROUND_TITLESCREEN_4 1810 -#define IMG_BACKGROUND_TITLESCREEN_5 1811 -#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_1 1812 -#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_2 1813 -#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_3 1814 -#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_4 1815 -#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_5 1816 -#define IMG_BACKGROUND_TITLEMESSAGE_1 1817 -#define IMG_BACKGROUND_TITLEMESSAGE_2 1818 -#define IMG_BACKGROUND_TITLEMESSAGE_3 1819 -#define IMG_BACKGROUND_TITLEMESSAGE_4 1820 -#define IMG_BACKGROUND_TITLEMESSAGE_5 1821 -#define IMG_BACKGROUND_ENVELOPE_1 1822 -#define IMG_BACKGROUND_ENVELOPE_2 1823 -#define IMG_BACKGROUND_ENVELOPE_3 1824 -#define IMG_BACKGROUND_ENVELOPE_4 1825 -#define IMG_TITLESCREEN_INITIAL_1 1826 -#define IMG_TITLESCREEN_INITIAL_2 1827 -#define IMG_TITLESCREEN_INITIAL_3 1828 -#define IMG_TITLESCREEN_INITIAL_4 1829 -#define IMG_TITLESCREEN_INITIAL_5 1830 -#define IMG_TITLESCREEN_1 1831 -#define IMG_TITLESCREEN_2 1832 -#define IMG_TITLESCREEN_3 1833 -#define IMG_TITLESCREEN_4 1834 -#define IMG_TITLESCREEN_5 1835 +#define IMG_FONT_TEXT_1_LEVELNR 1729 +#define IMG_FONT_TEXT_1_SETUP 1730 +#define IMG_FONT_TEXT_1_PREVIEW 1731 +#define IMG_FONT_TEXT_1_SCORES 1732 +#define IMG_FONT_TEXT_1_ACTIVE_SCORES 1733 +#define IMG_FONT_TEXT_1_PANEL 1734 +#define IMG_FONT_TEXT_1_DOOR 1735 +#define IMG_FONT_TEXT_2 1736 +#define IMG_FONT_TEXT_2_MAIN 1737 +#define IMG_FONT_TEXT_2_LEVELS 1738 +#define IMG_FONT_TEXT_2_LEVELNR 1739 +#define IMG_FONT_TEXT_2_SETUP 1740 +#define IMG_FONT_TEXT_2_PREVIEW 1741 +#define IMG_FONT_TEXT_2_SCORES 1742 +#define IMG_FONT_TEXT_2_ACTIVE_SCORES 1743 +#define IMG_FONT_TEXT_3 1744 +#define IMG_FONT_TEXT_3_LEVELS 1745 +#define IMG_FONT_TEXT_3_LEVELNR 1746 +#define IMG_FONT_TEXT_3_SETUP 1747 +#define IMG_FONT_TEXT_3_PREVIEW 1748 +#define IMG_FONT_TEXT_3_SCORES 1749 +#define IMG_FONT_TEXT_3_ACTIVE_SCORES 1750 +#define IMG_FONT_TEXT_4 1751 +#define IMG_FONT_TEXT_4_MAIN 1752 +#define IMG_FONT_TEXT_4_LEVELS 1753 +#define IMG_FONT_TEXT_4_LEVELNR 1754 +#define IMG_FONT_TEXT_4_SETUP 1755 +#define IMG_FONT_TEXT_4_SCORES 1756 +#define IMG_FONT_TEXT_4_ACTIVE_SCORES 1757 +#define IMG_FONT_ENVELOPE_1 1758 +#define IMG_FONT_ENVELOPE_2 1759 +#define IMG_FONT_ENVELOPE_3 1760 +#define IMG_FONT_ENVELOPE_4 1761 +#define IMG_FONT_INPUT_1 1762 +#define IMG_FONT_INPUT_1_MAIN 1763 +#define IMG_FONT_INPUT_1_ACTIVE 1764 +#define IMG_FONT_INPUT_1_ACTIVE_MAIN 1765 +#define IMG_FONT_INPUT_1_ACTIVE_SETUP 1766 +#define IMG_FONT_INPUT_2 1767 +#define IMG_FONT_INPUT_2_ACTIVE 1768 +#define IMG_FONT_OPTION_OFF 1769 +#define IMG_FONT_OPTION_ON 1770 +#define IMG_FONT_VALUE_1 1771 +#define IMG_FONT_VALUE_2 1772 +#define IMG_FONT_VALUE_OLD 1773 +#define IMG_FONT_LEVEL_NUMBER 1774 +#define IMG_FONT_LEVEL_NUMBER_ACTIVE 1775 +#define IMG_FONT_TAPE_RECORDER 1776 +#define IMG_FONT_GAME_INFO 1777 +#define IMG_FONT_INFO_ELEMENTS 1778 +#define IMG_FONT_INFO_LEVELSET 1779 +#define IMG_GLOBAL_BORDER 1780 +#define IMG_GLOBAL_DOOR 1781 +#define IMG_GLOBAL_BUSY 1782 +#define IMG_EDITOR_ELEMENT_BORDER 1783 +#define IMG_EDITOR_ELEMENT_BORDER_INPUT 1784 +#define IMG_EDITOR_CASCADE_LIST 1785 +#define IMG_EDITOR_CASCADE_LIST_ACTIVE 1786 +#define IMG_BACKGROUND 1787 +#define IMG_BACKGROUND_TITLE_INITIAL 1788 +#define IMG_BACKGROUND_TITLE 1789 +#define IMG_BACKGROUND_MAIN 1790 +#define IMG_BACKGROUND_LEVELS 1791 +#define IMG_BACKGROUND_LEVELNR 1792 +#define IMG_BACKGROUND_SCORES 1793 +#define IMG_BACKGROUND_EDITOR 1794 +#define IMG_BACKGROUND_INFO 1795 +#define IMG_BACKGROUND_INFO_ELEMENTS 1796 +#define IMG_BACKGROUND_INFO_MUSIC 1797 +#define IMG_BACKGROUND_INFO_CREDITS 1798 +#define IMG_BACKGROUND_INFO_PROGRAM 1799 +#define IMG_BACKGROUND_INFO_VERSION 1800 +#define IMG_BACKGROUND_INFO_LEVELSET 1801 +#define IMG_BACKGROUND_SETUP 1802 +#define IMG_BACKGROUND_PLAYING 1803 +#define IMG_BACKGROUND_DOOR 1804 +#define IMG_BACKGROUND_TAPE 1805 +#define IMG_BACKGROUND_PANEL 1806 +#define IMG_BACKGROUND_TITLESCREEN_INITIAL_1 1807 +#define IMG_BACKGROUND_TITLESCREEN_INITIAL_2 1808 +#define IMG_BACKGROUND_TITLESCREEN_INITIAL_3 1809 +#define IMG_BACKGROUND_TITLESCREEN_INITIAL_4 1810 +#define IMG_BACKGROUND_TITLESCREEN_INITIAL_5 1811 +#define IMG_BACKGROUND_TITLESCREEN_1 1812 +#define IMG_BACKGROUND_TITLESCREEN_2 1813 +#define IMG_BACKGROUND_TITLESCREEN_3 1814 +#define IMG_BACKGROUND_TITLESCREEN_4 1815 +#define IMG_BACKGROUND_TITLESCREEN_5 1816 +#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_1 1817 +#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_2 1818 +#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_3 1819 +#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_4 1820 +#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_5 1821 +#define IMG_BACKGROUND_TITLEMESSAGE_1 1822 +#define IMG_BACKGROUND_TITLEMESSAGE_2 1823 +#define IMG_BACKGROUND_TITLEMESSAGE_3 1824 +#define IMG_BACKGROUND_TITLEMESSAGE_4 1825 +#define IMG_BACKGROUND_TITLEMESSAGE_5 1826 +#define IMG_BACKGROUND_ENVELOPE_1 1827 +#define IMG_BACKGROUND_ENVELOPE_2 1828 +#define IMG_BACKGROUND_ENVELOPE_3 1829 +#define IMG_BACKGROUND_ENVELOPE_4 1830 +#define IMG_TITLESCREEN_INITIAL_1 1831 +#define IMG_TITLESCREEN_INITIAL_2 1832 +#define IMG_TITLESCREEN_INITIAL_3 1833 +#define IMG_TITLESCREEN_INITIAL_4 1834 +#define IMG_TITLESCREEN_INITIAL_5 1835 +#define IMG_TITLESCREEN_1 1836 +#define IMG_TITLESCREEN_2 1837 +#define IMG_TITLESCREEN_3 1838 +#define IMG_TITLESCREEN_4 1839 +#define IMG_TITLESCREEN_5 1840 -#define NUM_IMAGE_FILES 1836 +#define NUM_IMAGE_FILES 1841 #endif /* CONF_GFX_H */ diff --git a/src/conf_var.c b/src/conf_var.c index f29e8b55..059f3db6 100644 --- a/src/conf_var.c +++ b/src/conf_var.c @@ -936,6 +936,10 @@ struct TokenIntPtrInfo image_config_vars[] = "border.draw_masked.LEVELS", &border.draw_masked[GFX_SPECIAL_ARG_LEVELS] }, + { + "border.draw_masked.LEVELNR", + &border.draw_masked[GFX_SPECIAL_ARG_LEVELNR] + }, { "border.draw_masked.SCORES", &border.draw_masked[GFX_SPECIAL_ARG_SCORES] @@ -1160,6 +1164,14 @@ struct TokenIntPtrInfo image_config_vars[] = "menu.draw_yoffset.LEVELS", &menu.draw_yoffset[GFX_SPECIAL_ARG_LEVELS] }, + { + "menu.draw_xoffset.LEVELNR", + &menu.draw_xoffset[GFX_SPECIAL_ARG_LEVELNR] + }, + { + "menu.draw_yoffset.LEVELNR", + &menu.draw_yoffset[GFX_SPECIAL_ARG_LEVELNR] + }, { "menu.draw_xoffset.SCORES", &menu.draw_xoffset[GFX_SPECIAL_ARG_SCORES] @@ -1356,6 +1368,10 @@ struct TokenIntPtrInfo image_config_vars[] = "menu.list_size.LEVELS", &menu.list_size[GFX_SPECIAL_ARG_LEVELS] }, + { + "menu.list_size.LEVELNR", + &menu.list_size[GFX_SPECIAL_ARG_LEVELNR] + }, { "menu.list_size.SCORES", &menu.list_size[GFX_SPECIAL_ARG_SCORES] diff --git a/src/conftime.h b/src/conftime.h index d417f020..b3a00a14 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "2010-07-08 15:40" +#define COMPILE_DATE_STRING "2010-07-12 15:47" diff --git a/src/events.c b/src/events.c index cb810adf..ebcb5e1d 100644 --- a/src/events.c +++ b/src/events.c @@ -465,7 +465,11 @@ void HandleButton(int mx, int my, int button, int button_nr) break; case GAME_MODE_LEVELS: - HandleChooseLevel(mx, my, 0, 0, button); + HandleChooseLevelSet(mx, my, 0, 0, button); + break; + + case GAME_MODE_LEVELNR: + HandleChooseLevelNr(mx, my, 0, 0, button); break; case GAME_MODE_SCORES: @@ -871,6 +875,7 @@ void HandleKey(Key key, int key_status) case GAME_MODE_TITLE: case GAME_MODE_MAIN: case GAME_MODE_LEVELS: + case GAME_MODE_LEVELNR: case GAME_MODE_SETUP: case GAME_MODE_INFO: case GAME_MODE_SCORES: @@ -883,7 +888,9 @@ void HandleKey(Key key, int key_status) else if (game_status == GAME_MODE_MAIN) HandleMainMenu(0, 0, 0, 0, MB_MENU_CHOICE); else if (game_status == GAME_MODE_LEVELS) - HandleChooseLevel(0, 0, 0, 0, MB_MENU_CHOICE); + HandleChooseLevelSet(0, 0, 0, 0, MB_MENU_CHOICE); + else if (game_status == GAME_MODE_LEVELNR) + HandleChooseLevelNr(0, 0, 0, 0, MB_MENU_CHOICE); else if (game_status == GAME_MODE_SETUP) HandleSetupScreen(0, 0, 0, 0, MB_MENU_CHOICE); else if (game_status == GAME_MODE_INFO) @@ -899,7 +906,9 @@ void HandleKey(Key key, int key_status) if (game_status == GAME_MODE_TITLE) HandleTitleScreen(0, 0, 0, 0, MB_MENU_LEAVE); else if (game_status == GAME_MODE_LEVELS) - HandleChooseLevel(0, 0, 0, 0, MB_MENU_LEAVE); + HandleChooseLevelSet(0, 0, 0, 0, MB_MENU_LEAVE); + else if (game_status == GAME_MODE_LEVELNR) + HandleChooseLevelNr(0, 0, 0, 0, MB_MENU_LEAVE); else if (game_status == GAME_MODE_SETUP) HandleSetupScreen(0, 0, 0, 0, MB_MENU_LEAVE); else if (game_status == GAME_MODE_INFO) @@ -910,7 +919,9 @@ void HandleKey(Key key, int key_status) case KSYM_Page_Up: if (game_status == GAME_MODE_LEVELS) - HandleChooseLevel(0, 0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK); + HandleChooseLevelSet(0, 0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK); + else if (game_status == GAME_MODE_LEVELNR) + HandleChooseLevelNr(0, 0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK); else if (game_status == GAME_MODE_SETUP) HandleSetupScreen(0, 0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK); else if (game_status == GAME_MODE_INFO) @@ -921,7 +932,9 @@ void HandleKey(Key key, int key_status) case KSYM_Page_Down: if (game_status == GAME_MODE_LEVELS) - HandleChooseLevel(0, 0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK); + HandleChooseLevelSet(0, 0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK); + else if (game_status == GAME_MODE_LEVELNR) + HandleChooseLevelNr(0, 0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK); else if (game_status == GAME_MODE_SETUP) HandleSetupScreen(0, 0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK); else if (game_status == GAME_MODE_INFO) @@ -1124,6 +1137,7 @@ void HandleJoystick() case GAME_MODE_TITLE: case GAME_MODE_MAIN: case GAME_MODE_LEVELS: + case GAME_MODE_LEVELNR: case GAME_MODE_SETUP: case GAME_MODE_INFO: { @@ -1138,7 +1152,9 @@ void HandleJoystick() else if (game_status == GAME_MODE_MAIN) HandleMainMenu(0,0,dx,dy, newbutton ? MB_MENU_CHOICE : MB_MENU_MARK); else if (game_status == GAME_MODE_LEVELS) - HandleChooseLevel(0,0,dx,dy, newbutton ? MB_MENU_CHOICE : MB_MENU_MARK); + HandleChooseLevelSet(0,0,dx,dy,newbutton?MB_MENU_CHOICE : MB_MENU_MARK); + else if (game_status == GAME_MODE_LEVELNR) + HandleChooseLevelNr(0,0,dx,dy,newbutton? MB_MENU_CHOICE : MB_MENU_MARK); else if (game_status == GAME_MODE_SETUP) HandleSetupScreen(0,0,dx,dy, newbutton ? MB_MENU_CHOICE : MB_MENU_MARK); else if (game_status == GAME_MODE_INFO) diff --git a/src/files.c b/src/files.c index 74702b8d..ff33da82 100644 --- a/src/files.c +++ b/src/files.c @@ -1596,11 +1596,203 @@ void setElementChangeInfoToDefaults(struct ElementChangeInfo *change) change->post_change_function = NULL; } -static void setLevelInfoToDefaults(struct LevelInfo *level) +#if 1 + +static void setLevelInfoToDefaults_Level(struct LevelInfo *level) +{ + int i, x, y; + + li = *level; /* copy level data into temporary buffer */ + setConfigToDefaultsFromConfigList(chunk_config_INFO); + *level = li; /* copy temporary buffer back to level data */ + + setLevelInfoToDefaults_EM(); + setLevelInfoToDefaults_SP(); + + level->native_em_level = &native_em_level; + level->native_sp_level = &native_sp_level; + + level->file_version = FILE_VERSION_ACTUAL; + level->game_version = GAME_VERSION_ACTUAL; + + level->creation_date = getCurrentDate(); + + level->encoding_16bit_field = TRUE; + level->encoding_16bit_yamyam = TRUE; + level->encoding_16bit_amoeba = TRUE; + + for (x = 0; x < MAX_LEV_FIELDX; x++) + for (y = 0; y < MAX_LEV_FIELDY; y++) + level->field[x][y] = EL_SAND; + + for (i = 0; i < MAX_LEVEL_NAME_LEN; i++) + level->name[i] = '\0'; + for (i = 0; i < MAX_LEVEL_AUTHOR_LEN; i++) + level->author[i] = '\0'; + + strcpy(level->name, NAMELESS_LEVEL_NAME); + strcpy(level->author, ANONYMOUS_NAME); + + level->field[0][0] = EL_PLAYER_1; + level->field[STD_LEV_FIELDX - 1][STD_LEV_FIELDY - 1] = EL_EXIT_CLOSED; + + BorderElement = EL_STEELWALL; + + /* set all bug compatibility flags to "false" => do not emulate this bug */ + level->use_action_after_change_bug = FALSE; + + if (leveldir_current) + { + /* try to determine better author name than 'anonymous' */ + if (!strEqual(leveldir_current->author, ANONYMOUS_NAME)) + { + strncpy(level->author, leveldir_current->author, MAX_LEVEL_AUTHOR_LEN); + level->author[MAX_LEVEL_AUTHOR_LEN] = '\0'; + } + else + { + switch (LEVELCLASS(leveldir_current)) + { + case LEVELCLASS_TUTORIAL: + strcpy(level->author, PROGRAM_AUTHOR_STRING); + break; + + case LEVELCLASS_CONTRIB: + strncpy(level->author, leveldir_current->name, MAX_LEVEL_AUTHOR_LEN); + level->author[MAX_LEVEL_AUTHOR_LEN] = '\0'; + break; + + case LEVELCLASS_PRIVATE: + strncpy(level->author, getRealName(), MAX_LEVEL_AUTHOR_LEN); + level->author[MAX_LEVEL_AUTHOR_LEN] = '\0'; + break; + + default: + /* keep default value */ + break; + } + } + } +} + +static void setLevelInfoToDefaults_Elements(struct LevelInfo *level) +{ + static boolean clipboard_elements_initialized = FALSE; + int i; + + InitElementPropertiesStatic(); + + li = *level; /* copy level data into temporary buffer */ + setConfigToDefaultsFromConfigList(chunk_config_ELEM); + *level = li; /* copy temporary buffer back to level data */ + + for (i = 0; i < MAX_NUM_ELEMENTS; i++) + { + int element = i; + struct ElementInfo *ei = &element_info[element]; + + /* never initialize clipboard elements after the very first time */ + /* (to be able to use clipboard elements between several levels) */ + if (IS_CLIPBOARD_ELEMENT(element) && clipboard_elements_initialized) + continue; + + if (IS_ENVELOPE(element)) + { + int envelope_nr = element - EL_ENVELOPE_1; + + setConfigToDefaultsFromConfigList(chunk_config_NOTE); + + level->envelope[envelope_nr] = xx_envelope; + } + + if (IS_CUSTOM_ELEMENT(element) || + IS_GROUP_ELEMENT(element) || + IS_INTERNAL_ELEMENT(element)) + { + xx_ei = *ei; /* copy element data into temporary buffer */ + + setConfigToDefaultsFromConfigList(chunk_config_CUSX_base); + + *ei = xx_ei; + } + + setElementChangePages(ei, 1); + setElementChangeInfoToDefaults(ei->change); + + if (IS_CUSTOM_ELEMENT(element) || + IS_GROUP_ELEMENT(element) || + IS_INTERNAL_ELEMENT(element)) + { + setElementDescriptionToDefault(ei); + + ei->modified_settings = FALSE; + } + + if (IS_CUSTOM_ELEMENT(element) || + IS_INTERNAL_ELEMENT(element)) + { + /* internal values used in level editor */ + + ei->access_type = 0; + ei->access_layer = 0; + ei->access_protected = 0; + ei->walk_to_action = 0; + ei->smash_targets = 0; + ei->deadliness = 0; + + ei->can_explode_by_fire = FALSE; + ei->can_explode_smashed = FALSE; + ei->can_explode_impact = FALSE; + + ei->current_change_page = 0; + } + + if (IS_GROUP_ELEMENT(element) || + IS_INTERNAL_ELEMENT(element)) + { + struct ElementGroupInfo *group; + + /* initialize memory for list of elements in group */ + if (ei->group == NULL) + ei->group = checked_malloc(sizeof(struct ElementGroupInfo)); + + group = ei->group; + + xx_group = *group; /* copy group data into temporary buffer */ + + setConfigToDefaultsFromConfigList(chunk_config_GRPX); + + *group = xx_group; + } + } + + clipboard_elements_initialized = TRUE; +} + +static void setLevelInfoToDefaults(struct LevelInfo *level, + boolean level_info_only) +{ + setLevelInfoToDefaults_Level(level); + + if (!level_info_only) + setLevelInfoToDefaults_Elements(level); + + level->no_valid_file = FALSE; + + level->changed = FALSE; +} + +#else + +static void setLevelInfoToDefaults(struct LevelInfo *level, + boolean level_info_only) { static boolean clipboard_elements_initialized = FALSE; int i, x, y; + if (level_info_only) + return; + InitElementPropertiesStatic(); li = *level; /* copy level data into temporary buffer */ @@ -1731,40 +1923,42 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) /* set all bug compatibility flags to "false" => do not emulate this bug */ level->use_action_after_change_bug = FALSE; - if (leveldir_current == NULL) /* only when dumping level */ - return; - - /* try to determine better author name than 'anonymous' */ - if (!strEqual(leveldir_current->author, ANONYMOUS_NAME)) - { - strncpy(level->author, leveldir_current->author, MAX_LEVEL_AUTHOR_LEN); - level->author[MAX_LEVEL_AUTHOR_LEN] = '\0'; - } - else + if (leveldir_current) { - switch (LEVELCLASS(leveldir_current)) + /* try to determine better author name than 'anonymous' */ + if (!strEqual(leveldir_current->author, ANONYMOUS_NAME)) { - case LEVELCLASS_TUTORIAL: - strcpy(level->author, PROGRAM_AUTHOR_STRING); - break; - - case LEVELCLASS_CONTRIB: - strncpy(level->author, leveldir_current->name, MAX_LEVEL_AUTHOR_LEN); - level->author[MAX_LEVEL_AUTHOR_LEN] = '\0'; - break; - - case LEVELCLASS_PRIVATE: - strncpy(level->author, getRealName(), MAX_LEVEL_AUTHOR_LEN); - level->author[MAX_LEVEL_AUTHOR_LEN] = '\0'; - break; - - default: - /* keep default value */ - break; + strncpy(level->author, leveldir_current->author, MAX_LEVEL_AUTHOR_LEN); + level->author[MAX_LEVEL_AUTHOR_LEN] = '\0'; + } + else + { + switch (LEVELCLASS(leveldir_current)) + { + case LEVELCLASS_TUTORIAL: + strcpy(level->author, PROGRAM_AUTHOR_STRING); + break; + + case LEVELCLASS_CONTRIB: + strncpy(level->author, leveldir_current->name, MAX_LEVEL_AUTHOR_LEN); + level->author[MAX_LEVEL_AUTHOR_LEN] = '\0'; + break; + + case LEVELCLASS_PRIVATE: + strncpy(level->author, getRealName(), MAX_LEVEL_AUTHOR_LEN); + level->author[MAX_LEVEL_AUTHOR_LEN] = '\0'; + break; + + default: + /* keep default value */ + break; + } } } } +#endif + static void setFileInfoToDefaults(struct LevelFileInfo *level_file_info) { level_file_info->nr = 0; @@ -3120,7 +3314,8 @@ static int LoadLevel_GRPX(FILE *file, int chunk_size, struct LevelInfo *level) } static void LoadLevelFromFileInfo_RND(struct LevelInfo *level, - struct LevelFileInfo *level_file_info) + struct LevelFileInfo *level_file_info, + boolean level_info_only) { char *filename = level_file_info->filename; char cookie[MAX_LINE_LEN]; @@ -3133,7 +3328,8 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level, level->no_valid_file = TRUE; #if 1 - Error(ERR_WARN, "cannot read level '%s' -- using empty level", filename); + if (!level_info_only) + Error(ERR_WARN, "cannot read level '%s' -- using empty level", filename); #else if (level != &level_template) Error(ERR_WARN, "cannot read level '%s' -- using empty level", filename); @@ -4091,7 +4287,8 @@ static void LoadLevelFromFileStream_SP(FILE *file, struct LevelInfo *level, } static void LoadLevelFromFileInfo_SP(struct LevelInfo *level, - struct LevelFileInfo *level_file_info) + struct LevelFileInfo *level_file_info, + boolean level_info_only) { char *filename = level_file_info->filename; FILE *file; @@ -4109,7 +4306,8 @@ static void LoadLevelFromFileInfo_SP(struct LevelInfo *level, { level->no_valid_file = TRUE; - Error(ERR_WARN, "cannot read level '%s' -- using empty level", filename); + if (!level_info_only) + Error(ERR_WARN, "cannot read level '%s' -- using empty level", filename); return; } @@ -6186,7 +6384,8 @@ static void LoadLevelFromFileStream_DC(FILE *file, struct LevelInfo *level, } static void LoadLevelFromFileInfo_DC(struct LevelInfo *level, - struct LevelFileInfo *level_file_info) + struct LevelFileInfo *level_file_info, + boolean level_info_only) { char *filename = level_file_info->filename; FILE *file; @@ -6198,7 +6397,8 @@ static void LoadLevelFromFileInfo_DC(struct LevelInfo *level, { level->no_valid_file = TRUE; - Error(ERR_WARN, "cannot read level '%s' -- using empty level", filename); + if (!level_info_only) + Error(ERR_WARN, "cannot read level '%s' -- using empty level", filename); return; } @@ -6301,7 +6501,8 @@ static void LoadLevelFromFileInfo_DC(struct LevelInfo *level, { level->no_valid_file = TRUE; - Error(ERR_WARN, "cannot read level '%s' -- using empty level", filename); + if (!level_info_only) + Error(ERR_WARN, "cannot read level '%s' -- using empty level", filename); return; } @@ -6535,7 +6736,8 @@ int getMappedElement_SB(int element_ascii, boolean use_ces) } static void LoadLevelFromFileInfo_SB(struct LevelInfo *level, - struct LevelFileInfo *level_file_info) + struct LevelFileInfo *level_file_info, + boolean level_info_only) { char *filename = level_file_info->filename; char line[MAX_LINE_LEN], line_raw[MAX_LINE_LEN], previous_line[MAX_LINE_LEN]; @@ -6565,7 +6767,8 @@ static void LoadLevelFromFileInfo_SB(struct LevelInfo *level, { level->no_valid_file = TRUE; - Error(ERR_WARN, "cannot read level '%s' -- using empty level", filename); + if (!level_info_only) + Error(ERR_WARN, "cannot read level '%s' -- using empty level", filename); return; } @@ -6842,14 +7045,16 @@ static void LoadLevelFromFileInfo_SB(struct LevelInfo *level, /* ------------------------------------------------------------------------- */ static void LoadLevelFromFileInfo_EM(struct LevelInfo *level, - struct LevelFileInfo *level_file_info) + struct LevelFileInfo *level_file_info, + boolean level_info_only) { - if (!LoadNativeLevel_EM(level_file_info->filename)) + if (!LoadNativeLevel_EM(level_file_info->filename, level_info_only)) level->no_valid_file = TRUE; } static void LoadLevelFromFileInfo_SP(struct LevelInfo *level, - struct LevelFileInfo *level_file_info) + struct LevelFileInfo *level_file_info, + boolean level_info_only) { int pos = 0; @@ -6857,7 +7062,7 @@ static void LoadLevelFromFileInfo_SP(struct LevelInfo *level, if (level_file_info->packed) pos = level_file_info->nr - leveldir_current->first_level; - if (!LoadNativeLevel_SP(level_file_info->filename, pos)) + if (!LoadNativeLevel_SP(level_file_info->filename, pos, level_info_only)) level->no_valid_file = TRUE; } @@ -6896,44 +7101,45 @@ void SaveNativeLevel(struct LevelInfo *level) /* functions for loading generic level */ /* ------------------------------------------------------------------------- */ -void LoadLevelFromFileInfo(struct LevelInfo *level, - struct LevelFileInfo *level_file_info) +static void LoadLevelFromFileInfo(struct LevelInfo *level, + struct LevelFileInfo *level_file_info, + boolean level_info_only) { /* always start with reliable default values */ - setLevelInfoToDefaults(level); + setLevelInfoToDefaults(level, level_info_only); switch (level_file_info->type) { case LEVEL_FILE_TYPE_RND: - LoadLevelFromFileInfo_RND(level, level_file_info); + LoadLevelFromFileInfo_RND(level, level_file_info, level_info_only); break; case LEVEL_FILE_TYPE_EM: - LoadLevelFromFileInfo_EM(level, level_file_info); + LoadLevelFromFileInfo_EM(level, level_file_info, level_info_only); level->game_engine_type = GAME_ENGINE_TYPE_EM; break; case LEVEL_FILE_TYPE_SP: - LoadLevelFromFileInfo_SP(level, level_file_info); + LoadLevelFromFileInfo_SP(level, level_file_info, level_info_only); level->game_engine_type = GAME_ENGINE_TYPE_SP; break; case LEVEL_FILE_TYPE_DC: - LoadLevelFromFileInfo_DC(level, level_file_info); + LoadLevelFromFileInfo_DC(level, level_file_info, level_info_only); break; case LEVEL_FILE_TYPE_SB: - LoadLevelFromFileInfo_SB(level, level_file_info); + LoadLevelFromFileInfo_SB(level, level_file_info, level_info_only); break; default: - LoadLevelFromFileInfo_RND(level, level_file_info); + LoadLevelFromFileInfo_RND(level, level_file_info, level_info_only); break; } /* if level file is invalid, restore level structure to default values */ if (level->no_valid_file) - setLevelInfoToDefaults(level); + setLevelInfoToDefaults(level, level_info_only); if (level->game_engine_type == GAME_ENGINE_TYPE_UNKNOWN) level->game_engine_type = GAME_ENGINE_TYPE_RND; @@ -6953,7 +7159,7 @@ void LoadLevelFromFilename(struct LevelInfo *level, char *filename) level_file_info.type = LEVEL_FILE_TYPE_RND; /* no others supported yet */ level_file_info.filename = filename; - LoadLevelFromFileInfo(level, &level_file_info); + LoadLevelFromFileInfo(level, &level_file_info, FALSE); } static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename) @@ -7341,7 +7547,7 @@ void LoadLevelTemplate(int nr) setLevelFileInfo(&level_template.file_info, nr); filename = level_template.file_info.filename; - LoadLevelFromFileInfo(&level_template, &level_template.file_info); + LoadLevelFromFileInfo(&level_template, &level_template.file_info, FALSE); LoadLevel_InitVersion(&level_template, filename); LoadLevel_InitElements(&level_template, filename); @@ -7356,7 +7562,7 @@ void LoadLevel(int nr) setLevelFileInfo(&level.file_info, nr); filename = level.file_info.filename; - LoadLevelFromFileInfo(&level, &level.file_info); + LoadLevelFromFileInfo(&level, &level.file_info, FALSE); if (level.use_custom_template) LoadLevelTemplate(-1); @@ -7368,6 +7574,16 @@ void LoadLevel(int nr) LoadLevel_InitNativeEngines(&level, filename); } +void LoadLevelInfoOnly(int nr) +{ + char *filename; + + setLevelFileInfo(&level.file_info, nr); + filename = level.file_info.filename; + + LoadLevelFromFileInfo(&level, &level.file_info, TRUE); +} + static int SaveLevel_VERS(FILE *file, struct LevelInfo *level) { int chunk_size = 0; diff --git a/src/files.h b/src/files.h index 9edda322..cd8bfec4 100644 --- a/src/files.h +++ b/src/files.h @@ -36,6 +36,7 @@ char *getDefaultLevelFilename(int); void LoadLevelFromFilename(struct LevelInfo *, char *); void LoadLevel(int); void LoadLevelTemplate(int); +void LoadLevelInfoOnly(int); void SaveLevel(int); void SaveLevelTemplate(); void SaveNativeLevel(struct LevelInfo *); diff --git a/src/game_em/cave.c b/src/game_em/cave.c index 5fb55dc5..b816aff2 100644 --- a/src/game_em/cave.c +++ b/src/game_em/cave.c @@ -74,7 +74,7 @@ void setLevelInfoToDefaults_EM(void) #define MAX_EM_LEVEL_SIZE 16384 -boolean LoadNativeLevel_EM(char *filename) +boolean LoadNativeLevel_EM(char *filename, boolean level_info_only) { unsigned char raw_leveldata[MAX_EM_LEVEL_SIZE]; int raw_leveldata_length; @@ -86,7 +86,8 @@ boolean LoadNativeLevel_EM(char *filename) if (!(file = fopen(filename, MODE_READ))) { - Error(ERR_WARN, "cannot open level '%s' -- using empty level", filename); + if (!level_info_only) + Error(ERR_WARN, "cannot open level '%s' -- using empty level", filename); return FALSE; } diff --git a/src/game_em/export.h b/src/game_em/export.h index b9a7e412..f9fa8884 100644 --- a/src/game_em/export.h +++ b/src/game_em/export.h @@ -735,7 +735,7 @@ extern void GameActions_EM(byte *, boolean); extern unsigned int InitEngineRandom_EM(long); extern void setLevelInfoToDefaults_EM(); -extern boolean LoadNativeLevel_EM(char *); +extern boolean LoadNativeLevel_EM(char *, boolean); extern void BackToFront_EM(void); extern void BlitScreenToBitmap_EM(Bitmap *); diff --git a/src/game_em/global.h b/src/game_em/global.h index 9590d196..0f2a6448 100644 --- a/src/game_em/global.h +++ b/src/game_em/global.h @@ -45,7 +45,6 @@ void play_sound(int, int, int); void sound_play(void); int cave_convert(char *); -boolean LoadNativeLevel_EM(char *); void game_init_vars(void); void game_play_init(int, char *); diff --git a/src/game_sp/export.h b/src/game_sp/export.h index 2dbd0ae0..a8e6e318 100644 --- a/src/game_sp/export.h +++ b/src/game_sp/export.h @@ -197,7 +197,7 @@ extern unsigned int InitEngineRandom_SP(long); extern void setLevelInfoToDefaults_SP(); extern void copyInternalEngineVars_SP(); -extern boolean LoadNativeLevel_SP(char *, int); +extern boolean LoadNativeLevel_SP(char *, int, boolean); extern void SaveNativeLevel_SP(char *); extern void BackToFront_SP(void); diff --git a/src/game_sp/file.c b/src/game_sp/file.c index 27cb452a..53eb22ff 100644 --- a/src/game_sp/file.c +++ b/src/game_sp/file.c @@ -298,7 +298,8 @@ static void LoadNativeLevelFromFileStream_SP(FILE *file, int width, int height, } } -boolean LoadNativeLevel_SP(char *filename, int level_pos) +boolean LoadNativeLevel_SP(char *filename, int level_pos, + boolean level_info_only) { FILE *file; int i, l, x, y; @@ -324,7 +325,8 @@ boolean LoadNativeLevel_SP(char *filename, int level_pos) if (!(file = fopen(filename, MODE_READ))) { - Error(ERR_WARN, "cannot open file '%s' -- using empty level", filename); + if (!level_info_only) + Error(ERR_WARN, "cannot open file '%s' -- using empty level", filename); return FALSE; } diff --git a/src/init.c b/src/init.c index 506f9354..e239da9d 100644 --- a/src/init.c +++ b/src/init.c @@ -1877,6 +1877,7 @@ static void InitGraphicInfo() IMG_BACKGROUND_TITLE, IMG_BACKGROUND_MAIN, IMG_BACKGROUND_LEVELS, + IMG_BACKGROUND_LEVELNR, IMG_BACKGROUND_SCORES, IMG_BACKGROUND_EDITOR, IMG_BACKGROUND_INFO, diff --git a/src/libgame/setup.c b/src/libgame/setup.c index b7e34adf..3b0bc871 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -2679,7 +2679,7 @@ static TreeInfo *getTreeInfoCopy(TreeInfo *ti) return ti_copy; } -static void freeTreeInfo(TreeInfo *ti) +void freeTreeInfo(TreeInfo *ti) { if (ti == NULL) return; diff --git a/src/libgame/setup.h b/src/libgame/setup.h index b0b6a8d2..68643a2f 100644 --- a/src/libgame/setup.h +++ b/src/libgame/setup.h @@ -266,6 +266,7 @@ void sortTreeInfoBySortFunction(TreeInfo **, int (*compare_function)(const void *, const void *)); void sortTreeInfo(TreeInfo **); +void freeTreeInfo(TreeInfo *); char *getHomeDir(void); char *getCommonDataDir(void); diff --git a/src/libgame/system.h b/src/libgame/system.h index d9b42bac..e5375e09 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -504,16 +504,20 @@ #define TREE_TYPE_SOUNDS_DIR ARTWORK_TYPE_SOUNDS #define TREE_TYPE_MUSIC_DIR ARTWORK_TYPE_MUSIC #define TREE_TYPE_LEVEL_DIR 3 +#define TREE_TYPE_LEVEL_NR 4 -#define NUM_TREE_TYPES 4 +#define NUM_TREE_TYPES 5 #define INFOTEXT_UNDEFINED "" #define INFOTEXT_GRAPHICS_DIR "Custom Graphics" #define INFOTEXT_SOUNDS_DIR "Custom Sounds" #define INFOTEXT_MUSIC_DIR "Custom Music" #define INFOTEXT_LEVEL_DIR "Level Sets" +#define INFOTEXT_LEVEL_NR "Levels" -#define TREE_INFOTEXT(t) ((t) == TREE_TYPE_LEVEL_DIR ? \ +#define TREE_INFOTEXT(t) ((t) == TREE_TYPE_LEVEL_NR ? \ + INFOTEXT_LEVEL_NR : \ + (t) == TREE_TYPE_LEVEL_DIR ? \ INFOTEXT_LEVEL_DIR : \ (t) == TREE_TYPE_GRAPHICS_DIR ? \ INFOTEXT_GRAPHICS_DIR : \ diff --git a/src/main.c b/src/main.c index 3e3ad2a7..5c25fc6b 100644 --- a/src/main.c +++ b/src/main.c @@ -5460,6 +5460,7 @@ struct SpecialSuffixInfo special_suffix_info[NUM_SPECIAL_GFX_ARGS + 1 + 1] = { ".TITLE", GFX_SPECIAL_ARG_TITLE, }, { ".MAIN", GFX_SPECIAL_ARG_MAIN, }, { ".LEVELS", GFX_SPECIAL_ARG_LEVELS }, + { ".LEVELNR", GFX_SPECIAL_ARG_LEVELNR }, { ".SCORES", GFX_SPECIAL_ARG_SCORES, }, { ".EDITOR", GFX_SPECIAL_ARG_EDITOR, }, { ".INFO", GFX_SPECIAL_ARG_INFO, }, diff --git a/src/main.h b/src/main.h index 3fd8c915..b9cc814e 100644 --- a/src/main.h +++ b/src/main.h @@ -1858,18 +1858,19 @@ #define GFX_SPECIAL_ARG_TITLE 3 #define GFX_SPECIAL_ARG_MAIN 4 #define GFX_SPECIAL_ARG_LEVELS 5 -#define GFX_SPECIAL_ARG_SCORES 6 -#define GFX_SPECIAL_ARG_EDITOR 7 -#define GFX_SPECIAL_ARG_INFO 8 -#define GFX_SPECIAL_ARG_SETUP 9 -#define GFX_SPECIAL_ARG_PLAYING 10 -#define GFX_SPECIAL_ARG_DOOR 11 -#define GFX_SPECIAL_ARG_TAPE 12 -#define GFX_SPECIAL_ARG_PANEL 13 -#define GFX_SPECIAL_ARG_PREVIEW 14 -#define GFX_SPECIAL_ARG_CRUMBLED 15 - -#define NUM_SPECIAL_GFX_ARGS 16 +#define GFX_SPECIAL_ARG_LEVELNR 6 +#define GFX_SPECIAL_ARG_SCORES 7 +#define GFX_SPECIAL_ARG_EDITOR 8 +#define GFX_SPECIAL_ARG_INFO 9 +#define GFX_SPECIAL_ARG_SETUP 10 +#define GFX_SPECIAL_ARG_PLAYING 11 +#define GFX_SPECIAL_ARG_DOOR 12 +#define GFX_SPECIAL_ARG_TAPE 13 +#define GFX_SPECIAL_ARG_PANEL 14 +#define GFX_SPECIAL_ARG_PREVIEW 15 +#define GFX_SPECIAL_ARG_CRUMBLED 16 + +#define NUM_SPECIAL_GFX_ARGS 17 /* these additional definitions are currently only used for draw offsets */ #define GFX_SPECIAL_ARG_INFO_MAIN 0 @@ -2036,20 +2037,21 @@ #define GAME_MODE_TITLE 3 #define GAME_MODE_MAIN 4 #define GAME_MODE_LEVELS 5 -#define GAME_MODE_SCORES 6 -#define GAME_MODE_EDITOR 7 -#define GAME_MODE_INFO 8 -#define GAME_MODE_SETUP 9 -#define GAME_MODE_PLAYING 10 -#define GAME_MODE_PSEUDO_DOOR 11 -#define GAME_MODE_PSEUDO_TAPE 12 -#define GAME_MODE_PSEUDO_PANEL 13 -#define GAME_MODE_PSEUDO_PREVIEW 14 -#define GAME_MODE_PSEUDO_CRUMBLED 15 +#define GAME_MODE_LEVELNR 6 +#define GAME_MODE_SCORES 7 +#define GAME_MODE_EDITOR 8 +#define GAME_MODE_INFO 9 +#define GAME_MODE_SETUP 10 +#define GAME_MODE_PLAYING 11 +#define GAME_MODE_PSEUDO_DOOR 12 +#define GAME_MODE_PSEUDO_TAPE 13 +#define GAME_MODE_PSEUDO_PANEL 14 +#define GAME_MODE_PSEUDO_PREVIEW 15 +#define GAME_MODE_PSEUDO_CRUMBLED 16 /* there are no special config file suffixes for these modes */ -#define GAME_MODE_PSEUDO_TYPENAME 16 -#define GAME_MODE_QUIT 17 +#define GAME_MODE_PSEUDO_TYPENAME 17 +#define GAME_MODE_QUIT 18 /* special definitions currently only used for custom artwork configuration */ #define MUSIC_PREFIX_BACKGROUND 0 diff --git a/src/screens.c b/src/screens.c index cd9edc46..37ccbe8e 100644 --- a/src/screens.c +++ b/src/screens.c @@ -141,7 +141,8 @@ static void execSetupGraphics(void); static void execSetupArtwork(void); static void HandleChooseTree(int, int, int, int, int, TreeInfo **); -static void DrawChooseLevel(void); +static void DrawChooseLevelSet(void); +static void DrawChooseLevelNr(void); static void DrawInfoScreen(void); static void DrawAndFadeInInfoScreen(int); static void DrawSetupScreen(void); @@ -175,6 +176,9 @@ static TreeInfo *scroll_delay_current = NULL; static TreeInfo *game_speeds = NULL; static TreeInfo *game_speed_current = NULL; +static TreeInfo *level_number = NULL; +static TreeInfo *level_number_current = NULL; + static struct { int value; @@ -867,8 +871,13 @@ static void InitializeMainControls() if (pos_text != NULL) /* (x/y may be -1/-1 here) */ { +#if 1 + /* calculate size for non-clickable text -- needed for text alignment */ + boolean calculate_text_size = (pos_button == NULL && text != NULL); +#else /* calculate width for non-clickable text -- needed for text alignment */ boolean calculate_text_width = (pos_button == NULL && text != NULL); +#endif if (visibleMenuPos(pos_button)) { @@ -878,10 +887,17 @@ static void InitializeMainControls() pos_text->y = pos_button->y; } +#if 1 + if (pos_text->width == -1 || calculate_text_size) + pos_text->width = text_width; + if (pos_text->height == -1 || calculate_text_size) + pos_text->height = text_height; +#else if (pos_text->width == -1 || calculate_text_width) pos_text->width = text_width; if (pos_text->height == -1) pos_text->height = text_height; +#endif } if (pos_input != NULL) /* (x/y may be -1/-1 here) */ @@ -1020,6 +1036,13 @@ static boolean insideTextPosRect(struct TextPosInfo *rect, int x, int y) int rect_x = ALIGNED_TEXT_XPOS(rect); int rect_y = ALIGNED_TEXT_YPOS(rect); +#if 0 + printf("::: insideTextPosRect: (%d, %d), (%d, %d) [%d, %d] (%d, %d) => %d\n", + x, y, rect_x, rect_y, rect->x, rect->y, rect->width, rect->height, + (x >= rect_x && x < rect_x + rect->width && + y >= rect_y && y < rect_y + rect->height)); +#endif + return (x >= rect_x && x < rect_x + rect->width && y >= rect_y && y < rect_y + rect->height); } @@ -1703,10 +1726,19 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) for (i = 0; main_controls[i].nr != -1; i++) { +#if 0 + printf("::: check click (%d, %d) for %d [%d] ...\n", + mx - mSX, my - mSY, i, main_controls[i].nr); +#endif + if (insideMenuPosRect(main_controls[i].pos_button, mx - mSX, my - mSY) || insideTextPosRect(main_controls[i].pos_text, mx - mSX, my - mSY) || insideTextPosRect(main_controls[i].pos_input, mx - mSX, my - mSY)) { +#if 0 + printf("::: inside %d\n", i); +#endif + pos = main_controls[i].nr; break; @@ -1726,6 +1758,20 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) { HandleMainMenu_SelectLevel(1, dx < 0 ? -1 : +1); } + else if (pos == MAIN_CONTROL_FIRST_LEVEL && !button) + { + HandleMainMenu_SelectLevel(MAX_LEVELS, -1); + } + else if (pos == MAIN_CONTROL_LAST_LEVEL && !button) + { + HandleMainMenu_SelectLevel(MAX_LEVELS, +1); + } + else if (pos == MAIN_CONTROL_LEVEL_NUMBER && !button) + { + game_status = GAME_MODE_LEVELNR; + + DrawChooseLevelNr(); + } else if (pos >= MAIN_CONTROL_NAME && pos <= MAIN_CONTROL_QUIT) { if (button) @@ -1763,7 +1809,7 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) gotoTopLevelDir(); #endif - DrawChooseLevel(); + DrawChooseLevelSet(); } } else if (pos == MAIN_CONTROL_SCORES) @@ -3296,8 +3342,8 @@ static void drawChooseTreeList(int first_entry, int num_page_entries, char *title_string = NULL; int yoffset_sets = MENU_TITLE1_YPOS; int yoffset_setup = 16; - int yoffset = (ti->type == TREE_TYPE_LEVEL_DIR ? yoffset_sets : - yoffset_setup); + int yoffset = (ti->type == TREE_TYPE_LEVEL_DIR || + ti->type == TREE_TYPE_LEVEL_NR ? yoffset_sets : yoffset_setup); int last_game_status = game_status; /* save current game status */ title_string = ti->infotext; @@ -3365,6 +3411,9 @@ static void drawChooseTreeInfo(int entry_pos, TreeInfo *ti) int ypos = MENU_TITLE2_YPOS; int font_nr = FONT_TITLE_2; + if (ti->type == TREE_TYPE_LEVEL_NR) + DrawTextFCentered(ypos, font_nr, leveldir_current->name); + if (ti->type != TREE_TYPE_LEVEL_DIR) return; @@ -3373,6 +3422,18 @@ static void drawChooseTreeInfo(int entry_pos, TreeInfo *ti) DrawBackgroundForFont(SX, SY + ypos, SXSIZE, getFontHeight(font_nr), font_nr); +#if 1 + if (node->parent_link) + DrawTextFCentered(ypos, font_nr, "leave \"%s\"", + node->node_parent->name); + else if (node->level_group) + DrawTextFCentered(ypos, font_nr, "enter \"%s\"", + node->name); + else if (ti->type == TREE_TYPE_LEVEL_DIR) + DrawTextFCentered(ypos, font_nr, "%3d %s (%s)", + node->levels, (node->levels > 1 ? "levels" : "level"), + node->class_desc); +#else if (node->parent_link) DrawTextFCentered(ypos, font_nr, "leave group \"%s\"", node->class_desc); @@ -3382,6 +3443,7 @@ static void drawChooseTreeInfo(int entry_pos, TreeInfo *ti) else if (ti->type == TREE_TYPE_LEVEL_DIR) DrawTextFCentered(ypos, font_nr, "%3d levels (%s)", node->levels, node->class_desc); +#endif /* let BackToFront() redraw only what is needed */ redraw_mask = last_redraw_mask | REDRAW_TILES; @@ -3468,6 +3530,9 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, } else { + if (game_status == GAME_MODE_LEVELNR) + level_nr = atoi(level_number_current->identifier); + game_status = GAME_MODE_MAIN; DrawMainMenuExt(REDRAW_FIELD, FALSE); @@ -3651,7 +3716,11 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, } else { + if (game_status == GAME_MODE_LEVELNR) + level_nr = atoi(level_number_current->identifier); + game_status = GAME_MODE_MAIN; + DrawMainMenu(); } } @@ -3659,7 +3728,7 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, } } -void DrawChooseLevel() +void DrawChooseLevelSet() { SetMainBackgroundImage(IMG_BACKGROUND_LEVELS); @@ -3669,13 +3738,80 @@ void DrawChooseLevel() PlayMenuMusic(); } -void HandleChooseLevel(int mx, int my, int dx, int dy, int button) +void HandleChooseLevelSet(int mx, int my, int dx, int dy, int button) { HandleChooseTree(mx, my, dx, dy, button, &leveldir_current); DoAnimation(); } +void DrawChooseLevelNr() +{ + int i; + + if (level_number != NULL) + { + freeTreeInfo(level_number); + + level_number = NULL; + } + + for (i = leveldir_current->first_level; i <= leveldir_current->last_level;i++) + { + TreeInfo *ti = newTreeInfo_setDefaults(TREE_TYPE_LEVEL_NR); + char identifier[32], name[32]; + int value = i; + + /* temporarily load level info to get level name */ + LoadLevelInfoOnly(i); + + ti->node_top = &level_number; + ti->sort_priority = 10000 + value; + + sprintf(identifier, "%d", value); + sprintf(name, "%03d: %s", value, level.name); + + setString(&ti->identifier, identifier); + setString(&ti->name, name); + setString(&ti->name_sorting, name); + + pushTreeInfo(&level_number, ti); + } + + /* sort level number values to start with lowest level number */ + sortTreeInfo(&level_number); + + /* set current level number to current level number */ + level_number_current = + getTreeInfoFromIdentifier(level_number, i_to_a(level_nr)); + + /* if that also fails, set current level number to first available level */ + if (level_number_current == NULL) + level_number_current = level_number; + + SetMainBackgroundImage(IMG_BACKGROUND_LEVELNR); + +#if 1 + DrawChooseTree(&level_number_current); +#else + DrawChooseTree(&leveldir_current); +#endif + + PlayMenuSound(); + PlayMenuMusic(); +} + +void HandleChooseLevelNr(int mx, int my, int dx, int dy, int button) +{ +#if 1 + HandleChooseTree(mx, my, dx, dy, button, &level_number_current); +#else + HandleChooseTree(mx, my, dx, dy, button, &leveldir_current); +#endif + + DoAnimation(); +} + void DrawHallOfFame(int highlight_position) { UnmapAllGadgets(); @@ -6087,21 +6223,27 @@ static void HandleScreenGadgets(struct GadgetInfo *gi) case SCREEN_CTRL_ID_SCROLL_UP: if (game_status == GAME_MODE_LEVELS) - HandleChooseLevel(0,0, 0, -1 * SCROLL_LINE, MB_MENU_MARK); + HandleChooseLevelSet(0,0, 0, -1 * SCROLL_LINE, MB_MENU_MARK); + else if (game_status == GAME_MODE_LEVELNR) + HandleChooseLevelNr(0,0, 0, -1 * SCROLL_LINE, MB_MENU_MARK); else if (game_status == GAME_MODE_SETUP) HandleSetupScreen(0,0, 0, -1 * SCROLL_LINE, MB_MENU_MARK); break; case SCREEN_CTRL_ID_SCROLL_DOWN: if (game_status == GAME_MODE_LEVELS) - HandleChooseLevel(0,0, 0, +1 * SCROLL_LINE, MB_MENU_MARK); + HandleChooseLevelSet(0,0, 0, +1 * SCROLL_LINE, MB_MENU_MARK); + else if (game_status == GAME_MODE_LEVELNR) + HandleChooseLevelNr(0,0, 0, +1 * SCROLL_LINE, MB_MENU_MARK); else if (game_status == GAME_MODE_SETUP) HandleSetupScreen(0,0, 0, +1 * SCROLL_LINE, MB_MENU_MARK); break; case SCREEN_CTRL_ID_SCROLL_VERTICAL: if (game_status == GAME_MODE_LEVELS) - HandleChooseLevel(0,0, 999,gi->event.item_position,MB_MENU_INITIALIZE); + HandleChooseLevelSet(0,0,999,gi->event.item_position,MB_MENU_INITIALIZE); + else if (game_status == GAME_MODE_LEVELNR) + HandleChooseLevelNr(0,0,999,gi->event.item_position,MB_MENU_INITIALIZE); else if (game_status == GAME_MODE_SETUP) HandleSetupScreen(0,0, 999,gi->event.item_position,MB_MENU_INITIALIZE); break; diff --git a/src/screens.h b/src/screens.h index e08e1be4..7c3a1999 100644 --- a/src/screens.h +++ b/src/screens.h @@ -32,7 +32,8 @@ void RedrawSetupScreenAfterFullscreenToggle(); void HandleTitleScreen(int, int, int, int, int); void HandleMainMenu(int, int, int, int, int); -void HandleChooseLevel(int, int, int, int, int); +void HandleChooseLevelSet(int, int, int, int, int); +void HandleChooseLevelNr(int, int, int, int, int); void HandleHallOfFame(int, int, int, int, int); void HandleInfoScreen(int, int, int, int, int); void HandleSetupScreen(int, int, int, int, int); -- 2.34.1