CGameOptions: Eliminate type punning in CHintOptions constructor and PutTo()

Type punning with unions is undefined behavior.
This commit is contained in:
Lioncash 2020-04-03 02:14:28 -04:00
parent b122fd30a8
commit 4c6ab60110
1 changed files with 16 additions and 9 deletions

View File

@ -1,5 +1,7 @@
#include "Runtime/CGameOptions.hpp" #include "Runtime/CGameOptions.hpp"
#include <cstring>
#include "Runtime/CGameHintInfo.hpp" #include "Runtime/CGameHintInfo.hpp"
#include "Runtime/CGameState.hpp" #include "Runtime/CGameState.hpp"
#include "Runtime/CMemoryCardSys.hpp" #include "Runtime/CMemoryCardSys.hpp"
@ -522,18 +524,20 @@ CHintOptions::CHintOptions(CBitStreamReader& stream) {
x0_hintStates.reserve(hints.size()); x0_hintStates.reserve(hints.size());
u32 hintIdx = 0; u32 hintIdx = 0;
for (const auto& hint : hints) { for ([[maybe_unused]] const auto& hint : hints) {
(void)hint; const auto state = EHintState(stream.ReadEncoded(2));
EHintState state = EHintState(stream.ReadEncoded(2)); const s32 timeBits = stream.ReadEncoded(32);
union { s32 i; float f; } timeBits = {stream.ReadEncoded(32)}; float time;
float time = timeBits.f; std::memcpy(&time, &timeBits, sizeof(s32));
if (state == EHintState::Zero) if (state == EHintState::Zero) {
time = 0.f; time = 0.f;
}
x0_hintStates.emplace_back(state, time, false); x0_hintStates.emplace_back(state, time, false);
if (x10_nextHintIdx == -1 && state == EHintState::Displaying) if (x10_nextHintIdx == -1 && state == EHintState::Displaying) {
x10_nextHintIdx = hintIdx; x10_nextHintIdx = hintIdx;
}
++hintIdx; ++hintIdx;
} }
} }
@ -541,8 +545,11 @@ CHintOptions::CHintOptions(CBitStreamReader& stream) {
void CHintOptions::PutTo(CBitStreamWriter& writer) const { void CHintOptions::PutTo(CBitStreamWriter& writer) const {
for (const SHintState& hint : x0_hintStates) { for (const SHintState& hint : x0_hintStates) {
writer.WriteEncoded(u32(hint.x0_state), 2); writer.WriteEncoded(u32(hint.x0_state), 2);
union { float f; u32 i; } timeBits = {hint.x4_time};
writer.WriteEncoded(timeBits.i, 32); u32 timeBits;
std::memcpy(&timeBits, &hint.x4_time, sizeof(timeBits));
writer.WriteEncoded(timeBits, 32);
} }
} }