Skip to content

Instantly share code, notes, and snippets.

@redthing1
Created February 23, 2022 21:06
Show Gist options
  • Save redthing1/efea44226abf197bd0407ad7228b1e69 to your computer and use it in GitHub Desktop.
Save redthing1/efea44226abf197bd0407ad7228b1e69 to your computer and use it in GitHub Desktop.
documented tonc big tilemap bigmap.c
#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