tunnel-runner

Pseudo 3D tunnel effect.
Log | Files | Refs | README | LICENSE

commit 7c3ab02bc9f44aadfcfc991580686bd5752412c8
parent 87bdd1403b0d82ec0fc965009a17a2886c233da0
Author: Amin Mesbah <mesbah.amin@gmail.com>
Date:   Fri, 17 Mar 2017 13:15:22 -0700

Fix lag and jitter.

I'm still working out the difference between getting input, updating
state, and rendering. Before I was rendering way more often than I
needed too. Now the rendering happens once per frame, as it should.

For each tick of the main loop, updates are processed as many times as
necessary to catch the game state up to where it should be based on
real-world time.

I'm now in a good position to simulate some basic physics for the
player's movement.

Diffstat:
Msdl_tunnel_runner.cpp | 239++++++++++++++++++++++++++++++++++++++++---------------------------------------
1 file changed, 120 insertions(+), 119 deletions(-)

diff --git a/sdl_tunnel_runner.cpp b/sdl_tunnel_runner.cpp @@ -1,4 +1,5 @@ #include <cmath> +#include <inttypes.h> #include <SDL.h> #include <stdio.h> #include <stdint.h> @@ -37,7 +38,7 @@ typedef uint64_t uint64; #define SECOND 1000.0f #define FPS 60 #define MS_PER_FRAME (SECOND / FPS) -#define UPDATES_PER_SECOND 65 +#define UPDATES_PER_SECOND 120 #define MS_PER_UPDATE (SECOND / UPDATES_PER_SECOND) @@ -478,140 +479,140 @@ int main(void) lag += elapsed_ms; //printf("Lag: %d\n", lag); - SDL_Event event; - - while (SDL_PollEvent(&event)) + printf("%" PRIu64 ", %f\n", lag, MS_PER_UPDATE); + while (lag >= MS_PER_UPDATE) { - if (handle_event(&event)) + SDL_Event event; + + while (SDL_PollEvent(&event)) { - running = false; + running = !handle_event(&event); } - } - SDL_PumpEvents(); + SDL_PumpEvents(); - dimension = sdl_get_window_dimension(window); + dimension = sdl_get_window_dimension(window); - const uint8 *keystate = SDL_GetKeyboardState(0); + const uint8 *keystate = SDL_GetKeyboardState(0); - if (keystate[SDL_SCANCODE_A]) - { - rotation_offset -= MOVEMENT_SPEED; - } - if (keystate[SDL_SCANCODE_D]) - { - rotation_offset += MOVEMENT_SPEED; - } - if (keystate[SDL_SCANCODE_W]) - { - translation_offset += MOVEMENT_SPEED; - } - if (keystate[SDL_SCANCODE_S]) - { - translation_offset -= MOVEMENT_SPEED; - } - if (keystate[SDL_SCANCODE_LEFT]) - { - rotation_offset --; - } - if (keystate[SDL_SCANCODE_RIGHT]) - { - rotation_offset ++; - } - if (keystate[SDL_SCANCODE_UP]) - { - translation_offset ++; - } - if (keystate[SDL_SCANCODE_DOWN]) - { - translation_offset --; - } - - - for (int controller_index = 0; controller_index < MAX_CONTROLLERS; ++controller_index) - { - if (SDL_GameControllerGetAttached(controller_handles[controller_index])) + if (keystate[SDL_SCANCODE_A]) { - bool start = SDL_GameControllerGetButton(controller_handles[controller_index], SDL_CONTROLLER_BUTTON_START); - bool back = SDL_GameControllerGetButton(controller_handles[controller_index], SDL_CONTROLLER_BUTTON_BACK); - bool a_button = SDL_GameControllerGetButton(controller_handles[controller_index], SDL_CONTROLLER_BUTTON_A); - bool b_button = SDL_GameControllerGetButton(controller_handles[controller_index], SDL_CONTROLLER_BUTTON_B); - bool x_button = SDL_GameControllerGetButton(controller_handles[controller_index], SDL_CONTROLLER_BUTTON_X); - bool y_button = SDL_GameControllerGetButton(controller_handles[controller_index], SDL_CONTROLLER_BUTTON_Y); - bool left_shoulder = SDL_GameControllerGetButton(controller_handles[controller_index], SDL_CONTROLLER_BUTTON_LEFTSHOULDER); - bool right_shoulder = SDL_GameControllerGetButton(controller_handles[controller_index], SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); - - int16 stick_leftx = SDL_GameControllerGetAxis(controller_handles[controller_index], SDL_CONTROLLER_AXIS_LEFTX); - int16 stick_lefty = SDL_GameControllerGetAxis(controller_handles[controller_index], SDL_CONTROLLER_AXIS_LEFTY); - int16 stick_rightx = SDL_GameControllerGetAxis(controller_handles[controller_index], SDL_CONTROLLER_AXIS_RIGHTX); - int16 stick_righty = SDL_GameControllerGetAxis(controller_handles[controller_index], SDL_CONTROLLER_AXIS_RIGHTY); - - if (start) - { - SDL_HapticRumblePlay(rumble_handles[controller_index], 0.5f, 2000); - color_choice = '\0'; - } - else - { - SDL_HapticRumbleStop(rumble_handles[controller_index]); - } + rotation_offset -= MOVEMENT_SPEED; + } + if (keystate[SDL_SCANCODE_D]) + { + rotation_offset += MOVEMENT_SPEED; + } + if (keystate[SDL_SCANCODE_W]) + { + translation_offset += MOVEMENT_SPEED; + } + if (keystate[SDL_SCANCODE_S]) + { + translation_offset -= MOVEMENT_SPEED; + } + if (keystate[SDL_SCANCODE_LEFT]) + { + rotation_offset --; + } + if (keystate[SDL_SCANCODE_RIGHT]) + { + rotation_offset ++; + } + if (keystate[SDL_SCANCODE_UP]) + { + translation_offset ++; + } + if (keystate[SDL_SCANCODE_DOWN]) + { + translation_offset --; + } - if (back) - { - running = false; - } - // NOTE(amin): Buttons select colors. - if (a_button) - { - color_choice = 'g'; - } - if (b_button) - { - color_choice = 'r'; - } - if (x_button) - { - color_choice = 'b'; - } - if (y_button) - { - color_choice = 'y'; - } - if (left_shoulder) - { - color_choice = 'm'; - } - if (right_shoulder) + for (int controller_index = 0; controller_index < MAX_CONTROLLERS; ++controller_index) + { + if (SDL_GameControllerGetAttached(controller_handles[controller_index])) { - color_choice = 'c'; + bool start = SDL_GameControllerGetButton(controller_handles[controller_index], SDL_CONTROLLER_BUTTON_START); + bool back = SDL_GameControllerGetButton(controller_handles[controller_index], SDL_CONTROLLER_BUTTON_BACK); + bool a_button = SDL_GameControllerGetButton(controller_handles[controller_index], SDL_CONTROLLER_BUTTON_A); + bool b_button = SDL_GameControllerGetButton(controller_handles[controller_index], SDL_CONTROLLER_BUTTON_B); + bool x_button = SDL_GameControllerGetButton(controller_handles[controller_index], SDL_CONTROLLER_BUTTON_X); + bool y_button = SDL_GameControllerGetButton(controller_handles[controller_index], SDL_CONTROLLER_BUTTON_Y); + bool left_shoulder = SDL_GameControllerGetButton(controller_handles[controller_index], SDL_CONTROLLER_BUTTON_LEFTSHOULDER); + bool right_shoulder = SDL_GameControllerGetButton(controller_handles[controller_index], SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); + + int16 stick_leftx = SDL_GameControllerGetAxis(controller_handles[controller_index], SDL_CONTROLLER_AXIS_LEFTX); + int16 stick_lefty = SDL_GameControllerGetAxis(controller_handles[controller_index], SDL_CONTROLLER_AXIS_LEFTY); + int16 stick_rightx = SDL_GameControllerGetAxis(controller_handles[controller_index], SDL_CONTROLLER_AXIS_RIGHTX); + int16 stick_righty = SDL_GameControllerGetAxis(controller_handles[controller_index], SDL_CONTROLLER_AXIS_RIGHTY); + + if (start) + { + SDL_HapticRumblePlay(rumble_handles[controller_index], 0.5f, 2000); + color_choice = '\0'; + } + else + { + SDL_HapticRumbleStop(rumble_handles[controller_index]); + } + + if (back) + { + running = false; + } + + // NOTE(amin): Buttons select colors. + if (a_button) + { + color_choice = 'g'; + } + if (b_button) + { + color_choice = 'r'; + } + if (x_button) + { + color_choice = 'b'; + } + if (y_button) + { + color_choice = 'y'; + } + if (left_shoulder) + { + color_choice = 'm'; + } + if (right_shoulder) + { + color_choice = 'c'; + } + + rotation_offset += stick_leftx / 5000; + translation_offset -= stick_lefty / 5000; + + int dampened_x_max = dimension.width / 2; + int dampened_x_min = -(dimension.width / 2); + int dampened_y_max = dimension.height / 2; + int dampened_y_min = -(dimension.height / 2); + + int dampened_x = (stick_rightx - CONTROLLER_STICK_MIN) * (dampened_x_max - dampened_x_min) / (CONTROLLER_STICK_MAX - CONTROLLER_STICK_MIN) + dampened_x_min; + int dampened_y = (stick_righty - CONTROLLER_STICK_MIN) * (dampened_y_max - dampened_y_min) / (CONTROLLER_STICK_MAX - CONTROLLER_STICK_MIN) + dampened_y_min; + + transform.look_shift_x = dimension.width / 2 + dampened_x; + transform.look_shift_y = dimension.height / 2 + dampened_y; + //printf("dimension.width / 2: %d\t damp_x: %d\t raw_x: %d\n", dimension.width / 2, dampened_x, stick_rightx); + //printf("dimension.height / 2: %d\t damp_y: %d\t raw_y: %d\n", dimension.height / 2, dampened_y, stick_righty); } - - rotation_offset += stick_leftx / 5000; - translation_offset -= stick_lefty / 5000; - - int dampened_x_max = dimension.width / 2; - int dampened_x_min = -(dimension.width / 2); - int dampened_y_max = dimension.height / 2; - int dampened_y_min = -(dimension.height / 2); - - int dampened_x = (stick_rightx - CONTROLLER_STICK_MIN) * (dampened_x_max - dampened_x_min) / (CONTROLLER_STICK_MAX - CONTROLLER_STICK_MIN) + dampened_x_min; - int dampened_y = (stick_righty - CONTROLLER_STICK_MIN) * (dampened_y_max - dampened_y_min) / (CONTROLLER_STICK_MAX - CONTROLLER_STICK_MIN) + dampened_y_min; - - transform.look_shift_x = dimension.width / 2 + dampened_x; - transform.look_shift_y = dimension.height / 2 + dampened_y; - //printf("dimension.width / 2: %d\t damp_x: %d\t raw_x: %d\n", dimension.width / 2, dampened_x, stick_rightx); - //printf("dimension.height / 2: %d\t damp_y: %d\t raw_y: %d\n", dimension.height / 2, dampened_y, stick_righty); } - } - printf("%d, %d\n", translation_offset, rotation_offset); + //printf("%d, %d\n", translation_offset, rotation_offset); - while (lag >= MS_PER_UPDATE) - { - render_tunnel(global_back_buffer, texture, rotation_offset, translation_offset, color_choice); - //render_texture(global_back_buffer, texture, rotation_offset, translation_offset, color_choice); + printf("\t%" PRIu64 ", %f\n", lag, MS_PER_UPDATE); + //render_tunnel(global_back_buffer, texture, rotation_offset, translation_offset, color_choice); lag -= MS_PER_UPDATE; } + render_tunnel(global_back_buffer, texture, rotation_offset, translation_offset, color_choice); + //render_texture(global_back_buffer, texture, rotation_offset, translation_offset, color_choice); sdl_update_window(window, renderer, global_back_buffer); if (elapsed_ms <= MS_PER_FRAME) {