Merge pull request 'fix: handled all audio and parameter types correctly to prevent crashes' (#11) from GeorgeV22/LegacyEvolved:main into main

Reviewed-on: https://codeberg.org/piebot/LegacyEvolved/pulls/11
This commit is contained in:
piebot 2026-04-07 11:54:27 +02:00
commit fbc7243d16
7 changed files with 189 additions and 96 deletions

View file

@ -139,6 +139,12 @@ const char *SoundEngine::m_szStreamFileA[eStream_Max]=
// The End
"the_end_dragon_alive",
"the_end_end",
// Battle
"BattleMode1",
"BattleMode2",
"BattleMode3",
"BattleMode4",
// CDs
"11",
@ -189,7 +195,7 @@ void SoundEngine::init(Options* pOptions)
return;
}
void SoundEngine::SetStreamingSounds(int iOverworldMin, int iOverWorldMax, int iNetherMin, int iNetherMax, int iEndMin, int iEndMax, int iCD1)
void SoundEngine::SetStreamingSounds(int iOverworldMin, int iOverWorldMax, int iNetherMin, int iNetherMax, int iEndMin, int iEndMax, int iCreativeMin, int iCreativeMax, int iMenuMin, int iMenuMax, int iBattleMin, int iBattleMax, int iCD1)
{
m_iStream_Overworld_Min=iOverworldMin;
m_iStream_Overworld_Max=iOverWorldMax;
@ -197,6 +203,12 @@ void SoundEngine::SetStreamingSounds(int iOverworldMin, int iOverWorldMax, int i
m_iStream_Nether_Max=iNetherMax;
m_iStream_End_Min=iEndMin;
m_iStream_End_Max=iEndMax;
m_iStream_Creative_Min = iCreativeMin;
m_iStream_Creative_Max = iCreativeMax;
m_iStream_Menu_Min = iMenuMin;
m_iStream_Menu_Max = iMenuMax;
m_iStream_Battle_Min = iBattleMin;
m_iStream_Battle_Max = iBattleMax;
m_iStream_CD_1=iCD1;
// array to monitor recently played tracks
@ -402,12 +414,15 @@ SoundEngine::SoundEngine()
m_bHeardTrackA=nullptr;
// Start the streaming music playing some music from the overworld
SetStreamingSounds(eStream_Overworld_Calm1,eStream_Overworld_piano3,
eStream_Nether1,eStream_Nether4,
eStream_end_dragon,eStream_end_end,
eStream_CD_1);
SetStreamingSounds(eStream_Overworld_Calm1, eStream_Overworld_piano3,
eStream_Nether1, eStream_Nether4,
eStream_end_dragon, eStream_end_end,
eStream_Overworld_Creative1, eStream_Overworld_Creative6,
eStream_Overworld_Menu1, eStream_Overworld_Menu4,
eStream_BattleMode1, eStream_BattleMode4,
eStream_CD_1);
m_musicID=getMusicID(LevelData::DIMENSION_OVERWORLD);
m_musicID = getMusicID(eMusicDomain_Menu);
m_StreamingAudioInfo.bIs3D=false;
m_StreamingAudioInfo.x=0;
@ -661,81 +676,83 @@ void SoundEngine::playUI(int iSound, float volume, float pitch)
// playStreaming
//
/////////////////////////////////////////////
void SoundEngine::playStreaming(const wstring& name, float x, float y , float z, float volume, float pitch, bool bMusicDelay)
void SoundEngine::playStreaming(const wstring& name, float x, float y, float z, float volume, float pitch, bool bMusicDelay)
{
// This function doesn't actually play a streaming sound, just sets states and an id for the music tick to play it
// Level audio will be played when a play with an empty name comes in
// CD audio will be played when a named stream comes in
m_StreamingAudioInfo.x=x;
m_StreamingAudioInfo.y=y;
m_StreamingAudioInfo.z=z;
m_StreamingAudioInfo.volume=volume;
m_StreamingAudioInfo.pitch=pitch;
m_StreamingAudioInfo.x = x;
m_StreamingAudioInfo.y = y;
m_StreamingAudioInfo.z = z;
m_StreamingAudioInfo.volume = volume;
m_StreamingAudioInfo.pitch = pitch;
if(m_StreamState==eMusicStreamState_Playing)
{
m_StreamState=eMusicStreamState_Stop;
}
else if(m_StreamState==eMusicStreamState_Opening)
{
m_StreamState=eMusicStreamState_OpeningCancel;
}
if(m_StreamState == eMusicStreamState_Playing)
m_StreamState = eMusicStreamState_Stop;
else if(m_StreamState == eMusicStreamState_Opening)
m_StreamState = eMusicStreamState_OpeningCancel;
if(name.empty())
{
// music, or stop CD
m_StreamingAudioInfo.bIs3D=false;
m_StreamingAudioInfo.bIs3D = false;
// we need a music id
// random delay of up to 3 minutes for music
m_iMusicDelay = random->nextInt(20 * 60 * 3);//random->nextInt(20 * 60 * 10) + 20 * 60 * 10;
m_iMusicDelay = random->nextInt(20 * 60 * 3);
#ifdef _DEBUG
m_iMusicDelay=0;
m_iMusicDelay = 0;
#endif
Minecraft *pMinecraft=Minecraft::GetInstance();
bool playerInEnd=false;
bool playerInNether=false;
Minecraft *pMinecraft = Minecraft::GetInstance();
for(unsigned int i=0;i<MAX_LOCAL_PLAYERS;i++)
bool playerInEnd = false;
bool playerInNether = false;
// @3UR: the pseudo is so cancer but i am pretty sure this is what they did
// IF it is wrong please correct it.
unsigned int i = 0;
for(i = 0; i < MAX_LOCAL_PLAYERS; i++)
{
if(pMinecraft->localplayers[i]!=nullptr)
if(pMinecraft->localplayers[i] != nullptr)
{
if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_END)
{
playerInEnd=true;
}
else if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_NETHER)
{
playerInNether=true;
}
if(pMinecraft->localplayers[i]->dimension == LevelData::DIMENSION_END)
playerInEnd = true;
else if(pMinecraft->localplayers[i]->dimension == LevelData::DIMENSION_NETHER)
playerInNether = true;
}
}
if(playerInEnd)
{
m_musicID = getMusicID(LevelData::DIMENSION_END);
}
m_musicID = getMusicID(eMusicDomain_End);
else if(playerInNether)
{
m_musicID = getMusicID(LevelData::DIMENSION_NETHER);
}
m_musicID = getMusicID(eMusicDomain_Nether);
else
{
m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD);
// @3UR: in ida it looks like they didnt have a var for the player but idc its cleaner
MultiplayerLocalPlayer* pPlayer = pMinecraft->localplayers[i-1].get();
if(pPlayer != nullptr && pPlayer->abilities.instabuild && pPlayer->abilities.mayfly)
m_musicID = getMusicID(eMusicDomain_Creative);
// TODO(3UR): this is a part of minigames also in the future other minigame ids will need to be handled for now TU30 only checks for BATTLE
//else if(pMinecraft->GetCustomGameMode() && CustomGameModeInst::GetId() == EMiniGameId::BATTLE) // @3UR: thanks https://github.com/GRAnimated/MinecraftLCE/blob/6947670d152582457bfe02bd909ee30a7ab7eb55/src/Minecraft.World/net/minecraft/world/level/gamemode/minigames/EMiniGameId.h#L3
// m_musicID = getMusicID(eMuszicDomain_Battle);
else
m_musicID = getMusicID(eMusicDomain_Overworld);
}
}
else
{
// jukebox
m_StreamingAudioInfo.bIs3D=true;
m_musicID=getMusicID(name);
m_iMusicDelay=0;
m_StreamingAudioInfo.bIs3D=true;
m_musicID=getMusicID(name);
m_iMusicDelay=0;
}
}
int SoundEngine::GetRandomishTrack(int iStart,int iEnd)
{
// 4J-PB - make it more likely that we'll get a track we've not heard for a while, although repeating tracks sometimes is fine
@ -1305,7 +1322,7 @@ void SoundEngine::playMusicUpdate()
m_StreamState=eMusicStreamState_Stop;
// Set the end track
m_musicID = getMusicID(LevelData::DIMENSION_END);
m_musicID = getMusicID(eMusicDomain_End);
SetIsPlayingEndMusic(true);
SetIsPlayingNetherMusic(false);
}
@ -1316,7 +1333,7 @@ void SoundEngine::playMusicUpdate()
m_StreamState=eMusicStreamState_Stop;
// Set the end track
m_musicID = getMusicID(LevelData::DIMENSION_NETHER);
m_musicID = getMusicID(eMusicDomain_Nether);
SetIsPlayingEndMusic(false);
SetIsPlayingNetherMusic(true);
}
@ -1325,7 +1342,7 @@ void SoundEngine::playMusicUpdate()
m_StreamState=eMusicStreamState_Stop;
// Set the end track
m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD);
m_musicID = getMusicID(eMusicDomain_Overworld);
SetIsPlayingEndMusic(false);
SetIsPlayingNetherMusic(false);
}
@ -1334,7 +1351,7 @@ void SoundEngine::playMusicUpdate()
{
m_StreamState=eMusicStreamState_Stop;
// set the Nether track
m_musicID = getMusicID(LevelData::DIMENSION_NETHER);
m_musicID = getMusicID(eMusicDomain_Nether);
SetIsPlayingNetherMusic(true);
SetIsPlayingEndMusic(false);
}
@ -1344,7 +1361,7 @@ void SoundEngine::playMusicUpdate()
{
m_StreamState=eMusicStreamState_Stop;
// set the Nether track
m_musicID = getMusicID(LevelData::DIMENSION_END);
m_musicID = getMusicID(eMusicDomain_End);
SetIsPlayingNetherMusic(false);
SetIsPlayingEndMusic(true);
}
@ -1352,7 +1369,7 @@ void SoundEngine::playMusicUpdate()
{
m_StreamState=eMusicStreamState_Stop;
// set the Nether track
m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD);
m_musicID = getMusicID(eMusicDomain_Overworld);
SetIsPlayingNetherMusic(false);
SetIsPlayingEndMusic(false);
}
@ -1432,19 +1449,19 @@ void SoundEngine::playMusicUpdate()
}
if(playerInEnd)
{
m_musicID = getMusicID(LevelData::DIMENSION_END);
m_musicID = getMusicID(eMusicDomain_End);
SetIsPlayingEndMusic(true);
SetIsPlayingNetherMusic(false);
}
else if(playerInNether)
{
m_musicID = getMusicID(LevelData::DIMENSION_NETHER);
m_musicID = getMusicID(eMusicDomain_Nether);
SetIsPlayingNetherMusic(true);
SetIsPlayingEndMusic(false);
}
else
{
m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD);
m_musicID = getMusicID(eMusicDomain_Overworld);
SetIsPlayingNetherMusic(false);
SetIsPlayingEndMusic(false);
}

