X-Git-Url: https://harrygodden.com/git/?p=csRadar.git;a=blobdiff_plain;f=csRadar.c;h=17f09a85b547e5434cfa1499471a8d55179eccf3;hp=b05b6a6be3126ae06e7d385c4923f90bd7f99498;hb=HEAD;hpb=a53095e1511fecb8cc83c692e7ce7b23852fff16 diff --git a/csRadar.c b/csRadar.c index b05b6a6..17f09a8 100644 --- a/csRadar.c +++ b/csRadar.c @@ -1,92 +1,106 @@ -#include -#include -#include -#include -#include -#include +// Copyright (C) 2021 Harry Godden (hgn) -// CSR lib -#include "csrOpt.h" -#include "csrTypes.h" -#include "csrMath.h" -#include "csrMem.h" -#include "csrIO.h" -#include "csrComb.h" +// Building: +// gcc -rdynamic csRadar.c -o csRadar -lm -ldl +// +// Plugins: +// gcc -fpic -shared -o ext/my_plugin.so my_plugin.c -lm -// 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 standard_layers = 0; - int write_txt = 1; - int multi_sample = 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, + .min_z = -INFINITY, + .max_z = INFINITY, + .write_txt = 1, + .api_version = csr_api_version, + .sampling_mode = k_EMSAA_RGSS + }; + int output_set = 0; + 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 ) { - fprintf( stderr, "Too many arguments! Max 20\n" ); - fs_exit(); - exit(0); + log_error( "Too many arguments! Max 20\n" ); + goto IL_CSR_EXIT; } - printf( "got: %s\n", arg ); - - 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 ); 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" )) + { + api.sampling_mode = k_EMSAA_none; + } + else if( !strcmp( arg, "rgss" )) + { + api.sampling_mode = k_EMSAA_RGSS; + } + else if( !strcmp( arg, "2x" )) + { + api.sampling_mode = k_EMSAA_2x2; + } + else if( !strcmp( arg, "8r" )) + { + api.sampling_mode = k_EMSAA_8R; + } + else + { + log_error( "Invalid sampling pattern '%s'\n", arg ); + goto IL_CSR_EXIT; + } + } + + if( (arg = csr_long_opt_arg( "extension" )) ) + { + extension = arg; } + + if( (arg = csr_long_opt_arg( "min" )) ) + api.min_z = atof( arg ); + if( (arg = csr_long_opt_arg( "max" )) ) + api.max_z = atof( arg ); if( csr_opt( 'v' ) || csr_long_opt( "version" ) ) { - printf( "csRadar version: " CSR_VERSION "\n" ); - return 0; + printf( "csRadar build: %u, api_version: %u\n", csr_build, csr_api_version ); + goto IL_CSR_EXIT; } if( csr_opt( 'h' ) || csr_long_opt( "help" ) ) @@ -104,110 +118,111 @@ int main( int argc, char *argv[] ) "Options:\n" " -g Required if you are loading models\n" " -r 1024 Output resolution\n" - " -o Specify output name/path\n" + " -o Specify output name/path (no extension, dir must exist)\n" + " -e Same as default arg, but instead filters for entity class\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" - " --multi-sample= [ none, 2, 4, 4r, 8kn (default), 16c ]\n" + " --multi-sample=rgss [ none, 2x, rgss, 8r ]\n" + " --extension=TAR Use an extension binary instead\n" + " --min=z Miniumum height to render\n" + " --max=z Maxiumum height to render\n" "\n" " -v --version Display program version\n" " -h --help Display this help text\n" ); - return 0; + goto IL_CSR_EXIT; } } - if( num_strings ) + if( api.num_strings ) { - vmf_map *map = vmf_init( strings[0], 1 ); + if( gameinfo ) + { + fs_set_gameinfo( gameinfo ); + } - if( map ) + // Path handling + if( !output_set ) { - // Path handling - if( !output_set ) + strcpy( api.output_path, api.strings[0].str ); + csr_stripext( api.output_path ); + } + + strcpy( api.vmf_name, csr_filename( api.output_path ) ); + strcpy( api.vmf_folder, api.output_path ); + csr_downlvl( api.vmf_folder ); + + log_info( "output_path: '%s'\n", api.output_path ); + log_info( "vmf_name: '%s'\n", api.vmf_name ); + log_info( "vmf_folder: '%s'\n", api.vmf_folder ); + + 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 ++ ) { - strcpy( output_path, strings[0] ); - csr_stripext( 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 = "csr_substance"; + + csr_so ext = csr_libopen( extension ); - char *base_name; - if( !(base_name = csr_findext( output_path, '/' ) )) + if( ext ) { - base_name = output_path; - } - - strcpy( vmf_name, base_name ); - - printf( "output_path: '%s'\nvmf_name: '%s'\n", output_path, vmf_name ); - - - // Main + void (*csr_ext_main)(csr_api *); + void (*csr_ext_exit)(csr_api *); + + csr_ext_main = csr_get_proc( ext, "csr_ext_main" ); + csr_ext_exit = csr_get_proc( ext, "csr_ext_exit" ); - csr_target target; - - csr_create_target( &target, resolution, resolution ); - csr_rt_clear( &target ); - - // 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( num_strings == 1 ) + if( csr_ext_main && csr_ext_exit ) { - // Draw everything - draw_vmf_group( &target, map, map->root, &filter, NULL, NULL ); - csr_rt_save_buffers( &target, output_path, "all" ); + csr_ext_main( &api ); + + // Do other + if( api.write_txt ) + { + char radar_path[512]; + strcpy( radar_path, api.output_path ); + strcat( radar_path, ".txt" ); + csr_write_txt( radar_path, api.vmf_name, &api.target ); + } + + csr_ext_exit( &api ); } 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 ); - } + csr_liberr(); } - filter.compute_bounds_only = 0; - csr_auto_fit( &target, padding ); + 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 { - fprintf( stderr, "Could not load VMF\n" ); + log_error( "Could not load VMF\n" ); } } else { - fprintf( stderr, "Missing required argument: mapfile\n" ); + log_error( "Missing required argument: mapfile\n" ); } +IL_CSR_EXIT: fs_exit(); - return 0; }