diff --git a/boxes.cpp b/boxes.cpp index 72a4c6c9b03..9135ee84980 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 71cffd06a61..1c98b7d8118 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_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; diff --git a/resource.cpp b/resource.cpp index c08b5f90fc5..bfd0c1686ae 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; - 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= 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>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 3bc6e6f69d5..c23f688e4c6 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 84932b1c090..7e76086ced9 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 93eb73a3e98..3c4af0fdad0 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 f1e1c89d0c3..d34514863f8 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 ffcb6e6518b..b7ff534e3bb 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 5ef08573295..27536532143 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 95af65a705f..339d01fe58e 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