mirror of
https://github.com/isledecomp/isle-portable.git
synced 2025-09-23 03:55:44 -04:00
Handle unaligned read/write (#82)
This commit is contained in:
parent
d5b5148cd5
commit
3a0366a3d9
@ -119,7 +119,8 @@ void LegoEntity::SetWorld()
|
||||
{
|
||||
LegoWorld* world = CurrentWorld();
|
||||
|
||||
if (world != NULL && world != (LegoWorld*) this) {
|
||||
LegoWorld* maybeWorld = dynamic_cast<LegoWorld*>(this);
|
||||
if (world != NULL && world != maybeWorld) {
|
||||
world->Add(this);
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ public:
|
||||
~MxAssignedDevice();
|
||||
|
||||
unsigned int GetFlags() { return m_flags; }
|
||||
BOOL GetHardwareMode() { return ((int) m_flags << 31) >> 31; }
|
||||
BOOL GetHardwareMode() { return (m_flags & 1) != 0; }
|
||||
D3DDEVICEDESC& GetDesc() { return m_desc; }
|
||||
|
||||
friend class MxDirect3D;
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "decomp.h"
|
||||
#include "mxcore.h"
|
||||
#include "mxtypes.h"
|
||||
#include "mxutilities.h"
|
||||
|
||||
#define DS_CHUNK_BIT1 0x01
|
||||
#define DS_CHUNK_END_OF_STREAM 0x02
|
||||
@ -37,7 +38,10 @@ public:
|
||||
static MxU32 GetHeaderSize();
|
||||
|
||||
// FUNCTION: BETA10 0x101641f0
|
||||
static MxU32 Size(MxU8* p_buffer) { return (*(MxU32*) (p_buffer + 4) & 1) + *(MxU32*) (p_buffer + 4) + 8; }
|
||||
static MxU32 Size(MxU8* p_buffer)
|
||||
{
|
||||
return (UnalignedRead<MxU32>(p_buffer + 4) & 1) + UnalignedRead<MxU32>(p_buffer + 4) + 8;
|
||||
}
|
||||
|
||||
// FUNCTION: BETA10 0x10164220
|
||||
static MxU8* End(MxU8* p_buffer) { return p_buffer + Size(p_buffer); }
|
||||
|
@ -29,6 +29,14 @@ inline T Max(T p_t1, T p_t2)
|
||||
return p_t1 > p_t2 ? p_t1 : p_t2;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T UnalignedRead(MxU8* p_source)
|
||||
{
|
||||
T value;
|
||||
memcpy(&value, p_source, sizeof(T));
|
||||
return value;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void GetScalar(MxU8*& p_source, T& p_dest)
|
||||
{
|
||||
|
@ -261,21 +261,21 @@ void MxDSAction::Deserialize(MxU8*& p_source, MxS16 p_flags)
|
||||
MxDSObject::Deserialize(p_source, p_flags);
|
||||
|
||||
// clang-format off
|
||||
m_flags = *( MxU32*) p_source; p_source += sizeof(m_flags);
|
||||
m_startTime = *(MxLong*) p_source; p_source += sizeof(m_startTime);
|
||||
m_duration = *(MxLong*) p_source; p_source += sizeof(m_duration);
|
||||
m_loopCount = *( MxS32*) p_source; p_source += sizeof(m_loopCount);
|
||||
m_location[0] = *(double*) p_source; p_source += sizeof(double);
|
||||
m_location[1] = *(double*) p_source; p_source += sizeof(double);
|
||||
m_location[2] = *(double*) p_source; p_source += sizeof(double);
|
||||
m_direction[0] = *(double*) p_source; p_source += sizeof(double);
|
||||
m_direction[1] = *(double*) p_source; p_source += sizeof(double);
|
||||
m_direction[2] = *(double*) p_source; p_source += sizeof(double);
|
||||
m_up[0] = *(double*) p_source; p_source += sizeof(double);
|
||||
m_up[1] = *(double*) p_source; p_source += sizeof(double);
|
||||
m_up[2] = *(double*) p_source; p_source += sizeof(double);
|
||||
m_flags = UnalignedRead<MxU32>(p_source); p_source += sizeof(MxU32);
|
||||
m_startTime = UnalignedRead<MxLong>(p_source); p_source += sizeof(MxLong);
|
||||
m_duration = UnalignedRead<MxLong>(p_source); p_source += sizeof(MxLong);
|
||||
m_loopCount = UnalignedRead<MxS32>(p_source); p_source += sizeof(MxS32);
|
||||
m_location[0] = UnalignedRead<double>(p_source); p_source += sizeof(double);
|
||||
m_location[1] = UnalignedRead<double>(p_source); p_source += sizeof(double);
|
||||
m_location[2] = UnalignedRead<double>(p_source); p_source += sizeof(double);
|
||||
m_direction[0] = UnalignedRead<double>(p_source); p_source += sizeof(double);
|
||||
m_direction[1] = UnalignedRead<double>(p_source); p_source += sizeof(double);
|
||||
m_direction[2] = UnalignedRead<double>(p_source); p_source += sizeof(double);
|
||||
m_up[0] = UnalignedRead<double>(p_source); p_source += sizeof(double);
|
||||
m_up[1] = UnalignedRead<double>(p_source); p_source += sizeof(double);
|
||||
m_up[2] = UnalignedRead<double>(p_source); p_source += sizeof(double);
|
||||
|
||||
MxU16 extraLength = *( MxU16*) p_source; p_source += sizeof(extraLength);
|
||||
MxU16 extraLength = UnalignedRead<MxU16>(p_source); p_source += sizeof(extraLength);
|
||||
// clang-format on
|
||||
|
||||
if (extraLength) {
|
||||
|
@ -137,12 +137,12 @@ void MxDSMediaAction::Deserialize(MxU8*& p_source, MxS16 p_flags)
|
||||
p_source += strlen(m_mediaSrcPath) + 1;
|
||||
|
||||
// clang-format off
|
||||
m_unk0x9c.SetUnk0x00(*(MxU32*) p_source); p_source += sizeof(m_unk0x9c.m_unk0x00);
|
||||
m_unk0x9c.SetUnk0x04(*(MxU32*) p_source); p_source += sizeof(m_unk0x9c.m_unk0x04);
|
||||
m_unk0x9c.SetUnk0x00(UnalignedRead<MxU32>(p_source)); p_source += sizeof(MxU32);
|
||||
m_unk0x9c.SetUnk0x04(UnalignedRead<MxU32>(p_source)); p_source += sizeof(MxU32);
|
||||
|
||||
m_framesPerSecond = *(MxS32*) p_source; p_source += sizeof(m_framesPerSecond);
|
||||
m_mediaFormat = *(MxS32*) p_source; p_source += sizeof(m_mediaFormat);
|
||||
m_paletteManagement = *(MxS32*) p_source; p_source += sizeof(m_paletteManagement);
|
||||
m_sustainTime = *(MxS32*) p_source; p_source += sizeof(m_sustainTime);
|
||||
m_framesPerSecond = UnalignedRead<MxS32>(p_source); p_source += sizeof(MxS32);
|
||||
m_mediaFormat = UnalignedRead<MxS32>(p_source); p_source += sizeof(MxS32);
|
||||
m_paletteManagement = UnalignedRead<MxS32>(p_source); p_source += sizeof(MxS32);
|
||||
m_sustainTime = UnalignedRead<MxS32>(p_source); p_source += sizeof(MxS32);
|
||||
// clang-format on
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "mxdsmultiaction.h"
|
||||
|
||||
#include "mxutilities.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
DECOMP_SIZE_ASSERT(MxDSMultiAction, 0x9c)
|
||||
@ -153,15 +155,15 @@ void MxDSMultiAction::Deserialize(MxU8*& p_source, MxS16 p_flags)
|
||||
{
|
||||
MxDSAction::Deserialize(p_source, p_flags);
|
||||
|
||||
MxU32 extraFlag = *(MxU32*) (p_source + 4) & 1;
|
||||
MxU32 extraFlag = UnalignedRead<MxU32>(p_source + 4) & 1;
|
||||
p_source += 12;
|
||||
|
||||
MxU32 count = *(MxU32*) p_source;
|
||||
MxU32 count = UnalignedRead<MxU32>(p_source);
|
||||
p_source += sizeof(count);
|
||||
|
||||
if (count) {
|
||||
while (count--) {
|
||||
MxU32 extraFlag = *(MxU32*) (p_source + 4) & 1;
|
||||
MxU32 extraFlag = UnalignedRead<MxU32>(p_source + 4) & 1;
|
||||
p_source += 8;
|
||||
|
||||
MxDSAction* action = (MxDSAction*) DeserializeDSObjectDispatch(p_source, p_flags);
|
||||
|
@ -161,13 +161,13 @@ void MxDSObject::Deserialize(MxU8*& p_source, MxS16 p_flags)
|
||||
SetSourceName((char*) p_source);
|
||||
p_source += strlen(m_sourceName) + 1;
|
||||
|
||||
m_unk0x14 = *(undefined4*) p_source;
|
||||
m_unk0x14 = UnalignedRead<undefined4>(p_source);
|
||||
p_source += sizeof(m_unk0x14);
|
||||
|
||||
SetObjectName((char*) p_source);
|
||||
p_source += strlen(m_objectName) + 1;
|
||||
|
||||
m_objectId = *(MxU32*) p_source;
|
||||
m_objectId = UnalignedRead<MxU32>(p_source);
|
||||
p_source += sizeof(m_objectId);
|
||||
|
||||
m_unk0x24 = p_flags;
|
||||
@ -211,7 +211,7 @@ MxDSObject* DeserializeDSObjectDispatch(MxU8*& p_source, MxS16 p_flags)
|
||||
{
|
||||
MxDSObject* obj = NULL;
|
||||
|
||||
MxU16 type = *(MxU16*) p_source;
|
||||
MxU16 type = UnalignedRead<MxU16>(p_source);
|
||||
p_source += 2;
|
||||
|
||||
switch (type) {
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "mxdssound.h"
|
||||
|
||||
#include "mxutilities.h"
|
||||
|
||||
DECOMP_SIZE_ASSERT(MxDSSound, 0xc0)
|
||||
|
||||
// FUNCTION: LEGO1 0x100c92c0
|
||||
@ -61,7 +63,7 @@ MxDSAction* MxDSSound::Clone()
|
||||
void MxDSSound::Deserialize(MxU8*& p_source, MxS16 p_flags)
|
||||
{
|
||||
MxDSMediaAction::Deserialize(p_source, p_flags);
|
||||
m_volume = *(MxS32*) p_source;
|
||||
m_volume = UnalignedRead<MxS32>(p_source);
|
||||
p_source += sizeof(m_volume);
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "mxstreamcontroller.h"
|
||||
#include "mxstreamer.h"
|
||||
#include "mxstreamprovider.h"
|
||||
#include "mxutilities.h"
|
||||
|
||||
DECOMP_SIZE_ASSERT(MxDSBuffer, 0x34);
|
||||
|
||||
@ -177,11 +178,11 @@ MxResult MxDSBuffer::CreateObject(
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (*p_data == FOURCC('M', 'x', 'O', 'b')) {
|
||||
if (UnalignedRead<MxU32>((MxU8*) p_data) == FOURCC('M', 'x', 'O', 'b')) {
|
||||
MxDSAction* action = (MxDSAction*) header;
|
||||
return StartPresenterFromAction(p_controller, p_action, action);
|
||||
}
|
||||
else if (*p_data == FOURCC('M', 'x', 'C', 'h')) {
|
||||
else if (UnalignedRead<MxU32>((MxU8*) p_data) == FOURCC('M', 'x', 'C', 'h')) {
|
||||
MxStreamChunk* chunk = (MxStreamChunk*) header;
|
||||
if (!m_unk0x30->HasId((chunk)->GetObjectId())) {
|
||||
delete header;
|
||||
@ -326,7 +327,7 @@ MxCore* MxDSBuffer::ReadChunk(MxDSBuffer* p_buffer, MxU32* p_chunkData, MxU16 p_
|
||||
MxCore* result = NULL;
|
||||
MxU8* dataStart = (MxU8*) p_chunkData + 8;
|
||||
|
||||
switch (*p_chunkData) {
|
||||
switch (UnalignedRead<MxU32>((MxU8*) p_chunkData)) {
|
||||
case FOURCC('M', 'x', 'O', 'b'): {
|
||||
MxDSObject* obj = DeserializeDSObjectDispatch(dataStart, p_flags);
|
||||
result = obj;
|
||||
@ -355,11 +356,12 @@ MxU8* MxDSBuffer::SkipToData()
|
||||
|
||||
if (m_pIntoBuffer != NULL) {
|
||||
while (TRUE) {
|
||||
switch (*(MxU32*) m_pIntoBuffer) {
|
||||
switch (UnalignedRead<MxU32>(m_pIntoBuffer)) {
|
||||
case FOURCC('M', 'x', 'O', 'b'):
|
||||
case FOURCC('M', 'x', 'C', 'h'):
|
||||
result = m_pIntoBuffer;
|
||||
m_pIntoBuffer += (*(MxU32*) (m_pIntoBuffer + 4) & 1) + *(MxU32*) (m_pIntoBuffer + 4);
|
||||
m_pIntoBuffer +=
|
||||
(UnalignedRead<MxU32>(m_pIntoBuffer + 4) & 1) + UnalignedRead<MxU32>(m_pIntoBuffer + 4);
|
||||
m_pIntoBuffer += 8;
|
||||
|
||||
if (m_pBuffer + m_writeOffset - 8 < m_pIntoBuffer) {
|
||||
@ -372,7 +374,7 @@ MxU8* MxDSBuffer::SkipToData()
|
||||
m_pIntoBuffer += 8;
|
||||
break;
|
||||
case FOURCC('M', 'x', 'H', 'd'):
|
||||
m_pIntoBuffer += *(MxU32*) (m_pIntoBuffer + 4) + 8;
|
||||
m_pIntoBuffer += UnalignedRead<MxU32>(m_pIntoBuffer + 4) + 8;
|
||||
break;
|
||||
case FOURCC('L', 'I', 'S', 'T'):
|
||||
case FOURCC('R', 'I', 'F', 'F'):
|
||||
@ -424,7 +426,7 @@ MxResult MxDSBuffer::CalcBytesRemaining(MxU8* p_data)
|
||||
|
||||
if (m_writeOffset == m_bytesRemaining) {
|
||||
ptr = p_data;
|
||||
bytesRead = *(MxU32*) (p_data + 4) + 8;
|
||||
bytesRead = UnalignedRead<MxU32>(p_data + 4) + 8;
|
||||
}
|
||||
else {
|
||||
ptr = p_data + MxStreamChunk::GetHeaderSize() + 8;
|
||||
@ -435,7 +437,9 @@ MxResult MxDSBuffer::CalcBytesRemaining(MxU8* p_data)
|
||||
memcpy(m_pBuffer + m_writeOffset - m_bytesRemaining, ptr, bytesRead);
|
||||
|
||||
if (m_writeOffset == m_bytesRemaining) {
|
||||
*(MxU32*) (m_pBuffer + 4) = *MxStreamChunk::IntoLength(m_pBuffer) + MxStreamChunk::GetHeaderSize();
|
||||
MxU32 length =
|
||||
UnalignedRead<MxU32>((MxU8*) MxStreamChunk::IntoLength(m_pBuffer)) + MxStreamChunk::GetHeaderSize();
|
||||
memcpy(m_pBuffer + 4, &length, sizeof(length));
|
||||
}
|
||||
|
||||
m_bytesRemaining -= bytesRead;
|
||||
@ -462,7 +466,7 @@ MxU8* MxDSBuffer::FUN_100c6fa0(MxU8* p_data)
|
||||
MxU8* end = m_writeOffset + m_pBuffer - 8;
|
||||
|
||||
while (current <= end) {
|
||||
switch (*((MxU32*) current)) {
|
||||
switch (UnalignedRead<MxU32>(current)) {
|
||||
case FOURCC('L', 'I', 'S', 'T'):
|
||||
case FOURCC('R', 'I', 'F', 'F'):
|
||||
current += 12;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "mxdsfile.h"
|
||||
#include "mxomni.h"
|
||||
#include "mxstreamcontroller.h"
|
||||
#include "mxutilities.h"
|
||||
|
||||
DECOMP_SIZE_ASSERT(MxStreamProvider, 0x10)
|
||||
DECOMP_SIZE_ASSERT(MxRAMStreamProvider, 0x24)
|
||||
@ -109,10 +110,8 @@ MxU32 ReadData(MxU8* p_buffer, MxU32 p_size)
|
||||
MxU8* data = p_buffer;
|
||||
MxU8* data2;
|
||||
|
||||
#define IntoType(p) ((MxU32*) (p))
|
||||
|
||||
while (data < p_buffer + p_size) {
|
||||
if (*IntoType(data) == FOURCC('M', 'x', 'O', 'b')) {
|
||||
if (data + sizeof(MxU32) <= p_buffer + p_size && UnalignedRead<MxU32>(data) == FOURCC('M', 'x', 'O', 'b')) {
|
||||
data2 = data;
|
||||
data = data2 + 8;
|
||||
|
||||
@ -122,11 +121,11 @@ MxU32 ReadData(MxU8* p_buffer, MxU32 p_size)
|
||||
|
||||
data = MxDSChunk::End(data2);
|
||||
while (data < p_buffer + p_size) {
|
||||
if (*IntoType(data) == FOURCC('M', 'x', 'C', 'h')) {
|
||||
if (UnalignedRead<MxU32>(data) == FOURCC('M', 'x', 'C', 'h')) {
|
||||
MxU8* data3 = data;
|
||||
data = MxDSChunk::End(data3);
|
||||
|
||||
if ((*IntoType(data2) == FOURCC('M', 'x', 'C', 'h')) &&
|
||||
if ((UnalignedRead<MxU32>(data2) == FOURCC('M', 'x', 'C', 'h')) &&
|
||||
(*MxStreamChunk::IntoFlags(data2) & DS_CHUNK_SPLIT)) {
|
||||
if (*MxStreamChunk::IntoObjectId(data2) == *MxStreamChunk::IntoObjectId(data3) &&
|
||||
(*MxStreamChunk::IntoFlags(data3) & DS_CHUNK_SPLIT) &&
|
||||
@ -142,7 +141,7 @@ MxU32 ReadData(MxU8* p_buffer, MxU32 p_size)
|
||||
data2 = MxDSChunk::End(data2);
|
||||
memmove(data2, data3, MxDSChunk::Size(data3));
|
||||
|
||||
if (*MxStreamChunk::IntoObjectId(data2) == id &&
|
||||
if (UnalignedRead<MxU32>((MxU8*) MxStreamChunk::IntoObjectId(data2)) == id &&
|
||||
(*MxStreamChunk::IntoFlags(data2) & DS_CHUNK_END_OF_STREAM)) {
|
||||
break;
|
||||
}
|
||||
@ -159,6 +158,4 @@ MxU32 ReadData(MxU8* p_buffer, MxU32 p_size)
|
||||
|
||||
*MxStreamChunk::IntoFlags(data2) &= ~DS_CHUNK_SPLIT;
|
||||
return MxDSChunk::Size(data2) + (MxU32) (data2 - p_buffer);
|
||||
|
||||
#undef IntoType
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ MxResult MxStreamChunk::ReadChunk(MxDSBuffer* p_buffer, MxU8* p_chunkData)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
|
||||
if (p_chunkData != NULL && *(MxU32*) p_chunkData == FOURCC('M', 'x', 'C', 'h')) {
|
||||
if (p_chunkData != NULL && UnalignedRead<MxU32>(p_chunkData) == FOURCC('M', 'x', 'C', 'h')) {
|
||||
if (ReadChunkHeader(p_chunkData + 8)) {
|
||||
if (p_buffer) {
|
||||
SetBuffer(p_buffer);
|
||||
|
Loading…
x
Reference in New Issue
Block a user