diff --git a/src/Makefile.am b/src/Makefile.am index 2d8815d9..a75588bd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ diff --git a/src/core.h b/src/core.h index c91201d5..1edabe78 100644 --- a/src/core.h +++ b/src/core.h @@ -28,6 +28,7 @@ #include "tileset.h" // Other objects +#include "dict.h" #include "map.h" #include "layer.h" diff --git a/src/debugfps.cpp b/src/debugfps.cpp index 5e162579..fd0c9d46 100644 --- a/src/debugfps.cpp +++ b/src/debugfps.cpp @@ -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; } diff --git a/src/dict.cpp b/src/dict.cpp new file mode 100644 index 00000000..e040b65e --- /dev/null +++ b/src/dict.cpp @@ -0,0 +1,111 @@ +// +// Deus Hax (working title) +// Copyright (c) 2010 Sam Hocevar +// + +#if defined HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#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]; +} + diff --git a/src/dict.h b/src/dict.h new file mode 100644 index 00000000..d704757a --- /dev/null +++ b/src/dict.h @@ -0,0 +1,35 @@ +// +// Deus Hax (working title) +// Copyright (c) 2010 Sam Hocevar +// + +// +// 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__ + diff --git a/src/entity.cpp b/src/entity.cpp index 4fb0f617..63d9e077 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -35,6 +35,11 @@ Entity::~Entity() #endif } +char const *Entity::GetName() +{ + return "Generic entity"; +} + Entity::Group Entity::GetGroup() { return GROUP_DEFAULT; diff --git a/src/entity.h b/src/entity.h index d943e0dd..2ac7bea8 100644 --- a/src/entity.h +++ b/src/entity.h @@ -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); diff --git a/src/font.h b/src/font.h index 0ab5026a..b5c3a214 100644 --- a/src/font.h +++ b/src/font.h @@ -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); diff --git a/src/forge.cpp b/src/forge.cpp index bf8ed7fc..59a88bdc 100644 --- a/src/forge.cpp +++ b/src/forge.cpp @@ -7,10 +7,6 @@ # include "config.h" #endif -#include -#include -#include - #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); } diff --git a/src/forge.h b/src/forge.h index 58b91ffb..d7330d0f 100644 --- a/src/forge.h +++ b/src/forge.h @@ -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__ diff --git a/src/tiler.cpp b/src/tiler.cpp index 1c407953..3cae79f7 100644 --- a/src/tiler.cpp +++ b/src/tiler.cpp @@ -7,10 +7,6 @@ # include "config.h" #endif -#include -#include -#include - #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); } diff --git a/src/tileset.h b/src/tileset.h index 91888eaf..791140a3 100644 --- a/src/tileset.h +++ b/src/tileset.h @@ -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: