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 <iostream>
00024
00025 #ifndef ALPHA_LINUX_CXX
00026 # include <cstdio>
00027 # include <cstring>
00028 # include <string>
00029 #endif
00030
00031 #include "exult_types.h"
00032
00033
00034 using std::cout;
00035 using std::endl;
00036 using std::cerr;
00037 using std::string;
00038 using std::strlen;
00039 using std::strrchr;
00040 using std::strcpy;
00041 using std::memcpy;
00042 using std::exit;
00043
00044 struct u7frame {
00045 bool tile;
00046 uint32 datalen;
00047 uint8 *data;
00048 };
00049
00050 struct u7shape {
00051 int num_frames;
00052 struct u7frame *frames;
00053 };
00054
00055 unsigned int read1(FILE *f)
00056 {
00057 unsigned char b0;
00058 b0 = fgetc(f);
00059 return b0;
00060 }
00061
00062 unsigned int read2(FILE *f)
00063 {
00064 unsigned char b0, b1;
00065 b0 = fgetc(f);
00066 b1 = fgetc(f);
00067 return (b0 + (b1<<8));
00068 }
00069
00070 signed int read2signed(FILE *f)
00071 {
00072 unsigned char b0, b1;
00073 signed int i0;
00074 b0 = fgetc(f);
00075 b1 = fgetc(f);
00076 i0 = b0 + (b1<<8);
00077 if (i0 >= 32768) { i0 -= 65536; }
00078 return (i0);
00079 }
00080
00081 unsigned int read4(FILE *f)
00082 {
00083 unsigned char b0, b1, b2, b3;
00084 b0 = fgetc(f);
00085 b1 = fgetc(f);
00086 b2 = fgetc(f);
00087 b3 = fgetc(f);
00088 return (b0 + (b1<<8) + (b2<<16) + (b3<<24));
00089 }
00090
00091 void write4(FILE *f, unsigned int b)
00092 {
00093 fputc(b & 0xFF, f);
00094 fputc((b >> 8) & 0xFF, f);
00095 fputc((b >> 16) & 0xFF, f);
00096 fputc((b >> 24) & 0xFF, f);
00097 }
00098
00099 char* framefilename(char * shapefilename, int frame)
00100 {
00101 char *fn = new char[strlen(shapefilename)+5];
00102 char *dot = strrchr(shapefilename, '.');
00103 #ifdef WIN32
00104 char *slash = strrchr(shapefilename, '\\');
00105 #else
00106 char *slash = strrchr(shapefilename, '/');
00107 #endif
00108 int dotpos;
00109
00110 if (dot == 0 || slash > dot)
00111 dotpos = strlen(shapefilename);
00112 else
00113 dotpos = dot - shapefilename;
00114
00115 memcpy(fn, shapefilename, dotpos);
00116 sprintf(fn + dotpos, "_%03i", frame);
00117 strcpy(fn + dotpos + 4, shapefilename + dotpos);
00118
00119 return fn;
00120 }
00121
00122 void split_shape(char* filename)
00123 {
00124 FILE *shpfile, *framefile;
00125 int file_size, shape_size, hdr_size;
00126 int frame_offset, next_frame_offset;
00127 int num_frames;
00128 int datalen;
00129 uint8 *data;
00130 char *framename;
00131 int i;
00132
00133 shpfile = fopen (filename, "rb");
00134 if (!shpfile) {
00135 cerr << "Can't open " << filename << endl;
00136 return;
00137 }
00138 fseek(shpfile, 0, SEEK_END);
00139 file_size = ftell(shpfile);
00140 fseek(shpfile, 0, SEEK_SET);
00141
00142 shape_size = read4(shpfile);
00143
00144 if(file_size!=shape_size) {
00145 num_frames = file_size/64;
00146 fseek(shpfile, 0, SEEK_SET);
00147 cout << "num_frames = " << num_frames << endl;
00148 data = new uint8[64];
00149 for(i=0; i<num_frames; i++) {
00150 framename = framefilename(filename, i);
00151 cout << "writing " << framename << "..." << endl;
00152 framefile = fopen(framename, "wb");
00153 fread(data, 1, 64, shpfile);
00154 fwrite(data, 1, 64, framefile);
00155 fclose(framefile);
00156 delete[] framename;
00157 }
00158 delete[] data;
00159 } else {
00160 hdr_size = read4(shpfile);
00161 num_frames = (hdr_size-4)/4;
00162
00163 cout << "num_frames = "<< num_frames << endl;
00164
00165 for(i=0; i<num_frames; i++) {
00166 framename = framefilename(filename, i);
00167 cout << "writing " << framename << "..." << endl;
00168 framefile = fopen(framename, "wb");
00169
00170
00171 fseek(shpfile, (i+1)*4, SEEK_SET);
00172 frame_offset = read4(shpfile);
00173
00174 if (i+1 < num_frames)
00175 next_frame_offset = read4(shpfile);
00176 else
00177 next_frame_offset = shape_size;
00178
00179 fseek(shpfile, frame_offset, SEEK_SET);
00180 datalen = next_frame_offset - frame_offset;
00181
00182 write4(framefile, datalen+8);
00183 write4(framefile, 8);
00184
00185 data = new uint8[datalen];
00186 fread(data, 1, datalen, shpfile);
00187 fwrite(data, 1, datalen, framefile);
00188 fclose(framefile);
00189 delete[] framename;
00190 delete[] data;
00191 }
00192 }
00193 cout << "done" << endl;
00194
00195 fclose(shpfile);
00196 }
00197
00198 void merge_frames(char *shapefile, char** framefiles, int numframefiles)
00199 {
00200 FILE *shpfile, *framefile;
00201 int i;
00202 bool tiles = false;
00203 int file_size, shape_size, hdr_size, frame_size;
00204 int total_size;
00205 uint8 *data;
00206
00207 shpfile = fopen(shapefile, "wb");
00208
00209 total_size = 4 + 4*numframefiles;
00210
00211 for (i=0; i<numframefiles; i++) {
00212 framefile = fopen(framefiles[i], "rb");
00213
00214 cout << "reading " << framefiles[i] << "..." << endl;
00215
00216 fseek(framefile, 0, SEEK_END);
00217 file_size = ftell(framefile);
00218 fseek(framefile, 0, SEEK_SET);
00219 shape_size = read4(framefile);
00220
00221 if (file_size != shape_size) {
00222 if (i > 0 && !tiles) {
00223 cout << "Error: can't mix 8x8 tiles and non-tile shapes!" << endl;
00224 exit(1);
00225 }
00226
00227 tiles = true;
00228
00229 fseek(framefile, 0, SEEK_SET);
00230 fseek(shpfile, 64*i, SEEK_SET);
00231
00232 data = new uint8[64];
00233
00234 fread(data, 1, 64, framefile);
00235 fwrite(data, 1, 64, shpfile);
00236 fclose(framefile);
00237
00238 delete [] data;
00239 } else {
00240 if (tiles) {
00241 cout << "Error: can't mix 8x8 tiles and non-tile shapes!" << endl;
00242 exit(1);
00243 }
00244
00245 hdr_size = read4(framefile);
00246
00247 if (hdr_size > 8) {
00248 frame_size = read4(framefile);
00249 frame_size -= hdr_size;
00250 } else {
00251 frame_size = shape_size - hdr_size;
00252 }
00253
00254 data = new uint8[frame_size];
00255 fseek(framefile, hdr_size, SEEK_SET);
00256 fread(data, 1, frame_size, framefile);
00257 fclose(framefile);
00258
00259 fseek(shpfile, 4 + (i*4), SEEK_SET);
00260 write4(shpfile, total_size);
00261 fseek(shpfile, total_size, SEEK_SET);
00262 fwrite(data, 1, frame_size, shpfile);
00263
00264 total_size += frame_size;
00265 delete [] data;
00266 }
00267 }
00268
00269 if (!tiles) {
00270 fseek(shpfile, 0, SEEK_SET);
00271 write4(shpfile, total_size);
00272 }
00273
00274 cout << "done" << endl;
00275
00276 fclose(shpfile);
00277 }
00278
00279 int main(int argc, char *argv[])
00280 {
00281 char* shapefile;
00282 int numframefiles;
00283 char* framefiles[255];
00284 u7shape* sh;
00285
00286 if (argc < 2) {
00287 cout << "Usage: To split: splitshp [shape file]" << endl
00288 << " or to pack: splitshp [shape file] [frame files]" << endl;
00289 return 0;
00290 }
00291
00292 shapefile = argv[1];
00293
00294 if (argc > 2) {
00295 numframefiles = argc - 2;
00296 for (int i=0; i<numframefiles; i++)
00297 framefiles[i] = argv[i+2];
00298 merge_frames(shapefile, framefiles, numframefiles);
00299 } else {
00300 split_shape(shapefile);
00301 }
00302
00303 return 0;
00304 }