From 84cd8d2dc7673bf883945cfdf600d98769817bc6 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Tue, 5 Jan 2010 01:22:16 +0000 Subject: Renamed /gui to /graphics and /sfx to /sound, to better illustrate their purpose svn-id: r47007 --- engines/sci/gui/gui.cpp | 935 ---------------------------------- engines/sci/gui/gui.h | 202 -------- engines/sci/gui/gui_animate.cpp | 559 --------------------- engines/sci/gui/gui_animate.h | 99 ---- engines/sci/gui/gui_controls.cpp | 231 --------- engines/sci/gui/gui_controls.h | 60 --- engines/sci/gui/gui_cursor.cpp | 227 --------- engines/sci/gui/gui_cursor.h | 84 ---- engines/sci/gui/gui_font.cpp | 101 ---- engines/sci/gui/gui_font.h | 63 --- engines/sci/gui/gui_gfx.cpp | 536 -------------------- engines/sci/gui/gui_gfx.h | 130 ----- engines/sci/gui/gui_helpers.h | 130 ----- engines/sci/gui/gui_menu.cpp | 648 ------------------------ engines/sci/gui/gui_menu.h | 123 ----- engines/sci/gui/gui_palette.cpp | 380 -------------- engines/sci/gui/gui_palette.h | 66 --- engines/sci/gui/gui_picture.cpp | 973 ------------------------------------ engines/sci/gui/gui_picture.h | 82 --- engines/sci/gui/gui_portrait.cpp | 66 --- engines/sci/gui/gui_portrait.h | 49 -- engines/sci/gui/gui_screen.cpp | 513 ------------------- engines/sci/gui/gui_screen.h | 130 ----- engines/sci/gui/gui_text.cpp | 410 --------------- engines/sci/gui/gui_text.h | 83 --- engines/sci/gui/gui_transitions.cpp | 576 --------------------- engines/sci/gui/gui_transitions.h | 106 ---- engines/sci/gui/gui_view.cpp | 513 ------------------- engines/sci/gui/gui_view.h | 91 ---- engines/sci/gui/gui_windowmgr.cpp | 286 ----------- engines/sci/gui/gui_windowmgr.h | 71 --- 31 files changed, 8523 deletions(-) delete mode 100644 engines/sci/gui/gui.cpp delete mode 100644 engines/sci/gui/gui.h delete mode 100644 engines/sci/gui/gui_animate.cpp delete mode 100644 engines/sci/gui/gui_animate.h delete mode 100644 engines/sci/gui/gui_controls.cpp delete mode 100644 engines/sci/gui/gui_controls.h delete mode 100644 engines/sci/gui/gui_cursor.cpp delete mode 100644 engines/sci/gui/gui_cursor.h delete mode 100644 engines/sci/gui/gui_font.cpp delete mode 100644 engines/sci/gui/gui_font.h delete mode 100644 engines/sci/gui/gui_gfx.cpp delete mode 100644 engines/sci/gui/gui_gfx.h delete mode 100644 engines/sci/gui/gui_helpers.h delete mode 100644 engines/sci/gui/gui_menu.cpp delete mode 100644 engines/sci/gui/gui_menu.h delete mode 100644 engines/sci/gui/gui_palette.cpp delete mode 100644 engines/sci/gui/gui_palette.h delete mode 100644 engines/sci/gui/gui_picture.cpp delete mode 100644 engines/sci/gui/gui_picture.h delete mode 100644 engines/sci/gui/gui_portrait.cpp delete mode 100644 engines/sci/gui/gui_portrait.h delete mode 100644 engines/sci/gui/gui_screen.cpp delete mode 100644 engines/sci/gui/gui_screen.h delete mode 100644 engines/sci/gui/gui_text.cpp delete mode 100644 engines/sci/gui/gui_text.h delete mode 100644 engines/sci/gui/gui_transitions.cpp delete mode 100644 engines/sci/gui/gui_transitions.h delete mode 100644 engines/sci/gui/gui_view.cpp delete mode 100644 engines/sci/gui/gui_view.h delete mode 100644 engines/sci/gui/gui_windowmgr.cpp delete mode 100644 engines/sci/gui/gui_windowmgr.h (limited to 'engines/sci/gui') diff --git a/engines/sci/gui/gui.cpp b/engines/sci/gui/gui.cpp deleted file mode 100644 index 9377d439bf..0000000000 --- a/engines/sci/gui/gui.cpp +++ /dev/null @@ -1,935 +0,0 @@ -/* 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/debug.h" // for g_debug_sleeptime_factor -#include "sci/event.h" -#include "sci/engine/state.h" -#include "sci/gui/gui.h" -#include "sci/gui/gui_screen.h" -#include "sci/gui/gui_palette.h" -#include "sci/gui/gui_cursor.h" -#include "sci/gui/gui_gfx.h" -#include "sci/gui/gui_windowmgr.h" -#include "sci/gui/gui_animate.h" -#include "sci/gui/gui_controls.h" -#include "sci/gui/gui_menu.h" -#include "sci/gui/gui_text.h" -#include "sci/gui/gui_transitions.h" -#include "sci/gui/gui_view.h" - -namespace Sci { - -// for debug purposes -// class SciGui32 : public SciGui { -// public: -// SciGui32(EngineState *s, SciGuiScreen *screen, SciGuiPalette *palette, SciGuiCursor *cursor); -// ~SciGui32(); -// }; - -SciGui::SciGui(EngineState *state, SciGuiScreen *screen, SciGuiPalette *palette, SciGuiCursor *cursor) - : _s(state), _screen(screen), _palette(palette), _cursor(cursor) { - - _gfx = new SciGuiGfx(_s->resMan, _s->_segMan, _s->_kernel, _screen, _palette); - _transitions = new SciGuiTransitions(this, _screen, _palette, _s->resMan->isVGA()); - _animate = new SciGuiAnimate(_s, _gfx, _screen, _palette); - _text = new SciGuiText(_s->resMan, _gfx, _screen); - _windowMgr = new SciGuiWindowMgr(this, _screen, _gfx, _text); - _controls = new SciGuiControls(_s->_segMan, _gfx, _text); - _menu = new SciGuiMenu(_s->_event, _s->_segMan, _gfx, _text, _screen, _cursor); -// _gui32 = new SciGui32(_s, _screen, _palette, _cursor); // for debug purposes -} - -SciGui::SciGui() { -} - -SciGui::~SciGui() { - delete _menu; - delete _controls; - delete _windowMgr; - delete _text; - delete _animate; - delete _transitions; - delete _gfx; -} - -void SciGui::resetEngineState(EngineState *s) { - _s = s; - _animate->resetEngineState(s); -} - -void SciGui::init(bool usesOldGfxFunctions) { - _usesOldGfxFunctions = usesOldGfxFunctions; - - _gfx->init(_text); - _windowMgr->init(_s->_gameId); - initPriorityBands(); -} - -void SciGui::initPriorityBands() { - if (_usesOldGfxFunctions) { - _gfx->PriorityBandsInit(15, 42, 200); - } else { - _gfx->PriorityBandsInit(14, 42, 190); - } -} - -void SciGui::wait(int16 ticks) { - uint32 time; - - time = g_system->getMillis(); - _s->r_acc = make_reg(0, ((long)time - (long)_s->last_wait_time) * 60 / 1000); - _s->last_wait_time = time; - - ticks *= g_debug_sleeptime_factor; - kernel_sleep(_s->_event, ticks * 1000 / 60); -} - -void SciGui::setPort(uint16 portPtr) { - switch (portPtr) { - case 0: - _gfx->SetPort(_windowMgr->_wmgrPort); - break; - case 0xFFFF: - _gfx->SetPort(_gfx->_menuPort); - break; - default: - _gfx->SetPort(_windowMgr->getPortById(portPtr)); - }; -} - -Common::Rect SciGui::getPortPic(int16 &picTop, int16 &picLeft) { - picTop = _windowMgr->_picWind->top; - picLeft = _windowMgr->_picWind->left; - return _windowMgr->_picWind->rect; -} - -void SciGui::setPortPic(Common::Rect rect, int16 picTop, int16 picLeft, bool initPriorityBandsFlag) { - _windowMgr->_picWind->rect = rect; - _windowMgr->_picWind->top = picTop; - _windowMgr->_picWind->left = picLeft; - if (initPriorityBandsFlag) - initPriorityBands(); -} - -reg_t SciGui::getPort() { - return make_reg(0, _gfx->GetPort()->id); -} - -void SciGui::globalToLocal(int16 *x, int16 *y) { - GuiPort *curPort = _gfx->GetPort(); - *x = *x - curPort->left; - *y = *y - curPort->top; -} - -void SciGui::localToGlobal(int16 *x, int16 *y) { - GuiPort *curPort = _gfx->GetPort(); - *x = *x + curPort->left; - *y = *y + curPort->top; -} - -int16 SciGui::coordinateToPriority(int16 y) { - return _gfx->CoordinateToPriority(y); -} - -int16 SciGui::priorityToCoordinate(int16 priority) { - return _gfx->PriorityToCoordinate(priority); -} - -reg_t SciGui::newWindow(Common::Rect dims, Common::Rect restoreRect, uint16 style, int16 priority, int16 colorPen, int16 colorBack, const char *title) { - GuiWindow *wnd = NULL; - - if (restoreRect.top != 0 && restoreRect.left != 0 && restoreRect.height() != 0 && restoreRect.width() != 0) - wnd = _windowMgr->NewWindow(dims, &restoreRect, title, style, priority, false); - else - wnd = _windowMgr->NewWindow(dims, NULL, title, style, priority, false); - wnd->penClr = colorPen; - wnd->backClr = colorBack; - _windowMgr->DrawWindow(wnd); - - return make_reg(0, wnd->id); -} - -void SciGui::disposeWindow(uint16 windowPtr, bool reanimate) { - GuiWindow *wnd = (GuiWindow *)_windowMgr->getPortById(windowPtr); - _windowMgr->DisposeWindow(wnd, reanimate); -} - -#define SCI_DISPLAY_MOVEPEN 100 -#define SCI_DISPLAY_SETALIGNMENT 101 -#define SCI_DISPLAY_SETPENCOLOR 102 -#define SCI_DISPLAY_SETBACKGROUNDCOLOR 103 -#define SCI_DISPLAY_SETGREYEDOUTPUT 104 -#define SCI_DISPLAY_SETFONT 105 -#define SCI_DISPLAY_WIDTH 106 -#define SCI_DISPLAY_SAVEUNDER 107 -#define SCI_DISPLAY_RESTOREUNDER 108 -#define SCI_DISPLAY_DONTSHOWBITS 121 - -void SciGui::display(const char *text, int argc, reg_t *argv) { - int displayArg; - GuiTextAlignment alignment = SCI_TEXT_ALIGNMENT_LEFT; - int16 bgcolor = -1, width = -1, bRedraw = 1; - bool doSaveUnder = false; - Common::Rect rect; - - // Make a "backup" of the port settings - GuiPort oldPort = *_gfx->GetPort(); - - // setting defaults - _gfx->PenMode(0); - _gfx->PenColor(0); - _gfx->TextGreyedOutput(false); - // processing codes in argv - while (argc > 0) { - displayArg = argv[0].toUint16(); - argc--; argv++; - switch (displayArg) { - case SCI_DISPLAY_MOVEPEN: - _gfx->MoveTo(argv[0].toUint16(), argv[1].toUint16()); - argc -= 2; argv += 2; - break; - case SCI_DISPLAY_SETALIGNMENT: - alignment = argv[0].toSint16(); - argc--; argv++; - break; - case SCI_DISPLAY_SETPENCOLOR: - _gfx->PenColor(argv[0].toUint16()); - argc--; argv++; - break; - case SCI_DISPLAY_SETBACKGROUNDCOLOR: - bgcolor = argv[0].toUint16(); - argc--; argv++; - break; - case SCI_DISPLAY_SETGREYEDOUTPUT: - _gfx->TextGreyedOutput(argv[0].isNull() ? false : true); - argc--; argv++; - break; - case SCI_DISPLAY_SETFONT: - _text->SetFont(argv[0].toUint16()); - argc--; argv++; - break; - case SCI_DISPLAY_WIDTH: - width = argv[0].toUint16(); - argc--; argv++; - break; - case SCI_DISPLAY_SAVEUNDER: - doSaveUnder = true; - break; - case SCI_DISPLAY_RESTOREUNDER: - _gfx->BitsGetRect(argv[0], &rect); - rect.translate(-_gfx->GetPort()->left, -_gfx->GetPort()->top); - _gfx->BitsRestore(argv[0]); - graphRedrawBox(rect); - // finishing loop - argc = 0; - break; - case SCI_DISPLAY_DONTSHOWBITS: - bRedraw = 0; - break; - default: - warning("Unknown kDisplay argument %X", displayArg); - break; - } - } - - // now drawing the text - _text->Size(rect, text, -1, width); - rect.moveTo(_gfx->GetPort()->curLeft, _gfx->GetPort()->curTop); - if (getSciVersion() >= SCI_VERSION_1_LATE) { - _gfx->Move(rect.right <= _screen->_width ? 0 : _screen->_width - rect.right, rect.bottom <= _screen->_height ? 0 : _screen->_width - rect.bottom); - rect.moveTo(_gfx->GetPort()->curLeft, _gfx->GetPort()->curTop); - } - - if (doSaveUnder) - _s->r_acc = _gfx->BitsSave(rect, SCI_SCREEN_MASK_VISUAL); - if (bgcolor != -1) - _gfx->FillRect(rect, SCI_SCREEN_MASK_VISUAL, bgcolor, 0, 0); - _text->Box(text, 0, rect, alignment, -1); - if (_screen->_picNotValid == 0 && bRedraw) - _gfx->BitsShow(rect); - // restoring port and cursor pos - GuiPort *currport = _gfx->GetPort(); - uint16 tTop = currport->curTop; - uint16 tLeft = currport->curLeft; - *currport = oldPort; - currport->curTop = tTop; - currport->curLeft = tLeft; -} - -void SciGui::textSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight) { - Common::Rect rect(0, 0, *textWidth, *textHeight); - _text->Size(rect, text, font, maxWidth); - *textWidth = rect.width(); - *textHeight = rect.height(); -} - -// Used SCI1+ for text codes -void SciGui::textFonts(int argc, reg_t *argv) { - _text->CodeSetFonts(argc, argv); -} - -// Used SCI1+ for text codes -void SciGui::textColors(int argc, reg_t *argv) { - _text->CodeSetColors(argc, argv); -} - -void SciGui::drawStatus(const char *text, int16 colorPen, int16 colorBack) { - GuiPort *oldPort = _gfx->SetPort(_gfx->_menuPort); - - _gfx->FillRect(_gfx->_menuBarRect, 1, colorBack); - _gfx->PenColor(colorPen); - _gfx->MoveTo(0, 1); - _text->Draw_String(text); - if (_screen->_picNotValid == 0) - _gfx->BitsShow(_gfx->_menuBarRect); - _gfx->SetPort(oldPort); -} - -void SciGui::drawMenuBar(bool clear) { - if (!clear) { - GuiPort *oldPort = _gfx->SetPort(_gfx->_menuPort); - _menu->drawBar(); - if (_screen->_picNotValid == 0) - _gfx->BitsShow(_gfx->_menuBarRect); - _gfx->SetPort(oldPort); - } else { - drawStatus("", 0, 0); - } -} - -void SciGui::menuReset() { - delete _menu; - _menu = new SciGuiMenu(_s->_event, _s->_segMan, _gfx, _text, _screen, _cursor); -} - -void SciGui::menuAdd(Common::String title, Common::String content, reg_t contentVmPtr) { - _menu->add(title, content, contentVmPtr); -} - -void SciGui::menuSet(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value) { - _menu->setAttribute(menuId, itemId, attributeId, value); -} - -reg_t SciGui::menuGet(uint16 menuId, uint16 itemId, uint16 attributeId) { - return _menu->getAttribute(menuId, itemId, attributeId); -} - -reg_t SciGui::menuSelect(reg_t eventObject) { - return _menu->select(eventObject); -} - -void SciGui::drawPicture(GuiResourceId pictureId, int16 animationNr, bool animationBlackoutFlag, bool mirroredFlag, bool addToFlag, int16 EGApaletteNo) { - GuiPort *oldPort = _gfx->SetPort((GuiPort *)_windowMgr->_picWind); - - if (_windowMgr->isFrontWindow(_windowMgr->_picWind)) { - _screen->_picNotValid = 1; - _gfx->drawPicture(pictureId, animationNr, mirroredFlag, addToFlag, EGApaletteNo); - _transitions->setup(animationNr, animationBlackoutFlag); - } else { - _windowMgr->BeginUpdate(_windowMgr->_picWind); - _gfx->drawPicture(pictureId, animationNr, mirroredFlag, addToFlag, EGApaletteNo); - _windowMgr->EndUpdate(_windowMgr->_picWind); - } - _gfx->SetPort(oldPort); -} - -void SciGui::drawCel(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo, int16 origHeight) { - _gfx->drawCel(viewId, loopNo, celNo, leftPos, topPos, priority, paletteNo, origHeight); - _palette->setOnScreen(); -} - -int SciGui::getControlPicNotValid() { - if (getSciVersion() >= SCI_VERSION_1_1) - return _screen->_picNotValidSci11; - return _screen->_picNotValid; -} - -void SciGui::drawControlButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool hilite) { - if (!hilite) { - rect.grow(1); - _gfx->EraseRect(rect); - _gfx->FrameRect(rect); - rect.grow(-2); - _gfx->TextGreyedOutput(style & 1 ? false : true); - _text->Box(text, 0, rect, SCI_TEXT_ALIGNMENT_CENTER, fontId); - _gfx->TextGreyedOutput(false); - rect.grow(1); - if (style & 8) // selected - _gfx->FrameRect(rect); - if (!getControlPicNotValid()) { - rect.grow(1); - _gfx->BitsShow(rect); - } - } else { - _gfx->InvertRect(rect); - _gfx->BitsShow(rect); - } -} - -void SciGui::drawControlText(Common::Rect rect, reg_t obj, const char *text, int16 fontId, GuiTextAlignment alignment, int16 style, bool hilite) { - if (!hilite) { - rect.grow(1); - _gfx->EraseRect(rect); - rect.grow(-1); - _text->Box(text, 0, rect, alignment, fontId); - if (style & 8) { // selected - _gfx->FrameRect(rect); - } - rect.grow(1); - if (!getControlPicNotValid()) - _gfx->BitsShow(rect); - } else { - _gfx->InvertRect(rect); - _gfx->BitsShow(rect); - } -} - -void SciGui::drawControlTextEdit(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 mode, int16 style, int16 cursorPos, int16 maxChars, bool hilite) { - Common::Rect textRect = rect; - uint16 oldFontId = _text->GetFontId(); - - rect.grow(1); - _controls->TexteditCursorErase(); - _gfx->EraseRect(rect); - _text->Box(text, 0, textRect, SCI_TEXT_ALIGNMENT_LEFT, fontId); - _gfx->FrameRect(rect); - if (style & 8) { - _text->SetFont(fontId); - rect.grow(-1); - _controls->TexteditCursorDraw(rect, text, cursorPos); - _text->SetFont(oldFontId); - rect.grow(1); - } - if (!getControlPicNotValid()) - _gfx->BitsShow(rect); -} - -void SciGui::drawControlIcon(Common::Rect rect, reg_t obj, GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, int16 style, bool hilite) { - if (!hilite) { - _gfx->drawCel(viewId, loopNo, celNo, rect.left, rect.top, 255, 0); - if (style & 0x20) { - _gfx->FrameRect(rect); - } - if (!getControlPicNotValid()) - _gfx->BitsShow(rect); - } else { - _gfx->InvertRect(rect); - _gfx->BitsShow(rect); - } -} - -void SciGui::drawControlList(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 style, int16 upperPos, int16 cursorPos, bool isAlias, bool hilite) { - if (!hilite) { - _controls->drawListControl(rect, obj, maxChars, count, entries, fontId, upperPos, cursorPos, isAlias); - rect.grow(1); - if (isAlias && (style & 8)) { - _gfx->FrameRect(rect); - } - if (!getControlPicNotValid()) - _gfx->BitsShow(rect); - } -} - -void SciGui::editControl(reg_t controlObject, reg_t eventObject) { - int16 controlType = GET_SEL32V(_s->_segMan, controlObject, type); - - switch (controlType) { - case SCI_CONTROLS_TYPE_TEXTEDIT: - // Only process textedit controls in here - _controls->TexteditChange(controlObject, eventObject); - return; - } -} - -void SciGui::graphFillBoxForeground(Common::Rect rect) { - _gfx->PaintRect(rect); -} - -void SciGui::graphFillBoxBackground(Common::Rect rect) { - _gfx->EraseRect(rect); -} - -void SciGui::graphFillBox(Common::Rect rect, uint16 colorMask, int16 color, int16 priority, int16 control) { - _gfx->FillRect(rect, colorMask, color, priority, control); -} - -void SciGui::graphFrameBox(Common::Rect rect, int16 color) { - int16 oldColor = _gfx->GetPort()->penClr; - _gfx->PenColor(color); - _gfx->FrameRect(rect); - _gfx->PenColor(oldColor); -} - -void SciGui::graphDrawLine(Common::Point startPoint, Common::Point endPoint, int16 color, int16 priority, int16 control) { - _gfx->OffsetLine(startPoint, endPoint); - _screen->drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y, color, priority, control); -} - -reg_t SciGui::graphSaveBox(Common::Rect rect, uint16 screenMask) { - return _gfx->BitsSave(rect, screenMask); -} - -reg_t SciGui::graphSaveUpscaledHiresBox(Common::Rect rect) { - return _gfx->BitsSave(rect, SCI_SCREEN_MASK_DISPLAY); -} - -void SciGui::graphRestoreBox(reg_t handle) { - _gfx->BitsRestore(handle); -} - -void SciGui::graphUpdateBox(Common::Rect rect) { - _gfx->BitsShow(rect); -} - -void SciGui::graphRedrawBox(Common::Rect rect) { - localToGlobal(&rect.left, &rect.top); - localToGlobal(&rect.right, &rect.bottom); - GuiPort *oldPort = _gfx->SetPort((GuiPort *)_windowMgr->_picWind); - globalToLocal(&rect.left, &rect.top); - globalToLocal(&rect.right, &rect.bottom); - - _animate->reAnimate(rect); - - _gfx->SetPort(oldPort); -} - -void SciGui::graphAdjustPriority(int top, int bottom) { - if (_usesOldGfxFunctions) { - _gfx->PriorityBandsInit(15, top, bottom); - } else { - _gfx->PriorityBandsInit(14, top, bottom); - } -} - -int16 SciGui::picNotValid(int16 newPicNotValid) { - int16 oldPicNotValid; - - if (getSciVersion() >= SCI_VERSION_1_1) { - oldPicNotValid = _screen->_picNotValidSci11; - - if (newPicNotValid != -1) - _screen->_picNotValidSci11 = newPicNotValid; - } else { - oldPicNotValid = _screen->_picNotValid; - - if (newPicNotValid != -1) - _screen->_picNotValid = newPicNotValid; - } - - return oldPicNotValid; -} - - -void SciGui::paletteSet(GuiResourceId resourceId, uint16 flags) { - // we are also called on EGA games as well, this doesnt make sense. doing this would actually break the system EGA palette - if (!_s->resMan->isVGA()) - return; - _palette->setFromResource(resourceId, flags); -} - -void SciGui::paletteSetFlag(uint16 fromColor, uint16 toColor, uint16 flag) { - _palette->setFlag(fromColor, toColor, flag); -} - -void SciGui::paletteUnsetFlag(uint16 fromColor, uint16 toColor, uint16 flag) { - _palette->unsetFlag(fromColor, toColor, flag); -} - -int16 SciGui::paletteFind(uint16 r, uint16 g, uint16 b) { - return _palette->matchColor(&_palette->_sysPalette, r, g, b) & 0xFF; -} - -void SciGui::paletteSetIntensity(uint16 fromColor, uint16 toColor, uint16 intensity, bool setPalette) { - _palette->setIntensity(fromColor, toColor, intensity, setPalette); -} - -bool SciGui::paletteAnimate(uint16 fromColor, uint16 toColor, int16 speed) { - // we are also called on Amiga as well, but for colors above 32, so it doesnt make sense - if (!_s->resMan->isVGA()) - return false; - - return _palette->animate(fromColor, toColor, speed); -} - -void SciGui::paletteAnimateSet() { - _palette->setOnScreen(); -} - -void SciGui::shakeScreen(uint16 shakeCount, uint16 directions) { - while (shakeCount--) { - if (directions & SCI_SHAKE_DIRECTION_VERTICAL) - _screen->setVerticalShakePos(10); - // TODO: horizontal shakes - g_system->updateScreen(); - wait(3); - if (directions & SCI_SHAKE_DIRECTION_VERTICAL) - _screen->setVerticalShakePos(0); - g_system->updateScreen(); - wait(3); - } -} - -uint16 SciGui::onControl(byte screenMask, Common::Rect rect) { - GuiPort *oldPort = _gfx->SetPort((GuiPort *)_windowMgr->_picWind); - uint16 result; - - result = _gfx->onControl(screenMask, rect); - _gfx->SetPort(oldPort); - return result; -} - -void SciGui::animateShowPic() { - GuiPort *picPort = _windowMgr->_picWind; - Common::Rect picRect = picPort->rect; - bool previousCursorState = _cursor->isVisible(); - - if (previousCursorState) - _cursor->hide(); - // Adjust picRect to become relative to screen - picRect.translate(picPort->left, picPort->top); - _transitions->doit(picRect); - if (previousCursorState) - _cursor->show(); -} - -void SciGui::animate(reg_t listReference, bool cycle, int argc, reg_t *argv) { - byte old_picNotValid = _screen->_picNotValid; - - if (listReference.isNull()) { - _animate->disposeLastCast(); - if (_screen->_picNotValid) - animateShowPic(); - return; - } - - List *list = _s->_segMan->lookupList(listReference); - if (!list) - error("kAnimate called with non-list as parameter"); - - if (cycle) { - if (!_animate->invoke(list, argc, argv)) - return; - } - - GuiPort *oldPort = _gfx->SetPort((GuiPort *)_windowMgr->_picWind); - _animate->disposeLastCast(); - - _animate->makeSortedList(list); - _animate->fill(old_picNotValid); - - if (old_picNotValid) { - _windowMgr->BeginUpdate(_windowMgr->_picWind); - _animate->update(); - _windowMgr->EndUpdate(_windowMgr->_picWind); - } - - _animate->drawCels(); - - if (_screen->_picNotValid) - animateShowPic(); - - _animate->updateScreen(old_picNotValid); - _animate->restoreAndDelete(argc, argv); - - _gfx->SetPort(oldPort); -} - -void SciGui::addToPicSetPicNotValid() { - if (getSciVersion() <= SCI_VERSION_1_EARLY) - _screen->_picNotValid = 1; - else - _screen->_picNotValid = 2; -} - -void SciGui::addToPicList(reg_t listReference, int argc, reg_t *argv) { - List *list; - - _gfx->SetPort((GuiPort *)_windowMgr->_picWind); - - list = _s->_segMan->lookupList(listReference); - if (!list) - error("kAddToPic called with non-list as parameter"); - - _animate->makeSortedList(list); - _animate->addToPicDrawCels(); - - addToPicSetPicNotValid(); -} - -void SciGui::addToPicView(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, int16 leftPos, int16 topPos, int16 priority, int16 control) { - _gfx->SetPort((GuiPort *)_windowMgr->_picWind); - _animate->addToPicDrawView(viewId, loopNo, celNo, leftPos, topPos, priority, control); - addToPicSetPicNotValid(); -} - -void SciGui::setNowSeen(reg_t objectReference) { - _gfx->SetNowSeen(objectReference); -} - -bool SciGui::canBeHere(reg_t curObject, reg_t listReference) { - GuiPort *oldPort = _gfx->SetPort((GuiPort *)_windowMgr->_picWind); - Common::Rect checkRect; - uint16 signal, controlMask; - bool result; - - checkRect.left = GET_SEL32V(_s->_segMan, curObject, brLeft); - checkRect.top = GET_SEL32V(_s->_segMan, curObject, brTop); - checkRect.right = GET_SEL32V(_s->_segMan, curObject, brRight); - checkRect.bottom = GET_SEL32V(_s->_segMan, curObject, brBottom); - signal = GET_SEL32V(_s->_segMan, curObject, signal); - controlMask = GET_SEL32V(_s->_segMan, curObject, illegalBits); - result = (_gfx->onControl(SCI_SCREEN_MASK_CONTROL, checkRect) & controlMask) ? false : true; - if ((result) && (signal & (kSignalIgnoreActor | kSignalRemoveView)) == 0) { - List *list = _s->_segMan->lookupList(listReference); - if (!list) - error("kCanBeHere called with non-list as parameter"); - - result = _gfx->CanBeHereCheckRectList(curObject, checkRect, list); - } - _gfx->SetPort(oldPort); - return result; -} - -bool SciGui::isItSkip(GuiResourceId viewId, int16 loopNo, int16 celNo, Common::Point position) { - SciGuiView *tmpView = _gfx->getView(viewId); - sciViewCelInfo *celInfo = tmpView->getCelInfo(loopNo, celNo); - position.x = CLIP(position.x, 0, celInfo->width - 1); - position.y = CLIP(position.y, 0, celInfo->height - 1); - byte *celData = tmpView->getBitmap(loopNo, celNo); - bool result = (celData[position.y * celInfo->width + position.x] == celInfo->clearKey); - return result; -} - -void SciGui::baseSetter(reg_t object) { - if (lookup_selector(_s->_segMan, object, _s->_kernel->_selectorCache.brLeft, NULL, NULL) == kSelectorVariable) { - int16 x = GET_SEL32V(_s->_segMan, object, x); - int16 y = GET_SEL32V(_s->_segMan, object, y); - int16 z = (_s->_kernel->_selectorCache.z > -1) ? GET_SEL32V(_s->_segMan, object, z) : 0; - int16 yStep = GET_SEL32V(_s->_segMan, object, yStep); - GuiResourceId viewId = GET_SEL32V(_s->_segMan, object, view); - GuiViewLoopNo loopNo = GET_SEL32V(_s->_segMan, object, loop); - GuiViewCelNo celNo = GET_SEL32V(_s->_segMan, object, cel); - - SciGuiView *tmpView = _gfx->getView(viewId); - Common::Rect celRect; - - tmpView->getCelRect(loopNo, celNo, x, y, z, &celRect); - celRect.bottom = y + 1; - celRect.top = celRect.bottom - yStep; - - PUT_SEL32V(_s->_segMan, object, brLeft, celRect.left); - PUT_SEL32V(_s->_segMan, object, brRight, celRect.right); - PUT_SEL32V(_s->_segMan, object, brTop, celRect.top); - PUT_SEL32V(_s->_segMan, object, brBottom, celRect.bottom); - } -} - -void SciGui::hideCursor() { - _cursor->hide(); -} - -void SciGui::showCursor() { - _cursor->show(); -} - -void SciGui::setCursorShape(GuiResourceId cursorId) { - _cursor->setShape(cursorId); -} - -void SciGui::setCursorView(GuiResourceId viewNum, int loopNum, int cellNum, Common::Point *hotspot) { - _cursor->setView(viewNum, loopNum, cellNum, hotspot); -} - -void SciGui::setCursorPos(Common::Point pos) { - pos.y += _gfx->GetPort()->top; - pos.x += _gfx->GetPort()->left; - moveCursor(pos); -} - -Common::Point SciGui::getCursorPos() { - return _cursor->getPosition(); -} - -void SciGui::moveCursor(Common::Point pos) { - pos.y += _windowMgr->_picWind->rect.top; - pos.x += _windowMgr->_picWind->rect.left; - - pos.y = CLIP(pos.y, _windowMgr->_picWind->rect.top, _windowMgr->_picWind->rect.bottom - 1); - pos.x = CLIP(pos.x, _windowMgr->_picWind->rect.left, _windowMgr->_picWind->rect.right - 1); - - if (pos.x > _screen->_width || pos.y > _screen->_height) { - warning("attempt to place cursor at invalid coordinates (%d, %d)", pos.y, pos.x); - return; - } - - _cursor->setPosition(pos); - - // Trigger event reading to make sure the mouse coordinates will - // actually have changed the next time we read them. - _s->_event->get(SCI_EVENT_PEEK); -} - -void SciGui::setCursorZone(Common::Rect zone) { - _cursor->setMoveZone(zone); -} - -int16 SciGui::getCelWidth(GuiResourceId viewId, int16 loopNo, int16 celNo) { - return _gfx->getView(viewId)->getCelInfo(loopNo, celNo)->width; -} - -int16 SciGui::getCelHeight(GuiResourceId viewId, int16 loopNo, int16 celNo) { - return _gfx->getView(viewId)->getCelInfo(loopNo, celNo)->height; -} - -int16 SciGui::getLoopCount(GuiResourceId viewId) { - return _gfx->getView(viewId)->getLoopCount(); -} - -int16 SciGui::getCelCount(GuiResourceId viewId, int16 loopNo) { - return _gfx->getView(viewId)->getLoopInfo(loopNo)->celCount; -} - -reg_t SciGui::portraitLoad(Common::String resourceName) { - return NULL_REG; -} - -void SciGui::portraitShow(Common::String resourceName, Common::Point position, uint16 resourceNum, uint16 noun, uint16 verb, uint16 cond, uint16 seq) { -} - -void SciGui::portraitUnload(uint16 portraitId) { -} - -uint16 SciGui::getScreenWidth() { - return _screen->_displayWidth; -} - -uint16 SciGui::getScreenHeight() { - return _screen->_displayHeight; -} - -#ifdef ENABLE_SCI32 -void SciGui::addScreenItem(reg_t object) { - _screenItems.push_back(object); -} - -void SciGui::deleteScreenItem(reg_t object) { - for (uint32 itemNr = 0; itemNr < _screenItems.size(); itemNr++) { - if (_screenItems[itemNr] == object) { - _screenItems.remove_at(itemNr); - return; - } - } -} - -void SciGui::addPlane(reg_t object) { - _planes.push_back(object); -} - -void SciGui::updatePlane(reg_t object) { - int16 picNum = GET_SEL32V(_s->_segMan, object, picture); - if (picNum > -1) { - drawPicture(picNum, 100, false, false, false, 0); - animateShowPic(); - } -} - -void SciGui::deletePlane(reg_t object) { - for (uint32 planeNr = 0; planeNr < _planes.size(); planeNr++) { - if (_planes[planeNr] == object) { - _planes.remove_at(planeNr); - return; - } - } -} - -void SciGui::frameOut() { - for (uint32 planeNr = 0; planeNr < _planes.size(); planeNr++) { - reg_t planeObj = _planes[planeNr]; - int16 priority = GET_SEL32V(_s->_segMan, planeObj, priority); - - if (priority == -1) - continue; - - // FIXME: This code doesn't currently work properly because of the way we set up the - // view port. We are starting at 10 pixels from the top automatically. The offset should - // be based on the plane's top in SCI32 instead. Here we would be adding 10 to 10 and - // therefore drawing too low. We would need to draw each picture at the correct offset - // which doesn't currently happen. - //int16 planeTop = GET_SEL32V(_s->_segMan, planeObj, top); - //int16 planeLeft = GET_SEL32V(_s->_segMan, planeObj, left); - - for (uint32 itemNr = 0; itemNr < _screenItems.size(); itemNr++) { - reg_t viewObj = _screenItems[itemNr]; - reg_t planeOfItem = GET_SEL32(_s->_segMan, viewObj, plane); - if (planeOfItem == _planes[planeNr]) { - uint16 viewId = GET_SEL32V(_s->_segMan, viewObj, view); - uint16 loopNo = GET_SEL32V(_s->_segMan, viewObj, loop); - uint16 celNo = GET_SEL32V(_s->_segMan, viewObj, cel); - uint16 leftPos = GET_SEL32V(_s->_segMan, viewObj, x); - uint16 topPos = GET_SEL32V(_s->_segMan, viewObj, y); - priority = GET_SEL32V(_s->_segMan, viewObj, priority); - //int16 signal = GET_SEL32V(_s->_segMan, viewObj, signal); - - // FIXME: See above - //leftPos += planeLeft; - //topPos += planeTop; - - // Theoretically, leftPos and topPos should be sane - // Apparently, sometimes they're not, therefore I'm adding some sanity checks here so that - // the hack underneath does not try and draw cels outside the screen coordinates - if (leftPos >= getScreenWidth()) { - warning("kAddScreenItem: invalid left position (%d), resetting to 0", leftPos); - leftPos = 0; - } - - if (topPos >= getScreenHeight()) { - warning("kAddScreenItem: invalid top position (%d), resetting to 0", topPos); - topPos = 0; - } - - // HACK: just draw the view on screen - if (viewId != 0xffff) - drawCel(viewId, loopNo, celNo, leftPos, topPos, priority, 0); - } - } - } -} -#endif - -bool SciGui::debugUndither(bool flag) { - _screen->unditherSetState(flag); - return false; -} - -bool SciGui::debugShowMap(int mapNo) { - _screen->debugShowMap(mapNo); - return false; -} - -} // End of namespace Sci diff --git a/engines/sci/gui/gui.h b/engines/sci/gui/gui.h deleted file mode 100644 index 154ff825a6..0000000000 --- a/engines/sci/gui/gui.h +++ /dev/null @@ -1,202 +0,0 @@ -/* 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_GUI_H -#define SCI_GUI_GUI_H - -#include "sci/gui/gui_helpers.h" - -namespace Sci { - -// Control types and flags -enum { - SCI_CONTROLS_TYPE_BUTTON = 1, - SCI_CONTROLS_TYPE_TEXT = 2, - SCI_CONTROLS_TYPE_TEXTEDIT = 3, - SCI_CONTROLS_TYPE_ICON = 4, - SCI_CONTROLS_TYPE_LIST = 6, - SCI_CONTROLS_TYPE_LIST_ALIAS = 7, - SCI_CONTROLS_TYPE_DUMMY = 10 -}; - -class SciGuiScreen; -class SciGuiPalette; -class SciGuiCursor; -class SciGuiGfx; -class SciGuiWindowMgr; -class SciGuiAnimate; -class SciGuiControls; -class SciGuiMenu; -class SciGuiText; -class SciGuiTransitions; -class SciGui32; // for debug purposes - -class SciGui { -public: - SciGui(EngineState *s, SciGuiScreen *screen, SciGuiPalette *palette, SciGuiCursor *cursor); - SciGui(); - virtual ~SciGui(); - - virtual void init(bool usesOldGfxFunctions); - - virtual void wait(int16 ticks); - virtual void setPort(uint16 portPtr); - virtual Common::Rect getPortPic(int16 &picTop, int16 &picLeft); - virtual void setPortPic(Common::Rect rect, int16 picTop, int16 picLeft, bool initPriorityBandsFlag); - virtual reg_t getPort(); - virtual void globalToLocal(int16 *x, int16 *y); - virtual void localToGlobal(int16 *x, int16 *y); - virtual int16 coordinateToPriority(int16 y); - virtual int16 priorityToCoordinate(int16 priority); - - virtual reg_t newWindow(Common::Rect dims, Common::Rect restoreRect, uint16 style, int16 priority, int16 colorPen, int16 colorBack, const char *title); - virtual void disposeWindow(uint16 windowPtr, bool reanimate); - - virtual void display(const char *text, int argc, reg_t *argv); - - virtual void textSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight); - virtual void textFonts(int argc, reg_t *argv); - virtual void textColors(int argc, reg_t *argv); - - virtual void drawStatus(const char *text, int16 colorPen, int16 colorBack); - virtual void drawMenuBar(bool clear); - virtual void menuReset(); - virtual void menuAdd(Common::String title, Common::String content, reg_t contentVmPtr); - virtual void menuSet(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value); - virtual reg_t menuGet(uint16 menuId, uint16 itemId, uint16 attributeId); - virtual reg_t menuSelect(reg_t eventObject); - - virtual void drawPicture(GuiResourceId pictureId, int16 animationNr, bool animationBlackoutFlag, bool mirroredFlag, bool addToFlag, int16 EGApaletteNo); - virtual void drawCel(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo, int16 origHeight = -1); - virtual void drawControlButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool hilite); - virtual void drawControlText(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 alignment, int16 style, bool hilite); - virtual void drawControlTextEdit(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 mode, int16 style, int16 cursorPos, int16 maxChars, bool hilite); - virtual void drawControlIcon(Common::Rect rect, reg_t obj, GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, int16 style, bool hilite); - virtual void drawControlList(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 style, int16 upperPos, int16 cursorPos, bool isAlias, bool hilite); - virtual void editControl(reg_t controlObject, reg_t eventObject); - - virtual void graphFillBoxForeground(Common::Rect rect); - virtual void graphFillBoxBackground(Common::Rect rect); - virtual void graphFillBox(Common::Rect rect, uint16 colorMask, int16 color, int16 priority, int16 control); - virtual void graphFrameBox(Common::Rect rect, int16 color); - virtual void graphDrawLine(Common::Point startPoint, Common::Point endPoint, int16 color, int16 priority, int16 control); - virtual reg_t graphSaveBox(Common::Rect rect, uint16 flags); - virtual reg_t graphSaveUpscaledHiresBox(Common::Rect rect); - virtual void graphRestoreBox(reg_t handle); - virtual void graphUpdateBox(Common::Rect rect); - virtual void graphRedrawBox(Common::Rect rect); - virtual void graphAdjustPriority(int top, int bottom); - - virtual int16 picNotValid(int16 newPicNotValid); - - virtual void paletteSet(GuiResourceId resourceNo, uint16 flags); - virtual void paletteSetFlag(uint16 fromColor, uint16 toColor, uint16 flag); - virtual void paletteUnsetFlag(uint16 fromColor, uint16 toColor, uint16 flag); - virtual int16 paletteFind(uint16 r, uint16 g, uint16 b); - virtual void paletteSetIntensity(uint16 fromColor, uint16 toColor, uint16 intensity, bool setPalette); - virtual bool paletteAnimate(uint16 fromColor, uint16 toColor, int16 speed); - virtual void paletteAnimateSet(); - - virtual void shakeScreen(uint16 shakeCount, uint16 directions); - - virtual uint16 onControl(byte screenMask, Common::Rect rect); - virtual void animateShowPic(); - virtual void animate(reg_t listReference, bool cycle, int argc, reg_t *argv); - virtual void addToPicList(reg_t listReference, int argc, reg_t *argv); - virtual void addToPicView(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, int16 leftPos, int16 topPos, int16 priority, int16 control); - virtual void setNowSeen(reg_t objectReference); - virtual bool canBeHere(reg_t curObject, reg_t listReference); - virtual bool isItSkip(GuiResourceId viewId, int16 loopNo, int16 celNo, Common::Point position); - virtual void baseSetter(reg_t object); - - void hideCursor(); - void showCursor(); - void setCursorShape(GuiResourceId cursorId); - void setCursorView(GuiResourceId viewNum, int loopNum, int cellNum, Common::Point *hotspot); - virtual void setCursorPos(Common::Point pos); - Common::Point getCursorPos(); - virtual void moveCursor(Common::Point pos); - void setCursorZone(Common::Rect zone); - - virtual int16 getCelWidth(GuiResourceId viewId, int16 loopNo, int16 celNo); - virtual int16 getCelHeight(GuiResourceId viewId, int16 loopNo, int16 celNo); - - virtual int16 getLoopCount(GuiResourceId viewId); - virtual int16 getCelCount(GuiResourceId viewId, int16 loopNo); - - virtual reg_t portraitLoad(Common::String resourceName); - virtual void portraitShow(Common::String resourceName, Common::Point position, uint16 resourceNum, uint16 noun, uint16 verb, uint16 cond, uint16 seq); - virtual void portraitUnload(uint16 portraitId); - - virtual uint16 getScreenWidth(); - virtual uint16 getScreenHeight(); - -#ifdef ENABLE_SCI32 - // SCI32 - virtual void addScreenItem(reg_t object); - virtual void deleteScreenItem(reg_t object); - virtual void addPlane(reg_t object); - virtual void updatePlane(reg_t object); - virtual void deletePlane(reg_t object); - virtual void frameOut(); -#endif - - virtual bool debugUndither(bool flag); - virtual bool debugShowMap(int mapNo); - - // FIXME: Don't store EngineState - virtual void resetEngineState(EngineState *s); - -protected: - SciGuiCursor *_cursor; - EngineState *_s; - SciGuiScreen *_screen; - SciGuiPalette *_palette; - SciGuiGfx *_gfx; - -private: - virtual void initPriorityBands(); - virtual void addToPicSetPicNotValid(); - virtual int getControlPicNotValid(); - - SciGuiWindowMgr *_windowMgr; - SciGuiAnimate *_animate; - SciGuiControls *_controls; - SciGuiMenu *_menu; - SciGuiText *_text; - SciGuiTransitions *_transitions; -// SciGui32 *_gui32; // for debug purposes - - bool _usesOldGfxFunctions; - -#ifdef ENABLE_SCI32 - Common::Array _screenItems; - Common::Array _planes; -#endif -}; - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui/gui_animate.cpp b/engines/sci/gui/gui_animate.cpp deleted file mode 100644 index 16e67873aa..0000000000 --- a/engines/sci/gui/gui_animate.cpp +++ /dev/null @@ -1,559 +0,0 @@ -/* 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/util.h" -#include "common/stack.h" -#include "graphics/primitives.h" - -#include "sci/sci.h" -#include "sci/engine/state.h" -#include "sci/engine/vm.h" -#include "sci/gui/gui_gfx.h" -#include "sci/gui/gui_view.h" -#include "sci/gui/gui_screen.h" -#include "sci/gui/gui_transitions.h" -#include "sci/gui/gui_animate.h" - -namespace Sci { - -SciGuiAnimate::SciGuiAnimate(EngineState *state, SciGuiGfx *gfx, SciGuiScreen *screen, SciGuiPalette *palette) - : _s(state), _gfx(gfx), _screen(screen), _palette(palette) { - init(); -} - -SciGuiAnimate::~SciGuiAnimate() { - free(_listData); - free(_lastCastData); -} - -void SciGuiAnimate::init() { - _listData = NULL; - _listCount = 0; - _lastCastData = NULL; - _lastCastCount = 0; - - _ignoreFastCast = false; - // fastCast object is not found in any SCI games prior SCI1 - if (getSciVersion() <= SCI_VERSION_01) - _ignoreFastCast = true; - // Also if fastCast object exists at gamestartup, we can assume that the interpreter doesnt do kAnimate aborts - // (found in larry 1) - if (!_s->_segMan->findObjectByName("fastCast").isNull()) - _ignoreFastCast = true; -} - -void SciGuiAnimate::disposeLastCast() { - _lastCastCount = 0; -} - -bool SciGuiAnimate::invoke(List *list, int argc, reg_t *argv) { - reg_t curAddress = list->first; - Node *curNode = _s->_segMan->lookupNode(curAddress); - reg_t curObject; - uint16 signal; - - while (curNode) { - curObject = curNode->value; - - if (!_ignoreFastCast) { - // Check if the game has a fastCast object set - // if we don't abort kAnimate processing, at least in kq5 there will be animation cels drawn into speech boxes. - reg_t global84 = _s->script_000->_localsBlock->_locals[84]; - - if (!global84.isNull()) { - if (!strcmp(_s->_segMan->getObjectName(global84), "fastCast")) - return false; - } - } - - signal = GET_SEL32V(_s->_segMan, curObject, signal); - if (!(signal & kSignalFrozen)) { - // Call .doit method of that object - invoke_selector(_s, curObject, _s->_kernel->_selectorCache.doit, kContinueOnInvalidSelector, argv, argc, 0); - // Lookup node again, since the nodetable it was in may have been reallocated - curNode = _s->_segMan->lookupNode(curAddress); - } - curAddress = curNode->succ; - curNode = _s->_segMan->lookupNode(curAddress); - } - return true; -} - -bool sortHelper(const GuiAnimateEntry* entry1, const GuiAnimateEntry* entry2) { - return (entry1->y == entry2->y) ? (entry1->z < entry2->z) : (entry1->y < entry2->y); -} - -void SciGuiAnimate::makeSortedList(List *list) { - reg_t curAddress = list->first; - Node *curNode = _s->_segMan->lookupNode(curAddress); - reg_t curObject; - GuiAnimateEntry *listEntry; - int16 listNr, listCount = 0; - - // Count the list entries - while (curNode) { - listCount++; - curAddress = curNode->succ; - curNode = _s->_segMan->lookupNode(curAddress); - } - - _list.clear(); - - // No entries -> exit immediately - if (listCount == 0) - return; - - // Adjust list size, if needed - if ((_listData == NULL) || (_listCount < listCount)) { - free(_listData); - _listData = (GuiAnimateEntry *)malloc(listCount * sizeof(GuiAnimateEntry)); - if (!_listData) - error("Could not allocate memory for _listData"); - _listCount = listCount; - - free(_lastCastData); - _lastCastData = (GuiAnimateEntry *)malloc(listCount * sizeof(GuiAnimateEntry)); - if (!_lastCastData) - error("Could not allocate memory for _lastCastData"); - _lastCastCount = 0; - } - - // Fill the list - curAddress = list->first; - curNode = _s->_segMan->lookupNode(curAddress); - listEntry = _listData; - for (listNr = 0; listNr < listCount; listNr++) { - curObject = curNode->value; - listEntry->object = curObject; - - // Get data from current object - listEntry->viewId = GET_SEL32V(_s->_segMan, curObject, view); - listEntry->loopNo = GET_SEL32V(_s->_segMan, curObject, loop); - listEntry->celNo = GET_SEL32V(_s->_segMan, curObject, cel); - listEntry->paletteNo = GET_SEL32V(_s->_segMan, curObject, palette); - listEntry->x = GET_SEL32V(_s->_segMan, curObject, x); - listEntry->y = GET_SEL32V(_s->_segMan, curObject, y); - listEntry->z = GET_SEL32V(_s->_segMan, curObject, z); - listEntry->priority = GET_SEL32V(_s->_segMan, curObject, priority); - listEntry->signal = GET_SEL32V(_s->_segMan, curObject, signal); - // listEntry->celRect is filled in AnimateFill() - listEntry->showBitsFlag = false; - - _list.push_back(listEntry); - - listEntry++; - curAddress = curNode->succ; - curNode = _s->_segMan->lookupNode(curAddress); - } - - // Now sort the list according y and z (descending) - GuiAnimateList::iterator listBegin = _list.begin(); - GuiAnimateList::iterator listEnd = _list.end(); - - Common::sort(_list.begin(), _list.end(), sortHelper); -} - -void SciGuiAnimate::fill(byte &old_picNotValid) { - reg_t curObject; - GuiAnimateEntry *listEntry; - uint16 signal; - SciGuiView *view = NULL; - GuiAnimateList::iterator listIterator; - GuiAnimateList::iterator listEnd = _list.end(); - - listIterator = _list.begin(); - while (listIterator != listEnd) { - listEntry = *listIterator; - curObject = listEntry->object; - - // Get the corresponding view - view = _gfx->getView(listEntry->viewId); - - // adjust loop and cel, if any of those is invalid - if (listEntry->loopNo >= view->getLoopCount()) { - listEntry->loopNo = 0; - PUT_SEL32V(_s->_segMan, curObject, loop, listEntry->loopNo); - } - if (listEntry->celNo >= view->getCelCount(listEntry->loopNo)) { - listEntry->celNo = 0; - PUT_SEL32V(_s->_segMan, curObject, cel, listEntry->celNo); - } - - // Create rect according to coordinates and given cel - view->getCelRect(listEntry->loopNo, listEntry->celNo, listEntry->x, listEntry->y, listEntry->z, &listEntry->celRect); - PUT_SEL32V(_s->_segMan, curObject, nsLeft, listEntry->celRect.left); - PUT_SEL32V(_s->_segMan, curObject, nsTop, listEntry->celRect.top); - PUT_SEL32V(_s->_segMan, curObject, nsRight, listEntry->celRect.right); - PUT_SEL32V(_s->_segMan, curObject, nsBottom, listEntry->celRect.bottom); - - signal = listEntry->signal; - - // Calculate current priority according to y-coordinate - if (!(signal & kSignalFixedPriority)) { - listEntry->priority = _gfx->CoordinateToPriority(listEntry->y); - PUT_SEL32V(_s->_segMan, curObject, priority, listEntry->priority); - } - - if (signal & kSignalNoUpdate) { - if (signal & (kSignalForceUpdate | kSignalViewUpdated) - || (signal & kSignalHidden && !(signal & kSignalRemoveView)) - || (!(signal & kSignalHidden) && signal & kSignalRemoveView) - || (signal & kSignalAlwaysUpdate)) - old_picNotValid++; - signal &= 0xFFFF ^ kSignalStopUpdate; - } else { - if (signal & kSignalStopUpdate || signal & kSignalAlwaysUpdate) - old_picNotValid++; - signal &= 0xFFFF ^ kSignalForceUpdate; - } - listEntry->signal = signal; - - listIterator++; - } -} - -void SciGuiAnimate::update() { - reg_t curObject; - GuiAnimateEntry *listEntry; - uint16 signal; - reg_t bitsHandle; - Common::Rect rect; - GuiAnimateList::iterator listIterator; - GuiAnimateList::iterator listBegin = _list.begin(); - GuiAnimateList::iterator listEnd = _list.end(); - - // Remove all no-update cels, if requested - listIterator = _list.reverse_begin(); - while (listIterator != listEnd) { - listEntry = *listIterator; - curObject = listEntry->object; - signal = listEntry->signal; - - if (signal & kSignalNoUpdate) { - if (!(signal & kSignalRemoveView)) { - bitsHandle = GET_SEL32(_s->_segMan, curObject, underBits); - if (_screen->_picNotValid != 1) { - _gfx->BitsRestore(bitsHandle); - listEntry->showBitsFlag = true; - } else { - _gfx->BitsFree(bitsHandle); - } - PUT_SEL32V(_s->_segMan, curObject, underBits, 0); - } - signal &= 0xFFFF ^ kSignalForceUpdate; - signal &= signal & kSignalViewUpdated ? 0xFFFF ^ (kSignalViewUpdated | kSignalNoUpdate) : 0xFFFF; - } else if (signal & kSignalStopUpdate) { - signal = (signal & (0xFFFF ^ kSignalStopUpdate)) | kSignalNoUpdate; - } - listEntry->signal = signal; - listIterator--; - } - - // Draw always-update cels - listIterator = listBegin; - while (listIterator != listEnd) { - listEntry = *listIterator; - curObject = listEntry->object; - signal = listEntry->signal; - - if (signal & kSignalAlwaysUpdate) { - // draw corresponding cel - _gfx->drawCel(listEntry->viewId, listEntry->loopNo, listEntry->celNo, listEntry->celRect, listEntry->priority, listEntry->paletteNo); - listEntry->showBitsFlag = true; - - signal &= 0xFFFF ^ (kSignalStopUpdate | kSignalViewUpdated | kSignalNoUpdate | kSignalForceUpdate); - if ((signal & kSignalIgnoreActor) == 0) { - rect = listEntry->celRect; - rect.top = CLIP(_gfx->PriorityToCoordinate(listEntry->priority) - 1, rect.top, rect.bottom - 1); - _gfx->FillRect(rect, SCI_SCREEN_MASK_CONTROL, 0, 0, 15); - } - listEntry->signal = signal; - } - listIterator++; - } - - // Saving background for all NoUpdate-cels - listIterator = listBegin; - while (listIterator != listEnd) { - listEntry = *listIterator; - curObject = listEntry->object; - signal = listEntry->signal; - - if (signal & kSignalNoUpdate) { - if (signal & kSignalHidden) { - signal |= kSignalRemoveView; - } else { - signal &= 0xFFFF ^ kSignalRemoveView; - if (signal & kSignalIgnoreActor) - bitsHandle = _gfx->BitsSave(listEntry->celRect, SCI_SCREEN_MASK_VISUAL|SCI_SCREEN_MASK_PRIORITY); - else - bitsHandle = _gfx->BitsSave(listEntry->celRect, SCI_SCREEN_MASK_ALL); - PUT_SEL32(_s->_segMan, curObject, underBits, bitsHandle); - } - listEntry->signal = signal; - } - listIterator++; - } - - // Draw NoUpdate cels - listIterator = listBegin; - while (listIterator != listEnd) { - listEntry = *listIterator; - curObject = listEntry->object; - signal = listEntry->signal; - - if (signal & kSignalNoUpdate && !(signal & kSignalHidden)) { - // draw corresponding cel - _gfx->drawCel(listEntry->viewId, listEntry->loopNo, listEntry->celNo, listEntry->celRect, listEntry->priority, listEntry->paletteNo); - listEntry->showBitsFlag = true; - - if ((signal & kSignalIgnoreActor) == 0) { - rect = listEntry->celRect; - rect.top = CLIP(_gfx->PriorityToCoordinate(listEntry->priority) - 1, rect.top, rect.bottom - 1); - _gfx->FillRect(rect, SCI_SCREEN_MASK_CONTROL, 0, 0, 15); - } - } - listIterator++; - } -} - -void SciGuiAnimate::drawCels() { - reg_t curObject; - GuiAnimateEntry *listEntry; - GuiAnimateEntry *lastCastEntry = _lastCastData; - uint16 signal; - reg_t bitsHandle; - GuiAnimateList::iterator listIterator; - GuiAnimateList::iterator listEnd = _list.end(); - - _lastCastCount = 0; - - listIterator = _list.begin(); - while (listIterator != listEnd) { - listEntry = *listIterator; - curObject = listEntry->object; - signal = listEntry->signal; - - if (!(signal & (kSignalNoUpdate | kSignalHidden | kSignalAlwaysUpdate))) { - // Save background - bitsHandle = _gfx->BitsSave(listEntry->celRect, SCI_SCREEN_MASK_ALL); - PUT_SEL32(_s->_segMan, curObject, underBits, bitsHandle); - - // draw corresponding cel - _gfx->drawCel(listEntry->viewId, listEntry->loopNo, listEntry->celNo, listEntry->celRect, listEntry->priority, listEntry->paletteNo); - listEntry->showBitsFlag = true; - - if (signal & kSignalRemoveView) { - signal &= 0xFFFF ^ kSignalRemoveView; - } - listEntry->signal = signal; - - // Remember that entry in lastCast - memcpy(lastCastEntry, listEntry, sizeof(GuiAnimateEntry)); - lastCastEntry++; _lastCastCount++; - } - listIterator++; - } -} - -void SciGuiAnimate::updateScreen(byte oldPicNotValid) { - reg_t curObject; - GuiAnimateEntry *listEntry; - uint16 signal; - GuiAnimateList::iterator listIterator; - GuiAnimateList::iterator listEnd = _list.end(); - Common::Rect lsRect; - Common::Rect workerRect; - - listIterator = _list.begin(); - while (listIterator != listEnd) { - listEntry = *listIterator; - curObject = listEntry->object; - signal = listEntry->signal; - - if (listEntry->showBitsFlag || !(signal & (kSignalRemoveView | kSignalNoUpdate) || - (!(signal & kSignalRemoveView) && (signal & kSignalNoUpdate) && oldPicNotValid))) { - lsRect.left = GET_SEL32V(_s->_segMan, curObject, lsLeft); - lsRect.top = GET_SEL32V(_s->_segMan, curObject, lsTop); - lsRect.right = GET_SEL32V(_s->_segMan, curObject, lsRight); - lsRect.bottom = GET_SEL32V(_s->_segMan, curObject, lsBottom); - - workerRect = lsRect; - workerRect.clip(listEntry->celRect); - - if (!workerRect.isEmpty()) { - workerRect = lsRect; - workerRect.extend(listEntry->celRect); - } else { - _gfx->BitsShow(lsRect); - workerRect = listEntry->celRect; - } - PUT_SEL32V(_s->_segMan, curObject, lsLeft, workerRect.left); - PUT_SEL32V(_s->_segMan, curObject, lsTop, workerRect.top); - PUT_SEL32V(_s->_segMan, curObject, lsRight, workerRect.right); - PUT_SEL32V(_s->_segMan, curObject, lsBottom, workerRect.bottom); - _gfx->BitsShow(workerRect); - - if (signal & kSignalHidden) { - listEntry->signal |= kSignalRemoveView; - } - } - - listIterator++; - } - // use this for debug purposes - // _screen->copyToScreen(); -} - -void SciGuiAnimate::restoreAndDelete(int argc, reg_t *argv) { - reg_t curObject; - GuiAnimateEntry *listEntry; - uint16 signal; - GuiAnimateList::iterator listIterator; - GuiAnimateList::iterator listEnd = _list.end(); - - - // This has to be done in a separate loop. At least in sq1 some .dispose modifies FIXEDLOOP flag in signal for - // another object. In that case we would overwrite the new signal with our version of the old signal - listIterator = _list.begin(); - while (listIterator != listEnd) { - listEntry = *listIterator; - curObject = listEntry->object; - signal = listEntry->signal; - - // Finally update signal - PUT_SEL32V(_s->_segMan, curObject, signal, signal); - listIterator++; - } - - listIterator = _list.reverse_begin(); - while (listIterator != listEnd) { - listEntry = *listIterator; - curObject = listEntry->object; - // We read out signal here again, this is not by accident but to ensure that we got an up-to-date signal - signal = GET_SEL32V(_s->_segMan, curObject, signal); - - if ((signal & (kSignalNoUpdate | kSignalRemoveView)) == 0) { - _gfx->BitsRestore(GET_SEL32(_s->_segMan, curObject, underBits)); - PUT_SEL32V(_s->_segMan, curObject, underBits, 0); - } - - if (signal & kSignalDisposeMe) { - // Call .delete_ method of that object - invoke_selector(_s, curObject, _s->_kernel->_selectorCache.delete_, kContinueOnInvalidSelector, argv, argc, 0); - } - listIterator--; - } -} - -void SciGuiAnimate::reAnimate(Common::Rect rect) { - GuiAnimateEntry *lastCastEntry; - uint16 lastCastCount; - - if (_lastCastCount > 0) { - lastCastEntry = _lastCastData; - lastCastCount = _lastCastCount; - while (lastCastCount > 0) { - lastCastEntry->castHandle = _gfx->BitsSave(lastCastEntry->celRect, SCI_SCREEN_MASK_VISUAL|SCI_SCREEN_MASK_PRIORITY); - _gfx->drawCel(lastCastEntry->viewId, lastCastEntry->loopNo, lastCastEntry->celNo, lastCastEntry->celRect, lastCastEntry->priority, lastCastEntry->paletteNo); - lastCastEntry++; lastCastCount--; - } - _gfx->BitsShow(rect); - // restoring - lastCastCount = _lastCastCount; - while (lastCastCount > 0) { - lastCastEntry--; - _gfx->BitsRestore(lastCastEntry->castHandle); - lastCastCount--; - } - } else { - _gfx->BitsShow(rect); - } - - /* - if (!_lastCast->isEmpty()) { - HEAPHANDLE hnode = _lastCast->getFirst(); - sciCast *pCast; - CResView *res; - while (hnode) { - pCast = (sciCast *)heap2Ptr(hnode); - res = (CResView *)ResMgr.ResLoad(SCI_RES_VIEW, pCast->view); - pCast->hSaved = _gfx->SaveBits(pCast->rect, 3); - res->drawCel(pCast->loop, pCast->cel, &pCast->rect, pCast->z, pCast->pal); - hnode = pCast->node.next; - } - _gfx->BitsShow(rect); - // restoring - hnode = _lastCast->getLast(); - while (hnode) { - pCast = (sciCast *)heap2Ptr(hnode); - _gfx->BitsShow(pCast->hSaved); - hnode = pCast->node.prev; - } - */ -} - -void SciGuiAnimate::addToPicDrawCels() { - reg_t curObject; - GuiAnimateEntry *listEntry; - SciGuiView *view = NULL; - GuiAnimateList::iterator listIterator; - GuiAnimateList::iterator listEnd = _list.end(); - - listIterator = _list.begin(); - while (listIterator != listEnd) { - listEntry = *listIterator; - curObject = listEntry->object; - - if (listEntry->priority == -1) - listEntry->priority = _gfx->CoordinateToPriority(listEntry->y); - - // Get the corresponding view - view = _gfx->getView(listEntry->viewId); - - // Create rect according to coordinates and given cel - view->getCelRect(listEntry->loopNo, listEntry->celNo, listEntry->x, listEntry->y, listEntry->z, &listEntry->celRect); - - // draw corresponding cel - _gfx->drawCel(listEntry->viewId, listEntry->loopNo, listEntry->celNo, listEntry->celRect, listEntry->priority, listEntry->paletteNo); - if ((listEntry->signal & kSignalIgnoreActor) == 0) { - listEntry->celRect.top = CLIP(_gfx->PriorityToCoordinate(listEntry->priority) - 1, listEntry->celRect.top, listEntry->celRect.bottom - 1); - _gfx->FillRect(listEntry->celRect, SCI_SCREEN_MASK_CONTROL, 0, 0, 15); - } - - listIterator++; - } -} - -void SciGuiAnimate::addToPicDrawView(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, int16 leftPos, int16 topPos, int16 priority, int16 control) { - SciGuiView *view = _gfx->getView(viewId); - Common::Rect celRect; - - // Create rect according to coordinates and given cel - view->getCelRect(loopNo, celNo, leftPos, topPos, priority, &celRect); - _gfx->drawCel(view, loopNo, celNo, celRect, priority, 0); -} - -} // End of namespace Sci diff --git a/engines/sci/gui/gui_animate.h b/engines/sci/gui/gui_animate.h deleted file mode 100644 index ca6400d0da..0000000000 --- a/engines/sci/gui/gui_animate.h +++ /dev/null @@ -1,99 +0,0 @@ -/* 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_ANIMATE_H -#define SCI_GUI_ANIMATE_H - -#include "sci/gui/gui_helpers.h" - -namespace Sci { - -// Flags for the signal selector -enum ViewSignals { - kSignalStopUpdate = 0x0001, - kSignalViewUpdated = 0x0002, - kSignalNoUpdate = 0x0004, - kSignalHidden = 0x0008, - kSignalFixedPriority = 0x0010, - kSignalAlwaysUpdate = 0x0020, - kSignalForceUpdate = 0x0040, - kSignalRemoveView = 0x0080, - kSignalFrozen = 0x0100, - kSignalExtraActor = 0x0200, // unused by us, defines all actors that may be included into the background if speed to slow - kSignalHitObstacle = 0x0400, // used in the actor movement code by kDoBresen() - kSignalDoesntTurn = 0x0800, // used by _k_dirloop() to determine if an actor can turn or not - kSignalNoCycler = 0x1000, // unused by us - kSignalIgnoreHorizon = 0x2000, // unused by us, defines actor that can ignore horizon - kSignalIgnoreActor = 0x4000, - kSignalDisposeMe = 0x8000, - - kSignalStopUpdHack = 0x20000000 // View has been stop-updated (again???) - a hack used by the old GUI code only, for dynamic views -}; - -class SciGuiGfx; -class SciGuiScreen; -class SciGuiPalette; -class SciGuiTransitions; -class SciGuiAnimate { -public: - SciGuiAnimate(EngineState *state, SciGuiGfx *gfx, SciGuiScreen *screen, SciGuiPalette *palette); - ~SciGuiAnimate(); - - // FIXME: Don't store EngineState - void resetEngineState(EngineState *newState) { _s = newState; } - - void disposeLastCast(); - bool invoke(List *list, int argc, reg_t *argv); - void makeSortedList(List *list); - void fill(byte &oldPicNotValid); - void update(); - void drawCels(); - void updateScreen(byte oldPicNotValid); - void restoreAndDelete(int argc, reg_t *argv); - void reAnimate(Common::Rect rect); - void addToPicDrawCels(); - void addToPicDrawView(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, int16 leftPos, int16 topPos, int16 priority, int16 control); - -private: - void init(); - - EngineState *_s; - SciGuiGfx *_gfx; - SciGuiScreen *_screen; - SciGuiPalette *_palette; - - uint16 _listCount; - GuiAnimateEntry *_listData; - GuiAnimateList _list; - - uint16 _lastCastCount; - GuiAnimateEntry *_lastCastData; - - bool _ignoreFastCast; -}; - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui/gui_controls.cpp b/engines/sci/gui/gui_controls.cpp deleted file mode 100644 index 55385084dc..0000000000 --- a/engines/sci/gui/gui_controls.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/* 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/util.h" -#include "common/stack.h" -#include "graphics/primitives.h" - -#include "sci/sci.h" -#include "sci/event.h" -#include "sci/engine/state.h" -#include "sci/gui/gui_gfx.h" -#include "sci/gui/gui_font.h" -#include "sci/gui/gui_text.h" -#include "sci/gui/gui_controls.h" - -namespace Sci { - -SciGuiControls::SciGuiControls(SegManager *segMan, SciGuiGfx *gfx, SciGuiText *text) - : _segMan(segMan), _gfx(gfx), _text(text) { - init(); -} - -SciGuiControls::~SciGuiControls() { -} - -void SciGuiControls::init() { - _texteditCursorVisible = false; -} - -const char controlListUpArrow[2] = { 0x18, 0 }; -const char controlListDownArrow[2] = { 0x19, 0 }; - -void SciGuiControls::drawListControl(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 upperPos, int16 cursorPos, bool isAlias) { - Common::Rect workerRect = rect; - GuiResourceId oldFontId = _text->GetFontId(); - int16 oldPenColor = _gfx->_curPort->penClr; - uint16 fontSize = 0; - int16 i; - const char *listEntry; - int16 listEntryLen; - int16 lastYpos; - - // draw basic window - _gfx->EraseRect(workerRect); - workerRect.grow(1); - _gfx->FrameRect(workerRect); - - // draw UP/DOWN arrows - // we draw UP arrow one pixel lower than sierra did, because it looks nicer. Also the DOWN arrow has one pixel - // line inbetween as well - workerRect.top++; - _text->Box(controlListUpArrow, 0, workerRect, SCI_TEXT_ALIGNMENT_CENTER, 0); - workerRect.top = workerRect.bottom - 10; - _text->Box(controlListDownArrow, 0, workerRect, SCI_TEXT_ALIGNMENT_CENTER, 0); - - // Draw inner lines - workerRect.top = rect.top + 9; - workerRect.bottom -= 10; - _gfx->FrameRect(workerRect); - workerRect.grow(-1); - - _text->SetFont(fontId); - fontSize = _gfx->_curPort->fontHeight; - _gfx->PenColor(_gfx->_curPort->penClr); _gfx->BackColor(_gfx->_curPort->backClr); - workerRect.bottom = workerRect.top + 9; - lastYpos = rect.bottom - fontSize; - - // Write actual text - for (i = upperPos; i < count; i++) { - _gfx->EraseRect(workerRect); - listEntry = entries[i]; - if (listEntry[0]) { - _gfx->MoveTo(workerRect.left, workerRect.top); - listEntryLen = strlen(listEntry); - _text->Draw(listEntry, 0, MIN(maxChars, listEntryLen), oldFontId, oldPenColor); - if ((!isAlias) && (i == cursorPos)) { - _gfx->InvertRect(workerRect); - } - } - workerRect.translate(0, fontSize); - if (workerRect.bottom > lastYpos) - break; - } - - _text->SetFont(oldFontId); -} - -void SciGuiControls::TexteditCursorDraw(Common::Rect rect, const char *text, uint16 curPos) { - int16 textWidth, i; - if (!_texteditCursorVisible) { - textWidth = 0; - for (i = 0; i < curPos; i++) { - textWidth += _text->_font->getCharWidth(text[i]); - } - _texteditCursorRect.left = rect.left + textWidth; - _texteditCursorRect.top = rect.top; - _texteditCursorRect.bottom = _texteditCursorRect.top + _text->_font->getHeight(); - _texteditCursorRect.right = _texteditCursorRect.left + (text[curPos] == 0 ? 1 : _text->_font->getCharWidth(text[curPos])); - _gfx->InvertRect(_texteditCursorRect); - _gfx->BitsShow(_texteditCursorRect); - _texteditCursorVisible = true; - TexteditSetBlinkTime(); - } -} - -void SciGuiControls::TexteditCursorErase() { - if (_texteditCursorVisible) { - _gfx->InvertRect(_texteditCursorRect); - _gfx->BitsShow(_texteditCursorRect); - _texteditCursorVisible = false; - } - TexteditSetBlinkTime(); -} - -void SciGuiControls::TexteditSetBlinkTime() { - _texteditBlinkTime = g_system->getMillis() + (30 * 1000 / 60); -} - -void SciGuiControls::TexteditChange(reg_t controlObject, reg_t eventObject) { - uint16 cursorPos = GET_SEL32V(_segMan, controlObject, cursor); - uint16 maxChars = GET_SEL32V(_segMan, controlObject, max); - reg_t textReference = GET_SEL32(_segMan, controlObject, text); - Common::String text; - uint16 textSize, eventType, eventKey; - bool textChanged = false; - Common::Rect rect; - - if (textReference.isNull()) - error("kEditControl called on object that doesnt have a text reference"); - text = _segMan->getString(textReference); - - if (!eventObject.isNull()) { - textSize = text.size(); - eventType = GET_SEL32V(_segMan, eventObject, type); - - switch (eventType) { - case SCI_EVENT_MOUSE_PRESS: - // TODO: Implement mouse support for cursor change - break; - case SCI_EVENT_KEYBOARD: - eventKey = GET_SEL32V(_segMan, eventObject, message); - switch (eventKey) { - case SCI_KEY_BACKSPACE: - if (cursorPos > 0) { - cursorPos--; text.deleteChar(cursorPos); - textChanged = true; - } - break; - case SCI_KEY_DELETE: - text.deleteChar(cursorPos); - textChanged = true; - break; - case SCI_KEY_HOME: // HOME - cursorPos = 0; textChanged = true; - break; - case SCI_KEY_END: // END - cursorPos = textSize; textChanged = true; - break; - case SCI_KEY_LEFT: // LEFT - if (cursorPos > 0) { - cursorPos--; textChanged = true; - } - break; - case SCI_KEY_RIGHT: // RIGHT - if (cursorPos + 1 <= textSize) { - cursorPos++; textChanged = true; - } - break; - default: - if (eventKey > 31 && eventKey < 256 && textSize < maxChars) { - // insert pressed character - // we check, if there is space left for this character - - text.insertChar(eventKey, cursorPos++); - textChanged = true; - } - break; - } - break; - } - } - - if (textChanged) { - GuiResourceId oldFontId = _text->GetFontId(); - GuiResourceId fontId = GET_SEL32V(_segMan, controlObject, font); - rect = Common::Rect(GET_SEL32V(_segMan, controlObject, nsLeft), GET_SEL32V(_segMan, controlObject, nsTop), - GET_SEL32V(_segMan, controlObject, nsRight), GET_SEL32V(_segMan, controlObject, nsBottom)); - TexteditCursorErase(); - _gfx->EraseRect(rect); - _text->Box(text.c_str(), 0, rect, SCI_TEXT_ALIGNMENT_LEFT, fontId); - _gfx->BitsShow(rect); - _text->SetFont(fontId); - TexteditCursorDraw(rect, text.c_str(), cursorPos); - _text->SetFont(oldFontId); - // Write back string - _segMan->strcpy(textReference, text.c_str()); - } else { - if (g_system->getMillis() >= _texteditBlinkTime) { - _gfx->InvertRect(_texteditCursorRect); - _gfx->BitsShow(_texteditCursorRect); - _texteditCursorVisible = !_texteditCursorVisible; - TexteditSetBlinkTime(); - } - } - - PUT_SEL32V(_segMan, controlObject, cursor, cursorPos); -} - -} // End of namespace Sci diff --git a/engines/sci/gui/gui_controls.h b/engines/sci/gui/gui_controls.h deleted file mode 100644 index a2d027d514..0000000000 --- a/engines/sci/gui/gui_controls.h +++ /dev/null @@ -1,60 +0,0 @@ -/* 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_CONTROLS_H -#define SCI_GUI_CONTROLS_H - -namespace Sci { - -class SciGuiGfx; -class SciGuiFont; -class SciGuiText; -class SciGuiControls { -public: - SciGuiControls(SegManager *segMan, SciGuiGfx *gfx, SciGuiText *text); - ~SciGuiControls(); - - void drawListControl(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 upperPos, int16 cursorPos, bool isAlias); - void TexteditCursorDraw(Common::Rect rect, const char *text, uint16 curPos); - void TexteditCursorErase(); - void TexteditChange(reg_t controlObject, reg_t eventObject); - -private: - void init(); - void TexteditSetBlinkTime(); - - SegManager *_segMan; - SciGuiGfx *_gfx; - SciGuiText *_text; - - // Textedit-Control related - Common::Rect _texteditCursorRect; - bool _texteditCursorVisible; - uint32 _texteditBlinkTime; -}; - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui/gui_cursor.cpp b/engines/sci/gui/gui_cursor.cpp deleted file mode 100644 index cf6256640f..0000000000 --- a/engines/sci/gui/gui_cursor.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* 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 "graphics/cursorman.h" -#include "common/util.h" -#include "common/events.h" - -#include "sci/sci.h" -#include "sci/engine/state.h" -#include "sci/gui/gui_palette.h" -#include "sci/gui/gui_screen.h" -#include "sci/gui/gui_view.h" -#include "sci/gui/gui_cursor.h" - -namespace Sci { - -SciGuiCursor::SciGuiCursor(ResourceManager *resMan, SciGuiPalette *palette, SciGuiScreen *screen) - : _resMan(resMan), _palette(palette), _screen(screen) { - - _upscaledHires = _screen->getUpscaledHires(); - // center mouse cursor - setPosition(Common::Point(_screen->_displayWidth / 2, _screen->_displayHeight / 2)); - setMoveZone(Common::Rect(0, 0, _screen->_displayWidth, _screen->_displayHeight)); - - _isVisible = true; -} - -SciGuiCursor::~SciGuiCursor() { - purgeCache(); -} - -void SciGuiCursor::show() { - CursorMan.showMouse(true); - _isVisible = true; -} - -void SciGuiCursor::hide() { - CursorMan.showMouse(false); - _isVisible = false; -} - -bool SciGuiCursor::isVisible() { - return _isVisible; -} - -void SciGuiCursor::purgeCache() { - for (CursorCache::iterator iter = _cachedCursors.begin(); iter != _cachedCursors.end(); ++iter) { - delete iter->_value; - iter->_value = 0; - } - - _cachedCursors.clear(); -} - -void SciGuiCursor::setShape(GuiResourceId resourceId) { - Resource *resource; - byte *resourceData; - Common::Point hotspot = Common::Point(0, 0); - byte colorMapping[4]; - int16 x, y; - byte color; - int16 maskA, maskB; - byte *pOut; - byte *rawBitmap = new byte[SCI_CURSOR_SCI0_HEIGHTWIDTH * SCI_CURSOR_SCI0_HEIGHTWIDTH]; - - if (resourceId == -1) { - // no resourceId given, so we actually hide the cursor - hide(); - delete[] rawBitmap; - return; - } - - // Load cursor resource... - resource = _resMan->findResource(ResourceId(kResourceTypeCursor, resourceId), false); - if (!resource) - error("cursor resource %d not found", resourceId); - if (resource->size != SCI_CURSOR_SCI0_RESOURCESIZE) - error("cursor resource %d has invalid size", resourceId); - - resourceData = resource->data; - // hotspot is specified for SCI1 cursors - hotspot.x = READ_LE_UINT16(resourceData); - hotspot.y = READ_LE_UINT16(resourceData + 2); - // bit 0 of resourceData[3] is set on _colorWhite; // White is also hardcoded - colorMapping[2] = SCI_CURSOR_SCI0_TRANSPARENCYCOLOR; - colorMapping[3] = _palette->matchColor(&_palette->_sysPalette, 170, 170, 170); // Grey - - // Seek to actual data - resourceData += 4; - - pOut = rawBitmap; - for (y = 0; y < SCI_CURSOR_SCI0_HEIGHTWIDTH; y++) { - maskA = READ_LE_UINT16(resourceData + (y << 1)); - maskB = READ_LE_UINT16(resourceData + 32 + (y << 1)); - - for (x = 0; x < SCI_CURSOR_SCI0_HEIGHTWIDTH; x++) { - color = (((maskA << x) & 0x8000) | (((maskB << x) >> 1) & 0x4000)) >> 14; - *pOut++ = colorMapping[color]; - } - } - - CursorMan.replaceCursor(rawBitmap, SCI_CURSOR_SCI0_HEIGHTWIDTH, SCI_CURSOR_SCI0_HEIGHTWIDTH, hotspot.x, hotspot.y, SCI_CURSOR_SCI0_TRANSPARENCYCOLOR); - CursorMan.showMouse(true); - - delete[] rawBitmap; -} - -void SciGuiCursor::setView(GuiResourceId viewNum, int loopNum, int celNum, Common::Point *hotspot) { - if (_cachedCursors.size() >= MAX_CACHED_CURSORS) - purgeCache(); - - if (!_cachedCursors.contains(viewNum)) - _cachedCursors[viewNum] = new SciGuiView(_resMan, _screen, _palette, viewNum); - - SciGuiView *cursorView = _cachedCursors[viewNum]; - - sciViewCelInfo *celInfo = cursorView->getCelInfo(loopNum, celNum); - int16 width = celInfo->width; - int16 height = celInfo->height; - byte clearKey = celInfo->clearKey; - Common::Point *cursorHotspot = hotspot; - if (!cursorHotspot) - // Compute hotspot from xoffset/yoffset - cursorHotspot = new Common::Point((celInfo->width >> 1) - celInfo->displaceX, celInfo->height - celInfo->displaceY - 1); - - // Eco Quest 1 uses a 1x1 transparent cursor to hide the cursor from the user. Some scalers don't seem to support this - if (width < 2 || height < 2) { - hide(); - delete cursorHotspot; - return; - } - - byte *cursorBitmap = cursorView->getBitmap(loopNum, celNum); - - if (_upscaledHires) { - // Scale cursor by 2x - width *= 2; - height *= 2; - cursorHotspot->x *= 2; - cursorHotspot->y *= 2; - cursorBitmap = new byte[width * height]; - _screen->scale2x(celInfo->rawBitmap, cursorBitmap, celInfo->width, celInfo->height); - } - - CursorMan.replaceCursor(cursorBitmap, width, height, cursorHotspot->x, cursorHotspot->y, clearKey); - - if (_upscaledHires) - delete[] cursorBitmap; - - show(); - - delete cursorHotspot; -} - -void SciGuiCursor::setPosition(Common::Point pos) { - if (!_upscaledHires) { - g_system->warpMouse(pos.x, pos.y); - } else { - g_system->warpMouse(pos.x * 2, pos.y * 2); - } -} - -Common::Point SciGuiCursor::getPosition() { - Common::Point mousePos = g_system->getEventManager()->getMousePos(); - - if (_upscaledHires) { - mousePos.x /= 2; - mousePos.y /= 2; - } - - return mousePos; -} - -void SciGuiCursor::refreshPosition() { - bool clipped = false; - Common::Point mousePoint = getPosition(); - - if (mousePoint.x < _moveZone.left) { - mousePoint.x = _moveZone.left; - clipped = true; - } else if (mousePoint.x >= _moveZone.right) { - mousePoint.x = _moveZone.right - 1; - clipped = true; - } - - if (mousePoint.y < _moveZone.top) { - mousePoint.y = _moveZone.top; - clipped = true; - } else if (mousePoint.y >= _moveZone.bottom) { - mousePoint.y = _moveZone.bottom - 1; - clipped = true; - } - - // FIXME: Do this only when mouse is grabbed? - if (clipped) - setPosition(mousePoint); -} - -} // End of namespace Sci diff --git a/engines/sci/gui/gui_cursor.h b/engines/sci/gui/gui_cursor.h deleted file mode 100644 index 293c508bdb..0000000000 --- a/engines/sci/gui/gui_cursor.h +++ /dev/null @@ -1,84 +0,0 @@ -/* 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_CURSOR_H -#define SCI_GUI_CURSOR_H - -#include "common/hashmap.h" - -namespace Sci { - -#define SCI_CURSOR_SCI0_HEIGHTWIDTH 16 -#define SCI_CURSOR_SCI0_RESOURCESIZE 68 - -#define SCI_CURSOR_SCI0_TRANSPARENCYCOLOR 1 - -#define MAX_CACHED_CURSORS 10 - -class SciGuiView; -class SciGuiPalette; - -typedef Common::HashMap CursorCache; - -class SciGuiCursor { -public: - SciGuiCursor(ResourceManager *resMan, SciGuiPalette *palette, SciGuiScreen *screen); - ~SciGuiCursor(); - - void show(); - void hide(); - bool isVisible(); - void setShape(GuiResourceId resourceId); - void setView(GuiResourceId viewNum, int loopNum, int celNum, Common::Point *hotspot); - void setPosition(Common::Point pos); - Common::Point getPosition(); - void refreshPosition(); - - /** - * Limits the mouse movement to a given rectangle. - * - * @param[in] rect The rectangle - */ - void setMoveZone(Common::Rect zone) { _moveZone = zone; } - -private: - void purgeCache(); - - ResourceManager *_resMan; - SciGuiScreen *_screen; - SciGuiPalette *_palette; - - bool _upscaledHires; - - Common::Rect _moveZone; // Rectangle in which the pointer can move - - CursorCache _cachedCursors; - - bool _isVisible; -}; - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui/gui_font.cpp b/engines/sci/gui/gui_font.cpp deleted file mode 100644 index 0af0942c1f..0000000000 --- a/engines/sci/gui/gui_font.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* 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 "sci/sci.h" -#include "sci/engine/state.h" -#include "sci/gui/gui_screen.h" -#include "sci/gui/gui_font.h" - -namespace Sci { - -SciGuiFont::SciGuiFont(ResourceManager *resMan, GuiResourceId resourceId) - : _resourceId(resourceId), _resMan(resMan) { - assert(resourceId != -1); - - // Workaround: lsl1sci mixes its own internal fonts with the global - // SCI ones, so we translate them here, by removing their extra bits - if (!resMan->testResource(ResourceId(kResourceTypeFont, resourceId))) - resourceId = resourceId & 0x7ff; - - _resource = resMan->findResource(ResourceId(kResourceTypeFont, resourceId), true); - if (!_resource) { - error("font resource %d not found", resourceId); - } - _resourceData = _resource->data; - - _numChars = READ_LE_UINT16(_resourceData + 2); - _fontHeight = READ_LE_UINT16(_resourceData + 4); - _chars = new Charinfo[_numChars]; - // filling info for every char - for (int16 i = 0; i < _numChars; i++) { - _chars[i].offset = READ_LE_UINT16(_resourceData + 6 + i * 2); - _chars[i].w = _resourceData[_chars[i].offset]; - _chars[i].h = _resourceData[_chars[i].offset + 1]; - } -} - -SciGuiFont::~SciGuiFont() { - delete []_chars; - _resMan->unlockResource(_resource); -} - -GuiResourceId SciGuiFont::getResourceId() { - return _resourceId; -} - -byte SciGuiFont::getHeight() { - return _fontHeight; -} -byte SciGuiFont::getCharWidth(byte chr) { - return chr < _numChars ? _chars[chr].w : 0; -} -byte SciGuiFont::getCharHeight(byte chr) { - return chr < _numChars ? _chars[chr].h : 0; -} -byte *SciGuiFont::getCharData(byte chr) { - return chr < _numChars ? _resourceData + _chars[chr].offset + 2 : 0; -} - -void SciGuiFont::draw(SciGuiScreen *screen, int16 chr, int16 top, int16 left, byte color, bool greyedOutput) { - int charWidth = MIN(getCharWidth(chr), screen->_width - left); - int charHeight = MIN(getCharHeight(chr), 200 - top); - byte b = 0, mask = 0xFF; - int y = top; - - byte *pIn = getCharData(chr); - for (int i = 0; i < charHeight; i++, y++) { - if (greyedOutput) - mask = top++ % 2 ? 0xAA : 0x55; - for (int done = 0; done < charWidth; done++) { - if ((done & 7) == 0) // fetching next data byte - b = *(pIn++) & mask; - if (b & 0x80) // if MSB is set - paint it - screen->putPixel(left + done, y, 1, color, 0, 0); - b = b << 1; - } - } -} - -} // End of namespace Sci diff --git a/engines/sci/gui/gui_font.h b/engines/sci/gui/gui_font.h deleted file mode 100644 index a3b8aa9da5..0000000000 --- a/engines/sci/gui/gui_font.h +++ /dev/null @@ -1,63 +0,0 @@ -/* 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_FONT_H -#define SCI_GUI_FONT_H - -#include "sci/gui/gui_helpers.h" - -namespace Sci { - -class SciGuiFont { -public: - SciGuiFont(ResourceManager *resMan, GuiResourceId resourceId); - ~SciGuiFont(); - - GuiResourceId getResourceId(); - byte getHeight(); - byte getCharWidth(byte chr); - byte getCharHeight(byte chr); - byte *getCharData(byte chr); - void draw(SciGuiScreen *screen, int16 chr, int16 top, int16 left, byte color, bool greyedOutput); - -private: - ResourceManager *_resMan; - - Resource *_resource; - GuiResourceId _resourceId; - byte *_resourceData; - - struct Charinfo { - byte w, h; - int16 offset; - }; - byte _fontHeight; - uint16 _numChars; - Charinfo *_chars; -}; - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui/gui_gfx.cpp b/engines/sci/gui/gui_gfx.cpp deleted file mode 100644 index 18d925e3cf..0000000000 --- a/engines/sci/gui/gui_gfx.cpp +++ /dev/null @@ -1,536 +0,0 @@ -/* 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/util.h" -#include "common/stack.h" -#include "graphics/primitives.h" - -#include "sci/sci.h" -#include "sci/engine/state.h" -#include "sci/gui/gui_gfx.h" -#include "sci/gui/gui_animate.h" -#include "sci/gui/gui_font.h" -#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_text.h" - -namespace Sci { - -SciGuiGfx::SciGuiGfx(ResourceManager *resMan, SegManager *segMan, Kernel *kernel, SciGuiScreen *screen, SciGuiPalette *palette) - : _resMan(resMan), _segMan(segMan), _kernel(kernel), _screen(screen), _palette(palette) { -} - -SciGuiGfx::~SciGuiGfx() { - purgeCache(); - - delete _mainPort; - delete _menuPort; -} - -void SciGuiGfx::init(SciGuiText *text) { - _text = text; - - // _mainPort is not known to windowmanager, that's okay according to sierra sci - // its not even used currently in our engine - _mainPort = new GuiPort(0); - SetPort(_mainPort); - OpenPort(_mainPort); - - // _menuPort has actually hardcoded id 0xFFFF. Its not meant to be known to windowmanager according to sierra sci - _menuPort = new GuiPort(0xFFFF); - OpenPort(_menuPort); - _text->SetFont(0); - _menuPort->rect = Common::Rect(0, 0, _screen->_width, _screen->_height); - _menuBarRect = Common::Rect(0, 0, _screen->_width, 9); -} - -void SciGuiGfx::purgeCache() { - for (ViewCache::iterator iter = _cachedViews.begin(); iter != _cachedViews.end(); ++iter) { - delete iter->_value; - iter->_value = 0; - } - - _cachedViews.clear(); -} - -SciGuiView *SciGuiGfx::getView(GuiResourceId viewNum) { - if (_cachedViews.size() >= MAX_CACHED_VIEWS) - purgeCache(); - - if (!_cachedViews.contains(viewNum)) - _cachedViews[viewNum] = new SciGuiView(_resMan, _screen, _palette, viewNum); - - return _cachedViews[viewNum]; -} - -GuiPort *SciGuiGfx::SetPort(GuiPort *newPort) { - GuiPort *oldPort = _curPort; - _curPort = newPort; - return oldPort; -} - -GuiPort *SciGuiGfx::GetPort() { - return _curPort; -} - -void SciGuiGfx::SetOrigin(int16 left, int16 top) { - _curPort->left = left; - _curPort->top = top; -} - -void SciGuiGfx::MoveTo(int16 left, int16 top) { - _curPort->curTop = top; - _curPort->curLeft = left; -} - -void SciGuiGfx::Move(int16 left, int16 top) { - _curPort->curTop += top; - _curPort->curLeft += left; -} - -void SciGuiGfx::OpenPort(GuiPort *port) { - port->fontId = 0; - port->fontHeight = 8; - - GuiPort *tmp = _curPort; - _curPort = port; - _text->SetFont(port->fontId); - _curPort = tmp; - - port->top = 0; - port->left = 0; - port->greyedOutput = false; - port->penClr = 0; - port->backClr = 255; - port->penMode = 0; - port->rect = _bounds; -} - -void SciGuiGfx::PenColor(int16 color) { - _curPort->penClr = color; -} - -void SciGuiGfx::BackColor(int16 color) { - _curPort->backClr = color; -} - -void SciGuiGfx::PenMode(int16 mode) { - _curPort->penMode = mode; -} - -void SciGuiGfx::TextGreyedOutput(bool state) { - _curPort->greyedOutput = state; -} - -int16 SciGuiGfx::GetPointSize() { - return _curPort->fontHeight; -} - -void SciGuiGfx::ClearScreen(byte color) { - FillRect(_curPort->rect, SCI_SCREEN_MASK_ALL, color, 0, 0); -} - -void SciGuiGfx::InvertRect(const Common::Rect &rect) { - int16 oldpenmode = _curPort->penMode; - _curPort->penMode = 2; - FillRect(rect, 1, _curPort->penClr, _curPort->backClr); - _curPort->penMode = oldpenmode; -} - -void SciGuiGfx::EraseRect(const Common::Rect &rect) { - FillRect(rect, 1, _curPort->backClr); -} - -void SciGuiGfx::PaintRect(const Common::Rect &rect) { - FillRect(rect, 1, _curPort->penClr); -} - -void SciGuiGfx::FillRect(const Common::Rect &rect, int16 drawFlags, byte clrPen, byte clrBack, byte bControl) { - Common::Rect r = rect; - r.clip(_curPort->rect); - if (r.isEmpty()) // nothing to fill - return; - - int16 oldPenMode = _curPort->penMode; - OffsetRect(r); - int16 x, y; - byte curVisual; - - // Doing visual first - if (drawFlags & SCI_SCREEN_MASK_VISUAL) { - if (oldPenMode == 2) { // invert mode - for (y = r.top; y < r.bottom; y++) { - for (x = r.left; x < r.right; x++) { - curVisual = _screen->getVisual(x, y); - if (curVisual == clrPen) { - _screen->putPixel(x, y, 1, clrBack, 0, 0); - } else if (curVisual == clrBack) { - _screen->putPixel(x, y, 1, clrPen, 0, 0); - } - } - } - } else { // just fill rect with ClrPen - for (y = r.top; y < r.bottom; y++) { - for (x = r.left; x < r.right; x++) { - _screen->putPixel(x, y, 1, clrPen, 0, 0); - } - } - } - } - - if (drawFlags < 2) - return; - drawFlags &= SCI_SCREEN_MASK_PRIORITY|SCI_SCREEN_MASK_CONTROL; - - if (oldPenMode != 2) { - for (y = r.top; y < r.bottom; y++) { - for (x = r.left; x < r.right; x++) { - _screen->putPixel(x, y, drawFlags, 0, clrBack, bControl); - } - } - } else { - for (y = r.top; y < r.bottom; y++) { - for (x = r.left; x < r.right; x++) { - _screen->putPixel(x, y, drawFlags, 0, !_screen->getPriority(x, y), !_screen->getControl(x, y)); - } - } - } -} - -void SciGuiGfx::FrameRect(const Common::Rect &rect) { - Common::Rect r; - // left - r = rect; - r.right = rect.left + 1; - PaintRect(r); - // right - r.right = rect.right; - r.left = rect.right - 1; - PaintRect(r); - //top - r.left = rect.left; - r.bottom = rect.top + 1; - PaintRect(r); - //bottom - r.bottom = rect.bottom; - r.top = rect.bottom - 1; - PaintRect(r); -} - -void SciGuiGfx::OffsetRect(Common::Rect &r) { - r.top += _curPort->top; - r.bottom += _curPort->top; - r.left += _curPort->left; - r.right += _curPort->left; -} - -void SciGuiGfx::OffsetLine(Common::Point &start, Common::Point &end) { - start.x += _curPort->left; - start.y += _curPort->top; - end.x += _curPort->left; - end.y += _curPort->top; -} - -void SciGuiGfx::BitsShow(const Common::Rect &rect) { - Common::Rect workerRect(rect.left, rect.top, rect.right, rect.bottom); - workerRect.clip(_curPort->rect); - if (workerRect.isEmpty()) // nothing to show - return; - - OffsetRect(workerRect); - _screen->copyRectToScreen(workerRect); -} - -GuiMemoryHandle SciGuiGfx::BitsSave(const Common::Rect &rect, byte screenMask) { - GuiMemoryHandle memoryId; - byte *memoryPtr; - int size; - - Common::Rect workerRect(rect.left, rect.top, rect.right, rect.bottom); - workerRect.clip(_curPort->rect); - if (workerRect.isEmpty()) // nothing to save - return NULL_REG; - - OffsetRect(workerRect); - - // now actually ask _screen how much space it will need for saving - size = _screen->bitsGetDataSize(workerRect, screenMask); - - memoryId = kalloc(_segMan, "SaveBits()", size); - memoryPtr = kmem(_segMan, memoryId); - _screen->bitsSave(workerRect, screenMask, memoryPtr); - return memoryId; -} - -void SciGuiGfx::BitsGetRect(GuiMemoryHandle memoryHandle, Common::Rect *destRect) { - byte *memoryPtr = NULL; - - if (!memoryHandle.isNull()) { - memoryPtr = kmem(_segMan, memoryHandle); - - if (memoryPtr) { - _screen->bitsGetRect(memoryPtr, destRect); - } - } -} - -void SciGuiGfx::BitsRestore(GuiMemoryHandle memoryHandle) { - byte *memoryPtr = NULL; - - if (!memoryHandle.isNull()) { - memoryPtr = kmem(_segMan, memoryHandle); - - if (memoryPtr) { - _screen->bitsRestore(memoryPtr); - kfree(_segMan, memoryHandle); - } - } -} - -void SciGuiGfx::BitsFree(GuiMemoryHandle memoryHandle) { - if (!memoryHandle.isNull()) { - kfree(_segMan, memoryHandle); - } -} - -void SciGuiGfx::drawPicture(GuiResourceId pictureId, int16 animationNr, bool mirroredFlag, bool addToFlag, GuiResourceId paletteId) { - SciGuiPicture *picture = new SciGuiPicture(_resMan, this, _screen, _palette, pictureId); - - // do we add to a picture? if not -> clear screen with white - if (!addToFlag) - ClearScreen(_screen->_colorWhite); - - picture->draw(animationNr, mirroredFlag, addToFlag, paletteId); - delete picture; -} - -// This one is the only one that updates screen! -void SciGuiGfx::drawCel(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, uint16 leftPos, uint16 topPos, byte priority, uint16 paletteNo, int16 origHeight) { - SciGuiView *view = getView(viewId); - Common::Rect rect; - Common::Rect clipRect; - if (view) { - rect.left = leftPos; - rect.top = topPos; - rect.right = rect.left + view->getWidth(loopNo, celNo); - rect.bottom = rect.top + view->getHeight(loopNo, celNo); - clipRect = rect; - clipRect.clip(_curPort->rect); - if (clipRect.isEmpty()) { // nothing to draw - return; - } - - Common::Rect clipRectTranslated = clipRect; - OffsetRect(clipRectTranslated); - view->draw(rect, clipRect, clipRectTranslated, loopNo, celNo, priority, paletteNo, origHeight); - if (getSciVersion() >= SCI_VERSION_1_1) { - if (!_screen->_picNotValidSci11) - BitsShow(rect); - } else { - if (!_screen->_picNotValid) - BitsShow(rect); - } - } -} - -// This version of drawCel is not supposed to call BitsShow()! -void SciGuiGfx::drawCel(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, Common::Rect celRect, byte priority, uint16 paletteNo) { - SciGuiView *view = getView(viewId); - Common::Rect clipRect; - if (view) { - clipRect = celRect; - clipRect.clip(_curPort->rect); - if (clipRect.isEmpty()) { // nothing to draw - return; - } - - Common::Rect clipRectTranslated = clipRect; - OffsetRect(clipRectTranslated); - view->draw(celRect, clipRect, clipRectTranslated, loopNo, celNo, priority, paletteNo); - } -} - -// This version of drawCel is not supposed to call BitsShow()! -void SciGuiGfx::drawCel(SciGuiView *view, GuiViewLoopNo loopNo, GuiViewCelNo celNo, Common::Rect celRect, byte priority, uint16 paletteNo) { - Common::Rect clipRect; - clipRect = celRect; - clipRect.clip(_curPort->rect); - if (clipRect.isEmpty()) // nothing to draw - return; - - Common::Rect clipRectTranslated = clipRect; - OffsetRect(clipRectTranslated); - view->draw(celRect, clipRect, clipRectTranslated, loopNo, celNo, priority, paletteNo); -} - -uint16 SciGuiGfx::onControl(uint16 screenMask, Common::Rect rect) { - Common::Rect outRect(rect.left, rect.top, rect.right, rect.bottom); - int16 x, y; - uint16 result = 0; - - outRect.clip(_curPort->rect); - if (outRect.isEmpty()) // nothing to control - return 0; - OffsetRect(outRect); - - if (screenMask & SCI_SCREEN_MASK_PRIORITY) { - for (y = outRect.top; y < outRect.bottom; y++) { - for (x = outRect.left; x < outRect.right; x++) { - result |= 1 << _screen->getPriority(x, y); - } - } - } else { - for (y = outRect.top; y < outRect.bottom; y++) { - for (x = outRect.left; x < outRect.right; x++) { - result |= 1 << _screen->getControl(x, y); - } - } - } - return result; -} - -static inline int sign_extend_byte(int value) { - if (value & 0x80) - return value - 256; - else - return value; -} - -void SciGuiGfx::PriorityBandsInit(int16 bandCount, int16 top, int16 bottom) { - int16 y; - int32 bandSize; - - if (bandCount != -1) - _priorityBandCount = bandCount; - - _priorityTop = top; - _priorityBottom = bottom; - - // Do NOT modify this algo or optimize it anyhow, sierra sci used int32 for calculating the - // priority bands and by using double or anything rounding WILL destroy the result - bandSize = ((_priorityBottom - _priorityTop) * 2000) / _priorityBandCount; - - memset(_priorityBands, 0, sizeof(byte) * _priorityTop); - for (y = _priorityTop; y < _priorityBottom; y++) - _priorityBands[y] = 1 + (((y - _priorityTop) * 2000) / bandSize); - if (_priorityBandCount == 15) { - // When having 15 priority bands, we actually replace band 15 with band 14, cause the original sci interpreter also - // does it that way as well - y = _priorityBottom; - while (_priorityBands[--y] == _priorityBandCount) - _priorityBands[y]--; - } - // We fill space that is left over with the highest band - for (y = _priorityBottom; y < _screen->_height; y++) - _priorityBands[y] = _priorityBandCount; -} - -void SciGuiGfx::PriorityBandsInit(byte *data) { - int i = 0, inx; - byte priority = 0; - - for (inx = 0; inx < 14; inx++) { - priority = *data++; - while (i < priority) - _priorityBands[i++] = inx; - } - while (i < 200) - _priorityBands[i++] = inx; -} - -byte SciGuiGfx::CoordinateToPriority(int16 y) { - if (y < _priorityTop) - return _priorityBands[_priorityTop]; - if (y > _priorityBottom) - return _priorityBands[_priorityBottom]; - return _priorityBands[y]; -} - -int16 SciGuiGfx::PriorityToCoordinate(byte priority) { - int16 y; - if (priority <= _priorityBandCount) { - for (y = 0; y <= _priorityBottom; y++) - if (_priorityBands[y] == priority) - return y; - } - return _priorityBottom; -} - -bool SciGuiGfx::CanBeHereCheckRectList(reg_t checkObject, Common::Rect checkRect, List *list) { - reg_t curAddress = list->first; - Node *curNode = _segMan->lookupNode(curAddress); - reg_t curObject; - uint16 signal; - Common::Rect curRect; - - while (curNode) { - curObject = curNode->value; - if (curObject != checkObject) { - signal = GET_SEL32V(_segMan, curObject, signal); - if ((signal & (kSignalIgnoreActor | kSignalRemoveView | kSignalNoUpdate)) == 0) { - curRect.left = GET_SEL32V(_segMan, curObject, brLeft); - curRect.top = GET_SEL32V(_segMan, curObject, brTop); - curRect.right = GET_SEL32V(_segMan, curObject, brRight); - curRect.bottom = GET_SEL32V(_segMan, curObject, brBottom); - // Check if curRect is within checkRect - if (curRect.right > checkRect.left && curRect.left < checkRect.right && curRect.bottom > checkRect.top && curRect.top < checkRect.bottom) { - return false; - } - } - } - curAddress = curNode->succ; - curNode = _segMan->lookupNode(curAddress); - } - return true; -} - -void SciGuiGfx::SetNowSeen(reg_t objectReference) { - SciGuiView *view = NULL; - Common::Rect celRect(0, 0); - GuiResourceId viewId = (GuiResourceId)GET_SEL32V(_segMan, objectReference, view); - GuiViewLoopNo loopNo = sign_extend_byte((GuiViewLoopNo)GET_SEL32V(_segMan, objectReference, loop)); - GuiViewCelNo celNo = sign_extend_byte((GuiViewCelNo)GET_SEL32V(_segMan, objectReference, cel)); - int16 x = (int16)GET_SEL32V(_segMan, objectReference, x); - int16 y = (int16)GET_SEL32V(_segMan, objectReference, y); - int16 z = 0; - if (_kernel->_selectorCache.z > -1) - z = (int16)GET_SEL32V(_segMan, objectReference, z); - - // now get cel rectangle - view = getView(viewId); - view->getCelRect(loopNo, celNo, x, y, z, &celRect); - - // TODO: sometimes loop is negative. Check what it means - if (lookup_selector(_segMan, objectReference, _kernel->_selectorCache.nsTop, NULL, NULL) == kSelectorVariable) { - PUT_SEL32V(_segMan, objectReference, nsLeft, celRect.left); - PUT_SEL32V(_segMan, objectReference, nsRight, celRect.right); - PUT_SEL32V(_segMan, objectReference, nsTop, celRect.top); - PUT_SEL32V(_segMan, objectReference, nsBottom, celRect.bottom); - } -} - -} // End of namespace Sci diff --git a/engines/sci/gui/gui_gfx.h b/engines/sci/gui/gui_gfx.h deleted file mode 100644 index 0cbed35f45..0000000000 --- a/engines/sci/gui/gui_gfx.h +++ /dev/null @@ -1,130 +0,0 @@ -/* 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_GFX_H -#define SCI_GUI_GFX_H - -#include "sci/gui/gui.h" - -#include "common/hashmap.h" - -namespace Sci { - -#define SCI_TEXT_ALIGNMENT_RIGHT -1 -#define SCI_TEXT_ALIGNMENT_CENTER 1 -#define SCI_TEXT_ALIGNMENT_LEFT 0 - -#define MAX_CACHED_VIEWS 50 - -class SciGuiScreen; -class SciGuiPalette; -class SciGuiFont; -class SciGuiPicture; -class SciGuiView; - -typedef Common::HashMap ViewCache; - -class SciGuiGfx { -public: - SciGuiGfx(ResourceManager *resMan, SegManager *segMan, Kernel *kernel, SciGuiScreen *screen, SciGuiPalette *palette); - ~SciGuiGfx(); - - void init(SciGuiText *text); - - byte *GetSegment(byte seg); - void ResetScreen(); - - GuiPort *SetPort(GuiPort *port); - GuiPort *GetPort(); - void SetOrigin(int16 left, int16 top); - void MoveTo(int16 left, int16 top); - void Move(int16 left, int16 top); - void OpenPort(GuiPort *port); - void PenColor(int16 color); - void BackColor(int16 color); - void PenMode(int16 mode); - void TextGreyedOutput(bool state); - int16 GetPointSize(); - - void ClearScreen(byte color = 255); - void InvertRect(const Common::Rect &rect); - void EraseRect(const Common::Rect &rect); - void PaintRect(const Common::Rect &rect); - void FillRect(const Common::Rect &rect, int16 drawFlags, byte clrPen, byte clrBack = 0, byte bControl = 0); - void FrameRect(const Common::Rect &rect); - void OffsetRect(Common::Rect &r); - void OffsetLine(Common::Point &start, Common::Point &end); - - void BitsShow(const Common::Rect &r); - GuiMemoryHandle BitsSave(const Common::Rect &rect, byte screenFlags); - void BitsGetRect(GuiMemoryHandle memoryHandle, Common::Rect *destRect); - void BitsRestore(GuiMemoryHandle memoryHandle); - void BitsFree(GuiMemoryHandle memoryHandle); - - void drawPicture(GuiResourceId pictureId, int16 animationNr, bool mirroredFlag, bool addToFlag, GuiResourceId paletteId); - void drawCel(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, uint16 leftPos, uint16 topPos, byte priority, uint16 paletteNo, int16 origHeight = -1); - void drawCel(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, Common::Rect celRect, byte priority, uint16 paletteNo); - void drawCel(SciGuiView *view, GuiViewLoopNo loopNo, GuiViewCelNo celNo, Common::Rect celRect, byte priority, uint16 paletteNo); - - uint16 onControl(uint16 screenMask, Common::Rect rect); - - void PriorityBandsInit(int16 bandCount, int16 top, int16 bottom); - void PriorityBandsInit(byte *data); - byte CoordinateToPriority(int16 y); - int16 PriorityToCoordinate(byte priority); - - bool CanBeHereCheckRectList(reg_t checkObject, Common::Rect checkRect, List *list); - - void SetNowSeen(reg_t objectReference); - - GuiPort *_menuPort; - Common::Rect _menuBarRect; - GuiPort *_curPort; - - SciGuiView *getView(GuiResourceId viewNum); - -private: - void purgeCache(); - - ResourceManager *_resMan; - SegManager *_segMan; - Kernel *_kernel; - SciGuiScreen *_screen; - SciGuiPalette *_palette; - SciGuiText *_text; - - Common::Rect _bounds; - GuiPort *_mainPort; - - // Priority Bands related variables - int16 _priorityTop, _priorityBottom, _priorityBandCount; - byte _priorityBands[200]; - - ViewCache _cachedViews; -}; - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui/gui_helpers.h b/engines/sci/gui/gui_helpers.h deleted file mode 100644 index 554282e312..0000000000 --- a/engines/sci/gui/gui_helpers.h +++ /dev/null @@ -1,130 +0,0 @@ -/* 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_HELPERS_H -#define SCI_GUI_HELPERS_H - -#include "common/endian.h" // for READ_LE_UINT16 -#include "common/rect.h" -#include "sci/engine/vm_types.h" - -namespace Sci { - -#define SCI_SHAKE_DIRECTION_VERTICAL 1 -#define SCI_SHAKE_DIRECTION_HORIZONTAL 2 - -typedef int GuiResourceId; // is a resource-number and -1 means no parameter given -typedef reg_t GuiMemoryHandle; -typedef int16 GuiViewLoopNo; -typedef int16 GuiViewCelNo; - -typedef int16 GuiTextAlignment; - -struct GuiPort { - uint16 id; - int16 top, left; - Common::Rect rect; - int16 curTop, curLeft; - int16 fontHeight; - GuiResourceId fontId; - bool greyedOutput; - int16 penClr, backClr; - int16 penMode; - - GuiPort(uint16 theId) : id(theId), top(0), left(0), - curTop(0), curLeft(0), - fontHeight(0), fontId(0), greyedOutput(false), - penClr(0), backClr(0xFF), penMode(0) { - } -}; - -struct GuiWindow : public GuiPort { - Common::Rect dims; // client area of window - Common::Rect restoreRect; // total area of window including borders - uint16 wndStyle; - uint16 saveScreenMask; - reg_t hSaved1; - reg_t hSaved2; - Common::String title; - bool bDrawn; - - GuiWindow(uint16 theId) : GuiPort(theId), - wndStyle(0), saveScreenMask(0), - hSaved1(NULL_REG), hSaved2(NULL_REG), - bDrawn(false) { - } -}; - -struct GuiAnimateEntry { - reg_t object; - GuiResourceId viewId; - GuiViewLoopNo loopNo; - GuiViewCelNo celNo; - int16 paletteNo; - int16 x, y, z; - int16 priority; - uint16 signal; - Common::Rect celRect; - bool showBitsFlag; - GuiMemoryHandle castHandle; -}; -typedef Common::List GuiAnimateList; - -struct GuiColor { - byte used; - byte r, g, b; -}; - -struct GuiPalette { - byte mapping[256]; - uint32 timestamp; - GuiColor colors[256]; - byte intensity[256]; -}; - -struct GuiPalSchedule { - byte from; - uint32 schedule; -}; - -/** Button and frame control flags. */ -enum controlStateFlags { - kControlStateEnabled = 0x0001, ///< 0001 - enabled buttons (used by the interpreter) - kControlStateDisabled = 0x0004, ///< 0010 - grayed out buttons (used by the interpreter) - kControlStateFramed = 0x0008, ///< 1000 - widgets surrounded by a frame (used by the interpreter) - kControlStateDitherFramed = 0x1000 ///< 0001 0000 0000 0000 - widgets surrounded by a dithered frame (used in kgraphics) -}; - -enum ViewType { - kViewUnknown, - kViewEga, - kViewVga, - kViewVga11, - kViewAmiga -}; - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui/gui_menu.cpp b/engines/sci/gui/gui_menu.cpp deleted file mode 100644 index e9795edc5c..0000000000 --- a/engines/sci/gui/gui_menu.cpp +++ /dev/null @@ -1,648 +0,0 @@ -/* 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/util.h" -#include "common/stack.h" -#include "graphics/primitives.h" - -#include "sci/sci.h" -#include "sci/event.h" -#include "sci/engine/state.h" -#include "sci/gui/gui_helpers.h" -#include "sci/gui/gui_gfx.h" -#include "sci/gui/gui_cursor.h" -#include "sci/gui/gui_font.h" -#include "sci/gui/gui_text.h" -#include "sci/gui/gui_screen.h" -#include "sci/gui/gui_menu.h" - -namespace Sci { - -SciGuiMenu::SciGuiMenu(SciEvent *event, SegManager *segMan, SciGuiGfx *gfx, SciGuiText *text, SciGuiScreen *screen, SciGuiCursor *cursor) - : _event(event), _segMan(segMan), _gfx(gfx), _text(text), _screen(screen), _cursor(cursor) { - - _listCount = 0; - // We actually set active item in here and remember last selection of the user - // sierra sci always defaulted to first item every time menu was called via ESC, we dont follow that logic - _curMenuId = 1; - _curItemId = 1; - - _menuSaveHandle = NULL_REG; - _barSaveHandle = NULL_REG; - _oldPort = NULL; -} - -SciGuiMenu::~SciGuiMenu() { - // TODO: deallocate _list and _itemList -} - -void SciGuiMenu::add(Common::String title, Common::String content, reg_t contentVmPtr) { - GuiMenuEntry *menuEntry; - uint16 itemCount = 0; - GuiMenuItemEntry *itemEntry; - int contentSize = content.size(); - int separatorCount; - int curPos, beginPos, endPos, tempPos; - int tagPos, rightAlignedPos, functionPos, altPos, controlPos; - - // Sierra SCI starts with id 1, so we do so as well - _listCount++; - menuEntry = new GuiMenuEntry(_listCount); - menuEntry->text = title; - _list.push_back(menuEntry); - - curPos = 0; - do { - itemCount++; - itemEntry = new GuiMenuItemEntry(_listCount, itemCount); - - beginPos = curPos; - - // Now go through the content till we find end-marker and collect data about it - // ':' is an end-marker for each item - tagPos = 0; rightAlignedPos = 0; - controlPos = 0; altPos = 0; functionPos = 0; - while ((curPos < contentSize) && (content[curPos] != ':')) { - switch (content[curPos]) { - case '=': // Set tag - if (tagPos) - error("multiple tag markers within one menu-item"); - tagPos = curPos; - break; - case '`': // Right-aligned - if (rightAlignedPos) - error("multiple right-aligned markers within one menu-item"); - rightAlignedPos = curPos; - break; - case '^': // Ctrl-prefix - if (controlPos) - error("multiple control markers within one menu-item"); - controlPos = curPos; - break; - case '@': // Alt-prefix - if (altPos) - error("multiple alt markers within one menu-item"); - altPos = curPos; - break; - case '#': // Function-prefix - if (functionPos) - error("multiple function markers within one menu-item"); - functionPos = curPos; - break; - } - curPos++; - } - endPos = curPos; - - // Control/Alt/Function key mapping... - if (controlPos) { - content.setChar(SCI_MENU_REPLACE_ONCONTROL, controlPos); - itemEntry->keyModifier = SCI_KEYMOD_CTRL; - tempPos = controlPos + 1; - if (tempPos >= contentSize) - error("control marker at end of item"); - itemEntry->keyPress = tolower(content[tempPos]); - content.setChar(toupper(content[tempPos]), tempPos); - } - if (altPos) { - content.setChar(SCI_MENU_REPLACE_ONALT, altPos); - itemEntry->keyModifier = SCI_KEYMOD_ALT; - tempPos = altPos + 1; - if (tempPos >= contentSize) - error("alt marker at end of item"); - itemEntry->keyPress = tolower(content[tempPos]); - content.setChar(toupper(content[tempPos]), tempPos); - } - if (functionPos) { - content.setChar(SCI_MENU_REPLACE_ONFUNCTION, functionPos); - tempPos = functionPos + 1; - if (tempPos >= contentSize) - error("function marker at end of item"); - itemEntry->keyPress = content[tempPos]; - switch (content[functionPos + 1]) { - case '1': itemEntry->keyPress = SCI_KEY_F1; break; - case '2': itemEntry->keyPress = SCI_KEY_F2; break; - case '3': itemEntry->keyPress = SCI_KEY_F3; break; - case '4': itemEntry->keyPress = SCI_KEY_F4; break; - case '5': itemEntry->keyPress = SCI_KEY_F5; break; - case '6': itemEntry->keyPress = SCI_KEY_F6; break; - case '7': itemEntry->keyPress = SCI_KEY_F7; break; - case '8': itemEntry->keyPress = SCI_KEY_F8; break; - case '9': itemEntry->keyPress = SCI_KEY_F9; break; - case '0': itemEntry->keyPress = SCI_KEY_F10; break; - default: - error("illegal function key specified"); - } - } - - // Now get all strings - tempPos = endPos; - if (rightAlignedPos) { - tempPos = rightAlignedPos; - } else if (tagPos) { - tempPos = tagPos; - } - curPos = beginPos; - separatorCount = 0; - while (curPos < tempPos) { - switch (content[curPos]) { - case '!': - case '-': - case ' ': - separatorCount++; - } - curPos++; - } - if (separatorCount == tempPos - beginPos) { - itemEntry->separatorLine = true; - } else { - EngineState *s = ((SciEngine *)g_engine)->getEngineState(); // HACK: needed for strSplit() - itemEntry->text = s->strSplit(Common::String(content.c_str() + beginPos, tempPos - beginPos).c_str()); - } - itemEntry->textVmPtr = contentVmPtr; - itemEntry->textVmPtr.offset += beginPos; - - if (rightAlignedPos) { - rightAlignedPos++; - tempPos = endPos; - // Shouldnt be needed at all, cause right aligned occurs after tag (hopefully) - // If no game is found that causes problems, remove this line (29.11.2009) - //if (tagPos && tagPos >= rightAlignedPos) - // tempPos = tagPos; - itemEntry->textRightAligned = Common::String(content.c_str() + rightAlignedPos, tempPos - rightAlignedPos); - } - - if (tagPos) { - tempPos = functionPos + 1; - if (tempPos >= contentSize) - error("tag marker at end of item"); - itemEntry->tag = atoi(content.c_str() + tempPos); - } - - curPos = endPos + 1; - - _itemList.push_back(itemEntry); - } while (curPos < contentSize); -} - -GuiMenuItemEntry *SciGuiMenu::findItem(uint16 menuId, uint16 itemId) { - GuiMenuItemList::iterator listIterator; - GuiMenuItemList::iterator listEnd = _itemList.end(); - GuiMenuItemEntry *listEntry; - - listIterator = _itemList.begin(); - while (listIterator != listEnd) { - listEntry = *listIterator; - if ((listEntry->menuId == menuId) && (listEntry->id == itemId)) - return listEntry; - - listIterator++; - } - return NULL; -} - -void SciGuiMenu::setAttribute(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value) { - EngineState *s = ((SciEngine *)g_engine)->getEngineState(); // HACK: needed for strSplit() - GuiMenuItemEntry *itemEntry = findItem(menuId, itemId); - if (!itemEntry) - error("Tried to setAttribute() on non-existant menu-item %d:%d", menuId, itemId); - switch (attributeId) { - case SCI_MENU_ATTRIBUTE_ENABLED: - itemEntry->enabled = value.isNull() ? false : true; - break; - case SCI_MENU_ATTRIBUTE_SAID: - itemEntry->saidVmPtr = value; - break; - case SCI_MENU_ATTRIBUTE_TEXT: - itemEntry->text = s->strSplit(_segMan->getString(value).c_str()); - itemEntry->textVmPtr = value; - // We assume here that no script ever creates a separatorLine dynamically - break; - case SCI_MENU_ATTRIBUTE_KEYPRESS: - itemEntry->keyPress = tolower(value.offset); - itemEntry->keyModifier = 0; - // TODO: Find out how modifier is handled - printf("setAttr keypress %X %X\n", value.segment, value.offset); - break; - case SCI_MENU_ATTRIBUTE_TAG: - itemEntry->tag = value.offset; - break; - default: - // Happens when loading a game in LSL3 - attribute 1A - warning("setAttribute() called with unsupported attributeId %X", attributeId); - } -} - -reg_t SciGuiMenu::getAttribute(uint16 menuId, uint16 itemId, uint16 attributeId) { - GuiMenuItemEntry *itemEntry = findItem(menuId, itemId); - if (!itemEntry) - error("Tried to getAttribute() on non-existant menu-item %d:%d", menuId, itemId); - switch (attributeId) { - case SCI_MENU_ATTRIBUTE_ENABLED: - if (itemEntry->enabled) - return make_reg(0, 1); - break; - case SCI_MENU_ATTRIBUTE_SAID: - return itemEntry->saidVmPtr; - case SCI_MENU_ATTRIBUTE_TEXT: - return itemEntry->textVmPtr; - case SCI_MENU_ATTRIBUTE_KEYPRESS: - // TODO: Find out how modifier is handled - return make_reg(0, itemEntry->keyPress); - case SCI_MENU_ATTRIBUTE_TAG: - return make_reg(0, itemEntry->tag); - default: - error("getAttribute() called with unsupported attributeId %X", attributeId); - } - return NULL_REG; -} - -void SciGuiMenu::drawBar() { - GuiMenuEntry *listEntry; - GuiMenuList::iterator listIterator; - GuiMenuList::iterator listEnd = _list.end(); - - // Hardcoded black on white - _gfx->FillRect(_gfx->_menuBarRect, 1, _screen->_colorWhite); - _gfx->PenColor(0); - _gfx->MoveTo(8, 1); - - listIterator = _list.begin(); - while (listIterator != listEnd) { - listEntry = *listIterator; - _text->Draw_String(listEntry->text.c_str()); - - listIterator++; - } -} - -// This helper calculates all text widths for all menus/items -void SciGuiMenu::calculateTextWidth() { - GuiMenuList::iterator menuIterator; - GuiMenuList::iterator menuEnd = _list.end(); - GuiMenuEntry *menuEntry; - GuiMenuItemList::iterator itemIterator; - GuiMenuItemList::iterator itemEnd = _itemList.end(); - GuiMenuItemEntry *itemEntry; - int16 dummyHeight; - - menuIterator = _list.begin(); - while (menuIterator != menuEnd) { - menuEntry = *menuIterator; - _text->StringWidth(menuEntry->text.c_str(), 0, menuEntry->textWidth, dummyHeight); - - menuIterator++; - } - - itemIterator = _itemList.begin(); - while (itemIterator != itemEnd) { - itemEntry = *itemIterator; - _text->StringWidth(itemEntry->text.c_str(), 0, itemEntry->textWidth, dummyHeight); - _text->StringWidth(itemEntry->textRightAligned.c_str(), 0, itemEntry->textRightAlignedWidth, dummyHeight); - - itemIterator++; - } -} - -reg_t SciGuiMenu::select(reg_t eventObject) { - int16 eventType = GET_SEL32V(_segMan, eventObject, type); - int16 keyPress, keyModifier; - Common::Point mousePosition; - GuiMenuItemList::iterator itemIterator = _itemList.begin(); - GuiMenuItemList::iterator itemEnd = _itemList.end(); - GuiMenuItemEntry *itemEntry = NULL; - bool forceClaimed = false; - EngineState *s; - byte saidSpec[64]; - - switch (eventType) { - case SCI_EVENT_KEYBOARD: - keyPress = GET_SEL32V(_segMan, eventObject, message); - keyModifier = GET_SEL32V(_segMan, eventObject, modifiers); - switch (keyPress) { - case 0: - break; - case SCI_KEY_ESC: - itemEntry = interactiveWithKeyboard(); - forceClaimed = true; - break; - default: - while (itemIterator != itemEnd) { - itemEntry = *itemIterator; - if ((itemEntry->keyPress == keyPress) && (itemEntry->keyModifier == keyModifier)) - break; - itemIterator++; - } - if (itemIterator == itemEnd) - itemEntry = NULL; - } - break; - - case SCI_EVENT_SAID: - // HACK: should be removed as soon as said() is cleaned up - s = ((SciEngine *)g_engine)->getEngineState(); - while (itemIterator != itemEnd) { - itemEntry = *itemIterator; - - if (!itemEntry->saidVmPtr.isNull()) { - // TODO: get a pointer to saidVmPtr or make said() work on VmPtrs - _segMan->memcpy(saidSpec, itemEntry->saidVmPtr, 64); - if (said(s, saidSpec, 0) != SAID_NO_MATCH) - break; - } - itemIterator++; - } - if (itemIterator == itemEnd) - itemEntry = NULL; - break; - - case SCI_EVENT_MOUSE_PRESS: - mousePosition = _cursor->getPosition(); - if (mousePosition.y < 10) { - itemEntry = interactiveWithMouse(); - forceClaimed = true; - } - break; - } - - if (!_menuSaveHandle.isNull()) { - _gfx->BitsRestore(_menuSaveHandle); - _gfx->BitsShow(_menuRect); - _menuSaveHandle = NULL_REG; - // TODO: Change to ReAnimate() - } - if (!_barSaveHandle.isNull()) { - _gfx->BitsRestore(_barSaveHandle); - _gfx->BitsShow(_gfx->_menuBarRect); - _barSaveHandle = NULL_REG; - } - if (_oldPort) - _gfx->SetPort(_oldPort); - - if ((itemEntry) || (forceClaimed)) - PUT_SEL32(_segMan, eventObject, claimed, make_reg(0, 1)); - if (itemEntry) - return make_reg(0, (itemEntry->menuId << 8) | (itemEntry->id)); - return NULL_REG; -} - -GuiMenuItemEntry *SciGuiMenu::interactiveGetItem(uint16 menuId, uint16 itemId, bool menuChanged) { - GuiMenuItemList::iterator itemIterator = _itemList.begin(); - GuiMenuItemList::iterator itemEnd = _itemList.end(); - GuiMenuItemEntry *itemEntry; - GuiMenuItemEntry *firstItemEntry = NULL; - GuiMenuItemEntry *lastItemEntry = NULL; - - // Fixup menuId if needed - if (menuId > _listCount) - menuId = 1; - if (menuId == 0) - menuId = _listCount; - while (itemIterator != itemEnd) { - itemEntry = *itemIterator; - if (itemEntry->menuId == menuId) { - if (itemEntry->id == itemId) - return itemEntry; - if (!firstItemEntry) - firstItemEntry = itemEntry; - if ((!lastItemEntry) || (itemEntry->id > lastItemEntry->id)) - lastItemEntry = itemEntry; - } - itemIterator++; - } - if ((itemId == 0) || (menuChanged)) - return lastItemEntry; - return firstItemEntry; -} - -void SciGuiMenu::drawMenu(uint16 oldMenuId, uint16 newMenuId) { - GuiMenuEntry *listEntry; - GuiMenuList::iterator listIterator; - GuiMenuList::iterator listEnd = _list.end(); - GuiMenuItemEntry *listItemEntry; - GuiMenuItemList::iterator listItemIterator; - GuiMenuItemList::iterator listItemEnd = _itemList.end(); - Common::Rect menuTextRect; - uint16 listNr = 0; - int16 maxTextWidth = 0, maxTextRightAlignedWidth = 0; - int16 topPos; - Common::Point pixelPos; - - // Remove menu, if one is displayed - if (!_menuSaveHandle.isNull()) { - _gfx->BitsRestore(_menuSaveHandle); - _gfx->BitsShow(_menuRect); - // TODO: Change to ReAnimate() - } - - // First calculate rect of menu and also invert old and new menu text - _menuRect.top = _gfx->_menuBarRect.bottom; - menuTextRect.top = _gfx->_menuBarRect.top; - menuTextRect.bottom = _gfx->_menuBarRect.bottom; - menuTextRect.left = menuTextRect.right = 7; - listIterator = _list.begin(); - while (listIterator != listEnd) { - listEntry = *listIterator; - listNr++; - menuTextRect.left = menuTextRect.right; - menuTextRect.right += listEntry->textWidth; - if (listNr == newMenuId) - _menuRect.left = menuTextRect.left; - if ((listNr == newMenuId) || (listNr == oldMenuId)) { - menuTextRect.translate(1, 0); - _gfx->InvertRect(menuTextRect); - menuTextRect.translate(-1, 0); - } - - listIterator++; - } - if (oldMenuId != 0) - _gfx->BitsShow(_gfx->_menuBarRect); - - _menuRect.bottom = _menuRect.top + 2; - listItemIterator = _itemList.begin(); - while (listItemIterator != listItemEnd) { - listItemEntry = *listItemIterator; - if (listItemEntry->menuId == newMenuId) { - _menuRect.bottom += _gfx->_curPort->fontHeight; - maxTextWidth = MAX(maxTextWidth, listItemEntry->textWidth); - maxTextRightAlignedWidth = MAX(maxTextRightAlignedWidth, listItemEntry->textRightAlignedWidth); - } - listItemIterator++; - } - _menuRect.right = _menuRect.left + 16 + 4 + 2; - _menuRect.right += maxTextWidth + maxTextRightAlignedWidth; - if (!maxTextRightAlignedWidth) - _menuRect.right -= 5; - - // Save background - _menuSaveHandle = _gfx->BitsSave(_menuRect, SCI_SCREEN_MASK_VISUAL); - - // Do the drawing - _gfx->FillRect(_menuRect, SCI_SCREEN_MASK_VISUAL, 0); - _menuRect.left++; _menuRect.right--; _menuRect.bottom--; - _gfx->FillRect(_menuRect, SCI_SCREEN_MASK_VISUAL, _screen->_colorWhite); - - _menuRect.left += 8; - topPos = _menuRect.top + 1; - listItemIterator = _itemList.begin(); - while (listItemIterator != listItemEnd) { - listItemEntry = *listItemIterator; - if (listItemEntry->menuId == newMenuId) { - if (!listItemEntry->separatorLine) { - _gfx->TextGreyedOutput(listItemEntry->enabled ? false : true); - _gfx->MoveTo(_menuRect.left, topPos); - _text->Draw_String(listItemEntry->text.c_str()); - _gfx->MoveTo(_menuRect.right - listItemEntry->textRightAlignedWidth - 5, topPos); - _text->Draw_String(listItemEntry->textRightAligned.c_str()); - } else { - // We dont 100% follow sierra here, we draw the line from left to right. Looks better - // BTW. SCI1.1 seems to put 2 pixels and then skip one, we don't do this at all (lsl6) - pixelPos.y = topPos + (_gfx->_curPort->fontHeight >> 1) - 1; - pixelPos.x = _menuRect.left - 7; - while (pixelPos.x < (_menuRect.right - 1)) { - _screen->putPixel(pixelPos.x, pixelPos.y, SCI_SCREEN_MASK_VISUAL, 0, 0, 0); - pixelPos.x += 2; - } - } - topPos += _gfx->_curPort->fontHeight; - } - listItemIterator++; - } - _gfx->TextGreyedOutput(false); - - - _menuRect.left -= 8; - _menuRect.left--; _menuRect.right++; _menuRect.bottom++; - _gfx->BitsShow(_menuRect); -} - -void SciGuiMenu::invertMenuSelection(uint16 itemId) { - Common::Rect itemRect = _menuRect; - - itemRect.top += (itemId - 1) * _gfx->_curPort->fontHeight; - itemRect.bottom = itemRect.top + _gfx->_curPort->fontHeight + 1; - itemRect.left++; itemRect.right--; - - _gfx->InvertRect(itemRect); - _gfx->BitsShow(itemRect); -} - -GuiMenuItemEntry *SciGuiMenu::interactiveWithKeyboard() { - sciEvent curEvent; - uint16 newMenuId = _curMenuId; - uint16 newItemId = _curItemId; - GuiMenuItemEntry *curItemEntry = findItem(_curMenuId, _curItemId); - GuiMenuItemEntry *newItemEntry = curItemEntry; - - // We don't 100% follow sierra here: we select last item instead of selecting first item of first menu everytime - - calculateTextWidth(); - _oldPort = _gfx->SetPort(_gfx->_menuPort); - _barSaveHandle = _gfx->BitsSave(_gfx->_menuBarRect, SCI_SCREEN_MASK_VISUAL); - - _gfx->PenColor(0); - _gfx->BackColor(_screen->_colorWhite); - - drawBar(); - drawMenu(0, curItemEntry->menuId); - invertMenuSelection(curItemEntry->id); - _gfx->BitsShow(_gfx->_menuBarRect); - _gfx->BitsShow(_menuRect); - - while (true) { - curEvent = _event->get(SCI_EVENT_ANY); - - switch (curEvent.type) { - case SCI_EVENT_KEYBOARD: - // We don't 100% follow sierra here: - sierra didn't wrap around when changing item id - // - sierra allowed item id to be 0, which didnt make any sense - do { - switch (curEvent.data) { - case SCI_KEY_ESC: - _curMenuId = curItemEntry->menuId; _curItemId = curItemEntry->id; - return NULL; - case SCI_KEY_ENTER: - if (curItemEntry->enabled) { - _curMenuId = curItemEntry->menuId; _curItemId = curItemEntry->id; - return curItemEntry; - } - break; - case SCI_KEY_LEFT: - newMenuId--; newItemId = 1; - break; - case SCI_KEY_RIGHT: - newMenuId++; newItemId = 1; - break; - case SCI_KEY_UP: - newItemId--; - break; - case SCI_KEY_DOWN: - newItemId++; - break; - } - if ((newMenuId != curItemEntry->menuId) || (newItemId != curItemEntry->id)) { - // Selection changed, fix up new selection if required - newItemEntry = interactiveGetItem(newMenuId, newItemId, newMenuId != curItemEntry->menuId); - newMenuId = newItemEntry->menuId; newItemId = newItemEntry->id; - - // if we do this step again because of a separator line -> don't repeat left/right, but go down - switch (curEvent.data) { - case SCI_KEY_LEFT: - case SCI_KEY_RIGHT: - curEvent.data = SCI_KEY_DOWN; - } - } - } while (newItemEntry->separatorLine); - if ((newMenuId != curItemEntry->menuId) || (newItemId != curItemEntry->id)) { - // paint old and new - if (newMenuId != curItemEntry->menuId) { - // Menu changed, remove cur menu and paint new menu - drawMenu(curItemEntry->menuId, newMenuId); - } else { - invertMenuSelection(curItemEntry->id); - } - invertMenuSelection(newItemId); - - curItemEntry = newItemEntry; - } - break; - - case SCI_EVENT_NONE: - kernel_sleep(_event, 2500 / 1000); - break; - } - } -} - -GuiMenuItemEntry *SciGuiMenu::interactiveWithMouse() { - calculateTextWidth(); - - // TODO - - return NULL; -} - -} // End of namespace Sci diff --git a/engines/sci/gui/gui_menu.h b/engines/sci/gui/gui_menu.h deleted file mode 100644 index a396378dc0..0000000000 --- a/engines/sci/gui/gui_menu.h +++ /dev/null @@ -1,123 +0,0 @@ -/* 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_MENU_H -#define SCI_GUI_MENU_H - -namespace Sci { - -enum { - SCI_MENU_ATTRIBUTE_SAID = 0x6d, - SCI_MENU_ATTRIBUTE_TEXT = 0x6e, - SCI_MENU_ATTRIBUTE_KEYPRESS = 0x6f, - SCI_MENU_ATTRIBUTE_ENABLED = 0x70, - SCI_MENU_ATTRIBUTE_TAG = 0x71 -}; - -enum { - SCI_MENU_REPLACE_ONCONTROL = 0x03, - SCI_MENU_REPLACE_ONALT = 0x02, - SCI_MENU_REPLACE_ONFUNCTION = 'F' -}; - -struct GuiMenuEntry { - uint16 id; - Common::String text; - int16 textWidth; - - GuiMenuEntry(uint16 curId) - : id(curId), textWidth(0) { } -}; -typedef Common::List GuiMenuList; - -struct GuiMenuItemEntry { - uint16 menuId; - uint16 id; - bool enabled; - uint16 tag; - uint16 keyPress; - uint16 keyModifier; - bool separatorLine; - reg_t saidVmPtr; - Common::String text; - reg_t textVmPtr; - int16 textWidth; - Common::String textRightAligned; - int16 textRightAlignedWidth; - - GuiMenuItemEntry(uint16 curMenuId, uint16 curId) - : menuId(curMenuId), id(curId), - enabled(true), tag(0), keyPress(0), keyModifier(0), separatorLine(false), textWidth(0), textRightAlignedWidth(0) { - saidVmPtr = NULL_REG; - textVmPtr = NULL_REG; - } -}; -typedef Common::List GuiMenuItemList; - -class SciGuiMenu { -public: - SciGuiMenu(SciEvent *event, SegManager *segMan, SciGuiGfx *gfx, SciGuiText *text, SciGuiScreen *screen, SciGuiCursor *cursor); - ~SciGuiMenu(); - - void reset(); - void add(Common::String title, Common::String content, reg_t contentVmPtr); - void setAttribute(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value); - reg_t getAttribute(uint16 menuId, uint16 itemId, uint16 attributeId); - - void drawBar(); - reg_t select(reg_t eventObject); - -private: - GuiMenuItemEntry *findItem(uint16 menuId, uint16 itemId); - void calculateTextWidth(); - void drawMenu(uint16 oldMenuId, uint16 newMenuId); - void invertMenuSelection(uint16 itemId); - GuiMenuItemEntry *interactiveWithKeyboard(); - GuiMenuItemEntry *interactiveWithMouse(); - GuiMenuItemEntry *interactiveGetItem(uint16 menuId, uint16 itemId, bool menuChanged); - - SciEvent *_event; - SegManager *_segMan; - SciGuiGfx *_gfx; - SciGuiText *_text; - SciGuiScreen *_screen; - SciGuiCursor *_cursor; - - uint16 _listCount; - GuiMenuList _list; - GuiMenuItemList _itemList; - - uint16 _curMenuId; - uint16 _curItemId; - - GuiPort *_oldPort; - GuiMemoryHandle _barSaveHandle; - GuiMemoryHandle _menuSaveHandle; - Common::Rect _menuRect; -}; - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui/gui_palette.cpp b/engines/sci/gui/gui_palette.cpp deleted file mode 100644 index 977f63e4f9..0000000000 --- a/engines/sci/gui/gui_palette.cpp +++ /dev/null @@ -1,380 +0,0 @@ -/* 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/gui/gui_screen.h" -#include "sci/gui/gui_palette.h" - -namespace Sci { - -SciGuiPalette::SciGuiPalette(ResourceManager *resMan, SciGuiScreen *screen, bool autoSetPalette) - : _resMan(resMan), _screen(screen) { - int16 color; - - _sysPalette.timestamp = 0; - for (color = 0; color < 256; color++) { - _sysPalette.colors[color].used = 0; - _sysPalette.colors[color].r = 0; - _sysPalette.colors[color].g = 0; - _sysPalette.colors[color].b = 0; - _sysPalette.intensity[color] = 100; - _sysPalette.mapping[color] = color; - } - // Black and white are hardcoded - _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; - - if (autoSetPalette) { - if (_resMan->getViewType() == kViewEga) - setEGA(); - else if (_resMan->getViewType() == kViewAmiga) - setAmiga(); - else - setFromResource(999, 2); - } -} - -SciGuiPalette::~SciGuiPalette() { -} - -#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) || (data[0] == 0 && data[1] == 0 && READ_LE_UINT16(data + 29) == 0)) { - // 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(); - setOnScreen(); - return true; - } - return false; -} - -void SciGuiPalette::setEGA() { - int i; - byte color1, color2; - _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; - } - // Now setting colors 16-254 to the correct mix colors that occur when not doing a dithering run on - // finished pictures - for (i = 0x10; i <= 0xFE; i++) { - _sysPalette.colors[i].used = 1; - color1 = i & 0x0F; color2 = i >> 4; - _sysPalette.colors[i].r = (_sysPalette.colors[color1].r >> 1) + (_sysPalette.colors[color2].r >> 1); - _sysPalette.colors[i].g = (_sysPalette.colors[color1].g >> 1) + (_sysPalette.colors[color2].g >> 1); - _sysPalette.colors[i].b = (_sysPalette.colors[color1].b >> 1) + (_sysPalette.colors[color2].b >> 1); - } - setOnScreen(); -} - -bool SciGuiPalette::setFromResource(GuiResourceId resourceId, uint16 flag) { - Resource *palResource = _resMan->findResource(ResourceId(kResourceTypePalette, resourceId), 0); - GuiPalette palette; - - if (palResource) { - createFromData(palResource->data, &palette); - set(&palette, 2); - return true; - } - return false; -} - -void SciGuiPalette::set(GuiPalette *sciPal, uint16 flag) { - uint32 systime = _sysPalette.timestamp; - if (flag == 2 || sciPal->timestamp != systime) { - merge(sciPal, &_sysPalette, flag); - sciPal->timestamp = _sysPalette.timestamp; - if (_screen->_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; - } - // is the same color already at the same position? -> match it directly w/o lookup - // this fixes games like lsl1demo/sq5 where the same rgb color exists multiple times and where we would - // otherwise match the wrong one (which would result into the pixels affected (or not) by palette changes) - if ((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 = g_system->getMillis() * 60 / 1000; -} - -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 = 1; i < 255; 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 = (dr*dr) + (dg*dg) + (db*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::setFlag(uint16 fromColor, uint16 toColor, uint16 flag) { - uint16 colorNr; - for (colorNr = fromColor; colorNr < toColor; colorNr++) { - _sysPalette.colors[colorNr].used |= flag; - } -} - -void SciGuiPalette::unsetFlag(uint16 fromColor, uint16 toColor, uint16 flag) { - uint16 colorNr; - for (colorNr = fromColor; colorNr < toColor; colorNr++) { - _sysPalette.colors[colorNr].used &= ~flag; - } -} - -void SciGuiPalette::setIntensity(uint16 fromColor, uint16 toColor, uint16 intensity, bool setPalette) { - memset(&_sysPalette.intensity[0] + fromColor, intensity, toColor - fromColor); - if (setPalette) - setOnScreen(); -} - -// Returns true, if palette got changed -bool SciGuiPalette::animate(byte fromColor, byte toColor, int speed) { - GuiColor col; - //byte colorNr; - int16 colorCount; - uint32 now = g_system->getMillis() * 60 / 1000; - - // search for sheduled animations with the same 'from' value - // schedule animation... - int scheduleCount = _schedules.size(); - int scheduleNr; - for (scheduleNr = 0; scheduleNr < scheduleCount; scheduleNr++) { - if (_schedules[scheduleNr].from == fromColor) - break; - } - if (scheduleNr == scheduleCount) { - // adding a new schedule - GuiPalSchedule newSchedule; - newSchedule.from = fromColor; - newSchedule.schedule = now + ABS(speed); - _schedules.push_back(newSchedule); - scheduleCount++; - } - - for (scheduleNr = 0; scheduleNr < scheduleCount; scheduleNr++) { - if (_schedules[scheduleNr].from == fromColor) { - if (_schedules[scheduleNr].schedule <= now) { - if (speed > 0) { - // TODO: Not really sure about this, sierra sci seems to do exactly this here - col = _sysPalette.colors[fromColor]; - if (fromColor < toColor) { - colorCount = toColor - fromColor - 1; - memmove(&_sysPalette.colors[fromColor], &_sysPalette.colors[fromColor + 1], colorCount * sizeof(GuiColor)); - } - _sysPalette.colors[toColor - 1] = col; - } else { - col = _sysPalette.colors[toColor - 1]; - if (fromColor < toColor) { - colorCount = toColor - fromColor - 1; - memmove(&_sysPalette.colors[fromColor + 1], &_sysPalette.colors[fromColor], colorCount * sizeof(GuiColor)); - } - _sysPalette.colors[fromColor] = col; - } - // removing schedule - _schedules[scheduleNr].schedule = now + ABS(speed); - // TODO: Not sure when sierra actually removes a schedule - //_schedules.remove_at(scheduleNr); - return true; - } - return false; - } - } - return false; -} - -// palVary -// init - only does, if palVaryOn == false -// target, start, new palette allocation -// palVaryOn = true -// palDirection = 1 -// palStop = 64 -// palTime = from caller -// copy resource palette to target -// init target palette (used = 1 on all colors, color 0 = RGB 0, 0, 0 color 255 = RGB 0xFF, 0xFF, 0xFF -// copy sysPalette to startPalette -// init new palette like target palette -// palPercent = 1 -// do various things -// return 1 -// deinit - unloads target palette, kills timer hook, disables palVaryOn -// pause - counts up or down, if counter != 0 -> signal wont get counted up by timer -// will only count down to 0 -// -// Restarting game -// palVary = false -// palPercent = 0 -// call palVary deinit -// -// Saving/restoring -// need to save start and target-palette, when palVaryOn = true - -} // End of namespace Sci diff --git a/engines/sci/gui/gui_palette.h b/engines/sci/gui/gui_palette.h deleted file mode 100644 index f3eca7448d..0000000000 --- a/engines/sci/gui/gui_palette.h +++ /dev/null @@ -1,66 +0,0 @@ -/* 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_helpers.h" - -namespace Sci { - -class SciGuiScreen; -class SciGuiPalette { -public: - SciGuiPalette(ResourceManager *resMan, SciGuiScreen *screen, bool autoSetPalette = true); - ~SciGuiPalette(); - - void createFromData(byte *data, GuiPalette *paletteOut); - bool setAmiga(); - void setEGA(); - bool setFromResource(GuiResourceId resourceId, uint16 flag); - void set(GuiPalette *sciPal, uint16 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 setFlag(uint16 fromColor, uint16 toColor, uint16 flag); - void unsetFlag(uint16 fromColor, uint16 toColor, uint16 flag); - void setIntensity(uint16 fromColor, uint16 toColor, uint16 intensity, bool setPalette); - bool animate(byte fromColor, byte toColor, int speed); - - GuiPalette _sysPalette; - -private: - SciGuiScreen *_screen; - ResourceManager *_resMan; - - Common::Array _schedules; -}; - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui/gui_picture.cpp b/engines/sci/gui/gui_picture.cpp deleted file mode 100644 index 1ab54a51e1..0000000000 --- a/engines/sci/gui/gui_picture.cpp +++ /dev/null @@ -1,973 +0,0 @@ -/* 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/stack.h" -#include "sci/sci.h" -#include "sci/engine/state.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(ResourceManager *resMan, SciGuiGfx *gfx, SciGuiScreen *screen, SciGuiPalette *palette, GuiResourceId resourceId) - : _resMan(resMan), _gfx(gfx), _screen(screen), _palette(palette), _resourceId(resourceId) { - assert(resourceId != -1); - initData(resourceId); -} - -SciGuiPicture::~SciGuiPicture() { -} - -void SciGuiPicture::initData(GuiResourceId resourceId) { - _resource = _resMan->findResource(ResourceId(kResourceTypePic, resourceId), false); - if (!_resource) { - error("picture resource %d not found", resourceId); - } -} - -GuiResourceId SciGuiPicture::getResourceId() { - return _resourceId; -} - -// TODO: subclass this -void SciGuiPicture::draw(int16 animationNr, bool mirroredFlag, bool addToFlag, int16 EGApaletteNo) { - uint16 headerSize; - - _animationNr = animationNr; - _mirroredFlag = mirroredFlag; - _addToFlag = addToFlag; - _EGApaletteNo = EGApaletteNo; - _priority = 0; - - headerSize = READ_LE_UINT16(_resource->data); - switch (headerSize) { - case 0x26: // SCI 1.1 VGA picture - drawSci11Vga(); - break; -#ifdef ENABLE_SCI32 - case 0x0e: // SCI32 VGA picture - drawSci32Vga(); - break; -#endif - default: - // VGA, EGA or Amiga vector data - drawVectorData(_resource->data, _resource->size); - } -} - -void SciGuiPicture::reset() { - int16 x, y; - for (y = _gfx->GetPort()->top; y < _screen->_height; y++) { - for (x = 0; x < _screen->_width; x++) { - _screen->putPixel(x, y, SCI_SCREEN_MASK_ALL, 255, 0, 0); - } - } -} - -void SciGuiPicture::drawSci11Vga() { - byte *inbuffer = _resource->data; - int size = _resource->size; - int has_cel = READ_LE_UINT16(inbuffer + 4); - int vector_dataPos = READ_LE_UINT16(inbuffer + 16); - int vector_size = size - vector_dataPos; - int palette_data_ptr = READ_LE_UINT16(inbuffer + 28); - int cel_headerPos = READ_LE_UINT16(inbuffer + 32); - int cel_RlePos = READ_LE_UINT16(inbuffer + cel_headerPos + 24); - int cel_LiteralPos = READ_LE_UINT16(inbuffer + cel_headerPos + 28); - GuiPalette palette; - - // Create palette and set it - _palette->createFromData(inbuffer + palette_data_ptr, &palette); - _palette->set(&palette, 2); - - // display Cel-data - if (has_cel) { - drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, 0, 0, false); - } - - // process vector data - drawVectorData(inbuffer + vector_dataPos, vector_size); -} - -#ifdef ENABLE_SCI32 -void SciGuiPicture::drawSci32Vga() { - byte *inbuffer = _resource->data; - int size = _resource->size; - int header_size = READ_LE_UINT16(inbuffer); - int palette_data_ptr = READ_LE_UINT16(inbuffer + 6); - int cel_headerPos = header_size; - int cel_RlePos = READ_LE_UINT16(inbuffer + cel_headerPos + 24); - int cel_LiteralPos = READ_LE_UINT16(inbuffer + cel_headerPos + 28); - GuiPalette palette; - - // Create palette and set it - _palette->createFromData(inbuffer + palette_data_ptr, &palette); - _palette->set(&palette, 2); - - drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, 0, 0, true); - - // TODO: find out where priority map is stored -} -#endif - -void SciGuiPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 callerX, int16 callerY, bool hasSci32Header) { - byte *celBitmap = NULL; - byte *ptr = NULL; - byte *headerPtr = inbuffer + headerPos; - byte *rlePtr = inbuffer + rlePos; - byte *literalPtr = inbuffer + literalPos; - uint16 width = READ_LE_UINT16(headerPtr + 0); - uint16 height = READ_LE_UINT16(headerPtr + 2); - int16 displaceX, displaceY; - byte priority = _addToFlag ? _priority : 0; - byte clearColor; - bool compression = true; - byte curByte, runLength; - int16 y, lastY, x, leftX, rightX; - uint16 pixelNr, pixelCount; - -#ifdef ENABLE_SCI32 - if (!hasSci32Header) { -#endif - displaceX = (signed char)headerPtr[4]; - displaceY = (unsigned char)headerPtr[5]; - clearColor = headerPtr[6]; -#ifdef ENABLE_SCI32 - } else { - displaceX = READ_LE_UINT16(headerPtr + 4); // probably signed?!? - displaceY = READ_LE_UINT16(headerPtr + 6); // probably signed?!? - clearColor = headerPtr[8]; - if (headerPtr[9] == 0) - compression = false; - } -#endif - - if (displaceX || displaceY) - error("unsupported embedded cel-data in picture"); - - pixelCount = width * height; - celBitmap = new byte[pixelCount]; - if (!celBitmap) - error("Unable to allocate temporary memory for picture drawing"); - - if (compression) { - // We will unpack cel-data into a temporary buffer and then plot it to screen - // That needs to be done cause a mirrored picture may be requested - memset(celBitmap, clearColor, pixelCount); - pixelNr = 0; - ptr = celBitmap; - if (literalPos == 0) { - // decompression for data that has only one stream (vecor embedded view data) - switch (_resMan->getViewType()) { - case kViewEga: - while (pixelNr < pixelCount) { - curByte = *rlePtr++; - runLength = curByte >> 4; - memset(ptr + pixelNr, curByte & 0x0F, MIN(runLength, pixelCount - pixelNr)); - pixelNr += runLength; - } - break; - case kViewVga: - case kViewVga11: - while (pixelNr < pixelCount) { - curByte = *rlePtr++; - runLength = curByte & 0x3F; - switch (curByte & 0xC0) { - case 0: // copy bytes as-is - while (runLength-- && pixelNr < pixelCount) - ptr[pixelNr++] = *rlePtr++; - break; - case 0x80: // fill with color - memset(ptr + pixelNr, *rlePtr++, MIN(runLength, pixelCount - pixelNr)); - pixelNr += runLength; - break; - case 0xC0: // fill with transparent - pixelNr += runLength; - break; - } - } - break; - case kViewAmiga: - while (pixelNr < pixelCount) { - curByte = *rlePtr++; - if (curByte & 0x07) { // fill with color - runLength = curByte & 0x07; - curByte = curByte >> 3; - while (runLength-- && pixelNr < pixelCount) { - ptr[pixelNr++] = curByte; - } - } else { // fill with transparent - runLength = curByte >> 3; - pixelNr += runLength; - } - } - break; - - default: - error("Unsupported picture viewtype"); - } - } else { - // decompression for data that has two separate streams (probably SCI 1.1 picture) - while (pixelNr < pixelCount) { - curByte = *rlePtr++; - runLength = curByte & 0x3F; - switch (curByte & 0xC0) { - case 0: // copy bytes as-is - while (runLength-- && pixelNr < pixelCount) - ptr[pixelNr++] = *literalPtr++; - break; - case 0x80: // fill with color - memset(ptr + pixelNr, *literalPtr++, MIN(runLength, pixelCount - pixelNr)); - pixelNr += runLength; - break; - case 0xC0: // fill with transparent - pixelNr += runLength; - break; - } - } - } - } else { - // No compression (some SCI32 pictures) - memcpy(celBitmap, rlePtr, pixelCount); - } - - // Set initial vertical coordinate by using current port - y = callerY + _gfx->GetPort()->top; - lastY = MIN(height + y, _gfx->GetPort()->rect.bottom + _gfx->GetPort()->top); - leftX = callerX + _gfx->GetPort()->left; - rightX = MIN(width + leftX, _gfx->GetPort()->rect.right + _gfx->GetPort()->left); - - // Change clearcolor to white, if we dont add to an existing picture. That way we will paint everything on screen - // but white and that wont matter because the screen is supposed to be already white. It seems that most (if not all) - // SCI1.1 games use color 0 as transparency and SCI1 games use color 255 as transparency. Sierra SCI seems to paint - // the whole data to screen and wont skip over transparent pixels. So this will actually make it work like Sierra - if (!_addToFlag) - clearColor = _screen->_colorWhite; - - ptr = celBitmap; - if (!_mirroredFlag) { - // Draw bitmap to screen - x = leftX; - while (y < lastY) { - curByte = *ptr++; - if ((curByte != clearColor) && (priority >= _screen->getPriority(x, y))) - _screen->putPixel(x, y, SCI_SCREEN_MASK_VISUAL | SCI_SCREEN_MASK_PRIORITY, curByte, priority, 0); - x++; - if (x >= rightX) { - x = leftX; y++; - } - } - } else { - // Draw bitmap to screen (mirrored) - x = rightX - 1; - while (y < lastY) { - curByte = *ptr++; - if ((curByte != clearColor) && (priority >= _screen->getPriority(x, y))) - _screen->putPixel(x, y, SCI_SCREEN_MASK_VISUAL | SCI_SCREEN_MASK_PRIORITY, curByte, priority, 0); - if (x == leftX) { - x = rightX; y++; - } - x--; - } - } - delete[] celBitmap; -} - -enum { - PIC_OP_SET_COLOR = 0xf0, - PIC_OP_DISABLE_VISUAL = 0xf1, - PIC_OP_SET_PRIORITY = 0xf2, - PIC_OP_DISABLE_PRIORITY = 0xf3, - PIC_OP_SHORT_PATTERNS = 0xf4, - PIC_OP_MEDIUM_LINES = 0xf5, - PIC_OP_LONG_LINES = 0xf6, - PIC_OP_SHORT_LINES = 0xf7, - PIC_OP_FILL = 0xf8, - PIC_OP_SET_PATTERN = 0xf9, - PIC_OP_ABSOLUTE_PATTERN = 0xfa, - PIC_OP_SET_CONTROL = 0xfb, - PIC_OP_DISABLE_CONTROL = 0xfc, - PIC_OP_MEDIUM_PATTERNS = 0xfd, - PIC_OP_OPX = 0xfe, - PIC_OP_TERMINATE = 0xff -}; -#define PIC_OP_FIRST PIC_OP_SET_COLOR - -enum { - PIC_OPX_EGA_SET_PALETTE_ENTRIES = 0, - PIC_OPX_EGA_SET_PALETTE = 1, - PIC_OPX_EGA_MONO0 = 2, - PIC_OPX_EGA_MONO1 = 3, - PIC_OPX_EGA_MONO2 = 4, - PIC_OPX_EGA_MONO3 = 5, - PIC_OPX_EGA_MONO4 = 6, - PIC_OPX_EGA_EMBEDDED_VIEW = 7, - PIC_OPX_EGA_SET_PRIORITY_TABLE = 8 -}; - -enum { - PIC_OPX_VGA_SET_PALETTE_ENTRIES = 0, - PIC_OPX_VGA_EMBEDDED_VIEW = 1, - PIC_OPX_VGA_SET_PALETTE = 2, - PIC_OPX_VGA_PRIORITY_TABLE_EQDIST = 3, - PIC_OPX_VGA_PRIORITY_TABLE_EXPLICIT = 4 -}; - -#define PIC_EGAPALETTE_COUNT 4 -#define PIC_EGAPALETTE_SIZE 40 -#define PIC_EGAPALETTE_TOTALSIZE PIC_EGAPALETTE_COUNT*PIC_EGAPALETTE_SIZE -#define PIC_EGAPRIORITY_SIZE PIC_EGAPALETTE_SIZE - -static const byte vector_defaultEGApalette[PIC_EGAPALETTE_SIZE] = { - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x88, - 0x88, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x88, - 0x88, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, - 0x08, 0x91, 0x2a, 0x3b, 0x4c, 0x5d, 0x6e, 0x88 -}; - -static const byte vector_defaultEGApriority[PIC_EGAPRIORITY_SIZE] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 -}; - -void SciGuiPicture::drawVectorData(byte *data, int dataSize) { - byte pic_op; - byte pic_color = _screen->_colorDefaultVectorData; - byte pic_priority = 255, pic_control = 255; - int16 x = 0, y = 0, oldx, oldy; - byte EGApalettes[PIC_EGAPALETTE_TOTALSIZE] = {0}; - byte *EGApalette = &EGApalettes[_EGApaletteNo * PIC_EGAPALETTE_SIZE]; - byte EGApriority[PIC_EGAPRIORITY_SIZE] = {0}; - bool isEGA = false; - int curPos = 0; - uint16 size; - byte pixel; - int i; - GuiPalette palette; - int16 pattern_Code = 0, pattern_Texture = 0; - - memset(&palette, 0, sizeof(palette)); - - if (_EGApaletteNo >= PIC_EGAPALETTE_COUNT) - _EGApaletteNo = 0; - - if (_resMan->getViewType() == kViewEga) { - isEGA = true; - // setup default mapping tables - for (i = 0; i < PIC_EGAPALETTE_TOTALSIZE; i += PIC_EGAPALETTE_SIZE) - memcpy(&EGApalettes[i], &vector_defaultEGApalette, sizeof(vector_defaultEGApalette)); - memcpy(&EGApriority, &vector_defaultEGApriority, sizeof(vector_defaultEGApriority)); - } - - // Drawing - while (curPos < dataSize) { - //warning("%X at %d", data[curPos], curPos); - switch (pic_op = data[curPos++]) { - case PIC_OP_SET_COLOR: - pic_color = data[curPos++]; - if (isEGA) { - pic_color = EGApalette[pic_color]; - pic_color ^= pic_color << 4; - } - break; - case PIC_OP_DISABLE_VISUAL: - pic_color = 0xFF; - break; - - case PIC_OP_SET_PRIORITY: - pic_priority = data[curPos++] & 0x0F; - if (isEGA) { - pic_priority = EGApriority[pic_priority]; - } - break; - case PIC_OP_DISABLE_PRIORITY: - pic_priority = 255; - break; - - case PIC_OP_SET_CONTROL: - pic_control = data[curPos++] & 0x0F; - break; - case PIC_OP_DISABLE_CONTROL: - pic_control = 255; - break; - - case PIC_OP_SHORT_LINES: // short line - vectorGetAbsCoords(data, curPos, x, y); - while (vectorIsNonOpcode(data[curPos])) { - oldx = x; oldy = y; - vectorGetRelCoords(data, curPos, x, y); - Common::Point startPoint(oldx, oldy); - Common::Point endPoint(x, y); - _gfx->OffsetLine(startPoint, endPoint); - _screen->drawLine(startPoint, endPoint, pic_color, pic_priority, pic_control); - } - break; - case PIC_OP_MEDIUM_LINES: // medium line - vectorGetAbsCoords(data, curPos, x, y); - while (vectorIsNonOpcode(data[curPos])) { - oldx = x; oldy = y; - vectorGetRelCoordsMed(data, curPos, x, y); - Common::Point startPoint(oldx, oldy); - Common::Point endPoint(x, y); - _gfx->OffsetLine(startPoint, endPoint); - _screen->drawLine(startPoint, endPoint, pic_color, pic_priority, pic_control); - } - break; - case PIC_OP_LONG_LINES: // long line - vectorGetAbsCoords(data, curPos, x, y); - while (vectorIsNonOpcode(data[curPos])) { - oldx = x; oldy = y; - vectorGetAbsCoords(data, curPos, x, y); - Common::Point startPoint(oldx, oldy); - Common::Point endPoint(x, y); - _gfx->OffsetLine(startPoint, endPoint); - _screen->drawLine(startPoint, endPoint, pic_color, pic_priority, pic_control); - } - break; - - case PIC_OP_FILL: //fill - while (vectorIsNonOpcode(data[curPos])) { - vectorGetAbsCoords(data, curPos, x, y); - vectorFloodFill(x, y, pic_color, pic_priority, pic_control); - } - break; - - case PIC_OP_SET_PATTERN: - pattern_Code = data[curPos++]; - break; - case PIC_OP_SHORT_PATTERNS: - vectorGetPatternTexture(data, curPos, pattern_Code, pattern_Texture); - vectorGetAbsCoords(data, curPos, x, y); - vectorPattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture); - while (vectorIsNonOpcode(data[curPos])) { - vectorGetPatternTexture(data, curPos, pattern_Code, pattern_Texture); - vectorGetRelCoords(data, curPos, x, y); - vectorPattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture); - } - break; - case PIC_OP_MEDIUM_PATTERNS: - vectorGetPatternTexture(data, curPos, pattern_Code, pattern_Texture); - vectorGetAbsCoords(data, curPos, x, y); - vectorPattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture); - while (vectorIsNonOpcode(data[curPos])) { - vectorGetPatternTexture(data, curPos, pattern_Code, pattern_Texture); - vectorGetRelCoordsMed(data, curPos, x, y); - vectorPattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture); - } - break; - case PIC_OP_ABSOLUTE_PATTERN: - while (vectorIsNonOpcode(data[curPos])) { - vectorGetPatternTexture(data, curPos, pattern_Code, pattern_Texture); - vectorGetAbsCoords(data, curPos, x, y); - vectorPattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture); - } - break; - - case PIC_OP_OPX: // Extended functions - if (isEGA) { - switch (pic_op = data[curPos++]) { - case PIC_OPX_EGA_SET_PALETTE_ENTRIES: - while (vectorIsNonOpcode(data[curPos])) { - pixel = data[curPos++]; - if (pixel >= PIC_EGAPALETTE_TOTALSIZE) { - error("picture trying to write to invalid EGA-palette"); - } - EGApalettes[pixel] = data[curPos++]; - } - break; - case PIC_OPX_EGA_SET_PALETTE: - pixel = data[curPos++]; - if (pixel >= PIC_EGAPALETTE_COUNT) { - error("picture trying to write to invalid palette %d", (int)pixel); - } - pixel *= PIC_EGAPALETTE_SIZE; - for (i = 0; i < PIC_EGAPALETTE_SIZE; i++) { - EGApalettes[pixel + i] = data[curPos++]; - } - break; - case PIC_OPX_EGA_MONO0: - curPos += 41; - break; - case PIC_OPX_EGA_MONO1: - case PIC_OPX_EGA_MONO3: - curPos++; - break; - case PIC_OPX_EGA_MONO2: - case PIC_OPX_EGA_MONO4: - break; - case PIC_OPX_EGA_EMBEDDED_VIEW: - vectorGetAbsCoordsNoMirror(data, curPos, x, y); - size = READ_LE_UINT16(data + curPos); curPos += 2; - _priority = pic_priority; // set global priority so the cel gets drawn using current priority as well - drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y, false); - curPos += size; - break; - case PIC_OPX_EGA_SET_PRIORITY_TABLE: - _gfx->PriorityBandsInit(data + curPos); - curPos += 14; - break; - default: - error("Unsupported sci1 extended pic-operation %X", pic_op); - } - } else { - switch (pic_op = data[curPos++]) { - case PIC_OPX_VGA_SET_PALETTE_ENTRIES: - while (vectorIsNonOpcode(data[curPos])) { - curPos++; // skip commands - } - break; - case PIC_OPX_VGA_SET_PALETTE: - curPos += 256 + 4; // Skip over mapping and timestamp - for (i = 0; i < 256; i++) { - palette.colors[i].used = data[curPos++]; - palette.colors[i].r = data[curPos++]; palette.colors[i].g = data[curPos++]; palette.colors[i].b = data[curPos++]; - } - _palette->set(&palette, 2); - break; - case PIC_OPX_VGA_EMBEDDED_VIEW: // draw cel - vectorGetAbsCoordsNoMirror(data, curPos, x, y); - size = READ_LE_UINT16(data + curPos); curPos += 2; - _priority = pic_priority; // set global priority so the cel gets drawn using current priority as well - drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y, false); - curPos += size; - break; - case PIC_OPX_VGA_PRIORITY_TABLE_EQDIST: - _gfx->PriorityBandsInit(-1, READ_LE_UINT16(data + curPos), READ_LE_UINT16(data + curPos + 2)); - curPos += 4; - break; - case PIC_OPX_VGA_PRIORITY_TABLE_EXPLICIT: - _gfx->PriorityBandsInit(data + curPos); - curPos += 14; - break; - default: - error("Unsupported sci1 extended pic-operation %X", pic_op); - } - } - break; - case PIC_OP_TERMINATE: - _priority = pic_priority; - // Dithering EGA pictures - if (isEGA) { - _screen->dither(_addToFlag); - } - return; - default: - error("Unsupported pic-operation %X", pic_op); - } - //printf("picop %X\n", pic_op); - // for debug purposes - //_screen->copyToScreen(); - //g_system->updateScreen(); - //g_system->delayMillis(500); - } - error("picture vector data without terminator"); -} - -bool SciGuiPicture::vectorIsNonOpcode(byte pixel) { - if (pixel >= PIC_OP_FIRST) - return false; - return true; -} - -void SciGuiPicture::vectorGetAbsCoords(byte *data, int &curPos, int16 &x, int16 &y) { - byte pixel = data[curPos++]; - x = data[curPos++] + ((pixel & 0xF0) << 4); - y = data[curPos++] + ((pixel & 0x0F) << 8); - if (_mirroredFlag) x = 319 - x; -} - -void SciGuiPicture::vectorGetAbsCoordsNoMirror(byte *data, int &curPos, int16 &x, int16 &y) { - byte pixel = data[curPos++]; - x = data[curPos++] + ((pixel & 0xF0) << 4); - y = data[curPos++] + ((pixel & 0x0F) << 8); -} - -void SciGuiPicture::vectorGetRelCoords(byte *data, int &curPos, int16 &x, int16 &y) { - byte pixel = data[curPos++]; - if (pixel & 0x80) { - x -= ((pixel >> 4) & 7) * (_mirroredFlag ? -1 : 1); - } else { - x += (pixel >> 4) * (_mirroredFlag ? -1 : 1); - } - if (pixel & 0x08) { - y -= (pixel & 7); - } else { - y += (pixel & 7); - } -} - -void SciGuiPicture::vectorGetRelCoordsMed(byte *data, int &curPos, int16 &x, int16 &y) { - byte pixel = data[curPos++]; - if (pixel & 0x80) { - y -= (pixel & 0x7F); - } else { - y += pixel; - } - pixel = data[curPos++]; - if (pixel & 0x80) { - x -= (128 - (pixel & 0x7F)) * (_mirroredFlag ? -1 : 1); - } else { - x += pixel * (_mirroredFlag ? -1 : 1); - } -} - -void SciGuiPicture::vectorGetPatternTexture(byte *data, int &curPos, int16 pattern_Code, int16 &pattern_Texture) { - if (pattern_Code & SCI_PATTERN_CODE_USE_TEXTURE) { - pattern_Texture = (data[curPos++] >> 1) & 0x7f; - } -} - -// Do not replace w/ some generic code. This algo really needs to behave exactly as the one from sierra -void SciGuiPicture::vectorFloodFill(int16 x, int16 y, byte color, byte priority, byte control) { - GuiPort *curPort = _gfx->GetPort(); - Common::Stack stack; - Common::Point p, p1; - byte screenMask = _screen->getDrawingMask(color, priority, control); - byte matchedMask, matchMask; - int16 w, e, a_set, b_set; - - p.x = x + curPort->left; - p.y = y + curPort->top; - stack.push(p); - - byte searchColor = _screen->getVisual(p.x, p.y); - byte searchPriority = _screen->getPriority(p.x, p.y); - byte searchControl = _screen->getControl(p.x, p.y); - - // This logic was taken directly from sierra sci, floodfill will get aborted on various occations - if (screenMask & SCI_SCREEN_MASK_VISUAL) { - if ((color == _screen->_colorWhite) || (searchColor != _screen->_colorWhite)) - return; - } else if (screenMask & SCI_SCREEN_MASK_PRIORITY) { - if ((priority == 0) || (searchPriority != 0)) - return; - } else if (screenMask & SCI_SCREEN_MASK_CONTROL) { - if ((control == 0) || (searchControl != 0)) - return; - } - - // Now remove screens, that already got the right color/priority/control - if ((screenMask & SCI_SCREEN_MASK_VISUAL) && (searchColor == color)) - screenMask ^= SCI_SCREEN_MASK_VISUAL; - if ((screenMask & SCI_SCREEN_MASK_PRIORITY) && (searchPriority == priority)) - screenMask ^= SCI_SCREEN_MASK_PRIORITY; - if ((screenMask & SCI_SCREEN_MASK_CONTROL) && (searchControl == control)) - screenMask ^= SCI_SCREEN_MASK_CONTROL; - - // Exit, if no screens left - if (!screenMask) - return; - - if (screenMask & SCI_SCREEN_MASK_VISUAL) { - matchMask = SCI_SCREEN_MASK_VISUAL; - } else if (screenMask & SCI_SCREEN_MASK_PRIORITY) { - matchMask = SCI_SCREEN_MASK_PRIORITY; - } else { - matchMask = SCI_SCREEN_MASK_CONTROL; - } - - // hard borders for filling - int l = curPort->rect.left + curPort->left; - int t = curPort->rect.top + curPort->top; - int r = curPort->rect.right + curPort->left - 1; - int b = curPort->rect.bottom + curPort->top - 1; - while (stack.size()) { - p = stack.pop(); - if ((matchedMask = _screen->isFillMatch(p.x, p.y, matchMask, searchColor, searchPriority, searchControl)) == 0) // already filled - continue; - _screen->putPixel(p.x, p.y, screenMask, color, priority, control); - w = p.x; - e = p.x; - // moving west and east pointers as long as there is a matching color to fill - while (w > l && (matchedMask = _screen->isFillMatch(w - 1, p.y, matchMask, searchColor, searchPriority, searchControl))) - _screen->putPixel(--w, p.y, screenMask, color, priority, control); - while (e < r && (matchedMask = _screen->isFillMatch(e + 1, p.y, matchMask, searchColor, searchPriority, searchControl))) - _screen->putPixel(++e, p.y, screenMask, color, priority, control); - // checking lines above and below for possible flood targets - a_set = b_set = 0; - while (w <= e) { - if (p.y > t && (matchedMask = _screen->isFillMatch(w, p.y - 1, matchMask, searchColor, searchPriority, searchControl))) { // one line above - if (a_set == 0) { - p1.x = w; - p1.y = p.y - 1; - stack.push(p1); - a_set = 1; - } - } else - a_set = 0; - - if (p.y < b && (matchedMask = _screen->isFillMatch(w, p.y + 1, matchMask, searchColor, searchPriority, searchControl))) { // one line below - if (b_set == 0) { - p1.x = w; - p1.y = p.y + 1; - stack.push(p1); - b_set = 1; - } - } else - b_set = 0; - w++; - } - } -} - -// Bitmap for drawing sierra circles -static const byte vectorPatternCircles[8][30] = { - { 0x01 }, - { 0x72, 0x02 }, - { 0xCE, 0xF7, 0x7D, 0x0E }, - { 0x1C, 0x3E, 0x7F, 0x7F, 0x7F, 0x3E, 0x1C, 0x00 }, - { 0x38, 0xF8, 0xF3, 0xDF, 0x7F, 0xFF, 0xFD, 0xF7, 0x9F, 0x3F, 0x38 }, - { 0x70, 0xC0, 0x1F, 0xFE, 0xE3, 0x3F, 0xFF, 0xF7, 0x7F, 0xFF, 0xE7, 0x3F, 0xFE, 0xC3, 0x1F, 0xF8, 0x00 }, - { 0xF0, 0x01, 0xFF, 0xE1, 0xFF, 0xF8, 0x3F, 0xFF, 0xDF, 0xFF, 0xF7, 0xFF, 0xFD, 0x7F, 0xFF, 0x9F, 0xFF, - 0xE3, 0xFF, 0xF0, 0x1F, 0xF0, 0x01 }, - { 0xE0, 0x03, 0xF8, 0x0F, 0xFC, 0x1F, 0xFE, 0x3F, 0xFE, 0x3F, 0xFF, 0x7F, 0xFF, 0x7F, 0xFF, 0x7F, 0xFF, - 0x7F, 0xFF, 0x7F, 0xFE, 0x3F, 0xFE, 0x3F, 0xFC, 0x1F, 0xF8, 0x0F, 0xE0, 0x03 } -// { 0x01 }; -// { 0x03, 0x03, 0x03 }, -// { 0x02, 0x07, 0x07, 0x07, 0x02 }, -// { 0x06, 0x06, 0x0F, 0x0F, 0x0F, 0x06, 0x06 }, -// { 0x04, 0x0E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x04 }, -// { 0x0C, 0x1E, 0x1E, 0x1E, 0x3F, 0x3F, 0x3F, 0x1E, 0x1E, 0x1E, 0x0C }, -// { 0x1C, 0x3E, 0x3E, 0x3E, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x3E, 0x3E, 0x3E, 0x1C }, -// { 0x18, 0x3C, 0x7E, 0x7E, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7E, 0x7E, 0x3C, 0x18 } -}; - -// TODO: perhaps this is a better way to set the s_patternTextures array below? -// in that case one would need to adjust bits of secondary table. Bit 256 is ignored by original interpreter -#if 0 -static const byte patternTextures[32 * 2] = { - 0x04, 0x29, 0x40, 0x24, 0x09, 0x41, 0x25, 0x45, - 0x41, 0x90, 0x50, 0x44, 0x48, 0x08, 0x42, 0x28, - 0x89, 0x52, 0x89, 0x88, 0x10, 0x48, 0xA4, 0x08, - 0x44, 0x15, 0x28, 0x24, 0x00, 0x0A, 0x24, 0x20, - // Now the table is actually duplicated, so we won't need to wrap around - 0x04, 0x29, 0x40, 0x24, 0x09, 0x41, 0x25, 0x45, - 0x41, 0x90, 0x50, 0x44, 0x48, 0x08, 0x42, 0x28, - 0x89, 0x52, 0x89, 0x88, 0x10, 0x48, 0xA4, 0x08, - 0x44, 0x15, 0x28, 0x24, 0x00, 0x0A, 0x24, 0x20, -}; -#endif - -// This table is bitwise upwards (from bit0 to bit7), sierras original table went down the bits (bit7 to bit0) -// this was done to simplify things, so we can just run through the table w/o worrying too much about clipping -static const bool vectorPatternTextures[32 * 8 * 2] = { - false, false, true, false, false, false, false, false, // 0x04 - true, false, false, true, false, true, false, false, // 0x29 - false, false, false, false, false, false, true, false, // 0x40 - false, false, true, false, false, true, false, false, // 0x24 - true, false, false, true, false, false, false, false, // 0x09 - true, false, false, false, false, false, true, false, // 0x41 - true, false, true, false, false, true, false, false, // 0x25 - true, false, true, false, false, false, true, false, // 0x45 - true, false, false, false, false, false, true, false, // 0x41 - false, false, false, false, true, false, false, true, // 0x90 - false, false, false, false, true, false, true, false, // 0x50 - false, false, true, false, false, false, true, false, // 0x44 - false, false, false, true, false, false, true, false, // 0x48 - false, false, false, true, false, false, false, false, // 0x08 - false, true, false, false, false, false, true, false, // 0x42 - false, false, false, true, false, true, false, false, // 0x28 - true, false, false, true, false, false, false, true, // 0x89 - false, true, false, false, true, false, true, false, // 0x52 - true, false, false, true, false, false, false, true, // 0x89 - false, false, false, true, false, false, false, true, // 0x88 - false, false, false, false, true, false, false, false, // 0x10 - false, false, false, true, false, false, true, false, // 0x48 - false, false, true, false, false, true, false, true, // 0xA4 - false, false, false, true, false, false, false, false, // 0x08 - false, false, true, false, false, false, true, false, // 0x44 - true, false, true, false, true, false, false, false, // 0x15 - false, false, false, true, false, true, false, false, // 0x28 - false, false, true, false, false, true, false, false, // 0x24 - false, false, false, false, false, false, false, false, // 0x00 - false, true, false, true, false, false, false, false, // 0x0A - false, false, true, false, false, true, false, false, // 0x24 - false, false, false, false, false, true, false, // 0x20 (last bit is not mentioned cause original interpreter also ignores that bit) - // Now the table is actually duplicated, so we won't need to wrap around - false, false, true, false, false, false, false, false, // 0x04 - true, false, false, true, false, true, false, false, // 0x29 - false, false, false, false, false, false, true, false, // 0x40 - false, false, true, false, false, true, false, false, // 0x24 - true, false, false, true, false, false, false, false, // 0x09 - true, false, false, false, false, false, true, false, // 0x41 - true, false, true, false, false, true, false, false, // 0x25 - true, false, true, false, false, false, true, false, // 0x45 - true, false, false, false, false, false, true, false, // 0x41 - false, false, false, false, true, false, false, true, // 0x90 - false, false, false, false, true, false, true, false, // 0x50 - false, false, true, false, false, false, true, false, // 0x44 - false, false, false, true, false, false, true, false, // 0x48 - false, false, false, true, false, false, false, false, // 0x08 - false, true, false, false, false, false, true, false, // 0x42 - false, false, false, true, false, true, false, false, // 0x28 - true, false, false, true, false, false, false, true, // 0x89 - false, true, false, false, true, false, true, false, // 0x52 - true, false, false, true, false, false, false, true, // 0x89 - false, false, false, true, false, false, false, true, // 0x88 - false, false, false, false, true, false, false, false, // 0x10 - false, false, false, true, false, false, true, false, // 0x48 - false, false, true, false, false, true, false, true, // 0xA4 - false, false, false, true, false, false, false, false, // 0x08 - false, false, true, false, false, false, true, false, // 0x44 - true, false, true, false, true, false, false, false, // 0x15 - false, false, false, true, false, true, false, false, // 0x28 - false, false, true, false, false, true, false, false, // 0x24 - false, false, false, false, false, false, false, false, // 0x00 - false, true, false, true, false, false, false, false, // 0x0A - false, false, true, false, false, true, false, false, // 0x24 - false, false, false, false, false, true, false, // 0x20 (last bit is not mentioned cause original interpreter also ignores that bit) -}; - -// Bit offsets into pattern_textures -static const byte vectorPatternTextureOffset[128] = { - 0x00, 0x18, 0x30, 0xc4, 0xdc, 0x65, 0xeb, 0x48, - 0x60, 0xbd, 0x89, 0x05, 0x0a, 0xf4, 0x7d, 0x7d, - 0x85, 0xb0, 0x8e, 0x95, 0x1f, 0x22, 0x0d, 0xdf, - 0x2a, 0x78, 0xd5, 0x73, 0x1c, 0xb4, 0x40, 0xa1, - 0xb9, 0x3c, 0xca, 0x58, 0x92, 0x34, 0xcc, 0xce, - 0xd7, 0x42, 0x90, 0x0f, 0x8b, 0x7f, 0x32, 0xed, - 0x5c, 0x9d, 0xc8, 0x99, 0xad, 0x4e, 0x56, 0xa6, - 0xf7, 0x68, 0xb7, 0x25, 0x82, 0x37, 0x3a, 0x51, - 0x69, 0x26, 0x38, 0x52, 0x9e, 0x9a, 0x4f, 0xa7, - 0x43, 0x10, 0x80, 0xee, 0x3d, 0x59, 0x35, 0xcf, - 0x79, 0x74, 0xb5, 0xa2, 0xb1, 0x96, 0x23, 0xe0, - 0xbe, 0x05, 0xf5, 0x6e, 0x19, 0xc5, 0x66, 0x49, - 0xf0, 0xd1, 0x54, 0xa9, 0x70, 0x4b, 0xa4, 0xe2, - 0xe6, 0xe5, 0xab, 0xe4, 0xd2, 0xaa, 0x4c, 0xe3, - 0x06, 0x6f, 0xc6, 0x4a, 0xa4, 0x75, 0x97, 0xe1 -}; - -void SciGuiPicture::vectorPatternBox(Common::Rect box, byte color, byte prio, byte control) { - byte flag = _screen->getDrawingMask(color, prio, control); - int y, x; - - for (y = box.top; y < box.bottom; y++) { - for (x = box.left; x < box.right; x++) { - _screen->putPixel(x, y, flag, color, prio, control); - } - } -} - -void SciGuiPicture::vectorPatternTexturedBox(Common::Rect box, byte color, byte prio, byte control, byte texture) { - byte flag = _screen->getDrawingMask(color, prio, control); - const bool *textureData = &vectorPatternTextures[vectorPatternTextureOffset[texture]]; - int y, x; - - for (y = box.top; y < box.bottom; y++) { - for (x = box.left; x < box.right; x++) { - if (*textureData) { - _screen->putPixel(x, y, flag, color, prio, control); - } - textureData++; - } - } -} - -void SciGuiPicture::vectorPatternCircle(Common::Rect box, byte size, byte color, byte prio, byte control) { - byte flag = _screen->getDrawingMask(color, prio, control); - const byte *circleData = vectorPatternCircles[size]; - byte bitmap = *circleData; - byte bitNo = 0; - int y, x; - - for (y = box.top; y < box.bottom; y++) { - for (x = box.left; x < box.right; x++) { - if (bitmap & 1) { - _screen->putPixel(x, y, flag, color, prio, control); - } - bitNo++; - if (bitNo == 8) { - circleData++; bitmap = *circleData; bitNo = 0; - } else { - bitmap = bitmap >> 1; - } - } - } -} - -void SciGuiPicture::vectorPatternTexturedCircle(Common::Rect box, byte size, byte color, byte prio, byte control, byte texture) { - byte flag = _screen->getDrawingMask(color, prio, control); - const byte *circleData = vectorPatternCircles[size]; - byte bitmap = *circleData; - byte bitNo = 0; - const bool *textureData = &vectorPatternTextures[vectorPatternTextureOffset[texture]]; - int y, x; - - for (y = box.top; y < box.bottom; y++) { - for (x = box.left; x < box.right; x++) { - if (bitmap & 1) { - if (*textureData) { - _screen->putPixel(x, y, flag, color, prio, control); - } - textureData++; - } - bitNo++; - if (bitNo == 8) { - circleData++; bitmap = *circleData; bitNo = 0; - } else { - bitmap = bitmap >> 1; - } - } - } -} - -void SciGuiPicture::vectorPattern(int16 x, int16 y, byte color, byte priority, byte control, byte code, byte texture) { - byte size = code & SCI_PATTERN_CODE_PENSIZE; - Common::Rect rect; - - // We need to adjust the given coordinates, because the ones given us do not define upper left but somewhat middle - y -= size; if (y < 0) y = 0; - x -= size; if (x < 0) x = 0; - - rect.top = y; rect.left = x; - rect.setHeight((size*2)+1); rect.setWidth((size*2)+2); - _gfx->OffsetRect(rect); - rect.clip(_screen->_width, _screen->_height); - - if (code & SCI_PATTERN_CODE_RECTANGLE) { - // Rectangle - if (code & SCI_PATTERN_CODE_USE_TEXTURE) { - vectorPatternTexturedBox(rect, color, priority, control, texture); - } else { - vectorPatternBox(rect, color, priority, control); - } - - } else { - // Circle - if (code & SCI_PATTERN_CODE_USE_TEXTURE) { - vectorPatternTexturedCircle(rect, size, color, priority, control, texture); - } else { - vectorPatternCircle(rect, size, color, priority, control); - } - } -} - -} // End of namespace Sci diff --git a/engines/sci/gui/gui_picture.h b/engines/sci/gui/gui_picture.h deleted file mode 100644 index 4c3283c53b..0000000000 --- a/engines/sci/gui/gui_picture.h +++ /dev/null @@ -1,82 +0,0 @@ -/* 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_PICTURE_H -#define SCI_GUI_PICTURE_H - -namespace Sci { - -#define SCI_PATTERN_CODE_RECTANGLE 0x10 -#define SCI_PATTERN_CODE_USE_TEXTURE 0x20 -#define SCI_PATTERN_CODE_PENSIZE 0x07 - -class SciGuiPicture { -public: - SciGuiPicture(ResourceManager *resMan, SciGuiGfx *gfx, SciGuiScreen *screen, SciGuiPalette *palette, GuiResourceId resourceId); - ~SciGuiPicture(); - - GuiResourceId getResourceId(); - void draw(int16 animationNr, bool mirroredFlag, bool addToFlag, int16 EGApaletteNo); - -private: - void initData(GuiResourceId resourceId); - void reset(); - void drawSci11Vga(); -#ifdef ENABLE_SCI32 - void drawSci32Vga(); -#endif - void drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 callerX, int16 callerY, bool hasSci32Header); - void drawVectorData(byte *data, int size); - bool vectorIsNonOpcode(byte pixel); - void vectorGetAbsCoords(byte *data, int &curPos, int16 &x, int16 &y); - void vectorGetAbsCoordsNoMirror(byte *data, int &curPos, int16 &x, int16 &y); - void vectorGetRelCoords(byte *data, int &curPos, int16 &x, int16 &y); - void vectorGetRelCoordsMed(byte *data, int &curPos, int16 &x, int16 &y); - void vectorGetPatternTexture(byte *data, int &curPos, int16 pattern_Code, int16 &pattern_Texture); - void vectorFloodFill(int16 x, int16 y, byte color, byte prio, byte control); - void vectorPattern(int16 x, int16 y, byte pic_color, byte pic_priority, byte pic_control, byte code, byte texture); - void vectorPatternBox(Common::Rect box, byte color, byte prio, byte control); - void vectorPatternTexturedBox(Common::Rect box, byte color, byte prio, byte control, byte texture); - void vectorPatternCircle(Common::Rect box, byte size, byte color, byte prio, byte control); - void vectorPatternTexturedCircle(Common::Rect box, byte size, byte color, byte prio, byte control, byte texture); - - ResourceManager *_resMan; - SciGuiGfx *_gfx; - SciGuiScreen *_screen; - SciGuiPalette *_palette; - - int16 _resourceId; - Resource *_resource; - - int16 _animationNr; - bool _mirroredFlag; - bool _addToFlag; - int16 _EGApaletteNo; - byte _priority; -}; - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui/gui_portrait.cpp b/engines/sci/gui/gui_portrait.cpp deleted file mode 100644 index 09eba8a24d..0000000000 --- a/engines/sci/gui/gui_portrait.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* 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/util.h" -#include "common/stack.h" -#include "graphics/primitives.h" - -#include "sci/sci.h" -#include "sci/engine/state.h" -#include "sci/gui/gui_screen.h" -#include "sci/gui/gui_palette.h" -#include "sci/gui/gui_portrait.h" - -namespace Sci { - -SciGuiPortrait::SciGuiPortrait(ResourceManager *resMan, SciGuiScreen *screen, SciGuiPalette *palette, Common::String resourceName) - : _resMan(resMan), _screen(screen), _palette(palette), _resourceName(resourceName) { - init(); -} - -SciGuiPortrait::~SciGuiPortrait() { -} - -void SciGuiPortrait::init() { - // .BIN files are loaded from actors directory and from .\ directory - // header: - // 3 bytes "WIN" - // 2 bytes main height (should be the same as first bitmap header height) - // 2 bytes main width (should be the same as first bitmap header width) - // 2 bytes animation count - // 2 bytes unknown - // 2 bytes unknown - // 4 bytes paletteSize (base 1) - // paletteSize bytes paletteData - // 14 bytes bitmap header - // -> 4 bytes unknown - // -> 2 bytes height - // -> 2 bytes width - // -> 6 bytes unknown - // height * width bitmap data - // another animation count times bitmap header and data -} - -} // End of namespace Sci diff --git a/engines/sci/gui/gui_portrait.h b/engines/sci/gui/gui_portrait.h deleted file mode 100644 index b97f3dd2a6..0000000000 --- a/engines/sci/gui/gui_portrait.h +++ /dev/null @@ -1,49 +0,0 @@ -/* 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_PORTRAITS_H -#define SCI_GUI_PORTRAITS_H - -namespace Sci { - -class SciGuiPortrait { -public: - SciGuiPortrait(ResourceManager *resMan, SciGuiScreen *screen, SciGuiPalette *palette, Common::String resourceName); - ~SciGuiPortrait(); - -private: - void init(); - - ResourceManager *_resMan; - SciGuiScreen *_screen; - SciGuiPalette *_palette; - - Common::String _resourceName; - byte *_resourceData; -}; - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui/gui_screen.cpp b/engines/sci/gui/gui_screen.cpp deleted file mode 100644 index 702b68d6b6..0000000000 --- a/engines/sci/gui/gui_screen.cpp +++ /dev/null @@ -1,513 +0,0 @@ -/* 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 "graphics/surface.h" - -#include "sci/sci.h" -#include "sci/engine/state.h" -#include "sci/gui/gui_screen.h" - -namespace Sci { - -SciGuiScreen::SciGuiScreen(ResourceManager *resMan, int16 width, int16 height, bool upscaledHires) : - _resMan(resMan), _width(width), _height(height), _upscaledHires(upscaledHires) { - - _pixels = _width * _height; - - _displayWidth = _width; - _displayHeight = _height; - if (_upscaledHires) { - _displayWidth *= 2; - _displayHeight *= 2; - } - _displayPixels = _displayWidth * _displayHeight; - - _visualScreen = (byte *)calloc(_pixels, 1); - _priorityScreen = (byte *)calloc(_pixels, 1); - _controlScreen = (byte *)calloc(_pixels, 1); - _displayScreen = (byte *)calloc(_displayPixels, 1); - - // Sets display screen to be actually displayed - _activeScreen = _displayScreen; - - _picNotValid = 0; - _picNotValidSci11 = 0; - _unditherState = true; - - if (_resMan->isVGA()) { - _colorWhite = 255; - if (getSciVersion() >= SCI_VERSION_1_1) - _colorDefaultVectorData = 255; - else - _colorDefaultVectorData = 0; - } else { - _colorWhite = 15; - _colorDefaultVectorData = 0; - } - - // Initialize the actual screen - initGraphics(_displayWidth, _displayHeight, _displayWidth > 320); -} - -SciGuiScreen::~SciGuiScreen() { - free(_visualScreen); - free(_priorityScreen); - free(_controlScreen); - free(_displayScreen); -} - -void SciGuiScreen::copyToScreen() { - g_system->copyRectToScreen(_activeScreen, _displayWidth, 0, 0, _displayWidth, _displayHeight); -} - -void SciGuiScreen::copyFromScreen(byte *buffer) { - Graphics::Surface *screen; - screen = g_system->lockScreen(); - memcpy(buffer, screen->pixels, _displayWidth * _displayHeight); - g_system->unlockScreen(); -} - -void SciGuiScreen::copyRectToScreen(const Common::Rect &rect) { - if (!_upscaledHires) { - g_system->copyRectToScreen(_activeScreen + rect.top * _displayWidth + rect.left, _displayWidth, rect.left, rect.top, rect.width(), rect.height()); - } else { - g_system->copyRectToScreen(_activeScreen + rect.top * 2 * _displayWidth + rect.left * 2, _displayWidth, rect.left * 2, rect.top * 2, rect.width() * 2, rect.height() * 2); - } -} - -void SciGuiScreen::copyRectToScreen(const Common::Rect &rect, int16 x, int16 y) { - if (!_upscaledHires) { - g_system->copyRectToScreen(_activeScreen + rect.top * _displayWidth + rect.left, _displayWidth, x, y, rect.width(), rect.height()); - } else { - g_system->copyRectToScreen(_activeScreen + rect.top * 2 * _displayWidth + rect.left * 2, _displayWidth, x * 2, y * 2, rect.width() * 2, rect.height() * 2); - } -} - -byte SciGuiScreen::getDrawingMask(byte color, byte prio, byte control) { - byte flag = 0; - if (color != 255) - flag |= SCI_SCREEN_MASK_VISUAL; - if (prio != 255) - flag |= SCI_SCREEN_MASK_PRIORITY; - if (control != 255) - flag |= SCI_SCREEN_MASK_CONTROL; - return flag; -} - -void SciGuiScreen::putPixel(int x, int y, byte drawMask, byte color, byte priority, byte control) { - int offset = y * _width + x; - - if (drawMask & SCI_SCREEN_MASK_VISUAL) { - _visualScreen[offset] = color; - if (!_upscaledHires) { - _displayScreen[offset] = color; - } else { - int displayOffset = y * 2 * _displayWidth + x * 2; - _displayScreen[displayOffset] = color; - _displayScreen[displayOffset + 1] = color; - _displayScreen[displayOffset + _displayWidth] = color; - _displayScreen[displayOffset + _displayWidth + 1] = color; - } - } - if (drawMask & SCI_SCREEN_MASK_PRIORITY) - _priorityScreen[offset] = priority; - if (drawMask & SCI_SCREEN_MASK_CONTROL) - _controlScreen[offset] = control; -} - -// This will just change a pixel directly on displayscreen. Its supposed to get only used on upscaled-Hires games where -// hires content needs to get drawn ONTO the upscaled display screen (like japanese fonts, hires portraits, etc.) -void SciGuiScreen::putPixelOnDisplay(int x, int y, byte color) { - int offset = y * _width + x; - _displayScreen[offset] = color; -} - -// Sierra's Bresenham line drawing -// WARNING: Do not just blindly replace this with Graphics::drawLine(), as it seems to create issues with flood fill -void SciGuiScreen::drawLine(Common::Point startPoint, Common::Point endPoint, byte color, byte priority, byte control) { - int16 left = startPoint.x; - int16 top = startPoint.y; - int16 right = endPoint.x; - int16 bottom = endPoint.y; - - //set_drawing_flag - byte drawMask = getDrawingMask(color, priority, control); - - // horizontal line - if (top == bottom) { - if (right < left) - SWAP(right, left); - for (int i = left; i <= right; i++) - putPixel(i, top, drawMask, color, priority, control); - return; - } - // vertical line - if (left == right) { - if (top > bottom) - SWAP(top, bottom); - for (int i = top; i <= bottom; i++) - putPixel(left, i, drawMask, color, priority, control); - return; - } - // sloped line - draw with Bresenham algorithm - int dy = bottom - top; - int dx = right - left; - int stepy = dy < 0 ? -1 : 1; - int stepx = dx < 0 ? -1 : 1; - dy = ABS(dy) << 1; - dx = ABS(dx) << 1; - - // setting the 1st and last pixel - putPixel(left, top, drawMask, color, priority, control); - putPixel(right, bottom, drawMask, color, priority, control); - // drawing the line - if (dx > dy) { // going horizontal - int fraction = dy - (dx >> 1); - while (left != right) { - if (fraction >= 0) { - top += stepy; - fraction -= dx; - } - left += stepx; - fraction += dy; - putPixel(left, top, drawMask, color, priority, control); - } - } else { // going vertical - int fraction = dx - (dy >> 1); - while (top != bottom) { - if (fraction >= 0) { - left += stepx; - fraction -= dy; - } - top += stepy; - fraction += dx; - putPixel(left, top, drawMask, color, priority, control); - } - } -} - -byte SciGuiScreen::getVisual(int x, int y) { - return _visualScreen[y * _width + x]; -} - -byte SciGuiScreen::getPriority(int x, int y) { - return _priorityScreen[y * _width + x]; -} - -byte SciGuiScreen::getControl(int x, int y) { - return _controlScreen[y * _width + x]; -} - -byte SciGuiScreen::isFillMatch(int16 x, int16 y, byte screenMask, byte t_color, byte t_pri, byte t_con) { - int offset = y * _width + x; - byte match = 0; - - if (screenMask & SCI_SCREEN_MASK_VISUAL && *(_visualScreen + offset) == t_color) - match |= SCI_SCREEN_MASK_VISUAL; - if (screenMask & SCI_SCREEN_MASK_PRIORITY && *(_priorityScreen + offset) == t_pri) - match |= SCI_SCREEN_MASK_PRIORITY; - if (screenMask & SCI_SCREEN_MASK_CONTROL && *(_controlScreen + offset) == t_con) - match |= SCI_SCREEN_MASK_CONTROL; - return match; -} - -int SciGuiScreen::bitsGetDataSize(Common::Rect rect, byte mask) { - int byteCount = sizeof(rect) + sizeof(mask); - int pixels = rect.width() * rect.height(); - if (mask & SCI_SCREEN_MASK_VISUAL) { - byteCount += pixels; // _visualScreen - if (!_upscaledHires) { - byteCount += pixels; // _displayScreen - } else { - byteCount += pixels * 4; // _displayScreen (upscaled hires) - } - } - if (mask & SCI_SCREEN_MASK_PRIORITY) { - byteCount += pixels; // _priorityScreen - } - if (mask & SCI_SCREEN_MASK_CONTROL) { - byteCount += pixels; // _controlScreen - } - if (mask & SCI_SCREEN_MASK_DISPLAY) { - if (!_upscaledHires) - error("bitsGetDataSize() called w/o being in upscaled hires mode"); - byteCount += pixels; // _displayScreen (coordinates actually are given to us for hires displayScreen) - } - - return byteCount; -} - -void SciGuiScreen::bitsSave(Common::Rect rect, byte mask, byte *memoryPtr) { - memcpy(memoryPtr, (void *)&rect, sizeof(rect)); memoryPtr += sizeof(rect); - memcpy(memoryPtr, (void *)&mask, sizeof(mask)); memoryPtr += sizeof(mask); - - if (mask & SCI_SCREEN_MASK_VISUAL) { - bitsSaveScreen(rect, _visualScreen, memoryPtr); - bitsSaveDisplayScreen(rect, memoryPtr); - } - if (mask & SCI_SCREEN_MASK_PRIORITY) { - bitsSaveScreen(rect, _priorityScreen, memoryPtr); - } - if (mask & SCI_SCREEN_MASK_CONTROL) { - bitsSaveScreen(rect, _controlScreen, memoryPtr); - } - if (mask & SCI_SCREEN_MASK_DISPLAY) { - if (!_upscaledHires) - error("bitsSave() called w/o being in upscaled hires mode"); - bitsSaveScreen(rect, _displayScreen, memoryPtr); - } -} - -void SciGuiScreen::bitsSaveScreen(Common::Rect rect, byte *screen, byte *&memoryPtr) { - int width = rect.width(); - int y; - - screen += (rect.top * _width) + rect.left; - - for (y = rect.top; y < rect.bottom; y++) { - memcpy(memoryPtr, (void*)screen, width); memoryPtr += width; - screen += _width; - } -} - -void SciGuiScreen::bitsSaveDisplayScreen(Common::Rect rect, byte *&memoryPtr) { - byte *screen = _displayScreen; - int width = rect.width(); - int y; - - if (!_upscaledHires) { - screen += (rect.top * _displayWidth) + rect.left; - } else { - screen += (rect.top * 2 * _displayWidth) + rect.left * 2; - width *= 2; - rect.top *= 2; rect.bottom *= 2; - } - - for (y = rect.top; y < rect.bottom; y++) { - memcpy(memoryPtr, (void*)screen, width); memoryPtr += width; - screen += _displayWidth; - } -} - -void SciGuiScreen::bitsGetRect(byte *memoryPtr, Common::Rect *destRect) { - memcpy((void *)destRect, memoryPtr, sizeof(Common::Rect)); -} - -void SciGuiScreen::bitsRestore(byte *memoryPtr) { - Common::Rect rect; - byte mask; - - memcpy((void *)&rect, memoryPtr, sizeof(rect)); memoryPtr += sizeof(rect); - memcpy((void *)&mask, memoryPtr, sizeof(mask)); memoryPtr += sizeof(mask); - - if (mask & SCI_SCREEN_MASK_VISUAL) { - bitsRestoreScreen(rect, memoryPtr, _visualScreen); - bitsRestoreDisplayScreen(rect, memoryPtr); - } - if (mask & SCI_SCREEN_MASK_PRIORITY) { - bitsRestoreScreen(rect, memoryPtr, _priorityScreen); - } - if (mask & SCI_SCREEN_MASK_CONTROL) { - bitsRestoreScreen(rect, memoryPtr, _controlScreen); - } - if (mask & SCI_SCREEN_MASK_DISPLAY) { - if (!_upscaledHires) - error("bitsRestore() called w/o being in upscaled hires mode"); - bitsRestoreScreen(rect, memoryPtr, _displayScreen); - } -} - -void SciGuiScreen::bitsRestoreScreen(Common::Rect rect, byte *&memoryPtr, byte *screen) { - int width = rect.width(); - int y; - - screen += (rect.top * _width) + rect.left; - - for (y = rect.top; y < rect.bottom; y++) { - memcpy((void*) screen, memoryPtr, width); memoryPtr += width; - screen += _width; - } -} - -void SciGuiScreen::bitsRestoreDisplayScreen(Common::Rect rect, byte *&memoryPtr) { - byte *screen = _displayScreen; - int width = rect.width(); - int y; - - if (!_upscaledHires) { - screen += (rect.top * _displayWidth) + rect.left; - } else { - screen += (rect.top * 2 * _displayWidth) + rect.left * 2; - width *= 2; - rect.top *= 2; rect.bottom *= 2; - } - - for (y = rect.top; y < rect.bottom; y++) { - memcpy((void*) screen, memoryPtr, width); memoryPtr += width; - screen += _displayWidth; - } -} - -void SciGuiScreen::setPalette(GuiPalette*pal) { - // just copy palette to system - byte bpal[4 * 256]; - // Get current palette, update it and put back - g_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; - } - g_system->setPalette(bpal, 0, 256); -} - -void SciGuiScreen::setVerticalShakePos(uint16 shakePos) { - if (!_upscaledHires) - g_system->setShakePos(shakePos); - else - g_system->setShakePos(shakePos * 2); -} - -void SciGuiScreen::dither(bool addToFlag) { - int y, x; - byte color, ditheredColor; - byte *visualPtr = _visualScreen; - byte *displayPtr = _displayScreen; - - if (!_unditherState) { - // Do dithering on visual and display-screen - for (y = 0; y < _height; y++) { - for (x = 0; x < _width; x++) { - color = *visualPtr; - if (color & 0xF0) { - color ^= color << 4; - color = ((x^y) & 1) ? color >> 4 : color & 0x0F; - *displayPtr = color; - if (_upscaledHires) { - *(displayPtr + 1) = color; - *(displayPtr + _displayWidth) = color; - *(displayPtr + _displayWidth + 1) = color; - } - *visualPtr = color; - } - visualPtr++; displayPtr++; - if (_upscaledHires) - displayPtr++; - } - if (_upscaledHires) - displayPtr += _displayWidth; - } - } else { - if (!addToFlag) - memset(&_unditherMemorial, 0, sizeof(_unditherMemorial)); - // Do dithering on visual screen and put decoded but undithered byte onto display-screen - for (y = 0; y < _height; y++) { - for (x = 0; x < _width; x++) { - color = *visualPtr; - if (color & 0xF0) { - color ^= color << 4; - // remember dither combination for cel-undithering - _unditherMemorial[color]++; - // if decoded color wants do dither with black on left side, we turn it around - // otherwise the normal ega color would get used for display - if (color & 0xF0) { - ditheredColor = color; - } else { - ditheredColor = color << 4; - } - *displayPtr = ditheredColor; - if (_upscaledHires) { - *(displayPtr + 1) = ditheredColor; - *(displayPtr + _displayWidth) = ditheredColor; - *(displayPtr + _displayWidth + 1) = ditheredColor; - } - color = ((x^y) & 1) ? color >> 4 : color & 0x0F; - *visualPtr = color; - } - visualPtr++; displayPtr++; - if (_upscaledHires) - displayPtr++; - } - if (_upscaledHires) - displayPtr += _displayWidth; - } - } -} - -void SciGuiScreen::unditherSetState(bool flag) { - _unditherState = flag; -} - -int16 *SciGuiScreen::unditherGetMemorial() { - if (_unditherState) - return (int16 *)&_unditherMemorial; - else - return NULL; -} - -void SciGuiScreen::debugShowMap(int mapNo) { - // We cannot really support changing maps when in upscaledHires mode - if (_upscaledHires) - return; - - switch (mapNo) { - case 0: - _activeScreen = _visualScreen; - break; - case 1: - _activeScreen = _priorityScreen; - break; - case 2: - _activeScreen = _controlScreen; - break; - case 3: - _activeScreen = _displayScreen; - break; - } - copyToScreen(); -} - -void SciGuiScreen::scale2x(byte *src, byte *dst, int16 srcWidth, int16 srcHeight) { - int newWidth = srcWidth * 2; - byte *srcPtr = src; - - for (int y = 0; y < srcHeight; y++) { - for (int x = 0; x < srcWidth; x++) { - int destOffset = y * 2 * newWidth + x * 2; - dst[destOffset] = *srcPtr; - dst[destOffset + 1] = *srcPtr; - dst[destOffset + newWidth] = *srcPtr; - dst[destOffset + newWidth + 1] = *srcPtr; - srcPtr++; - } - } -} - -} // End of namespace Sci diff --git a/engines/sci/gui/gui_screen.h b/engines/sci/gui/gui_screen.h deleted file mode 100644 index 1429e3d7be..0000000000 --- a/engines/sci/gui/gui_screen.h +++ /dev/null @@ -1,130 +0,0 @@ -/* 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_SCREEN_H -#define SCI_GUI_SCREEN_H - -#include "sci/sci.h" -#include "sci/gui/gui_helpers.h" - -namespace Sci { - -#define SCI_SCREEN_MAXHEIGHT 400 - -#define SCI_SCREEN_MASK_VISUAL 1 -#define SCI_SCREEN_MASK_PRIORITY 2 -#define SCI_SCREEN_MASK_CONTROL 4 -#define SCI_SCREEN_MASK_DISPLAY 8 // not official sierra sci -#define SCI_SCREEN_MASK_ALL SCI_SCREEN_MASK_VISUAL|SCI_SCREEN_MASK_PRIORITY|SCI_SCREEN_MASK_CONTROL - -#define SCI_SCREEN_UNDITHERMEMORIAL_SIZE 256 - -class SciGuiScreen { -public: - SciGuiScreen(ResourceManager *resMan, int16 width = 320, int16 height = 200, bool upscaledHires = false); - ~SciGuiScreen(); - - void copyToScreen(); - void copyFromScreen(byte *buffer); - void copyRectToScreen(const Common::Rect &rect); - void copyRectToScreen(const Common::Rect &rect, int16 x, int16 y); - - byte getDrawingMask(byte color, byte prio, byte control); - void putPixel(int x, int y, byte drawMask, byte color, byte prio, byte control); - void putPixelOnDisplay(int x, int y, byte color); - void drawLine(Common::Point startPoint, Common::Point endPoint, byte color, byte prio, byte control); - void drawLine(int16 left, int16 top, int16 right, int16 bottom, byte color, byte prio, byte control) { - drawLine(Common::Point(left, top), Common::Point(right, bottom), color, prio, control); - } - bool getUpscaledHires() { - return _upscaledHires; - } - byte getVisual(int x, int y); - byte getPriority(int x, int y); - byte getControl(int x, int y); - byte isFillMatch(int16 x, int16 y, byte drawMask, byte t_color, byte t_pri, byte t_con); - - int bitsGetDataSize(Common::Rect rect, byte mask); - void bitsSave(Common::Rect rect, byte mask, byte *memoryPtr); - void bitsGetRect(byte *memoryPtr, Common::Rect *destRect); - void bitsRestore(byte *memoryPtr); - - void setPalette(GuiPalette*pal); - - void setVerticalShakePos(uint16 shakePos); - - void scale2x(byte *src, byte *dst, int16 srcWidth, int16 srcHeight); - - void dither(bool addToFlag); - void unditherSetState(bool flag); - int16 *unditherGetMemorial(); - - void debugShowMap(int mapNo); - - uint16 _width; - uint16 _height; - uint _pixels; - uint16 _displayWidth; - uint16 _displayHeight; - uint _displayPixels; - - int _picNotValid; // possible values 0, 1 and 2 - int _picNotValidSci11; // another variable that is used by kPicNotValid in sci1.1 - - byte _colorWhite; - byte _colorDefaultVectorData; - -private: - void bitsRestoreScreen(Common::Rect rect, byte *&memoryPtr, byte *screen); - void bitsRestoreDisplayScreen(Common::Rect rect, byte *&memoryPtr); - void bitsSaveScreen(Common::Rect rect, byte *screen, byte *&memoryPtr); - void bitsSaveDisplayScreen(Common::Rect rect, byte *&memoryPtr); - - bool _unditherState; - int16 _unditherMemorial[SCI_SCREEN_UNDITHERMEMORIAL_SIZE]; - -public: // HACK. TODO: make private - // these screens have the real resolution of the game engine (320x200 for SCI0/SCI1/SCI11 games, 640x480 for SCI2 games) - // SCI0 games will be dithered in here at any time - byte *_visualScreen; - byte *_priorityScreen; - byte *_controlScreen; - - // this screen is the one that is actually displayed to the user. It may be 640x480 for japanese SCI1 games - // SCI0 games may be undithered in here. Only read from this buffer for Save/ShowBits usage. - byte *_displayScreen; -private: - Common::Rect getScaledRect(Common::Rect rect); - - ResourceManager *_resMan; - - // this is a pointer to the currently active screen (changing it only required for debug purposes) - byte *_activeScreen; - bool _upscaledHires; -}; - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui/gui_text.cpp b/engines/sci/gui/gui_text.cpp deleted file mode 100644 index 218008a95e..0000000000 --- a/engines/sci/gui/gui_text.cpp +++ /dev/null @@ -1,410 +0,0 @@ -/* 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/util.h" -#include "common/stack.h" -#include "graphics/primitives.h" - -#include "sci/sci.h" -#include "sci/engine/state.h" -#include "sci/gui/gui_gfx.h" -#include "sci/gui/gui_font.h" -#include "sci/gui/gui_text.h" - -namespace Sci { - -SciGuiText::SciGuiText(ResourceManager *resMan, SciGuiGfx *gfx, SciGuiScreen *screen) - : _resMan(resMan), _gfx(gfx), _screen(screen) { - init(); -} - -SciGuiText::~SciGuiText() { - delete _font; -} - -void SciGuiText::init() { - _font = NULL; - _codeFonts = NULL; - _codeFontsCount = 0; - _codeColors = NULL; - _codeColorsCount = 0; -} - -GuiResourceId SciGuiText::GetFontId() { - return _gfx->_curPort->fontId; -} - -SciGuiFont *SciGuiText::GetFont() { - if ((_font == NULL) || (_font->getResourceId() != _gfx->_curPort->fontId)) - _font = new SciGuiFont(_resMan, _gfx->_curPort->fontId); - - return _font; -} - -void SciGuiText::SetFont(GuiResourceId fontId) { - if ((_font == NULL) || (_font->getResourceId() != fontId)) - _font = new SciGuiFont(_resMan, fontId); - - _gfx->_curPort->fontId = _font->getResourceId(); - _gfx->_curPort->fontHeight = _font->getHeight(); -} - -void SciGuiText::CodeSetFonts(int argc, reg_t *argv) { - int i; - - delete _codeFonts; - _codeFontsCount = argc; - _codeFonts = new GuiResourceId[argc]; - for (i = 0; i < argc; i++) { - _codeFonts[i] = (GuiResourceId)argv[i].toUint16(); - } -} - -void SciGuiText::CodeSetColors(int argc, reg_t *argv) { - int i; - - delete _codeColors; - _codeColorsCount = argc; - _codeColors = new uint16[argc]; - for (i = 0; i < argc; i++) { - _codeColors[i] = argv[i].toUint16(); - } -} - -void SciGuiText::ClearChar(int16 chr) { - if (_gfx->_curPort->penMode != 1) - return; - Common::Rect rect; - rect.top = _gfx->_curPort->curTop; - rect.bottom = rect.top + _gfx->_curPort->fontHeight; - rect.left = _gfx->_curPort->curLeft; - rect.right = rect.left + GetFont()->getCharWidth(chr); - _gfx->EraseRect(rect); -} - -void SciGuiText::DrawChar(int16 chr) { - chr = chr & 0xFF; - ClearChar(chr); - StdChar(chr); - _gfx->_curPort->curLeft += GetFont()->getCharWidth(chr); -} - -void SciGuiText::StdChar(int16 chr) { -#if 0 - CResFont*res = getResFont(); - if (res) - res->Draw(chr, _curPort->top + _curPort->curTop, _curPort->left - + _curPort->curLeft, _vSeg, 320, _curPort->penClr, - _curPort->textFace); -#endif -} - -// This internal function gets called as soon as a '|' is found in a text -// It will process the encountered code and set new font/set color -// We only support one-digit codes currently, don't know if multi-digit codes are possible -// Returns textcode character count -int16 SciGuiText::CodeProcessing(const char *&text, GuiResourceId orgFontId, int16 orgPenColor) { - const char *textCode = text; - int16 textCodeSize = 0; - char curCode; - unsigned char curCodeParm; - - // Find the end of the textcode - while ((++textCodeSize) && (*text != 0) && (*text++ != 0x7C)) { } - - // possible TextCodes: - // c -> sets textColor to current port pen color - // cX -> sets textColor to _textColors[X-1] - curCode = textCode[0]; - curCodeParm = textCode[1]; - if (isdigit(curCodeParm)) { - curCodeParm -= '0'; - } else { - curCodeParm = 0; - } - switch (curCode) { - case 'c': // set text color - if (curCodeParm == 0) { - _gfx->_curPort->penClr = orgPenColor; - } else { - if (curCodeParm < _codeColorsCount) { - _gfx->_curPort->penClr = _codeColors[curCodeParm]; - } - } - break; - case 'f': - if (curCodeParm == 0) { - SetFont(orgFontId); - } else { - if (curCodeParm < _codeFontsCount) { - SetFont(_codeFonts[curCodeParm]); - } - } - break; - } - return textCodeSize; -} - -// return max # of chars to fit maxwidth with full words -int16 SciGuiText::GetLongest(const char *text, int16 maxWidth, GuiResourceId orgFontId) { - char curChar; - int16 maxChars = 0, curCharCount = 0; - uint16 width = 0; - GuiResourceId oldFontId = GetFontId(); - int16 oldPenColor = _gfx->_curPort->penClr; - - GetFont(); - if (!_font) - return 0; - - while (width <= maxWidth) { - curChar = *text++; - switch (curChar) { - case 0x7C: - if (getSciVersion() >= SCI_VERSION_1_1) { - curCharCount++; - curCharCount += CodeProcessing(text, orgFontId, oldPenColor); - continue; - } - break; - - case 0xD: - curCharCount++; - continue; - - case 0xA: - curCharCount++; - case 0: - SetFont(oldFontId); - _gfx->PenColor(oldPenColor); - return curCharCount; - - case ' ': - maxChars = curCharCount + 1; - break; - } - width += _font->getCharWidth(curChar); - curCharCount++; - } - SetFont(oldFontId); - _gfx->PenColor(oldPenColor); - return maxChars; -} - -void SciGuiText::Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight) { - unsigned char curChar; - GuiResourceId oldFontId = GetFontId(); - int16 oldPenColor = _gfx->_curPort->penClr; - - textWidth = 0; textHeight = 0; - - GetFont(); - if (_font) { - text += from; - while (len--) { - curChar = *text++; - switch (curChar) { - case 0x0A: - case 0x0D: - textHeight = MAX (textHeight, _gfx->_curPort->fontHeight); - break; - case 0x7C: - if (getSciVersion() >= SCI_VERSION_1_1) { - len -= CodeProcessing(text, orgFontId, 0); - break; - } - default: - textHeight = MAX (textHeight, _gfx->_curPort->fontHeight); - textWidth += _font->getCharWidth(curChar); - } - } - } - SetFont(oldFontId); - _gfx->PenColor(oldPenColor); - return; -} - -void SciGuiText::StringWidth(const char *str, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight) { - Width(str, 0, (int16)strlen(str), orgFontId, textWidth, textHeight); -} - -void SciGuiText::ShowString(const char *str, GuiResourceId orgFontId, int16 orgPenColor) { - Show(str, 0, (int16)strlen(str), orgFontId, orgPenColor); -} -void SciGuiText::DrawString(const char *str, GuiResourceId orgFontId, int16 orgPenColor) { - Draw(str, 0, (int16)strlen(str), orgFontId, orgPenColor); -} - -int16 SciGuiText::Size(Common::Rect &rect, const char *str, GuiResourceId fontId, int16 maxWidth) { - GuiResourceId oldFontId = GetFontId(); - int16 oldPenColor = _gfx->_curPort->penClr; - int16 charCount; - int16 maxTextWidth = 0, textWidth; - int16 totalHeight = 0, textHeight; - - if (fontId != -1) - SetFont(fontId); - rect.top = rect.left = 0; - - if (maxWidth < 0) { // force output as single line - StringWidth(str, oldFontId, textWidth, textHeight); - rect.bottom = textHeight; - rect.right = textWidth; - } else { - // rect.right=found widest line with RTextWidth and GetLongest - // rect.bottom=num. lines * GetPointSize - rect.right = (maxWidth ? maxWidth : 192); - const char*p = str; - while (*p) { - //if (*p == 0xD || *p == 0xA) { - // p++; - // continue; - //} - charCount = GetLongest(p, rect.right, oldFontId); - if (charCount == 0) - break; - Width(p, 0, charCount, oldFontId, textWidth, textHeight); - maxTextWidth = MAX(textWidth, maxTextWidth); - totalHeight += textHeight; - p += charCount; - } - rect.bottom = totalHeight; - rect.right = maxWidth ? maxWidth : MIN(rect.right, maxTextWidth); - } - SetFont(oldFontId); - _gfx->PenColor(oldPenColor); - return rect.right; -} - -// returns maximum font height used -void SciGuiText::Draw(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 orgPenColor) { - int16 curChar, charWidth; - Common::Rect rect; - - GetFont(); - if (!_font) - return; - - rect.top = _gfx->_curPort->curTop; - rect.bottom = rect.top + _gfx->_curPort->fontHeight; - text += from; - while (len--) { - curChar = (*text++); - switch (curChar) { - case 0x0A: - case 0x0D: - case 0: - break; - case 0x7C: - if (getSciVersion() >= SCI_VERSION_1_1) { - len -= CodeProcessing(text, orgFontId, orgPenColor); - break; - } - default: - charWidth = _font->getCharWidth(curChar); - // clear char - if (_gfx->_curPort->penMode == 1) { - rect.left = _gfx->_curPort->curLeft; - rect.right = rect.left + charWidth; - _gfx->EraseRect(rect); - } - // CharStd - _font->draw(_screen, curChar, _gfx->_curPort->top + _gfx->_curPort->curTop, _gfx->_curPort->left + _gfx->_curPort->curLeft, _gfx->_curPort->penClr, _gfx->_curPort->greyedOutput); - _gfx->_curPort->curLeft += charWidth; - } - } -} - -// returns maximum font height used -void SciGuiText::Show(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 orgPenColor) { - Common::Rect rect; - - rect.top = _gfx->_curPort->curTop; - rect.bottom = rect.top + _gfx->GetPointSize(); - rect.left = _gfx->_curPort->curLeft; - Draw(text, from, len, orgFontId, orgPenColor); - rect.right = _gfx->_curPort->curLeft; - _gfx->BitsShow(rect); -} - -// Draws a text in rect. -void SciGuiText::Box(const char *text, int16 bshow, const Common::Rect &rect, GuiTextAlignment alignment, GuiResourceId fontId) { - int16 textWidth, textHeight, charCount; - int16 offset = 0; - int16 hline = 0; - GuiResourceId orgFontId = GetFontId(); - int16 orgPenColor = _gfx->_curPort->penClr; - - if (fontId != -1) - SetFont(fontId); - - while (*text) { -// if (*text == 0xD || *text == 0xA) { -// text++; -// continue; -// } - charCount = GetLongest(text, rect.width(), orgFontId); - if (charCount == 0) - break; - Width(text, 0, charCount, orgFontId, textWidth, textHeight); - switch (alignment) { - case SCI_TEXT_ALIGNMENT_RIGHT: - offset = rect.width() - textWidth; - break; - case SCI_TEXT_ALIGNMENT_CENTER: - offset = (rect.width() - textWidth) / 2; - break; - case SCI_TEXT_ALIGNMENT_LEFT: - offset = 0; - break; - - default: // left-aligned - warning("Invalid alignment %d used in TextBox()", alignment); - } - _gfx->MoveTo(rect.left + offset, rect.top + hline); - - if (bshow) { - Show(text, 0, charCount, orgFontId, orgPenColor); - } else { - Draw(text, 0, charCount, orgFontId, orgPenColor); - } - - hline += textHeight; - text += charCount; - } - SetFont(orgFontId); - _gfx->PenColor(orgPenColor); -} - -void SciGuiText::Draw_String(const char *text) { - GuiResourceId orgFontId = GetFontId(); - int16 orgPenColor = _gfx->_curPort->penClr; - - Draw(text, 0, strlen(text), orgFontId, orgPenColor); - SetFont(orgFontId); - _gfx->PenColor(orgPenColor); -} - -} // End of namespace Sci diff --git a/engines/sci/gui/gui_text.h b/engines/sci/gui/gui_text.h deleted file mode 100644 index 8002cdcf0c..0000000000 --- a/engines/sci/gui/gui_text.h +++ /dev/null @@ -1,83 +0,0 @@ -/* 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_TEXT_H -#define SCI_GUI_TEXT_H - -namespace Sci { - -#define SCI_TEXT_ALIGNMENT_RIGHT -1 -#define SCI_TEXT_ALIGNMENT_CENTER 1 -#define SCI_TEXT_ALIGNMENT_LEFT 0 - -class SciGuiGfx; -class SciGuiScreen; -class SciGuiFont; -class SciGuiText { -public: - SciGuiText(ResourceManager *_resMan, SciGuiGfx *gfx, SciGuiScreen *screen); - ~SciGuiText(); - - GuiResourceId GetFontId(); - SciGuiFont *GetFont(); - void SetFont(GuiResourceId fontId); - - void CodeSetFonts(int argc, reg_t *argv); - void CodeSetColors(int argc, reg_t *argv); - int16 CodeProcessing(const char *&text, GuiResourceId orgFontId, int16 orgPenColor); - - void ClearChar(int16 chr); - void DrawChar(int16 chr); - void StdChar(int16 chr); - - int16 GetLongest(const char *text, int16 maxWidth, GuiResourceId orgFontId); - void Width(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight); - void StringWidth(const char *str, GuiResourceId orgFontId, int16 &textWidth, int16 &textHeight); - void ShowString(const char *str, GuiResourceId orgFontId, int16 orgPenColor); - void DrawString(const char *str, GuiResourceId orgFontId, int16 orgPenColor); - int16 Size(Common::Rect &rect, const char *str, GuiResourceId fontId, int16 maxWidth); - void Draw(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 orgPenColor); - void Show(const char *text, int16 from, int16 len, GuiResourceId orgFontId, int16 orgPenColor); - void Box(const char *text, int16 bshow, const Common::Rect &rect, GuiTextAlignment alignment, GuiResourceId fontId); - void Draw_String(const char *text); - - SciGuiFont *_font; - -private: - void init(); - - ResourceManager *_resMan; - SciGuiGfx *_gfx; - SciGuiScreen *_screen; - - int _codeFontsCount; - GuiResourceId *_codeFonts; - int _codeColorsCount; - uint16 *_codeColors; -}; - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui/gui_transitions.cpp b/engines/sci/gui/gui_transitions.cpp deleted file mode 100644 index f4c6853bbe..0000000000 --- a/engines/sci/gui/gui_transitions.cpp +++ /dev/null @@ -1,576 +0,0 @@ -/* 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/events.h" -#include "common/util.h" -#include "common/stack.h" -#include "graphics/surface.h" - -#include "sci/sci.h" -#include "sci/engine/state.h" -#include "sci/gui/gui.h" -#include "sci/gui/gui_screen.h" -#include "sci/gui/gui_palette.h" -#include "sci/gui/gui_transitions.h" - -namespace Sci { - -SciGuiTransitions::SciGuiTransitions(SciGui *gui, SciGuiScreen *screen, SciGuiPalette *palette, bool isVGA) - : _gui(gui), _screen(screen), _palette(palette), _isVGA(isVGA) { - init(); -} - -SciGuiTransitions::~SciGuiTransitions() { - delete[] _oldScreen; -} - -// This table contains a mapping between oldIDs (prior SCI1LATE) and newIDs -static const GuiTransitionTranslateEntry oldTransitionIDs[] = { - { 0, SCI_TRANSITIONS_VERTICALROLL_FROMCENTER, false }, - { 1, SCI_TRANSITIONS_HORIZONTALROLL_FROMCENTER, false }, - { 2, SCI_TRANSITIONS_STRAIGHT_FROM_RIGHT, false }, - { 3, SCI_TRANSITIONS_STRAIGHT_FROM_LEFT, false }, - { 4, SCI_TRANSITIONS_STRAIGHT_FROM_BOTTOM, false }, - { 5, SCI_TRANSITIONS_STRAIGHT_FROM_TOP, false }, - { 6, SCI_TRANSITIONS_DIAGONALROLL_FROMCENTER, false }, - { 7, SCI_TRANSITIONS_DIAGONALROLL_TOCENTER, false }, - { 8, SCI_TRANSITIONS_BLOCKS, false }, - { 9, SCI_TRANSITIONS_VERTICALROLL_TOCENTER, false }, - { 10, SCI_TRANSITIONS_HORIZONTALROLL_TOCENTER, false }, - { 11, SCI_TRANSITIONS_STRAIGHT_FROM_RIGHT, true }, - { 12, SCI_TRANSITIONS_STRAIGHT_FROM_LEFT, true }, - { 13, SCI_TRANSITIONS_STRAIGHT_FROM_BOTTOM, true }, - { 14, SCI_TRANSITIONS_STRAIGHT_FROM_TOP, true }, - { 15, SCI_TRANSITIONS_DIAGONALROLL_FROMCENTER, true }, - { 16, SCI_TRANSITIONS_DIAGONALROLL_TOCENTER, true }, - { 17, SCI_TRANSITIONS_BLOCKS, true }, - { 18, SCI_TRANSITIONS_PIXELATION, false }, - { 27, SCI_TRANSITIONS_PIXELATION , true }, - { 30, SCI_TRANSITIONS_FADEPALETTE, false }, - { 40, SCI_TRANSITIONS_SCROLL_RIGHT, false }, - { 41, SCI_TRANSITIONS_SCROLL_LEFT, false }, - { 42, SCI_TRANSITIONS_SCROLL_UP, false }, - { 43, SCI_TRANSITIONS_SCROLL_DOWN, false }, - { 100, SCI_TRANSITIONS_NONE, false }, - { 255, 255, false } -}; - -// this table defines the blackout-transition that needs to be done prior doing the actual transition -static const GuiTransitionTranslateEntry blackoutTransitionIDs[] = { - { SCI_TRANSITIONS_VERTICALROLL_FROMCENTER, SCI_TRANSITIONS_VERTICALROLL_TOCENTER, true }, - { SCI_TRANSITIONS_HORIZONTALROLL_FROMCENTER, SCI_TRANSITIONS_HORIZONTALROLL_TOCENTER, true }, - { SCI_TRANSITIONS_STRAIGHT_FROM_RIGHT, SCI_TRANSITIONS_STRAIGHT_FROM_LEFT, true }, - { SCI_TRANSITIONS_STRAIGHT_FROM_LEFT, SCI_TRANSITIONS_STRAIGHT_FROM_RIGHT, true }, - { SCI_TRANSITIONS_STRAIGHT_FROM_BOTTOM, SCI_TRANSITIONS_STRAIGHT_FROM_TOP, true }, - { SCI_TRANSITIONS_STRAIGHT_FROM_TOP, SCI_TRANSITIONS_STRAIGHT_FROM_BOTTOM, true }, - { SCI_TRANSITIONS_DIAGONALROLL_FROMCENTER, SCI_TRANSITIONS_DIAGONALROLL_TOCENTER, true }, - { SCI_TRANSITIONS_DIAGONALROLL_TOCENTER, SCI_TRANSITIONS_DIAGONALROLL_FROMCENTER, true }, - { SCI_TRANSITIONS_BLOCKS, SCI_TRANSITIONS_BLOCKS, true }, - { SCI_TRANSITIONS_PIXELATION, SCI_TRANSITIONS_PIXELATION, true }, - { SCI_TRANSITIONS_FADEPALETTE, SCI_TRANSITIONS_NONE, true }, - { SCI_TRANSITIONS_SCROLL_RIGHT, SCI_TRANSITIONS_NONE, true }, - { SCI_TRANSITIONS_SCROLL_LEFT, SCI_TRANSITIONS_NONE, true }, - { SCI_TRANSITIONS_SCROLL_UP, SCI_TRANSITIONS_NONE, true }, - { SCI_TRANSITIONS_SCROLL_DOWN, SCI_TRANSITIONS_NONE, true }, - { SCI_TRANSITIONS_NONE_LONGBOW, SCI_TRANSITIONS_NONE, true }, - { SCI_TRANSITIONS_NONE, SCI_TRANSITIONS_NONE, true }, - { SCI_TRANSITIONS_VERTICALROLL_TOCENTER, SCI_TRANSITIONS_NONE, true }, - { SCI_TRANSITIONS_HORIZONTALROLL_TOCENTER, SCI_TRANSITIONS_NONE, true }, - { 255, 255, true } -}; - -void SciGuiTransitions::init() { - _oldScreen = new byte[_screen->_displayHeight * _screen->_displayWidth]; - - if (getSciVersion() >= SCI_VERSION_1_LATE) - _translationTable = NULL; - else - _translationTable = oldTransitionIDs; - - // setup default transition - _number = SCI_TRANSITIONS_HORIZONTALROLL_FROMCENTER; - _blackoutFlag = false; -} - -void SciGuiTransitions::setup(int16 number, bool blackoutFlag) { - if (number != -1) { - _number = number; - _blackoutFlag = blackoutFlag; - } -} - -void SciGuiTransitions::updateScreenAndWait(int msec) { - Common::Event ev; - g_system->updateScreen(); - g_system->delayMillis(msec); - while (g_system->getEventManager()->pollEvent(ev)) {} // discard all events -} - -// will translate a number and return corresponding translationEntry -const GuiTransitionTranslateEntry *SciGuiTransitions::translateNumber (int16 number, const GuiTransitionTranslateEntry *tablePtr) { - while (1) { - if (tablePtr->orgId == 255) - return NULL; - if (tablePtr->orgId == number) - return tablePtr; - tablePtr++; - } -} - -void SciGuiTransitions::doit(Common::Rect picRect) { - const GuiTransitionTranslateEntry *translationEntry = _translationTable; - - _picRect = picRect; - - if (_translationTable) { - // We need to translate the ID - translationEntry = translateNumber(_number, _translationTable); - if (translationEntry) { - _number = translationEntry->newId; - _blackoutFlag = translationEntry->blackoutFlag; - } else { - warning("SciGuiTransitions: old ID %d not supported", _number); - _number = SCI_TRANSITIONS_NONE; - _blackoutFlag = false; - } - } - - if (_blackoutFlag) { - // We need to find out what transition we are supposed to use for blackout - translationEntry = translateNumber(_number, blackoutTransitionIDs); - if (translationEntry) { - doTransition(translationEntry->newId, true); - } else { - warning("SciGuiTransitions: ID %d not listed in blackoutTransitionIDs", _number); - } - } - - // Now we do the actual transition to the new screen - doTransition(_number, false); - - if (picRect.bottom != 320) { - // TODO: this is a workaround for lsl6 not showing menubar when playing - // There is some new code in the sierra sci in ShowPic that seems to do something similar to this - _screen->copyToScreen(); - g_system->updateScreen(); - } - - _screen->_picNotValid = 0; -} - -// This may get called twice, if blackoutFlag is set. It will get once called with blackoutFlag set and another time -// with no blackoutFlag. -void SciGuiTransitions::doTransition(int16 number, bool blackoutFlag) { - if (number != SCI_TRANSITIONS_FADEPALETTE) { - setNewPalette(blackoutFlag); - } - - switch (number) { - case SCI_TRANSITIONS_VERTICALROLL_FROMCENTER: - verticalRollFromCenter(blackoutFlag); - break; - case SCI_TRANSITIONS_VERTICALROLL_TOCENTER: - verticalRollFromCenter(blackoutFlag); - break; - case SCI_TRANSITIONS_HORIZONTALROLL_FROMCENTER: - horizontalRollFromCenter(blackoutFlag); - break; - case SCI_TRANSITIONS_HORIZONTALROLL_TOCENTER: - horizontalRollToCenter(blackoutFlag); - break; - case SCI_TRANSITIONS_DIAGONALROLL_TOCENTER: - diagonalRollToCenter(blackoutFlag); - break; - case SCI_TRANSITIONS_DIAGONALROLL_FROMCENTER: - diagonalRollFromCenter(blackoutFlag); - break; - - case SCI_TRANSITIONS_STRAIGHT_FROM_RIGHT: - case SCI_TRANSITIONS_STRAIGHT_FROM_LEFT: - case SCI_TRANSITIONS_STRAIGHT_FROM_BOTTOM: - case SCI_TRANSITIONS_STRAIGHT_FROM_TOP: - straight(number, blackoutFlag); - break; - - case SCI_TRANSITIONS_PIXELATION: - pixelation(blackoutFlag); - break; - - case SCI_TRANSITIONS_BLOCKS: - blocks(blackoutFlag); - break; - - case SCI_TRANSITIONS_FADEPALETTE: - if (!blackoutFlag) { - fadeOut(); setNewScreen(blackoutFlag); fadeIn(); - } - break; - - case SCI_TRANSITIONS_SCROLL_RIGHT: - case SCI_TRANSITIONS_SCROLL_LEFT: - case SCI_TRANSITIONS_SCROLL_UP: - case SCI_TRANSITIONS_SCROLL_DOWN: - scroll(number); - break; - - case SCI_TRANSITIONS_NONE_LONGBOW: - case SCI_TRANSITIONS_NONE: - setNewScreen(blackoutFlag); - break; - - default: - warning("SciGuiTransitions: ID %d not implemented", number); - setNewScreen(blackoutFlag); - } -} - -void SciGuiTransitions::setNewPalette(bool blackoutFlag) { - if (!blackoutFlag) - if (_isVGA) - _palette->setOnScreen(); -} - -void SciGuiTransitions::setNewScreen(bool blackoutFlag) { - if (!blackoutFlag) { - _screen->copyRectToScreen(_picRect); - g_system->updateScreen(); - } -} - -void SciGuiTransitions::copyRectToScreen(const Common::Rect rect, bool blackoutFlag) { - if (!blackoutFlag) { - _screen->copyRectToScreen(rect); - } else { - Graphics::Surface *surface = g_system->lockScreen(); - surface->fillRect(rect, 0); - g_system->unlockScreen(); - } -} - -// Note: dont do too many steps in here, otherwise cpu will crap out because of the load -void SciGuiTransitions::fadeOut() { - byte oldPalette[4 * 256], workPalette[4 * 256]; - int16 stepNr, colorNr; - - g_system->grabPalette(oldPalette, 0, 256); - - for (stepNr = 100; stepNr >= 0; stepNr -= 10) { - for (colorNr = 1; colorNr < 255; colorNr++){ - workPalette[colorNr * 4 + 0] = oldPalette[colorNr * 4] * stepNr / 100; - workPalette[colorNr * 4 + 1] = oldPalette[colorNr * 4 + 1] * stepNr / 100; - workPalette[colorNr * 4 + 2] = oldPalette[colorNr * 4 + 2] * stepNr / 100; - } - g_system->setPalette(workPalette + 4, 1, 254); - _gui->wait(2); - } -} - -// Note: dont do too many steps in here, otherwise cpu will crap out because of the load -void SciGuiTransitions::fadeIn() { - int16 stepNr; - - for (stepNr = 0; stepNr <= 100; stepNr += 10) { - _palette->setIntensity(1, 255, stepNr, true); - _gui->wait(2); - } -} - -// pixelates the new picture over the old one - works against the whole screen -// TODO: it seems this needs to get applied on _picRect only if possible -void SciGuiTransitions::pixelation (bool blackoutFlag) { - uint16 mask = 0x40, stepNr = 0; - Common::Rect pixelRect; - - do { - mask = (mask & 1) ? (mask >> 1) ^ 0xB400 : mask >> 1; - if (mask >= 320 * 200) - continue; - pixelRect.left = mask % 320; pixelRect.right = pixelRect.left + 1; - pixelRect.top = mask / 320; pixelRect.bottom = pixelRect.top + 1; - pixelRect.clip(_picRect); - if (!pixelRect.isEmpty()) - copyRectToScreen(pixelRect, blackoutFlag); - if ((stepNr & 0x3FF) == 0) { - updateScreenAndWait(5); - } - stepNr++; - } while (mask != 0x40); -} - -// like pixelation but uses 8x8 blocks - works against the whole screen -// TODO: it seems this needs to get applied on _picRect only if possible -void SciGuiTransitions::blocks(bool blackoutFlag) { - uint16 mask = 0x40, stepNr = 0; - Common::Rect blockRect; - - do { - mask = (mask & 1) ? (mask >> 1) ^ 0x240 : mask >> 1; - if (mask >= 40 * 25) - continue; - blockRect.left = (mask % 40) << 3; blockRect.right = blockRect.left + 8; - blockRect.top = (mask / 40) << 3; blockRect.bottom = blockRect.top + 8; - blockRect.clip(_picRect); - if (!blockRect.isEmpty()) - copyRectToScreen(blockRect, blackoutFlag); - if ((stepNr & 7) == 0) { - updateScreenAndWait(4); - } - stepNr++; - } while (mask != 0x40); -} - -// directly shows new screen starting up/down/left/right and going to the opposite direction - works on _picRect area only -void SciGuiTransitions::straight(int16 number, bool blackoutFlag) { - int16 stepNr = 0; - Common::Rect newScreenRect = _picRect; - - switch (number) { - case SCI_TRANSITIONS_STRAIGHT_FROM_RIGHT: - newScreenRect.left = newScreenRect.right - 1; - while (newScreenRect.left >= _picRect.left) { - copyRectToScreen(newScreenRect, blackoutFlag); - if ((stepNr & 1) == 0) { - updateScreenAndWait(1); - } - stepNr++; - newScreenRect.translate(-1, 0); - } - break; - - case SCI_TRANSITIONS_STRAIGHT_FROM_LEFT: - newScreenRect.right = newScreenRect.left + 1; - while (newScreenRect.right <= _picRect.right) { - copyRectToScreen(newScreenRect, blackoutFlag); - if ((stepNr & 1) == 0) { - updateScreenAndWait(1); - } - stepNr++; - newScreenRect.translate(1, 0); - } - break; - - case SCI_TRANSITIONS_STRAIGHT_FROM_BOTTOM: - newScreenRect.top = newScreenRect.bottom - 1; - while (newScreenRect.top >= _picRect.top) { - copyRectToScreen(newScreenRect, blackoutFlag); - updateScreenAndWait(3); - stepNr++; - newScreenRect.translate(0, -1); - } - break; - - case SCI_TRANSITIONS_STRAIGHT_FROM_TOP: - newScreenRect.bottom = newScreenRect.top + 1; - while (newScreenRect.bottom <= _picRect.bottom) { - copyRectToScreen(newScreenRect, blackoutFlag); - updateScreenAndWait(3); - stepNr++; - newScreenRect.translate(0, 1); - } - break; - } -} - -// scroll old screen (up/down/left/right) and insert new screen that way - works on _picRect area only -void SciGuiTransitions::scroll(int16 number) { - int16 screenWidth, screenHeight; - byte *oldScreenPtr; - int16 stepNr = 0; - Common::Rect oldMoveRect = _picRect; - Common::Rect newMoveRect = _picRect; - Common::Rect newScreenRect = _picRect; - - _screen->copyFromScreen(_oldScreen); - screenWidth = _screen->_displayWidth; screenHeight = _screen->_displayHeight; - - oldScreenPtr = _oldScreen + _picRect.left + _picRect.top * screenWidth; - - switch (number) { - case SCI_TRANSITIONS_SCROLL_LEFT: - newScreenRect.right = newScreenRect.left; - newMoveRect.left = newMoveRect.right; - while (oldMoveRect.left < oldMoveRect.right) { - oldScreenPtr++; oldMoveRect.right--; - if (oldMoveRect.right > oldMoveRect.left) - g_system->copyRectToScreen(oldScreenPtr, screenWidth, oldMoveRect.left, oldMoveRect.top, oldMoveRect.width(), oldMoveRect.height()); - newScreenRect.right++; newMoveRect.left--; - _screen->copyRectToScreen(newScreenRect, newMoveRect.left, newMoveRect.top); - if ((stepNr & 1) == 0) { - updateScreenAndWait(1); - } - stepNr++; - } - if ((stepNr & 1) == 0) - g_system->updateScreen(); - break; - - case SCI_TRANSITIONS_SCROLL_RIGHT: - newScreenRect.left = newScreenRect.right; - while (oldMoveRect.left < oldMoveRect.right) { - oldMoveRect.left++; - if (oldMoveRect.right > oldMoveRect.left) - g_system->copyRectToScreen(oldScreenPtr, screenWidth, oldMoveRect.left, oldMoveRect.top, oldMoveRect.width(), oldMoveRect.height()); - newScreenRect.left--; - _screen->copyRectToScreen(newScreenRect, newMoveRect.left, newMoveRect.top); - if ((stepNr & 1) == 0) { - updateScreenAndWait(1); - } - stepNr++; - } - if ((stepNr & 1) == 0) - g_system->updateScreen(); - break; - - case SCI_TRANSITIONS_SCROLL_UP: - newScreenRect.bottom = newScreenRect.top; - newMoveRect.top = newMoveRect.bottom; - while (oldMoveRect.top < oldMoveRect.bottom) { - oldScreenPtr += screenWidth; oldMoveRect.top++; - if (oldMoveRect.top < oldMoveRect.bottom) - g_system->copyRectToScreen(oldScreenPtr, screenWidth, _picRect.left, _picRect.top, oldMoveRect.width(), oldMoveRect.height()); - newScreenRect.bottom++; newMoveRect.top--; - _screen->copyRectToScreen(newScreenRect, newMoveRect.left, newMoveRect.top); - updateScreenAndWait(3); - } - break; - - case SCI_TRANSITIONS_SCROLL_DOWN: - newScreenRect.top = newScreenRect.bottom; - while (oldMoveRect.top < oldMoveRect.bottom) { - oldMoveRect.top++; - if (oldMoveRect.top < oldMoveRect.bottom) - g_system->copyRectToScreen(oldScreenPtr, screenWidth, oldMoveRect.left, oldMoveRect.top, oldMoveRect.width(), oldMoveRect.height()); - newScreenRect.top--; - _screen->copyRectToScreen(newScreenRect, _picRect.left, _picRect.top); - updateScreenAndWait(3); - } - break; - } -} - -// vertically displays new screen starting from center - works on _picRect area only -void SciGuiTransitions::verticalRollFromCenter(bool blackoutFlag) { - Common::Rect leftRect = Common::Rect(_picRect.left + (_picRect.width() / 2) -1, _picRect.top, _picRect.left + (_picRect.width() / 2), _picRect.bottom); - Common::Rect rightRect = Common::Rect(leftRect.right, _picRect.top, leftRect.right + 1, _picRect.bottom); - - while ((leftRect.left >= _picRect.left) || (rightRect.right <= _picRect.right)) { - if (leftRect.left < _picRect.left) - leftRect.translate(1, 0); - if (rightRect.right > _picRect.right) - rightRect.translate(-1, 0); - copyRectToScreen(leftRect, blackoutFlag); leftRect.translate(-1, 0); - copyRectToScreen(rightRect, blackoutFlag); rightRect.translate(1, 0); - updateScreenAndWait(2); - } -} - -// vertically displays new screen starting from edges - works on _picRect area only -void SciGuiTransitions::verticalRollToCenter(bool blackoutFlag) { - Common::Rect leftRect = Common::Rect(_picRect.left, _picRect.top, _picRect.left + 1, _picRect.bottom); - Common::Rect rightRect = Common::Rect(leftRect.right - 1, _picRect.top, leftRect.right, _picRect.bottom); - - while (leftRect.left < rightRect.right) { - copyRectToScreen(leftRect, blackoutFlag); leftRect.translate(1, 0); - copyRectToScreen(rightRect, blackoutFlag); rightRect.translate(-1, 0); - updateScreenAndWait(2); - } -} - -// horizontally displays new screen starting from center - works on _picRect area only -void SciGuiTransitions::horizontalRollFromCenter(bool blackoutFlag) { - Common::Rect upperRect = Common::Rect(_picRect.left, _picRect.top + (_picRect.height() / 2) - 1, _picRect.right, _picRect.top + (_picRect.height() / 2)); - Common::Rect lowerRect = Common::Rect(upperRect.left, upperRect.bottom, upperRect.right, upperRect.bottom + 1); - - while ((upperRect.top >= _picRect.top) || (lowerRect.bottom <= _picRect.bottom)) { - if (upperRect.top < _picRect.top) - upperRect.translate(0, 1); - if (lowerRect.bottom > _picRect.bottom) - lowerRect.translate(0, -1); - copyRectToScreen(upperRect, blackoutFlag); upperRect.translate(0, -1); - copyRectToScreen(lowerRect, blackoutFlag); lowerRect.translate(0, 1); - updateScreenAndWait(3); - } -} - -// horizontally displays new screen starting from upper and lower edge - works on _picRect area only -void SciGuiTransitions::horizontalRollToCenter(bool blackoutFlag) { - Common::Rect upperRect = Common::Rect(_picRect.left, _picRect.top, _picRect.right, _picRect.top + 1); - Common::Rect lowerRect = Common::Rect(upperRect.left, _picRect.bottom - 1, upperRect.right, _picRect.bottom); - - while (upperRect.top < lowerRect.bottom) { - copyRectToScreen(upperRect, blackoutFlag); upperRect.translate(0, 1); - copyRectToScreen(lowerRect, blackoutFlag); lowerRect.translate(0, -1); - updateScreenAndWait(3); - } -} - -// diagonally displays new screen starting from center - works on _picRect area only -// assumes that height of rect is larger than width -void SciGuiTransitions::diagonalRollFromCenter(bool blackoutFlag) { - int16 halfHeight = _picRect.height() / 2; - Common::Rect upperRect(_picRect.left + halfHeight - 2, _picRect.top + halfHeight, _picRect.right - halfHeight + 1, _picRect.top + halfHeight + 1); - Common::Rect lowerRect(upperRect.left, upperRect.top, upperRect.right, upperRect.bottom); - Common::Rect leftRect(upperRect.left, upperRect.top, upperRect.left + 1, lowerRect.bottom); - Common::Rect rightRect(upperRect.right, upperRect.top, upperRect.right + 1, lowerRect.bottom); - - while ((upperRect.top >= _picRect.top) || (lowerRect.bottom <= _picRect.bottom)) { - if (upperRect.top < _picRect.top) { - upperRect.translate(0, 1); leftRect.top++; rightRect.top++; - } - if (lowerRect.bottom > _picRect.bottom) { - lowerRect.translate(0, -1); leftRect.bottom--; rightRect.bottom--; - } - if (leftRect.left < _picRect.left) { - leftRect.translate(1, 0); upperRect.left++; lowerRect.left++; - } - if (rightRect.right > _picRect.right) { - rightRect.translate(-1, 0); upperRect.right--; lowerRect.right--; - } - copyRectToScreen(upperRect, blackoutFlag); upperRect.translate(0, -1); upperRect.left--; upperRect.right++; - copyRectToScreen(lowerRect, blackoutFlag); lowerRect.translate(0, 1); lowerRect.left--; lowerRect.right++; - copyRectToScreen(leftRect, blackoutFlag); leftRect.translate(-1, 0); leftRect.top--; leftRect.bottom++; - copyRectToScreen(rightRect, blackoutFlag); rightRect.translate(1, 0); rightRect.top--; rightRect.bottom++; - updateScreenAndWait(3); - } -} - -// diagonally displays new screen starting from edges - works on _picRect area only -// assumes that height of rect is larger than width -void SciGuiTransitions::diagonalRollToCenter(bool blackoutFlag) { - Common::Rect upperRect(_picRect.left, _picRect.top, _picRect.right, _picRect.top + 1); - Common::Rect lowerRect(_picRect.left, _picRect.bottom - 1, _picRect.right, _picRect.bottom); - Common::Rect leftRect(_picRect.left, _picRect.top, _picRect.left + 1, _picRect.bottom); - Common::Rect rightRect(_picRect.right - 1, _picRect.top, _picRect.right, _picRect.bottom); - - while (upperRect.top < lowerRect.bottom) { - copyRectToScreen(upperRect, blackoutFlag); upperRect.translate(0, 1); upperRect.left++; upperRect.right--; - copyRectToScreen(lowerRect, blackoutFlag); lowerRect.translate(0, -1); lowerRect.left++; lowerRect.right--; - copyRectToScreen(leftRect, blackoutFlag); leftRect.translate(1, 0); - copyRectToScreen(rightRect, blackoutFlag); rightRect.translate(-1, 0); - updateScreenAndWait(3); - } -} - -} // End of namespace Sci diff --git a/engines/sci/gui/gui_transitions.h b/engines/sci/gui/gui_transitions.h deleted file mode 100644 index b20e22fa5b..0000000000 --- a/engines/sci/gui/gui_transitions.h +++ /dev/null @@ -1,106 +0,0 @@ -/* 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_TRANSITIONS_H -#define SCI_GUI_TRANSITIONS_H - -#include "sci/gui/gui_helpers.h" - -namespace Sci { - -struct GuiTransitionTranslateEntry { - int16 orgId; - int16 newId; - bool blackoutFlag; -}; - -enum { - SCI_TRANSITIONS_VERTICALROLL_FROMCENTER = 0, - SCI_TRANSITIONS_HORIZONTALROLL_FROMCENTER = 1, - SCI_TRANSITIONS_STRAIGHT_FROM_RIGHT = 2, - SCI_TRANSITIONS_STRAIGHT_FROM_LEFT = 3, - SCI_TRANSITIONS_STRAIGHT_FROM_BOTTOM = 4, - SCI_TRANSITIONS_STRAIGHT_FROM_TOP = 5, - SCI_TRANSITIONS_DIAGONALROLL_FROMCENTER = 6, - SCI_TRANSITIONS_DIAGONALROLL_TOCENTER = 7, - SCI_TRANSITIONS_BLOCKS = 8, - SCI_TRANSITIONS_PIXELATION = 9, - SCI_TRANSITIONS_FADEPALETTE = 10, - SCI_TRANSITIONS_SCROLL_RIGHT = 11, - SCI_TRANSITIONS_SCROLL_LEFT = 12, - SCI_TRANSITIONS_SCROLL_UP = 13, - SCI_TRANSITIONS_SCROLL_DOWN = 14, - SCI_TRANSITIONS_NONE_LONGBOW = 15, - SCI_TRANSITIONS_NONE = 100, - // here are transitions that are used by the old tableset, but are not included anymore in the new tableset - SCI_TRANSITIONS_VERTICALROLL_TOCENTER = 300, - SCI_TRANSITIONS_HORIZONTALROLL_TOCENTER = 301 -}; - -class SciGuiScreen; -class SciGuiTransitions { -public: - SciGuiTransitions(SciGui *gui, SciGuiScreen *screen, SciGuiPalette *palette, bool isVGA); - ~SciGuiTransitions(); - - void setup(int16 number, bool blackoutFlag); - void doit(Common::Rect picRect); - -private: - void init(); - const GuiTransitionTranslateEntry *translateNumber(int16 number, const GuiTransitionTranslateEntry *tablePtr); - void doTransition(int16 number, bool blackout); - void setNewPalette(bool blackoutFlag); - void setNewScreen(bool blackoutFlag); - void copyRectToScreen(const Common::Rect rect, bool blackoutFlag); - void fadeOut(); - void fadeIn(); - void pixelation(bool blackoutFlag); - void blocks(bool blackoutFlag); - void straight(int16 number, bool blackoutFlag); - void scroll(int16 number); - void verticalRollFromCenter(bool blackoutFlag); - void verticalRollToCenter(bool blackoutFlag); - void horizontalRollFromCenter(bool blackoutFlag); - void horizontalRollToCenter(bool blackoutFlag); - void diagonalRollFromCenter(bool blackoutFlag); - void diagonalRollToCenter(bool blackoutFlag); - void updateScreenAndWait(int msec); - - SciGui *_gui; - SciGuiScreen *_screen; - SciGuiPalette *_palette; - - bool _isVGA; - const GuiTransitionTranslateEntry *_translationTable; - int16 _number; - bool _blackoutFlag; - Common::Rect _picRect; - byte *_oldScreen; // buffer for saving current active screen data to, has dimenions of _screen->_displayScreen -}; - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui/gui_view.cpp b/engines/sci/gui/gui_view.cpp deleted file mode 100644 index 3442f32eb8..0000000000 --- a/engines/sci/gui/gui_view.cpp +++ /dev/null @@ -1,513 +0,0 @@ -/* 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 "sci/sci.h" -#include "sci/engine/state.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, SciGuiPalette *palette, GuiResourceId resourceId) - : _resMan(resMan), _screen(screen), _palette(palette), _resourceId(resourceId) { - assert(resourceId != -1); - initData(resourceId); -} - -SciGuiView::~SciGuiView() { - // Iterate through the loops - for (uint16 loopNum = 0; loopNum < _loopCount; loopNum++) { - // and through the cells of each loop - for (uint16 celNum = 0; celNum < _loop[loopNum].celCount; celNum++) { - delete[] _loop[loopNum].cel[celNum].rawBitmap; - } - delete[] _loop[loopNum].cel; - } - delete[] _loop; - - _resMan->unlockResource(_resource); -} - -static const byte EGAmappingStraight[SCI_VIEW_EGAMAPPING_SIZE] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 -}; - -void SciGuiView::initData(GuiResourceId resourceId) { - _resource = _resMan->findResource(ResourceId(kResourceTypeView, resourceId), true); - if (!_resource) { - error("view resource %d not found", resourceId); - } - _resourceData = _resource->data; - - byte *celData, *loopData; - uint16 celOffset; - sciViewCelInfo *cel; - uint16 celCount = 0; - uint16 mirrorBits = 0; - uint16 palOffset = 0; - uint16 headerSize = 0; - uint16 loopSize = 0, celSize = 0; - int loopNo, celNo, EGAmapNr; - byte seekEntry; - bool isEGA = false; - bool isCompressed = true; - - _loopCount = 0; - _embeddedPal = false; - _EGAmapping = NULL; - - switch (_resMan->getViewType()) { - case kViewEga: // View-format SCI0 (and Amiga 16 colors) - isEGA = true; - case kViewAmiga: // View-format Amiga (32 colors) - case kViewVga: // View-format SCI1 - // LoopCount:WORD MirrorMask:WORD Version:WORD PaletteOffset:WORD LoopOffset0:WORD LoopOffset1:WORD... - - _loopCount = _resourceData[0]; - // bit 0x8000 of _resourceData[1] means palette is set - if (_resourceData[1] & 0x40) - isCompressed = false; - mirrorBits = READ_LE_UINT16(_resourceData + 2); - palOffset = READ_LE_UINT16(_resourceData + 6); - - if (palOffset && palOffset != 0x100) { - // Some SCI0/SCI01 games also have an offset set. It seems that it points to a 16-byte mapping table - // but on those games using that mapping will actually screw things up. - // On the other side: vga sci1 games have this pointing to a VGA palette - // and ega sci1 games have this pointing to a 8x16 byte mapping table that needs to get applied then - if (!isEGA) { - _palette->createFromData(&_resourceData[palOffset], &_viewPalette); - _embeddedPal = true; - } else { - // Only use the EGA-mapping, when being SCI1 - if (getSciVersion() >= SCI_VERSION_1_EGA) { - _EGAmapping = &_resourceData[palOffset]; - for (EGAmapNr = 0; EGAmapNr < SCI_VIEW_EGAMAPPING_COUNT; EGAmapNr++) { - if (memcmp(_EGAmapping, EGAmappingStraight, SCI_VIEW_EGAMAPPING_SIZE)!=0) - break; - _EGAmapping += SCI_VIEW_EGAMAPPING_SIZE; - } - // If all mappings are "straight", then we actually ignore the mapping - if (EGAmapNr == SCI_VIEW_EGAMAPPING_COUNT) - _EGAmapping = NULL; - else - _EGAmapping = &_resourceData[palOffset]; - } - } - } - - _loop = new sciViewLoopInfo[_loopCount]; - for (loopNo = 0; loopNo < _loopCount; loopNo++) { - loopData = _resourceData + READ_LE_UINT16(_resourceData + 8 + loopNo * 2); - // CelCount:WORD Unknown:WORD CelOffset0:WORD CelOffset1:WORD... - - celCount = READ_LE_UINT16(loopData); - _loop[loopNo].celCount = celCount; - _loop[loopNo].mirrorFlag = mirrorBits & 1 ? true : false; - mirrorBits >>= 1; - - // read cel info - _loop[loopNo].cel = new sciViewCelInfo[celCount]; - for (celNo = 0; celNo < celCount; celNo++) { - celOffset = READ_LE_UINT16(loopData + 4 + celNo * 2); - celData = _resourceData + celOffset; - - // For VGA - // Width:WORD Height:WORD DisplaceX:BYTE DisplaceY:BYTE ClearKey:BYTE Unknown:BYTE RLEData starts now directly - // For EGA - // Width:WORD Height:WORD DisplaceX:BYTE DisplaceY:BYTE ClearKey:BYTE EGAData starts now directly - cel = &_loop[loopNo].cel[celNo]; - cel->width = READ_LE_UINT16(celData); - cel->height = READ_LE_UINT16(celData + 2); - cel->displaceX = celData[4]; - cel->displaceY = celData[5]; - cel->clearKey = celData[6]; - if (isEGA) { - cel->offsetEGA = celOffset + 7; - cel->offsetRLE = 0; - cel->offsetLiteral = 0; - } else { - cel->offsetEGA = 0; - if (isCompressed) { - cel->offsetRLE = celOffset + 8; - cel->offsetLiteral = 0; - } else { - cel->offsetRLE = 0; - cel->offsetLiteral = celOffset + 8; - } - } - cel->rawBitmap = 0; - if (_loop[loopNo].mirrorFlag) - cel->displaceX = -cel->displaceX; - } - } - break; - - case kViewVga11: // View-format SCI1.1 - // LoopCount:WORD MirrorMask:WORD Version:WORD PaletteOffset:WORD LoopOffset0:WORD LoopOffset1:WORD... - // HeaderSize:WORD LoopCount:BYTE Unknown:BYTE Version:WORD Unknown:WORD PaletteOffset:WORD - headerSize = READ_LE_UINT16(_resourceData + 0); - _loopCount = _resourceData[2]; - palOffset = READ_LE_UINT16(_resourceData + 8); - // FIXME: After LoopCount there is another byte and its set for view 50 within Laura Bow 2 CD, check what it means - - loopData = _resourceData + headerSize; - loopSize = _resourceData[12]; - celSize = _resourceData[13]; - - if (palOffset) { - _palette->createFromData(&_resourceData[palOffset], &_viewPalette); - _embeddedPal = true; - } - - _loop = new sciViewLoopInfo[_loopCount]; - for (loopNo = 0; loopNo < _loopCount; loopNo++) { - loopData = _resourceData + headerSize + (loopNo * loopSize); - - seekEntry = loopData[2]; - if (seekEntry != 255) { - if (seekEntry >= _loopCount) - error("Bad loop-pointer in sci 1.1 view"); - _loop[loopNo].mirrorFlag = true; - loopData = _resourceData + headerSize + (seekEntry * loopSize); - } else { - _loop[loopNo].mirrorFlag = false; - } - - celCount = loopData[4]; - _loop[loopNo].celCount = celCount; - - celData = _resourceData + READ_LE_UINT16(loopData + 14); - - // read cel info - _loop[loopNo].cel = new sciViewCelInfo[celCount]; - for (celNo = 0; celNo < celCount; celNo++) { - cel = &_loop[loopNo].cel[celNo]; - cel->width = READ_LE_UINT16(celData); - cel->height = READ_LE_UINT16(celData + 2); - cel->displaceX = READ_LE_UINT16(celData + 4); - cel->displaceY = READ_LE_UINT16(celData + 6); - cel->clearKey = celData[8]; - cel->offsetEGA = 0; - cel->offsetRLE = READ_LE_UINT16(celData + 24); - cel->offsetLiteral = READ_LE_UINT16(celData + 28); - cel->rawBitmap = 0; - if (_loop[loopNo].mirrorFlag) - cel->displaceX = -cel->displaceX; - - celData += celSize; - } - } - break; - - default: - error("ViewType was not detected, can't continue"); - } -} - -GuiResourceId SciGuiView::getResourceId() { - return _resourceId; -} - -int16 SciGuiView::getWidth(GuiViewLoopNo loopNo, GuiViewCelNo celNo) { - loopNo = CLIP(loopNo, 0, _loopCount - 1); - celNo = CLIP(celNo, 0, _loop[loopNo].celCount - 1); - return _loopCount ? _loop[loopNo].cel[celNo].width : 0; -} - -int16 SciGuiView::getHeight(GuiViewLoopNo loopNo, GuiViewCelNo celNo) { - loopNo = CLIP(loopNo, 0, _loopCount -1); - celNo = CLIP(celNo, 0, _loop[loopNo].celCount - 1); - return _loopCount ? _loop[loopNo].cel[celNo].height : 0; -} - -sciViewCelInfo *SciGuiView::getCelInfo(GuiViewLoopNo loopNo, GuiViewCelNo celNo) { - loopNo = CLIP(loopNo, 0, _loopCount - 1); - celNo = CLIP(celNo, 0, _loop[loopNo].celCount - 1); - return _loopCount ? &_loop[loopNo].cel[celNo] : NULL; -} - -sciViewLoopInfo *SciGuiView::getLoopInfo(GuiViewLoopNo loopNo) { - loopNo = CLIP(loopNo, 0, _loopCount - 1); - return _loopCount ? &_loop[loopNo] : NULL; -} - -void SciGuiView::getCelRect(GuiViewLoopNo loopNo, GuiViewCelNo celNo, int16 x, int16 y, int16 z, Common::Rect *outRect) { - sciViewCelInfo *celInfo = getCelInfo(loopNo, celNo); - if (celInfo) { - outRect->left = x + celInfo->displaceX - (celInfo->width >> 1); - outRect->right = outRect->left + celInfo->width; - outRect->bottom = y + celInfo->displaceY - z + 1; - outRect->top = outRect->bottom - celInfo->height; - } -} - -void SciGuiView::unpackCel(GuiViewLoopNo loopNo, GuiViewCelNo celNo, byte *outPtr, uint16 pixelCount) { - sciViewCelInfo *celInfo = getCelInfo(loopNo, celNo); - byte *rlePtr; - byte *literalPtr; - uint16 pixelNo = 0, runLength; - byte pixel; - - if (celInfo->offsetEGA) { - // decompression for EGA views - literalPtr = _resourceData + _loop[loopNo].cel[celNo].offsetEGA; - while (pixelNo < pixelCount) { - pixel = *literalPtr++; - runLength = pixel >> 4; - memset(outPtr + pixelNo, pixel & 0x0F, MIN(runLength, pixelCount - pixelNo)); - pixelNo += runLength; - } - return; - } - - rlePtr = _resourceData + celInfo->offsetRLE; - if (!celInfo->offsetLiteral) { // no additional literal data - if (_resMan->getViewType() == kViewAmiga) { - // decompression for amiga views - while (pixelNo < pixelCount) { - pixel = *rlePtr++; - if (pixel & 0x07) { // fill with color - runLength = pixel & 0x07; - pixel = pixel >> 3; - while (runLength-- && pixelNo < pixelCount) { - outPtr[pixelNo++] = pixel; - } - } else { // fill with transparent - runLength = pixel >> 3; - pixelNo += runLength; - } - } - return; - } else { - // decompression for data that has just one combined stream - while (pixelNo < pixelCount) { - pixel = *rlePtr++; - runLength = pixel & 0x3F; - switch (pixel & 0xC0) { - case 0: // copy bytes as-is - while (runLength-- && pixelNo < pixelCount) - outPtr[pixelNo++] = *rlePtr++; - break; - case 0x80: // fill with color - memset(outPtr + pixelNo, *rlePtr++, MIN(runLength, pixelCount - pixelNo)); - pixelNo += runLength; - break; - case 0xC0: // fill with transparent - pixelNo += runLength; - break; - } - } - return; - } - } else { - literalPtr = _resourceData + celInfo->offsetLiteral; - if (celInfo->offsetRLE) { - // decompression for data that has separate rle and literal streams - while (pixelNo < pixelCount) { - pixel = *rlePtr++; - runLength = pixel & 0x3F; - switch (pixel & 0xC0) { - case 0: // copy bytes as-is - while (runLength-- && pixelNo < pixelCount) - outPtr[pixelNo++] = *literalPtr++; - break; - case 0x80: // fill with color - memset(outPtr + pixelNo, *literalPtr++, MIN(runLength, pixelCount - pixelNo)); - pixelNo += runLength; - break; - case 0xC0: // fill with transparent - pixelNo += runLength; - break; - } - } - } else { - // literal stream only, so no compression - memcpy(outPtr, literalPtr, pixelCount); - } - return; - } - error("Unable to decompress view"); -} - -byte *SciGuiView::getBitmap(GuiViewLoopNo loopNo, GuiViewCelNo celNo) { - loopNo = CLIP(loopNo, 0, _loopCount -1); - celNo = CLIP(celNo, 0, _loop[loopNo].celCount - 1); - if (_loop[loopNo].cel[celNo].rawBitmap) - return _loop[loopNo].cel[celNo].rawBitmap; - - uint16 width = _loop[loopNo].cel[celNo].width; - uint16 height = _loop[loopNo].cel[celNo].height; - // allocating memory to store cel's bitmap - assert(width * height <= 64000); - uint16 pixelCount = width * height; - _loop[loopNo].cel[celNo].rawBitmap = new byte[pixelCount]; - byte *pBitmap = _loop[loopNo].cel[celNo].rawBitmap; - - // Some RLE compressed cels end with the last non-transparent pixel, thats why we fill it up here - // FIXME: change this to fill the remaining bytes within unpackCel() - memset(pBitmap, _loop[loopNo].cel[celNo].clearKey, pixelCount); - unpackCel(loopNo, celNo, pBitmap, pixelCount); - - if (!_resMan->isVGA()) { - unditherBitmap(pBitmap, width, height, _loop[loopNo].cel[celNo].clearKey); - } - - // mirroring the cel if needed - if (_loop[loopNo].mirrorFlag) { - for (int i = 0; i < height; i++, pBitmap += width) - for (int j = 0; j < width / 2; j++) - SWAP(pBitmap[j], pBitmap[width - j - 1]); - } - return _loop[loopNo].cel[celNo].rawBitmap; -} - -// Called after unpacking an EGA cel, this will try to undither (parts) of the cel if the dithering in here -// matches dithering used by the current picture -void SciGuiView::unditherBitmap(byte *bitmapPtr, int16 width, int16 height, byte clearKey) { - int16 *unditherMemorial = _screen->unditherGetMemorial(); - - // It makes no sense to go further, if no memorial data from current picture is available - if (!unditherMemorial) - return; - - // Makes no sense to process bitmaps that are 3 pixels wide or less - if (width <= 3) return; - - // If EGA mapping is used for this view, dont do undithering as well - if (_EGAmapping) - return; - - // Walk through the bitmap and remember all combinations of colors - int16 bitmapMemorial[SCI_SCREEN_UNDITHERMEMORIAL_SIZE]; - byte *curPtr; - byte color1, color2; - int16 y, x; - - memset(&bitmapMemorial, 0, sizeof(bitmapMemorial)); - - // Count all seemingly dithered pixel-combinations as soon as at least 4 pixels are adjacent - curPtr = bitmapPtr; - for (y = 0; y < height; y++) { - color1 = curPtr[0]; color2 = (curPtr[1] << 4) | curPtr[2]; - curPtr += 3; - for (x = 3; x < width; x++) { - color1 = (color1 << 4) | (color2 >> 4); - color2 = (color2 << 4) | *curPtr++; - if (color1 == color2) - bitmapMemorial[color1]++; - } - } - - // Now compare both memorial tables to find out matching dithering-combinations - bool unditherTable[SCI_SCREEN_UNDITHERMEMORIAL_SIZE]; - byte color, unditherCount = 0; - memset(&unditherTable, false, sizeof(unditherTable)); - for (color = 0; color < 255; color++) { - if ((bitmapMemorial[color] > 5) && (unditherMemorial[color] > 200)) { - // match found, check if colorKey is contained -> if so, we ignore of course - color1 = color & 0x0F; color2 = color >> 4; - if ((color1 != clearKey) && (color2 != clearKey) && (color1 != color2)) { - // so set this and the reversed color-combination for undithering - unditherTable[color] = true; unditherTable[(color1 << 4) | color2] = true; - unditherCount++; - } - } - } - - // Nothing found to undither -> exit straight away - if (!unditherCount) - return; - - // We now need to replace color-combinations - curPtr = bitmapPtr; - for (y = 0; y < height; y++) { - color = *curPtr; - for (x = 1; x < width; x++) { - color = (color << 4) | curPtr[1]; - if (unditherTable[color]) { - // some color with black? turn colors around otherwise it wont be the right color at all - if ((color & 0xF0)==0) - color = (color << 4) | (color >> 4); - curPtr[0] = color; curPtr[1] = color; - } - curPtr++; - } - curPtr++; - } -} - -void SciGuiView::draw(Common::Rect rect, Common::Rect clipRect, Common::Rect clipRectTranslated, GuiViewLoopNo loopNo, GuiViewCelNo celNo, byte priority, uint16 EGAmappingNr, int16 origHeight) { - GuiPalette *palette = _embeddedPal ? &_viewPalette : &_palette->_sysPalette; - sciViewCelInfo *celInfo = getCelInfo(loopNo, celNo); - byte *bitmap = getBitmap(loopNo, celNo); - int16 celHeight = celInfo->height, celWidth = celInfo->width; - int16 width, height; - byte clearKey = celInfo->clearKey; - byte color; - 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); - - bitmap += (clipRect.top - rect.top) * celWidth + (clipRect.left - rect.left); - - if (!_EGAmapping) { - for (y = clipRectTranslated.top; y < clipRectTranslated.top + height; y++, bitmap += celWidth) { - for (x = 0; x < width; x++) { - color = bitmap[x]; - if (color != clearKey && priority >= _screen->getPriority(clipRectTranslated.left + x, y)) { - if (origHeight == -1) // HACK: this parameter is passed for already scaled views, but we're not actually using it - _screen->putPixel(clipRectTranslated.left + x, y, drawMask, palette->mapping[color], priority, 0); - else - _screen->putPixelOnDisplay(clipRectTranslated.left + x, y, palette->mapping[color]); - } - } - } - } else { - byte *EGAmapping = _EGAmapping + (EGAmappingNr * SCI_VIEW_EGAMAPPING_SIZE); - for (y = clipRectTranslated.top; y < clipRectTranslated.top + height; y++, bitmap += celWidth) { - for (x = 0; x < width; x++) { - color = EGAmapping[bitmap[x]]; - if (color != clearKey && priority >= _screen->getPriority(clipRectTranslated.left + x, y)) - _screen->putPixel(clipRectTranslated.left + x, y, drawMask, color, priority, 0); - } - } - } -} - -GuiPalette *SciGuiView::getPalette() { - return _embeddedPal ? &_viewPalette : &_palette->_sysPalette; -} - -} // End of namespace Sci diff --git a/engines/sci/gui/gui_view.h b/engines/sci/gui/gui_view.h deleted file mode 100644 index c4ed3db2b0..0000000000 --- a/engines/sci/gui/gui_view.h +++ /dev/null @@ -1,91 +0,0 @@ -/* 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_VIEW_H -#define SCI_GUI_VIEW_H - -namespace Sci { - -struct sciViewCelInfo { - int16 width, height; - char displaceX; - byte displaceY; - byte clearKey; - uint16 offsetEGA; - uint16 offsetRLE; - uint16 offsetLiteral; - byte *rawBitmap; -}; - -struct sciViewLoopInfo { - bool mirrorFlag; - uint16 celCount; - sciViewCelInfo *cel; -}; - -#define SCI_VIEW_EGAMAPPING_SIZE 16 -#define SCI_VIEW_EGAMAPPING_COUNT 8 - -class SciGuiView { -public: - SciGuiView(ResourceManager *resMan, SciGuiScreen *screen, SciGuiPalette *palette, GuiResourceId resourceId); - ~SciGuiView(); - - GuiResourceId getResourceId(); - int16 getWidth(GuiViewLoopNo loopNo, GuiViewCelNo celNo); - int16 getHeight(GuiViewLoopNo loopNo, GuiViewCelNo celNo); - sciViewCelInfo *getCelInfo(GuiViewLoopNo loopNo, GuiViewCelNo celNo); - sciViewLoopInfo *getLoopInfo(GuiViewLoopNo loopNo); - void getCelRect(GuiViewLoopNo loopNo, GuiViewCelNo celNo, int16 x, int16 y, int16 z, Common::Rect *outRect); - byte *getBitmap(GuiViewLoopNo loopNo, GuiViewCelNo celNo); - void draw(Common::Rect rect, Common::Rect clipRect, Common::Rect clipRectTranslated, GuiViewLoopNo loopNo, GuiViewCelNo celNo, byte priority, uint16 EGAmappingNr, int16 origHeight = -1); - uint16 getLoopCount() const { return _loopCount; } - uint16 getCelCount(GuiViewLoopNo loopNo) { return _loop[loopNo].celCount; } - GuiPalette *getPalette(); - -private: - void initData(GuiResourceId resourceId); - void unpackCel(GuiViewLoopNo loopNo, GuiViewCelNo celNo, byte *outPtr, uint16 pixelCount); - void unditherBitmap(byte *bitmap, int16 width, int16 height, byte clearKey); - - ResourceManager *_resMan; - SciGuiScreen *_screen; - SciGuiPalette *_palette; - - GuiResourceId _resourceId; - Resource *_resource; - byte *_resourceData; - - uint16 _loopCount; - sciViewLoopInfo *_loop; - bool _embeddedPal; - GuiPalette _viewPalette; - - byte *_EGAmapping; -}; - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui/gui_windowmgr.cpp b/engines/sci/gui/gui_windowmgr.cpp deleted file mode 100644 index 9dfa0edf2e..0000000000 --- a/engines/sci/gui/gui_windowmgr.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/* 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/util.h" - -#include "sci/sci.h" -#include "sci/engine/state.h" -#include "sci/gui/gui_screen.h" -#include "sci/gui/gui_gfx.h" -#include "sci/gui/gui_animate.h" -#include "sci/gui/gui_text.h" -#include "sci/gui/gui_windowmgr.h" - -namespace Sci { - -// window styles -enum { - SCI_WINDOWMGR_STYLE_TRANSPARENT = (1 << 0), - SCI_WINDOWMGR_STYLE_NOFRAME = (1 << 1), - SCI_WINDOWMGR_STYLE_TITLE = (1 << 2), - SCI_WINDOWMGR_STYLE_TOPMOST = (1 << 3), - SCI_WINDOWMGR_STYLE_USER = (1 << 7) -}; - -SciGuiWindowMgr::SciGuiWindowMgr(SciGui *gui, SciGuiScreen *screen, SciGuiGfx *gfx, SciGuiText *text) - : _gui(gui), _screen(screen), _gfx(gfx), _text(text) { -} - -SciGuiWindowMgr::~SciGuiWindowMgr() { - // TODO: Clear _windowList and delete all stuff in it? -} - -void SciGuiWindowMgr::init(Common::String gameId) { - int16 offTop = 10; - - _wmgrPort = new GuiPort(1); - _windowsById.resize(2); - _windowsById[0] = _wmgrPort; // wmgrPort is supposed to be accessible via id 0 - _windowsById[1] = _wmgrPort; // but wmgrPort may not actually have id 0, so we assign id 1 (as well) - // Background: sierra sci replies with the offset of curPort on kGetPort calls. If we reply with 0 there most games - // will work, but some scripts seem to check for 0 and initialize the variable again in that case - // resulting in problems. - - // Jones sierra sci was called with parameter -Nw 0 0 200 320 - // this actually meant not skipping the first 10 pixellines in windowMgrPort - if (gameId == "jones") - offTop = 0; - - _gfx->OpenPort(_wmgrPort); - _gfx->SetPort(_wmgrPort); - _gfx->SetOrigin(0, offTop); - _wmgrPort->rect.bottom = 200 - offTop; - _wmgrPort->rect.right = 320; - _wmgrPort->rect.moveTo(0, 0); - _wmgrPort->curTop = 0; - _wmgrPort->curLeft = 0; - _windowList.push_front(_wmgrPort); - - _picWind = NewWindow(Common::Rect(0, offTop, _screen->_width, _screen->_height), 0, 0, SCI_WINDOWMGR_STYLE_TRANSPARENT | SCI_WINDOWMGR_STYLE_NOFRAME, 0, true); -} - -int16 SciGuiWindowMgr::isFrontWindow(GuiWindow *pWnd) { - return _windowList.back() == pWnd; -} - -void SciGuiWindowMgr::BeginUpdate(GuiWindow *wnd) { - GuiPort *oldPort = _gfx->SetPort(_wmgrPort); - PortList::iterator it = _windowList.reverse_begin(); - const PortList::iterator end = Common::find(_windowList.begin(), _windowList.end(), wnd); - while (it != end) { - // FIXME: We also store GuiPort objects in the window list. - // We should add a check that we really only pass windows here... - UpdateWindow((GuiWindow *)*it); - --it; - } - _gfx->SetPort(oldPort); -} - -void SciGuiWindowMgr::EndUpdate(GuiWindow *wnd) { - GuiPort *oldPort = _gfx->SetPort(_wmgrPort); - const PortList::iterator end = _windowList.end(); - PortList::iterator it = Common::find(_windowList.begin(), end, wnd); - - // wnd has to be in _windowList - assert(it != end); - - while (++it != end) { - // FIXME: We also store GuiPort objects in the window list. - // We should add a check that we really only pass windows here... - UpdateWindow((GuiWindow *)*it); - } - - _gfx->SetPort(oldPort); -} - -GuiWindow *SciGuiWindowMgr::NewWindow(const Common::Rect &dims, const Common::Rect *restoreRect, const char *title, uint16 style, int16 priority, bool draw) { - // Find an unused window/port id - uint id = 1; - while (id < _windowsById.size() && _windowsById[id]) { - ++id; - } - if (id == _windowsById.size()) - _windowsById.push_back(0); - assert(0 < id && id < 0xFFFF); - - GuiWindow *pwnd = new GuiWindow(id); - Common::Rect r; - - if (!pwnd) { - warning("Can't open window!"); - return 0; - } - - _windowsById[id] = pwnd; - if (style & SCI_WINDOWMGR_STYLE_TOPMOST) - _windowList.push_front(pwnd); - else - _windowList.push_back(pwnd); - _gfx->OpenPort(pwnd); - r = dims; - pwnd->rect = dims; - if (restoreRect) - pwnd->restoreRect = *restoreRect; - - pwnd->wndStyle = style; - pwnd->hSaved1 = pwnd->hSaved2 = NULL_REG; - pwnd->bDrawn = false; - if ((style & SCI_WINDOWMGR_STYLE_TRANSPARENT) == 0) - pwnd->saveScreenMask = (priority == -1 ? SCI_SCREEN_MASK_VISUAL : SCI_SCREEN_MASK_VISUAL | SCI_SCREEN_MASK_PRIORITY); - - if (title && (style & SCI_WINDOWMGR_STYLE_TITLE)) { - pwnd->title = title; - } - - r = dims; - if (style == SCI_WINDOWMGR_STYLE_USER || !(style & SCI_WINDOWMGR_STYLE_NOFRAME)) { - r.grow(1); - if (style & SCI_WINDOWMGR_STYLE_TITLE) { - r.top -= 10; - r.bottom++; - } - } - - // FIXME: it seems as if shadows may result in the window getting moved one upwards - // so that the shadow is visible (lsl5) - - pwnd->dims = r; - const Common::Rect *wmprect = &_wmgrPort->rect; - int16 oldtop = pwnd->dims.top; - int16 oldleft = pwnd->dims.left; - if (wmprect->top > pwnd->dims.top) - pwnd->dims.moveTo(pwnd->dims.left, wmprect->top); - - if (wmprect->bottom < pwnd->dims.bottom) - pwnd->dims.moveTo(pwnd->dims.left, wmprect->bottom - pwnd->dims.bottom + pwnd->dims.top); - - if (wmprect->right < pwnd->dims.right) - pwnd->dims.moveTo(wmprect->right + pwnd->dims.left - pwnd->dims.right, pwnd->dims.top); - - if (wmprect->left > pwnd->dims.left) - pwnd->dims.moveTo(wmprect->left, pwnd->dims.top); - - pwnd->rect.moveTo(pwnd->rect.left + pwnd->dims.left - oldleft, pwnd->rect.top + pwnd->dims.top - oldtop); - if (restoreRect == 0) - pwnd->restoreRect = pwnd->dims; - - if (!(pwnd->wndStyle & (SCI_WINDOWMGR_STYLE_USER | SCI_WINDOWMGR_STYLE_NOFRAME))) { - // The shadow is drawn slightly outside the window. - // Enlarge restoreRect to cover that. - pwnd->restoreRect.bottom++; - pwnd->restoreRect.right++; - } - - if (draw) - DrawWindow(pwnd); - _gfx->SetPort((GuiPort *)pwnd); - _gfx->SetOrigin(pwnd->rect.left, pwnd->rect.top + _wmgrPort->top); - pwnd->rect.moveTo(0, 0); - return pwnd; -} - -void SciGuiWindowMgr::DrawWindow(GuiWindow *pWnd) { - if (pWnd->bDrawn) - return; - Common::Rect r; - int16 wndStyle = pWnd->wndStyle; - - pWnd->bDrawn = true; - GuiPort *oldport = _gfx->SetPort(_wmgrPort); - _gfx->PenColor(0); - if ((wndStyle & SCI_WINDOWMGR_STYLE_TRANSPARENT) == 0) { - pWnd->hSaved1 = _gfx->BitsSave(pWnd->restoreRect, SCI_SCREEN_MASK_VISUAL); - if (pWnd->saveScreenMask & SCI_SCREEN_MASK_PRIORITY) { - pWnd->hSaved2 = _gfx->BitsSave(pWnd->restoreRect, SCI_SCREEN_MASK_PRIORITY); - if ((wndStyle & SCI_WINDOWMGR_STYLE_USER) == 0) - _gfx->FillRect(pWnd->restoreRect, SCI_SCREEN_MASK_PRIORITY, 0, 15); - } - } - - // drawing frame,shadow and title - if (!(wndStyle & SCI_WINDOWMGR_STYLE_USER)) { - r = pWnd->dims; - if (!(wndStyle & SCI_WINDOWMGR_STYLE_NOFRAME)) { - r.translate(1, 1); - _gfx->FrameRect(r);// shadow - r.translate(-1, -1); - _gfx->FrameRect(r);// window frame - - if (wndStyle & SCI_WINDOWMGR_STYLE_TITLE) { - _gfx->FrameRect(r); - r.grow(-1); - _gfx->FillRect(r, SCI_SCREEN_MASK_VISUAL, 0); - if (!pWnd->title.empty()) { - int16 oldcolor = _gfx->GetPort()->penClr; - _gfx->PenColor(255); - _text->Box(pWnd->title.c_str(), 1, r, SCI_TEXT_ALIGNMENT_CENTER, 0); - _gfx->PenColor(oldcolor); - } - - r = pWnd->dims; - r.top += 9; - } - - r.grow(-1); - } - - if (!(wndStyle & SCI_WINDOWMGR_STYLE_TRANSPARENT)) - _gfx->FillRect(r, SCI_SCREEN_MASK_VISUAL, pWnd->backClr); - - _gfx->BitsShow(pWnd->restoreRect); - } - _gfx->SetPort(oldport); -} - -void SciGuiWindowMgr::DisposeWindow(GuiWindow *pWnd, bool reanimate) { - _gfx->SetPort(_wmgrPort); - _gfx->BitsRestore(pWnd->hSaved1); - _gfx->BitsRestore(pWnd->hSaved2); - if (!reanimate) - _gfx->BitsShow(pWnd->restoreRect); - else - _gui->graphRedrawBox(pWnd->restoreRect); - _windowList.remove(pWnd); - _gfx->SetPort(_windowList.back()); - _windowsById[pWnd->id] = 0; - delete pWnd; -} - -void SciGuiWindowMgr::UpdateWindow(GuiWindow *wnd) { - GuiMemoryHandle handle; - - if (wnd->saveScreenMask && wnd->bDrawn) { - handle = _gfx->BitsSave(wnd->restoreRect, SCI_SCREEN_MASK_VISUAL); - _gfx->BitsRestore(wnd->hSaved1); - wnd->hSaved1 = handle; - if (wnd->saveScreenMask & SCI_SCREEN_MASK_PRIORITY) { - handle = _gfx->BitsSave(wnd->restoreRect, SCI_SCREEN_MASK_PRIORITY); - _gfx->BitsRestore(wnd->hSaved2); - wnd->hSaved2 = handle; - } - } -} - -} // End of namespace Sci diff --git a/engines/sci/gui/gui_windowmgr.h b/engines/sci/gui/gui_windowmgr.h deleted file mode 100644 index 483df9efc5..0000000000 --- a/engines/sci/gui/gui_windowmgr.h +++ /dev/null @@ -1,71 +0,0 @@ -/* 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_WINDOWMGR_H -#define SCI_GUI_WINDOWMGR_H - -#include "common/list.h" -#include "common/array.h" - -namespace Sci { - -class SciGuiWindowMgr { -public: - SciGuiWindowMgr(SciGui *gui, SciGuiScreen *screen, SciGuiGfx *gfx, SciGuiText *text); - ~SciGuiWindowMgr(); - - void init(Common::String gameId); - - int16 isFrontWindow(GuiWindow *wnd); - void BeginUpdate(GuiWindow *wnd); - void EndUpdate(GuiWindow *wnd); - GuiWindow *NewWindow(const Common::Rect &dims, const Common::Rect *restoreRect, const char *title, uint16 style, int16 priority, bool draw); - void DrawWindow(GuiWindow *wnd); - void DisposeWindow(GuiWindow *pWnd, bool reanimate); - void UpdateWindow(GuiWindow *wnd); - - GuiPort *getPortById(uint16 id) const { return _windowsById[id]; } - - GuiPort *_wmgrPort; - GuiWindow *_picWind; - -private: - typedef Common::List PortList; - - SciGui *_gui; - SciGuiScreen *_screen; - SciGuiGfx *_gfx; - SciGuiText *_text; - - /** The list of open 'windows' (and ports), in visual order. */ - PortList _windowList; - - /** The list of all open 'windows' (and ports), ordered by their id. */ - Common::Array _windowsById; -}; - -} // End of namespace Sci - -#endif -- cgit v1.2.3