Update render, spritebatch and input stuffs.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2025 Dominic Masters
|
* Copyright (c) 2025 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "util/math.h"
|
#include "util/math.h"
|
||||||
|
#include "display/shader/shaderunlit.h"
|
||||||
|
|
||||||
meshvertex_t SPRITEBATCH_VERTICES[SPRITEBATCH_VERTEX_COUNT];
|
meshvertex_t SPRITEBATCH_VERTICES[SPRITEBATCH_VERTEX_COUNT];
|
||||||
spritebatch_t SPRITEBATCH;
|
spritebatch_t SPRITEBATCH;
|
||||||
@@ -25,6 +26,59 @@ errorret_t spriteBatchInit() {
|
|||||||
errorOk();
|
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(
|
errorret_t spriteBatchPushv(
|
||||||
const float_t *minX,
|
const float_t *minX,
|
||||||
const float_t *minY,
|
const float_t *minY,
|
||||||
@@ -40,92 +94,17 @@ errorret_t spriteBatchPushv(
|
|||||||
const float_t *v1,
|
const float_t *v1,
|
||||||
const size_t count
|
const size_t count
|
||||||
) {
|
) {
|
||||||
size_t offset = 0;
|
for(size_t i = 0; i < count; i++) {
|
||||||
while(offset < count) {
|
spritebatchsprite_t sprite;
|
||||||
if(SPRITEBATCH.spriteCount >= SPRITEBATCH_SPRITES_MAX_PER_FLUSH) {
|
sprite.min[0] = minX[i]; sprite.min[1] = minY[i]; sprite.min[2] = z[i];
|
||||||
errorChain(spriteBatchFlush());
|
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];
|
||||||
size_t available = (size_t)(
|
sprite.texture = SPRITEBATCH.currentTexture;
|
||||||
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
|
|
||||||
|
|
||||||
#if MESH_ENABLE_COLOR
|
#if MESH_ENABLE_COLOR
|
||||||
for(uint8_t vi = 0; vi < QUAD_VERTEX_COUNT; vi++) {
|
sprite.color = color[i];
|
||||||
memoryCopyInterleaved(
|
|
||||||
&start[vi].color, dstStride,
|
|
||||||
color + offset, sizeof(color_t), sizeof(color_t), toPush
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
errorChain(spriteBatchBuffer(&sprite, 1));
|
||||||
SPRITEBATCH.spriteCount += (int32_t)toPush;
|
|
||||||
offset += toPush;
|
|
||||||
}
|
}
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
@@ -143,52 +122,37 @@ errorret_t spriteBatchPush(
|
|||||||
const float_t u1,
|
const float_t u1,
|
||||||
const float_t v1
|
const float_t v1
|
||||||
) {
|
) {
|
||||||
return spriteBatchPushv(
|
spritebatchsprite_t sprite;
|
||||||
&minX, &minY, &maxX, &maxY, &(float_t){0},
|
sprite.min[0] = minX; sprite.min[1] = minY; sprite.min[2] = 0;
|
||||||
#if MESH_ENABLE_COLOR
|
sprite.max[0] = maxX; sprite.max[1] = maxY; sprite.max[2] = 0;
|
||||||
&color,
|
sprite.uvMin[0] = u0; sprite.uvMin[1] = v0;
|
||||||
#endif
|
sprite.uvMax[0] = u1; sprite.uvMax[1] = v1;
|
||||||
&u0, &v0, &u1, &v1,
|
sprite.texture = SPRITEBATCH.currentTexture;
|
||||||
1
|
#if MESH_ENABLE_COLOR
|
||||||
);
|
sprite.color = color;
|
||||||
|
#endif
|
||||||
|
return spriteBatchBuffer(&sprite, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t spriteBatchPush3D(
|
errorret_t spriteBatchPushZ(
|
||||||
const vec3 min,
|
const vec3 min,
|
||||||
const vec3 max,
|
const vec3 max,
|
||||||
#if MESH_ENABLE_COLOR
|
#if MESH_ENABLE_COLOR
|
||||||
const color_t color,
|
const color_t color,
|
||||||
#endif
|
#endif
|
||||||
const vec2 uv0,
|
const vec2 uvMin,
|
||||||
const vec2 uv1
|
const vec2 uvMax
|
||||||
) {
|
) {
|
||||||
return spriteBatchPushv(
|
spritebatchsprite_t sprite;
|
||||||
&min[0], &min[1],
|
sprite.min[0] = min[0]; sprite.min[1] = min[1]; sprite.min[2] = min[2];
|
||||||
&max[0], &max[1],
|
sprite.max[0] = max[0]; sprite.max[1] = max[1]; sprite.max[2] = max[2];
|
||||||
&min[2],
|
sprite.uvMin[0] = uvMin[0]; sprite.uvMin[1] = uvMin[1];
|
||||||
#if MESH_ENABLE_COLOR
|
sprite.uvMax[0] = uvMax[0]; sprite.uvMax[1] = uvMax[1];
|
||||||
&color,
|
sprite.texture = SPRITEBATCH.currentTexture;
|
||||||
#endif
|
#if MESH_ENABLE_COLOR
|
||||||
&uv0[0], &uv0[1],
|
sprite.color = color;
|
||||||
&uv1[0], &uv1[1],
|
#endif
|
||||||
1
|
return spriteBatchBuffer(&sprite, 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
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void spriteBatchClear() {
|
void spriteBatchClear() {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2025 Dominic Masters
|
* Copyright (c) 2025 Dominic Masters
|
||||||
*
|
*
|
||||||
* This software is released under the MIT License.
|
* This software is released under the MIT License.
|
||||||
* https://opensource.org/licenses/MIT
|
* https://opensource.org/licenses/MIT
|
||||||
*/
|
*/
|
||||||
@@ -40,14 +40,34 @@ extern spritebatch_t SPRITEBATCH;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a sprite batch.
|
* Initializes a sprite batch.
|
||||||
*
|
*
|
||||||
* @param spriteBatch The sprite batch to initialize.
|
|
||||||
* @return An error code indicating success or failure.
|
* @return An error code indicating success or failure.
|
||||||
*/
|
*/
|
||||||
errorret_t spriteBatchInit();
|
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 minX Array of minimum x coordinates.
|
||||||
* @param minY Array of minimum y 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
|
* Pushes a 2D sprite (z=0) to the batch.
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* @param minX The minimum x coordinate of the sprite.
|
* @param minX The minimum x coordinate of the sprite.
|
||||||
* @param minY The minimum y coordinate of the sprite.
|
* @param minY The minimum y coordinate of the sprite.
|
||||||
* @param maxX The maximum x coordinate of the sprite.
|
* @param maxX The maximum x coordinate of the sprite.
|
||||||
* @param maxY The maximum y coordinate of the sprite.
|
* @param maxY The maximum y coordinate of the sprite.
|
||||||
* @param color The color to tint the sprite with.
|
* @param color The color to tint the sprite with.
|
||||||
* @param u0 The texture coordinate for the top-left corner of the sprite.
|
* @param u0 Texture u coordinate for the top-left corner.
|
||||||
* @param v0 The texture coordinate for the top-left corner of the sprite.
|
* @param v0 Texture v coordinate for the top-left corner.
|
||||||
* @param u1 The texture coordinate for the bottom-right corner of the sprite.
|
* @param u1 Texture u coordinate for the bottom-right corner.
|
||||||
* @param v1 The texture coordinate for the bottom-right corner of the sprite.
|
* @param v1 Texture v coordinate for the bottom-right corner.
|
||||||
* @return An error code indicating success or failure.
|
* @return An error code indicating success or failure.
|
||||||
*/
|
*/
|
||||||
errorret_t spriteBatchPush(
|
errorret_t spriteBatchPush(
|
||||||
@@ -112,17 +127,16 @@ errorret_t spriteBatchPush(
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pushes a 3D sprite to the batch. This is like spriteBatchPush but takes
|
* Pushes a 3D sprite to the batch.
|
||||||
* 3D coordinates instead of 2D.
|
*
|
||||||
*
|
|
||||||
* @param min The minimum (x,y,z) coordinate of the sprite.
|
* @param min The minimum (x,y,z) coordinate of the sprite.
|
||||||
* @param max The maximum (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 color The color to tint the sprite with.
|
||||||
* @param uvMin The texture coordinate for the top-left corner of the sprite.
|
* @param uvMin Texture coordinate for the top-left corner.
|
||||||
* @param uvMax The texture coordinate for the bottom-right corner of the sprite
|
* @param uvMax Texture coordinate for the bottom-right corner.
|
||||||
* @return An error code indicating success or failure.
|
* @return An error code indicating success or failure.
|
||||||
*/
|
*/
|
||||||
errorret_t spriteBatchPush3D(
|
errorret_t spriteBatchPushZ(
|
||||||
const vec3 min,
|
const vec3 min,
|
||||||
const vec3 max,
|
const vec3 max,
|
||||||
#if MESH_ENABLE_COLOR
|
#if MESH_ENABLE_COLOR
|
||||||
@@ -133,29 +147,20 @@ errorret_t spriteBatchPush3D(
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Buffers a sprite defined by a spritebatchsprite_t. Automatically flushes
|
* Clears the sprite batch. Calling flush after this renders nothing.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
void spriteBatchClear();
|
void spriteBatchClear();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flushes the sprite batch, rendering all queued sprites.
|
* Flushes the sprite batch, rendering all queued sprites.
|
||||||
*
|
*
|
||||||
* @return An error code indicating success or failure.
|
* @return An error code indicating success or failure.
|
||||||
*/
|
*/
|
||||||
errorret_t spriteBatchFlush();
|
errorret_t spriteBatchFlush();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disposes of the sprite batch, freeing any allocated resources.
|
* Disposes of the sprite batch, freeing any allocated resources.
|
||||||
*
|
*
|
||||||
* @return An error code indicating success or failure.
|
* @return An error code indicating success or failure.
|
||||||
*/
|
*/
|
||||||
errorret_t spriteBatchDispose();
|
errorret_t spriteBatchDispose();
|
||||||
|
|||||||
@@ -7,6 +7,10 @@
|
|||||||
|
|
||||||
#include "initialscene.h"
|
#include "initialscene.h"
|
||||||
#include "console/console.h"
|
#include "console/console.h"
|
||||||
|
#include "display/spritebatch/spritebatch.h"
|
||||||
|
#include "display/screen/screen.h"
|
||||||
|
|
||||||
|
#include "display/shader/shaderunlit.h"
|
||||||
|
|
||||||
void initialSceneInit(void) {
|
void initialSceneInit(void) {
|
||||||
consolePrint("Initial scene initialized");
|
consolePrint("Initial scene initialized");
|
||||||
@@ -17,6 +21,42 @@ errorret_t initialSceneUpdate(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
errorret_t initialSceneDraw(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();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+46
-29
@@ -34,27 +34,39 @@ errorret_t sceneInit(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
errorret_t sceneUpdate(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
|
#ifdef DUSK_TIME_DYNAMIC
|
||||||
if(TIME.dynamicUpdate) {
|
if(TIME.dynamicUpdate) {
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Dispose current scene.
|
if(SCENE.type != SCENE_TYPE_NULL && SCENE_FUNCTIONS[SCENE.type].update) {
|
||||||
if(SCENE.type != SCENE_TYPE_NULL) {
|
errorChain(SCENE_FUNCTIONS[SCENE.type].update());
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
@@ -63,25 +75,34 @@ errorret_t sceneUpdate(void) {
|
|||||||
dusktimeepoch_t LAST;
|
dusktimeepoch_t LAST;
|
||||||
|
|
||||||
errorret_t sceneRender(void) {
|
errorret_t sceneRender(void) {
|
||||||
mat4 view, proj;
|
mat4 model;
|
||||||
glm_ortho(
|
glm_mat4_identity(model);
|
||||||
0.0f, SCREEN.width,
|
|
||||||
SCREEN.height, 0.0f,
|
|
||||||
0.1f, 100.0f,
|
|
||||||
proj
|
|
||||||
);
|
|
||||||
|
|
||||||
errorChain(shaderBind(&SHADER_UNLIT));
|
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) {
|
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());
|
errorChain(SCENE_FUNCTIONS[SCENE.type].render());
|
||||||
}
|
}
|
||||||
|
|
||||||
// UI Rendering
|
// 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(
|
glm_lookat(
|
||||||
(vec3){ 0.0f, 0.0f, 1.0f },
|
(vec3){ 0.0f, 0.0f, 1.0f },
|
||||||
(vec3){ 0.0f, 0.0f, 0.0f },
|
(vec3){ 0.0f, 0.0f, 0.0f },
|
||||||
@@ -89,10 +110,6 @@ errorret_t sceneRender(void) {
|
|||||||
view
|
view
|
||||||
);
|
);
|
||||||
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_VIEW, 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){
|
errorChain(displaySetState((displaystate_t){
|
||||||
.flags = DISPLAY_STATE_FLAG_BLEND
|
.flags = DISPLAY_STATE_FLAG_BLEND
|
||||||
|
|||||||
@@ -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 = "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 = "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 } } },
|
{ .name = "rtrigger", { .type = INPUT_BUTTON_TYPE_GAMEPAD_AXIS, .gpAxis = { .axis = INPUT_GAMEPAD_AXIS_TRIGGER_RIGHT, .positive = true } } },
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{ .name = NULL }
|
{ .name = NULL }
|
||||||
@@ -47,6 +46,47 @@ inputbuttondata_t INPUT_BUTTON_DATA[] = {
|
|||||||
errorret_t inputInitDolphin(void) {
|
errorret_t inputInitDolphin(void) {
|
||||||
PAD_Init();
|
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();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -184,6 +184,52 @@ inputbuttondata_t INPUT_BUTTON_DATA[] = {
|
|||||||
{ .name = NULL },
|
{ .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) {
|
float_t inputGetDeadzoneSDL2(const inputbutton_t button) {
|
||||||
return 0.17f;
|
return 0.17f;
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -36,6 +36,26 @@ inputbuttondata_t INPUT_BUTTON_DATA[] = {
|
|||||||
{ .name = NULL }
|
{ .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) {
|
float_t inputGetDeadzoneSDL2(const inputbutton_t button) {
|
||||||
return 0.2f;
|
return 0.2f;
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
@@ -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;
|
|
||||||
@@ -44,6 +44,25 @@ typedef struct {
|
|||||||
#endif
|
#endif
|
||||||
} inputsdl2_t;
|
} 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.
|
* Updates the input state for SDL2.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user