2009-06-26 23:34:06 +00:00
|
|
|
/* 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.
|
|
|
|
*
|
|
|
|
* $URL$
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2009-06-27 01:04:24 +00:00
|
|
|
#include "common/stream.h"
|
|
|
|
|
|
|
|
#include "draci/draci.h"
|
2009-06-26 23:34:06 +00:00
|
|
|
#include "draci/game.h"
|
2009-06-27 01:04:24 +00:00
|
|
|
#include "draci/barchive.h"
|
2009-06-28 16:19:10 +00:00
|
|
|
#include "draci/script.h"
|
2009-07-03 17:54:13 +00:00
|
|
|
#include "draci/animation.h"
|
2009-06-27 01:04:24 +00:00
|
|
|
|
|
|
|
namespace Draci {
|
|
|
|
|
2009-06-28 16:19:10 +00:00
|
|
|
Game::Game(DraciEngine *vm) : _vm(vm) {
|
2009-06-27 05:10:24 +00:00
|
|
|
unsigned int i;
|
2009-06-27 01:04:24 +00:00
|
|
|
Common::String path("INIT.DFW");
|
|
|
|
|
|
|
|
BArchive initArchive(path);
|
|
|
|
BAFile *file;
|
|
|
|
|
2009-06-27 05:10:24 +00:00
|
|
|
// Read in persons
|
|
|
|
|
2009-07-02 16:15:32 +00:00
|
|
|
file = initArchive.getFile(5);
|
2009-06-27 05:10:24 +00:00
|
|
|
Common::MemoryReadStream personData(file->_data, file->_length);
|
2009-06-27 01:04:24 +00:00
|
|
|
|
|
|
|
unsigned int numPersons = file->_length / personSize;
|
|
|
|
_persons = new Person[numPersons];
|
|
|
|
|
2009-06-27 05:10:24 +00:00
|
|
|
for (i = 0; i < numPersons; ++i) {
|
|
|
|
_persons[i]._x = personData.readByte();
|
|
|
|
_persons[i]._y = personData.readByte();
|
|
|
|
_persons[i]._fontColour = personData.readUint16LE();
|
|
|
|
}
|
2009-07-17 01:20:51 +00:00
|
|
|
|
|
|
|
// Close persons file
|
|
|
|
file->close();
|
2009-06-27 05:10:24 +00:00
|
|
|
|
|
|
|
// Read in dialog offsets
|
|
|
|
|
2009-07-02 16:15:32 +00:00
|
|
|
file = initArchive.getFile(4);
|
2009-06-27 05:10:24 +00:00
|
|
|
Common::MemoryReadStream dialogData(file->_data, file->_length);
|
|
|
|
|
|
|
|
unsigned int numDialogs = file->_length / sizeof(uint16);
|
2009-07-17 01:20:51 +00:00
|
|
|
_dialogOffsets = new uint[numDialogs];
|
2009-06-27 05:10:24 +00:00
|
|
|
|
|
|
|
unsigned int curOffset;
|
|
|
|
for (i = 0, curOffset = 0; i < numDialogs; ++i) {
|
|
|
|
_dialogOffsets[i] = curOffset;
|
|
|
|
curOffset += dialogData.readUint16LE();
|
2009-06-27 01:04:24 +00:00
|
|
|
}
|
2009-06-27 05:10:24 +00:00
|
|
|
|
2009-07-17 01:20:51 +00:00
|
|
|
// Close dialogs file
|
|
|
|
file->close();
|
|
|
|
|
2009-06-27 05:10:24 +00:00
|
|
|
// Read in game info
|
|
|
|
|
2009-07-02 16:15:32 +00:00
|
|
|
file = initArchive.getFile(3);
|
2009-06-27 05:10:24 +00:00
|
|
|
Common::MemoryReadStream gameData(file->_data, file->_length);
|
|
|
|
|
2009-07-14 00:51:35 +00:00
|
|
|
_info._startRoom = gameData.readByte() - 1;
|
2009-07-14 00:41:17 +00:00
|
|
|
_info._mapRoom = gameData.readByte() - 1;
|
|
|
|
_info._numObjects = gameData.readUint16LE();
|
|
|
|
_info._numIcons = gameData.readUint16LE();
|
|
|
|
_info._numVariables = gameData.readByte();
|
|
|
|
_info._numPersons = gameData.readByte();
|
|
|
|
_info._numDialogs = gameData.readByte();
|
|
|
|
_info._maxIconWidth = gameData.readUint16LE();
|
|
|
|
_info._maxIconHeight = gameData.readUint16LE();
|
|
|
|
_info._musicLength = gameData.readUint16LE();
|
|
|
|
_info._crc[0] = gameData.readUint16LE();
|
|
|
|
_info._crc[1] = gameData.readUint16LE();
|
|
|
|
_info._crc[2] = gameData.readUint16LE();
|
|
|
|
_info._crc[3] = gameData.readUint16LE();
|
|
|
|
|
|
|
|
_info._numDialogBlocks = curOffset;
|
2009-06-27 05:10:24 +00:00
|
|
|
|
2009-07-17 01:20:51 +00:00
|
|
|
// Close game info file
|
|
|
|
file->close();
|
|
|
|
|
2009-06-27 05:10:24 +00:00
|
|
|
// Read in variables
|
|
|
|
|
2009-07-02 16:15:32 +00:00
|
|
|
file = initArchive.getFile(2);
|
2009-06-27 05:10:24 +00:00
|
|
|
unsigned int numVariables = file->_length / sizeof (int16);
|
2009-06-29 22:20:30 +00:00
|
|
|
|
2009-07-07 20:57:14 +00:00
|
|
|
_variables = new int[numVariables];
|
2009-06-29 22:20:30 +00:00
|
|
|
Common::MemoryReadStream variableData(file->_data, file->_length);
|
2009-06-27 05:10:24 +00:00
|
|
|
|
2009-06-29 22:20:30 +00:00
|
|
|
for (i = 0; i < numVariables; ++i) {
|
|
|
|
_variables[i] = variableData.readUint16LE();
|
|
|
|
}
|
|
|
|
|
2009-07-17 01:20:51 +00:00
|
|
|
// Close variables file
|
|
|
|
file->close();
|
|
|
|
|
2009-07-13 19:24:22 +00:00
|
|
|
// Read in item icon status
|
2009-06-27 05:10:24 +00:00
|
|
|
|
2009-07-02 16:15:32 +00:00
|
|
|
file = initArchive.getFile(1);
|
2009-07-17 01:20:51 +00:00
|
|
|
_iconStatus = file->_data;
|
2009-07-13 19:24:22 +00:00
|
|
|
uint numIcons = file->_length;
|
2009-06-27 05:10:24 +00:00
|
|
|
|
|
|
|
// Read in object status
|
|
|
|
|
2009-07-02 16:15:32 +00:00
|
|
|
file = initArchive.getFile(0);
|
2009-06-27 05:10:24 +00:00
|
|
|
unsigned int numObjects = file->_length;
|
|
|
|
|
2009-07-02 15:08:42 +00:00
|
|
|
_objects = new GameObject[numObjects];
|
|
|
|
Common::MemoryReadStream objStatus(file->_data, file->_length);
|
2009-06-27 05:10:24 +00:00
|
|
|
|
2009-07-02 15:08:42 +00:00
|
|
|
for (i = 0; i < numObjects; ++i) {
|
|
|
|
byte tmp = objStatus.readByte();
|
|
|
|
|
|
|
|
// Set object visibility
|
2009-07-06 19:50:59 +00:00
|
|
|
_objects[i]._visible = tmp & (1 << 7);
|
2009-07-02 15:08:42 +00:00
|
|
|
|
|
|
|
// Set object location
|
2009-07-06 19:50:59 +00:00
|
|
|
_objects[i]._location = (~(1 << 7) & tmp) - 1;
|
2009-07-02 15:08:42 +00:00
|
|
|
}
|
2009-07-17 01:20:51 +00:00
|
|
|
|
|
|
|
// Close object status file
|
|
|
|
file->close();
|
2009-07-02 15:08:42 +00:00
|
|
|
|
2009-07-14 00:41:17 +00:00
|
|
|
assert(numDialogs == _info._numDialogs);
|
|
|
|
assert(numPersons == _info._numPersons);
|
|
|
|
assert(numVariables == _info._numVariables);
|
|
|
|
assert(numObjects == _info._numObjects);
|
|
|
|
assert(numIcons == _info._numIcons);
|
2009-07-04 18:35:08 +00:00
|
|
|
}
|
2009-06-27 05:10:24 +00:00
|
|
|
|
2009-07-04 18:35:08 +00:00
|
|
|
void Game::init() {
|
2009-07-07 19:50:12 +00:00
|
|
|
loadObject(kDragonObject);
|
2009-07-04 15:21:12 +00:00
|
|
|
|
2009-07-07 19:53:40 +00:00
|
|
|
GameObject *dragon = getObject(kDragonObject);
|
2009-07-15 19:06:24 +00:00
|
|
|
debugC(4, kDraciLogicDebugLevel, "Running init program for the dragon object...");
|
2009-07-07 19:53:40 +00:00
|
|
|
_vm->_script->run(dragon->_program, dragon->_init);
|
2009-07-04 23:05:13 +00:00
|
|
|
|
2009-07-18 03:00:12 +00:00
|
|
|
_currentRoom._roomNum = _info._startRoom;
|
2009-07-15 19:06:24 +00:00
|
|
|
changeRoom(_info._startRoom);
|
2009-07-16 12:07:41 +00:00
|
|
|
|
|
|
|
_vm->_mouse->setCursorType(kNormalCursor);
|
2009-06-27 01:04:24 +00:00
|
|
|
}
|
|
|
|
|
2009-07-17 00:20:57 +00:00
|
|
|
void Game::loop() {
|
|
|
|
|
|
|
|
if (_currentRoom._mouseOn) {
|
|
|
|
int x = _vm->_mouse->getPosX();
|
|
|
|
int y = _vm->_mouse->getPosY();
|
2009-07-18 03:00:12 +00:00
|
|
|
|
2009-07-17 00:20:57 +00:00
|
|
|
if (_vm->_mouse->lButtonPressed() && _currentRoom._walkingMap.isWalkable(x, y)) {
|
2009-07-18 03:00:12 +00:00
|
|
|
|
|
|
|
int animID = getObject(kDragonObject)->_anims[0];
|
|
|
|
|
|
|
|
Animation *anim = _vm->_anims->getAnimation(animID);
|
|
|
|
Drawable *frame = anim->getFrame();
|
|
|
|
y -= frame->getHeight();
|
|
|
|
|
|
|
|
// HACK: Z needs to be handled according to Y position
|
|
|
|
anim->setZ(256);
|
|
|
|
|
|
|
|
anim->setRelative(x, y);
|
|
|
|
|
|
|
|
_vm->_anims->play(animID);
|
|
|
|
|
2009-07-17 00:20:57 +00:00
|
|
|
debugC(4, kDraciLogicDebugLevel, "Walk to x: %d y: %d", x, y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-07-13 19:53:53 +00:00
|
|
|
void Game::loadRoom(int roomNum) {
|
2009-07-04 15:21:12 +00:00
|
|
|
|
|
|
|
BAFile *f;
|
|
|
|
f = _vm->_roomsArchive->getFile(roomNum * 4);
|
|
|
|
Common::MemoryReadStream roomReader(f->_data, f->_length);
|
|
|
|
|
|
|
|
roomReader.readUint32LE(); // Pointer to room program, not used
|
|
|
|
roomReader.readUint16LE(); // Program length, not used
|
|
|
|
roomReader.readUint32LE(); // Pointer to room title, not used
|
|
|
|
|
|
|
|
_currentRoom._music = roomReader.readByte();
|
2009-07-16 18:31:15 +00:00
|
|
|
|
|
|
|
int mapIdx = roomReader.readByte() - 1;
|
|
|
|
f = _vm->_walkingMapsArchive->getFile(mapIdx);
|
|
|
|
_currentRoom._walkingMap.load(f->_data, f->_length);
|
|
|
|
|
2009-07-04 15:21:12 +00:00
|
|
|
_currentRoom._palette = roomReader.readByte() - 1;
|
2009-07-17 00:27:21 +00:00
|
|
|
_currentRoom._numOverlays = roomReader.readSint16LE();
|
2009-07-15 19:06:24 +00:00
|
|
|
_currentRoom._init = roomReader.readSint16LE();
|
|
|
|
_currentRoom._look = roomReader.readSint16LE();
|
|
|
|
_currentRoom._use = roomReader.readSint16LE();
|
|
|
|
_currentRoom._canUse = roomReader.readSint16LE();
|
2009-07-04 15:21:12 +00:00
|
|
|
_currentRoom._imInit = roomReader.readByte();
|
|
|
|
_currentRoom._imLook = roomReader.readByte();
|
|
|
|
_currentRoom._imUse = roomReader.readByte();
|
|
|
|
_currentRoom._mouseOn = roomReader.readByte();
|
|
|
|
_currentRoom._heroOn = roomReader.readByte();
|
2009-07-15 19:06:24 +00:00
|
|
|
roomReader.read(&_currentRoom._pers0, 6);
|
|
|
|
roomReader.read(&_currentRoom._persStep, 6);
|
2009-07-04 15:21:12 +00:00
|
|
|
_currentRoom._escRoom = roomReader.readByte() - 1;
|
|
|
|
_currentRoom._numGates = roomReader.readByte();
|
|
|
|
|
2009-07-16 18:31:15 +00:00
|
|
|
debugC(4, kDraciLogicDebugLevel, "Music: %d", _currentRoom._music);
|
|
|
|
debugC(4, kDraciLogicDebugLevel, "Map: %d", mapIdx);
|
|
|
|
debugC(4, kDraciLogicDebugLevel, "Palette: %d", _currentRoom._palette);
|
2009-07-17 00:27:21 +00:00
|
|
|
debugC(4, kDraciLogicDebugLevel, "Overlays: %d", _currentRoom._numOverlays);
|
2009-07-16 18:31:15 +00:00
|
|
|
debugC(4, kDraciLogicDebugLevel, "Init: %d", _currentRoom._init);
|
|
|
|
debugC(4, kDraciLogicDebugLevel, "Look: %d", _currentRoom._look);
|
|
|
|
debugC(4, kDraciLogicDebugLevel, "Use: %d", _currentRoom._use);
|
|
|
|
debugC(4, kDraciLogicDebugLevel, "CanUse: %d", _currentRoom._canUse);
|
|
|
|
debugC(4, kDraciLogicDebugLevel, "ImInit: %d", _currentRoom._imInit);
|
|
|
|
debugC(4, kDraciLogicDebugLevel, "ImLook: %d", _currentRoom._imLook);
|
|
|
|
debugC(4, kDraciLogicDebugLevel, "ImUse: %d", _currentRoom._imUse);
|
|
|
|
debugC(4, kDraciLogicDebugLevel, "MouseOn: %d", _currentRoom._mouseOn);
|
|
|
|
debugC(4, kDraciLogicDebugLevel, "HeroOn: %d", _currentRoom._heroOn);
|
|
|
|
debugC(4, kDraciLogicDebugLevel, "Pers0: %f", _currentRoom._pers0);
|
|
|
|
debugC(4, kDraciLogicDebugLevel, "PersStep: %f", _currentRoom._persStep);
|
|
|
|
debugC(4, kDraciLogicDebugLevel, "EscRoom: %d", _currentRoom._escRoom);
|
|
|
|
debugC(4, kDraciLogicDebugLevel, "Gates: %d", _currentRoom._numGates);
|
2009-07-15 19:06:24 +00:00
|
|
|
|
2009-07-16 12:07:41 +00:00
|
|
|
// Set cursor state
|
|
|
|
if (_currentRoom._mouseOn) {
|
|
|
|
debugC(6, kDraciLogicDebugLevel, "Mouse: ON");
|
|
|
|
_vm->_mouse->cursorOn();
|
|
|
|
} else {
|
|
|
|
debugC(6, kDraciLogicDebugLevel, "Mouse: OFF");
|
|
|
|
_vm->_mouse->cursorOff();
|
|
|
|
}
|
|
|
|
|
2009-07-15 19:06:24 +00:00
|
|
|
Common::Array<int> gates;
|
|
|
|
|
|
|
|
for (uint i = 0; i < _currentRoom._numGates; ++i) {
|
|
|
|
gates.push_back(roomReader.readSint16LE());
|
|
|
|
}
|
|
|
|
|
2009-07-14 00:41:17 +00:00
|
|
|
for (uint i = 0; i < _info._numObjects; ++i) {
|
2009-07-15 19:06:24 +00:00
|
|
|
debugC(7, kDraciLogicDebugLevel,
|
2009-07-06 19:50:59 +00:00
|
|
|
"Checking if object %d (%d) is at the current location (%d)", i,
|
|
|
|
_objects[i]._location, roomNum);
|
|
|
|
|
|
|
|
if (_objects[i]._location == roomNum) {
|
2009-07-15 19:06:24 +00:00
|
|
|
debugC(6, kDraciLogicDebugLevel, "Loading object %d from room %d", i, roomNum);
|
2009-07-06 19:50:59 +00:00
|
|
|
loadObject(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-07-07 15:31:13 +00:00
|
|
|
// Run the init scripts for room objects
|
2009-07-06 19:50:59 +00:00
|
|
|
// We can't do this in the above loop because some objects' scripts reference
|
|
|
|
// other objects that may not yet be loaded
|
2009-07-14 00:41:17 +00:00
|
|
|
for (uint i = 0; i < _info._numObjects; ++i) {
|
2009-07-06 19:50:59 +00:00
|
|
|
if (_objects[i]._location == roomNum) {
|
2009-07-15 19:06:24 +00:00
|
|
|
debugC(6, kDraciLogicDebugLevel,
|
|
|
|
"Running init program for object %d (offset %d)", i, getObject(i)->_init);
|
2009-07-06 19:50:59 +00:00
|
|
|
_vm->_script->run(getObject(i)->_program, getObject(i)->_init);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
f = _vm->_roomsArchive->getFile(roomNum * 4 + 3);
|
2009-07-17 01:20:51 +00:00
|
|
|
_currentRoom._program._bytecode = f->_data;
|
2009-07-06 19:50:59 +00:00
|
|
|
_currentRoom._program._length = f->_length;
|
|
|
|
|
2009-07-15 19:06:24 +00:00
|
|
|
debugC(4, kDraciLogicDebugLevel, "Running room init program...");
|
2009-07-06 19:50:59 +00:00
|
|
|
_vm->_script->run(_currentRoom._program, _currentRoom._init);
|
|
|
|
|
2009-07-16 12:07:41 +00:00
|
|
|
// HACK: Gates' scripts shouldn't be run unconditionally
|
|
|
|
// This is for testing
|
2009-07-15 19:06:24 +00:00
|
|
|
for (uint i = 0; i < _currentRoom._numGates; ++i) {
|
|
|
|
debugC(6, kDraciLogicDebugLevel, "Running program for gate %d", i);
|
|
|
|
_vm->_script->run(_currentRoom._program, gates[i]);
|
|
|
|
}
|
|
|
|
|
2009-07-04 15:21:12 +00:00
|
|
|
f = _vm->_paletteArchive->getFile(_currentRoom._palette);
|
|
|
|
_vm->_screen->setPalette(f->_data, 0, kNumColours);
|
2009-07-18 03:00:12 +00:00
|
|
|
|
|
|
|
// HACK: Create a visible overlay from the walking map so we can test it
|
|
|
|
byte *wlk = new byte[kScreenWidth * kScreenHeight];
|
|
|
|
memset(wlk, 255, kScreenWidth * kScreenHeight);
|
|
|
|
|
|
|
|
for (uint i = 0; i < kScreenWidth; ++i) {
|
|
|
|
for (uint j = 0; j < kScreenHeight; ++j) {
|
|
|
|
if (_currentRoom._walkingMap.isWalkable(i, j)) {
|
|
|
|
wlk[j * kScreenWidth + i] = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Sprite *ov = new Sprite(wlk, kScreenWidth, kScreenHeight, 0, 0, false);
|
|
|
|
|
|
|
|
Animation *map = _vm->_anims->addAnimation(-2, 255, false);
|
|
|
|
map->addFrame(ov);
|
2009-07-04 15:21:12 +00:00
|
|
|
}
|
|
|
|
|
2009-07-07 21:18:28 +00:00
|
|
|
int Game::loadAnimation(uint animNum, uint z) {
|
2009-07-04 15:21:12 +00:00
|
|
|
|
|
|
|
BAFile *animFile = _vm->_animationsArchive->getFile(animNum);
|
|
|
|
Common::MemoryReadStream animationReader(animFile->_data, animFile->_length);
|
|
|
|
|
2009-07-13 19:53:53 +00:00
|
|
|
uint numFrames = animationReader.readByte();
|
2009-07-04 15:21:12 +00:00
|
|
|
|
|
|
|
// FIXME: handle these properly
|
|
|
|
animationReader.readByte(); // Memory logic field, not used
|
|
|
|
animationReader.readByte(); // Disable erasing field, not used
|
2009-07-07 21:30:36 +00:00
|
|
|
|
|
|
|
bool cyclic = animationReader.readByte();
|
|
|
|
|
2009-07-04 15:21:12 +00:00
|
|
|
animationReader.readByte(); // Relative field, not used
|
|
|
|
|
2009-07-07 21:18:28 +00:00
|
|
|
Animation *anim = _vm->_anims->addAnimation(animNum, z, false);
|
2009-07-12 19:32:01 +00:00
|
|
|
|
|
|
|
anim->setLooping(cyclic);
|
|
|
|
|
2009-07-04 15:21:12 +00:00
|
|
|
for (uint i = 0; i < numFrames; ++i) {
|
|
|
|
uint spriteNum = animationReader.readUint16LE() - 1;
|
|
|
|
int x = animationReader.readSint16LE();
|
|
|
|
int y = animationReader.readSint16LE();
|
|
|
|
uint zoomX = animationReader.readUint16LE();
|
|
|
|
uint zoomY = animationReader.readUint16LE();
|
|
|
|
byte mirror = animationReader.readByte();
|
|
|
|
uint sample = animationReader.readUint16LE();
|
|
|
|
uint freq = animationReader.readUint16LE();
|
|
|
|
uint delay = animationReader.readUint16LE();
|
|
|
|
|
|
|
|
BAFile *spriteFile = _vm->_spritesArchive->getFile(spriteNum);
|
|
|
|
|
2009-07-04 18:35:08 +00:00
|
|
|
Sprite *sp = new Sprite(spriteFile->_data, spriteFile->_length, x, y, true);
|
2009-07-04 15:21:12 +00:00
|
|
|
|
|
|
|
if (mirror)
|
|
|
|
sp->setMirrorOn();
|
|
|
|
|
2009-07-12 19:32:01 +00:00
|
|
|
sp->setDelay(delay * 10);
|
2009-07-05 03:24:46 +00:00
|
|
|
|
2009-07-05 11:52:17 +00:00
|
|
|
anim->addFrame(sp);
|
2009-07-04 15:21:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return animNum;
|
|
|
|
}
|
2009-07-02 16:15:32 +00:00
|
|
|
|
2009-07-04 15:21:12 +00:00
|
|
|
void Game::loadObject(uint objNum) {
|
|
|
|
BAFile *file;
|
|
|
|
|
2009-07-02 16:15:32 +00:00
|
|
|
file = _vm->_objectsArchive->getFile(objNum * 3);
|
2009-06-28 13:10:53 +00:00
|
|
|
Common::MemoryReadStream objReader(file->_data, file->_length);
|
|
|
|
|
2009-07-02 16:15:32 +00:00
|
|
|
GameObject *obj = _objects + objNum;
|
2009-07-02 15:08:42 +00:00
|
|
|
|
2009-06-28 13:10:53 +00:00
|
|
|
obj->_init = objReader.readUint16LE();
|
|
|
|
obj->_look = objReader.readUint16LE();
|
|
|
|
obj->_use = objReader.readUint16LE();
|
|
|
|
obj->_canUse = objReader.readUint16LE();
|
|
|
|
obj->_imInit = objReader.readByte();
|
|
|
|
obj->_imLook = objReader.readByte();
|
|
|
|
obj->_imUse = objReader.readByte();
|
|
|
|
obj->_walkDir = objReader.readByte();
|
2009-07-16 18:39:39 +00:00
|
|
|
obj->_z = objReader.readByte();
|
2009-07-07 21:18:28 +00:00
|
|
|
objReader.readUint16LE(); // idxSeq field, not used
|
|
|
|
objReader.readUint16LE(); // numSeq field, not used
|
2009-06-28 13:10:53 +00:00
|
|
|
obj->_lookX = objReader.readUint16LE();
|
|
|
|
obj->_lookY = objReader.readUint16LE();
|
|
|
|
obj->_useX = objReader.readUint16LE();
|
|
|
|
obj->_useY = objReader.readUint16LE();
|
|
|
|
obj->_lookDir = objReader.readByte();
|
|
|
|
obj->_useDir = objReader.readByte();
|
|
|
|
|
|
|
|
obj->_absNum = objNum;
|
|
|
|
|
2009-07-02 16:15:32 +00:00
|
|
|
file = _vm->_objectsArchive->getFile(objNum * 3 + 1);
|
2009-07-17 01:20:51 +00:00
|
|
|
obj->_title = file->_data;
|
2009-06-28 13:10:53 +00:00
|
|
|
|
2009-07-02 16:15:32 +00:00
|
|
|
file = _vm->_objectsArchive->getFile(objNum * 3 + 2);
|
2009-07-17 01:20:51 +00:00
|
|
|
obj->_program._bytecode = file->_data;
|
2009-06-28 16:19:10 +00:00
|
|
|
obj->_program._length = file->_length;
|
2009-06-28 13:10:53 +00:00
|
|
|
}
|
2009-07-02 15:08:42 +00:00
|
|
|
|
2009-07-04 15:21:12 +00:00
|
|
|
GameObject *Game::getObject(uint objNum) {
|
2009-07-02 16:15:32 +00:00
|
|
|
return _objects + objNum;
|
2009-07-02 15:08:42 +00:00
|
|
|
}
|
|
|
|
|
2009-07-04 15:21:12 +00:00
|
|
|
void Game::loadOverlays() {
|
|
|
|
uint x, y, z, num;
|
|
|
|
|
|
|
|
BAFile *overlayHeader;
|
|
|
|
|
|
|
|
overlayHeader = _vm->_roomsArchive->getFile(_currentRoom._roomNum * 4 + 2);
|
|
|
|
Common::MemoryReadStream overlayReader(overlayHeader->_data, overlayHeader->_length);
|
|
|
|
BAFile *overlayFile;
|
|
|
|
|
2009-07-17 00:27:21 +00:00
|
|
|
for (int i = 0; i < _currentRoom._numOverlays; i++) {
|
2009-07-04 15:21:12 +00:00
|
|
|
|
|
|
|
num = overlayReader.readUint16LE() - 1;
|
|
|
|
x = overlayReader.readUint16LE();
|
|
|
|
y = overlayReader.readUint16LE();
|
|
|
|
z = overlayReader.readByte();
|
|
|
|
|
|
|
|
overlayFile = _vm->_overlaysArchive->getFile(num);
|
2009-07-04 18:35:08 +00:00
|
|
|
Sprite *sp = new Sprite(overlayFile->_data, overlayFile->_length, x, y, true);
|
2009-07-04 15:21:12 +00:00
|
|
|
|
|
|
|
_vm->_anims->addOverlay(sp, z);
|
2009-07-03 17:54:13 +00:00
|
|
|
}
|
2009-07-04 15:21:12 +00:00
|
|
|
|
2009-07-03 18:17:05 +00:00
|
|
|
_vm->_overlaysArchive->clearCache();
|
2009-07-03 17:54:13 +00:00
|
|
|
|
2009-07-04 15:21:12 +00:00
|
|
|
_vm->_screen->getSurface()->markDirty();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Game::changeRoom(uint roomNum) {
|
2009-07-14 19:13:49 +00:00
|
|
|
|
|
|
|
debugC(1, kDraciLogicDebugLevel, "Changing to room %d", roomNum);
|
|
|
|
|
2009-07-17 01:20:51 +00:00
|
|
|
// Clear archives
|
2009-07-08 00:40:22 +00:00
|
|
|
_vm->_roomsArchive->clearCache();
|
|
|
|
_vm->_spritesArchive->clearCache();
|
|
|
|
_vm->_paletteArchive->clearCache();
|
2009-07-17 01:20:51 +00:00
|
|
|
_vm->_animationsArchive->clearCache();
|
|
|
|
_vm->_walkingMapsArchive->clearCache();
|
2009-07-08 00:40:22 +00:00
|
|
|
|
2009-07-12 19:00:24 +00:00
|
|
|
_vm->_screen->clearScreen();
|
|
|
|
|
2009-07-07 15:21:41 +00:00
|
|
|
_vm->_anims->deleteOverlays();
|
2009-07-18 03:00:12 +00:00
|
|
|
|
|
|
|
// Delete walking map testing overlay
|
|
|
|
_vm->_anims->deleteAnimation(-2);
|
2009-07-07 15:21:41 +00:00
|
|
|
|
|
|
|
int oldRoomNum = _currentRoom._roomNum;
|
|
|
|
|
2009-07-14 00:41:17 +00:00
|
|
|
for (uint i = 0; i < _info._numObjects; ++i) {
|
2009-07-07 15:21:41 +00:00
|
|
|
GameObject *obj = &_objects[i];
|
2009-07-18 03:00:12 +00:00
|
|
|
|
|
|
|
if (i != 0 && (obj->_location == oldRoomNum)) {
|
2009-07-07 21:18:28 +00:00
|
|
|
for (uint j = 0; j < obj->_anims.size(); ++j) {
|
|
|
|
_vm->_anims->deleteAnimation(obj->_anims[j]);
|
2009-07-07 15:21:41 +00:00
|
|
|
}
|
2009-07-18 03:00:12 +00:00
|
|
|
obj->_anims.clear();
|
2009-07-07 15:21:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-07-04 15:21:12 +00:00
|
|
|
_currentRoom._roomNum = roomNum;
|
|
|
|
loadRoom(roomNum);
|
2009-07-06 19:50:59 +00:00
|
|
|
loadOverlays();
|
|
|
|
}
|
|
|
|
|
|
|
|
int Game::getRoomNum() {
|
|
|
|
return _currentRoom._roomNum;
|
2009-07-02 20:29:14 +00:00
|
|
|
}
|
|
|
|
|
2009-07-07 21:30:36 +00:00
|
|
|
int Game::getVariable(int numVar) {
|
|
|
|
return _variables[numVar];
|
|
|
|
}
|
|
|
|
|
|
|
|
void Game::setVariable(int numVar, int value) {
|
|
|
|
_variables[numVar] = value;
|
|
|
|
}
|
|
|
|
|
2009-07-13 19:53:53 +00:00
|
|
|
int Game::getIconStatus(int iconID) {
|
|
|
|
return _iconStatus[iconID];
|
|
|
|
}
|
|
|
|
|
2009-06-27 05:10:24 +00:00
|
|
|
Game::~Game() {
|
|
|
|
delete[] _persons;
|
|
|
|
delete[] _variables;
|
|
|
|
delete[] _dialogOffsets;
|
2009-07-02 15:08:42 +00:00
|
|
|
delete[] _objects;
|
2009-06-28 13:10:53 +00:00
|
|
|
}
|
|
|
|
|
2009-07-17 00:20:57 +00:00
|
|
|
bool WalkingMap::isWalkable(int x, int y) {
|
|
|
|
|
|
|
|
// Convert to map pixels
|
|
|
|
x = x / _deltaX;
|
|
|
|
y = y / _deltaY;
|
|
|
|
|
|
|
|
int pixelIndex = _mapWidth * y + x;
|
|
|
|
int byteIndex = pixelIndex / 8;
|
|
|
|
int mapByte = _data[byteIndex];
|
|
|
|
|
|
|
|
return mapByte & (1 << pixelIndex % 8);
|
|
|
|
}
|
|
|
|
|
2009-07-18 03:00:12 +00:00
|
|
|
|
2009-06-27 01:04:24 +00:00
|
|
|
}
|