3636#include "texturecache.h"
3737#include "gui_util.h"
3838
39- #define DEFAULT_LOG { NULL, LOG_LINES_COUNT, 0, 200 }
40- #define DEFAULT_EVENT_MESSAGES { NULL, 5, 0, 200 }
39+ #define DEFAULT_EVENT_MESSAGES { NULL, 5, 0, LOG_LINES_MAX_LEN }
4140
4241#define POS_Y_COLLECTABLES 64
4342#define POS_Y_XPBAR 128
4443
4544static struct LogData_t {
46- char * * log ;
47- unsigned int len ;
48- unsigned int count ;
49- unsigned int strlen ;
50- } log_data = DEFAULT_LOG ;
45+ char log [LOG_LINES_COUNT ][LOG_LINES_MAX_LEN ];
46+ uint8_t capacity ;
47+ uint8_t head ;
48+ uint8_t tail ;
49+ uint8_t count ;
50+ uint8_t strlen ;
51+ } log_data = {
52+ { "" , "" , "" , "" , "" , "" , "" , "" , "" , "" },
53+ LOG_LINES_COUNT ,
54+ 0 ,
55+ 0 ,
56+ 0 ,
57+ LOG_LINES_MAX_LEN
58+ };
5159
5260static struct GuiEventMsgs {
5361 char * * messages ;
@@ -56,19 +64,6 @@ static struct GuiEventMsgs {
5664 unsigned int strlen ;
5765} event_messages = DEFAULT_EVENT_MESSAGES ;
5866
59- static void
60- gui_malloc_log (void )
61- {
62- if (log_data .log != NULL )
63- return ;
64-
65- unsigned int i ;
66-
67- log_data .log = ec_malloc (log_data .len * sizeof (char * ));
68- for (i = 0 ; i < log_data .len ; ++ i )
69- log_data .log [i ] = NULL ;
70- }
71-
7267static void
7368gui_malloc_eventmessages (void )
7469{
@@ -273,7 +268,6 @@ gui_create(Camera *cam)
273268 POS_Y_COLLECTABLES + 32 + 5
274269 ));
275270
276- gui_malloc_log ();
277271 gui_malloc_eventmessages ();
278272
279273 init_sprites (gui , cam );
@@ -599,31 +593,32 @@ gui_reset(Gui *gui, Camera *cam)
599593void
600594gui_log (const char * fmt , ...)
601595{
602- char buffer [200 ];
603- char * new_message ;
596+ char buffer [LOG_LINES_MAX_LEN ];
597+ uint8_t next_idx ;
598+ char * next_message ;
604599 char tstamp [10 ];
605600
606601 va_list args ;
607602
608- new_message = ec_malloc (log_data .strlen * sizeof (char ));
609- timestamp (tstamp , 10 );
603+ next_idx = (uint8_t )(log_data .head + 1 ) % log_data .capacity ;
604+
605+ // Increment indexes
606+ if (log_data .count > 0 && log_data .head == log_data .tail ) {
607+ log_data .tail = (uint8_t )(log_data .tail + 1 ) % log_data .capacity ;
608+ log_data .count = log_data .capacity ;
609+ } else if (log_data .count < log_data .capacity ) {
610+ log_data .count ++ ;
611+ }
612+
613+ next_message = log_data .log [log_data .head ];
614+ log_data .head = next_idx ;
610615
616+ // Build log line
617+ timestamp (tstamp , 10 );
611618 va_start (args , fmt );
612- m_vsprintf (buffer , 200 , fmt , args );
619+ m_vsprintf (buffer , LOG_LINES_MAX_LEN , fmt , args );
613620 va_end (args );
614- m_sprintf (new_message , log_data .strlen , "%s > %s" , tstamp , buffer );
615-
616- log_data .count ++ ;
617- if (log_data .count > log_data .len ) {
618- log_data .count = log_data .len ;
619- free (log_data .log [0 ]);
620- log_data .log [0 ] = NULL ;
621- for (size_t i = 0 ; i < log_data .count - 1 ; ++ i ) {
622- log_data .log [i ] = log_data .log [i + 1 ];
623- log_data .log [i + 1 ] = NULL ;
624- }
625- }
626- log_data .log [log_data .count - 1 ] = new_message ;
621+ m_sprintf (next_message , log_data .strlen , "%s > %s" , tstamp , buffer );
627622}
628623
629624void
@@ -656,15 +651,27 @@ gui_render_tooltip(Gui *gui, Camera *cam)
656651void
657652gui_render_log (Gui * gui , Camera * cam )
658653{
659- SDL_Rect box = { 16 , 0 , 16 , 16 } ;
654+ static uint8_t last_head = 0 ;
660655
661656 sprite_render (gui -> bottomFrame , cam );
662657
663- for (Uint32 i = 0 ; i < log_data .count ; ++ i ) {
658+ // Update log textures
659+ const uint8_t visible = log_data .count ;
660+ if (log_data .head != last_head ) {
661+ for (uint8_t i = 0 ; i < visible ; ++ i ) {
662+ const uint8_t log_index = (uint8_t )((log_data .tail + i ) % log_data .capacity );
663+ Texture * t = gui -> log_lines [i ];
664+ texture_load_from_text (t , log_data .log [log_index ], C_WHITE , C_BLACK , cam -> renderer );
665+ }
666+ }
667+ last_head = log_data .head ;
668+
669+ // Render log textures
670+ SDL_Rect box = { 16 , 0 , 16 , 16 };
671+ for (uint8_t i = 0 ; i < visible ; ++ i ) {
664672 Texture * t ;
665673 box .y = 16 + ((LOG_FONT_SIZE + 5 ) * i );
666674 t = gui -> log_lines [i ];
667- texture_load_from_text (t , log_data .log [i ], C_WHITE , C_BLACK , cam -> renderer );
668675 box .w = t -> dim .width ;
669676 box .h = t -> dim .height ;
670677 texture_render (t , & box , cam );
@@ -714,25 +721,12 @@ gui_clear_message_log(void)
714721 }
715722 event_messages .count = 0 ;
716723
717- for (size_t i = 0 ; i < log_data .count ; ++ i )
718- free (log_data .log [i ]);
724+ // Don't need to clear the log buffer. Just reset the head/tail
725+ log_data .head = 0 ;
726+ log_data .tail = 0 ;
719727 log_data .count = 0 ;
720728}
721729
722- static void
723- destroy_log (void )
724- {
725- if (log_data .log == NULL )
726- return ;
727-
728- unsigned int i ;
729- for (i = 0 ; i < log_data .count ; ++ i )
730- free (log_data .log [i ]);
731-
732- free (log_data .log );
733- log_data .log = NULL ;
734- }
735-
736730static void
737731destroy_event_messages (void )
738732{
@@ -750,7 +744,6 @@ destroy_event_messages(void)
750744void
751745gui_destroy (Gui * gui )
752746{
753- destroy_log ();
754747 destroy_event_messages ();
755748
756749 timer_destroy (gui -> event_message_timer );
0 commit comments