Skip to content

Commit

Permalink
Cleaned up the tileset manager code
Browse files Browse the repository at this point in the history
  • Loading branch information
mmatyas committed Apr 8, 2024
1 parent 762858b commit 18a0d9e
Show file tree
Hide file tree
Showing 12 changed files with 199 additions and 216 deletions.
2 changes: 1 addition & 1 deletion src/common/ResourceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ bool CResourceManager::LoadGameGraphics()
{
const char * graphicspack = gamegraphicspacklist->current_name();

g_tilesetmanager->Init(graphicspack);
g_tilesetmanager->init(graphicspack);

bool loadok = true;
loadok &= game_font_small.init(convertPath("gfx/packs/fonts/font_small.png", graphicspack));
Expand Down
241 changes: 114 additions & 127 deletions src/common/TilesetManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <cassert>
#include <cstdio>
#include <cstring>
#include <memory>

#if defined(__APPLE__)
#include <sys/stat.h>
Expand Down Expand Up @@ -114,7 +115,7 @@ void CTileset::Draw(SDL_Surface* dstSurface, short tileSize, SDL_Rect* srcRect,
}


void CTileset::SaveTileset()
void CTileset::saveTileset() const
{
BinaryFile tsf(m_tilesetPath.c_str(), "wb");
if (!tsf.is_open()) {
Expand All @@ -137,165 +138,151 @@ void CTileset::SaveTileset()
* CTilesetManager
*********************************/

CTilesetManager::CTilesetManager() :
SimpleDirectoryList(convertPath("gfx/packs/Classic/tilesets/"))
CTilesetManager::CTilesetManager()
: SimpleDirectoryList(convertPath("gfx/packs/Classic/tilesets/"))
{}

CTilesetManager::~CTilesetManager()
{}

void CTilesetManager::Init(const char * szGfxPack)
void CTilesetManager::init(const std::string& gfxPack)
{
//Remove all existing tilesets
std::vector<CTileset*>::iterator iter = tilesetlist.begin(), lim = tilesetlist.end();
while (iter != lim) {
delete (*iter);

iter = tilesetlist.erase(iter);
lim = tilesetlist.end();
}

//Add in tilesets from the new gfxpack (if the gfxpack isn't "Classic")
if (strcmp(getFileFromPath(szGfxPack).c_str(), "Classic")) {
std::string s = convertPath("gfx/packs/tilesets", szGfxPack) + '/';
SimpleDirectoryList dirlist(s);

short iLength = dirlist.GetCount();
for (short i = 0; i < iLength; i++) {
CTileset * tileset = new CTileset(dirlist.current_name());
tilesetlist.push_back(tileset);

//If the tileset is "classic" then keep it's index for common operations
if (tileset->name() == "Classic") {
tClassicTileset = tileset;
iClassicTilesetIndex = i;
}

dirlist.next();
}
}

//Add in tilesets from the classic tileset to fill the gaps
short iLength = filelist.size();
char szTilesetName[128];
for (short i = 0; i < iLength; i++) {
strncpy(szTilesetName, getFileFromPath(filelist[i]).c_str(), 128);
szTilesetName[127] = 0;

//See if the new tileset already exists and if it does, skip it
short iTilesetSize = tilesetlist.size();
bool fFound = false;
for (short iTileset = 0; iTileset < iTilesetSize; iTileset++) {
if (tilesetlist[iTileset]->name() == szTilesetName) {
fFound = true;
break;
}
}

//Add the tileset if another one by the same name isn't already in the tileset
if (!fFound) {
CTileset * tileset = new CTileset(filelist[i].c_str());
tilesetlist.push_back(tileset);
//Remove all existing tilesets
m_tilesetlist.clear();

//Add in tilesets from the new gfxpack (if the gfxpack isn't "Classic")
if (getFileFromPath(gfxPack) != "Classic") {
std::string s = convertPath("gfx/packs/tilesets", gfxPack) + '/';
SimpleDirectoryList dirlist(s);

for (short i = 0; i < dirlist.GetCount(); i++) {
std::unique_ptr<CTileset> tileset = std::make_unique<CTileset>(dirlist.current_name());

//If the tileset is "classic" then keep it's index for common operations
if (tileset->name() == "Classic")
m_classicTilesetIndex = i;

m_tilesetlist.emplace_back(std::move(tileset));
dirlist.next();
}
}

if (tileset->name() == "Classic") {
tClassicTileset = tileset;
iClassicTilesetIndex = i;
}
}
}
//Add in tilesets from the classic tileset to fill the gaps
for (size_t i = 0; i < filelist.size(); i++) {
const std::string tilesetName = getFileFromPath(filelist[i]);

InitTilesetRects();
//See if the new tileset already exists and if it does, skip it
bool fFound = false;
for (size_t iTileset = 0; iTileset < m_tilesetlist.size(); iTileset++) {
if (m_tilesetlist[iTileset]->name() == tilesetName) {
fFound = true;
break;
}
}

//Add the tileset if another one by the same name isn't already in the tileset
if (!fFound) {
std::unique_ptr<CTileset> tileset = std::make_unique<CTileset>(filelist[i]);
if (tileset->name() == "Classic") {
m_classicTilesetIndex = i;
}
m_tilesetlist.emplace_back(std::move(tileset));
}
}

initTilesetRects();
}

void CTilesetManager::InitTilesetRects()

void CTilesetManager::initTilesetRects()
{
size_t max_tileset_rows = 0;
for (CTileset* tileset : tilesetlist) {
max_tileset_rows = std::max<size_t>(max_tileset_rows, tileset->height());
max_tileset_cols = std::max<size_t>(max_tileset_cols, tileset->width());
}

const size_t tile_count = max_tileset_rows * max_tileset_cols;
rects_ingame.reserve(tile_count);
rects_preview.reserve(tile_count);
rects_thumb.reserve(tile_count);

short y1 = 0, y2 = 0, y3 = 0;
for (size_t row = 0; row < max_tileset_rows; row++) {
short x1 = 0, x2 = 0, x3 = 0;
for (size_t col = 0; col < max_tileset_cols; col++) {
rects_ingame.emplace_back(SDL_Rect { x1, y1, TILESIZE, TILESIZE });
rects_preview.emplace_back(SDL_Rect { x2, y2, PREVIEWTILESIZE, PREVIEWTILESIZE });
rects_thumb.emplace_back(SDL_Rect { x3, y3, THUMBTILESIZE, THUMBTILESIZE });

x1 += TILESIZE;
x2 += PREVIEWTILESIZE;
x3 += THUMBTILESIZE;
}

y1 += TILESIZE;
y2 += PREVIEWTILESIZE;
y3 += THUMBTILESIZE;
}
size_t max_tileset_rows = 0;
for (const std::unique_ptr<CTileset>& tileset : m_tilesetlist) {
max_tileset_rows = std::max<size_t>(max_tileset_rows, tileset->height());
m_max_tileset_cols = std::max<size_t>(m_max_tileset_cols, tileset->width());
}

const size_t tile_count = max_tileset_rows * m_max_tileset_cols;
m_rects_ingame.reserve(tile_count);
m_rects_preview.reserve(tile_count);
m_rects_thumb.reserve(tile_count);

short y1 = 0, y2 = 0, y3 = 0;
for (size_t row = 0; row < max_tileset_rows; row++) {
short x1 = 0, x2 = 0, x3 = 0;
for (size_t col = 0; col < m_max_tileset_cols; col++) {
m_rects_ingame.emplace_back(SDL_Rect { x1, y1, TILESIZE, TILESIZE });
m_rects_preview.emplace_back(SDL_Rect { x2, y2, PREVIEWTILESIZE, PREVIEWTILESIZE });
m_rects_thumb.emplace_back(SDL_Rect { x3, y3, THUMBTILESIZE, THUMBTILESIZE });

x1 += TILESIZE;
x2 += PREVIEWTILESIZE;
x3 += THUMBTILESIZE;
}

y1 += TILESIZE;
y2 += PREVIEWTILESIZE;
y3 += THUMBTILESIZE;
}
}

short CTilesetManager::GetIndexFromName(const char * szName)

size_t CTilesetManager::indexFromName(const std::string& name) const
{
for (size_t i = 0; i < tilesetlist.size(); i++) {
if (tilesetlist[i]->name() == szName)
for (size_t i = 0; i < m_tilesetlist.size(); i++) {
if (m_tilesetlist[i]->name() == name)
return i;
}

return TILESETUNKNOWN;
}


void CTilesetManager::Draw(SDL_Surface * dstSurface, short iTilesetID, short iTileSize, short iSrcTileCol, short iSrcTileRow, short iDstTileCol, short iDstTileRow)
{
assert(0 <= iTilesetID && static_cast<size_t>(iTilesetID) < tilesetlist.size());
assert(iSrcTileCol >= 0 && iSrcTileRow >= 0);
assert(iDstTileCol >= 0 && iDstTileRow >= 0);
assert(0 <= iTilesetID && static_cast<size_t>(iTilesetID) < m_tilesetlist.size());
assert(iSrcTileCol >= 0 && iSrcTileRow >= 0);
assert(iDstTileCol >= 0 && iDstTileRow >= 0);

const size_t src_rect_idx = iSrcTileRow * max_tileset_cols + iSrcTileCol;
const size_t dst_rect_idx = iDstTileRow * max_tileset_cols + iDstTileCol;
const size_t src_rect_idx = iSrcTileRow * m_max_tileset_cols + iSrcTileCol;
const size_t dst_rect_idx = iDstTileRow * m_max_tileset_cols + iDstTileCol;

SDL_Rect* src_rect = GetRect(iTileSize, src_rect_idx);
SDL_Rect* dst_rect = GetRect(iTileSize, dst_rect_idx);
SDL_Rect* src_rect = rect(iTileSize, src_rect_idx);
SDL_Rect* dst_rect = rect(iTileSize, dst_rect_idx);

tilesetlist[iTilesetID]->Draw(dstSurface, iTileSize, src_rect, dst_rect);
m_tilesetlist[iTilesetID]->Draw(dstSurface, iTileSize, src_rect, dst_rect);
}

CTileset * CTilesetManager::GetTileset(short iTilesetID)
{
if (iTilesetID < 0 || iTilesetID >= (short)tilesetlist.size())
return NULL;

return tilesetlist[iTilesetID];
CTileset* CTilesetManager::tileset(size_t index)
{
return index < m_tilesetlist.size()
? m_tilesetlist[index].get()
: nullptr;
}

SDL_Rect* CTilesetManager::GetRect(short size_id, short col, short row)

SDL_Rect* CTilesetManager::rect(short size_id, short col, short row)
{
const size_t rect_idx = row * max_tileset_cols + col;
return GetRect(size_id, rect_idx);
const size_t rect_idx = row * m_max_tileset_cols + col;
return rect(size_id, rect_idx);
}

SDL_Rect* CTilesetManager::GetRect(short size_id, size_t idx)

SDL_Rect* CTilesetManager::rect(short size_id, size_t idx)
{
assert(0 <= size_id && size_id < 3);
assert(idx < rects_ingame.size());

switch (size_id) {
case 0: return &rects_ingame[idx];
case 1: return &rects_preview[idx];
case 2: return &rects_thumb[idx];
default: return nullptr;
}
assert(0 <= size_id && size_id < 3);
assert(idx < m_rects_ingame.size());

switch (size_id) {
case 0: return &m_rects_ingame[idx];
case 1: return &m_rects_preview[idx];
case 2: return &m_rects_thumb[idx];
default: return nullptr;
}
}

void CTilesetManager::SaveTilesets()
{
short iLength = tilesetlist.size();

for (short i = 0; i < iLength; i++) {
tilesetlist[i]->SaveTileset();
}
void CTilesetManager::saveTilesets() const
{
for (const std::unique_ptr<CTileset>& tileset : m_tilesetlist)
tileset->saveTileset();
}
58 changes: 27 additions & 31 deletions src/common/TilesetManager.h
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
#ifndef TILESETMANAGER_H
#define TILESETMANAGER_H
#pragma once

#include "FileList.h"
#include "gfx/gfxSprite.h"
#include "map.h"

#include <array>
#include <memory>
#include <vector>


class CTileset {
public:
CTileset(const std::string& dir);

void SaveTileset();
void saveTileset() const;

TileType tileType(size_t iTileCol, size_t iTileRow) const;
void setTileType(size_t iTileCol, size_t iTileRow, TileType type);
Expand All @@ -39,41 +39,37 @@ class CTileset {


//it was kinda a bad idea to have skinlist and announcer list based on this, because both are accessed in different ways (skinlist like an vector and announcer list like a list). grrrr
class CTilesetManager : public SimpleDirectoryList
{
public:
CTilesetManager();
virtual ~CTilesetManager();
void Init(const char * szGfxPack);
class CTilesetManager : public SimpleDirectoryList {
public:
CTilesetManager();

void init(const std::string& gfxPack);

short GetIndexFromName(const char * szName);
size_t indexFromName(const std::string& name) const;

void Draw(SDL_Surface * dstSurface, short iTilesetID, short iTileSize, short iSrcTileCol, short iSrcTileRow, short iDstTileCol, short iDstTileRow);
void Draw(SDL_Surface * dstSurface, short iTilesetID, short iTileSize, short iSrcTileCol, short iSrcTileRow, short iDstTileCol, short iDstTileRow);

void SaveTilesets();
void saveTilesets() const;

CTileset * GetClassicTileset() {
return tClassicTileset;
size_t classicTilesetIndex() const {
return m_classicTilesetIndex;
}
short GetClassicTilesetIndex() {
return iClassicTilesetIndex;
const CTileset& classicTileset() const {
return *m_tilesetlist.at(classicTilesetIndex());
}

CTileset * GetTileset(short iID);
SDL_Rect* GetRect(short size_id, short col, short row);
SDL_Rect* GetRect(short size_id, size_t idx);
CTileset* tileset(size_t index);
SDL_Rect* rect(short size_id, short col, short row);
SDL_Rect* rect(short size_id, size_t idx);

private:
std::vector<CTileset*> tilesetlist;
CTileset* tClassicTileset = nullptr;
short iClassicTilesetIndex;
private:
std::vector<std::unique_ptr<CTileset>> m_tilesetlist; // TODO: Store objects
size_t m_classicTilesetIndex = SIZE_MAX;

std::vector<SDL_Rect> rects_ingame;
std::vector<SDL_Rect> rects_preview;
std::vector<SDL_Rect> rects_thumb;
size_t max_tileset_cols = 0;
std::vector<SDL_Rect> m_rects_ingame;
std::vector<SDL_Rect> m_rects_preview;
std::vector<SDL_Rect> m_rects_thumb;
size_t m_max_tileset_cols = 0;

void InitTilesetRects();
void initTilesetRects();
};

#endif // TILESETMANAGER_H
Loading

0 comments on commit 18a0d9e

Please sign in to comment.