aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--boxes.cpp13
-rw-r--r--object.cpp133
-rw-r--r--resource.cpp164
-rw-r--r--script_v1.cpp99
-rw-r--r--scumm.h3
-rw-r--r--scummvm.cpp110
-rw-r--r--sdl.cpp5
-rw-r--r--sound.cpp4
-rw-r--r--string.cpp49
-rw-r--r--verbs.cpp33
10 files changed, 468 insertions, 145 deletions
diff --git a/boxes.cpp b/boxes.cpp
index 72a4c6c9b0..9135ee8498 100644
--- a/boxes.cpp
+++ b/boxes.cpp
@@ -43,15 +43,12 @@ byte Scumm::getNumBoxes() {
}
Box *Scumm::getBoxBaseAddr(int box) {
- byte *ptr;
-
- if(_features & GF_SMALL_HEADER)
- ptr = getResourceAddress(rtMatrix, 1);
- else
- ptr = getResourceAddress(rtMatrix, 2);
-
+ byte *ptr = getResourceAddress(rtMatrix, 2);
checkRange(ptr[0]-1, 0, box, "Illegal box %d");
- return (Box*)(ptr + box*SIZEOF_BOX + 2);
+ if(_features & GF_SMALL_HEADER)
+ return (Box*)(ptr + box*SIZEOF_BOX + 1);
+ else
+ return (Box*)(ptr + box*SIZEOF_BOX + 2);
}
bool Scumm::checkXYInBoxBounds(int b, int x, int y) {
diff --git a/object.cpp b/object.cpp
index 71cffd06a6..1c98b7d811 100644
--- a/object.cpp
+++ b/object.cpp
@@ -134,27 +134,33 @@ void Scumm::getObjectXYPos(int object) {
ImageHeader *imhd;
int x,y;
AdjustBoxResult abr;
-
- if (_features&GF_AFTER_V6) {
- state = getState(object)-1;
- if (state<0)
- state = 0;
-
- if (od->fl_object_index) {
- ptr = getResourceAddress(rtFlObject, od->fl_object_index);
- ptr = findResource(MKID('OBIM'), ptr);
- } else {
- ptr = getResourceAddress(rtRoom, _roomResource);
- ptr += od->offs_obim_to_room;
- }
- assert(ptr);
- imhd = (ImageHeader*)findResourceData(MKID('IMHD'), ptr);
- x = od->x_pos + (int16)READ_LE_UINT16(&imhd->hotspot[state].x);
- y = od->y_pos + (int16)READ_LE_UINT16(&imhd->hotspot[state].y);
- } else {
- x = (int16)READ_LE_UINT16(&od->walk_x);
- y = (int16)READ_LE_UINT16(&od->walk_y);
- }
+ if(!(_features & GF_SMALL_HEADER)) {
+ if (_features&GF_AFTER_V6) {
+ state = getState(object)-1;
+ if (state<0)
+ state = 0;
+
+ if (od->fl_object_index) {
+ ptr = getResourceAddress(rtFlObject, od->fl_object_index);
+ ptr = findResource(MKID('OBIM'), ptr);
+ } else {
+ ptr = getResourceAddress(rtRoom, _roomResource);
+ ptr += od->offs_obim_to_room;
+ }
+ assert(ptr);
+ imhd = (ImageHeader*)findResourceData(MKID('IMHD'), ptr);
+ x = od->x_pos + (int16)READ_LE_UINT16(&imhd->hotspot[state].x);
+ y = od->y_pos + (int16)READ_LE_UINT16(&imhd->hotspot[state].y);
+ } else {
+ x = (int16)READ_LE_UINT16(&od->walk_x);
+ y = (int16)READ_LE_UINT16(&od->walk_y);
+ }
+ } else {
+ x = (int16)READ_LE_UINT16(&od->x_pos);
+ y = (int16)READ_LE_UINT16(&od->y_pos);
+ _xPos = x;
+ _yPos = y;
+ }
// abr = adjustXYToBeInBox(0, x, y);
// _xPos = abr.x;
@@ -304,7 +310,10 @@ void Scumm::drawObject(int obj, int arg) {
ptr = ptr + od->offs_obim_to_room;
}
- ptr = findResource(IMxx_tags[getState(od->obj_nr)], ptr);
+ if(_features & GF_SMALL_HEADER)
+ ptr +=8;
+ else
+ ptr = findResource(IMxx_tags[getState(od->obj_nr)], ptr);
if (!ptr)
return;
@@ -473,8 +482,24 @@ void Scumm::setupRoomObject(ObjectData *od, byte *room) {
CodeHeader *cdhd;
ImageHeader *imhd;
- cdhd = (CodeHeader*)findResourceData(MKID('CDHD'), room + od->offs_obcd_to_room);
+ if(_features & GF_SMALL_HEADER) {
+ byte *ptr = room + od->offs_obcd_to_room;
+ od->obj_nr = READ_LE_UINT16(ptr+6);
+ od->width = *(ptr+11)<<3;
+ od->height = *(ptr+17);
+ od->x_pos = *(ptr+9)<<3;
+ od->y_pos = *(ptr+10)<<3;
+
+ if(*(ptr+10) == 0x80) {
+ od->parentstate = 1; // it's 0x10 in the original code
+ } else {
+ od->parentstate = 0;
+ }
+
+ return;
+ }
+ cdhd = (CodeHeader*)findResourceData(MKID('CDHD'), room + od->offs_obcd_to_room);
od->obj_nr = READ_LE_UINT16(&cdhd->obj_id);
#if !defined(FULL_THROTTLE)
@@ -614,6 +639,14 @@ byte *Scumm::getObjOrActorName(int obj) {
if (obj < NUM_ACTORS)
return getActorName(derefActorSafe(obj, "getObjOrActorName"));
+ if(_features & GF_SMALL_HEADER) {
+ byte offset;
+
+ objptr = getOBCDFromObject(obj);
+ offset = *(objptr+18);
+ return(objptr+offset);
+ }
+
objptr = getOBCDFromObject(obj);
if (objptr==NULL)
return (byte*)" ";
@@ -677,7 +710,10 @@ void Scumm::addObjectToInventory(uint obj, uint room) {
memcpy(getResourceAddress(rtInventory, slot), ptr, size);
} else {
findObjectInRoom(&foir, foCodeHeader, obj, room);
- size = READ_BE_UINT32_UNALIGNED(foir.obcd+4);
+ if(_features & GF_SMALL_HEADER )
+ size = READ_LE_UINT32(foir.obcd);
+ else
+ size = READ_BE_UINT32_UNALIGNED(foir.obcd+4);
slot = getInventorySlot();
_inventory[slot] = obj;
createResource(rtInventory, slot, size);
@@ -715,15 +751,26 @@ void Scumm::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, uint
if (findWhat & foCodeHeader) {
searchptr = roomptr;
for (i=0;;) {
- obcdptr = findResource(MKID('OBCD'), searchptr);
+ if(_features & GF_SMALL_HEADER)
+ obcdptr = findResourceSmall(MKID('OBCD'), searchptr);
+ else
+ obcdptr = findResource(MKID('OBCD'), searchptr);
if(obcdptr==NULL)
error("findObjectInRoom: Not enough code blocks in room %d", room);
- cdhd = (CodeHeader*)findResourceData(MKID('CDHD'), obcdptr);
- if ( READ_LE_UINT16(&cdhd->obj_id) == (uint16)id) {
- fo->cdhd = cdhd;
- fo->obcd = obcdptr;
- break;
- }
+ if ( _features & GF_SMALL_HEADER) {
+ if ( READ_LE_UINT16(obcdptr+6) == (uint16)id) {
+ fo->cdhd = NULL;
+ fo->obcd = obcdptr;
+ break;
+ }
+ } else {
+ cdhd = (CodeHeader*)findResourceData(MKID('CDHD'), obcdptr);
+ if ( READ_LE_UINT16(&cdhd->obj_id) == (uint16)id) {
+ fo->cdhd = cdhd;
+ fo->obcd = obcdptr;
+ break;
+ }
+ }
if (++i == numobj)
error("findObjectInRoom: Object %d not found in room %d", id, room);
searchptr = NULL;
@@ -733,16 +780,26 @@ void Scumm::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, uint
if (findWhat & foImageHeader) {
searchptr = roomptr;
for(i=0;;) {
- obimptr = findResource(MKID('OBIM'), searchptr);
+ if(_features & GF_SMALL_HEADER)
+ obimptr = findResourceSmall(MKID('OBIM'), searchptr);
+ else
+ obimptr = findResource(MKID('OBIM'), searchptr);
if (obimptr==NULL)
error("findObjectInRoom: Not enough image blocks in room %d", room);
imhd = (ImageHeader*)findResourceData(MKID('IMHD'), obimptr);
- if (READ_LE_UINT16(&imhd->obj_id) == (uint16)id) {
- fo->obim = obimptr;
- fo->imhd = imhd;
- break;
- }
-
+ if(_features & GF_SMALL_HEADER){
+ if (READ_LE_UINT16(obimptr+6) == (uint16)id) {
+ fo->obim = obimptr;
+ fo->imhd = imhd;
+ break;
+ }
+ } else {
+ if (READ_LE_UINT16(&imhd->obj_id) == (uint16)id) {
+ fo->obim = obimptr;
+ fo->imhd = imhd;
+ break;
+ }
+ }
if (++i==numobj)
error("findObjectInRoom: Object %d image not found in room %d", id, room);
searchptr = NULL;
diff --git a/resource.cpp b/resource.cpp
index c08b5f90fc..bfd0c1686a 100644
--- a/resource.cpp
+++ b/resource.cpp
@@ -48,7 +48,10 @@ void Scumm::openRoom(int room) {
#if REAL_CODE
room_offs = _roomFileOffsets[room];
#else
- room_offs = room ? _roomFileOffsets[room] : 0;
+ if(_features & GF_EXTERNAL_CHARSET && room>=900)
+ room_offs = 0;
+ else
+ room_offs = room ? _roomFileOffsets[room] : 0;
#endif
if (room_offs == 0xFFFFFFFF)
@@ -61,11 +64,34 @@ void Scumm::openRoom(int room) {
#if defined(FULL_THROTTLE)
sprintf(buf, "%s.la%d", _exe_name,
room==0 ? 0 : res.roomno[rtRoom][room]);
+ _encbyte = (_features & GF_USE_KEY) ? 0x69 : 0;
#else
- sprintf(buf, "%s.%.3d", _exe_name,
- room==0 ? 0 : res.roomno[rtRoom][room]);
+ if( !(_features & GF_SMALL_NAMES))
+ {
+ if(room==0 || room>=900) {
+ sprintf(buf, "%s\\%.3d.lfl",_exe_name,room);
+ _encbyte = 0;
+ if (openResourceFile(buf)) {
+ return;
+ }
+ askForDisk(buf);
+
+ } else {
+ sprintf(buf, "%s\\disk%.2d.lec",_exe_name,res.roomno[rtRoom][room]);
+ _encbyte = 0x69;
+ }
+ } else {
+ sprintf(buf, "%s\\%.2d.lfl",_exe_name,room);
+ if(_features & GF_OLD_BUNDLE)
+ _encbyte = 0xFF;
+ else
+ _encbyte = 0;
+ }
+
+// sprintf(buf, "%s.%.3d", _exe_name, room==0 ? 0 : res.roomno[rtRoom][room]);
+// _encbyte = (_features & GF_USE_KEY) ? 0x69 : 0;
#endif
- _encbyte = (_features & GF_USE_KEY) ? 0x69 : 0;
+
if (openResourceFile(buf)) {
if (room==0)
return;
@@ -110,11 +136,18 @@ void Scumm::readRoomsOffsets() {
debug(9, "readRoomOffsets()");
- deleteRoomOffsets();
- if (!_dynamicRoomOffsets)
- return;
+ deleteRoomOffsets();
+ if(_features & GF_SMALL_NAMES)
+ return;
+
+ if (!(_features & GF_SMALL_HEADER)) {
+ if (!_dynamicRoomOffsets)
+ return;
- fileSeek(_fileHandle, 16, SEEK_SET);
+ fileSeek(_fileHandle, 16, SEEK_SET);
+ } else {
+ fileSeek(_fileHandle, 12, SEEK_SET); // Directlry searching for the room offset block would be more generic...
+ }
num = fileReadByte();
while (num) {
@@ -439,9 +472,16 @@ void Scumm::readResTypeList(int id, uint32 tag, const char *name) {
}
allocResTypeData(id, tag, num, name, 1);
}
-
- fileRead(_fileHandle, res.roomno[id], num*sizeof(uint8));
- fileRead(_fileHandle, res.roomoffs[id], num*sizeof(uint32));
+
+ if (_features & GF_SMALL_HEADER) {
+ for (i=0; i<num; i++) {
+ res.roomno[id][i] = fileReadByte();
+ res.roomoffs[id][i]= fileReadDwordLE();
+ }
+ } else {
+ fileRead(_fileHandle, res.roomno[id], num*sizeof(uint8));
+ fileRead(_fileHandle, res.roomoffs[id], num*sizeof(uint32));
+ }
#if defined(SCUMM_BIG_ENDIAN)
for (i=0; i<num; i++)
@@ -476,8 +516,20 @@ void Scumm::loadCharset(int no) {
byte *ptr;
debug(9, "loadCharset(%d)",no);
-
- checkRange(_maxCharsets-1, 1, no, "Loading illegal charset %d");
+ if(_features & GF_EXTERNAL_CHARSET) {
+ uint32 size;
+ checkRange(4 ,0 ,no , "Loading illegal charset %d");
+ openRoom(-1);
+ if( _features & GF_SMALL_NAMES)
+ openRoom(98+no);
+ else
+ openRoom(900+no);
+ size = fileReadDword();
+ fileRead(_fileHandle, createResource(6, no, size), size);
+ openRoom(-1);
+ } else {
+ checkRange(_maxCharsets-1, 1, no, "Loading illegal charset %d");
+ }
// ensureResourceLoaded(6, no);
ptr = getResourceAddress(6, no);
@@ -522,6 +574,11 @@ int Scumm::loadResource(int type, int index) {
// debug(1, "loadResource(%d,%d)", type,index);
+ if(type == rtCharset && (_features & GF_SMALL_HEADER)){
+ loadCharset(index);
+ return(1);
+ }
+
roomNr = getResourceRoomNr(type, index);
if (roomNr == 0 || index >= res.num[type]) {
error("%s %d undefined",
@@ -541,25 +598,33 @@ int Scumm::loadResource(int type, int index) {
openRoom(roomNr);
fileSeek(_fileHandle, fileOffs + _fileOffset, SEEK_SET);
- if (type==rtSound) {
- fileReadDwordLE();
- fileReadDwordLE();
- return readSoundResource(type, index);
- }
-
- tag = fileReadDword();
- if (tag != res.tags[type]) {
- error("%s %d not in room %d at %d+%d",
- res.name[type], type, roomNr, _fileOffset, fileOffs);
- }
+ if (_features & GF_SMALL_HEADER) {
+ if(!(_features & GF_SMALL_NAMES))
+ fileSeek(_fileHandle, 8, SEEK_CUR);
+ size = fileReadDwordLE();
+ tag = fileReadWordLE();
+ fileSeek(_fileHandle, -6, SEEK_CUR);
+ } else {
+ if (type==rtSound) {
+ fileReadDwordLE();
+ fileReadDwordLE();
+ return readSoundResource(type, index);
+ }
+
+ tag = fileReadDword();
- size = fileReadDwordBE();
- fileSeek(_fileHandle, -8, SEEK_CUR);
+ if (tag != res.tags[type]) {
+ error("%s %d not in room %d at %d+%d",
+ res.name[type], type, roomNr, _fileOffset, fileOffs);
+ }
+ size = fileReadDwordBE();
+ fileSeek(_fileHandle, -8, SEEK_CUR);
+ }
fileRead(_fileHandle, createResource(type, index, size), size);
- /* dump the resource */
+ /* dump the resource */
#ifdef DUMP_SCRIPTS
if(type==rtScript) {
dumpResource("script-", index, getResourceAddress(rtScript, index));
@@ -733,6 +798,13 @@ void Scumm::nukeResource(int type, int index) {
}
byte *Scumm::findResourceData(uint32 tag, byte *ptr) {
+ if(_features & GF_SMALL_HEADER) {
+ ptr = findResourceSmall(tag,ptr,0);
+ if (ptr==NULL)
+ return NULL;
+ return ptr + 6;
+ }
+
ptr = findResource(tag,ptr,0);
if (ptr==NULL)
return NULL;
@@ -742,7 +814,11 @@ byte *Scumm::findResourceData(uint32 tag, byte *ptr) {
int Scumm::getResourceDataSize(byte *ptr) {
if (ptr==NULL)
return 0;
- return READ_BE_UINT32(ptr-4)-8;
+
+ if (_features & GF_SMALL_HEADER)
+ return READ_LE_UINT32(ptr)-6;
+ else
+ return READ_BE_UINT32(ptr-4)-8;
}
struct FindResourceState {
@@ -840,6 +916,38 @@ byte *findResource(uint32 tag, byte *searchin, int index) {
return NULL;
}
+byte *findResourceSmall(uint32 tag, byte *searchin, int index) {
+ uint32 maxsize,curpos,totalsize,size;
+ uint16 smallTag;
+
+ smallTag=newTag2Old(tag);
+
+ assert(searchin);
+
+ totalsize = READ_LE_UINT32(searchin);
+ searchin += 6;
+ curpos = 6;
+
+ while (curpos<totalsize) {
+ size = READ_LE_UINT32(searchin);
+
+ if (READ_LE_UINT16(searchin+4)==smallTag && !index--)
+ return searchin;
+
+ if ((int32)size <= 0) {
+ error("(%c%c%c%c) Not found in %d... illegal block len %d",
+ tag&0xFF,(tag>>8)&0xFF,(tag>>16)&0xFF,(tag>>24)&0xFF,
+ 0, size);
+ return NULL;
+ }
+
+ curpos += size;
+ searchin += size;
+ }
+
+ return NULL;
+}
+
void Scumm::lock(int type, int i) {
validateResource("Locking", type, i);
res.flags[type][i] |= RF_LOCK;
diff --git a/script_v1.cpp b/script_v1.cpp
index 3bc6e6f69d..c23f688e4c 100644
--- a/script_v1.cpp
+++ b/script_v1.cpp
@@ -141,7 +141,7 @@ void Scumm::setupOpcodes() {
&Scumm::o5_add,
&Scumm::o5_divide,
/* 5C */
- &Scumm::o5_badOpcode,
+ &Scumm::o5_oldRoomEffect,
&Scumm::o5_actorSetClass,
&Scumm::o5_walkActorTo,
&Scumm::o5_isActorInBox,
@@ -363,11 +363,15 @@ void Scumm::o5_actorFromPos() {
}
void Scumm::o5_actorSet() {
+ byte convertTable[20] = {1,0,0,2,0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,20};
int act = getVarOrDirectByte(0x80);
Actor *a = derefActorSafe(act, "actorSet");
int i,j;
while ( (_opcode = fetchScriptByte()) != 0xFF) {
+ if(_features & GF_SMALL_HEADER)
+ _opcode = (_opcode&0xE0) | convertTable[(_opcode&0x1F)-1];
+
switch(_opcode&0x1F) {
case 1: /* costume */
setActorCostume(a, getVarOrDirectByte(0x80));
@@ -464,7 +468,7 @@ FixRoom:
a->shadow_mode = getVarOrDirectByte(0x80); /* shadow mode */
break;
default:
- error("o5_actorSet: default case");
+ warning("o5_actorSet: default case");
}
}
}
@@ -578,7 +582,8 @@ void Scumm::o5_cursorCommand() {
case 10: /* set cursor img */
i = getVarOrDirectByte(0x80);
j = getVarOrDirectByte(0x40);
- setCursorImg(i, j, 1);
+ if (!(_gameId==GID_LOOM256))
+ setCursorImg(i, j, 1);
break;
case 11: /* set cursor hotspot */
i = getVarOrDirectByte(0x80);
@@ -698,6 +703,38 @@ void Scumm::o5_drawObject() {
xpos = ypos = 255;
obj = getVarOrDirectWord(0x80);
+ if (_features & GF_SMALL_HEADER) {
+ int temp = getVarOrDirectWord(0x40);
+ int room = getVarOrDirectWord(0x20);
+
+ index = getObjectIndex(obj);
+ if(index==-1)
+ return;
+ od = &_objs[index];
+ xpos = ypos = 255;
+ if (temp!=0xFF) {
+ od->walk_x += (xpos<<3) - od->x_pos;
+ od->x_pos = xpos<<3;
+ od->walk_y += (ypos<<3) - od->y_pos;
+ od->y_pos = ypos<<3;
+ }
+ addObjectToDrawQue(index);
+
+ x = od->x_pos;
+ y = od->y_pos;
+ w = od->width;
+ h = od->height;
+
+ i = _numObjectsInRoom;
+ do {
+ if (_objs[i].x_pos == x && _objs[i].y_pos == y && _objs[i].width == w && _objs[i].height==h)
+ putState(_objs[i].obj_nr, 0);
+ } while (--i);
+
+ putState(obj, state);
+ return;
+ }
+
switch((_opcode = fetchScriptByte())&0x1F) {
case 1: /* draw at */
xpos = getVarOrDirectWord(0x80);
@@ -1318,6 +1355,9 @@ void Scumm::o5_resourceRoutines() {
case 20:/* load fl object */
loadFlObject(getVarOrDirectWord(0x40), res);
break;
+ default:
+ warning("Unknown o5_resourcesroutine: %d", _opcode&0x1F);
+ break;
}
}
@@ -1338,7 +1378,15 @@ void Scumm::o5_roomOps() {
_vars[VAR_CAMERA_MAX_X] = b;
break;
case 2: /* room color */
- error("room-color is no longer a valid command");
+ if(_features & GF_SMALL_HEADER) {
+ a = getVarOrDirectWord(0x80);
+ b = getVarOrDirectWord(0x40);
+ checkRange(256, 0, a, "o5_roomOps: 2: Illegal room color slot (%d)");
+ _currentPalette[a]=b;
+ _fullRedraw = 1;
+ } else {
+ error("room-color is no longer a valid command");
+ }
break;
case 3: /* set screen */
@@ -1347,13 +1395,22 @@ void Scumm::o5_roomOps() {
initScreens(0,a,320,b);
break;
case 4: /* set palette color */
- a = getVarOrDirectWord(0x80);
- b = getVarOrDirectWord(0x40);
- c = getVarOrDirectWord(0x20);
- _opcode = fetchScriptByte();
- d = getVarOrDirectByte(0x80);
- setPalColor(d, a, b, c); /* index, r, g, b */
- break;
+ if(_features & GF_SMALL_HEADER) {
+ a = getVarOrDirectWord(0x80);
+ b = getVarOrDirectWord(0x40);
+ checkRange(256, 0, a, "o5_roomOps: 2: Illegal room color slot (%d)");
+ _currentPalette[a]=b;
+ _fullRedraw = 1;
+ setDirtyColors(a,a);
+ } else {
+ a = getVarOrDirectWord(0x80);
+ b = getVarOrDirectWord(0x40);
+ c = getVarOrDirectWord(0x20);
+ _opcode = fetchScriptByte();
+ d = getVarOrDirectByte(0x80);
+ setPalColor(d, a, b, c); /* index, r, g, b */
+ }
+ break;
case 5: /* shake on */
setShake(1);
break;
@@ -1428,6 +1485,7 @@ void Scumm::o5_roomOps() {
case 16: /* ? */
a = getVarOrDirectByte(0x80);
b = getVarOrDirectByte(0x40);
+ if (a < 1) a = 1; /* FIXME: ZAK256 */
checkRange(16, 1, a, "o5_roomOps: 16: color cycle out of range (%d)");
_colorCycle[a-1].delay = (b!=0) ? 0x4000 / (b*0x4C) : 0;
break;
@@ -1650,9 +1708,13 @@ void Scumm::o5_stringOps() {
a = getVarOrDirectByte(0x80);
b = getVarOrDirectByte(0x40);
ptr = getResourceAddress(rtString, a);
- if (ptr==NULL) error("String %d does not exist", a);
- c = getVarOrDirectByte(0x20);
- ptr[b] = c;
+ if (!(_gameId == GID_LOOM256)) { /* FIXME - LOOM256 */
+ if (ptr==NULL) error("String %d does not exist", a);
+ c = getVarOrDirectByte(0x20);
+ ptr[b] = c;
+ } else
+ getVarOrDirectByte(0x20);
+
break;
case 4: /* get string char */
@@ -2000,4 +2062,13 @@ void Scumm::decodeParseString() {
string[textSlot].t_charset = string[textSlot].charset;
}
+void Scumm::o5_oldRoomEffect() {
+ int a;
+ _opcode=fetchScriptByte();
+ if((_opcode & 0x1F) == 3)
+ {
+ a = getVarOrDirectWord(0x80);
+ }
+ warning("Unsupported oldRoomEffect");
+}
diff --git a/scumm.h b/scumm.h
index 84932b1c09..7e76086ced 100644
--- a/scumm.h
+++ b/scumm.h
@@ -921,6 +921,7 @@ enum GameFeatures {
GF_DEFAULT = GF_USE_KEY,
GF_SMALL_HEADER = 32,
+ GF_EXTERNAL_CHARSET = GF_SMALL_HEADER,
GF_SMALL_NAMES = 64,
GF_OLD_BUNDLE = 128,
GF_16COLOR = 256,
@@ -1500,6 +1501,7 @@ struct Scumm {
void o5_walkActorTo();
void o5_walkActorToActor();
void o5_walkActorToObject();
+ void o5_oldRoomEffect();
void o6_pushByte();
void o6_pushWord();
@@ -2243,6 +2245,7 @@ void drawMouse(Scumm *s, int x, int y, int color, byte *mask, bool visible);
void drawMouse(Scumm *s, int x, int y, int w, int h, byte *buf, bool visible);
void blit(byte *dst, byte *src, int w, int h);
byte *findResource(uint32 tag, byte *searchin, int index);
+byte *findResourceSmall(uint32 tag, byte *searchin, int index);
byte *findResource(uint32 tag, byte *searchin);
byte *findResourceSmall(uint32 tag, byte *searchin);
void playSfxSound(void *sound, uint32 size, uint rate);
diff --git a/scummvm.cpp b/scummvm.cpp
index 93eb73a3e9..3c4af0fdad 100644
--- a/scummvm.cpp
+++ b/scummvm.cpp
@@ -675,24 +675,38 @@ void Scumm::initRoomSubBlocks() {
dumpResource("entry-", _roomResource, ptr - 8);
#endif
}
-
- ptr = findResourceData(MKID('BOXD'), roomptr);
- if (ptr) {
- int size = getResourceDataSize(ptr);
- createResource(rtMatrix, 2, size);
- roomptr = getResourceAddress(rtRoom, _roomResource);
- ptr = findResourceData(MKID('BOXD'), roomptr);
- memcpy(getResourceAddress(rtMatrix, 2), ptr, size);
- }
- ptr = findResourceData(MKID('BOXM'), roomptr);
- if (ptr) {
- int size = getResourceDataSize(ptr);
- createResource(rtMatrix, 1, size);
- roomptr = getResourceAddress(rtRoom, _roomResource);
- ptr = findResourceData(MKID('BOXM'), roomptr);
- memcpy(getResourceAddress(rtMatrix, 1), ptr, size);
- }
+ if(_features & GF_SMALL_HEADER) {
+ ptr = findResourceData(MKID('BOXD'), roomptr);
+ if (ptr) {
+ byte numOfBoxes=*(ptr);
+ int size = numOfBoxes * SIZEOF_BOX+1;
+ createResource(rtMatrix, 2, size);
+ memcpy(getResourceAddress(rtMatrix, 2), ptr, size);
+ ptr += size;
+ size = getResourceDataSize(ptr-size-6) - size;
+ createResource(rtMatrix, 1, size);
+ memcpy(getResourceAddress(rtMatrix, 1), ptr, size);
+ }
+ } else {
+ ptr = findResourceData(MKID('BOXD'), roomptr);
+ if (ptr) {
+ int size = getResourceDataSize(ptr);
+ createResource(rtMatrix, 2, size);
+ roomptr = getResourceAddress(rtRoom, _roomResource);
+ ptr = findResourceData(MKID('BOXD'), roomptr);
+ memcpy(getResourceAddress(rtMatrix, 2), ptr, size);
+ }
+
+ ptr = findResourceData(MKID('BOXM'), roomptr);
+ if (ptr) {
+ int size = getResourceDataSize(ptr);
+ createResource(rtMatrix, 1, size);
+ roomptr = getResourceAddress(rtRoom, _roomResource);
+ ptr = findResourceData(MKID('BOXM'), roomptr);
+ memcpy(getResourceAddress(rtMatrix, 1), ptr, size);
+ }
+ }
ptr = findResourceData(MKID('SCAL'), roomptr);
if (ptr) {
@@ -711,34 +725,58 @@ void Scumm::initRoomSubBlocks() {
memset(_localScriptList, 0, sizeof(_localScriptList));
searchptr = roomptr = getResourceAddress(rtRoom, _roomResource);
- while( (ptr = findResource(MKID('LSCR'), searchptr)) != NULL ) {
- int id;
+ if(_features & GF_SMALL_HEADER) {
+ while( (ptr = findResourceSmall(MKID('LSCR'), searchptr)) != NULL ) {
+ int id;
+ ptr += _resourceHeaderSize; /* skip tag & size */
+ #ifdef DUMP_SCRIPTS
+ do {
+ char buf[32];
+ sprintf(buf,"room-%d-",_roomResource);
+ dumpResource(buf, id, ptr - 6);
+ } while (0);
+ #endif
+ id = ptr[0];
+ _localScriptList[id - _numGlobalScripts] = ptr + 1 - roomptr;
+ searchptr = NULL;
+ }
+ } else {
+ while( (ptr = findResource(MKID('LSCR'), searchptr)) != NULL ) {
+ int id;
- ptr += _resourceHeaderSize; /* skip tag & size */
+ ptr += _resourceHeaderSize; /* skip tag & size */
#ifdef FULL_THROTTLE
- id = READ_LE_UINT16(ptr);
- checkRange(2050, 2000, id, "Invalid local script %d");
- _localScriptList[id - _numGlobalScripts] = ptr + 2 - roomptr;
+ id = READ_LE_UINT16(ptr);
+ checkRange(2050, 2000, id, "Invalid local script %d");
+ _localScriptList[id - _numGlobalScripts] = ptr + 2 - roomptr;
#else
- id = ptr[0];
- _localScriptList[id - _numGlobalScripts] = ptr + 1 - roomptr;
+ id = ptr[0];
+ _localScriptList[id - _numGlobalScripts] = ptr + 1 - roomptr;
#endif
#ifdef DUMP_SCRIPTS
- do {
- char buf[32];
- sprintf(buf,"room-%d-",_roomResource);
- dumpResource(buf, id, ptr - 8);
- } while (0);
+ do {
+ char buf[32];
+ sprintf(buf,"room-%d-",_roomResource);
+ dumpResource(buf, id, ptr - 8);
+ } while (0);
#endif
- searchptr = NULL;
- }
-
+ searchptr = NULL;
+ }
+ }
+
+ if( _features & GF_SMALL_HEADER)
+ ptr = findResourceSmall(MKID('EPAL'), roomptr);
+ else
+ ptr = findResource(MKID('EPAL'), roomptr);
- ptr = findResource(MKID('EPAL'), roomptr);
if (ptr)
_EPAL_offs = ptr - roomptr;
-
- ptr = findResourceData(MKID('CLUT'), roomptr);
+
+ if( _features & GF_SMALL_HEADER)
+ ptr = findResourceSmall(MKID('CLUT'), roomptr);
+ else
+ ptr = findResourceData(MKID('CLUT'), roomptr);
+
if (ptr) {
_CLUT_offs = ptr - roomptr;
setPaletteFromRes();
diff --git a/sdl.cpp b/sdl.cpp
index f1e1c89d0c..d34514863f 100644
--- a/sdl.cpp
+++ b/sdl.cpp
@@ -543,9 +543,10 @@ int main(int argc, char* argv[]) {
sound.initialize(&scumm, &snd_driv);
scumm._gui = &gui;
- scumm.scummMain(argc, argv);
+ scumm.scummMain(argc, argv);
- gui.init(&scumm);
+ if (!(scumm._features & GF_SMALL_HEADER))
+ gui.init(&scumm);
last_time = SDL_GetTicks();
delta = 0;
diff --git a/sound.cpp b/sound.cpp
index ffcb6e6518..b7ff534e3b 100644
--- a/sound.cpp
+++ b/sound.cpp
@@ -89,7 +89,9 @@ void Scumm::processSoundQues() {
}
void Scumm::playSound(int sound) {
- SoundEngine *se = (SoundEngine*)_soundEngine;
+ SoundEngine *se = (SoundEngine*)_soundEngine;
+ if (_gameId == GID_ZAK256) return; /* FIXME */
+
if (se) {
getResourceAddress(rtSound, sound);
se->start_sound(sound);
diff --git a/string.cpp b/string.cpp
index 5ef0857329..2753653214 100644
--- a/string.cpp
+++ b/string.cpp
@@ -29,6 +29,8 @@ int CharsetRenderer::getStringWidth(int arg, byte *text, int pos) {
width = 1;
ptr = _vm->getResourceAddress(rtCharset, _curId) + 29;
+ if(_vm->_features & GF_SMALL_HEADER)
+ ptr-=12;
while ( (chr = text[pos++]) != 0) {
if (chr==0xD)
@@ -57,6 +59,8 @@ int CharsetRenderer::getStringWidth(int arg, byte *text, int pos) {
int set = text[pos] | (text[pos+1]<<8);
pos+=2;
ptr = _vm->getResourceAddress(rtCharset, set) + 29;
+ if(_vm->_features & GF_SMALL_HEADER)
+ ptr-=12;
continue;
}
}
@@ -82,6 +86,8 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) {
byte chr;
ptr = _vm->getResourceAddress(rtCharset, _curId) + 29;
+ if(_vm->_features & GF_SMALL_HEADER)
+ ptr-=12;
while ( (chr=str[pos++]) != 0) {
if (chr=='@')
@@ -114,6 +120,8 @@ void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) {
int set = str[pos] | (str[pos+1]<<8);
pos+=2;
ptr = _vm->getResourceAddress(rtCharset, set) + 29;
+ if(_vm->_features & GF_SMALL_HEADER)
+ ptr-=12;
continue;
}
}
@@ -235,8 +243,11 @@ void Scumm::CHARSET_1() {
_bkColor = 0;
for (i=0; i<4; i++)
- charset._colorMap[i] = _charsetData[charset._curId][i];
-
+ if(_features & GF_SMALL_HEADER)
+ charset._colorMap[i] = _charsetData[charset._curId][i-12];
+ else
+ charset._colorMap[i] = _charsetData[charset._curId][i];
+
if (_keepText) {
charset._strLeft = gdi._mask_left;
charset._strRight = gdi._mask_right;
@@ -311,9 +322,9 @@ newLine:;
charset._top = charset._ypos2;
if (!(_features&GF_AFTER_V6)) {
- if (!_vars[VAR_V5_CHARFLAG]) {
+// if (!_vars[VAR_V5_CHARFLAG]) { /* FIXME */
charset.printChar(c);
- }
+// }
} else {
charset.printChar(c);
}
@@ -354,7 +365,10 @@ newLine:;
charset._curId = *buffer++;
buffer += 2;
for (i=0; i<4; i++)
- charset._colorMap[i] = _charsetData[charset._curId][i];
+ if(_features & GF_SMALL_HEADER)
+ charset._colorMap[i] = _charsetData[charset._curId][i-12];
+ else
+ charset._colorMap[i] = _charsetData[charset._curId][i];
charset._ypos2 -= getResourceAddress(rtCharset,charset._curId)[30] - oldy;
} else if (c==12) {
int color;
@@ -402,9 +416,14 @@ void Scumm::drawString(int a) {
charsetptr = getResourceAddress(rtCharset, charset._curId);
assert(charsetptr);
charsetptr += 29;
+ if(_features & GF_SMALL_HEADER)
+ charsetptr-=12;
for(i=0; i<4; i++)
- charset._colorMap[i] = _charsetData[charset._curId][i];
+ if(_features & GF_SMALL_HEADER)
+ charset._colorMap[i] = _charsetData[charset._curId][i-12];
+ else
+ charset._colorMap[i] = _charsetData[charset._curId][i];
byte1 = charsetptr[1];
@@ -485,6 +504,9 @@ byte *Scumm::addMessageToStack(byte *msg) {
if (ptr==NULL)
error("Message stack not allocated");
+ if (msg==NULL)
+ error("Bad message in addMessageToStack");
+
while ( (chr=*msg++) != 0) {
if (num > 500)
error("Message stack overflow");
@@ -623,14 +645,20 @@ void Scumm::unkAddMsgToStack5(int var) {
void Scumm::initCharset(int charsetno) {
int i;
- if (!getResourceAddress(rtCharset, charsetno))
- loadCharset(charsetno);
+ if (_features & GF_SMALL_HEADER)
+ loadCharset(charsetno);
+ else
+ if (!getResourceAddress(rtCharset, charsetno))
+ loadCharset(charsetno);
string[0].t_charset = charsetno;
string[1].t_charset = charsetno;
for (i=0; i<0x10; i++)
- charset._colorMap[i] = _charsetData[charsetno][i];
+ if(_features & GF_SMALL_HEADER)
+ charset._colorMap[i] = _charsetData[charset._curId][i-12];
+ else
+ charset._colorMap[i] = _charsetData[charset._curId][i];
}
void CharsetRenderer::printChar(int chr) {
@@ -644,6 +672,9 @@ void CharsetRenderer::printChar(int chr) {
if (chr=='@')
return;
+ if (_vm->_features & GF_SMALL_HEADER)
+ _ptr -= 12;
+
_ptr = _vm->getResourceAddress(rtCharset, _curId) + 29;
_bpp = _unk2 = *_ptr;
diff --git a/verbs.cpp b/verbs.cpp
index 95af65a705..339d01fe58 100644
--- a/verbs.cpp
+++ b/verbs.cpp
@@ -184,15 +184,27 @@ void Scumm::drawVerbBitmap(int vrb, int x, int y) {
ydiff = y - vs->topline;
obim = getResourceAddress(rtVerb, vrb);
-
- imhd = (ImageHeader*)findResourceData(MKID('IMHD'), obim);
- imgw = READ_LE_UINT16(&imhd->width) >> 3;
- imgh = READ_LE_UINT16(&imhd->height) >> 3;
+ if (_features & GF_SMALL_HEADER) {
+ ObjectData *od;
+ int index, obj;
+ obj = READ_LE_UINT16(obim+6);
+ index = getObjectIndex(obj);
+ if(index==-1)
+ return;
+ od = &_objs[index];
+
+ imgw = od->width>>3;
+ imgh = od->height>>3;
+ imptr = obim+8;
+ } else {
+ imhd = (ImageHeader*)findResourceData(MKID('IMHD'), obim);
+ imgw = READ_LE_UINT16(&imhd->width) >> 3;
+ imgh = READ_LE_UINT16(&imhd->height) >> 3;
- imptr = findResource(MKID('IM01'), obim);
- if (!imptr)
- error("No image for verb %d", vrb);
-
+ imptr = findResource(MKID('IM01'), obim);
+ if (!imptr)
+ error("No image for verb %d", vrb);
+ }
for (i=0; i<imgw; i++) {
tmp = xstrip + i;
if ((uint)tmp < 40)
@@ -250,7 +262,10 @@ void Scumm::setVerbObject(uint room, uint object, uint verb) {
error("Can't grab verb image from flobject");
findObjectInRoom(&foir, foImageHeader, object, room);
- size = READ_BE_UINT32_UNALIGNED(foir.obim+4);
+ if(_features & GF_SMALL_HEADER)
+ size = READ_LE_UINT32(foir.obim);
+ else
+ size = READ_BE_UINT32_UNALIGNED(foir.obim+4);
createResource(rtVerb, verb, size);
obimptr = getResourceAddress(rtRoom, room) - foir.roomptr + foir.obim;
memcpy(getResourceAddress(rtVerb, verb), obimptr, size);