naev 0.12.6
gui_omsg.c
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
5#include <stdlib.h>
6
7#include "naev.h"
9
10#include "gui_omsg.h"
11
12#include "array.h"
13#include "font.h"
14#include "log.h"
15#include "ndata.h"
16#include "nstring.h"
17#include "opengl.h"
18
22typedef struct omsg_font_s {
23 int size;
26static omsg_font_t *omsg_font_array = NULL;
27
31typedef struct omsg_s {
32 unsigned int id;
33 char **msg;
34 double duration;
35 int font;
36 glColour col;
37} omsg_t;
38static omsg_t *omsg_array = NULL;
39static unsigned int omsg_idgen = 0;
40
41static double omsg_center_x = 0.;
42static double omsg_center_y = 0.;
43static double omsg_center_w = 100.;
44
45/*
46 * Prototypes.
47 */
48static omsg_t *omsg_get( unsigned int id );
49static void omsg_free( omsg_t *omsg );
50static void omsg_setMsg( omsg_t *omsg, const char *msg );
51static int omsg_getFontID( int size );
52static glFont *omsg_getFont( int font );
53
57static omsg_t *omsg_get( unsigned int id )
58{
59 for ( int i = 0; i < array_size( omsg_array ); i++ )
60 if ( omsg_array[i].id == id )
61 return &omsg_array[i];
62 return NULL;
63}
64
68static void omsg_free( omsg_t *omsg )
69{
70 for ( int i = 0; i < array_size( omsg->msg ); i++ )
71 free( omsg->msg[i] );
72 array_free( omsg->msg );
73 omsg->msg = NULL;
74}
75
79static void omsg_setMsg( omsg_t *omsg, const char *msg )
80{
81 glFont *font;
83
84 /* Clean up after old stuff. */
85 omsg_free( omsg );
86
87 /* Create data. */
88 font = omsg_getFont( omsg->font );
89
90 omsg->msg = array_create( char * );
91 gl_printLineIteratorInit( &iter, font, msg, omsg_center_w );
92 while ( gl_printLineIteratorNext( &iter ) )
93 array_push_back( &omsg->msg, strndup( &iter.text[iter.l_begin],
94 iter.l_end - iter.l_begin ) );
95}
96
100static int omsg_getFontID( int size )
101{
102 omsg_font_t *font;
103
104 /* Create array if not done so yet. */
105 if ( omsg_font_array == NULL )
106 omsg_font_array = array_create( omsg_font_t );
107
108 /* Try to match. */
109 for ( int i = 0; i < array_size( omsg_font_array ); i++ )
110 if ( size == omsg_font_array[i].size )
111 return i;
112
113 /* Create font. */
114 font = &array_grow( &omsg_font_array );
115 gl_fontInit( &font->font, _( FONT_MONOSPACE_PATH ), size, FONT_PATH_PREFIX,
116 0 );
117 font->size = size;
118 return array_size( omsg_font_array ) - 1;
119}
120
124static glFont *omsg_getFont( int font )
125{
126 return &omsg_font_array[font].font;
127}
128
136void omsg_position( double center_x, double center_y, double width )
137{
138 omsg_center_x = center_x;
139 omsg_center_y = center_y;
140 omsg_center_w = width;
141}
142
146void omsg_cleanup( void )
147{
148 /* Free fonts. */
149 for ( int i = 0; i < array_size( omsg_font_array ); i++ )
150 gl_freeFont( &omsg_font_array[i].font );
151 array_free( omsg_font_array );
152 omsg_font_array = NULL;
153
154 /* Destroy messages. */
155 for ( int i = 0; i < array_size( omsg_array ); i++ )
156 omsg_free( &omsg_array[i] );
157 array_free( omsg_array );
158 omsg_array = NULL;
159}
160
164void omsg_render( double dt )
165{
166 double x, y;
167
168 /* Case nothing to do. */
169 if ( omsg_array == NULL )
170 return;
171
172 /* Center. */
173 x = omsg_center_x - omsg_center_w / 2.;
174 y = omsg_center_y;
175
176 /* Render. */
177 for ( int i = 0; i < array_size( omsg_array ); i++ ) {
178 omsg_t *omsg = &omsg_array[i];
179
180 /* Render. */
181 glFont *font = omsg_getFont( omsg->font );
182 glColour col = omsg->col;
183 if ( omsg->duration < 1. )
184 col.a = omsg->duration;
186 for ( int j = 0; j < array_size( omsg->msg ); j++ ) {
187 y -= font->h * 1.5;
189 gl_printMidRaw( font, omsg_center_w, x, y, &col, -1., omsg->msg[j] );
190 }
191
192 /* Check if time to erase. */
193 omsg->duration -= dt;
194 if ( omsg->duration < 0. ) {
195 omsg_free( omsg );
196 array_erase( &omsg_array, &omsg[0], &omsg[1] );
197 i--;
198 continue;
199 }
200 }
201}
202
212unsigned int omsg_add( const char *msg, double duration, int fontsize,
213 const glColour *col )
214{
215 omsg_t *omsg;
216 int font;
217
218 /* Create if necessary. */
219 if ( omsg_array == NULL )
220 omsg_array = array_create( omsg_t );
221
222 /* Get font size. */
223 font = omsg_getFontID( fontsize );
224
225 /* Create the message. */
226 omsg = &array_grow( &omsg_array );
227 memset( omsg, 0, sizeof( omsg_t ) );
228 omsg->id = ++omsg_idgen;
229 omsg->duration = duration;
230 omsg->font = font;
231 omsg->col = *col;
232 omsg_setMsg( omsg, msg );
233
234 return omsg->id;
235}
236
245int omsg_change( unsigned int id, const char *msg, double duration )
246{
247 omsg_t *omsg = omsg_get( id );
248 if ( omsg == NULL )
249 return -1;
250
251 omsg_setMsg( omsg, msg );
252 omsg->duration = duration;
253 return 0;
254}
255
262int omsg_exists( unsigned int id )
263{
264 return ( omsg_get( id ) != NULL );
265}
266
272void omsg_rm( unsigned int id )
273{
274 omsg_t *omsg = omsg_get( id );
275 if ( omsg == NULL )
276 return;
277
278 /* Destroy. */
279 omsg_free( omsg );
280 array_erase( &omsg_array, &omsg[0], &omsg[1] );
281}
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
Definition array.h:170
#define array_erase(ptr_array, first, last)
Erases elements in interval [first, last).
Definition array.h:148
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition array.h:179
#define array_grow(ptr_array)
Increases the number of elements by one and returns the last element.
Definition array.h:122
#define array_push_back(ptr_array, element)
Adds a new element at the end of the array.
Definition array.h:134
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
Definition array.h:93
void gl_printRestoreClear(void)
Clears the restoration.
Definition font.c:398
int gl_printLineIteratorNext(glPrintLineIterator *iter)
Updates iter with the next line's information.
Definition font.c:550
int gl_printMidRaw(const glFont *ft_font, int width, double x, double y, const glColour *c, double outlineR, const char *text)
Displays text centered in position and width.
Definition font.c:821
void gl_freeFont(glFont *font)
Frees a loaded font. Caution: its glFontStash still has a slot in avail_fonts. At the time of writing...
Definition font.c:1881
void gl_printLineIteratorInit(glPrintLineIterator *iter, const glFont *ft_font, const char *text, int width)
Initialize an iterator object for breaking text into lines.
Definition font.c:528
int gl_fontInit(glFont *font, const char *fname, const unsigned int h, const char *prefix, unsigned int flags)
Initializes a font.
Definition font.c:1670
void gl_printRestoreLast(void)
Restores last colour.
Definition font.c:406
Header file with generic functions and naev-specifics.
char * strndup(const char *s, size_t n)
Return a pointer to a new string, which is a duplicate of the string s (or, if necessary,...
Definition nstring.c:69
Represents a font in memory.
Definition font.h:17
int h
Definition font.h:19
The state of a line iteration. This matches the process of rendering text into an on-screen box: An e...
Definition font.h:44
const char * text
Definition font.h:45
Fonts.
Definition gui_omsg.c:22
glFont font
Definition gui_omsg.c:24
Message struct.
Definition gui_omsg.c:31
double duration
Definition gui_omsg.c:34
glColour col
Definition gui_omsg.c:36
int font
Definition gui_omsg.c:35
char ** msg
Definition gui_omsg.c:33
unsigned int id
Definition gui_omsg.c:32