@@ -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: | |||