maug
Quick and dirty C mini-augmentation library.
Loading...
Searching...
No Matches
retrogxc.h
1
2#ifndef RETROGXC_H
3#define RETROGXC_H
4
5#include <maug.h>
6
7/* TODO: Unified asset type that automatically uses RetroGXC if present and
8 * directly loads assets to handles if not.
9 *
10 * *or*
11 *
12 * Loader function that passes back a pointer to the cached object
13 * to be used with the normal functions associated with it.
14 */
15
16/* TODO: The loaders here pass path to file-loading functions. What they
17 * *should* do is open those paths into mfiles on their own, so that
18 * a shim can be inserted to force loading from arrays in memory.
19 */
20
21#define RETROGXC_PRESENT 1
22
23#ifndef RETROGXC_INITIAL_SZ
24# define RETROGXC_INITIAL_SZ 16
25#endif /* !RETROGXC_INITIAL_SZ */
26
27#ifndef RETROGXC_TRACE_LVL
28# define RETROGXC_TRACE_LVL 0
29#endif /* !RETROGXC_TRACE_LVL */
30
31#define RETROGXC_ERROR_CACHE_MISS (-1)
32
33#define RETROGXC_ASSET_TYPE_NONE 0
34#define RETROGXC_ASSET_TYPE_BITMAP 1
35#define RETROGXC_ASSET_TYPE_FONT 2
36
37#define retrogxc_load_bitmap( res_p, flags ) \
38 retrogxc_load_asset( res_p, retrogxc_loader_bitmap, NULL, flags )
39
40typedef int8_t RETROGXC_ASSET_TYPE;
41
42typedef RETROGXC_ASSET_TYPE (*retrogxc_loader)(
43 const retroflat_asset_path res_p, MAUG_MHANDLE* handle_p,
44 void* data, uint8_t flags );
45
47 uint8_t type;
48 MAUG_MHANDLE handle;
50};
51
53 uint8_t glyph_h;
54 uint16_t first_glyph;
55 uint16_t glyphs_count;
56};
57
58MERROR_RETVAL retrogxc_init();
59
60void retrogxc_clear_cache();
61
62void retrogxc_shutdown();
63
64RETROGXC_ASSET_TYPE retrogxc_loader_bitmap(
65 const retroflat_asset_path res_p, MAUG_MHANDLE* handle_p,
66 void* data, uint8_t flags );
67
68RETROGXC_ASSET_TYPE retrogxc_loader_xpm(
69 const retroflat_asset_path res_p, MAUG_MHANDLE* handle_p,
70 void* data, uint8_t flags );
71
72RETROGXC_ASSET_TYPE retrogxc_loader_font(
73 const retroflat_asset_path res_p, MAUG_MHANDLE* handle_p,
74 void* data, uint8_t flags );
75
76int16_t retrogxc_load_font(
77 const retroflat_asset_path font_name,
78 uint8_t glyph_h, uint16_t first_glyph, uint16_t glyphs_count );
79
80int16_t retrogxc_load_asset(
81 const retroflat_asset_path res_p, retrogxc_loader l, void* data,
82 uint8_t flags );
83
84MERROR_RETVAL retrogxc_blit_bitmap(
85 retroflat_blit_t* target, size_t bitmap_idx,
86 size_t s_x, size_t s_y, size_t d_x, size_t d_y,
87 size_t w, size_t h, int16_t instance );
88
89MERROR_RETVAL retrogxc_string(
90 retroflat_blit_t* target, RETROFLAT_COLOR color,
91 const char* str, size_t str_sz,
92 size_t font_idx, size_t x, size_t y,
93 size_t max_w, size_t max_h, uint8_t flags );
94
95MERROR_RETVAL retrogxc_string_sz(
96 retroflat_blit_t* target, const char* str, size_t str_sz,
97 size_t font_idx, size_t max_w, size_t max_h,
98 size_t* out_w_p, size_t* out_h_p, uint8_t flags );
99
100MERROR_RETVAL retrogxc_bitmap_wh(
101 size_t bitmap_idx, retroflat_pxxy_t* p_w, retroflat_pxxy_t* p_h );
102
103#ifdef RETROGXC_C
104
105static struct MDATA_VECTOR gs_retrogxc_bitmaps;
106
107/* === */
108
109MERROR_RETVAL retrogxc_init() {
110 MERROR_RETVAL retval = MERROR_OK;
111
112 /*
113 size_printf( RETROGXC_TRACE_LVL,
114 "asset struct", sizeof( struct RETROFLAT_CACHE_ASSET ) );
115 size_printf( RETROGXC_TRACE_LVL, "initial graphics cache",
116 sizeof( struct RETROFLAT_CACHE_ASSET ) * gs_retrogxc_sz );
117 */
118
119 return retval;
120}
121
122/* === */
123
124void retrogxc_clear_cache() {
125 size_t dropped_count = 0;
126 struct RETROFLAT_CACHE_ASSET* asset = NULL;
127 retroflat_blit_t* bitmap = NULL;
128 MERROR_RETVAL retval = MERROR_OK;
129
130 mdata_vector_lock( &gs_retrogxc_bitmaps );
131
132 while( 0 < mdata_vector_ct( &gs_retrogxc_bitmaps ) ) {
133 asset = mdata_vector_get(
134 &gs_retrogxc_bitmaps, 0, struct RETROFLAT_CACHE_ASSET );
135 assert( NULL != asset );
136
137 /* Asset-type-specific cleanup. */
138 switch( asset->type ) {
139 case RETROGXC_ASSET_TYPE_BITMAP:
140 maug_mlock( asset->handle, bitmap );
141 if( NULL != bitmap ) {
142 retroflat_2d_destroy_bitmap( bitmap );
143 }
144 maug_munlock( asset->handle, bitmap );
145 maug_mfree( asset->handle );
146 dropped_count++;
147
148 case RETROGXC_ASSET_TYPE_FONT:
149 /* Fonts are just a blob of data after a struct, so just free it! */
150 maug_mfree( asset->handle );
151 dropped_count++;
152 }
153
154 mdata_vector_unlock( &gs_retrogxc_bitmaps );
155 mdata_vector_remove( &gs_retrogxc_bitmaps, 0 );
156 mdata_vector_lock( &gs_retrogxc_bitmaps );
157 }
158
159 debug_printf( RETROGXC_TRACE_LVL,
160 "graphics cache cleared (" SIZE_T_FMT " assets)", dropped_count );
161
162cleanup:
163
164 if( MERROR_OK == retval ) {
165 mdata_vector_unlock( &gs_retrogxc_bitmaps );
166 }
167
168 return;
169}
170
171/* === */
172
173void retrogxc_shutdown() {
174 retrogxc_clear_cache();
175 mdata_vector_free( &gs_retrogxc_bitmaps );
176}
177
178/* === */
179
180RETROGXC_ASSET_TYPE retrogxc_loader_bitmap(
181 const retroflat_asset_path res_p, MAUG_MHANDLE* handle_p, void* data,
182 uint8_t flags
183) {
184 MERROR_RETVAL retval = MERROR_OK;
185 retroflat_blit_t* bitmap = NULL;
186
187 assert( (MAUG_MHANDLE)NULL == *handle_p );
188
189 *handle_p = maug_malloc( 1, sizeof( retroflat_blit_t ) );
190 maug_cleanup_if_null_alloc( MAUG_MHANDLE, *handle_p );
191
192 maug_mlock( *handle_p, bitmap );
193 maug_cleanup_if_null_alloc( retroflat_blit_t*, bitmap );
194
195 /* Load requested bitmap into the cache. */
196#ifdef RETROFLAT_XPM
197 retval = retroflat_load_xpm( res_p, bitmap, flags );
198#else
199 retval = retroflat_2d_load_bitmap( res_p, bitmap, flags );
200#endif /* RETROFLAT_XPM */
201 maug_cleanup_if_not_ok();
202
203cleanup:
204
205 if( NULL != bitmap ) {
206 maug_munlock( *handle_p, bitmap );
207 }
208
209 if( MERROR_OK == retval ) {
210 return RETROGXC_ASSET_TYPE_BITMAP;
211 } else {
212 if( NULL != *handle_p ) {
213 maug_mfree( *handle_p );
214 }
215 return RETROGXC_ASSET_TYPE_NONE;
216 }
217}
218
219/* === */
220
221#ifdef RETROFONT_PRESENT
222
223RETROGXC_ASSET_TYPE retrogxc_loader_font(
224 const retroflat_asset_path res_p, MAUG_MHANDLE* handle_p, void* data,
225 uint8_t flags
226) {
227 MERROR_RETVAL retval = MERROR_OK;
228 struct RETROGXC_FONT_PARMS* parms = (struct RETROGXC_FONT_PARMS*)data;
229
230 assert( (MAUG_MHANDLE)NULL == *handle_p );
231
232 debug_printf( 1, "loading font into cache: %s (%d, %d, %d)",
233 res_p, parms->glyph_h, parms->first_glyph, parms->glyphs_count );
234
235 retval = retrofont_load( res_p, handle_p,
236 parms->glyph_h, parms->first_glyph, parms->glyphs_count );
237 maug_cleanup_if_not_ok();
238
239cleanup:
240
241 if( MERROR_OK == retval ) {
242 return RETROGXC_ASSET_TYPE_FONT;
243 } else {
244 return RETROGXC_ASSET_TYPE_NONE;
245 }
246}
247
248#endif /* RETROFONT_PRESENT */
249
250/* === */
251
252int16_t retrogxc_load_asset(
253 const retroflat_asset_path res_p, retrogxc_loader l, void* data,
254 uint8_t flags
255) {
256 int16_t idx = RETROGXC_ERROR_CACHE_MISS,
257 i = 0;
258 struct RETROFLAT_CACHE_ASSET asset_new;
259 struct RETROFLAT_CACHE_ASSET* asset_iter = NULL;
260 RETROGXC_ASSET_TYPE asset_type = RETROGXC_ASSET_TYPE_NONE;
261 MERROR_RETVAL retval = MERROR_OK;
262
263 maug_mzero( &asset_new, sizeof( struct RETROFLAT_CACHE_ASSET ) );
264
265 if( 0 == mdata_vector_ct( &gs_retrogxc_bitmaps ) ) {
266 goto just_load_asset;
267 }
268
269 /* Try to find the bitmap already in the cache. */
270 mdata_vector_lock( &gs_retrogxc_bitmaps );
271 for( i = 0 ; mdata_vector_ct( &gs_retrogxc_bitmaps ) > (size_t)i ; i++ ) {
272 asset_iter = mdata_vector_get(
273 &gs_retrogxc_bitmaps, i, struct RETROFLAT_CACHE_ASSET );
274 assert( NULL != asset_iter );
275 debug_printf( RETROGXC_TRACE_LVL, "\"%s\" vs \"%s\"",
276 asset_iter->id, res_p );
277 if( 0 == retroflat_cmp_asset_path( asset_iter->id, res_p ) ) {
278 debug_printf( RETROGXC_TRACE_LVL,
279 "found asset \"%s\" at index %d with type %d!",
280 res_p, i, asset_iter->type );
281 idx = i;
282 mdata_vector_unlock( &gs_retrogxc_bitmaps );
283 goto cleanup;
284 }
285 }
286 mdata_vector_unlock( &gs_retrogxc_bitmaps );
287
288just_load_asset:
289
290 /* Bitmap not found. */
291 debug_printf( RETROGXC_TRACE_LVL,
292 "asset %s not found in cache; loading...", res_p );
293
294 /* Call the format-specific loader. */
295 asset_type = l( res_p, &asset_new.handle, data, flags );
296 if( RETROGXC_ASSET_TYPE_NONE != asset_type ) {
297 asset_new.type = asset_type;
298 retroflat_assign_asset_path( asset_new.id, res_p );
299 idx = mdata_vector_append(
300 &gs_retrogxc_bitmaps, &asset_new,
301 sizeof( struct RETROFLAT_CACHE_ASSET ) );
302 if( 0 > idx ) {
303 goto cleanup;
304 }
305 debug_printf( RETROGXC_TRACE_LVL,
306 "asset type %d, \"%s\" assigned cache ID: %d",
307 asset_type, res_p, idx );
308 goto cleanup;
309 }
310
311 /* Still not found! */
312 error_printf( "unable to load asset; cache full or not initialized?" );
313
314cleanup:
315
316 if( MERROR_OK != retval ) {
317 idx = retval * -1;
318 }
319
320 return idx;
321}
322
323/* === */
324
325MERROR_RETVAL retrogxc_blit_bitmap(
326 retroflat_blit_t* target, size_t bitmap_idx,
327 size_t s_x, size_t s_y, size_t d_x, size_t d_y,
328 size_t w, size_t h, int16_t instance
329) {
330 MERROR_RETVAL retval = MERROR_OK;
331 struct RETROFLAT_CACHE_ASSET* asset = NULL;
332 retroflat_blit_t* bitmap = NULL;
333
334 assert( NULL != gs_retrogxc_bitmaps.data_h );
335
336 mdata_vector_lock( &gs_retrogxc_bitmaps );
337
338 if( mdata_vector_ct( &gs_retrogxc_bitmaps ) <= bitmap_idx ) {
339 error_printf( "invalid bitmap index: " SIZE_T_FMT, bitmap_idx );
340 retval = MERROR_OVERFLOW;
341 goto cleanup;
342 }
343
344 asset = mdata_vector_get(
345 &gs_retrogxc_bitmaps, bitmap_idx, struct RETROFLAT_CACHE_ASSET );
346
347 if( RETROGXC_ASSET_TYPE_BITMAP != asset->type ) {
348 error_printf(
349 "index " SIZE_T_FMT " not present in cache or not bitmap (%d)!",
350 bitmap_idx, asset->type );
351 retval = MERROR_FILE;
352 goto cleanup;
353 }
354
355 maug_mlock( asset->handle, bitmap );
356
357 retval = retroflat_2d_blit_bitmap(
358 target, bitmap, s_x, s_y, d_x, d_y, w, h, instance );
359
360cleanup:
361
362 if( NULL != bitmap ) {
363 maug_munlock( asset->handle, bitmap );
364 }
365
366 mdata_vector_unlock( &gs_retrogxc_bitmaps );
367
368 return retval;
369}
370
371/* === */
372
373MERROR_RETVAL retrogxc_bitmap_wh(
374 size_t bitmap_idx, retroflat_pxxy_t* p_w, retroflat_pxxy_t* p_h
375) {
376 MERROR_RETVAL retval = MERROR_OK;
377 struct RETROFLAT_CACHE_ASSET* asset = NULL;
378 retroflat_blit_t* bitmap = NULL;
379
380 mdata_vector_lock( &gs_retrogxc_bitmaps );
381
382 if( mdata_vector_ct( &gs_retrogxc_bitmaps ) <= bitmap_idx ) {
383 error_printf( "invalid bitmap index: " SIZE_T_FMT, bitmap_idx );
384 retval = MERROR_OVERFLOW;
385 goto cleanup;
386 }
387
388 asset = mdata_vector_get(
389 &gs_retrogxc_bitmaps, bitmap_idx, struct RETROFLAT_CACHE_ASSET );
390
391 if( RETROGXC_ASSET_TYPE_BITMAP != asset->type ) {
392 error_printf(
393 "index " SIZE_T_FMT " not present in cache or not bitmap (%d)!",
394 bitmap_idx, asset->type );
395 retval = MERROR_FILE;
396 goto cleanup;
397 }
398
399 maug_mlock( asset->handle, bitmap );
400
401 if( NULL != p_w ) {
402 *p_w = retroflat_2d_bitmap_w( bitmap );
403 }
404
405 if( NULL != p_h ) {
406 *p_h = retroflat_2d_bitmap_h( bitmap );
407 }
408
409cleanup:
410
411 if( NULL != bitmap ) {
412 maug_munlock( asset->handle, bitmap );
413 }
414
415 mdata_vector_unlock( &gs_retrogxc_bitmaps );
416
417 return retval;
418}
419
420/* === */
421
422#ifdef RETROFONT_PRESENT
423
424int16_t retrogxc_load_font(
425 const retroflat_asset_path font_name,
426 uint8_t glyph_h, uint16_t first_glyph, uint16_t glyphs_count
427) {
428 int16_t idx = -1;
429 struct RETROGXC_FONT_PARMS parms;
430
431 parms.glyph_h = glyph_h;
432 parms.first_glyph = first_glyph;
433 parms.glyphs_count = glyphs_count;
434
435 idx = retrogxc_load_asset( font_name, retrogxc_loader_font, &parms, 0 );
436
437 return idx;
438}
439
440/* === */
441
442MERROR_RETVAL retrogxc_string(
443 retroflat_blit_t* target, RETROFLAT_COLOR color,
444 const char* str, size_t str_sz,
445 size_t font_idx, size_t x, size_t y,
446 size_t max_w, size_t max_h, uint8_t flags
447) {
448 MERROR_RETVAL retval = MERROR_OK;
449 struct RETROFLAT_CACHE_ASSET* asset = NULL;
450
451 mdata_vector_lock( &gs_retrogxc_bitmaps );
452
453 if( mdata_vector_ct( &gs_retrogxc_bitmaps ) <= font_idx ) {
454 error_printf( "invalid font index: " SIZE_T_FMT, font_idx );
455 retval = MERROR_OVERFLOW;
456 goto cleanup;
457 }
458
459 asset = mdata_vector_get(
460 &gs_retrogxc_bitmaps, font_idx, struct RETROFLAT_CACHE_ASSET );
461
462 if( RETROGXC_ASSET_TYPE_FONT != asset->type ) {
463 error_printf(
464 "index " SIZE_T_FMT " not present in cache or not font (%d)!",
465 font_idx, asset->type );
466 retval = MERROR_FILE;
467 goto cleanup;
468 }
469
470 retrofont_string(
471 target, color, str, str_sz, asset->handle, x, y, max_w, max_h, flags );
472
473cleanup:
474
475 mdata_vector_unlock( &gs_retrogxc_bitmaps );
476
477 return retval;
478}
479
480/* === */
481
482MERROR_RETVAL retrogxc_string_sz(
483 retroflat_blit_t* target, const char* str, size_t str_sz,
484 size_t font_idx, size_t max_w, size_t max_h,
485 size_t* out_w_p, size_t* out_h_p, uint8_t flags
486) {
487 MERROR_RETVAL retval = MERROR_OK;
488 struct RETROFLAT_CACHE_ASSET* asset = NULL;
489
490 mdata_vector_lock( &gs_retrogxc_bitmaps );
491
492 if( mdata_vector_ct( &gs_retrogxc_bitmaps ) <= font_idx ) {
493 error_printf( "invalid font index: " SIZE_T_FMT, font_idx );
494 retval = MERROR_OVERFLOW;
495 goto cleanup;
496 }
497
498 asset = mdata_vector_get(
499 &gs_retrogxc_bitmaps, font_idx, struct RETROFLAT_CACHE_ASSET );
500
501 if( RETROGXC_ASSET_TYPE_FONT != asset->type ) {
502 error_printf(
503 "index " SIZE_T_FMT " not present in cache or not font (%d)!",
504 font_idx, asset->type );
505 retval = MERROR_FILE;
506 goto cleanup;
507 }
508
509 retrofont_string_sz(
510 target, str, str_sz, asset->handle,
511 max_w, max_h, out_w_p, out_h_p, flags );
512
513cleanup:
514
515 mdata_vector_unlock( &gs_retrogxc_bitmaps );
516
517 return retval;
518}
519
520#endif /* RETROFONT_PRESENT */
521
522#endif /* RETROGXC_C */
523
524#endif /* !RETROGXC_H */
525
int MERROR_RETVAL
Return type indicating function returns a value from this list.
Definition merror.h:19
#define maug_mzero(ptr, sz)
Zero the block of memory pointed to by ptr.
Definition mmem.h:65
#define retroflat_cmp_asset_path(a, b)
Compare two asset paths. Return 0 if they're the same.
Definition retroflt.h:776
char retroflat_asset_path[RETROFLAT_PATH_MAX+1]
Path/name used to load an asset from disk.
Definition retroflt.h:771
int8_t RETROFLAT_COLOR
Defines an index in the platform-specific color-table.
Definition retroflt.h:325
size_t retroflat_pxxy_t
Type used for surface pixel coordinates.
Definition retroflt.h:895
A vector of uniformly-sized objects, stored contiguously.
Definition mdata.h:89
Definition retrogxc.h:46
Definition retrogxc.h:52