shithub: zelda3

Download patch

ref: 2b7e9f69fbd3802da36575de0bd7c8cb5a3716a8
parent: d3138f9e13a3535c1c42aab37b592919a48df4d8
author: Snesrev <snesrev@protonmail.com>
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) {