ref: 2b7e9f69fbd3802da36575de0bd7c8cb5a3716a8
parent: d3138f9e13a3535c1c42aab37b592919a48df4d8
author: Snesrev <[email protected]>
date: Sat Oct 1 17:46:10 EDT 2022
Write directly to VRAM instead of through zelda_ppu_write
--- a/attract.c
+++ b/attract.c
@@ -532,7 +532,7 @@
CGWSEL_copy = 2;
CGADSUB_copy = 0x20;
misc_sprites_graphics_index = 10;
- LoadCommonSprites_2();
+ LoadCommonSprites();
uint16 bak0 = attract_var12;
uint16 bak1 = WORD(attract_state);
Dungeon_LoadAndDrawEntranceRoom(0x74);
--- a/ending.c
+++ b/ending.c
@@ -143,13 +143,13 @@
load_chr_halfslot_even_odd = 0;
LoadOWMusicIfNeeded();
- zelda_ppu_write(VMAIN, 0x80);
- zelda_ppu_write_word(VMADDL, 0x27f0);
- int i = 16;
- do {
- zelda_ppu_write_word(VMDATAL, 0);
+ // why 17?
+ for(int i = 0; i < 17; i++)
main_palette_buffer[144 + i] = 0x7fff;
- } while (--i >= 0);
+
+ for (int i = 0; i < 17; i++)
+ g_zenv.vram[0x27f0 + i] = 0;
+
R16 = 0x1ffe;
R18 = 0x1bfe;
}
@@ -664,7 +664,7 @@
void Intro_InitializeTriforcePolyThread() { // 8cc33c
misc_sprites_graphics_index = 8;
- LoadCommonSprites_2();
+ LoadCommonSprites();
Intro_InitGfx_Helper();
intro_sprite_isinited[0] = 1;
intro_sprite_isinited[1] = 1;
@@ -1007,7 +1007,7 @@
void TriforceRoom_PrepGFXSlotForPoly() { // 8cca54
misc_sprites_graphics_index = 8;
- LoadCommonSprites_2();
+ LoadCommonSprites();
Intro_InitGfx_Helper();
intro_sprite_isinited[0] = 1;
intro_sprite_isinited[1] = 1;
@@ -1021,7 +1021,7 @@
void Credits_InitializePolyhedral() { // 8cca81
misc_sprites_graphics_index = 8;
- LoadCommonSprites_2();
+ LoadCommonSprites();
Intro_InitGfx_Helper();
poly_config1 = 0;
intro_sprite_isinited[0] = 1;
--- a/load_gfx.c
+++ b/load_gfx.c
@@ -413,11 +413,10 @@
EraseTileMaps(0x7f, 0x1ec);
}
-void DecompAndUpload2bpp(uint8 pack) {
+static void DecompAndUpload2bpp(uint16 *vram_ptr, uint8 pack) {
Decomp_spr(&g_ram[0x14000], pack);
const uint8 *src = &g_ram[0x14000];
- for (int i = 0; i < 1024; i++, src += 2)
- zelda_ppu_write_word(VMDATAL, WORD(src[0]));
+ memcpy(vram_ptr, src, 1024 * sizeof(uint16));
}
void RecoverPegGFXFromMapping() {
@@ -816,9 +815,8 @@
}
void InitializeTilesets() { // 80e19b
- zelda_ppu_write(VMAIN, 0x80);
- zelda_ppu_write_word(VMADDL, 0x4400);
LoadCommonSprites();
+
const uint8 *p = kSpriteTilesets[sprite_graphics_index];
if (p[0]) sprite_gfx_subset_0 = p[0];
if (p[1]) sprite_gfx_subset_1 = p[1];
@@ -825,13 +823,11 @@
if (p[2]) sprite_gfx_subset_2 = p[2];
if (p[3]) sprite_gfx_subset_3 = p[3];
- LoadSpriteGraphics(sprite_gfx_subset_0, &g_ram[0x7800]);
- LoadSpriteGraphics(sprite_gfx_subset_1, &g_ram[0x7e00]);
- LoadSpriteGraphics(sprite_gfx_subset_2, &g_ram[0x8400]);
- LoadSpriteGraphics(sprite_gfx_subset_3, &g_ram[0x8a00]);
+ LoadSpriteGraphics(&g_zenv.vram[0x5000], sprite_gfx_subset_0, &g_ram[0x7800]);
+ LoadSpriteGraphics(&g_zenv.vram[0x5400], sprite_gfx_subset_1, &g_ram[0x7e00]);
+ LoadSpriteGraphics(&g_zenv.vram[0x5800], sprite_gfx_subset_2, &g_ram[0x8400]);
+ LoadSpriteGraphics(&g_zenv.vram[0x5c00], sprite_gfx_subset_3, &g_ram[0x8a00]);
- zelda_ppu_write_word(VMADDL, 0x2000);
-
const uint8 *mt = kMainTilesets[main_tile_theme_index];
const uint8 *at = kAuxTilesets[aux_tile_theme_index];
@@ -840,53 +836,43 @@
aux_bg_subset_2 = at[2] ? at[2] : mt[5];
aux_bg_subset_3 = at[3] ? at[3] : mt[6];
- LoadBackgroundGraphics(mt[0], 7, &g_ram[0x14000]);
- LoadBackgroundGraphics(mt[1], 6, &g_ram[0x14000]);
- LoadBackgroundGraphics(mt[2], 5, &g_ram[0x14000]);
- LoadBackgroundGraphics(aux_bg_subset_0, 4, &g_ram[0x6000]);
- LoadBackgroundGraphics(aux_bg_subset_1, 3, &g_ram[0x6600]);
- LoadBackgroundGraphics(aux_bg_subset_2, 2, &g_ram[0x6c00]);
- LoadBackgroundGraphics(aux_bg_subset_3, 1, &g_ram[0x7200]);
- LoadBackgroundGraphics(mt[7], 0, &g_ram[0x14000]);
+ LoadBackgroundGraphics(&g_zenv.vram[0x2000], mt[0], 7, &g_ram[0x14000]);
+ LoadBackgroundGraphics(&g_zenv.vram[0x2400], mt[1], 6, &g_ram[0x14000]);
+ LoadBackgroundGraphics(&g_zenv.vram[0x2800], mt[2], 5, &g_ram[0x14000]);
+ LoadBackgroundGraphics(&g_zenv.vram[0x2c00], aux_bg_subset_0, 4, &g_ram[0x6000]);
+ LoadBackgroundGraphics(&g_zenv.vram[0x3000], aux_bg_subset_1, 3, &g_ram[0x6600]);
+ LoadBackgroundGraphics(&g_zenv.vram[0x3400], aux_bg_subset_2, 2, &g_ram[0x6c00]);
+ LoadBackgroundGraphics(&g_zenv.vram[0x3800], aux_bg_subset_3, 1, &g_ram[0x7200]);
+ LoadBackgroundGraphics(&g_zenv.vram[0x3c00], mt[7], 0, &g_ram[0x14000]);
}
void LoadDefaultGraphics() { // 80e2d0
- zelda_ppu_write(VMAIN, 0x80);
- zelda_ppu_write_word(VMADDL, 0x4000);
const uint8 *src = GetCompSpritePtr(0);
+ uint16 *vram_ptr = &g_zenv.vram[0x4000];
uint16 *tmp = (uint16 *)&g_ram[0xbf];
int num = 64;
do {
for (int i = 7; i >= 0; i--, src += 2) {
- zelda_ppu_write_word(VMDATAL, WORD(src[0]));
+ *vram_ptr++ = WORD(src[0]);
tmp[i] = src[0] | src[1];
}
for (int i = 7; i >= 0; i--, src++) {
- zelda_ppu_write_word(VMDATAL, src[0] | (src[0] | tmp[i]) << 8);
+ *vram_ptr++ = src[0] | (src[0] | tmp[i]) << 8;
}
} while (--num);
// Load 2bpp graphics used for hud
- zelda_ppu_write_word(VMADDL, 0x7000);
- DecompAndUpload2bpp(0x6a);
- DecompAndUpload2bpp(0x6b);
- DecompAndUpload2bpp(0x69);
+ DecompAndUpload2bpp(&g_zenv.vram[0x7000], 0x6a);
+ DecompAndUpload2bpp(&g_zenv.vram[0x7400], 0x6b);
+ DecompAndUpload2bpp(&g_zenv.vram[0x7800], 0x69);
}
void Attract_LoadBG3GFX() { // 80e36d
// load 2bpp gfx for attract images
- zelda_ppu_write(VMAIN, 0x80);
- zelda_ppu_write_word(VMADDL, 0x7800);
- DecompAndUpload2bpp(0x67);
+ DecompAndUpload2bpp(&g_zenv.vram[0x7800], 0x67);
}
-void LoadCommonSprites_2() { // 80e384
- zelda_ppu_write(VMAIN, 0x80);
- zelda_ppu_write_word(VMADDL, 0x4400);
- LoadCommonSprites();
-}
-
void Graphics_LoadChrHalfSlot() { // 80e3fa
int k = load_chr_halfslot_even_odd;
if (k == 0)
@@ -949,64 +935,59 @@
}
void TransferFontToVRAM() { // 80e556
- zelda_ppu_write(VMAIN, 0x80);
- zelda_ppu_write_word(VMADDL, 0x7000);
- const uint16 *src = GetFontPtr();
- for (int i = 0; i != 0x800; i++, src++)
- zelda_ppu_write_word(VMDATAL, *src);
+ memcpy(&g_zenv.vram[0x7000], GetFontPtr(), 0x800 * sizeof(uint16));
}
-void LoadSpriteGraphics(int gfx_pack, uint8 *decomp_addr) { // 80e583
- Decomp_spr(decomp_addr, gfx_pack);
-
- if (gfx_pack == 0x52 || gfx_pack == 0x53 || gfx_pack == 0x5a || gfx_pack == 0x5b ||
- gfx_pack == 0x5c || gfx_pack == 0x5e || gfx_pack == 0x5f)
- Do3To4High(decomp_addr);
- else
- Do3To4Low(decomp_addr);
-}
-
-void Do3To4High(const uint8 *decomp_addr) { // 80e5af
+void Do3To4High(uint16 *vram_ptr, const uint8 *decomp_addr) { // 80e5af
for (int j = 0; j < 64; j++) {
uint16 *t = (uint16 *)&dung_line_ptrs_row0;
for (int i = 7; i >= 0; i--, decomp_addr += 2) {
uint16 d = *(uint16 *)decomp_addr;
t[i] = (d | (d >> 8)) & 0xff;
- zelda_ppu_write_word(VMDATAL, d);
+ *vram_ptr++ = d;
}
for (int i = 7; i >= 0; i--, decomp_addr += 1) {
uint8 d = *decomp_addr;
- zelda_ppu_write_word(VMDATAL, d | (t[i] | d) << 8);
+ *vram_ptr++ = d | (t[i] | d) << 8;
}
}
}
-void LoadBackgroundGraphics(int gfx_pack, int slot, uint8 *decomp_addr) { // 80e609
- Decomp_bg(decomp_addr, gfx_pack);
- if ((main_tile_theme_index >= 0x20) ? (slot == 7 || slot == 2 || slot == 3 || slot == 4) : (slot >= 4))
- Do3To4High(decomp_addr);
- else
- Do3To4Low(decomp_addr);
-}
-
-void Do3To4Low(const uint8 *decomp_addr) { // 80e63c
+void Do3To4Low(uint16 *vram_ptr, const uint8 *decomp_addr) { // 80e63c
for (int j = 0; j < 64; j++) {
for (int i = 0; i < 8; i++, decomp_addr += 2)
- zelda_ppu_write_word(VMDATAL, *(uint16 *)decomp_addr);
+ *vram_ptr++ = *(uint16 *)decomp_addr;
for (int i = 0; i < 8; i++, decomp_addr += 1)
- zelda_ppu_write_word(VMDATAL, *decomp_addr);
+ *vram_ptr++ = *decomp_addr;
}
}
+void LoadSpriteGraphics(uint16 *vram_ptr, int gfx_pack, uint8 *decomp_addr) { // 80e583
+ Decomp_spr(decomp_addr, gfx_pack);
+ if (gfx_pack == 0x52 || gfx_pack == 0x53 || gfx_pack == 0x5a || gfx_pack == 0x5b ||
+ gfx_pack == 0x5c || gfx_pack == 0x5e || gfx_pack == 0x5f)
+ Do3To4High(vram_ptr, decomp_addr);
+ else
+ Do3To4Low(vram_ptr, decomp_addr);
+}
+
+void LoadBackgroundGraphics(uint16 *vram_ptr, int gfx_pack, int slot, uint8 *decomp_addr) { // 80e609
+ Decomp_bg(decomp_addr, gfx_pack);
+ if ((main_tile_theme_index >= 0x20) ? (slot == 7 || slot == 2 || slot == 3 || slot == 4) : (slot >= 4))
+ Do3To4High(vram_ptr, decomp_addr);
+ else
+ Do3To4Low(vram_ptr, decomp_addr);
+}
+
void LoadCommonSprites() { // 80e6b7
- Do3To4High(GetCompSpritePtr(misc_sprites_graphics_index));
+ Do3To4High(&g_zenv.vram[0x4400], GetCompSpritePtr(misc_sprites_graphics_index));
if (main_module_index != 1) {
- Do3To4Low(GetCompSpritePtr(6));
- Do3To4Low(GetCompSpritePtr(7));
+ Do3To4Low(&g_zenv.vram[0x4800], GetCompSpritePtr(6));
+ Do3To4Low(&g_zenv.vram[0x4c00], GetCompSpritePtr(7));
} else {
// select file
- LoadSpriteGraphics(94, &g_ram[0x14000]);
- LoadSpriteGraphics(95, &g_ram[0x14000]);
+ LoadSpriteGraphics(&g_zenv.vram[0x4800], 94, &g_ram[0x14000]);
+ LoadSpriteGraphics(&g_zenv.vram[0x4c00], 95, &g_ram[0x14000]);
}
}
--- a/load_gfx.h
+++ b/load_gfx.h
@@ -20,7 +20,6 @@
uint8 *LoadItemAnimationGfxOne(uint8 *dst, int num, int r12, bool from_temp);
uint16 snes_divide(uint16 dividend, uint8 divisor);
void EraseTileMaps_normal();
-void DecompAndUpload2bpp(uint8 pack);
void RecoverPegGFXFromMapping();
void LoadOverworldMapPalette();
void EraseTileMaps_triforce();
@@ -52,13 +51,12 @@
void InitializeTilesets();
void LoadDefaultGraphics();
void Attract_LoadBG3GFX();
-void LoadCommonSprites_2();
void Graphics_LoadChrHalfSlot();
void TransferFontToVRAM();
-void LoadSpriteGraphics(int gfx_pack, uint8 *decomp_addr);
-void Do3To4High(const uint8 *decomp_addr);
-void LoadBackgroundGraphics(int gfx_pack, int slot, uint8 *decomp_addr);
-void Do3To4Low(const uint8 *decomp_addr);
+void Do3To4High(uint16 *vram_ptr, const uint8 *decomp_addr);
+void Do3To4Low(uint16 *vram_ptr, const uint8 *decomp_addr);
+void LoadSpriteGraphics(uint16 *vram_ptr, int gfx_pack, uint8 *decomp_addr);
+void LoadBackgroundGraphics(uint16 *vram_ptr, int gfx_pack, int slot, uint8 *decomp_addr);
void LoadCommonSprites();
int Decomp_spr(uint8 *dst, int gfx);
int Decomp_bg(uint8 *dst, int gfx);
--- a/nmi.c
+++ b/nmi.c
@@ -46,11 +46,11 @@
NMI_HandleArbitraryTileMap(&g_ram[0x13000], 0x40, 0x80);
}
-void CopyToVram(uint32 dstv, const uint8 *src, int len) {
+static void CopyToVram(uint32 dstv, const uint8 *src, int len) {
memcpy(&g_zenv.vram[dstv], src, len);
}
-void CopyToVramVertical(uint32 dstv, const uint8 *src, int len) {
+static void CopyToVramVertical(uint32 dstv, const uint8 *src, int len) {
assert(!(len & 1));
uint16 *dst = &g_zenv.vram[dstv];
for (int i = 0, i_end = len >> 1; i < i_end; i++, dst += 32, src += 2)
@@ -57,12 +57,10 @@
*dst = WORD(*src);
}
-void CopyToVramLow(const uint8 *src, uint32 addr, int num) {
- zelda_ppu_write(VMAIN, 0);
- zelda_ppu_write_word(VMADDL, addr);
- for (int i = 0; i < num; i++) {
- zelda_ppu_write(VMDATAL, *src++);
- }
+static void CopyToVramLow(const uint8 *src, uint32 addr, int num) {
+ uint16 *dst = &g_zenv.vram[addr];
+ for (int i = 0; i < num; i++)
+ dst[i] = (dst[i] & ~0xff) | src[i];
}
void WritePpuRegisters() {
--- a/nmi.h
+++ b/nmi.h
@@ -3,9 +3,6 @@
void NMI_UploadSubscreenOverlayFormer();
void NMI_UploadSubscreenOverlayLatter();
-void CopyToVram(uint32 dstv, const uint8 *src, int len);
-void CopyToVramVertical(uint32 dstv, const uint8 *src, int len);
-void CopyToVramLow(const uint8 *src, uint32 addr, int num);
void Interrupt_NMI(uint16 joypad_input);
void NMI_ReadJoypads(uint16 joypad_input);
void NMI_DoUpdates();
--- a/select_file.c
+++ b/select_file.c
@@ -184,25 +184,16 @@
}
void LoadFileSelectGraphics() { // 80e4e9
- zelda_ppu_write(VMAIN, 0x80);
- zelda_ppu_write_word(VMADDL, 0x5000);
-
Decomp_spr(&g_ram[0x14000], 0x5e);
- Do3To4High(&g_ram[0x14000]);
+ Do3To4High(&g_zenv.vram[0x5000], &g_ram[0x14000]);
Decomp_spr(&g_ram[0x14000], 0x5f);
- Do3To4High(&g_ram[0x14000]);
+ Do3To4High(&g_zenv.vram[0x5400], &g_ram[0x14000]);
- zelda_ppu_write_word(VMADDL, 0x7000);
+ memcpy(&g_zenv.vram[0x7000], GetFontPtr(), 0x800 * sizeof(uint16));
- const uint16 *src = GetFontPtr();
- for (int i = 0; i < 0x800; i++)
- zelda_ppu_write_word(VMDATAL, *src++);
-
Decomp_spr(&g_ram[0x14000], 0x6b);
- src = (const uint16 *)&g_ram[0x14000];
- for (int i = 0; i < 0x300; i++)
- zelda_ppu_write_word(VMDATAL, *src++);
+ memcpy(&g_zenv.vram[0x7800], &g_ram[0x14000], 0x300 * sizeof(uint16));
}
void Intro_ValidateSram() { // 828054
--- a/snes/ppu.c
+++ b/snes/ppu.c
@@ -1417,7 +1417,7 @@
ppu->scrollPrev = val;
break;
}
- case 0x15: {
+ case 0x15: { // VMAIN
if((val & 3) == 0) {
ppu->vramIncrement = 1;
} else if((val & 3) == 1) {