Game no longer crashes on Dolphin
This commit is contained in:
17
src/duskdolphin/display/CMakeLists.txt
Normal file
17
src/duskdolphin/display/CMakeLists.txt
Normal 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)
|
||||
11
src/duskdolphin/display/camera/CMakeLists.txt
Normal file
11
src/duskdolphin/display/camera/CMakeLists.txt
Normal 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
|
||||
)
|
||||
107
src/duskdolphin/display/camera/cameradolphin.c
Normal file
107
src/duskdolphin/display/camera/cameradolphin.c
Normal 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) {
|
||||
|
||||
}
|
||||
23
src/duskdolphin/display/camera/cameradolphin.h
Normal file
23
src/duskdolphin/display/camera/cameradolphin.h
Normal 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);
|
||||
12
src/duskdolphin/display/camera/cameraplatform.h
Normal file
12
src/duskdolphin/display/camera/cameraplatform.h
Normal 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
|
||||
102
src/duskdolphin/display/displaydolphin.c
Normal file
102
src/duskdolphin/display/displaydolphin.c
Normal 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();
|
||||
}
|
||||
33
src/duskdolphin/display/displaydolphin.h
Normal file
33
src/duskdolphin/display/displaydolphin.h
Normal 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);
|
||||
15
src/duskdolphin/display/displayplatform.h
Normal file
15
src/duskdolphin/display/displayplatform.h
Normal 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;
|
||||
11
src/duskdolphin/display/framebuffer/CMakeLists.txt
Normal file
11
src/duskdolphin/display/framebuffer/CMakeLists.txt
Normal 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
|
||||
)
|
||||
54
src/duskdolphin/display/framebuffer/framebufferdolphin.c
Normal file
54
src/duskdolphin/display/framebuffer/framebufferdolphin.c
Normal 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
|
||||
);
|
||||
}
|
||||
55
src/duskdolphin/display/framebuffer/framebufferdolphin.h
Normal file
55
src/duskdolphin/display/framebuffer/framebufferdolphin.h
Normal 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);
|
||||
17
src/duskdolphin/display/framebuffer/framebufferplatform.h
Normal file
17
src/duskdolphin/display/framebuffer/framebufferplatform.h
Normal 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
|
||||
11
src/duskdolphin/display/mesh/CMakeLists.txt
Normal file
11
src/duskdolphin/display/mesh/CMakeLists.txt
Normal 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
|
||||
)
|
||||
73
src/duskdolphin/display/mesh/meshdolphin.c
Normal file
73
src/duskdolphin/display/mesh/meshdolphin.c
Normal 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();
|
||||
}
|
||||
68
src/duskdolphin/display/mesh/meshdolphin.h
Normal file
68
src/duskdolphin/display/mesh/meshdolphin.h
Normal 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);
|
||||
16
src/duskdolphin/display/mesh/meshplatform.h
Normal file
16
src/duskdolphin/display/mesh/meshplatform.h
Normal 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;
|
||||
11
src/duskdolphin/display/texture/CMakeLists.txt
Normal file
11
src/duskdolphin/display/texture/CMakeLists.txt
Normal 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
|
||||
)
|
||||
188
src/duskdolphin/display/texture/texturedolphin.c
Normal file
188
src/duskdolphin/display/texture/texturedolphin.c
Normal 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) {
|
||||
|
||||
}
|
||||
63
src/duskdolphin/display/texture/texturedolphin.h
Normal file
63
src/duskdolphin/display/texture/texturedolphin.h
Normal 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);
|
||||
16
src/duskdolphin/display/texture/textureplatform.h
Normal file
16
src/duskdolphin/display/texture/textureplatform.h
Normal 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
|
||||
Reference in New Issue
Block a user