Switching to sfml

This commit is contained in:
n0ffie 2025-03-17 20:04:47 +01:00
parent 4536c62dad
commit de72aead56
40 changed files with 462 additions and 2385 deletions

162
src/Map/Map.cpp Normal file
View file

@ -0,0 +1,162 @@
#include "Map.hpp"
#include <fstream>
Map::Map() {}
bool operator&(uint8_t lhs, MapFlags rhs)
{
return lhs & static_cast<uint8_t>(rhs);
}
bool operator==(int lhs, TileType rhs)
{
return lhs == static_cast<int>(rhs);
}
auto operator<=>(int lhs, TileType rhs)
{
return lhs <=> static_cast<int>(rhs);
}
#include <iostream>
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);
if (std::memcmp(magic, "CYMF", 4) != 0) {
return {"Map: [Loading] Invalid magic number", 1};
}
// reading the version
uint8_t version[3];
file.read(reinterpret_cast<char*>(version), 3);
if (version[0] != MAP_VERSION_MAJOR || version[1] > MAP_VERSION_MINOR)
{
return {"Map: [Loading] Invalid version; Current: " MAP_VERSION_STRING, 1};
}
// reading the flags
uint8_t flags;
file.read(reinterpret_cast<char*>(&flags), 1);
// flag CustomTilemap -> load the tilemap
if (flags & MapFlags::CustomTilemap)
{
uint32_t filepath_buffer_size;
file.read(reinterpret_cast<char*>(&filepath_buffer_size), 4);
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;
}
// load the map info
uint32_t map_info[3];
file.read(reinterpret_cast<char*>(map_info), 12);
map_size = sf::Vector3<size_t>(static_cast<size_t>(map_info[0])*map_info[1], map_info[0], map_info[1]);
// load the tiles
tiles = new int[map_info[0] * map_info[1] + map_info[2] * (sizeof(MapSpecial)/4)];
for (int i = 0; i < map_info[0] * map_info[1] + map_info[2] * (sizeof(MapSpecial)/4); i++)
{
// read the special if needed
file.read(reinterpret_cast<char*>(&tiles[i]), 4);
if (tiles[i] == TileType::Special)
{
MapSpecial special{};
file.read(reinterpret_cast<char*>(&special), sizeof(MapSpecial));
// get position
uint32_t tile_x = i % map_info[0];
uint32_t tile_y = i / map_info[0];
specials.emplace_back(std::pair<sf::Vector2u, MapSpecial>({tile_x, tile_y}, special));
}
}
// load the player spawn
uint32_t t_player_spawn[2];
file.read(reinterpret_cast<char*>(t_player_spawn), 8);
player_spawn = sf::Vector2u{t_player_spawn[0], t_player_spawn[1]};
if (player_spawn.x >= map_size.y || player_spawn.y >= map_size.z)
{
return {"Map: [Loading] Player: Spawn out of bounds", 2};
}
int player_tile = tiles[player_spawn.x + player_spawn.y * map_size.x];
if (player_tile <= TileType::Special)
{
return {"Map: [Loading] Player: Spawn is not a valid tile (invalid: wall, special; valid: Floor)", 2};
}
// load all the enemy spawns
uint32_t number_enemy_spawns;
file.read(reinterpret_cast<char*>(&number_enemy_spawns), 4);
if (number_enemy_spawns > map_size.x)
{
return {"Map: [Loading] Enemies: Too many enemy spawns (More than tile in the map)", 3};
}
for (int i = 0; i < number_enemy_spawns; i++)
{
uint32_t t_enemy_spawn[2];
file.read(reinterpret_cast<char*>(t_enemy_spawn), 8);
if (t_enemy_spawn[0] >= map_size.x || t_enemy_spawn[1] >= map_size.y)
{
return {"Map: [Loading] Enemy: Spawn out of bounds", 4};
}
if (tiles[t_enemy_spawn[0] + t_enemy_spawn[1] * map_size.y] <= TileType::Special)
{
return {"Map: [Loading] Enemy: Spawn is not a valid tile (invalid: wall, special; valid: Floor)", 4};
}
if (t_enemy_spawn[0] == player_spawn.x && t_enemy_spawn[1] == player_spawn.y)
{
return {"Map: [Loading] Enemy: Spawn is the same as the player spawn", 4};
}
enemy_spawns.emplace_back(t_enemy_spawn[0], t_enemy_spawn[1]);
}
// Everything went well
return {"Map: [Loading] Success", 0};
}
sf::Vector2u Map::getSize() const
{
return {static_cast<uint32_t>(map_size.y), static_cast<uint32_t>(map_size.z)};
}
void Map::draw(sf::RenderTarget& target, const 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);
}
}
}
#include <iostream>
void Map::debug()
{
std::cout << "Map Debug" << std::endl;
std::cout << "\tSize : " << map_size.x << ", " << map_size.y << ", " << map_size.z << std::endl;
std::cout << "\tTiles : 0x" << tiles << std::endl;
for (auto& special : specials)
{
std::cout << "\t\tSpecial : " << special.first.x << ", " << special.first.y << std::endl;
std::cout << "\t\t\tType : " << special.second.type << std::endl;
std::cout << "\t\t\tPortal : " << special.second.portal_end[0] << ", " << special.second.portal_end[1] << std::endl;
}
std::cout << "\t\tEnemy Spawns : " << enemy_spawns.size() << std::endl;
for (auto& spawn : enemy_spawns)
{
std::cout << "\t\t\tSpawn : " << spawn.x << ", " << spawn.y << std::endl;
}
std::cout << "\t\tPlayer Spawn : " << player_spawn.x << ", " << player_spawn.y << std::endl;
}