medfall

A super great game engine
Log | Files | Refs

commit ebc725d507ae1ac1d8b4ee7fb38ae1b62a97c183
parent 97a3d87c2d2b700495dee61b33812de0e4944d48
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Wed Aug 30 16:57:44 +0100

Press N for noclip

Diffstat:
array.h | 4++++
game.h | 4+++-
hm.cc | 241+++++++++++++++++++++++++++++++++++++++++--------------------------------------
keys.h | 12++++++------
main.cc | 7+++++++
5 files changed, 145 insertions(+), 123 deletions(-)
diff --git a/array.h b/array.h @@ -222,6 +222,10 @@ public: return elems; } + size_t size() const { + return N; + } + size_t num_bytes() const { return sizeof( T ) * N; } diff --git a/game.h b/game.h @@ -26,6 +26,7 @@ struct GameState { v3 pos, velocity; bool on_ground; + bool noclip; float pitch, yaw; TerrainManager tm; @@ -52,7 +53,8 @@ struct GameMemory { }; struct GameInput { - bool keys[ KEY_COUNT ]; + StaticArray< bool, KEY_COUNT > keys; + StaticArray< bool, KEY_COUNT > key_edges; double mouse_dx; double mouse_dy; }; diff --git a/hm.cc b/hm.cc @@ -68,6 +68,7 @@ GAME_INIT( game_init ) { game->pos = v3( 1500, 1500, 120 ); game->pos = v3( 1160, 1160, 3 ); + game->noclip = false; game->pitch = 0; game->yaw = 45; @@ -178,154 +179,161 @@ GAME_FRAME( game_frame ) { const float dsun = ( input->keys[ KEY_EQUALS ] - input->keys[ KEY_MINUS ] ) * dt * 0.25f; game->sun_angle += dsun; + if( input->keys[ KEY_N ] && input->key_edges[ KEY_N ] ) { + game->noclip = !game->noclip; + game->velocity = v3( 0 ); + } + const v3 world_up = v3( 0, 0, 1 ); v3 forward = v3_forward( game->pitch, game->yaw ); v3 right = normalize( cross( forward, world_up ) ); v3 up = normalize( cross( right, forward ) ); -#if 1 - if( game->on_ground ) { - if( input->keys[ KEY_SPACE ] ) { - game->velocity.z = 9.8; - game->on_ground = false; - } + if( game->noclip ) { + const float speed = 100.0f; + game->pos += forward * dt * fb * speed; + game->pos += right * dt * lr * speed; + game->pos.z += dt * dz * speed; } - - const float acceleration = 12; - if( game->on_ground ) { - // apply friction - if( dot( game->velocity, game->velocity ) < 0.01 ) { - game->velocity.x = 0; - game->velocity.y = 0; - } - else { - float current_speed = length( game->velocity ); - float drop = max( acceleration, current_speed ) * acceleration * dt / 2.0f; - float new_speed = max( 0.0f, current_speed - drop ); - game->velocity = new_speed * ( game->velocity / current_speed ); + else { + if( game->on_ground ) { + if( input->keys[ KEY_SPACE ] ) { + game->velocity.z = 9.8; + game->on_ground = false; + } } - if( fb != 0 || lr != 0 ) { - // apply acceleration - float max_speed = 10; + const float acceleration = 12; + if( game->on_ground ) { + // apply friction + if( dot( game->velocity, game->velocity ) < 0.01 ) { + game->velocity.x = 0; + game->velocity.y = 0; + } + else { + float current_speed = length( game->velocity ); + float drop = max( acceleration, current_speed ) * acceleration * dt / 2.0f; + float new_speed = max( 0.0f, current_speed - drop ); + game->velocity = new_speed * ( game->velocity / current_speed ); + } + + if( fb != 0 || lr != 0 ) { + // apply acceleration + float max_speed = 10; - v3 forward_xy = v3_forward_xy( game->yaw ); - v3 right_xy = normalize( cross( forward_xy, world_up ) ); - v3 desired_direction = fb * forward_xy + lr * right_xy; + v3 forward_xy = v3_forward_xy( game->yaw ); + v3 right_xy = normalize( cross( forward_xy, world_up ) ); + v3 desired_direction = fb * forward_xy + lr * right_xy; - desired_direction = normalize( desired_direction ); + desired_direction = normalize( desired_direction ); - float speed_in_desired_direction = dot( game->velocity, desired_direction ); + float speed_in_desired_direction = dot( game->velocity, desired_direction ); - if( speed_in_desired_direction < max_speed ) { - float accel_speed = min( acceleration * dt * max_speed, max_speed - speed_in_desired_direction ); - game->velocity += accel_speed * desired_direction; + if( speed_in_desired_direction < max_speed ) { + float accel_speed = min( acceleration * dt * max_speed, max_speed - speed_in_desired_direction ); + game->velocity += accel_speed * desired_direction; + } } } - } - int spins = 0; - float remaining_t = dt; - while( remaining_t > 0 && spins < 5 ) { - spins++; - if( game->on_ground ) { - const float step_height = 0.1f; + int spins = 0; + float remaining_t = dt; + while( remaining_t > 0 && spins < 5 ) { + spins++; + if( game->on_ground ) { + const float step_height = 0.1f; - v3 low_start = game->pos; - v3 low_end = low_start + game->velocity * remaining_t; + v3 low_start = game->pos; + v3 low_end = low_start + game->velocity * remaining_t; - v3 high_start = game->pos + v3( 0, 0, step_height ); - v3 high_end = high_start + game->velocity * remaining_t; + v3 high_start = game->pos + v3( 0, 0, step_height ); + v3 high_end = high_start + game->velocity * remaining_t; - float low_t; - // initialise high_t to -1 so we never pick the high trace - // if we couldn't step up (fails the high_t > low_t test) - float high_t = -1; - v3 low_normal, high_normal; + float low_t; + // initialise high_t to -1 so we never pick the high trace + // if we couldn't step up (fails the high_t > low_t test) + float high_t = -1; + v3 low_normal, high_normal; - bool low_hit = segment_vs_terrain( &game->tm, low_start, low_end, &low_t, &low_normal ); - bool high_hit = false; + bool low_hit = segment_vs_terrain( &game->tm, low_start, low_end, &low_t, &low_normal ); + bool high_hit = false; - bool step_up_hit = segment_vs_terrain( &game->tm, low_start, high_start, NULL, NULL ); - if( !step_up_hit ) { - high_hit = segment_vs_terrain( &game->tm, high_start, high_end, &high_t, &high_normal ); - } + bool step_up_hit = segment_vs_terrain( &game->tm, low_start, high_start, NULL, NULL ); + if( !step_up_hit ) { + high_hit = segment_vs_terrain( &game->tm, high_start, high_end, &high_t, &high_normal ); + } - v3 step_down_start; - float step_down_distance; - bool should_step_down = false; + v3 step_down_start; + float step_down_distance; + bool should_step_down = false; - if( high_t > low_t ) { - if( high_hit ) { - game->pos = high_start + game->velocity * high_t * remaining_t; - remaining_t = ( 1.0f - high_t ) * remaining_t; + if( high_t > low_t ) { + if( high_hit ) { + game->pos = high_start + game->velocity * high_t * remaining_t; + remaining_t = ( 1.0f - high_t ) * remaining_t; + } + else { + step_down_start = high_end; + step_down_distance = step_height * 2; + should_step_down = true; + remaining_t = 0; + } } else { - step_down_start = high_end; - step_down_distance = step_height * 2; - should_step_down = true; - remaining_t = 0; + if( low_hit ) { + game->pos = low_start + game->velocity * low_t * remaining_t; + remaining_t = ( 1.0f - low_t ) * remaining_t; + } + else { + step_down_start = low_end; + step_down_distance = step_height; + should_step_down = true; + remaining_t = 0; + } + } + + if( should_step_down ) { + float step_down_t; + v3 step_down_end = step_down_start - v3( 0, 0, step_down_distance ); + + bool step_down_hit = segment_vs_terrain( &game->tm, step_down_start, step_down_end, &step_down_t, NULL ); + + game->pos = lerp( step_down_start, step_down_t, step_down_end ); + game->on_ground = step_down_hit; } } - else { - if( low_hit ) { - game->pos = low_start + game->velocity * low_t * remaining_t; - remaining_t = ( 1.0f - low_t ) * remaining_t; + + // TODO: this might be quite harmful + if( !game->on_ground ) { + // TODO: rk4 integration + const float gravity = -30.0f; + game->velocity += v3( 0, 0, gravity ) * remaining_t; + + v3 end = game->pos + game->velocity * remaining_t; + float t; + v3 normal; + bool hit = segment_vs_terrain( &game->tm, game->pos, end, &t, &normal ); + if( hit ) { + // TODO: check normal is flat enough, otherwise stay in the air + game->on_ground = true; + game->pos += game->velocity * t * remaining_t; + // TODO: truncate velocity + game->velocity.z = 0; + + remaining_t = ( 1.0f - t ) * remaining_t; } else { - step_down_start = low_end; - step_down_distance = step_height; - should_step_down = true; + game->pos = end; remaining_t = 0; } } - if( should_step_down ) { - float step_down_t; - v3 step_down_end = step_down_start - v3( 0, 0, step_down_distance ); - - bool step_down_hit = segment_vs_terrain( &game->tm, step_down_start, step_down_end, &step_down_t, NULL ); - - game->pos = lerp( step_down_start, step_down_t, step_down_end ); - game->on_ground = step_down_hit; - } - } - - if( !game->on_ground ) { - // TODO: rk4 integration - const float gravity = -30.0f; - game->velocity += v3( 0, 0, gravity ) * remaining_t; - - v3 end = game->pos + game->velocity * remaining_t; - float t; - v3 normal; - bool hit = segment_vs_terrain( &game->tm, game->pos, end, &t, &normal ); - if( hit ) { - // TODO: check normal is flat enough, otherwise stay in the air - game->on_ground = true; - game->pos += game->velocity * t * remaining_t; - // TODO: truncate velocity - game->velocity.z = 0; - - remaining_t = ( 1.0f - t ) * remaining_t; + if( game->on_ground ) { + // move up 1mm so float imprecision doesn't make us fall through the world + game->pos.z += 0.001f; } - else { - game->pos = end; - remaining_t = 0; - } - } - - if( game->on_ground ) { - // move up 1mm so float imprecision doesn't make us fall through the world - game->pos.z += 0.001f; } } -#else - const float speed = 100.0f; - game->pos += forward * dt * fb * speed; - game->pos += right * dt * lr * speed; - game->pos.z += dt * dz * speed; -#endif terrain_update( &game->tm, game->pos ); @@ -543,11 +551,12 @@ GAME_FRAME( game_frame ) { } { - const str< 128 > status( "Frame time: {.1}ms FPS: {.1} {} {.1}", + const str< 128 > status( "Frame time: {.1}ms FPS: {.1} {} {.1} noclip: {}", dt * 1000.0f, 1.0f / dt, - connected ? "connected!" : "connecting", game->pos ); + connected ? "connected!" : "connecting", game->pos, + game->noclip ); draw_text( status.c_str(), 2, 2, 16.0f ); - draw_text( str< 128 >( "velocity = {.1}, speed = {.2}", game->velocity, length( game->velocity.xy() ) ).c_str(), 2, 20, 16 ); + draw_text( str< 128 >( "velocity = {.1}, speed = {.2}, sun_angle = {.2}", game->velocity, length( game->velocity.xy() ), game->sun_angle ).c_str(), 2, 20, 16 ); } } diff --git a/keys.h b/keys.h @@ -18,12 +18,12 @@ enum KeyNames { KEY_J = 'j', KEY_K = 'k', KEY_L = 'l', - // KEY_M, - // KEY_N, - // KEY_O, - // KEY_P, - // KEY_Q, - // KEY_R, + KEY_M = 'm', + KEY_N = 'n', + KEY_O = 'o', + KEY_P = 'p', + KEY_Q = 'q', + KEY_R = 'r', KEY_S = 's', KEY_T = 't', // KEY_U, diff --git a/main.cc b/main.cc @@ -53,6 +53,7 @@ int main( int argc, char ** argv ) { const double program_start_time = glfwGetTime(); double last_frame_time = program_start_time; + GameInput last_input = { }; u64 total_frames = 0; _MM_SET_DENORMALS_ZERO_MODE( _MM_DENORMALS_ZERO_ON ); @@ -81,6 +82,7 @@ int main( int argc, char ** argv ) { input.keys[ KEY_J ] = glfwGetKey( window, GLFW_KEY_J ) == GLFW_PRESS; input.keys[ KEY_K ] = glfwGetKey( window, GLFW_KEY_K ) == GLFW_PRESS; input.keys[ KEY_L ] = glfwGetKey( window, GLFW_KEY_L ) == GLFW_PRESS; + input.keys[ KEY_N ] = glfwGetKey( window, GLFW_KEY_N ) == GLFW_PRESS; input.keys[ KEY_S ] = glfwGetKey( window, GLFW_KEY_S ) == GLFW_PRESS; input.keys[ KEY_T ] = glfwGetKey( window, GLFW_KEY_T ) == GLFW_PRESS; input.keys[ KEY_W ] = glfwGetKey( window, GLFW_KEY_W ) == GLFW_PRESS; @@ -108,6 +110,10 @@ int main( int argc, char ** argv ) { input.keys[ KEY_F11 ] = glfwGetKey( window, GLFW_KEY_F11 ) == GLFW_PRESS; input.keys[ KEY_F12 ] = glfwGetKey( window, GLFW_KEY_F12 ) == GLFW_PRESS; + for( size_t i = 0; i < input.keys.size(); i++ ) { + input.key_edges[ i ] = input.keys[ i ] != last_input.keys[ i ]; + } + break1 = input.keys[ KEY_F1 ]; break2 = input.keys[ KEY_F2 ]; break3 = input.keys[ KEY_F3 ]; @@ -130,6 +136,7 @@ int main( int argc, char ** argv ) { glfwPollEvents(); last_frame_time = current_frame_time; + last_input = input; total_frames++; unsigned int csr = _mm_getcsr();