00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifdef HAVE_CONFIG_H
00020 #include <config.h>
00021 #endif
00022
00023 #include "ops.h"
00024 #include "files/utils.h"
00025 #include "exceptions.h"
00026 #include <cstdlib>
00027 #include <iomanip>
00028 #include <fstream>
00029 #include <stack>
00030 #ifdef HAVE_SSTREAM
00031 #include <sstream>
00032 using std::stringstream;
00033 #endif
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 using std::vector;
00047 using std::ifstream;
00048 using std::cout;
00049 using std::endl;
00050 using std::string;
00051 using std::cerr;
00052 using std::ends;
00053 using std::setw;
00054 using std::setfill;
00055 using std::setbase;
00056 using std::pair;
00057 using std::map;
00058
00059 #define MAX_NO_OPCODES 512
00060 vector<UCOpcodeData> opcode_table_data(MAX_NO_OPCODES);
00061
00062 vector<pair<unsigned int, unsigned int> > opcode_jumps;
00063
00064 map<unsigned int, string> uc_intrinsics;
00065
00066 map<string, pair<unsigned int, bool> > type_size_map;
00067
00068 void ucxtInit::init(const Configuration &config, const UCOptions &options)
00069 {
00070 datadir = get_datadir(config, options);
00071
00072 misc_data = "u7misc.data";
00073 misc_root = "misc";
00074
00075 opcodes_data = "u7opcodes.data";
00076 opcodes_root = "opcodes";
00077
00078 bg_intrinsics_data = "u7bgintrinsics.data";
00079 bg_intrinsics_root = "intrinsics";
00080
00081 si_intrinsics_data = "u7siintrinsics.data";
00082 si_intrinsics_root = "intrinsics";
00083
00084 if(options.verbose) cout << "Initing misc..." << endl;
00085 misc();
00086
00087 if(options.verbose) cout << "Initing opcodes..." << endl;
00088 opcodes();
00089
00090 if(options.verbose) cout << "Initing intrinsics..." << endl;
00091 if(options.game_bg())
00092 intrinsics(bg_intrinsics_data, bg_intrinsics_root);
00093 else if(options.game_si())
00094 intrinsics(si_intrinsics_data, si_intrinsics_root);
00095 }
00096
00097 string ucxtInit::get_datadir(const Configuration &config, const UCOptions &options)
00098 {
00099 string datadir;
00100
00101
00102 #ifdef HAVE_CONFIG_H
00103 if(options.noconf == false) config.value("config/ucxt/root", datadir, EXULT_DATADIR);
00104 #else
00105 if(options.noconf == false) config.value("config/ucxt/root", datadir, "data/");
00106 #endif
00107
00108 if(datadir.size() && datadir[datadir.size()-1]!='/' && datadir[datadir.size()-1]!='\\') datadir+='/';
00109 if(options.verbose) cout << "datadir: " << datadir << endl;
00110
00111 return datadir;
00112 }
00113
00114 void ucxtInit::misc()
00115 {
00116 Configuration miscdata(datadir + misc_data, misc_root);
00117
00118 Configuration::KeyTypeList om;
00119 miscdata.getsubkeys(om, misc_root + "/offset_munge");
00120
00121 Configuration::KeyTypeList st;
00122 miscdata.getsubkeys(st, misc_root + "/size_type");
00123
00124
00125 for(typeof(st.begin()) k=st.begin(); k!=st.end(); ++k)
00126 {
00127 bool munge_offset=false;
00128
00129 const string tmpstr(k->first + "/");
00130
00131
00132
00133 for(typeof(om.begin()) m=om.begin(); m!=om.end(); ++m)
00134 if(m->first.size()-1==k->first.size())
00135 if(m->first==tmpstr)
00136
00137 munge_offset=true;
00138
00139
00140 pair<unsigned int, bool> tsm_tmp(strtol(k->second.c_str(), 0, 0), munge_offset);
00141 type_size_map.insert(pair<string, pair<unsigned int, bool> >(k->first, tsm_tmp));
00142 }
00143 }
00144
00145
00146 void ucxtInit::opcodes()
00147 {
00148 Configuration opdata(datadir + opcodes_data, opcodes_root);
00149
00150 vector<string> keys = opdata.listkeys(opcodes_root);
00151
00152 #if 1
00153 for(vector<string>::iterator key=keys.begin(); key!=keys.end(); ++key)
00154 {
00155 if((*key)[0]!='!')
00156 {
00157 Configuration::KeyTypeList ktl;
00158
00159 opdata.getsubkeys(ktl, *key);
00160
00161 if(ktl.size())
00162 {
00163 unsigned int i = strtol(key->substr(key->find_first_of("0")).c_str(), 0, 0);
00164 opcode_table_data[i] = UCOpcodeData(i, ktl);
00165 }
00166 }
00167 }
00168
00169 #else
00170
00171 string ucxtroot(datadir + "opcodes.txt");
00172
00173 std::ifstream file;
00174
00175 try
00176 {
00177 U7open(file, ucxtroot.c_str(), true);
00178 } catch (const file_open_exception& e)
00179 {
00180 cerr << e.what() << ". exiting." << endl;
00181 exit(1);
00182 }
00183
00184 std::string s;
00185 while(!file.eof())
00186 {
00187 getline(file, s);
00188 if(s.size() && s[0]=='>')
00189 {
00190 UCOpcodeData uco(str2vec(s));
00191 assert(uco.opcode<MAX_NO_OPCODES);
00192 opcode_table_data[uco.opcode] = uco;
00193 }
00194 }
00195 file.close();
00196 #endif
00197
00198
00199
00200 for(std::vector<UCOpcodeData>::iterator op=opcode_table_data.begin(); op!=opcode_table_data.end(); op++)
00201 {
00202 for(unsigned int i=0; i<op->param_sizes.size(); i++)
00203 {
00204 if(op->param_sizes[i].second==true)
00205 {
00206 opcode_jumps.push_back(std::pair<unsigned int, unsigned int>(op->opcode, i+1));
00207 }
00208 }
00209 }
00210
00211 #if 0
00212 std::cout << "Calculated Opcode pairs:" << std::endl;
00213 for(std::vector<std::pair<unsigned int, unsigned int> >::iterator i=opcode_jumps.begin(); i!=opcode_jumps.end(); i++)
00214 std::cout << setw(4) << i->first << '\t' << setw(4) << i->second << std::endl;
00215 #endif
00216 }
00217
00218 void ucxtInit::intrinsics(const string &intrinsic_data, const string &intrinsic_root)
00219 {
00220 Configuration intdata(datadir + intrinsic_data, intrinsic_root);
00221
00222 Configuration::KeyTypeList ktl;
00223
00224 intdata.getsubkeys(ktl, intrinsic_root);
00225
00226 for(Configuration::KeyTypeList::iterator k=ktl.begin(); k!=ktl.end(); k++)
00227 uc_intrinsics.insert(pair<unsigned int, string>(strtol(k->first.c_str(), 0, 0), k->second));
00228 }
00229
00230
00231 std::vector<std::string> qnd_ocsplit(const std::string &s)
00232 {
00233 assert((s[0]=='{') && (s[s.size()-1]=='}'));
00234
00235 std::vector<std::string> vs;
00236 std::string tstr;
00237
00238 for(std::string::const_iterator i=s.begin(); i!=s.end(); ++i)
00239 {
00240 if(*i==',')
00241 {
00242 vs.push_back(tstr);
00243 tstr="";
00244 }
00245 else if(*i=='{' || *i=='}')
00246 { }
00247 else
00248 tstr+=*i;
00249 }
00250 if(tstr.size())
00251 vs.push_back(tstr);
00252
00253 return vs;
00254 }
00255
00256 std::vector<std::string> str2vec(const std::string &s)
00257 {
00258 std::vector<std::string> vs;
00259 unsigned int lasti=0;
00260
00261
00262 if(s.size()==0) return vs;
00263
00264 bool indquote=false;
00265 for(unsigned int i=0; i<s.size(); i++)
00266 {
00267 if(s[i]=='"')
00268 indquote = !indquote;
00269 else if(isspace(s[i]) && (!indquote))
00270 {
00271 if(lasti!=i)
00272 {
00273 if((s[lasti]=='"') && (s[i-1]=='"'))
00274 {
00275 if((lasti+1)!=(lasti-1))
00276 vs.push_back(s.substr(lasti+1, i-lasti-2));
00277 }
00278 else
00279 vs.push_back(s.substr(lasti, i-lasti));
00280 }
00281
00282 lasti=i+1;
00283 }
00284 if(i==s.size()-1)
00285 {
00286 if((s[lasti]=='"') && (s[i]=='"'))
00287 {
00288 if((lasti+1)!=(lasti-1))
00289 vs.push_back(s.substr(lasti+1, i-lasti-2));
00290 }
00291 else
00292 vs.push_back(s.substr(lasti, i-lasti+1));
00293 }
00294 }
00295
00296 #if 0 //test
00297 for(unsigned int i=0; i<vs.size(); i++)
00298 std::cout << "\t\"" << vs[i] << "\"" << std::endl;
00299 #endif
00300
00301 return vs;
00302 }
00303
00304 void map_type_size(const std::vector<std::string> ¶m_types, std::vector<std::pair<unsigned int, bool> > ¶m_sizes)
00305 {
00306 for(std::vector<std::string>::const_iterator s=param_types.begin(); s!=param_types.end(); ++s)
00307 {
00308 map<string, pair<unsigned int, bool> >::iterator tsm(type_size_map.find(*s));
00309 if(tsm==type_size_map.end())
00310 {
00311 cerr << "error: No size type `" << *s << "`" << endl;
00312 assert(tsm!=type_size_map.end());
00313 }
00314
00315 param_sizes.push_back(std::pair<unsigned int, bool>(tsm->second.first, tsm->second.second));
00316 }
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400