mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-24 21:21:05 +00:00
SHERLOCK: More scene loading code and support methods
This commit is contained in:
parent
43381e9819
commit
cf92e540db
@ -134,7 +134,7 @@ void Object::synchronize(Common::SeekableReadStream &s) {
|
||||
_maxFrames = s.readUint16LE();
|
||||
_flags = s.readByte();
|
||||
_aOpen.synchronize(s);
|
||||
_aType = s.readByte();
|
||||
_aType = (AType)s.readByte();
|
||||
_lookFrames = s.readByte();
|
||||
_seqCounter = s.readByte();
|
||||
_lookPosition.x = s.readUint16LE();
|
||||
@ -155,6 +155,41 @@ void Object::synchronize(Common::SeekableReadStream &s) {
|
||||
_use[idx].synchronize(s);
|
||||
}
|
||||
|
||||
void Object::toggleHidden() {
|
||||
if (_type != HIDDEN && _type != HIDE_SHAPE && _type != INVALID) {
|
||||
if (_seqTo != 0)
|
||||
_sequences[_frameNumber] = _seqTo + SEQ_TO_CODE + 128;
|
||||
_seqTo = 0;
|
||||
|
||||
if (_images == nullptr || _images->size() == 0)
|
||||
// No shape to erase, so flag as hidden
|
||||
_type = HIDDEN;
|
||||
else
|
||||
// Otherwise, flag it to be hidden after it gets erased
|
||||
_type = HIDE_SHAPE;
|
||||
} else if (_type != INVALID) {
|
||||
if (_seqTo != 0)
|
||||
_sequences[_frameNumber] = _seqTo + SEQ_TO_CODE + 128;
|
||||
_seqTo = 0;
|
||||
|
||||
_seqCounter = _seqcounter2 = 0;
|
||||
_seqStack = 0;
|
||||
_frameNumber = -1;
|
||||
|
||||
if (_images == nullptr || _images->size() == 0) {
|
||||
_type = NO_SHAPE;
|
||||
} else {
|
||||
_type = ACTIVE_BG_SHAPE;
|
||||
int idx = _sequences[0];
|
||||
if (idx >= _maxFrames)
|
||||
// Turn on: set up first frame
|
||||
idx = 0;
|
||||
|
||||
_imageFrame = &(*_images)[idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
void CAnim::synchronize(Common::SeekableReadStream &s) {
|
||||
|
@ -49,9 +49,31 @@ enum SpriteType {
|
||||
HIDE_SHAPE = 8 // Object needs to be hidden
|
||||
};
|
||||
|
||||
enum AType {
|
||||
OBJECT = 0,
|
||||
PERSON = 1,
|
||||
SOLID = 2,
|
||||
TALK = 3, // Standard talk zone
|
||||
FLAG_SET = 4,
|
||||
DELTA = 5,
|
||||
WALK_AROUND = 6,
|
||||
TALK_EVERY = 7, // Talk zone that turns on every room visit
|
||||
TALK_MOVE = 8, // Talk zone that only activates when Holmes moves
|
||||
PAL_CHANGE = 9, // Changes the palette down so that it gets darker
|
||||
PAL_CHANGE2 = 10, // Same as PAL_CHANGE, except that it goes up
|
||||
SCRIPT_ZONE = 11, // If this is clicked in, it is activated
|
||||
BLANK_ZONE = 12, // This masks out other objects when entered
|
||||
NOWALK_ZONE = 13 // Player cannot walk here
|
||||
};
|
||||
|
||||
#define MAX_HOLMES_SEQUENCE 16
|
||||
#define MAX_FRAME 30
|
||||
|
||||
// code put into sequences to defines 1-10 type seqs
|
||||
#define SEQ_TO_CODE 67
|
||||
#define FLIP_CODE (64 + 128)
|
||||
#define SOUND_CODE (34 + 128)
|
||||
|
||||
struct Sprite {
|
||||
Common::String _name; // Name
|
||||
Common::String _description; // Description
|
||||
@ -131,7 +153,7 @@ struct Object {
|
||||
int _maxFrames; // Number of frames
|
||||
int _flags; // Tells if object can be walked behind
|
||||
ActionType _aOpen; // Holds data for moving object
|
||||
int _aType; // Tells if this is an object, person, talk, etc.
|
||||
AType _aType; // Tells if this is an object, person, talk, etc.
|
||||
int _lookFrames; // How many frames to play of the look anim before pausing
|
||||
int _seqCounter; // How many times this sequence has been executed
|
||||
Common::Point _lookPosition; // Where to walk when examining object
|
||||
@ -147,6 +169,8 @@ struct Object {
|
||||
UseType _use[4];
|
||||
|
||||
void synchronize(Common::SeekableReadStream &s);
|
||||
|
||||
void toggleHidden();
|
||||
};
|
||||
|
||||
struct CAnim {
|
||||
|
@ -46,18 +46,47 @@ void BgfileheaderInfo::synchronize(Common::SeekableReadStream &s) {
|
||||
_filename = Common::String(buffer);
|
||||
}
|
||||
|
||||
int _fSize; // How long images are
|
||||
int _maxFrames; // How many unique frames in object
|
||||
Common::String _filename; // Filename of object
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
void Exit::synchronize(Common::SeekableReadStream &s) {
|
||||
_position.x = s.readSint16LE();
|
||||
_position.y = s.readSint16LE();
|
||||
_size.x = s.readSint16LE();
|
||||
_size.y = s.readSint16LE();
|
||||
_scene = s.readSint16LE();
|
||||
_allow = s.readSint16LE();
|
||||
_people.x = s.readSint16LE();
|
||||
_people.y = s.readSint16LE();
|
||||
_peopleDir = s.readUint16LE();
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
void SceneEntry::synchronize(Common::SeekableReadStream &s) {
|
||||
_startPosition.x = s.readSint16LE();
|
||||
_startPosition.y = s.readSint16LE();
|
||||
_startDir = s.readByte();
|
||||
_allow = s.readByte();
|
||||
}
|
||||
|
||||
void SceneSound::synchronize(Common::SeekableReadStream &s) {
|
||||
char buffer[9];
|
||||
s.read(buffer, 8);
|
||||
buffer[8] = '\0';
|
||||
|
||||
_name = Common::String(buffer);
|
||||
_priority = s.readByte();
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
Scene::Scene(SherlockEngine *vm): _vm(vm) {
|
||||
for (int idx = 0; idx < SCENES_COUNT; ++idx)
|
||||
Common::fill(&_stats[idx][0], &_stats[idx][9], false);
|
||||
_currentScene = -1;
|
||||
_goToRoom = -1;
|
||||
_changes = false;
|
||||
_oldCharPoint = 0;
|
||||
_numExits = 0;
|
||||
_windowOpen = _infoFlag = false;
|
||||
_menuMode = _keyboardInput = 0;
|
||||
_walkedInScene = false;
|
||||
@ -66,10 +95,12 @@ Scene::Scene(SherlockEngine *vm): _vm(vm) {
|
||||
_lzwMode = false;
|
||||
_invGraphicItems = 0;
|
||||
|
||||
_controlPanel = new ImageFile("controls.vgs");
|
||||
_controls = nullptr; // new ImageFile("menu.all");
|
||||
}
|
||||
|
||||
Scene::~Scene() {
|
||||
delete _controlPanel;
|
||||
delete _controls;
|
||||
clear();
|
||||
}
|
||||
@ -78,13 +109,10 @@ Scene::~Scene() {
|
||||
* Takes care of clearing any scene data
|
||||
*/
|
||||
void Scene::clear() {
|
||||
for (uint idx = 0; idx < _bgShapes.size(); ++idx)
|
||||
delete _bgShapes[idx]._images;
|
||||
}
|
||||
|
||||
void Scene::selectScene() {
|
||||
// Reset fields
|
||||
_numExits = 0;
|
||||
_windowOpen = _infoFlag = false;
|
||||
_menuMode = _keyboardInput = 0;
|
||||
_oldKey = _help = _oldHelp = 0;
|
||||
@ -93,6 +121,7 @@ void Scene::selectScene() {
|
||||
// Load the scene
|
||||
Common::String sceneFile = Common::String::format("res%02d", _goToRoom);
|
||||
Common::String roomName = Common::String::format("res%02d.rrm", _goToRoom);
|
||||
_currentScene = _goToRoom;
|
||||
_goToRoom = -1;
|
||||
|
||||
loadScene(sceneFile);
|
||||
@ -108,6 +137,8 @@ void Scene::selectScene() {
|
||||
* that it should point to after loading; _misc is then set to 0.
|
||||
*/
|
||||
void Scene::loadScene(const Common::String &filename) {
|
||||
Screen &screen = *_vm->_screen;
|
||||
Sound &sound = *_vm->_sound;
|
||||
bool flag;
|
||||
|
||||
_walkedInScene = false;
|
||||
@ -240,11 +271,160 @@ void Scene::loadScene(const Common::String &filename) {
|
||||
// Back at version byte, so skip over it
|
||||
rrmStream->skip(1);
|
||||
|
||||
// TODO
|
||||
// Load the walk directory
|
||||
for (int idx1 = 0; idx1 < MAX_ZONES; ++idx1) {
|
||||
for (int idx2 = 0; idx2 < MAX_ZONES; ++idx2)
|
||||
_walkDirectory[idx1][idx2] = rrmStream->readSint16LE();
|
||||
}
|
||||
|
||||
// Read in the walk data
|
||||
size = rrmStream->readUint16LE();
|
||||
Common::SeekableReadStream *walkStream = !_lzwMode ? rrmStream :
|
||||
decompressLZ(*rrmStream, size);
|
||||
|
||||
_walkData.resize(size);
|
||||
walkStream->read(&_walkData[0], size);
|
||||
|
||||
if (_lzwMode)
|
||||
delete walkStream;
|
||||
|
||||
// Read in the exits
|
||||
int numExits = rrmStream->readByte();
|
||||
_exits.resize(numExits);
|
||||
|
||||
for (int idx = 0; idx < numExits; ++idx)
|
||||
_exits[idx].synchronize(*rrmStream);
|
||||
|
||||
// Read in the entrance
|
||||
_entrance.synchronize(*rrmStream);
|
||||
|
||||
// Initialize sound list
|
||||
int numSounds = rrmStream->readByte();
|
||||
_sounds.resize(numSounds);
|
||||
|
||||
for (int idx = 0; idx < numSounds; ++idx)
|
||||
_sounds[idx].synchronize(*rrmStream);
|
||||
|
||||
// If sound is turned on, load the sounds into memory
|
||||
if (sound._sfxEnabled) {
|
||||
for (int idx = 0; idx < numSounds; ++idx) {
|
||||
sound.loadSound(_sounds[idx]._name, _sounds[idx]._priority);
|
||||
_sounds[idx]._name = "";
|
||||
}
|
||||
}
|
||||
|
||||
// Read in palette
|
||||
rrmStream->read(screen._cMap, PALETTE_SIZE);
|
||||
for (int idx = 0; idx < PALETTE_SIZE; ++idx)
|
||||
screen._cMap[idx] = VGA_COLOR_TRANS(screen._cMap[idx]);
|
||||
|
||||
Common::copy(screen._cMap, screen._cMap + PALETTE_SIZE, screen._sMap);
|
||||
|
||||
// Read in the background
|
||||
Common::SeekableReadStream *bgStream = !_lzwMode ? rrmStream :
|
||||
decompressLZ(*rrmStream, SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT);
|
||||
|
||||
bgStream->read(screen._backBuffer.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT);
|
||||
|
||||
if (_lzwMode)
|
||||
delete bgStream;
|
||||
|
||||
// Set the palette
|
||||
screen._backBuffer2.blitFrom(screen._backBuffer);
|
||||
screen.setPalette(screen._cMap);
|
||||
|
||||
delete rrmStream;
|
||||
}
|
||||
|
||||
// Clear user interface area and draw controls
|
||||
screen._backBuffer2.fillRect(0, INFO_LINE, SHERLOCK_SCREEN_WIDTH, INFO_LINE + 10, INFO_BLACK);
|
||||
screen._backBuffer.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y));
|
||||
screen._backBuffer2.transBlitFrom((*_controlPanel)[0], Common::Point(0, CONTROLS_Y));
|
||||
|
||||
_changes = false;
|
||||
checkSceneStatus();
|
||||
|
||||
if (!_vm->_justLoaded) {
|
||||
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
|
||||
if (_bgShapes[idx]._type == HIDDEN && _bgShapes[idx]._aType == TALK_EVERY)
|
||||
_bgShapes[idx].toggleHidden();
|
||||
}
|
||||
|
||||
// Check for TURNON objects
|
||||
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
|
||||
if (_bgShapes[idx]._type == HIDDEN && (_bgShapes[idx]._flags & 0x20))
|
||||
_bgShapes[idx].toggleHidden();
|
||||
}
|
||||
|
||||
// Check for TURNOFF objects
|
||||
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
|
||||
if (_bgShapes[idx]._type != HIDDEN && (_bgShapes[idx]._flags & 0x40) &&
|
||||
_bgShapes[idx]._type != INVALID)
|
||||
_bgShapes[idx].toggleHidden();
|
||||
}
|
||||
}
|
||||
|
||||
checkSceneFlags(false);
|
||||
checkInventory();
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* Set objects to their current persistent state. This includes things such as
|
||||
* opening or moving them
|
||||
*/
|
||||
void Scene::checkSceneStatus() {
|
||||
if (_stats[_currentScene][8]) {
|
||||
for (int idx = 0; idx < 8; ++idx) {
|
||||
int val = _stats[_currentScene][idx];
|
||||
|
||||
for (int bit = 0; bit < 8; ++bit) {
|
||||
uint objNumber = idx * 8 + bit;
|
||||
if (objNumber < _bgShapes.size()) {
|
||||
Object &obj = _bgShapes[objNumber];
|
||||
|
||||
if (val & 1) {
|
||||
// No shape to erase, so flag as hidden
|
||||
obj._type = HIDDEN;
|
||||
} else if (obj._images == nullptr || obj._images->size() == 0) {
|
||||
// No shape
|
||||
obj._type = NO_SHAPE;
|
||||
} else {
|
||||
obj._type = ACTIVE_BG_SHAPE;
|
||||
}
|
||||
} else {
|
||||
// Finished checks
|
||||
return;
|
||||
}
|
||||
|
||||
val >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the scene's objects against the game flags. If false is passed,
|
||||
* it means the scene has just been loaded. A value of true means that the scene
|
||||
* is in use (ie. not just loaded)
|
||||
*/
|
||||
void Scene::checkSceneFlags(bool flag) {
|
||||
int mode = mode ? HIDE_SHAPE : HIDDEN;
|
||||
|
||||
for (uint idx = 0; idx < _bgShapes.size(); ++idx) {
|
||||
Object &o = _bgShapes[idx];
|
||||
// TODO: read_flags calls
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks scene objects against the player's inventory items. If there are any
|
||||
* matching names, it means the given item has already been picked up, and should
|
||||
* be hidden in the scene.
|
||||
*/
|
||||
void Scene::checkInventory() {
|
||||
|
||||
}
|
||||
|
||||
} // End of namespace Sherlock
|
||||
|
@ -32,6 +32,10 @@
|
||||
namespace Sherlock {
|
||||
|
||||
#define SCENES_COUNT 63
|
||||
#define MAX_ZONES 40
|
||||
#define INFO_LINE 140
|
||||
#define CONTROLS_Y 138
|
||||
#define CONTROLS_Y1 151
|
||||
|
||||
class SherlockEngine;
|
||||
|
||||
@ -54,6 +58,33 @@ struct BgfileheaderInfo {
|
||||
void synchronize(Common::SeekableReadStream &s);
|
||||
};
|
||||
|
||||
struct Exit {
|
||||
Common::Point _position;
|
||||
Common::Point _size;
|
||||
|
||||
int _scene;
|
||||
int _allow;
|
||||
Common::Point _people;
|
||||
int _peopleDir;
|
||||
|
||||
void synchronize(Common::SeekableReadStream &s);
|
||||
};
|
||||
|
||||
struct SceneEntry {
|
||||
Common::Point _startPosition;
|
||||
int _startDir;
|
||||
int _allow;
|
||||
|
||||
void synchronize(Common::SeekableReadStream &s);
|
||||
};
|
||||
|
||||
struct SceneSound {
|
||||
Common::String _name;
|
||||
int _priority;
|
||||
|
||||
void synchronize(Common::SeekableReadStream &s);
|
||||
};
|
||||
|
||||
class Scene {
|
||||
private:
|
||||
SherlockEngine *_vm;
|
||||
@ -61,15 +92,23 @@ private:
|
||||
void loadScene();
|
||||
|
||||
void loadScene(const Common::String &filename);
|
||||
|
||||
void checkSceneStatus();
|
||||
|
||||
void checkSceneFlags(bool mode);
|
||||
|
||||
void checkInventory();
|
||||
public:
|
||||
int _currentScene;
|
||||
int _goToRoom;
|
||||
bool _changes;
|
||||
bool _stats[SCENES_COUNT][9];
|
||||
bool _savedStats[SCENES_COUNT][9];
|
||||
int _goToRoom;
|
||||
Common::Point _bigPos;
|
||||
Common::Point _overPos;
|
||||
int _oldCharPoint;
|
||||
ImageFile *_controls;
|
||||
int _numExits;
|
||||
ImageFile *_controlPanel;
|
||||
bool _windowOpen, _infoFlag;
|
||||
int _menuMode, _keyboardInput;
|
||||
int _oldKey, _help, _oldHelp;
|
||||
@ -86,6 +125,11 @@ public:
|
||||
Common::Array<CAnim> _cAnim;
|
||||
Common::Array<byte> _sequenceBuffer;
|
||||
Common::Array<InvGraphicType> _inv;
|
||||
int _walkDirectory[MAX_ZONES][MAX_ZONES];
|
||||
Common::Array<byte> _walkData;
|
||||
Common::Array<Exit> _exits;
|
||||
SceneEntry _entrance;
|
||||
Common::Array<SceneSound> _sounds;
|
||||
public:
|
||||
Scene(SherlockEngine *vm);
|
||||
~Scene();
|
||||
|
@ -32,6 +32,8 @@ Screen::Screen(SherlockEngine *vm) : Surface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCR
|
||||
_backBuffer2(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT) {
|
||||
_transitionSeed = 1;
|
||||
_fadeStyle = false;
|
||||
Common::fill(&_cMap[0], &_cMap[PALETTE_SIZE], 0);
|
||||
Common::fill(&_sMap[0], &_sMap[PALETTE_SIZE], 0);
|
||||
setFont(1);
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ namespace Sherlock {
|
||||
#define PALETTE_SIZE 768
|
||||
#define PALETTE_COUNT 256
|
||||
#define VGA_COLOR_TRANS(x) ((x) * 255 / 63)
|
||||
#define INFO_BLACK 1
|
||||
|
||||
class SherlockEngine;
|
||||
|
||||
@ -52,6 +53,8 @@ protected:
|
||||
public:
|
||||
Surface _backBuffer, _backBuffer2;
|
||||
bool _fadeStyle;
|
||||
byte _cMap[PALETTE_SIZE];
|
||||
byte _sMap[PALETTE_SIZE];
|
||||
public:
|
||||
Screen(SherlockEngine *vm);
|
||||
|
||||
|
@ -43,6 +43,7 @@ SherlockEngine::SherlockEngine(OSystem *syst, const SherlockGameDescription *gam
|
||||
_useEpilogue2 = false;
|
||||
_hsavedPos = Common::Point(-1, -1);
|
||||
_hsavedFs = -1;
|
||||
_justLoaded = false;
|
||||
}
|
||||
|
||||
SherlockEngine::~SherlockEngine() {
|
||||
|
@ -59,6 +59,7 @@ enum {
|
||||
|
||||
#define SHERLOCK_SCREEN_WIDTH 320
|
||||
#define SHERLOCK_SCREEN_HEIGHT 200
|
||||
#define SHERLOCK_SCENE_HEIGHT 138
|
||||
|
||||
struct SherlockGameDescription;
|
||||
|
||||
@ -91,6 +92,7 @@ public:
|
||||
bool _useEpilogue2;
|
||||
Common::Point _hsavedPos;
|
||||
int _hsavedFs;
|
||||
bool _justLoaded;
|
||||
public:
|
||||
SherlockEngine(OSystem *syst, const SherlockGameDescription *gameDesc);
|
||||
virtual ~SherlockEngine();
|
||||
|
@ -32,6 +32,10 @@ Sound::Sound(SherlockEngine *vm): _vm(vm) {
|
||||
_music = false;
|
||||
}
|
||||
|
||||
void Sound::loadSound(const Common::String &name, int priority) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Sound::playSound(const Common::String &name, WaitType waitType) {
|
||||
// TODO
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ public:
|
||||
public:
|
||||
Sound(SherlockEngine *vm);
|
||||
|
||||
void loadSound(const Common::String &name, int priority);
|
||||
void playSound(const Common::String &name, WaitType waitType = WAIT_RETURN_IMMEDIATELY);
|
||||
void cacheSound(const Common::String &name, int index);
|
||||
void playCachedSound(int index);
|
||||
|
Loading…
x
Reference in New Issue
Block a user