ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

endian.h

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #ifndef COMMON_ENDIAN_H
00024 #define COMMON_ENDIAN_H
00025 
00026 #include "common/scummsys.h"
00027 
00047 // Sanity check
00048 #if !defined(SCUMM_LITTLE_ENDIAN) && !defined(SCUMM_BIG_ENDIAN)
00049 #   error No endianness defined
00050 #endif
00051 
00052 #define SWAP_CONSTANT_64(a) \
00053     ((uint64)((((a) >> 56) & 0x000000FF) | \
00054               (((a) >> 40) & 0x0000FF00) | \
00055               (((a) >> 24) & 0x00FF0000) | \
00056               (((a) >>  8) & 0xFF000000) | \
00057               (((a) & 0xFF000000) <<  8) | \
00058               (((a) & 0x00FF0000) << 24) | \
00059               (((a) & 0x0000FF00) << 40) | \
00060               (((a) & 0x000000FF) << 56) ))
00061 
00062 #define SWAP_CONSTANT_32(a) \
00063     ((uint32)((((a) >> 24) & 0x00FF) | \
00064               (((a) >>  8) & 0xFF00) | \
00065               (((a) & 0xFF00) <<  8) | \
00066               (((a) & 0x00FF) << 24) ))
00067 
00068 #define SWAP_CONSTANT_16(a) \
00069     ((uint16)((((a) >>  8) & 0x00FF) | \
00070               (((a) <<  8) & 0xFF00) ))
00071 
00072 
00073 
00079 // compilerspecific variants come first, fallback last
00080 
00081 // Test for GCC and if the target has the MIPS rel.2 instructions (we know the psp does)
00082 #if defined(__GNUC__) && (defined(__psp__) || defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2))
00083 
00084     FORCEINLINE uint16 SWAP_BYTES_16(const uint16 a) {
00085         if (__builtin_constant_p(a)) {
00086             return SWAP_CONSTANT_16(a);
00087         } else {
00088             uint16 result;
00089             __asm__ ("wsbh %0,%1" : "=r" (result) : "r" (a));
00090             return result;
00091         }
00092     }
00093 #else
00094 
00095     inline uint16 SWAP_BYTES_16(const uint16 a) {
00096         return (a >> 8) | (a << 8);
00097     }
00098 #endif
00099 
00100 
00101 
00107 // machine/compiler-specific variants come first, fallback last
00108 
00109 // Test for GCC and if the target has the MIPS rel.2 instructions (we know the psp does)
00110 #if defined(__GNUC__) && (defined(__psp__) || defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2))
00111 
00112     FORCEINLINE uint32 SWAP_BYTES_32(const uint32 a) {
00113         if (__builtin_constant_p(a)) {
00114             return SWAP_CONSTANT_32(a);
00115         } else {
00116             uint32 result;
00117 #   if defined(__psp__)
00118             // use special allegrex instruction
00119             __asm__ ("wsbw %0,%1" : "=r" (result) : "r" (a));
00120 #   else
00121             __asm__ ("wsbh %0,%1\n"
00122                      "rotr %0,%0,16" : "=r" (result) : "r" (a));
00123 #   endif
00124             return result;
00125         }
00126     }
00127 
00128 // Test for GCC >= 4.3.0 as this version added the bswap builtin
00129 #elif GCC_ATLEAST(4, 3)
00130 
00131     FORCEINLINE uint32 SWAP_BYTES_32(uint32 a) {
00132         return __builtin_bswap32(a);
00133     }
00134 
00135 #elif defined(_MSC_VER)
00136 
00137     FORCEINLINE uint32 SWAP_BYTES_32(uint32 a) {
00138         return _byteswap_ulong(a);
00139     }
00140 
00141 // generic fallback
00142 #else
00143 
00144     inline uint32 SWAP_BYTES_32(uint32 a) {
00145         const uint16 low = (uint16)a, high = (uint16)(a >> 16);
00146         return ((uint32)(uint16)((low >> 8) | (low << 8)) << 16)
00147                | (uint16)((high >> 8) | (high << 8));
00148     }
00149 #endif
00150 
00156 // machine/compiler-specific variants come first, fallback last
00157 
00158 // Test for GCC and if the target has the MIPS rel.2 instructions (we know the psp does)
00159 //
00160 #if defined(__GNUC__) && (defined(__psp__) || defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2))
00161 
00162     FORCEINLINE uint64 SWAP_BYTES_64(const uint64 a) {
00163         if (__builtin_constant_p(a)) {
00164             return SWAP_CONSTANT_64(a);
00165         } else {
00166             uint32 low = (uint32)a, high = (uint32)(a >> 32);
00167             low = SWAP_BYTES_32(low);
00168             high = SWAP_BYTES_32(high);
00169 
00170             return (((uint64)low) << 32) | high;
00171         }
00172     }
00173 
00174 // Test for GCC >= 4.3.0 as this version added the bswap builtin
00175 #elif GCC_ATLEAST(4, 3)
00176 
00177     FORCEINLINE uint64 SWAP_BYTES_64(uint64 a) {
00178         return __builtin_bswap64(a);
00179     }
00180 
00181 #elif defined(_MSC_VER)
00182 
00183     FORCEINLINE uint64 SWAP_BYTES_64(uint64 a) {
00184         return _byteswap_uint64(a);
00185     }
00186 
00187 // generic fallback
00188 #else
00189 
00190     inline uint64 SWAP_BYTES_64(uint64 a) {
00191         uint32 low = (uint32)a, high = (uint32)(a >> 32);
00192         uint16 lowLow = (uint16)low, lowHigh = (uint16)(low >> 16),
00193                highLow = (uint16)high, highHigh = (uint16)(high >> 16);
00194 
00195         return ((uint64)(((uint32)(uint16)((lowLow   >> 8) | (lowLow   << 8)) << 16) |
00196                                   (uint16)((lowHigh  >> 8) | (lowHigh  << 8))) << 32) |
00197                         (((uint32)(uint16)((highLow  >> 8) | (highLow  << 8)) << 16) |
00198                                   (uint16)((highHigh >> 8) | (highHigh << 8)));
00199     }
00200 #endif
00201 
00202 
00203 
00212 #define MKTAG(a0,a1,a2,a3) ((uint32)((a3) | ((a2) << 8) | ((a1) << 16) | ((a0) << 24)))
00213 
00218 #define MKTAG16(a0,a1) ((uint16)((a1) | ((a0) << 8)))
00219 
00220 // Functions for reading/writing native integers.
00221 // They also transparently handle the need for alignment.
00222 
00223 // Test for GCC >= 4.0. These implementations will automatically use
00224 // CPU-specific instructions for unaligned data when they are available (eg.
00225 // MIPS). See also this email thread on scummvm-devel for details:
00226 // <http://thread.gmane.org/gmane.games.devel.scummvm/8063>
00227 //
00228 // Moreover, we activate this code for GCC >= 3.3 but *only* if unaligned access
00229 // is allowed.
00230 #if GCC_ATLEAST(4, 0) || (GCC_ATLEAST(3, 3) && !defined(SCUMM_NEED_ALIGNMENT))
00231 
00232     FORCEINLINE uint16 READ_UINT16(const void *ptr) {
00233         struct Unaligned16 { uint16 val; } __attribute__ ((__packed__, __may_alias__));
00234         return ((const Unaligned16 *)ptr)->val;
00235     }
00236 
00237     FORCEINLINE uint32 READ_UINT32(const void *ptr) {
00238         struct Unaligned32 { uint32 val; } __attribute__ ((__packed__, __may_alias__));
00239         return ((const Unaligned32 *)ptr)->val;
00240     }
00241 
00242     FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) {
00243         struct Unaligned16 { uint16 val; } __attribute__ ((__packed__, __may_alias__));
00244         ((Unaligned16 *)ptr)->val = value;
00245     }
00246 
00247     FORCEINLINE void WRITE_UINT32(void *ptr, uint32 value) {
00248         struct Unaligned32 { uint32 val; } __attribute__ ((__packed__, __may_alias__));
00249         ((Unaligned32 *)ptr)->val = value;
00250     }
00251 
00252     FORCEINLINE uint64 READ_UINT64(const void *ptr) {
00253         struct Unaligned64 { uint64 val; } __attribute__ ((__packed__, __may_alias__));
00254         return ((const Unaligned64 *)ptr)->val;
00255     }
00256 
00257     FORCEINLINE void WRITE_UINT64(void *ptr, uint64 value) {
00258         struct Unaligned64 { uint64 val; } __attribute__((__packed__, __may_alias__));
00259         ((Unaligned64 *)ptr)->val = value;
00260     }
00261 
00262 #elif !defined(SCUMM_NEED_ALIGNMENT)
00263 
00264     FORCEINLINE uint16 READ_UINT16(const void *ptr) {
00265         return *(const uint16 *)(ptr);
00266     }
00267 
00268     FORCEINLINE uint32 READ_UINT32(const void *ptr) {
00269         return *(const uint32 *)(ptr);
00270     }
00271 
00272     FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) {
00273         *(uint16 *)(ptr) = value;
00274     }
00275 
00276     FORCEINLINE void WRITE_UINT32(void *ptr, uint32 value) {
00277         *(uint32 *)(ptr) = value;
00278     }
00279 
00280     FORCEINLINE uint64 READ_UINT64(const void *ptr) {
00281         return *(const uint64 *)(ptr);
00282     }
00283 
00284     FORCEINLINE void WRITE_UINT64(void *ptr, uint64 value) {
00285         *(uint64 *)(ptr) = value;
00286     }
00287 
00288 
00289 // use software fallback by loading each byte explicitely
00290 #else
00291 
00292 #   if defined(SCUMM_LITTLE_ENDIAN)
00293 
00294         inline uint16 READ_UINT16(const void *ptr) {
00295             const uint8 *b = (const uint8 *)ptr;
00296             return (b[1] << 8) | b[0];
00297         }
00298         inline uint32 READ_UINT32(const void *ptr) {
00299             const uint8 *b = (const uint8 *)ptr;
00300             return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]);
00301         }
00302         inline void WRITE_UINT16(void *ptr, uint16 value) {
00303             uint8 *b = (uint8 *)ptr;
00304             b[0] = (uint8)(value >> 0);
00305             b[1] = (uint8)(value >> 8);
00306         }
00307         inline void WRITE_UINT32(void *ptr, uint32 value) {
00308             uint8 *b = (uint8 *)ptr;
00309             b[0] = (uint8)(value >>  0);
00310             b[1] = (uint8)(value >>  8);
00311             b[2] = (uint8)(value >> 16);
00312             b[3] = (uint8)(value >> 24);
00313         }
00314         inline uint64 READ_UINT64(const void *ptr) {
00315             const uint8 *b = (const uint8 *)ptr;
00316             return ((uint64)b[7] << 56) | ((uint64)b[6] << 48) | ((uint64)b[5] << 40) | ((uint64)b[4] << 32) | ((uint64)b[3] << 24) | ((uint64)b[2] << 16) | ((uint64)b[1] << 8) | ((uint64)b[0]);
00317         }
00318         inline void WRITE_UINT64(void *ptr, uint64 value) {
00319             uint8 *b = (uint8 *)ptr;
00320             b[0] = (uint8)(value >>  0);
00321             b[1] = (uint8)(value >>  8);
00322             b[2] = (uint8)(value >> 16);
00323             b[3] = (uint8)(value >> 24);
00324             b[4] = (uint8)(value >> 32);
00325             b[5] = (uint8)(value >> 40);
00326             b[6] = (uint8)(value >> 48);
00327             b[7] = (uint8)(value >> 56);
00328         }
00329 
00330 #   elif defined(SCUMM_BIG_ENDIAN)
00331 
00332         inline uint16 READ_UINT16(const void *ptr) {
00333             const uint8 *b = (const uint8 *)ptr;
00334             return (b[0] << 8) | b[1];
00335         }
00336         inline uint32 READ_UINT32(const void *ptr) {
00337             const uint8 *b = (const uint8 *)ptr;
00338             return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
00339         }
00340         inline void WRITE_UINT16(void *ptr, uint16 value) {
00341             uint8 *b = (uint8 *)ptr;
00342             b[0] = (uint8)(value >> 8);
00343             b[1] = (uint8)(value >> 0);
00344         }
00345         inline void WRITE_UINT32(void *ptr, uint32 value) {
00346             uint8 *b = (uint8 *)ptr;
00347             b[0] = (uint8)(value >> 24);
00348             b[1] = (uint8)(value >> 16);
00349             b[2] = (uint8)(value >>  8);
00350             b[3] = (uint8)(value >>  0);
00351         }
00352         inline uint64 READ_UINT64(const void *ptr) {
00353             const uint8 *b = (const uint8 *)ptr;
00354             return ((uint64)b[0] << 56) | ((uint64)b[1] << 48) | ((uint64)b[2] << 40) | ((uint64)b[3] << 32) | ((uint64)b[4] << 24) | ((uint64)b[5] << 16) | ((uint64)b[6] << 8) | ((uint64)b[7]);
00355         }
00356         inline void WRITE_UINT64(void *ptr, uint64 value) {
00357             uint8 *b = (uint8 *)ptr;
00358             b[0] = (uint8)(value >> 56);
00359             b[1] = (uint8)(value >> 48);
00360             b[2] = (uint8)(value >> 40);
00361             b[3] = (uint8)(value >> 32);
00362             b[4] = (uint8)(value >> 24);
00363             b[5] = (uint8)(value >> 16);
00364             b[6] = (uint8)(value >>  8);
00365             b[7] = (uint8)(value >>  0);
00366         }
00367 
00368 #   endif
00369 
00370 #endif
00371 
00372 
00373 //  Map Funtions for reading/writing BE/LE integers depending on native endianess
00374 #if defined(SCUMM_LITTLE_ENDIAN)
00375 
00376     #define READ_LE_UINT16(a) READ_UINT16(a)
00377     #define READ_LE_UINT32(a) READ_UINT32(a)
00378 
00379     #define WRITE_LE_UINT16(a, v) WRITE_UINT16(a, v)
00380     #define WRITE_LE_UINT32(a, v) WRITE_UINT32(a, v)
00381 
00382     #define FROM_LE_32(a) ((uint32)(a))
00383     #define FROM_LE_16(a) ((uint16)(a))
00384 
00385     #define FROM_BE_32(a) SWAP_BYTES_32(a)
00386     #define FROM_BE_16(a) SWAP_BYTES_16(a)
00387 
00388     #define TO_LE_32(a) ((uint32)(a))
00389     #define TO_LE_16(a) ((uint16)(a))
00390 
00391     #define TO_BE_32(a) SWAP_BYTES_32(a)
00392     #define TO_BE_16(a) SWAP_BYTES_16(a)
00393 
00394     #define CONSTANT_LE_32(a) ((uint32)(a))
00395     #define CONSTANT_LE_16(a) ((uint16)(a))
00396 
00397     #define CONSTANT_BE_32(a) SWAP_CONSTANT_32(a)
00398     #define CONSTANT_BE_16(a) SWAP_CONSTANT_16(a)
00399 
00400     #define READ_LE_UINT64(a) READ_UINT64(a)
00401     #define WRITE_LE_UINT64(a, v) WRITE_UINT64(a, v)
00402     #define FROM_LE_64(a) ((uint64)(a))
00403     #define FROM_BE_64(a) SWAP_BYTES_64(a)
00404     #define TO_LE_64(a) ((uint64)(a))
00405     #define TO_BE_64(a) SWAP_BYTES_64(a)
00406     #define CONSTANT_LE_64(a) ((uint64)(a))
00407     #define CONSTANT_BE_64(a) SWAP_CONSTANT_64(a)
00408 
00409 // if the unaligned load and the byteswap take alot instructions its better to directly read and invert
00410 #   if defined(SCUMM_NEED_ALIGNMENT) && !defined(__mips__)
00411 
00412         inline uint16 READ_BE_UINT16(const void *ptr) {
00413             const uint8 *b = (const uint8 *)ptr;
00414             return (b[0] << 8) | b[1];
00415         }
00416         inline uint32 READ_BE_UINT32(const void *ptr) {
00417             const uint8 *b = (const uint8 *)ptr;
00418             return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
00419         }
00420         inline void WRITE_BE_UINT16(void *ptr, uint16 value) {
00421             uint8 *b = (uint8 *)ptr;
00422             b[0] = (uint8)(value >> 8);
00423             b[1] = (uint8)(value >> 0);
00424         }
00425         inline void WRITE_BE_UINT32(void *ptr, uint32 value) {
00426             uint8 *b = (uint8 *)ptr;
00427             b[0] = (uint8)(value >> 24);
00428             b[1] = (uint8)(value >> 16);
00429             b[2] = (uint8)(value >>  8);
00430             b[3] = (uint8)(value >>  0);
00431         }
00432         inline uint64 READ_BE_UINT64(const void *ptr) {
00433             const uint8 *b = (const uint8 *)ptr;
00434             return ((uint64)b[0] << 56) | ((uint64)b[1] << 48) | ((uint64)b[2] << 40) | ((uint64)b[3] << 32) | ((uint64)b[4] << 24) | ((uint64)b[5] << 16) | ((uint64)b[6] << 8) | ((uint64)b[7]);
00435         }
00436         inline void WRITE_BE_UINT64(void *ptr, uint64 value) {
00437             uint8 *b = (uint8 *)ptr;
00438             b[0] = (uint8)(value >> 56);
00439             b[1] = (uint8)(value >> 48);
00440             b[2] = (uint8)(value >> 40);
00441             b[3] = (uint8)(value >> 32);
00442             b[4] = (uint8)(value >> 24);
00443             b[5] = (uint8)(value >> 16);
00444             b[6] = (uint8)(value >> 8);
00445             b[7] = (uint8)(value >> 0);
00446         }
00447 
00448 #   else
00449 
00450         inline uint16 READ_BE_UINT16(const void *ptr) {
00451             return SWAP_BYTES_16(READ_UINT16(ptr));
00452         }
00453         inline uint32 READ_BE_UINT32(const void *ptr) {
00454             return SWAP_BYTES_32(READ_UINT32(ptr));
00455         }
00456         inline void WRITE_BE_UINT16(void *ptr, uint16 value) {
00457             WRITE_UINT16(ptr, SWAP_BYTES_16(value));
00458         }
00459         inline void WRITE_BE_UINT32(void *ptr, uint32 value) {
00460             WRITE_UINT32(ptr, SWAP_BYTES_32(value));
00461         }
00462         inline uint64 READ_BE_UINT64(const void *ptr) {
00463             return SWAP_BYTES_64(READ_UINT64(ptr));
00464         }
00465         inline void WRITE_BE_UINT64(void *ptr, uint64 value) {
00466             WRITE_UINT64(ptr, SWAP_BYTES_64(value));
00467         }
00468 
00469 #   endif   // if defined(SCUMM_NEED_ALIGNMENT)
00470 
00471 #elif defined(SCUMM_BIG_ENDIAN)
00472 
00473     #define READ_BE_UINT16(a) READ_UINT16(a)
00474     #define READ_BE_UINT32(a) READ_UINT32(a)
00475 
00476     #define WRITE_BE_UINT16(a, v) WRITE_UINT16(a, v)
00477     #define WRITE_BE_UINT32(a, v) WRITE_UINT32(a, v)
00478 
00479     #define FROM_LE_32(a) SWAP_BYTES_32(a)
00480     #define FROM_LE_16(a) SWAP_BYTES_16(a)
00481 
00482     #define FROM_BE_32(a) ((uint32)(a))
00483     #define FROM_BE_16(a) ((uint16)(a))
00484 
00485     #define TO_LE_32(a) SWAP_BYTES_32(a)
00486     #define TO_LE_16(a) SWAP_BYTES_16(a)
00487 
00488     #define TO_BE_32(a) ((uint32)(a))
00489     #define TO_BE_16(a) ((uint16)(a))
00490 
00491     #define CONSTANT_LE_32(a) SWAP_CONSTANT_32(a)
00492     #define CONSTANT_LE_16(a) SWAP_CONSTANT_16(a)
00493 
00494     #define CONSTANT_BE_32(a) ((uint32)(a))
00495     #define CONSTANT_BE_16(a) ((uint16)(a))
00496 
00497     #define READ_BE_UINT64(a) READ_UINT64(a)
00498     #define WRITE_BE_UINT64(a, v) WRITE_UINT64(a, v)
00499     #define FROM_LE_64(a) SWAP_BYTES_64(a)
00500     #define FROM_BE_64(a) ((uint64)(a))
00501     #define TO_LE_64(a) SWAP_BYTES_64(a)
00502     #define TO_BE_64(a) ((uint64)(a))
00503     #define CONSTANT_LE_64(a) SWAP_CONSTANT_64(a)
00504     #define CONSTANT_BE_64(a) ((uint64)(a))
00505 
00506 // if the unaligned load and the byteswap take alot instructions its better to directly read and invert
00507 #   if defined(SCUMM_NEED_ALIGNMENT) && !defined(__mips__)
00508 
00509     inline uint16 READ_LE_UINT16(const void *ptr) {
00510         const uint8 *b = (const uint8 *)ptr;
00511         return (b[1] << 8) | b[0];
00512     }
00513     inline uint32 READ_LE_UINT32(const void *ptr) {
00514         const uint8 *b = (const uint8 *)ptr;
00515         return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]);
00516     }
00517     inline void WRITE_LE_UINT16(void *ptr, uint16 value) {
00518         uint8 *b = (uint8 *)ptr;
00519         b[0] = (uint8)(value >> 0);
00520         b[1] = (uint8)(value >> 8);
00521     }
00522     inline void WRITE_LE_UINT32(void *ptr, uint32 value) {
00523         uint8 *b = (uint8 *)ptr;
00524         b[0] = (uint8)(value >>  0);
00525         b[1] = (uint8)(value >>  8);
00526         b[2] = (uint8)(value >> 16);
00527         b[3] = (uint8)(value >> 24);
00528     }
00529 
00530     inline uint64 READ_LE_UINT64(const void *ptr) {
00531         const uint8 *b = (const uint8 *)ptr;
00532         return ((uint64)b[7] << 56) | ((uint64)b[6] << 48) | ((uint64)b[5] << 40) | ((uint64)b[4] << 32) | ((uint64)b[3] << 24) | ((uint64)b[2] << 16) | ((uint64)b[1] << 8) | ((uint64)b[0]);
00533     }
00534     inline void WRITE_LE_UINT64(void *ptr, uint64 value) {
00535         uint8 *b = (uint8 *)ptr;
00536         b[0] = (uint8)(value >>  0);
00537         b[1] = (uint8)(value >>  8);
00538         b[2] = (uint8)(value >> 16);
00539         b[3] = (uint8)(value >> 24);
00540         b[4] = (uint8)(value >> 32);
00541         b[5] = (uint8)(value >> 40);
00542         b[6] = (uint8)(value >> 48);
00543         b[7] = (uint8)(value >> 56);
00544     }
00545 
00546 #   else
00547 
00548     inline uint16 READ_LE_UINT16(const void *ptr) {
00549         return SWAP_BYTES_16(READ_UINT16(ptr));
00550     }
00551     inline uint32 READ_LE_UINT32(const void *ptr) {
00552         return SWAP_BYTES_32(READ_UINT32(ptr));
00553     }
00554     inline void WRITE_LE_UINT16(void *ptr, uint16 value) {
00555         WRITE_UINT16(ptr, SWAP_BYTES_16(value));
00556     }
00557     inline void WRITE_LE_UINT32(void *ptr, uint32 value) {
00558         WRITE_UINT32(ptr, SWAP_BYTES_32(value));
00559     }
00560     inline uint64 READ_LE_UINT64(const void *ptr) {
00561         return SWAP_BYTES_64(READ_UINT64(ptr));
00562     }
00563     inline void WRITE_LE_UINT64(void *ptr, uint64 value) {
00564         WRITE_UINT64(ptr, SWAP_BYTES_64(value));
00565     }
00566 
00567 #   endif   // if defined(SCUMM_NEED_ALIGNMENT)
00568 
00569 #endif  // if defined(SCUMM_LITTLE_ENDIAN)
00570 
00571 inline uint32 READ_LE_UINT24(const void *ptr) {
00572     const uint8 *b = (const uint8 *)ptr;
00573     return (b[2] << 16) | (b[1] << 8) | (b[0]);
00574 }
00575 
00576 inline uint32 READ_BE_UINT24(const void *ptr) {
00577     const uint8 *b = (const uint8 *)ptr;
00578     return (b[0] << 16) | (b[1] << 8) | (b[2]);
00579 }
00580 
00581 #ifdef SCUMM_LITTLE_ENDIAN
00582 #define READ_UINT24(a) READ_LE_UINT24(a)
00583 #else
00584 #define READ_UINT24(a) READ_BE_UINT24(a)
00585 #endif
00586 
00587 inline int16 READ_LE_INT16(const void *ptr) {
00588     return static_cast<int16>(READ_LE_UINT16(ptr));
00589 }
00590 
00591 inline void WRITE_LE_INT16(void *ptr, int16 value) {
00592     WRITE_LE_UINT16(ptr, static_cast<uint16>(value));
00593 }
00594 
00595 inline int16 READ_BE_INT16(const void *ptr) {
00596     return static_cast<int16>(READ_BE_UINT16(ptr));
00597 }
00598 
00599 inline void WRITE_BE_INT16(void *ptr, int16 value) {
00600     WRITE_BE_UINT16(ptr, static_cast<uint16>(value));
00601 }
00602 
00603 inline int32 READ_LE_INT32(const void *ptr) {
00604     return static_cast<int32>(READ_LE_UINT32(ptr));
00605 }
00606 
00607 inline void WRITE_LE_INT32(void *ptr, int32 value) {
00608     WRITE_LE_UINT32(ptr, static_cast<uint32>(value));
00609 }
00610 
00611 inline int32 READ_BE_INT32(const void *ptr) {
00612     return static_cast<int32>(READ_BE_UINT32(ptr));
00613 }
00614 
00615 inline void WRITE_BE_INT32(void *ptr, int32 value) {
00616     WRITE_BE_UINT32(ptr, static_cast<uint32>(value));
00617 }
00618 
00619 #endif


Generated on Sat Mar 16 2019 05:01:30 for ResidualVM by doxygen 1.7.1
curved edge   curved edge