fixed instance loading forget to append basepath.. other path fixes (windows)
[csRadar.git] / csRadar.c
index 9c8c0b4d0f08e8922896ef1911554a2ba8c6e78a..17f09a85b547e5434cfa1499471a8d55179eccf3 100644 (file)
--- a/csRadar.c
+++ b/csRadar.c
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include <time.h>
+// Copyright (C) 2021 Harry Godden (hgn)
 
-// CSR lib
-#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 "csrDraw.h"
-#include "csr32f.h"
-
-
-//#include "stretchy_buffer.h"
+#define VALVE_IMPLEMENTATION
+#define CSR_EXECUTABLE
+#include "csRadar.h"
 
 int main( int argc, char *argv[] )
 {
-       if( argc == 2 )
+       csr_api api = 
        {
-               fs_set_gameinfo( "/home/harry/SteamLibrary/steamapps/common/Counter-Strike Global Offensive/csgo/gameinfo.txt" );
-               
-               printf( "read: %s\n", argv[1] );
-               //vdf_node *node = vdf_open_file( argv[1] );
+               .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( api.num_strings == 20 )
+                       {
+                               log_error( "Too many arguments! Max 20\n" );
+                               goto IL_CSR_EXIT;
+                       }
+                       
+                       api.strings[ api.num_strings ++ ].str = arg;
+               }
                
-               vmf_map *map = vmf_init( argv[1], 1 );
+               if( (arg = csr_opt_arg( 'o' )) )
+               {
+                       strcpy( api.output_path, arg );
+                       output_set = 1;
+               }
                
-               // TODO: Make init/free codes
-               csr_target target = 
+               if( (arg = csr_opt_arg( 'g' )) )
                {
-                       .x = 1024, .y = 1024,
-                       .fragments = (csr_frag *)csr_malloc( 1024*1024*sizeof(csr_frag) ),
-                       .bounds = { -1000.f, -1000.f, 1000.f, 1000.f }
-               };
-               csr_rt_clear( &target );
+                       gameinfo = arg;
+               }
                
-               draw_vmf_group( &target, map, map->root, 0, NULL, NULL );
+               if( (arg = csr_opt_arg( 'r' )) )
+               {
+                       api.resolution = atoi( arg );
+               }
                
-               float *rgba_test = (float *)csr_malloc( 1024*1024*sizeof(float)*3 );
+               if( (arg = csr_long_opt_arg( "padding" )) )
+               {
+                       api.padding = atof( arg );
+               }
                
-               for( int l = 0; l < 1024; l ++ )
+               if( (arg = csr_long_opt_arg( "multi-sample" )) )
                {
-                       for( int x = 0; x < 1024; x ++ )
+                       if( !strcmp( arg, "none" ))
                        {
-                               float *dst = &rgba_test[ (l*1024+x)*3 ];
-                               csr_frag *src = &target.fragments[ ((1023-l)*1024+x) ];
-                               
-                               dst[0] = src->co[0];
-                               dst[1] = src->co[1];
-                               dst[2] = src->co[2];
+                               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;
                        }
                }
                
