From f0508df4aed53ea10740c97213bd62998af1619d Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Mon, 5 Oct 2020 23:27:42 -0400 Subject: [PATCH] GBHawk: Fix alignment of sprite evaluation when window is activated --- .../Consoles/Nintendo/GBHawk/GBC_GB_PPU.cs | 29 ++++++++++------- .../Consoles/Nintendo/GBHawk/GBC_PPU.cs | 31 ++++++++++++------- .../Consoles/Nintendo/GBHawk/GB_PPU.cs | 31 ++++++++++++------- .../Consoles/Nintendo/GBHawk/PPU.cs | 2 ++ 4 files changed, 58 insertions(+), 35 deletions(-) diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_GB_PPU.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_GB_PPU.cs index 9287e401aa..9466fef2d3 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_GB_PPU.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_GB_PPU.cs @@ -1096,6 +1096,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // x scroll is latched here, only the lower 3 bits are latched though render_offset = scroll_offset = scroll_x % 8; + // sprite scroll offset could change depending on window usage + sprite_scroll_offset = scroll_offset; + render_counter = 0; latch_counter = 0; read_case = 0; @@ -1216,12 +1219,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk render_counter = 8 - scroll_offset; render_offset = 7 - window_x_latch; + + sprite_scroll_offset = 8 - (window_x_latch + 8 - 7) % 8; } else { render_offset = 0; read_case = 4; render_counter = 8; + + sprite_scroll_offset = 8 - (window_x_latch - 7) % 8; } latch_counter = 0; @@ -1349,23 +1356,23 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // there is no penalty if the next sprites to be fetched are within the currentfetch block (8 pixels) if (first_fetch || (last_eval >= consecutive_sprite)) { - if (((last_eval + scroll_offset) % 8) == 0) { sprite_fetch_counter += 5; } - else if (((last_eval + scroll_offset) % 8) == 1) { sprite_fetch_counter += 4; } - else if (((last_eval + scroll_offset) % 8) == 2) { sprite_fetch_counter += 3; } - else if (((last_eval + scroll_offset) % 8) == 3) { sprite_fetch_counter += 2; } - else if (((last_eval + scroll_offset) % 8) == 4) { sprite_fetch_counter += 1; } - else if (((last_eval + scroll_offset) % 8) == 5) { sprite_fetch_counter += 0; } - else if (((last_eval + scroll_offset) % 8) == 6) { sprite_fetch_counter += 0; } - else if (((last_eval + scroll_offset) % 8) == 7) { sprite_fetch_counter += 0; } + if (((last_eval + sprite_scroll_offset) % 8) == 0) { sprite_fetch_counter += 5; } + else if (((last_eval + sprite_scroll_offset) % 8) == 1) { sprite_fetch_counter += 4; } + else if (((last_eval + sprite_scroll_offset) % 8) == 2) { sprite_fetch_counter += 3; } + else if (((last_eval + sprite_scroll_offset) % 8) == 3) { sprite_fetch_counter += 2; } + else if (((last_eval + sprite_scroll_offset) % 8) == 4) { sprite_fetch_counter += 1; } + else if (((last_eval + sprite_scroll_offset) % 8) == 5) { sprite_fetch_counter += 0; } + else if (((last_eval + sprite_scroll_offset) % 8) == 6) { sprite_fetch_counter += 0; } + else if (((last_eval + sprite_scroll_offset) % 8) == 7) { sprite_fetch_counter += 0; } - consecutive_sprite = (int)Math.Floor((double)(last_eval + scroll_offset) / 8) * 8 + 8 - scroll_offset; + consecutive_sprite = (int)Math.Floor((double)(last_eval + sprite_scroll_offset) / 8) * 8 + 8 - sprite_scroll_offset; // special case exists here for sprites at zero with non-zero x-scroll. Not sure exactly the reason for it. if (last_eval == 0) { - if (scroll_offset <= 5) + if (sprite_scroll_offset <= 5) { - sprite_fetch_counter += scroll_offset; + sprite_fetch_counter += sprite_scroll_offset; } else { diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs index 3bf5ebcd5f..bd6001bf40 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs @@ -1051,6 +1051,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // x scroll is latched here, only the lower 3 bits are latched though render_offset = scroll_offset = scroll_x % 8; + // sprite scroll offset could change depending on window usage + sprite_scroll_offset = scroll_offset; + render_counter = 0; latch_counter = 0; read_case = 0; @@ -1170,13 +1173,17 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } render_counter = 8 - scroll_offset; - render_offset = 7 - window_x_latch; + render_offset = 7 - window_x_latch; + + sprite_scroll_offset = 8 - (window_x_latch + 8 - 7) % 8; } else { render_offset = 0; read_case = 4; render_counter = 8; + + sprite_scroll_offset = 8 - (window_x_latch - 7) % 8; } latch_counter = 0; @@ -1315,23 +1322,23 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // there is no penalty if the next sprites to be fetched are within the currentfetch block (8 pixels) if (first_fetch || (last_eval >= consecutive_sprite)) { - if (((last_eval + scroll_offset) % 8) == 0) { sprite_fetch_counter += 5; } - else if (((last_eval + scroll_offset) % 8) == 1) { sprite_fetch_counter += 4; } - else if (((last_eval + scroll_offset) % 8) == 2) { sprite_fetch_counter += 3; } - else if (((last_eval + scroll_offset) % 8) == 3) { sprite_fetch_counter += 2; } - else if (((last_eval + scroll_offset) % 8) == 4) { sprite_fetch_counter += 1; } - else if (((last_eval + scroll_offset) % 8) == 5) { sprite_fetch_counter += 0; } - else if (((last_eval + scroll_offset) % 8) == 6) { sprite_fetch_counter += 0; } - else if (((last_eval + scroll_offset) % 8) == 7) { sprite_fetch_counter += 0; } + if (((last_eval + sprite_scroll_offset) % 8) == 0) { sprite_fetch_counter += 5; } + else if (((last_eval + sprite_scroll_offset) % 8) == 1) { sprite_fetch_counter += 4; } + else if (((last_eval + sprite_scroll_offset) % 8) == 2) { sprite_fetch_counter += 3; } + else if (((last_eval + sprite_scroll_offset) % 8) == 3) { sprite_fetch_counter += 2; } + else if (((last_eval + sprite_scroll_offset) % 8) == 4) { sprite_fetch_counter += 1; } + else if (((last_eval + sprite_scroll_offset) % 8) == 5) { sprite_fetch_counter += 0; } + else if (((last_eval + sprite_scroll_offset) % 8) == 6) { sprite_fetch_counter += 0; } + else if (((last_eval + sprite_scroll_offset) % 8) == 7) { sprite_fetch_counter += 0; } - consecutive_sprite = (int)Math.Floor((double)(last_eval + scroll_offset) / 8) * 8 + 8 - scroll_offset; + consecutive_sprite = (int)Math.Floor((double)(last_eval + sprite_scroll_offset) / 8) * 8 + 8 - sprite_scroll_offset; // special case exists here for sprites at zero with non-zero x-scroll. Not sure exactly the reason for it. if (last_eval == 0) { - if (scroll_offset <= 5) + if (sprite_scroll_offset <= 5) { - sprite_fetch_counter += scroll_offset; + sprite_fetch_counter += sprite_scroll_offset; } else { diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GB_PPU.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GB_PPU.cs index 347deb806c..e2a7290e67 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GB_PPU.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GB_PPU.cs @@ -714,6 +714,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // x scroll is latched here render_offset = scroll_offset = scroll_x % 8; + // sprite scroll offset could change depending on window usage + sprite_scroll_offset = scroll_offset; + render_counter = 0; latch_counter = 0; read_case = 0; @@ -819,12 +822,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk render_counter = 8 - scroll_offset; render_offset = 7 - window_x_latch; + + sprite_scroll_offset = 8 - (window_x_latch + 8 - 7) % 8; } else { render_offset = 0; read_case = 4; - render_counter = 8; + render_counter = 8; + + sprite_scroll_offset = 8 - (window_x_latch - 7) % 8; } latch_counter = 0; @@ -944,23 +951,23 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // there is no penalty if the next sprites to be fetched are within the currentfetch block (8 pixels) if (first_fetch || (last_eval >= consecutive_sprite)) { - if (((last_eval + scroll_offset) % 8) == 0) { sprite_fetch_counter += 5; } - else if (((last_eval + scroll_offset) % 8) == 1) { sprite_fetch_counter += 4; } - else if (((last_eval + scroll_offset) % 8) == 2) { sprite_fetch_counter += 3; } - else if (((last_eval + scroll_offset) % 8) == 3) { sprite_fetch_counter += 2; } - else if (((last_eval + scroll_offset) % 8) == 4) { sprite_fetch_counter += 1; } - else if (((last_eval + scroll_offset) % 8) == 5) { sprite_fetch_counter += 0; } - else if (((last_eval + scroll_offset) % 8) == 6) { sprite_fetch_counter += 0; } - else if (((last_eval + scroll_offset) % 8) == 7) { sprite_fetch_counter += 0; } + if (((last_eval + sprite_scroll_offset) % 8) == 0) { sprite_fetch_counter += 5; } + else if (((last_eval + sprite_scroll_offset) % 8) == 1) { sprite_fetch_counter += 4; } + else if (((last_eval + sprite_scroll_offset) % 8) == 2) { sprite_fetch_counter += 3; } + else if (((last_eval + sprite_scroll_offset) % 8) == 3) { sprite_fetch_counter += 2; } + else if (((last_eval + sprite_scroll_offset) % 8) == 4) { sprite_fetch_counter += 1; } + else if (((last_eval + sprite_scroll_offset) % 8) == 5) { sprite_fetch_counter += 0; } + else if (((last_eval + sprite_scroll_offset) % 8) == 6) { sprite_fetch_counter += 0; } + else if (((last_eval + sprite_scroll_offset) % 8) == 7) { sprite_fetch_counter += 0; } - consecutive_sprite = (int)Math.Floor((double)(last_eval + scroll_offset) / 8) * 8 + 8 - scroll_offset; + consecutive_sprite = (int)Math.Floor((double)(last_eval + sprite_scroll_offset) / 8) * 8 + 8 - sprite_scroll_offset; // special case exists here for sprites at zero with non-zero x-scroll. Not sure exactly the reason for it. if (last_eval == 0) { - if (scroll_offset <= 5) + if (sprite_scroll_offset <= 5) { - sprite_fetch_counter += scroll_offset; + sprite_fetch_counter += sprite_scroll_offset; } else { diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs index 46605f916f..dd69c5e8b0 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs @@ -113,6 +113,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk public int window_y_latch; public int hbl_countdown; + public int sprite_scroll_offset; public virtual byte ReadReg(int addr) { @@ -274,6 +275,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk ser.Sync(nameof(window_y_latch), ref window_y_latch); ser.Sync(nameof(hbl_countdown), ref hbl_countdown); + ser.Sync(nameof(sprite_scroll_offset), ref sprite_scroll_offset); } } }