aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/graphics
diff options
context:
space:
mode:
authorMartin Kiewitz2010-07-26 14:41:19 +0000
committerMartin Kiewitz2010-07-26 14:41:19 +0000
commite3e2ae799e59a6245a43c21629313ee3a948e9ce (patch)
treea87cac69656dcb3d0defc781ea2919d8b3ce25fd /engines/sci/graphics
parent756d5e28479bb74ad011be3fc3aff50a222b6325 (diff)
downloadscummvm-rg350-e3e2ae799e59a6245a43c21629313ee3a948e9ce.tar.gz
scummvm-rg350-e3e2ae799e59a6245a43c21629313ee3a948e9ce.tar.bz2
scummvm-rg350-e3e2ae799e59a6245a43c21629313ee3a948e9ce.zip
SCI: adding scrollcapability to sci32
svn-id: r51313
Diffstat (limited to 'engines/sci/graphics')
-rw-r--r--engines/sci/graphics/frameout.cpp123
-rw-r--r--engines/sci/graphics/frameout.h19
-rw-r--r--engines/sci/graphics/picture.cpp7
-rw-r--r--engines/sci/graphics/picture.h1
4 files changed, 105 insertions, 45 deletions
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp
index df1273933a..ffa90e8e1f 100644
--- a/engines/sci/graphics/frameout.cpp
+++ b/engines/sci/graphics/frameout.cpp
@@ -68,7 +68,6 @@ void GfxFrameout::kernelAddPlane(reg_t object) {
newPlane.object = object;
newPlane.pictureId = 0xFFFF;
- newPlane.picture = NULL;
newPlane.lastPriority = 0xFFFF; // hidden
_planes.push_back(newPlane);
@@ -84,13 +83,11 @@ void GfxFrameout::kernelUpdatePlane(reg_t object) {
it->pictureId = readSelectorValue(_segMan, object, SELECTOR(picture));
if (lastPictureId != it->pictureId) {
// picture got changed, load new picture
+ deletePlanePictures(object);
if ((it->pictureId != 0xFFFF) && (it->pictureId != 0xFFFE)) {
// SQ6 gives us a bad picture number for the control menu
if (_resMan->testResource(ResourceId(kResourceTypePic, it->pictureId)))
- it->picture = new GfxPicture(_resMan, _coordAdjuster, 0, _screen, _palette, it->pictureId, false);
- } else {
- delete it->picture;
- it->picture = NULL;
+ addPlanePicture(object, it->pictureId, 0);
}
}
sortPlanes();
@@ -101,6 +98,7 @@ void GfxFrameout::kernelUpdatePlane(reg_t object) {
}
void GfxFrameout::kernelDeletePlane(reg_t object) {
+ deletePlanePictures(object);
for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); it++) {
if (it->object == object) {
_planes.erase(it);
@@ -121,6 +119,26 @@ void GfxFrameout::kernelDeletePlane(reg_t object) {
}
}
+void GfxFrameout::addPlanePicture(reg_t object, GuiResourceId pictureId, uint16 startX) {
+ PlanePictureEntry newPicture;
+ newPicture.object = object;
+ newPicture.pictureId = pictureId;
+ newPicture.picture = new GfxPicture(_resMan, _coordAdjuster, 0, _screen, _palette, pictureId, false);
+ newPicture.startX = startX;
+ _planePictures.push_back(newPicture);
+}
+
+void GfxFrameout::deletePlanePictures(reg_t object) {
+ for (PlanePictureList::iterator it = _planePictures.begin(); it != _planePictures.end(); it++) {
+ if (it->object == object) {
+ delete it->picture;
+ _planePictures.erase(it);
+ deletePlanePictures(object);
+ return;
+ }
+ }
+}
+
void GfxFrameout::kernelAddScreenItem(reg_t object) {
_screenItems.push_back(object);
}
@@ -141,11 +159,7 @@ int16 GfxFrameout::kernelGetHighPlanePri() {
// No idea yet how to implement this
void GfxFrameout::kernelAddPicAt(reg_t planeObj, int16 forWidth, GuiResourceId pictureId) {
- //if (forWidth == 320) {
- // writeSelectorValue(_segMan, planeObj, SELECTOR(left), 0);
- // writeSelectorValue(_segMan, planeObj, SELECTOR(picture), pictureId);
- // kernelUpdatePlane(planeObj);
- //}
+ addPlanePicture(planeObj, pictureId, forWidth);
}
bool sortHelper(const FrameoutEntry* entry1, const FrameoutEntry* entry2) {
@@ -247,20 +261,14 @@ void GfxFrameout::kernelFrameout() {
if (planeBack)
_paint32->fillRect(planeRect, planeBack);
- GuiResourceId planePictureNr = it->pictureId;
- GfxPicture *planePicture = it->picture;
- int16 planePictureCels = 0;
- bool planePictureMirrored = false;
+ GuiResourceId planeMainPictureId = it->pictureId;
- if (planePicture) {
- planePictureCels = planePicture->getSci32celCount();
+ bool planePictureMirrored = false;
+ if (readSelectorValue(_segMan, planeObject, SELECTOR(mirrored)))
+ planePictureMirrored = true;
- _coordAdjuster->pictureSetDisplayArea(planeRect);
- _palette->drewPicture(planePictureNr);
-
- if (readSelectorValue(_segMan, planeObject, SELECTOR(mirrored)))
- planePictureMirrored = true;
- }
+ _coordAdjuster->pictureSetDisplayArea(planeRect);
+ _palette->drewPicture(planeMainPictureId);
// Fill our itemlist for this plane
int16 itemCount = 0;
@@ -302,23 +310,28 @@ void GfxFrameout::kernelFrameout() {
}
}
- FrameoutEntry *pictureCels = NULL;
-
- if (planePicture) {
- // Allocate memory for picture cels
- pictureCels = new FrameoutEntry[planePicture->getSci32celCount()];
- // Add following cels to the itemlist
- FrameoutEntry *picEntry = pictureCels;
- for (int pictureCelNr = 0; pictureCelNr < planePictureCels; pictureCelNr++) {
- picEntry->celNo = pictureCelNr;
- picEntry->object = NULL_REG;
- picEntry->y = planePicture->getSci32celY(pictureCelNr);
- picEntry->x = planePicture->getSci32celX(pictureCelNr);
-
- picEntry->priority = planePicture->getSci32celPriority(pictureCelNr);
-
- itemList.push_back(picEntry);
- picEntry++;
+ for (PlanePictureList::iterator pictureIt = _planePictures.begin(); pictureIt != _planePictures.end(); pictureIt++) {
+ if (pictureIt->object == planeObject) {
+ GfxPicture *planePicture = pictureIt->picture;
+ // Allocate memory for picture cels
+ pictureIt->pictureCels = new FrameoutEntry[planePicture->getSci32celCount()];
+
+ // Add following cels to the itemlist
+ FrameoutEntry *picEntry = pictureIt->pictureCels;
+ int planePictureCels = planePicture->getSci32celCount();
+ for (int pictureCelNr = 0; pictureCelNr < planePictureCels; pictureCelNr++) {
+ picEntry->celNo = pictureCelNr;
+ picEntry->object = NULL_REG;
+ picEntry->picture = planePicture;
+ picEntry->y = planePicture->getSci32celY(pictureCelNr);
+ picEntry->x = planePicture->getSci32celX(pictureCelNr);
+ picEntry->picStartX = pictureIt->startX;
+
+ picEntry->priority = planePicture->getSci32celPriority(pictureCelNr);
+
+ itemList.push_back(picEntry);
+ picEntry++;
+ }
}
}
@@ -337,9 +350,31 @@ void GfxFrameout::kernelFrameout() {
// Picture cel data
itemEntry->y = ((itemEntry->y * _screen->getHeight()) / scriptsRunningHeight);
itemEntry->x = ((itemEntry->x * _screen->getWidth()) / scriptsRunningWidth);
+ itemEntry->picStartX = ((itemEntry->picStartX * _screen->getWidth()) / scriptsRunningWidth);
+
+ // Out of view
+ int16 pictureCelStartX = itemEntry->picStartX + itemEntry->x;
+ int16 pictureCelEndX = pictureCelStartX + itemEntry->picture->getSci32celWidth(itemEntry->celNo);
+ int16 planeStartX = planeOffsetX;
+ int16 planeEndX = planeStartX + planeRect.width();
+ if (pictureCelEndX < planeStartX)
+ continue;
+ if (pictureCelStartX > planeEndX)
+ continue;
- planePicture->drawSci32Vga(itemEntry->celNo, itemEntry->x, itemEntry->y, planeOffsetX, planePictureMirrored);
-// warning("picture cel %d %d", itemEntry->celNo, itemEntry->priority);
+ int16 pictureOffsetX = planeOffsetX;
+ int16 pictureX = itemEntry->x;
+ if (planeOffsetX) {
+ if (planeOffsetX <= itemEntry->picStartX) {
+ pictureX += itemEntry->picStartX - planeOffsetX;
+ pictureOffsetX = 0;
+ } else {
+ pictureOffsetX = planeOffsetX - itemEntry->picStartX;
+ }
+ }
+
+ itemEntry->picture->drawSci32Vga(itemEntry->celNo, pictureX, itemEntry->y, pictureOffsetX, planePictureMirrored);
+ warning("picture cel %d %d", itemEntry->celNo, itemEntry->priority);
} else if (itemEntry->viewId != 0xFFFF) {
GfxView *view = _cache->getView(itemEntry->viewId);
@@ -468,8 +503,10 @@ void GfxFrameout::kernelFrameout() {
}
}
- if (planePicture) {
- delete[] pictureCels;
+ for (PlanePictureList::iterator pictureIt = _planePictures.begin(); pictureIt != _planePictures.end(); pictureIt++) {
+ if (pictureIt->object == planeObject) {
+ delete[] pictureIt->pictureCels;
+ }
}
}
diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h
index beb89d5d71..f8f7e54a27 100644
--- a/engines/sci/graphics/frameout.h
+++ b/engines/sci/graphics/frameout.h
@@ -31,9 +31,8 @@ namespace Sci {
struct PlaneEntry {
reg_t object;
uint16 priority;
- GuiResourceId pictureId;
- GfxPicture *picture;
uint16 lastPriority;
+ GuiResourceId pictureId;
};
typedef Common::List<PlaneEntry> PlaneList;
@@ -51,10 +50,22 @@ struct FrameoutEntry {
int16 scaleX;
int16 scaleY;
Common::Rect celRect;
+ GfxPicture *picture;
+ int16 picStartX;
};
typedef Common::List<FrameoutEntry *> FrameoutList;
+struct PlanePictureEntry {
+ reg_t object;
+ int16 startX;
+ GuiResourceId pictureId;
+ GfxPicture *picture;
+ FrameoutEntry *pictureCels; // temporary
+};
+
+typedef Common::List<PlanePictureEntry> PlanePictureList;
+
class GfxCache;
class GfxCoordAdjuster32;
class GfxPaint32;
@@ -77,6 +88,9 @@ public:
void kernelAddPicAt(reg_t planeObj, int16 forWidth, GuiResourceId pictureId);
void kernelFrameout();
+ void addPlanePicture(reg_t object, GuiResourceId pictureId, uint16 startX);
+ void deletePlanePictures(reg_t object);
+
private:
SegManager *_segMan;
ResourceManager *_resMan;
@@ -88,6 +102,7 @@ private:
Common::Array<reg_t> _screenItems;
PlaneList _planes;
+ PlanePictureList _planePictures;
void sortPlanes();
diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp
index e10a319c4c..b31036daa8 100644
--- a/engines/sci/graphics/picture.cpp
+++ b/engines/sci/graphics/picture.cpp
@@ -146,6 +146,13 @@ int16 GfxPicture::getSci32celX(int16 celNo) {
return READ_LE_UINT16(inbuffer + cel_headerPos + 38);
}
+int16 GfxPicture::getSci32celWidth(int16 celNo) {
+ byte *inbuffer = _resource->data;
+ int header_size = READ_LE_UINT16(inbuffer);
+ int cel_headerPos = header_size + 42 * celNo;
+ return READ_LE_UINT16(inbuffer + cel_headerPos + 0);
+}
+
int16 GfxPicture::getSci32celPriority(int16 celNo) {
byte *inbuffer = _resource->data;
int header_size = READ_LE_UINT16(inbuffer);
diff --git a/engines/sci/graphics/picture.h b/engines/sci/graphics/picture.h
index b3a0a1509c..7cd0d71b67 100644
--- a/engines/sci/graphics/picture.h
+++ b/engines/sci/graphics/picture.h
@@ -58,6 +58,7 @@ public:
int16 getSci32celCount();
int16 getSci32celY(int16 celNo);
int16 getSci32celX(int16 celNo);
+ int16 getSci32celWidth(int16 celNo);
int16 getSci32celPriority(int16 celNo);
void drawSci32Vga(int16 celNo, int16 callerX, int16 callerY, int16 pictureX, bool mirrored);
#endif