@@ -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); | ||||