mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-12 16:21:04 +02:00
266 lines
6.2 KiB
C++
266 lines
6.2 KiB
C++
#include "precompiled.h"
|
|
#pragma hdrstop
|
|
|
|
#include "prey_local.h"
|
|
|
|
|
|
CLASS_DECLARATION(hhSound, hhJukeBoxSpeaker)
|
|
END_CLASS
|
|
|
|
|
|
const idEventDef EV_SetNumTracks("setNumTracks", "d");
|
|
const idEventDef EV_SetTrack("setTrack", "d");
|
|
const idEventDef EV_PlaySelected("playSelected", NULL);
|
|
const idEventDef EV_TrackOver("<trackover>", NULL);
|
|
const idEventDef EV_SetJukeboxVolume("setvolume", "f");
|
|
|
|
CLASS_DECLARATION(hhConsole, hhJukeBox)
|
|
EVENT( EV_SetNumTracks, hhJukeBox::Event_SetNumTracks)
|
|
EVENT( EV_SetTrack, hhJukeBox::Event_SetTrack)
|
|
EVENT( EV_PlaySelected, hhJukeBox::Event_PlaySelected)
|
|
EVENT( EV_TrackOver, hhJukeBox::Event_TrackOver)
|
|
EVENT( EV_SetJukeboxVolume, hhJukeBox::Event_SetVolume)
|
|
END_CLASS
|
|
|
|
|
|
void hhJukeBox::Spawn() {
|
|
track = 1;
|
|
currentHistorySample = 0;
|
|
numTracks = spawnArgs.GetInt("numtracks", "1");
|
|
volume = spawnArgs.GetFloat("volume");
|
|
UpdateView();
|
|
}
|
|
|
|
void hhJukeBox::Save(idSaveGame *savefile) const {
|
|
int i;
|
|
|
|
savefile->WriteFloat( volume );
|
|
savefile->WriteInt( track );
|
|
savefile->WriteInt( numTracks );
|
|
savefile->WriteInt( currentHistorySample );
|
|
|
|
savefile->WriteInt( speakers.Num() ); // Saving of idList<idEntity*>
|
|
for( i = 0; i < speakers.Num(); i++ ) {
|
|
savefile->WriteObject(speakers[i]);
|
|
}
|
|
}
|
|
|
|
void hhJukeBox::Restore( idRestoreGame *savefile ) {
|
|
int i, num;
|
|
|
|
savefile->ReadFloat( volume );
|
|
savefile->ReadInt( track );
|
|
savefile->ReadInt( numTracks );
|
|
savefile->ReadInt( currentHistorySample );
|
|
|
|
speakers.Clear();
|
|
savefile->ReadInt( num );
|
|
speakers.SetNum( num );
|
|
for( i = 0; i < num; i++ ) {
|
|
savefile->ReadObject( reinterpret_cast<idClass *&>(speakers[i]) );
|
|
}
|
|
|
|
UpdateVolume();
|
|
}
|
|
|
|
void hhJukeBox::ConsoleActivated() {
|
|
BecomeActive(TH_MISC3);
|
|
}
|
|
|
|
void hhJukeBox::UpdateView() {
|
|
idUserInterface *gui = renderEntity.gui[0];
|
|
|
|
if (gui) {
|
|
gui->SetStateInt("track", track);
|
|
gui->SetStateFloat("volume", volume);
|
|
}
|
|
}
|
|
|
|
void hhJukeBox::ClearSpectrum() {
|
|
idUserInterface *gui = renderEntity.gui[0];
|
|
if (gui) {
|
|
gui->SetStateFloat("amplitude", 0.0f);
|
|
|
|
for (int ix=0; ix<10; ix++) {
|
|
gui->SetStateFloat(va("amplitude%d", ix), 0.0f);
|
|
}
|
|
gui->StateChanged(gameLocal.time);
|
|
}
|
|
}
|
|
|
|
void hhJukeBox::SetTrack(int newTrack) {
|
|
track = idMath::ClampInt(1, numTracks, newTrack);
|
|
}
|
|
|
|
void hhJukeBox::PlayCurrentTrack() {
|
|
const char *shaderName = spawnArgs.GetString(va("snd_song%d", track), NULL);
|
|
const idSoundShader *shader = declManager->FindSound(shaderName);
|
|
int time = 0;
|
|
|
|
// Clear up any previous state, even if using another mixer at the time
|
|
StopCurrentTrack();
|
|
|
|
// In OpenAL, samples that are out of range pause instead of mute so the targetted speakers can get out of sync.
|
|
if (shader && targets.Num() && !cvarSystem->GetCVarBool("s_useOpenAL")) {
|
|
for (int ix=0; ix<targets.Num(); ix++) {
|
|
if (targets[ix].IsValid()) {
|
|
targets[ix]->StartSoundShader(shader, SND_CHANNEL_VOICE, 0, true, &time);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
StartSound(va("snd_song%d", track), SND_CHANNEL_VOICE, 0, true, &time);
|
|
}
|
|
UpdateVolume();
|
|
CancelEvents(&EV_TrackOver);
|
|
PostEventMS(&EV_TrackOver, time + 500);
|
|
}
|
|
|
|
void hhJukeBox::StopCurrentTrack() {
|
|
CancelEvents(&EV_TrackOver);
|
|
ClearSpectrum();
|
|
|
|
// Stop speakers and jukebox so no mixer switches can screw us up
|
|
StopSound(SND_CHANNEL_VOICE, true);
|
|
for (int ix=0; ix<targets.Num(); ix++) {
|
|
if (targets[ix].IsValid()) {
|
|
targets[ix]->StopSound(SND_CHANNEL_VOICE, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool hhJukeBox::HandleSingleGuiCommand(idEntity *entityGui, idLexer *src) {
|
|
|
|
idToken token;
|
|
|
|
if (!src->ReadToken(&token)) {
|
|
return false;
|
|
}
|
|
|
|
if (token == ";") {
|
|
return false;
|
|
}
|
|
|
|
if (token.Icmp("prevtrack") == 0) {
|
|
SetTrack(track-1);
|
|
UpdateView();
|
|
}
|
|
else if (token.Icmp("nexttrack") == 0) {
|
|
SetTrack(track+1);
|
|
UpdateView();
|
|
}
|
|
else if (token.Icmp("selecttrack") == 0) {
|
|
BecomeActive(TH_MISC3);
|
|
PlayCurrentTrack();
|
|
UpdateView();
|
|
}
|
|
else if (token.Icmp("turnoff") == 0) {
|
|
StopCurrentTrack();
|
|
BecomeInactive(TH_MISC3);
|
|
UpdateView();
|
|
}
|
|
else if (token.Icmp("turnon") == 0) {
|
|
BecomeActive(TH_MISC3);
|
|
UpdateView();
|
|
}
|
|
else if (token.Icmp("volumeup") == 0) {
|
|
volume = idMath::ClampFloat(0.0f, 1.0f, volume + 0.02f);
|
|
UpdateVolume();
|
|
UpdateView();
|
|
}
|
|
else if (token.Icmp("volumedown") == 0) {
|
|
volume = idMath::ClampFloat(0.0f, 1.0f, volume - 0.02f);
|
|
UpdateVolume();
|
|
UpdateView();
|
|
}
|
|
else {
|
|
src->UnreadToken(&token);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void hhJukeBox::UpdateEntityVolume(idEntity *ent) {
|
|
ent->HH_SetSoundVolume(volume, SND_CHANNEL_VOICE);
|
|
}
|
|
|
|
void hhJukeBox::UpdateVolume() {
|
|
if (targets.Num() && !cvarSystem->GetCVarBool("s_useOpenAL")) {
|
|
for (int ix=0; ix<targets.Num(); ix++) {
|
|
if (targets[ix].IsValid()) {
|
|
UpdateEntityVolume(targets[ix].GetEntity());
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
UpdateEntityVolume(this);
|
|
}
|
|
}
|
|
|
|
void hhJukeBox::Think() {
|
|
|
|
hhConsole::Think();
|
|
|
|
if (thinkFlags & TH_MISC3) {
|
|
float amplitude = 0.0f;
|
|
|
|
//TODO: This sampling really only needs to take place once/render
|
|
if (refSound.referenceSound && refSound.referenceSound->CurrentlyPlaying()) {
|
|
amplitude = refSound.referenceSound->CurrentAmplitude();
|
|
}
|
|
else if (targets.Num() && targets[0].IsValid() && targets[0].GetEntity()->IsType(hhSound::Type) ) {
|
|
amplitude = static_cast<hhSound*>(targets[0].GetEntity())->GetCurrentAmplitude(SND_CHANNEL_VOICE);
|
|
}
|
|
|
|
amplitude = idMath::ClampFloat(0.0f, 1.0f, amplitude);
|
|
idUserInterface *gui = renderEntity.gui[0]; // Interface area
|
|
if (gui) {
|
|
gui->SetStateFloat("amplitude", amplitude);
|
|
|
|
currentHistorySample = (currentHistorySample+1)%10;
|
|
gui->SetStateFloat(va("amplitude%d", currentHistorySample), amplitude);
|
|
gui->StateChanged(gameLocal.time);
|
|
}
|
|
gui = renderEntity.gui[1]; // Outer jukebox
|
|
if (gui) {
|
|
gui->SetStateFloat("amplitude", amplitude);
|
|
}
|
|
}
|
|
}
|
|
|
|
void hhJukeBox::Event_SetNumTracks(int newNumTracks) {
|
|
numTracks = newNumTracks;
|
|
}
|
|
|
|
void hhJukeBox::Event_SetTrack(int newTrack) {
|
|
SetTrack(newTrack);
|
|
UpdateView();
|
|
}
|
|
|
|
void hhJukeBox::Event_PlaySelected() {
|
|
PlayCurrentTrack();
|
|
BecomeActive(TH_MISC3);
|
|
UpdateView();
|
|
}
|
|
|
|
void hhJukeBox::Event_TrackOver() {
|
|
ClearSpectrum();
|
|
//loop to beginning
|
|
if ( track+1 > numTracks ) {
|
|
SetTrack(1);
|
|
} else {
|
|
SetTrack(track+1);
|
|
}
|
|
PlayCurrentTrack();
|
|
UpdateView();
|
|
}
|
|
|
|
void hhJukeBox::Event_SetVolume(float vol) {
|
|
volume = idMath::ClampFloat(0.0f, 1.0f, vol);
|
|
UpdateVolume();
|
|
UpdateView();
|
|
}
|
|
|
|
|