1 #define NOMINMAX
2 #include <windows.h>
3 #include <cstring>
4 #include "xr_file_system.h"
5 #include "xr_ini_file.h"
6 #include "xr_string_utils.h"
7 #include "xr_cl_parser.h"
8 #include "xr_log.h"
9 #include "aiwrapper.h"
10 #include "syncer.h"
11
12 using namespace xray_re;
13
usage()14 const void usage()
15 {
16 printf("X-Ray AI compiler wrapper (%s)\n", BUILD_DATE);
17 printf("Vendor: ZENOBIAN mod team\n");
18 printf("Usage: aiwrapper <options>\n\n");
19 printf("xrAI derived options:\n");
20 printf(" -h or -? this help\n");
21 printf(" -verify <NAME> verify AI map in gamedata\\levels\\<NAME>\\\n");
22 printf(" -f <NAME> build AI map in gamedata\\levels\\<NAME>\\\n");
23 printf(" -g <NAME> build off-line AI graph and cross-table to AI map in gamedata\\levels\\<NAME>\\\n");
24 printf(" -m merge level graphs\n");
25 printf(" -s build game spawn data\n");
26 printf(" -draft build draft AI map\n\n");
27 printf("Custom options:\n");
28 printf(" -fs <SPEC> use <SPEC> as file system specification file (default is %s)\n", DEFAULT_FS_SPEC);
29 printf(" -fast_sync update just older files in shadow xrAI tree\n");
30 printf(" -split_spawns restore level.spawn files from all.spawn/game.graph\n");
31 printf(" -split_paths restore level.game files from all.spawn\n");
32 printf(" -split_graphs restore level.graph files from all.spawn/game.graph\n");
33 printf(" -check_paths check walk paths in all.spawn\n");
34 printf(" -upgrade <BLD> convert levels into CS (3502) or CoP (3870) format\n\n");
35 printf("Deprecated options:\n");
36 printf(" -m2 <FILE> adjust level graphs according to <FILE> and merge them\n");
37 printf(" -dump_gp dump list of graph points in all level.spawn files\n");
38 // printf(" -use_orig_gp read graph points from original level.spawn\n");
39 }
40
run_xrai(const char * opt,const char * arg=0)41 static void run_xrai(const char* opt, const char* arg = 0)
42 {
43 xr_file_system& fs = xr_file_system::instance();
44 const char* root = fs.resolve_path(PA2215_FS_ROOT);
45 char cmd[2*MAX_PATH];
46 xr_snprintf(cmd, sizeof(cmd), "%sxrAI.exe %s%s%s", root, opt, arg ? " " : "", arg ? arg : "");
47 STARTUPINFOA si = {0};
48 si.cb = sizeof(si);
49 PROCESS_INFORMATION pi = {0};
50 msg("launching '%s'", cmd + std::strlen(root));
51 BOOL success = CreateProcessA(NULL, cmd, NULL, NULL, FALSE, 0, NULL, root, &si, &pi);
52 if (!success)
53 throw syncer::sync_error();
54 WaitForSingleObject(pi.hProcess, INFINITE);
55 CloseHandle(pi.hProcess);
56 CloseHandle(pi.hThread);
57 }
58
main(int argc,char * argv[])59 int main(int argc, char* argv[])
60 {
61 static const cl_parser::option_desc options[] = {
62 {"-h", cl_parser::OT_BOOL},
63 {"-?", cl_parser::OT_BOOL},
64 {"-verify", cl_parser::OT_STRING},
65 {"-f", cl_parser::OT_STRING},
66 {"-g", cl_parser::OT_STRING},
67 {"-m", cl_parser::OT_BOOL},
68 {"-s", cl_parser::OT_BOOL},
69 {"-draft", cl_parser::OT_BOOL},
70 {"-fs", cl_parser::OT_STRING},
71 {"-fast_sync", cl_parser::OT_BOOL},
72 {"-split_spawns", cl_parser::OT_BOOL},
73 {"-split_paths", cl_parser::OT_BOOL},
74 {"-split_graphs", cl_parser::OT_BOOL},
75 {"-check_paths", cl_parser::OT_BOOL},
76 {"-upgrade", cl_parser::OT_INTEGER},
77 {"-m2", cl_parser::OT_STRING},
78 {"-dump_gp", cl_parser::OT_BOOL},
79 {"-use_orig_dp", cl_parser::OT_BOOL},
80 };
81 cl_parser cl;
82 if (!cl.parse(argc, argv, xr_dim(options), options) || cl.num_params() != 0) {
83 usage();
84 return 1;
85 }
86 if (cl.get_bool("-h") || cl.get_bool("-?") || cl.num_options() == 0) {
87 usage();
88 return 0;
89 }
90
91 const char* fs_spec;
92 if (!cl.get_string("-fs", fs_spec))
93 fs_spec = DEFAULT_FS_SPEC;
94 if (!xr_file_system::file_exist(fs_spec)) {
95 msg("can't find %s", fs_spec);
96 return 1;
97 }
98 xr_file_system& fs = xr_file_system::instance();
99 if (!fs.initialize(fs_spec, 0)) {
100 msg("can't initialize the file system");
101 return 1;
102 }
103 xr_log::instance().init("aiwrapper");
104
105 try {
106 syncer sync;
107 sync.check_fs_paths();
108 sync.load_ini("aiwrapper.ini");
109 unsigned force = cl.get_bool("-fast_sync") ? 0 : SYNC_FORCE;
110 const char* name;
111 int bld_ver;
112 if (cl.get_string("-f", name)) {
113 sync.to_xrai(name, SYNC_BUILD_AIMAP|SYNC_BUILD_CFORM|SYNC_BUILD_PRJ|force);
114 run_xrai((cl.get_bool("-draft") ? "-draft -f" : "-f"), name);
115 sync.from_xrai(name, SYNC_LEVEL_AI|SYNC_FORCE);
116 } else if (cl.get_string("-verify", name)) {
117 sync.to_xrai(name, SYNC_LEVEL_AI|force);
118 run_xrai("-verify", name);
119 } else if (cl.get_string("-g", name)) {
120 sync.to_xrai(name, SYNC_LEVEL_AI|SYNC_LEVEL_SECTORS_AI|SYNC_LEVEL_SPAWN|force);
121 run_xrai("-g", name);
122 sync.from_xrai(name, SYNC_LEVEL_GRAPH|SYNC_LEVEL_GCT_RAW|SYNC_LEVEL_SECTORS_AI|SYNC_FORCE);
123 } else if (cl.get_bool("-m")) {
124 sync.to_xrai(SYNC_GAME_LTX|SYNC_LEVEL_AI|SYNC_LEVEL_GCT_RAW|SYNC_LEVEL_GRAPH|SYNC_LEVEL_SPAWN|force);
125 run_xrai("-m");
126 sync.from_xrai(SYNC_GAME_GRAPH|SYNC_LEVEL_GCT|SYNC_LEVEL_GCT_RAW|SYNC_FORCE);
127 } else if (cl.get_bool("-s")) {
128 sync.to_xrai(SYNC_GAME_LTX|SYNC_GAME_GRAPH|SYNC_LEVEL_AI|SYNC_LEVEL_SECTORS_AI|
129 SYNC_LEVEL_GRAPH|SYNC_LEVEL_GCT|SYNC_LEVEL_GCT_RAW|SYNC_LEVEL_SPAWN|force);
130 run_xrai("-s");
131 sync.from_xrai(SYNC_GAME_SPAWN|SYNC_LEVEL_SECTORS_AI|SYNC_FORCE);
132 } else if (cl.get_bool("-split_spawns")) {
133 sync.split_spawns(cl.get_bool("-use_orig_gp"));
134 } else if (cl.get_bool("-split_paths")) {
135 sync.split_paths();
136 } else if (cl.get_bool("-split_graphs")) {
137 sync.split_graphs();
138 } else if (cl.get_bool("-check_paths")) {
139 sync.check_paths();
140 } else if (cl.get_integer("-upgrade", bld_ver)) {
141 sync.upgrade(bld_ver);
142 } else if (cl.get_string("-m2", name)) {
143 sync.load_links_ini(name);
144 sync.to_xrai(SYNC_GAME_LTX|SYNC_LEVEL_AI|SYNC_LEVEL_GCT_RAW|SYNC_LEVEL_GRAPH|SYNC_LEVEL_SPAWN|force);
145 run_xrai("-m");
146 sync.from_xrai(SYNC_GAME_GRAPH|SYNC_LEVEL_GCT|SYNC_LEVEL_GCT_RAW|SYNC_FORCE);
147 } else if (cl.get_bool("-dump_gp")) {
148 sync.dump_links("links.output");
149 } else {
150 usage();
151 }
152 } catch (syncer::sync_error) {
153 msg("ERROR occured! Aborting.");
154 }
155 return 0;
156 }
157