diff options
-rw-r--r-- | engines/parallaction/callables_ns.cpp | 31 | ||||
-rw-r--r-- | engines/parallaction/disk_ns.cpp | 24 | ||||
-rw-r--r-- | engines/parallaction/graphics.cpp | 239 | ||||
-rw-r--r-- | engines/parallaction/graphics.h | 41 | ||||
-rw-r--r-- | engines/parallaction/location.cpp | 15 |
5 files changed, 202 insertions, 148 deletions
diff --git a/engines/parallaction/callables_ns.cpp b/engines/parallaction/callables_ns.cpp index 20535fc388..26b472345e 100644 --- a/engines/parallaction/callables_ns.cpp +++ b/engines/parallaction/callables_ns.cpp @@ -199,13 +199,11 @@ void Parallaction_ns::_c_score(void *parm) { void Parallaction_ns::_c_fade(void *parm) { - _gfx->setBlackPalette(); - - Gfx::Palette pal; - memset(pal, 0, sizeof(Gfx::Palette)); + Palette pal; + _gfx->setPalette(pal); for (uint16 _di = 0; _di < 64; _di++) { - _gfx->fadePalette(pal, _gfx->_palette, 1); + pal.fadeTo(_gfx->_palette, 1); _gfx->setPalette(pal); _gfx->updateScreen(); @@ -340,11 +338,11 @@ void Parallaction_ns::_c_endComment(void *param) { _gfx->showLocationComment(_location._endComment, true); - Gfx::Palette pal; - _gfx->makeGrayscalePalette(pal); + Palette pal(_gfx->_palette); + pal.makeGrayscale(); for (uint di = 0; di < 64; di++) { - _gfx->fadePalette(_gfx->_palette, pal, 1); + _gfx->_palette.fadeTo(pal, 1); _gfx->setPalette(_gfx->_palette); _gfx->updateScreen(); @@ -358,24 +356,19 @@ void Parallaction_ns::_c_endComment(void *param) { void Parallaction_ns::_c_frankenstein(void *parm) { - Gfx::Palette pal0; - Gfx::Palette pal1; - - for (uint16 i = 0; i <= BASE_PALETTE_COLORS; i++) { - pal0[(i+FIRST_BASE_COLOR)] = _gfx->_palette[i]; - pal0[(i+FIRST_BASE_COLOR)*3+1] = 0; - pal0[(i+FIRST_BASE_COLOR)*3+2] = 0; + Palette pal0(_gfx->_palette); + Palette pal1; - pal1[(i+FIRST_BASE_COLOR)*3+1] = 0; - pal1[(i+FIRST_BASE_COLOR)*3+2] = 0; + for (uint16 i = 0; i <= 32; i++) { + pal0.setEntry(i, -1, 0, 0); // leaves reds unchanged while zeroing other components } for (uint16 _di = 0; _di < 30; _di++) { g_system->delayMillis(20); - _gfx->setPalette(pal0, FIRST_BASE_COLOR, BASE_PALETTE_COLORS); + _gfx->setPalette(pal0); _gfx->updateScreen(); g_system->delayMillis(20); - _gfx->setPalette(pal1, FIRST_BASE_COLOR, BASE_PALETTE_COLORS); + _gfx->setPalette(pal1); _gfx->updateScreen(); } diff --git a/engines/parallaction/disk_ns.cpp b/engines/parallaction/disk_ns.cpp index c111525011..6506ddd2ac 100644 --- a/engines/parallaction/disk_ns.cpp +++ b/engines/parallaction/disk_ns.cpp @@ -564,7 +564,15 @@ void DosDisk_ns::parseDepths(Common::SeekableReadStream &stream) { void DosDisk_ns::parseBackground(Common::SeekableReadStream &stream) { - stream.read(_vm->_gfx->_palette, BASE_PALETTE_SIZE); + byte tmp[3]; + + for (uint i = 0; i < 32; i++) { + tmp[0] = stream.readByte(); + tmp[1] = stream.readByte(); + tmp[2] = stream.readByte(); + _vm->_gfx->_palette.setEntry(i, tmp[0], tmp[1], tmp[2]); + } + _vm->_gfx->setPalette(_vm->_gfx->_palette); parseDepths(stream); @@ -1189,8 +1197,18 @@ void AmigaDisk_ns::loadBackground(const char *name) { BackgroundDecoder decoder(*s, *surf, pal, _vm->_gfx->_palettefx); decoder.decode(); - for (uint32 i = 0; i < BASE_PALETTE_COLORS * 3; i++) - _vm->_gfx->_palette[i] = pal[i] >> 2; + byte *p = pal; + for (uint i = 0; i < 32; i++) { + byte r = *p >> 2; + p++; + byte g = *p >> 2; + p++; + byte b = *p >> 2; + p++; + _vm->_gfx->_palette.setEntry(i, r, g, b); + + } + free(pal); _vm->_gfx->setPalette(_vm->_gfx->_palette); _vm->_gfx->setBackground(surf); diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp index 15445877eb..f1ad6634e6 100644 --- a/engines/parallaction/graphics.cpp +++ b/engines/parallaction/graphics.cpp @@ -32,6 +32,138 @@ namespace Parallaction { + + +Palette::Palette() { + + int gameType = _vm->getGameType(); + + if (gameType == GType_Nippon) { + _colors = 32; + _hb = (_vm->getPlatform() == Common::kPlatformAmiga); + } else + if (gameType == GType_BRA) { + _colors = 256; + _hb = false; + } else + error("can't create palette for id = '%i'", gameType); + + _size = _colors * 3; + + makeBlack(); +}; + +Palette::Palette(const Palette &pal) { + _colors = pal._colors; + _hb = pal._hb; + _size = pal._size; + memcpy(_data, pal._data, _size); +} + + +void Palette::makeBlack() { + memset(_data, 0, _size); +} + +void Palette::setEntry(uint index, int red, int green, int blue) { + assert(index < _colors); + + if (red >= 0) + _data[index*3] = red & 0xFF; + + if (green >= 0) + _data[index*3+1] = green & 0xFF; + + if (blue >= 0) + _data[index*3+2] = blue & 0xFF; +} + +void Palette::makeGrayscale() { + byte v; + for (uint16 i = 0; i < _colors; i++) { + v = MAX(_data[i*3+1], _data[i*3+2]); + v = MAX(v, _data[i*3]); + setEntry(i, v, v, v); + } +} + +void Palette::fadeTo(const Palette& target, uint step) { + + if (step == 0) + return; + + for (uint16 i = 0; i < _size; i++) { + if (_data[i] == target._data[i]) continue; + + if (_data[i] < target._data[i]) + _data[i] = CLIP(_data[i] + step, (uint)0, (uint)target._data[i]); + else + _data[i] = CLIP(_data[i] - step, (uint)target._data[i], (uint)255); + } + + return; +} + +uint Palette::fillRGBA(byte *rgba) { + + byte r, g, b; + byte *hbPal = rgba + _size; + + for (uint32 i = 0; i < _colors; i++) { + r = (_data[i*3] << 2) | (_data[i*3] >> 4); + g = (_data[i*3+1] << 2) | (_data[i*3+1] >> 4); + b = (_data[i*3+2] << 2) | (_data[i*3+2] >> 4); + + rgba[i*4] = r; + rgba[i*4+1] = g; + rgba[i*4+2] = b; + rgba[i*4+3] = 0; + + if (_hb) { + hbPal[i*4] = r >> 1; + hbPal[i*4+1] = g >> 1; + hbPal[i*4+2] = b >> 1; + hbPal[i*4+3] = 0; + } + + } + + return ((_hb) ? 2 : 1) * _colors; +} + +void Palette::rotate(uint first, uint last, bool forward) { + + byte tmp[3]; + + if (forward) { // forward + + tmp[0] = _data[first * 3]; + tmp[1] = _data[first * 3 + 1]; + tmp[2] = _data[first * 3 + 2]; + + memmove(_data+first*3, _data+(first+1)*3, (last - first)*3); + + _data[last * 3] = tmp[0]; + _data[last * 3 + 1] = tmp[1]; + _data[last * 3 + 2] = tmp[2]; + + } else { // backward + + tmp[0] = _data[last * 3]; + tmp[1] = _data[last * 3 + 1]; + tmp[2] = _data[last * 3 + 2]; + + memmove(_data+(first+1)*3, _data+first*3, (last - first)*3); + + _data[first * 3] = tmp[0]; + _data[first * 3 + 1] = tmp[1]; + _data[first * 3 + 2] = tmp[2]; + + } + +} + + #define BALLOON_TAIL_WIDTH 12 #define BALLOON_TAIL_HEIGHT 10 @@ -104,57 +236,22 @@ void Gfx::showLocationComment(const char *text, bool end) { return; } -void Gfx::setPalette(Palette pal, uint32 first, uint32 num) { -// printf("setPalette(%i, %i)\n", first, num); - - if (first + num > BASE_PALETTE_COLORS) - error("wrong parameters for setPalette()"); - - byte sysBasePal[EHB_PALETTE_COLORS*4]; - byte sysExtraPal[BASE_PALETTE_COLORS*4]; - - byte r, g, b; - uint32 j = 0; - for (uint32 i = first; i < first+num; i++) { - r = (pal[i*3] << 2) | (pal[i*3] >> 4); - g = (pal[i*3+1] << 2) | (pal[i*3+1] >> 4); - b = (pal[i*3+2] << 2) | (pal[i*3+2] >> 4); - - sysBasePal[j*4] = r; - sysBasePal[j*4+1] = g; - sysBasePal[j*4+2] = b; - sysBasePal[j*4+3] = 0; - - if (_vm->getPlatform() == Common::kPlatformAmiga) { - sysExtraPal[j*4] = r >> 1; - sysExtraPal[j*4+1] = g >> 1; - sysExtraPal[j*4+2] = b >> 1; - sysExtraPal[j*4+3] = 0; - } else { - sysExtraPal[j*4] = 0; - sysExtraPal[j*4+1] = 0; - sysExtraPal[j*4+2] = 0; - sysExtraPal[j*4+3] = 0; - } - - j++; - } - - g_system->setPalette(sysBasePal, first, num); - if (_vm->getPlatform() == Common::kPlatformAmiga) - g_system->setPalette(sysExtraPal, first+FIRST_EHB_COLOR, num); +void Gfx::setPalette(Palette pal) { + byte sysPal[256*4]; - return; + uint n = pal.fillRGBA(sysPal); + g_system->setPalette(sysPal, 0, n); } void Gfx::setBlackPalette() { Palette pal; - memset(pal, 0, PALETTE_SIZE); setPalette(pal); } + + void Gfx::animatePalette() { byte tmp[3]; @@ -169,32 +266,7 @@ void Gfx::animatePalette() { _palettefx[i]._timer = 0; // reset timer - if (_palettefx[i]._flags & 2) { // forward - - tmp[0] = _palette[_palettefx[i]._first * 3]; - tmp[1] = _palette[_palettefx[i]._first * 3 + 1]; - tmp[2] = _palette[_palettefx[i]._first * 3 + 2]; - - memmove(_palette+_palettefx[i]._first*3, _palette+(_palettefx[i]._first+1)*3, (_palettefx[i]._last - _palettefx[i]._first)*3); - - _palette[_palettefx[i]._last * 3] = tmp[0]; - _palette[_palettefx[i]._last * 3 + 1] = tmp[1]; - _palette[_palettefx[i]._last * 3 + 2] = tmp[2]; - - } else { // backward - - tmp[0] = _palette[_palettefx[i]._last * 3]; - tmp[1] = _palette[_palettefx[i]._last * 3 + 1]; - tmp[2] = _palette[_palettefx[i]._last * 3 + 2]; - - memmove(_palette+(_palettefx[i]._first+1)*3, _palette+_palettefx[i]._first*3, (_palettefx[i]._last - _palettefx[i]._first)*3); - - _palette[_palettefx[i]._first * 3] = tmp[0]; - _palette[_palettefx[i]._first * 3 + 1] = tmp[1]; - _palette[_palettefx[i]._first * 3 + 2] = tmp[2]; - - } - + _palette.rotate(_palettefx[i]._first, _palettefx[i]._last, (_palettefx[i]._flags & 2) != 0); } setPalette(_palette); @@ -202,39 +274,9 @@ void Gfx::animatePalette() { return; } -void Gfx::makeGrayscalePalette(Palette pal) { - for (uint16 i = 0; i < BASE_PALETTE_COLORS; i++) { - byte max; - max = MAX(_palette[i*3+1], _palette[i*3+2]); - max = MAX(max, _palette[i*3]); - pal[i*3] = max; - pal[i*3+1] = max; - pal[i*3+2] = max; - } - - return; -} - -void Gfx::fadePalette(Palette pal, Palette target, uint step) { - - if (step == 0) - return; - - for (uint16 i = 0; i < BASE_PALETTE_COLORS * 3; i++) { - if (pal[i] == target[i]) continue; - - if (pal[i] < target[i]) - pal[i] = CLIP(pal[i] + step, (uint)0, (uint)target[i]); - else - pal[i] = CLIP(pal[i] - step, (uint)target[i], (uint)255); - - } - - return; -} void Gfx::setHalfbriteMode(bool enable) { #ifdef HALFBRITE @@ -820,11 +862,10 @@ Gfx::Gfx(Parallaction* vm) : _depthMask = 0; - setBlackPalette(); + setPalette(_palette); _bgLayers[0] = _bgLayers[1] = _bgLayers[2] = _bgLayers[3] = 0; - memset(_palette, 0, sizeof(_palette)); memset(_palettefx, 0, sizeof(_palettefx)); initMouse( 0 ); diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h index b959383a43..61df559b64 100644 --- a/engines/parallaction/graphics.h +++ b/engines/parallaction/graphics.h @@ -37,19 +37,6 @@ namespace Parallaction { -#define BASE_PALETTE_COLORS 32 -#define FIRST_BASE_COLOR 0 -#define LAST_BASE_COLOR (FIRST_BASE_COLOR+BASE_PALETTE_COLORS-1) - -#define EHB_PALETTE_COLORS 32 // extra half-brite colors for amiga -#define FIRST_EHB_COLOR (LAST_BASE_COLOR+1) -#define LAST_EHB_COLOR (FIRST_EHB_COLOR+EHB_PALETTE_COLORS-1) - -#define PALETTE_COLORS (BASE_PALETTE_COLORS+EHB_PALETTE_COLORS) - -#define BASE_PALETTE_SIZE BASE_PALETTE_COLORS*3 -#define PALETTE_SIZE PALETTE_COLORS*3 - #define MOUSEARROW_WIDTH 16 #define MOUSEARROW_HEIGHT 16 @@ -173,11 +160,31 @@ public: }; -class Gfx { +class Palette { + + byte _data[768]; + uint _colors; + uint _size; + bool _hb; public: - typedef byte Palette[PALETTE_SIZE]; + Palette(); + Palette(const Palette &pal); + + void makeBlack(); + void setEntries(byte* data, uint first, uint num); + void setEntry(uint index, int red, int green, int blue); + void makeGrayscale(); + void fadeTo(const Palette& target, uint step); + uint fillRGBA(byte *rgba); + void rotate(uint first, uint last, bool forward); +}; + + +class Gfx { + +public: enum Buffers { // bit buffers kBitFront, @@ -220,11 +227,9 @@ public: void floodFill(Gfx::Buffers buffer, const Common::Rect& r, byte color); // palette - void setPalette(Palette palette, uint32 first = FIRST_BASE_COLOR, uint32 num = BASE_PALETTE_COLORS); + void setPalette(Palette palette); void setBlackPalette(); void animatePalette(); - void fadePalette(Palette palette, Palette target, uint step); // fades palette to target palette, with specified step - void makeGrayscalePalette(Palette palette); // transform palette into black and white // amiga specific void setHalfbriteMode(bool enable); diff --git a/engines/parallaction/location.cpp b/engines/parallaction/location.cpp index cd14e0efa2..9961a41652 100644 --- a/engines/parallaction/location.cpp +++ b/engines/parallaction/location.cpp @@ -238,17 +238,14 @@ void Parallaction::parseWalkNodes(Script& script, WalkNodeList &list) { void Parallaction::switchBackground(const char* background, const char* mask) { // printf("switchBackground(%s)", name); - Gfx::Palette pal; + Palette pal; uint16 v2 = 0; if (!scumm_stricmp(background, "final")) { _gfx->clearScreen(Gfx::kBitBack); - for (uint16 _si = 0; _si <= 93; ) { - pal[_si] = v2; - pal[_si+1] = v2; - pal[_si+2] = v2; + for (uint16 _si = 0; _si <= 32; _si++) { + pal.setEntry(_si, v2, v2, v2); v2 += 4; - _si += 3; } g_system->delayMillis(20); @@ -423,8 +420,8 @@ void Parallaction::doLocationEnterTransition() { return; // visited } - byte pal[PALETTE_SIZE]; - _gfx->makeGrayscalePalette(pal); + Palette pal(_gfx->_palette); + pal.makeGrayscale(); _gfx->setPalette(pal); jobRunScripts(NULL, NULL); @@ -441,7 +438,7 @@ void Parallaction::doLocationEnterTransition() { // fades maximum intensity palette towards approximation of main palette for (uint16 _si = 0; _si<6; _si++) { - _gfx->fadePalette(pal, _gfx->_palette, 4); + pal.fadeTo(_gfx->_palette, 4); _gfx->setPalette(pal); waitTime( 1 ); _gfx->updateScreen(); |