From 101150832582bba15d463ba27e60cb9f0d65a437 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Fri, 11 Sep 2009 08:55:47 +0000 Subject: Slightly modified version of Patch #2838562: Improve endian.h and stream.h svn-id: r44027 --- common/endian.h | 394 +++++++++++++++++++++++++++++++++------------ common/scummsys.h | 12 +- common/stream.h | 105 ++++++------ engines/saga/animation.cpp | 4 +- 4 files changed, 359 insertions(+), 156 deletions(-) diff --git a/common/endian.h b/common/endian.h index c889371a2f..badf57b1dc 100644 --- a/common/endian.h +++ b/common/endian.h @@ -28,28 +28,115 @@ #include "common/scummsys.h" -// -// Endian conversion functions, macros etc., follow from here! -// +/** + * \file endian.h + * Endian conversion and byteswap conversion functions or macros + * + * SWAP_BYTES_??(a) - inverse byte order + * SWAP_CONSTANT_??(a) - inverse byte order, implemented as macro. + * Use with compiletime-constants only, the result will be a compiletime-constant aswell. + * Unlike most other functions these can be used for eg. switch-case labels + * + * READ_UINT??(a) - read native value from pointer a + * READ_??_UINT??(a) - read LE/BE value from pointer a and convert it to native + * WRITE_??_UINT??(a, v) - write native value v to pointer a with LE/BE encoding + * TO_??_??(a) - convert native value v to LE/BE + * FROM_??_??(a) - convert LE/BE value v to native + * CONSTANT_??_??(a) - convert LE/BE value v to native, implemented as macro. + * Use with compiletime-constants only, the result will be a compiletime-constant aswell. + * Unlike most other functions these can be used for eg. switch-case labels + */ + +// Sanity check +#if !defined(SCUMM_LITTLE_ENDIAN) && !defined(SCUMM_BIG_ENDIAN) +# error No endianness defined +#endif + +#define SWAP_CONSTANT_32(a) \ + ((uint32)((((a) >> 24) & 0x00FF) | \ + (((a) >> 8) & 0xFF00) | \ + (((a) & 0xFF00) << 8) | \ + (((a) & 0x00FF) << 24) )) + +#define SWAP_CONSTANT_16(a) \ + ((uint16)((((a) >> 8) & 0x00FF) | \ + (((a) << 8) & 0xFF00) )) /** * Swap the bytes in a 32 bit word in order to convert LE encoded data to BE * and vice versa. */ -FORCEINLINE uint32 SWAP_BYTES_32(uint32 a) { - return ((a >> 24) & 0x000000FF) | - ((a >> 8) & 0x0000FF00) | - ((a << 8) & 0x00FF0000) | - ((a << 24) & 0xFF000000); -} + +// machine/compiler-specific variants come first, fallback last + +// Test for GCC and if the target has the MIPS rel.2 instructions (we know the psp does) +#if defined(__GNUC__) && (defined(__psp__) || defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)) + + FORCEINLINE uint32 SWAP_BYTES_32(const uint32 a) { + if (__builtin_constant_p(a)) { + return SWAP_CONSTANT_32(a); + } else { + uint32 result; +# if defined(__psp__) + // use special allegrex instruction + __asm__ ("wsbw %0,%1" : "=r" (result) : "r" (a)); +# else + __asm__ ("wsbh %0,%1\n" + "rotr %0,%0,16" : "=r" (result) : "r" (a)); +# endif + return result; + } + } + +// Test for GCC >= 4.3.0 as this version added the bswap builtin +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + + FORCEINLINE uint32 SWAP_BYTES_32(uint32 a) { + return __builtin_bswap32(a); + } + +// test for MSVC 7 or newer +#elif defined(_MSC_VER) && _MSC_VER >= 1300 + + FORCEINLINE uint32 SWAP_BYTES_32(uint32 a) { + return _byteswap_ulong(a); + } + +// generic fallback +#else + + inline uint32 SWAP_BYTES_32(uint32 a) { + const uint16 low = (uint16)a, high = (uint16)(a >> 16); + return ((uint32)(uint16)((low >> 8) | (low << 8)) << 16) + | (uint16)((high >> 8) | (high << 8)); + } +#endif /** * Swap the bytes in a 16 bit word in order to convert LE encoded data to BE * and vice versa. */ -FORCEINLINE uint16 SWAP_BYTES_16(uint16 a) { - return ((a >> 8) & 0x00FF) + ((a << 8) & 0xFF00); -} + +// compilerspecific variants come first, fallback last + +// Test for GCC and if the target has the MIPS rel.2 instructions (we know the psp does) +#if defined(__GNUC__) && (defined(__psp__) || defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)) + + FORCEINLINE uint16 SWAP_BYTES_16(const uint16 a) { + if (__builtin_constant_p(a)) { + return SWAP_CONSTANT_16(a); + } else { + uint16 result; + __asm__ ("wsbh %0,%1" : "=r" (result) : "r" (a)); + return result; + } + } +#else + + inline uint16 SWAP_BYTES_16(const uint16 a) { + return (a >> 8) | (a << 8); + } +#endif /** @@ -70,25 +157,119 @@ FORCEINLINE uint16 SWAP_BYTES_16(uint16 a) { * For the latter systems we provide the INVERSE_MKID override. */ #if defined(INVERSE_MKID) -#define MKID_BE(a) ((uint32) \ - (((a) >> 24) & 0x000000FF) | \ - (((a) >> 8) & 0x0000FF00) | \ - (((a) << 8) & 0x00FF0000) | \ - (((a) << 24) & 0xFF000000)) +#define MKID_BE(a) SWAP_CONSTANT_32(a) #else # define MKID_BE(a) ((uint32)(a)) #endif +// Functions for reading/writing native Integers, +// this transparently handles the need for alignment + +#if !defined(SCUMM_NEED_ALIGNMENT) + + FORCEINLINE uint16 READ_UINT16(const void *ptr) { + return *(const uint16 *)(ptr); + } + + FORCEINLINE uint32 READ_UINT32(const void *ptr) { + return *(const uint32 *)(ptr); + } + + FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) { + *(uint16 *)(ptr) = value; + } + + FORCEINLINE void WRITE_UINT32(void *ptr, uint32 value) { + *(uint32 *)(ptr) = value; + } +// test for GCC >= 4.0. these implementations will automatically use CPU-specific +// instructions for unaligned data when they are available (eg. MIPS) +#elif defined(__GNUC__) && (__GNUC__ >= 4) + FORCEINLINE uint16 READ_UINT16(const void *ptr) { + struct Unaligned16 { uint16 val; } __attribute__ ((__packed__)); + return ((const Unaligned16 *)ptr)->val; + } + + FORCEINLINE uint32 READ_UINT32(const void *ptr) { + struct Unaligned32 { uint32 val; } __attribute__ ((__packed__)); + return ((const Unaligned32 *)ptr)->val; + } + + FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) { + struct Unaligned16 { uint16 val; } __attribute__ ((__packed__)); + ((Unaligned16 *)ptr)->val = value; + } + + FORCEINLINE void WRITE_UINT32(void *ptr, uint32 value) { + struct Unaligned32 { uint32 val; } __attribute__ ((__packed__)); + ((Unaligned32 *)ptr)->val = value; + } + +// use software fallback by loading each byte explicitely +#else + +# if defined(SCUMM_LITTLE_ENDIAN) + + inline uint16 READ_UINT16(const void *ptr) { + const uint8 *b = (const uint8 *)ptr; + return (b[1] << 8) | b[0]; + } + inline uint32 READ_UINT32(const void *ptr) { + const uint8 *b = (const uint8 *)ptr; + return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]); + } + inline void WRITE_UINT16(void *ptr, uint16 value) { + uint8 *b = (uint8 *)ptr; + b[0] = (uint8)(value >> 0); + b[1] = (uint8)(value >> 8); + } + inline void WRITE_UINT32(void *ptr, uint32 value) { + uint8 *b = (uint8 *)ptr; + b[0] = (uint8)(value >> 0); + b[1] = (uint8)(value >> 8); + b[2] = (uint8)(value >> 16); + b[3] = (uint8)(value >> 24); + } + +# elif defined(SCUMM_BIG_ENDIAN) + + inline uint16 READ_UINT16(const void *ptr) { + const uint8 *b = (const uint8 *)ptr; + return (b[0] << 8) | b[1]; + } + inline uint32 READ_UINT32(const void *ptr) { + const uint8 *b = (const uint8 *)ptr; + return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]); + } + inline void WRITE_UINT16(void *ptr, uint16 value) { + uint8 *b = (uint8 *)ptr; + b[0] = (uint8)(value >> 8); + b[1] = (uint8)(value >> 0); + } + inline void WRITE_UINT32(void *ptr, uint32 value) { + uint8 *b = (uint8 *)ptr; + b[0] = (uint8)(value >> 24); + b[1] = (uint8)(value >> 16); + b[2] = (uint8)(value >> 8); + b[3] = (uint8)(value >> 0); + } + +# endif + +#endif + + +// Map Funtions for reading/writing BE/LE integers depending on native endianess #if defined(SCUMM_LITTLE_ENDIAN) - #define READ_UINT16(a) READ_LE_UINT16(a) - #define READ_UINT32(a) READ_LE_UINT32(a) + #define READ_LE_UINT16(a) READ_UINT16(a) + #define READ_LE_UINT32(a) READ_UINT32(a) - #define WRITE_UINT16(a, v) WRITE_LE_UINT16(a, v) - #define WRITE_UINT32(a, v) WRITE_LE_UINT32(a, v) + #define WRITE_LE_UINT16(a, v) WRITE_UINT16(a, v) + #define WRITE_LE_UINT32(a, v) WRITE_UINT32(a, v) #define FROM_LE_32(a) ((uint32)(a)) #define FROM_LE_16(a) ((uint16)(a)) @@ -102,16 +283,61 @@ FORCEINLINE uint16 SWAP_BYTES_16(uint16 a) { #define TO_BE_32(a) SWAP_BYTES_32(a) #define TO_BE_16(a) SWAP_BYTES_16(a) + #define CONSTANT_LE_32(a) ((uint32)(a)) + #define CONSTANT_LE_16(a) ((uint16)(a)) + + #define CONSTANT_BE_32(a) SWAP_CONSTANT_32(a) + #define CONSTANT_BE_16(a) SWAP_CONSTANT_16(a) + +// if the unaligned load and the byteswap take alot instructions its better to directly read and invert +# if defined(SCUMM_NEED_ALIGNMENT) && !defined(__mips__) + + inline uint16 READ_BE_UINT16(const void *ptr) { + const uint8 *b = (const uint8 *)ptr; + return (b[0] << 8) | b[1]; + } + inline uint32 READ_BE_UINT32(const void *ptr) { + const uint8 *b = (const uint8 *)ptr; + return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]); + } + inline void WRITE_BE_UINT16(void *ptr, uint16 value) { + uint8 *b = (uint8 *)ptr; + b[0] = (uint8)(value >> 8); + b[1] = (uint8)(value >> 0); + } + inline void WRITE_BE_UINT32(void *ptr, uint32 value) { + uint8 *b = (uint8 *)ptr; + b[0] = (uint8)(value >> 24); + b[1] = (uint8)(value >> 16); + b[2] = (uint8)(value >> 8); + b[3] = (uint8)(value >> 0); + } +# else + + inline uint16 READ_BE_UINT16(const void *ptr) { + return SWAP_BYTES_16(READ_UINT16(ptr)); + } + inline uint32 READ_BE_UINT32(const void *ptr) { + return SWAP_BYTES_32(READ_UINT32(ptr)); + } + inline void WRITE_BE_UINT16(void *ptr, uint16 value) { + WRITE_UINT16(ptr, SWAP_BYTES_16(value)); + } + inline void WRITE_BE_UINT32(void *ptr, uint32 value) { + WRITE_UINT32(ptr, SWAP_BYTES_32(value)); + } + +# endif // if defined(SCUMM_NEED_ALIGNMENT) + #elif defined(SCUMM_BIG_ENDIAN) - #define MKID(a) ((uint32)(a)) #define MKID_BE(a) ((uint32)(a)) - #define READ_UINT16(a) READ_BE_UINT16(a) - #define READ_UINT32(a) READ_BE_UINT32(a) + #define READ_BE_UINT16(a) READ_UINT16(a) + #define READ_BE_UINT32(a) READ_UINT32(a) - #define WRITE_UINT16(a, v) WRITE_BE_UINT16(a, v) - #define WRITE_UINT32(a, v) WRITE_BE_UINT32(a, v) + #define WRITE_BE_UINT16(a, v) WRITE_UINT16(a, v) + #define WRITE_BE_UINT32(a, v) WRITE_UINT32(a, v) #define FROM_LE_32(a) SWAP_BYTES_32(a) #define FROM_LE_16(a) SWAP_BYTES_16(a) @@ -125,96 +351,62 @@ FORCEINLINE uint16 SWAP_BYTES_16(uint16 a) { #define TO_BE_32(a) ((uint32)(a)) #define TO_BE_16(a) ((uint16)(a)) -#else - - #error No endianness defined - + #define CONSTANT_LE_32(a) SWAP_CONSTANT_32(a) + #define CONSTANT_LE_16(a) SWAP_CONSTANT_16(a) -#endif + #define CONSTANT_BE_32(a) ((uint32)(a)) + #define CONSTANT_BE_16(a) ((uint16)(a)) +// if the unaligned load and the byteswap take alot instructions its better to directly read and invert +# if defined(SCUMM_NEED_ALIGNMENT) && !defined(__mips__) -#if defined(SCUMM_NEED_ALIGNMENT) || !defined(SCUMM_LITTLE_ENDIAN) - FORCEINLINE uint16 READ_LE_UINT16(const void *ptr) { - const byte *b = (const byte *)ptr; - return (b[1] << 8) + b[0]; - } - FORCEINLINE uint32 READ_LE_UINT32(const void *ptr) { - const byte *b = (const byte *)ptr; - return (b[3] << 24) + (b[2] << 16) + (b[1] << 8) + (b[0]); - } - FORCEINLINE void WRITE_LE_UINT16(void *ptr, uint16 value) { - byte *b = (byte *)ptr; - b[0] = (byte)(value >> 0); - b[1] = (byte)(value >> 8); + inline uint16 READ_LE_UINT16(const void *ptr) { + const uint8 *b = (const uint8 *)ptr; + return (b[1] << 8) | b[0]; } - FORCEINLINE void WRITE_LE_UINT32(void *ptr, uint32 value) { - byte *b = (byte *)ptr; - b[0] = (byte)(value >> 0); - b[1] = (byte)(value >> 8); - b[2] = (byte)(value >> 16); - b[3] = (byte)(value >> 24); + inline uint32 READ_LE_UINT32(const void *ptr) { + const uint8 *b = (const uint8 *)ptr; + return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]); } -#else - FORCEINLINE uint16 READ_LE_UINT16(const void *ptr) { - return *(const uint16 *)(ptr); - } - FORCEINLINE uint32 READ_LE_UINT32(const void *ptr) { - return *(const uint32 *)(ptr); + inline void WRITE_LE_UINT16(void *ptr, uint16 value) { + uint8 *b = (uint8 *)ptr; + b[0] = (uint8)(value >> 0); + b[1] = (uint8)(value >> 8); } - FORCEINLINE void WRITE_LE_UINT16(void *ptr, uint16 value) { - *(uint16 *)(ptr) = value; + inline void WRITE_LE_UINT32(void *ptr, uint32 value) { + uint8 *b = (uint8 *)ptr; + b[0] = (uint8)(value >> 0); + b[1] = (uint8)(value >> 8); + b[2] = (uint8)(value >> 16); + b[3] = (uint8)(value >> 24); } - FORCEINLINE void WRITE_LE_UINT32(void *ptr, uint32 value) { - *(uint32 *)(ptr) = value; - } -#endif - +# else -#if defined(SCUMM_NEED_ALIGNMENT) || !defined(SCUMM_BIG_ENDIAN) - FORCEINLINE uint16 READ_BE_UINT16(const void *ptr) { - const byte *b = (const byte *)ptr; - return (b[0] << 8) + b[1]; + inline uint16 READ_LE_UINT16(const void *ptr) { + return SWAP_BYTES_16(READ_UINT16(ptr)); } - FORCEINLINE uint32 READ_BE_UINT32(const void *ptr) { - const byte *b = (const byte*)ptr; - return (b[0] << 24) + (b[1] << 16) + (b[2] << 8) + (b[3]); + inline uint32 READ_LE_UINT32(const void *ptr) { + return SWAP_BYTES_32(READ_UINT32(ptr)); } - FORCEINLINE void WRITE_BE_UINT16(void *ptr, uint16 value) { - byte *b = (byte *)ptr; - b[0] = (byte)(value >> 8); - b[1] = (byte)(value >> 0); + inline void WRITE_LE_UINT16(void *ptr, uint16 value) { + WRITE_UINT16(ptr, SWAP_BYTES_16(value)); } - FORCEINLINE void WRITE_BE_UINT32(void *ptr, uint32 value) { - byte *b = (byte *)ptr; - b[0] = (byte)(value >> 24); - b[1] = (byte)(value >> 16); - b[2] = (byte)(value >> 8); - b[3] = (byte)(value >> 0); + inline void WRITE_LE_UINT32(void *ptr, uint32 value) { + WRITE_UINT32(ptr, SWAP_BYTES_32(value)); } -#else - FORCEINLINE uint16 READ_BE_UINT16(const void *ptr) { - return *(const uint16 *)(ptr); - } - FORCEINLINE uint32 READ_BE_UINT32(const void *ptr) { - return *(const uint32 *)(ptr); - } - FORCEINLINE void WRITE_BE_UINT16(void *ptr, uint16 value) { - *(uint16 *)(ptr) = value; - } - FORCEINLINE void WRITE_BE_UINT32(void *ptr, uint32 value) { - *(uint32 *)(ptr) = value; - } -#endif + +# endif // if defined(SCUMM_NEED_ALIGNMENT) -FORCEINLINE uint32 READ_LE_UINT24(const void *ptr) { - const byte *b = (const byte *)ptr; - return (b[2] << 16) + (b[1] << 8) + (b[0]); -} +#endif // if defined(SCUMM_LITTLE_ENDIAN) -FORCEINLINE uint32 READ_BE_UINT24(const void *ptr) { - const byte *b = (const byte*)ptr; - return (b[0] << 16) + (b[1] << 8) + (b[2]); +inline uint32 READ_LE_UINT24(const void *ptr) { + const uint8 *b = (const uint8 *)ptr; + return (b[2] << 16) | (b[1] << 8) | (b[0]); } +inline uint32 READ_BE_UINT24(const void *ptr) { + const uint8 *b = (const uint8 *)ptr; + return (b[0] << 16) | (b[1] << 8) | (b[2]); +} #endif diff --git a/common/scummsys.h b/common/scummsys.h index a9c5fb3266..bdb11344bc 100644 --- a/common/scummsys.h +++ b/common/scummsys.h @@ -202,7 +202,7 @@ #ifndef __GNUC__ #define FORCEINLINE __forceinline - #define NORETURN _declspec(noreturn) + #define NORETURN __declspec(noreturn) #endif #define PLUGIN_EXPORT __declspec(dllexport) @@ -224,7 +224,7 @@ #define SCUMM_LITTLE_ENDIAN #define FORCEINLINE __forceinline - #define NORETURN _declspec(noreturn) + #define NORETURN __declspec(noreturn) #define PLUGIN_EXPORT __declspec(dllexport) typedef signed char int8_t; @@ -380,8 +380,12 @@ // #if defined(__GNUC__) #define NORETURN __attribute__((__noreturn__)) - #define PACKED_STRUCT __attribute__((packed)) - #define GCC_PRINTF(x,y) __attribute__((format(printf, x, y))) + #define PACKED_STRUCT __attribute__((__packed__)) + #define GCC_PRINTF(x,y) __attribute__((__format__(printf, x, y))) + + #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) + #define FORCEINLINE __attribute__((__always_inline__)) inline + #endif #else #define PACKED_STRUCT #define GCC_PRINTF(x,y) diff --git a/common/stream.h b/common/stream.h index 6b127e6086..edc1c3e35a 100644 --- a/common/stream.h +++ b/common/stream.h @@ -27,6 +27,7 @@ #define COMMON_STREAM_H #include "common/scummsys.h" +#include "common/endian.h" namespace Common { @@ -106,38 +107,38 @@ public: } void writeUint16LE(uint16 value) { - writeByte((byte)(value & 0xff)); - writeByte((byte)(value >> 8)); + value = TO_LE_16(value); + write(&value, 2); } void writeUint32LE(uint32 value) { - writeUint16LE((uint16)(value & 0xffff)); - writeUint16LE((uint16)(value >> 16)); + value = TO_LE_32(value); + write(&value, 4); } void writeUint16BE(uint16 value) { - writeByte((byte)(value >> 8)); - writeByte((byte)(value & 0xff)); + value = TO_BE_16(value); + write(&value, 2); } void writeUint32BE(uint32 value) { - writeUint16BE((uint16)(value >> 16)); - writeUint16BE((uint16)(value & 0xffff)); + value = TO_BE_32(value); + write(&value, 4); } - void writeSint16LE(int16 value) { + FORCEINLINE void writeSint16LE(int16 value) { writeUint16LE((uint16)value); } - void writeSint32LE(int32 value) { + FORCEINLINE void writeSint32LE(int32 value) { writeUint32LE((uint32)value); } - void writeSint16BE(int16 value) { + FORCEINLINE void writeSint16BE(int16 value) { writeUint16BE((uint16)value); } - void writeSint32BE(int32 value) { + FORCEINLINE void writeSint32BE(int32 value) { writeUint32BE((uint32)value); } @@ -188,7 +189,7 @@ public: * calling err() and eos() ). */ byte readByte() { - byte b = 0; + byte b = 0; // FIXME: remove initialisation read(&b, 1); return b; } @@ -199,10 +200,8 @@ public: * if a read error occurred (for which client code can check by * calling err() and eos() ). */ - int8 readSByte() { - int8 b = 0; - read(&b, 1); - return b; + FORCEINLINE int8 readSByte() { + return (int8)readByte(); } /** @@ -213,9 +212,9 @@ public: * calling err() and eos() ). */ uint16 readUint16LE() { - uint16 a = readByte(); - uint16 b = readByte(); - return a | (b << 8); + uint16 val; + read(&val, 2); + return FROM_LE_16(val); } /** @@ -226,9 +225,9 @@ public: * calling err() and eos() ). */ uint32 readUint32LE() { - uint32 a = readUint16LE(); - uint32 b = readUint16LE(); - return (b << 16) | a; + uint32 val; + read(&val, 4); + return FROM_LE_32(val); } /** @@ -239,9 +238,9 @@ public: * calling err() and eos() ). */ uint16 readUint16BE() { - uint16 b = readByte(); - uint16 a = readByte(); - return a | (b << 8); + uint16 val; + read(&val, 2); + return FROM_BE_16(val); } /** @@ -252,9 +251,9 @@ public: * calling err() and eos() ). */ uint32 readUint32BE() { - uint32 b = readUint16BE(); - uint32 a = readUint16BE(); - return (b << 16) | a; + uint32 val; + read(&val, 4); + return FROM_BE_32(val); } /** @@ -264,7 +263,7 @@ public: * if a read error occurred (for which client code can check by * calling err() and eos() ). */ - int16 readSint16LE() { + FORCEINLINE int16 readSint16LE() { return (int16)readUint16LE(); } @@ -275,7 +274,7 @@ public: * if a read error occurred (for which client code can check by * calling err() and eos() ). */ - int32 readSint32LE() { + FORCEINLINE int32 readSint32LE() { return (int32)readUint32LE(); } @@ -286,7 +285,7 @@ public: * if a read error occurred (for which client code can check by * calling err() and eos() ). */ - int16 readSint16BE() { + FORCEINLINE int16 readSint16BE() { return (int16)readUint16BE(); } @@ -297,7 +296,7 @@ public: * if a read error occurred (for which client code can check by * calling err() and eos() ). */ - int32 readSint32BE() { + FORCEINLINE int32 readSint32BE() { return (int32)readUint32BE(); } @@ -460,26 +459,31 @@ public: * @see SubReadStream */ class SeekableSubReadStreamEndian : public SeekableSubReadStream { -public: - bool _bigEndian; +private: + const bool _bigEndian; +public: SeekableSubReadStreamEndian(SeekableReadStream *parentStream, uint32 begin, uint32 end, bool bigEndian = false, bool disposeParentStream = false) : SeekableSubReadStream(parentStream, begin, end, disposeParentStream), _bigEndian(bigEndian) { } - inline uint16 readUint16() { - return (_bigEndian) ? readUint16BE() : readUint16LE(); + uint16 readUint16() { + uint16 val; + read(&val, 2); + return (_bigEndian) ? TO_BE_16(val) : TO_LE_16(val); } - inline uint32 readUint32() { - return (_bigEndian) ? readUint32BE() : readUint32LE(); + uint32 readUint32() { + uint32 val; + read(&val, 4); + return (_bigEndian) ? TO_BE_32(val) : TO_LE_32(val); } - inline int16 readSint16() { + FORCEINLINE int16 readSint16() { return (int16)readUint16(); } - inline int32 readSint32() { + FORCEINLINE int32 readSint32() { return (int32)readUint32(); } }; @@ -582,23 +586,28 @@ public: */ class MemoryReadStreamEndian : public Common::MemoryReadStream { private: + const bool _bigEndian; + public: - bool _bigEndian; MemoryReadStreamEndian(const byte *buf, uint32 len, bool bigEndian = false) : MemoryReadStream(buf, len), _bigEndian(bigEndian) {} - inline uint16 readUint16() { - return (_bigEndian) ? readUint16BE() : readUint16LE(); + uint16 readUint16() { + uint16 val; + read(&val, 2); + return (_bigEndian) ? TO_BE_16(val) : TO_LE_16(val); } - inline uint32 readUint32() { - return (_bigEndian) ? readUint32BE() : readUint32LE(); + uint32 readUint32() { + uint32 val; + read(&val, 4); + return (_bigEndian) ? TO_BE_32(val) : TO_LE_32(val); } - inline int16 readSint16() { + FORCEINLINE int16 readSint16() { return (int16)readUint16(); } - inline int32 readSint32() { + FORCEINLINE int32 readSint32() { return (int32)readUint32(); } }; diff --git a/engines/saga/animation.cpp b/engines/saga/animation.cpp index 0d298bf96a..95a850cfe2 100644 --- a/engines/saga/animation.cpp +++ b/engines/saga/animation.cpp @@ -826,12 +826,10 @@ int Anim::fillFrameOffsets(AnimationData *anim, bool reallyFill) { int i; bool longData = isLongData(); - MemoryReadStreamEndian readS(anim->resourceData, anim->resourceLength, _vm->isBigEndian()); + MemoryReadStreamEndian readS(anim->resourceData, anim->resourceLength, !_vm->isBigEndian()); // RLE has inversion BE<>LE readS.seek(12); - readS._bigEndian = !_vm->isBigEndian(); // RLE has inversion BE<>LE - while (readS.pos() != readS.size()) { if (reallyFill) { anim->frameOffsets[currentFrame] = readS.pos(); -- cgit v1.2.3