From 37a249dc6278948847657f34396a50a4492d00e9 Mon Sep 17 00:00:00 2001 From: n0ffie Date: Tue, 18 Mar 2025 21:55:08 +0100 Subject: [PATCH] Fixing loading problem + ImHex Pattern Code --- CMakeLists.txt | 4 +-- src/Enemy/Enemy.cpp | 2 ++ src/Game.cpp | 7 +++++ src/Map/Map.cpp | 66 +++++++++++++++++++++++++++++++--------- src/Map/Map.hpp | 15 +++++++-- src/Map/TileAtlas.cpp | 27 ++++++++-------- src/Map/TileAtlas.hpp | 8 +++-- src/main.cpp | 20 ++++++++++-- utils/MapFile.hexpat | 71 +++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 179 insertions(+), 41 deletions(-) create mode 100644 utils/MapFile.hexpat diff --git a/CMakeLists.txt b/CMakeLists.txt index 749f093..62a6637 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,9 +55,7 @@ target_link_libraries(colysis target_compile_definitions(colysis PUBLIC "$<$:_DEBUG>") -target_include_directories(colysis PUBLIC include - #${ALYSON_INCLUDE_DIR} -) +target_include_directories(colysis PUBLIC include ) # put the assets folder path as a C preprocessor define set(ASSETS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/assets/") diff --git a/src/Enemy/Enemy.cpp b/src/Enemy/Enemy.cpp index 65fb124..fed83d1 100644 --- a/src/Enemy/Enemy.cpp +++ b/src/Enemy/Enemy.cpp @@ -1,5 +1,7 @@ #include "Enemy.hpp" +#include + Enemy::Enemy(sf::Vector2f position) : rectangle(sf::Vector2f{100, 100}) { rectangle.move(position); diff --git a/src/Game.cpp b/src/Game.cpp index aeb7e9c..433b1c7 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -9,12 +9,19 @@ Game::Game(sf::RenderWindow& window) : window(window) #include void Game::run() { +#ifdef _DEBUG std::cout << "Loading map... Version: " MAP_VERSION_STRING << std::endl; auto start = std::chrono::system_clock::now(); +#endif + auto err = map.load(ASSETS_PATH "/test.cymf"); + +#ifdef _DEBUG auto end = std::chrono::system_clock::now(); auto milliseconds = std::chrono::duration_cast(end - start); std::cout << "Loading took: " << milliseconds << std::endl; +#endif + if (err.code != 0) { std::cout << err.message << std::endl; diff --git a/src/Map/Map.cpp b/src/Map/Map.cpp index af8470b..e9511c9 100644 --- a/src/Map/Map.cpp +++ b/src/Map/Map.cpp @@ -2,7 +2,9 @@ #include -Map::Map() {} +bool operator==(uint32_t lhs, TileType rhs) { + return lhs == static_cast(rhs); +} bool operator&(uint8_t lhs, MapFlags rhs) { @@ -19,17 +21,47 @@ auto operator<=>(int lhs, TileType rhs) return lhs <=> static_cast(rhs); } +MapError Map::populate_vertex_array() { + if (!tiles) return {"Map: [Loading] Tilemap is not loaded", 2}; + + vertices.setPrimitiveType(sf::PrimitiveType::Triangles); + vertices.resize(map_size.x * map_size.y); + + for (uint32_t x = 0; x < map_size.x; x++) { + for (uint32_t y = 0; y < map_size.y; ++y) + { + uint32_t tile = tiles[x + y * map_size.y]; + /* + * ----- + * --#++ + * +++++ + * + * + = other + * - = wall + * # = special + */ + } + } + return {"Map: [Loading] Success", 0}; +} + +Map::Map() {} + + #include +#include + +#include MapError Map::load(const std::filesystem::path& path) { // opening the file and checking the magic number std::ifstream file(path, std::ios::binary | std::ios::in); - char magic[4]; - file.read(magic, 4); + uint32_t magic; + file.read(reinterpret_cast(&magic), 4); - if (std::memcmp(magic, "CYMF", 4) != 0) { - return {"Map: [Loading] Invalid magic number", 1}; + if (std::memcmp(&magic, "CYMF", 4) != 0) { + return {"Map: [Loading] Invalid magic number: " + std::string(reinterpret_cast(&magic), 4) + " (expected CYMF)", 1}; } // reading the version @@ -53,7 +85,7 @@ MapError Map::load(const std::filesystem::path& path) char* filepath_buffer = new char[filepath_buffer_size]; file.read(filepath_buffer, filepath_buffer_size); - tileAtlas.load(std::filesystem::path(filepath_buffer)); + delete[] filepath_buffer; } @@ -129,19 +161,22 @@ sf::Vector2u Map::getSize() const return {static_cast(map_size.y), static_cast(map_size.z)}; } -void Map::draw(sf::RenderTarget& target, const sf::RenderStates states) const +void Map::draw(sf::RenderTarget& target, sf::RenderStates states) const { if (!tiles) return; - for (uint32_t x = 0; x < map_size.y; x++) { - for (uint32_t y = 0; y < map_size.z; ++y) - { - target.draw(tileAtlas, states); - } - } + + // apply the transform + states.transform *= getTransform(); + + // apply the tileset texture + states.texture = &texture; + + // draw the vertex array + target.draw(vertices, states); } -#include +#ifdef _DEBUG void Map::debug() { std::cout << "Map Debug" << std::endl; @@ -159,4 +194,5 @@ void Map::debug() std::cout << "\t\t\tSpawn : " << spawn.x << ", " << spawn.y << std::endl; } std::cout << "\t\tPlayer Spawn : " << player_spawn.x << ", " << player_spawn.y << std::endl; -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/src/Map/Map.hpp b/src/Map/Map.hpp index f28e631..c56c5ec 100644 --- a/src/Map/Map.hpp +++ b/src/Map/Map.hpp @@ -66,18 +66,22 @@ enum class TileType : int struct MapError { - const char* message; + std::string message; int code; }; #include "TileAtlas.hpp" -class Map : public sf::Drawable +class Map : public sf::Drawable, public sf::Transformable { static_assert(sizeof(MapSpecial)%4 == 0); - TileAtlas tileAtlas = TileAtlas::defaultAtlas(); + sf::Vector2u tile_size; + sf::Vector2u tile_count; + sf::Texture texture; + sf::VertexArray vertices; + sf::Vector3 map_size; // width * height, width, height int *tiles = nullptr; @@ -86,6 +90,9 @@ class Map : public sf::Drawable std::vector enemy_spawns; sf::Vector2u player_spawn; + + MapError populate_vertex_array(); + public: Map(); @@ -95,7 +102,9 @@ public: void draw(sf::RenderTarget& target, sf::RenderStates states) const override; +#ifdef _DEBUG void debug(); +#endif }; diff --git a/src/Map/TileAtlas.cpp b/src/Map/TileAtlas.cpp index 5bd7d9e..b3277ed 100644 --- a/src/Map/TileAtlas.cpp +++ b/src/Map/TileAtlas.cpp @@ -3,39 +3,36 @@ TileAtlas TileAtlas::defaultAtlas() { TileAtlas atlas(sf::Vector2u{16, 16}, sf::Vector2u{16, 16}, ASSETS_PATH "/default_tilemap.png"); - atlas.sprite.setTexture(atlas.texture); - atlas.sprite.setTextureRect(sf::IntRect({0, 0}, {static_cast(atlas.tile_size.x), static_cast(atlas.tile_size.y)})); return atlas; } void TileAtlas::set(uint32_t x, uint32_t y) { if (x >= tile_count.x || y >= tile_count.y) return; - sprite.setTextureRect(sf::IntRect({static_cast(x * tile_size.x), static_cast(y * tile_size.y)}, sf::Vector2(tile_size))); } TileAtlas::TileAtlas(const sf::Vector2u tile_size, const sf::Vector2u tile_count, const std::filesystem::path& path) : - tile_size(tile_size), tile_count(tile_count), sprite(texture) { load(path); } + tile_size(tile_size), tile_count(tile_count) { load(path); } -TileAtlas::TileAtlas(sf::Vector2u tile_size, sf::Vector2u tile_count) : tile_size(tile_size), tile_count(tile_count), sprite(texture) +TileAtlas::TileAtlas(sf::Vector2u tile_size, sf::Vector2u tile_count) : tile_size(tile_size), tile_count(tile_count) { } -void TileAtlas::load(const std::filesystem::path& path) -{ +void TileAtlas::load(const std::filesystem::path& path) { if (!texture.loadFromFile(path)) { throw std::runtime_error("TileAtlas: [Loading] Could not load tilemap -> Fatal"); } - sprite.setTexture(texture); - sprite.setTextureRect(sf::IntRect({0, 0}, {static_cast(tile_size.x), static_cast(tile_size.y)})); } -void TileAtlas::draw(sf::RenderTarget& target, const sf::RenderStates states) const +void TileAtlas::draw(sf::RenderTarget& target, sf::RenderStates states) const { - if (texture.getSize().x == 0 || texture.getSize().y == 0) - { - return; - } - target.draw(sprite, states); + // apply the transform + states.transform *= getTransform(); + + // apply the tileset texture + states.texture = &texture; + + // draw the vertex array + target.draw(vertices, states); } \ No newline at end of file diff --git a/src/Map/TileAtlas.hpp b/src/Map/TileAtlas.hpp index ee4663a..cbe08a4 100644 --- a/src/Map/TileAtlas.hpp +++ b/src/Map/TileAtlas.hpp @@ -1,12 +1,11 @@ #pragma once #include -class TileAtlas : public sf::Drawable +class TileAtlas : public sf::Drawable, public sf::Transformable { sf::Vector2u tile_size; sf::Vector2u tile_count; - sf::Texture texture; - sf::Sprite sprite; + public: explicit TileAtlas(sf::Vector2u tile_size, sf::Vector2u tile_count, const std::filesystem::path& path); TileAtlas(sf::Vector2u tile_size, sf::Vector2u tile_count); @@ -18,4 +17,7 @@ public: void set(uint32_t, uint32_t); void draw(sf::RenderTarget& target, sf::RenderStates states) const override; + +private: + }; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index c351104..dc17698 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,13 +3,29 @@ #include "Game.hpp" +#include int main() { sf::RenderWindow window(sf::VideoMode({800, 450}), "Colysis", sf::Style::Close | sf::Style::Titlebar); window.setMinimumSize(sf::Vector2u{800, 450}); - Game game(window); - game.run(); + try { + Game game(window); + game.run(); + } + catch (const std::runtime_error& e) + { + std::cerr << e.what() << std::endl; + } + catch (const std::exception& e) + { + std::cerr << e.what() << std::endl; + } + catch (...) + { + std::cerr << "Unknown error" << std::endl; + } + std::flush(std::cerr); return 0; } diff --git a/utils/MapFile.hexpat b/utils/MapFile.hexpat new file mode 100644 index 0000000..7711e85 --- /dev/null +++ b/utils/MapFile.hexpat @@ -0,0 +1,71 @@ +#pragma endian little + +struct Version { + u8 major; + u8 minor; + u8 patch; +}; + +bitfield OptionFlags { + bool CustomeTilemap : 1; +}; + + +struct TilemapInfo { +}; + +struct Options { + OptionFlags flags; + if (flags.CustomeTilemap) { + u32 filepath_length; + char filepath[filepath_length]; + TilemapInfo info; + } +}; + +struct SpecialData { + u32 data; +}; + +struct Tile { + u32 type; + if (type == 0) { + SpecialData special; + } +}[[single_color]]; + +struct Map +{ + u32 width; + u32 height; + u32 specials; + + Tile tiles[width * height]; +}; + +struct Spawn { + u32 x,y; +}[[single_color]]; + +struct EnemySpawns { + u32 count; + Spawn spawns[count]; +}; + +import std.io as io; + +char magic[4] @$; +if (magic != "CYMF") { + io::warning("Magic does not match: \"" + magic + "\"; Expected: \"CYMF\""); +} + +Version version @$ [[single_color]]; + +Options options @$; + + +Map map @$; + +Spawn player @$ [[single_color]]; + +EnemySpawns enemies @$; \ No newline at end of file