View file

@ -47,6 +47,11 @@ enum eMUSICFILES
// The End
eStream_end_dragon,
eStream_end_end,
// Battle
eStream_BattleMode1,
eStream_BattleMode2,
eStream_BattleMode3,
eStream_BattleMode4,
eStream_CD_1,
eStream_CD_2,
eStream_CD_3,
@ -62,6 +67,26 @@ enum eMUSICFILES
eStream_Max,
};
// @3UR: This may not even be an enum—this is mostly guesswork.
// Why? Previously it used LevelData::DIMENSION_XXX enum, and it's unlikely they
// would have extended that with all this additional data.
// It also does not match up in IDA: LevelData::DIMENSION_END is 1,
// but now we see getMusicId(v5, 4); instead of 1.
//
// This suggests they likely introduced an entirely new enum.
//
// Additionally, there was never a case for 3, so it's skipped.
// That might indicate they extended an existing enum, but it's unclear.
enum eMUSICDOMAIN
{
eMusicDomain_Nether = 0,
eMusicDomain_Overworld = 1,
eMusicDomain_Menu = 2,
eMusicDomain_End = 4,
eMusicDomain_Creative = 5,
eMusicDomain_Battle = 6,
};
enum eMUSICTYPE
{
eMusicType_None,
@ -134,7 +159,7 @@ public:
bool isStreamingWavebankReady(); // 4J Added
int getMusicID(int iDomain);
int getMusicID(const wstring& name);
void SetStreamingSounds(int iOverworldMin, int iOverWorldMax, int iNetherMin, int iNetherMax, int iEndMin, int iEndMax, int iCD1);
void SetStreamingSounds(int iOverworldMin, int iOverWorldMax, int iNetherMin, int iNetherMax, int iEndMin, int iEndMax, int iCreativeMin, int iCreativeMax, int iMenuMin, int iMenuMax, int iBattleMin, int iBattleMax, int iCD1);
void updateMiniAudio();
void playMusicUpdate();
@ -184,6 +209,9 @@ private:
int m_iStream_Overworld_Min,m_iStream_Overworld_Max;
int m_iStream_Nether_Min,m_iStream_Nether_Max;
int m_iStream_End_Min,m_iStream_End_Max;
int m_iStream_Creative_Min,m_iStream_Creative_Max;
int m_iStream_Menu_Min,m_iStream_Menu_Max;
int m_iStream_Battle_Min,m_iStream_Battle_Max;
int m_iStream_CD_1;
bool *m_bHeardTrackA;

View file

@ -3791,10 +3791,13 @@ void CMinecraftApp::HandleXuiActions(void)
// need to stop the streaming audio - by playing streaming audio from the default texture pack now
// reset the streaming sounds back to the normal ones
#ifndef _XBOX
pMinecraft->soundEngine->SetStreamingSounds(eStream_Overworld_Calm1,eStream_Overworld_piano3,
eStream_Nether1,eStream_Nether4,
eStream_end_dragon,eStream_end_end,
eStream_CD_1);
pMinecraft->soundEngine->SetStreamingSounds(eStream_Overworld_Calm1,eStream_Overworld_piano3,
eStream_Nether1,eStream_Nether4,
eStream_end_dragon,eStream_end_end,
eStream_Overworld_Creative1,eStream_Overworld_Creative6,
eStream_Overworld_Menu1,eStream_Overworld_Menu4,
eStream_BattleMode1,eStream_BattleMode4,
eStream_CD_1);
#endif
pMinecraft->soundEngine->playStreaming(L"", 0, 0, 0, 1, 1);

View file

@ -26,10 +26,12 @@ PBYTE DLCAudioFile::getData(DWORD &dwBytes)
return m_pbData;
}
// @3UR: thanks https://github.com/LCERD/PCK-Studio/blob/500fc74395ce99fe20cbd7598999bfab3b606745/PckStudio.Core/IO/PckAudio/PckAudioFileWriter.cs#L15
const WCHAR *DLCAudioFile::wchTypeNamesA[]=
{
L"CUENAME",
L"CREDIT",
L"CUENAME",
L"CREDIT",
L"CREDITID",
};
DLCAudioFile::EAudioParameterType DLCAudioFile::getParameterType(const wstring &paramName)
@ -76,7 +78,7 @@ void DLCAudioFile::addParameter(EAudioType type, EAudioParameterType ptype, cons
case XC_LANGUAGE_JAPANESE:
case XC_LANGUAGE_TCHINESE:
case XC_LANGUAGE_KOREAN:
maximumChars = 35;
maximumChars = 55; // @3UR: this is 55 in TU30
break;
}
wstring creditValue = value;
@ -88,23 +90,6 @@ void DLCAudioFile::addParameter(EAudioType type, EAudioParameterType ptype, cons
i++;
}
size_t iLast=creditValue.find_last_of(L" ", i);
switch(XGetLanguage())
{
case XC_LANGUAGE_JAPANESE:
case XC_LANGUAGE_TCHINESE:
case XC_LANGUAGE_KOREAN:
iLast = maximumChars;
break;
default:
iLast=creditValue.find_last_of(L" ", i);
break;
}
// if a space was found, include the space on this line
if(iLast!=i)
{
iLast++;
}
app.AddCreditText((creditValue.substr(0, iLast)).c_str());
creditValue = creditValue.substr(iLast);
@ -117,6 +102,9 @@ void DLCAudioFile::addParameter(EAudioType type, EAudioParameterType ptype, cons
m_parameters[type].push_back(value);
//m_parameters[(int)type] = value;
break;
// @3UR: in IDA for TU30 this is literally just empty...
case e_AudioParamType_CreditId:
break;
}
}

