Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Editor Main Menu #7241

Merged
merged 16 commits into from
May 30, 2023
Merged
1 change: 1 addition & 0 deletions VisualStudio/fheroes2/sources.props
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
<ClCompile Include="src\fheroes2\game\game_campaign.cpp" />
<ClCompile Include="src\fheroes2\game\game_credits.cpp" />
<ClCompile Include="src\fheroes2\game\game_delays.cpp" />
<ClCompile Include="src\fheroes2\game\game_editor_mainmenu.cpp" />
<ClCompile Include="src\fheroes2\game\game_highscores.cpp" />
<ClCompile Include="src\fheroes2\game\game_hotkeys.cpp" />
<ClCompile Include="src\fheroes2\game\game_interface.cpp" />
Expand Down
10 changes: 9 additions & 1 deletion src/fheroes2/agg/agg_image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2635,6 +2635,14 @@ 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();
fheroes2::ApplyPalette( _icnVsSprite[id][0], PAL::GetPalette( PAL::PaletteType::NO_CYCLE ) );
}
return true;
case ICN::HEROES:
LoadOriginalICN( id );
if ( !_icnVsSprite[id].empty() ) {
Expand Down Expand Up @@ -3672,7 +3680,7 @@ 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;
return id == ICN::EDITOR || id == ICN::HEROES || id == ICN::BTNSHNGL || id == ICN::SHNGANIM;
}

const Sprite & GetScaledICN( const int icnId, const uint32_t index )
Expand Down
4 changes: 4 additions & 0 deletions src/fheroes2/game/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ namespace Game
fheroes2::GameMode CompleteCampaignScenario( const bool isLoadingSaveFile );
fheroes2::GameMode DisplayHighScores( const bool isCampaign );

fheroes2::GameMode editorMainMenu();
fheroes2::GameMode editorNewMap();
fheroes2::GameMode editorLoadMap();

bool isSuccessionWarsCampaignPresent();
bool isPriceOfLoyaltyCampaignPresent();

Expand Down
174 changes: 174 additions & 0 deletions src/fheroes2/game/game_editor_mainmenu.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
/***************************************************************************
* fheroes2: https://github.com/ihhub/fheroes2 *
* Copyright (C) 2023 *
* *
* Free Heroes2 Engine: http://sourceforge.net/projects/fheroes2 *
* Copyright (C) 2009 by Andrey Afletdinov <fheroes2@gmail.com> *
* *
* 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. *
***************************************************************************/

#include <cstddef>
#include <cstdint>
#include <memory>
#include <vector>

#include "audio.h"
#include "audio_manager.h"
#include "cursor.h"
#include "dialog.h"
#include "game.h"
#include "game_hotkeys.h"
#include "game_mainmenu_ui.h"
#include "game_mode.h"
#include "icn.h"
#include "localevent.h"
#include "math_base.h"
#include "mus.h"
#include "text.h"
#include "translations.h"
#include "ui_button.h"
#include "ui_dialog.h"
#include "ui_text.h"

namespace
{
const int32_t buttonYStep = 66;

void showWIPInfo()
{
fheroes2::showMessage( fheroes2::Text{ _( "Warning!" ), fheroes2::FontType::normalYellow() },
fheroes2::Text{ "The Map Editor is still in WIP. This function is not available yet.", fheroes2::FontType::normalWhite() }, Dialog::OK );
}

}

