Added Map Rendering

This commit is contained in:
n0ffie 2025-03-18 23:00:42 +01:00
parent 37a249dc62
commit ea72294a3e
8 changed files with 114 additions and 97 deletions

View file

@ -24,28 +24,85 @@ auto operator<=>(int lhs, TileType 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);
atlas.vertices.setPrimitiveType(sf::PrimitiveType::Triangles);
atlas.vertices.resize(map_size.x * map_size.y * 6);
for (uint32_t x = 0; x < map_size.x; x++) {
for (uint32_t y = 0; y < map_size.y; ++y)
const auto xw = static_cast<float>(atlas.tile_size.x);
const auto yw = static_cast<float>(atlas.tile_size.y);
const auto tex_w = static_cast<float>(atlas.tile_size.x);
const auto tex_h = static_cast<float>(atlas.tile_size.y);
for (uint32_t x = 0; x < map_size.y; x++) {
for (uint32_t y = 0; y < map_size.z; y++)
{
uint32_t tile = tiles[x + y * map_size.y];
const int32_t tile = tiles[x + y * map_size.y];
if (tile < -atlas.wall_tiles || tile > atlas.other_tiles) return {"Map: [Loading] Invalid tile! Tile type does not have a texture; ID: " + std::to_string(tile), 3};
// map tile type to atlas
/*
* -----
* --#++
* +++++
* Atlas:
* +++++
* +++--
* ---##
*
* + = other
* - = wall
* # = special
* + = wall
* # = special
* - = other
*
* wall_tiles = 8
* other_tiles = 5
* special_tiles = 2
*
* Tile:
* -1 <= wall
* 0 == special @ .type == tile_type
* 1 >= other
*/
if (tile == 0) return {"Map: [Loading] [Not Implemented!] Tile is a special tile", 3};
// atlas tile index
const uint32_t atlas_tile = atlas.wall_tiles + (tile - 1);
if (atlas_tile >= atlas.wall_tiles + atlas.other_tiles) return {"Map: [Loading] Invalid tile! Tile type does not have a texture", 3};
// add the vertices
const auto xf = static_cast<float>(x);
const auto yf = static_cast<float>(y);
const uint32_t tile_x = atlas_tile % atlas.tile_count.x;
const uint32_t tile_y = atlas_tile / atlas.tile_count.x;
const auto tex_x = static_cast<float>(tile_x * atlas.tile_size.x);
const auto tex_y = static_cast<float>(tile_y * atlas.tile_size.y);
sf::Vertex tl = {{xf, yf}, sf::Color::White, {tex_x, tex_y}};
sf::Vertex tr = {{xf + xw, yf}, sf::Color::White, {tex_x + tex_w, tex_y}};
sf::Vertex bl = {{xf, yf + yw}, sf::Color::White, {tex_x, tex_y + tex_h}};
sf::Vertex br = {{xf + xw, yf + yw}, sf::Color::White, {tex_x + tex_w, tex_y + tex_h}};
atlas.vertices.append(tl);
atlas.vertices.append(tr);
atlas.vertices.append(bl);
atlas.vertices.append(bl);
atlas.vertices.append(tr);
atlas.vertices.append(br);
}
}
return {"Map: [Loading] Success", 0};
}
Map::Map() {}
void Map::LoadDefaultTilemap() {
atlas.wall_tiles = 0;
atlas.other_tiles = 1;
atlas.special_tiles = 0;
atlas.tile_count = {1, 1};
atlas.tile_size = {16, 16};
if (!atlas.texture.loadFromFile(ASSETS_PATH "/default_tilemap.png")) {
throw std::runtime_error("Map: [Loading] Could not load default tilemap -> Fatal");
}
}
Map::Map(): atlas() {
}
#include <iostream>
@ -57,11 +114,16 @@ 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);
uint32_t magic;
file.read(reinterpret_cast<char*>(&magic), 4);
if (std::memcmp(&magic, "CYMF", 4) != 0) {
return {"Map: [Loading] Invalid magic number: " + std::string(reinterpret_cast<const char *>(&magic), 4) + " (expected CYMF)", 1};
if (!file.is_open()) {
return {"Map: [Loading] Could not open file: " + path.string(), 1};
}
char magic[4];
file.read(magic, 4);
if (std::memcmp(magic, "CYMF", 4) != 0) {
return {"Map: [Loading] Invalid magic number: " + std::string(magic, 4) + " (expected CYMF)", 1};
}
// reading the version
@ -85,9 +147,13 @@ MapError Map::load(const std::filesystem::path& path)
char* filepath_buffer = new char[filepath_buffer_size];
file.read(filepath_buffer, filepath_buffer_size);
return {"Map: [Loading] [Not Implemented] Custom Tilemap is not implemented. Tilemap file: " + std::string(filepath_buffer, filepath_buffer_size), 1};
delete[] filepath_buffer;
}
else {
LoadDefaultTilemap();
}
// load the map info
@ -96,8 +162,8 @@ MapError Map::load(const std::filesystem::path& path)
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++)
tiles = new int[map_info[0] * map_info[1]];
for (int i = 0; i < map_info[0] * map_info[1]; i++)
{
// read the special if needed
file.read(reinterpret_cast<char*>(&tiles[i]), 4);
@ -153,7 +219,7 @@ MapError Map::load(const std::filesystem::path& path)
}
// Everything went well
return {"Map: [Loading] Success", 0};
return populate_vertex_array();
}
sf::Vector2u Map::getSize() const
@ -169,10 +235,10 @@ void Map::draw(sf::RenderTarget& target, sf::RenderStates states) const
states.transform *= getTransform();
// apply the tileset texture
states.texture = &texture;
states.texture = &atlas.texture;
// draw the vertex array
target.draw(vertices, states);
target.draw(atlas.vertices, states);
}
@ -181,7 +247,7 @@ 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;
std::cout << "\tTiles : " << tiles << std::endl;
for (auto& special : specials)
{
std::cout << "\t\tSpecial : " << special.first.x << ", " << special.first.y << std::endl;