summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonAki <konaki@anokonaki.org>2026-10-11 16:58:55 +0800
committerKonAki <konaki@anokonaki.org>2026-10-11 16:58:55 +0800
commitcbde2ee49bf1a94ee38106ef229db89812538de4 (patch)
tree5ba2aeb3d66bc34445198105e6eb4c1bbf4f1f91
parentafa49424839562edc89020c1b376135b9b44e6c9 (diff)
handmade: mouse look, texture table
-rw-r--r--examples/handmade.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/examples/handmade.c b/examples/handmade.c
index 072106e..f2f6847 100644
--- a/examples/handmade.c
+++ b/examples/handmade.c
@@ -6,7 +6,8 @@
* and build it (linux): cc -std=c99 -o handmade handmade.c -lX11 -lXext -lXrandr -lm
* (windows): cc -std=c99 -o handmade.exe handmade.c -lgdi32 -lm
*
- * the map is text inside this file and the gem is a list of vertices. w and s walk, a and d strafe, left and right turn, escape quits
+ * the map is text inside this file and the gem is a list of vertices. click to grab the mouse and look around, tab lets go.
+ * w and s walk, a and d strafe, left and right turn, escape quits. which picture goes on which texture name is the table in textures[]
*/
#define KONWINLIB_IMPLEMENTATION
@@ -80,7 +81,7 @@ typedef struct state {
kon_sectorMesh_t *mesh;
kon_material_t materials[8];
kon_image *mark;
- float x, z, yaw;
+ float x, z, yaw, pitch;
int sector;
int forward, strafe, turn;
kon_time last, time;
@@ -103,11 +104,20 @@ static kon_image *makeMark(void)
return image;
}
+/* the names the map uses and what they look like. a name that is not in here is grey */
+static const struct { const char *name; uint32_t color; } textures[] = {
+ { "stone", 0xFF6C6688 },
+ { "brick", 0xFF8A5560 },
+ { "plaster", 0xFFB5AECB },
+};
+
static uint32_t colorOf(const char *name)
{
- if (!strcmp(name, "stone")) return 0xFF6C6688;
- if (!strcmp(name, "brick")) return 0xFF8A5560;
- if (!strcmp(name, "plaster")) return 0xFFB5AECB;
+ size_t i;
+
+ for (i = 0; i < sizeof(textures) / sizeof(textures[0]); i++) {
+ if (strcmp(name, textures[i].name) == 0) return textures[i].color;
+ }
return 0xFF9A93B3;
}
@@ -159,6 +169,14 @@ static void frame(void *data)
int down = ev.type == KON_EVENT_KEY_DOWN;
if (ev.type == KON_EVENT_RESIZE) kon_resizeDisplay(state->display, ev.width, ev.height);
+ if (ev.type == KON_EVENT_MOUSE_MOVE && kon_isMouseCaptured(state->window)) {
+ state->yaw += (float)ev.mouseDX * 0.0015f;
+ state->pitch -= (float)ev.mouseDY * 0.0015f;
+ if (state->pitch > 1.2f) state->pitch = 1.2f;
+ if (state->pitch < -1.2f) state->pitch = -1.2f;
+ }
+ if (ev.type == KON_EVENT_MOUSE_DOWN && !kon_isMouseCaptured(state->window)) kon_setMouseCapture(state->window, true);
+ if (ev.type == KON_EVENT_KEY_DOWN && ev.key == KON_KEY_TAB) kon_setMouseCapture(state->window, !kon_isMouseCaptured(state->window));
if (ev.type != KON_EVENT_KEY_DOWN && ev.type != KON_EVENT_KEY_UP) continue;
switch (ev.key) {
case KON_KEY_W: state->forward = down ? 1 : (state->forward > 0 ? 0 : state->forward); break;
@@ -175,7 +193,7 @@ static void frame(void *data)
walk(state, (fx * (float)state->forward - fz * (float)state->strafe) * step, (fz * (float)state->forward + fx * (float)state->strafe) * step);
camera.position = KON_VEC3(state->x, state->map->sectors[state->sector].floor + EYE, state->z);
- camera.target = KON_VEC3(state->x + fx, camera.position.y, state->z + fz);
+ camera.target = KON_VEC3(state->x + fx * cosf(state->pitch), camera.position.y + sinf(state->pitch), state->z + fz * cosf(state->pitch));
camera.fov = KON_DEG2RAD(60);
camera.nearZ = 0.05f;
camera.farZ = 40.0f;