1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-06 13:16:52 +02:00

#138 add sound decoder

This commit is contained in:
XProger
2018-11-12 07:55:55 +03:00
parent 34ab88f18b
commit cec3af9080
3 changed files with 59 additions and 16 deletions

View File

@@ -1325,7 +1325,11 @@ struct Controller {
Basis& getJoint(int index) { Basis& getJoint(int index) {
updateJoints(); updateJoints();
ASSERT(getModel() && index < getModel()->mCount); ASSERT(getModel() && index < getModel()->mCount);
if (getModel() && getModel()->mCount && index >= getModel()->mCount)
return joints[0];
return joints[index]; return joints[index];
} }

View File

@@ -3299,6 +3299,19 @@ namespace TR {
uint32 flag = stream.readBE32(); uint32 flag = stream.readBE32();
if (flag == 0x00000000) { // SND if (flag == 0x00000000) { // SND
ASSERTV(stream.readBE32() == 0x00000000); ASSERTV(stream.readBE32() == 0x00000000);
int pos = stream.pos;
stream.setPos(0);
soundDataSize = stream.size;
soundData = new uint8[soundDataSize];
stream.raw(soundData, soundDataSize);
soundOffsetsCount = 256;
soundOffsets = new uint32[soundOffsetsCount];
soundSize = new uint32[soundOffsetsCount];
memset(soundOffsets, 0, soundOffsetsCount * sizeof(uint32));
memset(soundSize, 0, soundOffsetsCount * sizeof(uint32));
stream.setPos(pos);
break; break;
} }
ASSERT(flag == 0x00000010); // SAT ASSERT(flag == 0x00000010); // SAT
@@ -3603,8 +3616,8 @@ namespace TR {
spriteSequences = spriteSequencesCount ? new SpriteSequence[spriteSequencesCount] : NULL; spriteSequences = spriteSequencesCount ? new SpriteSequence[spriteSequencesCount] : NULL;
for (int i = 0; i < spriteSequencesCount; i++) { for (int i = 0; i < spriteSequencesCount; i++) {
SpriteSequence &s = spriteSequences[i]; SpriteSequence &s = spriteSequences[i];
s.unused = stream.readBE16(); ASSERTV(stream.readBE16() == 0);
s.type = Entity::remap(version, Entity::Type(stream.readBE16())); s.type = Entity::remap(version, Entity::Type(stream.readBE16()));
s.sCount = (s.type >= Entity::TR1_TYPE_MAX) ? 1 : -stream.readBE16(); s.sCount = (s.type >= Entity::TR1_TYPE_MAX) ? 1 : -stream.readBE16();
s.sStart = stream.readBE16(); s.sStart = stream.readBE16();
} }
@@ -3619,22 +3632,33 @@ namespace TR {
ASSERTV(stream.readBE32() == 0x00000002); ASSERTV(stream.readBE32() == 0x00000002);
int count = stream.readBE32(); int count = stream.readBE32();
soundsMap = new int16[count]; soundsMap = new int16[count];
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++)
soundsMap[i] = stream.readBE16(); soundsMap[i] = stream.readBE16();
soundsMap[i] = -1; // TODO
}
break; break;
} }
case CHUNK("SAMPINFS") : { case CHUNK("SAMPINFS") : {
ASSERTV(stream.readBE32() == 0x00000008); ASSERTV(stream.readBE32() == 0x00000008);
int count = stream.readBE32(); soundsInfoCount = stream.readBE32();
stream.seek(count * 8); // TODO soundsInfo = soundsInfoCount ? new SoundInfo[soundsInfoCount] : NULL;
for (int i = 0; i < soundsInfoCount; i++) {
SoundInfo &s = soundsInfo[i];
s.index = stream.readBE16();
s.volume = float(stream.readBE16()) / 0x7FFF;
s.chance = float(stream.readBE16()) / 0xFFFF;
s.range = 8 * 1024;
s.pitch = 0.2f;
s.flags.value = stream.readBE16();
}
break; break;
} }
case CHUNK("SAMPLE ") : { case CHUNK("SAMPLE ") : {
int32 index = stream.readBE32(); int32 index = stream.readBE32();
int32 count = stream.readBE32(); int32 size = stream.readBE32();
stream.seek(count); // TODO ASSERT(index < soundOffsetsCount);
soundOffsets[index] = stream.pos - 4;
soundSize[index] = size - 4; // trim last samples (clicks)
*((uint32*)(&soundData[soundOffsets[index]])) = FOURCC("SEGA"); // mark sample as SEGA PCM
stream.seek(size);
break; break;
} }
case CHUNK("ENDFILE\0") : case CHUNK("ENDFILE\0") :
@@ -5329,6 +5353,7 @@ namespace TR {
uint8 *data = &soundData[soundOffsets[index]]; uint8 *data = &soundData[soundOffsets[index]];
uint32 size = 0; uint32 size = 0;
switch (version) { switch (version) {
case VER_TR1_SAT : size = soundSize[index]; break;
case VER_TR1_PC : case VER_TR1_PC :
case VER_TR2_PC : case VER_TR2_PC :
case VER_TR3_PC : size = FOURCC(data + 4) + 8; break; // read size from wave header case VER_TR3_PC : size = FOURCC(data + 4) + 8; break; // read size from wave header

View File

@@ -225,13 +225,24 @@ namespace Sound {
frame.R = stream->read(value); frame.R = stream->read(value);
} else } else
frame.L = frame.R = stream->read(value); frame.L = frame.R = stream->read(value);
} else if (bits == 8) { } else if (bits == 8 || bits == -8) {
uint8 value;
if (channels == 2) { if (bits > 0) {
frame.L = stream->read(value) * 257 - 32768; uint8 value;
frame.R = stream->read(value) * 257 - 32768; if (channels == 2) {
} else frame.L = stream->read(value) * 257 - 32768;
frame.L = frame.R = stream->read(value) * 257 - 32768; frame.R = stream->read(value) * 257 - 32768;
} else
frame.L = frame.R = stream->read(value) * 257 - 32768;
} else {
int8 value;
if (channels == 2) {
frame.L = (stream->read(value) + 128) * 257 - 32768;
frame.R = (stream->read(value) + 128) * 257 - 32768;
} else
frame.L = frame.R = (stream->read(value) + 128) * 257 - 32768;
}
} else { } else {
ASSERT(false); ASSERT(false);
return 0; return 0;
@@ -746,6 +757,9 @@ namespace Sound {
decoder = new MP3(stream, 2); decoder = new MP3(stream, 2);
#endif #endif
} }
else if (fourcc == FOURCC("SEGA")) { // Sega Saturn PCM mono signed 8-bit 11025 Hz
decoder = new PCM(stream, 1, 11025, stream->size, -8);
}
else { // vag else { // vag
stream->setPos(0); stream->setPos(0);
#ifdef DECODE_VAG #ifdef DECODE_VAG