PS2: Preparation for refactoring palette logic

This commit is contained in:
UnknownShadow200 2025-06-07 18:21:18 +10:00
parent dbaa2e5e5d
commit 2751661a4e
3 changed files with 183 additions and 109 deletions

View File

@ -17,30 +17,33 @@
#define MAX_PALETTE_ENTRIES 2048 #define MAX_PALETTE_ENTRIES 2048
typedef struct Matrix VU0_MATRIX __attribute__((aligned(16))); #define QWORD_ALIGNED __attribute__((aligned(16)))
typedef struct Vec4 VU0_VECTOR __attribute__((aligned(16)));
typedef struct { int x, y, z, w; } VU0_IVECTOR __attribute__((aligned(16))); typedef struct Matrix VU0_matrix QWORD_ALIGNED;
typedef struct Vec4 VU0_vector QWORD_ALIGNED;
typedef struct { int x, y, z, w; } VU0_IVector QWORD_ALIGNED;
static void* gfx_vertices; static void* gfx_vertices;
extern framebuffer_t fb_colors[2]; extern framebuffer_t fb_colors[2];
extern zbuffer_t fb_depth; extern zbuffer_t fb_depth;
static VU0_VECTOR vp_origin, vp_scale; static VU0_vector vp_origin, vp_scale;
static cc_bool stateDirty, formatDirty; static cc_bool stateDirty, formatDirty;
static framebuffer_t* fb_draw; static framebuffer_t* fb_draw;
static framebuffer_t* fb_display; static framebuffer_t* fb_display;
static VU0_MATRIX mvp; static VU0_matrix mvp;
extern void LoadMvpMatrix(VU0_MATRIX* matrix); extern void LoadMvpMatrix(VU0_matrix* matrix);
extern void LoadClipScaleFactors(VU0_VECTOR* scale); extern void LoadClipScaleFactors(VU0_vector* scale);
extern void LoadViewportOrigin(VU0_VECTOR* origin); extern void LoadViewportOrigin(VU0_vector* origin);
extern void LoadViewportScale(VU0_VECTOR* scale); extern void LoadViewportScale(VU0_vector* scale);
// double buffering // double buffering
static packet_t* packets[2]; static packet_t* packets[2];
static packet_t* current; static packet_t* current;
static int context; static int context;
static qword_t* dma_beg; static qword_t* dma_beg;
static qword_t* q; static qword_t* Q;
static GfxResourceID white_square; static GfxResourceID white_square;
static int primitive_type; static int primitive_type;
@ -75,32 +78,32 @@ static void UpdateContext(void) {
dma_beg = current->data; dma_beg = current->data;
// increment past the dmatag itself // increment past the dmatag itself
q = dma_beg + 1; Q = dma_beg + 1;
} }
static void SetTextureWrapping(int context) { static void SetTextureWrapping(int context) {
PACK_GIFTAG(q, GIF_SET_TAG(1,0,0,0, GIF_FLG_PACKED, 1), GIF_REG_AD); PACK_GIFTAG(Q, GIF_SET_TAG(1,0,0,0, GIF_FLG_PACKED, 1), GIF_REG_AD);
q++; Q++;
PACK_GIFTAG(q, GS_SET_CLAMP(WRAP_REPEAT, WRAP_REPEAT, 0, 0, 0, 0), PACK_GIFTAG(Q, GS_SET_CLAMP(WRAP_REPEAT, WRAP_REPEAT, 0, 0, 0, 0),
GS_REG_CLAMP + context); GS_REG_CLAMP + context);
q++; Q++;
} }
static void SetTextureSampling(int context) { static void SetTextureSampling(int context) {
PACK_GIFTAG(q, GIF_SET_TAG(1,0,0,0, GIF_FLG_PACKED, 1), GIF_REG_AD); PACK_GIFTAG(Q, GIF_SET_TAG(1,0,0,0, GIF_FLG_PACKED, 1), GIF_REG_AD);
q++; Q++;
// TODO: should mipmapselect (first 0 after MIN_NEAREST) be 1? // TODO: should mipmapselect (first 0 after MIN_NEAREST) be 1?
PACK_GIFTAG(q, GS_SET_TEX1(LOD_USE_K, 0, LOD_MAG_NEAREST, LOD_MIN_NEAREST, 0, 0, 0), PACK_GIFTAG(Q, GS_SET_TEX1(LOD_USE_K, 0, LOD_MAG_NEAREST, LOD_MIN_NEAREST, 0, 0, 0),
GS_REG_TEX1 + context); GS_REG_TEX1 + context);
q++; Q++;
} }
static void SetAlphaBlending(int context) { static void SetAlphaBlending(int context) {
PACK_GIFTAG(q, GIF_SET_TAG(1,0,0,0, GIF_FLG_PACKED, 1), GIF_REG_AD); PACK_GIFTAG(Q, GIF_SET_TAG(1,0,0,0, GIF_FLG_PACKED, 1), GIF_REG_AD);
q++; Q++;
// https://psi-rockin.github.io/ps2tek/#gsalphablending // https://psi-rockin.github.io/ps2tek/#gsalphablending
// Output = (((A - B) * C) >> 7) + D // Output = (((A - B) * C) >> 7) + D
@ -108,25 +111,25 @@ static void SetAlphaBlending(int context) {
// = (src * alpha - dst * alpha) / 128 + dst // = (src * alpha - dst * alpha) / 128 + dst
// = (src * alpha - dst * alpha) / 128 + dst * 128 / 128 // = (src * alpha - dst * alpha) / 128 + dst * 128 / 128
// = ((src * alpha + dst * (128 - alpha)) / 128 // = ((src * alpha + dst * (128 - alpha)) / 128
PACK_GIFTAG(q, GS_SET_ALPHA(BLEND_COLOR_SOURCE, BLEND_COLOR_DEST, BLEND_ALPHA_SOURCE, PACK_GIFTAG(Q, GS_SET_ALPHA(BLEND_COLOR_SOURCE, BLEND_COLOR_DEST, BLEND_ALPHA_SOURCE,
BLEND_COLOR_DEST, 0x80), GS_REG_ALPHA + context); BLEND_COLOR_DEST, 0x80), GS_REG_ALPHA + context);
q++; Q++;
} }
static void InitDrawingEnv(void) { static void InitDrawingEnv(void) {
qword_t* beg = q; qword_t* beg = Q;
q = draw_setup_environment(q, 0, fb_draw, &fb_depth); Q = draw_setup_environment(Q, 0, fb_draw, &fb_depth);
// GS can render from 0 to 4096, so set primitive origin to centre of that // GS can render from 0 to 4096, so set primitive origin to centre of that
q = draw_primitive_xyoffset(q, 0, 2048 - Game.Width / 2, 2048 - Game.Height / 2); Q = draw_primitive_xyoffset(Q, 0, 2048 - Game.Width / 2, 2048 - Game.Height / 2);
SetTextureWrapping(0); SetTextureWrapping(0);
SetTextureSampling(0); SetTextureSampling(0);
SetAlphaBlending(0); // TODO has no effect ? SetAlphaBlending(0); // TODO has no effect ?
q = draw_finish(q); Q = draw_finish(Q);
dma_channel_send_normal(DMA_CHANNEL_GIF, beg, q - beg, 0, 0); dma_channel_send_normal(DMA_CHANNEL_GIF, beg, Q - beg, 0, 0);
dma_wait_fast(); dma_wait_fast();
q = dma_beg + 1; Q = dma_beg + 1;
} }
static unsigned clut_offset, tex_offset; static unsigned clut_offset, tex_offset;
@ -160,21 +163,90 @@ void Gfx_Free(void) {
} }
static CC_INLINE void DMAFlushBuffer(void) { static CC_INLINE void DMAFlushBuffer(void) {
if (q == dma_beg) return; if (Q == dma_beg) return;
DMATAG_END(dma_beg, (q - dma_beg) - 1, 0, 0, 0); DMATAG_END(dma_beg, (Q - dma_beg) - 1, 0, 0, 0);
dma_channel_send_chain(DMA_CHANNEL_GIF, dma_beg, q - dma_beg, 0, 0); dma_channel_send_chain(DMA_CHANNEL_GIF, dma_beg, Q - dma_beg, 0, 0);
} }
void Gfx_TransferPixels(void* src, int src_width, int src_height, static int CalculateQWords(int width, int height, int psm) {
int format, unsigned dst_addr, unsigned dst_stride) { switch (psm)
packet_t *packet = packet_init(200, PACKET_NORMAL); {
qword_t *Q = packet->data; case GS_PSM_32:
case GS_PSM_24:
case GS_PSMZ_32:
case GS_PSMZ_24:
return (width * height) >> 2;
Q = draw_texture_transfer(Q, src, src_width, src_height, format, dst_addr, dst_stride); case GS_PSM_16:
Q = draw_texture_flush(Q); case GS_PSM_16S:
case GS_PSMZ_16:
case GS_PSMZ_16S:
return (width * height) >> 3;
dma_channel_send_chain(DMA_CHANNEL_GIF, packet->data, Q - packet->data, 0,0); case GS_PSM_8:
case GS_PSM_8H:
return (width * height) >> 4;
case GS_PSM_4:
case GS_PSM_4HL:
case GS_PSM_4HH:
return (width * height) >> 5;
}
return 0;
}
static qword_t* BuildTransfer(qword_t* q, u8* src, int width, int height, int psm,
int dst_base, int dst_width)
{
int qwords = CalculateQWords(width, height, psm);
// Parameters for RAM -> GS transfer
DMATAG_CNT(q,5,0,0,0);
q++;
PACK_GIFTAG(q, GIF_SET_TAG(4,0,0,0,GIF_FLG_PACKED,1), GIF_REG_AD);
q++;
PACK_GIFTAG(q, GS_SET_BITBLTBUF(0,0,0, dst_base >> 6, dst_width >> 6, psm), GS_REG_BITBLTBUF);
q++;
PACK_GIFTAG(q, GS_SET_TRXPOS(0,0,0,0,0), GS_REG_TRXPOS);
q++;
PACK_GIFTAG(q, GS_SET_TRXREG(width, height), GS_REG_TRXREG);
q++;
PACK_GIFTAG(q, GS_SET_TRXDIR(0), GS_REG_TRXDIR);
q++;
while (qwords)
{
int num_qwords = min(qwords, GIF_BLOCK_SIZE);
DMATAG_CNT(q,1,0,0,0);
q++;
PACK_GIFTAG(q, GIF_SET_TAG(num_qwords,0,0,0,GIF_FLG_IMAGE,0), 0);
q++;
DMATAG_REF(q, num_qwords, (unsigned int)src, 0,0,0);
q++;
src += num_qwords * 16;
qwords -= num_qwords;
}
DMATAG_END(q,2,0,0,0);
q++;
PACK_GIFTAG(q,GIF_SET_TAG(1,1,0,0,GIF_FLG_PACKED,1),GIF_REG_AD);
q++;
PACK_GIFTAG(q,1,GS_REG_TEXFLUSH);
q++;
return q;
}
void Gfx_TransferPixels(void* src, int width, int height,
int format, unsigned dst_base, unsigned dst_stride) {
packet_t* packet = packet_init(200, PACKET_NORMAL);
qword_t* q = packet->data;
q = BuildTransfer(q, src, width, height, format, dst_base, dst_stride);
dma_channel_send_chain(DMA_CHANNEL_GIF, packet->data, q - packet->data, 0,0);
dma_wait_fast(); dma_wait_fast();
packet_free(packet); packet_free(packet);
@ -280,7 +352,7 @@ GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags,
tex->log2_height = draw_log2(bmp->height); tex->log2_height = draw_log2(bmp->height);
tex->pal_index = 0; tex->pal_index = 0;
BitmapCol palette[MAX_PAL_ENTRIES] __attribute__((aligned(16))); BitmapCol palette[MAX_PAL_ENTRIES] QWORD_ALIGNED;
int pal_count = 0; int pal_count = 0;
int pal_index = FindFreePalette(flags); int pal_index = FindFreePalette(flags);
@ -303,8 +375,8 @@ GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags,
} }
static void UpdateTextureBuffer(int context, CCTexture* tex, unsigned buf_addr, unsigned buf_stride) { static void UpdateTextureBuffer(int context, CCTexture* tex, unsigned buf_addr, unsigned buf_stride) {
PACK_GIFTAG(q, GIF_SET_TAG(1,0,0,0, GIF_FLG_PACKED, 1), GIF_REG_AD); PACK_GIFTAG(Q, GIF_SET_TAG(1,0,0,0, GIF_FLG_PACKED, 1), GIF_REG_AD);
q++; Q++;
unsigned clut_addr = tex->format == GS_PSM_32 ? 0 : PaletteAddr(tex->pal_index) >> 6; unsigned clut_addr = tex->format == GS_PSM_32 ? 0 : PaletteAddr(tex->pal_index) >> 6;
unsigned clut_entry = 0; unsigned clut_entry = 0;
@ -312,10 +384,10 @@ static void UpdateTextureBuffer(int context, CCTexture* tex, unsigned buf_addr,
//unsigned clut_entry = tex->format == GS_PSM_32 ? 0 : tex->pal_index; //unsigned clut_entry = tex->format == GS_PSM_32 ? 0 : tex->pal_index;
unsigned clut_mode = tex->format == GS_PSM_32 ? CLUT_NO_LOAD : CLUT_LOAD; unsigned clut_mode = tex->format == GS_PSM_32 ? CLUT_NO_LOAD : CLUT_LOAD;
PACK_GIFTAG(q, GS_SET_TEX0(buf_addr >> 6, buf_stride >> 6, tex->format, PACK_GIFTAG(Q, GS_SET_TEX0(buf_addr >> 6, buf_stride >> 6, tex->format,
tex->log2_width, tex->log2_height, TEXTURE_COMPONENTS_RGBA, TEXTURE_FUNCTION_MODULATE, tex->log2_width, tex->log2_height, TEXTURE_COMPONENTS_RGBA, TEXTURE_FUNCTION_MODULATE,
clut_addr, GS_PSM_32, CLUT_STORAGE_MODE1, clut_entry, clut_mode), GS_REG_TEX0 + context); clut_addr, GS_PSM_32, CLUT_STORAGE_MODE1, clut_entry, clut_mode), GS_REG_TEX0 + context);
q++; Q++;
} }
void Gfx_BindTexture(GfxResourceID texId) { void Gfx_BindTexture(GfxResourceID texId) {
@ -335,7 +407,7 @@ void Gfx_BindTexture(GfxResourceID texId) {
tex->format, dst_addr, dst_stride); tex->format, dst_addr, dst_stride);
// TODO terrible perf // TODO terrible perf
q = dma_beg + 1; Q = dma_beg + 1;
UpdateTextureBuffer(0, tex, dst_addr, dst_stride); UpdateTextureBuffer(0, tex, dst_addr, dst_stride);
} }
@ -380,13 +452,13 @@ static void UpdateState(int context) {
int aMethod = gfx_alphaTest ? ATEST_METHOD_GREATER_EQUAL : ATEST_METHOD_ALLPASS; int aMethod = gfx_alphaTest ? ATEST_METHOD_GREATER_EQUAL : ATEST_METHOD_ALLPASS;
int zMethod = gfx_depthTest ? ZTEST_METHOD_GREATER_EQUAL : ZTEST_METHOD_ALLPASS; int zMethod = gfx_depthTest ? ZTEST_METHOD_GREATER_EQUAL : ZTEST_METHOD_ALLPASS;
PACK_GIFTAG(q, GIF_SET_TAG(1,0,0,0, GIF_FLG_PACKED, 1), GIF_REG_AD); PACK_GIFTAG(Q, GIF_SET_TAG(1,0,0,0, GIF_FLG_PACKED, 1), GIF_REG_AD);
q++; Q++;
// NOTE: Reference value is 0x40 instead of 0x80, since alpha values are halved compared to normal // NOTE: Reference value is 0x40 instead of 0x80, since alpha values are halved compared to normal
PACK_GIFTAG(q, GS_SET_TEST(DRAW_ENABLE, aMethod, 0x40, ATEST_KEEP_ALL, PACK_GIFTAG(Q, GS_SET_TEST(DRAW_ENABLE, aMethod, 0x40, ATEST_KEEP_ALL,
DRAW_DISABLE, DRAW_DISABLE, DRAW_DISABLE, DRAW_DISABLE,
DRAW_ENABLE, zMethod), GS_REG_TEST + context); DRAW_ENABLE, zMethod), GS_REG_TEST + context);
q++; Q++;
stateDirty = false; stateDirty = false;
} }
@ -394,12 +466,12 @@ static void UpdateState(int context) {
static void UpdateFormat(int context) { static void UpdateFormat(int context) {
cc_bool texturing = gfx_format == VERTEX_FORMAT_TEXTURED; cc_bool texturing = gfx_format == VERTEX_FORMAT_TEXTURED;
PACK_GIFTAG(q, GIF_SET_TAG(1,0,0,0, GIF_FLG_PACKED, 1), GIF_REG_AD); PACK_GIFTAG(Q, GIF_SET_TAG(1,0,0,0, GIF_FLG_PACKED, 1), GIF_REG_AD);
q++; Q++;
PACK_GIFTAG(q, GS_SET_PRIM(PRIM_TRIANGLE, PRIM_SHADE_GOURAUD, texturing, DRAW_DISABLE, PACK_GIFTAG(Q, GS_SET_PRIM(PRIM_TRIANGLE, PRIM_SHADE_GOURAUD, texturing, DRAW_DISABLE,
gfx_alphaBlend, DRAW_DISABLE, PRIM_MAP_ST, gfx_alphaBlend, DRAW_DISABLE, PRIM_MAP_ST,
context, PRIM_UNFIXED), GS_REG_PRIM); context, PRIM_UNFIXED), GS_REG_PRIM);
q++; Q++;
formatDirty = false; formatDirty = false;
} }
@ -420,8 +492,8 @@ void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
void Gfx_ClearBuffers(GfxBuffers buffers) { void Gfx_ClearBuffers(GfxBuffers buffers) {
// TODO clear only some buffers // TODO clear only some buffers
q = draw_disable_tests(q, 0, &fb_depth); Q = draw_disable_tests(Q, 0, &fb_depth);
q = draw_clear(q, 0, 2048.0f - fb_colors[0].width / 2.0f, 2048.0f - fb_colors[0].height / 2.0f, Q = draw_clear(Q, 0, 2048.0f - fb_colors[0].width / 2.0f, 2048.0f - fb_colors[0].height / 2.0f,
fb_colors[0].width, fb_colors[0].height, clearR, clearG, clearB); fb_colors[0].width, fb_colors[0].height, clearR, clearG, clearB);
UpdateState(0); UpdateState(0);
@ -441,7 +513,7 @@ void Gfx_SetDepthTest(cc_bool enabled) {
void Gfx_SetDepthWrite(cc_bool enabled) { void Gfx_SetDepthWrite(cc_bool enabled) {
fb_depth.mask = !enabled; fb_depth.mask = !enabled;
q = draw_zbuffer(q, 0, &fb_depth); Q = draw_zbuffer(Q, 0, &fb_depth);
fb_depth.mask = 0; fb_depth.mask = 0;
} }
@ -453,7 +525,7 @@ static void SetColorWrite(cc_bool r, cc_bool g, cc_bool b, cc_bool a) {
if (!a) mask |= 0xFF000000; if (!a) mask |= 0xFF000000;
fb_draw->mask = mask; fb_draw->mask = mask;
q = draw_framebuffer(q, 0, fb_draw); Q = draw_framebuffer(Q, 0, fb_draw);
fb_draw->mask = 0; fb_draw->mask = 0;
} }
@ -655,10 +727,10 @@ void Gfx_SetVertexFormat(VertexFormat fmt) {
formatDirty = true; formatDirty = true;
} }
extern void ViewportTransform(VU0_VECTOR* src, VU0_IVECTOR* dst); extern void ViewportTransform(VU0_vector* src, VU0_IVector* dst);
static xyz_t FinishVertex(VU0_VECTOR* src, float invW) { static xyz_t FinishVertex(VU0_vector* src, float invW) {
src->w = invW; src->w = invW;
VU0_IVECTOR tmp; VU0_IVector tmp;
ViewportTransform(src, &tmp); ViewportTransform(src, &tmp);
xyz_t xyz; xyz_t xyz;
@ -668,50 +740,50 @@ static xyz_t FinishVertex(VU0_VECTOR* src, float invW) {
return xyz; return xyz;
} }
static u64* DrawTexturedTriangle(u64* dw, VU0_VECTOR* coords, static u64* DrawTexturedTriangle(u64* dw, VU0_vector* coords,
struct VertexTextured* V0, struct VertexTextured* V1, struct VertexTextured* V2) { struct VertexTextured* V0, struct VertexTextured* V1, struct VertexTextured* V2) {
TexturedVertex* dst = (TexturedVertex*)dw; TexturedVertex* dst = (TexturedVertex*)dw;
float Q; float q;
// TODO optimise // TODO optimise
// Add the "primitives" to the GIF packet // Add the "primitives" to the GIF packet
Q = 1.0f / coords[0].w; q = 1.0f / coords[0].w;
dst[0].rgba = V0->Col; dst[0].rgba = V0->Col;
dst[0].q = Q; dst[0].q = q;
dst[0].u = V0->U * Q; dst[0].u = V0->U * q;
dst[0].v = V0->V * Q; dst[0].v = V0->V * q;
dst[0].xyz = FinishVertex(&coords[0], Q); dst[0].xyz = FinishVertex(&coords[0], q);
Q = 1.0f / coords[1].w; q = 1.0f / coords[1].w;
dst[1].rgba = V1->Col; dst[1].rgba = V1->Col;
dst[1].q = Q; dst[1].q = q;
dst[1].u = V1->U * Q; dst[1].u = V1->U * q;
dst[1].v = V1->V * Q; dst[1].v = V1->V * q;
dst[1].xyz = FinishVertex(&coords[1], Q); dst[1].xyz = FinishVertex(&coords[1], q);
Q = 1.0f / coords[2].w; q = 1.0f / coords[2].w;
dst[2].rgba = V2->Col; dst[2].rgba = V2->Col;
dst[2].q = Q; dst[2].q = q;
dst[2].u = V2->U * Q; dst[2].u = V2->U * q;
dst[2].v = V2->V * Q; dst[2].v = V2->V * q;
dst[2].xyz = FinishVertex(&coords[2], Q); dst[2].xyz = FinishVertex(&coords[2], q);
return dw + 9; return dw + 9;
} }
extern void TransformTexturedQuad(void* src, VU0_VECTOR* dst, VU0_VECTOR* tmp, int* clip_flags); extern void TransformTexturedQuad(void* src, VU0_vector* dst, VU0_vector* tmp, int* clip_flags);
extern void TransformColouredQuad(void* src, VU0_VECTOR* dst, VU0_VECTOR* tmp, int* clip_flags); extern void TransformColouredQuad(void* src, VU0_vector* dst, VU0_vector* tmp, int* clip_flags);
extern u64* DrawTexturedQuad(void* src, u64* dst, VU0_VECTOR* tmp); extern u64* DrawTexturedQuad(void* src, u64* dst, VU0_vector* tmp);
extern u64* DrawColouredQuad(void* src, u64* dst, VU0_VECTOR* tmp); extern u64* DrawColouredQuad(void* src, u64* dst, VU0_vector* tmp);
static void DrawTexturedTriangles(int verticesCount, int startVertex) { static void DrawTexturedTriangles(int verticesCount, int startVertex) {
struct VertexTextured* v = (struct VertexTextured*)gfx_vertices + startVertex; struct VertexTextured* v = (struct VertexTextured*)gfx_vertices + startVertex;
qword_t* base = q; qword_t* base = Q;
q++; // skip over GIF tag (will be filled in later) Q++; // skip over GIF tag (will be filled in later)
u64* dw = (u64*)q; u64* dw = (u64*)Q;
u64* beg = dw; u64* beg = dw;
VU0_VECTOR tmp[6]; VU0_vector tmp[6];
for (int i = 0; i < verticesCount / 4; i++, v += 4) for (int i = 0; i < verticesCount / 4; i++, v += 4)
{ {
@ -720,10 +792,10 @@ static void DrawTexturedTriangles(int verticesCount, int startVertex) {
unsigned numVerts = (unsigned)(dw - beg) / 3; unsigned numVerts = (unsigned)(dw - beg) / 3;
if (numVerts == 0) { if (numVerts == 0) {
q--; // No GIF tag was added Q--; // No GIF tag was added
} else { } else {
if (numVerts & 1) dw++; // one more to even out number of doublewords if (numVerts & 1) dw++; // one more to even out number of doublewords
q = (qword_t*)dw; Q = (qword_t*)dw;
// Fill GIF tag in now that know number of GIF "primitives" (aka vertices) // Fill GIF tag in now that know number of GIF "primitives" (aka vertices)
// 2 registers per GIF "primitive" (colour, position) // 2 registers per GIF "primitive" (colour, position)
@ -733,12 +805,12 @@ static void DrawTexturedTriangles(int verticesCount, int startVertex) {
static void DrawColouredTriangles(int verticesCount, int startVertex) { static void DrawColouredTriangles(int verticesCount, int startVertex) {
struct VertexColoured* v = (struct VertexColoured*)gfx_vertices + startVertex; struct VertexColoured* v = (struct VertexColoured*)gfx_vertices + startVertex;
qword_t* base = q; qword_t* base = Q;
q++; // skip over GIF tag (will be filled in later) Q++; // skip over GIF tag (will be filled in later)
u64* dw = (u64*)q; u64* dw = (u64*)Q;
u64* beg = dw; u64* beg = dw;
VU0_VECTOR tmp[6]; VU0_vector tmp[6];
for (int i = 0; i < verticesCount / 4; i++, v += 4) for (int i = 0; i < verticesCount / 4; i++, v += 4)
{ {
@ -747,9 +819,9 @@ static void DrawColouredTriangles(int verticesCount, int startVertex) {
unsigned numVerts = (unsigned)(dw - beg) / 2; unsigned numVerts = (unsigned)(dw - beg) / 2;
if (numVerts == 0) { if (numVerts == 0) {
q--; // No GIF tag was added Q--; // No GIF tag was added
} else { } else {
q = (qword_t*)dw; Q = (qword_t*)dw;
// Fill GIF tag in now that know number of GIF "primitives" (aka vertices) // Fill GIF tag in now that know number of GIF "primitives" (aka vertices)
// 2 registers per GIF "primitive" (colour, texture, position) // 2 registers per GIF "primitive" (colour, texture, position)
@ -761,10 +833,10 @@ static void DrawTriangles(int verticesCount, int startVertex) {
if (stateDirty) UpdateState(0); if (stateDirty) UpdateState(0);
if (formatDirty) UpdateFormat(0); if (formatDirty) UpdateFormat(0);
if ((q - current->data) > 45000) { if ((Q - current->data) > 45000) {
DMAFlushBuffer(); DMAFlushBuffer();
dma_wait_fast(); dma_wait_fast();
q = dma_beg + 1; Q = dma_beg + 1;
Platform_LogConst("Too much geometry!!"); Platform_LogConst("Too much geometry!!");
} }
@ -786,12 +858,12 @@ static void SetPrimitiveType(int type) {
if (primitive_type == type) return; if (primitive_type == type) return;
primitive_type = type; primitive_type = type;
PACK_GIFTAG(q, GIF_SET_TAG(1,0,0,0, GIF_FLG_PACKED, 1), GIF_REG_AD); PACK_GIFTAG(Q, GIF_SET_TAG(1,0,0,0, GIF_FLG_PACKED, 1), GIF_REG_AD);
q++; Q++;
PACK_GIFTAG(q, GS_SET_PRIM(type, PRIM_SHADE_GOURAUD, DRAW_DISABLE, DRAW_DISABLE, PACK_GIFTAG(Q, GS_SET_PRIM(type, PRIM_SHADE_GOURAUD, DRAW_DISABLE, DRAW_DISABLE,
DRAW_DISABLE, DRAW_DISABLE, PRIM_MAP_ST, DRAW_DISABLE, DRAW_DISABLE, PRIM_MAP_ST,
0, PRIM_UNFIXED), GS_REG_PRIM); 0, PRIM_UNFIXED), GS_REG_PRIM);
q++; Q++;
} }
void Gfx_DrawVb_Lines(int verticesCount) { void Gfx_DrawVb_Lines(int verticesCount) {
@ -833,7 +905,7 @@ void Gfx_BeginFrame(void) {
void Gfx_EndFrame(void) { void Gfx_EndFrame(void) {
//Platform_LogConst("--- EF1 ---"); //Platform_LogConst("--- EF1 ---");
q = draw_finish(q); Q = draw_finish(Q);
dma_wait_fast(); dma_wait_fast();
DMAFlushBuffer(); DMAFlushBuffer();
@ -847,7 +919,7 @@ void Gfx_EndFrame(void) {
UpdateContext(); UpdateContext();
// Double buffering // Double buffering
q = draw_framebuffer(q, 0, fb_draw); Q = draw_framebuffer(Q, 0, fb_draw);
graph_set_framebuffer_filtered(fb_display->address, graph_set_framebuffer_filtered(fb_display->address,
fb_display->width, fb_display->width,
fb_display->psm, 0, 0); fb_display->psm, 0, 0);
@ -864,7 +936,7 @@ void Gfx_OnWindowResize(void) {
} }
void Gfx_SetViewport(int x, int y, int w, int h) { void Gfx_SetViewport(int x, int y, int w, int h) {
VU0_VECTOR clip_scale; VU0_vector clip_scale;
unsigned int maxZ = 1 << (24 - 1); // TODO: half this? or << 24 instead? unsigned int maxZ = 1 << (24 - 1); // TODO: half this? or << 24 instead?
vp_origin.x = ftoi4(2048 - (x / 2)); vp_origin.x = ftoi4(2048 - (x / 2));
@ -907,10 +979,10 @@ void Gfx_SetViewport(int x, int y, int w, int h) {
void Gfx_SetScissor(int x, int y, int w, int h) { void Gfx_SetScissor(int x, int y, int w, int h) {
int context = 0; int context = 0;
PACK_GIFTAG(q, GIF_SET_TAG(1,0,0,0, GIF_FLG_PACKED, 1), GIF_REG_AD); PACK_GIFTAG(Q, GIF_SET_TAG(1,0,0,0, GIF_FLG_PACKED, 1), GIF_REG_AD);
q++; Q++;
PACK_GIFTAG(q, GS_SET_SCISSOR(x, x+w-1, y,y+h-1), GS_REG_SCISSOR + context); PACK_GIFTAG(Q, GS_SET_SCISSOR(x, x+w-1, y,y+h-1), GS_REG_SCISSOR + context);
q++; Q++;
} }
void Gfx_GetApiInfo(cc_string* info) { void Gfx_GetApiInfo(cc_string* info) {

View File

@ -666,7 +666,9 @@ static void IconsPngProcess(struct Stream* stream, const cc_string* name) {
static struct TextureEntry icons_entry = { "icons.png", IconsPngProcess }; static struct TextureEntry icons_entry = { "icons.png", IconsPngProcess };
static void TouchPngProcess(struct Stream* stream, const cc_string* name) { static void TouchPngProcess(struct Stream* stream, const cc_string* name) {
Game_UpdateTexture(&Gui.TouchTex, stream, name, NULL, NULL); if (!Gui.TouchUI) return;
Game_UpdateTexture(&Gui.TouchTex, stream, name, NULL, NULL);
} }
static struct TextureEntry touch_entry = { "touch.png", TouchPngProcess }; static struct TextureEntry touch_entry = { "touch.png", TouchPngProcess };

View File

@ -328,8 +328,8 @@ void Window_AllocFramebuffer(struct Bitmap* bmp, int width, int height) {
packet_free(packet); packet_free(packet);
} }
extern void Gfx_TransferPixels(void* src, int src_width, int src_height, extern void Gfx_TransferPixels(void* src, int width, int height,
int format, unsigned dst_addr, unsigned dst_stride); int format, unsigned dst_base, unsigned dst_stride);
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) { void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
// FlushCache bios call https://psi-rockin.github.io/ps2tek/ // FlushCache bios call https://psi-rockin.github.io/ps2tek/