Major V7 update with vertical scrolling. Added a few scumm vars related to scrolling. Dig inventory isn't displayed where it should. I hope it doesn't break anything else in other game...

svn-id: r4066
This commit is contained in:
Vincent Hamm 2002-04-23 23:58:31 +00:00
parent 72798160d8
commit 20e9ad5e23
8 changed files with 80 additions and 35 deletions

73
gfx.cpp
View file

@ -51,23 +51,23 @@ void Scumm::initScreens(int a, int b, int w, int h)
int i; int i;
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
// nukeResource(rtBuffer, i+1); nukeResource(rtBuffer, i+1);
nukeResource(rtBuffer, i + 5); nukeResource(rtBuffer, i + 5);
} }
if (!getResourceAddress(rtBuffer, 4)) { 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(0, 0, b, 320, h - b, true, true);
initVirtScreen(1, 0, b, false, false); initVirtScreen(1, 0, 0, 320, b, false, false);
initVirtScreen(2, h, 200 - h, false, false); initVirtScreen(2, 0, h, 320, 200 - h, false, false);
_screenB = b; _screenB = b;
_screenH = h; _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) bool fourextra)
{ {
VirtScreen *vs = &virtscr[slot]; VirtScreen *vs = &virtscr[slot];
@ -92,9 +92,10 @@ void Scumm::initVirtScreen(int slot, int top, int height, bool twobufs,
if (vs->scrollable) if (vs->scrollable)
size += 320 * 4; 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; ptr = vs->screenPtr;
for (i = 0; i < size; i++) // reset background ? for (i = 0; i < size; i++) // reset background ?
@ -130,6 +131,7 @@ void Scumm::drawDirtyScreenParts()
{ {
int i; int i;
VirtScreen *vs; VirtScreen *vs;
byte * src;
updateDirtyScreen(2); updateDirtyScreen(2);
if (_features & GF_OLD256) if (_features & GF_OLD256)
@ -141,9 +143,10 @@ void Scumm::drawDirtyScreenParts()
updateDirtyScreen(0); updateDirtyScreen(0);
} else { } else {
vs = &virtscr[0]; vs = &virtscr[0];
_system->copy_rect(vs->screenPtr + _screenStartStrip * 8, 320, src = vs->screenPtr + _screenStartStrip * 8 + camera._cur.y - 100;
0, vs->topline, 320, vs->height);
_system->copy_rect(src , 320, 0, vs->topline, 320, vs->height);
for (i = 0; i < 40; i++) { for (i = 0; i < 40; i++) {
vs->tdirty[i] = (byte)vs->height; vs->tdirty[i] = (byte)vs->height;
@ -180,6 +183,9 @@ void Gdi::updateDirtyScreen(VirtScreen * vs)
for (i = 0; i < 40; i++) { for (i = 0; i < 40; i++) {
bottom = vs->bdirty[i]; bottom = vs->bdirty[i];
if (_vm->camera._cur.y != _vm->camera._last.y)
drawStripToScreen(vs, start, w, 0, vs->height);
else
if (bottom) { if (bottom) {
top = vs->tdirty[i]; top = vs->tdirty[i];
vs->tdirty[i] = (byte)vs->height; vs->tdirty[i] = (byte)vs->height;
@ -189,7 +195,8 @@ void Gdi::updateDirtyScreen(VirtScreen * vs)
w += 8; w += 8;
continue; continue;
} }
drawStripToScreen(vs, start, w, top, bottom); // drawStripToScreen(vs, start, w, top, bottom);
drawStripToScreen(vs, start, w, 0, vs->height);
w = 8; w = 8;
} }
start = i + 1; 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) void Gdi::drawStripToScreen(VirtScreen * vs, int x, int w, int t, int b)
{ {
byte *ptr; byte *ptr;
int scrollY;
int width = w;
int height;
height = b - t;
if(height > 200)
height = 200;
if (b <= t) if (b <= t)
return; return;
@ -209,15 +224,20 @@ void Gdi::drawStripToScreen(VirtScreen * vs, int x, int w, int t, int b)
if (b > vs->height) if (b > vs->height)
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( _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) void blit(byte *dst, byte *src, int w, int h)
{ {
assert(h > 0); assert(h > 0);
do { do {
memcpy(dst, src, w); memcpy(dst, src, w);
dst += 320; dst += 320;
@ -332,12 +352,17 @@ void Scumm::setCameraFollows(Actor * a)
} }
} }
void Scumm::initBGBuffers() void Scumm::initBGBuffers(int height)
{ {
byte *ptr; byte *ptr;
int size, itemsize, i; int size, itemsize, i;
byte *room; byte *room;
if (_features & GF_AFTER_V7)
{
initVirtScreen(0, 0, virtscr[0].topline, 200, height, 1, 1);
}
room = getResourceAddress(rtRoom, _roomResource); room = getResourceAddress(rtRoom, _roomResource);
if (_features & GF_SMALL_HEADER) { if (_features & GF_SMALL_HEADER) {
gdi._numZBuffer = 2; // ENDER gdi._numZBuffer = 2; // ENDER
@ -347,7 +372,8 @@ void Scumm::initBGBuffers()
} }
assert(gdi._numZBuffer >= 1 && gdi._numZBuffer <= 5); 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; size = itemsize * gdi._numZBuffer;
createResource(rtBuffer, 9, size); createResource(rtBuffer, 9, size);
@ -671,7 +697,7 @@ void Gdi::drawBitmap(byte *ptr, VirtScreen * vs, int x, int y, int h,
bottom = y + h; bottom = y + h;
if (bottom > vs->height) { 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); vs->height);
} }
@ -1902,7 +1928,11 @@ void Scumm::moveCamera()
if (cd->_cur.x != old.x || cd->_cur.y != old.y) { if (cd->_cur.x != old.x || cd->_cur.y != old.y) {
_vars[VAR_CAMERA_POS_X] = cd->_cur.x; _vars[VAR_CAMERA_POS_X] = cd->_cur.x;
_vars[VAR_CAMERA_POS_Y] = cd->_cur.y; _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 { } else {
CameraData *cd = &camera; CameraData *cd = &camera;
@ -2173,7 +2203,8 @@ void Scumm::resetActorBgs()
while (onlyActorFlags) { while (onlyActorFlags) {
if (onlyActorFlags & 1 && a->top != 0xFF && a->needBgReset) { if (onlyActorFlags & 1 && a->top != 0xFF && a->needBgReset) {
gfxUsageBits[_screenStartStrip + i] ^= bitpos; 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; bitpos <<= 1;
onlyActorFlags >>= 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]; VirtScreen *vs = &_vm->virtscr[0];
int offs; int offs;
@ -2197,7 +2228,7 @@ void Gdi::resetBackground(byte top, byte bottom, int strip)
if (bottom > vs->bdirty[strip]) if (bottom > vs->bdirty[strip])
vs->bdirty[strip] = bottom; vs->bdirty[strip] = bottom;
offs = (top * 40 + _vm->_screenStartStrip + strip); offs = (top * 40 + _vm->_screenStartStrip + strip );
_mask_ptr = _vm->getResourceAddress(rtBuffer, 9) + offs; _mask_ptr = _vm->getResourceAddress(rtBuffer, 9) + offs;
_bgbak_ptr = _vm->getResourceAddress(rtBuffer, 5) + (offs << 3); _bgbak_ptr = _vm->getResourceAddress(rtBuffer, 5) + (offs << 3);
_backbuff_ptr = vs->screenPtr + (offs << 3); _backbuff_ptr = vs->screenPtr + (offs << 3);

8
gfx.h
View file

@ -106,8 +106,8 @@ struct Gdi {
byte _disable_zbuffer; byte _disable_zbuffer;
bool _useOrDecompress; bool _useOrDecompress;
byte _numLinesToProcess; int _numLinesToProcess;
byte _tempNumLines; int _tempNumLines;
byte _currentX; byte _currentX;
byte _hotspot_x; byte _hotspot_x;
byte _hotspot_y; byte _hotspot_y;
@ -132,7 +132,7 @@ struct Gdi {
byte _palette_mod; byte _palette_mod;
byte _decomp_shr, _decomp_mask; byte _decomp_shr, _decomp_mask;
byte _transparency; byte _transparency;
uint16 _vertStripNextInc; uint32 _vertStripNextInc;
byte *_backupIsWhere; byte *_backupIsWhere;
/* Bitmap decompressors */ /* Bitmap decompressors */
@ -161,7 +161,7 @@ struct Gdi {
void decompressMaskImgOr(); void decompressMaskImgOr();
void decompressMaskImg(); 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 drawStripToScreen(VirtScreen *vs, int x, int w, int t, int b);
void updateDirtyScreen(VirtScreen *vs); void updateDirtyScreen(VirtScreen *vs);

View file

@ -683,9 +683,6 @@ byte *Scumm::createResource(int type, int idx, uint32 size)
CHECK_HEAP debug(9, "createResource(%d,%d,%d)", type, idx, 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); validateResource("allocating", type, idx);
nukeResource(type, idx); nukeResource(type, idx);

View file

@ -175,7 +175,7 @@ bool Scumm::loadState(int slot, bool compat)
if (_features & GF_AFTER_V7) if (_features & GF_AFTER_V7)
cameraMoved(); cameraMoved();
initBGBuffers(); initBGBuffers(_scrHeight);
CHECK_HEAP debug(1, "State loaded from '%s'", filename); CHECK_HEAP debug(1, "State loaded from '%s'", filename);

View file

@ -1145,8 +1145,8 @@ public:
void getGraphicsPerformance(); void getGraphicsPerformance();
void initScreens(int a, int b, int w, int h); void initScreens(int a, int b, int w, int h);
void initVirtScreen(int slot, int top, int height, bool twobufs, bool fourextra); void initVirtScreen(int slot, int number, int top, int width, int height, bool twobufs, bool fourextra);
void initBGBuffers(); void initBGBuffers(int height);
void initCycl(byte *ptr); // Color cycle void initCycl(byte *ptr); // Color cycle
void createSpecialPalette(int16 a, int16 b, int16 c, int16 d, int16 e, int16 colorMin, int16 colorMax); 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_SPEED_Y;
byte VAR_CAMERA_ACCEL_X; byte VAR_CAMERA_ACCEL_X;
byte VAR_CAMERA_ACCEL_Y; 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_LEFTBTN_DOWN;
byte VAR_RIGHTBTN_DOWN; byte VAR_RIGHTBTN_DOWN;

View file

@ -328,6 +328,7 @@ int Scumm::scummLoop(int delta)
if (camera._cur.x != camera._last.x || camera._cur.y != camera._last.y if (camera._cur.x != camera._last.x || camera._cur.y != camera._last.y
|| _BgNeedsRedraw || _fullRedraw) { || _BgNeedsRedraw || _fullRedraw) {
redrawBGAreas(); redrawBGAreas();
_videoBuffer = virtscr[0].screenPtr + (camera._cur.y - 100) * 328;
} }
} }
processDrawQue(); processDrawQue();
@ -456,6 +457,7 @@ void Scumm::startScene(int room, Actor * a, int objectNr)
if (!(_features & GF_AFTER_V7)) { if (!(_features & GF_AFTER_V7)) {
camera._mode = CM_NORMAL; camera._mode = CM_NORMAL;
camera._cur.x = camera._dest.x = 160; camera._cur.x = camera._dest.x = 160;
camera._cur.y = camera._dest.y = 100;
} }
if (_features & GF_AFTER_V6) { if (_features & GF_AFTER_V6) {
@ -707,7 +709,9 @@ void Scumm::initRoomSubBlocks()
else else
gdi._transparency = 255; gdi._transparency = 255;
initBGBuffers(); initBGBuffers(_scrHeight);
_videoBuffer = virtscr[0].screenPtr;
memset(_extraBoxFlags, 0, sizeof(_extraBoxFlags)); memset(_extraBoxFlags, 0, sizeof(_extraBoxFlags));
} }
@ -817,7 +821,11 @@ void Scumm::processKbd()
getKeyInput(0); getKeyInput(0);
_virtual_mouse_x = mouse.x + virtscr[0].xstart; _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)) if (!(_features & GF_OLD256))
_virtual_mouse_y += virtscr[0].topline; _virtual_mouse_y += virtscr[0].topline;
@ -1251,10 +1259,10 @@ void Scumm::launch()
_minHeapThreshold = 400000; _minHeapThreshold = 400000;
/* Create a primary virtual screen */ /* Create a primary virtual screen */
_videoBuffer = (byte*)malloc(328*200); _videoBuffer = (byte*)malloc(328*800);
allocResTypeData(rtBuffer, MKID('NONE'), 10, "buffer", 0); 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) if (_features & GF_AFTER_V7)
setupScummVarsNew(); setupScummVarsNew();

View file

@ -237,6 +237,8 @@ void Scumm::CHARSET_1()
string[0].ypos = ((a->new_1 - s) >> 1) + s - a->elevation + a->y; string[0].ypos = ((a->new_1 - s) >> 1) + s - a->elevation + a->y;
if (string[0].ypos < 1) if (string[0].ypos < 1)
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; s = a->scalex * a->new_2 / 0xFF;
string[0].xpos = ((a->new_2 - s) >> 1) + s + a->x - camera._cur.x + 160; string[0].xpos = ((a->new_2 - s) >> 1) + s + a->x - camera._cur.x + 160;

View file

@ -140,6 +140,10 @@ void Scumm::setupScummVarsNew()
VAR_NEW_ROOM = 35; VAR_NEW_ROOM = 35;
VAR_WALKTO_OBJ = 36; VAR_WALKTO_OBJ = 36;
VAR_CAMERA_DEST_X = 38;
VAR_CAMERA_DEST_Y = 39;
VAR_CAMERA_FOLLOWED_ACTOR = 40;
VAR_SCROLL_SCRIPT = 50; VAR_SCROLL_SCRIPT = 50;
VAR_ENTRY_SCRIPT = 51; VAR_ENTRY_SCRIPT = 51;
VAR_ENTRY_SCRIPT2 = 52; VAR_ENTRY_SCRIPT2 = 52;