git repos / saland

commit fb952d0a

Poul Sander · 2025-11-17 20:18
fb952d0a37f61d731a42b53cab101f980deed107 patch · browse files
parent 10fa88ee425918b1d071794340ad0efa789416de

Backport sago:: changees from blockattaack

Changed files

M src/sago/SagoDataHolder.cpp before
M src/sago/SagoDataHolder.hpp before
A src/sago/SagoLogicalResize.hpp
M src/sago/SagoMisc.cpp before
M src/sago/SagoSprite.cpp before
M src/sago/SagoSprite.hpp before
M src/sago/SagoSpriteHolder.cpp before
M src/sago/SagoTextBox.cpp before
M src/sago/SagoTextBox.hpp before
M src/sago/SagoTextField.cpp before
M src/sago/SagoTextField.hpp before
diff --git a/src/sago/SagoDataHolder.cpp b/src/sago/SagoDataHolder.cpp index 47ef639..3f8d338 100644 --- a/src/sago/SagoDataHolder.cpp +++ b/src/sago/SagoDataHolder.cpp
@@ -24,7 +24,6 @@ SOFTWARE.
#include "SagoDataHolder.hpp"
#include <iostream>
-#include <mutex>
#include <map>
#include <vector>
#include <physfs.h>
@@ -114,8 +113,12 @@ SDL_Texture* SagoDataHolder::getTexturePtr(const std::string& textureName) const
printFileWeLoad(path);
}
if (!PHYSFS_exists(path.c_str())) {
- std::cerr << "getTextureFailed - Texture does not exist: " << path << "\n";
- return getTexturePtr("fallback");
+ // We did not find the png file. Try to see if there are a jpg file.
+ std::string jpg_path = "textures/"+textureName+".jpg";
+ if (!PHYSFS_exists(jpg_path.c_str())) {
+ sago::SagoFatalErrorF("getTextureFailed - Texture does not exist: %s", path.c_str());
+ }
+ path = jpg_path;
}
unsigned int m_size = 0;
std::unique_ptr<char[]> m_data;
@@ -253,7 +256,7 @@ TextureHandler::TextureHandler(const SagoDataHolder* holder, const std::string&
this->data = nullptr;
}
-SDL_Texture* TextureHandler::get() {
+SDL_Texture* TextureHandler::get() const {
if (version != holder->getVersion()) {
//The holder has been invalidated
this->data = this->holder->getTexturePtr(textureName);
diff --git a/src/sago/SagoDataHolder.hpp b/src/sago/SagoDataHolder.hpp index 377b51b..339d111 100644 --- a/src/sago/SagoDataHolder.hpp +++ b/src/sago/SagoDataHolder.hpp
@@ -40,11 +40,11 @@ class TextureHandler {
public:
TextureHandler() {};
TextureHandler(const SagoDataHolder* holder, const std::string& textureName);
- SDL_Texture* get();
+ SDL_Texture* get() const;
private:
std::string textureName;
const SagoDataHolder* holder = nullptr;
- SDL_Texture* data = nullptr;
+ mutable SDL_Texture* data = nullptr;
Uint64 version = 0;
};
diff --git a/src/sago/SagoLogicalResize.hpp b/src/sago/SagoLogicalResize.hpp new file mode 100644 index 0000000..53db267 --- /dev/null +++ b/src/sago/SagoLogicalResize.hpp
@@ -0,0 +1,219 @@
+/*
+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 {
+
+/**
+ * @brief Provides coordinate transformation between logical and physical screen coordinates.
+ *
+ * This class helps create resolution-independent layouts by defining coordinates in a fixed
+ * "logical" resolution and automatically converting them to the actual "physical" screen size.
+ * It maintains aspect ratio by adding letterboxing/pillarboxing margins when needed.
+ *
+ * Key concepts:
+ * - Logical coordinates: Fixed coordinate system you design for (e.g., 1920x1080)
+ * - Physical coordinates: Actual screen/window size (e.g., 1280x720, 3840x2160, etc.)
+ * - Scale factor: Calculated to fit logical size into physical size while preserving aspect ratio
+ * - Margins: Black bars added to maintain aspect ratio (letterboxing/pillarboxing)
+ * - Tile alignment: As long as tiles are resized with LogicalToPhysical, they will align correctly. No gaps or overlaps.
+ *
+ * Example usage:
+ * @code
+ * // Design your UI for 1920x1080
+ * SagoLogicalResize resize(1920, 1080);
+ * resize.SetPhysicalSize(window_width, window_height);
+ *
+ * // Draw at logical position (100, 100)
+ * int phys_x, phys_y;
+ * resize.LogicalToPhysical(100, 100, phys_x, phys_y);
+ * DrawSprite(renderer, phys_x, phys_y);
+ *
+ * // Handle mouse input
+ * int log_x, log_y;
+ * resize.PhysicalToLogical(mouse_x, mouse_y, log_x, log_y);
+ * if (log_x > 100 && log_x < 200) { ... }
+ * @endcode
+ */
+class SagoLogicalResize {
+public:
+ /**
+ * @brief Default constructor with minimal 1x1 logical size.
+ */
+ SagoLogicalResize() : logical_width_(1), logical_height_(1), physical_width_(1), physical_height_(1) {
+ SetScaleFactor();
+ }
+
+ /**
+ * @brief Constructor with specified logical resolution.
+ * @param logical_width The width of the logical coordinate system (minimum 1)
+ * @param logical_height The height of the logical coordinate system (minimum 1)
+ */
+ 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();
+ }
+
+ /**
+ * @brief Updates the physical (actual) screen size and recalculates scaling.
+ *
+ * Call this when the window is resized or when initializing the physical display size.
+ * This recalculates the scale factor and margins to fit the logical size into the physical size.
+ *
+ * @param physical_width The actual width of the screen/window (minimum 1)
+ * @param physical_height The actual height of the screen/window (minimum 1)
+ */
+ 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();
+ }
+
+ /**
+ * @brief Converts logical coordinates to physical screen coordinates.
+ *
+ * This applies the scale factor and adds the appropriate margins.
+ * Use this to convert positions where you want to draw elements on screen.
+ *
+ * @param logical_x The x coordinate in logical space
+ * @param logical_y The y coordinate in logical space
+ * @param physical_x Output: the x coordinate in physical screen space
+ * @param physical_y Output: the y coordinate in physical screen space
+ */
+ 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);
+ }
+
+ /**
+ * @brief Converts logical coordinates to physical screen coordinates (pointer version).
+ *
+ * This applies the scale factor and adds the appropriate margins.
+ * Null pointers are safely ignored.
+ *
+ * @param x Pointer to x coordinate (will be converted in place), can be null
+ * @param y Pointer to y coordinate (will be converted in place), can be null
+ */
+ void LogicalToPhysical(int* x, int* y) const {
+ if (x) {
+ *x = *x * scale_factor_ + left_margin_;
+ }
+ if (y) {
+ *y = *y * scale_factor_ + top_margin_;
+ }
+ }
+
+ /**
+ * @brief Converts a logical rectangle to physical screen coordinates.
+ *
+ * This converts both the position AND size of a rectangle. The rectangle
+ * is transformed in place. Use this for converting areas/regions rather than
+ * just single points.
+ *
+ * Note: This properly handles the size conversion by converting the bottom-right
+ * corner and calculating the new width/height from the difference.
+ *
+ * @param inout The rectangle in logical coordinates (input), converted to physical coordinates (output)
+ */
+ 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;
+ }
+
+ /**
+ * @brief Converts physical screen coordinates to logical coordinates.
+ *
+ * Use this to convert mouse input or other physical positions back to your
+ * logical coordinate system for hit detection and input handling.
+ * This removes margins and applies inverse scaling.
+ *
+ * @param physical_x The x coordinate in physical screen space
+ * @param physical_y The y coordinate in physical screen space
+ * @param logical_x Output: the x coordinate in logical space
+ * @param logical_y Output: the y coordinate in logical space
+ */
+ 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_;
+ }
+
+ /**
+ * @brief Gets the top margin (letterboxing/pillarboxing offset).
+ *
+ * This is the black bar size at the top when the aspect ratio requires vertical margins.
+ * Useful for debugging or custom rendering that needs to know the drawable area.
+ *
+ * @return The top margin in physical pixels
+ */
+ int GetTopMargin() const {
+ return top_margin_;
+ }
+
+ /**
+ * @brief Gets the left margin (letterboxing/pillarboxing offset).
+ *
+ * This is the black bar size on the left when the aspect ratio requires horizontal margins.
+ * Useful for debugging or custom rendering that needs to know the drawable area.
+ *
+ * @return The left margin in physical pixels
+ */
+ int GetLeftMargin() const {
+ return left_margin_;
+ }
+
+private:
+ /**
+ * @brief Calculates the scale factor and margins based on current logical and physical sizes.
+ *
+ * The scale factor is chosen to fit the logical size into the physical size while
+ * maintaining aspect ratio. The margins center the content on screen.
+ *
+ * Scale factor = min(physical_width/logical_width, physical_height/logical_height)
+ * This ensures the content fits in both dimensions without distortion.
+ */
+ 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_; ///< Multiplier to convert logical size to physical size
+ int top_margin_; ///< Vertical offset for centering (letterboxing)
+ int left_margin_; ///< Horizontal offset for centering (pillarboxing)
+ double logical_width_; ///< Width of the logical coordinate system
+ double logical_height_; ///< Height of the logical coordinate system
+ double physical_width_; ///< Actual width of the screen/window
+ double physical_height_; ///< Actual height of the screen/window
+};
+
+} // namespace sago
\ No newline at end of file
diff --git a/src/sago/SagoMisc.cpp b/src/sago/SagoMisc.cpp index ce21e09..08c92d6 100644 --- a/src/sago/SagoMisc.cpp +++ b/src/sago/SagoMisc.cpp
@@ -80,7 +80,8 @@ std::string GetFileContent(const char* filename) {
std::unique_ptr<char[]> m_data;
ReadBytesFromFile(filename, m_data, m_size);
//Now create a std::string
- ret = std::string(m_data.get(), m_data.get()+m_size);
+ char* inbuf = m_data.get();
+ ret = std::string(inbuf, inbuf+m_size);
return ret;
}
diff --git a/src/sago/SagoSprite.cpp b/src/sago/SagoSprite.cpp index c116e3e..e097660 100644 --- a/src/sago/SagoSprite.cpp +++ b/src/sago/SagoSprite.cpp
@@ -32,61 +32,39 @@ SOFTWARE.
namespace sago {
-struct SagoSprite::SagoSpriteData {
- TextureHandler tex;
- SDL_Rect imgCord = {};
- SDL_Rect origin = {};
- int aniFrames = 0;
- int aniFrameTime = 0;
-};
SagoSprite::SagoSprite() {
- data = new SagoSpriteData();
}
SagoSprite::SagoSprite(const SagoDataHolder& texHolder, const std::string& texture,const SDL_Rect& initImage,const int animationFrames, const int animationFrameLength) {
- data = new SagoSpriteData();
- data->tex = texHolder.getTextureHandler(texture);
- data->imgCord = initImage;
- data->aniFrames = animationFrames;
- data->aniFrameTime = animationFrameLength;
+ tex = texHolder.getTextureHandler(texture);
+ imgCord = initImage;
+ aniFrames = animationFrames;
+ aniFrameTime = animationFrameLength;
}
-SagoSprite::SagoSprite(const SagoSprite& base) : data(new SagoSpriteData(*base.data)) {
-
-}
-
-SagoSprite& SagoSprite::operator=(const SagoSprite& base) {
- *data = *base.data;
- return *this;
-}
-
-SagoSprite::~SagoSprite() {
- delete data;
+void SagoSprite::Draw(SDL_Renderer* target, Sint32 frameTime, int x, int y, SagoLogicalResize* resize) const {
+ DrawScaled(target, frameTime, x, y, imgCord.w, imgCord.h, resize);
}
-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::DrawRotated(SDL_Renderer* target, Sint32 frameTime, int x, int y, const double angleRadian, SagoLogicalResize* resize) const {
+ SDL_Point center = {this->origin.x, this->origin.y};
+ DrawScaledAndRotated(target, frameTime, x, y, imgCord.w, imgCord.h, angleRadian, &center, SDL_FLIP_NONE, resize);
}
-void SagoSprite::DrawRotated(SDL_Renderer* target, Sint32 frameTime, int x, int y, const double angleRadian) 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);
+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::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::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 {
- if (!data->tex.get()) {
+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 (!tex.get()) {
std::cerr << "Texture is null!\n";
}
- SDL_Rect rect = data->imgCord;
- rect.x+=rect.w*((frameTime/data->aniFrameTime)%data->aniFrames);
+ SDL_Rect rect = imgCord;
+ rect.x+=rect.w*((frameTime/aniFrameTime)%aniFrames);
SDL_Rect pos = rect;
- pos.x = x - this->data->origin.x;
- pos.y = y - this->data->origin.y;
+ pos.x = x - this->origin.x;
+ pos.y = y - this->origin.y;
if (w > 0) {
pos.w = w;
}
@@ -94,31 +72,37 @@ void SagoSprite::DrawScaledAndRotated(SDL_Renderer* target, Sint32 frameTime, in
pos.h = h;
}
double angleDegress = angleRadian/M_PI*180.0;
- SDL_RenderCopyEx(target, data->tex.get(), &rect, &pos, angleDegress, center, flip);
+ if (resize) {
+ resize->LogicalToPhysical(pos);
+ }
+ SDL_RenderCopyEx(target, tex.get(), &rect, &pos, angleDegress, center, flip);
}
-void SagoSprite::Draw(SDL_Renderer* target, Sint32 frameTime, int x, int y, const SDL_Rect& part) const {
- SDL_Rect rect = data->imgCord;
- rect.x+=rect.w*((frameTime/data->aniFrameTime)%data->aniFrames);
+void SagoSprite::Draw(SDL_Renderer* target, Sint32 frameTime, int x, int y, const SDL_Rect& part, SagoLogicalResize* resize) const {
+ SDL_Rect rect = imgCord;
+ rect.x+=rect.w*((frameTime/aniFrameTime)%aniFrames);
rect.x += part.x;
rect.y += part.y;
rect.w = part.w;
rect.h = part.h;
SDL_Rect pos = rect;
- pos.x = x - this->data->origin.x;
- pos.y = y - this->data->origin.y;
- SDL_RenderCopy(target, data->tex.get(), &rect, &pos);
+ pos.x = x - this->origin.x;
+ pos.y = y - this->origin.y;
+ if (resize) {
+ resize->LogicalToPhysical(pos);
+ }
+ SDL_RenderCopy(target, tex.get(), &rect, &pos);
}
-void SagoSprite::DrawProgressive(SDL_Renderer* target, float progress, int x, int y) const {
- Sint32 frameNumber = progress*data->aniFrames;
- Sint32 frameTime = frameNumber*data->aniFrameTime;
- Draw(target, frameTime, x, y);
+void SagoSprite::DrawProgressive(SDL_Renderer* target, float progress, int x, int y, SagoLogicalResize* resize) const {
+ Sint32 frameNumber = progress*aniFrames;
+ Sint32 frameTime = frameNumber*aniFrameTime;
+ Draw(target, frameTime, x, y, resize);
}
-void SagoSprite::DrawBounded(SDL_Renderer* target, Sint32 frameTime, int x, int y, const SDL_Rect& bounds) const {
- SDL_Rect rect = data->imgCord;
- rect.x+=rect.w*((frameTime/data->aniFrameTime)%data->aniFrames);
+void SagoSprite::DrawBounded(SDL_Renderer* target, Sint32 frameTime, int x, int y, const SDL_Rect& bounds, SagoLogicalResize* resize) const {
+ SDL_Rect rect = imgCord;
+ rect.x+=rect.w*((frameTime/aniFrameTime)%aniFrames);
SDL_Rect pos = rect;
pos.x = x;
pos.y = y;
@@ -159,18 +143,21 @@ void SagoSprite::DrawBounded(SDL_Renderer* target, Sint32 frameTime, int x, int
rect.h -= absDiff;
}
- SDL_RenderCopy(target, data->tex.get(), &rect, &pos);
+ if (resize) {
+ resize->LogicalToPhysical(pos);
+ }
+ SDL_RenderCopy(target, tex.get(), &rect, &pos);
}
void SagoSprite::SetOrigin(const SDL_Rect& newOrigin) {
- data->origin = newOrigin;
+ origin = newOrigin;
}
int SagoSprite::GetWidth() const {
- return data->imgCord.w;
+ return imgCord.w;
}
int SagoSprite::GetHeight() const {
- return data->imgCord.h;
+ return imgCord.h;
}
} //namespace sago
diff --git a/src/sago/SagoSprite.hpp b/src/sago/SagoSprite.hpp index 57c4e17..025d6b6 100644 --- a/src/sago/SagoSprite.hpp +++ b/src/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,25 +81,41 @@ 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
* @param newOrigin the coordinates that should be the new origin. Call with {0,0} to reset to default
*/
void SetOrigin(const SDL_Rect& newOrigin);
- SagoSprite(const SagoSprite& base);
- SagoSprite& operator=(const SagoSprite& base);
+ SagoSprite(const SagoSprite& base) = default;
+ SagoSprite& operator=(const SagoSprite& base) = default;
int GetWidth() const;
int GetHeight() const;
- ~SagoSprite();
+ ~SagoSprite() = default;
+
+ const TextureHandler& GetTextureHandler() const {
+ return this->tex;
+ }
+
+ const SDL_Rect& GetImageCord() const {
+ return this->imgCord;
+ }
+
+ const SDL_Rect& GetOrigin() const {
+ return this->origin;
+ }
+
private:
- struct SagoSpriteData;
- SagoSpriteData* data;
+ TextureHandler tex;
+ SDL_Rect imgCord = {};
+ SDL_Rect origin = {};
+ int aniFrames = 0;
+ int aniFrameTime = 0;
};
}
diff --git a/src/sago/SagoSpriteHolder.cpp b/src/sago/SagoSpriteHolder.cpp index 94c4c1c..88047d4 100644 --- a/src/sago/SagoSpriteHolder.cpp +++ b/src/sago/SagoSpriteHolder.cpp
@@ -148,6 +148,7 @@ const sago::SagoSprite& SagoSpriteHolder::GetSprite(const std::string& spritenam
}
}
+
const SagoDataHolder& SagoSpriteHolder::GetDataHolder() const {
return *data->tex;
}
diff --git a/src/sago/SagoTextBox.cpp b/src/sago/SagoTextBox.cpp index 8ad56fb..41a1c6e 100644 --- a/src/sago/SagoTextBox.cpp +++ b/src/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/src/sago/SagoTextBox.hpp b/src/sago/SagoTextBox.hpp index 6882006..4532a4a 100644 --- a/src/sago/SagoTextBox.hpp +++ b/src/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/src/sago/SagoTextField.cpp b/src/sago/SagoTextField.cpp index 85e63fa..eef904a 100644 --- a/src/sago/SagoTextField.cpp +++ b/src/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/src/sago/SagoTextField.hpp b/src/sago/SagoTextField.hpp index c97846f..9230ce5 100644 --- a/src/sago/SagoTextField.hpp +++ b/src/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.