aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudvig Strigeus2001-12-27 17:51:58 +0000
committerLudvig Strigeus2001-12-27 17:51:58 +0000
commit5a7b86cbf6d31b94e95843f7324052dea561e10d (patch)
tree025539c4ed59c91eb0a7f711c7916f8e26402c53
parent1caad519e208320033b4560074d6d25467cd7648 (diff)
downloadscummvm-rg350-5a7b86cbf6d31b94e95843f7324052dea561e10d.tar.gz
scummvm-rg350-5a7b86cbf6d31b94e95843f7324052dea561e10d.tar.bz2
scummvm-rg350-5a7b86cbf6d31b94e95843f7324052dea561e10d.zip
better full throttle support,
a couple of MI2 fixes. svn-id: r3532
-rw-r--r--actor.cpp239
-rw-r--r--akos.cpp237
-rw-r--r--boxes.cpp16
-rw-r--r--costume.cpp224
-rw-r--r--debug.cpp14
-rw-r--r--gfx.cpp405
-rw-r--r--object.cpp58
-rw-r--r--resource.cpp31
-rw-r--r--saveload.cpp38
-rw-r--r--script.cpp15
-rw-r--r--script_v1.cpp56
-rw-r--r--script_v2.cpp228
-rw-r--r--scumm.h153
-rw-r--r--scummvm.cpp183
-rw-r--r--scummvm.dsp2
-rw-r--r--sdl.cpp16
-rw-r--r--sound.cpp2
-rw-r--r--string.cpp14
-rw-r--r--verbs.cpp9
-rw-r--r--windows.cpp445
20 files changed, 1278 insertions, 1107 deletions
diff --git a/actor.cpp b/actor.cpp
index 7d499c12c7..a7673ac08d 100644
--- a/actor.cpp
+++ b/actor.cpp
@@ -29,8 +29,10 @@ void Scumm::initActor(Actor *a, int mode) {
a->x = 0;
a->y = 0;
a->facing = 180;
+ a->newDirection = 180;
} else if (mode==2) {
a->facing = 180;
+ a->newDirection = 180;
}
a->elevation = 0;
@@ -49,8 +51,11 @@ void Scumm::initActor(Actor *a, int mode) {
a->sound[6] = 0;
a->sound[7] = 0;
a->newDirection = 0;
- a->moving = 0;
- a->unk1 = 0;
+
+ stopActorMoving(a);
+
+ a->shadow_mode = 0;
+ a->layer = 0;
setActorWalkSpeed(a, 8, 2);
@@ -63,7 +68,19 @@ void Scumm::initActor(Actor *a, int mode) {
a->talkFrame1 = 4;
a->talkFrame2 = 5;
- _classData[a->number] = 0;
+ a->walk_script = 0;
+ a->talk_script = 0;
+
+ if (_features & GF_AFTER_V7) {
+ _classData[a->number] = _classData[0];
+ } else {
+ _classData[a->number] = 0;
+ }
+}
+
+void Scumm::stopActorMoving(Actor *a) {
+ stopScriptNr(a->walk_script);
+ a->moving = 0;
}
void Scumm::setActorWalkSpeed(Actor *a, uint speedx, uint speedy) {
@@ -183,12 +200,18 @@ int Scumm::remapDirection(Actor *a, int dir) {
int Scumm::updateActorDirection(Actor *a) {
int from,to;
int diff;
+ int dirType;
+ int num;
- from = toSimpleDir(a->facing);
- to = toSimpleDir(remapDirection(a, a->newDirection));
+ dirType = akos_hasManyDirections(a);
+
+ from = toSimpleDir(dirType, a->facing);
+ to = toSimpleDir(dirType, remapDirection(a, a->newDirection));
diff = to - from;
- if (abs(diff) > 2)
+ num = numSimpleDirDirections(dirType);
+
+ if (abs(diff) > (num>>1))
diff = -diff;
if (diff==0) {
@@ -198,7 +221,7 @@ int Scumm::updateActorDirection(Actor *a) {
from--;
}
- return fromSimpleDir(from&3);
+ return fromSimpleDir(dirType, from & (num-1));
}
void Scumm::setActorBox(Actor *a, int box) {
@@ -271,6 +294,7 @@ int Scumm::actorWalkStep(Actor *a) {
void Scumm::setupActorScale(Actor *a) {
uint16 scale;
byte *resptr;
+ int y;
if (a->ignoreBoxes != 0)
return;
@@ -282,9 +306,12 @@ void Scumm::setupActorScale(Actor *a) {
resptr = getResourceAddress(rtScaleTable, scale);
if (resptr==NULL)
error("Scale table %d not defined",scale);
- if (a->y >= 0)
- resptr += a->y;
- scale = *resptr;
+ y = a->y;
+ if (y>=200)
+ y=199;
+ if (y<0)
+ y=0;
+ scale = resptr[y];
}
if (scale>255)
@@ -294,60 +321,57 @@ void Scumm::setupActorScale(Actor *a) {
a->scaley = (byte)scale;
}
-#if defined(FULL_THROTTLE)
void Scumm::startAnimActor(Actor *a, int frame) {
- switch(frame) {
- case 1001: frame = a->initFrame; break;
- case 1002: frame = a->walkFrame; break;
- case 1003: frame = a->standFrame; break;
- case 1004: frame = a->talkFrame1; break;
- case 1005: frame = a->talkFrame2; break;
- }
+ if (_features & GF_NEW_COSTUMES) {
+ switch(frame) {
+ case 1001: frame = a->initFrame; break;
+ case 1002: frame = a->walkFrame; break;
+ case 1003: frame = a->standFrame; break;
+ case 1004: frame = a->talkFrame1; break;
+ case 1005: frame = a->talkFrame2; break;
+ }
- if (a->costume != 0) {
- a->animProgress = 0;
- a->needRedraw = true;
- a->needBgReset = true;
- if (frame == a->initFrame)
- initActorCostumeData(a);
- akos_decodeData(a, frame, (uint)-1);
- }
-}
-#else
-void Scumm::startAnimActor(Actor *a, int frame) {
- if (frame==0x38)
- frame = a->initFrame;
+ if (a->costume != 0) {
+ a->animProgress = 0;
+ a->needRedraw = true;
+ a->needBgReset = true;
+ if (frame == a->initFrame)
+ initActorCostumeData(a);
+ akos_decodeData(a, frame, (uint)-1);
+ }
- if (frame==0x39)
- frame = a->walkFrame;
+ } else {
+ if (frame==0x38)
+ frame = a->initFrame;
- if (frame==0x3A)
- frame = a->standFrame;
+ if (frame==0x39)
+ frame = a->walkFrame;
- if (frame==0x3B)
- frame = a->talkFrame1;
+ if (frame==0x3A)
+ frame = a->standFrame;
- if (frame==0x3C)
- frame = a->talkFrame2;
+ if (frame==0x3B)
+ frame = a->talkFrame1;
- if (a->room == _currentRoom && a->costume) {
- a->animProgress = 0;
- a->cost.animCounter1 = 0;
- a->needRedraw = true;
-
- cost.loadCostume(a->costume);
+ if (frame==0x3C)
+ frame = a->talkFrame2;
+
+ if (a->room == _currentRoom && a->costume) {
+ a->animProgress = 0;
+ a->cost.animCounter1 = 0;
+ a->needRedraw = true;
- if (a->initFrame==frame)
- initActorCostumeData(a);
+ if (a->initFrame==frame)
+ initActorCostumeData(a);
- if (frame!=0x3E) {
- decodeCostData(a, frame, -1);
+ if (frame!=0x3E) {
+ cost_decodeData(a, frame, -1);
+ }
}
- }
- a->needBgReset = true;
+ a->needBgReset = true;
+ }
}
-#endif
void Scumm::fixActorDirection(Actor *a, int direction) {
uint mask;
@@ -362,17 +386,13 @@ void Scumm::fixActorDirection(Actor *a, int direction) {
if (a->costume==0)
return;
-#if !defined(FULL_THROTTLE)
- cost.loadCostume(a->costume);
-#endif
-
mask = 0x8000;
for (i=0; i<16; i++,mask>>=1) {
vald = a->cost.frame[i];
if (vald==0xFFFF)
continue;
#if !defined(FULL_THROTTLE)
- decodeCostData(a, vald, mask);
+ cost_decodeData(a, vald, mask);
#else
akos_decodeData(a, vald, mask);
#endif
@@ -755,7 +775,7 @@ void Scumm::processActors() {
ac2 = actors;
cnt2 = numactors;
do {
- if ( (*ac2)->y > (*ac)->y ) {
+ if ( (*ac2)->y - ((*ac2)->layer<<11) > (*ac)->y - ((*ac)->layer<<11) ) {
tmp = *ac;
*ac = *ac2;
*ac2 = tmp;
@@ -777,49 +797,46 @@ void Scumm::processActors() {
} while (ac++,--cnt);
}
-void Scumm::setupCostumeRenderer(CostumeRenderer *c, Actor *a) {
- c->_actorX = a->x - virtscr->xstart;
- c->_actorY = a->y - a->elevation;
- c->_zbuf = a->mask;
- if (c->_zbuf > gdi._numZBuffer)
- c->_zbuf = (byte)gdi._numZBuffer;
- if (a->forceClip)
- c->_zbuf = a->forceClip;
-
- c->_scaleX = a->scalex;
- c->_scaleY = a->scaley;
-}
-
-void Scumm::setActorCostPalette(Actor *a) {
- int i;
- byte color;
-
- cost.loadCostume(a->costume);
-
- for (i=0; i<cost._numColors; i++) {
- color = a->palette[i];
- if (color==255)
- color = cost._ptr[8+i];
- cost._palette[i] = color;
- }
-}
-
#if !defined(FULL_THROTTLE)
void Scumm::drawActorCostume(Actor *a) {
+ CostumeRenderer cr;
+
if (a==NULL || !a->needRedraw)
return;
+ a->needRedraw = false;
+
setupActorScale(a);
- setupCostumeRenderer(&cost, a);
- setActorCostPalette(a);
+
+ cr._actorX = a->x - virtscr->xstart;
+ cr._actorY = a->y - a->elevation;
+ cr._scaleX = a->scalex;
+ cr._scaleY = a->scaley;
+
+ cr._outheight = virtscr->height;
+ cr._vm = this;
+
+ cr._zbuf = a->mask;
+ if (cr._zbuf > gdi._numZBuffer)
+ cr._zbuf = (byte)gdi._numZBuffer;
+ if (a->forceClip)
+ cr._zbuf = a->forceClip;
+
+ cr._shadow_table = _shadowPalette;
+
+ cost_setCostume(&cr, a->costume);
+ cost_setPalette(&cr, a->palette);
+ cost_setFacing(&cr, a);
a->top = 0xFF;
- a->needRedraw = 0;
+
a->bottom = 0;
- cost.loadCostume(a->costume);
- cost._mirror = newDirToOldDir(a->facing)!=0 || (cost._ptr[7]&0x80);
- cost.drawCostume(a);
+ /* if the actor is partially hidden, redraw it next frame */
+ if(cr.drawCostume(a)&1) {
+ a->needBgReset = true;
+ a->needRedraw = true;
+ }
}
#else
void Scumm::drawActorCostume(Actor *a) {
@@ -842,11 +859,15 @@ void Scumm::drawActorCostume(Actor *a) {
if (ar.clipping > (byte)gdi._numZBuffer)
ar.clipping = gdi._numZBuffer;
}
+ ar.charsetmask = _vars[VAR_CHARSET_MASK]!=0;
ar.outptr = getResourceAddress(rtBuffer, 1) + virtscr->xstart;
ar.outwidth = virtscr->width;
ar.outheight = virtscr->height;
+ ar.shadow_mode = a->shadow_mode;
+ ar.shadow_table = _shadowPalette;
+
akos_setCostume(&ar, a->costume);
akos_setPalette(&ar, a->palette);
akos_setFacing(&ar, a);
@@ -864,7 +885,11 @@ void Scumm::drawActorCostume(Actor *a) {
#endif
void Scumm::actorAnimate(Actor *a) {
+#if defined(FULL_THROTTLE)
byte *akos;
+#else
+ LoadedCostume lc;
+#endif
if (a==NULL || a->costume == 0)
return;
@@ -878,8 +903,8 @@ void Scumm::actorAnimate(Actor *a) {
assert(akos);
if (akos_increaseAnims(akos, a)) {
#else
- cost.loadCostume(a->costume);
- if (cost.animate(a)) {
+ loadCostume(&lc, a->costume);
+ if (cost_increaseAnims(&lc, a)) {
#endif
a->needRedraw = true;
a->needBgReset = true;
@@ -1087,7 +1112,7 @@ void Scumm::remapActor(Actor *a, int r_fact, int g_fact, int b_fact, int thresho
akpl_color=*akpl++;
// allow remap of generic palette entry?
- if (!a->unk1 || akpl_color>=16) {
+ if (!a->shadow_mode || akpl_color>=16) {
if (r_fact!=256) r = (r*r_fact) >> 8;
if (g_fact!=256) g = (g*g_fact) >> 8;
if (b_fact!=256) b = (b*b_fact) >> 8;
@@ -1097,5 +1122,29 @@ void Scumm::remapActor(Actor *a, int r_fact, int g_fact, int b_fact, int thresho
}
void Scumm::setupShadowPalette(int slot,int rfact,int gfact,int bfact,int from,int to) {
- warning("stub setupShadowPalette(%d,%d,%d,%d,%d,%d)", slot,rfact,gfact,bfact,from,to);
+ byte *table;
+ int i,num;
+ byte *curpal;
+
+ if (slot<0 || slot > 7)
+ error("setupShadowPalette: invalid slot %d", slot);
+
+ if (from<0 || from>255 || to<0 || from>255 || to < from)
+ error("setupShadowPalette: invalid range from %d to %d", from, to);
+
+ table = _shadowPalette + slot * 256;
+ for(i=0; i<256; i++)
+ table[i] = i;
+
+ table += from;
+ curpal = _currentPalette + from*3;
+ num = to - from + 1;
+ do {
+ *table++ = remapPaletteColor(
+ curpal[0] * rfact >> 8,
+ curpal[1] * gfact >> 8,
+ curpal[2] * bfact >> 8,
+ (uint)-1);
+ curpal+=3;
+ } while (--num);
}
diff --git a/akos.cpp b/akos.cpp
index accefa1e53..cc23a27c65 100644
--- a/akos.cpp
+++ b/akos.cpp
@@ -21,16 +21,18 @@
#include "stdafx.h"
#include "scumm.h"
-#if defined(FULL_THROTTLE)
-
bool Scumm::akos_hasManyDirections(Actor *a) {
- byte *akos;
- AkosHeader *akhd;
+ if (_features & GF_NEW_COSTUMES) {
+ byte *akos;
+ AkosHeader *akhd;
- akos = getResourceAddress(rtCostume, a->costume);
- assert(akos);
- akhd = (AkosHeader*)findResource(MKID('AKHD'), akos);
- return (akhd->flags&2) != 0;
+ akos = getResourceAddress(rtCostume, a->costume);
+ assert(akos);
+
+ akhd = (AkosHeader*)findResourceData(MKID('AKHD'), akos);
+ return (akhd->flags&2) != 0;
+ }
+ return 0;
}
@@ -60,7 +62,7 @@ void Scumm::akos_decodeData(Actor *a, int frame, uint usemask) {
akos = getResourceAddress(rtCostume, a->costume);
assert(akos);
- akhd = (AkosHeader*)findResource(MKID('AKHD'), akos);
+ akhd = (AkosHeader*)findResourceData(MKID('AKHD'), akos);
if (anim>=READ_LE_UINT16(&akhd->num_anims))
return;
@@ -121,9 +123,8 @@ void Scumm::akos_setPalette(AkosRenderer *ar, byte *palette) {
byte *akos, *akpl;
uint size, i;
- akpl = findResource(MKID('AKPL'), ar->akos);
- size = READ_BE_UINT32_UNALIGNED(akpl+4) - 8;
- akpl += 8;
+ akpl = findResourceData(MKID('AKPL'), ar->akos);
+ size = getResourceDataSize(akpl);
if (size > 256)
error("akos_setPalette: %d is too many colors", size);
@@ -137,12 +138,12 @@ void Scumm::akos_setCostume(AkosRenderer *ar, int costume) {
ar->akos = getResourceAddress(rtCostume, costume);
assert(ar->akos);
- ar->akhd = (AkosHeader*)findResource(MKID('AKHD'), ar->akos);
- ar->akof = (AkosOffset*)(findResource(MKID('AKOF'), ar->akos)+8);
- ar->akci = (findResource(MKID('AKCI'), ar->akos)+8);
- ar->aksq = (findResource(MKID('AKSQ'), ar->akos)+8);
- ar->akcd = (findResource(MKID('AKCD'), ar->akos)+8);
- ar->akpl = (findResource(MKID('AKPL'), ar->akos)+8);
+ ar->akhd = (AkosHeader*)findResourceData(MKID('AKHD'), ar->akos);
+ ar->akof = (AkosOffset*)findResourceData(MKID('AKOF'), ar->akos);
+ ar->akci = findResourceData(MKID('AKCI'), ar->akos);
+ ar->aksq = findResourceData(MKID('AKSQ'), ar->akos);
+ ar->akcd = findResourceData(MKID('AKCD'), ar->akos);
+ ar->akpl = findResourceData(MKID('AKPL'), ar->akos);
ar->codec = READ_LE_UINT16(&ar->akhd->codec);
}
@@ -188,7 +189,7 @@ bool Scumm::akos_drawCostumeChannel(AkosRenderer *ar, int chan) {
assert( (code&0x7000) == 0);
ar->srcptr = ar->akcd + READ_LE_UINT32(&off->akcd);
- akci = (AkosCI*)ar->akci + READ_LE_UINT16(&off->akci);
+ akci = (AkosCI*)(ar->akci + READ_LE_UINT16(&off->akci));
ar->move_x_cur = ar->move_x + (int16)READ_LE_UINT16(&akci->rel_x);
ar->move_y_cur = ar->move_y + (int16)READ_LE_UINT16(&akci->rel_y);
@@ -264,7 +265,7 @@ void akos_c1_0y_decode(AkosRenderer *ar) {
height = ar->height;
y = ar->v1.y;
- if (ar->v1.doContinue) goto StartPos;
+ if (len) goto StartPos;
do {
len = *src++;
@@ -291,65 +292,133 @@ StartPos:;
} while (1);
}
-#if 0
+void akos_generic_decode(AkosRenderer *ar) {
+ byte *src,*dst;
+ byte len,height,pcolor, maskbit;
+ uint y,scrheight;
+ uint color;
+ int t;
+ const byte *scaleytab, *mask;
+
+
+ y = ar->v1.y;
+
+ len = ar->v1.replen;
+ src = ar->srcptr;
+ dst = ar->v1.destptr;
+ color = ar->v1.repcolor;
+ height = ar->height;
+
+ scaleytab = &ar->v1.scaletable[ar->v1.tmp_y];
+ maskbit = revBitMask[ar->v1.x&7];
+ mask = ar->v1.mask_ptr + (ar->v1.x>>3);
+
+ if (len) goto StartPos;
+
+ do {
+ len = *src++;
+ color = len>>ar->v1.shl;
+ len &= ar->v1.mask;
+ if (!len) len = *src++;
+
+ do {
+ if (*scaleytab++ < ar->scale_y) {
+ if (color && y < ar->outheight && (!ar->v1.mask_ptr || !((mask[0]|mask[ar->v1.imgbufoffs]) & maskbit)) ) {
+ *dst = ar->palette[color];
+ }
+ mask += 40;
+ dst += ar->outwidth;
+ y++;
+ }
+ if (!--height) {
+ if(!--ar->v1.skip_width)
+ return;
+ height = ar->height;
+ y = ar->v1.y;
+
+ scaleytab = &ar->v1.scaletable[ar->v1.tmp_y];
+
+ if (ar->v1.scaletable[ar->v1.tmp_x] < ar->scale_x) {
+ ar->v1.x += ar->v1.scaleXstep;
+ if ((uint)ar->v1.x >= 320)
+ return;
+ maskbit = revBitMask[ar->v1.x&7];
+ ar->v1.destptr += ar->v1.scaleXstep;
+ }
+ mask = ar->v1.mask_ptr + (ar->v1.x>>3);
+ ar->v1.tmp_x += ar->v1.scaleXstep;
+ dst = ar->v1.destptr;
+ }
+StartPos:;
+ } while (--len);
+ } while(1);
+}
+
+
void akos_c1_spec1(AkosRenderer *ar) {
- byte *mask,*src,*dst,*dstorg;
- byte maskbit,len,height,pcolor,width;
- uint y;
- int color;
+ byte *src,*dst;
+ byte len,height,pcolor, maskbit;
+ uint y,scrheight;
+ uint color;
int t;
+ const byte *scaleytab, *mask;
+
- mask = _mask_ptr = ar->v1.mask_ptr_dest;
- maskbit = revBitMask[ar_xpos&7];
- y = _ypos;
+ y = ar->v1.y;
+
+ len = ar->v1.replen;
+ src = ar->srcptr;
+ dst = ar->v1.destptr;
+ color = ar->v1.repcolor;
+ height = ar->height;
- dstorg = dst = _backbuff_ptr;
- height = _height2;
- width = _width2;
- len = _replen;
- color = _repcolor;
- src = _srcptr;
+ scaleytab = &ar->v1.scaletable[ar->v1.tmp_y];
+ maskbit = revBitMask[ar->v1.x&7];
+ mask = ar->v1.mask_ptr + (ar->v1.x>>3);
- if (_docontinue) goto StartPos;
+ if (len) goto StartPos;
do {
len = *src++;
- color = len>>_shrval;
- len &= _maskval;
+ color = len>>ar->v1.shl;
+ len &= ar->v1.mask;
if (!len) len = *src++;
do {
- if (cost_scaleTable[_scaleIndexY++] < _scaleY) {
- if (color && y < _vscreenheight) {
- pcolor = _palette[color];
+ if (*scaleytab++ < ar->scale_y) {
+ if (color && y < ar->outheight && (!ar->v1.mask_ptr || !((mask[0]|mask[ar->v1.imgbufoffs]) & maskbit)) ) {
+ pcolor = ar->palette[color];
if (pcolor==13)
- pcolor = _transEffect[*dst];
+ pcolor = ar->shadow_table[*dst];
*dst = pcolor;
}
- dst += 320;
+ mask += 40;
+ dst += ar->outwidth;
y++;
}
if (!--height) {
- if(!--width)
+ if(!--ar->v1.skip_width)
return;
- height = _height;
- y = _ypostop;
- _scaleIndexY = _scaleIndexYTop;
- t = _scaleIndexX;
- _scaleIndexX = t + _scaleIndexXStep;
- if (cost_scaleTable[t] < _scaleX) {
- _xpos += _scaleIndexXStep;
- if (_xpos >= 320)
+ height = ar->height;
+ y = ar->v1.y;
+
+ scaleytab = &ar->v1.scaletable[ar->v1.tmp_y];
+
+ if (ar->v1.scaletable[ar->v1.tmp_x] < ar->scale_x) {
+ ar->v1.x += ar->v1.scaleXstep;
+ if ((uint)ar->v1.x >= 320)
return;
- _backbuff_ptr += _scaleIndexXStep;
+ maskbit = revBitMask[ar->v1.x&7];
+ ar->v1.destptr += ar->v1.scaleXstep;
}
- dst = _backbuff_ptr;
+ mask = ar->v1.mask_ptr + (ar->v1.x>>3);
+ ar->v1.tmp_x += ar->v1.scaleXstep;
+ dst = ar->v1.destptr;
}
StartPos:;
} while (--len);
} while(1);
}
-#endif
const byte default_scale_table[768] = {
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
@@ -469,7 +538,7 @@ void Scumm::akos_codec1(AkosRenderer *ar) {
ar->v1.scaletable = default_scale_table;
/* Setup color decoding variables */
- num_colors = READ_BE_UINT32_UNALIGNED(ar->akpl-4)-8;
+ num_colors = getResourceDataSize(ar->akpl);
if (num_colors == 32) {
ar->v1.mask = (1<<3)-1;
ar->v1.shl = 3;
@@ -483,8 +552,6 @@ void Scumm::akos_codec1(AkosRenderer *ar) {
use_scaling = (ar->scale_x!=0xFF) || (ar->scale_y!=0xFF);
- use_scaling = false;
-
x = ar->x;
y = ar->y;
@@ -531,7 +598,7 @@ void Scumm::akos_codec1(AkosRenderer *ar) {
j = tmp_x;
for(i=0,skip=0; i<ar->width; i++) {
- if (x_left >= ar->outwidth) {
+ if (x_left >= (int)ar->outwidth) {
tmp_x = j;
skip++;
@@ -596,13 +663,10 @@ void Scumm::akos_codec1(AkosRenderer *ar) {
if ((uint)y_top >= (uint)ar->outheight || y_bottom <= 0)
return;
- if ((uint)x_left >= (uint)ar->outwidth || x_right <= 0)
+ if ((int)x_left >= (int)ar->outwidth || x_right <= 0)
return;
- updateDirtyRect(0, x_left, x_right, y_top, y_bottom, 1<<ar->dirty_id);
-
- ar->v1.doContinue = false;
-
+ ar->v1.replen = 0;
ar->v1.y_pitch = ar->height * ar->outwidth;
if (ar->mirror) {
@@ -613,7 +677,6 @@ void Scumm::akos_codec1(AkosRenderer *ar) {
ar->v1.skip_width -= skip;
akos_codec1_ignorePakCols(ar, skip);
x = 0;
- ar->v1.doContinue = true;
} else {
skip = x_right - ar->outwidth;
if (skip > 0)
@@ -628,7 +691,6 @@ void Scumm::akos_codec1(AkosRenderer *ar) {
ar->v1.skip_width -= skip;
akos_codec1_ignorePakCols(ar, skip);
x = ar->outwidth - 1;
- ar->v1.doContinue = true;
} else {
skip = -1 - x_left;
if (skip > 0)
@@ -642,8 +704,9 @@ void Scumm::akos_codec1(AkosRenderer *ar) {
if (ar->v1.skip_width <= 0 || ar->height<=0)
return;
+ updateDirtyRect(0, x_left, x_right, y_top, y_bottom, 1<<ar->dirty_id);
- y_clipping = (y_bottom > ar->outheight || y_top < 0);
+ y_clipping = ((uint)y_bottom > ar->outheight || y_top < 0);
if ( (uint)y_top > (uint)ar->outheight)
y_top = 0;
@@ -660,8 +723,7 @@ void Scumm::akos_codec1(AkosRenderer *ar) {
ar->v1.destptr = ar->outptr + x + y * ar->outwidth;
- charsetmask = false;
-
+ charsetmask = ar->charsetmask;
masking = false;
if (ar->clipping) {
masking = isMaskActiveAt(x_left, y_top, x_right, y_bottom,
@@ -669,35 +731,35 @@ void Scumm::akos_codec1(AkosRenderer *ar) {
) != 0;
}
- if (masking || charsetmask || ar->actor_unk1) {
+ ar->v1.mask_ptr = NULL;
+
+ if (masking || charsetmask || ar->shadow_mode) {
ar->v1.mask_ptr = getResourceAddress(rtBuffer, 9) + y*40 + _screenStartStrip;
ar->v1.imgbufoffs = gdi._imgBufOffs[ar->clipping];
if (!charsetmask && masking) {
ar->v1.mask_ptr += ar->v1.imgbufoffs;
ar->v1.imgbufoffs = 0;
}
- ar->v1.mask_ptr_dest = ar->v1.mask_ptr + (x >> 3);
}
- ar->actor_unk1 = 0;
-
- if(ar->actor_unk1==0)
- akos_c1_0y_decode(ar);
-
-#if 0
-
- switch(ar->actor_unk1) {
+ switch(ar->shadow_mode) {
case 1:
akos_c1_spec1(ar);
return;
case 2:
- akos_c1_spec2(ar);
+// akos_c1_spec2(ar);
return;
case 3:
- akos_c1_spec3(ar);
+// akos_c1_spec3(ar);
return;
}
+ akos_generic_decode(ar);
+
+ // akos_c1_0y_decode(ar);
+
+#if 0
+
switch(((byte)y_clipping<<3) | ((byte)use_scaling<<2) | ((byte)masking<<1) | (byte)charsetmask) {
case 0: akos_c1_0_decode(ar); break;
case 0+8: akos_c1_0y_decode(ar); break;
@@ -762,14 +824,10 @@ bool Scumm::akos_increaseAnims(byte *akos, Actor *a) {
uint size;
bool result;
- aksq = findResource(MKID('AKSQ'), akos) + 8;
- akfo = findResource(MKID('AKFO'), akos);
+ aksq = findResourceData(MKID('AKSQ'), akos);
+ akfo = findResourceData(MKID('AKFO'), akos);
- size = 0;
- if (akfo) {
- size = (READ_BE_UINT32_UNALIGNED(akfo)-8)>>1;
- akfo += 8;
- }
+ size = getResourceDataSize(akfo)>>1;
result = false;
for(i=0;i!=0x10;i++) {
@@ -1036,7 +1094,4 @@ int Scumm::getAnimVar(Actor *a, byte var) {
void Scumm::setAnimVar(Actor *a, byte var, int value) {
assert(var>=0 && var<=15);
a->animVariable[var] = value;
-}
-
-
-#endif
+} \ No newline at end of file
diff --git a/boxes.cpp b/boxes.cpp
index fc5038760e..2a8c9bf150 100644
--- a/boxes.cpp
+++ b/boxes.cpp
@@ -39,13 +39,13 @@ int Scumm::getBoxScale(int box) {
byte Scumm::getNumBoxes() {
byte *ptr = getResourceAddress(rtMatrix, 2);
- return ptr[8];
+ return ptr[0];
}
Box *Scumm::getBoxBaseAddr(int box) {
byte *ptr = getResourceAddress(rtMatrix, 2);
- checkRange(ptr[8]-1, 0, box, "Illegal box %d");
- return (Box*)(ptr + box*SIZEOF_BOX + 10);
+ checkRange(ptr[0]-1, 0, box, "Illegal box %d");
+ return (Box*)(ptr + box*SIZEOF_BOX + 2);
}
bool Scumm::checkXYInBoxBounds(int b, int x, int y) {
@@ -290,7 +290,7 @@ AdjustBoxResult Scumm::getClosestPtOnBox(int b, int x, int y) {
}
byte *Scumm::getBoxMatrixBaseAddr() {
- byte *ptr = getResourceAddress(rtMatrix, 1) + 8;
+ byte *ptr = getResourceAddress(rtMatrix, 1);
if (*ptr==0xFF) ptr++;
return ptr;
}
@@ -491,16 +491,12 @@ void Scumm::createBoxMatrix() {
createResource(rtMatrix, 4, 1000);
createResource(rtMatrix, 3, 4160); //65 items of something of size 64
- createResource(rtMatrix, 1, BOX_MATRIX_SIZE+8);
+ createResource(rtMatrix, 1, BOX_MATRIX_SIZE);
matrix_ptr = getResourceAddress(rtMatrix, 1);
- /* endian & alignment safe */
- ((uint32*)matrix_ptr)[1] = TO_BE_32(BOX_MATRIX_SIZE+8);
- ((uint32*)matrix_ptr)[0] = MKID('BOXM');
-
_boxMatrixPtr4 = getResourceAddress(rtMatrix, 4);
- _boxMatrixPtr1 = getResourceAddress(rtMatrix, 1) + 8;
+ _boxMatrixPtr1 = getResourceAddress(rtMatrix, 1);
_boxMatrixPtr3 = getResourceAddress(rtMatrix, 3);
_boxPathVertexHeapIndex = _boxMatrixItem = 0;
diff --git a/costume.cpp b/costume.cpp
index ede1fb09db..c0979d3210 100644
--- a/costume.cpp
+++ b/costume.cpp
@@ -82,7 +82,7 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
_maskval = 0xF;
_shrval = 4;
- if (_numColors == 32) {
+ if (_loaded._numColors == 32) {
_maskval = 7;
_shrval = 3;
}
@@ -97,14 +97,14 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
_ymove -= (int16)READ_LE_UINT16(_srcptr+10);
_srcptr += 12;
- switch(_ptr[7]&0x7F) {
+ switch(_loaded._ptr[7]&0x7F) {
case 0x60: case 0x61:
ex1 = _srcptr[0];
ex2 = _srcptr[1];
_srcptr += 2;
if (ex1!=0xFF || ex2!=0xFF) {
- ex1=READ_LE_UINT16(_ptr + _numColors + 10 + ex1*2);
- _srcptr = _ptr + READ_LE_UINT16(_ptr + ex1 + ex2*2) + 14;
+ ex1=READ_LE_UINT16(_loaded._ptr + _loaded._numColors + 10 + ex1*2);
+ _srcptr = _loaded._ptr + READ_LE_UINT16(_loaded._ptr + ex1 + ex2*2) + 14;
}
}
@@ -200,17 +200,17 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
if (_mirror)
_scaleIndexXStep = 1;
_ypostop = _ypos;
- _vscreenheight = _vm->virtscr[0].height;
+
_vm->updateDirtyRect(0, _left, _right+1,_top,_bottom,1<<a->number);
- if (_top >= (int)_vscreenheight || _bottom <= 0)
+ if (_top >= (int)_outheight || _bottom <= 0)
return 0;
_ypitch = _height * 320;
_docontinue = 0;
b = 1;
if (_left > 319 || _right <= 0)
- return 0;
+ return 1;
if (_mirror) {
_ypitch--;
if (scaling==0) {
@@ -250,13 +250,13 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
if (_width2==0)
return 0;
- if ((uint)_top > (uint)_vscreenheight)
+ if ((uint)_top > (uint)_outheight)
_top = 0;
if (_left<0) _left=0;
- if ((uint)_bottom > _vscreenheight)
- _bottom = _vscreenheight;
+ if ((uint)_bottom > _outheight)
+ _bottom = _outheight;
if (a->top > _top)
a->top = _top;
@@ -269,7 +269,6 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
return 2;
}
-
_bgbak_ptr = _vm->getResourceAddress(rtBuffer, 5) + _vm->virtscr[0].xstart + _ypos*320 + _xpos;
_backbuff_ptr = _vm->getResourceAddress(rtBuffer, 1) + _vm->virtscr[0].xstart + _ypos*320 + _xpos;
charsetmask = _vm->hasCharsetMask(_left, _top + _vm->virtscr[0].topline, _right, _vm->virtscr[0].topline + _bottom);
@@ -292,8 +291,8 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) {
CHECK_HEAP
- if (a->unk1) {
- proc_special(a->unk1);
+ if (a->shadow_mode) {
+ proc_special(a->shadow_mode);
return b;
}
@@ -335,7 +334,7 @@ void CostumeRenderer::proc6() {
src = _srcptr;
dst = _backbuff_ptr;
color = _repcolor;
- scrheight = _vscreenheight;
+ scrheight = _outheight;
width = _width2;
height = _height2;
@@ -383,7 +382,7 @@ void CostumeRenderer::proc5() {
dst = _backbuff_ptr;
len = _replen;
color = _repcolor;
- scrheight = _vscreenheight;
+ scrheight = _outheight;
height = _height2;
if (_docontinue) goto StartPos;
@@ -443,7 +442,7 @@ void CostumeRenderer::proc4() {
dst = _backbuff_ptr;
len = _replen;
color = _repcolor;
- scrheight = _vscreenheight;
+ scrheight = _outheight;
height = _height2;
if (_docontinue) goto StartPos;
@@ -515,7 +514,7 @@ void CostumeRenderer::proc3() {
if (!len) len = *src++;
do {
if (cost_scaleTable[_scaleIndexY++] < _scaleY) {
- if (color && y < _vscreenheight && !((*mask|mask[_imgbufoffs])&maskbit)) {
+ if (color && y < _outheight && !((*mask|mask[_imgbufoffs])&maskbit)) {
pcolor = _palette[color];
if (pcolor==13)
pcolor = _transEffect[*dst];
@@ -573,7 +572,7 @@ void CostumeRenderer::proc2() {
if (!len) len = *src++;
do {
if (cost_scaleTable[_scaleIndexY++] < _scaleY) {
- if (color && y < _vscreenheight && !(*mask&maskbit)) {
+ if (color && y < _outheight && !(*mask&maskbit)) {
pcolor = _palette[color];
if (pcolor==13)
pcolor = _transEffect[*dst];
@@ -635,7 +634,7 @@ void CostumeRenderer::proc1() {
do {
if (cost_scaleTable[_scaleIndexY++] < _scaleY) {
- if (color && y < _vscreenheight) {
+ if (color && y < _outheight) {
pcolor = _palette[color];
if (pcolor==13)
pcolor = _transEffect[*dst];
@@ -669,6 +668,7 @@ void CostumeRenderer::proc_special(byte code) {
warning("stub CostumeRenderer::proc_special(%d) not implemented");
}
+#if 0
void CostumeRenderer::loadCostume(int id) {
_ptr = _vm->getResourceAddress(rtCostume, id);
@@ -697,6 +697,7 @@ void CostumeRenderer::loadCostume(int id) {
_dataptr = _ptr + READ_LE_UINT16(_ptr + _numColors + 8);
}
+#endif
void Scumm::initActorCostumeData(Actor *a) {
CostumeData *cd = &a->cost;
@@ -719,10 +720,10 @@ byte CostumeRenderer::drawOneSlot(Actor *a, int slot) {
return 0;
i = cd->curpos[slot]&0x7FFF;
- _frameptr = _ptr + READ_LE_UINT16(_ptr + _numColors + slot*2 + 10);
- code = _dataptr[i]&0x7F;
+ _frameptr = _loaded._ptr + READ_LE_UINT16(_loaded._ptr + _loaded._numColors + slot*2 + 10);
+ code = _loaded._dataptr[i]&0x7F;
- _srcptr = _ptr + READ_LE_UINT16(_frameptr + code*2);
+ _srcptr = _loaded._ptr + READ_LE_UINT16(_frameptr + code*2);
if (code != 0x7B) {
return mainRoutine(a, slot, code);
@@ -738,98 +739,68 @@ byte CostumeRenderer::drawCostume(Actor *a) {
byte r = 0;
_xmove = _ymove = 0;
- for (i=0; i<16; i++)
+ for (i=0; i!=16; i++)
r|=drawOneSlot(a, i);
return r;
}
-byte CostumeRenderer::animateOneSlot(Actor *a, int slot) {
- int highflag;
- int i,end;
- byte code,nc;
-
- if (a->cost.curpos[slot]==0xFFFF)
- return 0;
-
- highflag = a->cost.curpos[slot]&0x8000;
- i = a->cost.curpos[slot]&0x7FFF;
- end = a->cost.end[slot];
- code=_dataptr[i]&0x7F;
-
- do {
- if (!highflag) {
- if (i++ >= end)
- i = a->cost.start[slot];
- } else {
- if (i != end)
- i++;
- }
-
- nc = _dataptr[i];
-
- if (nc==0x7C) {
- a->cost.animCounter1++;
- if(a->cost.start[slot] != end)
- continue;
- } else {
- if (_vm->_features&GF_AFTER_V6) {
- if (nc>=0x71 && nc<=0x78) {
- _vm->addSoundToQueue2(a->sound[nc-0x71]);
- if(a->cost.start[slot] != end)
- continue;
- }
- } else {
- if (nc==0x78) {
- a->cost.animCounter2++;
- if(a->cost.start[slot] != end)
- continue;
- }
- }
- }
-
- a->cost.curpos[slot] = i|highflag;
- return (_dataptr[i]&0x7F) != code;
- } while(1);
+int Scumm::cost_frameToAnim(Actor *a, int frame) {
+ return newDirToOldDir(a->facing) + frame * 4;
}
-byte CostumeRenderer::animate(Actor *a) {
- int i;
- byte r = 0;
+void Scumm::loadCostume(LoadedCostume *lc, int costume) {
+ lc->_ptr = getResourceAddress(rtCostume, costume);
+
+ if (_features&GF_AFTER_V6) {
+ lc->_ptr += 8;
+ } else {
+ lc->_ptr += 2;
+ }
-#if !defined(FULL_THROTTLE)
- for (i=0; i<16; i++) {
- if(a->cost.curpos[i]!=0xFFFF)
- r+=animateOneSlot(a, i);
+ switch(lc->_ptr[7]&0x7F) {
+ case 0x58:
+ lc->_numColors = 16;
+ break;
+ case 0x59:
+ lc->_numColors = 32;
+ break;
+ case 0x60: /* New since version 6 */
+ lc->_numColors = 16;
+ break;
+ case 0x61: /* New since version 6 */
+ lc->_numColors = 32;
+ break;
+ default:
+ error("Costume %d is invalid", costume);
}
-#endif
- return r;
-}
-int Scumm::cost_frameToAnim(Actor *a, int frame) {
- return newDirToOldDir(a->facing) + frame * 4;
+ lc->_dataptr = lc->_ptr + READ_LE_UINT16(lc->_ptr + lc->_numColors + 8);
}
-void Scumm::decodeCostData(Actor *a, int frame, uint usemask) {
+void Scumm::cost_decodeData(Actor *a, int frame, uint usemask) {
byte *p,*r;
uint mask,j;
int i;
byte extra,cmd;
byte *dataptr;
int anim;
+ LoadedCostume lc;
+
+ loadCostume(&lc, a->costume);
anim = cost_frameToAnim(a, frame);
- p = cost._ptr;
+ p = lc._ptr;
if (anim > p[6]) {
return;
}
- r = p + READ_LE_UINT16(p + anim*2 + cost._numColors + 42);
+ r = p + READ_LE_UINT16(p + anim*2 + lc._numColors + 42);
if (r==p) {
return;
}
- dataptr = p + READ_LE_UINT16(p + cost._numColors + 8);
+ dataptr = p + READ_LE_UINT16(p + lc._numColors + 8);
mask = READ_LE_UINT16(r);
r+=2;
@@ -868,3 +839,84 @@ void Scumm::decodeCostData(Actor *a, int frame, uint usemask) {
mask <<= 1;
} while ((uint16)mask);
}
+
+void Scumm::cost_setPalette(CostumeRenderer *cr, byte *palette) {
+ int i;
+ byte color;
+
+ for (i=0; i<cr->_loaded._numColors; i++) {
+ color = palette[i];
+ if (color==255)
+ color = cr->_loaded._ptr[8+i];
+ cr->_palette[i] = color;
+ }
+}
+
+void Scumm::cost_setFacing(CostumeRenderer *cr, Actor *a) {
+ cr->_mirror = newDirToOldDir(a->facing)!=0 || (cr->_loaded._ptr[7]&0x80);
+}
+
+void Scumm::cost_setCostume(CostumeRenderer *cr, int costume) {
+ loadCostume(&cr->_loaded, costume);
+}
+
+byte Scumm::cost_increaseAnims(LoadedCostume *lc, Actor *a) {
+ int i;
+ byte r = 0;
+
+ for (i=0; i!=16; i++) {
+ if(a->cost.curpos[i]!=0xFFFF)
+ r+=cost_increaseAnim(lc, a, i);
+ }
+ return r;
+}
+
+byte Scumm::cost_increaseAnim(LoadedCostume *lc, Actor *a, int slot) {
+ int highflag;
+ int i,end;
+ byte code,nc;
+
+ if (a->cost.curpos[slot]==0xFFFF)
+ return 0;
+
+ highflag = a->cost.curpos[slot]&0x8000;
+ i = a->cost.curpos[slot]&0x7FFF;
+ end = a->cost.end[slot];
+ code=lc->_dataptr[i]&0x7F;
+
+ do {
+ if (!highflag) {
+ if (i++ >= end)
+ i = a->cost.start[slot];
+ } else {
+ if (i != end)
+ i++;
+ }
+
+ nc = lc->_dataptr[i];
+
+ if (nc==0x7C) {
+ a->cost.animCounter1++;
+ if(a->cost.start[slot] != end)
+ continue;
+ } else {
+ if (_features&GF_AFTER_V6) {
+ if (nc>=0x71 && nc<=0x78) {
+ addSoundToQueue2(a->sound[nc-0x71]);
+ if(a->cost.start[slot] != end)
+ continue;
+ }
+ } else {
+ if (nc==0x78) {
+ a->cost.animCounter2++;
+ if(a->cost.start[slot] != end)
+ continue;
+ }
+ }
+ }
+
+ a->cost.curpos[slot] = i|highflag;
+ return (lc->_dataptr[i]&0x7F) != code;
+ } while(1);
+}
+
diff --git a/debug.cpp b/debug.cpp
index 5dd4c5f7fa..8e17616c2e 100644
--- a/debug.cpp
+++ b/debug.cpp
@@ -37,6 +37,7 @@ enum {
CMD_GO,
CMD_ACTOR,
CMD_SCRIPTS,
+ CMD_LOAD_ROOM,
CMD_EXIT
};
@@ -65,6 +66,7 @@ bool ScummDebugger::do_command() {
"(q)uit -> quit the debugger\n"
"(g)o [numframes] -> increase frame\n"
"(a)ctor [actornum] -> show actor information\n"
+ "(r)oom roomnum -> load room\n"
"(s)cripts -> show running scripts\n"
"(e)xit -> exit game\n"
);
@@ -89,6 +91,17 @@ bool ScummDebugger::do_command() {
case CMD_SCRIPTS:
printScripts();
return true;
+ case CMD_LOAD_ROOM:
+ if (!_parameters[0]) {
+ printf("Enter a room number...\n");
+ } else {
+ int room=atoi(_parameters);
+ _s->actor[_s->_vars[VAR_EGO]].room=room;
+ _s->startScene(room, 0, 0);
+ _s->_fullRedraw = 1;
+ }
+ return true;
+
case CMD_EXIT:
exit(1);
}
@@ -130,6 +143,7 @@ static const DebuggerCommands debugger_commands[] = {
{ "g", 1, CMD_GO },
{ "a", 1, CMD_ACTOR },
{ "s", 1, CMD_SCRIPTS },
+ { "r", 1, CMD_LOAD_ROOM },
{ "e", 1, CMD_EXIT },
{ 0, 0, 0 },
};
diff --git a/gfx.cpp b/gfx.cpp
index ab24c92081..1c9282b6db 100644
--- a/gfx.cpp
+++ b/gfx.cpp
@@ -107,7 +107,12 @@ void Scumm::drawDirtyScreenParts() {
updateDirtyScreen(2);
- if (camera._lastPos == camera._curPos) {
+#if defined(FULL_THROTTLE)
+ if (camera._last.x==camera._cur.x &&
+ camera._last.y==camera._cur.y) {
+#else
+ if (camera._last.x == camera._cur.x) {
+#endif
updateDirtyScreen(0);
} else {
vs = &virtscr[0];
@@ -182,99 +187,86 @@ void blit(byte *dst, byte *src, int w, int h) {
} while (--h);
}
-/* TODO: writes are being done to this data */
-MouseCursor mouse_cursors[4] = {
- 8,7,{15,15,7,8},
- {
- 0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,
- 0x00,0x80,0x00,0x80,0x00,0x00,0x7E,0x3F,
- 0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x80,
- 0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00,
- },
- 8,7,{15,15,7,8},
- {
- 0x00,0x00,0x7F,0xFE,0x60,0x06,0x30,0x0C,
- 0x18,0x18,0x0C,0x30,0x06,0x60,0x03,0xC0,
- 0x06,0x60,0x0C,0x30,0x19,0x98,0x33,0xCC,
- 0x67,0xE6,0x7F,0xFE,0x00,0x00,0x00,0x00,
- },
-
- 8,7,{15,15,7,8},
- {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- },
- 8,7,{15,15,7,8},
- {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- },
+void Scumm::setCursor(int cursor) {
+ warning("setCursor(%d)", cursor);
+}
-};
+#if defined(FULL_THROTTLE)
-void Scumm::setCursor(int cursor) {
- MouseCursor *cur = &mouse_cursors[cursor];
- int i,j;
- byte *mask;
- const byte *src;
- byte shramount;
- uint32 data;
+void Scumm::setCameraAt(int pos_x, int pos_y) {
+ CameraData *cd = &camera;
+ Point old;
- debug(1,"Loading cursor %d", cursor);
- gdi._hotspot_x = cur->hotspot_x;
- gdi._hotspot_y = cur->hotspot_y;
- gdi._currentCursor = cursor;
+ old = cd->_cur;
- for (i=0; i<4; i++)
- gdi._mouseColors[i] = cur->colors[i];
-
- mask = gdi._mouseMask;
- shramount = 0;
+ cd->_cur.x = pos_x;
+ cd->_cur.y = pos_y;
- for(j=0; j<8; j++) {
- src = cur->data;
- i=16;
- do {
- data = ((src[0]<<16) | (src[1]<<8))>>shramount;
- src += 2;
- mask[0] = (byte)(data>>24);
- mask[1] = (byte)(data>>16);
- mask[2] = (byte)(data>>8);
- mask[3] = (byte)(data);
- mask += 4;
- } while (--i);
- shramount++;
+ clampCameraPos(&cd->_cur);
+
+ cd->_dest = cd->_cur;
+
+ assert(cd->_cur.x>=160 && cd->_cur.y>=100);
+
+ if ((cd->_cur.x != old.x || cd->_cur.y != old.y) && _vars[VAR_SCROLL_SCRIPT]) {
+ _vars[VAR_CAMERA_POS_X] = cd->_cur.x;
+ _vars[VAR_CAMERA_POS_Y] = cd->_cur.y;
+ runScript(_vars[VAR_SCROLL_SCRIPT], 0, 0, 0);
}
}
-
-void Scumm::setCameraAt(int dest) {
+#else
+void Scumm::setCameraAt(int pos_x, int pos_y) {
int t;
CameraData *cd = &camera;
- if (cd->_mode!=CM_FOLLOW_ACTOR || abs(dest - cd->_curPos) > 160) {
- cd->_curPos = dest;
+ if (cd->_mode!=CM_FOLLOW_ACTOR || abs(pos_x - cd->_cur.x) > 160) {
+ cd->_cur.x = pos_x;
}
- cd->_destPos = dest;
+ cd->_dest.x = pos_x;
t = _vars[VAR_CAMERA_MIN_X];
- if (cd->_curPos < t) cd->_curPos = t;
+ if (cd->_cur.x < t) cd->_cur.x = t;
t = _vars[VAR_CAMERA_MAX_X];
- if (cd->_curPos > t) cd->_curPos = t;
+ if (cd->_cur.x > t) cd->_cur.x = t;
if (_vars[VAR_SCROLL_SCRIPT]) {
- _vars[VAR_CAMERA_POS_X] = cd->_curPos;
+ _vars[VAR_CAMERA_POS_X] = cd->_cur.x;
runScript(_vars[VAR_SCROLL_SCRIPT], 0, 0, 0);
}
- if (cd->_curPos != cd->_lastPos && charset._hasMask)
+ if (cd->_cur.x != cd->_last.x && charset._hasMask)
stopTalk();
}
+#endif
+
+#if defined(FULL_THROTTLE)
+void Scumm::setCameraFollows(Actor *a) {
+ CameraData *cd = &camera;
+ byte oldfollow = cd->_follows;
+ int ax,ay;
+
+ cd->_follows = a->number;
+
+ if (a->room != _currentRoom) {
+ startScene(a->room, 0, 0);
+ }
+
+ ax = abs(a->x - cd->_cur.x);
+ ay = abs(a->y - cd->_cur.y);
+
+ if ( ax > _vars[VAR_CAMERA_THRESHOLD_X] ||
+ ay > _vars[VAR_CAMERA_THRESHOLD_Y] ||
+ ax > 160 ||
+ ay > 100) {
+ setCameraAt(a->x, a->y);
+ }
+
+ if (a->number != oldfollow)
+ runHook(0);
+}
+#else
void Scumm::setCameraFollows(Actor *a) {
int t,i;
CameraData *cd = &camera;
@@ -285,15 +277,15 @@ void Scumm::setCameraFollows(Actor *a) {
if (a->room != _currentRoom) {
startScene(a->room, 0, 0);
cd->_mode = CM_FOLLOW_ACTOR;
- cd->_curPos = a->x;
- setCameraAt(cd->_curPos);
+ cd->_cur.x = a->x;
+ setCameraAt(cd->_cur.x, 0);
}
t = (a->x >> 3);
if (t-_screenStartStrip < cd->_leftTrigger ||
t-_screenStartStrip > cd->_rightTrigger)
- setCameraAt(a->x);
+ setCameraAt(a->x, 0);
for (i=1,a=getFirstActor(); ++a,i<NUM_ACTORS; i++) {
if (a->room==_currentRoom)
@@ -301,6 +293,7 @@ void Scumm::setCameraFollows(Actor *a) {
}
runHook(0);
}
+#endif
void Scumm::initBGBuffers() {
byte *ptr;
@@ -325,14 +318,11 @@ void Scumm::initBGBuffers() {
}
void Scumm::setPaletteFromPtr(byte *ptr) {
- uint32 size = READ_BE_UINT32_UNALIGNED(ptr+4);
int i, r, g, b;
byte *dest, *epal;
int numcolor;
- numcolor = (size-8) / 3;
-
- ptr += 8;
+ numcolor = getResourceDataSize(ptr) / 3;
checkRange(256, 0, numcolor, "Too many colors (%d) in Palette");
@@ -481,7 +471,9 @@ void Scumm::unkVirtScreen4(int a) {
VirtScreen *vs;
setDirtyRange(0, 0, 0);
- camera._lastPos = camera._curPos;
+#if !defined(FULL_THROTTLE)
+ camera._last.x = camera._cur.x;
+#endif
if (!_screenEffectFlag)
return;
_screenEffectFlag = false;
@@ -520,31 +512,50 @@ void Scumm::redrawBGAreas() {
int i;
int val;
CameraData *cd = &camera;
+ int diff;
- if (cd->_curPos!=cd->_lastPos && charset._hasMask)
+#if !defined(FULL_THROTTLE)
+ if (cd->_cur.x!=cd->_last.x && charset._hasMask)
stopTalk();
+#endif
val = 0;
if (!_fullRedraw && _BgNeedsRedraw) {
- for (i=0; i<40; i++) {
+ for (i=0; i!=40; i++) {
if (gfxUsageBits[_screenStartStrip + i]&0x80000000) {
redrawBGStrip(i, 1);
}
}
}
- if (_fullRedraw==0 && cd->_curPos - cd->_lastPos == 8) {
+#if defined(FULL_THROTTLE)
+ diff = (cd->_cur.x>>3) - (cd->_last.x>>3);
+ if (_fullRedraw==0 && diff==1) {
val = 2;
redrawBGStrip(39, 1);
- } else if (_fullRedraw==0 && cd->_curPos - cd->_lastPos == -8) {
+ } else if (_fullRedraw==0 && diff==-1) {
val = 1;
redrawBGStrip(0, 1);
- } else if (_fullRedraw!=0 || cd->_curPos != cd->_lastPos) {
+ } else if (_fullRedraw!=0 || diff!=0) {
_BgNeedsRedraw = false;
+ _fullRedraw = false;
redrawBGStrip(0, 40);
}
+#else
+ if (_fullRedraw==0 && cd->_cur.x - cd->_last.x == 8) {
+ val = 2;
+ redrawBGStrip(39, 1);
+ } else if (_fullRedraw==0 && cd->_cur.x - cd->_last.x == -8) {
+ val = 1;
+ redrawBGStrip(0, 1);
+ } else if (_fullRedraw!=0 || cd->_cur.x != cd->_last.x) {
+ _BgNeedsRedraw = false;
+ redrawBGStrip(0, 40);
+ }
+#endif
+
drawRoomObjects(val);
_BgNeedsRedraw = false;
}
@@ -553,7 +564,8 @@ const uint32 zplane_tags[] = {
MKID('ZP00'),
MKID('ZP01'),
MKID('ZP02'),
- MKID('ZP03')
+ MKID('ZP03'),
+ MKID('ZP04')
};
void Gdi::drawBitmap(byte *ptr, VirtScreen *vs, int x, int y, int h, int stripnr, int numstrip, byte flag) {
@@ -1245,13 +1257,17 @@ void Scumm::updateDirtyRect(int virt, int left, int right, int top, int bottom,
uint32 *sp;
int num;
- if (top > vs->height || bottom < 0)
+ if (top > vs->height || left > vs->width || right < 0 || bottom < 0)
return;
if (top<0)
top=0;
+ if (left<0)
+ left=0;
if (bottom > vs->height)
bottom = vs->height;
+ if (right > vs->width)
+ right = vs->width;
if (virt==0 && dirtybits) {
rp = (right >> 3) + _screenStartStrip;
@@ -1425,28 +1441,130 @@ void Gdi::clearUpperMask() {
);
}
+#if defined(FULL_THROTTLE)
+
+void Scumm::clampCameraPos(Point *pt) {
+ if (pt->x < _vars[VAR_CAMERA_MIN_X])
+ pt->x = _vars[VAR_CAMERA_MIN_X];
+
+ if (pt->x > _vars[VAR_CAMERA_MAX_X])
+ pt->x = _vars[VAR_CAMERA_MAX_X];
+
+ if (pt->y < _vars[VAR_CAMERA_MIN_Y])
+ pt->y = _vars[VAR_CAMERA_MIN_Y];
+
+ if (pt->y > _vars[VAR_CAMERA_MAX_Y])
+ pt->y = _vars[VAR_CAMERA_MAX_Y];
+}
+
+
+void Scumm::moveCamera() {
+ CameraData *cd = &camera;
+ Point old = cd->_cur;
+ Actor *a;
+
+ if (cd->_follows) {
+ a = derefActorSafe(cd->_follows, "moveCamera");
+ if (abs(cd->_cur.x - a->x) > _vars[VAR_CAMERA_THRESHOLD_X] ||
+ abs(cd->_cur.y - a->y) > _vars[VAR_CAMERA_THRESHOLD_Y]) {
+ cd->_movingToActor = true;
+ if (_vars[VAR_CAMERA_THRESHOLD_X] == 0)
+ cd->_cur.x = a->x;
+ if (_vars[VAR_CAMERA_THRESHOLD_Y] == 0)
+ cd->_cur.y = a->y;
+ clampCameraPos(&cd->_cur);
+ }
+ } else {
+ cd->_movingToActor = false;
+ }
+
+ if (cd->_movingToActor) {
+ cd->_dest.x = a->x;
+ cd->_dest.y = a->y;
+ }
+
+ assert(cd->_cur.x>=160 && cd->_cur.y>=100);
+
+ clampCameraPos(&cd->_dest);
+
+ if (cd->_cur.x < cd->_dest.x) {
+ cd->_cur.x += _vars[VAR_CAMERA_SPEED_X];
+ if (cd->_cur.x > cd->_dest.x)
+ cd->_cur.x = cd->_dest.x;
+ }
+
+ if (cd->_cur.x > cd->_dest.x) {
+ cd->_cur.x -= _vars[VAR_CAMERA_SPEED_X];
+ if (cd->_cur.x < cd->_dest.x)
+ cd->_cur.x = cd->_dest.x;
+ }
+
+ if (cd->_cur.y < cd->_dest.y) {
+ cd->_cur.y += _vars[VAR_CAMERA_SPEED_Y];
+ if (cd->_cur.y > cd->_dest.y)
+ cd->_cur.y = cd->_dest.y;
+ }
+
+ if (cd->_cur.y > cd->_dest.y) {
+ cd->_cur.y -= _vars[VAR_CAMERA_SPEED_Y];
+ if (cd->_cur.y < cd->_dest.y)
+ cd->_cur.y = cd->_dest.y;
+ }
+
+ if (cd->_cur.x == cd->_dest.x &&
+ cd->_cur.y == cd->_dest.y) {
+
+ cd->_movingToActor = false;
+ cd->_accel.x = cd->_accel.y = 0;
+ _vars[VAR_CAMERA_SPEED_X] = _vars[VAR_CAMERA_SPEED_Y] = 0;
+ } else {
+
+ cd->_accel.x += _vars[VAR_CAMERA_ACCEL_X];
+ cd->_accel.y += _vars[VAR_CAMERA_ACCEL_Y];
+
+ _vars[VAR_CAMERA_SPEED_X] += cd->_accel.x / 100;
+ _vars[VAR_CAMERA_SPEED_Y] += cd->_accel.y / 100;
+
+ if (_vars[VAR_CAMERA_SPEED_X] < 8)
+ _vars[VAR_CAMERA_SPEED_X] = 8;
+
+ if (_vars[VAR_CAMERA_SPEED_Y] < 8)
+ _vars[VAR_CAMERA_SPEED_Y] = 8;
+
+ }
+
+ cameraMoved();
+
+ 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);
+ }
+}
+
+#else
void Scumm::moveCamera() {
CameraData *cd = &camera;
- int pos = cd->_curPos;
+ int pos = cd->_cur.x;
int actorx, t;
Actor *a;
- cd->_curPos &= 0xFFF8;
+ cd->_cur.x &= 0xFFF8;
- if (cd->_curPos < _vars[VAR_CAMERA_MIN_X]) {
+ if (cd->_cur.x < _vars[VAR_CAMERA_MIN_X]) {
if (_vars[VAR_CAMERA_FAST_X])
- cd->_curPos = _vars[VAR_CAMERA_MIN_X];
+ cd->_cur.x = _vars[VAR_CAMERA_MIN_X];
else
- cd->_curPos += 8;
+ cd->_cur.x += 8;
cameraMoved();
return;
}
- if (cd->_curPos > _vars[VAR_CAMERA_MAX_X]) {
+ if (cd->_cur.x > _vars[VAR_CAMERA_MAX_X]) {
if (_vars[VAR_CAMERA_FAST_X])
- cd->_curPos = _vars[VAR_CAMERA_MAX_X];
+ cd->_cur.x = _vars[VAR_CAMERA_MAX_X];
else
- cd->_curPos-=8;
+ cd->_cur.x-=8;
cameraMoved();
return;
}
@@ -1460,9 +1578,9 @@ void Scumm::moveCamera() {
if (t < cd->_leftTrigger || t > cd->_rightTrigger) {
if (_vars[VAR_CAMERA_FAST_X]) {
if (t > 35)
- cd->_destPos = actorx + 80;
+ cd->_dest.x = actorx + 80;
if (t < 5)
- cd->_destPos = actorx - 80;
+ cd->_dest.x = actorx - 80;
} else
cd->_movingToActor = 1;
}
@@ -1470,59 +1588,88 @@ void Scumm::moveCamera() {
if (cd->_movingToActor) {
a = derefActorSafe(cd->_follows, "moveCamera(2)");
- cd->_destPos = a->x;
+ cd->_dest.x = a->x;
}
- if (cd->_destPos < _vars[VAR_CAMERA_MIN_X])
- cd->_destPos = _vars[VAR_CAMERA_MIN_X];
+ if (cd->_dest.x < _vars[VAR_CAMERA_MIN_X])
+ cd->_dest.x = _vars[VAR_CAMERA_MIN_X];
- if (cd->_destPos > _vars[VAR_CAMERA_MAX_X])
- cd->_destPos = _vars[VAR_CAMERA_MAX_X];
+ if (cd->_dest.x > _vars[VAR_CAMERA_MAX_X])
+ cd->_dest.x = _vars[VAR_CAMERA_MAX_X];
if (_vars[VAR_CAMERA_FAST_X]) {
- cd->_curPos = cd->_destPos;
+ cd->_cur.x = cd->_dest.x;
} else {
- if (cd->_curPos < cd->_destPos)
- cd->_curPos+=8;
- if (cd->_curPos > cd->_destPos)
- cd->_curPos-=8;
+ if (cd->_cur.x < cd->_dest.x)
+ cd->_cur.x+=8;
+ if (cd->_cur.x > cd->_dest.x)
+ cd->_cur.x-=8;
}
/* a is set a bit above */
- if (cd->_movingToActor && cd->_curPos>>3 == a->x>>3) {
+ if (cd->_movingToActor && cd->_cur.x>>3 == a->x>>3) {
cd->_movingToActor = 0;
}
cameraMoved();
- if (pos != cd->_curPos && _vars[VAR_SCROLL_SCRIPT]) {
- _vars[VAR_CAMERA_POS_X] = cd->_curPos;
+ if (pos != cd->_cur.x && _vars[VAR_SCROLL_SCRIPT]) {
+ _vars[VAR_CAMERA_POS_X] = cd->_cur.x;
runScript(_vars[VAR_SCROLL_SCRIPT], 0, 0, 0);
}
}
+#endif
+#if defined(FULL_THROTTLE)
void Scumm::cameraMoved() {
CameraData *cd = &camera;
- if (cd->_curPos < 160) {
- cd->_curPos = 160;
- } else if (cd->_curPos + 160 >= _scrWidthIn8Unit<<3) {
- cd->_curPos = (_scrWidthIn8Unit-20)<<3;
+ assert(cd->_cur.x>=160 && cd->_cur.y>=100);
+
+ _screenStartStrip = (cd->_cur.x-160) >> 3;
+ _screenEndStrip = _screenStartStrip + 39;
+ virtscr[0].xstart = _screenStartStrip << 3;
+
+ _screenLeft = cd->_cur.x - 160;
+ _screenTop = cd->_cur.y - 100;
+}
+
+
+#else
+void Scumm::cameraMoved() {
+ CameraData *cd = &camera;
+
+ if (cd->_cur.x < 160) {
+ cd->_cur.x = 160;
+ } else if (cd->_cur.x + 160 >= _scrWidth) {
+ cd->_cur.x = _scrWidth-160;
}
- _screenStartStrip = (cd->_curPos >> 3) - 20;
+ _screenStartStrip = (cd->_cur.x >> 3) - 20;
_screenEndStrip = _screenStartStrip + 39;
virtscr[0].xstart = _screenStartStrip << 3;
}
+#endif
-void Scumm::panCameraTo(int x) {
+#if defined(FULL_THROTTLE)
+void Scumm::panCameraTo(int x, int y) {
+ CameraData *cd = &camera;
+ cd->_follows = 0;
+ cd->_dest.x = x;
+ cd->_dest.y = y;
+}
+
+#else
+void Scumm::panCameraTo(int x, int y) {
CameraData *cd = &camera;
- cd->_destPos = x;
+ cd->_dest.x = x;
cd->_mode = CM_PANNING;
cd->_movingToActor = 0;
}
+#endif
void Scumm::actorFollowCamera(int act) {
+#if !defined(FULL_THROTTLE)
int old;
CameraData *cd = &camera;
@@ -1540,14 +1687,17 @@ void Scumm::actorFollowCamera(int act) {
runHook(0);
cd->_movingToActor = 0;
+#endif
}
void Scumm::setCameraAtEx(int at) {
+#if !defined(FULL_THROTTLE)
CameraData *cd = &camera;
cd->_mode = CM_NORMAL;
- cd->_curPos = at;
- setCameraAt(at);
+ cd->_cur.x = at;
+ setCameraAt(at, 0);
cd->_movingToActor = 0;
+#endif
}
void Scumm::palManipulate() {
@@ -1705,12 +1855,6 @@ void Scumm::drawMouse() {
);
}
-void Scumm::setCursorHotspot(int cursor, int x, int y) {
- MouseCursor *cur = &mouse_cursors[cursor];
- cur->hotspot_x = x;
- cur->hotspot_y = y;
-}
-
void Scumm::setCursorHotspot2(int x,int y) {
_cursorHotspotX = x;
_cursorHotspotY = y;
@@ -1759,16 +1903,16 @@ byte *Scumm::findPalInPals(byte *pal, int index) {
if (pal==NULL)
return NULL;
- offs = findResource(MKID('OFFS'),pal);
+ offs = findResourceData(MKID('OFFS'),pal);
if (offs==NULL)
return NULL;
- size = (READ_BE_UINT32_UNALIGNED(offs+4)-8) >> 2;
+ size = getResourceDataSize(offs) >> 2;
if ((uint32)index >= (uint32)size)
return NULL;
- return offs + READ_LE_UINT32(offs + 8 + index * sizeof(uint32));
+ return offs + READ_LE_UINT32(offs + index * sizeof(uint32));
}
byte *Scumm::getPalettePtr() {
@@ -1788,8 +1932,7 @@ void Scumm::darkenPalette(int a, int b, int c, int d, int e) {
int num;
int color;
- cptr = getPalettePtr();
- cptr += 8 + a*3;
+ cptr = getPalettePtr() + a*3;
cur = _currentPalette + a*3;
if (a <= b) {
num = b - a + 1;
@@ -1995,7 +2138,7 @@ void Scumm::drawBomp(BompDrawData *bd) {
inside = (bd->x>=0) && (bd->y>=0) &&
(bd->x <= bd->outwidth - bd->srcwidth) &&
(bd->y <= bd->outheight - bd->srcheight);
- assert(_objs[2].obj_nr == 36);
+
if (1 || bd->scale_x==255 && bd->scale_y==255) {
/* Routine used when no scaling is needed */
@@ -2072,5 +2215,5 @@ void Scumm::drawBomp(BompDrawData *bd) {
/* scaling of bomp images not supported yet */
}
CHECK_HEAP
- assert(_objs[2].obj_nr == 36);
+
} \ No newline at end of file
diff --git a/object.cpp b/object.cpp
index 783336492d..98c1f43407 100644
--- a/object.cpp
+++ b/object.cpp
@@ -148,7 +148,7 @@ void Scumm::getObjectXYPos(int object) {
ptr += od->offs_obim_to_room;
}
assert(ptr);
- imhd = (ImageHeader*)findResource(MKID('IMHD'), ptr);
+ imhd = (ImageHeader*)findResourceData(MKID('IMHD'), ptr);
x = od->x_pos + (int16)READ_LE_UINT16(&imhd->hotspot[state].x);
y = od->y_pos + (int16)READ_LE_UINT16(&imhd->hotspot[state].y);
} else {
@@ -326,7 +326,7 @@ void Scumm::drawObject(int obj, int arg) {
if (numstrip!=0) {
byte flags = Gdi::dbAllowMaskOr;
- if (getClass(od->obj_nr, 22))
+ if (_features&GF_AFTER_V7 && getClass(od->obj_nr, 22))
flags |= Gdi::dbDrawMaskOnBoth;
gdi.drawBitmap(ptr, _curVirtScreen, x, ypos, height, x-xpos, numstrip, flags);
}
@@ -346,7 +346,7 @@ void Scumm::loadRoomObjects() {
CHECK_HEAP
room = getResourceAddress(rtRoom, _roomResource);
- roomhdr = (RoomHeader*)findResource(MKID('RMHD'), room);
+ roomhdr = (RoomHeader*)findResourceData(MKID('RMHD'), room);
_numObjectsInRoom = READ_LE_UINT16(&roomhdr->numObjects);
@@ -364,7 +364,7 @@ void Scumm::loadRoomObjects() {
error("Room %d missing object code block(s)", _roomResource);
od->offs_obcd_to_room = ptr - room;
- cdhd = (CodeHeader*)findResource(MKID('CDHD'), ptr, 0);
+ cdhd = (CodeHeader*)findResourceData(MKID('CDHD'), ptr);
od->obj_nr = READ_LE_UINT16(&cdhd->obj_id);
#ifdef DUMP_SCRIPTS
@@ -383,7 +383,7 @@ void Scumm::loadRoomObjects() {
if (ptr==NULL)
error("Room %d missing image blocks(s)", _roomResource);
- imhd = (ImageHeader*)findResource(MKID('IMHD'), ptr, 0);
+ imhd = (ImageHeader*)findResourceData(MKID('IMHD'), ptr);
obim_id = READ_LE_UINT16(&imhd->obj_id);
for(j=1; j<=_numObjectsInRoom; j++) {
@@ -406,7 +406,7 @@ void Scumm::setupRoomObject(ObjectData *od, byte *room) {
CodeHeader *cdhd;
ImageHeader *imhd;
- cdhd = (CodeHeader*)findResource(MKID('CDHD'), room + od->offs_obcd_to_room);
+ cdhd = (CodeHeader*)findResourceData(MKID('CDHD'), room + od->offs_obcd_to_room);
od->obj_nr = READ_LE_UINT16(&cdhd->obj_id);
@@ -442,7 +442,7 @@ void Scumm::setupRoomObject(ObjectData *od, byte *room) {
od->parent = cdhd->parent;
od->parentstate = cdhd->parentstate;
- imhd = (ImageHeader*)findResource(MKID('IMHD'), room + od->offs_obim_to_room);
+ imhd = (ImageHeader*)findResourceData(MKID('IMHD'), room + od->offs_obim_to_room);
od->x_pos = imhd->x_pos;
od->y_pos = imhd->y_pos;
od->width = imhd->width;
@@ -547,11 +547,11 @@ byte *Scumm::getObjOrActorName(int obj) {
if (obj < NUM_ACTORS)
return getActorName(derefActorSafe(obj, "getObjOrActorName"));
- objptr = getObjectAddress(obj);
+ objptr = getOBCDFromObject(obj);
if (objptr==NULL)
return (byte*)" ";
- return findResource(MKID('OBNA'), objptr) + 8;
+ return findResourceData(MKID('OBNA'), objptr);
}
uint32 Scumm::getOBCDOffs(int object) {
@@ -569,7 +569,7 @@ uint32 Scumm::getOBCDOffs(int object) {
return 0;
}
-byte *Scumm::getObjectAddress(int obj) {
+byte *Scumm::getOBCDFromObject(int obj) {
int i;
if (_objectOwnerTable[obj] != OF_OWNER_ROOM) {
@@ -601,12 +601,12 @@ void Scumm::addObjectToInventory(uint obj, uint room) {
if (whereIsObject(obj)==WIO_FLOBJECT) {
i = getObjectIndex(obj);
- ptr = getResourceAddress(rtFlObject, _objs[i].fl_object_index) + 64;
+ ptr = getResourceAddress(rtFlObject, _objs[i].fl_object_index) + 8;
size = READ_BE_UINT32_UNALIGNED(ptr+4);
slot = getInventorySlot();
_inventory[slot] = obj;
createResource(rtInventory, slot, size);
- ptr = getResourceAddress(rtFlObject, _objs[i].fl_object_index) + 64;
+ ptr = getResourceAddress(rtFlObject, _objs[i].fl_object_index) + 8;
memcpy(getResourceAddress(rtInventory, slot), ptr, size);
} else {
findObjectInRoom(&foir, foCodeHeader, obj, room);
@@ -629,16 +629,16 @@ void Scumm::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, uint
ImageHeader *imhd;
if (findWhat&foCheckAlreadyLoaded && getObjectIndex(id) != -1) {
- fo->obcd = obcdptr = getObjectAddress(id);
+ fo->obcd = obcdptr = getOBCDFromObject(id);
assert((byte*)obcdptr > (byte*)256);
- fo->obim = obimptr = obcdptr + READ_BE_UINT32_UNALIGNED(&((ImageHeader*)obcdptr)->size);
- fo->cdhd = (CodeHeader*)findResource(MKID('CDHD'), obcdptr);
- fo->imhd = (ImageHeader*)findResource(MKID('IMHD'), obimptr);
+ fo->obim = obimptr = obcdptr + READ_BE_UINT32_UNALIGNED(&((ResHdr*)obcdptr)->size);
+ fo->cdhd = (CodeHeader*)findResourceData(MKID('CDHD'), obcdptr);
+ fo->imhd = (ImageHeader*)findResourceData(MKID('IMHD'), obimptr);
return;
}
fo->roomptr = roomptr = getResourceAddress(rtRoom, room);
- roomhdr = (RoomHeader*)findResource(MKID('RMHD'), roomptr);
+ roomhdr = (RoomHeader*)findResourceData(MKID('RMHD'), roomptr);
numobj = READ_LE_UINT16(&roomhdr->numObjects);
if (numobj==0)
error("findObjectInRoom: No object found in room %d", room);
@@ -651,7 +651,7 @@ void Scumm::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, uint
obcdptr = findResource(MKID('OBCD'), searchptr);
if(obcdptr==NULL)
error("findObjectInRoom: Not enough code blocks in room %d", room);
- cdhd = (CodeHeader*)findResource(MKID('CDHD'), obcdptr, 0);
+ cdhd = (CodeHeader*)findResourceData(MKID('CDHD'), obcdptr);
if ( READ_LE_UINT16(&cdhd->obj_id) == (uint16)id) {
fo->cdhd = cdhd;
fo->obcd = obcdptr;
@@ -669,7 +669,7 @@ void Scumm::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, uint
obimptr = findResource(MKID('OBIM'), searchptr);
if (obimptr==NULL)
error("findObjectInRoom: Not enough image blocks in room %d", room);
- imhd = (ImageHeader*)findResource(MKID('IMHD'), obimptr, 0);
+ imhd = (ImageHeader*)findResourceData(MKID('IMHD'), obimptr);
if (READ_LE_UINT16(&imhd->obj_id) == (uint16)id) {
fo->obim = obimptr;
fo->imhd = imhd;
@@ -730,15 +730,24 @@ int Scumm::getObjY(int obj) {
}
}
-int Scumm::getObjDir(int obj) {
+int Scumm::getObjOldDir(int obj) {
if (obj < NUM_ACTORS) {
- return newDirToOldDir(derefActorSafe(obj,"getObjDir")->facing);
+ return newDirToOldDir(derefActorSafe(obj,"getObjOldDir")->facing);
} else {
getObjectXYPos(obj);
return _dir;
}
}
+int Scumm::getObjNewDir(int obj) {
+ if (obj < NUM_ACTORS) {
+ return derefActorSafe(obj,"getObjNewDir")->facing;
+ } else {
+ getObjectXYPos(obj);
+ return oldDirToNewDir(_dir);
+ }
+}
+
int Scumm::findInventory(int owner, int index) {
int count = 1, i, obj;
for (i=0; i!=_maxInventoryItems; i++) {
@@ -876,7 +885,7 @@ void Scumm::nukeFlObjects(int min, int max) {
}
}
-void Scumm::enqueueObject(int a, int b, int c, int d, int e, int f, int g, int h) {
+void Scumm::enqueueObject(int a, int b, int c, int d, int e, int f, int g, int h, int mode) {
EnqueuedObject *eo;
ObjectData *od;
@@ -955,7 +964,7 @@ void Scumm::drawEnqueuedObject(EnqueuedObject *eo) {
assert(ptr);
ptr = findResource(MKID('IM01'), ptr);
assert(ptr);
- bomp = findResource(MKID('BOMP'), ptr);
+ bomp = findResourceData(MKID('BOMP'), ptr);
bdd.srcwidth = READ_LE_UINT16(&((BompHeader*)bomp)->width);
bdd.srcheight = READ_LE_UINT16(&((BompHeader*)bomp)->height);
@@ -1012,9 +1021,6 @@ void Scumm::loadFlObject(uint object, uint room) {
if (whereIsObject(object) != WIO_NOT_FOUND)
return;
- if (room==(uint)-1)
- room = getObjectRoom(object);
-
/* Locate the object in the room resource */
findObjectInRoom(&foir, foImageHeader | foCodeHeader, object, room);
diff --git a/resource.cpp b/resource.cpp
index 25c87e2a5a..da59b330d6 100644
--- a/resource.cpp
+++ b/resource.cpp
@@ -566,7 +566,7 @@ byte *Scumm::createResource(int type, int index, uint32 size) {
debug(9, "createResource(%d,%d,%d)", type, index,size);
if (size > 65536*4+37856)
- warning("Probably invalid size allocating");
+ warning("Probably invalid size allocating %d", size);
validateResource("allocating", type, index);
nukeResource(type, index);
@@ -612,12 +612,18 @@ void Scumm::nukeResource(int type, int index) {
}
byte *Scumm::findResourceData(uint32 tag, byte *ptr) {
- ptr = findResource(tag,ptr);
+ ptr = findResource(tag,ptr,0);
if (ptr==NULL)
return NULL;
return ptr + 8;
}
+int Scumm::getResourceDataSize(byte *ptr) {
+ if (ptr==NULL)
+ return 0;
+ return READ_BE_UINT32(ptr-4)-8;
+}
+
struct FindResourceState {
uint32 size,pos;
byte *ptr;
@@ -861,6 +867,8 @@ void Scumm::readMAXS() {
_objectRoomTable = (byte*)alloc(_numGlobalObjects);
_numGlobalScripts = 2000;
+
+ _shadowPaletteSize = NUM_SHADOW_PALETTE * 256;
} else if (_features & GF_AFTER_V6) {
_numVariables = fileReadWordLE();
fileReadWordLE();
@@ -881,6 +889,8 @@ void Scumm::readMAXS() {
_objectRoomTable = NULL;
_numGlobalScripts = 200;
+
+ _shadowPaletteSize = 256;
} else {
_numVariables = fileReadWordLE(); /* 800 */
fileReadWordLE(); /* 16 */
@@ -897,8 +907,14 @@ void Scumm::readMAXS() {
fileReadWordLE(); /* 50 */
_numInventory = fileReadWordLE(); /* 80 */
_numGlobalScripts = 200;
+
+ _shadowPaletteSize = 256;
+
+ _numFlObject = 50;
}
+ if (_shadowPaletteSize)
+ _shadowPalette = (byte*)alloc(_shadowPaletteSize);
allocateArrays();
_dynamicRoomOffsets = 1;
@@ -917,11 +933,10 @@ void Scumm::allocateArrays() {
_vars = (int16*)alloc(_numVariables * sizeof(int16));
_bitVars = (byte*)alloc(_numBitVariables >> 3);
-#if defined(FULL_THROTTLE)
- allocResTypeData(rtCostume, MKID('AKOS'), _numCostumes, "costume", 1);
-#else
- allocResTypeData(rtCostume, MKID('COST'), _numCostumes, "costume", 1);
-#endif
+ allocResTypeData(rtCostume,
+ (_features & GF_NEW_COSTUMES) ? MKID('AKOS') : MKID('COST'),
+ _numCostumes, "costume", 1);
+
allocResTypeData(rtRoom, MKID('ROOM'), _numRooms, "room", 1);
allocResTypeData(rtSound, MKID('SOUN'), _numSounds, "sound", 1);
allocResTypeData(rtScript, MKID('SCRP'), _numScripts, "script", 1);
@@ -930,7 +945,7 @@ void Scumm::allocateArrays() {
allocResTypeData(rtInventory, MKID('NONE'), _numInventory, "inventory", 0);
allocResTypeData(rtTemp,MKID('NONE'),10, "temp", 0);
allocResTypeData(rtScaleTable,MKID('NONE'),5, "scale table", 0);
- allocResTypeData(rtActorName, MKID('NONE'),13,"actor name", 0);
+ allocResTypeData(rtActorName, MKID('NONE'),NUM_ACTORS,"actor name", 0);
allocResTypeData(rtBuffer, MKID('NONE'),10,"buffer", 0);
allocResTypeData(rtVerb, MKID('NONE'),_numVerbs,"verb", 0);
allocResTypeData(rtString, MKID('NONE'),_numArray,"array", 0);
diff --git a/saveload.cpp b/saveload.cpp
index 9625dd886d..4701b1fa51 100644
--- a/saveload.cpp
+++ b/saveload.cpp
@@ -30,7 +30,7 @@ struct SaveGameHeader {
char name[32];
};
-#define CURRENT_VER 5
+#define CURRENT_VER 7
bool Scumm::saveState(int slot, bool compat) {
char filename[256];
@@ -132,6 +132,10 @@ bool Scumm::loadState(int slot, bool compat) {
_drawObjectQueNr = 0;
_verbMouseOver = 0;
+#if defined(FULL_THROTTLE)
+ cameraMoved();
+#endif
+
initBGBuffers();
CHECK_HEAP
@@ -235,7 +239,7 @@ void Scumm::saveOrLoad(Serializer *s) {
MKLINE(Actor,cost.animCounter2,sleByte),
MKARRAY(Actor,palette[0],sleByte,64),
MKLINE(Actor,mask,sleByte),
- MKLINE(Actor,unk1,sleByte),
+ MKLINE(Actor,shadow_mode,sleByte),
MKLINE(Actor,visible,sleByte),
MKLINE(Actor,frame,sleByte),
MKLINE(Actor,animSpeed,sleByte),
@@ -249,6 +253,8 @@ void Scumm::saveOrLoad(Serializer *s) {
MKLINE(Actor,new_2,sleInt16),
MKLINE(Actor,new_3,sleByte),
+ MKLINE(Actor,layer,sleByte),
+
MKLINE(Actor,talk_script,sleUint16),
MKLINE(Actor,walk_script,sleUint16),
@@ -301,7 +307,7 @@ void Scumm::saveOrLoad(Serializer *s) {
};
const SaveLoadEntry mainEntries[] = {
- MKLINE(Scumm,_scrWidthIn8Unit,sleUint16),
+ MKLINE(Scumm,_scrWidth,sleUint16),
MKLINE(Scumm,_scrHeight,sleUint16),
MKLINE(Scumm,_ENCD_offs,sleUint32),
MKLINE(Scumm,_EXCD_offs,sleUint32),
@@ -321,9 +327,21 @@ void Scumm::saveOrLoad(Serializer *s) {
MKARRAY(Scumm,_charsetData[0][0],sleByte,10*16),
MKLINE(Scumm,_curExecScript,sleUint16),
- MKLINE(Scumm,camera._destPos,sleInt16),
- MKLINE(Scumm,camera._curPos,sleInt16),
- MKLINE(Scumm,camera._lastPos,sleInt16),
+#if defined(FULL_THROTTLE)
+ MKLINE(Scumm,camera._dest.x,sleInt16),
+ MKLINE(Scumm,camera._dest.y,sleInt16),
+ MKLINE(Scumm,camera._cur.x,sleInt16),
+ MKLINE(Scumm,camera._cur.y,sleInt16),
+ MKLINE(Scumm,camera._last.x,sleInt16),
+ MKLINE(Scumm,camera._last.y,sleInt16),
+ MKLINE(Scumm,camera._accel.x,sleInt16),
+ MKLINE(Scumm,camera._accel.y,sleInt16),
+ MKLINE(Scumm,camera._follows,sleByte),
+ MKLINE(Scumm,camera._movingToActor,sleUint16),
+#else
+ MKLINE(Scumm,camera._dest.x,sleInt16),
+ MKLINE(Scumm,camera._cur.x,sleInt16),
+ MKLINE(Scumm,camera._last.x,sleInt16),
MKLINE(Scumm,_screenStartStrip,sleInt16),
MKLINE(Scumm,_screenEndStrip,sleInt16),
MKLINE(Scumm,camera._mode,sleByte),
@@ -331,7 +349,7 @@ void Scumm::saveOrLoad(Serializer *s) {
MKLINE(Scumm,camera._leftTrigger,sleInt16),
MKLINE(Scumm,camera._rightTrigger,sleInt16),
MKLINE(Scumm,camera._movingToActor,sleUint16),
-
+#endif
MKLINE(Scumm,_actorToPrintStrFor,sleByte),
MKLINE(Scumm,_charsetColor,sleByte),
MKLINE(Scumm,charset._bufPos,sleByte),
@@ -386,8 +404,6 @@ void Scumm::saveOrLoad(Serializer *s) {
MKLINE(Scumm,_screenB,sleUint16),
MKLINE(Scumm,_screenH,sleUint16),
- MKARRAY(Scumm,cost._transEffect[0],sleByte,256),
-
MKEND()
};
@@ -475,8 +491,8 @@ void Scumm::saveOrLoad(Serializer *s) {
if (_objectRoomTable)
s->saveLoadArrayOf(_objectRoomTable, _numGlobalObjects, sizeof(_objectRoomTable[0]), sleByte);
- if (_shadowPalette)
- s->saveLoadArrayOf(_shadowPalette, NUM_SHADOW_PALETTE * 256, 1, sleByte);
+ if (_shadowPaletteSize)
+ s->saveLoadArrayOf(_shadowPalette, _shadowPaletteSize, 1, sleByte);
s->saveLoadArrayOf(_classData, _numGlobalObjects, sizeof(_classData[0]), sleUint32);
s->saveLoadArrayOf(_vars, _numVariables, sizeof(_vars[0]), sleInt16);
diff --git a/script.cpp b/script.cpp
index 8279629fde..35fc7c708f 100644
--- a/script.cpp
+++ b/script.cpp
@@ -22,8 +22,6 @@
#include "stdafx.h"
#include "scumm.h"
-#define NO_SOUND_HACK
-
void Scumm::runScript(int script, int a, int b, int16 *lvarptr) {
byte *scriptPtr;
uint32 scriptOffs;
@@ -31,11 +29,6 @@ void Scumm::runScript(int script, int a, int b, int16 *lvarptr) {
int slot;
ScriptSlot *s;
-#ifdef NO_SOUND_HACK
- if (script==212 && _currentRoom==50)
- return;
-#endif
-
if (script==0)
return;
@@ -526,7 +519,7 @@ void Scumm::runExitScript() {
vm.slot[slot].status = 2;
vm.slot[slot].number = 10001;
vm.slot[slot].where = WIO_ROOM;
- vm.slot[slot].offs = _EXCD_offs + 8;
+ vm.slot[slot].offs = _EXCD_offs;
vm.slot[slot].unk1 = 0;
vm.slot[slot].unk2 = 0;
vm.slot[slot].freezeCount = 0;
@@ -544,7 +537,7 @@ void Scumm::runEntryScript() {
vm.slot[slot].status = 2;
vm.slot[slot].number = 10002;
vm.slot[slot].where = WIO_ROOM;
- vm.slot[slot].offs = _ENCD_offs + 8;
+ vm.slot[slot].offs = _ENCD_offs;
vm.slot[slot].unk1 = 0;
vm.slot[slot].unk2 = 0;
vm.slot[slot].freezeCount = 0;
@@ -700,7 +693,7 @@ int Scumm::getVerbEntrypoint(int obj, int entry) {
if (whereIsObject(obj)==WIO_NOT_FOUND)
return 0;
- objptr = getObjectAddress(obj);
+ objptr = getOBCDFromObject(obj);
assert(objptr);
verbptr = findResource(MKID('VERB'), objptr);
@@ -709,7 +702,7 @@ int Scumm::getVerbEntrypoint(int obj, int entry) {
verboffs = verbptr - objptr;
- verbptr += 8;
+ verbptr += _resourceHeaderSize;
do {
if (!*verbptr)
return 0;
diff --git a/script_v1.cpp b/script_v1.cpp
index 5bbbe4570b..3bc6e6f69d 100644
--- a/script_v1.cpp
+++ b/script_v1.cpp
@@ -461,7 +461,7 @@ FixRoom:
a->animProgress = 0;
break;
case 23: /* unk2 */
- a->unk1 = getVarOrDirectByte(0x80); /* unused? */
+ a->shadow_mode = getVarOrDirectByte(0x80); /* shadow mode */
break;
default:
error("o5_actorSet: default case");
@@ -584,7 +584,7 @@ void Scumm::o5_cursorCommand() {
i = getVarOrDirectByte(0x80);
j = getVarOrDirectByte(0x40);
k = getVarOrDirectByte(0x20);
- setCursorHotspot(i, j, k);
+ setCursorHotspot2(j, k);
break;
case 12: /* init cursor */
@@ -895,10 +895,16 @@ void Scumm::o5_getClosestObjActor() {
void Scumm::o5_getDist() {
int o1,o2;
+ int r;
getResultPos();
o1 = getVarOrDirectWord(0x80);
o2 = getVarOrDirectWord(0x40);
- setResult(getObjActToObjActDist(o1,o2));
+ r = getObjActToObjActDist(o1,o2);
+
+ /* Fix for monkey 2, dunno what's wrong in scummvm */
+ if (_gameId==GID_MONKEY2 && vm.slot[_currentScript].number==40 && r<60)
+ r=60;
+ setResult(r);
}
void Scumm::o5_getInventoryCount() {
@@ -1077,12 +1083,14 @@ void Scumm::o5_loadRoomWithEgo() {
_egoPositioned = false;
_vars[VAR_WALKTO_OBJ] = obj;
-
startScene(a->room, a, obj);
-
_vars[VAR_WALKTO_OBJ] = 0;
- camera._destPos = camera._curPos = a->x;
+
+#if !defined(FULL_THROTTLE)
+ camera._dest.x = camera._cur.x = a->x;
setCameraFollows(a);
+#endif
+
_fullRedraw=1;
if (x != -1) {
@@ -1144,7 +1152,7 @@ void Scumm::o5_overRide() {
}
void Scumm::o5_panCameraTo() {
- panCameraTo(getVarOrDirectWord(0x80));
+ panCameraTo(getVarOrDirectWord(0x80), 0);
}
void Scumm::o5_pickupObject() {
@@ -1323,9 +1331,9 @@ void Scumm::o5_roomOps() {
a = getVarOrDirectWord(0x80);
b = getVarOrDirectWord(0x40);
if (a < 160) a=160;
- if (a > ((_scrWidthIn8Unit-20)<<3)) a=((_scrWidthIn8Unit-20)<<3);
if (b < 160) b=160;
- if (b > ((_scrWidthIn8Unit-20)<<3)) b=((_scrWidthIn8Unit-20)<<3);
+ if (a > _scrWidth-160) a=_scrWidth-160;
+ if (b > _scrWidth-160) b=_scrWidth-160;
_vars[VAR_CAMERA_MIN_X] = a;
_vars[VAR_CAMERA_MAX_X] = b;
break;
@@ -1480,34 +1488,36 @@ void Scumm::o5_setCameraAt() {
}
void Scumm::o5_setObjectName() {
- int act = getVarOrDirectWord(0x80);
+ int obj = getVarOrDirectWord(0x80);
int size;
int a;
int i;
+ byte *name;
- if (act < NUM_ACTORS)
- error("Can't set actor %d name with new-name-of", act);
+ if (obj < NUM_ACTORS)
+ error("Can't set actor %d name with new-name-of", obj);
- if (!getObjectAddress(act))
- error("Can't set name of object %d", act);
+ if (!getOBCDFromObject(obj))
+ error("Can't set name of object %d", obj);
- size = READ_BE_UINT32_UNALIGNED(getObjOrActorName(act) - 4)-9;
+ name = getObjOrActorName(obj);
+ size = getResourceDataSize(name);
i = 0;
while ((a = fetchScriptByte()) != 0) {
- getObjOrActorName(act)[i++] = a;
+ name[i++] = a;
if (a==0xFF) {
- getObjOrActorName(act)[i++] = fetchScriptByte();
- getObjOrActorName(act)[i++] = fetchScriptByte();
- getObjOrActorName(act)[i++] = fetchScriptByte();
+ name[i++] = fetchScriptByte();
+ name[i++] = fetchScriptByte();
+ name[i++] = fetchScriptByte();
}
- if (i > size)
- error("New name of object %d too long", act);
+ if (i >= size)
+ error("New name of object %d too long", obj);
}
- getObjOrActorName(act)[i] = 0;
+ name[i] = 0;
runHook(0);
}
@@ -1807,7 +1817,7 @@ void Scumm::o5_wait() {
break;
return;
case 3: /* wait for camera */
- if (camera._curPos>>3 != camera._destPos>>3)
+ if (camera._cur.x>>3 != camera._dest.x>>3)
break;
return;
case 4: /* wait for sentence */
diff --git a/script_v2.cpp b/script_v2.cpp
index 3e83d89c54..09140c17d2 100644
--- a/script_v2.cpp
+++ b/script_v2.cpp
@@ -149,7 +149,7 @@ void Scumm::setupOpcodes2() {
&Scumm::o6_startObject,
&Scumm::o6_setObjectState,
&Scumm::o6_setObjectXY,
- &Scumm::o6_invalid,
+ &Scumm::o6_drawBlastObject,
/* 64 */
&Scumm::o6_invalid,
&Scumm::o6_stopObjectCode,
@@ -204,7 +204,7 @@ void Scumm::setupOpcodes2() {
&Scumm::o6_getActorRoom,
&Scumm::o6_getObjectX,
&Scumm::o6_getObjectY,
- &Scumm::o6_getObjectDir,
+ &Scumm::o6_getObjectOldDir,
/* 90 */
&Scumm::o6_getActorWalkBox,
&Scumm::o6_getActorCostume,
@@ -288,7 +288,7 @@ void Scumm::setupOpcodes2() {
/* D0 */
&Scumm::o6_invalid,
&Scumm::o6_invalid,
- &Scumm::o6_invalid,
+ &Scumm::o6_getAnimateVariable,
&Scumm::o6_invalid,
/* D4 */
&Scumm::o6_invalid,
@@ -322,7 +322,7 @@ void Scumm::setupOpcodes2() {
&Scumm::o6_invalid,
/* EC */
&Scumm::o6_invalid,
- &Scumm::o6_invalid,
+ &Scumm::o6_getObjectNewDir,
&Scumm::o6_invalid,
&Scumm::o6_invalid,
/* F0 */
@@ -350,6 +350,21 @@ void Scumm::setupOpcodes2() {
_opcodes = opcode_list;
}
+int Scumm::popRoomAndObj(int *room) {
+ int obj;
+
+ if (_features & GF_HAS_ROOMTABLE) {
+ obj = pop();
+ *room = getObjectRoom(obj);
+ } else {
+ *room = pop();
+ obj = pop();
+ }
+
+ return obj;
+}
+
+
int Scumm::readArray(int array, int index, int base) {
ArrayHeader *ah = (ArrayHeader*)getResourceAddress(rtString, readVar(array));
@@ -727,10 +742,11 @@ void Scumm::o6_cursorCommand() {
case 0x97:
_userPut--;
break;
- case 0x99:
- a = pop();
- setCursorImg(pop(), a, 1);
+ case 0x99: {
+ int room,obj = popRoomAndObj(&room);
+ setCursorImg(obj,room, 1);
break;
+ }
case 0x9A:
a = pop();
setCursorHotspot2(pop(),a);
@@ -839,15 +855,36 @@ void Scumm::o6_stopObjectScript() {
}
void Scumm::o6_panCameraTo() {
- panCameraTo(pop());
+#if defined(FULL_THROTTLE)
+ int y = pop();
+ int x = pop();
+ panCameraTo(x,y);
+#else
+ panCameraTo(pop(), 0);
+#endif
}
void Scumm::o6_actorFollowCamera() {
+#if defined(FULL_THROTTLE)
+ setCameraFollows(derefActorSafe(pop(), "actorFollowCamera"));
+#else
actorFollowCamera(pop());
+#endif
}
void Scumm::o6_setCameraAt() {
+#if defined(FULL_THROTTLE)
+ int x,y;
+
+ camera._follows = 0;
+
+ y = pop();
+ x = pop();
+
+ setCameraAt(x,y);
+#else
setCameraAtEx(pop());
+#endif
}
void Scumm::o6_loadRoom() {
@@ -924,17 +961,12 @@ void Scumm::o6_putActorInRoom() {
putActor(a, x, y, room);
}
+
void Scumm::o6_putActorAtObject() {
int room,obj,x,y;
Actor *a;
- if (_features & GF_HAS_ROOMTABLE) {
- obj = pop();
- room = getObjectRoom(obj);
- } else {
- room = pop();
- obj = pop();
- }
+ obj=popRoomAndObj(&room);
a = derefActorSafe(pop(), "o6_putActorAtObject");
if (whereIsObject(obj)!=WIO_NOT_FOUND) {
@@ -984,15 +1016,9 @@ void Scumm::o6_pickupObject() {
int obj, room;
int i;
- if (_features & GF_HAS_ROOMTABLE) {
- obj = pop();
- room = getObjectRoom(obj);
- } else {
- room = pop();
- obj = pop();
- if (room==0)
- room = _roomResource;
- }
+ obj=popRoomAndObj(&room);
+ if (room==0)
+ room = _roomResource;
for(i=1; i<_maxInventoryItems; i++) {
if (_inventory[i] == (uint16)obj) {
@@ -1018,14 +1044,8 @@ void Scumm::o6_loadRoomWithEgo() {
y = pop();
x = pop();
- if (_features & GF_HAS_ROOMTABLE) {
- obj = pop();
- room = getObjectRoom(obj);
- } else {
- room = pop();
- obj = pop();
- }
-
+ obj=popRoomAndObj(&room);
+
a = derefActorSafe(_vars[VAR_EGO], "o_loadRoomWithEgo");
putActor(a, 0, 0, room);
@@ -1036,8 +1056,10 @@ void Scumm::o6_loadRoomWithEgo() {
_vars[VAR_WALKTO_OBJ] = 0;
/* startScene maybe modifies VAR_EGO, i hope not */
- camera._destPos = camera._curPos = a->x;
+#if !defined(FULL_THROTTLE)
+ camera._dest.x = camera._cur.x = a->x;
setCameraFollows(a);
+#endif
_fullRedraw=1;
if (x != -1) {
startWalkActor(a, x, y, -1);
@@ -1083,14 +1105,12 @@ void Scumm::o6_getObjectY() {
push(getObjY(pop()));
}
-void Scumm::o6_getObjectDir() {
- int dir = getObjDir(pop());
-
- if (_features & GF_USE_ANGLES) {
- dir = oldDirToNewDir(dir);
- }
+void Scumm::o6_getObjectOldDir() {
+ push(getObjOldDir(pop()));
+}
- push(dir);
+void Scumm::o6_getObjectNewDir() {
+ push(getObjNewDir(pop()));
}
void Scumm::o6_getActorWalkBox() {
@@ -1136,7 +1156,7 @@ void Scumm::o6_setObjectName() {
if (obj < NUM_ACTORS)
error("Can't set actor %d name with new-name-of", obj);
- if (!getObjectAddress(obj))
+ if (!getOBCDFromObject(obj))
error("Can't set name of object %d", obj);
for (i=1; i<50; i++) {
@@ -1189,6 +1209,10 @@ void Scumm::o6_resourceRoutines() {
switch(fetchScriptByte()) {
case 100: /* load script */
res = pop();
+#if defined(FULL_THROTTLE)
+ if (res >= _numGlobalScripts)
+ break;
+#endif
ensureResourceLoaded(rtScript, res);
break;
case 101: /* load sound */
@@ -1205,6 +1229,10 @@ void Scumm::o6_resourceRoutines() {
break;
case 104: /* nuke script */
res = pop();
+#if defined(FULL_THROTTLE)
+ if (res >= _numGlobalScripts)
+ break;
+#endif
setResourceCounter(rtScript, res, 0x7F);
debug(5, "nuke script %d", res);
break;
@@ -1273,10 +1301,11 @@ void Scumm::o6_resourceRoutines() {
res = pop();
nukeCharset(res);
break;
- case 119:/* load fl object */
- res = (_features & GF_HAS_ROOMTABLE) ? -1 : pop();
- loadFlObject(pop(), res);
+ case 119: {/* load fl object */
+ int room,obj = popRoomAndObj(&room);
+ loadFlObject(obj,room);
break;
+ }
default:
error("o6_resourceRoutines: default case");
}
@@ -1290,9 +1319,9 @@ void Scumm::o6_roomOps() {
b = pop();
a = pop();
if (a < 160) a=160;
- if (a > ((_scrWidthIn8Unit-20)<<3)) a=((_scrWidthIn8Unit-20)<<3);
+ if (a > _scrWidth) a=_scrWidth;
if (b < 160) b=160;
- if (b > ((_scrWidthIn8Unit-20)<<3)) b=((_scrWidthIn8Unit-20)<<3);
+ if (b > _scrHeight) b=_scrHeight;
_vars[VAR_CAMERA_MIN_X] = a;
_vars[VAR_CAMERA_MAX_X] = b;
break;
@@ -1498,12 +1527,16 @@ FixRooms:;
a->animProgress = 0;
break;
case 98:
- a->unk1 = pop();
+ a->shadow_mode = pop();
break;
case 99:
a->new_1 = pop();
a->new_2 = pop();
break;
+ case 198: /* set anim variable */
+ i = pop(); /* value */
+ setAnimVar(a, pop(), i);
+ break;
case 215:
a->new_3 = 1;
break;
@@ -1513,19 +1546,32 @@ FixRooms:;
case 217:
initActor(a, 2);
break;
+ case 227: /* actor_layer */
+ a->layer = pop();
+ break;
+ case 228: /* walk script */
+ a->walk_script = pop();
+ break;
case 235: /* talk_script */
a->talk_script = pop();
break;
-
- case 198: /* set anim variable */
- case 227: /* actor_unk2 */
- case 228: /* actor script */
case 229: /* stand */
- case 230: /* turn? */
- case 231: /* turn? */
- case 233: /* ? */
- case 234: /* ? */
-
+ stopActorMoving(a);
+ startAnimActor(a, a->standFrame);
+ break;
+ case 230: /* set direction */
+ a->moving&=~4;
+ fixActorDirection(a, pop());
+ break;
+ case 231: /* turn to direction */
+ turnToDirection(a, pop());
+ break;
+ case 233: /* freeze actor */
+ a->moving|=0x80;
+ break;
+ case 234: /* unfreeze actor */
+ a->moving&=~0x7f;
+ break;
default:
error("o6_actorset: default case %d", b);
}
@@ -1787,21 +1833,27 @@ void Scumm::o6_wait() {
byte oldaddr;
switch(fetchScriptByte()) {
- case 168:
+ case 168: {
+ int offs = (int16)fetchScriptWord();
if (derefActorSafe(pop(), "o6_wait")->moving) {
- _scriptPointer += (int16)fetchScriptWord();
+ _scriptPointer += offs;
o6_breakHere();
- } else {
- fetchScriptWord();
}
return;
+ }
case 169:
if (_vars[VAR_HAVE_MSG])
break;
return;
case 170:
- if (camera._curPos>>3 != camera._destPos>>3)
+#if !defined(FULL_THROTTLE)
+ if (camera._cur.x>>3 != camera._dest.x>>3)
break;
+#else
+ if (camera._dest.x != camera._cur.x ||
+ camera._dest.y != camera._cur.y)
+ break;
+#endif
return;
case 171:
if (_sentenceNum) {
@@ -1813,6 +1865,24 @@ void Scumm::o6_wait() {
if (!isScriptInUse(_vars[VAR_SENTENCE_SCRIPT]))
return;
break;
+ case 226: { /* wait until actor drawn */
+ Actor *a = derefActorSafe(pop(), "o6_wait:226");
+ int offs = (int16)fetchScriptWord();
+ if (a->room==_currentRoom && a->needRedraw) {
+ _scriptPointer += offs;
+ o6_breakHere();
+ }
+ return;
+ }
+ case 232: { /* wait until actor stops turning */
+ Actor *a = derefActorSafe(pop(), "o6_wait:226");
+ int offs = (int16)fetchScriptWord();
+ if (a->room==_currentRoom && a->moving&4) {
+ _scriptPointer += offs;
+ o6_breakHere();
+ }
+ return;
+ }
default:
error("o6_wait: default case");
}
@@ -1829,6 +1899,11 @@ void Scumm::o6_getActorAnimCounter1() {
push(derefActorSafe(pop(),"o6_getActorAnimCounter")->cost.animCounter1);
}
+void Scumm::o6_getAnimateVariable() {
+ int var = pop();
+ push(getAnimVar(derefActorSafe(pop(),"o6_getAnimateVariable"), var));
+}
+
void Scumm::o6_soundKludge() {
int16 list[16];
getStackList(list,sizeof(list)/sizeof(list[0]));
@@ -2048,6 +2123,19 @@ void Scumm::o6_dummy_stacklist() {
error("opcode o6_dummy_stacklist invalid");
}
+void Scumm::o6_drawBlastObject() {
+ int16 args[16];
+ int a,b,c,d,e;
+
+ getStackList(args,sizeof(args)/sizeof(args[0]));
+ e = pop();
+ d = pop();
+ c = pop();
+ b = pop();
+ a = pop();
+ enqueueObject(a, b, c, d, e, 0xFF, 0xFF, 1, 0);
+}
+
void Scumm::o6_miscOps() {
int16 args[30];
int i;
@@ -2084,9 +2172,13 @@ void Scumm::o6_miscOps() {
case 15:
warning("o6_miscOps: stub15(%d)", args[1]);
break;
- case 16:
- warning("o6_miscOps: stub16(%d,%d,%d,%d)",args[1],args[2],args[3],args[4]);
+ case 16: {
+ byte buf[200];
+ _msgPtrToAdd = buf;
+ addMessageToStack(getStringAddress(_vars[VAR_STRING2DRAW]));
+ warning("o6_miscOps: drawString(%s,charset=%d,color=%d,x=%d,y=%d)",buf, args[1],args[2],args[3],args[4]);
break;
+ }
case 17:
warning("o6_miscOps: stub17(%d,%d,%d,%d)",args[1],args[2],args[3],args[4]);
break;
@@ -2109,13 +2201,13 @@ void Scumm::o6_miscOps() {
warning("o6_miscOps: stub114()");
break;
case 117:
- warning("o6_miscOps: stub117()");
+ freezeScripts(2);
break;
case 118:
- warning("o6_miscOps: stub118(%d,%d,%d,%d,%d,%d,%d,%d)",args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]);
+ enqueueObject(args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8], 3);
break;
case 119:
- warning("o6_miscOps: stub119(%d,%d,%d,%d,%d,%d,%d,%d)",args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]);
+ enqueueObject(args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8], 0);
break;
case 120:
warning("o6_miscOps: stub120(%d,%d)", args[1], args[2]);
@@ -2183,7 +2275,7 @@ void Scumm::o6_miscOps() {
case 111:
a = derefActorSafe(args[1], "o6_miscops: 111");
- a->unk1 = args[2] + args[3];
+ a->shadow_mode = args[2] + args[3];
break;
case 112:
@@ -2208,7 +2300,7 @@ void Scumm::o6_miscOps() {
case 119:
enqueueObject(args[1], args[2], args[3], args[4], args[5],
- args[6], args[7], args[8]);
+ args[6], args[7], args[8], 0);
break;
case 120:
diff --git a/scumm.h b/scumm.h
index 7b6b0e72d4..fe24021ed4 100644
--- a/scumm.h
+++ b/scumm.h
@@ -76,7 +76,6 @@ struct ResHdr {
struct RoomHeader {
- uint32 tag, size;
#ifdef FULL_THROTTLE
uint32 version;
#endif
@@ -85,14 +84,11 @@ struct RoomHeader {
} GCC_PACK;
struct BompHeader {
- uint32 tag,size;
uint16 unk;
uint16 width,height;
} GCC_PACK;
struct AkosHeader {
- uint32 tag;
- uint32 size;
byte x_1[2];
byte flags;
byte x_2;
@@ -114,8 +110,6 @@ struct AkosCI {
#if defined(FULL_THROTTLE)
struct CodeHeader {
- uint32 tag;
- uint32 size;
uint32 version;
uint16 obj_id;
byte parent;
@@ -124,8 +118,6 @@ struct CodeHeader {
#else
struct CodeHeader {
- uint32 id;
- uint32 size;
uint16 obj_id;
union {
@@ -152,8 +144,6 @@ struct CodeHeader {
#if defined(FULL_THROTTLE)
struct ImageHeader { /* file format */
- uint32 tag;
- uint32 size;
uint32 version;
uint16 obj_id;
uint16 unk[1];
@@ -168,12 +158,10 @@ struct ImageHeader { /* file format */
} GCC_PACK;
#else
struct ImageHeader { /* file format */
- uint32 id;
- uint32 size;
uint16 obj_id;
uint16 unk[5];
- uint16 img_w;
- uint16 img_h;
+ uint16 width;
+ uint16 height;
uint16 unk_2;
struct {
int16 x,y;
@@ -398,6 +386,11 @@ enum ScummVars {
VAR_HAVE_MSG = 13,
VAR_TIMER = 14,
VAR_TMR_4 = 15,
+ VAR_LEFTBTN_DOWN = 22,
+ VAR_RIGHTBTN_DOWN = 23,
+ VAR_LEFTBTN_HOLD = 24,
+ VAR_RIGHTBTN_HOLD = 25,
+
VAR_PERFORMANCE_1 = 26,
VAR_PERFORMANCE_2 = 27,
VAR_GAME_LOADED = 29,
@@ -433,8 +426,8 @@ enum ScummVars {
VAR_CAMERA_MAX_X = 102,
VAR_CAMERA_MIN_Y = 103,
VAR_CAMERA_MAX_Y = 104,
- VAR_CAMERA_FAST_X = 105,
- VAR_CAMERA_FAST_Y = 106,
+ VAR_CAMERA_THRESHOLD_X = 105,
+ VAR_CAMERA_THRESHOLD_Y = 106,
VAR_CAMERA_SPEED_X = 107,
VAR_CAMERA_SPEED_Y = 108,
VAR_CAMERA_ACCEL_X = 109,
@@ -447,6 +440,8 @@ enum ScummVars {
VAR_DEFAULT_TALK_DELAY = 114,
VAR_CHARINC = 115,
VAR_DEBUGMODE = 116,
+
+ VAR_CHARSET_MASK = 119,
//VAR_V5_DRAWFLAGS = 9,
VAR_MI1_TIMER = 14,
@@ -456,7 +451,8 @@ enum ScummVars {
VAR_V5_CHARFLAG = 60,
VAR_V6_EMSSPACE = 76,
-
+
+ VAR_STRING2DRAW = 130,
};
#endif
@@ -595,12 +591,13 @@ struct AkosRenderer {
int x,y; /* where to draw costume */
byte scale_x, scale_y; /* scaling */
byte clipping; /* clip mask */
- byte actor_unk1;
+ bool charsetmask;
+ byte shadow_mode;
uint16 codec;
bool mirror; /* draw actor mirrored */
byte dirty_id;
byte *outptr;
- int outwidth, outheight;
+ uint outwidth, outheight;
/* pointer to various parts of the costume resource */
byte *akos;
@@ -614,6 +611,7 @@ struct AkosRenderer {
int width,height;
byte *srcptr;
+ byte *shadow_table;
struct {
/* codec stuff */
@@ -628,7 +626,7 @@ struct AkosRenderer {
int y_pitch;
int skip_width;
byte *destptr;
- byte *mask_ptr,*mask_ptr_dest;
+ byte *mask_ptr;
int imgbufoffs;
} v1;
@@ -638,7 +636,6 @@ struct AkosRenderer {
AkosOffset *akof;
byte *akcd;
-
byte palette[256];
};
@@ -651,11 +648,20 @@ struct BompDrawData {
int srcwidth, srcheight;
};
-struct CostumeRenderer {
- Scumm *_vm;
+struct LoadedCostume {
byte *_ptr;
- byte _numColors;
byte *_dataptr;
+ byte _numColors;
+
+};
+
+struct CostumeRenderer {
+ Scumm *_vm;
+
+ LoadedCostume _loaded;
+
+ byte *_shadow_table;
+
byte *_frameptr;
byte *_srcptr;
byte *_bgbak_ptr, *_backbuff_ptr, *_mask_ptr, *_mask_ptr_dest;
@@ -671,7 +677,8 @@ struct CostumeRenderer {
byte _height2;
int _height;
int _xpos, _ypos;
-
+
+ uint _outheight;
int _scaleIndexXStep;
int _scaleIndexYStep;
byte _scaleIndexX; /* must wrap at 256*/
@@ -680,7 +687,6 @@ struct CostumeRenderer {
int _dir2;
int _top,_bottom;
int _ypostop;
- uint _vscreenheight;
int _ypitch;
byte _docontinue;
int _imgbufoffs;
@@ -699,12 +705,9 @@ struct CostumeRenderer {
byte mainRoutine(Actor *a, int slot, int frame);
void ignorePakCols(int num);
- void loadCostume(int id);
byte drawOneSlot(Actor *a, int slot);
byte drawCostume(Actor *a);
- byte animateOneSlot(Actor *a, int slot);
- byte animate(Actor *a);
};
struct Actor {
@@ -724,10 +727,8 @@ struct Actor {
byte forceClip;
byte initFrame,walkFrame,standFrame,talkFrame1,talkFrame2;
bool needRedraw, needBgReset,costumeNeedsInit,visible;
- byte unk1;
-#if defined(FULL_THROTTLE)
+ byte shadow_mode;
bool flip;
-#endif
uint speedx,speedy;
byte frame;
byte walkbox;
@@ -736,6 +737,7 @@ struct Actor {
int16 new_1,new_2;
uint16 talk_script, walk_script;
byte new_3;
+ int8 layer;
ActorWalkData walkdata;
//#if defined(FULL_THROTTLE)
int16 animVariable[16];
@@ -745,12 +747,25 @@ struct Actor {
byte palette[64];
};
+#if defined(FULL_THROTTLE)
+struct CameraData {
+ Point _cur;
+ Point _dest;
+ Point _accel;
+ Point _last;
+ byte _follows;
+ bool _movingToActor;
+};
+#else
struct CameraData {
- int16 _destPos, _curPos, _lastPos;
- int16 _leftTrigger, _rightTrigger;
+ Point _cur;
+ Point _dest;
+ Point _last;
+ int _leftTrigger, _rightTrigger;
byte _follows, _mode;
- uint16 _movingToActor;
+ bool _movingToActor;
};
+#endif
#define ARRAY_HDR_SIZE 6
struct ArrayHeader {
@@ -828,8 +843,6 @@ struct Gdi {
uint16 _vertStripNextInc;
byte *_backupIsWhere;
- byte _mouseMask[0x200];
-
void unkDecode1();
void unkDecode2();
void unkDecode3();
@@ -889,6 +902,7 @@ enum GameFeatures {
GF_AFTER_V7 = 4,
GF_HAS_ROOMTABLE = GF_AFTER_V7,
GF_USE_KEY = 8,
+ GF_NEW_COSTUMES = GF_AFTER_V7,
GF_USE_ANGLES = GF_AFTER_V7,
GF_DRAWOBJ_OTHER_ORDER = 16,
@@ -907,6 +921,11 @@ enum WhereIsObject {
WIO_FLOBJECT = 4,
};
+enum MouseButtonStatus {
+ msDown = 1,
+ msClicked = 2,
+};
+
struct BoxCoords {
Point ul;
Point ur;
@@ -1019,6 +1038,8 @@ struct Scumm {
byte _switchRoomEffect2, _switchRoomEffect;
+ int _resourceHeaderSize;
+
bool _egoPositioned;
bool _doEffect;
bool _screenEffectFlag;
@@ -1055,8 +1076,11 @@ struct Scumm {
byte _numObjectsInRoom;
byte _actorToPrintStrFor;
- int16 _screenStartStrip;
- int16 _screenEndStrip;
+ int _screenStartStrip;
+ int _screenEndStrip;
+
+ int _screenLeft;
+ int _screenTop;
byte _fastMode;
@@ -1138,6 +1162,7 @@ struct Scumm {
byte **_lastCodePtr;
byte *_shadowPalette;
+ int _shadowPaletteSize;
// int _numSoundTags;
// byte *_soundTagTable;
@@ -1160,8 +1185,6 @@ struct Scumm {
StringTab string[6];
- CostumeRenderer cost;
-
uint16 _mouthSyncTimes[52];
int16 _soundQuePos;
@@ -1179,7 +1202,7 @@ struct Scumm {
uint16 _curExecScript;
- int _scrWidthIn8Unit;
+ int _scrWidth;
int _scrHeight;
byte _currentPalette[0x300];
@@ -1211,7 +1234,7 @@ struct Scumm {
int _boxPathVertexHeapIndex;
int _boxMatrixItem;
- byte _grabbedCursor[1024];
+ byte _grabbedCursor[2048];
char _saveLoadName[32];
@@ -1330,7 +1353,7 @@ struct Scumm {
int getProgrDirChange(Actor *a, int mode);
void initActorCostumeData(Actor *a);
void fixActorDirection(Actor *a, int direction);
- void decodeCostData(Actor *a, int frame, uint mask);
+ void cpst_decodeData(Actor *a, int frame, uint mask);
void scummInit();
void scummMain(int argc, char **argv);
@@ -1542,7 +1565,8 @@ struct Scumm {
void o6_getActorRoom();
void o6_getObjectX();
void o6_getObjectY();
- void o6_getObjectDir();
+ void o6_getObjectOldDir();
+ void o6_getObjectNewDir();
void o6_getActorWalkBox();
void o6_getActorCostume();
void o6_findInventory();
@@ -1602,6 +1626,10 @@ struct Scumm {
void o6_jumpToScript();
void o6_isRoomScriptRunning();
void o6_kernelFunction();
+ void o6_getAnimateVariable();
+ void o6_drawBlastObject();
+
+ int popRoomAndObj(int *room);
void soundKludge(int16 *list);
@@ -1632,7 +1660,7 @@ struct Scumm {
bool inBoxQuickReject(int box, int x, int y, int threshold);
AdjustBoxResult getClosestPtOnBox(int box, int x, int y);
- void setCameraAt(int dest);
+ void setCameraAt(int pos_x, int pos_y);
void stopTalk();
void restoreCharsetBg();
@@ -1723,7 +1751,6 @@ struct Scumm {
int getPathToDestBox(byte from, byte to);
int findPathTowards(Actor *a, byte box, byte box2, byte box3);
- void setActorCostPalette(Actor *a);
void drawActorCostume(Actor *a);
void actorAnimate(Actor *a);
@@ -1743,7 +1770,7 @@ struct Scumm {
void walkActorTo(Actor *a, int x, int y, int direction);
void setCursorImg(uint img, uint room, uint imgindex);
- void setCursorHotspot(int cursor, int x, int y);
+// void setCursorHotspot(int cursor, int x, int y);
void initCharset(int charset);
void addObjectToDrawQue(int object);
int getVerbEntrypoint(int obj, int entry);
@@ -1768,7 +1795,7 @@ struct Scumm {
void unkRoomFunc4(int a, int b, int c, int d, int e);
int getVerbSlot(int id, int mode);
void killVerb(int slot);
- byte *getObjectAddress(int obj);
+ byte *getOBCDFromObject(int obj);
byte *getObjOrActorName(int obj);
void clearOwnerOf(int obj);
void runVerbCode(int script, int entry, int a, int b, int16 *vars);
@@ -1813,8 +1840,6 @@ struct Scumm {
Actor *derefActorSafe(int id, const char *errmsg);
Actor *getFirstActor() { return actor; }
- void setupCostumeRenderer(CostumeRenderer *c, Actor *a);
-
PathVertex *unkMatrixProc1(PathVertex *vtx, PathNode *node);
PathNode *unkMatrixProc2(PathVertex *vtx, int i);
bool areBoxesNeighbours(int i, int j);
@@ -1835,10 +1860,12 @@ struct Scumm {
void cutscene(int16 *args);
void setOwnerOf(int obj, int owner);
- void panCameraTo(int x);
+ void panCameraTo(int x, int y);
void actorFollowCamera(int act);
void setCameraAtEx(int at);
+ void clampCameraPos(Point *pt);
+
void setCursorHotspot2(int x,int y);
void makeCursorColorTransparent(int a);
@@ -1849,7 +1876,8 @@ struct Scumm {
bool isRoomScriptRunning(int script);
int getObjX(int obj);
int getObjY(int obj);
- int getObjDir(int obj);
+ int getObjOldDir(int obj);
+ int getObjNewDir(int obj);
int findInventory(int owner, int index);
int getInventoryCount(int owner);
@@ -1932,7 +1960,7 @@ struct Scumm {
void swapPalColors(int a, int b);
- void enqueueObject(int a, int b, int c, int d, int e, int f, int g, int h);
+ void enqueueObject(int a, int b, int c, int d, int e, int f, int g, int h, int mode);
void clearEnqueue() { _enqueuePos = 0; }
void drawEnqueuedObjects();
@@ -1973,11 +2001,12 @@ struct Scumm {
void remapActor(Actor *a, int b, int c, int d, int e);
byte *findResourceData(uint32 tag, byte *ptr);
+ int getResourceDataSize(byte *ptr);
void akos_decodeData(Actor *a, int frame, uint usemask);
int akos_frameToAnim(Actor *a, int frame);
bool akos_hasManyDirections(Actor *a);
- void stopActorMoving(Actor *a) { a->moving = 0; }
+ void stopActorMoving(Actor *a);
int newDirToOldDir(int dir);
int oldDirToNewDir(int dir);
@@ -1995,7 +2024,6 @@ struct Scumm {
void akos_codec5(AkosRenderer *ar);
void akos_codec16(AkosRenderer *ar);
void akos_codec1_ignorePakCols(AkosRenderer *ar, int num);
- void akos_c1_spec1(AkosRenderer *ar);
void akos_c1_spec2(AkosRenderer *ar);
void akos_c1_spec3(AkosRenderer *ar);
@@ -2019,8 +2047,9 @@ struct Scumm {
bool akos_compare(int a, int b, byte cmd);
static int normalizeAngle(int angle);
- static int fromSimpleDir(int dir);
- static int toSimpleDir(int dir);
+ static int fromSimpleDir(int dirtype, int dir);
+ static int toSimpleDir(int dirtype, int dir);
+ static int numSimpleDirDirections(int dirType);
void doSentence(int c, int b, int a);
int cost_frameToAnim(Actor *a, int frame);
@@ -2028,6 +2057,14 @@ struct Scumm {
void setupShadowPalette(int slot,int rfact,int gfact,int bfact,int from,int to);
void drawBomp(BompDrawData *bd);
+ void loadCostume(LoadedCostume *lc, int costume);
+
+ void cost_setPalette(CostumeRenderer *cr, byte *palette);
+ void cost_setFacing(CostumeRenderer *cr, Actor *a);
+ void cost_setCostume(CostumeRenderer *cr, int costume);
+ byte cost_increaseAnims(LoadedCostume *lc, Actor *a);
+ byte cost_increaseAnim(LoadedCostume *lc, Actor *a, int slot);
+ void cost_decodeData(Actor *a, int frame, uint usemask);
};
enum AkosOpcodes{
diff --git a/scummvm.cpp b/scummvm.cpp
index 8e36f04e19..75e22bd511 100644
--- a/scummvm.cpp
+++ b/scummvm.cpp
@@ -46,6 +46,8 @@ void Scumm::scummInit() {
debug(9, "scummInit");
+ _resourceHeaderSize = 8;
+
loadCharset(1);
initScreens(0, 16, 320, 144);
@@ -80,9 +82,11 @@ void Scumm::scummInit() {
_verbs[i].key = 0;
}
+#if !defined(FULL_THROTTLE)
camera._leftTrigger = 10;
camera._rightTrigger = 30;
camera._mode = 0;
+#endif
camera._follows = 0;
virtscr[0].xstart = 0;
@@ -172,7 +176,6 @@ void Scumm::scummMain(int argc, char **argv) {
Actor *a;
charset._vm = this;
- cost._vm = this;
gdi._vm = this;
_fileHandle = NULL;
@@ -247,7 +250,12 @@ int Scumm::scummLoop(int delta) {
processKbd();
- _vars[VAR_CAMERA_POS_X] = camera._curPos;
+#if defined(FULL_THROTTLE)
+ _vars[VAR_CAMERA_POS_X] = camera._cur.x;
+ _vars[VAR_CAMERA_POS_Y] = camera._cur.y;
+#else
+ _vars[VAR_CAMERA_POS_X] = camera._cur.x;
+#endif
_vars[VAR_HAVE_MSG] = _haveMsg;
_vars[VAR_VIRT_MOUSE_X] = _virtual_mouse_x;
_vars[VAR_VIRT_MOUSE_Y] = _virtual_mouse_y;
@@ -293,13 +301,19 @@ int Scumm::scummLoop(int delta) {
CHARSET_1();
drawDirtyScreenParts();
processSoundQues();
- camera._lastPos = camera._curPos;
+ camera._last = camera._cur;
} else {
walkActors();
moveCamera();
fixObjectFlags();
CHARSET_1();
- if (camera._curPos != camera._lastPos || _BgNeedsRedraw || _fullRedraw) {
+#if !defined(FULL_THROTTLE)
+ if (camera._cur.x != camera._last.x || _BgNeedsRedraw || _fullRedraw) {
+#else
+ if (camera._cur.x != camera._last.x ||
+ camera._cur.y != camera._last.y || _BgNeedsRedraw ||
+ _fullRedraw) {
+#endif
redrawBGAreas();
}
processDrawQue();
@@ -335,7 +349,7 @@ int Scumm::scummLoop(int delta) {
playActorSounds();
processSoundQues();
- camera._lastPos = camera._curPos;
+ camera._last = camera._cur;
}
if (!(++_expire_counter)) {
@@ -479,15 +493,18 @@ void Scumm::startScene(int room, Actor *a, int objectNr) {
_vars[VAR_NEW_ROOM] = room;
runExitScript();
killScriptsAndResources();
+ clearEnqueue();
stopCycle(0);
-
+
for(i=1,at=getFirstActor(); ++at,i<NUM_ACTORS; i++) {
if (at->visible)
hideActor(at);
}
-
- for (i=0; i<0x100; i++)
- cost._transEffect[i] = i;
+
+ if (!(_features & GF_AFTER_V7)) {
+ for (i=0; i<0x100; i++)
+ _shadowPalette[i] = i;
+ }
clearDrawObjectQueue();
@@ -518,22 +535,32 @@ void Scumm::startScene(int room, Actor *a, int objectNr) {
}
initRoomSubBlocks();
-
loadRoomObjects();
+#if !defined(FULL_THROTTLE)
camera._mode = CM_NORMAL;
- camera._curPos = camera._destPos = 160;
+ camera._cur.x = camera._dest.x = 160;
+#endif
if (_features&GF_AFTER_V6) {
- _vars[VAR_V6_SCREEN_WIDTH] = _scrWidthIn8Unit<<3;
+ _vars[VAR_V6_SCREEN_WIDTH] = _scrWidth;
_vars[VAR_V6_SCREEN_HEIGHT] = _scrHeight;
}
+#if defined(FULL_THROTTLE)
+ _vars[VAR_CAMERA_MIN_X] = 160;
+ _vars[VAR_CAMERA_MAX_X] = _scrWidth - 160;
+ _vars[VAR_CAMERA_MIN_Y] = 100;
+ _vars[VAR_CAMERA_MAX_Y] = _scrHeight - 100;
+ setCameraAt(160, 100);
+#else
+ _vars[VAR_CAMERA_MAX_X] = _scrWidth - 160;
+ _vars[VAR_CAMERA_MIN_X] = 160;
+#endif
+
if (_roomResource == 0)
return;
- _vars[VAR_CAMERA_MAX_X] = (_scrWidthIn8Unit<<3) - 160;
- _vars[VAR_CAMERA_MIN_X] = 160;
memset(gfxUsageBits, 0, sizeof(gfxUsageBits));
@@ -551,11 +578,19 @@ void Scumm::startScene(int room, Actor *a, int objectNr) {
_egoPositioned = false;
runEntryScript();
+
+#if !defined(FULL_THROTTLE)
if (a && !_egoPositioned) {
getObjectXYPos(objectNr);
putActor(a, _xPos, _yPos, _currentRoom);
a->moving = 0;
}
+#else
+ if (camera._follows) {
+ Actor *a = derefActorSafe(camera._follows, "startScene: follows");
+ setCameraAt(a->x, a->y);
+ }
+#endif
_doEffect = true;
@@ -566,6 +601,7 @@ void Scumm::initRoomSubBlocks() {
int i,offs;
byte *ptr;
byte *roomptr,*searchptr;
+ RoomHeader *rmhd;
_ENCD_offs = 0;
_EXCD_offs = 0;
@@ -580,55 +616,55 @@ void Scumm::initRoomSubBlocks() {
roomptr = getResourceAddress(rtRoom, _roomResource);
- ptr = findResource(MKID('RMHD'), roomptr);
- _scrWidthIn8Unit = READ_LE_UINT16(&((RoomHeader*)ptr)->width) >> 3;
- _scrHeight = READ_LE_UINT16(&((RoomHeader*)ptr)->height);
+ rmhd = (RoomHeader*)findResourceData(MKID('RMHD'), roomptr);
+ _scrWidth = READ_LE_UINT16(&rmhd->width);
+ _scrHeight = READ_LE_UINT16(&rmhd->height);
_IM00_offs = findResource(MKID('IM00'), findResource(MKID('RMIM'), roomptr))
- roomptr;
- ptr = findResource(MKID('EXCD'), roomptr);
+ ptr = findResourceData(MKID('EXCD'), roomptr);
if (ptr) {
_EXCD_offs = ptr - roomptr;
#ifdef DUMP_SCRIPTS
- dumpResource("exit-", _roomResource, ptr);
+ dumpResource("exit-", _roomResource, ptr - 8);
#endif
}
- ptr = findResource(MKID('ENCD'), roomptr);
+ ptr = findResourceData(MKID('ENCD'), roomptr);
if (ptr) {
_ENCD_offs = ptr - roomptr;
#ifdef DUMP_SCRIPTS
- dumpResource("entry-", _roomResource, ptr);
+ dumpResource("entry-", _roomResource, ptr - 8);
#endif
}
- ptr = findResource(MKID('BOXD'), roomptr);
+ ptr = findResourceData(MKID('BOXD'), roomptr);
if (ptr) {
- int size = READ_BE_UINT32_UNALIGNED(ptr+4);
- createResource(rtMatrix, 2, size);
+ int size = getResourceDataSize(ptr);
+ createResource(rtMatrix, 2, size);
roomptr = getResourceAddress(rtRoom, _roomResource);
- ptr = findResource(MKID('BOXD'), roomptr);
+ ptr = findResourceData(MKID('BOXD'), roomptr);
memcpy(getResourceAddress(rtMatrix, 2), ptr, size);
}
- ptr = findResource(MKID('BOXM'), roomptr);
+ ptr = findResourceData(MKID('BOXM'), roomptr);
if (ptr) {
- int size = READ_BE_UINT32_UNALIGNED(ptr+4);
+ int size = getResourceDataSize(ptr);
createResource(rtMatrix, 1, size);
roomptr = getResourceAddress(rtRoom, _roomResource);
- ptr = findResource(MKID('BOXM'), roomptr);
+ ptr = findResourceData(MKID('BOXM'), roomptr);
memcpy(getResourceAddress(rtMatrix, 1), ptr, size);
}
- ptr = findResource(MKID('SCAL'), roomptr);
+ ptr = findResourceData(MKID('SCAL'), roomptr);
if (ptr) {
offs = ptr - roomptr;
for (i=1; i<_maxScaleTable; i++, offs+=8) {
- int a = READ_LE_UINT16(roomptr + offs + 8);
- int b = READ_LE_UINT16(roomptr + offs + 10);
- int c = READ_LE_UINT16(roomptr + offs + 12);
- int d = READ_LE_UINT16(roomptr + offs + 14);
+ int a = READ_LE_UINT16(roomptr + offs);
+ int b = READ_LE_UINT16(roomptr + offs + 2);
+ int c = READ_LE_UINT16(roomptr + offs + 4);
+ int d = READ_LE_UINT16(roomptr + offs + 6);
if (a || b || c || d) {
setScaleItem(i, b, a, d, c);
roomptr = getResourceAddress(rtRoom, _roomResource);
@@ -640,19 +676,21 @@ void Scumm::initRoomSubBlocks() {
searchptr = roomptr = getResourceAddress(rtRoom, _roomResource);
while( (ptr = findResource(MKID('LSCR'), searchptr)) != NULL ) {
int id;
+
+ ptr += _resourceHeaderSize; /* skip tag & size */
#ifdef FULL_THROTTLE
- id = READ_LE_UINT16(ptr + 8);
+ id = READ_LE_UINT16(ptr);
checkRange(2050, 2000, id, "Invalid local script %d");
- _localScriptList[id - _numGlobalScripts] = ptr + 10 - roomptr;
+ _localScriptList[id - _numGlobalScripts] = ptr + 2 - roomptr;
#else
- id = ptr[8];
- _localScriptList[id - _numGlobalScripts] = ptr + 9 - roomptr;
+ id = ptr[0];
+ _localScriptList[id - _numGlobalScripts] = ptr + 1 - roomptr;
#endif
#ifdef DUMP_SCRIPTS
do {
char buf[32];
sprintf(buf,"room-%d-",_roomResource);
- dumpResource(buf, id, ptr);
+ dumpResource(buf, id, ptr - 8);
} while (0);
#endif
searchptr = NULL;
@@ -663,7 +701,7 @@ void Scumm::initRoomSubBlocks() {
if (ptr)
_EPAL_offs = ptr - roomptr;
- ptr = findResource(MKID('CLUT'), roomptr);
+ ptr = findResourceData(MKID('CLUT'), roomptr);
if (ptr) {
_CLUT_offs = ptr - roomptr;
setPaletteFromRes();
@@ -677,11 +715,11 @@ void Scumm::initRoomSubBlocks() {
}
}
- initCycl(findResource(MKID('CYCL'), roomptr) + 8);
+ initCycl(findResourceData(MKID('CYCL'), roomptr));
- ptr = findResource(MKID('TRNS'), roomptr);
+ ptr = findResourceData(MKID('TRNS'), roomptr);
if (ptr)
- gdi._transparency = ptr[8];
+ gdi._transparency = ptr[0];
else
gdi._transparency = 255;
@@ -817,17 +855,24 @@ int Scumm::getKeyInput(int a) {
if (mouse.y<0) mouse.y=0;
if (mouse.y>199) mouse.y=199;
- if (_leftBtnPressed&1 && _rightBtnPressed&1) {
+ if (_leftBtnPressed&msClicked && _rightBtnPressed&msClicked) {
_mouseButStat = 0;
_lastKeyHit = _vars[VAR_CUTSCENEEXIT_KEY];
- } else if (_leftBtnPressed&1) {
+ } else if (_leftBtnPressed&msClicked) {
_mouseButStat = MBS_LEFT_CLICK;
- } else if (_rightBtnPressed&1) {
+ } else if (_rightBtnPressed&msClicked) {
_mouseButStat = MBS_RIGHT_CLICK;
}
-
- _leftBtnPressed &= ~1;
- _rightBtnPressed &= ~1;
+
+#if defined(FULL_THROTTLE)
+// _vars[VAR_LEFTBTN_DOWN] = (_leftBtnPressed&msClicked) != 0;
+ _vars[VAR_LEFTBTN_HOLD] = (_leftBtnPressed&msDown) != 0;
+// _vars[VAR_RIGHTBTN_DOWN] = (_rightBtnPressed&msClicked) != 0;
+ _vars[VAR_RIGHTBTN_HOLD] = (_rightBtnPressed&msDown) != 0;
+#endif
+
+ _leftBtnPressed &= ~msClicked;
+ _rightBtnPressed &= ~msClicked;
return _lastKeyHit;
}
@@ -917,18 +962,42 @@ int Scumm::oldDirToNewDir(int dir) {
return new_dir_table[dir];
}
-int Scumm::toSimpleDir(int dir) {
- if (dir>=71 && dir<=109)
- return 1;
- if (dir>=109 && dir<=251)
- return 2;
- if (dir>=251 && dir<=289)
- return 3;
+
+const uint16 many_direction_tab[18] = {
+ 71, 109, 251, 530,
+ 0,
+ 0,
+ 0,
+ 0,
+ 22,72,107,
+ 157,
+ 202,
+ 252,
+ 287,
+ 337
+};
+
+
+int Scumm::numSimpleDirDirections(int dirType) {
+ return dirType ? 8 : 4;
+}
+
+/* Convert an angle to a simple direction */
+int Scumm::toSimpleDir(int dirType, int dir) {
+ int num = dirType ? 8 : 4, i;
+ const uint16 *dirtab = &many_direction_tab[dirType*8];
+ for(i=1;i<num;i++,dirtab++) {
+ if (dir >= dirtab[0] && dir <= dirtab[1])
+ return i;
+ }
return 0;
+
}
-int Scumm::fromSimpleDir(int dir) {
- return dir * 90;
+/* Convert a simple direction to an angle */
+int Scumm::fromSimpleDir(int dirType, int dir) {
+ if (!dirType)dir+=dir;
+ return dir * 45;
}
diff --git a/scummvm.dsp b/scummvm.dsp
index 829b6f37bb..8290c2de17 100644
--- a/scummvm.dsp
+++ b/scummvm.dsp
@@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "./sound" /I "./" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "ALLOW_GDI" /D "BYPASS_COPY_PROT" /D "USE_ADLIB" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "./sound" /I "./" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "ALLOW_GDI" /D "BYPASS_COPY_PROT" /D "USE_ADLIB" /D "DUMP_SCRIPTS" /D "FULL_THROTTLE" /D "CHECK_HEAP" /Yu"stdafx.h" /FD /GZ /c
# SUBTRACT CPP /Fr
# ADD BASE RSC /l 0x41d /d "_DEBUG"
# ADD RSC /l 0x41d /d "_DEBUG"
diff --git a/sdl.cpp b/sdl.cpp
index 8d4821118f..27ad3ee970 100644
--- a/sdl.cpp
+++ b/sdl.cpp
@@ -139,10 +139,17 @@ void waitForTimer(Scumm *s, int msec_delay) {
}
case SDL_MOUSEBUTTONDOWN:
if (event.button.button==SDL_BUTTON_LEFT)
- s->_leftBtnPressed |= 1;
+ s->_leftBtnPressed |= msClicked|msDown;
else if (event.button.button==SDL_BUTTON_RIGHT)
- s->_rightBtnPressed |= 1;
+ s->_rightBtnPressed |= msClicked|msDown;
break;
+ case SDL_MOUSEBUTTONUP:
+ if (event.button.button==SDL_BUTTON_LEFT)
+ s->_leftBtnPressed &= ~msDown;
+ else if (event.button.button==SDL_BUTTON_RIGHT)
+ s->_rightBtnPressed &= ~msDown;
+ break;
+
case SDL_QUIT:
exit(1);
break;
@@ -165,7 +172,7 @@ int old_mouse_h, old_mouse_w;
bool has_mouse,hide_mouse;
#define BAK_WIDTH 40
-#define BAK_HEIGHT 24
+#define BAK_HEIGHT 40
byte old_backup[BAK_WIDTH*BAK_HEIGHT*2];
@@ -252,6 +259,7 @@ void updateScreen(Scumm *s) {
}
if (fullRedraw) {
SDL_UpdateRect(screen, 0,0,0,0);
+ fullRedraw = false;
#if defined(SHOW_AREA)
debug(2,"update area 100 %%");
#endif
@@ -277,6 +285,8 @@ void drawMouse(Scumm *s, int xdraw, int ydraw, int w, int h, byte *buf, bool vis
if (hide_mouse)
visible = false;
+ assert(w<=BAK_WIDTH && h<=BAK_HEIGHT);
+
if (SDL_LockSurface(screen)==-1)
error("SDL_LockSurface failed: %s.\n", SDL_GetError());
diff --git a/sound.cpp b/sound.cpp
index 4854bdc58e..73c7ff235a 100644
--- a/sound.cpp
+++ b/sound.cpp
@@ -320,6 +320,8 @@ void Scumm::startSfxSound(void *file) {
int rate,comp;
byte *data;
+ /* Full throttle audio fix HERE */
+
if (fread(&hdr, sizeof(hdr), 1, (FILE*)file) != 1 ||
memcmp(hdr.id, VALID_VOC_ID, sizeof(hdr.id)) != 0) {
warning("startSfxSound: invalid header");
diff --git a/string.cpp b/string.cpp
index 0b369ec207..5ef0857329 100644
--- a/string.cpp
+++ b/string.cpp
@@ -177,17 +177,21 @@ void Scumm::CHARSET_1() {
Actor *a;
byte *buffer;
- if (!_haveMsg || (camera._destPos>>3) != (camera._curPos>>3) ||
- camera._curPos != camera._lastPos
+#if !defined(FULL_THROTTLE)
+ if (!_haveMsg || (camera._dest.x>>3) != (camera._cur.x>>3) ||
+ camera._cur.x != camera._last.x
) return;
-
+#else
+ if (!_haveMsg)
+ return;
+#endif
a = NULL;
if (_vars[VAR_TALK_ACTOR] != 0xFF)
a = derefActorSafe(_vars[VAR_TALK_ACTOR], "CHARSET_1");
if (a && string[0].overhead!=0) {
if (!(_features & GF_AFTER_V6)) {
- string[0].xpos = a->x - camera._curPos + 160;
+ string[0].xpos = a->x - camera._cur.x + 160;
if (_vars[VAR_V5_TALK_STRING_Y] < 0) {
s = (a->scaley * (int)_vars[VAR_V5_TALK_STRING_Y]) / 0xFF;
@@ -209,7 +213,7 @@ void Scumm::CHARSET_1() {
string[0].ypos = 1;
s = a->scalex * a->new_2 / 0xFF;
- string[0].xpos = ((a->new_2 - s)>>1) + s + a->x - camera._curPos + 160;
+ string[0].xpos = ((a->new_2 - s)>>1) + s + a->x - camera._cur.x + 160;
if (string[0].xpos < 80)
string[0].xpos = 80;
if (string[0].xpos > 240)
diff --git a/verbs.cpp b/verbs.cpp
index e921346c1b..95af65a705 100644
--- a/verbs.cpp
+++ b/verbs.cpp
@@ -167,8 +167,8 @@ void Scumm::drawVerbBitmap(int vrb, int x, int y) {
int ydiff, xstrip;
int imgw, imgh;
int i,tmp;
- byte *IMHD_ptr;
byte *obim;
+ ImageHeader *imhd;
if ((vs=findVirtScreen(y)) == NULL)
return;
@@ -183,12 +183,11 @@ void Scumm::drawVerbBitmap(int vrb, int x, int y) {
xstrip = x>>3;
ydiff = y - vs->topline;
-
obim = getResourceAddress(rtVerb, vrb);
- IMHD_ptr = findResource(MKID('IMHD'), obim);
- imgw = READ_LE_UINT16(IMHD_ptr+0x14) >> 3;
- imgh = READ_LE_UINT16(IMHD_ptr+0x16) >> 3;
+ imhd = (ImageHeader*)findResourceData(MKID('IMHD'), obim);
+ imgw = READ_LE_UINT16(&imhd->width) >> 3;
+ imgh = READ_LE_UINT16(&imhd->height) >> 3;
imptr = findResource(MKID('IM01'), obim);
if (!imptr)
diff --git a/windows.cpp b/windows.cpp
index 1199b675bc..d1ea84ca37 100644
--- a/windows.cpp
+++ b/windows.cpp
@@ -18,18 +18,9 @@
* $Header$
*/
-#if USE_DIRECTX
-#define INITGUID
-#include <ddraw.h>
-#endif
-
#include "stdafx.h"
#include <assert.h>
-#if USE_DRAWDIB
-#include <vfw.h>
-#endif
-
#include "scumm.h"
#include "sound.h"
#include "gui.h"
@@ -73,32 +64,16 @@ class WndMan {
bool terminated;
#if USE_GDI
-// BITMAPINFO *biHeader;
-// byte *BmpBG;
public:
DIB dib;
private:
#endif
-#if USE_DRAWDIB
- BITMAPINFOHEADER *biHeader;
- HDRAWDIB hdb;
-#endif
-
public:
byte *_vgabuf;
Scumm *_scumm;
-#if USE_DIRECTX
- IDirectDrawSurface4 *MainSurf,*Surf2;
- IDirectDraw *DxObject;
- IDirectDraw4 *Dx4Object;
- IDirectDrawPalette *DxPal;
- bool OutOfGame;
- void InitDirectX();
-#endif
-
HANDLE _event;
DWORD _threadId;
HWAVEOUT _handle;
@@ -153,8 +128,6 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l
{
case WM_DESTROY:
case WM_CLOSE:
-// TerminateThread((void*)wm->_threadId, 0);
-// wm->_scumm->destroy();
exit(0);
break;
@@ -195,10 +168,16 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l
wm->_scumm->mouse.y = ((int16*)&lParam)[1];
break;
case WM_LBUTTONDOWN:
- wm->_scumm->_leftBtnPressed |= 1;
+ wm->_scumm->_leftBtnPressed |= msClicked|msDown;
+ break;
+ case WM_LBUTTONUP:
+ wm->_scumm->_leftBtnPressed &= ~msDown;
break;
case WM_RBUTTONDOWN:
- wm->_scumm->_rightBtnPressed |= 1;
+ wm->_scumm->_rightBtnPressed |= msClicked|msDown;
+ break;
+ case WM_RBUTTONUP:
+ wm->_scumm->_rightBtnPressed &= ~msDown;
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
@@ -208,49 +187,6 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l
#if USE_GDI
-void copy_320x200_to_640x400(byte *s, byte *d) {
- _asm {
- push ebp
-
- mov esi,s
- mov edi,d
-
- mov ebp,SRC_HEIGHT
- againouter:
-
- mov ebx,320/4
- againinner:
- mov eax,[esi]
- mov dl,ah
- mov dh,ah
- shl edx,16
- mov dl,al
- mov dh,al
- shr eax,16
- mov cl,ah
- mov ch,ah
- shl ecx,16
- mov cl,al
- mov ch,al
-
- mov [edi],edx
- mov [edi+4],ecx
- mov [edi+640],edx
- mov [edi+644],ecx
-
- add esi,4
- add edi,8
-
- dec ebx
- jnz againinner
-// add esi,15
- add edi,640
- dec ebp
- jnz againouter
- pop ebp
- }
-}
-
bool WndMan::allocateDIB(int w, int h) {
struct {
BITMAPINFOHEADER bih;
@@ -281,11 +217,6 @@ void WndMan::writeToScreen() {
RECT r;
HDC dc,bmpdc;
HBITMAP bmpOld;
-// if (!BmpBG)
-// BmpBG = (byte*)LocalAlloc(LMEM_FIXED, DEST_WIDTH*DEST_HEIGHT);
-#if DEST_WIDTH==640
- copy_320x200_to_640x400(_vgabuf, dib.buf);
-#endif
#if DEST_WIDTH==320
if (_vgabuf) {
for (int y=0; y<200; y++) {
@@ -294,8 +225,6 @@ void WndMan::writeToScreen() {
}
#endif
-// setsel(dib.buf);
-
r.left = r.top = 0;
r.right = DEST_WIDTH;
r.bottom = DEST_HEIGHT;
@@ -311,14 +240,10 @@ void WndMan::writeToScreen() {
}
SetStretchBltMode(dc, BLACKONWHITE);
-#if DEST_WIDTH==640
- StretchBlt(dc, r.left, r.top, r.right-r.left, r.bottom-r.top, bmpdc, 0, 0, 640,480, SRCCOPY);
-#endif
#if DEST_WIDTH==320
StretchBlt(dc, r.left, r.top, r.right-r.left, r.bottom-r.top, bmpdc, 0, 0, 320,200, SRCCOPY);
#endif
-// //StretchDIBits(dc, r.left, r.top, r.right - r.left, r.bottom - r.top, 0, 0, DEST_WIDTH, DEST_HEIGHT, BmpBG, biHeader, DIB_RGB_COLORS, SRCCOPY);
SelectObject(bmpdc, bmpOld);
@@ -329,288 +254,17 @@ void WndMan::writeToScreen() {
void WndMan::setPalette(byte *ctab, int first, int num) {
int i;
-#if 1
for (i=0; i<256; i++) {
dib.pal[i].rgbRed = ctab[i*3+0];
dib.pal[i].rgbGreen = ctab[i*3+1];
dib.pal[i].rgbBlue = ctab[i*3+2];
}
-#else
- for (i=0; i<256; i++) {
- dib.pal[i].rgbRed = i;
- dib.pal[i].rgbGreen = i;
- dib.pal[i].rgbBlue = i;
- }
-#endif
dib.new_pal = true;
}
#endif
-#if USE_DIRECTX
-
-void WndMan::writeToScreen() {
- RECT r;
- DDSURFACEDESC2 dd;
-
- r.left = r.top = 0;
- r.right = SRC_WIDTH;
- r.bottom = SRC_HEIGHT;
-
- if (OutOfGame) {
- if (GetForegroundWindow() != hWnd) return;
- OutOfGame = false;
- }
-
- dd.dwSize = sizeof(dd);
-
- int j;
- do {
- j = MainSurf->Lock(NULL, &dd, DDLOCK_WRITEONLY, NULL);
- if (j!=DDERR_SURFACELOST) break;
- if (MainSurf->Restore() != DD_OK) {
- OutOfGame = true;
- return;
- }
- } while (1);
-
- if (j == DD_OK) {
- byte *d = (byte*)dd.lpSurface;
- byte *s = _vgabuf;
-
- for(int h=SRC_HEIGHT;--h>=0; ) {
- memcpy(d, s, SRC_WIDTH);
- d+=dd.lPitch;
- s+=SRC_PITCH;
- }
-
- MainSurf->Unlock(NULL);
- }
-}
-
-void WndMan::setPalette(byte *ctab, int first, int num) {
- PALETTEENTRY pal[256];
-
- for (int i=0; i<256; i++) {
- pal[i].peFlags = 0;
- pal[i].peRed = *ctab++;
- pal[i].peGreen = *ctab++;
- pal[i].peBlue = *ctab++;
- }
-
- DxPal->SetEntries(0, 0, 256, (PALETTEENTRY*)&pal);
-}
-
-IDirectDrawSurface4 *CreateMainSurface(IDirectDraw4 *dd);
-
-void WndMan::InitDirectX() {
-
- if (DirectDrawCreate(NULL, &DxObject, NULL) != DD_OK) Error("DirectDrawCreate failed!");
- if (DxObject->QueryInterface(IID_IDirectDraw4, (void**)&Dx4Object) != DD_OK) Error("QueryInterface failed!");
-
-if (Dx4Object->SetCooperativeLevel(hWnd,DDSCL_NORMAL) != DD_OK) Error("SetCooperativeLevel failed!");
-
- DDCAPS ddcaps;
- BOOL bHasOverlay, bHasColorKey, bCanStretch;
- ddcaps.dwSize = sizeof( ddcaps );
- if (Dx4Object->GetCaps(&ddcaps, NULL ) != DD_OK) Error("GetCaps failed!");
-
- /* Determine if the hardware supports overlay surfaces */
- bHasOverlay = ddcaps.dwCaps & DDCAPS_OVERLAY;
-
- /* Determine if the hardware supports colorkeying */
- bHasColorKey = ((ddcaps.dwCaps & DDCAPS_COLORKEY) == DDCAPS_COLORKEY) ? TRUE : FALSE;
-
- /* Determine if the hardware supports scaling of the overlay surface */
- bCanStretch = ((ddcaps.dwCaps & DDCAPS_OVERLAYSTRETCH) == DDCAPS_OVERLAYSTRETCH) ? TRUE : FALSE;
-
- if ( ( ddcaps.dwCaps & DDCAPS_ALIGNBOUNDARYDEST ) ||
- ( ddcaps.dwCaps & DDCAPS_ALIGNBOUNDARYSRC ) ||
- ( ddcaps.dwCaps & DDCAPS_ALIGNSIZEDEST ) ||
- ( ddcaps.dwCaps & DDCAPS_ALIGNSIZESRC ) ) {
-
- Error("Alignment restriction!");
- }
-
- // Are any overlays available for use?
- if ( ddcaps.dwMaxVisibleOverlays ==
- ddcaps.dwCurrVisibleOverlays )
- {
- Error("No overlay free");
-
- }
-
-
- if (!bHasOverlay || !bHasColorKey || !bCanStretch) {
- Error("Bad hardware!");
- }
-
- /* Create primary surface */
-
- DDSURFACEDESC2 ddsd;
- DDSCAPS ddscaps;
- LPDIRECTDRAWSURFACE4 lpFrontBuffer;
- LPDIRECTDRAWSURFACE4 lpBackBuffer;
- LPDIRECTDRAWSURFACE4 lpPrimary;
- HRESULT LastError;
- RECT rectOverlaySource, rectOverlayDest;
- DDOVERLAYFX ddofx;
-
-
-
-// if (!CreateMainSurface(Dx4Object))
-// Error("sad");
-
- /* Create the primary surface */
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP |
- DDSCAPS_COMPLEX |
- DDSCAPS_VIDEOMEMORY;
- ddsd.dwBackBufferCount = 1;
-
- if (Dx4Object->CreateSurface(&ddsd, &lpPrimary, NULL) != DD_OK)
- Error("Main surface creation failed!");
-
- /* Create a flippable scaleable overlay surface */
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_BACKBUFFERCOUNT | DDSD_PIXELFORMAT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_VIDEOMEMORY;
- ddsd.dwBackBufferCount = 1; /* One back buffer for triple buffering, set to 2 */
- ddsd.dwWidth = 320;
- ddsd.dwHeight = 240;
-// ddsd.ddckCKDestOverlay.dwColorSpaceLowValue = 0x123456;
-// ddsd.ddckCKDestOverlay.dwColorSpaceHighValue = 0x123456;
-
-
- ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
-
- ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
- ddsd.ddpfPixelFormat.dwFourCC = 0;
- ddsd.ddpfPixelFormat.dwRGBBitCount = 16;
- ddsd.ddpfPixelFormat.dwRBitMask = 0x7C00; //0x7C00 is a hexadecimal memory address
- ddsd.ddpfPixelFormat.dwGBitMask = 0x03e0;
- ddsd.ddpfPixelFormat.dwBBitMask = 0x001F;
- ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0;
-
-// ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
-// ddsd.ddpfPixelFormat.dwRGBBitCount = 8;
-
- if ((LastError = Dx4Object->CreateSurface(&ddsd, &lpFrontBuffer, NULL)) != DD_OK) {
- if (LastError==DDERR_NOOVERLAYHW )
- Error("No hardware!");
- else
- Error("2nd surface failed");
- }
-
-#if 0
- if (Dx4Object->SetCooperativeLevel(hWnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE) != DD_OK) Error("SetCooperativeLevel failed!");
- // if (Dx4Object->SetDisplayMode(SRC_WIDTH,SRC_HEIGHT,8,0,DDSDM_STANDARDVGAMODE) != DD_OK) Error("SetDisplayMode failed!");
- if (!(MainSurf = CreateMainSurface(Dx4Object))) Error("CreateMainSurface failed!");
- if (!(Surf2 = Create2ndSurface(Dx4Object, _vgabuf))) Error("Create 2ndSurface failed!");
- if (!(DxPal = CreateGamePalette(Dx4Object))) Error("CreateGamePalette failed!");
- if (MainSurf->SetPalette(DxPal) != DD_OK) Error("SetPalette Failed!");
-#endif
-
-}
-
-
-IDirectDrawSurface4 *CreateMainSurface(IDirectDraw4 *dd) {
- DDSURFACEDESC2 d;
- IDirectDrawSurface4 *ds;
-
-// if(dd->GetGDISurface(&ds) != DD_OK)
-// return NULL;
-
- memset(&d, 0, sizeof(d));
-
- d.dwSize = sizeof(d);
- d.dwFlags = DDSD_CAPS;
- d.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
-
- int i;
- if ((i = dd->CreateSurface(&d, &ds, NULL)) != DD_OK)
- return NULL;
-
- return ds;
-}
-
-
-IDirectDrawSurface4 *Create2ndSurface(IDirectDraw4 *dd, byte *surfmem) {
- DDSURFACEDESC2 d;
- IDirectDrawSurface4 *ds;
-
- memset(&d, 0, sizeof(d));
-
- d.dwSize = sizeof(d);
- d.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PITCH | /*DDSD_LPSURFACE |*/ DDSD_PIXELFORMAT;
- d.dwWidth = 640/*SRC_WIDTH*/;
- d.dwHeight = 480/*SRC_HEIGHT*/;
- d.lPitch = 640;
- d.lpSurface = surfmem;
-
- d.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
- d.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8;
- d.ddpfPixelFormat.dwRGBBitCount = 8;
-
- d.ddsCaps.dwCaps = DDSCAPS_OVERLAY;
-
- int i;
- if ((i = dd->CreateSurface(&d, &ds, NULL)) != DD_OK)
- return NULL;
- return ds;
-}
-
-IDirectDrawPalette *CreateGamePalette(IDirectDraw4 *dd) {
- PALETTEENTRY pal[256];
- int i;
- IDirectDrawPalette *p;
-
- memset(&pal, 0, sizeof(pal));
- if ((i=dd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256, pal, &p, NULL)) != DD_OK)
- return NULL;
-
- return p;
-}
-
-#endif
-
-#if USE_DRAWDIB
-void WndMan::writeToScreen() {
- RECT r;
- HDC dc;
-
- r.left = r.top = 0;
- r.right = DEST_WIDTH/2;
- r.bottom = DEST_HEIGHT/2;
-
- dc = GetDC(hWnd);
-
- DrawDibRealize(hdb, dc, TRUE);
- DrawDibDraw(hdb, dc, r.left, r.top, r.right-r.left, r.bottom-r.top, biHeader, _vgabuf, 0, 0, 320, 240, 0);
-
-// StretchDIBits(dc, r.left, r.top, r.right - r.left, r.bottom - r.top, 0, 0, DEST_WIDTH, DEST_HEIGHT, BmpBG, biHeader, DIB_RGB_COLORS, SRCCOPY);
- ReleaseDC(hWnd, dc);
-}
-
-void WndMan::setPalette(byte *ctab, int first, int num) {
- PALETTEENTRY pal[256];
- for (int i=0; i < num; i++,ctab+=3) {
- pal[i].peFlags = 0;
- pal[i].peRed = ctab[0];
- pal[i].peGreen = ctab[1];
- pal[i].peBlue = ctab[2];
- }
-
- DrawDibChangePalette(hdb, 0, 16, pal);
-
- GetLastError();
-}
-
-
-#endif
HWND globWnd;
void WndMan::init() {
@@ -635,25 +289,10 @@ void WndMan::init() {
if (!RegisterClassEx(&wcex))
Error("Cannot register window class!");
-#if USE_DIRECTX
- hWnd = CreateWindow("ScummVM", "ScummVM", 0,
- CW_USEDEFAULT, CW_USEDEFAULT, SRC_WIDTH, SRC_HEIGHT, NULL, NULL, hInst, NULL);
-
- SetWindowLong(hWnd, GWL_USERDATA, (long)this);
- SetWindowLong(hWnd, GWL_STYLE, 0);
- ShowCursor(false);
-
-
- InitDirectX();
-
- ShowWindow(hWnd, SW_SHOW);
-#endif
-
#if USE_GDI
globWnd = hWnd = CreateWindow("ScummVM", "ScummVM", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, DEST_WIDTH+10, DEST_HEIGHT+30, NULL, NULL, hInst, NULL);
SetWindowLong(hWnd, GWL_USERDATA, (long)this);
-// ShowCursor(false);
dib.pal = (RGBQUAD*)calloc(sizeof(RGBQUAD),256);
dib.new_pal = false;
@@ -661,46 +300,9 @@ void WndMan::init() {
if (!allocateDIB(DEST_WIDTH, DEST_HEIGHT))
Error("allocateDIB failed!");
-#if 0
- biHeader = (BITMAPINFO*)LocalAlloc(LMEM_FIXED, sizeof(BITMAPINFOHEADER) + 1024 );
- memset(biHeader, 0, sizeof(BITMAPINFOHEADER) + 1024);
-
- biHeader->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- biHeader->bmiHeader.biWidth = DEST_WIDTH;
- biHeader->bmiHeader.biHeight = -DEST_HEIGHT; /* top down */
- biHeader->bmiHeader.biPlanes = 1;
- biHeader->bmiHeader.biBitCount = 8; /* 256 colors */
- biHeader->bmiHeader.biCompression = BI_RGB; /* uncompressed */
-#endif
-
ShowWindow(hWnd, SW_SHOW);
#endif
-#if USE_DRAWDIB
- hdb = DrawDibOpen();
-
- hWnd = CreateWindow("ScummVM", "ScummVM", WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT, DEST_WIDTH+10, DEST_HEIGHT+30, NULL, NULL, hInst, NULL);
- SetWindowLong(hWnd, GWL_USERDATA, (long)this);
- ShowCursor(false);
-
- biHeader = (BITMAPINFOHEADER*)LocalAlloc(LMEM_FIXED, sizeof(BITMAPINFOHEADER));
- memset(biHeader, 0, sizeof(BITMAPINFOHEADER));
-
- biHeader->biSize = sizeof(BITMAPINFOHEADER);
- biHeader->biWidth = SRC_PITCH;
- biHeader->biHeight = SRC_HEIGHT; /* top down */
- biHeader->biPlanes = 1;
- biHeader->biBitCount = 8; /* 256 colors */
- biHeader->biCompression = BI_RGB; /* uncompressed */
-
- ShowWindow(hWnd, SW_SHOW);
-
-// int k = DrawDibProfileDisplay(biHeader);
-// printf("%d\n", k&PD_CAN_STRETCHDIB);
-
-
-#endif
}
@@ -742,24 +344,31 @@ int _declspec(naked) endpentiumtest() {
}
-
-
-void decompressMask(byte *d, byte *s) {
+void decompressMask(byte *d, byte *s, int w=320, int h=144) {
int x,y;
- byte bits = 0x80, bdata = *s++;
-
- for (y=0; y<144; y++)
- for (x=0; x<320; x++) {
- *d++ = (bdata & bits) ? 128 : 0;
+
+ for (y=0; y<h; y++) {
+ byte *p = s+y*40;
+ byte *pd = d + y*320;
+ byte bits = 0x80, bdata = *p++;
+ for (x=0; x<w; x++) {
+ *pd++ = (bdata & bits) ? 128 : 0;
bits>>=1;
if (!bits) {
- bdata = *s++;
+ bdata = *p++;
bits=0x80;
}
}
+ }
}
-
+void outputlittlemask(byte *mask, int w, int h) {
+ byte *old = wm->_vgabuf;
+ wm->_vgabuf = NULL;
+ decompressMask(wm->dib.buf, mask, w, h);
+ wm->writeToScreen();
+ wm->_vgabuf = old;
+}
void outputdisplay2(Scumm *s, int disp) {
byte *old = wm->_vgabuf;
@@ -770,12 +379,12 @@ void outputdisplay2(Scumm *s, int disp) {
case 0:
wm->_vgabuf = buf;
memcpy(buf, wm->_vgabuf, 64000);
- memcpy(buf,s->getResourceAddress(rtBuffer, 5),320*144);
+ memcpy(buf,s->getResourceAddress(rtBuffer, 5),320*200);
break;
case 1:
wm->_vgabuf = buf;
memcpy(buf, wm->_vgabuf, 64000);
- memcpy(buf,s->getResourceAddress(rtBuffer, 1),320*144);
+ memcpy(buf,s->getResourceAddress(rtBuffer, 1),320*200);
break;
case 2:
wm->_vgabuf = NULL;