Need a break from Dolphin
All checks were successful
Build Dusk / run-tests (push) Successful in 1m36s
Build Dusk / build-linux (push) Successful in 1m14s
Build Dusk / build-psp (push) Successful in 2m2s
Build Dusk / build-dolphin (push) Successful in 2m49s

This commit is contained in:
2026-02-09 22:18:44 -06:00
parent 073ee8dca9
commit e1f08b07aa
11 changed files with 92 additions and 82 deletions

View File

@@ -3,11 +3,11 @@ docker build -t myapp:latest -f .ci/dolphin/Dockerfile .
docker run -it -v ./:/workdir myapp:latest /bin/bash -c ' \ docker run -it -v ./:/workdir myapp:latest /bin/bash -c ' \
export PATH="$DEVKITPPC/bin:$PATH" && \ export PATH="$DEVKITPPC/bin:$PATH" && \
cd /workdir && \ cd /workdir && \
rm -rf build2 && \ rm -rf build-gamecube && \
mkdir -p build2 && \ mkdir -p build-gamecube && \
# cmake -S. -Bbuild2 -DDUSK_TARGET_SYSTEM=gamecube -DCMAKE_TOOLCHAIN_FILE="$DEVKITPRO/cmake/GameCube.cmake" && \ # cmake -S. -Bbuild-gamecube -DDUSK_TARGET_SYSTEM=gamecube -DCMAKE_TOOLCHAIN_FILE="$DEVKITPRO/cmake/GameCube.cmake" && \
cmake -S. -Bbuild2 -DDUSK_TARGET_SYSTEM=wii -DCMAKE_TOOLCHAIN_FILE="$DEVKITPRO/cmake/Wii.cmake" && \ cmake -S. -Bbuild-gamecube -DDUSK_TARGET_SYSTEM=wii -DCMAKE_TOOLCHAIN_FILE="$DEVKITPRO/cmake/Wii.cmake" && \
cd build2 && \ cd build-gamecube && \
make -j$(nproc) VERBOSE=1 && \ make -j$(nproc) VERBOSE=1 && \
cp ./Dusk.dol ./boot.dol cp ./Dusk.dol ./boot.dol
' '

View File

