| @@ -33,11 +33,8 @@ DebugFps::DebugFps() | |||||
| data = new DebugFpsData(); | data = new DebugFpsData(); | ||||
| data->fontid = Forge::Register("gfx/font/ascii.png"); | data->fontid = Forge::Register("gfx/font/ascii.png"); | ||||
| } | |||||
| Entity::Group DebugFps::GetGroup() | |||||
| { | |||||
| return GROUP_AFTER; | |||||
| drawgroup = DRAWGROUP_HUD; | |||||
| } | } | ||||
| void DebugFps::TickDraw(float deltams) | void DebugFps::TickDraw(float deltams) | ||||
| @@ -22,7 +22,6 @@ public: | |||||
| virtual ~DebugFps(); | virtual ~DebugFps(); | ||||
| protected: | protected: | ||||
| virtual Group GetGroup(); | |||||
| virtual void TickDraw(float deltams); | virtual void TickDraw(float deltams); | ||||
| private: | private: | ||||
| @@ -46,11 +46,8 @@ DebugRecord::DebugRecord(char const *path) | |||||
| #if defined USE_PIPI | #if defined USE_PIPI | ||||
| data->sequence = NULL; | data->sequence = NULL; | ||||
| #endif | #endif | ||||
| } | |||||
| Entity::Group DebugRecord::GetGroup() | |||||
| { | |||||
| return GROUP_DRAW_CAPTURE; | |||||
| drawgroup = DRAWGROUP_CAPTURE; | |||||
| } | } | ||||
| void DebugRecord::TickGame(float deltams) | void DebugRecord::TickGame(float deltams) | ||||
| @@ -22,7 +22,6 @@ public: | |||||
| virtual ~DebugRecord(); | virtual ~DebugRecord(); | ||||
| protected: | protected: | ||||
| virtual Group GetGroup(); | |||||
| virtual void TickGame(float deltams); | virtual void TickGame(float deltams); | ||||
| virtual void TickDraw(float deltams); | virtual void TickDraw(float deltams); | ||||
| @@ -110,11 +110,6 @@ DebugSphere::DebugSphere() | |||||
| data->time = 0.0f; | data->time = 0.0f; | ||||
| } | } | ||||
| Entity::Group DebugSphere::GetGroup() | |||||
| { | |||||
| return GROUP_DEFAULT; | |||||
| } | |||||
| void DebugSphere::TickGame(float deltams) | void DebugSphere::TickGame(float deltams) | ||||
| { | { | ||||
| Entity::TickGame(deltams); | Entity::TickGame(deltams); | ||||
| @@ -22,7 +22,6 @@ public: | |||||
| virtual ~DebugSphere(); | virtual ~DebugSphere(); | ||||
| protected: | protected: | ||||
| virtual Group GetGroup(); | |||||
| virtual void TickGame(float deltams); | virtual void TickGame(float deltams); | ||||
| virtual void TickDraw(float deltams); | virtual void TickDraw(float deltams); | ||||
| @@ -42,11 +42,6 @@ DebugSprite::DebugSprite(Game *game) | |||||
| data->z = 0; | data->z = 0; | ||||
| } | } | ||||
| Entity::Group DebugSprite::GetGroup() | |||||
| { | |||||
| return GROUP_DEFAULT; | |||||
| } | |||||
| void DebugSprite::TickGame(float deltams) | void DebugSprite::TickGame(float deltams) | ||||
| { | { | ||||
| Entity::TickGame(deltams); | Entity::TickGame(deltams); | ||||
| @@ -23,7 +23,6 @@ public: | |||||
| virtual ~DebugSprite(); | virtual ~DebugSprite(); | ||||
| protected: | protected: | ||||
| virtual Group GetGroup(); | |||||
| virtual void TickGame(float deltams); | virtual void TickGame(float deltams); | ||||
| virtual void TickDraw(float deltams); | virtual void TickDraw(float deltams); | ||||
| @@ -32,11 +32,8 @@ DebugStats::DebugStats(char const *path) | |||||
| { | { | ||||
| data = new DebugStatsData(); | data = new DebugStatsData(); | ||||
| data->fp = fopen(path, "w+"); | data->fp = fopen(path, "w+"); | ||||
| } | |||||
| Entity::Group DebugStats::GetGroup() | |||||
| { | |||||
| return GROUP_AFTER; | |||||
| gamegroup = GAMEGROUP_AFTER; | |||||
| } | } | ||||
| void DebugStats::TickGame(float deltams) | void DebugStats::TickGame(float deltams) | ||||
| @@ -22,7 +22,6 @@ public: | |||||
| virtual ~DebugStats(); | virtual ~DebugStats(); | ||||
| protected: | protected: | ||||
| virtual Group GetGroup(); | |||||
| virtual void TickGame(float deltams); | virtual void TickGame(float deltams); | ||||
| private: | private: | ||||
| @@ -17,13 +17,16 @@ | |||||
| */ | */ | ||||
| Entity::Entity() : | Entity::Entity() : | ||||
| next(0), | |||||
| gamenext(0), | |||||
| drawnext(0), | |||||
| ref(0), | ref(0), | ||||
| destroy(0) | destroy(0) | ||||
| { | { | ||||
| #if !FINAL_RELEASE | #if !FINAL_RELEASE | ||||
| state = STATE_IDLE; | state = STATE_IDLE; | ||||
| #endif | #endif | ||||
| gamegroup = GAMEGROUP_DEFAULT; | |||||
| drawgroup = DRAWGROUP_DEFAULT; | |||||
| Ticker::Register(this); | Ticker::Register(this); | ||||
| } | } | ||||
| @@ -40,11 +43,6 @@ char const *Entity::GetName() | |||||
| return "<entity>"; | return "<entity>"; | ||||
| } | } | ||||
| Entity::Group Entity::GetGroup() | |||||
| { | |||||
| return GROUP_DEFAULT; | |||||
| } | |||||
| void Entity::TickGame(float deltams) | void Entity::TickGame(float deltams) | ||||
| { | { | ||||
| #if !FINAL_RELEASE | #if !FINAL_RELEASE | ||||
| @@ -23,29 +23,42 @@ class Entity | |||||
| friend class Dict; | friend class Dict; | ||||
| protected: | protected: | ||||
| typedef enum | |||||
| { | |||||
| GROUP_BEFORE = 0, | |||||
| GROUP_DEFAULT, | |||||
| GROUP_AFTER, | |||||
| GROUP_DRAW_CAPTURE, | |||||
| // Must be the last element | |||||
| GROUP_COUNT | |||||
| } | |||||
| Group; | |||||
| Entity(); | Entity(); | ||||
| virtual ~Entity(); | virtual ~Entity(); | ||||
| virtual char const *GetName(); | virtual char const *GetName(); | ||||
| virtual Group GetGroup(); | |||||
| virtual void TickGame(float deltams); | virtual void TickGame(float deltams); | ||||
| virtual void TickDraw(float deltams); | virtual void TickDraw(float deltams); | ||||
| Entity *next, *autonext; | |||||
| Entity *gamenext, *drawnext, *autonext; | |||||
| int ref, autorelease, destroy; | int ref, autorelease, destroy; | ||||
| enum | |||||
| { | |||||
| GAMEGROUP_BEFORE = 0, | |||||
| GAMEGROUP_DEFAULT, | |||||
| GAMEGROUP_AFTER, | |||||
| // Must be the last element | |||||
| GAMEGROUP_END | |||||
| } | |||||
| gamegroup; | |||||
| enum | |||||
| { | |||||
| DRAWGROUP_BEFORE = GAMEGROUP_END, | |||||
| DRAWGROUP_DEFAULT, | |||||
| DRAWGROUP_HUD, | |||||
| DRAWGROUP_CAPTURE, | |||||
| // Must be the last element | |||||
| DRAWGROUP_END | |||||
| } | |||||
| drawgroup; | |||||
| static int const GAMEGROUP_BEGIN = 0; | |||||
| static int const DRAWGROUP_BEGIN = GAMEGROUP_END; | |||||
| static int const ALLGROUP_END = DRAWGROUP_END; | |||||
| #if !FINAL_RELEASE | #if !FINAL_RELEASE | ||||
| enum | enum | ||||
| { | { | ||||
| @@ -58,6 +58,8 @@ Font::Font(char const *path) | |||||
| SDL_Quit(); | SDL_Quit(); | ||||
| exit(1); | exit(1); | ||||
| } | } | ||||
| drawgroup = DRAWGROUP_BEFORE; | |||||
| } | } | ||||
| Font::~Font() | Font::~Font() | ||||
| @@ -65,11 +67,6 @@ Font::~Font() | |||||
| delete data; | delete data; | ||||
| } | } | ||||
| Entity::Group Font::GetGroup() | |||||
| { | |||||
| return GROUP_BEFORE; | |||||
| } | |||||
| void Font::TickDraw(float deltams) | void Font::TickDraw(float deltams) | ||||
| { | { | ||||
| Entity::TickDraw(deltams); | Entity::TickDraw(deltams); | ||||
| @@ -24,7 +24,6 @@ public: | |||||
| protected: | protected: | ||||
| /* Inherited from Entity */ | /* Inherited from Entity */ | ||||
| virtual char const *GetName(); | virtual char const *GetName(); | ||||
| virtual Group GetGroup(); | |||||
| virtual void TickDraw(float deltams); | virtual void TickDraw(float deltams); | ||||
| public: | public: | ||||
| @@ -47,11 +47,6 @@ Game::~Game() | |||||
| delete data; | delete data; | ||||
| } | } | ||||
| Entity::Group Game::GetGroup() | |||||
| { | |||||
| return Entity::GetGroup(); | |||||
| } | |||||
| void Game::TickGame(float deltams) | void Game::TickGame(float deltams) | ||||
| { | { | ||||
| Entity::TickGame(deltams); | Entity::TickGame(deltams); | ||||
| @@ -24,7 +24,6 @@ public: | |||||
| protected: | protected: | ||||
| /* Inherited from Entity */ | /* Inherited from Entity */ | ||||
| virtual Group GetGroup(); | |||||
| virtual void TickGame(float deltams); | virtual void TickGame(float deltams); | ||||
| virtual void TickDraw(float deltams); | virtual void TickDraw(float deltams); | ||||
| @@ -47,11 +47,6 @@ MapViewer::~MapViewer() | |||||
| delete data; | delete data; | ||||
| } | } | ||||
| Entity::Group MapViewer::GetGroup() | |||||
| { | |||||
| return Entity::GetGroup(); | |||||
| } | |||||
| void MapViewer::TickGame(float deltams) | void MapViewer::TickGame(float deltams) | ||||
| { | { | ||||
| Entity::TickGame(deltams); | Entity::TickGame(deltams); | ||||
| @@ -24,7 +24,6 @@ public: | |||||
| protected: | protected: | ||||
| /* Inherited from Entity */ | /* Inherited from Entity */ | ||||
| virtual Group GetGroup(); | |||||
| virtual void TickGame(float deltams); | virtual void TickGame(float deltams); | ||||
| virtual void TickDraw(float deltams); | virtual void TickDraw(float deltams); | ||||
| @@ -34,11 +34,8 @@ SdlInput::SdlInput() | |||||
| data = new SdlInputData(); | data = new SdlInputData(); | ||||
| SDL_GetMouseState(&data->mx, &data->my); | SDL_GetMouseState(&data->mx, &data->my); | ||||
| } | |||||
| Entity::Group SdlInput::GetGroup() | |||||
| { | |||||
| return GROUP_BEFORE; | |||||
| gamegroup = GAMEGROUP_BEFORE; | |||||
| } | } | ||||
| void SdlInput::TickGame(float deltams) | void SdlInput::TickGame(float deltams) | ||||
| @@ -23,7 +23,6 @@ public: | |||||
| virtual ~SdlInput(); | virtual ~SdlInput(); | ||||
| protected: | protected: | ||||
| virtual Group GetGroup(); | |||||
| virtual void TickGame(float deltams); | virtual void TickGame(float deltams); | ||||
| private: | private: | ||||
| @@ -27,7 +27,7 @@ public: | |||||
| nentities(0), | nentities(0), | ||||
| frame(0), deltams(0), bias(0) | frame(0), deltams(0), bias(0) | ||||
| { | { | ||||
| for (int i = 0; i < Entity::GROUP_COUNT; i++) | |||||
| for (int i = 0; i < Entity::ALLGROUP_END; i++) | |||||
| list[i] = NULL; | list[i] = NULL; | ||||
| } | } | ||||
| @@ -51,7 +51,7 @@ public: | |||||
| private: | private: | ||||
| /* Entity management */ | /* Entity management */ | ||||
| Entity *todolist, *autolist; | Entity *todolist, *autolist; | ||||
| Entity *list[Entity::GROUP_COUNT]; | |||||
| Entity *list[Entity::ALLGROUP_END]; | |||||
| int nentities; | int nentities; | ||||
| /* Fixed framerate management */ | /* Fixed framerate management */ | ||||
| @@ -72,7 +72,7 @@ void Ticker::Register(Entity *entity) | |||||
| /* If we are called from its constructor, the object's vtable is not | /* If we are called from its constructor, the object's vtable is not | ||||
| * ready yet, so we do not know which group this entity belongs to. Wait | * ready yet, so we do not know which group this entity belongs to. Wait | ||||
| * until the first tick. */ | * until the first tick. */ | ||||
| entity->next = data->todolist; | |||||
| entity->gamenext = data->todolist; | |||||
| data->todolist = entity; | data->todolist = entity; | ||||
| /* Objects are autoreleased by default. Put them in a circular list. */ | /* Objects are autoreleased by default. Put them in a circular list. */ | ||||
| entity->autorelease = 1; | entity->autorelease = 1; | ||||
| @@ -99,10 +99,7 @@ void Ticker::Ref(Entity *entity) | |||||
| { | { | ||||
| if (e == entity) | if (e == entity) | ||||
| { | { | ||||
| if (prev) | |||||
| prev->autonext = e->autonext; | |||||
| else | |||||
| data->autolist = e->autonext; | |||||
| (prev ? prev->autonext : data->autolist) = e->autonext; | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| @@ -132,12 +129,16 @@ void Ticker::TickGame() | |||||
| #if 0 | #if 0 | ||||
| fprintf(stderr, "-------------------------------------\n"); | fprintf(stderr, "-------------------------------------\n"); | ||||
| for (int i = 0; i < Entity::GROUP_COUNT; i++) | |||||
| for (int i = 0; i < Entity::ALLGROUP_END; i++) | |||||
| { | { | ||||
| fprintf(stderr, "Group %i\n", i); | |||||
| fprintf(stderr, "%s Group %i\n", | |||||
| (i < Entity::GAMEGROUP_END) ? "Game" : "Draw", i); | |||||
| for (Entity *e = data->list[i]; e; e = e->next) | |||||
| for (Entity *e = data->list[i]; e; ) | |||||
| { | |||||
| fprintf(stderr, " \\-- %s (ref %i, destroy %i)\n", e->GetName(), e->ref, e->destroy); | fprintf(stderr, " \\-- %s (ref %i, destroy %i)\n", e->GetName(), e->ref, e->destroy); | ||||
| e = (i < Entity::GAMEGROUP_END) ? e->gamenext : e->drawnext; | |||||
| } | |||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -147,30 +148,37 @@ void Ticker::TickGame() | |||||
| data->bias += data->deltams; | data->bias += data->deltams; | ||||
| /* Garbage collect objects that can be destroyed. We can do this | /* Garbage collect objects that can be destroyed. We can do this | ||||
| * before inserting awaiting objects, because there is no way these | |||||
| * are already marked for destruction. */ | |||||
| for (int i = 0; i < Entity::GROUP_COUNT; i++) | |||||
| * before inserting awaiting objects, because only objects already in | |||||
| * the tick lists can be marked for destruction. */ | |||||
| for (int i = 0; i < Entity::ALLGROUP_END; i++) | |||||
| for (Entity *e = data->list[i], *prev = NULL; e; ) | for (Entity *e = data->list[i], *prev = NULL; e; ) | ||||
| { | { | ||||
| if (e->destroy) | |||||
| if (e->destroy && i < Entity::GAMEGROUP_END) | |||||
| { | |||||
| /* If entity is to be destroyed, remove it from the | |||||
| * game tick list. */ | |||||
| (prev ? prev->gamenext : data->list[i]) = e->gamenext; | |||||
| e = e->gamenext; | |||||
| } | |||||
| else if (e->destroy) | |||||
| { | { | ||||
| if (prev) | |||||
| prev->next = e->next; | |||||
| else | |||||
| data->list[i] = e->next; | |||||
| /* If entity is to be destroyed, remove it from the | |||||
| * draw tick list and destroy it. */ | |||||
| (prev ? prev->drawnext : data->list[i]) = e->drawnext; | |||||
| Entity *tmp = e; | Entity *tmp = e; | ||||
| e = e->next; | |||||
| e = e->drawnext; /* Can only be in a draw group list */ | |||||
| delete tmp; | delete tmp; | ||||
| data->nentities--; | data->nentities--; | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| if (e->ref <= 0) | |||||
| if (e->ref <= 0 && i >= Entity::DRAWGROUP_BEGIN) | |||||
| e->destroy = 1; | e->destroy = 1; | ||||
| prev = e; | prev = e; | ||||
| e = e->next; | |||||
| e = (i < Entity::GAMEGROUP_END) ? e->gamenext : e->drawnext; | |||||
| } | } | ||||
| } | } | ||||
| @@ -178,16 +186,17 @@ void Ticker::TickGame() | |||||
| while (data->todolist) | while (data->todolist) | ||||
| { | { | ||||
| Entity *e = data->todolist; | Entity *e = data->todolist; | ||||
| data->todolist = e->next; | |||||
| data->todolist = e->gamenext; | |||||
| int i = e->GetGroup(); | |||||
| e->next = data->list[i]; | |||||
| data->list[i] = e; | |||||
| e->gamenext = data->list[e->gamegroup]; | |||||
| data->list[e->gamegroup] = e; | |||||
| e->drawnext = data->list[e->drawgroup]; | |||||
| data->list[e->drawgroup] = e; | |||||
| } | } | ||||
| /* Tick objects for the game loop */ | /* Tick objects for the game loop */ | ||||
| for (int i = 0; i < Entity::GROUP_COUNT; i++) | |||||
| for (Entity *e = data->list[i]; e; e = e->next) | |||||
| for (int i = Entity::GAMEGROUP_BEGIN; i < Entity::GAMEGROUP_END; i++) | |||||
| for (Entity *e = data->list[i]; e; e = e->gamenext) | |||||
| if (!e->destroy) | if (!e->destroy) | ||||
| { | { | ||||
| #if !FINAL_RELEASE | #if !FINAL_RELEASE | ||||
| @@ -211,8 +220,8 @@ void Ticker::TickDraw() | |||||
| Profiler::Start(Profiler::STAT_TICK_DRAW); | Profiler::Start(Profiler::STAT_TICK_DRAW); | ||||
| /* Tick objects for the draw loop */ | /* Tick objects for the draw loop */ | ||||
| for (int i = 0; i < Entity::GROUP_COUNT; i++) | |||||
| for (Entity *e = data->list[i]; e; e = e->next) | |||||
| for (int i = Entity::DRAWGROUP_BEGIN; i < Entity::DRAWGROUP_END; i++) | |||||
| for (Entity *e = data->list[i]; e; e = e->drawnext) | |||||
| if (!e->destroy) | if (!e->destroy) | ||||
| { | { | ||||
| #if !FINAL_RELEASE | #if !FINAL_RELEASE | ||||
| @@ -71,6 +71,8 @@ TileSet::TileSet(char const *path) | |||||
| data->ntiles = data->nw * data->nh; | data->ntiles = data->nw * data->nh; | ||||
| data->tx = 32.0f / data->img->w; | data->tx = 32.0f / data->img->w; | ||||
| data->ty = 32.0f / data->img->h; | data->ty = 32.0f / data->img->h; | ||||
| drawgroup = DRAWGROUP_BEFORE; | |||||
| } | } | ||||
| TileSet::~TileSet() | TileSet::~TileSet() | ||||
| @@ -80,11 +82,6 @@ TileSet::~TileSet() | |||||
| delete data; | delete data; | ||||
| } | } | ||||
| Entity::Group TileSet::GetGroup() | |||||
| { | |||||
| return GROUP_BEFORE; | |||||
| } | |||||
| void TileSet::TickDraw(float deltams) | void TileSet::TickDraw(float deltams) | ||||
| { | { | ||||
| Entity::TickDraw(deltams); | Entity::TickDraw(deltams); | ||||
| @@ -29,7 +29,6 @@ public: | |||||
| protected: | protected: | ||||
| /* Inherited from Entity */ | /* Inherited from Entity */ | ||||
| virtual char const *GetName(); | virtual char const *GetName(); | ||||
| virtual Group GetGroup(); | |||||
| virtual void TickDraw(float deltams); | virtual void TickDraw(float deltams); | ||||
| public: | public: | ||||
| @@ -35,6 +35,8 @@ World::World() | |||||
| data = new WorldData(); | data = new WorldData(); | ||||
| data->width = 0; | data->width = 0; | ||||
| data->height = 0; | data->height = 0; | ||||
| drawgroup = DRAWGROUP_BEFORE; | |||||
| } | } | ||||
| World::~World() | World::~World() | ||||
| @@ -42,11 +44,6 @@ World::~World() | |||||
| delete data; | delete data; | ||||
| } | } | ||||
| Entity::Group World::GetGroup() | |||||
| { | |||||
| return GROUP_BEFORE; | |||||
| } | |||||
| char const *World::GetName() | char const *World::GetName() | ||||
| { | { | ||||
| return "<world>"; | return "<world>"; | ||||
| @@ -24,7 +24,6 @@ public: | |||||
| protected: | protected: | ||||
| /* Inherited from Entity */ | /* Inherited from Entity */ | ||||
| virtual char const *GetName(); | virtual char const *GetName(); | ||||
| virtual Group GetGroup(); | |||||
| virtual void TickGame(float deltams); | virtual void TickGame(float deltams); | ||||
| virtual void TickDraw(float deltams); | virtual void TickDraw(float deltams); | ||||