diff options
Diffstat (limited to 'src/game')
| -rw-r--r-- | src/game/assets.cpp | 5 | ||||
| -rw-r--r-- | src/game/camera.h | 9 | ||||
| -rw-r--r-- | src/game/player.cpp | 133 | ||||
| -rw-r--r-- | src/game/player.h | 13 | ||||
| -rw-r--r-- | src/game/raycast.cpp | 2 | ||||
| -rw-r--r-- | src/game/world/bsp.cpp | 89 | ||||
| -rw-r--r-- | src/game/world/bsp.h | 5 | ||||
| -rw-r--r-- | src/game/world/draw.cpp | 2 | ||||
| -rw-r--r-- | src/game/world/trace.cpp | 4 |
9 files changed, 227 insertions, 35 deletions
diff --git a/src/game/assets.cpp b/src/game/assets.cpp index 7d755c0..62663a9 100644 --- a/src/game/assets.cpp +++ b/src/game/assets.cpp @@ -3,8 +3,11 @@ #include "../game.h" #include "../render/gl_2d_font.h" +#include "../util/stb_image.h" +#include "../util/anim.h" + void assets_init( GAME_DATA *game ) { - game->assets.test = gl_texture_create( game->gl, "assets/test.png" ); + game->assets.test = gl_texture_from_file( game->gl, "uvtest.png" ); game->assets.fonts_init = 0; } diff --git a/src/game/camera.h b/src/game/camera.h new file mode 100644 index 0000000..b9fe402 --- /dev/null +++ b/src/game/camera.h @@ -0,0 +1,9 @@ +#pragma once + +#include "../util/vector.h" + +struct PLAYER_CAMERA { + VEC3 pos; + VEC3 rot; + F32 fov; +}; diff --git a/src/game/player.cpp b/src/game/player.cpp index 87786df..51d1cf8 100644 --- a/src/game/player.cpp +++ b/src/game/player.cpp @@ -2,6 +2,7 @@ #include "SDL_scancode.h" #include "objlist.h" #include "world/trace.h" +#include <cmath> #include "player.h" F32 PLAYER_HULL_HEIGHT = 50.f; @@ -30,50 +31,132 @@ PLAYER* player_create( VEC3 origin, F32 yaw ) { return p; } -void player_input( GAME_DATA* game, PLAYER* p ) { - F32* yaw = &p->rot.y; - VEC3* pos = &p->pos; +void capture_mouse( PLAYER* p ) { + F32* yaw = &p->input.cam.pos.y; + F32* pitch = &p->input.cam.pos.x; + if( input.keys[SDL_SCANCODE_F1] ) { + input_capture_mouse( false ); + } - if( input.keys[(U8)'a'] ) - *yaw -= 360.f * TICK_INTERVAL * 0.5f; - if( input.keys[(U8)'d'] ) - *yaw += 360.f * TICK_INTERVAL * 0.5f; + if( input.mouselock ) { + *yaw += input.mouse.pos_delta.x * input.msens; + *pitch -= input.mouse.pos_delta.y * input.msens; - if( input.keys[SDL_SCANCODE_UP] ) { - if( p->rot.x < 89.f ) - p->rot.x += 360.f * TICK_INTERVAL * 0.5f; - } - if( input.keys[SDL_SCANCODE_DOWN] ) { - if( p->rot.x > -89.f ) - p->rot.x -= 360.f * TICK_INTERVAL * 0.5f; + if( *pitch > 89.f ) *pitch = 89.f; + if( *pitch < -89.f ) *pitch = -89.f; + + input_reset_mouse_accumulator(); } *yaw = remainderf( *yaw, 360.f ); + p->rot.x = *pitch; + p->rot.y = *yaw; +} +void capture_move_keys( PLAYER* p ) { + VEC2* move = &p->input.move; + if( input.keys[input.binds.fwd] ) { + if( !p->input.fwd_held ) + move->x = 1.f; + p->input.fwd_held = true; + } else { + if( p->input.fwd_held ) { + if( p->input.bk_held ) + move->x = -1.f; + else + move->x = 0.f; + } + p->input.fwd_held = false; + } - VEC3 wishmove; - VEC3 dir = m_radial_offset( *yaw, 70.f ); - if( input.keys[(U8)'w'] ) { - wishmove = dir * TICK_INTERVAL; + if( input.keys[input.binds.back] ) { + if( !p->input.bk_held ) + move->x = -1.f; + p->input.bk_held = true; + } else { + if( p->input.bk_held ) { + if( p->input.fwd_held ) + move->x = 1.f; + else + move->x = 0.f; + } + p->input.bk_held = false; } - if( input.keys[(U8)'s'] ) { - wishmove = dir * -TICK_INTERVAL; + + if( input.keys[input.binds.left] ) { + if( !p->input.left_held ) + move->y = -1.f; + p->input.left_held = true; + } else { + if( p->input.left_held ) { + if( p->input.right_held ) + move->y = 1.f; + else + move->y = 0.f; + } + p->input.left_held = false; } + if( input.keys[input.binds.right] ) { + if( !p->input.right_held ) + move->y = 1.f; + p->input.right_held = true; + } else { + if( p->input.right_held ) { + if( p->input.left_held ) + move->y = -1.f; + else + move->y = 0.f; + } + p->input.right_held = false; + } +} + +void player_input( GAME_DATA* game, PLAYER* p ) { + if( !p ) + return; + + capture_mouse( p ); + capture_move_keys( p ); +} + +void player_move( GAME_DATA* game, PLAYER* p ) { + VEC2 move = p->input.move; + F32 yawrad = m_deg2rad( p->rot.y ); + + VEC3 wishdir = { + move.x * cosf( yawrad ) - move.y * sinf( yawrad ), + move.y * cosf( yawrad ) + move.x * sinf( yawrad ), + 0 + }; + + VEC3 vel = wishdir * 70.f; + p->velocity = vel; + VEC3 wishmove = vel * TICK_INTERVAL; // todo : should never be false if( vec_len( wishmove ) > BSP_TRACE_EPSILON && game->state.map->bsp ) { BSP_TRACE tr{}; AABB aabb{}; - tr.in_start = *pos; - tr.in_end = *pos + wishmove * 2.f; + tr.in_start = p->pos; + tr.in_end = tr.in_start + wishmove; aabb.min = p->mins; aabb.max = p->maxs; bsp_trace( &tr, game->state.map->bsp, aabb ); if( !tr.hit ) - *pos += wishmove; - else - *pos += wishmove * tr.frac; + p->pos += wishmove; + else { + p->pos += wishmove * tr.frac; + + + // TODO: clipvelocity fixes this, clips velocity to 1 wall (should do 4) + VEC3 left = wishmove * (1.f - tr.frac); + F32 into = vec_dot( left, tr.normal ); + if( into < 0.f ) + left -= tr.normal * into; + + p->pos += left; + } } } diff --git a/src/game/player.h b/src/game/player.h index 71b1c02..6617f01 100644 --- a/src/game/player.h +++ b/src/game/player.h @@ -1,8 +1,16 @@ #pragma once #include "object.h" +#include "camera.h" + struct PLAYER_INPUT { - + PLAYER_CAMERA cam; + struct PLAYER* pobj; + + // for nulls + U8 fwd_held{}, bk_held{}, left_held{}, right_held{}; + + VEC2 move; }; struct PLAYER : OBJECT { @@ -11,6 +19,8 @@ struct PLAYER : OBJECT { F32 fov{72.f}; F32 eyeoffset{40.f}; + PLAYER_INPUT input; + VEC3 mins; VEC3 maxs; @@ -19,4 +29,5 @@ struct PLAYER : OBJECT { extern PLAYER* player_create( VEC3 origin, F32 yaw ); extern void player_input( struct GAME_DATA* game, PLAYER* player ); +extern void player_move( struct GAME_DATA* game, PLAYER* player ); extern VEC3 player_get_view_pos( PLAYER* player ); diff --git a/src/game/raycast.cpp b/src/game/raycast.cpp index c82a3ed..d38eb0a 100644 --- a/src/game/raycast.cpp +++ b/src/game/raycast.cpp @@ -126,7 +126,7 @@ U32 ray_trace( TRACE* tr, VEC3 end ) { } void draw_player( GAME_DATA* game, PLAYER* pl ) { - GL_PROGRAM* gl2d = game->shaders.gl2d; + GL_SHADER_PROGRAM* gl2d = game->shaders.gl2d; VEC2 xy = { pl->pos.x, pl->pos.y }; gl_2d_frect( gl2d, xy - VEC2{ 5.f, 5.f }, { 10.f, 10.f }, CLR::RED() ); diff --git a/src/game/world/bsp.cpp b/src/game/world/bsp.cpp index 9aa94d7..a95a693 100644 --- a/src/game/world/bsp.cpp +++ b/src/game/world/bsp.cpp @@ -637,7 +637,89 @@ U8 pvs_get( BSP_BITSET* pvs, U32 count, U32 cluster, U32 seen ) { U32 w = seen / 32, b = seen % 32; if( base + w >= pvs->size ) return 0; - return ( pvs->data[base + w] >> b) & 1u; + return (pvs->data[base + w] >> b) & 1u; +} + +void bsp_build_pvs( BSP* bsp ) { + U32 nclusters = bsp->leaves.size; + bsp->pvs_bits.clear(); + bsp->clusters.clear(); + bsp->clusters.reserve( nclusters ); + + LIST<LIST<I32>> leaf_portals; + leaf_portals.resize( nclusters ); + + for( U32 i = 0; i < bsp->portals.size; ++i ) { + BSP_PORTAL* p = &bsp->portals.data[i]; + I32 lf = bsp_leaf_index( p->front ); + I32 rf = bsp_leaf_index( p->back ); + + leaf_portals.data[lf].push( i ); + leaf_portals.data[rf].push( i ); + } + + for( U32 i = 0; i < nclusters; ++i ) { + BSP_CLUSTER* c = &bsp->clusters.data[i]; + c->first = 0; + c->count = 0; + c->pvs_off = 0; + } + + for( U32 from = 0; from < nclusters; ++from ) { + LIST<I32>* plist = &leaf_portals.data[from]; + pvs_set( &bsp->pvs_bits, nclusters, from, from ); + + LIST<BSP_PORTAL_QUEUE> queue; + for( U32 i = 0; i < plist->size; ++i ) { + I32 pid = plist->data[i]; + BSP_PORTAL* p = &bsp->portals.data[pid]; + + BSP_PORTAL_QUEUE it{ + .front = (I32)from, + .frustum = p->w + }; + + queue.push( it ) ; + } + + while( queue.size ) { + BSP_PORTAL_QUEUE it = queue.pop(); + LIST<I32>* plist = &leaf_portals.data[it.front]; + + for( U32 i = 0; plist->size; ++i ) { + BSP_PORTAL* p = &bsp->portals.data[plist->data[i]]; + I32 lf = bsp_leaf_index( p->front ); + I32 lb = bsp_leaf_index( p->back ); + + I32 neighbor = (lf == it.front) ? lb : (lb == it.front) ? lf : -1; + if( neighbor < 0 ) + continue; + + BSP_WINDING next_w; + if( !bsp_winding_intersect_plane( &p->plane, &it.frustum, &p->w, &next_w ) ) + continue; + + if( !pvs_get( &bsp->pvs_bits, nclusters, from, (U32)neighbor ) ) { + pvs_set( &bsp->pvs_bits, nclusters, from, (U32)neighbor ); + + LIST<I32>* nbr_plist = &leaf_portals.data[neighbor]; + for( U32 i2 = 0; i2 < nbr_plist->size; ++i2 ) { + BSP_PORTAL* nbr_p = &bsp->portals.data[nbr_plist->data[i2]]; + if( nbr_p == p ) + continue; + + BSP_WINDING clipped = next_w; + if( bsp_winding_intersect_plane( &nbr_p->plane, &clipped, &nbr_p->w, &clipped ) ) { + BSP_PORTAL_QUEUE n{}; + n.front = neighbor; + n.frustum = clipped; + queue.push( n ); + } + } + } + } + } + } } BSP* bsp_build_map( WORLD_MAP* m ) { @@ -647,12 +729,13 @@ BSP* bsp_build_map( WORLD_MAP* m ) { LIST<BSP_PLANE> planes = bsp_map_get_planes( m ); bsp->root = bsp_build_nodes( bsp, planes, faces, 0 ); - U32 vertc = 0; - m->polygons.each( fn( MAP_POLYGON* p ) { vertc += p->vertices.size; } ); for( U32 i = 0; i < bsp->faces.size; ++i ) { bsp->faces.data[i].id = i; } bsp_gen_render_vertices( bsp ); + + bsp_build_portals( bsp ); + bsp_build_pvs( bsp ); return bsp; } diff --git a/src/game/world/bsp.h b/src/game/world/bsp.h index 439fce1..457bcb9 100644 --- a/src/game/world/bsp.h +++ b/src/game/world/bsp.h @@ -71,6 +71,11 @@ struct BSP_PORTAL_NODE { BSP_WINDING w; }; +struct BSP_PORTAL_QUEUE { + I32 front; + BSP_WINDING frustum; +}; + struct BSP_BITSET : public LIST<U32> {}; struct BSP { diff --git a/src/game/world/draw.cpp b/src/game/world/draw.cpp index 9269a21..aad4d09 100644 --- a/src/game/world/draw.cpp +++ b/src/game/world/draw.cpp @@ -11,7 +11,7 @@ VEC2 world_project_pos( GAME_DATA* game, VEC3 pos ) { - GL_3D* gl3d = (GL_3D*)game->shaders.gl3d; + GL3D* gl3d = (GL3D*)game->shaders.gl3d; VEC4 clip = { pos.x, pos.z, pos.y, 1.f }; VEC4 ndc; diff --git a/src/game/world/trace.cpp b/src/game/world/trace.cpp index b3a0041..c8ad3be 100644 --- a/src/game/world/trace.cpp +++ b/src/game/world/trace.cpp @@ -200,9 +200,7 @@ inline U8 point_in_inflated_poly( in = in * -1.0f; F32 dist = vec_dot( point - a, in ); - VEC2 feet = aabb_extend_at_feet( hull, in ); - F32 pos_r = feet.x, neg_r = feet.y; - F32 expand = norm.z >= 0 ? neg_r : pos_r; + F32 expand = aabb_extend_at_feet( hull, in ).x; if( dist < -expand - BSP_TRACE_EPSILON ) return 0; } |
