diff options
author | Norbert Lange | 2009-08-24 12:39:03 +0000 |
---|---|---|
committer | Norbert Lange | 2009-08-24 12:39:03 +0000 |
commit | 184aae3c8c863541771fbeb09ce5f1a72ecabb95 (patch) | |
tree | ec822b0d376e9cb7ab3e8f1830cd3b87f5c10d11 | |
parent | 40aac5fbf7a2f582ecc38d99c67a52e5fefdff17 (diff) | |
download | scummvm-rg350-184aae3c8c863541771fbeb09ce5f1a72ecabb95.tar.gz scummvm-rg350-184aae3c8c863541771fbeb09ce5f1a72ecabb95.tar.bz2 scummvm-rg350-184aae3c8c863541771fbeb09ce5f1a72ecabb95.zip |
Enable alternative palettse for Amiga Monkey Island - Patch ID: 2819787
use tables for palette colors instead of code with constants
svn-id: r43696
-rw-r--r-- | common/endian.h | 302 | ||||
-rw-r--r-- | common/stream.h | 101 | ||||
-rw-r--r-- | engines/saga/animation.cpp | 4 | ||||
-rw-r--r-- | engines/scumm/palette.cpp | 320 | ||||
-rw-r--r-- | engines/scumm/scumm.cpp | 4 | ||||
-rw-r--r-- | engines/scumm/scumm.h | 9 |
6 files changed, 399 insertions, 341 deletions
diff --git a/common/endian.h b/common/endian.h index c889371a2f..2e52af139b 100644 --- a/common/endian.h +++ b/common/endian.h @@ -32,23 +32,47 @@ // Endian conversion functions, macros etc., follow from here! // +// Sanity check +#if !defined(SCUMM_LITTLE_ENDIAN) && !defined(SCUMM_BIG_ENDIAN) +# error No endianness defined +#endif + /** * Swap the bytes in a 32 bit word in order to convert LE encoded data to BE * and vice versa. + * compilerspecific variants come first, fallback last */ -FORCEINLINE uint32 SWAP_BYTES_32(uint32 a) { - return ((a >> 24) & 0x000000FF) | - ((a >> 8) & 0x0000FF00) | - ((a << 8) & 0x00FF0000) | - ((a << 24) & 0xFF000000); -} + +// Test for GCC >= 4.3.0 as this version added the bswap builtin +#if 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); +FORCEINLINE uint16 SWAP_BYTES_16(const uint16 a) { + return (a >> 8) | (a << 8); } @@ -70,25 +94,123 @@ FORCEINLINE uint16 SWAP_BYTES_16(uint16 a) { * For the latter systems we provide the INVERSE_MKID override. */ #if defined(INVERSE_MKID) -#define MKID_BE(a) ((uint32) \ - (((a) >> 24) & 0x000000FF) | \ - (((a) >> 8) & 0x0000FF00) | \ - (((a) << 8) & 0x00FF0000) | \ - (((a) << 24) & 0xFF000000)) +#define MKID_BE(a) ((uint32)( \ + (((a) >> 24) & 0x00FF) | \ + (((a) >> 8) & 0xFF00) | \ + (((a) & 0xFF00) << 8) | \ + (((a) & 0x00FF) << 24) )) #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) + + FORCEINLINE 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]); + } + FORCEINLINE 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) + + FORCEINLINE 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]); + } + FORCEINLINE 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 +224,57 @@ FORCEINLINE uint16 SWAP_BYTES_16(uint16 a) { #define TO_BE_32(a) SWAP_BYTES_32(a) #define TO_BE_16(a) SWAP_BYTES_16(a) +# if defined(SCUMM_NEED_ALIGNMENT) + + FORCEINLINE 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]); + } + FORCEINLINE 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 + + FORCEINLINE uint16 READ_BE_UINT16(const void *ptr) { + return SWAP_BYTES_16(*(const uint16 *)ptr); + } + FORCEINLINE uint32 READ_BE_UINT32(const void *ptr) { + return SWAP_BYTES_32(*(const uint32 *)ptr); + } + FORCEINLINE void WRITE_BE_UINT16(void *ptr, uint16 value) { + *(uint16 *)ptr = SWAP_BYTES_16(value); + } + FORCEINLINE void WRITE_BE_UINT32(void *ptr, uint32 value) { + *(uint32 *)ptr = SWAP_BYTES_32(value); + } + +# endif // if defined(SCUMM_NEED_ALIGNMENT) + #elif defined(SCUMM_BIG_ENDIAN) + // I thought this would be compiler-specific and not dependent + // on endianess after the comments above? #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 +288,55 @@ FORCEINLINE uint16 SWAP_BYTES_16(uint16 a) { #define TO_BE_32(a) ((uint32)(a)) #define TO_BE_16(a) ((uint16)(a)) -#else - - #error No endianness defined - - -#endif - +# if defined(SCUMM_NEED_ALIGNMENT) -#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]; + 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); + 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 +# else + FORCEINLINE uint16 READ_LE_UINT16(const void *ptr) { - return *(const uint16 *)(ptr); + return SWAP_BYTES_16(*(const uint16 *)ptr); } FORCEINLINE uint32 READ_LE_UINT32(const void *ptr) { - return *(const uint32 *)(ptr); + return SWAP_BYTES_32(*(const uint32 *)ptr); } FORCEINLINE void WRITE_LE_UINT16(void *ptr, uint16 value) { - *(uint16 *)(ptr) = value; + *(uint16 *)ptr = SWAP_BYTES_16(value); } FORCEINLINE void WRITE_LE_UINT32(void *ptr, uint32 value) { - *(uint32 *)(ptr) = value; + *(uint32 *)ptr = SWAP_BYTES_32(value); } -#endif - + +# endif // if defined(SCUMM_NEED_ALIGNMENT) -#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 +#endif // if defined(SCUMM_LITTLE_ENDIAN) FORCEINLINE uint32 READ_LE_UINT24(const void *ptr) { - const byte *b = (const byte *)ptr; - return (b[2] << 16) + (b[1] << 8) + (b[0]); + 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]); + const uint8 *b = (const uint8 *)ptr; + return (b[0] << 16) | (b[1] << 8) | (b[2]); } - #endif diff --git a/common/stream.h b/common/stream.h index 86e8e71134..9475f6fa2d 100644 --- a/common/stream.h +++ b/common/stream.h @@ -27,6 +27,7 @@ #define COMMON_STREAM_H #include "common/scummsys.h" +#include "common/endian.h" namespace Common { @@ -106,38 +107,38 @@ public: } void writeUint16LE(uint16 value) { - writeByte((byte)(value & 0xff)); - writeByte((byte)(value >> 8)); + value = TO_LE_16(value); + write(&value, 2); } void writeUint32LE(uint32 value) { - writeUint16LE((uint16)(value & 0xffff)); - writeUint16LE((uint16)(value >> 16)); + value = TO_LE_32(value); + write(&value, 4); } void writeUint16BE(uint16 value) { - writeByte((byte)(value >> 8)); - writeByte((byte)(value & 0xff)); + value = TO_BE_16(value); + write(&value, 2); } void writeUint32BE(uint32 value) { - writeUint16BE((uint16)(value >> 16)); - writeUint16BE((uint16)(value & 0xffff)); + value = TO_BE_32(value); + write(&value, 4); } - void writeSint16LE(int16 value) { + FORCEINLINE void writeSint16LE(int16 value) { writeUint16LE((uint16)value); } - void writeSint32LE(int32 value) { + FORCEINLINE void writeSint32LE(int32 value) { writeUint32LE((uint32)value); } - void writeSint16BE(int16 value) { + FORCEINLINE void writeSint16BE(int16 value) { writeUint16BE((uint16)value); } - void writeSint32BE(int32 value) { + FORCEINLINE void writeSint32BE(int32 value) { writeUint32BE((uint32)value); } @@ -188,7 +189,7 @@ public: * calling err() and eos() ). */ byte readByte() { - byte b = 0; + byte b = 0; // FIXME: remove initialisation read(&b, 1); return b; } @@ -200,7 +201,7 @@ public: * calling err() and eos() ). */ int8 readSByte() { - int8 b = 0; + int8 b = 0; // FIXME: remove initialisation read(&b, 1); return b; } @@ -213,9 +214,9 @@ public: * calling err() and eos() ). */ uint16 readUint16LE() { - uint16 a = readByte(); - uint16 b = readByte(); - return a | (b << 8); + uint16 val; + read(&val, 2); + return FROM_LE_16(val); } /** @@ -226,9 +227,9 @@ public: * calling err() and eos() ). */ uint32 readUint32LE() { - uint32 a = readUint16LE(); - uint32 b = readUint16LE(); - return (b << 16) | a; + uint32 val; + read(&val, 4); + return FROM_LE_32(val); } /** @@ -239,9 +240,9 @@ public: * calling err() and eos() ). */ uint16 readUint16BE() { - uint16 b = readByte(); - uint16 a = readByte(); - return a | (b << 8); + uint16 val; + read(&val, 2); + return FROM_BE_16(val); } /** @@ -252,9 +253,9 @@ public: * calling err() and eos() ). */ uint32 readUint32BE() { - uint32 b = readUint16BE(); - uint32 a = readUint16BE(); - return (b << 16) | a; + uint32 val; + read(&val, 4); + return FROM_BE_32(val); } /** @@ -264,7 +265,7 @@ public: * if a read error occurred (for which client code can check by * calling err() and eos() ). */ - int16 readSint16LE() { + FORCEINLINE int16 readSint16LE() { return (int16)readUint16LE(); } @@ -275,7 +276,7 @@ public: * if a read error occurred (for which client code can check by * calling err() and eos() ). */ - int32 readSint32LE() { + FORCEINLINE int32 readSint32LE() { return (int32)readUint32LE(); } @@ -286,7 +287,7 @@ public: * if a read error occurred (for which client code can check by * calling err() and eos() ). */ - int16 readSint16BE() { + FORCEINLINE int16 readSint16BE() { return (int16)readUint16BE(); } @@ -297,7 +298,7 @@ public: * if a read error occurred (for which client code can check by * calling err() and eos() ). */ - int32 readSint32BE() { + FORCEINLINE int32 readSint32BE() { return (int32)readUint32BE(); } @@ -460,26 +461,31 @@ public: * @see SubReadStream */ class SeekableSubReadStreamEndian : public SeekableSubReadStream { -public: - bool _bigEndian; +private: + const bool _bigEndian; +public: SeekableSubReadStreamEndian(SeekableReadStream *parentStream, uint32 begin, uint32 end, bool bigEndian = false, bool disposeParentStream = false) : SeekableSubReadStream(parentStream, begin, end, disposeParentStream), _bigEndian(bigEndian) { } - inline uint16 readUint16() { - return (_bigEndian) ? readUint16BE() : readUint16LE(); + uint16 readUint16() { + uint16 val; + read(&val, 2); + return (_bigEndian) ? TO_BE_16(val) : TO_LE_16(val); } - inline uint32 readUint32() { - return (_bigEndian) ? readUint32BE() : readUint32LE(); + uint32 readUint32() { + uint32 val; + read(&val, 4); + return (_bigEndian) ? TO_BE_32(val) : TO_LE_32(val); } - inline int16 readSint16() { + FORCEINLINE int16 readSint16() { return (int16)readUint16(); } - inline int32 readSint32() { + FORCEINLINE int32 readSint32() { return (int32)readUint32(); } }; @@ -582,23 +588,28 @@ public: */ class MemoryReadStreamEndian : public Common::MemoryReadStream { private: + const bool _bigEndian; + public: - bool _bigEndian; MemoryReadStreamEndian(const byte *buf, uint32 len, bool bigEndian = false) : MemoryReadStream(buf, len), _bigEndian(bigEndian) {} - inline uint16 readUint16() { - return (_bigEndian) ? readUint16BE() : readUint16LE(); + uint16 readUint16() { + uint16 val; + read(&val, 2); + return (_bigEndian) ? TO_BE_16(val) : TO_LE_16(val); } - inline uint32 readUint32() { - return (_bigEndian) ? readUint32BE() : readUint32LE(); + uint32 readUint32() { + uint32 val; + read(&val, 4); + return (_bigEndian) ? TO_BE_32(val) : TO_LE_32(val); } - inline int16 readSint16() { + FORCEINLINE int16 readSint16() { return (int16)readUint16(); } - inline int32 readSint32() { + FORCEINLINE int32 readSint32() { return (int32)readUint32(); } }; diff --git a/engines/saga/animation.cpp b/engines/saga/animation.cpp index 0d298bf96a..95a850cfe2 100644 --- a/engines/saga/animation.cpp +++ b/engines/saga/animation.cpp @@ -826,12 +826,10 @@ int Anim::fillFrameOffsets(AnimationData *anim, bool reallyFill) { int i; bool longData = isLongData(); - MemoryReadStreamEndian readS(anim->resourceData, anim->resourceLength, _vm->isBigEndian()); + MemoryReadStreamEndian readS(anim->resourceData, anim->resourceLength, !_vm->isBigEndian()); // RLE has inversion BE<>LE readS.seek(12); - readS._bigEndian = !_vm->isBigEndian(); // RLE has inversion BE<>LE - while (readS.pos() != readS.size()) { if (reallyFill) { anim->frameOffsets[currentFrame] = readS.pos(); diff --git a/engines/scumm/palette.cpp b/engines/scumm/palette.cpp index a596cc5b1a..2fe3f34530 100644 --- a/engines/scumm/palette.cpp +++ b/engines/scumm/palette.cpp @@ -55,230 +55,155 @@ uint16 ScummEngine::get16BitColor(uint8 r, uint8 g, uint8 b) { } void ScummEngine::resetPalette() { + static const byte tableC64Palette[] = { + 0x00, 0x00, 0x00, 0xFD, 0xFE, 0xFC, 0xBE, 0x1A, 0x24, 0x30, 0xE6, 0xC6, + 0xB4, 0x1A, 0xE2, 0x1F, 0xD2, 0x1E, 0x21, 0x1B, 0xAE, 0xDF, 0xF6, 0x0A, + 0xB8, 0x41, 0x04, 0x6A, 0x33, 0x04, 0xFE, 0x4A, 0x57, 0x42, 0x45, 0x40, + 0x70, 0x74, 0x6F, 0x59, 0xFE, 0x59, 0x5F, 0x53, 0xFE, 0xA4, 0xA7, 0xA2, + + // Use 17 color table for v1 games to allow correct color for inventory and + // sentence line. Original games used some kind of dynamic color table + // remapping between rooms. + 0xFF, 0x55, 0xFF + }; + + static const byte tableNESPalette[] = { + /* 0x1D */ + 0x00, 0x00, 0x00, 0x00, 0x24, 0x92, 0x00, 0x00, 0xDB, 0x6D, 0x49, 0xDB, + 0x92, 0x00, 0x6D, 0xB6, 0x00, 0x6D, 0xB6, 0x24, 0x00, 0x92, 0x49, 0x00, + 0x6D, 0x49, 0x00, 0x24, 0x49, 0x00, 0x00, 0x6D, 0x24, 0x00, 0x92, 0x00, + 0x00, 0x49, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0xB6, 0xB6, 0xB6, 0x00, 0x6D, 0xDB, 0x00, 0x49, 0xFF, 0x92, 0x00, 0xFF, + 0xB6, 0x00, 0xFF, 0xFF, 0x00, 0x92, 0xFF, 0x00, 0x00, 0xDB, 0x6D, 0x00, + 0x92, 0x6D, 0x00, 0x24, 0x92, 0x00, 0x00, 0x92, 0x00, 0x00, 0xB6, 0x6D, + /* 0x00 */ + 0x00, 0x92, 0x92, 0x6D, 0x6D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0xFF, 0xFF, 0xFF, 0x6D, 0xB6, 0xFF, 0x92, 0x92, 0xFF, 0xDB, 0x6D, 0xFF, + 0xFF, 0x00, 0xFF, 0xFF, 0x6D, 0xFF, 0xFF, 0x92, 0x00, 0xFF, 0xB6, 0x00, + 0xDB, 0xDB, 0x00, 0x6D, 0xDB, 0x00, 0x00, 0xFF, 0x00, 0x49, 0xFF, 0xDB, + 0x00, 0xFF, 0xFF, 0x49, 0x49, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0xFF, 0xFF, 0xFF, 0xB6, 0xDB, 0xFF, 0xDB, 0xB6, 0xFF, 0xFF, 0xB6, 0xFF, + 0xFF, 0x92, 0xFF, 0xFF, 0xB6, 0xB6, 0xFF, 0xDB, 0x92, 0xFF, 0xFF, 0x49, + 0xFF, 0xFF, 0x6D, 0xB6, 0xFF, 0x49, 0x92, 0xFF, 0x6D, 0x49, 0xFF, 0xDB, + 0x92, 0xDB, 0xFF, 0x92, 0x92, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + static const byte tableAmigaPalette[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB, 0x00, 0xBB, 0x00, 0x00, 0xBB, 0xBB, + 0xBB, 0x00, 0x00, 0xBB, 0x00, 0xBB, 0xBB, 0x77, 0x00, 0xBB, 0xBB, 0xBB, + 0x77, 0x77, 0x77, 0x77, 0x77, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0x88, 0x88, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF + }; + + static const byte tableAmigaMIPalette[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x88, 0x22, 0x00, 0x66, 0x77, + 0xBB, 0x66, 0x66, 0xAA, 0x22, 0xAA, 0x88, 0x55, 0x22, 0x77, 0x77, 0x77, + 0x33, 0x33, 0x33, 0x22, 0x55, 0xDD, 0x22, 0xDD, 0x44, 0x00, 0xCC, 0xFF, + 0xFF, 0x99, 0x99, 0xFF, 0x55, 0xFF, 0xFF, 0xFF, 0x77, 0xFF, 0xFF, 0xFF + }; + + static const byte tableEGAPalette[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0x00, 0xAA, 0xAA, + 0xAA, 0x00, 0x00, 0xAA, 0x00, 0xAA, 0xAA, 0x55, 0x00, 0xAA, 0xAA, 0xAA, + 0x55, 0x55, 0x55, 0x55, 0x55, 0xFF, 0x55, 0xFF, 0x55, 0x55, 0xFF, 0xFF, + 0xFF, 0x55, 0x55, 0xFF, 0x55, 0xFF, 0xFF, 0xFF, 0x55, 0xFF, 0xFF, 0xFF + }; + + static const byte tableV1Palette[] = { + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xAA, 0x00, 0x00, 0x00, 0xAA, 0xAA, + 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xAA, 0xFF, 0xFF, 0x55, + 0xFF, 0x55, 0x55, 0xAA, 0x55, 0x00, 0xFF, 0x55, 0x55, 0x55, 0x55, 0x55, + 0xAA, 0xAA, 0xAA, 0x55, 0xFF, 0x55, 0x55, 0x55, 0xFF, 0x55, 0x55, 0x55, + + 0xFF, 0x55, 0xFF + }; + + static const byte tableCGAPalette[] = { + 0x00, 0x00, 0x00, 0x00, 0xA8, 0xA8, 0xA8, 0x00, 0xA8, 0xA8, 0xA8, 0xA8 + }; + + static const byte tableHercAPalette[] = { + 0x00, 0x00, 0x00, 0xAE, 0x69, 0x38 + }; + + static const byte tableHercGPalette[] = { + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00 + }; + if (_game.version <= 1) { if (_game.platform == Common::kPlatformApple2GS) { // TODO: unique palette? - setC64Palette(); + setPaletteFromTable(tableC64Palette, sizeof(tableC64Palette) / 3); } else if (_game.platform == Common::kPlatformC64) { - setC64Palette(); + setPaletteFromTable(tableC64Palette, sizeof(tableC64Palette) / 3); } else if (_game.platform == Common::kPlatformNES) { - setNESPalette(); + setPaletteFromTable(tableNESPalette, sizeof(tableNESPalette) / 3); } else { - setV1Palette(); + setPaletteFromTable(tableV1Palette, sizeof(tableV1Palette) / 3); + if (_game.id == GID_ZAK) + setPalColor(15, 170, 170, 170); } } else if (_game.features & GF_16COLOR) { + bool setupCursor = false; + switch (_renderMode) { case Common::kRenderEGA: - setEGAPalette(); + setPaletteFromTable(tableEGAPalette, sizeof(tableEGAPalette) / 3); break; case Common::kRenderAmiga: - setAmigaPalette(); + setPaletteFromTable(tableAmigaPalette, sizeof(tableAmigaPalette) / 3); break; case Common::kRenderCGA: - setCGAPalette(); + setPaletteFromTable(tableCGAPalette, sizeof(tableCGAPalette) / 3); + setupCursor = true; break; case Common::kRenderHercA: + setPaletteFromTable(tableHercAPalette, sizeof(tableHercAPalette) / 3); + setupCursor = true; + break; + case Common::kRenderHercG: - setHercPalette(); + setPaletteFromTable(tableHercGPalette, sizeof(tableHercGPalette) / 3); + setupCursor = true; break; default: if ((_game.platform == Common::kPlatformAmiga) || (_game.platform == Common::kPlatformAtariST)) - setAmigaPalette(); + setPaletteFromTable(tableAmigaPalette, sizeof(tableAmigaPalette) / 3); else - setEGAPalette(); + setPaletteFromTable(tableEGAPalette, sizeof(tableEGAPalette) / 3); + } + if (setupCursor) { + // Setup cursor palette + setPalColor( 7, 170, 170, 170); + setPalColor( 8, 85, 85, 85); + setPalColor(15, 255, 255, 255); } - } else - setDirtyColors(0, 255); -} - -void ScummEngine::setC64Palette() { - setPalColor( 0, 0x00, 0x00, 0x00); - setPalColor( 1, 0xFD, 0xFE, 0xFC); - setPalColor( 2, 0xBE, 0x1A, 0x24); - setPalColor( 3, 0x30, 0xE6, 0xC6); - setPalColor( 4, 0xB4, 0x1A, 0xE2); - setPalColor( 5, 0x1F, 0xD2, 0x1E); - setPalColor( 6, 0x21, 0x1B, 0xAE); - setPalColor( 7, 0xDF, 0xF6, 0x0A); - setPalColor( 8, 0xB8, 0x41, 0x04); - setPalColor( 9, 0x6A, 0x33, 0x04); - setPalColor(10, 0xFE, 0x4A, 0x57); - setPalColor(11, 0x42, 0x45, 0x40); - setPalColor(12, 0x70, 0x74, 0x6F); - setPalColor(13, 0x59, 0xFE, 0x59); - setPalColor(14, 0x5F, 0x53, 0xFE); - setPalColor(15, 0xA4, 0xA7, 0xA2); - - // Use 17 color table for v1 games to allow correct color for inventory and - // sentence line. Original games used some kind of dynamic color table - // remapping between rooms. - setPalColor(16, 255, 85, 255); -} - -void ScummEngine::setNESPalette() { - setPalColor(0x00,0x00,0x00,0x00); // 0x1D - setPalColor(0x01,0x00,0x24,0x92); - setPalColor(0x02,0x00,0x00,0xDB); - setPalColor(0x03,0x6D,0x49,0xDB); - setPalColor(0x04,0x92,0x00,0x6D); - setPalColor(0x05,0xB6,0x00,0x6D); - setPalColor(0x06,0xB6,0x24,0x00); - setPalColor(0x07,0x92,0x49,0x00); - setPalColor(0x08,0x6D,0x49,0x00); - setPalColor(0x09,0x24,0x49,0x00); - setPalColor(0x0A,0x00,0x6D,0x24); - setPalColor(0x0B,0x00,0x92,0x00); - setPalColor(0x0C,0x00,0x49,0x49); - setPalColor(0x0D,0x00,0x00,0x00); - setPalColor(0x0E,0x00,0x00,0x00); - setPalColor(0x0F,0x00,0x00,0x00); - - setPalColor(0x10,0xB6,0xB6,0xB6); - setPalColor(0x11,0x00,0x6D,0xDB); - setPalColor(0x12,0x00,0x49,0xFF); - setPalColor(0x13,0x92,0x00,0xFF); - setPalColor(0x14,0xB6,0x00,0xFF); - setPalColor(0x15,0xFF,0x00,0x92); - setPalColor(0x16,0xFF,0x00,0x00); - setPalColor(0x17,0xDB,0x6D,0x00); - setPalColor(0x18,0x92,0x6D,0x00); - setPalColor(0x19,0x24,0x92,0x00); - setPalColor(0x1A,0x00,0x92,0x00); - setPalColor(0x1B,0x00,0xB6,0x6D); - setPalColor(0x1C,0x00,0x92,0x92); - setPalColor(0x1D,0x6D,0x6D,0x6D); // 0x00 - setPalColor(0x1E,0x00,0x00,0x00); - setPalColor(0x1F,0x00,0x00,0x00); - - setPalColor(0x20,0xFF,0xFF,0xFF); - setPalColor(0x21,0x6D,0xB6,0xFF); - setPalColor(0x22,0x92,0x92,0xFF); - setPalColor(0x23,0xDB,0x6D,0xFF); - setPalColor(0x24,0xFF,0x00,0xFF); - setPalColor(0x25,0xFF,0x6D,0xFF); - setPalColor(0x26,0xFF,0x92,0x00); - setPalColor(0x27,0xFF,0xB6,0x00); - setPalColor(0x28,0xDB,0xDB,0x00); - setPalColor(0x29,0x6D,0xDB,0x00); - setPalColor(0x2A,0x00,0xFF,0x00); - setPalColor(0x2B,0x49,0xFF,0xDB); - setPalColor(0x2C,0x00,0xFF,0xFF); - setPalColor(0x2D,0x49,0x49,0x49); - setPalColor(0x2E,0x00,0x00,0x00); - setPalColor(0x2F,0x00,0x00,0x00); - - setPalColor(0x30,0xFF,0xFF,0xFF); - setPalColor(0x31,0xB6,0xDB,0xFF); - setPalColor(0x32,0xDB,0xB6,0xFF); - setPalColor(0x33,0xFF,0xB6,0xFF); - setPalColor(0x34,0xFF,0x92,0xFF); - setPalColor(0x35,0xFF,0xB6,0xB6); - setPalColor(0x36,0xFF,0xDB,0x92); - setPalColor(0x37,0xFF,0xFF,0x49); - setPalColor(0x38,0xFF,0xFF,0x6D); - setPalColor(0x39,0xB6,0xFF,0x49); - setPalColor(0x3A,0x92,0xFF,0x6D); - setPalColor(0x3B,0x49,0xFF,0xDB); - setPalColor(0x3C,0x92,0xDB,0xFF); - setPalColor(0x3D,0x92,0x92,0x92); - setPalColor(0x3E,0x00,0x00,0x00); - setPalColor(0x3F,0x00,0x00,0x00); -} - -void ScummEngine::setAmigaPalette() { - setPalColor( 0, 0, 0, 0); - setPalColor( 1, 0, 0, 187); - setPalColor( 2, 0, 187, 0); - setPalColor( 3, 0, 187, 187); - setPalColor( 4, 187, 0, 0); - setPalColor( 5, 187, 0, 187); - setPalColor( 6, 187, 119, 0); - setPalColor( 7, 187, 187, 187); - setPalColor( 8, 119, 119, 119); - setPalColor( 9, 119, 119, 255); - setPalColor(10, 0, 255, 0); - setPalColor(11, 0, 255, 255); - setPalColor(12, 255, 136, 136); - setPalColor(13, 255, 0, 255); - setPalColor(14, 255, 255, 0); - setPalColor(15, 255, 255, 255); -} - -void ScummEngine::setHercPalette() { - setPalColor( 0, 0, 0, 0); - - if (_renderMode == Common::kRenderHercA) - setPalColor( 1, 0xAE, 0x69, 0x38); - else - setPalColor( 1, 0x00, 0xFF, 0x00); - - // Setup cursor palette - setPalColor( 7, 170, 170, 170); - setPalColor( 8, 85, 85, 85); - setPalColor(15, 255, 255, 255); -} - -void ScummEngine::setCGAPalette() { - setPalColor( 0, 0, 0, 0); - setPalColor( 1, 0, 168, 168); - setPalColor( 2, 168, 0, 168); - setPalColor( 3, 168, 168, 168); - - // Setup cursor palette - setPalColor( 7, 170, 170, 170); - setPalColor( 8, 85, 85, 85); - setPalColor(15, 255, 255, 255); -} -void ScummEngine::setEGAPalette() { - setPalColor( 0, 0, 0, 0); - setPalColor( 1, 0, 0, 170); - setPalColor( 2, 0, 170, 0); - setPalColor( 3, 0, 170, 170); - setPalColor( 4, 170, 0, 0); - setPalColor( 5, 170, 0, 170); - setPalColor( 6, 170, 85, 0); - setPalColor( 7, 170, 170, 170); - setPalColor( 8, 85, 85, 85); - setPalColor( 9, 85, 85, 255); - setPalColor(10, 85, 255, 85); - setPalColor(11, 85, 255, 255); - setPalColor(12, 255, 85, 85); - setPalColor(13, 255, 85, 255); - setPalColor(14, 255, 255, 85); - setPalColor(15, 255, 255, 255); + } else { + if ((_game.platform == Common::kPlatformAmiga) && _game.version == 4) { + // if rendermode is set to EGA we use the full palette from the resources + // else we initialise and then lock down the first 16 colors. + if (_renderMode != Common::kRenderEGA) + setPaletteFromTable(tableAmigaMIPalette, sizeof(tableAmigaMIPalette) / 3); + } + setDirtyColors(0, 255); + } } -void ScummEngine::setV1Palette() { - setPalColor( 0, 0, 0, 0); - setPalColor( 1, 255, 255, 255); - setPalColor( 2, 170, 0, 0); - setPalColor( 3, 0, 170, 170); - setPalColor( 4, 170, 0, 170); - setPalColor( 5, 0, 170, 0); - setPalColor( 6, 0, 0, 170); - setPalColor( 7, 255, 255, 85); - setPalColor( 8, 255, 85, 85); - setPalColor( 9, 170, 85, 0); - setPalColor(10, 255, 85, 85); - setPalColor(11, 85, 85, 85); - setPalColor(12, 170, 170, 170); - setPalColor(13, 85, 255, 85); - setPalColor(14, 85, 85, 255); - - if (_game.id == GID_ZAK) - setPalColor(15, 170, 170, 170); - else - setPalColor(15, 85, 85, 85); - - setPalColor(16, 255, 85, 255); +void ScummEngine::setPaletteFromTable(const byte *ptr, int numcolor, int index) { + for ( ; numcolor > 0; --numcolor, ++index, ptr += 3) + setPalColor( index, ptr[0], ptr[1], ptr[2]); } void ScummEngine::setPaletteFromPtr(const byte *ptr, int numcolor) { + int firstIndex = 0; int i; byte *dest, r, g, b; @@ -298,7 +223,14 @@ void ScummEngine::setPaletteFromPtr(const byte *ptr, int numcolor) { dest = _currentPalette; - for (i = 0; i < numcolor; i++) { + // Test for Amiga Monkey Island and EGA Mode unset, if true then skip the first 16 colors. + if ((_game.platform == Common::kPlatformAmiga) && _game.version == 4 && _renderMode != Common::kRenderEGA) { + firstIndex = 16; + dest += 3 * 16; + ptr += 3 * 16; + } + + for (i = firstIndex; i < numcolor; i++) { r = *ptr++; g = *ptr++; b = *ptr++; @@ -323,7 +255,7 @@ void ScummEngine::setPaletteFromPtr(const byte *ptr, int numcolor) { memcpy(_darkenPalette, _currentPalette, 768); } - setDirtyColors(0, numcolor - 1); + setDirtyColors(firstIndex, numcolor - 1); } void ScummEngine::setDirtyColors(int min, int max) { diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 9f3ebb8053..af6b9278c6 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -499,7 +499,9 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) case Common::kRenderCGA: case Common::kRenderEGA: case Common::kRenderAmiga: - if ((_game.version >= 4 && !(_game.features & GF_16COLOR)) || (_game.features & GF_OLD256)) + if ((_game.version >= 4 && !(_game.features & GF_16COLOR) + && !(_game.platform == Common::kPlatformAmiga && _renderMode == Common::kRenderEGA)) + || (_game.features & GF_OLD256)) _renderMode = Common::kRenderDefault; break; diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index 7d2bf3336a..6866b17668 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -1029,14 +1029,7 @@ protected: const byte *getPalettePtr(int palindex, int room); - void setC64Palette(); - void setNESPalette(); - void setAmigaPalette(); - void setHercPalette(); - void setCGAPalette(); - void setEGAPalette(); - void setV1Palette(); - + void setPaletteFromTable(const byte *ptr, int numcolor, int firstIndex = 0); void resetPalette(); void setCurrentPalette(int pal); |