From da1891aa0a053297e1b17bc34c23c362f9ac0c6b Mon Sep 17 00:00:00 2001 From: Connor Thomson Date: Wed, 9 Sep 2026 20:31:31 -0700 Subject: Add mouse movement --- src/camera.c | 47 +++++++++++++++++++++++++++++++++++++++-------- src/main.c | 1 + src/mouse.c | 5 +++++ src/obj_model.c | 6 ++++-- src/ta_math.c | 24 ++++++++++++++++++++++++ src/window.c | 1 + 6 files changed, 74 insertions(+), 10 deletions(-) create mode 100644 src/ta_math.c (limited to 'src') diff --git a/src/camera.c b/src/camera.c index ffb63cb..2699841 100644 --- a/src/camera.c +++ b/src/camera.c @@ -17,21 +17,52 @@ * along with this program. If not, see . */ +#include +#include "ta_math.h" #include "camera.h" -#include "ta_sdl.h" +#include "mouse.h" ta_camera ta_camera_current; +float ta_camera_sensitivity = 0.0025f; + void ta_camera_init(void) { - ta_camera_current = (ta_camera){ 0.0f, 0.0f, 5.0f }; + ta_camera_current = (ta_camera){ 0.0f, 0.0f, 5.0f, 0.0f, 0.0f }; } -void ta_camera_get_view_matrix(float *matrix) { - for (int index = 0; index < 16; index++) { - matrix[index] = index % 5 == 0 ? 1.0f : 0.0f; +void ta_camera_update(void) { + const float pitch_limit = ta_rad(90.0f); + + ta_camera_current.yaw -= ta_mouse_delta_x * ta_camera_sensitivity; + ta_camera_current.pitch += ta_mouse_delta_y * ta_camera_sensitivity; + + if (ta_camera_current.pitch > pitch_limit) { + ta_camera_current.pitch = pitch_limit; + } else if (ta_camera_current.pitch < -pitch_limit) { + ta_camera_current.pitch = -pitch_limit; } +} + +void ta_camera_get_view_matrix(float *matrix) { + float yaw_cosine = cosf(ta_camera_current.yaw); + float yaw_sine = sinf(ta_camera_current.yaw); + float pitch_cosine = cosf(ta_camera_current.pitch); + float pitch_sine = sinf(ta_camera_current.pitch); - matrix[12] = -ta_camera_current.x; - matrix[13] = -ta_camera_current.y; - matrix[14] = -ta_camera_current.z; + matrix[0] = yaw_cosine; + matrix[1] = -pitch_sine * yaw_sine; + matrix[2] = pitch_cosine * yaw_sine; + matrix[3] = 0.0f; + matrix[4] = 0.0f; + matrix[5] = pitch_cosine; + matrix[6] = pitch_sine; + matrix[7] = 0.0f; + matrix[8] = -yaw_sine; + matrix[9] = -pitch_sine * yaw_cosine; + matrix[10] = pitch_cosine * yaw_cosine; + matrix[11] = 0.0f; + matrix[12] = -yaw_cosine * ta_camera_current.x + yaw_sine * ta_camera_current.z; + matrix[13] = pitch_sine * yaw_sine * ta_camera_current.x - pitch_cosine * ta_camera_current.y + pitch_sine * yaw_cosine * ta_camera_current.z; + matrix[14] = -pitch_cosine * yaw_sine * ta_camera_current.x - pitch_sine * ta_camera_current.y - pitch_cosine * yaw_cosine * ta_camera_current.z; + matrix[15] = 1.0f; } \ No newline at end of file diff --git a/src/main.c b/src/main.c index 7e60569..1b3d1fc 100644 --- a/src/main.c +++ b/src/main.c @@ -60,6 +60,7 @@ static void ta_main_update(void) { #endif // ENABLE_AUDIO ta_gpu_start_frame(); ta_mouse_update(); + ta_camera_update(); ta_screen_update(); ta_gpu_end_frame(); } diff --git a/src/mouse.c b/src/mouse.c index 2ae3229..dbe8396 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -22,6 +22,8 @@ int ta_mouse_x; int ta_mouse_y; +float ta_mouse_delta_x; +float ta_mouse_delta_y; bool ta_mouse_click; void ta_mouse_update(void) { @@ -32,4 +34,7 @@ void ta_mouse_update(void) { ta_mouse_x = (int)x; ta_mouse_y = (int)y; ta_mouse_click = (buttons & SDL_BUTTON_LMASK) != 0; + ta_mouse_delta_x = 0.0f; + ta_mouse_delta_y = 0.0f; + SDL_GetRelativeMouseState(&ta_mouse_delta_x, &ta_mouse_delta_y); } \ No newline at end of file diff --git a/src/obj_model.c b/src/obj_model.c index ffbfcf3..6b11583 100644 --- a/src/obj_model.c +++ b/src/obj_model.c @@ -157,12 +157,14 @@ void ta_obj_model_render(const ta_obj_model *model, SDL_GPUCommandBuffer *comman uniforms.model[14] = model->position[2]; float aspect = (float)window_width / (float)window_height; float focal_length = 1.0f / tanf(22.5f * 0.01745329252f); + float near_plane = 0.1f; + float far_plane = 100.0f; ta_camera_get_view_matrix(view); projection[0] = focal_length / aspect; projection[5] = focal_length; - projection[10] = -101.0f / 99.0f; + projection[10] = far_plane / (near_plane - far_plane); projection[11] = -1.0f; - projection[14] = -200.0f / 99.0f; + projection[14] = near_plane * far_plane / (near_plane - far_plane); ta_obj_multiply(view_model, view, uniforms.model); ta_obj_multiply(uniforms.mvp, projection, view_model); SDL_PushGPUVertexUniformData(command_buffer, 0, &uniforms, sizeof(uniforms)); diff --git a/src/ta_math.c b/src/ta_math.c new file mode 100644 index 0000000..9d9e413 --- /dev/null +++ b/src/ta_math.c @@ -0,0 +1,24 @@ +/* + * Tuxánci 2 - A first person shooter + * Copyright (C) 2007-2011 Tuxánci Development Team + * Copyright (C) 2025-2026 Connor Thomson + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "ta_math.h" + +double ta_rad(double degrees) { + return degrees * (PI / (CIRCLE_DEG / 2)); +} \ No newline at end of file diff --git a/src/window.c b/src/window.c index fdcd31f..b03b0f9 100644 --- a/src/window.c +++ b/src/window.c @@ -36,6 +36,7 @@ void ta_window_init(void) { ta_sdl_init(SDL_INIT_VIDEO); ta_window = ta_sdl_create_window(TA_DEFAULT_WINDOW_TITLE, TA_DEFAULT_WINDOW_WIDTH, TA_DEFAULT_WINDOW_HEIGHT); + SDL_SetWindowRelativeMouseMode(ta_window, true); } void ta_window_update(void) { -- cgit v1.2.3