pvr: reschedule spg when SPG_HBLANK_INT is updated
Fixes Triggerheart Exelica input lag Issue #691
This commit is contained in:
parent
2332884d8b
commit
19204882c4
|
@ -205,6 +205,14 @@ void pvr_WriteReg(u32 paddr,u32 data)
|
|||
data &= 0x01fffffc;
|
||||
break;
|
||||
|
||||
case SPG_HBLANK_INT_addr:
|
||||
data &= 0x03FF33FF;
|
||||
if (data != SPG_HBLANK_INT.full) {
|
||||
SPG_HBLANK_INT.full = data;
|
||||
rescheduleSPG();
|
||||
}
|
||||
return;
|
||||
|
||||
case PAL_RAM_CTRL_addr:
|
||||
pal_needs_update = pal_needs_update || ((data ^ PAL_RAM_CTRL) & 3) != 0;
|
||||
break;
|
||||
|
|
|
@ -55,6 +55,39 @@ void CalculateSync()
|
|||
sh4_sched_request(vblank_schid, Line_Cycles);
|
||||
}
|
||||
|
||||
static int getNextSpgInterrupt()
|
||||
{
|
||||
u32 min_scanline = prv_cur_scanline + 1;
|
||||
u32 min_active = pvr_numscanlines;
|
||||
|
||||
if (min_scanline < SPG_VBLANK_INT.vblank_in_interrupt_line_number)
|
||||
min_active = std::min(min_active, SPG_VBLANK_INT.vblank_in_interrupt_line_number);
|
||||
|
||||
if (min_scanline < SPG_VBLANK_INT.vblank_out_interrupt_line_number)
|
||||
min_active = std::min(min_active, SPG_VBLANK_INT.vblank_out_interrupt_line_number);
|
||||
|
||||
if (min_scanline < SPG_VBLANK.vstart)
|
||||
min_active = std::min(min_active, SPG_VBLANK.vstart);
|
||||
|
||||
if (min_scanline < SPG_VBLANK.vbend)
|
||||
min_active = std::min(min_active, SPG_VBLANK.vbend);
|
||||
|
||||
if (lightgun_line != 0xffff && min_scanline < lightgun_line)
|
||||
min_active = std::min(min_active, lightgun_line);
|
||||
|
||||
if (SPG_HBLANK_INT.hblank_int_mode == 0 && min_scanline < SPG_HBLANK_INT.line_comp_val)
|
||||
min_active = std::min(min_active, SPG_HBLANK_INT.line_comp_val);
|
||||
|
||||
min_active = std::max(min_active, min_scanline);
|
||||
|
||||
return (min_active - prv_cur_scanline) * Line_Cycles;
|
||||
}
|
||||
|
||||
void rescheduleSPG()
|
||||
{
|
||||
sh4_sched_request(vblank_schid, getNextSpgInterrupt());
|
||||
}
|
||||
|
||||
//called from sh4 context , should update pvr/ta state and everything else
|
||||
static int spg_line_sched(int tag, int cycl, int jit)
|
||||
{
|
||||
|
@ -190,37 +223,7 @@ static int spg_line_sched(int tag, int cycl, int jit)
|
|||
}
|
||||
}
|
||||
|
||||
//interrupts
|
||||
//0
|
||||
//vblank_in_interrupt_line_number
|
||||
//vblank_out_interrupt_line_number
|
||||
//vstart
|
||||
//vbend
|
||||
//pvr_numscanlines
|
||||
u32 min_scanline=prv_cur_scanline+1;
|
||||
u32 min_active=pvr_numscanlines;
|
||||
|
||||
if (min_scanline<SPG_VBLANK_INT.vblank_in_interrupt_line_number)
|
||||
min_active = std::min(min_active,SPG_VBLANK_INT.vblank_in_interrupt_line_number);
|
||||
|
||||
if (min_scanline<SPG_VBLANK_INT.vblank_out_interrupt_line_number)
|
||||
min_active = std::min(min_active,SPG_VBLANK_INT.vblank_out_interrupt_line_number);
|
||||
|
||||
if (min_scanline<SPG_VBLANK.vstart)
|
||||
min_active = std::min(min_active,SPG_VBLANK.vstart);
|
||||
|
||||
if (min_scanline<SPG_VBLANK.vbend)
|
||||
min_active = std::min(min_active,SPG_VBLANK.vbend);
|
||||
|
||||
if (lightgun_line != 0xffff && min_scanline < lightgun_line)
|
||||
min_active = std::min(min_active, lightgun_line);
|
||||
|
||||
if (SPG_HBLANK_INT.hblank_int_mode == 0 && min_scanline < SPG_HBLANK_INT.line_comp_val)
|
||||
min_active = std::min(min_active, SPG_HBLANK_INT.line_comp_val);
|
||||
|
||||
min_active = std::max(min_active,min_scanline);
|
||||
|
||||
return (min_active - prv_cur_scanline) * Line_Cycles;
|
||||
return getNextSpgInterrupt();
|
||||
}
|
||||
|
||||
void read_lightgun_position(int x, int y)
|
||||
|
|
|
@ -12,3 +12,4 @@ void spg_Deserialize(Deserializer& deser);
|
|||
void CalculateSync();
|
||||
void read_lightgun_position(int x, int y);
|
||||
void scheduleRenderDone(TA_context *cntx);
|
||||
void rescheduleSPG();
|
||||
|
|
Loading…
Reference in New Issue