aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorMartin Kiewitz2010-02-02 16:25:35 +0000
committerMartin Kiewitz2010-02-02 16:25:35 +0000
commit714665f9d9bde9bf337160276c50b662a5501442 (patch)
tree22f6cb8390a6fbff1838978766a17ba65a74531a /engines/sci
parentb0208e7306c40a41b0e5b6365f0c49f8aebe3b94 (diff)
downloadscummvm-rg350-714665f9d9bde9bf337160276c50b662a5501442.tar.gz
scummvm-rg350-714665f9d9bde9bf337160276c50b662a5501442.tar.bz2
scummvm-rg350-714665f9d9bde9bf337160276c50b662a5501442.zip
SCI: some sort of priority support for sci32 (not working right, but at least the menu in gk1 now correctly shows up)
svn-id: r47814
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/graphics/frameout.cpp216
-rw-r--r--engines/sci/graphics/frameout.h75
-rw-r--r--engines/sci/graphics/gui32.cpp118
-rw-r--r--engines/sci/graphics/gui32.h12
-rw-r--r--engines/sci/graphics/picture.cpp23
-rw-r--r--engines/sci/graphics/picture.h8
-rw-r--r--engines/sci/module.mk1
7 files changed, 333 insertions, 120 deletions
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp
new file mode 100644
index 0000000000..09251d0ce2
--- /dev/null
+++ b/engines/sci/graphics/frameout.cpp
@@ -0,0 +1,216 @@
+/* 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/selector.h"
+#include "sci/engine/vm.h"
+#include "sci/graphics/cache.h"
+#include "sci/graphics/view.h"
+#include "sci/graphics/screen.h"
+#include "sci/graphics/picture.h"
+#include "sci/graphics/frameout.h"
+
+namespace Sci {
+
+GfxFrameout::GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCache *cache, GfxScreen *screen, GfxPalette *palette)
+ : _segMan(segMan), _resMan(resMan), _cache(cache), _screen(screen), _palette(palette) {
+}
+
+GfxFrameout::~GfxFrameout() {
+}
+
+void GfxFrameout::kernelAddPlane(reg_t object) {
+ _planes.push_back(object);
+ int16 planePri = GET_SEL32V(_segMan, object, priority) & 0xFFFF;
+ if (planePri > _highPlanePri)
+ _highPlanePri = planePri;
+}
+
+void GfxFrameout::kernelUpdatePlane(reg_t object) {
+}
+
+void GfxFrameout::kernelDeletePlane(reg_t object) {
+ for (uint32 planeNr = 0; planeNr < _planes.size(); planeNr++) {
+ if (_planes[planeNr] == object) {
+ _planes.remove_at(planeNr);
+ break;
+ }
+ }
+
+ // Recalculate highPlanePri
+ _highPlanePri = 0;
+
+ for (uint32 planeNr = 0; planeNr < _planes.size(); planeNr++) {
+ int16 planePri = GET_SEL32V(_segMan, _planes[planeNr], priority) & 0xFFFF;
+ if (planePri > _highPlanePri)
+ _highPlanePri = planePri;
+ }
+}
+
+void GfxFrameout::kernelAddScreenItem(reg_t object) {
+ _screenItems.push_back(object);
+ warning("addScreenItem %X:%X (%s)", object.segment, object.offset, _segMan->getObjectName(object));
+}
+
+void GfxFrameout::kernelDeleteScreenItem(reg_t object) {
+ for (uint32 itemNr = 0; itemNr < _screenItems.size(); itemNr++) {
+ if (_screenItems[itemNr] == object) {
+ _screenItems.remove_at(itemNr);
+ return;
+ }
+ }
+}
+
+int16 GfxFrameout::kernelGetHighPlanePri() {
+ return _highPlanePri;
+}
+
+bool sortHelper(const FrameoutEntry* entry1, const FrameoutEntry* entry2) {
+ return (entry1->priority == entry2->priority) ? (entry1->y < entry2->y) : (entry1->priority < entry2->priority);
+}
+
+void GfxFrameout::kernelFrameout() {
+ int16 itemCount = 0;
+ reg_t planeObject;
+ GuiResourceId planePictureNr;
+ SciGuiPicture *planePicture = 0;
+ int16 planePictureCels;
+ int16 planePictureCel;
+ int16 planePriority;
+ int16 planeTop, planeLeft;
+
+ reg_t itemObject;
+ reg_t itemPlane;
+
+ FrameoutEntry *itemData;
+ FrameoutList itemList;
+ FrameoutEntry *itemEntry;
+
+ // Allocate enough space for all screen items
+ itemData = (FrameoutEntry *)malloc(_screenItems.size() * sizeof(FrameoutEntry));
+
+ for (uint32 planeNr = 0; planeNr < _planes.size(); planeNr++) {
+ planeObject = _planes[planeNr];
+ planePriority = GET_SEL32V(_segMan, planeObject, priority);
+
+ if (planePriority == -1) // Plane currently not meant to be shown
+ continue;
+
+ planePictureNr = GET_SEL32V(_segMan, planeObject, picture);
+ if (planePictureNr != 0xFFFF) {
+ planePicture = new SciGuiPicture(_resMan, 0, _screen, _palette, planePictureNr, false);
+ planePictureCels = planePicture->getSci32celCount();
+ }
+
+ planeTop = GET_SEL32V(_segMan, planeObject, top);
+ planeLeft = GET_SEL32V(_segMan, planeObject, left);
+
+ // Fill our itemlist for this plane
+ itemCount = 0;
+ itemEntry = itemData;
+ for (uint32 itemNr = 0; itemNr < _screenItems.size(); itemNr++) {
+ itemObject = _screenItems[itemNr];
+ itemPlane = GET_SEL32(_segMan, itemObject, plane);
+ if (planeObject == itemPlane) {
+ // Found an item on current plane
+ itemEntry->viewId = GET_SEL32V(_segMan, itemObject, view);
+ itemEntry->loopNo = GET_SEL32V(_segMan, itemObject, loop);
+ itemEntry->celNo = GET_SEL32V(_segMan, itemObject, cel);
+ itemEntry->x = GET_SEL32V(_segMan, itemObject, x);
+ itemEntry->y = GET_SEL32V(_segMan, itemObject, y);
+ itemEntry->z = GET_SEL32V(_segMan, itemObject, z);
+ itemEntry->priority = GET_SEL32V(_segMan, itemObject, priority);
+ itemEntry->scaleX = GET_SEL32V(_segMan, itemObject, scaleX);
+ itemEntry->scaleY = GET_SEL32V(_segMan, itemObject, scaleY);
+
+ itemEntry->x += planeLeft;
+ itemEntry->y += planeTop;
+
+ itemList.push_back(itemEntry);
+ itemEntry++;
+ itemCount++;
+ }
+ }
+
+ // Now sort our itemlist
+ Common::sort(itemList.begin(), itemList.end(), sortHelper);
+
+ // Now display itemlist
+ planePictureCel = 0;
+
+ itemEntry = itemData;
+ FrameoutList::iterator listIterator = itemList.begin();
+ FrameoutList::iterator listEnd = itemList.end();
+ while (listIterator != listEnd) {
+ itemEntry = *listIterator;
+ if (planePicture) {
+ while ((planePictureCel <= itemEntry->priority) && (planePictureCel < planePictureCels)) {
+ planePicture->drawSci32Vga(planePictureCel);
+ planePictureCel++;
+ }
+ }
+ if (itemEntry->viewId != 0xFFFF) {
+ View *view = _cache->getView(itemEntry->viewId);
+
+ if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128))
+ view->getCelRect(itemEntry->loopNo, itemEntry->celNo, itemEntry->x, itemEntry->y, itemEntry->z, &itemEntry->celRect);
+ else
+ view->getCelScaledRect(itemEntry->loopNo, itemEntry->celNo, itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->scaleX, itemEntry->scaleY, &itemEntry->celRect);
+
+ if (itemEntry->celRect.top < 0 || itemEntry->celRect.top >= _screen->getHeight()) {
+ listIterator++;
+ continue;
+ }
+
+ if (itemEntry->celRect.left < 0 || itemEntry->celRect.left >= _screen->getWidth()) {
+ listIterator++;
+ continue;
+ }
+
+ if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128))
+ view->draw(itemEntry->celRect, itemEntry->celRect, itemEntry->celRect, itemEntry->loopNo, itemEntry->celNo, 255, 0, false);
+ else
+ view->drawScaled(itemEntry->celRect, itemEntry->celRect, itemEntry->celRect, itemEntry->loopNo, itemEntry->celNo, 255, itemEntry->scaleX, itemEntry->scaleY);
+ }
+ listIterator++;
+ }
+ if (planePicture) {
+ while (planePictureCel < planePictureCels) {
+ planePicture->drawSci32Vga(planePictureCel);
+ planePictureCel++;
+ }
+ delete planePicture;
+ planePicture = 0;
+ }
+ }
+ free(itemData);
+}
+
+} // End of namespace Sci
diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h
new file mode 100644
index 0000000000..bd5c13b2da
--- /dev/null
+++ b/engines/sci/graphics/frameout.h
@@ -0,0 +1,75 @@
+/* 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_FRAMEOUT_H
+#define SCI_GRAPHICS_FRAMEOUT_H
+
+namespace Sci {
+
+struct FrameoutEntry {
+ reg_t object;
+ GuiResourceId viewId;
+ int16 loopNo;
+ int16 celNo;
+ int16 x, y, z;
+ int16 priority;
+ uint16 scaleSignal;
+ int16 scaleX;
+ int16 scaleY;
+ Common::Rect celRect;
+};
+typedef Common::List<FrameoutEntry *> FrameoutList;
+
+class GfxCache;
+class Screen;
+class SciPalette;
+class GfxFrameout {
+public:
+ GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCache *cache, GfxScreen *screen, GfxPalette *palette);
+ ~GfxFrameout();
+
+ void kernelAddPlane(reg_t object);
+ void kernelUpdatePlane(reg_t object);
+ void kernelDeletePlane(reg_t object);
+ void kernelAddScreenItem(reg_t object);
+ void kernelDeleteScreenItem(reg_t object);
+ int16 kernelGetHighPlanePri();
+ void kernelFrameout();
+
+private:
+ SegManager *_segMan;
+ ResourceManager *_resMan;
+ GfxCache *_cache;
+ GfxPalette *_palette;
+ GfxScreen *_screen;
+
+ Common::Array<reg_t> _screenItems;
+ Common::Array<reg_t> _planes;
+ int16 _highPlanePri;
+};
+
+} // End of namespace Sci
+
+#endif
diff --git a/engines/sci/graphics/gui32.cpp b/engines/sci/graphics/gui32.cpp
index d5cf1700a2..61add8a8cd 100644
--- a/engines/sci/graphics/gui32.cpp
+++ b/engines/sci/graphics/gui32.cpp
@@ -37,6 +37,7 @@
#include "sci/graphics/cursor.h"
#include "sci/graphics/cache.h"
#include "sci/graphics/compare.h"
+#include "sci/graphics/frameout.h"
#include "sci/graphics/picture.h"
#include "sci/graphics/robot.h"
#include "sci/graphics/view.h"
@@ -44,9 +45,10 @@
namespace Sci {
SciGui32::SciGui32(EngineState *state, GfxScreen *screen, GfxPalette *palette, GfxCache *cache, Cursor *cursor)
- : _s(state), _screen(screen), _palette(palette), _cache(cache), _cursor(cursor), _highPlanePri(0) {
+ : _s(state), _screen(screen), _palette(palette), _cache(cache), _cursor(cursor) {
_compare = new GfxCompare(_s->_segMan, _s->_kernel, _cache, _screen);
+ _frameout = new GfxFrameout(_s->_segMan, _s->resMan, _cache, _screen, _palette);
}
SciGui32::~SciGui32() {
@@ -214,128 +216,32 @@ void SciGui32::moveCursor(Common::Point pos) {
void SciGui32::setCursorZone(Common::Rect zone) {
_cursor->setMoveZone(zone);
}
-
void SciGui32::addScreenItem(reg_t object) {
- _screenItems.push_back(object);
- warning("addScreenItem %X:%X (%s)", object.segment, object.offset, _s->_segMan->getObjectName(object));
+ _frameout->kernelAddScreenItem(object);
}
void SciGui32::deleteScreenItem(reg_t object) {
- for (uint32 itemNr = 0; itemNr < _screenItems.size(); itemNr++) {
- if (_screenItems[itemNr] == object) {
- _screenItems.remove_at(itemNr);
- return;
- }
- }
+ _frameout->kernelDeleteScreenItem(object);
}
void SciGui32::addPlane(reg_t object) {
- _planes.push_back(object);
- byte planePri = GET_SEL32V(_s->_segMan, object, priority) & 0xFF;
- if (planePri > _highPlanePri)
- _highPlanePri = planePri;
+ _frameout->kernelAddPlane(object);
}
void SciGui32::updatePlane(reg_t object) {
+ _frameout->kernelUpdatePlane(object);
}
void SciGui32::deletePlane(reg_t object) {
- for (uint32 planeNr = 0; planeNr < _planes.size(); planeNr++) {
- if (_planes[planeNr] == object) {
- _planes.remove_at(planeNr);
- break;
- }
- }
-
- // Recalculate highPlanePri
- _highPlanePri = 0;
+ _frameout->kernelDeletePlane(object);
+}
- for (uint32 planeNr = 0; planeNr < _planes.size(); planeNr++) {
- byte planePri = GET_SEL32V(_s->_segMan, _planes[planeNr], priority) & 0xFF;
- if (planePri > _highPlanePri)
- _highPlanePri = planePri;
- }
+int16 SciGui32::getHighPlanePri() {
+ return _frameout->kernelGetHighPlanePri();
}
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 (x >= _screen->getWidth()) {
- continue;
- }
-
- if (y >= _screen->getHeight()) {
- continue;
- }
-
- if (viewId != 0xffff) {
- Common::Rect celRect;
- View *view = _cache->getView(viewId);
-
- if ((scaleX == 128) && (scaleY == 128))
- view->getCelRect(loopNo, celNo, x, y, z, &celRect);
- else
- view->getCelScaledRect(loopNo, celNo, x, y, z, scaleX, scaleY, &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);
- }
- }
- }
- }
+ _frameout->kernelFrameout();
_screen->copyToScreen();
}
diff --git a/engines/sci/graphics/gui32.h b/engines/sci/graphics/gui32.h
index e57c972af7..a6f32618a9 100644
--- a/engines/sci/graphics/gui32.h
+++ b/engines/sci/graphics/gui32.h
@@ -30,12 +30,12 @@
namespace Sci {
-class Screen;
-class SciPalette;
class Cursor;
+class GfxScreen;
+class GfxPalette;
class GfxCache;
class GfxCompare;
-class Text;
+class GfxFrameout;
class SciGui32 {
public:
@@ -69,7 +69,7 @@ public:
void addPlane(reg_t object);
void updatePlane(reg_t object);
void deletePlane(reg_t object);
- byte getHighPlanePri() { return _highPlanePri; }
+ int16 getHighPlanePri();
void frameOut();
void globalToLocal(int16 *x, int16 *y, reg_t planeObj);
void localToGlobal(int16 *x, int16 *y, reg_t planeObj);
@@ -88,11 +88,9 @@ protected:
GfxPalette *_palette;
GfxCache *_cache;
GfxCompare *_compare;
+ GfxFrameout *_frameout;
private:
- Common::Array<reg_t> _screenItems;
- Common::Array<reg_t> _planes;
- byte _highPlanePri;
};
} // End of namespace Sci
diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp
index 96683ba344..a2dc25f797 100644
--- a/engines/sci/graphics/picture.cpp
+++ b/engines/sci/graphics/picture.cpp
@@ -117,7 +117,12 @@ void SciGuiPicture::drawSci11Vga() {
}
#ifdef ENABLE_SCI32
-void SciGuiPicture::drawSci32Vga() {
+int16 SciGuiPicture::getSci32celCount() {
+ byte *inbuffer = _resource->data;
+ return inbuffer[2];
+}
+
+void SciGuiPicture::drawSci32Vga(int16 celNo) {
byte *inbuffer = _resource->data;
int size = _resource->size;
int header_size = READ_LE_UINT16(inbuffer);
@@ -128,9 +133,19 @@ void SciGuiPicture::drawSci32Vga() {
int cel_relXpos, cel_relYpos;
Palette palette;
- // Create palette and set it
- _palette->createFromData(inbuffer + palette_data_ptr, &palette);
- _palette->set(&palette, true);
+ // HACK
+ _mirroredFlag = false;
+ _addToFlag = false;
+
+ if ((celNo == -1) || (celNo == 0)) {
+ // Create palette and set it
+ _palette->createFromData(inbuffer + palette_data_ptr, &palette);
+ _palette->set(&palette, true);
+ }
+ if (celNo != -1) {
+ cel_headerPos += 42 * celNo;
+ celCount = 1;
+ }
while (celCount > 0) {
cel_RlePos = READ_LE_UINT16(inbuffer + cel_headerPos + 24);
diff --git a/engines/sci/graphics/picture.h b/engines/sci/graphics/picture.h
index 38dc17fed0..85c2696533 100644
--- a/engines/sci/graphics/picture.h
+++ b/engines/sci/graphics/picture.h
@@ -44,13 +44,15 @@ public:
GuiResourceId getResourceId();
void draw(int16 animationNr, bool mirroredFlag, bool addToFlag, int16 EGApaletteNo);
+#ifdef ENABLE_SCI32
+ int16 getSci32celCount();
+ void drawSci32Vga(int16 celNo = -1);
+#endif
+
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);
diff --git a/engines/sci/module.mk b/engines/sci/module.mk
index 23e1606078..c6ecf07f2c 100644
--- a/engines/sci/module.mk
+++ b/engines/sci/module.mk
@@ -39,6 +39,7 @@ MODULE_OBJS := \
graphics/controls.o \
graphics/cursor.o \
graphics/font.o \
+ graphics/frameout.o \
graphics/gui.o \
graphics/menu.o \
graphics/paint16.o \