From f3ea11f402102f88750e98dd5b55779695ff832f Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sun, 8 Jan 2017 20:09:51 +0200 Subject: CHEWY: Initial implementation of scene sprites, props and hotspots --- engines/chewy/scene.cpp | 150 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) (limited to 'engines/chewy/scene.cpp') diff --git a/engines/chewy/scene.cpp b/engines/chewy/scene.cpp index 03e4332f85..c6c12fc3ff 100644 --- a/engines/chewy/scene.cpp +++ b/engines/chewy/scene.cpp @@ -35,10 +35,53 @@ namespace Chewy { +#define MAX_DETAILS 32 +#define MAX_HOTSPOTS 50 + +// Animated details - scene animations +struct AnimatedDetails { + uint16 x; + uint16 y; + // 66 bytes animated details - TODO +}; + +// Static details - scene sprites and props +struct StaticDetails { + int16 x; + int16 y; + int16 spriteNum; + uint16 z; + byte hide; + // 1 byte dummy +}; + +struct SceneInfo { + uint16 staticDetailsCount; + uint16 animatedDetailsCount; + uint32 spritePtr; + AnimatedDetails animatedDetails[MAX_DETAILS]; + StaticDetails staticDetails[MAX_DETAILS]; + Common::Rect hotspot[MAX_HOTSPOTS]; + uint16 hotspotDescRes[MAX_HOTSPOTS]; + Common::String hotspotDesc[MAX_HOTSPOTS]; + byte roomNum; + byte picNum; + byte autoMoveCount; + byte loadTaf; + Common::String tafName; // 14 bytes + byte zoomFactor; + // 1 byte dummy + // 6 * 20 = 120 bytes automove coordinates - TODO + // MAX_DETAILS * 3 * 2 = 192 bytes voc - TODO + // MAX_DETAILS * 3 = 96 bytes samples - TODO +}; + Scene::Scene(ChewyEngine *vm) : _vm(vm) { + _sceneInfo = new SceneInfo(); } Scene::~Scene() { + delete _sceneInfo; } void Scene::change(uint scene) { @@ -46,14 +89,121 @@ void Scene::change(uint scene) { _vm->_cursor->setCursor(0); _vm->_cursor->showCursor(); + loadSceneInfo(); draw(); } void Scene::draw() { + // Background _vm->_graphics->drawImage("episode1.tgp", _curScene); + + // Static details + for (uint16 i = 0; i < MAX_HOTSPOTS; i++) { + StaticDetails s = _sceneInfo->staticDetails[i]; + if (s.spriteNum >= 0 && s.x >= 0 && s.y >= 0 && !s.hide) + _vm->_graphics->drawSprite(Common::String::format("det%d.taf", _curScene), s.spriteNum, s.x, s.y); + } + + // TODO: These are all hardcoded for now _vm->_graphics->drawSprite("det1.taf", 0, 200, 100); _vm->_graphics->loadFont("6x8.tff"); _vm->_graphics->drawText("This is a test", 200, 80); } +void Scene::updateMouse(Common::Point coords) { + // Animated details + // TODO: handle these + + // Static details + for (uint16 i = 0; i < MAX_HOTSPOTS; i++) { + if (_sceneInfo->hotspot[i].contains(coords)) { + // TODO: Draw hotspot description on screen + debug("Coords %d, %d: '%s'", coords.x, coords.y, _sceneInfo->hotspotDesc[i].c_str()); + break; + } + } +} + +void Scene::loadSceneInfo() { + const uint32 sceneInfoSize = 3784; + const uint32 headerRDI = MKTAG('R', 'D', 'I', '\0'); + const char *sceneIndexFileName = "test.rdi"; + Common::File indexFile; + if (!Common::File::exists(sceneIndexFileName)) + error("File %s not found", sceneIndexFileName); + Text *text = new Text(); + + indexFile.open(sceneIndexFileName); + + uint32 header = indexFile.readUint32BE(); + if (header != headerRDI) + error("Invalid resource - %s", sceneIndexFileName); + + indexFile.seek(sceneInfoSize * _curScene, SEEK_CUR); + + // TODO: These can be set to larger numbers than MAX_DETAILS + _sceneInfo->staticDetailsCount = indexFile.readUint16LE(); + _sceneInfo->animatedDetailsCount = indexFile.readUint16LE(); + indexFile.skip(6); + + // Animated details + for (int i = 0; i < MAX_DETAILS; i++) { + _sceneInfo->animatedDetails[i].x = indexFile.readUint16LE(); + _sceneInfo->animatedDetails[i].y = indexFile.readUint16LE(); + indexFile.skip(66); // animated details info - TODO: read these + } + + // Static details + for (int i = 0; i < MAX_DETAILS; i++) { + _sceneInfo->staticDetails[i].x = indexFile.readSint16LE(); + _sceneInfo->staticDetails[i].y = indexFile.readSint16LE(); + _sceneInfo->staticDetails[i].spriteNum = indexFile.readSint16LE(); + _sceneInfo->staticDetails[i].z = indexFile.readUint16LE(); + _sceneInfo->staticDetails[i].hide = indexFile.readByte(); + indexFile.readByte(); // padding + } + + // Hotspots + for (int i = 0; i < MAX_HOTSPOTS; i++) { + _sceneInfo->hotspot[i].left = indexFile.readUint16LE(); + _sceneInfo->hotspot[i].top = indexFile.readUint16LE(); + _sceneInfo->hotspot[i].right = indexFile.readUint16LE(); + _sceneInfo->hotspot[i].bottom = indexFile.readUint16LE(); + if (!_sceneInfo->hotspot[i].isValidRect()) + warning("Hotspot %d has an invalid rect", i); + } + + // Hotspot descriptions + for (int i = 0; i < MAX_HOTSPOTS; i++) { + _sceneInfo->hotspotDescRes[i] = indexFile.readUint16LE(); + + if (_sceneInfo->hotspotDescRes[i] < kATSTextMax) { + // TODO: Hotspot description IDs are off... investigate why + _sceneInfo->hotspotDesc[i] = text->getText(_curScene + kADSTextMax, _sceneInfo->hotspotDescRes[i])->text; + } else { + // TODO: Handle these types of hotspot descriptions + warning("Hotspot %d has an invalid description resource (%d)", i, _sceneInfo->hotspotDescRes[i]); + _sceneInfo->hotspotDesc[i] = Common::String::format("Hotspot %d", _sceneInfo->hotspotDescRes[i]); + } + } + + _sceneInfo->roomNum = indexFile.readByte(); + _sceneInfo->picNum = indexFile.readByte(); + _sceneInfo->autoMoveCount = indexFile.readByte(); + _sceneInfo->loadTaf = indexFile.readByte(); + + for (int i = 0; i < 14; i++) + _sceneInfo->tafName += indexFile.readByte(); + + _sceneInfo->zoomFactor = indexFile.readByte(); + indexFile.readByte(); // padding + + // 6 * 20 = 120 bytes automove coordinates - TODO: read these + // MAX_DETAILS * 3 * 2 = 192 bytes voc - TODO: read these + // MAX_DETAILS * 3 = 96 bytes samples - TODO: read these + + delete text; + indexFile.close(); +} + } // End of namespace Chewy -- cgit v1.2.3