diff --git a/src/dusk/display/spritebatch/spritebatch.c b/src/dusk/display/spritebatch/spritebatch.c index ab2f4f8c..591beb4f 100644 --- a/src/dusk/display/spritebatch/spritebatch.c +++ b/src/dusk/display/spritebatch/spritebatch.c @@ -1,6 +1,6 @@ /** * Copyright (c) 2025 Dominic Masters - * + * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ @@ -9,6 +9,7 @@ #include "assert/assert.h" #include "util/memory.h" #include "util/math.h" +#include "display/shader/shaderunlit.h" meshvertex_t SPRITEBATCH_VERTICES[SPRITEBATCH_VERTEX_COUNT]; spritebatch_t SPRITEBATCH; @@ -25,6 +26,59 @@ errorret_t spriteBatchInit() { errorOk(); } +errorret_t spriteBatchBuffer( + const spritebatchsprite_t *sprites, + const uint32_t count +) { + for(uint32_t i = 0; i < count; i++) { + const spritebatchsprite_t *s = &sprites[i]; + + // if(s->texture != SPRITEBATCH.currentTexture) { + // errorChain(spriteBatchFlush()); + // } + + if(SPRITEBATCH.spriteCount >= SPRITEBATCH_SPRITES_MAX_PER_FLUSH) { + errorChain(spriteBatchFlush()); + } + + meshvertex_t *v = &SPRITEBATCH_VERTICES[ + (SPRITEBATCH.spriteCount + (SPRITEBATCH.spriteFlush * + SPRITEBATCH_SPRITES_MAX_PER_FLUSH)) * QUAD_VERTEX_COUNT + ]; + + v[0].pos[0] = s->min[0]; v[0].pos[1] = s->min[1]; v[0].pos[2] = s->min[2]; + v[0].uv[0] = s->uvMin[0]; v[0].uv[1] = s->uvMin[1]; + + v[1].pos[0] = s->max[0]; v[1].pos[1] = s->min[1]; v[1].pos[2] = s->min[2]; + v[1].uv[0] = s->uvMax[0]; v[1].uv[1] = s->uvMin[1]; + + v[2].pos[0] = s->max[0]; v[2].pos[1] = s->max[1]; v[2].pos[2] = s->min[2]; + v[2].uv[0] = s->uvMax[0]; v[2].uv[1] = s->uvMax[1]; + + v[3].pos[0] = s->min[0]; v[3].pos[1] = s->min[1]; v[3].pos[2] = s->min[2]; + v[3].uv[0] = s->uvMin[0]; v[3].uv[1] = s->uvMin[1]; + + v[4].pos[0] = s->max[0]; v[4].pos[1] = s->max[1]; v[4].pos[2] = s->min[2]; + v[4].uv[0] = s->uvMax[0]; v[4].uv[1] = s->uvMax[1]; + + v[5].pos[0] = s->min[0]; v[5].pos[1] = s->max[1]; v[5].pos[2] = s->min[2]; + v[5].uv[0] = s->uvMin[0]; v[5].uv[1] = s->uvMax[1]; + + #if MESH_ENABLE_COLOR + for(uint8_t vi = 0; vi < QUAD_VERTEX_COUNT; vi++) { + v[vi].color = s->color; + } + #endif + + SPRITEBATCH.spriteCount++; + } + errorOk(); +} + +errorret_t spriteBatchBufferSprite(const spritebatchsprite_t *sprite) { + return spriteBatchBuffer(sprite, 1); +} + errorret_t spriteBatchPushv( const float_t *minX, const float_t *minY, @@ -40,92 +94,17 @@ errorret_t spriteBatchPushv( const float_t *v1, const size_t count ) { - size_t offset = 0; - while(offset < count) { - if(SPRITEBATCH.spriteCount >= SPRITEBATCH_SPRITES_MAX_PER_FLUSH) { - errorChain(spriteBatchFlush()); - } - - size_t available = (size_t)( - SPRITEBATCH_SPRITES_MAX_PER_FLUSH - SPRITEBATCH.spriteCount - ); - size_t toPush = mathMin(count - offset, available); - - meshvertex_t *start = &SPRITEBATCH_VERTICES[ - (SPRITEBATCH.spriteCount + (SPRITEBATCH.spriteFlush * - SPRITEBATCH_SPRITES_MAX_PER_FLUSH)) * QUAD_VERTEX_COUNT - ]; - - // Fill all toPush sprites field-by-field, one memoryCopyInterleaved per - // vertex-slot per field. Vertex layout matches quadBuffer3D: - // v0=(minX,minY,z,u0,v0) v1=(maxX,minY,z,u1,v0) v2=(maxX,maxY,z,u1,v1) - // v3=(minX,minY,z,u0,v0) v4=(maxX,maxY,z,u1,v1) v5=(minX,maxY,z,u0,v1) - const size_t dstStride = sizeof(meshvertex_t) * QUAD_VERTEX_COUNT; - const size_t fSz = sizeof(float_t); - const float_t *sMinX = minX + offset; - const float_t *sMaxX = maxX + offset; - const float_t *sMinY = minY + offset; - const float_t *sMaxY = maxY + offset; - const float_t *sZ = z + offset; - const float_t *sU0 = u0 + offset; - const float_t *sU1 = u1 + offset; - const float_t *sV0 = v0 + offset; - const float_t *sV1 = v1 + offset; - - #define memshVertCopy(vi, field, srcArr) \ - memoryCopyInterleaved( \ - &start[vi].field, dstStride, srcArr, fSz, fSz, toPush \ - ) - - memshVertCopy(0, pos[0], sMinX); - memshVertCopy(0, pos[1], sMinY); - memshVertCopy(0, pos[2], sZ); - memshVertCopy(0, uv[0], sU0); - memshVertCopy(0, uv[1], sV0); - - memshVertCopy(1, pos[0], sMaxX); - memshVertCopy(1, pos[1], sMinY); - memshVertCopy(1, pos[2], sZ); - memshVertCopy(1, uv[0], sU1); - memshVertCopy(1, uv[1], sV0); - - memshVertCopy(2, pos[0], sMaxX); - memshVertCopy(2, pos[1], sMaxY); - memshVertCopy(2, pos[2], sZ); - memshVertCopy(2, uv[0], sU1); - memshVertCopy(2, uv[1], sV1); - - memshVertCopy(3, pos[0], sMinX); - memshVertCopy(3, pos[1], sMinY); - memshVertCopy(3, pos[2], sZ); - memshVertCopy(3, uv[0], sU0); - memshVertCopy(3, uv[1], sV0); - - memshVertCopy(4, pos[0], sMaxX); - memshVertCopy(4, pos[1], sMaxY); - memshVertCopy(4, pos[2], sZ); - memshVertCopy(4, uv[0], sU1); - memshVertCopy(4, uv[1], sV1); - - memshVertCopy(5, pos[0], sMinX); - memshVertCopy(5, pos[1], sMaxY); - memshVertCopy(5, pos[2], sZ); - memshVertCopy(5, uv[0], sU0); - memshVertCopy(5, uv[1], sV1); - - #undef memshVertCopy - + for(size_t i = 0; i < count; i++) { + spritebatchsprite_t sprite; + sprite.min[0] = minX[i]; sprite.min[1] = minY[i]; sprite.min[2] = z[i]; + sprite.max[0] = maxX[i]; sprite.max[1] = maxY[i]; sprite.max[2] = z[i]; + sprite.uvMin[0] = u0[i]; sprite.uvMin[1] = v0[i]; + sprite.uvMax[0] = u1[i]; sprite.uvMax[1] = v1[i]; + sprite.texture = SPRITEBATCH.currentTexture; #if MESH_ENABLE_COLOR - for(uint8_t vi = 0; vi < QUAD_VERTEX_COUNT; vi++) { - memoryCopyInterleaved( - &start[vi].color, dstStride, - color + offset, sizeof(color_t), sizeof(color_t), toPush - ); - } + sprite.color = color[i]; #endif - - SPRITEBATCH.spriteCount += (int32_t)toPush; - offset += toPush; + errorChain(spriteBatchBuffer(&sprite, 1)); } errorOk(); } @@ -143,52 +122,37 @@ errorret_t spriteBatchPush( const float_t u1, const float_t v1 ) { - return spriteBatchPushv( - &minX, &minY, &maxX, &maxY, &(float_t){0}, - #if MESH_ENABLE_COLOR - &color, - #endif - &u0, &v0, &u1, &v1, - 1 - ); + spritebatchsprite_t sprite; + sprite.min[0] = minX; sprite.min[1] = minY; sprite.min[2] = 0; + sprite.max[0] = maxX; sprite.max[1] = maxY; sprite.max[2] = 0; + sprite.uvMin[0] = u0; sprite.uvMin[1] = v0; + sprite.uvMax[0] = u1; sprite.uvMax[1] = v1; + sprite.texture = SPRITEBATCH.currentTexture; + #if MESH_ENABLE_COLOR + sprite.color = color; + #endif + return spriteBatchBuffer(&sprite, 1); } -errorret_t spriteBatchPush3D( +errorret_t spriteBatchPushZ( const vec3 min, const vec3 max, #if MESH_ENABLE_COLOR const color_t color, #endif - const vec2 uv0, - const vec2 uv1 + const vec2 uvMin, + const vec2 uvMax ) { - return spriteBatchPushv( - &min[0], &min[1], - &max[0], &max[1], - &min[2], - #if MESH_ENABLE_COLOR - &color, - #endif - &uv0[0], &uv0[1], - &uv1[0], &uv1[1], - 1 - ); -} - -errorret_t spriteBatchBufferSprite(const spritebatchsprite_t *sprite) { - if(sprite->texture != SPRITEBATCH.currentTexture) { - errorChain(spriteBatchFlush()); - SPRITEBATCH.currentTexture = sprite->texture; - } - return spriteBatchPush3D( - sprite->min, - sprite->max, - #if MESH_ENABLE_COLOR - sprite->color, - #endif - sprite->uvMin, - sprite->uvMax - ); + spritebatchsprite_t sprite; + sprite.min[0] = min[0]; sprite.min[1] = min[1]; sprite.min[2] = min[2]; + sprite.max[0] = max[0]; sprite.max[1] = max[1]; sprite.max[2] = max[2]; + sprite.uvMin[0] = uvMin[0]; sprite.uvMin[1] = uvMin[1]; + sprite.uvMax[0] = uvMax[0]; sprite.uvMax[1] = uvMax[1]; + sprite.texture = SPRITEBATCH.currentTexture; + #if MESH_ENABLE_COLOR + sprite.color = color; + #endif + return spriteBatchBuffer(&sprite, 1); } void spriteBatchClear() { diff --git a/src/dusk/display/spritebatch/spritebatch.h b/src/dusk/display/spritebatch/spritebatch.h index 6632fbdc..0da6dba6 100644 --- a/src/dusk/display/spritebatch/spritebatch.h +++ b/src/dusk/display/spritebatch/spritebatch.h @@ -1,6 +1,6 @@ /** * Copyright (c) 2025 Dominic Masters - * + * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ @@ -40,14 +40,34 @@ extern spritebatch_t SPRITEBATCH; /** * Initializes a sprite batch. - * - * @param spriteBatch The sprite batch to initialize. + * * @return An error code indicating success or failure. */ errorret_t spriteBatchInit(); /** - * Pushes multiple sprites to the batch using arrays of values. + * Buffers an array of sprites. Flushes automatically when the texture changes + * or the per-flush limit is reached. + * + * @param sprites Pointer to the sprite array. + * @param count Number of sprites to buffer. + * @return An error code indicating success or failure. + */ +errorret_t spriteBatchBuffer( + const spritebatchsprite_t *sprites, + const uint32_t count +); + +/** + * Convenience wrapper — buffers a single sprite. + * + * @param sprite The sprite to buffer. + * @return An error code indicating success or failure. + */ +errorret_t spriteBatchBufferSprite(const spritebatchsprite_t *sprite); + +/** + * Pushes multiple sprites to the batch using parallel arrays of values. * * @param minX Array of minimum x coordinates. * @param minY Array of minimum y coordinates. @@ -79,22 +99,17 @@ errorret_t spriteBatchPushv( ); /** - * Pushes a sprite to the batch. This basically "queues" it to render (well - * technically it is buffering the vertices to the mesh at the moment, but - * that is likely to change when we switch to VAOs or VBOs or even Shader UBOs). - * - * Currently changing texture pointer will cause the buffer to flush but this is - * also likely to change in the future. - * + * Pushes a 2D sprite (z=0) to the batch. + * * @param minX The minimum x coordinate of the sprite. * @param minY The minimum y coordinate of the sprite. * @param maxX The maximum x coordinate of the sprite. * @param maxY The maximum y coordinate of the sprite. * @param color The color to tint the sprite with. - * @param u0 The texture coordinate for the top-left corner of the sprite. - * @param v0 The texture coordinate for the top-left corner of the sprite. - * @param u1 The texture coordinate for the bottom-right corner of the sprite. - * @param v1 The texture coordinate for the bottom-right corner of the sprite. + * @param u0 Texture u coordinate for the top-left corner. + * @param v0 Texture v coordinate for the top-left corner. + * @param u1 Texture u coordinate for the bottom-right corner. + * @param v1 Texture v coordinate for the bottom-right corner. * @return An error code indicating success or failure. */ errorret_t spriteBatchPush( @@ -112,17 +127,16 @@ errorret_t spriteBatchPush( ); /** - * Pushes a 3D sprite to the batch. This is like spriteBatchPush but takes - * 3D coordinates instead of 2D. - * + * Pushes a 3D sprite to the batch. + * * @param min The minimum (x,y,z) coordinate of the sprite. * @param max The maximum (x,y,z) coordinate of the sprite. * @param color The color to tint the sprite with. - * @param uvMin The texture coordinate for the top-left corner of the sprite. - * @param uvMax The texture coordinate for the bottom-right corner of the sprite + * @param uvMin Texture coordinate for the top-left corner. + * @param uvMax Texture coordinate for the bottom-right corner. * @return An error code indicating success or failure. */ -errorret_t spriteBatchPush3D( +errorret_t spriteBatchPushZ( const vec3 min, const vec3 max, #if MESH_ENABLE_COLOR @@ -133,29 +147,20 @@ errorret_t spriteBatchPush3D( ); /** - * Buffers a sprite defined by a spritebatchsprite_t. Automatically flushes - * if the texture changes from the previously buffered sprite. - * - * @param sprite The sprite to buffer. - * @return An error code indicating success or failure. - */ -errorret_t spriteBatchBufferSprite(const spritebatchsprite_t *sprite); - -/** - * Clears the sprite batch. This will mean calling flush renders nothing. + * Clears the sprite batch. Calling flush after this renders nothing. */ void spriteBatchClear(); /** * Flushes the sprite batch, rendering all queued sprites. - * + * * @return An error code indicating success or failure. */ errorret_t spriteBatchFlush(); /** * Disposes of the sprite batch, freeing any allocated resources. - * + * * @return An error code indicating success or failure. */ -errorret_t spriteBatchDispose(); \ No newline at end of file +errorret_t spriteBatchDispose(); diff --git a/src/dusk/scene/initial/initialscene.c b/src/dusk/scene/initial/initialscene.c index 2d027570..3a7ea5a3 100644 --- a/src/dusk/scene/initial/initialscene.c +++ b/src/dusk/scene/initial/initialscene.c @@ -7,6 +7,10 @@ #include "initialscene.h" #include "console/console.h" +#include "display/spritebatch/spritebatch.h" +#include "display/screen/screen.h" + +#include "display/shader/shaderunlit.h" void initialSceneInit(void) { consolePrint("Initial scene initialized"); @@ -17,6 +21,42 @@ errorret_t initialSceneUpdate(void) { } errorret_t initialSceneDraw(void) { + { + mat4 view, proj; + glm_perspective( + glm_rad(45.0f), + (float_t)SCREEN.width / (float_t)SCREEN.height, + 0.1f, + 100.0f, + proj + ); + shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj); + + glm_lookat( + (vec3){ 3.0f, 3.0f, 3.0f }, + (vec3){ 0.0f, 0.0f, 0.0f }, + (vec3){ 0.0f, 1.0f, 0.0f }, + view + ); + shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, view); + } + + errorChain(displaySetState((displaystate_t){ + .flags = DISPLAY_STATE_FLAG_BLEND | DISPLAY_STATE_FLAG_DEPTH_TEST + })); + + // Draw entities + spriteBatchPushZ( + (vec3){ 0.0f, 0.0f, 0.0f }, + (vec3){ 32.0f, 32.0f, 0.0f }, + #if MESH_ENABLE_COLOR + COLOR_WHITE, + #endif + (vec2){ 0.0f, 0.0f }, + (vec2){ 1.0f, 1.0f } + ); + spriteBatchFlush(); + errorOk(); } diff --git a/src/dusk/scene/scene.c b/src/dusk/scene/scene.c index c6f2257c..0473eca5 100644 --- a/src/dusk/scene/scene.c +++ b/src/dusk/scene/scene.c @@ -34,27 +34,39 @@ errorret_t sceneInit(void) { } errorret_t sceneUpdate(void) { + if(SCENE.nextType == SCENE_TYPE_NULL) { + errorOk(); + } + + // Handle scene change + if(SCENE.nextType != SCENE_TYPE_NULL) { + // Dispose current scene. + if(SCENE.type != SCENE_TYPE_NULL) { + if(SCENE_FUNCTIONS[SCENE.type].dispose) { + SCENE_FUNCTIONS[SCENE.type].dispose(); + } + } + + // Init new scene + SCENE.type = SCENE.nextType; + SCENE.nextType = SCENE_TYPE_NULL; + + if(SCENE.type != SCENE_TYPE_NULL) { + if(SCENE_FUNCTIONS[SCENE.type].init) { + SCENE_FUNCTIONS[SCENE.type].init(); + } + } + } + + // Update scene #ifdef DUSK_TIME_DYNAMIC if(TIME.dynamicUpdate) { errorOk(); } #endif - // Dispose current scene. - if(SCENE.type != SCENE_TYPE_NULL) { - if(SCENE_FUNCTIONS[SCENE.type].dispose) { - SCENE_FUNCTIONS[SCENE.type].dispose(); - } - } - - // Init new scene - SCENE.type = SCENE.nextType; - SCENE.nextType = SCENE_TYPE_NULL; - - if(SCENE.type != SCENE_TYPE_NULL) { - if(SCENE_FUNCTIONS[SCENE.type].init) { - SCENE_FUNCTIONS[SCENE.type].init(); - } + if(SCENE.type != SCENE_TYPE_NULL && SCENE_FUNCTIONS[SCENE.type].update) { + errorChain(SCENE_FUNCTIONS[SCENE.type].update()); } errorOk(); @@ -63,25 +75,34 @@ errorret_t sceneUpdate(void) { dusktimeepoch_t LAST; errorret_t sceneRender(void) { - mat4 view, proj; - glm_ortho( - 0.0f, SCREEN.width, - SCREEN.height, 0.0f, - 0.1f, 100.0f, - proj - ); + mat4 model; + glm_mat4_identity(model); errorChain(shaderBind(&SHADER_UNLIT)); - errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj)); + // Perform soft reset + errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model)); + errorChain(shaderSetTexture(&SHADER_UNLIT, SHADER_UNLIT_TEXTURE, NULL)); + errorChain(shaderSetColor(&SHADER_UNLIT, SHADER_UNLIT_COLOR, COLOR_WHITE)); + + // Render scene. if(SCENE.type != SCENE_TYPE_NULL && SCENE_FUNCTIONS[SCENE.type].render) { - glm_mat4_identity(view); - errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, view)); errorChain(SCENE_FUNCTIONS[SCENE.type].render()); } // UI Rendering { + errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model)); + + mat4 view, proj; + glm_ortho( + 0.0f, SCREEN.width, + SCREEN.height, 0.0f, + 0.1f, 100.0f, + proj + ); + errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_PROJECTION, proj)); + glm_lookat( (vec3){ 0.0f, 0.0f, 1.0f }, (vec3){ 0.0f, 0.0f, 0.0f }, @@ -89,10 +110,6 @@ errorret_t sceneRender(void) { view ); errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, view)); - - mat4 model; - glm_mat4_identity(model); - errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, model)); errorChain(displaySetState((displaystate_t){ .flags = DISPLAY_STATE_FLAG_BLEND diff --git a/src/duskdolphin/input/inputdolphin.c b/src/duskdolphin/input/inputdolphin.c index d634fc2c..59d503ab 100644 --- a/src/duskdolphin/input/inputdolphin.c +++ b/src/duskdolphin/input/inputdolphin.c @@ -38,7 +38,6 @@ inputbuttondata_t INPUT_BUTTON_DATA[] = { { .name = "lstick_right", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_LEFT_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 { .name = NULL } @@ -47,6 +46,47 @@ inputbuttondata_t INPUT_BUTTON_DATA[] = { errorret_t inputInitDolphin(void) { PAD_Init(); + #define X(buttonName, buttonAction) \ + inputBind(inputButtonGetByName(buttonName), buttonAction); + + #if defined(DUSK_GAMECUBE) + X("up", INPUT_ACTION_UP); + X("down", INPUT_ACTION_DOWN); + X("left", INPUT_ACTION_LEFT); + X("right", INPUT_ACTION_RIGHT); + X("lstick_up", INPUT_ACTION_UP); + X("lstick_down", INPUT_ACTION_DOWN); + X("lstick_left", INPUT_ACTION_LEFT); + X("lstick_right", INPUT_ACTION_RIGHT); + + X("a", INPUT_ACTION_ACCEPT); + X("b", INPUT_ACTION_CANCEL); + X("z", INPUT_ACTION_CONSOLE); + X("start", INPUT_ACTION_RAGEQUIT); + + #elif defined(DUSK_WII) + X("up", INPUT_ACTION_UP); + X("down", INPUT_ACTION_DOWN); + X("left", INPUT_ACTION_LEFT); + X("right", INPUT_ACTION_RIGHT); + X("lstick_up", INPUT_ACTION_UP); + X("lstick_down", INPUT_ACTION_DOWN); + X("lstick_left", INPUT_ACTION_LEFT); + X("lstick_right", INPUT_ACTION_RIGHT); + + X("a", INPUT_ACTION_ACCEPT); + X("b", INPUT_ACTION_CANCEL); + X("z", INPUT_ACTION_CONSOLE); + X("start", INPUT_ACTION_RAGEQUIT); + + // TODO: Wiimote, USB Keyboard, probably more. + + #else + #error "Unknown Dolphin platform?" + #endif + + #undef X + errorOk(); } diff --git a/src/dusklinux/input/inputlinux.c b/src/dusklinux/input/inputlinux.c index 1eb10ca4..1938f6f8 100644 --- a/src/dusklinux/input/inputlinux.c +++ b/src/dusklinux/input/inputlinux.c @@ -184,6 +184,52 @@ inputbuttondata_t INPUT_BUTTON_DATA[] = { { .name = NULL }, }; +errorret_t inputInitLinux(void) { + #define X(buttonName, buttonAction) \ + inputBind(inputButtonGetByName(buttonName), buttonAction); + + #ifdef DUSK_INPUT_KEYBOARD + X("w", INPUT_ACTION_UP); + X("s", INPUT_ACTION_DOWN); + X("a", INPUT_ACTION_LEFT); + X("d", INPUT_ACTION_RIGHT); + X("left", INPUT_ACTION_LEFT); + X("right", INPUT_ACTION_RIGHT); + X("up", INPUT_ACTION_UP); + X("down", INPUT_ACTION_DOWN); + X("enter", INPUT_ACTION_ACCEPT); + X("e", INPUT_ACTION_ACCEPT); + X("space", INPUT_ACTION_ACCEPT); + X("tab", INPUT_ACTION_CANCEL); + X("q", INPUT_ACTION_CANCEL); + X("escape", INPUT_ACTION_RAGEQUIT); + X("`", INPUT_ACTION_CONSOLE); + #endif + + #ifdef DUSK_INPUT_GAMEPAD + X("gamepad_up", INPUT_ACTION_UP); + X("gamepad_down", INPUT_ACTION_DOWN); + X("gamepad_left", INPUT_ACTION_LEFT); + X("gamepad_right", INPUT_ACTION_RIGHT); + X("gamepad_a", INPUT_ACTION_ACCEPT); + X("gamepad_b", INPUT_ACTION_CANCEL); + X("gamepad_back", INPUT_ACTION_RAGEQUIT); + X("gamepad_lstick_up", INPUT_ACTION_UP); + X("gamepad_lstick_down", INPUT_ACTION_DOWN); + X("gamepad_lstick_left", INPUT_ACTION_LEFT); + X("gamepad_lstick_right", INPUT_ACTION_RIGHT); + #endif + + #ifdef DUSK_INPUT_POINTER + X("mouse_x", INPUT_ACTION_POINTERX); + X("mouse_y", INPUT_ACTION_POINTERY); + #endif + + #undef X + + errorOk(); +} + float_t inputGetDeadzoneSDL2(const inputbutton_t button) { return 0.17f; } \ No newline at end of file diff --git a/src/dusklinux/input/inputlinux.h b/src/dusklinux/input/inputlinux.h new file mode 100644 index 00000000..ba962fd1 --- /dev/null +++ b/src/dusklinux/input/inputlinux.h @@ -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 "error/error.h" +#include "input/inputsdl2.h" + +/** + * Initializes the input system on Linux. + * + * @return An error code indicating success or failure. + */ +errorret_t inputInitLinux(void); \ No newline at end of file diff --git a/src/dusklinux/input/inputplatform.h b/src/dusklinux/input/inputplatform.h new file mode 100644 index 00000000..b390dcff --- /dev/null +++ b/src/dusklinux/input/inputplatform.h @@ -0,0 +1,11 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "input/inputlinux.h" + +#define inputInitPlatform inputInitLinux \ No newline at end of file diff --git a/src/duskpsp/input/inputplatform.h b/src/duskpsp/input/inputplatform.h new file mode 100644 index 00000000..8de3d7fa --- /dev/null +++ b/src/duskpsp/input/inputplatform.h @@ -0,0 +1,11 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "input/inputpsp.h" + +#define inputInitPlatform inputInitPSP \ No newline at end of file diff --git a/src/duskpsp/input/inputpsp.c b/src/duskpsp/input/inputpsp.c index ace962bc..25fa9c25 100644 --- a/src/duskpsp/input/inputpsp.c +++ b/src/duskpsp/input/inputpsp.c @@ -36,6 +36,26 @@ inputbuttondata_t INPUT_BUTTON_DATA[] = { { .name = NULL } }; +errorret_t inputInitPSP(void) { + #define X(buttonName, buttonAction) \ + inputBind(inputButtonGetByName(buttonName), buttonAction); + X("up", INPUT_ACTION_UP); + X("down", INPUT_ACTION_DOWN); + X("left", INPUT_ACTION_LEFT); + X("right", INPUT_ACTION_RIGHT); + X("accept", INPUT_ACTION_ACCEPT); + X("cancel", INPUT_ACTION_CANCEL); + X("triangle", INPUT_ACTION_CONSOLE); + X("select", INPUT_ACTION_RAGEQUIT); + X("lstick_up", INPUT_ACTION_UP); + X("lstick_down", INPUT_ACTION_DOWN); + X("lstick_left", INPUT_ACTION_LEFT); + X("lstick_right", INPUT_ACTION_RIGHT); + #undef X + + errorOk(); +} + float_t inputGetDeadzoneSDL2(const inputbutton_t button) { return 0.2f; } \ No newline at end of file diff --git a/src/duskpsp/input/inputpsp.h b/src/duskpsp/input/inputpsp.h new file mode 100644 index 00000000..b51fa36a --- /dev/null +++ b/src/duskpsp/input/inputpsp.h @@ -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 "error/error.h" +#include "input/inputsdl2.h" + +/** + * Initializes the input system on PSP. + * + * @return An error code indicating success or failure. + */ +errorret_t inputInitPSP(void); \ No newline at end of file diff --git a/src/dusksdl2/input/inputplatform.h b/src/dusksdl2/input/inputplatform.h deleted file mode 100644 index c71c3d19..00000000 --- a/src/dusksdl2/input/inputplatform.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "inputsdl2.h" - -#ifdef DUSK_INPUT_KEYBOARD - typedef inputscancodesdl2_t inputscancodeplatform_t; -#endif - -#ifdef DUSK_INPUT_GAMEPAD - typedef inputgamepadbuttonsdl2_t inputgamepadbuttonplatform_t; - typedef inputgamepadaxissdl2_t inputgamepadaxissplatform_t; -#endif - -#ifdef DUSK_INPUT_POINTER - typedef inputpointeraxissdl2_t inputpointeraxisplatform_t; -#endif - -#define inputUpdatePlatform inputUpdateSDL2 -#define inputButtonGetValuePlatform inputButtonGetValueSDL2 - -typedef inputsdl2_t inputplatform_t; \ No newline at end of file diff --git a/src/dusksdl2/input/inputsdl2.h b/src/dusksdl2/input/inputsdl2.h index 9b3af5c4..03ba9ebc 100644 --- a/src/dusksdl2/input/inputsdl2.h +++ b/src/dusksdl2/input/inputsdl2.h @@ -44,6 +44,25 @@ typedef struct { #endif } inputsdl2_t; +// Setup platform variables for input. +#ifdef DUSK_INPUT_KEYBOARD + typedef inputscancodesdl2_t inputscancodeplatform_t; +#endif + +#ifdef DUSK_INPUT_GAMEPAD + typedef inputgamepadbuttonsdl2_t inputgamepadbuttonplatform_t; + typedef inputgamepadaxissdl2_t inputgamepadaxissplatform_t; +#endif + +#ifdef DUSK_INPUT_POINTER + typedef inputpointeraxissdl2_t inputpointeraxisplatform_t; +#endif + +#define inputUpdatePlatform inputUpdateSDL2 +#define inputButtonGetValuePlatform inputButtonGetValueSDL2 + +typedef inputsdl2_t inputplatform_t; + /** * Updates the input state for SDL2. */