2009-11-04 21:03:57 +00:00

803 lines
23 KiB
C++

/* 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/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"
#include "sci/gfx/operations.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->_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->_gameName);
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;
gfxop_sleep(_s->gfx_state, 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));
};
}
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_SETTEXTFACE 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->TextFace(0);
// 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_SETTEXTFACE:
_gfx->TextFace(argv[0].toUint16());
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);
_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->_menuRect, 1, colorBack);
_gfx->PenColor(colorPen);
_gfx->MoveTo(0, 1);
_text->Draw_String(text);
if (_screen->_picNotValid == 0)
_gfx->BitsShow(_gfx->_menuRect);
_gfx->SetPort(oldPort);
}
void SciGui::drawMenuBar(bool clear) {
if (!clear) {
GuiPort *oldPort = _gfx->SetPort(_gfx->_menuPort);
_menu->drawBar();
_gfx->SetPort(oldPort);
} else {
drawStatus("", 0, 0);
}
}
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();
}
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->TextFace(style & 1 ? 0 : 1);
_text->Box(text, 0, rect, SCI_TEXT_ALIGNMENT_CENTER, fontId);
_gfx->TextFace(0);
rect.grow(1);
if (style & 8) // selected
_gfx->FrameRect(rect);
if (_screen->_picNotValid == 0) {
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 (_screen->_picNotValid == 0)
_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 (_screen->_picNotValid == 0)
_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 (_screen->_picNotValid == 0)
_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 (_screen->_picNotValid == 0)
_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 = _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);
}
void 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;
_palette->animate(fromColor, toColor, speed);
}
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;
_cursor->hide();
// Adjust picRect to become relative to screen
picRect.translate(picPort->left, picPort->top);
_transitions->doit(picRect);
_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<int>(position.x, 0, celInfo->width - 1);
position.y = CLIP<int>(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<int16>(pos.y, _windowMgr->_picWind->rect.top, _windowMgr->_picWind->rect.bottom - 1);
pos.x = CLIP<int16>(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; // Not fatal
}
_cursor->setPosition(pos);
// Trigger event reading to make sure the mouse coordinates will
// actually have changed the next time we read them.
//gfxop_get_event(_s->gfx_state, SCI_EVT_PEEK);
// FIXME!
}
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) {
}
bool SciGui::debugUndither(bool flag) {
_screen->unditherSetState(flag);
return false;
}
bool SciGui::debugShowMap(int mapNo) {
_screen->debugShowMap(mapNo);
return false;
}
} // End of namespace Sci