Game no longer crashes on Dolphin

This commit is contained in:
2026-03-09 08:05:26 -05:00
parent 23eaffa3a7
commit c5f5b025a6
39 changed files with 1227 additions and 160 deletions

View File

@@ -0,0 +1,17 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
displaydolphin.c
# debug.c
)
# Subdirs
add_subdirectory(camera)
add_subdirectory(framebuffer)
add_subdirectory(mesh)
add_subdirectory(texture)

View File

@@ -0,0 +1,11 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
cameradolphin.c
)

View File

@@ -0,0 +1,107 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "display/camera/camera.h"
#include "display/framebuffer/framebuffer.h"
#include "assert/assert.h"
void cameraPushMatrixDolphin(camera_t *camera) {
assertNotNull(camera, "Camera cannot be null");
Mtx44 guProjection;
Mtx guView;
Mtx modelView;
switch(camera->projType) {
case CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC:
guOrtho(
guProjection,
camera->orthographic.top,
camera->orthographic.bottom,
camera->orthographic.left,
camera->orthographic.right,
camera->nearClip,
camera->farClip
);
break;
case CAMERA_PROJECTION_TYPE_PERSPECTIVE:
guPerspective(
guProjection,
// FOV is in degrees.
camera->perspective.fov * (180.0f / GLM_PIf),
(float_t)frameBufferGetWidth(FRAMEBUFFER_BOUND) /
(float_t)frameBufferGetHeight(FRAMEBUFFER_BOUND),
camera->nearClip,
camera->farClip
);
break;
case CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED:
assertUnreachable("Flipped perspective not implemented on Dolphin");
break;
default:
assertUnreachable("Invalid camera projection type");
}
switch(camera->viewType) {
case CAMERA_VIEW_TYPE_LOOKAT:
guVector eye = {
camera->lookat.position[0],
camera->lookat.position[1],
camera->lookat.position[2]
};
guVector up = {
camera->lookat.up[0],
camera->lookat.up[1],
camera->lookat.up[2]
};
guVector look = {
camera->lookat.target[0],
camera->lookat.target[1],
camera->lookat.target[2]
};
guLookAt(guView, &eye, &up, &look);
break;
case CAMERA_VIEW_TYPE_MATRIX:
assertUnreachable("Matrix camera not implemented");
break;
case CAMERA_VIEW_TYPE_LOOKAT_PIXEL_PERFECT:
assertUnreachable("Pixel perfect camera not implemented");
break;
case CAMERA_VIEW_TYPE_2D:
guMtxIdentity(guView);
guMtxTrans(guView, -camera->_2d.position[0], -camera->_2d.position[1], 0.0f);
guMtxScale(guView, camera->_2d.zoom, camera->_2d.zoom, 1.0f);
break;
default:
assertUnreachable("Invalid camera view type");
}
// Set Projection Matrix
GX_LoadProjectionMtx(
guProjection,
camera->projType == CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC ?
GX_ORTHOGRAPHIC :
GX_PERSPECTIVE
);
// Set view and model matrix. Dunno how I'll handle models but whatever.
guMtxIdentity(modelView);
guMtxTransApply(modelView, modelView, 0.0F, 0.0F, 0.0F);
guMtxConcat(guView,modelView,modelView);
GX_LoadPosMtxImm(modelView, GX_PNMTX0);
}
void cameraPopMatrixDolphin(void) {
}

View File

@@ -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 "dusk.h"
typedef struct camera_s camera_t;
/**
* Pushes the camera's transformation matrix onto the graphics stack.
*
* @param camera The camera to push the matrix of.
*/
void cameraPushMatrixDolphin(camera_t *camera);
/**
* Pops the camera's transformation matrix from the graphics stack.
*/
void cameraPopMatrixDolphin(void);

View File

@@ -0,0 +1,12 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "cameradolphin.h"
#define cameraPushMatrixPlatform cameraPushMatrixDolphin
#define cameraPopMatrixPlatform cameraPopMatrixDolphin

View File

