From ea2dc4f6b50e424d70af7ccdb7f40282e798bb568340a1b640663d1b00d999d3 Mon Sep 17 00:00:00 2001 From: Mexpert_PRO Date: Mon, 2 Feb 2026 20:52:28 +0100 Subject: [PATCH] implemented TileMap, still need Shader for it with billboarding and all that jizz XD --- TSE_Core/src/BehaviourScripts/TileMap.cpp | 54 ++++++++++++++++ TSE_Core/src/BehaviourScripts/TileMap.hpp | 56 ++++++++++++++++ TSE_Core/src/elements/Texture.cpp | 78 ----------------------- TSE_Core/src/elements/Texture.hpp | 2 - TSE_Core/src/elements/TileSet.hpp | 2 +- TSE_Math/src/MathF.hpp | 3 + TSE_Math/src/Vector2.hpp | 16 +++++ 7 files changed, 130 insertions(+), 81 deletions(-) create mode 100644 TSE_Core/src/BehaviourScripts/TileMap.cpp create mode 100644 TSE_Core/src/BehaviourScripts/TileMap.hpp diff --git a/TSE_Core/src/BehaviourScripts/TileMap.cpp b/TSE_Core/src/BehaviourScripts/TileMap.cpp new file mode 100644 index 0000000..3c9aacf --- /dev/null +++ b/TSE_Core/src/BehaviourScripts/TileMap.cpp @@ -0,0 +1,54 @@ +#include "TileMap.hpp" + +TSE::TileMapChunk::TileMapChunk(int _chunksize, const Vector2 &_pos, SortingOrder _order) +{ + chunksize = _chunksize; + pos = _pos; + order = _order; +} + +void TSE::TileMapChunk::SetTile(const Vector2& p, const Vector2& Spriteindex, TileSet* set) +{ + Sprite s; + set->GetSpriteAt(Spriteindex, s); + sprites[p] = s; +} + +void TSE::TileMapChunk::RemoveTile(Vector2 p) +{ + sprites.erase(p); +} + +void TSE::TileMapChunk::SetOrdering(SortingOrder _order) +{ + order = _order; +} + +void TSE::TileMap::RemoveTile(Vector2 p) +{ + Vector2 chunkInnerPos = LocalToChunkPos(p); + Vector2 chunkIndex = p - chunkInnerPos; + if(chunks.contains(chunkIndex)) + chunks[chunkIndex].RemoveTile(chunkInnerPos); +} + +void TSE::TileMap::SetTile(Vector2 p, Vector2 Spriteindex) +{ + Vector2 chunkInnerPos = LocalToChunkPos(p); + Vector2 chunkIndex = p - chunkInnerPos; + if(!chunks.contains(chunkIndex)) + { + chunks[chunkIndex] = TileMapChunk(chunkSize, chunkIndex, order); + } + chunks[chunkIndex].SetTile(chunkInnerPos, Spriteindex, set); +} + +TSE::Vector2 TSE::TileMap::LocalToChunkPos(const Vector2 &v) +{ + return Vector2((int)v.x % chunkSize, (int)v.y % chunkSize); +} + +TSE::Vector2 TSE::TileMap::ChunkToLocalPos(const Vector2 &v, const TileMapChunk &chunk) +{ + return v + chunk.pos * chunkSize; +} diff --git a/TSE_Core/src/BehaviourScripts/TileMap.hpp b/TSE_Core/src/BehaviourScripts/TileMap.hpp new file mode 100644 index 0000000..c30abe1 --- /dev/null +++ b/TSE_Core/src/BehaviourScripts/TileMap.hpp @@ -0,0 +1,56 @@ +#pragma once + +#define TILE_MAP typeid(TSE::TileMap).name() + +#include +#include "elements/BehaviourScript.hpp" +#include "Vector2.hpp" +#include "elements/Sprite.hpp" +#include "elements/TileSet.hpp" + +namespace TSE +{ + enum SortingOrder + { + TopRight, + TopLeft, + BottomRight, + BottomLeft, + }; + + struct TileMapChunk + { + private: + SortingOrder order; + int chunksize; + std::unordered_map sprites; + public: + Vector2 pos; + TileMapChunk(int _chunksize, const Vector2& _pos, SortingOrder _order); + + void SetTile(const Vector2& p, const Vector2& Spriteindex, TileSet* set); + void RemoveTile(Vector2 p); + void SetOrdering(SortingOrder _order); + + }; + + class TileMap : public BehaviourScript + { + public: + int chunkSize = 16; + SortingOrder order = TopRight; + TileSet* set; + std::unordered_map chunks; + + void RemoveTile(Vector2 p); + void SetTile(Vector2 p, Vector2 Spriteindex); + + inline const char* GetName() override + { + return "Tile Map"; + } + private: + Vector2 LocalToChunkPos(const Vector2& v); + Vector2 ChunkToLocalPos(const Vector2& v, const TileMapChunk& chunk); + }; +} // namespace TSE diff --git a/TSE_Core/src/elements/Texture.cpp b/TSE_Core/src/elements/Texture.cpp index d4b36da..336a3fe 100644 --- a/TSE_Core/src/elements/Texture.cpp +++ b/TSE_Core/src/elements/Texture.cpp @@ -199,84 +199,6 @@ TSE::Texture TSE::Texture::CutOut(const Vector2 &pos, Vector2 &size) const return out; } -TSE::Texture TSE::Texture::Upscale(const Vector2 &size) const -{ - Texture result = Texture(0,0); - if(bmp == nullptr) - { - TSE_ERROR("Failed to upscale texture. Source bitmap was nullptr."); - Texture::makeError(result); - return result; - } - - const int width = static_cast(size.x); - const int height = static_cast(size.y); - if(width <= 0 || height <= 0) - { - TSE_ERROR("Failed to upscale texture. Size must be greater than 0."); - Texture::makeError(result); - return result; - } - - FIBITMAP* scaled = FreeImage_Rescale(bmp, width, height, FILTER_NEAREST); - if(scaled == nullptr) - { - TSE_ERROR("Failed to upscale texture. FreeImage_Rescale returned nullptr."); - Texture::makeError(result); - return result; - } - - Texture out = Texture(width, height, Bpp); - if(out.bmp != nullptr) - FreeImage_Unload(out.bmp); - out.bmp = scaled; - out.imagePtr = FreeImage_GetBits(scaled); - out.Bpp = Bpp; - out.chanels = chanels; - out.Size = Vector2(width, height); - out.Apply(); - return out; -} - -TSE::Texture TSE::Texture::Downscale(const Vector2 &size) const -{ - Texture result = Texture(0,0); - if(bmp == nullptr) - { - TSE_ERROR("Failed to downscale texture. Source bitmap was nullptr."); - Texture::makeError(result); - return result; - } - - const int width = static_cast(size.x); - const int height = static_cast(size.y); - if(width <= 0 || height <= 0) - { - TSE_ERROR("Failed to downscale texture. Size must be greater than 0."); - Texture::makeError(result); - return result; - } - - FIBITMAP* scaled = FreeImage_Rescale(bmp, width, height, FILTER_NEAREST); - if(scaled == nullptr) - { - TSE_ERROR("Failed to downscale texture. FreeImage_Rescale returned nullptr."); - Texture::makeError(result); - return result; - } - - Texture out = Texture(width, height, Bpp); - if(out.bmp != nullptr) - FreeImage_Unload(out.bmp); - out.bmp = scaled; - out.imagePtr = FreeImage_GetBits(scaled); - out.Bpp = Bpp; - out.chanels = chanels; - out.Size = Vector2(width, height); - out.Apply(); - return out; -} - void TSE::Texture::PasteIn(const Vector2 &pos, Texture &t) { if(bmp == nullptr) diff --git a/TSE_Core/src/elements/Texture.hpp b/TSE_Core/src/elements/Texture.hpp index 543668c..0c6ebb4 100644 --- a/TSE_Core/src/elements/Texture.hpp +++ b/TSE_Core/src/elements/Texture.hpp @@ -39,8 +39,6 @@ namespace TSE void SetPixel(const Vector2& pos, const Color& c); void GetPixel(const Vector2& pos, Color& c) const; Texture CutOut(const Vector2& pos, Vector2& size) const; - Texture Upscale(const Vector2& size) const; - Texture Downscale(const Vector2& size) const; void PasteIn(const Vector2& pos, Texture& t); void SetPixelNoApply(const Vector2& pos, const Color& c); void ToSprite(Sprite& s); diff --git a/TSE_Core/src/elements/TileSet.hpp b/TSE_Core/src/elements/TileSet.hpp index d5fa3dd..c507878 100644 --- a/TSE_Core/src/elements/TileSet.hpp +++ b/TSE_Core/src/elements/TileSet.hpp @@ -23,7 +23,7 @@ namespace TSE { SetCount(v.x, v.y); }; - inline void GetSpriteAt(Vector2& v, Sprite& s) + inline void GetSpriteAt(const Vector2& v, Sprite& s) { GetSpriteAt(v.x, v.y, s); }; diff --git a/TSE_Math/src/MathF.hpp b/TSE_Math/src/MathF.hpp index cf4f6d0..f59f368 100644 --- a/TSE_Math/src/MathF.hpp +++ b/TSE_Math/src/MathF.hpp @@ -11,6 +11,9 @@ namespace TSE /// @brief the epsilon used as min float value for comparisons in the engine constexpr float TSE_EPSILON = 1e-6f; + /// @brief 32-bit golden ratio constant used for hash mixing + constexpr uint TSE_HASH_GOLDEN_RATIO_32 = 0x9e3779b9u; + /// @brief a simple degrees to radiant conversion function /// @param deg the degrees value /// @return the radiant value diff --git a/TSE_Math/src/Vector2.hpp b/TSE_Math/src/Vector2.hpp index 6d8c834..e4a90f1 100644 --- a/TSE_Math/src/Vector2.hpp +++ b/TSE_Math/src/Vector2.hpp @@ -1,6 +1,8 @@ #pragma once #include "Types.hpp" +#include "MathF.hpp" +#include namespace TSE { @@ -135,3 +137,17 @@ namespace TSE #pragma endregion methods }; } // namespace TSE + +namespace std +{ + template<> + struct hash + { + size_t operator()(const TSE::Vector2& v) const noexcept + { + size_t h1 = std::hash{}(v.x); + size_t h2 = std::hash{}(v.y); + return h1 ^ (h2 + TSE::TSE_HASH_GOLDEN_RATIO_32 + (h1 << 6) + (h1 >> 2)); + } + }; +}