diff options
-rw-r--r-- | gfx.cpp | 73 | ||||
-rw-r--r-- | gfx.h | 8 | ||||
-rw-r--r-- | resource.cpp | 3 | ||||
-rw-r--r-- | saveload.cpp | 2 | ||||
-rw-r--r-- | scumm.h | 7 | ||||
-rw-r--r-- | scummvm.cpp | 16 | ||||
-rw-r--r-- | string.cpp | 2 | ||||
-rw-r--r-- | vars.cpp | 4 |
8 files changed, 80 insertions, 35 deletions
@@ -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); @@ -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); @@ -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; @@ -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; |