aboutsummaryrefslogtreecommitdiff
path: root/engines/sword2/palette.cpp
diff options
context:
space:
mode:
authorMax Horn2006-02-11 22:45:04 +0000
committerMax Horn2006-02-11 22:45:04 +0000
commit26ee630756ebdd7c96bccede0881a8c8b98e8f2b (patch)
tree26e378d5cf990a2b81c2c96e9e683a7f333b62e8 /engines/sword2/palette.cpp
parent2a9a0d4211b1ea5723f1409d91cb95de8984429e (diff)
downloadscummvm-rg350-26ee630756ebdd7c96bccede0881a8c8b98e8f2b.tar.gz
scummvm-rg350-26ee630756ebdd7c96bccede0881a8c8b98e8f2b.tar.bz2
scummvm-rg350-26ee630756ebdd7c96bccede0881a8c8b98e8f2b.zip
Moved engines to the new engines/ directory
svn-id: r20582
Diffstat (limited to 'engines/sword2/palette.cpp')
-rw-r--r--engines/sword2/palette.cpp267
1 files changed, 267 insertions, 0 deletions
diff --git a/engines/sword2/palette.cpp b/engines/sword2/palette.cpp
new file mode 100644
index 0000000000..0b6b7a8ca2
--- /dev/null
+++ b/engines/sword2/palette.cpp
@@ -0,0 +1,267 @@
+/* Copyright (C) 1994-1998 Revolution Software Ltd.
+ * Copyright (C) 2003-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#include "common/stdafx.h"
+#include "common/system.h"
+#include "sword2/sword2.h"
+#include "sword2/defs.h"
+#include "sword2/logic.h"
+#include "sword2/resman.h"
+
+namespace Sword2 {
+
+/**
+ * Start layer palette fading up
+ */
+
+void Screen::startNewPalette() {
+ // If the screen is still fading down then wait for black - could
+ // happen when everythings cached into a large memory model
+ waitForFade();
+
+ byte *screenFile = _vm->_resman->openResource(_thisScreen.background_layer_id);
+
+ memcpy(_paletteMatch, _vm->fetchPaletteMatchTable(screenFile), PALTABLESIZE);
+ setPalette(0, 256, _vm->fetchPalette(screenFile), RDPAL_FADE);
+
+ // Indicating that it's a screen palette
+ _lastPaletteRes = 0;
+
+ _vm->_resman->closeResource(_thisScreen.background_layer_id);
+ fadeUp();
+ _thisScreen.new_palette = 0;
+}
+
+void Screen::setFullPalette(int32 palRes) {
+ // fudge for hut interior
+ // - unpausing should restore last palette as normal (could be screen
+ // palette or 'dark_palette_13')
+ // - but restoring the screen palette after 'dark_palette_13' should
+ // now work properly too!
+
+ // "Hut interior" refers to the watchman's hut in Marseille, and this
+ // is apparently needed for the palette to be restored properly when
+ // you turn the light off. (I didn't even notice the light switch!)
+
+ if (_vm->_logic->readVar(LOCATION) == 13) {
+ // unpausing
+ if (palRes == -1) {
+ // restore whatever palette was last set (screen
+ // palette or 'dark_palette_13')
+ palRes = _lastPaletteRes;
+ }
+ } else {
+ // check if we're just restoring the current screen palette
+ // because we might actually need to use a separate palette
+ // file anyway eg. for pausing & unpausing during the eclipse
+
+ // unpausing (fudged for location 13)
+ if (palRes == -1) {
+ // we really meant '0'
+ palRes = 0;
+ }
+
+ if (palRes == 0 && _lastPaletteRes)
+ palRes = _lastPaletteRes;
+ }
+
+ // If non-zero, set palette to this separate palette file. Otherwise,
+ // set palette to current screen palette.
+
+ if (palRes) {
+ byte *pal = _vm->_resman->openResource(palRes);
+
+ assert(_vm->_resman->fetchType(pal) == PALETTE_FILE);
+
+ pal += ResHeader::size();
+
+ // always set colour 0 to black because most background screen
+ // palettes have a bright colour 0 although it should come out
+ // as black in the game!
+
+ pal[0] = 0;
+ pal[1] = 0;
+ pal[2] = 0;
+ pal[3] = 0;
+
+ setPalette(0, 256, pal, RDPAL_INSTANT);
+ _vm->_resman->closeResource(palRes);
+ } else {
+ if (_thisScreen.background_layer_id) {
+ byte *data = _vm->_resman->openResource(_thisScreen.background_layer_id);
+ memcpy(_paletteMatch, _vm->fetchPaletteMatchTable(data), PALTABLESIZE);
+ setPalette(0, 256, _vm->fetchPalette(data), RDPAL_INSTANT);
+ _vm->_resman->closeResource(_thisScreen.background_layer_id);
+ } else
+ error("setFullPalette(0) called, but no current screen available!");
+ }
+
+ if (palRes != CONTROL_PANEL_PALETTE)
+ _lastPaletteRes = palRes;
+}
+
+/**
+ * Matches a colour triplet to a palette index.
+ * @param r red colour component
+ * @param g green colour component
+ * @param b blue colour component
+ * @return the palette index of the closest matching colour in the palette
+ */
+
+// FIXME: This used to be inlined - probably a good idea - but the
+// linker complained when I tried to use it in sprite.cpp.
+
+uint8 Screen::quickMatch(uint8 r, uint8 g, uint8 b) {
+ return _paletteMatch[((int32)(r >> 2) << 12) + ((int32)(g >> 2) << 6) + (b >> 2)];
+}
+
+/**
+ * Sets the palette.
+ * @param startEntry the first colour entry to set
+ * @param noEntries the number of colour entries to set
+ * @param colourTable the new colour entries
+ * @param fadeNow whether to perform the change immediately or delayed
+ */
+
+void Screen::setPalette(int16 startEntry, int16 noEntries, byte *colourTable, uint8 fadeNow) {
+ assert(noEntries > 0);
+
+ memcpy(&_palette[4 * startEntry], colourTable, noEntries * 4);
+
+ if (fadeNow == RDPAL_INSTANT) {
+ _vm->_system->setPalette(_palette, startEntry, noEntries);
+ setNeedFullRedraw();
+ }
+}
+
+void Screen::dimPalette() {
+ byte *p = _palette;
+
+ for (int i = 0; i < 256; i++) {
+ p[i * 4 + 0] /= 2;
+ p[i * 4 + 1] /= 2;
+ p[i * 4 + 2] /= 2;
+ }
+
+ _vm->_system->setPalette(p, 0, 256);
+ setNeedFullRedraw();
+}
+
+/**
+ * Fades the palette up from black to the current palette.
+ * @param time the time it will take the palette to fade up
+ */
+
+int32 Screen::fadeUp(float time) {
+ if (getFadeStatus() != RDFADE_BLACK && getFadeStatus() != RDFADE_NONE)
+ return RDERR_FADEINCOMPLETE;
+
+ _fadeTotalTime = (int32)(time * 1000);
+ _fadeStatus = RDFADE_UP;
+ _fadeStartTime = _vm->_system->getMillis();
+
+ return RD_OK;
+}
+
+/**
+ * Fades the palette down to black from the current palette.
+ * @param time the time it will take the palette to fade down
+ */
+
+int32 Screen::fadeDown(float time) {
+ if (getFadeStatus() != RDFADE_BLACK && getFadeStatus() != RDFADE_NONE)
+ return RDERR_FADEINCOMPLETE;
+
+ _fadeTotalTime = (int32)(time * 1000);
+ _fadeStatus = RDFADE_DOWN;
+ _fadeStartTime = _vm->_system->getMillis();
+
+ return RD_OK;
+}
+
+/**
+ * Get the current fade status
+ * @return RDFADE_UP (fading up), RDFADE_DOWN (fading down), RDFADE_NONE
+ * (not faded), or RDFADE_BLACK (completely faded down)
+ */
+
+uint8 Screen::getFadeStatus() {
+ return _fadeStatus;
+}
+
+void Screen::waitForFade() {
+ while (getFadeStatus() != RDFADE_NONE && getFadeStatus() != RDFADE_BLACK && !_vm->_quit) {
+ updateDisplay();
+ _vm->_system->delayMillis(20);
+ }
+}
+
+void Screen::fadeServer() {
+ static int32 previousTime = 0;
+ byte fadePalette[256 * 4];
+ byte *newPalette = fadePalette;
+ int32 currentTime;
+ int16 fadeMultiplier;
+ int16 i;
+
+ // If we're not in the process of fading, do nothing.
+ if (getFadeStatus() != RDFADE_UP && getFadeStatus() != RDFADE_DOWN)
+ return;
+
+ // I don't know if this is necessary, but let's limit how often the
+ // palette is updated, just to be safe.
+ currentTime = _vm->_system->getMillis();
+ if (currentTime - previousTime <= 25)
+ return;
+
+ previousTime = currentTime;
+
+ if (getFadeStatus() == RDFADE_UP) {
+ if (currentTime >= _fadeStartTime + _fadeTotalTime) {
+ _fadeStatus = RDFADE_NONE;
+ newPalette = _palette;
+ } else {
+ fadeMultiplier = (int16)(((int32)(currentTime - _fadeStartTime) * 256) / _fadeTotalTime);
+ for (i = 0; i < 256; i++) {
+ newPalette[i * 4 + 0] = (_palette[i * 4 + 0] * fadeMultiplier) >> 8;
+ newPalette[i * 4 + 1] = (_palette[i * 4 + 1] * fadeMultiplier) >> 8;
+ newPalette[i * 4 + 2] = (_palette[i * 4 + 2] * fadeMultiplier) >> 8;
+ }
+ }
+ } else {
+ if (currentTime >= _fadeStartTime + _fadeTotalTime) {
+ _fadeStatus = RDFADE_BLACK;
+ memset(newPalette, 0, sizeof(fadePalette));
+ } else {
+ fadeMultiplier = (int16)(((int32)(_fadeTotalTime - (currentTime - _fadeStartTime)) * 256) / _fadeTotalTime);
+ for (i = 0; i < 256; i++) {
+ newPalette[i * 4 + 0] = (_palette[i * 4 + 0] * fadeMultiplier) >> 8;
+ newPalette[i * 4 + 1] = (_palette[i * 4 + 1] * fadeMultiplier) >> 8;
+ newPalette[i * 4 + 2] = (_palette[i * 4 + 2] * fadeMultiplier) >> 8;
+ }
+ }
+ }
+
+ _vm->_system->setPalette(newPalette, 0, 256);
+ setNeedFullRedraw();
+}
+
+} // End of namespace Sword2