Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ps2xRuntime/include/ps2_call_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down
29 changes: 29 additions & 0 deletions ps2xRuntime/src/lib/stubs/helpers/ps2_stubs_helpers.inl
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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)
Expand Down
84 changes: 84 additions & 0 deletions ps2xRuntime/src/lib/stubs/ps2_stubs_gs.inl
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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));
Expand Down