| @@ -4,7 +4,7 @@ noinst_PROGRAMS = test-map editor | |||||
| noinst_LIBRARIES = libcommon.a | noinst_LIBRARIES = libcommon.a | ||||
| libcommon_a_SOURCES = \ | libcommon_a_SOURCES = \ | ||||
| core.h matrix.h game.cpp game.h tiler.cpp tiler.h \ | |||||
| core.h matrix.h game.cpp game.h tiler.cpp tiler.h dict.cpp dict.h \ | |||||
| scene.cpp scene.h font.cpp font.h layer.cpp layer.h map.cpp map.h \ | scene.cpp scene.h font.cpp font.h layer.cpp layer.h map.cpp map.h \ | ||||
| entity.cpp entity.h ticker.cpp ticker.h tileset.cpp tileset.h \ | entity.cpp entity.h ticker.cpp ticker.h tileset.cpp tileset.h \ | ||||
| forge.cpp forge.h video.cpp video.h timer.cpp timer.h bitfield.h \ | forge.cpp forge.h video.cpp video.h timer.cpp timer.h bitfield.h \ | ||||
| @@ -28,6 +28,7 @@ | |||||
| #include "tileset.h" | #include "tileset.h" | ||||
| // Other objects | // Other objects | ||||
| #include "dict.h" | |||||
| #include "map.h" | #include "map.h" | ||||
| #include "layer.h" | #include "layer.h" | ||||
| @@ -21,7 +21,7 @@ class DebugFpsData | |||||
| friend class DebugFps; | friend class DebugFps; | ||||
| private: | private: | ||||
| Font *font; | |||||
| int fontid; | |||||
| int frame; | int frame; | ||||
| }; | }; | ||||
| @@ -33,7 +33,7 @@ DebugFps::DebugFps() | |||||
| { | { | ||||
| data = new DebugFpsData(); | data = new DebugFpsData(); | ||||
| data->font = Forge::GetFont("gfx/font/ascii.png"); | |||||
| data->fontid = Forge::Register("gfx/font/ascii.png"); | |||||
| data->frame = 0; | data->frame = 0; | ||||
| } | } | ||||
| @@ -49,35 +49,36 @@ void DebugFps::TickRender(float deltams) | |||||
| data->frame++; | data->frame++; | ||||
| char buf[1024]; | char buf[1024]; | ||||
| Font *font = Forge::GetFont(data->fontid); | |||||
| sprintf(buf, "%2.2f fps (%i)", | sprintf(buf, "%2.2f fps (%i)", | ||||
| 1e3f / Profiler::GetMean(Profiler::STAT_TICK_FRAME), data->frame); | 1e3f / Profiler::GetMean(Profiler::STAT_TICK_FRAME), data->frame); | ||||
| data->font->PrintBold(10, 10, buf); | |||||
| font->PrintBold(10, 10, buf); | |||||
| sprintf(buf, "Game % 7.2f % 7.2f", | sprintf(buf, "Game % 7.2f % 7.2f", | ||||
| Profiler::GetMean(Profiler::STAT_TICK_GAME), | Profiler::GetMean(Profiler::STAT_TICK_GAME), | ||||
| Profiler::GetMax(Profiler::STAT_TICK_GAME)); | Profiler::GetMax(Profiler::STAT_TICK_GAME)); | ||||
| data->font->PrintBold(10, 34, buf); | |||||
| font->PrintBold(10, 34, buf); | |||||
| sprintf(buf, "Render % 7.2f % 7.2f", | sprintf(buf, "Render % 7.2f % 7.2f", | ||||
| Profiler::GetMean(Profiler::STAT_TICK_RENDER), | Profiler::GetMean(Profiler::STAT_TICK_RENDER), | ||||
| Profiler::GetMax(Profiler::STAT_TICK_RENDER)); | Profiler::GetMax(Profiler::STAT_TICK_RENDER)); | ||||
| data->font->PrintBold(10, 50, buf); | |||||
| font->PrintBold(10, 50, buf); | |||||
| sprintf(buf, "Blit % 7.2f % 7.2f", | sprintf(buf, "Blit % 7.2f % 7.2f", | ||||
| Profiler::GetMean(Profiler::STAT_TICK_BLIT), | Profiler::GetMean(Profiler::STAT_TICK_BLIT), | ||||
| Profiler::GetMax(Profiler::STAT_TICK_BLIT)); | Profiler::GetMax(Profiler::STAT_TICK_BLIT)); | ||||
| data->font->PrintBold(10, 66, buf); | |||||
| font->PrintBold(10, 66, buf); | |||||
| sprintf(buf, "Frame % 7.2f % 7.2f", | sprintf(buf, "Frame % 7.2f % 7.2f", | ||||
| Profiler::GetMean(Profiler::STAT_TICK_FRAME), | Profiler::GetMean(Profiler::STAT_TICK_FRAME), | ||||
| Profiler::GetMax(Profiler::STAT_TICK_FRAME)); | Profiler::GetMax(Profiler::STAT_TICK_FRAME)); | ||||
| data->font->PrintBold(10, 82, buf); | |||||
| font->PrintBold(10, 82, buf); | |||||
| } | } | ||||
| DebugFps::~DebugFps() | DebugFps::~DebugFps() | ||||
| { | { | ||||
| Forge::ReleaseFont(data->font); | |||||
| Forge::Deregister(data->fontid); | |||||
| delete data; | delete data; | ||||
| } | } | ||||
| @@ -0,0 +1,111 @@ | |||||
| // | |||||
| // Deus Hax (working title) | |||||
| // Copyright (c) 2010 Sam Hocevar <sam@hocevar.net> | |||||
| // | |||||
| #if defined HAVE_CONFIG_H | |||||
| # include "config.h" | |||||
| #endif | |||||
| #include <cstring> | |||||
| #include <cstdio> | |||||
| #include <cstdlib> | |||||
| #include "core.h" | |||||
| /* | |||||
| * Dict implementation class | |||||
| */ | |||||
| class DictData | |||||
| { | |||||
| friend class Dict; | |||||
| public: | |||||
| DictData() : | |||||
| entities(0), | |||||
| nentities(0) | |||||
| { | |||||
| /* Nothing to do */ | |||||
| } | |||||
| ~DictData() | |||||
| { | |||||
| if (nentities) | |||||
| fprintf(stderr, "ERROR: still %i entities in dict\n", nentities); | |||||
| free(entities); | |||||
| } | |||||
| private: | |||||
| Entity **entities; | |||||
| int nentities; | |||||
| }; | |||||
| /* | |||||
| * Public Dict class | |||||
| */ | |||||
| Dict::Dict() | |||||
| { | |||||
| data = new DictData(); | |||||
| } | |||||
| Dict::~Dict() | |||||
| { | |||||
| delete data; | |||||
| } | |||||
| int Dict::MakeSlot(char const *name) | |||||
| { | |||||
| int id, empty = -1; | |||||
| /* If the entry is already registered, remember its ID. Look for an | |||||
| * empty slot at the same time. */ | |||||
| for (id = 0; id < data->nentities; id++) | |||||
| { | |||||
| Entity *e = data->entities[id]; | |||||
| if (!e) | |||||
| empty = id; | |||||
| else if (!strcasecmp(name, e->GetName())) | |||||
| break; | |||||
| } | |||||
| /* If this is a new entry, create a new slot for it. */ | |||||
| if (id == data->nentities) | |||||
| { | |||||
| if (empty == -1) | |||||
| { | |||||
| empty = data->nentities++; | |||||
| data->entities = (Entity **)realloc(data->entities, | |||||
| data->nentities * sizeof(Entity *)); | |||||
| } | |||||
| data->entities[empty] = NULL; | |||||
| id = empty; | |||||
| } | |||||
| else | |||||
| { | |||||
| data->entities[id]->Ref(); | |||||
| } | |||||
| return id; | |||||
| } | |||||
| void Dict::RemoveSlot(int id) | |||||
| { | |||||
| if (data->entities[id]->Unref() == 0) | |||||
| data->entities[id] = NULL; | |||||
| } | |||||
| void Dict::SetEntity(int id, Entity *entity) | |||||
| { | |||||
| entity->Ref(); | |||||
| data->entities[id] = entity; | |||||
| } | |||||
| Entity *Dict::GetEntity(int id) | |||||
| { | |||||
| return data->entities[id]; | |||||
| } | |||||
| @@ -0,0 +1,35 @@ | |||||
| // | |||||
| // Deus Hax (working title) | |||||
| // Copyright (c) 2010 Sam Hocevar <sam@hocevar.net> | |||||
| // | |||||
| // | |||||
| // The Dict class | |||||
| // -------------- | |||||
| // | |||||
| #if !defined __DH_DICT_H__ | |||||
| #define __DH_DICT_H__ | |||||
| #include "entity.h" | |||||
| class DictData; | |||||
| class Dict | |||||
| { | |||||
| public: | |||||
| Dict(); | |||||
| ~Dict(); | |||||
| int MakeSlot(char const *name); | |||||
| void RemoveSlot(int id); | |||||
| void SetEntity(int id, Entity *entity); | |||||
| Entity *GetEntity(int id); | |||||
| private: | |||||
| DictData *data; | |||||
| }; | |||||
| #endif // __DH_DICT_H__ | |||||
| @@ -35,6 +35,11 @@ Entity::~Entity() | |||||
| #endif | #endif | ||||
| } | } | ||||
| char const *Entity::GetName() | |||||
| { | |||||
| return "Generic entity"; | |||||
| } | |||||
| Entity::Group Entity::GetGroup() | Entity::Group Entity::GetGroup() | ||||
| { | { | ||||
| return GROUP_DEFAULT; | return GROUP_DEFAULT; | ||||
| @@ -20,6 +20,7 @@ class Entity | |||||
| { | { | ||||
| friend class Ticker; | friend class Ticker; | ||||
| friend class TickerData; | friend class TickerData; | ||||
| friend class Dict; | |||||
| public: | public: | ||||
| virtual void Ref(); | virtual void Ref(); | ||||
| @@ -40,6 +41,7 @@ protected: | |||||
| Entity(); | Entity(); | ||||
| virtual ~Entity(); | virtual ~Entity(); | ||||
| virtual char const *GetName(); | |||||
| virtual Group GetGroup(); | virtual Group GetGroup(); | ||||
| virtual void TickGame(float deltams); | virtual void TickGame(float deltams); | ||||
| @@ -23,13 +23,12 @@ public: | |||||
| protected: | protected: | ||||
| /* Inherited from Entity */ | /* Inherited from Entity */ | ||||
| virtual char const *GetName(); | |||||
| virtual Group GetGroup(); | virtual Group GetGroup(); | ||||
| virtual void TickRender(float deltams); | virtual void TickRender(float deltams); | ||||
| public: | public: | ||||
| /* New methods */ | /* New methods */ | ||||
| char const *GetName(); | |||||
| void Print(int x, int y, char const *str); | void Print(int x, int y, char const *str); | ||||
| void PrintBold(int x, int y, char const *str); | void PrintBold(int x, int y, char const *str); | ||||
| @@ -7,10 +7,6 @@ | |||||
| # include "config.h" | # include "config.h" | ||||
| #endif | #endif | ||||
| #include <cstring> | |||||
| #include <cstdio> | |||||
| #include <cstdlib> | |||||
| #include "core.h" | #include "core.h" | ||||
| #if defined WIN32 | #if defined WIN32 | ||||
| @@ -26,23 +22,7 @@ static class ForgeData | |||||
| friend class Forge; | friend class Forge; | ||||
| public: | public: | ||||
| ForgeData() : | |||||
| fonts(0), | |||||
| nfonts(0) | |||||
| { | |||||
| /* Nothing to do */ | |||||
| } | |||||
| ~ForgeData() | |||||
| { | |||||
| if (nfonts) | |||||
| fprintf(stderr, "ERROR: still %i fonts in forge\n", nfonts); | |||||
| free(fonts); | |||||
| } | |||||
| private: | |||||
| Font **fonts; | |||||
| int nfonts; | |||||
| Dict fonts; | |||||
| } | } | ||||
| forgedata; | forgedata; | ||||
| @@ -52,47 +32,26 @@ static ForgeData * const data = &forgedata; | |||||
| * Public Forge class | * Public Forge class | ||||
| */ | */ | ||||
| Font *Forge::GetFont(char const *path) | |||||
| int Forge::Register(char const *path) | |||||
| { | { | ||||
| int id, empty = -1; | |||||
| int id = data->fonts.MakeSlot(path); | |||||
| /* If the font is already registered, remember its ID. Look for an | |||||
| * empty slot at the same time. */ | |||||
| for (id = 0; id < data->nfonts; id++) | |||||
| if (!data->fonts.GetEntity(id)) | |||||
| { | { | ||||
| Font *t = data->fonts[id]; | |||||
| if (!t) | |||||
| empty = id; | |||||
| else if (!strcasecmp(path, t->GetName())) | |||||
| break; | |||||
| Font *font = new Font(path); | |||||
| data->fonts.SetEntity(id, font); | |||||
| } | } | ||||
| /* If this is a new font, create a new one. */ | |||||
| if (id == data->nfonts) | |||||
| { | |||||
| if (empty == -1) | |||||
| { | |||||
| empty = data->nfonts++; | |||||
| data->fonts = (Font **)realloc(data->fonts, | |||||
| data->nfonts * sizeof(Font *)); | |||||
| } | |||||
| data->fonts[empty] = new Font(path); | |||||
| id = empty; | |||||
| } | |||||
| return id; | |||||
| } | |||||
| data->fonts[id]->Ref(); | |||||
| return data->fonts[id]; | |||||
| void Forge::Deregister(int id) | |||||
| { | |||||
| data->fonts.RemoveSlot(id); | |||||
| } | } | ||||
| void Forge::ReleaseFont(Font *font) | |||||
| Font *Forge::GetFont(int id) | |||||
| { | { | ||||
| if (font->Unref() == 0) | |||||
| for (int id = 0; id < data->nfonts; id++) | |||||
| if (font == data->fonts[id]) | |||||
| { | |||||
| data->fonts[id] = NULL; | |||||
| break; | |||||
| } | |||||
| return (Font *)data->fonts.GetEntity(id); | |||||
| } | } | ||||
| @@ -17,8 +17,9 @@ | |||||
| class Forge | class Forge | ||||
| { | { | ||||
| public: | public: | ||||
| static Font *GetFont(char const *path); | |||||
| static void ReleaseFont(Font *font); | |||||
| static int Register(char const *path); | |||||
| static void Deregister(int id); | |||||
| static Font *GetFont(int id); | |||||
| }; | }; | ||||
| #endif // __DH_FORGE_H__ | #endif // __DH_FORGE_H__ | ||||
| @@ -7,10 +7,6 @@ | |||||
| # include "config.h" | # include "config.h" | ||||
| #endif | #endif | ||||
| #include <cstring> | |||||
| #include <cstdio> | |||||
| #include <cstdlib> | |||||
| #include "core.h" | #include "core.h" | ||||
| #if defined WIN32 | #if defined WIN32 | ||||
| @@ -26,23 +22,7 @@ static class TilerData | |||||
| friend class Tiler; | friend class Tiler; | ||||
| public: | public: | ||||
| TilerData() : | |||||
| tilesets(0), | |||||
| ntilesets(0) | |||||
| { | |||||
| /* Nothing to do */ | |||||
| } | |||||
| ~TilerData() | |||||
| { | |||||
| if (ntilesets) | |||||
| fprintf(stderr, "ERROR: still %i tilesets in tiler\n", ntilesets); | |||||
| free(tilesets); | |||||
| } | |||||
| private: | |||||
| TileSet **tilesets; | |||||
| int ntilesets; | |||||
| Dict tilesets; | |||||
| } | } | ||||
| tilerdata; | tilerdata; | ||||
| @@ -54,49 +34,27 @@ static TilerData * const data = &tilerdata; | |||||
| int Tiler::Register(char const *path) | int Tiler::Register(char const *path) | ||||
| { | { | ||||
| int id, empty = -1; | |||||
| /* If the tileset is already registered, remember its ID. Look for an | |||||
| * empty slot at the same time. */ | |||||
| for (id = 0; id < data->ntilesets; id++) | |||||
| { | |||||
| TileSet *t = data->tilesets[id]; | |||||
| if (!t) | |||||
| empty = id; | |||||
| else if (!strcasecmp(path, t->GetName())) | |||||
| break; | |||||
| } | |||||
| int id = data->tilesets.MakeSlot(path); | |||||
| /* If this is a new tileset, create a new one. */ | |||||
| if (id == data->ntilesets) | |||||
| if (!data->tilesets.GetEntity(id)) | |||||
| { | { | ||||
| if (empty == -1) | |||||
| { | |||||
| empty = data->ntilesets++; | |||||
| data->tilesets = (TileSet **)realloc(data->tilesets, | |||||
| data->ntilesets * sizeof(TileSet *)); | |||||
| } | |||||
| data->tilesets[empty] = new TileSet(path); | |||||
| id = empty; | |||||
| TileSet *tileset = new TileSet(path); | |||||
| data->tilesets.SetEntity(id, tileset); | |||||
| } | } | ||||
| data->tilesets[id]->Ref(); | |||||
| return id + 1; /* ID 0 is for the empty tileset */ | return id + 1; /* ID 0 is for the empty tileset */ | ||||
| } | } | ||||
| void Tiler::Deregister(int id) | void Tiler::Deregister(int id) | ||||
| { | { | ||||
| --id; /* ID 0 is for the empty tileset */ | |||||
| if (data->tilesets[id]->Unref() == 0) | |||||
| data->tilesets[id] = NULL; | |||||
| data->tilesets.RemoveSlot(id - 1); /* ID 0 is for the empty tileset */ | |||||
| } | } | ||||
| void Tiler::BlitTile(uint32_t code, int x, int y, int z, int o) | void Tiler::BlitTile(uint32_t code, int x, int y, int z, int o) | ||||
| { | { | ||||
| int id = (code >> 16) - 1; /* ID 0 is for the empty tileset */ | int id = (code >> 16) - 1; /* ID 0 is for the empty tileset */ | ||||
| data->tilesets[id]->BlitTile(code & 0xffff, x, y, z, o); | |||||
| TileSet *tileset = (TileSet *)data->tilesets.GetEntity(id); | |||||
| tileset->BlitTile(code & 0xffff, x, y, z, o); | |||||
| } | } | ||||
| @@ -28,13 +28,12 @@ public: | |||||
| protected: | protected: | ||||
| /* Inherited from Entity */ | /* Inherited from Entity */ | ||||
| virtual char const *GetName(); | |||||
| virtual Group GetGroup(); | virtual Group GetGroup(); | ||||
| virtual void TickRender(float deltams); | virtual void TickRender(float deltams); | ||||
| public: | public: | ||||
| /* New methods */ | /* New methods */ | ||||
| char const *GetName(); | |||||
| void BlitTile(uint32_t id, int x, int y, int z, int o); | void BlitTile(uint32_t id, int x, int y, int z, int o); | ||||
| private: | private: | ||||