diff options
-rw-r--r-- | actor.cpp | 239 | ||||
-rw-r--r-- | akos.cpp | 237 | ||||
-rw-r--r-- | boxes.cpp | 16 | ||||
-rw-r--r-- | costume.cpp | 224 | ||||
-rw-r--r-- | debug.cpp | 14 | ||||
-rw-r--r-- | gfx.cpp | 405 | ||||
-rw-r--r-- | object.cpp | 58 | ||||
-rw-r--r-- | resource.cpp | 31 | ||||
-rw-r--r-- | saveload.cpp | 38 | ||||
-rw-r--r-- | script.cpp | 15 | ||||
-rw-r--r-- | script_v1.cpp | 56 | ||||
-rw-r--r-- | script_v2.cpp | 228 | ||||
-rw-r--r-- | scumm.h | 153 | ||||
-rw-r--r-- | scummvm.cpp | 183 | ||||
-rw-r--r-- | scummvm.dsp | 2 | ||||
-rw-r--r-- | sdl.cpp | 16 | ||||
-rw-r--r-- | sound.cpp | 2 | ||||
-rw-r--r-- | string.cpp | 14 | ||||
-rw-r--r-- | verbs.cpp | 9 | ||||
-rw-r--r-- | windows.cpp | 445 |
20 files changed, 1278 insertions, 1107 deletions
@@ -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); } @@ -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 @@ -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); +} + @@ -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 }, }; @@ -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: @@ -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"
@@ -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()); @@ -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) @@ -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; |