Compare commits

...
8 Commits
Author SHA1 Message Date
lightningterror c7f7bd6f3d GS/DX11: Align drawlist bounding box to 4 pixel boundaries.
Will be faster using Direct Memory Access, otherwise it may stall as more commands need to be issued.
2026-01-31 16:57:42 +01:00
PCSX2 Botandlightningterror dd81fbbd5f [ci skip] Qt: Update Base Translation. 2026-01-31 02:58:58 +01:00
Mrlinkwiiandlightningterror b4293a40d2 Docs: update Gamedb documentation 2026-01-30 18:06:59 +01:00
Mrlinkwiiandlightningterror 9acadb21fe GameDB: remove left over schemea options 2026-01-30 18:06:02 +01:00
TJnotJTandlightningterror e82fa0bba5 GS/HW: Require 32 bit RT for accumulation blend on max blend. 2026-01-30 11:06:13 +01:00
ZiemasandTy 45490d903a SPU: Slow down DMA 2026-01-29 22:26:28 -05:00
PCSX2 Botandlightningterror 76dadf792a [ci skip] Qt: Update Base Translation. 2026-01-30 02:03:26 +01:00
wxvuandlightningterror 204829865d GameDB: Add fixes for Puchi Copter 2 2026-01-29 14:21:14 +01:00
10 changed files with 1128 additions and 1084 deletions
Binary file not shown.
+10
View File
@@ -24781,6 +24781,11 @@ SLES-53820:
SLES-53821:
name: "Radio Helicopter II"
region: "PAL-E"
patches:
9A695202:
content: |-
comment=Patch that nops a branch instruction causing a freeze.
patch=1,EE,001799AC,word,00000000
SLES-53824:
name: "Trapt"
region: "PAL-E"
@@ -40089,6 +40094,11 @@ SLPM-62624:
name-sort: "ぷちこぷたー2"
name-en: "Petit Copter 2"
region: "NTSC-J"
patches:
9A695202:
content: |-
comment=Patch that nops a branch instruction causing a freeze.
patch=1,EE,001799B8,word,00000000
SLPM-62625:
name: "鬼浜爆走愚連隊 激闘編"
name-sort: "おにはまばくそうぐれんたい げきとうへん"
File diff suppressed because it is too large Load Diff
+11 -2
View File
@@ -139,12 +139,15 @@ The clamp modes are also numerically based.
### GS Hardware Mipmap Fixes
* mipmap [`0` or `1` or `2`] {Off, Basic, Full} Default: Automatic (No value, looks up GameDB)
* mipmap [`0` or `1`] {Off, On} Default: On (looks up GameDB)
* trilinearFiltering [`0` or `1` or `2`] {None, Trilinear, Trilinear Ultra} Default: None (`0`)
### GS Hardware General Fixes
* beforeDraw {`OI` with suffix } {None unless specific game GSC} Default: Automatic (No value, looks up GameDB) with valid variable name (ex. OI_BurnoutGames)
* moveHandler {`MV` with suffix } {None unless specific game GSC} Default: Automatic (No value, looks up GameDB) with valid variable name (ex. MV_Ico)
* afterDraw {`OO` with suffix } {None unless specific game GSC} Default: Automatic (No value, looks up GameDB) with valid variable name
* conservativeFramebuffer [`0` or `1`] {Off or On} Default: On (`1`)
* texturePreloading [`0` or `1` or `2`] {None, Partial or Full Hash Cache} Default: None (`0`)
@@ -153,11 +156,17 @@ The clamp modes are also numerically based.
### GS Hardware Renderer Fixes
* autoFlush [`0` or `1` or `2`] {Disabled, Enabled (Sprites Only), Enabled (All Primitives)} Default: Off (`0`)
* partialTargetInvalidation [`0` or `1`] {Off, On} Default: Off (`0`)
* PCRTCOffsets [`0` or `1`] {Off, On} Default: Off (`0`)
* PCRTCOverscan [`0` or `1`] {Off, On} Default: Off (`0`)
* disableDepthSupport [`0` or `1`] {Off, On} Default: Off (`0`)
* disablePartialInvalidation [`0` or `1`] {Off, On} Default: Off (`0`)
* cpuFramebufferConversion [`0` or `1`] {Off, On} Default: Off (`0`)
* preloadFrameData [`0` or `1`] {Off, On} Default: Off (`0`)
* textureInsideRT [`0` or `1`] {Disabled, Inside Targets, Merge Targets} Default: Off (`0`)
* textureInsideRT [`0` or `1`or `2`] {Disabled, Inside Targets, Merge Targets} Default: Off (`0`)
* PCRTCOverscan [`0` or `1`] {Off, On} Default: Off (`0`)
* PCRTCOverscan [`0` or `1`] {Off, On} Default: Off (`0`)
* cpuCLUTRender [`0` or `1` or `2`] {Disabled, Normal, Aggressive} Default: Disabled (`0`)
* cpuSpriteRenderBW [Value between `0` to `10`] {Disabled, 1 (64), 2 (128), 3 (192), 4 (256), 5 (320), 6 (384), 7 (448), 8 (512), 9 (576), 10 (640)} Default: Off (`0`)
-5
View File
@@ -229,11 +229,6 @@
"minimum": 0,
"maximum": 100000
},
"halfBottomOverride": {
"type": "integer",
"minimum": 0,
"maximum": 1
},
"halfPixelOffset": {
"type": "integer",
"minimum": 0,
+22 -3
View File
@@ -2847,6 +2847,7 @@ void GSDevice11::SendHWDraw(const GSHWDrawConfig& config, GSTexture* draw_rt_clo
{
const u32 draw_list_size = static_cast<u32>(config.drawlist->size());
const u32 indices_per_prim = config.indices_per_prim;
const GSVector4i rtsize(0, 0, draw_rt->GetWidth(), draw_rt->GetHeight());
pxAssert(config.drawlist && !config.drawlist->empty());
pxAssert(config.drawlist_bbox && static_cast<u32>(config.drawlist_bbox->size()) == draw_list_size);
@@ -2855,10 +2856,28 @@ void GSDevice11::SendHWDraw(const GSHWDrawConfig& config, GSTexture* draw_rt_clo
{
const u32 count = (*config.drawlist)[n] * indices_per_prim;
GSVector4i bbox = (*config.drawlist_bbox)[n].rintersect(config.drawarea);
const GSVector4i original_bbox = (*config.drawlist_bbox)[n].rintersect(config.drawarea);
GSVector4i snapped_bbox = original_bbox;
// Copy only the part needed by the draw.
CopyAndBind(bbox);
// We don't want the snapped box adjustments when the rect is empty as it might make the copy to pass.
// The empty rect itself needs to be handled in renderer properly.
if (!snapped_bbox.rempty())
{
// Aligning bbox to 4 pixel boundaries so copies will be faster using Direct Memory Access,
// otherwise it may stall as more commands need to be issued.
snapped_bbox.left &= ~3;
snapped_bbox.top &= ~3;
snapped_bbox.right = (snapped_bbox.right + 3) & ~3;
snapped_bbox.bottom = (snapped_bbox.bottom + 3) & ~3;
// Ensure the new sizes are within bounds.
snapped_bbox.left = std::max(0, snapped_bbox.left);
snapped_bbox.top = std::max(0, snapped_bbox.top);
snapped_bbox.right = std::min(snapped_bbox.right, rtsize.right);
snapped_bbox.bottom = std::min(snapped_bbox.bottom, rtsize.bottom);
}
CopyAndBind(snapped_bbox);
DrawIndexedPrimitive(p, count);
p += count;
+1
View File
@@ -5910,6 +5910,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
{
case AccBlendLevel::Maximum:
sw_blending |= true;
accumulation_blend &= (GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].bpp == 32);
[[fallthrough]];
case AccBlendLevel::Full:
sw_blending |= m_conf.ps.blend_a != m_conf.ps.blend_b && alpha_c0_high_max_one;
-1
View File
@@ -380,7 +380,6 @@ static const char* s_gs_hw_fix_names[] = {
"trilinearFiltering",
"skipDrawStart",
"skipDrawEnd",
"halfBottomOverride",
"halfPixelOffset",
"roundSprite",
"nativeScaling",
-1
View File
@@ -65,7 +65,6 @@ namespace GameDatabaseSchema
TrilinearFiltering,
SkipDrawStart,
SkipDrawEnd,
HalfBottomOverride,
HalfPixelOffset,
RoundSprite,
NativeScaling,
+9 -9
View File
@@ -163,7 +163,7 @@ void V_Core::StartADMAWrite(u16* pMem, u32 sz)
if ((AutoDMACtrl & (Index + 1)) == 0)
{
ActiveTSA = 0x2000 + (Index << 10);
DMAICounter = size * 4;
DMAICounter = size * 48;
LastClock = psxRegs.cycle;
}
else if (size >= 256)
@@ -191,7 +191,7 @@ void V_Core::StartADMAWrite(u16* pMem, u32 sz)
if (SPU2::MsgToConsole())
SPU2::ConLog("ADMA%c Error Size of %x too small\n", GetDmaIndexChar(), size);
InputDataLeft = 0;
DMAICounter = size * 4;
DMAICounter = size * 48;
LastClock = psxRegs.cycle;
}
}
@@ -248,7 +248,7 @@ void V_Core::FinishDMAwrite()
DMA7LogWrite(DMAPtr, ReadSize << 1);
#endif
u32 buff1end = ActiveTSA + std::min(ReadSize, (u32)0x100 + std::abs(DMAICounter / 4));
u32 buff1end = ActiveTSA + std::min(ReadSize, (u32)0x100 + std::abs(DMAICounter / 48));
u32 buff2end = 0;
if (buff1end > 0x100000)
{
@@ -343,7 +343,7 @@ void V_Core::FinishDMAwrite()
DMAPtr += TDA - ActiveTSA;
ReadSize -= TDA - ActiveTSA;
DMAICounter = (DMAICounter - ReadSize) * 4;
DMAICounter = (DMAICounter - ReadSize) * 48;
CounterUpdate(DMAICounter);
@@ -354,7 +354,7 @@ void V_Core::FinishDMAwrite()
void V_Core::FinishDMAread()
{
u32 buff1end = ActiveTSA + std::min(ReadSize, (u32)0x100 + std::abs(DMAICounter / 4));
u32 buff1end = ActiveTSA + std::min(ReadSize, (u32)0x100 + std::abs(DMAICounter / 48));
u32 buff2end = 0;
if (buff1end > 0x100000)
@@ -426,9 +426,9 @@ void V_Core::FinishDMAread()
// DMA Reads are done AFTER the delay, so to get the timing right we need to scheule one last DMA to catch IRQ's
if (ReadSize)
DMAICounter = std::min(ReadSize, (u32)0x100) * 4;
DMAICounter = std::min(ReadSize, (u32)0x100) * 48;
else
DMAICounter = 4;
DMAICounter = 48;
CounterUpdate(DMAICounter);
@@ -446,7 +446,7 @@ void V_Core::DoDMAread(u16* pMem, u32 size)
ReadSize = size;
IsDMARead = true;
LastClock = psxRegs.cycle;
DMAICounter = std::min(ReadSize, (u32)0x100) * 4;
DMAICounter = (std::min(ReadSize, (u32)0x100) * 48);
Regs.STATX &= ~0x80;
Regs.STATX |= 0x400;
//Regs.ATTR |= 0x30;
@@ -470,7 +470,7 @@ void V_Core::DoDMAwrite(u16* pMem, u32 size)
{
Regs.STATX &= ~0x80;
//Regs.ATTR |= 0x30;
DMAICounter = 1 * 4;
DMAICounter = 1 * 48;
LastClock = psxRegs.cycle;
return;
}