Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "render.h"
- #include "camera.h"
- #include "player.h"
- #include "entity.h"
- #include "dialogue.h"
- #include "ui.h"
- #include "data/maps/overworld_map_data.h"
- uint8_t g_render_flags;
- const map_t *g_current_map;
- const map_chunk_t *g_current_chunk;
- void load_tile( uint8_t tile, uint8_t screen_x, uint8_t screen_y );
- void render_initialise()
- {
- g_render_flags = RENDER_FLAG_REDRAW_ALL
- | RENDER_FLAG_REDRAW_BOTTOM | RENDER_FLAG_REDRAW_TOP | RENDER_FLAG_REDRAW_LEFT | RENDER_FLAG_REDRAW_RIGHT
- | RENDER_FLAG_LOAD_OVERWORLD_UI | RENDER_FLAG_UPDATE_OVERWORLD_UI;
- g_current_chunk = NULL;
- g_current_map = &overworld_map;
- // TODO TEMP - just loading the one since there is only one atm
- //DEBUG_MESSAGE( "loading new tileset & palette" ); // TODO TEMP
- g_current_chunk = &g_current_map->chunks[ 1 ];
- const tileset_t *map_tilesets = g_current_map->tilesets;
- const uint8_t *tilesets = g_current_chunk->tilesets;
- uint8_t size = g_current_chunk->tilesets_count;
- uint8_t i;
- for ( i = 0; i != size; ++i )
- {
- SWITCH_ROM( map_tilesets->bank_used );
- const tileset_t *tileset = &map_tilesets[ i ];
- SWITCH_ROM( tileset->bank_used );
- set_bkg_data( tileset->offset, tileset->tile_count, tileset->tiles[ 0 ] );
- }
- const palette_t *map_palettes = g_current_map->palettes;
- const uint8_t *palettes = g_current_chunk->palettes;
- size = g_current_chunk->palette_count;
- for ( i = 0; i != size; ++i )
- {
- const palette_t *palette = &map_palettes[ palettes[ i ] ];
- set_bkg_palette( palette->offset, 1, ( palette_color_t * )palette->colours );
- }
- }
- void render()
- {
- const uint8_t state = ( LCDC_REG & ( LCDCF_BGON ) );
- const uint8_t previous_bank = _current_bank;
- const map_chunk_t *old_chunk = g_current_chunk;
- static uint8_t cam_metatile_x, cam_metatile_y;
- static uint8_t cam_metatile_x_end, cam_metatile_y_end;
- static uint8_t meta_tile_x_max, meta_tile_y_max;
- static uint8_t meta_tile_x, meta_tile_y;
- static uint8_t chunk_x, chunk_y;
- static uint8_t tile_x, tile_y;
- static uint8_t ychunk_offset;
- static uint8_t screen_x, screen_y;
- wait_vbl_done();
- SCX_REG = g_camera.x;
- SCY_REG = g_camera.y;
- if ( g_render_flags & RENDER_FLAG_REDRAW_ALL )
- {
- HIDE_BKG;
- cam_metatile_x = PIXEL_TO_META_TILE( g_camera.x ) > 0u ? PIXEL_TO_META_TILE( g_camera.x ) - 1u : PIXEL_TO_META_TILE( g_camera.x );
- cam_metatile_y = PIXEL_TO_META_TILE( g_camera.y ) > 0u ? PIXEL_TO_META_TILE( g_camera.y ) - 1u : PIXEL_TO_META_TILE( g_camera.y );
- cam_metatile_x_end = MIN( cam_metatile_x + META_TILE_SCREEN_WIDTH + 2u, g_current_map->meta_map_size_x );
- cam_metatile_y_end = MIN( cam_metatile_y + META_TILE_SCREEN_HEIGHT + 2u, g_current_map->meta_map_size_y );
- meta_tile_x_max = ( cam_metatile_x_end - cam_metatile_x ) + 1u;
- meta_tile_y_max = ( cam_metatile_y_end - cam_metatile_y ) + 1u;
- for ( meta_tile_y = 0; meta_tile_y != meta_tile_y_max; ++meta_tile_y )
- {
- ychunk_offset = g_current_map->chunk_y_offset[ META_TILE_TO_CHUNK( cam_metatile_y + meta_tile_y ) ];
- screen_y = META_TILE_TO_TILE( cam_metatile_y + meta_tile_y );
- tile_y = CHUNK_META_TILE_REM( cam_metatile_y + meta_tile_y );
- for ( meta_tile_x = 0u; meta_tile_x != meta_tile_x_max; ++meta_tile_x )
- {
- g_current_chunk = &g_current_map->chunks[ META_TILE_TO_CHUNK( cam_metatile_x + meta_tile_x ) + ychunk_offset ];
- SWITCH_ROM( g_current_chunk->bank_used );
- load_tile( CHUNK_META_TILE_REM( cam_metatile_x + meta_tile_x ) + g_current_chunk->tile_y_offset[ tile_y ], META_TILE_TO_TILE( cam_metatile_x + meta_tile_x ), screen_y );
- }
- }
- g_render_flags &= ~( RENDER_FLAG_REDRAW_ALL );
- }
- else if ( g_render_flags & ( RENDER_FLAG_REDRAW_RIGHT | RENDER_FLAG_REDRAW_TOP | RENDER_FLAG_REDRAW_LEFT | RENDER_FLAG_REDRAW_BOTTOM ) )
- {
- cam_metatile_x = PIXEL_TO_META_TILE( g_camera.x ) > 0u ? PIXEL_TO_META_TILE( g_camera.x ) - 1u : PIXEL_TO_META_TILE( g_camera.x );
- cam_metatile_y = PIXEL_TO_META_TILE( g_camera.y ) > 0u ? PIXEL_TO_META_TILE( g_camera.y ) - 1u : PIXEL_TO_META_TILE( g_camera.y );
- cam_metatile_x_end = MIN( cam_metatile_x + META_TILE_SCREEN_WIDTH + 2u, g_current_map->meta_map_size_x );
- cam_metatile_y_end = MIN( cam_metatile_y + META_TILE_SCREEN_HEIGHT + 2u, g_current_map->meta_map_size_y );
- meta_tile_x_max = ( cam_metatile_x_end - cam_metatile_x ) + 1u;
- meta_tile_y_max = ( cam_metatile_y_end - cam_metatile_y ) + 1u;
- if ( g_render_flags & RENDER_FLAG_REDRAW_LEFT )
- {
- g_render_flags &= ~( RENDER_FLAG_REDRAW_LEFT );
- chunk_x = META_TILE_TO_CHUNK( cam_metatile_x );
- tile_x = CHUNK_META_TILE_REM( cam_metatile_x );
- screen_x = META_TILE_TO_TILE( cam_metatile_x );
- for ( meta_tile_y = 0u; meta_tile_y != meta_tile_y_max; ++meta_tile_y )
- {
- g_current_chunk = &g_current_map->chunks[ chunk_x + g_current_map->chunk_y_offset[ META_TILE_TO_CHUNK( cam_metatile_y + meta_tile_y ) ] ];
- SWITCH_ROM( g_current_chunk->bank_used );
- load_tile( tile_x + g_current_chunk->tile_y_offset[ CHUNK_META_TILE_REM( cam_metatile_y + meta_tile_y ) ], screen_x, META_TILE_TO_TILE( cam_metatile_y + meta_tile_y ) );
- }
- }
- else if ( g_render_flags & RENDER_FLAG_REDRAW_RIGHT )
- {
- g_render_flags &= ~( RENDER_FLAG_REDRAW_RIGHT );
- meta_tile_x = ( cam_metatile_x + meta_tile_x_max - 1u );
- chunk_x = META_TILE_TO_CHUNK( meta_tile_x );
- tile_x = CHUNK_META_TILE_REM( meta_tile_x );
- screen_x = META_TILE_TO_TILE( meta_tile_x );
- for ( meta_tile_y = 0u; meta_tile_y != meta_tile_y_max; ++meta_tile_y )
- {
- g_current_chunk = &g_current_map->chunks[ chunk_x + g_current_map->chunk_y_offset[ META_TILE_TO_CHUNK( cam_metatile_y + meta_tile_y ) ] ];
- SWITCH_ROM( g_current_chunk->bank_used );
- load_tile( tile_x + g_current_chunk->tile_y_offset[ CHUNK_META_TILE_REM( cam_metatile_y + meta_tile_y ) ], screen_x, META_TILE_TO_TILE( cam_metatile_y + meta_tile_y ) );
- }
- }
- else if ( g_render_flags & RENDER_FLAG_REDRAW_TOP )
- {
- g_render_flags &= ~( RENDER_FLAG_REDRAW_TOP );
- tile_y = CHUNK_META_TILE_REM( cam_metatile_y );
- ychunk_offset = g_current_map->chunk_y_offset[ META_TILE_TO_CHUNK( cam_metatile_y ) ];
- screen_y = META_TILE_TO_TILE( cam_metatile_y );
- for ( meta_tile_x = 0u; meta_tile_x != meta_tile_x_max; ++meta_tile_x )
- {
- g_current_chunk = &g_current_map->chunks[ META_TILE_TO_CHUNK( cam_metatile_x + meta_tile_x ) + ychunk_offset ];
- SWITCH_ROM( g_current_chunk->bank_used );
- load_tile( CHUNK_META_TILE_REM( cam_metatile_x + meta_tile_x ) + g_current_chunk->tile_y_offset[ tile_y ], META_TILE_TO_TILE( cam_metatile_x + meta_tile_x ), screen_y );
- }
- }
- else if ( g_render_flags & RENDER_FLAG_REDRAW_BOTTOM )
- {
- g_render_flags &= ~( RENDER_FLAG_REDRAW_BOTTOM );
- meta_tile_y = ( cam_metatile_y + meta_tile_y_max - 1u );
- tile_y = CHUNK_META_TILE_REM( meta_tile_y );
- ychunk_offset = g_current_map->chunk_y_offset[ META_TILE_TO_CHUNK( meta_tile_y ) ];
- screen_y = META_TILE_TO_TILE( meta_tile_y );
- for ( meta_tile_x = 0u; meta_tile_x != meta_tile_x_max; ++meta_tile_x )
- {
- g_current_chunk = &g_current_map->chunks[ META_TILE_TO_CHUNK( cam_metatile_x + meta_tile_x ) + ychunk_offset ];
- SWITCH_ROM( g_current_chunk->bank_used );
- load_tile( CHUNK_META_TILE_REM( cam_metatile_x + meta_tile_x ) + g_current_chunk->tile_y_offset[ tile_y ], META_TILE_TO_TILE( cam_metatile_x + meta_tile_x ), screen_y );
- }
- }
- }
- uint8_t i;
- if ( g_player.entity.flags & ENTITY_FLAGS_ACTIVE )
- {
- entity_sprite_update( &g_player.entity );
- }
- for ( uint8_t i = 0u; i != MAX_ENEMIES_ON_SCREEN; ++i )
- {
- if ( g_enemy[ i ].flags & ENTITY_FLAGS_ACTIVE )
- {
- entity_sprite_update( &g_enemy[ i ] );
- }
- }
- if ( g_dialogue_state != DIALOGUE_STATE_CLOSED )
- {
- dialog_update();
- }
- if ( g_render_flags & RENDER_FLAG_LOAD_OVERWORLD_UI )
- {
- overworld_ui_load_tileset();
- g_render_flags &= ~RENDER_FLAG_LOAD_OVERWORLD_UI;
- }
- if ( g_render_flags & RENDER_FLAG_UPDATE_OVERWORLD_UI )
- {
- overworld_ui_draw();
- overworld_ui_draw_health();
- g_render_flags &= ~RENDER_FLAG_UPDATE_OVERWORLD_UI;
- }
- LCDC_REG |= state;
- SWITCH_ROM( previous_bank );
- }
- void load_tile( uint8_t tile, uint8_t screen_x, uint8_t screen_y )
- {
- // @func load_tile
- // @desc Assumes the data is in the correct ROM bank
- // to find the attr, tile >> 2, because each byte is 4 tiles (2 bits per tile)
- // ( 3u - ( ( tile ) & 3 ) ) wraps how many shifts are needed 3, 2, 1, 0
- // << 1 previous number is shifted for * 2 so : 6, 4, 2, 0
- // & 3 and the end makes sure just 2 bits wanted are in the attr
- const uint8_t tile_id = g_current_chunk->map_data[ tile ];
- const uint8_t attr = ( g_current_chunk->map_attributes[ tile >> 2u ] >> ( ( 3u - ( tile & 3u ) ) << 1u ) ) & 3u;
- const uint8_t * const tiles = g_current_chunk->meta_tiles[ tile_id ];
- const uint8_t * const attrs = g_current_chunk->meta_attributes[ tile_id ];
- uint8_t t0, t1, t2, t3, flip;
- // metatile attribute
- switch ( attr )
- {
- case 0: t0 = 0u; t1 = 1u; t2 = 2u; t3 = 3u; flip = 0u; break;
- case 1: t0 = 2u; t1 = 3u; t2 = 0u; t3 = 1u; flip = ( 1u << 6u ); break; // hflip
- case 2: t0 = 1u; t1 = 0u; t2 = 3u; t3 = 2u; flip = ( 1u << 5u ); break; // vflip
- case 3: t0 = 3u; t1 = 2u; t2 = 1u; t3 = 0u; flip = ( 1u << 5u ) | ( 1u << 6u ); break; // hflip + vflip
- default:
- DEBUG_PRINT( "Unexpected Attribute : %u", attr );
- t0 = 0u; t1 = 1u; t2 = 2u; t3 = 3u; flip = 0u;
- break;
- }
- // tiles
- uint8_t * const ta0 = set_bkg_tile_xy( ( screen_x ) & 31u, ( screen_y ) & 31u, tiles[ t0 ] );
- uint8_t * const ta1 = set_bkg_tile_xy( ( screen_x + 1u ) & 31u, ( screen_y ) & 31u, tiles[ t1 ] );
- uint8_t * const ta2 = set_bkg_tile_xy( ( screen_x ) & 31u, ( screen_y + 1u ) & 31u, tiles[ t2 ] );
- uint8_t * const ta3 = set_bkg_tile_xy( ( screen_x + 1u ) & 31u, ( screen_y + 1u ) & 31u, tiles[ t3 ] );
- VBK_REG = 1;
- // attributes
- set_vram_byte( ta0, attrs[ t0 ] ^ flip );
- set_vram_byte( ta1, attrs[ t1 ] ^ flip );
- set_vram_byte( ta2, attrs[ t2 ] ^ flip );
- set_vram_byte( ta3, attrs[ t3 ] ^ flip );
- VBK_REG = 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement