diff --git a/.ci/dolphin/build.sh b/.ci/dolphin/build.sh index 3f6498a..feaf4de 100755 --- a/.ci/dolphin/build.sh +++ b/.ci/dolphin/build.sh @@ -5,8 +5,10 @@ docker run -it -v ./:/workdir myapp:latest /bin/bash -c ' \ cd /workdir && \ rm -rf build2 && \ mkdir -p build2 && \ - cmake -S. -Bbuild2 -DDUSK_TARGET_SYSTEM=gamecube -DCMAKE_TOOLCHAIN_FILE="$DEVKITPRO/cmake/GameCube.cmake" && \ + # cmake -S. -Bbuild2 -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" && \ cd build2 && \ - make VERBOSE=1 \ + make VERBOSE=1 && \ + cp ./Dusk.dol ./boot.dol ' # docker run -it -v ./:/workdir myapp:latest /bin/bash \ No newline at end of file diff --git a/assets/init.lua b/assets/init.lua index 46a3d5e..d5254b6 100644 --- a/assets/init.lua +++ b/assets/init.lua @@ -16,6 +16,21 @@ if PLATFORM == "psp" then inputBind("lstick_down", INPUT_ACTION_DOWN) inputBind("lstick_left", INPUT_ACTION_LEFT) inputBind("lstick_right", INPUT_ACTION_RIGHT) + +elseif PLATFORM == "gamecube" then + inputBind("start", INPUT_ACTION_RAGEQUIT) + -- inputBind("dpad_up", INPUT_ACTION_UP) + -- inputBind("dpad_down", INPUT_ACTION_DOWN) + -- inputBind("dpad_left", INPUT_ACTION_LEFT) + -- inputBind("dpad_right", INPUT_ACTION_RIGHT) + -- inputBind("button_b", INPUT_ACTION_CANCEL) + -- inputBind("button_a", INPUT_ACTION_ACCEPT) + -- inputBind("button_start", INPUT_ACTION_RAGEQUIT) + -- inputBind("lstick_up", INPUT_ACTION_UP) + -- inputBind("lstick_down", INPUT_ACTION_DOWN) + -- inputBind("lstick_left", INPUT_ACTION_LEFT) + -- inputBind("lstick_right", INPUT_ACTION_RIGHT) + else if INPUT_KEYBOARD then inputBind("w", INPUT_ACTION_UP) diff --git a/src/display/display.c b/src/display/display.c index 408cd66..a7d8e34 100644 --- a/src/display/display.c +++ b/src/display/display.c @@ -40,26 +40,6 @@ display_t DISPLAY = { 0 }; } #endif -meshvertex_t vertices[3] = { - { - .color = COLOR_RED_4B, - .uv = { 0.5f, 1.0f }, - .pos = { 0.0f, 15.0f, 0.0f } - }, - - { - .color = COLOR_GREEN_4B, - .uv = { 0.0f, 0.0f }, - .pos = { -15.0f, -15.0f, 0.0f } - }, - - { - .color = COLOR_BLUE_4B, - .uv = { 1.0f, 0.0f }, - .pos = { 15.0f, -15.0f, 0.0f } - } -}; - errorret_t displayInit(void) { #if DISPLAY_SDL2 uint32_t flags = SDL_INIT_VIDEO; @@ -213,6 +193,36 @@ errorret_t displayUpdate(void) { ); errorChain(sceneRender()); + color_t colors[4 * 4] = { + COLOR_RED_4B, COLOR_GREEN_4B, COLOR_BLUE_4B, COLOR_YELLOW_4B, + COLOR_CYAN_4B, COLOR_MAGENTA_4B, COLOR_WHITE_4B, COLOR_BLACK_4B, + COLOR_ORANGE_4B, COLOR_PURPLE_4B, COLOR_GRAY_4B, COLOR_BROWN_4B, + COLOR_PINK_4B, COLOR_LIME_4B, COLOR_NAVY_4B, COLOR_TEAL_4B + }; + texturedata_t data = { + .rgba = { .colors = colors } + }; + + camera_t camera; + cameraInit(&camera); + + texture_t texture; + textureInit(&texture, 4, 4, TEXTURE_FORMAT_RGBA, data); + + cameraPushMatrix(&camera); + spriteBatchClear(); + spriteBatchPush( + &texture, + -1, -1, + 1, 1, + COLOR_WHITE_4B, + 0, 0, + 1, 1 + ); + spriteBatchFlush(); + cameraPopMatrix(); + textureDispose(&texture); + // Render UI // uiRender(); diff --git a/src/display/mesh/mesh.c b/src/display/mesh/mesh.c index d35e429..a14bcfb 100644 --- a/src/display/mesh/mesh.c +++ b/src/display/mesh/mesh.c @@ -72,32 +72,64 @@ void meshDraw( #elif DOLPHIN // Prepare Vertex descriptor + DCFlushRange( + (void*)&mesh->vertices[offset], + sizeof(meshvertex_t) * count + ); GX_ClearVtxDesc();// Just clears so may be un-needed? GX_SetVtxDesc(GX_VA_POS, GX_INDEX16); - // GX_SetVtxDesc(GX_VA_TEX0, 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_TEX0, GX_TEX_ST, GX_F32, 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); const u8 stride = (u8)sizeof(meshvertex_t); GX_SetArray(GX_VA_POS, &mesh->vertices[offset].pos[0], stride); - // GX_SetArray(GX_VA_TEX0, &mesh->vertices[offset].uv[0], stride); GX_SetArray(GX_VA_CLR0, &mesh->vertices[offset].color, stride); + GX_SetArray(GX_VA_TEX0, &mesh->vertices[offset].uv[0], stride); + + // GX_SetNumChans(1);// How many color channels are used + // GX_SetNumTexGens(0);// How many texture coordinate generators are used + // GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORDNULL, GX_TEXMAP_NULL, GX_COLOR0A0); + // GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR); - GX_SetNumChans(1);// How many color channels are used - GX_SetNumTexGens(0);// How many texture coordinate generators are used // Basically the shader setup - GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORDNULL, GX_TEXMAP_NULL, GX_COLOR0A0); - GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR); + 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 + ); + + GX_SetNumTexGens(1); + GX_SetTexCoordGen( + GX_TEXCOORD0, + GX_TG_MTX2x4, + GX_TG_TEX0, + GX_IDENTITY + ); + + + GX_SetTevOrder( + GX_TEVSTAGE0, + GX_TEXCOORD0, + GX_TEXMAP0, + GX_COLOR0A0 + ); + GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE); GX_Begin(mesh->primitiveType, GX_VTXFMT0, (uint16_t)count); for(u16 i = 0; i < (u16)count; ++i) { GX_Position1x16(i); - // GX_TexCoord1x16(i); GX_Color1x16(i); + GX_TexCoord1x16(i); } GX_End(); #endif diff --git a/src/display/mesh/mesh.h b/src/display/mesh/mesh.h index 8853c54..eec9f63 100644 --- a/src/display/mesh/mesh.h +++ b/src/display/mesh/mesh.h @@ -22,21 +22,13 @@ typedef enum { #define MESH_VERTEX_UV_SIZE 2 #define MESH_VERTEX_POS_SIZE 3 -#if DOLPHIN - typedef struct ATTRIBUTE_ALIGN(32) { -#else - typedef struct { -#endif - color4b_t color; +typedef struct { + color_t color; float uv[MESH_VERTEX_UV_SIZE]; float pos[MESH_VERTEX_POS_SIZE]; } meshvertex_t; -#if DOLPHIN - typedef struct ATTRIBUTE_ALIGN(32) { -#else - typedef struct { -#endif +typedef struct { const meshvertex_t *vertices; int32_t vertexCount; meshprimitivetype_t primitiveType; diff --git a/src/display/mesh/quad.c b/src/display/mesh/quad.c index 49a1d0f..f9e9884 100644 --- a/src/display/mesh/quad.c +++ b/src/display/mesh/quad.c @@ -10,13 +10,13 @@ mesh_t QUAD_MESH_SIMPLE; meshvertex_t QUAD_MESH_SIMPLE_VERTICES[QUAD_VERTEX_COUNT] = { - { COLOR_WHITE_4B, { 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } }, - { COLOR_WHITE_4B, { 1.0f, 0.0f }, { 1.0f, 0.0f, 0.0f } }, - { COLOR_WHITE_4B, { 1.0f, 1.0f }, { 1.0f, 1.0f, 0.0f } }, - - { COLOR_WHITE_4B, { 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } }, - { COLOR_WHITE_4B, { 1.0f, 1.0f }, { 1.0f, 1.0f, 0.0f } }, - { COLOR_WHITE_4B, { 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f } } + { .color = COLOR_WHITE_4B, .uv = { 0.0f, 0.0f }, .pos = { 0.0f, 0.0f, 0.0f } }, + { .color = COLOR_WHITE_4B, .uv = { 1.0f, 0.0f }, .pos = { 1.0f, 0.0f, 0.0f } }, + { .color = COLOR_WHITE_4B, .uv = { 1.0f, 1.0f }, .pos = { 1.0f, 1.0f, 0.0f } }, + + { .color = COLOR_WHITE_4B, .uv = { 0.0f, 0.0f }, .pos = { 0.0f, 0.0f, 0.0f } }, + { .color = COLOR_WHITE_4B, .uv = { 1.0f, 1.0f }, .pos = { 1.0f, 1.0f, 0.0f } }, + { .color = COLOR_WHITE_4B, .uv = { 0.0f, 1.0f }, .pos = { 0.0f, 1.0f, 0.0f } } }; void quadInit() { @@ -44,38 +44,48 @@ void quadBuffer( assertNotNull(vertices, "Vertices cannot be NULL"); // First triangle - vertices[0] = (meshvertex_t) { - { color.r, color.g, color.b, color.a }, // Color - { u0, v0 }, // UV - { minX, minY, z } // Position - }; - vertices[1] = (meshvertex_t) { - { color.r, color.g, color.b, color.a }, // Color - { u1, v0 }, // UV - { maxX, minY, z } // Position - }; - vertices[2] = (meshvertex_t) { - { color.r, color.g, color.b, color.a }, // Color - { u1, v1 }, // UV - { maxX, maxY, z } // Position - }; + vertices[0].color = color; + vertices[0].uv[0] = u0; + vertices[0].uv[1] = v1; + vertices[0].pos[0] = minX; + vertices[0].pos[1] = maxY; + 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].uv[0] = u1; + vertices[1].uv[1] = v0; + vertices[1].pos[0] = maxX; + vertices[1].pos[1] = minY; + vertices[1].pos[2] = z; // Second triangle - vertices[3] = (meshvertex_t) { - { color.r, color.g, color.b, color.a }, // Color - { u0, v0 }, // UV - { minX, minY, z } // Position - }; - vertices[4] = (meshvertex_t) { - { color.r, color.g, color.b, color.a }, // Color - { u1, v1 }, // UV - { maxX, maxY, z } // Position - }; - vertices[5] = (meshvertex_t) { - { color.r, color.g, color.b, color.a }, // Color - { u0, v1 }, // UV - { minX, maxY, z } // Position - }; + vertices[3].color = color; + vertices[3].uv[0] = u0; + vertices[3].uv[1] = v1; + vertices[3].pos[0] = minX; + vertices[3].pos[1] = maxY; + 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].uv[0] = u1; + vertices[4].uv[1] = v1; + vertices[4].pos[0] = maxX; + vertices[4].pos[1] = maxY; + vertices[4].pos[2] = z; } void quadBuffer3D( @@ -93,36 +103,46 @@ void quadBuffer3D( assertNotNull(uvMax, "UV Max vector cannot be NULL"); // First triangle - vertices[0] = (meshvertex_t) { - { color.r, color.g, color.b, color.a }, // Color - { uvMin[0], uvMin[1] }, // UV - { min[0], min[1], min[2] } // Position - }; - vertices[1] = (meshvertex_t) { - { color.r, color.g, color.b, color.a }, // Color - { uvMax[0], uvMin[1] }, // UV - { max[0], min[1], min[2] } // Position - }; - vertices[2] = (meshvertex_t) { - { color.r, color.g, color.b, color.a }, // Color - { uvMax[0], uvMax[1] }, // UV - { max[0], max[1], min[2] } // Position - }; + vertices[0].color = color; + vertices[0].uv[0] = uvMin[0]; + vertices[0].uv[1] = uvMin[1]; + vertices[0].pos[0] = min[0]; + vertices[0].pos[1] = min[1]; + vertices[0].pos[2] = min[2]; + + vertices[1].color = color; + vertices[1].uv[0] = uvMax[0]; + vertices[1].uv[1] = uvMin[1]; + vertices[1].pos[0] = max[0]; + vertices[1].pos[1] = min[1]; + vertices[1].pos[2] = min[2]; + + vertices[2].color = color; + vertices[2].uv[0] = uvMax[0]; + vertices[2].uv[1] = uvMax[1]; + vertices[2].pos[0] = max[0]; + vertices[2].pos[1] = max[1]; + vertices[2].pos[2] = min[2]; // Second triangle - vertices[3] = (meshvertex_t) { - { color.r, color.g, color.b, color.a }, // Color - { uvMin[0], uvMin[1] }, // UV - { min[0], min[1], min[2] } // Position - }; - vertices[4] = (meshvertex_t) { - { color.r, color.g, color.b, color.a }, // Color - { uvMax[0], uvMax[1] }, // UV - { max[0], max[1], min[2] } // Position - }; - vertices[5] = (meshvertex_t) { - { color.r, color.g, color.b, color.a }, // Color - { uvMin[0], uvMax[1] }, // UV - { min[0], max[1], min[2] } // Position - }; + vertices[3].color = color; + vertices[3].uv[0] = uvMin[0]; + vertices[3].uv[1] = uvMin[1]; + vertices[3].pos[0] = min[0]; + vertices[3].pos[1] = min[1]; + vertices[3].pos[2] = min[2]; + + vertices[4].color = color; + vertices[4].uv[0] = uvMax[0]; + vertices[4].uv[1] = uvMax[1]; + vertices[4].pos[0] = max[0]; + vertices[4].pos[1] = max[1]; + vertices[4].pos[2] = min[2]; + + vertices[5].color = color; + vertices[5].uv[0] = uvMin[0]; + vertices[5].uv[1] = uvMax[1]; + vertices[5].pos[0] = min[0]; + vertices[5].pos[1] = max[1]; + vertices[5].pos[2] = min[2]; } \ No newline at end of file diff --git a/src/display/spritebatch.c b/src/display/spritebatch.c index 06ef550..9669992 100644 --- a/src/display/spritebatch.c +++ b/src/display/spritebatch.c @@ -9,9 +9,12 @@ #include "assert/assert.h" #include "util/memory.h" +meshvertex_t SPRITEBATCH_VERTICES[SPRITEBATCH_VERTEX_COUNT]; spritebatch_t SPRITEBATCH; void spriteBatchInit() { + memoryZero(&SPRITEBATCH, sizeof(spritebatch_t)); + SPRITEBATCH.spriteCount = 0; SPRITEBATCH.currentTexture = NULL; @@ -19,7 +22,7 @@ void spriteBatchInit() { &SPRITEBATCH.mesh, MESH_PRIMITIVE_TRIANGLES, SPRITEBATCH_VERTEX_COUNT, - &SPRITEBATCH.vertices[0] + &SPRITEBATCH_VERTICES[0] ); } @@ -45,7 +48,7 @@ void spriteBatchPush( } quadBuffer( - &SPRITEBATCH.vertices[SPRITEBATCH.spriteCount * QUAD_VERTEX_COUNT], + &SPRITEBATCH_VERTICES[SPRITEBATCH.spriteCount * QUAD_VERTEX_COUNT], minX, minY, maxX, maxY, color, u0, v0, u1, v1 @@ -72,7 +75,7 @@ void spriteBatchPush3D( } quadBuffer3D( - &SPRITEBATCH.vertices[SPRITEBATCH.spriteCount * QUAD_VERTEX_COUNT], + &SPRITEBATCH_VERTICES[SPRITEBATCH.spriteCount * QUAD_VERTEX_COUNT], min, max, color, uv0, uv1 ); diff --git a/src/display/spritebatch.h b/src/display/spritebatch.h index b2da2d9..95e9890 100644 --- a/src/display/spritebatch.h +++ b/src/display/spritebatch.h @@ -17,9 +17,11 @@ typedef struct { mesh_t mesh; int32_t spriteCount; texture_t *currentTexture; - meshvertex_t vertices[SPRITEBATCH_VERTEX_COUNT]; } 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; /** diff --git a/src/display/texture.c b/src/display/texture.c index 63f24d7..8965398 100644 --- a/src/display/texture.c +++ b/src/display/texture.c @@ -144,10 +144,78 @@ void textureInit( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_2D, 0); + texture->ready = true; + + #elif DOLPHIN + 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); + + 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_CLAMP, GX_CLAMP, + 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 + ); + + texture->ready = true; #endif } -void textureBind(const texture_t *texture) { +void textureBind(texture_t *texture) { if(TEXTURE_BOUND == texture) return; if(texture == NULL) { @@ -158,10 +226,7 @@ void textureBind(const texture_t *texture) { return; } - assertTrue( - texture->id != 0, - "Texture ID must not be 0" - ); + assertTrue(texture->ready, "Texture ID must be ready"); assertTrue( texture->width > 0 && texture->height > 0, "Texture width and height must be greater than 0" @@ -171,15 +236,28 @@ void textureBind(const texture_t *texture) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture->id); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + #elif DOLPHIN + GX_LoadTexObj(&texture->texObj, GX_TEXMAP0); + #endif TEXTURE_BOUND = texture; } void textureDispose(texture_t *texture) { assertNotNull(texture, "Texture cannot be NULL"); - assertTrue(texture->id != 0, "Texture ID must not be 0"); + assertTrue(texture->ready, "Texture ID must be ready"); + + if(TEXTURE_BOUND == texture) { + textureBind(NULL); + } #if DISPLAY_SDL2 glDeleteTextures(1, &texture->id); + #elif DOLPHIN + if(texture->rgba) { + free(texture->rgba); + texture->rgba = NULL; + } + #endif } \ No newline at end of file diff --git a/src/display/texture.h b/src/display/texture.h index 6c2d760..c040457 100644 --- a/src/display/texture.h +++ b/src/display/texture.h @@ -25,9 +25,14 @@ typedef struct { #if DISPLAY_SDL2 GLuint id; #elif DOLPHIN - uint8_t id; + GXTexObj texObj; + + union { + u16 *rgba; + }; #endif + bool_t ready; int32_t width; int32_t height; } texture_t; @@ -71,7 +76,7 @@ void textureInit( * * @param texture The texture to bind. */ -void textureBind(const texture_t *texture); +void textureBind(texture_t *texture); /** * Disposes a texture. diff --git a/src/dusk.h b/src/dusk.h index 34c9356..0352c83 100644 --- a/src/dusk.h +++ b/src/dusk.h @@ -32,6 +32,7 @@ #if DOLPHIN #include #include + #include #endif typedef bool bool_t; diff --git a/src/engine/engine.c b/src/engine/engine.c index b0df1f6..252ff5c 100644 --- a/src/engine/engine.c +++ b/src/engine/engine.c @@ -62,6 +62,8 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) { " inputBind(\"lstick_down\", INPUT_ACTION_DOWN)\n" " inputBind(\"lstick_left\", INPUT_ACTION_LEFT)\n" " inputBind(\"lstick_right\", INPUT_ACTION_RIGHT)\n" + // "elseif PLATFORM == \"gamecube\" then\n" + // " inputBind(\"start\", INPUT_ACTION_RAGEQUIT)\n" "else\n" " if INPUT_KEYBOARD then\n" " inputBind(\"w\", INPUT_ACTION_UP)\n" @@ -79,8 +81,7 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) { " end \n" "end\n" // "localeSet(DUSK_LOCALE_EN_US)\n" - "sceneSet('scene/initial.dsf')\n" - + // "sceneSet('scene/initial.dsf')\n" )); scriptContextDispose(&ctx); diff --git a/src/input/input.c b/src/input/input.c index e714c14..c096819 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -55,7 +55,17 @@ void inputUpdate(void) { INPUT.keyboardState = SDL_GetKeyboardState(NULL); #endif #elif DOLPHIN - PAD_Read(INPUT.pads); + PAD_ScanPads(); + + for(uint8_t i = 0; i < INPUT_PAD_COUNT; i++) { + INPUT.padState[i] = PAD_ButtonsDown(i); + INPUT.pads[i][INPUT_GAMEPAD_AXIS_LEFT_X] = INPUT_AXIS_FLOAT(PAD_StickX(i)); + INPUT.pads[i][INPUT_GAMEPAD_AXIS_LEFT_Y] = INPUT_AXIS_FLOAT(PAD_StickY(i)); + INPUT.pads[i][INPUT_GAMEPAD_AXIS_C_X] = INPUT_AXIS_FLOAT(PAD_SubStickX(i)); + INPUT.pads[i][INPUT_GAMEPAD_AXIS_C_Y] = INPUT_AXIS_FLOAT(PAD_SubStickY(i)); + INPUT.pads[i][INPUT_GAMEPAD_AXIS_TRIGGER_LEFT] = INPUT_AXIS_FLOAT(PAD_TriggerL(i)); + INPUT.pads[i][INPUT_GAMEPAD_AXIS_TRIGGER_RIGHT] = INPUT_AXIS_FLOAT(PAD_TriggerR(i)); + } #endif diff --git a/src/input/input.h b/src/input/input.h index 29b7dca..1dabc22 100644 --- a/src/input/input.h +++ b/src/input/input.h @@ -10,6 +10,11 @@ #include "inputaction.h" #include "event/event.h" +#if DOLPHIN + #define INPUT_PAD_COUNT PAD_CHANMAX + #define INPUT_AXIS_FLOAT(value) ((float_t)(value) / 128.0f) +#endif + #define INPUT_LISTENER_PRESSED_MAX 16 #define INPUT_LISTENER_RELEASED_MAX INPUT_LISTENER_PRESSED_MAX @@ -39,7 +44,8 @@ typedef struct { #endif #elif DOLPHIN - PADStatus pads[4]; + int padState[INPUT_PAD_COUNT]; + float_t pads[INPUT_PAD_COUNT][INPUT_GAMEPAD_AXIS_COUNT]; #endif } input_t; diff --git a/src/input/inputbutton.c b/src/input/inputbutton.c index a9ffa03..93e965b 100644 --- a/src/input/inputbutton.c +++ b/src/input/inputbutton.c @@ -173,27 +173,58 @@ inputbuttondata_t INPUT_BUTTON_DATA[] = { #endif #elif DOLPHIN - #if INPUT_GAMEPAD == 1 - { .name = "a", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_A } }, - { .name = "b", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_B } }, - { .name = "x", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_X } }, - { .name = "y", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_Y } }, - { .name = "start", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_START } }, - { .name = "dpad_up", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_UP } }, - { .name = "dpad_down", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_DOWN } }, - { .name = "dpad_left", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_LEFT } }, - { .name = "dpad_right", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_RIGHT } }, - { .name = "l", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_TRIGGER_L } }, - { .name = "r", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_TRIGGER_R } }, - { .name = "z", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_TRIGGER_Z } }, - { .name = "lstick_positive_x", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_LEFT_X, .positive = true } } }, - { .name = "lstick_negative_x", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_LEFT_X, .positive = false } } }, - { .name = "lstick_positive_y", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_LEFT_Y, .positive = true } } }, - { .name = "lstick_negative_y", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_LEFT_Y, .positive = false } } }, - { .name = "cstick_positive_x", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_C_X, .positive = true } } }, - { .name = "cstick_negative_x", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_C_X, .positive = false } } }, - { .name = "cstick_positive_y", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_C_Y, .positive = true } } }, - { .name = "cstick_negative_y", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_C_Y, .positive = false } } }, + #if WII + #if INPUT_GAMEPAD == 1 + { .name = "a", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_A } }, + { .name = "b", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_B } }, + { .name = "x", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_X } }, + { .name = "y", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_Y } }, + { .name = "start", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_START } }, + { .name = "dpad_up", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_UP } }, + { .name = "dpad_down", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_DOWN } }, + { .name = "dpad_left", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_LEFT } }, + { .name = "dpad_right", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_RIGHT } }, + { .name = "l", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_TRIGGER_L } }, + { .name = "r", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_TRIGGER_R } }, + { .name = "z", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_TRIGGER_Z } }, + { .name = "menu", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_MENU } }, + { .name = "lstick_positive_x", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_LEFT_X, .positive = true } } }, + { .name = "lstick_negative_x", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_LEFT_X, .positive = false } } }, + { .name = "lstick_positive_y", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_LEFT_Y, .positive = true } } }, + { .name = "lstick_negative_y", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_LEFT_Y, .positive = false } } }, + { .name = "cstick_positive_x", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_C_X, .positive = true } } }, + { .name = "cstick_negative_x", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_C_X, .positive = false } } }, + { .name = "cstick_positive_y", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_C_Y, .positive = true } } }, + { .name = "cstick_negative_y", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_C_Y, .positive = false } } }, + { .name = "ltrigger", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_TRIGGER_LEFT, .positive = true } } }, + { .name = "rtrigger", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_TRIGGER_RIGHT, .positive = true } } }, + #endif + #elif GAMECUBE + #if INPUT_GAMEPAD == 1 + { .name = "a", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_A } }, + { .name = "b", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_B } }, + { .name = "x", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_X } }, + { .name = "y", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_Y } }, + { .name = "start", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_START } }, + { .name = "dpad_up", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_UP } }, + { .name = "dpad_down", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_DOWN } }, + { .name = "dpad_left", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_LEFT } }, + { .name = "dpad_right", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_RIGHT } }, + { .name = "l", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_TRIGGER_L } }, + { .name = "r", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_TRIGGER_R } }, + { .name = "z", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_TRIGGER_Z } }, + { .name = "menu", { .type = INPUT_BUTTON_TYPE_GAMEPAD, .gpButton = PAD_BUTTON_MENU } }, + { .name = "lstick_positive_x", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_LEFT_X, .positive = true } } }, + { .name = "lstick_negative_x", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_LEFT_X, .positive = false } } }, + { .name = "lstick_positive_y", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_LEFT_Y, .positive = true } } }, + { .name = "lstick_negative_y", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_LEFT_Y, .positive = false } } }, + { .name = "cstick_positive_x", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_C_X, .positive = true } } }, + { .name = "cstick_negative_x", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_C_X, .positive = false } } }, + { .name = "cstick_positive_y", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_C_Y, .positive = true } } }, + { .name = "cstick_negative_y", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_C_Y, .positive = false } } }, + { .name = "ltrigger", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_TRIGGER_LEFT, .positive = true } } }, + { .name = "rtrigger", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_TRIGGER_RIGHT, .positive = true } } }, + #endif #endif #endif @@ -232,21 +263,28 @@ float_t inputButtonGetValue(const inputbutton_t button) { if(SDL_GameControllerGetButton(INPUT.controller, button.gpButton)) { return 1.0f; } + #elif DOLPHIN + if(INPUT.padState[0] & button.gpButton) return 1.0f; + #endif return 0.0f; } case INPUT_BUTTON_TYPE_GAMEPAD_AXIS: { + float_t value = 0.0f; + #if INPUT_SDL2 == 1 Sint16 axis = SDL_GameControllerGetAxis(INPUT.controller, button.gpAxis.axis); - if(!button.gpAxis.positive) axis = -axis; - float_t value = (float_t)axis / 32767.0f; - // Deadzone - if(value < INPUT.deadzone) return 0.0f; - return value; + value = (float_t)axis / 32767.0f; + + #elif DOLPHIN + value = INPUT.pads[0][button.gpAxis.axis]; + #endif + if(!button.gpAxis.positive) value = -value; + if(value >= INPUT.deadzone) return value; return 0.0f; } #endif diff --git a/src/input/inputbutton.h b/src/input/inputbutton.h index 9e484e0..329aadf 100644 --- a/src/input/inputbutton.h +++ b/src/input/inputbutton.h @@ -36,7 +36,9 @@ INPUT_GAMEPAD_AXIS_C_X, INPUT_GAMEPAD_AXIS_C_Y, INPUT_GAMEPAD_AXIS_TRIGGER_LEFT, - INPUT_GAMEPAD_AXIS_TRIGGER_RIGHT + INPUT_GAMEPAD_AXIS_TRIGGER_RIGHT, + + INPUT_GAMEPAD_AXIS_COUNT } inputgamepadaxis_t; #endif #endif diff --git a/src/scene/scene.c b/src/scene/scene.c index 2ce754e..7c54b8a 100644 --- a/src/scene/scene.c +++ b/src/scene/scene.c @@ -93,9 +93,9 @@ errorret_t sceneSet(const char_t *script) { "function sceneUpdate()\n" "end\n" "function sceneRender()\n" - " mapCamera.position = vec3(4, 4, 4)\n" + " mapCamera.position = vec3(32, 32, 32)\n" " cameraPushMatrix(mapCamera)\n" - " spriteBatchPush(nil, -1, -1, 1, 1, colorBlue())\n" + " spriteBatchPush(nil, -10, -10, 10, 10, colorBlue())\n" " spriteBatchFlush()\n" " cameraPopMatrix()\n" "end\n" diff --git a/src/util/memory.c b/src/util/memory.c index 40d609e..838843c 100644 --- a/src/util/memory.c +++ b/src/util/memory.c @@ -27,7 +27,6 @@ void memoryFree(void *ptr) { MEMORY_POINTERS_IN_USE--; } - void memoryCopy(void *dest, const void *src, const size_t size) { assertNotNull(dest, "Cannot copy to NULL memory."); assertNotNull(src, "Cannot copy from NULL memory.");