reimplement: SHC_3BB0A8C1_0x0047AF50 100%#117
Conversation
|
Claude's try: 61% #include "../SoundSystem.func.hpp"
#include "OpenSHC/Audio/SFX/SFXState.func.hpp"
#include "OpenSHC/string-literals.hpp"
#include "OpenSHC/Globals/DAT_GameCore.hpp"
#include "OpenSHC/Globals/DAT_GameSynchronyState.hpp"
#include "OpenSHC/Globals/DAT_SFXState.hpp"
#include "OpenSHC/Globals/DAT_SoundEffectsHelperData1.hpp"
namespace OpenSHC {
namespace Audio {
namespace MSS {
// FUNCTION: STRONGHOLDCRUSADER 0x0047AF50
void SoundSystem::handleBattleEndMusicTransition()
{
if (DAT_GameCore::ptr->gameMode_2 == Game::GM_EDITOR) {
return;
}
if (DAT_GameCore::ptr->gameMode_2 == Game::GM_SIEGE_THAT) {
return;
}
if (DAT_SoundEffectsHelperData1::ptr->SEC_Section1079.field0_0x0 != 5) {
return;
}
if (DAT_SoundEffectsHelperData1::ptr->SEC_Section1079.field6_0x18 != 0) {
return;
}
int vol;
if (DAT_SoundEffectsHelperData1::ptr->SEC_Section1079.troopValueLevel == 0) {
DAT_SoundEffectsHelperData1::ptr->SEC_Section1079.field6_0x18 = 1;
unsigned int volumeLevel = (unsigned int)DAT_SoundEffectsHelperData1::ptr->SEC_Section1079.volumeLevel + (unsigned int)-1;
if (volumeLevel > 4) {
return;
}
MACRO_CALL_MEMBER(SoundSystem_Func::setSomeSoundTime, this)();
if (DAT_SoundEffectsHelperData1::ptr->SEC_Section1079.troopValueLevel == 0) {
DAT_SoundEffectsHelperData1::ptr->SEC_Section1079.field0_0x0 = 1;
goto do_play_victory_1;
}
DAT_SoundEffectsHelperData1::ptr->SEC_Section1079.field0_0x0 = 1;
} else {
DAT_SoundEffectsHelperData1::ptr->SEC_Section1079.field6_0x18 = 1;
}
vol = DAT_SoundEffectsHelperData1::ptr->SEC_Section1079.volumeLevel;
vol -= 1;
if (vol != 0) {
vol -= 1;
if (vol != 0) {
return;
}
// vol == 2
MACRO_CALL_MEMBER(SoundSystem_Func::setSomeSoundTime, this)();
if (DAT_GameSynchronyState::ptr->DAT_CurrentGameMode == Game::GM_SOLITARY) {
int variation = DAT_SoundEffectsHelperData1::ptr->DAT_WinMusicVariation;
MACRO_CALL_MEMBER(SoundSystem_Func::setupVolumeAndSoundIDWithMultiplier, this)(
(eMusicIDs)(variation + DE::SHCDE::MUSIC_TUNE_WIN1), 100);
variation = DAT_SoundEffectsHelperData1::ptr->DAT_WinMusicVariation + 1;
DAT_SoundEffectsHelperData1::ptr->DAT_WinMusicVariation = variation;
if (variation > 2) {
DAT_SoundEffectsHelperData1::ptr->DAT_WinMusicVariation = 0;
goto do_play_victory_1;
}
// variation <= 2: fall through to tail2
} else {
DAT_SoundEffectsHelperData1::ptr->SEC_Section1079.field0_0x0 = 1;
}
do_play_victory_2:
MACRO_CALL_MEMBER(SFX::SFXState_Func::playVictoryMusic678, DAT_SFXState::ptr)();
return;
}
// vol == 1
if (DAT_GameSynchronyState::ptr->DAT_CurrentGameMode != Game::GM_SOLITARY) {
MACRO_CALL_MEMBER(SoundSystem_Func::setSomeSoundTime, this)();
DAT_SoundEffectsHelperData1::ptr->SEC_Section1079.field0_0x0 = 1;
return;
}
MACRO_CALL_MEMBER(SoundSystem_Func::stopMusicPlayback, this)();
MACRO_CALL_MEMBER(SoundSystem_Func::setupVolumeAndSoundIDWithMultiplier, this)(
DE::SHCDE::MUSIC_TUNE_BATTLE_L1D, 100);
do_play_victory_1:
MACRO_CALL_MEMBER(SFX::SFXState_Func::playVictoryMusic678, DAT_SFXState::ptr)();
}
}
}
}
|
|
So, I am now out of ideas.
The code structure itself basically is equal to the logic displayed in assembly. I even think the switch is determined by the code. Tests also revealed that the same intitial value that should not be loaded in to ECX is happily loaded into EAX in cases it is not used for the call. But even in source the value is only used for the call. Things that I could now think of but will not test for now. The first I consider more likely:
For all intends an purposes, the logic is identical, so this one could just be an annoyance, but it would still be nice to figure out how this happenend in the first place. It should stay draft at least until all other SoundSystem functions are done. Then we can test the theory with sharing a file with the one usage function. After that, we can discuss if we just add it with a lesser percentage. |
368e19d to
04c17cf
Compare
|
Managed to resolve this by changing if (DAT_SoundEffectsHelperData1::ptr->SEC_Section1079.volumeLevel - 1U > 4) {to It is hard to connect these and the position that used the other registers. It seems it just increased the pressure to use In general, in cases where the logic is sound, but the result is not fitting, one must try to find the boundaries the logic itself requires. Function calls or or variable usage or lifetime. Within these boundaries, certain structures can be moved, or local variables created and used. These can influence the compiler. There is still the usage of a call requiring the |
|
Wow! Nice solve! |
|
Desired changes have been implemented upstream a1f7e6d |
04c17cf to
07d5c00
Compare
Faulty register usuage related and scoped to a call. Out of ideas:- Copied known functions inside file: No sharing issue.- Outside of this, the structure seems to fit completely. The only other things are jmps extended by one byte due to the ECX move.