Bitstream fixes

This commit is contained in:
Jack Andersen 2017-02-05 17:21:58 -10:00
parent 1c86d0ac93
commit 6a7fc0145f
26 changed files with 268 additions and 120 deletions

View File

@ -183,7 +183,13 @@ bool ProjectManager::saveProject()
void ProjectManager::mainUpdate() void ProjectManager::mainUpdate()
{ {
if (m_mainMP1) if (m_mainMP1)
m_mainMP1->Proc(); {
if (m_mainMP1->Proc())
{
m_mainMP1->Shutdown();
m_mainMP1 = std::experimental::nullopt;
}
}
} }
void ProjectManager::mainDraw() void ProjectManager::mainDraw()

View File

@ -82,9 +82,23 @@ void CAudioSys::SysRemoveGroupFromAmuse(const std::string& name)
RemoveAudioGroup(set->GetAudioGroupData()); RemoveAudioGroup(set->GetAudioGroupData());
} }
static float s_MasterVol = 1.f;
static float s_SfxVol = 1.f;
void CAudioSys::_UpdateVolume()
{
GetAmuseEngine().setVolume(s_MasterVol * s_SfxVol);
}
void CAudioSys::SysSetVolume(u8 volume) void CAudioSys::SysSetVolume(u8 volume)
{ {
GetAmuseEngine().setVolume(volume / 127.f); s_MasterVol = volume / 127.f;
_UpdateVolume();
}
void CAudioSys::SysSetSfxVolume(u8 volume, u16 time, bool music, bool fx)
{
s_SfxVol = volume / 127.f;
_UpdateVolume();
} }
static s16 s_VolumeScale = 0x7f; static s16 s_VolumeScale = 0x7f;

View File

@ -31,6 +31,7 @@ private:
static CAudioSys* g_SharedSys; static CAudioSys* g_SharedSys;
boo::IAudioVoiceEngine* m_voiceEngine; boo::IAudioVoiceEngine* m_voiceEngine;
amuse::Engine m_engine; amuse::Engine m_engine;
static void _UpdateVolume();
public: public:
struct C3DEmitterParmData struct C3DEmitterParmData
@ -86,6 +87,7 @@ public:
static void SysAddGroupIntoAmuse(const std::string& name); static void SysAddGroupIntoAmuse(const std::string& name);
static void SysRemoveGroupFromAmuse(const std::string& name); static void SysRemoveGroupFromAmuse(const std::string& name);
static void SysSetVolume(u8 volume); static void SysSetVolume(u8 volume);
static void SysSetSfxVolume(u8 volume, u16 time, bool music, bool fx);
static s16 GetDefaultVolumeScale(); static s16 GetDefaultVolumeScale();
static void SetDefaultVolumeScale(s16 scale); static void SetDefaultVolumeScale(s16 scale);

View File

@ -66,10 +66,10 @@ void CStaticAudioPlayer::DecodeMonoAndMix(s16* bufOut, u32 numSamples,
if (!loopState && cur + i == loopStartCur) if (!loopState && cur + i == loopStartCur)
loopState.emplace(state); loopState.emplace(state);
*bufOut = SampClamp((g721_decoder(*byte & 0xf, &state) * vol) >> 15); *bufOut = SampClamp(((g721_decoder(*byte & 0xf, &state) * vol) >> 15) * 0.7f);
bufOut += 2; bufOut += 2;
*bufOut = SampClamp((g721_decoder(*byte >> 4 & 0xf, &state) * vol) >> 15); *bufOut = SampClamp(((g721_decoder(*byte >> 4 & 0xf, &state) * vol) >> 15) * 0.7f);
bufOut += 2; bufOut += 2;
} }

View File

@ -328,8 +328,8 @@ struct SDSPStream : boo::IAudioVoiceCallback
if (!x0_active || xe8_silent) if (!x0_active || xe8_silent)
return; return;
float coefs[8] = {}; float coefs[8] = {};
coefs[int(boo::AudioChannel::FrontLeft)] = m_leftgain * vol; coefs[int(boo::AudioChannel::FrontLeft)] = m_leftgain * vol * 0.7f;
coefs[int(boo::AudioChannel::FrontRight)] = m_rightgain * vol; coefs[int(boo::AudioChannel::FrontRight)] = m_rightgain * vol * 0.7f;
m_booVoice->setMonoChannelLevels(nullptr, coefs, true); m_booVoice->setMonoChannelLevels(nullptr, coefs, true);
} }
@ -1153,12 +1153,44 @@ void CStreamAudioManager::UpdateDSPStreamers(float dt)
UpdateDSP(true, dt); UpdateDSP(true, dt);
} }
void CStreamAudioManager::StopAllStreams()
{
for (int i=0 ; i<2 ; ++i)
{
StopStreaming(i);
SDSPPlayer& p = s_Players[i];
SDSPPlayer& qp = s_QueuedPlayers[i];
p = SDSPPlayer();
qp = SDSPPlayer();
}
}
void CStreamAudioManager::Update(float dt) void CStreamAudioManager::Update(float dt)
{ {
CDSPStreamManager::PollHeaderReadCompletions(); CDSPStreamManager::PollHeaderReadCompletions();
UpdateDSPStreamers(dt); UpdateDSPStreamers(dt);
} }
void CStreamAudioManager::StopAll()
{
StopAllStreams();
}
void CStreamAudioManager::SetMusicUnmute(bool unmute)
{
g_MusicUnmute = unmute;
}
void CStreamAudioManager::SetSfxVolume(u8 volume)
{
g_SfxVolume = std::min(volume, u8(127));
}
void CStreamAudioManager::SetMusicVolume(u8 volume)
{
g_MusicVolume = std::min(volume, u8(127));
}
void CStreamAudioManager::Initialize() void CStreamAudioManager::Initialize()
{ {
CDSPStreamManager::Initialize(); CDSPStreamManager::Initialize();

View File

@ -17,6 +17,7 @@ class CStreamAudioManager
static void StopStreaming(bool oneshot); static void StopStreaming(bool oneshot);
static void UpdateDSP(bool oneshot, float dt); static void UpdateDSP(bool oneshot, float dt);
static void UpdateDSPStreamers(float dt); static void UpdateDSPStreamers(float dt);
static void StopAllStreams();
public: public:
static void Start(bool oneshot, const std::string& fileName, u8 volume, static void Start(bool oneshot, const std::string& fileName, u8 volume,
@ -25,6 +26,11 @@ public:
static void FadeBackIn(bool oneshot, float fadeTime); static void FadeBackIn(bool oneshot, float fadeTime);
static void TemporaryFadeOut(bool oneshot, float fadeTime); static void TemporaryFadeOut(bool oneshot, float fadeTime);
static void Update(float dt); static void Update(float dt);
static void StopAll();
static void SetMusicUnmute(bool unmute);
static void SetSfxVolume(u8 volume);
static void SetMusicVolume(u8 volume);
static void Initialize(); static void Initialize();
static void Shutdown(); static void Shutdown();
}; };

View File

@ -8,7 +8,8 @@
#include "CGameState.hpp" #include "CGameState.hpp"
#include "Input/CFinalInput.hpp" #include "Input/CFinalInput.hpp"
#include "Audio/CSfxManager.hpp" #include "Audio/CSfxManager.hpp"
//#include "Audio/CStreamedAudioManager.hpp" #include "Audio/CStreamAudioManager.hpp"
#include "Graphics/CMoviePlayer.hpp"
namespace urde namespace urde
{ {
@ -283,23 +284,19 @@ void CGameOptions::SetSfxVolume(s32 vol, bool apply)
{ {
x58_sfxVol = zeus::clamp(0, vol, 0x7f); x58_sfxVol = zeus::clamp(0, vol, 0x7f);
#if 0
if (apply) if (apply)
{ {
CAudioSys::SysSetSfxVolume(x58_sfxVol, 1, 1, 1); CAudioSys::SysSetSfxVolume(x58_sfxVol, 1, 1, 1);
CStreamedAudioManager::SetSfxVolume(x58_sfxVol); CStreamAudioManager::SetSfxVolume(x58_sfxVol);
CMoviePlayer::SetSfxVolume(x58_sfxVol); CMoviePlayer::SetSfxVolume(x58_sfxVol);
} }
#endif
} }
void CGameOptions::SetMusicVolume(s32 vol, bool apply) void CGameOptions::SetMusicVolume(s32 vol, bool apply)
{ {
x5c_musicVol = zeus::clamp(0, vol, 0x7f); x5c_musicVol = zeus::clamp(0, vol, 0x7f);
# if 0
if (apply) if (apply)
CStreamedAudioManager::SetGlobalVolume(x5c_musicVol); CStreamAudioManager::SetMusicVolume(x5c_musicVol);
#endif
} }
void CGameOptions::SetHUDAlpha(u32 alpha) void CGameOptions::SetHUDAlpha(u32 alpha)
@ -570,4 +567,10 @@ void CHintOptions::SetNextHintTime()
g_MemoryCardSys->GetHints()[x10_nextHintIdx].GetTime() + 5.f; g_MemoryCardSys->GetHints()[x10_nextHintIdx].GetTime() + 5.f;
} }
void CHintOptions::InitializeMemoryState()
{
const auto& hints = g_MemoryCardSys->GetHints();
x0_hintStates.resize(hints.size());
}
} }

View File

@ -205,6 +205,7 @@ public:
CHintOptions(CBitStreamReader& stream); CHintOptions(CBitStreamReader& stream);
void PutTo(CBitStreamWriter& writer) const; void PutTo(CBitStreamWriter& writer) const;
void SetNextHintTime(); void SetNextHintTime();
void InitializeMemoryState();
}; };
} }

View File

@ -113,7 +113,8 @@ CGameState::GameFileStateInfo CGameState::LoadGameFileState(const u8* data)
ret.x20_hardMode = stream.ReadEncoded(1); ret.x20_hardMode = stream.ReadEncoded(1);
stream.ReadEncoded(1); stream.ReadEncoded(1);
ret.x8_mlvlId = g_ResFactory->TranslateOriginalToNew(stream.ReadEncoded(32)); ResId origMLVL = stream.ReadEncoded(32);
ret.x8_mlvlId = g_ResFactory->TranslateOriginalToNew(origMLVL);
BitsToDouble conv; BitsToDouble conv;
conv.low = stream.ReadEncoded(32); conv.low = stream.ReadEncoded(32);
@ -124,7 +125,7 @@ CGameState::GameFileStateInfo CGameState::LoadGameFileState(const u8* data)
ret.x10_energyTanks = playerState.GetItemCapacity(CPlayerState::EItemType::EnergyTanks); ret.x10_energyTanks = playerState.GetItemCapacity(CPlayerState::EItemType::EnergyTanks);
u32 itemPercent; u32 itemPercent;
if (ret.x8_mlvlId == 0x158EFE17) if (origMLVL == 0x158EFE17)
itemPercent = 0; itemPercent = 0;
else else
itemPercent = playerState.CalculateItemCollectionRate() * 100 / playerState.GetPickupTotal(); itemPercent = playerState.CalculateItemCollectionRate() * 100 / playerState.GetPickupTotal();
@ -142,14 +143,17 @@ CGameState::GameFileStateInfo CGameState::LoadGameFileState(const u8* data)
CGameState::CGameState() CGameState::CGameState()
{ {
x98_playerState.reset(new CPlayerState()); x98_playerState = std::make_shared<CPlayerState>();
x9c_transManager.reset(new CWorldTransManager()); x9c_transManager = std::make_shared<CWorldTransManager>();
x228_25_deferPowerupInit = true; x228_25_deferPowerupInit = true;
if (g_MemoryCardSys)
InitializeMemoryStates();
} }
CGameState::CGameState(CBitStreamReader& stream, u32 saveIdx) CGameState::CGameState(CBitStreamReader& stream, u32 saveIdx)
: x20c_saveFileIdx(saveIdx) : x20c_saveFileIdx(saveIdx)
{ {
x9c_transManager = std::make_shared<CWorldTransManager>();
x228_25_deferPowerupInit = true; x228_25_deferPowerupInit = true;
for (u32 i = 0; i < 128; i++) for (u32 i = 0; i < 128; i++)
@ -180,6 +184,9 @@ CGameState::CGameState(CBitStreamReader& stream, u32 saveIdx)
g_SimplePool->GetObj(SObjectTag{FOURCC('SAVW'), memWorld.second.GetSaveWorldAssetId()}); g_SimplePool->GetObj(SObjectTag{FOURCC('SAVW'), memWorld.second.GetSaveWorldAssetId()});
x88_worldStates.emplace_back(stream, memWorld.first, *saveWorld); x88_worldStates.emplace_back(stream, memWorld.first, *saveWorld);
} }
InitializeMemoryWorlds();
WriteBackupBuf();
} }
void CGameState::ReadPersistentOptions(CBitStreamReader& r) void CGameState::ReadPersistentOptions(CBitStreamReader& r)
@ -292,4 +299,22 @@ float CGameState::GetHardModeWeaponMultiplier() const
return g_tweakGame->GetHardModeWeaponMultiplier(); return g_tweakGame->GetHardModeWeaponMultiplier();
} }
void CGameState::InitializeMemoryWorlds()
{
const auto& memoryWorlds = g_MemoryCardSys->GetMemoryWorlds();
for (const auto& wld : memoryWorlds)
{
const auto& layerState = StateForWorld(wld.first).GetLayerState();
layerState->InitializeWorldLayers(wld.second.GetDefaultLayerStates());
}
}
void CGameState::InitializeMemoryStates()
{
x98_playerState->InitializeScanTimes();
x1f8_hintOptions.InitializeMemoryState();
InitializeMemoryWorlds();
WriteBackupBuf();
}
} }

View File

