DRAGONS: handle negative offsets in background shift for minigame 3

This commit is contained in:
Eric Fry 2019-11-13 07:42:52 +11:00 committed by Eugene Sandulenko
parent 3299c2136d
commit fcd92dc4c3
8 changed files with 79 additions and 57 deletions

View file

@ -88,7 +88,9 @@ Background::Background() : _priorityLayer(0), _points1(0), _points2(0), _data(0)
_layerSurface[0] = NULL;
_layerSurface[1] = NULL;
_layerSurface[2] = NULL;
_xOffset = 0;
layerOffset[0] = Common::Point(0,0);
layerOffset[1] = Common::Point(0,0);
layerOffset[2] = Common::Point(0,0);
}
Background::~Background() {
@ -274,12 +276,14 @@ void Background::setPalette(byte *newPalette) {
}
}
void Background::setXOffset(int16 xOffset) {
_xOffset = xOffset;
void Background::setLayerOffset(uint8 layerNumber, Common::Point offset) {
assert(layerNumber < 4);
layerOffset[layerNumber] = offset;
}
int16 Background::getXOffset() {
return _xOffset;
Common::Point Background::getLayerOffset(uint8 layerNumber) {
assert(layerNumber < 4);
return layerOffset[layerNumber];
}
BackgroundResourceLoader::BackgroundResourceLoader(BigfileArchive *bigFileArchive, DragonRMS *dragonRMS) : _bigFileArchive(

View file

@ -62,8 +62,7 @@ private:
Common::Point *_points1;
Common::Point *_points2;
uint8 layerPriority[3];
int16 _xOffset;
Common::Point layerOffset[3];
public:
Background();
~Background();
@ -91,8 +90,8 @@ public:
void overlayImage(uint16 layerNum, byte *data, int16 x, int16 y, int16 w, int16 h);
void restoreTiles(uint16 layerNum, int16 x, int16 y, int16 w, int16 h);
void setPalette(byte *newPalette);
void setXOffset(int16 xOffset);
int16 getXOffset();
void setLayerOffset(uint8 layerNumber, Common::Point offset);
Common::Point getLayerOffset(uint8 layerNumber);
private:
Common::Point *loadPoints(Common::SeekableReadStream &stream);
Graphics::Surface *initGfxLayer(TileMap &tileMap);

View file

@ -766,13 +766,7 @@ void Minigame3::run() {
}
void Minigame3::updateBackgroundLayerOffset(uint32 layerNumber, int16 xOffset, int16 yOffset) {
_vm->_scene->setLayerXOffset(layerNumber, xOffset);
// int iVar1;
//
// iVar1 = (param_1 & 0xffff) * 0x24;
// *(undefined2 *)(&DAT_80069644 + iVar1) = param_2;
// *(short *)(&DAT_80069646 + iVar1) = param_3 + 8;
_vm->_scene->setLayerOffset(layerNumber, Common::Point(xOffset, yOffset));
}
void Minigame3::FUN_80017f70_paletteRelated(uint16 param_1) {

View file

@ -339,7 +339,7 @@ void Scene::loadSceneData(uint32 sceneId, uint32 cameraPointId) {
}
void Scene::draw() {
Common::Rect rect(_camera.x + _stage->getXOffset(), _camera.y, _camera.x + 320 + _stage->getXOffset(), _camera.y + 200);
Common::Rect rect(_camera.x, _camera.y, _camera.x + 320, _camera.y + 200);
_vm->_screen->clearScreen();
for(uint16 priority = 1; priority < 16; priority++) {
@ -348,11 +348,11 @@ void Scene::draw() {
}
if (priority == _stage->getBgLayerPriority()) {
_screen->copyRectToSurface8bpp(*_stage->getBgLayer(), _screen->getPalette(0), 0, 0, rect, false, 128);
drawBgLayer(0, rect, _stage->getBgLayer());
} else if (priority == _stage->getMgLayerPriority()) {
_screen->copyRectToSurface8bpp(*_stage->getMgLayer(), _screen->getPalette(0), 0, 0, rect, false, 128);
drawBgLayer(1, rect, _stage->getMgLayer());
} else if (priority == _stage->getFgLayerPriority()) {
_screen->copyRectToSurface8bpp(*_stage->getFgLayer(), _screen->getPalette(0), 0, 0, rect, false, 128);
drawBgLayer(2, rect, _stage->getFgLayer());
} else if (priority == 5) {
if (_vm->isFlagSet(ENGINE_FLAG_80)) {
_vm->_inventory->draw();
@ -490,10 +490,22 @@ void Scene::drawActorNumber(int16 x, int16 y, uint16 actorId) {
_vm->_fontManager->addText(x, y, text, strlen(text8), 1);
}
void Scene::setLayerXOffset(uint8 layerNumber, uint16 xOffset) {
if (layerNumber == 2) {
_stage->setXOffset(xOffset);
}
void Scene::setLayerOffset(uint8 layerNumber, Common::Point offset) {
_stage->setLayerOffset(layerNumber, offset);
}
Common::Point Scene::getLayerOffset(uint8 layerNumber) {
return _stage->getLayerOffset(layerNumber);
}
void Scene::drawBgLayer(uint8 layerNumber, Common::Rect rect, Graphics::Surface *surface) {
Common::Point offset = _stage->getLayerOffset(layerNumber);
Common::Rect clippedRect = _screen->clipRectToRect(offset.x, offset.y, rect, Common::Rect(_stage->getBgLayer()->w, _stage->getBgLayer()->h));
clippedRect.left += offset.x < 0 ? -offset.x : 0;
clippedRect.right += offset.x < 0 ? -offset.x : 0;
clippedRect.top += offset.y < 0 ? -offset.y : 0;
clippedRect.bottom += offset.y < 0 ? -offset.y : 0;
_screen->copyRectToSurface8bpp(*surface, _screen->getPalette(0), 0, 0, clippedRect, false, 128);
}
} // End of namespace Dragons

View file

@ -81,10 +81,12 @@ public:
void setMgLayerPriority(uint8 newPriority);
void setFgLayerPriority(uint8 newPriority);
void setLayerXOffset(uint8 layerNumber, uint16 xOffset);
void setLayerOffset(uint8 layerNumber, Common::Point offset);
Common::Point getLayerOffset(uint8 layerNumber);
private:
void resetActorFrameFlags();
void drawActorNumber(int16 x, int16 y, uint16 actorId);
void drawBgLayer(uint8 layerNumber, Common::Rect rect, Graphics::Surface *surface);
};
} // End of namespace Dragons

View file

@ -157,17 +157,21 @@ void Screen::copyRectToSurface8bpp(const void *buffer, byte* palette, int srcPit
}
Common::Rect Screen::clipRectToScreen(int destX, int destY, const Common::Rect rect) {
return clipRectToRect(destX, destY, rect, Common::Rect(320, 200));
}
Common::Rect Screen::clipRectToRect(int destX, int destY, const Common::Rect rect, const Common::Rect containerRect) {
int16 x, y, w, h;
x = rect.left;
y = rect.top;
w = rect.width();
h = rect.height();
if (destX >= 320) {
if (destX >= containerRect.width()) {
w = 0;
}
if (destY >= 200) {
if (destY >= containerRect.height()) {
h = 0;
}
@ -181,12 +185,12 @@ Common::Rect Screen::clipRectToScreen(int destX, int destY, const Common::Rect r
y += -destY;
}
if (w > 0 && destX + w >= 320) {
w -= (destX + w) - 320;
if (w > 0 && destX + w >= containerRect.width()) {
w -= (destX + w) - containerRect.width();
}
if (h > 0 && destY + h >= 200) {
h -= (destY + h) - 200;
if (h > 0 && destY + h >= containerRect.height()) {
h -= (destY + h) - containerRect.height();
}
if (w < 0) {

View file

@ -48,10 +48,12 @@ public:
void updatePaletteTransparency(uint16 paletteNum, uint16 startOffset, uint16 endOffset, bool isTransparent);
void clearScreen();
void drawRect(uint16 colour, Common::Rect rect, int id);
Common::Rect clipRectToScreen(int destX, int destY, const Common::Rect rect);
Common::Rect clipRectToRect(int destX, int destY, const Common::Rect rect, const Common::Rect containerRect);
private:
void copyRectToSurface(const void *buffer, int srcPitch, int srcWidth, int srcXOffset, int destX, int destY, int width, int height, bool flipX, uint8 alpha);
void copyRectToSurface8bpp(const void *buffer, byte* palette, int srcPitch, int srcWidth, int srcXOffset, int destX, int destY, int width, int height, bool flipX, uint8 alpha);
Common::Rect clipRectToScreen(int destX, int destY, const Common::Rect rect);
};
} // End of namespace Dragons

View file

@ -164,10 +164,30 @@ bool ScriptOpcodes::runScript4(ScriptOpCall &scriptOpCall) {
}
void ScriptOpcodes::executeScriptLoop(ScriptOpCall &scriptOpCall) {
if (scriptOpCall._code >= scriptOpCall._codeEnd || scriptOpCall._result & 1) {
return;
}
//
// if (scriptOpCall._code >= scriptOpCall._codeEnd || scriptOpCall._result & 1) {
// return;
// }
//
// if (_vm->isFlagSet(Dragons::ENGINE_FLAG_100000)) {
// return;
// }
//
// if (_vm->isFlagSet(Dragons::ENGINE_FLAG_80000)) {
// //TODO
//// if (IsPressedStart(0)) {
//// Dragons::getEngine()->setFlags(Dragons::ENGINE_FLAG_100000);
//// }
// }
//
// uint16 opcode = READ_LE_UINT16(scriptOpCall._code) & 0x7fff;
//
// scriptOpCall._op = (byte) opcode;
// if (opcode < DRAGONS_NUM_SCRIPT_OPCODES) {
// execOpcode(scriptOpCall);
// }
//
while (scriptOpCall._code < scriptOpCall._codeEnd && !(scriptOpCall._result & 1)) {
if (_vm->isFlagSet(Dragons::ENGINE_FLAG_100000)) {
return;
@ -182,31 +202,16 @@ void ScriptOpcodes::executeScriptLoop(ScriptOpCall &scriptOpCall) {
uint16 opcode = READ_LE_UINT16(scriptOpCall._code) & 0x7fff;
scriptOpCall._op = (byte) opcode;
if (opcode < DRAGONS_NUM_SCRIPT_OPCODES) {
execOpcode(scriptOpCall);
}
while (scriptOpCall._code < scriptOpCall._codeEnd && !(scriptOpCall._result & 1) && _data_80071f5c == 0) {
if (_vm->isFlagSet(Dragons::ENGINE_FLAG_100000)) {
return;
}
if (_vm->isFlagSet(Dragons::ENGINE_FLAG_80000)) {
//TODO
// if (IsPressedStart(0)) {
// Dragons::getEngine()->setFlags(Dragons::ENGINE_FLAG_100000);
// }
}
opcode = READ_LE_UINT16(scriptOpCall._code) & 0x7fff;
if (opcode >= DRAGONS_NUM_SCRIPT_OPCODES) {
return; //TODO should continue here.
}
scriptOpCall._op = (byte) opcode;
execOpcode(scriptOpCall);
if (_data_80071f5c != 0) {
scriptOpCall._result |= 1;
break;
}
}
}