Created
February 23, 2022 21:06
-
-
Save redthing1/efea44226abf197bd0407ad7228b1e69 to your computer and use it in GitHub Desktop.
documented tonc big tilemap bigmap.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <tonc.h> | |
#include "map.h" | |
#include "maps/bigmap.h" | |
#include "assets/pokemonMap.h" | |
#include "assets/Pal0.h" | |
#include "assets/Pal1.h" | |
#include "assets/Pal2.h" | |
#include "assets/Pal3.h" | |
#include "assets/Pal4.h" | |
#include "assets/Pal5.h" | |
#include "assets/Pal6.h" | |
static void append_map_column(int src_tile_x, int src_tile_y); | |
static void append_map_row(int src_tile_x, int src_tile_y); | |
Viewport g_viewport; | |
TMap g_map; | |
void init_map(POINT16 start_pos) { | |
g_map.bgNum = 0; | |
g_map.srcMap = (SCR_ENTRY*) BG_0; | |
g_map.dstMap = se_mem[31]; // One 256x256p map takes up a single screenblock | |
g_map.srcMapWidth = BIGMAP_WIDTH; | |
g_map.srcMapHeight = BIGMAP_HEIGHT; | |
// Copy base tiles to charblock 0 | |
GRIT_CPY(tile_mem[0], pokemonMapTiles); | |
centre_viewport(start_pos); | |
g_viewport.prevOffset = g_viewport.offset; | |
// Tile coordinates (in 128x128t srcMap space) of the top left corner of the viewport | |
int src_y = g_viewport.offset.y / 8; | |
int src_x = g_viewport.offset.x / 8; | |
// Copy first 32x32 tiles around the start pos. from srcMap into dstMap (se_mem) | |
for (int y = 0; y < 32; y++) { | |
append_map_row(src_x, src_y); | |
src_y++; | |
} | |
// Copy palettes to correct banks in BG pallete memory | |
GRIT_CPY(pal_bg_bank[0], Pal0Pal); | |
GRIT_CPY(pal_bg_bank[1], Pal1Pal); | |
GRIT_CPY(pal_bg_bank[2], Pal2Pal); | |
GRIT_CPY(pal_bg_bank[3], Pal3Pal); | |
GRIT_CPY(pal_bg_bank[4], Pal4Pal); | |
GRIT_CPY(pal_bg_bank[5], Pal5Pal); | |
GRIT_CPY(pal_bg_bank[6], Pal6Pal); | |
REG_BGCNT[g_map.bgNum] = BG_CBB(0) | BG_SBB(31) | BG_4BPP | BG_REG_32x32; | |
} | |
void centre_viewport(POINT16 pt) { | |
g_viewport.offset.x = clamp(pt.x - (SCREEN_WIDTH / 2), 0, 1024 - SCREEN_WIDTH); | |
g_viewport.offset.y = clamp(pt.y - (SCREEN_HEIGHT / 2), 0, 1024 - SCREEN_HEIGHT); | |
} | |
/* | |
Check whether the viewport has shifted to another tile (up/down/left/right) this frame. | |
If it has, copy one 32t row/column of srcMap over to dstMap to give the appearance of a | |
larger continuously scrolling map. | |
Since regular backgrounds wrap around by default, REG_BG_OFS (the viewport offset) is modulo | |
256x256p (dimensions of dstMap). We can thus write the newly exposed row/column from srcMap | |
to the row/column in 32x32t dstMap space that is just outside the dimensions of the | |
viewport (in the direction of the shift). | |
The result is that the viewport will always show a 240x160p slice of dstMap that corresponds | |
to the "camera's position" in srcMap (centred around the player's position). | |
*/ | |
void update_map() { | |
// Tile coordinates of the viewport in srcMap | |
int prev_tile_x = g_viewport.prevOffset.x / 8; | |
int prev_tile_y = g_viewport.prevOffset.y / 8; | |
int curr_tile_x = g_viewport.offset.x / 8; | |
int curr_tile_y = g_viewport.offset.y / 8; | |
if (curr_tile_x < prev_tile_x) { | |
append_map_column(curr_tile_x, curr_tile_y); // Append from left side of srcMap | |
} else if (curr_tile_x > prev_tile_x) { | |
append_map_column(curr_tile_x + 31, curr_tile_y); // Append from right side of srcMap | |
} | |
if (curr_tile_y < prev_tile_y) { | |
append_map_row(curr_tile_x, curr_tile_y); // Append from top row of srcMap | |
} else if (curr_tile_y > prev_tile_y) { | |
append_map_row(curr_tile_x, curr_tile_y + 31); // Append from bottom row of srcMap | |
} | |
g_viewport.prevOffset = g_viewport.offset; | |
REG_BG_OFS[g_map.bgNum] = g_viewport.offset; | |
} | |
/* | |
Write one 32t column of SCR_ENTRIES from srcMap to dstMap. | |
Called when the viewport has moved to a new tile coordinate | |
towards the left or right this frame. | |
Parameters: The tile coordinates (in range [srcWidth, srcHeight]) of either | |
a) the top left corner, or | |
b) the top right corner | |
of the viewport window. | |
The column is retrieved from srcMap tile coords | |
(x = src_tile_x, y in [src_tile_y, src_tile_y + 31]). | |
It's copied over to | |
(x = dst_tile_x, y in [0, 31]). | |
*/ | |
static void append_map_column(int src_tile_x, int src_tile_y) { | |
// Find a corresponding column in the 32x32t space of dstMap | |
int dst_tile_x = src_tile_x % 32; | |
int dst_tile_y = src_tile_y % 32; | |
// SCR_ENTRY of the newly exposed tile (top left/right of viewport) in srcMap | |
SCR_ENTRY* src_entry = &g_map.srcMap[src_tile_y * g_map.srcMapWidth + src_tile_x]; | |
// SCR_ENTRY in dstMap (left/rightmost edge of the viewport offset) to write the new tile to | |
SCR_ENTRY* dst_entry = &g_map.dstMap[dst_tile_y * 32 + dst_tile_x]; | |
// Copy over every tile to dstMap for y range [dst_tile_y, dst_tile_y + 31] | |
for(int y = dst_tile_y; y < 32; y++) { | |
// Write a single tile | |
*dst_entry= *src_entry; | |
// Move dst_entry pointer down one tile (dst_tile_y++) | |
dst_entry += 32; | |
// Move src_entry pointer down one tile (src_tile_y++) | |
src_entry += g_map.srcMapWidth; | |
} | |
// Move dst_entry pointer up to y = 0 | |
dst_entry -= 1024; | |
// Copy over every tile to dstMap for y range [0, dst_tile_y - 1] | |
for(int y = 0; y < dst_tile_y; y++) { | |
*dst_entry= *src_entry; | |
dst_entry += 32; | |
src_entry += g_map.srcMapWidth; | |
} | |
} | |
/* | |
Write one 32t row of SCR_ENTRIES from srcMap to dstMap. | |
Called when the viewport has moved up or down one tile coordinate | |
this frame. | |
Parameters: The tile coordinates (in range [srcWidth, srcHeight]) of either | |
a) the top left corner, or | |
b) the bottom left corner | |
of the viewport window. | |
The row is retrieved from srcMap tile coords | |
(x in [src_tile_x, src_tile_x + 31], y = src_tile_y). | |
It's copied over to | |
(x in [0, 31], y = dst_tile_y). | |
*/ | |
static void append_map_row(int src_tile_x, int src_tile_y) { | |
// Find a corresponding row in the 32x32t space of dstMap | |
int dst_tile_x = src_tile_x % 32; | |
int dst_tile_y = src_tile_y % 32; | |
// SCR_ENTRY of the newly exposed tile (top/bottom left of viewport) in srcMap | |
SCR_ENTRY* src_entry = &g_map.srcMap[src_tile_y * g_map.srcMapWidth + src_tile_x]; | |
// SCR_ENTRY in dstMap (top/bottom edge of the viewport offset) to write the new tile to | |
SCR_ENTRY* dst_entry = &g_map.dstMap[dst_tile_y * 32 + dst_tile_x]; | |
// Write every tile to dstMap from x in [dst_tile_x, 31] | |
for(int x = dst_tile_x; x < 32; x++) { | |
*dst_entry = *src_entry; | |
dst_entry++; | |
src_entry++; | |
} | |
// Move dst_entry back to x = 0 | |
dst_entry -= 32; | |
// Write every tile to dstMap from x in [0, dst_tile_x - 1] | |
for(int x = 0; x < dst_tile_x; x++) { | |
*dst_entry = *src_entry; | |
dst_entry++; | |
src_entry++; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment