aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gfx.cpp73
-rw-r--r--gfx.h8
-rw-r--r--resource.cpp3
-rw-r--r--saveload.cpp2
-rw-r--r--scumm.h7
-rw-r--r--scummvm.cpp16
-rw-r--r--string.cpp2
-rw-r--r--vars.cpp4
8 files changed, 80 insertions, 35 deletions
diff --git a/gfx.cpp b/gfx.cpp
index f0d60ea375..c2bffae476 100644
--- a/gfx.cpp
+++ b/gfx.cpp
@@ -51,23 +51,23 @@ void Scumm::initScreens(int a, int b, int w, int h)
int i;
for (i = 0; i < 3; i++) {
-// nukeResource(rtBuffer, i+1);
+ nukeResource(rtBuffer, i+1);
nukeResource(rtBuffer, i + 5);
}
if (!getResourceAddress(rtBuffer, 4)) {
- initVirtScreen(3, 80, 13, false, false);
+ initVirtScreen(3, 0, 80, 320, 13, false, false);
}
- initVirtScreen(0, b, h - b, true, true);
- initVirtScreen(1, 0, b, false, false);
- initVirtScreen(2, h, 200 - h, false, false);
+ initVirtScreen(0, 0, b, 320, h - b, true, true);
+ initVirtScreen(1, 0, 0, 320, b, false, false);
+ initVirtScreen(2, 0, h, 320, 200 - h, false, false);
_screenB = b;
_screenH = h;
}
-void Scumm::initVirtScreen(int slot, int top, int height, bool twobufs,
+void Scumm::initVirtScreen(int slot, int number, int top, int width, int height, bool twobufs,
bool fourextra)
{
VirtScreen *vs = &virtscr[slot];
@@ -92,9 +92,10 @@ void Scumm::initVirtScreen(int slot, int top, int height, bool twobufs,
if (vs->scrollable)
size += 320 * 4;
-// createResource(rtBuffer, slot+1, size);
- vs->screenPtr = _videoBuffer + 328 * top;
+ createResource(rtBuffer, slot+1, size);
+
+ vs->screenPtr = getResourceAddress(rtBuffer, slot+1);
ptr = vs->screenPtr;
for (i = 0; i < size; i++) // reset background ?
@@ -130,6 +131,7 @@ void Scumm::drawDirtyScreenParts()
{
int i;
VirtScreen *vs;
+ byte * src;
updateDirtyScreen(2);
if (_features & GF_OLD256)
@@ -141,9 +143,10 @@ void Scumm::drawDirtyScreenParts()
updateDirtyScreen(0);
} else {
vs = &virtscr[0];
-
- _system->copy_rect(vs->screenPtr + _screenStartStrip * 8, 320,
- 0, vs->topline, 320, vs->height);
+
+ src = vs->screenPtr + _screenStartStrip * 8 + camera._cur.y - 100;
+
+ _system->copy_rect(src , 320, 0, vs->topline, 320, vs->height);
for (i = 0; i < 40; i++) {
vs->tdirty[i] = (byte)vs->height;
@@ -180,6 +183,9 @@ void Gdi::updateDirtyScreen(VirtScreen * vs)
for (i = 0; i < 40; i++) {
bottom = vs->bdirty[i];
+ if (_vm->camera._cur.y != _vm->camera._last.y)
+ drawStripToScreen(vs, start, w, 0, vs->height);
+ else
if (bottom) {
top = vs->tdirty[i];
vs->tdirty[i] = (byte)vs->height;
@@ -189,7 +195,8 @@ void Gdi::updateDirtyScreen(VirtScreen * vs)
w += 8;
continue;
}
- drawStripToScreen(vs, start, w, top, bottom);
+ // drawStripToScreen(vs, start, w, top, bottom);
+ drawStripToScreen(vs, start, w, 0, vs->height);
w = 8;
}
start = i + 1;
@@ -199,6 +206,14 @@ void Gdi::updateDirtyScreen(VirtScreen * vs)
void Gdi::drawStripToScreen(VirtScreen * vs, int x, int w, int t, int b)
{
byte *ptr;
+ int scrollY;
+ int width = w;
+ int height;
+
+ height = b - t;
+
+ if(height > 200)
+ height = 200;
if (b <= t)
return;
@@ -209,15 +224,20 @@ void Gdi::drawStripToScreen(VirtScreen * vs, int x, int w, int t, int b)
if (b > vs->height)
b = vs->height;
- ptr = vs->screenPtr + (t * 40 + x) * 8 + _readOffs;
+ scrollY = _vm->camera._cur.y - 100;
+ if(scrollY == -100)
+ scrollY = 0;
+
+ ptr = vs->screenPtr + (t * 40 + x) * 8 + _readOffs + scrollY * 320;
_vm->_system->copy_rect(
- ptr, 320, x * 8, vs->topline + t, w, b - t);
+ ptr, 320, x * 8, vs->topline + t , w, height);
}
void blit(byte *dst, byte *src, int w, int h)
{
assert(h > 0);
+
do {
memcpy(dst, src, w);
dst += 320;
@@ -332,12 +352,17 @@ void Scumm::setCameraFollows(Actor * a)
}
}
-void Scumm::initBGBuffers()
+void Scumm::initBGBuffers(int height)
{
byte *ptr;
int size, itemsize, i;
byte *room;
+ if (_features & GF_AFTER_V7)
+ {
+ initVirtScreen(0, 0, virtscr[0].topline, 200, height, 1, 1);
+ }
+
room = getResourceAddress(rtRoom, _roomResource);
if (_features & GF_SMALL_HEADER) {
gdi._numZBuffer = 2; // ENDER
@@ -347,7 +372,8 @@ void Scumm::initBGBuffers()
}
assert(gdi._numZBuffer >= 1 && gdi._numZBuffer <= 5);
- itemsize = (_scrHeight + 4) * 40;
+// itemsize = (_scrHeight + 4) * 40;
+ itemsize = (virtscr[0].height +4) * 40;
size = itemsize * gdi._numZBuffer;
createResource(rtBuffer, 9, size);
@@ -671,7 +697,7 @@ void Gdi::drawBitmap(byte *ptr, VirtScreen * vs, int x, int y, int h,
bottom = y + h;
if (bottom > vs->height) {
- error("Gdi::drawBitmap, strip drawn to %d below window bottom %d", bottom,
+ warning("Gdi::drawBitmap, strip drawn to %d below window bottom %d", bottom,
vs->height);
}
@@ -1902,7 +1928,11 @@ void Scumm::moveCamera()
if (cd->_cur.x != old.x || cd->_cur.y != old.y) {
_vars[VAR_CAMERA_POS_X] = cd->_cur.x;
_vars[VAR_CAMERA_POS_Y] = cd->_cur.y;
- runScript(_vars[VAR_SCROLL_SCRIPT], 0, 0, 0);
+ _vars[VAR_CAMERA_DEST_X] = cd->_dest.x;
+ _vars[VAR_CAMERA_DEST_Y] = cd->_dest.y;
+ _vars[VAR_CAMERA_FOLLOWED_ACTOR] = cd ->_follows;
+ if(_vars[VAR_SCROLL_SCRIPT])
+ runScript(_vars[VAR_SCROLL_SCRIPT], 0, 0, 0);
}
} else {
CameraData *cd = &camera;
@@ -2173,7 +2203,8 @@ void Scumm::resetActorBgs()
while (onlyActorFlags) {
if (onlyActorFlags & 1 && a->top != 0xFF && a->needBgReset) {
gfxUsageBits[_screenStartStrip + i] ^= bitpos;
- gdi.resetBackground(a->top, a->bottom, i);
+ if((a->bottom - a->top) >=0)
+ gdi.resetBackground(a->top, a->bottom, i);
}
bitpos <<= 1;
onlyActorFlags >>= 1;
@@ -2186,7 +2217,7 @@ void Scumm::resetActorBgs()
}
}
-void Gdi::resetBackground(byte top, byte bottom, int strip)
+void Gdi::resetBackground(int top, int bottom, int strip)
{
VirtScreen *vs = &_vm->virtscr[0];
int offs;
@@ -2197,7 +2228,7 @@ void Gdi::resetBackground(byte top, byte bottom, int strip)
if (bottom > vs->bdirty[strip])
vs->bdirty[strip] = bottom;
- offs = (top * 40 + _vm->_screenStartStrip + strip);
+ offs = (top * 40 + _vm->_screenStartStrip + strip );
_mask_ptr = _vm->getResourceAddress(rtBuffer, 9) + offs;
_bgbak_ptr = _vm->getResourceAddress(rtBuffer, 5) + (offs << 3);
_backbuff_ptr = vs->screenPtr + (offs << 3);
diff --git a/gfx.h b/gfx.h
index 0e747a067d..0206f32d5a 100644
--- a/gfx.h
+++ b/gfx.h
@@ -106,8 +106,8 @@ struct Gdi {
byte _disable_zbuffer;
bool _useOrDecompress;
- byte _numLinesToProcess;
- byte _tempNumLines;
+ int _numLinesToProcess;
+ int _tempNumLines;
byte _currentX;
byte _hotspot_x;
byte _hotspot_y;
@@ -132,7 +132,7 @@ struct Gdi {
byte _palette_mod;
byte _decomp_shr, _decomp_mask;
byte _transparency;
- uint16 _vertStripNextInc;
+ uint32 _vertStripNextInc;
byte *_backupIsWhere;
/* Bitmap decompressors */
@@ -161,7 +161,7 @@ struct Gdi {
void decompressMaskImgOr();
void decompressMaskImg();
- void resetBackground(byte top, byte bottom, int strip);
+ void resetBackground(int top, int bottom, int strip);
void drawStripToScreen(VirtScreen *vs, int x, int w, int t, int b);
void updateDirtyScreen(VirtScreen *vs);
diff --git a/resource.cpp b/resource.cpp
index 2d33eaad13..d89df0abeb 100644
--- a/resource.cpp
+++ b/resource.cpp
@@ -683,9 +683,6 @@ byte *Scumm::createResource(int type, int idx, uint32 size)
CHECK_HEAP debug(9, "createResource(%d,%d,%d)", type, idx, size);
- if (size > 65536 * 4 + 37856)
- warning("Probably invalid size allocating %d", size);
-
validateResource("allocating", type, idx);
nukeResource(type, idx);
diff --git a/saveload.cpp b/saveload.cpp
index ccfbd5d92f..9d0db96f18 100644
--- a/saveload.cpp
+++ b/saveload.cpp
@@ -175,7 +175,7 @@ bool Scumm::loadState(int slot, bool compat)
if (_features & GF_AFTER_V7)
cameraMoved();
- initBGBuffers();
+ initBGBuffers(_scrHeight);
CHECK_HEAP debug(1, "State loaded from '%s'", filename);
diff --git a/scumm.h b/scumm.h
index b864586fb7..ed8e3dfffd 100644
--- a/scumm.h
+++ b/scumm.h
@@ -1145,8 +1145,8 @@ public:
void getGraphicsPerformance();
void initScreens(int a, int b, int w, int h);
- void initVirtScreen(int slot, int top, int height, bool twobufs, bool fourextra);
- void initBGBuffers();
+ void initVirtScreen(int slot, int number, int top, int width, int height, bool twobufs, bool fourextra);
+ void initBGBuffers(int height);
void initCycl(byte *ptr); // Color cycle
void createSpecialPalette(int16 a, int16 b, int16 c, int16 d, int16 e, int16 colorMin, int16 colorMax);
@@ -1692,6 +1692,9 @@ public:
byte VAR_CAMERA_SPEED_Y;
byte VAR_CAMERA_ACCEL_X;
byte VAR_CAMERA_ACCEL_Y;
+ byte VAR_CAMERA_DEST_X;
+ byte VAR_CAMERA_DEST_Y;
+ byte VAR_CAMERA_FOLLOWED_ACTOR;
byte VAR_LEFTBTN_DOWN;
byte VAR_RIGHTBTN_DOWN;
diff --git a/scummvm.cpp b/scummvm.cpp
index 3f5aa7eab5..15e418e4fc 100644
--- a/scummvm.cpp
+++ b/scummvm.cpp
@@ -328,6 +328,7 @@ int Scumm::scummLoop(int delta)
if (camera._cur.x != camera._last.x || camera._cur.y != camera._last.y
|| _BgNeedsRedraw || _fullRedraw) {
redrawBGAreas();
+ _videoBuffer = virtscr[0].screenPtr + (camera._cur.y - 100) * 328;
}
}
processDrawQue();
@@ -456,6 +457,7 @@ void Scumm::startScene(int room, Actor * a, int objectNr)
if (!(_features & GF_AFTER_V7)) {
camera._mode = CM_NORMAL;
camera._cur.x = camera._dest.x = 160;
+ camera._cur.y = camera._dest.y = 100;
}
if (_features & GF_AFTER_V6) {
@@ -707,7 +709,9 @@ void Scumm::initRoomSubBlocks()
else
gdi._transparency = 255;
- initBGBuffers();
+ initBGBuffers(_scrHeight);
+
+ _videoBuffer = virtscr[0].screenPtr;
memset(_extraBoxFlags, 0, sizeof(_extraBoxFlags));
}
@@ -817,7 +821,11 @@ void Scumm::processKbd()
getKeyInput(0);
_virtual_mouse_x = mouse.x + virtscr[0].xstart;
- _virtual_mouse_y = mouse.y;
+
+ if(_features & GF_AFTER_V7)
+ _virtual_mouse_y = mouse.y + camera._cur.y-100;
+ else
+ _virtual_mouse_y = mouse.y;
if (!(_features & GF_OLD256))
_virtual_mouse_y += virtscr[0].topline;
@@ -1251,10 +1259,10 @@ void Scumm::launch()
_minHeapThreshold = 400000;
/* Create a primary virtual screen */
- _videoBuffer = (byte*)malloc(328*200);
+ _videoBuffer = (byte*)malloc(328*800);
allocResTypeData(rtBuffer, MKID('NONE'), 10, "buffer", 0);
- initVirtScreen(0, 0, 200, false, false);
+ initVirtScreen(0, 0, 0, 320, 200, false, false);
if (_features & GF_AFTER_V7)
setupScummVarsNew();
diff --git a/string.cpp b/string.cpp
index 873a525743..6ddb6381ec 100644
--- a/string.cpp
+++ b/string.cpp
@@ -237,6 +237,8 @@ void Scumm::CHARSET_1()
string[0].ypos = ((a->new_1 - s) >> 1) + s - a->elevation + a->y;
if (string[0].ypos < 1)
string[0].ypos = 1;
+ if (string[0].ypos < camera._cur.y - 100)
+ string[0].ypos = camera._cur.y - 100;
s = a->scalex * a->new_2 / 0xFF;
string[0].xpos = ((a->new_2 - s) >> 1) + s + a->x - camera._cur.x + 160;
diff --git a/vars.cpp b/vars.cpp
index eb2c8a88b2..300dc5d0ef 100644
--- a/vars.cpp
+++ b/vars.cpp
@@ -140,6 +140,10 @@ void Scumm::setupScummVarsNew()
VAR_NEW_ROOM = 35;
VAR_WALKTO_OBJ = 36;
+ VAR_CAMERA_DEST_X = 38;
+ VAR_CAMERA_DEST_Y = 39;
+ VAR_CAMERA_FOLLOWED_ACTOR = 40;
+
VAR_SCROLL_SCRIPT = 50;
VAR_ENTRY_SCRIPT = 51;
VAR_ENTRY_SCRIPT2 = 52;