-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include <time.h>
-#include <stdarg.h>
+// Copyright (C) 2021 Harry Godden (hgn)
+// Building:
+// gcc -rdynamic csRadar.c -o csRadar -lm -ldl
+//
+// Plugins:
+// gcc -fpic -shared -o ext/my_plugin.so my_plugin.c -lm
-#include <unistd.h>
-
-// CSR lib
-#include "csrLog.h"
-#include "csrOpt.h"
-#include "csrTypes.h"
-#include "csrMath.h"
-#include "csrMem.h"
-#include "csrIO.h"
-#include "csrComb.h"
-
-// Valve formats
-#include "vdf.h"
-#include "vpk.h"
-#include "vfilesys.h"
-
-#include "vmdl.h"
-#include "vmf.h"
-
-// CSR main
-#include "csr32f.h"
-#include "csrDraw.h"
-
-#define CSR_VERSION "0.0.1"
-
-// gcc -Wall -fsanitize=address csRadar.c -o csRadar -lm
+#define VALVE_IMPLEMENTATION
+#define CSR_EXECUTABLE
+#include "csRadar.h"
int main( int argc, char *argv[] )
{
- char *arg;
- char *strings[ 20 ];
- int num_strings = 0;
-
- float padding = 128.f;
- u32 resolution = 1024;
- int write_txt = 1;
- char output_path[ 512 ]; // Full path eg. /home/harry/my_map.vmf
- char vmf_name[ 128 ]; // Just the base name eg. my_map
+ csr_api api =
+ {
+ .padding = 128.f,
+ .resolution = 1024,
+ .write_txt = 1,
+ .api_version = csr_api_version,
+ .sampling_mode = k_EMSAA_RGSS
+ };
+
int output_set = 0;
- EMSAA sampling_mode = k_EMSAA_RGSS;
+ char *extension = NULL;
+ char *gameinfo = NULL;
+ char *arg;
while( csr_argp( argc, argv ) )
{
if( (arg = csr_arg()) )
{
- if( num_strings == 20 )
+ if( api.num_strings == 20 )
{
log_error( "Too many arguments! Max 20\n" );
goto IL_CSR_EXIT;
}
- strings[ num_strings ++ ] = arg;
+ api.strings[ api.num_strings ++ ].str = arg;
}
if( (arg = csr_opt_arg( 'o' )) )
{
- strcpy( output_path, arg );
- csr_path_winunix( output_path );
+ strcpy( api.output_path, arg );
+ csr_path_winunix( api.output_path );
output_set = 1;
}
if( (arg = csr_opt_arg( 'g' )) )
{
- fs_set_gameinfo( arg );
+ gameinfo = arg;
}
if( (arg = csr_opt_arg( 'r' )) )
{
- resolution = atoi( arg );
+ api.resolution = atoi( arg );
}
if( (arg = csr_long_opt_arg( "padding" )) )
{
- padding = atof( arg );
+ api.padding = atof( arg );
}
if( (arg = csr_long_opt_arg( "multi-sample" )) )
{
if( !strcmp( arg, "none" ))
{
- sampling_mode = k_EMSAA_none;
+ api.sampling_mode = k_EMSAA_none;
}
else if( !strcmp( arg, "rgss" ))
{
- sampling_mode = k_EMSAA_RGSS;
+ api.sampling_mode = k_EMSAA_RGSS;
}
else if( !strcmp( arg, "2x" ))
{
- sampling_mode = k_EMSAA_2x2;
+ api.sampling_mode = k_EMSAA_2x2;
}
else if( !strcmp( arg, "8r" ))
{
- sampling_mode = k_EMSAA_8R;
+ api.sampling_mode = k_EMSAA_8R;
}
else
{
goto IL_CSR_EXIT;
}
}
+
+ if( (arg = csr_long_opt_arg( "extension" )) )
+ {
+ extension = arg;
+ }
if( csr_opt( 'v' ) || csr_long_opt( "version" ) )
{
- printf( "csRadar version: " CSR_VERSION "\n" );
+ printf( "csRadar build: %u, api_version: %u\n", csr_build, csr_api_version );
goto IL_CSR_EXIT;
}
" -g <gameinfo.txt path> Required if you are loading models\n"
" -r 1024 Output resolution\n"
" -o <output> Specify output name/path\n"
+ " -e <classname> Same as default arg, but instead filters for entity class\n"
+ //" -s <height> Add a vertical split at this height\n"
" --padding=128 When cropping radar, add padding units to border\n"
//" --standard-layers Use standard TAR layers/groups\n"
" --no-txt Don't create matching radar txt\n"
}
}
- if( num_strings )
+ if( api.num_strings )
{
- vmf_map *map = vmf_init( strings[0] );
+ if( gameinfo )
+ {
+ fs_set_gameinfo( gameinfo );
+ }
- if( map )
+ // Path handling
+ if( !output_set )
{
- // Path handling
- if( !output_set )
- {
- strcpy( output_path, strings[0] );
- csr_stripext( output_path );
- }
-
- char *base_name;
- if( !(base_name = csr_findext( output_path, '/' ) ))
+ strcpy( api.output_path, api.strings[0].str );
+ csr_stripext( api.output_path );
+ }
+
+ char *base_name;
+ if( !(base_name = csr_findext( api.output_path, '/' ) ))
+ {
+ base_name = api.output_path;
+ }
+
+ strcpy( api.vmf_name, base_name );
+
+ log_info( "output_path: '%s'\n", api.output_path );
+ log_info( "vmf_name: '%s'\n", api.vmf_name );
+
+ api.map = vmf_init( api.strings[0].str );
+ if( api.map )
+ {
+ // Update arg inferred types
+ api.strings[0].type = k_iftype_vmf;
+ for( int i = 1; i < api.num_strings; i ++ )
{
- base_name = output_path;
+ if( vmf_visgroup_id( api.map->root, api.strings[i].str ) != -1 )
+ api.strings[i].type = k_iftype_visgroup;
+ else
+ api.strings[i].type = k_iftype_classname;
}
+
+ if( !extension )
+ extension = "csRadarFree";
+
+ csr_so ext = csr_libopen( extension );
- strcpy( vmf_name, base_name );
-
- log_info( "output_path: '%s'\n", output_path );
- log_info( "vmf_name: '%s'\n", vmf_name );
-
- // Main
- csr_target target;
-
- csr_create_target( &target, resolution, resolution, sampling_mode );
- csr_rt_clear( &target );
-
- csr_use_program( &target, frag_gbuffer );
-
- // Compute bounds
- csr_filter filter =
- {
- .classname = NULL,
- .visgroup = NULL,
- .compute_bounds_only = 1
- };
-
- // One pass for fitting, second pass for drawing
- for( int i = 0; i < 2; i ++ )
+ if( ext )
{
- if( num_strings == 1 )
- {
- // Draw everything
- draw_vmf_group( &target, map, map->root, &filter, NULL, NULL );
- csr_rt_save_buffers( &target, output_path, "all" );
- }
- else
- {
- // Draw groups
- for( int i = 1; i < num_strings; i ++ )
- {
- filter.visgroup = strings[ i ];
-
- draw_vmf_group( &target, map, map->root, &filter, NULL, NULL );
- csr_rt_save_buffers( &target, output_path, strings[i] );
-
- csr_rt_clear( &target );
- }
- }
+ void (*csr_ext_main)(csr_api *);
+ void (*csr_ext_exit)(csr_api *);
- if( i == 0 )
+ csr_ext_main = csr_get_proc( ext, "csr_ext_main" );
+ csr_ext_exit = csr_get_proc( ext, "csr_ext_exit" );
+
+ if( csr_ext_main && csr_ext_exit )
{
- filter.compute_bounds_only = 0;
- csr_auto_fit( &target, padding );
- vmf_load_models( map );
+ csr_ext_main( &api );
+
+ // Do other
+
+ csr_ext_exit( &api );
}
else
{
- float prog = 0.f;
- csr_prog_begin( "Rendering" );
- for(;;)
- {
- if( prog > 1.f )
- break;
-
- csr_prog_update( prog );
- usleep( 20000 );
-
- prog += 0.01f;
- }
-
- csr_prog_end();
+ csr_liberr();
}
+
+ csr_libclose( ext );
}
-
- if( write_txt )
+ else
{
- char txt_path[ 512 ];
-
- strcpy( txt_path, output_path );
- strcat( txt_path, ".txt" );
-
- csr_write_txt( txt_path, vmf_name, &target );
+ csr_liberr();
}
- csr_rt_free( &target );
- vmf_free( map );
+ vmf_free( api.map );
}
else
{