diff options
author | Ludvig Strigeus | 2001-11-05 19:21:49 +0000 |
---|---|---|
committer | Ludvig Strigeus | 2001-11-05 19:21:49 +0000 |
commit | e5aca15a0b50a05f5dfcbb42fe0d3e771b36ffa3 (patch) | |
tree | 56763f74cbefb6091d6d76d1d3dca234acca2eeb | |
parent | cd6443a8e571bdabfd3add2d105c97db704fe31d (diff) | |
download | scummvm-rg350-e5aca15a0b50a05f5dfcbb42fe0d3e771b36ffa3.tar.gz scummvm-rg350-e5aca15a0b50a05f5dfcbb42fe0d3e771b36ffa3.tar.bz2 scummvm-rg350-e5aca15a0b50a05f5dfcbb42fe0d3e771b36ffa3.zip |
bug fixes,
speech in dott
svn-id: r3454
-rw-r--r-- | Makefile | 16 | ||||
-rw-r--r-- | actor.cpp | 36 | ||||
-rw-r--r-- | boxes.cpp | 36 | ||||
-rw-r--r-- | costume.cpp | 65 | ||||
-rw-r--r-- | gfx.cpp | 103 | ||||
-rw-r--r-- | object.cpp | 46 | ||||
-rw-r--r-- | resource.cpp | 153 | ||||
-rw-r--r-- | saveload.cpp | 172 | ||||
-rw-r--r-- | script.cpp | 39 | ||||
-rw-r--r-- | script_v1.cpp | 77 | ||||
-rw-r--r-- | script_v2.cpp | 72 | ||||
-rw-r--r-- | scumm.h | 225 | ||||
-rw-r--r-- | scummsys.h | 9 | ||||
-rw-r--r-- | scummvm.cpp | 66 | ||||
-rw-r--r-- | scummvm.dsp | 20 | ||||
-rw-r--r-- | sdl.cpp | 166 | ||||
-rw-r--r-- | sound.cpp | 295 | ||||
-rw-r--r-- | stdafx.h | 12 | ||||
-rw-r--r-- | string.cpp | 92 | ||||
-rw-r--r-- | sys.cpp | 22 | ||||
-rw-r--r-- | verbs.cpp | 20 | ||||
-rw-r--r-- | windows.cpp | 109 |
22 files changed, 1363 insertions, 488 deletions
@@ -1,17 +1,8 @@ -# $Id$ -# -# $Log$ -# Revision 1.7 2001/11/03 06:17:36 cmatsuoka -# Using full path for SDL includes (-ISDL doesn't seem to work for -# native builds). -# - CC = gcc CFLAGS = -g -Wno-multichar DEFINES = -DUNIX -LDFLAGS := -INCLUDES:= -I/usr/include/SDL -D_REENTRANT -LIBS := -lSDL +LDFLAGS := `sdl-config --libs` +INCLUDES:= `sdl-config --cflags` CPPFLAGS= $(DEFINES) $(INCLUDES) ZIPFILE := scummvm-`date '+%Y-%m-%d'`.zip @@ -44,6 +35,3 @@ dist: check: $(OBJS): $(INCS) - -$(OBJS): Makefile - @@ -17,6 +17,10 @@ * * Change Log: * $Log$ + * Revision 1.8 2001/11/05 19:21:49 strigeus + * bug fixes, + * speech in dott + * * Revision 1.7 2001/10/26 17:34:50 strigeus * bug fixes, code cleanup * @@ -241,7 +245,7 @@ void Scumm::setupActorScale(Actor *a) { if (scale & 0x8000) { scale = (scale&0x7FFF)+1; - resptr = getResourceAddress(0xB, scale); + resptr = getResourceAddress(rtScaleTable, scale); if (resptr==NULL) error("Scale table %d not defined",scale); if (a->y >= 0) @@ -584,7 +588,7 @@ void Scumm::showActor(Actor *a) { adjustActorPos(a); - ensureResourceLoaded(3, a->costume); + ensureResourceLoaded(rtCostume, a->costume); if (a->costumeNeedsInit) { startAnimActor(a, a->initFrame, a->facing); @@ -615,8 +619,9 @@ void Scumm::stopTalk() { act = _vars[VAR_TALK_ACTOR]; if (act && act<0x80) { Actor *a = derefActorSafe(act, "stopTalk"); - if (_currentRoom == a->room) { - startAnimActor(a, a->talkFrame2, a->facing); + if (_currentRoom == a->room && _useTalkAnims) { + startAnimActor(a, a->talkFrame2, a->facing); + _useTalkAnims = false; } _vars[VAR_TALK_ACTOR] = 0xFF; } @@ -824,7 +829,7 @@ void Scumm::actorAnimate(Actor *a) { if (a->animProgress >= a->animSpeed) { a->animProgress = 0; cost.loadCostume(a->costume); - if (cost.animate(&a->cost)) { + if (cost.animate(a)) { a->needRedraw = true; a->needBgReset = true; } @@ -885,7 +890,10 @@ void Scumm::actorTalk() { if (!_keepText) stopTalk(); _vars[VAR_TALK_ACTOR] = a->number; - startAnimActor(a,a->talkFrame1,a->facing); + if (!string[0].no_talk_anim) { + startAnimActor(a,a->talkFrame1,a->facing); + _useTalkAnims = true; + } oldact = _vars[VAR_TALK_ACTOR]; } } @@ -976,8 +984,22 @@ void Scumm::startWalkActor(Actor *a, int x, int y, int dir) { } byte *Scumm::getActorName(Actor *a) { - byte *ptr = getResourceAddress(9, a->number); + byte *ptr = getResourceAddress(rtActorName, a->number); if(ptr==NULL) return (byte*)" "; return ptr; } + +bool Scumm::isCostumeInUse(int cost) { + int i; + Actor *a; + + if (_roomResource!=0) + for (i=1; i<13; i++) { + a = derefActor(i); + if (a->room == _currentRoom && a->costume == cost) + return true; + } + + return false; +}
\ No newline at end of file @@ -17,6 +17,10 @@ * * Change Log: * $Log$ + * Revision 1.3 2001/11/05 19:21:49 strigeus + * bug fixes, + * speech in dott + * * Revision 1.2 2001/10/11 10:45:39 strigeus * Fixed bug in Scumm::getBoxCoordinates where unsigned integers were read * instead of signed ones. @@ -47,12 +51,12 @@ int Scumm::getBoxScale(int box) { } byte Scumm::getNumBoxes() { - byte *ptr = getResourceAddress(0xE, 2); + byte *ptr = getResourceAddress(rtMatrix, 2); return ptr[8]; } Box *Scumm::getBoxBaseAddr(int box) { - byte *ptr = getResourceAddress(0xE, 2); + byte *ptr = getResourceAddress(rtMatrix, 2); checkRange(ptr[8]-1, 0, box, "Illegal box %d"); return (Box*)(ptr + box*SIZEOF_BOX + 10); } @@ -295,7 +299,7 @@ AdjustBoxResult Scumm::getClosestPtOnBox(int b, int x, int y) { } byte *Scumm::getBoxMatrixBaseAddr() { - byte *ptr = getResourceAddress(0xE, 1) + 8; + byte *ptr = getResourceAddress(rtMatrix, 1) + 8; if (*ptr==0xFF) ptr++; return ptr; } @@ -512,19 +516,19 @@ void Scumm::createBoxMatrix() { _maxBoxVertexHeap = 1000; - createResource(0xE, 4, 1000); - createResource(0xE, 3, 4160); //65 items of something of size 64 - createResource(0xE, 1, BOX_MATRIX_SIZE+8); + createResource(rtMatrix, 4, 1000); + createResource(rtMatrix, 3, 4160); //65 items of something of size 64 + createResource(rtMatrix, 1, BOX_MATRIX_SIZE+8); - matrix_ptr = getResourceAddress(0xE, 1); + 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(0xE, 4); - _boxMatrixPtr1 = getResourceAddress(0xE, 1) + 8; - _boxMatrixPtr3 = getResourceAddress(0xE, 3); + _boxMatrixPtr4 = getResourceAddress(rtMatrix, 4); + _boxMatrixPtr1 = getResourceAddress(rtMatrix, 1) + 8; + _boxMatrixPtr3 = getResourceAddress(rtMatrix, 3); _boxPathVertexHeapIndex = _boxMatrixItem = 0; @@ -628,8 +632,8 @@ void Scumm::createBoxMatrix() { } addToBoxMatrix(0xFF); - nukeResource(0xE, 4); - nukeResource(0xE, 3); + nukeResource(rtMatrix, 4); + nukeResource(rtMatrix, 3); } PathVertex *Scumm::unkMatrixProc1(PathVertex *vtx, PathNode *node) { @@ -716,7 +720,6 @@ bool Scumm::areBoxesNeighbours(int box1, int box2) { if (upperRightX == upperLeftX && box.upperLeftX == upperLeftX && box.upperRightX == upperRightX) { - /* 5b74 */ n = m = 0; if (upperRightY < upperLeftY) { n = 1; @@ -732,7 +735,6 @@ bool Scumm::areBoxesNeighbours(int box1, int box2) { box.upperRightY==upperLeftY) && upperRightY != upperLeftY && box.upperLeftY!=box.upperRightY) { - /* if_1_if */ if (n) { SWAP(upperRightY, upperLeftY); } @@ -740,7 +742,6 @@ bool Scumm::areBoxesNeighbours(int box1, int box2) { SWAP(box.upperRightY, box.upperLeftY); } } else { - /* if_1_else */ if (n) { SWAP(upperRightY, upperLeftY); } @@ -751,7 +752,6 @@ bool Scumm::areBoxesNeighbours(int box1, int box2) { } } - /* do_it_for_y */ if (upperRightY == upperLeftY && box.upperLeftY == upperLeftY && box.upperRightY == upperRightY) { @@ -771,7 +771,6 @@ bool Scumm::areBoxesNeighbours(int box1, int box2) { upperRightX != upperLeftX && box.upperLeftX!=box.upperRightX) { - /* if_2_if */ if (n) { SWAP(upperRightX, upperLeftX); } @@ -779,7 +778,6 @@ bool Scumm::areBoxesNeighbours(int box1, int box2) { SWAP(box.upperRightX, box.upperLeftX); } } else { - /* if_2_else */ if (n) { SWAP(upperRightX, upperLeftX); } @@ -836,7 +834,7 @@ void *Scumm::addToBoxVertexHeap(int size) { } PathVertex *Scumm::addPathVertex() { - _boxMatrixPtr4 = getResourceAddress(0xE, 4); + _boxMatrixPtr4 = getResourceAddress(rtMatrix, 4); _boxPathVertexHeapIndex = 0; return (PathVertex*)addToBoxVertexHeap(sizeof(PathVertex)); } diff --git a/costume.cpp b/costume.cpp index 62d882b9ea..d4327290de 100644 --- a/costume.cpp +++ b/costume.cpp @@ -17,6 +17,10 @@ * * Change Log: * $Log$ + * Revision 1.7 2001/11/05 19:21:49 strigeus + * bug fixes, + * speech in dott + * * Revision 1.6 2001/10/26 17:34:50 strigeus * bug fixes, code cleanup * @@ -275,6 +279,8 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) { if ((uint)_top > (uint)_vscreenheight) _top = 0; + if (_left<0) _left=0; + if ((uint)_bottom > _vscreenheight) _bottom = _vscreenheight; @@ -289,19 +295,20 @@ byte CostumeRenderer::mainRoutine(Actor *a, int slot, int frame) { return 2; } - _bgbak_ptr = _vm->getResourceAddress(0xA, 5) + _vm->virtscr[0].xstart + _ypos*320 + _xpos; - _backbuff_ptr = _vm->getResourceAddress(0xA, 1) + _vm->virtscr[0].xstart + _ypos*320 + _xpos; + + _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); masking = 0; if (_zbuf) { masking = _vm->isMaskActiveAt(_left, _top, _right, _bottom, - _vm->getResourceAddress(0xA, 9) + _vm->gdi._imgBufOffs[_zbuf] + _vm->_screenStartStrip + _vm->getResourceAddress(rtBuffer, 9) + _vm->gdi._imgBufOffs[_zbuf] + _vm->_screenStartStrip ); } if (_zbuf || charsetmask) { - _mask_ptr = _vm->getResourceAddress(0xA, 9) + _ypos*40 + _vm->_screenStartStrip; + _mask_ptr = _vm->getResourceAddress(rtBuffer, 9) + _ypos*40 + _vm->_screenStartStrip; _imgbufoffs = _vm->gdi._imgBufOffs[_zbuf]; if (!charsetmask && _zbuf!=0) @@ -680,7 +687,6 @@ StartPos:; } void CostumeRenderer::loadCostume(int id) { - _ptr = _vm->getResourceAddress(3, id); if (_vm->_majorScummVersion == 6) { @@ -739,51 +745,62 @@ byte CostumeRenderer::drawCostume(Actor *a) { return r; } -byte CostumeRenderer::animateOneSlot(CostumeData *cd, int slot) { +byte CostumeRenderer::animateOneSlot(Actor *a, int slot) { int highflag; - int i,end,code; + int i,end; + byte code,nc; - if (cd->a[slot]==0xFFFF) + if (a->cost.a[slot]==0xFFFF) return 0; - highflag = cd->a[slot]&0x8000; - i = cd->a[slot]&0x7FFF; - end = cd->c[slot]; + highflag = a->cost.a[slot]&0x8000; + i = a->cost.a[slot]&0x7FFF; + end = a->cost.c[slot]; code=_dataptr[i]&0x7F; do { if (!highflag) { if (i++ >= end) - i = cd->b[slot]; + i = a->cost.b[slot]; } else { if (i != end) i++; } - if (_dataptr[i]==0x7C) { - cd->animCounter1++; - if(cd->b[slot] != end) - continue; - } + nc = _dataptr[i]; - if (_dataptr[i]==0x78) { - cd->animCounter2++; - if(cd->b[slot] != end) + if (nc==0x7C) { + a->cost.animCounter1++; + if(a->cost.b[slot] != end) continue; + } else { + if (_vm->_majorScummVersion == 6) { + if (nc>=0x71 && nc<=0x78) { + _vm->addSoundToQueue2(a->sound[nc-0x71]); + if(a->cost.b[slot] != end) + continue; + } + } else { + if (nc==0x78) { + a->cost.animCounter2++; + if(a->cost.b[slot] != end) + continue; + } + } } - cd->a[slot] = i|highflag; + a->cost.a[slot] = i|highflag; return (_dataptr[i]&0x7F) != code; } while(1); } -byte CostumeRenderer::animate(CostumeData *cd) { +byte CostumeRenderer::animate(Actor *a) { int i; byte r = 0; for (i=0; i<16; i++) { - if(cd->a[i]!=0xFFFF) - r+=animateOneSlot(cd, i); + if(a->cost.a[i]!=0xFFFF) + r+=animateOneSlot(a, i); } return r; } @@ -17,6 +17,10 @@ * * Change Log: * $Log$ + * Revision 1.11 2001/11/05 19:21:49 strigeus + * bug fixes, + * speech in dott + * * Revision 1.10 2001/10/29 23:07:24 strigeus * better MI1 compatibility * @@ -82,11 +86,11 @@ void Scumm::initScreens(int a, int b, int w, int h) { int i; for (i=0; i<3; i++) { - nukeResource(10, i+1); - nukeResource(10, i+5); + nukeResource(rtBuffer, i+1); + nukeResource(rtBuffer, i+5); } - if (!getResourceAddress(10,4)) { + if (!getResourceAddress(rtBuffer,4)) { initVirtScreen(3, 80, 13, false, false); } initVirtScreen(0, b, h-b, true, true); @@ -118,10 +122,10 @@ void Scumm::initVirtScreen(int slot, int top, int height, bool twobufs, bool fou if (vs->scrollable) size += 320*4; - memset(createResource(10, slot+1, size),0,size); + memset(createResource(rtBuffer, slot+1, size),0,size); if (twobufs) { - memset(createResource(10, slot+5, size),0x23,size); + memset(createResource(rtBuffer, slot+5, size),0x23,size); } if (slot != 3) { @@ -149,7 +153,7 @@ void Scumm::unkVirtScreen2() { } else { vs = &virtscr[0]; - blitToScreen(this, getResourceAddress(10, 1) + _screenStartStrip*8, + blitToScreen(this, getResourceAddress(rtBuffer, 1) + _screenStartStrip*8, 0, vs->topline, 320, vs->height); for (i = 0; i<40; i++) { @@ -206,7 +210,7 @@ void Gdi::drawStripToScreen(VirtScreen *vs, int x, int w, int t, int b) { if (b > vs->height) b = vs->height; - ptr = _vm->getResourceAddress(10, vs->number+1) + (t*40+x)*8 + _readOffs; + ptr = _vm->getResourceAddress(rtBuffer, vs->number+1) + (t*40+x)*8 + _readOffs; blitToScreen(_vm, ptr, x*8, vs->topline+t, w, b-t); } @@ -344,7 +348,7 @@ void Scumm::initBGBuffers() { int size, itemsize, i; byte *room; - room = getResourceAddress(1, _roomResource); + room = getResourceAddress(rtRoom, _roomResource); ptr = findResource(MKID('RMIH'), findResource(MKID('RMIM'), room, 0), 0); @@ -355,7 +359,7 @@ void Scumm::initBGBuffers() { itemsize = (_scrHeight + 4) * 40; size = itemsize * gdi._numZBuffer; - memset(createResource(10, 9, size), 0, size); + memset(createResource(rtBuffer, 9, size), 0, size); for (i=0; i<4; i++) gdi._imgBufOffs[i] = i*itemsize; @@ -391,7 +395,7 @@ void Scumm::setPaletteFromPtr(byte *ptr) { } if (_videoMode==0xE) { - epal = getResourceAddress(1, _roomResource) + _EPAL_offs + 8; + epal = getResourceAddress(rtRoom, _roomResource) + _EPAL_offs + 8; for (i=0; i<256; i++,epal++) { _currentPalette[i] = *epal&0xF; _currentPalette[i+256] = *epal>>4; @@ -403,7 +407,7 @@ void Scumm::setPaletteFromPtr(byte *ptr) { void Scumm::setPaletteFromRes() { byte *ptr; - ptr = getResourceAddress(1, _roomResource) + _CLUT_offs; + ptr = getResourceAddress(rtRoom, _roomResource) + _CLUT_offs; setPaletteFromPtr(ptr); } @@ -503,11 +507,11 @@ void Scumm::moveMemInPalRes(int start, int end, byte direction) { if (!_palManipCounter) return; - startptr = getResourceAddress(0xC, 4) + start * 6; - endptr = getResourceAddress(0xC, 4) + end * 6; + startptr = getResourceAddress(rtTemp, 4) + start * 6; + endptr = getResourceAddress(rtTemp, 4) + end * 6; - startptr2 = getResourceAddress(0xC, 5) + start * 6; - endptr2 = getResourceAddress(0xC, 5) + end * 6; + startptr2 = getResourceAddress(rtTemp, 5) + start * 6; + endptr2 = getResourceAddress(rtTemp, 5) + end * 6; num = end - start; @@ -541,7 +545,7 @@ void Scumm::unkVirtScreen4(int a) { return; vs = &virtscr[0]; - gdi._backbuff_ptr = getResourceAddress(0xA, 1) + vs->xstart; + gdi._backbuff_ptr = getResourceAddress(rtBuffer, 1) + vs->xstart; memset(gdi._backbuff_ptr, 0, vs->size); switch(a) { @@ -655,12 +659,12 @@ void Gdi::drawBitmap(byte *ptr, VirtScreen *vs, int x, int y, int h, int stripnr if (bottom > vs->bdirty[sx]) vs->bdirty[sx] = bottom; - _backbuff_ptr = _vm->getResourceAddress(0xA, vs->number+1) + (y*40+x)*8; - _bgbak_ptr = _vm->getResourceAddress(0xA, vs->number+5) + (y*40+x)*8; + _backbuff_ptr = _vm->getResourceAddress(rtBuffer, vs->number+1) + (y*40+x)*8; + _bgbak_ptr = _vm->getResourceAddress(rtBuffer, vs->number+5) + (y*40+x)*8; if (!twobufs) { _bgbak_ptr = _backbuff_ptr; } - _mask_ptr = _vm->getResourceAddress(0xA, 9) + (y*40+x); + _mask_ptr = _vm->getResourceAddress(rtBuffer, 9) + (y*40+x); where_draw_ptr = _bgbak_ptr; decompressBitmap(); @@ -688,8 +692,8 @@ void Gdi::drawBitmap(byte *ptr, VirtScreen *vs, int x, int y, int h, int stripnr if (!zplane_list[i]) continue; _z_plane_ptr = zplane_list[i] + READ_LE_UINT16(zplane_list[i] + stripnr*2 + 8); - _mask_ptr_dest = _vm->getResourceAddress(0xA, 9) + y*40 + x + _imgBufOffs[i]; - if (dseg_4E3B!=0 && flag) + _mask_ptr_dest = _vm->getResourceAddress(rtBuffer, 9) + y*40 + x + _imgBufOffs[i]; + if (_useOrDecompress && flag) decompressMaskImgOr(); else decompressMaskImg(); @@ -706,7 +710,7 @@ void Gdi::decompressBitmap() { 0x0, 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x0, }; - dseg_4E3B = 0; + _useOrDecompress = true; byte code = *_smap_ptr++; @@ -729,14 +733,14 @@ void Gdi::decompressBitmap() { break; case 34: case 35: case 36: case 37: case 38: - dseg_4E3B = 1; + _useOrDecompress = true; _decomp_shr = code - 30; _decomp_mask = decompress_table[code - 30 ]; unkDecode4(); break; case 44: case 45: case 46: case 47: case 48: - dseg_4E3B = 1; + _useOrDecompress = true; _decomp_shr = code - 40; _decomp_mask = decompress_table[code - 40]; unkDecode2(); @@ -749,7 +753,7 @@ void Gdi::decompressBitmap() { break; case 84: case 85: case 86: case 87: case 88: - dseg_4E3B = 1; + _useOrDecompress = true; _decomp_shr = code - 80; _decomp_mask = decompress_table[code - 80]; unkDecode3(); @@ -764,7 +768,7 @@ void Gdi::decompressBitmap() { /* New since version 6 */ case 124: case 125: case 126: case 127: case 128: - dseg_4E3B = 1; + _useOrDecompress = true; _decomp_shr = code - 120; _decomp_mask = decompress_table[code - 120]; unkDecode3(); @@ -918,7 +922,7 @@ void Scumm::redrawBGStrip(int start, int num) { _scrHeight); } - gdi.drawBitmap(getResourceAddress(1, _roomResource)+_IM00_offs, + gdi.drawBitmap(getResourceAddress(rtRoom, _roomResource)+_IM00_offs, _curVirtScreen, s, 0, _curVirtScreen->height, s, num, 0); } @@ -1250,9 +1254,9 @@ void Scumm::restoreBG(int left, int top, int right, int bottom) { height = (top-topline) * 320 + vs->xstart + left; - backbuff = getResourceAddress(0xA, vs->number+1) + height; - bgbak = getResourceAddress(0xA, vs->number+5) + height; - mask = getResourceAddress(0xA, 9) + top * 40 + (left>>3) + _screenStartStrip; + backbuff = getResourceAddress(rtBuffer, vs->number+1) + height; + bgbak = getResourceAddress(rtBuffer, vs->number+5) + height; + mask = getResourceAddress(rtBuffer, 9) + top * 40 + (left>>3) + _screenStartStrip; if (vs->number==0) { mask += vs->topline * 216; } @@ -1455,7 +1459,7 @@ void Scumm::setShake(int mode) { void Gdi::clearUpperMask() { memset( - _vm->getResourceAddress(0xA, 9), + _vm->getResourceAddress(rtBuffer, 9), 0, _imgBufOffs[1] - _imgBufOffs[0] ); @@ -1593,8 +1597,8 @@ void Scumm::palManipulate() { if (!_palManipCounter) return; - srcptr = getResourceAddress(0xC, 4) + _palManipStart*6; - destptr = getResourceAddress(0xC, 5) + _palManipStart*6; + srcptr = getResourceAddress(rtTemp, 4) + _palManipStart*6; + destptr = getResourceAddress(rtTemp, 5) + _palManipStart*6; pal = _currentPalette + _palManipStart * 3; i = _palManipStart; @@ -1618,8 +1622,8 @@ void Scumm::palManipulate() { } setDirtyColors(_palManipStart, _palManipEnd); if (!--_palManipCounter) { - nukeResource(0xC, 4); - nukeResource(0xC, 5); + nukeResource(rtTemp, 4); + nukeResource(rtTemp, 5); } } @@ -1635,6 +1639,7 @@ void Scumm::screenEffect(int effect) { case 133: unkScreenEffect4(); break; case 134: unkScreenEffect5(0); break; case 135: unkScreenEffect5(1); break; + case 129: break; default: warning("Unknown screen effect, %d", effect); } @@ -1683,9 +1688,9 @@ void Gdi::resetBackground(byte top, byte bottom, int strip) { vs->bdirty[strip] = bottom; offs = (top * 40 + _vm->_screenStartStrip + strip); - _mask_ptr = _vm->getResourceAddress(0xA, 9) + offs; - _bgbak_ptr = _vm->getResourceAddress(0xA, 5) + (offs<<3); - _backbuff_ptr = _vm->getResourceAddress(0xA, 1) + (offs<<3); + _mask_ptr = _vm->getResourceAddress(rtBuffer, 9) + offs; + _bgbak_ptr = _vm->getResourceAddress(rtBuffer, 5) + (offs<<3); + _backbuff_ptr = _vm->getResourceAddress(rtBuffer, 1) + (offs<<3); _numLinesToProcess = bottom - top; if (_numLinesToProcess) { @@ -1762,6 +1767,10 @@ void Scumm::setCursorImg(int room, int img) { byte Scumm::isMaskActiveAt(int l, int t, int r, int b, byte *mem) { int w,h,inc,i; + + if (l<0 || t<0) { + l = 0; + } mem += b*40 + (l>>3); @@ -1812,7 +1821,7 @@ byte *Scumm::findPalInPals(byte *pal, int index) { byte *Scumm::getPalettePtr() { byte *cptr; - cptr = getResourceAddress(1, _roomResource); + cptr = getResourceAddress(rtRoom, _roomResource); if (_CLUT_offs) { cptr += _CLUT_offs; } else { @@ -1876,13 +1885,21 @@ void Scumm::unkMiscOp4(int a, int b, int c, int d) { } grabCursor( - getResourceAddress(10, vs->number+1) + (b-vs->topline)*320 + a, + getResourceAddress(rtBuffer, vs->number+1) + (b-vs->topline)*320 + a, c,d); - - - warning("stub unkMiscOp4(%d,%d,%d,%d)", a,b,c,d); + +// _cursor_width = c; +// _cursor_height = d; } void Scumm::grabCursor(byte *ptr, int width, int height) { +#if 0 + int size; + byte *ptr; + size = width * height; + if (size > 10240) + error("grabCursor: grabbed cursor too big"); + ptr = createResource( +#endif } diff --git a/object.cpp b/object.cpp index 36b8390998..5d44855b19 100644 --- a/object.cpp +++ b/object.cpp @@ -17,6 +17,10 @@ * * Change Log: * $Log$ + * Revision 1.8 2001/11/05 19:21:49 strigeus + * bug fixes, + * speech in dott + * * Revision 1.7 2001/10/26 17:34:50 strigeus * bug fixes, code cleanup * @@ -154,10 +158,10 @@ void Scumm::getObjectXYPos(int object) { state = 0; if (od->fl_object_index) { - ptr = getResourceAddress(0xD, od->fl_object_index); + ptr = getResourceAddress(rtFlObject, od->fl_object_index); ptr = findResource(MKID('OBIM'), ptr, 0); } else { - ptr = getResourceAddress(1, _roomResource); + ptr = getResourceAddress(rtRoom, _roomResource); ptr += od->offs_obim_to_room; } @@ -302,10 +306,10 @@ void Scumm::drawObject(int obj, int arg) { return; if (od->fl_object_index) { - ptr = getResourceAddress(0xD, od->fl_object_index); + ptr = getResourceAddress(rtFlObject, od->fl_object_index); ptr = findResource(MKID('OBIM'), ptr, 0); } else { - ptr = getResourceAddress(1, _roomResource); + ptr = getResourceAddress(rtRoom, _roomResource); ptr = ptr + od->offs_obim_to_room; } @@ -351,7 +355,7 @@ void Scumm::loadRoomObjects() { CHECK_HEAP - room = getResourceAddress(1, _roomResource); + room = getResourceAddress(rtRoom, _roomResource); roomhdr = (RoomHeader*)findResource(MKID('RMHD'), room, 0); _numObjectsInRoom = READ_LE_UINT16(&roomhdr->numObjects); @@ -465,7 +469,7 @@ void Scumm::clearOwnerOf(int obj) { if (_objs[i].obj_nr==obj) { if (!_objs[i].fl_object_index) return; - nukeResource(0xD, _objs[i].fl_object_index); + nukeResource(rtFlObject, _objs[i].fl_object_index); _objs[i].obj_nr = 0; _objs[i].fl_object_index = 0; } @@ -476,7 +480,7 @@ void Scumm::clearOwnerOf(int obj) { if (_inventory[i] == obj) { j = whereIsObject(obj); if (j==0) { - nukeResource(5, i); + nukeResource(rtInventory, i); _inventory[i] = 0; } a = &_inventory[1]; @@ -484,7 +488,7 @@ void Scumm::clearOwnerOf(int obj) { if (!a[0] && a[1]) { a[0] = a[1]; a[1] = 0; - ptr = getResourceAddress(5, i+1); + ptr = getResourceAddress(rtInventory, i+1); _baseInventoryItems[i] = _baseInventoryItems[i+1]; _baseInventoryItems[i+1] = 0; /* TODO: some wacky write is done here */ @@ -558,14 +562,14 @@ byte *Scumm::getObjectAddress(int obj) { if ((_objectFlagTable[obj]&0xF)!=0xF) { for(i=0; i<_maxInventoryItems; i++) { if (_inventory[i] == obj) - return getResourceAddress(5, i); + return getResourceAddress(rtInventory, i); } } else { for(i=_numObjectsInRoom; i>0; --i) { if (_objs[i].obj_nr==obj) { if (_objs[i].fl_object_index) - return getResourceAddress(0xD, _objs[i].fl_object_index)+8; - return getResourceAddress(1, _roomResource) + _objs[i].offs_obcd_to_room; + return getResourceAddress(rtFlObject, _objs[i].fl_object_index)+8; + return getResourceAddress(rtRoom, _roomResource) + _objs[i].offs_obcd_to_room; } } } @@ -587,18 +591,18 @@ void Scumm::addObjectToInventory(int obj, int room) { if (whereIsObject(obj)==4) { i = getObjectIndex(obj); - ptr = getResourceAddress(0xD, _objs[i].fl_object_index) + 64; + ptr = getResourceAddress(rtFlObject, _objs[i].fl_object_index) + 64; size = READ_BE_UINT32_UNALIGNED(ptr+4); slot = getInventorySlot(); _inventory[slot] = obj; - createResource(5, slot, size); - ptr = getResourceAddress(0xD, _objs[i].fl_object_index) + 64; - memcpy(getResourceAddress(5, slot), ptr, size); + createResource(rtInventory, slot, size); + ptr = getResourceAddress(rtFlObject, _objs[i].fl_object_index) + 64; + memcpy(getResourceAddress(rtInventory, slot), ptr, size); CHECK_HEAP return; } - ensureResourceLoaded(1, room); - roomptr = getResourceAddress(1, room); +// ensureResourceLoaded(rtRoom, room); + roomptr = getResourceAddress(rtRoom, room); roomhdr = (RoomHeader*)findResource(MKID('RMHD'), roomptr, 0); numobj = READ_LE_UINT16(&roomhdr->numObjects); if (numobj==0) @@ -616,9 +620,9 @@ void Scumm::addObjectToInventory(int obj, int room) { size = READ_BE_UINT32_UNALIGNED(obcdptr+4); slot = getInventorySlot(); _inventory[slot] = obj; - createResource(5, slot, size); - obcdptr = getResourceAddress(1, room) + cdoffs; - memcpy(getResourceAddress(5,slot),obcdptr,size); + createResource(rtInventory, slot, size); + obcdptr = getResourceAddress(rtRoom, room) + cdoffs; + memcpy(getResourceAddress(rtInventory,slot),obcdptr,size); CHECK_HEAP return; } @@ -713,7 +717,7 @@ void Scumm::setObjectState(int obj, int state, int x, int y) { if (x != -1) { _objs[i].x_pos = x; - _objs[i].x_pos = y; + _objs[i].y_pos = y; } addObjectToDrawQue(i); diff --git a/resource.cpp b/resource.cpp index 973940eabb..fa0f3c5033 100644 --- a/resource.cpp +++ b/resource.cpp @@ -17,6 +17,10 @@ * * Change Log: * $Log$ + * Revision 1.9 2001/11/05 19:21:49 strigeus + * bug fixes, + * speech in dott + * * Revision 1.8 2001/10/29 21:49:25 strigeus * fixed bug in validateResource * @@ -424,7 +428,7 @@ void Scumm::loadCharset(int no) { debug(9, "loadCharset(%d)",no); checkRange(_maxCharsets-1, 1, no, "Loading illegal charset %d"); - ensureResourceLoaded(6, no); +// ensureResourceLoaded(6, no); ptr = getResourceAddress(6, no); for (i=0; i<15; i++) { @@ -434,7 +438,7 @@ void Scumm::loadCharset(int no) { void Scumm::nukeCharset(int i) { checkRange(_maxCharsets-1, 1, i, "Nuking illegal charset %d"); - nukeResource(6, i); + nukeResource(rtCharset, i); } void Scumm::ensureResourceLoaded(int type, int i) { @@ -506,7 +510,7 @@ int Scumm::loadResource(int type, int index) { /* dump the resource */ #ifdef DUMP_SCRIPTS if(type==2) { - dumpResource("script-", index, getResourceAddress(2, index)); + dumpResource("script-", index, getResourceAddress(rtScript, index)); } #endif @@ -540,11 +544,11 @@ int Scumm::readSoundResource(int type, int index) { resStart += size2 + 8; - for (i=0,ptr=_soundTagTable; i<_numSoundTags; i++,ptr+=5) { + for (i=0,ptr=_soundTagTable; i<_numSoundTags; i++,ptr+=4) { /* endian OK, tags are in native format */ if (READ_UINT32_UNALIGNED(ptr) == tag) { fileSeek(_fileHandle, -8, SEEK_CUR); - fileRead(_fileHandle,createResource(type, index, size2+8), size+8); + fileRead(_fileHandle,createResource(type, index, size2+8), size2+8); return 1; } } @@ -575,7 +579,7 @@ byte *Scumm::getResourceAddress(int type, int index) { ensureResourceLoaded(type, index); } - setResourceFlags(type, index, 1); + setResourceCounter(type, index, 1); ptr=(byte*)res.address[type][index]; if (!ptr) @@ -585,7 +589,7 @@ byte *Scumm::getResourceAddress(int type, int index) { } byte *Scumm::getStringAddress(int i) { - byte *b = getResourceAddress(7, i); + byte *b = getResourceAddress(rtString, i); if (!b) return b; @@ -594,11 +598,14 @@ byte *Scumm::getStringAddress(int i) { return b; } -void Scumm::setResourceFlags(int type, int index, byte flag) { +void Scumm::setResourceCounter(int type, int index, byte flag) { res.flags[type][index] &= 0x80; res.flags[type][index] |= flag; } +/* 2 bytes safety area to make "precaching" of bytes in the gdi drawer easier */ +#define SAFETY_AREA 2 + byte *Scumm::createResource(int type, int index, uint32 size) { byte *ptr; @@ -612,19 +619,20 @@ byte *Scumm::createResource(int type, int index, uint32 size) { validateResource("allocating", type, index); nukeResource(type, index); + expireResources(size); + CHECK_HEAP - ptr = (byte*)alloc(size + sizeof(ResHeader)); + ptr = (byte*)alloc(size + sizeof(ResHeader) + SAFETY_AREA); if (ptr==NULL) { error("Out of memory while allocating %d", size); } - res.address[type][index] = ptr; + _allocatedSize += size; + res.address[type][index] = ptr; ((ResHeader*)ptr)->size = size; - - setResourceFlags(type, index, 1); - + setResourceCounter(type, index, 1); return ptr + sizeof(ResHeader); /* skip header */ } @@ -635,27 +643,22 @@ void Scumm::validateResource(const char *str, int type, int index) { } void Scumm::nukeResource(int type, int index) { - + byte *ptr; + debug(9, "nukeResource(%d,%d)", type, index); CHECK_HEAP assert( res.address[type] ); assert( index>=0 && index < res.num[type]); - if (res.address[type][index]) { - free(res.address[type][index]); + if ((ptr = res.address[type][index]) != NULL) { res.address[type][index] = 0; + res.flags[type][index] = 0; + _allocatedSize -= ((ResHeader*)ptr)->size; + free(ptr); } } -void Scumm::unkResourceProc() { - int i; - for (i=1; i<16; i++) { - } - /* TODO: not implemented */ - warning("unkResourceProc: not implemented"); -} - byte *findResource(uint32 tag, byte *searchin, int index) { uint32 maxsize,curpos,totalsize,size; @@ -687,11 +690,97 @@ byte *findResource(uint32 tag, byte *searchin, int index) { void Scumm::lock(int type, int i) { validateResource("Locking", type, i); res.flags[type][i] |= 0x80; + + debug(9, "locking %d,%d", type, i); } void Scumm::unlock(int type, int i) { validateResource("Unlocking", type, i); - res.flags[type][i] &= ~0x7F; + res.flags[type][i] &= ~0x80; + + debug(9, "unlocking %d,%d", type, i); +} + +bool Scumm::isResourceInUse(int type, int i) { + validateResource("isResourceInUse", type, i); + switch(type) { + case rtRoom: + return _roomResource == (byte)i; + case rtScript: + return isScriptInUse(i); + case rtCostume: + return isCostumeInUse(i); + case rtSound: + return isSoundRunning(i)!=0; + default: + return false; + } +} + +void Scumm::increaseResourceCounter() { + int i,j; + byte counter; + + for (i=1; i<=16; i++) { + for(j=res.num[i]; --j>=0;) { + counter = res.flags[i][j] & 0x7F; + if (counter && counter < 0x7F) { + setResourceCounter(i, j, counter+1); + } + } + } +} + +#define EXPIRE_FREQ 40 + +void Scumm::expireResources(uint32 size) { + int i,j; + byte flag; + byte best_counter; + int best_type, best_res; + + if (_expire_counter != 0xFF) { + _expire_counter = 0xFF; + increaseResourceCounter(); + } + + if (size + _allocatedSize < _maxHeapThreshold) + return; + + do { + best_type = 0; + best_counter = 2; + + for (i=1; i<=16; i++) + if (res.mode[i]) { + for(j=res.num[i]; --j>=0;) { + flag = res.flags[i][j]; + if (!(flag&0x80) && flag >= best_counter && !isResourceInUse(i,j)) { + best_counter = flag; + best_type = i; + best_res = j; + } + } + } + + if (!best_type) + break; + nukeResource(best_type, best_res); + } while (size + _allocatedSize > _minHeapThreshold); +} + +void Scumm::freeResources() { + int i,j; + for (i=1; i<=16; i++) { + for(j=res.num[i]; --j>=0;) { + if (isResourceLoaded(i,j)) + nukeResource(i,j); + } + free(res.address[i]); + free(res.flags[i]); + free(res.roomno[i]); + free(res.roomoffs[i]); + } } void Scumm::loadPtrToResource(int type, int resindex, byte *source) { @@ -717,6 +806,15 @@ void Scumm::loadPtrToResource(int type, int resindex, byte *source) { } } +bool Scumm::isResourceLoaded(int type, int index) { + validateResource("isLoaded", type, index); + return res.address[type][index] != NULL; +} + +void Scumm::resourceStats() { + printf("Total allocated size=%d\n", _allocatedSize); +} + void Scumm::heapClear(int mode) { /* TODO: implement this */ warning("heapClear: not implemented"); @@ -727,11 +825,10 @@ void Scumm::unkHeapProc2(int a, int b) { warning("unkHeapProc2: not implemented"); } -void Scumm::unkResProc(int a, int b) { - warning("unkResProc:not implemented"); +void Scumm::loadFlObject(int a, int b) { + debug(9, "loadFlObject(%d,%d):not implemented", a, b); } - void Scumm::readMAXS() { _numVariables = fileReadWordLE(); fileReadWordLE(); diff --git a/saveload.cpp b/saveload.cpp index 2a8af2d5d2..fdd4b1b32c 100644 --- a/saveload.cpp +++ b/saveload.cpp @@ -17,6 +17,10 @@ * * Change Log: * $Log$ + * Revision 1.7 2001/11/05 19:21:49 strigeus + * bug fixes, + * speech in dott + * * Revision 1.6 2001/10/26 17:34:50 strigeus * bug fixes, code cleanup * @@ -55,6 +59,7 @@ struct SaveGameHeader { bool Scumm::saveState(const char *filename) { FILE *out = fopen(filename,"wb"); SaveGameHeader hdr; + Serializer ser; if (out==NULL) return false; @@ -65,7 +70,10 @@ bool Scumm::saveState(const char *filename) { fwrite(&hdr, sizeof(hdr), 1, out); - saveOrLoad(out,true); + ser._saveLoadStream = out; + ser._saveOrLoad = true; + saveOrLoad(&ser); + fclose(out); debug(1,"State saved as '%s'", filename); return true; @@ -75,6 +83,7 @@ bool Scumm::loadState(const char *filename) { FILE *out = fopen(filename,"rb"); int i,j; SaveGameHeader hdr; + Serializer ser; int sb,sh; if (out==NULL) @@ -106,7 +115,9 @@ bool Scumm::loadState(const char *filename) { initScummVars(); - saveOrLoad(out,false); + ser._saveLoadStream = out; + ser._saveOrLoad = false; + saveOrLoad(&ser); fclose(out); sb = _screenB; @@ -137,12 +148,11 @@ bool Scumm::loadState(const char *filename) { #define OFFS(type,item) ((int)(&((type*)0)->item)) #define SIZE(type,item) sizeof(((type*)0)->item) - #define MKLINE(type,item,saveas) {OFFS(type,item),saveas,SIZE(type,item)} #define MKARRAY(type,item,saveas,num) {OFFS(type,item),128|saveas,SIZE(type,item)}, {num,0,0} #define MKEND() {0xFFFF,0xFF,0xFF} -void Scumm::saveOrLoad(FILE *inout, bool mode) { +void Scumm::saveOrLoad(Serializer *s) { const SaveLoadEntry objectEntries[] = { MKLINE(ObjectData,offs_obim_to_room,sleUint32), MKLINE(ObjectData,offs_obcd_to_room,sleUint32), @@ -290,6 +300,7 @@ void Scumm::saveOrLoad(FILE *inout, bool mode) { MKLINE(Scumm,_charsetColor,sleByte), MKLINE(Scumm,charset._bufPos,sleByte), MKLINE(Scumm,_haveMsg,sleByte), + MKLINE(Scumm,_useTalkAnims,sleByte), MKLINE(Scumm,_talkDelay,sleInt16), MKLINE(Scumm,_defaultTalkDelay,sleInt16), @@ -380,7 +391,7 @@ void Scumm::saveOrLoad(FILE *inout, bool mode) { MKLINE(StringTab,t_ypos,sleInt16), MKLINE(StringTab,t_center,sleInt16), MKLINE(StringTab,t_overhead,sleInt16), - MKLINE(StringTab,t_new3,sleInt16), + MKLINE(StringTab,t_no_talk_anim,sleInt16), MKLINE(StringTab,t_right,sleInt16), MKLINE(StringTab,t_color,sleInt16), MKLINE(StringTab,t_charset,sleInt16), @@ -390,7 +401,7 @@ void Scumm::saveOrLoad(FILE *inout, bool mode) { MKLINE(StringTab,ypos2,sleInt16), MKLINE(StringTab,center,sleInt16), MKLINE(StringTab,overhead,sleInt16), - MKLINE(StringTab,new_3,sleInt16), + MKLINE(StringTab,no_talk_anim,sleInt16), MKLINE(StringTab,right,sleInt16), MKLINE(StringTab,mask_top,sleInt16), MKLINE(StringTab,mask_bottom,sleInt16), @@ -405,43 +416,60 @@ void Scumm::saveOrLoad(FILE *inout, bool mode) { MKLINE(ColorCycle,flags,sleUint16), MKLINE(ColorCycle,start,sleByte), MKLINE(ColorCycle,end,sleByte), + MKEND() }; int i,j; - - _saveLoadStream = inout; - _saveOrLoad = mode; - - saveLoadEntries(this,mainEntries); - for (i=1; i<13; i++) - saveLoadEntries(&actor[i],actorEntries); - for (i=0; i<NUM_SCRIPT_SLOT; i++) - saveLoadEntries(&vm.slot[i],scriptSlotEntries); - for (i=0; i<_numLocalObjects; i++) - saveLoadEntries(&_objs[i],objectEntries); - for (i=0; i<_numVerbs; i++) - saveLoadEntries(&_verbs[i],verbEntries); - for (i=0; i<16; i++) - saveLoadEntries(&vm.nest[i],nestedScriptEntries); - for (i=0; i<6; i++) - saveLoadEntries(&sentence[i],sentenceTabEntries); - for (i=0; i<6; i++) - saveLoadEntries(&string[i],stringTabEntries); - for (i=0; i<16; i++) - saveLoadEntries(&_colorCycle,colorCycleEntries); - - for (i=1; i<16; i++) + + s->saveLoadEntries(this,mainEntries); + + s->saveLoadArrayOf(actor+1, 12, sizeof(actor[0]), actorEntries); + s->saveLoadArrayOf(vm.slot, NUM_SCRIPT_SLOT, sizeof(vm.slot[0]), scriptSlotEntries); + s->saveLoadArrayOf(_objs, _numLocalObjects, sizeof(_objs[0]), objectEntries); + s->saveLoadArrayOf(_verbs, _numVerbs, sizeof(_verbs[0]), verbEntries); + s->saveLoadArrayOf(vm.nest, 16, sizeof(vm.nest[0]), nestedScriptEntries); + s->saveLoadArrayOf(sentence, 6, sizeof(sentence[0]), sentenceTabEntries); + s->saveLoadArrayOf(string, 6, sizeof(string[0]), stringTabEntries); + s->saveLoadArrayOf(_colorCycle, 16, sizeof(_colorCycle[0]), colorCycleEntries); + +// debug(1, "1) At position %d", ftell(inout)); +// for (i=1; i<13; i++) +// s->saveLoadEntries(&actor[i],actorEntries); +// debug(1, "2) At position %d", ftell(inout)); +// for (i=0; i<NUM_SCRIPT_SLOT; i++) +// s->saveLoadEntries(&vm.slot[i],scriptSlotEntries); +// debug(1, "3) At position %d", ftell(inout)); +// for (i=0; i<_numLocalObjects; i++) +// s->saveLoadEntries(&_objs[i],objectEntries); +// debug(1, "4) At position %d", ftell(inout)); +// for (i=0; i<_numVerbs; i++) +// s->saveLoadEntries(&_verbs[i],verbEntries); +// debug(1, "5) At position %d", ftell(inout)); +// for (i=0; i<16; i++) +// s->saveLoadEntries(&vm.nest[i],nestedScriptEntries); +// debug(1, "6) At position %d", ftell(inout)); +// for (i=0; i<6; i++) +// s->saveLoadEntries(&sentence[i],sentenceTabEntries); +// debug(1, "7) At position %d", ftell(inout)); +// for (i=0; i<6; i++) +// s->saveLoadEntries(&string[i],stringTabEntries); +// debug(1, "8) At position %d", ftell(inout)); +// for (i=0; i<16; i++) +// s->saveLoadEntries(&_colorCycle[i],colorCycleEntries); +// debug(1, "9) At position %d", ftell(inout)); + + for (i=1; i<=16; i++) if (res.mode[i]==0) for(j=1; j<res.num[i]; j++) - saveLoadResource(i,j); + saveLoadResource(s,i,j); - saveLoadArrayOf(_objectFlagTable, _numGlobalObjects, sizeof(_objectFlagTable[0]), sleByte); - saveLoadArrayOf(_classData, _numGlobalObjects, sizeof(_classData[0]), sleUint32); - saveLoadArrayOf(_vars, _numVariables, sizeof(_vars[0]), sleInt16); - saveLoadArrayOf(_bitVars, _numBitVariables>>3, 1, sleByte); + s->saveLoadArrayOf(_objectFlagTable, _numGlobalObjects, sizeof(_objectFlagTable[0]), sleByte); + s->saveLoadArrayOf(_classData, _numGlobalObjects, sizeof(_classData[0]), sleUint32); + s->saveLoadArrayOf(_vars, _numVariables, sizeof(_vars[0]), sleInt16); + s->saveLoadArrayOf(_bitVars, _numBitVariables>>3, 1, sleByte); } -void Scumm::saveLoadResource(int type, int index) { +void Scumm::saveLoadResource(Serializer *ser, int type, int index) { byte *ptr; uint32 size,sizele; @@ -449,76 +477,82 @@ void Scumm::saveLoadResource(int type, int index) { if (type==13 || type==12 || type==10 || res.mode[type]) return; - if (_saveOrLoad) { + if (ser->isSaving()) { ptr = res.address[type][index]; if (ptr==NULL) { - saveUint32(0); + ser->saveUint32(0); return; } size = ((ResHeader*)ptr)->size; - - saveUint32(size); - saveLoadBytes(ptr+sizeof(ResHeader),size); + + ser->saveUint32(size); + ser->saveLoadBytes(ptr+sizeof(ResHeader),size); if (type==5) { - saveWord(_inventory[index]); + ser->saveWord(_inventory[index]); } } else { - size = loadUint32(); + size = ser->loadUint32(); if (size) { createResource(type, index, size); - saveLoadBytes(getResourceAddress(type, index), size); + ser->saveLoadBytes(getResourceAddress(type, index), size); if (type==5) { - _inventory[index] = loadWord(); + _inventory[index] = ser->loadWord(); } } } } -void Scumm::saveLoadBytes(void *b, int len) { +void Serializer::saveLoadBytes(void *b, int len) { if (_saveOrLoad) fwrite(b, 1, len, _saveLoadStream); else fread(b, 1, len, _saveLoadStream); } -void Scumm::saveUint32(uint32 d) { +void Serializer::saveUint32(uint32 d) { uint32 e = FROM_LE_32(d); saveLoadBytes(&e,4); } -void Scumm::saveWord(uint16 d) { +void Serializer::saveWord(uint16 d) { uint16 e = FROM_LE_16(d); saveLoadBytes(&e,2); } -void Scumm::saveByte(byte b) { +void Serializer::saveByte(byte b) { saveLoadBytes(&b,1); } -uint32 Scumm::loadUint32() { +uint32 Serializer::loadUint32() { uint32 e; saveLoadBytes(&e,4); return FROM_LE_32(e); } -uint16 Scumm::loadWord() { +uint16 Serializer::loadWord() { uint16 e; saveLoadBytes(&e,2); return FROM_LE_16(e); } -byte Scumm::loadByte() { +byte Serializer::loadByte() { byte e; saveLoadBytes(&e,1); return e; } -void Scumm::saveLoadArrayOf(void *b, int len, int datasize, byte filetype) { +void Serializer::saveLoadArrayOf(void *b, int len, int datasize, byte filetype) { byte *at = (byte*)b; uint32 data; + /* speed up byte arrays */ + if (datasize==1 && filetype==sleByte) { + saveLoadBytes(b, len); + return; + } + while (--len>=0) { if (_saveOrLoad) { /* saving */ @@ -570,11 +604,20 @@ void Scumm::saveLoadArrayOf(void *b, int len, int datasize, byte filetype) { } } +void Serializer::saveLoadArrayOf(void *b, int num, int datasize, const SaveLoadEntry *sle) { + byte *data = (byte*)b; + while (--num) { + saveLoadEntries(data, sle); + data += datasize; + } +} + -void Scumm::saveLoadEntries(void *d, const SaveLoadEntry *sle) { +void Serializer::saveLoadEntries(void *d, const SaveLoadEntry *sle) { int replen; byte type; byte *at; + int size; int value; @@ -582,14 +625,25 @@ void Scumm::saveLoadEntries(void *d, const SaveLoadEntry *sle) { at = (byte*)d + sle->offs; size = sle->size; type = sle->type; - replen = 1; - if (type&128) { + + if (size==0xFF) { + if (_saveOrLoad) { + /* save reference */ + saveWord((*_save_ref)(_ref_me, type, *((void**)at))); + } else { + /* load reference */ + *((void**)at) = (*_load_ref)(_ref_me, type, loadWord()); + } + } else { + replen = 1; + if (type&128) { + sle++; + replen = sle->offs; + type&=~128; + } + saveLoadArrayOf(at, replen, size, type); sle++; - replen = sle->offs; - type&=~128; } - sle++; - saveLoadArrayOf(at, replen, size, type); } } diff --git a/script.cpp b/script.cpp index b6c036be79..654d2570a1 100644 --- a/script.cpp +++ b/script.cpp @@ -17,6 +17,10 @@ * * Change Log: * $Log$ + * Revision 1.6 2001/11/05 19:21:49 strigeus + * bug fixes, + * speech in dott + * * Revision 1.5 2001/10/26 17:34:50 strigeus * bug fixes, code cleanup * @@ -61,7 +65,7 @@ void Scumm::runScript(int script, int a, int b, int16 *lvarptr) { stopScriptNr(script); if (script < _numGlobalScripts) { - scriptPtr = getResourceAddress(2, script); + scriptPtr = getResourceAddress(rtScript, script); scriptOffs = 8; scriptType = 2; } else { @@ -194,7 +198,6 @@ void Scumm::runScriptNested(int script) { slot = &vm.slot[_currentScript]; nest->number = slot->number; nest->type = slot->type; - /* scumm is buggy here */ nest->slot = _currentScript; } @@ -242,24 +245,24 @@ void Scumm::getScriptBaseAddress() { switch(ss->type) { case 0: /* inventory script **/ index = getObjectIndex(ss->number); - _scriptOrgPointer = getResourceAddress(5, index); + _scriptOrgPointer = getResourceAddress(rtInventory, index); _lastCodePtr = &_baseInventoryItems[index]; break; case 3: case 1: /* room script */ - _scriptOrgPointer = getResourceAddress(1, _roomResource); + _scriptOrgPointer = getResourceAddress(rtRoom, _roomResource); _lastCodePtr = &_baseRooms[_roomResource]; break; case 2: /* global script */ - _scriptOrgPointer = getResourceAddress(2, ss->number); + _scriptOrgPointer = getResourceAddress(rtScript, ss->number); _lastCodePtr = &_baseScripts[ss->number]; break; case 4: /* flobject script */ index = getObjectIndex(ss->number); - _scriptOrgPointer = getResourceAddress(13,_objs[index].fl_object_index); + _scriptOrgPointer = getResourceAddress(rtFlObject,_objs[index].fl_object_index); _lastCodePtr = &_baseFLObject[ss->number]; break; default: @@ -443,7 +446,7 @@ void Scumm::drawBox(int x, int y, int x2, int y2, int color) { updateDirtyRect(vs->number, x, x2, y-top, y2-top, 0); - backbuff = getResourceAddress(0xA, vs->number+1) + vs->xstart + (y-top)*320 + x; + backbuff = getResourceAddress(rtBuffer, vs->number+1) + vs->xstart + (y-top)*320 + x; count = y2 - y; while (count) { @@ -475,7 +478,7 @@ void Scumm::stopObjectCode() { _currentScript = 0xFF; } -bool Scumm::isScriptLoaded(int script) { +bool Scumm::isScriptInUse(int script) { ScriptSlot *ss; int i; @@ -602,11 +605,23 @@ void Scumm::killScriptsAndResources() { } } + /* Nuke FL objects */ i = 0; do { if (_objs[i].fl_object_index) nukeResource(0xD, _objs[i].fl_object_index); } while (++i <= _numObjectsInRoom); + + /* Nuke local object names */ + if (_newNames) { + for (i=0; i<50; i++) { + int j = _newNames[i]; + if (j && (getOwner(j)&0xF) == 0) { + _newNames[i] = 0; + nukeResource(rtObjectName, i); + } + } + } } void Scumm::checkAndRunVar33() { @@ -614,7 +629,7 @@ void Scumm::checkAndRunVar33() { ScriptSlot *ss; memset(_localParamList, 0, sizeof(_localParamList)); - if (isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT])) { + if (isScriptInUse(_vars[VAR_SENTENCE_SCRIPT])) { ss = vm.slot; for (i=0; i<NUM_SCRIPT_SLOT; i++,ss++) if (ss->number==_vars[VAR_SENTENCE_SCRIPT] && ss->status!=0 && ss->freezeCount==0) @@ -910,7 +925,7 @@ int Scumm::defineArray(int array, int type, int dim2, int dim1) { size *= dim1+1; size >>= 3; - ah = (ArrayHeader*)createResource(7, id, size+sizeof(ArrayHeader)); + ah = (ArrayHeader*)createResource(rtString, id, size+sizeof(ArrayHeader)); ah->type = type; ah->dim1_size = dim1+1; @@ -925,7 +940,7 @@ void Scumm::nukeArray(int a) { data = readVar(a); if (data) - nukeResource(7, data); + nukeResource(rtString, data); _arrays[data] = 0; writeVar(a, 0); @@ -948,7 +963,7 @@ void Scumm::arrayop_1(int a, byte *ptr) { int len = getStringLen(ptr); r = defineArray(a, 4, 0, len); - ah = (ArrayHeader*)getResourceAddress(7,r); + ah = (ArrayHeader*)getResourceAddress(rtString,r); copyString(ah->data,ptr,len); } diff --git a/script_v1.cpp b/script_v1.cpp index 0c1a3522cb..481a10c10f 100644 --- a/script_v1.cpp +++ b/script_v1.cpp @@ -17,6 +17,10 @@ * * Change Log: * $Log$ + * Revision 1.6 2001/11/05 19:21:49 strigeus + * bug fixes, + * speech in dott + * * Revision 1.5 2001/10/29 22:09:20 strigeus * script invoked loading&saving in compatible mode * @@ -1046,7 +1050,7 @@ void Scumm::o5_isSoundRunning() { getResultPos(); snd = getVarOrDirectByte(0x80); if (snd) - snd = unkSoundProc23(snd); + snd = isSoundRunning(snd); setResult(snd); } @@ -1071,7 +1075,6 @@ void Scumm::o5_lights() { void Scumm::o5_loadRoom() { int room = getVarOrDirectByte(0x80); - debug(1,"Loading room %d", room); startScene(room, 0, 0); _fullRedraw = 1; } @@ -1259,60 +1262,60 @@ void Scumm::o5_resourceRoutines() { res = getVarOrDirectByte(0x80); switch(_opcode&0x1F) { case 1: /* load script */ - ensureResourceLoaded(2, res); + ensureResourceLoaded(rtScript, res); break; case 2: /* load sound */ - ensureResourceLoaded(4, res); + ensureResourceLoaded(rtSound, res); break; case 3: /* load costume */ - ensureResourceLoaded(3, res); + ensureResourceLoaded(rtCostume, res); break; case 4: /* load room */ - ensureResourceLoaded(1, res); + ensureResourceLoaded(rtRoom, res); break; case 5: /* nuke script */ - setResourceFlags(2, res, 0x7F); + setResourceCounter(rtScript, res, 0x7F); break; case 6: /* nuke sound */ - setResourceFlags(4, res, 0x7F); + setResourceCounter(rtSound, res, 0x7F); break; case 7: /* nuke costume */ - setResourceFlags(3, res, 0x7F); + setResourceCounter(rtCostume, res, 0x7F); break; case 8: /* nuke room */ - setResourceFlags(1, res, 0x7F); + setResourceCounter(rtRoom, res, 0x7F); break; case 9: /* lock script */ if (res >= _numGlobalScripts) break; - lock(2,res); + lock(rtScript,res); break; case 10:/* lock sound */ - lock(4,res); + lock(rtSound,res); break; case 11:/* lock costume */ - lock(3,res); + lock(rtCostume,res); break; case 12:/* lock room */ if (res > 0x7F) res = _resourceMapper[res&0x7F]; - lock(1,res); + lock(rtRoom,res); break; case 13:/* unlock script */ if (res >= _numGlobalScripts) break; - unlock(2,res); + unlock(rtScript,res); break; case 14:/* unlock sound */ - unlock(4,res); + unlock(rtSound,res); break; case 15:/* unlock costume */ - unlock(3,res); + unlock(rtCostume,res); break; case 16:/* unlock room */ if (res > 0x7F) res = _resourceMapper[res&0x7F]; - unlock(1,res); + unlock(rtRoom,res); break; case 17:/* clear heap */ heapClear(0); @@ -1324,8 +1327,8 @@ void Scumm::o5_resourceRoutines() { case 19:/* nuke charset */ nukeCharset(res); break; - case 20:/* ? */ - unkResProc(getVarOrDirectWord(0x40), res); + case 20:/* load fl object */ + loadFlObject(getVarOrDirectWord(0x40), res); break; } } @@ -1573,7 +1576,6 @@ void Scumm::o5_soundKludge() { getWordVararg(items); soundKludge(items); - } void Scumm::o5_startMusic() { @@ -1613,8 +1615,7 @@ void Scumm::o5_startSound() { } void Scumm::o5_stopMusic() { - /* TODO: not implemented */ - warning("o5_stopMusic: not implemented"); + stopAllSounds(); } void Scumm::o5_stopObjectCode() { @@ -1636,7 +1637,7 @@ void Scumm::o5_stopScript() { } void Scumm::o5_stopSound() { - unkSoundProc1(getVarOrDirectByte(0x80)); + stopSound(getVarOrDirectByte(0x80)); } void Scumm::o5_stringOps() { @@ -1651,9 +1652,9 @@ void Scumm::o5_stringOps() { case 2: /* copystring */ a = getVarOrDirectByte(0x80); b = getVarOrDirectByte(0x40); - nukeResource(7, a); - ptr = getResourceAddress(7, b); - if (ptr) loadPtrToResource(7, a, ptr); + nukeResource(rtString, a); + ptr = getResourceAddress(rtString, b); + if (ptr) loadPtrToResource(rtString, a, ptr); break; case 3: /* set string char */ a = getVarOrDirectByte(0x80); @@ -1668,7 +1669,7 @@ void Scumm::o5_stringOps() { getResultPos(); a = getVarOrDirectByte(0x80); b = getVarOrDirectByte(0x40); - ptr = getResourceAddress(7, a); + ptr = getResourceAddress(rtString, a); if (ptr==NULL) error("String %d does not exist", a); setResult(ptr[b]); break; @@ -1676,9 +1677,9 @@ void Scumm::o5_stringOps() { case 5: /* create empty string */ a = getVarOrDirectByte(0x80); b = getVarOrDirectByte(0x40); - nukeResource(7, a); + nukeResource(rtString, a); if (b) { - ptr = createResource(7, a, b); + ptr = createResource(rtString, a, b); if (ptr) { for(i=0; i<b; i++) ptr[i] = 0; @@ -1719,9 +1720,9 @@ void Scumm::o5_verbOps() { } break; case 2: /* load from code */ - loadPtrToResource(8, slot, NULL); + loadPtrToResource(rtVerb, slot, NULL); if (slot==0) - nukeResource(8, slot); + nukeResource(rtVerb, slot); vs->type = 0; vs->imgindex = 0; break; @@ -1781,14 +1782,14 @@ void Scumm::o5_verbOps() { vs->center = 1; break; case 20: /* set to string */ - ptr = getResourceAddress(7, getVarOrDirectWord(0x80)); + ptr = getResourceAddress(rtString, getVarOrDirectWord(0x80)); if (!ptr) - nukeResource(8, slot); + nukeResource(rtVerb, slot); else { - loadPtrToResource(8, slot, ptr); + loadPtrToResource(rtVerb, slot, ptr); } if (slot==0) - nukeResource(8, slot); + nukeResource(rtVerb, slot); vs->type = 0; vs->imgindex = 0; break; @@ -1832,11 +1833,11 @@ void Scumm::o5_wait() { case 4: /* wait for sentence */ if (_sentenceIndex!=0xFF) { if (sentence[_sentenceIndex].unk && - !isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT]) ) + !isScriptInUse(_vars[VAR_SENTENCE_SCRIPT]) ) return; break; } - if (!isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT])) + if (!isScriptInUse(_vars[VAR_SENTENCE_SCRIPT])) return; break; default: diff --git a/script_v2.cpp b/script_v2.cpp index f1327b4ab7..fc49844cc2 100644 --- a/script_v2.cpp +++ b/script_v2.cpp @@ -17,6 +17,10 @@ * * Change Log: * $Log$ + * Revision 1.5 2001/11/05 19:21:49 strigeus + * bug fixes, + * speech in dott + * * Revision 1.4 2001/10/26 17:34:50 strigeus * bug fixes, code cleanup * @@ -364,7 +368,7 @@ void Scumm::setupOpcodes2() { } int Scumm::readArray(int array, int index, int base) { - ArrayHeader *ah = (ArrayHeader*)getResourceAddress(7, readVar(array)); + ArrayHeader *ah = (ArrayHeader*)getResourceAddress(rtString, readVar(array)); assert(ah); @@ -380,7 +384,7 @@ int Scumm::readArray(int array, int index, int base) { } void Scumm::writeArray(int array, int index, int base, int value) { - ArrayHeader *ah = (ArrayHeader*)getResourceAddress(7, readVar(array)); + ArrayHeader *ah = (ArrayHeader*)getResourceAddress(rtString, readVar(array)); assert(ah); base += index*ah->dim1_size; @@ -676,7 +680,7 @@ void Scumm::o6_cutScene() { } void Scumm::o6_stopMusic() { - warning("o6_stopMusic: not implemented"); + stopAllSounds(); } void Scumm::o6_freezeUnfreeze() { @@ -818,7 +822,7 @@ void Scumm::o6_startSound() { } void Scumm::o6_stopSound() { - unkSoundProc1(pop()); + stopSound(pop()); } void Scumm::o6_startMusic() { @@ -843,7 +847,6 @@ void Scumm::o6_setCameraAt() { void Scumm::o6_loadRoom() { int room = pop(); - debug(1,"Loading room %d", room); startScene(room, 0, 0); _fullRedraw = 1; } @@ -946,6 +949,12 @@ void Scumm::o6_faceActor() { void Scumm::o6_animateActor() { int anim = pop(); int act = pop(); + + if (_gameId==GID_TENTACLE && act==593) { + warning("o6_animateActor(%d,%d): fixed tentacle bug", act, anim); + return; + } + animateActor(act, anim); } @@ -1102,7 +1111,7 @@ void Scumm::o6_setObjectName() { for (i=1; i<50; i++) { if (_newNames[i] == obj) { - nukeResource(16, i); + nukeResource(rtObjectName, i); _newNames[i] = 0; break; } @@ -1110,7 +1119,7 @@ void Scumm::o6_setObjectName() { for (i=1; i<50; i++) { if (_newNames[i] == 0) { - loadPtrToResource(16, i, NULL); + loadPtrToResource(rtObjectName, i, NULL); _newNames[i] = obj; runHook(0); return; @@ -1123,7 +1132,7 @@ void Scumm::o6_setObjectName() { void Scumm::o6_isSoundRunning() { int snd = pop(); if (snd) - snd = unkSoundProc23(snd); + snd = isSoundRunning(snd); push(snd); } @@ -1149,75 +1158,76 @@ void Scumm::o6_resourceRoutines() { switch(fetchScriptByte()) { case 100: /* load script */ res = pop(); - ensureResourceLoaded(2, res); + ensureResourceLoaded(rtScript, res); break; case 101: /* load sound */ res = pop(); - ensureResourceLoaded(4, res); + ensureResourceLoaded(rtSound, res); break; case 102: /* load costume */ res = pop(); - ensureResourceLoaded(3, res); + ensureResourceLoaded(rtCostume, res); break; case 103: /* load room */ res = pop(); - ensureResourceLoaded(1, res); + ensureResourceLoaded(rtRoom, res); break; case 104: /* nuke script */ res = pop(); - setResourceFlags(2, res, 0x7F); + setResourceCounter(rtScript, res, 0x7F); + debug(5, "nuke script %d", res); break; case 105: /* nuke sound */ res = pop(); - setResourceFlags(4, res, 0x7F); + setResourceCounter(rtSound, res, 0x7F); break; case 106: /* nuke costume */ res = pop(); - setResourceFlags(3, res, 0x7F); + setResourceCounter(rtCostume, res, 0x7F); break; case 107: /* nuke room */ res = pop(); - setResourceFlags(1, res, 0x7F); + setResourceCounter(rtRoom, res, 0x7F); break; case 108: /* lock script */ res = pop(); if (res >= _numGlobalScripts) break; - lock(2,res); + lock(rtScript,res); break; case 109:/* lock sound */ res = pop(); - lock(4,res); + lock(rtSound,res); break; case 110:/* lock costume */ res = pop(); - lock(3,res); + lock(rtCostume,res); break; case 111:/* lock room */ res = pop(); if (res > 0x7F) res = _resourceMapper[res&0x7F]; - lock(1,res); + lock(rtRoom,res); break; case 112:/* unlock script */ res = pop(); if (res >= _numGlobalScripts) break; - unlock(2,res); + unlock(rtScript,res); break; case 113:/* unlock sound */ res = pop(); - unlock(4,res); + unlock(rtSound,res); break; case 114:/* unlock costume */ res = pop(); - unlock(3,res); + unlock(rtCostume,res); break; case 115:/* unlock room */ res = pop(); if (res > 0x7F) res = _resourceMapper[res&0x7F]; - unlock(1,res); + unlock(rtRoom,res); break; case 116:/* clear heap */ /* this is actually a scumm message */ @@ -1232,9 +1242,9 @@ void Scumm::o6_resourceRoutines() { res = pop(); nukeCharset(res); break; - case 119:/* ? */ + case 119:/* load fl object */ res = pop(); - unkResProc(pop(), res); + loadFlObject(pop(), res); break; default: error("o6_resourceRoutines: default case"); @@ -1751,11 +1761,11 @@ void Scumm::o6_wait() { case 171: if (_sentenceIndex!=0xFF) { if (sentence[_sentenceIndex].unk && - !isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT]) ) + !isScriptInUse(_vars[VAR_SENTENCE_SCRIPT]) ) return; break; } - if (!isScriptLoaded(_vars[VAR_SENTENCE_SCRIPT])) + if (!isScriptInUse(_vars[VAR_SENTENCE_SCRIPT])) return; break; default: @@ -2090,13 +2100,13 @@ void Scumm::decodeParseString2(int m, int n) { break; case 72: string[m].overhead = 1; - string[m].new_3 = 0; + string[m].no_talk_anim = 0; break; case 73: error("decodeParseString2: case 73"); break; case 74: - string[m].new_3 = 1; + string[m].no_talk_anim = 1; break; case 75: _messagePtr = _scriptPointer; @@ -2119,7 +2129,7 @@ void Scumm::decodeParseString2(int m, int n) { string[m].t_ypos = string[m].ypos; string[m].t_center = string[m].center; string[m].t_overhead = string[m].overhead; - string[m].t_new3 = string[m].new_3; + string[m].t_no_talk_anim = string[m].no_talk_anim; string[m].t_right = string[m].right; string[m].t_color = string[m].color; string[m].t_charset = string[m].charset; @@ -17,6 +17,10 @@ * * Change Log: * $Log$ + * Revision 1.16 2001/11/05 19:21:49 strigeus + * bug fixes, + * speech in dott + * * Revision 1.15 2001/10/29 23:07:24 strigeus * better MI1 compatibility * @@ -251,15 +255,11 @@ struct PathVertex { PathNode *right; }; -struct SaveLoadEntry { - uint16 offs; - uint8 type; - uint8 size; -}; enum { sleByte = 1, sleUint8 = 1, + sleInt8 = 1, sleInt16 = 2, sleUint16 = 3, sleInt32 = 4, @@ -342,28 +342,48 @@ enum ScummVars { }; -#define _maxRooms res.num[1] -#define _maxScripts res.num[2] -#define _maxCostumes res.num[3] -#define _maxInventoryItems res.num[5] -#define _maxCharsets res.num[6] -#define _maxStrings res.num[7] -#define _maxVerbs res.num[8] -#define _maxActorNames res.num[9] -#define _maxBuffer res.num[10] -#define _maxScaleTable res.num[11] -#define _maxTemp res.num[12] -#define _maxFLObject res.num[13] -#define _maxMatrixes res.num[14] -#define _maxBoxes res.num[15] - -#define _baseRooms res.address[1] -#define _baseScripts res.address[2] -#define _baseInventoryItems res.address[5] -#define _baseFLObject res.address[13] -#define _baseArrays res.address[7] - -#define _roomFileOffsets res.roomoffs[1] +enum ResTypes { + rtRoom = 1, + rtScript = 2, + rtCostume = 3, + rtSound = 4, + rtInventory = 5, + rtCharset = 6, + rtString = 7, + rtVerb = 8, + rtActorName = 9, + rtBuffer = 10, + rtScaleTable = 11, + rtTemp = 12, + rtFlObject = 13, + rtMatrix = 14, + rtBox = 15, + rtObjectName = 16, + +}; + +#define _maxRooms res.num[rtRoom] +#define _maxScripts res.num[rtScript] +#define _maxCostumes res.num[rtCostume] +#define _maxInventoryItems res.num[rtInventory] +#define _maxCharsets res.num[rtCharset] +#define _maxStrings res.num[rtString] +#define _maxVerbs res.num[rtVerb] +#define _maxActorNames res.num[rtActorName] +#define _maxBuffer res.num[rtBuffer] +#define _maxScaleTable res.num[rtScaleTable] +#define _maxTemp res.num[rtTemp] +#define _maxFLObject res.num[rtFlObject] +#define _maxMatrixes res.num[rtMatrix] +#define _maxBoxes res.num[rtBox] + +#define _baseRooms res.address[rtRoom] +#define _baseScripts res.address[rtScript] +#define _baseInventoryItems res.address[rtInventory] +#define _baseFLObject res.address[rtFlObject] +#define _baseArrays res.address[rtString] + +#define _roomFileOffsets res.roomoffs[rtRoom] struct CharsetRenderer { Scumm *_vm; @@ -459,8 +479,8 @@ struct CostumeRenderer { byte drawOneSlot(Actor *a, int slot); byte drawCostume(Actor *a); - byte animateOneSlot(CostumeData *cd, int slot); - byte animate(CostumeData *cd); + byte animateOneSlot(Actor *a, int slot); + byte animate(Actor *a); }; struct Actor { @@ -520,11 +540,11 @@ struct SentenceTab { struct StringTab { int16 t_xpos, t_ypos, t_center, t_overhead; - int16 t_new3, t_right, t_color, t_charset; + int16 t_no_talk_anim, t_right, t_color, t_charset; int16 xpos, ypos; int16 xpos2,ypos2; int16 center, overhead; - int16 new_3, right; + int16 no_talk_anim, right; int16 color,charset; int16 mask_top, mask_bottom, mask_right, mask_left; }; @@ -549,7 +569,7 @@ struct Gdi { int _imgBufOffs[4]; byte _disable_zbuffer; - byte dseg_4E3B; + bool _useOrDecompress; byte _numLinesToProcess; byte _tempNumLines; byte _currentX; @@ -614,7 +634,7 @@ enum GameId { }; struct ScummDebugger; - +struct Serializer; struct Scumm { const char *_gameText; @@ -629,6 +649,7 @@ struct Scumm { int _roomResource; byte _encbyte; void *_fileHandle; + void *_sfxFile; char *_exe_name; byte _saveLoadFlag; @@ -637,12 +658,16 @@ struct Scumm { bool _dynamicRoomOffsets; byte _resFilePathId; + + bool _useTalkAnims; char *_resFilePrefix; char *_resFilePath; int _keyPressed; + void *_soundDriver; + uint16 *_inventory; byte *_arrays; VerbSlot *_verbs; @@ -685,6 +710,13 @@ struct Scumm { byte *_scriptPointer, *_scriptOrgPointer; byte *_scriptPointerStart; byte _opcode; + + byte _expire_counter; + + bool _noTalkAnims; + + bool _mouthSyncMode; + bool _endOfMouthSync; uint32 _randSeed1; uint32 _randSeed2; @@ -703,6 +735,9 @@ struct Scumm { bool _doEffect; bool _screenEffectFlag; bool _keepText; + + uint32 _maxHeapThreshold; + uint32 _minHeapThreshold; byte _bkColor; uint16 _lastXstart; @@ -714,8 +749,6 @@ struct Scumm { byte _charsetColor; - uint32 _localScriptList[0x39]; - uint16 _debugMode; byte *_messagePtr; @@ -737,16 +770,18 @@ struct Scumm { uint16 _completeScreenRedraw; - - int8 _userPut; int8 _cursorState; + byte _sfxMode; + uint16 _mouseButStat; byte _leftBtnPressed, _rightBtnPressed; int _numInMsgStack; + uint32 _localScriptList[0x39]; + VirtScreen virtscr[4]; uint32 _ENCD_offs, _EXCD_offs; @@ -754,6 +789,11 @@ struct Scumm { uint32 _IM00_offs; uint32 _PALS_offs; + uint32 _allocatedSize; + + uint32 _talk_sound_a, _talk_sound_b; + byte _talk_sound_mode; + int _drawObjectQueNr; byte _drawObjectQue[0xC8]; @@ -841,6 +881,8 @@ struct Scumm { CostumeRenderer cost; + uint16 _mouthSyncTimes[52]; + int16 _soundQuePos; int16 _soundQue[0x100]; @@ -858,6 +900,7 @@ struct Scumm { int _palDirtyMin, _palDirtyMax; + uint _curSoundPos; ColorCycle _colorCycle[16]; @@ -881,6 +924,8 @@ struct Scumm { byte *_boxMatrixPtr4, *_boxMatrixPtr1, *_boxMatrixPtr3; int _boxPathVertexHeapIndex; int _boxMatrixItem; + +// void _grabbedCursor[1024]; OpcodeProc getOpcode(int i) { return _opcodes[i]; } @@ -909,8 +954,8 @@ struct Scumm { uint fileReadWordLE(); uint fileReadWordBE(); - byte *alloc(int size); - void free(void *mem); + static byte *alloc(int size); + static void free(void *mem); void readResTypeList(int id, uint32 tag, const char *name); void allocResTypeData(int id, uint32 tag, int num, const char *name, int mode); @@ -943,7 +988,7 @@ struct Scumm { int loadResource(int type, int i); int getResourceRoomNr(int type, int index); int readSoundResource(int type, int index); - void setResourceFlags(int type, int index, byte flag); + void setResourceCounter(int type, int index, byte flag); void validateResource(const char *str, int type, int index); void initVirtScreen(int slot, int top, int height, bool twobufs, bool fourextra); @@ -1281,7 +1326,7 @@ struct Scumm { int getObjectOrActorXY(int object); void addSoundToQueue(int sound); void addSoundToQueue2(int sound); - bool isScriptLoaded(int script); + bool isScriptInUse(int script); int getActorXYPos(Actor *a); void getObjectXYPos(int object); AdjustBoxResult adjustXYToBeInBox(Actor *a, int x, int y); @@ -1289,7 +1334,7 @@ struct Scumm { int getWordVararg(int16 *ptr); int getObjActToObjActDist(int a, int b); - void unkSoundProc22(); + void processSoundQues(); bool inBoxQuickReject(int box, int x, int y, int threshold); AdjustBoxResult getClosestPtOnBox(int box, int x, int y); @@ -1312,7 +1357,8 @@ struct Scumm { void runExitScript(); void runEntryScript(); - void unkResourceProc(); + void increaseResourceCounter(); + bool isResourceInUse(int type, int i); void initRoomSubBlocks(); void loadRoomObjects(); @@ -1321,11 +1367,6 @@ struct Scumm { void initBGBuffers(); void setDirtyColors(int min, int max); -#if 0 - byte *findResource(uint32 tag, byte *searchin); - byte *findResource2(uint32 tag, byte *searchin); -#endif - void setScaleItem(int slot, int a, int b, int c, int d); void cyclePalette(); @@ -1337,8 +1378,6 @@ struct Scumm { void redrawBGStrip(int start, int num); void drawObject(int obj, int arg); -// void drawBmp(byte *ptr, int a, int b, int c, const char *str, int objnr); - int hasCharsetMask(int x, int y, int x2, int y2); void restoreBG(int left, int top, int right, int bottom); @@ -1357,7 +1396,6 @@ struct Scumm { void decreaseScriptDelay(int amount); void processKbd(); - void redrawVerbs(); void checkExecVerbs(); @@ -1414,7 +1452,7 @@ struct Scumm { void initCharset(int charset); void addObjectToDrawQue(int object); int getVerbEntrypoint(int obj, int entry); - int unkSoundProc23(int a); + int isSoundRunning(int a); void startWalkActor(Actor *a, int x, int y, int dir); void setBoxFlags(int box, int val); void setBoxScale(int box, int b); @@ -1428,7 +1466,7 @@ struct Scumm { void unlock(int type, int i); void heapClear(int mode); void unkHeapProc2(int a, int b); - void unkResProc(int a, int b); + void loadFlObject(int a, int b); void setPalColor(int index, int r, int g, int b); void darkenPalette(int a, int b, int c, int d, int e); void unkRoomFunc3(int a, int b, int c, int d, int e); @@ -1439,7 +1477,6 @@ struct Scumm { byte *getObjOrActorName(int obj); void clearOwnerOf(int obj); void runVerbCode(int script, int entry, int a, int b, int16 *vars); - void unkSoundProc1(int a); void setVerbObject(int room, int object, int verb); void unkMessage1(); void unkMessage2(); @@ -1469,25 +1506,13 @@ struct Scumm { void dumpResource(char *tag, int index, byte *ptr); - FILE *_saveLoadStream; - bool _saveOrLoad; bool saveState(const char *filename); bool loadState(const char *filename); - void saveOrLoad(FILE *inout, bool mode); - void saveLoadBytes(void *b, int len); - void saveLoadResource(int type, int index); - bool isResourceLoaded(int type, int index); - void saveLoadArrayOf(void *b, int len, int datasize, byte filetype); - - void saveLoadEntries(void *d, const SaveLoadEntry *sle); + void saveOrLoad(Serializer *s); - void saveUint32(uint32 d); - void saveWord(uint16 d); - void saveByte(byte b); + void saveLoadResource(Serializer *ser, int type, int index); + bool isResourceLoaded(int type, int index); - byte loadByte(); - uint16 loadWord(); - uint32 loadUint32(); Actor *derefActor(int id) { return &actor[id]; } Actor *derefActorSafe(int id, const char *errmsg); @@ -1565,12 +1590,26 @@ struct Scumm { void unkMiscOp4(int a, int b, int c, int d); void unkMiscOp9(); void startManiac(); - void readIndexFileV5(int i); - void grabCursor(byte *ptr, int width, int height); - byte *getPalettePtr(); + void setupSound(); + void stopAllSounds(); + void stopSound(int sound); + bool isSoundInQueue(int sound); + void clearSoundQue(); + void talkSound(uint32 a, uint32 b, int mode); + void processSfxQueues(); + void startTalkSound(uint32 a, uint32 b, int mode); + bool isMouthSyncOff(uint pos); + void startSfxSound(void *file); + void *openSfxFile(); + void resourceStats(); + bool isCostumeInUse(int i); + void expireResources(uint32 size); + + void freeResources(); + void destroy(); }; struct ScummDebugger { @@ -1595,6 +1634,44 @@ struct ScummDebugger { void printScripts(); }; +struct SaveLoadEntry { + uint16 offs; + uint8 type; + uint8 size; +}; + +typedef int SerializerSaveReference(void *me, byte type, void *ref); +typedef void *SerializerLoadReference(void *me, byte type, int ref); + + +struct Serializer { + FILE *_saveLoadStream; + + union { + SerializerSaveReference *_save_ref; + SerializerLoadReference *_load_ref; + }; + void *_ref_me; + + bool _saveOrLoad; + + + void saveLoadBytes(void *b, int len); + void saveLoadArrayOf(void *b, int len, int datasize, byte filetype); + void saveLoadEntries(void *d, const SaveLoadEntry *sle); + void saveLoadArrayOf(void *b, int num, int datasize, const SaveLoadEntry *sle); + + void saveUint32(uint32 d); + void saveWord(uint16 d); + void saveByte(byte b); + + byte loadByte(); + uint16 loadWord(); + uint32 loadUint32(); + + bool isSaving() { return _saveOrLoad; } +}; + void waitForTimer(Scumm *s); @@ -1611,4 +1688,6 @@ void updateScreen(Scumm *s); void drawMouse(Scumm *s, int x, int y, int color, byte *mask, bool visible); void blit(byte *dst, byte *src, int w, int h); -byte *findResource(uint32 id, byte *searchin, int index);
\ No newline at end of file +byte *findResource(uint32 id, byte *searchin, int index); +void playSfxSound(void *sound, int size, int rate); +bool isSfxFinished();
\ No newline at end of file diff --git a/scummsys.h b/scummsys.h index b4a07906a5..b46ff58c4a 100644 --- a/scummsys.h +++ b/scummsys.h @@ -17,9 +17,9 @@ * * Change Log: * $Log$ - * Revision 1.6 2001/11/03 06:33:29 cmatsuoka - * Protecting VC++-specific pragmas with ifdef _MSC_VER to allow - * a clean Cygwin build. + * Revision 1.7 2001/11/05 19:21:49 strigeus + * bug fixes, + * speech in dott * * Revision 1.5 2001/10/23 19:51:50 strigeus * recompile not needed when switching games @@ -43,11 +43,8 @@ #if defined(WIN32) -/* Pragmas are VC++-specific */ -#if defined(_MSC_VER) #pragma warning (disable: 4244) #pragma warning (disable: 4101) -#endif #define scumm_stricmp stricmp diff --git a/scummvm.cpp b/scummvm.cpp index 8600d0f654..a09833c5a2 100644 --- a/scummvm.cpp +++ b/scummvm.cpp @@ -17,6 +17,10 @@ * * Change Log: * $Log$ + * Revision 1.15 2001/11/05 19:21:49 strigeus + * bug fixes, + * speech in dott + * * Revision 1.14 2001/10/29 23:07:24 strigeus * better MI1 compatibility * @@ -212,7 +216,7 @@ void Scumm::scummInit() { _numInMsgStack = 0; - createResource(12, 6, 500); + createResource(rtTemp, 6, 500); initScummVars(); @@ -254,6 +258,9 @@ void Scumm::scummMain(int argc, char **argv) { _fileHandle = NULL; _debugMode = 1; + + _maxHeapThreshold = 350000; + _minHeapThreshold = 300000; parseCommandLine(argc, argv); @@ -285,6 +292,7 @@ void Scumm::scummMain(int argc, char **argv) { _vars[74] = 1225; } + setupSound(); runScript(1,0,0,&_bootParam); _scummTimer = 0; @@ -301,6 +309,10 @@ void Scumm::scummMain(int argc, char **argv) { if (_debugger) _debugger->on_frame(); + if (!(++_expire_counter)) { + increaseResourceCounter(); + } + _vars[VAR_TIMER] = _scummTimer >> 2; do { waitForTimer(this); @@ -340,7 +352,7 @@ void Scumm::scummMain(int argc, char **argv) { if (_saveLoadFlag) { char buf[256]; - sprintf(buf, "savegame.%d", _saveLoadSlot); + sprintf(buf, "%s.%c%.2d", _exe_name, _saveLoadCompatible ? 'c': 's', _saveLoadSlot); if (_saveLoadFlag==1) { saveState(buf); if (_saveLoadCompatible) @@ -372,7 +384,7 @@ void Scumm::scummMain(int argc, char **argv) { gdi._unk4 = 0; CHARSET_1(); unkVirtScreen2(); - unkSoundProc22(); + processSoundQues(); camera._lastPos = camera._curPos; continue; } @@ -414,7 +426,7 @@ void Scumm::scummMain(int argc, char **argv) { if (_majorScummVersion==5) playActorSounds(); - unkSoundProc22(); + processSoundQues(); camera._lastPos = camera._curPos; } while (1); } @@ -506,6 +518,8 @@ void Scumm::startScene(int room, Actor *a, int objectNr) { CHECK_HEAP + debug(1,"Loading room %d", room); + clearMsgQueue(); unkVirtScreen4(_switchRoomEffect2); @@ -543,7 +557,7 @@ void Scumm::startScene(int room, Actor *a, int objectNr) { _roomResource = _currentRoom = 0xFF; - unkResourceProc(); + increaseResourceCounter(); _currentRoom = room; _vars[VAR_ROOM] = room; @@ -619,13 +633,13 @@ void Scumm::initRoomSubBlocks() { _CLUT_offs = 0; _PALS_offs = 0; - nukeResource(0xE, 1); - nukeResource(0xE, 2); + nukeResource(rtMatrix, 1); + nukeResource(rtMatrix, 2); for (i=1; i<_maxScaleTable; i++) - nukeResource(0xB, i); + nukeResource(rtScaleTable, i); - roomptr = getResourceAddress(1, _roomResource); + roomptr = getResourceAddress(rtRoom, _roomResource); ptr = findResource(MKID('RMHD'), roomptr, 0); _scrWidthIn8Unit = READ_LE_UINT16(&((RoomHeader*)ptr)->width) >> 3; @@ -653,19 +667,19 @@ void Scumm::initRoomSubBlocks() { ptr = findResource(MKID('BOXD'), roomptr, 0); if (ptr) { int size = READ_BE_UINT32_UNALIGNED(ptr+4); - createResource(14, 2, size); - roomptr = getResourceAddress(1, _roomResource); + createResource(rtMatrix, 2, size); + roomptr = getResourceAddress(rtRoom, _roomResource); ptr = findResource(MKID('BOXD'), roomptr, 0); - memcpy(getResourceAddress(0xE, 2), ptr, size); + memcpy(getResourceAddress(rtMatrix, 2), ptr, size); } ptr = findResource(MKID('BOXM'), roomptr, 0); if (ptr) { int size = READ_BE_UINT32_UNALIGNED(ptr+4); - createResource(14, 1, size); - roomptr = getResourceAddress(1, _roomResource); + createResource(rtMatrix, 1, size); + roomptr = getResourceAddress(rtRoom, _roomResource); ptr = findResource(MKID('BOXM'), roomptr, 0); - memcpy(getResourceAddress(0xE, 1), ptr, size); + memcpy(getResourceAddress(rtMatrix, 1), ptr, size); } ptr = findResource(MKID('SCAL'), roomptr, 0); @@ -678,13 +692,13 @@ void Scumm::initRoomSubBlocks() { int d = READ_LE_UINT16(roomptr + offs + 14); if (a || b || c || d) { setScaleItem(i, b, a, d, c); - roomptr = getResourceAddress(1, _roomResource); + roomptr = getResourceAddress(rtRoom, _roomResource); } } } memset(_localScriptList, 0, (0x100 - _numGlobalScripts) * 4); - roomptr = getResourceAddress(1, _roomResource); + roomptr = getResourceAddress(rtRoom, _roomResource); for (i=0; ptr = findResource(MKID('LSCR'), roomptr, i++) ;) { _localScriptList[ptr[8] - _numGlobalScripts] = ptr - roomptr; #ifdef DUMP_SCRIPTS @@ -730,7 +744,7 @@ void Scumm::setScaleItem(int slot, int a, int b, int c, int d) { byte *ptr; int cur,amounttoadd,i,tmp; - ptr = createResource(11, slot, 200); + ptr = createResource(rtScaleTable, slot, 200); if (a==c) return; @@ -908,7 +922,7 @@ void Scumm::setStringVars(int slot) { st->ypos = st->t_ypos; st->center = st->t_center; st->overhead = st->t_overhead; - st->new_3 = st->t_new3; + st->no_talk_anim = st->t_no_talk_anim; st->right = st->t_right; st->color = st->t_color; st->charset = st->t_charset; @@ -922,6 +936,20 @@ void Scumm::startManiac() { warning("stub startManiac()"); } +void Scumm::destroy() { + freeResources(); + + free(_objectFlagTable); + free(_inventory); + free(_arrays); + free(_verbs); + free(_objs); + free(_vars); + free(_bitVars); + free(_newNames); + free(_classData); +} + extern Scumm scumm; diff --git a/scummvm.dsp b/scummvm.dsp index 505c01fbf2..5f67c0f6a1 100644 --- a/scummvm.dsp +++ b/scummvm.dsp @@ -50,7 +50,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib sdl.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib sdl.lib winmm.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "scummvm - Win32 Debug"
@@ -75,7 +75,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib sdl.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib sdl.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ENDIF
@@ -140,6 +140,10 @@ SOURCE=.\debug.cpp # End Source File
# Begin Source File
+SOURCE=.\fmopl.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\gfx.cpp
!IF "$(CFG)" == "scummvm - Win32 Release"
@@ -153,6 +157,10 @@ SOURCE=.\gfx.cpp # End Source File
# Begin Source File
+SOURCE=.\midi2.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\object.cpp
!IF "$(CFG)" == "scummvm - Win32 Release"
@@ -319,6 +327,10 @@ SOURCE=.\windows.cpp # PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
+SOURCE=.\fmopl.h
+# End Source File
+# Begin Source File
+
SOURCE=.\scumm.h
# End Source File
# Begin Source File
@@ -327,6 +339,10 @@ SOURCE=.\scummsys.h # End Source File
# Begin Source File
+SOURCE=.\sound.h
+# End Source File
+# Begin Source File
+
SOURCE=.\StdAfx.h
# End Source File
# End Group
@@ -17,6 +17,10 @@ * * Change Log: * $Log$ + * Revision 1.13 2001/11/05 19:21:49 strigeus + * bug fixes, + * speech in dott + * * Revision 1.12 2001/10/26 17:34:50 strigeus * bug fixes, code cleanup * @@ -62,11 +66,19 @@ #include "stdafx.h" #include "scumm.h" +#if defined(USE_IMUSE) +#include "sound.h" +#endif + #define SCALEUP_2x2 Scumm scumm; ScummDebugger debugger; +#if defined(USE_IMUSE) +SoundEngine sound; +#endif + static SDL_Surface *screen; void updatePalette(Scumm *s) { @@ -113,9 +125,16 @@ void waitForTimer(Scumm *s) { if (event.key.keysym.sym=='f' && event.key.keysym.mod&KMOD_CTRL) { s->_fastMode ^= 1; } + if (event.key.keysym.sym=='g' && event.key.keysym.mod&KMOD_CTRL) { + s->_fastMode ^= 2; + } + if (event.key.keysym.sym=='d' && event.key.keysym.mod&KMOD_CTRL) { debugger.attach(s); } + if (event.key.keysym.sym=='s' && event.key.keysym.mod&KMOD_CTRL) { + s->resourceStats(); + } break; case SDL_MOUSEMOTION: { @@ -153,7 +172,9 @@ void waitForTimer(Scumm *s) { break; } } - SDL_Delay(dontPause ? 10 : 100); + + if (!(s->_fastMode&2)) + SDL_Delay(dontPause ? 10 : 100); } while (!dontPause); s->_scummTimer+=3; @@ -175,10 +196,17 @@ void addDirtyRect(int x, int y, int w, int h) { fullRedraw = true; else if (!fullRedraw) { r = &dirtyRects[numDirtyRects++]; +#if defined(SCALEUP_2x2) r->x = x*2; r->y = y*2; r->w = w*2; r->h = h*2; +#else + r->x = x; + r->y = y; + r->w = w; + r->h = h; +#endif } } @@ -209,7 +237,7 @@ void blitToScreen(Scumm *s, byte *src,int x, int y, int w, int h) { addDirtyRect(x,y,w,h); do { memcpy(dst, src, w); - dst += 640; + dst += 320; src += 320; } while (--h); #else @@ -231,7 +259,11 @@ void blitToScreen(Scumm *s, byte *src,int x, int y, int w, int h) { } void updateScreen(Scumm *s) { - + + if (s->_fastMode&2) + return; + + if (hide_mouse) { hide_mouse = false; s->drawMouse(); @@ -252,6 +284,7 @@ void updateScreen(Scumm *s) { area += (dirtyRects[i].w * dirtyRects[i].h); debug(2,"update area %f %%", (float)area/640); #endif + SDL_UpdateRects(screen, numDirtyRects, dirtyRects); } @@ -269,6 +302,8 @@ void drawMouse(Scumm *s, int xdraw, int ydraw, int color, byte *mask, bool visib if (SDL_LockSurface(screen)==-1) error("SDL_LockSurface failed: %s.\n", SDL_GetError()); +#if defined(SCALEUP_2x2) + if (has_mouse) { dst = (byte*)screen->pixels + old_mouse_y*640*2 + old_mouse_x*2; bak = old_backup; @@ -308,6 +343,43 @@ void drawMouse(Scumm *s, int xdraw, int ydraw, int color, byte *mask, bool visib } } } +#else + if (has_mouse) { + dst = (byte*)screen->pixels + old_mouse_y*320 + old_mouse_x; + bak = old_backup; + + for (y=0; y<16; y++,bak+=24,dst+=320) { + if ( (uint)(old_mouse_y + y) < 200) { + for (x=0; x<24; x++) { + if ((uint)(old_mouse_x + x) < 320) { + dst[x] = bak[x]; + } + } + } + } + } + if (visible) { + dst = (byte*)screen->pixels + ydraw*320 + xdraw; + bak = old_backup; + + for (y=0; y<16; y++,dst+=320,bak+=24) { + bits = mask[3] | (mask[2]<<8) | (mask[1]<<16); + mask += 4; + if ((uint)(ydraw+y)<200) { + for (x=0; x<24; x++,bits<<=1) { + if ((uint)(xdraw+x)<320) { + bak[x] = dst[x]; + if (bits&(1<<23)) { + dst[x] = color; + } + } + } + } + } + } + + +#endif SDL_UnlockSurface(screen); @@ -322,13 +394,77 @@ void drawMouse(Scumm *s, int xdraw, int ydraw, int color, byte *mask, bool visib old_mouse_x = xdraw; old_mouse_y = ydraw; } - + +} + +#define SAMPLES_PER_SEC 22050 +#define BUFFER_SIZE (8192) +#define BITS_PER_SAMPLE 16 + +static void *_sfx_sound; +static int _sfx_pos; +static int _sfx_size; + +static uint32 _sfx_fp_speed; +static uint32 _sfx_fp_pos; + +bool isSfxFinished() { + return _sfx_size == 0; +} + +void playSfxSound(void *sound, int size, int rate) { + if (_sfx_sound) { + free(_sfx_sound); + } + _sfx_sound = sound; + _sfx_pos = 0; + _sfx_fp_speed = (1<<16) * rate / 22050; + _sfx_fp_pos = 0; + _sfx_size = size * 22050 / rate; +} + +void mix_sound(int16 *data, int len) { + int8 *s; + int i; + uint32 fp_pos, fp_speed; + + if (!_sfx_size) + return; + if (len > _sfx_size) + len = _sfx_size; + _sfx_size -= len; + + s = (int8*)_sfx_sound + _sfx_pos; + fp_pos = _sfx_fp_pos; + fp_speed = _sfx_fp_speed; + + do { + fp_pos += fp_speed; + *data++ += (*s<<6); + s += fp_pos >> 16; + fp_pos &= 0x0000FFFF; + } while (--len); + + _sfx_pos = s - (int8*)_sfx_sound; + _sfx_fp_speed = fp_speed; + _sfx_fp_pos = fp_pos; +} + +void fill_sound(void *userdata, Uint8 *stream, int len) { +#if defined(USE_IMUSE) + sound.generate_samples((int16*)stream, len>>1); +#else + memset(stream, 0, len); +#endif + mix_sound((int16*)stream, len>>1); } void initGraphics(Scumm *s) { - if (SDL_Init(SDL_INIT_VIDEO)==-1) { + SDL_AudioSpec desired; + + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)==-1) { error("Could not initialize SDL: %s.\n", SDL_GetError()); - exit(1); + exit(1); } /* Clean up on exit */ @@ -338,10 +474,20 @@ void initGraphics(Scumm *s) { sprintf(buf, "ScummVM - %s", gameName = s->getGameName()); free(gameName); - + + desired.freq = SAMPLES_PER_SEC; + desired.format = AUDIO_S16SYS; + desired.channels = 1; + desired.samples = 2048; + desired.callback = fill_sound; + SDL_OpenAudio(&desired, NULL); + SDL_PauseAudio(0); + + SDL_WM_SetCaption(buf,buf); SDL_ShowCursor(SDL_DISABLE); + #if !defined(SCALEUP_2x2) screen = SDL_SetVideoMode(320, 200, 8, SDL_SWSURFACE); #else @@ -362,6 +508,12 @@ void initGraphics(Scumm *s) { #undef main int main(int argc, char* argv[]) { scumm._videoMode = 0x13; + +#if defined(USE_IMUSE) + sound.initialize(NULL); + scumm._soundDriver = &sound; +#endif + scumm.scummMain(argc, argv); return 0; } @@ -17,6 +17,10 @@ * * Change Log: * $Log$ + * Revision 1.3 2001/11/05 19:21:49 strigeus + * bug fixes, + * speech in dott + * * Revision 1.2 2001/10/16 10:01:48 strigeus * preliminary DOTT support * @@ -30,6 +34,20 @@ #include "stdafx.h" #include "scumm.h" +#if defined(USE_IMUSE) +#include "sound.h" +#else +struct SoundEngine { + byte **_base_sounds; + int start_sound(int sound) { return -1; } + int stop_sound(int sound) { return -1; } + int stop_all_sounds() { return -1; } + int32 do_command(int a, int b, int c, int d, int e, int f, int g, int h) { return -1; } + int get_sound_status(int sound) { return -1; } + int clear_queue() { return -1; } +}; +#endif + void Scumm::addSoundToQueue(int sound) { _vars[VAR_LAST_SOUND] = sound; ensureResourceLoaded(4, sound); @@ -42,11 +60,14 @@ void Scumm::addSoundToQueue2(int sound) { } } -void Scumm::unkSoundProc22() { +void Scumm::processSoundQues() { byte d; int i,j; int num; int16 data[16]; + SoundEngine *se; + + processSfxQueues(); while (_soundQue2Pos){ d=_soundQue2[--_soundQue2Pos]; @@ -54,39 +75,199 @@ void Scumm::unkSoundProc22() { playSound(d); } -#if 0 for (i=0; i<_soundQuePos; ) { num = _soundQue[i++]; + if (i + num > _soundQuePos) { + warning("processSoundQues: invalid num value"); + break; + } for (j=0; j<16; j++) data[j] = 0; if (num>0) { for (j=0; j<num; j++) - _soundQue[i+j] = data[j]; + data[j] = _soundQue[i+j]; i += num; - /* XXX: not implemented */ - warning("unkSoundProc22: not implemented"); -// vm.vars[VAR_SOUNDRESULT] = soundProcPtr1(...); + + se = (SoundEngine*)_soundDriver; +#if 0 + debug(1,"processSoundQues(%d,%d,%d,%d,%d,%d,%d,%d,%d)", + data[0]>>8, + data[0]&0xFF, + data[1], + data[2], + data[3], + data[4], + data[5], + data[6], + data[7] + ); +#endif + if (se) + _vars[VAR_SOUNDRESULT] = se->do_command(data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7]); } } - #endif _soundQuePos = 0; } void Scumm::playSound(int sound) { - getResourceAddress(4, sound); - /* XXX: not implemented */ -// warning("stub playSound(%d)", sound); + SoundEngine *se = (SoundEngine*)_soundDriver; + if (se) { + getResourceAddress(rtSound, sound); + se->start_sound(sound); + } } -int Scumm::unkSoundProc23(int a) { - /* TODO: implement this */ -// warning("unkSoundProc23: not implemented"); +void Scumm::processSfxQueues() { + Actor *a; + int act; + bool b,finished; + + if (_talk_sound_mode != 0) { + startTalkSound(_talk_sound_a, _talk_sound_b, _talk_sound_mode); + _talk_sound_mode = 0; + } + + if (_sfxMode==2) { + act = _vars[VAR_TALK_ACTOR]; + finished = isSfxFinished(); + + if (act!=0 && (uint)act<0x80 && !string[0].no_talk_anim) { + a = derefActorSafe(act, "processSfxQueues"); + if (a->room==_currentRoom && (finished || !_endOfMouthSync)) { + b = true; + if (!finished) + b = isMouthSyncOff(_curSoundPos); + if (_mouthSyncMode != b) { + _mouthSyncMode = b; + startAnimActor(a, b ? a->talkFrame2 : a->talkFrame1, a->facing); + } + } + } + if (finished && _talkDelay==0) { + stopTalk(); + _sfxMode = 0; + } + } else if (_sfxMode==1) { + if (isSfxFinished()) { + _sfxMode = 0; + } + } +} + +void Scumm::startTalkSound(uint32 offset, uint32 b, int mode) { + int num, i; + byte file_byte,file_byte_2; + uint16 elem; + + if (!_sfxFile) { + warning("startTalkSound: SFX file is not open"); + return; + } + + fileSeek((FILE*)_sfxFile, offset + 8, SEEK_SET); + i = 0; + if (b>8) { + num = (b-8)>>1; + do { + fileRead((FILE*)_sfxFile, &file_byte, sizeof(file_byte)); + fileRead((FILE*)_sfxFile, &file_byte_2, sizeof(file_byte_2)); + _mouthSyncTimes[i++] = file_byte | (file_byte_2<<8); + } while (--num); + } + _mouthSyncTimes[i] = 0xFFFF; + _sfxMode = mode; + _curSoundPos = 0; + _mouthSyncMode = true; + + startSfxSound(_sfxFile); +} + +bool Scumm::isMouthSyncOff(uint pos) { + uint j; + bool val = true; + uint16 *ms = _mouthSyncTimes; + + _endOfMouthSync = false; + do { + val ^= 1; + j = *ms++; + if (j==0xFFFF) { + _endOfMouthSync = true; + break; + } + } while (pos > j); + return val; +} + + +int Scumm::isSoundRunning(int sound) { + SoundEngine *se; + int i; + + i = _soundQue2Pos; + while (i--) { + if (_soundQue2[i] == sound) + return 1; + } + + if (isSoundInQueue(sound)) + return 1; + + if (!isResourceLoaded(4, sound)) + return 0; + + + se = (SoundEngine*)_soundDriver; + if (!se) + return 0; + return se->get_sound_status(sound); +} + +bool Scumm::isSoundInQueue(int sound) { + int i = 0,j, num; + int16 table[16]; + + while (i < _soundQuePos) { + num = _soundQue[i++]; + + memset(table, 0, sizeof(table)); + + if (num > 0) { + for (j=0; j<num; j++) + table[j] = _soundQue[i+j]; + i += num; + if (table[0] == 0x10F && table[1]==8 && table[2] == sound) + return 1; + } + } return 0; } -void Scumm::unkSoundProc1(int a) { - /* TODO: implement this */ -// warning("unkSoundProc: not implemented"); +void Scumm::stopSound(int a) { + SoundEngine *se; + int i; + + se = (SoundEngine*)_soundDriver; + if (se) + se->stop_sound(a); + + for (i=0; i<10; i++) + if (_soundQue2[i] == (byte)a) + _soundQue2[i] = 0; +} + +void Scumm::stopAllSounds() { + SoundEngine *se = (SoundEngine*)_soundDriver; + if (se) { + se->stop_all_sounds(); + se->clear_queue(); + } + clearSoundQue(); +} + +void Scumm::clearSoundQue() { + _soundQue2Pos = 0; + memset(_soundQue2, 0, sizeof(_soundQue2)); } void Scumm::soundKludge(int16 *list) { @@ -94,7 +275,7 @@ void Scumm::soundKludge(int16 *list) { int i; if (list[0]==-1) { - unkSoundProc22(); + processSoundQues(); return; } _soundQue[_soundQuePos++] = 8; @@ -106,4 +287,84 @@ void Scumm::soundKludge(int16 *list) { *ptr++ = list[i]; if (_soundQuePos > 0x100) error("Sound que buffer overflow"); +} + +void Scumm::talkSound(uint32 a, uint32 b, int mode) { + _talk_sound_a = a; + _talk_sound_b = b; + _talk_sound_mode = mode; +} + +static const uint32 sound_tags[] = { + MKID('ADL ') +}; + +void Scumm::setupSound() { + SoundEngine *se = (SoundEngine*)_soundDriver; + if (se) { + se->_base_sounds = res.address[4]; + } + _soundTagTable = (byte*)sound_tags; + _numSoundTags = 1; + if (_majorScummVersion==6) + _sfxFile = openSfxFile(); +} + +struct VOCHeader { + byte id[19]; + byte extra[7]; +}; + +static const char VALID_VOC_ID[] = "Creative Voice File"; +static const char VALID_VOC_VERSION[] = ""; +void Scumm::startSfxSound(void *file) { + VOCHeader hdr; + int block_type; + byte work[8]; + uint size,i; + int rate,comp; + byte *data; + + if (fread(&hdr, sizeof(hdr), 1, (FILE*)file) != 1 || + memcmp(hdr.id, VALID_VOC_ID, sizeof(hdr.id)) != 0) { + warning("startSfxSound: invalid header"); + return; + } + + block_type = getc( (FILE*)file ); + if (block_type != 1) { + warning("startSfxSound: Expecting block_type == 1, got %d", block_type); + return; + } + + fread(work, 3, 1, (FILE*)file); + + size = ( work[0] | ( work[1] << 8 ) | ( work[2] << 16 ) ) - 2; + rate = getc( (FILE*)file ); + comp = getc( (FILE*)file ); + + if (comp != 0) { + warning("startSfxSound: Unsupported compression type %d", comp); + return; + } + + data = (byte*) malloc(size); + if (data==NULL) { + error("startSfxSound: out of memory"); + return; + } + + if (fread(data, size, 1, (FILE*)file) != 1) { + /* no need to free the memory since error will shut down */ + error("startSfxSound: cannot read %d bytes", size); + return; + } + for(i=0;i<size; i++) + data[i] ^= 0x80; + + playSfxSound(data, size, 1000000 / (256 - rate) ); +} + +void *Scumm::openSfxFile() { + return fopen("monster.sou", "rb"); }
\ No newline at end of file @@ -1,12 +1,3 @@ -/* - * $Id$ - * - * $Log$ - * Revision 1.4 2001/11/03 06:40:51 cmatsuoka - * Not including unistd.h in BeOS (breaks cross-compilation). - * - */ - #if defined(WIN32) #if _MSC_VER > 1000 @@ -48,6 +39,7 @@ #include <conio.h> #include <malloc.h> #include <assert.h> +#include <mmsystem.h> #else @@ -56,9 +48,7 @@ #endif #include <sys/types.h> #include <sys/uio.h> -#if !defined(__BEOS__) #include <unistd.h> -#endif #include <stdio.h> #include <fcntl.h> #include <stdlib.h> diff --git a/string.cpp b/string.cpp index 556b6aa249..7ed750f133 100644 --- a/string.cpp +++ b/string.cpp @@ -17,6 +17,10 @@ * * Change Log: * $Log$ + * Revision 1.6 2001/11/05 19:21:49 strigeus + * bug fixes, + * speech in dott + * * Revision 1.5 2001/10/26 17:34:50 strigeus * bug fixes, code cleanup * @@ -46,7 +50,7 @@ int CharsetRenderer::getStringWidth(int arg, byte *text, int pos) { byte chr; width = 1; - ptr = _vm->getResourceAddress(6, _curId) + 29; + ptr = _vm->getResourceAddress(rtCharset, _curId) + 29; while ( (chr = text[pos++]) != 0) { if (chr==0xD) @@ -74,7 +78,7 @@ int CharsetRenderer::getStringWidth(int arg, byte *text, int pos) { if (chr==14) { int set = text[pos] | (text[pos+1]<<8); pos+=2; - ptr = _vm->getResourceAddress(6, set) + 29; + ptr = _vm->getResourceAddress(rtCharset, set) + 29; continue; } } @@ -99,7 +103,7 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) { byte *ptr; byte chr; - ptr = _vm->getResourceAddress(6, _curId) + 29; + ptr = _vm->getResourceAddress(rtCharset, _curId) + 29; while ( (chr=str[pos++]) != 0) { if (chr=='@') @@ -131,7 +135,7 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) { if (chr==14) { int set = str[pos] | (str[pos+1]<<8); pos+=2; - ptr = _vm->getResourceAddress(6, set) + 29; + ptr = _vm->getResourceAddress(rtCharset, set) + 29; continue; } } @@ -160,10 +164,18 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) { } void Scumm::unkMessage1() { - byte buf[100]; - _msgPtrToAdd = buf; + byte buffer[100]; + _msgPtrToAdd = buffer; _messagePtr = addMessageToStack(_messagePtr); + if (buffer[0] == 0xFF && buffer[1]==10) { + uint32 a,b; + + a = buffer[2] | (buffer[3]<<8) | (buffer[6]<<16) | (buffer[7]<<24); + b = buffer[10] | (buffer[11]<<8) | (buffer[14]<<16) | (buffer[15]<<24); + talkSound(a,b,1); + } + // warning("unkMessage1(\"%s\")", buf); } @@ -185,6 +197,7 @@ void Scumm::CHARSET_1() { int s, i, t, c; int frme; Actor *a; + byte *buffer; if (!_haveMsg || (camera._destPos>>3) != (camera._curPos>>3) || camera._curPos != camera._lastPos @@ -253,12 +266,14 @@ void Scumm::CHARSET_1() { return; if (_haveMsg!=0xFF) { - stopTalk(); + if (_sfxMode==0) + stopTalk(); return; } - if (a) { + if (a && !string[0].no_talk_anim) { startAnimActor(a, a->talkFrame1, a->facing); + _useTalkAnims = true; } _talkDelay = _defaultTalkDelay; @@ -275,17 +290,20 @@ void Scumm::CHARSET_1() { t = string[0].xpos2; t <<= 1; } - charset.addLinebreaks(0, charset._buffer, charset._bufPos, t); + + buffer = charset._buffer + charset._bufPos; + + charset.addLinebreaks(0, buffer,0, t); _lastXstart = virtscr[0].xstart; if (charset._center) { - string[0].xpos2 -= charset.getStringWidth(0, charset._buffer, charset._bufPos) >> 1; + string[0].xpos2 -= charset.getStringWidth(0, buffer,0) >> 1; } charset._disableOffsX = charset._unk12 = !_keepText; do { - c = charset._buffer[charset._bufPos++]; + c = *buffer++; if (c==0) { _haveMsg = 1; _keepText = false; @@ -295,9 +313,9 @@ void Scumm::CHARSET_1() { newLine:; string[0].xpos2 = string[0].xpos; if (charset._center) { - string[0].xpos2 -= charset.getStringWidth(0, charset._buffer, charset._bufPos)>>1; + string[0].xpos2 -= charset.getStringWidth(0, buffer, 0)>>1; } - string[0].ypos2 += getResourceAddress(6,charset._curId)[30]; + string[0].ypos2 += getResourceAddress(rtCharset,charset._curId)[30]; charset._disableOffsX = 1; continue; } @@ -323,7 +341,7 @@ newLine:; continue; } - c = charset._buffer[charset._bufPos++]; + c = *buffer++; if (c==3) { _haveMsg = 0xFF; _keepText = false; @@ -335,36 +353,42 @@ newLine:; _keepText = true; break; } else if (c==9) { - frme = charset._buffer[charset._bufPos++]; - frme |= charset._buffer[charset._bufPos++]<<8; + frme = *buffer++; + frme |= *buffer++<<8; if (a) startAnimActor(a, frme, a->facing); } else if (c==10) { - warning("CHARSET_1: code 10 unimplemented"); - charset._bufPos += 14; + uint32 a,b; + + a = buffer[0] | (buffer[1]<<8) | (buffer[4]<<16) | (buffer[5]<<24); + b = buffer[8] | (buffer[9]<<8) | (buffer[12]<<16) | (buffer[13]<<24); + talkSound(a,b,2); + buffer += 14; } else if (c==14) { - int oldy = getResourceAddress(6,charset._curId)[30]; + int oldy = getResourceAddress(rtCharset,charset._curId)[30]; - charset._curId = charset._buffer[charset._bufPos]; - charset._bufPos += 2; + charset._curId = *buffer++; + buffer += 2; for (i=0; i<4; i++) charset._colorMap[i] = _charsetData[charset._curId][i]; - string[0].ypos2 -= getResourceAddress(6,charset._curId)[30] - oldy; + string[0].ypos2 -= getResourceAddress(rtCharset,charset._curId)[30] - oldy; } else if (c==12) { int color; - color = charset._buffer[charset._bufPos++]; - color |= charset._buffer[charset._bufPos++]<<8; + color = *buffer++; + color |= *buffer++<<8; if (color==0xFF) charset._color = _charsetColor; else charset._color = color; } else if (c==13) { - charset._bufPos += 2; + buffer += 2; } else { warning("CHARSET_1: invalid code %d", c); } } while (1); + charset._bufPos = buffer - charset._buffer; + string[0].mask_left = charset._strLeft; string[0].mask_right = charset._strRight; string[0].mask_top = charset._strTop; @@ -391,7 +415,7 @@ void Scumm::drawString(int a) { charset._unk12 = 1; charset._disableOffsX = 1; - charsetptr = getResourceAddress(6, charset._curId); + charsetptr = getResourceAddress(rtCharset, charset._curId); assert(charsetptr); charsetptr += 29; @@ -469,7 +493,7 @@ byte *Scumm::addMessageToStack(byte *msg) { byte *ptr, chr; numorg = num = _numInMsgStack; - ptr = getResourceAddress(0xC, 6); + ptr = getResourceAddress(rtTemp, 6); if (ptr==NULL) error("Message stack not allocated"); @@ -495,7 +519,7 @@ byte *Scumm::addMessageToStack(byte *msg) { num = numorg; while (1) { - ptr = getResourceAddress(0xC, 6); + ptr = getResourceAddress(rtTemp, 6); chr = ptr[num++]; if (chr == 0) break; @@ -573,7 +597,7 @@ void Scumm::unkAddMsgToStack3(int var) { if (num) { for (i=1; i<_maxVerbs; i++) { if (num==_verbs[i].verbid && !_verbs[i].type && !_verbs[i].saveid) { - addMessageToStack(getResourceAddress(8, i)); + addMessageToStack(getResourceAddress(rtVerb, i)); break; } } @@ -612,7 +636,7 @@ void Scumm::unkAddMsgToStack5(int var) { void Scumm::initCharset(int charsetno) { int i; - if (!getResourceAddress(6, charsetno)) + if (!getResourceAddress(rtCharset, charsetno)) loadCharset(charsetno); string[0].t_charset = charsetno; @@ -633,7 +657,7 @@ void CharsetRenderer::printChar(int chr) { if (chr=='@') return; - _ptr = _vm->getResourceAddress(6, _curId) + 29; + _ptr = _vm->getResourceAddress(rtCharset, _curId) + 29; _bpp = _unk2 = *_ptr; _invNumBits = 8 - _bpp; @@ -716,7 +740,7 @@ void CharsetRenderer::printChar(int chr) { _hasMask = true; #endif - _bg_ptr2 = _backbuff_ptr = _vm->getResourceAddress(0xA, vs->number+1) + _bg_ptr2 = _backbuff_ptr = _vm->getResourceAddress(rtBuffer, vs->number+1) + vs->xstart + _drawTop * 320 + _left; #if !defined(OLD) @@ -724,11 +748,11 @@ void CharsetRenderer::printChar(int chr) { #else if (1) { #endif - _bg_ptr2 = _bgbak_ptr = _vm->getResourceAddress(0xA, vs->number+5) + _bg_ptr2 = _bgbak_ptr = _vm->getResourceAddress(rtBuffer, vs->number+5) + vs->xstart + _drawTop * 320 + _left; } - _mask_ptr = _vm->getResourceAddress(0xA, 9) + _mask_ptr = _vm->getResourceAddress(rtBuffer, 9) + _drawTop * 40 + _left/8 + _vm->_screenStartStrip; @@ -17,6 +17,10 @@ * * Change Log: * $Log$ + * Revision 1.3 2001/11/05 19:21:49 strigeus + * bug fixes, + * speech in dott + * * Revision 1.2 2001/10/10 10:02:33 strigeus * alternative mouse cursor * basic save&load @@ -96,7 +100,7 @@ void Scumm::fileRead(void *file, void *ptr, uint32 size) { if (size==0) return; - src = getResourceAddress(0xC, 3) + _whereInResToRead; + src = getResourceAddress(rtTemp, 3) + _whereInResToRead; _whereInResToRead += size; do { *ptr2++ = *src++ ^ _encbyte; @@ -116,7 +120,7 @@ int Scumm::fileReadByte() { return b ^ _encbyte; case 3: - src = getResourceAddress(0xC, 3) + _whereInResToRead; + src = getResourceAddress(rtTemp, 3) + _whereInResToRead; _whereInResToRead++; return *src ^ _encbyte; } @@ -157,13 +161,15 @@ byte *Scumm::alloc(int size) { } void Scumm::free(void *mem) { - byte *me = (byte*)mem - 4; - if ( *((uint32*)me) != 0xDEADBEEF) { - error("Freeing invalid block."); + if (mem) { + byte *me = (byte*)mem - 4; + if ( *((uint32*)me) != 0xDEADBEEF) { + error("Freeing invalid block."); + } + + *((uint32*)me) = 0xC007CAFE; + ::free(me); } - - *((uint32*)me) = 0xC007CAFE; - ::free(me); } bool Scumm::checkFixedDisk() { @@ -17,6 +17,10 @@ * * Change Log: * $Log$ + * Revision 1.5 2001/11/05 19:21:49 strigeus + * bug fixes, + * speech in dott + * * Revision 1.4 2001/10/26 17:34:50 strigeus * bug fixes, code cleanup * @@ -143,7 +147,7 @@ void Scumm::drawVerb(int vrb, int mode) { string[4].color = color; if (vs->curmode==2) string[4].color = vs->dimcolor; - _messagePtr = getResourceAddress(8, vrb); + _messagePtr = getResourceAddress(rtVerb, vrb); assert(_messagePtr); tmp = charset._center; charset._center = 0; @@ -198,7 +202,7 @@ void Scumm::drawVerbBitmap(int vrb, int x, int y) { ydiff = y - vs->topline; - obim = getResourceAddress(8, vrb); + obim = getResourceAddress(rtVerb, vrb); IMHD_ptr = findResource(MKID('IMHD'), obim, 0); imgw = READ_LE_UINT16(IMHD_ptr+0x14) >> 3; @@ -247,7 +251,7 @@ void Scumm::killVerb(int slot) { vs->verbid = 0; vs->curmode = 0; - nukeResource(8, slot); + nukeResource(rtVerb, slot); if (vs->saveid==0) { drawVerb(slot, 0); @@ -267,8 +271,8 @@ void Scumm::setVerbObject(int room, int object, int verb) { if (whereIsObject(object) == 4) error("Can't grab verb image from flobject"); - ensureResourceLoaded(1,room); - roomptr = getResourceAddress(1, room); + ensureResourceLoaded(rtRoom,room); + roomptr = getResourceAddress(rtRoom, room); roomhdr = (RoomHeader*)findResource(MKID('RMHD'), roomptr, 0); numobj = READ_LE_UINT16(&roomhdr->numObjects); @@ -285,9 +289,9 @@ void Scumm::setVerbObject(int room, int object, int verb) { if ( READ_LE_UINT16(&imhd->obj_id) == object) { imoffs = obimptr - roomptr; size = READ_BE_UINT32_UNALIGNED(obimptr+4); - createResource(8, verb, size); - obimptr = getResourceAddress(1, room) + imoffs; - memcpy(getResourceAddress(8, verb), obimptr, size); + createResource(rtVerb, verb, size); + obimptr = getResourceAddress(rtRoom, room) + imoffs; + memcpy(getResourceAddress(rtVerb, verb), obimptr, size); return; } } diff --git a/windows.cpp b/windows.cpp index dcb0f6d947..2092ffd775 100644 --- a/windows.cpp +++ b/windows.cpp @@ -17,6 +17,10 @@ * * Change Log: * $Log$ + * Revision 1.9 2001/11/05 19:21:49 strigeus + * bug fixes, + * speech in dott + * * Revision 1.8 2001/10/26 17:34:50 strigeus * bug fixes, code cleanup * @@ -61,6 +65,10 @@ #include "scumm.h" +#if defined(USE_IMUSE) +#include "sound.h" +#endif + #define SRC_WIDTH 320 #define SRC_HEIGHT 200 #define SRC_PITCH (320) @@ -72,6 +80,13 @@ #define USE_DRAWDIB 0 #define USE_GDI 1 +#define SAMPLES_PER_SEC 22050 +#define BUFFER_SIZE (8192) +#define BITS_PER_SAMPLE 16 + +static bool shutdown; + + #if USE_GDI typedef struct DIB { HBITMAP hSect; @@ -115,6 +130,11 @@ public: void InitDirectX(); #endif + HANDLE _event; + DWORD _threadId; + HWAVEOUT _handle; + WAVEHDR _hdr[2]; + public: void init(); @@ -123,6 +143,10 @@ public: void setPalette(byte *ctab, int first, int num); void writeToScreen(); + void prepare_header(WAVEHDR *wh, int i); + void sound_init(); + static DWORD _stdcall sound_thread(WndMan *wm); + #if USE_GDI bool allocateDIB(int w, int h); #endif @@ -137,6 +161,7 @@ void Error(const char *msg) { int sel; Scumm scumm; ScummDebugger debugger; +SoundEngine sound; WndMan wm[1]; byte veryFastMode; @@ -150,7 +175,9 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l { case WM_DESTROY: case WM_CLOSE: - PostQuitMessage(0); +// TerminateThread((void*)wm->_threadId, 0); +// wm->_scumm->destroy(); + exit(0); break; case WM_CHAR: @@ -178,6 +205,10 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l if (wParam=='D') { debugger.attach(wm->_scumm); } + + if (wParam=='S') { + wm->_scumm->resourceStats(); + } break; @@ -761,28 +792,28 @@ void outputdisplay2(Scumm *s, int disp) { case 0: wm->_vgabuf = buf; memcpy(buf, wm->_vgabuf, 64000); - memcpy(buf+320*144,s->getResourceAddress(0xA, 7),320*56); + memcpy(buf+320*144,s->getResourceAddress(rtBuffer, 7),320*56); break; case 1: wm->_vgabuf = buf; memcpy(buf, wm->_vgabuf, 64000); - memcpy(buf+320*144,s->getResourceAddress(0xA, 3),320*56); + memcpy(buf+320*144,s->getResourceAddress(rtBuffer, 3),320*56); break; case 2: wm->_vgabuf = NULL; - decompressMask(wm->dib.buf, s->getResourceAddress(0xA, 9)+s->_screenStartStrip); + decompressMask(wm->dib.buf, s->getResourceAddress(rtBuffer, 9)+s->_screenStartStrip); break; case 3: wm->_vgabuf = NULL; - decompressMask(wm->dib.buf, s->getResourceAddress(0xA, 9)+5920+s->_screenStartStrip); + decompressMask(wm->dib.buf, s->getResourceAddress(rtBuffer, 9)+5920+s->_screenStartStrip); break; case 4: wm->_vgabuf = NULL; - decompressMask(wm->dib.buf, s->getResourceAddress(0xA, 9)+5920*2+s->_screenStartStrip); + decompressMask(wm->dib.buf, s->getResourceAddress(rtBuffer, 9)+5920*2+s->_screenStartStrip); break; case 5: wm->_vgabuf = NULL; - decompressMask(wm->dib.buf, s->getResourceAddress(0xA, 9)+5920*3+s->_screenStartStrip); + decompressMask(wm->dib.buf, s->getResourceAddress(rtBuffer, 9)+5920*3+s->_screenStartStrip); break; } wm->writeToScreen(); @@ -838,17 +869,81 @@ void initGraphics(Scumm *s) { void drawMouse(Scumm *s, int, int, int, byte*, bool) { } +void WndMan::prepare_header(WAVEHDR *wh, int i) { + memset(wh, 0, sizeof(WAVEHDR)); + wh->lpData = (char*)malloc(BUFFER_SIZE); + wh->dwBufferLength = BUFFER_SIZE; + + waveOutPrepareHeader(_handle, wh, sizeof(WAVEHDR)); + + sound.generate_samples((int16*)wh->lpData, wh->dwBufferLength>>1); + waveOutWrite(_handle, wh, sizeof(WAVEHDR)); +} + +void WndMan::sound_init() { + WAVEFORMATEX wfx; + + memset(&wfx, 0, sizeof(wfx)); + wfx.wFormatTag = WAVE_FORMAT_PCM; + wfx.nChannels = 1; + wfx.nSamplesPerSec = SAMPLES_PER_SEC; + wfx.nAvgBytesPerSec = SAMPLES_PER_SEC * BITS_PER_SAMPLE / 8; + wfx.wBitsPerSample = BITS_PER_SAMPLE; + wfx.nBlockAlign = BITS_PER_SAMPLE * 1 / 8; + + CreateThread(NULL, 0, (unsigned long (__stdcall *)(void *))&sound_thread, this, 0, &_threadId); + + _event = CreateEvent(NULL, false, false, NULL); + + memset(_hdr,0,sizeof(_hdr)); + + waveOutOpen(&_handle, WAVE_MAPPER, &wfx, (long)_event, (long)this, CALLBACK_EVENT ); + + prepare_header(&_hdr[0], 0); + prepare_header(&_hdr[1], 1); +} + +DWORD _stdcall WndMan::sound_thread(WndMan *wm) { + int i; + while (1) { + WaitForSingleObject(wm->_event, INFINITE); + for(i=0; i<2; i++) { + WAVEHDR *hdr = &wm->_hdr[i]; + if (hdr->dwFlags & WHDR_DONE) { + sound.generate_samples((int16*)hdr->lpData, hdr->dwBufferLength>>1); + waveOutWrite(wm->_handle, hdr, sizeof(WAVEHDR)); + } + } + } +} + + #undef main int main(int argc, char* argv[]) { scumm._videoMode = 0x13; wm->init(); + wm->sound_init(); wm->_vgabuf = (byte*)calloc(320,200); wm->_scumm = &scumm; +#if defined(USE_IMUSE) + sound.initialize(NULL); + scumm._soundDriver = &sound; +#endif + scumm.scummMain(argc, argv); return 0; } + +bool isSfxFinished() { + return true; +} + +void playSfxSound(void *sound, int size, int rate) { + +} + |