summaryrefslogtreecommitdiff
path: root/src/game
diff options
context:
space:
mode:
Diffstat (limited to 'src/game')
-rw-r--r--src/game/assets.cpp5
-rw-r--r--src/game/camera.h9
-rw-r--r--src/game/player.cpp133
-rw-r--r--src/game/player.h13
-rw-r--r--src/game/raycast.cpp2
-rw-r--r--src/game/world/bsp.cpp89
-rw-r--r--src/game/world/bsp.h5
-rw-r--r--src/game/world/draw.cpp2
-rw-r--r--src/game/world/trace.cpp4
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;
}