diff options
Diffstat (limited to 'scumm')
-rw-r--r-- | scumm/gfx.cpp | 148 | ||||
-rw-r--r-- | scumm/resource.cpp | 98 | ||||
-rw-r--r-- | scumm/saveload.cpp | 2 | ||||
-rw-r--r-- | scumm/script_v1.cpp | 4 | ||||
-rw-r--r-- | scumm/script_v2.cpp | 2 | ||||
-rw-r--r-- | scumm/scumm.h | 4 | ||||
-rw-r--r-- | scumm/scummvm.cpp | 141 |
7 files changed, 209 insertions, 190 deletions
diff --git a/scumm/gfx.cpp b/scumm/gfx.cpp index cda2598c70..7866c2dfd8 100644 --- a/scumm/gfx.cpp +++ b/scumm/gfx.cpp @@ -2370,6 +2370,88 @@ void Scumm::setCameraAtEx(int at) } } +void Scumm::palManipulateInit(int start, int end, int d, int time, int e) +{ + // TODO - correctly implement this function (see also bug #558245) + // + // There are two known places (both in FOA) where this function is being + // called. The fist is during the FOA extro, to change the color to match + // the sinking sun. The following three calls (with some pauses between them) + // are issued: + // + // palManipulateInit(16, 190, 32, 180, 1) + // palManipulateInit(16, 190, 32, 1, 1) + // palManipulateInit(16, 190, 32, 800, 1) + // + // The second place is in the Inner Sanctum after you used the stone discs, + // here it is used to give the scene a "lava glow". + // + // palManipulateInit(32, 65, 46, 20, 1): not implemented! + // + // The first two parameters seem to specify a palette range (as the colors + // from 16 to 190 are the ones that make up water & sky). + // + // Maybe the change has to be done over a period of time, possibly specified + // by the second last parameter - between call 1 and 2, about 17-18 seconds + // seem to pass (well using get_msecs, I measured 17155 ms, 17613 ms, 17815 ms). + // + // No clue about the third and fifth parameter right now, they just always + // are 32 and 1 - possibly finding another example of this function being + // used would help a lot. Also, I can't currently compare it with the original, + // doing that (and possibly, taking screenshots of it for analysis!) would + // help a lot. + + warning("palManipulateInit(%d, %d, %d, %d, %d): not implemented", start, end, d, time, e); + + // FIXME - is this right? + // It seems we already have had this "palManipulate" and "moveMemInPalRes" + // functions, only they were never used (somebody disassembled them and + // didn't disassmble the functions using them?). + // + // I + _palManipStart = start; + _palManipEnd = end; + //_palManipCounter = ? + + { + int redScale = 0xFF; + int greenScale = 0xFF - d; + int blueScale = 0xFF - d; + byte *cptr; + byte *cur; + int num; + int color; + + cptr = _currentPalette + start * 3; + cur = _currentPalette + start * 3; + num = end - start + 1; + + do { + color = *cptr++; + if (redScale != 0xFF) + color = color * redScale / 0xFF; + if (color > 255) + color = 255; + *cur++ = color; + + color = *cptr++; + if (greenScale != 0xFF) + color = color * greenScale / 0xFF; + if (color > 255) + color = 255; + *cur++ = color; + + color = *cptr++; + if (blueScale != 0xFF) + color = color * blueScale / 0xFF; + if (color > 255) + color = 255; + *cur++ = color; + } while (--num); + setDirtyColors(start, end); + } +} + void Scumm::palManipulate() { byte *srcptr, *destptr; @@ -2378,8 +2460,12 @@ void Scumm::palManipulate() if (!_palManipCounter) return; + srcptr = getResourceAddress(rtTemp, 4) + _palManipStart * 6; destptr = getResourceAddress(rtTemp, 5) + _palManipStart * 6; + if (!srcptr || !destptr) + return; + pal = _currentPalette + _palManipStart * 3; i = _palManipStart; @@ -2402,12 +2488,72 @@ void Scumm::palManipulate() i++; } setDirtyColors(_palManipStart, _palManipEnd); - if (!--_palManipCounter) { + _palManipCounter--; + if (!_palManipCounter) { nukeResource(rtTemp, 4); nukeResource(rtTemp, 5); } } +void Scumm::unkRoomFunc3(int unk1, int unk2, int rfact, int gfact, int bfact) +{ + byte *pal = _currentPalette; + byte *table = _shadowPalette; + int i; + + warning("unkRoomFunc3(%d,%d,%d,%d,%d): not fully implemented", unk1, unk2, rfact, gfact, bfact); + + // TODO - correctly implement this function (see also patch #588501) + // + // Some "typical" examples of how this function is being invoked in real life: + // + // 1) + // unkRoomFunc3(16, 255, 200, 200, 200) + // + // FOA: Sets up the colors for the boat and submarine shadows in the + // diving scene. Are the shadows too light? Maybe unk1 is used to + // darken the colors? + // + // 2) + // unkRoomFunc3(0, 255, 700, 700, 700) + // + // FOA: Sets up the colors for the subway car headlight when it first + // goes on. This seems to work ok. + // + // 3) + // unkRoomFunc3(160, 191, 300, 300, 300) + // unkRoomFunc3(160, 191, 289, 289, 289) + // ... + // unkRoomFunc3(160, 191, 14, 14, 14) + // unkRoomFunc3(160, 191, 3, 3, 3) + // + // 4) + // FOA: Sets up the colors for the subway car headlight for the later + // half of the trip, where it fades out. This currently doesn't work + // at all. The colors are too dark to be brightened. At first I thought + // unk1 and unk2 were used to tell which color interval to manipulate, + // but as far as I can tell the colors 160-191 aren't used at all to + // draw the light, that can't be it. Apparently unk1 and/or unk2 are + // used to brighten the colors. + // + // 5) + // unkRoomFunc3(16,255,500,500,500) + // + // FOA: Used in the Inner Sanctum after you activated the machine using the + // stone discs (briefly before the Nazis arrive). No idea at all if it is + // right here; also note that palManipulateInit() is called at the same time. + // + // + + for (i = 0; i <= 255; i++) { + int r = (int) (*pal++ * rfact) >> 8; + int g = (int) (*pal++ * gfact) >> 8; + int b = (int) (*pal++ * bfact) >> 8; + + *table++ = remapPaletteColor(r, g, b, (uint) -1); + } +} + void Scumm::swapPalColors(int a, int b) { byte *ap, *bp; diff --git a/scumm/resource.cpp b/scumm/resource.cpp index 318bcce181..1a91504396 100644 --- a/scumm/resource.cpp +++ b/scumm/resource.cpp @@ -470,8 +470,8 @@ void Scumm::loadCharset(int no) assert(no < (int)sizeof(_charsetData) / 16); checkRange(_maxCharsets - 1, 1, no, "Loading illegal charset %d"); -// ensureResourceLoaded(6, no); - ptr = getResourceAddress(6, no); +// ensureResourceLoaded(rtCharset, no); + ptr = getResourceAddress(rtCharset, no); for (i = 0; i < 15; i++) { _charsetData[no][i + 1] = ptr[i + 14]; @@ -537,54 +537,52 @@ int Scumm::loadResource(int type, int idx) return 0; } - do { - for (i = 0; i < 5; i++) { - openRoom(roomNr); - - fileSeek(_fileHandle, fileOffs + _fileOffset, SEEK_SET); - - if (_features & GF_OLD_BUNDLE) { - size = fileReadWordLE(); - } else 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, idx); - } + for (i = 0; i < 5; i++) { + openRoom(roomNr); - tag = fileReadDword(); + fileSeek(_fileHandle, fileOffs + _fileOffset, SEEK_SET); - if (tag != res.tags[type]) { - error("%s %d not in room %d at %d+%d", res.name[type], type, roomNr, _fileOffset, fileOffs); - } + if (_features & GF_OLD_BUNDLE) { + size = fileReadWordLE(); + } else 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, idx); + } - size = fileReadDwordBE(); - fileSeek(_fileHandle, -8, SEEK_CUR); + tag = fileReadDword(); + + if (tag != res.tags[type]) { + error("%s %d not in room %d at %d+%d", res.name[type], type, roomNr, _fileOffset, fileOffs); } - fileRead(_fileHandle, createResource(type, idx, size), size); - /* dump the resource */ + size = fileReadDwordBE(); + fileSeek(_fileHandle, -8, SEEK_CUR); + } + fileRead(_fileHandle, createResource(type, idx, size), size); + + /* dump the resource */ #ifdef DUMP_SCRIPTS - if (type == rtScript) { - dumpResource("script-", idx, getResourceAddress(rtScript, idx)); - } + if (type == rtScript) { + dumpResource("script-", idx, getResourceAddress(rtScript, idx)); + } #endif - if (!fileReadFailed(_fileHandle)) { - return 1; - } - - nukeResource(type, idx); + if (!fileReadFailed(_fileHandle)) { + return 1; } - error("Cannot read resource"); - } while (1); + nukeResource(type, idx); + } + + error("Cannot read resource"); } int Scumm::readSoundResource(int type, int idx) @@ -763,10 +761,9 @@ byte *Scumm::getResourceAddress(int type, int idx) { byte *ptr; - CHECK_HEAP validateResource("getResourceAddress", type, idx); if (!res.address[type]) { - debug(9, "getResourceAddress(%s,%d) == NULL", resTypeFromId(type), idx); + debug(1, "getResourceAddress(%s,%d), res.address[type] == NULL", resTypeFromId(type), idx); return NULL; } @@ -774,9 +771,8 @@ byte *Scumm::getResourceAddress(int type, int idx) ensureResourceLoaded(type, idx); } - if (!(ptr = (byte *)res.address[type][idx])) { - debug(9, "getResourceAddress(%s,%d) == NULL", resTypeFromId(type), idx); + debug(1, "getResourceAddress(%s,%d) == NULL", resTypeFromId(type), idx); return NULL; } @@ -857,9 +853,8 @@ void Scumm::nukeResource(int type, int idx) { byte *ptr; - CHECK_HEAP if (!res.address[type]) - return; + return; assert(idx >= 0 && idx < res.num[type]); @@ -874,17 +869,14 @@ void Scumm::nukeResource(int type, int idx) byte *Scumm::findResourceData(uint32 tag, byte *ptr) { - if (_features & GF_SMALL_HEADER) { + if (_features & GF_SMALL_HEADER) ptr = findResourceSmall(tag, ptr, 0); - if (ptr == NULL) - return NULL; - return ptr + 6; - } + else + ptr = findResource(tag, ptr, 0); - ptr = findResource(tag, ptr, 0); if (ptr == NULL) return NULL; - return ptr + 8; + return ptr + _resourceHeaderSize; } int Scumm::getResourceDataSize(byte *ptr) diff --git a/scumm/saveload.cpp b/scumm/saveload.cpp index 6ac7bdd0df..839808120a 100644 --- a/scumm/saveload.cpp +++ b/scumm/saveload.cpp @@ -337,6 +337,7 @@ void Scumm::saveOrLoad(Serializer *s) MKLINE(Scumm, _EXCD_offs, sleUint32), MKLINE(Scumm, _IM00_offs, sleUint32), MKLINE(Scumm, _CLUT_offs, sleUint32), + /* XXX Remove _EPAL_offs next time format changes */ MKLINE(Scumm, _EPAL_offs, sleUint32), MKLINE(Scumm, _PALS_offs, sleUint32), MKLINE(Scumm, _curPalIndex, sleByte), @@ -441,6 +442,7 @@ void Scumm::saveOrLoad(Serializer *s) MKLINE(Scumm, _EXCD_offs, sleUint32), MKLINE(Scumm, _IM00_offs, sleUint32), MKLINE(Scumm, _CLUT_offs, sleUint32), + /* XXX Remove _EPAL_offs next time format changes */ MKLINE(Scumm, _EPAL_offs, sleUint32), MKLINE(Scumm, _PALS_offs, sleUint32), MKLINE(Scumm, _curPalIndex, sleByte), diff --git a/scumm/script_v1.cpp b/scumm/script_v1.cpp index 3fd4f6f3cc..106923aca9 100644 --- a/scumm/script_v1.cpp +++ b/scumm/script_v1.cpp @@ -1899,6 +1899,7 @@ void Scumm::o5_roomOps() } checkRange(256, 0, a, "o5_roomOps: 2: Illegal room color slot (%d)"); _currentPalette[a] = b; +printf("palette change, %d -> %d\n", a, b); _fullRedraw = 1; } else { error("room-color is no longer a valid command"); @@ -1919,6 +1920,7 @@ void Scumm::o5_roomOps() b = getVarOrDirectWord(0x40); } checkRange(256, 0, a, "o5_roomOps: 2: Illegal room color slot (%d)"); +printf("shadow palette change, %d -> %d\n", a, b); _shadowPalette[b] = a; setDirtyColors(b, b); } else { @@ -2049,7 +2051,7 @@ void Scumm::o5_roomOps() c = getVarOrDirectByte(0x40); _opcode = fetchScriptByte(); d = getVarOrDirectByte(0x80); - palManipulate(b, c, a, d, 1); + palManipulateInit(b, c, a, d, 1); break; case 16: diff --git a/scumm/script_v2.cpp b/scumm/script_v2.cpp index cde491405d..9e2b8c52ca 100644 --- a/scumm/script_v2.cpp +++ b/scumm/script_v2.cpp @@ -1878,7 +1878,7 @@ void Scumm::o6_roomOps() c = pop(); b = pop(); a = pop(); - palManipulate(a, b, c, d, 1); + palManipulateInit(a, b, c, d, 1); break; case 187: /* color cycle delay */ diff --git a/scumm/scumm.h b/scumm/scumm.h index 0b0dfcf590..b4c01e06ff 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -461,8 +461,6 @@ public: byte _numObjectsInRoom; int8 _userPut; int _resourceHeaderSize; - void unkRoomFunc3(int a, int b, int c, int d, int e); - void palManipulate(int a, int b, int c, int d, int e); void setScaleItem(int slot, int a, int b, int c, int d); void clearClickedStatus(); void startManiac(); @@ -796,7 +794,9 @@ public: void swapPalColors(int a, int b); void cyclePalette(); void stopCycle(int i); + void palManipulateInit(int a, int b, int c, int d, int e); void palManipulate(); + void unkRoomFunc3(int a, int b, int c, int d, int e); int remapPaletteColor(int r, int g, int b, uint threshold); void moveMemInPalRes(int start, int end, byte direction); void setupShadowPalette(int slot, int rfact, int gfact, int bfact, int from, int to); diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp index bb6756d5d4..b41bb43b65 100644 --- a/scumm/scummvm.cpp +++ b/scumm/scummvm.cpp @@ -780,14 +780,13 @@ void Scumm::initRoomSubBlocks() } } - if (_features & GF_SMALL_HEADER) - ptr = findResourceSmall(MKID('EPAL'), roomptr); - else - ptr = findResource(MKID('EPAL'), roomptr); - - if (ptr) - _EPAL_offs = ptr - roomptr; - + // FIXME - we could simply always call findResourceData here, it will + // do the right thing even if GF_SMALL_HEADER is set. But then, we have + // to change setPaletteFromPtr() (easy). The problematic bit is save game + // compatibility - _CLUT_offs is stored in the save game after all. + // Of course we could just decide to not use _CLUT_offs anymore, and change + // setPaletteFromRes() to invoke findResourceData() each time + // (and also getPalettePtr()). if (_features & GF_SMALL_HEADER) ptr = findResourceSmall(MKID('CLUT'), roomptr); else @@ -806,13 +805,10 @@ void Scumm::initRoomSubBlocks() } } - if (_features & GF_SMALL_HEADER) - ptr = findResourceData(MKID('CYCL'), roomptr); - else - ptr = findResourceData(MKID('CYCL'), roomptr); + ptr = findResourceData(MKID('CYCL'), roomptr); if (ptr) - initCycl(findResourceData(MKID('CYCL'), roomptr)); + initCycl(ptr); ptr = findResourceData(MKID('TRNS'), roomptr); if (ptr) @@ -897,125 +893,6 @@ int Scumm::checkKeyHit() return a; } -void Scumm::unkRoomFunc3(int unk1, int unk2, int rfact, int gfact, int bfact) -{ - byte *pal = _currentPalette; - byte *table = _shadowPalette; - int i; - - warning("unkRoomFunc3(%d,%d,%d,%d,%d): not fully implemented", unk1, unk2, rfact, gfact, bfact); - - // TODO - correctly implement this function (see also patch #588501) - // - // Some "typical" examples of how this function is being invoked in real life: - // - // unkRoomFunc3(16, 255, 200, 200, 200) - // - // FOA: Sets up the colors for the boat and submarine shadows in the - // diving scene. Are the shadows too light? Maybe unk1 is used to - // darken the colors? - // - // unkRoomFunc3(0, 255, 700, 700, 700) - // - // FOA: Sets up the colors for the subway car headlight when it first - // goes on. This seems to work ok. - // - // unkRoomFunc3(160, 191, 300, 300, 300) - // unkRoomFunc3(160, 191, 289, 289, 289) - // ... - // unkRoomFunc3(160, 191, 14, 14, 14) - // unkRoomFunc3(160, 191, 3, 3, 3) - // - // FOA: Sets up the colors for the subway car headlight for the later - // half of the trip, where it fades out. This currently doesn't work - // at all. The colors are too dark to be brightened. At first I thought - // unk1 and unk2 were used to tell which color interval to manipulate, - // but as far as I can tell the colors 160-191 aren't used at all to - // draw the light, that can't be it. Apparently unk1 and/or unk2 are - // used to brighten the colors. - - for (i = 0; i <= 255; i++) { - int r = (int) (*pal++ * rfact) >> 8; - int g = (int) (*pal++ * gfact) >> 8; - int b = (int) (*pal++ * bfact) >> 8; - - *table++ = remapPaletteColor(r, g, b, (uint) -1); - } -} - - -void Scumm::palManipulate(int start, int end, int d, int time, int e) -{ - // TODO - correctly implement this function (see also bug #558245) - // - // The only place I know of where this function is being called is in the - // FOA extro, to change the color to match the sinking sun. The following - // three calls (with some pauses between them) are issued: - // - // palManipulate(16, 190, 32, 180, 1) - // palManipulate(16, 190, 32, 1, 1) - // palManipulate(16, 190, 32, 800, 1) - // - // The first two parameters seem to specify a palette range (as the colors - // from 16 to 190 are the ones that make up water & sky). - // - // Maybe the change has to be done over a period of time, possibly specified - // by the second last parameter - between call 1 and 2, about 17-18 seconds - // seem to pass (well using get_msecs, I measured 17155 ms, 17613 ms, 17815 ms). - // - // No clue about the third and fifth parameter right now, they just always - // are 32 and 1 - possibly finding another example of this function being - // used would help a lot. Also, I can't currently compare it with the original, - // doing that (and possibly, taking screenshots of it for analysis!) would - // help a lot. - - static int sys_time = 0; - int new_sys_time = _system->get_msecs(); - - warning("palManipulate(%d, %d, %d, %d, %d): not implemented", start, end, d, time, e); - if (sys_time != 0) - printf("Time since last call: %d\n", new_sys_time-sys_time); - sys_time = new_sys_time; - - { - int redScale = 0xFF; - int greenScale = 0xFF - d; - int blueScale = 0xFF - d; - byte *cptr; - byte *cur; - int num; - int color; - - cptr = _currentPalette + start * 3; - cur = _currentPalette + start * 3; - num = end - start + 1; - - do { - color = *cptr++; - if (redScale != 0xFF) - color = color * redScale / 0xFF; - if (color > 255) - color = 255; - *cur++ = color; - - color = *cptr++; - if (greenScale != 0xFF) - color = color * greenScale / 0xFF; - if (color > 255) - color = 255; - *cur++ = color; - - color = *cptr++; - if (blueScale != 0xFF) - color = color * blueScale / 0xFF; - if (color > 255) - color = 255; - *cur++ = color; - } while (--num); - setDirtyColors(start, end); - } -} - void Scumm::pauseGame(bool user) { //_gui->pause(); |