mirror of
https://github.com/ran-j/PS2Recomp.git
synced 2026-09-26 08:51:05 -04:00
sceGsSetDefDBuff and sceGsSwapDBuff implementation based on the DC version (#106)
This commit is contained in:
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user