1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-04-22 03:51:58 +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) {
updateJoints();
ASSERT(getModel() && index < getModel()->mCount);
if (getModel() && getModel()->mCount && index >= getModel()->mCount)
return joints[0];
return joints[index];
}

View File

@ -3299,6 +3299,19 @@ namespace TR {
uint32 flag = stream.readBE32();
if (flag == 0x00000000) { // SND
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;
}
ASSERT(flag == 0x00000010); // SAT
@ -3603,8 +3616,8 @@ namespace TR {
spriteSequences = spriteSequencesCount ? new SpriteSequence[spriteSequencesCount] : NULL;
for (int i = 0; i < spriteSequencesCount; i++) {
SpriteSequence &s = spriteSequences[i];
s.unused = stream.readBE16();
s.type = Entity::remap(version, Entity::Type(stream.readBE16()));
ASSERTV(stream.readBE16() == 0);
s.type = Entity::remap(version, Entity::Type(stream.readBE16()));
s.sCount = (s.type >= Entity::TR1_TYPE_MAX) ? 1 : -stream.readBE16();
s.sStart = stream.readBE16();
}
@ -3619,22 +3632,33 @@ namespace TR {
ASSERTV(stream.readBE32() == 0x00000002);
int count = stream.readBE32();
soundsMap = new int16[count];
for (int i = 0; i < count; i++) {
for (int i = 0; i < count; i++)
soundsMap[i] = stream.readBE16();
soundsMap[i] = -1; // TODO
}
break;
}
case CHUNK("SAMPINFS") : {
ASSERTV(stream.readBE32() == 0x00000008);
int count = stream.readBE32();
stream.seek(count * 8); // TODO
soundsInfoCount = stream.readBE32();
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;
}
case CHUNK("SAMPLE ") : {
int32 index = stream.readBE32();
int32 count = stream.readBE32();
stream.seek(count); // TODO
int32 size = stream.readBE32();
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;
}
case CHUNK("ENDFILE\0") :
@ -5329,6 +5353,7 @@ namespace TR {
uint8 *data = &soundData[soundOffsets[index]];
uint32 size = 0;
switch (version) {
case VER_TR1_SAT : size = soundSize[index]; break;
case VER_TR1_PC :
case VER_TR2_PC :
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);
} else
frame.L = frame.R = stream->read(value);
} else if (bits == 8) {
uint8 value;
if (channels == 2) {
frame.L = stream->read(value) * 257 - 32768;
frame.R = stream->read(value) * 257 - 32768;
} else
frame.L = frame.R = stream->read(value) * 257 - 32768;
} else if (bits == 8 || bits == -8) {
if (bits > 0) {
uint8 value;
if (channels == 2) {
frame.L = 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 {
ASSERT(false);
return 0;
@ -746,6 +757,9 @@ namespace Sound {
decoder = new MP3(stream, 2);
#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
stream->setPos(0);
#ifdef DECODE_VAG