void ExtractMMApple::execute() { int i, j; unsigned short signature; char fname[256]; Common::Filename inpath1(_inputPaths[0].path); Common::Filename inpath2(_inputPaths[1].path); Common::Filename &outpath = _outputPath; if (outpath.empty()) // Standard output path outpath.setFullPath("out/"); Common::File input1(inpath1, "rb"); Common::File input2(inpath2, "rb"); input1.seek(142080, SEEK_SET); input2.seek(143104, SEEK_SET); /* check signature */ signature = input1.readUint16LE(); if (signature != 0x0A31) error("Signature not found in disk 1!"); signature = input2.readUint16LE(); if (signature != 0x0032) error("Signature not found in disk 2!"); outpath.setFullName("00.LFL"); Common::File output(outpath, "wb"); // All output should be xored output.setXorMode(0xFF); print("Creating 00.LFL...\n"); /* write signature */ output.writeUint16LE(signature); /* copy object flags */ for (i = 0; i < 256; i++) output.writeByte(input1.readByte()); /* copy room offsets */ for (i = 0; i < NUM_ROOMS; i++) { room_disks_apple[i] = input1.readByte(); output.writeByte(room_disks_apple[i]); } for (i = 0; i < NUM_ROOMS; i++) { room_sectors_apple[i] = input1.readByte(); output.writeByte(room_sectors_apple[i]); room_tracks_apple[i] = input1.readByte(); output.writeByte(room_tracks_apple[i]); } /* copy costume offsets */ for (i = 0; i < 25; i++) output.writeByte(input1.readByte()); for (i = 0; i < 25; i++) output.writeUint16LE(input1.readUint16LE()); /* copy script offsets */ for (i = 0; i < 160; i++) output.writeByte(input1.readByte()); for (i = 0; i < 160; i++) output.writeUint16LE(input1.readUint16LE()); /* copy sound offsets */ for (i = 0; i < 70; i++) output.writeByte(input1.readByte()); for (i = 0; i < 70; i++) output.writeUint16LE(input1.readUint16LE()); /* NOTE: Extra 92 bytes of unknown data */ for (i = 0; i < NUM_ROOMS; i++) { Common::File *input; if (room_disks_apple[i] == '1') input = &input1; else if (room_disks_apple[i] == '2') input = &input2; else continue; sprintf(fname, "%02i.LFL", i); outpath.setFullName(fname); output.open(outpath, "wb"); print("Creating %s...\n", fname); input->seek((SectorOffset[room_tracks_apple[i]] + room_sectors_apple[i]) * 256, SEEK_SET); for (j = 0; j < ResourcesPerFile[i]; j++) { unsigned short len = input->readUint16LE(); output.writeUint16LE(len); for (len -= 2; len > 0; len--) output.writeByte(input->readByte()); } input->rewind(); } print("All done!"); }
void ExtractZakC64::execute() { int i, j; unsigned short signature; char fname[256]; // Two disks... Common::Filename inpath1(_inputPaths[0].path); Common::Filename inpath2(_inputPaths[1].path); Common::Filename &outpath = _outputPath; if (outpath.empty()) // Standard output path outpath.setFullPath("out/"); Common::File input1(inpath1, "rb"); Common::File input2(inpath2, "rb"); /* check signature */ signature = input1.readUint16LE(); if (signature != 0x0A31) error("Signature not found in disk 1!"); signature = input2.readUint16LE(); if (signature != 0x0132) error("Signature not found in disk 2!"); outpath.setFullName("00.LFL"); Common::File output(outpath, "wb"); output.setXorMode(0xFF); print("Creating 00.LFL..."); /* write signature */ output.writeUint16LE(signature); /* copy object flags */ for (i = 0; i < 775; i++) output.writeByte(input1.readByte()); /* copy room offsets */ for (i = 0; i < NUM_ROOMS; i++) { room_disks_c64[i] = input1.readByte(); output.writeByte(room_disks_c64[i]); } for (i = 0; i < NUM_ROOMS; i++) { room_sectors_c64[i] = input1.readByte(); output.writeByte(room_sectors_c64[i]); room_tracks_c64[i] = input1.readByte(); output.writeByte(room_tracks_c64[i]); } /* copy costume offsets */ for (i = 0; i < 38; i++) output.writeByte(input1.readByte()); for (i = 0; i < 38; i++) output.writeUint16LE(input1.readUint16LE()); /* copy script offsets */ for (i = 0; i < 155; i++) output.writeByte(input1.readByte()); for (i = 0; i < 155; i++) output.writeUint16LE(input1.readUint16LE()); /* copy sound offsets */ for (i = 0; i < 127; i++) output.writeByte(input1.readByte()); for (i = 0; i < 127; i++) output.writeUint16LE(input1.readUint16LE()); output.close(); for (i = 0; i < NUM_ROOMS; i++) { Common::File *input; if (room_disks_c64[i] == '1') input = &input1; else if (room_disks_c64[i] == '2') input = &input2; else continue; sprintf(fname, "%02i.LFL", i); outpath.setFullName(fname); output.open(outpath, "wb"); print("Creating %s...", fname); input->seek((SectorOffset[room_tracks_c64[i]] + room_sectors_c64[i]) * 256, SEEK_SET); for (j = 0; j < ResourcesPerFile[i]; j++) { unsigned short len; do { len = input->readUint16LE(); output.writeUint16LE(len); } while (len == 0xffff); for (len -= 2; len > 0; len--) { output.writeByte(input->readByte()); } } input->rewind(); } print("All done!"); }
void CompressionExample::execute() { // By now, all arguments have been parsed, all members setup and all input paths setup // If this was a compression tool _format would contain the selected audio format // Note that we almost need no error handling, since exceptions will be thrown if we do // something bad, and all parameters have already been setup // This 'tool' doesn't takes two input files // It writes the of each file 100 times into X files, where X is the input file size. // _inputPaths[0].path is always valid and contains the correct path, same for 1 Common::Filename inpath1(_inputPaths[0].path); Common::Filename inpath2(_inputPaths[1].path); // We always need to setup default output path, since there is no obligation to specify it // If you don't do this, the OS will usually default to the working directory, if we output a file // it will fail most likely if (_outputPath.empty()) _outputPath = "output/"; // The File class is very similar to the FILE struct, look in util.h for details File in1(inpath1, "r"); File in2(inpath2, "r"); // Read the complete contents of the files (if they don't contain NUL ofcourse) std::string text1 = in1.readString(); std::string text2 = in2.readString(); // Start the 'extraction' size_t total_files = in1.size() + in2.size(); // There has to be some roof on this if (total_files > 1000) throw ToolException("Input files are too large!"); for (size_t i = 0; i < total_files; ++i) { // This updates any progress bar, if there is any // if you don't support progress bars, you should use notifyProgress instead // to make sure progress can be aborted (print calls notifyProgress internally) updateProgress(i, total_files); // Convert i to string std::ostringstream outname; outname << i; // Open a file for writing if (_outputFiles) { File out(_outputPath.getPath() + outname.str() + ".exo", "w"); // What we actually do, output some text alot for (size_t j = 0; j < 100; ++j) { if (i < in1.size()) out.write(text1.c_str(), 1, text1.size()); else out.write(text2.c_str(), 1, text2.size()); } } else { // Do nothing for awhile for (int i = 0; i < 1000000; ++i) { int *n = new int; delete n; } } // Print can also throw an AbortException // Do NOT use printf or anything else that outputs to standard output, as it will not display in the GUI. print("Outputted file %d of %d", i, total_files); } // We indicate success by not throwing any exceptions during the execution print("Extraction finished without errors!"); }