| @@ -4,7 +4,7 @@ noinst_PROGRAMS = test-map editor | |||
| noinst_LIBRARIES = libcommon.a | |||
| 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 \ | |||
| 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 \ | |||
| @@ -28,6 +28,7 @@ | |||
| #include "tileset.h" | |||
| // Other objects | |||
| #include "dict.h" | |||
| #include "map.h" | |||
| #include "layer.h" | |||
| @@ -21,7 +21,7 @@ class DebugFpsData | |||
| friend class DebugFps; | |||
| private: | |||
| Font *font; | |||
| int fontid; | |||
| int frame; | |||
| }; | |||
| @@ -33,7 +33,7 @@ DebugFps::DebugFps() | |||
| { | |||
| data = new DebugFpsData(); | |||
| data->font = Forge::GetFont("gfx/font/ascii.png"); | |||
| data->fontid = Forge::Register("gfx/font/ascii.png"); | |||
| data->frame = 0; | |||
| } | |||
| @@ -49,35 +49,36 @@ void DebugFps::TickRender(float deltams) | |||
| data->frame++; | |||
| char buf[1024]; | |||
| Font *font = Forge::GetFont(data->fontid); | |||
| sprintf(buf, "%2.2f fps (%i)", | |||
| 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", | |||
| Profiler::GetMean(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", | |||
| Profiler::GetMean(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", | |||
| Profiler::GetMean(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", | |||
| Profiler::GetMean(Profiler::STAT_TICK_FRAME), | |||
| Profiler::GetMax(Profiler::STAT_TICK_FRAME)); | |||
| data->font->PrintBold(10, 82, buf); | |||
| font->PrintBold(10, 82, buf); | |||
| } | |||
| DebugFps::~DebugFps() | |||
| { | |||
| Forge::ReleaseFont(data->font); | |||
| Forge::Deregister(data->fontid); | |||
| 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 | |||
| } | |||
| char const *Entity::GetName() | |||
| { | |||
| return "Generic entity"; | |||
| } | |||
| Entity::Group Entity::GetGroup() | |||
| { | |||
| return GROUP_DEFAULT; | |||
| @@ -20,6 +20,7 @@ class Entity | |||
| { | |||
| friend class Ticker; | |||
| friend class TickerData; | |||
| friend class Dict; | |||
| public: | |||
| virtual void Ref(); | |||
| @@ -40,6 +41,7 @@ protected: | |||
| Entity(); | |||
| virtual ~Entity(); | |||
| virtual char const *GetName(); | |||
| virtual Group GetGroup(); | |||
| virtual void TickGame(float deltams); | |||
| @@ -23,13 +23,12 @@ public: | |||
| protected: | |||
| /* Inherited from Entity */ | |||
| virtual char const *GetName(); | |||
| virtual Group GetGroup(); | |||
| virtual void TickRender(float deltams); | |||
| public: | |||
| /* New methods */ | |||
| char const *GetName(); | |||
| void Print(int x, int y, char const *str); | |||
| void PrintBold(int x, int y, char const *str); | |||
| @@ -7,10 +7,6 @@ | |||
| # include "config.h" | |||
| #endif | |||
| #include <cstring> | |||
| #include <cstdio> | |||
| #include <cstdlib> | |||
| #include "core.h" | |||
| #if defined WIN32 | |||
| @@ -26,23 +22,7 @@ static class ForgeData | |||
| friend class Forge; | |||
| 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; | |||
| @@ -52,47 +32,26 @@ static ForgeData * const data = &forgedata; | |||
| * 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 | |||
| { | |||
| 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__ | |||
| @@ -7,10 +7,6 @@ | |||
| # include "config.h" | |||
| #endif | |||
| #include <cstring> | |||
| #include <cstdio> | |||
| #include <cstdlib> | |||
| #include "core.h" | |||
| #if defined WIN32 | |||
| @@ -26,23 +22,7 @@ static class TilerData | |||
| friend class Tiler; | |||
| 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; | |||
| @@ -54,49 +34,27 @@ static TilerData * const data = &tilerdata; | |||
| 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 */ | |||
| } | |||
| 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) | |||
| { | |||
| 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: | |||
| /* Inherited from Entity */ | |||
| virtual char const *GetName(); | |||
| virtual Group GetGroup(); | |||
| virtual void TickRender(float deltams); | |||
| public: | |||
| /* New methods */ | |||
| char const *GetName(); | |||
| void BlitTile(uint32_t id, int x, int y, int z, int o); | |||
| private: | |||