@ -120,6 +120,8 @@ public:
void PutTo(CBitStreamWriter& writer) const; void PutTo(CBitStreamWriter& writer) const;
float GetHardModeDamageMultiplier() const; float GetHardModeDamageMultiplier() const;
float GetHardModeWeaponMultiplier() const; float GetHardModeWeaponMultiplier() const;
void InitializeMemoryWorlds();
void InitializeMemoryStates();
struct GameFileStateInfo struct GameFileStateInfo
{ {

View File

@ -63,8 +63,9 @@ bool CIOWinManager::DistributeOneMessage(const CArchitectureMessage& msg,
CArchitectureQueue& queue) CArchitectureQueue& queue)
{ {
CArchitectureMessage tmpMsg = msg; CArchitectureMessage tmpMsg = msg;
for (IOWinPQNode* node = x4_pumpRoot ; node ; node = node->x8_next) for (IOWinPQNode* node = x4_pumpRoot ; node ;)
{ {
IOWinPQNode* next = node->x8_next;
CIOWin* iow = node->GetIOWin(); CIOWin* iow = node->GetIOWin();
CIOWin::EMessageReturn mret = iow->OnMessage(tmpMsg, x8_localGatherQueue); CIOWin::EMessageReturn mret = iow->OnMessage(tmpMsg, x8_localGatherQueue);
@ -99,6 +100,8 @@ bool CIOWinManager::DistributeOneMessage(const CArchitectureMessage& msg,
return false; return false;
default: break; default: break;
} }
node = next;
} }
return false; return false;

View File

@ -37,6 +37,7 @@ public:
void RemoveAllIOWins(); void RemoveAllIOWins();
void RemoveIOWin(CIOWin* toRemove); void RemoveIOWin(CIOWin* toRemove);
void AddIOWin(std::weak_ptr<CIOWin> toAdd, int pumpPrio, int drawPrio); void AddIOWin(std::weak_ptr<CIOWin> toAdd, int pumpPrio, int drawPrio);
bool IsEmpty() const { return x0_drawRoot == nullptr && x4_pumpRoot == nullptr; }
}; };
} }

View File

@ -138,7 +138,13 @@ bool CMemoryCardSys::InitializePump()
x20_scanStates.reserve(x20_scanStates.size() + savw.GetScans().size()); x20_scanStates.reserve(x20_scanStates.size() + savw.GetScans().size());
for (const CSaveWorld::SScanState& scan : savw.GetScans()) for (const CSaveWorld::SScanState& scan : savw.GetScans())
{
auto existingSearch =
std::find_if(x20_scanStates.begin(), x20_scanStates.end(), [&](const auto& test)
{ return test.first == scan.x0_id && test.second == scan.x4_category; });
if (existingSearch == x20_scanStates.end())
x20_scanStates.emplace_back(scan.x0_id, scan.x4_category); x20_scanStates.emplace_back(scan.x0_id, scan.x4_category);
}
wldMemOut.x3c_saveWorld = std::move(world.x34_saveWorld); wldMemOut.x3c_saveWorld = std::move(world.x34_saveWorld);
wldMemOut.x2c_worldName = g_SimplePool->GetObj(SObjectTag{FOURCC('STRG'), wldMemOut.x0_strgId}); wldMemOut.x2c_worldName = g_SimplePool->GetObj(SObjectTag{FOURCC('STRG'), wldMemOut.x0_strgId});

View File

@ -29,7 +29,7 @@ class CSaveWorldMemory
public: public:
ResId GetSaveWorldAssetId() const { return x4_savwId; } ResId GetSaveWorldAssetId() const { return x4_savwId; }
u32 GetAreaCount() const { return x8_areaCount; } u32 GetAreaCount() const { return x8_areaCount; }
const std::vector<CWorldLayers::Area>& GetDefaultLayerStates() const { return x1c_defaultLayerStates; }
const TLockedToken<CStringTable>& GetWorldName() const { return x2c_worldName; } const TLockedToken<CStringTable>& GetWorldName() const { return x2c_worldName; }
const TLockedToken<CSaveWorld>& GetSaveWorld() const { return x3c_saveWorld; } const TLockedToken<CSaveWorld>& GetSaveWorld() const { return x3c_saveWorld; }
const char16_t* GetFrontEndName() const const char16_t* GetFrontEndName() const

View File

