From 66d607e68f44af26b9ae8a83d8fe57e18500d99e Mon Sep 17 00:00:00 2001 From: Zenseii Date: Mon, 3 Feb 2025 17:10:22 +0100 Subject: [PATCH 01/54] Add height dimension to customNormalButton --- src/fheroes2/agg/agg_image.cpp | 7 +- src/fheroes2/dialog/dialog_selectcount.cpp | 6 +- src/fheroes2/dialog/dialog_selectfile.cpp | 2 +- .../editor/editor_save_map_window.cpp | 2 +- src/fheroes2/gui/ui_button.cpp | 33 +++++---- src/fheroes2/gui/ui_button.h | 4 +- src/fheroes2/gui/ui_keyboard.cpp | 70 +++++++++---------- src/fheroes2/gui/ui_window.cpp | 4 +- src/fheroes2/gui/ui_window.h | 2 +- 9 files changed, 67 insertions(+), 63 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index be37c5ca394..6eda8f6e5cb 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -422,15 +422,16 @@ namespace pressedText.draw( pressedTextOffset.x, pressedTextOffset.y + ( buttonSize.height - pressedTextSize.height ) / 2, buttonSize.width, pressedState ); } - void createNormalButton( fheroes2::Sprite & released, fheroes2::Sprite & pressed, int32_t textWidth, const char * text, const bool isEvilInterface ) + void createNormalButton( fheroes2::Sprite & released, fheroes2::Sprite & pressed, int32_t buttonWidth, const char * text, const bool isEvilInterface, + int32_t buttonHeight = 25 ) { fheroes2::Point releasedOffset; fheroes2::Point pressedOffset; - fheroes2::getCustomNormalButton( released, pressed, isEvilInterface, textWidth, releasedOffset, pressedOffset ); + fheroes2::getCustomNormalButton( released, pressed, isEvilInterface, { buttonWidth, buttonHeight }, releasedOffset, pressedOffset ); const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( released, pressed, text, releasedOffset, pressedOffset, { textWidth, fheroes2::getFontHeight( fheroes2::FontSize::BUTTON_RELEASED ) }, + renderTextOnButton( released, pressed, text, releasedOffset, pressedOffset, { buttonWidth, fheroes2::getFontHeight( fheroes2::FontSize::BUTTON_RELEASED ) }, buttonFontColor ); } diff --git a/src/fheroes2/dialog/dialog_selectcount.cpp b/src/fheroes2/dialog/dialog_selectcount.cpp index d6b0ccdacaa..1a99b476a81 100644 --- a/src/fheroes2/dialog/dialog_selectcount.cpp +++ b/src/fheroes2/dialog/dialog_selectcount.cpp @@ -232,11 +232,11 @@ bool Dialog::inputString( const fheroes2::TextBase & title, const fheroes2::Text // Generate a button to open the Virtual Keyboard window. fheroes2::Sprite releasedVirtualKB; fheroes2::Sprite pressedVirtualKB; - const int32_t buttonVirtualKBWidth = 40; + const fheroes2::Size buttonVirtualKBSize{ 40, 25 }; - makeButtonSprites( releasedVirtualKB, pressedVirtualKB, "...", buttonVirtualKBWidth, isEvilInterface, true ); + makeButtonSprites( releasedVirtualKB, pressedVirtualKB, "...", buttonVirtualKBSize, isEvilInterface, true ); // To center the button horizontally we have to take into account that actual button sprite is 10 pixels longer then the requested button width. - fheroes2::ButtonSprite buttonVirtualKB = makeButtonWithBackground( frameBoxArea.x + ( frameBoxArea.width - buttonVirtualKBWidth - 10 ) / 2, dst_pt.y - 30, + fheroes2::ButtonSprite buttonVirtualKB = makeButtonWithBackground( frameBoxArea.x + ( frameBoxArea.width - buttonVirtualKBSize.width - 10 ) / 2, dst_pt.y - 30, releasedVirtualKB, pressedVirtualKB, display ); if ( result.empty() ) { diff --git a/src/fheroes2/dialog/dialog_selectfile.cpp b/src/fheroes2/dialog/dialog_selectfile.cpp index 79f7594a23b..01612804665 100644 --- a/src/fheroes2/dialog/dialog_selectfile.cpp +++ b/src/fheroes2/dialog/dialog_selectfile.cpp @@ -376,7 +376,7 @@ namespace if ( isEditing ) { // Render a button to open the Virtual Keyboard window. buttonVirtualKB = std::make_unique(); - background.renderButtonSprite( *buttonVirtualKB, "...", 48, { 0, 7 }, isEvilInterface, fheroes2::StandardWindow::Padding::BOTTOM_CENTER ); + background.renderButtonSprite( *buttonVirtualKB, "...", { 48, 25 }, { 0, 7 }, isEvilInterface, fheroes2::StandardWindow::Padding::BOTTOM_CENTER ); Game::passAnimationDelay( Game::DelayType::CURSOR_BLINK_DELAY ); } diff --git a/src/fheroes2/editor/editor_save_map_window.cpp b/src/fheroes2/editor/editor_save_map_window.cpp index 84a29028bfc..2a416b883ff 100644 --- a/src/fheroes2/editor/editor_save_map_window.cpp +++ b/src/fheroes2/editor/editor_save_map_window.cpp @@ -312,7 +312,7 @@ namespace Editor // Render a button to open the Virtual Keyboard window. fheroes2::ButtonSprite buttonVirtualKB; - background.renderButtonSprite( buttonVirtualKB, "...", 48, { 0, 7 }, isEvilInterface, fheroes2::StandardWindow::Padding::BOTTOM_CENTER ); + background.renderButtonSprite( buttonVirtualKB, "...", { 48, 25 }, { 0, 7 }, isEvilInterface, fheroes2::StandardWindow::Padding::BOTTOM_CENTER ); Game::passAnimationDelay( Game::DelayType::CURSOR_BLINK_DELAY ); diff --git a/src/fheroes2/gui/ui_button.cpp b/src/fheroes2/gui/ui_button.cpp index 4576c9bd9d3..cc16e3e23c8 100644 --- a/src/fheroes2/gui/ui_button.cpp +++ b/src/fheroes2/gui/ui_button.cpp @@ -716,27 +716,32 @@ namespace fheroes2 std::move( disabledWithBackground ) }; } - void getCustomNormalButton( Sprite & released, Sprite & pressed, const bool isEvilInterface, int32_t width, Point & releasedOffset, Point & pressedOffset, + void getCustomNormalButton( Sprite & released, Sprite & pressed, const bool isEvilInterface, fheroes2::Size buttonSize, Point & releasedOffset, Point & pressedOffset, const bool isTransparentBackground /* = false */ ) { - assert( width > 0 ); + assert( buttonSize.width > 0 && buttonSize.height > 0 ); releasedOffset = { 7, 5 }; pressedOffset = { 6, 6 }; - // The actual button sprite is 10 pixels longer. - width += 10; + // The actual button sprite is 10 pixels wider. + buttonSize.width += 10; + + const int32_t minimumButtonWidth = 16; + const int32_t maximumButtonWidth = 200; // Why is such a wide button needed? + buttonSize.width = std::clamp( buttonSize.width, minimumButtonWidth, maximumButtonWidth ); + + const int32_t minimumButtonHeight = 25; + const int32_t maximumButtonHeight = 200; // Why is such a wide button needed? + buttonSize.height = std::clamp( buttonSize.height, minimumButtonHeight, maximumButtonHeight ); const int32_t icnId = isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON; - const int32_t minimumButtonSize = 16; - const int32_t maximumButtonSize = 200; // Why is such a wide button needed? - width = std::clamp( width, minimumButtonSize, maximumButtonSize ); const Sprite & originalReleased = AGG::GetICN( icnId, 0 ); const Sprite & originalPressed = AGG::GetICN( icnId, 1 ); - released = resizeButton( originalReleased, { width, originalReleased.height() } ); - pressed = resizeButton( originalPressed, { width, originalPressed.height() } ); + released = resizeButton( originalReleased, buttonSize ); + pressed = resizeButton( originalPressed, buttonSize ); addButtonShine( released, icnId ); @@ -809,21 +814,19 @@ namespace fheroes2 pressedText.draw( pressedOffset.x + 1, pressedOffset.y + ( textAreaHeight - pressedTextSize.height ) / 2, textAreaWidth, pressed ); } - void makeButtonSprites( Sprite & released, Sprite & pressed, const std::string & text, const int32_t buttonWidth, const bool isEvilInterface, + void makeButtonSprites( Sprite & released, Sprite & pressed, const std::string & text, const fheroes2::Size buttonSize, const bool isEvilInterface, const bool isTransparentBackground ) { fheroes2::Point releasedOffset; fheroes2::Point pressedOffset; - fheroes2::getCustomNormalButton( released, pressed, isEvilInterface, buttonWidth, releasedOffset, pressedOffset, isTransparentBackground ); + fheroes2::getCustomNormalButton( released, pressed, isEvilInterface, buttonSize, releasedOffset, pressedOffset, isTransparentBackground ); const fheroes2::FontColor fontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; const fheroes2::Text releasedText( text, { fheroes2::FontSize::BUTTON_RELEASED, fontColor } ); const fheroes2::Text pressedText( text, { fheroes2::FontSize::BUTTON_PRESSED, fontColor } ); - const fheroes2::Point textOffset{ ( buttonWidth - releasedText.width() ) / 2, ( 16 - fheroes2::getFontHeight( fheroes2::FontSize::NORMAL ) ) / 2 }; - - releasedText.draw( releasedOffset.x + textOffset.x, releasedOffset.y + textOffset.y, released ); - pressedText.draw( pressedOffset.x + textOffset.x, pressedOffset.y + textOffset.y, pressed ); + releasedText.draw( releasedOffset.x, ( buttonSize.height - releasedText.height( buttonSize.width ) ) / 2, buttonSize.width, released ); + pressedText.draw( pressedOffset.x, ( buttonSize.height - pressedText.height( buttonSize.width ) ) / 2, buttonSize.width, pressed ); } } diff --git a/src/fheroes2/gui/ui_button.h b/src/fheroes2/gui/ui_button.h index f0ee5667ab8..250a871cec1 100644 --- a/src/fheroes2/gui/ui_button.h +++ b/src/fheroes2/gui/ui_button.h @@ -348,13 +348,13 @@ namespace fheroes2 // The height of text area is only 16 pixels. If 'isTransparentBackground' is set to false the button sprite will have a default background pattern from // STONEBAK or STONEBAK_EVIL (for Evil interface). The pattern is the same for all buttons. - void getCustomNormalButton( Sprite & released, Sprite & pressed, const bool isEvilInterface, int32_t width, Point & releasedOffset, Point & pressedOffset, + void getCustomNormalButton( Sprite & released, Sprite & pressed, const bool isEvilInterface, fheroes2::Size buttonSize, Point & releasedOffset, Point & pressedOffset, const bool isTransparentBackground = false ); // Makes a button that has the width necessary to fit a provided text using an empty button template void getTextAdaptedButton( Sprite & released, Sprite & pressed, const char * text, const int icnId, const int buttonBackgroundIcnID ); // Generate released and pressed button sprites with the text on it over a transparent or a default (STONEBAK/STONEBAK_EVIL) background. - void makeButtonSprites( Sprite & released, Sprite & pressed, const std::string & text, const int32_t buttonWidth, const bool isEvilInterface, + void makeButtonSprites( Sprite & released, Sprite & pressed, const std::string & text, const fheroes2::Size buttonSize, const bool isEvilInterface, const bool isTransparentBackground ); } diff --git a/src/fheroes2/gui/ui_keyboard.cpp b/src/fheroes2/gui/ui_keyboard.cpp index 7617743e561..d20a941ae36 100644 --- a/src/fheroes2/gui/ui_keyboard.cpp +++ b/src/fheroes2/gui/ui_keyboard.cpp @@ -55,8 +55,8 @@ namespace { const int32_t buttonOffset{ 8 }; const int32_t defaultButtonHeight{ 25 }; - const int32_t defaultSpecialButtonWidth{ 54 }; - const int32_t spacebarButtonWidth{ 175 }; + const fheroes2::Size defaultSpecialButtonSize{ 54, defaultButtonHeight }; + const fheroes2::Size spacebarButtonSize{ 175, defaultButtonHeight }; const int32_t defaultWindowWidth{ 520 }; const int32_t numpadWindowWidth{ 320 }; const int32_t defaultWindowHeight{ 250 }; @@ -278,13 +278,13 @@ namespace { KeyboardButton() = default; - KeyboardButton( std::string input, const int32_t buttonWidth, const bool isEvilInterface, std::function actionEvent ) + KeyboardButton( std::string input, const fheroes2::Size buttonSize, const bool isEvilInterface, std::function actionEvent ) : text( std::move( input ) ) , action( std::move( actionEvent ) ) { fheroes2::Sprite released; fheroes2::Sprite pressed; - makeButtonSprites( released, pressed, text, buttonWidth, isEvilInterface, false ); + makeButtonSprites( released, pressed, text, buttonSize, isEvilInterface, false ); button.setSprite( released, pressed ); // Make Image with shadow for button to Blit it during render. @@ -420,7 +420,7 @@ namespace } } - int32_t getDefaultButtonWidth( const fheroes2::SupportedLanguage language ) + fheroes2::Size getDefaultButtonSize( const fheroes2::SupportedLanguage language ) { // Different languages have different number of letters per row. // We cannot expand the virtual keyboard window beyond 640 pixels but we can change the size of buttons. @@ -428,12 +428,12 @@ namespace case fheroes2::SupportedLanguage::Czech: case fheroes2::SupportedLanguage::English: case fheroes2::SupportedLanguage::Polish: - return 30; + return { 30, defaultButtonHeight }; case fheroes2::SupportedLanguage::Belarusian: case fheroes2::SupportedLanguage::Russian: case fheroes2::SupportedLanguage::Slovak: case fheroes2::SupportedLanguage::Ukrainian: - return 24; + return { 24, defaultButtonHeight }; default: // Did you add a new supported language? Add the value above! assert( 0 ); @@ -454,13 +454,13 @@ namespace std::vector> buttons; buttons.resize( buttonLetters.size() ); - const int32_t buttonWidth - = ( layoutType == LayoutType::AlphaNumeric ) ? getDefaultButtonWidth( fheroes2::SupportedLanguage::English ) : getDefaultButtonWidth( language ); + const fheroes2::Size buttonSize + = ( layoutType == LayoutType::AlphaNumeric ) ? getDefaultButtonSize( fheroes2::SupportedLanguage::English ) : getDefaultButtonSize( language ); for ( size_t i = 0; i < buttonLetters.size(); ++i ) { assert( buttonLetters[i].size() == returnLetters[i].size() ); for ( size_t buttonId = 0; buttonId < buttonLetters[i].size(); ++buttonId ) { - buttons[i].emplace_back( std::string( 1, buttonLetters[i][buttonId] ), buttonWidth, isEvilInterface, + buttons[i].emplace_back( std::string( 1, buttonLetters[i][buttonId] ), buttonSize, isEvilInterface, [letter = returnLetters[i][buttonId]]( KeyboardRenderer & renderer ) { renderer.insertCharacter( letter ); return DialogAction::AddLetter; @@ -478,109 +478,109 @@ namespace switch ( layoutType ) { case LayoutType::LowerCase: - lastButtonRow.emplace_back( "|", defaultSpecialButtonWidth, isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::UpperCase; } ); + lastButtonRow.emplace_back( "|", defaultSpecialButtonSize, isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::UpperCase; } ); - lastButtonRow.emplace_back( _( "Keyboard|123" ), defaultSpecialButtonWidth, isEvilInterface, + lastButtonRow.emplace_back( _( "Keyboard|123" ), defaultSpecialButtonSize, isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::AlphaNumeric; } ); - lastButtonRow.emplace_back( _( "Keyboard|SPACE" ), spacebarButtonWidth, isEvilInterface, []( KeyboardRenderer & renderer ) { + lastButtonRow.emplace_back( _( "Keyboard|SPACE" ), spacebarButtonSize, isEvilInterface, []( KeyboardRenderer & renderer ) { renderer.insertCharacter( ' ' ); return DialogAction::AddLetter; } ); - lastButtonRow.emplace_back( "\x7F", defaultSpecialButtonWidth, isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::ChangeLanguage; } ); + lastButtonRow.emplace_back( "\x7F", defaultSpecialButtonSize, isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::ChangeLanguage; } ); if ( !isExtraLanguageSupported ) { lastButtonRow.back().button.hide(); } - lastButtonRow.emplace_back( "~", defaultSpecialButtonWidth, isEvilInterface, []( KeyboardRenderer & renderer ) { + lastButtonRow.emplace_back( "~", defaultSpecialButtonSize, isEvilInterface, []( KeyboardRenderer & renderer ) { renderer.removeCharacter(); return DialogAction::Backspace; } ); break; case LayoutType::UpperCase: - lastButtonRow.emplace_back( "|", defaultSpecialButtonWidth, isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::LowerCase; } ); + lastButtonRow.emplace_back( "|", defaultSpecialButtonSize, isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::LowerCase; } ); lastButtonRow.back().isInvertedRenderingLogic = true; - lastButtonRow.emplace_back( _( "Keyboard|123" ), defaultSpecialButtonWidth, isEvilInterface, + lastButtonRow.emplace_back( _( "Keyboard|123" ), defaultSpecialButtonSize, isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::AlphaNumeric; } ); - lastButtonRow.emplace_back( _( "Keyboard|SPACE" ), spacebarButtonWidth, isEvilInterface, []( KeyboardRenderer & renderer ) { + lastButtonRow.emplace_back( _( "Keyboard|SPACE" ), spacebarButtonSize, isEvilInterface, []( KeyboardRenderer & renderer ) { renderer.insertCharacter( ' ' ); return DialogAction::AddLetter; } ); - lastButtonRow.emplace_back( "\x7F", defaultSpecialButtonWidth, isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::ChangeLanguage; } ); + lastButtonRow.emplace_back( "\x7F", defaultSpecialButtonSize, isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::ChangeLanguage; } ); if ( !isExtraLanguageSupported ) { lastButtonRow.back().button.hide(); } - lastButtonRow.emplace_back( "~", defaultSpecialButtonWidth, isEvilInterface, []( KeyboardRenderer & renderer ) { + lastButtonRow.emplace_back( "~", defaultSpecialButtonSize, isEvilInterface, []( KeyboardRenderer & renderer ) { renderer.removeCharacter(); return DialogAction::Backspace; } ); break; case LayoutType::AlphaNumeric: - lastButtonRow.emplace_back( "|", defaultSpecialButtonWidth, isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::DoNothing; } ); + lastButtonRow.emplace_back( "|", defaultSpecialButtonSize, isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::DoNothing; } ); lastButtonRow.back().button.hide(); - lastButtonRow.emplace_back( _( "Keyboard|ABC" ), defaultSpecialButtonWidth, isEvilInterface, + lastButtonRow.emplace_back( _( "Keyboard|ABC" ), defaultSpecialButtonSize, isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::LowerCase; } ); - lastButtonRow.emplace_back( _( "Keyboard|SPACE" ), spacebarButtonWidth, isEvilInterface, []( KeyboardRenderer & renderer ) { + lastButtonRow.emplace_back( _( "Keyboard|SPACE" ), spacebarButtonSize, isEvilInterface, []( KeyboardRenderer & renderer ) { renderer.insertCharacter( ' ' ); return DialogAction::AddLetter; } ); - lastButtonRow.emplace_back( "\x7F", defaultSpecialButtonWidth, isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::ChangeLanguage; } ); + lastButtonRow.emplace_back( "\x7F", defaultSpecialButtonSize, isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::ChangeLanguage; } ); lastButtonRow.back().button.hide(); - lastButtonRow.emplace_back( "~", defaultSpecialButtonWidth, isEvilInterface, []( KeyboardRenderer & renderer ) { + lastButtonRow.emplace_back( "~", defaultSpecialButtonSize, isEvilInterface, []( KeyboardRenderer & renderer ) { renderer.removeCharacter(); return DialogAction::Backspace; } ); break; case LayoutType::SignedNumeric: - lastButtonRow.emplace_back( "|", defaultSpecialButtonWidth, isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::DoNothing; } ); + lastButtonRow.emplace_back( "|", defaultSpecialButtonSize, isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::DoNothing; } ); lastButtonRow.back().button.hide(); - lastButtonRow.emplace_back( "-", getDefaultButtonWidth( fheroes2::SupportedLanguage::English ), isEvilInterface, []( KeyboardRenderer & renderer ) { + lastButtonRow.emplace_back( "-", getDefaultButtonSize( fheroes2::SupportedLanguage::English ), isEvilInterface, []( KeyboardRenderer & renderer ) { renderer.swapSign(); return DialogAction::AddLetter; } ); - lastButtonRow.emplace_back( "0", getDefaultButtonWidth( fheroes2::SupportedLanguage::English ), isEvilInterface, []( KeyboardRenderer & renderer ) { + lastButtonRow.emplace_back( "0", getDefaultButtonSize( fheroes2::SupportedLanguage::English ), isEvilInterface, []( KeyboardRenderer & renderer ) { renderer.insertCharacter( '0' ); return DialogAction::AddLetter; } ); - lastButtonRow.emplace_back( "\x7F", getDefaultButtonWidth( fheroes2::SupportedLanguage::English ), isEvilInterface, + lastButtonRow.emplace_back( "\x7F", getDefaultButtonSize( fheroes2::SupportedLanguage::English ), isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::ChangeLanguage; } ); lastButtonRow.back().button.hide(); - lastButtonRow.emplace_back( "~", defaultSpecialButtonWidth, isEvilInterface, []( KeyboardRenderer & renderer ) { + lastButtonRow.emplace_back( "~", defaultSpecialButtonSize, isEvilInterface, []( KeyboardRenderer & renderer ) { renderer.removeCharacter(); return DialogAction::Backspace; } ); break; case LayoutType::UnsignedNumeric: - lastButtonRow.emplace_back( "|", defaultSpecialButtonWidth, isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::DoNothing; } ); + lastButtonRow.emplace_back( "|", defaultSpecialButtonSize, isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::DoNothing; } ); lastButtonRow.back().button.hide(); - lastButtonRow.emplace_back( "-", getDefaultButtonWidth( fheroes2::SupportedLanguage::English ), isEvilInterface, + lastButtonRow.emplace_back( "-", getDefaultButtonSize( fheroes2::SupportedLanguage::English ), isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::DoNothing; } ); lastButtonRow.back().button.hide(); - lastButtonRow.emplace_back( "0", getDefaultButtonWidth( fheroes2::SupportedLanguage::English ), isEvilInterface, []( KeyboardRenderer & renderer ) { + lastButtonRow.emplace_back( "0", getDefaultButtonSize( fheroes2::SupportedLanguage::English ), isEvilInterface, []( KeyboardRenderer & renderer ) { renderer.insertCharacter( '0' ); return DialogAction::AddLetter; } ); - lastButtonRow.emplace_back( "\x7F", getDefaultButtonWidth( fheroes2::SupportedLanguage::English ), isEvilInterface, + lastButtonRow.emplace_back( "\x7F", getDefaultButtonSize( fheroes2::SupportedLanguage::English ), isEvilInterface, []( const KeyboardRenderer & ) { return DialogAction::ChangeLanguage; } ); lastButtonRow.back().button.hide(); - lastButtonRow.emplace_back( "~", defaultSpecialButtonWidth, isEvilInterface, []( KeyboardRenderer & renderer ) { + lastButtonRow.emplace_back( "~", defaultSpecialButtonSize, isEvilInterface, []( KeyboardRenderer & renderer ) { renderer.removeCharacter(); return DialogAction::Backspace; } ); diff --git a/src/fheroes2/gui/ui_window.cpp b/src/fheroes2/gui/ui_window.cpp index b291d44bc1e..0d7a1139053 100644 --- a/src/fheroes2/gui/ui_window.cpp +++ b/src/fheroes2/gui/ui_window.cpp @@ -343,13 +343,13 @@ namespace fheroes2 } } - void StandardWindow::renderButtonSprite( ButtonSprite & button, const std::string & buttonText, const int32_t buttonWidth, const Point & offset, + void StandardWindow::renderButtonSprite( ButtonSprite & button, const std::string & buttonText, const fheroes2::Size buttonSize, const Point & offset, const bool isEvilInterface, const Padding padding ) { Sprite released; Sprite pressed; - makeButtonSprites( released, pressed, buttonText, buttonWidth, isEvilInterface, false ); + makeButtonSprites( released, pressed, buttonText, buttonSize, isEvilInterface, false ); const Point pos = _getRenderPos( offset, { released.width(), released.height() }, padding ); diff --git a/src/fheroes2/gui/ui_window.h b/src/fheroes2/gui/ui_window.h index 15c3e152e42..54931d0ed32 100644 --- a/src/fheroes2/gui/ui_window.h +++ b/src/fheroes2/gui/ui_window.h @@ -85,7 +85,7 @@ namespace fheroes2 void renderScrollbarBackground( const Rect & roi, const bool isEvilInterface ); - void renderButtonSprite( ButtonSprite & button, const std::string & buttonText, const int32_t buttonWidth, const Point & offset, const bool isEvilInterface, + void renderButtonSprite( ButtonSprite & button, const std::string & buttonText, const fheroes2::Size buttonSize, const Point & offset, const bool isEvilInterface, const Padding padding ); void renderButton( Button & button, const int icnId, const uint32_t releasedIndex, const uint32_t pressedIndex, const Point & offset, const Padding padding ); void renderOkayCancelButtons( Button & buttonOk, Button & buttonCancel, const bool isEvilInterface ); From 841894d9959e8e8870b7dc20f7caea70748be9ba Mon Sep 17 00:00:00 2001 From: Zenseii Date: Mon, 3 Feb 2025 22:31:15 +0100 Subject: [PATCH 02/54] First pass of adjusting to changes --- src/fheroes2/agg/agg_image.cpp | 565 ++++++++++++---------------- src/fheroes2/agg/icn.h | 1 - src/fheroes2/game/game_loadgame.cpp | 29 +- src/fheroes2/game/game_newgame.cpp | 58 ++- 4 files changed, 301 insertions(+), 352 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 6eda8f6e5cb..9b008e33630 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -180,7 +180,6 @@ namespace ICN::BUTTON_HSCORES_VERTICAL_EXIT, ICN::BUTTON_HSCORES_VERTICAL_STANDARD, ICN::DISMISS_HERO_DISABLED_BUTTON, - ICN::NEW_CAMPAIGN_DISABLED_BUTTON, ICN::BUTTON_RUMORS_GOOD, ICN::BUTTON_RUMORS_EVIL, ICN::BUTTON_EVENTS_GOOD, @@ -418,11 +417,11 @@ namespace const fheroes2::Size releasedTextSize( releasedText.width( buttonSize.width ), releasedText.height( buttonSize.width ) ); const fheroes2::Size pressedTextSize( pressedText.width( buttonSize.width ), pressedText.height( buttonSize.width ) ); - releasedText.draw( releasedTextOffset.x, releasedTextOffset.y + ( buttonSize.height - releasedTextSize.height ) / 2, buttonSize.width, releasedState ); - pressedText.draw( pressedTextOffset.x, pressedTextOffset.y + ( buttonSize.height - pressedTextSize.height ) / 2, buttonSize.width, pressedState ); + releasedText.draw( releasedTextOffset.x, ( buttonSize.height - releasedTextSize.height ) / 2, buttonSize.width, releasedState ); + pressedText.draw( pressedTextOffset.x, ( buttonSize.height - pressedTextSize.height ) / 2 + 1, buttonSize.width, pressedState ); } - void createNormalButton( fheroes2::Sprite & released, fheroes2::Sprite & pressed, int32_t buttonWidth, const char * text, const bool isEvilInterface, + void createNormalButton( fheroes2::Sprite & released, fheroes2::Sprite & pressed, const char * text, const bool isEvilInterface, int32_t buttonWidth, int32_t buttonHeight = 25 ) { fheroes2::Point releasedOffset; @@ -431,7 +430,7 @@ namespace const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( released, pressed, text, releasedOffset, pressedOffset, { buttonWidth, fheroes2::getFontHeight( fheroes2::FontSize::BUTTON_RELEASED ) }, + renderTextOnButton( released, pressed, text, releasedOffset, pressedOffset, { buttonWidth, buttonHeight }, buttonFontColor ); } @@ -625,15 +624,7 @@ namespace case ICN::BTNBATTLEONLY: { _icnVsSprite[id].resize( 2 ); - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::BTNCOM, i ); - - // clean button. - Fill( out, 13, 11, 113, 31, getButtonFillingColor( i == 0 ) ); - } - - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "BATTLE\nONLY" ), { 12, 5 }, { 11, 6 }, { 117, 47 }, fheroes2::FontColor::WHITE ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "BATTLE\nONLY" ), false, 117, 56 ); break; } @@ -649,15 +640,7 @@ namespace break; } - const int baseIcnId = isEvilInterface ? ICN::EMPTY_EVIL_MEDIUM_BUTTON : ICN::EMPTY_GOOD_MEDIUM_BUTTON; - - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( baseIcnId, i ); - } - - const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "NEW\nGAME" ), { 7, 5 }, { 6, 6 }, { 86, 48 }, buttonFontColor ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "NEW\nGAME" ), isEvilInterface, 86, 56 ); break; } @@ -673,15 +656,7 @@ namespace break; } - const int baseIcnId = isEvilInterface ? ICN::EMPTY_EVIL_MEDIUM_BUTTON : ICN::EMPTY_GOOD_MEDIUM_BUTTON; - - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( baseIcnId, i ); - } - - const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "SAVE\nGAME" ), { 7, 5 }, { 6, 6 }, { 86, 48 }, buttonFontColor ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "SAVE\nGAME" ), isEvilInterface, 86, 56 ); break; } @@ -697,15 +672,7 @@ namespace break; } - const int baseIcnId = isEvilInterface ? ICN::EMPTY_EVIL_MEDIUM_BUTTON : ICN::EMPTY_GOOD_MEDIUM_BUTTON; - - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( baseIcnId, i ); - } - - const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "LOAD\nGAME" ), { 7, 5 }, { 6, 6 }, { 86, 48 }, buttonFontColor ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "LOAD\nGAME" ), isEvilInterface, 86, 56 ); break; } @@ -721,15 +688,7 @@ namespace break; } - const int baseIcnId = isEvilInterface ? ICN::EMPTY_EVIL_MEDIUM_BUTTON : ICN::EMPTY_GOOD_MEDIUM_BUTTON; - - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( baseIcnId, i ); - } - - const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "INFO" ), { 7, 5 }, { 6, 6 }, { 86, 48 }, buttonFontColor ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "INFO" ), isEvilInterface, 86, 56 ); break; } @@ -745,15 +704,7 @@ namespace break; } - const int baseIcnId = isEvilInterface ? ICN::EMPTY_EVIL_MEDIUM_BUTTON : ICN::EMPTY_GOOD_MEDIUM_BUTTON; - - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( baseIcnId, i ); - } - - const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "QUIT" ), { 7, 5 }, { 6, 6 }, { 86, 48 }, buttonFontColor ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "QUIT" ), isEvilInterface, 86, 56 ); break; } @@ -769,15 +720,7 @@ namespace break; } - const int baseIcnId = isEvilInterface ? ICN::EMPTY_EVIL_MEDIUM_BUTTON : ICN::EMPTY_GOOD_MEDIUM_BUTTON; - - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( baseIcnId, i ); - } - - const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "NEW\nMAP" ), { 7, 5 }, { 6, 6 }, { 86, 48 }, buttonFontColor ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "NEW\nMAP" ), isEvilInterface, 86, 56 ); break; } @@ -793,15 +736,7 @@ namespace break; } - const int baseIcnId = isEvilInterface ? ICN::EMPTY_EVIL_MEDIUM_BUTTON : ICN::EMPTY_GOOD_MEDIUM_BUTTON; - - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( baseIcnId, i ); - } - - const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "SAVE\nMAP" ), { 7, 5 }, { 6, 6 }, { 86, 48 }, buttonFontColor ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "SAVE\nMAP" ), isEvilInterface, 86, 56 ); break; } @@ -819,13 +754,7 @@ namespace const int baseIcnId = isEvilInterface ? ICN::EMPTY_EVIL_MEDIUM_BUTTON : ICN::EMPTY_GOOD_MEDIUM_BUTTON; - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( baseIcnId, i ); - } - - const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "LOAD\nMAP" ), { 7, 5 }, { 6, 6 }, { 86, 48 }, buttonFontColor ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "LOAD\nMAP" ), isEvilInterface, 86, 56 ); break; } @@ -1015,8 +944,7 @@ namespace // The heroes meeting screen has an embedded shadow so the button needs to be fixed at the same size as the original one. // TODO: Remove the embedded shadow and button in the heroes meeting screen and use getTextAdaptedButton() instead. - const int32_t textWidth = 70; - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], textWidth, gettext_noop( "smallerButton|EXIT" ), false ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), false, 70 ); break; } @@ -1032,17 +960,8 @@ namespace // Needs to be generated from original assets because it needs the black background from the pressed state. // TODO: Make a way to generate buttons with black background since it is needed for MAX and EXIT in the Well and Guilds. - for ( int32_t i = 0; i < static_cast( buttonStates.size() ); ++i ) { - fheroes2::Sprite & out = buttonStates[i]; - out = fheroes2::AGG::GetICN( ICN::TREASURY, 1 + i ); - // clean the button. - Fill( out, 6 - i, 4 + i, 70, 17, getButtonFillingColor( i == 0 ) ); - } - - const int32_t textWidth = 70; - renderTextOnButton( buttonStates[0], buttonStates[1], gettext_noop( "smallerButton|EXIT" ), { 7, 5 }, { 6, 6 }, - { textWidth, fheroes2::getFontHeight( fheroes2::FontSize::BUTTON_RELEASED ) }, fheroes2::FontColor::WHITE ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), false, 70 ); break; } @@ -1137,16 +1056,7 @@ namespace break; } - // Needs to be generated from original assets because the pressed state is 1px wider than normal. - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::OVERVIEW, 4 + i ); - - // clean the button. - Fill( out, 6 - i, 4 + i, 89, 16, getButtonFillingColor( i == 0 ) ); - } - - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "EXIT" ), { 6, 5 }, { 5, 6 }, { 89, 16 }, fheroes2::FontColor::WHITE ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), false, 89 ); break; } @@ -1159,15 +1069,7 @@ namespace break; } - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::OVERVIEW, 0 + i ); - - // clean the button. - Fill( out, 5, 10 + i, 89, 20, getButtonFillingColor( i == 0 ) ); - } - - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "HEROES" ), { 6, 5 }, { 5, 6 }, { 89, 34 }, fheroes2::FontColor::WHITE ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "HEROES" ), false, 89, 42 ); break; } @@ -1188,7 +1090,7 @@ namespace Fill( out, 6, 6 + i, 89 - i, 30, getButtonFillingColor( i == 0 ) ); } - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "TOWNS/\nCASTLES" ), { 6, 5 }, { 5, 6 }, { 90, 34 }, fheroes2::FontColor::WHITE ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "TOWNS/\nCASTLES" ), false, 89, 42 ); break; } @@ -1202,8 +1104,7 @@ namespace break; } - const int32_t textWidth = 46; - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], textWidth, gettext_noop( "S" ), false ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "S" ), false, 46 ); break; } @@ -1216,8 +1117,7 @@ namespace break; } - const int32_t textWidth = 46; - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], textWidth, gettext_noop( "M" ), false ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "M" ), false, 46 ); break; } @@ -1230,8 +1130,7 @@ namespace break; } - const int32_t textWidth = 46; - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], textWidth, gettext_noop( "L" ), false ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "L" ), false, 46 ); break; } @@ -1244,8 +1143,7 @@ namespace break; } - const int32_t textWidth = 46; - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], textWidth, gettext_noop( "X-L" ), false ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "X-L" ), false, 46 ); break; } @@ -1258,8 +1156,7 @@ namespace break; } - const int32_t textWidth = 58; - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], textWidth, gettext_noop( "ALL" ), false ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "ALL" ), false, 58 ); break; } @@ -1293,20 +1190,24 @@ namespace _icnVsSprite[id].resize( 2 ); if ( useOriginalResources() ) { - _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 0 ); - _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 1 ); - break; - } + // Remove embedded shadows so that we can add them later. + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::BTNCOM, i ); - // clean button. - Fill( out, 13, 11, 113, 31, getButtonFillingColor( i == 0 ) ); + const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 0 ); + const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 1 ); + + released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + + Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + + setButtonCornersTransparent( released ); + break; } - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "STANDARD\nGAME" ), { 12, 5 }, { 11, 6 }, { 120, 47 }, - fheroes2::FontColor::WHITE ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "STANDARD\nGAME" ), false, 117, 56 ); break; } @@ -1314,20 +1215,29 @@ namespace _icnVsSprite[id].resize( 2 ); if ( useOriginalResources() ) { - _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 2 ); - _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 3 ); - break; - } + // Remove embedded shadows so that we can add them later. + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::BTNCOM, i ); - // clean button. - Fill( out, 13, 11, 113, 31, getButtonFillingColor( i == 0 ) ); + const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 2 ); + const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 3 ); + + released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + + Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + // Fix the disabled state. + fheroes2::Image common = fheroes2::ExtractCommonPattern( { &released, &pressed } ); + common = fheroes2::FilterOnePixelNoise( common ); + common = fheroes2::FilterOnePixelNoise( common ); + common = fheroes2::FilterOnePixelNoise( common ); + + setButtonCornersTransparent( released ); + break; } - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "CAMPAIGN\nGAME" ), { 11, 5 }, { 10, 6 }, { 119, 47 }, - fheroes2::FontColor::WHITE ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "CAMPAIGN\nGAME" ), false, 117, 56 ); break; } @@ -1335,20 +1245,25 @@ namespace _icnVsSprite[id].resize( 2 ); if ( useOriginalResources() ) { - _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 4 ); - _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 5 ); + // Remove embedded shadows so that we can add them later. + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; + + const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 4 ); + const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 5 ); + + released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + + Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + + setButtonCornersTransparent( released ); break; } - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::BTNCOM, i ); - // clean button. - Fill( out, 13, 11, 113, 31, getButtonFillingColor( i == 0 ) ); - } + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MULTI-\nPLAYER\nGAME" ), false, 117, 56 ); - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MULTI-\nPLAYER\nGAME" ), { 12, 5 }, { 11, 6 }, { 117, 47 }, - fheroes2::FontColor::WHITE ); break; } @@ -1356,19 +1271,24 @@ namespace _icnVsSprite[id].resize( 2 ); if ( useOriginalResources() ) { - _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 ); - _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 7 ); - break; - } + // Remove embedded shadows so that we can add them later. + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::BTNCOM, i ); - // clean button. - Fill( out, 13, 11, 113, 31, getButtonFillingColor( i == 0 ) ); + const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 ); + const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 7 ); + + released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + + Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + + setButtonCornersTransparent( released ); + break; } - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "CANCEL" ), { 12, 5 }, { 11, 6 }, { 117, 47 }, fheroes2::FontColor::WHITE ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "CANCEL" ), false, 117, 56 ); break; } @@ -1376,19 +1296,24 @@ namespace _icnVsSprite[id].resize( 2 ); if ( useOriginalResources() ) { - _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::BTNDCCFG, 4 ); - _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::BTNDCCFG, 5 ); - break; - } + // Remove embedded shadows so that we can add them later. + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::BTNCOM, i ); - // clean button. - Fill( out, 13, 11, 113, 31, getButtonFillingColor( i == 0 ) ); + const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNDCCFG, 4 ); + const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNDCCFG, 5 ); + + released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + + Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + + setButtonCornersTransparent( released ); + break; } - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "CONFIG" ), { 12, 5 }, { 11, 6 }, { 117, 47 }, fheroes2::FontColor::WHITE ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "CONFIG" ), false, 117, 56 ); break; } @@ -1396,20 +1321,25 @@ namespace _icnVsSprite[id].resize( 2 ); if ( useOriginalResources() ) { - _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::X_LOADCM, 0 ); - _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::X_LOADCM, 1 ); - break; - } + // Remove embedded shadows so that we can add them later. + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::BTNCOM, i ); - // clean button. - Fill( out, 13, 11, 113, 31, getButtonFillingColor( i == 0 ) ); + const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::X_LOADCM, 0 ); + const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::X_LOADCM, 1 ); + + released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + + Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + + setButtonCornersTransparent( released ); + + break; } - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "ORIGINAL\nCAMPAIGN" ), { 12, 5 }, { 11, 6 }, { 117, 47 }, - fheroes2::FontColor::WHITE ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "ORIGINAL\nCAMPAIGN" ), false, 117, 56 ); break; } @@ -1417,20 +1347,24 @@ namespace _icnVsSprite[id].resize( 2 ); if ( useOriginalResources() ) { - _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::X_LOADCM, 2 ); - _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::X_LOADCM, 3 ); - break; - } + // Remove embedded shadows so that we can add them later. + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::BTNCOM, i ); - // clean button. - Fill( out, 13, 11, 113, 31, getButtonFillingColor( i == 0 ) ); + const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::X_LOADCM, 2 ); + const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::X_LOADCM, 3 ); + + released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + + Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + + setButtonCornersTransparent( released ); + break; } - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "EXPANSION\nCAMPAIGN" ), { 12, 5 }, { 11, 6 }, { 117, 47 }, - fheroes2::FontColor::WHITE ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "EXPANSION\nCAMPAIGN" ), false, 117, 56 ); break; } @@ -1438,19 +1372,24 @@ namespace _icnVsSprite[id].resize( 2 ); if ( useOriginalResources() ) { - _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::BTNMP, 0 ); - _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::BTNMP, 1 ); - break; - } + // Remove embedded shadows so that we can add them later. + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::BTNCOM, i ); - // clean button. - Fill( out, 13, 11, 113, 31, getButtonFillingColor( i == 0 ) ); + const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNMP, 0 ); + const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNMP, 1 ); + + released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + + Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + + setButtonCornersTransparent( released ); + break; } - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "HOT SEAT" ), { 11, 5 }, { 10, 6 }, { 120, 47 }, fheroes2::FontColor::WHITE ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "HOT SEAT" ), false, 117, 56 ); break; } @@ -1458,19 +1397,24 @@ namespace _icnVsSprite[id].resize( 2 ); if ( useOriginalResources() ) { - _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::BTNHOTST, 0 ); - _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::BTNHOTST, 1 ); - break; - } + // Remove embedded shadows so that we can add them later. + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::BTNCOM, i ); - // clean button. - Fill( out, 13, 11, 113, 31, getButtonFillingColor( i == 0 ) ); + const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNHOTST, 0 ); + const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNHOTST, 1 ); + + released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + + Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + + setButtonCornersTransparent( released ); + break; } - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "2 PLAYERS" ), { 11, 5 }, { 10, 6 }, { 120, 47 }, fheroes2::FontColor::WHITE ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "2 PLAYERS" ), false, 117, 56 ); break; } @@ -1478,19 +1422,24 @@ namespace _icnVsSprite[id].resize( 2 ); if ( useOriginalResources() ) { - _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::BTNHOTST, 2 ); - _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::BTNHOTST, 3 ); - break; - } + // Remove embedded shadows so that we can add them later. + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::BTNCOM, i ); - // clean button. - Fill( out, 13, 11, 113, 31, getButtonFillingColor( i == 0 ) ); + const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNHOTST, 2 ); + const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNHOTST, 3 ); + + released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + + Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + + setButtonCornersTransparent( released ); + break; } - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "3 PLAYERS" ), { 11, 5 }, { 10, 6 }, { 120, 47 }, fheroes2::FontColor::WHITE ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "3 PLAYERS" ), false, 117, 56 ); break; } @@ -1498,19 +1447,25 @@ namespace _icnVsSprite[id].resize( 2 ); if ( useOriginalResources() ) { - _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::BTNHOTST, 4 ); - _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::BTNHOTST, 5 ); + // Remove embedded shadows so that we can add them later. + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; + + const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNHOTST, 4 ); + const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNHOTST, 5 ); + + released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + + Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + + setButtonCornersTransparent( released ); break; } - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::BTNCOM, i ); - // clean button. - Fill( out, 13, 11, 113, 31, getButtonFillingColor( i == 0 ) ); - } + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "4 PLAYERS" ), false, 117, 56 ); - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "4 PLAYERS" ), { 11, 5 }, { 10, 6 }, { 120, 47 }, fheroes2::FontColor::WHITE ); break; } @@ -1518,19 +1473,24 @@ namespace _icnVsSprite[id].resize( 2 ); if ( useOriginalResources() ) { - _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::BTNHOTST, 6 ); - _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::BTNHOTST, 7 ); - break; - } + // Remove embedded shadows so that we can add them later. + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::BTNCOM, i ); - // clean button. - Fill( out, 13, 11, 113, 31, getButtonFillingColor( i == 0 ) ); + const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNHOTST, 6 ); + const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNHOTST, 7 ); + + released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + + Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + + setButtonCornersTransparent( released ); + break; } - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "5 PLAYERS" ), { 11, 5 }, { 10, 6 }, { 120, 47 }, fheroes2::FontColor::WHITE ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "5 PLAYERS" ), false, 117, 56 ); break; } @@ -1538,19 +1498,24 @@ namespace _icnVsSprite[id].resize( 2 ); if ( useOriginalResources() ) { - _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::BTNHOTST, 8 ); - _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::BTNHOTST, 9 ); - break; - } + // Remove embedded shadows so that we can add them later. + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::BTNCOM, i ); - // clean button. - Fill( out, 13, 11, 113, 31, getButtonFillingColor( i == 0 ) ); + const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNHOTST, 8 ); + const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNHOTST, 9 ); + + released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + + Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + + setButtonCornersTransparent( released ); + break; } - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "6 PLAYERS" ), { 11, 5 }, { 10, 6 }, { 120, 47 }, fheroes2::FontColor::WHITE ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "6 PLAYERS" ), false, 117, 56 ); break; } @@ -1591,16 +1556,8 @@ namespace const bool isEvilInterface = ( id == ICN::BUTTON_VIEWWORLD_EXIT_EVIL ); const int baseIcnId = isEvilInterface ? ICN::LGNDXTRE : ICN::LGNDXTRA; - - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( baseIcnId, 0 + i ); - // clean the button. - Fill( out, 27 - i, 4 + i, 25, 26, getButtonFillingColor( i == 0, !isEvilInterface ) ); - } - - const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "EXIT" ), { 6, 5 }, { 5, 6 }, { 71, 27 }, buttonFontColor ); + // TODO: Can't be drawn because it is both taller and smaller than the standard button which resizeButton does not handle yet. + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), isEvilInterface, 70, 35 ); break; } @@ -1699,55 +1656,28 @@ namespace case ICN::BUTTON_SMALL_MIN_GOOD: { _icnVsSprite[id].resize( 2 ); - if ( useOriginalResources() ) { - // Write the "MIN" text on original assets ICNs. - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - _icnVsSprite[id][i] = fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MAX_GOOD, 0 + i ); - - // Clean the button text. - Blit( fheroes2::AGG::GetICN( ICN::SYSTEM, 11 + i ), 10 - i, 4 + i, _icnVsSprite[id][i], 6 - i, 4 + i, 50, 16 ); - } - - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MIN" ), { 6, 5 }, { 5, 6 }, { 52, 16 }, fheroes2::FontColor::WHITE ); - - break; - } - - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], 61, gettext_noop( "MIN" ), false ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MIN" ), false, 61 ); break; } case ICN::BUTTON_SMALL_MIN_EVIL: { _icnVsSprite[id].resize( 2 ); - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], 61, gettext_noop( "MIN" ), true ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MIN" ), true, 61 ); break; } case ICN::BUTTON_SMALL_MAX_GOOD: { _icnVsSprite[id].resize( 2 ); - if ( useOriginalResources() ) { - // The original assets ICN contains button with shadow. We crop only the button. - _icnVsSprite[id][0] = fheroes2::Crop( fheroes2::AGG::GetICN( ICN::RECRUIT, 4 ), 5, 0, 60, 25 ); - _icnVsSprite[id][1] = fheroes2::Crop( fheroes2::AGG::GetICN( ICN::RECRUIT, 5 ), 5, 0, 60, 25 ); - - // To properly generate shadows and Blit the button we need to make some pixels transparent. - for ( fheroes2::Sprite & image : _icnVsSprite[id] ) { - setButtonCornersTransparent( image ); - } - - break; - } - - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], 61, gettext_noop( "MAX" ), false ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MAX" ), false, 61 ); break; } case ICN::BUTTON_SMALL_MAX_EVIL: { _icnVsSprite[id].resize( 2 ); - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], 61, gettext_noop( "MAX" ), true ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MAX" ), true, 61 ); break; } @@ -1785,7 +1715,7 @@ namespace // Normal button width is 80 pixels so if the overall length is smaller than 80 then set the default value. const int32_t width = std::max( 80, std::max( townTextWidth, castleTextWidth ) ); - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], width, gettext_noop( "CASTLE" ), id == ICN::BUTTON_CASTLE_EVIL ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "CASTLE" ), id == ICN::BUTTON_CASTLE_EVIL, width ); break; } @@ -1802,7 +1732,7 @@ namespace // Normal button width is 80 pixels so if the overall length is smaller than 80 then set the default value. const int32_t width = std::max( 80, std::max( townTextWidth, castleTextWidth ) ); - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], width, gettext_noop( "TOWN" ), id == ICN::BUTTON_TOWN_EVIL ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "TOWN" ), id == ICN::BUTTON_TOWN_EVIL, width ); break; } @@ -1823,28 +1753,10 @@ namespace _icnVsSprite[id].resize( 2 ); const bool isEvilInterface = ( id == ICN::UNIFORM_EVIL_MAX_BUTTON || id == ICN::UNIFORM_EVIL_MIN_BUTTON ); - const int baseIcnId = isEvilInterface ? ICN::SYSTEME : ICN::SYSTEM; - - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - const fheroes2::Sprite & originalButton = fheroes2::AGG::GetICN( ICN::RECRUIT, 4 + i ); - out.resize( originalButton.width() + 4, originalButton.height() - 5 + i ); - out.reset(); + const char * text = ( id == ICN::UNIFORM_GOOD_MIN_BUTTON || id == ICN::UNIFORM_EVIL_MIN_BUTTON ) ? gettext_noop( "MIN" ) : gettext_noop( "MAX" ); - const fheroes2::Sprite & emptyButton = fheroes2::AGG::GetICN( baseIcnId, 11 + i ); - - // Copy left main body of button. - fheroes2::Copy( emptyButton, 0, 0, out, 0, 0, originalButton.width() - 3 + i, originalButton.height() - 5 + i ); - - // Copy terminating right margin of the button. - fheroes2::Copy( emptyButton, 89 + i, 0, out, 63 + i, 0, 7 - i, originalButton.height() - i ); - } - - const char * text( ( id == ICN::UNIFORM_GOOD_MIN_BUTTON || id == ICN::UNIFORM_EVIL_MIN_BUTTON ) ? "MIN" : "MAX" ); - - const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( text ), { 6, 5 }, { 4, 6 }, { 62, 16 }, buttonFontColor ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], text, isEvilInterface, 61 ); break; } @@ -1923,7 +1835,7 @@ namespace break; } - // We need to temporarily remove the letter specific X offsets in the font because if not the letters will + // We need to temporarily remove the letter-specific X offsets in the font because if not the letters will // be off-centered when we are displaying one letter per line const ButtonFontOffsetRestorer fontReleased( _icnVsSprite[ICN::BUTTON_GOOD_FONT_RELEASED], -1 ); const ButtonFontOffsetRestorer fontPressed( _icnVsSprite[ICN::BUTTON_GOOD_FONT_PRESSED], -1 ); @@ -2020,7 +1932,7 @@ namespace const ButtonFontOffsetRestorer fontRestorerReleased( _icnVsSprite[ICN::BUTTON_GOOD_FONT_RELEASED], -1 ); const ButtonFontOffsetRestorer fontRestorerPressed( _icnVsSprite[ICN::BUTTON_GOOD_FONT_PRESSED], -1 ); - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], buttonText, { 4, 4 }, { 3, 5 }, { 21, 124 }, fheroes2::FontColor::WHITE ); + renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], buttonText, { 4, 4 }, { 3, 5 }, { 27, 133 }, fheroes2::FontColor::WHITE ); break; } @@ -2079,11 +1991,10 @@ namespace break; } - case ICN::DISMISS_HERO_DISABLED_BUTTON: - case ICN::NEW_CAMPAIGN_DISABLED_BUTTON: { + case ICN::DISMISS_HERO_DISABLED_BUTTON: { _icnVsSprite[id].resize( 1 ); - const int buttonIcnId = ( id == ICN::DISMISS_HERO_DISABLED_BUTTON ) ? ICN::BUTTON_VERTICAL_DISMISS : ICN::BUTTON_CAMPAIGN_GAME; + const int buttonIcnId = ICN::BUTTON_VERTICAL_DISMISS; const fheroes2::Sprite & released = fheroes2::AGG::GetICN( buttonIcnId, 0 ); const fheroes2::Sprite & pressed = fheroes2::AGG::GetICN( buttonIcnId, 1 ); diff --git a/src/fheroes2/agg/icn.h b/src/fheroes2/agg/icn.h index 7fb443faeb6..3c6c6391a93 100644 --- a/src/fheroes2/agg/icn.h +++ b/src/fheroes2/agg/icn.h @@ -949,7 +949,6 @@ namespace ICN MONO_CURSOR_ADVENTURE_MAP, DISMISS_HERO_DISABLED_BUTTON, - NEW_CAMPAIGN_DISABLED_BUTTON, KNIGHT_CASTLE_RIGHT_FARM, KNIGHT_CASTLE_LEFT_FARM, diff --git a/src/fheroes2/game/game_loadgame.cpp b/src/fheroes2/game/game_loadgame.cpp index 0503f39658f..d206bbacf7a 100644 --- a/src/fheroes2/game/game_loadgame.cpp +++ b/src/fheroes2/game/game_loadgame.cpp @@ -91,10 +91,14 @@ fheroes2::GameMode Game::LoadMulti() fheroes2::drawMainMenuScreen(); const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); + fheroes2::ButtonSprite buttonHotSeat = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y, fheroes2::AGG::GetICN( ICN::BUTTON_HOT_SEAT, 0 ), + fheroes2::AGG::GetICN( ICN::BUTTON_HOT_SEAT, 1 ), display, { -5, 6 } ); - fheroes2::Button buttonHotSeat( buttonPos.x, buttonPos.y, ICN::BUTTON_HOT_SEAT, 0, 1 ); - fheroes2::Button buttonNetwork( buttonPos.x, buttonPos.y + buttonYStep * 1, ICN::BTNMP, 2, 3 ); - fheroes2::Button buttonCancel( buttonPos.x, buttonPos.y + buttonYStep * 5, ICN::BUTTON_LARGE_CANCEL, 0, 1 ); + fheroes2::ButtonSprite buttonNetwork = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BTNMP, 2 ), + fheroes2::AGG::GetICN( ICN::BTNMP, 3 ), display, { -5, 6 } ); + fheroes2::ButtonSprite buttonCancel + = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 5, fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 0 ), + fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 1 ), display, { -5, 6 } ); buttonHotSeat.draw(); buttonCancel.draw(); @@ -151,12 +155,21 @@ fheroes2::GameMode Game::LoadGame() fheroes2::drawMainMenuScreen(); const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); + fheroes2::Display & display = fheroes2::Display::instance(); + + fheroes2::ButtonSprite buttonStandardGame + = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BUTTON_STANDARD_GAME, 0 ), + fheroes2::AGG::GetICN( ICN::BUTTON_STANDARD_GAME, 1 ), display, { -5, 6 } ); + fheroes2::ButtonSprite buttonCampaignGame + = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BUTTON_CAMPAIGN_GAME, 0 ), + fheroes2::AGG::GetICN( ICN::BUTTON_CAMPAIGN_GAME, 1 ), display, { -5, 6 } ); + fheroes2::ButtonSprite buttonMultiplayerGame + = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BUTTON_MULTIPLAYER_GAME, 0 ), + fheroes2::AGG::GetICN( ICN::BUTTON_MULTIPLAYER_GAME, 1 ), display, { -5, 6 } ); + fheroes2::ButtonSprite buttonCancel + = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 0 ), + fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 1 ), display, { -5, 6 } ); - fheroes2::Button buttonStandardGame( 0, 0, ICN::BUTTON_STANDARD_GAME, 0, 1 ); - fheroes2::ButtonSprite buttonCampaignGame( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BUTTON_CAMPAIGN_GAME, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_CAMPAIGN_GAME, 1 ), fheroes2::AGG::GetICN( ICN::NEW_CAMPAIGN_DISABLED_BUTTON, 0 ) ); - fheroes2::Button buttonMultiplayerGame( 0, 0, ICN::BUTTON_MULTIPLAYER_GAME, 0, 1 ); - fheroes2::Button buttonCancel( 0, 0, ICN::BUTTON_LARGE_CANCEL, 0, 1 ); const std::array buttons{ &buttonStandardGame, &buttonCampaignGame, &buttonMultiplayerGame, &buttonCancel }; diff --git a/src/fheroes2/game/game_newgame.cpp b/src/fheroes2/game/game_newgame.cpp index 0611b4618bf..afed68e5faa 100644 --- a/src/fheroes2/game/game_newgame.cpp +++ b/src/fheroes2/game/game_newgame.cpp @@ -199,10 +199,17 @@ fheroes2::GameMode Game::CampaignSelection() fheroes2::drawMainMenuScreen(); const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); + fheroes2::Display & display = fheroes2::Display::instance(); - fheroes2::Button buttonSuccessionWars( buttonPos.x, buttonPos.y, ICN::BUTTON_ORIGINAL_CAMPAIGN, 0, 1 ); - fheroes2::Button buttonPriceOfLoyalty( buttonPos.x, buttonPos.y + buttonYStep * 1, ICN::BUTTON_EXPANSION_CAMPAIGN, 0, 1 ); - fheroes2::Button buttonCancel( buttonPos.x, buttonPos.y + buttonYStep * 5, ICN::BUTTON_LARGE_CANCEL, 0, 1 ); + fheroes2::ButtonSprite buttonSuccessionWars + = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y, fheroes2::AGG::GetICN( ICN::BUTTON_ORIGINAL_CAMPAIGN, 0 ), + fheroes2::AGG::GetICN( ICN::BUTTON_ORIGINAL_CAMPAIGN, 1 ), display, { -5, 6 } ); + fheroes2::ButtonSprite buttonPriceOfLoyalty + = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BUTTON_EXPANSION_CAMPAIGN, 0 ), + fheroes2::AGG::GetICN( ICN::BUTTON_EXPANSION_CAMPAIGN, 1 ), display, { -5, 6 } ); + fheroes2::ButtonSprite buttonCancel + = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 5, fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 0 ), + fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 1 ), display, { -5, 6 } ); buttonSuccessionWars.draw(); buttonPriceOfLoyalty.draw(); @@ -481,10 +488,14 @@ fheroes2::GameMode Game::NewNetwork() fheroes2::drawMainMenuScreen(); const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); + fheroes2::Display & display = fheroes2::Display::instance(); - fheroes2::Button buttonHost( buttonPos.x, buttonPos.y, ICN::BTNNET, 0, 1 ); - fheroes2::Button buttonGuest( buttonPos.x, buttonPos.y + buttonYStep, ICN::BTNNET, 2, 3 ); - fheroes2::Button buttonCancel( buttonPos.x, buttonPos.y + buttonYStep * 2, ICN::BTNMP, 8, 9 ); + fheroes2::ButtonSprite buttonHost = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y, fheroes2::AGG::GetICN( ICN::BTNNET, 0 ), + fheroes2::AGG::GetICN( ICN::BTNNET, 1 ), display, { -5, 6 } ); + fheroes2::ButtonSprite buttonGuest = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BTNNET, 2 ), + fheroes2::AGG::GetICN( ICN::BTNNET, 3 ), display, { -5, 6 } ); + fheroes2::ButtonSprite buttonCancel = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 5, fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 0 ), + fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 1 ), display, { -5, 6 } ); buttonHost.draw(); buttonGuest.draw(); @@ -536,14 +547,24 @@ fheroes2::GameMode Game::NewGame( const bool isProbablyDemoVersion ) fheroes2::drawMainMenuScreen(); const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); + fheroes2::Display & display = fheroes2::Display::instance(); - fheroes2::Button buttonStandardGame( buttonPos.x, buttonPos.y, ICN::BUTTON_STANDARD_GAME, 0, 1 ); - fheroes2::ButtonSprite buttonCampaignGame( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BUTTON_CAMPAIGN_GAME, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_CAMPAIGN_GAME, 1 ), fheroes2::AGG::GetICN( ICN::NEW_CAMPAIGN_DISABLED_BUTTON, 0 ) ); - fheroes2::Button buttonMultiGame( buttonPos.x, buttonPos.y + buttonYStep * 2, ICN::BUTTON_MULTIPLAYER_GAME, 0, 1 ); - fheroes2::Button buttonBattleGame( buttonPos.x, buttonPos.y + buttonYStep * 3, ICN::BTNBATTLEONLY, 0, 1 ); - fheroes2::Button buttonSettings( buttonPos.x, buttonPos.y + buttonYStep * 4, ICN::BUTTON_LARGE_CONFIG, 0, 1 ); - fheroes2::Button buttonCancel( buttonPos.x, buttonPos.y + buttonYStep * 5, ICN::BUTTON_LARGE_CANCEL, 0, 1 ); + fheroes2::ButtonSprite buttonStandardGame = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y, fheroes2::AGG::GetICN( ICN::BUTTON_STANDARD_GAME, 0 ), + fheroes2::AGG::GetICN( ICN::BUTTON_STANDARD_GAME, 1 ), display, { -5, 6 } ); + fheroes2::ButtonSprite buttonCampaignGame + = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BUTTON_CAMPAIGN_GAME, 0 ), + fheroes2::AGG::GetICN( ICN::BUTTON_CAMPAIGN_GAME, 1 ), display, { -5, 6 } ); + fheroes2::ButtonSprite buttonMultiGame + = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 2, fheroes2::AGG::GetICN( ICN::BUTTON_MULTIPLAYER_GAME, 0 ), + fheroes2::AGG::GetICN( ICN::BUTTON_MULTIPLAYER_GAME, 1 ), display, { -5, 6 } ); + fheroes2::ButtonSprite buttonBattleGame = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 3, fheroes2::AGG::GetICN( ICN::BTNBATTLEONLY, 0 ), + fheroes2::AGG::GetICN( ICN::BTNBATTLEONLY, 1 ), display, { -5, 6 } ); + fheroes2::ButtonSprite buttonSettings + = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 4, fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CONFIG, 0 ), + fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CONFIG, 1 ), display, { -5, 6 } ); + fheroes2::ButtonSprite buttonCancel + = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 5, fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 0 ), + fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 1 ), display, { -5, 6 } ); if ( !isSuccessionWarsCampaignPresent() ) { buttonCampaignGame.disable(); @@ -633,11 +654,16 @@ fheroes2::GameMode Game::NewMulti() const CursorRestorer cursorRestorer( true, Cursor::POINTER ); fheroes2::drawMainMenuScreen(); + fheroes2::Display & display = fheroes2::Display::instance(); const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); - fheroes2::Button buttonHotSeat( buttonPos.x, buttonPos.y, ICN::BUTTON_HOT_SEAT, 0, 1 ); - fheroes2::Button buttonNetwork( buttonPos.x, buttonPos.y + buttonYStep * 1, ICN::BTNMP, 2, 3 ); - fheroes2::Button buttonCancel( buttonPos.x, buttonPos.y + buttonYStep * 5, ICN::BUTTON_LARGE_CANCEL, 0, 1 ); + fheroes2::ButtonSprite buttonHotSeat = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y, fheroes2::AGG::GetICN( ICN::BUTTON_HOT_SEAT, 0 ), + fheroes2::AGG::GetICN( ICN::BUTTON_HOT_SEAT, 1 ), display, { -5, 6 } ); + fheroes2::ButtonSprite buttonNetwork = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BTNMP, 2 ), + fheroes2::AGG::GetICN( ICN::BTNMP, 3 ), display, { -5, 6 } ); + fheroes2::ButtonSprite buttonCancel + = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 5, fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 0 ), + fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 1 ), display, { -5, 6 } ); buttonHotSeat.draw(); buttonCancel.draw(); From 81c7c692a4abdba69ca42f5e94c07bdd6e57bede Mon Sep 17 00:00:00 2001 From: Zenseii Date: Mon, 3 Feb 2025 22:39:18 +0100 Subject: [PATCH 03/54] Code style --- src/fheroes2/agg/agg_image.cpp | 4 +--- src/fheroes2/game/game_loadgame.cpp | 1 - src/fheroes2/game/game_newgame.cpp | 10 +++++----- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 9b008e33630..3d6fd32165f 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -430,8 +430,7 @@ namespace const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( released, pressed, text, releasedOffset, pressedOffset, { buttonWidth, buttonHeight }, - buttonFontColor ); + renderTextOnButton( released, pressed, text, releasedOffset, pressedOffset, { buttonWidth, buttonHeight }, buttonFontColor ); } void createCampaignButtonSet( const int campaignSetIcnId, const std::array & texts ) @@ -1466,7 +1465,6 @@ namespace createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "4 PLAYERS" ), false, 117, 56 ); - break; } case ICN::BUTTON_5_PLAYERS: { diff --git a/src/fheroes2/game/game_loadgame.cpp b/src/fheroes2/game/game_loadgame.cpp index d206bbacf7a..34141a418a7 100644 --- a/src/fheroes2/game/game_loadgame.cpp +++ b/src/fheroes2/game/game_loadgame.cpp @@ -170,7 +170,6 @@ fheroes2::GameMode Game::LoadGame() = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 0 ), fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 1 ), display, { -5, 6 } ); - const std::array buttons{ &buttonStandardGame, &buttonCampaignGame, &buttonMultiplayerGame, &buttonCancel }; if ( !isSuccessionWarsCampaignPresent() ) { diff --git a/src/fheroes2/game/game_newgame.cpp b/src/fheroes2/game/game_newgame.cpp index afed68e5faa..adf7d9b0c5d 100644 --- a/src/fheroes2/game/game_newgame.cpp +++ b/src/fheroes2/game/game_newgame.cpp @@ -201,9 +201,8 @@ fheroes2::GameMode Game::CampaignSelection() const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); fheroes2::Display & display = fheroes2::Display::instance(); - fheroes2::ButtonSprite buttonSuccessionWars - = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y, fheroes2::AGG::GetICN( ICN::BUTTON_ORIGINAL_CAMPAIGN, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_ORIGINAL_CAMPAIGN, 1 ), display, { -5, 6 } ); + fheroes2::ButtonSprite buttonSuccessionWars = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y, fheroes2::AGG::GetICN( ICN::BUTTON_ORIGINAL_CAMPAIGN, 0 ), + fheroes2::AGG::GetICN( ICN::BUTTON_ORIGINAL_CAMPAIGN, 1 ), display, { -5, 6 } ); fheroes2::ButtonSprite buttonPriceOfLoyalty = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BUTTON_EXPANSION_CAMPAIGN, 0 ), fheroes2::AGG::GetICN( ICN::BUTTON_EXPANSION_CAMPAIGN, 1 ), display, { -5, 6 } ); @@ -494,8 +493,9 @@ fheroes2::GameMode Game::NewNetwork() fheroes2::AGG::GetICN( ICN::BTNNET, 1 ), display, { -5, 6 } ); fheroes2::ButtonSprite buttonGuest = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BTNNET, 2 ), fheroes2::AGG::GetICN( ICN::BTNNET, 3 ), display, { -5, 6 } ); - fheroes2::ButtonSprite buttonCancel = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 5, fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 1 ), display, { -5, 6 } ); + fheroes2::ButtonSprite buttonCancel + = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 5, fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 0 ), + fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 1 ), display, { -5, 6 } ); buttonHost.draw(); buttonGuest.draw(); From 7ca3120b0eda6f7f4d8768a65d5917fcbe0f4bec Mon Sep 17 00:00:00 2001 From: Zenseii Date: Mon, 3 Feb 2025 22:41:52 +0100 Subject: [PATCH 04/54] Fix copyright year --- src/fheroes2/dialog/dialog_selectcount.cpp | 2 +- src/fheroes2/dialog/dialog_selectfile.cpp | 2 +- src/fheroes2/editor/editor_save_map_window.cpp | 2 +- src/fheroes2/game/game_loadgame.cpp | 2 +- src/fheroes2/game/game_newgame.cpp | 2 +- src/fheroes2/gui/ui_button.h | 2 +- src/fheroes2/gui/ui_keyboard.cpp | 2 +- src/fheroes2/gui/ui_window.cpp | 2 +- src/fheroes2/gui/ui_window.h | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/fheroes2/dialog/dialog_selectcount.cpp b/src/fheroes2/dialog/dialog_selectcount.cpp index 1a99b476a81..fb347847944 100644 --- a/src/fheroes2/dialog/dialog_selectcount.cpp +++ b/src/fheroes2/dialog/dialog_selectcount.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2019 - 2024 * + * Copyright (C) 2019 - 2025 * * * * Free Heroes2 Engine: http://sourceforge.net/projects/fheroes2 * * Copyright (C) 2009 by Andrey Afletdinov * diff --git a/src/fheroes2/dialog/dialog_selectfile.cpp b/src/fheroes2/dialog/dialog_selectfile.cpp index 01612804665..8b9bbabe475 100644 --- a/src/fheroes2/dialog/dialog_selectfile.cpp +++ b/src/fheroes2/dialog/dialog_selectfile.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2019 - 2024 * + * Copyright (C) 2019 - 2025 * * * * Free Heroes2 Engine: http://sourceforge.net/projects/fheroes2 * * Copyright (C) 2009 by Andrey Afletdinov * diff --git a/src/fheroes2/editor/editor_save_map_window.cpp b/src/fheroes2/editor/editor_save_map_window.cpp index 2a416b883ff..2526d61a6e8 100644 --- a/src/fheroes2/editor/editor_save_map_window.cpp +++ b/src/fheroes2/editor/editor_save_map_window.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2019 - 2024 * + * Copyright (C) 2019 - 2025 * * * * 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 * diff --git a/src/fheroes2/game/game_loadgame.cpp b/src/fheroes2/game/game_loadgame.cpp index 34141a418a7..8bac0fa7479 100644 --- a/src/fheroes2/game/game_loadgame.cpp +++ b/src/fheroes2/game/game_loadgame.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2019 - 2024 * + * Copyright (C) 2019 - 2025 * * * * Free Heroes2 Engine: http://sourceforge.net/projects/fheroes2 * * Copyright (C) 2009 by Andrey Afletdinov * diff --git a/src/fheroes2/game/game_newgame.cpp b/src/fheroes2/game/game_newgame.cpp index adf7d9b0c5d..28bd1851831 100644 --- a/src/fheroes2/game/game_newgame.cpp +++ b/src/fheroes2/game/game_newgame.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2019 - 2024 * + * Copyright (C) 2019 - 2025 * * * * Free Heroes2 Engine: http://sourceforge.net/projects/fheroes2 * * Copyright (C) 2009 by Andrey Afletdinov * diff --git a/src/fheroes2/gui/ui_button.h b/src/fheroes2/gui/ui_button.h index 250a871cec1..dd10459cb58 100644 --- a/src/fheroes2/gui/ui_button.h +++ b/src/fheroes2/gui/ui_button.h @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2020 - 2024 * + * Copyright (C) 2020 - 2025 * * * * 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 * diff --git a/src/fheroes2/gui/ui_keyboard.cpp b/src/fheroes2/gui/ui_keyboard.cpp index d20a941ae36..104d1d180b9 100644 --- a/src/fheroes2/gui/ui_keyboard.cpp +++ b/src/fheroes2/gui/ui_keyboard.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2023 - 2024 * + * Copyright (C) 2023 - 2025 * * * * 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 * diff --git a/src/fheroes2/gui/ui_window.cpp b/src/fheroes2/gui/ui_window.cpp index 0d7a1139053..88c86056243 100644 --- a/src/fheroes2/gui/ui_window.cpp +++ b/src/fheroes2/gui/ui_window.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2021 - 2024 * + * Copyright (C) 2021 - 2025 * * * * 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 * diff --git a/src/fheroes2/gui/ui_window.h b/src/fheroes2/gui/ui_window.h index 54931d0ed32..27b013b2098 100644 --- a/src/fheroes2/gui/ui_window.h +++ b/src/fheroes2/gui/ui_window.h @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2021 - 2024 * + * Copyright (C) 2021 - 2025 * * * * 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 * From 7ffd3c81d95c970e697ba6a10ecaf60a3794407d Mon Sep 17 00:00:00 2001 From: Zenseii Date: Mon, 3 Feb 2025 22:42:58 +0100 Subject: [PATCH 05/54] code style --- src/fheroes2/agg/agg_image.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 3d6fd32165f..7dc4180ea19 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -1263,7 +1263,6 @@ namespace createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MULTI-\nPLAYER\nGAME" ), false, 117, 56 ); - break; } case ICN::BUTTON_LARGE_CANCEL: { From 7f745d8c3d1dd4b98dfb3a87dc71eec10d4f185b Mon Sep 17 00:00:00 2001 From: Zenseii Date: Mon, 3 Feb 2025 22:55:50 +0100 Subject: [PATCH 06/54] Remove the empty medium button because we can resize into any size now --- src/fheroes2/agg/agg_image.cpp | 28 ---------------------------- src/fheroes2/agg/icn.h | 2 -- 2 files changed, 30 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 7dc4180ea19..69f11a1b7f9 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -751,8 +751,6 @@ namespace break; } - const int baseIcnId = isEvilInterface ? ICN::EMPTY_EVIL_MEDIUM_BUTTON : ICN::EMPTY_GOOD_MEDIUM_BUTTON; - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "LOAD\nMAP" ), isEvilInterface, 86, 56 ); break; @@ -4811,32 +4809,6 @@ namespace return true; } - case ICN::EMPTY_GOOD_MEDIUM_BUTTON: - case ICN::EMPTY_EVIL_MEDIUM_BUTTON: { - const bool isGoodInterface = ( id == ICN::EMPTY_GOOD_MEDIUM_BUTTON ); - const int32_t originalId = isGoodInterface ? ICN::APANEL : ICN::APANELE; - loadICN( originalId ); - - if ( _icnVsSprite[originalId].size() < 10 ) { - return true; - } - - _icnVsSprite[id].resize( 2 ); - - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - - released = _icnVsSprite[originalId][2]; - pressed = _icnVsSprite[originalId][3]; - - if ( released.width() > 2 && released.height() > 2 && pressed.width() > 2 && pressed.height() > 2 ) { - // Clean the buttons. - Fill( released, 28, 15, 42, 27, getButtonFillingColor( true, isGoodInterface ) ); - Fill( pressed, 27, 16, 42, 27, getButtonFillingColor( false, isGoodInterface ) ); - } - - return true; - } case ICN::EMPTY_VERTICAL_GOOD_BUTTON: { const int32_t originalId = ICN::HSBTNS; loadICN( originalId ); diff --git a/src/fheroes2/agg/icn.h b/src/fheroes2/agg/icn.h index 3c6c6391a93..4d4b93ffd11 100644 --- a/src/fheroes2/agg/icn.h +++ b/src/fheroes2/agg/icn.h @@ -997,8 +997,6 @@ namespace ICN EMPTY_GOOD_BUTTON, EMPTY_EVIL_BUTTON, - EMPTY_GOOD_MEDIUM_BUTTON, - EMPTY_EVIL_MEDIUM_BUTTON, EMPTY_POL_BUTTON, EMPTY_GUILDWELL_BUTTON, EMPTY_VERTICAL_GOOD_BUTTON, From 81ccf997f942c5367bdad9ce40f7ce833a2bd59f Mon Sep 17 00:00:00 2001 From: Zenseii Date: Mon, 3 Feb 2025 22:56:29 +0100 Subject: [PATCH 07/54] remove unused view world exit variable --- src/fheroes2/agg/agg_image.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 69f11a1b7f9..c9744707ec4 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -1550,7 +1550,6 @@ namespace _icnVsSprite[id].resize( 2 ); const bool isEvilInterface = ( id == ICN::BUTTON_VIEWWORLD_EXIT_EVIL ); - const int baseIcnId = isEvilInterface ? ICN::LGNDXTRE : ICN::LGNDXTRA; // TODO: Can't be drawn because it is both taller and smaller than the standard button which resizeButton does not handle yet. createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), isEvilInterface, 70, 35 ); From e5e2958d03be7dc5e52b19072590cdcb47816771 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Mon, 3 Feb 2025 22:58:20 +0100 Subject: [PATCH 08/54] add consts --- src/fheroes2/game/game_loadgame.cpp | 2 +- src/fheroes2/game/game_newgame.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/fheroes2/game/game_loadgame.cpp b/src/fheroes2/game/game_loadgame.cpp index 8bac0fa7479..f2c60295ed1 100644 --- a/src/fheroes2/game/game_loadgame.cpp +++ b/src/fheroes2/game/game_loadgame.cpp @@ -155,7 +155,7 @@ fheroes2::GameMode Game::LoadGame() fheroes2::drawMainMenuScreen(); const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); - fheroes2::Display & display = fheroes2::Display::instance(); + const fheroes2::Display & display = fheroes2::Display::instance(); fheroes2::ButtonSprite buttonStandardGame = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BUTTON_STANDARD_GAME, 0 ), diff --git a/src/fheroes2/game/game_newgame.cpp b/src/fheroes2/game/game_newgame.cpp index 28bd1851831..ba9c5cae678 100644 --- a/src/fheroes2/game/game_newgame.cpp +++ b/src/fheroes2/game/game_newgame.cpp @@ -199,7 +199,7 @@ fheroes2::GameMode Game::CampaignSelection() fheroes2::drawMainMenuScreen(); const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); - fheroes2::Display & display = fheroes2::Display::instance(); + const fheroes2::Display & display = fheroes2::Display::instance(); fheroes2::ButtonSprite buttonSuccessionWars = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y, fheroes2::AGG::GetICN( ICN::BUTTON_ORIGINAL_CAMPAIGN, 0 ), fheroes2::AGG::GetICN( ICN::BUTTON_ORIGINAL_CAMPAIGN, 1 ), display, { -5, 6 } ); @@ -487,7 +487,7 @@ fheroes2::GameMode Game::NewNetwork() fheroes2::drawMainMenuScreen(); const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); - fheroes2::Display & display = fheroes2::Display::instance(); + const fheroes2::Display & display = fheroes2::Display::instance(); fheroes2::ButtonSprite buttonHost = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y, fheroes2::AGG::GetICN( ICN::BTNNET, 0 ), fheroes2::AGG::GetICN( ICN::BTNNET, 1 ), display, { -5, 6 } ); @@ -547,7 +547,7 @@ fheroes2::GameMode Game::NewGame( const bool isProbablyDemoVersion ) fheroes2::drawMainMenuScreen(); const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); - fheroes2::Display & display = fheroes2::Display::instance(); + const fheroes2::Display & display = fheroes2::Display::instance(); fheroes2::ButtonSprite buttonStandardGame = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y, fheroes2::AGG::GetICN( ICN::BUTTON_STANDARD_GAME, 0 ), fheroes2::AGG::GetICN( ICN::BUTTON_STANDARD_GAME, 1 ), display, { -5, 6 } ); @@ -654,7 +654,7 @@ fheroes2::GameMode Game::NewMulti() const CursorRestorer cursorRestorer( true, Cursor::POINTER ); fheroes2::drawMainMenuScreen(); - fheroes2::Display & display = fheroes2::Display::instance(); + const fheroes2::Display & display = fheroes2::Display::instance(); const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); fheroes2::ButtonSprite buttonHotSeat = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y, fheroes2::AGG::GetICN( ICN::BUTTON_HOT_SEAT, 0 ), From 774b4d5ed9186c6b50e31ac38f3926be1837815a Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 07:58:07 +0100 Subject: [PATCH 09/54] Fix y-change for pressed state in makeButtonSprites --- src/fheroes2/gui/ui_button.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fheroes2/gui/ui_button.cpp b/src/fheroes2/gui/ui_button.cpp index cc16e3e23c8..a6c6123e0f1 100644 --- a/src/fheroes2/gui/ui_button.cpp +++ b/src/fheroes2/gui/ui_button.cpp @@ -827,6 +827,6 @@ namespace fheroes2 const fheroes2::Text pressedText( text, { fheroes2::FontSize::BUTTON_PRESSED, fontColor } ); releasedText.draw( releasedOffset.x, ( buttonSize.height - releasedText.height( buttonSize.width ) ) / 2, buttonSize.width, released ); - pressedText.draw( pressedOffset.x, ( buttonSize.height - pressedText.height( buttonSize.width ) ) / 2, buttonSize.width, pressed ); + pressedText.draw( pressedOffset.x, ( buttonSize.height - pressedText.height( buttonSize.width ) ) / 2 + 1, buttonSize.width, pressed ); } } From 7a99d5437157869f48ae9d602cbf6df2f3c1cf7f Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 08:56:46 +0100 Subject: [PATCH 10/54] Add code to generate taller and thinner buttons --- src/fheroes2/gui/ui_button.cpp | 35 ++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/fheroes2/gui/ui_button.cpp b/src/fheroes2/gui/ui_button.cpp index a6c6123e0f1..12aa425e2c6 100644 --- a/src/fheroes2/gui/ui_button.cpp +++ b/src/fheroes2/gui/ui_button.cpp @@ -110,6 +110,41 @@ namespace fheroes2::Copy( original, originalWidth - secondHalfWidth, originalHeight - secondHalfHeight, output, buttonSize.width - secondHalfWidth, buttonSize.height - secondHalfHeight, secondHalfWidth, secondHalfHeight ); } + // Buttons that are taller but less wide. + else if ( buttonSize.height > originalHeight && buttonSize.width < originalWidth ) { + // Height increase + const int32_t middleHeight = originalHeight / 5; + const int32_t overallMiddleHeight = buttonSize.height - middleHeight * 2; + const int32_t middleHeightCount = overallMiddleHeight / middleHeight; + const int32_t middleHeightLeftOver = overallMiddleHeight - middleHeightCount * middleHeight; + + const int32_t middleWidth = originalWidth / 3; + + // The new button doesn't fit the two end corners. Are you using the wrong empty button to generate the new one? + assert( buttonSize.width >= middleWidth * 2 ); + + const int32_t rightSideWidth = buttonSize.width - middleWidth; + + fheroes2::Copy( original, 0, 0, output, 0, 0, middleWidth, middleHeight ); + fheroes2::Copy( original, rightSideWidth, 0, output, middleWidth, 0, rightSideWidth, middleHeight ); + + int32_t offsetY = middleHeight; + for ( int32_t i = 0; i < middleHeightCount; ++i ) { + fheroes2::Copy( original, 0, middleHeight, output, 0, offsetY, middleWidth, middleHeight ); + fheroes2::Copy( original, rightSideWidth, middleHeight, output, middleWidth, offsetY, rightSideWidth, middleHeight ); + offsetY += middleHeight; + } + + if ( middleHeightLeftOver > 0 ) { + fheroes2::Copy( original, 0, middleHeight, output, 0, offsetY, middleWidth, middleHeightLeftOver ); + fheroes2::Copy( original, rightSideWidth, middleHeight, output, middleWidth, offsetY, rightSideWidth, middleHeightLeftOver ); + offsetY += middleHeightLeftOver; + } + assert( offsetY + originalHeight - middleHeight * 4 == buttonSize.height ); + + fheroes2::Copy( original, 0, originalHeight - middleHeight, output, 0, offsetY, middleWidth, middleHeight ); + fheroes2::Copy( original, rightSideWidth, originalHeight - middleHeight, output, middleWidth, offsetY, rightSideWidth, middleHeight ); + } // Buttons that have increased width and height. else if ( buttonSize.height > originalHeight && buttonSize.width > originalWidth ) { const int32_t middleWidth = originalWidth / 3; From 908a0f07994199020df4dc19057146e85b8be8f9 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 09:48:36 +0100 Subject: [PATCH 11/54] generate puzzle exit --- src/fheroes2/agg/agg_image.cpp | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index c9744707ec4..7948a5dd1e1 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -968,28 +968,15 @@ namespace buttonStates.resize( 2 ); const bool isEvilInterface = ( id == ICN::BUTTON_EXIT_PUZZLE_DIM_DOOR_EVIL ); - const int originalButtonICN = isEvilInterface ? ICN::LGNDXTRE : ICN::LGNDXTRA; if ( useOriginalResources() ) { + const int originalButtonICN = isEvilInterface ? ICN::LGNDXTRE : ICN::LGNDXTRA; buttonStates[0] = fheroes2::AGG::GetICN( originalButtonICN, 4 ); buttonStates[1] = fheroes2::AGG::GetICN( originalButtonICN, 5 ); break; } - // Needs to be generated from original assets because the background has a much darker shadow than normal. - // TODO: Make the button generated as normal after removing the embedded shadow on the background. - for ( int32_t i = 0; i < static_cast( buttonStates.size() ); ++i ) { - fheroes2::Sprite & out = buttonStates[i]; - out = fheroes2::AGG::GetICN( originalButtonICN, 4 + i ); - - // clean the button. - Fill( out, 6 - i, 4 + i, 71 - i, 17, getButtonFillingColor( i == 0, !isEvilInterface ) ); - } - - const int32_t textWidth = 71; - renderTextOnButton( buttonStates[0], buttonStates[1], gettext_noop( "smallerButton|EXIT" ), { 6, 5 }, { 5, 6 }, - { textWidth, fheroes2::getFontHeight( fheroes2::FontSize::BUTTON_RELEASED ) }, - isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), isEvilInterface, 70 ); break; } From 183d2a959631f32d22d22cd80339c8be33dc7cd0 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 10:44:53 +0100 Subject: [PATCH 12/54] Remove German specific images It uses a worse version of the English one that we generate. --- src/fheroes2/agg/agg_image.cpp | 46 ---------------------------------- 1 file changed, 46 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 7948a5dd1e1..99b54d2430b 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -2002,47 +2002,6 @@ namespace } } - bool generateGermanSpecificImages( const int id ) - { - switch ( id ) { - case ICN::BTNBATTLEONLY: - _icnVsSprite[id].resize( 2 ); - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 + i ); - // Clean the button - Fill( out, 25, 18, 88, 23, getButtonFillingColor( i == 0 ) ); - // Add 'K' - Blit( fheroes2::AGG::GetICN( ICN::BTNDCCFG, 4 + i ), 34 - i, 23, out, 40 - i, 23, 12, 14 ); - //'Add 'A' - Blit( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 4 + i ), 56 - i, 23, out, 52 - i, 23, 13, 14 ); - Blit( out, 20, 20, out, 52 - i + 12, 25, 3, 3 ); - // Add 'M' - Blit( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 4 + i ), 39 - i, 8, out, 65 - i, 23, 14, 14 ); - // Add 'F' - Blit( fheroes2::AGG::GetICN( ICN::BTNDCCFG, 4 + i ), 70 - i, 23, out, 87 - i, 23, 10, 14 ); - // Add 'P' - Blit( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 4 + i ), 36 - i, 23, out, 78 - i, 23, 10, 14 ); - } - return true; - case ICN::BUTTON_SMALL_MIN_GOOD: - _icnVsSprite[id].resize( 2 ); - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::RECRUIT, 4 + i ); - // clean the button - Blit( fheroes2::AGG::GetICN( ICN::SYSTEM, 11 + i ), 10, 6 + i, out, 30 - 2 * i, 5 + i, 31, 15 ); - // add 'IN' - Copy( fheroes2::AGG::GetICN( ICN::APANEL, 4 + i ), 23 - i, 22 + i, out, 33 - i, 6 + i, 8, 14 ); // letter 'I' - Copy( fheroes2::AGG::GetICN( ICN::APANEL, 4 + i ), 31 - i, 22 + i, out, 44 - i, 6 + i, 17, 14 ); // letter 'N' - } - return true; - default: - break; - } - return false; - } - bool generateFrenchSpecificImages( const int id ) { switch ( id ) { @@ -2293,11 +2252,6 @@ namespace // Language-specific image generators, may fail if ( fheroes2::getCurrentLanguage() == resourceLanguage ) { switch ( resourceLanguage ) { - case fheroes2::SupportedLanguage::German: - if ( generateGermanSpecificImages( id ) ) { - return; - } - break; case fheroes2::SupportedLanguage::French: if ( generateFrenchSpecificImages( id ) ) { return; From 620c41638000d22e3347f6e41b294155cc75ff4b Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 10:48:00 +0100 Subject: [PATCH 13/54] Remove Italian specific images It uses just a worse font than the English one we generate. --- src/fheroes2/agg/agg_image.cpp | 51 ---------------------------------- 1 file changed, 51 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 99b54d2430b..dcf862173d9 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -2197,52 +2197,6 @@ namespace return false; } - bool generateItalianSpecificImages( const int id ) - { - switch ( id ) { - case ICN::BTNBATTLEONLY: - _icnVsSprite[id].resize( 2 ); - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 + i ); - // clean the button - const uint8_t buttonFillingColor = getButtonFillingColor( i == 0 ); - Fill( out, 25, 18, 88, 23, buttonFillingColor ); - const int32_t offsetX = 16; - const int32_t offsetY = 21; - // Add 'B' - Blit( fheroes2::AGG::GetICN( ICN::BTNBAUD, 0 + i ), 42 - i, 28, out, offsetX - i, offsetY, 13, 15 ); - Fill( out, offsetX + 11, offsetY + 13, 1, 2, buttonFillingColor ); - // Add 'A' - Blit( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 0 + i ), 80 - i, 28, out, offsetX + 13 - i, offsetY, 14, 15 ); - Fill( out, offsetX + 13 - i, offsetY + 3, 1, 4, buttonFillingColor ); - // Add 'T' - Blit( fheroes2::AGG::GetICN( ICN::BTNMP, 0 + i ), 74 - i, 5, out, offsetX + 27 - 2 * i, offsetY, 12, 15 ); - // Add 'T' - Blit( fheroes2::AGG::GetICN( ICN::BTNMP, 0 + i ), 74 - i, 5, out, offsetX + 39 - 2 * i, offsetY, 12, 15 ); - // Add 'A' - Blit( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 0 + i ), 80 - i, 28, out, offsetX + 50 - i, offsetY, 14, 15 ); - Fill( out, offsetX + 65 - i, offsetY + 5, 1, 2, buttonFillingColor ); - Fill( out, offsetX + 65 - i, offsetY + 14, 1, 3, buttonFillingColor ); - Fill( out, offsetX + 50 - i, offsetY + 3, 1, 4, buttonFillingColor ); - // Add 'G' - Blit( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 0 + i ), 44 - i, 12, out, offsetX + 65 - i, offsetY, 11, 15 ); - // Add 'L' - Blit( fheroes2::AGG::GetICN( ICN::BTNDC, 4 + i ), 77 - i, 21, out, offsetX + 77 - 2 * i, offsetY, 9, 15 ); - // Add 'I' - Blit( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 0 + i ), 56 - i, 12, out, offsetX + 86 - i, offsetY, 7, 15 ); - // Add 'A' - Blit( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 0 + i ), 80 - i, 28, out, offsetX + 93 - i, offsetY, 14, 15 ); - Fill( out, offsetX + 109 - i, offsetY + 5, 1, 2, buttonFillingColor ); - Fill( out, offsetX + 93 - i, offsetY + 3, 1, 4, buttonFillingColor ); - } - return true; - default: - break; - } - return false; - } - void generateLanguageSpecificImages( int id ) { assert( isLanguageDependentIcnId( id ) ); @@ -2262,11 +2216,6 @@ namespace return; } break; - case fheroes2::SupportedLanguage::Italian: - if ( generateItalianSpecificImages( id ) ) { - return; - } - break; default: break; } From edbf1c492319a994fe0e9b040f96767a1cf9d9a6 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 11:53:14 +0100 Subject: [PATCH 14/54] Remove shadows for language-specific battle only buttons. --- src/fheroes2/agg/agg_image.cpp | 59 +++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index dcf862173d9..3fd2e7eb67c 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -2009,37 +2009,40 @@ namespace _icnVsSprite[id].resize( 2 ); for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 + i ); + const fheroes2::Sprite originalSprite = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 + i ); + const int32_t newWidth = originalSprite.width() - 5; + const int32_t newHeight = originalSprite.height() - 6; + out.resize( newWidth, newHeight ); + Copy( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 + i ), 5, 0, out, 0, 0, newWidth, newHeight ); // Clean the button - Fill( out, 25, 18, 88, 23, getButtonFillingColor( i == 0 ) ); - + Fill( out, 27 - i, 21 + i, 77, 14, getButtonFillingColor( i == 0 ) ); const int32_t secondLine = 28; // Add 'MODE' - Blit( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 4 + i ), 40 - i, 13, out, 45 - i, 13, 50, 15 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 4 + i ), 40 - i, 13, out, 40 - i, 13, 50, 15 ); // Clean up 'MODE' - Blit( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 114 - i, 18, out, 94 - i, 18, 1, 10 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 114 - i, 18, out, 89 - i, 18, 1, 10 ); // Add 'BA' - Blit( fheroes2::AGG::GetICN( ICN::BTNBAUD, 2 + i ), 42 - i, 28, out, 28 - i, secondLine, 22, 15 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNBAUD, 2 + i ), 42 - i, 28, out, 23 - i, secondLine, 22, 15 ); // Clean up 'BA' - Blit( fheroes2::AGG::GetICN( ICN::BTNBAUD, 2 + i ), 42 - i, 31, out, 39 - i, secondLine, 1, 1 ); - Blit( fheroes2::AGG::GetICN( ICN::BTNBAUD, 2 + i ), 39 - i, 31, out, 49 - i, secondLine + 4, 1, 2 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNBAUD, 2 + i ), 42 - i, 31, out, 34 - i, secondLine, 1, 1 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNBAUD, 2 + i ), 39 - i, 31, out, 44 - i, secondLine + 4, 1, 2 ); // Add 'T' - Blit( fheroes2::AGG::GetICN( ICN::BTNDC, 2 + i ), 89 - i, 21, out, 50 - i, secondLine, 12, 15 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNDC, 2 + i ), 89 - i, 21, out, 45 - i, secondLine, 12, 15 ); // Clean up 'AT' - Blit( fheroes2::AGG::GetICN( ICN::BTNDC, 2 + i ), 89 - i, 18, out, 50 - i, secondLine, 1, 1 ); - Blit( fheroes2::AGG::GetICN( ICN::BTNDC, 2 + i ), 92 - ( 5 * i ), 27 - i, out, 49 - i, secondLine + 4 + i, 1, 3 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNDC, 2 + i ), 89 - i, 18, out, 45 - i, secondLine, 1, 1 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNDC, 2 + i ), 92 - ( 5 * i ), 27 - i, out, 44 - i, secondLine + 4 + i, 1, 3 ); // Add 'AI'. - Blit( fheroes2::AGG::GetICN( ICN::BTNMP, 6 + i ), 56 - i, 13, out, 62 - i, secondLine, 18, 15 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNMP, 6 + i ), 56 - i, 13, out, 57 - i, secondLine, 18, 15 ); // Clean up 'TA' - Blit( fheroes2::AGG::GetICN( ICN::BTNBAUD, 2 + i ), 51 - i, 40, out, 60 - i, secondLine + 12, 3, 3 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNBAUD, 2 + i ), 51 - i, 40, out, 55 - i, secondLine + 12, 3, 3 ); // Add 'LLE' - Blit( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 85 - i, 13, out, 81 - i, secondLine, 31, 15 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 85 - i, 13, out, 76 - i, secondLine, 31, 15 ); // Clean up "IL" - Blit( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 85 - i, 18, out, 81 - i, secondLine + 7, 1, 1 ); - Blit( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 94 - i, 17, out, 80 - i, secondLine + 4, 2, 2 ); - Blit( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 93 - i, 25, out, 79 - i, secondLine + 12, 3, 3 ); - Blit( fheroes2::AGG::GetICN( ICN::BTNDC, 4 + i ), 23 - i, 8, out, 79 - i, secondLine + 5, 1, 10 ); - Blit( fheroes2::AGG::GetICN( ICN::BTNMP, 6 + i ), 73 - i, 22, out, 79 - i, secondLine + 9, 1, 1 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 85 - i, 18, out, 76 - i, secondLine + 7, 1, 1 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 94 - i, 17, out, 75 - i, secondLine + 4, 2, 2 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 93 - i, 25, out, 74 - i, secondLine + 12, 3, 3 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNDC, 4 + i ), 23 - i, 8, out, 74 - i, secondLine + 5, 1, 10 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNMP, 6 + i ), 73 - i, 22, out, 74 - i, secondLine + 9, 1, 1 ); } return true; case ICN::BTNGIFT_GOOD: @@ -2176,19 +2179,23 @@ namespace _icnVsSprite[id].resize( 2 ); for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 + i ); + const fheroes2::Sprite originalSprite = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 + i ); + const int32_t newWidth = originalSprite.width() - 5; + const int32_t newHeight = originalSprite.height() - 6; + out.resize( newWidth, newHeight ); + Copy( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 + i ), 5, 0, out, 0, 0, newWidth, newHeight ); // clean the button - Fill( out, 25, 18, 88, 23, getButtonFillingColor( i == 0 ) ); - const int32_t offsetX = 46; + Fill( out, 36 - i, 23 + i, 57, 11, getButtonFillingColor( i == 0 ) ); + const int32_t offsetX = 41; const int32_t offsetY = 23; // Add 'BI' - Blit( fheroes2::AGG::GetICN( ICN::BTNMCFG, 2 + i ), 58 - i, 29, out, offsetX - i, offsetY, 14, 11 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNMCFG, 2 + i ), 58 - i, 29, out, offsetX - i, offsetY, 14, 11 ); // Add 'T' - Blit( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 0 + i ), 24 - i, 29, out, offsetX + 14 - i, offsetY, 9, 11 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 0 + i ), 24 - i, 29, out, offsetX + 14 - i, offsetY, 9, 11 ); // Add 'WA' - Blit( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 45 - i, 23, out, offsetX + 23 - i, offsetY, 24, 11 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 45 - i, 23, out, offsetX + 23 - i, offsetY, 24, 11 ); // Add pixel to 'W' - Blit( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 47 - i, 23 + i, out, offsetX + 38 - i, offsetY + i, 1, 1 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 47 - i, 23 + i, out, offsetX + 38 - i, offsetY + i, 1, 1 ); } return true; default: From fc0066f580756b10850d140e9aac8272723352a3 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 12:13:24 +0100 Subject: [PATCH 15/54] Re-add German specific buttons Can't be removed until button texts can be crammed --- src/fheroes2/agg/agg_image.cpp | 50 ++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 3fd2e7eb67c..bcacb65f4e8 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -2002,6 +2002,51 @@ namespace } } + bool generateGermanSpecificImages( const int id ) + { + switch ( id ) { + case ICN::BTNBATTLEONLY: + _icnVsSprite[id].resize( 2 ); + for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { + fheroes2::Sprite & out = _icnVsSprite[id][i]; + const fheroes2::Sprite originalSprite = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 + i ); + const int32_t newWidth = originalSprite.width() - 5; + const int32_t newHeight = originalSprite.height() - 6; + out.resize( newWidth, newHeight ); + Copy( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 + i ), 5, 0, out, 0, 0, newWidth, newHeight ); + // Clean the button + Fill( out, 21 - i, 23 + i, 84, 11, getButtonFillingColor( i == 0 ) ); + // Add 'K' + Copy( fheroes2::AGG::GetICN( ICN::BTNDCCFG, 4 + i ), 34 - i, 23, out, 35 - i, 23, 12, 14 ); + //'Add 'A' + Copy( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 4 + i ), 56 - i, 23, out, 47 - i, 23, 13, 14 ); + Copy( out, 20, 20, out, 47 - i + 12, 25, 3, 3 ); + // Add 'M' + Copy( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 4 + i ), 39 - i, 8, out, 60 - i, 23, 14, 14 ); + // Add 'F' + Copy( fheroes2::AGG::GetICN( ICN::BTNDCCFG, 4 + i ), 70 - i, 23, out, 82 - i, 23, 10, 14 ); + // Add 'P' + Copy( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 4 + i ), 36 - i, 23, out, 73 - i, 23, 10, 14 ); + } + return true; + case ICN::BUTTON_SMALL_MIN_GOOD: + _icnVsSprite[id].resize( 2 ); + for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { + fheroes2::Sprite & out = _icnVsSprite[id][i]; + out = fheroes2::AGG::GetICN( ICN::RECRUIT, 4 + i ); + // clean the button + Blit( fheroes2::AGG::GetICN( ICN::SYSTEM, 11 + i ), 10, 6 + i, out, 30 - 2 * i, 5 + i, 31, 15 ); + // add 'IN' + Copy( fheroes2::AGG::GetICN( ICN::APANEL, 4 + i ), 23 - i, 22 + i, out, 33 - i, 6 + i, 8, 14 ); // letter 'I' + Copy( fheroes2::AGG::GetICN( ICN::APANEL, 4 + i ), 31 - i, 22 + i, out, 44 - i, 6 + i, 17, 14 ); // letter 'N' + } + return true; + default: + break; + } + return false; + } + bool generateFrenchSpecificImages( const int id ) { switch ( id ) { @@ -2213,6 +2258,11 @@ namespace // Language-specific image generators, may fail if ( fheroes2::getCurrentLanguage() == resourceLanguage ) { switch ( resourceLanguage ) { + case fheroes2::SupportedLanguage::German: + if ( generateGermanSpecificImages( id ) ) { + return; + } + break; case fheroes2::SupportedLanguage::French: if ( generateFrenchSpecificImages( id ) ) { return; From a495b2c871def1788010592ffa9a91638b621fc7 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 12:27:24 +0100 Subject: [PATCH 16/54] Remove fixed TODO comment --- src/fheroes2/agg/agg_image.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index bcacb65f4e8..456b9e3b4d1 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -1537,7 +1537,6 @@ namespace _icnVsSprite[id].resize( 2 ); const bool isEvilInterface = ( id == ICN::BUTTON_VIEWWORLD_EXIT_EVIL ); - // TODO: Can't be drawn because it is both taller and smaller than the standard button which resizeButton does not handle yet. createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), isEvilInterface, 70, 35 ); break; From f31f8edd42da132dec01e34cc28eedbff627562d Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 14:47:21 +0100 Subject: [PATCH 17/54] Re-add original button shadows --- src/fheroes2/agg/agg_image.cpp | 430 +++++++++------------------- src/fheroes2/game/game_loadgame.cpp | 34 +-- src/fheroes2/game/game_newgame.cpp | 61 ++-- 3 files changed, 160 insertions(+), 365 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 456b9e3b4d1..074086a5d98 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -1170,334 +1170,172 @@ namespace break; } - case ICN::BUTTON_STANDARD_GAME: { + case ICN::BUTTON_STANDARD_GAME: + case ICN::BUTTON_CAMPAIGN_GAME: + case ICN::BUTTON_MULTIPLAYER_GAME: + case ICN::BUTTON_LARGE_CANCEL: + case ICN::BUTTON_LARGE_CONFIG: + case ICN::BUTTON_ORIGINAL_CAMPAIGN: + case ICN::BUTTON_EXPANSION_CAMPAIGN: + case ICN::BUTTON_HOT_SEAT: + case ICN::BUTTON_2_PLAYERS: + case ICN::BUTTON_3_PLAYERS: + case ICN::BUTTON_4_PLAYERS: + case ICN::BUTTON_5_PLAYERS: + case ICN::BUTTON_6_PLAYERS: { _icnVsSprite[id].resize( 2 ); if ( useOriginalResources() ) { - // Remove embedded shadows so that we can add them later. - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - - const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 0 ); - const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 1 ); - - released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); + int buttonIcnID = ICN::BTNNEWGM; + fheroes2::Point icnIndex( 0, 1 ); + switch ( id ) { + case ICN::BUTTON_CAMPAIGN_GAME: { + icnIndex = { 2, 3 }; + break; + } + case ICN::BUTTON_MULTIPLAYER_GAME: { + icnIndex = { 4, 5 }; + break; + } + case ICN::BUTTON_LARGE_CANCEL: { + icnIndex = { 6, 7 }; + break; + } + case ICN::BUTTON_LARGE_CONFIG: { + buttonIcnID = ICN::BTNDCCFG; + icnIndex = { 4, 5 }; + break; + } + case ICN::BUTTON_ORIGINAL_CAMPAIGN: { + buttonIcnID = ICN::X_LOADCM; + icnIndex = { 0, 1 }; + break; + } + case ICN::BUTTON_EXPANSION_CAMPAIGN: { + buttonIcnID = ICN::X_LOADCM; + icnIndex = { 2, 3 }; + break; + } + case ICN::BUTTON_HOT_SEAT: { + buttonIcnID = ICN::BTNMP; + break; + } + case ICN::BUTTON_2_PLAYERS: { + buttonIcnID = ICN::BTNHOTST; + break; + } + case ICN::BUTTON_3_PLAYERS: { + buttonIcnID = ICN::BTNHOTST; + icnIndex = { 2, 3 }; + break; + } + case ICN::BUTTON_4_PLAYERS: { + buttonIcnID = ICN::BTNHOTST; + icnIndex = { 4, 5 }; + break; + } + case ICN::BUTTON_5_PLAYERS: { + buttonIcnID = ICN::BTNHOTST; + icnIndex = { 6, 7 }; + break; + } + case ICN::BUTTON_6_PLAYERS: { + buttonIcnID = ICN::BTNHOTST; + icnIndex = { 8, 9 }; + break; + } + default: + break; + } - Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); + _icnVsSprite[id][0] = fheroes2::AGG::GetICN( buttonIcnID, icnIndex.x ); + _icnVsSprite[id][1] = fheroes2::AGG::GetICN( buttonIcnID, icnIndex.y ); + if ( id == ICN::BUTTON_CAMPAIGN_GAME ) { + // Fix the disabled state. + fheroes2::Image common = fheroes2::ExtractCommonPattern( { &_icnVsSprite[id][0], &_icnVsSprite[id][1] } ); + common = fheroes2::FilterOnePixelNoise( common ); + common = fheroes2::FilterOnePixelNoise( common ); + common = fheroes2::FilterOnePixelNoise( common ); + fheroes2::Blit( common, _icnVsSprite[id][0] ); + } - setButtonCornersTransparent( released ); break; } - - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "STANDARD\nGAME" ), false, 117, 56 ); - - break; - } - case ICN::BUTTON_CAMPAIGN_GAME: { - _icnVsSprite[id].resize( 2 ); - - if ( useOriginalResources() ) { - // Remove embedded shadows so that we can add them later. - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - - const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 2 ); - const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 3 ); - - released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - - Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - // Fix the disabled state. - fheroes2::Image common = fheroes2::ExtractCommonPattern( { &released, &pressed } ); - common = fheroes2::FilterOnePixelNoise( common ); - common = fheroes2::FilterOnePixelNoise( common ); - common = fheroes2::FilterOnePixelNoise( common ); - - setButtonCornersTransparent( released ); + const char * text = gettext_noop( "STANDARD\nGAME" ); + switch ( id ) { + case ICN::BUTTON_STANDARD_GAME: { + text = gettext_noop( "STANDARD\nGAME" ); break; } - - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "CAMPAIGN\nGAME" ), false, 117, 56 ); - - break; - } - case ICN::BUTTON_MULTIPLAYER_GAME: { - _icnVsSprite[id].resize( 2 ); - - if ( useOriginalResources() ) { - // Remove embedded shadows so that we can add them later. - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - - const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 4 ); - const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 5 ); - - released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - - Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - - setButtonCornersTransparent( released ); + case ICN::BUTTON_CAMPAIGN_GAME: { + text = gettext_noop( "CAMPAIGN\nGAME" ); break; } - - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MULTI-\nPLAYER\nGAME" ), false, 117, 56 ); - - break; - } - case ICN::BUTTON_LARGE_CANCEL: { - _icnVsSprite[id].resize( 2 ); - - if ( useOriginalResources() ) { - // Remove embedded shadows so that we can add them later. - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - - const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 ); - const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 7 ); - - released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - - Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - - setButtonCornersTransparent( released ); + case ICN::BUTTON_MULTIPLAYER_GAME: { + text = gettext_noop( "MULTI-\nPLAYER\nGAME" ); break; } - - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "CANCEL" ), false, 117, 56 ); - - break; - } - case ICN::BUTTON_LARGE_CONFIG: { - _icnVsSprite[id].resize( 2 ); - - if ( useOriginalResources() ) { - // Remove embedded shadows so that we can add them later. - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - - const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNDCCFG, 4 ); - const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNDCCFG, 5 ); - - released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - - Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - - setButtonCornersTransparent( released ); + case ICN::BUTTON_LARGE_CANCEL: { + text = gettext_noop( "CANCEL" ); break; } - - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "CONFIG" ), false, 117, 56 ); - - break; - } - case ICN::BUTTON_ORIGINAL_CAMPAIGN: { - _icnVsSprite[id].resize( 2 ); - - if ( useOriginalResources() ) { - // Remove embedded shadows so that we can add them later. - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - - const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::X_LOADCM, 0 ); - const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::X_LOADCM, 1 ); - - released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - - Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - - setButtonCornersTransparent( released ); - + case ICN::BUTTON_LARGE_CONFIG: { + text = gettext_noop( "CONFIG" ); break; } - - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "ORIGINAL\nCAMPAIGN" ), false, 117, 56 ); - - break; - } - case ICN::BUTTON_EXPANSION_CAMPAIGN: { - _icnVsSprite[id].resize( 2 ); - - if ( useOriginalResources() ) { - // Remove embedded shadows so that we can add them later. - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - - const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::X_LOADCM, 2 ); - const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::X_LOADCM, 3 ); - - released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - - Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - - setButtonCornersTransparent( released ); + case ICN::BUTTON_ORIGINAL_CAMPAIGN: { + text = gettext_noop( "ORIGINAL\nCAMPAIGN" ); break; } - - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "EXPANSION\nCAMPAIGN" ), false, 117, 56 ); - - break; - } - case ICN::BUTTON_HOT_SEAT: { - _icnVsSprite[id].resize( 2 ); - - if ( useOriginalResources() ) { - // Remove embedded shadows so that we can add them later. - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - - const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNMP, 0 ); - const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNMP, 1 ); - - released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - - Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - - setButtonCornersTransparent( released ); + case ICN::BUTTON_EXPANSION_CAMPAIGN: { + text = gettext_noop( "EXPANSION\nCAMPAIGN" ); break; } - - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "HOT SEAT" ), false, 117, 56 ); - - break; - } - case ICN::BUTTON_2_PLAYERS: { - _icnVsSprite[id].resize( 2 ); - - if ( useOriginalResources() ) { - // Remove embedded shadows so that we can add them later. - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - - const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNHOTST, 0 ); - const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNHOTST, 1 ); - - released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - - Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - - setButtonCornersTransparent( released ); + case ICN::BUTTON_HOT_SEAT: { + text = gettext_noop( "HOT SEAT" ); break; } - - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "2 PLAYERS" ), false, 117, 56 ); - - break; - } - case ICN::BUTTON_3_PLAYERS: { - _icnVsSprite[id].resize( 2 ); - - if ( useOriginalResources() ) { - // Remove embedded shadows so that we can add them later. - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - - const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNHOTST, 2 ); - const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNHOTST, 3 ); - - released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - - Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - - setButtonCornersTransparent( released ); + case ICN::BUTTON_2_PLAYERS: { + text = gettext_noop( "2 PLAYERS" ); break; } - - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "3 PLAYERS" ), false, 117, 56 ); - - break; - } - case ICN::BUTTON_4_PLAYERS: { - _icnVsSprite[id].resize( 2 ); - - if ( useOriginalResources() ) { - // Remove embedded shadows so that we can add them later. - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - - const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNHOTST, 4 ); - const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNHOTST, 5 ); - - released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - - Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - - setButtonCornersTransparent( released ); + case ICN::BUTTON_3_PLAYERS: { + text = gettext_noop( "3 PLAYERS" ); break; } - - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "4 PLAYERS" ), false, 117, 56 ); - - break; - } - case ICN::BUTTON_5_PLAYERS: { - _icnVsSprite[id].resize( 2 ); - - if ( useOriginalResources() ) { - // Remove embedded shadows so that we can add them later. - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - - const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNHOTST, 6 ); - const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNHOTST, 7 ); - - released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - - Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - - setButtonCornersTransparent( released ); + case ICN::BUTTON_4_PLAYERS: { + text = gettext_noop( "4 PLAYERS" ); break; } - - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "5 PLAYERS" ), false, 117, 56 ); - - break; - } - case ICN::BUTTON_6_PLAYERS: { - _icnVsSprite[id].resize( 2 ); - - if ( useOriginalResources() ) { - // Remove embedded shadows so that we can add them later. - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - - const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNHOTST, 8 ); - const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::BTNHOTST, 9 ); - - released.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - pressed.resize( originalReleased.width() - 5, originalReleased.height() - 6 ); - - Copy( originalReleased, 5, 0, _icnVsSprite[id][0], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - Copy( originalPressed, 5, 0, _icnVsSprite[id][1], 0, 0, originalReleased.width() - 5, originalReleased.height() - 6 ); - - setButtonCornersTransparent( released ); + case ICN::BUTTON_5_PLAYERS: { + text = gettext_noop( "5 PLAYERS" ); + break; + } + case ICN::BUTTON_6_PLAYERS: { + text = gettext_noop( "6 PLAYERS" ); + break; + } + default: break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "6 PLAYERS" ), false, 117, 56 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], text, false, 117, 56 ); + + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; + // Add original shadow. + const fheroes2::Sprite & originalShadow = fheroes2::AGG::GetICN( ICN::BTNCOM, 0 ); + fheroes2::Image temp( originalShadow.width(), originalShadow.height() ); + + Copy( released, 0, 0, temp, 5, 6, released.width(), released.height() ); + fheroes2::Copy( originalShadow, 0, 0, temp, 0, 0, 5, originalShadow.height() ); + fheroes2::Copy( originalShadow, 5, originalShadow.height() - 6, temp, 5, originalShadow.height() - 6, originalShadow.width() - 5, 6 ); + fheroes2::Copy( temp, released ); + + Copy( pressed, 0, 0, temp, 5, 6, released.width(), released.height() ); + fheroes2::Copy( originalShadow, 0, 0, temp, 0, 0, 5, originalShadow.height() ); + fheroes2::Copy( originalShadow, 5, originalShadow.height() - 6, temp, 5, originalShadow.height() - 6, originalShadow.width() - 5, 6 ); + fheroes2::Copy( temp, pressed ); break; } diff --git a/src/fheroes2/game/game_loadgame.cpp b/src/fheroes2/game/game_loadgame.cpp index f2c60295ed1..3a15a0d1ff9 100644 --- a/src/fheroes2/game/game_loadgame.cpp +++ b/src/fheroes2/game/game_loadgame.cpp @@ -82,8 +82,6 @@ fheroes2::GameMode Game::LoadHotseat() fheroes2::GameMode Game::LoadMulti() { - fheroes2::Display & display = fheroes2::Display::instance(); - // setup cursor const CursorRestorer cursorRestorer( true, Cursor::POINTER ); @@ -91,20 +89,16 @@ fheroes2::GameMode Game::LoadMulti() fheroes2::drawMainMenuScreen(); const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); - fheroes2::ButtonSprite buttonHotSeat = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y, fheroes2::AGG::GetICN( ICN::BUTTON_HOT_SEAT, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_HOT_SEAT, 1 ), display, { -5, 6 } ); - fheroes2::ButtonSprite buttonNetwork = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BTNMP, 2 ), - fheroes2::AGG::GetICN( ICN::BTNMP, 3 ), display, { -5, 6 } ); - fheroes2::ButtonSprite buttonCancel - = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 5, fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 1 ), display, { -5, 6 } ); + fheroes2::Button buttonHotSeat( buttonPos.x, buttonPos.y, ICN::BUTTON_HOT_SEAT, 0, 1 ); + fheroes2::Button buttonNetwork( buttonPos.x, buttonPos.y + buttonYStep, ICN::BTNMP, 2, 3 ); + fheroes2::Button buttonCancel( buttonPos.x, buttonPos.y + buttonYStep * 5, ICN::BUTTON_LARGE_CANCEL, 0, 1 ); buttonHotSeat.draw(); buttonCancel.draw(); buttonNetwork.disable(); - display.render(); + fheroes2::Display::instance().render(); LocalEvent & le = LocalEvent::Get(); while ( le.HandleEvents() ) { @@ -155,21 +149,11 @@ fheroes2::GameMode Game::LoadGame() fheroes2::drawMainMenuScreen(); const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); - const fheroes2::Display & display = fheroes2::Display::instance(); - - fheroes2::ButtonSprite buttonStandardGame - = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BUTTON_STANDARD_GAME, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_STANDARD_GAME, 1 ), display, { -5, 6 } ); - fheroes2::ButtonSprite buttonCampaignGame - = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BUTTON_CAMPAIGN_GAME, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_CAMPAIGN_GAME, 1 ), display, { -5, 6 } ); - fheroes2::ButtonSprite buttonMultiplayerGame - = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BUTTON_MULTIPLAYER_GAME, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_MULTIPLAYER_GAME, 1 ), display, { -5, 6 } ); - fheroes2::ButtonSprite buttonCancel - = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 1 ), display, { -5, 6 } ); + fheroes2::Button buttonStandardGame( buttonPos.x, buttonPos.y, ICN::BUTTON_STANDARD_GAME, 0, 1 ); + fheroes2::Button buttonCampaignGame( buttonPos.x, buttonPos.y + buttonYStep, ICN::BUTTON_CAMPAIGN_GAME, 0, 1 ); + fheroes2::Button buttonMultiplayerGame( buttonPos.x, buttonPos.y + buttonYStep, ICN::BUTTON_MULTIPLAYER_GAME, 0, 1 ); + fheroes2::Button buttonCancel( buttonPos.x, buttonPos.y + buttonYStep * 5, ICN::BUTTON_LARGE_CANCEL, 0, 1 ); const std::array buttons{ &buttonStandardGame, &buttonCampaignGame, &buttonMultiplayerGame, &buttonCancel }; if ( !isSuccessionWarsCampaignPresent() ) { @@ -182,7 +166,7 @@ fheroes2::GameMode Game::LoadGame() buttons[i]->draw(); } - // following the cancel button in newgame + // following the cancel button in new game buttonCancel.setPosition( buttonPos.x, buttonPos.y + buttonYStep * 5 ); buttonCancel.draw(); diff --git a/src/fheroes2/game/game_newgame.cpp b/src/fheroes2/game/game_newgame.cpp index ba9c5cae678..5a5786fcc66 100644 --- a/src/fheroes2/game/game_newgame.cpp +++ b/src/fheroes2/game/game_newgame.cpp @@ -199,16 +199,10 @@ fheroes2::GameMode Game::CampaignSelection() fheroes2::drawMainMenuScreen(); const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); - const fheroes2::Display & display = fheroes2::Display::instance(); - fheroes2::ButtonSprite buttonSuccessionWars = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y, fheroes2::AGG::GetICN( ICN::BUTTON_ORIGINAL_CAMPAIGN, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_ORIGINAL_CAMPAIGN, 1 ), display, { -5, 6 } ); - fheroes2::ButtonSprite buttonPriceOfLoyalty - = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BUTTON_EXPANSION_CAMPAIGN, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_EXPANSION_CAMPAIGN, 1 ), display, { -5, 6 } ); - fheroes2::ButtonSprite buttonCancel - = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 5, fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 1 ), display, { -5, 6 } ); + fheroes2::Button buttonSuccessionWars( buttonPos.x, buttonPos.y, ICN::BUTTON_ORIGINAL_CAMPAIGN, 0, 1 ); + fheroes2::Button buttonPriceOfLoyalty( buttonPos.x, buttonPos.y + buttonYStep, ICN::BUTTON_EXPANSION_CAMPAIGN, 0, 1 ); + fheroes2::Button buttonCancel( buttonPos.x, buttonPos.y + buttonYStep * 5, ICN::BUTTON_LARGE_CANCEL, 0, 1 ); buttonSuccessionWars.draw(); buttonPriceOfLoyalty.draw(); @@ -487,15 +481,10 @@ fheroes2::GameMode Game::NewNetwork() fheroes2::drawMainMenuScreen(); const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); - const fheroes2::Display & display = fheroes2::Display::instance(); - fheroes2::ButtonSprite buttonHost = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y, fheroes2::AGG::GetICN( ICN::BTNNET, 0 ), - fheroes2::AGG::GetICN( ICN::BTNNET, 1 ), display, { -5, 6 } ); - fheroes2::ButtonSprite buttonGuest = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BTNNET, 2 ), - fheroes2::AGG::GetICN( ICN::BTNNET, 3 ), display, { -5, 6 } ); - fheroes2::ButtonSprite buttonCancel - = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 5, fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 1 ), display, { -5, 6 } ); + fheroes2::Button buttonHost( buttonPos.x, buttonPos.y, ICN::BTNNET, 0, 1 ); + fheroes2::Button buttonGuest( buttonPos.x, buttonPos.y + buttonYStep, ICN::BTNNET, 2, 3 ); + fheroes2::Button buttonCancel( buttonPos.x, buttonPos.y + buttonYStep * 5, ICN::BUTTON_LARGE_CANCEL, 0, 1 ); buttonHost.draw(); buttonGuest.draw(); @@ -547,24 +536,13 @@ fheroes2::GameMode Game::NewGame( const bool isProbablyDemoVersion ) fheroes2::drawMainMenuScreen(); const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); - const fheroes2::Display & display = fheroes2::Display::instance(); - - fheroes2::ButtonSprite buttonStandardGame = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y, fheroes2::AGG::GetICN( ICN::BUTTON_STANDARD_GAME, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_STANDARD_GAME, 1 ), display, { -5, 6 } ); - fheroes2::ButtonSprite buttonCampaignGame - = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BUTTON_CAMPAIGN_GAME, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_CAMPAIGN_GAME, 1 ), display, { -5, 6 } ); - fheroes2::ButtonSprite buttonMultiGame - = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 2, fheroes2::AGG::GetICN( ICN::BUTTON_MULTIPLAYER_GAME, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_MULTIPLAYER_GAME, 1 ), display, { -5, 6 } ); - fheroes2::ButtonSprite buttonBattleGame = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 3, fheroes2::AGG::GetICN( ICN::BTNBATTLEONLY, 0 ), - fheroes2::AGG::GetICN( ICN::BTNBATTLEONLY, 1 ), display, { -5, 6 } ); - fheroes2::ButtonSprite buttonSettings - = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 4, fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CONFIG, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CONFIG, 1 ), display, { -5, 6 } ); - fheroes2::ButtonSprite buttonCancel - = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 5, fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 1 ), display, { -5, 6 } ); + + fheroes2::Button buttonStandardGame( buttonPos.x, buttonPos.y, ICN::BUTTON_STANDARD_GAME, 0, 1 ); + fheroes2::Button buttonCampaignGame( buttonPos.x, buttonPos.y + buttonYStep * 1, ICN::BUTTON_CAMPAIGN_GAME, 0, 1 ); + fheroes2::Button buttonMultiGame( buttonPos.x, buttonPos.y + buttonYStep * 2, ICN::BUTTON_MULTIPLAYER_GAME, 0, 1 ); + fheroes2::Button buttonBattleGame( buttonPos.x, buttonPos.y + buttonYStep * 3, ICN::BTNBATTLEONLY, 0, 1 ); + fheroes2::Button buttonSettings( buttonPos.x, buttonPos.y + buttonYStep * 4, ICN::BUTTON_LARGE_CONFIG, 0, 1 ); + fheroes2::Button buttonCancel( buttonPos.x, buttonPos.y + buttonYStep * 5, ICN::BUTTON_LARGE_CANCEL, 0, 1 ); if ( !isSuccessionWarsCampaignPresent() ) { buttonCampaignGame.disable(); @@ -654,16 +632,11 @@ fheroes2::GameMode Game::NewMulti() const CursorRestorer cursorRestorer( true, Cursor::POINTER ); fheroes2::drawMainMenuScreen(); - const fheroes2::Display & display = fheroes2::Display::instance(); const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); - fheroes2::ButtonSprite buttonHotSeat = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y, fheroes2::AGG::GetICN( ICN::BUTTON_HOT_SEAT, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_HOT_SEAT, 1 ), display, { -5, 6 } ); - fheroes2::ButtonSprite buttonNetwork = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 1, fheroes2::AGG::GetICN( ICN::BTNMP, 2 ), - fheroes2::AGG::GetICN( ICN::BTNMP, 3 ), display, { -5, 6 } ); - fheroes2::ButtonSprite buttonCancel - = fheroes2::makeButtonWithShadow( buttonPos.x, buttonPos.y + buttonYStep * 5, fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 0 ), - fheroes2::AGG::GetICN( ICN::BUTTON_LARGE_CANCEL, 1 ), display, { -5, 6 } ); + fheroes2::Button buttonHotSeat( buttonPos.x, buttonPos.y, ICN::BUTTON_HOT_SEAT, 0, 1 ); + fheroes2::Button buttonNetwork( buttonPos.x, buttonPos.y + buttonYStep * 1, ICN::BTNMP, 2, 3 ); + fheroes2::Button buttonCancel( buttonPos.x, buttonPos.y + buttonYStep * 5, ICN::BUTTON_LARGE_CANCEL, 0, 1 ); buttonHotSeat.draw(); buttonCancel.draw(); @@ -672,7 +645,7 @@ fheroes2::GameMode Game::NewMulti() fheroes2::Display::instance().render(); LocalEvent & le = LocalEvent::Get(); - // newgame loop + // new game loop while ( le.HandleEvents() ) { buttonHotSeat.drawOnState( le.isMouseLeftButtonPressedInArea( buttonHotSeat.area() ) ); if ( buttonNetwork.isEnabled() ) { From 1645d02a5bf58dff1559986ff15e87e746d155f0 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 14:57:35 +0100 Subject: [PATCH 18/54] Revert removing shadow from battle only --- src/fheroes2/agg/agg_image.cpp | 70 ++++++++++++++-------------------- 1 file changed, 29 insertions(+), 41 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 074086a5d98..b8b3615d3f4 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -1846,24 +1846,20 @@ namespace _icnVsSprite[id].resize( 2 ); for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { fheroes2::Sprite & out = _icnVsSprite[id][i]; - const fheroes2::Sprite originalSprite = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 + i ); - const int32_t newWidth = originalSprite.width() - 5; - const int32_t newHeight = originalSprite.height() - 6; - out.resize( newWidth, newHeight ); - Copy( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 + i ), 5, 0, out, 0, 0, newWidth, newHeight ); + out = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 + i ); // Clean the button - Fill( out, 21 - i, 23 + i, 84, 11, getButtonFillingColor( i == 0 ) ); + Fill( out, 26 - i, 23 + i, 84, 11, getButtonFillingColor( i == 0 ) ); // Add 'K' - Copy( fheroes2::AGG::GetICN( ICN::BTNDCCFG, 4 + i ), 34 - i, 23, out, 35 - i, 23, 12, 14 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNDCCFG, 4 + i ), 34 - i, 23, out, 40 - i, 23, 12, 14 ); //'Add 'A' - Copy( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 4 + i ), 56 - i, 23, out, 47 - i, 23, 13, 14 ); - Copy( out, 20, 20, out, 47 - i + 12, 25, 3, 3 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 4 + i ), 56 - i, 23, out, 52 - i, 23, 13, 14 ); + Copy( out, 20, 20, out, 52 - i + 12, 25, 3, 3 ); // Add 'M' - Copy( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 4 + i ), 39 - i, 8, out, 60 - i, 23, 14, 14 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 4 + i ), 39 - i, 8, out, 65 - i, 23, 14, 14 ); // Add 'F' - Copy( fheroes2::AGG::GetICN( ICN::BTNDCCFG, 4 + i ), 70 - i, 23, out, 82 - i, 23, 10, 14 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNDCCFG, 4 + i ), 70 - i, 23, out, 87 - i, 23, 10, 14 ); // Add 'P' - Copy( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 4 + i ), 36 - i, 23, out, 73 - i, 23, 10, 14 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 4 + i ), 36 - i, 23, out, 78 - i, 23, 10, 14 ); } return true; case ICN::BUTTON_SMALL_MIN_GOOD: @@ -1891,40 +1887,36 @@ namespace _icnVsSprite[id].resize( 2 ); for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { fheroes2::Sprite & out = _icnVsSprite[id][i]; - const fheroes2::Sprite originalSprite = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 + i ); - const int32_t newWidth = originalSprite.width() - 5; - const int32_t newHeight = originalSprite.height() - 6; - out.resize( newWidth, newHeight ); - Copy( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 + i ), 5, 0, out, 0, 0, newWidth, newHeight ); + out = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 + i ); // Clean the button - Fill( out, 27 - i, 21 + i, 77, 14, getButtonFillingColor( i == 0 ) ); + Fill( out, 32 - i, 21 + i, 77, 14, getButtonFillingColor( i == 0 ) ); const int32_t secondLine = 28; // Add 'MODE' - Copy( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 4 + i ), 40 - i, 13, out, 40 - i, 13, 50, 15 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 4 + i ), 40 - i, 13, out, 45 - i, 13, 50, 15 ); // Clean up 'MODE' - Copy( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 114 - i, 18, out, 89 - i, 18, 1, 10 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 114 - i, 18, out, 94 - i, 18, 1, 10 ); // Add 'BA' - Copy( fheroes2::AGG::GetICN( ICN::BTNBAUD, 2 + i ), 42 - i, 28, out, 23 - i, secondLine, 22, 15 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNBAUD, 2 + i ), 42 - i, 28, out, 28 - i, secondLine, 22, 15 ); // Clean up 'BA' - Copy( fheroes2::AGG::GetICN( ICN::BTNBAUD, 2 + i ), 42 - i, 31, out, 34 - i, secondLine, 1, 1 ); - Copy( fheroes2::AGG::GetICN( ICN::BTNBAUD, 2 + i ), 39 - i, 31, out, 44 - i, secondLine + 4, 1, 2 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNBAUD, 2 + i ), 42 - i, 31, out, 39 - i, secondLine, 1, 1 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNBAUD, 2 + i ), 39 - i, 31, out, 49 - i, secondLine + 4, 1, 2 ); // Add 'T' - Copy( fheroes2::AGG::GetICN( ICN::BTNDC, 2 + i ), 89 - i, 21, out, 45 - i, secondLine, 12, 15 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNDC, 2 + i ), 89 - i, 21, out, 49 - i, secondLine, 12, 15 ); // Clean up 'AT' - Copy( fheroes2::AGG::GetICN( ICN::BTNDC, 2 + i ), 89 - i, 18, out, 45 - i, secondLine, 1, 1 ); - Copy( fheroes2::AGG::GetICN( ICN::BTNDC, 2 + i ), 92 - ( 5 * i ), 27 - i, out, 44 - i, secondLine + 4 + i, 1, 3 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNDC, 2 + i ), 89 - i, 18, out, 50 - i, secondLine, 1, 1 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNDC, 2 + i ), 92 - ( 5 * i ), 27 - i, out, 49 - i, secondLine + 4 + i, 1, 3 ); // Add 'AI'. - Copy( fheroes2::AGG::GetICN( ICN::BTNMP, 6 + i ), 56 - i, 13, out, 57 - i, secondLine, 18, 15 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNMP, 6 + i ), 56 - i, 13, out, 62 - i, secondLine, 18, 15 ); // Clean up 'TA' - Copy( fheroes2::AGG::GetICN( ICN::BTNBAUD, 2 + i ), 51 - i, 40, out, 55 - i, secondLine + 12, 3, 3 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNBAUD, 2 + i ), 51 - i, 40, out, 60 - i, secondLine + 12, 3, 3 ); // Add 'LLE' - Copy( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 85 - i, 13, out, 76 - i, secondLine, 31, 15 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 85 - i, 13, out, 81 - i, secondLine, 31, 15 ); // Clean up "IL" - Copy( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 85 - i, 18, out, 76 - i, secondLine + 7, 1, 1 ); - Copy( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 94 - i, 17, out, 75 - i, secondLine + 4, 2, 2 ); - Copy( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 93 - i, 25, out, 74 - i, secondLine + 12, 3, 3 ); - Copy( fheroes2::AGG::GetICN( ICN::BTNDC, 4 + i ), 23 - i, 8, out, 74 - i, secondLine + 5, 1, 10 ); - Copy( fheroes2::AGG::GetICN( ICN::BTNMP, 6 + i ), 73 - i, 22, out, 74 - i, secondLine + 9, 1, 1 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 85 - i, 18, out, 81 - i, secondLine + 7, 1, 1 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 94 - i, 17, out, 80 - i, secondLine + 4, 2, 2 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 93 - i, 25, out, 79 - i, secondLine + 12, 3, 3 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNDC, 4 + i ), 23 - i, 8, out, 79 - i, secondLine + 5, 1, 10 ); + Copy( fheroes2::AGG::GetICN( ICN::BTNMP, 6 + i ), 73 - i, 22, out, 79 - i, secondLine + 9, 1, 1 ); } return true; case ICN::BTNGIFT_GOOD: @@ -2061,14 +2053,10 @@ namespace _icnVsSprite[id].resize( 2 ); for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { fheroes2::Sprite & out = _icnVsSprite[id][i]; - const fheroes2::Sprite originalSprite = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 + i ); - const int32_t newWidth = originalSprite.width() - 5; - const int32_t newHeight = originalSprite.height() - 6; - out.resize( newWidth, newHeight ); - Copy( fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 + i ), 5, 0, out, 0, 0, newWidth, newHeight ); + out = fheroes2::AGG::GetICN( ICN::BTNNEWGM, 6 + i ); // clean the button - Fill( out, 36 - i, 23 + i, 57, 11, getButtonFillingColor( i == 0 ) ); - const int32_t offsetX = 41; + Fill( out, 41 - i, 23 + i, 57, 11, getButtonFillingColor( i == 0 ) ); + const int32_t offsetX = 46; const int32_t offsetY = 23; // Add 'BI' Copy( fheroes2::AGG::GetICN( ICN::BTNMCFG, 2 + i ), 58 - i, 29, out, offsetX - i, offsetY, 14, 11 ); From a0831ee101c5136ea3a19f9babdc0b628b0519ae Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 15:06:18 +0100 Subject: [PATCH 19/54] Move Battle Only and fix y offset --- src/fheroes2/agg/agg_image.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index b8b3615d3f4..fa874aec271 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -620,13 +620,6 @@ namespace void generateDefaultImages( const int id ) { switch ( id ) { - case ICN::BTNBATTLEONLY: { - _icnVsSprite[id].resize( 2 ); - - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "BATTLE\nONLY" ), false, 117, 56 ); - - break; - } case ICN::BUTTON_NEW_GAME_EVIL: case ICN::BUTTON_NEW_GAME_GOOD: { _icnVsSprite[id].resize( 2 ); @@ -1170,6 +1163,7 @@ namespace break; } + case ICN::BTNBATTLEONLY: case ICN::BUTTON_STANDARD_GAME: case ICN::BUTTON_CAMPAIGN_GAME: case ICN::BUTTON_MULTIPLAYER_GAME: @@ -1185,7 +1179,7 @@ namespace case ICN::BUTTON_6_PLAYERS: { _icnVsSprite[id].resize( 2 ); - if ( useOriginalResources() ) { + if ( useOriginalResources() && id != ICN::BTNBATTLEONLY ) { int buttonIcnID = ICN::BTNNEWGM; fheroes2::Point icnIndex( 0, 1 ); switch ( id ) { @@ -1263,8 +1257,8 @@ namespace } const char * text = gettext_noop( "STANDARD\nGAME" ); switch ( id ) { - case ICN::BUTTON_STANDARD_GAME: { - text = gettext_noop( "STANDARD\nGAME" ); + case ICN::BTNBATTLEONLY: { + text = gettext_noop( "BATTLE\nONLY" ); break; } case ICN::BUTTON_CAMPAIGN_GAME: { @@ -1327,12 +1321,12 @@ namespace const fheroes2::Sprite & originalShadow = fheroes2::AGG::GetICN( ICN::BTNCOM, 0 ); fheroes2::Image temp( originalShadow.width(), originalShadow.height() ); - Copy( released, 0, 0, temp, 5, 6, released.width(), released.height() ); + Copy( released, 0, 0, temp, 5, 0, released.width(), released.height() ); fheroes2::Copy( originalShadow, 0, 0, temp, 0, 0, 5, originalShadow.height() ); fheroes2::Copy( originalShadow, 5, originalShadow.height() - 6, temp, 5, originalShadow.height() - 6, originalShadow.width() - 5, 6 ); fheroes2::Copy( temp, released ); - Copy( pressed, 0, 0, temp, 5, 6, released.width(), released.height() ); + Copy( pressed, 0, 0, temp, 5, 0, released.width(), released.height() ); fheroes2::Copy( originalShadow, 0, 0, temp, 0, 0, 5, originalShadow.height() ); fheroes2::Copy( originalShadow, 5, originalShadow.height() - 6, temp, 5, originalShadow.height() - 6, originalShadow.width() - 5, 6 ); fheroes2::Copy( temp, pressed ); From 15045d3422497a425a6446593949b9470cb35cfe Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 15:10:29 +0100 Subject: [PATCH 20/54] code style --- src/fheroes2/agg/agg_image.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index fa874aec271..6e10986c5bb 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -1833,7 +1833,7 @@ namespace } } - bool generateGermanSpecificImages( const int id ) + bool generateGermanSpecificImages( const int id ) { switch ( id ) { case ICN::BTNBATTLEONLY: From b41d63e9063f9816f141bf0a4cadc56fa3f8c956 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 15:18:43 +0100 Subject: [PATCH 21/54] Revert style changes loadgame --- src/fheroes2/game/game_loadgame.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fheroes2/game/game_loadgame.cpp b/src/fheroes2/game/game_loadgame.cpp index 3a15a0d1ff9..19d3f2f7650 100644 --- a/src/fheroes2/game/game_loadgame.cpp +++ b/src/fheroes2/game/game_loadgame.cpp @@ -150,10 +150,10 @@ fheroes2::GameMode Game::LoadGame() const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); - fheroes2::Button buttonStandardGame( buttonPos.x, buttonPos.y, ICN::BUTTON_STANDARD_GAME, 0, 1 ); - fheroes2::Button buttonCampaignGame( buttonPos.x, buttonPos.y + buttonYStep, ICN::BUTTON_CAMPAIGN_GAME, 0, 1 ); - fheroes2::Button buttonMultiplayerGame( buttonPos.x, buttonPos.y + buttonYStep, ICN::BUTTON_MULTIPLAYER_GAME, 0, 1 ); - fheroes2::Button buttonCancel( buttonPos.x, buttonPos.y + buttonYStep * 5, ICN::BUTTON_LARGE_CANCEL, 0, 1 ); + fheroes2::Button buttonStandardGame( 0, 0, ICN::BUTTON_STANDARD_GAME, 0, 1 ); + fheroes2::Button buttonCampaignGame( 0, 0, ICN::BUTTON_CAMPAIGN_GAME, 0, 1 ); + fheroes2::Button buttonMultiplayerGame( 0, 0, ICN::BUTTON_MULTIPLAYER_GAME, 0, 1 ); + fheroes2::Button buttonCancel( 0, 0, ICN::BUTTON_LARGE_CANCEL, 0, 1 ); const std::array buttons{ &buttonStandardGame, &buttonCampaignGame, &buttonMultiplayerGame, &buttonCancel }; if ( !isSuccessionWarsCampaignPresent() ) { From a863993e85e4d7cbb495ce03efbe6c447406ca3c Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 15:20:41 +0100 Subject: [PATCH 22/54] remove include game_loadgame --- src/fheroes2/game/game_loadgame.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/fheroes2/game/game_loadgame.cpp b/src/fheroes2/game/game_loadgame.cpp index 19d3f2f7650..453614ed599 100644 --- a/src/fheroes2/game/game_loadgame.cpp +++ b/src/fheroes2/game/game_loadgame.cpp @@ -29,7 +29,6 @@ #include #include -#include "agg_image.h" #include "audio.h" #include "audio_manager.h" #include "cursor.h" From dae8d83fc2629a36935f5a52ecb4bf5a92516afb Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 15:27:54 +0100 Subject: [PATCH 23/54] change reference --- src/fheroes2/agg/agg_image.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 6e10986c5bb..bd24d45be06 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -1246,7 +1246,9 @@ namespace _icnVsSprite[id][1] = fheroes2::AGG::GetICN( buttonIcnID, icnIndex.y ); if ( id == ICN::BUTTON_CAMPAIGN_GAME ) { // Fix the disabled state. - fheroes2::Image common = fheroes2::ExtractCommonPattern( { &_icnVsSprite[id][0], &_icnVsSprite[id][1] } ); + const fheroes2::Sprite & released = fheroes2::AGG::GetICN( buttonIcnID, icnIndex.x ); + const fheroes2::Sprite & pressed = fheroes2::AGG::GetICN( buttonIcnID, icnIndex.y ); + fheroes2::Image common = fheroes2::ExtractCommonPattern( { &released, &pressed } ); common = fheroes2::FilterOnePixelNoise( common ); common = fheroes2::FilterOnePixelNoise( common ); common = fheroes2::FilterOnePixelNoise( common ); From 58562e967cbb1fc7ed5a54c62960ef55d7d21f6e Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 15:31:24 +0100 Subject: [PATCH 24/54] revert small change --- src/fheroes2/game/game_newgame.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fheroes2/game/game_newgame.cpp b/src/fheroes2/game/game_newgame.cpp index 5a5786fcc66..33934a35873 100644 --- a/src/fheroes2/game/game_newgame.cpp +++ b/src/fheroes2/game/game_newgame.cpp @@ -201,7 +201,7 @@ fheroes2::GameMode Game::CampaignSelection() const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); fheroes2::Button buttonSuccessionWars( buttonPos.x, buttonPos.y, ICN::BUTTON_ORIGINAL_CAMPAIGN, 0, 1 ); - fheroes2::Button buttonPriceOfLoyalty( buttonPos.x, buttonPos.y + buttonYStep, ICN::BUTTON_EXPANSION_CAMPAIGN, 0, 1 ); + fheroes2::Button buttonPriceOfLoyalty( buttonPos.x, buttonPos.y + buttonYStep * 1, ICN::BUTTON_EXPANSION_CAMPAIGN, 0, 1 ); fheroes2::Button buttonCancel( buttonPos.x, buttonPos.y + buttonYStep * 5, ICN::BUTTON_LARGE_CANCEL, 0, 1 ); buttonSuccessionWars.draw(); From 8085425b30605548127ad32b3e99048dbbe6ea71 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 15:33:34 +0100 Subject: [PATCH 25/54] Revert small style changes --- src/fheroes2/game/game_loadgame.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fheroes2/game/game_loadgame.cpp b/src/fheroes2/game/game_loadgame.cpp index 453614ed599..4876cfae6d1 100644 --- a/src/fheroes2/game/game_loadgame.cpp +++ b/src/fheroes2/game/game_loadgame.cpp @@ -90,7 +90,7 @@ fheroes2::GameMode Game::LoadMulti() const fheroes2::Point buttonPos = fheroes2::drawButtonPanel(); fheroes2::Button buttonHotSeat( buttonPos.x, buttonPos.y, ICN::BUTTON_HOT_SEAT, 0, 1 ); - fheroes2::Button buttonNetwork( buttonPos.x, buttonPos.y + buttonYStep, ICN::BTNMP, 2, 3 ); + fheroes2::Button buttonNetwork( buttonPos.x, buttonPos.y + buttonYStep * 1, ICN::BTNMP, 2, 3 ); fheroes2::Button buttonCancel( buttonPos.x, buttonPos.y + buttonYStep * 5, ICN::BUTTON_LARGE_CANCEL, 0, 1 ); buttonHotSeat.draw(); @@ -153,6 +153,7 @@ fheroes2::GameMode Game::LoadGame() fheroes2::Button buttonCampaignGame( 0, 0, ICN::BUTTON_CAMPAIGN_GAME, 0, 1 ); fheroes2::Button buttonMultiplayerGame( 0, 0, ICN::BUTTON_MULTIPLAYER_GAME, 0, 1 ); fheroes2::Button buttonCancel( 0, 0, ICN::BUTTON_LARGE_CANCEL, 0, 1 ); + const std::array buttons{ &buttonStandardGame, &buttonCampaignGame, &buttonMultiplayerGame, &buttonCancel }; if ( !isSuccessionWarsCampaignPresent() ) { From 8b3df3283283f0792eaff1487a7635b3de1b96ca Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 15:36:30 +0100 Subject: [PATCH 26/54] remove missed for loop --- src/fheroes2/agg/agg_image.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index bd24d45be06..425f49c1c27 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -1059,14 +1059,6 @@ namespace break; } - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::OVERVIEW, 2 + i ); - - // clean the button. - Fill( out, 6, 6 + i, 89 - i, 30, getButtonFillingColor( i == 0 ) ); - } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "TOWNS/\nCASTLES" ), false, 89, 42 ); break; From b1ae5c328ffcbc9a93fdf4d61f3a26bc090d34c8 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 15:55:06 +0100 Subject: [PATCH 27/54] Re-add original asset for viewworld exit small style changes --- src/fheroes2/agg/agg_image.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 425f49c1c27..377e45acc20 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -774,9 +774,8 @@ namespace _icnVsSprite[id].resize( 2 ); const bool isEvilInterface = ( id == ICN::BUTTON_SMALL_OKAY_EVIL ); - const bool isSameResourceAsLanguage = useOriginalResources(); - if ( isSameResourceAsLanguage && ( id == ICN::BUTTON_SMALL_OKAY_EVIL || id == ICN::BUTTON_SMALL_OKAY_GOOD ) ) { + if ( useOriginalResources() ) { _icnVsSprite[id][0] = fheroes2::AGG::GetICN( isEvilInterface ? ICN::SPANBTNE : ICN::SPANBTN, 0 ); _icnVsSprite[id][1] = fheroes2::AGG::GetICN( isEvilInterface ? ICN::SPANBTNE : ICN::SPANBTN, 1 ); @@ -950,22 +949,20 @@ namespace // Needs to be generated from original assets because it needs the black background from the pressed state. // TODO: Make a way to generate buttons with black background since it is needed for MAX and EXIT in the Well and Guilds. - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), false, 70 ); break; } case ICN::BUTTON_EXIT_PUZZLE_DIM_DOOR_GOOD: case ICN::BUTTON_EXIT_PUZZLE_DIM_DOOR_EVIL: { - std::vector & buttonStates = _icnVsSprite[id]; - buttonStates.resize( 2 ); + _icnVsSprite[id].resize( 2 ); const bool isEvilInterface = ( id == ICN::BUTTON_EXIT_PUZZLE_DIM_DOOR_EVIL ); if ( useOriginalResources() ) { const int originalButtonICN = isEvilInterface ? ICN::LGNDXTRE : ICN::LGNDXTRA; - buttonStates[0] = fheroes2::AGG::GetICN( originalButtonICN, 4 ); - buttonStates[1] = fheroes2::AGG::GetICN( originalButtonICN, 5 ); + _icnVsSprite[id][0] = fheroes2::AGG::GetICN( originalButtonICN, 4 ); + _icnVsSprite[id][1] = fheroes2::AGG::GetICN( originalButtonICN, 5 ); break; } @@ -1354,6 +1351,7 @@ namespace _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::WELLXTRA, 1 ); break; } + fheroes2::getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "EXIT" ), ICN::EMPTY_GUILDWELL_BUTTON, ICN::UNKNOWN ); break; @@ -1361,8 +1359,15 @@ namespace case ICN::BUTTON_VIEWWORLD_EXIT_GOOD: case ICN::BUTTON_VIEWWORLD_EXIT_EVIL: { _icnVsSprite[id].resize( 2 ); - const bool isEvilInterface = ( id == ICN::BUTTON_VIEWWORLD_EXIT_EVIL ); + + if ( useOriginalResources() ) { + const int originalIcnId = isEvilInterface ? ICN::LGNDXTRE : ICN::LGNDXTRA; + _icnVsSprite[id][0] = fheroes2::AGG::GetICN( originalIcnId, 2 ); + _icnVsSprite[id][1] = fheroes2::AGG::GetICN( originalIcnId, 3 ); + break; + } + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), isEvilInterface, 70, 35 ); break; From e36fb9b21d40e86eb10ccefe18161e0b7b5932f0 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 16:08:54 +0100 Subject: [PATCH 28/54] Add black background --- src/fheroes2/agg/agg_image.cpp | 7 +++++++ src/fheroes2/agg/icn.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 377e45acc20..5c69a2b20df 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -4237,6 +4237,13 @@ namespace } return true; } + case ICN::BLACKBAK: { + _icnVsSprite[id].resize( 1 ); + fheroes2::Image & background = _icnVsSprite[id][0]; + // This enough to cover the largest buttons. + background.resize( 200, 200 ); + fheroes2::Fill( background, 0, 0, background.width(), background.height(), 20 ); + } case ICN::UNIFORMBAK_GOOD: case ICN::UNIFORMBAK_EVIL: { _icnVsSprite[id].resize( 1 ); diff --git a/src/fheroes2/agg/icn.h b/src/fheroes2/agg/icn.h index 4d4b93ffd11..a77f2175a45 100644 --- a/src/fheroes2/agg/icn.h +++ b/src/fheroes2/agg/icn.h @@ -975,6 +975,7 @@ namespace ICN UNIFORMBAK_GOOD, UNIFORMBAK_EVIL, REDBAK_SMALL_VERTICAL, + BLACKBAK, WELLBKG_EVIL, CASLWIND_EVIL, CASLXTRA_EVIL, From f7ab1b1a126401630de79f42ffc595f7893c3978 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 16:13:12 +0100 Subject: [PATCH 29/54] Rename getTextAdapted function --- src/fheroes2/agg/agg_image.cpp | 70 +++++++++++++++++----------------- src/fheroes2/gui/ui_button.cpp | 2 +- src/fheroes2/gui/ui_button.h | 2 +- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 5c69a2b20df..9557842ec74 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -458,7 +458,7 @@ namespace for ( size_t i = 0; i < texts.size(); ++i ) { const size_t icnIndex = 2 * i; - fheroes2::getTextAdaptedButton( _icnVsSprite[campaignSetIcnId][icnIndex], _icnVsSprite[campaignSetIcnId][icnIndex + 1], texts[i], emptyButtonIcnID, + fheroes2::getTextAdaptedSprite( _icnVsSprite[campaignSetIcnId][icnIndex], _icnVsSprite[campaignSetIcnId][icnIndex + 1], texts[i], emptyButtonIcnID, buttonBackgroundICN ); } } @@ -764,7 +764,7 @@ namespace break; } - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "CANCEL" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "CANCEL" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK ); break; @@ -785,7 +785,7 @@ namespace break; } - fheroes2::getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "OKAY" ), + fheroes2::getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "OKAY" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK ); break; @@ -806,7 +806,7 @@ namespace break; } - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "ACCEPT" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "ACCEPT" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK ); break; @@ -827,7 +827,7 @@ namespace break; } - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "DECLINE" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "DECLINE" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK ); break; @@ -845,7 +845,7 @@ namespace break; } - fheroes2::getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "LEARN" ), + fheroes2::getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "LEARN" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD ); @@ -863,7 +863,7 @@ namespace break; } - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "TRADE" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "TRADE" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD ); break; } @@ -880,7 +880,7 @@ namespace break; } - fheroes2::getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "YES" ), + fheroes2::getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "YES" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD ); break; @@ -898,7 +898,7 @@ namespace break; } - fheroes2::getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "NO" ), + fheroes2::getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "NO" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD ); break; @@ -915,7 +915,7 @@ namespace break; } - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "EXIT" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "EXIT" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK ); break; @@ -932,7 +932,7 @@ namespace } // The heroes meeting screen has an embedded shadow so the button needs to be fixed at the same size as the original one. - // TODO: Remove the embedded shadow and button in the heroes meeting screen and use getTextAdaptedButton() instead. + // TODO: Remove the embedded shadow and button in the heroes meeting screen and use getTextAdaptedSprite() instead. createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), false, 70 ); break; @@ -982,7 +982,7 @@ namespace break; } - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "DISMISS" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "DISMISS" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK ); break; @@ -999,7 +999,7 @@ namespace break; } - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "UPGRADE" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "UPGRADE" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK ); break; @@ -1016,7 +1016,7 @@ namespace break; } - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "RESTART" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "RESTART" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK ); break; @@ -1142,7 +1142,7 @@ namespace break; } - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "SELECT" ), ICN::EMPTY_MAP_SELECT_BUTTON, ICN::UNKNOWN ); + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "SELECT" ), ICN::EMPTY_MAP_SELECT_BUTTON, ICN::UNKNOWN ); if ( isEvilInterface ) { const std::vector & goodToEvilPalette = PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_INTERFACE ); @@ -1330,7 +1330,7 @@ namespace const bool isEvilInterface = ( id == ICN::BTNGIFT_EVIL ); - fheroes2::getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "GIFT" ), + fheroes2::getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "GIFT" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD ); @@ -1339,7 +1339,7 @@ namespace case ICN::BUYMAX: { _icnVsSprite[id].resize( 2 ); - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MAX" ), ICN::EMPTY_GUILDWELL_BUTTON, ICN::UNKNOWN ); + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MAX" ), ICN::EMPTY_GUILDWELL_BUTTON, ICN::UNKNOWN ); break; } @@ -1352,7 +1352,7 @@ namespace break; } - fheroes2::getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "EXIT" ), ICN::EMPTY_GUILDWELL_BUTTON, ICN::UNKNOWN ); + fheroes2::getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "EXIT" ), ICN::EMPTY_GUILDWELL_BUTTON, ICN::UNKNOWN ); break; } @@ -1406,7 +1406,7 @@ namespace fheroes2::makeTransparentBackground( released, pressed, buttonBackground ); } // Generate the DIFFICULTY button because it is not present in the original resources - fheroes2::getTextAdaptedButton( _icnVsSprite[id][8], _icnVsSprite[id][9], gettext_noop( "DIFFICULTY" ), + fheroes2::getTextAdaptedSprite( _icnVsSprite[id][8], _icnVsSprite[id][9], gettext_noop( "DIFFICULTY" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, buttonBackground ); break; } @@ -1456,7 +1456,7 @@ namespace fheroes2::makeTransparentBackground( released, pressed, ICN::STONEBAK_SMALL_POL ); } // generate the DIFFICULTY button as it is not present in the original resources - fheroes2::getTextAdaptedButton( _icnVsSprite[id][8], _icnVsSprite[id][9], gettext_noop( "DIFFICULTY" ), ICN::EMPTY_POL_BUTTON, ICN::STONEBAK_SMALL_POL ); + fheroes2::getTextAdaptedSprite( _icnVsSprite[id][8], _icnVsSprite[id][9], gettext_noop( "DIFFICULTY" ), ICN::EMPTY_POL_BUTTON, ICN::STONEBAK_SMALL_POL ); break; } createCampaignButtonSet( id, { gettext_noop( "VIEW INTRO" ), gettext_noop( "RESTART" ), gettext_noop( "OKAY" ), gettext_noop( "CANCEL" ), @@ -1495,21 +1495,21 @@ namespace case ICN::BUTTON_EXIT_GOOD: { _icnVsSprite[id].resize( 2 ); - fheroes2::getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "EXIT" ), ICN::EMPTY_GOOD_BUTTON, ICN::STONEBAK ); + fheroes2::getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "EXIT" ), ICN::EMPTY_GOOD_BUTTON, ICN::STONEBAK ); break; } case ICN::BUTTON_RESET_GOOD: { _icnVsSprite[id].resize( 2 ); - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "RESET" ), ICN::EMPTY_GOOD_BUTTON, ICN::STONEBAK ); + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "RESET" ), ICN::EMPTY_GOOD_BUTTON, ICN::STONEBAK ); break; } case ICN::BUTTON_START_GOOD: { _icnVsSprite[id].resize( 2 ); - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "START" ), ICN::EMPTY_GOOD_BUTTON, ICN::STONEBAK ); + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "START" ), ICN::EMPTY_GOOD_BUTTON, ICN::STONEBAK ); break; } @@ -1551,7 +1551,7 @@ namespace case ICN::BUTTON_RESTRICT_EVIL: { _icnVsSprite[id].resize( 2 ); - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "RESTRICT" ), + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "RESTRICT" ), id == ICN::BUTTON_RESTRICT_EVIL ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, id == ICN::BUTTON_RESTRICT_EVIL ? ICN::STONEBAK_EVIL : ICN::STONEBAK ); @@ -1584,7 +1584,7 @@ namespace break; } - fheroes2::getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "OKAY" ), + fheroes2::getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "OKAY" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD ); break; @@ -1602,7 +1602,7 @@ namespace break; } - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "CANCEL" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "CANCEL" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD ); break; @@ -1620,7 +1620,7 @@ namespace break; } - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "EXIT" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "EXIT" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD ); break; @@ -1650,7 +1650,7 @@ namespace // be off-centered when we are displaying one letter per line const ButtonFontOffsetRestorer fontReleased( _icnVsSprite[ICN::BUTTON_GOOD_FONT_RELEASED], -1 ); const ButtonFontOffsetRestorer fontPressed( _icnVsSprite[ICN::BUTTON_GOOD_FONT_PRESSED], -1 ); - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "D\nI\nS\nM\nI\nS\nS" ), ICN::EMPTY_VERTICAL_GOOD_BUTTON, + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "D\nI\nS\nM\nI\nS\nS" ), ICN::EMPTY_VERTICAL_GOOD_BUTTON, ICN::REDBAK_SMALL_VERTICAL ); break; @@ -1680,7 +1680,7 @@ namespace // be off-centered when we are displaying one letter per line const ButtonFontOffsetRestorer fontReleased( _icnVsSprite[ICN::BUTTON_GOOD_FONT_RELEASED], -1 ); const ButtonFontOffsetRestorer fontPressed( _icnVsSprite[ICN::BUTTON_GOOD_FONT_PRESSED], -1 ); - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "E\nX\nI\nT" ), ICN::EMPTY_VERTICAL_GOOD_BUTTON, ICN::REDBAK_SMALL_VERTICAL ); + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "E\nX\nI\nT" ), ICN::EMPTY_VERTICAL_GOOD_BUTTON, ICN::REDBAK_SMALL_VERTICAL ); break; } @@ -1691,7 +1691,7 @@ namespace // be off-centered when we are displaying one letter per line const ButtonFontOffsetRestorer fontReleased( _icnVsSprite[ICN::BUTTON_GOOD_FONT_RELEASED], -1 ); const ButtonFontOffsetRestorer fontPressed( _icnVsSprite[ICN::BUTTON_GOOD_FONT_PRESSED], -1 ); - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "P\nA\nT\nR\nO\nL" ), ICN::EMPTY_VERTICAL_GOOD_BUTTON, + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "P\nA\nT\nR\nO\nL" ), ICN::EMPTY_VERTICAL_GOOD_BUTTON, ICN::REDBAK_SMALL_VERTICAL ); break; @@ -1753,7 +1753,7 @@ namespace const bool isEvilInterface = ( id == ICN::BUTTON_RUMORS_EVIL ); - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "RUMORS" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "RUMORS" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK ); break; @@ -1764,7 +1764,7 @@ namespace const bool isEvilInterface = ( id == ICN::BUTTON_EVENTS_EVIL ); - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "EVENTS" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "EVENTS" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK ); break; @@ -1775,7 +1775,7 @@ namespace const bool isEvilInterface = ( id == ICN::BUTTON_LANGUAGE_EVIL ); - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "LANGUAGE" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "LANGUAGE" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK ); break; @@ -1786,7 +1786,7 @@ namespace const bool isEvilInterface = ( id == ICN::BUTTON_AUTO_COMBAT_EVIL ); - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "AUTO\nCOMBAT" ), + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "AUTO\nCOMBAT" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK ); break; @@ -1797,7 +1797,7 @@ namespace const bool isEvilInterface = ( id == ICN::BUTTON_QUICK_COMBAT_EVIL ); - getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "QUICK\nCOMBAT" ), + getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "QUICK\nCOMBAT" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK ); break; diff --git a/src/fheroes2/gui/ui_button.cpp b/src/fheroes2/gui/ui_button.cpp index 12aa425e2c6..543c6c52bb8 100644 --- a/src/fheroes2/gui/ui_button.cpp +++ b/src/fheroes2/gui/ui_button.cpp @@ -786,7 +786,7 @@ namespace fheroes2 } } - void getTextAdaptedButton( Sprite & released, Sprite & pressed, const char * text, const int emptyButtonIcnID, const int buttonBackgroundIcnID ) + void getTextAdaptedSprite( Sprite & released, Sprite & pressed, const char * text, const int emptyButtonIcnID, const int buttonBackgroundIcnID ) { fheroes2::FontColor buttonFont = fheroes2::FontColor::WHITE; fheroes2::Point textAreaMargins = { 0, 3 }; diff --git a/src/fheroes2/gui/ui_button.h b/src/fheroes2/gui/ui_button.h index dd10459cb58..2e73297bf5e 100644 --- a/src/fheroes2/gui/ui_button.h +++ b/src/fheroes2/gui/ui_button.h @@ -352,7 +352,7 @@ namespace fheroes2 const bool isTransparentBackground = false ); // Makes a button that has the width necessary to fit a provided text using an empty button template - void getTextAdaptedButton( Sprite & released, Sprite & pressed, const char * text, const int icnId, const int buttonBackgroundIcnID ); + void getTextAdaptedSprite( Sprite & released, Sprite & pressed, const char * text, const int icnId, const int buttonBackgroundIcnID ); // Generate released and pressed button sprites with the text on it over a transparent or a default (STONEBAK/STONEBAK_EVIL) background. void makeButtonSprites( Sprite & released, Sprite & pressed, const std::string & text, const fheroes2::Size buttonSize, const bool isEvilInterface, From ac74a60aad3c43cc0edfdc861d4f3d61339ffd76 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 19:46:56 +0100 Subject: [PATCH 30/54] add background parameter to custom Buttons Add black background --- src/fheroes2/agg/agg_image.cpp | 79 ++++++++++++---------- src/fheroes2/dialog/dialog_selectcount.cpp | 2 +- src/fheroes2/gui/ui_button.cpp | 11 ++- src/fheroes2/gui/ui_button.h | 5 +- src/fheroes2/gui/ui_keyboard.cpp | 2 +- src/fheroes2/gui/ui_window.cpp | 2 +- 6 files changed, 54 insertions(+), 47 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 9557842ec74..8970c2d7ef7 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -421,12 +421,12 @@ namespace pressedText.draw( pressedTextOffset.x, ( buttonSize.height - pressedTextSize.height ) / 2 + 1, buttonSize.width, pressedState ); } - void createNormalButton( fheroes2::Sprite & released, fheroes2::Sprite & pressed, const char * text, const bool isEvilInterface, int32_t buttonWidth, + void createNormalButton( fheroes2::Sprite & released, fheroes2::Sprite & pressed, const char * text, const bool isEvilInterface, const uint32_t backgroundIcnId, int32_t buttonWidth, int32_t buttonHeight = 25 ) { fheroes2::Point releasedOffset; fheroes2::Point pressedOffset; - fheroes2::getCustomNormalButton( released, pressed, isEvilInterface, { buttonWidth, buttonHeight }, releasedOffset, pressedOffset ); + fheroes2::getCustomNormalButton( released, pressed, isEvilInterface, { buttonWidth, buttonHeight }, releasedOffset, pressedOffset, backgroundIcnId ); const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; @@ -632,7 +632,8 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "NEW\nGAME" ), isEvilInterface, 86, 56 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "NEW\nGAME" ), isEvilInterface, + isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 86, 56 ); break; } @@ -648,7 +649,8 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "SAVE\nGAME" ), isEvilInterface, 86, 56 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "SAVE\nGAME" ), isEvilInterface, + isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 86, 56 ); break; } @@ -664,7 +666,8 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "LOAD\nGAME" ), isEvilInterface, 86, 56 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "LOAD\nGAME" ), isEvilInterface, + isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 86, 56 ); break; } @@ -680,7 +683,8 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "INFO" ), isEvilInterface, 86, 56 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "INFO" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, + 86, 56 ); break; } @@ -696,7 +700,8 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "QUIT" ), isEvilInterface, 86, 56 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "QUIT" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, + 86, 56 ); break; } @@ -712,7 +717,8 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "NEW\nMAP" ), isEvilInterface, 86, 56 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "NEW\nMAP" ), isEvilInterface, + isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 86, 56 ); break; } @@ -728,7 +734,8 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "SAVE\nMAP" ), isEvilInterface, 86, 56 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "SAVE\nMAP" ), isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, + isEvilInterface, 86, 56 ); break; } @@ -744,7 +751,8 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "LOAD\nMAP" ), isEvilInterface, 86, 56 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "LOAD\nMAP" ), isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, + isEvilInterface, 86, 56 ); break; } @@ -933,7 +941,7 @@ namespace // The heroes meeting screen has an embedded shadow so the button needs to be fixed at the same size as the original one. // TODO: Remove the embedded shadow and button in the heroes meeting screen and use getTextAdaptedSprite() instead. - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), false, 70 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), false, ICN::STONEBAK, 70 ); break; } @@ -947,9 +955,7 @@ namespace break; } - // Needs to be generated from original assets because it needs the black background from the pressed state. - // TODO: Make a way to generate buttons with black background since it is needed for MAX and EXIT in the Well and Guilds. - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), false, 70 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), false, ICN::BLACKBAK, 70 ); break; } @@ -966,7 +972,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), isEvilInterface, 70 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 70 ); break; } @@ -1030,7 +1036,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), false, 89 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), false, ICN::UNKNOWN, 89 ); break; } @@ -1043,7 +1049,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "HEROES" ), false, 89, 42 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "HEROES" ), false, ICN::UNKNOWN, 89, 42 ); break; } @@ -1056,7 +1062,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "TOWNS/\nCASTLES" ), false, 89, 42 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "TOWNS/\nCASTLES" ), false, ICN::UNKNOWN, 89, 42 ); break; } @@ -1070,7 +1076,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "S" ), false, 46 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "S" ), false, ICN::STONEBAK, 46 ); break; } @@ -1083,7 +1089,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "M" ), false, 46 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "M" ), false, ICN::STONEBAK, 46 ); break; } @@ -1096,7 +1102,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "L" ), false, 46 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "L" ), false, ICN::STONEBAK, 46 ); break; } @@ -1109,7 +1115,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "X-L" ), false, 46 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "X-L" ), false, ICN::STONEBAK, 46 ); break; } @@ -1122,7 +1128,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "ALL" ), false, 58 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "ALL" ), false, ICN::STONEBAK, 58 ); break; } @@ -1304,7 +1310,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], text, false, 117, 56 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], text, false, ICN::STONEBAK, 117, 56 ); fheroes2::Sprite & released = _icnVsSprite[id][0]; fheroes2::Sprite & pressed = _icnVsSprite[id][1]; @@ -1368,7 +1374,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), isEvilInterface, 70, 35 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 70, 35 ); break; } @@ -1467,28 +1473,28 @@ namespace case ICN::BUTTON_SMALL_MIN_GOOD: { _icnVsSprite[id].resize( 2 ); - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MIN" ), false, 61 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MIN" ), false, ICN::STONEBAK, 61 ); break; } case ICN::BUTTON_SMALL_MIN_EVIL: { _icnVsSprite[id].resize( 2 ); - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MIN" ), true, 61 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MIN" ), true, ICN::STONEBAK_EVIL, 61 ); break; } case ICN::BUTTON_SMALL_MAX_GOOD: { _icnVsSprite[id].resize( 2 ); - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MAX" ), false, 61 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MAX" ), false, ICN::STONEBAK, 61 ); break; } case ICN::BUTTON_SMALL_MAX_EVIL: { _icnVsSprite[id].resize( 2 ); - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MAX" ), true, 61 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MAX" ), true, ICN::STONEBAK_EVIL, 61 ); break; } @@ -1525,8 +1531,9 @@ namespace // Normal button width is 80 pixels so if the overall length is smaller than 80 then set the default value. const int32_t width = std::max( 80, std::max( townTextWidth, castleTextWidth ) ); - - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "CASTLE" ), id == ICN::BUTTON_CASTLE_EVIL, width ); + const bool isEvilInterface = id == ICN::BUTTON_CASTLE_EVIL; + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "CASTLE" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, + width ); break; } @@ -1542,8 +1549,9 @@ namespace // Normal button width is 80 pixels so if the overall length is smaller than 80 then set the default value. const int32_t width = std::max( 80, std::max( townTextWidth, castleTextWidth ) ); + const bool isEvilInterface = id == ICN::BUTTON_TOWN_EVIL; - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "TOWN" ), id == ICN::BUTTON_TOWN_EVIL, width ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "TOWN" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, width ); break; } @@ -1567,7 +1575,7 @@ namespace const char * text = ( id == ICN::UNIFORM_GOOD_MIN_BUTTON || id == ICN::UNIFORM_EVIL_MIN_BUTTON ) ? gettext_noop( "MIN" ) : gettext_noop( "MAX" ); - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], text, isEvilInterface, 61 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], text, isEvilInterface,isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD, 61 ); break; } @@ -4240,9 +4248,10 @@ namespace case ICN::BLACKBAK: { _icnVsSprite[id].resize( 1 ); fheroes2::Image & background = _icnVsSprite[id][0]; - // This enough to cover the largest buttons. + // This is enough to cover the largest buttons. background.resize( 200, 200 ); - fheroes2::Fill( background, 0, 0, background.width(), background.height(), 20 ); + fheroes2::Fill( background, 0, 0, background.width(), background.height(), 9 ); + return true; } case ICN::UNIFORMBAK_GOOD: case ICN::UNIFORMBAK_EVIL: { diff --git a/src/fheroes2/dialog/dialog_selectcount.cpp b/src/fheroes2/dialog/dialog_selectcount.cpp index fb347847944..a3adc257a9b 100644 --- a/src/fheroes2/dialog/dialog_selectcount.cpp +++ b/src/fheroes2/dialog/dialog_selectcount.cpp @@ -234,7 +234,7 @@ bool Dialog::inputString( const fheroes2::TextBase & title, const fheroes2::Text fheroes2::Sprite pressedVirtualKB; const fheroes2::Size buttonVirtualKBSize{ 40, 25 }; - makeButtonSprites( releasedVirtualKB, pressedVirtualKB, "...", buttonVirtualKBSize, isEvilInterface, true ); + makeButtonSprites( releasedVirtualKB, pressedVirtualKB, "...", buttonVirtualKBSize, isEvilInterface, isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD ); // To center the button horizontally we have to take into account that actual button sprite is 10 pixels longer then the requested button width. fheroes2::ButtonSprite buttonVirtualKB = makeButtonWithBackground( frameBoxArea.x + ( frameBoxArea.width - buttonVirtualKBSize.width - 10 ) / 2, dst_pt.y - 30, releasedVirtualKB, pressedVirtualKB, display ); diff --git a/src/fheroes2/gui/ui_button.cpp b/src/fheroes2/gui/ui_button.cpp index 543c6c52bb8..543d038563a 100644 --- a/src/fheroes2/gui/ui_button.cpp +++ b/src/fheroes2/gui/ui_button.cpp @@ -751,8 +751,8 @@ namespace fheroes2 std::move( disabledWithBackground ) }; } - void getCustomNormalButton( Sprite & released, Sprite & pressed, const bool isEvilInterface, fheroes2::Size buttonSize, Point & releasedOffset, Point & pressedOffset, - const bool isTransparentBackground /* = false */ ) + void fheroes2::getCustomNormalButton( Sprite & released, Sprite & pressed, const bool isEvilInterface, fheroes2::Size buttonSize, Point & releasedOffset, + Point & pressedOffset, const int32_t backgroundIcnId ) { assert( buttonSize.width > 0 && buttonSize.height > 0 ); @@ -780,8 +780,7 @@ namespace fheroes2 addButtonShine( released, icnId ); - if ( !isTransparentBackground ) { - const int backgroundIcnId = isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK; + if ( backgroundIcnId != ICN::UNKNOWN ) { makeTransparentBackground( released, pressed, backgroundIcnId ); } } @@ -850,11 +849,11 @@ namespace fheroes2 } void makeButtonSprites( Sprite & released, Sprite & pressed, const std::string & text, const fheroes2::Size buttonSize, const bool isEvilInterface, - const bool isTransparentBackground ) + const uint32_t backgroundIcnId ) { fheroes2::Point releasedOffset; fheroes2::Point pressedOffset; - fheroes2::getCustomNormalButton( released, pressed, isEvilInterface, buttonSize, releasedOffset, pressedOffset, isTransparentBackground ); + fheroes2::getCustomNormalButton( released, pressed, isEvilInterface, buttonSize, releasedOffset, pressedOffset, backgroundIcnId ); const fheroes2::FontColor fontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; diff --git a/src/fheroes2/gui/ui_button.h b/src/fheroes2/gui/ui_button.h index 2e73297bf5e..2bc97f46ed9 100644 --- a/src/fheroes2/gui/ui_button.h +++ b/src/fheroes2/gui/ui_button.h @@ -348,13 +348,12 @@ namespace fheroes2 // The height of text area is only 16 pixels. If 'isTransparentBackground' is set to false the button sprite will have a default background pattern from // STONEBAK or STONEBAK_EVIL (for Evil interface). The pattern is the same for all buttons. - void getCustomNormalButton( Sprite & released, Sprite & pressed, const bool isEvilInterface, fheroes2::Size buttonSize, Point & releasedOffset, Point & pressedOffset, - const bool isTransparentBackground = false ); + void getCustomNormalButton(Sprite & released, Sprite & pressed, const bool isEvilInterface, fheroes2::Size buttonSize, Point & releasedOffset, Point & pressedOffset, const int32_t backgroundIcnId ); // Makes a button that has the width necessary to fit a provided text using an empty button template void getTextAdaptedSprite( Sprite & released, Sprite & pressed, const char * text, const int icnId, const int buttonBackgroundIcnID ); // Generate released and pressed button sprites with the text on it over a transparent or a default (STONEBAK/STONEBAK_EVIL) background. void makeButtonSprites( Sprite & released, Sprite & pressed, const std::string & text, const fheroes2::Size buttonSize, const bool isEvilInterface, - const bool isTransparentBackground ); + const uint32_t backgroundIcnId ); } diff --git a/src/fheroes2/gui/ui_keyboard.cpp b/src/fheroes2/gui/ui_keyboard.cpp index 104d1d180b9..1e79552952b 100644 --- a/src/fheroes2/gui/ui_keyboard.cpp +++ b/src/fheroes2/gui/ui_keyboard.cpp @@ -284,7 +284,7 @@ namespace { fheroes2::Sprite released; fheroes2::Sprite pressed; - makeButtonSprites( released, pressed, text, buttonSize, isEvilInterface, false ); + makeButtonSprites( released, pressed, text, buttonSize, isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK ); button.setSprite( released, pressed ); // Make Image with shadow for button to Blit it during render. diff --git a/src/fheroes2/gui/ui_window.cpp b/src/fheroes2/gui/ui_window.cpp index 88c86056243..d2a9f133c66 100644 --- a/src/fheroes2/gui/ui_window.cpp +++ b/src/fheroes2/gui/ui_window.cpp @@ -349,7 +349,7 @@ namespace fheroes2 Sprite released; Sprite pressed; - makeButtonSprites( released, pressed, buttonText, buttonSize, isEvilInterface, false ); + makeButtonSprites( released, pressed, buttonText, buttonSize, isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK ); const Point pos = _getRenderPos( offset, { released.width(), released.height() }, padding ); From c584d137b689a5dca4e9b263c38d1ab88700c048 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 20:44:20 +0100 Subject: [PATCH 31/54] Fix transparency bugs in kingdom overview Add brown background --- src/fheroes2/agg/agg_image.cpp | 24 ++++++++++++++++++++--- src/fheroes2/agg/icn.h | 1 + src/fheroes2/kingdom/kingdom_overview.cpp | 10 +++------- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 8970c2d7ef7..95784398ec1 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -1036,7 +1036,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), false, ICN::UNKNOWN, 89 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), false, ICN::BROWNBAK, 89 ); break; } @@ -1049,7 +1049,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "HEROES" ), false, ICN::UNKNOWN, 89, 42 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "HEROES" ), false, ICN::BROWNBAK, 89, 42 ); break; } @@ -1062,7 +1062,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "TOWNS/\nCASTLES" ), false, ICN::UNKNOWN, 89, 42 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "TOWNS/\nCASTLES" ), false, ICN::BROWNBAK, 89, 42 ); break; } @@ -4204,6 +4204,16 @@ namespace } } return true; + case ICN::OVERBACK: { + LoadOriginalICN( id ); + fheroes2::Sprite & background = _icnVsSprite[id][0]; + // Fill button backgrounds. This bug was present in the original game too. + Fill( background, 540, 361, 99, 83, 57 ); + Fill( background, 540, 454, 99, 24, 57 ); + fheroes2::Copy( fheroes2::AGG::GetICN( ICN::OVERBACK, 0 ), 540, 444, background, 540, 402, 99, 5 ); + fheroes2::Save( background, "overviewBackground.png", 96 ); + return true; + } case ICN::ESPANBKG_EVIL: { _icnVsSprite[id].resize( 2 ); @@ -4253,6 +4263,14 @@ namespace fheroes2::Fill( background, 0, 0, background.width(), background.height(), 9 ); return true; } + case ICN::BROWNBAK: { + _icnVsSprite[id].resize( 1 ); + fheroes2::Image & background = _icnVsSprite[id][0]; + // This is enough to cover the largest buttons. + background.resize( 200, 200 ); + fheroes2::Fill( background, 0, 0, background.width(), background.height(), 57 ); + return true; + } case ICN::UNIFORMBAK_GOOD: case ICN::UNIFORMBAK_EVIL: { _icnVsSprite[id].resize( 1 ); diff --git a/src/fheroes2/agg/icn.h b/src/fheroes2/agg/icn.h index a77f2175a45..1c62d63c558 100644 --- a/src/fheroes2/agg/icn.h +++ b/src/fheroes2/agg/icn.h @@ -976,6 +976,7 @@ namespace ICN UNIFORMBAK_EVIL, REDBAK_SMALL_VERTICAL, BLACKBAK, + BROWNBAK, WELLBKG_EVIL, CASLWIND_EVIL, CASLXTRA_EVIL, diff --git a/src/fheroes2/kingdom/kingdom_overview.cpp b/src/fheroes2/kingdom/kingdom_overview.cpp index 2cbca4a9b88..2b23d8a0370 100644 --- a/src/fheroes2/kingdom/kingdom_overview.cpp +++ b/src/fheroes2/kingdom/kingdom_overview.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2019 - 2024 * + * Copyright (C) 2019 - 2025 * * * * Free Heroes2 Engine: http://sourceforge.net/projects/fheroes2 * * Copyright (C) 2012 by Andrey Afletdinov * @@ -789,14 +789,10 @@ void Kingdom::openOverviewDialog() // buttons dst_pt.x = cur_pt.x + 540; - dst_pt.y = cur_pt.y + 360; + dst_pt.y = cur_pt.y + 361; fheroes2::Button buttonHeroes( dst_pt.x, dst_pt.y, ICN::BUTTON_KINGDOM_HEROES, 0, 1 ); - // We need to additionally render the background between HEROES and TOWNS/CASTLES buttons. - dst_pt.y += 42; - fheroes2::Copy( fheroes2::AGG::GetICN( ICN::OVERBACK, 0 ), 540, 444, display, dst_pt.x, dst_pt.y, 99, 5 ); - - dst_pt.y += 3; + dst_pt.y += 45; fheroes2::Button buttonCastle( dst_pt.x, dst_pt.y, ICN::BUTTON_KINGDOM_TOWNS, 0, 1 ); dst_pt.y += 48; From 1df97886f18a0a9041d3bd6bb0d33bf1f529fe0f Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 21:26:38 +0100 Subject: [PATCH 32/54] Remove missed save call Fix extra pixel on empty pressed state buttons --- src/fheroes2/agg/agg_image.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 95784398ec1..5439c032e40 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -4211,7 +4211,6 @@ namespace Fill( background, 540, 361, 99, 83, 57 ); Fill( background, 540, 454, 99, 24, 57 ); fheroes2::Copy( fheroes2::AGG::GetICN( ICN::OVERBACK, 0 ), 540, 444, background, 540, 402, 99, 5 ); - fheroes2::Save( background, "overviewBackground.png", 96 ); return true; } case ICN::ESPANBKG_EVIL: { @@ -4513,14 +4512,13 @@ namespace released = _icnVsSprite[originalId][11]; - // fix single bright pixel in the left part of the text area of the released state buttons Fill( released, 8, 7, 1, 1, getButtonFillingColor( true, isGoodInterface ) ); const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( originalId, 12 ); if ( originalPressed.width() > 2 && originalPressed.height() > 2 ) { pressed.resize( originalPressed.width(), originalPressed.height() ); - // copy the original pressed button but add the missing darker leftside border from the released state + // Copy the original pressed button but add the missing darker left side border from the released state Copy( released, 0, 0, pressed, 0, 0, 1, released.height() ); Copy( originalPressed, 0, 0, pressed, 1, 0, originalPressed.width() - 1, originalPressed.height() ); @@ -4539,6 +4537,8 @@ namespace FillTransform( pressed, pressed.width() - 2, pressed.height() - 3, 1, 1, 1 ); } + Fill( pressed, 90, 5, 1, 1, getButtonFillingColor( false, isGoodInterface ) ); + return true; } case ICN::EMPTY_POL_BUTTON: { From 39fecc11ab77acc8677a710d2f5f97e7d866f6d5 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 23:35:54 +0100 Subject: [PATCH 33/54] Add Polish and French Min buttons Fix French Min button transparency --- src/fheroes2/agg/agg_image.cpp | 128 +++++++++++++++++++++++++++------ 1 file changed, 105 insertions(+), 23 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 5439c032e40..e6210fdca1f 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -1470,31 +1470,47 @@ namespace break; } - case ICN::BUTTON_SMALL_MIN_GOOD: { - _icnVsSprite[id].resize( 2 ); - - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MIN" ), false, ICN::STONEBAK, 61 ); - - break; - } + case ICN::BUTTON_SMALL_MIN_GOOD: case ICN::BUTTON_SMALL_MIN_EVIL: { _icnVsSprite[id].resize( 2 ); - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MIN" ), true, ICN::STONEBAK_EVIL, 61 ); + const bool isEvilInterface = id == ICN::BUTTON_SMALL_MIN_EVIL; + + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MIN" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, + fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MAX_GOOD, 0 ).width() - 10 ); break; } + case ICN::BUTTON_SMALL_MAX_EVIL: case ICN::BUTTON_SMALL_MAX_GOOD: { _icnVsSprite[id].resize( 2 ); - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MAX" ), false, ICN::STONEBAK, 61 ); + const bool isEvilInterface = id == ICN::BUTTON_SMALL_MAX_EVIL; - break; - } - case ICN::BUTTON_SMALL_MAX_EVIL: { - _icnVsSprite[id].resize( 2 ); + if ( useOriginalResources() && !isEvilInterface ) { + // The original assets ICN contains button with shadow. We crop only the button. + _icnVsSprite[id][0] = fheroes2::Crop( fheroes2::AGG::GetICN( ICN::RECRUIT, 4 ), 5, 0, 60, 25 ); + _icnVsSprite[id][1] = fheroes2::Crop( fheroes2::AGG::GetICN( ICN::RECRUIT, 5 ), 5, 0, 60, 25 ); - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MAX" ), true, ICN::STONEBAK_EVIL, 61 ); + // To properly generate shadows and Blit the button we need to make some pixels transparent. + for ( fheroes2::Sprite & image : _icnVsSprite[id] ) { + setButtonCornersTransparent( image ); + } + + break; + } + else if ( useOriginalResources() && isEvilInterface ) { + _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MAX_GOOD, 0 ); + _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MAX_GOOD, 1 ); + if ( isEvilInterface ) { + fheroes2::ApplyPalette( _icnVsSprite[id][0], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_INTERFACE ) ); + fheroes2::ApplyPalette( _icnVsSprite[id][1], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_INTERFACE ) ); + } + + break; + } + + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MAX" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 61 ); break; } @@ -2023,24 +2039,61 @@ namespace offsetXD + offsetXO + offsetXN + offsetXN + offsetXN + 21, offsetY + 4, 1, 1 ); } return true; + case ICN::BUTTON_SMALL_MAX_GOOD: { + _icnVsSprite[id].resize( 2 ); + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; + const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::RECRUIT, 4 ); + const fheroes2::Sprite & originalPressed = fheroes2::AGG::GetICN( ICN::RECRUIT, 5 ); + released = originalReleased; + pressed = originalPressed; + // The original assets ICN contains button with shadow. We crop only the button. + released = fheroes2::Crop( originalReleased, 5, 0, 60, 25 ); + pressed = fheroes2::Crop( originalPressed, 5, 0, 60, 25 ); + released.setPosition( 0, 0 ); + pressed.setPosition( 0, 0 ); + // Fill wrong transparent text pixels with color. + fheroes2::Image whiteBackground( released.width(), released.height() ); + fheroes2::Fill( whiteBackground, 0, 0, released.width(), released.height(), 10 ); + Blit( released, whiteBackground ); + released = whiteBackground; + // To properly generate shadows and Blit the button we need to make some pixels transparent. + for ( fheroes2::Sprite & image : _icnVsSprite[id] ) { + setButtonCornersTransparent( image ); + } + fheroes2::Image common = fheroes2::ExtractCommonPattern( { &released, &pressed } ); + common = fheroes2::FilterOnePixelNoise( common ); + common = fheroes2::FilterOnePixelNoise( common ); + common = fheroes2::FilterOnePixelNoise( common ); + fheroes2::Blit( common, _icnVsSprite[id][0] ); + + return true; + } case ICN::BUTTON_SMALL_MIN_GOOD: _icnVsSprite[id].resize( 2 ); for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::RECRUIT, 4 + i ); + out = fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MAX_GOOD, i ); // Clean the button and leave 'M' - Fill( out, 31 - 2 * i, 5 + i, 25, 15, getButtonFillingColor( i == 0 ) ); - Fill( out, 29 - 2 * i, 17 + i, 2, 2, getButtonFillingColor( i == 0 ) ); + Fill( out, 26 - 2 * i, 5 + i, 25, 15, getButtonFillingColor( i == 0 ) ); + Fill( out, 24 - 2 * i, 17 + i, 2, 2, getButtonFillingColor( i == 0 ) ); // Add 'I' - Blit( fheroes2::AGG::GetICN( ICN::APANEL, 4 + i ), 25 - i, 19 + i, out, 32 - i, 4 + i, 7 - i, 15 ); - Blit( fheroes2::AGG::GetICN( ICN::RECRUIT, 4 + i ), 28 - i, 7 + i, out, 36 - i, 7 + i, 3, 9 ); - Fill( out, 37 - i, 16 + i, 2, 3, getButtonFillingColor( i == 0 ) ); + Copy( fheroes2::AGG::GetICN( ICN::APANEL, 4 + i ), 25 - i, 19 + i, out, 27 - i, 4 + i, 7 - i, 15 ); + Copy( fheroes2::AGG::GetICN( ICN::RECRUIT, 4 + i ), 28 - i, 7 + i, out, 31 - i, 7 + i, 3, 9 ); + Fill( out, 32 - i, 16 + i, 2, 3, getButtonFillingColor( i == 0 ) ); // Add 'N' - Blit( fheroes2::AGG::GetICN( ICN::TRADPOST, 17 + i ), 50 - i, 5, out, 41 - i, 5, 14, 15 ); - Fill( out, 41 - i, 5, 1, 1, getButtonFillingColor( i == 0 ) ); - Fill( out, 41 - i, 5 + 9, 1, 1, getButtonFillingColor( i == 0 ) ); + Copy( fheroes2::AGG::GetICN( ICN::TRADPOST, 17 + i ), 50 - i, 5, out, 36 - i, 5, 14, 15 ); + Fill( out, 36 - i, 5, 1, 1, getButtonFillingColor( i == 0 ) ); + Fill( out, 36 - i, 5 + 9, 1, 1, getButtonFillingColor( i == 0 ) ); } return true; + case ICN::BUTTON_SMALL_MIN_EVIL: + _icnVsSprite[id].resize( 2 ); + _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MIN_GOOD, 0 ); + _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MIN_GOOD, 1 ); + fheroes2::ApplyPalette( _icnVsSprite[id][0], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_INTERFACE ) ); + fheroes2::ApplyPalette( _icnVsSprite[id][1], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_INTERFACE ) ); + return true; default: break; } @@ -2069,6 +2122,35 @@ namespace Copy( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 47 - i, 23 + i, out, offsetX + 38 - i, offsetY + i, 1, 1 ); } return true; + case ICN::BUTTON_SMALL_MIN_GOOD: + _icnVsSprite[id].resize( 2 ); + for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { + fheroes2::Sprite & out = _icnVsSprite[id][i]; + const fheroes2::Sprite & original = fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MAX_GOOD, i ); + out = original; + // Wipe the button + Fill( out, 9 - 2 * i, 7 + i, 46 + i, 10, getButtonFillingColor( i == 0 ) ); + // 'M' + Copy( original, 9 - i, 7 + i, out, 13 - i, 7 + i, 14, 10 ); + // 'I' + Copy( fheroes2::AGG::GetICN( ICN::BTNMCFG, 4 + i ), 53 - i, 23 + i, out, 28 - i, 7 + i, 5, 10 ); + // 'N' + Copy( fheroes2::AGG::GetICN( ICN::BTNMCFG, 0 + i ), 83 - i, 29 + i, out, 34 - i, 7 + i, 11, 10 ); + // '.' + Copy( original, 52 - i, 14 + i, out, 47 - i, 14 + i, 3, 3 ); + fheroes2::Fill( out, 44 - i, 8 + i, 1, 9, getButtonFillingColor( i == 0 ) ); + if ( i == 0 ) { + fheroes2::ReplaceColorId( out, 56, 55 ); + } + } + return true; + case ICN::BUTTON_SMALL_MIN_EVIL: + _icnVsSprite[id].resize( 2 ); + _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MIN_GOOD, 0 ); + _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MIN_GOOD, 1 ); + fheroes2::ApplyPalette( _icnVsSprite[id][0], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_INTERFACE ) ); + fheroes2::ApplyPalette( _icnVsSprite[id][1], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_INTERFACE ) ); + return true; default: break; } From 4a22e5cca4a01a3a31eb2060e8a1044649d1c679 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Tue, 4 Feb 2025 23:56:45 +0100 Subject: [PATCH 34/54] Use original min buttons for original assets --- src/fheroes2/agg/agg_image.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index e6210fdca1f..fcf368b9ddf 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -1588,10 +1588,23 @@ namespace _icnVsSprite[id].resize( 2 ); const bool isEvilInterface = ( id == ICN::UNIFORM_EVIL_MAX_BUTTON || id == ICN::UNIFORM_EVIL_MIN_BUTTON ); + if ( useOriginalResources() ) { + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; + int buttonIcnId = id == ICN::UNIFORM_GOOD_MAX_BUTTON ? ICN::BUTTON_SMALL_MAX_GOOD : ICN::BUTTON_SMALL_MIN_GOOD; + if ( isEvilInterface ) { + buttonIcnId = id == ICN::UNIFORM_EVIL_MAX_BUTTON ? ICN::BUTTON_SMALL_MAX_EVIL : ICN::BUTTON_SMALL_MIN_EVIL; + } + + released = fheroes2::AGG::GetICN( buttonIcnId, 0 ); + pressed = fheroes2::AGG::GetICN( buttonIcnId, 1 ); + fheroes2::makeTransparentBackground( released, pressed, isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD ); + break; + } const char * text = ( id == ICN::UNIFORM_GOOD_MIN_BUTTON || id == ICN::UNIFORM_EVIL_MIN_BUTTON ) ? gettext_noop( "MIN" ) : gettext_noop( "MAX" ); - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], text, isEvilInterface,isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD, 61 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], text, isEvilInterface, isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD, 61 ); break; } From 1216fd5d1eca87cdfde2a55bf47e27669639e83e Mon Sep 17 00:00:00 2001 From: Zenseii Date: Wed, 5 Feb 2025 00:01:22 +0100 Subject: [PATCH 35/54] address comments --- src/fheroes2/agg/agg_image.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index fcf368b9ddf..6f37fdb4f21 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -1499,18 +1499,18 @@ namespace break; } - else if ( useOriginalResources() && isEvilInterface ) { + if ( useOriginalResources() && isEvilInterface ) { _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MAX_GOOD, 0 ); _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MAX_GOOD, 1 ); - if ( isEvilInterface ) { - fheroes2::ApplyPalette( _icnVsSprite[id][0], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_INTERFACE ) ); - fheroes2::ApplyPalette( _icnVsSprite[id][1], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_INTERFACE ) ); - } + + fheroes2::ApplyPalette( _icnVsSprite[id][0], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_INTERFACE ) ); + fheroes2::ApplyPalette( _icnVsSprite[id][1], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_INTERFACE ) ); break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MAX" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 61 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MAX" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, + 61 ); break; } From 570788965017ab79fc75949bd3ee1a01cb04fe8f Mon Sep 17 00:00:00 2001 From: Zenseii Date: Wed, 5 Feb 2025 00:07:36 +0100 Subject: [PATCH 36/54] Tidy --- src/fheroes2/agg/agg_image.cpp | 13 ++++++++----- src/fheroes2/gui/ui_button.h | 3 ++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 6f37fdb4f21..7bc1a9aef75 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -421,8 +421,8 @@ namespace pressedText.draw( pressedTextOffset.x, ( buttonSize.height - pressedTextSize.height ) / 2 + 1, buttonSize.width, pressedState ); } - void createNormalButton( fheroes2::Sprite & released, fheroes2::Sprite & pressed, const char * text, const bool isEvilInterface, const uint32_t backgroundIcnId, int32_t buttonWidth, - int32_t buttonHeight = 25 ) + void createNormalButton( fheroes2::Sprite & released, fheroes2::Sprite & pressed, const char * text, const bool isEvilInterface, const uint32_t backgroundIcnId, + int32_t buttonWidth, int32_t buttonHeight = 25 ) { fheroes2::Point releasedOffset; fheroes2::Point pressedOffset; @@ -972,7 +972,8 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 70 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), isEvilInterface, + isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 70 ); break; } @@ -1374,7 +1375,8 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 70, 35 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), isEvilInterface, + isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 70, 35 ); break; } @@ -1567,7 +1569,8 @@ namespace const int32_t width = std::max( 80, std::max( townTextWidth, castleTextWidth ) ); const bool isEvilInterface = id == ICN::BUTTON_TOWN_EVIL; - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "TOWN" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, width ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "TOWN" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, + width ); break; } diff --git a/src/fheroes2/gui/ui_button.h b/src/fheroes2/gui/ui_button.h index 2bc97f46ed9..6e6bd469036 100644 --- a/src/fheroes2/gui/ui_button.h +++ b/src/fheroes2/gui/ui_button.h @@ -348,7 +348,8 @@ namespace fheroes2 // The height of text area is only 16 pixels. If 'isTransparentBackground' is set to false the button sprite will have a default background pattern from // STONEBAK or STONEBAK_EVIL (for Evil interface). The pattern is the same for all buttons. - void getCustomNormalButton(Sprite & released, Sprite & pressed, const bool isEvilInterface, fheroes2::Size buttonSize, Point & releasedOffset, Point & pressedOffset, const int32_t backgroundIcnId ); + void getCustomNormalButton( Sprite & released, Sprite & pressed, const bool isEvilInterface, fheroes2::Size buttonSize, Point & releasedOffset, Point & pressedOffset, + const int32_t backgroundIcnId ); // Makes a button that has the width necessary to fit a provided text using an empty button template void getTextAdaptedSprite( Sprite & released, Sprite & pressed, const char * text, const int icnId, const int buttonBackgroundIcnID ); From b4fb9fd03bae2c1eb64fbec9ec328de1b77578d4 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Wed, 5 Feb 2025 00:17:33 +0100 Subject: [PATCH 37/54] fix types --- src/fheroes2/agg/agg_image.cpp | 2 +- src/fheroes2/gui/ui_button.cpp | 4 ++-- src/fheroes2/gui/ui_button.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 7bc1a9aef75..28aeaa17e91 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -421,7 +421,7 @@ namespace pressedText.draw( pressedTextOffset.x, ( buttonSize.height - pressedTextSize.height ) / 2 + 1, buttonSize.width, pressedState ); } - void createNormalButton( fheroes2::Sprite & released, fheroes2::Sprite & pressed, const char * text, const bool isEvilInterface, const uint32_t backgroundIcnId, + void createNormalButton( fheroes2::Sprite & released, fheroes2::Sprite & pressed, const char * text, const bool isEvilInterface, const int backgroundIcnId, int32_t buttonWidth, int32_t buttonHeight = 25 ) { fheroes2::Point releasedOffset; diff --git a/src/fheroes2/gui/ui_button.cpp b/src/fheroes2/gui/ui_button.cpp index 543d038563a..45c2336c3a0 100644 --- a/src/fheroes2/gui/ui_button.cpp +++ b/src/fheroes2/gui/ui_button.cpp @@ -752,7 +752,7 @@ namespace fheroes2 } void fheroes2::getCustomNormalButton( Sprite & released, Sprite & pressed, const bool isEvilInterface, fheroes2::Size buttonSize, Point & releasedOffset, - Point & pressedOffset, const int32_t backgroundIcnId ) + Point & pressedOffset, const int backgroundIcnId ) { assert( buttonSize.width > 0 && buttonSize.height > 0 ); @@ -849,7 +849,7 @@ namespace fheroes2 } void makeButtonSprites( Sprite & released, Sprite & pressed, const std::string & text, const fheroes2::Size buttonSize, const bool isEvilInterface, - const uint32_t backgroundIcnId ) + const int backgroundIcnId ) { fheroes2::Point releasedOffset; fheroes2::Point pressedOffset; diff --git a/src/fheroes2/gui/ui_button.h b/src/fheroes2/gui/ui_button.h index 6e6bd469036..2e7af7c2750 100644 --- a/src/fheroes2/gui/ui_button.h +++ b/src/fheroes2/gui/ui_button.h @@ -349,12 +349,12 @@ namespace fheroes2 // The height of text area is only 16 pixels. If 'isTransparentBackground' is set to false the button sprite will have a default background pattern from // STONEBAK or STONEBAK_EVIL (for Evil interface). The pattern is the same for all buttons. void getCustomNormalButton( Sprite & released, Sprite & pressed, const bool isEvilInterface, fheroes2::Size buttonSize, Point & releasedOffset, Point & pressedOffset, - const int32_t backgroundIcnId ); + const int backgroundIcnId ); // Makes a button that has the width necessary to fit a provided text using an empty button template void getTextAdaptedSprite( Sprite & released, Sprite & pressed, const char * text, const int icnId, const int buttonBackgroundIcnID ); // Generate released and pressed button sprites with the text on it over a transparent or a default (STONEBAK/STONEBAK_EVIL) background. void makeButtonSprites( Sprite & released, Sprite & pressed, const std::string & text, const fheroes2::Size buttonSize, const bool isEvilInterface, - const uint32_t backgroundIcnId ); + const int backgroundIcnId ); } From 3679a55dc1eee1a8256b325f24ffc43546fe4ef6 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Wed, 5 Feb 2025 00:26:02 +0100 Subject: [PATCH 38/54] clang tidy --- src/fheroes2/gui/ui_button.cpp | 2 +- src/fheroes2/gui/ui_button.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fheroes2/gui/ui_button.cpp b/src/fheroes2/gui/ui_button.cpp index 45c2336c3a0..35fe55888c8 100644 --- a/src/fheroes2/gui/ui_button.cpp +++ b/src/fheroes2/gui/ui_button.cpp @@ -751,7 +751,7 @@ namespace fheroes2 std::move( disabledWithBackground ) }; } - void fheroes2::getCustomNormalButton( Sprite & released, Sprite & pressed, const bool isEvilInterface, fheroes2::Size buttonSize, Point & releasedOffset, + void fheroes2::getCustomNormalButton( Sprite & released, Sprite & pressed, const bool isEvilInterface, Size buttonSize, Point & releasedOffset, Point & pressedOffset, const int backgroundIcnId ) { assert( buttonSize.width > 0 && buttonSize.height > 0 ); diff --git a/src/fheroes2/gui/ui_button.h b/src/fheroes2/gui/ui_button.h index 2e7af7c2750..4a144949b00 100644 --- a/src/fheroes2/gui/ui_button.h +++ b/src/fheroes2/gui/ui_button.h @@ -348,7 +348,7 @@ namespace fheroes2 // The height of text area is only 16 pixels. If 'isTransparentBackground' is set to false the button sprite will have a default background pattern from // STONEBAK or STONEBAK_EVIL (for Evil interface). The pattern is the same for all buttons. - void getCustomNormalButton( Sprite & released, Sprite & pressed, const bool isEvilInterface, fheroes2::Size buttonSize, Point & releasedOffset, Point & pressedOffset, + void getCustomNormalButton( Sprite & released, Sprite & pressed, const bool isEvilInterface, Size buttonSize, Point & releasedOffset, Point & pressedOffset, const int backgroundIcnId ); // Makes a button that has the width necessary to fit a provided text using an empty button template From 498d755427684daf75ff24b6ea8b278be85a8cc0 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Wed, 5 Feb 2025 00:27:13 +0100 Subject: [PATCH 39/54] code style --- src/fheroes2/gui/ui_button.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fheroes2/gui/ui_button.cpp b/src/fheroes2/gui/ui_button.cpp index 35fe55888c8..32eb5507969 100644 --- a/src/fheroes2/gui/ui_button.cpp +++ b/src/fheroes2/gui/ui_button.cpp @@ -751,8 +751,8 @@ namespace fheroes2 std::move( disabledWithBackground ) }; } - void fheroes2::getCustomNormalButton( Sprite & released, Sprite & pressed, const bool isEvilInterface, Size buttonSize, Point & releasedOffset, - Point & pressedOffset, const int backgroundIcnId ) + void fheroes2::getCustomNormalButton( Sprite & released, Sprite & pressed, const bool isEvilInterface, Size buttonSize, Point & releasedOffset, Point & pressedOffset, + const int backgroundIcnId ) { assert( buttonSize.width > 0 && buttonSize.height > 0 ); From d9374682cb01ea47d2ca8a98ed3884354b8cce5d Mon Sep 17 00:00:00 2001 From: Zenseii Date: Wed, 5 Feb 2025 12:35:29 +0100 Subject: [PATCH 40/54] Remove unnecessary qualification --- src/fheroes2/gui/ui_button.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fheroes2/gui/ui_button.cpp b/src/fheroes2/gui/ui_button.cpp index 32eb5507969..8bb81d86d50 100644 --- a/src/fheroes2/gui/ui_button.cpp +++ b/src/fheroes2/gui/ui_button.cpp @@ -751,8 +751,8 @@ namespace fheroes2 std::move( disabledWithBackground ) }; } - void fheroes2::getCustomNormalButton( Sprite & released, Sprite & pressed, const bool isEvilInterface, Size buttonSize, Point & releasedOffset, Point & pressedOffset, - const int backgroundIcnId ) + void getCustomNormalButton( Sprite & released, Sprite & pressed, const bool isEvilInterface, Size buttonSize, Point & releasedOffset, Point & pressedOffset, + const int backgroundIcnId ) { assert( buttonSize.width > 0 && buttonSize.height > 0 ); From 4ebc4440c76a8a079ed1557d508d344aa7d0fd59 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Wed, 5 Feb 2025 13:20:10 +0100 Subject: [PATCH 41/54] Fix wrong arguments --- src/fheroes2/agg/agg_image.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 28aeaa17e91..9c3f74784ce 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -734,8 +734,8 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "SAVE\nMAP" ), isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, - isEvilInterface, 86, 56 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "SAVE\nMAP" ), isEvilInterface, + isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 86, 56 ); break; } @@ -751,8 +751,8 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "LOAD\nMAP" ), isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, - isEvilInterface, 86, 56 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "LOAD\nMAP" ), isEvilInterface, + isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 86, 56 ); break; } From 508907a6652fcecf50e17e12b670fc29add2115b Mon Sep 17 00:00:00 2001 From: Zenseii Date: Thu, 6 Feb 2025 00:52:09 +0100 Subject: [PATCH 42/54] Add evil button conversion table --- src/engine/pal.cpp | 15 +++++++++++++++ src/engine/pal.h | 1 + 2 files changed, 16 insertions(+) diff --git a/src/engine/pal.cpp b/src/engine/pal.cpp index 893cfa26a7c..17da40183bc 100644 --- a/src/engine/pal.cpp +++ b/src/engine/pal.cpp @@ -138,6 +138,17 @@ namespace 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, }; + const std::vector goodToEvilButtonTable = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 14, 15, 16, 17, 17, 18, 19, 22, 21, 22, 23, 24, 25, 26, 26, 27, 32, 29, 30, 31, 32, 58, 59, 60, 61, 35, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + }; + const std::vector purpleTable = { 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 131, 132, 133, 133, 134, 135, 136, 136, 137, 138, 139, 139, 140, 141, 142, 142, 143, 144, 145, 145, 146, 147, 148, 149, 149, 150, 151, 131, 132, 133, 134, 134, 135, 136, 137, 138, 138, 139, 140, 141, 142, 142, 143, 144, 145, 146, 146, 147, @@ -229,6 +240,10 @@ const std::vector & PAL::GetPalette( const PaletteType type ) assert( goodToEvilInterfaceTable.size() == paletteSize ); return goodToEvilInterfaceTable; } + case PaletteType::GOOD_TO_EVIL_BUTTON: { + assert( goodToEvilButtonTable.size() == paletteSize ); + return goodToEvilButtonTable; + } case PaletteType::PURPLE: { assert( purpleTable.size() == paletteSize ); return purpleTable; diff --git a/src/engine/pal.h b/src/engine/pal.h index 235561065ff..bd54365f96c 100644 --- a/src/engine/pal.h +++ b/src/engine/pal.h @@ -39,6 +39,7 @@ namespace PAL MIRROR_IMAGE, DARKENING, // for disabled buttons GOOD_TO_EVIL_INTERFACE, // a custom palette for converting Good Interface images into Evil Interface images. + GOOD_TO_EVIL_BUTTON, // for converting Good style buttons into Evil style buttons. PURPLE, // For random object images. CUSTOM }; From 8f29458bbcb9277ba67302237a6c1e98e7cacfcd Mon Sep 17 00:00:00 2001 From: Zenseii Date: Thu, 6 Feb 2025 10:47:07 +0100 Subject: [PATCH 43/54] Use good to evil button conversion Fix all French and Polish variants of min and max buttons --- src/fheroes2/agg/agg_image.cpp | 293 ++++++++++++++++++--------------- 1 file changed, 161 insertions(+), 132 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 9c3f74784ce..e5575a3b5af 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -1142,7 +1142,7 @@ namespace _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::NGEXTRA, 64 ); _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::NGEXTRA, 65 ); if ( isEvilInterface ) { - const std::vector & goodToEvilPalette = PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_INTERFACE ); + const std::vector & goodToEvilPalette = PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ); fheroes2::ApplyPalette( _icnVsSprite[id][0], goodToEvilPalette ); fheroes2::ApplyPalette( _icnVsSprite[id][1], goodToEvilPalette ); } @@ -1152,7 +1152,7 @@ namespace getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "SELECT" ), ICN::EMPTY_MAP_SELECT_BUTTON, ICN::UNKNOWN ); if ( isEvilInterface ) { - const std::vector & goodToEvilPalette = PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_INTERFACE ); + const std::vector & goodToEvilPalette = PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ); fheroes2::ApplyPalette( _icnVsSprite[id][0], goodToEvilPalette ); fheroes2::ApplyPalette( _icnVsSprite[id][1], goodToEvilPalette ); } @@ -1489,24 +1489,21 @@ namespace const bool isEvilInterface = id == ICN::BUTTON_SMALL_MAX_EVIL; - if ( useOriginalResources() && !isEvilInterface ) { + if ( useOriginalResources() ) { // The original assets ICN contains button with shadow. We crop only the button. _icnVsSprite[id][0] = fheroes2::Crop( fheroes2::AGG::GetICN( ICN::RECRUIT, 4 ), 5, 0, 60, 25 ); _icnVsSprite[id][1] = fheroes2::Crop( fheroes2::AGG::GetICN( ICN::RECRUIT, 5 ), 5, 0, 60, 25 ); + _icnVsSprite[id][0].setPosition( 0, 0 ); + _icnVsSprite[id][1].setPosition( 0, 0 ); // To properly generate shadows and Blit the button we need to make some pixels transparent. for ( fheroes2::Sprite & image : _icnVsSprite[id] ) { setButtonCornersTransparent( image ); } - - break; - } - if ( useOriginalResources() && isEvilInterface ) { - _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MAX_GOOD, 0 ); - _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MAX_GOOD, 1 ); - - fheroes2::ApplyPalette( _icnVsSprite[id][0], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_INTERFACE ) ); - fheroes2::ApplyPalette( _icnVsSprite[id][1], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_INTERFACE ) ); + if ( isEvilInterface ) { + fheroes2::ApplyPalette( _icnVsSprite[id][0], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); + fheroes2::ApplyPalette( _icnVsSprite[id][1], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); + } break; } @@ -1516,6 +1513,20 @@ namespace break; } + case ICN::UNIFORM_EVIL_MAX_BUTTON: + case ICN::UNIFORM_GOOD_MAX_BUTTON: + case ICN::UNIFORM_EVIL_MIN_BUTTON: + case ICN::UNIFORM_GOOD_MIN_BUTTON: { + _icnVsSprite[id].resize( 2 ); + + const bool isEvilInterface = ( id == ICN::UNIFORM_EVIL_MAX_BUTTON || id == ICN::UNIFORM_EVIL_MIN_BUTTON ); + + const char * text = ( id == ICN::UNIFORM_GOOD_MIN_BUTTON || id == ICN::UNIFORM_EVIL_MIN_BUTTON ) ? gettext_noop( "MIN" ) : gettext_noop( "MAX" ); + + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], text, isEvilInterface, isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD, 61 ); + + break; + } case ICN::BUTTON_EXIT_GOOD: { _icnVsSprite[id].resize( 2 ); @@ -1584,33 +1595,6 @@ namespace break; } - case ICN::UNIFORM_EVIL_MAX_BUTTON: - case ICN::UNIFORM_EVIL_MIN_BUTTON: - case ICN::UNIFORM_GOOD_MAX_BUTTON: - case ICN::UNIFORM_GOOD_MIN_BUTTON: { - _icnVsSprite[id].resize( 2 ); - - const bool isEvilInterface = ( id == ICN::UNIFORM_EVIL_MAX_BUTTON || id == ICN::UNIFORM_EVIL_MIN_BUTTON ); - if ( useOriginalResources() ) { - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - int buttonIcnId = id == ICN::UNIFORM_GOOD_MAX_BUTTON ? ICN::BUTTON_SMALL_MAX_GOOD : ICN::BUTTON_SMALL_MIN_GOOD; - if ( isEvilInterface ) { - buttonIcnId = id == ICN::UNIFORM_EVIL_MAX_BUTTON ? ICN::BUTTON_SMALL_MAX_EVIL : ICN::BUTTON_SMALL_MIN_EVIL; - } - - released = fheroes2::AGG::GetICN( buttonIcnId, 0 ); - pressed = fheroes2::AGG::GetICN( buttonIcnId, 1 ); - fheroes2::makeTransparentBackground( released, pressed, isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD ); - break; - } - - const char * text = ( id == ICN::UNIFORM_GOOD_MIN_BUTTON || id == ICN::UNIFORM_EVIL_MIN_BUTTON ) ? gettext_noop( "MIN" ) : gettext_noop( "MAX" ); - - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], text, isEvilInterface, isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD, 61 ); - - break; - } case ICN::UNIFORM_GOOD_OKAY_BUTTON: case ICN::UNIFORM_EVIL_OKAY_BUTTON: { _icnVsSprite[id].resize( 2 ); @@ -1916,7 +1900,7 @@ namespace bool generateFrenchSpecificImages( const int id ) { switch ( id ) { - case ICN::BTNBATTLEONLY: + case ICN::BTNBATTLEONLY: { _icnVsSprite[id].resize( 2 ); for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { fheroes2::Sprite & out = _icnVsSprite[id][i]; @@ -1952,109 +1936,69 @@ namespace Copy( fheroes2::AGG::GetICN( ICN::BTNMP, 6 + i ), 73 - i, 22, out, 79 - i, secondLine + 9, 1, 1 ); } return true; - case ICN::BTNGIFT_GOOD: + } + case ICN::BTNGIFT_GOOD: { _icnVsSprite[id].resize( 2 ); for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::TRADPOST, 17 + i ); - // clean the button + const fheroes2::Sprite & original = fheroes2::AGG::GetICN( ICN::TRADPOST, 17 + i ); + // Using this Copy function to convert pressed original from single layered. + Copy( original, out ); + // Clean the button Fill( out, 33, 5, 31, 16, getButtonFillingColor( i == 0 ) ); - const int32_t offsetY = 5; // Add 'D' const int32_t offsetXD = 14; - Blit( fheroes2::AGG::GetICN( ICN::CPANEL, 4 + i ), 48 - i, 28 + i, out, offsetXD - i, offsetY + i, 10, 15 ); + Copy( fheroes2::AGG::GetICN( ICN::CPANEL, 4 + i ), 48 - i, 28 + i, out, offsetXD - i, offsetY + i, 10, 15 ); // Clean up 'D' and restore button ornament - Blit( fheroes2::AGG::GetICN( ICN::CPANEL, 4 + i ), 48 - i, 36, out, offsetXD - 1 - i, offsetY + 4 + i, 1, 1 ); - Blit( fheroes2::AGG::GetICN( ICN::CPANEL, 4 + i ), 48 - i, 35, out, offsetXD - i, offsetY + 9 + i, 1, 2 ); - Blit( fheroes2::AGG::GetICN( ICN::CPANEL, 4 + i ), 48 - i, 35, out, offsetXD - 1 - i, offsetY + 13 + i, 1, 1 ); + Copy( fheroes2::AGG::GetICN( ICN::CPANEL, 4 + i ), 48 - i, 36, out, offsetXD - 1 - i, offsetY + 4 + i, 1, 1 ); + Copy( fheroes2::AGG::GetICN( ICN::CPANEL, 4 + i ), 48 - i, 35, out, offsetXD - i, offsetY + 9 + i, 1, 2 ); + Copy( fheroes2::AGG::GetICN( ICN::CPANEL, 4 + i ), 48 - i, 35, out, offsetXD - 1 - i, offsetY + 13 + i, 1, 1 ); Fill( out, offsetXD + 9 - i, offsetY + 13 + i, 1, 1, getButtonFillingColor( i == 0 ) ); - Blit( fheroes2::AGG::GetICN( ICN::TRADPOST, 17 + i ), offsetXD, offsetY, out, offsetXD, offsetY, 1, 1 ); + Copy( fheroes2::AGG::GetICN( ICN::TRADPOST, 17 + i ), offsetXD, offsetY, out, offsetXD, offsetY, 1, 1 ); // Add 'O' const int32_t offsetXO = 10; - Blit( fheroes2::AGG::GetICN( ICN::CAMPXTRG, i ), 40 - ( 7 * i ), 5 + i, out, offsetXD + offsetXO + 1 - i, offsetY + i, 13 - i, 15 ); + Copy( fheroes2::AGG::GetICN( ICN::CAMPXTRG, i ), 40 - ( 7 * i ), 5 + i, out, offsetXD + offsetXO + 1 - i, offsetY + i, 13 - i, 15 ); // Clean up 'DO' - Blit( fheroes2::AGG::GetICN( ICN::CPANEL, 4 + i ), 51 - i, 34, out, offsetXD + offsetXO - i, offsetY + 5, 2, 2 ); - Blit( fheroes2::AGG::GetICN( ICN::CPANEL, 4 + i ), 51 - i, 34, out, offsetXD + offsetXO - i, offsetY + 7, 1, 1 + i ); - Blit( fheroes2::AGG::GetICN( ICN::CPANEL, 4 + i ), 55 - i, 28 + i, out, offsetXD + 9 - i, offsetY + 2 + i, 3, 3 ); + Copy( fheroes2::AGG::GetICN( ICN::CPANEL, 4 + i ), 51 - i, 34, out, offsetXD + offsetXO - i, offsetY + 5, 2, 2 ); + Copy( fheroes2::AGG::GetICN( ICN::CPANEL, 4 + i ), 51 - i, 34, out, offsetXD + offsetXO - i, offsetY + 7, 1, 1 + i ); + Copy( fheroes2::AGG::GetICN( ICN::CPANEL, 4 + i ), 55 - i, 28 + i, out, offsetXD + 9 - i, offsetY + 2 + i, 3, 3 ); Fill( out, offsetXD + 11 - i, offsetY + i, 2, 2, getButtonFillingColor( i == 0 ) ); // Add 'N' const int32_t offsetXN = 13; - Blit( fheroes2::AGG::GetICN( ICN::TRADPOST, 17 + i ), 50 - i, 5, out, offsetXD + offsetXO + offsetXN - i, offsetY, 14, 15 ); + Copy( fheroes2::AGG::GetICN( ICN::TRADPOST, 17 + i ), 50 - i, 5, out, offsetXD + offsetXO + offsetXN - i, offsetY, 14, 15 ); // Clean up 'ON' Fill( out, offsetXD + offsetXO + offsetXN, offsetY, 1, 1, getButtonFillingColor( i == 0 ) ); Fill( out, offsetXD + offsetXO + offsetXN - i, offsetY + 9, 1, 1, getButtonFillingColor( i == 0 ) ); // Add 'N' - Blit( fheroes2::AGG::GetICN( ICN::TRADPOST, 17 + i ), 50 - i, 5, out, offsetXD + 10 + offsetXN + offsetXN - i, offsetY, 14, 15 ); + Copy( fheroes2::AGG::GetICN( ICN::TRADPOST, 17 + i ), 50 - i, 5, out, offsetXD + 10 + offsetXN + offsetXN - i, offsetY, 14, 15 ); // Clean up 'NN' Fill( out, offsetXD + offsetXO + offsetXN + offsetXN - i, offsetY + 9, 1, 1, getButtonFillingColor( i == 0 ) ); // Add 'ER' - Blit( fheroes2::AGG::GetICN( ICN::CAMPXTRG, 2 + i ), 75 - ( 8 * i ), 5, out, offsetXD + offsetXO + offsetXN + offsetXN + offsetXN - ( 2 * i ), offsetY, + Copy( fheroes2::AGG::GetICN( ICN::CAMPXTRG, 2 + i ), 75 - ( 8 * i ), 5, out, offsetXD + offsetXO + offsetXN + offsetXN + offsetXN - ( 2 * i ), offsetY, 23, 15 ); // Restore button ornament - Blit( fheroes2::AGG::GetICN( ICN::TRADPOST, 17 + i ), offsetXD + offsetXO + offsetXN + offsetXN + offsetXN + 20, offsetY, out, + Copy( fheroes2::AGG::GetICN( ICN::TRADPOST, 17 + i ), offsetXD + offsetXO + offsetXN + offsetXN + offsetXN + 20, offsetY, out, offsetXD + offsetXO + offsetXN + offsetXN + offsetXN + 20, offsetY, 1, 1 ); - Blit( fheroes2::AGG::GetICN( ICN::TRADPOST, 17 + i ), offsetXD + offsetXO + offsetXN + offsetXN + offsetXN + 21, offsetY + 1, out, + Copy( fheroes2::AGG::GetICN( ICN::TRADPOST, 17 + i ), offsetXD + offsetXO + offsetXN + offsetXN + offsetXN + 21, offsetY + 1, out, offsetXD + offsetXO + offsetXN + offsetXN + offsetXN + 21, offsetY + 1, 2, 3 ); - Blit( fheroes2::AGG::GetICN( ICN::TRADPOST, 17 + i ), offsetXD + offsetXO + offsetXN + offsetXN + offsetXN + 20, offsetY, out, + Copy( fheroes2::AGG::GetICN( ICN::TRADPOST, 17 + i ), offsetXD + offsetXO + offsetXN + offsetXN + offsetXN + 20, offsetY, out, offsetXD + offsetXO + offsetXN + offsetXN + offsetXN + 21, offsetY + 4, 1, 1 ); } return true; - case ICN::BTNGIFT_EVIL: + } + case ICN::BTNGIFT_EVIL: { _icnVsSprite[id].resize( 2 ); - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( ICN::TRADPOSE, 17 + i ); - // clean the button - Fill( out, 33, 5, 31, 16, getButtonFillingColor( i == 0, false ) ); - - const int32_t offsetY = 5; - // Add 'D' - const int32_t offsetXD = 14; - Blit( fheroes2::AGG::GetICN( ICN::CPANELE, 4 + i ), 48 - i, 28 + i, out, offsetXD - i, offsetY + i, 10, 15 ); - // Clean up 'D' and restore button ornament - Blit( fheroes2::AGG::GetICN( ICN::CPANELE, 4 + i ), 48 - i, 36, out, offsetXD - 1 - i, offsetY + 4 + i, 1, 1 ); - Blit( fheroes2::AGG::GetICN( ICN::CPANELE, 4 + i ), 48 - i, 35, out, offsetXD - i, offsetY + 9 + i, 1, 2 ); - Blit( fheroes2::AGG::GetICN( ICN::CPANELE, 4 + i ), 48 - i, 35, out, offsetXD - 1 - i, offsetY + 13 + i, 1, 1 ); - Fill( out, offsetXD + 9 - i, offsetY + 13 + i, 1, 1, getButtonFillingColor( i == 0, false ) ); - Blit( fheroes2::AGG::GetICN( ICN::TRADPOSE, 17 + i ), offsetXD, offsetY, out, offsetXD, offsetY, 1, 1 ); - Fill( out, offsetXD + 9 - i, offsetY + i, 1, 1, getButtonFillingColor( i == 0, false ) ); - // Add 'O' - const int32_t offsetXO = 10; - Blit( fheroes2::AGG::GetICN( ICN::APANELE, 4 + i ), 50 - i, 20 + i, out, offsetXD + offsetXO + 1 - i, offsetY + i, 13 - i, 14 ); - // Clean up 'DO' - Blit( fheroes2::AGG::GetICN( ICN::CPANELE, 4 + i ), 51 - i, 34, out, offsetXD + offsetXO - i, offsetY + 5, 2, 2 ); - Blit( fheroes2::AGG::GetICN( ICN::CPANELE, 4 + i ), 51 - i, 34, out, offsetXD + offsetXO - i, offsetY + 7, 1, 1 + i ); - Blit( fheroes2::AGG::GetICN( ICN::CPANELE, 4 + i ), 56 - i, 28 + i, out, offsetXD + 10 - i, offsetY + 2 + i, 1, 3 ); - Blit( fheroes2::AGG::GetICN( ICN::CPANELE, 4 + i ), 56 - i, 28 + i, out, offsetXD + 11 - i, offsetY + 3 + i, 1, 2 ); - Fill( out, offsetXD + 11 - i, offsetY + i, 3, 3, getButtonFillingColor( i == 0, false ) ); - Fill( out, offsetXD + 12 - i, offsetY + 3 + i, 1, 2, getButtonFillingColor( i == 0, false ) ); - // Add 'N' - const int32_t offsetXN = 13; - Blit( fheroes2::AGG::GetICN( ICN::TRADPOSE, 17 + i ), 50 - i, 5, out, offsetXD + offsetXO + offsetXN - i, offsetY, 14, 15 ); - // Clean up 'ON' - Fill( out, offsetXD + offsetXO + offsetXN - 1 - i, offsetY + 11 + i, 1, 3, getButtonFillingColor( i == 0, false ) ); - Fill( out, offsetXD + offsetXO + offsetXN - i, offsetY, 1, 1, getButtonFillingColor( i == 0, false ) ); - Fill( out, offsetXD + offsetXO + offsetXN - i, offsetY + 9, 1, 1, getButtonFillingColor( i == 0, false ) ); - // Add 'N' - Blit( fheroes2::AGG::GetICN( ICN::TRADPOSE, 17 + i ), 50 - i, 5, out, offsetXD + offsetXO + offsetXN + offsetXN - i, offsetY, 13, 15 ); - // Clean up 'NN' - Fill( out, offsetXD + offsetXO + offsetXN + offsetXN - i, offsetY + 9, 1, 1, getButtonFillingColor( i == 0, false ) ); - // Add 'ER' - Blit( fheroes2::AGG::GetICN( ICN::APANELE, 8 + i ), 66 - ( 3 * i ), 5 + ( 2 * i ), out, offsetXD + offsetXO + offsetXN + offsetXN + offsetXN - ( 2 * i ), - offsetY + ( 2 * i ), 23, 14 - i ); - // Clean up 'NE' - Blit( fheroes2::AGG::GetICN( ICN::TRADPOSE, 17 + i ), 50 - i, 5, out, offsetXD + offsetXO + offsetXN + offsetXN + offsetXN - i, offsetY, 2, 10 ); - Fill( out, offsetXD + offsetXO + offsetXN + offsetXN + offsetXN - ( 2 * i ), offsetY + 9 + i, 1 + i, 2 + i, getButtonFillingColor( i == 0, false ) ); - // Restore button ornament - Blit( fheroes2::AGG::GetICN( ICN::TRADPOSE, 17 + i ), offsetXD + offsetXO + offsetXN + offsetXN + offsetXN + 20, offsetY, out, - offsetXD + offsetXO + offsetXN + offsetXN + offsetXN + 20, offsetY, 1, 1 ); - Blit( fheroes2::AGG::GetICN( ICN::TRADPOSE, 17 + i ), offsetXD + offsetXO + offsetXN + offsetXN + offsetXN + 21, offsetY + 1, out, - offsetXD + offsetXO + offsetXN + offsetXN + offsetXN + 21, offsetY + 1, 2, 3 ); - Blit( fheroes2::AGG::GetICN( ICN::TRADPOSE, 17 + i ), offsetXD + offsetXO + offsetXN + offsetXN + offsetXN + 20, offsetY, out, - offsetXD + offsetXO + offsetXN + offsetXN + offsetXN + 21, offsetY + 4, 1, 1 ); - } + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; + const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNGIFT_GOOD, 0 ); + released = originalReleased; + pressed = fheroes2::AGG::GetICN( ICN::BTNGIFT_GOOD, 1 ); + ApplyPalette( released, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); + ApplyPalette( pressed, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); + fheroes2::makeTransparentBackground( released, pressed, ICN::UNIFORMBAK_EVIL ); return true; + } case ICN::BUTTON_SMALL_MAX_GOOD: { _icnVsSprite[id].resize( 2 ); fheroes2::Sprite & released = _icnVsSprite[id][0]; @@ -2064,13 +2008,13 @@ namespace released = originalReleased; pressed = originalPressed; // The original assets ICN contains button with shadow. We crop only the button. - released = fheroes2::Crop( originalReleased, 5, 0, 60, 25 ); - pressed = fheroes2::Crop( originalPressed, 5, 0, 60, 25 ); + released = Crop( originalReleased, 5, 0, 60, 25 ); + pressed = Crop( originalPressed, 5, 0, 60, 25 ); released.setPosition( 0, 0 ); pressed.setPosition( 0, 0 ); // Fill wrong transparent text pixels with color. fheroes2::Image whiteBackground( released.width(), released.height() ); - fheroes2::Fill( whiteBackground, 0, 0, released.width(), released.height(), 10 ); + Fill( whiteBackground, 0, 0, released.width(), released.height(), 10 ); Blit( released, whiteBackground ); released = whiteBackground; // To properly generate shadows and Blit the button we need to make some pixels transparent. @@ -2078,14 +2022,14 @@ namespace setButtonCornersTransparent( image ); } fheroes2::Image common = fheroes2::ExtractCommonPattern( { &released, &pressed } ); - common = fheroes2::FilterOnePixelNoise( common ); - common = fheroes2::FilterOnePixelNoise( common ); - common = fheroes2::FilterOnePixelNoise( common ); - fheroes2::Blit( common, _icnVsSprite[id][0] ); + common = FilterOnePixelNoise( common ); + common = FilterOnePixelNoise( common ); + common = FilterOnePixelNoise( common ); + Blit( common, _icnVsSprite[id][0] ); return true; } - case ICN::BUTTON_SMALL_MIN_GOOD: + case ICN::BUTTON_SMALL_MIN_GOOD: { _icnVsSprite[id].resize( 2 ); for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { fheroes2::Sprite & out = _icnVsSprite[id][i]; @@ -2103,13 +2047,53 @@ namespace Fill( out, 36 - i, 5 + 9, 1, 1, getButtonFillingColor( i == 0 ) ); } return true; - case ICN::BUTTON_SMALL_MIN_EVIL: + } + case ICN::UNIFORM_GOOD_MIN_BUTTON: + case ICN::UNIFORM_GOOD_MAX_BUTTON: { + _icnVsSprite[id].resize( 2 ); + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; + const bool maxButton = id == ICN::UNIFORM_GOOD_MAX_BUTTON; + const int buttonIcnID = maxButton ? ICN::BUTTON_SMALL_MAX_GOOD : ICN::BUTTON_SMALL_MIN_GOOD; + released = fheroes2::AGG::GetICN( buttonIcnID, 0 ); + pressed = fheroes2::AGG::GetICN( buttonIcnID, 1 ); + // Clean the borders of the pressed state. + FillTransform( pressed, 4, 0, 54, 1, 1 ); + FillTransform( pressed, 57, 1, 2, 1, 1 ); + FillTransform( pressed, 58, 2, 2, 1, 1 ); + FillTransform( pressed, 59, 3, 1, 18, 1 ); + fheroes2::makeTransparentBackground( released, pressed, ICN::UNIFORMBAK_GOOD ); + + return true; + } + case ICN::UNIFORM_EVIL_MAX_BUTTON: + case ICN::UNIFORM_EVIL_MIN_BUTTON: { _icnVsSprite[id].resize( 2 ); - _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MIN_GOOD, 0 ); - _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MIN_GOOD, 1 ); - fheroes2::ApplyPalette( _icnVsSprite[id][0], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_INTERFACE ) ); - fheroes2::ApplyPalette( _icnVsSprite[id][1], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_INTERFACE ) ); + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; + const bool isMaxButton = id == ICN::UNIFORM_EVIL_MAX_BUTTON; + const int buttonIcnID = isMaxButton ? ICN::UNIFORM_GOOD_MAX_BUTTON : ICN::UNIFORM_GOOD_MIN_BUTTON; + released = fheroes2::AGG::GetICN( buttonIcnID, 0 ); + pressed = fheroes2::AGG::GetICN( buttonIcnID, 1 ); + ApplyPalette( released, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); + ApplyPalette( pressed, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); + return true; + } + case ICN::BUTTON_SMALL_MAX_EVIL: + case ICN::BUTTON_SMALL_MIN_EVIL: { + _icnVsSprite[id].resize( 2 ); + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; + const bool isMaxButton = id == ICN::BUTTON_SMALL_MAX_EVIL; + const int buttonIcnID = isMaxButton ? ICN::BUTTON_SMALL_MAX_GOOD : ICN::BUTTON_SMALL_MIN_GOOD; + released = fheroes2::AGG::GetICN( buttonIcnID, 0 ); + pressed = fheroes2::AGG::GetICN( buttonIcnID, 1 ); + ApplyPalette( released, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); + ApplyPalette( pressed, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); + + return true; + } default: break; } @@ -2119,7 +2103,7 @@ namespace bool generatePolishSpecificImages( const int id ) { switch ( id ) { - case ICN::BTNBATTLEONLY: + case ICN::BTNBATTLEONLY: { _icnVsSprite[id].resize( 2 ); for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { fheroes2::Sprite & out = _icnVsSprite[id][i]; @@ -2138,7 +2122,8 @@ namespace Copy( fheroes2::AGG::GetICN( ICN::BTNEMAIN, 0 + i ), 47 - i, 23 + i, out, offsetX + 38 - i, offsetY + i, 1, 1 ); } return true; - case ICN::BUTTON_SMALL_MIN_GOOD: + } + case ICN::BUTTON_SMALL_MIN_GOOD: { _icnVsSprite[id].resize( 2 ); for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { fheroes2::Sprite & out = _icnVsSprite[id][i]; @@ -2158,15 +2143,59 @@ namespace if ( i == 0 ) { fheroes2::ReplaceColorId( out, 56, 55 ); } + if ( id == ICN::BUTTON_SMALL_MIN_EVIL ) { + ApplyPalette( _icnVsSprite[id][0], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); + ApplyPalette( _icnVsSprite[id][1], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); + } } return true; - case ICN::BUTTON_SMALL_MIN_EVIL: + } + case ICN::BUTTON_SMALL_MAX_EVIL: + case ICN::BUTTON_SMALL_MIN_EVIL: { _icnVsSprite[id].resize( 2 ); - _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MIN_GOOD, 0 ); - _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MIN_GOOD, 1 ); - fheroes2::ApplyPalette( _icnVsSprite[id][0], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_INTERFACE ) ); - fheroes2::ApplyPalette( _icnVsSprite[id][1], PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_INTERFACE ) ); + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; + const bool isMaxButton = id == ICN::BUTTON_SMALL_MAX_EVIL; + const int buttonIcnID = isMaxButton ? ICN::BUTTON_SMALL_MAX_GOOD : ICN::BUTTON_SMALL_MIN_GOOD; + released = fheroes2::AGG::GetICN( buttonIcnID, 0 ); + pressed = fheroes2::AGG::GetICN( buttonIcnID, 1 ); + ApplyPalette( released, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); + ApplyPalette( pressed, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); + + return true; + } + case ICN::UNIFORM_GOOD_MIN_BUTTON: + case ICN::UNIFORM_GOOD_MAX_BUTTON: { + _icnVsSprite[id].resize( 2 ); + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; + const bool maxButton = id == ICN::UNIFORM_GOOD_MAX_BUTTON; + const int buttonIcnID = maxButton ? ICN::BUTTON_SMALL_MAX_GOOD : ICN::BUTTON_SMALL_MIN_GOOD; + released = fheroes2::AGG::GetICN( buttonIcnID, 0 ); + pressed = fheroes2::AGG::GetICN( buttonIcnID, 1 ); + // Clean the borders of the pressed state. + FillTransform( pressed, 4, 0, 54, 1, 1 ); + FillTransform( pressed, 57, 1, 2, 1, 1 ); + FillTransform( pressed, 58, 2, 2, 1, 1 ); + FillTransform( pressed, 59, 3, 1, 18, 1 ); + fheroes2::makeTransparentBackground( released, pressed, ICN::UNIFORMBAK_GOOD ); + return true; + } + case ICN::UNIFORM_EVIL_MAX_BUTTON: + case ICN::UNIFORM_EVIL_MIN_BUTTON: { + _icnVsSprite[id].resize( 2 ); + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; + const bool isMaxButton = id == ICN::UNIFORM_EVIL_MAX_BUTTON; + const int buttonIcnID = isMaxButton ? ICN::UNIFORM_GOOD_MAX_BUTTON : ICN::UNIFORM_GOOD_MIN_BUTTON; + released = fheroes2::AGG::GetICN( buttonIcnID, 0 ); + pressed = fheroes2::AGG::GetICN( buttonIcnID, 1 ); + ApplyPalette( released, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); + ApplyPalette( pressed, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); + + return true; + } default: break; } From 67f9d1081e92430a5458c9a97da709ccf66bfbf9 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Thu, 6 Feb 2025 13:34:57 +0100 Subject: [PATCH 44/54] Adjust max min recruit button placement now that offset post crop is fixed --- src/fheroes2/dialog/dialog_recruit.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/fheroes2/dialog/dialog_recruit.cpp b/src/fheroes2/dialog/dialog_recruit.cpp index f7e3559a9cd..64fc1c3c4a7 100644 --- a/src/fheroes2/dialog/dialog_recruit.cpp +++ b/src/fheroes2/dialog/dialog_recruit.cpp @@ -314,10 +314,11 @@ Troop Dialog::RecruitMonster( const Monster & monster0, const uint32_t available fheroes2::Button buttonCancel( dst_pt.x, dst_pt.y, buttonId, 0, 1 ); drawButtonShadow( display, buttonId, 0, dst_pt ); - dst_pt.x = dialogOffset.x + 218; + buttonId = isEvilInterface ? ICN::BUTTON_SMALL_MAX_EVIL : ICN::BUTTON_SMALL_MAX_GOOD; + const int32_t buttonMaxWidth = fheroes2::AGG ::GetICN( buttonId, 0 ).width(); + dst_pt.x = dialogOffset.x + 253 - buttonMaxWidth / 2; dst_pt.y = dialogOffset.y + 140; - buttonId = isEvilInterface ? ICN::BUTTON_SMALL_MAX_EVIL : ICN::BUTTON_SMALL_MAX_GOOD; fheroes2::Button buttonMax( dst_pt.x, dst_pt.y, buttonId, 0, 1 ); fheroes2::Button buttonMin( dst_pt.x, dst_pt.y, isEvilInterface ? ICN::BUTTON_SMALL_MIN_EVIL : ICN::BUTTON_SMALL_MIN_GOOD, 0, 1 ); drawButtonShadow( display, buttonId, 0, dst_pt ); From a3814a6ef2b994e0c64f99d89da5acf58d9ae766 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Thu, 6 Feb 2025 15:03:49 +0100 Subject: [PATCH 45/54] Improve button shine --- src/fheroes2/gui/ui_button.cpp | 63 +++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/src/fheroes2/gui/ui_button.cpp b/src/fheroes2/gui/ui_button.cpp index 8bb81d86d50..45b966e0e2b 100644 --- a/src/fheroes2/gui/ui_button.cpp +++ b/src/fheroes2/gui/ui_button.cpp @@ -214,7 +214,7 @@ namespace const bool isGoodButton = ( emptyButtonIcnID == ICN::EMPTY_GOOD_BUTTON ); if ( isGoodButton || emptyButtonIcnID == ICN::EMPTY_EVIL_BUTTON ) { const uint8_t firstColor = 10; - const uint8_t secondColor = isGoodButton ? 38 : 15; + const uint8_t secondColor = isGoodButton ? 37 : 15; const uint8_t lastColor = isGoodButton ? 39 : 16; // Left-side shine fheroes2::SetPixel( buttonImage, 11, 4, firstColor ); @@ -225,10 +225,63 @@ namespace fheroes2::SetPixel( buttonImage, 8, 7, lastColor ); fheroes2::SetPixel( buttonImage, 15, 4, lastColor ); // Right-side shine - fheroes2::SetPixel( buttonImage, buttonImage.width() - 9, 4, firstColor ); - fheroes2::SetPixel( buttonImage, buttonImage.width() - 7, 4, firstColor ); - fheroes2::DrawLine( buttonImage, { buttonImage.width() - 10, 5 }, { buttonImage.width() - 11, 6 }, secondColor ); - fheroes2::SetPixel( buttonImage, buttonImage.width() - 8, 5, secondColor ); + const int32_t buttonWidth = buttonImage.width(); + fheroes2::SetPixel( buttonImage, buttonWidth - 9, 4, firstColor ); + fheroes2::SetPixel( buttonImage, buttonWidth - 7, 4, firstColor ); + fheroes2::DrawLine( buttonImage, { buttonWidth - 10, 5 }, { buttonWidth - 11, 6 }, secondColor ); + fheroes2::SetPixel( buttonImage, buttonWidth - 8, 5, secondColor ); + + const int32_t buttonHeight = buttonImage.height(); + // To avoid overcrowding the ',,,' virtual keyboard button with decorations we set 50. + if ( buttonWidth > 50 ) { + // Longer left-side shine + fheroes2::DrawLine( buttonImage, { 11, 4 }, { 9, 6 }, firstColor ); + fheroes2::SetPixel( buttonImage, 8, 7, lastColor ); + fheroes2::SetPixel( buttonImage, 13, 4, secondColor ); + fheroes2::DrawLine( buttonImage, { 12, 5 }, { 9, 8 }, lastColor ); + fheroes2::DrawLine( buttonImage, { 8, 9 }, { 7, 10 }, firstColor ); + fheroes2::SetPixel( buttonImage, 6, 11, lastColor ); + fheroes2::DrawLine( buttonImage, { 15, 4 }, { 13, 6 }, firstColor ); + fheroes2::SetPixel( buttonImage, 12, 7, lastColor ); + + // Longer right-side shine + fheroes2::SetPixel( buttonImage, buttonWidth - 10, 2, firstColor ); + fheroes2::SetPixel( buttonImage, buttonWidth - 8, 3, secondColor ); + fheroes2::SetPixel( buttonImage, buttonWidth - 11, 3, secondColor ); + fheroes2::SetPixel( buttonImage, buttonWidth - 12, 4, firstColor ); + fheroes2::DrawLine( buttonImage, { buttonWidth - 13, 5 }, { buttonWidth - 14, 6 }, lastColor ); + fheroes2::DrawLine( buttonImage, { buttonWidth - 10, 5 }, { buttonWidth - 12, 7 }, firstColor ); + fheroes2::DrawLine( buttonImage, { buttonWidth - 13, 8 }, { buttonWidth - 14, 9 }, secondColor ); + fheroes2::DrawLine( buttonImage, { buttonWidth - 8, 5 }, { buttonWidth - 10, 7 }, firstColor ); + fheroes2::SetPixel( buttonImage, buttonWidth - 11, 8, lastColor ); + // Bottom left-side shine + fheroes2::SetPixel( buttonImage, 11, buttonHeight - 6, lastColor ); + fheroes2::DrawLine( buttonImage, { 12, buttonHeight - 7 }, { 13, buttonHeight - 8 }, firstColor ); + fheroes2::SetPixel( buttonImage, 14, buttonHeight - 9, lastColor ); + if ( buttonWidth > 96 || buttonHeight > 25 ) { + // Longer bottom left shine + fheroes2::SetPixel( buttonImage, 10, buttonHeight - 5, lastColor ); + // Center part shine + fheroes2::SetPixel( buttonImage, 30, buttonHeight - 5, secondColor ); + fheroes2::SetPixel( buttonImage, 31, buttonHeight - 6, lastColor ); + fheroes2::DrawLine( buttonImage, { 32, buttonHeight - 5 }, { 34, buttonHeight - 7 }, firstColor ); + fheroes2::SetPixel( buttonImage, 35, buttonHeight - 8, secondColor ); + fheroes2::SetPixel( buttonImage, 36, buttonHeight - 9, lastColor ); + fheroes2::SetPixel( buttonImage, 34, buttonHeight - 5, secondColor ); + fheroes2::SetPixel( buttonImage, 35, buttonHeight - 6, lastColor ); + } + + if ( buttonHeight > 25 ) { + // Bottom right-side shine + fheroes2::DrawLine( buttonImage, { buttonWidth - 20, buttonHeight - 5 }, { buttonWidth - 16, buttonHeight - 9 }, secondColor ); + fheroes2::SetPixel( buttonImage, buttonWidth - 15, buttonHeight - 10, lastColor ); + fheroes2::DrawLine( buttonImage, { buttonWidth - 18, buttonHeight - 5 }, { buttonWidth - 14, buttonHeight - 9 }, firstColor ); + fheroes2::DrawLine( buttonImage, { buttonWidth - 13, buttonHeight - 10 }, { buttonWidth - 12, buttonHeight - 11 }, secondColor ); + fheroes2::DrawLine( buttonImage, { buttonWidth - 11, buttonHeight - 12 }, { buttonWidth - 10, buttonHeight - 13 }, lastColor ); + fheroes2::DrawLine( buttonImage, { buttonWidth - 16, buttonHeight - 5 }, { buttonWidth - 12, buttonHeight - 9 }, secondColor ); + fheroes2::SetPixel( buttonImage, buttonWidth - 11, buttonHeight - 10, lastColor ); + } + } } } From e3aefa2bac31392714bebfafb2abdf59d973f21c Mon Sep 17 00:00:00 2001 From: Zenseii Date: Thu, 6 Feb 2025 15:06:54 +0100 Subject: [PATCH 46/54] Copyright year --- src/engine/pal.cpp | 2 +- src/fheroes2/dialog/dialog_recruit.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/pal.cpp b/src/engine/pal.cpp index 17da40183bc..2bb30471e10 100644 --- a/src/engine/pal.cpp +++ b/src/engine/pal.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2020 - 2024 * + * Copyright (C) 2020 - 2025 * * * * 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 * diff --git a/src/fheroes2/dialog/dialog_recruit.cpp b/src/fheroes2/dialog/dialog_recruit.cpp index 64fc1c3c4a7..8e62780fc55 100644 --- a/src/fheroes2/dialog/dialog_recruit.cpp +++ b/src/fheroes2/dialog/dialog_recruit.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2019 - 2024 * + * Copyright (C) 2019 - 2025 * * * * Free Heroes2 Engine: http://sourceforge.net/projects/fheroes2 * * Copyright (C) 2009 by Andrey Afletdinov * From 4a97802a23a96c9fd4f3d632a6d147ee79bbd225 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Thu, 6 Feb 2025 15:38:09 +0100 Subject: [PATCH 47/54] Unite evil and uniform max/min button generations Rename buy max and gift button names --- src/fheroes2/agg/agg_image.cpp | 187 +++++++-------------- src/fheroes2/agg/icn.h | 6 +- src/fheroes2/castle/castle_well.cpp | 4 +- src/fheroes2/dialog/dialog_marketplace.cpp | 2 +- 4 files changed, 70 insertions(+), 129 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index e5575a3b5af..1d036938a81 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -73,7 +73,7 @@ namespace // Some resources are language dependent. These are mostly buttons with a text of them. // Once a user changes a language we have to update resources. To do this we need to clear the existing images. - const std::set languageDependentIcnId{ ICN::BUYMAX, + const std::set languageDependentIcnId{ ICN::BUTTON_WELL_MAX, ICN::BUTTON_NEW_GAME_GOOD, ICN::BUTTON_NEW_GAME_EVIL, ICN::BUTTON_SAVE_GAME_GOOD, @@ -142,8 +142,8 @@ namespace ICN::BUTTON_5_PLAYERS, ICN::BUTTON_6_PLAYERS, ICN::BTNBATTLEONLY, - ICN::BTNGIFT_GOOD, - ICN::BTNGIFT_EVIL, + ICN::BUTTON_GIFT_GOOD, + ICN::BUTTON_GIFT_EVIL, ICN::UNIFORM_EVIL_MAX_BUTTON, ICN::UNIFORM_EVIL_MIN_BUTTON, ICN::UNIFORM_GOOD_MAX_BUTTON, @@ -1331,11 +1331,10 @@ namespace break; } - case ICN::BTNGIFT_GOOD: - case ICN::BTNGIFT_EVIL: { + case ICN::BUTTON_GIFT_GOOD: { _icnVsSprite[id].resize( 2 ); - const bool isEvilInterface = ( id == ICN::BTNGIFT_EVIL ); + const bool isEvilInterface = ( id == ICN::BUTTON_GIFT_EVIL ); fheroes2::getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "GIFT" ), isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, @@ -1343,7 +1342,20 @@ namespace break; } - case ICN::BUYMAX: { + case ICN::BUTTON_GIFT_EVIL: { + // To preserve language-specific generations from generateLanguageSpecificImages() we do a palette swap. + _icnVsSprite[id].resize( 2 ); + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; + const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BUTTON_GIFT_GOOD, 0 ); + released = originalReleased; + pressed = fheroes2::AGG::GetICN( ICN::BUTTON_GIFT_GOOD, 1 ); + ApplyPalette( released, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); + ApplyPalette( pressed, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); + fheroes2::makeTransparentBackground( released, pressed, ICN::UNIFORMBAK_EVIL ); + break; + } + case ICN::BUTTON_WELL_MAX: { _icnVsSprite[id].resize( 2 ); getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MAX" ), ICN::EMPTY_GUILDWELL_BUTTON, ICN::UNKNOWN ); @@ -1472,8 +1484,7 @@ namespace break; } - case ICN::BUTTON_SMALL_MIN_GOOD: - case ICN::BUTTON_SMALL_MIN_EVIL: { + case ICN::BUTTON_SMALL_MIN_GOOD: { _icnVsSprite[id].resize( 2 ); const bool isEvilInterface = id == ICN::BUTTON_SMALL_MIN_EVIL; @@ -1483,7 +1494,6 @@ namespace break; } - case ICN::BUTTON_SMALL_MAX_EVIL: case ICN::BUTTON_SMALL_MAX_GOOD: { _icnVsSprite[id].resize( 2 ); @@ -1513,17 +1523,52 @@ namespace break; } - case ICN::UNIFORM_EVIL_MAX_BUTTON: - case ICN::UNIFORM_GOOD_MAX_BUTTON: - case ICN::UNIFORM_EVIL_MIN_BUTTON: - case ICN::UNIFORM_GOOD_MIN_BUTTON: { + case ICN::UNIFORM_GOOD_MIN_BUTTON: + case ICN::UNIFORM_GOOD_MAX_BUTTON: { + // To preserve language-specific generations from generateLanguageSpecificImages() we clean the non uniform button. _icnVsSprite[id].resize( 2 ); + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; + const bool maxButton = id == ICN::UNIFORM_GOOD_MAX_BUTTON; + const int buttonIcnID = maxButton ? ICN::BUTTON_SMALL_MAX_GOOD : ICN::BUTTON_SMALL_MIN_GOOD; + released = fheroes2::AGG::GetICN( buttonIcnID, 0 ); + pressed = fheroes2::AGG::GetICN( buttonIcnID, 1 ); + // Clean the borders of the pressed state. + FillTransform( pressed, 4, 0, pressed.width() - 3, 1, 1 ); + FillTransform( pressed, pressed.width() - 3, 1, 2, 1, 1 ); + FillTransform( pressed, pressed.width() - 2, 2, 2, 1, 1 ); + FillTransform( pressed, pressed.width() - 1, 3, 1, pressed.height() - 5, 1 ); + fheroes2::makeTransparentBackground( released, pressed, ICN::UNIFORMBAK_GOOD ); - const bool isEvilInterface = ( id == ICN::UNIFORM_EVIL_MAX_BUTTON || id == ICN::UNIFORM_EVIL_MIN_BUTTON ); - - const char * text = ( id == ICN::UNIFORM_GOOD_MIN_BUTTON || id == ICN::UNIFORM_EVIL_MIN_BUTTON ) ? gettext_noop( "MIN" ) : gettext_noop( "MAX" ); + break; + } + case ICN::UNIFORM_EVIL_MAX_BUTTON: + case ICN::UNIFORM_EVIL_MIN_BUTTON: { + // To preserve language-specific generations from generateLanguageSpecificImages() we do a palette swap. + _icnVsSprite[id].resize( 2 ); + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; + const bool isMaxButton = id == ICN::UNIFORM_EVIL_MAX_BUTTON; + const int buttonIcnID = isMaxButton ? ICN::UNIFORM_GOOD_MAX_BUTTON : ICN::UNIFORM_GOOD_MIN_BUTTON; + released = fheroes2::AGG::GetICN( buttonIcnID, 0 ); + pressed = fheroes2::AGG::GetICN( buttonIcnID, 1 ); + ApplyPalette( released, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); + ApplyPalette( pressed, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], text, isEvilInterface, isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD, 61 ); + break; + } + case ICN::BUTTON_SMALL_MAX_EVIL: + case ICN::BUTTON_SMALL_MIN_EVIL: { + // To preserve language-specific generations from generateLanguageSpecificImages() we do a palette swap. + _icnVsSprite[id].resize( 2 ); + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; + const bool isMaxButton = id == ICN::BUTTON_SMALL_MAX_EVIL; + const int buttonIcnID = isMaxButton ? ICN::BUTTON_SMALL_MAX_GOOD : ICN::BUTTON_SMALL_MIN_GOOD; + released = fheroes2::AGG::GetICN( buttonIcnID, 0 ); + pressed = fheroes2::AGG::GetICN( buttonIcnID, 1 ); + ApplyPalette( released, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); + ApplyPalette( pressed, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); break; } @@ -1937,7 +1982,7 @@ namespace } return true; } - case ICN::BTNGIFT_GOOD: { + case ICN::BUTTON_GIFT_GOOD: { _icnVsSprite[id].resize( 2 ); for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { fheroes2::Sprite & out = _icnVsSprite[id][i]; @@ -1987,18 +2032,6 @@ namespace } return true; } - case ICN::BTNGIFT_EVIL: { - _icnVsSprite[id].resize( 2 ); - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - const fheroes2::Sprite & originalReleased = fheroes2::AGG::GetICN( ICN::BTNGIFT_GOOD, 0 ); - released = originalReleased; - pressed = fheroes2::AGG::GetICN( ICN::BTNGIFT_GOOD, 1 ); - ApplyPalette( released, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); - ApplyPalette( pressed, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); - fheroes2::makeTransparentBackground( released, pressed, ICN::UNIFORMBAK_EVIL ); - return true; - } case ICN::BUTTON_SMALL_MAX_GOOD: { _icnVsSprite[id].resize( 2 ); fheroes2::Sprite & released = _icnVsSprite[id][0]; @@ -2048,52 +2081,6 @@ namespace } return true; } - case ICN::UNIFORM_GOOD_MIN_BUTTON: - case ICN::UNIFORM_GOOD_MAX_BUTTON: { - _icnVsSprite[id].resize( 2 ); - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - const bool maxButton = id == ICN::UNIFORM_GOOD_MAX_BUTTON; - const int buttonIcnID = maxButton ? ICN::BUTTON_SMALL_MAX_GOOD : ICN::BUTTON_SMALL_MIN_GOOD; - released = fheroes2::AGG::GetICN( buttonIcnID, 0 ); - pressed = fheroes2::AGG::GetICN( buttonIcnID, 1 ); - // Clean the borders of the pressed state. - FillTransform( pressed, 4, 0, 54, 1, 1 ); - FillTransform( pressed, 57, 1, 2, 1, 1 ); - FillTransform( pressed, 58, 2, 2, 1, 1 ); - FillTransform( pressed, 59, 3, 1, 18, 1 ); - fheroes2::makeTransparentBackground( released, pressed, ICN::UNIFORMBAK_GOOD ); - - return true; - } - case ICN::UNIFORM_EVIL_MAX_BUTTON: - case ICN::UNIFORM_EVIL_MIN_BUTTON: { - _icnVsSprite[id].resize( 2 ); - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - const bool isMaxButton = id == ICN::UNIFORM_EVIL_MAX_BUTTON; - const int buttonIcnID = isMaxButton ? ICN::UNIFORM_GOOD_MAX_BUTTON : ICN::UNIFORM_GOOD_MIN_BUTTON; - released = fheroes2::AGG::GetICN( buttonIcnID, 0 ); - pressed = fheroes2::AGG::GetICN( buttonIcnID, 1 ); - ApplyPalette( released, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); - ApplyPalette( pressed, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); - - return true; - } - case ICN::BUTTON_SMALL_MAX_EVIL: - case ICN::BUTTON_SMALL_MIN_EVIL: { - _icnVsSprite[id].resize( 2 ); - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - const bool isMaxButton = id == ICN::BUTTON_SMALL_MAX_EVIL; - const int buttonIcnID = isMaxButton ? ICN::BUTTON_SMALL_MAX_GOOD : ICN::BUTTON_SMALL_MIN_GOOD; - released = fheroes2::AGG::GetICN( buttonIcnID, 0 ); - pressed = fheroes2::AGG::GetICN( buttonIcnID, 1 ); - ApplyPalette( released, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); - ApplyPalette( pressed, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); - - return true; - } default: break; } @@ -2150,52 +2137,6 @@ namespace } return true; } - case ICN::BUTTON_SMALL_MAX_EVIL: - case ICN::BUTTON_SMALL_MIN_EVIL: { - _icnVsSprite[id].resize( 2 ); - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - const bool isMaxButton = id == ICN::BUTTON_SMALL_MAX_EVIL; - const int buttonIcnID = isMaxButton ? ICN::BUTTON_SMALL_MAX_GOOD : ICN::BUTTON_SMALL_MIN_GOOD; - released = fheroes2::AGG::GetICN( buttonIcnID, 0 ); - pressed = fheroes2::AGG::GetICN( buttonIcnID, 1 ); - ApplyPalette( released, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); - ApplyPalette( pressed, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); - - return true; - } - case ICN::UNIFORM_GOOD_MIN_BUTTON: - case ICN::UNIFORM_GOOD_MAX_BUTTON: { - _icnVsSprite[id].resize( 2 ); - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - const bool maxButton = id == ICN::UNIFORM_GOOD_MAX_BUTTON; - const int buttonIcnID = maxButton ? ICN::BUTTON_SMALL_MAX_GOOD : ICN::BUTTON_SMALL_MIN_GOOD; - released = fheroes2::AGG::GetICN( buttonIcnID, 0 ); - pressed = fheroes2::AGG::GetICN( buttonIcnID, 1 ); - // Clean the borders of the pressed state. - FillTransform( pressed, 4, 0, 54, 1, 1 ); - FillTransform( pressed, 57, 1, 2, 1, 1 ); - FillTransform( pressed, 58, 2, 2, 1, 1 ); - FillTransform( pressed, 59, 3, 1, 18, 1 ); - fheroes2::makeTransparentBackground( released, pressed, ICN::UNIFORMBAK_GOOD ); - - return true; - } - case ICN::UNIFORM_EVIL_MAX_BUTTON: - case ICN::UNIFORM_EVIL_MIN_BUTTON: { - _icnVsSprite[id].resize( 2 ); - fheroes2::Sprite & released = _icnVsSprite[id][0]; - fheroes2::Sprite & pressed = _icnVsSprite[id][1]; - const bool isMaxButton = id == ICN::UNIFORM_EVIL_MAX_BUTTON; - const int buttonIcnID = isMaxButton ? ICN::UNIFORM_GOOD_MAX_BUTTON : ICN::UNIFORM_GOOD_MIN_BUTTON; - released = fheroes2::AGG::GetICN( buttonIcnID, 0 ); - pressed = fheroes2::AGG::GetICN( buttonIcnID, 1 ); - ApplyPalette( released, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); - ApplyPalette( pressed, PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ) ); - - return true; - } default: break; } diff --git a/src/fheroes2/agg/icn.h b/src/fheroes2/agg/icn.h index 1c62d63c558..2cd90c1a21d 100644 --- a/src/fheroes2/agg/icn.h +++ b/src/fheroes2/agg/icn.h @@ -908,10 +908,10 @@ namespace ICN ROUTERED, YELLOW_FONT, YELLOW_SMALLFONT, - BUYMAX, + BUTTON_WELL_MAX, BTNBATTLEONLY, - BTNGIFT_GOOD, - BTNGIFT_EVIL, + BUTTON_GIFT_GOOD, + BUTTON_GIFT_EVIL, CSLMARKER, GRAY_FONT, diff --git a/src/fheroes2/castle/castle_well.cpp b/src/fheroes2/castle/castle_well.cpp index e41ce338830..a34a7b6b76e 100644 --- a/src/fheroes2/castle/castle_well.cpp +++ b/src/fheroes2/castle/castle_well.cpp @@ -215,7 +215,7 @@ void Castle::_openWell() const int32_t buttonOffsetY = roi.y + bottomBarOffsetY; // MAX button. - fheroes2::Button buttonMax( roi.x, buttonOffsetY, ICN::BUYMAX, 0, 1 ); + fheroes2::Button buttonMax( roi.x, buttonOffsetY, ICN::BUTTON_WELL_MAX, 0, 1 ); // EXIT button. fheroes2::Button buttonExit( roi.x + roi.width - fheroes2::AGG::GetICN( ICN::BUTTON_GUILDWELL_EXIT, 0 ).width(), buttonOffsetY, ICN::BUTTON_GUILDWELL_EXIT, 0, 1 ); @@ -376,7 +376,7 @@ void Castle::_wellRedrawBackground( fheroes2::Image & background ) const const fheroes2::Sprite & bottomBar = fheroes2::AGG::GetICN( ICN::SMALLBAR, 0 ); const int32_t barHeight = bottomBar.height(); const int32_t exitWidth = fheroes2::AGG::GetICN( ICN::BUTTON_GUILDWELL_EXIT, 0 ).width(); - const int32_t buttonMaxWidth = fheroes2::AGG::GetICN( ICN::BUYMAX, 0 ).width(); + const int32_t buttonMaxWidth = fheroes2::AGG::GetICN( ICN::BUTTON_WELL_MAX, 0 ).width(); // ICN::SMALLBAR image's first column contains all black pixels. This should not be drawn. fheroes2::Copy( bottomBar, 1, 0, background, buttonMaxWidth, bottomBarOffsetY, backgroundWidth / 2 - buttonMaxWidth, barHeight ); fheroes2::Copy( bottomBar, bottomBar.width() - backgroundWidth / 2 + exitWidth - 1, 0, background, backgroundWidth / 2, bottomBarOffsetY, diff --git a/src/fheroes2/dialog/dialog_marketplace.cpp b/src/fheroes2/dialog/dialog_marketplace.cpp index 42956e6a3af..027bf9b4a26 100644 --- a/src/fheroes2/dialog/dialog_marketplace.cpp +++ b/src/fheroes2/dialog/dialog_marketplace.cpp @@ -91,7 +91,7 @@ namespace const bool isEvilInterface = conf.isEvilInterfaceEnabled(); const int tradeButtonIcnID = isEvilInterface ? ICN::BUTTON_SMALL_TRADE_EVIL : ICN::BUTTON_SMALL_TRADE_GOOD; - const int giftButtonIcnID = isEvilInterface ? ICN::BTNGIFT_EVIL : ICN::BTNGIFT_GOOD; + const int giftButtonIcnID = isEvilInterface ? ICN::BUTTON_GIFT_EVIL : ICN::BUTTON_GIFT_GOOD; buttonGift.setICNInfo( giftButtonIcnID, 0, 1 ); buttonTrade.setICNInfo( tradeButtonIcnID, 0, 1 ); From 709ca935aef70bd7d80e121e3f0abff2059e07ce Mon Sep 17 00:00:00 2001 From: Zenseii Date: Thu, 6 Feb 2025 15:40:20 +0100 Subject: [PATCH 48/54] revert unrelated change --- src/fheroes2/game/game_loadgame.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/fheroes2/game/game_loadgame.cpp b/src/fheroes2/game/game_loadgame.cpp index 4876cfae6d1..920ec5f9322 100644 --- a/src/fheroes2/game/game_loadgame.cpp +++ b/src/fheroes2/game/game_loadgame.cpp @@ -81,6 +81,8 @@ fheroes2::GameMode Game::LoadHotseat() fheroes2::GameMode Game::LoadMulti() { + fheroes2::Display & display = fheroes2::Display::instance(); + // setup cursor const CursorRestorer cursorRestorer( true, Cursor::POINTER ); @@ -97,7 +99,7 @@ fheroes2::GameMode Game::LoadMulti() buttonCancel.draw(); buttonNetwork.disable(); - fheroes2::Display::instance().render(); + display.render(); LocalEvent & le = LocalEvent::Get(); while ( le.HandleEvents() ) { From d96ac9584469572b3876c8acbecc611876d0a9f7 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Thu, 6 Feb 2025 15:41:09 +0100 Subject: [PATCH 49/54] fix '...' --- src/fheroes2/gui/ui_button.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fheroes2/gui/ui_button.cpp b/src/fheroes2/gui/ui_button.cpp index 45b966e0e2b..ba8e8106126 100644 --- a/src/fheroes2/gui/ui_button.cpp +++ b/src/fheroes2/gui/ui_button.cpp @@ -232,7 +232,7 @@ namespace fheroes2::SetPixel( buttonImage, buttonWidth - 8, 5, secondColor ); const int32_t buttonHeight = buttonImage.height(); - // To avoid overcrowding the ',,,' virtual keyboard button with decorations we set 50. + // To avoid overcrowding the '...' virtual keyboard button with decorations we set 50. if ( buttonWidth > 50 ) { // Longer left-side shine fheroes2::DrawLine( buttonImage, { 11, 4 }, { 9, 6 }, firstColor ); From b64f1ac030261b7dc2a435d77fad1e342c08e3d6 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Thu, 6 Feb 2025 15:41:34 +0100 Subject: [PATCH 50/54] Style fix --- src/fheroes2/gui/ui_button.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/fheroes2/gui/ui_button.cpp b/src/fheroes2/gui/ui_button.cpp index ba8e8106126..deca09c7ee5 100644 --- a/src/fheroes2/gui/ui_button.cpp +++ b/src/fheroes2/gui/ui_button.cpp @@ -243,7 +243,6 @@ namespace fheroes2::SetPixel( buttonImage, 6, 11, lastColor ); fheroes2::DrawLine( buttonImage, { 15, 4 }, { 13, 6 }, firstColor ); fheroes2::SetPixel( buttonImage, 12, 7, lastColor ); - // Longer right-side shine fheroes2::SetPixel( buttonImage, buttonWidth - 10, 2, firstColor ); fheroes2::SetPixel( buttonImage, buttonWidth - 8, 3, secondColor ); From e75458de264f2dbb4636a4b6561d4d7ecdb521de Mon Sep 17 00:00:00 2001 From: Zenseii Date: Thu, 6 Feb 2025 15:44:07 +0100 Subject: [PATCH 51/54] Copyright years + wide -> tall --- src/fheroes2/castle/castle_well.cpp | 2 +- src/fheroes2/dialog/dialog_marketplace.cpp | 2 +- src/fheroes2/gui/ui_button.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fheroes2/castle/castle_well.cpp b/src/fheroes2/castle/castle_well.cpp index a34a7b6b76e..d98cf30133f 100644 --- a/src/fheroes2/castle/castle_well.cpp +++ b/src/fheroes2/castle/castle_well.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2019 - 2024 * + * Copyright (C) 2019 - 2025 * * * * Free Heroes2 Engine: http://sourceforge.net/projects/fheroes2 * * Copyright (C) 2009 by Andrey Afletdinov * diff --git a/src/fheroes2/dialog/dialog_marketplace.cpp b/src/fheroes2/dialog/dialog_marketplace.cpp index 027bf9b4a26..91d90a961d9 100644 --- a/src/fheroes2/dialog/dialog_marketplace.cpp +++ b/src/fheroes2/dialog/dialog_marketplace.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2019 - 2024 * + * Copyright (C) 2019 - 2025 * * * * Free Heroes2 Engine: http://sourceforge.net/projects/fheroes2 * * Copyright (C) 2009 by Andrey Afletdinov * diff --git a/src/fheroes2/gui/ui_button.cpp b/src/fheroes2/gui/ui_button.cpp index deca09c7ee5..b9ffd1c4db8 100644 --- a/src/fheroes2/gui/ui_button.cpp +++ b/src/fheroes2/gui/ui_button.cpp @@ -819,7 +819,7 @@ namespace fheroes2 buttonSize.width = std::clamp( buttonSize.width, minimumButtonWidth, maximumButtonWidth ); const int32_t minimumButtonHeight = 25; - const int32_t maximumButtonHeight = 200; // Why is such a wide button needed? + const int32_t maximumButtonHeight = 200; // Why is such a tall button needed? buttonSize.height = std::clamp( buttonSize.height, minimumButtonHeight, maximumButtonHeight ); const int32_t icnId = isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON; From c7d84360338d5179dddee2ba8d61cec31d4c0389 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Thu, 6 Feb 2025 15:50:14 +0100 Subject: [PATCH 52/54] Change to Size type for createNormal parameter --- src/fheroes2/agg/agg_image.cpp | 57 +++++++++++++++++----------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 1d036938a81..487caabee79 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -422,15 +422,16 @@ namespace } void createNormalButton( fheroes2::Sprite & released, fheroes2::Sprite & pressed, const char * text, const bool isEvilInterface, const int backgroundIcnId, - int32_t buttonWidth, int32_t buttonHeight = 25 ) + fheroes2::Size buttonSize ) { fheroes2::Point releasedOffset; fheroes2::Point pressedOffset; - fheroes2::getCustomNormalButton( released, pressed, isEvilInterface, { buttonWidth, buttonHeight }, releasedOffset, pressedOffset, backgroundIcnId ); + fheroes2::getCustomNormalButton( released, pressed, isEvilInterface, { buttonSize.width, buttonSize.height }, releasedOffset, pressedOffset, + backgroundIcnId ); const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( released, pressed, text, releasedOffset, pressedOffset, { buttonWidth, buttonHeight }, buttonFontColor ); + renderTextOnButton( released, pressed, text, releasedOffset, pressedOffset, { buttonSize.width, buttonSize.height}, buttonFontColor ); } void createCampaignButtonSet( const int campaignSetIcnId, const std::array & texts ) @@ -633,7 +634,7 @@ namespace } createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "NEW\nGAME" ), isEvilInterface, - isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 86, 56 ); + isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, { 86, 56 } ); break; } @@ -650,7 +651,7 @@ namespace } createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "SAVE\nGAME" ), isEvilInterface, - isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 86, 56 ); + isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, { 86, 56 } ); break; } @@ -667,7 +668,7 @@ namespace } createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "LOAD\nGAME" ), isEvilInterface, - isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 86, 56 ); + isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, { 86, 56 } ); break; } @@ -684,7 +685,7 @@ namespace } createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "INFO" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, - 86, 56 ); + { 86, 56 } ); break; } @@ -701,7 +702,7 @@ namespace } createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "QUIT" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, - 86, 56 ); + { 86, 56 } ); break; } @@ -718,7 +719,7 @@ namespace } createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "NEW\nMAP" ), isEvilInterface, - isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 86, 56 ); + isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, { 86, 56 } ); break; } @@ -735,7 +736,7 @@ namespace } createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "SAVE\nMAP" ), isEvilInterface, - isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 86, 56 ); + isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, { 86, 56 } ); break; } @@ -752,7 +753,7 @@ namespace } createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "LOAD\nMAP" ), isEvilInterface, - isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 86, 56 ); + isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, { 86, 56 } ); break; } @@ -941,7 +942,7 @@ namespace // The heroes meeting screen has an embedded shadow so the button needs to be fixed at the same size as the original one. // TODO: Remove the embedded shadow and button in the heroes meeting screen and use getTextAdaptedSprite() instead. - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), false, ICN::STONEBAK, 70 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), false, ICN::STONEBAK, { 70, 25 } ); break; } @@ -955,7 +956,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), false, ICN::BLACKBAK, 70 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), false, ICN::BLACKBAK, { 70, 25 } ); break; } @@ -973,7 +974,7 @@ namespace } createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), isEvilInterface, - isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 70 ); + isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, { 70, 25 } ); break; } @@ -1037,7 +1038,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), false, ICN::BROWNBAK, 89 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), false, ICN::BROWNBAK, { 89, 25 } ); break; } @@ -1050,7 +1051,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "HEROES" ), false, ICN::BROWNBAK, 89, 42 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "HEROES" ), false, ICN::BROWNBAK, { 89, 42 } ); break; } @@ -1063,7 +1064,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "TOWNS/\nCASTLES" ), false, ICN::BROWNBAK, 89, 42 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "TOWNS/\nCASTLES" ), false, ICN::BROWNBAK, { 89, 42 } ); break; } @@ -1077,7 +1078,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "S" ), false, ICN::STONEBAK, 46 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "S" ), false, ICN::STONEBAK, { 46, 25 } ); break; } @@ -1090,7 +1091,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "M" ), false, ICN::STONEBAK, 46 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "M" ), false, ICN::STONEBAK, { 46, 25 } ); break; } @@ -1103,7 +1104,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "L" ), false, ICN::STONEBAK, 46 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "L" ), false, ICN::STONEBAK, { 46, 25 } ); break; } @@ -1116,7 +1117,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "X-L" ), false, ICN::STONEBAK, 46 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "X-L" ), false, ICN::STONEBAK, { 46, 25 } ); break; } @@ -1129,7 +1130,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "ALL" ), false, ICN::STONEBAK, 58 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "ALL" ), false, ICN::STONEBAK, { 58, 25 } ); break; } @@ -1311,7 +1312,7 @@ namespace break; } - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], text, false, ICN::STONEBAK, 117, 56 ); + createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], text, false, ICN::STONEBAK, { 117, 56 } ); fheroes2::Sprite & released = _icnVsSprite[id][0]; fheroes2::Sprite & pressed = _icnVsSprite[id][1]; @@ -1388,7 +1389,7 @@ namespace } createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "smallerButton|EXIT" ), isEvilInterface, - isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, 70, 35 ); + isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, { 70, 35 } ); break; } @@ -1490,7 +1491,7 @@ namespace const bool isEvilInterface = id == ICN::BUTTON_SMALL_MIN_EVIL; createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MIN" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, - fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MAX_GOOD, 0 ).width() - 10 ); + { fheroes2::AGG::GetICN( ICN::BUTTON_SMALL_MAX_GOOD, 0 ).width() - 10, 25 } ); break; } @@ -1519,7 +1520,7 @@ namespace } createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "MAX" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, - 61 ); + { 61, 25 } ); break; } @@ -1607,7 +1608,7 @@ namespace const int32_t width = std::max( 80, std::max( townTextWidth, castleTextWidth ) ); const bool isEvilInterface = id == ICN::BUTTON_CASTLE_EVIL; createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "CASTLE" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, - width ); + { width, 25 } ); break; } @@ -1626,7 +1627,7 @@ namespace const bool isEvilInterface = id == ICN::BUTTON_TOWN_EVIL; createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "TOWN" ), isEvilInterface, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK, - width ); + { width, 25 } ); break; } From 094c7ab8f21f01757ad08735b500477fd28860f6 Mon Sep 17 00:00:00 2001 From: Zenseii Date: Thu, 6 Feb 2025 16:04:45 +0100 Subject: [PATCH 53/54] Code style and style nits --- src/fheroes2/agg/agg_image.cpp | 7 +++---- src/fheroes2/gui/ui_button.cpp | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 487caabee79..093cc624cb9 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -426,12 +426,11 @@ namespace { fheroes2::Point releasedOffset; fheroes2::Point pressedOffset; - fheroes2::getCustomNormalButton( released, pressed, isEvilInterface, { buttonSize.width, buttonSize.height }, releasedOffset, pressedOffset, - backgroundIcnId ); + fheroes2::getCustomNormalButton( released, pressed, isEvilInterface, { buttonSize.width, buttonSize.height }, releasedOffset, pressedOffset, backgroundIcnId ); const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( released, pressed, text, releasedOffset, pressedOffset, { buttonSize.width, buttonSize.height}, buttonFontColor ); + renderTextOnButton( released, pressed, text, releasedOffset, pressedOffset, { buttonSize.width, buttonSize.height }, buttonFontColor ); } void createCampaignButtonSet( const int campaignSetIcnId, const std::array & texts ) @@ -1988,7 +1987,7 @@ namespace for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { fheroes2::Sprite & out = _icnVsSprite[id][i]; const fheroes2::Sprite & original = fheroes2::AGG::GetICN( ICN::TRADPOST, 17 + i ); - // Using this Copy function to convert pressed original from single layered. + // We use this Copy function to make the pressed state not single layered like the original. Copy( original, out ); // Clean the button Fill( out, 33, 5, 31, 16, getButtonFillingColor( i == 0 ) ); diff --git a/src/fheroes2/gui/ui_button.cpp b/src/fheroes2/gui/ui_button.cpp index b9ffd1c4db8..9734da9a342 100644 --- a/src/fheroes2/gui/ui_button.cpp +++ b/src/fheroes2/gui/ui_button.cpp @@ -120,7 +120,7 @@ namespace const int32_t middleWidth = originalWidth / 3; - // The new button doesn't fit the two end corners. Are you using the wrong empty button to generate the new one? + // The new button cannot even fit the two end corners. Are you using the wrong empty button to generate the new one? assert( buttonSize.width >= middleWidth * 2 ); const int32_t rightSideWidth = buttonSize.width - middleWidth; @@ -257,6 +257,7 @@ namespace fheroes2::SetPixel( buttonImage, 11, buttonHeight - 6, lastColor ); fheroes2::DrawLine( buttonImage, { 12, buttonHeight - 7 }, { 13, buttonHeight - 8 }, firstColor ); fheroes2::SetPixel( buttonImage, 14, buttonHeight - 9, lastColor ); + // This is mainly to decorate the space bar button if ( buttonWidth > 96 || buttonHeight > 25 ) { // Longer bottom left shine fheroes2::SetPixel( buttonImage, 10, buttonHeight - 5, lastColor ); @@ -269,7 +270,6 @@ namespace fheroes2::SetPixel( buttonImage, 34, buttonHeight - 5, secondColor ); fheroes2::SetPixel( buttonImage, 35, buttonHeight - 6, lastColor ); } - if ( buttonHeight > 25 ) { // Bottom right-side shine fheroes2::DrawLine( buttonImage, { buttonWidth - 20, buttonHeight - 5 }, { buttonWidth - 16, buttonHeight - 9 }, secondColor ); From cdc55b607b476c93c2823df96b7a29ccb699e85a Mon Sep 17 00:00:00 2001 From: Zenseii Date: Thu, 6 Feb 2025 19:35:20 +0100 Subject: [PATCH 54/54] Don't generate button twice for evil select Fix high scores vertical buttons --- src/fheroes2/agg/agg_image.cpp | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 093cc624cb9..aa1cfd9e599 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -1133,30 +1133,32 @@ namespace break; } - case ICN::BUTTON_MAP_SELECT_EVIL: case ICN::BUTTON_MAP_SELECT_GOOD: { _icnVsSprite[id].resize( 2 ); - const bool isEvilInterface = ( id == ICN::BUTTON_MAP_SELECT_EVIL ); if ( useOriginalResources() ) { _icnVsSprite[id][0] = fheroes2::AGG::GetICN( ICN::NGEXTRA, 64 ); _icnVsSprite[id][1] = fheroes2::AGG::GetICN( ICN::NGEXTRA, 65 ); - if ( isEvilInterface ) { - const std::vector & goodToEvilPalette = PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ); - fheroes2::ApplyPalette( _icnVsSprite[id][0], goodToEvilPalette ); - fheroes2::ApplyPalette( _icnVsSprite[id][1], goodToEvilPalette ); - } break; } getTextAdaptedSprite( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "SELECT" ), ICN::EMPTY_MAP_SELECT_BUTTON, ICN::UNKNOWN ); - if ( isEvilInterface ) { - const std::vector & goodToEvilPalette = PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ); - fheroes2::ApplyPalette( _icnVsSprite[id][0], goodToEvilPalette ); - fheroes2::ApplyPalette( _icnVsSprite[id][1], goodToEvilPalette ); - } + break; + } + case ICN::BUTTON_MAP_SELECT_EVIL: { + _icnVsSprite[id].resize( 2 ); + + fheroes2::Sprite & released = _icnVsSprite[id][0]; + fheroes2::Sprite & pressed = _icnVsSprite[id][1]; + + const int buttonIcnID = ICN::BUTTON_MAP_SELECT_GOOD; + released = fheroes2::AGG::GetICN( buttonIcnID, 0 ); + pressed = fheroes2::AGG::GetICN( buttonIcnID, 1 ); + const std::vector & goodToEvilPalette = PAL::GetPalette( PAL::PaletteType::GOOD_TO_EVIL_BUTTON ); + fheroes2::ApplyPalette( released, goodToEvilPalette ); + fheroes2::ApplyPalette( pressed, goodToEvilPalette ); break; } case ICN::BTNBATTLEONLY: @@ -1812,7 +1814,7 @@ namespace const ButtonFontOffsetRestorer fontRestorerReleased( _icnVsSprite[ICN::BUTTON_GOOD_FONT_RELEASED], -1 ); const ButtonFontOffsetRestorer fontRestorerPressed( _icnVsSprite[ICN::BUTTON_GOOD_FONT_PRESSED], -1 ); - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], buttonText, { 4, 4 }, { 3, 5 }, { 27, 133 }, fheroes2::FontColor::WHITE ); + renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], buttonText, { 3, 4 }, { 2, 5 }, { 23, 133 }, fheroes2::FontColor::WHITE ); break; }