/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "bbvs/gamemodule.h" #include "engines/util.h" namespace Bbvs { GameModule::GameModule() : _bgSpriteCount(0), _bgSpriteIndices(0), _bgSpritePriorities(0), _walkRectsCount(0), _walkRects(0), _sceneExitsCount(0), _sceneExits(0), _bgObjectsCount(0), _bgObjects(0), _animationsCount(0), _animations(0), _sceneObjectDefsCount(0), _sceneObjectDefs(0), _sceneObjectInitsCount(0), _sceneObjectInits(0), _actionsCount(0), _actions(0), _sceneSoundsCount(0), _sceneSounds(0), _preloadSoundsCount(0), _preloadSounds(0) { } GameModule::~GameModule() { unload(); } void GameModule::load(const char *filename) { debug(0, "GameModule::load()"); unload(); Common::File fd; if (!fd.open(filename)) error("GameModule::load() Could not open %s", filename); loadBgSprites(fd); loadCameraInits(fd); loadWalkRects(fd); loadSceneExits(fd); loadBgObjects(fd); loadAnimations(fd); loadSceneObjectDefs(fd); loadSceneObjectInits(fd); loadActions(fd); loadGuiSpriteIndices(fd); loadInventoryItemSpriteIndices(fd); loadInventoryItemInfos(fd); loadDialogItemSpriteIndices(fd); loadSceneSounds(fd); loadPreloadSounds(fd); fd.seek(0xC); _fieldC = fd.readUint32LE(); fd.seek(0x1A8); _buttheadObjectIndex = fd.readUint32LE(); fd.close(); debug(0, "GameModule::load() OK"); } int GameModule::getFieldC() { return _fieldC; } int GameModule::getButtheadObjectIndex() { return _buttheadObjectIndex; } int GameModule::getGuiSpriteIndex(int index) { assert(index < kGuiSpriteCount); return _guiSpriteIndices[index]; } int GameModule::getInventoryItemSpriteIndex(int index) { assert(index < kInventoryItemSpriteCount); return _inventoryItemSpriteIndices[index]; } int GameModule::getDialogItemSpriteIndex(int index) { assert(index < kDialogItemSpriteCount); return _dialogItemSpriteIndices[index]; } int GameModule::getActionsCount() { return _actionsCount; } Action *GameModule::getAction(int index) { assert(index < _actionsCount); return &_actions[index]; } InventoryItemInfo *GameModule::getInventoryItemInfo(int index) { assert(index < kInventoryItemCount); return &_inventoryItemInfos[index]; } CameraInit *GameModule::getCameraInit(int cameraNum) { assert(cameraNum < kCameraInitsCount); return &_cameraInits[cameraNum]; } int GameModule::getSceneExitsCount() { return _sceneExitsCount; } SceneExit *GameModule::getSceneExit(int index) { assert(index < _sceneExitsCount); return &_sceneExits[index]; } int GameModule::getWalkRectsCount() { return _walkRectsCount; } Common::Rect *GameModule::getWalkRects() { return _walkRects; } int GameModule::getSceneObjectDefsCount() { return _sceneObjectDefsCount; } SceneObjectDef *GameModule::getSceneObjectDef(int index) { assert(index < _sceneObjectDefsCount); return &_sceneObjectDefs[index]; } int GameModule::getSceneObjectInitsCount() { return _sceneObjectInitsCount; } SceneObjectInit *GameModule::getSceneObjectInit(int index) { assert(index < _sceneObjectInitsCount); return &_sceneObjectInits[index]; } int GameModule::getBgObjectsCount() { return _bgObjectsCount; } BgObject *GameModule::getBgObject(int index) { assert(index < _bgObjectsCount); return &_bgObjects[index]; } int GameModule::getBgSpritesCount() { return _bgSpriteCount; } int GameModule::getBgSpriteIndex(int index) { assert(index < _bgSpriteCount); return _bgSpriteIndices[index]; } int GameModule::getBgSpritePriority(int index) { assert(index < _bgSpriteCount); return _bgSpritePriorities[index]; } int GameModule::getSceneSoundsCount() { return _sceneSoundsCount; } SceneSound *GameModule::getSceneSound(int index) { assert(index < _sceneSoundsCount); return &_sceneSounds[index]; } uint GameModule::getSceneSoundIndex(uint soundNum) { for (int i = 0; i < getSceneSoundsCount(); ++i) if (getSceneSound(i)->soundNum == soundNum) return i; return 0; } uint GameModule::getPreloadSoundsCount() { return _preloadSoundsCount; } uint GameModule::getPreloadSound(uint index) { assert(index < _preloadSoundsCount); return _preloadSounds[index]; } Animation *GameModule::getAnimation(int index) { assert(index < _animationsCount); return &_animations[index]; } Common::Point GameModule::readPoint(Common::SeekableReadStream &s) { Common::Point p; p.x = s.readUint16LE(); p.y = s.readUint16LE(); return p; } Common::Rect GameModule::readRect(Common::SeekableReadStream &s) { Common::Rect r; r.left = s.readUint16LE(); r.top = s.readUint16LE(); r.setWidth(s.readUint16LE()); r.setHeight(s.readUint16LE()); return r; } Conditions GameModule::readConditions(Common::SeekableReadStream &s) { Conditions c; for (int i = 0; i < 8; ++i) { c.conditions[i].cond = s.readByte(); c.conditions[i].value1 = s.readByte(); c.conditions[i].value2 = s.readUint16LE(); } return c; } void GameModule::unload() { delete[] _bgSpriteIndices; delete[] _bgSpritePriorities; delete[] _walkRects; delete[] _sceneExits; delete[] _bgObjects; delete[] _animations; delete[] _sceneObjectDefs; delete[] _sceneObjectInits; delete[] _actions; delete[] _sceneSounds; delete[] _preloadSounds; _bgSpriteIndices = 0; _bgSpritePriorities = 0; _walkRects = 0; _sceneExits = 0; _bgObjects = 0; _animations = 0; _sceneObjectDefs = 0; _sceneObjectInits = 0; _actions = 0; _sceneSounds = 0; _preloadSounds = 0; } void GameModule::loadBgSprites(Common::SeekableReadStream &s) { debug(0, "GameModule::loadBgSprites()"); s.seek(0x14); _bgSpriteCount = s.readUint32LE(); uint32 bgSpriteIndicesOffs = s.readUint32LE(); uint32 bgSpritePrioritiesOffs = s.readUint32LE(); _bgSpriteIndices = new int[_bgSpriteCount]; _bgSpritePriorities = new int16[_bgSpriteCount]; s.seek(bgSpriteIndicesOffs); for (int i = 0; i < _bgSpriteCount; ++i) _bgSpriteIndices[i] = s.readUint32LE(); s.seek(bgSpritePrioritiesOffs); for (int i = 0; i < _bgSpriteCount; ++i) _bgSpritePriorities[i] = s.readUint16LE(); } void GameModule::loadCameraInits(Common::SeekableReadStream &s) { debug(0, "GameModule::loadCameraInits()"); s.seek(0x20); for (int i = 0; i < kCameraInitsCount; ++i) { CameraInit &cameraInit = _cameraInits[i]; cameraInit.cameraPos = readPoint(s); for (int j = 0; j < 8; ++j) cameraInit.cameraLinks[j] = s.readByte(); for (int j = 0; j < 8; ++j) cameraInit.rects[j] = readRect(s); } } void GameModule::loadWalkRects(Common::SeekableReadStream &s) { debug(0, "GameModule::loadWalkRects()"); s.seek(0x150); _walkRectsCount = s.readUint32LE(); uint32 offs = s.readUint32LE(); _walkRects = new Common::Rect[_walkRectsCount]; s.seek(offs); for (int i = 0; i < _walkRectsCount; ++i) _walkRects[i] = readRect(s); } void GameModule::loadSceneExits(Common::SeekableReadStream &s) { debug(0, "GameModule::loadSceneExits()"); s.seek(0x158); _sceneExitsCount = s.readUint32LE(); uint32 offs = s.readUint32LE(); _sceneExits = new SceneExit[_sceneExitsCount]; s.seek(offs); for (int i = 0; i < _sceneExitsCount; ++i) { _sceneExits[i].rect = readRect(s); _sceneExits[i].newModuleNum = s.readUint32LE(); } } void GameModule::loadBgObjects(Common::SeekableReadStream &s) { debug(0, "GameModule::loadBgObjects()"); s.seek(0x160); _bgObjectsCount = s.readUint32LE(); uint32 offs = s.readUint32LE(); _bgObjects = new BgObject[_bgObjectsCount]; s.seek(offs); for (int i = 0; i < _bgObjectsCount; ++i) { s.read(_bgObjects[i].name, 20); _bgObjects[i].rect = readRect(s); } } void GameModule::loadAnimations(Common::SeekableReadStream &s) { debug(0, "GameModule::loadAnimations()"); s.seek(0x168); _animationsCount = s.readUint32LE(); uint32 offs = s.readUint32LE(); _animations = new Animation[_animationsCount]; for (int i = 0; i < _animationsCount; ++i) { Animation &anim = _animations[i]; s.seek(offs + i * 20); anim.frameCount = s.readUint32LE(); uint32 frameSpriteIndicesOffs = s.readUint32LE(); uint32 frameTicksOffs = s.readUint32LE(); uint32 frameRects1Offs = s.readUint32LE(); uint32 frameRects2Offs = s.readUint32LE(); anim.frameSpriteIndices = new int[anim.frameCount]; s.seek(frameSpriteIndicesOffs); for (int j = 0; j < anim.frameCount; ++j) anim.frameSpriteIndices[j] = s.readUint32LE(); anim.frameTicks = new int16[anim.frameCount]; s.seek(frameTicksOffs); for (int j = 0; j < anim.frameCount; ++j) anim.frameTicks[j] = s.readUint16LE(); anim.frameRects1 = new Common::Rect[anim.frameCount]; s.seek(frameRects1Offs); for (int j = 0; j < anim.frameCount; ++j) anim.frameRects1[j] = readRect(s); anim.frameRects2 = new Common::Rect[anim.frameCount]; s.seek(frameRects2Offs); for (int j = 0; j < anim.frameCount; ++j) anim.frameRects2[j] = readRect(s); } } void GameModule::loadSceneObjectDefs(Common::SeekableReadStream &s) { debug(0, "GameModule::loadSceneObjectDefs()"); s.seek(0x170); _sceneObjectDefsCount = s.readUint32LE(); uint32 offs = s.readUint32LE(); _sceneObjectDefs = new SceneObjectDef[_sceneObjectDefsCount]; s.seek(offs); for (int i = 0; i < _sceneObjectDefsCount; ++i) { s.read(_sceneObjectDefs[i].name, 20); _sceneObjectDefs[i].walkSpeed = s.readUint32LE(); for (int j = 0; j < 16; ++j) _sceneObjectDefs[i].animIndices[j] = s.readUint32LE(); } } void GameModule::loadSceneObjectInits(Common::SeekableReadStream &s) { debug(0, "GameModule::loadSceneObjectInits()"); s.seek(0x178); _sceneObjectInitsCount = s.readUint32LE(); uint32 offs = s.readUint32LE(); _sceneObjectInits = new SceneObjectInit[_sceneObjectInitsCount]; s.seek(offs); for (int i = 0; i < _sceneObjectInitsCount; ++i) { _sceneObjectInits[i].conditions = readConditions(s); _sceneObjectInits[i].sceneObjectIndex = s.readUint32LE(); _sceneObjectInits[i].animIndex = s.readUint32LE(); _sceneObjectInits[i].x = s.readUint16LE(); _sceneObjectInits[i].y = s.readUint16LE(); } } void GameModule::loadActions(Common::SeekableReadStream &s) { debug(0, "GameModule::loadActions()"); s.seek(0x180); _actionsCount = s.readUint32LE(); uint32 offs = s.readUint32LE(); _actions = new Action[_actionsCount]; for (int i = 0; i < _actionsCount; ++i) { s.seek(offs + i * 72); debug(0, "Action(%d) offs: %08X", i, offs + i * 72); _actions[i].conditions = readConditions(s); for (int j = 0; j < 8; ++j) { _actions[i].results.actionResults[j].kind = s.readByte(); _actions[i].results.actionResults[j].value1 = s.readByte(); _actions[i].results.actionResults[j].value2 = s.readUint16LE(); } const int actionListCount = s.readUint32LE(); const uint32 actionListOffs = s.readUint32LE(); s.seek(actionListOffs); for (int j = 0; j < actionListCount; ++j) { ActionCommand actionCommand; actionCommand.cmd = s.readUint16LE(); actionCommand.sceneObjectIndex = s.readUint16LE(); actionCommand.timeStamp = s.readUint32LE(); actionCommand.walkDest = readPoint(s); actionCommand.param = s.readUint32LE(); _actions[i].actionCommands.push_back(actionCommand); } } } void GameModule::loadGuiSpriteIndices(Common::SeekableReadStream &s) { debug(0, "GameModule::loadGuiSpriteIndices()"); s.seek(0x188); uint32 offs = s.readUint32LE(); s.seek(offs); for (int i = 0; i < kGuiSpriteCount; ++i) _guiSpriteIndices[i] = s.readUint32LE(); } void GameModule::loadInventoryItemSpriteIndices(Common::SeekableReadStream &s) { debug(0, "GameModule::loadInventoryItemSpriteIndices()"); s.seek(0x18C); uint32 offs = s.readUint32LE(); s.seek(offs); for (int i = 0; i < kInventoryItemSpriteCount; ++i) _inventoryItemSpriteIndices[i] = s.readUint32LE(); } void GameModule::loadInventoryItemInfos(Common::SeekableReadStream &s) { debug(0, "GameModule::loadInventoryItemInfos()"); s.seek(0x190); uint32 offs = s.readUint32LE(); s.seek(offs); for (int i = 0; i < kInventoryItemCount; ++i) { _inventoryItemInfos[i].xOffs = s.readUint16LE(); _inventoryItemInfos[i].yOffs = s.readUint16LE(); _inventoryItemInfos[i].width = s.readUint16LE(); _inventoryItemInfos[i].height = s.readUint16LE(); s.skip(8); // Unused } } void GameModule::loadDialogItemSpriteIndices(Common::SeekableReadStream &s) { debug(0, "GameModule::loadDialogItemSpriteIndices()"); s.seek(0x194); uint32 offs = s.readUint32LE(); s.seek(offs); for (int i = 0; i < kDialogItemSpriteCount; ++i) { _dialogItemSpriteIndices[i] = s.readUint32LE(); } } void GameModule::loadSceneSounds(Common::SeekableReadStream &s) { debug(0, "GameModule::loadSceneSounds()"); s.seek(0x1A0); _sceneSoundsCount = s.readUint32LE(); uint32 offs = s.readUint32LE(); _sceneSounds = new SceneSound[_sceneSoundsCount]; s.seek(offs); for (int i = 0; i < _sceneSoundsCount; ++i) { _sceneSounds[i].conditions = readConditions(s); _sceneSounds[i].soundNum = s.readUint32LE(); } } void GameModule::loadPreloadSounds(Common::SeekableReadStream &s) { debug(0, "GameModule::loadPreloadSounds()"); s.seek(0x198); _preloadSoundsCount = s.readUint32LE(); uint32 offs = s.readUint32LE(); _preloadSounds = new uint[_preloadSoundsCount]; s.seek(offs); for (uint i = 0; i < _preloadSoundsCount; ++i) _preloadSounds[i] = s.readUint32LE(); } } // End of namespace Bbvs