mirror of
https://github.com/Liondarkz/issn_pc.git
synced 2026-11-07 04:36:01 -10:00
4K: the exposure meter gets room for 4K tiles (the dark picture that comes and goes)
The game meters exposure on tiles of 128x72 pixels: the CPU (eboot 0x171610) sums one float per tile from buffers made for 625 tiles (2500 bytes; four of them, set up at 0x171310 and 0x172320), enough up to 1800p. At a 4K render (900 tiles) it summed whatever lay past them, so the exposure jumped and the picture went dark, back to normal, and dark again (GitHub issue 15, tester logs 11-01 at 3840x2160 with and without the Pro-mode patch; 1080p and 1440p were fine). The 'Bigger light list (needed for native 4K)' patch, on by default, now also makes the four buffers 8192 bytes / 2048 tiles (checked on the 01.07 eboot: all 10 writes apply). With a render size above 1800p and the patch off, the shim does the same (ApplyExposureCapacity). The light list line no longer says 'not enlarged' when the patch already did it. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_014CsPEH9HsibG9QrEt8o9SE
This commit is contained in:
2 files changed
+55
-2
No files matched your search
@@ -262,7 +262,11 @@ static void ApplyLightListCapacity(u32 width, u32 height) {
|
||||
std::memcpy(&mov_imm, at(0x16be1f), 4);
|
||||
if (std::memcmp(at(0x16be04), imul_head, 3) != 0 || std::memcmp(at(0x16be1d), mov_head, 2) != 0 ||
|
||||
imul_imm != Original || mov_imm != Original) {
|
||||
std::printf("Render size: light list not enlarged (the code differs in this eboot.bin)\n");
|
||||
if (imul_imm == mov_imm && imul_imm >= entries) {
|
||||
std::printf("Render size: light list already %u entries (patch)\n", imul_imm);
|
||||
} else {
|
||||
std::printf("Render size: light list not enlarged (the code differs in this eboot.bin)\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
std::memcpy(at(0x16be07), &entries, 4);
|
||||
@@ -270,6 +274,43 @@ static void ApplyLightListCapacity(u32 width, u32 height) {
|
||||
std::printf("Render size: light list %u entries for %ux%u\n", entries, width, height);
|
||||
}
|
||||
|
||||
// issn 11-04: the exposure meter (CPU sum at eboot 0x171610) reads one float per 128x72-pixel tile
|
||||
// from buffers made for 625 tiles (2500 bytes, eboot 0x171310 and 0x172320): enough up to 1800p.
|
||||
// At 4K (900 tiles) it summed bytes past them, and the picture went dark and back (tester logs,
|
||||
// GitHub issue 15). The patch "Bigger light list" enlarges them too; without it, this does.
|
||||
static void ApplyExposureCapacity(u32 width, u32 height) {
|
||||
const u64 tiles = u64((width + 127) / 128) * ((height + 71) / 72);
|
||||
if (tiles <= 625) {
|
||||
return;
|
||||
}
|
||||
static constexpr u64 sizes[4] = {0x17132b, 0x171375, 0x172341, 0x172388}; // mov esi, 0x9c4
|
||||
static constexpr u64 counts[4] = {0x17134f, 0x171399, 0x172364, 0x1723ab}; // mov ecx, 0x271
|
||||
const auto at = [](u64 offset) { return reinterpret_cast<u8*>(g_eboot_address + offset); };
|
||||
bool original = true, patched = true;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
u32 size = 0, count = 0;
|
||||
std::memcpy(&size, at(sizes[i]), 4);
|
||||
std::memcpy(&count, at(counts[i]), 4);
|
||||
original = original && at(sizes[i])[-1] == 0xbe && at(counts[i])[-1] == 0xb9 && size == 0x9c4 &&
|
||||
count == 0x271;
|
||||
patched = patched && size >= tiles * 4 && count >= tiles;
|
||||
}
|
||||
if (patched) {
|
||||
std::printf("Exposure meter: room for %llu tiles (patch)\n", static_cast<unsigned long long>(tiles));
|
||||
return;
|
||||
}
|
||||
if (!original) {
|
||||
std::printf("Exposure meter: not enlarged (the code differs in this eboot.bin): the picture may go dark\n");
|
||||
return;
|
||||
}
|
||||
const u32 count = 2048, size = count * 4;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
std::memcpy(at(sizes[i]), &size, 4);
|
||||
std::memcpy(at(counts[i]), &count, 4);
|
||||
}
|
||||
std::printf("Exposure meter: %u tiles for %ux%u\n", count, width, height);
|
||||
}
|
||||
|
||||
/// The render size at 16:9-basis height h0 in the shape `aspect` (axylpup's SizeAt): wide shapes
|
||||
/// keep the height (up to 32:9), narrow ones keep the 16:9 width (down to 1:1).
|
||||
static void SizeAt(u32 h0, double aspect, u32& width, u32& height) {
|
||||
@@ -413,6 +454,7 @@ static void ApplyRenderSize() {
|
||||
std::memcpy(reinterpret_cast<void*>(g_eboot_address + imm.offset), &value, 4);
|
||||
}
|
||||
ApplyLightListCapacity(width, height);
|
||||
ApplyExposureCapacity(width, height);
|
||||
if (narrow) {
|
||||
const float two_over_k = float(2.0 / (base / aspect));
|
||||
std::memcpy(reinterpret_cast<void*>(g_eboot_address + 0x581c84), &two_over_k, 4);
|
||||
|
||||
@@ -29,10 +29,21 @@
|
||||
<Line Type="bytes" Address="0x0072fa15" Value="E9A65C99006690" OriginalHash="3ee41d36233286e4"/>
|
||||
</PatchList>
|
||||
</Metadata>
|
||||
<Metadata Title="inFAMOUS Second Son" Name="Bigger light list (needed for native 4K)" Note="The game sizes its light lists for 25 600 tiles of 16 pixels (enough up to 1800p); 4K needs 32 400. FR : liste des lumieres agrandie, necessaire pour la 4K native." Author="AYOUB1080p" PatchVer="1.0" AppVer="01.00" AppElf="eboot.bin" isEnabled="true">
|
||||
<Metadata Title="inFAMOUS Second Son" Name="Bigger light list (needed for native 4K)" Note="The game sizes its light lists for 25 600 tiles of 16 pixels (enough up to 1800p); 4K needs 32 400. Also the exposure meter (625 tiles of 128x72 px; 4K needs 900, else the picture goes dark). FR : liste des lumieres agrandie, necessaire pour la 4K native." Author="AYOUB1080p" PatchVer="1.0" AppVer="01.00" AppElf="eboot.bin" isEnabled="true">
|
||||
<PatchList>
|
||||
<Line Type="bytes" Address="0x0056be07" Value="00004800" OriginalHash="4cf5e27f9da5a7b7"/>
|
||||
<Line Type="bytes" Address="0x0056be1f" Value="00004800" OriginalHash="4cf5e27f9da5a7b7"/>
|
||||
<!-- issn 11-04: the exposure meter's tile buffers (four, 2500 bytes / 625 tiles of 128x72 px:
|
||||
enough up to 1800p; 4K needs 900, so the camera's exposure read garbage past them and
|
||||
the picture went dark and back). 8192 bytes / 2048 tiles each. -->
|
||||
<Line Type="bytes" Address="0x0057132b" Value="00200000" OriginalHash="05de299f0f9c851e"/>
|
||||
<Line Type="bytes" Address="0x00571375" Value="00200000" OriginalHash="05de299f0f9c851e"/>
|
||||
<Line Type="bytes" Address="0x00572341" Value="00200000" OriginalHash="05de299f0f9c851e"/>
|
||||
<Line Type="bytes" Address="0x00572388" Value="00200000" OriginalHash="05de299f0f9c851e"/>
|
||||
<Line Type="bytes" Address="0x0057134f" Value="00080000" OriginalHash="bd7e02077b7bafea"/>
|
||||
<Line Type="bytes" Address="0x00571399" Value="00080000" OriginalHash="bd7e02077b7bafea"/>
|
||||
<Line Type="bytes" Address="0x00572364" Value="00080000" OriginalHash="bd7e02077b7bafea"/>
|
||||
<Line Type="bytes" Address="0x005723ab" Value="00080000" OriginalHash="bd7e02077b7bafea"/>
|
||||
</PatchList>
|
||||
</Metadata>
|
||||
<Metadata Title="inFAMOUS Second Son" Name="Streaming: closest city blocks first" Note="Lower priority penalties of the world block streamer (3000/2000/2000 -> 1000/700/700): the blocks nearest to the player are loaded and kept in high detail sooner. FR : streaming, les blocs de la ville les plus proches passent en priorite." Author="AYOUB1080p" PatchVer="1.0" AppVer="01.00" AppElf="eboot.bin" isEnabled="false">
|
||||
|
||||
Reference in new issue
Block a user