aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/endian.h6
-rw-r--r--engines/sword1/control.cpp33
-rw-r--r--engines/sword1/logic.cpp54
-rw-r--r--engines/sword1/mouse.cpp33
-rw-r--r--engines/sword1/objectman.cpp11
-rw-r--r--engines/sword1/resman.cpp163
-rw-r--r--engines/sword1/resman.h36
-rw-r--r--engines/sword1/router.cpp41
-rw-r--r--engines/sword1/screen.cpp47
-rw-r--r--engines/sword1/sword1.cpp218
-rw-r--r--engines/sword1/sword1.h4
-rw-r--r--engines/sword1/text.cpp14
12 files changed, 449 insertions, 211 deletions
diff --git a/common/endian.h b/common/endian.h
index 6a6fb8cfae..173605dde4 100644
--- a/common/endian.h
+++ b/common/endian.h
@@ -91,6 +91,9 @@ FORCEINLINE uint16 SWAP_BYTES_16(uint16 a) {
#define FROM_LE_32(a) ((uint32)(a))
#define FROM_LE_16(a) ((uint16)(a))
+ #define FROM_BE_32(a) SWAP_BYTES_32(a)
+ #define FROM_BE_16(a) SWAP_BYTES_16(a)
+
#define TO_LE_32(a) ((uint32)(a))
#define TO_LE_16(a) ((uint16)(a))
@@ -111,6 +114,9 @@ FORCEINLINE uint16 SWAP_BYTES_16(uint16 a) {
#define FROM_LE_32(a) SWAP_BYTES_32(a)
#define FROM_LE_16(a) SWAP_BYTES_16(a)
+ #define FROM_BE_32(a) ((uint32)(a))
+ #define FROM_BE_16(a) ((uint16)(a))
+
#define TO_LE_32(a) SWAP_BYTES_32(a)
#define TO_LE_16(a) SWAP_BYTES_16(a)
diff --git a/engines/sword1/control.cpp b/engines/sword1/control.cpp
index 38cc2f4554..85e25c75fc 100644
--- a/engines/sword1/control.cpp
+++ b/engines/sword1/control.cpp
@@ -21,7 +21,6 @@
*/
#include "common/stdafx.h"
-#include "common/endian.h"
#include "common/file.h"
#include "common/util.h"
#include "common/savefile.h"
@@ -118,8 +117,8 @@ ControlButton::ControlButton(uint16 x, uint16 y, uint32 resId, uint8 id, uint8 f
_frameIdx = 0;
_resMan->resOpen(_resId);
FrameHeader *tmp = _resMan->fetchFrame(_resMan->fetchRes(_resId), 0);
- _width = FROM_LE_16(tmp->width);
- _height = FROM_LE_16(tmp->height);
+ _width = _resMan->getUint16(tmp->width);
+ _height = _resMan->getUint16(tmp->height);
if ((x == 0) && (y == 0)) { // center the frame (used for panels);
_x = (640 - _width) / 2;
_y = (480 - _height) / 2;
@@ -140,12 +139,12 @@ void ControlButton::draw(void) {
FrameHeader *fHead = _resMan->fetchFrame(_resMan->fetchRes(_resId), _frameIdx);
uint8 *src = (uint8*)fHead + sizeof(FrameHeader);
uint8 *dst = _dstBuf;
- for (uint16 cnt = 0; cnt < READ_LE_UINT16(&fHead->height); cnt++) {
- for (uint16 cntx = 0; cntx < READ_LE_UINT16(&fHead->width); cntx++)
+ for (uint16 cnt = 0; cnt < _resMan->readUint16(&fHead->height); cnt++) {
+ for (uint16 cntx = 0; cntx < _resMan->readUint16(&fHead->width); cntx++)
if (src[cntx])
dst[cntx] = src[cntx];
dst += SCREEN_WIDTH;
- src += READ_LE_UINT16(&fHead->width);
+ src += _resMan->readUint16(&fHead->width);
}
_system->copyRectToScreen(_dstBuf, SCREEN_WIDTH, _x, _y, _width, _height);
}
@@ -485,8 +484,8 @@ void Control::setupMainPanel(void) {
void Control::setupSaveRestorePanel(bool saving) {
FrameHeader *savePanel = _resMan->fetchFrame(_resMan->openFetchRes(SR_WINDOW), 0);
- uint16 panelX = (640 - FROM_LE_16(savePanel->width)) / 2;
- uint16 panelY = (480 - FROM_LE_16(savePanel->height)) / 2;
+ uint16 panelX = (640 - _resMan->getUint16(savePanel->width)) / 2;
+ uint16 panelY = (480 - _resMan->getUint16(savePanel->height)) / 2;
ControlButton *panel = new ControlButton(panelX, panelY, SR_WINDOW, 0, 0, _resMan, _screenBuf, _system);
panel->draw();
delete panel;
@@ -870,7 +869,7 @@ void Control::destroyButtons(void) {
uint16 Control::getTextWidth(const uint8 *str) {
uint16 width = 0;
while (*str) {
- width += FROM_LE_16(_resMan->fetchFrame(_font, *str - 32)->width) - 3;
+ width += _resMan->getUint16(_resMan->fetchFrame(_font, *str - 32)->width) - 3;
str++;
}
return width;
@@ -894,15 +893,15 @@ void Control::renderText(const uint8 *str, uint16 x, uint16 y, uint8 mode) {
FrameHeader *chSpr = _resMan->fetchFrame(font, *str - 32);
uint8 *sprData = (uint8*)chSpr + sizeof(FrameHeader);
- for (uint16 cnty = 0; cnty < FROM_LE_16(chSpr->height); cnty++) {
- for (uint16 cntx = 0; cntx < FROM_LE_16(chSpr->width); cntx++) {
+ for (uint16 cnty = 0; cnty < _resMan->getUint16(chSpr->height); cnty++) {
+ for (uint16 cntx = 0; cntx < _resMan->getUint16(chSpr->width); cntx++) {
if (sprData[cntx])
dst[cntx] = sprData[cntx];
}
- sprData += FROM_LE_16(chSpr->width);
+ sprData += _resMan->getUint16(chSpr->width);
dst += SCREEN_WIDTH;
}
- destX += FROM_LE_16(chSpr->width) - 3;
+ destX += _resMan->getUint16(chSpr->width) - 3;
str++;
}
_system->copyRectToScreen(_screenBuf + y * SCREEN_WIDTH + x, SCREEN_WIDTH, x, y, (destX - x) + 3, 28);
@@ -917,12 +916,12 @@ void Control::renderVolumeBar(uint8 id, uint8 volL, uint8 volR) {
FrameHeader *frHead = _resMan->fetchFrame(_resMan->openFetchRes(SR_VLIGHT), (vol + 15) >> 4);
uint8 *destMem = _screenBuf + destY * SCREEN_WIDTH + destX;
uint8 *srcMem = (uint8*)frHead + sizeof(FrameHeader);
- for (uint16 cnty = 0; cnty < FROM_LE_16(frHead->height); cnty++) {
- memcpy(destMem, srcMem, FROM_LE_16(frHead->width));
- srcMem += FROM_LE_16(frHead->width);
+ for (uint16 cnty = 0; cnty < _resMan->getUint16(frHead->height); cnty++) {
+ memcpy(destMem, srcMem, _resMan->getUint16(frHead->width));
+ srcMem += _resMan->getUint16(frHead->width);
destMem += SCREEN_WIDTH;
}
- _system->copyRectToScreen(_screenBuf + destY * SCREEN_WIDTH + destX, SCREEN_WIDTH, destX, destY, FROM_LE_16(frHead->width), FROM_LE_16(frHead->height));
+ _system->copyRectToScreen(_screenBuf + destY * SCREEN_WIDTH + destX, SCREEN_WIDTH, destX, destY, _resMan->getUint16(frHead->width), _resMan->getUint16(frHead->height));
_resMan->resClose(SR_VLIGHT);
destX += 32;
}
diff --git a/engines/sword1/logic.cpp b/engines/sword1/logic.cpp
index 13b2e1afb0..105646cb5f 100644
--- a/engines/sword1/logic.cpp
+++ b/engines/sword1/logic.cpp
@@ -355,7 +355,7 @@ int Logic::speechDriver(Object *compact) {
}
if (compact->o_anim_resource) {
uint8 *animData = ((uint8*)_resMan->openFetchRes(compact->o_anim_resource)) + sizeof(Header);
- int32 numFrames = READ_LE_UINT32(animData);
+ int32 numFrames = _resMan->readUint32(animData);
animData += 4;
compact->o_anim_pc++; // go to next frame of anim
@@ -365,10 +365,10 @@ int Logic::speechDriver(Object *compact) {
AnimUnit *animPtr = (AnimUnit*)(animData + sizeof(AnimUnit) * compact->o_anim_pc);
if (!(compact->o_status & STAT_SHRINK)) {
- compact->o_anim_x = FROM_LE_32(animPtr->animX);
- compact->o_anim_y = FROM_LE_32(animPtr->animY);
+ compact->o_anim_x = _resMan->getUint32(animPtr->animX);
+ compact->o_anim_y = _resMan->getUint32(animPtr->animY);
}
- compact->o_frame = FROM_LE_32(animPtr->animFrame);
+ compact->o_frame = _resMan->getUint32(animPtr->animFrame);
_resMan->resClose(compact->o_anim_resource);
}
return 0;
@@ -380,13 +380,13 @@ int Logic::fullAnimDriver(Object *compact) {
return 1;
}
uint8 *data = ((uint8*)_resMan->openFetchRes(compact->o_anim_resource)) + sizeof(Header);
- uint32 numFrames = READ_LE_UINT32(data);
+ uint32 numFrames = _resMan->readUint32(data);
data += 4;
AnimUnit *animPtr = (AnimUnit*)(data + compact->o_anim_pc * sizeof(AnimUnit));
- compact->o_anim_x = compact->o_xcoord = FROM_LE_32(animPtr->animX);
- compact->o_anim_y = compact->o_ycoord = FROM_LE_32(animPtr->animY);
- compact->o_frame = FROM_LE_32(animPtr->animFrame);
+ compact->o_anim_x = compact->o_xcoord = _resMan->getUint32(animPtr->animX);
+ compact->o_anim_y = compact->o_ycoord = _resMan->getUint32(animPtr->animY);
+ compact->o_frame = _resMan->getUint32(animPtr->animFrame);
compact->o_anim_pc++;
if (compact->o_anim_pc == (int)numFrames)
@@ -402,15 +402,15 @@ int Logic::animDriver(Object *compact) {
return 1;
}
uint8 *data = ((uint8*)_resMan->openFetchRes(compact->o_anim_resource)) + sizeof(Header);
- uint32 numFrames = READ_LE_UINT32(data);
+ uint32 numFrames = _resMan->readUint32(data);
AnimUnit *animPtr = (AnimUnit*)(data + 4 + compact->o_anim_pc * sizeof(AnimUnit));
if (!(compact->o_status & STAT_SHRINK)) {
- compact->o_anim_x = FROM_LE_32(animPtr->animX);
- compact->o_anim_y = FROM_LE_32(animPtr->animY);
+ compact->o_anim_x = _resMan->getUint32(animPtr->animX);
+ compact->o_anim_y = _resMan->getUint32(animPtr->animY);
}
- compact->o_frame = FROM_LE_32(animPtr->animFrame);
+ compact->o_frame = _resMan->getUint32(animPtr->animFrame);
compact->o_anim_pc++;
if (compact->o_anim_pc == (int)numFrames)
compact->o_logic = LOGIC_script;
@@ -828,8 +828,8 @@ int Logic::fnAnim(Object *cpt, int32 id, int32 cdt, int32 spr, int32 e, int32 f,
animTab = (AnimSet*)((uint8*)_resMan->openFetchRes(cdt) + sizeof(Header));
animTab += cpt->o_dir;
- cpt->o_anim_resource = FROM_LE_32(animTab->cdt);
- cpt->o_resource = FROM_LE_32(animTab->spr);
+ cpt->o_anim_resource = _resMan->getUint32(animTab->cdt);
+ cpt->o_resource = _resMan->getUint32(animTab->spr);
_resMan->resClose(cdt);
} else {
cpt->o_anim_resource = cdt;
@@ -862,14 +862,14 @@ int Logic::fnSetFrame(Object *cpt, int32 id, int32 cdt, int32 spr, int32 frameNo
uint8 *data = (uint8*)_resMan->openFetchRes(cdt);
data += sizeof(Header);
if (frameNo == LAST_FRAME)
- frameNo = READ_LE_UINT32(data) - 1;
+ frameNo = _resMan->readUint32(data) - 1;
data += 4;
animPtr = (AnimUnit*)(data + frameNo * sizeof(AnimUnit));
- cpt->o_anim_x = FROM_LE_32(animPtr->animX);
- cpt->o_anim_y = FROM_LE_32(animPtr->animY);
- cpt->o_frame = FROM_LE_32(animPtr->animFrame);
+ cpt->o_anim_x = _resMan->getUint32(animPtr->animX);
+ cpt->o_anim_y = _resMan->getUint32(animPtr->animY);
+ cpt->o_frame = _resMan->getUint32(animPtr->animFrame);
cpt->o_resource = spr;
cpt->o_status &= ~STAT_SHRINK;
@@ -892,13 +892,13 @@ int Logic::fnFullSetFrame(Object *cpt, int32 id, int32 cdt, int32 spr, int32 fra
uint8 *data = (uint8*)_resMan->openFetchRes(cdt) + sizeof(Header);
if (frameNo == LAST_FRAME)
- frameNo = READ_LE_UINT32(data) - 1;
+ frameNo = _resMan->readUint32(data) - 1;
data += 4;
AnimUnit *animPtr = (AnimUnit*)(data + sizeof(AnimUnit) * frameNo);
- cpt->o_anim_x = cpt->o_xcoord = FROM_LE_32(animPtr->animX);
- cpt->o_anim_y = cpt->o_ycoord = FROM_LE_32(animPtr->animY);
- cpt->o_frame = FROM_LE_32(animPtr->animFrame);
+ cpt->o_anim_x = cpt->o_xcoord = _resMan->getUint32(animPtr->animX);
+ cpt->o_anim_y = cpt->o_ycoord = _resMan->getUint32(animPtr->animY);
+ cpt->o_frame = _resMan->getUint32(animPtr->animFrame);
cpt->o_resource = spr;
cpt->o_status &= ~STAT_SHRINK;
@@ -1116,9 +1116,9 @@ int Logic::fnISpeak(Object *cpt, int32 id, int32 cdt, int32 textNo, int32 spr, i
AnimSet *animTab = (AnimSet*)((uint8*)_resMan->openFetchRes(cdt) + sizeof(Header));
animTab += cpt->o_dir;
- cpt->o_anim_resource = FROM_LE_32(animTab->cdt);
+ cpt->o_anim_resource = _resMan->getUint32(animTab->cdt);
if (animTab->cdt)
- cpt->o_resource = FROM_LE_32(animTab->spr);
+ cpt->o_resource = _resMan->getUint32(animTab->spr);
_resMan->resClose(cdt);
} else {
cpt->o_anim_resource = cdt;
@@ -1158,8 +1158,8 @@ int Logic::fnISpeak(Object *cpt, int32 id, int32 cdt, int32 textNo, int32 spr, i
textCpt->o_target = textCptId;
// the graphic is a property of Text, so we don't lock/unlock it.
- uint16 textSpriteWidth = FROM_LE_16(_textMan->giveSpriteData(textCpt->o_target)->width);
- uint16 textSpriteHeight = FROM_LE_16(_textMan->giveSpriteData(textCpt->o_target)->height);
+ uint16 textSpriteWidth = _resMan->getUint16(_textMan->giveSpriteData(textCpt->o_target)->width);
+ uint16 textSpriteHeight = _resMan->getUint16(_textMan->giveSpriteData(textCpt->o_target)->height);
cpt->o_text_id = textCptId;
@@ -1717,6 +1717,8 @@ void Logic::startPosCallFn(uint8 fnId, uint32 param1, uint32 param2, uint32 para
}
void Logic::runStartScript(const uint8 *data) {
+ // Here data is a static resource defined in staticres.cpp
+ // It is always in little endian
uint16 varId = 0;
uint8 fnId = 0;
uint32 param1 = 0;
diff --git a/engines/sword1/mouse.cpp b/engines/sword1/mouse.cpp
index eefdf99466..6e4923c304 100644
--- a/engines/sword1/mouse.cpp
+++ b/engines/sword1/mouse.cpp
@@ -21,7 +21,6 @@
*/
#include "common/stdafx.h"
-#include "common/endian.h"
#include "common/system.h"
#include "graphics/cursorman.h"
@@ -199,33 +198,33 @@ void Mouse::createPointer(uint32 ptrId, uint32 luggageId) {
if (ptrId) {
MousePtr *lugg = NULL;
MousePtr *ptr = (MousePtr*)_resMan->openFetchRes(ptrId);
- uint16 resSizeX = FROM_LE_16(ptr->sizeX);
- uint16 resSizeY = FROM_LE_16(ptr->sizeY);
- uint16 noFrames = FROM_LE_16(ptr->numFrames);
+ uint16 resSizeX = _resMan->getLEUint16(ptr->sizeX);
+ uint16 resSizeY = _resMan->getLEUint16(ptr->sizeY);
+ uint16 noFrames = _resMan->getLEUint16(ptr->numFrames);
if (luggageId) {
lugg = (MousePtr*)_resMan->openFetchRes(luggageId);
- resSizeX = MAX(resSizeX, (uint16)((resSizeX / 2) + FROM_LE_16(lugg->sizeX)));
- resSizeY = MAX(resSizeY, (uint16)((resSizeY / 2) + FROM_LE_16(lugg->sizeY)));
+ resSizeX = MAX(resSizeX, (uint16)((resSizeX / 2) + _resMan->getLEUint16(lugg->sizeX)));
+ resSizeY = MAX(resSizeY, (uint16)((resSizeY / 2) + _resMan->getLEUint16(lugg->sizeY)));
}
_currentPtr = (MousePtr*)malloc(sizeof(MousePtr) + resSizeX * resSizeY * noFrames);
- _currentPtr->hotSpotX = FROM_LE_16(ptr->hotSpotX);
- _currentPtr->hotSpotY = FROM_LE_16(ptr->hotSpotY);
+ _currentPtr->hotSpotX = _resMan->getLEUint16(ptr->hotSpotX);
+ _currentPtr->hotSpotY = _resMan->getLEUint16(ptr->hotSpotY);
_currentPtr->numFrames = noFrames;
_currentPtr->sizeX = resSizeX;
_currentPtr->sizeY = resSizeY;
uint8 *ptrData = (uint8*)_currentPtr + sizeof(MousePtr);
memset(ptrData, 255, resSizeX * resSizeY * noFrames);
if (luggageId) {
- uint8 *dstData = ptrData + resSizeX - FROM_LE_16(lugg->sizeX);
+ uint8 *dstData = ptrData + resSizeX - _resMan->getLEUint16(lugg->sizeX);
for (uint32 frameCnt = 0; frameCnt < noFrames; frameCnt++) {
uint8 *luggSrc = (uint8*)lugg + sizeof(MousePtr);
- dstData += (resSizeY - FROM_LE_16(lugg->sizeY)) * resSizeX;
- for (uint32 cnty = 0; cnty < FROM_LE_16(lugg->sizeY); cnty++) {
- for (uint32 cntx = 0; cntx < FROM_LE_16(lugg->sizeX); cntx++)
+ dstData += (resSizeY - _resMan->getLEUint16(lugg->sizeY)) * resSizeX;
+ for (uint32 cnty = 0; cnty < _resMan->getLEUint16(lugg->sizeY); cnty++) {
+ for (uint32 cntx = 0; cntx < _resMan->getLEUint16(lugg->sizeX); cntx++)
if (luggSrc[cntx])
dstData[cntx] = luggSrc[cntx];
dstData += resSizeX;
- luggSrc += FROM_LE_16(lugg->sizeX);
+ luggSrc += _resMan->getLEUint16(lugg->sizeX);
}
}
_resMan->resClose(luggageId);
@@ -233,14 +232,14 @@ void Mouse::createPointer(uint32 ptrId, uint32 luggageId) {
uint8 *dstData = ptrData;
uint8 *srcData = (uint8*)ptr + sizeof(MousePtr);
for (uint32 frameCnt = 0; frameCnt < noFrames; frameCnt++) {
- for (uint32 cnty = 0; cnty < FROM_LE_16(ptr->sizeY); cnty++) {
- for (uint32 cntx = 0; cntx < FROM_LE_16(ptr->sizeX); cntx++)
+ for (uint32 cnty = 0; cnty < _resMan->getLEUint16(ptr->sizeY); cnty++) {
+ for (uint32 cntx = 0; cntx < _resMan->getLEUint16(ptr->sizeX); cntx++)
if (srcData[cntx])
dstData[cntx] = srcData[cntx];
- srcData += FROM_LE_16(ptr->sizeX);
+ srcData += _resMan->getLEUint16(ptr->sizeX);
dstData += resSizeX;
}
- dstData += (resSizeY - FROM_LE_16(ptr->sizeY)) * resSizeX;
+ dstData += (resSizeY - _resMan->getLEUint16(ptr->sizeY)) * resSizeX;
}
_resMan->resClose(ptrId);
}
diff --git a/engines/sword1/objectman.cpp b/engines/sword1/objectman.cpp
index bb21f25b13..5aab4859be 100644
--- a/engines/sword1/objectman.cpp
+++ b/engines/sword1/objectman.cpp
@@ -21,7 +21,6 @@
*/
#include "common/stdafx.h"
-#include "common/endian.h"
#include "common/util.h"
#include "sword1/objectman.h"
@@ -88,7 +87,7 @@ uint8 ObjectMan::fnCheckForTextLine(uint32 textId) {
uint8 lang = SwordEngine::_systemVars.language;
uint32 *textData = (uint32*)((uint8*)_resMan->openFetchRes(_textList[textId / ITM_PER_SEC][lang]) + sizeof(Header));
- if ((textId & ITM_ID) < READ_LE_UINT32(textData)) {
+ if ((textId & ITM_ID) < _resMan->readUint32(textData)) {
textData++;
if (textData[textId & ITM_ID])
retVal = 1;
@@ -100,11 +99,11 @@ uint8 ObjectMan::fnCheckForTextLine(uint32 textId) {
char *ObjectMan::lockText(uint32 textId) {
uint8 lang = SwordEngine::_systemVars.language;
char *addr = (char*)_resMan->openFetchRes(_textList[textId / ITM_PER_SEC][lang]) + sizeof(Header);
- if ((textId & ITM_ID) >= READ_LE_UINT32(addr)) {
- warning("ObjectMan::lockText(%d): only %d texts in file", textId & ITM_ID, READ_LE_UINT32(addr));
+ if ((textId & ITM_ID) >= _resMan->readUint32(addr)) {
+ warning("ObjectMan::lockText(%d): only %d texts in file", textId & ITM_ID, _resMan->readUint32(addr));
textId = 0; // get first line instead
}
- uint32 offset = READ_LE_UINT32(addr + ((textId & ITM_ID) + 1)* 4);
+ uint32 offset = _resMan->readUint32(addr + ((textId & ITM_ID) + 1)* 4);
if (offset == 0) {
warning("ObjectMan::lockText(%d): text number has no text lines", textId);
return _errorStr;
@@ -118,7 +117,7 @@ void ObjectMan::unlockText(uint32 textId) {
uint32 ObjectMan::lastTextNumber(int section) {
uint8 *data = (uint8*)_resMan->openFetchRes(_textList[section][SwordEngine::_systemVars.language]) + sizeof(Header);
- uint32 result = READ_LE_UINT32(data) - 1;
+ uint32 result = _resMan->readUint32(data) - 1;
_resMan->resClose(_textList[section][SwordEngine::_systemVars.language]);
return result;
}
diff --git a/engines/sword1/resman.cpp b/engines/sword1/resman.cpp
index 1397a5506e..1abc91a2e1 100644
--- a/engines/sword1/resman.cpp
+++ b/engines/sword1/resman.cpp
@@ -21,7 +21,6 @@
*/
#include "common/stdafx.h"
-#include "common/endian.h"
#include "common/config-manager.h"
#include "common/util.h"
#include "common/str.h"
@@ -49,9 +48,10 @@ namespace Sword1 {
#define MAX_PATH_LEN 260
-ResMan::ResMan(const char *fileName) {
+ResMan::ResMan(const char *fileName, bool isMacFile) {
_openCluStart = _openCluEnd = NULL;
_openClus = 0;
+ _isBigEndian = isMacFile;
_memMan = new MemMan();
loadCluDescript(fileName);
}
@@ -82,6 +82,7 @@ ResMan::~ResMan(void) {
}
void ResMan::loadCluDescript(const char *fileName) {
+ // The cluster description file is always little endian (even on the mac version, whose cluster files are big endian)
Common::File file;
file.open(fileName);
@@ -223,13 +224,9 @@ Header *ResMan::lockScript(uint32 scrID) {
error("Script id %d not found.\n", scrID);
scrID = _scriptList[scrID / ITM_PER_SEC];
#ifdef SCUMM_BIG_ENDIAN
- MemHandle *memHandle = resHandle(scrID);
- if (memHandle->cond == MEM_FREED)
- openScriptResourceBigEndian(scrID);
- else
- resOpen(scrID);
+ openScriptResourceBigEndian(scrID);
#else
- resOpen(scrID);
+ openScriptResourceLittleEndian(scrID);
#endif
return (Header*)resHandle(scrID)->data;
}
@@ -240,13 +237,9 @@ void ResMan::unlockScript(uint32 scrID) {
void *ResMan::cptResOpen(uint32 id) {
#ifdef SCUMM_BIG_ENDIAN
- MemHandle *memHandle = resHandle(id);
- if (memHandle->cond == MEM_FREED)
- openCptResourceBigEndian(id);
- else
- resOpen(id);
+ openCptResourceBigEndian(id);
#else
- resOpen(id);
+ openCptResourceLittleEndian(id);
#endif
return resHandle(id)->data;
}
@@ -286,9 +279,15 @@ void ResMan::resClose(uint32 id) {
FrameHeader *ResMan::fetchFrame(void *resourceData, uint32 frameNo) {
uint8 *frameFile = (uint8*)resourceData;
uint8 *idxData = frameFile + sizeof(Header);
- if (frameNo >= READ_LE_UINT32(idxData))
- error("fetchFrame:: frame %d doesn't exist in resource.", frameNo);
- frameFile += READ_LE_UINT32(idxData + (frameNo+1) * 4);
+ if (_isBigEndian) {
+ if (frameNo >= READ_BE_UINT32(idxData))
+ error("fetchFrame:: frame %d doesn't exist in resource.", frameNo);
+ frameFile += READ_BE_UINT32(idxData + (frameNo+1) * 4);
+ } else {
+ if (frameNo >= READ_LE_UINT32(idxData))
+ error("fetchFrame:: frame %d doesn't exist in resource.", frameNo);
+ frameFile += READ_LE_UINT32(idxData + (frameNo+1) * 4);
+ }
return (FrameHeader*)frameFile;
}
@@ -304,7 +303,12 @@ Common::File *ResMan::resFile(uint32 id) {
}
cluster->file = new Common::File();
char fileName[15];
- sprintf(fileName, "%s.CLU", _prj.clu[(id >> 24)-1].label);
+ // Supposes that big endian means mac cluster file and little endian means PC cluster file.
+ // This works, but we may want to separate the file name from the endianess or try .CLM extension if opening.clu file fail.
+ if (_isBigEndian)
+ sprintf(fileName, "%s.CLM", _prj.clu[(id >> 24)-1].label);
+ else
+ sprintf(fileName, "%s.CLU", _prj.clu[(id >> 24)-1].label);
cluster->file->open(fileName);
if (!cluster->file->isOpen()) {
@@ -355,39 +359,114 @@ uint32 ResMan::resOffset(uint32 id) {
}
void ResMan::openCptResourceBigEndian(uint32 id) {
+ bool needByteSwap = false;
+ if (!_isBigEndian) {
+ // Cluster files are in little endian fomat.
+ // If the resource are not in memory anymore, and therefore will be read
+ // from disk, they will need to be byte swaped.
+ MemHandle *memHandle = resHandle(id);
+ needByteSwap = (memHandle->cond == MEM_FREED);
+ }
resOpen(id);
- MemHandle *handle = resHandle(id);
- uint32 totSize = handle->size;
- uint32 *data = (uint32*)((uint8*)handle->data + sizeof(Header));
- totSize -= sizeof(Header);
- if (totSize & 3)
- error("Illegal compact size for id %d: %d", id, totSize);
- totSize /= 4;
- for (uint32 cnt = 0; cnt < totSize; cnt++) {
- *data = READ_LE_UINT32(data);
- data++;
+ if (needByteSwap) {
+ MemHandle *handle = resHandle(id);
+ uint32 totSize = handle->size;
+ uint32 *data = (uint32*)((uint8*)handle->data + sizeof(Header));
+ totSize -= sizeof(Header);
+ if (totSize & 3)
+ error("Illegal compact size for id %d: %d", id, totSize);
+ totSize /= 4;
+ for (uint32 cnt = 0; cnt < totSize; cnt++) {
+ *data = READ_LE_UINT32(data);
+ data++;
+ }
+ }
+}
+
+void ResMan::openCptResourceLittleEndian(uint32 id) {
+ bool needByteSwap = false;
+ if (_isBigEndian) {
+ // Cluster files are in big endian fomat.
+ // If the resource are not in memory anymore, and therefore will be read
+ // from disk, they will need to be byte swaped.
+ MemHandle *memHandle = resHandle(id);
+ needByteSwap = (memHandle->cond == MEM_FREED);
+ }
+ resOpen(id);
+ if (needByteSwap) {
+ MemHandle *handle = resHandle(id);
+ uint32 totSize = handle->size;
+ uint32 *data = (uint32*)((uint8*)handle->data + sizeof(Header));
+ totSize -= sizeof(Header);
+ if (totSize & 3)
+ error("Illegal compact size for id %d: %d", id, totSize);
+ totSize /= 4;
+ for (uint32 cnt = 0; cnt < totSize; cnt++) {
+ *data = READ_BE_UINT32(data);
+ data++;
+ }
}
}
void ResMan::openScriptResourceBigEndian(uint32 id) {
+ bool needByteSwap = false;
+ if (!_isBigEndian) {
+ // Cluster files are in little endian fomat.
+ // If the resource are not in memory anymore, and therefore will be read
+ // from disk, they will need to be byte swaped.
+ MemHandle *memHandle = resHandle(id);
+ needByteSwap = (memHandle->cond == MEM_FREED);
+ }
resOpen(id);
- MemHandle *handle = resHandle(id);
- // uint32 totSize = handle->size;
- Header *head = (Header*)handle->data;
- head->comp_length = FROM_LE_32(head->comp_length);
- head->decomp_length = FROM_LE_32(head->decomp_length);
- head->version = FROM_LE_16(head->version);
- uint32 *data = (uint32*)((uint8*)handle->data + sizeof(Header));
- uint32 size = handle->size - sizeof(Header);
- if (size & 3)
- error("Odd size during script endian conversion. Resource ID =%d, size = %d", id, size);
- size >>= 2;
- for (uint32 cnt = 0; cnt < size; cnt++) {
- *data = READ_LE_UINT32(data);
- data++;
+ if (needByteSwap) {
+ MemHandle *handle = resHandle(id);
+ // uint32 totSize = handle->size;
+ Header *head = (Header*)handle->data;
+ head->comp_length = FROM_LE_32(head->comp_length);
+ head->decomp_length = FROM_LE_32(head->decomp_length);
+ head->version = FROM_LE_16(head->version);
+ uint32 *data = (uint32*)((uint8*)handle->data + sizeof(Header));
+ uint32 size = handle->size - sizeof(Header);
+ if (size & 3)
+ error("Odd size during script endian conversion. Resource ID =%d, size = %d", id, size);
+ size >>= 2;
+ for (uint32 cnt = 0; cnt < size; cnt++) {
+ *data = READ_LE_UINT32(data);
+ data++;
+ }
+ }
+}
+
+void ResMan::openScriptResourceLittleEndian(uint32 id) {
+ bool needByteSwap = false;
+ if (_isBigEndian) {
+ // Cluster files are in big endian fomat.
+ // If the resource are not in memory anymore, and therefore will be read
+ // from disk, they will need to be byte swaped.
+ MemHandle *memHandle = resHandle(id);
+ needByteSwap = (memHandle->cond == MEM_FREED);
+ }
+ resOpen(id);
+ if (needByteSwap) {
+ MemHandle *handle = resHandle(id);
+ // uint32 totSize = handle->size;
+ Header *head = (Header*)handle->data;
+ head->comp_length = FROM_BE_32(head->comp_length);
+ head->decomp_length = FROM_BE_32(head->decomp_length);
+ head->version = FROM_BE_16(head->version);
+ uint32 *data = (uint32*)((uint8*)handle->data + sizeof(Header));
+ uint32 size = handle->size - sizeof(Header);
+ if (size & 3)
+ error("Odd size during script endian conversion. Resource ID =%d, size = %d", id, size);
+ size >>= 2;
+ for (uint32 cnt = 0; cnt < size; cnt++) {
+ *data = READ_BE_UINT32(data);
+ data++;
+ }
}
}
+
uint32 ResMan::_srIdList[29] = { // the file numbers differ for the control panel file IDs, so we need this array
OTHER_SR_FONT, // SR_FONT
0x04050000, // SR_BUTTON
diff --git a/engines/sword1/resman.h b/engines/sword1/resman.h
index e2920b0a81..05cc54f92f 100644
--- a/engines/sword1/resman.h
+++ b/engines/sword1/resman.h
@@ -26,6 +26,7 @@
#include "sword1/memman.h"
#include "common/file.h"
#include "sword1/sworddefs.h"
+#include "common/endian.h"
namespace Sword1 {
@@ -62,7 +63,7 @@ struct Prj {
class ResMan {
public:
- ResMan(const char *fileName);
+ ResMan(const char *fileName, bool isMacFile);
~ResMan(void);
void flush(void);
void resClose(uint32 id);
@@ -74,6 +75,36 @@ public:
Header *lockScript(uint32 scrID);
void unlockScript(uint32 scrID);
FrameHeader *fetchFrame(void *resourceData, uint32 frameNo);
+
+ uint16 getUint16(uint16 value) {
+ return (_isBigEndian) ? FROM_BE_16(value): FROM_LE_16(value);
+ }
+ uint32 getUint32(uint32 value) {
+ return (_isBigEndian) ? FROM_BE_32(value): FROM_LE_32(value);
+ }
+ uint16 getLEUint16(uint16 value) {
+ return FROM_LE_16(value);
+ }
+ uint32 getLEUint32(uint32 value) {
+ return FROM_LE_32(value);
+ }
+ uint16 readUint16(const void *ptr) {
+ return (_isBigEndian) ? READ_BE_UINT16(ptr): READ_LE_UINT16(ptr);
+ }
+ uint32 readUint32(const void *ptr) {
+ return (_isBigEndian) ? READ_BE_UINT32(ptr):READ_LE_UINT32(ptr);
+ }
+ uint32 readLEUint32(const void *ptr) {
+ return READ_LE_UINT32(ptr);
+ }
+ uint16 toUint16(uint16 value) {
+ return (_isBigEndian) ? TO_BE_16(value): TO_LE_16(value);
+ }
+ uint32 toUint32(uint32 value) {
+ return (_isBigEndian) ? TO_BE_32(value): TO_LE_32(value);
+ }
+
+
private:
uint32 resLength(uint32 id);
MemHandle *resHandle(uint32 id);
@@ -82,6 +113,8 @@ private:
void openCptResourceBigEndian(uint32 id);
void openScriptResourceBigEndian(uint32 id);
+ void openCptResourceLittleEndian(uint32 id);
+ void openScriptResourceLittleEndian(uint32 id);
void loadCluDescript(const char *fileName);
void freeCluDescript(void);
@@ -91,6 +124,7 @@ private:
static uint32 _srIdList[29];
Clu *_openCluStart, *_openCluEnd;
int _openClus;
+ bool _isBigEndian;
};
} // End of namespace Sword1
diff --git a/engines/sword1/router.cpp b/engines/sword1/router.cpp
index 8b263758fb..7ca917326b 100644
--- a/engines/sword1/router.cpp
+++ b/engines/sword1/router.cpp
@@ -21,7 +21,6 @@
*/
#include "common/stdafx.h"
-#include "common/endian.h"
#include "common/util.h"
#include "sword1/router.h"
@@ -1911,7 +1910,7 @@ int32 Router::LoadWalkResources(Object *megaObject, int32 x, int32 y, int32 dir)
fPolygrid += sizeof(Header);
memcpy(&floorHeader,fPolygrid,sizeof(WalkGridHeader));
fPolygrid += sizeof(WalkGridHeader);
- _nBars = FROM_LE_32(floorHeader.numBars);
+ _nBars = _resMan->getUint32(floorHeader.numBars);
if (_nBars >= O_GRID_SIZE)
{
@@ -1921,7 +1920,7 @@ int32 Router::LoadWalkResources(Object *megaObject, int32 x, int32 y, int32 dir)
_nBars = 0;
}
- _nNodes = FROM_LE_32(floorHeader.numNodes)+1; //array starts at 0 begins at a start _node has nnodes nodes and a target _node
+ _nNodes = _resMan->getUint32(floorHeader.numNodes)+1; //array starts at 0 begins at a start _node has nnodes nodes and a target _node
if (_nNodes >= O_GRID_SIZE)
{
@@ -1934,17 +1933,17 @@ int32 Router::LoadWalkResources(Object *megaObject, int32 x, int32 y, int32 dir)
/*memmove(&_bars[0],fPolygrid,_nBars*sizeof(BarData));
fPolygrid += _nBars*sizeof(BarData);//move pointer to start of _node data*/
for (cnt = 0; cnt < _nBars; cnt++) {
- _bars[cnt].x1 = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
- _bars[cnt].y1 = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
- _bars[cnt].x2 = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
- _bars[cnt].y2 = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
- _bars[cnt].xmin = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
- _bars[cnt].ymin = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
- _bars[cnt].xmax = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
- _bars[cnt].ymax = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
- _bars[cnt].dx = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
- _bars[cnt].dy = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
- _bars[cnt].co = READ_LE_UINT32(fPolygrid); fPolygrid += 4;
+ _bars[cnt].x1 = _resMan->readUint16(fPolygrid); fPolygrid += 2;
+ _bars[cnt].y1 = _resMan->readUint16(fPolygrid); fPolygrid += 2;
+ _bars[cnt].x2 = _resMan->readUint16(fPolygrid); fPolygrid += 2;
+ _bars[cnt].y2 = _resMan->readUint16(fPolygrid); fPolygrid += 2;
+ _bars[cnt].xmin = _resMan->readUint16(fPolygrid); fPolygrid += 2;
+ _bars[cnt].ymin = _resMan->readUint16(fPolygrid); fPolygrid += 2;
+ _bars[cnt].xmax = _resMan->readUint16(fPolygrid); fPolygrid += 2;
+ _bars[cnt].ymax = _resMan->readUint16(fPolygrid); fPolygrid += 2;
+ _bars[cnt].dx = _resMan->readUint16(fPolygrid); fPolygrid += 2;
+ _bars[cnt].dy = _resMan->readUint16(fPolygrid); fPolygrid += 2;
+ _bars[cnt].co = _resMan->readUint32(fPolygrid); fPolygrid += 4;
}
/*j = 1;// leave _node 0 for start _node
@@ -1954,8 +1953,8 @@ int32 Router::LoadWalkResources(Object *megaObject, int32 x, int32 y, int32 dir)
j ++;
} while (j < _nNodes);//array starts at 0*/
for (cnt = 1; cnt < _nNodes; cnt++) {
- _node[cnt].x = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
- _node[cnt].y = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
+ _node[cnt].x = _resMan->readUint16(fPolygrid); fPolygrid += 2;
+ _node[cnt].y = _resMan->readUint16(fPolygrid); fPolygrid += 2;
}
//ResUnlock(walkGridResourceId); // mouse wiggle
@@ -1980,17 +1979,17 @@ int32 Router::LoadWalkResources(Object *megaObject, int32 x, int32 y, int32 dir)
//ResOpen(megaObject->o_mega_resource); // mouse wiggle
//fMegaWalkData = ResLock(megaObject->o_mega_resource); // mouse wiggle
fMegaWalkData = (uint8*)_resMan->openFetchRes(megaObject->o_mega_resource);
+ // Apparently this resource is in little endian in both the Mac and the PC version
_nWalkFrames = fMegaWalkData[0];
_nTurnFrames = fMegaWalkData[1];
fMegaWalkData += 2;
-
for (cnt = 0; cnt < NO_DIRECTIONS * (_nWalkFrames + 1 + _nTurnFrames); cnt++) {
- _dx[cnt] = (int32)READ_LE_UINT32(fMegaWalkData);
+ _dx[cnt] = (int32)_resMan->readLEUint32(fMegaWalkData);
fMegaWalkData += 4;
}
for (cnt = 0; cnt < NO_DIRECTIONS * (_nWalkFrames + 1 + _nTurnFrames); cnt++) {
- _dy[cnt] = (int32)READ_LE_UINT32(fMegaWalkData);
+ _dy[cnt] = (int32)_resMan->readLEUint32(fMegaWalkData);
fMegaWalkData += 4;
}
/*memmove(&_dx[0],fMegaWalkData,NO_DIRECTIONS*(_nWalkFrames+1+_nTurnFrames)*sizeof(int32));
@@ -1999,11 +1998,11 @@ int32 Router::LoadWalkResources(Object *megaObject, int32 x, int32 y, int32 dir)
fMegaWalkData += NO_DIRECTIONS*(_nWalkFrames+1+_nTurnFrames)*sizeof(int32);*/
for (cntu = 0; cntu < NO_DIRECTIONS; cntu++) {
- _modX[cntu] = (int32)READ_LE_UINT32(fMegaWalkData);
+ _modX[cntu] = (int32)_resMan->readLEUint32(fMegaWalkData);
fMegaWalkData += 4;
}
for (cntu = 0; cntu < NO_DIRECTIONS; cntu++) {
- _modY[cntu] = (int32)READ_LE_UINT32(fMegaWalkData);
+ _modY[cntu] = (int32)_resMan->readLEUint32(fMegaWalkData);
fMegaWalkData += 4;
}
/*memmove(&_modX[0],fMegaWalkData,NO_DIRECTIONS*sizeof(int32));
diff --git a/engines/sword1/screen.cpp b/engines/sword1/screen.cpp
index ba04d03d84..a3045440f5 100644
--- a/engines/sword1/screen.cpp
+++ b/engines/sword1/screen.cpp
@@ -21,7 +21,6 @@
*/
#include "common/stdafx.h"
-#include "common/endian.h"
#include "common/system.h"
#include "common/util.h"
@@ -407,40 +406,40 @@ void Screen::processImage(uint32 id) {
uint16 spriteY = compact->o_anim_y;
if (compact->o_status & STAT_SHRINK) {
scale = (compact->o_scale_a * compact->o_ycoord + compact->o_scale_b) / 256;
- spriteX += ((int16)READ_LE_UINT16(&frameHead->offsetX) * scale) / 256;
- spriteY += ((int16)READ_LE_UINT16(&frameHead->offsetY) * scale) / 256;
+ spriteX += ((int16)_resMan->readUint16(&frameHead->offsetX) * scale) / 256;
+ spriteY += ((int16)_resMan->readUint16(&frameHead->offsetY) * scale) / 256;
} else {
scale = 256;
- spriteX += (int16)READ_LE_UINT16(&frameHead->offsetX);
- spriteY += (int16)READ_LE_UINT16(&frameHead->offsetY);
+ spriteX += (int16)_resMan->readUint16(&frameHead->offsetX);
+ spriteY += (int16)_resMan->readUint16(&frameHead->offsetY);
}
uint8 *tonyBuf = NULL;
if (frameHead->runTimeComp[3] == '7') { // RLE7 encoded?
- decompressRLE7(sprData, READ_LE_UINT32(&frameHead->compSize), _rleBuffer);
+ decompressRLE7(sprData, _resMan->readUint32(&frameHead->compSize), _rleBuffer);
sprData = _rleBuffer;
} else if (frameHead->runTimeComp[3] == '0') { // RLE0 encoded?
- decompressRLE0(sprData, READ_LE_UINT32(&frameHead->compSize), _rleBuffer);
+ decompressRLE0(sprData, _resMan->readUint32(&frameHead->compSize), _rleBuffer);
sprData = _rleBuffer;
} else if (frameHead->runTimeComp[1] == 'I') { // new type
- tonyBuf = (uint8*)malloc(READ_LE_UINT16(&frameHead->width) * READ_LE_UINT16(&frameHead->height));
- decompressTony(sprData, READ_LE_UINT32(&frameHead->compSize), tonyBuf);
+ tonyBuf = (uint8*)malloc(_resMan->readUint16(&frameHead->width) * _resMan->readUint16(&frameHead->height));
+ decompressTony(sprData, _resMan->readUint32(&frameHead->compSize), tonyBuf);
sprData = tonyBuf;
}
uint16 sprSizeX, sprSizeY;
if (compact->o_status & STAT_SHRINK) {
- sprSizeX = (scale * READ_LE_UINT16(&frameHead->width)) / 256;
- sprSizeY = (scale * READ_LE_UINT16(&frameHead->height)) / 256;
- fastShrink(sprData, READ_LE_UINT16(&frameHead->width), READ_LE_UINT16(&frameHead->height), scale, _shrinkBuffer);
+ sprSizeX = (scale * _resMan->readUint16(&frameHead->width)) / 256;
+ sprSizeY = (scale * _resMan->readUint16(&frameHead->height)) / 256;
+ fastShrink(sprData, _resMan->readUint16(&frameHead->width), _resMan->readUint16(&frameHead->height), scale, _shrinkBuffer);
sprData = _shrinkBuffer;
} else {
- sprSizeX = READ_LE_UINT16(&frameHead->width);
- sprSizeY = READ_LE_UINT16(&frameHead->height);
+ sprSizeX = _resMan->readUint16(&frameHead->width);
+ sprSizeY = _resMan->readUint16(&frameHead->height);
}
if (!(compact->o_status & STAT_OVERRIDE)) {
//mouse size linked to exact size & coordinates of sprite box - shrink friendly
- if (READ_LE_UINT16(&frameHead->offsetX) || READ_LE_UINT16(&frameHead->offsetY)) {
+ if (_resMan->readUint16(&frameHead->offsetX) || _resMan->readUint16(&frameHead->offsetY)) {
//for megas the mouse area is reduced to account for sprite not
//filling the box size is reduced to 1/2 width, 4/5 height
compact->o_mouse_x1 = spriteX + sprSizeX / 4;
@@ -495,7 +494,7 @@ void Screen::verticalMask(uint16 x, uint16 y, uint16 bWidth, uint16 bHeight) {
uint16 *grid = _layerGrid[level] + gridX + blkx + gridY * lGridSizeX;
for (int16 blky = bHeight - 1; blky >= 0; blky--) {
if (*grid) {
- uint8 *blkData = _layerBlocks[level + 1] + (READ_LE_UINT16(grid) - 1) * 128;
+ uint8 *blkData = _layerBlocks[level + 1] + (_resMan->readUint16(grid) - 1) * 128;
blitBlockClear(x + blkx, y + blky, blkData);
} else
break;
@@ -520,7 +519,7 @@ void Screen::blitBlockClear(uint16 x, uint16 y, uint8 *data) {
void Screen::renderParallax(uint8 *data) {
ParallaxHeader *header = (ParallaxHeader*)data;
uint32 *lineIndexes = (uint32*)(data + sizeof(ParallaxHeader));
- assert((FROM_LE_16(header->sizeX) >= SCREEN_WIDTH) && (FROM_LE_16(header->sizeY) >= SCREEN_DEPTH));
+ assert((_resMan->getUint16(header->sizeX) >= SCREEN_WIDTH) && (_resMan->getUint16(header->sizeY) >= SCREEN_DEPTH));
uint16 paraScrlX, paraScrlY;
uint16 scrnScrlX, scrnScrlY;
@@ -533,19 +532,19 @@ void Screen::renderParallax(uint8 *data) {
scrnHeight = SCREEN_DEPTH + ABS((int32)_oldScrollY - (int32)Logic::_scriptVars[SCROLL_OFFSET_Y]);
if (_scrnSizeX != SCREEN_WIDTH) {
- double scrlfx = (FROM_LE_16(header->sizeX) - SCREEN_WIDTH) / ((double)(_scrnSizeX - SCREEN_WIDTH));
+ double scrlfx = (_resMan->getUint16(header->sizeX) - SCREEN_WIDTH) / ((double)(_scrnSizeX - SCREEN_WIDTH));
paraScrlX = (uint16)(scrnScrlX * scrlfx);
} else
paraScrlX = 0;
if (_scrnSizeY != SCREEN_DEPTH) {
- double scrlfy = (FROM_LE_16(header->sizeY) - SCREEN_DEPTH) / ((double)(_scrnSizeY - SCREEN_DEPTH));
+ double scrlfy = (_resMan->getUint16(header->sizeY) - SCREEN_DEPTH) / ((double)(_scrnSizeY - SCREEN_DEPTH));
paraScrlY = (uint16)(scrnScrlY * scrlfy);
} else
paraScrlY = 0;
for (uint16 cnty = 0; cnty < scrnHeight; cnty++) {
- uint8 *src = data + READ_LE_UINT32(lineIndexes + cnty + paraScrlY);
+ uint8 *src = data + _resMan->readUint32(lineIndexes + cnty + paraScrlY);
uint8 *dest = _screenBuf + scrnScrlX + (cnty + scrnScrlY) * _scrnSizeX;
uint16 remain = paraScrlX;
uint16 xPos = 0;
@@ -655,7 +654,7 @@ void Screen::addToGraphicList(uint8 listId, uint32 objId) {
if (!(cpt->o_status & STAT_SHRINK)) { // not a boxed mega using shrinking
Header *frameRaw = (Header*)_resMan->openFetchRes(cpt->o_resource);
FrameHeader *frameHead = _resMan->fetchFrame(frameRaw, cpt->o_frame);
- _sortList[_sortLength].y += READ_LE_UINT16(&frameHead->height) - 1; // now pointing to base of sprite
+ _sortList[_sortLength].y += _resMan->readUint16(&frameHead->height) - 1; // now pointing to base of sprite
_resMan->resClose(cpt->o_resource);
}
_sortLength++;
@@ -803,9 +802,9 @@ void Screen::showFrame(uint16 x, uint16 y, uint32 resId, uint32 frameNo, const b
FrameHeader *frameHead = _resMan->fetchFrame(_resMan->openFetchRes(resId), frameNo);
uint8 *frameData = ((uint8*)frameHead) + sizeof(FrameHeader);
- for (i = 0; i < FROM_LE_16(frameHead->height); i++) {
- for (j = 0; j < FROM_LE_16(frameHead->height); j++) {
- frame[(i + 4) * 40 + j + 2] = frameData[i * FROM_LE_16(frameHead->width) + j];
+ for (i = 0; i < _resMan->getUint16(frameHead->height); i++) {
+ for (j = 0; j < _resMan->getUint16(frameHead->height); j++) {
+ frame[(i + 4) * 40 + j + 2] = frameData[i * _resMan->getUint16(frameHead->width) + j];
}
}
diff --git a/engines/sword1/sword1.cpp b/engines/sword1/sword1.cpp
index 88c8063c08..485091bece 100644
--- a/engines/sword1/sword1.cpp
+++ b/engines/sword1/sword1.cpp
@@ -51,16 +51,27 @@ static const PlainGameDescriptor sword1FullSettings =
{"sword1", "Broken Sword 1: The Shadow of the Templars"};
static const PlainGameDescriptor sword1DemoSettings =
{"sword1demo", "Broken Sword 1: The Shadow of the Templars (Demo)"};
+static const PlainGameDescriptor sword1MacFullSettings =
+ {"sword1mac", "Broken Sword 1: The Shadow of the Templars (Mac)"};
+static const PlainGameDescriptor sword1MacDemoSettings =
+ {"sword1macdemo", "Broken Sword 1: The Shadow of the Templars (Mac demo)"};
// check these subdirectories (if present)
static const char *g_dirNames[] = { "clusters", "speech" };
-#define NUM_FILES_TO_CHECK 5
+#define NUM_COMMON_FILES_TO_CHECK 1
+#define NUM_PC_FILES_TO_CHECK 3
+#define NUM_MAC_FILES_TO_CHECK 3
+#define NUM_DEMO_FILES_TO_CHECK 1
+#define NUM_FILES_TO_CHECK NUM_COMMON_FILES_TO_CHECK + NUM_PC_FILES_TO_CHECK + NUM_MAC_FILES_TO_CHECK + NUM_DEMO_FILES_TO_CHECK
static const char *g_filesToCheck[NUM_FILES_TO_CHECK] = { // these files have to be found
- "swordres.rif",
- "general.clu",
- "compacts.clu",
- "scripts.clu",
+ "swordres.rif", // Mac and PC version
+ "general.clu", // PC version only
+ "compacts.clu", // PC version only
+ "scripts.clu", // PC version only
+ "general.clm", // Mac version only
+ "compacts.clm", // Mac version only
+ "scripts.clm", // Mac version only
"cows.mad", // this one should only exist in the demo version
// the engine needs several more files to work, but checking these should be sufficient
};
@@ -69,6 +80,8 @@ GameList Engine_SWORD1_gameIDList() {
GameList games;
games.push_back(sword1FullSettings);
games.push_back(sword1DemoSettings);
+ games.push_back(sword1MacFullSettings);
+ //games.push_back(sword1MacDemoSettings);
return games;
}
@@ -77,6 +90,10 @@ GameDescriptor Engine_SWORD1_findGameID(const char *gameid) {
return sword1FullSettings;
if (0 == scumm_stricmp(gameid, sword1DemoSettings.gameid))
return sword1DemoSettings;
+ if (0 == scumm_stricmp(gameid, sword1MacFullSettings.gameid))
+ return sword1MacFullSettings;
+ //if (0 == scumm_stricmp(gameid, sword1MacDemoSettings.gameid))
+ // return sword1MacDemoSettings;
return GameDescriptor();
}
@@ -99,22 +116,38 @@ void Sword1CheckDirectory(const FSList &fslist, bool *filesFound) {
}
DetectedGameList Engine_SWORD1_detectGames(const FSList &fslist) {
- int i;
+ int i, j;
DetectedGameList detectedGames;
bool filesFound[NUM_FILES_TO_CHECK];
for (i = 0; i < NUM_FILES_TO_CHECK; i++)
filesFound[i] = false;
-
+
Sword1CheckDirectory(fslist, filesFound);
bool mainFilesFound = true;
- for (i = 0; i < NUM_FILES_TO_CHECK -1; i++)
+ bool pcFilesFound = true;
+ bool macFilesFound = true;
+ bool demoFilesFound = true;
+ for (i = 0; i < NUM_COMMON_FILES_TO_CHECK; i++)
if (!filesFound[i])
mainFilesFound = false;
+ for (j = 0; j < NUM_PC_FILES_TO_CHECK; i++, j++)
+ if (!filesFound[i])
+ pcFilesFound = false;
+ for (j = 0; j < NUM_MAC_FILES_TO_CHECK; i++, j++)
+ if (!filesFound[i])
+ macFilesFound = false;
+ for (j = 0; j < NUM_DEMO_FILES_TO_CHECK; i++, j++)
+ if (!filesFound[i])
+ demoFilesFound = false;
- if (mainFilesFound && filesFound[NUM_FILES_TO_CHECK - 1])
+ if (mainFilesFound && pcFilesFound && demoFilesFound)
detectedGames.push_back(sword1DemoSettings);
- else if (mainFilesFound)
+ else if (mainFilesFound && pcFilesFound)
detectedGames.push_back(sword1FullSettings);
+ //else if (mainFilesFound && macFilesFound && demoFilesFound)
+ // detectedGames.push_back(sword1MacDemoSettings);
+ else if (mainFilesFound && macFilesFound)
+ detectedGames.push_back(sword1MacFullSettings);
return detectedGames;
}
@@ -134,11 +167,11 @@ SystemVars SwordEngine::_systemVars;
SwordEngine::SwordEngine(OSystem *syst)
: Engine(syst) {
- if (0 == scumm_stricmp(ConfMan.get("gameid").c_str(), "sword1demo"))
+ if ( 0 == scumm_stricmp(ConfMan.get("gameid").c_str(), "sword1demo") ||
+ 0 == scumm_stricmp(ConfMan.get("gameid").c_str(), "sword1macdemo") )
_features = GF_DEMO;
else
- _features = 0;
-
+ _features = 0;
if (!_mixer->isReady())
warning("Sound initialization failed");
@@ -172,11 +205,17 @@ int SwordEngine::init() {
initCommonGFX(true);
_system->initSize(640, 480);
_system->endGFXTransaction();
+
+ if ( 0 == scumm_stricmp(ConfMan.get("gameid").c_str(), "sword1mac") ||
+ 0 == scumm_stricmp(ConfMan.get("gameid").c_str(), "sword1macdemo") )
+ _systemVars.isMac = true;
+ else
+ _systemVars.isMac = false;
checkCdFiles();
debug(5, "Starting resource manager");
- _resMan = new ResMan("swordres.rif");
+ _resMan = new ResMan("swordres.rif", _systemVars.isMac);
debug(5, "Starting object manager");
_objectMan = new ObjectMan(_resMan);
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, Audio::Mixer::kMaxMixerVolume);
@@ -287,7 +326,7 @@ static const char *errorMsgs[] = {
"Please copy these files from their corresponding CDs:\n"
};
-const CdFile SwordEngine::_cdFileList[] = {
+const CdFile SwordEngine::_pcCdFileList[] = {
{ "paris2.clu", FLAG_CD1 },
{ "ireland.clu", FLAG_CD2 },
{ "paris3.clu", FLAG_CD1 },
@@ -316,29 +355,84 @@ const CdFile SwordEngine::_cdFileList[] = {
#endif
};
+const CdFile SwordEngine::_macCdFileList[] = {
+ { "paris2.clm", FLAG_CD1 },
+ { "ireland.clm", FLAG_CD2 },
+ { "paris3.clm", FLAG_CD1 },
+ { "paris4.clm", FLAG_CD1 },
+ { "scotland.clm", FLAG_CD2 },
+ { "spain.clm", FLAG_CD2 },
+ { "syria.clm", FLAG_CD2 },
+ { "train.clm", FLAG_CD2 },
+ { "compacts.clm", FLAG_CD1 | FLAG_DEMO | FLAG_IMMED },
+ { "general.clm", FLAG_CD1 | FLAG_DEMO | FLAG_IMMED },
+ { "maps.clm", FLAG_CD1 | FLAG_DEMO },
+ { "paris1.clm", FLAG_CD1 | FLAG_DEMO },
+ { "scripts.clm", FLAG_CD1 | FLAG_DEMO | FLAG_IMMED },
+ { "swordres.rif", FLAG_CD1 | FLAG_DEMO | FLAG_IMMED },
+ { "text.clm", FLAG_CD1 | FLAG_DEMO },
+ { "cows.mad", FLAG_DEMO },
+ { "speech1.clu", FLAG_SPEECH1 },
+ { "speech2.clu", FLAG_SPEECH2 }
+#ifdef USE_MAD
+ ,{ "speech1.cl3", FLAG_SPEECH1 },
+ { "speech2.cl3", FLAG_SPEECH2 }
+#endif
+#ifdef USE_VORBIS
+ ,{ "speech1.clv", FLAG_SPEECH1 },
+ { "speech2.clv", FLAG_SPEECH2 }
+#endif
+};
+
+
void SwordEngine::showFileErrorMsg(uint8 type, bool *fileExists) {
char msg[1024];
int missCnt = 0, missNum = 0;
- for (int i = 0; i < ARRAYSIZE(_cdFileList); i++)
- if (!fileExists[i]) {
- missCnt++;
- missNum = i;
+
+ if (_systemVars.isMac) {
+ for (int i = 0; i < ARRAYSIZE(_macCdFileList); i++)
+ if (!fileExists[i]) {
+ missCnt++;
+ missNum = i;
+ }
+ assert(missCnt > 0); // this function shouldn't get called if there's nothing missing.
+ warning("%d files missing", missCnt);
+ int msgId = (type == TYPE_IMMED) ? 0 : 2;
+ if (missCnt == 1) {
+ sprintf(msg, errorMsgs[msgId],
+ _macCdFileList[missNum].name, (_macCdFileList[missNum].flags & FLAG_CD2) ? 2 : 1);
+ warning(msg);
+ } else {
+ char *pos = msg + sprintf(msg, errorMsgs[msgId + 1], missCnt);
+ warning(msg);
+ for (int i = 0; i < ARRAYSIZE(_macCdFileList); i++)
+ if (!fileExists[i]) {
+ warning("\"%s\" (CD %d)", _macCdFileList[i].name, (_macCdFileList[i].flags & FLAG_CD2) ? 2 : 1);
+ pos += sprintf(pos, "\"%s\" (CD %d)\n", _macCdFileList[i].name, (_macCdFileList[i].flags & FLAG_CD2) ? 2 : 1);
+ }
}
- assert(missCnt > 0); // this function shouldn't get called if there's nothing missing.
- warning("%d files missing", missCnt);
- int msgId = (type == TYPE_IMMED) ? 0 : 2;
- if (missCnt == 1) {
- sprintf(msg, errorMsgs[msgId],
- _cdFileList[missNum].name, (_cdFileList[missNum].flags & FLAG_CD2) ? 2 : 1);
- warning(msg);
} else {
- char *pos = msg + sprintf(msg, errorMsgs[msgId + 1], missCnt);
- warning(msg);
- for (int i = 0; i < ARRAYSIZE(_cdFileList); i++)
+ for (int i = 0; i < ARRAYSIZE(_pcCdFileList); i++)
if (!fileExists[i]) {
- warning("\"%s\" (CD %d)", _cdFileList[i].name, (_cdFileList[i].flags & FLAG_CD2) ? 2 : 1);
- pos += sprintf(pos, "\"%s\" (CD %d)\n", _cdFileList[i].name, (_cdFileList[i].flags & FLAG_CD2) ? 2 : 1);
+ missCnt++;
+ missNum = i;
}
+ assert(missCnt > 0); // this function shouldn't get called if there's nothing missing.
+ warning("%d files missing", missCnt);
+ int msgId = (type == TYPE_IMMED) ? 0 : 2;
+ if (missCnt == 1) {
+ sprintf(msg, errorMsgs[msgId],
+ _pcCdFileList[missNum].name, (_pcCdFileList[missNum].flags & FLAG_CD2) ? 2 : 1);
+ warning(msg);
+ } else {
+ char *pos = msg + sprintf(msg, errorMsgs[msgId + 1], missCnt);
+ warning(msg);
+ for (int i = 0; i < ARRAYSIZE(_pcCdFileList); i++)
+ if (!fileExists[i]) {
+ warning("\"%s\" (CD %d)", _pcCdFileList[i].name, (_pcCdFileList[i].flags & FLAG_CD2) ? 2 : 1);
+ pos += sprintf(pos, "\"%s\" (CD %d)\n", _pcCdFileList[i].name, (_pcCdFileList[i].flags & FLAG_CD2) ? 2 : 1);
+ }
+ }
}
GUI::MessageDialog dialog(msg);
dialog.runModal();
@@ -356,17 +450,33 @@ void SwordEngine::checkCdFiles(void) { // check if we're running from cd, hdd or
_systemVars.playSpeech = true;
// check all files and look out if we can find a file that wouldn't exist if this was the demo version
- for (int fcnt = 0; fcnt < ARRAYSIZE(_cdFileList); fcnt++) {
- if (Common::File::exists(_cdFileList[fcnt].name)) {
- fileExists[fcnt] = true;
- flagsToBool(foundTypes, _cdFileList[fcnt].flags);
- if (!(_cdFileList[fcnt].flags & FLAG_DEMO))
- isFullVersion = true;
- if (_cdFileList[fcnt].flags & FLAG_CD2)
- cd2FilesFound = true;
- } else {
- flagsToBool(missingTypes, _cdFileList[fcnt].flags);
- fileExists[fcnt] = false;
+ if (_systemVars.isMac) {
+ for (int fcnt = 0; fcnt < ARRAYSIZE(_macCdFileList); fcnt++) {
+ if (Common::File::exists(_macCdFileList[fcnt].name)) {
+ fileExists[fcnt] = true;
+ flagsToBool(foundTypes, _macCdFileList[fcnt].flags);
+ if (!(_macCdFileList[fcnt].flags & FLAG_DEMO))
+ isFullVersion = true;
+ if (_macCdFileList[fcnt].flags & FLAG_CD2)
+ cd2FilesFound = true;
+ } else {
+ flagsToBool(missingTypes, _macCdFileList[fcnt].flags);
+ fileExists[fcnt] = false;
+ }
+ }
+ } else {
+ for (int fcnt = 0; fcnt < ARRAYSIZE(_pcCdFileList); fcnt++) {
+ if (Common::File::exists(_pcCdFileList[fcnt].name)) {
+ fileExists[fcnt] = true;
+ flagsToBool(foundTypes, _pcCdFileList[fcnt].flags);
+ if (!(_pcCdFileList[fcnt].flags & FLAG_DEMO))
+ isFullVersion = true;
+ if (_pcCdFileList[fcnt].flags & FLAG_CD2)
+ cd2FilesFound = true;
+ } else {
+ flagsToBool(missingTypes, _pcCdFileList[fcnt].flags);
+ fileExists[fcnt] = false;
+ }
}
}
@@ -388,13 +498,23 @@ void SwordEngine::checkCdFiles(void) { // check if we're running from cd, hdd or
somethingMissing |= missingTypes[i];
if (somethingMissing) { // okay, there *are* files missing
// first, update the fileExists[] array depending on our changed missingTypes
- for (int fileCnt = 0; fileCnt < ARRAYSIZE(_cdFileList); fileCnt++)
- if (!fileExists[fileCnt]) {
- fileExists[fileCnt] = true;
- for (int flagCnt = 0; flagCnt < 8; flagCnt++)
- if (missingTypes[flagCnt] && ((_cdFileList[fileCnt].flags & (1 << flagCnt)) != 0))
- fileExists[fileCnt] = false; // this is one of the files we were looking for
- }
+ if (_systemVars.isMac) {
+ for (int fileCnt = 0; fileCnt < ARRAYSIZE(_macCdFileList); fileCnt++)
+ if (!fileExists[fileCnt]) {
+ fileExists[fileCnt] = true;
+ for (int flagCnt = 0; flagCnt < 8; flagCnt++)
+ if (missingTypes[flagCnt] && ((_macCdFileList[fileCnt].flags & (1 << flagCnt)) != 0))
+ fileExists[fileCnt] = false; // this is one of the files we were looking for
+ }
+ } else {
+ for (int fileCnt = 0; fileCnt < ARRAYSIZE(_pcCdFileList); fileCnt++)
+ if (!fileExists[fileCnt]) {
+ fileExists[fileCnt] = true;
+ for (int flagCnt = 0; flagCnt < 8; flagCnt++)
+ if (missingTypes[flagCnt] && ((_pcCdFileList[fileCnt].flags & (1 << flagCnt)) != 0))
+ fileExists[fileCnt] = false; // this is one of the files we were looking for
+ }
+ }
if (missingTypes[TYPE_IMMED]) {
// important files missing, can't start the game without them
showFileErrorMsg(TYPE_IMMED, fileExists);
diff --git a/engines/sword1/sword1.h b/engines/sword1/sword1.h
index 798e26d541..0052c576ec 100644
--- a/engines/sword1/sword1.h
+++ b/engines/sword1/sword1.h
@@ -63,6 +63,7 @@ struct SystemVars {
uint8 showText;
uint8 language;
bool isDemo;
+ bool isMac;
uint8 cutscenePackVersion;
};
@@ -100,7 +101,8 @@ private:
Music *_music;
Control *_control;
static const uint8 _cdList[TOTAL_SECTIONS];
- static const CdFile _cdFileList[];
+ static const CdFile _pcCdFileList[];
+ static const CdFile _macCdFileList[];
};
} // End of namespace Sword1
diff --git a/engines/sword1/text.cpp b/engines/sword1/text.cpp
index f227ca11f9..3b28ed5691 100644
--- a/engines/sword1/text.cpp
+++ b/engines/sword1/text.cpp
@@ -48,7 +48,7 @@ Text::Text(ObjectMan *pObjMan, ResMan *pResMan, bool czechVersion) {
_font = (uint8*)_resMan->openFetchRes(_fontId);
_joinWidth = charWidth( SPACE ) - 2 * OVERLAP;
- _charHeight = FROM_LE_16(_resMan->fetchFrame(_font, 0)->height); // all chars have the same height
+ _charHeight = _resMan->getUint16(_resMan->fetchFrame(_font, 0)->height); // all chars have the same height
_textBlocks[0] = _textBlocks[1] = NULL;
}
@@ -92,8 +92,8 @@ void Text::makeTextSprite(uint8 slot, uint8 *text, uint16 maxWidth, uint8 pen) {
memcpy( _textBlocks[slot]->runTimeComp, "Nu ", 4);
_textBlocks[slot]->compSize = 0;
- _textBlocks[slot]->width = TO_LE_16(sprWidth);
- _textBlocks[slot]->height = TO_LE_16(sprHeight);
+ _textBlocks[slot]->width = _resMan->toUint16(sprWidth);
+ _textBlocks[slot]->height = _resMan->toUint16(sprHeight);
_textBlocks[slot]->offsetX = 0;
_textBlocks[slot]->offsetY = 0;
@@ -111,7 +111,7 @@ void Text::makeTextSprite(uint8 slot, uint8 *text, uint16 maxWidth, uint8 pen) {
uint16 Text::charWidth(uint8 ch) {
if (ch < SPACE)
ch = 64;
- return FROM_LE_16(_resMan->fetchFrame(_font, ch - SPACE)->width);
+ return _resMan->getUint16(_resMan->fetchFrame(_font, ch - SPACE)->width);
}
uint16 Text::analyzeSentence(uint8 *text, uint16 maxWidth, LineInfo *line) {
@@ -158,8 +158,8 @@ uint16 Text::copyChar(uint8 ch, uint8 *sprPtr, uint16 sprWidth, uint8 pen) {
FrameHeader *chFrame = _resMan->fetchFrame(_font, ch - SPACE);
uint8 *chData = ((uint8*)chFrame) + sizeof(FrameHeader);
uint8 *dest = sprPtr;
- for (uint16 cnty = 0; cnty < FROM_LE_16(chFrame->height); cnty++) {
- for (uint16 cntx = 0; cntx < FROM_LE_16(chFrame->width); cntx++) {
+ for (uint16 cnty = 0; cnty < _resMan->getUint16(chFrame->height); cnty++) {
+ for (uint16 cntx = 0; cntx < _resMan->getUint16(chFrame->width); cntx++) {
if (*chData == LETTER_COL)
dest[cntx] = pen;
else if ((*chData == BORDER_COL) && (!dest[cntx])) // don't do a border if there's already a color underneath (chars can overlap)
@@ -168,7 +168,7 @@ uint16 Text::copyChar(uint8 ch, uint8 *sprPtr, uint16 sprWidth, uint8 pen) {
}
dest += sprWidth;
}
- return FROM_LE_16(chFrame->width);
+ return _resMan->getUint16(chFrame->width);
}
FrameHeader *Text::giveSpriteData(uint32 textTarget) {