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:
James Brown 2002-02-12 21:28:07 +00:00
parent f620d138f6
commit 7ee034af88
10 changed files with 467 additions and 144 deletions

View File

@ -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) {

View File

@ -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;

View File

@ -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;

View File

@ -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");
}

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);