1 // Copyright (C) 2021 Harry Godden (hgn)
4 // gcc -rdynamic csRadar.c -o csRadar -lm -ldl
7 // gcc -fpic -shared -o ext/my_plugin.so my_plugin.c -lm
9 #define VALVE_IMPLEMENTATION
10 #define CSR_EXECUTABLE
13 int main( int argc
, char *argv
[] )
22 .api_version
= csr_api_version
,
23 .sampling_mode
= k_EMSAA_RGSS
27 char *extension
= NULL
;
28 char *gameinfo
= NULL
;
31 while( csr_argp( argc
, argv
) )
33 if( (arg
= csr_arg()) )
35 if( api
.num_strings
== 20 )
37 log_error( "Too many arguments! Max 20\n" );
41 api
.strings
[ api
.num_strings
++ ].str
= arg
;
44 if( (arg
= csr_opt_arg( 'o' )) )
46 strcpy( api
.output_path
, arg
);
50 if( (arg
= csr_opt_arg( 'g' )) )
55 if( (arg
= csr_opt_arg( 'r' )) )
57 api
.resolution
= atoi( arg
);
60 if( (arg
= csr_long_opt_arg( "padding" )) )
62 api
.padding
= atof( arg
);
65 if( (arg
= csr_long_opt_arg( "multi-sample" )) )
67 if( !strcmp( arg
, "none" ))
69 api
.sampling_mode
= k_EMSAA_none
;
71 else if( !strcmp( arg
, "rgss" ))
73 api
.sampling_mode
= k_EMSAA_RGSS
;
75 else if( !strcmp( arg
, "2x" ))
77 api
.sampling_mode
= k_EMSAA_2x2
;
79 else if( !strcmp( arg
, "8r" ))
81 api
.sampling_mode
= k_EMSAA_8R
;
85 log_error( "Invalid sampling pattern '%s'\n", arg
);
90 if( (arg
= csr_long_opt_arg( "extension" )) )
95 if( (arg
= csr_long_opt_arg( "min" )) )
96 api
.min_z
= atof( arg
);
97 if( (arg
= csr_long_opt_arg( "max" )) )
98 api
.max_z
= atof( arg
);
100 if( csr_opt( 'v' ) || csr_long_opt( "version" ) )
102 printf( "csRadar build: %u, api_version: %u\n", csr_build
, csr_api_version
);
106 if( csr_opt( 'h' ) || csr_long_opt( "help" ) )
111 "csRadar Copyright (C) 2021 Harry Godden (hgn)\n"
113 "Usage: ./csRadar map.vmf -g \"/gamedir/gameinfo.txt\" layout cover\n"
114 " VMF file is first, then any other arguments (eg. layout, cover), will specify\n"
115 " visgroups to be rendered into individual files\n"
116 " No visgroups specified will simply draw everything\n"
119 " -g <gameinfo.txt path> Required if you are loading models\n"
120 " -r 1024 Output resolution\n"
121 " -o <output> Specify output name/path (no extension, dir must exist)\n"
122 " -e <classname> Same as default arg, but instead filters for entity class\n"
123 " --padding=128 When cropping radar, add padding units to border\n"
124 " --no-txt Don't create matching radar txt\n"
125 " --multi-sample=rgss [ none, 2x, rgss, 8r ]\n"
126 " --extension=TAR Use an extension binary instead\n"
127 " --min=z Miniumum height to render\n"
128 " --max=z Maxiumum height to render\n"
130 " -v --version Display program version\n"
131 " -h --help Display this help text\n"
138 if( api
.num_strings
)
142 fs_set_gameinfo( gameinfo
);
148 strcpy( api
.output_path
, api
.strings
[0].str
);
149 csr_stripext( api
.output_path
);
152 strcpy( api
.vmf_name
, csr_filename( api
.output_path
) );
153 strcpy( api
.vmf_folder
, api
.output_path
);
154 csr_downlvl( api
.vmf_folder
);
156 log_info( "output_path: '%s'\n", api
.output_path
);
157 log_info( "vmf_name: '%s'\n", api
.vmf_name
);
158 log_info( "vmf_folder: '%s'\n", api
.vmf_folder
);
160 api
.map
= vmf_init( api
.strings
[0].str
);
163 // Update arg inferred types
164 api
.strings
[0].type
= k_iftype_vmf
;
165 for( int i
= 1; i
< api
.num_strings
; i
++ )
167 if( vmf_visgroup_id( api
.map
->root
, api
.strings
[i
].str
) != -1 )
168 api
.strings
[i
].type
= k_iftype_visgroup
;
170 api
.strings
[i
].type
= k_iftype_classname
;
174 extension
= "csr_substance";
176 csr_so ext
= csr_libopen( extension
);
180 void (*csr_ext_main
)(csr_api
*);
181 void (*csr_ext_exit
)(csr_api
*);
183 csr_ext_main
= csr_get_proc( ext
, "csr_ext_main" );
184 csr_ext_exit
= csr_get_proc( ext
, "csr_ext_exit" );
186 if( csr_ext_main
&& csr_ext_exit
)
188 csr_ext_main( &api
);
193 char radar_path
[512];
194 strcpy( radar_path
, api
.output_path
);
195 strcat( radar_path
, ".txt" );
196 csr_write_txt( radar_path
, api
.vmf_name
, &api
.target
);
199 csr_ext_exit( &api
);
217 log_error( "Could not load VMF\n" );
222 log_error( "Missing required argument: mapfile\n" );