diff options
-rw-r--r-- | actor.cpp | 7 | ||||
-rw-r--r-- | boxes.cpp | 8 | ||||
-rw-r--r-- | costume.cpp | 4 | ||||
-rw-r--r-- | gfx.cpp | 203 | ||||
-rw-r--r-- | object.cpp | 69 | ||||
-rw-r--r-- | resource.cpp | 197 | ||||
-rw-r--r-- | script.cpp | 22 | ||||
-rw-r--r-- | scumm.h | 21 | ||||
-rw-r--r-- | scummvm.cpp | 104 | ||||
-rw-r--r-- | sound/imuse.cpp | 2 |
10 files changed, 584 insertions, 53 deletions
@@ -449,6 +449,7 @@ int Scumm::getActorXYPos(Actor *a) { } AdjustBoxResult Scumm::adjustXYToBeInBox(Actor *a, int x, int y, int pathfrom) { + // Yazoo: need to recheck with Loom for the class data flags (0x400000) AdjustBoxResult abr,tmp; uint threshold; uint best; @@ -461,13 +462,17 @@ AdjustBoxResult Scumm::adjustXYToBeInBox(Actor *a, int x, int y, int pathfrom) { if (a && a->ignoreBoxes==0) { threshold = 30; + + if ((_features & GF_SMALL_HEADER) && (_classData[a->number] & 0x200000)) + return abr; while(1) { box = getNumBoxes() - 1; best = (uint)0xFFFF; b = 0; - do { + if(((_features & GF_SMALL_HEADER) && box) || !(_features & GF_SMALL_HEADER)) + do { flags = getBoxFlags(box); if (flags&0x80 && (!(flags&0x20) || getClass(a->number, 0x1F)) ) continue; @@ -43,7 +43,13 @@ byte Scumm::getNumBoxes() { } Box *Scumm::getBoxBaseAddr(int box) { - byte *ptr = getResourceAddress(rtMatrix, 2); + byte *ptr; + + if(_features & GF_SMALL_HEADER) + ptr = getResourceAddress(rtMatrix, 1); + else + ptr = getResourceAddress(rtMatrix, 2); + checkRange(ptr[0]-1, 0, box, "Illegal box %d"); return (Box*)(ptr + box*SIZEOF_BOX + 2); } diff --git a/costume.cpp b/costume.cpp index c0979d3210..23d677ec0b 100644 --- a/costume.cpp +++ b/costume.cpp @@ -674,7 +674,7 @@ void CostumeRenderer::loadCostume(int id) { if (_vm->_features&GF_AFTER_V6) { _ptr += 8; - } else { + } else if(!(_features&GF_SMALL_HEADER)) { _ptr += 2; } @@ -753,7 +753,7 @@ void Scumm::loadCostume(LoadedCostume *lc, int costume) { if (_features&GF_AFTER_V6) { lc->_ptr += 8; - } else { + } else if (!(_features&GF_SMALL_HEADER)) { lc->_ptr += 2; } @@ -337,10 +337,12 @@ void Scumm::initBGBuffers() { room = getResourceAddress(rtRoom, _roomResource); - ptr = findResource(MKID('RMIH'), findResource(MKID('RMIM'), room)); - - gdi._numZBuffer = READ_LE_UINT16(ptr+8) + 1; - + if(_features & GF_SMALL_HEADER) { + gdi._numZBuffer = 1; + } else { + ptr = findResource(MKID('RMIH'), findResource(MKID('RMIM'), room)); + gdi._numZBuffer = READ_LE_UINT16(ptr+8) + 1; + } assert(gdi._numZBuffer>=1 && gdi._numZBuffer<=4); itemsize = (_scrHeight + 4) * 40; @@ -357,7 +359,17 @@ void Scumm::setPaletteFromPtr(byte *ptr) { byte *dest, *epal; int numcolor; - numcolor = getResourceDataSize(ptr) / 3; + if( _features & GF_SMALL_HEADER ) { + if (_features & GF_OLD256) { + numcolor = 256; + ptr+=2; + } else { + numcolor = READ_LE_UINT16(ptr+6) / 3; + ptr+=8; + } + } else { + numcolor = getResourceDataSize(ptr) / 3; + } checkRange(256, 0, numcolor, "Too many colors (%d) in Palette"); @@ -531,6 +543,7 @@ void Scumm::unkVirtScreen4(int a) { // setDirtyRange(0, 0, vs->height); // updateDirtyScreen(0); /* XXX: EGA_proc4(0); */ + warning("EGA_proc4"); /* FIXME */ break; case 134: unkScreenEffect5(0); @@ -611,10 +624,16 @@ void Gdi::drawBitmap(byte *ptr, VirtScreen *vs, int x, int y, int h, int stripnr byte twobufs; int numzbuf; int sx; - + + if(_vm->_features & GF_16COLOR) /* FIXME */ + return; + CHECK_HEAP - smap_ptr = findResource(MKID('SMAP'), ptr); + if(_vm->_features & GF_SMALL_HEADER) + smap_ptr = _smap_ptr = ptr; + else + smap_ptr = findResource(MKID('SMAP'), ptr); assert(smap_ptr); @@ -636,7 +655,10 @@ void Gdi::drawBitmap(byte *ptr, VirtScreen *vs, int x, int y, int h, int stripnr _numLinesToProcess = h; do { - _smap_ptr = smap_ptr + READ_LE_UINT32(smap_ptr + stripnr*4 + 8); + if(_vm->_features & GF_SMALL_HEADER) + _smap_ptr = smap_ptr + READ_LE_UINT32(smap_ptr + stripnr*4 + 4); + else + _smap_ptr = smap_ptr + READ_LE_UINT32(smap_ptr + stripnr*4 + 8); CHECK_HEAP @@ -723,6 +745,23 @@ void Gdi::decompressBitmap() { case 1: unkDecode7(); break; + + case 2: + unkDecode8(); /* Ender - Zak256/Indy256 */ + break; + + case 3: + unkDecode9(); /* Ender - Zak256/Indy256 */ + break; + + case 4: + unkDecode10(); /* Ender - Zak256/Indy256 */ + break; + + case 7: + unkDecode11(); /* Ender - Zak256/Indy256 */ + break; + case 14: case 15: case 16: case 17: case 18: _decomp_shr = code - 10; _decomp_mask = decompress_table[code - 10]; @@ -1207,6 +1246,149 @@ void Gdi::unkDecode7() { } while (--height); } +/* Ender - Zak256/Indy256 decoders */ +#define READ_256BIT \ + if ((mask <<= 1) == 256) {buffer = *src++; mask = 1;} \ + bits = ((buffer & mask) != 0); + +#define NEXT_ROW \ + dst += 320; \ + if (--h == 0) { \ + if (!--_currentX) \ + return; \ + dst -= _vertStripNextInc; \ + h = _numLinesToProcess; \ + } + +void Gdi::unkDecode8() { + byte *src = _smap_ptr; + byte *dst = _bgbak_ptr; + int i; + uint h = _numLinesToProcess; + + _currentX = 8; + for(;;) { + uint run = (*src++)+1; + byte color = *src++; + + do { + *dst = color; + NEXT_ROW + } while (--run); + } +} + +void Gdi::unkDecode9() { /* FIXME: This one doesn't work.. */ + byte *src = _smap_ptr; + byte *dst = _bgbak_ptr; + unsigned char c, bits, color, run; + int x, y, i, z; + uint buffer, mask = 128; + int h = _numLinesToProcess; + x = y = i = z = run = 0; + + while (x < 8) { + c = 0; + for (i = 0; i < 4; i++) {READ_256BIT; c+=(bits<<i);} + /* printf("%d,", c>>2); */ + switch ((c>>2)) { + case 0: + color= 0; + for (i=0; i<4; i++) {READ_256BIT; color+=bits<<i;}// color+=getbit(-1)<<i; + for (i=0; i<((c&3)+2); i++) { + *dst = (run * 16 + color); + NEXT_ROW + } + break; + + case 1: + for (i=0; i<((c&3)+1); i++) { + color = 0; + for (z=0; z < 4; z++) {READ_256BIT; color+=bits<<i;} + *dst = (run * 16 + color); + NEXT_ROW // y++; if (y>=height) {y=0; x++;}} + } + break; + + case 2: + run = 0; + for (i = 0; i < 4; i++) {READ_256BIT; c+=run<<i;} + break; + } + } + /* printf("\n"); */ +} + +void Gdi::unkDecode10() { + byte *src = _smap_ptr; + byte *dst = _bgbak_ptr; + int i; + unsigned char local_palette[256], numcolors = *src++; + uint h = _numLinesToProcess; + + for (i=0; i < numcolors; i++) + local_palette[i] = *src++; + + _currentX = 8; + + for(;;) { + byte color = *src++; + if (color < numcolors) { + *dst = local_palette[color]; + NEXT_ROW + } else { + uint run = color - numcolors + 1; + color = *src++; + do { + *dst = color; + NEXT_ROW + } while (--run); + } + } +} + + +void Gdi::unkDecode11() { + byte *src = _smap_ptr; + byte *dst = _bgbak_ptr; + int bits, i; + uint buffer, mask = 128; + unsigned char inc = 1, color = *src++; + + _currentX = 8; + do { + _tempNumLines = _numLinesToProcess; + do { + *dst = color; + dst+=320; + for (i=0; i<3; i++) {READ_256BIT if (!bits) break;} + switch (i) { + case 1: + inc=-inc; + color-=inc; + break; + + case 2: + color-=inc; + break; + + case 3: + color = 0; + inc = 1; + for (i=0; i<8; i++) { + READ_256BIT + color+= bits<<i; + } + break; + } + } while (--_tempNumLines); + dst -= _vertStripNextInc; + } while (--_currentX); +} + + +#undef NEXT_ROW +#undef READ_256BIT #undef READ_BIT #undef FILL_BITS @@ -1893,7 +2075,10 @@ void Scumm::setCursorHotspot2(int x,int y) { byte Scumm::isMaskActiveAt(int l, int t, int r, int b, byte *mem) { int w,h,i; - + + if(_features & GF_SMALL_HEADER) /* FIXME */ + return false; + l>>=3; if (l<0) l = 0; if (t<0) t = 0; diff --git a/object.cpp b/object.cpp index 46acf689f2..71cffd06a6 100644 --- a/object.cpp +++ b/object.cpp @@ -401,8 +401,75 @@ void Scumm::loadRoomObjects() { CHECK_HEAP } +void Scumm::loadRoomObjectsSmall() { + int i,j; + ObjectData *od; + byte *ptr; + uint16 obim_id; + byte *room,*searchptr; + ImageHeader *imhd; + RoomHeader *roomhdr; + + CodeHeader *cdhd; + + CHECK_HEAP + + room = getResourceAddress(rtRoom, _roomResource); + roomhdr = (RoomHeader*)findResourceData(MKID('RMHD'), room); + + _numObjectsInRoom = READ_LE_UINT16(&roomhdr->numObjects); + + if (_numObjectsInRoom == 0) + return; + + if (_numObjectsInRoom > _numLocalObjects) + error("More than %d objects in room %d", _numLocalObjects, _roomResource); + + od = &_objs[1]; + searchptr = room; + for (i=0; i<_numObjectsInRoom; i++,od++) { + ptr = findResourceSmall(MKID('OBCD'), searchptr); + if (ptr==NULL) + error("Room %d missing object code block(s)", _roomResource); + + od->offs_obcd_to_room = ptr - room; + od->obj_nr = READ_LE_UINT16(ptr+6); + +#ifdef DUMP_SCRIPTS + do { + char buf[32]; + sprintf(buf,"roomobj-%d-",_roomResource); + dumpResource(buf, od->obj_nr, ptr); + } while (0); +#endif + searchptr = NULL; + } + + searchptr = room; + for (i=0; i<_numObjectsInRoom; i++) { + ptr = findResourceSmall(MKID('OBIM'), searchptr); + if (ptr==NULL) + error("Room %d missing image blocks(s)", _roomResource); + + obim_id = READ_LE_UINT16(ptr+6); + + for(j=1; j<=_numObjectsInRoom; j++) { + if (_objs[j].obj_nr==obim_id) + _objs[j].offs_obim_to_room = ptr - room; + } + searchptr = NULL; + } + + od = &_objs[1]; + for (i=1; i<=_numObjectsInRoom; i++,od++) { + setupRoomObject(od, room); + } + + CHECK_HEAP +} + void Scumm::setupRoomObject(ObjectData *od, byte *room) { - byte *obcd; + byte *obcd; CodeHeader *cdhd; ImageHeader *imhd; diff --git a/resource.cpp b/resource.cpp index d053f34464..c08b5f90fc 100644 --- a/resource.cpp +++ b/resource.cpp @@ -95,7 +95,7 @@ void Scumm::openRoom(int room) { /* Delete the currently loaded room offsets */ void Scumm::deleteRoomOffsets() { - if (!_dynamicRoomOffsets) + if (!(_features & GF_SMALL_HEADER) && !_dynamicRoomOffsets) return; for (int i=0; i<_maxRooms; i++) { @@ -284,6 +284,127 @@ void Scumm::readIndexFile() { openRoom(-1); } +void Scumm::readIndexFileSmall() { + uint16 blocktype; + uint32 itemsize; + int numblock = 0; + int num, i; + + debug(9, "readIndexFile()"); + + openRoom(-1); + openRoom(0); + + if (!(_features & GF_AFTER_V6)) { + while (!fileEof(_fileHandle)) { + itemsize = fileReadDwordLE(); + blocktype = fileReadWordLE(); + if (fileReadFailed(_fileHandle)) + break; + + switch(blocktype) { + case 0x4E52: + fileReadWordLE(); + break; + case 0x5230: + _numRooms = fileReadWordLE(); + break; + case 0x5330: + _numScripts = fileReadWordLE(); + break; + case 0x4E30: + _numSounds = fileReadWordLE(); + break; + case 0x4330: + _numCostumes = fileReadWordLE(); + break; + case 0x4F30: + _numGlobalObjects = fileReadWordLE(); + break; + } + fileSeek(_fileHandle, itemsize-8,SEEK_CUR); + } + clearFileReadFailed(_fileHandle); + fileSeek(_fileHandle, 0, SEEK_SET); + } + + /* I'm not sure for those values yet, they will have to be rechecked */ + + _numVariables = 800; /* 800 */ + _numBitVariables = 4096; /* 2048 */ + _numLocalObjects = 200; /* 200 */ + _numArray = 50; + _numVerbs = 100; + _numNewNames = 0; + _objectRoomTable = NULL; + _numCharsets = 9; /* 9 */ + _numInventory = 80; /* 80 */ + _numGlobalScripts = 200; + + _shadowPaletteSize = 256; + _shadowPalette = (byte*)alloc(_shadowPaletteSize); // stupid for now. Need to be removed later + _numFlObject = 50; + + allocateArrays(); + + while (1) { + itemsize = fileReadDwordLE(); + + if (fileReadFailed(_fileHandle)) + break; + + blocktype = fileReadWordLE(); + + numblock++; + + switch(blocktype) { + + case 0x4E52: + fileSeek(_fileHandle, itemsize-6,SEEK_CUR); + break; + + case 0x5230: + readResTypeList(rtRoom,MKID('ROOM'),"room"); + break; + + case 0x5330: + readResTypeList(rtScript,MKID('SCRP'),"script"); + break; + + case 0x4E30: + readResTypeList(rtSound,MKID('SOUN'),"sound"); + break; + + case 0x4330: + readResTypeList(rtCostume,MKID('COST'),"costume"); + break; + + case 0x4F30: + num = fileReadWordLE(); + assert(num == _numGlobalObjects); + for (i=0; i<num; i++) { /* not too sure about all that */ + _classData[i] = fileReadWordLE(); //+ fileReadByte(); + fileReadByte(); + _objectOwnerTable[i] = fileReadByte(); + _objectStateTable[i] = _objectOwnerTable[i]>>OF_STATE_SHL; + _objectOwnerTable[i] &= OF_OWNER_MASK; + } + +#if defined(SCUMM_BIG_ENDIAN) + for (i=0; i<num; i++) { + _classData[i] = FROM_LE_32(_classData[i]); + } +#endif + break; + + default: + error("Bad ID %c%c found in directory!", blocktype&0xFF, blocktype>>8); + return; + } + } + + openRoom(-1); +} void Scumm::readArrayFromIndexFile() { int num; @@ -474,7 +595,7 @@ int Scumm::readSoundResource(int type, int index) { fileSeek(_fileHandle, -8, SEEK_CUR); fileRead(_fileHandle,createResource(type, index, total_size+8), total_size+8); return 1; - } + } #else best_pri = -1; while (pos < total_size) { @@ -658,6 +779,37 @@ StartScan: return f->ptr; } +byte *findResourceSmall(uint32 tag, byte *searchin) { + uint32 size; + static FindResourceState frs; + FindResourceState *f = &frs; /* easier to make it thread safe like this */ + uint16 smallTag; + + smallTag=newTag2Old(tag); + + if (searchin) { + f->size = READ_LE_UINT32(searchin); + f->pos = 6; + f->ptr = searchin+6; + goto StartScan; + } + + do { + size = READ_LE_UINT32(f->ptr); + if ((int32)size <= 0) + return NULL; + + f->pos += size; + f->ptr += size; + +StartScan: + if (f->pos >= f->size) + return NULL; + } while (READ_LE_UINT16(f->ptr+4) != smallTag); + + return f->ptr; +} + byte *findResource(uint32 tag, byte *searchin, int index) { uint32 maxsize,curpos,totalsize,size; @@ -952,3 +1104,44 @@ void Scumm::allocateArrays() { allocResTypeData(rtFlObject, MKID('NONE'),_numFlObject,"flobject", 0); allocResTypeData(rtMatrix, MKID('NONE'),10,"boxes", 0); } + +uint16 newTag2Old(uint32 oldTag) { + switch(oldTag) { + case(MKID('RMHD')): + return(0x4448); + break; + case(MKID('IM00')): + return(0x4D42); + break; + case(MKID('EXCD')): + return(0x5845); + break; + case(MKID('ENCD')): + return(0x4E45); + break; + case(MKID('SCAL')): + return(0x4153); + break; + case(MKID('LSCR')): + return(0x534C); + break; + case(MKID('OBCD')): + return(0x434F); + break; + case(MKID('OBIM')): + return(0x494F); + break; + case(MKID('SMAP')): + return(0x4D42); + break; + case(MKID('CLUT')): + return(0x4150); + break; + case(MKID('BOXD')): + return(0x5842); + break; + default: + return(0); + } +} + diff --git a/script.cpp b/script.cpp index ae41708a25..6bdaa5bd88 100644 --- a/script.cpp +++ b/script.cpp @@ -37,7 +37,10 @@ void Scumm::runScript(int script, int a, int b, int16 *lvarptr) { if (script < _numGlobalScripts) { scriptPtr = getResourceAddress(rtScript, script); - scriptOffs = 8; + if(_features & GF_SMALL_HEADER) + scriptOffs = 6; + else + scriptOffs = 8; scriptType = WIO_GLOBAL; } else { scriptOffs = _localScriptList[script - _numGlobalScripts]; @@ -662,7 +665,7 @@ void Scumm::runVerbCode(int object, int entry, int a, int b, int16 *vars) { slot = getScriptSlot(); offs = getVerbEntrypoint(object, entry); - if (offs==0) + if (offs==0) return; vm.slot[slot].number = object; @@ -700,13 +703,19 @@ int Scumm::getVerbEntrypoint(int obj, int entry) { objptr = getOBCDFromObject(obj); assert(objptr); - verbptr = findResource(MKID('VERB'), objptr); + if(_features & GF_SMALL_HEADER) + verbptr = objptr+19; + else + verbptr = findResource(MKID('VERB'), objptr); + if (verbptr==NULL) error("No verb block in object %d", obj); verboffs = verbptr - objptr; - verbptr += _resourceHeaderSize; + if(!(_features & GF_SMALL_HEADER)) + verbptr += _resourceHeaderSize; + do { if (!*verbptr) return 0; @@ -715,7 +724,10 @@ int Scumm::getVerbEntrypoint(int obj, int entry) { verbptr += 3; } while (1); - return verboffs + READ_LE_UINT16(verbptr+1); + if(_features & GF_SMALL_HEADER) + return READ_LE_UINT16(verbptr+1); + else + return verboffs + READ_LE_UINT16(verbptr+1); } @@ -853,6 +853,10 @@ struct Gdi { void unkDecode5(); void unkDecode6(); void unkDecode7(); + void unkDecode8(); + void unkDecode9(); + void unkDecode10(); + void unkDecode11(); void decompressBitmap(); @@ -897,6 +901,11 @@ enum GameId { GID_INDY4 = 3, GID_MONKEY = 4, GID_SAMNMAX = 5, + GID_MONKEY_EGA = 6, + GID_LOOM256 = 7, + GID_ZAK256 = 8, + GID_INDY3_256 = 9, + GID_LOOM = 10, }; enum GameFeatures { @@ -910,6 +919,12 @@ enum GameFeatures { GF_DRAWOBJ_OTHER_ORDER = 16, GF_DEFAULT = GF_USE_KEY, + + GF_SMALL_HEADER = 32, + GF_SMALL_NAMES = 64, + GF_OLD_BUNDLE = 128, + GF_16COLOR = 256, + GF_OLD256 = 512, }; struct ScummDebugger; @@ -1688,6 +1703,7 @@ struct Scumm { bool isResourceInUse(int type, int i); void initRoomSubBlocks(); void loadRoomObjects(); + void loadRoomObjectsSmall(); void setPaletteFromRes(); void initCycl(byte *ptr); @@ -1897,7 +1913,8 @@ struct Scumm { void readArrayFromIndexFile(); void readMAXS(); - void readIndexFile(); + void readIndexFile(); + void readIndexFileSmall(); int readArray(int array, int index, int base); void writeArray(int array, int index, int base, int value); @@ -2227,7 +2244,9 @@ 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 *findResource(uint32 tag, byte *searchin); +byte *findResourceSmall(uint32 tag, byte *searchin); void playSfxSound(void *sound, uint32 size, uint rate); bool isSfxFinished(); void waitForTimer(Scumm *s, int msec_delay); void setShakePos(Scumm *s, int shake_pos); +uint16 newTag2Old(uint32 oldTag); diff --git a/scummvm.cpp b/scummvm.cpp index 551a524d85..93eb73a3e9 100644 --- a/scummvm.cpp +++ b/scummvm.cpp @@ -46,9 +46,14 @@ void Scumm::scummInit() { debug(9, "scummInit"); - _resourceHeaderSize = 8; + if(_features & GF_SMALL_HEADER) + _resourceHeaderSize = 6; + else + _resourceHeaderSize = 8; + + if(!(_features & GF_SMALL_NAMES)) + loadCharset(1); - loadCharset(1); initScreens(0, 16, 320, 144); setShake(0); @@ -167,7 +172,7 @@ void Scumm::initScummVars() { void Scumm::checkRange(int max, int min, int no, const char *str) { if (no < min || no > max) { - error("Value %d is out of bounds (%d,%d) msg %s", no, min,max, str); + error("Value %d is out of bounds (%d,%d) int script(%d) msg %s", no, min,max, vm.slot[_curExecScript].number, str); } } @@ -205,8 +210,11 @@ void Scumm::scummMain(int argc, char **argv) { initGraphics(this, _fullScreen); - readIndexFile(); - + if (_features & GF_SMALL_HEADER) + readIndexFileSmall(); + else + readIndexFile(); + initRandSeeds(); if (_features & GF_NEW_OPCODES) @@ -412,25 +420,46 @@ struct VersionSettings { uint32 features; }; +/* + This is a list of all known SCUMM games. Commented games are not + supported at this time */ + static const VersionSettings version_settings[] = { - {"monkey", "Monkey Island 1", GID_MONKEY, 5, 2, 2, - GF_USE_KEY}, - {"monkey2", "Monkey Island 2: LeChuck's revenge", GID_MONKEY2, 5, 2, 2, - GF_USE_KEY}, - {"atlantis", "Indiana Jones 4 and the Fate of Atlantis", GID_INDY4, 5, 5, 0, - GF_USE_KEY}, - {"playfate", "Indiana Jones 4 and the Fate of Atlantis (Demo)", GID_INDY4, 5, 5, 0, - GF_USE_KEY}, - {"tentacle", "Day Of The Tentacle", GID_TENTACLE, 6, 4, 2, - GF_NEW_OPCODES|GF_AFTER_V6|GF_USE_KEY}, - {"dottdemo", "Day Of The Tentacle (Demo)", GID_TENTACLE, 6, 3, 2, - GF_NEW_OPCODES|GF_AFTER_V6|GF_USE_KEY}, - {"samnmax", "Sam & Max", GID_SAMNMAX, 6, 4, 2, - GF_NEW_OPCODES|GF_AFTER_V6|GF_USE_KEY|GF_DRAWOBJ_OTHER_ORDER}, - {"snmdemo", "Sam & Max (Demo)", GID_SAMNMAX, 6, 3, 0, - GF_NEW_OPCODES|GF_AFTER_V6|GF_USE_KEY}, - {"ft", "Full Throttle", GID_SAMNMAX, 7, 3, 0, - GF_NEW_OPCODES|GF_AFTER_V6|GF_AFTER_V7}, + /* Scumm Version 1 */ +// {"maniac", "Maniac Mansion (C64)", GID_MANIAC64, 1, 0, 0,}, +// {"zak", "Zak McKracken and the Alien Mindbenders (C64)", GID_ZAK64, 1, 0, 0,}, + + /* Scumm Version 2 */ +// {"maniac", "Maniac Mansion", GID_MANIAC, 2, 0, 0,}, +// {"zak", "Zak McKracken and the Alien Mindbenders", GID_ZAK, 2, 0, 0,}, +// {"indy3", "Indiana Jones and the Last Crusade", GID_INDY3, 2, 0, 0,}, + + /* Scumm Version 3 */ + {"indy3", "Indiana Jones and the Last Crusade (256)", GID_INDY3_256, 3, 0, 22, GF_SMALL_HEADER|GF_USE_KEY|GF_SMALL_NAMES|GF_OLD256}, + {"zak256", "Zak McKracken and the Alien Mindbenders (256)",GID_ZAK256, 3, 0, 0, GF_SMALL_HEADER|GF_USE_KEY|GF_SMALL_NAMES|GF_OLD256}, + {"loom", "Loom", GID_LOOM, 3, 5, 40, GF_SMALL_HEADER|GF_USE_KEY|GF_SMALL_NAMES|GF_OLD_BUNDLE|GF_16COLOR}, + + /* Scumm Version 4 */ + {"monkeyEGA", "Monkey Island 1 (EGA)", GID_MONKEY_EGA, 4, 0, 67, GF_SMALL_HEADER|GF_USE_KEY|GF_16COLOR}, // EGA version + + /* Scumm version 5 */ + {"loomcd", "Loom (256 color CD version)", GID_LOOM256, 5, 1, 42, GF_SMALL_HEADER|GF_USE_KEY}, + {"monkey", "Monkey Island 1", GID_MONKEY, 5, 2, 2, GF_USE_KEY}, + {"monkey2", "Monkey Island 2: LeChuck's revenge", GID_MONKEY2, 5, 2, 2, GF_USE_KEY}, + {"atlantis", "Indiana Jones 4 and the Fate of Atlantis", GID_INDY4, 5, 5, 0, GF_USE_KEY}, + {"playfate", "Indiana Jones 4 and the Fate of Atlantis (Demo)", GID_INDY4, 5, 5, 0, GF_USE_KEY}, + + /* Scumm Version 6 */ + {"tentacle", "Day Of The Tentacle", GID_TENTACLE, 6, 4, 2, GF_NEW_OPCODES|GF_AFTER_V6|GF_USE_KEY}, + {"dottdemo", "Day Of The Tentacle (Demo)", GID_TENTACLE, 6, 3, 2, GF_NEW_OPCODES|GF_AFTER_V6|GF_USE_KEY}, + {"samnmax", "Sam & Max", GID_SAMNMAX, 6, 4, 2, GF_NEW_OPCODES|GF_AFTER_V6|GF_USE_KEY|GF_DRAWOBJ_OTHER_ORDER}, + {"snmdemo", "Sam & Max (Demo)", GID_SAMNMAX, 6, 3, 0, GF_NEW_OPCODES|GF_AFTER_V6|GF_USE_KEY}, + + /* Scumm Version 7 */ + {"ft", "Full Throttle", GID_SAMNMAX, 7, 3, 0, GF_NEW_OPCODES|GF_AFTER_V6|GF_AFTER_V7}, + + /* Scumm Version 8 */ +// {"curse", "The Curse of Monkey Island", GID_CMI, 8, 1, 0,}, {NULL,NULL} }; @@ -538,7 +567,10 @@ void Scumm::startScene(int room, Actor *a, int objectNr) { } initRoomSubBlocks(); - loadRoomObjects(); + if(_features & GF_SMALL_HEADER) + loadRoomObjectsSmall(); + else + loadRoomObjects(); #if !defined(FULL_THROTTLE) camera._mode = CM_NORMAL; @@ -623,8 +655,10 @@ void Scumm::initRoomSubBlocks() { _scrWidth = READ_LE_UINT16(&rmhd->width); _scrHeight = READ_LE_UINT16(&rmhd->height); - _IM00_offs = findResource(MKID('IM00'), findResource(MKID('RMIM'), roomptr)) - - roomptr; + if( _features & GF_SMALL_HEADER) + _IM00_offs = findResourceData(MKID('IM00'), roomptr) - roomptr; + else + _IM00_offs = findResource(MKID('IM00'), findResource(MKID('RMIM'), roomptr)) - roomptr; ptr = findResourceData(MKID('EXCD'), roomptr); if (ptr) { @@ -717,8 +751,14 @@ void Scumm::initRoomSubBlocks() { setPalette(0); } } - - initCycl(findResourceData(MKID('CYCL'), roomptr)); + + if( _features & GF_SMALL_HEADER) + ptr = findResourceData(MKID('CYCL'), roomptr); + else + ptr = findResourceData(MKID('CYCL'), roomptr); + + if (ptr) + initCycl(findResourceData(MKID('CYCL'), roomptr)); ptr = findResourceData(MKID('TRNS'), roomptr); if (ptr) @@ -756,7 +796,11 @@ void Scumm::dumpResource(char *tag, int index, byte *ptr) { char buf[256]; FILE *out; - uint32 size = READ_BE_UINT32_UNALIGNED(ptr+4); + uint32 size; + if( _features & GF_SMALL_HEADER ) + size = READ_LE_UINT32(ptr); + else + size = READ_BE_UINT32_UNALIGNED(ptr+4); sprintf(buf, "dumps\\%s%d.dmp", tag,index); @@ -894,7 +938,7 @@ void Scumm::convertKeysToClicks() { Actor *Scumm::derefActorSafe(int id, const char *errmsg) { if (id<1 || id>=NUM_ACTORS) - error("Invalid actor %d in %s", id, errmsg); + error("Invalid actor %d in %s (script %d)", id, errmsg, vm.slot[_curExecScript].number); return derefActor(id); } diff --git a/sound/imuse.cpp b/sound/imuse.cpp index 77edde58c0..54681170c3 100644 --- a/sound/imuse.cpp +++ b/sound/imuse.cpp @@ -181,7 +181,7 @@ bool SoundEngine::start_sound(int sound) { void *mdhd; mdhd = findTag(sound, MDHD_TAG, 0); - if (!mdhd) + if (!mdhd) return false; player = allocate_player(128); |