mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-05 17:20:30 +00:00
1853d594b8
svn-id: r42071
265 lines
7.6 KiB
C++
265 lines
7.6 KiB
C++
/* 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$
|
|
*
|
|
*/
|
|
|
|
#include "common/stream.h"
|
|
|
|
#include "draci/draci.h"
|
|
#include "draci/game.h"
|
|
#include "draci/barchive.h"
|
|
#include "draci/script.h"
|
|
#include "draci/animation.h"
|
|
|
|
namespace Draci {
|
|
|
|
Game::Game(DraciEngine *vm) : _vm(vm) {
|
|
unsigned int i;
|
|
Common::String path("INIT.DFW");
|
|
|
|
BArchive initArchive(path);
|
|
BAFile *file;
|
|
|
|
// Read in persons
|
|
|
|
file = initArchive.getFile(5);
|
|
Common::MemoryReadStream personData(file->_data, file->_length);
|
|
|
|
unsigned int numPersons = file->_length / personSize;
|
|
_persons = new Person[numPersons];
|
|
|
|
for (i = 0; i < numPersons; ++i) {
|
|
_persons[i]._x = personData.readByte();
|
|
_persons[i]._y = personData.readByte();
|
|
_persons[i]._fontColour = personData.readUint16LE();
|
|
}
|
|
|
|
// Read in dialog offsets
|
|
|
|
file = initArchive.getFile(4);
|
|
Common::MemoryReadStream dialogData(file->_data, file->_length);
|
|
|
|
unsigned int numDialogs = file->_length / sizeof(uint16);
|
|
_dialogOffsets = new uint16[numDialogs];
|
|
|
|
unsigned int curOffset;
|
|
for (i = 0, curOffset = 0; i < numDialogs; ++i) {
|
|
_dialogOffsets[i] = curOffset;
|
|
curOffset += dialogData.readUint16LE();
|
|
}
|
|
|
|
// Read in game info
|
|
|
|
file = initArchive.getFile(3);
|
|
Common::MemoryReadStream gameData(file->_data, file->_length);
|
|
_info = new GameInfo();
|
|
|
|
_info->_currentRoom = gameData.readByte();
|
|
_info->_mapRoom = gameData.readByte();
|
|
_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;
|
|
|
|
// Read in variables
|
|
|
|
file = initArchive.getFile(2);
|
|
unsigned int numVariables = file->_length / sizeof (int16);
|
|
|
|
_variables = new int16[numVariables];
|
|
Common::MemoryReadStream variableData(file->_data, file->_length);
|
|
|
|
for (i = 0; i < numVariables; ++i) {
|
|
_variables[i] = variableData.readUint16LE();
|
|
}
|
|
|
|
// Read in item status
|
|
|
|
file = initArchive.getFile(1);
|
|
_itemStatus = new byte[file->_length];
|
|
memcpy(_itemStatus, file->_data, file->_length);
|
|
|
|
// Read in object status
|
|
|
|
file = initArchive.getFile(0);
|
|
unsigned int numObjects = file->_length;
|
|
|
|
_objects = new GameObject[numObjects];
|
|
Common::MemoryReadStream objStatus(file->_data, file->_length);
|
|
|
|
for (i = 0; i < numObjects; ++i) {
|
|
byte tmp = objStatus.readByte();
|
|
|
|
// Set object visibility
|
|
_objects[i]._visible = tmp & 1;
|
|
|
|
// Set object location
|
|
_objects[i]._location = tmp & ~1;
|
|
}
|
|
|
|
assert(numDialogs == _info->_numDialogs);
|
|
assert(numPersons == _info->_numPersons);
|
|
assert(numVariables == _info->_numVariables);
|
|
assert(numObjects == _info->_numObjects);
|
|
|
|
loadObject(1);
|
|
_vm->_script->run(getObject(1)->_program, getObject(1)->_init);
|
|
|
|
changeRoom(1);
|
|
}
|
|
|
|
void Game::loadObject(uint16 objNum) {
|
|
BAFile *file;
|
|
|
|
// Convert to real index (indexes begin with 1 in the data files)
|
|
objNum -= 1;
|
|
|
|
file = _vm->_objectsArchive->getFile(objNum * 3);
|
|
Common::MemoryReadStream objReader(file->_data, file->_length);
|
|
|
|
GameObject *obj = _objects + objNum;
|
|
|
|
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();
|
|
obj->_priority = objReader.readByte();
|
|
obj->_idxSeq = objReader.readUint16LE();
|
|
obj->_numSeq = objReader.readUint16LE();
|
|
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;
|
|
obj->_animObj = 0;
|
|
|
|
obj->_seqTab = new uint16[obj->_numSeq];
|
|
|
|
file = _vm->_objectsArchive->getFile(objNum * 3 + 1);
|
|
obj->_title = new byte[file->_length];
|
|
memcpy(obj->_title, file->_data, file->_length);
|
|
|
|
file = _vm->_objectsArchive->getFile(objNum * 3 + 2);
|
|
obj->_program._bytecode = new byte[file->_length];
|
|
obj->_program._length = file->_length;
|
|
memcpy(obj->_program._bytecode, file->_data, file->_length);
|
|
}
|
|
|
|
GameObject *Game::getObject(uint16 objNum) {
|
|
|
|
// Convert to real index (indexes begin with 1 in the data files)
|
|
objNum -= 1;
|
|
|
|
return _objects + objNum;
|
|
}
|
|
|
|
void Game::changeRoom(uint16 roomNum) {
|
|
|
|
// Convert to real index (indexes begin with 1 in the data files)
|
|
roomNum -= 1;
|
|
|
|
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();
|
|
_currentRoom._map = roomReader.readByte();
|
|
_currentRoom._palette = roomReader.readByte();
|
|
_currentRoom._numMasks = roomReader.readUint16LE();
|
|
_currentRoom._init = roomReader.readUint16LE();
|
|
_currentRoom._look = roomReader.readUint16LE();
|
|
_currentRoom._use = roomReader.readUint16LE();
|
|
_currentRoom._canUse = roomReader.readUint16LE();
|
|
_currentRoom._imInit = roomReader.readByte();
|
|
_currentRoom._imLook = roomReader.readByte();
|
|
_currentRoom._imUse = roomReader.readByte();
|
|
_currentRoom._mouseOn = roomReader.readByte();
|
|
_currentRoom._heroOn = roomReader.readByte();
|
|
roomReader.read(&_currentRoom._pers0, 12);
|
|
roomReader.read(&_currentRoom._persStep, 12);
|
|
_currentRoom._escRoom = roomReader.readByte();
|
|
_currentRoom._numGates = roomReader.readByte();
|
|
|
|
f = _vm->_paletteArchive->getFile(_currentRoom._palette - 1);
|
|
_vm->_screen->setPalette(f->_data, 0, kNumColours);
|
|
|
|
uint x, y, z, num;
|
|
|
|
f = _vm->_roomsArchive->getFile(roomNum * 4 + 2);
|
|
Common::MemoryReadStream overlayReader(f->_data, f->_length);
|
|
BAFile *overlayFile;
|
|
|
|
for (uint i = 0; i < _currentRoom._numMasks; i++) {
|
|
|
|
num = overlayReader.readUint16LE();
|
|
x = overlayReader.readUint16LE();
|
|
y = overlayReader.readUint16LE();
|
|
z = overlayReader.readByte();
|
|
|
|
overlayFile = _vm->_overlaysArchive->getFile(num - 1);
|
|
Sprite *sp = new Sprite(overlayFile->_data, overlayFile->_length, x, y, z, true);
|
|
|
|
_vm->_anims->addOverlay(sp, z);
|
|
}
|
|
|
|
_vm->_screen->getSurface()->markDirty();
|
|
}
|
|
|
|
Game::~Game() {
|
|
delete[] _persons;
|
|
delete[] _variables;
|
|
delete[] _dialogOffsets;
|
|
delete[] _itemStatus;
|
|
delete[] _objects;
|
|
delete _info;
|
|
}
|
|
|
|
GameObject::~GameObject() {
|
|
delete[] _seqTab;
|
|
delete[] _title;
|
|
delete[] _program._bytecode;
|
|
}
|
|
|
|
}
|