Something went wrong. Try again.
the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
Something went wrong. Try again.
30 kB · 1078 lines
C++
at main
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079#include "stdafx.h"#include "..\..\..\Minecraft.World\net.minecraft.world.entity.h"#include "..\..\..\Minecraft.World\Mth.h"#include "..\..\..\Minecraft.World\Random.h"#include "..\..\..\Minecraft.World\LevelData.h"#include "..\..\Minecraft.h"#include "..\..\MultiplayerLocalPlayer.h"#include "SoundEngine.h"#include "..\..\TexturePackRepository.h"#include "..\..\TexturePack.h"#include "..\..\Common\DLC\DLCAudioFile.h"#include "..\..\DLCTexturePack.h"
IXAudio2* g_pXAudio2 = NULL; // pointer to XAudio2 instance used by QNet and XACTIXAudio2MasteringVoice* g_pXAudio2MasteringVoice = NULL; // pointer to XAudio2 mastering voice
IXACT3Engine *SoundEngine::m_pXACT3Engine = NULL;IXACT3WaveBank *SoundEngine::m_pWaveBank = NULL;IXACT3WaveBank *SoundEngine::m_pWaveBank2 = NULL;IXACT3WaveBank *SoundEngine::m_pStreamedWaveBank = NULL;IXACT3WaveBank *SoundEngine::m_pStreamedWaveBankAdditional = NULL;IXACT3SoundBank *SoundEngine::m_pSoundBank = NULL;IXACT3SoundBank *SoundEngine::m_pSoundBank2 = NULL;CRITICAL_SECTION SoundEngine::m_CS;
X3DAUDIO_HANDLE SoundEngine::m_xact3dInstance;vector<SoundEngine::soundInfo *> SoundEngine::currentSounds;X3DAUDIO_DSP_SETTINGS SoundEngine::m_DSPSettings;X3DAUDIO_EMITTER SoundEngine::m_emitter;X3DAUDIO_LISTENER SoundEngine::m_listeners[4];int SoundEngine::m_validListenerCount = 0;
X3DAUDIO_DISTANCE_CURVE_POINT SoundEngine::m_VolumeCurvePoints[2] = { {0.0f, 1.0f}, {1.0f, 0.0f},};
X3DAUDIO_DISTANCE_CURVE_POINT SoundEngine::m_DragonVolumeCurvePoints[2] = { {0.0f, 1.0f}, {1.0f, 0.5f},};X3DAUDIO_DISTANCE_CURVE_POINT SoundEngine::m_VolumeCurvePointsNoDecay[2] = { {0.0f, 1.0f}, {1.0f, 1.0f},};
X3DAUDIO_DISTANCE_CURVE SoundEngine::m_VolumeCurve;X3DAUDIO_DISTANCE_CURVE SoundEngine::m_DragonVolumeCurve;X3DAUDIO_DISTANCE_CURVE SoundEngine::m_VolumeCurveNoDecay;
void SoundEngine::setXACTEngine( IXACT3Engine *pXACT3Engine){ m_pXACT3Engine = pXACT3Engine;}
void SoundEngine::destroy(){}
SoundEngine::SoundEngine(){ random = new Random(); noMusicDelay = random->nextInt(20 * 60 * 10);
ZeroMemory(&m_MusicInfo,sizeof(soundInfo)); //bIsPlayingStreamingCDMusic=false; //m_bIsPlayingStreamingGameMusic=false; SetIsPlayingEndMusic(false); SetIsPlayingNetherMusic(false); m_VolumeCurve.PointCount = 2; m_VolumeCurve.pPoints = m_VolumeCurvePoints; m_DragonVolumeCurve.PointCount = 2; m_DragonVolumeCurve.pPoints = m_DragonVolumeCurvePoints; m_VolumeCurveNoDecay.PointCount = 2; m_VolumeCurveNoDecay.pPoints = m_VolumeCurvePointsNoDecay;
m_bStreamingMusicReady=false; m_bStreamingWaveBank1Ready=false; m_bStreamingWaveBank2Ready=false;}
void SoundEngine::init(Options *pOptions){ InitializeCriticalSection(&m_CS);
// Iniatialise XACT itself HRESULT hr; if ( FAILED ( hr = XACT3CreateEngine( 0, &m_pXACT3Engine ) ) ) { app.FatalLoadError(); assert( false ); return; }
// Load global settings file // 4J-PB - move this to the title update, since we've corrected it to allow sounds to be pitch varied when they weren't before HANDLE file;#ifdef _TU_BUILD file = CreateFile("UPDATE:\\res\\audio\\Minecraft.xgs", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);#else file = CreateFile("GAME:\\res\\TitleUpdate\\audio\\Minecraft.xgs", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);#endif if( file == INVALID_HANDLE_VALUE ) { app.FatalLoadError(); assert(false); return; } DWORD dwFileSize = GetFileSize(file,NULL); DWORD bytesRead = 0; DWORD memFlags = MAKE_XALLOC_ATTRIBUTES(0,FALSE,TRUE,FALSE,0,XALLOC_PHYSICAL_ALIGNMENT_DEFAULT,XALLOC_MEMPROTECT_READWRITE,FALSE,XALLOC_MEMTYPE_PHYSICAL); void *pvGlobalSettings = XMemAlloc(dwFileSize, memFlags); ReadFile(file,pvGlobalSettings,dwFileSize,&bytesRead,NULL); CloseHandle(file);
XACT_RUNTIME_PARAMETERS EngineParameters = {0}; EngineParameters.lookAheadTime = XACT_ENGINE_LOOKAHEAD_DEFAULT; EngineParameters.fnNotificationCallback = &this->XACTNotificationCallback; EngineParameters.pGlobalSettingsBuffer = pvGlobalSettings; EngineParameters.globalSettingsBufferSize = dwFileSize; EngineParameters.globalSettingsFlags = XACT_FLAG_GLOBAL_SETTINGS_MANAGEDATA; EngineParameters.pXAudio2 = g_pXAudio2; EngineParameters.pMasteringVoice = g_pXAudio2MasteringVoice;
if ( FAILED ( hr = m_pXACT3Engine->Initialize( &EngineParameters ) ) ) { app.FatalLoadError(); assert( false ); return; }
// printf("XACT initialisation complete\n");
// Initialise X3D XACT3DInitialize(m_pXACT3Engine,m_xact3dInstance);
// Set up common structures that can be re-used between sounds & just have required bits updated memset(&m_DSPSettings,0,sizeof(X3DAUDIO_DSP_SETTINGS)); WAVEFORMATEXTENSIBLE format; m_pXACT3Engine->GetFinalMixFormat(&format); m_DSPSettings.SrcChannelCount = 1; m_DSPSettings.DstChannelCount = format.Format.nChannels; // printf("%d channels\n", format.Format.nChannels); m_DSPSettings.pMatrixCoefficients = new FLOAT32[m_DSPSettings.SrcChannelCount * m_DSPSettings.DstChannelCount];
for( int i = 0; i < 4; i++ ) { memset(&m_listeners[i],0,sizeof(X3DAUDIO_LISTENER)); m_listeners[i].OrientFront.z = 1.0f; m_listeners[i].OrientTop.y = 1.0f; } m_validListenerCount = 1; memset(&m_emitter,0,sizeof(X3DAUDIO_EMITTER)); m_emitter.ChannelCount = 1; m_emitter.pVolumeCurve = &m_VolumeCurve; m_emitter.pLFECurve = &m_VolumeCurve; m_emitter.CurveDistanceScaler = 16.0f; m_emitter.OrientFront.z = 1.0f; m_emitter.OrientTop.y = 1.0f;
// Create resident wave bank - leave memory for this managed by xact so it can free it
file = CreateFile("GAME:\\res\\audio\\resident.xwb", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if( file == INVALID_HANDLE_VALUE ) { app.FatalLoadError(); assert(false); return; }
dwFileSize = GetFileSize(file,NULL); void *pvWaveBank = XMemAlloc(dwFileSize, memFlags); ReadFile(file,pvWaveBank,dwFileSize,&bytesRead,NULL); CloseHandle(file);
if ( FAILED( hr = m_pXACT3Engine->CreateInMemoryWaveBank( pvWaveBank, dwFileSize, XACT_FLAG_ENGINE_CREATE_MANAGEDATA, memFlags, &m_pWaveBank ) ) ) { app.FatalLoadError(); assert(false); return; }
// 4J-PB - add new sounds wavebank#ifdef _TU_BUILD file = CreateFile("UPDATE:\\res\\audio\\additional.xwb", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);#else file = CreateFile("GAME:\\res\\TitleUpdate\\audio\\additional.xwb", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);#endif if( file == INVALID_HANDLE_VALUE ) { app.FatalLoadError(); assert(false); return; }
dwFileSize = GetFileSize(file,NULL); void *pvWaveBank2 = XMemAlloc(dwFileSize, memFlags); ReadFile(file,pvWaveBank2,dwFileSize,&bytesRead,NULL); CloseHandle(file);
if ( FAILED( hr = m_pXACT3Engine->CreateInMemoryWaveBank( pvWaveBank2, dwFileSize, XACT_FLAG_ENGINE_CREATE_MANAGEDATA, memFlags, &m_pWaveBank2 ) ) ) { app.FatalLoadError(); assert(false); return; }
// Create streamed sound bank
file = CreateFile("GAME:\\res\\audio\\streamed.xwb", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL);
if( file == INVALID_HANDLE_VALUE ) { app.FatalLoadError(); assert(false); return; }
XACT_WAVEBANK_STREAMING_PARAMETERS streamParams; streamParams.file = file; streamParams.offset = 0; streamParams.flags = 0; streamParams.packetSize = 16; // Not sure what to pick for this - suggests a "multiple of 16" for DVD playback
if ( FAILED( hr = m_pXACT3Engine->CreateStreamingWaveBank( &streamParams, &m_pStreamedWaveBank ) ) ) { app.FatalLoadError(); assert(false); return; }
// Create streamed sound bank
//file = CreateFile("GAME:\\res\\audio\\AdditionalMusic.xwb", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL);#ifdef _TU_BUILD file = CreateFile("UPDATE:\\res\\audio\\AdditionalMusic.xwb", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);#else file = CreateFile("GAME:\\res\\TitleUpdate\\audio\\AdditionalMusic.xwb", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);#endif if( file == INVALID_HANDLE_VALUE ) { app.FatalLoadError(); assert(false); return; }
streamParams.file = file; streamParams.offset = 0; streamParams.flags = 0; streamParams.packetSize = 16; // Not sure what to pick for this - suggests a "multiple of 16" for DVD playback
if ( FAILED( hr = m_pXACT3Engine->CreateStreamingWaveBank( &streamParams, &m_pStreamedWaveBankAdditional ) ) ) { app.FatalLoadError(); assert(false); return; }
// Create sound bank - leave memory for this managed by xact so it can free it // 4J-PB - updated for the TU //file = CreateFile("GAME:\\res\\audio\\minecraft.xsb", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);#ifdef _TU_BUILD file = CreateFile("UPDATE:\\res\\audio\\minecraft.xsb", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);#else file = CreateFile("GAME:\\res\\TitleUpdate\\audio\\minecraft.xsb", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);#endif if( file == INVALID_HANDLE_VALUE ) { app.FatalLoadError(); assert(false); return; } dwFileSize = GetFileSize(file,NULL); void *pvSoundBank = XMemAlloc(dwFileSize, memFlags); ReadFile(file,pvSoundBank,dwFileSize,&bytesRead,NULL); CloseHandle(file);
if ( FAILED( hr = m_pXACT3Engine->CreateSoundBank( pvSoundBank, dwFileSize, XACT_FLAG_ENGINE_CREATE_MANAGEDATA, memFlags, &m_pSoundBank ) ) ) { app.FatalLoadError(); assert(false); return; }
// Create sound bank2 - leave memory for this managed by xact so it can free it
#ifdef _TU_BUILD file = CreateFile("UPDATE:\\res\\audio\\additional.xsb", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);#else file = CreateFile("GAME:\\res\\TitleUpdate\\audio\\additional.xsb", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);#endif if( file == INVALID_HANDLE_VALUE ) { app.FatalLoadError(); assert(false); return; } dwFileSize = GetFileSize(file,NULL); void *pvSoundBank2 = XMemAlloc(dwFileSize, memFlags); ReadFile(file,pvSoundBank2,dwFileSize,&bytesRead,NULL); CloseHandle(file);
if ( FAILED( hr = m_pXACT3Engine->CreateSoundBank( pvSoundBank2, dwFileSize, XACT_FLAG_ENGINE_CREATE_MANAGEDATA, memFlags, &m_pSoundBank2 ) ) ) { app.FatalLoadError(); assert(false); return; }
XACT_NOTIFICATION_DESCRIPTION desc = {0}; desc.flags = XACT_FLAG_NOTIFICATION_PERSIST; desc.type = XACTNOTIFICATIONTYPE_WAVEBANKPREPARED; desc.pvContext=this; m_pXACT3Engine->RegisterNotification(&desc);
// get the category to manage the sfx (Default) m_xactSFX = m_pXACT3Engine->GetCategory("Default"); m_xactMusic = m_pXACT3Engine->GetCategory("Music");}
void SoundEngine::CreateStreamingWavebank(const char *pchName, IXACT3WaveBank **ppStreamedWaveBank){ // Create streamed sound bank HRESULT hr;
HANDLE file = CreateFile(pchName, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL);
if( file == INVALID_HANDLE_VALUE ) { app.FatalLoadError(); assert(false); return; }
XACT_WAVEBANK_STREAMING_PARAMETERS streamParams; streamParams.file = file; streamParams.offset = 0; streamParams.flags = 0; streamParams.packetSize = 16; // Not sure what to pick for this - suggests a "multiple of 16" for DVD playback
if ( FAILED( hr = m_pXACT3Engine->CreateStreamingWaveBank( &streamParams, ppStreamedWaveBank ) ) ) { app.FatalLoadError(); assert(false); return; }}
void SoundEngine::CreateSoundbank(const char *pchName, IXACT3SoundBank **ppSoundBank){ HRESULT hr; HANDLE file = CreateFile(pchName, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if( file == INVALID_HANDLE_VALUE ) { app.FatalLoadError(); assert(false); return; } DWORD dwFileSize = GetFileSize(file,NULL); DWORD bytesRead = 0; DWORD memFlags = MAKE_XALLOC_ATTRIBUTES(0,FALSE,TRUE,FALSE,0,XALLOC_PHYSICAL_ALIGNMENT_DEFAULT,XALLOC_MEMPROTECT_READWRITE,FALSE,XALLOC_MEMTYPE_PHYSICAL); void *pvSoundBank = XMemAlloc(dwFileSize, memFlags); ReadFile(file,pvSoundBank,dwFileSize,&bytesRead,NULL); CloseHandle(file);
if ( FAILED( hr = m_pXACT3Engine->CreateSoundBank( pvSoundBank, dwFileSize, XACT_FLAG_ENGINE_CREATE_MANAGEDATA, memFlags, ppSoundBank ) ) ) { app.FatalLoadError(); assert(false); return; }}
bool SoundEngine::isStreamingWavebankReady(){ if(m_bStreamingMusicReady==false) { DWORD dwState; m_pSoundBank->GetState(&dwState); if(dwState&XACT_WAVEBANKSTATE_PREPARED) { m_bStreamingWaveBank1Ready=true; } m_pSoundBank2->GetState(&dwState); if(dwState&XACT_WAVEBANKSTATE_PREPARED) { m_bStreamingWaveBank2Ready=true; }
if(m_bStreamingWaveBank1Ready && m_bStreamingWaveBank2Ready) { m_bStreamingMusicReady=true; } }
return m_bStreamingMusicReady;}
#ifdef _XBOXbool SoundEngine::isStreamingWavebankReady(IXACT3WaveBank *pWaveBank){ DWORD dwState; pWaveBank->GetState(&dwState); if(dwState&XACT_WAVEBANKSTATE_PREPARED) { return true; } else { return false; }}#endif
void SoundEngine::XACTNotificationCallback( const XACT_NOTIFICATION* pNotification ){ if(pNotification->pvContext!= NULL) { if(pNotification->type==XACTNOTIFICATIONTYPE_WAVEBANKPREPARED) { SoundEngine *pSoundEngine=(SoundEngine *)pNotification->pvContext; if(pNotification->waveBank.pWaveBank==pSoundEngine->m_pStreamedWaveBank) { pSoundEngine->m_bStreamingWaveBank1Ready=true; } if(pNotification->waveBank.pWaveBank==pSoundEngine->m_pStreamedWaveBankAdditional) { pSoundEngine->m_bStreamingWaveBank2Ready=true; }
if(pSoundEngine->m_bStreamingWaveBank1Ready && pSoundEngine->m_bStreamingWaveBank2Ready) { pSoundEngine->m_bStreamingMusicReady=true; } } }}
char *SoundEngine::ConvertSoundPathToName(const wstring& name, bool bConvertSpaces){ static char buf[256]; assert(name.length()<256); for(unsigned int i = 0; i < name.length(); i++ ) { wchar_t c = name[i]; if(c=='.') c='_'; buf[i] = (char)c; } buf[name.length()] = 0; return buf;}
void SoundEngine::play(int iSound, float x, float y, float z, float volume, float pitch){ if(iSound==-1) { app.DebugPrintf(6,"PlaySound with sound of -1 !!!!!!!!!!!!!!!\n"); return; }
bool bSoundbank1=(iSound<=eSoundType_STEP_SAND);
if( (m_pSoundBank == NULL ) || (m_pSoundBank2 == NULL))return;
if( currentSounds.size() > MAX_POLYPHONY ) { return; } wstring name = wchSoundNames[iSound]; //const unsigned char *name=ucSoundNames[iSound];
char *xboxName = ConvertSoundPathToName(name); XACTINDEX idx;
if(bSoundbank1) { idx = m_pSoundBank->GetCueIndex(xboxName); } else { idx = m_pSoundBank2->GetCueIndex(xboxName); }
if( idx == XACTINDEX_INVALID ) {#ifndef _CONTENT_PACKAGE#ifdef _DEBUG __debugbreak();#endif //wprintf(L"WARNING: Sound cue not found - %ls\n", name.c_str() ); app.DebugPrintf("Not found: %s\n",xboxName);#endif return; }
// 4J-PB - check how many of this cue are already playing and ignore if there are loads int iSameSoundC=0; for( unsigned int i = 0; i < currentSounds.size(); i++ ) { SoundEngine::soundInfo *info = currentSounds[i];
if((info->idx==idx) && (info->iSoundBank==(bSoundbank1?0:1))) { iSameSoundC++; } }
if(iSameSoundC>MAX_SAME_SOUNDS_PLAYING) { return; }
IXACT3Cue *cueInstance; HRESULT hr; MemSect(31);
if(bSoundbank1) { if( FAILED( hr = m_pSoundBank->Prepare(idx, 0, 0, &cueInstance ) ) ) { MemSect(0); // printf("Sound prep failed\n"); return; } } else { if( FAILED( hr = m_pSoundBank2->Prepare(idx, 0, 0, &cueInstance ) ) ) { MemSect(0); // printf("Sound prep failed\n"); return; } }
MemSect(0);
// Register to receive callbacks for cues stopping so we can keep a track of active sounds
soundInfo *info = new soundInfo(); info->idx = idx; info->eSoundID = (eSOUND_TYPE)iSound; info->iSoundBank = bSoundbank1?0:1; info->x = x; info->y = y; info->z = z; info->volume = volume;//*m_fSoundEffectsVolume; info->pitch = pitch; info->pCue = cueInstance; info->updatePos = true; EnterCriticalSection(&m_CS); currentSounds.push_back(info); LeaveCriticalSection(&m_CS);
XACTVARIABLEINDEX vidx = cueInstance->GetVariableIndex("Pitch"); if( vidx != XACTVARIABLEINDEX_INVALID ) { // Convert pitch multiplier to semitones float semiTones = (log(pitch)/log(2.0f)) * 12.0f; cueInstance->SetVariable( vidx, semiTones ); }
update3DPosition(info); cueInstance->Play();}
void SoundEngine::playUI(int iSound, float, float){ bool bSoundBank1=(iSound<=eSoundType_STEP_SAND);
if( (m_pSoundBank == NULL ) || (m_pSoundBank2 == NULL)) return;
if( currentSounds.size() > MAX_POLYPHONY ) { return; } wstring name = wchSoundNames[iSound];
char *xboxName = (char *)ConvertSoundPathToName(name);
XACTINDEX idx = m_pSoundBank->GetCueIndex(xboxName);
if( idx == XACTINDEX_INVALID ) { // check soundbank 2 idx = m_pSoundBank2->GetCueIndex(xboxName); if( idx == XACTINDEX_INVALID ) {#ifndef _CONTENT_PACKAGE printf("Not found UI: %s\n",xboxName);#endif return; } bSoundBank1=false; }
IXACT3Cue *cueInstance; HRESULT hr;
if(bSoundBank1) { if( FAILED( hr = m_pSoundBank->Prepare(idx, 0, 0, &cueInstance ) ) ) { // printf("Sound prep failed\n"); return; } } else { if( FAILED( hr = m_pSoundBank2->Prepare(idx, 0, 0, &cueInstance ) ) ) { // printf("Sound prep failed\n"); return; } }
// Add sound info just so we can detect end of this sound soundInfo *info = new soundInfo(); info->eSoundID = (eSOUND_TYPE)0; info->iSoundBank = bSoundBank1?0:1; info->idx =idx; info->x = 0.0f; info->y = 0.0f; info->z = 0.0f; info->volume = 0.0f; info->pitch = 0.0f; info->pCue = cueInstance; info->updatePos = false; EnterCriticalSection(&m_CS); currentSounds.push_back(info); LeaveCriticalSection(&m_CS);
cueInstance->Play();}
void SoundEngine::playStreaming(const wstring& name, float x, float y, float z, float vol, float pitch, bool bMusicDelay){ IXACT3SoundBank *pSoundBank=NULL; bool bSoundBank2=false; MemSect(34); if(m_MusicInfo.pCue!=NULL) { m_MusicInfo.pCue->Stop(0); m_MusicInfo.pCue->Destroy(); m_MusicInfo.pCue = NULL; }
m_MusicInfo.volume = 1.0f;//m_fMusicVolume; m_MusicInfo.pitch = 1.0f;
SetIsPlayingEndMusic(false); SetIsPlayingNetherMusic(false);
if(name.empty()) { SetIsPlayingStreamingCDMusic(false); SetIsPlayingStreamingGameMusic(false);// will be set to true when the sound is started in the tick if(bMusicDelay) { noMusicDelay = random->nextInt(20 * 60 * 10) + 20 * 60 * 10; } else { noMusicDelay=0; } // Check if we have a local player in The Nether or in The End, and play that music if they are Minecraft *pMinecraft=Minecraft::GetInstance(); bool playerInEnd=false; bool playerInNether=false;
for(unsigned int i=0;i<XUSER_MAX_COUNT;i++) { if(pMinecraft->localplayers[i]!=NULL) { if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_END) { playerInEnd=true; } else if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_NETHER) { playerInNether=true; } } } TexturePack *pTexPack=Minecraft::GetInstance()->skins->getSelected();
if(Minecraft::GetInstance()->skins->isUsingDefaultSkin() || pTexPack->hasAudio()==false) { if(playerInEnd || playerInNether) { pSoundBank=m_pSoundBank2; } else { pSoundBank=m_pSoundBank; } } else { // get the dlc texture pack DLCTexturePack *pDLCTexPack=(DLCTexturePack *)pTexPack; pSoundBank=pDLCTexPack->m_pSoundBank;
// check we can play the sound if(isStreamingWavebankReady(pDLCTexPack->m_pStreamedWaveBank)==false) { return; } }
if(playerInEnd) { m_musicIDX = pSoundBank->GetCueIndex("the_end_dragon"); SetIsPlayingEndMusic(true); bSoundBank2=true; } else if(playerInNether) { m_musicIDX = pSoundBank->GetCueIndex("nether"); SetIsPlayingNetherMusic(true); bSoundBank2=true; } else { m_musicIDX = pSoundBank->GetCueIndex("music"); } } else { pSoundBank=m_pSoundBank; SetIsPlayingStreamingCDMusic(true); SetIsPlayingStreamingGameMusic(false);
m_musicIDX = pSoundBank->GetCueIndex(ConvertSoundPathToName(name)); }
HRESULT hr;
if( FAILED( hr = pSoundBank->Prepare(m_musicIDX, 0, 0, &m_MusicInfo.pCue ) ) ) { // printf("Sound prep failed\n"); m_musicIDX = XACTINDEX_INVALID; // don't do anything in the tick m_MusicInfo.pCue=NULL; MemSect(0); return; }
if(GetIsPlayingStreamingCDMusic()) { m_MusicInfo.x = x; m_MusicInfo.y = y; m_MusicInfo.z = z; m_MusicInfo.updatePos = true; update3DPosition(&m_MusicInfo, false); m_MusicInfo.pCue->Play(); } else { // don't play the game music - it will start playing in the tick when noMusicDelay is 0
m_MusicInfo.x = 0.0f; // will be overridden by the bPlaceEmitterAtListener m_MusicInfo.y = 0.0f; // will be overridden by the bPlaceEmitterAtListener m_MusicInfo.z = 0.0f; // will be overridden by the bPlaceEmitterAtListener m_MusicInfo.updatePos = false;
update3DPosition(&m_MusicInfo, true); }
MemSect(0);}void SoundEngine::playMusicTick(){ if( (m_pSoundBank == NULL ) || (m_pSoundBank2 == NULL)) return;
if( m_musicIDX == XACTINDEX_INVALID ) { // printf("Not found music\n"); return; }
// check to see if the sound has stopped playing DWORD state; HRESULT hr; if(m_MusicInfo.pCue!=NULL) { if( FAILED( hr = m_MusicInfo.pCue->GetState(&state) ) ) { assert(false); } else { if( state == XACT_CUESTATE_STOPPED ) { // remove the sound and reset the music playStreaming(L"", 0, 0, 0, 0, 0); return; } } }
if(GetIsPlayingStreamingGameMusic()) { if(m_MusicInfo.pCue!=NULL) { bool playerInEnd = false; bool playerInNether=false; Minecraft *pMinecraft = Minecraft::GetInstance(); for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) { if(pMinecraft->localplayers[i]!=NULL) { if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_END) { playerInEnd=true; } else if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_NETHER) { playerInNether=true; } } }
if((playerInEnd && !GetIsPlayingEndMusic()) ||(!playerInEnd && GetIsPlayingEndMusic())) { // remove the sound and reset the music playStreaming(L"", 0, 0, 0, 0, 0); } else if ((playerInNether && !GetIsPlayingNetherMusic()) ||(!playerInNether && GetIsPlayingNetherMusic())) { // remove the sound and reset the music playStreaming(L"", 0, 0, 0, 0, 0); } } // not positional so doesn't need ticked return; }
// is this cd music? If so, we need to tick it if(GetIsPlayingStreamingCDMusic()) { update3DPosition(&m_MusicInfo, false, true); } else { if (noMusicDelay > 0) { noMusicDelay--; return; }
if(m_MusicInfo.pCue!=NULL) { update3DPosition(&m_MusicInfo, true); SetIsPlayingStreamingGameMusic(true); // and play the game music here m_MusicInfo.pCue->Play(); } }}
void SoundEngine::updateMusicVolume(float fVal){ XACTVOLUME xactVol=fVal; HRESULT hr=m_pXACT3Engine->SetVolume(m_xactMusic,fVal);}
void SoundEngine::updateSystemMusicPlaying(bool isPlaying){}
void SoundEngine::updateSoundEffectVolume(float fVal){ XACTVOLUME xactVol=fVal; HRESULT hr=m_pXACT3Engine->SetVolume(m_xactSFX,fVal);}
void SoundEngine::update3DPosition(SoundEngine::soundInfo *pInfo, bool bPlaceEmitterAtListener,bool bIsCDMusic){ X3DAUDIO_LISTENER *listener = &m_listeners[0]; // Default case for single listener
if( ( m_validListenerCount > 1 ) && !bPlaceEmitterAtListener ) { // More than one listener. Find out which one is closest float nearDistSq = ( listener->Position.x - pInfo->x ) * ( listener->Position.x - pInfo->x ) + ( listener->Position.y - pInfo->y ) * ( listener->Position.y - pInfo->y ) + ( listener->Position.z + pInfo->z ) * ( listener->Position.z + pInfo->z );
for( int i = 1; i < m_validListenerCount; i++ ) { float distSq = ( m_listeners[i].Position.x - pInfo->x ) * ( m_listeners[i].Position.x - pInfo->x ) + ( m_listeners[i].Position.y - pInfo->y ) * ( m_listeners[i].Position.y - pInfo->y ) + ( m_listeners[i].Position.z + pInfo->z ) * ( m_listeners[i].Position.z + pInfo->z ); if( distSq < nearDistSq ) { listener = &m_listeners[i]; nearDistSq = distSq; } }
// More than one listener, don't do directional sounds - point our listener towards the sound float xzDist = sqrtf( ( listener->Position.x - pInfo->x ) * ( listener->Position.x - pInfo->x ) + ( listener->Position.z + pInfo->z ) * ( listener->Position.z + pInfo->z ) ); // Don't orientate if its too near to work out a distance if( xzDist > 0.001f) { listener->OrientFront.x = ( pInfo->x - listener->Position.x ) / xzDist; listener->OrientFront.y = 0.0f; listener->OrientFront.z = ( - pInfo->z - listener->Position.z ) / xzDist; } }
if(bPlaceEmitterAtListener) { m_emitter.Position.x = listener->Position.x; m_emitter.Position.y = listener->Position.y; m_emitter.Position.z = listener->Position.z; } else { // Update the position of the emitter - we aren't dynamically changing anything else m_emitter.Position.x = pInfo->x; m_emitter.Position.y = pInfo->y; m_emitter.Position.z = -pInfo->z; // Flipped sign of z as x3daudio is expecting left handed coord system }
// If this is the CD music, then make the distance scaler 4 x normal if(bIsCDMusic) { m_emitter.CurveDistanceScaler=64.0f; } else { switch(pInfo->eSoundID) { // Is this the Dragon? case eSoundType_MOB_ENDERDRAGON_GROWL: case eSoundType_MOB_ENDERDRAGON_MOVE: case eSoundType_MOB_ENDERDRAGON_END: case eSoundType_MOB_ENDERDRAGON_HIT: m_emitter.CurveDistanceScaler=100.0f; break; case eSoundType_MOB_GHAST_MOAN: case eSoundType_MOB_GHAST_SCREAM: case eSoundType_MOB_GHAST_DEATH: case eSoundType_MOB_GHAST_CHARGE: case eSoundType_MOB_GHAST_FIREBALL: m_emitter.CurveDistanceScaler=30.0f; break; } }
// 10000.0f is passed as the volume for thunder... treat this as a special case, and use a volume curve that doesn't decay with distance // rather than just trying to guess at making something really really loud... if( pInfo->volume == 10000.0f ) { m_emitter.pVolumeCurve = &m_VolumeCurveNoDecay; } else { m_emitter.pVolumeCurve = &m_VolumeCurve; }
// Calculate all the 3D things XACT3DCalculate( m_xact3dInstance, listener, &m_emitter, &m_DSPSettings );
// Put volume curve back to default in case something else is depending on this m_emitter.pVolumeCurve = &m_VolumeCurve; //m_emitter.pLFECurve = &m_VolumeCurve; m_emitter.CurveDistanceScaler=16.0f; // Apply our general volume too by scaling the calculated coefficients - so long as this isn't our special case of 10000.0f (see comment above) if( pInfo->volume != 10000.0f ) { for(unsigned int i = 0; i < m_DSPSettings.DstChannelCount; i++ ) { m_DSPSettings.pMatrixCoefficients[i] *= pInfo->volume; } }
// Finally apply to the cue XACT3DApply( &m_DSPSettings, pInfo->pCue);}
void SoundEngine::tick(shared_ptr<Mob> *players, float a){ if( m_pXACT3Engine == NULL ) return;
// Creater listener array from the local players int listenerCount = 0; bool doPosUpdate = true; if( players ) { for( int i = 0; i < 4; i++ ) { if( players[i] != NULL ) { float yRot = players[i]->yRotO + (players[i]->yRot - players[i]->yRotO) * a;
m_listeners[listenerCount].Position.x = (float) (players[i]->xo + (players[i]->x - players[i]->xo) * a); m_listeners[listenerCount].Position.y = (float) (players[i]->yo + (players[i]->y - players[i]->yo) * a); m_listeners[listenerCount].Position.z = -(float) (players[i]->zo + (players[i]->z - players[i]->zo) * a); // Flipped sign of z as x3daudio is expecting left handed coord system
float yCos = (float)cos(-yRot * Mth::RAD_TO_GRAD - PI); float ySin = (float)sin(-yRot * Mth::RAD_TO_GRAD - PI);
m_listeners[listenerCount].OrientFront.x = -ySin; m_listeners[listenerCount].OrientFront.y = 0; m_listeners[listenerCount].OrientFront.z = yCos; // Flipped sign of z as x3daudio is expecting left handed coord system
listenerCount++; } } } // If there were no valid players set, make up a default listener if( listenerCount == 0 ) { doPosUpdate = false; // Don't bother updating positions of sounds already placed m_listeners[listenerCount].Position.x = 0; m_listeners[listenerCount].Position.y = 0; m_listeners[listenerCount].Position.z = 0; m_listeners[listenerCount].OrientFront.x = 0; m_listeners[listenerCount].OrientFront.y = 0; m_listeners[listenerCount].OrientFront.z = 1.0f; listenerCount++; } m_validListenerCount = listenerCount;
EnterCriticalSection(&m_CS); for( unsigned int i = 0; i < currentSounds.size(); i++ ) { SoundEngine::soundInfo *info = currentSounds[i];
DWORD state; HRESULT hr; if( FAILED( hr = info->pCue->GetState(&state) ) ) { assert(false); } else { if( state == XACT_CUESTATE_STOPPED ) { info->pCue->Destroy(); delete currentSounds[i]; currentSounds[i] = currentSounds.back(); currentSounds.pop_back(); } else { if( info->updatePos ) { if( doPosUpdate ) { update3DPosition(info); } } } } }
LeaveCriticalSection(&m_CS); m_pXACT3Engine->DoWork();}
void SoundEngine::add(const wstring& name, File *file){}
void SoundEngine::addMusic(const wstring& name, File *file){}
void SoundEngine::addStreaming(const wstring& name, File *file){}