[Scummvm-cvs-logs] SF.net SVN: scummvm:[44027] scummvm/trunk

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Fri Sep 11 10:55:47 CEST 2009


Revision: 44027
          http://scummvm.svn.sourceforge.net/scummvm/?rev=44027&view=rev
Author:   fingolfin
Date:     2009-09-11 08:55:47 +0000 (Fri, 11 Sep 2009)

Log Message:
-----------
Slightly modified version of Patch #2838562: Improve endian.h and stream.h

Modified Paths:
--------------
    scummvm/trunk/common/endian.h
    scummvm/trunk/common/scummsys.h
    scummvm/trunk/common/stream.h
    scummvm/trunk/engines/saga/animation.cpp

Modified: scummvm/trunk/common/endian.h
===================================================================
--- scummvm/trunk/common/endian.h	2009-09-11 08:43:32 UTC (rev 44026)
+++ scummvm/trunk/common/endian.h	2009-09-11 08:55:47 UTC (rev 44027)
@@ -28,30 +28,117 @@
 
 #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
+
+
 /**
  * A wrapper macro used around four character constants, like 'DATA', to
  * ensure portability. Typical usage: MKID_BE('DATA').
@@ -70,25 +157,119 @@
  * 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 @@
 	#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 @@
 	#define TO_BE_32(a) ((uint32)(a))
 	#define TO_BE_16(a) ((uint16)(a))
 
-#else
+	#define CONSTANT_LE_32(a) SWAP_CONSTANT_32(a)
+	#define CONSTANT_LE_16(a) SWAP_CONSTANT_16(a)
 
-	#error No endianness defined
+	#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__)
 
-#endif
-
-
-#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];
+	inline uint16 READ_LE_UINT16(const void *ptr) {
+		const uint8 *b = (const uint8 *)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]);
+	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]);
 	}
-	FORCEINLINE void WRITE_LE_UINT16(void *ptr, uint16 value) {
-		byte *b = (byte *)ptr;
-		b[0] = (byte)(value >> 0);
-		b[1] = (byte)(value >> 8);
+	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_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 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);
 	}
-#else
-	FORCEINLINE uint16 READ_LE_UINT16(const void *ptr) {
-		return *(const uint16 *)(ptr);
+#	else
+
+	inline uint16 READ_LE_UINT16(const void *ptr) {
+		return SWAP_BYTES_16(READ_UINT16(ptr));
 	}
-	FORCEINLINE uint32 READ_LE_UINT32(const void *ptr) {
-		return *(const uint32 *)(ptr);
+	inline uint32 READ_LE_UINT32(const void *ptr) {
+		return SWAP_BYTES_32(READ_UINT32(ptr));
 	}
-	FORCEINLINE void WRITE_LE_UINT16(void *ptr, uint16 value) {
-		*(uint16 *)(ptr) = value;
+	inline void WRITE_LE_UINT16(void *ptr, uint16 value) {
+		WRITE_UINT16(ptr, SWAP_BYTES_16(value));
 	}
-	FORCEINLINE void WRITE_LE_UINT32(void *ptr, uint32 value) {
-		*(uint32 *)(ptr) = value;
+	inline void WRITE_LE_UINT32(void *ptr, uint32 value) {
+		WRITE_UINT32(ptr, SWAP_BYTES_32(value));
 	}
-#endif
+	
+#	endif	// if defined(SCUMM_NEED_ALIGNMENT)
 
+#endif	// if defined(SCUMM_LITTLE_ENDIAN)
 
-#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];
-	}
-	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]);
-	}
-	FORCEINLINE void WRITE_BE_UINT16(void *ptr, uint16 value) {
-		byte *b = (byte *)ptr;
-		b[0] = (byte)(value >> 8);
-		b[1] = (byte)(value >> 0);
-	}
-	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);
-	}
-#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
-
-FORCEINLINE uint32 READ_LE_UINT24(const void *ptr) {
-	const byte *b = (const byte *)ptr;
-	return (b[2] << 16) + (b[1] << 8) + (b[0]);
+inline uint32 READ_LE_UINT24(const void *ptr) {
+	const uint8 *b = (const uint8 *)ptr;
+	return (b[2] << 16) | (b[1] << 8) | (b[0]);
 }
 
-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_BE_UINT24(const void *ptr) {
+	const uint8 *b = (const uint8 *)ptr;
+	return (b[0] << 16) | (b[1] << 8) | (b[2]);
 }
 
-
 #endif

Modified: scummvm/trunk/common/scummsys.h
===================================================================
--- scummvm/trunk/common/scummsys.h	2009-09-11 08:43:32 UTC (rev 44026)
+++ scummvm/trunk/common/scummsys.h	2009-09-11 08:55:47 UTC (rev 44027)
@@ -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)

Modified: scummvm/trunk/common/stream.h
===================================================================
--- scummvm/trunk/common/stream.h	2009-09-11 08:43:32 UTC (rev 44026)
+++ scummvm/trunk/common/stream.h	2009-09-11 08:55:47 UTC (rev 44027)
@@ -27,6 +27,7 @@
 #define COMMON_STREAM_H
 
 #include "common/scummsys.h"
+#include "common/endian.h"
 
 namespace Common {
 
@@ -106,38 +107,38 @@
 	}
 
 	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 @@
 	 * calling err() and eos() ).
 	 */
 	byte readByte() {
-		byte b = 0;
+		byte b = 0; // FIXME: remove initialisation
 		read(&b, 1);
 		return b;
 	}
@@ -199,10 +200,8 @@
 	 * 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 @@
 	 * 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 @@
 	 * 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 @@
 	 * 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 @@
 	 * 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 @@
 	 * 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 @@
 	 * 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 @@
 	 * 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 @@
 	 * 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 @@
  * @see SubReadStream
  */
 class SeekableSubReadStreamEndian : public SeekableSubReadStream {
+private:
+	const bool _bigEndian;
+
 public:
-	bool _bigEndian;
-
 	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 @@
  */
 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();
 	}
 };

Modified: scummvm/trunk/engines/saga/animation.cpp
===================================================================
--- scummvm/trunk/engines/saga/animation.cpp	2009-09-11 08:43:32 UTC (rev 44026)
+++ scummvm/trunk/engines/saga/animation.cpp	2009-09-11 08:55:47 UTC (rev 44027)
@@ -826,12 +826,10 @@
 	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();


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list