00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pent_include.h"
00020
00021 #include "util.h"
00022
00023 #include "FileSystem.h"
00024
00025 #include "Args.h"
00026
00027 #include "ConvertShape.h"
00028
00029 #include "crusader/ConvertShapeCrusader.h"
00030 #include "u8/ConvertShapeU8.h"
00031
00032 const ConvertShapeFormat AutoShapeFormat =
00033 {
00034 "Auto Detected",
00035
00036 0,
00037 0,
00038
00039 0,
00040 0,
00041 0,
00042
00043 0,
00044 0,
00045 0,
00046 0,
00047 0,
00048
00049 0,
00050 0,
00051 0,
00052 0,
00053 0,
00054 0,
00055 0,
00056
00057 0,
00058 0
00059 };
00060
00061
00062 const ConvertShapeFormat *read_format = &AutoShapeFormat;
00063 const ConvertShapeFormat *write_format = &U8ShapeFormat;
00064
00065
00066 #ifdef EXPORT_SHAPENUM
00067 int shapenum;
00068 #endif
00069
00070
00071 void ConvertFlexes(IDataSource *readfile, ODataSource *writefile)
00072 {
00073 ConvertShape shape;
00074 uint32 i;
00075
00076
00077 readfile->seek(0x54);
00078 uint32 num_entries = readfile->read4();
00079
00080
00081 for (i = 0; i < 0x52; i++) writefile->write1(0x1A);
00082 writefile->write2(0);
00083
00084
00085 writefile->write4(num_entries);
00086
00087
00088 uint32 write_offset = 0x80 + 8 * num_entries;
00089
00090
00091 for (i = 0x58; i < write_offset; i++) writefile->write1(0);
00092
00093
00094 con.Printf ("Convering %i shapes...\n", num_entries);
00095 for (uint32 s = 0; s < num_entries; s++)
00096 {
00097 #ifdef EXPORT_SHAPENUM
00098 shapenum = s;
00099 #endif
00100
00101
00102 readfile->seek(0x80 + 8*s);
00103 uint32 read_offset = readfile->read4();
00104 uint32 read_size = readfile->read4();
00105
00106 if (!read_size) continue;
00107
00108
00109 readfile->seek(read_offset);
00110
00111
00112 if (read_format == &AutoShapeFormat)
00113 {
00114 pout << "Auto detecting format..." << std::endl;
00115
00116 if (ConvertShape::Check(readfile, &U8ShapeFormat, read_size))
00117 read_format = &U8ShapeFormat;
00118 else if (ConvertShape::Check(readfile, &U82DShapeFormat, read_size))
00119 read_format = &U82DShapeFormat;
00120 else if (ConvertShape::Check(readfile, &U8SKFShapeFormat, read_size))
00121 read_format = &U8SKFShapeFormat;
00122 else if (ConvertShape::Check(readfile, &CrusaderShapeFormat, read_size))
00123 read_format = &CrusaderShapeFormat;
00124 else if (ConvertShape::Check(readfile, &Crusader2DShapeFormat, read_size))
00125 read_format = &Crusader2DShapeFormat;
00126 else if (ConvertShape::Check(readfile, &PentagramShapeFormat, read_size))
00127 read_format = &PentagramShapeFormat;
00128 else if (ConvertShape::Check(readfile, &U8CMPShapeFormat, read_size))
00129 read_format = &U8CMPShapeFormat;
00130 else
00131 {
00132 perr << "Error: Unable to detect shape format!" << std::endl;
00133 return;
00134 }
00135 pout << "Detected input format as: " << read_format->name << std::endl;
00136 }
00137
00138
00139 con.Printf ("Reading shape %i...\n", s);
00140 shape.Read(readfile, read_format, read_size);
00141
00142
00143 con.Printf ("Writing shape %i...\n", s);
00144 writefile->seek(write_offset);
00145 uint32 write_size;
00146 shape.Write(writefile, write_format, write_size);
00147
00148
00149 writefile->seek(0x80 + 8*s);
00150 writefile->write4(write_offset);
00151 writefile->write4(write_size);
00152
00153
00154 write_offset += write_size;
00155
00156
00157 shape.Free();
00158 }
00159 pout << "Done!" << std::endl;
00160 }
00161
00162 void ConvertShp(IDataSource *readfile, ODataSource *writefile)
00163 {
00164 #ifdef EXPORT_SHAPENUM
00165 shapenum = 1;
00166 #endif
00167 ConvertShape shape;
00168 uint32 read_size = readfile->getSize();
00169
00170
00171 if (read_format == &AutoShapeFormat)
00172 {
00173 pout << "Auto detecting format..." << std::endl;
00174 if (ConvertShape::Check(readfile, &U8ShapeFormat, read_size))
00175 read_format = &U8ShapeFormat;
00176 else if (ConvertShape::Check(readfile, &U82DShapeFormat, read_size))
00177 read_format = &U82DShapeFormat;
00178 else if (ConvertShape::Check(readfile, &U8SKFShapeFormat, read_size))
00179 read_format = &U8SKFShapeFormat;
00180 else if (ConvertShape::Check(readfile, &CrusaderShapeFormat, read_size))
00181 read_format = &CrusaderShapeFormat;
00182 else if (ConvertShape::Check(readfile, &Crusader2DShapeFormat, read_size))
00183 read_format = &Crusader2DShapeFormat;
00184 else if (ConvertShape::Check(readfile, &PentagramShapeFormat, read_size))
00185 read_format = &PentagramShapeFormat;
00186 else if (ConvertShape::Check(readfile, &U8CMPShapeFormat, read_size))
00187 read_format = &U8CMPShapeFormat;
00188 else
00189 {
00190 perr << "Error: Unable to detect shape format!" << std::endl;
00191 return;
00192 }
00193 pout << "Detected input format as: " << read_format->name << std::endl;
00194 }
00195
00196 con.Printf ("Reading shape...\n");
00197 shape.Read(readfile, read_format, read_size);
00198 uint32 write_size;
00199 con.Printf ("Writing shape...\n");
00200 shape.Write(writefile, write_format, write_size);
00201 shape.Free();
00202 pout << "Done!" << std::endl;
00203 }
00204
00205 const ConvertShapeFormat *GetShapeFormat(const char *game)
00206 {
00207 if (!Pentagram::strcasecmp(game, "u8")) return &U8ShapeFormat;
00208 else if (!Pentagram::strcasecmp(game, "u82D")) return &U82DShapeFormat;
00209 else if (!Pentagram::strcasecmp(game, "u8skf")) return &U8SKFShapeFormat;
00210 else if (!Pentagram::strcasecmp(game, "cru")) return &CrusaderShapeFormat;
00211 else if (!Pentagram::strcasecmp(game, "cru2D")) return &Crusader2DShapeFormat;
00212 else if (!Pentagram::strcasecmp(game, "pent")) return &PentagramShapeFormat;
00213
00214 return 0;
00215 }
00216
00217 int main(int argc, char **argv)
00218 {
00219 if (argc < 3) {
00220 perr << "Usage: ShapeConv <inflx> <outflx> [--ifmt u8|u82D|u8skf|u8cmp|cru|cru2D|pent|auto] [--ofmt u8|u82D|u8skf|cru|cru2D|pent] [--singlefile]" << std::endl;
00221 perr << std::endl;
00222 perr << "Default input format: Auto Detect" << std::endl;
00223 perr << "Default output format: Ultima 8" << std::endl;
00224 return 1;
00225 }
00226
00227 Args parameters;
00228 std::string ifmt, ofmt;
00229 bool singlefile=false;
00230
00231
00232 parameters.declare("--ifmt", &ifmt, "auto");
00233 parameters.declare("--ofmt", &ofmt, "u8");
00234 parameters.declare("--singlefile", &singlefile, true);
00235
00236 parameters.process(argc, argv);
00237
00238 if (!Pentagram::strcasecmp(ifmt.c_str(), "auto")) read_format = &AutoShapeFormat;
00239 else if (!Pentagram::strcasecmp(ifmt.c_str(), "u8cmp")) read_format = &U8CMPShapeFormat;
00240 else read_format = GetShapeFormat(ifmt.c_str());
00241
00242 write_format = GetShapeFormat(ofmt.c_str());
00243
00244 if (!read_format)
00245 {
00246 perr << "Unknown input format: " << ifmt << std::endl;
00247 return -1;
00248 }
00249
00250 if (!write_format)
00251 {
00252 perr << "Unknown output format: " << ifmt << std::endl;
00253 return -1;
00254 }
00255
00256
00257 if (std::strlen(argv[1]) > 4 && !Pentagram::strcasecmp(argv[1]+std::strlen(argv[1])-4, ".shp"))
00258 singlefile = true;
00259
00260 if (singlefile) pout << "Single shape mode" << std::endl;
00261
00262 if (singlefile)
00263 pout << "Converting " << read_format->name << " format shape in '"<< argv[1] << "' to " << write_format->name << " format in '"<< argv[2] << "'" << std::endl;
00264 else
00265 pout << "Converting " << read_format->name << " format shapes in flex '"<< argv[1] << "' to " << write_format->name << " format in '"<< argv[2] << "'" << std::endl;
00266
00267
00268 FileSystem filesys(true);
00269
00270
00271 IDataSource *readfile = filesys.ReadFile(argv[1]);
00272
00273
00274 if(readfile==0)
00275 {
00276 perr << "Error reading file '" << argv[1] << "'" << std::endl;
00277 return 1;
00278 }
00279
00280
00281 ODataSource *writefile = filesys.WriteFile(argv[2]);
00282
00283
00284 if(writefile==0)
00285 {
00286 perr << "Error writing file '" << argv[2] << "'" << std::endl;
00287 return 1;
00288 }
00289
00290 if (!singlefile)
00291 ConvertFlexes(readfile, writefile);
00292 else
00293 ConvertShp(readfile, writefile);
00294
00295
00296 delete readfile;
00297 delete writefile;
00298
00299 return 0;
00300 }