@@ -0,0 +1,102 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "display/display.h"
#include "util/memory.h"
#include "engine/engine.h"
errorret_t displayInitDolphin(void) {
VIDEO_Init();
DISPLAY.screenMode = VIDEO_GetPreferredMode(NULL);
DISPLAY.frameBuffer[0] = MEM_K0_TO_K1(
SYS_AllocateFramebuffer(DISPLAY.screenMode)
);
DISPLAY.frameBuffer[1] = MEM_K0_TO_K1(
SYS_AllocateFramebuffer(DISPLAY.screenMode)
);
VIDEO_Configure(DISPLAY.screenMode);
VIDEO_SetNextFramebuffer(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer]);
// VIDEO_SetPostRetraceCallback(copy_buffers);
VIDEO_SetBlack(FALSE);
VIDEO_Flush();
VIDEO_WaitVSync();
if(DISPLAY.screenMode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
DISPLAY.fifoBuffer = memalign(32, DISPLAY_DOLPHIN_FIFO_SIZE);
memoryZero(DISPLAY.fifoBuffer, DISPLAY_DOLPHIN_FIFO_SIZE);
GX_Init(DISPLAY.fifoBuffer, DISPLAY_DOLPHIN_FIFO_SIZE);
// This seems to be mostly related to interlacing vs progressive
GX_SetViewport(
0, 0,
DISPLAY.screenMode->fbWidth, DISPLAY.screenMode->efbHeight,
0, 1
);
float_t yscale = GX_GetYScaleFactor(
DISPLAY.screenMode->efbHeight, DISPLAY.screenMode->xfbHeight
);
uint32_t xfbHeight = GX_SetDispCopyYScale(yscale);
GX_SetScissor(
0, 0,
DISPLAY.screenMode->fbWidth, DISPLAY.screenMode->efbHeight
);
GX_SetDispCopySrc(
0, 0,
DISPLAY.screenMode->fbWidth, DISPLAY.screenMode->efbHeight
);
GX_SetDispCopyDst(DISPLAY.screenMode->fbWidth, xfbHeight);
GX_SetCopyFilter(
DISPLAY.screenMode->aa,
DISPLAY.screenMode->sample_pattern,
GX_TRUE,
DISPLAY.screenMode->vfilter
);
GX_SetFieldMode(
DISPLAY.screenMode->field_rendering,
(
(DISPLAY.screenMode->viHeight == 2 * DISPLAY.screenMode->xfbHeight) ?
GX_ENABLE :
GX_DISABLE
)
);
// Setup cull modes
GX_SetCullMode(GX_CULL_NONE);
GX_SetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE);
GX_CopyDisp(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer], GX_TRUE);
GX_SetDispCopyGamma(GX_GM_1_0);
GX_ClearVtxDesc();
GX_SetVtxDesc(GX_VA_POS, GX_INDEX16);
GX_SetVtxDesc(GX_VA_CLR0, 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_CLR0, GX_CLR_RGBA, GX_U8, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
errorOk();
}
errorret_t displayUpdateDolphin(void) {
ENGINE.running = SYS_MainLoop();
}
errorret_t displaySwapDolphin(void) {
GX_DrawDone();
DISPLAY.whichFrameBuffer ^= 1;
GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
GX_SetColorUpdate(GX_TRUE);
GX_CopyDisp(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer], GX_TRUE);
VIDEO_SetNextFramebuffer(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer]);
VIDEO_Flush();
VIDEO_WaitVSync();
errorOk();
}

View File

@@ -0,0 +1,33 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "error/error.h"
#define DISPLAY_DOLPHIN_FIFO_SIZE (256*1024)
typedef struct {
void *frameBuffer[2];// Double-Bufferred
int whichFrameBuffer;
GXRModeObj *screenMode;
void *fifoBuffer;
} displaydolphin_t;
/**
* Initializes the display system on Dolphin.
*/
errorret_t displayInitDolphin(void);
/**
* Tells the display system to actually draw the frame on Dolphin.
*/
errorret_t displayUpdateDolphin(void);
/**
* Swaps the display buffers on Dolphin.
*/
errorret_t displaySwapDolphin(void);

View File

@@ -0,0 +1,15 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "displaydolphin.h"
#define displayPlatformInit displayInitDolphin
#define displayPlatformUpdate displayUpdateDolphin
#define displayPlatformSwap displaySwapDolphin
typedef displaydolphin_t displayplatform_t;

View File

@@ -0,0 +1,11 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
framebufferdolphin.c
)

View File

