mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-07 10:48:43 +00:00
SCI: Add handling for the RAVE resource type, found in KQ6CD
This contains the sync data in the Windows version of KQ6CD. Note that currently the sync36 resource is 2 bytes bigger (it contains 2 bytes from the RAVE resource). Some test code has also been added to dump the RAVE sync resources
This commit is contained in:
parent
59b7aa354b
commit
fa2ea4fc61
@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "common/archive.h"
|
||||
#include "common/file.h" // for DumpFile
|
||||
#include "common/system.h"
|
||||
|
||||
#include "sci/sci.h"
|
||||
@ -140,6 +141,27 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint
|
||||
Resource *syncResource = _resMan->findResource(syncResourceId, true);
|
||||
uint syncOffset = 0;
|
||||
|
||||
#if 0
|
||||
// Dump the sync resources to disk
|
||||
Common::DumpFile *outFile = new Common::DumpFile();
|
||||
Common::String outName = syncResourceId.toPatchNameBase36() + ".sync36";
|
||||
outFile->open(outName);
|
||||
syncResource->writeToStream(outFile);
|
||||
outFile->finalize();
|
||||
outFile->close();
|
||||
|
||||
ResourceId raveResourceId = ResourceId(kResourceTypeRave, resourceId, noun, verb, cond, seq);
|
||||
Resource *raveResource = _resMan->findResource(raveResourceId, true);
|
||||
outName = raveResourceId.toPatchNameBase36() + ".rave";
|
||||
outFile->open(outName);
|
||||
raveResource->writeToStream(outFile);
|
||||
outFile->finalize();
|
||||
outFile->close();
|
||||
_resMan->unlockResource(raveResource);
|
||||
|
||||
delete outFile;
|
||||
#endif
|
||||
|
||||
// Set the portrait palette
|
||||
_palette->set(&_portraitPalette, false, true);
|
||||
|
||||
|
@ -112,11 +112,12 @@ static const char *const s_resourceTypeNames[] = {
|
||||
"audio", "sync", "message", "map", "heap",
|
||||
"audio36", "sync36", "xlate", "robot", "vmd",
|
||||
"chunk", "animation", "etc", "duck", "clut",
|
||||
"tga", "zzz", "macibin", "macibis", "macpict"
|
||||
"tga", "zzz", "macibin", "macibis", "macpict",
|
||||
"rave"
|
||||
};
|
||||
|
||||
// Resource type suffixes. Note that the
|
||||
// suffic of SCI3 scripts has been changed from
|
||||
// suffix of SCI3 scripts has been changed from
|
||||
// scr to csc
|
||||
static const char *const s_resourceTypeSuffixes[] = {
|
||||
"v56", "p56", "scr", "tex", "snd",
|
||||
@ -125,7 +126,7 @@ static const char *const s_resourceTypeSuffixes[] = {
|
||||
"msg", "map", "hep", "", "",
|
||||
"trn", "rbt", "vmd", "chk", "",
|
||||
"etc", "duk", "clu", "tga", "zzz",
|
||||
"", "", ""
|
||||
"", "", "", ""
|
||||
};
|
||||
|
||||
const char *getResourceTypeName(ResourceType restype) {
|
||||
@ -141,7 +142,7 @@ static const ResourceType s_resTypeMapSci0[] = {
|
||||
kResourceTypeCursor, kResourceTypePatch, kResourceTypeBitmap, kResourceTypePalette, // 0x08-0x0B
|
||||
kResourceTypeCdAudio, kResourceTypeAudio, kResourceTypeSync, kResourceTypeMessage, // 0x0C-0x0F
|
||||
kResourceTypeMap, kResourceTypeHeap, kResourceTypeAudio36, kResourceTypeSync36, // 0x10-0x13
|
||||
kResourceTypeTranslation // 0x14
|
||||
kResourceTypeTranslation, kResourceTypeRave // 0x14
|
||||
};
|
||||
|
||||
// TODO: 12 should be "Wave", but SCI seems to just store it in Audio resources
|
||||
@ -207,7 +208,7 @@ void Resource::unalloc() {
|
||||
}
|
||||
|
||||
void Resource::writeToStream(Common::WriteStream *stream) const {
|
||||
stream->writeByte(getType() | 0x80); // 0x80 is required by old sierra sci, otherwise it wont accept the patch file
|
||||
stream->writeByte(getType() | 0x80); // 0x80 is required by old Sierra SCI, otherwise it wont accept the patch file
|
||||
stream->writeByte(_headerSize);
|
||||
if (_headerSize > 0)
|
||||
stream->write(_header, _headerSize);
|
||||
@ -383,42 +384,13 @@ void PatchResourceSource::loadResource(ResourceManager *resMan, Resource *res) {
|
||||
|
||||
static Common::Array<uint32> resTypeToMacTags(ResourceType type);
|
||||
|
||||
static Common::String intToBase36(uint32 number, int minChar) {
|
||||
// Convert from an integer to a base36 string
|
||||
Common::String string;
|
||||
|
||||
while (minChar--) {
|
||||
int character = number % 36;
|
||||
string = ((character < 10) ? (character + '0') : (character + 'A' - 10)) + string;
|
||||
number /= 36;
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
static Common::String constructPatchNameBase36(ResourceId resId) {
|
||||
// Convert from a resource ID to a base36 patch name
|
||||
Common::String output;
|
||||
|
||||
output += (resId.getType() == kResourceTypeAudio36) ? '@' : '#'; // Identifier
|
||||
output += intToBase36(resId.getNumber(), 3); // Map
|
||||
output += intToBase36(resId.getTuple() >> 24, 2); // Noun
|
||||
output += intToBase36((resId.getTuple() >> 16) & 0xff, 2); // Verb
|
||||
output += '.'; // Separator
|
||||
output += intToBase36((resId.getTuple() >> 8) & 0xff, 2); // Cond
|
||||
output += intToBase36(resId.getTuple() & 0xff, 1); // Seq
|
||||
|
||||
assert(output.size() == 12); // We should always get 12 characters in the end
|
||||
return output;
|
||||
}
|
||||
|
||||
void MacResourceForkResourceSource::loadResource(ResourceManager *resMan, Resource *res) {
|
||||
ResourceType type = res->getType();
|
||||
Common::SeekableReadStream *stream = 0;
|
||||
|
||||
if (type == kResourceTypeAudio36 || type == kResourceTypeSync36) {
|
||||
// Handle audio36/sync36, convert back to audio/sync
|
||||
stream = _macResMan->getResource(constructPatchNameBase36(res->_id));
|
||||
stream = _macResMan->getResource(res->_id.toPatchNameBase36());
|
||||
} else {
|
||||
// Plain resource handling
|
||||
Common::Array<uint32> tagArray = resTypeToMacTags(type);
|
||||
|
@ -112,6 +112,8 @@ enum ResourceType {
|
||||
kResourceTypeMacIconBarPictS, // IBIS resources (icon bar, selected)
|
||||
kResourceTypeMacPict, // PICT resources (inventory)
|
||||
|
||||
kResourceTypeRave, // KQ6 hires RAVE (special sync) resources
|
||||
|
||||
kResourceTypeInvalid
|
||||
};
|
||||
|
||||
@ -143,6 +145,19 @@ class ResourceId {
|
||||
uint16 _number;
|
||||
uint32 _tuple; // Only used for audio36 and sync36
|
||||
|
||||
static Common::String intToBase36(uint32 number, int minChar) {
|
||||
// Convert from an integer to a base36 string
|
||||
Common::String string;
|
||||
|
||||
while (minChar--) {
|
||||
int character = number % 36;
|
||||
string = ((character < 10) ? (character + '0') : (character + 'A' - 10)) + string;
|
||||
number /= 36;
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
public:
|
||||
ResourceId() : _type(kResourceTypeInvalid), _number(0), _tuple(0) { }
|
||||
|
||||
@ -169,6 +184,22 @@ public:
|
||||
return retStr;
|
||||
}
|
||||
|
||||
// Convert from a resource ID to a base36 patch name
|
||||
Common::String toPatchNameBase36() {
|
||||
Common::String output;
|
||||
|
||||
output += (getType() == kResourceTypeAudio36) ? '@' : '#'; // Identifier
|
||||
output += intToBase36(getNumber(), 3); // Map
|
||||
output += intToBase36(getTuple() >> 24, 2); // Noun
|
||||
output += intToBase36((getTuple() >> 16) & 0xff, 2); // Verb
|
||||
output += '.'; // Separator
|
||||
output += intToBase36((getTuple() >> 8) & 0xff, 2); // Cond
|
||||
output += intToBase36(getTuple() & 0xff, 1); // Seq
|
||||
|
||||
assert(output.size() == 12); // We should always get 12 characters in the end
|
||||
return output;
|
||||
}
|
||||
|
||||
inline ResourceType getType() const { return _type; }
|
||||
inline uint16 getNumber() const { return _number; }
|
||||
inline uint32 getTuple() const { return _tuple; }
|
||||
|
@ -395,15 +395,22 @@ int ResourceManager::readAudioMapSCI11(ResourceSource *map) {
|
||||
syncSize = READ_LE_UINT16(ptr);
|
||||
ptr += 2;
|
||||
|
||||
// FIXME: The sync36 resource seems to be two bytes too big in KQ6CD
|
||||
// (bytes taken from the RAVE resource right after it)
|
||||
if (syncSize > 0)
|
||||
addResource(ResourceId(kResourceTypeSync36, map->_volumeNumber, n & 0xffffff3f), src, offset, syncSize);
|
||||
}
|
||||
|
||||
if (n & 0x40) {
|
||||
// This seems to define the size of raw lipsync data (at least
|
||||
// in kq6), may also just be general appended data.
|
||||
syncSize += READ_LE_UINT16(ptr);
|
||||
// in KQ6 CD Windows).
|
||||
int kq6HiresSyncSize = READ_LE_UINT16(ptr);
|
||||
ptr += 2;
|
||||
|
||||
if (kq6HiresSyncSize > 0) {
|
||||
addResource(ResourceId(kResourceTypeRave, map->_volumeNumber, n & 0xffffff3f), src, offset + syncSize, kq6HiresSyncSize);
|
||||
syncSize += kq6HiresSyncSize;
|
||||
}
|
||||
}
|
||||
|
||||
addResource(ResourceId(kResourceTypeAudio36, map->_volumeNumber, n & 0xffffff3f), src, offset + syncSize);
|
||||
|
Loading…
x
Reference in New Issue
Block a user