RGBA textures
This commit is contained in:
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
@@ -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
|
||||
);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#if DOLPHIN
|
||||
#include <ogcsys.h>
|
||||
#include <gccore.h>
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
typedef bool bool_t;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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.");
|
||||
|
||||
Reference in New Issue
Block a user