int ResourceManager::readAudioMapSCI11(IntMapResourceSource *map) { #ifndef ENABLE_SCI32 // SCI32 support is not built in. Check if this is a SCI32 game // and if it is abort here. if (_volVersion >= kResVersionSci2) return SCI_ERROR_RESMAP_NOT_FOUND; #endif uint32 offset = 0; Resource *mapRes = findResource(ResourceId(kResourceTypeMap, map->_mapNumber), false); if (!mapRes) { warning("Failed to open %i.MAP", map->_mapNumber); return SCI_ERROR_RESMAP_NOT_FOUND; } ResourceSource *src = findVolume(map, map->_volumeNumber); if (!src) { warning("Failed to find volume for %i.MAP", map->_mapNumber); return SCI_ERROR_NO_RESOURCE_FILES_FOUND; } byte *ptr = mapRes->data; // Heuristic to detect entry size uint32 entrySize = 0; for (int i = mapRes->size - 1; i >= 0; --i) { if (ptr[i] == 0xff) entrySize++; else break; } if (map->_mapNumber == 65535) { while (ptr < mapRes->data + mapRes->size) { uint16 n = READ_LE_UINT16(ptr); ptr += 2; if (n == 0xffff) break; if (entrySize == 6) { offset = READ_LE_UINT32(ptr); ptr += 4; } else { offset += READ_LE_UINT24(ptr); ptr += 3; } addResource(ResourceId(kResourceTypeAudio, n), src, offset); } } else if (map->_mapNumber == 0 && entrySize == 10 && ptr[3] == 0) { // QFG3 demo format // ptr[3] would be 'seq' in the normal format and cannot possibly be 0 while (ptr < mapRes->data + mapRes->size) { uint16 n = READ_BE_UINT16(ptr); ptr += 2; if (n == 0xffff) break; offset = READ_LE_UINT32(ptr); ptr += 4; uint32 size = READ_LE_UINT32(ptr); ptr += 4; addResource(ResourceId(kResourceTypeAudio, n), src, offset, size); } } else if (map->_mapNumber == 0 && entrySize == 8 && READ_LE_UINT16(ptr + 2) == 0xffff) { // LB2 Floppy/Mother Goose SCI1.1 format Common::SeekableReadStream *stream = getVolumeFile(src); while (ptr < mapRes->data + mapRes->size) { uint16 n = READ_LE_UINT16(ptr); ptr += 4; if (n == 0xffff) break; offset = READ_LE_UINT32(ptr); ptr += 4; // The size is not stored in the map and the entries have no order. // We need to dig into the audio resource in the volume to get the size. stream->seek(offset + 1); byte headerSize = stream->readByte(); assert(headerSize == 11 || headerSize == 12); stream->skip(5); uint32 size = stream->readUint32LE() + headerSize + 2; addResource(ResourceId(kResourceTypeAudio, n), src, offset, size); } } else { bool isEarly = (entrySize != 11); if (!isEarly) { offset = READ_LE_UINT32(ptr); ptr += 4; } while (ptr < mapRes->data + mapRes->size) { uint32 n = READ_BE_UINT32(ptr); int syncSize = 0; ptr += 4; if (n == 0xffffffff) break; if (isEarly) { offset = READ_LE_UINT32(ptr); ptr += 4; } else { offset += READ_LE_UINT24(ptr); ptr += 3; } if (isEarly || (n & 0x80)) { 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->_mapNumber, n & 0xffffff3f), src, offset, syncSize); } if (n & 0x40) { // This seems to define the size of raw lipsync data (at least // in KQ6 CD Windows). int kq6HiresSyncSize = READ_LE_UINT16(ptr); ptr += 2; if (kq6HiresSyncSize > 0) { addResource(ResourceId(kResourceTypeRave, map->_mapNumber, n & 0xffffff3f), src, offset + syncSize, kq6HiresSyncSize); syncSize += kq6HiresSyncSize; } } addResource(ResourceId(kResourceTypeAudio36, map->_mapNumber, n & 0xffffff3f), src, offset + syncSize); } } return 0; }
uint32 AGOSEngine_PN::getlong(uint32 pos) { // Only actually reads 24bit though if (pos > _dataBaseSize) error("getlong: Read beyond EOF (%d)", pos); return (uint32)READ_LE_UINT24(_dataBase + pos); }