fheroes2::GameMode Game::editorMainMenu()
{
// 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() ) || HotKeyPressEvent( HotKeyEvent::MAIN_MENU_STANDARD ) ) {
return fheroes2::GameMode::EDITOR_NEW_MAP;
}
else if ( le.MouseClickLeft( loadMap.area() ) || HotKeyPressEvent( HotKeyEvent::MAIN_MENU_CAMPAIGN ) ) {
return fheroes2::GameMode::EDITOR_LOAD_MAP;
}
else if ( le.MouseClickLeft( cancel.area() ) || HotKeyPressEvent( 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 Game::editorNewMap()
{
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() ) || HotKeyPressEvent( HotKeyEvent::MAIN_MENU_STANDARD ) ) {
showWIPInfo();
}
else if ( le.MouseClickLeft( randomMap.area() ) || HotKeyPressEvent( HotKeyEvent::MAIN_MENU_CAMPAIGN ) ) {
showWIPInfo();
}
else if ( le.MouseClickLeft( cancel.area() ) || HotKeyPressEvent( HotKeyEvent::DEFAULT_CANCEL ) ) {
return fheroes2::GameMode::EDITOR_MAIN_MENU;
}

if ( le.MousePressRight( scratchMap.area() ) ) {
Dialog::Message( _( "From Scratch" ), _( "Start from scratch with a blank map." ), Font::BIG );
}
else if ( le.MousePressRight( randomMap.area() ) ) {
Dialog::Message( _( "Random" ), _( "Create a randomly generated map." ), Font::BIG );
}
else if ( le.MousePressRight( cancel.area() ) ) {
Dialog::Message( _( "Cancel" ), _( "Cancel back to the main menu." ), Font::BIG );
}
}

return fheroes2::GameMode::EDITOR_MAIN_MENU;
}

fheroes2::GameMode Game::editorLoadMap()
{
const CursorRestorer cursorRestorer( true, Cursor::POINTER );

fheroes2::drawEditorMainMenuScreen();

fheroes2::validateFadeInAndRender();

showWIPInfo();

return fheroes2::GameMode::EDITOR_MAIN_MENU;
}
5 changes: 5 additions & 0 deletions src/fheroes2/game/game_hotkeys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,11 @@ 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 };
#endif

hotKeyEventInfo[hotKeyEventToInt( Game::HotKeyEvent::CAMPAIGN_ROLAND )]
= { HotKeyCategory::CAMPAIGN, gettext_noop( "hotkey|roland campaign" ), fheroes2::Key::KEY_1 };
hotKeyEventInfo[hotKeyEventToInt( Game::HotKeyEvent::CAMPAIGN_ARCHIBALD )]
Expand Down
2 changes: 2 additions & 0 deletions src/fheroes2/game/game_hotkeys.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ namespace Game
MAIN_MENU_NEW_ORIGINAL_CAMPAIGN,
MAIN_MENU_NEW_EXPANSION_CAMPAIGN,

EDITOR_MAIN_MENU,

CAMPAIGN_ROLAND,
CAMPAIGN_ARCHIBALD,
CAMPAIGN_PRICE_OF_LOYALTY,
Expand Down
12 changes: 12 additions & 0 deletions src/fheroes2/game/game_mainmenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,15 @@ void Game::mainGameLoop( bool isFirstGameRun )
result = Game::SelectCampaignScenario( fheroes2::GameMode::LOAD_CAMPAIGN, false );
}
break;
case fheroes2::GameMode::EDITOR_MAIN_MENU:
result = Game::editorMainMenu();
break;
case fheroes2::GameMode::EDITOR_NEW_MAP:
result = Game::editorNewMap();
break;
case fheroes2::GameMode::EDITOR_LOAD_MAP:
result = Game::editorLoadMap();
break;

default:
break;
Expand Down Expand Up @@ -349,6 +358,9 @@ fheroes2::GameMode Game::MainMenu( bool isFirstGameRun )

return fheroes2::GameMode::MAIN_MENU;
}
else if ( HotKeyPressEvent( HotKeyEvent::EDITOR_MAIN_MENU ) ) {
return fheroes2::GameMode::EDITOR_MAIN_MENU;
}

// right info
if ( le.MousePressRight( buttonQuit.area() ) )
Expand Down
37 changes: 25 additions & 12 deletions src/fheroes2/game/game_mainmenu_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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()
Expand Down
1 change: 1 addition & 0 deletions src/fheroes2/game/game_mainmenu_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
namespace fheroes2
{
void drawMainMenuScreen();
void drawEditorMainMenuScreen();

Point drawButtonPanel();

Expand Down
5 changes: 4 additions & 1 deletion src/fheroes2/game/game_mode.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
};
}