@@ -0,0 +1,54 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "display/framebuffer/framebuffer.h"
#include "display/display.h"
#include "assert/assert.h"
errorret_t frameBufferInitBackBufferDolphin(void) {
errorOk();
}
uint32_t frameBufferGetWidthDolphin(const framebufferdolphin_t *framebuffer) {
assertNotNull(framebuffer, "Cannot get width of NULL framebuffer.");
return DISPLAY.screenMode->fbWidth;
}
uint32_t frameBufferGetHeightDolphin(const framebufferdolphin_t *framebuffer) {
assertNotNull(framebuffer, "Cannot get height of NULL framebuffer.");
return DISPLAY.screenMode->efbHeight;
}
errorret_t frameBufferBindDolphin(framebufferdolphin_t *framebuffer) {
assertNotNull(framebuffer, "Cannot bind NULL framebuffer.");
assertTrue(
framebuffer == &FRAMEBUFFER_BACKBUFFER,
"Cannot bind framebuffer that is not the back buffer."
);
GX_InvVtxCache();
GX_InvalidateTexAll();
GX_SetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE);
GX_SetViewport(
0, 0,
frameBufferGetWidth(framebuffer),
frameBufferGetHeight(framebuffer),
0, 1
);
errorOk();
}
void frameBufferClearDolphin(const uint8_t flags, const color_t color) {
GX_SetCopyClear(
(GXColor){ color.r, color.g, color.b, color.a },
GX_MAX_Z24
);
}

View File

@@ -0,0 +1,55 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "display/color.h"
#include "error/error.h"
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC
#error "Dolphin does not support dynamic display sizes."
#endif
typedef struct {
uint8_t nothing;
} framebufferdolphin_t;
/**
* Initializes the backbuffer framebuffer. (Dolphin implementation).
*/
errorret_t frameBufferInitBackBufferDolphin(void);
/**
* Gets the height of the framebuffer. (Dolphin implementation).
*
* @param framebuffer The framebuffer to get the height of.
* @return The height of the framebuffer, or 0 if the framebuffer is NULL.
*/
uint32_t frameBufferGetWidthDolphin(const framebufferdolphin_t *framebuffer);
/**
* Gets the width of the framebuffer. (Dolphin implementation).
*
* @param framebuffer The framebuffer to get the width of.
* @return The width of the framebuffer, or 0 if the framebuffer is NULL.
*/
uint32_t frameBufferGetHeightDolphin(const framebufferdolphin_t *framebuffer);
/**
* Binds the framebuffer for rendering. (Dolphin implementation).
*
* @param framebuffer The framebuffer to bind.
* @return Either error or not.
*/
errorret_t frameBufferBindDolphin(framebufferdolphin_t *framebuffer);
/**
* Clears the framebuffer with the specified flags and color.
*
* @param flags The clear flags.
* @param color The clear color.
*/
void frameBufferClearDolphin(const uint8_t flags, const color_t color);

View File

@@ -0,0 +1,17 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "framebufferdolphin.h"
typedef framebufferdolphin_t framebufferplatform_t;
#define frameBufferPlatformInitBackBuffer frameBufferInitBackBufferDolphin
#define frameBufferPlatformGetWidth frameBufferGetWidthDolphin
#define frameBufferPlatformGetHeight frameBufferGetHeightDolphin
#define frameBufferPlatformBind frameBufferBindDolphin
#define frameBufferPlatformClear frameBufferClearDolphin

View File

@@ -0,0 +1,11 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
meshdolphin.c
)

View File

@@ -0,0 +1,73 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "display/mesh/mesh.h"
#include "display/texture/texture.h"
#include "assert/assert.h"
errorret_t meshInitDolphin(
meshdolphin_t *mesh,
const meshprimitivetypedolphin_t primitiveType,
const int32_t vertexCount,
const meshvertex_t *vertices
) {
assertNotNull(mesh, "Mesh cannot be null.");
assertNotNull(vertices, "Vertices cannot be null.");
assertTrue(vertexCount > 0, "Vertex count must be greater than 0.");
mesh->primitiveType = primitiveType;
mesh->vertexCount = vertexCount;
mesh->vertices = vertices;
errorOk();
}
errorret_t meshDrawDolphin(
const meshdolphin_t *mesh,
const int32_t vertexOffset,
const int32_t vertexCount
) {
assertNotNull(mesh, "Mesh cannot be NULL.");
assertTrue(vertexOffset >= 0, "Vertex offset must be >= 0");
assertTrue(vertexCount > 0, "Vertex count must be > 0");
assertTrue(
vertexOffset + vertexCount <= mesh->vertexCount,
"Requested vertex range is invalid"
);
// Prepare Vertex descriptor
DCFlushRange(
(void*)&mesh->vertices[vertexOffset],
sizeof(meshvertex_t) * vertexCount
);
const u8 stride = (u8)sizeof(meshvertex_t);
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_TEX0, (void*)&mesh->vertices[vertexOffset].uv[0], stride);
textureDolphinUploadTEV();
GX_Begin(mesh->primitiveType, GX_VTXFMT0, (uint16_t)vertexCount);
for(u16 i = 0; i < (u16)vertexCount; ++i) {
GX_Position1x16(i);
GX_Color1x16(i);
GX_TexCoord1x16(i);
}
GX_End();
errorOk();
}
int32_t meshGetVertexCountDolphin(const meshdolphin_t *mesh) {
assertNotNull(mesh, "Mesh cannot be NULL.");
return mesh->vertexCount;
}
errorret_t meshDisposeDolphin(meshdolphin_t *mesh) {
errorOk();
}

