mirror of
https://github.com/libretro/retroluxury.git
synced 2024-11-23 07:39:47 +00:00
render layers other than the background
This commit is contained in:
parent
9188a67cc5
commit
36b6251546
215
src/rl_map.c
215
src/rl_map.c
@ -2,28 +2,52 @@
|
||||
#include <rl_memory.h>
|
||||
#include <rl_backgrnd.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <rl_endian.c>
|
||||
|
||||
static rl_map_t* destroy( rl_map_t* map )
|
||||
static rl_map_t* destroy( const rl_map_t* map )
|
||||
{
|
||||
if ( map )
|
||||
{
|
||||
if ( map->tileset )
|
||||
for ( int i = map->num_layers - 1; i >= 0; --i )
|
||||
{
|
||||
rl_tileset_destroy( map->tileset );
|
||||
rl_free( (void*)map->layers[ i ] );
|
||||
}
|
||||
|
||||
if ( map->layer0 )
|
||||
{
|
||||
rl_free( map->layer0 );
|
||||
rl_free( (void*)map->layer0 );
|
||||
}
|
||||
|
||||
rl_free( map );
|
||||
if ( map->imageset )
|
||||
{
|
||||
rl_imageset_destroy( (void*)map->imageset );
|
||||
}
|
||||
|
||||
if ( map->tileset )
|
||||
{
|
||||
rl_tileset_destroy( (void*)map->tileset );
|
||||
}
|
||||
|
||||
rl_free( (void*)map );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* alloc_zero( size_t size )
|
||||
{
|
||||
void* ptr = rl_malloc( size );
|
||||
|
||||
if ( ptr )
|
||||
{
|
||||
memset( ptr, 0, size );
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
rl_map_t* rl_map_create( const void* data, size_t size )
|
||||
{
|
||||
union
|
||||
@ -40,69 +64,162 @@ rl_map_t* rl_map_create( const void* data, size_t size )
|
||||
int width = ne16( *ptr.u16++ );
|
||||
int height = ne16( *ptr.u16++ );
|
||||
int num_layers = ne16( *ptr.u16++ );
|
||||
ptr.u16++; /* padding */
|
||||
|
||||
rl_map_t* map = (rl_map_t*)rl_malloc( sizeof( rl_map_t ) );
|
||||
rl_map_t* map = (rl_map_t*)alloc_zero( sizeof( rl_map_t ) + ( num_layers - 1 ) * sizeof( rl_layern_t ) );
|
||||
|
||||
if ( map )
|
||||
if ( !map )
|
||||
{
|
||||
map->width = width;
|
||||
map->height = height;
|
||||
map->num_layers = num_layers;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
map->width = width;
|
||||
map->height = height;
|
||||
map->num_layers = num_layers;
|
||||
|
||||
size_t tileset_size = ne32( *ptr.u32++ );
|
||||
map->tileset = rl_tileset_create( ptr.v, tileset_size );
|
||||
|
||||
if ( !map->tileset )
|
||||
{
|
||||
return destroy( map );
|
||||
}
|
||||
|
||||
ptr.u8 += tileset_size;
|
||||
|
||||
size_t imageset_size = ne32( *ptr.u32++ );
|
||||
map->imageset = rl_imageset_create( ptr.v, imageset_size );
|
||||
|
||||
if ( !map->imageset )
|
||||
{
|
||||
return destroy( map );
|
||||
}
|
||||
|
||||
ptr.u8 += imageset_size;
|
||||
|
||||
map->layer0 = (rl_layer0_t*)alloc_zero( width * height * sizeof( uint16_t ) );
|
||||
|
||||
if ( !map->layer0 )
|
||||
{
|
||||
return destroy( map );
|
||||
}
|
||||
|
||||
uint16_t* restrict ndx = (uint16_t*)( (uint8_t*)map->layer0 + sizeof( rl_layer0_t ) );
|
||||
const uint16_t* restrict end = ndx + width * height;
|
||||
|
||||
while ( ndx < end )
|
||||
{
|
||||
*ndx++ = ne16( *ptr.u16++ );
|
||||
}
|
||||
|
||||
for ( int i = 1; i < num_layers; i++ )
|
||||
{
|
||||
map->layers[ i - 1 ] = (rl_layern_t*)alloc_zero( width * height * sizeof( uint16_t ) );
|
||||
|
||||
size_t tileset_size = ne32( *ptr.u32++ );
|
||||
map->tileset = rl_tileset_create( ptr.v, tileset_size );
|
||||
|
||||
if ( map->tileset )
|
||||
if ( !map->layers[ i - 1 ] )
|
||||
{
|
||||
ptr.u8 += tileset_size;
|
||||
map->layer0 = (rl_layer0_t*)rl_malloc( width * height * sizeof( uint16_t ) );
|
||||
|
||||
if ( map->layer0 )
|
||||
{
|
||||
uint16_t* restrict ndx = map->layer0->indices;
|
||||
const uint16_t* restrict end = ndx + width * height;
|
||||
|
||||
while ( ndx < end )
|
||||
{
|
||||
*ndx++ = ne16( *ptr.u16++ );
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
return destroy( map );
|
||||
}
|
||||
|
||||
ndx = (uint16_t*)( (uint8_t*)map->layers[ i - 1 ] + sizeof( rl_layern_t ) );
|
||||
end = ndx + width * height;
|
||||
|
||||
while ( ndx < end )
|
||||
{
|
||||
*ndx++ = ne16( *ptr.u16++ );
|
||||
}
|
||||
}
|
||||
|
||||
return destroy( map );
|
||||
return map;
|
||||
}
|
||||
|
||||
void rl_map_destroy( rl_map_t* map )
|
||||
void rl_map_destroy( const rl_map_t* map )
|
||||
{
|
||||
destroy( map );
|
||||
}
|
||||
|
||||
void rl_map_render_layer( rl_map_t* map, int ndx, int x, int y )
|
||||
static void render_layer0( const rl_map_t* map, int x, int y )
|
||||
{
|
||||
int width, height;
|
||||
rl_backgrnd_fb( &width, &height );
|
||||
int bg_width, bg_height;
|
||||
rl_backgrnd_fb( &bg_width, &bg_height );
|
||||
|
||||
if ( ndx == 0 )
|
||||
const rl_tileset_t* tileset = map->tileset;
|
||||
|
||||
int ts_width = tileset->width;
|
||||
int ts_height = tileset->height;
|
||||
|
||||
int dx = -( x % ts_width );
|
||||
int dy = -( y % ts_height );
|
||||
|
||||
int max_x = dx + bg_width + ts_width;
|
||||
int max_y = dy + bg_height + ts_height;
|
||||
|
||||
x /= ts_width;
|
||||
y /= ts_height;
|
||||
|
||||
int pitch = map->width;
|
||||
const uint16_t* restrict ndx = map->layer0->indices + y * pitch + x;
|
||||
|
||||
for ( y = dy; y < max_y; y += ts_height )
|
||||
{
|
||||
int wt = ( width + map->tileset->width - 1 ) / map->tileset->width + 1;
|
||||
int ht = ( width + map->tileset->height - 1 ) / map->tileset->height;
|
||||
const uint16_t* restrict next = ndx + pitch;
|
||||
|
||||
int dx = -( x % map->tileset->width );
|
||||
int dy = -( y % map->tileset->height );
|
||||
|
||||
x /= map->tileset->width;
|
||||
y /= map->tileset->height;
|
||||
|
||||
for ( int yy = 0; yy < ht; yy++ )
|
||||
for ( x = dx; x < max_x; x += ts_width )
|
||||
{
|
||||
for ( int xx = 0; xx < wt; xx++ )
|
||||
{
|
||||
rl_tileset_blit_nobg( map->tileset, map->layer0->indices[ ( y + yy ) * map->width + ( x + xx ) ], dx + xx * map->tileset->width, dy + yy * map->tileset->height );
|
||||
}
|
||||
rl_tileset_blit_nobg( tileset, *ndx++, x, y );
|
||||
}
|
||||
|
||||
ndx = next;
|
||||
}
|
||||
}
|
||||
|
||||
static void render_layern( const rl_map_t* map, int index, int x, int y )
|
||||
{
|
||||
int bg_width, bg_height;
|
||||
rl_backgrnd_fb( &bg_width, &bg_height );
|
||||
|
||||
const rl_imageset_t* imageset = map->imageset;
|
||||
|
||||
int ts_width = map->tileset->width;
|
||||
int ts_height = map->tileset->height;
|
||||
|
||||
int dx = -( x % ts_width );
|
||||
int dy = -( y % ts_height );
|
||||
|
||||
int max_x = dx + bg_width + ts_width;
|
||||
int max_y = dy + bg_height + ts_height;
|
||||
|
||||
x /= ts_width;
|
||||
y /= ts_height;
|
||||
|
||||
int pitch = map->width;
|
||||
const uint16_t* restrict ndx = map->layers[ --index ]->indices + y * pitch + x;
|
||||
|
||||
for ( y = dy; y < max_y; y += ts_height )
|
||||
{
|
||||
const uint16_t* restrict next = ndx + pitch;
|
||||
|
||||
for ( x = dx; x < max_x; x += ts_width )
|
||||
{
|
||||
index = *ndx++;
|
||||
|
||||
if ( index )
|
||||
{
|
||||
rl_image_blit_nobg( imageset->images[ index - 1 ], x, y );
|
||||
}
|
||||
}
|
||||
|
||||
ndx = next;
|
||||
}
|
||||
}
|
||||
|
||||
void rl_map_render_layer( const rl_map_t* map, int index, int x, int y )
|
||||
{
|
||||
if ( index )
|
||||
{
|
||||
render_layern( map, index, x, y );
|
||||
}
|
||||
else
|
||||
{
|
||||
render_layer0( map, x, y );
|
||||
}
|
||||
}
|
||||
|
15
src/rl_map.h
15
src/rl_map.h
@ -2,6 +2,7 @@
|
||||
#define RL_MAP_H
|
||||
|
||||
#include <rl_userdata.h>
|
||||
#include <rl_image.h>
|
||||
#include <rl_tile.h>
|
||||
|
||||
#include <stdint.h>
|
||||
@ -13,6 +14,9 @@ typedef struct
|
||||
}
|
||||
rl_layer0_t;
|
||||
|
||||
/* layern indices are *image* indices. */
|
||||
typedef rl_layer0_t rl_layern_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
rl_userdata_t ud;
|
||||
@ -21,16 +25,17 @@ typedef struct
|
||||
int height;
|
||||
int num_layers;
|
||||
|
||||
rl_tileset_t* tileset;
|
||||
rl_layer0_t* layer0;
|
||||
const rl_tileset_t* tileset;
|
||||
const rl_imageset_t* imageset;
|
||||
const rl_layer0_t* layer0;
|
||||
|
||||
//rl_layern_t* layers[ 0 ];
|
||||
rl_layern_t* layers[ 0 ];
|
||||
}
|
||||
rl_map_t;
|
||||
|
||||
rl_map_t* rl_map_create( const void* data, size_t size );
|
||||
void rl_map_destroy( rl_map_t* map );
|
||||
void rl_map_destroy( const rl_map_t* map );
|
||||
|
||||
void rl_map_render_layer( rl_map_t* map, int ndx, int x, int y );
|
||||
void rl_map_render_layer( const rl_map_t* map, int index, int x, int y );
|
||||
|
||||
#endif /* RL_MAP_H */
|
||||
|
Loading…
Reference in New Issue
Block a user