tweak around lcd line timing: make 3d vblank more generous (is still unrealistically brutal since all the rendering happens instantaneously, unlike real HW); give scanlines more time to render (render at end of scanline instead of hblank begin); execute an additional hblank dma on vcount=262 (speculative; fixes jittery nsmb split-parallax clouds)
This commit is contained in:
parent
c9f278e00d
commit
e068592d6b
|
@ -1378,31 +1378,10 @@ static void execHardware_hblank()
|
|||
SPU_Emulate_core();
|
||||
driver->AVI_SoundUpdate(SPU_core->outbuf,spu_core_samples);
|
||||
WAV_WavSoundUpdate(SPU_core->outbuf,spu_core_samples);
|
||||
|
||||
//this logic was formerly at hblank time. it was moved to the beginning of the scanline on a whim
|
||||
if(nds.VCount<192)
|
||||
{
|
||||
//so, we have chosen to do the line drawing at hblank time.
|
||||
//this is the traditional time for it in desmume.
|
||||
//while it may seem more ruthlessly accurate to do it at hstart,
|
||||
//in practice we need to be more forgiving, in case things have overrun the scanline start.
|
||||
//this should be safe since games cannot do anything timing dependent until this next
|
||||
//scanline begins, anyway (as this scanline was in the middle of drawing)
|
||||
//taskSubGpu.execute(renderSubScreen,NULL);
|
||||
GPU_RenderLine(&MainScreen, nds.VCount, frameSkipper.ShouldSkip2D());
|
||||
GPU_RenderLine(&SubScreen, nds.VCount, frameSkipper.ShouldSkip2D());
|
||||
//taskSubGpu.finish();
|
||||
|
||||
//trigger hblank dmas
|
||||
//but notice, we do that just after we finished drawing the line
|
||||
//(values copied by this hdma should not be used until the next scanline)
|
||||
triggerDma(EDMAMode_HBlank);
|
||||
}
|
||||
}
|
||||
|
||||
static void execHardware_hstart_vblankEnd()
|
||||
{
|
||||
nds.VCount = 0;
|
||||
sequencer.nds_vblankEnded = true;
|
||||
sequencer.reschedule = true;
|
||||
|
||||
|
@ -1469,9 +1448,41 @@ static void execHardware_hstart_vcount()
|
|||
|
||||
static void execHardware_hstart()
|
||||
{
|
||||
//this logic keeps moving around.
|
||||
//now, we try and give the game as much time as possible to finish doing its work for the scanline,
|
||||
//by drawing scanline N at the very, very end of scanline N (here at the beginning of scanline N+1)
|
||||
if(nds.VCount<192)
|
||||
{
|
||||
//taskSubGpu.execute(renderSubScreen,NULL);
|
||||
GPU_RenderLine(&MainScreen, nds.VCount, frameSkipper.ShouldSkip2D());
|
||||
GPU_RenderLine(&SubScreen, nds.VCount, frameSkipper.ShouldSkip2D());
|
||||
//taskSubGpu.finish();
|
||||
|
||||
//trigger hblank dmas
|
||||
//but notice, we do that just after we finished drawing the line
|
||||
//(values copied by this hdma should not be used until the next scanline)
|
||||
triggerDma(EDMAMode_HBlank);
|
||||
}
|
||||
|
||||
if(nds.VCount==192)
|
||||
{
|
||||
//we need to trigger one last hblank dma since
|
||||
//a. we're sort of lagged behind by one scanline
|
||||
//b. i think that 193 hblanks actually fire (one for the hblank in scanline 262)
|
||||
//this is demonstrated by NSMB splot-parallaxing clouds
|
||||
//for some reason the game will setup two hdma scroll register buffers
|
||||
//to be run consecutively, and unless we do this, the second buffer will be offset by one scanline
|
||||
//causing a glitch in the 0th scanline
|
||||
triggerDma(EDMAMode_HBlank);
|
||||
}
|
||||
|
||||
nds.VCount++;
|
||||
|
||||
if(nds.VCount==263)
|
||||
{
|
||||
nds.VCount=0;
|
||||
}
|
||||
if(nds.VCount==262)
|
||||
{
|
||||
execHardware_hstart_vblankEnd();
|
||||
} else if(nds.VCount==192)
|
||||
|
@ -1505,8 +1516,12 @@ static void execHardware_hstart()
|
|||
triggerDma(EDMAMode_MemDisplay);
|
||||
}
|
||||
|
||||
|
||||
//end of 3d vblank
|
||||
if(nds.VCount==214)
|
||||
//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)
|
||||
{
|
||||
gfx3d_VBlankEndSignal(frameSkipper.ShouldSkip3D());
|
||||
}
|
||||
|
@ -2151,7 +2166,6 @@ void NDS_Reset()
|
|||
|
||||
nds.wifiCycle = 0;
|
||||
memset(nds.timerCycle, 0, sizeof(u64) * 2 * 4);
|
||||
nds.VCount = 0;
|
||||
nds.old = 0;
|
||||
nds.touchX = nds.touchY = 0;
|
||||
nds.isTouch = 0;
|
||||
|
|
|
@ -525,6 +525,7 @@ extern struct TCommonSettings {
|
|||
|
||||
int num_cores;
|
||||
bool single_core() { return num_cores==1; }
|
||||
bool rigorous_timing;
|
||||
|
||||
struct _Wifi {
|
||||
int mode;
|
||||
|
|
|
@ -37,6 +37,7 @@ CommandLine::CommandLine()
|
|||
: is_cflash_configured(false)
|
||||
, error(NULL)
|
||||
, ctx(g_option_context_new (""))
|
||||
, _rigorous_timing(0)
|
||||
, _play_movie_file(0)
|
||||
, _record_movie_file(0)
|
||||
, _cflash_image(0)
|
||||
|
@ -84,6 +85,7 @@ void CommandLine::loadCommonOptions()
|
|||
{ "num-cores", 0, 0, G_OPTION_ARG_INT, &_num_cores, "Override numcores detection and use this many", "NUM_CORES"},
|
||||
{ "scanline-filter-a", 0, 0, G_OPTION_ARG_INT, &scanline_filter_a, "Intensity of fadeout for scanlines filter (edge) (default 2)", "SCANLINE_FILTER_A"},
|
||||
{ "scanline-filter-b", 0, 0, G_OPTION_ARG_INT, &scanline_filter_b, "Intensity of fadeout for scanlines filter (corner) (default 4)", "SCANLINE_FILTER_B"},
|
||||
{ "rigorous-timing", 0, 0, G_OPTION_ARG_INT, &_rigorous_timing, "Use some rigorous timings instead of unrealistically generous (default 0)", "RIGOROUS_TIMING"},
|
||||
#ifndef _MSC_VER
|
||||
{ "disable-sound", 0, 0, G_OPTION_ARG_NONE, &disable_sound, "Disables the sound emulation", NULL},
|
||||
{ "disable-limiter", 0, 0, G_OPTION_ARG_NONE, &disable_limiter, "Disables the 60fps limiter", NULL},
|
||||
|
@ -115,6 +117,7 @@ bool CommandLine::parse(int argc,char **argv)
|
|||
if(_gbaslot_rom) gbaslot_rom = _gbaslot_rom;
|
||||
|
||||
if(_num_cores != -1) CommonSettings.num_cores = _num_cores;
|
||||
if(_rigorous_timing) CommonSettings.rigorous_timing = true;
|
||||
|
||||
//TODO MAX PRIORITY! change ARM9BIOS etc to be a std::string
|
||||
if(_bios_arm9) { CommonSettings.UseExtBIOS = true; strcpy(CommonSettings.ARM9BIOS,_bios_arm9); }
|
||||
|
|
|
@ -86,6 +86,7 @@ private:
|
|||
int _bios_swi;
|
||||
int _spu_advanced;
|
||||
int _num_cores;
|
||||
int _rigorous_timing;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue