GPU: Change how DISPCAPCNT's CaptureEnable flag is handled, fixing a graphical issue when starting a battle in Pokemon Black/White. (Regression from r5259.)

- To note: This fix to Pokemon Black/White does not require
CommonSettings.pokehax to be enabled.
- The CaptureEnable flag is now only read at the start of line 0,
instead of being read directly from the DISPCAPCNT register per line.
In addition, this same state is held all the way through line 192.
- The CaptureEnable flag is now reset at the start of line 192, instead
of near the end of line 191 H-blank. (This is the proper behavior
according to GBATEK.)
- The CaptureEnable flag is now only reset when the VRAM configuration
is LCDC, instead of always being reset. This makes it possible for this
flag to remain set on line 192 if the VRAM configuration is changed to
a non-LCDC configuration.
- CommonSettings.pokehax is now initialized to false.
- Fix a small bug when setting CommonSettings.pokehax via the command
line.
This commit is contained in:
rogerman 2017-03-01 18:02:20 -08:00
parent 8e18531784
commit 5e06fbc547
5 changed files with 49 additions and 14 deletions

View File

@ -5122,6 +5122,7 @@ void GPUEngineA::Reset()
this->_Reset_Base();
memset(&this->_dispCapCnt, 0, sizeof(DISPCAPCNT_parsed));
this->_displayCaptureEnable = false;
this->_BGLayer[GPULayerID_BG0].BMPAddress = MMU_ABG;
this->_BGLayer[GPULayerID_BG1].BMPAddress = MMU_ABG;
@ -5253,7 +5254,22 @@ bool GPUEngineA::WillCapture3DLayerDirect(const size_t l)
bool GPUEngineA::WillDisplayCapture(const size_t l)
{
const IOREG_DISPCAPCNT &DISPCAPCNT = this->_IORegisterMap->DISPCAPCNT;
return (DISPCAPCNT.CaptureEnable != 0) && (vramConfiguration.banks[DISPCAPCNT.VRAMWriteBlock].purpose == VramConfiguration::LCDC) && (l < this->_dispCapCnt.capy);
return this->_displayCaptureEnable && (vramConfiguration.banks[DISPCAPCNT.VRAMWriteBlock].purpose == VramConfiguration::LCDC) && (l < this->_dispCapCnt.capy);
}
void GPUEngineA::SetDisplayCaptureEnable()
{
this->_displayCaptureEnable = (this->_IORegisterMap->DISPCAPCNT.CaptureEnable != 0);
}
void GPUEngineA::ResetDisplayCaptureEnable()
{
IOREG_DISPCAPCNT &DISPCAPCNT = this->_IORegisterMap->DISPCAPCNT;
if ( this->_displayCaptureEnable && vramConfiguration.banks[DISPCAPCNT.VRAMWriteBlock].purpose == VramConfiguration::LCDC )
{
DISPCAPCNT.CaptureEnable = 0;
this->_displayCaptureEnable = false;
}
}
bool GPUEngineA::VerifyVRAMLineDidChange(const size_t blockID, const size_t l)
@ -6683,8 +6699,6 @@ void GPUEngineA::_LineLarge8bpp(GPUEngineCompositorInfo &compInfo)
void GPUEngineA::LastLineProcess()
{
this->GPUEngineBase::LastLineProcess();
this->_IORegisterMap->DISPCAPCNT.CaptureEnable = 0;
DISP_FIFOreset();
}
@ -6961,6 +6975,16 @@ void GPUSubsystem::SetWillFrameSkip(const bool willFrameSkip)
this->_willFrameSkip = willFrameSkip;
}
void GPUSubsystem::SetDisplayCaptureEnable()
{
this->_engineMain->SetDisplayCaptureEnable();
}
void GPUSubsystem::ResetDisplayCaptureEnable()
{
this->_engineMain->ResetDisplayCaptureEnable();
}
void GPUSubsystem::UpdateRenderProperties()
{
this->_engineMain->vramBlockOBJIndex = VRAM_NO_3D_USAGE;

View File

@ -1524,6 +1524,7 @@ protected:
u16 *_VRAMCustomBlockPtr[4];
DISPCAPCNT_parsed _dispCapCnt;
bool _displayCaptureEnable;
template<bool ISDEBUGRENDER, bool MOSAIC, bool WILLPERFORMWINDOWTEST, bool COLOREFFECTDISABLEDHINT, bool ISCUSTOMRENDERINGNEEDED> void _LineLarge8bpp(GPUEngineCompositorInfo &compInfo);
@ -1565,6 +1566,8 @@ public:
bool WillRender3DLayer();
bool WillCapture3DLayerDirect(const size_t l);
bool WillDisplayCapture(const size_t l);
void SetDisplayCaptureEnable();
void ResetDisplayCaptureEnable();
bool VerifyVRAMLineDidChange(const size_t blockID, const size_t l);
void LastLineProcess();
@ -1685,6 +1688,8 @@ public:
bool GetWillFrameSkip() const;
void SetWillFrameSkip(const bool willFrameSkip);
void SetDisplayCaptureEnable();
void ResetDisplayCaptureEnable();
void UpdateRenderProperties();
// By default, the displays will automatically perform certain postprocessing steps on the

View File

@ -1480,21 +1480,20 @@ static void execHardware_hstart()
//this should be 214, but we are going to be generous for games with tight timing
//they shouldnt be changing any textures at 262 but they might accidentally still be at 214
//so..
if((CommonSettings.rigorous_timing && nds.VCount==214) || (!CommonSettings.rigorous_timing && nds.VCount==262))
if ( (CommonSettings.rigorous_timing && nds.VCount == 214) || (!CommonSettings.rigorous_timing && nds.VCount == 262) )
{
gfx3d_VBlankEndSignal(frameSkipper.ShouldSkip3D());
}
if(nds.VCount==261)
nds.overclock = 0;
if(nds.VCount==263)
if (nds.VCount == 263)
{
nds.VCount=0;
nds.VCount = 0;
GPU->SetDisplayCaptureEnable();
}
else if(nds.VCount==262)
else if (nds.VCount == 262)
{
if(!(NDS_ARM9.waitIRQ) && nds.overclock < 200 && CommonSettings.pokehax) {
if (!(NDS_ARM9.waitIRQ) && nds.overclock < 200 && CommonSettings.pokehax)
{
nds.overclock++;
nds.VCount = 261;
}
@ -1504,8 +1503,14 @@ static void execHardware_hstart()
execHardware_hstart_vblankEnd();
}
}
else if(nds.VCount==192)
else if (nds.VCount == 261)
{
nds.overclock = 0;
}
else if (nds.VCount == 192)
{
GPU->ResetDisplayCaptureEnable();
//turn on vblank status bit
T1WriteWord(MMU.ARM9_REG, 4, T1ReadWord(MMU.ARM9_REG, 4) | 1);
T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 1);
@ -1541,7 +1546,7 @@ static void execHardware_hstart()
//trigger hstart dmas
triggerDma(EDMAMode_HStart);
if(nds.VCount<192)
if (nds.VCount < 192)
{
//this is hacky.
//there is a corresponding hack in doDMA.

View File

@ -502,6 +502,7 @@ extern struct TCommonSettings {
, cheatsDisable(false)
, rigorous_timing(false)
, advanced_timing(true)
, pokehax(false)
, micMode(InternalNoise)
, spuInterpolationMode(1)
, manualBackupType(0)

View File

@ -354,7 +354,7 @@ bool CommandLine::parse(int argc,char **argv)
if(_num_cores != -1) CommonSettings.num_cores = _num_cores;
if(_rigorous_timing) CommonSettings.rigorous_timing = true;
if(_advanced_timing != -1) CommonSettings.advanced_timing = _advanced_timing==1;
if(_advanced_timing != -1) CommonSettings.pokehax = _pokehax==1;
if(_pokehax != -1) CommonSettings.pokehax = _pokehax==1;
#ifdef HAVE_JIT
if(_cpu_mode != -1) CommonSettings.use_jit = (_cpu_mode==1);