no more global timeline - from now on timelines can be instantiated!

This commit is contained in:
Sebastian Krzyszkowiak 2015-03-18 02:21:57 +01:00
parent 5172db6fe3
commit 937981a1df
11 changed files with 184 additions and 182 deletions

View file

@ -71,7 +71,7 @@ bool Type(struct Game *game, struct TM_Action *action, enum TM_ActionState state
strncpy(data->text, text, data->pos++);
data->text[data->pos] = 0;
if (strcmp(data->text, text) != 0) {
TM_AddBackgroundAction(Type, TM_AddToArgs(NULL, 1, data), 60 + rand() % 60, "type");
TM_AddBackgroundAction(data->timeline, Type, TM_AddToArgs(NULL, 1, data), 60 + rand() % 60, "type");
} else{
al_stop_sample_instance(data->kbd);
}
@ -82,7 +82,7 @@ bool Type(struct Game *game, struct TM_Action *action, enum TM_ActionState state
void Gamestate_Logic(struct Game *game, struct dosowiskoResources* data) {
TM_Process();
TM_Process(data->timeline);
data->tick++;
if (data->tick == 30) {
data->underscore = !data->underscore;
@ -129,22 +129,22 @@ void Gamestate_Start(struct Game *game, struct dosowiskoResources* data) {
data->fadeout = false;
data->underscore=true;
strcpy(data->text, "#");
TM_AddDelay(300);
TM_AddQueuedBackgroundAction(FadeIn, TM_AddToArgs(NULL, 1, data), 0, "fadein");
TM_AddDelay(1500);
TM_AddAction(Play, TM_AddToArgs(NULL, 1, data->kbd), "playkbd");
TM_AddQueuedBackgroundAction(Type, TM_AddToArgs(NULL, 1, data), 0, "type");
TM_AddDelay(3200);
TM_AddAction(Play, TM_AddToArgs(NULL, 1, data->key), "playkey");
TM_AddDelay(50);
TM_AddAction(FadeOut, TM_AddToArgs(NULL, 1, data), "fadeout");
TM_AddDelay(1000);
TM_AddAction(End, NULL, "end");
TM_AddDelay(data->timeline, 300);
TM_AddQueuedBackgroundAction(data->timeline, FadeIn, TM_AddToArgs(NULL, 1, data), 0, "fadein");
TM_AddDelay(data->timeline, 1500);
TM_AddAction(data->timeline, Play, TM_AddToArgs(NULL, 1, data->kbd), "playkbd");
TM_AddQueuedBackgroundAction(data->timeline, Type, TM_AddToArgs(NULL, 1, data), 0, "type");
TM_AddDelay(data->timeline, 3200);
TM_AddAction(data->timeline, Play, TM_AddToArgs(NULL, 1, data->key), "playkey");
TM_AddDelay(data->timeline, 50);
TM_AddAction(data->timeline, FadeOut, TM_AddToArgs(NULL, 1, data), "fadeout");
TM_AddDelay(data->timeline, 1000);
TM_AddAction(data->timeline, End, NULL, "end");
al_play_sample_instance(data->sound);
}
void Gamestate_ProcessEvent(struct Game *game, struct dosowiskoResources* data, ALLEGRO_EVENT *ev) {
TM_HandleEvent(ev);
TM_HandleEvent(data->timeline, ev);
if ((ev->type==ALLEGRO_EVENT_KEY_DOWN) && (ev->keyboard.keycode == ALLEGRO_KEY_ESCAPE)) {
SwitchGamestate(game, "dosowisko", "menu");
}
@ -152,7 +152,7 @@ void Gamestate_ProcessEvent(struct Game *game, struct dosowiskoResources* data,
void* Gamestate_Load(struct Game *game, void (*progress)(struct Game*)) {
struct dosowiskoResources *data = malloc(sizeof(struct dosowiskoResources));
TM_Init(game);
data->timeline = TM_Init(game, "main");
data->bitmap = al_create_bitmap(game->viewport.width, game->viewport.height);
data->checkerboard = al_create_bitmap(game->viewport.width, game->viewport.height);
@ -208,8 +208,8 @@ void Gamestate_Unload(struct Game *game, struct dosowiskoResources* data) {
al_destroy_sample(data->key_sample);
al_destroy_bitmap(data->bitmap);
al_destroy_bitmap(data->checkerboard);
TM_Destroy(data->timeline);
free(data);
TM_Destroy();
}
void Gamestate_Reload(struct Game *game, struct dosowiskoResources* data) {}

View file

@ -27,4 +27,5 @@ struct dosowiskoResources {
int pos, fade, tick, tan;
char text[255];
bool underscore, fadeout;
struct Timeline *timeline;
};

View file

@ -31,29 +31,29 @@
int Gamestate_ProgressCount = 2;
void Gamestate_Start(struct Game *game, struct Level1Resources* data) {
TM_AddBackgroundAction(&FadeIn, NULL, 0, "fadein");
TM_AddDelay(1000);
TM_AddQueuedBackgroundAction(&Welcome, NULL, 0, "welcome");
TM_AddDelay(1000);
TM_AddAction(&Walk, NULL, "walk");
TM_AddAction(&Move, NULL, "move");
TM_AddAction(&Stop, NULL, "stop");
TM_AddDelay(1000);
TM_AddAction(&Letter, NULL, "letter");
TM_AddDelay(200);
TM_AddQueuedBackgroundAction(&Accelerate, NULL, 0, "accelerate");
TM_AddAction(&Fly, NULL, "fly");
TM_AddDelay(500);
TM_AddBackgroundAction(data->dodger->timeline, &FadeIn, NULL, 0, "fadein");
TM_AddDelay(data->dodger->timeline, 1000);
TM_AddQueuedBackgroundAction(data->dodger->timeline, &Welcome, NULL, 0, "welcome");
TM_AddDelay(data->dodger->timeline, 1000);
TM_AddAction(data->dodger->timeline, &Walk, NULL, "walk");
TM_AddAction(data->dodger->timeline, &Move, NULL, "move");
TM_AddAction(data->dodger->timeline, &Stop, NULL, "stop");
TM_AddDelay(data->dodger->timeline, 1000);
TM_AddAction(data->dodger->timeline, &Letter, NULL, "letter");
TM_AddDelay(data->dodger->timeline, 200);
TM_AddQueuedBackgroundAction(data->dodger->timeline, &Accelerate, NULL, 0, "accelerate");
TM_AddAction(data->dodger->timeline, &Fly, NULL, "fly");
TM_AddDelay(data->dodger->timeline, 500);
/* first part gameplay goes here */
/* actions for generating obstacles should go here
* probably as regular actions. When one ends, harder one
* begins. After last one part with muffins starts. */
TM_AddAction(&GenerateObstacles, NULL, "obstacles");
TM_AddDelay(3*1000);
TM_AddAction(data->dodger->timeline, &GenerateObstacles, NULL, "obstacles");
TM_AddDelay(data->dodger->timeline, 3*1000);
/* wings disappear, deccelerate */
TM_AddAction(&Run, NULL, "run");
TM_AddDelay(3*1000);
TM_AddAction(data->dodger->timeline, &Run, NULL, "run");
TM_AddDelay(data->dodger->timeline, 3*1000);
/* show Fluttershy's house
// second part gameplay goes here
@ -61,7 +61,7 @@ void Gamestate_Start(struct Game *game, struct Level1Resources* data) {
// cutscene goes here */
TM_WrapArg(int, level, 1);
TM_AddAction(&PassLevel, TM_AddToArgs(NULL, 2, strdup("level1"), level), "passlevel");
TM_AddAction(data->dodger->timeline, &PassLevel, TM_AddToArgs(NULL, 2, strdup("level1"), level), "passlevel");
// init level specific obstacle (owl) for Dodger module
struct Obstacle *obst = malloc(sizeof(struct Obstacle));
@ -165,9 +165,8 @@ void Gamestate_PreloadBitmaps(struct Game *game, struct Level1Resources* data) {
}
struct Level1Resources* Gamestate_Load(struct Game *game) {
TM_Init(game);
struct Level1Resources *data = malloc(sizeof(struct Level1Resources));
struct Character *character = CreateCharacter(game, "derpy");
RegisterSpritesheet(game, character, "walk");
RegisterSpritesheet(game, character, "stand");
@ -176,6 +175,7 @@ struct Level1Resources* Gamestate_Load(struct Game *game) {
SelectSpritesheet(game, character, "run");
SetCharacterPosition(game, character, 0.1, 0.7, 0);
data->dodger = Dodger_Load(game, character);
data->dodger->timeline = TM_Init(game, "main");
data->failed=false;
data->cl_pos=0;
@ -196,12 +196,12 @@ void Gamestate_Draw(struct Game *game, struct Level1Resources* data) {
}
void Gamestate_Logic(struct Game *game, struct Level1Resources* data) {
TM_Process();
TM_Process(data->dodger->timeline);
Dodger_Logic(game, data->dodger);
}
void Gamestate_ProcessEvent(struct Game *game, struct Level1Resources* data, ALLEGRO_EVENT *ev) {
TM_HandleEvent(ev);
TM_HandleEvent(data->dodger->timeline, ev);
Dodger_ProcessEvent(game, data->dodger, ev);
if (ev->type == ALLEGRO_EVENT_KEY_DOWN) {
if (ev->keyboard.keycode == ALLEGRO_KEY_ESCAPE) {

View file

@ -46,7 +46,7 @@ void* Gamestate_Load(struct Game *game, void (*progress)(struct Game*)) {
(*progress)(game);
TM_WrapArg(int, level, LEVEL);
TM_AddAction(&PassLevel, TM_AddToArgs(NULL, 2, strdup(levelx), level), "passlevel");
TM_AddAction(data->moonwalk->timeline, &PassLevel, TM_AddToArgs(NULL, 2, strdup(levelx), level), "passlevel");
(*progress)(game);
data->font = al_load_ttf_font(GetDataFilePath(game, "fonts/ShadowsIntoLight.ttf"),game->viewport.height*0.09,0 );
@ -81,7 +81,7 @@ void Gamestate_Logic(struct Game *game, struct LevelXResources* data) {
}
void Gamestate_ProcessEvent(struct Game *game, struct LevelXResources* data, ALLEGRO_EVENT *ev) {
TM_HandleEvent(ev);
TM_HandleEvent(data->moonwalk->timeline, ev);
Moonwalk_ProcessEvent(game, data->moonwalk, ev);
if (ev->type == ALLEGRO_EVENT_KEY_DOWN) {
if (ev->keyboard.keycode == ALLEGRO_KEY_ESCAPE) {

View file

@ -102,7 +102,7 @@ void Dodger_Logic(struct Game *game, struct Dodger* data) {
data->failed = true;
data->handle_input = false;
data->speed_modifier = 1;
TM_AddBackgroundAction(&LevelFailed, NULL, 0, "levelfailed");
TM_AddBackgroundAction(data->timeline, &LevelFailed, NULL, 0, "levelfailed");
}
}
tmp->x -= data->speed*data->speed_modifier*tmp->speed*100*al_get_display_width(game->display)/(float)game->viewport.width;

View file

@ -67,6 +67,8 @@ struct Dodger {
ALLEGRO_BITMAP *screwball; /*!< Screwball spritesheet bitmap. */
} obst_bmps; /*!< Obstacle bitmaps. */
struct Timeline *timeline;
};
void Dodger_PreloadBitmaps(struct Game *game, struct Dodger* data);

View file

@ -58,7 +58,7 @@ bool Fly(struct Game *game, struct TM_Action *action, enum TM_ActionState state)
if (state == TM_ACTIONSTATE_START) {
// SelectDerpySpritesheet(game, "fly");
// game->level.derpy_angle = -0.15;
TM_AddBackgroundAction(&ShowMeter, NULL, 0, "showmeter");
// TM_AddBackgroundAction(&ShowMeter, NULL, 0, "showmeter");
}
else if (state == TM_ACTIONSTATE_DESTROY) {
// game->level.handle_input = true;

View file

@ -42,7 +42,7 @@ bool DoMoonwalk(struct Game *game, struct TM_Action *action, enum TM_ActionState
}
void Moonwalk_Logic(struct Game *game, struct Moonwalk *data) {
TM_Process();
TM_Process(data->timeline);
}
void Moonwalk_Draw(struct Game *game, struct Moonwalk *data) {
@ -86,8 +86,8 @@ struct Moonwalk* Moonwalk_Load(struct Game *game, int current_level) {
al_attach_sample_instance_to_mixer(data->music, game->audio.music);
al_set_sample_instance_playmode(data->music, ALLEGRO_PLAYMODE_LOOP);
TM_Init(game);
TM_AddAction(&DoMoonwalk, TM_AddToArgs(NULL, 1, data->derpy), "moonwalk");
data->timeline = TM_Init(game, "main");
TM_AddAction(data->timeline, &DoMoonwalk, TM_AddToArgs(NULL, 1, data->derpy), "moonwalk");
return data;
}
@ -100,7 +100,7 @@ void Moonwalk_Unload(struct Game *game, struct Moonwalk *data) {
unload_bitmaps(game, data);
DestroyCharacter(game, data->derpy);
free(data);
TM_Destroy();
TM_Destroy(data->timeline);
}
void Moonwalk_ProcessEvent(struct Game *game, struct Moonwalk *data, ALLEGRO_EVENT *ev) {}
@ -108,13 +108,13 @@ void Moonwalk_ProcessEvent(struct Game *game, struct Moonwalk *data, ALLEGRO_EVE
void Moonwalk_Pause(struct Game *game, struct Moonwalk *data) {
data->music_pos = al_get_sample_instance_position(data->music);
al_set_sample_instance_playing(data->music, false);
TM_Pause();
TM_Pause(data->timeline);
}
void Moonwalk_Resume(struct Game *game, struct Moonwalk *data) {
al_set_sample_instance_position(data->music, data->music_pos);
al_set_sample_instance_playing(data->music, true);
TM_Resume();
TM_Resume(data->timeline);
}
void Moonwalk_Reload(struct Game *game, struct Moonwalk *data) {

View file

@ -28,6 +28,7 @@ struct Moonwalk {
ALLEGRO_SAMPLE *sample;
ALLEGRO_SAMPLE_INSTANCE *music;
int music_pos;
struct Timeline *timeline;
};
bool DoMoonwalk(struct Game *game, struct TM_Action *action, enum TM_ActionState state);

View file

@ -22,69 +22,66 @@
#include "utils.h"
#include "timeline.h"
// FIXME: pack into Timeline structure (multipe instances support)
unsigned int lastid;
struct Game* game = NULL;
struct TM_Action *queue, *background;
void TM_Init(struct Game* g) {
PrintConsole(g, "Timeline Manager: init");
game = g;
lastid = 0;
queue = NULL;
background = NULL;
struct Timeline* TM_Init(struct Game* g, char* name) {
PrintConsole(g, "Timeline Manager[%s]: init", name);
struct Timeline* timeline = malloc(sizeof(struct Timeline));
timeline->game = g;
timeline->lastid = 0;
timeline->queue = NULL;
timeline->background = NULL;
timeline->name = strdup(name);
return timeline;
}
void TM_Process(void) {
if (!game) return;
void TM_Process(struct Timeline* timeline) {
/* process first element from queue
if returns true, delete it */
if (queue) {
if (*queue->function) {
if (!queue->active) {
PrintConsole(game, "Timeline Manager: queue: run action (%d - %s)", queue->id, queue->name);
(*queue->function)(game, queue, TM_ACTIONSTATE_START);
if (timeline->queue) {
if (*timeline->queue->function) {
if (!timeline->queue->active) {
PrintConsole(timeline->game, "Timeline Manager[%s]: queue: run action (%d - %s)", timeline->name, timeline->queue->id, timeline->queue->name);
(*timeline->queue->function)(timeline->game, timeline->queue, TM_ACTIONSTATE_START);
}
queue->active = true;
if ((*queue->function)(game, queue, TM_ACTIONSTATE_RUNNING)) {
PrintConsole(game, "Timeline Manager: queue: destroy action (%d - %s)", queue->id, queue->name);
queue->active=false;
struct TM_Action *tmp = queue;
queue = queue->next;
(*tmp->function)(game, tmp, TM_ACTIONSTATE_DESTROY);
timeline->queue->active = true;
if ((*timeline->queue->function)(timeline->game, timeline->queue, TM_ACTIONSTATE_RUNNING)) {
PrintConsole(timeline->game, "Timeline Manager[%s]: queue: destroy action (%d - %s)", timeline->name, timeline->queue->id, timeline->queue->name);
timeline->queue->active=false;
struct TM_Action *tmp = timeline->queue;
timeline->queue = timeline->queue->next;
(*tmp->function)(timeline->game, tmp, TM_ACTIONSTATE_DESTROY);
free(tmp->name);
free(tmp);
}
} else {
/* delay handling */
if (queue->active) {
struct TM_Action *tmp = queue;
queue = queue->next;
if (timeline->queue->active) {
struct TM_Action *tmp = timeline->queue;
timeline->queue = timeline->queue->next;
free(tmp->name);
free(tmp);
} else {
if (!al_get_timer_started(queue->timer)) {
PrintConsole(game, "Timeline Manager: queue: delay started %d ms (%d - %s)", queue->delay, queue->id, queue->name);
al_start_timer(queue->timer);
if (!al_get_timer_started(timeline->queue->timer)) {
PrintConsole(timeline->game, "Timeline Manager[%s]: queue: delay started %d ms (%d - %s)", timeline->name, timeline->queue->delay, timeline->queue->id, timeline->queue->name);
al_start_timer(timeline->queue->timer);
}
}
}
}
/* process all elements from background marked as active */
struct TM_Action *tmp, *tmp2, *pom = background;
struct TM_Action *tmp, *tmp2, *pom = timeline->background;
tmp = NULL;
while (pom!=NULL) {
bool destroy = false;
if (pom->active) {
if (*pom->function) {
if ((*pom->function)(game, pom, TM_ACTIONSTATE_RUNNING)) {
if ((*pom->function)(timeline->game, pom, TM_ACTIONSTATE_RUNNING)) {
pom->active=false;
PrintConsole(game, "Timeline Manager: background: destroy action (%d - %s)", pom->id, pom->name);
(*pom->function)(game, pom, TM_ACTIONSTATE_DESTROY);
PrintConsole(timeline->game, "Timeline Manager[%s]: background: destroy action (%d - %s)", timeline->name, pom->id, pom->name);
(*pom->function)(timeline->game, pom, TM_ACTIONSTATE_DESTROY);
if (tmp) {
tmp->next = pom->next;
} else {
background = pom->next;
timeline->background = pom->next;
}
destroy = true;
}
@ -93,7 +90,7 @@ void TM_Process(void) {
if (tmp) {
tmp->next = pom->next;
} else {
background = pom->next;
timeline->background = pom->next;
}
destroy = true;
}
@ -107,8 +104,8 @@ void TM_Process(void) {
free(pom);
tmp2 = tmp;
if (!tmp) {
if (background) {
pom=background->next;
if (timeline->background) {
pom=timeline->background->next;
} else {
pom=NULL;
}
@ -119,15 +116,15 @@ void TM_Process(void) {
}
}
void PauseTimers(bool pause) {
if (queue) {
if (queue->timer) {
void PauseTimers(struct Timeline* timeline, bool pause) {
if (timeline->queue) {
if (timeline->queue->timer) {
if (pause) {
al_stop_timer(queue->timer);
} else if (!queue->active) al_start_timer(queue->timer);
al_stop_timer(timeline->queue->timer);
} else if (!timeline->queue->active) al_start_timer(timeline->queue->timer);
}
}
struct TM_Action* tmp = background;
struct TM_Action* tmp = timeline->background;
while (tmp) {
if (tmp->timer) {
if (pause) {
@ -138,82 +135,80 @@ void PauseTimers(bool pause) {
}
}
void Propagate(enum TM_ActionState action) {
if (!game) return;
if (queue) {
if ((*queue->function) && (queue->active)) {
(*queue->function)(game, queue, action);
void Propagate(struct Timeline* timeline, enum TM_ActionState action) {
if (timeline->queue) {
if ((*timeline->queue->function) && (timeline->queue->active)) {
(*timeline->queue->function)(timeline->game, timeline->queue, action);
}
}
/* process all elements from background marked as active */
struct TM_Action *pom = background;
struct TM_Action *pom = timeline->background;
while (pom!=NULL) {
if (pom->active) {
if (*pom->function) {
(*pom->function)(game, pom, action);
(*pom->function)(timeline->game, pom, action);
}
}
pom = pom->next;
}
}
void TM_Draw(void) {
Propagate(TM_ACTIONSTATE_DRAW);
void TM_Draw(struct Timeline* timeline) {
Propagate(timeline, TM_ACTIONSTATE_DRAW);
}
void TM_Pause(void) {
PrintConsole(game, "Timeline Manager: Pause.");
PauseTimers(true);
Propagate(TM_ACTIONSTATE_PAUSE);
void TM_Pause(struct Timeline* timeline) {
PrintConsole(timeline->game, "Timeline Manager[%s]: Pause.", timeline->name);
PauseTimers(timeline, true);
Propagate(timeline, TM_ACTIONSTATE_PAUSE);
}
void TM_Resume(void) {
PrintConsole(game, "Timeline Manager: Resume.");
Propagate(TM_ACTIONSTATE_RESUME);
PauseTimers(false);
void TM_Resume(struct Timeline* timeline) {
PrintConsole(timeline->game, "Timeline Manager[%s]: Resume.", timeline->name);
Propagate(timeline, TM_ACTIONSTATE_RESUME);
PauseTimers(timeline, false);
}
void TM_HandleEvent(ALLEGRO_EVENT *ev) {
void TM_HandleEvent(struct Timeline* timeline, ALLEGRO_EVENT *ev) {
if (ev->type != ALLEGRO_EVENT_TIMER) return;
if (!game) return;
if (queue) {
if (ev->timer.source == queue->timer) {
queue->active=true;
al_destroy_timer(queue->timer);
queue->timer = NULL;
if (queue->function) {
PrintConsole(game, "Timeline Manager: queue: run action (%d - %s)", queue->id, queue->name);
(*queue->function)(game, queue, TM_ACTIONSTATE_START);
if (timeline->queue) {
if (ev->timer.source == timeline->queue->timer) {
timeline->queue->active=true;
al_destroy_timer(timeline->queue->timer);
timeline->queue->timer = NULL;
if (timeline->queue->function) {
PrintConsole(timeline->game, "Timeline Manager[%s]: queue: run action (%d - %s)", timeline->name, timeline->queue->id, timeline->queue->name);
(*timeline->queue->function)(timeline->game, timeline->queue, TM_ACTIONSTATE_START);
} else {
PrintConsole(game, "Timeline Manager: queue: delay reached (%d - %s)", queue->id, queue->name);
PrintConsole(timeline->game, "Timeline Manager[%s]: queue: delay reached (%d - %s)", timeline->name, timeline->queue->id, timeline->queue->name);
}
return;
}
}
struct TM_Action *pom = background;
struct TM_Action *pom = timeline->background;
while (pom) {
if (ev->timer.source == pom->timer) {
PrintConsole(game, "Timeline Manager: background: delay reached, run action (%d - %s)", pom->id, pom->name);
PrintConsole(timeline->game, "Timeline Manager[%s]: background: delay reached, run action (%d - %s)", timeline->name, pom->id, pom->name);
pom->active=true;
al_destroy_timer(pom->timer);
pom->timer = NULL;
(*pom->function)(game, pom, TM_ACTIONSTATE_START);
(*pom->function)(timeline->game, pom, TM_ACTIONSTATE_START);
return;
}
pom=pom->next;
}
}
struct TM_Action* TM_AddAction(bool (*func)(struct Game*, struct TM_Action*, enum TM_ActionState), struct TM_Arguments* args, char* name) {
struct TM_Action* TM_AddAction(struct Timeline* timeline, bool (*func)(struct Game*, struct TM_Action*, enum TM_ActionState), struct TM_Arguments* args, char* name) {
struct TM_Action *action = malloc(sizeof(struct TM_Action));
if (queue) {
struct TM_Action *pom = queue;
if (timeline->queue) {
struct TM_Action *pom = timeline->queue;
while (pom->next!=NULL) {
pom=pom->next;
}
pom->next = action;
} else {
queue = action;
timeline->queue = action;
}
action->next = NULL;
action->function = func;
@ -222,45 +217,45 @@ struct TM_Action* TM_AddAction(bool (*func)(struct Game*, struct TM_Action*, enu
action->timer = NULL;
action->active = false;
action->delay = 0;
action->id = ++lastid;
action->id = ++timeline->lastid;
if (action->function) {
PrintConsole(game, "Timeline Manager: queue: init action (%d - %s)", action->id, action->name);
(*action->function)(game, action, TM_ACTIONSTATE_INIT);
PrintConsole(timeline->game, "Timeline Manager[%s]: queue: init action (%d - %s)", timeline->name, action->id, action->name);
(*action->function)(timeline->game, action, TM_ACTIONSTATE_INIT);
}
return action;
}
struct TM_Action* TM_AddBackgroundAction(bool (*func)(struct Game*, struct TM_Action*, enum TM_ActionState), struct TM_Arguments* args, int delay, char* name) {
struct TM_Action* TM_AddBackgroundAction(struct Timeline* timeline, bool (*func)(struct Game*, struct TM_Action*, enum TM_ActionState), struct TM_Arguments* args, int delay, char* name) {
struct TM_Action *action = malloc(sizeof(struct TM_Action));
if (background) {
struct TM_Action *pom = background;
if (timeline->background) {
struct TM_Action *pom = timeline->background;
while (pom->next!=NULL) {
pom=pom->next;
}
pom->next = action;
} else {
background = action;
timeline->background = action;
}
action->next = NULL;
action->function = func;
action->arguments = args;
action->name = strdup(name);
action->delay = delay;
action->id = ++lastid;
action->id = ++timeline->lastid;
if (delay) {
PrintConsole(game, "Timeline Manager: background: init action with delay %d ms (%d - %s)", delay, action->id, action->name);
(*action->function)(game, action, TM_ACTIONSTATE_INIT);
PrintConsole(timeline->game, "Timeline Manager[%s]: background: init action with delay %d ms (%d - %s)", timeline->name, delay, action->id, action->name);
(*action->function)(timeline->game, action, TM_ACTIONSTATE_INIT);
action->active = false;
action->timer = al_create_timer(delay/1000.0);
al_register_event_source(game->_priv.event_queue, al_get_timer_event_source(action->timer));
al_register_event_source(timeline->game->_priv.event_queue, al_get_timer_event_source(action->timer));
al_start_timer(action->timer);
} else {
PrintConsole(game, "Timeline Manager: background: init action (%d - %s)", action->id, action->name);
(*action->function)(game, action, TM_ACTIONSTATE_INIT);
PrintConsole(timeline->game, "Timeline Manager[%s]: background: init action (%d - %s)", timeline->name, action->id, action->name);
(*action->function)(timeline->game, action, TM_ACTIONSTATE_INIT);
action->timer = NULL;
action->active = true;
PrintConsole(game, "Timeline Manager: background: run action (%d - %s)", action->id, action->name);
(*action->function)(game, action, TM_ACTIONSTATE_START);
PrintConsole(timeline->game, "Timeline Manager[%s]: background: run action (%d - %s)", timeline->name, action->id, action->name);
(*action->function)(timeline->game, action, TM_ACTIONSTATE_START);
}
return action;
}
@ -270,38 +265,38 @@ bool runinbackground(struct Game* game, struct TM_Action* action, enum TM_Action
if (state != TM_ACTIONSTATE_RUNNING) return false;
int* delay = (int*) action->arguments->next->value;
char* name = (char*) action->arguments->next->next->value;
TM_AddBackgroundAction(action->arguments->value, action->arguments->next->next->next, *delay, name);
struct Timeline *timeline = (struct Timeline*) action->arguments->next->next->next->value;
TM_AddBackgroundAction(timeline, action->arguments->value, action->arguments->next->next->next->next, *delay, name);
free(name);
return true;
}
struct TM_Action* TM_AddQueuedBackgroundAction(bool (*func)(struct Game*, struct TM_Action*, enum TM_ActionState), struct TM_Arguments* args, int delay, char* name) {
struct TM_Action* TM_AddQueuedBackgroundAction(struct Timeline* timeline, bool (*func)(struct Game*, struct TM_Action*, enum TM_ActionState), struct TM_Arguments* args, int delay, char* name) {
TM_WrapArg(int, del, delay);
struct TM_Arguments* arguments = TM_AddToArgs(NULL, 3, (void*) func, del, strdup(name));
arguments->next->next->next = args;
return TM_AddAction(*runinbackground, arguments, "TM_BackgroundAction");
struct TM_Arguments* arguments = TM_AddToArgs(NULL, 4, (void*) func, del, strdup(name), (void*) timeline);
arguments->next->next->next->next = args;
return TM_AddAction(timeline, *runinbackground, arguments, "TM_BackgroundAction");
}
void TM_AddDelay(int delay) {
void TM_AddDelay(struct Timeline* timeline, int delay) {
/*int *tmp;
tmp = malloc(sizeof(int));
*tmp = delay;
TM_AddAction(NULL, TM_AddToArgs(NULL, tmp));*/
struct TM_Action* tmp = TM_AddAction(NULL, NULL, "TM_Delay");
PrintConsole(game, "Timeline Manager: queue: adding delay %d ms (%d)", delay, tmp->id);
struct TM_Action* tmp = TM_AddAction(timeline, NULL, NULL, "TM_Delay");
PrintConsole(timeline->game, "Timeline Manager[%s]: queue: adding delay %d ms (%d)", timeline->name, delay, tmp->id);
tmp->delay = delay;
tmp->timer = al_create_timer(delay/1000.0);
al_register_event_source(game->_priv.event_queue, al_get_timer_event_source(tmp->timer));
al_register_event_source(timeline->game->_priv.event_queue, al_get_timer_event_source(tmp->timer));
}
void TM_Destroy(void) {
if (!game) return;
PrintConsole(game, "Timeline Manager: destroy");
struct TM_Action *tmp, *tmp2, *pom = queue;
void TM_Destroy(struct Timeline* timeline) {
PrintConsole(timeline->game, "Timeline Manager[%s]: destroy", timeline->name);
struct TM_Action *tmp, *tmp2, *pom = timeline->queue;
tmp = NULL;
while (pom!=NULL) {
if (pom->active) {
if (*pom->function) (*pom->function)(game, pom, TM_ACTIONSTATE_DESTROY);
if (*pom->function) (*pom->function)(timeline->game, pom, TM_ACTIONSTATE_DESTROY);
else {
if (pom->timer) al_destroy_timer(pom->timer);
}
@ -316,16 +311,16 @@ void TM_Destroy(void) {
free(pom->name);
free(pom);
tmp2 = tmp;
if (!tmp) pom=background->next;
if (!tmp) pom=timeline->background->next;
else pom=tmp->next;
tmp = tmp2;
}
}
tmp = NULL;
pom=background;
pom=timeline->background;
while (pom!=NULL) {
if (pom->active) {
if (*pom->function) (*pom->function)(game, pom, TM_ACTIONSTATE_DESTROY);
if (*pom->function) (*pom->function)(timeline->game, pom, TM_ACTIONSTATE_DESTROY);
else {
if (pom->timer) al_destroy_timer(pom->timer);
}
@ -340,13 +335,14 @@ void TM_Destroy(void) {
free(pom->name);
free(pom);
tmp2 = tmp;
if (!tmp) pom=background->next;
if (!tmp) pom=timeline->background->next;
else pom=tmp->next;
tmp = tmp2;
}
}
game = NULL;
free(timeline->name);
free(timeline);
}
struct TM_Arguments* TM_AddToArgs(struct TM_Arguments* args, int num, ...) {
@ -382,8 +378,3 @@ void TM_DestroyArgs(struct TM_Arguments* args) {
args = pom;
}
}
bool TM_Initialized(void) {
if (game) return true;
return false;
}

View file

@ -37,6 +37,15 @@ enum TM_ActionState {
TM_ACTIONSTATE_RESUME
};
/*! \brief Timeline structure. */
struct Timeline {
struct TM_Action *queue; /*!< Main timeline queue. */
struct TM_Action *background; /*!< Background queue. */
char* name; /*!< Name of the timeline. */
unsigned int lastid; /*!< Last ID given to timeline action. */
struct Game* game; /*!< Reference to the game object. */
};
/*! \brief Arguments for TM_Action. */
struct TM_Arguments {
void *value; /*!< Value of argument. */
@ -56,32 +65,30 @@ struct TM_Action {
};
/*! \brief Init timeline. */
void TM_Init(struct Game* game);
struct Timeline* TM_Init(struct Game* game, char* name);
/*! \brief Process current timeline actions. */
void TM_Process(void);
void TM_Process(struct Timeline*);
/*! \brief Ask current timeline actions to draw. */
void TM_Draw(void);
/*! \brief Pauses timeline. */
void TM_Pause(void);
/*! \brief Resumes timeline. */
void TM_Resume(void);
void TM_Draw(struct Timeline*);
/*! \brief Pauses the timeline. */
void TM_Pause(struct Timeline*);
/*! \brief Resumes the timeline. */
void TM_Resume(struct Timeline*);
/*! \brief Handle timer events. */
void TM_HandleEvent(ALLEGRO_EVENT *ev);
void TM_HandleEvent(struct Timeline*, ALLEGRO_EVENT *ev);
/*! \brief Add new action to main queue. */
struct TM_Action* TM_AddAction(bool (*func)(struct Game*, struct TM_Action*, enum TM_ActionState), struct TM_Arguments* args, char* name);
struct TM_Action* TM_AddAction(struct Timeline*, bool (*func)(struct Game*, struct TM_Action*, enum TM_ActionState), struct TM_Arguments* args, char* name);
/*! \brief Add new action to background queue. */
struct TM_Action* TM_AddBackgroundAction(bool (*func)(struct Game*, struct TM_Action*, enum TM_ActionState), struct TM_Arguments* args, int delay, char* name);
struct TM_Action* TM_AddBackgroundAction(struct Timeline*, bool (*func)(struct Game*, struct TM_Action*, enum TM_ActionState), struct TM_Arguments* args, int delay, char* name);
/*! \brief Add new action to main queue, which adds specified action into background queue. */
struct TM_Action* TM_AddQueuedBackgroundAction(bool (*func)(struct Game*, struct TM_Action*, enum TM_ActionState), struct TM_Arguments* args, int delay, char* name);
struct TM_Action* TM_AddQueuedBackgroundAction(struct Timeline*, bool (*func)(struct Game*, struct TM_Action*, enum TM_ActionState), struct TM_Arguments* args, int delay, char* name);
/*! \brief Add delay to main queue. */
void TM_AddDelay(int delay);
void TM_AddDelay(struct Timeline*, int delay);
/*! \brief Destroy timeline. */
void TM_Destroy(void);
void TM_Destroy(struct Timeline*);
/*! \brief Add data to TM_Arguments queue. */
struct TM_Arguments* TM_AddToArgs(struct TM_Arguments* args, int num, ...);
/*! \brief Destroy TM_Arguments queue. */
void TM_DestroyArgs(struct TM_Arguments* args);
/*! \brief Check if timeline is initialised. */
bool TM_Initialized(void);
#endif