diff options
Diffstat (limited to 'engines/sci/gui')
-rw-r--r-- | engines/sci/gui/gui.cpp | 91 | ||||
-rw-r--r-- | engines/sci/gui/gui.h | 11 | ||||
-rw-r--r-- | engines/sci/gui/gui_gfx.cpp | 301 | ||||
-rw-r--r-- | engines/sci/gui/gui_gfx.h | 24 | ||||
-rw-r--r-- | engines/sci/gui/gui_helpers.h | 53 | ||||
-rw-r--r-- | engines/sci/gui/gui_palette.cpp | 307 | ||||
-rw-r--r-- | engines/sci/gui/gui_palette.h | 71 | ||||
-rw-r--r-- | engines/sci/gui/gui_picture.cpp | 11 | ||||
-rw-r--r-- | engines/sci/gui/gui_picture.h | 3 | ||||
-rw-r--r-- | engines/sci/gui/gui_screen.cpp | 16 | ||||
-rw-r--r-- | engines/sci/gui/gui_screen.h | 4 | ||||
-rw-r--r-- | engines/sci/gui/gui_view.cpp | 16 | ||||
-rw-r--r-- | engines/sci/gui/gui_view.h | 11 |
13 files changed, 547 insertions, 372 deletions
diff --git a/engines/sci/gui/gui.cpp b/engines/sci/gui/gui.cpp index 2022c9c06c..33189cd015 100644 --- a/engines/sci/gui/gui.cpp +++ b/engines/sci/gui/gui.cpp @@ -23,6 +23,7 @@ * */ +#include "common/timer.h" #include "common/util.h" #include "sci/sci.h" @@ -30,6 +31,7 @@ #include "sci/tools.h" #include "sci/gui/gui.h" #include "sci/gui/gui_screen.h" +#include "sci/gui/gui_palette.h" #include "sci/gui/gui_gfx.h" #include "sci/gui/gui_windowmgr.h" #include "sci/gui/gui_view.h" @@ -40,7 +42,11 @@ namespace Sci { SciGui::SciGui(OSystem *system, EngineState *state, SciGuiScreen *screen) : _system(system), _s(state), _screen(screen) { - _gfx = new SciGuiGfx(_system, _s, _screen); + _picNotValid = 0; + _sysTicks = 0; + + _palette = new SciGuiPalette(_system, _s, this, _screen); + _gfx = new SciGuiGfx(_system, _s, _screen, _palette); _windowMgr = new SciGuiWindowMgr(_s, _gfx); } @@ -48,22 +54,30 @@ SciGui::SciGui() { } SciGui::~SciGui() { + _system->getTimerManager()->removeTimerProc(&timerHandler); +} + +void SciGui::init(bool usesOldGfxFunctions) { + _sysSpeed = 1000000 / 60; + Common::TimerManager *tm = _system->getTimerManager(); + tm->removeTimerProc(&timerHandler); + tm->installTimerProc(&timerHandler, _sysSpeed, this); } -void SciGui::init(bool oldGfxFunctions) { - _usesOldGfxFunctions = oldGfxFunctions; +void SciGui::timerHandler(void *ref) { + ((SciGui *)ref)->_sysTicks++; } int16 SciGui::getTimeTicks() { - return _gfx->_sysTicks; + return _sysTicks; } void SciGui::wait(int16 ticks) { - uint32 waitto = _gfx->_sysTicks + ticks; + uint32 waitto = _sysTicks + ticks; do { //eventMgr->pollEvents(); - _system->delayMillis(_gfx->_sysSpeed >> 11); - } while (_gfx->_sysTicks < waitto); + _system->delayMillis(_sysSpeed >> 11); + } while (_sysTicks < waitto); } void SciGui::setPort(uint16 portPtr) { @@ -256,12 +270,12 @@ void SciGui::drawPicture(GuiResourceId pictureId, uint16 style, uint16 flags, in _screen->copyToScreen(); _gfx->SetPort(oldPort); - _gfx->_picNotValid = true; + _picNotValid = true; } void SciGui::drawCel(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo) { _gfx->drawCel(viewId, loopNo, celNo, leftPos, topPos, priority, paletteNo); - _gfx->setScreenPalette(&_screen->_sysPalette); + _palette->setOnScreen(); _screen->copyToScreen(); } @@ -329,22 +343,22 @@ void SciGui::graphRestoreBox(reg_t handle) { } void SciGui::paletteSet(int resourceNo, int flags) { - _gfx->SetResPalette(resourceNo, flags); + _palette->setFromResource(resourceNo, flags); } int16 SciGui::paletteFind(int r, int g, int b) { - return _gfx->MatchColor(&_screen->_sysPalette, r, g, b) & 0xFF; + return _palette->matchColor(&_palette->_sysPalette, r, g, b) & 0xFF; } void SciGui::paletteSetIntensity(int fromColor, int toColor, int intensity, bool setPalette) { - _gfx->PaletteSetIntensity(fromColor, toColor, intensity, &_screen->_sysPalette); + _palette->setIntensity(fromColor, toColor, intensity, &_palette->_sysPalette); if (setPalette) { - _gfx->setScreenPalette(&_screen->_sysPalette); + _palette->setOnScreen(); } } void SciGui::paletteAnimate(int fromColor, int toColor, int speed) { - _gfx->PaletteAnimate(fromColor, toColor, speed); + _palette->animate(fromColor, toColor, speed); } int16 SciGui::onControl(byte screenMask, Common::Rect rect) { @@ -357,41 +371,39 @@ int16 SciGui::onControl(byte screenMask, Common::Rect rect) { } void SciGui::animate(reg_t listReference, bool cycle, int argc, reg_t *argv) { - bool old_picNotValid = _gfx->_picNotValid; + bool old_picNotValid = _picNotValid; if (listReference.isNull()) { _gfx->AnimateDisposeLastCast(); - if (_gfx->_picNotValid) { + if (_picNotValid) { //(this->*ShowPic)(_showMap, _showStyle); - _gfx->_picNotValid = false; + _picNotValid = 0; } return; } List *list = lookup_list(_s, listReference); - if (!list) { + if (!list) error("kAnimate called with non-list as parameter"); - } - if (cycle) { + if (cycle) _gfx->AnimateInvoke(list, argc, argv); - } GuiPort *oldPort = _gfx->SetPort((GuiPort *)_windowMgr->_picWind); _gfx->AnimateDisposeLastCast(); _gfx->AnimateFill(); - _gfx->AnimateSort(); + // _gfx->AnimateSort(); if (old_picNotValid) { _gfx->AnimateUpdate(); } _gfx->AnimateDrawCels(); - if (_gfx->_picNotValid) { + if (_picNotValid) { //(this->*ShowPic)(_showMap, _showStyle); - _gfx->_picNotValid = false; + _picNotValid = 0; } //_gfx->AnimateUpdateScreen(); @@ -402,7 +414,36 @@ void SciGui::animate(reg_t listReference, bool cycle, int argc, reg_t *argv) { } void SciGui::addToPicList(reg_t listReference, int argc, reg_t *argv) { - // FIXME: port over from gregs engine + List *list; + Common::List<GuiAnimateList> *sortedList; + + _gfx->SetPort((GuiPort *)_windowMgr->_picWind); + + list = lookup_list(_s, listReference); + if (!list) + error("kAddToPic called with non-list as parameter"); + + sortedList = _gfx->AnimateMakeSortedList(list); + +// uint16 szList = list.getSize(); +// HEAPHANDLE*arrObj = new HEAPHANDLE[szList]; +// int16*arrY = new int16[szList]; +// HEAPHANDLE hnode = list.getFirst(); +// sciNode1*pnode; +// +// for (int i = 0; i < szList; i++) { +// pnode = (sciNode1*)heap2Ptr(hnode); +// obj.set(pnode->value); +// arrY[i] = obj.getProperty(3); +//arrZ[i] = obj.getProperty( +// arrObj[i] = pnode->value; +// hnode = pnode->next; +// } +// animSort(arrObj, arrY, szList); + + _picNotValid = 2; + + delete sortedList; } void SciGui::addToPicView(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, int16 leftPos, int16 topPos, int16 priority, int16 control) { diff --git a/engines/sci/gui/gui.h b/engines/sci/gui/gui.h index a12449e5ca..79185deddf 100644 --- a/engines/sci/gui/gui.h +++ b/engines/sci/gui/gui.h @@ -31,6 +31,7 @@ namespace Sci { class SciGuiScreen; +class SciGuiPalette; class SciGuiGfx; class SciGuiresources; class SciGuiWindowMgr; @@ -43,7 +44,7 @@ public: // FIXME: Don't store EngineState virtual void resetEngineState(EngineState *s) { _s = s; } - virtual void init(bool oldGfxFunctions); + virtual void init(bool usesOldGfxFunctions); virtual int16 getTimeTicks(); virtual void wait(int16 ticks); @@ -89,14 +90,20 @@ public: virtual void moveCursor(int16 x, int16 y, int16 scaleFactor = 1); void moveCursor(Common::Point p, int16 scaleFactor = 1) { moveCursor(p.x, p.y, scaleFactor); } + int _picNotValid; // possible values 0, 1 and 2 + private: + static void timerHandler(void*ref); + OSystem *_system; EngineState *_s; SciGuiScreen *_screen; + SciGuiPalette *_palette; SciGuiGfx *_gfx; SciGuiresources *_resources; SciGuiWindowMgr *_windowMgr; - bool _usesOldGfxFunctions; + uint32 _sysTicks; + int32 _sysSpeed; // ticker timer in ms }; } // End of namespace Sci diff --git a/engines/sci/gui/gui_gfx.cpp b/engines/sci/gui/gui_gfx.cpp index 3978c6b8cd..2274a86de4 100644 --- a/engines/sci/gui/gui_gfx.cpp +++ b/engines/sci/gui/gui_gfx.cpp @@ -23,7 +23,6 @@ * */ -#include "common/timer.h" #include "common/util.h" #include "graphics/primitives.h" @@ -34,19 +33,17 @@ #include "sci/gui/gui_picture.h" #include "sci/gui/gui_view.h" #include "sci/gui/gui_screen.h" +#include "sci/gui/gui_palette.h" #include "sci/gui/gui_gfx.h" namespace Sci { -SciGuiGfx::SciGuiGfx(OSystem *system, EngineState *state, SciGuiScreen *screen) - : _system(system), _s(state), _screen(screen) { +SciGuiGfx::SciGuiGfx(OSystem *system, EngineState *state, SciGuiScreen *screen, SciGuiPalette *palette) + : _system(system), _s(state), _screen(screen), _palette(palette) { init(); - initPalette(); - initTimer(); } SciGuiGfx::~SciGuiGfx() { - _system->getTimerManager()->removeTimerProc(&timerHandler); } void SciGuiGfx::init() { @@ -54,8 +51,6 @@ void SciGuiGfx::init() { _textFonts = NULL; _textFontsCount = 0; _textColors = NULL; _textColorsCount = 0; - _picNotValid = false; - _mainPort = mallocPort(); SetPort(_mainPort); OpenPort(_mainPort); @@ -70,49 +65,6 @@ void SciGuiGfx::init() { // heapClearPtr(theMenuBarH); // _theMenuBar = (Common::Rect *)heap2Ptr(theMenuBarH); // *_theMenuBar = Common::Rect(_gfx->RGetPort()->rect.right, 10); - - _sysTicks = 0; -} - -void SciGuiGfx::initPalette() { - int16 i; - for (i = 0; i < 256; i++) { - _screen->_sysPalette.colors[i].used = 0; - _screen->_sysPalette.colors[i].r = 0; - _screen->_sysPalette.colors[i].g = 0; - _screen->_sysPalette.colors[i].b = 0; - _screen->_sysPalette.intensity[i] = 100; - _screen->_sysPalette.mapping[i] = i; - } - _screen->_sysPalette.colors[0].used = 1; - _screen->_sysPalette.colors[255].used = 1; - _screen->_sysPalette.colors[255].r = 255; - _screen->_sysPalette.colors[255].g = 255; - _screen->_sysPalette.colors[255].b = 255; - - // Load default palette from resource 999 - if (!SetResPalette(999, 2)) { - // if not found, we try to set amiga palette - if (!SetAmigaPalette()) { - // if that also doesnt work out, set EGA palette - SetEGApalette(); - } - }; - - // Init _clrPowers used in MatchColor - for(i = 0; i < 256; i++) - _clrPowers[i] = i*i; -} - -void SciGuiGfx::initTimer() { - _sysSpeed = 1000000 / 60; - Common::TimerManager *tm = _system->getTimerManager(); - tm->removeTimerProc(&timerHandler); - tm->installTimerProc(&timerHandler, _sysSpeed, this); -} - -void SciGuiGfx::timerHandler(void *ref) { - ((SciGuiGfx *)ref)->_sysTicks++; } GuiPort *SciGuiGfx::mallocPort() { @@ -122,166 +74,6 @@ GuiPort *SciGuiGfx::mallocPort() { return newPort; } -// Will try to set amiga palette by using "spal" file. If not found, we return false -bool SciGuiGfx::SetAmigaPalette() { - Common::File file; - int curColor, byte1, byte2; - - if (file.open("spal")) { - for (curColor = 0; curColor < 32; curColor++) { - byte1 = file.readByte(); - byte2 = file.readByte(); - if ((byte1 == EOF) || (byte2 == EOF)) - error("Amiga palette file ends prematurely"); - _screen->_sysPalette.colors[curColor].used = 1; - _screen->_sysPalette.colors[curColor].r = (byte1 & 0x0F) * 0x11; - _screen->_sysPalette.colors[curColor].g = ((byte2 & 0xF0) >> 4) * 0x11; - _screen->_sysPalette.colors[curColor].b = (byte2 & 0x0F) * 0x11; - } - file.close(); - return true; - } - return false; -} - -void SciGuiGfx::SetEGApalette() { - int i; - _screen->_sysPalette.colors[1].r = 0x000; _screen->_sysPalette.colors[1].g = 0x000; _screen->_sysPalette.colors[1].b = 0x0AA; - _screen->_sysPalette.colors[2].r = 0x000; _screen->_sysPalette.colors[2].g = 0x0AA; _screen->_sysPalette.colors[2].b = 0x000; - _screen->_sysPalette.colors[3].r = 0x000; _screen->_sysPalette.colors[3].g = 0x0AA; _screen->_sysPalette.colors[3].b = 0x0AA; - _screen->_sysPalette.colors[4].r = 0x0AA; _screen->_sysPalette.colors[4].g = 0x000; _screen->_sysPalette.colors[4].b = 0x000; - _screen->_sysPalette.colors[5].r = 0x0AA; _screen->_sysPalette.colors[5].g = 0x000; _screen->_sysPalette.colors[5].b = 0x0AA; - _screen->_sysPalette.colors[6].r = 0x0AA; _screen->_sysPalette.colors[6].g = 0x055; _screen->_sysPalette.colors[6].b = 0x000; - _screen->_sysPalette.colors[7].r = 0x0AA; _screen->_sysPalette.colors[7].g = 0x0AA; _screen->_sysPalette.colors[7].b = 0x0AA; - _screen->_sysPalette.colors[8].r = 0x055; _screen->_sysPalette.colors[8].g = 0x055; _screen->_sysPalette.colors[8].b = 0x055; - _screen->_sysPalette.colors[9].r = 0x055; _screen->_sysPalette.colors[9].g = 0x055; _screen->_sysPalette.colors[9].b = 0x0FF; - _screen->_sysPalette.colors[10].r = 0x055; _screen->_sysPalette.colors[10].g = 0x0FF; _screen->_sysPalette.colors[10].b = 0x055; - _screen->_sysPalette.colors[11].r = 0x055; _screen->_sysPalette.colors[11].g = 0x0FF; _screen->_sysPalette.colors[11].b = 0x0FF; - _screen->_sysPalette.colors[12].r = 0x0FF; _screen->_sysPalette.colors[12].g = 0x055; _screen->_sysPalette.colors[12].b = 0x055; - _screen->_sysPalette.colors[13].r = 0x0FF; _screen->_sysPalette.colors[13].g = 0x055; _screen->_sysPalette.colors[13].b = 0x0FF; - _screen->_sysPalette.colors[14].r = 0x0FF; _screen->_sysPalette.colors[14].g = 0x0FF; _screen->_sysPalette.colors[14].b = 0x055; - _screen->_sysPalette.colors[15].r = 0x0FF; _screen->_sysPalette.colors[15].g = 0x0FF; _screen->_sysPalette.colors[15].b = 0x0FF; - for (i = 0; i <= 15; i++) { - _screen->_sysPalette.colors[i].used = 1; - } - for (i = 16; i <= 254; i++) { - _screen->_sysPalette.colors[i].r = 200; - _screen->_sysPalette.colors[i].used = 1; - } - setScreenPalette(&_screen->_sysPalette); -} - -bool SciGuiGfx::SetResPalette(int16 resourceNo, int16 flag) { - Resource *palResource = _s->resMan->findResource(ResourceId(kResourceTypePalette, resourceNo), 0); - GuiPalette palette; - - if (palResource) { - CreatePaletteFromData(palResource->data, &palette); - SetPalette(&palette, 2); - return true; - } - return false; -} - -void SciGuiGfx::SetPalette(GuiPalette *sciPal, int16 flag) { - uint32 systime = _screen->_sysPalette.timestamp; - if (flag == 2 || sciPal->timestamp != systime) { - MergePalettes(sciPal, &_screen->_sysPalette, flag); - sciPal->timestamp = _screen->_sysPalette.timestamp; - if (_picNotValid == 0 && systime != _screen->_sysPalette.timestamp) - setScreenPalette(&_screen->_sysPalette); - } -} - -void SciGuiGfx::MergePalettes(GuiPalette *pFrom, GuiPalette *pTo, uint16 flag) { - uint16 res; - int i,j; - // colors 0 (black) and 255 (white) are not affected by merging - for (i = 1 ; i < 255; i++) { - if (!pFrom->colors[i].used)// color is not used - so skip it - continue; - // forced palette merging or dest color is not used yet - if (flag == 2 || (!pTo->colors[i].used)) { - pTo->colors[i].used = pFrom->colors[i].used; - pTo->colors[i].r = pFrom->colors[i].r; - pTo->colors[i].g = pFrom->colors[i].g; - pTo->colors[i].b = pFrom->colors[i].b; - pFrom->mapping[i] = i; - continue; - } - // check if exact color could be matched - res = MatchColor(pTo, pFrom->colors[i].r, pFrom->colors[i].g, pFrom->colors[i].b); - if (res & 0x8000) { // exact match was found - pFrom->mapping[i] = res & 0xFF; - continue; - } - // no exact match - see if there is an unused color - for (j = 1; j < 256; j++) - if (!pTo->colors[j].used) { - pTo->colors[j].used = pFrom->colors[i].used; - pTo->colors[j].r = pFrom->colors[i].r; - pTo->colors[j].g = pFrom->colors[i].g; - pTo->colors[j].b = pFrom->colors[i].b; - pFrom->mapping[i] = j; - break; - } - // if still no luck - set an approximate color - if (j == 256) { - pFrom->mapping[i] = res & 0xFF; - pTo->colors[res & 0xFF].used |= 0x10; - } - } - pTo->timestamp = _sysTicks; -} - -uint16 SciGuiGfx::MatchColor(GuiPalette*pPal, byte r, byte g, byte b) { - byte found = 0xFF; - int diff = 0x2FFFF, cdiff; - int16 dr,dg,db; - - for (int i = 0; i < 256; i++) { - if ((!pPal->colors[i].used)) - continue; - dr = pPal->colors[i].r - r; - dg = pPal->colors[i].g - g; - db = pPal->colors[i].b - b; -// minimum squares match - cdiff = _clrPowers[ABS(dr)] + _clrPowers[ABS(dg)] + _clrPowers[ABS(db)]; -// minimum sum match (Sierra's) -// cdiff = ABS(dr) + ABS(dg) + ABS(db); - if (cdiff < diff) { - if (cdiff == 0) - return i | 0x8000; // setting this flag to indicate exact match - found = i; - diff = cdiff; - } - } - return found; -} - -void SciGuiGfx::setScreenPalette(GuiPalette*pal) { - if (pal != &_screen->_sysPalette) - memcpy(&_screen->_sysPalette,pal,sizeof(GuiPalette)); - // just copy palette to system - byte bpal[4 * 256]; - // Get current palette, update it and put back - _system->grabPalette(bpal, 0, 256); - for (int16 i = 0; i < 256; i++) { - if (!pal->colors[i].used) - continue; - bpal[i * 4] = pal->colors[i].r * pal->intensity[i] / 100; - bpal[i * 4 + 1] = pal->colors[i].g * pal->intensity[i] / 100; - bpal[i * 4 + 2] = pal->colors[i].b * pal->intensity[i] / 100; - bpal[i * 4 + 3] = 100; - } - _system->setPalette(bpal, 0, 256); -} - -void SciGuiGfx::getSysPalette(GuiPalette*pal) { - if (pal != &_screen->_sysPalette) - memcpy(pal, &_screen->_sysPalette,sizeof(GuiPalette)); -} - GuiPort *SciGuiGfx::SetPort(GuiPort *newPort) { GuiPort *oldPort = _curPort; _curPort = newPort; @@ -890,6 +682,7 @@ const byte pattern_Circles[8][15] = { }; // TODO: perhaps this is a better way to set the pattern_Textures array below? +// in that case one would need to adjust bits of secondary table. Bit 256 is ignored by original interpreter #if 0 const byte patternTextures[32 * 2] = { 0x04, 0x29, 0x40, 0x24, 0x09, 0x41, 0x25, 0x45, @@ -1169,16 +962,19 @@ void SciGuiGfx::Pic_Fill(int16 x, int16 y, byte color, byte prio, byte control) void SciGuiGfx::drawPicture(GuiResourceId pictureId, uint16 style, bool addToFlag, GuiResourceId paletteId) { SciGuiPicture *picture; - picture = new SciGuiPicture(_s, this, _screen, pictureId); + picture = new SciGuiPicture(_s, this, _screen, _palette, pictureId); // do we add to a picture? if not -> clear screen if (!addToFlag) { - ClearScreen(0); + if (_s->resMan->isVGA()) + ClearScreen(0); + else + ClearScreen(15); } picture->draw(style, addToFlag, paletteId); } void SciGuiGfx::drawCel(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, uint16 leftPos, uint16 topPos, byte priority, uint16 paletteNo) { - SciGuiView *view = new SciGuiView(_s->resMan, _screen, viewId); + SciGuiView *view = new SciGuiView(_s->resMan, _screen, _palette, viewId); Common::Rect rect(0, 0); Common::Rect clipRect(0, 0); if (view) { @@ -1191,11 +987,6 @@ void SciGuiGfx::drawCel(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo if (clipRect.isEmpty()) // nothing to draw return; - if (view->hasEmbeddedPal()) { - // Merge view palette in... - SetPalette(view->getPalette(), 1); - } - Common::Rect clipRectTranslated = clipRect; OffsetRect(clipRectTranslated); view->draw(rect, clipRect, clipRectTranslated, loopNo, celNo, priority, paletteNo); @@ -1205,42 +996,6 @@ void SciGuiGfx::drawCel(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo } } -void SciGuiGfx::PaletteSetIntensity(int fromColor, int toColor, int intensity, GuiPalette *destPalette) { - memset(destPalette->intensity + fromColor, intensity, toColor - fromColor); -} - -void SciGuiGfx::PaletteAnimate(byte fromColor, byte toColor, int speed) { - GuiColor col; - int len = toColor - fromColor - 1; - uint32 now = _sysTicks; - // search for sheduled animations with the same 'from' value - int sz = _palSchedules.size(); - for (int i = 0; i < sz; i++) { - if (_palSchedules[i].from == fromColor) { - if (_palSchedules[i].schedule < now) { - if (speed > 0) { - col = _screen->_sysPalette.colors[fromColor]; - memmove(&_screen->_sysPalette.colors[fromColor], &_screen->_sysPalette.colors[fromColor + 1], len * sizeof(GuiColor)); - _screen->_sysPalette.colors[toColor - 1] = col; - } else { - col = _screen->_sysPalette.colors[toColor - 1]; - memmove(&_screen->_sysPalette.colors[fromColor + 1], &_screen->_sysPalette.colors[fromColor], len * sizeof(GuiColor)); - _screen->_sysPalette.colors[fromColor] = col; - } - // removing schedule - _palSchedules.remove_at(i); - } - setScreenPalette(&_screen->_sysPalette); - return; - } - } - // adding a new schedule - GuiPalSchedule sched; - sched.from = fromColor; - sched.schedule = now + ABS(speed); - _palSchedules.push_back(sched); -} - int16 SciGuiGfx::onControl(uint16 screenMask, Common::Rect rect) { Common::Rect outRect(rect.left, rect.top, rect.right, rect.bottom); int16 x, y; @@ -1303,7 +1058,39 @@ void SciGuiGfx::AnimateInvoke(List *list, int argc, reg_t *argv) { void SciGuiGfx::AnimateFill() { } -void SciGuiGfx::AnimateSort() { +Common::List<GuiAnimateList> *SciGuiGfx::AnimateMakeSortedList(List *list) { + SegManager *segMan = _s->_segMan; + Common::List<GuiAnimateList> *sortedList = new Common::List<GuiAnimateList>; + GuiAnimateList listHelper; + reg_t curAddress = list->first; + Node *curNode = lookup_node(_s, curAddress); + reg_t curObject; + + // First convert the given List to Common::List + while (curNode) { + curObject = curNode->value; + listHelper.address = curAddress; + listHelper.y = (int16)GET_SEL32V(curObject, y); + listHelper.z = (int16)GET_SEL32V(curObject, z); + sortedList->push_back(listHelper); + + curAddress = curNode->succ; + curNode = lookup_node(_s, curAddress); + } + + // Now do a bubble sort on this Common::List + if (sortedList->size() < 2) + return sortedList; + + sortedList->begin(); +// Common::List<ExecStack>::iterator iter; +// for (iter = s->_executionStack.begin(); +// iter != s->_executionStack.end(); ++iter) { +// ExecStack &es = *iter; + + + + return sortedList; } void SciGuiGfx::AnimateUpdate() { @@ -1330,7 +1117,7 @@ void SciGuiGfx::SetNowSeen(reg_t objectReference) { } // now get cel rectangle - view = new SciGuiView(_s->resMan, _screen, viewId); + view = new SciGuiView(_s->resMan, _screen, _palette, viewId); view->getCelRect(loopNo, celNo, x, y, z, &celRect); // TODO: sometimes loop is negative. Check what it means diff --git a/engines/sci/gui/gui_gfx.h b/engines/sci/gui/gui_gfx.h index efb0ce806a..d8ff32c984 100644 --- a/engines/sci/gui/gui_gfx.h +++ b/engines/sci/gui/gui_gfx.h @@ -35,30 +35,20 @@ namespace Sci { #define SCI_PATTERN_CODE_PENSIZE 0x07 class SciGuiScreen; +class SciGuiPalette; class SciGuiFont; class SciGuiPicture; class SciGuiView; class SciGuiGfx { public: - SciGuiGfx(OSystem *system, EngineState *state, SciGuiScreen *screen); + SciGuiGfx(OSystem *system, EngineState *state, SciGuiScreen *screen, SciGuiPalette *palette); ~SciGuiGfx(); void init(void); - void initPalette(); - void initTimer(); - static void timerHandler(void*ref); GuiPort *mallocPort (); byte *GetSegment(byte seg); void ResetScreen(); - bool SetAmigaPalette(); - void SetEGApalette(); - bool SetResPalette(int16 resourceNo, int16 flag); - void SetPalette(GuiPalette *sciPal, int16 flag); - void MergePalettes(GuiPalette *pFrom, GuiPalette *pTo, uint16 flag); - uint16 MatchColor(GuiPalette *pPal, byte r, byte g, byte b); - void setScreenPalette(GuiPalette *pal); - void getSysPalette(GuiPalette *pal); GuiPort *SetPort(GuiPort *port); GuiPort *GetPort(); @@ -114,14 +104,11 @@ public: void drawPicture(GuiResourceId pictureId, uint16 style, bool addToFlag, GuiResourceId paletteId); void drawCel(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, uint16 leftPos, uint16 topPos, byte priority, uint16 paletteNo); - void PaletteSetIntensity(int fromColor, int toColor, int intensity, GuiPalette *destPalette); - void PaletteAnimate(byte fromColor, byte toColor, int speed); - int16 onControl(uint16 screenMask, Common::Rect rect); void AnimateDisposeLastCast(); void AnimateInvoke(List *list, int argc, reg_t *argv); void AnimateFill(); - void AnimateSort(); + Common::List<GuiAnimateList> *AnimateMakeSortedList(List *list); void AnimateUpdate(); void AnimateDrawCels(); void AnimateRestoreAndDelete(); @@ -129,10 +116,6 @@ public: GuiPort *_menuPort; Common::Rect _menuRect; - uint32 _sysTicks; - int32 _sysSpeed; // ticker timer in ms - - bool _picNotValid; private: int16 TextCodeProcessing(const char *&text, GuiResourceId orgFontId, int16 orgPenColor); @@ -145,6 +128,7 @@ private: OSystem *_system; EngineState *_s; SciGuiScreen *_screen; + SciGuiPalette *_palette; Common::Rect _bounds; GuiPort *_mainPort; diff --git a/engines/sci/gui/gui_helpers.h b/engines/sci/gui/gui_helpers.h index ed66705976..4f97c73484 100644 --- a/engines/sci/gui/gui_helpers.h +++ b/engines/sci/gui/gui_helpers.h @@ -71,6 +71,12 @@ struct GuiWindow : public GuiPort { } }; +struct GuiAnimateList { + reg_t address; + int16 y; + int16 z; +}; + struct GuiCast { uint16 view; uint16 loop; @@ -108,53 +114,6 @@ enum { GFX_REMOVEVIEW = 0x80 }; -#define SCI_PAL_FORMAT_CONSTANT 1 -#define SCI_PAL_FORMAT_VARIABLE 0 - -static inline void CreatePaletteFromData(byte *data, GuiPalette *paletteOut) { - int palFormat = 0; - int palOffset = 0; - int palColorStart = 0; - int palColorCount = 0; - int colorNo = 0; - - memset(paletteOut, 0, sizeof(GuiPalette)); - // Setup default mapping - for (colorNo = 0; colorNo < 256; colorNo++) { - paletteOut->mapping[colorNo] = colorNo; - } - if (data[0] == 0 && data[1] == 1) { - // SCI0/SCI1 palette - palFormat = SCI_PAL_FORMAT_VARIABLE; // CONSTANT; - palOffset = 260; - palColorStart = 0; palColorCount = 256; - //memcpy(&paletteOut->mapping, data, 256); - } else { - // SCI1.1 palette - palFormat = data[32]; - palOffset = 37; - palColorStart = READ_LE_UINT16(data + 25); palColorCount = READ_LE_UINT16(data + 29); - } - switch (palFormat) { - case SCI_PAL_FORMAT_CONSTANT: - for (colorNo = palColorStart; colorNo < palColorStart + palColorCount; colorNo++) { - paletteOut->colors[colorNo].used = 1; - paletteOut->colors[colorNo].r = data[palOffset++]; - paletteOut->colors[colorNo].g = data[palOffset++]; - paletteOut->colors[colorNo].b = data[palOffset++]; - } - break; - case SCI_PAL_FORMAT_VARIABLE: - for (colorNo = palColorStart; colorNo < palColorStart + palColorCount; colorNo++) { - paletteOut->colors[colorNo].used = data[palOffset++]; - paletteOut->colors[colorNo].r = data[palOffset++]; - paletteOut->colors[colorNo].g = data[palOffset++]; - paletteOut->colors[colorNo].b = data[palOffset++]; - } - break; - } -} - } // End of namespace Sci #endif diff --git a/engines/sci/gui/gui_palette.cpp b/engines/sci/gui/gui_palette.cpp new file mode 100644 index 0000000000..f41bbafa85 --- /dev/null +++ b/engines/sci/gui/gui_palette.cpp @@ -0,0 +1,307 @@ +/* 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$ + * + */ + +#include "common/timer.h" +#include "common/util.h" + +#include "sci/sci.h" +#include "sci/engine/state.h" +#include "sci/tools.h" +#include "sci/gui/gui_screen.h" +#include "sci/gui/gui_palette.h" + +namespace Sci { + +SciGuiPalette::SciGuiPalette(OSystem *system, EngineState *state, SciGui *gui, SciGuiScreen *screen) + : _system(system), _s(state), _gui(gui), _screen(screen) { + init(); +} + +SciGuiPalette::~SciGuiPalette() { +} + +void SciGuiPalette::init() { + int16 i; + for (i = 0; i < 256; i++) { + _sysPalette.colors[i].used = 0; + _sysPalette.colors[i].r = 0; + _sysPalette.colors[i].g = 0; + _sysPalette.colors[i].b = 0; + _sysPalette.intensity[i] = 100; + _sysPalette.mapping[i] = i; + } + _sysPalette.colors[0].used = 1; + _sysPalette.colors[255].used = 1; + _sysPalette.colors[255].r = 255; + _sysPalette.colors[255].g = 255; + _sysPalette.colors[255].b = 255; + + // Load default palette from resource 999 + if (!setFromResource(999, 2)) { + // if not found, we try to set amiga palette + if (!setAmiga()) { + // if that also doesnt work out, set EGA palette + setEGA(); + } + }; + + // Init _clrPowers used in MatchColor + for(i = 0; i < 256; i++) + _clrPowers[i] = i*i; +} + +#define SCI_PAL_FORMAT_CONSTANT 1 +#define SCI_PAL_FORMAT_VARIABLE 0 + +void SciGuiPalette::createFromData(byte *data, GuiPalette *paletteOut) { + int palFormat = 0; + int palOffset = 0; + int palColorStart = 0; + int palColorCount = 0; + int colorNo = 0; + + memset(paletteOut, 0, sizeof(GuiPalette)); + // Setup default mapping + for (colorNo = 0; colorNo < 256; colorNo++) { + paletteOut->mapping[colorNo] = colorNo; + } + if (data[0] == 0 && data[1] == 1) { + // SCI0/SCI1 palette + palFormat = SCI_PAL_FORMAT_VARIABLE; // CONSTANT; + palOffset = 260; + palColorStart = 0; palColorCount = 256; + //memcpy(&paletteOut->mapping, data, 256); + } else { + // SCI1.1 palette + palFormat = data[32]; + palOffset = 37; + palColorStart = READ_LE_UINT16(data + 25); palColorCount = READ_LE_UINT16(data + 29); + } + switch (palFormat) { + case SCI_PAL_FORMAT_CONSTANT: + for (colorNo = palColorStart; colorNo < palColorStart + palColorCount; colorNo++) { + paletteOut->colors[colorNo].used = 1; + paletteOut->colors[colorNo].r = data[palOffset++]; + paletteOut->colors[colorNo].g = data[palOffset++]; + paletteOut->colors[colorNo].b = data[palOffset++]; + } + break; + case SCI_PAL_FORMAT_VARIABLE: + for (colorNo = palColorStart; colorNo < palColorStart + palColorCount; colorNo++) { + paletteOut->colors[colorNo].used = data[palOffset++]; + paletteOut->colors[colorNo].r = data[palOffset++]; + paletteOut->colors[colorNo].g = data[palOffset++]; + paletteOut->colors[colorNo].b = data[palOffset++]; + } + break; + } +} + + +// Will try to set amiga palette by using "spal" file. If not found, we return false +bool SciGuiPalette::setAmiga() { + Common::File file; + int curColor, byte1, byte2; + + if (file.open("spal")) { + for (curColor = 0; curColor < 32; curColor++) { + byte1 = file.readByte(); + byte2 = file.readByte(); + if ((byte1 == EOF) || (byte2 == EOF)) + error("Amiga palette file ends prematurely"); + _sysPalette.colors[curColor].used = 1; + _sysPalette.colors[curColor].r = (byte1 & 0x0F) * 0x11; + _sysPalette.colors[curColor].g = ((byte2 & 0xF0) >> 4) * 0x11; + _sysPalette.colors[curColor].b = (byte2 & 0x0F) * 0x11; + } + file.close(); + return true; + } + return false; +} + +void SciGuiPalette::setEGA() { + int i; + _sysPalette.colors[1].r = 0x000; _sysPalette.colors[1].g = 0x000; _sysPalette.colors[1].b = 0x0AA; + _sysPalette.colors[2].r = 0x000; _sysPalette.colors[2].g = 0x0AA; _sysPalette.colors[2].b = 0x000; + _sysPalette.colors[3].r = 0x000; _sysPalette.colors[3].g = 0x0AA; _sysPalette.colors[3].b = 0x0AA; + _sysPalette.colors[4].r = 0x0AA; _sysPalette.colors[4].g = 0x000; _sysPalette.colors[4].b = 0x000; + _sysPalette.colors[5].r = 0x0AA; _sysPalette.colors[5].g = 0x000; _sysPalette.colors[5].b = 0x0AA; + _sysPalette.colors[6].r = 0x0AA; _sysPalette.colors[6].g = 0x055; _sysPalette.colors[6].b = 0x000; + _sysPalette.colors[7].r = 0x0AA; _sysPalette.colors[7].g = 0x0AA; _sysPalette.colors[7].b = 0x0AA; + _sysPalette.colors[8].r = 0x055; _sysPalette.colors[8].g = 0x055; _sysPalette.colors[8].b = 0x055; + _sysPalette.colors[9].r = 0x055; _sysPalette.colors[9].g = 0x055; _sysPalette.colors[9].b = 0x0FF; + _sysPalette.colors[10].r = 0x055; _sysPalette.colors[10].g = 0x0FF; _sysPalette.colors[10].b = 0x055; + _sysPalette.colors[11].r = 0x055; _sysPalette.colors[11].g = 0x0FF; _sysPalette.colors[11].b = 0x0FF; + _sysPalette.colors[12].r = 0x0FF; _sysPalette.colors[12].g = 0x055; _sysPalette.colors[12].b = 0x055; + _sysPalette.colors[13].r = 0x0FF; _sysPalette.colors[13].g = 0x055; _sysPalette.colors[13].b = 0x0FF; + _sysPalette.colors[14].r = 0x0FF; _sysPalette.colors[14].g = 0x0FF; _sysPalette.colors[14].b = 0x055; + _sysPalette.colors[15].r = 0x0FF; _sysPalette.colors[15].g = 0x0FF; _sysPalette.colors[15].b = 0x0FF; + for (i = 0; i <= 15; i++) { + _sysPalette.colors[i].used = 1; + } + for (i = 16; i <= 254; i++) { + _sysPalette.colors[i].r = 200; + _sysPalette.colors[i].used = 1; + } + setOnScreen(); +} + +bool SciGuiPalette::setFromResource(int16 resourceNo, int16 flag) { + Resource *palResource = _s->resMan->findResource(ResourceId(kResourceTypePalette, resourceNo), 0); + GuiPalette palette; + + if (palResource) { + createFromData(palResource->data, &palette); + set(&palette, 2); + return true; + } + return false; +} + +void SciGuiPalette::set(GuiPalette *sciPal, int16 flag) { + uint32 systime = _sysPalette.timestamp; + if (flag == 2 || sciPal->timestamp != systime) { + merge(sciPal, &_sysPalette, flag); + sciPal->timestamp = _sysPalette.timestamp; + if (_gui->_picNotValid == 0 && systime != _sysPalette.timestamp) + setOnScreen(); + } +} + +void SciGuiPalette::merge(GuiPalette *pFrom, GuiPalette *pTo, uint16 flag) { + uint16 res; + int i,j; + // colors 0 (black) and 255 (white) are not affected by merging + for (i = 1 ; i < 255; i++) { + if (!pFrom->colors[i].used)// color is not used - so skip it + continue; + // forced palette merging or dest color is not used yet + if (flag == 2 || (!pTo->colors[i].used)) { + pTo->colors[i].used = pFrom->colors[i].used; + pTo->colors[i].r = pFrom->colors[i].r; + pTo->colors[i].g = pFrom->colors[i].g; + pTo->colors[i].b = pFrom->colors[i].b; + pFrom->mapping[i] = i; + continue; + } + // check if exact color could be matched + res = matchColor(pTo, pFrom->colors[i].r, pFrom->colors[i].g, pFrom->colors[i].b); + if (res & 0x8000) { // exact match was found + pFrom->mapping[i] = res & 0xFF; + continue; + } + // no exact match - see if there is an unused color + for (j = 1; j < 256; j++) + if (!pTo->colors[j].used) { + pTo->colors[j].used = pFrom->colors[i].used; + pTo->colors[j].r = pFrom->colors[i].r; + pTo->colors[j].g = pFrom->colors[i].g; + pTo->colors[j].b = pFrom->colors[i].b; + pFrom->mapping[i] = j; + break; + } + // if still no luck - set an approximate color + if (j == 256) { + pFrom->mapping[i] = res & 0xFF; + pTo->colors[res & 0xFF].used |= 0x10; + } + } + pTo->timestamp = _gui->getTimeTicks(); +} + +uint16 SciGuiPalette::matchColor(GuiPalette*pPal, byte r, byte g, byte b) { + byte found = 0xFF; + int diff = 0x2FFFF, cdiff; + int16 dr,dg,db; + + for (int i = 0; i < 256; i++) { + if ((!pPal->colors[i].used)) + continue; + dr = pPal->colors[i].r - r; + dg = pPal->colors[i].g - g; + db = pPal->colors[i].b - b; +// minimum squares match + cdiff = _clrPowers[ABS(dr)] + _clrPowers[ABS(dg)] + _clrPowers[ABS(db)]; +// minimum sum match (Sierra's) +// cdiff = ABS(dr) + ABS(dg) + ABS(db); + if (cdiff < diff) { + if (cdiff == 0) + return i | 0x8000; // setting this flag to indicate exact match + found = i; + diff = cdiff; + } + } + return found; +} + +void SciGuiPalette::getSys(GuiPalette*pal) { + if (pal != &_sysPalette) + memcpy(pal, &_sysPalette,sizeof(GuiPalette)); +} + +void SciGuiPalette::setOnScreen() { +// if (pal != &_sysPalette) +// memcpy(&_sysPalette,pal,sizeof(GuiPalette)); + _screen->setPalette(&_sysPalette); +} + +void SciGuiPalette::setIntensity(int fromColor, int toColor, int intensity, GuiPalette *destPalette) { + memset(destPalette->intensity + fromColor, intensity, toColor - fromColor); +} + +void SciGuiPalette::animate(byte fromColor, byte toColor, int speed) { + GuiColor col; + int len = toColor - fromColor - 1; + uint32 now = _gui->getTimeTicks(); + // search for sheduled animations with the same 'from' value + int sz = _palSchedules.size(); + for (int i = 0; i < sz; i++) { + if (_palSchedules[i].from == fromColor) { + if (_palSchedules[i].schedule < now) { + if (speed > 0) { + col = _sysPalette.colors[fromColor]; + memmove(&_sysPalette.colors[fromColor], &_sysPalette.colors[fromColor + 1], len * sizeof(GuiColor)); + _sysPalette.colors[toColor - 1] = col; + } else { + col = _sysPalette.colors[toColor - 1]; + memmove(&_sysPalette.colors[fromColor + 1], &_sysPalette.colors[fromColor], len * sizeof(GuiColor)); + _sysPalette.colors[fromColor] = col; + } + // removing schedule + _palSchedules.remove_at(i); + } + setOnScreen(); + return; + } + } + // adding a new schedule + GuiPalSchedule sched; + sched.from = fromColor; + sched.schedule = now + ABS(speed); + _palSchedules.push_back(sched); +} + +} // End of namespace Sci diff --git a/engines/sci/gui/gui_palette.h b/engines/sci/gui/gui_palette.h new file mode 100644 index 0000000000..a67f194ff7 --- /dev/null +++ b/engines/sci/gui/gui_palette.h @@ -0,0 +1,71 @@ +/* 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$ + * + */ + +#ifndef SCI_GUI_PALETTE_H +#define SCI_GUI_PALETTE_H + +#include "sci/gui/gui.h" + +namespace Sci { + +class SciGuiScreen; +class SciGuiPalette { +public: + SciGuiPalette(OSystem *system, EngineState *state, SciGui *gui, SciGuiScreen *screen); + ~SciGuiPalette(); + + void init(); + + void createFromData(byte *data, GuiPalette *paletteOut); + bool setAmiga(); + void setEGA(); + bool setFromResource(int16 resourceNo, int16 flag); + void set(GuiPalette *sciPal, int16 flag); + void merge(GuiPalette *pFrom, GuiPalette *pTo, uint16 flag); + uint16 matchColor(GuiPalette *pPal, byte r, byte g, byte b); + void getSys(GuiPalette *pal); + + void setOnScreen(); + + void setIntensity(int fromColor, int toColor, int intensity, GuiPalette *destPalette); + void animate(byte fromColor, byte toColor, int speed); + + GuiPalette _sysPalette; + +private: + OSystem *_system; + EngineState *_s; + SciGui *_gui; + SciGuiScreen *_screen; + + uint16 _clrPowers[256]; + + GuiPalette *pPicPal; + Common::Array<GuiPalSchedule> _palSchedules; +}; + +} // End of namespace Sci + +#endif diff --git a/engines/sci/gui/gui_picture.cpp b/engines/sci/gui/gui_picture.cpp index aa54333688..2dc58bd312 100644 --- a/engines/sci/gui/gui_picture.cpp +++ b/engines/sci/gui/gui_picture.cpp @@ -27,13 +27,14 @@ #include "sci/engine/state.h" #include "sci/tools.h" #include "sci/gui/gui_screen.h" +#include "sci/gui/gui_palette.h" #include "sci/gui/gui_gfx.h" #include "sci/gui/gui_picture.h" namespace Sci { -SciGuiPicture::SciGuiPicture(EngineState *state, SciGuiGfx *gfx, SciGuiScreen *screen, GuiResourceId resourceId) - : _s(state), _gfx(gfx), _screen(screen), _resourceId(resourceId) { +SciGuiPicture::SciGuiPicture(EngineState *state, SciGuiGfx *gfx, SciGuiScreen *screen, SciGuiPalette *palette, GuiResourceId resourceId) + : _s(state), _gfx(gfx), _screen(screen), _palette(palette), _resourceId(resourceId) { assert(resourceId != -1); initData(resourceId); } @@ -91,8 +92,8 @@ void SciGuiPicture::drawSci11Vga() { GuiPalette palette; // Create palette and set it - CreatePaletteFromData(inbuffer + palette_data_ptr, &palette); - _gfx->SetPalette(&palette, 2); + _palette->createFromData(inbuffer + palette_data_ptr, &palette); + _palette->set(&palette, 2); // display Cel-data if (has_view) { @@ -468,7 +469,7 @@ void SciGuiPicture::drawVectorData(byte *data, int dataSize) { palette.colors[i].used = data[curPos++]; palette.colors[i].r = data[curPos++]; palette.colors[i].g = data[curPos++]; palette.colors[i].b = data[curPos++]; } - _gfx->SetPalette(&palette, 2); + _palette->set(&palette, 2); break; case PIC_OPX_VGA_EMBEDDED_VIEW: // draw cel vectorGetAbsCoords(data, curPos, x, y); diff --git a/engines/sci/gui/gui_picture.h b/engines/sci/gui/gui_picture.h index b56f357e67..a1f4ddc674 100644 --- a/engines/sci/gui/gui_picture.h +++ b/engines/sci/gui/gui_picture.h @@ -32,7 +32,7 @@ namespace Sci { class SciGuiPicture { public: - SciGuiPicture(EngineState *state, SciGuiGfx *gfx, SciGuiScreen *screen, GuiResourceId resourceId); + SciGuiPicture(EngineState *state, SciGuiGfx *gfx, SciGuiScreen *screen, SciGuiPalette *palette, GuiResourceId resourceId); ~SciGuiPicture(); GuiResourceId getResourceId(); @@ -54,6 +54,7 @@ private: EngineState *_s; SciGuiGfx *_gfx; SciGuiScreen *_screen; + SciGuiPalette *_palette; int16 _resourceId; Resource *_resource; diff --git a/engines/sci/gui/gui_screen.cpp b/engines/sci/gui/gui_screen.cpp index 7889f7022e..7786dc7282 100644 --- a/engines/sci/gui/gui_screen.cpp +++ b/engines/sci/gui/gui_screen.cpp @@ -199,6 +199,22 @@ void SciGuiScreen::restoreBitsScreen(Common::Rect rect, byte *&memoryPtr, byte * } } +void SciGuiScreen::setPalette(GuiPalette*pal) { + // just copy palette to system + byte bpal[4 * 256]; + // Get current palette, update it and put back + _system->grabPalette(bpal, 0, 256); + for (int16 i = 0; i < 256; i++) { + if (!pal->colors[i].used) + continue; + bpal[i * 4] = pal->colors[i].r * pal->intensity[i] / 100; + bpal[i * 4 + 1] = pal->colors[i].g * pal->intensity[i] / 100; + bpal[i * 4 + 2] = pal->colors[i].b * pal->intensity[i] / 100; + bpal[i * 4 + 3] = 100; + } + _system->setPalette(bpal, 0, 256); +} + // Currently not really done, its supposed to be possible to only dither _visualScreen void SciGuiScreen::dither() { int y, x; diff --git a/engines/sci/gui/gui_screen.h b/engines/sci/gui/gui_screen.h index 1b3688e5a4..75913515e9 100644 --- a/engines/sci/gui/gui_screen.h +++ b/engines/sci/gui/gui_screen.h @@ -59,6 +59,8 @@ public: void saveBits(Common::Rect rect, byte mask, byte *memoryPtr); void restoreBits(byte *memoryPtr); + void setPalette(GuiPalette*pal); + void dither(); uint16 _width; @@ -68,8 +70,6 @@ public: uint16 _displayHeight; uint _displayPixels; - GuiPalette _sysPalette; - private: void restoreBitsScreen(Common::Rect rect, byte *&memoryPtr, byte *screen); void saveBitsScreen(Common::Rect rect, byte *screen, byte *&memoryPtr); diff --git a/engines/sci/gui/gui_view.cpp b/engines/sci/gui/gui_view.cpp index c5bcd6cc9e..379e8bf612 100644 --- a/engines/sci/gui/gui_view.cpp +++ b/engines/sci/gui/gui_view.cpp @@ -28,12 +28,13 @@ #include "sci/tools.h" #include "sci/gui/gui_gfx.h" #include "sci/gui/gui_screen.h" +#include "sci/gui/gui_palette.h" #include "sci/gui/gui_view.h" namespace Sci { -SciGuiView::SciGuiView(ResourceManager *resMan, SciGuiScreen *screen, GuiResourceId resourceId) - : _resMan(resMan), _screen(screen), _resourceId(resourceId) { +SciGuiView::SciGuiView(ResourceManager *resMan, SciGuiScreen *screen, SciGuiPalette *palette, GuiResourceId resourceId) + : _resMan(resMan), _screen(screen), _palette(palette), _resourceId(resourceId) { assert(resourceId != -1); initData(resourceId); } @@ -82,7 +83,7 @@ void SciGuiView::initData(GuiResourceId resourceId) { if (IsEGA) { // simple mapping for 16 colors _EGAMapping = _resourceData + palOffset; } else { - CreatePaletteFromData(&_resourceData[palOffset], &_palette); + _palette->createFromData(&_resourceData[palOffset], &_viewPalette); _embeddedPal = true; } } @@ -141,7 +142,7 @@ void SciGuiView::initData(GuiResourceId resourceId) { celSize = _resourceData[13]; if (palOffset) { - CreatePaletteFromData(&_resourceData[palOffset], &_palette); + _palette->createFromData(&_resourceData[palOffset], &_viewPalette); _embeddedPal = true; } @@ -344,7 +345,7 @@ byte *SciGuiView::getBitmap(GuiViewLoopNo loopNo, GuiViewCelNo celNo) { } void SciGuiView::draw(Common::Rect rect, Common::Rect clipRect, Common::Rect clipRectTranslated, GuiViewLoopNo loopNo, GuiViewCelNo celNo, byte priority, uint16 paletteNo) { - GuiPalette *palette = _embeddedPal ? &_palette : &_screen->_sysPalette; + GuiPalette *palette = _embeddedPal ? &_viewPalette : &_palette->_sysPalette; sciViewCelInfo *celInfo = getCelInfo(loopNo, celNo); byte *bitmap = getBitmap(loopNo, celNo); int16 celHeight = celInfo->height, celWidth = celInfo->width; @@ -354,6 +355,11 @@ void SciGuiView::draw(Common::Rect rect, Common::Rect clipRect, Common::Rect cli byte drawMask = priority == 255 ? SCI_SCREEN_MASK_VISUAL : SCI_SCREEN_MASK_VISUAL|SCI_SCREEN_MASK_PRIORITY; int x, y; + if (_embeddedPal) { + // Merge view palette in... + _palette->set(&_viewPalette, 1); + } + width = MIN(clipRect.width(), celWidth); height = MIN(clipRect.height(), celHeight); diff --git a/engines/sci/gui/gui_view.h b/engines/sci/gui/gui_view.h index b2bf9d7d35..c356fbe579 100644 --- a/engines/sci/gui/gui_view.h +++ b/engines/sci/gui/gui_view.h @@ -47,11 +47,9 @@ struct sciViewLoopInfo { class SciGuiView { public: - SciGuiView(ResourceManager *resMan, SciGuiScreen *screen, GuiResourceId resourceId); + SciGuiView(ResourceManager *resMan, SciGuiScreen *screen, SciGuiPalette *palette, GuiResourceId resourceId); ~SciGuiView(); - // TODO: Remove gfx reference after putting palette things into SciGuiScreen - GuiResourceId getResourceId(); int16 getWidth(GuiViewLoopNo loopNo, GuiViewCelNo celNo); int16 getHeight(GuiViewLoopNo loopNo, GuiViewCelNo celNo); @@ -61,16 +59,13 @@ public: byte *getBitmap(GuiViewLoopNo loopNo, GuiViewCelNo celNo); void draw(Common::Rect rect, Common::Rect clipRect, Common::Rect clipRectTranslated, GuiViewLoopNo loopNo, GuiViewCelNo celNo, byte priority, uint16 paletteNo); - bool hasEmbeddedPal() const { return _embeddedPal; } - - GuiPalette *getPalette() { return &_palette; } - private: void initData(GuiResourceId resourceId); void unpackCel(GuiViewLoopNo loopNo, GuiViewCelNo celNo, byte *outPtr, uint16 pixelCount); ResourceManager *_resMan; SciGuiScreen *_screen; + SciGuiPalette *_palette; GuiResourceId _resourceId; byte *_resourceData; @@ -78,7 +73,7 @@ private: uint16 _loopCount; sciViewLoopInfo *_loop; bool _embeddedPal; - GuiPalette _palette; + GuiPalette _viewPalette; const byte *_EGAMapping; // simple translation map for all 16 colors }; |