/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * 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$ * * Palette Fader and Flasher processes. */ #include "tinsel/pid.h" // list of all process IDs #include "tinsel/sched.h" // scheduler defs #include "tinsel/faders.h" // fader defs #include "tinsel/handle.h" #include "tinsel/palette.h" // Palette Manager defs namespace Tinsel { /** structure used by the "FadeProcess" process */ struct FADE { const long *pColourMultTable; // list of fixed point colour multipliers - terminated with negative entry PALQ *pPalQ; // palette queue entry to fade }; // fixed point fade multiplier tables //const long fadeout[] = {0xf000, 0xd000, 0xb000, 0x9000, 0x7000, 0x5000, 0x3000, 0x1000, 0, -1}; const long fadeout[] = {0xd000, 0xa000, 0x7000, 0x4000, 0x1000, 0, -1}; //const long fadein[] = {0, 0x1000, 0x3000, 0x5000, 0x7000, 0x9000, 0xb000, 0xd000, 0x10000L, -1}; const long fadein[] = {0, 0x1000, 0x4000, 0x7000, 0xa000, 0xd000, 0x10000L, -1}; /** * Scale 'colour' by the fixed point colour multiplier 'colourMult' * @param colour Colour to scale * @param colourMult Fixed point multiplier */ static COLORREF ScaleColour(COLORREF colour, uint32 colourMult) { // apply multiplier to RGB components uint32 red = ((GetRValue(colour) * colourMult) << 8) >> 24; uint32 green = ((GetGValue(colour) * colourMult) << 8) >> 24; uint32 blue = ((GetBValue(colour) * colourMult) << 8) >> 24; // return new colour return RGB(red, green, blue); } /** * Applies the fixed point multiplier 'mult' to all colours in * 'pOrig' to produce 'pNew'. Each colour in the palette will be * multiplied by 'mult'. * @param pNew Pointer to new palette * @param pOrig Pointer to original palette * @param numColours Number of colours in the above palettes * @param mult Fixed point multiplier */ static void FadePalette(COLORREF *pNew, COLORREF *pOrig, int numColours, uint32 mult) { for (int i = 0; i < numColours; i++, pNew++, pOrig++) { // apply multiplier to RGB components *pNew = ScaleColour(*pOrig, mult); } } /** * Process to fade one palette. * A pointer to a 'FADE' structure must be passed to this process when * it is created. */ static void FadeProcess(CORO_PARAM, const void *param) { // COROUTINE CORO_BEGIN_CONTEXT; COLORREF fadeRGB[MAX_COLOURS]; // local copy of palette const long *pColMult; // pointer to colour multiplier table PALETTE *pPalette; // pointer to palette CORO_END_CONTEXT(_ctx); // get the fade data structure - copied to process when it was created FADE *pFade = (FADE *)param; CORO_BEGIN_CODE(_ctx); // get pointer to palette - reduce pointer indirection a bit _ctx->pPalette = (PALETTE *)LockMem(pFade->pPalQ->hPal); for (_ctx->pColMult = pFade->pColourMultTable; *_ctx->pColMult >= 0; _ctx->pColMult++) { // go through all multipliers in table - until a negative entry // fade palette using next multiplier FadePalette(_ctx->fadeRGB, _ctx->pPalette->palRGB, FROM_LE_32(_ctx->pPalette->numColours), (uint32) *_ctx->pColMult); // send new palette to video DAC UpdateDACqueue(pFade->pPalQ->posInDAC, FROM_LE_32(_ctx->pPalette->numColours), _ctx->fadeRGB); // allow time for video DAC to be updated CORO_SLEEP(1); } CORO_END_CODE; } /** * Generic palette fader/unfader. Creates a 'FadeProcess' process * for each palette that is to fade. * @param multTable Fixed point colour multiplier table * @param noFadeTable List of palettes not to fade */ static void Fader(const long multTable[], SCNHANDLE noFadeTable[]) { PALQ *pPal; // palette manager iterator // create a process for each palette in the palette queue for (pPal = GetNextPalette(NULL); pPal != NULL; pPal = GetNextPalette(pPal)) { bool bFade = true; // assume we want to fade this palette // is palette in the list of palettes not to fade if (noFadeTable != NULL) { // there is a list of palettes not to fade for (int i = 0; noFadeTable[i] != 0; i++) { if (pPal->hPal == noFadeTable[i]) { // palette is in the list - dont fade it bFade = false; // leave loop prematurely break; } } } if (bFade) { FADE fade; // fill in FADE struct fade.pColourMultTable = multTable; fade.pPalQ = pPal; // create a fader process for this palette g_scheduler->createProcess(PID_FADER, FadeProcess, (void *)&fade, sizeof(FADE)); } } } /** * Fades a list of palettes down to black. * @param noFadeTable A NULL terminated list of palettes not to fade. */ void FadeOutFast(SCNHANDLE noFadeTable[]) { // call generic fader Fader(fadeout, noFadeTable); } /** * Fades a list of palettes from black to their current colours. * @param noFadeTable A NULL terminated list of palettes not to fade. */ void FadeInFast(SCNHANDLE noFadeTable[]) { // call generic fader Fader(fadein, noFadeTable); } } // end of namespace Tinsel