ref: d4f9f78c9d7e54c6fa22aec76987cbcec97ab653
parent: 18c351f101ddcd572360dc21be029ba3e62d45d0
author: Snesrev <snesrev@protonmail.com>
date: Wed Oct 19 13:44:46 EDT 2022
Show widescreen world map
--- a/messaging.c
+++ b/messaging.c
@@ -17,6 +17,8 @@
#include "nmi.h"
#include "assets.h"
+static void WorldMap_AddSprite(int spr, uint8 big, uint8 flags, uint8 ch, uint16 x, uint16 y);
+static bool WorldMap_CalculateOamCoordinates(Point16U *pt);
static const int8 kDungMap_Tab0[14] = {-1, -1, -1, -1, -1, 2, 0, 10, 4, 8, -1, 6, 12, 14};
static const uint16 kDungMap_Tab1[8] = {0x2108, 0x2109, 0x2109, 0x210a, 0x210b, 0x210c, 0x210d, 0x211d};
@@ -1068,7 +1070,7 @@
}
void FluteMenu_HandleSelection() { // 8ab78b
- PointU8 pt;
+ Point16U pt;
if (some_menu_ctr == 0) {
if ((joypad1L_last | joypad1H_last) & 0xc0) {
@@ -1092,7 +1094,7 @@
}
birdtravel_var1[0] = birdtravel_var1[0] & 7;
if (frame_counter & 0x10 && WorldMap_CalculateOamCoordinates(&pt))
- WorldMap_HandleSpriteBlink(16, 2, 0x3e, 0, pt.x - 4, pt.y - 4);
+ WorldMap_AddSprite(16, 2, 0x3e, 0, pt.x - 4, pt.y - 4);
uint16 ybak = link_y_coord_spexit;
uint16 xbak = link_x_coord_spexit;
@@ -1106,7 +1108,7 @@
link_y_coord_spexit = kBirdTravel_y_hi[i] << 8 | kBirdTravel_y_lo[i];
if (WorldMap_CalculateOamCoordinates(&pt))
- WorldMap_HandleSpriteBlink(i, 0, (i == birdtravel_var1[0]) ? 0x30 + (frame_counter & 6) : 0x32, kBirdTravel_tab1[i], pt.x, pt.y);
+ WorldMap_AddSprite(i, 0, (i == birdtravel_var1[0]) ? 0x30 + (frame_counter & 6) : 0x32, kBirdTravel_tab1[i], pt.x, pt.y);
}
link_x_coord_spexit = xbak;
link_y_coord_spexit = ybak;
@@ -1396,10 +1398,10 @@
}
void WorldMap_HandleSprites() { // 8abf66
- PointU8 pt;
+ Point16U pt;
if (frame_counter & 0x10 && WorldMap_CalculateOamCoordinates(&pt))
- WorldMap_HandleSpriteBlink(0, 2, 0x3e, 0, pt.x - 4, pt.y - 4);
+ WorldMap_AddSprite(0, 2, 0x3e, 0, pt.x - 4, pt.y - 4);
uint16 ybak = link_y_coord_spexit;
uint16 xbak = link_x_coord_spexit;
@@ -1411,7 +1413,7 @@
link_x_coord_spexit = bird_travel_x_hi[k] << 8 | bird_travel_x_lo[k];
link_y_coord_spexit = bird_travel_y_hi[k] << 8 | bird_travel_y_lo[k];
if (WorldMap_CalculateOamCoordinates(&pt))
- WorldMap_HandleSpriteBlink(15, 2, kOverworldMap_Table4[frame_counter >> 1 & 3], 0x6a, pt.x, pt.y);
+ WorldMap_AddSprite(15, 2, kOverworldMap_Table4[frame_counter >> 1 & 3], 0x6a, pt.x, pt.y);
}
if (save_ow_event_info[0x5b] & 0x20 || (((savegame_map_icons_indicator >= 6) ^ is_in_dark_world) & 1))
@@ -1433,7 +1435,7 @@
uint8 ext = 2;
if (!(info >> 8))
info = kOwMap_tab2[frame_counter >> 3 & 3] << 8 | 0x32, ext = 0;
- WorldMap_HandleSpriteBlink(14, ext, (uint8)info, (uint8)(info >> 8), pt.x, pt.y);
+ WorldMap_AddSprite(14, ext, (uint8)info, (uint8)(info >> 8), pt.x, pt.y);
}
endif_crystal0:;
}
@@ -1452,7 +1454,7 @@
uint8 ext = 2;
if (!(info >> 8))
info = kOwMap_tab2[frame_counter >> 3 & 3] << 8 | 0x32, ext = 0;
- WorldMap_HandleSpriteBlink(13, ext, (uint8)info, (uint8)(info >> 8), pt.x, pt.y);
+ WorldMap_AddSprite(13, ext, (uint8)info, (uint8)(info >> 8), pt.x, pt.y);
}
endif_crystal1:;
}
@@ -1471,7 +1473,7 @@
uint8 ext = 2;
if (!(info >> 8))
info = kOwMap_tab2[frame_counter >> 3 & 3] << 8 | 0x32, ext = 0;
- WorldMap_HandleSpriteBlink(12, ext, (uint8)info, (uint8)(info >> 8), pt.x, pt.y);
+ WorldMap_AddSprite(12, ext, (uint8)info, (uint8)(info >> 8), pt.x, pt.y);
}
endif_crystal2:;
}
@@ -1490,7 +1492,7 @@
uint8 ext = 2;
if (!(info >> 8))
info = kOwMap_tab2[frame_counter >> 3 & 3] << 8 | 0x32, ext = 0;
- WorldMap_HandleSpriteBlink(11, ext, (uint8)info, (uint8)(info >> 8), pt.x, pt.y);
+ WorldMap_AddSprite(11, ext, (uint8)info, (uint8)(info >> 8), pt.x, pt.y);
}
endif_crystal3:;
}
@@ -1509,7 +1511,7 @@
uint8 ext = 2;
if (!(info >> 8))
info = kOwMap_tab2[frame_counter >> 3 & 3] << 8 | 0x32, ext = 0;
- WorldMap_HandleSpriteBlink(10, ext, (uint8)info, (uint8)(info >> 8), pt.x, pt.y);
+ WorldMap_AddSprite(10, ext, (uint8)info, (uint8)(info >> 8), pt.x, pt.y);
}
endif_crystal4:;
}
@@ -1528,7 +1530,7 @@
uint8 ext = 2;
if (!(info >> 8))
info = kOwMap_tab2[frame_counter >> 3 & 3] << 8 | 0x32, ext = 0;
- WorldMap_HandleSpriteBlink(9, ext, (uint8)info, (uint8)(info >> 8), pt.x, pt.y);
+ WorldMap_AddSprite(9, ext, (uint8)info, (uint8)(info >> 8), pt.x, pt.y);
}
endif_crystal5:;
}
@@ -1547,7 +1549,7 @@
uint8 ext = 2;
if (!(info >> 8))
info = kOwMap_tab2[frame_counter >> 3 & 3] << 8 | 0x32, ext = 0;
- WorldMap_HandleSpriteBlink(8, ext, (uint8)info, (uint8)(info >> 8), pt.x, pt.y);
+ WorldMap_AddSprite(8, ext, (uint8)info, (uint8)(info >> 8), pt.x, pt.y);
}
endif_crystal6:;
}
@@ -1557,13 +1559,11 @@
link_y_coord_spexit = ybak;
}
-bool WorldMap_CalculateOamCoordinates(PointU8 *pt) { // 8ac39f
- uint8 r14, r15;
-
+static bool WorldMap_CalculateOamCoordinates(Point16U *pt) { // 8ac39f
if (overworld_map_flags == 0) {
int j = -(link_y_coord_spexit >> 4) + M7Y_copy + (link_y_coord_spexit >> 3 & 1) - 0xc0;
uint8 t0 = kOverworldMap_tab1[j];
- r15 = 13 * t0 >> 4;
+ uint8 yval = 13 * t0 >> 4;
uint8 at = link_x_coord_spexit >> 4;
bool below = at < 0x80;
@@ -1570,12 +1570,12 @@
at -= 0x80;
if (sign8(at)) at = ~at;
- uint8 t1 = ((r15 < 224 ? r15 : 0) * 0x54 >> 8) + 0xb2;
+ uint8 t1 = ((yval < 224 ? yval : 0) * 0x54 >> 8) + 0xb2;
uint8 t2 = at * t1 >> 8;
uint8 t3 = (below) ? 0x80 - t2 : t2 + 0x80;
pt->x = t3 - BG1HOFS_copy2 + 0x80;
- pt->y = r15 + 12;
+ pt->y = yval + 12;
return true;
} else {
uint16 t0 = -(link_y_coord_spexit >> 4) + M7Y_copy - 0x80;
@@ -1584,13 +1584,13 @@
uint16 t1 = t0 * 37 >> 4;
if (t1 >= 333)
return false;
- r15 = kOverworldMap_tab1[t1];
+ uint8 yval = kOverworldMap_tab1[t1];
uint16 t2 = link_x_coord_spexit;
bool below = t2 < 0x7F8;
t2 -= 0x7f8;
if (sign16(t2))
t2 = -t2;
- uint8 t3 = r15 < 226 ? r15 : 0;
+ uint8 t3 = yval < 226 ? yval : 0;
uint8 t4 = (t3 * 84 >> 8) + 178; // r0
uint8 t5 = (uint8)t2 * t4 >> 8; // r1
uint16 t6 = (uint8)(t2 >> 8) * t4 + t5;
@@ -1601,27 +1601,29 @@
uint8 t9 = (uint8)t8 * 45 >> 8;
uint16 t10 = ((t8 >> 8) * 45) + t9;
uint16 t11 = below2 ? 0x80 - t10 : t10 + 0x80;
- r14 = t11 - BG1HOFS_copy2;
- uint16 t12 = t11 - 0xFF80 - BG1HOFS_copy2;
- if (t12 >= 0x100)
+ uint16 xval = t11 - BG1HOFS_copy2;
+ int xt = enhanced_features0 & kFeatures0_ExtendScreen64 ? 0x48 : 0;
+ if ((uint16)(xval + 0x80 + xt) >= (0x100 + xt * 2))
return false;
- pt->x = r14 + 0x81;
- pt->y = r15 + 16;
+ pt->x = xval + 0x81;
+ pt->y = yval + 16;
return true;
}
}
-void WorldMap_HandleSpriteBlink(int spr, uint8 r11_ext, uint8 r12_flags, uint8 r13_char, uint8 r14_x, uint8 r15_y) { // 8ac51c
- if (!(frame_counter & 0x10) && r13_char == 100) {
+static void WorldMap_AddSprite(int spr, uint8 big, uint8 flags, uint8 ch, uint16 x, uint16 y) { // 8ac51c
+ if (!(frame_counter & 0x10) && ch == 100) {
assert(spr >= 8);
- r13_char = kOverworldMapData[spr - 8];
- r12_flags = 0x32;
- r11_ext = 0;
+ ch = kOverworldMapData[spr - 8];
+ flags = 0x32;
+ big = 0;
} else {
- r14_x -= 4;
- r15_y -= 4;
+ x -= 4;
+ y -= 4;
}
- SetOamPlain(&oam_buf[spr], r14_x, r15_y, r13_char, r12_flags, r11_ext);
+ if (enhanced_features0 & kFeatures0_ExtendScreen64)
+ big |= (x >> 8 & 1);
+ SetOamPlain(&oam_buf[spr], x, y, ch, flags, big);
}
bool OverworldMap_CheckForPendant(int k) { // 8ac5a9
--- a/messaging.h
+++ b/messaging.h
@@ -63,8 +63,6 @@
void WorldMap_SetUpHDMA();
void WorldMap_FillTilemapWithEF();
void WorldMap_HandleSprites();
-bool WorldMap_CalculateOamCoordinates(PointU8 *pt);
-void WorldMap_HandleSpriteBlink(int spr, uint8 r11_ext, uint8 r12_flags, uint8 r13_char, uint8 r14_x, uint8 r15_y);
bool OverworldMap_CheckForPendant(int k);
bool OverworldMap_CheckForCrystal(int k);
void Module0E_03_DungeonMap();
--- a/snes/ppu.c
+++ b/snes/ppu.c
@@ -714,9 +714,6 @@
uint32 xCenter = ((int16_t)(ppu->m7matrix[4] << 3)) >> 3, yCenter = ((int16_t)(ppu->m7matrix[5] << 3)) >> 3;
uint32 clippedH = (((int16_t)(ppu->m7matrix[6] << 3)) >> 3) - xCenter;
uint32 clippedV = (((int16_t)(ppu->m7matrix[7] << 3)) >> 3) - yCenter;
- uint32 m0 = ppu->m7matrix[0]; // xpos increment per horiz movement
- uint32 m3 = ppu->m7matrix[3]; // ypos increment per vert movement
- uint8 *dst_start = &ppu->renderBuffer[(y - 1) * 4 * ppu->renderPitch], *dst_end, *dst = dst_start + ppu->extraLeftRight * 4 * 4;
int32 m0v[4];
if (*(uint32*)&ppu->mode7PerspectiveLow == 0) {
m0v[0] = m0v[1] = m0v[2] = m0v[3] = ppu->m7matrix[0] << 12;
@@ -725,11 +722,15 @@
for (int i = 0; i < 4; i++)
m0v[i] = 4096.0f / FloatInterpolate((int)y + kInterpolateOffsets[i], 0, 223, ppu->mode7PerspectiveLow, ppu->mode7PerspectiveHigh);
}
-
+ size_t pitch = ppu->renderPitch;
+ uint8 *render_buffer_ptr = &ppu->renderBuffer[(y - 1) * 4 * pitch];
+ uint8 *dst_start = render_buffer_ptr + (ppu->extraLeftRight - ppu->extraLeftCur) * 16;
+ size_t draw_width = 256 + ppu->extraLeftCur + ppu->extraRightCur;
+ uint8 *dst_curline = dst_start;
+ uint32 m1 = ppu->m7matrix[1] << 12; // xpos increment per vert movement
+ uint32 m2 = ppu->m7matrix[2] << 12; // ypos increment per horiz movement
for (int j = 0; j < 4; j++) {
- m0 = m3 = m0v[j];
- uint32 m1 = ppu->m7matrix[1] << 12; // xpos increment per vert movement
- uint32 m2 = ppu->m7matrix[2] << 12; // ypos increment per horiz movement
+ uint32 m0 = m0v[j], m3 = m0;
uint32 xpos = m0 * clippedH + m1 * (clippedV + y) + (xCenter << 20), xcur;
uint32 ypos = m2 * clippedH + m3 * (clippedV + y) + (yCenter << 20), ycur;
@@ -738,11 +739,17 @@
ypos -= (m2 + m3) >> 1;
xcur = (xpos << 2) + j * m1;
ycur = (ypos << 2) + j * m3;
- dst_end = dst + 4096;
+ xcur -= ppu->extraLeftCur * 4 * m0;
+ ycur -= ppu->extraLeftCur * 4 * m2;
+
+ uint8 *dst = dst_curline;
+ uint8 *dst_end = dst_curline + draw_width * 16;
+
#define DRAW_PIXEL(mode) \
tile = ppu->vram[(ycur >> 25 & 0x7f) * 128 + (xcur >> 25 & 0x7f)] & 0xff; \
pixel = ppu->vram[tile * 64 + (ycur >> 22 & 7) * 8 + (xcur >> 22 & 7)] >> 8; \
+ pixel = (xcur & 0x80000000) ? 0 : pixel; \
*(uint32*)dst = (mode ? (ppu->colorMapRgb[pixel] & 0xfefefe) >> 1 : ppu->colorMapRgb[pixel]); \
xcur += m0, ycur += m2, dst += 4;
@@ -760,18 +767,17 @@
DRAW_PIXEL(1);
DRAW_PIXEL(1);
} while (dst != dst_end);
-
}
#undef DRAW_PIXEL
- dst += (ppu->renderPitch - 4096);
+
+ dst_curline += pitch;
}
if (ppu->lineHasSprites) {
- PpuZbufType *pixels = ppu->objBuffer.data;
- size_t pitch = ppu->renderPitch;
- uint8 *dst = dst_start + ppu->extraLeftRight * 16;
- for (size_t i = 0; i < 256; i++, dst += 16) {
- uint32 pixel = pixels[i + kPpuExtraLeftRight] & 0xff;
+ uint8 *dst = dst_start;
+ PpuZbufType *pixels = ppu->objBuffer.data + (kPpuExtraLeftRight - ppu->extraLeftCur);
+ for (size_t i = 0; i < draw_width; i++, dst += 16) {
+ uint32 pixel = pixels[i] & 0xff;
if (pixel) {
uint32 color = ppu->colorMapRgb[pixel];
((uint32 *)dst)[3] = ((uint32 *)dst)[2] = ((uint32 *)dst)[1] = ((uint32 *)dst)[0] = color;
@@ -784,15 +790,13 @@
if (ppu->extraLeftRight - ppu->extraLeftCur != 0) {
size_t n = 4 * sizeof(uint32) * (ppu->extraLeftRight - ppu->extraLeftCur);
- size_t pitch = ppu->renderPitch;
for(int i = 0; i < 4; i++)
- memset(dst_start + pitch * i, 0, n);
+ memset(render_buffer_ptr + pitch * i, 0, n);
}
if (ppu->extraLeftRight - ppu->extraRightCur != 0) {
size_t n = 4 * sizeof(uint32) * (ppu->extraLeftRight - ppu->extraRightCur);
- size_t pitch = ppu->renderPitch;
for (int i = 0; i < 4; i++)
- memset(dst_start + pitch * i + (256 + ppu->extraLeftRight * 2 - (ppu->extraLeftRight - ppu->extraRightCur)) * 4 * sizeof(uint32), 0, n);
+ memset(render_buffer_ptr + pitch * i + (256 + ppu->extraLeftRight * 2 - (ppu->extraLeftRight - ppu->extraRightCur)) * 4 * sizeof(uint32), 0, n);
}
#undef DRAW_PIXEL
}
--- a/zelda_rtl.c
+++ b/zelda_rtl.c
@@ -145,10 +145,16 @@
if (mod == 14)
mod = saved_module_for_menu;
if (mod == 9) {
- // outdoors
- extra_left = BG2HOFS_copy2 - ow_scroll_vars0.xstart;
- extra_right = ow_scroll_vars0.xend - BG2HOFS_copy2;
- extra_bottom = ow_scroll_vars0.yend - BG2VOFS_copy2;
+ if (main_module_index == 14 && submodule_index == 7 && overworld_map_state >= 4) {
+ // World map
+ extra_left = kPpuExtraLeftRight, extra_right = kPpuExtraLeftRight;
+ extra_bottom = 16;
+ } else {
+ // outdoors
+ extra_left = BG2HOFS_copy2 - ow_scroll_vars0.xstart;
+ extra_right = ow_scroll_vars0.xend - BG2HOFS_copy2;
+ extra_bottom = ow_scroll_vars0.yend - BG2VOFS_copy2;
+ }
} else if (mod == 7) {
// indoors, except when the light cone is in use
if (!(hdr_dungeon_dark_with_lantern && TS_copy != 0)) {