@@ -24,10 +24,11 @@ textureGrid = textureLoad("minesweeper/grid_bg.dpi")
tilesetCell = tilesetGetByName("cell") tilesetCell = tilesetGetByName("cell")
textureCell = textureLoad(tilesetCell.texture) textureCell = textureLoad(tilesetCell.texture)
cellSliceHover = tilesetPositionGetUV(tilesetCell, 3, 4) -- cellSliceDefault = tilesetPositionGetUV(tilesetCell, 3, 5)
cellSliceDefault = tilesetPositionGetUV(tilesetCell, 3, 5) cellSliceDefault = tilesetPositionGetUV(tilesetCell, 0, 4)
cellSliceDown = tilesetPositionGetUV(tilesetCell, 3, 6) -- cellSliceHover = tilesetPositionGetUV(tilesetCell, 3, 4)
cellSliceDisabled = tilesetPositionGetUV(tilesetCell, 3, 7) -- cellSliceDown = tilesetPositionGetUV(tilesetCell, 3, 6)
-- cellSliceDisabled = tilesetPositionGetUV(tilesetCell, 3, 7)
width = 10 width = 10
height = 14 height = 14
@@ -42,15 +43,7 @@ for y = 1, height do
end end
function cellDraw(x, y, type) function cellDraw(x, y, type)
if type == CELL_STATE_HOVER then slice = cellSliceDefault
slice = cellSliceHover
elseif type == CELL_STATE_DOWN then
slice = cellSliceDown
elseif type == CELL_STATE_DISABLED then
slice = cellSliceDisabled
else
slice = cellSliceDefault
end
spriteBatchPush(textureCell, spriteBatchPush(textureCell,
x, y, x, y,
@@ -90,21 +83,22 @@ function sceneRender()
cameraPushMatrix(camera) cameraPushMatrix(camera)
camera.bottom = screenGetHeight() camera.bottom = screenGetHeight()
camera.right = screenGetWidth() camera.right = screenGetWidth()
cellDraw(0, 0, 0)
backgroundDraw() -- backgroundDraw()
offsetX = 32 -- offsetX = 32
offsetY = 32 -- offsetY = 32
for y = 0, height - 1 do -- for y = 0, height - 1 do
for x = 0, width - 1 do -- for x = 0, width - 1 do
cellDraw( -- cellDraw(
x * tilesetCell.tileWidth + offsetX, -- x * tilesetCell.tileWidth + offsetX,
y * tilesetCell.tileHeight + offsetY, -- y * tilesetCell.tileHeight + offsetY,
cells[i] -- cells[i]
) -- )
break -- end
end -- end
end
spriteBatchFlush() spriteBatchFlush()
cameraPopMatrix() cameraPopMatrix()

View File

@@ -147,7 +147,7 @@ errorret_t displayInit(void) {
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_RGBA8, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_U8, 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);
#endif #endif
@@ -191,9 +191,6 @@ errorret_t displayUpdate(void) {
SDL_GL_MakeCurrent(DISPLAY.window, DISPLAY.glContext); SDL_GL_MakeCurrent(DISPLAY.window, DISPLAY.glContext);
#elif DOLPHIN
#endif #endif
// Reset state // Reset state
@@ -206,6 +203,7 @@ errorret_t displayUpdate(void) {
FRAMEBUFFER_CLEAR_COLOR | FRAMEBUFFER_CLEAR_DEPTH, FRAMEBUFFER_CLEAR_COLOR | FRAMEBUFFER_CLEAR_DEPTH,
SCREEN.background SCREEN.background
); );
errorChain(sceneRender()); errorChain(sceneRender());
// Render UI // Render UI

View File

@@ -132,6 +132,7 @@ void frameBufferBind(const framebuffer_t *framebuffer) {
#elif DOLPHIN #elif DOLPHIN
GX_InvVtxCache(); GX_InvVtxCache();
GX_InvalidateTexAll(); GX_InvalidateTexAll();
GX_SetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE);
GX_SetViewport( GX_SetViewport(
0, 0, 0, 0,

View File

@@ -24,8 +24,8 @@ typedef enum {
typedef struct { typedef struct {
color_t color; color_t color;
float uv[MESH_VERTEX_UV_SIZE]; float_t uv[MESH_VERTEX_UV_SIZE];
float pos[MESH_VERTEX_POS_SIZE]; float_t pos[MESH_VERTEX_POS_SIZE];
} meshvertex_t; } meshvertex_t;
typedef struct { typedef struct {

View File

@@ -7,6 +7,7 @@
#include "quad.h" #include "quad.h"
#include "assert/assert.h" #include "assert/assert.h"
#include "debug/debug.h"
mesh_t QUAD_MESH_SIMPLE; mesh_t QUAD_MESH_SIMPLE;
meshvertex_t QUAD_MESH_SIMPLE_VERTICES[QUAD_VERTEX_COUNT] = { meshvertex_t QUAD_MESH_SIMPLE_VERTICES[QUAD_VERTEX_COUNT] = {
@@ -51,13 +52,6 @@ void quadBuffer(
vertices[0].pos[1] = maxY; vertices[0].pos[1] = maxY;
vertices[0].pos[2] = z; vertices[0].pos[2] = z;
vertices[2].color = color;
vertices[2].uv[0] = u0;
vertices[2].uv[1] = v0;
vertices[2].pos[0] = minX;
vertices[2].pos[1] = minY;
vertices[2].pos[2] = z;
vertices[1].color = color; vertices[1].color = color;
vertices[1].uv[0] = u1; vertices[1].uv[0] = u1;
vertices[1].uv[1] = v0; vertices[1].uv[1] = v0;
@@ -65,6 +59,13 @@ void quadBuffer(
vertices[1].pos[1] = minY; vertices[1].pos[1] = minY;
vertices[1].pos[2] = z; vertices[1].pos[2] = z;
vertices[2].color = color;
vertices[2].uv[0] = u0;
vertices[2].uv[1] = v0;
vertices[2].pos[0] = minX;
vertices[2].pos[1] = minY;
vertices[2].pos[2] = z;
// Second triangle // Second triangle
vertices[3].color = color; vertices[3].color = color;
vertices[3].uv[0] = u0; vertices[3].uv[0] = u0;
@@ -73,19 +74,19 @@ void quadBuffer(
vertices[3].pos[1] = maxY; vertices[3].pos[1] = maxY;
vertices[3].pos[2] = z; vertices[3].pos[2] = z;
vertices[5].color = color;
vertices[5].uv[0] = u1;
vertices[5].uv[1] = v0;
vertices[5].pos[0] = maxX;
vertices[5].pos[1] = minY;
vertices[5].pos[2] = z;
vertices[4].color = color; vertices[4].color = color;
vertices[4].uv[0] = u1; vertices[4].uv[0] = u1;
vertices[4].uv[1] = v1; vertices[4].uv[1] = v1;
vertices[4].pos[0] = maxX; vertices[4].pos[0] = maxX;
vertices[4].pos[1] = maxY; vertices[4].pos[1] = maxY;
vertices[4].pos[2] = z; vertices[4].pos[2] = z;
vertices[5].color = color;
vertices[5].uv[0] = u1;
vertices[5].uv[1] = v0;
vertices[5].pos[0] = maxX;
vertices[5].pos[1] = minY;
vertices[5].pos[2] = z;
} }
void quadBuffer3D( void quadBuffer3D(
@@ -145,4 +146,6 @@ void quadBuffer3D(
vertices[5].pos[0] = min[0]; vertices[5].pos[0] = min[0];
vertices[5].pos[1] = max[1]; vertices[5].pos[1] = max[1];
vertices[5].pos[2] = min[2]; vertices[5].pos[2] = min[2];
printf("UVS: (%f, %f), (%f, %f)\n", uvMin[0], uvMin[1], uvMax[0], uvMax[1]);
} }

View File

@@ -15,9 +15,6 @@ spritebatch_t SPRITEBATCH;
void spriteBatchInit() { void spriteBatchInit() {
memoryZero(&SPRITEBATCH, sizeof(spritebatch_t)); memoryZero(&SPRITEBATCH, sizeof(spritebatch_t));
SPRITEBATCH.spriteCount = 0;
SPRITEBATCH.currentTexture = NULL;
meshInit( meshInit(
&SPRITEBATCH.mesh, &SPRITEBATCH.mesh,
MESH_PRIMITIVE_TRIANGLES, MESH_PRIMITIVE_TRIANGLES,
@@ -38,23 +35,14 @@ void spriteBatchPush(
const float_t u1, const float_t u1,
const float_t v1 const float_t v1
) { ) {
// Need to flush? return spriteBatchPush3D(
if( texture,
SPRITEBATCH.currentTexture != texture || (vec3){ minX, minY, 0 },
SPRITEBATCH.spriteCount >= SPRITEBATCH_SPRITES_MAX (vec3){ maxX, maxY, 0 },
) {
spriteBatchFlush();
SPRITEBATCH.currentTexture = texture;
}
quadBuffer(
&SPRITEBATCH_VERTICES[SPRITEBATCH.spriteCount * QUAD_VERTEX_COUNT],
minX, minY, maxX, maxY,
color, color,
u0, v0, u1, v1 (vec2){ u0, v0 },
(vec2){ u1, v1 }
); );
SPRITEBATCH.spriteCount++;
} }
void spriteBatchPush3D( void spriteBatchPush3D(
@@ -74,8 +62,15 @@ void spriteBatchPush3D(
SPRITEBATCH.currentTexture = texture; SPRITEBATCH.currentTexture = texture;
} }
size_t vertexOffset = SPRITEBATCH.spriteCount * QUAD_VERTEX_COUNT;
#if DOLPHIN
vertexOffset += (
SPRITEBATCH.batchIndex * SPRITEBATCH_SPRITES_MAX * QUAD_VERTEX_COUNT
);
#endif
quadBuffer3D( quadBuffer3D(
&SPRITEBATCH_VERTICES[SPRITEBATCH.spriteCount * QUAD_VERTEX_COUNT], &SPRITEBATCH_VERTICES[vertexOffset],
min, max, color, uv0, uv1 min, max, color, uv0, uv1
); );
SPRITEBATCH.spriteCount++; SPRITEBATCH.spriteCount++;
@@ -89,7 +84,19 @@ void spriteBatchClear() {
void spriteBatchFlush() { void spriteBatchFlush() {
if(SPRITEBATCH.spriteCount == 0) return; if(SPRITEBATCH.spriteCount == 0) return;
textureBind(SPRITEBATCH.currentTexture); textureBind(SPRITEBATCH.currentTexture);
meshDraw(&SPRITEBATCH.mesh, 0, QUAD_VERTEX_COUNT * SPRITEBATCH.spriteCount);
#if DOLPHIN
meshDraw(
&SPRITEBATCH.mesh,
QUAD_VERTEX_COUNT * SPRITEBATCH.batchIndex * SPRITEBATCH_SPRITES_MAX,
QUAD_VERTEX_COUNT * SPRITEBATCH.spriteCount
);
SPRITEBATCH.batchIndex = (
(SPRITEBATCH.batchIndex + 1) % SPRITEBATCH_BATCH_COUNT
);
#else
meshDraw(&SPRITEBATCH.mesh, 0, QUAD_VERTEX_COUNT * SPRITEBATCH.spriteCount);
#endif
spriteBatchClear(); spriteBatchClear();
} }

View File

@@ -12,11 +12,20 @@
#define SPRITEBATCH_SPRITES_MAX 128 #define SPRITEBATCH_SPRITES_MAX 128
#define SPRITEBATCH_VERTEX_COUNT (SPRITEBATCH_SPRITES_MAX * QUAD_VERTEX_COUNT) #define SPRITEBATCH_VERTEX_COUNT (SPRITEBATCH_SPRITES_MAX * QUAD_VERTEX_COUNT)
#if DOLPHIN
#define SPRITEBATCH_SPRITES_MAX 16
#define SPRITEBATCH_BATCH_COUNT 16
#define SPRITEBATCH_VERTEX_COUNT (SPRITEBATCH_SPRITES_MAX * QUAD_VERTEX_COUNT * SPRITEBATCH_BATCH_COUNT)
#endif
typedef struct { typedef struct {
mesh_t mesh; mesh_t mesh;
int32_t spriteCount; int32_t spriteCount;
texture_t *currentTexture; texture_t *currentTexture;
#if DOLPHIN
uint8_t batchIndex;
#endif
} 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.

View File

@@ -346,16 +346,14 @@ void textureInit(
#endif #endif
} }
#if DOLPHIN
static uint8_t dolphinTextureNextSlot = 0;
#endif
void textureBind(texture_t *texture) { void textureBind(texture_t *texture) {
if(TEXTURE_BOUND == texture) return; if(TEXTURE_BOUND == texture) return;
if(texture == NULL) { if(texture == NULL) {
#if DISPLAY_SDL2 #if DISPLAY_SDL2
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
#elif DOLPHIN
GX_SetNumChans(0);
#endif #endif
TEXTURE_BOUND = NULL; TEXTURE_BOUND = NULL;
return; return;
@@ -372,9 +370,8 @@ void textureBind(texture_t *texture) {
glBindTexture(GL_TEXTURE_2D, texture->id); glBindTexture(GL_TEXTURE_2D, texture->id);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
#elif DOLPHIN #elif DOLPHIN
GX_InvalidateTexAll(); GX_SetNumChans(1);
GX_LoadTexObj(&TEXTURE_BOUND->texObj, GX_TEXMAP0 + dolphinTextureNextSlot); GX_LoadTexObj(&texture->texObj, GX_TEXMAP0);
dolphinTextureNextSlot = (dolphinTextureNextSlot + 1) % GX_MAX_TEXMAP;
#endif #endif
TEXTURE_BOUND = texture; TEXTURE_BOUND = texture;
} }
@@ -442,13 +439,13 @@ void textureDispose(texture_t *texture) {
case TEXTURE_FORMAT_RGBA: case TEXTURE_FORMAT_RGBA:
// One TEV stage: vertex color * texture color // One TEV stage: vertex color * texture color
GX_SetNumTevStages(1); GX_SetNumTevStages(1);
GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);
GX_SetTevOrder( GX_SetTevOrder(
GX_TEVSTAGE0, GX_TEVSTAGE0,
GX_TEXCOORD0, GX_TEXCOORD0,
GX_TEXMAP0, GX_TEXMAP0,
GX_COLOR0A0 GX_COLOR0A0
); );
GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); 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); GX_SetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
break; break;

View File

@@ -30,8 +30,8 @@ void tilesetPositionGetUV(
assertTrue(column < tileset->columns, "Column index out of bounds"); assertTrue(column < tileset->columns, "Column index out of bounds");
assertTrue(row < tileset->rows, "Row index out of bounds"); assertTrue(row < tileset->rows, "Row index out of bounds");
outUV[0] = column * tileset->uv[0]; outUV[0] = ((float_t)column) * tileset->uv[0];
outUV[1] = row * tileset->uv[1]; outUV[1] = ((float_t)row) * tileset->uv[1];
outUV[2] = outUV[0] + tileset->uv[0]; outUV[2] = outUV[0] + tileset->uv[0];
outUV[3] = outUV[1] + tileset->uv[1]; outUV[3] = outUV[1] + tileset->uv[1];
} }

View File

@@ -10,6 +10,7 @@
#include "display/tileset/tileset.h" #include "display/tileset/tileset.h"
#include "util/memory.h" #include "util/memory.h"
#include "util/string.h" #include "util/string.h"
#include "debug/debug.h"
void moduleTileset(scriptcontext_t *ctx) { void moduleTileset(scriptcontext_t *ctx) {
assertNotNull(ctx, "Script context cannot be NULL"); assertNotNull(ctx, "Script context cannot be NULL");
@@ -152,7 +153,7 @@ int moduleTilesetPositionGetUV(lua_State *l) {
return 0; return 0;
} }
uint16_t row = (uint16_t)lua_tonumber(l, 3); uint16_t row = (uint16_t)lua_tonumber(l, 3);
// Create vec4 that lua owns // Create vec4 that lua owns
vec4 *uv = (vec4 *)lua_newuserdata(l, sizeof(vec4)); vec4 *uv = (vec4 *)lua_newuserdata(l, sizeof(vec4));
tilesetPositionGetUV(ts, column, row, *uv); tilesetPositionGetUV(ts, column, row, *uv);