sceGsSetDefDBuff and sceGsSwapDBuff implementation based on the DC version (#106)

This commit is contained in:
roby65
2026-03-25 01:34:17 +01:00
committed by GitHub
parent cad1ca0bb5
commit 553a9027d8
3 changed files with 115 additions and 0 deletions
+2
View File
@@ -350,12 +350,14 @@
X(sceGsResetPath) \
X(sceGsSetDefClear) \
X(sceGsSetDefDBuffDc) \
X(sceGsSetDefDBuff) \
X(sceGsSetDefDispEnv) \
X(sceGsSetDefDrawEnv) \
X(sceGsSetDefDrawEnv2) \
X(sceGsSetDefLoadImage) \
X(sceGsSetDefStoreImage) \
X(sceGsSwapDBuffDc) \
X(sceGsSwapDBuff) \
X(sceGsSyncPath) \
X(sceGsSyncV) \
X(sceGsSyncVCallback) \
@@ -1552,6 +1552,17 @@ namespace
GsClearMem clear1;
};
struct GsDBuffMem
{
GsDispEnvMem disp[2];
GsGiftagMem giftag0;
GsDrawEnv1Mem draw0;
GsClearMem clear0;
GsGiftagMem giftag1;
GsDrawEnv1Mem draw1;
GsClearMem clear1;
};
struct GsImageMem
{
uint16_t x;
@@ -1809,6 +1820,15 @@ namespace
return true;
}
static bool readGsDBuff(uint8_t* rdram, uint32_t addr, GsDBuffMem& out)
{
const uint8_t* ptr = getConstMemPtr(rdram, addr);
if (!ptr)
return false;
std::memcpy(&out, ptr, sizeof(out));
return true;
}
static bool writeGsDBuffDc(uint8_t *rdram, uint32_t addr, const GsDBuffDcMem &db)
{
uint8_t *ptr = getMemPtr(rdram, addr);
@@ -1818,6 +1838,15 @@ namespace
return true;
}
static bool writeGsDBuff(uint8_t* rdram, uint32_t addr, const GsDBuffMem& db)
{
uint8_t* ptr = getMemPtr(rdram, addr);
if (!ptr)
return false;
std::memcpy(ptr, &db, sizeof(db));
return true;
}
static bool readGsRegPairs(uint8_t *rdram, uint32_t addr, GsRegPairMem *pairs, size_t pairCount)
{
if (!pairs || pairCount == 0u)
@@ -449,6 +449,65 @@ void sceGsSetDefDBuffDc(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime)
setReturnS32(ctx, 0);
}
void sceGsSetDefDBuff(uint8_t* rdram, R5900Context* ctx, PS2Runtime* runtime)
{
const uint32_t envAddr = getRegU32(ctx, 4);
uint32_t psm = getRegU32(ctx, 5);
uint32_t w = getRegU32(ctx, 6);
uint32_t h = getRegU32(ctx, 7);
const uint32_t ztest = readStackU32(rdram, ctx, 16);
const uint32_t zpsm = readStackU32(rdram, ctx, 20);
const uint32_t clear = readStackU32(rdram, ctx, 24);
(void)clear;
if (w == 0u)
{
w = 640u;
}
if (h == 0u)
{
h = 448u;
}
const uint32_t fbw = std::max<uint32_t>(1u, (w + 63u) / 64u);
const uint64_t pmode = makePmode(1u, 1u, 0u, 0u, 0u, 0x80u);
const uint64_t smode2 =
(static_cast<uint64_t>(g_gparam.interlace & 0x1u) << 0) |
(static_cast<uint64_t>(g_gparam.ffmode & 0x1u) << 1);
const uint64_t dispfb = makeDispFb(0u, fbw, psm, 0u, 0u);
const uint64_t display = makeDisplay(636u, 32u, 0u, 0u, w - 1u, h - 1u);
const int32_t drawWidth = static_cast<int32_t>(w);
const int32_t drawHeight = static_cast<int32_t>(h);
uint32_t zbufAddr = 0u;
{
R5900Context temp = *ctx;
sceGszbufaddr(rdram, &temp, runtime);
zbufAddr = getRegU32(&temp, 2);
}
GsDBuffMem db{};
db.disp[0].pmode = pmode;
db.disp[0].smode2 = smode2;
db.disp[0].dispfb = dispfb;
db.disp[0].display = display;
db.disp[0].bgcolor = 0u;
db.disp[1] = db.disp[0];
db.giftag0 = { makeGiftagAplusD(14u), 0x0E0E0E0E0E0E0E0EULL };
seedGsDrawEnv1(db.draw0, drawWidth, drawHeight, 0u, fbw, psm, zbufAddr, zpsm, ztest, false);
db.giftag1 = db.giftag0;
seedGsDrawEnv1(db.draw1, drawWidth, drawHeight, 0u, fbw, psm, zbufAddr, zpsm, ztest, false);
if (!writeGsDBuff(rdram, envAddr, db))
{
setReturnS32(ctx, -1);
return;
}
setReturnS32(ctx, 0);
}
void sceGsSetDefDispEnv(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime)
{
uint32_t envAddr = getRegU32(ctx, 4);
@@ -605,6 +664,31 @@ void sceGsSwapDBuffDc(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime)
setReturnS32(ctx, static_cast<int32_t>(which ^ 1u));
}
void sceGsSwapDBuff(uint8_t* rdram, R5900Context* ctx, PS2Runtime* runtime)
{
const uint32_t envAddr = getRegU32(ctx, 4);
const uint32_t which = getRegU32(ctx, 5) & 1u;
GsDBuffMem db{};
if (!runtime || !readGsDBuff(rdram, envAddr, db))
{
setReturnS32(ctx, -1);
return;
}
applyGsDispEnv(runtime, db.disp[which]);
if (which == 0u)
{
applyGsRegPairs(runtime, reinterpret_cast<const GsRegPairMem*>(&db.draw0), 8u);
}
else
{
applyGsRegPairs(runtime, reinterpret_cast<const GsRegPairMem*>(&db.draw1), 8u);
}
setReturnS32(ctx, static_cast<int32_t>(which ^ 1u));
}
void sceGsSyncPath(uint8_t *rdram, R5900Context *ctx, PS2Runtime *runtime)
{
int32_t mode = static_cast<int32_t>(getRegU32(ctx, 4));