Slighty modified Patch #1571787: "Support for Mac Broken Sword 1". sword1macdemo

target was commented out until existence of the demo is confirmed.

svn-id: r24697
This commit is contained in:
Eugene Sandulenko 2006-11-12 19:05:51 +00:00
parent 6e66bf5051
commit 3e6414a55f
12 changed files with 451 additions and 213 deletions

View file

@ -91,6 +91,9 @@ FORCEINLINE uint16 SWAP_BYTES_16(uint16 a) {
#define FROM_LE_32(a) ((uint32)(a)) #define FROM_LE_32(a) ((uint32)(a))
#define FROM_LE_16(a) ((uint16)(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_32(a) ((uint32)(a))
#define TO_LE_16(a) ((uint16)(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_32(a) SWAP_BYTES_32(a)
#define FROM_LE_16(a) SWAP_BYTES_16(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_32(a) SWAP_BYTES_32(a)
#define TO_LE_16(a) SWAP_BYTES_16(a) #define TO_LE_16(a) SWAP_BYTES_16(a)

View file

@ -21,7 +21,6 @@
*/ */
#include "common/stdafx.h" #include "common/stdafx.h"
#include "common/endian.h"
#include "common/file.h" #include "common/file.h"
#include "common/util.h" #include "common/util.h"
#include "common/savefile.h" #include "common/savefile.h"
@ -118,8 +117,8 @@ ControlButton::ControlButton(uint16 x, uint16 y, uint32 resId, uint8 id, uint8 f
_frameIdx = 0; _frameIdx = 0;
_resMan->resOpen(_resId); _resMan->resOpen(_resId);
FrameHeader *tmp = _resMan->fetchFrame(_resMan->fetchRes(_resId), 0); FrameHeader *tmp = _resMan->fetchFrame(_resMan->fetchRes(_resId), 0);
_width = FROM_LE_16(tmp->width); _width = _resMan->getUint16(tmp->width);
_height = FROM_LE_16(tmp->height); _height = _resMan->getUint16(tmp->height);
if ((x == 0) && (y == 0)) { // center the frame (used for panels); if ((x == 0) && (y == 0)) { // center the frame (used for panels);
_x = (640 - _width) / 2; _x = (640 - _width) / 2;
_y = (480 - _height) / 2; _y = (480 - _height) / 2;
@ -140,12 +139,12 @@ void ControlButton::draw(void) {
FrameHeader *fHead = _resMan->fetchFrame(_resMan->fetchRes(_resId), _frameIdx); FrameHeader *fHead = _resMan->fetchFrame(_resMan->fetchRes(_resId), _frameIdx);
uint8 *src = (uint8*)fHead + sizeof(FrameHeader); uint8 *src = (uint8*)fHead + sizeof(FrameHeader);
uint8 *dst = _dstBuf; uint8 *dst = _dstBuf;
for (uint16 cnt = 0; cnt < READ_LE_UINT16(&fHead->height); cnt++) { for (uint16 cnt = 0; cnt < _resMan->readUint16(&fHead->height); cnt++) {
for (uint16 cntx = 0; cntx < READ_LE_UINT16(&fHead->width); cntx++) for (uint16 cntx = 0; cntx < _resMan->readUint16(&fHead->width); cntx++)
if (src[cntx]) if (src[cntx])
dst[cntx] = src[cntx]; dst[cntx] = src[cntx];
dst += SCREEN_WIDTH; dst += SCREEN_WIDTH;
src += READ_LE_UINT16(&fHead->width); src += _resMan->readUint16(&fHead->width);
} }
_system->copyRectToScreen(_dstBuf, SCREEN_WIDTH, _x, _y, _width, _height); _system->copyRectToScreen(_dstBuf, SCREEN_WIDTH, _x, _y, _width, _height);
} }
@ -485,8 +484,8 @@ void Control::setupMainPanel(void) {
void Control::setupSaveRestorePanel(bool saving) { void Control::setupSaveRestorePanel(bool saving) {
FrameHeader *savePanel = _resMan->fetchFrame(_resMan->openFetchRes(SR_WINDOW), 0); FrameHeader *savePanel = _resMan->fetchFrame(_resMan->openFetchRes(SR_WINDOW), 0);
uint16 panelX = (640 - FROM_LE_16(savePanel->width)) / 2; uint16 panelX = (640 - _resMan->getUint16(savePanel->width)) / 2;
uint16 panelY = (480 - FROM_LE_16(savePanel->height)) / 2; uint16 panelY = (480 - _resMan->getUint16(savePanel->height)) / 2;
ControlButton *panel = new ControlButton(panelX, panelY, SR_WINDOW, 0, 0, _resMan, _screenBuf, _system); ControlButton *panel = new ControlButton(panelX, panelY, SR_WINDOW, 0, 0, _resMan, _screenBuf, _system);
panel->draw(); panel->draw();
delete panel; delete panel;
@ -870,7 +869,7 @@ void Control::destroyButtons(void) {
uint16 Control::getTextWidth(const uint8 *str) { uint16 Control::getTextWidth(const uint8 *str) {
uint16 width = 0; uint16 width = 0;
while (*str) { while (*str) {
width += FROM_LE_16(_resMan->fetchFrame(_font, *str - 32)->width) - 3; width += _resMan->getUint16(_resMan->fetchFrame(_font, *str - 32)->width) - 3;
str++; str++;
} }
return width; 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); FrameHeader *chSpr = _resMan->fetchFrame(font, *str - 32);
uint8 *sprData = (uint8*)chSpr + sizeof(FrameHeader); uint8 *sprData = (uint8*)chSpr + sizeof(FrameHeader);
for (uint16 cnty = 0; cnty < FROM_LE_16(chSpr->height); cnty++) { for (uint16 cnty = 0; cnty < _resMan->getUint16(chSpr->height); cnty++) {
for (uint16 cntx = 0; cntx < FROM_LE_16(chSpr->width); cntx++) { for (uint16 cntx = 0; cntx < _resMan->getUint16(chSpr->width); cntx++) {
if (sprData[cntx]) if (sprData[cntx])
dst[cntx] = sprData[cntx]; dst[cntx] = sprData[cntx];
} }
sprData += FROM_LE_16(chSpr->width); sprData += _resMan->getUint16(chSpr->width);
dst += SCREEN_WIDTH; dst += SCREEN_WIDTH;
} }
destX += FROM_LE_16(chSpr->width) - 3; destX += _resMan->getUint16(chSpr->width) - 3;
str++; str++;
} }
_system->copyRectToScreen(_screenBuf + y * SCREEN_WIDTH + x, SCREEN_WIDTH, x, y, (destX - x) + 3, 28); _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); FrameHeader *frHead = _resMan->fetchFrame(_resMan->openFetchRes(SR_VLIGHT), (vol + 15) >> 4);
uint8 *destMem = _screenBuf + destY * SCREEN_WIDTH + destX; uint8 *destMem = _screenBuf + destY * SCREEN_WIDTH + destX;
uint8 *srcMem = (uint8*)frHead + sizeof(FrameHeader); uint8 *srcMem = (uint8*)frHead + sizeof(FrameHeader);
for (uint16 cnty = 0; cnty < FROM_LE_16(frHead->height); cnty++) { for (uint16 cnty = 0; cnty < _resMan->getUint16(frHead->height); cnty++) {
memcpy(destMem, srcMem, FROM_LE_16(frHead->width)); memcpy(destMem, srcMem, _resMan->getUint16(frHead->width));
srcMem += FROM_LE_16(frHead->width); srcMem += _resMan->getUint16(frHead->width);
destMem += SCREEN_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); _resMan->resClose(SR_VLIGHT);
destX += 32; destX += 32;
} }

View file

@ -355,7 +355,7 @@ int Logic::speechDriver(Object *compact) {
} }
if (compact->o_anim_resource) { if (compact->o_anim_resource) {
uint8 *animData = ((uint8*)_resMan->openFetchRes(compact->o_anim_resource)) + sizeof(Header); uint8 *animData = ((uint8*)_resMan->openFetchRes(compact->o_anim_resource)) + sizeof(Header);
int32 numFrames = READ_LE_UINT32(animData); int32 numFrames = _resMan->readUint32(animData);
animData += 4; animData += 4;
compact->o_anim_pc++; // go to next frame of anim 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); AnimUnit *animPtr = (AnimUnit*)(animData + sizeof(AnimUnit) * compact->o_anim_pc);
if (!(compact->o_status & STAT_SHRINK)) { if (!(compact->o_status & STAT_SHRINK)) {
compact->o_anim_x = FROM_LE_32(animPtr->animX); compact->o_anim_x = _resMan->getUint32(animPtr->animX);
compact->o_anim_y = FROM_LE_32(animPtr->animY); 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); _resMan->resClose(compact->o_anim_resource);
} }
return 0; return 0;
@ -380,13 +380,13 @@ int Logic::fullAnimDriver(Object *compact) {
return 1; return 1;
} }
uint8 *data = ((uint8*)_resMan->openFetchRes(compact->o_anim_resource)) + sizeof(Header); uint8 *data = ((uint8*)_resMan->openFetchRes(compact->o_anim_resource)) + sizeof(Header);
uint32 numFrames = READ_LE_UINT32(data); uint32 numFrames = _resMan->readUint32(data);
data += 4; data += 4;
AnimUnit *animPtr = (AnimUnit*)(data + compact->o_anim_pc * sizeof(AnimUnit)); 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_x = compact->o_xcoord = _resMan->getUint32(animPtr->animX);
compact->o_anim_y = compact->o_ycoord = FROM_LE_32(animPtr->animY); compact->o_anim_y = compact->o_ycoord = _resMan->getUint32(animPtr->animY);
compact->o_frame = FROM_LE_32(animPtr->animFrame); compact->o_frame = _resMan->getUint32(animPtr->animFrame);
compact->o_anim_pc++; compact->o_anim_pc++;
if (compact->o_anim_pc == (int)numFrames) if (compact->o_anim_pc == (int)numFrames)
@ -402,15 +402,15 @@ int Logic::animDriver(Object *compact) {
return 1; return 1;
} }
uint8 *data = ((uint8*)_resMan->openFetchRes(compact->o_anim_resource)) + sizeof(Header); 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)); AnimUnit *animPtr = (AnimUnit*)(data + 4 + compact->o_anim_pc * sizeof(AnimUnit));
if (!(compact->o_status & STAT_SHRINK)) { if (!(compact->o_status & STAT_SHRINK)) {
compact->o_anim_x = FROM_LE_32(animPtr->animX); compact->o_anim_x = _resMan->getUint32(animPtr->animX);
compact->o_anim_y = FROM_LE_32(animPtr->animY); 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++; compact->o_anim_pc++;
if (compact->o_anim_pc == (int)numFrames) if (compact->o_anim_pc == (int)numFrames)
compact->o_logic = LOGIC_script; 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 = (AnimSet*)((uint8*)_resMan->openFetchRes(cdt) + sizeof(Header));
animTab += cpt->o_dir; animTab += cpt->o_dir;
cpt->o_anim_resource = FROM_LE_32(animTab->cdt); cpt->o_anim_resource = _resMan->getUint32(animTab->cdt);
cpt->o_resource = FROM_LE_32(animTab->spr); cpt->o_resource = _resMan->getUint32(animTab->spr);
_resMan->resClose(cdt); _resMan->resClose(cdt);
} else { } else {
cpt->o_anim_resource = cdt; 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); uint8 *data = (uint8*)_resMan->openFetchRes(cdt);
data += sizeof(Header); data += sizeof(Header);
if (frameNo == LAST_FRAME) if (frameNo == LAST_FRAME)
frameNo = READ_LE_UINT32(data) - 1; frameNo = _resMan->readUint32(data) - 1;
data += 4; data += 4;
animPtr = (AnimUnit*)(data + frameNo * sizeof(AnimUnit)); animPtr = (AnimUnit*)(data + frameNo * sizeof(AnimUnit));
cpt->o_anim_x = FROM_LE_32(animPtr->animX); cpt->o_anim_x = _resMan->getUint32(animPtr->animX);
cpt->o_anim_y = FROM_LE_32(animPtr->animY); cpt->o_anim_y = _resMan->getUint32(animPtr->animY);
cpt->o_frame = FROM_LE_32(animPtr->animFrame); cpt->o_frame = _resMan->getUint32(animPtr->animFrame);
cpt->o_resource = spr; cpt->o_resource = spr;
cpt->o_status &= ~STAT_SHRINK; 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); uint8 *data = (uint8*)_resMan->openFetchRes(cdt) + sizeof(Header);
if (frameNo == LAST_FRAME) if (frameNo == LAST_FRAME)
frameNo = READ_LE_UINT32(data) - 1; frameNo = _resMan->readUint32(data) - 1;
data += 4; data += 4;
AnimUnit *animPtr = (AnimUnit*)(data + sizeof(AnimUnit) * frameNo); AnimUnit *animPtr = (AnimUnit*)(data + sizeof(AnimUnit) * frameNo);
cpt->o_anim_x = cpt->o_xcoord = FROM_LE_32(animPtr->animX); cpt->o_anim_x = cpt->o_xcoord = _resMan->getUint32(animPtr->animX);
cpt->o_anim_y = cpt->o_ycoord = FROM_LE_32(animPtr->animY); cpt->o_anim_y = cpt->o_ycoord = _resMan->getUint32(animPtr->animY);
cpt->o_frame = FROM_LE_32(animPtr->animFrame); cpt->o_frame = _resMan->getUint32(animPtr->animFrame);
cpt->o_resource = spr; cpt->o_resource = spr;
cpt->o_status &= ~STAT_SHRINK; 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)); AnimSet *animTab = (AnimSet*)((uint8*)_resMan->openFetchRes(cdt) + sizeof(Header));
animTab += cpt->o_dir; animTab += cpt->o_dir;
cpt->o_anim_resource = FROM_LE_32(animTab->cdt); cpt->o_anim_resource = _resMan->getUint32(animTab->cdt);
if (animTab->cdt) if (animTab->cdt)
cpt->o_resource = FROM_LE_32(animTab->spr); cpt->o_resource = _resMan->getUint32(animTab->spr);
_resMan->resClose(cdt); _resMan->resClose(cdt);
} else { } else {
cpt->o_anim_resource = cdt; 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; textCpt->o_target = textCptId;
// the graphic is a property of Text, so we don't lock/unlock it. // 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 textSpriteWidth = _resMan->getUint16(_textMan->giveSpriteData(textCpt->o_target)->width);
uint16 textSpriteHeight = FROM_LE_16(_textMan->giveSpriteData(textCpt->o_target)->height); uint16 textSpriteHeight = _resMan->getUint16(_textMan->giveSpriteData(textCpt->o_target)->height);
cpt->o_text_id = textCptId; 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) { 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; uint16 varId = 0;
uint8 fnId = 0; uint8 fnId = 0;
uint32 param1 = 0; uint32 param1 = 0;

View file

@ -21,7 +21,6 @@
*/ */
#include "common/stdafx.h" #include "common/stdafx.h"
#include "common/endian.h"
#include "common/system.h" #include "common/system.h"
#include "graphics/cursorman.h" #include "graphics/cursorman.h"
@ -199,33 +198,33 @@ void Mouse::createPointer(uint32 ptrId, uint32 luggageId) {
if (ptrId) { if (ptrId) {
MousePtr *lugg = NULL; MousePtr *lugg = NULL;
MousePtr *ptr = (MousePtr*)_resMan->openFetchRes(ptrId); MousePtr *ptr = (MousePtr*)_resMan->openFetchRes(ptrId);
uint16 resSizeX = FROM_LE_16(ptr->sizeX); uint16 resSizeX = _resMan->getLEUint16(ptr->sizeX);
uint16 resSizeY = FROM_LE_16(ptr->sizeY); uint16 resSizeY = _resMan->getLEUint16(ptr->sizeY);
uint16 noFrames = FROM_LE_16(ptr->numFrames); uint16 noFrames = _resMan->getLEUint16(ptr->numFrames);
if (luggageId) { if (luggageId) {
lugg = (MousePtr*)_resMan->openFetchRes(luggageId); lugg = (MousePtr*)_resMan->openFetchRes(luggageId);
resSizeX = MAX(resSizeX, (uint16)((resSizeX / 2) + FROM_LE_16(lugg->sizeX))); resSizeX = MAX(resSizeX, (uint16)((resSizeX / 2) + _resMan->getLEUint16(lugg->sizeX)));
resSizeY = MAX(resSizeY, (uint16)((resSizeY / 2) + FROM_LE_16(lugg->sizeY))); resSizeY = MAX(resSizeY, (uint16)((resSizeY / 2) + _resMan->getLEUint16(lugg->sizeY)));
} }
_currentPtr = (MousePtr*)malloc(sizeof(MousePtr) + resSizeX * resSizeY * noFrames); _currentPtr = (MousePtr*)malloc(sizeof(MousePtr) + resSizeX * resSizeY * noFrames);
_currentPtr->hotSpotX = FROM_LE_16(ptr->hotSpotX); _currentPtr->hotSpotX = _resMan->getLEUint16(ptr->hotSpotX);
_currentPtr->hotSpotY = FROM_LE_16(ptr->hotSpotY); _currentPtr->hotSpotY = _resMan->getLEUint16(ptr->hotSpotY);
_currentPtr->numFrames = noFrames; _currentPtr->numFrames = noFrames;
_currentPtr->sizeX = resSizeX; _currentPtr->sizeX = resSizeX;
_currentPtr->sizeY = resSizeY; _currentPtr->sizeY = resSizeY;
uint8 *ptrData = (uint8*)_currentPtr + sizeof(MousePtr); uint8 *ptrData = (uint8*)_currentPtr + sizeof(MousePtr);
memset(ptrData, 255, resSizeX * resSizeY * noFrames); memset(ptrData, 255, resSizeX * resSizeY * noFrames);
if (luggageId) { 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++) { for (uint32 frameCnt = 0; frameCnt < noFrames; frameCnt++) {
uint8 *luggSrc = (uint8*)lugg + sizeof(MousePtr); uint8 *luggSrc = (uint8*)lugg + sizeof(MousePtr);
dstData += (resSizeY - FROM_LE_16(lugg->sizeY)) * resSizeX; dstData += (resSizeY - _resMan->getLEUint16(lugg->sizeY)) * resSizeX;
for (uint32 cnty = 0; cnty < FROM_LE_16(lugg->sizeY); cnty++) { for (uint32 cnty = 0; cnty < _resMan->getLEUint16(lugg->sizeY); cnty++) {
for (uint32 cntx = 0; cntx < FROM_LE_16(lugg->sizeX); cntx++) for (uint32 cntx = 0; cntx < _resMan->getLEUint16(lugg->sizeX); cntx++)
if (luggSrc[cntx]) if (luggSrc[cntx])
dstData[cntx] = luggSrc[cntx]; dstData[cntx] = luggSrc[cntx];
dstData += resSizeX; dstData += resSizeX;
luggSrc += FROM_LE_16(lugg->sizeX); luggSrc += _resMan->getLEUint16(lugg->sizeX);
} }
} }
_resMan->resClose(luggageId); _resMan->resClose(luggageId);
@ -233,14 +232,14 @@ void Mouse::createPointer(uint32 ptrId, uint32 luggageId) {
uint8 *dstData = ptrData; uint8 *dstData = ptrData;
uint8 *srcData = (uint8*)ptr + sizeof(MousePtr); uint8 *srcData = (uint8*)ptr + sizeof(MousePtr);
for (uint32 frameCnt = 0; frameCnt < noFrames; frameCnt++) { for (uint32 frameCnt = 0; frameCnt < noFrames; frameCnt++) {
for (uint32 cnty = 0; cnty < FROM_LE_16(ptr->sizeY); cnty++) { for (uint32 cnty = 0; cnty < _resMan->getLEUint16(ptr->sizeY); cnty++) {
for (uint32 cntx = 0; cntx < FROM_LE_16(ptr->sizeX); cntx++) for (uint32 cntx = 0; cntx < _resMan->getLEUint16(ptr->sizeX); cntx++)
if (srcData[cntx]) if (srcData[cntx])
dstData[cntx] = srcData[cntx]; dstData[cntx] = srcData[cntx];
srcData += FROM_LE_16(ptr->sizeX); srcData += _resMan->getLEUint16(ptr->sizeX);
dstData += resSizeX; dstData += resSizeX;
} }
dstData += (resSizeY - FROM_LE_16(ptr->sizeY)) * resSizeX; dstData += (resSizeY - _resMan->getLEUint16(ptr->sizeY)) * resSizeX;
} }
_resMan->resClose(ptrId); _resMan->resClose(ptrId);
} }

View file

@ -21,7 +21,6 @@
*/ */
#include "common/stdafx.h" #include "common/stdafx.h"
#include "common/endian.h"
#include "common/util.h" #include "common/util.h"
#include "sword1/objectman.h" #include "sword1/objectman.h"
@ -88,7 +87,7 @@ uint8 ObjectMan::fnCheckForTextLine(uint32 textId) {
uint8 lang = SwordEngine::_systemVars.language; uint8 lang = SwordEngine::_systemVars.language;
uint32 *textData = (uint32*)((uint8*)_resMan->openFetchRes(_textList[textId / ITM_PER_SEC][lang]) + sizeof(Header)); 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++; textData++;
if (textData[textId & ITM_ID]) if (textData[textId & ITM_ID])
retVal = 1; retVal = 1;
@ -100,11 +99,11 @@ uint8 ObjectMan::fnCheckForTextLine(uint32 textId) {
char *ObjectMan::lockText(uint32 textId) { char *ObjectMan::lockText(uint32 textId) {
uint8 lang = SwordEngine::_systemVars.language; uint8 lang = SwordEngine::_systemVars.language;
char *addr = (char*)_resMan->openFetchRes(_textList[textId / ITM_PER_SEC][lang]) + sizeof(Header); char *addr = (char*)_resMan->openFetchRes(_textList[textId / ITM_PER_SEC][lang]) + sizeof(Header);
if ((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, READ_LE_UINT32(addr)); warning("ObjectMan::lockText(%d): only %d texts in file", textId & ITM_ID, _resMan->readUint32(addr));
textId = 0; // get first line instead 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) { if (offset == 0) {
warning("ObjectMan::lockText(%d): text number has no text lines", textId); warning("ObjectMan::lockText(%d): text number has no text lines", textId);
return _errorStr; return _errorStr;
@ -118,7 +117,7 @@ void ObjectMan::unlockText(uint32 textId) {
uint32 ObjectMan::lastTextNumber(int section) { uint32 ObjectMan::lastTextNumber(int section) {
uint8 *data = (uint8*)_resMan->openFetchRes(_textList[section][SwordEngine::_systemVars.language]) + sizeof(Header); 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]); _resMan->resClose(_textList[section][SwordEngine::_systemVars.language]);
return result; return result;
} }

View file

@ -21,7 +21,6 @@
*/ */
#include "common/stdafx.h" #include "common/stdafx.h"
#include "common/endian.h"
#include "common/config-manager.h" #include "common/config-manager.h"
#include "common/util.h" #include "common/util.h"
#include "common/str.h" #include "common/str.h"
@ -49,9 +48,10 @@ namespace Sword1 {
#define MAX_PATH_LEN 260 #define MAX_PATH_LEN 260
ResMan::ResMan(const char *fileName) { ResMan::ResMan(const char *fileName, bool isMacFile) {
_openCluStart = _openCluEnd = NULL; _openCluStart = _openCluEnd = NULL;
_openClus = 0; _openClus = 0;
_isBigEndian = isMacFile;
_memMan = new MemMan(); _memMan = new MemMan();
loadCluDescript(fileName); loadCluDescript(fileName);
} }
@ -82,6 +82,7 @@ ResMan::~ResMan(void) {
} }
void ResMan::loadCluDescript(const char *fileName) { 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; Common::File file;
file.open(fileName); file.open(fileName);
@ -223,13 +224,9 @@ Header *ResMan::lockScript(uint32 scrID) {
error("Script id %d not found.\n", scrID); error("Script id %d not found.\n", scrID);
scrID = _scriptList[scrID / ITM_PER_SEC]; scrID = _scriptList[scrID / ITM_PER_SEC];
#ifdef SCUMM_BIG_ENDIAN #ifdef SCUMM_BIG_ENDIAN
MemHandle *memHandle = resHandle(scrID); openScriptResourceBigEndian(scrID);
if (memHandle->cond == MEM_FREED)
openScriptResourceBigEndian(scrID);
else
resOpen(scrID);
#else #else
resOpen(scrID); openScriptResourceLittleEndian(scrID);
#endif #endif
return (Header*)resHandle(scrID)->data; return (Header*)resHandle(scrID)->data;
} }
@ -240,13 +237,9 @@ void ResMan::unlockScript(uint32 scrID) {
void *ResMan::cptResOpen(uint32 id) { void *ResMan::cptResOpen(uint32 id) {
#ifdef SCUMM_BIG_ENDIAN #ifdef SCUMM_BIG_ENDIAN
MemHandle *memHandle = resHandle(id); openCptResourceBigEndian(id);
if (memHandle->cond == MEM_FREED)
openCptResourceBigEndian(id);
else
resOpen(id);
#else #else
resOpen(id); openCptResourceLittleEndian(id);
#endif #endif
return resHandle(id)->data; return resHandle(id)->data;
} }
@ -286,9 +279,15 @@ void ResMan::resClose(uint32 id) {
FrameHeader *ResMan::fetchFrame(void *resourceData, uint32 frameNo) { FrameHeader *ResMan::fetchFrame(void *resourceData, uint32 frameNo) {
uint8 *frameFile = (uint8*)resourceData; uint8 *frameFile = (uint8*)resourceData;
uint8 *idxData = frameFile + sizeof(Header); uint8 *idxData = frameFile + sizeof(Header);
if (frameNo >= READ_LE_UINT32(idxData)) if (_isBigEndian) {
error("fetchFrame:: frame %d doesn't exist in resource.", frameNo); if (frameNo >= READ_BE_UINT32(idxData))
frameFile += READ_LE_UINT32(idxData + (frameNo+1) * 4); 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; return (FrameHeader*)frameFile;
} }
@ -304,7 +303,12 @@ Common::File *ResMan::resFile(uint32 id) {
} }
cluster->file = new Common::File(); cluster->file = new Common::File();
char fileName[15]; 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); cluster->file->open(fileName);
if (!cluster->file->isOpen()) { if (!cluster->file->isOpen()) {
@ -355,39 +359,114 @@ uint32 ResMan::resOffset(uint32 id) {
} }
void ResMan::openCptResourceBigEndian(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); resOpen(id);
MemHandle *handle = resHandle(id); if (needByteSwap) {
uint32 totSize = handle->size; MemHandle *handle = resHandle(id);
uint32 *data = (uint32*)((uint8*)handle->data + sizeof(Header)); uint32 totSize = handle->size;
totSize -= sizeof(Header); uint32 *data = (uint32*)((uint8*)handle->data + sizeof(Header));
if (totSize & 3) totSize -= sizeof(Header);
error("Illegal compact size for id %d: %d", id, totSize); if (totSize & 3)
totSize /= 4; error("Illegal compact size for id %d: %d", id, totSize);
for (uint32 cnt = 0; cnt < totSize; cnt++) { totSize /= 4;
*data = READ_LE_UINT32(data); for (uint32 cnt = 0; cnt < totSize; cnt++) {
data++; *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) { 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); resOpen(id);
MemHandle *handle = resHandle(id); if (needByteSwap) {
// uint32 totSize = handle->size; MemHandle *handle = resHandle(id);
Header *head = (Header*)handle->data; // uint32 totSize = handle->size;
head->comp_length = FROM_LE_32(head->comp_length); Header *head = (Header*)handle->data;
head->decomp_length = FROM_LE_32(head->decomp_length); head->comp_length = FROM_LE_32(head->comp_length);
head->version = FROM_LE_16(head->version); head->decomp_length = FROM_LE_32(head->decomp_length);
uint32 *data = (uint32*)((uint8*)handle->data + sizeof(Header)); head->version = FROM_LE_16(head->version);
uint32 size = handle->size - sizeof(Header); uint32 *data = (uint32*)((uint8*)handle->data + sizeof(Header));
if (size & 3) uint32 size = handle->size - sizeof(Header);
error("Odd size during script endian conversion. Resource ID =%d, size = %d", id, size); if (size & 3)
size >>= 2; error("Odd size during script endian conversion. Resource ID =%d, size = %d", id, size);
for (uint32 cnt = 0; cnt < size; cnt++) { size >>= 2;
*data = READ_LE_UINT32(data); for (uint32 cnt = 0; cnt < size; cnt++) {
data++; *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 uint32 ResMan::_srIdList[29] = { // the file numbers differ for the control panel file IDs, so we need this array
OTHER_SR_FONT, // SR_FONT OTHER_SR_FONT, // SR_FONT
0x04050000, // SR_BUTTON 0x04050000, // SR_BUTTON

View file

@ -26,6 +26,7 @@
#include "sword1/memman.h" #include "sword1/memman.h"
#include "common/file.h" #include "common/file.h"
#include "sword1/sworddefs.h" #include "sword1/sworddefs.h"
#include "common/endian.h"
namespace Sword1 { namespace Sword1 {
@ -62,7 +63,7 @@ struct Prj {
class ResMan { class ResMan {
public: public:
ResMan(const char *fileName); ResMan(const char *fileName, bool isMacFile);
~ResMan(void); ~ResMan(void);
void flush(void); void flush(void);
void resClose(uint32 id); void resClose(uint32 id);
@ -74,6 +75,36 @@ public:
Header *lockScript(uint32 scrID); Header *lockScript(uint32 scrID);
void unlockScript(uint32 scrID); void unlockScript(uint32 scrID);
FrameHeader *fetchFrame(void *resourceData, uint32 frameNo); 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: private:
uint32 resLength(uint32 id); uint32 resLength(uint32 id);
MemHandle *resHandle(uint32 id); MemHandle *resHandle(uint32 id);
@ -82,6 +113,8 @@ private:
void openCptResourceBigEndian(uint32 id); void openCptResourceBigEndian(uint32 id);
void openScriptResourceBigEndian(uint32 id); void openScriptResourceBigEndian(uint32 id);
void openCptResourceLittleEndian(uint32 id);
void openScriptResourceLittleEndian(uint32 id);
void loadCluDescript(const char *fileName); void loadCluDescript(const char *fileName);
void freeCluDescript(void); void freeCluDescript(void);
@ -91,6 +124,7 @@ private:
static uint32 _srIdList[29]; static uint32 _srIdList[29];
Clu *_openCluStart, *_openCluEnd; Clu *_openCluStart, *_openCluEnd;
int _openClus; int _openClus;
bool _isBigEndian;
}; };
} // End of namespace Sword1 } // End of namespace Sword1

View file

@ -21,7 +21,6 @@
*/ */
#include "common/stdafx.h" #include "common/stdafx.h"
#include "common/endian.h"
#include "common/util.h" #include "common/util.h"
#include "sword1/router.h" #include "sword1/router.h"
@ -1911,7 +1910,7 @@ int32 Router::LoadWalkResources(Object *megaObject, int32 x, int32 y, int32 dir)
fPolygrid += sizeof(Header); fPolygrid += sizeof(Header);
memcpy(&floorHeader,fPolygrid,sizeof(WalkGridHeader)); memcpy(&floorHeader,fPolygrid,sizeof(WalkGridHeader));
fPolygrid += sizeof(WalkGridHeader); fPolygrid += sizeof(WalkGridHeader);
_nBars = FROM_LE_32(floorHeader.numBars); _nBars = _resMan->getUint32(floorHeader.numBars);
if (_nBars >= O_GRID_SIZE) if (_nBars >= O_GRID_SIZE)
{ {
@ -1921,7 +1920,7 @@ int32 Router::LoadWalkResources(Object *megaObject, int32 x, int32 y, int32 dir)
_nBars = 0; _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) 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)); /*memmove(&_bars[0],fPolygrid,_nBars*sizeof(BarData));
fPolygrid += _nBars*sizeof(BarData);//move pointer to start of _node data*/ fPolygrid += _nBars*sizeof(BarData);//move pointer to start of _node data*/
for (cnt = 0; cnt < _nBars; cnt++) { for (cnt = 0; cnt < _nBars; cnt++) {
_bars[cnt].x1 = READ_LE_UINT16(fPolygrid); fPolygrid += 2; _bars[cnt].x1 = _resMan->readUint16(fPolygrid); fPolygrid += 2;
_bars[cnt].y1 = READ_LE_UINT16(fPolygrid); fPolygrid += 2; _bars[cnt].y1 = _resMan->readUint16(fPolygrid); fPolygrid += 2;
_bars[cnt].x2 = READ_LE_UINT16(fPolygrid); fPolygrid += 2; _bars[cnt].x2 = _resMan->readUint16(fPolygrid); fPolygrid += 2;
_bars[cnt].y2 = READ_LE_UINT16(fPolygrid); fPolygrid += 2; _bars[cnt].y2 = _resMan->readUint16(fPolygrid); fPolygrid += 2;
_bars[cnt].xmin = READ_LE_UINT16(fPolygrid); fPolygrid += 2; _bars[cnt].xmin = _resMan->readUint16(fPolygrid); fPolygrid += 2;
_bars[cnt].ymin = READ_LE_UINT16(fPolygrid); fPolygrid += 2; _bars[cnt].ymin = _resMan->readUint16(fPolygrid); fPolygrid += 2;
_bars[cnt].xmax = READ_LE_UINT16(fPolygrid); fPolygrid += 2; _bars[cnt].xmax = _resMan->readUint16(fPolygrid); fPolygrid += 2;
_bars[cnt].ymax = READ_LE_UINT16(fPolygrid); fPolygrid += 2; _bars[cnt].ymax = _resMan->readUint16(fPolygrid); fPolygrid += 2;
_bars[cnt].dx = READ_LE_UINT16(fPolygrid); fPolygrid += 2; _bars[cnt].dx = _resMan->readUint16(fPolygrid); fPolygrid += 2;
_bars[cnt].dy = READ_LE_UINT16(fPolygrid); fPolygrid += 2; _bars[cnt].dy = _resMan->readUint16(fPolygrid); fPolygrid += 2;
_bars[cnt].co = READ_LE_UINT32(fPolygrid); fPolygrid += 4; _bars[cnt].co = _resMan->readUint32(fPolygrid); fPolygrid += 4;
} }
/*j = 1;// leave _node 0 for start _node /*j = 1;// leave _node 0 for start _node
@ -1954,8 +1953,8 @@ int32 Router::LoadWalkResources(Object *megaObject, int32 x, int32 y, int32 dir)
j ++; j ++;
} while (j < _nNodes);//array starts at 0*/ } while (j < _nNodes);//array starts at 0*/
for (cnt = 1; cnt < _nNodes; cnt++) { for (cnt = 1; cnt < _nNodes; cnt++) {
_node[cnt].x = READ_LE_UINT16(fPolygrid); fPolygrid += 2; _node[cnt].x = _resMan->readUint16(fPolygrid); fPolygrid += 2;
_node[cnt].y = READ_LE_UINT16(fPolygrid); fPolygrid += 2; _node[cnt].y = _resMan->readUint16(fPolygrid); fPolygrid += 2;
} }
//ResUnlock(walkGridResourceId); // mouse wiggle //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 //ResOpen(megaObject->o_mega_resource); // mouse wiggle
//fMegaWalkData = ResLock(megaObject->o_mega_resource); // mouse wiggle //fMegaWalkData = ResLock(megaObject->o_mega_resource); // mouse wiggle
fMegaWalkData = (uint8*)_resMan->openFetchRes(megaObject->o_mega_resource); 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]; _nWalkFrames = fMegaWalkData[0];
_nTurnFrames = fMegaWalkData[1]; _nTurnFrames = fMegaWalkData[1];
fMegaWalkData += 2; fMegaWalkData += 2;
for (cnt = 0; cnt < NO_DIRECTIONS * (_nWalkFrames + 1 + _nTurnFrames); cnt++) { 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; fMegaWalkData += 4;
} }
for (cnt = 0; cnt < NO_DIRECTIONS * (_nWalkFrames + 1 + _nTurnFrames); cnt++) { 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; fMegaWalkData += 4;
} }
/*memmove(&_dx[0],fMegaWalkData,NO_DIRECTIONS*(_nWalkFrames+1+_nTurnFrames)*sizeof(int32)); /*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);*/ fMegaWalkData += NO_DIRECTIONS*(_nWalkFrames+1+_nTurnFrames)*sizeof(int32);*/
for (cntu = 0; cntu < NO_DIRECTIONS; cntu++) { for (cntu = 0; cntu < NO_DIRECTIONS; cntu++) {
_modX[cntu] = (int32)READ_LE_UINT32(fMegaWalkData); _modX[cntu] = (int32)_resMan->readLEUint32(fMegaWalkData);
fMegaWalkData += 4; fMegaWalkData += 4;
} }
for (cntu = 0; cntu < NO_DIRECTIONS; cntu++) { for (cntu = 0; cntu < NO_DIRECTIONS; cntu++) {
_modY[cntu] = (int32)READ_LE_UINT32(fMegaWalkData); _modY[cntu] = (int32)_resMan->readLEUint32(fMegaWalkData);
fMegaWalkData += 4; fMegaWalkData += 4;
} }
/*memmove(&_modX[0],fMegaWalkData,NO_DIRECTIONS*sizeof(int32)); /*memmove(&_modX[0],fMegaWalkData,NO_DIRECTIONS*sizeof(int32));

View file

@ -21,7 +21,6 @@
*/ */
#include "common/stdafx.h" #include "common/stdafx.h"
#include "common/endian.h"
#include "common/system.h" #include "common/system.h"
#include "common/util.h" #include "common/util.h"
@ -407,40 +406,40 @@ void Screen::processImage(uint32 id) {
uint16 spriteY = compact->o_anim_y; uint16 spriteY = compact->o_anim_y;
if (compact->o_status & STAT_SHRINK) { if (compact->o_status & STAT_SHRINK) {
scale = (compact->o_scale_a * compact->o_ycoord + compact->o_scale_b) / 256; scale = (compact->o_scale_a * compact->o_ycoord + compact->o_scale_b) / 256;
spriteX += ((int16)READ_LE_UINT16(&frameHead->offsetX) * scale) / 256; spriteX += ((int16)_resMan->readUint16(&frameHead->offsetX) * scale) / 256;
spriteY += ((int16)READ_LE_UINT16(&frameHead->offsetY) * scale) / 256; spriteY += ((int16)_resMan->readUint16(&frameHead->offsetY) * scale) / 256;
} else { } else {
scale = 256; scale = 256;
spriteX += (int16)READ_LE_UINT16(&frameHead->offsetX); spriteX += (int16)_resMan->readUint16(&frameHead->offsetX);
spriteY += (int16)READ_LE_UINT16(&frameHead->offsetY); spriteY += (int16)_resMan->readUint16(&frameHead->offsetY);
} }
uint8 *tonyBuf = NULL; uint8 *tonyBuf = NULL;
if (frameHead->runTimeComp[3] == '7') { // RLE7 encoded? if (frameHead->runTimeComp[3] == '7') { // RLE7 encoded?
decompressRLE7(sprData, READ_LE_UINT32(&frameHead->compSize), _rleBuffer); decompressRLE7(sprData, _resMan->readUint32(&frameHead->compSize), _rleBuffer);
sprData = _rleBuffer; sprData = _rleBuffer;
} else if (frameHead->runTimeComp[3] == '0') { // RLE0 encoded? } 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; sprData = _rleBuffer;
} else if (frameHead->runTimeComp[1] == 'I') { // new type } else if (frameHead->runTimeComp[1] == 'I') { // new type
tonyBuf = (uint8*)malloc(READ_LE_UINT16(&frameHead->width) * READ_LE_UINT16(&frameHead->height)); tonyBuf = (uint8*)malloc(_resMan->readUint16(&frameHead->width) * _resMan->readUint16(&frameHead->height));
decompressTony(sprData, READ_LE_UINT32(&frameHead->compSize), tonyBuf); decompressTony(sprData, _resMan->readUint32(&frameHead->compSize), tonyBuf);
sprData = tonyBuf; sprData = tonyBuf;
} }
uint16 sprSizeX, sprSizeY; uint16 sprSizeX, sprSizeY;
if (compact->o_status & STAT_SHRINK) { if (compact->o_status & STAT_SHRINK) {
sprSizeX = (scale * READ_LE_UINT16(&frameHead->width)) / 256; sprSizeX = (scale * _resMan->readUint16(&frameHead->width)) / 256;
sprSizeY = (scale * READ_LE_UINT16(&frameHead->height)) / 256; sprSizeY = (scale * _resMan->readUint16(&frameHead->height)) / 256;
fastShrink(sprData, READ_LE_UINT16(&frameHead->width), READ_LE_UINT16(&frameHead->height), scale, _shrinkBuffer); fastShrink(sprData, _resMan->readUint16(&frameHead->width), _resMan->readUint16(&frameHead->height), scale, _shrinkBuffer);
sprData = _shrinkBuffer; sprData = _shrinkBuffer;
} else { } else {
sprSizeX = READ_LE_UINT16(&frameHead->width); sprSizeX = _resMan->readUint16(&frameHead->width);
sprSizeY = READ_LE_UINT16(&frameHead->height); sprSizeY = _resMan->readUint16(&frameHead->height);
} }
if (!(compact->o_status & STAT_OVERRIDE)) { if (!(compact->o_status & STAT_OVERRIDE)) {
//mouse size linked to exact size & coordinates of sprite box - shrink friendly //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 //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 //filling the box size is reduced to 1/2 width, 4/5 height
compact->o_mouse_x1 = spriteX + sprSizeX / 4; 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; uint16 *grid = _layerGrid[level] + gridX + blkx + gridY * lGridSizeX;
for (int16 blky = bHeight - 1; blky >= 0; blky--) { for (int16 blky = bHeight - 1; blky >= 0; blky--) {
if (*grid) { 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); blitBlockClear(x + blkx, y + blky, blkData);
} else } else
break; break;
@ -520,7 +519,7 @@ void Screen::blitBlockClear(uint16 x, uint16 y, uint8 *data) {
void Screen::renderParallax(uint8 *data) { void Screen::renderParallax(uint8 *data) {
ParallaxHeader *header = (ParallaxHeader*)data; ParallaxHeader *header = (ParallaxHeader*)data;
uint32 *lineIndexes = (uint32*)(data + sizeof(ParallaxHeader)); 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 paraScrlX, paraScrlY;
uint16 scrnScrlX, scrnScrlY; uint16 scrnScrlX, scrnScrlY;
@ -533,19 +532,19 @@ void Screen::renderParallax(uint8 *data) {
scrnHeight = SCREEN_DEPTH + ABS((int32)_oldScrollY - (int32)Logic::_scriptVars[SCROLL_OFFSET_Y]); scrnHeight = SCREEN_DEPTH + ABS((int32)_oldScrollY - (int32)Logic::_scriptVars[SCROLL_OFFSET_Y]);
if (_scrnSizeX != SCREEN_WIDTH) { 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); paraScrlX = (uint16)(scrnScrlX * scrlfx);
} else } else
paraScrlX = 0; paraScrlX = 0;
if (_scrnSizeY != SCREEN_DEPTH) { 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); paraScrlY = (uint16)(scrnScrlY * scrlfy);
} else } else
paraScrlY = 0; paraScrlY = 0;
for (uint16 cnty = 0; cnty < scrnHeight; cnty++) { 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; uint8 *dest = _screenBuf + scrnScrlX + (cnty + scrnScrlY) * _scrnSizeX;
uint16 remain = paraScrlX; uint16 remain = paraScrlX;
uint16 xPos = 0; 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 if (!(cpt->o_status & STAT_SHRINK)) { // not a boxed mega using shrinking
Header *frameRaw = (Header*)_resMan->openFetchRes(cpt->o_resource); Header *frameRaw = (Header*)_resMan->openFetchRes(cpt->o_resource);
FrameHeader *frameHead = _resMan->fetchFrame(frameRaw, cpt->o_frame); 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); _resMan->resClose(cpt->o_resource);
} }
_sortLength++; _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); FrameHeader *frameHead = _resMan->fetchFrame(_resMan->openFetchRes(resId), frameNo);
uint8 *frameData = ((uint8*)frameHead) + sizeof(FrameHeader); uint8 *frameData = ((uint8*)frameHead) + sizeof(FrameHeader);
for (i = 0; i < FROM_LE_16(frameHead->height); i++) { for (i = 0; i < _resMan->getUint16(frameHead->height); i++) {
for (j = 0; j < FROM_LE_16(frameHead->height); j++) { for (j = 0; j < _resMan->getUint16(frameHead->height); j++) {
frame[(i + 4) * 40 + j + 2] = frameData[i * FROM_LE_16(frameHead->width) + j]; frame[(i + 4) * 40 + j + 2] = frameData[i * _resMan->getUint16(frameHead->width) + j];
} }
} }

View file

@ -51,16 +51,27 @@ static const PlainGameDescriptor sword1FullSettings =
{"sword1", "Broken Sword 1: The Shadow of the Templars"}; {"sword1", "Broken Sword 1: The Shadow of the Templars"};
static const PlainGameDescriptor sword1DemoSettings = static const PlainGameDescriptor sword1DemoSettings =
{"sword1demo", "Broken Sword 1: The Shadow of the Templars (Demo)"}; {"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) // check these subdirectories (if present)
static const char *g_dirNames[] = { "clusters", "speech" }; 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 static const char *g_filesToCheck[NUM_FILES_TO_CHECK] = { // these files have to be found
"swordres.rif", "swordres.rif", // Mac and PC version
"general.clu", "general.clu", // PC version only
"compacts.clu", "compacts.clu", // PC version only
"scripts.clu", "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 "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 // the engine needs several more files to work, but checking these should be sufficient
}; };
@ -69,6 +80,8 @@ GameList Engine_SWORD1_gameIDList() {
GameList games; GameList games;
games.push_back(sword1FullSettings); games.push_back(sword1FullSettings);
games.push_back(sword1DemoSettings); games.push_back(sword1DemoSettings);
games.push_back(sword1MacFullSettings);
//games.push_back(sword1MacDemoSettings);
return games; return games;
} }
@ -77,6 +90,10 @@ GameDescriptor Engine_SWORD1_findGameID(const char *gameid) {
return sword1FullSettings; return sword1FullSettings;
if (0 == scumm_stricmp(gameid, sword1DemoSettings.gameid)) if (0 == scumm_stricmp(gameid, sword1DemoSettings.gameid))
return sword1DemoSettings; return sword1DemoSettings;
if (0 == scumm_stricmp(gameid, sword1MacFullSettings.gameid))
return sword1MacFullSettings;
//if (0 == scumm_stricmp(gameid, sword1MacDemoSettings.gameid))
// return sword1MacDemoSettings;
return GameDescriptor(); return GameDescriptor();
} }
@ -99,22 +116,38 @@ void Sword1CheckDirectory(const FSList &fslist, bool *filesFound) {
} }
DetectedGameList Engine_SWORD1_detectGames(const FSList &fslist) { DetectedGameList Engine_SWORD1_detectGames(const FSList &fslist) {
int i; int i, j;
DetectedGameList detectedGames; DetectedGameList detectedGames;
bool filesFound[NUM_FILES_TO_CHECK]; bool filesFound[NUM_FILES_TO_CHECK];
for (i = 0; i < NUM_FILES_TO_CHECK; i++) for (i = 0; i < NUM_FILES_TO_CHECK; i++)
filesFound[i] = false; filesFound[i] = false;
Sword1CheckDirectory(fslist, filesFound); Sword1CheckDirectory(fslist, filesFound);
bool mainFilesFound = true; 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]) if (!filesFound[i])
mainFilesFound = false; 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); detectedGames.push_back(sword1DemoSettings);
else if (mainFilesFound) else if (mainFilesFound && pcFilesFound)
detectedGames.push_back(sword1FullSettings); detectedGames.push_back(sword1FullSettings);
//else if (mainFilesFound && macFilesFound && demoFilesFound)
// detectedGames.push_back(sword1MacDemoSettings);
else if (mainFilesFound && macFilesFound)
detectedGames.push_back(sword1MacFullSettings);
return detectedGames; return detectedGames;
} }
@ -134,11 +167,11 @@ SystemVars SwordEngine::_systemVars;
SwordEngine::SwordEngine(OSystem *syst) SwordEngine::SwordEngine(OSystem *syst)
: Engine(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; _features = GF_DEMO;
else else
_features = 0; _features = 0;
if (!_mixer->isReady()) if (!_mixer->isReady())
warning("Sound initialization failed"); warning("Sound initialization failed");
@ -172,11 +205,17 @@ int SwordEngine::init() {
initCommonGFX(true); initCommonGFX(true);
_system->initSize(640, 480); _system->initSize(640, 480);
_system->endGFXTransaction(); _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(); checkCdFiles();
debug(5, "Starting resource manager"); debug(5, "Starting resource manager");
_resMan = new ResMan("swordres.rif"); _resMan = new ResMan("swordres.rif", _systemVars.isMac);
debug(5, "Starting object manager"); debug(5, "Starting object manager");
_objectMan = new ObjectMan(_resMan); _objectMan = new ObjectMan(_resMan);
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, Audio::Mixer::kMaxMixerVolume); _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" "Please copy these files from their corresponding CDs:\n"
}; };
const CdFile SwordEngine::_cdFileList[] = { const CdFile SwordEngine::_pcCdFileList[] = {
{ "paris2.clu", FLAG_CD1 }, { "paris2.clu", FLAG_CD1 },
{ "ireland.clu", FLAG_CD2 }, { "ireland.clu", FLAG_CD2 },
{ "paris3.clu", FLAG_CD1 }, { "paris3.clu", FLAG_CD1 },
@ -316,29 +355,84 @@ const CdFile SwordEngine::_cdFileList[] = {
#endif #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) { void SwordEngine::showFileErrorMsg(uint8 type, bool *fileExists) {
char msg[1024]; char msg[1024];
int missCnt = 0, missNum = 0; int missCnt = 0, missNum = 0;
for (int i = 0; i < ARRAYSIZE(_cdFileList); i++)
if (!fileExists[i]) { if (_systemVars.isMac) {
missCnt++; for (int i = 0; i < ARRAYSIZE(_macCdFileList); i++)
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],
_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++)
if (!fileExists[i]) { if (!fileExists[i]) {
warning("\"%s\" (CD %d)", _cdFileList[i].name, (_cdFileList[i].flags & FLAG_CD2) ? 2 : 1); missCnt++;
pos += sprintf(pos, "\"%s\" (CD %d)\n", _cdFileList[i].name, (_cdFileList[i].flags & FLAG_CD2) ? 2 : 1); 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);
}
}
} else {
for (int i = 0; i < ARRAYSIZE(_pcCdFileList); 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],
_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); GUI::MessageDialog dialog(msg);
dialog.runModal(); dialog.runModal();
@ -356,17 +450,33 @@ void SwordEngine::checkCdFiles(void) { // check if we're running from cd, hdd or
_systemVars.playSpeech = true; _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 // 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 (_systemVars.isMac) {
if (Common::File::exists(_cdFileList[fcnt].name)) { for (int fcnt = 0; fcnt < ARRAYSIZE(_macCdFileList); fcnt++) {
fileExists[fcnt] = true; if (Common::File::exists(_macCdFileList[fcnt].name)) {
flagsToBool(foundTypes, _cdFileList[fcnt].flags); fileExists[fcnt] = true;
if (!(_cdFileList[fcnt].flags & FLAG_DEMO)) flagsToBool(foundTypes, _macCdFileList[fcnt].flags);
isFullVersion = true; if (!(_macCdFileList[fcnt].flags & FLAG_DEMO))
if (_cdFileList[fcnt].flags & FLAG_CD2) isFullVersion = true;
cd2FilesFound = true; if (_macCdFileList[fcnt].flags & FLAG_CD2)
} else { cd2FilesFound = true;
flagsToBool(missingTypes, _cdFileList[fcnt].flags); } else {
fileExists[fcnt] = false; 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]; somethingMissing |= missingTypes[i];
if (somethingMissing) { // okay, there *are* files missing if (somethingMissing) { // okay, there *are* files missing
// first, update the fileExists[] array depending on our changed missingTypes // first, update the fileExists[] array depending on our changed missingTypes
for (int fileCnt = 0; fileCnt < ARRAYSIZE(_cdFileList); fileCnt++) if (_systemVars.isMac) {
if (!fileExists[fileCnt]) { for (int fileCnt = 0; fileCnt < ARRAYSIZE(_macCdFileList); fileCnt++)
fileExists[fileCnt] = true; if (!fileExists[fileCnt]) {
for (int flagCnt = 0; flagCnt < 8; flagCnt++) fileExists[fileCnt] = true;
if (missingTypes[flagCnt] && ((_cdFileList[fileCnt].flags & (1 << flagCnt)) != 0)) for (int flagCnt = 0; flagCnt < 8; flagCnt++)
fileExists[fileCnt] = false; // this is one of the files we were looking for 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]) { if (missingTypes[TYPE_IMMED]) {
// important files missing, can't start the game without them // important files missing, can't start the game without them
showFileErrorMsg(TYPE_IMMED, fileExists); showFileErrorMsg(TYPE_IMMED, fileExists);

View file

@ -63,6 +63,7 @@ struct SystemVars {
uint8 showText; uint8 showText;
uint8 language; uint8 language;
bool isDemo; bool isDemo;
bool isMac;
uint8 cutscenePackVersion; uint8 cutscenePackVersion;
}; };
@ -100,7 +101,8 @@ private:
Music *_music; Music *_music;
Control *_control; Control *_control;
static const uint8 _cdList[TOTAL_SECTIONS]; static const uint8 _cdList[TOTAL_SECTIONS];
static const CdFile _cdFileList[]; static const CdFile _pcCdFileList[];
static const CdFile _macCdFileList[];
}; };
} // End of namespace Sword1 } // End of namespace Sword1

View file

@ -48,7 +48,7 @@ Text::Text(ObjectMan *pObjMan, ResMan *pResMan, bool czechVersion) {
_font = (uint8*)_resMan->openFetchRes(_fontId); _font = (uint8*)_resMan->openFetchRes(_fontId);
_joinWidth = charWidth( SPACE ) - 2 * OVERLAP; _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; _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); memcpy( _textBlocks[slot]->runTimeComp, "Nu ", 4);
_textBlocks[slot]->compSize = 0; _textBlocks[slot]->compSize = 0;
_textBlocks[slot]->width = TO_LE_16(sprWidth); _textBlocks[slot]->width = _resMan->toUint16(sprWidth);
_textBlocks[slot]->height = TO_LE_16(sprHeight); _textBlocks[slot]->height = _resMan->toUint16(sprHeight);
_textBlocks[slot]->offsetX = 0; _textBlocks[slot]->offsetX = 0;
_textBlocks[slot]->offsetY = 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) { uint16 Text::charWidth(uint8 ch) {
if (ch < SPACE) if (ch < SPACE)
ch = 64; 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) { 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); FrameHeader *chFrame = _resMan->fetchFrame(_font, ch - SPACE);
uint8 *chData = ((uint8*)chFrame) + sizeof(FrameHeader); uint8 *chData = ((uint8*)chFrame) + sizeof(FrameHeader);
uint8 *dest = sprPtr; uint8 *dest = sprPtr;
for (uint16 cnty = 0; cnty < FROM_LE_16(chFrame->height); cnty++) { for (uint16 cnty = 0; cnty < _resMan->getUint16(chFrame->height); cnty++) {
for (uint16 cntx = 0; cntx < FROM_LE_16(chFrame->width); cntx++) { for (uint16 cntx = 0; cntx < _resMan->getUint16(chFrame->width); cntx++) {
if (*chData == LETTER_COL) if (*chData == LETTER_COL)
dest[cntx] = pen; 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) 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; dest += sprWidth;
} }
return FROM_LE_16(chFrame->width); return _resMan->getUint16(chFrame->width);
} }
FrameHeader *Text::giveSpriteData(uint32 textTarget) { FrameHeader *Text::giveSpriteData(uint32 textTarget) {