From 3fe7df2982793f7b62dfac9449749e66a16fc747 Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Mon, 7 Aug 2017 02:26:36 +0200 Subject: [PATCH] timeline: make debug draw optional and automatic --- src/internal.c | 79 +++++++++++++++++++++++++++++++++++++++++++++ src/internal.h | 3 ++ src/libsuperderpy.c | 7 +++- src/libsuperderpy.h | 3 +- src/timeline.c | 56 +++----------------------------- src/timeline.h | 2 -- 6 files changed, 95 insertions(+), 55 deletions(-) diff --git a/src/internal.c b/src/internal.c index e8f783f..b092fab 100644 --- a/src/internal.c +++ b/src/internal.c @@ -114,6 +114,7 @@ SYMBOL_INTERNAL void DrawConsole(struct Game *game) { } game->_priv.fps_count.frames_done++; + DrawTimelines(game); } SYMBOL_INTERNAL void Console_Load(struct Game *game) { @@ -208,6 +209,28 @@ SYMBOL_INTERNAL void ClearGarbage(struct Game *game) { } } +SYMBOL_INTERNAL void AddTimeline(struct Game *game, struct Timeline *timeline) { + game->_priv.timelines = AddToList(game->_priv.timelines, timeline); +} + +SYMBOL_INTERNAL void RemoveTimeline(struct Game *game, struct Timeline *timeline) { + struct libsuperderpy_list *tmp = game->_priv.timelines; + if (tmp->data == timeline) { + struct libsuperderpy_list *next = tmp->next; + free(tmp); + game->_priv.timelines = next; + return; + } + while (tmp->next) { + if (tmp->next->data == timeline) { + struct libsuperderpy_list *next = tmp->next->next; + free(tmp->next); + tmp->next = next; + return; + } + } +} + SYMBOL_INTERNAL void ClearScreen(struct Game *game) { ALLEGRO_TRANSFORM identity; int clipX, clipY, clipWidth, clipHeight; @@ -220,3 +243,59 @@ SYMBOL_INTERNAL void ClearScreen(struct Game *game) { al_use_transform(&game->projection); al_set_clipping_rectangle(clipX, clipY, clipWidth, clipHeight); } + +SYMBOL_INTERNAL void DrawQueue(struct Game *game, struct TM_Action* queue, int clipX, int clipY) { + + int pos = clipX; + + struct TM_Action *pom = queue; + while (pom!=NULL) { + + int width = al_get_text_width(game->_priv.font_console, pom->name); + al_draw_filled_rectangle(pos-(10/3200.0)*game->viewport.width, clipY, pos+width+(10/3200.0)*game->viewport.width, clipY+ (60/1800.0)*game->viewport.height, pom->active ? al_map_rgba(255,255,255,192) : al_map_rgba(0, 0, 0, 0) ); + al_draw_rectangle(pos-(10/3200.0)*game->viewport.width, clipY, pos+width+(10/3200.0)*game->viewport.width, clipY+ (60/1800.0)*game->viewport.height, al_map_rgb(255,255,255), 2); + al_draw_text(game->_priv.font_console, pom->active ? al_map_rgb(0,0,0) : al_map_rgb(255,255,255), pos, clipY, ALLEGRO_ALIGN_LEFT, pom->name); + + if (pom->delay) { + al_draw_textf(game->_priv.font_console, al_map_rgb(255,255,255), pos, clipY - (50/1800.0)*game->viewport.height, ALLEGRO_ALIGN_LEFT, "%d", pom->delay); + } + + if (strncmp(pom->name, "TM_BackgroundAction", 19) == 0) { + al_draw_textf(game->_priv.font_console, al_map_rgb(255,255,255), pos, clipY - (50/1800.0)*game->viewport.height, ALLEGRO_ALIGN_LEFT, "%s", (char*)pom->arguments->next->next->value); + } + + pos += width + (20/3200.0)*game->viewport.width; + pom = pom->next; + } +} + +SYMBOL_INTERNAL void DrawTimeline(struct Game *game, struct Timeline* timeline, int pos) { + al_set_target_backbuffer(game->display); + ALLEGRO_TRANSFORM trans; + al_identity_transform(&trans); + int clipX, clipY, clipWidth, clipHeight; + al_get_clipping_rectangle(&clipX, &clipY, &clipWidth, &clipHeight); + al_use_transform(&trans); + + al_draw_filled_rectangle(clipX, clipY+clipHeight-(340/1800.0)*game->viewport.height*(pos+1), clipX + clipWidth, clipY+clipHeight-(340/1800.0)*game->viewport.height*pos, al_map_rgba(0,0,0,92)); + + al_draw_textf(game->_priv.font_console, al_map_rgb(255,255,255), clipX + clipWidth / 2, clipY+clipHeight-(340/1800.0)*game->viewport.height*(pos+1) + (10/1800.0)*game->viewport.height, ALLEGRO_ALIGN_CENTER, "Timeline: %s", timeline->name); + + DrawQueue(game, timeline->queue, clipX + (25/3200.0)*game->viewport.width, clipY + clipHeight - (220/1800.0)*game->viewport.height - (340/1800.0)*game->viewport.height*pos); + DrawQueue(game, timeline->background, clipX + (25/3200.0)*game->viewport.width, clipY + clipHeight - (100/1800.0)*game->viewport.height - (340/1800.0)*game->viewport.height*pos); + + al_use_transform(&game->projection); +} + +SYMBOL_INTERNAL void DrawTimelines(struct Game *game) { + if ((!game->_priv.showconsole) || (!game->_priv.showtimeline)) { + return; + } + struct libsuperderpy_list *tmp = game->_priv.timelines; + int i=0; + while (tmp) { + DrawTimeline(game, tmp->data, i); + i++; + tmp = tmp->next; + } +} diff --git a/src/internal.h b/src/internal.h index 7308fb7..bcffb8c 100644 --- a/src/internal.h +++ b/src/internal.h @@ -55,5 +55,8 @@ void GamestateProgress(struct Game *game); void* AddGarbage(struct Game *game, void* data); void ClearGarbage(struct Game *game); void ClearScreen(struct Game *game); +void AddTimeline(struct Game *game, struct Timeline *timeline); +void RemoveTimeline(struct Game *game, struct Timeline *timeline); +void DrawTimelines(struct Game *game); #endif diff --git a/src/libsuperderpy.c b/src/libsuperderpy.c index 19dee62..bfd2f37 100644 --- a/src/libsuperderpy.c +++ b/src/libsuperderpy.c @@ -71,6 +71,7 @@ SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char* game->_priv.console_tmp = NULL; game->_priv.garbage = NULL; + game->_priv.timelines = NULL; game->eventHandler = NULL; @@ -85,6 +86,7 @@ SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char* if (game->config.height<180) game->config.height=180; game->_priv.showconsole = game->config.debug; + game->_priv.showtimeline = false; if(!al_init_image_addon()) { fprintf(stderr, "failed to initialize image addon!\n"); @@ -446,9 +448,12 @@ SYMBOL_EXPORT int libsuperderpy_run(struct Game *game) { #ifdef ALLEGRO_ANDROID else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (ev.keyboard.keycode == ALLEGRO_KEY_MENU)) { #else - else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && ((ev.keyboard.keycode == ALLEGRO_KEY_TILDE) || (ev.keyboard.keycode == ALLEGRO_KEY_BACKQUOTE))) { + else if ((ev.type == ALLEGRO_EVENT_KEY_CHAR) && ((ev.keyboard.keycode == ALLEGRO_KEY_TILDE) || (ev.keyboard.keycode == ALLEGRO_KEY_BACKQUOTE))) { #endif game->_priv.showconsole = !game->_priv.showconsole; + if (ev.keyboard.modifiers & ALLEGRO_KEYMOD_CTRL) { + game->_priv.showtimeline = game->_priv.showconsole; + } } else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (game->config.debug) && (ev.keyboard.keycode == ALLEGRO_KEY_F1)) { int i; diff --git a/src/libsuperderpy.h b/src/libsuperderpy.h index dd269df..009c3e6 100644 --- a/src/libsuperderpy.h +++ b/src/libsuperderpy.h @@ -88,6 +88,7 @@ struct Game { ALLEGRO_EVENT_QUEUE *event_queue; /*!< Main event queue. */ ALLEGRO_TIMER *timer; /*!< Main LPS (logic) timer. */ bool showconsole; /*!< If true, game console is rendered on screen. */ + bool showtimeline; struct { double old_time, fps; @@ -118,7 +119,7 @@ struct Game { struct Gamestate *current_gamestate; - struct libsuperderpy_list *garbage; + struct libsuperderpy_list *garbage, *timelines; bool draw; diff --git a/src/timeline.c b/src/timeline.c index f36dc5f..16081a3 100644 --- a/src/timeline.c +++ b/src/timeline.c @@ -22,14 +22,15 @@ #include "utils.h" #include "timeline.h" -SYMBOL_EXPORT struct Timeline* TM_Init(struct Game* g, char* name) { - PrintConsole(g, "Timeline Manager[%s]: init", name); +SYMBOL_EXPORT struct Timeline* TM_Init(struct Game* game, char* name) { + PrintConsole(game, "Timeline Manager[%s]: init", name); struct Timeline* timeline = malloc(sizeof(struct Timeline)); - timeline->game = g; + timeline->game = game; timeline->lastid = 0; timeline->queue = NULL; timeline->background = NULL; timeline->name = strdup(name); + AddTimeline(game, timeline); return timeline; } @@ -348,54 +349,6 @@ SYMBOL_EXPORT void TM_CleanBackgroundQueue(struct Timeline* timeline) { } } -SYMBOL_INTERNAL void DrawQueue(struct Game *game, struct TM_Action* queue, int clipX, int clipY) { - - int pos = clipX; - - struct TM_Action *pom = queue; - while (pom!=NULL) { - - int width = al_get_text_width(game->_priv.font_console, pom->name); - al_draw_filled_rectangle(pos-(10/3200.0)*game->viewport.width, clipY, pos+width+(10/3200.0)*game->viewport.width, clipY+ (60/1800.0)*game->viewport.height, pom->active ? al_map_rgba(255,255,255,192) : al_map_rgba(0, 0, 0, 0) ); - al_draw_rectangle(pos-(10/3200.0)*game->viewport.width, clipY, pos+width+(10/3200.0)*game->viewport.width, clipY+ (60/1800.0)*game->viewport.height, al_map_rgb(255,255,255), 2); - al_draw_text(game->_priv.font_console, pom->active ? al_map_rgb(0,0,0) : al_map_rgb(255,255,255), pos, clipY, ALLEGRO_ALIGN_LEFT, pom->name); - - if (pom->delay) { - al_draw_textf(game->_priv.font_console, al_map_rgb(255,255,255), pos, clipY - (50/1800.0)*game->viewport.height, ALLEGRO_ALIGN_LEFT, "%d", pom->delay); - } - - if (pom->function == *runinbackground) { - al_draw_textf(game->_priv.font_console, al_map_rgb(255,255,255), pos, clipY - (50/1800.0)*game->viewport.height, ALLEGRO_ALIGN_LEFT, "%s", (char*)pom->arguments->next->next->value); - } - - pos += width + (20/3200.0)*game->viewport.width; - pom = pom->next; - } -} - -SYMBOL_EXPORT void TM_DrawDebug(struct Game *game, struct Timeline* timeline, int pos) { - - if (!game->_priv.showconsole) { - return; - } - - al_set_target_backbuffer(game->display); - ALLEGRO_TRANSFORM trans; - al_identity_transform(&trans); - int clipX, clipY, clipWidth, clipHeight; - al_get_clipping_rectangle(&clipX, &clipY, &clipWidth, &clipHeight); - al_use_transform(&trans); - - al_draw_filled_rectangle(clipX, clipY+clipHeight-(340/1800.0)*game->viewport.height*(pos+1), clipX + clipWidth, clipY+clipHeight-(340/1800.0)*game->viewport.height*pos, al_map_rgba(0,0,0,92)); - - al_draw_textf(game->_priv.font_console, al_map_rgb(255,255,255), clipX + clipWidth / 2, clipY+clipHeight-(340/1800.0)*game->viewport.height*(pos+1) + (10/1800.0)*game->viewport.height, ALLEGRO_ALIGN_CENTER, "Timeline: %s", timeline->name); - - DrawQueue(game, timeline->queue, clipX + (25/3200.0)*game->viewport.width, clipY + clipHeight - (220/1800.0)*game->viewport.height - (340/1800.0)*game->viewport.height*pos); - DrawQueue(game, timeline->background, clipX + (25/3200.0)*game->viewport.width, clipY + clipHeight - (100/1800.0)*game->viewport.height - (340/1800.0)*game->viewport.height*pos); - - al_use_transform(&game->projection); -} - SYMBOL_EXPORT void TM_SkipDelay(struct Timeline* timeline) { if (timeline->queue && timeline->queue->timer) { al_stop_timer(timeline->queue->timer); @@ -412,6 +365,7 @@ SYMBOL_EXPORT bool TM_IsBackgroundEmpty(struct Timeline* timeline) { } SYMBOL_EXPORT void TM_Destroy(struct Timeline* timeline) { + RemoveTimeline(timeline->game, timeline); TM_CleanQueue(timeline); TM_CleanBackgroundQueue(timeline); PrintConsole(timeline->game, "Timeline Manager[%s]: destroy", timeline->name); diff --git a/src/timeline.h b/src/timeline.h index 72089d9..ac0b275 100644 --- a/src/timeline.h +++ b/src/timeline.h @@ -101,7 +101,5 @@ void TM_SkipDelay(struct Timeline*); bool TM_IsEmpty(struct Timeline* timeline); /*! \brief Checks if the background queue is empty */ bool TM_IsBackgroundEmpty(struct Timeline* timeline); -/*! \brief Draws debug info when console is visible */ -void TM_DrawDebug(struct Game *game, struct Timeline* timeline, int pos); #endif