mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-12 12:09:15 +00:00
Further LFL additions. Zak256 plays bits of its intro, and LoomCD partially runs (may need
to hit escape a few times, after selecting your difficulty). Still very incomplete and in progress. svn-id: r3568
This commit is contained in:
parent
f620d138f6
commit
7ee034af88
13
boxes.cpp
13
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) {
|
||||
|
131
object.cpp
131
object.cpp
@ -134,27 +134,33 @@ void Scumm::getObjectXYPos(int object) {
|
||||
ImageHeader *imhd;
|
||||
int x,y;
|
||||
AdjustBoxResult abr;
|
||||
if(!(_features & GF_SMALL_HEADER)) {
|
||||
if (_features&GF_AFTER_V6) {
|
||||
state = getState(object)-1;
|
||||
if (state<0)
|
||||
state = 0;
|
||||
|
||||
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 (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;
|
||||
|
164
resource.cpp
164
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;
|
||||
|
||||
fileSeek(_fileHandle, 16, SEEK_SET);
|
||||
if (!(_features & GF_SMALL_HEADER)) {
|
||||
if (!_dynamicRoomOffsets)
|
||||
return;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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();
|
||||
tag = fileReadDword();
|
||||
|
||||
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);
|
||||
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;
|
||||
|
@ -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");
|
||||
}
|
||||
|
3
scumm.h
3
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);
|
||||
|
110
scummvm.cpp
110
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();
|
||||
|
5
sdl.cpp
5
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;
|
||||
|
@ -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);
|
||||
|
49
string.cpp
49
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;
|
||||
|
33
verbs.cpp
33
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);
|
||||
|
Loading…
Reference in New Issue
Block a user