Renders on Dolphin also.

This commit is contained in:
2026-03-10 15:07:50 -05:00
parent c5f5b025a6
commit 9a98348582
8 changed files with 114 additions and 75 deletions

View File

@@ -15,7 +15,7 @@ CELL_STATE_HOVER = 1
CELL_STATE_DOWN = 2 CELL_STATE_DOWN = 2
CELL_STATE_DISABLED = 3 CELL_STATE_DISABLED = 3
screenSetBackground(colorBlack()) screenSetBackground(colorCornflowerBlue())
camera = cameraCreate(CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC) camera = cameraCreate(CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC)
-- tilesetUi = tilesetGetByName("ui") -- tilesetUi = tilesetGetByName("ui")

View File

@@ -1,6 +1,5 @@
# Target definitions # Target definitions
target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC
DUSK_PLATFORM_ENDIAN_BIG
DUSK_DOLPHIN DUSK_DOLPHIN
DUSK_DISPLAY_WIDTH=640 DUSK_DISPLAY_WIDTH=640
DUSK_DISPLAY_HEIGHT=480 DUSK_DISPLAY_HEIGHT=480

View File

@@ -8,6 +8,7 @@
#include "mesh.h" #include "mesh.h"
#include "util/memory.h" #include "util/memory.h"
#include "assert/assert.h" #include "assert/assert.h"
#include "debug/debug.h"
errorret_t meshInit( errorret_t meshInit(
mesh_t *mesh, mesh_t *mesh,

View File

@@ -9,7 +9,7 @@
#include "display/mesh/quad.h" #include "display/mesh/quad.h"
#include "display/texture/texture.h" #include "display/texture/texture.h"
#define SPRITEBATCH_SPRITES_MAX 128 #define SPRITEBATCH_SPRITES_MAX 16
#define SPRITEBATCH_VERTEX_COUNT (SPRITEBATCH_SPRITES_MAX * QUAD_VERTEX_COUNT) #define SPRITEBATCH_VERTEX_COUNT (SPRITEBATCH_SPRITES_MAX * QUAD_VERTEX_COUNT)
@@ -20,7 +20,6 @@ typedef struct {
} spritebatch_t; } spritebatch_t;
// Have to define these seperately because of alignment in certain platforms. // Have to define these seperately because of alignment in certain platforms.
// (Looking at you Dolphin)
extern meshvertex_t SPRITEBATCH_VERTICES[SPRITEBATCH_VERTEX_COUNT]; extern meshvertex_t SPRITEBATCH_VERTICES[SPRITEBATCH_VERTEX_COUNT];
extern spritebatch_t SPRITEBATCH; extern spritebatch_t SPRITEBATCH;

View File

@@ -12,20 +12,25 @@
static char_t DEBUG_ERROR_BUFFER[16*1024] = {0}; static char_t DEBUG_ERROR_BUFFER[16*1024] = {0};
void debugPrint(const char_t *message, ...) { void debugPrint(const char_t *message, ...) {
// append to error buffer
size_t start = strlen(DEBUG_ERROR_BUFFER); size_t start = strlen(DEBUG_ERROR_BUFFER);
va_list args; va_list args;
va_start(args, message); va_start(args, message);
fprintf(stdout, message, args);
va_end(args);
va_start(args, message); // Print to stdout
va_list copy;
va_copy(copy, args);
vfprintf(stdout, message, copy);
va_end(copy);
// Append to buffer
vsnprintf( vsnprintf(
DEBUG_ERROR_BUFFER + start, DEBUG_ERROR_BUFFER + start,
sizeof(DEBUG_ERROR_BUFFER) - start, sizeof(DEBUG_ERROR_BUFFER) - start,
message, message,
args args
); );
va_end(args); va_end(args);
} }

View File

@@ -15,9 +15,15 @@ errorret_t displayInitDolphin(void) {
DISPLAY.frameBuffer[0] = MEM_K0_TO_K1( DISPLAY.frameBuffer[0] = MEM_K0_TO_K1(
SYS_AllocateFramebuffer(DISPLAY.screenMode) SYS_AllocateFramebuffer(DISPLAY.screenMode)
); );
if(DISPLAY.frameBuffer[0] == NULL) {
errorThrow("Failed to allocate framebuffer");
}
DISPLAY.frameBuffer[1] = MEM_K0_TO_K1( DISPLAY.frameBuffer[1] = MEM_K0_TO_K1(
SYS_AllocateFramebuffer(DISPLAY.screenMode) SYS_AllocateFramebuffer(DISPLAY.screenMode)
); );
if(DISPLAY.frameBuffer[1] == NULL) {
errorThrow("Failed to allocate framebuffer");
}
VIDEO_Configure(DISPLAY.screenMode); VIDEO_Configure(DISPLAY.screenMode);
VIDEO_SetNextFramebuffer(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer]); VIDEO_SetNextFramebuffer(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer]);
@@ -28,6 +34,9 @@ errorret_t displayInitDolphin(void) {
if(DISPLAY.screenMode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync(); if(DISPLAY.screenMode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
DISPLAY.fifoBuffer = memalign(32, DISPLAY_DOLPHIN_FIFO_SIZE); DISPLAY.fifoBuffer = memalign(32, DISPLAY_DOLPHIN_FIFO_SIZE);
if(DISPLAY.fifoBuffer == NULL) {
errorThrow("Failed to allocate FIFO buffer");
}
memoryZero(DISPLAY.fifoBuffer, DISPLAY_DOLPHIN_FIFO_SIZE); memoryZero(DISPLAY.fifoBuffer, DISPLAY_DOLPHIN_FIFO_SIZE);
GX_Init(DISPLAY.fifoBuffer, DISPLAY_DOLPHIN_FIFO_SIZE); GX_Init(DISPLAY.fifoBuffer, DISPLAY_DOLPHIN_FIFO_SIZE);
@@ -69,15 +78,16 @@ errorret_t displayInitDolphin(void) {
// Setup cull modes // Setup cull modes
GX_SetCullMode(GX_CULL_NONE); GX_SetCullMode(GX_CULL_NONE);
GX_SetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE); GX_SetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE);
GX_CopyDisp(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer], GX_TRUE);
GX_SetDispCopyGamma(GX_GM_1_0); GX_SetDispCopyGamma(GX_GM_1_0);
GX_SetColorUpdate(GX_TRUE);
// Describe mesh vertex format.
GX_ClearVtxDesc(); GX_ClearVtxDesc();
GX_SetVtxDesc(GX_VA_POS, GX_INDEX16); GX_SetVtxDesc(GX_VA_POS, GX_INDEX16);
GX_SetVtxDesc(GX_VA_CLR0, GX_INDEX16); GX_SetVtxDesc(GX_VA_CLR0, GX_INDEX16);
GX_SetVtxDesc(GX_VA_TEX0, GX_INDEX16); GX_SetVtxDesc(GX_VA_TEX0, GX_INDEX16);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_U8, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
errorOk(); errorOk();
@@ -85,14 +95,15 @@ errorret_t displayInitDolphin(void) {
errorret_t displayUpdateDolphin(void) { errorret_t displayUpdateDolphin(void) {
ENGINE.running = SYS_MainLoop(); ENGINE.running = SYS_MainLoop();
errorOk();
} }
errorret_t displaySwapDolphin(void) { errorret_t displaySwapDolphin(void) {
GX_DrawDone(); GX_DrawDone();
DISPLAY.whichFrameBuffer ^= 1; DISPLAY.whichFrameBuffer ^= 1;
GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); // GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
GX_SetColorUpdate(GX_TRUE); // GX_SetColorUpdate(GX_TRUE);
GX_CopyDisp(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer], GX_TRUE); GX_CopyDisp(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer], GX_TRUE);
VIDEO_SetNextFramebuffer(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer]); VIDEO_SetNextFramebuffer(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer]);
VIDEO_Flush(); VIDEO_Flush();

