diff options
Diffstat (limited to 'src/util')
| -rw-r--r-- | src/util/aabb.h | 1 | ||||
| -rw-r--r-- | src/util/allocator.h | 26 | ||||
| -rw-r--r-- | src/util/config/config.cpp | 92 | ||||
| -rw-r--r-- | src/util/input.cpp | 16 | ||||
| -rw-r--r-- | src/util/input.h | 21 |
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 ) |
