diff --git a/engines/sci/compress_sci.cpp b/engines/sci/compress_sci.cpp
index 3d82b7e..ec30bb6 100644
a
|
b
|
CompressSci::CompressSci(const std::string &name) : CompressionTool(name, TOOLTY
|
58 | 58 | |
59 | 59 | _outputToDirectory = false; |
60 | 60 | |
61 | | _shorthelp = "Used to compress Sierra resource.aud/resource.sfx files. (NOT SCI32 compatible!)"; |
| 61 | _shorthelp = "Used to compress Sierra resource.aud/.sfx and AUDIO001.002 files. (NOT SCI32 compatible!)"; |
62 | 62 | _helptext = "\nUsage: " + getName() + " [mode-params] [-o outputname] <inputname>\n"; |
63 | 63 | } |
64 | 64 | |
65 | 65 | // header is first 6 bytes read from file |
66 | 66 | SciResourceDataType CompressSci::detectData(byte *header, bool compressMode) { |
67 | | byte buffer[20]; |
68 | 67 | uint32 dataSize; |
| 68 | if (_rawAudio) { |
| 69 | // File is a raw audio file |
| 70 | dataSize = _rawAudioMap[_inputOffset]; |
| 71 | _inputEndOffset = _inputOffset + dataSize; |
| 72 | return kSciResourceDataTypeRaw; |
| 73 | } |
| 74 | byte buffer[20]; |
69 | 75 | memcpy(&buffer, header, 6); |
70 | 76 | if ((memcmp(buffer + 1, "RIFF", 4) == 0) || (memcmp(buffer + 1, "\x8d\x0bSOL", 4) == 0)) { |
71 | 77 | // Fixup for pharkas resource.sfx, several WAVE files contain a size thats not right (-1 byte) |
… |
… |
static void deDPCM8(byte *soundBuf, byte *inputBuf, uint32 n) {
|
220 | 226 | void CompressSci::compressData(SciResourceDataType dataType) { |
221 | 227 | int orgDataSize = _inputEndOffset - _inputOffset; |
222 | 228 | int newDataSize = 0; |
223 | | byte *orgData = new byte[orgDataSize]; |
224 | 229 | byte *newData = 0; |
225 | 230 | |
226 | 231 | int sampleRate = 0; |
… |
… |
void CompressSci::compressData(SciResourceDataType dataType) {
|
230 | 235 | uint8 sampleBits = 8; |
231 | 236 | byte sampleFlags = 0; |
232 | 237 | |
233 | | if (!orgData) |
234 | | error("malloc error"); |
235 | | |
236 | 238 | switch (dataType) { |
237 | 239 | case kSciResourceDataTypeWAVE: |
238 | 240 | print("WAVE found\n"); |
… |
… |
void CompressSci::compressData(SciResourceDataType dataType) {
|
281 | 283 | } |
282 | 284 | break; |
283 | 285 | } |
| 286 | case kSciResourceDataTypeRaw: |
| 287 | sampleRate = 11025; |
| 288 | // No headers so just use the original data as sample data |
| 289 | sampleDataSize = orgDataSize; |
| 290 | sampleData = new byte[sampleDataSize]; |
| 291 | if (!sampleData) |
| 292 | error("malloc error"); |
| 293 | _input.read_throwsOnError(sampleData, sampleDataSize); |
| 294 | break; |
284 | 295 | case kSciResourceTypeTypeSync: |
285 | 296 | print("SYNC found at %lx\n", _inputOffset); |
286 | 297 | // Simply copy original data over |
287 | | _input.read_throwsOnError(orgData, orgDataSize); |
288 | | newData = orgData; |
289 | 298 | newDataSize = orgDataSize; |
| 299 | newData = new byte[newDataSize]; |
| 300 | if (!newData) |
| 301 | error("malloc error"); |
| 302 | _input.read_throwsOnError(newData, newDataSize); |
290 | 303 | break; |
291 | 304 | default: |
292 | 305 | error("Unsupported datatype"); |
… |
… |
void CompressSci::compressData(SciResourceDataType dataType) {
|
305 | 318 | Common::File tempfileEnc(TEMP_ENC, "rb"); |
306 | 319 | newDataSize = tempfileEnc.size(); |
307 | 320 | newData = new byte[newDataSize]; |
| 321 | if (!newData) |
| 322 | error("malloc error"); |
308 | 323 | tempfileEnc.read_throwsOnError(newData, newDataSize); |
309 | 324 | tempfileEnc.close(); |
310 | 325 | } |
311 | 326 | |
312 | 327 | _output.write(newData, newDataSize); |
| 328 | delete[] newData; |
| 329 | } |
313 | 330 | |
314 | | if ((newData) && (newData != orgData)) |
315 | | delete[] newData; |
316 | | delete[] orgData; |
| 331 | uint CompressSci::parseRawAudioMap() { |
| 332 | Common::Filename mapFileName = _inputPaths[0].path; |
| 333 | // Assume the map is in the same dir as the resource file |
| 334 | // and is called AUDIO001.MAP |
| 335 | mapFileName.setFullName("AUDIO001.MAP"); |
| 336 | warning("Trying %s as resource map\n", mapFileName.getFullPath().data()); |
| 337 | Common::File mapFile; |
| 338 | mapFile.open(mapFileName, "rb"); |
| 339 | // Ten byte entries, the last one is fake |
| 340 | uint32 numEntries = (mapFile.size() / 10) - 1; |
| 341 | uint32 offset = 0; |
| 342 | uint32 size = 0; |
| 343 | for (uint32 i = 0; i < numEntries; i++) { |
| 344 | // shouldn't reach the fake entry but break if we do |
| 345 | if (mapFile.readUint16LE() == 0xffff) break; |
| 346 | // mask out the resource volume number |
| 347 | offset = mapFile.readUint32LE() & 0x0fffffff; |
| 348 | size = mapFile.readUint32LE(); |
| 349 | _rawAudioMap[offset] = size; |
| 350 | } |
| 351 | mapFile.close(); |
| 352 | return _rawAudioMap.size(); |
317 | 353 | } |
318 | 354 | |
319 | 355 | void CompressSci::execute() { |
… |
… |
void CompressSci::execute() {
|
325 | 361 | _inputSize = _input.size(); |
326 | 362 | |
327 | 363 | // First find out how many samples are in this file |
328 | | // We only support SOL audio and WAVE |
329 | | // We can't support games that use "raw" audio (would have to walk through audio map for those, which would |
330 | | // complicate this code - all talkie games that use this (kq5) don't use much space anyway, so not supporting |
331 | | // those isn't a big issue |
332 | 364 | |
| 365 | _rawAudio = false; |
333 | 366 | _input.seek(0, SEEK_SET); |
334 | 367 | byte header[6]; |
335 | 368 | |
… |
… |
void CompressSci::execute() {
|
343 | 376 | error("This resource file is already FLAC-compressed, aborting...\n"); |
344 | 377 | |
345 | 378 | int resourceCount = 0; |
346 | | do { |
347 | | recognizedDataType = detectData(header, false); |
348 | | if (!recognizedDataType) |
349 | | error("Unsupported data at offset %lx", _inputOffset); |
350 | | _input.seek(_inputEndOffset, SEEK_SET); |
351 | | _inputOffset = _inputEndOffset; |
352 | | resourceCount++; |
353 | | // We abort even, if file position is one below size because of pharkas resource.sfx |
354 | | if (_inputOffset >= _inputSize - 1) |
355 | | break; |
| 379 | if (_input.size() == 0x05C9B000 or _input.size() == 0x0160E000) { |
| 380 | warning("Size matches KQ5 or Jones in the Fast Lane audio file, assuming raw audio\n"); |
| 381 | _rawAudio = true; |
| 382 | resourceCount = parseRawAudioMap(); |
| 383 | } else { |
| 384 | do { |
| 385 | recognizedDataType = detectData(header, false); |
| 386 | if (!recognizedDataType) |
| 387 | error("Unsupported data at offset %lx", _inputOffset); |
| 388 | _input.seek(_inputEndOffset, SEEK_SET); |
| 389 | _inputOffset = _inputEndOffset; |
| 390 | resourceCount++; |
| 391 | // We abort even, if file position is one below size because of pharkas resource.sfx |
| 392 | if (_inputOffset >= _inputSize - 1) |
| 393 | break; |
356 | 394 | |
357 | | _input.read_throwsOnError(&header, 6); |
358 | | } while (true); |
| 395 | _input.read_throwsOnError(&header, 6); |
| 396 | } while (true); |
| 397 | } |
359 | 398 | |
360 | 399 | // This case happens on pharkas resource.sfx |
361 | 400 | if (_inputOffset != _inputSize) |
… |
… |
void CompressSci::execute() {
|
394 | 433 | _input.seek(_inputOffset, SEEK_SET); |
395 | 434 | compressData(recognizedDataType); |
396 | 435 | |
| 436 | // raw files are 0-padded to 2048 bytes |
| 437 | if (recognizedDataType == kSciResourceDataTypeRaw and _inputEndOffset % 2048) |
| 438 | _inputEndOffset = (((_inputEndOffset >> 11) + 1) << 11) & 0xffffffff; |
| 439 | |
397 | 440 | // Seek inputfile to the end of the data |
398 | 441 | _input.seek(_inputEndOffset, SEEK_SET); |
399 | 442 | // Seek outputfile to mapping table |
diff --git a/engines/sci/compress_sci.h b/engines/sci/compress_sci.h
index 3c92d6f..e1e404a 100644
a
|
b
|
|
24 | 24 | #define COMPRESS_SCI_H |
25 | 25 | |
26 | 26 | #include "compress.h" |
| 27 | #include <map> |
27 | 28 | |
28 | 29 | enum SciResourceDataType { |
29 | 30 | kSciResourceDataTypeUnknown = 0, |
30 | 31 | kSciResourceDataTypeWAVE = 1, |
31 | 32 | kSciResourceDataTypeSOL = 2, |
32 | | kSciResourceTypeTypeSync = 3 |
| 33 | kSciResourceTypeTypeSync = 3, |
| 34 | kSciResourceDataTypeRaw = 4 |
33 | 35 | }; |
34 | 36 | |
35 | 37 | class CompressSci : public CompressionTool { |
… |
… |
public:
|
41 | 43 | protected: |
42 | 44 | SciResourceDataType detectData(byte *header, bool compressMode); |
43 | 45 | void compressData(SciResourceDataType dataType); |
| 46 | uint parseRawAudioMap(); |
44 | 47 | |
45 | 48 | Common::File _input, _output; |
46 | 49 | int _inputOffset; |
47 | 50 | int _inputEndOffset; |
48 | 51 | int _inputSize; |
49 | 52 | int _outputOffset; |
| 53 | bool _rawAudio; |
| 54 | std::map<uint32,uint32> _rawAudioMap; |
50 | 55 | }; |
51 | 56 | |
52 | 57 | #endif |