Ticket #9070: endian2.patch

File endian2.patch, 20.4 KB (added by SF/nolange, 15 years ago)

add special support for PSP and CONSTANT functions

  • 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        FORCEINLINE 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                        __asm__ ("wsbh %0,%1\n"
     81                                 "rotr %0,%0,16" : "=r" (result) : "r" (a));
     82                        return result;
     83                }
     84        }
     85
     86// Test for GCC >= 4.3.0 as this version added the bswap builtin
     87#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
     88
     89        FORCEINLINE uint32 SWAP_BYTES_32(uint32 a) {
     90                return __builtin_bswap32(a);
     91        }
     92
     93// test for MSVC 7 or newer
     94#elif defined(_MSC_VER) && _MSC_VER >= 1300
     95
     96        FORCEINLINE uint32 SWAP_BYTES_32(uint32 a) {
     97                return _byteswap_ulong(a);
     98        }
     99
     100// generic fallback
     101#else
     102
     103        inline uint32 SWAP_BYTES_32(uint32 a) {
     104                const uint16 low = (uint16)a, high = (uint16)(a >> 16);
     105                return ((uint32)(uint16)((low >> 8) | (low << 8)) << 16)
     106                           | (uint16)((high >> 8) | (high << 8));
     107        }
     108#endif
     109
    46110/**
    47111 * Swap the bytes in a 16 bit word in order to convert LE encoded data to BE
    48112 * and vice versa.
    49113 */
    50 FORCEINLINE uint16 SWAP_BYTES_16(uint16 a) {
    51         return ((a >> 8) & 0x00FF) + ((a << 8) & 0xFF00);
    52 }
    53114
     115// compilerspecific variants come first, fallback last
    54116
     117// Test for GCC and if the target has the MIPS rel.2 instructions (we know the psp does)
     118#if defined(__GNUC__) && (defined(__psp__) || defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2))
     119        FORCEINLINE uint16 SWAP_BYTES_16(const uint16 a) {
     120                if (__builtin_constant_p(a)) {
     121                        return SWAP_CONSTANT_16(a);
     122                } else {
     123                        uint16 result;
     124                        __asm__ ("wsbh %0,%1" : "=r" (result) : "r" (a));
     125                        return result;
     126                }
     127        }
     128#else
     129        FORCEINLINE uint16 SWAP_BYTES_16(const uint16 a) {
     130                return (a >> 8) | (a << 8);
     131        }
     132#endif
     133
     134
    55135/**
    56136 * A wrapper macro used around four character constants, like 'DATA', to
    57137 * ensure portability. Typical usage: MKID_BE('DATA').
     
    70150 * For the latter systems we provide the INVERSE_MKID override.
    71151 */
    72152#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))
     153#define MKID_BE(a) SWAP_CONSTANT_32(a)
    78154
    79155#else
    80156#  define MKID_BE(a) ((uint32)(a))
    81157#endif
    82158
     159// Functions for reading/writing native Integers,
     160// this transparently handles the need for alignment
    83161
     162#if !defined(SCUMM_NEED_ALIGNMENT)
    84163
     164        FORCEINLINE uint16 READ_UINT16(const void *ptr) {
     165                return *(const uint16 *)(ptr);
     166        }
     167
     168        FORCEINLINE uint32 READ_UINT32(const void *ptr) {
     169                return *(const uint32 *)(ptr);
     170        }
     171
     172        FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) {
     173                *(uint16 *)(ptr) = value;
     174        }
     175
     176        FORCEINLINE void WRITE_UINT32(void *ptr, uint32 value) {
     177                *(uint32 *)(ptr) = value;
     178        }
     179
     180// test for GCC >= 4.0. these implementations will automatically use CPU-specific
     181// instructions for unaligned data when they are available (eg. MIPS)
     182#elif defined(__GNUC__) && (__GNUC__ >= 4)
     183
     184        inline uint16 READ_UINT16(const void *ptr) {
     185                struct Unaligned16 { uint16 val; } __attribute__ ((__packed__));
     186                return ((const Unaligned16 *)ptr)->val;
     187        }
     188
     189        inline uint32 READ_UINT32(const void *ptr) {
     190                struct Unaligned32 { uint32 val; } __attribute__ ((__packed__));
     191                return ((const Unaligned32 *)ptr)->val;
     192        }
     193
     194        inline void WRITE_UINT16(void *ptr, uint16 value) {
     195                struct Unaligned16 { uint16 val; } __attribute__ ((__packed__));
     196                ((Unaligned16 *)ptr)->val = value;
     197        }
     198
     199        inline void WRITE_UINT32(void *ptr, uint32 value) {
     200                struct Unaligned32 { uint32 val; } __attribute__ ((__packed__));
     201                ((Unaligned32 *)ptr)->val = value;
     202        }
     203
     204// use software fallback by loading each byte explicitely
     205#else
     206
     207#       if defined(SCUMM_LITTLE_ENDIAN)
     208
     209                inline uint16 READ_UINT16(const void *ptr) {
     210                        const uint8 *b = (const uint8 *)ptr;
     211                        return (b[1] << 8) | b[0];
     212                }
     213                inline uint32 READ_UINT32(const void *ptr) {
     214                        const uint8 *b = (const uint8 *)ptr;
     215                        return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]);
     216                }
     217                inline void WRITE_UINT16(void *ptr, uint16 value) {
     218                        uint8 *b = (uint8 *)ptr;
     219                        b[0] = (uint8)(value >> 0);
     220                        b[1] = (uint8)(value >> 8);
     221                }
     222                inline void WRITE_UINT32(void *ptr, uint32 value) {
     223                        uint8 *b = (uint8 *)ptr;
     224                        b[0] = (uint8)(value >>  0);
     225                        b[1] = (uint8)(value >>  8);
     226                        b[2] = (uint8)(value >> 16);
     227                        b[3] = (uint8)(value >> 24);
     228                }
     229
     230#       elif defined(SCUMM_BIG_ENDIAN)
     231
     232                inline uint16 READ_UINT16(const void *ptr) {
     233                        const uint8 *b = (const uint8 *)ptr;
     234                        return (b[0] << 8) | b[1];
     235                }
     236                inline uint32 READ_UINT32(const void *ptr) {
     237                        const uint8 *b = (const uint8 *)ptr;
     238                        return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
     239                }
     240                inline void WRITE_UINT16(void *ptr, uint16 value) {
     241                        uint8 *b = (uint8 *)ptr;
     242                        b[0] = (uint8)(value >> 8);
     243                        b[1] = (uint8)(value >> 0);
     244                }
     245                inline void WRITE_UINT32(void *ptr, uint32 value) {
     246                        uint8 *b = (uint8 *)ptr;
     247                        b[0] = (uint8)(value >> 24);
     248                        b[1] = (uint8)(value >> 16);
     249                        b[2] = (uint8)(value >>  8);
     250                        b[3] = (uint8)(value >>  0);
     251                }
     252
     253#       endif
     254
     255#endif
     256
     257
     258//  Map Funtions for reading/writing BE/LE integers depending on native endianess
    85259#if defined(SCUMM_LITTLE_ENDIAN)
    86260
    87         #define READ_UINT16(a) READ_LE_UINT16(a)
    88         #define READ_UINT32(a) READ_LE_UINT32(a)
     261        #define READ_LE_UINT16(a) READ_UINT16(a)
     262        #define READ_LE_UINT32(a) READ_UINT32(a)
    89263
    90         #define WRITE_UINT16(a, v) WRITE_LE_UINT16(a, v)
    91         #define WRITE_UINT32(a, v) WRITE_LE_UINT32(a, v)
     264        #define WRITE_LE_UINT16(a, v) WRITE_UINT16(a, v)
     265        #define WRITE_LE_UINT32(a, v) WRITE_UINT32(a, v)
    92266
    93267        #define FROM_LE_32(a) ((uint32)(a))
    94268        #define FROM_LE_16(a) ((uint16)(a))
     
    102276        #define TO_BE_32(a) SWAP_BYTES_32(a)
    103277        #define TO_BE_16(a) SWAP_BYTES_16(a)
    104278
     279        #define CONSTANT_LE_32(a) ((uint32)(a))
     280        #define CONSTANT_LE_16(a) ((uint16)(a))
     281
     282        #define CONSTANT_BE_32(a) SWAP_CONSTANT_32(a)
     283        #define CONSTANT_BE_16(a) SWAP_CONSTANT_16(a)
     284
     285// if the unaligned load and the byteswap take alot instructions its better to directly read and invert
     286#       if defined(SCUMM_NEED_ALIGNMENT) && !defined(__mips__)
     287
     288                inline uint16 READ_BE_UINT16(const void *ptr) {
     289                        const uint8 *b = (const uint8 *)ptr;
     290                        return (b[0] << 8) | b[1];
     291                }
     292                inline uint32 READ_BE_UINT32(const void *ptr) {
     293                        const uint8 *b = (const uint8 *)ptr;
     294                        return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
     295                }
     296                inline void WRITE_BE_UINT16(void *ptr, uint16 value) {
     297                        uint8 *b = (uint8 *)ptr;
     298                        b[0] = (uint8)(value >> 8);
     299                        b[1] = (uint8)(value >> 0);
     300                }
     301                inline void WRITE_BE_UINT32(void *ptr, uint32 value) {
     302                        uint8 *b = (uint8 *)ptr;
     303                        b[0] = (uint8)(value >> 24);
     304                        b[1] = (uint8)(value >> 16);
     305                        b[2] = (uint8)(value >>  8);
     306                        b[3] = (uint8)(value >>  0);
     307                }
     308#       else
     309
     310                FORCEINLINE uint16 READ_BE_UINT16(const void *ptr) {
     311                        return SWAP_BYTES_16(READ_UINT16(ptr));
     312                }
     313                FORCEINLINE uint32 READ_BE_UINT32(const void *ptr) {
     314                        return SWAP_BYTES_32(READ_UINT32(ptr));
     315                }
     316                FORCEINLINE void WRITE_BE_UINT16(void *ptr, uint16 value) {
     317                        WRITE_UINT16(ptr, SWAP_BYTES_16(value));
     318                }
     319                FORCEINLINE void WRITE_BE_UINT32(void *ptr, uint32 value) {
     320                        WRITE_UINT32(ptr, SWAP_BYTES_32(value));
     321                }
     322       
     323#       endif   // if defined(SCUMM_NEED_ALIGNMENT)
     324
    105325#elif defined(SCUMM_BIG_ENDIAN)
    106326
     327        // I thought this would be compiler-specific and not dependent
     328        // on endianess after the comments above?
    107329        #define MKID(a) ((uint32)(a))
    108330        #define MKID_BE(a) ((uint32)(a))
    109331
    110         #define READ_UINT16(a) READ_BE_UINT16(a)
    111         #define READ_UINT32(a) READ_BE_UINT32(a)
     332        #define READ_BE_UINT16(a) READ_UINT16(a)
     333        #define READ_BE_UINT32(a) READ_UINT32(a)
    112334
    113         #define WRITE_UINT16(a, v) WRITE_BE_UINT16(a, v)
    114         #define WRITE_UINT32(a, v) WRITE_BE_UINT32(a, v)
     335        #define WRITE_BE_UINT16(a, v) WRITE_UINT16(a, v)
     336        #define WRITE_BE_UINT32(a, v) WRITE_UINT32(a, v)
    115337
    116338        #define FROM_LE_32(a) SWAP_BYTES_32(a)
    117339        #define FROM_LE_16(a) SWAP_BYTES_16(a)
     
    125347        #define TO_BE_32(a) ((uint32)(a))
    126348        #define TO_BE_16(a) ((uint16)(a))
    127349
    128 #else
     350        #define CONSTANT_LE_32(a) SWAP_CONSTANT_32(a)
     351        #define CONSTANT_LE_16(a) SWAP_CONSTANT_16(a)
    129352
    130         #error No endianness defined
     353        #define CONSTANT_BE_32(a) ((uint32)(a))
     354        #define CONSTANT_BE_16(a) ((uint16)(a))
    131355
     356// if the unaligned load and the byteswap take alot instructions its better to directly read and invert
     357#       if defined(SCUMM_NEED_ALIGNMENT) && !defined(__mips__)
    132358
    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];
     359        inline uint16 READ_LE_UINT16(const void *ptr) {
     360                const uint8 *b = (const uint8 *)ptr;
     361                return (b[1] << 8) | b[0];
    140362        }
    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]);
     363        inline uint32 READ_LE_UINT32(const void *ptr) {
     364                const uint8 *b = (const uint8 *)ptr;
     365                return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]);
    144366        }
    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);
     367        inline void WRITE_LE_UINT16(void *ptr, uint16 value) {
     368                uint8 *b = (uint8 *)ptr;
     369                b[0] = (uint8)(value >> 0);
     370                b[1] = (uint8)(value >> 8);
    149371        }
    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);
     372        inline void WRITE_LE_UINT32(void *ptr, uint32 value) {
     373                uint8 *b = (uint8 *)ptr;
     374                b[0] = (uint8)(value >>  0);
     375                b[1] = (uint8)(value >>  8);
     376                b[2] = (uint8)(value >> 16);
     377                b[3] = (uint8)(value >> 24);
    156378        }
    157 #else
     379#       else
     380
    158381        FORCEINLINE uint16 READ_LE_UINT16(const void *ptr) {
    159                 return *(const uint16 *)(ptr);
     382                return SWAP_BYTES_16(READ_UINT16(ptr));
    160383        }
    161384        FORCEINLINE uint32 READ_LE_UINT32(const void *ptr) {
    162                 return *(const uint32 *)(ptr);
     385                return SWAP_BYTES_32(READ_UINT32(ptr));
    163386        }
    164387        FORCEINLINE void WRITE_LE_UINT16(void *ptr, uint16 value) {
    165                 *(uint16 *)(ptr) = value;
     388                WRITE_UINT16(ptr, SWAP_BYTES_16(value));
    166389        }
    167390        FORCEINLINE void WRITE_LE_UINT32(void *ptr, uint32 value) {
    168                 *(uint32 *)(ptr) = value;
     391                WRITE_UINT32(ptr, SWAP_BYTES_32(value));
    169392        }
    170 #endif
     393       
     394#       endif   // if defined(SCUMM_NEED_ALIGNMENT)
    171395
     396#endif  // if defined(SCUMM_LITTLE_ENDIAN)
    172397
    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]);
     398inline uint32 READ_LE_UINT24(const void *ptr) {
     399        const uint8 *b = (const uint8 *)ptr;
     400        return (b[2] << 16) | (b[1] << 8) | (b[0]);
    212401}
    213402
    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]);
     403inline uint32 READ_BE_UINT24(const void *ptr) {
     404        const uint8 *b = (const uint8 *)ptr;
     405        return (b[0] << 16) | (b[1] << 8) | (b[2]);
    217406}
    218407
    219 
    220408#endif
  • 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        }
     
    200201         * calling err() and eos() ).
    201202         */
    202203        int8 readSByte() {
    203                 int8 b = 0;
     204                int8 b = 0; // FIXME: remove initialisation
    204205                read(&b, 1);
    205206                return b;
    206207        }
     
    213214         * calling err() and eos() ).
    214215         */
    215216        uint16 readUint16LE() {
    216                 uint16 a = readByte();
    217                 uint16 b = readByte();
    218                 return a | (b << 8);
     217                uint16 val;
     218                read(&val, 2);
     219                return FROM_LE_16(val);
    219220        }
    220221
    221222        /**
     
    226227         * calling err() and eos() ).
    227228         */
    228229        uint32 readUint32LE() {
    229                 uint32 a = readUint16LE();
    230                 uint32 b = readUint16LE();
    231                 return (b << 16) | a;
     230                uint32 val;
     231                read(&val, 4);
     232                return FROM_LE_32(val);
    232233        }
    233234
    234235        /**
     
    239240         * calling err() and eos() ).
    240241         */
    241242        uint16 readUint16BE() {
    242                 uint16 b = readByte();
    243                 uint16 a = readByte();
    244                 return a | (b << 8);
     243                uint16 val;
     244                read(&val, 2);
     245                return FROM_BE_16(val);
    245246        }
    246247
    247248        /**
     
    252253         * calling err() and eos() ).
    253254         */
    254255        uint32 readUint32BE() {
    255                 uint32 b = readUint16BE();
    256                 uint32 a = readUint16BE();
    257                 return (b << 16) | a;
     256                uint32 val;
     257                read(&val, 4);
     258                return FROM_BE_32(val);
    258259        }
    259260
    260261        /**
     
    264265         * if a read error occurred (for which client code can check by
    265266         * calling err() and eos() ).
    266267         */
    267         int16 readSint16LE() {
     268        FORCEINLINE int16 readSint16LE() {
    268269                return (int16)readUint16LE();
    269270        }
    270271
     
    275276         * if a read error occurred (for which client code can check by
    276277         * calling err() and eos() ).
    277278         */
    278         int32 readSint32LE() {
     279        FORCEINLINE int32 readSint32LE() {
    279280                return (int32)readUint32LE();
    280281        }
    281282
     
    286287         * if a read error occurred (for which client code can check by
    287288         * calling err() and eos() ).
    288289         */
    289         int16 readSint16BE() {
     290        FORCEINLINE int16 readSint16BE() {
    290291                return (int16)readUint16BE();
    291292        }
    292293
     
    297298         * if a read error occurred (for which client code can check by
    298299         * calling err() and eos() ).
    299300         */
    300         int32 readSint32BE() {
     301        FORCEINLINE int32 readSint32BE() {
    301302                return (int32)readUint32BE();
    302303        }
    303304
     
    460461 * @see SubReadStream
    461462 */
    462463class SeekableSubReadStreamEndian : public SeekableSubReadStream {
     464private:
     465        const bool _bigEndian;
     466
    463467public:
    464         bool _bigEndian;
    465 
    466468        SeekableSubReadStreamEndian(SeekableReadStream *parentStream, uint32 begin, uint32 end, bool bigEndian = false, bool disposeParentStream = false)
    467469                : SeekableSubReadStream(parentStream, begin, end, disposeParentStream), _bigEndian(bigEndian) {
    468470        }
    469471
    470         inline uint16 readUint16() {
    471                 return (_bigEndian) ? readUint16BE() : readUint16LE();
     472        uint16 readUint16() {
     473                uint16 val;
     474                read(&val, 2);
     475                return (_bigEndian) ? TO_BE_16(val) : TO_LE_16(val);
    472476        }
    473477
    474         inline uint32 readUint32() {
    475                 return (_bigEndian) ? readUint32BE() : readUint32LE();
     478        uint32 readUint32() {
     479                uint32 val;
     480                read(&val, 4);
     481                return (_bigEndian) ? TO_BE_32(val) : TO_LE_32(val);
    476482        }
    477483
    478         inline int16 readSint16() {
     484        FORCEINLINE int16 readSint16() {
    479485                return (int16)readUint16();
    480486        }
    481487
    482         inline int32 readSint32() {
     488        FORCEINLINE int32 readSint32() {
    483489                return (int32)readUint32();
    484490        }
    485491};
     
    582588 */
    583589class MemoryReadStreamEndian : public Common::MemoryReadStream {
    584590private:
     591        const bool _bigEndian;
     592
    585593public:
    586         bool _bigEndian;
    587594        MemoryReadStreamEndian(const byte *buf, uint32 len, bool bigEndian = false) : MemoryReadStream(buf, len), _bigEndian(bigEndian) {}
    588595
    589         inline uint16 readUint16() {
    590                 return (_bigEndian) ? readUint16BE() : readUint16LE();
     596        uint16 readUint16() {
     597                uint16 val;
     598                read(&val, 2);
     599                return (_bigEndian) ? TO_BE_16(val) : TO_LE_16(val);
    591600        }
    592601
    593         inline uint32 readUint32() {
    594                 return (_bigEndian) ? readUint32BE() : readUint32LE();
     602        uint32 readUint32() {
     603                uint32 val;
     604                read(&val, 4);
     605                return (_bigEndian) ? TO_BE_32(val) : TO_LE_32(val);
    595606        }
    596607
    597         inline int16 readSint16() {
     608        FORCEINLINE int16 readSint16() {
    598609                return (int16)readUint16();
    599610        }
    600611
    601         inline int32 readSint32() {
     612        FORCEINLINE int32 readSint32() {
    602613                return (int32)readUint32();
    603614        }
    604615};
  • 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();