38static unsigned int osd_idgen = 0;
39static OSD_t *osd_list = NULL;
48static int osd_lines = 0;
50static int osd_tabLen = 0;
51static int osd_hyphenLen = 0;
56static OSD_t *osd_get(
unsigned int osd );
57static int osd_free(
OSD_t *osd );
58static void osd_calcDimensions (
void);
60static int osd_sortCompare(
const void * arg1,
const void * arg2 );
61static void osd_sort (
void);
62static void osd_wordwrap(
OSD_t* osd );
64static int osd_sortCompare(
const void *arg1,
const void *arg2 )
66 const OSD_t *osd1, *osd2;
85 for (
int i=0; i<m; i++) {
86 ret = strcmp( osd1->
msg[i], osd2->
msg[i] );
98 if (osd1->
id > osd2->
id)
100 else if (osd1->
id < osd2->
id)
108static void osd_sort (
void)
110 qsort( osd_list,
array_size(osd_list),
sizeof(
OSD_t), osd_sortCompare );
121unsigned int osd_create(
const char *title,
int nitems,
const char **items,
int priority )
127 if (osd_list == NULL)
130 memset( osd, 0,
sizeof(
OSD_t) );
131 osd->
id =
id = ++osd_idgen;
135 osd->
title = strdup(title);
140 for (
int i=0; i<nitems; i++) {
147 osd_calcDimensions();
155void osd_wordwrap(
OSD_t* osd )
166 int chunk_len = iter.
l_end - iter.l_begin + 1;
167 char *chunk = malloc( chunk_len );
168 snprintf( chunk, chunk_len,
"%s", &iter.
text[iter.l_begin] );
174 int msg_len, w, has_tab;
175 const char *chunk_fmt;
177 free(osd->
items[i][l]);
180 msg_len = strlen(osd->
msg[i]);
185 has_tab = !!(osd->
msg[i][0] ==
'\t');
186 w = osd_w - (has_tab ? osd_tabLen : osd_hyphenLen);
188 chunk_fmt = has_tab ?
" %s" :
"- %s";
192 int chunk_len = iter.
l_end - iter.l_begin + strlen( chunk_fmt ) - 1;
193 char *chunk = malloc( chunk_len );
194 snprintf( chunk, chunk_len, chunk_fmt, &iter.
text[iter.l_begin] );
196 chunk_fmt = has_tab ?
" %s" :
"%s";
197 iter.
width = has_tab ? osd_w - osd_tabLen - osd_hyphenLen : osd_w - osd_hyphenLen;
207static OSD_t *osd_get(
unsigned int osd )
210 OSD_t *ll = &osd_list[i];
214 WARN(_(
"OSD '%d' not found."), osd);
221static int osd_free(
OSD_t *osd )
227 free(osd->
items[i][j]);
244int osd_destroy(
unsigned int osd )
246 for (
int i=0; i<
array_size( osd_list ); i++) {
247 OSD_t *ll = &osd_list[i];
252 osd_free( &osd_list[i] );
255 array_erase( &osd_list, &osd_list[i], &osd_list[i+1] );
258 osd_calcDimensions();
268 WARN(_(
"OSD '%u' not found to destroy."), osd );
279int osd_active(
unsigned int osd,
int msg )
281 OSD_t *o = osd_get(osd);
291 osd_calcDimensions();
301int osd_getActive(
unsigned int osd )
303 OSD_t *o = osd_get(osd);
318int osd_setup(
int x,
int y,
int w,
int h )
321 int must_rewrap = (osd_w != w) && (osd_list != NULL);
334 osd_wordwrap( &osd_list[i] );
335 osd_calcDimensions();
346 OSD_t *ll = &osd_list[i];
357void osd_render (
void)
361 char title[STRMAX_SHORT];
364 if (osd_list == NULL)
368 gl_renderRect( osd_x-5., osd_y-(osd_rh+5.), osd_w+10., osd_rh+10, &cBlackHilight );
375 OSD_t *ll = &osd_list[k];
386 snprintf( title,
sizeof(title),
"%s #b(%dx)#0", ll->
titlew[i], ll->
duplicates+1 );
399 const glColour *
c = (i == (int)ll->
active) ? &cFontWhite : &cFontGrey;
404 x = osd_x + osd_hyphenLen;
417static void osd_calcDimensions (
void)
422 if (osd_list == NULL)
427 OSD_t *ll = &osd_list[k];
436 OSD_t *ll = &osd_list[k];
443 for (
int m=k+1; m<
array_size(osd_list); m++) {
444 OSD_t *lm = &osd_list[m];
449 int is_duplicate = 1;
453 if (strcmp(lm->
items[i][j], ll->
items[i][j]) != 0 ) {
481 osd_rh =
MIN( len, osd_h );
490char *osd_getTitle(
unsigned int osd )
492 OSD_t *o = osd_get(osd);
505char **osd_getItems(
unsigned int osd )
507 OSD_t *o = osd_get(osd);
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
#define array_resize(ptr_array, new_size)
Resizes the array to accomodate new_size elements.
#define array_create_size(basic_type, capacity)
Creates a new dynamic array of ‘basic_type’ with an initial capacity.
#define array_erase(ptr_array, first, last)
Erases elements in interval [first, last).
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
#define array_grow(ptr_array)
Increases the number of elements by one and returns the last element.
#define array_push_back(ptr_array, element)
Adds a new element at the end of the array.
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
int gl_printLineIteratorNext(glPrintLineIterator *iter)
Updates iter with the next line's information.
void gl_printRaw(const glFont *ft_font, double x, double y, const glColour *c, double outlineR, const char *text)
Prints text on screen.
int gl_printWidthRaw(const glFont *ft_font, const char *text)
Gets the width that it would take to print some text.
void gl_printLineIteratorInit(glPrintLineIterator *iter, const glFont *ft_font, const char *text, int width)
Initialize an iterator object for breaking text into lines.
int gl_printMaxRaw(const glFont *ft_font, const int max, double x, double y, const glColour *c, double outlineR, const char *text)
Behaves like gl_printRaw but stops displaying text after a certain distance.
Header file with generic functions and naev-specifics.
void gl_renderRect(double x, double y, double w, double h, const glColour *c)
Renders a rectangle.
On Screen Display element.
The state of a line iteration. This matches the process of rendering text into an on-screen box: An e...