mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-05 04:37:50 +02:00
10
src/level.h
10
src/level.h
@@ -195,7 +195,7 @@ struct Level : IGame {
|
|||||||
if (!stream) return;
|
if (!stream) return;
|
||||||
Level *level = (Level*)userData;
|
Level *level = (Level*)userData;
|
||||||
|
|
||||||
level->sndSoundtrack = Sound::play(stream, vec3(0.0f), 0.01f, 1.0f, 0);
|
level->sndSoundtrack = Sound::play(stream, vec3(0.0f), 0.01f, 1.0f, Sound::MUSIC);
|
||||||
if (level->sndSoundtrack)
|
if (level->sndSoundtrack)
|
||||||
level->sndSoundtrack->setVolume(1.0f, 0.2f);
|
level->sndSoundtrack->setVolume(1.0f, 0.2f);
|
||||||
}
|
}
|
||||||
@@ -385,7 +385,7 @@ struct Level : IGame {
|
|||||||
// init sounds
|
// init sounds
|
||||||
//sndSoundtrack = Sound::play(Sound::openWAD("05_Lara's_Themes.wav"), vec3(0.0f), 1, 1, Sound::Flags::LOOP);
|
//sndSoundtrack = Sound::play(Sound::openWAD("05_Lara's_Themes.wav"), vec3(0.0f), 1, 1, Sound::Flags::LOOP);
|
||||||
|
|
||||||
sndUnderwater = lara->playSound(TR::SND_UNDERWATER, vec3(0.0f), Sound::LOOP);
|
sndUnderwater = lara->playSound(TR::SND_UNDERWATER, vec3(0.0f), Sound::LOOP | Sound::MUSIC);
|
||||||
if (sndUnderwater)
|
if (sndUnderwater)
|
||||||
sndUnderwater->volume = sndUnderwater->volumeTarget = 0.0f;
|
sndUnderwater->volume = sndUnderwater->volumeTarget = 0.0f;
|
||||||
|
|
||||||
@@ -790,7 +790,11 @@ struct Level : IGame {
|
|||||||
if (entity.type == TR::Entity::CRYSTAL)
|
if (entity.type == TR::Entity::CRYSTAL)
|
||||||
type = Shader::MIRROR;
|
type = Shader::MIRROR;
|
||||||
|
|
||||||
setRoomParams(roomIndex, type, 1.0f, intensityf(lum), controller->specular, 1.0f, isModel ? !mesh->models[entity.modelIndex - 1].opaque : true);
|
if (type == Shader::SPRITE) {
|
||||||
|
float alpha = (entity.type == TR::Entity::SMOKE || entity.type == TR::Entity::WATER_SPLASH) ? 0.75f : 1.0f;
|
||||||
|
setRoomParams(roomIndex, type, 0.5f, intensityf(lum), controller->specular, alpha, isModel ? !mesh->models[entity.modelIndex - 1].opaque : true);
|
||||||
|
} else
|
||||||
|
setRoomParams(roomIndex, type, 1.0f, intensityf(lum), controller->specular, 1.0f, isModel ? !mesh->models[entity.modelIndex - 1].opaque : true);
|
||||||
|
|
||||||
if (isModel) { // model
|
if (isModel) { // model
|
||||||
vec3 pos = controller->getPos();
|
vec3 pos = controller->getPos();
|
||||||
|
@@ -107,7 +107,7 @@
|
|||||||
<input type="button" value="Browse Level" onclick="document.getElementById('browseFile').click();" /> (.PHD, .PSX)
|
<input type="button" value="Browse Level" onclick="document.getElementById('browseFile').click();" /> (.PHD, .PSX)
|
||||||
<p style="margin:8px">
|
<p style="margin:8px">
|
||||||
OpenLara on <a target="_blank" href="https://github.com/XProger/OpenLara">github</a> & <a target="_blank" href="https://www.facebook.com/OpenLaraTR">facebook</a><br>
|
OpenLara on <a target="_blank" href="https://github.com/XProger/OpenLara">github</a> & <a target="_blank" href="https://www.facebook.com/OpenLaraTR">facebook</a><br>
|
||||||
<br><i>last update: 11.09.2017</i><br>
|
<br><i>last update: 12.09.2017</i><br>
|
||||||
</p>
|
</p>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
90
src/sound.h
90
src/sound.h
@@ -28,11 +28,15 @@ namespace Sound {
|
|||||||
short L, R;
|
short L, R;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Filter {
|
struct FrameHI {
|
||||||
#define MAX_FDN 32
|
int L, R;
|
||||||
#define MAX_DELAY 2048
|
};
|
||||||
|
|
||||||
static const short FDN[MAX_FDN] = {281,331,373,419,461,503,547,593,641,683,727,769,811,853,907,953,997,1039,1087,1129,1171,1213,1259,1301,1361,1409,1451,1493,1543,1597,1657,1699};
|
namespace Filter {
|
||||||
|
#define MAX_FDN 16
|
||||||
|
#define MAX_DELAY 1024
|
||||||
|
|
||||||
|
static const short FDN[MAX_FDN] = {281,331,373,419,461,503,547,593,641,683,727,769,811,853,907,953};
|
||||||
|
|
||||||
struct Delay {
|
struct Delay {
|
||||||
int index;
|
int index;
|
||||||
@@ -82,7 +86,7 @@ namespace Sound {
|
|||||||
void setRoomSize(const vec3 &size) {
|
void setRoomSize(const vec3 &size) {
|
||||||
float S = (size.x * size.z + size.x * size.y + size.z * size.y) * 2;
|
float S = (size.x * size.z + size.x * size.y + size.z * size.y) * 2;
|
||||||
float V = size.x * size.y * size.z;
|
float V = size.x * size.y * size.z;
|
||||||
float f = 0.07f; // brick absorption
|
float f = 0.1f; // absorption factor
|
||||||
float rt60 = 0.161f * (V / (S * f));
|
float rt60 = 0.161f * (V / (S * f));
|
||||||
float k = -10.0f / (44100.0f * rt60);
|
float k = -10.0f / (44100.0f * rt60);
|
||||||
|
|
||||||
@@ -92,22 +96,23 @@ namespace Sound {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void process(Frame *frames, int count) {
|
void process(FrameHI *frames, int count) {
|
||||||
float buffer[MAX_FDN];
|
float buffer[MAX_FDN];
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
Frame &frame = frames[i];
|
FrameHI &frame = frames[i];
|
||||||
float L = float(frame.L);
|
float L = frame.L * (1.0f / 32768.0f);
|
||||||
float R = float(frame.R);
|
float R = frame.R * (1.0f / 32768.0f);
|
||||||
float in = (L + R) * 0.5f;
|
float in = (L + R) * 0.5f;
|
||||||
float out = 0.0f;
|
float out = 0.0f;
|
||||||
|
|
||||||
// apply delay & absorption filters
|
// apply delay & absorption filters
|
||||||
for (int j = 0; j < MAX_FDN; j++) {
|
for (int j = 0; j < MAX_FDN; j++) {
|
||||||
buffer[j] = in + output[j];
|
float k = in + output[j];
|
||||||
buffer[j] = df[j].process(buffer[j], FDN[j]);
|
k = df[j].process(k, FDN[j]);
|
||||||
buffer[j] = af[j].process(buffer[j], absCoeff[j][0], absCoeff[j][1]);
|
k = af[j].process(k, absCoeff[j][0], absCoeff[j][1]);
|
||||||
out += buffer[j] * (2.0f / MAX_FDN);
|
out += k * (2.0f / MAX_FDN);
|
||||||
|
buffer[j] = k;
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply pan
|
// apply pan
|
||||||
@@ -117,8 +122,8 @@ namespace Sound {
|
|||||||
R += buffer[j] * panCoeff[j][1];
|
R += buffer[j] * panCoeff[j][1];
|
||||||
}
|
}
|
||||||
|
|
||||||
frame.L = clamp(int(L), -32768, 32767);
|
frame.L = int(L * 32768.0f);
|
||||||
frame.R = clamp(int(R), -32768, 32767);
|
frame.R = int(R * 32768.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -400,7 +405,6 @@ namespace Sound {
|
|||||||
|
|
||||||
struct Listener {
|
struct Listener {
|
||||||
mat4 matrix;
|
mat4 matrix;
|
||||||
// vec3 velocity;
|
|
||||||
} listener;
|
} listener;
|
||||||
|
|
||||||
enum Flags {
|
enum Flags {
|
||||||
@@ -410,12 +414,12 @@ namespace Sound {
|
|||||||
REPLAY = 8,
|
REPLAY = 8,
|
||||||
SYNC = 16,
|
SYNC = 16,
|
||||||
STATIC = 32,
|
STATIC = 32,
|
||||||
|
MUSIC = 64,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Sample {
|
struct Sample {
|
||||||
Decoder *decoder;
|
Decoder *decoder;
|
||||||
vec3 pos;
|
vec3 pos;
|
||||||
vec3 velocity;
|
|
||||||
float volume;
|
float volume;
|
||||||
float volumeTarget;
|
float volumeTarget;
|
||||||
float volumeDelta;
|
float volumeDelta;
|
||||||
@@ -560,11 +564,15 @@ namespace Sound {
|
|||||||
typedef void (Callback)(Sample *channel);
|
typedef void (Callback)(Sample *channel);
|
||||||
Callback *callback;
|
Callback *callback;
|
||||||
|
|
||||||
|
FrameHI *result;
|
||||||
|
Frame *buffer;
|
||||||
Filter::Reverberation reverb;
|
Filter::Reverberation reverb;
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
channelsCount = 0;
|
channelsCount = 0;
|
||||||
callback = NULL;
|
callback = NULL;
|
||||||
|
buffer = NULL;
|
||||||
|
result = NULL;
|
||||||
#ifdef DECODE_MP3
|
#ifdef DECODE_MP3
|
||||||
mp3_decode_init();
|
mp3_decode_init();
|
||||||
#endif
|
#endif
|
||||||
@@ -576,27 +584,18 @@ namespace Sound {
|
|||||||
#ifdef DECODE_MP3
|
#ifdef DECODE_MP3
|
||||||
mp3_decode_free();
|
mp3_decode_free();
|
||||||
#endif
|
#endif
|
||||||
|
delete[] buffer;
|
||||||
|
delete[] result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill(Frame *frames, int count) {
|
void renderChannels(FrameHI *result, int count, bool music) {
|
||||||
if (!channelsCount) {
|
|
||||||
memset(frames, 0, sizeof(frames[0]) * count);
|
|
||||||
if (Core::settings.audio.reverb)
|
|
||||||
reverb.process(frames, count);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct FrameHI {
|
|
||||||
int L, R;
|
|
||||||
};
|
|
||||||
|
|
||||||
FrameHI *result = new FrameHI[count];
|
|
||||||
memset(result, 0, sizeof(FrameHI) * count);
|
|
||||||
|
|
||||||
int bufSize = count + count / 2;
|
int bufSize = count + count / 2;
|
||||||
Frame *buffer = new Frame[bufSize]; // + 50% for pitch
|
if (!buffer) buffer = new Frame[bufSize]; // + 50% for pitch
|
||||||
|
|
||||||
for (int i = 0; i < channelsCount; i++) {
|
for (int i = 0; i < channelsCount; i++) {
|
||||||
|
if (music != ((channels[i]->flags & MUSIC) != 0))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (channels[i]->flags & STATIC) {
|
if (channels[i]->flags & STATIC) {
|
||||||
vec3 d = channels[i]->pos - listener.matrix.getPos();
|
vec3 d = channels[i]->pos - listener.matrix.getPos();
|
||||||
if (fabsf(d.x) > SND_FADEOFF_DIST || fabsf(d.y) > SND_FADEOFF_DIST || fabsf(d.z) > SND_FADEOFF_DIST)
|
if (fabsf(d.x) > SND_FADEOFF_DIST || fabsf(d.y) > SND_FADEOFF_DIST || fabsf(d.z) > SND_FADEOFF_DIST)
|
||||||
@@ -625,18 +624,31 @@ namespace Sound {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill(Frame *frames, int count) {
|
||||||
|
if (!channelsCount) {
|
||||||
|
memset(frames, 0, sizeof(frames[0]) * count);
|
||||||
|
//if (Core::settings.audio.reverb)
|
||||||
|
// reverb.process(frames, count);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result) result = new FrameHI[count];
|
||||||
|
memset(result, 0, sizeof(FrameHI) * count);
|
||||||
|
|
||||||
|
renderChannels(result, count, false);
|
||||||
|
|
||||||
|
if (Core::settings.audio.reverb)
|
||||||
|
reverb.process(result, count);
|
||||||
|
|
||||||
|
renderChannels(result, count, true);
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
frames[i].L = clamp(result[i].L, -32768, 32767);
|
frames[i].L = clamp(result[i].L, -32768, 32767);
|
||||||
frames[i].R = clamp(result[i].R, -32768, 32767);
|
frames[i].R = clamp(result[i].R, -32768, 32767);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Core::settings.audio.reverb)
|
|
||||||
reverb.process(frames, count);
|
|
||||||
|
|
||||||
delete[] buffer;
|
|
||||||
delete[] result;
|
|
||||||
|
|
||||||
for (int i = 0; i < channelsCount; i++)
|
for (int i = 0; i < channelsCount; i++)
|
||||||
if (!channels[i]->isPlaying) {
|
if (!channels[i]->isPlaying) {
|
||||||
if (callback) callback(channels[i]);
|
if (callback) callback(channels[i]);
|
||||||
|
@@ -68,13 +68,6 @@ struct Sprite : Controller {
|
|||||||
|
|
||||||
virtual void render(Frustum *frustum, MeshBuilder *mesh, Shader::Type type, bool caustics) {
|
virtual void render(Frustum *frustum, MeshBuilder *mesh, Shader::Type type, bool caustics) {
|
||||||
Core::setBlending(bmAlpha);
|
Core::setBlending(bmAlpha);
|
||||||
|
|
||||||
TR::Entity::Type eType = getEntity().type;
|
|
||||||
if (eType == TR::Entity::SMOKE || eType == TR::Entity::WATER_SPLASH)
|
|
||||||
Core::active.shader->setParam(uMaterial, vec4(0.5f, 1.0f, 0.0f, 0.75f));
|
|
||||||
else
|
|
||||||
Core::active.shader->setParam(uMaterial, vec4(0.5f, 1.0f, 0.0f, 1.0f));
|
|
||||||
|
|
||||||
Core::active.shader->setParam(uBasis, Basis(Core::mViewInv.getRot(), pos));
|
Core::active.shader->setParam(uBasis, Basis(Core::mViewInv.getRot(), pos));
|
||||||
mesh->renderSprite(-(getEntity().modelIndex + 1), frame);
|
mesh->renderSprite(-(getEntity().modelIndex + 1), frame);
|
||||||
Core::setBlending(bmNone);
|
Core::setBlending(bmNone);
|
||||||
|
Reference in New Issue
Block a user