15#define RETROTILE_PRESENT
17typedef int16_t retrotile_coord_t;
19#ifndef RETROTILE_NAME_SZ_MAX
21# define RETROTILE_NAME_SZ_MAX 10
24#ifndef RETROTILE_PROP_NAME_SZ_MAX
26# define RETROTILE_PROP_NAME_SZ_MAX 10
29#ifndef RETROTILE_TILE_SCALE_DEFAULT
31# define RETROTILE_TILE_SCALE_DEFAULT 1.0f
34#ifndef RETROTILE_TRACE_LVL
36# define RETROTILE_TRACE_LVL 0
39#ifndef RETROTILE_VORONOI_DEFAULT_SPB
40# define RETROTILE_VORONOI_DEFAULT_SPB 8
43#ifndef RETROTILE_VORONOI_DEFAULT_DRIFT
44# define RETROTILE_VORONOI_DEFAULT_DRIFT 4
47#ifdef MPARSER_TRACE_NAMES
48# define retrotile_mstate_name( state ) gc_retrotile_mstate_names[state]
50# define retrotile_mstate_name( state ) state
58#define RETROTILE_PARSER_MODE_MAP 0
65#define RETROTILE_PARSER_MODE_DEFS 1
67#define RETROTILE_CLASS_TILE 0
68#define RETROTILE_CLASS_MOBILE 1
69#define RETROTILE_CLASS_WARP 2
70#define RETROTILE_CLASS_ITEM 3
86#define RETROTILE_TILE_FLAG_BLOCK 0x01
92#define RETROTILE_TILE_FLAG_RESERVED1 0x02
98#define RETROTILE_TILE_FLAG_RESERVED2 0x04
104#define RETROTILE_TILE_FLAG_RESERVED3 0x08
118#define RETROTILE_DS_FLAG_INIT_DATA 0x02
123#define RETROTILE_IDX_FMT "%u"
138 retrotile_coord_t warp_x;
139 retrotile_coord_t warp_y;
142 struct RETRO3DP_MODEL model;
144#ifdef RETROGXC_PRESENT
145 ssize_t image_cache_id;
155 uint16_t layer_class;
215 int16_t tiles_changed;
222#define retrotile_get_tile( tilemap, layer, x, y ) \
223 (retrotile_get_tiles_p( layer )[((y) * (tilemap)->tiles_w) + (x)])
225#define retrotile_set_tile( tilemap, layer, x, y, new_val ) \
226 (retrotile_get_tiles_p( layer )[((y) * (tilemap)->tiles_w) + (x)])
228#define retrotile_get_tiles_p( layer ) \
229 ((retroflat_tile_t*)(((uint8_t*)(layer)) + \
230 sizeof( struct RETROTILE_LAYER )))
232#define retrotile_clear_tiles( t, layer ) \
233 memset( retrotile_get_tiles_p( layer ), -1, \
234 t->tiles_w * t->tiles_h * sizeof( retroflat_tile_t ) )
242 const char* dirname,
const char* filename, MAUG_MHANDLE* p_tm_h,
243 struct MDATA_VECTOR* p_td, mparser_wait_cb_t wait_cb,
void* wait_data,
244 mparser_parse_token_cb token_cb,
void* token_cb_data, uint8_t passes );
253 mparser_wait_cb_t wait_cb;
255 retroflat_ms_t wait_last;
256 size_t layer_tile_iter;
259 size_t last_prop_name_sz;
262 size_t pass_layer_iter;
271 retrotile_tj_parse_cb tj_parse_cb;
278 void* custom_token_cb_data;
279 struct MJSON_PARSER jparser;
281 char dirname[RETROFLAT_PATH_MAX + 1];
282 uint16_t layer_class;
286#define RETROTILE_PARSER_MSTATE_TABLE( f ) \
287 f( MTILESTATE_NONE, 0, "", 0, 0 ) \
288 f( MTILESTATE_HEIGHT, 1, "height", 0 , 0 ) \
289 f( MTILESTATE_WIDTH, 2, "width", 0 , 0 ) \
290 f( MTILESTATE_LAYERS, 3, "layers", 0 , 0 ) \
291 f( MTILESTATE_LAYER_DATA, 4, "data", 15 , 0 ) \
292 f( MTILESTATE_LAYER_NAME, 5, "name", 15 , 0 ) \
293 f( MTILESTATE_TILES, 6, "tiles", 0 , 1 ) \
294 f( MTILESTATE_TILES_ID, 7, "id", 6 , 1 ) \
295 f( MTILESTATE_TILES_IMAGE, 8, "image", 6 , 1 ) \
296 f( MTILESTATE_TILESETS, 9, "tilesets", 0 , 0 ) \
297 f( MTILESTATE_TILESETS_SRC, 10, "source", 9 , 0 ) \
298 f( MTILESTATE_TILESETS_FGID, 11, "firstgid", 9 , 0 ) \
299 f( MTILESTATE_TILESETS_PROP, 12, "firstgid", 9 , 0 ) \
300 f( MTILESTATE_GRID, 13, "grid", 0 , 1 ) \
301 f( MTILESTATE_TILES_PROP, 14, "properties", 6 , 1 ) \
302 f( MTILESTATE_LAYER, 15, "layers", 3 , 0 ) \
303 f( MTILESTATE_TILES_PROP_NAME, 16, "name", 14 , 1 ) \
304 f( MTILESTATE_TILES_PROP_VAL, 17, "value", 14 , 1 ) \
305 f( MTILESTATE_PROP, 18, "properties", 0 , 0 ) \
306 f( MTILESTATE_PROP_NAME, 19, "name", 18 , 0 ) \
307 f( MTILESTATE_PROP_VAL, 20, "value", 18 , 0 ) \
308 f( MTILESTATE_LAYER_CLASS, 21, "class", 15 , 0 ) \
309 f( MTILESTATE_TILES_CLASS, 22, "type", 6 , 1 )
348 const char* dirname,
const char* filename, MAUG_MHANDLE* p_tilemap_h,
350 mparser_wait_cb_t wait_cb,
void* wait_data,
351 mparser_parse_token_cb token_cb,
void* token_cb_data, uint8_t passes );
362 void* animation_cb_data, int16_t iter );
366 uint32_t tuning,
size_t layer_idx, uint8_t flags,
void* data,
367 retrotile_ani_cb animation_cb,
void* animation_cb_data );
380 uint32_t tuning,
size_t layer_idx, uint8_t flags,
void* data,
381 retrotile_ani_cb animation_cb,
void* animation_cb_data );
395 uint32_t tuning,
size_t layer_idx, uint8_t flags,
void* data,
396 retrotile_ani_cb animation_cb,
void* animation_cb_data );
407 uint32_t tuning,
size_t layer_idx, uint8_t flags,
void* data,
408 retrotile_ani_cb animation_cb,
void* animation_cb_data );
418 uint32_t tuning,
size_t layer_idx, uint8_t flags,
void* data,
419 retrotile_ani_cb animation_cb,
void* animation_cb_data );
424 struct RETROTILE* tilemap, uint32_t layer_idx );
427 MAUG_MHANDLE* p_tilemap_h,
size_t w,
size_t h,
size_t layers_count,
428 const char* tilemap_name );
442#define retrotile_parser_mstate( parser, new_mstate ) \
443 parser->mstate = new_mstate; \
445 RETROTILE_TRACE_LVL, "parser mstate: %s", \
446 retrotile_mstate_name( parser->mstate ) );
448# define RETROTILE_PARSER_MSTATE_TABLE_CONST( name, idx, tokn, parent, m ) \
449 MAUG_CONST uint8_t SEG_MCONST name = idx;
451RETROTILE_PARSER_MSTATE_TABLE( RETROTILE_PARSER_MSTATE_TABLE_CONST )
453#ifdef MPARSER_TRACE_NAMES
454# define RETROTILE_PARSER_MSTATE_TABLE_NAME( name, idx, tokn, parent, m ) \
457static MAUG_CONST
char* SEG_MCONST gc_retrotile_mstate_names[] = {
458 RETROTILE_PARSER_MSTATE_TABLE( RETROTILE_PARSER_MSTATE_TABLE_NAME )
463# define RETROTILE_PARSER_MSTATE_TABLE_TOKEN( name, idx, tokn, parent, m ) \
466static MAUG_CONST
char* SEG_MCONST gc_retrotile_mstate_tokens[] = {
467 RETROTILE_PARSER_MSTATE_TABLE( RETROTILE_PARSER_MSTATE_TABLE_TOKEN )
471# define RETROTILE_PARSER_MSTATE_TABLE_PARNT( name, idx, tokn, parent, m ) \
474static MAUG_CONST uint8_t SEG_MCONST gc_retrotile_mstate_parents[] = {
475 RETROTILE_PARSER_MSTATE_TABLE( RETROTILE_PARSER_MSTATE_TABLE_PARNT )
479# define RETROTILE_PARSER_MSTATE_TABLE_MODE( name, idx, tokn, parent, m ) \
482static MAUG_CONST uint8_t SEG_MCONST gc_retrotile_mstate_modes[] = {
483 RETROTILE_PARSER_MSTATE_TABLE( RETROTILE_PARSER_MSTATE_TABLE_MODE )
489static void retrotile_parser_match_token(
495 while(
'\0' != gc_retrotile_mstate_tokens[j][0] ) {
498 maug_strlen( gc_retrotile_mstate_tokens[j] ) != token_sz ||
500 token, gc_retrotile_mstate_tokens[j], token_sz
511 parser->mstate != gc_retrotile_mstate_parents[j]
513#ifdef RETROTILE_TRACE_TOKENS
516 "found token \"%s\" "
517#ifdef MPARSER_TRACE_NAMES
518 "but incorrect parent %s (%d) (needs %s (%d))!",
520 "but incorrect parent %d (needs %d)!",
523#ifdef MPARSER_TRACE_NAMES
524 retrotile_mstate_name( parser->mstate ),
526 retrotile_mstate_name( gc_retrotile_mstate_parents[j] ),
527 gc_retrotile_mstate_parents[j]
530 gc_retrotile_mstate_parents[j]
537 }
else if( parser->
mode != gc_retrotile_mstate_modes[j] ) {
538#ifdef RETROTILE_TRACE_TOKENS
542 gc_retrotile_mstate_modes[j] );
549#ifdef RETROTILE_TRACE_TOKENS
552 "found token \"%s\" "
553#ifdef MPARSER_TRACE_NAMES
554 "under correct parent %s (%d)!",
556 "under correct parent %d!",
559#ifdef MPARSER_TRACE_NAMES
560 retrotile_mstate_name( parser->mstate ),
568 retrotile_parser_mstate( parser, j );
577 const char* token,
size_t token_sz,
void* parser_arg
582 size_t tileset_id_parsed = 0;
593 token, token_sz, parser_arg ))
598 if( MJSON_PSTATE_OBJECT_VAL != mjson_parser_pstate( &(parser->jparser) ) ) {
600 retrotile_parser_match_token( token, token_sz, parser );
604 if( MTILESTATE_TILES_ID == parser->mstate ) {
605 retrotile_parser_mstate( parser, MTILESTATE_TILES );
606 if( 0 == parser->pass ) {
608 tileset_id_parsed =
maug_atou32( token, token_sz, 10 );
616 assert( 0 < mdata_vector_ct( parser->p_tile_defs ) );
622 retrotile_parser_mstate( parser, MTILESTATE_TILES );
624 }
else if( MTILESTATE_TILES_IMAGE == parser->mstate ) {
625 if( 1 == parser->pass ) {
627 mdata_vector_lock( parser->p_tile_defs );
628 tile_def = mdata_vector_get(
631 assert( NULL != tile_def );
634 retroflat_assign_asset_path( tile_def->image_path, token );
640 retrotile_parser_mstate( parser, MTILESTATE_TILES );
642 }
else if( MTILESTATE_TILES_CLASS == parser->mstate ) {
643 if( 1 == parser->pass ) {
650 mdata_vector_lock( parser->p_tile_defs );
651 tile_def = mdata_vector_get(
654 assert( NULL != tile_def );
655 assert( 0 == tile_def->tile_class );
657 if( 0 == strncmp(
"mobile", token, 7 ) ) {
658 tile_def->tile_class = RETROTILE_CLASS_MOBILE;
660 "set tile " SIZE_T_FMT
" type: mobile (%u)",
663 }
else if( 0 == strncmp(
"warp", token, 5 ) ) {
664 tile_def->tile_class = RETROTILE_CLASS_WARP;
666 "set tile " SIZE_T_FMT
" type: warp (%u)",
669 }
else if( 0 == strncmp(
"item", token, 5 ) ) {
670 tile_def->tile_class = RETROTILE_CLASS_ITEM;
672 "set tile " SIZE_T_FMT
" type: item (%u)",
676 tile_def->tile_class = RETROTILE_CLASS_TILE;
678 "set tile " SIZE_T_FMT
" type: tile (%u)",
682 retrotile_parser_mstate( parser, MTILESTATE_TILES );
684 }
else if( MTILESTATE_TILES_PROP_NAME == parser->mstate ) {
688 retrotile_parser_mstate( parser, MTILESTATE_TILES_PROP );
690 }
else if( MTILESTATE_TILES_PROP_VAL == parser->mstate ) {
694 if( 1 == parser->pass ) {
695 mdata_vector_lock( parser->p_tile_defs );
696 tile_def = mdata_vector_get(
699 assert( NULL != tile_def );
704 debug_printf( 1,
"set tile " SIZE_T_FMT
" warp_dest: %s",
707 }
else if( 0 == strncmp(
"warp_x", parser->
last_prop_name, 7 ) ) {
709 debug_printf( 1,
"set tile " SIZE_T_FMT
" warp_x: %d",
712 }
else if( 0 == strncmp(
"warp_y", parser->
last_prop_name, 7 ) ) {
714 debug_printf( 1,
"set tile " SIZE_T_FMT
" warp_y: %d",
721 retrotile_parser_mstate( parser, MTILESTATE_TILES_PROP );
726 mdata_vector_unlock( parser->p_tile_defs );
728 if( MERROR_PREEMPT == retval ) {
739 const char* token,
size_t token_sz,
void* parser_arg
751 token, token_sz, parser_arg ))
756 if( MJSON_PSTATE_LIST == mjson_parser_pstate( &(parser->jparser) ) ) {
766 MTILESTATE_LAYER_DATA == parser->mstate
781 assert( NULL != parser->t );
782 tiles_layer = retrotile_get_layer_p(
783 parser->t, parser->pass_layer_iter );
784 assert( NULL != tiles_layer );
787 tiles_layer->layer_class = parser->layer_class;
789 tiles = retrotile_get_tiles_p( tiles_layer );
798 assert( NULL != token );
799 assert( NULL != parser );
800 assert( NULL != tiles );
803 parser->layer_tile_iter >=
808 "tile " SIZE_T_FMT
" outside of layer tile buffer size "
810 parser->layer_tile_iter,
812 retval = MERROR_OVERFLOW;
816 assert( 0 == tiles[parser->layer_tile_iter] );
818 tiles[parser->layer_tile_iter] = atoi( token );
821 parser->layer_tile_iter++;
825 MJSON_PSTATE_OBJECT_VAL ==
826 mjson_parser_pstate( &(parser->jparser) )
837 if( MTILESTATE_TILESETS_FGID == parser->mstate ) {
838 if( 1 == parser->pass ) {
844 retrotile_parser_mstate( parser, MTILESTATE_TILESETS );
846 }
else if( MTILESTATE_TILESETS_SRC == parser->mstate ) {
847 if( 1 == parser->pass ) {
850 parser->dirname, token, NULL, parser->p_tile_defs,
851 parser->wait_cb, parser->wait_data,
853 parser->passes_max );
855 retrotile_parser_mstate( parser, MTILESTATE_TILESETS );
857 }
else if( MTILESTATE_HEIGHT == parser->mstate ) {
858 if( 0 == parser->pass ) {
860 parser->tiles_h = atoi( token );
865 retrotile_parser_mstate( parser, MTILESTATE_NONE );
867 }
else if( MTILESTATE_WIDTH == parser->mstate ) {
868 if( 0 == parser->pass ) {
870 parser->tiles_w = atoi( token );
875 retrotile_parser_mstate( parser, MTILESTATE_NONE );
877 }
else if( MTILESTATE_LAYER_NAME == parser->mstate ) {
879 retrotile_parser_mstate( parser, MTILESTATE_LAYER );
881 }
else if( MTILESTATE_LAYER_CLASS == parser->mstate ) {
882 if( 0 == strncmp(
"mobile", token, 7 ) ) {
884 "layer " SIZE_T_FMT
" type: mobile",
885 parser->pass_layer_iter );
886 parser->layer_class = RETROTILE_CLASS_MOBILE;
889 "layer " SIZE_T_FMT
" type: tile",
890 parser->pass_layer_iter );
891 parser->layer_class = RETROTILE_CLASS_TILE;
893 retrotile_parser_mstate( parser, MTILESTATE_LAYER );
895 }
else if( MTILESTATE_PROP_NAME == parser->mstate ) {
899 parser->last_prop_name_sz = token_sz;
900 retrotile_parser_mstate( parser, MTILESTATE_PROP );
902 }
else if( MTILESTATE_PROP_VAL == parser->mstate ) {
910 retrotile_parser_mstate( parser, MTILESTATE_PROP );
915 retrotile_parser_match_token( token, token_sz, parser );
927 if( MTILESTATE_LAYER_DATA == parser->mstate ) {
930 parser->layer_tile_iter );
931 assert( parser->layer_tile_iter > 0 );
932 retrotile_parser_mstate( parser, MTILESTATE_LAYER );
934 }
else if( MTILESTATE_LAYERS == parser->mstate ) {
936 retrotile_parser_mstate( parser, MTILESTATE_NONE );
938 }
else if( MTILESTATE_TILESETS == parser->mstate ) {
940 retrotile_parser_mstate( parser, MTILESTATE_NONE );
942 }
else if( MTILESTATE_TILES_PROP == parser->mstate ) {
944 retrotile_parser_mstate( parser, MTILESTATE_TILES );
946 }
else if( MTILESTATE_TILES == parser->mstate ) {
948 retrotile_parser_mstate( parser, MTILESTATE_NONE );
950 }
else if( MTILESTATE_PROP == parser->mstate ) {
951 retrotile_parser_mstate( parser, MTILESTATE_NONE );
962 if( MTILESTATE_LAYERS == parser->mstate ) {
966 parser->layer_tile_iter = 0;
967 retrotile_parser_mstate( parser, MTILESTATE_LAYER );
978 if( MTILESTATE_LAYER == parser->mstate ) {
981 "incrementing pass layer to " SIZE_T_FMT
" after " SIZE_T_FMT
983 parser->pass_layer_iter + 1, parser->layer_tile_iter );
984 parser->pass_layer_iter++;
985 retrotile_parser_mstate( parser, MTILESTATE_LAYERS );
987 }
else if( MTILESTATE_GRID == parser->mstate ) {
988 retrotile_parser_mstate( parser, MTILESTATE_NONE );
997 mfix_t static_rotate_out = 0;
1004 if( 0 == strncmp( dir,
"NW", 2 ) ) {
1005 static_rotate_out = mfix_from_f( 90.0f );
1006 }
else if( 0 == strncmp( dir,
"SW", 2 ) ) {
1007 static_rotate_out = mfix_from_f( 180.0f );
1008 }
else if( 0 == strncmp( dir,
"SE", 2 ) ) {
1009 static_rotate_out = mfix_from_f( 270.0f );
1011 }
else if( 0 == strncmp( dir,
"W", 1 ) ) {
1012 static_rotate_out = mfix_from_f( 90.0f );
1013 }
else if( 0 == strncmp( dir,
"S", 1 ) ) {
1014 static_rotate_out = mfix_from_f( 180.0f );
1015 }
else if( 0 == strncmp( dir,
"E", 1 ) ) {
1016 static_rotate_out = mfix_from_f( 270.0f );
1019 static_rotate_out = 0;
1022 return static_rotate_out;
1028 const char* dirname,
const char* filename, MAUG_MHANDLE* p_tilemap_h,
1029 struct MDATA_VECTOR* p_tile_defs, mparser_wait_cb_t wait_cb,
void* wait_data,
1030 mparser_parse_token_cb token_cb,
void* token_cb_data, uint8_t passes
1033 MAUG_MHANDLE parser_h = (MAUG_MHANDLE)NULL;
1035 char filename_path[RETROFLAT_PATH_MAX];
1038 char* filename_ext = NULL;
1042 maug_cleanup_if_null_alloc( MAUG_MHANDLE, parser_h );
1044 maug_mlock( parser_h, parser );
1050 parser->custom_token_cb_data = token_cb_data;
1052 maug_strncpy( parser->dirname, dirname, RETROFLAT_PATH_MAX );
1056 "increasing parse passes to minimum, 2!" );
1060 parser->passes_max = passes;
1063 memset( filename_path,
'\0', RETROFLAT_PATH_MAX );
1066 filename_path, RETROFLAT_PATH_MAX,
"%s/%s", dirname, filename );
1071 maug_cleanup_if_not_ok();
1074 for( parser->pass = 0 ; passes > parser->pass ; parser->pass++ ) {
1082 maug_mzero( &(parser->jparser.base),
sizeof(
struct MJSON_PARSER ) );
1084 parser->wait_cb = wait_cb;
1085 parser->wait_data = wait_data;
1086 parser->jparser.base.wait_cb = wait_cb;
1087 parser->jparser.base.wait_data = wait_data;
1090 filename_ext = maug_strrchr( filename,
'.' );
1091 if( NULL == filename_ext ) {
1092 error_printf(
"could not parse filename extension!" );
1093 retval = MERROR_FILE;
1096 if(
's' == filename_ext[2] ) {
1098 "(tile_defs pass %u)", parser->pass );
1100 parser->jparser.token_parser = retrotile_parser_parse_tiledef_token;
1101 parser->jparser.token_parser_arg = parser;
1102 parser->jparser.close_list = retrotile_json_close_list;
1103 parser->jparser.close_list_arg = parser;
1104 parser->jparser.close_obj = retrotile_json_close_obj;
1105 parser->jparser.close_obj_arg = parser;
1110 parser->p_tile_defs = p_tile_defs;
1112 assert( NULL != p_tile_defs );
1113 if( 1 == parser->pass ) {
1129 parser->jparser.close_list = retrotile_json_close_list;
1130 parser->jparser.close_list_arg = parser;
1131 parser->jparser.open_obj = retrotile_json_open_obj;
1132 parser->jparser.open_obj_arg = parser;
1133 parser->jparser.close_obj = retrotile_json_close_obj;
1134 parser->jparser.close_obj_arg = parser;
1135 parser->jparser.token_parser = retrotile_parser_parse_token;
1136 parser->jparser.token_parser_arg = parser;
1137 parser->p_tile_defs = p_tile_defs;
1139 assert( NULL != p_tilemap_h );
1140 assert( NULL != p_tile_defs );
1141 if( 1 == parser->pass ) {
1143 retval = retrotile_alloc(
1144 p_tilemap_h, parser->tiles_w, parser->tiles_h,
1146 maug_cleanup_if_not_ok();
1147 maug_mlock( *p_tilemap_h, parser->t );
1149 parser->pass_layer_iter = 0;
1152 while( mfile_has_bytes( &buffer ) ) {
1153 buffer.read_int( &buffer, (uint8_t*)&c, 1, 0 );
1154 retval = mjson_parse_c( &(parser->jparser), c );
1155 if( MERROR_OK != retval ) {
1156 error_printf(
"error parsing JSON!" );
1161 buffer.seek( &buffer, 0 );
1163 filename_ext = maug_strrchr( filename,
'.' );
1164 if( NULL == filename_ext ) {
1165 error_printf(
"could not parse filename extension!" );
1166 retval = MERROR_FILE;
1169 if(
's' != filename_ext[2] ) {
1171 "pass %u found " SIZE_T_FMT
" layers",
1172 parser->pass, parser->pass_layer_iter );
1181 if( NULL != parser ) {
1182 if( NULL != parser->t ) {
1183 maug_munlock( *p_tilemap_h, parser->t );
1185 maug_munlock( parser_h, parser );
1188 if( NULL != parser_h ) {
1189 maug_mfree( parser_h );
1203 if( 8 > rand() % 10 ) {
1205 avg -= (min_z / tuning) + (rand() % (max_z / tuning));
1225static void retrotile_gen_diamond_square_corners(
1226 int16_t corners_x[2][2], int16_t corners_y[2][2],
1239 for( iter_y = 0 ; iter_y < 2 ; iter_y++ ) {
1240 for( iter_x = 0 ; iter_x < 2 ; iter_x++ ) {
1243 corners_x[iter_x][iter_y] =
1245 if( 0 > corners_x[iter_x][iter_y] ) {
1246 corners_x[iter_x][iter_y] += 1;
1250 corners_y[iter_x][iter_y] =
1252 if( 0 > corners_y[iter_x][iter_y] ) {
1253 corners_y[iter_x][iter_y] += 1;
1259 assert( 0 <= corners_x[0][0] );
1260 assert( 0 <= corners_y[0][0] );
1261 assert( t->
tiles_w > corners_x[0][0] );
1262 assert( t->
tiles_h > corners_y[0][0] );
1265 top_left_z = retrotile_get_tile(
1270 if( 0 > top_left_z ) {
1273 corners_x[0][0] >= 0 ? corners_x[0][0] : 0,
1274 corners_y[0][0] >= 0 ? corners_y[0][0] : 0 ) = max_z;
1279 for( iter_y = 0 ; iter_y < 2 ; iter_y++ ) {
1280 for( iter_x = 0 ; iter_x < 2 ; iter_x++ ) {
1282 tile_iter = &(retrotile_get_tile(
1284 corners_x[iter_x][iter_y],
1285 corners_y[iter_x][iter_y] ));
1288 if( -1 != *tile_iter ) {
1291 corners_x[iter_x][iter_y], corners_y[iter_x][iter_y],
1294 corners_x[iter_x][iter_y],
1295 corners_y[iter_x][iter_y] ) );
1300 *tile_iter = retrotile_gen_diamond_square_rand(
1301 min_z, max_z, tuning, top_left_z );
1304 "missing corner coord %d x %d: %d",
1305 corners_x[iter_x][iter_y], corners_y[iter_x][iter_y],
1314 int16_t corners_x[2][2], int16_t corners_y[2][2],
1323 for( iter_y = 0 ; 2 > iter_y ; iter_y++ ) {
1324 for( iter_x = 0 ; 2 > iter_x ; iter_x++ ) {
1325 tile_iter = &(retrotile_get_tile(
1327 corners_x[iter_x][iter_y],
1328 corners_y[iter_x][iter_y] ));
1329 assert( -1 != *tile_iter );
1350 uint32_t tuning,
size_t layer_idx, uint8_t flags,
void* data,
1351 retrotile_ani_cb animation_cb,
void* animation_cb_data
1356 int16_t corners_x[2][2];
1357 int16_t corners_y[2][2];
1361 MAUG_MHANDLE data_ds_h = NULL;
1367 uint8_t free_ds_data = 0;
1374 #define _retrotile_ds_update_statistics( data, tile ) \
1376 if( (data)->highest_generated < (tile) && 32767 > (tile) ) { \
1377 (data)->highest_generated = (tile); \
1379 if( (data)->lowest_generated > (tile) && 0 < (tile) ) { \
1380 (data)->lowest_generated = (tile); \
1383 layer = retrotile_get_layer_p( t, layer_idx );
1391 if( NULL == data ) {
1394 maug_cleanup_if_null_alloc( MAUG_MHANDLE, data_ds_h );
1396 maug_mlock( data_ds_h, data_ds );
1403 memset( retrotile_get_tiles_p( layer ), -1,
1412 data_ds->lowest_generated = 32767;
1419 assert( NULL != data_ds );
1422 if( 0 == data_ds->
sect_w ) {
1440 retrotile_gen_diamond_square_corners(
1441 corners_x, corners_y, min_z, max_z, tuning, data_ds, layer, t );
1447 "%d return: reached innermost point", iter_depth );
1452 retrotile_gen_diamond_square_avg( corners_x, corners_y, t, layer );
1454 debug_printf( 1,
"avg :%d", avg );
1456 tile_iter = &(retrotile_get_tile(
1460 if( -1 != *tile_iter ) {
1467 _retrotile_ds_update_statistics( data_ds, avg );
1476 iter_y = data_ds->
sect_y ;
1481 iter_x = data_ds->
sect_x ;
1485 data_ds_sub.sect_x = data_ds->
sect_x + iter_x;
1487 data_ds_sub.sect_y = data_ds->
sect_y + iter_y;
1491 data_ds_sub.sect_w_half = data_ds_sub.sect_w >> 1;
1492 data_ds_sub.sect_h_half = data_ds_sub.sect_h >> 1;
1493 data_ds_sub.lowest_generated = 32767;
1494 data_ds_sub.highest_generated = 0;
1499 data_ds_sub.sect_x, data_ds_sub.sect_y, data_ds_sub.sect_w );
1502 t, min_z, max_z, tuning, layer_idx, flags, &data_ds_sub,
1503 animation_cb, animation_cb_data );
1504 maug_cleanup_if_not_ok();
1506 _retrotile_ds_update_statistics(
1507 data_ds, data_ds_sub.highest_generated );
1508 _retrotile_ds_update_statistics(
1509 data_ds, data_ds_sub.lowest_generated );
1515 NULL != animation_cb
1517 retval = animation_cb( animation_cb_data, iter_y );
1518 maug_cleanup_if_not_ok();
1526 if( free_ds_data && NULL != data_ds ) {
1527 maug_munlock( data_ds_h, data_ds );
1530 if( free_ds_data && NULL != data_ds_h ) {
1531 maug_mfree( data_ds_h );
1541 uint32_t tuning,
size_t layer_idx, uint8_t flags,
void* data,
1542 retrotile_ani_cb animation_cb,
void* animation_cb_data
1546 int16_t offset_x = 0,
1551 int16_t spb = RETROTILE_VORONOI_DEFAULT_SPB;
1552 int16_t drift = RETROTILE_VORONOI_DEFAULT_DRIFT;
1553 MAUG_MHANDLE temp_grid_h = (MAUG_MHANDLE)NULL;
1557 int8_t side_iter = 0;
1559 layer = retrotile_get_layer_p( t, 0 );
1561 tiles = retrotile_get_tiles_p( layer );
1568 for( y = 0 ; t->
tiles_w > y ; y += spb ) {
1569 for( x = 0 ; t->
tiles_w > x ; x += spb ) {
1570 offset_x = x + ((drift * -1) + (rand() % drift));
1571 offset_y = y + ((drift * -1) + (rand() % drift));
1574 if( 0 > offset_x ) {
1577 if( offset_x >= t->
tiles_w ) {
1580 if( 0 > offset_y ) {
1583 if( offset_y >= t->
tiles_h ) {
1587 retrotile_get_tile( t, layer, offset_x, offset_y ) =
1588 min_z + (rand() % max_z);
1592 temp_grid_h = maug_malloc(
1594 maug_cleanup_if_null_alloc( MAUG_MHANDLE, temp_grid_h );
1596 maug_mlock( temp_grid_h, temp_grid );
1600 while( !finished ) {
1601 if( NULL != animation_cb ) {
1602 retval = animation_cb( animation_cb_data, -1 );
1603 maug_cleanup_if_not_ok();
1615 for( y = 0 ; t->
tiles_h > y ; y++ ) {
1616 for( x = 0 ; t->
tiles_w > x ; x++ ) {
1617 if( -1 == retrotile_get_tile( t, layer, x, y ) ) {
1628 for( side_iter = 0 ; 4 > side_iter ; side_iter++ ) {
1630 SIZE_T_FMT
" (%d), " SIZE_T_FMT
" (%d) ("
1631 SIZE_T_FMT
", " SIZE_T_FMT
")",
1633 gc_retroflat_offsets4_x[side_iter],
1635 gc_retroflat_offsets4_y[side_iter],
1641 t->
tiles_w > x + gc_retroflat_offsets4_x[side_iter] &&
1642 t->
tiles_h > y + gc_retroflat_offsets4_y[side_iter] &&
1644 ((y + gc_retroflat_offsets4_y[side_iter]) *
1646 (x + gc_retroflat_offsets4_x[side_iter])]
1649 retrotile_get_tile( t, layer,
1650 x + gc_retroflat_offsets4_x[side_iter],
1651 y + gc_retroflat_offsets4_y[side_iter] ) =
1652 retrotile_get_tile( t, layer, x, y );
1662 if( NULL != temp_grid ) {
1663 maug_munlock( temp_grid_h, temp_grid );
1666 if( NULL != temp_grid_h ) {
1667 maug_mfree( temp_grid_h );
1677 uint32_t tuning,
size_t layer_idx, uint8_t flags,
void* data,
1678 retrotile_ani_cb animation_cb,
void* animation_cb_data
1683 int16_t side_iter = 0,
1689 assert( NULL != t );
1690 layer = retrotile_get_layer_p( t, layer_idx );
1691 assert( NULL != layer );
1693 for( y = 0 ; t->
tiles_h > y ; y++ ) {
1694 if( NULL != animation_cb ) {
1695 retval = animation_cb( animation_cb_data, y );
1696 maug_cleanup_if_not_ok();
1698 for( x = 0 ; t->
tiles_w > x ; x++ ) {
1704 for( side_iter = 0 ; 8 > side_iter ; side_iter++ ) {
1706 t->
tiles_w <= x + gc_retroflat_offsets8_x[side_iter] ||
1707 t->
tiles_h <= y + gc_retroflat_offsets8_y[side_iter]
1715 "si %d: x, y: " SIZE_T_FMT
" (+%d), " SIZE_T_FMT
1716 " (+%d) idx: " SIZE_T_FMT,
1718 x + gc_retroflat_offsets8_x[side_iter],
1719 gc_retroflat_offsets8_x[side_iter],
1720 y + gc_retroflat_offsets8_y[side_iter],
1721 gc_retroflat_offsets8_y[side_iter],
1722 ((y + gc_retroflat_offsets8_y[side_iter]) * t->
tiles_w) +
1723 x + gc_retroflat_offsets8_x[side_iter] );
1724 sides_sum += retrotile_get_tile(
1726 x + gc_retroflat_offsets8_x[side_iter],
1727 y + gc_retroflat_offsets8_y[side_iter] );
1730 retrotile_get_tile( t, layer, x, y ) = sides_sum / sides_avail;
1743 uint32_t tuning,
size_t layer_idx, uint8_t flags,
void* data,
1744 retrotile_ani_cb animation_cb,
void* animation_cb_data
1755 int16_t ctr_iter = 0,
1759 assert( NULL != t );
1760 layer = retrotile_get_layer_p( t, layer_idx );
1761 assert( NULL != layer );
1764 for( i = 0 ; 0 <= borders[i].center ; i++ ) {
1765 borders[i].tiles_changed = 0;
1768 debug_printf( 1,
"adding borders..." );
1770 for( y = 0 ; t->
tiles_h > y ; y++ ) {
1771 for( x = 0 ; t->
tiles_w > x ; x++ ) {
1773 while( 0 <= borders[i].center ) {
1775 ctr_iter = retrotile_get_tile( t, layer, x, y );
1777 "x: " SIZE_T_FMT
", y: " SIZE_T_FMT
", 0x%04x vs 0x%04x",
1778 x, y, ctr_iter, borders[i].center );
1779 if( ctr_iter != borders[i].center ) {
1787 for( side = 0 ; 8 > side ; side += 2 ) {
1789 x + gc_retroflat_offsets8_x[side] > t->
tiles_w ||
1790 y + gc_retroflat_offsets8_y[side] > t->
tiles_h
1796 outside_iter = retrotile_get_tile( t, layer,
1797 x + gc_retroflat_offsets8_x[side],
1798 y + gc_retroflat_offsets8_y[side] );
1802 if( side + 4 < 8 ) {
1803 x_plus_1 = x + gc_retroflat_offsets8_x[side + 4];
1804 y_plus_1 = y + gc_retroflat_offsets8_y[side + 4];
1806 x_plus_1 = x + gc_retroflat_offsets8_x[side - 4];
1807 y_plus_1 = y + gc_retroflat_offsets8_y[side - 4];
1811 x_plus_1 < t->tiles_w && y_plus_1 < t->tiles_h &&
1812 outside_iter == borders[i].outside &&
1813 outside_iter == retrotile_get_tile( t, layer,
1814 x_plus_1, y_plus_1 )
1818 retrotile_get_tile( t, layer, x, y ) =
1820 borders[i].tiles_changed++;
1827 for( side = 0 ; 8 > side ; side += 2 ) {
1829 x + gc_retroflat_offsets8_x[side] > t->
tiles_w ||
1830 y + gc_retroflat_offsets8_y[side] > t->
tiles_h
1836 outside_iter = retrotile_get_tile( t, layer,
1837 x + gc_retroflat_offsets8_x[side],
1838 y + gc_retroflat_offsets8_y[side] );
1842 if( side + 2 < 8 ) {
1843 x_plus_1 = x + gc_retroflat_offsets8_x[side + 2];
1844 y_plus_1 = y + gc_retroflat_offsets8_y[side + 2];
1846 x_plus_1 = x + gc_retroflat_offsets8_x[0];
1847 y_plus_1 = y + gc_retroflat_offsets8_y[0];
1851 x_plus_1 < t->tiles_w && y_plus_1 < t->tiles_h &&
1852 outside_iter == borders[i].outside &&
1853 outside_iter == retrotile_get_tile( t, layer,
1854 x_plus_1, y_plus_1 )
1857 retrotile_get_tile( t, layer, x, y ) =
1858 borders[i].
mod_to[side + 1 < 8 ? side + 1 : 0];
1859 borders[i].tiles_changed++;
1865 for( side = 0 ; 8 > side ; side += 2 ) {
1867 x + gc_retroflat_offsets8_x[side] > t->
tiles_w ||
1868 y + gc_retroflat_offsets8_y[side] > t->
tiles_h
1874 outside_iter = retrotile_get_tile( t, layer,
1875 x + gc_retroflat_offsets8_x[side],
1876 y + gc_retroflat_offsets8_y[side] );
1878 if( outside_iter == borders[i].outside ) {
1881 retrotile_get_tile( t, layer, x, y ) =
1883 borders[i].tiles_changed++;
1901 struct RETROTILE* tilemap, uint32_t layer_idx
1904 uint8_t* tilemap_buf = (uint8_t*)tilemap;
1907 error_printf(
"invalid layer " UPRINTF_U32_FMT
1908 " requested (of " UPRINTF_U32_FMT
")!",
1914 tilemap_buf +=
sizeof(
struct RETROTILE );
1916 while( layer_idx > 0 ) {
1917 tilemap_buf += layer_iter->sz;
1928 MAUG_MHANDLE* p_tilemap_h,
size_t w,
size_t h,
size_t layers_count,
1929 const char* tilemap_name
1933 size_t tilemap_sz = 0;
1937 tilemap_sz =
sizeof(
struct RETROTILE ) +
1941 debug_printf( 1,
"allocating new tilemap " SIZE_T_FMT
"x" SIZE_T_FMT
1942 " tiles, " SIZE_T_FMT
" layers (" SIZE_T_FMT
" bytes)...",
1943 w, h, layers_count, tilemap_sz );
1945 *p_tilemap_h = maug_malloc( 1, tilemap_sz );
1946 maug_cleanup_if_null_alloc( MAUG_MHANDLE, *p_tilemap_h );
1948 maug_mlock( *p_tilemap_h, tilemap );
1949 maug_cleanup_if_null_alloc(
struct RETROTILE*, tilemap );
1952 tilemap->
sz = tilemap_sz;
1960 for( i = 0 ; layers_count > i ; i++ ) {
1961 layer_iter = retrotile_get_layer_p( tilemap, i );
1962 assert( NULL != layer_iter );
1965 maug_cleanup_if_not_ok();
1970 if( NULL != tilemap ) {
1971 maug_munlock( *p_tilemap_h, tilemap );
1981#ifndef RETROFLAT_NO_VIEWPORT_REFRESH
1986 "clearing " SIZE_T_FMT
" vertical viewport pixels (" SIZE_T_FMT
1988 y_max, y_max / RETROFLAT_TILE_H );
1990 retroflat_viewport_lock_refresh();
1991 for( y = 0 ; y_max > y ; y += RETROFLAT_TILE_H ) {
1992 for( x = 0 ; retroflat_viewport_screen_w() > x ; x += RETROFLAT_TILE_W ) {
1993 retroflat_viewport_set_refresh( x, y, -1 );
1999 retroflat_viewport_unlock_refresh();
2021 layer = retrotile_get_layer_p( t, 0 );
2023 mdata_vector_lock( t_defs );
2028 y = ((retroflat_viewport_world_y() >>
2029 RETROFLAT_TILE_H_BITS) << RETROFLAT_TILE_H_BITS) ;
2030 y < (int)retroflat_viewport_world_y() +
2031 (int)retroflat_viewport_screen_h() ;
2032 y += RETROFLAT_TILE_H
2035 x = ((retroflat_viewport_world_x() >>
2036 RETROFLAT_TILE_W_BITS) << RETROFLAT_TILE_W_BITS) ;
2037 x < (int)retroflat_viewport_world_x() +
2038 (int)retroflat_viewport_screen_w() ;
2039 x += RETROFLAT_TILE_W
2044 (
int)retroflat_viewport_world_w() <= x ||
2045 (
int)retroflat_viewport_world_h() <= y
2051 x_tile = x >> RETROFLAT_TILE_W_BITS;
2052 y_tile = y >> RETROFLAT_TILE_H_BITS;
2054 tile_id = retrotile_get_tile( t, layer, x_tile, y_tile );
2055 t_def = mdata_vector_get(
2057 if( NULL == t_def ) {
2059 "invalid tile ID: %d (- " SIZE_T_FMT
" = " SIZE_T_FMT
")",
2063 assert( NULL != t_def );
2065#ifndef RETROFLAT_NO_VIEWPORT_REFRESH
2067 retroflat_viewport_lock_refresh();
2068 if( !retroflat_viewport_tile_is_stale(
2069 x - retroflat_viewport_world_x(),
2070 y - retroflat_viewport_world_y(), tile_id
2072 retroflat_viewport_unlock_refresh();
2081 retroflat_viewport_set_refresh(
2082 x - retroflat_viewport_world_x(),
2083 y - retroflat_viewport_world_y(), tile_id );
2084 retroflat_viewport_unlock_refresh();
2087#ifdef RETROGXC_PRESENT
2088 retrogxc_blit_bitmap( target, t_def->image_cache_id,
2092 RETROFLAT_TILE_W, RETROFLAT_TILE_H,
2099 RETROFLAT_TILE_W, RETROFLAT_TILE_H,
2107 mdata_vector_unlock( t_defs );
2116# define RETROTILE_PARSER_MSTATE_TABLE_CONST( name, idx, tokn, parent, m ) \
2117 extern MAUG_CONST uint8_t SEG_MCONST name;
2119RETROTILE_PARSER_MSTATE_TABLE( RETROTILE_PARSER_MSTATE_TABLE_CONST )
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:62
MERROR_RETVAL mfile_open_read(const char *filename, mfile_t *p_file)
Open a file and read it into memory or memory-map it.
char retroflat_asset_path[RETROFLAT_PATH_MAX]
Path/name used to load an asset from disk.
Definition retroflt.h:771
MERROR_RETVAL retroflat_blit_bitmap(struct RETROFLAT_BITMAP *target, struct RETROFLAT_BITMAP *src, size_t s_x, size_t s_y, int16_t d_x, int16_t d_y, size_t w, size_t h, int16_t instance)
Blit the contents of a RETROFLAT_BITMAP onto another RETROFLAT_BITMAP.
#define retroflat_instance_tile(instance)
Declare that a given instance ID is for a tile, rather than a sprite.
Definition retroflt.h:570
size_t retroflat_pxxy_t
Type used for surface pixel coordinates.
Definition retroflt.h:1011
#define retroflat_viewport_screen_y(world_y)
Return the screenspace Y coordinate at which something at the given world coordinate should be drawn.
Definition retroflt.h:1624
#define retroflat_viewport_screen_x(world_x)
Return the screenspace X coordinate at which something at the given world coordinate should be drawn.
Definition retroflt.h:1617
uint32_t maug_atou32(const char *buffer, size_t buffer_sz, uint8_t base)
int32_t maug_atos32(const char *buffer, size_t buffer_sz)
#define RETROTILE_DS_FLAG_INIT_DATA
Flag for retrotile_gen_diamond_square_iter() indicating that passed RETROTILE_DATA_DS object should b...
Definition retrotil.h:118
MERROR_RETVAL retrotile_gen_smooth_iter(struct RETROTILE *t, retroflat_tile_t min_z, retroflat_tile_t max_z, uint32_t tuning, size_t layer_idx, uint8_t flags, void *data, retrotile_ani_cb animation_cb, void *animation_cb_data)
Average the values in adjacent tiles over an already-generated tilemap.
MERROR_RETVAL retrotile_gen_borders_iter(struct RETROTILE *t, retroflat_tile_t min_z, retroflat_tile_t max_z, uint32_t tuning, size_t layer_idx, uint8_t flags, void *data, retrotile_ani_cb animation_cb, void *animation_cb_data)
Given a list of RETROTILE_DATA_BORDER structs, this will search for occurrences of RETROTILE_DATA_BOR...
MERROR_RETVAL retrotile_gen_diamond_square_iter(struct RETROTILE *t, retroflat_tile_t min_z, retroflat_tile_t max_z, uint32_t tuning, size_t layer_idx, uint8_t flags, void *data, retrotile_ani_cb animation_cb, void *animation_cb_data)
Generate tilemap terrain using diamond square algorithm.
MERROR_RETVAL retrotile_gen_voronoi_iter(struct RETROTILE *t, retroflat_tile_t min_z, retroflat_tile_t max_z, uint32_t tuning, size_t layer_idx, uint8_t flags, void *data, retrotile_ani_cb animation_cb, void *animation_cb_data)
Generate tilemap terrain using voronoi graph.
MERROR_RETVAL retrotile_parse_json_file(const char *dirname, const char *filename, MAUG_MHANDLE *p_tilemap_h, struct MDATA_VECTOR *p_tile_defs, mparser_wait_cb_t wait_cb, void *wait_data, mparser_parse_token_cb token_cb, void *token_cb_data, uint8_t passes)
Parse the JSON file at the given path into a heap-allocated tilemap with a RETROTILE struct header.
mfix_t retrotile_static_rotation_from_dir(const char *dir)
Convert a less-or-equal-to-two-character string to a direction in degrees.
#define RETROTILE_TILE_SCALE_DEFAULT
Default value for RETROTILE::tile_scale.
Definition retrotil.h:31
#define RETROTILE_PROP_NAME_SZ_MAX
Maximum number of chars in a parsed property name.
Definition retrotil.h:26
#define RETROTILE_PARSER_MODE_DEFS
Value for RETROTILE_PARSER::mode indicating the parser is currently parsing tile definitions.
Definition retrotil.h:65
#define RETROTILE_TRACE_LVL
If defined, bring debug printf statements up to this level.
Definition retrotil.h:36
#define RETROTILE_PARSER_MODE_MAP
Value for RETROTILE_PARSER::mode indicating the parser is currently parsing a tilemap.
Definition retrotil.h:58
int16_t retroflat_tile_t
Value for an individual tile in a RETROTILE_LAYER.
Definition retroflt.h:19
#define RETROTILE_NAME_SZ_MAX
Maximum number of chars in a RETROTILE::name.
Definition retrotil.h:21
A vector of uniformly-sized objects, stored contiguously.
Definition mdata.h:89
Platform-specific bitmap structure. retroflat_bitmap_ok() can be used on a pointer to it to determine...
Definition retpltd.h:21
This is not currently used for anything, but is provided as a a convenience for game logic.
Definition retrotil.h:162
Definition retrotil.h:214
retroflat_tile_t mod_to[8]
If the center and outside match, use this mod-to.
Definition retrotil.h:219
Internal data structure used by retrotile_gen_diamond_square_iter().
Definition retrotil.h:197
int16_t sect_y
Starting Y of subsector in a given iteration.
Definition retrotil.h:201
int16_t sect_w
Width of subsector in a given iteration.
Definition retrotil.h:203
int16_t sect_w_half
Half of the width of subsector in a given iteration.
Definition retrotil.h:207
int16_t sect_x
Starting X of subsector in a given iteration.
Definition retrotil.h:199
int16_t sect_h
Height of subsector in a given iteration.
Definition retrotil.h:205
int16_t sect_h_half
Half of the height of subsector in a given iteration.
Definition retrotil.h:209
Definition retrotil.h:153
Definition retrotil.h:246
mparser_parse_token_cb custom_token_cb
Callback to parse engine-specific custom tokens from the tilemap JSON. Should return MERROR_PREEMPT i...
Definition retrotil.h:277
char tilemap_name[RETROTILE_NAME_SZ_MAX+1]
The name to give to the new tilemap.
Definition retrotil.h:261
char last_prop_name[RETROTILE_PROP_NAME_SZ_MAX+1]
The name of the last property key/value pair parsed.
Definition retrotil.h:258
uint8_t mode
Value indicating the current type of object being parsed into.
Definition retrotil.h:252
size_t tileset_id_cur
Highest tileset ID on first pass and next ID to be assigned on second.
Definition retrotil.h:267
Definition retrotil.h:125
mfix_t static_rotation
Field indicating how many degrees the tile should always be rotated before drawin on-screen....
Definition retrotil.h:137
A struct representing a tilemap.
Definition retrotil.h:174
size_t tiles_h
Height of all layers of the tilemap in tiles.
Definition retrotil.h:183
size_t tileset_fgid
First GID in the accompanying tileset.
Definition retrotil.h:181
uint32_t sz
Size of the tilemap in bytes (including this struct header).
Definition retrotil.h:177
float tile_scale
Amount by which to scale tiles (convenience property).
Definition retrotil.h:190
size_t tiles_w
Width of all layers of the tilemap in tiles.
Definition retrotil.h:185
uint32_t layers_count
Number of tile layers in this tilemap.
Definition retrotil.h:179