Tilemap stuff
This commit is contained in:
@@ -16,6 +16,7 @@ target_sources(${DUSK_BINARY_TARGET_NAME}
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(asset)
|
||||
add_subdirectory(display)
|
||||
add_subdirectory(input)
|
||||
add_subdirectory(log)
|
||||
add_subdirectory(network)
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
# Copyright (c) 2026 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||
PUBLIC
|
||||
displaypsp.c
|
||||
)
|
||||
|
||||
add_subdirectory(render)
|
||||
@@ -6,12 +6,11 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "display/displaysdl2.h"
|
||||
#include "display/displaypsp.h"
|
||||
|
||||
typedef displaysdl2_t displayplatform_t;
|
||||
typedef displaypsp_t displayplatform_t;
|
||||
|
||||
#define displayPlatformInit displaySDL2Init
|
||||
#define displayPlatformUpdate displaySDL2Update
|
||||
#define displayPlatformSwap displaySDL2Swap
|
||||
#define displayPlatformDispose displaySDL2Dispose
|
||||
#define displayPlatformSetState displaySDL2SetState
|
||||
#define displayPlatformInit displayPSPInit
|
||||
#define displayPlatformFlush displayPSPFlush
|
||||
#define displayPlatformSwap displayPSPSwap
|
||||
#define displayPlatformDispose displayPSPDispose
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "display/displaypsp.h"
|
||||
#include "display/render/renderpsp.h"
|
||||
#include "display/display.h"
|
||||
#include "assert/assert.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)))
|
||||
|
||||
static uint32_t __attribute__((aligned(64))) displayList[0x10000];
|
||||
|
||||
errorret_t displayPSPInit(void) {
|
||||
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);
|
||||
|
||||
sceGuOffset(2048 - PSP_SCREEN_W / 2, 2048 - PSP_SCREEN_H / 2);
|
||||
sceGuViewport(2048, 2048, PSP_SCREEN_W, PSP_SCREEN_H);
|
||||
sceGuDepthRange(65535, 0); /* PSP uses reversed depth */
|
||||
sceGuScissor(0, 0, PSP_SCREEN_W, PSP_SCREEN_H);
|
||||
sceGuEnable(GU_SCISSOR_TEST);
|
||||
|
||||
sceGuEnable(GU_ALPHA_TEST);
|
||||
sceGuAlphaFunc(GU_GREATER, 0, 0xFF);
|
||||
|
||||
sceGuEnable(GU_DEPTH_TEST);
|
||||
sceGuDepthFunc(GU_GEQUAL);
|
||||
|
||||
sceGuFrontFace(GU_CW);
|
||||
|
||||
sceGuEnable(GU_TEXTURE_2D);
|
||||
sceGuEnable(GU_CLIP_PLANES);
|
||||
|
||||
sceGuFinish();
|
||||
sceGuSync(0, 0);
|
||||
|
||||
sceDisplaySetMode(0, PSP_SCREEN_W, PSP_SCREEN_H);
|
||||
sceGuDisplay(GU_TRUE);
|
||||
|
||||
errorChain(renderPSPInit());
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t displayPSPFlush(ropbuffer_t *buf) {
|
||||
assertNotNull(buf, "PSP flush: null ropbuffer");
|
||||
errorChain(renderPSPFlush(buf));
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t displayPSPSwap(void) {
|
||||
sceGuSwapBuffers();
|
||||
errorOk();
|
||||
}
|
||||
|
||||
void displayPSPDispose(void) {
|
||||
renderPSPDispose();
|
||||
sceGuDisplay(GU_FALSE);
|
||||
sceGuTerm();
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "error/error.h"
|
||||
#include "display/displaystate.h"
|
||||
#include "display/render/ropbuffer.h"
|
||||
|
||||
#define PSP_SCREEN_W 480
|
||||
#define PSP_SCREEN_H 272
|
||||
|
||||
typedef struct {
|
||||
int_t whichBuffer;
|
||||
} displaypsp_t;
|
||||
|
||||
errorret_t displayPSPInit(void);
|
||||
errorret_t displayPSPFlush(ropbuffer_t *buf);
|
||||
errorret_t displayPSPSwap(void);
|
||||
void displayPSPDispose(void);
|
||||
@@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2026 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||
PUBLIC
|
||||
renderpsp.c
|
||||
)
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "display/render/renderpsp.h"
|
||||
|
||||
#define renderPlatformTextureCreate renderPSPTextureCreate
|
||||
#define renderPlatformTextureDispose renderPSPTextureDispose
|
||||
#define renderPlatformTextureGetPalette renderPSPTextureGetPalette
|
||||
#define renderPlatformTextureGetIndices renderPSPTextureGetIndices
|
||||
@@ -0,0 +1,318 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "display/render/renderpsp.h"
|
||||
#include "display/render/rop.h"
|
||||
#include "display/color.h"
|
||||
#include "assert/assert.h"
|
||||
#include "util/memory.h"
|
||||
#include <malloc.h>
|
||||
#include <psputils.h> /* sceKernelDcacheWritebackRange */
|
||||
#include <pspgu.h>
|
||||
#include <pspgum.h>
|
||||
#include <pspdisplay.h>
|
||||
|
||||
/* ---- Display list -------------------------------------------------------- */
|
||||
|
||||
#define DISPLAY_LIST_SIZE (256 * 1024)
|
||||
|
||||
static uint32_t __attribute__((aligned(64))) displayList[DISPLAY_LIST_SIZE / 4];
|
||||
|
||||
/* ---- Texture table ------------------------------------------------------- */
|
||||
|
||||
#define PSP_RTEXTURE_MAX 256
|
||||
|
||||
/* GU T8 (8-bit indexed) textures.
|
||||
* cpuIndices : w*h row-major bytes, user-writable source of truth.
|
||||
* gpuIndices : tbw*h padded for sceGuTexImage, re-derived at bind.
|
||||
* palette : 256 RGBA entries, user-writable source of truth.
|
||||
* Converted to ABGR on-the-fly at bind into pspAbgrBuf.
|
||||
* tbw : power-of-two stride ≥ 8 required by the GU. */
|
||||
typedef struct {
|
||||
uint8_t *cpuIndices;
|
||||
uint8_t *gpuIndices;
|
||||
color_t palette[256];
|
||||
uint16_t w, h, tbw;
|
||||
} psptexentry_t;
|
||||
|
||||
/* Shared 16-byte-aligned ABGR buffer used during every CLUT load. */
|
||||
static uint32_t __attribute__((aligned(16))) pspAbgrBuf[256];
|
||||
|
||||
static psptexentry_t pspTexTable[PSP_RTEXTURE_MAX];
|
||||
static uint16_t pspTexNext = 1; /* 0 = white fallback */
|
||||
|
||||
/* ---- Vertex types -------------------------------------------------------- */
|
||||
|
||||
/* 2D sprite: two corner vertices define the rect (GU_SPRITES uses 2 verts). */
|
||||
typedef struct {
|
||||
uint16_t u, v; /* texel coords (integer, not normalised) */
|
||||
uint32_t color; /* ABGR */
|
||||
int16_t x, y, z;
|
||||
} __attribute__((packed)) GuVert2D;
|
||||
|
||||
/* 3D triangle vertex */
|
||||
typedef struct {
|
||||
float u, v;
|
||||
uint32_t color; /* ABGR */
|
||||
float x, y, z;
|
||||
} __attribute__((packed)) GuVert3D;
|
||||
|
||||
/* ---- Helpers ------------------------------------------------------------- */
|
||||
|
||||
static uint32_t toABGR(color_t c) {
|
||||
return ((uint32_t)c.a << 24) |
|
||||
((uint32_t)c.b << 16) |
|
||||
((uint32_t)c.g << 8) |
|
||||
((uint32_t)c.r);
|
||||
}
|
||||
|
||||
/* Smallest power-of-two ≥ n and ≥ 8 (PSP GU minimum stride for T8). */
|
||||
static uint16_t texturePow2(uint16_t n) {
|
||||
uint16_t p = 8;
|
||||
while(p < n) p = (uint16_t)(p << 1);
|
||||
return p;
|
||||
}
|
||||
|
||||
/* ---- Init ---------------------------------------------------------------- */
|
||||
|
||||
errorret_t renderPSPInit(void) {
|
||||
/* White 1×1 fallback: index 0 → palette[0] = white */
|
||||
psptexentry_t *e = &pspTexTable[0];
|
||||
e->cpuIndices = (uint8_t *)memalign(16, 1);
|
||||
assertNotNull(e->cpuIndices, "PSP: failed to allocate fallback cpu index buffer");
|
||||
e->cpuIndices[0] = 0;
|
||||
|
||||
e->gpuIndices = (uint8_t *)memalign(16, 8); /* tbw=8 minimum */
|
||||
assertNotNull(e->gpuIndices, "PSP: failed to allocate fallback gpu index buffer");
|
||||
memoryZero(e->gpuIndices, 8);
|
||||
|
||||
memoryZero(e->palette, 256 * sizeof(color_t));
|
||||
e->palette[0] = COLOR_WHITE;
|
||||
e->w = 1; e->h = 1; e->tbw = 8;
|
||||
errorOk();
|
||||
}
|
||||
|
||||
/* ---- Texture ------------------------------------------------------------- */
|
||||
|
||||
rtexture_t renderPSPTextureCreate(
|
||||
uint16_t w, uint16_t h,
|
||||
const uint8_t *indices, const color_t *palette
|
||||
) {
|
||||
assertTrue(pspTexNext < PSP_RTEXTURE_MAX, "PSP texture table full");
|
||||
|
||||
uint16_t tbw = texturePow2(w);
|
||||
rtexture_t handle = (rtexture_t)pspTexNext++;
|
||||
psptexentry_t *e = &pspTexTable[handle];
|
||||
|
||||
uint32_t cpuBytes = (uint32_t)w * h;
|
||||
e->cpuIndices = (uint8_t *)memalign(16, cpuBytes);
|
||||
assertNotNull(e->cpuIndices, "PSP: failed to allocate cpu index buffer");
|
||||
memoryCopy(e->cpuIndices, indices, cpuBytes);
|
||||
|
||||
uint32_t gpuBytes = (uint32_t)tbw * h;
|
||||
e->gpuIndices = (uint8_t *)memalign(16, gpuBytes);
|
||||
assertNotNull(e->gpuIndices, "PSP: failed to allocate gpu index buffer");
|
||||
memoryZero(e->gpuIndices, gpuBytes);
|
||||
for(uint16_t row = 0; row < h; row++)
|
||||
memoryCopy(e->gpuIndices + row * tbw, indices + row * w, w);
|
||||
|
||||
memoryCopy(e->palette, palette, 256 * sizeof(color_t));
|
||||
e->w = w; e->h = h; e->tbw = tbw;
|
||||
return handle;
|
||||
}
|
||||
|
||||
void renderPSPTextureDispose(rtexture_t tex) {
|
||||
if(tex == RTEXTURE_NONE || tex >= PSP_RTEXTURE_MAX) return;
|
||||
psptexentry_t *e = &pspTexTable[tex];
|
||||
if(e->cpuIndices) { free(e->cpuIndices); e->cpuIndices = NULL; }
|
||||
if(e->gpuIndices) { free(e->gpuIndices); e->gpuIndices = NULL; }
|
||||
}
|
||||
|
||||
color_t *renderPSPTextureGetPalette(rtexture_t tex) {
|
||||
if(tex == RTEXTURE_NONE || tex >= PSP_RTEXTURE_MAX) return NULL;
|
||||
return pspTexTable[tex].palette;
|
||||
}
|
||||
|
||||
uint8_t *renderPSPTextureGetIndices(rtexture_t tex) {
|
||||
if(tex == RTEXTURE_NONE || tex >= PSP_RTEXTURE_MAX) return NULL;
|
||||
return pspTexTable[tex].cpuIndices;
|
||||
}
|
||||
|
||||
static void bindTexture(rtexture_t tex) {
|
||||
psptexentry_t *e = (tex < PSP_RTEXTURE_MAX && pspTexTable[tex].cpuIndices)
|
||||
? &pspTexTable[tex]
|
||||
: &pspTexTable[0];
|
||||
|
||||
/* Re-pad cpuIndices → gpuIndices (stride tbw, rows w wide). */
|
||||
memoryZero(e->gpuIndices, (uint32_t)e->tbw * e->h);
|
||||
for(uint16_t row = 0; row < e->h; row++)
|
||||
memoryCopy(e->gpuIndices + row * e->tbw, e->cpuIndices + row * e->w, e->w);
|
||||
sceKernelDcacheWritebackRange(e->gpuIndices, (uint32_t)e->tbw * e->h);
|
||||
|
||||
/* Convert palette color_t RGBA → ABGR into the shared aligned buffer. */
|
||||
for(int i = 0; i < 256; i++) pspAbgrBuf[i] = toABGR(e->palette[i]);
|
||||
sceKernelDcacheWritebackRange(pspAbgrBuf, 256 * sizeof(uint32_t));
|
||||
|
||||
sceGuTexMode(GU_PSM_T8, 0, 0, GU_FALSE);
|
||||
sceGuClutMode(GU_PSM_8888, 0, 0xFF, 0);
|
||||
sceGuClutLoad(32, pspAbgrBuf); /* 32 × 8 entries = 256 */
|
||||
sceGuTexImage(0, e->tbw, e->h, e->tbw, e->gpuIndices);
|
||||
sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
|
||||
sceGuTexFilter(GU_NEAREST, GU_NEAREST);
|
||||
sceGuTexScale(1.0f, 1.0f);
|
||||
sceGuTexOffset(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
/* ---- Draw helpers -------------------------------------------------------- */
|
||||
|
||||
static void draw2DSprite(const ropsprite_t *s) {
|
||||
psptexentry_t *e = (s->texture < PSP_RTEXTURE_MAX && pspTexTable[s->texture].cpuIndices)
|
||||
? &pspTexTable[s->texture]
|
||||
: &pspTexTable[0];
|
||||
uint32_t abgr = toABGR(s->tint);
|
||||
float u0 = (s->uvX / 255.0f) * (float)e->w;
|
||||
float v0 = (s->uvY / 255.0f) * (float)e->h;
|
||||
float u1 = ((s->uvX + s->uvW) / 255.0f) * (float)e->w;
|
||||
float v1 = ((s->uvY + s->uvH) / 255.0f) * (float)e->h;
|
||||
|
||||
bindTexture(s->texture);
|
||||
|
||||
GuVert2D *verts = (GuVert2D *)sceGuGetMemory(2 * sizeof(GuVert2D));
|
||||
assertNotNull(verts, "PSP: failed to allocate sprite vertices");
|
||||
|
||||
verts[0].u = (uint16_t)u0; verts[0].v = (uint16_t)v0;
|
||||
verts[0].color = abgr;
|
||||
verts[0].x = s->x; verts[0].y = s->y; verts[0].z = 0;
|
||||
|
||||
verts[1].u = (uint16_t)u1; verts[1].v = (uint16_t)v1;
|
||||
verts[1].color = abgr;
|
||||
verts[1].x = (int16_t)(s->x + s->w);
|
||||
verts[1].y = (int16_t)(s->y + s->h);
|
||||
verts[1].z = 0;
|
||||
|
||||
sceGuDrawArray(
|
||||
GU_SPRITES,
|
||||
GU_TEXTURE_16BIT | GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D,
|
||||
2, 0, verts
|
||||
);
|
||||
}
|
||||
|
||||
static void draw3DQuad(const ropquad3d_t *q) {
|
||||
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;
|
||||
float v1 = (q->uvY + q->uvH) / 255.0f;
|
||||
|
||||
float cx = (float)q->cx, cy = (float)q->cy, cz = (float)q->cz;
|
||||
float rx = (float)q->rx, ry = (float)q->ry, rz = (float)q->rz;
|
||||
float ux = (float)q->ux, uy = (float)q->uy, uz = (float)q->uz;
|
||||
|
||||
float tlx = cx-rx+ux, tly = cy-ry+uy, tlz = cz-rz+uz;
|
||||
float trx = cx+rx+ux, try_= cy+ry+uy, trz = cz+rz+uz;
|
||||
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;
|
||||
|
||||
bindTexture(q->texture);
|
||||
|
||||
GuVert3D *verts = (GuVert3D *)sceGuGetMemory(6 * sizeof(GuVert3D));
|
||||
assertNotNull(verts, "PSP: failed to allocate 3D quad vertices");
|
||||
|
||||
verts[0] = (GuVert3D){u0,v0, abgr, tlx,tly,tlz};
|
||||
verts[1] = (GuVert3D){u0,v1, abgr, blx,bly,blz};
|
||||
verts[2] = (GuVert3D){u1,v1, abgr, brx,bry,brz};
|
||||
verts[3] = (GuVert3D){u0,v0, abgr, tlx,tly,tlz};
|
||||
verts[4] = (GuVert3D){u1,v1, abgr, brx,bry,brz};
|
||||
verts[5] = (GuVert3D){u1,v0, abgr, trx,try_,trz};
|
||||
|
||||
sceGuDrawArray(
|
||||
GU_TRIANGLES,
|
||||
GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D,
|
||||
6, 0, verts
|
||||
);
|
||||
}
|
||||
|
||||
/* ---- Flush --------------------------------------------------------------- */
|
||||
|
||||
errorret_t renderPSPFlush(ropbuffer_t *buf) {
|
||||
sceGuStart(GU_DIRECT, displayList);
|
||||
|
||||
sceGuEnable(GU_TEXTURE_2D);
|
||||
sceGuEnable(GU_DEPTH_TEST);
|
||||
sceGuDepthFunc(GU_GEQUAL); /* PSP uses reversed depth */
|
||||
|
||||
uint32_t offset = 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: {
|
||||
const ropclear_t *c = (const ropclear_t *)hdr;
|
||||
uint32_t abgr = toABGR(c->color);
|
||||
sceGuClearColor(abgr);
|
||||
sceGuClearDepth(0);
|
||||
sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT);
|
||||
break;
|
||||
}
|
||||
case ROP_DRAW_SPRITE:
|
||||
draw2DSprite((const ropsprite_t *)hdr);
|
||||
break;
|
||||
|
||||
case ROP_SET_PROJECTION: {
|
||||
const ropprojection_t *p = (const ropprojection_t *)hdr;
|
||||
sceGumMatrixMode(GU_PROJECTION);
|
||||
sceGumLoadIdentity();
|
||||
if(p->fovY > FIXED_ZERO) {
|
||||
float fovDeg = fixedToFloat(p->fovY) * (180.0f / 3.14159f);
|
||||
sceGumPerspective(
|
||||
fovDeg, fixedToFloat(p->aspect),
|
||||
fixedToFloat(p->nearZ), fixedToFloat(p->farZ)
|
||||
);
|
||||
} else {
|
||||
float aspect = fixedToFloat(p->aspect);
|
||||
sceGumOrtho(-aspect, aspect, -1.0f, 1.0f,
|
||||
fixedToFloat(p->nearZ), fixedToFloat(p->farZ));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ROP_SET_VIEW: {
|
||||
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};
|
||||
ScePspFVector3 up = {0.0f, 1.0f, 0.0f};
|
||||
sceGumMatrixMode(GU_VIEW);
|
||||
sceGumLoadIdentity();
|
||||
sceGumLookAt(&eye, &target, &up);
|
||||
sceGumMatrixMode(GU_MODEL);
|
||||
sceGumLoadIdentity();
|
||||
break;
|
||||
}
|
||||
case ROP_DRAW_QUAD_3D:
|
||||
draw3DQuad((const ropquad3d_t *)hdr);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
offset += ropOpSize(op);
|
||||
}
|
||||
|
||||
sceGuFinish();
|
||||
sceGuSync(0, 0);
|
||||
errorOk();
|
||||
}
|
||||
|
||||
/* ---- Dispose ------------------------------------------------------------- */
|
||||
|
||||
void renderPSPDispose(void) {
|
||||
for(uint16_t i = 0; i < pspTexNext; i++) {
|
||||
psptexentry_t *e = &pspTexTable[i];
|
||||
if(e->cpuIndices) { free(e->cpuIndices); e->cpuIndices = NULL; }
|
||||
if(e->gpuIndices) { free(e->gpuIndices); e->gpuIndices = NULL; }
|
||||
}
|
||||
pspTexNext = 1;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "error/error.h"
|
||||
#include "display/render/ropbuffer.h"
|
||||
#include "display/render/rtexture.h"
|
||||
#include "display/color.h"
|
||||
|
||||
errorret_t renderPSPInit(void);
|
||||
errorret_t renderPSPFlush(ropbuffer_t *buf);
|
||||
void renderPSPDispose(void);
|
||||
|
||||
rtexture_t renderPSPTextureCreate(
|
||||
uint16_t w, uint16_t h,
|
||||
const uint8_t *indices, const color_t *palette
|
||||
);
|
||||
void renderPSPTextureDispose(rtexture_t tex);
|
||||
color_t *renderPSPTextureGetPalette(rtexture_t tex);
|
||||
uint8_t *renderPSPTextureGetIndices(rtexture_t tex);
|
||||
Reference in New Issue
Block a user