View file

@ -14,7 +14,15 @@ public:
e_AudioType_Overworld = 0,
e_AudioType_Nether,
e_AudioType_End,
e_AudioType_End,
// @3UR: thanks https://github.com/LCERD/PCK-Studio/blob/500fc74395ce99fe20cbd7598999bfab3b606745/PckStudio.Core/FileFormats/PckAudioFile.cs#L25
e_AudioType_Creative,
e_AudioType_Menu,
e_AudioType_Battle,
e_AudioType_Tumble,
e_AudioType_Glide,
e_AudioType_BuildOff,
e_AudioType_Max,
};
@ -24,6 +32,7 @@ public:
e_AudioParamType_Cuename = 0,
e_AudioParamType_Credit,
e_AudioParamType_CreditId,
e_AudioParamType_Max,

View file

@ -2064,10 +2064,13 @@ void UIController::NavigateToHomeMenu()
{
// need to stop the streaming audio - by playing streaming audio from the default texture pack now
// reset the streaming sounds back to the normal ones
pMinecraft->soundEngine->SetStreamingSounds(eStream_Overworld_Calm1,eStream_Overworld_piano3,
eStream_Nether1,eStream_Nether4,
eStream_end_dragon,eStream_end_end,
eStream_CD_1);
pMinecraft->soundEngine->SetStreamingSounds(eStream_Overworld_Calm1,eStream_Overworld_piano3,
eStream_Nether1,eStream_Nether4,
eStream_end_dragon,eStream_end_end,
eStream_Overworld_Creative1,eStream_Overworld_Creative6,
eStream_Overworld_Menu1,eStream_Overworld_Menu4,
eStream_BattleMode1,eStream_BattleMode4,
eStream_CD_1);
pMinecraft->soundEngine->playStreaming(L"", 0, 0, 0, 1, 1);
// if(pDLCTexPack->m_pStreamedWaveBank!=nullptr)

View file

@ -473,18 +473,63 @@ int DLCTexturePack::packMounted(LPVOID pParam,int iPad,DWORD dwErr,DWORD dwLicen
DLCAudioFile *dlcFile = static_cast<DLCAudioFile *>(pack->getFile(DLCManager::e_DLCType_Audio, 0));
texturePack->setHasAudio(true);
// init the streaming sound ids for this texture pack
int iOverworldStart, iNetherStart, iEndStart;
int iOverworldC, iNetherC, iEndC;
int iOverworldC=dlcFile->GetCountofType(DLCAudioFile::e_AudioType_Overworld);
int iNetherC=dlcFile->GetCountofType(DLCAudioFile::e_AudioType_Nether);
int iEndStart=iOverworldC+iNetherC;
int iEndC=dlcFile->GetCountofType(DLCAudioFile::e_AudioType_End);
int iAfterEnd=iOverworldC+iNetherC+iEndC;
int iCreativeC=dlcFile->GetCountofType(DLCAudioFile::e_AudioType_Creative);
iOverworldStart=0;
iOverworldC=dlcFile->GetCountofType(DLCAudioFile::e_AudioType_Overworld);
iNetherStart=iOverworldC;
iNetherC=dlcFile->GetCountofType(DLCAudioFile::e_AudioType_Nether);
iEndStart=iOverworldC+iNetherC;
iEndC=dlcFile->GetCountofType(DLCAudioFile::e_AudioType_End);
int iCreativeStart, iCreativeRange;
if(iCreativeC)
{
iCreativeStart=iAfterEnd;
iCreativeRange=iCreativeC;
iAfterEnd+=iCreativeC;
}
else
{
iCreativeStart=0;
iCreativeRange=iOverworldC;
}
Minecraft::GetInstance()->soundEngine->SetStreamingSounds(iOverworldStart,iOverworldStart+iOverworldC-1,
iNetherStart,iNetherStart+iNetherC-1,iEndStart,iEndStart+iEndC-1,iEndStart+iEndC); // push the CD start to after
int iMenuC=dlcFile->GetCountofType(DLCAudioFile::e_AudioType_Menu);
int iMenuStart, iMenuRange;
if(iMenuC)
{
iMenuStart=iAfterEnd;
iMenuRange=iMenuC;
iAfterEnd+=iMenuC;
}
else
{
iMenuStart=0;
iMenuRange=iOverworldC;
}
int iBattleC=dlcFile->GetCountofType(DLCAudioFile::e_AudioType_Battle);
if(iBattleC)
{
Minecraft::GetInstance()->soundEngine->SetStreamingSounds(
0,iOverworldC-1,
iOverworldC,iOverworldC+iNetherC-1,
iEndStart,iEndStart+iEndC-1,
iCreativeStart,iCreativeStart+iCreativeRange-1,
iMenuStart,iMenuStart+iMenuRange-1,
iAfterEnd,iAfterEnd+iBattleC-1,
iAfterEnd+iBattleC);
}
else
{
Minecraft::GetInstance()->soundEngine->SetStreamingSounds(
0,iOverworldC-1,
iOverworldC,iOverworldC+iNetherC-1,
iEndStart,iEndStart+iEndC-1,
iCreativeStart,iCreativeStart+iCreativeRange-1,
iMenuStart,iMenuStart+iMenuRange-1,
0,iOverworldC-1,
iAfterEnd);
}
}
#endif
}