Renders on Dolphin also.
This commit is contained in:
@@ -15,7 +15,7 @@ CELL_STATE_HOVER = 1
|
||||
CELL_STATE_DOWN = 2
|
||||
CELL_STATE_DISABLED = 3
|
||||
|
||||
screenSetBackground(colorBlack())
|
||||
screenSetBackground(colorCornflowerBlue())
|
||||
camera = cameraCreate(CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC)
|
||||
|
||||
-- tilesetUi = tilesetGetByName("ui")
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# Target definitions
|
||||
target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC
|
||||
DUSK_PLATFORM_ENDIAN_BIG
|
||||
DUSK_DOLPHIN
|
||||
DUSK_DISPLAY_WIDTH=640
|
||||
DUSK_DISPLAY_HEIGHT=480
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "mesh.h"
|
||||
#include "util/memory.h"
|
||||
#include "assert/assert.h"
|
||||
#include "debug/debug.h"
|
||||
|
||||
errorret_t meshInit(
|
||||
mesh_t *mesh,
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "display/mesh/quad.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)
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ typedef struct {
|
||||
} spritebatch_t;
|
||||
|
||||
// Have to define these seperately because of alignment in certain platforms.
|
||||
// (Looking at you Dolphin)
|
||||
extern meshvertex_t SPRITEBATCH_VERTICES[SPRITEBATCH_VERTEX_COUNT];
|
||||
extern spritebatch_t SPRITEBATCH;
|
||||
|
||||
|
||||
@@ -12,20 +12,25 @@
|
||||
static char_t DEBUG_ERROR_BUFFER[16*1024] = {0};
|
||||
|
||||
void debugPrint(const char_t *message, ...) {
|
||||
// append to error buffer
|
||||
size_t start = strlen(DEBUG_ERROR_BUFFER);
|
||||
|
||||
va_list args;
|
||||
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(
|
||||
DEBUG_ERROR_BUFFER + start,
|
||||
sizeof(DEBUG_ERROR_BUFFER) - start,
|
||||
message,
|
||||
args
|
||||
);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,15 @@ errorret_t displayInitDolphin(void) {
|
||||
DISPLAY.frameBuffer[0] = MEM_K0_TO_K1(
|
||||
SYS_AllocateFramebuffer(DISPLAY.screenMode)
|
||||
);
|
||||
if(DISPLAY.frameBuffer[0] == NULL) {
|
||||
errorThrow("Failed to allocate framebuffer");
|
||||
}
|
||||
DISPLAY.frameBuffer[1] = MEM_K0_TO_K1(
|
||||
SYS_AllocateFramebuffer(DISPLAY.screenMode)
|
||||
);
|
||||
if(DISPLAY.frameBuffer[1] == NULL) {
|
||||
errorThrow("Failed to allocate framebuffer");
|
||||
}
|
||||
VIDEO_Configure(DISPLAY.screenMode);
|
||||
|
||||
VIDEO_SetNextFramebuffer(DISPLAY.frameBuffer[DISPLAY.whichFrameBuffer]);
|
||||
@@ -28,6 +34,9 @@ errorret_t displayInitDolphin(void) {
|
||||
if(DISPLAY.screenMode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
|
||||
|
||||
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);
|
||||
|
||||
GX_Init(DISPLAY.fifoBuffer, DISPLAY_DOLPHIN_FIFO_SIZE);
|
||||
@@ -69,15 +78,16 @@ errorret_t displayInitDolphin(void) {
|
||||
// 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_SetColorUpdate(GX_TRUE);
|
||||
|
||||
// Describe mesh vertex format.
|
||||
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_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
||||
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
|
||||
|
||||
errorOk();
|
||||
@@ -85,14 +95,15 @@ errorret_t displayInitDolphin(void) {
|
||||
|
||||
errorret_t displayUpdateDolphin(void) {
|
||||
ENGINE.running = SYS_MainLoop();
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t displaySwapDolphin(void) {
|
||||
GX_DrawDone();
|
||||
|
||||
DISPLAY.whichFrameBuffer ^= 1;
|
||||
GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
|
||||
GX_SetColorUpdate(GX_TRUE);
|
||||
// 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();
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "display/mesh/mesh.h"
|
||||
#include "display/texture/texture.h"
|
||||
#include "assert/assert.h"
|
||||
#include "debug/debug.h"
|
||||
|
||||
errorret_t meshInitDolphin(
|
||||
meshdolphin_t *mesh,
|
||||
@@ -38,22 +39,28 @@ errorret_t meshDrawDolphin(
|
||||
vertexOffset + vertexCount <= mesh->vertexCount,
|
||||
"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(
|
||||
(void*)&mesh->vertices[vertexOffset],
|
||||
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_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);
|
||||
|
||||
textureDolphinUploadTEV();
|
||||
|
||||
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_Color1x16(i);
|
||||
GX_TexCoord1x16(i);
|
||||
|
||||
@@ -87,62 +87,6 @@ errorret_t textureInitDolphin(
|
||||
// );
|
||||
// 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));
|
||||
@@ -176,6 +120,13 @@ errorret_t textureInitDolphin(
|
||||
}
|
||||
|
||||
errorret_t textureBindDolphin(texturedolphin_t *texture) {
|
||||
if(texture == NULL) {
|
||||
GX_SetNumChans(0);
|
||||
errorOk();
|
||||
}
|
||||
|
||||
GX_SetNumChans(1);
|
||||
GX_LoadTexObj(&texture->texObj, GX_TEXMAP0);
|
||||
errorOk();
|
||||
}
|
||||
|
||||
@@ -184,5 +135,71 @@ errorret_t textureDisposeDolphin(texturedolphin_t *texture) {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user