+#ifdef VG_ENGINE
#include "vg_engine.h"
-#include "vg_console.h"
#include "vg_ui/imgui.h"
+#endif
+
+#include "vg_console.h"
#include "vg_log.h"
#include "vg_string.h"
#include <string.h>
void vg_console_reg_var( const char *alias, void *ptr, enum vg_var_dtype type, u32 flags )
{
+#ifdef VG_ENGINE
THREAD_1;
+#endif
VG_ASSERT( vg_console.var_count < VG_ARRAY_LEN(vg_console.vars) );
vg_var *var = &vg_console.vars[ vg_console.var_count ++ ];
vg_info( "Console variable '%s' registered\n", alias );
}
-void vg_console_reg_cmd( const char *alias,
- int (*function)(int argc, const char *argv[]),
- void (*poll_suggest)(int argc, const char *argv[]) )
+void vg_console_reg_cmd( const char *alias, int (*function)(int argc, const char *argv[]),
+ void (*poll_suggest)(int argc, const char *argv[]) )
{
+#ifdef VG_ENGINE
THREAD_1;
+#endif
VG_ASSERT( vg_console.function_count < VG_ARRAY_LEN(vg_console.functions) );
vg_cmd *cmd = &vg_console.functions[ vg_console.function_count ++ ];
for( int i=0; i<vg_console.var_count; i ++ )
{
struct vg_var *cv = &vg_console.vars[ i ];
- vg_info( "%s %s\n",
- (const char *[]){ "i32","u32","f32","str" }[cv->data_type],
- cv->name );
+ vg_info( "%s %s\n", (const char *[]){ "i32","u32","f32","str" }[cv->data_type], cv->name );
}
return 0;
static void vg_console_write_persistent(void)
{
+#ifdef VG_ENGINE
enum engine_status status = SDL_AtomicGet( &vg.engine_status );
-
if( status < k_engine_status_running )
{
vg_low( "Not writing auto.conf due to early exit.\n" );
return;
}
+#endif
FILE *fp = fopen( "cfg/auto.conf", "w" );
-
if( !fp )
{
vg_error( "Cannot open cfg/auto.conf\n" );
if( cv->flags & VG_VAR_PERSISTENT )
{
if( cv->data_type == k_var_dtype_i32 )
- {
fprintf( fp, "%s %d\n", cv->name, *(i32 *)(cv->data) );
- }
else if( cv->data_type == k_var_dtype_u32 )
- {
fprintf( fp, "%s %u\n", cv->name, *(u32 *)(cv->data) );
- }
else if( cv->data_type == k_var_dtype_f32 )
- {
fprintf( fp, "%s %.5f\n", cv->name, *(float *)(cv->data ) );
- }
else if( cv->data_type == k_var_dtype_str )
{
vg_str *str = cv->data;
fclose( fp );
}
+#ifdef VG_ENGINE
static void _vg_console_free(void)
{
vg_console_write_persistent();
}
+#endif
/*
* splits src into tokens and fills out args as pointers to those tokens
* returns number of tokens
* dst must be as long as src
*/
-static int vg_console_tokenize( const char *src, char *dst,
- const char *args[8] )
+static int vg_console_tokenize( const char *src, char *dst, const char *args[8] )
{
int arg_count = 0,
in_token = 0;
return arg_count;
}
-vg_var *vg_console_match_var( const char *kw )
+static vg_var *vg_console_match_var( const char *kw )
{
for( int i=0; i<vg_console.var_count; i ++ )
{
return NULL;
}
-vg_cmd *vg_console_match_cmd( const char *kw )
+static vg_cmd *vg_console_match_cmd( const char *kw )
{
for( int i=0; i<vg_console.function_count; i ++ )
{
/* Cvar Matched, try get value */
if( arg_count >= 2 )
{
+#ifdef VG_ENGINE
if( cv->flags & VG_VAR_CHEAT )
{
- if( !vg_console.cheats && !silent )
+ bool cheats = vg_console.cheats;
+ if( !cheats && !silent )
{
vg_error( "variable is cheat protected\n" );
return;
}
}
+#endif
- if( (cv->data_type == k_var_dtype_u32) ||
- (cv->data_type == k_var_dtype_i32) )
+ if( (cv->data_type == k_var_dtype_u32) || (cv->data_type == k_var_dtype_i32) )
{
int *ptr = cv->data;
*ptr = atoi( args[1] );
vg_error( "No command/var named '%s'. Use 'list' to view all\n",args[0]);
}
+#ifdef VG_ENGINE
u32 str_lev_distance( const char *s1, const char *s2 )
{
u32 m = strlen( s1 ),
}
/* str must not fuckoff ever! */
-void console_suggest_score_text( const char *str, const char *input,
- int minscore )
+void console_suggest_score_text( const char *str, const char *input, int minscore )
{
if( !str )
return;
/* insert if good score */
if( best_pos < VG_ARRAY_LEN( vg_console.suggestions ) )
{
- int start = VG_MIN( vg_console.suggestion_count,
- VG_ARRAY_LEN( vg_console.suggestions )-1 );
+ int start = VG_MIN( vg_console.suggestion_count, VG_ARRAY_LEN( vg_console.suggestions )-1 );
for( int j=start; j>best_pos; j -- )
vg_console.suggestions[j] = vg_console.suggestions[j-1];
vg_console.suggestions[ best_pos ].len = strlen( str );
vg_console.suggestions[ best_pos ].lev_score = score;
- if( vg_console.suggestion_count <
- VG_ARRAY_LEN( vg_console.suggestions ) )
+ if( vg_console.suggestion_count < VG_ARRAY_LEN( vg_console.suggestions ) )
vg_console.suggestion_count ++;
}
}
vg_console.history_pos = -1;
vg_execute_console_input( vg_console.input, 0 );
- _ui_textbox_move_cursor( ctx,
- &ctx->textbox.cursor_user,
- &ctx->textbox.cursor_pos, -10000, 1 );
-
+ _ui_textbox_move_cursor( ctx, &ctx->textbox.cursor_user, &ctx->textbox.cursor_pos, -10000, 1 );
vg_console.input[0] = '\0';
console_update_suggestions( ctx );
}
vg_console.auto_focus = 1;
}
+#endif
-int vg_console_exec( int argc, const char *argv[] )
+static int vg_console_exec( int argc, const char *argv[] )
{
- if( argc < 1 ) return 0;
+ if( argc < 1 )
+ return 0;
int silent=0;
- if( argc == 2 ) silent=1;
+ if( argc == 2 )
+ silent=1;
char path[256];
strcpy( path, "cfg/" );
while( fgets( line, sizeof( line ), fp ) )
{
line[ strcspn( line, "\r\n#" ) ] = 0x00;
-
if( line[0] != 0x00 )
- {
- strcpy( vg_console.input, line );
vg_execute_console_input( line, silent );
- }
}
fclose( fp );
}
else
- {
vg_error( "Could not open '%s'\n", path );
- }
-
- vg_console.input[0] = '\0';
return 0;
}
{
vg_console_reg_cmd( "list", _vg_console_list, NULL );
vg_console_reg_cmd( "exec", vg_console_exec, NULL );
+#ifdef VG_ENGINE
vg_console_reg_var( "cheats", &vg_console.cheats, k_var_dtype_i32,
#ifdef VG_DEVWINDOW
VG_VAR_PERSISTENT
0
#endif
);
+#endif
}
+#ifdef VG_ENGINE
void vg_console_load_autos(void)
{
vg_console_exec( 2, (const char *[]){ "auto.conf", "silent" } );
if( SDL_UnlockMutex( vg_log.mutex ) )
vg_fatal_error( "" );
}
+#endif
#include <stddef.h>
#include <stdarg.h>
+/* util
+ * ------------------------------------------------------------------------------------------------------------------ */
+
static void vg_db_abort( vg_db *db, const char *message, ... )
{
fclose( db->fp );
return hash;
}
+static u64 vg_db_allocate_physical_page( vg_db *db );
+static void vg_db_sync_page( vg_db *db, u16 cache_id );
+
+/* API
+ * ------------------------------------------------------------------------------------------------------------------ */
+
+void vg_db_open( vg_db *db, const char *path )
+{
+ u32 k_ident = 0xf32b1a00;
+ vg_rand_seed( &db->rand, k_ident + time(NULL) );
+ db->fp = fopen( path, "rb+" );
+ db->page_data = malloc( VG_PAGE_SIZE*VG_MAX_CACHED_PAGES );
+ db->cache_count = 0;
+ db->lru_old = 0;
+ db->lru_young = 0;
+ if( db->fp )
+ {
+ u32 ident;
+ vg_db_read( db, 0, &ident, 4 );
+ if( ident != k_ident )
+ vg_db_abort( db, "Ident not found in db file '%s'\n", path );
+ vg_db_read( db, offsetof(vg_db_header,userdata_address), &db->userdata_address, 8 );
+ }
+ else
+ {
+ db->fp = fopen( path, "wb+" );
+ if( !db->fp )
+ vg_db_abort( db, "fopen(wb+) failed for '%s'\n", path );
+ vg_db_allocate_physical_page( db ); // Allocate header as 0
+ vg_db_write( db, offsetof(vg_db_header,ident), &k_ident, 4 );
+ db->userdata_address = vg_db_virtual_allocate( db, VG_1GB );
+ vg_db_write( db, offsetof(vg_db_header,userdata_address), &db->userdata_address, 8 );
+ vg_db_tree_init( db, offsetof(vg_db_header,address_tree) );
+ }
+}
+
+void vg_db_close( vg_db *db )
+{
+ for( u32 i=0; i<VG_MAX_CACHED_PAGES; i ++ )
+ vg_db_sync_page( db, i+1 );
+ fclose( db->fp );
+ db->fp = NULL;
+ free( db->page_data );
+ db->page_data = NULL;
+}
+
+/* paging
+ * ------------------------------------------------------------------------------------------------------------------ */
+
static u64 vg_db_allocate_physical_page( vg_db *db )
{
if( fseek( db->fp, 0, SEEK_END ) )
}
}
+static void vg_db_touch( vg_db *db, u16 cache_id )
+{
+ vg_db_page *page = &db->page_cache[ cache_id-1 ];
+ /* unlink entirely */
+ if( page->lru_younger )
+ db->page_cache[ page->lru_younger-1 ].lru_older = page->lru_older;
+ else if( db->lru_young == cache_id )
+ db->lru_young = page->lru_older;
+ if( page->lru_older )
+ db->page_cache[ page->lru_older-1 ].lru_younger = page->lru_younger;
+ else if( db->lru_old == cache_id )
+ db->lru_old = page->lru_younger;
+ /* re-link */
+ page->lru_younger = 0;
+ page->lru_older = db->lru_young;
+ if( db->lru_young )
+ {
+ page->lru_older = db->lru_young;
+ db->page_cache[ db->lru_young-1 ].lru_younger = cache_id;
+ }
+ db->lru_young = cache_id;
+ if( !db->lru_old )
+ db->lru_old = cache_id;
+}
+
+static void *vg_db_devirtualize( vg_db *db, u64 address, bool write )
+{
+ u64 page_base = address & ~(VG_PAGE_SIZE-1lu),
+ inner_offset = address & (VG_PAGE_SIZE-1lu);
+
+ /* Check hash table for our page */
+ u32 hash = vg_dbhash( (void *)(&page_base), sizeof(page_base) ) & (VG_PAGE_CACHE_HASH_WIDTH-1u);
+ u16 current = db->hash_table[ hash ];
+ while( current )
+ {
+ vg_db_page *page = &db->page_cache[ current-1 ];
+ if( page->virtual_id == page_base )
+ {
+ page->unwritten |= write;
+ vg_db_touch( db, current );
+ return db->page_data + ((u64)(current-1)*VG_PAGE_SIZE + inner_offset);
+ }
+ else
+ current = page->hash_prev;
+ }
+
+ /* Translate address & create page if need be */
+ u64 translated_page_base = page_base;
+ if( address & VG_VIRTUAL_ADDRESS_BIT )
+ {
+ u64 tree_address = offsetof(vg_db_header,address_tree);
+ translated_page_base = vg_db_translate( db, tree_address, page_base );
+ if( translated_page_base == 0 )
+ {
+ u64 new_page = vg_db_allocate_physical_page( db );
+ vg_db_tree_map( db, tree_address, page_base, new_page );
+ translated_page_base = new_page;
+ }
+ }
+
+ /* Allocate cache ID */
+ u16 cache_id = 0;
+ vg_db_page *page = NULL;
+ if( db->cache_count < VG_MAX_CACHED_PAGES )
+ {
+ cache_id = ++db->cache_count;
+ page = &db->page_cache[ cache_id-1 ];
+ memset( page, 0, sizeof(vg_db_page) );
+ }
+ else
+ {
+ cache_id = db->lru_old;
+ vg_db_sync_page( db, cache_id );
+ page = &db->page_cache[ cache_id-1 ];
+ u32 old_hash = vg_dbhash( (void *)(&page->virtual_id), sizeof(page->virtual_id) ) & (VG_PAGE_CACHE_HASH_WIDTH-1u);
+ u16 current = db->hash_table[ old_hash ], before = 0;
+ while( current != cache_id )
+ {
+ before = current;
+ current = db->page_cache[ current-1 ].hash_prev;
+ }
+ if( before )
+ db->page_cache[ before-1 ].hash_prev = page->hash_prev;
+ else
+ db->hash_table[ old_hash ] = 0;
+ }
+ page->hash_prev = db->hash_table[ hash ];
+ db->hash_table[ hash ] = cache_id;
+ vg_db_touch( db, cache_id );
+ page->virtual_id = page_base;
+ page->physical_offset = translated_page_base;
+ page->unwritten = write;
+
+ /* read into memory */
+ void *page_data = db->page_data + (u64)(cache_id-1)*VG_PAGE_SIZE;
+ if( fseek( db->fp, translated_page_base, SEEK_SET ) )
+ vg_db_abort( db, "SEEK_SET (%lx) failed\n", translated_page_base );
+ if( !fread( page_data, VG_PAGE_SIZE, 1, db->fp ) )
+ vg_db_abort( db, "fread page failed\n" );
+ return page_data + inner_offset;
+}
+
+void vg_db_xch( vg_db *db, u64 base_address, void *buf, u32 length, bool write )
+{
+ u64 address = base_address,
+ end = base_address + (u64)length;
+
+ while( address != end )
+ {
+ u64 byte_count = VG_PAGE_SIZE - (address & (VG_PAGE_SIZE-1lu));
+ if( address + byte_count > end )
+ byte_count = end - address;
+
+ void *cache_buffer = vg_db_devirtualize( db, address, write ),
+ *user_buffer = buf + (address-base_address);
+ if( write ) memcpy( cache_buffer, user_buffer, byte_count );
+ else memcpy( user_buffer, cache_buffer, byte_count );
+ address += byte_count;
+ }
+}
+
+u64 vg_db_virtual_allocate( vg_db *db, u64 bytes )
+{
+ u64 page_count = 0;
+ vg_db_read( db, 0x0lu + offsetof(vg_db_header,virtual_pages), &page_count, sizeof(page_count) );
+ u64 pages = (bytes + (VG_PAGE_SIZE-1lu)) >> VG_PAGE_BITS,
+ addr = page_count * VG_PAGE_SIZE;
+ page_count += pages;
+ vg_db_write( db,0x0lu + offsetof(vg_db_header,virtual_pages), &page_count, sizeof(page_count) );
+ return VG_VIRTUAL_ADDRESS_BIT | addr;
+}
+
+/* AA search tree
+ * ------------------------------------------------------------------------------------------------------------------ */
+
static u64 vg_db_skew( vg_db *db, u64 t_offset )
{
if( t_offset == 0 )
vg_db_write( db, tree_address, &tree, sizeof(tree) );
}
-static void vg_db_touch( vg_db *db, u16 cache_id )
-{
- vg_db_page *page = &db->page_cache[ cache_id-1 ];
- /* unlink entirely */
- if( page->lru_younger )
- db->page_cache[ page->lru_younger-1 ].lru_older = page->lru_older;
- else if( db->lru_young == cache_id )
- db->lru_young = page->lru_older;
- if( page->lru_older )
- db->page_cache[ page->lru_older-1 ].lru_younger = page->lru_younger;
- else if( db->lru_old == cache_id )
- db->lru_old = page->lru_younger;
- /* re-link */
- page->lru_younger = 0;
- page->lru_older = db->lru_young;
- if( db->lru_young )
- {
- page->lru_older = db->lru_young;
- db->page_cache[ db->lru_young-1 ].lru_younger = cache_id;
- }
- db->lru_young = cache_id;
- if( !db->lru_old )
- db->lru_old = cache_id;
-}
-
u64 vg_db_translate( vg_db *db, u64 tree_address, u64 key )
{
vg_db_address_tree tree;
}
}
+/* Randomized skiplist
+ * ------------------------------------------------------------------------------------------------------------------ */
+
void vg_db_skipper_init( vg_db *db, u64 skipper_address, u32 max_entries )
{
vg_db_skipper skipper;
}
}
-void vg_db_skipper_replace( vg_db *db, vg_skipper_context *ctx, u16 item_index, void *comparand_old, void *comparand_new )
-{
- vg_db_skipper_unplace( db, ctx, item_index, comparand_old );
- vg_db_skipper_placement( db, ctx, item_index, comparand_new );
-}
-
void vg_db_skipper_iter_start( vg_db *db, vg_skipper_context *ctx )
{
vg_db_skipper skipper;
return 1;
}
}
+
+/* Dumb table
+ * ------------------------------------------------------------------------------------------------------------------ */
void vg_db_dumb_table_init( vg_db *db, u64 table_address, u32 structure_size, u32 max_entries )
{
}
else return 0;
}
-
-static void *vg_db_devirtualize( vg_db *db, u64 address, bool write )
-{
- u64 page_base = address & ~(VG_PAGE_SIZE-1lu),
- inner_offset = address & (VG_PAGE_SIZE-1lu);
-
- /* Check hash table for our page */
- u32 hash = vg_dbhash( (void *)(&page_base), sizeof(page_base) ) & (VG_PAGE_CACHE_HASH_WIDTH-1u);
- u16 current = db->hash_table[ hash ];
- while( current )
- {
- vg_db_page *page = &db->page_cache[ current-1 ];
- if( page->virtual_id == page_base )
- {
- page->unwritten |= write;
- vg_db_touch( db, current );
- return db->page_data + ((u64)(current-1)*VG_PAGE_SIZE + inner_offset);
- }
- else
- current = page->hash_prev;
- }
-
- /* Translate address & create page if need be */
- u64 translated_page_base = page_base;
- if( address & VG_VIRTUAL_ADDRESS_BIT )
- {
- u64 tree_address = offsetof(vg_db_header,address_tree);
- translated_page_base = vg_db_translate( db, tree_address, page_base );
- if( translated_page_base == 0 )
- {
- u64 new_page = vg_db_allocate_physical_page( db );
- vg_db_tree_map( db, tree_address, page_base, new_page );
- translated_page_base = new_page;
- }
- }
-
- /* Allocate cache ID */
- u16 cache_id = 0;
- vg_db_page *page = NULL;
- if( db->cache_count < VG_MAX_CACHED_PAGES )
- {
- cache_id = ++db->cache_count;
- page = &db->page_cache[ cache_id-1 ];
- memset( page, 0, sizeof(vg_db_page) );
- }
- else
- {
- cache_id = db->lru_old;
- vg_db_sync_page( db, cache_id );
- page = &db->page_cache[ cache_id-1 ];
- u32 old_hash = vg_dbhash( (void *)(&page->virtual_id), sizeof(page->virtual_id) ) & (VG_PAGE_CACHE_HASH_WIDTH-1u);
- u16 current = db->hash_table[ old_hash ], before = 0;
- while( current != cache_id )
- {
- before = current;
- current = db->page_cache[ current-1 ].hash_prev;
- }
- if( before )
- db->page_cache[ before-1 ].hash_prev = page->hash_prev;
- else
- db->hash_table[ old_hash ] = 0;
- }
- page->hash_prev = db->hash_table[ hash ];
- db->hash_table[ hash ] = cache_id;
- vg_db_touch( db, cache_id );
- page->virtual_id = page_base;
- page->physical_offset = translated_page_base;
- page->unwritten = write;
-
- /* read into memory */
- void *page_data = db->page_data + (u64)(cache_id-1)*VG_PAGE_SIZE;
- if( fseek( db->fp, translated_page_base, SEEK_SET ) )
- vg_db_abort( db, "SEEK_SET (%lx) failed\n", translated_page_base );
- if( !fread( page_data, VG_PAGE_SIZE, 1, db->fp ) )
- vg_db_abort( db, "fread page failed\n" );
- return page_data + inner_offset;
-}
-
-void vg_db_xch( vg_db *db, u64 base_address, void *buf, u32 length, bool write )
-{
- u64 address = base_address,
- end = base_address + (u64)length;
-
- while( address != end )
- {
- u64 byte_count = VG_PAGE_SIZE - (address & (VG_PAGE_SIZE-1lu));
- if( address + byte_count > end )
- byte_count = end - address;
-
- void *cache_buffer = vg_db_devirtualize( db, address, write ),
- *user_buffer = buf + (address-base_address);
- if( write ) memcpy( cache_buffer, user_buffer, byte_count );
- else memcpy( user_buffer, cache_buffer, byte_count );
- address += byte_count;
- }
-}
-
-void vg_db_open( vg_db *db, const char *path )
-{
- u32 k_ident = 0xf32b1a00;
- vg_rand_seed( &db->rand, k_ident + time(NULL) );
- db->fp = fopen( path, "rb+" );
- db->page_data = malloc( VG_PAGE_SIZE*VG_MAX_CACHED_PAGES );
- db->cache_count = 0;
- db->lru_old = 0;
- db->lru_young = 0;
- if( db->fp )
- {
- u32 ident;
- vg_db_read( db, 0, &ident, 4 );
- if( ident != k_ident )
- vg_db_abort( db, "Ident not found in db file '%s'\n", path );
- vg_db_read( db, offsetof(vg_db_header,userdata_address), &db->userdata_address, 8 );
- }
- else
- {
- db->fp = fopen( path, "wb+" );
- if( !db->fp )
- vg_db_abort( db, "fopen(wb+) failed for '%s'\n", path );
- vg_db_allocate_physical_page( db ); // Allocate header as 0
- vg_db_write( db, offsetof(vg_db_header,ident), &k_ident, 4 );
- db->userdata_address = vg_db_virtual_allocate( db, VG_1GB );
- vg_db_write( db, offsetof(vg_db_header,userdata_address), &db->userdata_address, 8 );
- vg_db_tree_init( db, offsetof(vg_db_header,address_tree) );
- }
-}
-
-void vg_db_close( vg_db *db )
-{
- for( u32 i=0; i<VG_MAX_CACHED_PAGES; i ++ )
- vg_db_sync_page( db, i+1 );
- fclose( db->fp );
- db->fp = NULL;
- free( db->page_data );
- db->page_data = NULL;
-}
-
-u64 vg_db_virtual_allocate( vg_db *db, u64 bytes )
-{
- u64 page_count = 0;
- vg_db_read( db, 0x0lu + offsetof(vg_db_header,virtual_pages), &page_count, sizeof(page_count) );
- u64 pages = (bytes + (VG_PAGE_SIZE-1lu)) >> VG_PAGE_BITS,
- addr = page_count * VG_PAGE_SIZE;
- page_count += pages;
- vg_db_write( db,0x0lu + offsetof(vg_db_header,virtual_pages), &page_count, sizeof(page_count) );
- return VG_VIRTUAL_ADDRESS_BIT | addr;
-}