diff options
author | Matthew Hoops | 2011-05-03 17:17:27 -0400 |
---|---|---|
committer | Matthew Hoops | 2011-05-03 17:25:41 -0400 |
commit | 9cb600099f4c29298707787cafad2741a1cd6686 (patch) | |
tree | fb1930fa56b611317831d66442cba19b18d2e57a /engines/scumm | |
parent | 3b2283daf850605ca897002afbafe44489c35473 (diff) | |
parent | 95a6098f672191dc0792bd4f9bfa18706bbe8e3a (diff) | |
download | scummvm-rg350-9cb600099f4c29298707787cafad2741a1cd6686.tar.gz scummvm-rg350-9cb600099f4c29298707787cafad2741a1cd6686.tar.bz2 scummvm-rg350-9cb600099f4c29298707787cafad2741a1cd6686.zip |
Merge remote branch 'upstream/master' into pegasus
Diffstat (limited to 'engines/scumm')
87 files changed, 1726 insertions, 2448 deletions
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 5906545917..13581c4b45 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -26,6 +26,7 @@ #include "common/system.h" // for setFocusRectangle/clearFocusRectangle #include "scumm/scumm.h" #include "scumm/actor.h" +#include "scumm/actor_he.h" #include "scumm/akos.h" #include "scumm/boxes.h" #include "scumm/charset.h" @@ -75,7 +76,7 @@ void ActorHE::initActor(int mode) { if (_vm->_game.heversion >= 61) _flip = 0; - _clipOverride = _vm->_actorClipOverride; + _clipOverride = ((ScummEngine_v60he *)_vm)->_actorClipOverride; _auxBlock.reset(); } @@ -241,7 +242,7 @@ void Actor::setActorWalkSpeed(uint newSpeedX, uint newSpeedY) { int getAngleFromPos(int x, int y, bool useATAN) { if (useATAN) { double temp = atan2((double)x, (double)-y); - return normalizeAngle((int)(temp * 180 / PI)); + return normalizeAngle((int)(temp * 180 / M_PI)); } else { if (ABS(y) * 2 < ABS(x)) { if (x > 0) @@ -1852,8 +1853,8 @@ void Actor::animateLimb(int limb, int f) { byte *akos = _vm->getResourceAddress(rtCostume, _costume); assert(akos); - aksq = _vm->findResourceData(MKID_BE('AKSQ'), akos); - akfo = _vm->findResourceData(MKID_BE('AKFO'), akos); + aksq = _vm->findResourceData(MKTAG('A','K','S','Q'), akos); + akfo = _vm->findResourceData(MKTAG('A','K','F','O'), akos); size = _vm->getResourceDataSize(akfo) / 2; @@ -2373,7 +2374,7 @@ void Actor::remapActorPaletteColor(int color, int new_color) { return; } - akpl = _vm->findResourceData(MKID_BE('AKPL'), akos); + akpl = _vm->findResourceData(MKTAG('A','K','P','L'), akos); if (!akpl) { debugC(DEBUG_ACTORS, "Actor::remapActorPaletteColor: Can't remap actor %d, costume %d doesn't contain an AKPL block", _number, _costume); return; @@ -2408,7 +2409,7 @@ void Actor::remapActorPalette(int r_fact, int g_fact, int b_fact, int threshold) return; } - akpl = _vm->findResourceData(MKID_BE('AKPL'), akos); + akpl = _vm->findResourceData(MKTAG('A','K','P','L'), akos); if (!akpl) { debugC(DEBUG_ACTORS, "Actor::remapActorPalette: Can't remap actor %d, costume %d doesn't contain an AKPL block", _number, _costume); return; @@ -2417,7 +2418,7 @@ void Actor::remapActorPalette(int r_fact, int g_fact, int b_fact, int threshold) // Get the number palette entries akpl_size = _vm->getResourceDataSize(akpl); - rgbs = _vm->findResourceData(MKID_BE('RGBS'), akos); + rgbs = _vm->findResourceData(MKTAG('R','G','B','S'), akos); if (!rgbs) { debugC(DEBUG_ACTORS, "Actor::remapActorPalette: Can't remap actor %d costume %d doesn't contain an RGB block", _number, _costume); @@ -2534,19 +2535,19 @@ void ScummEngine_v71he::postProcessAuxQueue() { if (_game.heversion >= 72) dy -= a->getElevation(); - const uint8 *akax = findResource(MKID_BE('AKAX'), cost); + const uint8 *akax = findResource(MKTAG('A','K','A','X'), cost); assert(akax); const uint8 *auxd = findPalInPals(akax, ae->subIndex) - _resourceHeaderSize; assert(auxd); - const uint8 *frel = findResourceData(MKID_BE('FREL'), auxd); + const uint8 *frel = findResourceData(MKTAG('F','R','E','L'), auxd); if (frel) { error("unhandled FREL block"); } - const uint8 *disp = findResourceData(MKID_BE('DISP'), auxd); + const uint8 *disp = findResourceData(MKTAG('D','I','S','P'), auxd); if (disp) { error("unhandled DISP block"); } - const uint8 *axfd = findResourceData(MKID_BE('AXFD'), auxd); + const uint8 *axfd = findResourceData(MKTAG('A','X','F','D'), auxd); assert(axfd); uint16 comp = READ_LE_UINT16(axfd); @@ -2566,7 +2567,7 @@ void ScummEngine_v71he::postProcessAuxQueue() { error("unimplemented compression type %d", comp); } } - const uint8 *axur = findResourceData(MKID_BE('AXUR'), auxd); + const uint8 *axur = findResourceData(MKTAG('A','X','U','R'), auxd); if (axur) { uint16 n = READ_LE_UINT16(axur); axur += 2; while (n--) { @@ -2578,7 +2579,7 @@ void ScummEngine_v71he::postProcessAuxQueue() { axur += 8; } } - const uint8 *axer = findResourceData(MKID_BE('AXER'), auxd); + const uint8 *axer = findResourceData(MKTAG('A','X','E','R'), auxd); if (axer) { a->_auxBlock.visible = true; a->_auxBlock.r.left = (int16)READ_LE_UINT16(axer + 0) + dx; diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h index 98854ec5ba..8e699b5a49 100644 --- a/engines/scumm/actor.h +++ b/engines/scumm/actor.h @@ -34,7 +34,6 @@ namespace Scumm { - enum { V12_X_MULTIPLIER = 8, V12_Y_MULTIPLIER = 2, @@ -315,46 +314,6 @@ protected: bool findPathTowards(byte box, byte box2, byte box3, Common::Point &foundPath); }; -class ActorHE : public Actor { -public: - ActorHE(ScummEngine *scumm, int id) : Actor(scumm, id) {} - - virtual void initActor(int mode); - - virtual void hideActor(); - - void drawActorToBackBuf(int x, int y); - - void setHEFlag(int bit, int set); - - void setUserCondition(int slot, int set); - bool isUserConditionSet(int slot) const; - - void setTalkCondition(int slot); - bool isTalkConditionSet(int slot) const; - -public: - /** This rect is used to clip actor drawing. */ - Common::Rect _clipOverride; - - bool _heNoTalkAnimation; - bool _heTalking; - byte _heFlags; - - AuxBlock _auxBlock; - - struct { - int16 posX; - int16 posY; - int16 color; - byte sentence[128]; - } _heTalkQueue[16]; - - - virtual void prepareDrawActorCostume(BaseCostumeRenderer *bcr); - virtual void setActorCostume(int c); -}; - class Actor_v3 : public Actor { public: Actor_v3(ScummEngine *scumm, int id) : Actor(scumm, id) {} diff --git a/engines/scumm/actor_he.h b/engines/scumm/actor_he.h new file mode 100644 index 0000000000..bb7bbb6487 --- /dev/null +++ b/engines/scumm/actor_he.h @@ -0,0 +1,92 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + + +#ifndef SCUMM_ACTOR_HE_H +#define SCUMM_ACTOR_HE_H + +#include "scumm/actor.h" + +namespace Scumm { + +struct AuxBlock { + bool visible; + Common::Rect r; + + void reset() { + visible = false; + r.left = r.top = 0; + r.right = r.bottom = -1; + } +}; + +struct AuxEntry { + int actorNum; + int subIndex; +}; + +class ActorHE : public Actor { +public: + ActorHE(ScummEngine *scumm, int id) : Actor(scumm, id) {} + + virtual void initActor(int mode); + + virtual void hideActor(); + + void drawActorToBackBuf(int x, int y); + + void setHEFlag(int bit, int set); + + void setUserCondition(int slot, int set); + bool isUserConditionSet(int slot) const; + + void setTalkCondition(int slot); + bool isTalkConditionSet(int slot) const; + +public: + /** This rect is used to clip actor drawing. */ + Common::Rect _clipOverride; + + bool _heNoTalkAnimation; + bool _heTalking; + byte _heFlags; + + AuxBlock _auxBlock; + + struct { + int16 posX; + int16 posY; + int16 color; + byte sentence[128]; + } _heTalkQueue[16]; + + + virtual void prepareDrawActorCostume(BaseCostumeRenderer *bcr); + virtual void setActorCostume(int c); +}; + +} // End of namespace Scumm + +#endif diff --git a/engines/scumm/akos.cpp b/engines/scumm/akos.cpp index 354a1d4491..8acbb8058e 100644 --- a/engines/scumm/akos.cpp +++ b/engines/scumm/akos.cpp @@ -146,7 +146,7 @@ void AkosCostumeLoader::loadCostume(int id) { bool AkosCostumeLoader::hasManyDirections() { const AkosHeader *akhd; - akhd = (const AkosHeader *)_vm->findResourceData(MKID_BE('AKHD'), _akos); + akhd = (const AkosHeader *)_vm->findResourceData(MKTAG('A','K','H','D'), _akos); return (akhd->flags & 2) != 0; } @@ -170,12 +170,12 @@ void AkosCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { else anim = newDirToOldDir(a->getFacing()) + frame * 4; - akhd = (const AkosHeader *)_vm->findResourceData(MKID_BE('AKHD'), _akos); + akhd = (const AkosHeader *)_vm->findResourceData(MKTAG('A','K','H','D'), _akos); if (anim >= READ_LE_UINT16(&akhd->num_anims)) return; - r = _vm->findResourceData(MKID_BE('AKCH'), _akos); + r = _vm->findResourceData(MKTAG('A','K','C','H'), _akos); assert(r); offs = READ_LE_UINT16(r + anim * sizeof(uint16)); @@ -183,8 +183,8 @@ void AkosCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { return; r += offs; - const uint8 *akstPtr = _vm->findResourceData(MKID_BE('AKST'), _akos); - const uint8 *aksfPtr = _vm->findResourceData(MKID_BE('AKSF'), _akos); + const uint8 *akstPtr = _vm->findResourceData(MKTAG('A','K','S','T'), _akos); + const uint8 *aksfPtr = _vm->findResourceData(MKTAG('A','K','S','F'), _akos); i = 0; mask = READ_LE_UINT16(r); r += 2; @@ -341,21 +341,21 @@ void AkosRenderer::setCostume(int costume, int shadow) { const byte *akos = _vm->getResourceAddress(rtCostume, costume); assert(akos); - akhd = (const AkosHeader *) _vm->findResourceData(MKID_BE('AKHD'), akos); - akof = (const AkosOffset *) _vm->findResourceData(MKID_BE('AKOF'), akos); - akci = _vm->findResourceData(MKID_BE('AKCI'), akos); - aksq = _vm->findResourceData(MKID_BE('AKSQ'), akos); - akcd = _vm->findResourceData(MKID_BE('AKCD'), akos); - akpl = _vm->findResourceData(MKID_BE('AKPL'), akos); + akhd = (const AkosHeader *) _vm->findResourceData(MKTAG('A','K','H','D'), akos); + akof = (const AkosOffset *) _vm->findResourceData(MKTAG('A','K','O','F'), akos); + akci = _vm->findResourceData(MKTAG('A','K','C','I'), akos); + aksq = _vm->findResourceData(MKTAG('A','K','S','Q'), akos); + akcd = _vm->findResourceData(MKTAG('A','K','C','D'), akos); + akpl = _vm->findResourceData(MKTAG('A','K','P','L'), akos); _codec = READ_LE_UINT16(&akhd->codec); - akct = _vm->findResourceData(MKID_BE('AKCT'), akos); - rgbs = _vm->findResourceData(MKID_BE('RGBS'), akos); + akct = _vm->findResourceData(MKTAG('A','K','C','T'), akos); + rgbs = _vm->findResourceData(MKTAG('R','G','B','S'), akos); xmap = 0; if (shadow) { const uint8 *xmapPtr = _vm->getResourceAddress(rtImage, shadow); assert(xmapPtr); - xmap = _vm->findResourceData(MKID_BE('XMAP'), xmapPtr); + xmap = _vm->findResourceData(MKTAG('X','M','A','P'), xmapPtr); assert(xmap); } } @@ -1384,8 +1384,8 @@ bool ScummEngine_v6::akos_increaseAnims(const byte *akos, Actor *a) { uint size; bool result; - aksq = findResourceData(MKID_BE('AKSQ'), akos); - akfo = findResourceData(MKID_BE('AKFO'), akos); + aksq = findResourceData(MKTAG('A','K','S','Q'), akos); + akfo = findResourceData(MKTAG('A','K','F','O'), akos); size = getResourceDataSize(akfo) / 2; diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp index 861e448221..9fb76d9d63 100644 --- a/engines/scumm/charset.cpp +++ b/engines/scumm/charset.cpp @@ -401,7 +401,7 @@ int CharsetRendererClassic::getCharWidth(uint16 chr) { spacing++; } } - + } else if (chr >= 0x80) { return _vm->_2byteWidth / 2; } @@ -618,11 +618,12 @@ int CharsetRendererV3::getCharWidth(uint16 chr) { spacing = 4; } else if (chr & 0x80) { spacing = _vm->_2byteWidth / 2; - } + } } - if (!spacing) + if (!spacing) { spacing = *(_widthTable + chr); + } return spacing; } @@ -777,7 +778,7 @@ void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) { (ignoreCharsetMask || !vs->hasTwoBuffers)) { dst = vs->getPixels(_left, drawTop); if (charPtr) - drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight, vs->bytesPerPixel); + drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight, vs->format.bytesPerPixel); #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE else if (_vm->_cjkFont) _vm->_cjkFont->drawChar(vs, chr, _left, drawTop, _color, _shadowColor); @@ -785,7 +786,7 @@ void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) { } else { dst = (byte *)_vm->_textSurface.getBasePtr(_left * _vm->_textSurfaceMultiplier, _top * _vm->_textSurfaceMultiplier); if (charPtr) - drawBits1(_vm->_textSurface, dst, charPtr, drawTop, origWidth, origHeight, _vm->_textSurface.bytesPerPixel, (_vm->_textSurfaceMultiplier == 2 && !is2byte)); + drawBits1(_vm->_textSurface, dst, charPtr, drawTop, origWidth, origHeight, _vm->_textSurface.format.bytesPerPixel, (_vm->_textSurfaceMultiplier == 2 && !is2byte)); #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE else if (_vm->_cjkFont) _vm->_cjkFont->drawChar(_vm->_textSurface, chr, _left * _vm->_textSurfaceMultiplier, _top * _vm->_textSurfaceMultiplier, _color, _shadowColor); @@ -834,7 +835,7 @@ void CharsetRendererV3::drawChar(int chr, Graphics::Surface &s, int x, int y) { height = 8; } dst = (byte *)s.pixels + y * s.pitch + x; - drawBits1(s, dst, charPtr, y, width, height, s.bytesPerPixel); + drawBits1(s, dst, charPtr, y, width, height, s.format.bytesPerPixel); } void CharsetRenderer::translateColor() { @@ -857,17 +858,17 @@ void CharsetRenderer::processTownsCharsetColors(uint8 bytesPerPixel) { if (_vm->_game.platform == Common::kPlatformFMTowns) { for (int i = 0; i < (1 << bytesPerPixel); i++) { uint8 c = _vm->_charsetColorMap[i]; - + if (c > 16) { uint8 t = (_vm->_currentPalette[c * 3] < 32) ? 4 : 12; t |= ((_vm->_currentPalette[c * 3 + 1] < 32) ? 2 : 10); t |= ((_vm->_currentPalette[c * 3 + 1] < 32) ? 1 : 9); c = t; } - + if (c == 0) c = _vm->_townsOverrideShadowColor; - + c = ((c & 0x0f) << 4) | (c & 0x0f); _vm->_townsCharsetColorMap[i] = c; } @@ -920,12 +921,12 @@ void CharsetRendererClassic::printChar(int chr, bool ignoreCharsetMask) { noSjis = true; } } - + if (useTownsFontRomCharacter(chr) && !noSjis) { charPtr = 0; _vm->_cjkChar = chr; enableShadow(true); - + width = getCharWidth(chr); // For whatever reason MI1 uses a different font width // for alignment calculation and for drawing when @@ -947,7 +948,7 @@ void CharsetRendererClassic::printChar(int chr, bool ignoreCharsetMask) { height++; } } else -#endif +#endif { uint32 charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4); assert(charOffs < 0x14000); @@ -1096,7 +1097,7 @@ void CharsetRendererClassic::printCharIntern(bool is2byte, const byte *charPtr, } else #endif if (is2byte) { - drawBits1(dstSurface, dstPtr, charPtr, drawTop, origWidth, origHeight, dstSurface.bytesPerPixel); + drawBits1(dstSurface, dstPtr, charPtr, drawTop, origWidth, origHeight, dstSurface.format.bytesPerPixel); } else { drawBitsN(dstSurface, dstPtr, charPtr, *_fontPtr, drawTop, origWidth, origHeight, _vm->_textSurfaceMultiplier == 2); } @@ -1173,7 +1174,7 @@ void CharsetRendererClassic::drawChar(int chr, Graphics::Surface &s, int x, int dst = (byte *)s.pixels + y * s.pitch + x; if (is2byte) { - drawBits1(s, dst, charPtr, y, width, height, s.bytesPerPixel); + drawBits1(s, dst, charPtr, y, width, height, s.format.bytesPerPixel); } else { drawBitsN(s, dst, charPtr, *_fontPtr, y, width, height); } @@ -1259,14 +1260,14 @@ void CharsetRendererCommon::drawBits1(const Graphics::Surface &s, byte *dst, con #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE byte *dst3 = dst2; byte *dst4 = dst2; - if (scale2x) { + if (scale2x) { dst3 = dst2 + s.pitch; dst4 = dst3 + s.pitch; pitch <<= 1; } if (_vm->_game.platform == Common::kPlatformFMTowns && _vm->_game.version == 5) col = _vm->_townsCharsetColorMap[1]; -#endif +#endif for (y = 0; y < height && y + drawTop < s.h; y++) { for (x = 0; x < width; x++) { @@ -1287,19 +1288,19 @@ void CharsetRendererCommon::drawBits1(const Graphics::Surface &s, byte *dst, con if (scale2x) { dst[2] = dst[3] = dst2[2] = dst2[3] = _shadowColor; dst3[0] = dst4[0] = dst3[1] = dst4[1] = _shadowColor; - } else + } else #endif { dst[1] = dst2[0] = _shadowColor; if (_shadowMode != kFMTOWNSShadowMode) dst2[1] = _shadowColor; - } + } } dst[0] = col; #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (scale2x) - dst[1] = dst2[0] = dst2[1] = col; + dst[1] = dst2[0] = dst2[1] = col; #endif } } @@ -1317,7 +1318,7 @@ void CharsetRendererCommon::drawBits1(const Graphics::Surface &s, byte *dst, con dst += pitch; dst2 += pitch; -#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE +#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE dst3 += pitch; dst4 += pitch; #endif @@ -1519,10 +1520,10 @@ void CharsetRendererNES::printChar(int chr, bool ignoreCharsetMask) { if (ignoreCharsetMask || !vs->hasTwoBuffers) { dst = vs->getPixels(_left, drawTop); - drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight, vs->bytesPerPixel); + drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight, vs->format.bytesPerPixel); } else { dst = (byte *)_vm->_textSurface.pixels + _top * _vm->_textSurface.pitch + _left; - drawBits1(_vm->_textSurface, dst, charPtr, drawTop, origWidth, origHeight, _vm->_textSurface.bytesPerPixel); + drawBits1(_vm->_textSurface, dst, charPtr, drawTop, origWidth, origHeight, _vm->_textSurface.format.bytesPerPixel); } if (_str.left > _left) @@ -1552,7 +1553,7 @@ void CharsetRendererNES::drawChar(int chr, Graphics::Surface &s, int x, int y) { height = 8; dst = (byte *)s.pixels + y * s.pitch + x; - drawBits1(s, dst, charPtr, y, width, height, s.bytesPerPixel); + drawBits1(s, dst, charPtr, y, width, height, s.format.bytesPerPixel); } void CharsetRendererNES::drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth, bool scalex) { diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index cd366fcfd4..d0a3ec6e11 100644 --- a/engines/scumm/costume.cpp +++ b/engines/scumm/costume.cpp @@ -419,6 +419,11 @@ void ClassicCostumeRenderer::procC64(Codec1 &v1, int actor) { #undef MASK_AT #ifdef USE_ARM_COSTUME_ASM + +#ifndef IPHONE +#define ClassicProc3RendererShadowARM _ClassicProc3RendererShadowARM +#endif + extern "C" int ClassicProc3RendererShadowARM(int _scaleY, ClassicCostumeRenderer::Codec1 *v1, Graphics::Surface *_out, diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp index f49635d10f..820605924c 100644 --- a/engines/scumm/cursor.cpp +++ b/engines/scumm/cursor.cpp @@ -240,7 +240,7 @@ void ScummEngine_v6::setCursorFromImg(uint img, uint room, uint imgindex) { room = getObjectRoom(img); findObjectInRoom(&foir, foCodeHeader | foImageHeader | foCheckAlreadyLoaded, img, room); - imhd = (const ImageHeader *)findResourceData(MKID_BE('IMHD'), foir.obim); + imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), foir.obim); if (_game.version == 8) { setCursorHotspot(READ_LE_UINT32(&imhd->v8.hotspot[0].x), @@ -270,7 +270,7 @@ void ScummEngine_v6::setCursorFromImg(uint img, uint room, uint imgindex) { if (size > sizeof(_grabbedCursor)) error("setCursorFromImg: Cursor image too large"); - bomp = findResource(MKID_BE('BOMP'), dataptr); + bomp = findResource(MKTAG('B','O','M','P'), dataptr); } if (bomp != NULL) @@ -385,7 +385,7 @@ void ScummEngine_v5::redefineBuiltinCursorFromChar(int index, int chr) { s.pitch = s.w; // s.h = 17 for FM-TOWNS Loom Japanese. Fixes bug #1166917 assert(s.w <= 16 && s.h <= 17); - s.bytesPerPixel = 1; + s.format = Graphics::PixelFormat::createFormatCLUT8(); _charset->drawChar(chr, s, 0, 0); diff --git a/engines/scumm/debugger.cpp b/engines/scumm/debugger.cpp index cf0ee0fa0a..4c1942b865 100644 --- a/engines/scumm/debugger.cpp +++ b/engines/scumm/debugger.cpp @@ -23,7 +23,6 @@ * */ -#include "common/config-manager.h" #include "common/debug-channels.h" #include "common/file.h" #include "common/str.h" @@ -479,7 +478,7 @@ bool ScummDebugger::Cmd_Object(int argc, const char **argv) { //is BgNeedsRedraw enough? _vm->_bgNeedsRedraw = true; } else { - DebugPrintf("object command 'state' requires a parameter\n"); + DebugPrintf("State of object %d: %d\n", obj, _vm->getState(obj)); } } else if (!strcmp(argv[2], "name")) { DebugPrintf("Name of object %d: %s\n", obj, _vm->getObjOrActorName(obj)); diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp index 2a6de98dee..51b46b033c 100644 --- a/engines/scumm/detection.cpp +++ b/engines/scumm/detection.cpp @@ -23,6 +23,9 @@ * */ +// FIXME: Avoid using printf +#define FORBIDDEN_SYMBOL_EXCEPTION_printf + #include "base/plugins.h" #include "common/archive.h" @@ -77,8 +80,6 @@ Common::String ScummEngine::generateFilename(const int room) const { snprintf(buf, sizeof(buf), "disk%02d.lec", diskNumber); } } else { - char id = 0; - switch (_filenamePattern.genMethod) { case kGenDiskNum: snprintf(buf, sizeof(buf), _filenamePattern.pattern, diskNumber); @@ -88,59 +89,6 @@ Common::String ScummEngine::generateFilename(const int room) const { snprintf(buf, sizeof(buf), _filenamePattern.pattern, room); break; - case kGenHEMac: - case kGenHEMacNoParens: - case kGenHEPC: - if (room < 0) { - id = '0' - room; - } else if (_game.heversion >= 98) { - int disk = 0; - if (_heV7DiskOffsets) - disk = _heV7DiskOffsets[room]; - - switch (disk) { - case 2: - id = 'b'; - // Special cases for Blue's games, which share common (b) files - if (_game.id == GID_BIRTHDAY && !(_game.features & GF_DEMO)) - strcpy(buf, "Blue'sBirthday.(b)"); - else if (_game.id == GID_TREASUREHUNT) - strcpy(buf, "Blue'sTreasureHunt.(b)"); - else - snprintf(buf, sizeof(buf), "%s.(b)", _filenamePattern.pattern); - break; - case 1: - id = 'a'; - snprintf(buf, sizeof(buf), "%s.(a)", _filenamePattern.pattern); - break; - default: - id = '0'; - snprintf(buf, sizeof(buf), "%s.he0", _filenamePattern.pattern); - } - } else if (_game.heversion >= 70) { - id = (room == 0) ? '0' : '1'; - } else { - id = diskNumber + '0'; - } - - if (_filenamePattern.genMethod == kGenHEPC) { - // For HE >= 98, we already called snprintf above. - if (_game.heversion < 98 || room < 0) - snprintf(buf, sizeof(buf), "%s.he%c", _filenamePattern.pattern, id); - } else { - if (id == '3') { // special case for cursors - // For mac they're stored in game binary - strncpy(buf, _filenamePattern.pattern, sizeof(buf)); - } else { - if (_filenamePattern.genMethod == kGenHEMac) - snprintf(buf, sizeof(buf), "%s (%c)", _filenamePattern.pattern, id); - else - snprintf(buf, sizeof(buf), "%s %c", _filenamePattern.pattern, id); - } - } - - break; - case kGenUnchanged: strncpy(buf, _filenamePattern.pattern, sizeof(buf)); break; @@ -153,6 +101,109 @@ Common::String ScummEngine::generateFilename(const int room) const { return buf; } +Common::String ScummEngine_v60he::generateFilename(const int room) const { + char buf[128]; + char id = 0; + + switch (_filenamePattern.genMethod) { + case kGenHEMac: + case kGenHEMacNoParens: + case kGenHEPC: + if (room < 0) { + id = '0' - room; + } else { + const int diskNumber = (room > 0) ? _res->roomno[rtRoom][room] : 0; + id = diskNumber + '0'; + } + + if (_filenamePattern.genMethod == kGenHEPC) { + snprintf(buf, sizeof(buf), "%s.he%c", _filenamePattern.pattern, id); + } else { + if (id == '3') { // special case for cursors + // For mac they're stored in game binary + strncpy(buf, _filenamePattern.pattern, sizeof(buf)); + } else { + if (_filenamePattern.genMethod == kGenHEMac) + snprintf(buf, sizeof(buf), "%s (%c)", _filenamePattern.pattern, id); + else + snprintf(buf, sizeof(buf), "%s %c", _filenamePattern.pattern, id); + } + } + + break; + + default: + // Fallback to parent method + return ScummEngine::generateFilename(room); + } + + return buf; +} + +Common::String ScummEngine_v70he::generateFilename(const int room) const { + char buf[128]; + char id = 0; + + switch (_filenamePattern.genMethod) { + case kGenHEMac: + case kGenHEMacNoParens: + case kGenHEPC: + if (_game.heversion >= 98 && room >= 0) { + int disk = 0; + if (_heV7DiskOffsets) + disk = _heV7DiskOffsets[room]; + + switch (disk) { + case 2: + id = 'b'; + // Special cases for Blue's games, which share common (b) files + if (_game.id == GID_BIRTHDAY && !(_game.features & GF_DEMO)) + strcpy(buf, "Blue'sBirthday.(b)"); + else if (_game.id == GID_TREASUREHUNT) + strcpy(buf, "Blue'sTreasureHunt.(b)"); + else + snprintf(buf, sizeof(buf), "%s.(b)", _filenamePattern.pattern); + break; + case 1: + id = 'a'; + snprintf(buf, sizeof(buf), "%s.(a)", _filenamePattern.pattern); + break; + default: + id = '0'; + snprintf(buf, sizeof(buf), "%s.he0", _filenamePattern.pattern); + } + } else if (room < 0) { + id = '0' - room; + } else { + id = (room == 0) ? '0' : '1'; + } + + if (_filenamePattern.genMethod == kGenHEPC) { + // For HE >= 98, we already called snprintf above. + if (_game.heversion < 98 || room < 0) + snprintf(buf, sizeof(buf), "%s.he%c", _filenamePattern.pattern, id); + } else { + if (id == '3') { // special case for cursors + // For mac they're stored in game binary + strncpy(buf, _filenamePattern.pattern, sizeof(buf)); + } else { + if (_filenamePattern.genMethod == kGenHEMac) + snprintf(buf, sizeof(buf), "%s (%c)", _filenamePattern.pattern, id); + else + snprintf(buf, sizeof(buf), "%s %c", _filenamePattern.pattern, id); + } + } + + break; + + default: + // Fallback to parent method + return ScummEngine_v60he::generateFilename(room); + } + + return buf; +} + static Common::String generateFilenameForDetection(const char *pattern, FilenameGenMethod genMethod) { char buf[128]; @@ -946,7 +997,7 @@ Common::Error ScummMetaEngine::createInstance(OSystem *syst, Engine **engine) co Common::FSList fslist; Common::FSNode dir(ConfMan.get("path")); if (!dir.isDirectory()) - return Common::kInvalidPathError; + return Common::kPathNotDirectory; if (!dir.getChildren(fslist, Common::FSNode::kListFilesOnly)) return Common::kNoGameDataFoundError; @@ -1083,6 +1134,7 @@ Common::Error ScummMetaEngine::createInstance(OSystem *syst, Engine **engine) co break; case 62: case 61: + case 60: *engine = new ScummEngine_v60he(syst, res); break; default: @@ -1186,7 +1238,7 @@ SaveStateDescriptor ScummMetaEngine::querySaveMetaInfos(const char *target, int desc.setDeletableFlag(true); desc.setThumbnail(thumbnail); - InfoStuff infos; + SaveStateMetaInfos infos; memset(&infos, 0, sizeof(infos)); if (ScummEngine::loadInfosFromSlot(target, slot, &infos)) { int day = (infos.date >> 24) & 0xFF; diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h index a5542ca868..952abdb39a 100644 --- a/engines/scumm/detection_tables.h +++ b/engines/scumm/detection_tables.h @@ -372,7 +372,7 @@ static const GameSettings gameVariantsTable[] = { {"arttime", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, {"baseball2001", 0, 0, GID_BASEBALL2001, 6, 99, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, {"readtime", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, - {"SoccerMLS", 0, 0, GID_SOCCER, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, + {"SoccerMLS", 0, 0, GID_SOCCERMLS, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, {"spyozon", 0, 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, {"freddicove", "", 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, @@ -386,7 +386,7 @@ static const GameSettings gameVariantsTable[] = { {"Baseball2003", 0, 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, {"basketball", 0, 0, GID_BASKETBALL, 6, 100, MDT_NONE, GF_USE_KEY| GF_16BIT_COLOR, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, {"football2002", 0, 0, GID_FOOTBALL, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, - {"Soccer2004", 0, 0, GID_SOCCER, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, + {"Soccer2004", 0, 0, GID_SOCCER2004, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, // U32 code required, for testing only {"moonbase", 0, 0, GID_MOONBASE, 6, 100, MDT_NONE, GF_USE_KEY | GF_16BIT_COLOR, UNK, GUIO_NOLAUNCHLOAD | GUIO_NOMIDI}, @@ -483,6 +483,7 @@ static const GameFilenamePattern gameFilenamesTable[] = { #ifdef ENABLE_SCUMM_7_8 { "dig", "dig.la%d", kGenDiskNum, UNK_LANG, UNK, 0 }, + { "dig", "thedig.la%d", kGenDiskNum, UNK_LANG, UNK, "Demo" }, // Used by an alternate version of the demo { "dig", "The Dig Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 }, { "dig", "The Dig Demo Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, "Demo" }, diff --git a/engines/scumm/dialogs.h b/engines/scumm/dialogs.h index 0e6e18905f..40e549471b 100644 --- a/engines/scumm/dialogs.h +++ b/engines/scumm/dialogs.h @@ -33,8 +33,8 @@ #include "scumm/detection.h" namespace GUI { - class ListWidget; - class CommandSender; +class ListWidget; +class CommandSender; } diff --git a/engines/scumm/file_nes.cpp b/engines/scumm/file_nes.cpp index d9d84f04ff..47704d6eaf 100644 --- a/engines/scumm/file_nes.cpp +++ b/engines/scumm/file_nes.cpp @@ -28,6 +28,7 @@ #include "common/endian.h" #include "common/md5.h" #include "common/memstream.h" +#include "common/textconsole.h" namespace Scumm { diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp index 9efddc6ad2..e7abd5610e 100644 --- a/engines/scumm/gfx.cpp +++ b/engines/scumm/gfx.cpp @@ -36,6 +36,12 @@ #include "scumm/util.h" #ifdef USE_ARM_GFX_ASM + +#ifndef IPHONE +#define asmDrawStripToScreen _asmDrawStripToScreen +#define asmCopy8Col _asmCopy8Col +#endif + extern "C" void asmDrawStripToScreen(int height, int width, void const* text, void const* src, byte* dst, int vsPitch, int vmScreenWidth, int textSurfacePitch); extern "C" void asmCopy8Col(byte* dst, int dstPitch, const byte* src, int height, uint8 bitDepth); @@ -283,7 +289,7 @@ void Gdi::loadTiles(byte *roomptr) { #ifdef USE_RGB_COLOR void GdiPCEngine::loadTiles(byte *roomptr) { - decodePCEngineTileData(_vm->findResourceData(MKID_BE('TILE'), roomptr)); + decodePCEngineTileData(_vm->findResourceData(MKTAG('T','I','L','E'), roomptr)); } #endif @@ -385,8 +391,11 @@ void ScummEngine::initVirtScreen(VirtScreenNumber slot, int top, int width, int vs->hasTwoBuffers = twobufs; vs->xstart = 0; vs->backBuf = NULL; - vs->bytesPerPixel = (_game.features & GF_16BIT_COLOR) ? 2 : 1; - vs->pitch = width * vs->bytesPerPixel; + if (_game.features & GF_16BIT_COLOR) + vs->format = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); + else + vs->format = Graphics::PixelFormat::createFormatCLUT8(); + vs->pitch = width * vs->format.bytesPerPixel; if (_game.version >= 7) { // Increase the pitch by one; needed to accomodate the extra screen @@ -622,7 +631,7 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i int m = _textSurfaceMultiplier; int vsPitch; int pitch = vs->pitch; - vsPitch = vs->pitch - width * vs->bytesPerPixel; + vsPitch = vs->pitch - width * vs->format.bytesPerPixel; if (_game.version < 7) { @@ -667,7 +676,7 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i } else { WRITE_UINT16(dstPtr, _16BitPalette[tmp]); dstPtr += 2; } - srcPtr += vs->bytesPerPixel; + srcPtr += vs->format.bytesPerPixel; } srcPtr += vsPitch; textPtr += _textSurface.pitch - width * m; @@ -706,7 +715,7 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i } #endif src = _compositeBuf; - pitch = width * vs->bytesPerPixel; + pitch = width * vs->format.bytesPerPixel; if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) { ditherHerc(_compositeBuf, _herculesBuf, width, &x, &y, &width, &height); @@ -858,7 +867,7 @@ void ScummEngine::initBGBuffers(int height) { _gdi->_numZBuffer = 2; } else if (_game.features & GF_SMALL_HEADER) { int off; - ptr = findResourceData(MKID_BE('SMAP'), room); + ptr = findResourceData(MKTAG('S','M','A','P'), room); _gdi->_numZBuffer = 0; if (_game.features & GF_16COLOR) @@ -873,13 +882,13 @@ void ScummEngine::initBGBuffers(int height) { } } else if (_game.version == 8) { // in V8 there is no RMIH and num z buffers is in RMHD - ptr = findResource(MKID_BE('RMHD'), room); + ptr = findResource(MKTAG('R','M','H','D'), room); _gdi->_numZBuffer = READ_LE_UINT32(ptr + 24) + 1; } else if (_game.heversion >= 70) { - ptr = findResource(MKID_BE('RMIH'), room); + ptr = findResource(MKTAG('R','M','I','H'), room); _gdi->_numZBuffer = READ_LE_UINT16(ptr + 8) + 1; } else { - ptr = findResource(MKID_BE('RMIH'), findResource(MKID_BE('RMIM'), room)); + ptr = findResource(MKTAG('R','M','I','H'), findResource(MKTAG('R','M','I','M'), room)); _gdi->_numZBuffer = READ_LE_UINT16(ptr + 8) + 1; } assert(_gdi->_numZBuffer >= 1 && _gdi->_numZBuffer <= 8); @@ -1036,17 +1045,17 @@ void ScummEngine::restoreBackground(Common::Rect rect, byte backColor) { return; if (vs->hasTwoBuffers && _currentRoom != 0 && isLightOn()) { - blit(screenBuf, vs->pitch, vs->getBackPixels(rect.left, rect.top), vs->pitch, width, height, vs->bytesPerPixel); + blit(screenBuf, vs->pitch, vs->getBackPixels(rect.left, rect.top), vs->pitch, width, height, vs->format.bytesPerPixel); if (vs->number == kMainVirtScreen && _charset->_hasMask) { #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.platform == Common::kPlatformFMTowns) { byte *mask = (byte *)_textSurface.getBasePtr(rect.left * _textSurfaceMultiplier, (rect.top + vs->topline) * _textSurfaceMultiplier); - fill(mask, _textSurface.pitch, 0, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.bytesPerPixel); + fill(mask, _textSurface.pitch, 0, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.format.bytesPerPixel); } else #endif { byte *mask = (byte *)_textSurface.getBasePtr(rect.left, rect.top - _screenTop); - fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.bytesPerPixel); + fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.format.bytesPerPixel); } } } else { @@ -1054,14 +1063,14 @@ void ScummEngine::restoreBackground(Common::Rect rect, byte backColor) { if (_game.platform == Common::kPlatformFMTowns) { backColor |= (backColor << 4); byte *mask = (byte *)_textSurface.getBasePtr(rect.left * _textSurfaceMultiplier, (rect.top + vs->topline) * _textSurfaceMultiplier); - fill(mask, _textSurface.pitch, backColor, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.bytesPerPixel); + fill(mask, _textSurface.pitch, backColor, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.format.bytesPerPixel); } #endif if (_game.features & GF_16BIT_COLOR) - fill(screenBuf, vs->pitch, _16BitPalette[backColor], width, height, vs->bytesPerPixel); + fill(screenBuf, vs->pitch, _16BitPalette[backColor], width, height, vs->format.bytesPerPixel); else - fill(screenBuf, vs->pitch, backColor, width, height, vs->bytesPerPixel); + fill(screenBuf, vs->pitch, backColor, width, height, vs->format.bytesPerPixel); } } @@ -1090,7 +1099,7 @@ void ScummEngine::restoreCharsetBg() { if (vs->number != kMainVirtScreen) { // Restore from back buffer const byte *backBuf = vs->getBackPixels(0, 0); - blit(screenBuf, vs->pitch, backBuf, vs->pitch, vs->w, vs->h, vs->bytesPerPixel); + blit(screenBuf, vs->pitch, backBuf, vs->pitch, vs->w, vs->h, vs->format.bytesPerPixel); } } else { // Clear area @@ -1118,7 +1127,7 @@ void ScummEngine::clearTextSurface() { #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE _game.platform == Common::kPlatformFMTowns ? 0 : #endif - CHARSET_MASK_TRANSPARENCY, _textSurface.w, _textSurface.h, _textSurface.bytesPerPixel); + CHARSET_MASK_TRANSPARENCY, _textSurface.w, _textSurface.h, _textSurface.format.bytesPerPixel); } byte *ScummEngine::getMaskBuffer(int x, int y, int z) { @@ -1283,66 +1292,64 @@ void ScummEngine::drawBox(int x, int y, int x2, int y2, int color) { ) { #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.platform == Common::kPlatformFMTowns) { - if (color == 254) { - color = color; + if (color == 254) towns_setupPalCycleField(x, y, x2, y2); - } } else #endif { if (vs->number != kMainVirtScreen) error("can only copy bg to main window"); - blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height, vs->bytesPerPixel); + blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height, vs->format.bytesPerPixel); if (_charset->_hasMask) { byte *mask = (byte *)_textSurface.getBasePtr(x * _textSurfaceMultiplier, (y - _screenTop) * _textSurfaceMultiplier); - fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.bytesPerPixel); + fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.format.bytesPerPixel); } } } else if (_game.heversion >= 72) { // Flags are used for different methods in HE games uint32 flags = color; if ((flags & 0x2000) || (flags & 0x4000000)) { - blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height, vs->bytesPerPixel); + blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height, vs->format.bytesPerPixel); } else if ((flags & 0x4000) || (flags & 0x2000000)) { - blit(bgbuff, vs->pitch, backbuff, vs->pitch, width, height, vs->bytesPerPixel); + blit(bgbuff, vs->pitch, backbuff, vs->pitch, width, height, vs->format.bytesPerPixel); } else if ((flags & 0x8000) || (flags & 0x1000000)) { flags &= (flags & 0x1000000) ? 0xFFFFFF : 0x7FFF; - fill(backbuff, vs->pitch, flags, width, height, vs->bytesPerPixel); - fill(bgbuff, vs->pitch, flags, width, height, vs->bytesPerPixel); + fill(backbuff, vs->pitch, flags, width, height, vs->format.bytesPerPixel); + fill(bgbuff, vs->pitch, flags, width, height, vs->format.bytesPerPixel); } else { - fill(backbuff, vs->pitch, flags, width, height, vs->bytesPerPixel); + fill(backbuff, vs->pitch, flags, width, height, vs->format.bytesPerPixel); } } else if (_game.heversion >= 60) { // Flags are used for different methods in HE games uint16 flags = color; if (flags & 0x2000) { - blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height, vs->bytesPerPixel); + blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height, vs->format.bytesPerPixel); } else if (flags & 0x4000) { - blit(bgbuff, vs->pitch, backbuff, vs->pitch, width, height, vs->bytesPerPixel); + blit(bgbuff, vs->pitch, backbuff, vs->pitch, width, height, vs->format.bytesPerPixel); } else if (flags & 0x8000) { flags &= 0x7FFF; - fill(backbuff, vs->pitch, flags, width, height, vs->bytesPerPixel); - fill(bgbuff, vs->pitch, flags, width, height, vs->bytesPerPixel); + fill(backbuff, vs->pitch, flags, width, height, vs->format.bytesPerPixel); + fill(bgbuff, vs->pitch, flags, width, height, vs->format.bytesPerPixel); } else { - fill(backbuff, vs->pitch, flags, width, height, vs->bytesPerPixel); + fill(backbuff, vs->pitch, flags, width, height, vs->format.bytesPerPixel); } } else { if (_game.features & GF_16BIT_COLOR) { - fill(backbuff, vs->pitch, _16BitPalette[color], width, height, vs->bytesPerPixel); + fill(backbuff, vs->pitch, _16BitPalette[color], width, height, vs->format.bytesPerPixel); } else { #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_game.platform == Common::kPlatformFMTowns) { color = ((color & 0x0f) << 4) | (color & 0x0f); byte *mask = (byte *)_textSurface.getBasePtr(x * _textSurfaceMultiplier, (y - _screenTop + vs->topline) * _textSurfaceMultiplier); - fill(mask, _textSurface.pitch, color, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.bytesPerPixel); + fill(mask, _textSurface.pitch, color, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier, _textSurface.format.bytesPerPixel); if (_game.id == GID_MONKEY2 || _game.id == GID_INDY4 || ((_game.id == GID_INDY3 || _game.id == GID_ZAK) && vs->number != kTextVirtScreen) || (_game.id == GID_LOOM && vs->number == kMainVirtScreen)) return; } #endif - fill(backbuff, vs->pitch, color, width, height, vs->bytesPerPixel); + fill(backbuff, vs->pitch, color, width, height, vs->format.bytesPerPixel); } } } @@ -1381,7 +1388,7 @@ void ScummEngine_v5::drawFlashlight() { _flashlight.y, _flashlight.y + _flashlight.h, USAGE_BIT_DIRTY); if (_flashlight.buffer) { - fill(_flashlight.buffer, vs->pitch, 0, _flashlight.w, _flashlight.h, vs->bytesPerPixel); + fill(_flashlight.buffer, vs->pitch, 0, _flashlight.w, _flashlight.h, vs->format.bytesPerPixel); } _flashlight.isDrawn = false; } @@ -1428,20 +1435,20 @@ void ScummEngine_v5::drawFlashlight() { _flashlight.buffer = vs->getPixels(_flashlight.x, _flashlight.y); bgbak = vs->getBackPixels(_flashlight.x, _flashlight.y); - blit(_flashlight.buffer, vs->pitch, bgbak, vs->pitch, _flashlight.w, _flashlight.h, vs->bytesPerPixel); + blit(_flashlight.buffer, vs->pitch, bgbak, vs->pitch, _flashlight.w, _flashlight.h, vs->format.bytesPerPixel); // Round the corners. To do so, we simply hard-code a set of nicely // rounded corners. static const int corner_data[] = { 8, 6, 4, 3, 2, 2, 1, 1 }; int minrow = 0; - int maxcol = (_flashlight.w - 1) * vs->bytesPerPixel; + int maxcol = (_flashlight.w - 1) * vs->format.bytesPerPixel; int maxrow = (_flashlight.h - 1) * vs->pitch; for (i = 0; i < 8; i++, minrow += vs->pitch, maxrow -= vs->pitch) { int d = corner_data[i]; for (j = 0; j < d; j++) { - if (vs->bytesPerPixel == 2) { + if (vs->format.bytesPerPixel == 2) { WRITE_UINT16(&_flashlight.buffer[minrow + 2 * j], 0); WRITE_UINT16(&_flashlight.buffer[minrow + maxcol - 2 * j], 0); WRITE_UINT16(&_flashlight.buffer[maxrow + 2 * j], 0); @@ -1649,9 +1656,9 @@ int Gdi::getZPlanes(const byte *ptr, const byte *zplane_list[9], bool bmapImage) if ((_vm->_game.features & GF_SMALL_HEADER) || _vm->_game.version == 8) zplane_list[0] = ptr; else if (bmapImage) - zplane_list[0] = _vm->findResource(MKID_BE('BMAP'), ptr); + zplane_list[0] = _vm->findResource(MKTAG('B','M','A','P'), ptr); else - zplane_list[0] = _vm->findResource(MKID_BE('SMAP'), ptr); + zplane_list[0] = _vm->findResource(MKTAG('S','M','A','P'), ptr); if (_zbufferDisabled) numzbuf = 0; @@ -1694,11 +1701,11 @@ int Gdi::getZPlanes(const byte *ptr, const byte *zplane_list[9], bool bmapImage) } } else { const uint32 zplane_tags[] = { - MKID_BE('ZP00'), - MKID_BE('ZP01'), - MKID_BE('ZP02'), - MKID_BE('ZP03'), - MKID_BE('ZP04') + MKTAG('Z','P','0','0'), + MKTAG('Z','P','0','1'), + MKTAG('Z','P','0','2'), + MKTAG('Z','P','0','3'), + MKTAG('Z','P','0','4') }; for (i = 1; i < numzbuf; i++) { @@ -1735,7 +1742,7 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const // Skip to the BSTR->WRAP->OFFS chunk smap_ptr = ptr + 24; } else { - smap_ptr = _vm->findResource(MKID_BE('SMAP'), ptr); + smap_ptr = _vm->findResource(MKTAG('S','M','A','P'), ptr); assert(smap_ptr); } @@ -1743,7 +1750,7 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const const byte *tmsk_ptr = NULL; if (_vm->_game.heversion >= 72) { - tmsk_ptr = _vm->findResource(MKID_BE('TMSK'), ptr); + tmsk_ptr = _vm->findResource(MKTAG('T','M','S','K'), ptr); } if (y + height > vs->h) { @@ -1757,7 +1764,7 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const } #endif - _vertStripNextInc = height * vs->pitch - 1 * vs->bytesPerPixel; + _vertStripNextInc = height * vs->pitch - 1 * vs->format.bytesPerPixel; _objectMode = (flag & dbObjectMode) == dbObjectMode; prepareDrawBitmap(ptr, vs, x, y, width, height, stripnr, numstrip); @@ -1790,9 +1797,9 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const // In the case of a double buffered virtual screen, we draw to // the backbuffer, otherwise to the primary surface memory. if (vs->hasTwoBuffers) - dstPtr = vs->backBuf + y * vs->pitch + (x * 8 * vs->bytesPerPixel); + dstPtr = vs->backBuf + y * vs->pitch + (x * 8 * vs->format.bytesPerPixel); else - dstPtr = (byte *)vs->pixels + y * vs->pitch + (x * 8 * vs->bytesPerPixel); + dstPtr = (byte *)vs->pixels + y * vs->pitch + (x * 8 * vs->format.bytesPerPixel); transpStrip = drawStrip(dstPtr, vs, x, y, width, height, stripnr, smap_ptr); @@ -1801,11 +1808,11 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const transpStrip = true; if (vs->hasTwoBuffers) { - byte *frontBuf = (byte *)vs->pixels + y * vs->pitch + (x * 8 * vs->bytesPerPixel); + byte *frontBuf = (byte *)vs->pixels + y * vs->pitch + (x * 8 * vs->format.bytesPerPixel); if (lightsOn) - copy8Col(frontBuf, vs->pitch, dstPtr, height, vs->bytesPerPixel); + copy8Col(frontBuf, vs->pitch, dstPtr, height, vs->format.bytesPerPixel); else - clear8Col(frontBuf, vs->pitch, height, vs->bytesPerPixel); + clear8Col(frontBuf, vs->pitch, height, vs->format.bytesPerPixel); } decodeMask(x, y, width, height, stripnr, numzbuf, zplane_list, transpStrip, flag, tmsk_ptr); @@ -2013,7 +2020,7 @@ void Gdi::drawBMAPBg(const byte *ptr, VirtScreen *vs) { byte *mask_ptr; const byte *zplane_list[9]; - const byte *bmap_ptr = _vm->findResourceData(MKID_BE('BMAP'), ptr); + const byte *bmap_ptr = _vm->findResourceData(MKTAG('B','M','A','P'), ptr); assert(bmap_ptr); byte code = *bmap_ptr++; @@ -2041,7 +2048,7 @@ void Gdi::drawBMAPBg(const byte *ptr, VirtScreen *vs) { drawStripHE(dst, vs->pitch, bmap_ptr, vs->w, vs->h, true); break; case 150: - fill(dst, vs->pitch, *bmap_ptr, vs->w, vs->h, vs->bytesPerPixel); + fill(dst, vs->pitch, *bmap_ptr, vs->w, vs->h, vs->format.bytesPerPixel); break; default: // Alternative russian freddi3 uses badly formatted bitmaps @@ -2093,7 +2100,7 @@ void Gdi::drawBMAPBg(const byte *ptr, VirtScreen *vs) { } void Gdi::drawBMAPObject(const byte *ptr, VirtScreen *vs, int obj, int x, int y, int w, int h) { - const byte *bmap_ptr = _vm->findResourceData(MKID_BE('BMAP'), ptr); + const byte *bmap_ptr = _vm->findResourceData(MKTAG('B','M','A','P'), ptr); assert(bmap_ptr); byte code = *bmap_ptr++; @@ -2152,7 +2159,7 @@ void ScummEngine_v70he::restoreBackgroundHE(Common::Rect rect, int dirtybit) { assert(rw <= _screenWidth && rw > 0); assert(rh <= _screenHeight && rh > 0); - blit(dst, _virtscr[kMainVirtScreen].pitch, src, _virtscr[kMainVirtScreen].pitch, rw, rh, vs->bytesPerPixel); + blit(dst, _virtscr[kMainVirtScreen].pitch, src, _virtscr[kMainVirtScreen].pitch, rw, rh, vs->format.bytesPerPixel); markRectAsDirty(kMainVirtScreen, rect, dirtybit); } #endif @@ -2182,15 +2189,15 @@ void Gdi::resetBackground(int top, int bottom, int strip) { if (bottom > vs->bdirty[strip]) vs->bdirty[strip] = bottom; - bgbak_ptr = (byte *)vs->backBuf + top * vs->pitch + (strip + vs->xstart/8) * 8 * vs->bytesPerPixel; - backbuff_ptr = (byte *)vs->pixels + top * vs->pitch + (strip + vs->xstart/8) * 8 * vs->bytesPerPixel; + bgbak_ptr = (byte *)vs->backBuf + top * vs->pitch + (strip + vs->xstart/8) * 8 * vs->format.bytesPerPixel; + backbuff_ptr = (byte *)vs->pixels + top * vs->pitch + (strip + vs->xstart/8) * 8 * vs->format.bytesPerPixel; numLinesToProcess = bottom - top; if (numLinesToProcess) { if (_vm->isLightOn()) { - copy8Col(backbuff_ptr, vs->pitch, bgbak_ptr, numLinesToProcess, vs->bytesPerPixel); + copy8Col(backbuff_ptr, vs->pitch, bgbak_ptr, numLinesToProcess, vs->format.bytesPerPixel); } else { - clear8Col(backbuff_ptr, vs->pitch, numLinesToProcess, vs->bytesPerPixel); + clear8Col(backbuff_ptr, vs->pitch, numLinesToProcess, vs->format.bytesPerPixel); } } } @@ -2830,10 +2837,10 @@ void GdiPCEngine::decodeStrip(const byte *ptr, uint16 *tiles, byte *colors, uint void GdiPCEngine::decodePCEngineGfx(const byte *room) { uint16* stripOffsets; - decodePCEngineTileData(_vm->findResourceData(MKID_BE('TILE'), room)); - decodePCEngineMaskData(_vm->findResourceData(MKID_BE('ZP00'), room)); + decodePCEngineTileData(_vm->findResourceData(MKTAG('T','I','L','E'), room)); + decodePCEngineMaskData(_vm->findResourceData(MKTAG('Z','P','0','0'), room)); - const byte* smap_ptr = _vm->findResourceData(MKID_BE('IM00'), room); + const byte* smap_ptr = _vm->findResourceData(MKTAG('I','M','0','0'), room); smap_ptr++; // roomID int numStrips = *smap_ptr++; int numRows = *smap_ptr++; diff --git a/engines/scumm/gfx.h b/engines/scumm/gfx.h index c6062ef9be..3f69d75efd 100644 --- a/engines/scumm/gfx.h +++ b/engines/scumm/gfx.h @@ -158,11 +158,11 @@ struct VirtScreen : Graphics::Surface { } byte *getPixels(int x, int y) const { - return (byte *)pixels + y * pitch + (xstart + x) * bytesPerPixel; + return (byte *)pixels + y * pitch + (xstart + x) * format.bytesPerPixel; } byte *getBackPixels(int x, int y) const { - return (byte *)backBuf + y * pitch + (xstart + x) * bytesPerPixel; + return (byte *)backBuf + y * pitch + (xstart + x) * format.bytesPerPixel; } }; diff --git a/engines/scumm/gfxARM.s b/engines/scumm/gfxARM.s index 34de954a17..9f7c2949b3 100644 --- a/engines/scumm/gfxARM.s +++ b/engines/scumm/gfxARM.s @@ -25,8 +25,8 @@ .text - .global asmDrawStripToScreen - .global asmCopy8Col + .global _asmDrawStripToScreen + .global _asmCopy8Col @ ARM implementation of asmDrawStripToScreen. @ @@ -44,7 +44,7 @@ @ In addition, we assume that text, src and dst are all word (4 byte) @ aligned. This is the same assumption that the old 'inline' version @ made. -asmDrawStripToScreen: +_asmDrawStripToScreen: @ r0 = height @ r1 = width @ r2 = text @@ -125,7 +125,7 @@ end: @ In addition, we assume that src and dst are both word (4 byte) @ aligned. This is the same assumption that the old 'inline' version @ made. -asmCopy8Col: +_asmCopy8Col: @ r0 = dst @ r1 = dstPitch @ r2 = src diff --git a/engines/scumm/gfx_towns.cpp b/engines/scumm/gfx_towns.cpp index abf2da63a6..78c7ef23f1 100644 --- a/engines/scumm/gfx_towns.cpp +++ b/engines/scumm/gfx_towns.cpp @@ -48,7 +48,7 @@ void ScummEngine::towns_drawStripToScreen(VirtScreen *vs, int dstX, int dstY, in int dp1 = _townsScreen->getLayerPitch(0) - width * _townsScreen->getLayerBpp(0); int dp2 = _townsScreen->getLayerPitch(1) - width * m * _townsScreen->getLayerBpp(1); - int sp1 = vs->pitch - (width * vs->bytesPerPixel); + int sp1 = vs->pitch - (width * vs->format.bytesPerPixel); int sp2 = _textSurface.pitch - width * m; if (vs->number == kMainVirtScreen || _game.id == GID_INDY3 || _game.id == GID_ZAK) { diff --git a/engines/scumm/he/animation_he.cpp b/engines/scumm/he/animation_he.cpp index 7840b9df20..e3e25c161c 100644 --- a/engines/scumm/he/animation_he.cpp +++ b/engines/scumm/he/animation_he.cpp @@ -112,7 +112,7 @@ void MoviePlayer::handleNextFrame() { if (_flags & 2) { uint8 *dstPtr = _vm->getResourceAddress(rtImage, _wizResNum); assert(dstPtr); - uint8 *dst = _vm->findWrappedBlock(MKID_BE('WIZD'), dstPtr, 0, 0); + uint8 *dst = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dstPtr, 0, 0); assert(dst); copyFrameToBuffer(dst, kDstResource, 0, 0, _vm->_screenWidth * _vm->_bytesPerPixel); } else if (_flags & 1) { diff --git a/engines/scumm/he/cup_player_he.cpp b/engines/scumm/he/cup_player_he.cpp index 79bb47aafc..5cd75a5c62 100644 --- a/engines/scumm/he/cup_player_he.cpp +++ b/engines/scumm/he/cup_player_he.cpp @@ -30,6 +30,7 @@ #include "audio/audiostream.h" #include "audio/mixer.h" #include "audio/decoders/raw.h" +#include "graphics/palette.h" #include "scumm/scumm.h" #include "scumm/util.h" #include "scumm/he/intern_he.h" @@ -47,7 +48,7 @@ bool CUP_Player::open(const char *filename) { if (_fileStream.open(filename)) { uint32 tag = _fileStream.readUint32BE(); _fileStream.readUint32BE(); - if (tag == MKID_BE('BEAN')) { + if (tag == MKTAG('B','E','A','N')) { _playbackRate = kDefaultPlaybackRate; _width = kDefaultVideoWidth; _height = kDefaultVideoHeight; @@ -168,7 +169,7 @@ void CUP_Player::updateSfx() { assert(sfxIndex >= 0 && sfxIndex < _sfxCount); uint32 offset = READ_LE_UINT32(_sfxBuffer + sfxIndex * 4) - 8; uint8 *soundData = _sfxBuffer + offset; - if (READ_BE_UINT32(soundData) == MKID_BE('DATA')) { + if (READ_BE_UINT32(soundData) == MKTAG('D','A','T','A')) { uint32 soundSize = READ_BE_UINT32(soundData + 4); _mixer->playStream(Audio::Mixer::kSFXSoundType, &sfxChannel->handle, Audio::makeLoopingAudioStream( @@ -208,19 +209,19 @@ bool CUP_Player::parseNextHeaderTag(Common::SeekableReadStream &dataStream) { uint32 next = dataStream.pos() + size; debug(1, "New header tag %s %d dataSize %d", tag2str(tag), size, _dataSize); switch (tag) { - case MKID_BE('HEAD'): + case MKTAG('H','E','A','D'): handleHEAD(dataStream, size); break; - case MKID_BE('SFXB'): + case MKTAG('S','F','X','B'): handleSFXB(dataStream, size); break; - case MKID_BE('RGBS'): + case MKTAG('R','G','B','S'): handleRGBS(dataStream, size); break; - case MKID_BE('DATA'): + case MKTAG('D','A','T','A'): _dataSize = size; return false; - case MKID_BE('GFXB'): + case MKTAG('G','F','X','B'): // this is never triggered default: warning("Unhandled tag %s", tag2str(tag)); @@ -236,34 +237,34 @@ bool CUP_Player::parseNextBlockTag(Common::SeekableReadStream &dataStream) { uint32 next = dataStream.pos() + size; debug(1, "New block tag %s %d dataSize %d", tag2str(tag), size, _dataSize); switch (tag) { - case MKID_BE('FRAM'): + case MKTAG('F','R','A','M'): handleFRAM(dataStream, size); break; - case MKID_BE('LZSS'): + case MKTAG('L','Z','S','S'): if (handleLZSS(dataStream, size) && _outLzssBufSize != 0) { Common::MemoryReadStream memoryStream(_outLzssBufData, _outLzssBufSize); parseNextBlockTag(memoryStream); } break; - case MKID_BE('RATE'): + case MKTAG('R','A','T','E'): handleRATE(dataStream, size); break; - case MKID_BE('RGBS'): + case MKTAG('R','G','B','S'): handleRGBS(dataStream, size); break; - case MKID_BE('SNDE'): + case MKTAG('S','N','D','E'): handleSNDE(dataStream, size); break; - case MKID_BE('TOIL'): + case MKTAG('T','O','I','L'): handleTOIL(dataStream, size); break; - case MKID_BE('SRLE'): + case MKTAG('S','R','L','E'): handleSRLE(dataStream, size); break; - case MKID_BE('BLOK'): + case MKTAG('B','L','O','K'): _dataSize -= size + 8; return false; - case MKID_BE('WRLE'): + case MKTAG('W','R','L','E'): // this is never triggered default: warning("Unhandled tag %s", tag2str(tag)); @@ -283,10 +284,10 @@ void CUP_Player::handleSFXB(Common::SeekableReadStream &dataStream, uint32 dataS if (dataSize > 16) { // WRAP and OFFS chunks uint32 tag = dataStream.readUint32BE(); uint32 size = dataStream.readUint32BE(); - if (tag == MKID_BE('WRAP')) { + if (tag == MKTAG('W','R','A','P')) { tag = dataStream.readUint32BE(); size = dataStream.readUint32BE(); - if (tag == MKID_BE('OFFS')) { + if (tag == MKTAG('O','F','F','S')) { _sfxCount = (size - 8) / 4; _sfxBuffer = (uint8 *)malloc(dataSize - 16); if (_sfxBuffer) { @@ -439,12 +440,12 @@ static void decodeLZSS(uint8 *dst, const uint8 *src1, const uint8 *src2, const u bool CUP_Player::handleLZSS(Common::SeekableReadStream &dataStream, uint32 dataSize) { uint32 tag = dataStream.readUint32BE(); uint32 size = dataStream.readUint32BE(); - if (tag == MKID_BE('LZHD')) { + if (tag == MKTAG('L','Z','H','D')) { uint32 compressionType = dataStream.readUint32LE(); uint32 compressionSize = dataStream.readUint32LE(); tag = dataStream.readUint32BE(); size = dataStream.readUint32BE(); - if (tag == MKID_BE('DATA') && compressionType == 0x2000) { + if (tag == MKTAG('D','A','T','A') && compressionType == 0x2000) { if (_inLzssBufSize < size - 16) { free(_inLzssBufData); _inLzssBufSize = size - 16; diff --git a/engines/scumm/he/floodfill_he.cpp b/engines/scumm/he/floodfill_he.cpp index 491b91c17e..026a848828 100644 --- a/engines/scumm/he/floodfill_he.cpp +++ b/engines/scumm/he/floodfill_he.cpp @@ -240,7 +240,7 @@ void Wiz::fillWizFlood(const WizParameters *params) { if (params->processFlags & kWPFNewState) { state = params->img.state; } - uint8 *wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), dataPtr, state, 0); + uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), dataPtr, state, 0); assert(wizh); int c = READ_LE_UINT32(wizh + 0x0); int w = READ_LE_UINT32(wizh + 0x4); @@ -258,7 +258,7 @@ void Wiz::fillWizFlood(const WizParameters *params) { color = params->fillColor; } if (imageRect.contains(px, py)) { - uint8 *wizd = _vm->findWrappedBlock(MKID_BE('WIZD'), dataPtr, state, 0); + uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dataPtr, state, 0); assert(wizd); FloodFillState *ffs = new FloodFillState; diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h index 5b59558dd7..830e940322 100644 --- a/engines/scumm/he/intern_he.h +++ b/engines/scumm/he/intern_he.h @@ -31,6 +31,7 @@ #include "scumm/he/floodfill_he.h" #include "scumm/he/wiz_he.h" #endif +#include "scumm/actor_he.h" // For AuxBlock & AuxEntry namespace Common { class SeekableReadStream; @@ -55,7 +56,10 @@ public: Common::SeekableReadStream *_hInFileTable[17]; Common::WriteStream *_hOutFileTable[17]; + Common::Rect _actorClipOverride; // HE specific + int _heTimers[16]; + int getHETimer(int timer); void setHETimer(int timer); @@ -63,6 +67,8 @@ public: ScummEngine_v60he(OSystem *syst, const DetectorResult &dr); ~ScummEngine_v60he(); + virtual Common::String generateFilename(const int room) const; + virtual void resetScumm(); protected: @@ -107,7 +113,9 @@ class ScummEngine_v70he : public ScummEngine_v60he { protected: ResExtractor *_resExtractor; + byte *_heV7DiskOffsets; byte *_heV7RoomOffsets; + uint32 *_heV7RoomIntOffsets; int32 _heSndSoundId, _heSndOffset, _heSndChannel, _heSndFlags, _heSndSoundFreq; @@ -118,9 +126,14 @@ public: ScummEngine_v70he(OSystem *syst, const DetectorResult &dr); ~ScummEngine_v70he(); + virtual Common::String generateFilename(const int room) const; + void restoreBackgroundHE(Common::Rect rect, int dirtybit = 0); protected: + virtual void allocateArrays(); + virtual int readResTypeList(int id); + virtual uint32 getResourceRoomOffset(int type, int idx); virtual void setupOpcodes(); virtual void setupScummVars(); diff --git a/engines/scumm/he/logic_he.cpp b/engines/scumm/he/logic_he.cpp index ed92c33105..297c2992db 100644 --- a/engines/scumm/he/logic_he.cpp +++ b/engines/scumm/he/logic_he.cpp @@ -160,8 +160,8 @@ int32 LogicHErace::dispatch(int op, int numArgs, int32 *args) { return res; } -#define RAD2DEG (180 / PI) -#define DEG2RAD (PI / 180) +#define RAD2DEG (180 / M_PI) +#define DEG2RAD (M_PI / 180) int32 LogicHErace::op_1003(int32 *args) { int value = args[2] ? args[2] : 1; @@ -457,7 +457,7 @@ void LogicHEfunshop::op_1004(int32 *args) { sq = sqrt(data[i + 1] * data[i + 1] + data[i] * data[i]); if (at <= 0) - at += 2 * PI; + at += 2 * M_PI; data[i] = cos(at + a1) * sq; data[i + 1] = sin(at + a1) * sq; @@ -823,8 +823,18 @@ int LogicHEsoccer::versionID() { } LogicHEsoccer::LogicHEsoccer(ScummEngine_v90he *vm) : LogicHE(vm) { - // Originally it used 0x1b0d bytes _userDataD = (double *)calloc(1732, sizeof(double)); + _intArray1 = 0; + _intArray2 = 0; + _intArraysAllocated = false; + _array1013 = 0; + _array1013Allocated = false; +} + +LogicHEsoccer::~LogicHEsoccer() { + free(_userDataD); + op_1020(); // clear int arrays + delete[] _array1013; } int32 LogicHEsoccer::dispatch(int op, int numArgs, int32 *args) { @@ -843,6 +853,37 @@ int32 LogicHEsoccer::dispatch(int op, int numArgs, int32 *args) { res = op_1004(args); break; + case 1006: + res = op_1006(args[0], args[1], args[2], args[3]); + break; + + case 1011: + // args[4] is ignored! + // soccer passes the argument, but then ends up not using it + // Makes sense that they removed it for soccermls + res = op_1011(args[0], args[1], args[2], args[3], args[5]); + break; + + case 1012: + res = op_1012(args); + break; + + case 1013: + res = op_1013(args[0], args[1], args[2]); + break; + + case 1019: + res = op_1019(args); + break; + + case 1020: + res = op_1020(); + break; + + case 1021: + res = op_1021(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + break; + case 8221968: // Someone had a fun and used his birthday as opcode number res = getFromArray(args[0], args[1], args[2]); @@ -856,6 +897,32 @@ int32 LogicHEsoccer::dispatch(int op, int numArgs, int32 *args) { return res; } +void LogicHEsoccer::beforeBootScript() { + if (_intArraysAllocated) + op_1020(); + + _userDataD[530] = 0; +} + +void LogicHEsoccer::initOnce() { + // The original sets some paths here that we don't need to worry about + _array1013Allocated = false; + _userDataD[530] = 0; +} + +int LogicHEsoccer::startOfFrame() { + // This variable is some sort of flag that activates this mode + int res = (int)_userDataD[530]; + + // _userDataD[535] is not used! + // soccer passes the argument, but then ends up not using it + // Makes sense that they removed it for soccermls + if (res) + res = op_1011((int)_userDataD[531], (int)_userDataD[532], (int)_userDataD[533], (int)_userDataD[534], (int)_userDataD[536]); + + return res; +} + int LogicHEsoccer::op_1001(int32 *args) { return (int)(args[0] * sin((float)args[1])); } @@ -901,16 +968,16 @@ int LogicHEsoccer::op_1004(int32 *args) { return 1; } -int LogicHEsoccer::op_1006(int32 *args) { - double a1 = args[1] * 0.01; - double a2 = args[2] * 0.01; - double a3 = args[3] * 0.01; +int LogicHEsoccer::op_1006(int32 a1, int32 a2, int32 a3, int32 a4) { + double v1 = a1 * 0.01; + double v2 = a2 * 0.01; + double v3 = a3 * 0.01; double var108, var109; - _userDataD[529] = args[4]; + _userDataD[529] = a4; - var108 = atan2(a1, a3) * _userDataD[523] - args[4]; - var109 = _userDataD[526] - _userDataD[528] + (_userDataD[521] - atan2(_userDataD[524] - a2, a3)) * _userDataD[522]; + var108 = atan2(v1, v3) * _userDataD[523] - a4; + var109 = _userDataD[526] - _userDataD[528] + (_userDataD[521] - atan2(_userDataD[524] - v2, v3)) * _userDataD[522]; writeScummVar(108, (int32)var108); writeScummVar(109, (int32)var109); @@ -919,37 +986,358 @@ int LogicHEsoccer::op_1006(int32 *args) { } int LogicHEsoccer::op_1007(int32 *args) { - // TODO: Used when the HE logo is shown + // Used when the HE logo is shown + // This initializes the _userDataD fields that are used in op_1006/op_1011 + + _intArraysAllocated = false; + double v14 = (double)args[0] * 0.01; + double v13 = (double)args[2] * 0.01; + _userDataD[524] = v14; + double v12 = atan2(v13, v14); + _userDataD[520] = v12; + double v15 = atan2(v13 - (double)args[4] * 0.01, (double)args[3] * 0.01); + double v19 = v15 * 2.0; + double v17 = atan2(v13 - (double)args[4] * 0.01, v14); + _userDataD[519] = v19; + _userDataD[521] = v17; + _userDataD[525] = (v17 - v12) * 2.0; + _userDataD[527] = (double)args[5]; + _userDataD[526] = (double)args[6]; + _userDataD[528] = (double)args[7]; + _userDataD[522] = _userDataD[526] / _userDataD[525]; + _userDataD[523] = _userDataD[527] / _userDataD[519]; + _userDataD[518] = v13; + + // Clear both byte arrays + memset(_byteArray1, 0, 4096); + memset(_byteArray2, 0, 585); + + if (_array1013Allocated == 0 ) + op_1013(4, args[8], args[9]); return 1; } +// Returns the square root of the sum of the squares of the arguments +static inline double sqrtSquare(double a1, double a2, double a3) { + return sqrt(a1 * a1 + a2 * a2 + a3 * a3); +} + int LogicHEsoccer::op_1008(int32 *args) { // TODO: Used during a match (kicking?) return 1; } +int LogicHEsoccer::op_1011(int32 a1, int32 a2, int32 a3, int32 a4, int32 a5) { + // This is called on each frame by startOfFrame() if activated by op_1012. + // This seems to do player placement! + + float v28 = 0.0; + + for (int i = 0; i < 18; i++) { + // These seem to be some sort of percent? of angles? + int v32 = getFromArray(a1, i, 0); + int v6 = getFromArray(a1, i, 1); + int v30 = getFromArray(a1, i, 2); + + float v29 = (double)v32 / 100.0; + v28 = (double)v6 / 100.0; + float v31 = (double)v30 / 100.0; + + if (i < 13) { + int v25 = ((v32 + 2760) / 500 >= 0) ? ((v32 + 2750) / 500) : 0; + int v24 = 10; + + if (v25 <= 10) { + int v23 = 0; + if ((v32 + 2750) / 500 >= 0) + v23 = (v32 + 2750) / 500; + + v24 = v23; + } + + int v22 = 0; + if ((9219 - v30) / 500 >= 0) + v22 = (9219 - v30) / 500; + + int v21 = 6; + if (v22 <= 6) { + int v20 = 0; + if ((9219 - v30) / 500 >= 0) + v20 = (9219 - v30) / 500; + v21 = v20; + } + + if (a5) + putInArray(a5, 0, i, v24 + 11 * v21); + } + + float v7 = atan2(_userDataD[524] - v28, (double)v31); + int v8 = (int)(_userDataD[526] - (_userDataD[521] - v7) * _userDataD[522] + 300.0); + + double v9 = atan2(_userDataD[523], (double)v31); + // x/y position? + putInArray(a2, i, 0, (int32)(v29 * v9 + 640.0)); + putInArray(a2, i, 1, v8); + + double v10 = atan2(_userDataD[524], (double)v31); + int v12 = (int)(_userDataD[526] - (_userDataD[521] - (float)v10) * _userDataD[522] + 300.0); + double v13 = _userDataD[523]; + + v29 = atan2(v29, v31); + // x/y position? + putInArray(a2, i + 22, 0, (int32)(v29 * v13 + 640.0)); + putInArray(a2, i + 22, 1, v12); + } + + // soccer only uses one array here + // soccermls/soccer2004 use four + int start = (_vm->_game.id == GID_SOCCER) ? 19 : 18; + int end = (_vm->_game.id == GID_SOCCER) ? 19 : 21; + + for (int i = start; i <= end; i++) { + int v14 = getFromArray(a2, i, 0); + int v15 = getFromArray(a2, i, 1); + + // This retains v28 from (i == 17)? + float v16 = _userDataD[524] - v28; + float v17 = v16 / tan((_userDataD[528] + v15 - _userDataD[526]) / (_userDataD[522] + _userDataD[521])); + double v18 = tan((double)(v14 - 640) / _userDataD[523]) * v17; + putInArray(a1, i, 0, (int)(v18 * 100.0)); + putInArray(a1, i, 2, (int)(v17 * 100.0)); + } + + op_1011_sub(a1, a3, a4, a4); + + return 1; +} + +static inline int distance(int a1, int a2, int a3, int a4) { + return (int)sqrt((double)((a4 - a3) * (a4 - a3) + (a2 - a1) * (a2 - a1))); +} + +void LogicHEsoccer::op_1011_sub(int32 a1, int32 a2, int32 a3, int32 a4) { + // As you can guess, this is called from op_1011 + // This seems to be checking distances between the players and the ball + // and which distance is the shortest. + + int v6[13]; + int v7[13]; + int v8[13]; + int v18[195]; + + for (int i = 0; i < 13; i++) { + v6[i] = 0; + v7[i] = getFromArray(a1, i, 0); + v8[i] = getFromArray(a1, i, 2); + } + + // 12 here, 13 up there + // Probably 12 for players, 13 for players+ball + for (int i = 0; i < 12; i++) { + int v22 = a4; + for (int j = i + 1; j < 13; j++) { + v18[i * 15 + j] = distance(v7[i], v7[j], v8[i], v8[j]); + putInArray(a2, i, j, v18[i * 15 + j]); + putInArray(a2, j, i, v18[i * 15 + j]); + if (v18[i * 15 + j] < v22) { + v22 = v18[i * 15 + j]; + v6[i] = j + 1; + v6[j] = i + 1; + } + } + } + + int v13 = getFromArray(a1, 18, 0); + int v14 = getFromArray(a1, 18, 2); + int v15 = getFromArray(a1, 19, 0); + int v16 = getFromArray(a1, 19, 2); + int v19[15]; + int v20[15]; + + if (_vm->_game.id == GID_SOCCER) { + // soccer gets to be different + for (int i = 0; i < 13; i++) + v20[i] = distance(v13, v7[i], v14, v8[i]); + + for (int i = 0; i < 13; i++) + v19[i] = distance(v15, v7[i], v16, v8[i]); + } else { + // soccermls and soccer2004 use two other arrays here + int v9 = getFromArray(a1, 20, 0); + int v10 = getFromArray(a1, 20, 2); + int v11 = getFromArray(a1, 21, 0); + int v12 = getFromArray(a1, 21, 2); + + for (int i = 0; i < 6; i++) { + v20[i] = distance(v9, v7[i], v10, v8[i]); + v19[i] = distance(v13, v7[i], v14, v8[i]); + } + + for (int i = 6; i < 13; i++) { + v20[i] = distance(v11, v7[i], v12, v8[i]); + v19[i] = distance(v15, v7[i], v16, v8[i]); + } + } + + for (int i = 0; i < 13; i++) { + putInArray(a2, 14, i, v20[i]); + putInArray(a2, i, 14, v20[i]); + putInArray(a2, 13, i, v19[i]); + putInArray(a2, i, 13, v19[i]); + putInArray(a3, 0, i, v6[i]); + } +} + int LogicHEsoccer::op_1012(int32 *args) { - // TODO: Used after op_1019 + // Used after op_1019 + // This function activates startOfFrame() to call op_1011 + // (Possibly field parameters?) + + _userDataD[530] = (args[0] != 0) ? 1 : 0; + _userDataD[531] = args[1]; + _userDataD[532] = args[2]; + _userDataD[533] = args[3]; + _userDataD[534] = args[4]; + _userDataD[535] = args[5]; // unused!!! + _userDataD[536] = args[6]; + + return 1; +} + +// Some strange power operation, ignores negative exponents +static inline double u32Pow(float a1, int a2) { + if (a2 < 0) + return 0.0; + + float v4 = 1.0; + + for (int i = 1; i <= a2; i++) + v4 *= a1; + + return v4; +} + +int LogicHEsoccer::op_sub5(int a1, int a2, int a3) { + byte *v9 = _array1013 + 44 * a2; + + *((uint32 *)v9 + 4) = a3; + *((uint32 *)v9) = a2; + + if (a1 > 2) { + // Casual observation: 585 is also the size of _byteArray2 + *((uint32 *)v9 + 40) = 8 * a2 - 585; + for (int i = 0; i < 8; i++) + *((uint32 *)v9 + 4 * i + 8) = 0xffffffff; + } else { + for (int i = 0; i < 8; i++) + *((uint32 *)v9 + 4 * i + 8) = op_sub5(a1 + 1, i + 8 * a2 + 1, a2); + } + + return a2; +} + +int LogicHEsoccer::op_1013(int32 a1, int32 a2, int32 a3) { + // Creates _array1013 for *some* purpose + // _array1013Temp is used again op_1014 for some reason... + // Seems to be used in op_1015 + + int v4 = (int)((1.0 - u32Pow(8.0, 4)) / -7.0); + + _array1013 = new byte[v4 * 44]; + memset(_array1013, 0, v4 * 44); + _array1013Allocated = true; + memset(_array1013Temp, 0, 44); + + for (int i = 0; i < 8; i++) + _array1013Temp[i + 2] = op_sub5(1, i + 1, 0); + + // Yes, this is not endian-safe, but should not matter since we're + // not saving/loading the data anywhere + memcpy(_array1013, _array1013Temp, 44); return 1; } -int LogicHEsoccer::op_1014(int32 *args) { +int LogicHEsoccer::op_1014(int32 a1, int32 a2, int32 a3, int32 a4, int32 a5, int32 a6, int32 a7, int32 a8, int32 a9, int32 a10, int32 a11, int32 a12, int32 a13, int32 a14) { // TODO: Used many times during a match + // And called from op_1008! return 1; } int LogicHEsoccer::op_1019(int32 *args) { - // TODO: Used at the beginning of a match + // Used at the beginning of a match + // Initializes some arrays. Player positions? + + // These two arrays are used in op_1014 and op_1015 + for (int i = 0; i < 4096; i++) + _byteArray1[i] = getFromArray(args[1], 0, i); + + for (int i = 0; i < 585; i++) + _byteArray2[i] = getFromArray(args[0], 0, i); + + // Deallocate the two integer arrays + if (_intArraysAllocated) + op_1020(); + + // Reallocate them + _intArray1 = new uint32[1008]; + _intArray2 = new uint32[168]; + _intArraysAllocated = true; + + memset(_intArray1, 0, 4 * 4); + memset(_intArray2, 0, 24 * 4); + + // These two arrays are used in op_1015 + for (int i = 0; i < 42; i++) { + for (int j = 0; j < 24; j++) + _intArray1[j + 24 * i] = getFromArray(args[3], 0, j + 24 * i); + + for (int j = 0; j < 4; j++) + _intArray2[j + 4 * i] = getFromArray(args[2], 0, j + 4 * i); + } + + return 1; +} + +int LogicHEsoccer::op_1020() { + // Deallocate integer arrays + // The arrays can be allocated in op_1015 or op_1019 + + delete[] _intArray1; _intArray1 = 0; + delete[] _intArray2; _intArray2 = 0; + _intArraysAllocated = false; return 1; } -int LogicHEsoccer::op_1021(int32 *args) { - // TODO: Used during a match (ball movement?) +int LogicHEsoccer::op_1021(int32 a1, int32 a2, int32 a3, int32 a4, int32 a5, int32 a6, int32 a7) { + // Used during a match (ball movement?) + // Also called from op_1008 + + int v10; + if (a4 && a5) + v10 = (int)(((double)a2 - (double)a5 * (double)a1 / (double)a4) * -1.0 * (double)a4 / (double)a5); + else + v10 = a1; + + int v9; + if (a6 && a5) + v9 = (int)(((double)a2 - (double)a5 * (double)a3 / (double)a6) * -1.0 * (double)a6 / (double)a5); + else + v9 = a3; + + // The final argument chooses whether to store the results for op_1008 or + // store them in SCUMM variables. + if (a7) { + _var1021[0] = v10; + _var1021[1] = v9; + } else { + writeScummVar(108, v10); + writeScummVar(109, v9); + } return 1; } diff --git a/engines/scumm/he/logic_he.h b/engines/scumm/he/logic_he.h index ab952abd5e..d097d37e75 100644 --- a/engines/scumm/he/logic_he.h +++ b/engines/scumm/he/logic_he.h @@ -41,9 +41,9 @@ public: int getFromArray(int arg0, int idx2, int idx1); void putInArray(int arg0, int idx2, int idx1, int val); - void beforeBootScript() {} - void initOnce() {} - void startOfFrame() {} + virtual void beforeBootScript() {} + virtual void initOnce() {} + virtual int startOfFrame() { return 1; } void endOfFrame() {} void processKeyStroke(int keyPressed) {} @@ -115,22 +115,52 @@ private: public: LogicHEsoccer(ScummEngine_v90he *vm); + ~LogicHEsoccer(); int versionID(); int32 dispatch(int op, int numArgs, int32 *args); + void beforeBootScript(); + void initOnce(); + int startOfFrame(); + private: int op_1001(int32 *args); int op_1002(int32 *args); int op_1003(int32 *args); int op_1004(int32 *args); - int op_1006(int32 *args); + int op_1006(int32 a1, int32 a2, int32 a3, int32 a4); int op_1007(int32 *args); int op_1008(int32 *args); + int op_1011(int32 a1, int32 a2, int32 a3, int32 a4, int32 a5); int op_1012(int32 *args); - int op_1014(int32 *args); + int op_1013(int32 a1, int32 a2, int32 a3); + int op_1014(int32 a1, int32 a2, int32 a3, int32 a4, int32 a5, int32 a6, int32 a7, int32 a8, int32 a9, int32 a10, int32 a11, int32 a12, int32 a13, int32 a14); int op_1019(int32 *args); - int op_1021(int32 *args); + int op_1020(); + int op_1021(int32 a1, int32 a2, int32 a3, int32 a4, int32 a5, int32 a6, int32 a7); + + // Two integer arrays are used between some functions + // Originally, these pointers were in _userData, but we keep them separate + // Also, doing it that would break things on non 32-bit systems... + bool _intArraysAllocated; + uint32 *_intArray1, *_intArray2; + + // op_1007 allocates some arrays + // they're then filled by op_1019 + byte _byteArray1[4096], _byteArray2[585]; + + // op_1011 has a subfunction + void op_1011_sub(int32 a1, int32 a2, int32 a3, int32 a4); + + // op_1013 creates some array, purpose unknown + bool _array1013Allocated; + byte *_array1013; + uint32 _array1013Temp[11]; + int op_sub5(int a1, int a2, int a3); + + // op_1021 can (optionally) set two variables for use in op_1008 + uint32 _var1021[2]; }; class LogicHEbaseball2001 : public LogicHE { diff --git a/engines/scumm/he/palette_he.cpp b/engines/scumm/he/palette_he.cpp index b42d6e97e2..49e43a040b 100644 --- a/engines/scumm/he/palette_he.cpp +++ b/engines/scumm/he/palette_he.cpp @@ -26,6 +26,7 @@ #ifdef ENABLE_HE #include "common/system.h" +#include "graphics/palette.h" #include "scumm/scumm.h" #include "scumm/he/intern_he.h" #include "scumm/resource.h" @@ -192,7 +193,7 @@ void ScummEngine_v90he::setHEPaletteFromCostume(int palSlot, int resId) { assertRange(1, palSlot, _numPalettes, "palette"); const uint8 *data = getResourceAddress(rtCostume, resId); assert(data); - const uint8 *rgbs = findResourceData(MKID_BE('RGBS'), data); + const uint8 *rgbs = findResourceData(MKTAG('R','G','B','S'), data); assert(rgbs); setHEPaletteFromPtr(palSlot, rgbs); } @@ -202,7 +203,7 @@ void ScummEngine_v90he::setHEPaletteFromImage(int palSlot, int resId, int state) assertRange(1, palSlot, _numPalettes, "palette"); uint8 *data = getResourceAddress(rtImage, resId); assert(data); - const uint8 *rgbs = findWrappedBlock(MKID_BE('RGBS'), data, state, 0); + const uint8 *rgbs = findWrappedBlock(MKTAG('R','G','B','S'), data, state, 0); if (rgbs) setHEPaletteFromPtr(palSlot, rgbs); } @@ -212,7 +213,7 @@ void ScummEngine_v90he::setHEPaletteFromRoom(int palSlot, int resId, int state) assertRange(1, palSlot, _numPalettes, "palette"); const uint8 *data = getResourceAddress(rtRoom, resId); assert(data); - const uint8 *pals = findResourceData(MKID_BE('PALS'), data); + const uint8 *pals = findResourceData(MKTAG('P','A','L','S'), data); assert(pals); const uint8 *rgbs = findPalInPals(pals, state); assert(rgbs); diff --git a/engines/scumm/he/resource_he.cpp b/engines/scumm/he/resource_he.cpp index 72e7052034..ecb094f29b 100644 --- a/engines/scumm/he/resource_he.cpp +++ b/engines/scumm/he/resource_he.cpp @@ -4,10 +4,6 @@ * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * - * Parts of this code are heavily based on: - * icoutils - A set of programs dealing with MS Windows icons and cursors. - * Copyright (C) 1998-2001 Oskar Liljeblad - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 @@ -36,6 +32,7 @@ #include "audio/decoders/wave.h" #include "graphics/cursorman.h" +#include "graphics/wincursor.h" #include "common/archive.h" #include "common/memstream.h" @@ -43,14 +40,6 @@ namespace Scumm { -#if defined(SCUMM_LITTLE_ENDIAN) -#define LE16(x) -#define LE32(x) -#elif defined(SCUMM_BIG_ENDIAN) -#define LE16(x) ((x) = TO_LE_16(x)) -#define LE32(x) ((x) = TO_LE_32(x)) -#endif - ResExtractor::ResExtractor(ScummEngine_v70he *scumm) : _vm(scumm) { @@ -65,1092 +54,112 @@ ResExtractor::~ResExtractor() { free(cc->palette); } } + memset(_cursorCache, 0, sizeof(_cursorCache)); } ResExtractor::CachedCursor *ResExtractor::findCachedCursor(int id) { - for (int i = 0; i < MAX_CACHED_CURSORS; ++i) { - CachedCursor *cc = &_cursorCache[i]; - if (cc->valid && cc->id == id) { - return cc; - } - } + for (int i = 0; i < MAX_CACHED_CURSORS; ++i) + if (_cursorCache[i].valid && _cursorCache[i].id == id) + return &_cursorCache[i]; + return NULL; } ResExtractor::CachedCursor *ResExtractor::getCachedCursorSlot() { - uint32 min_last_used = 0; + uint32 minLastUsed = 0; CachedCursor *r = NULL; + for (int i = 0; i < MAX_CACHED_CURSORS; ++i) { CachedCursor *cc = &_cursorCache[i]; - if (!cc->valid) { + if (!cc->valid) return cc; - } else { - if (min_last_used == 0 || cc->last_used < min_last_used) { - min_last_used = cc->last_used; - r = cc; - } + + if (minLastUsed == 0 || cc->lastUsed < minLastUsed) { + minLastUsed = cc->lastUsed; + r = cc; } } + assert(r); - free(r->bitmap); - free(r->palette); + delete[] r->bitmap; + delete[] r->palette; memset(r, 0, sizeof(CachedCursor)); return r; } void ResExtractor::setCursor(int id) { - byte *cursorRes = 0; - int cursorsize; - int keycolor = 0; CachedCursor *cc = findCachedCursor(id); + if (cc != NULL) { debug(7, "Found cursor %d in cache slot %lu", id, (long)(cc - _cursorCache)); } else { cc = getCachedCursorSlot(); assert(cc && !cc->valid); - cursorsize = extractResource(id, &cursorRes); - convertIcons(cursorRes, cursorsize, &cc->bitmap, &cc->w, &cc->h, &cc->hotspot_x, &cc->hotspot_y, &keycolor, &cc->palette, &cc->palSize); + + if (!extractResource(id, cc)) + error("Could not extract cursor %d", id); + debug(7, "Adding cursor %d to cache slot %lu", id, (long)(cc - _cursorCache)); - free(cursorRes); + cc->valid = true; cc->id = id; - cc->last_used = g_system->getMillis(); + cc->lastUsed = g_system->getMillis(); } if (cc->palette) CursorMan.replaceCursorPalette(cc->palette, 0, cc->palSize); - _vm->setCursorHotspot(cc->hotspot_x, cc->hotspot_y); - _vm->setCursorFromBuffer(cc->bitmap, cc->w, cc->h, cc->w); + _vm->setCursorHotspot(cc->hotspotX, cc->hotspotY); + _vm->setCursorFromBuffer(cc->bitmap, cc->width, cc->height, cc->width); } -/* - * Static variables - */ -const char *res_types[] = { - /* 0x01: */ - "cursor", "bitmap", "icon", "menu", "dialog", "string", - "fontdir", "font", "accelerator", "rcdata", "messagelist", - "group_cursor", NULL, "group_icon", NULL, - /* the following are not defined in winbase.h, but found in wrc. */ - /* 0x10: */ - "version", "dlginclude", NULL, "plugplay", "vxd", - "anicursor", "aniicon" -}; -#define RES_TYPE_COUNT (sizeof(res_types)/sizeof(char *)) - Win32ResExtractor::Win32ResExtractor(ScummEngine_v70he *scumm) : ResExtractor(scumm) { } -int Win32ResExtractor::extractResource(int resId, byte **data) { - char buf[20]; - - snprintf(buf, sizeof(buf), "%d", resId); - - return extractResource_("group_cursor", buf, data); -} - -int Win32ResExtractor::extractResource_(const char *resType, char *resName, byte **data) { - char *arg_language = NULL; - const char *arg_type = resType; - char *arg_name = resName; - int ressize = 0; - - _arg_raw = false; - - /* translate --type option from resource type string to integer */ - arg_type = res_type_string_to_id(arg_type); - - WinLibrary fi; - - /* initiate stuff */ - fi.memory = NULL; - fi.file = NULL; - +bool Win32ResExtractor::extractResource(int id, CachedCursor *cc) { if (_fileName.empty()) { // We are running for the first time _fileName = _vm->generateFilename(-3); - } - - /* get file size */ - fi.file = SearchMan.createReadStreamForMember(_fileName); - if (!fi.file) { - error("Cannot open file %s", _fileName.c_str()); - } - - fi.total_size = fi.file->size(); - if (fi.total_size == -1) { - error("Cannot get size of file %s", _fileName.c_str()); - goto cleanup; - } - if (fi.total_size == 0) { - error("%s: file has a size of 0", _fileName.c_str()); - goto cleanup; - } - - /* read all of file */ - fi.memory = (byte *)malloc(fi.total_size); - if (fi.file->read(fi.memory, fi.total_size) == 0) { - error("Cannot read from file %s", _fileName.c_str()); - goto cleanup; - } - - /* identify file and find resource table */ - if (!read_library(&fi)) { - /* error reported by read_library */ - goto cleanup; - } - - /* errors will be printed by the callback */ - ressize = do_resources(&fi, arg_type, arg_name, arg_language, data); - - /* free stuff and close file */ - cleanup: - delete fi.file; - free(fi.memory); - - return ressize; -} - - -/** - * Translate a numeric resource type to it's corresponding string type. - * (For informative-ness.) - */ -const char *Win32ResExtractor::res_type_id_to_string(int id) { - if (id == 241) - return "toolbar"; - if (id > 0 && id <= (int)RES_TYPE_COUNT) - return res_types[id-1]; - return NULL; -} - -/** - * Translate a resource type string to integer. - * (Used to convert the --type option.) - */ -const char *Win32ResExtractor::res_type_string_to_id(const char *type) { - static const char *res_type_ids[] = { - "-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "-9", "-10", - "-11", "-12", NULL, "-14", NULL, "-16", "-17", NULL, "-19", - "-20", "-21", "-22" - }; - int c; - - if (type == NULL) - return NULL; - - for (c = 0; c < (int)RES_TYPE_COUNT; c++) { - if (res_types[c] != NULL && !scumm_stricmp(type, res_types[c])) - return res_type_ids[c]; - } - - return type; -} - -/** - * Return the resource id quoted if it is a string, otherwise (i.e. if - * it is numeric) just return it. - */ -Common::String Win32ResExtractor::WinResource::getQuotedResourceId() const { - if (numeric_id || id[0] == '\0') - return id; - return '"' + Common::String(id) + '"'; -} - -int Win32ResExtractor::extract_resources(WinLibrary *fi, WinResource *wr, - WinResource *type_wr, WinResource *name_wr, - WinResource *lang_wr, byte **data) { - int size; - bool free_it; - const char *type; - int32 id; - - if (*data) { - error("Win32ResExtractor::extract_resources() more than one cursor"); - return 0; - } - - *data = extract_resource(fi, wr, &size, &free_it, type_wr->id, (lang_wr == NULL ? NULL : lang_wr->id), _arg_raw); - - if (data == NULL) { - error("Win32ResExtractor::extract_resources() problem with resource extraction"); - return 0; - } - - /* get named resource type if possible */ - type = NULL; - if ((id = strtol(type_wr->id, 0, 10)) != 0) - type = res_type_id_to_string(id); - - if (lang_wr != NULL && lang_wr->id[0] != '\0') { - debugC(DEBUG_RESOURCE, "extractCursor(). Found cursor name: %s language: %s [size=%d]", - name_wr->getQuotedResourceId().c_str(), lang_wr->getQuotedResourceId().c_str(), size); - } else { - debugC(DEBUG_RESOURCE, "extractCursor(). Found cursor name: %s [size=%d]", - name_wr->getQuotedResourceId().c_str(), size); - } - return size; -} - -/** - * Extract a resource, returning pointer to data. - */ -byte *Win32ResExtractor::extract_resource(WinLibrary *fi, WinResource *wr, int *size, - bool *free_it, char *type, char *lang, bool raw) { - char *str; - int32 intval; - - /* just return pointer to data if raw */ - if (raw) { - *free_it = false; - /* get_resource_entry will print possible error */ - return get_resource_entry(fi, wr, size); - } - - /* find out how to extract */ - str = type; - if (str != NULL && (intval = strtol(STRIP_RES_ID_FORMAT(str), 0, 10))) { - if (intval == (int)RT_GROUP_ICON) { - *free_it = true; - return extract_group_icon_cursor_resource(fi, wr, lang, size, true); - } - if (intval == (int)RT_GROUP_CURSOR) { - *free_it = true; - return extract_group_icon_cursor_resource(fi, wr, lang, size, false); - } - } - - return NULL; -} - -/** - * Create a complete RT_GROUP_ICON resource, that can be written to - * an `.ico' file without modifications. Returns an allocated - * memory block that should be freed with free() once used. - * - * `root' is the offset in file that specifies the resource. - * `base' is the offset that string pointers are calculated from. - * `ressize' should point to an integer variable where the size of - * the returned memory block will be placed. - * `is_icon' indicates whether resource to be extracted is icon - * or cursor group. - */ -byte *Win32ResExtractor::extract_group_icon_cursor_resource(WinLibrary *fi, WinResource *wr, char *lang, - int *ressize, bool is_icon) { - Win32CursorIconDir *icondir; - Win32CursorIconFileDir *fileicondir; - byte *memory; - int c, offset, skipped; - int size; - - /* get resource data and size */ - icondir = (Win32CursorIconDir *)get_resource_entry(fi, wr, &size); - if (icondir == NULL) { - /* get_resource_entry will print error */ - return NULL; - } - - /* calculate total size of output file */ - RETURN_IF_BAD_POINTER(NULL, icondir->count); - skipped = 0; - for (c = 0; c < FROM_LE_16(icondir->count); c++) { - int level; - int iconsize; - char name[14]; - WinResource *fwr; - - RETURN_IF_BAD_POINTER(NULL, icondir->entries[c]); - /*debug("%d. bytes_in_res=%d width=%d height=%d planes=%d bit_count=%d", c, - FROM_LE_32(icondir->entries[c].bytes_in_res), - (is_icon ? icondir->entries[c].res_info.icon.width : FROM_LE_16(icondir->entries[c].res_info.cursor.width)), - (is_icon ? icondir->entries[c].res_info.icon.height : FROM_LE_16(icondir->entries[c].res_info.cursor.height)), - FROM_LE_16(icondir->entries[c].plane_count), - FROM_LE_16(icondir->entries[c].bit_count));*/ - - /* find the corresponding icon resource */ - snprintf(name, sizeof(name)/sizeof(char), "-%d", FROM_LE_16(icondir->entries[c].res_id)); - fwr = find_resource(fi, (is_icon ? "-3" : "-1"), name, lang, &level); - if (fwr == NULL) { - error("%s: could not find `%s' in `%s' resource.", - _fileName.c_str(), &name[1], (is_icon ? "group_icon" : "group_cursor")); - return NULL; - } - - if (get_resource_entry(fi, fwr, &iconsize) != NULL) { - if (iconsize == 0) { - debugC(DEBUG_RESOURCE, "%s: icon resource `%s' is empty, skipping", _fileName.c_str(), name); - skipped++; - continue; - } - if ((uint32)iconsize != FROM_LE_32(icondir->entries[c].bytes_in_res)) { - debugC(DEBUG_RESOURCE, "%s: mismatch of size in icon resource `%s' and group (%d != %d)", - _fileName.c_str(), name, iconsize, FROM_LE_32(icondir->entries[c].bytes_in_res)); - } - size += iconsize; /* size += FROM_LE_32(icondir->entries[c].bytes_in_res); */ - /* cursor resources have two additional WORDs that contain - * hotspot info */ - if (!is_icon) - size -= sizeof(uint16)*2; - } - } - offset = sizeof(Win32CursorIconFileDir) + (FROM_LE_16(icondir->count)-skipped) * sizeof(Win32CursorIconFileDirEntry); - size += offset; - *ressize = size; - - /* allocate that much memory */ - memory = (byte *)malloc(size); - fileicondir = (Win32CursorIconFileDir *)memory; - - /* transfer Win32CursorIconDir structure members */ - fileicondir->reserved = icondir->reserved; - fileicondir->type = icondir->type; - fileicondir->count = TO_LE_16(FROM_LE_16(icondir->count) - skipped); - - /* transfer each cursor/icon: Win32CursorIconDirEntry and data */ - skipped = 0; - for (c = 0; c < FROM_LE_16(icondir->count); c++) { - int level; - char name[14]; - WinResource *fwr; - byte *data; - - /* find the corresponding icon resource */ - snprintf(name, sizeof(name)/sizeof(char), "-%d", FROM_LE_16(icondir->entries[c].res_id)); - fwr = find_resource(fi, (is_icon ? "-3" : "-1"), name, lang, &level); - if (fwr == NULL) { - error("%s: could not find `%s' in `%s' resource.", - _fileName.c_str(), &name[1], (is_icon ? "group_icon" : "group_cursor")); - return NULL; - } - - /* get data and size of that resource */ - data = (byte *)get_resource_entry(fi, fwr, &size); - if (data == NULL) { - /* get_resource_entry has printed error */ - return NULL; - } - if (size == 0) { - skipped++; - continue; - } - - /* copy ICONDIRENTRY (not including last dwImageOffset) */ - memcpy(&fileicondir->entries[c-skipped], &icondir->entries[c], - sizeof(Win32CursorIconFileDirEntry)-sizeof(uint32)); - - /* special treatment for cursors */ - if (!is_icon) { - fileicondir->entries[c-skipped].width = icondir->entries[c].res_info.cursor.width; - fileicondir->entries[c-skipped].height = TO_LE_16(FROM_LE_16(icondir->entries[c].res_info.cursor.height) / 2); - fileicondir->entries[c-skipped].color_count = 0; - fileicondir->entries[c-skipped].reserved = 0; - } - - /* set image offset and increase it */ - fileicondir->entries[c-skipped].dib_offset = TO_LE_32(offset); - - /* transfer resource into file memory */ - if (is_icon) { - memcpy(&memory[offset], data, FROM_LE_32(icondir->entries[c].bytes_in_res)); - } else { - fileicondir->entries[c-skipped].hotspot_x = ((uint16 *) data)[0]; - fileicondir->entries[c-skipped].hotspot_y = ((uint16 *) data)[1]; - memcpy(&memory[offset], data+sizeof(uint16)*2, - FROM_LE_32(icondir->entries[c].bytes_in_res)-sizeof(uint16)*2); - offset -= sizeof(uint16)*2; - } - - /* increase the offset pointer */ - offset += FROM_LE_32(icondir->entries[c].bytes_in_res); + if (!_exe.loadFromEXE(_fileName)) + error("Cannot open file %s", _fileName.c_str()); } - return memory; -} - -/** - * Check if a chunk of data (determined by offset and size) - * is within the bounds of the WinLibrary file. - * Usually not called directly. - */ -bool Win32ResExtractor::check_offset(byte *memory, int total_size, const char *name, void *offset, int size) { - int need_size = (int)((byte *)offset - memory + size); - - debugC(DEBUG_RESOURCE, "check_offset: size=%x vs %x offset=%x size=%x", - need_size, total_size, (uint)((byte *)offset - memory), size); + Graphics::WinCursorGroup *group = Graphics::WinCursorGroup::createCursorGroup(_exe, id); - if (need_size < 0 || need_size > total_size) { - error("%s: premature end", name); + if (!group) return false; - } - - return true; -} - - -/** - * Do something for each resource matching type, name and lang. - */ -int Win32ResExtractor::do_resources(WinLibrary *fi, const char *type, char *name, char *lang, byte **data) { - WinResource *type_wr; - WinResource *name_wr; - WinResource *lang_wr; - int size; - - type_wr = (WinResource *)calloc(3, sizeof(WinResource)); - name_wr = type_wr + 1; - lang_wr = type_wr + 2; - - size = do_resources_recurs(fi, NULL, type_wr, name_wr, lang_wr, type, name, lang, data); - - free(type_wr); - - return size; -} - -/* what is each entry in this directory level for? type, name or language? */ -#define WINRESOURCE_BY_LEVEL(x) ((x)==0 ? type_wr : ((x)==1 ? name_wr : lang_wr)) - -/* does the id of this entry match the specified id? */ -#define LEVEL_MATCHES(x) (x == NULL || x ## _wr->id[0] == '\0' || compare_resource_id(x ## _wr, x)) -int Win32ResExtractor::do_resources_recurs(WinLibrary *fi, WinResource *base, - WinResource *type_wr, WinResource *name_wr, WinResource *lang_wr, - const char *type, char *name, char *lang, byte **data) { - int c, rescnt; - WinResource *wr; - uint32 size = 0; + Graphics::WinCursor *cursor = group->cursors[0].cursor; - /* get a list of all resources at this level */ - wr = list_resources(fi, base, &rescnt); - if (wr == NULL) { - return size; - } - - /* process each resource listed */ - for (c = 0; c < rescnt; c++) { - /* (over)write the corresponding WinResource holder with the current */ - memcpy(WINRESOURCE_BY_LEVEL(wr[c].level), wr+c, sizeof(WinResource)); - - /* go deeper unless there is something that does NOT match */ - if (LEVEL_MATCHES(type) && LEVEL_MATCHES(name) && LEVEL_MATCHES(lang)) { - if (wr->is_directory) - size = do_resources_recurs(fi, wr+c, type_wr, name_wr, lang_wr, type, name, lang, data); - else - size = extract_resources(fi, wr+c, type_wr, name_wr, lang_wr, data); - } - } - - /* since we're moving back one level after this, unset the - * WinResource holder used on this level */ - memset(WINRESOURCE_BY_LEVEL(wr[0].level), 0, sizeof(WinResource)); - - return size; -} - -bool Win32ResExtractor::compare_resource_id(WinResource *wr, const char *id) { - if (wr->numeric_id) { - int32 cmp1, cmp2; - if (id[0] == '+') - return false; - if (id[0] == '-') - id++; - cmp1 = strtol(wr->id, 0, 10); - cmp2 = strtol(id, 0, 10); - if (!cmp1 || !cmp2 || cmp1 != cmp2) - return false; - } else { - if (id[0] == '-') - return false; - if (id[0] == '+') - id++; - if (strcmp(wr->id, id)) - return false; - } + cc->bitmap = new byte[cursor->getWidth() * cursor->getHeight()]; + cc->width = cursor->getWidth(); + cc->height = cursor->getHeight(); + cc->hotspotX = cursor->getHotspotX(); + cc->hotspotY = cursor->getHotspotY(); - return true; -} + // Convert from the paletted format to the SCUMM palette + const byte *srcBitmap = cursor->getSurface(); -bool Win32ResExtractor::decode_pe_resource_id(WinLibrary *fi, WinResource *wr, uint32 value) { - if (value & IMAGE_RESOURCE_NAME_IS_STRING) { /* numeric id */ - int c, len; - uint16 *mem = (uint16 *) - (fi->first_resource + (value & ~IMAGE_RESOURCE_NAME_IS_STRING)); - - /* copy each char of the string, and terminate it */ - RETURN_IF_BAD_POINTER(false, *mem); - len = FROM_LE_16(mem[0]); - RETURN_IF_BAD_OFFSET(false, &mem[1], sizeof(uint16) * len); - - len = MIN(FROM_LE_16(mem[0]), (uint16)WINRES_ID_MAXLEN); - for (c = 0; c < len; c++) - wr->id[c] = FROM_LE_16(mem[c+1]) & 0x00FF; - wr->id[len] = '\0'; - wr->numeric_id = false; - } else { /* Unicode string id */ - /* translate id into a string */ - snprintf(wr->id, WINRES_ID_MAXLEN, "%d", value); - wr->numeric_id = true; + for (int i = 0; i < cursor->getWidth() * cursor->getHeight(); i++) { + if (srcBitmap[i] == cursor->getKeyColor()) // Transparent + cc->bitmap[i] = 255; + else if (srcBitmap[i] == 0) // Black + cc->bitmap[i] = 253; + else // White + cc->bitmap[i] = 254; } + delete group; return true; } -byte *Win32ResExtractor::get_resource_entry(WinLibrary *fi, WinResource *wr, int *size) { - byte *result; - - Win32ImageResourceDataEntry *dataent; - - dataent = (Win32ImageResourceDataEntry *) wr->children; - RETURN_IF_BAD_POINTER(NULL, *dataent); - *size = FROM_LE_32(dataent->size); - - result = fi->memory + FROM_LE_32(dataent->offset_to_data); - - RETURN_IF_BAD_OFFSET(NULL, result, *size); - - return result; -} - -Win32ResExtractor::WinResource *Win32ResExtractor::list_pe_resources(WinLibrary *fi, Win32ImageResourceDirectory *pe_res, int level, int *count) { - WinResource *wr; - int c, rescnt; - Win32ImageResourceDirectoryEntry *dirent - = (Win32ImageResourceDirectoryEntry *)(pe_res + 1); - - /* count number of `type' resources */ - RETURN_IF_BAD_POINTER(NULL, *dirent); - rescnt = FROM_LE_16(pe_res->number_of_named_entries) + FROM_LE_16(pe_res->number_of_id_entries); - *count = rescnt; - - /* allocate WinResource's */ - wr = (WinResource *)malloc(sizeof(WinResource) * rescnt); - - /* fill in the WinResource's */ - for (c = 0; c < rescnt; c++) { - RETURN_IF_BAD_POINTER(NULL, dirent[c]); - wr[c].this_ = pe_res; - wr[c].level = level; - wr[c].is_directory = ((FROM_LE_32(dirent[c].offset_to_data) & IMAGE_RESOURCE_DATA_IS_DIRECTORY) != 0); - wr[c].children = fi->first_resource + (FROM_LE_32(dirent[c].offset_to_data) & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY); - - /* fill in wr->id, wr->numeric_id */ - if (!decode_pe_resource_id(fi, wr + c, FROM_LE_32(dirent[c].name))) { - free(wr); - return NULL; - } - } - - return wr; -} - - -/** - * Return an array of WinResource's in the current - * resource level specified by _res-> - */ -Win32ResExtractor::WinResource *Win32ResExtractor::list_resources(WinLibrary *fi, WinResource *res, int *count) { - if (res != NULL && !res->is_directory) - return NULL; - - return list_pe_resources(fi, (Win32ImageResourceDirectory *) - (res == NULL ? fi->first_resource : res->children), - (res == NULL ? 0 : res->level+1), - count); -} - -/** - * Read header and get resource directory offset in a Windows library - * (AKA module). - */ -bool Win32ResExtractor::read_library(WinLibrary *fi) { - /* check for DOS header signature `MZ' */ - RETURN_IF_BAD_POINTER(false, MZ_HEADER(fi->memory)->magic); - if (FROM_LE_16(MZ_HEADER(fi->memory)->magic) == IMAGE_DOS_SIGNATURE) { - DOSImageHeader *mz_header = MZ_HEADER(fi->memory); - - RETURN_IF_BAD_POINTER(false, mz_header->lfanew); - - // Apply endian fix (currently only lfanew is used from the DOSImageHeader, - // so we don't bother to 'fix' the rest). - LE32(mz_header->lfanew); - - if (mz_header->lfanew < sizeof(DOSImageHeader)) { - error("%s: not a Windows library", _fileName.c_str()); - return false; - } - } - - /* check for NT header signature `PE' */ - RETURN_IF_BAD_POINTER(false, PE_HEADER(fi->memory)->signature); - if (FROM_LE_32(PE_HEADER(fi->memory)->signature) == IMAGE_NT_SIGNATURE) { - Win32ImageNTHeaders *pe_header; - int d; - - // Fix image header endianess - fix_win32_image_header_endian(PE_HEADER(fi->memory)); - - /* allocate new memory */ - fi->total_size = calc_vma_size(fi); - if (fi->total_size == 0) { - /* calc_vma_size has reported error */ - return false; - } - byte *ptr = (byte *)realloc(fi->memory, fi->total_size); - assert(ptr); - fi->memory = ptr; - - /* relocate memory, start from last section */ - pe_header = PE_HEADER(fi->memory); - RETURN_IF_BAD_POINTER(false, pe_header->file_header.number_of_sections); - - /* we don't need to do OFFSET checking for the sections. - * calc_vma_size has already done that */ - for (d = pe_header->file_header.number_of_sections - 1; d >= 0; d--) { - Win32ImageSectionHeader *pe_sec = PE_SECTIONS(fi->memory) + d; - - if (pe_sec->characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) - continue; - - //if (pe_sec->virtual_address + pe_sec->size_of_raw_data > fi->total_size) - - RETURN_IF_BAD_OFFSET(0, fi->memory + pe_sec->virtual_address, pe_sec->size_of_raw_data); - RETURN_IF_BAD_OFFSET(0, fi->memory + pe_sec->pointer_to_raw_data, pe_sec->size_of_raw_data); - if (FROM_LE_32(pe_sec->virtual_address) != pe_sec->pointer_to_raw_data) { - memmove(fi->memory + pe_sec->virtual_address, - fi->memory + pe_sec->pointer_to_raw_data, - pe_sec->size_of_raw_data); - } - } - - /* find resource directory */ - RETURN_IF_BAD_POINTER(false, pe_header->optional_header.data_directory[IMAGE_DIRECTORY_ENTRY_RESOURCE]); - Win32ImageDataDirectory *dir = pe_header->optional_header.data_directory + IMAGE_DIRECTORY_ENTRY_RESOURCE; - if (dir->size == 0) { - error("%s: file contains no resources", _fileName.c_str()); - return false; - } - - fix_win32_image_data_directory(dir); - - fi->first_resource = fi->memory + dir->virtual_address; - return true; - } - - /* other (unknown) header signature was found */ - error("%s: not a Windows library", _fileName.c_str()); - return false; -} - -/** - * Calculate the total amount of memory needed for a 32-bit Windows - * module. Returns -1 if file was too small. - */ -int Win32ResExtractor::calc_vma_size(WinLibrary *fi) { - Win32ImageSectionHeader *seg; - int c, segcount, size; - - size = 0; - RETURN_IF_BAD_POINTER(-1, PE_HEADER(fi->memory)->file_header.number_of_sections); - segcount = PE_HEADER(fi->memory)->file_header.number_of_sections; - - /* If there are no segments, just process file like it is. - * This is (probably) not the right thing to do, but problems - * will be delt with later anyway. - */ - if (segcount == 0) - return fi->total_size; - - seg = PE_SECTIONS(fi->memory); - RETURN_IF_BAD_POINTER(-1, *seg); - for (c = 0; c < segcount; c++) { - RETURN_IF_BAD_POINTER(0, *seg); - fix_win32_image_section_header(seg); - - size = MAX((uint32)size, seg->virtual_address + seg->size_of_raw_data); - /* I have no idea what misc.virtual_size is for... */ - size = MAX((uint32)size, seg->virtual_address + seg->misc.virtual_size); - seg++; - } - - return size; -} - -Win32ResExtractor::WinResource *Win32ResExtractor::find_with_resource_array(WinLibrary *fi, WinResource *wr, const char *id) { - int c, rescnt; - WinResource *return_wr; - - wr = list_resources(fi, wr, &rescnt); - if (wr == NULL) - return NULL; - - for (c = 0; c < rescnt; c++) { - if (compare_resource_id(&wr[c], id)) { - /* duplicate WinResource and return it */ - return_wr = (WinResource *)malloc(sizeof(WinResource)); - memcpy(return_wr, &wr[c], sizeof(WinResource)); - - /* free old WinResource */ - free(wr); - return return_wr; - } - } - - return NULL; -} - -Win32ResExtractor::WinResource *Win32ResExtractor::find_resource(WinLibrary *fi, const char *type, const char *name, const char *language, int *level) { - WinResource *wr; - - *level = 0; - if (type == NULL) - return NULL; - wr = find_with_resource_array(fi, NULL, type); - if (wr == NULL || !wr->is_directory) - return wr; - - *level = 1; - if (name == NULL) - return wr; - wr = find_with_resource_array(fi, wr, name); - if (wr == NULL || !wr->is_directory) - return wr; - - *level = 2; - if (language == NULL) - return wr; - wr = find_with_resource_array(fi, wr, language); - return wr; -} - -#define ROW_BYTES(bits) ((((bits) + 31) >> 5) << 2) - - -int Win32ResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h, - int *hotspot_x, int *hotspot_y, int *keycolor, byte **pal, int *palSize) { - Win32CursorIconFileDir dir; - Win32CursorIconFileDirEntry *entries = NULL; - uint32 offset; - uint32 c, d; - int completed; - int matched = 0; - Common::MemoryReadStream *in = new Common::MemoryReadStream(data, datasize); - - if (!in->read(&dir, sizeof(Win32CursorIconFileDir)- sizeof(Win32CursorIconFileDirEntry))) - goto cleanup; - fix_win32_cursor_icon_file_dir_endian(&dir); - - if (dir.reserved != 0) { - error("not an icon or cursor file (reserved non-zero)"); - goto cleanup; - } - if (dir.type != 1 && dir.type != 2) { - error("not an icon or cursor file (wrong type)"); - goto cleanup; - } - - entries = (Win32CursorIconFileDirEntry *)malloc(dir.count * sizeof(Win32CursorIconFileDirEntry)); - for (c = 0; c < dir.count; c++) { - if (!in->read(&entries[c], sizeof(Win32CursorIconFileDirEntry))) - goto cleanup; - fix_win32_cursor_icon_file_dir_entry_endian(&entries[c]); - if (entries[c].reserved != 0) - error("reserved is not zero"); - } - - offset = sizeof(Win32CursorIconFileDir) + (dir.count - 1) * (sizeof(Win32CursorIconFileDirEntry)); - - for (completed = 0; completed < dir.count; ) { - uint32 min_offset = 0x7fffffff; - int previous = completed; - - for (c = 0; c < dir.count; c++) { - if (entries[c].dib_offset == offset) { - Win32BitmapInfoHeader bitmap; - Win32RGBQuad *palette = NULL; - uint32 palette_count = 0; - uint32 image_size, mask_size; - uint32 width, height; - byte *image_data = NULL, *mask_data = NULL; - byte *row = NULL; - - if (!in->read(&bitmap, sizeof(Win32BitmapInfoHeader))) - goto local_cleanup; - - fix_win32_bitmap_info_header_endian(&bitmap); - if (bitmap.size < sizeof(Win32BitmapInfoHeader)) { - error("bitmap header is too short"); - goto local_cleanup; - } - if (bitmap.compression != 0) { - error("compressed image data not supported"); - goto local_cleanup; - } - if (bitmap.x_pels_per_meter != 0) - error("x_pels_per_meter field in bitmap should be zero"); - if (bitmap.y_pels_per_meter != 0) - error("y_pels_per_meter field in bitmap should be zero"); - if (bitmap.clr_important != 0) - error("clr_important field in bitmap should be zero"); - if (bitmap.planes != 1) - error("planes field in bitmap should be one"); - if (bitmap.size != sizeof(Win32BitmapInfoHeader)) { - uint32 skip = bitmap.size - sizeof(Win32BitmapInfoHeader); - error("skipping %d bytes of extended bitmap header", skip); - in->seek(skip, SEEK_CUR); - } - offset += bitmap.size; - - if (bitmap.clr_used != 0 || bitmap.bit_count < 24) { - palette_count = (bitmap.clr_used != 0 ? bitmap.clr_used : 1 << bitmap.bit_count); - palette = (Win32RGBQuad *)malloc(sizeof(Win32RGBQuad) * palette_count); - if (!in->read(palette, sizeof(Win32RGBQuad) * palette_count)) - goto local_cleanup; - offset += sizeof(Win32RGBQuad) * palette_count; - } - - width = bitmap.width; - height = ABS(bitmap.height)/2; - - image_size = height * ROW_BYTES(width * bitmap.bit_count); - mask_size = height * ROW_BYTES(width); - - if (entries[c].dib_size != bitmap.size + image_size + mask_size + palette_count * sizeof(Win32RGBQuad)) - debugC(DEBUG_RESOURCE, "incorrect total size of bitmap (%d specified; %d real)", - entries[c].dib_size, - (int)(bitmap.size + image_size + mask_size + palette_count * sizeof(Win32RGBQuad)) - ); - - image_data = (byte *)malloc(image_size); - if (!in->read(image_data, image_size)) - goto local_cleanup; - - mask_data = (byte *)malloc(mask_size); - if (!in->read(mask_data, mask_size)) - goto local_cleanup; - - offset += image_size; - offset += mask_size; - completed++; - matched++; - - *hotspot_x = entries[c].hotspot_x; - *hotspot_y = entries[c].hotspot_y; - *w = width; - *h = height; - *keycolor = 0; - *cursor = (byte *)malloc(width * height); - - row = (byte *)malloc(width * 4); - - for (d = 0; d < height; d++) { - uint32 x; - uint32 y = (bitmap.height < 0 ? d : height - d - 1); - uint32 imod = y * (image_size / height) * 8 / bitmap.bit_count; - uint32 mmod = y * (mask_size / height) * 8; - - for (x = 0; x < width; x++) { - - uint32 color = simple_vec(image_data, x + imod, bitmap.bit_count); - - // We set up cursor palette for default cursor, so use it - if (!simple_vec(mask_data, x + mmod, 1)) { - if (color) { - cursor[0][width * d + x] = 254; // white - } else { - cursor[0][width * d + x] = 253; // black - } - } else { - cursor[0][width * d + x] = 255; // transparent - } - /* - - if (bitmap.bit_count <= 16) { - if (color >= palette_count) { - error("color out of range in image data"); - goto local_cleanup; - } - row[4*x+0] = palette[color].red; - row[4*x+1] = palette[color].green; - row[4*x+2] = palette[color].blue; - - } else { - row[4*x+0] = (color >> 16) & 0xFF; - row[4*x+1] = (color >> 8) & 0xFF; - row[4*x+2] = (color >> 0) & 0xFF; - } - if (bitmap.bit_count == 32) - row[4*x+3] = (color >> 24) & 0xFF; - else - row[4*x+3] = simple_vec(mask_data, x + mmod, 1) ? 0 : 0xFF; - */ - } - - } - - free(row); - free(palette); - if (image_data != NULL) { - free(image_data); - free(mask_data); - } - continue; - - local_cleanup: - - free(row); - free(palette); - if (image_data != NULL) { - free(image_data); - free(mask_data); - } - goto cleanup; - } else { - if (entries[c].dib_offset > offset) - min_offset = MIN(min_offset, entries[c].dib_offset); - } - } - - if (previous == completed) { - if (min_offset < offset) { - error("offset of bitmap header incorrect (too low)"); - goto cleanup; - } - assert(min_offset != 0x7fffffff); - debugC(DEBUG_RESOURCE, "skipping %d bytes of garbage at %d", min_offset-offset, offset); - in->seek(min_offset - offset, SEEK_CUR); - offset = min_offset; - } - } - - free(entries); - return matched; - -cleanup: - - free(entries); - return -1; -} - -uint32 Win32ResExtractor::simple_vec(byte *data, uint32 ofs, byte size) { - switch (size) { - case 1: - return (data[ofs/8] >> (7 - ofs%8)) & 1; - case 2: - return (data[ofs/4] >> ((3 - ofs%4) << 1)) & 3; - case 4: - return (data[ofs/2] >> ((1 - ofs%2) << 2)) & 15; - case 8: - return data[ofs]; - case 16: - return data[2*ofs] | data[2*ofs+1] << 8; - case 24: - return data[3*ofs] | data[3*ofs+1] << 8 | data[3*ofs+2] << 16; - case 32: - return data[4*ofs] | data[4*ofs+1] << 8 | data[4*ofs+2] << 16 | data[4*ofs+3] << 24; - } - - return 0; -} - -void Win32ResExtractor::fix_win32_cursor_icon_file_dir_endian(Win32CursorIconFileDir *obj) { - LE16(obj->reserved); - LE16(obj->type); - LE16(obj->count); -} - -void Win32ResExtractor::fix_win32_bitmap_info_header_endian(Win32BitmapInfoHeader *obj) { - LE32(obj->size); - LE32(obj->width); - LE32(obj->height); - LE16(obj->planes); - LE16(obj->bit_count); - LE32(obj->compression); - LE32(obj->size_image); - LE32(obj->x_pels_per_meter); - LE32(obj->y_pels_per_meter); - LE32(obj->clr_used); - LE32(obj->clr_important); -} - -void Win32ResExtractor::fix_win32_cursor_icon_file_dir_entry_endian(Win32CursorIconFileDirEntry *obj) { - LE16(obj->hotspot_x); - LE16(obj->hotspot_y); - LE32(obj->dib_size); - LE32(obj->dib_offset); -} - -void Win32ResExtractor::fix_win32_image_section_header(Win32ImageSectionHeader *obj) { - LE32(obj->misc.physical_address); - LE32(obj->virtual_address); - LE32(obj->size_of_raw_data); - LE32(obj->pointer_to_raw_data); - LE32(obj->pointer_to_relocations); - LE32(obj->pointer_to_linenumbers); - LE16(obj->number_of_relocations); - LE16(obj->number_of_linenumbers); - LE32(obj->characteristics); -} - -/* fix_win32_image_header_endian: - * NOTE: This assumes that the optional header is always available. - */ -void Win32ResExtractor::fix_win32_image_header_endian(Win32ImageNTHeaders *obj) { - LE32(obj->signature); - LE16(obj->file_header.machine); - LE16(obj->file_header.number_of_sections); - LE32(obj->file_header.time_date_stamp); - LE32(obj->file_header.pointer_to_symbol_table); - LE32(obj->file_header.number_of_symbols); - LE16(obj->file_header.size_of_optional_header); - LE16(obj->file_header.characteristics); - - // FIXME: Does this assert ever trigger? If so, we should modify this function - // to properly deal with it. - assert(obj->file_header.size_of_optional_header >= sizeof(obj->optional_header)); - LE16(obj->optional_header.magic); - LE32(obj->optional_header.size_of_code); - LE32(obj->optional_header.size_of_initialized_data); - LE32(obj->optional_header.size_of_uninitialized_data); - LE32(obj->optional_header.address_of_entry_point); - LE32(obj->optional_header.base_of_code); - LE32(obj->optional_header.base_of_data); - LE32(obj->optional_header.image_base); - LE32(obj->optional_header.section_alignment); - LE32(obj->optional_header.file_alignment); - LE16(obj->optional_header.major_operating_system_version); - LE16(obj->optional_header.minor_operating_system_version); - LE16(obj->optional_header.major_image_version); - LE16(obj->optional_header.minor_image_version); - LE16(obj->optional_header.major_subsystem_version); - LE16(obj->optional_header.minor_subsystem_version); - LE32(obj->optional_header.win32_version_value); - LE32(obj->optional_header.size_of_image); - LE32(obj->optional_header.size_of_headers); - LE32(obj->optional_header.checksum); - LE16(obj->optional_header.subsystem); - LE16(obj->optional_header.dll_characteristics); - LE32(obj->optional_header.size_of_stack_reserve); - LE32(obj->optional_header.size_of_stack_commit); - LE32(obj->optional_header.size_of_heap_reserve); - LE32(obj->optional_header.size_of_heap_commit); - LE32(obj->optional_header.loader_flags); - LE32(obj->optional_header.number_of_rva_and_sizes); -} - -void Win32ResExtractor::fix_win32_image_data_directory(Win32ImageDataDirectory *obj) { - LE32(obj->virtual_address); - LE32(obj->size); -} - - MacResExtractor::MacResExtractor(ScummEngine_v70he *scumm) : ResExtractor(scumm) { _resMgr = NULL; } -int MacResExtractor::extractResource(int id, byte **buf) { +bool MacResExtractor::extractResource(int id, CachedCursor *cc) { // Create the MacResManager if not created already if (_resMgr == NULL) { _resMgr = new Common::MacResManager(); @@ -1158,25 +167,18 @@ int MacResExtractor::extractResource(int id, byte **buf) { error("Cannot open file %s", _fileName.c_str()); } - Common::SeekableReadStream *dataStream = _resMgr->getResource('crsr', 1000 + id); + Common::SeekableReadStream *dataStream = _resMgr->getResource('crsr', id + 1000); if (!dataStream) - error("There is no cursor ID #%d", 1000 + id); - - uint32 size = dataStream->size(); - *buf = (byte *)malloc(size); - dataStream->read(*buf, size); - delete dataStream; + return false; - return size; -} + int keyColor; // HACK: key color is ignored + _resMgr->convertCrsrCursor(dataStream, &cc->bitmap, cc->width, cc->height, cc->hotspotX, cc->hotspotY, + keyColor, _vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette), + &cc->palette, cc->palSize); -int MacResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h, - int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize) { - - _resMgr->convertCrsrCursor(data, datasize, cursor, w, h, hotspot_x, hotspot_y, keycolor, - _vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette), palette, palSize); - return 1; + delete dataStream; + return true; } void ScummEngine_v70he::readRoomsOffsets() { @@ -1330,7 +332,7 @@ int ScummEngine_v72he::getSoundResourceSize(int id) { if (!ptr) return 0; - if (READ_BE_UINT32(ptr) == MKID_BE('RIFF')) { + if (READ_BE_UINT32(ptr) == MKTAG('R','I','F','F')) { byte flags; int rate; @@ -1342,11 +344,11 @@ int ScummEngine_v72he::getSoundResourceSize(int id) { } } else { ptr += 8 + READ_BE_UINT32(ptr + 12); - if (READ_BE_UINT32(ptr) == MKID_BE('SBNG')) { + if (READ_BE_UINT32(ptr) == MKTAG('S','B','N','G')) { ptr += READ_BE_UINT32(ptr + 4); } - assert(READ_BE_UINT32(ptr) == MKID_BE('SDAT')); + assert(READ_BE_UINT32(ptr) == MKTAG('S','D','A','T')); size = READ_BE_UINT32(ptr + 4) - 8; } } diff --git a/engines/scumm/he/resource_he.h b/engines/scumm/he/resource_he.h index 6b4c3fe493..5d7c70db76 100644 --- a/engines/scumm/he/resource_he.h +++ b/engines/scumm/he/resource_he.h @@ -4,10 +4,6 @@ * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * - * Parts of this code are heavily based on: - * icoutils - A set of programs dealing with MS Windows icons and cursors. - * Copyright (C) 1998-2001 Oskar Liljeblad - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 @@ -31,89 +27,10 @@ #define SCUMM_HE_RESOURCE_HE_H #include "common/macresman.h" +#include "common/winexe_pe.h" namespace Scumm { -#define WINRES_ID_MAXLEN (256) - -/* - * Definitions - */ - -#define MZ_HEADER(x) ((DOSImageHeader *)(x)) - -#define STRIP_RES_ID_FORMAT(x) (x != NULL && (x[0] == '-' || x[0] == '+') ? ++x : x) - -#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 -#define IMAGE_SIZEOF_SHORT_NAME 8 - -#define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000 -#define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000 - -#define PE_HEADER(module) \ - ((Win32ImageNTHeaders*)((byte *)(module) + \ - (((DOSImageHeader*)(module))->lfanew))) - -#define PE_SECTIONS(module) \ - ((Win32ImageSectionHeader *)((byte *) &PE_HEADER(module)->optional_header + \ - PE_HEADER(module)->file_header.size_of_optional_header)) - -#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */ -#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */ - -/* The following symbols below and another group a few lines below are defined in - * the windows header, at least in wince and most likely in plain win32 as well. - * Defining them out silences a redefinition warning in gcc. - * If the same problem arises in win32 builds as well, please replace - * _WIN32_WCE with _WIN32 which is also defined in the wince platform. - */ -#ifndef _WIN32_WCE -#define IMAGE_SCN_CNT_CODE 0x00000020 -#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 -#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 -#endif - -// Only IMAGE_DIRECTORY_ENTRY_RESOURCE is used: -#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 -#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 -#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 -#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 -#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 -#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 -#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 -#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 -#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 /* (MIPS GP) */ -#define IMAGE_DIRECTORY_ENTRY_TLS 9 -#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 -#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 -#define IMAGE_DIRECTORY_ENTRY_IAT 12 /* Import Address Table */ -#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 -#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 - -#ifndef _WIN32_WCE -// Only RT_GROUP_CURSOR and RT_GROUP_ICON are used -#define RT_CURSOR 1 -#define RT_BITMAP 2 -#define RT_ICON 3 -#define RT_MENU 4 -#define RT_DIALOG 5 -#define RT_STRING 6 -#define RT_FONTDIR 7 -#define RT_FONT 8 -#define RT_ACCELERATOR 9 -#define RT_RCDATA 10 -#define RT_MESSAGELIST 11 -#define RT_GROUP_CURSOR 12 -#define RT_GROUP_ICON 14 -#endif - -#define RETURN_IF_BAD_POINTER(r, x) \ - if (!check_offset(fi->memory, fi->total_size, _fileName.c_str(), &(x), sizeof(x))) \ - return (r); -#define RETURN_IF_BAD_OFFSET(r, x, s) \ - if (!check_offset(fi->memory, fi->total_size, _fileName.c_str(), x, s)) \ - return (r); - class ScummEngine_v70he; class ResExtractor { @@ -123,312 +40,54 @@ public: void setCursor(int id); - virtual int extractResource(int id, byte **buf) { return 0; } - virtual int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h, - int *hotspot_x, int *hotspot_y, int *keycolor, - byte **palette, int *palSize) { return 0; } - - enum { - MAX_CACHED_CURSORS = 10 - }; - +protected: struct CachedCursor { bool valid; int id; byte *bitmap; - int w, h; - int hotspot_x, hotspot_y; - uint32 last_used; + int width, height; + int hotspotX, hotspotY; + uint32 lastUsed; byte *palette; int palSize; }; + Common::String _fileName; ScummEngine_v70he *_vm; + virtual bool extractResource(int id, CachedCursor *cc) = 0; + +private: + enum { + MAX_CACHED_CURSORS = 10 + }; + ResExtractor::CachedCursor *findCachedCursor(int id); ResExtractor::CachedCursor *getCachedCursorSlot(); - - bool _arg_raw; - Common::String _fileName; + CachedCursor _cursorCache[MAX_CACHED_CURSORS]; }; class Win32ResExtractor : public ResExtractor { - public: +public: Win32ResExtractor(ScummEngine_v70he *scumm); ~Win32ResExtractor() {} - int extractResource(int id, byte **data); - void setCursor(int id); - int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h, - int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize); - private: - int extractResource_(const char *resType, char *resName, byte **data); -/* - * Structures - */ - -#include "common/pack-start.h" // START STRUCT PACKING - - struct WinLibrary { - Common::SeekableReadStream *file; - byte *memory; - byte *first_resource; - int total_size; - } PACKED_STRUCT; - - struct WinResource { - char id[256]; - void *this_; - void *children; - int level; - bool numeric_id; - bool is_directory; - - Common::String getQuotedResourceId() const; - } PACKED_STRUCT; - - - struct Win32IconResDir { - byte width; - byte height; - byte color_count; - byte reserved; - } PACKED_STRUCT; - - struct Win32CursorDir { - uint16 width; - uint16 height; - } PACKED_STRUCT; - - struct Win32CursorIconDirEntry { - union { - Win32IconResDir icon; - Win32CursorDir cursor; - } res_info; - uint16 plane_count; - uint16 bit_count; - uint32 bytes_in_res; - uint16 res_id; - } PACKED_STRUCT; - - struct Win32CursorIconDir { - uint16 reserved; - uint16 type; - uint16 count; - Win32CursorIconDirEntry entries[1]; - } PACKED_STRUCT; - - struct Win32CursorIconFileDirEntry { - byte width; - byte height; - byte color_count; - byte reserved; - uint16 hotspot_x; - uint16 hotspot_y; - uint32 dib_size; - uint32 dib_offset; - } PACKED_STRUCT; - - struct Win32CursorIconFileDir { - uint16 reserved; - uint16 type; - uint16 count; - Win32CursorIconFileDirEntry entries[1]; - } PACKED_STRUCT; - - struct Win32BitmapInfoHeader { - uint32 size; - int32 width; - int32 height; - uint16 planes; - uint16 bit_count; - uint32 compression; - uint32 size_image; - int32 x_pels_per_meter; - int32 y_pels_per_meter; - uint32 clr_used; - uint32 clr_important; - } PACKED_STRUCT; - - struct Win32RGBQuad { - byte blue; - byte green; - byte red; - byte reserved; - } PACKED_STRUCT; - - struct Win32ImageResourceDirectoryEntry { - uint32 name; - uint32 offset_to_data; - } PACKED_STRUCT; - - struct Win16NETypeInfo { - uint16 type_id; - uint16 count; - uint32 resloader; // FARPROC16 - smaller? uint16? - } PACKED_STRUCT; - - struct DOSImageHeader { - uint16 magic; - uint16 cblp; - uint16 cp; - uint16 crlc; - uint16 cparhdr; - uint16 minalloc; - uint16 maxalloc; - uint16 ss; - uint16 sp; - uint16 csum; - uint16 ip; - uint16 cs; - uint16 lfarlc; - uint16 ovno; - uint16 res[4]; - uint16 oemid; - uint16 oeminfo; - uint16 res2[10]; - uint32 lfanew; - } PACKED_STRUCT; - - struct Win32ImageFileHeader { - uint16 machine; - uint16 number_of_sections; - uint32 time_date_stamp; - uint32 pointer_to_symbol_table; - uint32 number_of_symbols; - uint16 size_of_optional_header; - uint16 characteristics; - } PACKED_STRUCT; - - struct Win32ImageDataDirectory { - uint32 virtual_address; - uint32 size; - } PACKED_STRUCT; - - struct Win32ImageOptionalHeader { - uint16 magic; - byte major_linker_version; - byte minor_linker_version; - uint32 size_of_code; - uint32 size_of_initialized_data; - uint32 size_of_uninitialized_data; - uint32 address_of_entry_point; - uint32 base_of_code; - uint32 base_of_data; - uint32 image_base; - uint32 section_alignment; - uint32 file_alignment; - uint16 major_operating_system_version; - uint16 minor_operating_system_version; - uint16 major_image_version; - uint16 minor_image_version; - uint16 major_subsystem_version; - uint16 minor_subsystem_version; - uint32 win32_version_value; - uint32 size_of_image; - uint32 size_of_headers; - uint32 checksum; - uint16 subsystem; - uint16 dll_characteristics; - uint32 size_of_stack_reserve; - uint32 size_of_stack_commit; - uint32 size_of_heap_reserve; - uint32 size_of_heap_commit; - uint32 loader_flags; - uint32 number_of_rva_and_sizes; - Win32ImageDataDirectory data_directory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; - } PACKED_STRUCT; - - struct Win32ImageNTHeaders { - uint32 signature; - Win32ImageFileHeader file_header; - Win32ImageOptionalHeader optional_header; - } PACKED_STRUCT; - - struct Win32ImageSectionHeader { - byte name[IMAGE_SIZEOF_SHORT_NAME]; - union { - uint32 physical_address; - uint32 virtual_size; - } misc; - uint32 virtual_address; - uint32 size_of_raw_data; - uint32 pointer_to_raw_data; - uint32 pointer_to_relocations; - uint32 pointer_to_linenumbers; - uint16 number_of_relocations; - uint16 number_of_linenumbers; - uint32 characteristics; - } PACKED_STRUCT; - - struct Win32ImageResourceDataEntry { - uint32 offset_to_data; - uint32 size; - uint32 code_page; - uint32 resource_handle; - } PACKED_STRUCT; - - struct Win32ImageResourceDirectory { - uint32 characteristics; - uint32 time_date_stamp; - uint16 major_version; - uint16 minor_version; - uint16 number_of_named_entries; - uint16 number_of_id_entries; - } PACKED_STRUCT; - -#include "common/pack-end.h" // END STRUCT PACKING - -/* - * Function Prototypes - */ - - WinResource *list_resources(WinLibrary *, WinResource *, int *); - bool read_library(WinLibrary *); - WinResource *find_resource(WinLibrary *, const char *, const char *, const char *, int *); - byte *get_resource_entry(WinLibrary *, WinResource *, int *); - int do_resources(WinLibrary *, const char *, char *, char *, byte **); - bool compare_resource_id(WinResource *, const char *); - const char *res_type_string_to_id(const char *); - - const char *res_type_id_to_string(int); - char *get_destination_name(WinLibrary *, char *, char *, char *); - - byte *extract_resource(WinLibrary *, WinResource *, int *, bool *, char *, char *, bool); - int extract_resources(WinLibrary *, WinResource *, WinResource *, WinResource *, WinResource *, byte **); - byte *extract_group_icon_cursor_resource(WinLibrary *, WinResource *, char *, int *, bool); - - bool decode_pe_resource_id(WinLibrary *, WinResource *, uint32); - WinResource *list_pe_resources(WinLibrary *, Win32ImageResourceDirectory *, int, int *); - int calc_vma_size(WinLibrary *); - int do_resources_recurs(WinLibrary *, WinResource *, WinResource *, WinResource *, WinResource *, const char *, char *, char *, byte **); - WinResource *find_with_resource_array(WinLibrary *, WinResource *, const char *); - - bool check_offset(byte *, int, const char *, void *, int); - - uint32 simple_vec(byte *data, uint32 ofs, byte size); +private: + Common::PEResources _exe; - void fix_win32_cursor_icon_file_dir_endian(Win32CursorIconFileDir *obj); - void fix_win32_bitmap_info_header_endian(Win32BitmapInfoHeader *obj); - void fix_win32_cursor_icon_file_dir_entry_endian(Win32CursorIconFileDirEntry *obj); - void fix_win32_image_section_header(Win32ImageSectionHeader *obj); - void fix_win32_image_header_endian(Win32ImageNTHeaders *obj); - void fix_win32_image_data_directory(Win32ImageDataDirectory *obj); + bool extractResource(int id, CachedCursor *cc); }; class MacResExtractor : public ResExtractor { - public: MacResExtractor(ScummEngine_v70he *scumm); - ~MacResExtractor() { } + ~MacResExtractor() {} private: Common::MacResManager *_resMgr; - int extractResource(int id, byte **buf); - int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h, - int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize); + bool extractResource(int id, CachedCursor *cc); }; } // End of namespace Scumm diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp index ca4a65ac74..69063a1837 100644 --- a/engines/scumm/he/script_v100he.cpp +++ b/engines/scumm/he/script_v100he.cpp @@ -2999,7 +2999,7 @@ void ScummEngine_v100he::decodeParseString(int m, int n) { case 78: { byte *dataPtr = getResourceAddress(rtTalkie, pop()); - byte *text = findWrappedBlock(MKID_BE('TEXT'), dataPtr, 0, 0); + byte *text = findWrappedBlock(MKTAG('T','E','X','T'), dataPtr, 0, 0); size = getResourceDataSize(text); memcpy(name, text, size); printString(m, name); diff --git a/engines/scumm/he/script_v60he.cpp b/engines/scumm/he/script_v60he.cpp index 9d62a31f6d..7ecabd55e1 100644 --- a/engines/scumm/he/script_v60he.cpp +++ b/engines/scumm/he/script_v60he.cpp @@ -741,10 +741,14 @@ void ScummEngine_v60he::o60_openFile() { void ScummEngine_v60he::o60_closeFile() { int slot = pop(); if (0 <= slot && slot < 17) { - delete _hInFileTable[slot]; - delete _hOutFileTable[slot]; + if (_hOutFileTable[slot]) { + _hOutFileTable[slot]->finalize(); + delete _hOutFileTable[slot]; + _hOutFileTable[slot] = 0; + } + + delete _hInFileTable[slot]; _hInFileTable[slot] = 0; - _hOutFileTable[slot] = 0; } } diff --git a/engines/scumm/he/script_v71he.cpp b/engines/scumm/he/script_v71he.cpp index 46a8868949..a800a7d85c 100644 --- a/engines/scumm/he/script_v71he.cpp +++ b/engines/scumm/he/script_v71he.cpp @@ -88,15 +88,15 @@ byte *ScummEngine_v71he::heFindResource(uint32 tag, byte *searchin) { } byte *ScummEngine_v71he::findWrappedBlock(uint32 tag, byte *ptr, int state, bool errorFlag) { - if (READ_BE_UINT32(ptr) == MKID_BE('MULT')) { + if (READ_BE_UINT32(ptr) == MKTAG('M','U','L','T')) { byte *offs, *wrap; uint32 size; - wrap = heFindResource(MKID_BE('WRAP'), ptr); + wrap = heFindResource(MKTAG('W','R','A','P'), ptr); if (wrap == NULL) return NULL; - offs = heFindResourceData(MKID_BE('OFFS'), wrap); + offs = heFindResourceData(MKTAG('O','F','F','S'), wrap); if (offs == NULL) return NULL; @@ -109,7 +109,7 @@ byte *ScummEngine_v71he::findWrappedBlock(uint32 tag, byte *ptr, int state, bool if (offs) return offs; - offs = heFindResourceData(MKID_BE('DEFA'), ptr); + offs = heFindResourceData(MKTAG('D','E','F','A'), ptr); if (offs == NULL) return NULL; diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp index 32c15abcba..17bd29d826 100644 --- a/engines/scumm/he/script_v72he.cpp +++ b/engines/scumm/he/script_v72he.cpp @@ -1408,18 +1408,49 @@ void ScummEngine_v72he::o72_openFile() { if (slot != -1) { switch (mode) { - case 1: + case 1: // Read mode if (!_saveFileMan->listSavefiles(filename).empty()) { _hInFileTable[slot] = _saveFileMan->openForLoading(filename); } else { _hInFileTable[slot] = SearchMan.createReadStreamForMember(filename); } break; - case 2: + case 2: // Write mode if (!strchr(filename, '/')) { _hOutFileTable[slot] = _saveFileMan->openForSaving(filename); } break; + case 6: { // Append mode + if (strchr(filename, '/')) + break; + + // First check if the file already exists + Common::InSaveFile *initialState = 0; + if (!_saveFileMan->listSavefiles(filename).empty()) + initialState = _saveFileMan->openForLoading(filename); + else + initialState = SearchMan.createReadStreamForMember(filename); + + // Read in the data from the initial file + uint32 initialSize = 0; + byte *initialData = 0; + if (initialState) { + initialSize = initialState->size(); + initialData = new byte[initialSize]; + initialState->read(initialData, initialSize); + delete initialState; + } + + // Attempt to open a save file + _hOutFileTable[slot] = _saveFileMan->openForSaving(filename); + + // Begin us off with the data from the previous file + if (_hOutFileTable[slot] && initialData) { + _hOutFileTable[slot]->write(initialData, initialSize); + delete[] initialData; + } + + } break; default: error("o72_openFile(): wrong open file mode %d", mode); } @@ -2008,7 +2039,7 @@ void ScummEngine_v72he::decodeParseString(int m, int n) { case 0xE1: { byte *dataPtr = getResourceAddress(rtTalkie, pop()); - byte *text = findWrappedBlock(MKID_BE('TEXT'), dataPtr, 0, 0); + byte *text = findWrappedBlock(MKTAG('T','E','X','T'), dataPtr, 0, 0); size = getResourceDataSize(text); memcpy(name, text, size); printString(m, name); diff --git a/engines/scumm/he/script_v90he.cpp b/engines/scumm/he/script_v90he.cpp index 841eba960d..1a38a99f17 100644 --- a/engines/scumm/he/script_v90he.cpp +++ b/engines/scumm/he/script_v90he.cpp @@ -351,12 +351,12 @@ void ScummEngine_v90he::o90_max() { } void ScummEngine_v90he::o90_sin() { - double a = pop() * PI / 180.; + double a = pop() * M_PI / 180.; push((int)(sin(a) * 100000)); } void ScummEngine_v90he::o90_cos() { - double a = pop() * PI / 180.; + double a = pop() * M_PI / 180.; push((int)(cos(a) * 100000)); } @@ -372,7 +372,7 @@ void ScummEngine_v90he::o90_sqrt() { void ScummEngine_v90he::o90_atan2() { int y = pop(); int x = pop(); - int a = (int)(atan2((double)y, (double)x) * 180. / PI); + int a = (int)(atan2((double)y, (double)x) * 180. / M_PI); if (a < 0) { a += 360; } @@ -384,7 +384,7 @@ void ScummEngine_v90he::o90_getSegmentAngle() { int x1 = pop(); int dy = y1 - pop(); int dx = x1 - pop(); - int a = (int)(atan2((double)dy, (double)dx) * 180. / PI); + int a = (int)(atan2((double)dy, (double)dx) * 180. / M_PI); if (a < 0) { a += 360; } @@ -2292,13 +2292,13 @@ void ScummEngine_v90he::o90_kernelGetFunctions() { switch (args[0]) { case 1001: { - double b = args[1] * PI / 180.; + double b = args[1] * M_PI / 180.; push((int)(sin(b) * 100000)); } break; case 1002: { - double b = args[1] * PI / 180.; + double b = args[1] * M_PI / 180.; push((int)(cos(b) * 100000)); } break; diff --git a/engines/scumm/he/sound_he.cpp b/engines/scumm/he/sound_he.cpp index 4770f28cbc..4fd7caebf5 100644 --- a/engines/scumm/he/sound_he.cpp +++ b/engines/scumm/he/sound_he.cpp @@ -499,11 +499,11 @@ byte *findSoundTag(uint32 tag, byte *ptr) { byte *endPtr; uint32 offset, size; - if (READ_BE_UINT32(ptr) == MKID_BE('WSOU')) { + if (READ_BE_UINT32(ptr) == MKTAG('W','S','O','U')) { ptr += 8; } - if (READ_BE_UINT32(ptr) != MKID_BE('RIFF')) + if (READ_BE_UINT32(ptr) != MKTAG('R','I','F','F')) return NULL; endPtr = (ptr + 12); @@ -591,14 +591,14 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags) } // Support for sound in later HE games - if (READ_BE_UINT32(ptr) == MKID_BE('RIFF') || READ_BE_UINT32(ptr) == MKID_BE('WSOU')) { + if (READ_BE_UINT32(ptr) == MKTAG('R','I','F','F') || READ_BE_UINT32(ptr) == MKTAG('W','S','O','U')) { uint16 compType; int blockAlign; int codeOffs = -1; priority = (soundID > _vm->_numSounds) ? 255 : *(ptr + 18); - byte *sbngPtr = findSoundTag(MKID_BE('SBNG'), ptr); + byte *sbngPtr = findSoundTag(MKTAG('S','B','N','G'), ptr); if (sbngPtr != NULL) { codeOffs = sbngPtr - ptr + 8; } @@ -611,7 +611,7 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags) return; } - if (READ_BE_UINT32(ptr) == MKID_BE('WSOU')) + if (READ_BE_UINT32(ptr) == MKTAG('W','S','O','U')) ptr += 8; size = READ_LE_UINT32(ptr + 4); @@ -675,7 +675,7 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags) Audio::makeLoopingAudioStream(stream, (heFlags & 1) ? 0 : 1), soundID); } // Support for sound in Humongous Entertainment games - else if (READ_BE_UINT32(ptr) == MKID_BE('DIGI') || READ_BE_UINT32(ptr) == MKID_BE('TALK')) { + else if (READ_BE_UINT32(ptr) == MKTAG('D','I','G','I') || READ_BE_UINT32(ptr) == MKTAG('T','A','L','K')) { byte *sndPtr = ptr; int codeOffs = -1; @@ -693,12 +693,12 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags) return; } - if (READ_BE_UINT32(ptr) == MKID_BE('SBNG')) { + if (READ_BE_UINT32(ptr) == MKTAG('S','B','N','G')) { codeOffs = ptr - sndPtr + 8; ptr += READ_BE_UINT32(ptr + 4); } - assert(READ_BE_UINT32(ptr) == MKID_BE('SDAT')); + assert(READ_BE_UINT32(ptr) == MKTAG('S','D','A','T')); size = READ_BE_UINT32(ptr + 4) - 8; if (heOffset < 0 || heOffset > size) { // Occurs when making fireworks in puttmoon @@ -734,14 +734,14 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags) Audio::makeLoopingAudioStream(stream, (heFlags & 1) ? 0 : 1), soundID); } // Support for PCM music in 3DO versions of Humongous Entertainment games - else if (READ_BE_UINT32(ptr) == MKID_BE('MRAW')) { + else if (READ_BE_UINT32(ptr) == MKTAG('M','R','A','W')) { priority = *(ptr + 18); rate = READ_LE_UINT16(ptr + 22); // Skip DIGI (8) and HSHD (24) blocks ptr += 32; - assert(READ_BE_UINT32(ptr) == MKID_BE('SDAT')); + assert(READ_BE_UINT32(ptr) == MKTAG('S','D','A','T')); size = READ_BE_UINT32(ptr + 4) - 8; byte *sound = (byte *)malloc(size); @@ -753,7 +753,7 @@ void SoundHE::playHESound(int soundID, int heOffset, int heChannel, int heFlags) stream = Audio::makeRawStream(sound, size, rate, 0); _mixer->playStream(Audio::Mixer::kMusicSoundType, NULL, stream, soundID); } - else if (READ_BE_UINT32(ptr) == MKID_BE('MIDI')) { + else if (READ_BE_UINT32(ptr) == MKTAG('M','I','D','I')) { if (_vm->_imuse) { // This is used in the DOS version of Fatty Bear's // Birthday Surprise to change the note on the piano @@ -833,9 +833,9 @@ void ScummEngine_v80he::createSound(int snd1id, int snd2id) { chan = i; } - if (!findSoundTag(MKID_BE('data'), snd1Ptr)) { - sbng1Ptr = heFindResource(MKID_BE('SBNG'), snd1Ptr); - sbng2Ptr = heFindResource(MKID_BE('SBNG'), snd2Ptr); + if (!findSoundTag(MKTAG('d','a','t','a'), snd1Ptr)) { + sbng1Ptr = heFindResource(MKTAG('S','B','N','G'), snd1Ptr); + sbng2Ptr = heFindResource(MKTAG('S','B','N','G'), snd2Ptr); } if (sbng1Ptr != NULL && sbng2Ptr != NULL) { @@ -879,10 +879,10 @@ void ScummEngine_v80he::createSound(int snd1id, int snd2id) { } } - if (findSoundTag(MKID_BE('data'), snd1Ptr)) { - sdat1Ptr = findSoundTag(MKID_BE('data'), snd1Ptr); + if (findSoundTag(MKTAG('d','a','t','a'), snd1Ptr)) { + sdat1Ptr = findSoundTag(MKTAG('d','a','t','a'), snd1Ptr); assert(sdat1Ptr); - sdat2Ptr = findSoundTag(MKID_BE('data'), snd2Ptr); + sdat2Ptr = findSoundTag(MKTAG('d','a','t','a'), snd2Ptr); assert(sdat2Ptr); if (!_sndDataSize) @@ -890,9 +890,9 @@ void ScummEngine_v80he::createSound(int snd1id, int snd2id) { sdat2size = READ_LE_UINT32(sdat2Ptr + 4) - 8; } else { - sdat1Ptr = heFindResource(MKID_BE('SDAT'), snd1Ptr); + sdat1Ptr = heFindResource(MKTAG('S','D','A','T'), snd1Ptr); assert(sdat1Ptr); - sdat2Ptr = heFindResource(MKID_BE('SDAT'), snd2Ptr); + sdat2Ptr = heFindResource(MKTAG('S','D','A','T'), snd2Ptr); assert(sdat2Ptr); _sndDataSize = READ_BE_UINT32(sdat1Ptr + 4) - 8; diff --git a/engines/scumm/he/sprite_he.cpp b/engines/scumm/he/sprite_he.cpp index 5f751d8285..c66eed6ae6 100644 --- a/engines/scumm/he/sprite_he.cpp +++ b/engines/scumm/he/sprite_he.cpp @@ -46,7 +46,7 @@ Sprite::~Sprite() { } void ScummEngine_v90he::allocateArrays() { - ScummEngine::allocateArrays(); + ScummEngine_v70he::allocateArrays(); _sprite->allocTables(_numSprites, MAX(64, _numSprites / 4), 64); } diff --git a/engines/scumm/he/wiz_he.cpp b/engines/scumm/he/wiz_he.cpp index c7e6a56083..16cbadd65b 100644 --- a/engines/scumm/he/wiz_he.cpp +++ b/engines/scumm/he/wiz_he.cpp @@ -111,7 +111,7 @@ void Wiz::polygonStore(int id, bool flag, int vert1x, int vert1y, int vert2x, in } void Wiz::polygonRotatePoints(Common::Point *pts, int num, int angle) { - double alpha = angle * PI / 180.; + double alpha = angle * M_PI / 180.; double cos_alpha = cos(alpha); double sin_alpha = sin(alpha); @@ -1445,21 +1445,21 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int maskNum, int maskState, int if (shadow) { dataPtr = _vm->getResourceAddress(rtImage, shadow); assert(dataPtr); - xmapPtr = _vm->findResourceData(MKID_BE('XMAP'), dataPtr); + xmapPtr = _vm->findResourceData(MKTAG('X','M','A','P'), dataPtr); assert(xmapPtr); } dataPtr = _vm->getResourceAddress(rtImage, resNum); assert(dataPtr); - uint8 *wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), dataPtr, state, 0); + uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), dataPtr, state, 0); assert(wizh); uint32 comp = READ_LE_UINT32(wizh + 0x0); uint32 width = READ_LE_UINT32(wizh + 0x4); uint32 height = READ_LE_UINT32(wizh + 0x8); debug(3, "wiz_header.comp = %d wiz_header.w = %d wiz_header.h = %d", comp, width, height); - uint8 *wizd = _vm->findWrappedBlock(MKID_BE('WIZD'), dataPtr, state, 0); + uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dataPtr, state, 0); assert(wizd); uint8 *mask = NULL; @@ -1467,28 +1467,28 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int maskNum, int maskState, int uint8 *maskPtr = _vm->getResourceAddress(rtImage, maskNum); assert(maskPtr); - wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), maskPtr, maskState, 0); + wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), maskPtr, maskState, 0); assert(wizh); assert(comp == 2 && READ_LE_UINT32(wizh + 0x0) == 1); width = READ_LE_UINT32(wizh + 0x4); height = READ_LE_UINT32(wizh + 0x8); - mask = _vm->findWrappedBlock(MKID_BE('WIZD'), maskPtr, maskState, 0); + mask = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), maskPtr, maskState, 0); assert(mask); } if (flags & kWIFHasPalette) { - uint8 *pal = _vm->findWrappedBlock(MKID_BE('RGBS'), dataPtr, state, 0); + uint8 *pal = _vm->findWrappedBlock(MKTAG('R','G','B','S'), dataPtr, state, 0); assert(pal); _vm->setPaletteFromPtr(pal, 256); } uint8 *rmap = NULL; if (flags & kWIFRemapPalette) { - rmap = _vm->findWrappedBlock(MKID_BE('RMAP'), dataPtr, state, 0); + rmap = _vm->findWrappedBlock(MKTAG('R','M','A','P'), dataPtr, state, 0); assert(rmap); if (_vm->_game.heversion <= 80 || READ_BE_UINT32(rmap) != 0x01234567) { - uint8 *rgbs = _vm->findWrappedBlock(MKID_BE('RGBS'), dataPtr, state, 0); + uint8 *rgbs = _vm->findWrappedBlock(MKTAG('R','G','B','S'), dataPtr, state, 0); assert(rgbs); _vm->remapHEPalette(rgbs, rmap + 4); } @@ -1526,7 +1526,7 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int maskNum, int maskState, int if (dstResNum) { uint8 *dstPtr = _vm->getResourceAddress(rtImage, dstResNum); assert(dstPtr); - dst = _vm->findWrappedBlock(MKID_BE('WIZD'), dstPtr, 0, 0); + dst = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dstPtr, 0, 0); assert(dst); getWizImageDim(dstResNum, 0, cw, ch); dstPitch = cw * _vm->_bytesPerPixel; @@ -1567,7 +1567,7 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int maskNum, int maskState, int int transColor = -1; if (_vm->VAR_WIZ_TCOLOR != 0xFF) { - uint8 *trns = _vm->findWrappedBlock(MKID_BE('TRNS'), dataPtr, state, 0); + uint8 *trns = _vm->findWrappedBlock(MKTAG('T','R','N','S'), dataPtr, state, 0); transColor = (trns == NULL) ? _vm->VAR(_vm->VAR_WIZ_TCOLOR) : -1; } @@ -1817,7 +1817,7 @@ void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int assert(_vm->_bytesPerPixel == 1); uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum); assert(dataPtr); - srcWizBuf = _vm->findWrappedBlock(MKID_BE('WIZD'), dataPtr, state, 0); + srcWizBuf = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dataPtr, state, 0); assert(srcWizBuf); freeBuffer = false; } @@ -1827,7 +1827,7 @@ void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int } else { uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum); assert(dataPtr); - srcWizBuf = _vm->findWrappedBlock(MKID_BE('WIZD'), dataPtr, state, 0); + srcWizBuf = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dataPtr, state, 0); assert(srcWizBuf); freeBuffer = false; } @@ -1842,7 +1842,7 @@ void Wiz::drawWizPolygonTransform(int resNum, int state, Common::Point *wp, int if (dstResNum) { uint8 *dstPtr = _vm->getResourceAddress(rtImage, dstResNum); assert(dstPtr); - dst = _vm->findWrappedBlock(MKID_BE('WIZD'), dstPtr, 0, 0); + dst = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dstPtr, 0, 0); assert(dst); getWizImageDim(dstResNum, 0, dstw, dsth); dstpitch = dstw * _vm->_bytesPerPixel; @@ -2185,7 +2185,7 @@ void Wiz::fillWizRect(const WizParameters *params) { } uint8 *dataPtr = _vm->getResourceAddress(rtImage, params->img.resNum); if (dataPtr) { - uint8 *wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), dataPtr, state, 0); + uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), dataPtr, state, 0); assert(wizh); int c = READ_LE_UINT32(wizh + 0x0); int w = READ_LE_UINT32(wizh + 0x4); @@ -2210,7 +2210,7 @@ void Wiz::fillWizRect(const WizParameters *params) { } if (areaRect.intersects(imageRect)) { areaRect.clip(imageRect); - uint8 *wizd = _vm->findWrappedBlock(MKID_BE('WIZD'), dataPtr, state, 0); + uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dataPtr, state, 0); assert(wizd); int dx = areaRect.width(); int dy = areaRect.height(); @@ -2256,7 +2256,7 @@ void Wiz::fillWizLine(const WizParameters *params) { } uint8 *dataPtr = _vm->getResourceAddress(rtImage, params->img.resNum); if (dataPtr) { - uint8 *wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), dataPtr, state, 0); + uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), dataPtr, state, 0); assert(wizh); int c = READ_LE_UINT32(wizh + 0x0); int w = READ_LE_UINT32(wizh + 0x4); @@ -2274,7 +2274,7 @@ void Wiz::fillWizLine(const WizParameters *params) { if (params->processFlags & kWPFFillColor) { color = params->fillColor; } - uint8 *wizd = _vm->findWrappedBlock(MKID_BE('WIZD'), dataPtr, state, 0); + uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dataPtr, state, 0); assert(wizd); int x1 = params->box2.left; int y1 = params->box2.top; @@ -2309,7 +2309,7 @@ void Wiz::fillWizPixel(const WizParameters *params) { if (params->processFlags & kWPFNewState) { state = params->img.state; } - uint8 *wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), dataPtr, state, 0); + uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), dataPtr, state, 0); assert(wizh); int c = READ_LE_UINT32(wizh + 0x0); int w = READ_LE_UINT32(wizh + 0x4); @@ -2327,7 +2327,7 @@ void Wiz::fillWizPixel(const WizParameters *params) { color = params->fillColor; } if (imageRect.contains(px, py)) { - uint8 *wizd = _vm->findWrappedBlock(MKID_BE('WIZD'), dataPtr, state, 0); + uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dataPtr, state, 0); assert(wizd); *(wizd + py * w + px) = color; } @@ -2342,7 +2342,7 @@ void Wiz::remapWizImagePal(const WizParameters *params) { const uint8 *index = params->remapIndex; uint8 *iwiz = _vm->getResourceAddress(rtImage, params->img.resNum); assert(iwiz); - uint8 *rmap = _vm->findWrappedBlock(MKID_BE('RMAP'), iwiz, st, 0); + uint8 *rmap = _vm->findWrappedBlock(MKTAG('R','M','A','P'), iwiz, st, 0); assert(rmap); WRITE_BE_UINT32(rmap, 0x01234567); while (num--) { @@ -2380,7 +2380,7 @@ void Wiz::processWizImage(const WizParameters *params) { if (f) { uint32 id = f->readUint32BE(); - if (id == MKID_BE('AWIZ') || id == MKID_BE('MULT')) { + if (id == MKTAG('A','W','I','Z') || id == MKTAG('M','U','L','T')) { uint32 size = f->readUint32BE(); f->seek(0, SEEK_SET); byte *p = _vm->_res->createResource(rtImage, params->img.resNum, size); @@ -2510,7 +2510,7 @@ void Wiz::processWizImage(const WizParameters *params) { void Wiz::getWizImageDim(int resNum, int state, int32 &w, int32 &h) { uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum); assert(dataPtr); - uint8 *wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), dataPtr, state, 0); + uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), dataPtr, state, 0); assert(wizh); w = READ_LE_UINT32(wizh + 0x4); h = READ_LE_UINT32(wizh + 0x8); @@ -2519,7 +2519,7 @@ void Wiz::getWizImageDim(int resNum, int state, int32 &w, int32 &h) { void Wiz::getWizImageSpot(int resId, int state, int32 &x, int32 &y) { uint8 *dataPtr = _vm->getResourceAddress(rtImage, resId); assert(dataPtr); - uint8 *spotPtr = _vm->findWrappedBlock(MKID_BE('SPOT'), dataPtr, state, 0); + uint8 *spotPtr = _vm->findWrappedBlock(MKTAG('S','P','O','T'), dataPtr, state, 0); if (spotPtr) { x = READ_LE_UINT32(spotPtr + 0); y = READ_LE_UINT32(spotPtr + 4); @@ -2537,17 +2537,17 @@ int Wiz::getWizImageData(int resNum, int state, int type) { switch (type) { case 0: - wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), dataPtr, state, 0); + wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), dataPtr, state, 0); assert(wizh); return READ_LE_UINT32(wizh + 0x0); case 1: - return (_vm->findWrappedBlock(MKID_BE('RGBS'), dataPtr, state, 0) != NULL) ? 1 : 0; + return (_vm->findWrappedBlock(MKTAG('R','G','B','S'), dataPtr, state, 0) != NULL) ? 1 : 0; case 2: - return (_vm->findWrappedBlock(MKID_BE('RMAP'), dataPtr, state, 0) != NULL) ? 1 : 0; + return (_vm->findWrappedBlock(MKTAG('R','M','A','P'), dataPtr, state, 0) != NULL) ? 1 : 0; case 3: - return (_vm->findWrappedBlock(MKID_BE('TRNS'), dataPtr, state, 0) != NULL) ? 1 : 0; + return (_vm->findWrappedBlock(MKTAG('T','R','N','S'), dataPtr, state, 0) != NULL) ? 1 : 0; case 4: - return (_vm->findWrappedBlock(MKID_BE('XMAP'), dataPtr, state, 0) != NULL) ? 1 : 0; + return (_vm->findWrappedBlock(MKTAG('X','M','A','P'), dataPtr, state, 0) != NULL) ? 1 : 0; default: error("getWizImageData: Unknown type %d", type); } @@ -2556,14 +2556,14 @@ int Wiz::getWizImageData(int resNum, int state, int type) { int Wiz::getWizImageStates(int resNum) { const uint8 *dataPtr = _vm->getResourceAddress(rtImage, resNum); assert(dataPtr); - if (READ_BE_UINT32(dataPtr) == MKID_BE('MULT')) { + if (READ_BE_UINT32(dataPtr) == MKTAG('M','U','L','T')) { const byte *offs, *wrap; - wrap = _vm->findResource(MKID_BE('WRAP'), dataPtr); + wrap = _vm->findResource(MKTAG('W','R','A','P'), dataPtr); if (wrap == NULL) return 1; - offs = _vm->findResourceData(MKID_BE('OFFS'), wrap); + offs = _vm->findResourceData(MKTAG('O','F','F','S'), wrap); if (offs == NULL) return 1; @@ -2577,12 +2577,12 @@ int Wiz::isWizPixelNonTransparent(int resNum, int state, int x, int y, int flags int ret = 0; uint8 *data = _vm->getResourceAddress(rtImage, resNum); assert(data); - uint8 *wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), data, state, 0); + uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), data, state, 0); assert(wizh); int c = READ_LE_UINT32(wizh + 0x0); int w = READ_LE_UINT32(wizh + 0x4); int h = READ_LE_UINT32(wizh + 0x8); - uint8 *wizd = _vm->findWrappedBlock(MKID_BE('WIZD'), data, state, 0); + uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), data, state, 0); assert(wizd); if (x >= 0 && x < w && y >= 0 && y < h) { if (flags & kWIFFlipX) { @@ -2627,12 +2627,12 @@ uint16 Wiz::getWizPixelColor(int resNum, int state, int x, int y) { uint16 color = 0; uint8 *data = _vm->getResourceAddress(rtImage, resNum); assert(data); - uint8 *wizh = _vm->findWrappedBlock(MKID_BE('WIZH'), data, state, 0); + uint8 *wizh = _vm->findWrappedBlock(MKTAG('W','I','Z','H'), data, state, 0); assert(wizh); int c = READ_LE_UINT32(wizh + 0x0); int w = READ_LE_UINT32(wizh + 0x4); int h = READ_LE_UINT32(wizh + 0x8); - uint8 *wizd = _vm->findWrappedBlock(MKID_BE('WIZD'), data, state, 0); + uint8 *wizd = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), data, state, 0); assert(wizd); switch (c) { case 0: @@ -2671,13 +2671,13 @@ int ScummEngine_v90he::computeWizHistogram(int resNum, int state, int x, int y, Common::Rect rCapt(x, y, w + 1, h + 1); uint8 *data = getResourceAddress(rtImage, resNum); assert(data); - uint8 *wizh = findWrappedBlock(MKID_BE('WIZH'), data, state, 0); + uint8 *wizh = findWrappedBlock(MKTAG('W','I','Z','H'), data, state, 0); assert(wizh); int c = READ_LE_UINT32(wizh + 0x0); w = READ_LE_UINT32(wizh + 0x4); h = READ_LE_UINT32(wizh + 0x8); Common::Rect rWiz(w, h); - uint8 *wizd = findWrappedBlock(MKID_BE('WIZD'), data, state, 0); + uint8 *wizd = findWrappedBlock(MKTAG('W','I','Z','D'), data, state, 0); assert(wizd); if (rCapt.intersects(rWiz)) { rCapt.clip(rWiz); diff --git a/engines/scumm/help.cpp b/engines/scumm/help.cpp index 3738ebc2e5..a3bb85ab42 100644 --- a/engines/scumm/help.cpp +++ b/engines/scumm/help.cpp @@ -79,14 +79,14 @@ void ScummHelp::updateStrings(byte gameId, byte version, Common::Platform platfo ADD_BIND(".", _("Skip line of text")); ADD_BIND(_("Esc"), _("Skip cutscene")); ADD_BIND(_("Space"), _("Pause game")); - ADD_BIND(_("Ctrl 0-9"), _("Load game state 1-10")); - ADD_BIND(_("Alt 0-9"), _("Save game state 1-10")); + ADD_BIND(String(_("Ctrl")) + " 0-9", _("Load game state 1-10")); + ADD_BIND(String(_("Alt")) + " 0-9", _("Save game state 1-10")); #ifdef MACOSX ADD_BIND("Cmd q", _("Quit")); #else - ADD_BIND(_("Alt x, Ctrl z"), _("Quit")); + ADD_BIND(String(_("Alt")) + " x, " + _("Ctrl") + " z", _("Quit")); #endif - ADD_BIND(_("Alt Enter"), _("Toggle fullscreen")); + ADD_BIND(String(_("Alt")) + " " + _("Enter"), _("Toggle fullscreen")); ADD_BIND("[, ]", _("Music volume up / down")); ADD_BIND("-, +", _("Text speed slower / faster")); ADD_BIND(_("Enter"), _("Simulate left mouse button")); @@ -95,14 +95,14 @@ void ScummHelp::updateStrings(byte gameId, byte version, Common::Platform platfo case 2: title = _("Special keyboard commands:"); ADD_BIND("~, #", _("Show / Hide console")); - ADD_BIND(_("Ctrl d"), _("Start the debugger")); - ADD_BIND(_("Ctrl s"), _("Show memory consumption")); - ADD_BIND(_("Ctrl f"), _("Run in fast mode (*)")); - ADD_BIND(_("Ctrl g"), _("Run in really fast mode (*)")); - ADD_BIND(_("Ctrl m"), _("Toggle mouse capture")); - ADD_BIND(_("Ctrl Alt 1-8"), _("Switch between graphics filters")); - ADD_BIND(_("Ctrl Alt +, -"), _("Increase / Decrease scale factor")); - ADD_BIND(_("Ctrl Alt a"), _("Toggle aspect-ratio correction")); + ADD_BIND(String(_("Ctrl")) + " d", _("Start the debugger")); + ADD_BIND(String(_("Ctrl")) + " s", _("Show memory consumption")); + ADD_BIND(String(_("Ctrl")) + " f", _("Run in fast mode (*)")); + ADD_BIND(String(_("Ctrl")) + " g", _("Run in really fast mode (*)")); + ADD_BIND(String(_("Ctrl")) + " m", _("Toggle mouse capture")); + ADD_BIND(String(_("Ctrl")) + " " + _("Alt") + " 1-8", _("Switch between graphics filters")); + ADD_BIND(String(_("Ctrl")) + " " + _("Alt") + " +, -", _("Increase / Decrease scale factor")); + ADD_BIND(String(_("Ctrl")) + " " + _("Alt") + " a", _("Toggle aspect-ratio correction")); ADD_LINE; ADD_LINE; // FIXME: This should use word-wrapping, and should not assume diff --git a/engines/scumm/imuse/imuse.cpp b/engines/scumm/imuse/imuse.cpp index 4db40e6247..07fd99c809 100644 --- a/engines/scumm/imuse/imuse.cpp +++ b/engines/scumm/imuse/imuse.cpp @@ -57,7 +57,6 @@ _initialized(false), _tempoFactor(0), _player_limit(ARRAYSIZE(_players)), _recycle_players(false), -_direct_passthrough(false), _queue_end(0), _queue_pos(0), _queue_sound(0), @@ -151,22 +150,22 @@ bool IMuseInternal::isMT32(int sound) { tag = READ_BE_UINT32(ptr + 4); switch (tag) { - case MKID_BE('ADL '): - case MKID_BE('ASFX'): // Special AD class for old AdLib sound effects - case MKID_BE('SPK '): + case MKTAG('A','D','L',' '): + case MKTAG('A','S','F','X'): // Special AD class for old AdLib sound effects + case MKTAG('S','P','K',' '): return false; - case MKID_BE('AMI '): - case MKID_BE('ROL '): + case MKTAG('A','M','I',' '): + case MKTAG('R','O','L',' '): return true; - case MKID_BE('MAC '): // Occurs in the Mac version of FOA and MI2 + case MKTAG('M','A','C',' '): // Occurs in the Mac version of FOA and MI2 return true; - case MKID_BE('GMD '): + case MKTAG('G','M','D',' '): return false; - case MKID_BE('MIDI'): // Occurs in Sam & Max + case MKTAG('M','I','D','I'): // Occurs in Sam & Max // HE games use Roland music if (ptr[12] == 'H' && ptr[13] == 'S') return true; @@ -198,20 +197,20 @@ bool IMuseInternal::isMIDI(int sound) { tag = READ_BE_UINT32(ptr + 4); switch (tag) { - case MKID_BE('ADL '): - case MKID_BE('ASFX'): // Special AD class for old AdLib sound effects - case MKID_BE('SPK '): + case MKTAG('A','D','L',' '): + case MKTAG('A','S','F','X'): // Special AD class for old AdLib sound effects + case MKTAG('S','P','K',' '): return false; - case MKID_BE('AMI '): - case MKID_BE('ROL '): + case MKTAG('A','M','I',' '): + case MKTAG('R','O','L',' '): return true; - case MKID_BE('MAC '): // Occurs in the Mac version of FOA and MI2 + case MKTAG('M','A','C',' '): // Occurs in the Mac version of FOA and MI2 return true; - case MKID_BE('GMD '): - case MKID_BE('MIDI'): // Occurs in Sam & Max + case MKTAG('G','M','D',' '): + case MKTAG('M','I','D','I'): // Occurs in Sam & Max return true; } @@ -472,10 +471,6 @@ uint32 IMuseInternal::property(int prop, uint32 value) { _recycle_players = (value != 0); break; - case IMuse::PROP_DIRECT_PASSTHROUGH: - _direct_passthrough = (value != 0); - break; - case IMuse::PROP_GAME_ID: _game_id = value; break; @@ -636,7 +631,7 @@ bool IMuseInternal::startSound_internal(int sound, int offset) { player->clear(); player->setOffsetNote(offset); - return player->startSound(sound, driver, _direct_passthrough); + return player->startSound(sound, driver); } int IMuseInternal::stopSound_internal(int sound) { diff --git a/engines/scumm/imuse/imuse.h b/engines/scumm/imuse/imuse.h index d7ce2b7bdd..1e3b0fd756 100644 --- a/engines/scumm/imuse/imuse.h +++ b/engines/scumm/imuse/imuse.h @@ -58,7 +58,6 @@ public: PROP_GS, PROP_LIMIT_PLAYERS, PROP_RECYCLE_PLAYERS, - PROP_DIRECT_PASSTHROUGH, PROP_GAME_ID }; diff --git a/engines/scumm/imuse/imuse_internal.h b/engines/scumm/imuse/imuse_internal.h index 0014480894..7d46650d2e 100644 --- a/engines/scumm/imuse/imuse_internal.h +++ b/engines/scumm/imuse/imuse_internal.h @@ -155,7 +155,7 @@ struct CommandQueue { // ////////////////////////////////////////////////// -class Player : public MidiDriver { +class Player : public MidiDriver_BASE { /* * External SysEx handler functions shall each be defined in * a separate file. This header file shall be included at the @@ -174,7 +174,6 @@ protected: protected: MidiDriver *_midi; MidiParser *_parser; - bool _passThrough; // Only respond to EOT, all else direct to MidiDriver Part *_parts; bool _active; @@ -278,21 +277,14 @@ public: void setSpeed(byte speed); int setTranspose(byte relative, int b); int setVolume(byte vol); - bool startSound(int sound, MidiDriver *midi, bool passThrough); + bool startSound(int sound, MidiDriver *midi); int getMusicTimer() const; public: // MidiDriver interface - int open() { return 0; } - void close() { } void send(uint32 b); - const char *getErrorName(int error_code) { return "Unknown"; } void sysEx(const byte *msg, uint16 length); void metaEvent(byte type, byte *data, uint16 length); - void setTimerCallback(void *timer_param, void(*timer_proc)(void *)) { } - uint32 getBaseTempo(); - MidiChannel *allocateChannel() { return 0; } - MidiChannel *getPercussionChannel() { return 0; } }; @@ -424,7 +416,6 @@ protected: int _player_limit; // Limits how many simultaneous music tracks are played bool _recycle_players; // Can we stop a player in order to start another one? - bool _direct_passthrough; // Pass data direct to MidiDriver (no interactivity) uint _queue_end, _queue_pos, _queue_sound; byte _queue_adding; diff --git a/engines/scumm/imuse/imuse_part.cpp b/engines/scumm/imuse/imuse_part.cpp index 40889ec24f..487429c294 100644 --- a/engines/scumm/imuse/imuse_part.cpp +++ b/engines/scumm/imuse/imuse_part.cpp @@ -25,6 +25,8 @@ +#include "common/debug.h" +#include "common/textconsole.h" #include "common/util.h" #include "scumm/imuse/imuse_internal.h" #include "scumm/saveload.h" diff --git a/engines/scumm/imuse/imuse_player.cpp b/engines/scumm/imuse/imuse_player.cpp index ac2b2d4203..4d185d94d7 100644 --- a/engines/scumm/imuse/imuse_player.cpp +++ b/engines/scumm/imuse/imuse_player.cpp @@ -61,7 +61,6 @@ uint16 Player::_active_notes[128]; Player::Player() : _midi(NULL), _parser(NULL), - _passThrough(0), _parts(NULL), _active(false), _scanning(false), @@ -93,7 +92,7 @@ Player::~Player() { } } -bool Player::startSound(int sound, MidiDriver *midi, bool passThrough) { +bool Player::startSound(int sound, MidiDriver *midi) { void *ptr; int i; @@ -119,7 +118,6 @@ bool Player::startSound(int sound, MidiDriver *midi, bool passThrough) { _pan = 0; _transpose = 0; _detune = 0; - _passThrough = passThrough; for (i = 0; i < ARRAYSIZE(_parameterFaders); ++i) _parameterFaders[i].init(); @@ -227,11 +225,6 @@ void Player::setSpeed(byte speed) { } void Player::send(uint32 b) { - if (_passThrough) { - _midi->send(b); - return; - } - byte cmd = (byte)(b & 0xF0); byte chan = (byte)(b & 0x0F); byte param1 = (byte)((b >> 8) & 0xFF); @@ -348,11 +341,6 @@ void Player::sysEx(const byte *p, uint16 len) { byte buf[128]; Part *part; - if (_passThrough) { - _midi->sysEx(p, len); - return; - } - // Check SysEx manufacturer. a = *p++; --len; @@ -998,10 +986,6 @@ void Player::fixAfterLoad() { } } -uint32 Player::getBaseTempo() { - return (_midi ? _midi->getBaseTempo() : 0); -} - void Player::metaEvent(byte type, byte *msg, uint16 len) { if (type == 0x2F) clear(); diff --git a/engines/scumm/imuse/sysex_scumm.cpp b/engines/scumm/imuse/sysex_scumm.cpp index c96b2f757b..78028c6056 100644 --- a/engines/scumm/imuse/sysex_scumm.cpp +++ b/engines/scumm/imuse/sysex_scumm.cpp @@ -24,6 +24,7 @@ #include "common/endian.h" +#include "common/textconsole.h" #include "common/util.h" /* diff --git a/engines/scumm/imuse_digi/dimuse.cpp b/engines/scumm/imuse_digi/dimuse.cpp index 516a0497fa..3831689def 100644 --- a/engines/scumm/imuse_digi/dimuse.cpp +++ b/engines/scumm/imuse_digi/dimuse.cpp @@ -31,6 +31,7 @@ #include "scumm/sound.h" #include "scumm/imuse_digi/dimuse.h" #include "scumm/imuse_digi/dimuse_bndmgr.h" +#include "scumm/imuse_digi/dimuse_codecs.h" #include "scumm/imuse_digi/dimuse_track.h" #include "audio/audiostream.h" diff --git a/engines/scumm/imuse_digi/dimuse.h b/engines/scumm/imuse_digi/dimuse.h index 236edb5a89..1e96aa8827 100644 --- a/engines/scumm/imuse_digi/dimuse.h +++ b/engines/scumm/imuse_digi/dimuse.h @@ -26,6 +26,8 @@ #define SCUMM_IMUSE_DIGI_H #include "common/scummsys.h" +#include "common/mutex.h" +#include "common/textconsole.h" #include "common/util.h" #include "scumm/imuse_digi/dimuse.h" diff --git a/engines/scumm/imuse_digi/dimuse_bndmgr.cpp b/engines/scumm/imuse_digi/dimuse_bndmgr.cpp index f10f17f3d8..cb894d77cc 100644 --- a/engines/scumm/imuse_digi/dimuse_bndmgr.cpp +++ b/engines/scumm/imuse_digi/dimuse_bndmgr.cpp @@ -28,6 +28,7 @@ #include "scumm/util.h" #include "scumm/file.h" #include "scumm/imuse_digi/dimuse_bndmgr.h" +#include "scumm/imuse_digi/dimuse_codecs.h" namespace Scumm { @@ -92,7 +93,7 @@ int BundleDirCache::matchFile(const char *filename) { error("BundleDirCache::matchFileFile() Can't find free slot for file bundle dir cache"); tag = file.readUint32BE(); - if (tag == MKID_BE('LB23')) + if (tag == MKTAG('L','B','2','3')) _budleDirCache[freeSlot].isCompressed = true; offset = file.readUint32BE(); @@ -112,7 +113,7 @@ int BundleDirCache::matchFile(const char *filename) { int32 z = 0; int32 z2; - if (tag == MKID_BE('LB23')) { + if (tag == MKTAG('L','B','2','3')) { file.read(_budleDirCache[freeSlot].bundleTable[i].filename, 24); } else { for (z2 = 0; z2 < 8; z2++) @@ -224,7 +225,7 @@ bool BundleMgr::loadCompTable(int32 index) { assert(_numCompItems > 0); _file->seek(8, SEEK_CUR); - if (tag != MKID_BE('COMP')) { + if (tag != MKTAG('C','O','M','P')) { error("BundleMgr::loadCompTable() Compressed sound %d (%s:%d) invalid (%s)", index, _file->getName(), _bundleTable[index].offset, tag2str(tag)); return false; } diff --git a/engines/scumm/imuse_digi/dimuse_bndmgr.h b/engines/scumm/imuse_digi/dimuse_bndmgr.h index a78697a854..bed1ac6549 100644 --- a/engines/scumm/imuse_digi/dimuse_bndmgr.h +++ b/engines/scumm/imuse_digi/dimuse_bndmgr.h @@ -107,14 +107,6 @@ public: int32 decompressSampleByCurIndex(int32 offset, int32 size, byte **compFinal, int headerSize, bool headerOutside); }; -namespace BundleCodecs { - -uint32 decode12BitsSample(const byte *src, byte **dst, uint32 size); -void initializeImcTables(); -int32 decompressCodec(int32 codec, byte *compInput, byte *compOutput, int32 inputSize); - -} // End of namespace BundleCodecs - } // End of namespace Scumm #endif diff --git a/engines/scumm/imuse_digi/dimuse_codecs.cpp b/engines/scumm/imuse_digi/dimuse_codecs.cpp index 3f7c341701..c78e313fc2 100644 --- a/engines/scumm/imuse_digi/dimuse_codecs.cpp +++ b/engines/scumm/imuse_digi/dimuse_codecs.cpp @@ -25,6 +25,9 @@ #include "common/scummsys.h" #include "common/endian.h" #include "common/util.h" +#include "scumm/imuse_digi/dimuse_codecs.h" + +#include "audio/decoders/adpcm_intern.h" namespace Scumm { @@ -59,23 +62,10 @@ uint32 decode12BitsSample(const byte *src, byte **dst, uint32 size) { * varies the size of each "packet" between 2 and 7 bits. */ -static byte _imcTableEntryBitCount[89]; - -static const int16 imcTable[89] = { - 7, 8, 9, 10, 11, 12, 13, 14, - 16, 17, 19, 21, 23, 25, 28, 31, - 34, 37, 41, 45, 50, 55, 60, 66, - 73, 80, 88, 97, 107, 118, 130, 143, - 157, 173, 190, 209, 230, 253, 279, 307, - 337, 371, 408, 449, 494, 544, 598, 658, - 724, 796, 876, 963, 1060, 1166, 1282, 1411, - 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, - 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, - 7132, 7845, 8630, 9493,10442,11487,12635,13899, - 15289,16818,18500,20350,22385,24623,27086,29794, - 32767 -}; +static byte *_destImcTable = NULL; +static uint32 *_destImcTable2 = NULL; +// This table is the "big brother" of Audio::ADPCMStream::_stepAdjustTable. static const byte imxOtherTable[6][64] = { { 0xFF, @@ -116,23 +106,47 @@ static const byte imxOtherTable[6][64] = { } }; +void releaseImcTables() { + free(_destImcTable); + free(_destImcTable2); +} + void initializeImcTables() { int pos; - for (pos = 0; pos < ARRAYSIZE(imcTable); ++pos) { - byte put = 0; - int32 tableValue = ((imcTable[pos] * 4) / 7) / 2; + if (!_destImcTable) _destImcTable = (byte *)calloc(89, sizeof(byte)); + if (!_destImcTable2) _destImcTable2 = (uint32 *)calloc(89 * 64, sizeof(uint32)); + + for (pos = 0; pos <= 88; ++pos) { + byte put = 1; + int32 tableValue = ((Audio::Ima_ADPCMStream::_imaTable[pos] * 4) / 7) / 2; while (tableValue != 0) { tableValue /= 2; put++; } - if (put < 2) { - put = 2; + if (put < 3) { + put = 3; + } + if (put > 8) { + put = 8; } - if (put > 7) { - put = 7; + _destImcTable[pos] = put - 1; + } + + for (int n = 0; n < 64; n++) { + for (pos = 0; pos <= 88; ++pos) { + int32 count = 32; + int32 put = 0; + int32 tableValue = Audio::Ima_ADPCMStream::_imaTable[pos]; + do { + if ((count & n) != 0) { + put += tableValue; + } + count /= 2; + tableValue /= 2; + } while (count != 0); + _destImcTable2[n + pos * 64] = put; } - _imcTableEntryBitCount[pos] = put; } } @@ -183,8 +197,128 @@ static int32 compDecode(byte *src, byte *dst) { } #undef NextBit +int32 decompressADPCM(byte *compInput, byte *compOutput, int channels) { + byte *src; + + // Decoder for the the IMA ADPCM variants used in COMI. + // Contrary to regular IMA ADPCM, this codec uses a variable + // bitsize for the encoded data. + + const int MAX_CHANNELS = 2; + int32 outputSamplesLeft; + int32 destPos; + int16 firstWord; + byte initialTablePos[MAX_CHANNELS] = {0, 0}; + int32 initialimcTableEntry[MAX_CHANNELS] = {7, 7}; + int32 initialOutputWord[MAX_CHANNELS] = {0, 0}; + int32 totalBitOffset, curTablePos, outputWord; + byte *dst; + int i; + + // We only support mono and stereo + assert(channels == 1 || channels == 2); + + src = compInput; + dst = compOutput; + outputSamplesLeft = 0x1000; + + // Every data packet contains 0x2000 bytes of audio data + // when extracted. In order to encode bigger data sets, + // one has to split the data into multiple blocks. + // + // Every block starts with a 2 byte word. If that word is + // non-zero, it indicates the size of a block of raw audio + // data (not encoded) following it. That data we simply copy + // to the output buffer and then proceed by decoding the + // remaining data. + // + // If on the other hand the word is zero, then what follows + // are 7*channels bytes containing seed data for the decoder. + firstWord = READ_BE_UINT16(src); + src += 2; + if (firstWord != 0) { + // Copy raw data + memcpy(dst, src, firstWord); + dst += firstWord; + src += firstWord; + assert((firstWord & 1) == 0); + outputSamplesLeft -= firstWord / 2; + } else { + // Read the seed values for the decoder. + for (i = 0; i < channels; i++) { + initialTablePos[i] = *src; + src += 1; + initialimcTableEntry[i] = READ_BE_UINT32(src); + src += 4; + initialOutputWord[i] = READ_BE_UINT32(src); + src += 4; + } + } + + totalBitOffset = 0; + // The channels are encoded separately. + for (int chan = 0; chan < channels; chan++) { + // Read initial state (this makes it possible for the data stream + // to be split & spread across multiple data chunks. + curTablePos = initialTablePos[chan]; + //imcTableEntry = initialimcTableEntry[chan]; + outputWord = initialOutputWord[chan]; + + // We need to interleave the channels in the output; we achieve + // that by using a variables dest offset: + destPos = chan * 2; + + const int bound = (channels == 1) + ? outputSamplesLeft + : ((chan == 0) + ? (outputSamplesLeft+1) / 2 + : outputSamplesLeft / 2); + for (i = 0; i < bound; ++i) { + // Determine the size (in bits) of the next data packet + const int32 curTableEntryBitCount = _destImcTable[curTablePos]; + assert(2 <= curTableEntryBitCount && curTableEntryBitCount <= 7); + + // Read the next data packet + const byte *readPos = src + (totalBitOffset >> 3); + const uint16 readWord = (uint16)(READ_BE_UINT16(readPos) << (totalBitOffset & 7)); + const byte packet = (byte)(readWord >> (16 - curTableEntryBitCount)); + + // Advance read position to the next data packet + totalBitOffset += curTableEntryBitCount; + + // Decode the data packet into a delta value for the output signal. + const byte signBitMask = (1 << (curTableEntryBitCount - 1)); + const byte dataBitMask = (signBitMask - 1); + const byte data = (packet & dataBitMask); + + const int32 tmpA = (data << (7 - curTableEntryBitCount)); + const int32 imcTableEntry = Audio::Ima_ADPCMStream::_imaTable[curTablePos] >> (curTableEntryBitCount - 1); + int32 delta = imcTableEntry + _destImcTable2[tmpA + (curTablePos * 64)]; + + // The topmost bit in the data packet tells is a sign bit + if ((packet & signBitMask) != 0) { + delta = -delta; + } + + // Accumulate the delta onto the output data + outputWord += delta; + + // Clip outputWord to 16 bit signed, and write it into the destination stream + outputWord = CLIP<int32>(outputWord, -0x8000, 0x7fff); + WRITE_BE_UINT16(dst + destPos, outputWord); + destPos += channels << 1; + + // Adjust the curTablePos + curTablePos += (int8)imxOtherTable[curTableEntryBitCount - 2][data]; + curTablePos = CLIP<int32>(curTablePos, 0, ARRAYSIZE(Audio::Ima_ADPCMStream::_imaTable) - 1); + } + } + + return 0x2000; +} + int32 decompressCodec(int32 codec, byte *compInput, byte *compOutput, int32 inputSize) { - int32 outputSize, channels; + int32 outputSize; int32 offset1, offset2, offset3, length, k, c, s, j, r, t, z; byte *src, *t_table, *p, *ptr; byte t_tmp1, t_tmp2; @@ -506,132 +640,7 @@ int32 decompressCodec(int32 codec, byte *compInput, byte *compOutput, int32 inpu case 13: case 15: - if (codec == 13) { - channels = 1; - } else { - channels = 2; - } - - { - // Decoder for the the IMA ADPCM variants used in COMI. - // Contrary to regular IMA ADPCM, this codec uses a variable - // bitsize for the encoded data. - - const int MAX_CHANNELS = 2; - int32 outputSamplesLeft; - int32 destPos; - int16 firstWord; - byte initialTablePos[MAX_CHANNELS] = {0, 0}; - int32 initialimcTableEntry[MAX_CHANNELS] = {7, 7}; - int32 initialOutputWord[MAX_CHANNELS] = {0, 0}; - int32 totalBitOffset, curTablePos, outputWord; - byte *dst; - int i; - - // We only support mono and stereo - assert(channels == 1 || channels == 2); - - src = compInput; - dst = compOutput; - outputSize = 0x2000; - outputSamplesLeft = 0x1000; - - // Every data packet contains 0x2000 bytes of audio data - // when extracted. In order to encode bigger data sets, - // one has to split the data into multiple blocks. - // - // Every block starts with a 2 byte word. If that word is - // non-zero, it indicates the size of a block of raw audio - // data (not encoded) following it. That data we simply copy - // to the output buffer and the proceed by decoding the - // remaining data. - // - // If on the other hand the word is zero, then what follows - // are 7*channels bytes containing seed data for the decoder. - firstWord = READ_BE_UINT16(src); - src += 2; - if (firstWord != 0) { - // Copy raw data - memcpy(dst, src, firstWord); - dst += firstWord; - src += firstWord; - assert((firstWord & 1) == 0); - outputSamplesLeft -= firstWord / 2; - } else { - // Read the seed values for the decoder. - for (i = 0; i < channels; i++) { - initialTablePos[i] = *src; - src += 1; - initialimcTableEntry[i] = READ_BE_UINT32(src); - src += 4; - initialOutputWord[i] = READ_BE_UINT32(src); - src += 4; - } - } - - totalBitOffset = 0; - // The channels are encoded separately. - for (int chan = 0; chan < channels; chan++) { - // Read initial state (this makes it possible for the data stream - // to be split & spread across multiple data chunks. - curTablePos = initialTablePos[chan]; - //imcTableEntry = initialimcTableEntry[chan]; - outputWord = initialOutputWord[chan]; - - // We need to interleave the channels in the output; we achieve - // that by using a variables dest offset: - destPos = chan * 2; - - const int bound = (channels == 1) - ? outputSamplesLeft - : ((chan == 0) - ? (outputSamplesLeft+1) / 2 - : outputSamplesLeft / 2); - for (i = 0; i < bound; ++i) { - // Determine the size (in bits) of the next data packet - const int32 curTableEntryBitCount = _imcTableEntryBitCount[curTablePos]; - assert(2 <= curTableEntryBitCount && curTableEntryBitCount <= 7); - - // Read the next data packet - const byte *readPos = src + (totalBitOffset >> 3); - const uint16 readWord = (uint16)(READ_BE_UINT16(readPos) << (totalBitOffset & 7)); - const byte packet = (byte)(readWord >> (16 - curTableEntryBitCount)); - - // Advance read position to the next data packet - totalBitOffset += curTableEntryBitCount; - - // Decode the data packet into a delta value for the output signal. - const byte signBitMask = (1 << (curTableEntryBitCount - 1)); - const byte dataBitMask = (signBitMask - 1); - const byte data = (packet & dataBitMask); - - int32 delta = imcTable[curTablePos] * (2 * data + 1) >> (curTableEntryBitCount - 1); - - // The topmost bit in the data packet tells is a sign bit - if ((packet & signBitMask) != 0) { - delta = -delta; - } - - // Accumulate the delta onto the output data - outputWord += delta; - - // Clip outputWord to 16 bit signed, and write it into the destination stream - if (outputWord > 0x7fff) - outputWord = 0x7fff; - if (outputWord < -0x8000) - outputWord = -0x8000; - WRITE_BE_UINT16(dst + destPos, outputWord); - destPos += channels << 1; - - // Adjust the curTablePos - curTablePos += (int8)imxOtherTable[curTableEntryBitCount - 2][data]; - if (curTablePos < 0) - curTablePos = 0; - else if (curTablePos >= ARRAYSIZE(imcTable)) - curTablePos = ARRAYSIZE(imcTable) - 1; - } - } - } + outputSize = decompressADPCM(compInput, compOutput, (codec == 13) ? 1 : 2); break; default: diff --git a/engines/scumm/imuse_digi/dimuse_codecs.h b/engines/scumm/imuse_digi/dimuse_codecs.h new file mode 100644 index 0000000000..71fd24c3ac --- /dev/null +++ b/engines/scumm/imuse_digi/dimuse_codecs.h @@ -0,0 +1,44 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + */ + +#ifndef SCUMM_IMUSE_DIGI_CODECS_H +#define SCUMM_IMUSE_DIGI_CODECS_H + +#include "common/scummsys.h" + +namespace Scumm { + +namespace BundleCodecs { + +uint32 decode12BitsSample(const byte *src, byte **dst, uint32 size); +int32 decompressCodec(int32 codec, byte *compInput, byte *compOutput, int32 inputSize); + +void initializeImcTables(); +void releaseImcTables(); + +} // End of namespace BundleCodecs + +} // End of namespace Scumm + +#endif diff --git a/engines/scumm/imuse_digi/dimuse_sndmgr.cpp b/engines/scumm/imuse_digi/dimuse_sndmgr.cpp index 00074a951a..2cd90c4f2b 100644 --- a/engines/scumm/imuse_digi/dimuse_sndmgr.cpp +++ b/engines/scumm/imuse_digi/dimuse_sndmgr.cpp @@ -34,8 +34,9 @@ #include "scumm/scumm.h" #include "scumm/util.h" #include "scumm/imuse_digi/dimuse.h" -#include "scumm/imuse_digi/dimuse_sndmgr.h" #include "scumm/imuse_digi/dimuse_bndmgr.h" +#include "scumm/imuse_digi/dimuse_codecs.h" +#include "scumm/imuse_digi/dimuse_sndmgr.h" namespace Scumm { @@ -56,6 +57,7 @@ ImuseDigiSndMgr::~ImuseDigiSndMgr() { } delete _cacheBundleDir; + BundleCodecs::releaseImcTables(); } void ImuseDigiSndMgr::countElements(byte *ptr, int &numRegions, int &numJumps, int &numSyncs, int &numMarkers) { @@ -65,32 +67,32 @@ void ImuseDigiSndMgr::countElements(byte *ptr, int &numRegions, int &numJumps, i do { tag = READ_BE_UINT32(ptr); ptr += 4; switch (tag) { - case MKID_BE('STOP'): - case MKID_BE('FRMT'): - case MKID_BE('DATA'): + case MKTAG('S','T','O','P'): + case MKTAG('F','R','M','T'): + case MKTAG('D','A','T','A'): size = READ_BE_UINT32(ptr); ptr += size + 4; break; - case MKID_BE('TEXT'): + case MKTAG('T','E','X','T'): if (!scumm_stricmp((const char *)(ptr + 8), "exit")) numMarkers++; size = READ_BE_UINT32(ptr); ptr += size + 4; break; - case MKID_BE('REGN'): + case MKTAG('R','E','G','N'): numRegions++; size = READ_BE_UINT32(ptr); ptr += size + 4; break; - case MKID_BE('JUMP'): + case MKTAG('J','U','M','P'): numJumps++; size = READ_BE_UINT32(ptr); ptr += size + 4; break; - case MKID_BE('SYNC'): + case MKTAG('S','Y','N','C'): numSyncs++; size = READ_BE_UINT32(ptr); ptr += size + 4; break; default: error("ImuseDigiSndMgr::countElements() Unknown sfx header '%s'", tag2str(tag)); } - } while (tag != MKID_BE('DATA')); + } while (tag != MKTAG('D','A','T','A')); } void ImuseDigiSndMgr::prepareSoundFromRMAP(Common::SeekableReadStream *file, SoundDesc *sound, int32 offset, int32 size) { @@ -98,7 +100,7 @@ void ImuseDigiSndMgr::prepareSoundFromRMAP(Common::SeekableReadStream *file, Sou file->seek(offset, SEEK_SET); uint32 tag = file->readUint32BE(); - assert(tag == MKID_BE('RMAP')); + assert(tag == MKTAG('R','M','A','P')); int32 version = file->readUint32BE(); if (version != 3) { if (version == 2) { @@ -153,7 +155,7 @@ void ImuseDigiSndMgr::prepareSoundFromRMAP(Common::SeekableReadStream *file, Sou } void ImuseDigiSndMgr::prepareSound(byte *ptr, SoundDesc *sound) { - if (READ_BE_UINT32(ptr) == MKID_BE('Crea')) { + if (READ_BE_UINT32(ptr) == MKTAG('C','r','e','a')) { bool quit = false; int len; @@ -222,7 +224,7 @@ void ImuseDigiSndMgr::prepareSound(byte *ptr, SoundDesc *sound) { } offset += len; } - } else if (READ_BE_UINT32(ptr) == MKID_BE('iMUS')) { + } else if (READ_BE_UINT32(ptr) == MKTAG('i','M','U','S')) { uint32 tag; int32 size = 0; byte *s_ptr = ptr; @@ -250,13 +252,13 @@ void ImuseDigiSndMgr::prepareSound(byte *ptr, SoundDesc *sound) { do { tag = READ_BE_UINT32(ptr); ptr += 4; switch (tag) { - case MKID_BE('FRMT'): + case MKTAG('F','R','M','T'): ptr += 12; sound->bits = READ_BE_UINT32(ptr); ptr += 4; sound->freq = READ_BE_UINT32(ptr); ptr += 4; sound->channels = READ_BE_UINT32(ptr); ptr += 4; break; - case MKID_BE('TEXT'): + case MKTAG('T','E','X','T'): if (!scumm_stricmp((const char *)(ptr + 8), "exit")) { sound->marker[curIndexMarker].pos = READ_BE_UINT32(ptr + 4); sound->marker[curIndexMarker].length = strlen((const char *)(ptr + 8)) + 1; @@ -267,16 +269,16 @@ void ImuseDigiSndMgr::prepareSound(byte *ptr, SoundDesc *sound) { } size = READ_BE_UINT32(ptr); ptr += size + 4; break; - case MKID_BE('STOP'): + case MKTAG('S','T','O','P'): size = READ_BE_UINT32(ptr); ptr += size + 4; break; - case MKID_BE('REGN'): + case MKTAG('R','E','G','N'): ptr += 4; sound->region[curIndexRegion].offset = READ_BE_UINT32(ptr); ptr += 4; sound->region[curIndexRegion].length = READ_BE_UINT32(ptr); ptr += 4; curIndexRegion++; break; - case MKID_BE('JUMP'): + case MKTAG('J','U','M','P'): ptr += 4; sound->jump[curIndexJump].offset = READ_BE_UINT32(ptr); ptr += 4; sound->jump[curIndexJump].dest = READ_BE_UINT32(ptr); ptr += 4; @@ -284,7 +286,7 @@ void ImuseDigiSndMgr::prepareSound(byte *ptr, SoundDesc *sound) { sound->jump[curIndexJump].fadeDelay = READ_BE_UINT32(ptr); ptr += 4; curIndexJump++; break; - case MKID_BE('SYNC'): + case MKTAG('S','Y','N','C'): size = READ_BE_UINT32(ptr); ptr += 4; sound->sync[curIndexSync].size = size; sound->sync[curIndexSync].ptr = new byte[size]; @@ -293,13 +295,13 @@ void ImuseDigiSndMgr::prepareSound(byte *ptr, SoundDesc *sound) { curIndexSync++; ptr += size; break; - case MKID_BE('DATA'): + case MKTAG('D','A','T','A'): ptr += 4; break; default: error("ImuseDigiSndMgr::prepareSound(%d/%s) Unknown sfx header '%s'", sound->soundId, sound->name, tag2str(tag)); } - } while (tag != MKID_BE('DATA')); + } while (tag != MKTAG('D','A','T','A')); sound->offsetData = ptr - s_ptr; } else { error("ImuseDigiSndMgr::prepareSound(): Unknown sound format"); diff --git a/engines/scumm/insane/insane.cpp b/engines/scumm/insane/insane.cpp index f2e50382b3..a82c0ae408 100644 --- a/engines/scumm/insane/insane.cpp +++ b/engines/scumm/insane/insane.cpp @@ -1413,7 +1413,7 @@ int32 Insane::smush_setupSanWithFlu(const char *filename, int32 setupsan2, int32 _smush_setupsan1 = setupsan1; /* skip FLUP marker */ - if (READ_BE_UINT32(fluPtr) == MKID_BE('FLUP')) + if (READ_BE_UINT32(fluPtr) == MKTAG('F','L','U','P')) tmp += 8; _smush_setupsan2 = setupsan2; diff --git a/engines/scumm/insane/insane_iact.cpp b/engines/scumm/insane/insane_iact.cpp index 942256b1a4..265931ecc2 100644 --- a/engines/scumm/insane/insane_iact.cpp +++ b/engines/scumm/insane/insane_iact.cpp @@ -62,7 +62,7 @@ void Insane::procIACT(byte *renderBitmap, int32 codecparam, int32 setupsan12, void Insane::iactScene1(byte *renderBitmap, int32 codecparam, int32 setupsan12, int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags, int16 par1, int16 par2, int16 par3, int16 par4) { - int16 par5, par6, par7, par9, par11, par13, tmp; + int16 par5, par6, par7, par9, par11, par13; switch (par1) { case 2: // PATCH @@ -99,15 +99,15 @@ void Insane::iactScene1(byte *renderBitmap, int32 codecparam, int32 setupsan12, if (par2 != 13) break; - tmp = b.readUint16LE(); // +8 - tmp = b.readUint16LE(); // +10 - par7 = b.readUint16LE(); // +12 dx - tmp = b.readUint16LE(); // +14 - par9 = b.readUint16LE(); // +16 bx - tmp = b.readUint16LE(); // +18 - par11 = b.readUint16LE(); // +20 cx - tmp = b.readUint16LE(); // +22 - par13 = b.readUint16LE(); // +24 ax + b.readUint16LE(); // +8 + b.readUint16LE(); // +10 + par7 = b.readUint16LE(); // +12 dx + b.readUint16LE(); // +14 + par9 = b.readUint16LE(); // +16 bx + b.readUint16LE(); // +18 + par11 = b.readUint16LE(); // +20 cx + b.readUint16LE(); // +22 + par13 = b.readUint16LE(); // +24 ax if (par13 > _actor[0].x || par11 < _actor[0].x) { _tiresRustle = true; diff --git a/engines/scumm/midiparser_ro.cpp b/engines/scumm/midiparser_ro.cpp index e737d747ac..be77e4fd66 100644 --- a/engines/scumm/midiparser_ro.cpp +++ b/engines/scumm/midiparser_ro.cpp @@ -26,6 +26,7 @@ #include "audio/midiparser.h" #include "audio/mididrv.h" +#include "common/textconsole.h" #include "common/util.h" namespace Scumm { diff --git a/engines/scumm/nut_renderer.cpp b/engines/scumm/nut_renderer.cpp index d56017c6f5..7f250e45e0 100644 --- a/engines/scumm/nut_renderer.cpp +++ b/engines/scumm/nut_renderer.cpp @@ -95,7 +95,7 @@ void NutRenderer::loadFont(const char *filename) { } uint32 tag = file.readUint32BE(); - if (tag != MKID_BE('ANIM')) { + if (tag != MKTAG('A','N','I','M')) { error("NutRenderer::loadFont() there is no ANIM chunk in font header"); } @@ -104,7 +104,7 @@ void NutRenderer::loadFont(const char *filename) { file.read(dataSrc, length); file.close(); - if (READ_BE_UINT32(dataSrc) != MKID_BE('AHDR')) { + if (READ_BE_UINT32(dataSrc) != MKTAG('A','H','D','R')) { error("NutRenderer::loadFont() there is no AHDR chunk in font header"); } @@ -142,12 +142,12 @@ void NutRenderer::loadFont(const char *filename) { offset = 0; for (l = 0; l < _numChars; l++) { offset += READ_BE_UINT32(dataSrc + offset + 4) + 8; - if (READ_BE_UINT32(dataSrc + offset) != MKID_BE('FRME')) { + if (READ_BE_UINT32(dataSrc + offset) != MKTAG('F','R','M','E')) { error("NutRenderer::loadFont(%s) there is no FRME chunk %d (offset %x)", filename, l, offset); break; } offset += 8; - if (READ_BE_UINT32(dataSrc + offset) != MKID_BE('FOBJ')) { + if (READ_BE_UINT32(dataSrc + offset) != MKTAG('F','O','B','J')) { error("NutRenderer::loadFont(%s) there is no FOBJ chunk in FRME chunk %d (offset %x)", filename, l, offset); break; } diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp index c44043ca81..c2547f74f4 100644 --- a/engines/scumm/object.cpp +++ b/engines/scumm/object.cpp @@ -416,7 +416,7 @@ void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) { debug(0, "getObjectXYPos: Can't find object %d", object); return; } - imhd = (const ImageHeader *)findResourceData(MKID_BE('IMHD'), ptr); + imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), ptr); assert(imhd); if (_game.version == 8) { switch (FROM_LE_32(imhd->v8.version)) { @@ -655,7 +655,7 @@ void ScummEngine::drawObject(int obj, int arg) { flags |= Gdi::dbDrawMaskOnAll; #ifdef ENABLE_HE - if (_game.heversion >= 70 && findResource(MKID_BE('SMAP'), ptr) == NULL) + if (_game.heversion >= 70 && findResource(MKTAG('S','M','A','P'), ptr) == NULL) _gdi->drawBMAPObject(ptr, &_virtscr[kMainVirtScreen], obj, od.x_pos, od.y_pos, od.width, od.height); else #endif @@ -762,12 +762,12 @@ void ScummEngine::resetRoomObjects() { for (i = 0; i < _numObjectsInRoom; i++) { od = &_objs[findLocalObjectSlot()]; - ptr = obcds.findNext(MKID_BE('OBCD')); + ptr = obcds.findNext(MKTAG('O','B','C','D')); if (ptr == NULL) error("Room %d missing object code block(s)", _roomResource); od->OBCDoffset = ptr - rootptr; - cdhd = (const CodeHeader *)findResourceData(MKID_BE('CDHD'), ptr); + cdhd = (const CodeHeader *)findResourceData(MKTAG('C','D','H','D'), ptr); if (_game.version >= 7) od->obj_nr = READ_LE_UINT16(&(cdhd->v7.obj_id)); @@ -779,7 +779,7 @@ void ScummEngine::resetRoomObjects() { if (_dumpScripts) { char buf[32]; sprintf(buf, "roomobj-%d-", _roomResource); - ptr = findResource(MKID_BE('VERB'), ptr); + ptr = findResource(MKTAG('V','E','R','B'), ptr); dumpResource(buf, od->obj_nr, ptr); } @@ -788,7 +788,7 @@ void ScummEngine::resetRoomObjects() { searchptr = room; ResourceIterator obims(room, false); for (i = 0; i < _numObjectsInRoom; i++) { - ptr = obims.findNext(MKID_BE('OBIM')); + ptr = obims.findNext(MKTAG('O','B','I','M')); if (ptr == NULL) error("Room %d missing image blocks(s)", _roomResource); @@ -870,7 +870,7 @@ void ScummEngine_v4::resetRoomObjects() { for (i = 0; i < _numObjectsInRoom; i++) { od = &_objs[findLocalObjectSlot()]; - ptr = obcds.findNext(MKID_BE('OBCD')); + ptr = obcds.findNext(MKTAG('O','B','C','D')); if (ptr == NULL) error("Room %d missing object code block(s)", _roomResource); @@ -887,7 +887,7 @@ void ScummEngine_v4::resetRoomObjects() { for (i = 0; i < _numObjectsInRoom; i++) { // In the PC Engine version of Loom, there aren't image blocks // for all objects. - ptr = obims.findNext(MKID_BE('OBIM')); + ptr = obims.findNext(MKTAG('O','B','I','M')); if (ptr == NULL) break; @@ -991,11 +991,11 @@ void ScummEngine::resetRoomObject(ObjectData *od, const byte *room, const byte * searchptr = room; } - cdhd = (const CodeHeader *)findResourceData(MKID_BE('CDHD'), searchptr + od->OBCDoffset); + cdhd = (const CodeHeader *)findResourceData(MKTAG('C','D','H','D'), searchptr + od->OBCDoffset); if (cdhd == NULL) error("Room %d missing CDHD blocks(s)", _roomResource); if (od->OBIMoffset) - imhd = (const ImageHeader *)findResourceData(MKID_BE('IMHD'), room + od->OBIMoffset); + imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), room + od->OBIMoffset); od->flags = Gdi::dbAllowMaskOr; @@ -1194,7 +1194,7 @@ const byte *ScummEngine::getObjOrActorName(int obj) { return (objptr + offset); } - return findResourceData(MKID_BE('OBNA'), objptr); + return findResourceData(MKTAG('O','B','N','A'), objptr); } void ScummEngine::setObjectName(int obj) { @@ -1278,7 +1278,7 @@ const byte *ScummEngine::getOBIMFromObjectData(const ObjectData &od) { if (od.fl_object_index) { ptr = getResourceAddress(rtFlObject, od.fl_object_index); - ptr = findResource(MKID_BE('OBIM'), ptr); + ptr = findResource(MKTAG('O','B','I','M'), ptr); } else { ptr = getResourceAddress(rtRoom, _roomResource); if (ptr) @@ -1288,23 +1288,23 @@ const byte *ScummEngine::getOBIMFromObjectData(const ObjectData &od) { } static const uint32 IMxx_tags[] = { - MKID_BE('IM00'), - MKID_BE('IM01'), - MKID_BE('IM02'), - MKID_BE('IM03'), - MKID_BE('IM04'), - MKID_BE('IM05'), - MKID_BE('IM06'), - MKID_BE('IM07'), - MKID_BE('IM08'), - MKID_BE('IM09'), - MKID_BE('IM0A'), - MKID_BE('IM0B'), - MKID_BE('IM0C'), - MKID_BE('IM0D'), - MKID_BE('IM0E'), - MKID_BE('IM0F'), - MKID_BE('IM10') + MKTAG('I','M','0','0'), + MKTAG('I','M','0','1'), + MKTAG('I','M','0','2'), + MKTAG('I','M','0','3'), + MKTAG('I','M','0','4'), + MKTAG('I','M','0','5'), + MKTAG('I','M','0','6'), + MKTAG('I','M','0','7'), + MKTAG('I','M','0','8'), + MKTAG('I','M','0','9'), + MKTAG('I','M','0','A'), + MKTAG('I','M','0','B'), + MKTAG('I','M','0','C'), + MKTAG('I','M','0','D'), + MKTAG('I','M','0','E'), + MKTAG('I','M','0','F'), + MKTAG('I','M','1','0') }; const byte *ScummEngine::getObjectImage(const byte *ptr, int state) { @@ -1317,15 +1317,15 @@ const byte *ScummEngine::getObjectImage(const byte *ptr, int state) { // The OBIM contains an IMAG, which in turn contains a WRAP, which contains // an OFFS chunk and multiple BOMP/SMAP chunks. To find the right BOMP/SMAP, // we use the offsets in the OFFS chunk, - ptr = findResource(MKID_BE('IMAG'), ptr); + ptr = findResource(MKTAG('I','M','A','G'), ptr); if (!ptr) return 0; - ptr = findResource(MKID_BE('WRAP'), ptr); + ptr = findResource(MKTAG('W','R','A','P'), ptr); if (!ptr) return 0; - ptr = findResource(MKID_BE('OFFS'), ptr); + ptr = findResource(MKTAG('O','F','F','S'), ptr); if (!ptr) return 0; @@ -1348,7 +1348,7 @@ int ScummEngine::getObjectImageCount(int object) { return 0; ptr = getOBIMFromObjectData(_objs[objnum]); - imhd = (const ImageHeader *)findResourceData(MKID_BE('IMHD'), ptr); + imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), ptr); if (!imhd) return 0; @@ -1365,7 +1365,7 @@ int ScummEngine::getObjectImageCount(int object) { int ScummEngine_v8::getObjectIdFromOBIM(const byte *obim) { // In V8, IMHD has no obj_id, but rather a name string. We map the name // back to an object id using a table derived from the DOBJ resource. - const ImageHeader *imhd = (const ImageHeader *)findResourceData(MKID_BE('IMHD'), obim); + const ImageHeader *imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), obim); ObjectNameId *found = (ObjectNameId *)bsearch(imhd->v8.name, _objectIDMap, _objectIDMapSize, sizeof(ObjectNameId), (int (*)(const void*, const void*))strcmp); assert(found); @@ -1373,7 +1373,7 @@ int ScummEngine_v8::getObjectIdFromOBIM(const byte *obim) { } int ScummEngine_v7::getObjectIdFromOBIM(const byte *obim) { - const ImageHeader *imhd = (const ImageHeader *)findResourceData(MKID_BE('IMHD'), obim); + const ImageHeader *imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), obim); return READ_LE_UINT16(&imhd->v7.obj_id); } #endif @@ -1382,7 +1382,7 @@ int ScummEngine::getObjectIdFromOBIM(const byte *obim) { if (_game.features & GF_SMALL_HEADER) return READ_LE_UINT16(obim + 6); - const ImageHeader *imhd = (const ImageHeader *)findResourceData(MKID_BE('IMHD'), obim); + const ImageHeader *imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), obim); return READ_LE_UINT16(&imhd->old.obj_id); } @@ -1400,7 +1400,7 @@ void ScummEngine::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, if (findWhat & foCodeHeader) { fo->obcd = obcdptr = getOBCDFromObject(id); assert(obcdptr); - fo->cdhd = (const CodeHeader *)findResourceData(MKID_BE('CDHD'), obcdptr); + fo->cdhd = (const CodeHeader *)findResourceData(MKTAG('C','D','H','D'), obcdptr); } if (findWhat & foImageHeader) { fo->obim = obimptr = getOBIMFromObjectData(_objs[id2]); @@ -1416,7 +1416,7 @@ void ScummEngine::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, if (_game.features & GF_OLD_BUNDLE) { numobj = roomptr[20]; } else { - const RoomHeader *roomhdr = (const RoomHeader *)findResourceData(MKID_BE('RMHD'), roomptr); + const RoomHeader *roomhdr = (const RoomHeader *)findResourceData(MKTAG('R','M','H','D'), roomptr); if (_game.version == 8) numobj = READ_LE_UINT32(&(roomhdr->v8.numObjects)); @@ -1467,10 +1467,10 @@ void ScummEngine::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, assert(searchptr); ResourceIterator obcds(searchptr, (_game.features & GF_SMALL_HEADER) != 0); for (i = 0; i < numobj; i++) { - obcdptr = obcds.findNext(MKID_BE('OBCD')); + obcdptr = obcds.findNext(MKTAG('O','B','C','D')); if (obcdptr == NULL) error("findObjectInRoom: Not enough code blocks in room %d", room); - cdhd = (const CodeHeader *)findResourceData(MKID_BE('CDHD'), obcdptr); + cdhd = (const CodeHeader *)findResourceData(MKTAG('C','D','H','D'), obcdptr); if (_game.features & GF_SMALL_HEADER) id2 = READ_LE_UINT16(obcdptr + 6); @@ -1495,7 +1495,7 @@ void ScummEngine::findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint id, if (findWhat & foImageHeader) { ResourceIterator obims(roomptr, (_game.features & GF_SMALL_HEADER) != 0); for (i = 0; i < numobj; i++) { - obimptr = obims.findNext(MKID_BE('OBIM')); + obimptr = obims.findNext(MKTAG('O','B','I','M')); if (obimptr == NULL) error("findObjectInRoom: Not enough image blocks in room %d", room); obim_id = getObjectIdFromOBIM(obimptr); @@ -1699,7 +1699,7 @@ void ScummEngine_v6::drawBlastObject(BlastObject *eo) { if (!img) img = getObjectImage(ptr, 1); // Backward compatibility with samnmax blast objects assert(img); - bomp = findResourceData(MKID_BE('BOMP'), img); + bomp = findResourceData(MKTAG('B','O','M','P'), img); } if (!bomp) @@ -1843,7 +1843,7 @@ void ScummEngine::loadFlObject(uint object, uint room) { char buf[32]; const byte *ptr = foir.obcd; sprintf(buf, "roomobj-%d-", room); - ptr = findResource(MKID_BE('VERB'), ptr); + ptr = findResource(MKTAG('V','E','R','B'), ptr); dumpResource(buf, object, ptr); } @@ -1869,7 +1869,7 @@ void ScummEngine::loadFlObject(uint object, uint room) { assert(flob); // Copy object code + object image to floating object - WRITE_UINT32(flob, MKID_BE('FLOB')); + WRITE_UINT32(flob, MKTAG('F','L','O','B')); WRITE_BE_UINT32(flob + 4, flob_size); memcpy(flob + 8, foir.obcd, obcd_size); memcpy(flob + 8 + obcd_size, foir.obim, obim_size); diff --git a/engines/scumm/palette.cpp b/engines/scumm/palette.cpp index 18784151b7..b0786c924d 100644 --- a/engines/scumm/palette.cpp +++ b/engines/scumm/palette.cpp @@ -23,8 +23,11 @@ */ #include "common/system.h" +#include "common/textconsole.h" #include "common/util.h" +#include "graphics/palette.h" + #include "scumm/resource.h" #include "scumm/scumm.h" #include "scumm/scumm_v6.h" @@ -1029,7 +1032,7 @@ void ScummEngine::setCurrentPalette(int palindex) { void ScummEngine::setRoomPalette(int palindex, int room) { const byte *roomptr = getResourceAddress(rtRoom, room); assert(roomptr); - const byte *pals = findResource(MKID_BE('PALS'), roomptr); + const byte *pals = findResource(MKTAG('P','A','L','S'), roomptr); assert(pals); const byte *rgbs = findPalInPals(pals, palindex); assert(rgbs); @@ -1040,11 +1043,11 @@ const byte *ScummEngine::findPalInPals(const byte *pal, int idx) { const byte *offs; uint32 size; - pal = findResource(MKID_BE('WRAP'), pal); + pal = findResource(MKTAG('W','R','A','P'), pal); if (pal == NULL) return NULL; - offs = findResourceData(MKID_BE('OFFS'), pal); + offs = findResourceData(MKTAG('O','F','F','S'), pal); if (offs == NULL) return NULL; diff --git a/engines/scumm/player_mod.h b/engines/scumm/player_mod.h index 67d1bb4cbf..3f97c4cab9 100644 --- a/engines/scumm/player_mod.h +++ b/engines/scumm/player_mod.h @@ -31,7 +31,7 @@ #include "audio/mixer.h" namespace Audio { - class RateConverter; +class RateConverter; } namespace Scumm { diff --git a/engines/scumm/player_nes.h b/engines/scumm/player_nes.h index 5f6e8f2d8d..402eea7bf8 100644 --- a/engines/scumm/player_nes.h +++ b/engines/scumm/player_nes.h @@ -35,7 +35,7 @@ namespace Scumm { class ScummEngine; namespace APUe { - class APU; +class APU; } static const int MAXVOLUME = 0x7F; diff --git a/engines/scumm/player_pce.cpp b/engines/scumm/player_pce.cpp index 4236fb2d6b..46d976773d 100644 --- a/engines/scumm/player_pce.cpp +++ b/engines/scumm/player_pce.cpp @@ -515,7 +515,7 @@ int Player_PCE::readBuffer(int16 *buffer, const int numSamples) { int sampleCopyCnt; int samplesLeft = numSamples; - _mutex.lock(); + Common::StackLock lock(_mutex); while (true) { // copy samples to output buffer @@ -543,8 +543,6 @@ int Player_PCE::readBuffer(int16 *buffer, const int numSamples) { _sampleBufferCnt * sizeof(int16)); } - _mutex.unlock(); - return numSamples; } diff --git a/engines/scumm/player_pce.h b/engines/scumm/player_pce.h index 3f5033f724..42153e8abc 100644 --- a/engines/scumm/player_pce.h +++ b/engines/scumm/player_pce.h @@ -27,6 +27,7 @@ #define SCUMM_PLAYER_PCE_H #include "common/scummsys.h" +#include "common/mutex.h" #include "scumm/music.h" #include "audio/audiostream.h" #include "audio/mixer.h" diff --git a/engines/scumm/player_sid.cpp b/engines/scumm/player_sid.cpp index 34654a68c5..11468f3097 100644 --- a/engines/scumm/player_sid.cpp +++ b/engines/scumm/player_sid.cpp @@ -1287,7 +1287,7 @@ uint8 *Player_SID::getResource(int resID) { int Player_SID::readBuffer(int16 *buffer, const int numSamples) { int samplesLeft = numSamples; - _mutex.lock(); + Common::StackLock lock(_mutex); while (samplesLeft > 0) { // update SID status after each frame @@ -1296,13 +1296,11 @@ int Player_SID::readBuffer(int16 *buffer, const int numSamples) { _cpuCyclesLeft = timingProps[_videoSystem].cyclesPerFrame; } // fetch samples - int sampleCount = _sid->clock(_cpuCyclesLeft, (short*)buffer, samplesLeft); + int sampleCount = _sid->updateClock(_cpuCyclesLeft, (short*)buffer, samplesLeft); samplesLeft -= sampleCount; buffer += sampleCount; } - _mutex.unlock(); - return numSamples; } @@ -1337,7 +1335,7 @@ void Player_SID::startSound(int nr) { // prio 7 is never used in any sound file use this byte for auto-detection. bool isMusic = (data[4] == 0x07); - _mutex.lock(); + Common::StackLock lock(_mutex); if (isMusic) { initMusic(nr); @@ -1345,29 +1343,25 @@ void Player_SID::startSound(int nr) { stopSound_intern(nr); initSound(nr); } - - _mutex.unlock(); } void Player_SID::stopSound(int nr) { if (nr == -1) return; - _mutex.lock(); + Common::StackLock lock(_mutex); stopSound_intern(nr); - _mutex.unlock(); } void Player_SID::stopAllSounds() { - _mutex.lock(); + Common::StackLock lock(_mutex); stopAllSounds_intern(); - _mutex.unlock(); } int Player_SID::getSoundStatus(int nr) const { int result = 0; - //_mutex.lock(); + //Common::StackLock lock(_mutex); if (resID_song == nr && isMusicPlaying) { result = 1; @@ -1379,8 +1373,6 @@ int Player_SID::getSoundStatus(int nr) const { } } - //_mutex.unlock(); - return result; } diff --git a/engines/scumm/player_towns.cpp b/engines/scumm/player_towns.cpp index 06f97fd671..8922ff1730 100644 --- a/engines/scumm/player_towns.cpp +++ b/engines/scumm/player_towns.cpp @@ -622,7 +622,7 @@ int Player_Towns_v2::getSoundStatus(int sound) const { void Player_Towns_v2::startSound(int sound) { uint8 *ptr = _vm->getResourceAddress(rtSound, sound); - if (READ_BE_UINT32(ptr) == MKID_BE('TOWS')) { + if (READ_BE_UINT32(ptr) == MKTAG('T','O','W','S')) { _soundOverride[sound].type = 7; uint8 velo = _soundOverride[sound].velo ? _soundOverride[sound].velo - 1: (ptr[10] + ptr[11] + 1) >> 1; uint8 pan = _soundOverride[sound].pan ? _soundOverride[sound].pan - 1 : 64; @@ -630,7 +630,7 @@ void Player_Towns_v2::startSound(int sound) { _soundOverride[sound].velo = _soundOverride[sound].pan = 0; playPcmTrack(sound, ptr + 8, velo, pan, ptr[52], pri); - } else if (READ_BE_UINT32(ptr) == MKID_BE('SBL ')) { + } else if (READ_BE_UINT32(ptr) == MKTAG('S','B','L',' ')) { _soundOverride[sound].type = 5; playVocTrack(ptr + 27); @@ -680,7 +680,7 @@ int32 Player_Towns_v2::doCommand(int numargs, int args[]) { case 258: if (_soundOverride[args[1]].type == 0) { ptr = _vm->getResourceAddress(rtSound, args[1]); - if (READ_BE_UINT32(ptr) == MKID_BE('TOWS')) + if (READ_BE_UINT32(ptr) == MKTAG('T','O','W','S')) _soundOverride[args[1]].type = 7; } if (_soundOverride[args[1]].type == 7) { @@ -692,7 +692,7 @@ int32 Player_Towns_v2::doCommand(int numargs, int args[]) { case 259: if (_soundOverride[args[1]].type == 0) { ptr = _vm->getResourceAddress(rtSound, args[1]); - if (READ_BE_UINT32(ptr) == MKID_BE('TOWS')) + if (READ_BE_UINT32(ptr) == MKTAG('T','O','W','S')) _soundOverride[args[1]].type = 7; } if (_soundOverride[args[1]].type == 7) { diff --git a/engines/scumm/player_v4a.h b/engines/scumm/player_v4a.h index 108dbcf317..458a39b5fe 100644 --- a/engines/scumm/player_v4a.h +++ b/engines/scumm/player_v4a.h @@ -27,6 +27,7 @@ #define SCUMM_PLAYER_V4A_H #include "common/scummsys.h" +#include "common/util.h" #include "scumm/music.h" #include "audio/mixer.h" #include "audio/mods/tfmx.h" diff --git a/engines/scumm/proc3ARM.s b/engines/scumm/proc3ARM.s index 8b3e31f5f8..5acfa86c29 100644 --- a/engines/scumm/proc3ARM.s +++ b/engines/scumm/proc3ARM.s @@ -25,40 +25,40 @@ .text - .global ClassicProc3RendererShadowARM + .global _ClassicProc3RendererShadowARM -.equ _scaleIndexY , 112 -.equ _numStrips , 108 -.equ _palette , 104 -.equ _shadow_table , 100 -.equ _scaleIndexX , 96 -.equ _scaleX , 92 -.equ _height , 88 -.equ store_r14 , 84 -.equ store_r11 , 80 -.equ store_r10 , 76 -.equ store_r9 , 72 -.equ store_r8 , 68 -.equ store_r7 , 64 -.equ store_r6 , 60 -.equ store_r5 , 56 -.equ store_r4 , 52 -.equ src , 48 -.equ height , 44 -.equ len , 40 -.equ v1_shr , 36 -.equ v1_skip_width , 32 -.equ v1_destptr , 28 -.equ v1_scaleXstep , 24 -.equ v1_mask_ptr , 20 -.equ v1_y , 16 -.equ v1_scaletable , 12 -.equ pitch , 8 -.equ scaleIdxXPtr , 4 -.equ scaleIdxYPtr , 0 +.set _scaleIndexY , 112 +.set _numStrips , 108 +.set _palette , 104 +.set _shadow_table , 100 +.set _scaleIndexX , 96 +.set _scaleX , 92 +.set _height , 88 +.set store_r14 , 84 +.set store_r11 , 80 +.set store_r10 , 76 +.set store_r9 , 72 +.set store_r8 , 68 +.set store_r7 , 64 +.set store_r6 , 60 +.set store_r5 , 56 +.set store_r4 , 52 +.set src , 48 +.set height , 44 +.set len , 40 +.set v1_shr , 36 +.set v1_skip_width , 32 +.set v1_destptr , 28 +.set v1_scaleXstep , 24 +.set v1_mask_ptr , 20 +.set v1_y , 16 +.set v1_scaletable , 12 +.set pitch , 8 +.set scaleIdxXPtr , 4 +.set scaleIdxYPtr , 0 -.equ space , 48 +.set space , 48 @ r0 = _scaleY @ r1 = v1 @@ -71,7 +71,7 @@ @ <> = _palette @ <> = _numstrips @ <> = _scaleIndexY -ClassicProc3RendererShadowARM: +_ClassicProc3RendererShadowARM: @ shadow20 = false @ shadowed = true @ unscaled = false diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp index 5aae59d987..c872a83d14 100644 --- a/engines/scumm/resource.cpp +++ b/engines/scumm/resource.cpp @@ -167,8 +167,6 @@ void ScummEngine::deleteRoomOffsets() { /** Read room offsets */ void ScummEngine::readRoomsOffsets() { - int num, room; - debug(9, "readRoomOffsets()"); if (_game.features & GF_SMALL_HEADER) { @@ -177,13 +175,12 @@ void ScummEngine::readRoomsOffsets() { _fileHandle->seek(16, SEEK_SET); } - num = _fileHandle->readByte(); + int num = _fileHandle->readByte(); while (num--) { - room = _fileHandle->readByte(); + int room = _fileHandle->readByte(); + int offset = _fileHandle->readUint32LE(); if (_res->roomoffs[rtRoom][room] != RES_INVALID_OFFSET) { - _res->roomoffs[rtRoom][room] = _fileHandle->readUint32LE(); - } else { - _fileHandle->readUint32LE(); + _res->roomoffs[rtRoom][room] = offset; } } } @@ -262,26 +259,26 @@ void ScummEngine::readIndexFile() { if (_fileHandle->eos() || _fileHandle->err()) break; switch (blocktype) { - case MKID_BE('DOBJ'): + case MKTAG('D','O','B','J'): _numGlobalObjects = _fileHandle->readUint16LE(); itemsize -= 2; break; - case MKID_BE('DROO'): + case MKTAG('D','R','O','O'): _numRooms = _fileHandle->readUint16LE(); itemsize -= 2; break; - case MKID_BE('DSCR'): + case MKTAG('D','S','C','R'): _numScripts = _fileHandle->readUint16LE(); itemsize -= 2; break; - case MKID_BE('DCOS'): + case MKTAG('D','C','O','S'): _numCostumes = _fileHandle->readUint16LE(); itemsize -= 2; break; - case MKID_BE('DSOU'): + case MKTAG('D','S','O','U'): _numSounds = _fileHandle->readUint16LE(); itemsize -= 2; break; @@ -354,7 +351,7 @@ void ScummEngine_v7::readIndexBlock(uint32 blocktype, uint32 itemsize) { int num; char *ptr; switch (blocktype) { - case MKID_BE('ANAM'): // Used by: The Dig, FT + case MKTAG('A','N','A','M'): // Used by: The Dig, FT debug(9, "found ANAM block, reading audio names"); num = _fileHandle->readUint16LE(); ptr = (char*)malloc(num * 9); @@ -362,7 +359,7 @@ void ScummEngine_v7::readIndexBlock(uint32 blocktype, uint32 itemsize) { _imuseDigital->setAudioNames(num, ptr); break; - case MKID_BE('DRSC'): // Used by: COMI + case MKTAG('D','R','S','C'): // Used by: COMI readResTypeList(rtRoomScripts); break; @@ -375,37 +372,37 @@ void ScummEngine_v7::readIndexBlock(uint32 blocktype, uint32 itemsize) { void ScummEngine_v70he::readIndexBlock(uint32 blocktype, uint32 itemsize) { int i; switch (blocktype) { - case MKID_BE('DIRI'): + case MKTAG('D','I','R','I'): readResTypeList(rtRoomImage); break; - case MKID_BE('DIRM'): + case MKTAG('D','I','R','M'): readResTypeList(rtImage); break; - case MKID_BE('DIRT'): + case MKTAG('D','I','R','T'): readResTypeList(rtTalkie); break; - case MKID_BE('DLFL'): + case MKTAG('D','L','F','L'): i = _fileHandle->readUint16LE(); _fileHandle->seek(-2, SEEK_CUR); _heV7RoomOffsets = (byte *)calloc(2 + (i * 4), 1); _fileHandle->read(_heV7RoomOffsets, (2 + (i * 4)) ); break; - case MKID_BE('DISK'): + case MKTAG('D','I','S','K'): i = _fileHandle->readUint16LE(); _heV7DiskOffsets = (byte *)calloc(i, 1); _fileHandle->read(_heV7DiskOffsets, i); break; - case MKID_BE('SVER'): + case MKTAG('S','V','E','R'): // Index version number _fileHandle->seek(itemsize - 8, SEEK_CUR); break; - case MKID_BE('INIB'): + case MKTAG('I','N','I','B'): _fileHandle->seek(itemsize - 8, SEEK_CUR); debug(2, "INIB index block not yet handled, skipping"); break; @@ -418,17 +415,17 @@ void ScummEngine_v70he::readIndexBlock(uint32 blocktype, uint32 itemsize) { void ScummEngine::readIndexBlock(uint32 blocktype, uint32 itemsize) { int i; switch (blocktype) { - case MKID_BE('DCHR'): - case MKID_BE('DIRF'): + case MKTAG('D','C','H','R'): + case MKTAG('D','I','R','F'): readResTypeList(rtCharset); break; - case MKID_BE('DOBJ'): + case MKTAG('D','O','B','J'): debug(9, "found DOBJ block, reading object table"); readGlobalObjects(); break; - case MKID_BE('RNAM'): + case MKTAG('R','N','A','M'): // Names of rooms. Maybe we should put them into a table, for use by the debugger? if (_game.heversion >= 80) { for (int room; (room = _fileHandle->readUint16LE()); ) { @@ -452,32 +449,32 @@ void ScummEngine::readIndexBlock(uint32 blocktype, uint32 itemsize) { } break; - case MKID_BE('DROO'): - case MKID_BE('DIRR'): + case MKTAG('D','R','O','O'): + case MKTAG('D','I','R','R'): readResTypeList(rtRoom); break; - case MKID_BE('DSCR'): - case MKID_BE('DIRS'): + case MKTAG('D','S','C','R'): + case MKTAG('D','I','R','S'): readResTypeList(rtScript); break; - case MKID_BE('DCOS'): - case MKID_BE('DIRC'): + case MKTAG('D','C','O','S'): + case MKTAG('D','I','R','C'): readResTypeList(rtCostume); break; - case MKID_BE('MAXS'): + case MKTAG('M','A','X','S'): readMAXS(itemsize); allocateArrays(); break; - case MKID_BE('DIRN'): - case MKID_BE('DSOU'): + case MKTAG('D','I','R','N'): + case MKTAG('D','S','O','U'): readResTypeList(rtSound); break; - case MKID_BE('AARY'): + case MKTAG('A','A','R','Y'): readArrayFromIndexFile(); break; @@ -491,7 +488,7 @@ void ScummEngine::readArrayFromIndexFile() { error("readArrayFromIndexFile() not supported in pre-V6 games"); } -void ScummEngine::readResTypeList(int id) { +int ScummEngine::readResTypeList(int id) { int num; int i; @@ -511,16 +508,27 @@ void ScummEngine::readResTypeList(int id) { } for (i = 0; i < num; i++) { _res->roomoffs[id][i] = _fileHandle->readUint32LE(); - - if (id == rtRoom && _game.heversion >= 70) - _heV7RoomIntOffsets[i] = _res->roomoffs[id][i]; } - if (_game.heversion >= 70) { + return num; +} + +int ScummEngine_v70he::readResTypeList(int id) { + int num; + int i; + + num = ScummEngine::readResTypeList(id); + + if (id == rtRoom) for (i = 0; i < num; i++) { - _res->globsize[id][i] = _fileHandle->readUint32LE(); + _heV7RoomIntOffsets[i] = _res->roomoffs[rtRoom][i]; } + + for (i = 0; i < num; i++) { + _res->globsize[id][i] = _fileHandle->readUint32LE(); } + + return num; } void ResourceManager::allocResTypeData(int id, uint32 tag, int num_, const char *name_, int mode_) { @@ -635,18 +643,9 @@ int ScummEngine::loadResource(int type, int idx) { if (roomNr == 0) roomNr = _roomResource; - if (type == rtRoom) { - if (_game.version == 8) - fileOffs = 8; - else if (_game.heversion >= 70) - fileOffs = _heV7RoomIntOffsets[idx]; - else - fileOffs = 0; - } else { - fileOffs = _res->roomoffs[type][idx]; - if (fileOffs == RES_INVALID_OFFSET) - return 0; - } + fileOffs = getResourceRoomOffset(type, idx); + if (fileOffs == RES_INVALID_OFFSET) + return 0; openRoom(roomNr); @@ -691,13 +690,11 @@ int ScummEngine::loadResource(int type, int idx) { dumpResource("script-", idx, getResourceAddress(rtScript, idx)); } - if (!_fileHandle->err() && !_fileHandle->eos()) { - return 1; + if (_fileHandle->err() || _fileHandle->eos()) { + error("Cannot read resource"); } - _res->nukeResource(type, idx); - - error("Cannot read resource"); + return 1; } int ScummEngine::getResourceRoomNr(int type, int idx) { @@ -706,6 +703,20 @@ int ScummEngine::getResourceRoomNr(int type, int idx) { return _res->roomno[type][idx]; } +uint32 ScummEngine::getResourceRoomOffset(int type, int idx) { + if (type == rtRoom) { + return (_game.version == 8) ? 8 : 0; + } + return _res->roomoffs[type][idx]; +} + +uint32 ScummEngine_v70he::getResourceRoomOffset(int type, int idx) { + if (type == rtRoom) { + return _heV7RoomIntOffsets[idx]; + } + return _res->roomoffs[type][idx]; +} + int ScummEngine::getResourceSize(int type, int idx) { byte *ptr = getResourceAddress(type, idx); assert(ptr); @@ -1276,14 +1287,14 @@ void ScummEngine::allocateArrays() { _arraySlot = (byte *)calloc(_numArray, 1); } - _res->allocResTypeData(rtCostume, (_game.features & GF_NEW_COSTUMES) ? MKID_BE('AKOS') : MKID_BE('COST'), + _res->allocResTypeData(rtCostume, (_game.features & GF_NEW_COSTUMES) ? MKTAG('A','K','O','S') : MKTAG('C','O','S','T'), _numCostumes, "costume", 1); - _res->allocResTypeData(rtRoom, MKID_BE('ROOM'), _numRooms, "room", 1); - _res->allocResTypeData(rtRoomImage, MKID_BE('RMIM'), _numRooms, "room image", 1); - _res->allocResTypeData(rtRoomScripts, MKID_BE('RMSC'), _numRooms, "room script", 1); - _res->allocResTypeData(rtSound, MKID_BE('SOUN'), _numSounds, "sound", 2); - _res->allocResTypeData(rtScript, MKID_BE('SCRP'), _numScripts, "script", 1); - _res->allocResTypeData(rtCharset, MKID_BE('CHAR'), _numCharsets, "charset", 1); + _res->allocResTypeData(rtRoom, MKTAG('R','O','O','M'), _numRooms, "room", 1); + _res->allocResTypeData(rtRoomImage, MKTAG('R','M','I','M'), _numRooms, "room image", 1); + _res->allocResTypeData(rtRoomScripts, MKTAG('R','M','S','C'), _numRooms, "room script", 1); + _res->allocResTypeData(rtSound, MKTAG('S','O','U','N'), _numSounds, "sound", 2); + _res->allocResTypeData(rtScript, MKTAG('S','C','R','P'), _numScripts, "script", 1); + _res->allocResTypeData(rtCharset, MKTAG('C','H','A','R'), _numCharsets, "charset", 1); _res->allocResTypeData(rtObjectName, 0, _numNewNames, "new name", 0); _res->allocResTypeData(rtInventory, 0, _numInventory, "inventory", 0); _res->allocResTypeData(rtTemp, 0, 10, "temp", 0); @@ -1293,15 +1304,18 @@ void ScummEngine::allocateArrays() { _res->allocResTypeData(rtString, 0, _numArray, "array", 0); _res->allocResTypeData(rtFlObject, 0, _numFlObject, "flobject", 0); _res->allocResTypeData(rtMatrix, 0, 10, "boxes", 0); - _res->allocResTypeData(rtImage, MKID_BE('AWIZ'), _numImages, "images", 1); - _res->allocResTypeData(rtTalkie, MKID_BE('TLKE'), _numTalkies, "talkie", 1); + _res->allocResTypeData(rtImage, MKTAG('A','W','I','Z'), _numImages, "images", 1); + _res->allocResTypeData(rtTalkie, MKTAG('T','L','K','E'), _numTalkies, "talkie", 1); +} - if (_game.heversion >= 70) { - _res->allocResTypeData(rtSpoolBuffer, 0, 9, "spool buffer", 1); - _heV7RoomIntOffsets = (uint32 *)calloc(_numRooms, sizeof(uint32)); - } +void ScummEngine_v70he::allocateArrays() { + ScummEngine::allocateArrays(); + + _res->allocResTypeData(rtSpoolBuffer, 0, 9, "spool buffer", 1); + _heV7RoomIntOffsets = (uint32 *)calloc(_numRooms, sizeof(uint32)); } + void ScummEngine::dumpResource(const char *tag, int idx, const byte *ptr, int length) { char buf[256]; Common::DumpFile out; @@ -1450,35 +1464,35 @@ const byte *findResourceSmall(uint32 tag, const byte *searchin) { uint16 newTag2Old(uint32 newTag) { switch (newTag) { - case (MKID_BE('RMHD')): + case (MKTAG('R','M','H','D')): return (0x4448); // HD - case (MKID_BE('IM00')): + case (MKTAG('I','M','0','0')): return (0x4D42); // BM - case (MKID_BE('EXCD')): + case (MKTAG('E','X','C','D')): return (0x5845); // EX - case (MKID_BE('ENCD')): + case (MKTAG('E','N','C','D')): return (0x4E45); // EN - case (MKID_BE('SCAL')): + case (MKTAG('S','C','A','L')): return (0x4153); // SA - case (MKID_BE('LSCR')): + case (MKTAG('L','S','C','R')): return (0x534C); // LS - case (MKID_BE('OBCD')): + case (MKTAG('O','B','C','D')): return (0x434F); // OC - case (MKID_BE('OBIM')): + case (MKTAG('O','B','I','M')): return (0x494F); // OI - case (MKID_BE('SMAP')): + case (MKTAG('S','M','A','P')): return (0x4D42); // BM - case (MKID_BE('CLUT')): + case (MKTAG('C','L','U','T')): return (0x4150); // PA - case (MKID_BE('BOXD')): + case (MKTAG('B','O','X','D')): return (0x5842); // BX - case (MKID_BE('CYCL')): + case (MKTAG('C','Y','C','L')): return (0x4343); // CC - case (MKID_BE('EPAL')): + case (MKTAG('E','P','A','L')): return (0x5053); // SP - case (MKID_BE('TILE')): + case (MKTAG('T','I','L','E')): return (0x4C54); // TL - case (MKID_BE('ZP00')): + case (MKTAG('Z','P','0','0')): return (0x505A); // ZP default: return (0); diff --git a/engines/scumm/resource_v3.cpp b/engines/scumm/resource_v3.cpp index 0728395055..5f23720ce9 100644 --- a/engines/scumm/resource_v3.cpp +++ b/engines/scumm/resource_v3.cpp @@ -32,7 +32,7 @@ namespace Scumm { extern const char *resTypeFromId(int id); -void ScummEngine_v3old::readResTypeList(int id) { +int ScummEngine_v3old::readResTypeList(int id) { int num; int i; @@ -57,6 +57,8 @@ void ScummEngine_v3old::readResTypeList(int id) { if (_res->roomoffs[id][i] == 0xFFFF) _res->roomoffs[id][i] = (uint32)RES_INVALID_OFFSET; } + + return num; } void ScummEngine_v3old::readIndexFile() { diff --git a/engines/scumm/resource_v4.cpp b/engines/scumm/resource_v4.cpp index 808fcbd73e..b1d98494d4 100644 --- a/engines/scumm/resource_v4.cpp +++ b/engines/scumm/resource_v4.cpp @@ -33,7 +33,7 @@ namespace Scumm { extern const char *resTypeFromId(int id); -void ScummEngine_v4::readResTypeList(int id) { +int ScummEngine_v4::readResTypeList(int id) { int num; int i; @@ -49,6 +49,8 @@ void ScummEngine_v4::readResTypeList(int id) { _res->roomno[id][i] = _fileHandle->readByte(); _res->roomoffs[id][i] = _fileHandle->readUint32LE(); } + + return num; } void ScummEngine_v4::readIndexFile() { diff --git a/engines/scumm/room.cpp b/engines/scumm/room.cpp index 02b2482e40..06fa0f2c39 100644 --- a/engines/scumm/room.cpp +++ b/engines/scumm/room.cpp @@ -264,7 +264,7 @@ void ScummEngine::setupRoomSubBlocks() { // // Determine the room dimensions (width/height) // - rmhd = (const RoomHeader *)findResourceData(MKID_BE('RMHD'), roomptr); + rmhd = (const RoomHeader *)findResourceData(MKTAG('R','M','H','D'), roomptr); if (_game.version == 8) { _roomWidth = READ_LE_UINT32(&(rmhd->v8.width)); @@ -286,18 +286,18 @@ void ScummEngine::setupRoomSubBlocks() { if (_game.version == 8) { _IM00_offs = getObjectImage(roomptr, 1) - roomptr; } else if (_game.features & GF_SMALL_HEADER) { - _IM00_offs = findResourceData(MKID_BE('IM00'), roomptr) - roomptr; + _IM00_offs = findResourceData(MKTAG('I','M','0','0'), roomptr) - roomptr; } else if (_game.heversion >= 70) { byte *roomImagePtr = getResourceAddress(rtRoomImage, _roomResource); - _IM00_offs = findResource(MKID_BE('IM00'), roomImagePtr) - roomImagePtr; + _IM00_offs = findResource(MKTAG('I','M','0','0'), roomImagePtr) - roomImagePtr; } else { - _IM00_offs = findResource(MKID_BE('IM00'), findResource(MKID_BE('RMIM'), roomptr)) - roomptr; + _IM00_offs = findResource(MKTAG('I','M','0','0'), findResource(MKTAG('R','M','I','M'), roomptr)) - roomptr; } // // Look for an exit script // - ptr = findResourceData(MKID_BE('EXCD'), roomResPtr); + ptr = findResourceData(MKTAG('E','X','C','D'), roomResPtr); if (ptr) _EXCD_offs = ptr - roomResPtr; if (_dumpScripts && _EXCD_offs) @@ -306,7 +306,7 @@ void ScummEngine::setupRoomSubBlocks() { // // Look for an entry script // - ptr = findResourceData(MKID_BE('ENCD'), roomResPtr); + ptr = findResourceData(MKTAG('E','N','C','D'), roomResPtr); if (ptr) _ENCD_offs = ptr - roomResPtr; if (_dumpScripts && _ENCD_offs) @@ -326,7 +326,7 @@ void ScummEngine::setupRoomSubBlocks() { if (_game.features & GF_SMALL_HEADER) { ResourceIterator localScriptIterator(searchptr, true); - while ((ptr = localScriptIterator.findNext(MKID_BE('LSCR'))) != NULL) { + while ((ptr = localScriptIterator.findNext(MKTAG('L','S','C','R'))) != NULL) { int id = 0; ptr += _resourceHeaderSize; /* skip tag & size */ id = ptr[0]; @@ -341,7 +341,7 @@ void ScummEngine::setupRoomSubBlocks() { } } else if (_game.heversion >= 90) { ResourceIterator localScriptIterator2(searchptr, false); - while ((ptr = localScriptIterator2.findNext(MKID_BE('LSC2'))) != NULL) { + while ((ptr = localScriptIterator2.findNext(MKTAG('L','S','C','2'))) != NULL) { int id = 0; ptr += _resourceHeaderSize; /* skip tag & size */ @@ -359,7 +359,7 @@ void ScummEngine::setupRoomSubBlocks() { } ResourceIterator localScriptIterator(searchptr, false); - while ((ptr = localScriptIterator.findNext(MKID_BE('LSCR'))) != NULL) { + while ((ptr = localScriptIterator.findNext(MKTAG('L','S','C','R'))) != NULL) { int id = 0; ptr += _resourceHeaderSize; /* skip tag & size */ @@ -376,7 +376,7 @@ void ScummEngine::setupRoomSubBlocks() { } else { ResourceIterator localScriptIterator(searchptr, false); - while ((ptr = localScriptIterator.findNext(MKID_BE('LSCR'))) != NULL) { + while ((ptr = localScriptIterator.findNext(MKTAG('L','S','C','R'))) != NULL) { int id = 0; ptr += _resourceHeaderSize; /* skip tag & size */ @@ -403,18 +403,18 @@ void ScummEngine::setupRoomSubBlocks() { } // Locate the EGA palette (currently unused). - ptr = findResourceData(MKID_BE('EPAL'), roomptr); + ptr = findResourceData(MKTAG('E','P','A','L'), roomptr); if (ptr) _EPAL_offs = ptr - roomptr; // Locate the standard room palette (for V3-V5 games). - ptr = findResourceData(MKID_BE('CLUT'), roomptr); + ptr = findResourceData(MKTAG('C','L','U','T'), roomptr); if (ptr) _CLUT_offs = ptr - roomptr; // Locate the standard room palettes (for V6+ games). if (_game.version >= 6) { - ptr = findResource(MKID_BE('PALS'), roomptr); + ptr = findResource(MKTAG('P','A','L','S'), roomptr); if (ptr) { _PALS_offs = ptr - roomptr; } @@ -425,7 +425,7 @@ void ScummEngine::setupRoomSubBlocks() { if (_game.version == 8) trans = (byte)READ_LE_UINT32(&(rmhd->v8.transparency)); else { - ptr = findResourceData(MKID_BE('TRNS'), roomptr); + ptr = findResourceData(MKTAG('T','R','N','S'), roomptr); if (ptr) trans = ptr[0]; else @@ -434,7 +434,7 @@ void ScummEngine::setupRoomSubBlocks() { // Actor Palette in HE 70 games if (_game.heversion == 70) { - ptr = findResourceData(MKID_BE('REMP'), roomptr); + ptr = findResourceData(MKTAG('R','E','M','P'), roomptr); if (ptr) { for (i = 0; i < 256; i++) _HEV7ActorPalette[i] = *ptr++; @@ -485,7 +485,7 @@ void ScummEngine::resetRoomSubBlocks() { _res->nukeResource(rtMatrix, 1); _res->nukeResource(rtMatrix, 2); if (_game.features & GF_SMALL_HEADER) { - ptr = findResourceData(MKID_BE('BOXD'), roomptr); + ptr = findResourceData(MKTAG('B','O','X','D'), roomptr); if (ptr) { byte numOfBoxes = *ptr; int size; @@ -506,21 +506,21 @@ void ScummEngine::resetRoomSubBlocks() { } } else { - ptr = findResourceData(MKID_BE('BOXD'), roomptr); + ptr = findResourceData(MKTAG('B','O','X','D'), roomptr); if (ptr) { int size = getResourceDataSize(ptr); _res->createResource(rtMatrix, 2, size); roomptr = getResourceAddress(rtRoom, _roomResource); - ptr = findResourceData(MKID_BE('BOXD'), roomptr); + ptr = findResourceData(MKTAG('B','O','X','D'), roomptr); memcpy(getResourceAddress(rtMatrix, 2), ptr, size); } - ptr = findResourceData(MKID_BE('BOXM'), roomptr); + ptr = findResourceData(MKTAG('B','O','X','M'), roomptr); if (ptr) { int size = getResourceDataSize(ptr); _res->createResource(rtMatrix, 1, size); roomptr = getResourceAddress(rtRoom, _roomResource); - ptr = findResourceData(MKID_BE('BOXM'), roomptr); + ptr = findResourceData(MKTAG('B','O','X','M'), roomptr); memcpy(getResourceAddress(rtMatrix, 1), ptr, size); } } @@ -531,7 +531,7 @@ void ScummEngine::resetRoomSubBlocks() { for (i = 1; i < _res->num[rtScaleTable]; i++) _res->nukeResource(rtScaleTable, i); - ptr = findResourceData(MKID_BE('SCAL'), roomptr); + ptr = findResourceData(MKTAG('S','C','A','L'), roomptr); if (ptr) { int s1, s2, y1, y2; if (_game.version == 8) { @@ -558,7 +558,7 @@ void ScummEngine::resetRoomSubBlocks() { // Color cycling // HE 7.0 games load resources but don't use them. if (_game.version >= 4 && _game.heversion <= 62) { - ptr = findResourceData(MKID_BE('CYCL'), roomptr); + ptr = findResourceData(MKTAG('C','Y','C','L'), roomptr); if (ptr) { initCycl(ptr); } @@ -567,7 +567,7 @@ void ScummEngine::resetRoomSubBlocks() { #ifdef ENABLE_HE // Polygons in HE 80+ games if (_game.heversion >= 80) { - ptr = findResourceData(MKID_BE('POLD'), roomptr); + ptr = findResourceData(MKTAG('P','O','L','D'), roomptr); if (ptr) { ((ScummEngine_v71he *)this)->_wiz->polygonLoad(ptr); } @@ -581,7 +581,7 @@ void ScummEngine::resetRoomSubBlocks() { void ScummEngine_v3old::setupRoomSubBlocks() { const byte *ptr; - byte *roomptr, *searchptr = 0; + byte *roomptr; const RoomHeader *rmhd; _ENCD_offs = 0; @@ -669,7 +669,6 @@ void ScummEngine_v3old::setupRoomSubBlocks() { // Determine the room script base address roomptr = getResourceAddress(rtRoom, _roomResource); - searchptr = roomptr; memset(_localScriptOffsets, 0, sizeof(_localScriptOffsets)); diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index bdae4c5f6a..3bfe51a77b 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -154,7 +154,7 @@ void ScummEngine::requestLoad(int slot) { } static bool saveSaveGameHeader(Common::OutSaveFile *out, SaveGameHeader &hdr) { - hdr.type = MKID_BE('SCVM'); + hdr.type = MKTAG('S','C','V','M'); hdr.size = 0; hdr.ver = CURRENT_VER; @@ -308,7 +308,7 @@ static bool loadSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &h hdr.size = in->readUint32LE(); hdr.ver = in->readUint32LE(); in->read(hdr.name, sizeof(hdr.name)); - return !in->err() && hdr.type == MKID_BE('SCVM'); + return !in->err() && hdr.type == MKTAG('S','C','V','M'); } bool ScummEngine::loadState(int slot, bool compat) { @@ -373,7 +373,7 @@ bool ScummEngine::loadState(int slot, bool compat) { // Since version 56 we save additional information about the creation of // the save game and the save time. if (hdr.ver >= VER(56)) { - InfoStuff infos; + SaveStateMetaInfos infos; if (!loadInfos(in, &infos)) { warning("Info section could not be found"); delete in; @@ -703,7 +703,7 @@ Graphics::Surface *ScummEngine::loadThumbnailFromSlot(const char *target, int sl return thumb; } -bool ScummEngine::loadInfosFromSlot(const char *target, int slot, InfoStuff *stuff) { +bool ScummEngine::loadInfosFromSlot(const char *target, int slot, SaveStateMetaInfos *stuff) { Common::SeekableReadStream *in; SaveGameHeader hdr; @@ -741,12 +741,12 @@ bool ScummEngine::loadInfosFromSlot(const char *target, int slot, InfoStuff *stu return true; } -bool ScummEngine::loadInfos(Common::SeekableReadStream *file, InfoStuff *stuff) { - memset(stuff, 0, sizeof(InfoStuff)); +bool ScummEngine::loadInfos(Common::SeekableReadStream *file, SaveStateMetaInfos *stuff) { + memset(stuff, 0, sizeof(SaveStateMetaInfos)); SaveInfoSection section; section.type = file->readUint32BE(); - if (section.type != MKID_BE('INFO')) { + if (section.type != MKTAG('I','N','F','O')) { return false; } @@ -793,7 +793,7 @@ bool ScummEngine::loadInfos(Common::SeekableReadStream *file, InfoStuff *stuff) void ScummEngine::saveInfos(Common::WriteStream* file) { SaveInfoSection section; - section.type = MKID_BE('INFO'); + section.type = MKTAG('I','N','F','O'); section.version = INFOSECTION_VERSION; section.size = SaveInfoSectionSize; diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h index 91e780bcd1..eead241b90 100644 --- a/engines/scumm/saveload.h +++ b/engines/scumm/saveload.h @@ -30,8 +30,8 @@ #include <stddef.h> // for ptrdiff_t namespace Common { - class SeekableReadStream; - class WriteStream; +class SeekableReadStream; +class WriteStream; } namespace Scumm { diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index eac2061560..9e02f126cd 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -174,7 +174,7 @@ int ScummEngine::getVerbEntrypoint(int obj, int entry) { else if (_game.features & GF_SMALL_HEADER) verbptr = objptr + 19; else - verbptr = findResource(MKID_BE('VERB'), objptr); + verbptr = findResource(MKTAG('V','E','R','B'), objptr); assert(verbptr); @@ -261,8 +261,7 @@ void ScummEngine::stopScript(int script) { /* Stop an object script 'script'*/ void ScummEngine::stopObjectScript(int script) { ScriptSlot *ss; - NestedScript *nest; - int i, num; + int i; if (script == 0) return; @@ -282,19 +281,14 @@ void ScummEngine::stopObjectScript(int script) { } } - nest = vm.nest; - num = vm.numNestedScripts; - - while (num > 0) { - if (nest->number == script && - (nest->where == WIO_ROOM || nest->where == WIO_INVENTORY || nest->where == WIO_FLOBJECT)) { - nukeArrays(nest->slot); - nest->number = 0xFF; - nest->slot = 0xFF; - nest->where = 0xFF; + for (i = 0; i < vm.numNestedScripts; ++i) { + if (vm.nest[i].number == script && + (vm.nest[i].where == WIO_ROOM || vm.nest[i].where == WIO_INVENTORY || vm.nest[i].where == WIO_FLOBJECT)) { + nukeArrays(vm.nest[i].slot); + vm.nest[i].number = 0xFF; + vm.nest[i].slot = 0xFF; + vm.nest[i].where = 0xFF; } - nest++; - num--; } } @@ -319,6 +313,9 @@ void ScummEngine::runScriptNested(int script) { updateScriptPtr(); + if (vm.numNestedScripts >= kMaxScriptNesting) + error("Too many nested scripts"); + nest = &vm.nest[vm.numNestedScripts]; if (_currentScript == 0xFF) { @@ -334,9 +331,6 @@ void ScummEngine::runScriptNested(int script) { vm.numNestedScripts++; - if (vm.numNestedScripts > ARRAYSIZE(vm.nest)) - error("Too many nested scripts"); - _currentScript = script; getScriptBaseAddress(); resetScriptPointer(); @@ -927,7 +921,7 @@ void ScummEngine::runExitScript() { // be limiting ourselves to strictly reading the size from the header? if (_game.id == GID_INDY3 && !(_game.features & GF_OLD_BUNDLE)) { byte *roomptr = getResourceAddress(rtRoom, _roomResource); - const byte *excd = findResourceData(MKID_BE('EXCD'), roomptr) - _resourceHeaderSize; + const byte *excd = findResourceData(MKTAG('E','X','C','D'), roomptr) - _resourceHeaderSize; if (!excd || (getResourceDataSize(excd) < 1)) { debug(2, "Exit-%d is empty", _roomResource); return; @@ -1283,7 +1277,8 @@ void ScummEngine::beginCutscene(int *args) { int scr = _currentScript; vm.slot[scr].cutsceneOverride++; - if (++vm.cutSceneStackPointer > ARRAYSIZE(vm.cutSceneData)) + ++vm.cutSceneStackPointer; + if (vm.cutSceneStackPointer >= kMaxCutsceneNum) error("Cutscene stack overflow"); vm.cutSceneData[vm.cutSceneStackPointer] = args[0]; @@ -1313,6 +1308,9 @@ void ScummEngine::endCutscene() { vm.cutSceneScript[vm.cutSceneStackPointer] = 0; vm.cutScenePtr[vm.cutSceneStackPointer] = 0; + + if (0 == vm.cutSceneStackPointer) + error("Cutscene stack underflow"); vm.cutSceneStackPointer--; if (VAR(VAR_CUTSCENE_END_SCRIPT)) @@ -1321,7 +1319,7 @@ void ScummEngine::endCutscene() { void ScummEngine::abortCutscene() { const int idx = vm.cutSceneStackPointer; - assert(0 <= idx && idx < 5); + assert(0 <= idx && idx < kMaxCutsceneNum); uint32 offs = vm.cutScenePtr[idx]; if (offs) { @@ -1340,7 +1338,7 @@ void ScummEngine::abortCutscene() { void ScummEngine::beginOverride() { const int idx = vm.cutSceneStackPointer; - assert(0 <= idx && idx < 5); + assert(0 <= idx && idx < kMaxCutsceneNum); vm.cutScenePtr[idx] = _scriptPointer - _scriptOrgPointer; vm.cutSceneScript[idx] = _currentScript; @@ -1357,7 +1355,7 @@ void ScummEngine::beginOverride() { void ScummEngine::endOverride() { const int idx = vm.cutSceneStackPointer; - assert(0 <= idx && idx < 5); + assert(0 <= idx && idx < kMaxCutsceneNum); vm.cutScenePtr[idx] = 0; vm.cutSceneScript[idx] = 0; diff --git a/engines/scumm/script.h b/engines/scumm/script.h index dbfa2630e5..39d5d802b4 100644 --- a/engines/scumm/script.h +++ b/engines/scumm/script.h @@ -98,16 +98,29 @@ struct NestedScript { uint8 slot; }; +enum { + /** + * The maximal number of cutscenes that can be active + * in parallel (i.e. nested). + */ + kMaxCutsceneNum = 5, + + /** + * The maximal 'nesting' level for scripts. + */ + kMaxScriptNesting = 15 +}; + struct VirtualMachineState { - uint32 cutScenePtr[5]; - byte cutSceneScript[5]; - int16 cutSceneData[5]; + uint32 cutScenePtr[kMaxCutsceneNum]; + byte cutSceneScript[kMaxCutsceneNum]; + int16 cutSceneData[kMaxCutsceneNum]; int16 cutSceneScriptIndex; byte cutSceneStackPointer; ScriptSlot slot[NUM_SCRIPT_SLOT]; int32 localvar[NUM_SCRIPT_SLOT][26]; - NestedScript nest[15]; + NestedScript nest[kMaxScriptNesting]; byte numNestedScripts; }; diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp index 9e245aa168..ee790f7876 100644 --- a/engines/scumm/script_v5.cpp +++ b/engines/scumm/script_v5.cpp @@ -530,11 +530,20 @@ void ScummEngine_v5::o5_actorOps() { void ScummEngine_v5::o5_setClass() { int obj = getVarOrDirectWord(PARAM_1); - int newClass; + int cls; while ((_opcode = fetchScriptByte()) != 0xFF) { - newClass = getVarOrDirectWord(PARAM_1); - if (newClass == 0) { + cls = getVarOrDirectWord(PARAM_1); + + // WORKAROUND bug #1668393: Due to a script bug, the wrong opcode is + // used to test and set the state of various objects (e.g. the inside + // door (object 465) of the of the Hostel on Mars), when opening the + // Hostel door from the outside. + if (_game.id == GID_ZAK && _game.platform == Common::kPlatformFMTowns && + vm.slot[_currentScript].number == 205 && _currentRoom == 185 && + (cls == 0 || cls == 1)) { + putState(obj, cls); + } else if (cls == 0) { // Class '0' means: clean all class data _classData[obj] = 0; if ((_game.features & GF_SMALL_HEADER) && obj <= _numActors) { @@ -543,7 +552,7 @@ void ScummEngine_v5::o5_setClass() { a->_forceClip = 0; } } else - putClass(obj, newClass, (newClass & 0x80) ? true : false); + putClass(obj, cls, (cls & 0x80) ? true : false); } } @@ -1148,9 +1157,10 @@ void ScummEngine_v5::o5_ifClassOfIs() { while ((_opcode = fetchScriptByte()) != 0xFF) { cls = getVarOrDirectWord(PARAM_1); - // WORKAROUND bug #1668393: Due to a script bug, the wrong opcode is used - // to check the state of the inside door (object 465) of the Hostel on Mars, - // when opening the Hostel door from the outside. + // WORKAROUND bug #1668393: Due to a script bug, the wrong opcode is + // used to test and set the state of various objects (e.g. the inside + // door (object 465) of the of the Hostel on Mars), when opening the + // Hostel door from the outside. if (_game.id == GID_ZAK && _game.platform == Common::kPlatformFMTowns && vm.slot[_currentScript].number == 205 && _currentRoom == 185 && obj == 465 && cls == 0) { diff --git a/engines/scumm/script_v6.cpp b/engines/scumm/script_v6.cpp index 30187937f3..b2df1d0baa 100644 --- a/engines/scumm/script_v6.cpp +++ b/engines/scumm/script_v6.cpp @@ -1228,11 +1228,11 @@ void ScummEngine_v6::o6_animateActor() { } void ScummEngine_v6::o6_doSentence() { - int verb, objectA, objectB, dummy = 0; + int verb, objectA, objectB; objectB = pop(); if (_game.version < 8) - dummy = pop(); // dummy pop (in Sam&Max, seems to be always 0 or 130) + pop(); // dummy pop (in Sam&Max, seems to be always 0 or 130) objectA = pop(); verb = pop(); @@ -3014,7 +3014,7 @@ void ScummEngine_v6::o6_setBoxSet() { ResourceIterator boxds(room, false); for (i = 0; i < arg; i++) - boxd = boxds.findNext(MKID_BE('BOXD')); + boxd = boxds.findNext(MKTAG('B','O','X','D')); if (!boxd) error("ScummEngine_v6::o6_setBoxSet: Can't find dboxes for set %d", arg); @@ -3027,7 +3027,7 @@ void ScummEngine_v6::o6_setBoxSet() { ResourceIterator boxms(room, false); for (i = 0; i < arg; i++) - boxm = boxms.findNext(MKID_BE('BOXM')); + boxm = boxms.findNext(MKTAG('B','O','X','M')); if (!boxm) error("ScummEngine_v6::o6_setBoxSet: Can't find mboxes for set %d", arg); diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h index 40eeba3663..8f555818f4 100644 --- a/engines/scumm/scumm-md5.h +++ b/engines/scumm/scumm-md5.h @@ -1,5 +1,5 @@ /* - This file was generated by the md5table tool on Mon Oct 18 00:42:16 2010 + This file was generated by the md5table tool on Sun Apr 17 10:46:26 2011 DO NOT EDIT MANUALLY! */ @@ -206,6 +206,7 @@ static const MD5Table md5table[] = { { "4c4820518e16e1a0e3616a3b021a04f3", "catalog", "HE CUP", "Preview", 10927456, Common::DE_DEU, Common::kPlatformUnknown }, { "4cb9c3618f71668f8e4346c8f323fa82", "monkey2", "", "", 10700, Common::EN_ANY, Common::kPlatformMacintosh }, { "4ce2d5b355964bbcb5e5ce73236ef868", "freddicove", "HE 100", "", -1, Common::RU_RUS, Common::kPlatformWindows }, + { "4cfd3fda4a4e6e64a1fc488eba973b7a", "fbpack", "", "", -1, Common::EN_ANY, Common::kPlatformPC }, { "4d34042713958b971cb139fba4658586", "atlantis", "FM-TOWNS", "", -1, Common::JA_JPN, Common::kPlatformFMTowns }, { "4dbff3787aedcd96b0b325f2d92d7ad9", "maze", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown }, { "4dc780f1bc587a193ce8a97652791438", "loom", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformAmiga }, diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index c2556d6467..f43aed53f7 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -201,8 +201,6 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) _bootParam = 0; _dumpScripts = false; _debugMode = 0; - _heV7DiskOffsets = NULL; - _heV7RoomIntOffsets = NULL; _objectOwnerTable = NULL; _objectRoomTable = NULL; _objectStateTable = NULL; @@ -320,11 +318,6 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) _V1TalkingActor = 0; _NESStartStrip = 0; - _actorClipOverride.top = 0; - _actorClipOverride.bottom = 480; - _actorClipOverride.left = 0; - _actorClipOverride.right = 640; - _skipDrawObject = 0; #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE @@ -767,6 +760,12 @@ ScummEngine_v60he::ScummEngine_v60he(OSystem *syst, const DetectorResult &dr) : ScummEngine_v6(syst, dr) { memset(_hInFileTable, 0, sizeof(_hInFileTable)); memset(_hOutFileTable, 0, sizeof(_hOutFileTable)); + + _actorClipOverride.top = 0; + _actorClipOverride.bottom = 480; + _actorClipOverride.left = 0; + _actorClipOverride.right = 640; + memset(_heTimers, 0, sizeof(_heTimers)); if (_game.heversion >= 61) @@ -787,7 +786,9 @@ ScummEngine_v70he::ScummEngine_v70he(OSystem *syst, const DetectorResult &dr) else _resExtractor = new Win32ResExtractor(this); + _heV7DiskOffsets = NULL; _heV7RoomOffsets = NULL; + _heV7RoomIntOffsets = NULL; _heSndSoundId = 0; _heSndOffset = 0; @@ -804,8 +805,8 @@ ScummEngine_v70he::ScummEngine_v70he(OSystem *syst, const DetectorResult &dr) ScummEngine_v70he::~ScummEngine_v70he() { delete _resExtractor; free(_heV7DiskOffsets); - free(_heV7RoomIntOffsets); free(_heV7RoomOffsets); + free(_heV7RoomIntOffsets); free(_storedFlObjects); } @@ -1161,7 +1162,7 @@ Common::Error ScummEngine::init() { warning("Starting game without the required 16bit color support.\nYou may experience color glitches"); initGraphics(screenWidth, screenHeight, (screenWidth > 320)); } else { - error("16bit color support is required for this game"); + return Common::Error(Common::kUnsupportedColorMode, "16bit color support is required for this game"); } #endif } else { @@ -1221,7 +1222,7 @@ void ScummEngine::setupScumm() { setupCharsetRenderer(); // Create and clear the text surface - _textSurface.create(_screenWidth * _textSurfaceMultiplier, _screenHeight * _textSurfaceMultiplier, 1); + _textSurface.create(_screenWidth * _textSurfaceMultiplier, _screenHeight * _textSurfaceMultiplier, Graphics::PixelFormat::createFormatCLUT8()); clearTextSurface(); // Create the costume renderer @@ -1576,7 +1577,7 @@ void ScummEngine_v3::resetScumm() { // Load tile set and palette for the distaff byte *roomptr = getResourceAddress(rtRoom, 90); assert(roomptr); - const byte *palPtr = findResourceData(MKID_BE('CLUT'), roomptr); + const byte *palPtr = findResourceData(MKTAG('C','L','U','T'), roomptr); assert(palPtr - 4); setPCEPaletteFromPtr(palPtr); _gdi->_distaff = true; @@ -1647,6 +1648,8 @@ void ScummEngine_v90he::resetScumm() { break; case GID_SOCCER: + case GID_SOCCERMLS: + case GID_SOCCER2004: _logicHE = new LogicHEsoccer(this); break; @@ -1858,27 +1861,25 @@ void ScummEngine::setupMusic(int midi) { if (ConfMan.hasKey("tempo")) _imuse->property(IMuse::PROP_TEMPO_BASE, ConfMan.getInt("tempo")); // YM2162 driver can't handle midi->getPercussionChannel(), NULL shouldn't init MT-32/GM/GS - if (/*(midi != MDT_TOWNS) && (*/midi != MDT_NONE/*)*/) { + if (midi != MDT_NONE) { _imuse->property(IMuse::PROP_NATIVE_MT32, _native_mt32); if (MidiDriver::getMusicType(dev) != MT_MT32) // MT-32 Emulation shouldn't be GM/GS initialized _imuse->property(IMuse::PROP_GS, _enable_gs); } - if (_game.heversion >= 60 /*|| midi == MDT_TOWNS*/) { + if (_game.heversion >= 60) { _imuse->property(IMuse::PROP_LIMIT_PLAYERS, 1); _imuse->property(IMuse::PROP_RECYCLE_PLAYERS, 1); } - /*if (midi == MDT_TOWNS) - _imuse->property(IMuse::PROP_DIRECT_PASSTHROUGH, 1);*/ } } } void ScummEngine::syncSoundSettings() { + Engine::syncSoundSettings(); // Sync the engine with the config manager int soundVolumeMusic = ConfMan.getInt("music_volume"); int soundVolumeSfx = ConfMan.getInt("sfx_volume"); - int soundVolumeSpeech = ConfMan.getInt("speech_volume"); bool mute = false; @@ -1886,7 +1887,7 @@ void ScummEngine::syncSoundSettings() { mute = ConfMan.getBool("mute"); if (mute) - soundVolumeMusic = soundVolumeSfx = soundVolumeSpeech = 0; + soundVolumeMusic = soundVolumeSfx = 0; } if (_musicEngine) { @@ -1897,10 +1898,6 @@ void ScummEngine::syncSoundSettings() { _townsPlayer->setSfxVolume(soundVolumeSfx); } - _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, soundVolumeSfx); - _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, soundVolumeMusic); - _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, soundVolumeSpeech); - if (ConfMan.getBool("speech_mute")) _voiceMode = 2; else @@ -2499,7 +2496,7 @@ void ScummEngine_v90he::runBootscript() { void ScummEngine::startManiac() { debug(0, "stub startManiac()"); - displayMessage(0, "Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' directory inside the Tentacle game directory."); + displayMessage(0, "%s", _("Usually, Maniac Mansion would start now. But ScummVM doesn't do that yet. To play it, go to 'Add Game' in the ScummVM start menu and select the 'Maniac' directory inside the Tentacle game directory.")); } #pragma mark - diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index 587d1be776..62c6c70e5a 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -35,6 +35,7 @@ #include "common/random.h" #include "common/rect.h" #include "common/str.h" +#include "common/textconsole.h" #include "graphics/surface.h" #include "graphics/sjis.h" @@ -56,12 +57,12 @@ #endif namespace GUI { - class Dialog; +class Dialog; } using GUI::Dialog; namespace Common { - class SeekableReadStream; - class WriteStream; +class SeekableReadStream; +class WriteStream; } /** @@ -253,6 +254,8 @@ enum ScummGameId { GID_FUNSHOP, // Used for all three funshops GID_FOOTBALL, GID_SOCCER, + GID_SOCCERMLS, + GID_SOCCER2004, GID_BASEBALL2001, GID_BASKETBALL, GID_MOONBASE, @@ -308,24 +311,7 @@ enum WhereIsObject { WIO_FLOBJECT = 4 }; -struct AuxBlock { - bool visible; - Common::Rect r; - - void reset() { - visible = false; - r.left = r.top = 0; - r.right = r.bottom = -1; - } -}; - -struct AuxEntry { - int actorNum; - int subIndex; -}; - -// TODO: Rename InfoStuff to something more descriptive -struct InfoStuff { +struct SaveStateMetaInfos { uint32 date; uint16 time; uint32 playtime; @@ -480,7 +466,7 @@ public: virtual Common::Error run() { Common::Error err; err = init(); - if (err != Common::kNoError) + if (err.getCode() != Common::kNoError) return err; return go(); } @@ -630,7 +616,7 @@ public: FilenamePattern _filenamePattern; - Common::String generateFilename(const int room) const; + virtual Common::String generateFilename(const int room) const; protected: Common::KeyState _keyPressed; @@ -694,11 +680,11 @@ public: } static Graphics::Surface *loadThumbnailFromSlot(const char *target, int slot); - static bool loadInfosFromSlot(const char *target, int slot, InfoStuff *stuff); + static bool loadInfosFromSlot(const char *target, int slot, SaveStateMetaInfos *stuff); protected: void saveInfos(Common::WriteStream* file); - static bool loadInfos(Common::SeekableReadStream *file, InfoStuff *stuff); + static bool loadInfos(Common::SeekableReadStream *file, SaveStateMetaInfos *stuff); protected: /* Script VM - should be in Script class */ @@ -790,8 +776,6 @@ public: protected: int _resourceHeaderSize; byte _resourceMapper[128]; - byte *_heV7DiskOffsets; - uint32 *_heV7RoomIntOffsets; const byte *_resourceLastSearchBuf; // FIXME: need to put it to savefile? uint32 _resourceLastSearchSize; // FIXME: need to put it to savefile? @@ -804,11 +788,13 @@ protected: bool openResourceFile(const Common::String &filename, byte encByte); // TODO: Use Common::String void loadPtrToResource(int type, int i, const byte *ptr); - virtual void readResTypeList(int id); + virtual int readResTypeList(int id); // void allocResTypeData(int id, uint32 tag, int num, const char *name, int mode); // byte *createResource(int type, int index, uint32 size); int loadResource(int type, int i); // void nukeResource(int type, int i); + int getResourceRoomNr(int type, int idx); + virtual uint32 getResourceRoomOffset(int type, int idx); int getResourceSize(int type, int idx); public: @@ -816,7 +802,6 @@ public: virtual byte *getStringAddress(int i); byte *getStringAddressVar(int i); void ensureResourceLoaded(int type, int i); - int getResourceRoomNr(int type, int index); protected: int readSoundResource(int index); @@ -972,8 +957,6 @@ public: // Generic costume code bool isCostumeInUse(int i) const; - Common::Rect _actorClipOverride; // HE specific - protected: /* Should be in Graphics class? */ uint16 _screenB, _screenH; diff --git a/engines/scumm/scumm_v3.h b/engines/scumm/scumm_v3.h index abe75cd64d..6e8d593a35 100644 --- a/engines/scumm/scumm_v3.h +++ b/engines/scumm/scumm_v3.h @@ -62,7 +62,7 @@ public: ScummEngine_v3old(OSystem *syst, const DetectorResult &dr); protected: - virtual void readResTypeList(int id); + virtual int readResTypeList(int id); virtual void readIndexFile(); virtual void setupRoomSubBlocks(); virtual void resetRoomSubBlocks(); diff --git a/engines/scumm/scumm_v4.h b/engines/scumm/scumm_v4.h index be3f6cb47e..653cfc228e 100644 --- a/engines/scumm/scumm_v4.h +++ b/engines/scumm/scumm_v4.h @@ -59,7 +59,7 @@ protected: virtual void scummLoop_handleSaveLoad(); - virtual void readResTypeList(int id); + virtual int readResTypeList(int id); virtual void readIndexFile(); virtual void loadCharset(int no); virtual void resetRoomObjects(); diff --git a/engines/scumm/smush/channel.cpp b/engines/scumm/smush/channel.cpp index 4389890994..95b7653262 100644 --- a/engines/scumm/smush/channel.cpp +++ b/engines/scumm/smush/channel.cpp @@ -24,6 +24,8 @@ */ +#include "common/textconsole.h" + #include "scumm/smush/channel.h" namespace Scumm { diff --git a/engines/scumm/smush/channel.h b/engines/scumm/smush/channel.h index c35ac0ac00..717a294d96 100644 --- a/engines/scumm/smush/channel.h +++ b/engines/scumm/smush/channel.h @@ -29,7 +29,7 @@ #include "common/util.h" namespace Common { - class SeekableReadStream; +class SeekableReadStream; } namespace Scumm { diff --git a/engines/scumm/smush/codec37.cpp b/engines/scumm/smush/codec37.cpp index 658d67c1b4..9dbbc6816f 100644 --- a/engines/scumm/smush/codec37.cpp +++ b/engines/scumm/smush/codec37.cpp @@ -25,6 +25,7 @@ #include "common/endian.h" +#include "common/textconsole.h" #include "common/util.h" #include "scumm/bomp.h" #include "scumm/smush/codec37.h" diff --git a/engines/scumm/smush/codec47.cpp b/engines/scumm/smush/codec47.cpp index 333fdabccf..47286ba4fc 100644 --- a/engines/scumm/smush/codec47.cpp +++ b/engines/scumm/smush/codec47.cpp @@ -25,6 +25,7 @@ #include "common/endian.h" +#include "common/textconsole.h" #include "common/util.h" #include "scumm/bomp.h" #include "scumm/smush/codec47.h" @@ -342,11 +343,9 @@ void Codec47Decoder::makeTables47(int width) { #ifdef USE_ARM_SMUSH_ASM -extern "C" { #ifndef IPHONE #define ARM_Smush_decode2 _ARM_Smush_decode2 #endif -} extern "C" void ARM_Smush_decode2( byte *dst, const byte *src, diff --git a/engines/scumm/smush/imuse_channel.cpp b/engines/scumm/smush/imuse_channel.cpp index a838fdba56..32fa99a870 100644 --- a/engines/scumm/smush/imuse_channel.cpp +++ b/engines/scumm/smush/imuse_channel.cpp @@ -29,6 +29,7 @@ #include "scumm/scumm.h" // For DEBUG_SMUSH #include "scumm/util.h" #include "scumm/smush/channel.h" +#include "scumm/imuse_digi/dimuse_codecs.h" // for decode12BitsSample namespace Scumm { @@ -64,7 +65,7 @@ bool ImuseChannel::appendData(Common::SeekableReadStream &b, int32 size) { assert(size > 8); uint32 imus_type = b.readUint32BE(); /*uint32 imus_size =*/ b.readUint32BE(); - if (imus_type != MKID_BE('iMUS')) + if (imus_type != MKTAG('i','M','U','S')) error("Invalid Chunk for imuse_channel"); size -= 8; _tbufferSize = size; @@ -115,7 +116,7 @@ bool ImuseChannel::handleMap(byte *data) { size -= 8; switch (subType) { - case MKID_BE('FRMT'): + case MKTAG('F','R','M','T'): if (subSize != 20) error("invalid size for FRMT Chunk"); //uint32 imuse_start = READ_BE_UINT32(data); @@ -125,14 +126,14 @@ bool ImuseChannel::handleMap(byte *data) { _channels = READ_BE_UINT32(data+16); assert(_channels == 1 || _channels == 2); break; - case MKID_BE('TEXT'): + case MKTAG('T','E','X','T'): // Ignore this break; - case MKID_BE('REGN'): + case MKTAG('R','E','G','N'): if (subSize != 8) error("invalid size for REGN Chunk"); break; - case MKID_BE('STOP'): + case MKTAG('S','T','O','P'): if (subSize != 4) error("invalid size for STOP Chunk"); break; @@ -171,28 +172,10 @@ void ImuseChannel::decode() { } } - // FIXME: Code duplication! See decode12BitsSample() in imuse_digi/dimuse_codecs.cpp - - int loop_size = _sbufferSize / 3; - int new_size = loop_size * 4; - byte *keep, *decoded; - uint32 value; - keep = decoded = (byte *)malloc(new_size); - assert(keep); - unsigned char * source = _sbuffer; - - while (loop_size--) { - byte v1 = *source++; - byte v2 = *source++; - byte v3 = *source++; - value = ((((v2 & 0x0f) << 8) | v1) << 4) - 0x8000; - WRITE_BE_UINT16(decoded, value); decoded += 2; - value = ((((v2 & 0xf0) << 4) | v3) << 4) - 0x8000; - WRITE_BE_UINT16(decoded, value); decoded += 2; - } + byte *keep; + _sbufferSize = BundleCodecs::decode12BitsSample(_sbuffer, &keep, _sbufferSize); free(_sbuffer); _sbuffer = (byte *)keep; - _sbufferSize = new_size; } bool ImuseChannel::handleSubTags(int32 &offset) { @@ -201,13 +184,13 @@ bool ImuseChannel::handleSubTags(int32 &offset) { uint32 size = READ_BE_UINT32(_tbuffer + offset + 4); uint32 available_size = _tbufferSize - offset; switch (type) { - case MKID_BE('MAP '): + case MKTAG('M','A','P',' '): _inData = false; if (available_size >= (size + 8)) { handleMap((byte *)_tbuffer + offset); } break; - case MKID_BE('DATA'): + case MKTAG('D','A','T','A'): _inData = true; _dataSize = size; offset += 8; diff --git a/engines/scumm/smush/saud_channel.cpp b/engines/scumm/smush/saud_channel.cpp index 94df70633f..f730acf804 100644 --- a/engines/scumm/smush/saud_channel.cpp +++ b/engines/scumm/smush/saud_channel.cpp @@ -26,6 +26,7 @@ #include "common/endian.h" #include "common/stream.h" +#include "common/textconsole.h" #include "scumm/util.h" #include "scumm/smush/channel.h" @@ -50,7 +51,7 @@ bool SaudChannel::handleSubTags(int32 &offset) { uint32 available_size = _tbufferSize - offset; switch (type) { - case MKID_BE('STRK'): + case MKTAG('S','T','R','K'): _inData = false; if (available_size >= (size + 8)) { int32 subSize = READ_BE_UINT32((byte *)_tbuffer + offset + 4); @@ -60,14 +61,14 @@ bool SaudChannel::handleSubTags(int32 &offset) { } else return false; break; - case MKID_BE('SMRK'): + case MKTAG('S','M','R','K'): _inData = false; if (available_size >= (size + 8)) _markReached = true; else return false; break; - case MKID_BE('SHDR'): + case MKTAG('S','H','D','R'): _inData = false; if (available_size >= (size + 8)) { int32 subSize = READ_BE_UINT32((byte *)_tbuffer + offset + 4); @@ -76,7 +77,7 @@ bool SaudChannel::handleSubTags(int32 &offset) { } else return false; break; - case MKID_BE('SDAT'): + case MKTAG('S','D','A','T'): _inData = true; _dataSize = size; offset += 8; @@ -123,7 +124,7 @@ bool SaudChannel::appendData(Common::SeekableReadStream &b, int32 size) { assert(size > 8); uint32 saud_type = b.readUint32BE(); /*uint32 saud_size =*/ b.readUint32BE(); - if (saud_type != MKID_BE('SAUD')) + if (saud_type != MKTAG('S','A','U','D')) error("Invalid Chunk for SaudChannel : %X", saud_type); size -= 8; _dataSize = -2; diff --git a/engines/scumm/smush/smush_mixer.h b/engines/scumm/smush/smush_mixer.h index c7a7354511..3d62fdc722 100644 --- a/engines/scumm/smush/smush_mixer.h +++ b/engines/scumm/smush/smush_mixer.h @@ -27,6 +27,8 @@ #define SCUMM_SMUSH_MIXER_H +#include "audio/mixer.h" +#include "common/mutex.h" #include "scumm/sound.h" namespace Scumm { diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp index fe2b9d99ff..2e39558372 100644 --- a/engines/scumm/smush/smush_player.cpp +++ b/engines/scumm/smush/smush_player.cpp @@ -31,6 +31,7 @@ #include "common/util.h" #include "graphics/cursorman.h" +#include "graphics/palette.h" #include "scumm/bomp.h" #include "scumm/file.h" @@ -190,7 +191,7 @@ static StringResource *getStrings(ScummEngine *vm, const char *file, bool is_enc theFile.read(filebuffer, length); filebuffer[length] = 0; - if (is_encoded && READ_BE_UINT32(filebuffer) == MKID_BE('ETRS')) { + if (is_encoded && READ_BE_UINT32(filebuffer) == MKTAG('E','T','R','S')) { assert(length > ETRS_HEADER_LENGTH); length -= ETRS_HEADER_LENGTH; for (int i = 0; i < length; ++i) { @@ -507,7 +508,7 @@ void SmushPlayer::handleTextResource(uint32 subType, int32 subSize, Common::Seek const char *str; char *string = NULL, *string2 = NULL; - if (subType == MKID_BE('TEXT')) { + if (subType == MKTAG('T','E','X','T')) { string = (char *)malloc(subSize - 16); str = string; b.read(string, subSize - 16); @@ -845,40 +846,40 @@ void SmushPlayer::handleFrame(int32 frameSize, Common::SeekableReadStream &b) { const int32 subSize = b.readUint32BE(); const int32 subOffset = b.pos(); switch (subType) { - case MKID_BE('NPAL'): + case MKTAG('N','P','A','L'): handleNewPalette(subSize, b); break; - case MKID_BE('FOBJ'): + case MKTAG('F','O','B','J'): handleFrameObject(subSize, b); break; #ifdef USE_ZLIB - case MKID_BE('ZFOB'): + case MKTAG('Z','F','O','B'): handleZlibFrameObject(subSize, b); break; #endif - case MKID_BE('PSAD'): + case MKTAG('P','S','A','D'): if (!_compressedFileMode) handleSoundFrame(subSize, b); break; - case MKID_BE('TRES'): + case MKTAG('T','R','E','S'): handleTextResource(subType, subSize, b); break; - case MKID_BE('XPAL'): + case MKTAG('X','P','A','L'): handleDeltaPalette(subSize, b); break; - case MKID_BE('IACT'): + case MKTAG('I','A','C','T'): handleIACT(subSize, b); break; - case MKID_BE('STOR'): + case MKTAG('S','T','O','R'): handleStore(subSize, b); break; - case MKID_BE('FTCH'): + case MKTAG('F','T','C','H'): handleFetch(subSize, b); break; - case MKID_BE('SKIP'): + case MKTAG('S','K','I','P'): _vm->_insane->procSKIP(subSize, b); break; - case MKID_BE('TEXT'): + case MKTAG('T','E','X','T'): handleTextResource(subType, subSize, b); break; default: @@ -990,7 +991,7 @@ void SmushPlayer::parseNextFrame() { const uint32 subType = _base->readUint32BE(); const int32 subSize = _base->readUint32BE(); const int32 subOffset = _base->pos(); - assert(subType == MKID_BE('AHDR')); + assert(subType == MKTAG('A','H','D','R')); handleAnimHeader(subSize, *_base); _base->seek(subOffset + subSize, SEEK_SET); @@ -1029,10 +1030,10 @@ void SmushPlayer::parseNextFrame() { debug(3, "Chunk: %s at %x", tag2str(subType), subOffset); switch (subType) { - case MKID_BE('AHDR'): // FT INSANE may seek file to the beginning + case MKTAG('A','H','D','R'): // FT INSANE may seek file to the beginning handleAnimHeader(subSize, *_base); break; - case MKID_BE('FRME'): + case MKTAG('F','R','M','E'): handleFrame(subSize, *_base); break; default: diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp index cff1618c18..a38119584f 100644 --- a/engines/scumm/sound.cpp +++ b/engines/scumm/sound.cpp @@ -195,8 +195,7 @@ void Sound::playSound(int soundID) { return; } - debugC(DEBUG_SOUND, "playSound #%d (room %d)", soundID, - _vm->getResourceRoomNr(rtSound, soundID)); + debugC(DEBUG_SOUND, "playSound #%d", soundID); ptr = _vm->getResourceAddress(rtSound, soundID); @@ -207,7 +206,7 @@ void Sound::playSound(int soundID) { // Support for SFX in Monkey Island 1, Mac version // This is rather hackish right now, but works OK. SFX are not sounding // 100% correct, though, not sure right now what is causing this. - else if (READ_BE_UINT32(ptr) == MKID_BE('Mac1')) { + else if (READ_BE_UINT32(ptr) == MKTAG('M','a','c','1')) { // Read info from the header size = READ_BE_UINT32(ptr+0x60); rate = READ_BE_UINT16(ptr+0x64); @@ -246,7 +245,7 @@ void Sound::playSound(int soundID) { _mixer->playStream(Audio::Mixer::kSFXSoundType, NULL, stream, soundID); } // Support for sampled sound effects in Monkey Island 1 and 2 - else if (_vm->_game.platform != Common::kPlatformFMTowns && READ_BE_UINT32(ptr) == MKID_BE('SBL ')) { + else if (_vm->_game.platform != Common::kPlatformFMTowns && READ_BE_UINT32(ptr) == MKTAG('S','B','L',' ')) { debugC(DEBUG_SOUND, "Using SBL sound effect"); // SBL resources essentially contain VOC sound data. @@ -317,7 +316,7 @@ void Sound::playSound(int soundID) { stream = Audio::makeRawStream(sound, size, rate, Audio::FLAG_UNSIGNED); _mixer->playStream(Audio::Mixer::kSFXSoundType, NULL, stream, soundID); } - else if (_vm->_game.platform != Common::kPlatformFMTowns && READ_BE_UINT32(ptr) == MKID_BE('SOUN')) { + else if (_vm->_game.platform != Common::kPlatformFMTowns && READ_BE_UINT32(ptr) == MKTAG('S','O','U','N')) { if (_vm->_game.version != 3) ptr += 2; @@ -416,7 +415,7 @@ void Sound::playSound(int soundID) { // Rather it seems that starting a new music is supposed to // automatically stop the old song. if (_vm->_imuse) { - if (READ_BE_UINT32(ptr) != MKID_BE('ASFX')) + if (READ_BE_UINT32(ptr) != MKTAG('A','S','F','X')) _vm->_imuse->stopAllSounds(); } } @@ -528,6 +527,10 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle sprintf(filename, "audio/%s.%d/%d.voc", roomname, offset, b); _vm->openFile(*_sfxFile, filename); if (!_sfxFile->isOpen()) { + sprintf(filename, "audio/%s_%d/%d.voc", roomname, offset, b); + _vm->openFile(*_sfxFile, filename); + } + if (!_sfxFile->isOpen()) { sprintf(filename, "%d.%d.voc", offset, b); _vm->openFile(*_sfxFile, filename); } @@ -1091,15 +1094,15 @@ int ScummEngine::readSoundResource(int idx) { debugC(DEBUG_RESOURCE, " basetag: %s, total_size=%d", tag2str(basetag), total_size); switch (basetag) { - case MKID_BE('MIDI'): - case MKID_BE('iMUS'): + case MKTAG('M','I','D','I'): + case MKTAG('i','M','U','S'): if (_musicType != MDT_PCSPK && _musicType != MDT_PCJR) { _fileHandle->seek(-8, SEEK_CUR); _fileHandle->read(_res->createResource(rtSound, idx, total_size + 8), total_size + 8); return 1; } break; - case MKID_BE('SOU '): + case MKTAG('S','O','U',' '): best_pri = -1; while (pos < total_size) { tag = _fileHandle->readUint32BE(); @@ -1109,32 +1112,32 @@ int ScummEngine::readSoundResource(int idx) { pri = -1; switch (tag) { - case MKID_BE('TOWS'): + case MKTAG('T','O','W','S'): pri = 16; break; - case MKID_BE('SBL '): + case MKTAG('S','B','L',' '): pri = 15; break; - case MKID_BE('ADL '): + case MKTAG('A','D','L',' '): pri = 1; if (_musicType == MDT_ADLIB) pri = 10; break; - case MKID_BE('AMI '): + case MKTAG('A','M','I',' '): pri = 3; break; - case MKID_BE('ROL '): + case MKTAG('R','O','L',' '): pri = 3; if (_native_mt32) pri = 5; break; - case MKID_BE('GMD '): + case MKTAG('G','M','D',' '): pri = 4; break; - case MKID_BE('MAC '): // Occurs in Mac MI2, FOA + case MKTAG('M','A','C',' '): // Occurs in Mac MI2, FOA pri = 2; break; - case MKID_BE('SPK '): + case MKTAG('S','P','K',' '): pri = -1; // if (_musicType == MDT_PCSPK || _musicType == MDT_PCJR) // pri = 11; @@ -1164,7 +1167,7 @@ int ScummEngine::readSoundResource(int idx) { return 1; } break; - case MKID_BE('Mac0'): + case MKTAG('M','a','c','0'): _fileHandle->seek(-12, SEEK_CUR); total_size = _fileHandle->readUint32BE() - 8; ptr = (byte *)calloc(total_size, 1); @@ -1174,11 +1177,11 @@ int ScummEngine::readSoundResource(int idx) { free(ptr); return 1; - case MKID_BE('Mac1'): - case MKID_BE('RIFF'): - case MKID_BE('TALK'): - case MKID_BE('DIGI'): - case MKID_BE('Crea'): + case MKTAG('M','a','c','1'): + case MKTAG('R','I','F','F'): + case MKTAG('T','A','L','K'): + case MKTAG('D','I','G','I'): + case MKTAG('C','r','e','a'): case 0x460e200d: // WORKAROUND bug # 1311447 _fileHandle->seek(-12, SEEK_CUR); total_size = _fileHandle->readUint32BE(); @@ -1187,7 +1190,7 @@ int ScummEngine::readSoundResource(int idx) { //dumpResource("sound-", idx, ptr); return 1; - case MKID_BE('HSHD'): + case MKTAG('H','S','H','D'): // HE sound type without SOUN header _fileHandle->seek(-16, SEEK_CUR); total_size = max_total_size + 8; @@ -1196,7 +1199,7 @@ int ScummEngine::readSoundResource(int idx) { //dumpResource("sound-", idx, ptr); return 1; - case MKID_BE('FMUS'): { + case MKTAG('F','M','U','S'): { // Used in 3DO version of puttputt joins the parade and probably others // Specifies a separate file to be used for music from what I gather. int tmpsize; @@ -1223,7 +1226,7 @@ int ScummEngine::readSoundResource(int idx) { if (!dmuFile.open(buffer)) { error("Can't open music file %s", buffer); - _res->roomoffs[rtSound][idx] = (uint32)RES_INVALID_OFFSET; + _res->roomoffs[rtSound][idx] = RES_INVALID_OFFSET; return 0; } dmuFile.seek(4, SEEK_SET); @@ -1247,7 +1250,7 @@ int ScummEngine::readSoundResource(int idx) { } error("Unrecognized base tag 0x%08x in sound %d", basetag, idx); } - _res->roomoffs[rtSound][idx] = (uint32)RES_INVALID_OFFSET; + _res->roomoffs[rtSound][idx] = RES_INVALID_OFFSET; return 0; } @@ -1407,20 +1410,20 @@ static byte *writeVLQ(byte *ptr, int value) { static byte Mac0ToGMInstrument(uint32 type, int &transpose) { transpose = 0; switch (type) { - case MKID_BE('MARI'): return 12; - case MKID_BE('PLUC'): return 45; - case MKID_BE('HARM'): return 22; - case MKID_BE('PIPE'): return 19; - case MKID_BE('TROM'): transpose = -12; return 57; - case MKID_BE('STRI'): return 48; - case MKID_BE('HORN'): return 60; - case MKID_BE('VIBE'): return 11; - case MKID_BE('SHAK'): return 77; - case MKID_BE('PANP'): return 75; - case MKID_BE('WHIS'): return 76; - case MKID_BE('ORGA'): return 17; - case MKID_BE('BONG'): return 115; - case MKID_BE('BASS'): transpose = -24; return 35; + case MKTAG('M','A','R','I'): return 12; + case MKTAG('P','L','U','C'): return 45; + case MKTAG('H','A','R','M'): return 22; + case MKTAG('P','I','P','E'): return 19; + case MKTAG('T','R','O','M'): transpose = -12; return 57; + case MKTAG('S','T','R','I'): return 48; + case MKTAG('H','O','R','N'): return 60; + case MKTAG('V','I','B','E'): return 11; + case MKTAG('S','H','A','K'): return 77; + case MKTAG('P','A','N','P'): return 75; + case MKTAG('W','H','I','S'): return 76; + case MKTAG('O','R','G','A'): return 17; + case MKTAG('B','O','N','G'): return 115; + case MKTAG('B','A','S','S'): transpose = -24; return 35; default: error("Unknown Mac0 instrument %s found", tag2str(type)); } @@ -1505,13 +1508,13 @@ static void convertMac0Resource(ResourceManager *res, int idx, byte *src_ptr, in // Parse the three channels for (i = 0; i < 3; i++) { - assert(READ_BE_UINT32(src_ptr) == MKID_BE('Chan')); + assert(READ_BE_UINT32(src_ptr) == MKTAG('C','h','a','n')); len = READ_BE_UINT32(src_ptr + 4); track_len[i] = len - 24; track_instr[i] = Mac0ToGMInstrument(READ_BE_UINT32(src_ptr + 8), track_transpose[i]); track_data[i] = src_ptr + 12; src_ptr += len; - looped = (READ_BE_UINT32(src_ptr - 8) == MKID_BE('Loop')); + looped = (READ_BE_UINT32(src_ptr - 8) == MKTAG('L','o','o','p')); // For each note event, we need up to 6 bytes for the // Note On (3 VLQ, 3 event), and 6 bytes for the Note @@ -2122,7 +2125,7 @@ int ScummEngine::readSoundResourceSmallHeader(int idx) { _fileHandle->read(_res->createResource(rtSound, idx, ro_size - 4), ro_size - 4); return 1; } - _res->roomoffs[rtSound][idx] = (uint32)RES_INVALID_OFFSET; + _res->roomoffs[rtSound][idx] = RES_INVALID_OFFSET; return 0; } diff --git a/engines/scumm/util.cpp b/engines/scumm/util.cpp index ccd0230efa..5c3e4c9d0c 100644 --- a/engines/scumm/util.cpp +++ b/engines/scumm/util.cpp @@ -25,6 +25,7 @@ #include "scumm/util.h" #include "common/util.h" +#include "common/textconsole.h" namespace Scumm { diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index e8f75dd901..6d5eb3fad7 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -1499,7 +1499,7 @@ void ScummEngine::drawVerbBitmap(int verb, int x, int y) { } imptr = getObjectImage(obim, 1); } else { - const ImageHeader *imhd = (const ImageHeader *)findResourceData(MKID_BE('IMHD'), obim); + const ImageHeader *imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), obim); if (_game.version >= 7) { imgw = READ_LE_UINT16(&imhd->v7.width) / 8; imgh = READ_LE_UINT16(&imhd->v7.height) / 8; |