View File

@@ -8,6 +8,7 @@
#include "display/mesh/mesh.h" #include "display/mesh/mesh.h"
#include "display/texture/texture.h" #include "display/texture/texture.h"
#include "assert/assert.h" #include "assert/assert.h"
#include "debug/debug.h"
errorret_t meshInitDolphin( errorret_t meshInitDolphin(
meshdolphin_t *mesh, meshdolphin_t *mesh,
@@ -38,22 +39,28 @@ errorret_t meshDrawDolphin(
vertexOffset + vertexCount <= mesh->vertexCount, vertexOffset + vertexCount <= mesh->vertexCount,
"Requested vertex range is invalid" "Requested vertex range is invalid"
); );
assertTrue(vertexCount <= UINT16_MAX, "Vertex count exceeds GX limit");
// Matches vertex format described in displaydolphin.c
assertTrue(sizeof(color_t) == 4, "color_t must be exactly 4 bytes");
assertTrue(offsetof(meshvertex_t, color) == 0, "color offset wrong");
assertTrue(offsetof(meshvertex_t, uv) == 4, "uv offset wrong");
assertTrue(offsetof(meshvertex_t, pos) == 12, "pos offset wrong");
textureDolphinUploadTEV();
// Prepare Vertex descriptor
DCFlushRange( DCFlushRange(
(void*)&mesh->vertices[vertexOffset], (void*)&mesh->vertices[vertexOffset],
sizeof(meshvertex_t) * vertexCount sizeof(meshvertex_t) * vertexCount
); );
const u8 stride = (u8)sizeof(meshvertex_t); const uint8_t stride = (uint8_t)sizeof(meshvertex_t);
GX_SetArray(GX_VA_POS, (void*)&mesh->vertices[vertexOffset].pos[0], stride); GX_SetArray(GX_VA_POS, (void*)&mesh->vertices[vertexOffset].pos[0], stride);
GX_SetArray(GX_VA_CLR0, (void*)&mesh->vertices[vertexOffset].color, stride); GX_SetArray(GX_VA_CLR0, (void*)&mesh->vertices[vertexOffset].color.r, stride);
GX_SetArray(GX_VA_TEX0, (void*)&mesh->vertices[vertexOffset].uv[0], stride); GX_SetArray(GX_VA_TEX0, (void*)&mesh->vertices[vertexOffset].uv[0], stride);
textureDolphinUploadTEV();
GX_Begin(mesh->primitiveType, GX_VTXFMT0, (uint16_t)vertexCount); GX_Begin(mesh->primitiveType, GX_VTXFMT0, (uint16_t)vertexCount);
for(u16 i = 0; i < (u16)vertexCount; ++i) { for(uint16_t i = 0; i < (uint16_t)vertexCount; ++i) {
GX_Position1x16(i); GX_Position1x16(i);
GX_Color1x16(i); GX_Color1x16(i);
GX_TexCoord1x16(i); GX_TexCoord1x16(i);

View File

@@ -87,62 +87,6 @@ errorret_t textureInitDolphin(
// ); // );
// break; // break;
// case TEXTURE_FORMAT_ALPHA: {
// assertTrue(
// (width % 4) == 0 && (height % 4) == 0,
// "GX_TF_I8 requires w/h multiple of 4 (or pad)"
// );
// // 1 byte per pixel (I8), GX expects 4x4 tiled layout
// const size_t alphaSize = (size_t)width * (size_t)height;
// texture->alpha = (u8*)memalign(32, alphaSize);
// assertNotNull(texture->alpha, "Failed to allocate alpha texture data");
// const u32 tilesPerRow = ((u32)width) >> 3; // /8
// for (u32 y = 0; y < (u32)height; ++y) {
// const u32 tileY = y >> 2; // /4
// const u32 inTileY = (y & 3) << 3; // (y%4)*8
// for (u32 x = 0; x < (u32)width; ++x) {
// const u32 srcI = y * (u32)width + x;
// const u8 srcA = data.alpha.data[srcI]; // linear input
// const u32 tileX = x >> 3; // /8
// const u32 tileIndex = tileY * tilesPerRow + tileX;
// const u32 tileBase = tileIndex * 32; // 8*4*1 = 32 bytes per tile
// const u32 inTile = inTileY + (x & 7); // (y%4)*8 + (x%8)
// texture->alpha[tileBase + inTile] = 0xFF - srcA;// Fixes inverted alpha.
// }
// }
// // Flush CPU cache so GX sees the swizzled I8 texture data
// DCFlushRange(texture->alpha, alphaSize);
// // Initialize GX texture object with swizzled data
// GX_InitTexObj(
// &texture->texObj,
// texture->alpha,
// width, height,
// GX_TF_I8,
// GX_REPEAT, GX_REPEAT,
// GX_FALSE
// );
// GX_InitTexObjLOD(
// &texture->texObj,
// GX_NEAR, GX_NEAR,
// 0.0f, 0.0f, 0.0f,
// GX_FALSE,
// GX_FALSE,
// GX_ANISO_1
// );
// break;
// }
// case TEXTURE_FORMAT_PALETTE: { // case TEXTURE_FORMAT_PALETTE: {
// // Not supported, convert to RGBA using lookup // // Not supported, convert to RGBA using lookup
// color_t* formatted = memoryAllocate(width * height * sizeof(color_t)); // color_t* formatted = memoryAllocate(width * height * sizeof(color_t));
@@ -176,6 +120,13 @@ errorret_t textureInitDolphin(
} }
errorret_t textureBindDolphin(texturedolphin_t *texture) { errorret_t textureBindDolphin(texturedolphin_t *texture) {
if(texture == NULL) {
GX_SetNumChans(0);
errorOk();
}
GX_SetNumChans(1);
GX_LoadTexObj(&texture->texObj, GX_TEXMAP0);
errorOk(); errorOk();
} }
@@ -184,5 +135,71 @@ errorret_t textureDisposeDolphin(texturedolphin_t *texture) {
} }
void textureDolphinUploadTEV(void) { void textureDolphinUploadTEV(void) {
if(TEXTURE_BOUND == NULL) {
GX_SetNumChans(1);
GX_SetChanCtrl(
GX_COLOR0A0,
GX_DISABLE,
GX_SRC_REG,
GX_SRC_VTX,
GX_LIGHTNULL,
GX_DF_NONE,
GX_AF_NONE
);
GX_SetChanAmbColor(GX_COLOR0A0, (GXColor){0, 0, 0, 0});
GX_SetChanMatColor(GX_COLOR0A0, (GXColor){255, 255, 255, 255});
GX_SetNumTexGens(0);
GX_SetNumTevStages(1);
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORDNULL, GX_TEXMAP_NULL, GX_COLOR0A0);
GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
GX_SetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR);
GX_SetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
return;
}
// Add channel for vertex color
GX_SetNumChans(1);
GX_SetChanCtrl(
GX_COLOR0A0,// Store in color channel 0
GX_DISABLE,// Lighting disabled
GX_SRC_REG,// Ambient color?
GX_SRC_VTX,// Material color?
GX_LIGHTNULL,// Light Mask
GX_DF_NONE,// Diffuse function
GX_AF_NONE// Attenuation function
);
// One set of UVs
GX_SetNumTexGens(1);
GX_SetTexCoordGen(
GX_TEXCOORD0,
GX_TG_MTX2x4,
GX_TG_TEX0,
GX_IDENTITY
);
// Basically the shader setup
switch(TEXTURE_BOUND->format) {
case TEXTURE_FORMAT_RGBA:
// One TEV stage: vertex color * texture color
GX_SetNumTevStages(1);
GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);
GX_SetTevOrder(
GX_TEVSTAGE0,
GX_TEXCOORD0,
GX_TEXMAP0,
GX_COLOR0A0
);
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
GX_SetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
break;
default:
assertUnreachable("Unknown texture format in meshDraw");
break;
}
} }