@ -4,6 +4,8 @@
#include "CStateManager.hpp" #include "CStateManager.hpp"
#include "Camera/CCameraManager.hpp" #include "Camera/CCameraManager.hpp"
#include "Camera/CFirstPersonCamera.hpp" #include "Camera/CFirstPersonCamera.hpp"
#include "CMemoryCardSys.hpp"
#include "GameGlobalObjects.hpp"
namespace urde namespace urde
{ {
@ -57,8 +59,15 @@ const char* PowerUpNames[41]=
"Artifact of Newborn", "Artifact of Newborn",
}; };
CPlayerState::CPlayerState()
: x188_staticIntf(5)
{
x0_24_ = true;
x24_powerups.resize(41);
}
CPlayerState::CPlayerState(CBitStreamReader& stream) CPlayerState::CPlayerState(CBitStreamReader& stream)
: CPlayerState() : x188_staticIntf(5)
{ {
x4_ = stream.ReadEncoded(0x20); x4_ = stream.ReadEncoded(0x20);
u32 tmp = stream.ReadEncoded(0x20); u32 tmp = stream.ReadEncoded(0x20);
@ -76,14 +85,12 @@ CPlayerState::CPlayerState(CBitStreamReader& stream)
x24_powerups[i] = CPowerUp(a, b); x24_powerups[i] = CPowerUp(a, b);
} }
x170_scanTimes.resize(846); const auto& scanStates = g_MemoryCardSys->GetScanStates();
for (u32 i = 0; i < x170_scanTimes.size(); i++) x170_scanTimes.reserve(scanStates.size());
for (const auto& state : scanStates)
{ {
x170_scanTimes[i].first = stream.ReadEncoded(1); float time = stream.ReadEncoded(1) ? 1.f : 0.f;
if (x170_scanTimes[i].first) x170_scanTimes.emplace_back(state.first, time);
x170_scanTimes[i].second = 1.f;
else
x170_scanTimes[i].second = 0.f;
} }
x180_logScans = stream.ReadEncoded(CBitStreamReader::GetBitCount(0x100)); x180_logScans = stream.ReadEncoded(CBitStreamReader::GetBitCount(0x100));
@ -394,4 +401,15 @@ void CPlayerState::ReInitalizePowerUp(CPlayerState::EItemType type, u32 capacity
InitializePowerUp(type, capacity); InitializePowerUp(type, capacity);
} }
void CPlayerState::InitializeScanTimes()
{
if (x170_scanTimes.size())
return;
const auto& scanStates = g_MemoryCardSys->GetScanStates();
x170_scanTimes.reserve(scanStates.size());
for (const auto& state : scanStates)
x170_scanTimes.emplace_back(state.first, 0.f);
}
} }

View File

@ -123,7 +123,7 @@ private:
float x1c_visorTransitionFactor = 0.2f; float x1c_visorTransitionFactor = 0.2f;
EPlayerSuit x20_currentSuit = EPlayerSuit::Power; EPlayerSuit x20_currentSuit = EPlayerSuit::Power;
rstl::reserved_vector<CPowerUp, 41> x24_powerups; rstl::reserved_vector<CPowerUp, 41> x24_powerups;
rstl::reserved_vector<std::pair<u32, float>, 846> x170_scanTimes; rstl::reserved_vector<std::pair<ResId, float>, 846> x170_scanTimes;
u32 x180_logScans = 0; u32 x180_logScans = 0;
u32 x184_totalLogScans = 0; u32 x184_totalLogScans = 0;
CStaticInterference x188_staticIntf; CStaticInterference x188_staticIntf;
@ -168,8 +168,9 @@ public:
void InitializePowerUp(EItemType type, u32 capacity); void InitializePowerUp(EItemType type, u32 capacity);
u32 GetLogScans() const { return x180_logScans; } u32 GetLogScans() const { return x180_logScans; }
u32 GetTotalLogScans() const { return x184_totalLogScans; } u32 GetTotalLogScans() const { return x184_totalLogScans; }
const rstl::reserved_vector<std::pair<u32, float>, 846>& GetScanTimes() const { return x170_scanTimes; } void InitializeScanTimes();
CPlayerState() : x188_staticIntf(5) { x0_24_ = true; } const rstl::reserved_vector<std::pair<ResId, float>, 846>& GetScanTimes() const { return x170_scanTimes; }
CPlayerState();
CPlayerState(CBitStreamReader& stream); CPlayerState(CBitStreamReader& stream);
void PutTo(CBitStreamWriter& stream); void PutTo(CBitStreamWriter& stream);

View File

@ -191,6 +191,9 @@ static u32 StaticLoopEnd = 0;
static g72x_state StaticStateLeft = {}; static g72x_state StaticStateLeft = {};
static g72x_state StaticStateRight = {}; static g72x_state StaticStateRight = {};
/* THP SFX audio */
static float SfxVolume = 1.f;
static const char* BlockNames[] = {"SpecterViewBlock"}; static const char* BlockNames[] = {"SpecterViewBlock"};
static const char* TexNames[] = {"texY", "texU", "texV"}; static const char* TexNames[] = {"texY", "texU", "texV"};
@ -523,6 +526,11 @@ void CMoviePlayer::SetStaticAudio(const void* data, u32 size, u32 loopBegin, u32
g72x_init_state(&StaticStateRight); g72x_init_state(&StaticStateRight);
} }
void CMoviePlayer::SetSfxVolume(u8 volume)
{
SfxVolume = std::min(volume, u8(127)) / 127.f;
}
void CMoviePlayer::MixAudio(s16* out, const s16* in, u32 samples) void CMoviePlayer::MixAudio(s16* out, const s16* in, u32 samples)
{ {
/* No audio frames ready */ /* No audio frames ready */
@ -557,9 +565,9 @@ void CMoviePlayer::MixAudio(s16* out, const s16* in, u32 samples)
for (u32 i=0 ; i<thisSamples ; ++i, out += 2, in += 2) for (u32 i=0 ; i<thisSamples ; ++i, out += 2, in += 2)
{ {
out[0] = DSPSampClamp(in[0] + out[0] = DSPSampClamp(in[0] +
s32(tex->audioBuf[(i+tex->playedSamples)*2]) * 0x50F4 / 0x8000); s32(tex->audioBuf[(i+tex->playedSamples)*2]) * 0x50F4 / 0x8000 * SfxVolume);
out[1] = DSPSampClamp(in[1] + out[1] = DSPSampClamp(in[1] +
s32(tex->audioBuf[(i+tex->playedSamples)*2+1]) * 0x50F4 / 0x8000); s32(tex->audioBuf[(i+tex->playedSamples)*2+1]) * 0x50F4 / 0x8000 * SfxVolume);
} }
} }
else else
@ -567,9 +575,9 @@ void CMoviePlayer::MixAudio(s16* out, const s16* in, u32 samples)
for (u32 i=0 ; i<thisSamples ; ++i, out += 2) for (u32 i=0 ; i<thisSamples ; ++i, out += 2)
{ {
out[0] = DSPSampClamp( out[0] = DSPSampClamp(
s32(tex->audioBuf[(i+tex->playedSamples)*2]) * 0x50F4 / 0x8000); s32(tex->audioBuf[(i+tex->playedSamples)*2]) * 0x50F4 / 0x8000 * SfxVolume);
out[1] = DSPSampClamp( out[1] = DSPSampClamp(
s32(tex->audioBuf[(i+tex->playedSamples)*2+1]) * 0x50F4 / 0x8000); s32(tex->audioBuf[(i+tex->playedSamples)*2+1]) * 0x50F4 / 0x8000 * SfxVolume);
} }
} }
tex->playedSamples += thisSamples; tex->playedSamples += thisSamples;