View File

@@ -0,0 +1,68 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "display/mesh/meshvertex.h"
#include "error/error.h"
typedef enum {
MESH_PRIMITIVE_TYPE_TRIANGLES = GX_TRIANGLES,
MESH_PRIMITIVE_TYPE_LINES = GX_LINES,
MESH_PRIMITIVE_TYPE_POINTS = GX_POINTS,
} meshprimitivetypedolphin_t;
typedef struct {
const meshvertex_t *vertices;
int32_t vertexCount;
meshprimitivetypedolphin_t primitiveType;
} meshdolphin_t;
/**
* Initializes a mesh.
*
* @param mesh The mesh to initialize.
* @param primitiveType The Dolphin primitive type (e.g., GX_TRIANGLES).
* @param vertexCount The number of vertices in the mesh.
* @param vertices The vertex data for the mesh.
* @return An error indicating success or failure.
*/
errorret_t meshInitDolphin(
meshdolphin_t *mesh,
const meshprimitivetypedolphin_t primitiveType,
const int32_t vertexCount,
const meshvertex_t *vertices
);
/**
* Draws a mesh.
*
* @param mesh The mesh to draw.
* @param vertexOffset The offset in the vertex array to start drawing from.
* @param vertexCount The number of vertices to draw. If -1, draws all vertices.
* @return An error indicating success or failure.
*/
errorret_t meshDrawDolphin(
const meshdolphin_t *mesh,
const int32_t vertexOffset,
const int32_t vertexCount
);
/**
* Gets the vertex count of a mesh.
*
* @param mesh The mesh to get the vertex count from.
* @return The vertex count of the mesh.
*/
int32_t meshGetVertexCountDolphin(const meshdolphin_t *mesh);
/**
* Disposes of a mesh, freeing any associated resources.
*
* @param mesh The mesh to dispose of.
* @return An error indicating success or failure.
*/
errorret_t meshDisposeDolphin(meshdolphin_t *mesh);

View File

@@ -0,0 +1,16 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "meshdolphin.h"
#define meshInitPlatform meshInitDolphin
#define meshDrawPlatform meshDrawDolphin
#define meshGetVertexCountPlatform meshGetVertexCountDolphin
#define meshDisposePlatform meshDisposeDolphin
typedef meshprimitivetypedolphin_t meshprimitivetypeplatform_t;
typedef meshdolphin_t meshplatform_t;

View File

@@ -0,0 +1,11 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
texturedolphin.c
)

View File

