Advertisement
Guest User

Untitled

a guest
Apr 10th, 2022
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.07 KB | None | 0 0
  1.  
  2. #include "render.h"
  3. #include "camera.h"
  4. #include "player.h"
  5. #include "entity.h"
  6. #include "dialogue.h"
  7. #include "ui.h"
  8. #include "data/maps/overworld_map_data.h"
  9.  
  10. uint8_t g_render_flags;
  11.  
  12. const map_t *g_current_map;
  13. const map_chunk_t *g_current_chunk;
  14.  
  15. void load_tile( uint8_t tile, uint8_t screen_x, uint8_t screen_y );
  16.  
  17. void render_initialise()
  18. {
  19.     g_render_flags = RENDER_FLAG_REDRAW_ALL
  20.                     | RENDER_FLAG_REDRAW_BOTTOM | RENDER_FLAG_REDRAW_TOP | RENDER_FLAG_REDRAW_LEFT | RENDER_FLAG_REDRAW_RIGHT
  21.                     | RENDER_FLAG_LOAD_OVERWORLD_UI | RENDER_FLAG_UPDATE_OVERWORLD_UI;
  22.  
  23.     g_current_chunk = NULL;
  24.     g_current_map = &overworld_map;
  25.  
  26.     // TODO TEMP - just loading the one since there is only one atm
  27.     //DEBUG_MESSAGE( "loading new tileset & palette" ); // TODO TEMP
  28.     g_current_chunk = &g_current_map->chunks[ 1 ];
  29.     const tileset_t *map_tilesets = g_current_map->tilesets;
  30.     const uint8_t *tilesets = g_current_chunk->tilesets;
  31.     uint8_t size = g_current_chunk->tilesets_count;
  32.     uint8_t i;
  33.     for ( i = 0; i != size; ++i )
  34.     {
  35.         SWITCH_ROM( map_tilesets->bank_used );
  36.         const tileset_t *tileset = &map_tilesets[ i ];
  37.  
  38.         SWITCH_ROM( tileset->bank_used );
  39.         set_bkg_data( tileset->offset, tileset->tile_count, tileset->tiles[ 0 ] );
  40.     }
  41.  
  42.     const palette_t *map_palettes = g_current_map->palettes;
  43.     const uint8_t *palettes = g_current_chunk->palettes;
  44.     size = g_current_chunk->palette_count;
  45.  
  46.     for ( i = 0; i != size; ++i )
  47.     {
  48.         const palette_t *palette = &map_palettes[ palettes[ i ] ];
  49.  
  50.         set_bkg_palette( palette->offset, 1, ( palette_color_t * )palette->colours );
  51.     }
  52. }
  53.  
  54. void render()
  55. {
  56.     const uint8_t state = ( LCDC_REG & ( LCDCF_BGON ) );
  57.     const uint8_t previous_bank = _current_bank;
  58.     const map_chunk_t *old_chunk = g_current_chunk;
  59.  
  60.     static uint8_t cam_metatile_x, cam_metatile_y;
  61.     static uint8_t cam_metatile_x_end, cam_metatile_y_end;
  62.     static uint8_t meta_tile_x_max, meta_tile_y_max;
  63.  
  64.     static uint8_t meta_tile_x, meta_tile_y;
  65.     static uint8_t chunk_x, chunk_y;
  66.     static uint8_t tile_x, tile_y;
  67.     static uint8_t ychunk_offset;
  68.     static uint8_t screen_x, screen_y;
  69.  
  70.     wait_vbl_done();
  71.  
  72.     SCX_REG = g_camera.x;
  73.     SCY_REG = g_camera.y;
  74.  
  75.     if ( g_render_flags & RENDER_FLAG_REDRAW_ALL )
  76.     {
  77.         HIDE_BKG;
  78.  
  79.         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 );
  80.         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 );
  81.         cam_metatile_x_end = MIN( cam_metatile_x + META_TILE_SCREEN_WIDTH + 2u, g_current_map->meta_map_size_x );
  82.         cam_metatile_y_end = MIN( cam_metatile_y + META_TILE_SCREEN_HEIGHT + 2u, g_current_map->meta_map_size_y );
  83.         meta_tile_x_max = ( cam_metatile_x_end - cam_metatile_x ) + 1u;
  84.         meta_tile_y_max = ( cam_metatile_y_end - cam_metatile_y ) + 1u;
  85.  
  86.         for ( meta_tile_y = 0; meta_tile_y != meta_tile_y_max; ++meta_tile_y )
  87.         {
  88.             ychunk_offset   = g_current_map->chunk_y_offset[ META_TILE_TO_CHUNK( cam_metatile_y + meta_tile_y ) ];
  89.             screen_y        = META_TILE_TO_TILE( cam_metatile_y + meta_tile_y );
  90.             tile_y          = CHUNK_META_TILE_REM( cam_metatile_y + meta_tile_y );
  91.  
  92.             for ( meta_tile_x = 0u; meta_tile_x != meta_tile_x_max; ++meta_tile_x )
  93.             {
  94.                 g_current_chunk = &g_current_map->chunks[ META_TILE_TO_CHUNK( cam_metatile_x + meta_tile_x ) + ychunk_offset ];
  95.  
  96.                 SWITCH_ROM( g_current_chunk->bank_used );
  97.  
  98.                 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 );
  99.             }
  100.         }
  101.  
  102.         g_render_flags &= ~( RENDER_FLAG_REDRAW_ALL );
  103.     }
  104.     else if ( g_render_flags & ( RENDER_FLAG_REDRAW_RIGHT | RENDER_FLAG_REDRAW_TOP | RENDER_FLAG_REDRAW_LEFT | RENDER_FLAG_REDRAW_BOTTOM ) )
  105.     {
  106.         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 );
  107.         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 );
  108.         cam_metatile_x_end  = MIN( cam_metatile_x + META_TILE_SCREEN_WIDTH + 2u, g_current_map->meta_map_size_x );
  109.         cam_metatile_y_end  = MIN( cam_metatile_y + META_TILE_SCREEN_HEIGHT + 2u, g_current_map->meta_map_size_y );
  110.         meta_tile_x_max     = ( cam_metatile_x_end - cam_metatile_x ) + 1u;
  111.         meta_tile_y_max     = ( cam_metatile_y_end - cam_metatile_y ) + 1u;
  112.  
  113.         if ( g_render_flags & RENDER_FLAG_REDRAW_LEFT )
  114.         {
  115.             g_render_flags &= ~( RENDER_FLAG_REDRAW_LEFT );
  116.  
  117.             chunk_x         = META_TILE_TO_CHUNK( cam_metatile_x );
  118.             tile_x          = CHUNK_META_TILE_REM( cam_metatile_x );
  119.             screen_x        = META_TILE_TO_TILE( cam_metatile_x );
  120.  
  121.             for ( meta_tile_y = 0u; meta_tile_y != meta_tile_y_max; ++meta_tile_y )
  122.             {
  123.                 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 ) ] ];
  124.  
  125.                 SWITCH_ROM( g_current_chunk->bank_used );
  126.  
  127.                 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 ) );
  128.             }
  129.         }
  130.         else if ( g_render_flags & RENDER_FLAG_REDRAW_RIGHT )
  131.         {
  132.             g_render_flags &= ~( RENDER_FLAG_REDRAW_RIGHT );
  133.  
  134.             meta_tile_x     = ( cam_metatile_x + meta_tile_x_max - 1u );
  135.             chunk_x         = META_TILE_TO_CHUNK( meta_tile_x );
  136.             tile_x          = CHUNK_META_TILE_REM( meta_tile_x );
  137.             screen_x        = META_TILE_TO_TILE( meta_tile_x );
  138.  
  139.             for ( meta_tile_y = 0u; meta_tile_y != meta_tile_y_max; ++meta_tile_y )
  140.             {
  141.                 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 ) ] ];
  142.  
  143.                 SWITCH_ROM( g_current_chunk->bank_used );
  144.  
  145.                 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 ) );
  146.             }
  147.         }
  148.         else if ( g_render_flags & RENDER_FLAG_REDRAW_TOP )
  149.         {
  150.             g_render_flags &= ~( RENDER_FLAG_REDRAW_TOP );
  151.  
  152.             tile_y          = CHUNK_META_TILE_REM( cam_metatile_y );
  153.             ychunk_offset   = g_current_map->chunk_y_offset[ META_TILE_TO_CHUNK( cam_metatile_y ) ];
  154.             screen_y        = META_TILE_TO_TILE( cam_metatile_y );
  155.  
  156.             for ( meta_tile_x = 0u; meta_tile_x != meta_tile_x_max; ++meta_tile_x )
  157.             {
  158.                 g_current_chunk = &g_current_map->chunks[ META_TILE_TO_CHUNK( cam_metatile_x + meta_tile_x ) + ychunk_offset ];
  159.  
  160.                 SWITCH_ROM( g_current_chunk->bank_used );
  161.  
  162.                 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 );
  163.             }
  164.         }
  165.         else if ( g_render_flags & RENDER_FLAG_REDRAW_BOTTOM )
  166.         {
  167.             g_render_flags &= ~( RENDER_FLAG_REDRAW_BOTTOM );
  168.  
  169.             meta_tile_y     = ( cam_metatile_y + meta_tile_y_max - 1u );
  170.             tile_y          = CHUNK_META_TILE_REM( meta_tile_y );
  171.             ychunk_offset   = g_current_map->chunk_y_offset[ META_TILE_TO_CHUNK( meta_tile_y ) ];
  172.             screen_y        = META_TILE_TO_TILE( meta_tile_y );
  173.  
  174.             for ( meta_tile_x = 0u; meta_tile_x != meta_tile_x_max; ++meta_tile_x )
  175.             {
  176.                 g_current_chunk = &g_current_map->chunks[ META_TILE_TO_CHUNK( cam_metatile_x + meta_tile_x ) + ychunk_offset ];
  177.  
  178.                 SWITCH_ROM( g_current_chunk->bank_used );
  179.  
  180.                 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 );
  181.             }
  182.         }
  183.     }
  184.  
  185.     uint8_t i;
  186.  
  187.     if ( g_player.entity.flags & ENTITY_FLAGS_ACTIVE )
  188.     {
  189.         entity_sprite_update( &g_player.entity );
  190.     }
  191.  
  192.     for ( uint8_t i = 0u; i != MAX_ENEMIES_ON_SCREEN; ++i )
  193.     {
  194.         if ( g_enemy[ i ].flags & ENTITY_FLAGS_ACTIVE )
  195.         {
  196.             entity_sprite_update( &g_enemy[ i ] );
  197.         }
  198.     }
  199.  
  200.     if ( g_dialogue_state != DIALOGUE_STATE_CLOSED )
  201.     {
  202.         dialog_update();
  203.     }
  204.  
  205.     if ( g_render_flags & RENDER_FLAG_LOAD_OVERWORLD_UI )
  206.     {
  207.         overworld_ui_load_tileset();
  208.  
  209.         g_render_flags &= ~RENDER_FLAG_LOAD_OVERWORLD_UI;
  210.     }
  211.  
  212.     if ( g_render_flags & RENDER_FLAG_UPDATE_OVERWORLD_UI )
  213.     {
  214.         overworld_ui_draw();
  215.         overworld_ui_draw_health();
  216.  
  217.         g_render_flags &= ~RENDER_FLAG_UPDATE_OVERWORLD_UI;
  218.     }
  219.  
  220.     LCDC_REG |= state;
  221.  
  222.     SWITCH_ROM( previous_bank );
  223. }
  224.  
  225. void load_tile( uint8_t tile, uint8_t screen_x, uint8_t screen_y )
  226. {
  227.     // @func load_tile
  228.     // @desc Assumes the data is in the correct ROM bank
  229.     //       to find the attr, tile >> 2, because each byte is 4 tiles (2 bits per tile)
  230.     //       ( 3u - ( ( tile ) & 3 ) ) wraps how many shifts are needed 3, 2, 1, 0
  231.     //       << 1 previous number is shifted for * 2 so : 6, 4, 2, 0
  232.     //       & 3 and the end makes sure just 2 bits wanted are in the attr
  233.  
  234.     const uint8_t tile_id       = g_current_chunk->map_data[ tile ];
  235.     const uint8_t attr          = ( g_current_chunk->map_attributes[ tile >> 2u ] >> ( ( 3u - ( tile & 3u ) ) << 1u ) ) & 3u;
  236.     const uint8_t * const tiles = g_current_chunk->meta_tiles[ tile_id ];
  237.     const uint8_t * const attrs = g_current_chunk->meta_attributes[ tile_id ];
  238.  
  239.     uint8_t t0, t1, t2, t3, flip;
  240.  
  241.     // metatile attribute
  242.     switch ( attr )
  243.     {
  244.     case 0:     t0 = 0u; t1 = 1u; t2 = 2u; t3 = 3u; flip = 0u;                          break;
  245.     case 1:     t0 = 2u; t1 = 3u; t2 = 0u; t3 = 1u; flip = ( 1u << 6u );                break;  // hflip
  246.     case 2:     t0 = 1u; t1 = 0u; t2 = 3u; t3 = 2u; flip = ( 1u << 5u );                break;  // vflip
  247.     case 3:     t0 = 3u; t1 = 2u; t2 = 1u; t3 = 0u; flip = ( 1u << 5u ) | ( 1u << 6u ); break;  // hflip + vflip
  248.  
  249.     default:
  250.         DEBUG_PRINT( "Unexpected Attribute : %u", attr );
  251.         t0 = 0u; t1 = 1u; t2 = 2u; t3 = 3u; flip = 0u;
  252.         break;
  253.     }
  254.  
  255.     // tiles
  256.     uint8_t * const ta0 = set_bkg_tile_xy( ( screen_x ) & 31u, ( screen_y ) & 31u, tiles[ t0 ] );
  257.     uint8_t * const ta1 = set_bkg_tile_xy( ( screen_x + 1u ) & 31u, ( screen_y ) & 31u, tiles[ t1 ] );
  258.     uint8_t * const ta2 = set_bkg_tile_xy( ( screen_x ) & 31u, ( screen_y + 1u ) & 31u, tiles[ t2 ] );
  259.     uint8_t * const ta3 = set_bkg_tile_xy( ( screen_x + 1u ) & 31u, ( screen_y + 1u ) & 31u, tiles[ t3 ] );
  260.  
  261.     VBK_REG = 1;
  262.     // attributes
  263.     set_vram_byte( ta0, attrs[ t0 ] ^ flip );
  264.     set_vram_byte( ta1, attrs[ t1 ] ^ flip );
  265.     set_vram_byte( ta2, attrs[ t2 ] ^ flip );
  266.     set_vram_byte( ta3, attrs[ t3 ] ^ flip );
  267.     VBK_REG = 0;
  268. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement