diff options
author | Martin Kiewitz | 2010-01-29 21:30:46 +0000 |
---|---|---|
committer | Martin Kiewitz | 2010-01-29 21:30:46 +0000 |
commit | a800855bf4799de2025f6f1220dc363e66aab475 (patch) | |
tree | d97ab9702e0cf7c4a2cd3e0fc25b42de0e96e41b /engines/sci/graphics | |
parent | 85517515a76069d77fde6ecfb933f2e133b52a01 (diff) | |
download | scummvm-rg350-a800855bf4799de2025f6f1220dc363e66aab475.tar.gz scummvm-rg350-a800855bf4799de2025f6f1220dc363e66aab475.tar.bz2 scummvm-rg350-a800855bf4799de2025f6f1220dc363e66aab475.zip |
SCI: added new SciGui32 class, Gfx class needs some work though and hopefully i didnt overlook some kernel function that is also used by sci32. now using plane left/top
svn-id: r47679
Diffstat (limited to 'engines/sci/graphics')
-rw-r--r-- | engines/sci/graphics/gfx.cpp | 13 | ||||
-rw-r--r-- | engines/sci/graphics/gui.cpp | 154 | ||||
-rw-r--r-- | engines/sci/graphics/gui.h | 20 | ||||
-rw-r--r-- | engines/sci/graphics/gui32.cpp | 340 | ||||
-rw-r--r-- | engines/sci/graphics/gui32.h | 103 | ||||
-rw-r--r-- | engines/sci/graphics/picture.cpp | 19 |
6 files changed, 474 insertions, 175 deletions
diff --git a/engines/sci/graphics/gfx.cpp b/engines/sci/graphics/gfx.cpp index b3219d98e9..652ec2eb58 100644 --- a/engines/sci/graphics/gfx.cpp +++ b/engines/sci/graphics/gfx.cpp @@ -446,24 +446,21 @@ void Gfx::drawHiresCelAndShow(GuiResourceId viewId, int16 loopNo, int16 celNo, u } uint16 Gfx::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 + if (rect.isEmpty()) 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++) { + for (y = rect.top; y < rect.bottom; y++) { + for (x = rect.left; x < rect.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++) { + for (y = rect.top; y < rect.bottom; y++) { + for (x = rect.left; x < rect.right; x++) { result |= 1 << _screen->getControl(x, y); } } diff --git a/engines/sci/graphics/gui.cpp b/engines/sci/graphics/gui.cpp index 255d95a622..8c662290be 100644 --- a/engines/sci/graphics/gui.cpp +++ b/engines/sci/graphics/gui.cpp @@ -41,7 +41,6 @@ #include "sci/graphics/controls.h" #include "sci/graphics/menu.h" #include "sci/graphics/portrait.h" -#include "sci/graphics/robot.h" #include "sci/graphics/text.h" #include "sci/graphics/transitions.h" #include "sci/graphics/view.h" @@ -61,9 +60,6 @@ SciGui::SciGui(EngineState *state, Screen *screen, SciPalette *palette, Cursor * _menu = new Menu(_s->_event, _s->_segMan, this, _gfx, _text, _screen, _cursor); } -SciGui::SciGui() { -} - SciGui::~SciGui() { delete _menu; delete _controls; @@ -152,20 +148,6 @@ void SciGui::localToGlobal(int16 *x, int16 *y) { *y = *y + curPort->top; } -#ifdef ENABLE_SCI32 - -void SciGui::globalToLocal(int16 *x, int16 *y, reg_t planeObj) { - *x = *x - GET_SEL32V(_s->_segMan, planeObj, left); - *y = *y - GET_SEL32V(_s->_segMan, planeObj, top); -} - -void SciGui::localToGlobal(int16 *x, int16 *y, reg_t planeObj) { - *x = *x + GET_SEL32V(_s->_segMan, planeObj, left); - *y = *y + GET_SEL32V(_s->_segMan, planeObj, top); -} - -#endif - int16 SciGui::coordinateToPriority(int16 y) { return _gfx->CoordinateToPriority(y); } @@ -624,9 +606,13 @@ void SciGui::shakeScreen(uint16 shakeCount, uint16 directions) { uint16 SciGui::onControl(byte screenMask, Common::Rect rect) { Port *oldPort = _gfx->SetPort((Port *)_windowMgr->_picWind); + Common::Rect adjustedRect(rect.left, rect.top, rect.right, rect.bottom); uint16 result; - result = _gfx->onControl(screenMask, rect); + adjustedRect.clip(_gfx->GetPort()->rect); + _gfx->OffsetRect(adjustedRect); + result = _gfx->onControl(screenMask, adjustedRect); + _gfx->SetPort(oldPort); return result; } @@ -728,6 +714,7 @@ void SciGui::setNowSeen(reg_t objectReference) { bool SciGui::canBeHere(reg_t curObject, reg_t listReference) { Port *oldPort = _gfx->SetPort((Port *)_windowMgr->_picWind); Common::Rect checkRect; + Common::Rect adjustedRect; uint16 signal, controlMask; bool result; @@ -735,9 +722,14 @@ bool SciGui::canBeHere(reg_t curObject, reg_t listReference) { checkRect.top = GET_SEL32V(_s->_segMan, curObject, brTop); checkRect.right = GET_SEL32V(_s->_segMan, curObject, brRight); checkRect.bottom = GET_SEL32V(_s->_segMan, curObject, brBottom); + + adjustedRect = checkRect; + adjustedRect.clip(_gfx->GetPort()->rect); + _gfx->OffsetRect(adjustedRect); + 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; + result = (_gfx->onControl(SCI_SCREEN_MASK_CONTROL, adjustedRect) & controlMask) ? false : true; if ((result) && (signal & (kSignalIgnoreActor | kSignalRemoveView)) == 0) { List *list = _s->_segMan->lookupList(listReference); if (!list) @@ -908,128 +900,6 @@ void SciGui::doPalVary() { // TODO: do palette transition here... } -#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; - - int16 picNum = GET_SEL32V(_s->_segMan, planeObj, picture); - if (picNum > -1) { - drawPicture(picNum, 100, false, false, false, 0); - } - - // 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 x = GET_SEL32V(_s->_segMan, viewObj, x); - uint16 y = GET_SEL32V(_s->_segMan, viewObj, y); - uint16 z = GET_SEL32V(_s->_segMan, viewObj, z); - priority = GET_SEL32V(_s->_segMan, viewObj, priority); - uint16 scaleX = GET_SEL32V(_s->_segMan, viewObj, scaleX); - uint16 scaleY = GET_SEL32V(_s->_segMan, viewObj, scaleY); - //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 (x >= _screen->getWidth()) { - continue; - } - - if (y >= _screen->getHeight()) { - continue; - } - - if (viewId != 0xffff) { - Common::Rect celRect; - View *view = _gfx->getView(viewId); - // Sometimes x,y are bottom right - view->getCelRect(loopNo, celNo, x, y, z, &celRect); -// leftPos = GET_SEL32V(_s->_segMan, viewObj, x); -// topPos = GET_SEL32V(_s->_segMan, viewObj, y); -// celRect.left = leftPos; -// celRect.top = topPos; -// celRect.right = leftPos + view->getWidth(loopNo, celNo); -// celRect.bottom = topPos + view->getHeight(loopNo, celNo); -// warning("view %d, loop %d, cel %d", viewId, loopNo, celNo); - -//void View::getCelRect(int16 loopNo, int16 celNo, int16 x, int16 y, int16 z, Common::Rect *outRect) { - //celRect.right = leftPos; - //celRect.bottom = topPos; - //celRect.left = celRect.right - view->getWidth(loopNo, celNo);; - //celRect.top = celRect.bottom - view->getHeight(loopNo, celNo); - celRect.clip(_gfx->_curPort->rect); - _gfx->drawCel(view, loopNo, celNo, celRect, priority, 0, scaleX, scaleY); - } - //drawCel(viewId, loopNo, celNo, leftPos, topPos, priority, 0); - } - } - } - _screen->copyToScreen(); - //animateShowPic(); -} - -void SciGui::drawRobot(GuiResourceId robotId) { - Robot *test = new Robot(_s->resMan, _screen, robotId); - test->draw(); - delete test; -} -#endif - bool SciGui::debugUndither(bool flag) { _screen->unditherSetState(flag); return false; diff --git a/engines/sci/graphics/gui.h b/engines/sci/graphics/gui.h index ec7d385acf..50a2820fe8 100644 --- a/engines/sci/graphics/gui.h +++ b/engines/sci/graphics/gui.h @@ -55,7 +55,6 @@ class Transitions; class SciGui { public: SciGui(EngineState *s, Screen *screen, SciPalette *palette, Cursor *cursor, AudioPlayer *audio); - SciGui(); virtual ~SciGui(); virtual void init(bool usesOldGfxFunctions); @@ -156,20 +155,6 @@ public: void togglePalVary(bool pause); void stopPalVary(); -#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(); - virtual void globalToLocal(int16 *x, int16 *y, reg_t planeObj); - virtual void localToGlobal(int16 *x, int16 *y, reg_t planeObj); - - virtual void drawRobot(GuiResourceId robotId); -#endif - virtual bool debugUndither(bool flag); virtual bool debugShowMap(int mapNo); virtual bool debugEGAdrawingVisualize(bool state); @@ -203,11 +188,6 @@ private: uint32 _palVaryEnd; bool _usesOldGfxFunctions; - -#ifdef ENABLE_SCI32 - Common::Array<reg_t> _screenItems; - Common::Array<reg_t> _planes; -#endif }; } // End of namespace Sci diff --git a/engines/sci/graphics/gui32.cpp b/engines/sci/graphics/gui32.cpp new file mode 100644 index 0000000000..7caab09ae6 --- /dev/null +++ b/engines/sci/graphics/gui32.cpp @@ -0,0 +1,340 @@ +/* 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/engine/selector.h" +#include "sci/graphics/gui32.h" +#include "sci/graphics/screen.h" +#include "sci/graphics/palette.h" +#include "sci/graphics/cursor.h" +#include "sci/graphics/gfx.h" +#include "sci/graphics/picture.h" +#include "sci/graphics/robot.h" +#include "sci/graphics/text.h" +#include "sci/graphics/view.h" + +namespace Sci { + +SciGui32::SciGui32(EngineState *state, Screen *screen, SciPalette *palette, Cursor *cursor) + : _s(state), _screen(screen), _palette(palette), _cursor(cursor) { + + _gfx = new Gfx(_s->resMan, _s->_segMan, _s->_kernel, _screen, _palette); +} + +SciGui32::~SciGui32() { + delete _gfx; +} + +void SciGui32::resetEngineState(EngineState *s) { + _s = s; +} + +void SciGui32::init() { +} + +void SciGui32::globalToLocal(int16 *x, int16 *y, reg_t planeObj) { + *x = *x - GET_SEL32V(_s->_segMan, planeObj, left); + *y = *y - GET_SEL32V(_s->_segMan, planeObj, top); +} + +void SciGui32::localToGlobal(int16 *x, int16 *y, reg_t planeObj) { + *x = *x + GET_SEL32V(_s->_segMan, planeObj, left); + *y = *y + GET_SEL32V(_s->_segMan, planeObj, top); +} + +void SciGui32::textSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight) { + *textWidth = 0; + *textHeight = 0; +} + +uint16 SciGui32::onControl(byte screenMask, Common::Rect rect) { + Common::Rect adjustedRect = rect; + uint16 result; + + adjustedRect.translate(0, 10); + + result = _gfx->onControl(screenMask, rect); + return result; +} + +void SciGui32::setNowSeen(reg_t objectReference) { + _gfx->SetNowSeen(objectReference); +} + +bool SciGui32::canBeHere(reg_t curObject, reg_t listReference) { + 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)) { // gui16 && (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); + } + return result; +} + +bool SciGui32::isItSkip(GuiResourceId viewId, int16 loopNo, int16 celNo, Common::Point position) { + View *tmpView = _gfx->getView(viewId); + CelInfo *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 SciGui32::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); + int16 loopNo = GET_SEL32V(_s->_segMan, object, loop); + int16 celNo = GET_SEL32V(_s->_segMan, object, cel); + + View *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 SciGui32::hideCursor() { + _cursor->hide(); +} + +void SciGui32::showCursor() { + _cursor->show(); +} + +bool SciGui32::isCursorVisible() { + return _cursor->isVisible(); +} + +void SciGui32::setCursorShape(GuiResourceId cursorId) { + _cursor->setShape(cursorId); +} + +void SciGui32::setCursorView(GuiResourceId viewNum, int loopNum, int cellNum, Common::Point *hotspot) { + _cursor->setView(viewNum, loopNum, cellNum, hotspot); +} + +void SciGui32::setCursorPos(Common::Point pos) { + //pos.y += _gfx->GetPort()->top; + //pos.x += _gfx->GetPort()->left; + moveCursor(pos); +} + +Common::Point SciGui32::getCursorPos() { + return _cursor->getPosition(); +} + +void SciGui32::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->getWidth() || pos.y > _screen->getHeight()) { + 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 SciGui32::setCursorZone(Common::Rect zone) { + _cursor->setMoveZone(zone); +} + +int16 SciGui32::getCelWidth(GuiResourceId viewId, int16 loopNo, int16 celNo) { + return _gfx->getView(viewId)->getCelInfo(loopNo, celNo)->width; +} + +int16 SciGui32::getCelHeight(GuiResourceId viewId, int16 loopNo, int16 celNo) { + return _gfx->getView(viewId)->getCelInfo(loopNo, celNo)->height; +} + +int16 SciGui32::getLoopCount(GuiResourceId viewId) { + return _gfx->getView(viewId)->getLoopCount(); +} + +int16 SciGui32::getCelCount(GuiResourceId viewId, int16 loopNo) { + return _gfx->getView(viewId)->getLoopInfo(loopNo)->celCount; +} + +void SciGui32::syncWithFramebuffer() { + _screen->syncWithFramebuffer(); +} + +void SciGui32::addScreenItem(reg_t object) { + _screenItems.push_back(object); +} + +void SciGui32::deleteScreenItem(reg_t object) { + for (uint32 itemNr = 0; itemNr < _screenItems.size(); itemNr++) { + if (_screenItems[itemNr] == object) { + _screenItems.remove_at(itemNr); + return; + } + } +} + +void SciGui32::addPlane(reg_t object) { + _planes.push_back(object); +} + +void SciGui32::updatePlane(reg_t object) { +} + +void SciGui32::deletePlane(reg_t object) { + for (uint32 planeNr = 0; planeNr < _planes.size(); planeNr++) { + if (_planes[planeNr] == object) { + _planes.remove_at(planeNr); + return; + } + } +} + +void SciGui32::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; + + int16 picNum = GET_SEL32V(_s->_segMan, planeObj, picture); + if (picNum > -1) { + SciGuiPicture *picture = new SciGuiPicture(_s->resMan, 0, _screen, _palette, picNum, false); + + picture->draw(100, false, false, 0); + delete picture; + //_gfx->drawPicture(picNum, 100, false, false, 0); + } + + // 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 x = GET_SEL32V(_s->_segMan, viewObj, x); + uint16 y = GET_SEL32V(_s->_segMan, viewObj, y); + uint16 z = GET_SEL32V(_s->_segMan, viewObj, z); + priority = GET_SEL32V(_s->_segMan, viewObj, priority); + uint16 scaleX = GET_SEL32V(_s->_segMan, viewObj, scaleX); + uint16 scaleY = GET_SEL32V(_s->_segMan, viewObj, scaleY); + //int16 signal = GET_SEL32V(_s->_segMan, viewObj, signal); + + // FIXME: See above + x += planeLeft; + y += 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 (y < 0 || x >= _screen->getWidth()) { + continue; + } + + if (y < 0 || y >= _screen->getHeight()) { + continue; + } + + if (viewId != 0xffff) { + Common::Rect celRect; + View *view = _gfx->getView(viewId); + + view->getCelRect(loopNo, celNo, x, y, z, &celRect); + + if (celRect.top < 0 || celRect.top >= _screen->getHeight()) + continue; + + if (celRect.left < 0 || celRect.left >= _screen->getWidth()) + continue; + + if ((scaleX == 128) && (scaleY == 128)) + view->draw(celRect, celRect, celRect, loopNo, celNo, 255, 0, false); + else + view->drawScaled(celRect, celRect, celRect, loopNo, celNo, 255, scaleX, scaleY); + //_gfx->drawCel(view, loopNo, celNo, celRect, priority, 0, scaleX, scaleY); + } + } + } + } + _screen->copyToScreen(); +} + +void SciGui32::drawRobot(GuiResourceId robotId) { + Robot *test = new Robot(_s->resMan, _screen, robotId); + test->draw(); + delete test; +} + +bool SciGui32::debugShowMap(int mapNo) { + _screen->debugShowMap(mapNo); + return false; +} + +} // End of namespace Sci diff --git a/engines/sci/graphics/gui32.h b/engines/sci/graphics/gui32.h new file mode 100644 index 0000000000..9194d9e81e --- /dev/null +++ b/engines/sci/graphics/gui32.h @@ -0,0 +1,103 @@ +/* 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_GRAPHICS_GUI32_H +#define SCI_GRAPHICS_GUI32_H + +#include "sci/graphics/helpers.h" + +namespace Sci { + +class Screen; +class SciPalette; +class Cursor; +class Gfx; +class Text; + +class SciGui32 { +public: + SciGui32(EngineState *s, Screen *screen, SciPalette *palette, Cursor *cursor); + SciGui32(); + ~SciGui32(); + + void init(); + + void textSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight); + + uint16 onControl(byte screenMask, Common::Rect rect); + void setNowSeen(reg_t objectReference); + bool canBeHere(reg_t curObject, reg_t listReference); + bool isItSkip(GuiResourceId viewId, int16 loopNo, int16 celNo, Common::Point position); + void baseSetter(reg_t object); + + void hideCursor(); + void showCursor(); + bool isCursorVisible(); + 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); + + int16 getCelWidth(GuiResourceId viewId, int16 loopNo, int16 celNo); + int16 getCelHeight(GuiResourceId viewId, int16 loopNo, int16 celNo); + + int16 getLoopCount(GuiResourceId viewId); + int16 getCelCount(GuiResourceId viewId, int16 loopNo); + + void syncWithFramebuffer(); + + void addScreenItem(reg_t object); + void deleteScreenItem(reg_t object); + void addPlane(reg_t object); + void updatePlane(reg_t object); + void deletePlane(reg_t object); + void frameOut(); + void globalToLocal(int16 *x, int16 *y, reg_t planeObj); + void localToGlobal(int16 *x, int16 *y, reg_t planeObj); + + void drawRobot(GuiResourceId robotId); + + bool debugShowMap(int mapNo); + + // FIXME: Don't store EngineState + void resetEngineState(EngineState *s); + +protected: + Cursor *_cursor; + EngineState *_s; + Screen *_screen; + SciPalette *_palette; + Gfx *_gfx; + +private: + Common::Array<reg_t> _screenItems; + Common::Array<reg_t> _planes; +}; + +} // End of namespace Sci + +#endif diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp index d599277dd4..f914158fb1 100644 --- a/engines/sci/graphics/picture.cpp +++ b/engines/sci/graphics/picture.cpp @@ -265,11 +265,20 @@ void SciGuiPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rle memcpy(celBitmap, rlePtr, pixelCount); } - // Set initial vertical coordinate by using current port - y = callerY + _gfx->GetPort()->top; - lastY = MIN<int16>(height + y, _gfx->GetPort()->rect.bottom + _gfx->GetPort()->top); - leftX = callerX + _gfx->GetPort()->left; - rightX = MIN<int16>(width + leftX, _gfx->GetPort()->rect.right + _gfx->GetPort()->left); + if (_gfx) { + // Set initial vertical coordinate by using current port + y = callerY + _gfx->GetPort()->top; + lastY = MIN<int16>(height + y, _gfx->GetPort()->rect.bottom + _gfx->GetPort()->top); + leftX = callerX + _gfx->GetPort()->left; + rightX = MIN<int16>(width + leftX, _gfx->GetPort()->rect.right + _gfx->GetPort()->left); + } else { + y = callerY + 10; // TODO: Implement plane support for SCI32 + lastY = y + height; + if (lastY > _screen->getHeight()) + lastY = _screen->getHeight(); + leftX = callerX; + rightX = leftX + width; + } // 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) |