git repos / blockattack-game

commit 2a78ad0d

Poul Sander · 2025-03-29 15:45
2a78ad0d898a80fb270533e7d7158ab22f6474c5 patch · browse files
parent 95de0f5712fa70133f1c11eafdf371c1b2c9e4da
parent 9dabbfe5b3ae392fd4040adb192fba1801722d4f

Merge branch 'master' into puzzle_editor

Changed files

M CHANGELOG.md before
M CMakeLists.txt before
M source/code/BlockGameSdl.hpp before
M source/code/DialogBox.cpp before
M source/code/DialogBox.hpp before
M source/code/HelpCommon.cpp before
M source/code/HelpGamepadState.cpp before
M source/code/HelpHowtoState.cpp before
M source/code/MenuSystem.cpp before
M source/code/ScoresDisplay.cpp before
M source/code/global.hpp before
M source/code/levelselect.cpp before
M source/code/main.cpp before
M source/code/menudef_themes.cpp before
A source/code/sago/SagoLogicalResize.hpp
M source/code/sago/SagoSprite.cpp before
M source/code/sago/SagoSprite.hpp before
M source/code/sago/SagoTextBox.cpp before
M source/code/sago/SagoTextBox.hpp before
M source/code/sago/SagoTextField.cpp before
M source/code/sago/SagoTextField.hpp before
diff --git a/CHANGELOG.md b/CHANGELOG.md index 072db2c..21ae2d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md
@@ -8,6 +8,11 @@
### Removed
+## [2.9.1] - 2025-02-09
+
+### Changed
+ - Left and right on gamepad d-pad now works again. Broken in 2.6.0.
+
## [2.9.0] - 2024-05-09
### Added
diff --git a/CMakeLists.txt b/CMakeLists.txt index 00aabd0..977a976 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.5.1...3.27.4)
+cmake_minimum_required(VERSION 3.5.1...3.30.3)
project (blockattack)
set(BIN_DIR ${blockattack_SOURCE_DIR}/Game)
@@ -77,7 +77,7 @@ pkg_search_module(SDL2TTF REQUIRED SDL2_ttf)
find_package(Intl REQUIRED)
-find_package(Boost COMPONENTS program_options REQUIRED)
+find_package(Boost COMPONENTS program_options REQUIRED NO_MODULE)
include_directories(SYSTEM "source/code/Libs/imgui")
diff --git a/source/code/BlockGameSdl.hpp b/source/code/BlockGameSdl.hpp index 5b4a676..7ef6ff9 100644 --- a/source/code/BlockGameSdl.hpp +++ b/source/code/BlockGameSdl.hpp
@@ -89,7 +89,7 @@ public:
void PrintTextCenteredBoard(int x, int y, sago::SagoTextField& field) {
field.Draw(globalData.screen, x+topx+60, y+topy+20,
- sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::center);
+ sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::center, &globalData.logicalResize);
}
void SetTopXY(int tx, int ty) {
@@ -234,121 +234,8 @@ private:
}
}
- /**
- * Creates a new texture for a garabge block of size size_x*size_y at x,y and crops it.
- * Also sets globalData.screen to point to the texture, so Draw now draws on the Texture.
- */
- SDL_Texture* CreateGarbageTexture(int x, int y, int size_x, int size_y, SDL_Rect& dstrect, SDL_Rect& srcrect) const {
- dstrect = { x, y, size_x*bsize, size_y*bsize };
- srcrect = { 0, 0, size_x*bsize, size_y*bsize };
- SDL_Rect bound = {topx, topy, BOARD_WIDTH, BOARD_HEIGHT};
- CropTexture (dstrect, srcrect, bound);
- SDL_Texture* mTexture = SDL_CreateTexture( globalData.screen, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, size_x*bsize, size_y*bsize );
- SDL_SetRenderTarget( globalData.screen, mTexture );
-
- SDL_SetRenderDrawBlendMode(globalData.screen, SDL_BLENDMODE_NONE);
- SDL_SetTextureBlendMode(mTexture, SDL_BLENDMODE_BLEND);
- SDL_SetRenderDrawColor(globalData.screen, 0, 0, 0, 0);
- SDL_RenderFillRect(globalData.screen, NULL);
- SDL_SetRenderDrawBlendMode(globalData.screen, SDL_BLENDMODE_BLEND);
- return mTexture;
- }
-
- /**
- Paints a garbage block of size size_x*size_y (size in blocks) at x,y (coordinates in pixels).
- The garbage block will be painted on an internal texture and rendered to screen to protect against tearing.
- The result will be cropped to the playable area.
- */
- void PaintGarbageBlock(int x, int y, int size_x, int size_y) const {
- SDL_Rect dstrect ;
- SDL_Rect srcrect ;
- SDL_Texture* mTexture = CreateGarbageTexture(x, y, size_x, size_y, dstrect, srcrect);
- const Sint32 draw_time = SDL_GetTicks();
-
- if (size_y == 1) {
- //single line
- globalData.garbageML.Draw(globalData.screen, draw_time, 0, 0);
- for (int i = 1; i < size_x-1; ++i) {
- globalData.garbageM.Draw(globalData.screen, draw_time, i*bsize, 0);
- }
- globalData.garbageMR.Draw(globalData.screen, draw_time, (size_x-1)*bsize, 0);
- }
- if (size_y > 1) {
- // Top line
- globalData.garbageTL.Draw(globalData.screen, draw_time, 0, 0);
- for (int i = 1; i < size_x-1; ++i) {
- globalData.garbageT.Draw(globalData.screen, draw_time, i*bsize, 0);
- }
- globalData.garbageTR.Draw(globalData.screen, draw_time, (size_x-1)*bsize, 0);
- // Middle lines (if any)
- for (int j=1; j < size_y-1; ++j) {
- globalData.garbageL.Draw(globalData.screen, draw_time, 0, j*bsize);
- for (int i = 1; i < size_x-1; ++i) {
- globalData.garbageFill.Draw(globalData.screen, draw_time, i*bsize, j*bsize);
- }
- globalData.garbageR.Draw(globalData.screen, draw_time, (size_x-1)*bsize, j*bsize);
- }
- //Buttom line
- globalData.garbageBL.Draw(globalData.screen, draw_time, 0, (size_y-1)*bsize);
- for (int i = 1; i < size_x-1; ++i) {
- globalData.garbageB.Draw(globalData.screen, draw_time, i*bsize, (size_y-1)*bsize);
- }
- globalData.garbageBR.Draw(globalData.screen, draw_time, (size_x-1)*bsize, (size_y-1)*bsize);
- }
-
- SDL_SetRenderTarget( globalData.screen, nullptr );
- SDL_RenderCopy( globalData.screen, mTexture, &srcrect, &dstrect );
- SDL_DestroyTexture(mTexture);
- }
-
- /**
- Paints a grey garbage block of size size_x (size in blocks, always 6) at x,y (coordinates in pixels).
- The result will be cropped to the playable area.
- */
- void PaintGreyGarbageBlock(int x, int y, int size_x) const {
- const int size_y = bsize;
- SDL_Rect dstrect ;
- SDL_Rect srcrect ;
- SDL_Texture* mTexture = CreateGarbageTexture(x, y, size_x, size_y, dstrect, srcrect);
- const Sint32 draw_time = SDL_GetTicks();
-
- for (int j=0; j < size_y; ++j) {
- if (j==0) {
- globalData.garbageGML.Draw(globalData.screen, draw_time, j*bsize, 0);
- }
- else if (j==5) {
- globalData.garbageGMR.Draw(globalData.screen, draw_time, j*bsize, 0);
- }
- else {
- globalData.garbageGM.Draw(globalData.screen, draw_time, j*bsize, 0);
- }
- }
-
- SDL_SetRenderTarget( globalData.screen, nullptr );
- SDL_RenderCopy( globalData.screen, mTexture, &srcrect, &dstrect );
- SDL_DestroyTexture(mTexture);
- }
-
- std::pair<int, int> getGarbageSize(int topx, int topy) const {
- int size_x = 0;
- int size_y = 0;
- int number = board[topx][topy];
- for (int i=topy; i < 30 ; ++i) {
- if (number == board[topx][i]) {
- ++size_y;
- }
- }
- for (int i=topx; i < 7 ; ++i) {
- if (number == board[i][topy]) {
- ++size_x;
- }
- }
- return std::make_pair(size_x, size_y);
- }
-
//Draws all the bricks to the board (including garbage)
void PaintBricks() const {
- int lastGarbageNumber = 0;
for (int i=0; i<13; ++i) {
for (int j=0; j<6; ++j) {
int basicBrick = board[j][i]%10; //The basic brick, stored on the least significant digit
@@ -363,19 +250,78 @@ private:
}
if ((board[j][i]/1000000)%10==1) {
+ int left, right, over, under;
int number = board[j][i];
- if (number != lastGarbageNumber) {
- const auto& garbage_size = getGarbageSize(j, i);
- lastGarbageNumber = number;
- PaintGarbageBlock(topx+j*bsize, topy+12*bsize-i*bsize-(garbage_size.second-1)*bsize -pixels, garbage_size.first, garbage_size.second);
+ if (j<1) {
+ left = -1;
+ }
+ else {
+ left = board[j-1][i];
+ }
+ if (j>=5) {
+ right = -1;
+ }
+ else {
+ right = board[j+1][i];
+ }
+ if (i>28) {
+ over = -1;
+ }
+ else {
+ over = board[j][i+1];
+ }
+ if (i<1) {
+ under = -1;
+ }
+ else {
+ under = board[j][i-1];
+ }
+ if ((left == number)&&(right == number)&&(over == number)&&(under == number)) {
+ DrawImgBoardBounded(globalData.garbageFill, j*bsize, bsize*12-i*bsize-pixels);
+ }
+ if ((left != number)&&(right == number)&&(over == number)&&(under == number)) {
+ DrawImgBoardBounded(globalData.garbageL, j*bsize, bsize*12-i*bsize-pixels);
+ }
+ if ((left == number)&&(right != number)&&(over == number)&&(under == number)) {
+ DrawImgBoardBounded(globalData.garbageR, j*bsize, bsize*12-i*bsize-pixels);
+ }
+ if ((left == number)&&(right == number)&&(over != number)&&(under == number)) {
+ DrawImgBoardBounded(globalData.garbageT, j*bsize, bsize*12-i*bsize-pixels);
+ }
+ if ((left == number)&&(right == number)&&(over == number)&&(under != number)) {
+ DrawImgBoardBounded(globalData.garbageB, j*bsize, bsize*12-i*bsize-pixels);
+ }
+ if ((left != number)&&(right == number)&&(over != number)&&(under == number)) {
+ DrawImgBoardBounded(globalData.garbageTL, j*bsize, bsize*12-i*bsize-pixels);
+ }
+ if ((left != number)&&(right == number)&&(over == number)&&(under != number)) {
+ DrawImgBoardBounded(globalData.garbageBL, j*bsize, bsize*12-i*bsize-pixels);
+ }
+ if ((left == number)&&(right != number)&&(over != number)&&(under == number)) {
+ DrawImgBoardBounded(globalData.garbageTR, j*bsize, bsize*12-i*bsize-pixels);
+ }
+ if ((left == number)&&(right != number)&&(over == number)&&(under != number)) {
+ DrawImgBoardBounded(globalData.garbageBR, j*bsize, bsize*12-i*bsize-pixels);
+ }
+ if ((left == number)&&(right != number)&&(over != number)&&(under != number)) {
+ DrawImgBoardBounded(globalData.garbageMR, j*bsize, bsize*12-i*bsize-pixels);
+ }
+ if ((left == number)&&(right == number)&&(over != number)&&(under != number)) {
+ DrawImgBoardBounded(globalData.garbageM, j*bsize, bsize*12-i*bsize-pixels);
+ }
+ if ((left != number)&&(right == number)&&(over != number)&&(under != number)) {
+ DrawImgBoardBounded(globalData.garbageML, j*bsize, bsize*12-i*bsize-pixels);
}
}
if ((board[j][i]/1000000)%10==2) {
- int number = board[j][i];
- if (number != lastGarbageNumber) {
- const auto& garbage_size = getGarbageSize(j, i);
- lastGarbageNumber = number;
- PaintGreyGarbageBlock(topx+j*bsize, topy+12*bsize-i*bsize-(garbage_size.second-1)*bsize -pixels, garbage_size.first);
+ if (j==0) {
+ DrawImgBoardBounded(globalData.garbageGML, j*bsize, bsize*12-i*bsize-pixels);
+ }
+ else if (j==5) {
+ DrawImgBoardBounded(globalData.garbageGMR, j*bsize, bsize*12-i*bsize-pixels);
+ }
+ else {
+ DrawImgBoardBounded(globalData.garbageGM, j*bsize, bsize*12-i*bsize-pixels);
}
}
}
@@ -430,11 +376,11 @@ public:
sago::SagoSprite backback = globalData.spriteHolder->GetSprite(border.border_sprite);
DrawIMG(backback, globalData.screen, this->GetTopX()+border.border_sprite_offset.first, this->GetTopY()+border.border_sprite_offset.second);
- this->scoreLabel.Draw(globalData.screen, this->GetTopX()+border.score_label_offset.first,this->GetTopY()+border.score_label_offset.second);
- this->timeLabel.Draw(globalData.screen, this->GetTopX()+border.time_label_offset.first,this->GetTopY()+border.time_label_offset.second);
- this->chainLabel.Draw(globalData.screen, this->GetTopX()+border.chain_label_offset.first,this->GetTopY()+border.chain_label_offset.second);
- this->speedLabel.Draw(globalData.screen, this->GetTopX()+border.speed_label_offset.first,this->GetTopY()+border.speed_label_offset.second);
- globalData.spriteHolder->GetSprite(globalData.theme.back_board).DrawScaled(globalData.screen, SDL_GetTicks(), this->GetTopX(),this->GetTopY(), BOARD_WIDTH, BOARD_HEIGHT);
+ this->scoreLabel.Draw(globalData.screen, this->GetTopX()+border.score_label_offset.first,this->GetTopY()+border.score_label_offset.second, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
+ this->timeLabel.Draw(globalData.screen, this->GetTopX()+border.time_label_offset.first,this->GetTopY()+border.time_label_offset.second, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
+ this->chainLabel.Draw(globalData.screen, this->GetTopX()+border.chain_label_offset.first,this->GetTopY()+border.chain_label_offset.second, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
+ this->speedLabel.Draw(globalData.screen, this->GetTopX()+border.speed_label_offset.first,this->GetTopY()+border.speed_label_offset.second, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
+ globalData.spriteHolder->GetSprite(globalData.theme.back_board).DrawScaled(globalData.screen, SDL_GetTicks(), this->GetTopX(),this->GetTopY(), BOARD_WIDTH, BOARD_HEIGHT, &globalData.logicalResize);
PaintBricks();
if (stageClear) {
@@ -446,7 +392,7 @@ public:
static sago::SagoTextField movesPuzzleLabel;
sagoTextSetHelpFont(movesPuzzleLabel);
movesPuzzleLabel.SetText(strHolder);
- movesPuzzleLabel.Draw(globalData.screen, topx+5, topy+5);
+ movesPuzzleLabel.Draw(globalData.screen, topx+5, topy+5, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
}
if (puzzleMode && stageButtonStatus == SBpuzzleMode) {
@@ -466,7 +412,7 @@ public:
static sago::SagoTextField lastPuzzleLabel;
sagoTextSetHelpFont(lastPuzzleLabel);
lastPuzzleLabel.SetText(_("Last puzzle"));
- lastPuzzleLabel.Draw(globalData.screen, topx+5, topy+5);
+ lastPuzzleLabel.Draw(globalData.screen, topx+5, topy+5, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
}
}
if (stageClear && stageButtonStatus == SBstageClear) {
@@ -486,12 +432,12 @@ public:
static sago::SagoTextField lastStageLabel;
sagoTextSetHelpFont(lastStageLabel);
lastStageLabel.SetText(_("Last stage"));
- lastStageLabel.Draw(globalData.screen, topx+5, topy+5);
+ lastStageLabel.Draw(globalData.screen, topx+5, topy+5, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
}
}
if (!bGameOver && stop > 20) {
stopIntField.SetText(std::to_string(stop/10));
- stopIntField.Draw(globalData.screen, 240+topx, -40+topy);
+ stopIntField.Draw(globalData.screen, 240+topx, -40+topy, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
}
#if DEBUG
@@ -499,7 +445,7 @@ public:
sagoTextSetBlueFont(aiStatusField);
strHolder = "AI_status: " + std::to_string(AIstatus)+ ", "+ std::to_string(AIlineToClear);
aiStatusField.SetText(strHolder);
- aiStatusField.Draw(globalData.screen, topx+5, topy+5);
+ aiStatusField.Draw(globalData.screen, topx+5, topy+5, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
}
#endif
if (!bGameOver) {
@@ -554,15 +500,15 @@ public:
if (bGameOver) {
if (hasWonTheGame) {
- globalData.tbWinner.Draw(globalData.screen, topx+150, topy+200, sago::SagoTextField::Alignment::center);
+ globalData.tbWinner.Draw(globalData.screen, topx+150, topy+200, sago::SagoTextField::Alignment::center, &globalData.logicalResize);
}
else {
if (bDraw) {
- globalData.tbDraw.Draw(globalData.screen, topx+150, topy+200, sago::SagoTextField::Alignment::center);
+ globalData.tbDraw.Draw(globalData.screen, topx+150, topy+200, sago::SagoTextField::Alignment::center, &globalData.logicalResize);
}
else {
if (this->infostring.empty()) {
- globalData.tbGameOver.Draw(globalData.screen, topx+150, topy+200, sago::SagoTextField::Alignment::center);
+ globalData.tbGameOver.Draw(globalData.screen, topx+150, topy+200, sago::SagoTextField::Alignment::center, &globalData.logicalResize);
}
}
}
@@ -571,14 +517,14 @@ public:
std::string strHolder;
strHolder = std::to_string(this->GetScore()+this->GetHandicap());
player_score.SetText(strHolder);
- player_score.Draw(globalData.screen, this->GetTopX()+border.score_label_offset.first,this->GetTopY()+border.score_label_offset.second+22);
+ player_score.Draw(globalData.screen, this->GetTopX()+border.score_label_offset.first,this->GetTopY()+border.score_label_offset.second+22, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
if (this->GetAIenabled()) {
player_name.SetText(_("AI"));
}
else {
player_name.SetText(name);
}
- player_name.Draw(globalData.screen, this->GetTopX()+10,this->GetTopY()-34);
+ player_name.Draw(globalData.screen, this->GetTopX()+10,this->GetTopY()-34, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
if (this->isTimeTrial()) {
int tid = (int)SDL_GetTicks()-this->GetGameStartedAt();
int minutes;
@@ -622,14 +568,14 @@ public:
}
player_time.SetText(strHolder);
}
- player_time.Draw(globalData.screen, this->GetTopX()+border.time_label_offset.first,this->GetTopY()+border.time_label_offset.second+22);
+ player_time.Draw(globalData.screen, this->GetTopX()+border.time_label_offset.first,this->GetTopY()+border.time_label_offset.second+22, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
strHolder = std::to_string(this->GetChains());
player_chain.SetText(strHolder);
- player_chain.Draw(globalData.screen, this->GetTopX()+border.chain_label_offset.first,this->GetTopY()+border.chain_label_offset.second+22);
+ player_chain.Draw(globalData.screen, this->GetTopX()+border.chain_label_offset.first,this->GetTopY()+border.chain_label_offset.second+22, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
//drawspeedLevel:
strHolder = std::to_string(this->GetSpeedLevel());
player_speed.SetText(strHolder);
- player_speed.Draw(globalData.screen, this->GetTopX()+border.speed_label_offset.first,this->GetTopY()+border.speed_label_offset.second+22);
+ player_speed.Draw(globalData.screen, this->GetTopX()+border.speed_label_offset.first,this->GetTopY()+border.speed_label_offset.second+22, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
if ((this->isStageClear()) &&(this->GetTopY()+700+50*(this->GetStageClearLimit()-this->GetLinesCleared())-this->GetPixels()-1<600+this->GetTopY())) {
oldBubleX = this->GetTopX()+280;
oldBubleY = this->GetTopY()+650+50*(this->GetStageClearLimit()-this->GetLinesCleared())-this->GetPixels()-1;
@@ -647,9 +593,9 @@ public:
objectiveField.SetText(_("Objective:"));
sagoTextSetHelpFont(gametypeNameField);
gametypeNameField.SetText(infostringName);
- gametypeNameField.Draw(globalData.screen, this->GetTopX()+7,this->GetTopY()+10);
- objectiveField.Draw(globalData.screen, this->GetTopX()+7, this->GetTopY()+160);
- infoBox.Draw(globalData.screen, this->GetTopX()+7, this->GetTopY()+160+32);
+ gametypeNameField.Draw(globalData.screen, this->GetTopX()+7,this->GetTopY()+10, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
+ objectiveField.Draw(globalData.screen, this->GetTopX()+7, this->GetTopY()+160, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
+ infoBox.Draw(globalData.screen, this->GetTopX()+7, this->GetTopY()+160+32, sago::SagoTextField::Alignment::left, &globalData.logicalResize);
int y = this->GetTopY()+400;
static sago::SagoTextBox controldBox;
@@ -657,7 +603,7 @@ public:
sagoTextSetHelpFont(controldBox);
controldBox.SetMaxWidth(290);
controldBox.SetText(controldBoxText);
- controldBox.Draw(globalData.screen, this->GetTopX()+7,y);
+ controldBox.Draw(globalData.screen, this->GetTopX()+7,y, sago::SagoTextField::Alignment::left, &globalData.logicalResize);
}
}
diff --git a/source/code/DialogBox.cpp b/source/code/DialogBox.cpp index 7936b13..0e2551e 100644 --- a/source/code/DialogBox.cpp +++ b/source/code/DialogBox.cpp
@@ -29,6 +29,7 @@ http://www.blockattack.net
#include "MenuSystem.h"
#include <unordered_map>
#include <fmt/core.h>
+#include "sago/SagoLogicalResize.hpp"
static void setButtonFont(const sago::SagoDataHolder* holder, sago::SagoTextField& field, const char* text) {
field.SetHolder(holder);
@@ -52,9 +53,12 @@ static void draw_rect_cache_clear() {
}
-static void DrawRect(SDL_Renderer* target, int topx, int topy, int height, int width, const std::string& name) {
+static void DrawRect(SDL_Renderer* target, int topx, int topy, int height, int width, const std::string& name, sago::SagoLogicalResize* resize) {
const int size = 32;
SDL_Rect dstrect = { topx, topy, width, height };
+ if (resize) {
+ resize->LogicalToPhysical(dstrect);
+ }
std::string key_name = fmt::format("{}-{}-{}", name, width, height);
Uint64 new_version = globalData.spriteHolder->GetDataHolder().getVersion();
if (draw_rect_cache_version != new_version) {
@@ -104,14 +108,14 @@ static void DrawRect(SDL_Renderer* target, int topx, int topy, int height, int w
SDL_RenderCopy( target, mTexture, NULL, &dstrect );
}
-static void DrawRectWhite(SDL_Renderer* target, int topx, int topy, int height, int width) {
+static void DrawRectWhite(SDL_Renderer* target, int topx, int topy, int height, int width, sago::SagoLogicalResize* resize) {
std::string name = "ui_rect_white_";
- DrawRect(target, topx, topy, height, width, name);
+ DrawRect(target, topx, topy, height, width, name, resize);
}
-void DrawRectYellow(SDL_Renderer* target, int topx, int topy, int height, int width) {
+void DrawRectYellow(SDL_Renderer* target, int topx, int topy, int height, int width, sago::SagoLogicalResize* resize) {
std::string name = "ui_rect_yellow_";
- DrawRect(target, topx, topy, height, width, name);
+ DrawRect(target, topx, topy, height, width, name, resize);
}
bool OpenDialogbox(int x, int y, std::string& name, const std::string& header) {
@@ -160,16 +164,19 @@ bool DialogBox::IsActive() {
}
static bool insideRect (int x, int y, int height, int width) {
- if (globalData.mousex < x) {
+ int mousex;
+ int mousey;
+ globalData.logicalResize.PhysicalToLogical(globalData.mousex, globalData.mousey, mousex, mousey);
+ if (mousex < x) {
return false;
}
- if (globalData.mousex > x+width) {
+ if (mousex > x+width) {
return false;
}
- if (globalData.mousey < y) {
+ if (mousey < y) {
return false;
}
- if (globalData.mousey > y+height) {
+ if (mousey > y+height) {
return false;
}
return true;
@@ -182,25 +189,25 @@ void DialogBox::Draw(SDL_Renderer* target) {
DrawBackground(globalData.screen);
this->x = globalData.xsize/2-300;
this->y = globalData.ysize/2-100;
- DrawRectYellow(target, x, y, 200, 600);
- headerLabel.Draw(target, x+300, y+20, sago::SagoTextField::Alignment::center);
+ DrawRectYellow(target, x, y, 200, 600, &globalData.logicalResize);
+ headerLabel.Draw(target, x+300, y+20, sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
if (insideRect(x+25, y+128, 50, 250)) {
- DrawRectYellow(target, x+24, y+127, 52, 252);
+ DrawRectYellow(target, x+24, y+127, 52, 252, &globalData.logicalResize);
}
else {
- DrawRectYellow(target, x+25, y+128, 50, 250);
+ DrawRectYellow(target, x+25, y+128, 50, 250, &globalData.logicalResize);
}
- enterLabel.Draw(target, x+150, y+140, sago::SagoTextField::Alignment::center);
+ enterLabel.Draw(target, x+150, y+140, sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
if (insideRect(x+325, y+128, 50, 250)) {
- DrawRectYellow(target, x+324, y+127, 52, 252);
+ DrawRectYellow(target, x+324, y+127, 52, 252, &globalData.logicalResize);
}
else {
- DrawRectYellow(target, x+325, y+128, 50, 250);
+ DrawRectYellow(target, x+325, y+128, 50, 250, &globalData.logicalResize);
}
- cancelLabel.Draw(target, x+450, y+140, sago::SagoTextField::Alignment::center);
- DrawRectWhite(target, x+26, y+64, 54, 600-2*26);
+ cancelLabel.Draw(target, x+450, y+140, sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
+ DrawRectWhite(target, x+26, y+64, 54, 600-2*26, &globalData.logicalResize);
textField.SetText(rk->GetString());
- textField.Draw(target, x+40, y+76);
+ textField.Draw(target, x+40, y+76, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
std::string strHolder = rk->GetString();
strHolder.erase((int)rk->CharsBeforeCursor());
@@ -208,15 +215,15 @@ void DialogBox::Draw(SDL_Renderer* target) {
int width = 0;
textField.GetRenderedSize( strHolder.c_str(), &width);
width -= 2;
- cursorLabel.Draw(target, x+40+width,y+76);
+ cursorLabel.Draw(target, x+40+width,y+76, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
}
const sago::SagoSprite& marked = globalData.spriteHolder->GetSprite("i_level_check_box_marked");
for (size_t i = 0; i<virtualKeyboard.gamePadCharFields.size(); ++i) {
if (virtualKeyboard.selectedChar == static_cast<int>(i)) {
- marked.Draw(target, SDL_GetTicks(), globalData.xsize/2-400+(i%keyboardRowLimit)*40-5, globalData.ysize/2+150+(i/keyboardRowLimit)*40-5);
+ marked.Draw(target, SDL_GetTicks(), globalData.xsize/2-400+(i%keyboardRowLimit)*40-5, globalData.ysize/2+150+(i/keyboardRowLimit)*40-5, &globalData.logicalResize);
}
sago::SagoTextField& f = virtualKeyboard.gamePadCharFields.at(i);
- f.Draw(target, globalData.xsize/2-400+(i%keyboardRowLimit)*40, globalData.ysize/2+150+(i/keyboardRowLimit)*40);
+ f.Draw(target, globalData.xsize/2-400+(i%keyboardRowLimit)*40, globalData.ysize/2+150+(i/keyboardRowLimit)*40, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
}
}
@@ -369,7 +376,11 @@ void DialogBox::ProcessInput(const SDL_Event& event, bool& processed) {
}
}
- if (globalData.mousex != oldmousex || globalData.mousey != oldmousey) {
+ int mousex;
+ int mousey;
+ globalData.logicalResize.PhysicalToLogical(globalData.mousex, globalData.mousey, mousex, mousey);
+
+ if (mousex != oldmousex || mousey != oldmousey) {
for (size_t i = 0; i<virtualKeyboard.gamePadCharFields.size(); ++i) {
auto topx = globalData.xsize/2-400+(i%keyboardRowLimit)*40-5;
auto topy = globalData.ysize/2+150+(i/keyboardRowLimit)*40-5;
@@ -377,8 +388,8 @@ void DialogBox::ProcessInput(const SDL_Event& event, bool& processed) {
virtualKeyboard.selectedChar = i;
}
}
- oldmousex = globalData.mousex;
- oldmousey = globalData.mousey;
+ oldmousex = mousex;
+ oldmousey = mousey;
}
}
diff --git a/source/code/DialogBox.hpp b/source/code/DialogBox.hpp index 065da60..04ad0cf 100644 --- a/source/code/DialogBox.hpp +++ b/source/code/DialogBox.hpp
@@ -77,7 +77,7 @@ private:
int oldmousey = 0;
};
-void DrawRectYellow(SDL_Renderer* target, int topx, int topy, int height, int width);
+void DrawRectYellow(SDL_Renderer* target, int topx, int topy, int height, int width, sago::SagoLogicalResize* resize = nullptr);
#endif /* DIALOGBOX_HPP */
diff --git a/source/code/HelpCommon.cpp b/source/code/HelpCommon.cpp index 3f7a514..3956225 100644 --- a/source/code/HelpCommon.cpp +++ b/source/code/HelpCommon.cpp
@@ -78,7 +78,7 @@ extern sago::SagoSprite bExit;
void HelpCommonState::Draw(SDL_Renderer* target) {
- bExit.Draw(target, SDL_GetTicks(), globalData.xsize-buttonOffset, globalData.ysize-buttonOffset);
+ bExit.Draw(target, SDL_GetTicks(), globalData.xsize-buttonOffset, globalData.ysize-buttonOffset, &globalData.logicalResize);
#if DEBUG
static sago::SagoTextField mousePos;
mousePos.SetHolder(&globalData.spriteHolder->GetDataHolder());
@@ -91,13 +91,13 @@ void HelpCommonState::Draw(SDL_Renderer* target) {
void HelpTextBoxState::Draw(SDL_Renderer* target) {
DrawBackground(target);
- titleField.Draw(target, 50, 50);
- DrawRectYellow(target, 40, 90, 600, 900);
+ titleField.Draw(target, 50, 50, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
+ DrawRectYellow(target, 40, 90, 600, 900, &globalData.logicalResize);
infoBox.SetMaxWidth(850);
- infoBox.Draw(target, 50, 100);
+ infoBox.Draw(target, 50, 100, sago::SagoTextField::Alignment::left, &globalData.logicalResize);
if (filenameField.GetText().length() > 0) {
- DrawRectYellow(target, 40, 700, 50, 900);
- filenameField.Draw(target, 50, 715);
+ DrawRectYellow(target, 40, 700, 50, 900, &globalData.logicalResize);
+ filenameField.Draw(target, 50, 715, sago::SagoTextField::Alignment::left, &globalData.logicalResize);
}
HelpCommonState::Draw(target);
}
@@ -112,9 +112,13 @@ void HelpCommonState::Update() {
if (SDL_GetMouseState(nullptr,nullptr)&SDL_BUTTON(1) && bMouseUp) {
bMouseUp = false;
+ int mousex;
+ int mousey;
+ globalData.logicalResize.PhysicalToLogical(globalData.mousex, globalData.mousey, mousex, mousey);
+
//The Score button:
- if ((globalData.mousex>globalData.xsize-buttonOffset) && (globalData.mousex<globalData.xsize-buttonOffset+bExit.GetWidth())
- && (globalData.mousey>globalData.ysize-buttonOffset) && (globalData.mousey<globalData.ysize-buttonOffset+bExit.GetHeight())) {
+ if ((mousex>globalData.xsize-buttonOffset) && (mousex<globalData.xsize-buttonOffset+bExit.GetWidth())
+ && (mousey>globalData.ysize-buttonOffset) && (mousey<globalData.ysize-buttonOffset+bExit.GetHeight())) {
isActive = false;
}
diff --git a/source/code/HelpGamepadState.cpp b/source/code/HelpGamepadState.cpp index e42afae..480a130 100644 --- a/source/code/HelpGamepadState.cpp +++ b/source/code/HelpGamepadState.cpp
@@ -67,34 +67,40 @@ void HelpGamepadState::ProcessInput(const SDL_Event& event, bool& processed) {
#define OFFSETX (-512+globalData.xsize/2)
+static void RenderDrawLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2) {
+ globalData.logicalResize.LogicalToPhysical(&x1, &y1);
+ globalData.logicalResize.LogicalToPhysical(&x2, &y2);
+ SDL_RenderDrawLine(renderer, x1, y1, x2, y2);
+}
+
void HelpGamepadState::Draw(SDL_Renderer* target) {
DrawBackground(target);
const sago::SagoSprite& gamepad = globalData.spriteHolder->GetSprite("help_controller");
- gamepad.Draw(target, SDL_GetTicks(), globalData.xsize/2-480/2, 100);
+ gamepad.Draw(target, SDL_GetTicks(), globalData.xsize/2-480/2, 100, &globalData.logicalResize);
SDL_SetRenderDrawColor(target, 0, 0, 0, SDL_ALPHA_OPAQUE);
- SDL_RenderDrawLine(target, 100+OFFSETX, 210, globalData.xsize/2-480/2+130, 210);
- SDL_RenderDrawLine(target, 100+OFFSETX, 298, globalData.xsize/2-480/2+158, 298);
- SDL_RenderDrawLine(target, 100+OFFSETX, 210, 100+OFFSETX, 400);
- moveLabel.Draw(target, 100+OFFSETX, 404, sago::SagoTextField::Alignment::center);
+ RenderDrawLine(target, 100+OFFSETX, 210, globalData.xsize/2-480/2+130, 210);
+ RenderDrawLine(target, 100+OFFSETX, 298, globalData.xsize/2-480/2+158, 298);
+ RenderDrawLine(target, 100+OFFSETX, 210, 100+OFFSETX, 400);
+ moveLabel.Draw(target, 100+OFFSETX, 404, sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
//Push lines
- SDL_RenderDrawLine(target, globalData.xsize/2-480/2+140, 90, globalData.xsize/2-480/2+140, 105);
- SDL_RenderDrawLine(target, globalData.xsize/2+480/2-140, 90, globalData.xsize/2+480/2-140, 105);
- SDL_RenderDrawLine(target, globalData.xsize/2-480/2+140-38, 90, globalData.xsize/2+480/2-140+38, 90);
- SDL_RenderDrawLine(target, globalData.xsize/2-480/2+140-38, 90, globalData.xsize/2-480/2+140-38, 110);
- SDL_RenderDrawLine(target, globalData.xsize/2+480/2-140+38, 90, globalData.xsize/2+480/2-140+38, 110);
- SDL_RenderDrawLine(target, globalData.xsize/2, 80, globalData.xsize/2, 90);
- pushLabel.Draw(target, globalData.xsize/2, 80, sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::bottom);
+ RenderDrawLine(target, globalData.xsize/2-480/2+140, 90, globalData.xsize/2-480/2+140, 105);
+ RenderDrawLine(target, globalData.xsize/2+480/2-140, 90, globalData.xsize/2+480/2-140, 105);
+ RenderDrawLine(target, globalData.xsize/2-480/2+140-38, 90, globalData.xsize/2+480/2-140+38, 90);
+ RenderDrawLine(target, globalData.xsize/2-480/2+140-38, 90, globalData.xsize/2-480/2+140-38, 110);
+ RenderDrawLine(target, globalData.xsize/2+480/2-140+38, 90, globalData.xsize/2+480/2-140+38, 110);
+ RenderDrawLine(target, globalData.xsize/2, 80, globalData.xsize/2, 90);
+ pushLabel.Draw(target, globalData.xsize/2, 80, sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::bottom, &globalData.logicalResize);
//Back lines
- SDL_RenderDrawLine(target, 800+OFFSETX, 158, 800+OFFSETX, 207);
- SDL_RenderDrawLine(target, 490+OFFSETX, 180, 800+OFFSETX, 180);
- SDL_RenderDrawLine(target, 490+OFFSETX, 180, 490+OFFSETX, 195);
- SDL_RenderDrawLine(target, 663+OFFSETX, 207, 800+OFFSETX, 207);
- backLabel.Draw(target, 800+OFFSETX, 156, sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::bottom);
- SDL_RenderDrawLine(target, 625+OFFSETX, 241, 900+OFFSETX, 241);
- SDL_RenderDrawLine(target, 900+OFFSETX, 241, 900+OFFSETX, 400);
- switchLabel.Draw(target, 900+OFFSETX, 404, sago::SagoTextField::Alignment::center);
- confirmLabel.Draw(target, 900+OFFSETX, 404+30, sago::SagoTextField::Alignment::center);
- supportedControllers.Draw(target, 10, 600);
+ RenderDrawLine(target, 800+OFFSETX, 158, 800+OFFSETX, 207);
+ RenderDrawLine(target, 490+OFFSETX, 180, 800+OFFSETX, 180);
+ RenderDrawLine(target, 490+OFFSETX, 180, 490+OFFSETX, 195);
+ RenderDrawLine(target, 663+OFFSETX, 207, 800+OFFSETX, 207);
+ backLabel.Draw(target, 800+OFFSETX, 156, sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::bottom, &globalData.logicalResize);
+ RenderDrawLine(target, 625+OFFSETX, 241, 900+OFFSETX, 241);
+ RenderDrawLine(target, 900+OFFSETX, 241, 900+OFFSETX, 400);
+ switchLabel.Draw(target, 900+OFFSETX, 404, sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
+ confirmLabel.Draw(target, 900+OFFSETX, 404+30, sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
+ supportedControllers.Draw(target, 10, 600, sago::SagoTextField::Alignment::left, &globalData.logicalResize);
HelpCommonState::Draw(target);
}
diff --git a/source/code/HelpHowtoState.cpp b/source/code/HelpHowtoState.cpp index f705ed6..53716c3 100644 --- a/source/code/HelpHowtoState.cpp +++ b/source/code/HelpHowtoState.cpp
@@ -48,9 +48,9 @@ static void RenderRowOfBricks(SDL_Renderer* target, const std::string& brickStr,
brickChar = brickChar + 'a' - 'A';
}
if (brickChar >= 'a' && brickChar <= 'g') {
- globalData.bricks[brickChar - 'a'].Draw(target, tick, x+i*50, y);
+ globalData.bricks[brickChar - 'a'].Draw(target, tick, x+i*50, y, &globalData.logicalResize);
if (bomb) {
- globalData.spriteHolder->GetSprite("block_bomb").Draw(target, tick, x+i*50, y);
+ globalData.spriteHolder->GetSprite("block_bomb").Draw(target, tick, x+i*50, y, &globalData.logicalResize);
}
}
}
@@ -131,6 +131,12 @@ HelpHowtoState::~HelpHowtoState() {
const double PI =3.141592653589793238463;
+static void RenderDrawLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2) {
+ globalData.logicalResize.LogicalToPhysical(&x1, &y1);
+ globalData.logicalResize.LogicalToPhysical(&x2, &y2);
+ SDL_RenderDrawLine(renderer, x1, y1, x2, y2);
+}
+
static void DrawArrow(SDL_Renderer* target, int x1, int y1, int x2, int y2) {
double dx = x1-x2;
double dy = y1-y2;
@@ -140,33 +146,33 @@ static void DrawArrow(SDL_Renderer* target, int x1, int y1, int x2, int y2) {
double angle= PI/4.0;
double nx1 = dx * std::cos(angle) - dy * std::sin(angle) + x2;
double ny1 = dx * std::sin(angle) + dy * std::cos(angle) + y2;
- SDL_RenderDrawLine(target, x1, y1, x2, y2);
- SDL_RenderDrawLine(target, nx1, ny1, x2, y2);
+ RenderDrawLine(target, x1, y1, x2, y2);
+ RenderDrawLine(target, nx1, ny1, x2, y2);
nx1 = dx * std::cos(-angle) - dy * std::sin(-angle) + x2;
ny1 = dx * std::sin(-angle) + dy * std::cos(-angle) + y2;
- SDL_RenderDrawLine(target, nx1, ny1, x2, y2);
+ RenderDrawLine(target, nx1, ny1, x2, y2);
}
void HelpHowtoState::Draw(SDL_Renderer* target) {
DrawBackground(target);
SDL_SetRenderDrawColor(target, 0, 0, 0, SDL_ALPHA_OPAQUE);
RenderRowOfBricks(target, switchAnimation.brickStr, 50, 50);
- globalData.spriteHolder->GetSprite("cursor").Draw(target, SDL_GetTicks(), 50+switchAnimation.cursorPos*50, 50);
- switchAnimationField.Draw(target, 50 +150+30, 50+25, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::center);
+ globalData.spriteHolder->GetSprite("cursor").Draw(target, SDL_GetTicks(), 50+switchAnimation.cursorPos*50, 50, &globalData.logicalResize);
+ switchAnimationField.Draw(target, 50 +150+30, 50+25, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::center, &globalData.logicalResize);
RenderRowOfBricks(target, "adaa", 50, 150);
- globalData.spriteHolder->GetSprite("cursor").Draw(target, SDL_GetTicks(), 50, 150);
+ globalData.spriteHolder->GetSprite("cursor").Draw(target, SDL_GetTicks(), 50, 150, &globalData.logicalResize);
RenderRowOfBricks(target, "dAAA", 50+300, 150);
DrawArrow(target, 50+200+25, 150+25, 50+300-25, 150+25);
- clearRowfield.Draw(target, 600, 150+25, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::center);
- comboField.Draw(target, 50+175, 410, sago::SagoTextField::Alignment::center);
+ clearRowfield.Draw(target, 600, 150+25, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::center, &globalData.logicalResize);
+ comboField.Draw(target, 50+175, 410, sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
MultiLineBlocks().addLine("ab").addLine("ba").addLine("ab").Render(target, 50, 250);
- globalData.spriteHolder->GetSprite("cursor").Draw(target, SDL_GetTicks(), 50, 250+50);
+ globalData.spriteHolder->GetSprite("cursor").Draw(target, SDL_GetTicks(), 50, 250+50, &globalData.logicalResize);
MultiLineBlocks().addLine("AB").addLine("AB").addLine("AB").Render(target, 50+200, 250);
DrawArrow(target, 175, 325, 225, 325);
MultiLineBlocks().addLine("a").addLine("b").addLine("e").Render(target, 50+400, 250);
- globalData.spriteHolder->GetSprite("cursor").Draw(target, SDL_GetTicks(), 50+400, 250);
+ globalData.spriteHolder->GetSprite("cursor").Draw(target, SDL_GetTicks(), 50+400, 250, &globalData.logicalResize);
MultiLineBlocks().addLine(" ").addLine("b").addLine("ea").Render(target, 50+400+200, 250);
- dropField.Draw(target, 50+400+150, 410, sago::SagoTextField::Alignment::center);
+ dropField.Draw(target, 50+400+150, 410, sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
DrawArrow(target, 575, 325, 625, 325);
DrawArrow(target, 475, 275, 525, 275);
DrawArrow(target, 525, 275, 525, 375);
@@ -176,12 +182,12 @@ void HelpHowtoState::Draw(SDL_Renderer* target) {
MultiLineBlocks().addLine(" d").addLine(" F").addLine(" F").addLine("dFd").Render(target, 50+200, 500);
MultiLineBlocks().addLine(" d").addLine(" ").addLine(" ").addLine("d d").Render(target, 50+200*2, 500);
MultiLineBlocks().addLine(" ").addLine(" ").addLine(" ").addLine("DDD").Render(target, 50+200*3, 500);
- globalData.spriteHolder->GetSprite("cursor").Draw(target, SDL_GetTicks(), 50, 650);
+ globalData.spriteHolder->GetSprite("cursor").Draw(target, SDL_GetTicks(), 50, 650, &globalData.logicalResize);
DrawArrow(target, 200, 600, 250, 600);
DrawArrow(target, 400, 600, 450, 600);
DrawArrow(target, 600, 600, 650, 600);
DrawArrow(target, 525, 525, 525, 675);
- chainField.Draw(target, 400, 710, sago::SagoTextField::Alignment::center);
+ chainField.Draw(target, 400, 710, sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
HelpCommonState::Draw(target);
}
diff --git a/source/code/MenuSystem.cpp b/source/code/MenuSystem.cpp index aa990be..aca7ffe 100644 --- a/source/code/MenuSystem.cpp +++ b/source/code/MenuSystem.cpp
@@ -108,14 +108,14 @@ bool Button::isPopOnRun() const {
static void drawToScreen(const Button& b) {
if (b.marked) {
- globalData.spriteHolder->GetSprite(b.standardButton.menu_marked).Draw(globalData.screen, SDL_GetTicks(), b.x, b.y);
+ globalData.spriteHolder->GetSprite(b.standardButton.menu_marked).Draw(globalData.screen, SDL_GetTicks(), b.x, b.y, &globalData.logicalResize);
}
else {
- globalData.spriteHolder->GetSprite(b.standardButton.menu_unmarked).Draw(globalData.screen, SDL_GetTicks(), b.x, b.y);
+ globalData.spriteHolder->GetSprite(b.standardButton.menu_unmarked).Draw(globalData.screen, SDL_GetTicks(), b.x, b.y, &globalData.logicalResize);
}
b.standardButton.getLabel(b.getLabel(), b.marked)->Draw(globalData.screen, b.x+b.standardButton.xsize/2,b.y+b.standardButton.ysize/2,
- sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::center);
+ sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::center, &globalData.logicalResize);
}
@@ -132,7 +132,7 @@ void Menu::drawSelf(SDL_Renderer* target) {
drawToScreen(*b);
}
drawToScreen(exit);
- exit.standardButton.getLabel(title, false)->Draw(target, 50, 50);
+ exit.standardButton.getLabel(title, false)->Draw(target, 50, 50, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
}
@@ -330,25 +330,28 @@ void Menu::Update() {
if ( (buttonState&SDL_BUTTON(1))==0) {
bMouseUp=true;
}
+ int mousex = globalData.mousex;
+ int mousey = globalData.mousey;
+ globalData.logicalResize.PhysicalToLogical(globalData.mousex, globalData.mousey, mousex, mousey);
- if (abs(globalData.mousex-oldmousex)>5 || abs(globalData.mousey-oldmousey)>5) {
+ if (abs(mousex-oldmousex)>5 || abs(mousey-oldmousey)>5) {
for (int i=0; i< (int)buttons.size(); ++i) {
- if (isClicked(*buttons.at(i), globalData.mousex, globalData.mousey)) {
+ if (isClicked(*buttons.at(i), mousex, mousey)) {
marked = i;
}
}
- if (isClicked(exit, globalData.mousex, globalData.mousey)) {
+ if (isClicked(exit, mousex, mousey)) {
marked = buttons.size();
}
- oldmousex = globalData.mousex;
- oldmousey = globalData.mousey;
+ oldmousex = mousex;
+ oldmousey = mousey;
}
//mouse clicked
if ( (buttonState&SDL_BUTTON(1) )==SDL_BUTTON(1) && bMouseUp) {
bMouseUp = false;
for (int i=0; i< (int)buttons.size(); ++i) {
- if (isClicked(*buttons.at(i), globalData.mousex, globalData.mousey)) {
+ if (isClicked(*buttons.at(i), mousex, mousey)) {
buttons.at(i)->doAction();
if (buttons.at(i)->isPopOnRun()) {
running = false;
@@ -357,7 +360,7 @@ void Menu::Update() {
return;
}
}
- if (isClicked(exit, globalData.mousex, globalData.mousey)) {
+ if (isClicked(exit, mousex, mousey)) {
running = false;
}
}
diff --git a/source/code/ScoresDisplay.cpp b/source/code/ScoresDisplay.cpp index 4b2767e..e6038b9 100644 --- a/source/code/ScoresDisplay.cpp +++ b/source/code/ScoresDisplay.cpp
@@ -50,7 +50,7 @@ sago::SagoTextField* ScoresDisplay::getCachedText(const std::string& text) {
}
void ScoresDisplay::Write(SDL_Renderer* target, int x, int y, const char* text) {
- getCachedText(text)->Draw(target, x, y);
+ getCachedText(text)->Draw(target, x, y, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
}
@@ -264,18 +264,18 @@ void ScoresDisplay::Draw(SDL_Renderer* target) {
const sago::SagoDataHolder* holder = &globalData.spriteHolder->GetDataHolder();
//Draw buttons:
- globalData.bBack.Draw(globalData.screen, 0, backX, backY);
+ globalData.bBack.Draw(globalData.screen, 0, backX, backY, &globalData.logicalResize);
static sago::SagoTextField backLabel;
setButtonFont(holder, backLabel, _("Back"));
- backLabel.Draw(globalData.screen, backX+60,backY+10, sago::SagoTextField::Alignment::center);
- globalData.bNext.Draw(globalData.screen, 0, nextX, nextY);
+ backLabel.Draw(globalData.screen, backX+60,backY+10, sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
+ globalData.bNext.Draw(globalData.screen, 0, nextX, nextY, &globalData.logicalResize);
static sago::SagoTextField nextLabel;
setButtonFont(holder, nextLabel, _("Next"));
- nextLabel.Draw(globalData.screen, nextX+60, nextY+10, sago::SagoTextField::Alignment::center);
+ nextLabel.Draw(globalData.screen, nextX+60, nextY+10, sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
//Draw page number
std::string pageXofY = fmt::format(_("Page {} of {}"), page+1, numberOfPages);
- getCachedText(pageXofY)->Draw(globalData.screen, globalData.xsize/2, globalData.ysize-60, sago::SagoTextField::Alignment::center);
+ getCachedText(pageXofY)->Draw(globalData.screen, globalData.xsize/2, globalData.ysize-60, sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
HelpCommonState::Draw(target);
}
@@ -309,9 +309,12 @@ void ScoresDisplay::Update() {
if (SDL_GetMouseState(nullptr,nullptr)&SDL_BUTTON(1) && bMouseUp) {
bMouseUp = false;
+ int mousex;
+ int mousey;
+ globalData.logicalResize.PhysicalToLogical(globalData.mousex, globalData.mousey, mousex, mousey);
//The back button:
- if ((globalData.mousex>backX) && (globalData.mousex<backX+buttonXsize) && (globalData.mousey>backY) && (globalData.mousey<backY+buttonYsize)) {
+ if ((mousex>backX) && (mousex<backX+buttonXsize) && (mousey>backY) && (mousey<backY+buttonYsize)) {
page--;
if (page<0) {
page = numberOfPages-1;
@@ -319,7 +322,7 @@ void ScoresDisplay::Update() {
}
//The next button:
- if ((globalData.mousex>nextX) && (globalData.mousex<nextX+buttonXsize) && (globalData.mousey>nextY) && (globalData.mousey<nextY+buttonYsize)) {
+ if ((mousex>nextX) && (mousex<nextX+buttonXsize) && (mousey>nextY) && (mousey<nextY+buttonYsize)) {
page++;
if (page>=numberOfPages) {
page = 0;
diff --git a/source/code/global.hpp b/source/code/global.hpp index eb9c185..cfe4ede 100644 --- a/source/code/global.hpp +++ b/source/code/global.hpp
@@ -26,6 +26,7 @@ http://www.blockattack.net
#include <memory>
#include "sago/SagoSpriteHolder.hpp"
+#include "sago/SagoLogicalResize.hpp"
#include "highscore.h"
#include "sago/GameStateInterface.hpp"
#include "TextManager.hpp"
@@ -107,6 +108,7 @@ struct GlobalData {
std::vector<std::string> modList;
ModInfo modinfo;
Theme theme;
+ sago::SagoLogicalResize logicalResize;
TextManager theTextManager;
diff --git a/source/code/levelselect.cpp b/source/code/levelselect.cpp index 8a193f9..12b9c66 100644 --- a/source/code/levelselect.cpp +++ b/source/code/levelselect.cpp
@@ -47,7 +47,7 @@ static sago::SagoTextField* getCachedText(const std::string& text) {
}
static void Write(SDL_Renderer* target, int x, int y, const char* text) {
- getCachedText(text)->Draw(target, x, y);
+ getCachedText(text)->Draw(target, x, y, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
}
//The function that allows the player to choose PuzzleLevel
@@ -80,7 +80,10 @@ int PuzzleLevelSelect(int Type) {
SDL_Delay(1);
auto ticks = SDL_GetTicks();
DrawBackground(globalData.screen);
- globalData.iCheckBoxArea.Draw(globalData.screen,ticks,xplace,yplace);
+ int mousex;
+ int mousey;
+ globalData.logicalResize.PhysicalToLogical(globalData.mousex, globalData.mousey, mousex, mousey);
+ globalData.iCheckBoxArea.Draw(globalData.screen,ticks,xplace,yplace, &globalData.logicalResize);
if (Type == 0) {
Write(globalData.screen, xplace+12,yplace+2,_("Select Puzzle") );
}
@@ -89,21 +92,22 @@ int PuzzleLevelSelect(int Type) {
}
//Now drow the fields you click in (and a V if clicked):
for (int i = 0; i < nrOfLevels; i++) {
- globalData.iLevelCheckBox.Draw(globalData.screen, ticks, xplace+10+(i%10)*50, yplace+60+(i/10)*50);
+ globalData.iLevelCheckBox.Draw(globalData.screen, ticks, xplace+10+(i%10)*50, yplace+60+(i/10)*50, &globalData.logicalResize);
if (i==selected) {
- globalData.iLevelCheckBoxMarked.Draw(globalData.screen, ticks, xplace+10+(i%10)*50, yplace+60+(i/10)*50);
+ globalData.iLevelCheckBoxMarked.Draw(globalData.screen, ticks, xplace+10+(i%10)*50, yplace+60+(i/10)*50, &globalData.logicalResize);
}
if (Type == 0 && PuzzleIsCleared(i)) {
- globalData.iLevelCheck.Draw(globalData.screen,ticks, xplace+10+(i%10)*50, yplace+60+(i/10)*50);
+ globalData.iLevelCheck.Draw(globalData.screen,ticks, xplace+10+(i%10)*50, yplace+60+(i/10)*50, &globalData.logicalResize);
}
if (Type == 1 && IsStageCleared(i)) {
- globalData.iLevelCheck.Draw(globalData.screen, ticks, xplace+10+(i%10)*50, yplace+60+(i/10)*50);
+ globalData.iLevelCheck.Draw(globalData.screen, ticks, xplace+10+(i%10)*50, yplace+60+(i/10)*50, &globalData.logicalResize);
}
}
SDL_Event event;
while ( SDL_PollEvent(&event) ) {
UpdateMouseCoordinates(event, globalData.mousex, globalData.mousey);
+ globalData.logicalResize.PhysicalToLogical(globalData.mousex, globalData.mousey, mousex, mousey);
if ( event.type == SDL_QUIT ) {
Config::getInstance()->setShuttingDown(5);
@@ -146,25 +150,25 @@ int PuzzleLevelSelect(int Type) {
SDL_GetKeyboardState(nullptr);
- if (globalData.mousex != oldmousex || globalData.mousey != oldmousey) {
+ if (mousex != oldmousex || mousey != oldmousey) {
int tmpSelected = -1;
int j;
for (j = 0; (tmpSelected == -1) && ( (j<nrOfLevels/10)||((j<nrOfLevels/10+1)&&(nrOfLevels%10 != 0)) ); j++) {
- if ((60+j*50<globalData.mousey-yplace)&&(globalData.mousey-yplace<j*50+92)) {
+ if ((60+j*50<mousey-yplace)&&(mousey-yplace<j*50+92)) {
tmpSelected = j*10;
}
}
if (tmpSelected != -1) {
for (int k = 0; (( (!(nrOfLevels%10) || k<nrOfLevels-10*(j-1)) )&&(k<10)); k++) {
- if ((10+k*50<globalData.mousex-xplace)&&(globalData.mousex-xplace<k*50+42)) {
+ if ((10+k*50<mousex-xplace)&&(mousex-xplace<k*50+42)) {
tmpSelected +=k;
selected = tmpSelected;
}
}
}
}
- oldmousey = globalData.mousey;
- oldmousex= globalData.mousex;
+ oldmousey = mousey;
+ oldmousex= mousex;
// If the mouse button is released, make bMouseUp equal true
if ( !(SDL_GetMouseState(nullptr, nullptr)&SDL_BUTTON(1)) ) {
@@ -177,13 +181,13 @@ int PuzzleLevelSelect(int Type) {
int levelClicked = -1;
int i;
for (i = 0; (i<nrOfLevels/10)||((i<nrOfLevels/10+1)&&(nrOfLevels%10 != 0)); i++)
- if ((60+i*50<globalData.mousey-yplace)&&(globalData.mousey-yplace<i*50+92)) {
+ if ((60+i*50<mousey-yplace)&&(mousey-yplace<i*50+92)) {
levelClicked = i*10;
}
i++;
if (levelClicked != -1)
for (int j = 0; ((j<nrOfStageLevels%(i*10))&&(j<10)); j++)
- if ((10+j*50<globalData.mousex-xplace)&&(globalData.mousex-xplace<j*50+42)) {
+ if ((10+j*50<mousex-xplace)&&(mousex-xplace<j*50+42)) {
levelClicked +=j;
levelSelected = true;
levelNr = levelClicked;
diff --git a/source/code/main.cpp b/source/code/main.cpp index d96449a..4aaaa7d 100644 --- a/source/code/main.cpp +++ b/source/code/main.cpp
@@ -222,7 +222,7 @@ static int InitImages(sago::SagoSpriteHolder& holder) {
/*Draws a image from on a given Surface. Takes source image, destination surface and coordinates*/
void DrawIMG(const sago::SagoSprite& sprite, SDL_Renderer* target, int x, int y) {
- sprite.Draw(target, SDL_GetTicks(),x,y);
+ sprite.Draw(target, SDL_GetTicks(),x,y, &globalData.logicalResize);
}
void DrawIMG_Bounded(const sago::SagoSprite& sprite, SDL_Renderer* target, int x, int y, int minx, int miny, int maxx, int maxy) {
@@ -231,7 +231,7 @@ void DrawIMG_Bounded(const sago::SagoSprite& sprite, SDL_Renderer* target, int x
bounds.y = miny;
bounds.w = maxx-minx;
bounds.h = maxy-miny;
- sprite.DrawBounded(target, SDL_GetTicks(),x,y,bounds);
+ sprite.DrawBounded(target, SDL_GetTicks(),x,y,bounds, &globalData.logicalResize);
}
SDL_Window* sdlWindow;
@@ -260,9 +260,9 @@ void ResetFullscreen() {
if (globalData.xsize < FOUR_THREE_WIDTH) {
globalData.xsize = FOUR_THREE_WIDTH;
}
- if (!puzzleEditor) {
- SDL_RenderSetLogicalSize(globalData.screen, globalData.xsize, globalData.ysize);
- }
+
+ //SDL_RenderSetLogicalSize(globalData.screen, globalData.xsize, globalData.ysize);
+ globalData.logicalResize = sago::SagoLogicalResize(globalData.xsize, globalData.ysize);
dataHolder.invalidateAll(globalData.screen);
globalData.spriteHolder.reset(new sago::SagoSpriteHolder( dataHolder ) );
globalData.spriteHolder->ReadSprites(globalData.modinfo.getModSpriteFiles());
@@ -274,10 +274,12 @@ void ResetFullscreen() {
SDL_ShowCursor(SDL_DISABLE);
}
-static bool logicalRenderer = false;
-
void DrawBackground(SDL_Renderer* target) {
SDL_RenderClear(target);
+ int w=1;
+ int h=1;
+ SDL_GetRendererOutputSize(target, &w, &h);
+ globalData.logicalResize.SetPhysicalSize(w, h);
sago::SagoSprite background = globalData.spriteHolder->GetSprite(globalData.theme.background.background_sprite);
if ( (double)globalData.xsize/globalData.ysize > 1.5 && globalData.theme.background.background_sprite_16x9.length()) {
background = globalData.spriteHolder->GetSprite(globalData.theme.background.background_sprite_16x9);
@@ -301,7 +303,9 @@ void DrawBackground(SDL_Renderer* target) {
}
return;
}
- background.DrawScaled(target, ticks, 0, 0, globalData.xsize, globalData.ysize);
+ SDL_Rect r = {0,0,globalData.xsize,globalData.ysize};
+ globalData.logicalResize.LogicalToPhysical(r);
+ background.DrawScaled(target, ticks, r.x, r.y, r.w, r.h);
}
/**
@@ -522,7 +526,7 @@ static void DrawBalls() {
DrawIMG(globalData.iChainFrame, globalData.screen, x, y);
getSmallInt(globalData.theTextManager.textArray[i].getText())->Draw(globalData.screen, x+12, y+7,
- sago::SagoTextField::Alignment::center);
+ sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
}
}
} //DrawBalls
@@ -739,7 +743,7 @@ void DrawEverything(int xsize, int ysize,BlockGameSdl* theGame, BlockGameSdl* th
//draw exit
- bExit.Draw(globalData.screen,SDL_GetTicks(), xsize-bExitOffset, ysize-bExitOffset);
+ bExit.Draw(globalData.screen,SDL_GetTicks(), xsize-bExitOffset, ysize-bExitOffset, &globalData.logicalResize);
DrawBalls();
#if DEBUG
@@ -1243,6 +1247,7 @@ int main(int argc, char* argv[]) {
globalData.xsize = SIXTEEN_NINE_WIDTH;
}
globalData.ysize = SCREEN_HIGHT;
+ globalData.logicalResize = sago::SagoLogicalResize(globalData.xsize, globalData.ysize);
sdlWindow = SDL_CreateWindow("Block Attack - Rise of the Blocks " VERSION_NUMBER,
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
@@ -1255,10 +1260,7 @@ int main(int argc, char* argv[]) {
}
SDL_Renderer* renderer = SDL_CreateRenderer(sdlWindow, -1, rendererFlags);
dieOnNullptr(renderer, "Unable to create render");
- if (config.autoScale && !puzzleEditor) {
- SDL_RenderSetLogicalSize(renderer, globalData.xsize, globalData.ysize);
- logicalRenderer = true;
- }
+
if (globalData.verboseLevel) {
SDL_RendererInfo info;
SDL_GetRendererInfo(renderer, &info);
@@ -1540,6 +1542,9 @@ int runGame(Gametype gametype, int level) {
globalData.theTextManager.update();
bool mustWriteScreenshot = false;
+ int mousex;
+ int mousey;
+ globalData.logicalResize.PhysicalToLogical(globalData.mousex, globalData.mousey, mousex, mousey);
BlockGameAction a;
a.tick = SDL_GetTicks();
@@ -1548,6 +1553,9 @@ int runGame(Gametype gametype, int level) {
while ( SDL_PollEvent(&event) ) {
UpdateMouseCoordinates(event, globalData.mousex, globalData.mousey);
+ int mousex;
+ int mousey;
+ globalData.logicalResize.PhysicalToLogical(globalData.mousex, globalData.mousey, mousex, mousey);
if ( event.type == SDL_QUIT ) {
Config::getInstance()->setShuttingDown(5);
done = 1;
@@ -1724,33 +1732,34 @@ int runGame(Gametype gametype, int level) {
bool pressed = false;
int x = 0;
int y = 0;
- theGame.GetBrickCoordinateFromMouse(pressed, event.button.x, event.button.y, x, y);
+
+ theGame.GetBrickCoordinateFromMouse(pressed, mousex, mousey, x, y);
if (pressed) {
a.action = BlockGameAction::Action::MOUSE_DOWN;
a.x = x;
a.y = y;
theGame.DoAction(a);
}
- theGame2.GetBrickCoordinateFromMouse(pressed, event.button.x, event.button.y, x, y);
+ theGame2.GetBrickCoordinateFromMouse(pressed, mousex, mousey, x, y);
if (pressed) {
a.action = BlockGameAction::Action::MOUSE_DOWN;
a.x = x;
a.y = y;
theGame2.DoAction(a);
}
- mouseDownX = event.button.x;
- mouseDownY = event.button.y;
+ mouseDownX = mousex;
+ mouseDownY = mousey;
}
if (event.button.button == SDL_BUTTON_RIGHT) {
bool pressed = false;
int x = 0;
int y = 0;
- theGame.GetBrickCoordinateFromMouse(pressed, event.button.x, event.button.y, x, y);
+ theGame.GetBrickCoordinateFromMouse(pressed, mousex, mousey, x, y);
if (pressed) {
a.action = BlockGameAction::Action::PUSH;
theGame.DoAction(a);
}
- theGame2.GetBrickCoordinateFromMouse(pressed, event.button.x, event.button.y, x, y);
+ theGame2.GetBrickCoordinateFromMouse(pressed, mousex, mousey, x, y);
if (pressed) {
a.action = BlockGameAction::Action::PUSH;
theGame2.DoAction(a);
@@ -1759,8 +1768,8 @@ int runGame(Gametype gametype, int level) {
}
if (event.type == SDL_MOUSEBUTTONUP) {
if (event.button.button == SDL_BUTTON_LEFT) {
- int x = event.button.x;
- int y = event.button.y;
+ int x = mousex;
+ int y = mousey;
a.action = BlockGameAction::Action::MOUSE_UP;
theGame.DoAction(a);
theGame2.DoAction(a);
@@ -1783,7 +1792,7 @@ int runGame(Gametype gametype, int level) {
if (pressed) {
int mx = 0;
int my = 0;
- theGame.GetBrickCoordinateFromMouse(pressed, event.motion.x, event.motion.y, mx, my);
+ theGame.GetBrickCoordinateFromMouse(pressed, mousex, mousey, mx, my);
if (pressed) {
if (mx != x) {
a.action = BlockGameAction::Action::MOUSE_MOVE;
@@ -1796,7 +1805,7 @@ int runGame(Gametype gametype, int level) {
if (pressed) {
int mx = 0;
int my = 0;
- theGame2.GetBrickCoordinateFromMouse(pressed, event.motion.x, event.motion.y, mx, my);
+ theGame2.GetBrickCoordinateFromMouse(pressed, mousex, mousey, mx, my);
if (pressed) {
if (mx != x) {
a.action = BlockGameAction::Action::MOUSE_MOVE;
@@ -1826,24 +1835,24 @@ int runGame(Gametype gametype, int level) {
bMouseUp = false;
DrawBackground(globalData.screen);
- if (stageButtonStatus != SBdontShow && (globalData.mousex > theGame.GetTopX()+globalData.cordNextButton.x)
- && (globalData.mousex < theGame.GetTopX()+globalData.cordNextButton.x+globalData.cordNextButton.xsize)
- && (globalData.mousey > theGame.GetTopY()+globalData.cordNextButton.y)
- && (globalData.mousey < theGame.GetTopY()+globalData.cordNextButton.y+globalData.cordNextButton.ysize)) {
+ if (stageButtonStatus != SBdontShow && (mousex > theGame.GetTopX()+globalData.cordNextButton.x)
+ && (mousex < theGame.GetTopX()+globalData.cordNextButton.x+globalData.cordNextButton.xsize)
+ && (mousey > theGame.GetTopY()+globalData.cordNextButton.y)
+ && (mousey < theGame.GetTopY()+globalData.cordNextButton.y+globalData.cordNextButton.ysize)) {
//Clicked the next button after a stage clear or puzzle
nextLevel(theGame, SDL_GetTicks());
}
- if (stageButtonStatus != SBdontShow && (globalData.mousex > theGame.GetTopX()+globalData.cordRetryButton .x)
- &&(globalData.mousex < theGame.GetTopX()+globalData.cordRetryButton.x+globalData.cordRetryButton.xsize)
- &&(globalData.mousey > theGame.GetTopY()+globalData.cordRetryButton.y)
- &&(globalData.mousey < theGame.GetTopY()+globalData.cordRetryButton.y+globalData.cordRetryButton.ysize)) {
+ if (stageButtonStatus != SBdontShow && (mousex > theGame.GetTopX()+globalData.cordRetryButton .x)
+ &&(mousex < theGame.GetTopX()+globalData.cordRetryButton.x+globalData.cordRetryButton.xsize)
+ &&(mousey > theGame.GetTopY()+globalData.cordRetryButton.y)
+ &&(mousey < theGame.GetTopY()+globalData.cordRetryButton.y+globalData.cordRetryButton.ysize)) {
//Clicked the retry button
retryLevel(theGame, SDL_GetTicks());
}
- if (globalData.mousex > globalData.xsize-bExitOffset && globalData.mousex < globalData.xsize-bExitOffset+bExitSize &&
- globalData.mousey > globalData.ysize-bExitOffset && globalData.mousey < globalData.ysize-bExitOffset+bExitSize) {
+ if (mousex > globalData.xsize-bExitOffset && mousex < globalData.xsize-bExitOffset+bExitSize &&
+ mousey > globalData.ysize-bExitOffset && mousey < globalData.ysize-bExitOffset+bExitSize) {
done = 1;
}
}
diff --git a/source/code/menudef_themes.cpp b/source/code/menudef_themes.cpp index e1833a1..7678ca4 100644 --- a/source/code/menudef_themes.cpp +++ b/source/code/menudef_themes.cpp
@@ -74,7 +74,7 @@ public:
Menu::Draw(target);
game->DoPaintJob();
themeTitle.SetText(fmt::format(_("Theme: {}"), globalData.theme.theme_name));
- themeTitle.Draw(target, 10, globalData.ysize-50,sago::SagoTextField::Alignment::left);
+ themeTitle.Draw(target, 10, globalData.ysize-50,sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
}
};
diff --git a/source/code/sago/SagoLogicalResize.hpp b/source/code/sago/SagoLogicalResize.hpp new file mode 100644 index 0000000..2d9074f --- /dev/null +++ b/source/code/sago/SagoLogicalResize.hpp
@@ -0,0 +1,106 @@
+/*
+Copyright (c) 2025 Poul Sander
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#pragma once
+#include <algorithm>
+#include "SDL.h"
+
+
+namespace sago {
+
+class SagoLogicalResize
+{
+public:
+ SagoLogicalResize() : logical_width_(1), logical_height_(1), physical_width_(1), physical_height_(1) { SetScaleFactor(); }
+ SagoLogicalResize(int logical_width, int logical_height)
+ : logical_width_(std::max(1, logical_width)), logical_height_(std::max(1, logical_height)), physical_width_(1), physical_height_(1) { SetScaleFactor(); }
+
+ void SetPhysicalSize(int physical_width, int physical_height)
+ {
+ //Physical size must be at least 1. Less than 1 is not drawn anyway and it prevents division by zero.
+ physical_width_ = std::max(1, physical_width);
+ physical_height_ = std::max(1, physical_height);
+ SetScaleFactor();
+ }
+
+ void LogicalToPhysical(int logical_x, int logical_y, int &physical_x, int &physical_y) const
+ {
+ physical_x = logical_x;
+ physical_y = logical_y;
+ LogicalToPhysical(&physical_x, &physical_y);
+ }
+
+ void LogicalToPhysical(int *x, int *y) const
+ {
+ if (x) {
+ *x = *x * scale_factor_ + left_margin_;
+ }
+ if (y) {
+ *y = *y * scale_factor_ + top_margin_;
+ }
+ }
+
+ void LogicalToPhysical(SDL_Rect &inout) const
+ {
+ SDL_Rect input = inout;
+ LogicalToPhysical(&inout.x, &inout.y);
+ LogicalToPhysical(input.x + input.w + 1, input.y + input.h + 1, inout.w, inout.h);
+ inout.w -= inout.x - 1;
+ inout.h -= inout.y - 1;
+ }
+
+ void PhysicalToLogical(int physical_x, int physical_y, int &logical_x, int &logical_y) const
+ {
+ logical_x = (physical_x - left_margin_) / scale_factor_;
+ logical_y = (physical_y - top_margin_) / scale_factor_;
+ }
+
+ int GetTopMargin() const
+ {
+ return top_margin_;
+ }
+
+ int GetLeftMargin() const
+ {
+ return left_margin_;
+ }
+
+private:
+ void SetScaleFactor()
+ {
+ scale_factor_ = std::min(physical_width_ / logical_width_, physical_height_ / logical_height_);
+ left_margin_ = (physical_width_ - logical_width_ * scale_factor_) / 2;
+ top_margin_ = (physical_height_ - logical_height_ * scale_factor_) / 2;
+ }
+
+ double scale_factor_;
+ int top_margin_;
+ int left_margin_;
+ double logical_width_;
+ double logical_height_;
+ double physical_width_;
+ double physical_height_;
+};
+
+} // namespace sago
\ No newline at end of file
diff --git a/source/code/sago/SagoSprite.cpp b/source/code/sago/SagoSprite.cpp index c116e3e..3fbb337 100644 --- a/source/code/sago/SagoSprite.cpp +++ b/source/code/sago/SagoSprite.cpp
@@ -65,20 +65,20 @@ SagoSprite::~SagoSprite() {
delete data;
}
-void SagoSprite::Draw(SDL_Renderer* target, Sint32 frameTime, int x, int y) const {
- DrawScaled(target, frameTime, x, y, data->imgCord.w, data->imgCord.h);
+void SagoSprite::Draw(SDL_Renderer* target, Sint32 frameTime, int x, int y, SagoLogicalResize* resize) const {
+ DrawScaled(target, frameTime, x, y, data->imgCord.w, data->imgCord.h, resize);
}
-void SagoSprite::DrawRotated(SDL_Renderer* target, Sint32 frameTime, int x, int y, const double angleRadian) const {
+void SagoSprite::DrawRotated(SDL_Renderer* target, Sint32 frameTime, int x, int y, const double angleRadian, SagoLogicalResize* resize) const {
SDL_Point center = {this->data->origin.x, this->data->origin.y};
- DrawScaledAndRotated(target, frameTime, x, y, data->imgCord.w, data->imgCord.h, angleRadian, &center, SDL_FLIP_NONE);
+ DrawScaledAndRotated(target, frameTime, x, y, data->imgCord.w, data->imgCord.h, angleRadian, &center, SDL_FLIP_NONE, resize);
}
-void SagoSprite::DrawScaled(SDL_Renderer* target, Sint32 frameTime, int x, int y, int w, int h) const {
- DrawScaledAndRotated(target, frameTime, x, y, w, h, 0.0, nullptr, SDL_FLIP_NONE);
+void SagoSprite::DrawScaled(SDL_Renderer* target, Sint32 frameTime, int x, int y, int w, int h, SagoLogicalResize* resize) const {
+ DrawScaledAndRotated(target, frameTime, x, y, w, h, 0.0, nullptr, SDL_FLIP_NONE, resize);
}
-void SagoSprite::DrawScaledAndRotated(SDL_Renderer* target, Sint32 frameTime, int x, int y, int w, int h, const double angleRadian, const SDL_Point* center, const SDL_RendererFlip flip) const {
+void SagoSprite::DrawScaledAndRotated(SDL_Renderer* target, Sint32 frameTime, int x, int y, int w, int h, const double angleRadian, const SDL_Point* center, const SDL_RendererFlip flip, SagoLogicalResize* resize) const {
if (!data->tex.get()) {
std::cerr << "Texture is null!\n";
}
@@ -94,10 +94,13 @@ void SagoSprite::DrawScaledAndRotated(SDL_Renderer* target, Sint32 frameTime, in
pos.h = h;
}
double angleDegress = angleRadian/M_PI*180.0;
+ if (resize) {
+ resize->LogicalToPhysical(pos);
+ }
SDL_RenderCopyEx(target, data->tex.get(), &rect, &pos, angleDegress, center, flip);
}
-void SagoSprite::Draw(SDL_Renderer* target, Sint32 frameTime, int x, int y, const SDL_Rect& part) const {
+void SagoSprite::Draw(SDL_Renderer* target, Sint32 frameTime, int x, int y, const SDL_Rect& part, SagoLogicalResize* resize) const {
SDL_Rect rect = data->imgCord;
rect.x+=rect.w*((frameTime/data->aniFrameTime)%data->aniFrames);
rect.x += part.x;
@@ -107,16 +110,19 @@ void SagoSprite::Draw(SDL_Renderer* target, Sint32 frameTime, int x, int y, cons
SDL_Rect pos = rect;
pos.x = x - this->data->origin.x;
pos.y = y - this->data->origin.y;
+ if (resize) {
+ resize->LogicalToPhysical(pos);
+ }
SDL_RenderCopy(target, data->tex.get(), &rect, &pos);
}
-void SagoSprite::DrawProgressive(SDL_Renderer* target, float progress, int x, int y) const {
+void SagoSprite::DrawProgressive(SDL_Renderer* target, float progress, int x, int y, SagoLogicalResize* resize) const {
Sint32 frameNumber = progress*data->aniFrames;
Sint32 frameTime = frameNumber*data->aniFrameTime;
- Draw(target, frameTime, x, y);
+ Draw(target, frameTime, x, y, resize);
}
-void SagoSprite::DrawBounded(SDL_Renderer* target, Sint32 frameTime, int x, int y, const SDL_Rect& bounds) const {
+void SagoSprite::DrawBounded(SDL_Renderer* target, Sint32 frameTime, int x, int y, const SDL_Rect& bounds, SagoLogicalResize* resize) const {
SDL_Rect rect = data->imgCord;
rect.x+=rect.w*((frameTime/data->aniFrameTime)%data->aniFrames);
SDL_Rect pos = rect;
@@ -159,6 +165,9 @@ void SagoSprite::DrawBounded(SDL_Renderer* target, Sint32 frameTime, int x, int
rect.h -= absDiff;
}
+ if (resize) {
+ resize->LogicalToPhysical(pos);
+ }
SDL_RenderCopy(target, data->tex.get(), &rect, &pos);
}
diff --git a/source/code/sago/SagoSprite.hpp b/source/code/sago/SagoSprite.hpp index 57c4e17..3ac01f3 100644 --- a/source/code/sago/SagoSprite.hpp +++ b/source/code/sago/SagoSprite.hpp
@@ -26,6 +26,7 @@ SOFTWARE.
#define SAGOSPRITE_HPP
#include "SagoDataHolder.hpp"
+#include "SagoLogicalResize.hpp"
namespace sago {
@@ -41,7 +42,7 @@ public:
* @param x Place to draw the sprite
* @param y Place to draw the sprite
*/
- void Draw(SDL_Renderer* target, Sint32 frameTime, int x, int y) const;
+ void Draw(SDL_Renderer* target, Sint32 frameTime, int x, int y, SagoLogicalResize* resize = nullptr) const;
/**
* Draws the sprite to a given render window
@@ -51,7 +52,7 @@ public:
* @param y Place to draw the sprite
* @param angleRadian Angle to rotate the sprite around origin before drawing
*/
- void DrawRotated(SDL_Renderer* target, Sint32 frameTime, int x, int y, const double angleRadian) const;
+ void DrawRotated(SDL_Renderer* target, Sint32 frameTime, int x, int y, const double angleRadian, SagoLogicalResize* resize = nullptr) const;
/**
* Draws part of the sprite to a given render window
@@ -61,7 +62,7 @@ public:
* @param y Place to draw the sprite
* @param part the part of the sprite that should be drawn.
*/
- void Draw(SDL_Renderer* target, Sint32 frameTime, int x, int y, const SDL_Rect& part) const;
+ void Draw(SDL_Renderer* target, Sint32 frameTime, int x, int y, const SDL_Rect& part, SagoLogicalResize* resize = nullptr) const;
/**
* Draws the wprite to the given renderer but makes sure to not draw outside th bounds given
@@ -71,7 +72,7 @@ public:
* @param y Place to draw the sprite
* @param bounds A recagular area that we must not draw outside.
*/
- void DrawBounded(SDL_Renderer* target, Sint32 frameTime, int x, int y, const SDL_Rect& bounds) const;
+ void DrawBounded(SDL_Renderer* target, Sint32 frameTime, int x, int y, const SDL_Rect& bounds, SagoLogicalResize* resize = nullptr) const;
/**
* Draws the sprite to a given render window
@@ -80,11 +81,11 @@ public:
* @param x Place to draw the sprite
* @param y Place to draw the sprite
*/
- void DrawProgressive(SDL_Renderer* target, float progress, int x, int y) const;
+ void DrawProgressive(SDL_Renderer* target, float progress, int x, int y, SagoLogicalResize* resize = nullptr) const;
- void DrawScaled(SDL_Renderer* target, Sint32 frameTime, int x, int y, int w, int h) const;
+ void DrawScaled(SDL_Renderer* target, Sint32 frameTime, int x, int y, int w, int h, SagoLogicalResize* resize = nullptr) const;
void DrawScaledAndRotated(SDL_Renderer* target, Sint32 frameTime, int x, int y, int w, int h,
- const double angleRadian, const SDL_Point* center, const SDL_RendererFlip flip) const;
+ const double angleRadian, const SDL_Point* center, const SDL_RendererFlip flip, SagoLogicalResize* resize = nullptr) const;
/**
* Set a different origin. Normally it is the top left cornor. But in some cases you might want to center the origin or tranform it for other reasons
diff --git a/source/code/sago/SagoTextBox.cpp b/source/code/sago/SagoTextBox.cpp index 8ad56fb..41a1c6e 100644 --- a/source/code/sago/SagoTextBox.cpp +++ b/source/code/sago/SagoTextBox.cpp
@@ -177,14 +177,14 @@ void SagoTextBox::UpdateCache() {
data->renderedText = data->text;
}
-void SagoTextBox::Draw(SDL_Renderer* target, int x, int y, SagoTextField::Alignment alignment ) {
+void SagoTextBox::Draw(SDL_Renderer* target, int x, int y, SagoTextField::Alignment alignment, SagoLogicalResize* resize ) {
if (data->text != data->renderedText) {
UpdateCache();
}
TTF_Font* font = data->tex->getFontPtr(data->fontName, data->fontSize);
int lineSkip = TTF_FontLineSkip(font);
for (size_t i = 0; i < data->lines.size(); ++i) {
- data->lines[i].Draw(target, x, y+i*lineSkip, alignment);
+ data->lines[i].Draw(target, x, y+i*lineSkip, alignment, sago::SagoTextField::VerticalAlignment::top, resize);
}
}
diff --git a/source/code/sago/SagoTextBox.hpp b/source/code/sago/SagoTextBox.hpp index 6882006..4532a4a 100644 --- a/source/code/sago/SagoTextBox.hpp +++ b/source/code/sago/SagoTextBox.hpp
@@ -57,7 +57,7 @@ public:
*/
void SetMaxWidth(int width);
const std::string& GetText() const;
- void Draw(SDL_Renderer* target, int x, int y, SagoTextField::Alignment alignment = SagoTextField::Alignment::left);
+ void Draw(SDL_Renderer* target, int x, int y, SagoTextField::Alignment alignment = SagoTextField::Alignment::left, SagoLogicalResize* resize = nullptr);
void UpdateCache();
private:
void AppendLineToCache(const std::string& text);
diff --git a/source/code/sago/SagoTextField.cpp b/source/code/sago/SagoTextField.cpp index 85e63fa..eef904a 100644 --- a/source/code/sago/SagoTextField.cpp +++ b/source/code/sago/SagoTextField.cpp
@@ -193,7 +193,7 @@ void SagoTextField::GetRenderedSize(const char* text, int* w, int* h) {
}
}
-void SagoTextField::Draw(SDL_Renderer* target, int x, int y, Alignment alignment, VerticalAlignment verticalAlignment) {
+void SagoTextField::Draw(SDL_Renderer* target, int x, int y, Alignment alignment, VerticalAlignment verticalAlignment, SagoLogicalResize* resize) {
if (data->text.empty()) {
return;
}
@@ -224,8 +224,14 @@ void SagoTextField::Draw(SDL_Renderer* target, int x, int y, Alignment alignment
int outlineTexH = 0;
SDL_QueryTexture(data->outlineTexture, NULL, NULL, &outlineTexW, &outlineTexH);
SDL_Rect dstrectOutline = { x-(data->outline), y-(data->outline), outlineTexW, outlineTexH };
+ if (resize) {
+ resize->LogicalToPhysical(dstrectOutline);
+ }
SDL_RenderCopy(target, data->outlineTexture, NULL, &dstrectOutline);
}
+ if (resize) {
+ resize->LogicalToPhysical(dstrect);
+ }
SDL_RenderCopy(target, data->texture, NULL, &dstrect);
}
diff --git a/source/code/sago/SagoTextField.hpp b/source/code/sago/SagoTextField.hpp index c97846f..9230ce5 100644 --- a/source/code/sago/SagoTextField.hpp +++ b/source/code/sago/SagoTextField.hpp
@@ -26,6 +26,7 @@ SOFTWARE.
#define SAGOTEXTFIELD_HPP
#include "SagoDataHolder.hpp"
+#include "SagoLogicalResize.hpp"
namespace sago {
@@ -109,7 +110,7 @@ public:
enum class Alignment { left = 0, right=1, center = 2 };
enum class VerticalAlignment { top = 0, center = 1, bottom = 2};
- void Draw(SDL_Renderer* target, int x, int y, Alignment alignment = Alignment::left, VerticalAlignment verticalAlignment = VerticalAlignment::top);
+ void Draw(SDL_Renderer* target, int x, int y, Alignment alignment = Alignment::left, VerticalAlignment verticalAlignment = VerticalAlignment::top, SagoLogicalResize* resize = nullptr);
/**
* Updates the cache.