@@ -0,0 +1,188 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "display/texture/texture.h"
#include "assert/assert.h"
errorret_t textureInitDolphin(
texturedolphin_t *texture,
const int32_t width,
const int32_t height,
const textureformatdolphin_t format,
const texturedata_t data
) {
// switch(format) {
// case TEXTURE_FORMAT_RGBA:
// assertTrue(
// (width % 4) == 0 && (height % 4) == 0,
// "RGB5A3 requires w/h multiple of 4 (or pad)"
// );
// // Convert to RGB5A3 format
// size_t rgbaSize = width * height * sizeof(u16);
// texture->rgba = (u16*)memalign(32, rgbaSize);
// assertNotNull(texture->rgba, "Failed to allocate texture RGBA data");
// for(uint32_t y = 0; y < height; ++y) {
// for(uint32_t x = 0; x < width; ++x) {
// const int src = y * width + x;
// const int tileX = x >> 2;
// const int tileY = y >> 2;
// const int tilesPerRow = width >> 2;
// const int tileIndex = tileY * tilesPerRow + tileX;
// const int tileBaseWords = tileIndex * 16;
// const int inTile = ((y & 3) << 2) + (x & 3);
// const int dest = tileBaseWords + inTile;
// color4b_t col = data.rgba.colors[src];
// u16 outCol;
// if(col.a < 255) {
// // 0AAA RRRR GGGG BBBB
// outCol = (
// (0u << 15) |
// ((u16)(col.a >> 5) << 12) |
// ((u16)(col.r >> 4) << 8) |
// ((u16)(col.g >> 4) << 4) |
// ((u16)(col.b >> 4) << 0)
// );
// } else {
// // 1RRRR RRGG GGGB BBBB
// outCol = (
// (1u << 15) |
// ((u16)(col.r >> 3) << 10) |
// ((u16)(col.g >> 3) << 5) |
// ((u16)(col.b >> 3) << 0)
// );
// }
// texture->rgba[dest] = outCol;
// }
// }
// DCFlushRange(texture->rgba, rgbaSize);
// GX_InitTexObj(
// &texture->texObj,
// texture->rgba,
// width, height,
// GX_TF_RGB5A3,
// GX_REPEAT, GX_REPEAT,
// GX_FALSE
// );
// DCFlushRange(texture->rgba, rgbaSize);
// GX_InvalidateTexAll();
// 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_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: {
// // Not supported, convert to RGBA using lookup
// color_t* formatted = memoryAllocate(width * height * sizeof(color_t));
// for(int32_t i = 0; i < width * height; i++) {
// uint8_t index = data.palette.data[i];
// assertTrue(
// index < data.palette.palette->colorCount,
// "Palette index out of range"
// );
// formatted[i] = data.palette.palette->colors[index];
// }
// textureInit(
// texture, width, height, TEXTURE_FORMAT_RGBA,
// (texturedata_t){
// .rgba = { .colors = formatted }
// }
// );
// memoryFree(formatted);
// break;
// }
// default:
// assertUnreachable("Unsupported texture format for Dolphin");
// break;
// }
// texture->ready = true;
errorOk();
}
errorret_t textureBindDolphin(texturedolphin_t *texture) {
errorOk();
}
errorret_t textureDisposeDolphin(texturedolphin_t *texture) {
errorOk();
}
void textureDolphinUploadTEV(void) {
}

View File

@@ -0,0 +1,63 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
typedef union texturedata_u texturedata_t;
typedef enum {
TEXTURE_FORMAT_RGBA = GX_TF_RGBA8,
TEXTURE_FORMAT_PALETTE = GX_TF_CI8,
} textureformatdolphin_t;
typedef struct {
GXTexObj texObj;
textureformatdolphin_t format;
int32_t width;
int32_t height;
} texturedolphin_t;
/**
* Initializes a texture.
*
* @param texture The texture to initialize.
* @param width The width of the texture.
* @param height The height of the texture.
* @param format The format of the texture (e.g., GX_TF_RGBA8, GX_TF_CI8).
* @param data The data for the texture, the format changes per format.
* @return An error if the texture failed to initialize, otherwise success.
*/
errorret_t textureInitDolphin(
texturedolphin_t *texture,
const int32_t width,
const int32_t height,
const textureformatdolphin_t format,
const texturedata_t data
);
/**
* Binds a texture for rendering. Providing NULL will unbind any texture.
*
* @param texture The texture to bind.
* @return An error if the texture failed to bind, otherwise success.
*/
errorret_t textureBindDolphin(texturedolphin_t *texture);
/**
* Disposes a texture.
*
* @param texture The texture to dispose.
* @return An error if the texture failed to dispose, otherwise success.
*/
errorret_t textureDisposeDolphin(texturedolphin_t *texture);
/**
* Internal method that uploads the texture environment variables to the GPU
* for rendering. This is basically uploading the shader information.
*/
void textureDolphinUploadTEV(void);

View File

@@ -0,0 +1,16 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "texturedolphin.h"
typedef textureformatdolphin_t textureformatplatform_t;
typedef texturedolphin_t textureplatform_t;
#define textureInitPlatform textureInitDolphin
#define textureBindPlatform textureBindDolphin
#define textureDisposePlatform textureDisposeDolphin