git repos / blockattack-game

commit 55ea55dd

sago007 · 2018-03-24 16:07
55ea55dd987a7b88deff84dcf8266afc9cd18254 patch · browse files
parent 4ff0c7dff6bca92e9e1b92d66114d03ca4716bb8

Update the sago-library

Changed files

M source/code/BlockGameSdl.inc before
M source/code/sago/SagoDataHolder.hpp before
M source/code/sago/SagoMisc.cpp before
M source/code/sago/SagoSprite.cpp before
M source/code/sago/SagoSprite.hpp before
M source/code/sago/SagoSpriteHolder.cpp before
M source/code/sago/SagoSpriteHolder.hpp before
A source/code/sago/SagoTextBox.cpp
A source/code/sago/SagoTextBox.hpp
A source/code/sago/SagoTextField.cpp
A source/code/sago/SagoTextField.hpp
M source/code/sago/platform_folders.cpp before
M source/code/sago/platform_folders.h before
M source/misc/docker/Dockerfile.WindoesBuild before
diff --git a/source/code/BlockGameSdl.inc b/source/code/BlockGameSdl.inc index 687609f..9fadf51 100644 --- a/source/code/BlockGameSdl.inc +++ b/source/code/BlockGameSdl.inc
@@ -362,7 +362,7 @@ public:
DrawImgBoard(globalData.spriteHolder->GetSprite("touchcursor"),mx*bsize, 11*bsize-my*bsize-pixels);
}
else {
- DrawImgBoard(cursor,cursorx*bsize-4,11*bsize-cursory*bsize-pixels-4);
+ DrawImgBoard(cursor,cursorx*bsize,11*bsize-cursory*bsize-pixels);
}
}
if (ticks<gameStartedAt) {
diff --git a/source/code/sago/SagoDataHolder.hpp b/source/code/sago/SagoDataHolder.hpp index 4cc0185..068650a 100644 --- a/source/code/sago/SagoDataHolder.hpp +++ b/source/code/sago/SagoDataHolder.hpp
@@ -81,9 +81,9 @@ public:
* If the constructor without elements is used then invalidateAll(SDL_Renderer*) must be called before getTexturePtr
*/
SagoDataHolder();
- SagoDataHolder(SDL_Renderer* renderer);
+ explicit SagoDataHolder(SDL_Renderer* renderer);
/**
- * Return a pointer to the given texture. The pointer is valid for the lifetime of SagoDataHolder object it was taken from or invalidateAll is called.
+ * Return a pointer to the given texture. The pointer is valid for the lifetime of SagoDataHolder object it was taken from or until invalidateAll is called.
* @param textureName Name of the texture
* @return Pointer to the loaded texture
*/
@@ -106,6 +106,11 @@ public:
* Setting a new renderer might cause all old textures to no longer match the renderer format.
*/
void invalidateAll(SDL_Renderer* renderer);
+ /**
+ * The version number. Changes everytime the pointers are invalidated.
+ * Can be used to determen if it is neccecary to get a new pointer.
+ * @return A globally unique number.
+ */
Uint64 getVersion() const;
virtual ~SagoDataHolder();
private:
diff --git a/source/code/sago/SagoMisc.cpp b/source/code/sago/SagoMisc.cpp index da58bd8..fc0b960 100644 --- a/source/code/sago/SagoMisc.cpp +++ b/source/code/sago/SagoMisc.cpp
@@ -71,7 +71,18 @@ std::string GetFileContent(const char* filename) {
return ret;
}
+static void CreatePathToFile(const std::string& path) {
+ size_t end_of_path = path.find_last_of("/");
+ if (end_of_path == std::string::npos) {
+ //No path
+ return;
+ }
+ std::string path2dir = path.substr(0, end_of_path);
+ PHYSFS_mkdir(path2dir.c_str());
+}
+
void WriteFileContent(const char* filename, const std::string& content) {
+ CreatePathToFile(filename);
PHYSFS_file* myfile = PHYSFS_openWrite(filename);
if (!myfile) {
cerr << "Failed to open file for writing, " << PHYSFS_getLastError() << "\n";
diff --git a/source/code/sago/SagoSprite.cpp b/source/code/sago/SagoSprite.cpp index 2ddcd14..3d59b20 100644 --- a/source/code/sago/SagoSprite.cpp +++ b/source/code/sago/SagoSprite.cpp
@@ -29,8 +29,8 @@ namespace sago {
struct SagoSprite::SagoSpriteData {
TextureHandler tex;
- SDL_Rect imgCord{};
- SDL_Rect origin{};
+ SDL_Rect imgCord = {};
+ SDL_Rect origin = {};
int aniFrames = 0;
int aniFrameTime = 0;
};
@@ -71,8 +71,8 @@ void SagoSprite::DrawScaled(SDL_Renderer* target, Sint32 frameTime, int x, int y
SDL_Rect rect = data->imgCord;
rect.x+=rect.w*((frameTime/data->aniFrameTime)%data->aniFrames);
SDL_Rect pos = rect;
- pos.x = x;
- pos.y = y;
+ pos.x = x - this->data->origin.x;
+ pos.y = y - this->data->origin.y;
if (w > 0) {
pos.w = w;
}
@@ -90,11 +90,17 @@ void SagoSprite::Draw(SDL_Renderer* target, Sint32 frameTime, int x, int y, cons
rect.w = part.w;
rect.h = part.h;
SDL_Rect pos = rect;
- pos.x = x;
- pos.y = y;
+ pos.x = x - this->data->origin.x;
+ pos.y = y - this->data->origin.y;
SDL_RenderCopy(target, data->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::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);
diff --git a/source/code/sago/SagoSprite.hpp b/source/code/sago/SagoSprite.hpp index 6a19c3f..c66fd87 100644 --- a/source/code/sago/SagoSprite.hpp +++ b/source/code/sago/SagoSprite.hpp
@@ -58,7 +58,14 @@ 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) const;/**
+ * Draws the sprite to a given render window
+ * @param target The render window to draw on
+ * @param progress A float with value from 0.0f to 1.0f. Tells how far in the animation that we got
+ * @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 DrawScaled(SDL_Renderer* target, Sint32 frameTime, int x, int y, int w, int h) 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/SagoSpriteHolder.cpp b/source/code/sago/SagoSpriteHolder.cpp index 138b3e0..2b24e6a 100644 --- a/source/code/sago/SagoSpriteHolder.cpp +++ b/source/code/sago/SagoSpriteHolder.cpp
@@ -64,7 +64,7 @@ SagoSpriteHolder::~SagoSpriteHolder() {
static int getDefaultValue(const rapidjson::Value& value, const char* name, int defaultValue) {
assert(value.IsObject());
const auto& t = value.GetObject().FindMember(name);
- if (t->value.IsInt()) {
+ if (t != value.MemberEnd() && t->value.IsInt()) {
return t->value.GetInt();
}
return defaultValue;
@@ -103,8 +103,12 @@ void SagoSpriteHolder::ReadSpriteFile(const std::string& filename) {
int width = getDefaultValue(m.value, "width",0);
int number_of_frames = getDefaultValue(m.value, "number_of_frames",1);
int frame_time = getDefaultValue(m.value, "frame_time",1);
- int originx = getDefaultValue(m.value, "originx",0);
- int originy = getDefaultValue(m.value, "originy",0);
+ SDL_Rect origin = {};
+ origin.x = getDefaultValue(m.value, "originx",0);
+ origin.y = getDefaultValue(m.value, "originy",0);
+ if (origin.x != 0) {
+ cerr << "Origin: " << origin.x << ", " << origin.y << "\n";
+ }
if (number_of_frames < 1) {
number_of_frames = 1;
}
@@ -112,7 +116,7 @@ void SagoSpriteHolder::ReadSpriteFile(const std::string& filename) {
frame_time = 1;
}
std::shared_ptr<sago::SagoSprite> ptr(new SagoSprite(*(data->tex),textureName, {topx,topy,width,height},number_of_frames,frame_time));
- ptr->SetOrigin({originx,originy, 0, 0});
+ ptr->SetOrigin(origin);
this->data->sprites[std::string(spriteName)] = ptr;
}
}
diff --git a/source/code/sago/SagoSpriteHolder.hpp b/source/code/sago/SagoSpriteHolder.hpp index 2e88528..7e2924c 100644 --- a/source/code/sago/SagoSpriteHolder.hpp +++ b/source/code/sago/SagoSpriteHolder.hpp
@@ -32,7 +32,7 @@ namespace sago {
class SagoSpriteHolder {
public:
- SagoSpriteHolder(const SagoDataHolder &texHolder);
+ explicit SagoSpriteHolder(const SagoDataHolder &texHolder);
virtual ~SagoSpriteHolder();
void ReadSprites();
const sago::SagoSprite& GetSprite(const std::string &spritename) const;
diff --git a/source/code/sago/SagoTextBox.cpp b/source/code/sago/SagoTextBox.cpp new file mode 100644 index 0000000..d0efbfb --- /dev/null +++ b/source/code/sago/SagoTextBox.cpp
@@ -0,0 +1,182 @@
+/*
+Copyright (c) 2018 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.
+*/
+
+#include "SagoTextBox.hpp"
+#include "SagoTextField.hpp"
+#include <vector>
+#include <iostream>
+#include "utf8.h"
+#include <algorithm>
+
+namespace sago {
+
+struct SagoTextBox::SagoTextBoxData {
+ sago::SagoDataHolder* tex = nullptr;
+ std::string fontName = "freeserif";
+ SDL_Color color = { 255, 255, 255, 0 };
+ SDL_Color outlineColor = { 255, 255, 0, 0 };
+ int fontSize = 16;
+ int outline = 0;
+ std::string text = "";
+ std::string renderedText = "";
+ std::vector<SagoTextField> lines;
+ int maxWidth = 0;
+};
+
+SagoTextBox::SagoTextBox() {
+ data = new SagoTextBoxData();
+}
+
+SagoTextBox::~SagoTextBox() {
+ delete data;
+}
+
+void SagoTextBox::SetHolder(SagoDataHolder* holder) {
+ data->tex = holder;
+}
+
+void SagoTextBox::SetText(const char* text) {
+ data->text = text;
+}
+
+void SagoTextBox::SetColor(const SDL_Color& color) {
+ data->color = color;
+}
+
+void SagoTextBox::SetFont(const char* fontName) {
+ data->fontName = fontName;
+}
+
+void SagoTextBox::SetFontSize(int fontSize) {
+ data->fontSize = fontSize;
+}
+
+void SagoTextBox::SetOutline(int outlineSize, const SDL_Color& color) {
+ data->outline = outlineSize;
+ data->outlineColor = color;
+}
+
+void SagoTextBox::SetMaxWidth(int width) {
+ data->maxWidth = width;
+}
+
+const std::string& SagoTextBox::GetText() const {
+ return data->text;
+}
+
+void SagoTextBox::AppendLineToCache(const std::string& text) {
+ data->lines.resize(data->lines.size()+1);
+ SagoTextField& tf = data->lines.back();
+ tf.SetHolder(data->tex);
+ tf.SetFont(data->fontName.c_str());
+ tf.SetFontSize(data->fontSize);
+ tf.SetColor(data->color);
+ tf.SetOutline(data->outline, data->outlineColor);
+ tf.SetText(text.c_str());
+}
+
+
+void SagoTextBox::SplitAndAppendLineToCache(TTF_Font* font, const std::string& text) {
+ if (text.length() == 0) {
+ return;
+ }
+ int width = data->maxWidth;
+ TTF_SizeUTF8(font, text.c_str(),&width, nullptr);
+ if (data->maxWidth <= 0 || width <= data->maxWidth || text.length() == 1) {
+ AppendLineToCache(text);
+ return;
+ }
+ std::string::const_iterator splitLocation = text.begin()+1;
+ bool splitDone = false;
+ while (!splitDone) {
+ std::string::const_iterator nextSearchStart = splitLocation+1;
+ if (nextSearchStart == text.end()) {
+ splitDone = true;
+ continue;
+ }
+ std::string::const_iterator nextSpace = std::find(nextSearchStart, text.end(), ' ');
+ std::string attemptSubString(text.begin(), nextSpace);
+ TTF_SizeUTF8(font, attemptSubString.c_str(),&width, nullptr);
+ if (width <= data->maxWidth && nextSpace != text.end()) {
+ splitLocation = nextSpace;
+ }
+ else {
+ splitDone = true;
+ }
+ }
+ if (splitLocation == text.begin()+1) {
+ splitLocation = text.begin();
+ utf8::advance(splitLocation, 1, text.end());
+ splitDone = false;
+ while (!splitDone && splitLocation != text.end()) {
+ std::string::const_iterator nextSplit = splitLocation;
+ utf8::advance(nextSplit, 1, text.end());
+ std::string attemptSubString(text.begin(), nextSplit);
+ TTF_SizeUTF8(font, attemptSubString.c_str(), &width, nullptr);
+ if (width <= data->maxWidth) {
+ splitLocation = nextSplit;
+ }
+ else {
+ splitDone = true;
+ }
+ }
+ }
+ std::string firstPart(text.begin(), splitLocation);
+ AppendLineToCache(firstPart);
+ if (splitLocation == text.end()) {
+ return;
+ }
+ std::string secondPart(splitLocation, text.end());
+ SplitAndAppendLineToCache(font, secondPart);
+}
+
+void SagoTextBox::UpdateCache() {
+ TTF_Font *font = data->tex->getFontPtr(data->fontName, data->fontSize);
+ const char delim = '\n';
+ const std::string& s = data->text;
+ auto start = 0U;
+ auto end = s.find(delim);
+ while (end != std::string::npos)
+ {
+ const std::string& theSubString = s.substr(start, end - start);
+ SplitAndAppendLineToCache(font, theSubString);
+ start = end + 1;
+ end = s.find(delim, start);
+ }
+ SplitAndAppendLineToCache(font, s.substr(start, end));
+ data->renderedText = data->text;
+}
+
+void SagoTextBox::Draw(SDL_Renderer* target, int x, int y) {
+ 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);
+ }
+}
+
+} //namespace sago
\ No newline at end of file
diff --git a/source/code/sago/SagoTextBox.hpp b/source/code/sago/SagoTextBox.hpp new file mode 100644 index 0000000..fc28c3e --- /dev/null +++ b/source/code/sago/SagoTextBox.hpp
@@ -0,0 +1,66 @@
+/*
+Copyright (c) 2018 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.
+*/
+
+#ifndef SAGOTEXTBOX_HPP
+#define SAGOTEXTBOX_HPP
+
+#include "SagoDataHolder.hpp"
+#include "SagoTextField.hpp"
+
+namespace sago {
+
+class SagoTextBox {
+public:
+ SagoTextBox();
+ virtual ~SagoTextBox();
+ void SetHolder(SagoDataHolder* holder);
+ void SetText(const char* text);
+ void SetColor(const SDL_Color& color);
+ void SetFont(const char* fontName);
+ void SetFontSize(int fontSize);
+ void SetOutline(int outlineSize, const SDL_Color& color);
+ /**
+ * Sets the max width to generate. SagoTextBox will insert line breaks to keep the width below this number.
+ * Outline is not included in the width: If you have a 2 pixels outline the rendere may go 2 pixels beyond.
+ * You will always need to generate at least one char per line. If max width is too low one char will be drawn per line even if it goes above max width.
+ * Setting this to 0 will disable the feature.
+ * @param width The maximum width before forcing a line break
+ */
+ void SetMaxWidth(int width);
+ const std::string& GetText() const;
+ void Draw(SDL_Renderer* target, int x, int y);
+ void UpdateCache();
+private:
+ void AppendLineToCache(const std::string& text);
+ void SplitAndAppendLineToCache(TTF_Font* font, const std::string& text);
+ SagoTextBox(const SagoTextBox& orig) = delete;
+ SagoTextBox& operator=(const SagoTextBox& base) = delete;
+ struct SagoTextBoxData;
+ SagoTextBoxData *data;
+};
+
+} //namespace sago
+
+#endif /* SAGOTEXTBOX_HPP */
+
diff --git a/source/code/sago/SagoTextField.cpp b/source/code/sago/SagoTextField.cpp new file mode 100644 index 0000000..2a3641c --- /dev/null +++ b/source/code/sago/SagoTextField.cpp
@@ -0,0 +1,187 @@
+/*
+Copyright (c) 2018 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.
+*/
+
+#include "SagoTextField.hpp"
+#include <iostream>
+#include <SDL_ttf.h>
+
+namespace sago {
+
+ class OutlineHandler {
+ TTF_Font* font;
+ int originalOutline = 0;
+ int targetOutline;
+ bool doChange = false;
+ public:
+ OutlineHandler(TTF_Font* font, int outline) : font{font}, targetOutline{outline} {
+ originalOutline = TTF_GetFontOutline(font);
+ if (originalOutline == targetOutline) {
+ return;
+ }
+ doChange = true;
+ TTF_SetFontOutline(font, targetOutline);
+ };
+
+ void reset() {
+ if (doChange) {
+ TTF_SetFontOutline(font,originalOutline);
+ doChange = false;
+ }
+ }
+
+ ~OutlineHandler() {
+ reset();
+ }
+ private:
+ OutlineHandler(const OutlineHandler& orig) = delete;
+ OutlineHandler& operator=(const OutlineHandler& base) = delete;
+ };
+
+struct SagoTextField::SagoTextFieldData {
+ sago::SagoDataHolder* tex = nullptr;
+ SDL_Surface* textSurface = nullptr;
+ SDL_Texture* texture = nullptr;
+ SDL_Surface* outlineTextSurface = nullptr;
+ SDL_Texture* outlineTexture = nullptr;
+ std::string fontName = "freeserif";
+ SDL_Color color = { 255, 255, 255, 0 };
+ SDL_Color outlineColor = { 255, 255, 0, 0 };
+ int fontSize = 16;
+ int outline = 0;
+ std::string text = "";
+ std::string renderedText = "";
+ Uint64 renderedVersion = 0;
+};
+
+SagoTextField::SagoTextField() {
+ data = new SagoTextFieldData();
+}
+
+SagoTextField::SagoTextField(SagoTextField&& o) noexcept {
+ data = o.data;
+ o.data = nullptr;
+}
+
+SagoTextField::~SagoTextField() {
+ if(!data) {
+ return;
+ }
+ ClearCache();
+ delete data;
+}
+
+void SagoTextField::SetHolder(SagoDataHolder* holder) {
+ data->tex = holder;
+}
+
+void SagoTextField::SetText(const char* text) {
+ data->text = text;
+}
+
+void SagoTextField::SetColor(const SDL_Color& color) {
+ data->color = color;
+}
+
+void SagoTextField::SetFont(const char* fontName) {
+ data->fontName = fontName;
+}
+
+void SagoTextField::SetFontSize(int fontSize) {
+ data->fontSize = fontSize;
+}
+
+void SagoTextField::SetOutline(int outlineSize, const SDL_Color& color) {
+ data->outline = outlineSize;
+ data->outlineColor = color;
+}
+
+const std::string& SagoTextField::GetText() const {
+ return data->text;
+}
+
+void SagoTextField::ClearCache() {
+ if (!data->tex) {
+ std::cerr << "FATAL: DataHolder not set!\n";
+ abort();
+ }
+ if (data->texture) {
+ SDL_DestroyTexture(data->texture);
+ data->texture = nullptr;
+ }
+ if (data->textSurface) {
+ SDL_FreeSurface(data->textSurface);
+ data->textSurface = nullptr;
+ }
+ if (data->outlineTexture) {
+ SDL_DestroyTexture(data->outlineTexture);
+ data->outlineTexture = nullptr;
+ }
+ if (data->outlineTextSurface) {
+ SDL_FreeSurface(data->outlineTextSurface);
+ data->outlineTextSurface = nullptr;
+ }
+}
+
+void SagoTextField::UpdateCache(SDL_Renderer* target) {
+ ClearCache();
+ TTF_Font *font = data->tex->getFontPtr(data->fontName, data->fontSize);
+ data->textSurface = TTF_RenderUTF8_Blended (font, data->text.c_str(), data->color);
+ data->texture = SDL_CreateTextureFromSurface(target, data->textSurface);
+ int textWidth = 0;
+ SDL_QueryTexture(data->texture, NULL, NULL, &textWidth, NULL);
+ if (data->outline > 0) {
+ OutlineHandler oh(font, data->outline);
+ data->outlineTextSurface = TTF_RenderUTF8_Blended (font, data->text.c_str(), data->outlineColor);
+ data->outlineTexture = SDL_CreateTextureFromSurface(target, data->outlineTextSurface);
+ oh.reset();
+ }
+ data->renderedText = data->text;
+ data->renderedVersion = data->tex->getVersion();
+}
+
+void SagoTextField::Draw(SDL_Renderer* target, int x, int y) {
+ if (data->text.empty()) {
+ return;
+ }
+ if (data->text != data->renderedText || data->renderedVersion != data->tex->getVersion()) {
+ UpdateCache(target);
+ }
+ if (!data->texture) {
+ return;
+ }
+ int texW = 0;
+ int texH = 0;
+ SDL_QueryTexture(data->texture, NULL, NULL, &texW, &texH);
+ SDL_Rect dstrect = { x, y, texW, texH };
+ if (data->outlineTexture) {
+ int outlineTexW = 0;
+ int outlineTexH = 0;
+ SDL_QueryTexture(data->outlineTexture, NULL, NULL, &outlineTexW, &outlineTexH);
+ SDL_Rect dstrectOutline = { x-(data->outline), y-(data->outline), outlineTexW, outlineTexH };
+ SDL_RenderCopy(target, data->outlineTexture, NULL, &dstrectOutline);
+ }
+ SDL_RenderCopy(target, data->texture, NULL, &dstrect);
+}
+
+} //namespace sago
\ No newline at end of file
diff --git a/source/code/sago/SagoTextField.hpp b/source/code/sago/SagoTextField.hpp new file mode 100644 index 0000000..2edae17 --- /dev/null +++ b/source/code/sago/SagoTextField.hpp
@@ -0,0 +1,99 @@
+/*
+Copyright (c) 2018 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.
+*/
+
+#ifndef SAGOTEXTFIELD_HPP
+#define SAGOTEXTFIELD_HPP
+
+#include "SagoDataHolder.hpp"
+
+namespace sago {
+
+/**
+ * This is a text field.
+ * It represents a line of text to be drawn on screen. It is not possible to have line breaks.
+ * If line breaks are needed use SagoTextBox instead.
+ *
+ * This object renderes to a texture and cahces the texture. The texture will be automatically refreshed if the text changes, the SagoDataHolder is invalidated or ClearCache is called.
+ * Normally all values will be set at the beginning before text is drawn.
+ * SetHolder MUST be called before the field is drawn!
+ */
+class SagoTextField {
+public:
+ SagoTextField();
+ SagoTextField(SagoTextField&& o) noexcept;
+ SagoTextField& operator=(const SagoTextField&& base) = delete;
+ virtual ~SagoTextField();
+ /**
+ * Sets the data holder. This is MANDATORY
+ * @param holder The data holder to fetch the fonts from
+ */
+ void SetHolder(SagoDataHolder* holder);
+ /**
+ * Set the text to display.
+ * @param text The actual UTF-8 encoded text
+ */
+ void SetText(const char* text);
+ void SetColor(const SDL_Color& color);
+ /**
+ * Set the name of the font. Must be known to the data holder.
+ * @param fontName Name of the font as required by SagoDataHolder
+ */
+ void SetFont(const char* fontName);
+ void SetFontSize(int fontSize);
+ /**
+ * Enable outline against the font.
+ * @param outlineSize Number of pixels of outline.
+ * @param color The color of the outline.
+ */
+ void SetOutline(int outlineSize, const SDL_Color& color);
+ /**
+ * Get the text we are currently drawing
+ * @return The text
+ */
+ const std::string& GetText() const;
+ void Draw(SDL_Renderer* target, int x, int y);
+ /**
+ * Updates the cache.
+ * You normally do not want to call this from the outside as it is done just in time.
+ * Unless you want to precache of course....
+ * @param target Target the the text will eventually be rendered to
+ */
+ void UpdateCache(SDL_Renderer* target);
+ /**
+ * Clears the cache and forces the SagoTextField to render it again the next time it is drawn.
+ * Can be used if you have changed font, color or sizes.
+ * Changing the text implices a cache clear.
+ */
+ void ClearCache();
+private:
+ SagoTextField(const SagoTextField& orig) = delete;
+ SagoTextField& operator=(const SagoTextField& base) = delete;
+ struct SagoTextFieldData;
+ SagoTextFieldData *data;
+};
+
+} //namespace sago
+
+#endif /* SAGOTEXTFIELD_HPP */
+
diff --git a/source/code/sago/platform_folders.cpp b/source/code/sago/platform_folders.cpp index 34513bf..004ceac 100644 --- a/source/code/sago/platform_folders.cpp +++ b/source/code/sago/platform_folders.cpp
@@ -112,10 +112,10 @@ static void throwOnRelative(const char* envName, const char* envValue) {
}
/**
- * Retrives the effective user's home dir.
- * If the user is running as root we ignore the HOME environment. It works badly with sudo.
+ * Retrives the effective user's home dir.
+ * If the user is running as root we ignore the HOME environment. It works badly with sudo.
* Writing to $HOME as root implies security concerns that a multiplatform program cannot be assumed to handle.
- * @return The home directory. HOME environment is respected for non-root users if it exists.
+ * @return The home directory. HOME environment is respected for non-root users if it exists.
*/
static std::string getHome() {
std::string res;
@@ -260,7 +260,7 @@ static void PlatformFoldersFillData(std::map<std::string, std::string>& folders)
folders["XDG_TEMPLATES_DIR"] = "$HOME/.Templates";
folders["XDG_VIDEOS_DIR"] = "$HOME/Videos";
PlatformFoldersAddFromFile( getConfigHome()+"/user-dirs.dirs", folders);
- for (std::map<std::string, std::string>::iterator itr = folders.begin() ; itr != folders.end() ; itr ++ ) {
+ for (std::map<std::string, std::string>::iterator itr = folders.begin() ; itr != folders.end() ; ++itr ) {
std::string& value = itr->second;
if (value.compare(0, 5, "$HOME") == 0) {
value = getHome() + value.substr(5, std::string::npos);
diff --git a/source/code/sago/platform_folders.h b/source/code/sago/platform_folders.h index 0e3ef4a..73fba85 100644 --- a/source/code/sago/platform_folders.h +++ b/source/code/sago/platform_folders.h
@@ -27,7 +27,7 @@ SOFTWARE.
*/
#ifndef SAGO_PLATFORM_FOLDERS_H
-#define SAGO_PLATFORM_FOLDERS_H
+#define SAGO_PLATFORM_FOLDERS_H
#include <vector>
#include <string>
@@ -162,11 +162,14 @@ public:
private:
PlatformFolders(const PlatformFolders&);
PlatformFolders& operator=(const PlatformFolders&);
+#if defined(_WIN32)
+#elif defined(__APPLE__)
+#else
struct PlatformFoldersData;
PlatformFoldersData *data;
+#endif
};
} //namespace sago
-#endif /* PLATFORM_FOLDERS_H */
-
+#endif /* PLATFORM_FOLDERS_H */
diff --git a/source/misc/docker/Dockerfile.WindoesBuild b/source/misc/docker/Dockerfile.WindoesBuild index 0ff7982..64d43b0 100644 --- a/source/misc/docker/Dockerfile.WindoesBuild +++ b/source/misc/docker/Dockerfile.WindoesBuild
@@ -12,8 +12,8 @@ ENV BLOCKATTACK_VERSION 2.2.0-SNAPSHOT
RUN cd /staging/blockattack-game && \
./packdata.sh && \
-cp source/misc/travis_help/utf8_v2_3_4/source/utf8.h source/code/ && \
-cp -r source/misc/travis_help/utf8_v2_3_4/source/utf8 source/code/ && \
+cp source/misc/travis_help/utf8_v2_3_4/source/utf8.h source/code/Libs/include/ && \
+cp -r source/misc/travis_help/utf8_v2_3_4/source/utf8 source/code/Libs/include/ && \
i686-w64-mingw32.static-cmake . && \
make && \
cd windows\ installer/ && \