Some progress
This commit is contained in:
@@ -9,26 +9,32 @@
|
||||
#include "display/render/renderpsp.h"
|
||||
#include "display/display.h"
|
||||
#include "assert/assert.h"
|
||||
#include "log/log.h"
|
||||
#include <pspgu.h>
|
||||
#include <pspgum.h>
|
||||
#include <pspdisplay.h>
|
||||
#include <pspge.h>
|
||||
|
||||
#define FRAME_SIZE (PSP_SCREEN_W * PSP_SCREEN_H * 4)
|
||||
#define VRAM_ADDR(offset) ((void *)((uintptr_t)sceGeEdramGetAddr() + (offset)))
|
||||
/* GU framebuffer stride must be power-of-two; 512 is the standard for 480-wide. */
|
||||
#define PSP_BUF_W 512
|
||||
#define FRAME_SIZE (PSP_BUF_W * PSP_SCREEN_H * 4)
|
||||
/* sceGuDrawBuffer/DispBuffer/DepthBuffer take VRAM-relative byte offsets,
|
||||
* NOT absolute virtual addresses — do NOT add sceGeEdramGetAddr() here. */
|
||||
#define VRAM_ADDR(offset) ((void *)(uintptr_t)(offset))
|
||||
|
||||
static uint32_t __attribute__((aligned(64))) displayList[0x10000];
|
||||
|
||||
errorret_t displayPSPInit(void) {
|
||||
logDebug("[PSP] displayPSPInit: start\n");
|
||||
DISPLAY.whichBuffer = 0;
|
||||
|
||||
sceGuInit();
|
||||
sceGuStart(GU_DIRECT, displayList);
|
||||
|
||||
/* Draw buffer: frame 0 at offset 0, frame 1 at FRAME_SIZE */
|
||||
sceGuDrawBuffer(GU_PSM_8888, VRAM_ADDR(0), PSP_SCREEN_W);
|
||||
sceGuDispBuffer(PSP_SCREEN_W, PSP_SCREEN_H, VRAM_ADDR(FRAME_SIZE), PSP_SCREEN_W);
|
||||
sceGuDepthBuffer(VRAM_ADDR(FRAME_SIZE * 2), PSP_SCREEN_W);
|
||||
sceGuDrawBuffer(GU_PSM_8888, VRAM_ADDR(0), PSP_BUF_W);
|
||||
sceGuDispBuffer(PSP_SCREEN_W, PSP_SCREEN_H, VRAM_ADDR(FRAME_SIZE), PSP_BUF_W);
|
||||
sceGuDepthBuffer(VRAM_ADDR(FRAME_SIZE * 2), PSP_BUF_W);
|
||||
|
||||
sceGuOffset(2048 - PSP_SCREEN_W / 2, 2048 - PSP_SCREEN_H / 2);
|
||||
sceGuViewport(2048, 2048, PSP_SCREEN_W, PSP_SCREEN_H);
|
||||
@@ -52,18 +58,23 @@ errorret_t displayPSPInit(void) {
|
||||
|
||||
sceDisplaySetMode(0, PSP_SCREEN_W, PSP_SCREEN_H);
|
||||
sceGuDisplay(GU_TRUE);
|
||||
logDebug("[PSP] displayPSPInit: GU setup done, calling renderPSPInit\n");
|
||||
|
||||
errorChain(renderPSPInit());
|
||||
logDebug("[PSP] displayPSPInit: done\n");
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t displayPSPFlush(ropbuffer_t *buf) {
|
||||
logDebug("[PSP] displayPSPFlush: enter\n");
|
||||
assertNotNull(buf, "PSP flush: null ropbuffer");
|
||||
errorChain(renderPSPFlush(buf));
|
||||
logDebug("[PSP] displayPSPFlush: done\n");
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t displayPSPSwap(void) {
|
||||
logDebug("[PSP] displayPSPSwap\n");
|
||||
sceGuSwapBuffers();
|
||||
errorOk();
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "display/color.h"
|
||||
#include "assert/assert.h"
|
||||
#include "util/memory.h"
|
||||
#include "log/log.h"
|
||||
#include <malloc.h>
|
||||
#include <psputils.h> /* sceKernelDcacheWritebackRange */
|
||||
#include <pspgu.h>
|
||||
@@ -80,6 +81,7 @@ static uint16_t texturePow2(uint16_t n) {
|
||||
/* ---- Init ---------------------------------------------------------------- */
|
||||
|
||||
errorret_t renderPSPInit(void) {
|
||||
logDebug("[PSP] renderPSPInit: start\n");
|
||||
/* White 1×1 fallback: index 0 → palette[0] = white */
|
||||
psptexentry_t *e = &pspTexTable[0];
|
||||
e->cpuIndices = (uint8_t *)memalign(16, 1);
|
||||
@@ -93,6 +95,7 @@ errorret_t renderPSPInit(void) {
|
||||
memoryZero(e->palette, 256 * sizeof(color_t));
|
||||
e->palette[0] = COLOR_WHITE;
|
||||
e->w = 1; e->h = 1; e->tbw = 8;
|
||||
logDebug("[PSP] renderPSPInit: done\n");
|
||||
errorOk();
|
||||
}
|
||||
|
||||
@@ -202,6 +205,7 @@ static void draw2DSprite(const ropsprite_t *s) {
|
||||
}
|
||||
|
||||
static void draw3DQuad(const ropquad3d_t *q) {
|
||||
logDebug("[PSP] draw3DQuad: enter tex=%u\n", (unsigned)q->texture);
|
||||
uint32_t abgr = toABGR(q->tint);
|
||||
float u0 = q->uvX / 255.0f, v0 = q->uvY / 255.0f;
|
||||
float u1 = (q->uvX + q->uvW) / 255.0f;
|
||||
@@ -216,9 +220,12 @@ static void draw3DQuad(const ropquad3d_t *q) {
|
||||
float blx = cx-rx-ux, bly = cy-ry-uy, blz = cz-rz-uz;
|
||||
float brx = cx+rx-ux, bry = cy+ry-uy, brz = cz+rz-uz;
|
||||
|
||||
logDebug("[PSP] draw3DQuad: bindTexture\n");
|
||||
bindTexture(q->texture);
|
||||
|
||||
logDebug("[PSP] draw3DQuad: getMemory\n");
|
||||
GuVert3D *verts = (GuVert3D *)sceGuGetMemory(6 * sizeof(GuVert3D));
|
||||
logDebug("[PSP] draw3DQuad: verts=0x%08x\n", (unsigned)verts);
|
||||
assertNotNull(verts, "PSP: failed to allocate 3D quad vertices");
|
||||
|
||||
verts[0] = (GuVert3D){u0,v0, abgr, tlx,tly,tlz};
|
||||
@@ -228,16 +235,21 @@ static void draw3DQuad(const ropquad3d_t *q) {
|
||||
verts[4] = (GuVert3D){u1,v1, abgr, brx,bry,brz};
|
||||
verts[5] = (GuVert3D){u1,v0, abgr, trx,try_,trz};
|
||||
|
||||
logDebug("[PSP] draw3DQuad: sceGuDrawArray\n");
|
||||
sceGuDrawArray(
|
||||
GU_TRIANGLES,
|
||||
GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D,
|
||||
6, 0, verts
|
||||
);
|
||||
logDebug("[PSP] draw3DQuad: done\n");
|
||||
}
|
||||
|
||||
/* ---- Flush --------------------------------------------------------------- */
|
||||
|
||||
errorret_t renderPSPFlush(ropbuffer_t *buf) {
|
||||
logDebug("[PSP] renderPSPFlush: byteCount=%u count=%u\n",
|
||||
(unsigned)buf->byteCount, (unsigned)buf->count);
|
||||
|
||||
sceGuStart(GU_DIRECT, displayList);
|
||||
|
||||
sceGuEnable(GU_TEXTURE_2D);
|
||||
@@ -245,12 +257,14 @@ errorret_t renderPSPFlush(ropbuffer_t *buf) {
|
||||
sceGuDepthFunc(GU_GEQUAL); /* PSP uses reversed depth */
|
||||
|
||||
uint32_t offset = 0;
|
||||
uint32_t opIdx = 0;
|
||||
while(offset < buf->byteCount) {
|
||||
const ropheader_t *hdr = (const ropheader_t *)(buf->data + offset);
|
||||
ropop_t op = (ropop_t)hdr->op;
|
||||
|
||||
switch(op) {
|
||||
case ROP_CLEAR: {
|
||||
logDebug("[PSP] op[%u] ROP_CLEAR\n", (unsigned)opIdx);
|
||||
const ropclear_t *c = (const ropclear_t *)hdr;
|
||||
uint32_t abgr = toABGR(c->color);
|
||||
sceGuClearColor(abgr);
|
||||
@@ -259,10 +273,12 @@ errorret_t renderPSPFlush(ropbuffer_t *buf) {
|
||||
break;
|
||||
}
|
||||
case ROP_DRAW_SPRITE:
|
||||
logDebug("[PSP] op[%u] ROP_DRAW_SPRITE\n", (unsigned)opIdx);
|
||||
draw2DSprite((const ropsprite_t *)hdr);
|
||||
break;
|
||||
|
||||
case ROP_SET_PROJECTION: {
|
||||
logDebug("[PSP] op[%u] ROP_SET_PROJECTION\n", (unsigned)opIdx);
|
||||
const ropprojection_t *p = (const ropprojection_t *)hdr;
|
||||
sceGumMatrixMode(GU_PROJECTION);
|
||||
sceGumLoadIdentity();
|
||||
@@ -280,6 +296,7 @@ errorret_t renderPSPFlush(ropbuffer_t *buf) {
|
||||
break;
|
||||
}
|
||||
case ROP_SET_VIEW: {
|
||||
logDebug("[PSP] op[%u] ROP_SET_VIEW\n", (unsigned)opIdx);
|
||||
const ropview_t *v = (const ropview_t *)hdr;
|
||||
ScePspFVector3 eye = {(float)v->eyeX, (float)v->eyeY, (float)v->eyeZ};
|
||||
ScePspFVector3 target = {(float)v->tgtX, (float)v->tgtY, (float)v->tgtZ};
|
||||
@@ -292,17 +309,23 @@ errorret_t renderPSPFlush(ropbuffer_t *buf) {
|
||||
break;
|
||||
}
|
||||
case ROP_DRAW_QUAD_3D:
|
||||
logDebug("[PSP] op[%u] ROP_DRAW_QUAD_3D\n", (unsigned)opIdx);
|
||||
draw3DQuad((const ropquad3d_t *)hdr);
|
||||
break;
|
||||
|
||||
default:
|
||||
logDebug("[PSP] op[%u] unknown op=%u offset=%u\n",
|
||||
(unsigned)opIdx, (unsigned)op, (unsigned)offset);
|
||||
break;
|
||||
}
|
||||
offset += ropOpSize(op);
|
||||
opIdx++;
|
||||
}
|
||||
|
||||
logDebug("[PSP] renderPSPFlush: sceGuFinish\n");
|
||||
sceGuFinish();
|
||||
sceGuSync(0, 0);
|
||||
logDebug("[PSP] renderPSPFlush: done\n");
|
||||
errorOk();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,10 +11,11 @@ void logDebug(const char_t *message, ...) {
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
|
||||
// print to stdout
|
||||
// print to stdout — fflush so pspsh sees it immediately even on crash
|
||||
va_list copy;
|
||||
va_copy(copy, args);
|
||||
vprintf(message, copy);
|
||||
fflush(stdout);
|
||||
va_end(copy);
|
||||
|
||||
// print to file
|
||||
|
||||
Reference in New Issue
Block a user