aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile16
-rw-r--r--actor.cpp36
-rw-r--r--boxes.cpp36
-rw-r--r--costume.cpp65
-rw-r--r--gfx.cpp103
-rw-r--r--object.cpp46
-rw-r--r--resource.cpp153
-rw-r--r--saveload.cpp172
-rw-r--r--script.cpp39
-rw-r--r--script_v1.cpp77
-rw-r--r--script_v2.cpp72
-rw-r--r--scumm.h225
-rw-r--r--scummsys.h9
-rw-r--r--scummvm.cpp66
-rw-r--r--scummvm.dsp20
-rw-r--r--sdl.cpp166
-rw-r--r--sound.cpp295
-rw-r--r--stdafx.h12
-rw-r--r--string.cpp92
-rw-r--r--sys.cpp22
-rw-r--r--verbs.cpp20
-rw-r--r--windows.cpp109
22 files changed, 1363 insertions, 488 deletions
diff --git a/Makefile b/Makefile
index 985dc3f896..767bbaa308 100644
--- a/Makefile
+++ b/Makefile
@@ -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
-
diff --git a/actor.cpp b/actor.cpp
index 1069886e1b..efdac193a6 100644
--- a/actor.cpp
+++ b/actor.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
*
@@ -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
diff --git a/boxes.cpp b/boxes.cpp
index 6d56e15752..8db43bb69e 100644
--- a/boxes.cpp
+++ b/boxes.cpp
@@ -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;
}
diff --git a/gfx.cpp b/gfx.cpp
index 3aafdc4ba0..dcdb0e3848 100644
--- a/gfx.cpp
+++ b/gfx.cpp
@@ -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;
diff --git a/scumm.h b/scumm.h
index 71c5fe2e59..9ed9b23d7f 100644
--- a/scumm.h
+++ b/scumm.h
@@ -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
diff --git a/sdl.cpp b/sdl.cpp
index 183f7797b1..c142ba5193 100644
--- a/sdl.cpp
+++ b/sdl.cpp
@@ -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;
}
diff --git a/sound.cpp b/sound.cpp
index cfee9440a0..c8e3beab9a 100644
--- a/sound.cpp
+++ b/sound.cpp
@@ -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
diff --git a/stdafx.h b/stdafx.h
index 5ad444f399..f1f8202370 100644
--- a/stdafx.h
+++ b/stdafx.h
@@ -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;
diff --git a/sys.cpp b/sys.cpp
index 6d71570b57..9c5a10dd6d 100644
--- a/sys.cpp
+++ b/sys.cpp
@@ -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() {
diff --git a/verbs.cpp b/verbs.cpp
index 1b7df4cc22..bba4f698d4 100644
--- a/verbs.cpp
+++ b/verbs.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
*
@@ -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) {
+
+}
+