#include "map.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include "game.h"
|
|
#include "player.h"
|
|
#include "sdk/hardware.h"
|
|
#include "vram.h"
|
|
|
|
#define INIT_SCX ((SCRN_VX - SCRN_X) / 2)
|
|
#define INIT_SCY ((SCRN_VY - SCRN_Y) / 2)
|
|
|
|
map_t MAP;
|
|
|
|
#define ROW_BUFFER_SIZE (SCRN_X_B + 4)
|
|
#define COL_BUFFER_SIZE (SCRN_Y_B + 4)
|
|
|
|
uint8_t pending_row[ROW_BUFFER_SIZE];
|
|
uint16_t pending_row_dest;
|
|
|
|
uint8_t pending_col[COL_BUFFER_SIZE];
|
|
uint16_t pending_col_dest;
|
|
|
|
static void map_write_row(uint16_t map_ptr, int8_t x0, int8_t y0);
|
|
|
|
static void map_write_col(uint16_t map_ptr, int8_t x0, int8_t y0);
|
|
|
|
void map_load(map_t *map) {
|
|
MAP = *map;
|
|
|
|
rSCX = INIT_SCX;
|
|
rSCY = INIT_SCY;
|
|
|
|
PLAYER.x = (MAP.spawn_x - MAP.camera_x) * 8;
|
|
PLAYER.y = (MAP.spawn_y - MAP.camera_y) * 8;
|
|
|
|
memcpy(VRAM_TILE_PTR(TILE_INDEX_BACKGROUND), (uint8_t *)MAP.tile_ptr,
|
|
MAP.tile_size);
|
|
|
|
int8_t x0 = MAP.camera_x - INIT_SCX / 8;
|
|
int8_t y0 = MAP.camera_y - INIT_SCY / 8;
|
|
uint16_t map_ptr = _SCRN0;
|
|
|
|
for (uint8_t i = 0; i < SCRN_VY_B; ++i) {
|
|
map_write_row(map_ptr, x0, y0);
|
|
map_ptr += SCRN_VX_B;
|
|
y0++;
|
|
}
|
|
|
|
pending_row_dest = 0;
|
|
pending_col_dest = 0;
|
|
}
|
|
|
|
void map_update(void) {
|
|
if (pending_row_dest != 0) {
|
|
vram_enqueue_mem_xfer(XFER_TYPE_ROW, pending_row_dest, &pending_row[0],
|
|
sizeof pending_row);
|
|
pending_row_dest = 0;
|
|
}
|
|
|
|
if (pending_col_dest != 0) {
|
|
vram_enqueue_mem_xfer(XFER_TYPE_COL, pending_col_dest, &pending_col[0],
|
|
sizeof pending_col);
|
|
pending_col_dest = 0;
|
|
}
|
|
}
|
|
|
|
static void map_enqueue_row(uint16_t vram_ptr, int8_t x0, int8_t y0) {
|
|
pending_row_dest = vram_ptr;
|
|
|
|
if (y0 < 0 || y0 >= MAP.map_height) {
|
|
memset(&pending_row[0], TILE_INDEX_BACKGROUND, sizeof pending_row);
|
|
return;
|
|
}
|
|
|
|
uint8_t *map_ptr = (uint8_t *)(MAP.map_ptr + y0 * MAP.map_width);
|
|
uint8_t left = sizeof pending_row;
|
|
uint8_t *row = &pending_row[0];
|
|
|
|
while (left > 0 && x0 < 0) {
|
|
*row++ = TILE_INDEX_BACKGROUND;
|
|
x0++;
|
|
left--;
|
|
}
|
|
|
|
while (left > 0 && x0 < MAP.map_height) {
|
|
*row++ = TILE_INDEX_BACKGROUND + *map_ptr++;
|
|
x0++;
|
|
left--;
|
|
}
|
|
|
|
while (left > 0) {
|
|
*row++ = TILE_INDEX_BACKGROUND;
|
|
left--;
|
|
}
|
|
}
|
|
|
|
static void map_write_row(uint16_t vram_ptr, int8_t x0, int8_t y0) {
|
|
uint8_t *row = (uint8_t *)vram_ptr;
|
|
|
|
if (y0 < 0 || y0 >= MAP.map_height) {
|
|
memset(row, TILE_INDEX_BACKGROUND, SCRN_VX_B);
|
|
return;
|
|
}
|
|
|
|
uint8_t *map_ptr = (uint8_t *)(MAP.map_ptr + y0 * MAP.map_width);
|
|
uint8_t left = SCRN_VX_B;
|
|
|
|
while (left > 0 && x0 < 0) {
|
|
*row++ = TILE_INDEX_BACKGROUND;
|
|
x0++;
|
|
left--;
|
|
}
|
|
|
|
while (left > 0 && x0 < MAP.map_height) {
|
|
*row++ = TILE_INDEX_BACKGROUND + *map_ptr++;
|
|
x0++;
|
|
left--;
|
|
}
|
|
|
|
while (left > 0) {
|
|
*row++ = TILE_INDEX_BACKGROUND;
|
|
left--;
|
|
}
|
|
}
|
|
|
|
static void map_write_col(uint16_t map_ptr, int8_t x0, int8_t y0) {}
|