diff --git a/VisualStudio/fheroes2/common.props b/VisualStudio/fheroes2/common.props index b6d510181dd..d4b9e149844 100644 --- a/VisualStudio/fheroes2/common.props +++ b/VisualStudio/fheroes2/common.props @@ -2,7 +2,7 @@ - src\engine;src\fheroes2\gui;src\fheroes2\maps;src\fheroes2\kingdom;src\fheroes2\campaign;src\fheroes2\game;src\fheroes2\dialog;src\fheroes2\system;src\fheroes2\spell;src\fheroes2\monster;src\fheroes2\castle;src\fheroes2\agg;src\fheroes2\heroes;src\fheroes2\resource;src\fheroes2\ai;src\fheroes2\army;src\fheroes2\battle;src\fheroes2\h2d;src\fheroes2\objects;src\fheroes2\world;src\fheroes2\audio;src\fheroes2\image;src\thirdparty\libsmacker;%(AdditionalIncludeDirectories) + src\engine;src\fheroes2\gui;src\fheroes2\maps;src\fheroes2\kingdom;src\fheroes2\campaign;src\fheroes2\game;src\fheroes2\editor;src\fheroes2\dialog;src\fheroes2\system;src\fheroes2\spell;src\fheroes2\monster;src\fheroes2\castle;src\fheroes2\agg;src\fheroes2\heroes;src\fheroes2\resource;src\fheroes2\ai;src\fheroes2\army;src\fheroes2\battle;src\fheroes2\h2d;src\fheroes2\objects;src\fheroes2\world;src\fheroes2\audio;src\fheroes2\image;src\thirdparty\libsmacker;%(AdditionalIncludeDirectories) BUILD_VERSION=$(FHEROES2_BUILD_NUMBER);%(PreprocessorDefinitions) diff --git a/VisualStudio/fheroes2/sources.props b/VisualStudio/fheroes2/sources.props index 78ffea884ec..4cda29e1a4f 100644 --- a/VisualStudio/fheroes2/sources.props +++ b/VisualStudio/fheroes2/sources.props @@ -104,6 +104,7 @@ + @@ -298,6 +299,7 @@ + diff --git a/src/fheroes2/CMakeLists.txt b/src/fheroes2/CMakeLists.txt index 5d1dd2362a9..c35cce280e8 100644 --- a/src/fheroes2/CMakeLists.txt +++ b/src/fheroes2/CMakeLists.txt @@ -97,6 +97,7 @@ target_include_directories( campaign castle dialog + editor game gui h2d diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index a7a80740a1e..810e4ac8da6 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -2635,6 +2635,15 @@ namespace fheroes2 return true; } + case ICN::EDITOR: + LoadOriginalICN( id ); + if ( !_icnVsSprite[id].empty() ) { + // This is the Editor main menu background which shouldn't have any transform layer. + _icnVsSprite[id][0]._disableTransformLayer(); + // Fix the cycling colors in original editor main menu background. + fheroes2::ApplyPalette( _icnVsSprite[id][0], PAL::GetPalette( PAL::PaletteType::NO_CYCLE ) ); + } + return true; case ICN::HEROES: LoadOriginalICN( id ); if ( !_icnVsSprite[id].empty() ) { @@ -3672,7 +3681,15 @@ namespace fheroes2 // We have few ICNs which we need to scale like some related to main screen bool IsScalableICN( const int id ) { - return id == ICN::HEROES || id == ICN::BTNSHNGL || id == ICN::SHNGANIM; + switch ( id ) { + case ICN::EDITOR: + case ICN::HEROES: + case ICN::BTNSHNGL: + case ICN::SHNGANIM: + return true; + default: + return false; + } } const Sprite & GetScaledICN( const int icnId, const uint32_t index ) diff --git a/src/fheroes2/editor/editor.h b/src/fheroes2/editor/editor.h new file mode 100644 index 00000000000..fa79fffbc0f --- /dev/null +++ b/src/fheroes2/editor/editor.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * fheroes2: https://github.com/ihhub/fheroes2 * + * Copyright (C) 2023 * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#pragma once + +#if defined( WITH_DEBUG ) +#include "game.h" +#include "game_mode.h" + +namespace Editor +{ + fheroes2::GameMode menuMain(); + fheroes2::GameMode menuNewMap(); + fheroes2::GameMode menuLoadMap(); +} +#endif diff --git a/src/fheroes2/editor/editor_mainmenu.cpp b/src/fheroes2/editor/editor_mainmenu.cpp new file mode 100644 index 00000000000..26fe6874352 --- /dev/null +++ b/src/fheroes2/editor/editor_mainmenu.cpp @@ -0,0 +1,305 @@ +/*************************************************************************** + * fheroes2: https://github.com/ihhub/fheroes2 * + * Copyright (C) 2023 * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#if defined( WITH_DEBUG ) + +#include +#include +#include +#include +#include + +#include "audio.h" +#include "audio_manager.h" +#include "cursor.h" +#include "dialog.h" +#include "dialog_selectscenario.h" +#include "editor.h" +#include "game_hotkeys.h" +#include "game_mainmenu_ui.h" +#include "game_mode.h" +#include "icn.h" +#include "localevent.h" +#include "logging.h" +#include "maps.h" +#include "maps_fileinfo.h" +#include "math_base.h" +#include "mus.h" +#include "text.h" +#include "tools.h" +#include "translations.h" +#include "ui_button.h" +#include "ui_dialog.h" + +namespace +{ + const int32_t buttonYStep = 66; + const size_t mapSizeCount = 4; + const std::array mapSizeHotkeys = { Game::HotKeyEvent::MAIN_MENU_MAP_SIZE_SMALL, Game::HotKeyEvent::MAIN_MENU_MAP_SIZE_MEDIUM, + Game::HotKeyEvent::MAIN_MENU_MAP_SIZE_LARGE, Game::HotKeyEvent::MAIN_MENU_MAP_SIZE_EXTRA_LARGE }; + const std::array mapSizes = { Maps::SMALL, Maps::MEDIUM, Maps::LARGE, Maps::XLARGE }; + + void outputEditorMainMenuInTextSupportMode() + { + START_TEXT_SUPPORT_MODE + + COUT( "Map Editor\n" ) + + COUT( "Press " << Game::getHotKeyNameByEventId( Game::HotKeyEvent::EDITOR_NEW_MAP_MENU ) + << " to create a new map either from scratch or using the random map generator." ) + COUT( "Press " << Game::getHotKeyNameByEventId( Game::HotKeyEvent::EDITOR_LOAD_MAP_MENU ) << " to load an existing map." ) + COUT( "Press " << Game::getHotKeyNameByEventId( Game::HotKeyEvent::DEFAULT_CANCEL ) << " to go back to Main Menu." ) + } + + void outputEditorNewMapMenuInTextSupportMode() + { + START_TEXT_SUPPORT_MODE + + COUT( "New Map\n" ) + + COUT( "Press " << Game::getHotKeyNameByEventId( Game::HotKeyEvent::EDITOR_FROM_SCRATCH_MAP_MENU ) << " to create a blank map from scratch." ) + COUT( "Press " << Game::getHotKeyNameByEventId( Game::HotKeyEvent::EDITOR_RANDOM_MAP_MENU ) << " to create a randomly generated map." ) + COUT( "Press " << Game::getHotKeyNameByEventId( Game::HotKeyEvent::DEFAULT_CANCEL ) << " to go back to Map Editor main menu." ) + } + + void outputEditorMapSizeMenuInTextSupportMode() + { + START_TEXT_SUPPORT_MODE + + COUT( "Map Size\n" ) + + const size_t buttonCount = mapSizeHotkeys.size(); + for ( size_t i = 0; i < buttonCount; ++i ) { + std::string message = " to create a map that is %{size} squares wide and %{size} squares high."; + StringReplace( message, "%{size}", std::to_string( mapSizes[i] ) ); + + COUT( "Press " << Game::getHotKeyNameByEventId( mapSizeHotkeys[i] ) << message ) + } + + COUT( "Press " << Game::getHotKeyNameByEventId( Game::HotKeyEvent::DEFAULT_CANCEL ) << " to go back to New Map menu." ) + } + + void showWIPInfo() + { + fheroes2::showStandardTextMessage( _( "Warning!" ), "The Map Editor is still in development. This function is not available yet.", Dialog::OK ); + } + + Maps::mapsize_t selectMapSize() + { + outputEditorMapSizeMenuInTextSupportMode(); + + const CursorRestorer cursorRestorer( true, Cursor::POINTER ); + + fheroes2::drawEditorMainMenuScreen(); + + const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); + + std::array buttons; + + for ( uint32_t i = 0; i < mapSizeCount; ++i ) { + buttons[i].setICNInfo( ICN::BTNESIZE, 0 + i * 2, 1 + i * 2 ); + buttons[i].setPosition( buttonPos.x, buttonPos.y + buttonYStep * static_cast( i ) ); + buttons[i].draw(); + } + + fheroes2::Button cancel( buttonPos.x, buttonPos.y + 5 * buttonYStep, ICN::BUTTON_LARGE_CANCEL, 0, 1 ); + cancel.draw(); + + fheroes2::validateFadeInAndRender(); + + LocalEvent & le = LocalEvent::Get(); + + while ( le.HandleEvents() ) { + for ( size_t i = 0; i < mapSizeCount; ++i ) { + le.MousePressLeft( buttons[i].area() ) ? buttons[i].drawOnPress() : buttons[i].drawOnRelease(); + + if ( le.MouseClickLeft( buttons[i].area() ) || Game::HotKeyPressEvent( mapSizeHotkeys[i] ) ) { + return mapSizes[i]; + } + + if ( le.MousePressRight( buttons[i].area() ) ) { + std::string mapSize = std::to_string( mapSizes[i] ); + std::string message = _( "Create a map that is %{size} squares wide and %{size} squares high." ); + StringReplace( message, "%{size}", mapSize ); + mapSize += " x " + mapSize; + Dialog::Message( mapSize, message, Font::BIG ); + } + } + + le.MousePressLeft( cancel.area() ) ? cancel.drawOnPress() : cancel.drawOnRelease(); + + if ( le.MouseClickLeft( cancel.area() ) || Game::HotKeyPressEvent( Game::HotKeyEvent::DEFAULT_CANCEL ) ) { + return Maps::ZERO; + } + + if ( le.MousePressRight( cancel.area() ) ) { + Dialog::Message( _( "Cancel" ), _( "Cancel back to the New Map menu." ), Font::BIG ); + } + } + + return Maps::ZERO; + } +} + +namespace Editor +{ + fheroes2::GameMode menuMain() + { + outputEditorMainMenuInTextSupportMode(); + + // Stop all sounds, but not the music + AudioManager::stopSounds(); + + AudioManager::PlayMusicAsync( MUS::MAINMENU, Music::PlaybackMode::RESUME_AND_PLAY_INFINITE ); + + // setup cursor + const CursorRestorer cursorRestorer( true, Cursor::POINTER ); + + fheroes2::drawEditorMainMenuScreen(); + + const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); + + fheroes2::Button newMap( buttonPos.x, buttonPos.y, ICN::BTNEMAIN, 0, 1 ); + fheroes2::Button loadMap( buttonPos.x, buttonPos.y + buttonYStep, ICN::BTNEMAIN, 2, 3 ); + fheroes2::Button cancel( buttonPos.x, buttonPos.y + 5 * buttonYStep, ICN::BUTTON_LARGE_CANCEL, 0, 1 ); + + newMap.draw(); + loadMap.draw(); + cancel.draw(); + + fheroes2::validateFadeInAndRender(); + + LocalEvent & le = LocalEvent::Get(); + + while ( le.HandleEvents() ) { + le.MousePressLeft( newMap.area() ) ? newMap.drawOnPress() : newMap.drawOnRelease(); + le.MousePressLeft( loadMap.area() ) ? loadMap.drawOnPress() : loadMap.drawOnRelease(); + le.MousePressLeft( cancel.area() ) ? cancel.drawOnPress() : cancel.drawOnRelease(); + + if ( le.MouseClickLeft( newMap.area() ) || Game::HotKeyPressEvent( Game::HotKeyEvent::EDITOR_NEW_MAP_MENU ) ) { + return fheroes2::GameMode::EDITOR_NEW_MAP; + } + if ( le.MouseClickLeft( loadMap.area() ) || Game::HotKeyPressEvent( Game::HotKeyEvent::EDITOR_LOAD_MAP_MENU ) ) { + return fheroes2::GameMode::EDITOR_LOAD_MAP; + } + if ( le.MouseClickLeft( cancel.area() ) || Game::HotKeyPressEvent( Game::HotKeyEvent::DEFAULT_CANCEL ) ) { + return fheroes2::GameMode::MAIN_MENU; + } + + if ( le.MousePressRight( newMap.area() ) ) { + Dialog::Message( _( "New Map" ), _( "Create a new map either from scratch or using the random map generator." ), Font::BIG ); + } + else if ( le.MousePressRight( loadMap.area() ) ) { + Dialog::Message( _( "Load Map" ), _( "Load an existing map." ), Font::BIG ); + } + else if ( le.MousePressRight( cancel.area() ) ) { + Dialog::Message( _( "Cancel" ), _( "Cancel back to the main menu." ), Font::BIG ); + } + } + + return fheroes2::GameMode::MAIN_MENU; + } + + fheroes2::GameMode menuNewMap() + { + outputEditorNewMapMenuInTextSupportMode(); + + const CursorRestorer cursorRestorer( true, Cursor::POINTER ); + + fheroes2::drawEditorMainMenuScreen(); + + const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); + + fheroes2::Button scratchMap( buttonPos.x, buttonPos.y, ICN::BTNENEW, 0, 1 ); + fheroes2::Button randomMap( buttonPos.x, buttonPos.y + buttonYStep, ICN::BTNENEW, 2, 3 ); + fheroes2::Button cancel( buttonPos.x, buttonPos.y + 5 * buttonYStep, ICN::BUTTON_LARGE_CANCEL, 0, 1 ); + + scratchMap.draw(); + randomMap.draw(); + cancel.draw(); + + fheroes2::validateFadeInAndRender(); + + LocalEvent & le = LocalEvent::Get(); + + while ( le.HandleEvents() ) { + le.MousePressLeft( scratchMap.area() ) ? scratchMap.drawOnPress() : scratchMap.drawOnRelease(); + le.MousePressLeft( randomMap.area() ) ? randomMap.drawOnPress() : randomMap.drawOnRelease(); + le.MousePressLeft( cancel.area() ) ? cancel.drawOnPress() : cancel.drawOnRelease(); + + if ( le.MouseClickLeft( scratchMap.area() ) ) { + if ( selectMapSize() != Maps::ZERO ) { + showWIPInfo(); + } + return fheroes2::GameMode::EDITOR_NEW_MAP; + } + + if ( le.MouseClickLeft( randomMap.area() ) ) { + if ( selectMapSize() != Maps::ZERO ) { + showWIPInfo(); + } + return fheroes2::GameMode::EDITOR_NEW_MAP; + } + + if ( le.MouseClickLeft( cancel.area() ) || Game::HotKeyPressEvent( Game::HotKeyEvent::DEFAULT_CANCEL ) ) { + return fheroes2::GameMode::EDITOR_MAIN_MENU; + } + + if ( le.MousePressRight( scratchMap.area() ) || Game::HotKeyPressEvent( Game::HotKeyEvent::EDITOR_FROM_SCRATCH_MAP_MENU ) ) { + Dialog::Message( _( "From Scratch" ), _( "Start from scratch with a blank map." ), Font::BIG ); + } + else if ( le.MousePressRight( randomMap.area() ) || Game::HotKeyPressEvent( Game::HotKeyEvent::EDITOR_RANDOM_MAP_MENU ) ) { + Dialog::Message( _( "Random" ), _( "Create a randomly generated map." ), Font::BIG ); + } + else if ( le.MousePressRight( cancel.area() ) || Game::HotKeyPressEvent( Game::HotKeyEvent::DEFAULT_CANCEL ) ) { + Dialog::Message( _( "Cancel" ), _( "Cancel back to the Map Editor main menu." ), Font::BIG ); + } + } + + return fheroes2::GameMode::EDITOR_MAIN_MENU; + } + + fheroes2::GameMode menuLoadMap() + { + const CursorRestorer cursorRestorer( true, Cursor::POINTER ); + + fheroes2::drawEditorMainMenuScreen(); + + fheroes2::validateFadeInAndRender(); + + const MapsFileInfoList lists = Maps::prepareResurrectionMapsFileInfoList(); + if ( lists.empty() ) { + Dialog::Message( _( "Warning" ), _( "No maps available!" ), Font::BIG, Dialog::OK ); + return fheroes2::GameMode::EDITOR_MAIN_MENU; + } + + const Maps::FileInfo * fileInfo = Dialog::SelectScenario( lists ); + + if ( fileInfo ) { + fheroes2::showStandardTextMessage( _( "Warning!" ), "You have selected:\n" + fileInfo->name + "\n But the Map Editor is still in development.", Dialog::OK ); + } + else { + showWIPInfo(); + } + + return fheroes2::GameMode::EDITOR_MAIN_MENU; + } +} +#endif diff --git a/src/fheroes2/game/game_hotkeys.cpp b/src/fheroes2/game/game_hotkeys.cpp index ef43da8bcea..07ab9559078 100644 --- a/src/fheroes2/game/game_hotkeys.cpp +++ b/src/fheroes2/game/game_hotkeys.cpp @@ -174,6 +174,19 @@ namespace hotKeyEventInfo[hotKeyEventToInt( Game::HotKeyEvent::MAIN_MENU_NEW_EXPANSION_CAMPAIGN )] = { HotKeyCategory::MAIN_MENU, gettext_noop( "hotkey|choose the expansion campaign" ), fheroes2::Key::KEY_E }; +#if defined( WITH_DEBUG ) + hotKeyEventInfo[hotKeyEventToInt( Game::HotKeyEvent::EDITOR_MAIN_MENU )] + = { HotKeyCategory::WORLD_MAP, gettext_noop( "hotkey|map editor main menu" ), fheroes2::Key::KEY_E }; + hotKeyEventInfo[hotKeyEventToInt( Game::HotKeyEvent::EDITOR_NEW_MAP_MENU )] + = { HotKeyCategory::WORLD_MAP, gettext_noop( "hotkey|new map menu" ), fheroes2::Key::KEY_N }; + hotKeyEventInfo[hotKeyEventToInt( Game::HotKeyEvent::EDITOR_LOAD_MAP_MENU )] + = { HotKeyCategory::WORLD_MAP, gettext_noop( "hotkey|load map menu" ), fheroes2::Key::KEY_L }; + hotKeyEventInfo[hotKeyEventToInt( Game::HotKeyEvent::EDITOR_FROM_SCRATCH_MAP_MENU )] + = { HotKeyCategory::WORLD_MAP, gettext_noop( "hotkey|new map from scratch" ), fheroes2::Key::KEY_S }; + hotKeyEventInfo[hotKeyEventToInt( Game::HotKeyEvent::EDITOR_RANDOM_MAP_MENU )] + = { HotKeyCategory::WORLD_MAP, gettext_noop( "hotkey|new random map" ), fheroes2::Key::KEY_R }; +#endif + hotKeyEventInfo[hotKeyEventToInt( Game::HotKeyEvent::CAMPAIGN_ROLAND )] = { HotKeyCategory::CAMPAIGN, gettext_noop( "hotkey|roland campaign" ), fheroes2::Key::KEY_1 }; hotKeyEventInfo[hotKeyEventToInt( Game::HotKeyEvent::CAMPAIGN_ARCHIBALD )] diff --git a/src/fheroes2/game/game_hotkeys.h b/src/fheroes2/game/game_hotkeys.h index 320ac04f483..91d7c127003 100644 --- a/src/fheroes2/game/game_hotkeys.h +++ b/src/fheroes2/game/game_hotkeys.h @@ -65,6 +65,15 @@ namespace Game MAIN_MENU_NEW_ORIGINAL_CAMPAIGN, MAIN_MENU_NEW_EXPANSION_CAMPAIGN, +#if defined( WITH_DEBUG ) + // Editor is still in development. + EDITOR_MAIN_MENU, + EDITOR_NEW_MAP_MENU, + EDITOR_LOAD_MAP_MENU, + EDITOR_FROM_SCRATCH_MAP_MENU, + EDITOR_RANDOM_MAP_MENU, +#endif + CAMPAIGN_ROLAND, CAMPAIGN_ARCHIBALD, CAMPAIGN_PRICE_OF_LOYALTY, diff --git a/src/fheroes2/game/game_mainmenu.cpp b/src/fheroes2/game/game_mainmenu.cpp index c1ee0d5e993..f3cdf383814 100644 --- a/src/fheroes2/game/game_mainmenu.cpp +++ b/src/fheroes2/game/game_mainmenu.cpp @@ -38,6 +38,7 @@ #include "dialog_game_settings.h" #include "dialog_language_selection.h" #include "dialog_resolution.h" +#include "editor.h" #include "game.h" #include "game_delays.h" #include "game_hotkeys.h" @@ -173,6 +174,17 @@ void Game::mainGameLoop( bool isFirstGameRun ) result = Game::SelectCampaignScenario( fheroes2::GameMode::LOAD_CAMPAIGN, false ); } break; +#if defined( WITH_DEBUG ) + case fheroes2::GameMode::EDITOR_MAIN_MENU: + result = Editor::menuMain(); + break; + case fheroes2::GameMode::EDITOR_NEW_MAP: + result = Editor::menuNewMap(); + break; + case fheroes2::GameMode::EDITOR_LOAD_MAP: + result = Editor::menuLoadMap(); + break; +#endif default: break; @@ -349,6 +361,12 @@ fheroes2::GameMode Game::MainMenu( bool isFirstGameRun ) return fheroes2::GameMode::MAIN_MENU; } +#if defined( WITH_DEBUG ) + // Editor is still in development. + else if ( HotKeyPressEvent( HotKeyEvent::EDITOR_MAIN_MENU ) ) { + return fheroes2::GameMode::EDITOR_MAIN_MENU; + } +#endif // right info if ( le.MousePressRight( buttonQuit.area() ) ) diff --git a/src/fheroes2/game/game_mainmenu_ui.cpp b/src/fheroes2/game/game_mainmenu_ui.cpp index 76819b16428..92b20ea0b27 100644 --- a/src/fheroes2/game/game_mainmenu_ui.cpp +++ b/src/fheroes2/game/game_mainmenu_ui.cpp @@ -42,7 +42,7 @@ namespace fheroes2::Blit( sprite, 0, 0, output, sprite.x(), sprite.y(), sprite.width(), sprite.height() ); } - void renderWindowBackground( fheroes2::Image & output, const fheroes2::Rect roi ) + void renderWindowBackground( fheroes2::Image & output, const fheroes2::Rect & roi ) { if ( roi.width == 0 || roi.height == 0 ) { // Nothing to render. @@ -72,6 +72,20 @@ namespace offset.y += background.height(); } } + + void fillScreenBorders( fheroes2::Image & output, const fheroes2::Rect & backgroundRoi ) + { + if ( backgroundRoi.y == 0 ) { + renderWindowBackground( output, { 0, 0, backgroundRoi.x, output.height() } ); + renderWindowBackground( output, { backgroundRoi.x + backgroundRoi.width, 0, output.width() - backgroundRoi.x - backgroundRoi.width, output.height() } ); + } + else { + assert( backgroundRoi.x == 0 ); + + renderWindowBackground( output, { 0, 0, output.width(), backgroundRoi.y } ); + renderWindowBackground( output, { 0, backgroundRoi.y + backgroundRoi.height, output.width(), output.height() - backgroundRoi.y - backgroundRoi.height } ); + } + } } namespace fheroes2 @@ -89,18 +103,17 @@ namespace fheroes2 drawSprite( display, ICN::BTNSHNGL, 13 ); drawSprite( display, ICN::BTNSHNGL, 17 ); - if ( mainMenuBackground.y() == 0 ) { - renderWindowBackground( display, { 0, 0, mainMenuBackground.x(), display.height() } ); - renderWindowBackground( display, { mainMenuBackground.x() + mainMenuBackground.width(), 0, - display.width() - mainMenuBackground.x() - mainMenuBackground.width(), display.height() } ); - } - else { - assert( mainMenuBackground.x() == 0 ); + fillScreenBorders( display, { mainMenuBackground.x(), mainMenuBackground.y(), mainMenuBackground.width(), mainMenuBackground.height() } ); + } - renderWindowBackground( display, { 0, 0, display.width(), mainMenuBackground.y() } ); - renderWindowBackground( display, { 0, mainMenuBackground.y() + mainMenuBackground.height(), display.width(), - display.height() - mainMenuBackground.y() - mainMenuBackground.height() } ); - } + void drawEditorMainMenuScreen() + { + Display & display = Display::instance(); + + const Sprite & background = AGG::GetICN( ICN::EDITOR, 0 ); + Copy( background, 0, 0, display, background.x(), background.y(), background.width(), background.height() ); + + fillScreenBorders( display, { background.x(), background.y(), background.width(), background.height() } ); } Point drawButtonPanel() diff --git a/src/fheroes2/game/game_mainmenu_ui.h b/src/fheroes2/game/game_mainmenu_ui.h index 656129a886f..1bac71c6613 100644 --- a/src/fheroes2/game/game_mainmenu_ui.h +++ b/src/fheroes2/game/game_mainmenu_ui.h @@ -25,6 +25,7 @@ namespace fheroes2 { void drawMainMenuScreen(); + void drawEditorMainMenuScreen(); Point drawButtonPanel(); diff --git a/src/fheroes2/game/game_mode.h b/src/fheroes2/game/game_mode.h index 9863f4b834e..c09b2ce3a8c 100644 --- a/src/fheroes2/game/game_mode.h +++ b/src/fheroes2/game/game_mode.h @@ -50,6 +50,9 @@ namespace fheroes2 END_TURN, SELECT_CAMPAIGN_SCENARIO, COMPLETE_CAMPAIGN_SCENARIO, - COMPLETE_CAMPAIGN_SCENARIO_FROM_LOAD_FILE + COMPLETE_CAMPAIGN_SCENARIO_FROM_LOAD_FILE, + EDITOR_MAIN_MENU, + EDITOR_NEW_MAP, + EDITOR_LOAD_MAP }; } diff --git a/src/fheroes2/maps/maps_fileinfo.cpp b/src/fheroes2/maps/maps_fileinfo.cpp index 017eb36f4a5..3c03de7b57b 100644 --- a/src/fheroes2/maps/maps_fileinfo.cpp +++ b/src/fheroes2/maps/maps_fileinfo.cpp @@ -638,3 +638,38 @@ MapsFileInfoList Maps::PrepareMapsFileInfoList( const bool multi ) return result; } + +MapsFileInfoList Maps::prepareResurrectionMapsFileInfoList() +{ + // TODO: set the proper resurrection map extension. + const ListFiles maps = Settings::FindFiles( "maps", ".mpr", false ); + + // Create a list of unique maps (based on the map file name). + std::map uniqueMaps; + + for ( const std::string & mapFile : maps ) { + Maps::FileInfo fi; + + // These are test data values. + // TODO: make a function to read resurrection map info data and remove the test values. + fi.width = 36; + fi.height = 36; + fi.name = "Test name"; + fi.description = "Resurrection map test description.\nThe Map Editor is currently in development."; + fi.difficulty = 3; + + uniqueMaps[System::GetBasename( mapFile )] = fi; + } + + MapsFileInfoList result; + + result.reserve( uniqueMaps.size() ); + + for ( const auto & item : uniqueMaps ) { + result.push_back( item.second ); + } + + std::sort( result.begin(), result.end(), Maps::FileInfo::NameSorting ); + + return result; +} diff --git a/src/fheroes2/maps/maps_fileinfo.h b/src/fheroes2/maps/maps_fileinfo.h index 1bc2c9716f5..6cbd66a9674 100644 --- a/src/fheroes2/maps/maps_fileinfo.h +++ b/src/fheroes2/maps/maps_fileinfo.h @@ -196,6 +196,9 @@ using MapsFileInfoList = std::vector; namespace Maps { MapsFileInfoList PrepareMapsFileInfoList( const bool multi ); + + // Creates the list of fheroes2 Resurrection map files. + MapsFileInfoList prepareResurrectionMapsFileInfoList(); } #endif