View File

@ -146,6 +146,7 @@ public:
static void DisableStaticAudio() {SetStaticAudio(nullptr, 0, 0, 0);} static void DisableStaticAudio() {SetStaticAudio(nullptr, 0, 0, 0);}
static void SetStaticAudioVolume(int vol); static void SetStaticAudioVolume(int vol);
static void SetStaticAudio(const void* data, u32 size, u32 loopBegin, u32 loopEnd); static void SetStaticAudio(const void* data, u32 size, u32 loopBegin, u32 loopEnd);
static void SetSfxVolume(u8 volume);
static void MixStaticAudio(s16* out, const s16* in, u32 samples); static void MixStaticAudio(s16* out, const s16* in, u32 samples);
void MixAudio(s16* out, const s16* in, u32 samples); void MixAudio(s16* out, const s16* in, u32 samples);
void Rewind(); void Rewind();

View File

@ -1,7 +1,21 @@
#include "IOStreams.hpp" #include "IOStreams.hpp"
#include "hecl/hecl.hpp"
namespace urde namespace urde
{ {
#define DUMP_BITS 0
#if DUMP_BITS
static void PrintBinary(u32 val, u32 count)
{
for (int i=0 ; i<count ; ++i)
{
printf("%d", (val >> (count-i-1)) & 0x1);
}
}
#endif
/*! /*!
* \brief CBitStreamReader::ReadBit * \brief CBitStreamReader::ReadBit
* Reads and decodes an encoded value from a bitstream. * Reads and decodes an encoded value from a bitstream.
@ -10,91 +24,95 @@ namespace urde
*/ */
s32 CBitStreamReader::ReadEncoded(u32 bitCount) s32 CBitStreamReader::ReadEncoded(u32 bitCount)
{ {
s32 ret = 0; #if DUMP_BITS
if (bitCount < x20_bitOffset) auto pos = position();
auto boff = x20_bitOffset;
#endif
u32 ret = 0;
s32 shiftAmt = x20_bitOffset - s32(bitCount);
if (shiftAmt < 0)
{ {
u32 diff = 0x20 - bitCount; /* OR in remaining bits of cached value */
u32 baseVal = -1; u32 mask = (1 << bitCount) - 1;
if (x20_bitOffset != 0x20) ret |= (x1c_val << -shiftAmt) & mask;
baseVal = (1 << bitCount) - 1;
x20_bitOffset -= bitCount; /* Load in exact number of bytes remaining */
ret = baseVal & (x1c_val >> diff); auto loadDiv = std::div(-shiftAmt, 8);
x1c_val <<= bitCount; if (loadDiv.rem) ++loadDiv.quot;
readUBytesToBuf(reinterpret_cast<u8*>(&x1c_val) + 4 - loadDiv.quot, loadDiv.quot);
x1c_val = hecl::SBig(x1c_val);
/* New bit offset */
x20_bitOffset = loadDiv.quot * 8 + shiftAmt;
/* OR in next bits */
mask = (1 << -shiftAmt) - 1;
ret |= (x1c_val >> x20_bitOffset) & mask;
} }
else else
{ {
u32 diff = bitCount - x20_bitOffset; /* OR in bits of cached value */
u32 baseVal = -1; u32 mask = (1 << bitCount) - 1;
if (x20_bitOffset != 32) ret |= (x1c_val >> shiftAmt) & mask;
baseVal = (1 << x20_bitOffset) - 1;
baseVal = (baseVal & (x1c_val >> (32 - x20_bitOffset))) << diff; /* New bit offset */
x20_bitOffset = 0; x20_bitOffset -= bitCount;
auto pos = std::div(diff, 8);
if (pos.rem) ++pos.quot;
readUBytesToBuf(&x1c_val, pos.quot);
/* The game uses Big Endian, which doesn't work for us */
/* Little Endian sucks */
athena::utility::BigUint32(x1c_val);
u32 baseVal2 = -1;
if (diff != 32)
baseVal2 = (1 << diff) - 1;
ret = baseVal | (baseVal2 & (x1c_val >> (32 - diff))) << x20_bitOffset;
x20_bitOffset = (pos.quot << 3) - diff;
x1c_val <<= diff;
} }
#if DUMP_BITS
printf("READ ");
PrintBinary(ret, bitCount);
printf(" %d %d\n", int(pos), int(boff));
#endif
return ret; return ret;
} }
void CBitStreamWriter::WriteEncoded(u32 val, u32 bitCount) void CBitStreamWriter::WriteEncoded(u32 val, u32 bitCount)
{ {
if (x18_bitOffset >= bitCount) #if DUMP_BITS
printf("WRITE ");
PrintBinary(val, bitCount);
printf(" %d %d\n", int(position()), int(x18_bitOffset));
#endif
s32 shiftAmt = x18_bitOffset - s32(bitCount);
if (shiftAmt < 0)
{ {
int baseVal = -1; /* OR remaining bits to cached value */
if (bitCount != 32) u32 mask = (1 << x18_bitOffset) - 1;
baseVal = (1 << bitCount) - 1; x14_val |= (val >> -shiftAmt) & mask;
x14_val |= (val & baseVal) << (x18_bitOffset - bitCount);
x18_bitOffset -= bitCount; /* Write out 32-bits */
x14_val = hecl::SBig(x14_val);
writeUBytes(reinterpret_cast<u8*>(&x14_val), 4);
/* Cache remaining bits */
x18_bitOffset = 0x20 + shiftAmt;
x14_val = val << x18_bitOffset;
} }
else else
{ {
u32 diff = bitCount - x18_bitOffset; /* OR bits to cached value */
u32 baseVal = -1; u32 mask = (1 << bitCount) - 1;
if (x18_bitOffset != 32) x14_val |= (val & mask) << shiftAmt;
baseVal = (1 << x18_bitOffset) - 1;
x14_val |= (val >> diff) & baseVal; /* New bit offset */
x18_bitOffset = 0; x18_bitOffset -= bitCount;
u32 tmp = x14_val;
athena::utility::BigUint32(tmp);
auto pos = std::div(32 - x18_bitOffset, 8);
if (pos.rem) ++pos.quot;
writeBytes(&tmp, pos.quot);
u32 rem = 32 - diff;
baseVal = -1;
if (diff != 32)
baseVal = (1 << diff) - 1;
x14_val = (val & baseVal) << rem;
x18_bitOffset -= diff;
} }
} }
void CBitStreamWriter::Flush() void CBitStreamWriter::Flush()
{ {
if (x18_bitOffset && x18_bitOffset < 0x20) if (x18_bitOffset < 0x20)
{ {
u32 tmp = x14_val; auto pos = std::div(0x20 - x18_bitOffset, 8);
athena::utility::BigUint32(tmp);
auto pos = std::div(32 - x18_bitOffset, 8);
if (pos.rem) ++pos.quot; if (pos.rem) ++pos.quot;
writeBytes(&tmp, pos.quot); x14_val = hecl::SBig(x14_val);
x18_bitOffset = 32; writeUBytes(reinterpret_cast<u8*>(&x14_val), pos.quot);
x18_bitOffset = 0x20;
x14_val = 0; x14_val = 0;
} }
} }

View File

@ -31,38 +31,20 @@ public:
} }
CBitStreamReader(const void* data, atUint64 length) CBitStreamReader(const void* data, atUint64 length)
: MemoryReader(data, length) : MemoryReader(data, length) {}
{
}
atUint64 readUBytesToBuf(void *buf, atUint64 len)
{
x20_bitOffset = 0;
atUint64 tmp = MemoryReader::readUBytesToBuf(buf, len);
return tmp;
}
s32 ReadEncoded(u32 key); s32 ReadEncoded(u32 key);
}; };
class CBitStreamWriter : public athena::io::MemoryWriter class CBitStreamWriter : public athena::io::MemoryWriter
{ {
private:
u32 x14_val = 0; u32 x14_val = 0;
u32 x18_bitOffset = 32; u32 x18_bitOffset = 0x20;
public: public:
static inline u32 GetBitCount(u32 maxVal) { return CBitStreamReader::GetBitCount(maxVal); } static inline u32 GetBitCount(u32 maxVal) { return CBitStreamReader::GetBitCount(maxVal); }
CBitStreamWriter(atUint8* data = nullptr, atUint64 length=0x10) CBitStreamWriter(atUint8* data = nullptr, atUint64 length=0x10)
: MemoryWriter(data, length) : MemoryWriter(data, length) {}
{}
void writeUBytes(const atUint8 *data, atUint64 len)
{
x14_val = 0;
x18_bitOffset = 0x20;
MemoryWriter::writeUBytes(data, len);
}
void WriteEncoded(u32 val, u32 bitCount); void WriteEncoded(u32 val, u32 bitCount);

View File

@ -1754,7 +1754,9 @@ CFrontEndUI::CFrontEndUI()
xdc_saveUI = std::make_unique<CSaveUI>(ESaveContext::FrontEnd, g_GameState->GetCardSerial()); xdc_saveUI = std::make_unique<CSaveUI>(ESaveContext::FrontEnd, g_GameState->GetCardSerial());
m->ResetGameState(); m->ResetGameState();
g_GameState->SetCurrentWorldId(g_DefaultWorldTag.id); g_GameState->SetCurrentWorldId(g_ResFactory->TranslateOriginalToNew(g_DefaultWorldTag.id));
g_GameState->GameOptions().ResetToDefaults();
g_GameState->WriteBackupBuf();
for (int i=0 ; CDvdFile::FileExists(GetAttractMovieFileName(i).c_str()) ; ++i) for (int i=0 ; CDvdFile::FileExists(GetAttractMovieFileName(i).c_str()) ; ++i)
++xc0_attractCount; ++xc0_attractCount;

View File

@ -135,6 +135,7 @@ void CMemoryCardDriver::SGameFileSlot::InitializeFromGameState()
{ {
CBitStreamWriter w(x0_saveBuffer, 940); CBitStreamWriter w(x0_saveBuffer, 940);
g_GameState->PutTo(w); g_GameState->PutTo(w);
w.Flush();
x944_fileInfo = CGameState::LoadGameFileState(x0_saveBuffer); x944_fileInfo = CGameState::LoadGameFileState(x0_saveBuffer);
} }

View File

@ -46,6 +46,7 @@ CGameArchitectureSupport::CGameArchitectureSupport(CMain& parent, boo::IAudioVoi
CAudioSys::SetDefaultVolumeScale(0x75); CAudioSys::SetDefaultVolumeScale(0x75);
CAudioSys::SetVolumeScale(CAudioSys::GetDefaultVolumeScale()); CAudioSys::SetVolumeScale(CAudioSys::GetDefaultVolumeScale());
CStreamAudioManager::Initialize(); CStreamAudioManager::Initialize();
CStreamAudioManager::SetMusicVolume(0x7f);
m->ResetGameState(); m->ResetGameState();
//std::shared_ptr<CIOWin> splash = std::make_shared<CSplashScreen>(CSplashScreen::ESplashScreen::Nintendo); //std::shared_ptr<CIOWin> splash = std::make_shared<CSplashScreen>(CSplashScreen::ESplashScreen::Nintendo);
@ -276,6 +277,16 @@ bool CMain::Proc()
x164_archSupport->Update(); x164_archSupport->Update();
CSfxManager::Update(1.f / 60.f); CSfxManager::Update(1.f / 60.f);
CStreamAudioManager::Update(1.f / 60.f); CStreamAudioManager::Update(1.f / 60.f);
if (x164_archSupport->GetIOWinManager().IsEmpty() || CheckReset())
{
CStreamAudioManager::StopAll();
/*
x164_archSupport.reset();
g_archSupport = x164_archSupport.get();
x164_archSupport->PreloadAudio();
*/
x160_24_finished = true;
}
return x160_24_finished; return x160_24_finished;
} }

View File

@ -172,6 +172,8 @@ public:
m_rectIsDirty = false; m_rectIsDirty = false;
return m_windowRect; return m_windowRect;
} }
CIOWinManager& GetIOWinManager() { return x58_ioWinManager; }
}; };
#if MP1_USE_BOO #if MP1_USE_BOO
@ -261,7 +263,10 @@ public:
if (!memSys) if (!memSys)
memSys.reset(new CMemoryCardSys()); memSys.reset(new CMemoryCardSys());
if (memSys->InitializePump()) if (memSys->InitializePump())
{
g_MemoryCardSys = memSys.get(); g_MemoryCardSys = memSys.get();
g_GameState->InitializeMemoryStates();
}
} }
} }

2
amuse

@ -1 +1 @@
Subproject commit 2e7345f11d73219d77d345f3c7a039ab68be0e57 Subproject commit aff8880595b8a30130695f8a09428347d1f75939

2
nod

@ -1 +1 @@
Subproject commit e86971c9e082b58bb04ee794a106874b3ceae1c7 Subproject commit dc474ad1560e93f95d99d7577703387a859d7d26