-               csr_32f_write( "hello.pfm", 1024, 1024, rgba_test );
-               
-               free( target.fragments );
-               free( rgba_test );
-               vmf_free( map );
-               fs_exit();
-               
-               /*
-               vmf_solid solid_main;
+               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 build: %u, api_version: %u\n", csr_build, csr_api_version );
+                       goto IL_CSR_EXIT;
+               }
                
-               solidgen_ctx_init( &solid_main );
+               if( csr_opt( 'h' ) || csr_long_opt( "help" ) )
+               {
+                       // Display help
+                       printf
+                       ( 
+                               "csRadar Copyright (C) 2021 Harry Godden (hgn)\n"
+                               "\n"
+                               "Usage: ./csRadar map.vmf -g \"/gamedir/gameinfo.txt\" layout cover\n"
+                               "   VMF file is first, then any other arguments (eg. layout, cover), will specify\n"
+                               "   visgroups to be rendered into individual files\n"
+                               "   No visgroups specified will simply draw everything\n"
+                               "\n"
+                               "Options:\n"
+                               "   -g <gameinfo.txt path>         Required if you are loading models\n"
+                               "   -r 1024                        Output resolution\n"
+                               "   -o <output>                    Specify output name/path (no extension, dir must exist)\n"
+                               "   -e <classname>                 Same as default arg, but instead filters for entity class\n"
+                               "   --padding=128                  When cropping radar, add padding units to border\n"
+                               "   --no-txt                       Don't create matching radar txt\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"
+                       );
                        
-               vdf_node *world = vdf_next( node, "world", NULL );
-               
-               vdf_foreach( world, "solid", brush )
+                       goto IL_CSR_EXIT;
+               }
+       }
+       
+       if( api.num_strings )
+       {
+               if( gameinfo )
                {
-                       solidgen_push( &solid_main, brush );
+                       fs_set_gameinfo( gameinfo );
                }
-
-               clock_t t;
-               t = clock();
-               printf("Timer starts\n");
-
-               csr_frag *image = (csr_frag *)csr_malloc( 1024*1024*sizeof(csr_frag) );
-               clear_depth( image, 1024, 1024 );
-
-               for( int i = 0; i < csr_sb_count( solid_main.indices )/3; i ++ )
+       
+               // Path handling
+               if( !output_set )
                {
-                       u32 * base = solid_main.indices + i*3;
-                       
-                       vmf_vert tri[3];
-                       
-                       tri[0] = solid_main.verts[ base[0] ];
-                       tri[1] = solid_main.verts[ base[1] ];
-                       tri[2] = solid_main.verts[ base[2] ];
-                       
-                       draw_buffers( image, 1024, 1024, (v4f){ -1000.f, -1000.f, 1000.f, 1000.f }, tri, 1 );
+                       strcpy( api.output_path, api.strings[0].str );
+                       csr_stripext( api.output_path );
                }
                
-               printf("Timer ends \n");
-               t = clock() - t;
-               double time_taken = ((double)t)/CLOCKS_PER_SEC; // calculate the elapsed time
-               printf("Tracing took %f seconds to execute\n", time_taken);
+               strcpy( api.vmf_name, csr_filename( api.output_path ) );
+               strcpy( api.vmf_folder, api.output_path );
+               csr_downlvl( api.vmf_folder );
                
-               float *rgba_test = (float *)csr_malloc( 1024*1024*sizeof(float)*3 );
+               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 );
                
-               for( int i = 0; i < 1024*1024; i ++ )
+               api.map = vmf_init( api.strings[0].str );
+               if( api.map )
                {
-                       rgba_test[i*3+0] = image[i].qa;
-                       rgba_test[i*3+1] = image[i].qb;
-                       rgba_test[i*3+2] = image[i].depth;
-               }
-               
-               csr_32f_write( "hello.pfm", 1024, 1024, rgba_test );
-               
-               free( rgba_test );
-               free( image );
+                       // Update arg inferred types
+                       api.strings[0].type = k_iftype_vmf;
+                       for( int i = 1; i < api.num_strings; i ++ )
+                       {
+                               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;
+                       }
                
-               solidgen_to_obj( &solid_main, "hello.obj" );
+                       if( !extension )
+                               extension = "csr_substance";
                
-               vdf_free_r( node );
-               */
+                       csr_so ext = csr_libopen( extension );
+                       
+                       if( ext )
+                       {
+                               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" );
+                                       
+                               if( csr_ext_main && csr_ext_exit )
+                               {
+                                       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
+                               {
+                                       csr_liberr();
+                               }
+                               
+                               csr_libclose( ext );
+                       }
+                       else
+                       {
+                               csr_liberr();
+                       }
+                       
+                       vmf_free( api.map );
+               }
+               else
+               {
+                       log_error( "Could not load VMF\n" );
+               }
+       }
+       else
+       {
+               log_error( "Missing required argument: mapfile\n" );
        }
+       
+IL_CSR_EXIT:
+       fs_exit();
+       return 0;
 }