| @@ -7,7 +7,8 @@ libcommon_a_SOURCES = \ | |||
| game.cpp game.h tiler.cpp tiler.h tileset.cpp tileset.h \ | |||
| scene.cpp scene.h font.cpp font.h layer.cpp layer.h map.cpp map.h \ | |||
| joystick.cpp joystick.h asset.cpp asset.h ticker.cpp ticker.h \ | |||
| video.cpp video.h | |||
| forge.cpp forge.h video.cpp video.h \ | |||
| debugfps.cpp debugfps.h | |||
| libcommon_a_CXXFLAGS = `pkg-config --cflags sdl gl SDL_image` | |||
| test_map_SOURCES = test-map.cpp sdlinput.cpp sdlinput.h | |||
| @@ -27,7 +27,7 @@ Asset::Asset() : | |||
| Asset::~Asset() | |||
| { | |||
| #if !defined FINAL_RELEASE | |||
| #if !FINAL_RELEASE | |||
| if (!destroy) | |||
| fprintf(stderr, "ERROR: asset destructor called directly\n"); | |||
| #endif | |||
| @@ -0,0 +1,61 @@ | |||
| // | |||
| // Deus Hax (working title) | |||
| // Copyright (c) 2010 Sam Hocevar <sam@hocevar.net> | |||
| // | |||
| #if defined HAVE_CONFIG_H | |||
| # include "config.h" | |||
| #endif | |||
| #include <cstdio> | |||
| #include "debugfps.h" | |||
| #include "forge.h" | |||
| /* | |||
| * DebugFps implementation class | |||
| */ | |||
| class DebugFpsData | |||
| { | |||
| friend class DebugFps; | |||
| private: | |||
| Font *font; | |||
| int frame; | |||
| }; | |||
| /* | |||
| * Public DebugFps class | |||
| */ | |||
| DebugFps::DebugFps() | |||
| { | |||
| data = new DebugFpsData(); | |||
| data->font = Forge::GetFont("gfx/font/ascii.png"); | |||
| data->frame = 0; | |||
| } | |||
| Asset::Group DebugFps::GetGroup() | |||
| { | |||
| return GROUP_AFTER; | |||
| } | |||
| void DebugFps::TickRender(float delta_time) | |||
| { | |||
| Asset::TickGame(delta_time); | |||
| char buf[1024]; | |||
| sprintf(buf, "%3.2f fps (%i)", 1000.0f / delta_time, data->frame++); | |||
| data->font->Print(10, 10, buf); | |||
| data->font->Print(11, 10, buf); | |||
| data->font->Print(10, 11, buf); | |||
| } | |||
| DebugFps::~DebugFps() | |||
| { | |||
| Forge::ReleaseFont(data->font); | |||
| delete data; | |||
| } | |||
| @@ -0,0 +1,33 @@ | |||
| // | |||
| // Deus Hax (working title) | |||
| // Copyright (c) 2010 Sam Hocevar <sam@hocevar.net> | |||
| // | |||
| // | |||
| // The DebugFps class | |||
| // ------------------ | |||
| // | |||
| #if !defined __DH_DEBUGFPS_H__ | |||
| #define __DH_DEBUGFPS_H__ | |||
| #include "asset.h" | |||
| class DebugFpsData; | |||
| class DebugFps : public Asset | |||
| { | |||
| public: | |||
| DebugFps(); | |||
| virtual ~DebugFps(); | |||
| protected: | |||
| virtual Group GetGroup(); | |||
| virtual void TickRender(float delta_time); | |||
| private: | |||
| DebugFpsData *data; | |||
| }; | |||
| #endif // __DH_DEBUGFPS_H__ | |||
| @@ -32,6 +32,8 @@ class FontData | |||
| friend class Font; | |||
| private: | |||
| char *name; | |||
| SDL_Surface *img; | |||
| GLuint texture[1]; | |||
| }; | |||
| @@ -43,6 +45,7 @@ private: | |||
| Font::Font(char const *path) | |||
| { | |||
| data = new FontData(); | |||
| data->name = strdup(path); | |||
| data->img = NULL; | |||
| for (char const *name = path; *name; name++) | |||
| @@ -73,6 +76,21 @@ Font::~Font() | |||
| delete data; | |||
| } | |||
| Asset::Group Font::GetGroup() | |||
| { | |||
| return GROUP_BEFORE; | |||
| } | |||
| void Font::TickRender(float delta_time) | |||
| { | |||
| Asset::TickRender(delta_time); | |||
| } | |||
| char const *Font::GetName() | |||
| { | |||
| return data->name; | |||
| } | |||
| void Font::Print(int x, int y, char const *str) | |||
| { | |||
| int w = data->img->w / 16; | |||
| @@ -11,14 +11,25 @@ | |||
| #if !defined __DH_FONT_H__ | |||
| #define __DH_FONT_H__ | |||
| #include "asset.h" | |||
| class FontData; | |||
| class Font | |||
| class Font : public Asset | |||
| { | |||
| public: | |||
| Font(char const *path); | |||
| ~Font(); | |||
| protected: | |||
| /* Inherited from Asset */ | |||
| virtual Group GetGroup(); | |||
| virtual void TickRender(float delta_time); | |||
| public: | |||
| /* New methods */ | |||
| char const *GetName(); | |||
| void Print(int x, int y, char const *str); | |||
| private: | |||
| @@ -0,0 +1,98 @@ | |||
| // | |||
| // 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 "forge.h" | |||
| #if defined WIN32 | |||
| # define strcasecmp _stricmp | |||
| #endif | |||
| /* | |||
| * Forge implementation class | |||
| */ | |||
| 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; | |||
| } | |||
| forgedata; | |||
| static ForgeData * const data = &forgedata; | |||
| /* | |||
| * Public Forge class | |||
| */ | |||
| Font *Forge::GetFont(char const *path) | |||
| { | |||
| int id, empty = -1; | |||
| /* 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++) | |||
| { | |||
| Font *t = data->fonts[id]; | |||
| if (!t) | |||
| empty = id; | |||
| else if (!strcasecmp(path, t->GetName())) | |||
| break; | |||
| } | |||
| /* 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; | |||
| } | |||
| data->fonts[id]->Ref(); | |||
| return data->fonts[id]; | |||
| } | |||
| void Forge::ReleaseFont(Font *font) | |||
| { | |||
| if (font->Unref() == 0) | |||
| for (int id = 0; id < data->nfonts; id++) | |||
| if (font == data->fonts[id]) | |||
| { | |||
| data->fonts[id] = NULL; | |||
| break; | |||
| } | |||
| } | |||
| @@ -0,0 +1,25 @@ | |||
| // | |||
| // Deus Hax (working title) | |||
| // Copyright (c) 2010 Sam Hocevar <sam@hocevar.net> | |||
| // | |||
| // | |||
| // The Forge class | |||
| // --------------- | |||
| // The Forge is a static class that manages fonts. | |||
| // | |||
| #if !defined __DH_FORGE_H__ | |||
| #define __DH_FORGE_H__ | |||
| #include "font.h" | |||
| class Forge | |||
| { | |||
| public: | |||
| static Font *GetFont(char const *path); | |||
| static void ReleaseFont(Font *font); | |||
| }; | |||
| #endif // __DH_FORGE_H__ | |||
| @@ -11,7 +11,6 @@ | |||
| #include "game.h" | |||
| #include "map.h" | |||
| #include "font.h" | |||
| /* | |||
| * Game implementation class | |||
| @@ -23,7 +22,6 @@ class GameData | |||
| private: | |||
| Map *map; | |||
| Font *font; | |||
| int x, y; | |||
| int mousex, mousey; | |||
| int done; | |||
| @@ -39,7 +37,6 @@ Game::Game(char const *mapname) | |||
| { | |||
| data = new GameData(); | |||
| data->map = new Map(mapname); | |||
| data->font = new Font("gfx/font/ascii.png"); | |||
| data->x = data->y = 0; | |||
| data->done = 0; | |||
| data->frame = 0; | |||
| @@ -47,7 +44,6 @@ Game::Game(char const *mapname) | |||
| Game::~Game() | |||
| { | |||
| delete data->font; | |||
| delete data->map; | |||
| delete data; | |||
| } | |||
| @@ -72,10 +68,6 @@ void Game::TickRender(float delta_time) | |||
| scene->Render(); | |||
| delete scene; | |||
| char buf[1024]; | |||
| sprintf(buf, "Frame %i", data->frame++); | |||
| data->font->Print(10, 10, buf); | |||
| } | |||
| void Game::SetMouse(int x, int y) | |||
| @@ -15,6 +15,7 @@ | |||
| #include <gtkgl/gtkglarea.h> | |||
| #include "ticker.h" | |||
| #include "debugfps.h" | |||
| #include "video.h" | |||
| #include "game.h" | |||
| @@ -146,6 +147,7 @@ int main(int argc, char **argv) | |||
| // FIXME: detect when the game is killed | |||
| new Game("maps/testmap.tmx"); | |||
| new DebugFps(); | |||
| //gtk_idle_add(tick, glarea); | |||
| gtk_timeout_add(33, tick, glarea); | |||
| @@ -13,6 +13,7 @@ | |||
| #include <SDL.h> | |||
| #include "sdlinput.h" | |||
| #include "debugfps.h" | |||
| #include "game.h" | |||
| #include "ticker.h" | |||
| #include "video.h" | |||
| @@ -49,8 +50,9 @@ int main(int argc, char **argv) | |||
| /* Create a game */ | |||
| Game *game = new Game("maps/testmap.tmx"); | |||
| /* Register an input driver */ | |||
| /* Register an input driver and some debug stuff */ | |||
| new SdlInput(game); | |||
| new DebugFps(); | |||
| while (!game->Finished()) | |||
| { | |||
| @@ -24,6 +24,7 @@ static class TickerData | |||
| public: | |||
| TickerData() : | |||
| todo(0), | |||
| nassets(0) | |||
| { | |||
| for (int i = 0; i < Asset::GROUP_COUNT; i++) | |||
| @@ -32,11 +33,14 @@ public: | |||
| ~TickerData() | |||
| { | |||
| #if !FINAL_RELEASE | |||
| if (nassets) | |||
| fprintf(stderr, "ERROR: still %i assets in ticker\n", nassets); | |||
| #endif | |||
| } | |||
| private: | |||
| Asset *todo; | |||
| Asset *list[Asset::GROUP_COUNT]; | |||
| int nassets; | |||
| } | |||
| @@ -50,14 +54,27 @@ static TickerData * const data = &tickerdata; | |||
| void Ticker::Register(Asset *asset) | |||
| { | |||
| int i = asset->GetGroup(); | |||
| asset->next = data->list[i]; | |||
| data->list[i] = asset; | |||
| data->nassets++; | |||
| /* If we are called from its constructor, the object's vtable is not | |||
| * ready yet, so we do not know which group this asset belongs to. Wait | |||
| * until the first tick. */ | |||
| asset->next = data->todo; | |||
| data->todo = asset; | |||
| } | |||
| void Ticker::TickGame(float delta_time) | |||
| { | |||
| /* Insert waiting objects in the appropriate lists */ | |||
| while (data->todo) | |||
| { | |||
| Asset *a = data->todo; | |||
| data->todo = a->next; | |||
| int i = a->GetGroup(); | |||
| a->next = data->list[i]; | |||
| data->list[i] = a; | |||
| data->nassets++; | |||
| } | |||
| /* Garbage collect objects that can be destroyed */ | |||
| for (int i = 0; i < Asset::GROUP_COUNT; i++) | |||
| for (Asset *a = data->list[i], *prev = NULL; a; prev = a, a = a->next) | |||