finish up plugin architecture
[csRadar.git] / csRadar.c
1 #define VALVE_IMPLEMENTATION
2 #define CSR_EXECUTABLE
3 #include "csRadar.h"
4
5 // gcc -Wall -fsanitize=address csRadar.c -o csRadar -lm
6
7 int main( int argc, char *argv[] )
8 {
9 csr_api api =
10 {
11 .padding = 128.f,
12 .resolution = 1024,
13 .write_txt = 1,
14 .api_version = csr_api_version,
15 .sampling_mode = k_EMSAA_RGSS
16 };
17
18 int output_set = 0;
19 char *extension = NULL;
20
21 char *arg;
22 while( csr_argp( argc, argv ) )
23 {
24 if( (arg = csr_arg()) )
25 {
26 if( api.num_strings == 20 )
27 {
28 log_error( "Too many arguments! Max 20\n" );
29 goto IL_CSR_EXIT;
30 }
31
32 api.strings[ api.num_strings ++ ] = arg;
33 }
34
35 if( (arg = csr_opt_arg( 'o' )) )
36 {
37 strcpy( api.output_path, arg );
38 csr_path_winunix( api.output_path );
39
40 output_set = 1;
41 }
42
43 if( (arg = csr_opt_arg( 'g' )) )
44 {
45 fs_set_gameinfo( arg );
46 }
47
48 if( (arg = csr_opt_arg( 'r' )) )
49 {
50 api.resolution = atoi( arg );
51 }
52
53 if( (arg = csr_long_opt_arg( "padding" )) )
54 {
55 api.padding = atof( arg );
56 }
57
58 if( (arg = csr_long_opt_arg( "multi-sample" )) )
59 {
60 if( !strcmp( arg, "none" ))
61 {
62 api.sampling_mode = k_EMSAA_none;
63 }
64 else if( !strcmp( arg, "rgss" ))
65 {
66 api.sampling_mode = k_EMSAA_RGSS;
67 }
68 else if( !strcmp( arg, "2x" ))
69 {
70 api.sampling_mode = k_EMSAA_2x2;
71 }
72 else if( !strcmp( arg, "8r" ))
73 {
74 api.sampling_mode = k_EMSAA_8R;
75 }
76 else
77 {
78 log_error( "Invalid sampling pattern '%s'\n", arg );
79 goto IL_CSR_EXIT;
80 }
81 }
82
83 if( (arg = csr_long_opt_arg( "extension" )) )
84 {
85 extension = arg;
86 }
87
88 if( csr_opt( 'v' ) || csr_long_opt( "version" ) )
89 {
90 printf( "csRadar build: %u, api_version: %u\n", csr_build, csr_api_version );
91 goto IL_CSR_EXIT;
92 }
93
94 if( csr_opt( 'h' ) || csr_long_opt( "help" ) )
95 {
96 // Display help
97 printf
98 (
99 "csRadar Copyright (C) 2021 Harry Godden (hgn)\n"
100 "\n"
101 "Usage: ./csRadar map.vmf -g \"/gamedir/gameinfo.txt\" layout cover\n"
102 " VMF file is first, then any other arguments (eg. layout, cover), will specify\n"
103 " visgroups to be rendered into individual files\n"
104 " No visgroups specified will simply draw everything\n"
105 "\n"
106 "Options:\n"
107 " -g <gameinfo.txt path> Required if you are loading models\n"
108 " -r 1024 Output resolution\n"
109 " -o <output> Specify output name/path\n"
110 " --padding=128 When cropping radar, add padding units to border\n"
111 //" --standard-layers Use standard TAR layers/groups\n"
112 " --write-normals Enable normals as an output stream\n"
113 " --write-origins Enable entity origins as an output stream\n"
114 " --no-txt Don't create matching radar txt\n"
115 " --multi-sample=RGSS [ none, 2x, rgss, 8r ]\n"
116 " --extension=TAR Use an extension binary instead\n"
117 "\n"
118 " -v --version Display program version\n"
119 " -h --help Display this help text\n"
120 );
121
122 goto IL_CSR_EXIT;
123 }
124 }
125
126 if( api.num_strings )
127 {
128 // Path handling
129 if( !output_set )
130 {
131 strcpy( api.output_path, api.strings[0] );
132 csr_stripext( api.output_path );
133 }
134
135 char *base_name;
136 if( !(base_name = csr_findext( api.output_path, '/' ) ))
137 {
138 base_name = api.output_path;
139 }
140
141 strcpy( api.vmf_name, base_name );
142
143 log_info( "output_path: '%s'\n", api.output_path );
144 log_info( "vmf_name: '%s'\n", api.vmf_name );
145
146 api.map = vmf_init( api.strings[0] );
147 if( api.map )
148 {
149 if( !extension )
150 extension = "csRadarFree";
151
152 csr_so ext = csr_libopen( extension );
153
154 if( ext )
155 {
156 void (*csr_ext_main)(csr_api *);
157 void (*csr_ext_exit)(csr_api *);
158
159 csr_ext_main = csr_get_proc( ext, "csr_ext_main" );
160 csr_ext_exit = csr_get_proc( ext, "csr_ext_exit" );
161
162 if( csr_ext_main && csr_ext_exit )
163 {
164 csr_ext_main( &api );
165
166 // Do other
167
168 csr_ext_exit( &api );
169 }
170 else
171 {
172 csr_liberr();
173 }
174
175 csr_libclose( ext );
176 }
177 else
178 {
179 csr_liberr();
180 }
181
182 vmf_free( api.map );
183 }
184 else
185 {
186 log_error( "Could not load VMF\n" );
187 }
188 }
189 else
190 {
191 log_error( "Missing required argument: mapfile\n" );
192 }
193
194 IL_CSR_EXIT:
195 fs_exit();
196 return 0;
197 }