summaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authornavewindre <boneyaard@gmail.com>2025-11-28 14:41:22 +0100
committerGitHub <noreply@github.com>2025-11-28 14:41:22 +0100
commit9c05c795d7b59c5ab94fb769f315c712b37df0cd (patch)
tree16cccf8cbb88703de798066a06f94013f89a8a5a /src/util
parentf8b92ce3aa08b1445c9f956d8166830946562d12 (diff)
parent3e094f20d4dda90e0356aba3f0abc4b7c7015844 (diff)
Merge pull request #1 from navewindre/windows-compat
Windows compat
Diffstat (limited to 'src/util')
-rw-r--r--src/util/aabb.h1
-rw-r--r--src/util/allocator.h26
-rw-r--r--src/util/config/config.cpp92
-rw-r--r--src/util/input.cpp16
-rw-r--r--src/util/input.h21
5 files changed, 131 insertions, 25 deletions
diff --git a/src/util/aabb.h b/src/util/aabb.h
index f2fd251..4d74c88 100644
--- a/src/util/aabb.h
+++ b/src/util/aabb.h
@@ -14,6 +14,7 @@ inline F32 aabb_support_radius( const AABB& aabb, const VEC3& dir ) {
return fabsf(dir.x) * half.x + fabsf(dir.y) * half.y + fabsf(dir.z) * half.z;
}
+// returns positive radius in X and negative in Y
inline VEC2 aabb_extend_at_feet( const AABB& aabb, const VEC3& dir ) {
VEC3 half = aabb_half( aabb );
diff --git a/src/util/allocator.h b/src/util/allocator.h
index ee0ddd8..27b21c0 100644
--- a/src/util/allocator.h
+++ b/src/util/allocator.h
@@ -161,6 +161,22 @@ struct LIST {
return &data[size - 1];
}
+ void resize( U32 size ) {
+ if( size > capacity )
+ reserve( size * 2 );
+
+ if( size < capacity / 4 )
+ shrink();
+
+ if( this->size < size ) {
+ memset( &data[this->size], 0, sizeof(T) * (size - this->size) );
+ for( U32 i = this->size; i < size; ++i )
+ data[i] = T();
+ }
+
+ this->size = size;
+ }
+
// does not call copy constructors, raw memcpy
void emplace_list( const LIST<T>& list ) {
if( !list.size )
@@ -250,6 +266,16 @@ struct LIST {
return -1;
}
+ I32 idx_of( const T* what ) {
+ for( U32 i = 0; i < size; ++i ) {
+ if( &data[i] == what ) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
I32 idx_where( ON_SEARCH_FN what ) {
for( U32 i = 0; i < size; ++i ) {
if( what( &data[i] ) ) {
diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp
index 1601afe..a41e455 100644
--- a/src/util/config/config.cpp
+++ b/src/util/config/config.cpp
@@ -12,20 +12,21 @@ void cfg_seterr( CFG_PARSER* p, const char* fmt, ... ) {
}
inline U8 is_whitespace( char c ) {
- return c == ' ' || c == '\t' || c == '\n';
+ return c == ' ' || c == '\t' || c == '\n' || c == '\r';
}
inline void trim_whitespace( char* buf ) {
- U32 i;
- for( i = 0; !!buf[i]; ++i )
- if( !is_whitespace( buf[i] ) ) break;
- for( U32 i2 = i; !!buf[i2]; ++i2 ) {
- if( is_whitespace( buf[i2] ) ) {
- buf[i2 - i] = 0;
- return;
- }
- buf[i2 - i] = buf[i2];
- }
+ if (!buf || !*buf) return;
+
+ U32 start = 0;
+ while( buf[start] && is_whitespace( buf[start] ) ) start++;
+
+ U32 end = strlen( buf );
+ while( end > start && is_whitespace( buf[end - 1] ) ) end--;
+
+ U32 len = end - start;
+ memmove( buf, buf + start, len );
+ buf[len] = '\0';
}
inline void init_cfg_node( CFG_NODE* node, const char* name, CFG_NODE* parent, U8 type ) {
@@ -179,65 +180,108 @@ void parse_section( CFG_PARSER* parser, CFG_SECTION* current_section ) {
char* next_token;
while( fgets( line, sizeof(line), parser->file ) ) {
- token = strtok( line, " \t\n" );
+ parser->linen++;
+
+ trim_whitespace( line );
+ if( strlen( line ) == 0 )
+ continue;
+
+ char line_copy[8192];
+ strcpy( line_copy, line );
+
+ token = strtok( line_copy, " \t\r\n" );
if( !token ) continue;
- if( strcmp( token, "{" ) == 0 )
+
+ if( strcmp( token, "{" ) == 0 ) {
continue;
- else if( strcmp( token, "}" ) == 0 ) {
+ } else if( strcmp( token, "}" ) == 0 ) {
return;
} else if( strcmp( token, cfg_types[CFGT_SECTION].def ) == 0 ) {
- next_token = strtok( NULL, " \t\n" );
+ next_token = strtok( NULL, " \t\r\n" );
+ if( !next_token ) {
+ cfg_seterr( parser, "missing section name at line %d", parser->linen );
+ return;
+ }
+
char sectname[64];
- strcpy( sectname, next_token );
+ strncpy( sectname, next_token, sizeof(sectname) - 1 );
+ sectname[sizeof(sectname) - 1] = '\0';
trim_whitespace( sectname );
CFG_SECTION* new_section = cfg_section_new( sectname, (CFG_NODE*)current_section );
- strtok( NULL, " \t\n" );
+
+ char* brace = strtok( NULL, " \t\r\n" );
+ if( !brace || strcmp( brace, "{" ) != 0 ) {
+ cfg_seterr( parser, "expected '{' after section name at line %d", parser->linen );
+ return;
+ }
+
parse_section( parser, new_section );
} else {
char name[64];
- strcpy( name, token );
+ strncpy( name, token, sizeof(name) - 1 );
+ name[sizeof(name) - 1] = '\0';
trim_whitespace( name );
token = strtok( NULL, "=[" );
- if( !token )
+ if( !token ) {
+ cfg_seterr( parser, "invalid variable declaration at line %d", parser->linen );
continue;
+ }
char varname[64];
- strcpy( varname, token );
+ strncpy( varname, token, sizeof(varname) - 1 );
+ varname[sizeof(varname) - 1] = '\0';
trim_whitespace( varname );
+ U8 found = 0;
for( I32 i = 0; i < sizeof(cfg_types) / sizeof(CFG_TYPE); ++i ) {
const CFG_TYPE* fn = &cfg_types[i];
- if( strncmp( name, fn->def, strlen( fn->def ) ) == 0 ) {
+ if( strcmp( name, fn->def ) == 0 ) {
+ strcpy( line_copy, line );
+ strtok( line_copy, " \t\r\n" );
+ strtok( NULL, "=[" );
+
fn->parser( parser, current_section, varname );
+ found = true;
break;
}
}
+ if( !found ) {
+ cfg_seterr( parser, "unknown type '%s' at line %d", name, parser->linen );
+ return;
+ }
+
if( parser->iserr ) {
dlog( "parse_section() : %s parse error:\n - %s\n", name, parser->err );
return;
}
}
-
- parser->linen++;
}
}
CFG_SECTION* cfg_load( const char* path ) {
- FILE* f = fopen( path, "rb" );
+ FILE* f = fopen( path, "r" );
if( !f )
return 0;
CFG_PARSER p;
+ memset( &p, 0, sizeof(p) );
p.iserr = 0;
p.file = f;
p.linen = 0;
p.root = cfg_section_new( "root", 0 );
+
parse_section( &p, p.root );
fclose( f );
+
+ if( p.iserr ) {
+ cfg_free( (CFG_NODE*)p.root );
+ return 0;
+ }
+
return p.root;
}
diff --git a/src/util/input.cpp b/src/util/input.cpp
index 4a786aa..284ebfe 100644
--- a/src/util/input.cpp
+++ b/src/util/input.cpp
@@ -27,6 +27,8 @@ void input_on_event( SDL_Event* e ) {
case SDL_MOUSEMOTION: {
input.mouse.pos.x = (F32)e->motion.x;
input.mouse.pos.y = (F32)e->motion.y;
+ input.mouse.pos_delta.x += (F32)e->motion.xrel * input.mpitch;
+ input.mouse.pos_delta.y += (F32)e->motion.yrel * input.myaw;
} break;
case SDL_KEYDOWN: {
input.keys[e->key.keysym.sym & 0xff] = 1;
@@ -37,6 +39,10 @@ void input_on_event( SDL_Event* e ) {
}
}
+extern void input_reset_mouse_accumulator() {
+ input.mouse.pos_delta.x = 0;
+ input.mouse.pos_delta.y = 0;
+}
void input_on_mouse( I32 type, I32 x, I32 y ) {
if( type == MOUSEEV_MOVE ) {
@@ -72,3 +78,13 @@ void input_on_mouse( I32 type, I32 x, I32 y ) {
void input_frame_end() {
input.mouse.wheel = 0;
}
+
+U8 input_is_key_down( U32 key ) {
+ return input.keys[key];
+}
+
+void input_capture_mouse( bool capture ) {
+ input_reset_mouse_accumulator();
+ input.mouselock = capture;
+ SDL_SetRelativeMouseMode( capture ? SDL_TRUE : SDL_FALSE );
+}
diff --git a/src/util/input.h b/src/util/input.h
index e174fe6..86d715c 100644
--- a/src/util/input.h
+++ b/src/util/input.h
@@ -16,19 +16,36 @@ const U32 MOUSE_WHEEL = 0x4;
struct MOUSE_DATA {
VEC2 pos;
+ VEC2 pos_delta;
U8 left;
U8 right;
U8 middle;
U8 wheel;
};
+struct INPUT_KEYBINDS {
+ U8 fwd = 'w';
+ U8 back = 's';
+ U8 left = 'a';
+ U8 right = 'd';
+
+ U8 jump = ' ';
+ U8 crouch = SDL_SCANCODE_LCTRL;
+};
+
using ON_INPUT_FN = std::function<void( SDL_Event* )>;
struct INPUT_DATA {
MOUSE_DATA mouse;
U8 keys[0xff];
+ bool mouselock;
+ F32 msens = .3f;
+ F32 myaw = 1.f;
+ F32 mpitch = 1.f;
+ INPUT_KEYBINDS binds;
LIST<ON_INPUT_FN> on_input;
+
};
extern INPUT_DATA input;
@@ -36,6 +53,8 @@ extern INPUT_DATA input;
extern void input_frame_end();
extern void input_on_event( SDL_Event* e );
extern void input_on_mouse( I32 type, I32 x, I32 y );
-extern void input_is_key_down( U32 key );
+extern U8 input_is_key_down( U32 key );
+extern void input_capture_mouse( bool capture );
+extern void input_reset_mouse_accumulator();
#define kb_down( key ) input_is_key_down( key )