Ticket #9070: endian4.patch

File endian4.patch, 22.0 KB (added by SF/nolange, 12 years ago)

use special byteswap instruction for PSP

  • common/endian.h

     
    2828
    2929#include "common/scummsys.h"
    3030
    31 //
    32 // Endian conversion functions, macros etc., follow from here!
    33 //
     31/**
     32 *  \file endian.h
     33 *  Endian conversion and byteswap conversion functions or macros
     34 *
     35 *  SWAP_BYTES_??(a)      - inverse byte order
     36 *  SWAP_CONSTANT_??(a)   - inverse byte order, implemented as macro.
     37 *                              Use with compiletime-constants only, the result will be a compiletime-constant aswell.
     38 *                              Unlike most other functions these can be used for eg. switch-case labels
     39 *
     40 *  READ_UINT??(a)        - read native value from pointer a
     41 *  READ_??_UINT??(a)     - read LE/BE value from pointer a and convert it to native
     42 *  WRITE_??_UINT??(a, v) - write native value v to pointer a with LE/BE encoding
     43 *  TO_??_??(a)           - convert native value v to LE/BE
     44 *  FROM_??_??(a)         - convert LE/BE value v to native
     45 *  CONSTANT_??_??(a)     - convert LE/BE value v to native, implemented as macro.
     46 *                              Use with compiletime-constants only, the result will be a compiletime-constant aswell.
     47 *                              Unlike most other functions these can be used for eg. switch-case labels
     48 */
    3449
     50// Sanity check
     51#if !defined(SCUMM_LITTLE_ENDIAN) && !defined(SCUMM_BIG_ENDIAN)
     52#       error No endianness defined
     53#endif
     54
     55#define SWAP_CONSTANT_32(a) \
     56        ((uint32)((((a) >> 24) & 0x00FF) | \
     57                  (((a) >>  8) & 0xFF00) | \
     58                  (((a) & 0xFF00) <<  8) | \
     59                  (((a) & 0x00FF) << 24) ))
     60
     61#define SWAP_CONSTANT_16(a) \
     62        ((uint16)((((a) >>  8) & 0x00FF) | \
     63                  (((a) <<  8) & 0xFF00) ))
     64
    3565/**
    3666 * Swap the bytes in a 32 bit word in order to convert LE encoded data to BE
    3767 * and vice versa.
    3868 */
    39 FORCEINLINE uint32 SWAP_BYTES_32(uint32 a) {
    40         return ((a >> 24) & 0x000000FF) |
    41                    ((a >>  8) & 0x0000FF00) |
    42                    ((a <<  8) & 0x00FF0000) |
    43                    ((a << 24) & 0xFF000000);
    44 }
    4569
     70// machine/compiler-specific variants come first, fallback last
     71
     72// Test for GCC and if the target has the MIPS rel.2 instructions (we know the psp does)
     73#if defined(__GNUC__) && (defined(__psp__) || defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2))
     74
     75        __attribute__((__always_inline__)) inline uint32 SWAP_BYTES_32(const uint32 a) {
     76                if (__builtin_constant_p(a)) {
     77                        return SWAP_CONSTANT_32(a);
     78                } else {
     79                        uint32 result;
     80#       if defined(__psp__)
     81                        // use special allegrex instruction
     82                        __asm__ ("wsbw %0,%1" : "=r" (result) : "r" (a));
     83#       else
     84                        __asm__ ("wsbh %0,%1\n"
     85                                 "rotr %0,%0,16" : "=r" (result) : "r" (a));
     86#       endif
     87                        return result;
     88                }
     89        }
     90
     91// Test for GCC >= 4.3.0 as this version added the bswap builtin
     92#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
     93
     94        __attribute__((__always_inline__)) inline uint32 SWAP_BYTES_32(uint32 a) {
     95                return __builtin_bswap32(a);
     96        }
     97
     98// test for MSVC 7 or newer
     99#elif defined(_MSC_VER) && _MSC_VER >= 1300
     100
     101        __forceinline uint32 SWAP_BYTES_32(uint32 a) {
     102                return _byteswap_ulong(a);
     103        }
     104
     105// generic fallback
     106#else
     107
     108        inline uint32 SWAP_BYTES_32(uint32 a) {
     109                const uint16 low = (uint16)a, high = (uint16)(a >> 16);
     110                return ((uint32)(uint16)((low >> 8) | (low << 8)) << 16)
     111                           | (uint16)((high >> 8) | (high << 8));
     112        }
     113#endif
     114
    46115/**
    47116 * Swap the bytes in a 16 bit word in order to convert LE encoded data to BE
    48117 * and vice versa.
    49118 */
    50 FORCEINLINE uint16 SWAP_BYTES_16(uint16 a) {
    51         return ((a >> 8) & 0x00FF) + ((a << 8) & 0xFF00);
    52 }
    53119
     120// compilerspecific variants come first, fallback last
    54121
     122// Test for GCC and if the target has the MIPS rel.2 instructions (we know the psp does)
     123#if defined(__GNUC__) && (defined(__psp__) || defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2))
     124
     125        __attribute__((__always_inline__)) inline uint16 SWAP_BYTES_16(const uint16 a) {
     126                if (__builtin_constant_p(a)) {
     127                        return SWAP_CONSTANT_16(a);
     128                } else {
     129                        uint16 result;
     130                        __asm__ ("wsbh %0,%1" : "=r" (result) : "r" (a));
     131                        return result;
     132                }
     133        }
     134#else
     135
     136        inline uint16 SWAP_BYTES_16(const uint16 a) {
     137                return (a >> 8) | (a << 8);
     138        }
     139#endif
     140
     141
    55142/**
    56143 * A wrapper macro used around four character constants, like 'DATA', to
    57144 * ensure portability. Typical usage: MKID_BE('DATA').
     
    70157 * For the latter systems we provide the INVERSE_MKID override.
    71158 */
    72159#if defined(INVERSE_MKID)
    73 #define MKID_BE(a) ((uint32) \
    74                 (((a) >> 24) & 0x000000FF) | \
    75                 (((a) >>  8) & 0x0000FF00) | \
    76                 (((a) <<  8) & 0x00FF0000) | \
    77                 (((a) << 24) & 0xFF000000))
     160#define MKID_BE(a) SWAP_CONSTANT_32(a)
    78161
    79162#else
    80163#  define MKID_BE(a) ((uint32)(a))
    81164#endif
    82165
     166// Functions for reading/writing native Integers,
     167// this transparently handles the need for alignment
    83168
     169#if !defined(SCUMM_NEED_ALIGNMENT)
    84170
     171        FORCEINLINE uint16 READ_UINT16(const void *ptr) {
     172                return *(const uint16 *)(ptr);
     173        }
     174
     175        FORCEINLINE uint32 READ_UINT32(const void *ptr) {
     176                return *(const uint32 *)(ptr);
     177        }
     178
     179        FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) {
     180                *(uint16 *)(ptr) = value;
     181        }
     182
     183        FORCEINLINE void WRITE_UINT32(void *ptr, uint32 value) {
     184                *(uint32 *)(ptr) = value;
     185        }
     186
     187// test for GCC >= 4.0. these implementations will automatically use CPU-specific
     188// instructions for unaligned data when they are available (eg. MIPS)
     189#elif defined(__GNUC__) && (__GNUC__ >= 4)
     190
     191        FORCEINLINE uint16 READ_UINT16(const void *ptr) {
     192                struct Unaligned16 { uint16 val; } __attribute__ ((__packed__));
     193                return ((const Unaligned16 *)ptr)->val;
     194        }
     195
     196        FORCEINLINE uint32 READ_UINT32(const void *ptr) {
     197                struct Unaligned32 { uint32 val; } __attribute__ ((__packed__));
     198                return ((const Unaligned32 *)ptr)->val;
     199        }
     200
     201        FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) {
     202                struct Unaligned16 { uint16 val; } __attribute__ ((__packed__));
     203                ((Unaligned16 *)ptr)->val = value;
     204        }
     205
     206        FORCEINLINE void WRITE_UINT32(void *ptr, uint32 value) {
     207                struct Unaligned32 { uint32 val; } __attribute__ ((__packed__));
     208                ((Unaligned32 *)ptr)->val = value;
     209        }
     210
     211// use software fallback by loading each byte explicitely
     212#else
     213
     214#       if defined(SCUMM_LITTLE_ENDIAN)
     215
     216                inline uint16 READ_UINT16(const void *ptr) {
     217                        const uint8 *b = (const uint8 *)ptr;
     218                        return (b[1] << 8) | b[0];
     219                }
     220                inline uint32 READ_UINT32(const void *ptr) {
     221                        const uint8 *b = (const uint8 *)ptr;
     222                        return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]);
     223                }
     224                inline void WRITE_UINT16(void *ptr, uint16 value) {
     225                        uint8 *b = (uint8 *)ptr;
     226                        b[0] = (uint8)(value >> 0);
     227                        b[1] = (uint8)(value >> 8);
     228                }
     229                inline void WRITE_UINT32(void *ptr, uint32 value) {
     230                        uint8 *b = (uint8 *)ptr;
     231                        b[0] = (uint8)(value >>  0);
     232                        b[1] = (uint8)(value >>  8);
     233                        b[2] = (uint8)(value >> 16);
     234                        b[3] = (uint8)(value >> 24);
     235                }
     236
     237#       elif defined(SCUMM_BIG_ENDIAN)
     238
     239                inline uint16 READ_UINT16(const void *ptr) {
     240                        const uint8 *b = (const uint8 *)ptr;
     241                        return (b[0] << 8) | b[1];
     242                }
     243                inline uint32 READ_UINT32(const void *ptr) {
     244                        const uint8 *b = (const uint8 *)ptr;
     245                        return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
     246                }
     247                inline void WRITE_UINT16(void *ptr, uint16 value) {
     248                        uint8 *b = (uint8 *)ptr;
     249                        b[0] = (uint8)(value >> 8);
     250                        b[1] = (uint8)(value >> 0);
     251                }
     252                inline void WRITE_UINT32(void *ptr, uint32 value) {
     253                        uint8 *b = (uint8 *)ptr;
     254                        b[0] = (uint8)(value >> 24);
     255                        b[1] = (uint8)(value >> 16);
     256                        b[2] = (uint8)(value >>  8);
     257                        b[3] = (uint8)(value >>  0);
     258                }
     259
     260#       endif
     261
     262#endif
     263
     264
     265//  Map Funtions for reading/writing BE/LE integers depending on native endianess
    85266#if defined(SCUMM_LITTLE_ENDIAN)
    86267
    87         #define READ_UINT16(a) READ_LE_UINT16(a)
    88         #define READ_UINT32(a) READ_LE_UINT32(a)
     268        #define READ_LE_UINT16(a) READ_UINT16(a)
     269        #define READ_LE_UINT32(a) READ_UINT32(a)
    89270
    90         #define WRITE_UINT16(a, v) WRITE_LE_UINT16(a, v)
    91         #define WRITE_UINT32(a, v) WRITE_LE_UINT32(a, v)
     271        #define WRITE_LE_UINT16(a, v) WRITE_UINT16(a, v)
     272        #define WRITE_LE_UINT32(a, v) WRITE_UINT32(a, v)
    92273
    93274        #define FROM_LE_32(a) ((uint32)(a))
    94275        #define FROM_LE_16(a) ((uint16)(a))
     
    102283        #define TO_BE_32(a) SWAP_BYTES_32(a)
    103284        #define TO_BE_16(a) SWAP_BYTES_16(a)
    104285
     286        #define CONSTANT_LE_32(a) ((uint32)(a))
     287        #define CONSTANT_LE_16(a) ((uint16)(a))
     288
     289        #define CONSTANT_BE_32(a) SWAP_CONSTANT_32(a)
     290        #define CONSTANT_BE_16(a) SWAP_CONSTANT_16(a)
     291
     292// if the unaligned load and the byteswap take alot instructions its better to directly read and invert
     293#       if defined(SCUMM_NEED_ALIGNMENT) && !defined(__mips__)
     294
     295                inline uint16 READ_BE_UINT16(const void *ptr) {
     296                        const uint8 *b = (const uint8 *)ptr;
     297                        return (b[0] << 8) | b[1];
     298                }
     299                inline uint32 READ_BE_UINT32(const void *ptr) {
     300                        const uint8 *b = (const uint8 *)ptr;
     301                        return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
     302                }
     303                inline void WRITE_BE_UINT16(void *ptr, uint16 value) {
     304                        uint8 *b = (uint8 *)ptr;
     305                        b[0] = (uint8)(value >> 8);
     306                        b[1] = (uint8)(value >> 0);
     307                }
     308                inline void WRITE_BE_UINT32(void *ptr, uint32 value) {
     309                        uint8 *b = (uint8 *)ptr;
     310                        b[0] = (uint8)(value >> 24);
     311                        b[1] = (uint8)(value >> 16);
     312                        b[2] = (uint8)(value >>  8);
     313                        b[3] = (uint8)(value >>  0);
     314                }
     315#       else
     316
     317                inline uint16 READ_BE_UINT16(const void *ptr) {
     318                        return SWAP_BYTES_16(READ_UINT16(ptr));
     319                }
     320                inline uint32 READ_BE_UINT32(const void *ptr) {
     321                        return SWAP_BYTES_32(READ_UINT32(ptr));
     322                }
     323                inline void WRITE_BE_UINT16(void *ptr, uint16 value) {
     324                        WRITE_UINT16(ptr, SWAP_BYTES_16(value));
     325                }
     326                inline void WRITE_BE_UINT32(void *ptr, uint32 value) {
     327                        WRITE_UINT32(ptr, SWAP_BYTES_32(value));
     328                }
     329       
     330#       endif   // if defined(SCUMM_NEED_ALIGNMENT)
     331
    105332#elif defined(SCUMM_BIG_ENDIAN)
    106333
     334        // I thought this would be compiler-specific and not dependent
     335        // on endianess after the comments above?
    107336        #define MKID(a) ((uint32)(a))
    108337        #define MKID_BE(a) ((uint32)(a))
    109338
    110         #define READ_UINT16(a) READ_BE_UINT16(a)
    111         #define READ_UINT32(a) READ_BE_UINT32(a)
     339        #define READ_BE_UINT16(a) READ_UINT16(a)
     340        #define READ_BE_UINT32(a) READ_UINT32(a)
    112341
    113         #define WRITE_UINT16(a, v) WRITE_BE_UINT16(a, v)
    114         #define WRITE_UINT32(a, v) WRITE_BE_UINT32(a, v)
     342        #define WRITE_BE_UINT16(a, v) WRITE_UINT16(a, v)
     343        #define WRITE_BE_UINT32(a, v) WRITE_UINT32(a, v)
    115344
    116345        #define FROM_LE_32(a) SWAP_BYTES_32(a)
    117346        #define FROM_LE_16(a) SWAP_BYTES_16(a)
     
    125354        #define TO_BE_32(a) ((uint32)(a))
    126355        #define TO_BE_16(a) ((uint16)(a))
    127356
    128 #else
     357        #define CONSTANT_LE_32(a) SWAP_CONSTANT_32(a)
     358        #define CONSTANT_LE_16(a) SWAP_CONSTANT_16(a)
    129359
    130         #error No endianness defined
     360        #define CONSTANT_BE_32(a) ((uint32)(a))
     361        #define CONSTANT_BE_16(a) ((uint16)(a))
    131362
     363// if the unaligned load and the byteswap take alot instructions its better to directly read and invert
     364#       if defined(SCUMM_NEED_ALIGNMENT) && !defined(__mips__)
    132365
    133 #endif
    134 
    135 
    136 #if defined(SCUMM_NEED_ALIGNMENT) || !defined(SCUMM_LITTLE_ENDIAN)
    137         FORCEINLINE uint16 READ_LE_UINT16(const void *ptr) {
    138                 const byte *b = (const byte *)ptr;
    139                 return (b[1] << 8) + b[0];
     366        inline uint16 READ_LE_UINT16(const void *ptr) {
     367                const uint8 *b = (const uint8 *)ptr;
     368                return (b[1] << 8) | b[0];
    140369        }
    141         FORCEINLINE uint32 READ_LE_UINT32(const void *ptr) {
    142                 const byte *b = (const byte *)ptr;
    143                 return (b[3] << 24) + (b[2] << 16) + (b[1] << 8) + (b[0]);
     370        inline uint32 READ_LE_UINT32(const void *ptr) {
     371                const uint8 *b = (const uint8 *)ptr;
     372                return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]);
    144373        }
    145         FORCEINLINE void WRITE_LE_UINT16(void *ptr, uint16 value) {
    146                 byte *b = (byte *)ptr;
    147                 b[0] = (byte)(value >> 0);
    148                 b[1] = (byte)(value >> 8);
     374        inline void WRITE_LE_UINT16(void *ptr, uint16 value) {
     375                uint8 *b = (uint8 *)ptr;
     376                b[0] = (uint8)(value >> 0);
     377                b[1] = (uint8)(value >> 8);
    149378        }
    150         FORCEINLINE void WRITE_LE_UINT32(void *ptr, uint32 value) {
    151                 byte *b = (byte *)ptr;
    152                 b[0] = (byte)(value >>  0);
    153                 b[1] = (byte)(value >>  8);
    154                 b[2] = (byte)(value >> 16);
    155                 b[3] = (byte)(value >> 24);
     379        inline void WRITE_LE_UINT32(void *ptr, uint32 value) {
     380                uint8 *b = (uint8 *)ptr;
     381                b[0] = (uint8)(value >>  0);
     382                b[1] = (uint8)(value >>  8);
     383                b[2] = (uint8)(value >> 16);
     384                b[3] = (uint8)(value >> 24);
    156385        }
    157 #else
    158         FORCEINLINE uint16 READ_LE_UINT16(const void *ptr) {
    159                 return *(const uint16 *)(ptr);
     386#       else
     387
     388        inline uint16 READ_LE_UINT16(const void *ptr) {
     389                return SWAP_BYTES_16(READ_UINT16(ptr));
    160390        }
    161         FORCEINLINE uint32 READ_LE_UINT32(const void *ptr) {
    162                 return *(const uint32 *)(ptr);
     391        inline uint32 READ_LE_UINT32(const void *ptr) {
     392                return SWAP_BYTES_32(READ_UINT32(ptr));
    163393        }
    164         FORCEINLINE void WRITE_LE_UINT16(void *ptr, uint16 value) {
    165                 *(uint16 *)(ptr) = value;
     394        inline void WRITE_LE_UINT16(void *ptr, uint16 value) {
     395                WRITE_UINT16(ptr, SWAP_BYTES_16(value));
    166396        }
    167         FORCEINLINE void WRITE_LE_UINT32(void *ptr, uint32 value) {
    168                 *(uint32 *)(ptr) = value;
     397        inline void WRITE_LE_UINT32(void *ptr, uint32 value) {
     398                WRITE_UINT32(ptr, SWAP_BYTES_32(value));
    169399        }
    170 #endif
     400       
     401#       endif   // if defined(SCUMM_NEED_ALIGNMENT)
    171402
     403#endif  // if defined(SCUMM_LITTLE_ENDIAN)
    172404
    173 #if defined(SCUMM_NEED_ALIGNMENT) || !defined(SCUMM_BIG_ENDIAN)
    174         FORCEINLINE uint16 READ_BE_UINT16(const void *ptr) {
    175                 const byte *b = (const byte *)ptr;
    176                 return (b[0] << 8) + b[1];
    177         }
    178         FORCEINLINE uint32 READ_BE_UINT32(const void *ptr) {
    179                 const byte *b = (const byte*)ptr;
    180                 return (b[0] << 24) + (b[1] << 16) + (b[2] << 8) + (b[3]);
    181         }
    182         FORCEINLINE void WRITE_BE_UINT16(void *ptr, uint16 value) {
    183                 byte *b = (byte *)ptr;
    184                 b[0] = (byte)(value >> 8);
    185                 b[1] = (byte)(value >> 0);
    186         }
    187         FORCEINLINE void WRITE_BE_UINT32(void *ptr, uint32 value) {
    188                 byte *b = (byte *)ptr;
    189                 b[0] = (byte)(value >> 24);
    190                 b[1] = (byte)(value >> 16);
    191                 b[2] = (byte)(value >>  8);
    192                 b[3] = (byte)(value >>  0);
    193         }
    194 #else
    195         FORCEINLINE uint16 READ_BE_UINT16(const void *ptr) {
    196                 return *(const uint16 *)(ptr);
    197         }
    198         FORCEINLINE uint32 READ_BE_UINT32(const void *ptr) {
    199                 return *(const uint32 *)(ptr);
    200         }
    201         FORCEINLINE void WRITE_BE_UINT16(void *ptr, uint16 value) {
    202                 *(uint16 *)(ptr) = value;
    203         }
    204         FORCEINLINE void WRITE_BE_UINT32(void *ptr, uint32 value) {
    205                 *(uint32 *)(ptr) = value;
    206         }
    207 #endif
    208 
    209 FORCEINLINE uint32 READ_LE_UINT24(const void *ptr) {
    210         const byte *b = (const byte *)ptr;
    211         return (b[2] << 16) + (b[1] << 8) + (b[0]);
     405inline uint32 READ_LE_UINT24(const void *ptr) {
     406        const uint8 *b = (const uint8 *)ptr;
     407        return (b[2] << 16) | (b[1] << 8) | (b[0]);
    212408}
    213409
    214 FORCEINLINE uint32 READ_BE_UINT24(const void *ptr) {
    215         const byte *b = (const byte*)ptr;
    216         return (b[0] << 16) + (b[1] << 8) + (b[2]);
     410inline uint32 READ_BE_UINT24(const void *ptr) {
     411        const uint8 *b = (const uint8 *)ptr;
     412        return (b[0] << 16) | (b[1] << 8) | (b[2]);
    217413}
    218414
    219 
    220415#endif
  • common/scummsys.h

     
    202202
    203203        #ifndef __GNUC__
    204204                #define FORCEINLINE __forceinline
    205                 #define NORETURN _declspec(noreturn)
     205                #define NORETURN __declspec(noreturn)
    206206        #endif
    207207        #define PLUGIN_EXPORT __declspec(dllexport)
    208208
     
    224224        #define SCUMM_LITTLE_ENDIAN
    225225
    226226        #define FORCEINLINE __forceinline
    227         #define NORETURN _declspec(noreturn)
     227        #define NORETURN __declspec(noreturn)
    228228        #define PLUGIN_EXPORT __declspec(dllexport)
    229229
    230230        typedef signed char int8_t;
     
    380380//
    381381#if defined(__GNUC__)
    382382        #define NORETURN __attribute__((__noreturn__))
    383         #define PACKED_STRUCT __attribute__((packed))
    384         #define GCC_PRINTF(x,y) __attribute__((format(printf, x, y)))
     383        #define PACKED_STRUCT __attribute__((__packed__))
     384        #define GCC_PRINTF(x,y) __attribute__((__format__(printf, x, y)))
     385
     386        #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
     387                #define FORCEINLINE __attribute__((__always_inline__)) inline
     388        #endif
    385389#else
    386390        #define PACKED_STRUCT
    387391        #define GCC_PRINTF(x,y)
  • common/stream.h

     
    2727#define COMMON_STREAM_H
    2828
    2929#include "common/scummsys.h"
     30#include "common/endian.h"
    3031
    3132namespace Common {
    3233
     
    106107        }
    107108
    108109        void writeUint16LE(uint16 value) {
    109                 writeByte((byte)(value & 0xff));
    110                 writeByte((byte)(value >> 8));
     110                value = TO_LE_16(value);
     111                write(&value, 2);
    111112        }
    112113
    113114        void writeUint32LE(uint32 value) {
    114                 writeUint16LE((uint16)(value & 0xffff));
    115                 writeUint16LE((uint16)(value >> 16));
     115                value = TO_LE_32(value);
     116                write(&value, 4);
    116117        }
    117118
    118119        void writeUint16BE(uint16 value) {
    119                 writeByte((byte)(value >> 8));
    120                 writeByte((byte)(value & 0xff));
     120                value = TO_BE_16(value);
     121                write(&value, 2);
    121122        }
    122123
    123124        void writeUint32BE(uint32 value) {
    124                 writeUint16BE((uint16)(value >> 16));
    125                 writeUint16BE((uint16)(value & 0xffff));
     125                value = TO_BE_32(value);
     126                write(&value, 4);
    126127        }
    127128
    128         void writeSint16LE(int16 value) {
     129        FORCEINLINE void writeSint16LE(int16 value) {
    129130                writeUint16LE((uint16)value);
    130131        }
    131132
    132         void writeSint32LE(int32 value) {
     133        FORCEINLINE void writeSint32LE(int32 value) {
    133134                writeUint32LE((uint32)value);
    134135        }
    135136
    136         void writeSint16BE(int16 value) {
     137        FORCEINLINE void writeSint16BE(int16 value) {
    137138                writeUint16BE((uint16)value);
    138139        }
    139140
    140         void writeSint32BE(int32 value) {
     141        FORCEINLINE void writeSint32BE(int32 value) {
    141142                writeUint32BE((uint32)value);
    142143        }
    143144
     
    188189         * calling err() and eos() ).
    189190         */
    190191        byte readByte() {
    191                 byte b = 0;
     192                byte b = 0; // FIXME: remove initialisation
    192193                read(&b, 1);
    193194                return b;
    194195        }
     
    199200         * if a read error occurred (for which client code can check by
    200201         * calling err() and eos() ).
    201202         */
    202         int8 readSByte() {
    203                 int8 b = 0;
    204                 read(&b, 1);
    205                 return b;
     203        FORCEINLINE int8 readSByte() {
     204                return (int8)readByte();
    206205        }
    207206
    208207        /**
     
    213212         * calling err() and eos() ).
    214213         */
    215214        uint16 readUint16LE() {
    216                 uint16 a = readByte();
    217                 uint16 b = readByte();
    218                 return a | (b << 8);
     215                uint16 val;
     216                read(&val, 2);
     217                return FROM_LE_16(val);
    219218        }
    220219
    221220        /**
     
    226225         * calling err() and eos() ).
    227226         */
    228227        uint32 readUint32LE() {
    229                 uint32 a = readUint16LE();
    230                 uint32 b = readUint16LE();
    231                 return (b << 16) | a;
     228                uint32 val;
     229                read(&val, 4);
     230                return FROM_LE_32(val);
    232231        }
    233232
    234233        /**
     
    239238         * calling err() and eos() ).
    240239         */
    241240        uint16 readUint16BE() {
    242                 uint16 b = readByte();
    243                 uint16 a = readByte();
    244                 return a | (b << 8);
     241                uint16 val;
     242                read(&val, 2);
     243                return FROM_BE_16(val);
    245244        }
    246245
    247246        /**
     
    252251         * calling err() and eos() ).
    253252         */
    254253        uint32 readUint32BE() {
    255                 uint32 b = readUint16BE();
    256                 uint32 a = readUint16BE();
    257                 return (b << 16) | a;
     254                uint32 val;
     255                read(&val, 4);
     256                return FROM_BE_32(val);
    258257        }
    259258
    260259        /**
     
    264263         * if a read error occurred (for which client code can check by
    265264         * calling err() and eos() ).
    266265         */
    267         int16 readSint16LE() {
     266        FORCEINLINE int16 readSint16LE() {
    268267                return (int16)readUint16LE();
    269268        }
    270269
     
    275274         * if a read error occurred (for which client code can check by
    276275         * calling err() and eos() ).
    277276         */
    278         int32 readSint32LE() {
     277        FORCEINLINE int32 readSint32LE() {
    279278                return (int32)readUint32LE();
    280279        }
    281280
     
    286285         * if a read error occurred (for which client code can check by
    287286         * calling err() and eos() ).
    288287         */
    289         int16 readSint16BE() {
     288        FORCEINLINE int16 readSint16BE() {
    290289                return (int16)readUint16BE();
    291290        }
    292291
     
    297296         * if a read error occurred (for which client code can check by
    298297         * calling err() and eos() ).
    299298         */
    300         int32 readSint32BE() {
     299        FORCEINLINE int32 readSint32BE() {
    301300                return (int32)readUint32BE();
    302301        }
    303302
     
    460459 * @see SubReadStream
    461460 */
    462461class SeekableSubReadStreamEndian : public SeekableSubReadStream {
     462private:
     463        const bool _bigEndian;
     464
    463465public:
    464         bool _bigEndian;
    465 
    466466        SeekableSubReadStreamEndian(SeekableReadStream *parentStream, uint32 begin, uint32 end, bool bigEndian = false, bool disposeParentStream = false)
    467467                : SeekableSubReadStream(parentStream, begin, end, disposeParentStream), _bigEndian(bigEndian) {
    468468        }
    469469
    470         inline uint16 readUint16() {
    471                 return (_bigEndian) ? readUint16BE() : readUint16LE();
     470        uint16 readUint16() {
     471                uint16 val;
     472                read(&val, 2);
     473                return (_bigEndian) ? TO_BE_16(val) : TO_LE_16(val);
    472474        }
    473475
    474         inline uint32 readUint32() {
    475                 return (_bigEndian) ? readUint32BE() : readUint32LE();
     476        uint32 readUint32() {
     477                uint32 val;
     478                read(&val, 4);
     479                return (_bigEndian) ? TO_BE_32(val) : TO_LE_32(val);
    476480        }
    477481
    478         inline int16 readSint16() {
     482        FORCEINLINE int16 readSint16() {
    479483                return (int16)readUint16();
    480484        }
    481485
    482         inline int32 readSint32() {
     486        FORCEINLINE int32 readSint32() {
    483487                return (int32)readUint32();
    484488        }
    485489};
     
    582586 */
    583587class MemoryReadStreamEndian : public Common::MemoryReadStream {
    584588private:
     589        const bool _bigEndian;
     590
    585591public:
    586         bool _bigEndian;
    587592        MemoryReadStreamEndian(const byte *buf, uint32 len, bool bigEndian = false) : MemoryReadStream(buf, len), _bigEndian(bigEndian) {}
    588593
    589         inline uint16 readUint16() {
    590                 return (_bigEndian) ? readUint16BE() : readUint16LE();
     594        uint16 readUint16() {
     595                uint16 val;
     596                read(&val, 2);
     597                return (_bigEndian) ? TO_BE_16(val) : TO_LE_16(val);
    591598        }
    592599
    593         inline uint32 readUint32() {
    594                 return (_bigEndian) ? readUint32BE() : readUint32LE();
     600        uint32 readUint32() {
     601                uint32 val;
     602                read(&val, 4);
     603                return (_bigEndian) ? TO_BE_32(val) : TO_LE_32(val);
    595604        }
    596605
    597         inline int16 readSint16() {
     606        FORCEINLINE int16 readSint16() {
    598607                return (int16)readUint16();
    599608        }
    600609
    601         inline int32 readSint32() {
     610        FORCEINLINE int32 readSint32() {
    602611                return (int32)readUint32();
    603612        }
    604613};
  • engines/saga/animation.cpp

     
    826826        int i;
    827827        bool longData = isLongData();
    828828
    829         MemoryReadStreamEndian readS(anim->resourceData, anim->resourceLength, _vm->isBigEndian());
     829        MemoryReadStreamEndian readS(anim->resourceData, anim->resourceLength, !_vm->isBigEndian()); // RLE has inversion BE<>LE
    830830
    831831        readS.seek(12);
    832832
    833         readS._bigEndian = !_vm->isBigEndian(); // RLE has inversion BE<>LE
    834 
    835833        while (readS.pos() != readS.size()) {
    836834                if (reallyFill) {
    837835                        anim->frameOffsets[currentFrame] = readS.pos();