MADS: In progress implementation of loadScene

This commit is contained in:
Paul Gilbert 2014-02-25 23:10:51 -05:00
parent 9eaab29afe
commit c49d7196fc
16 changed files with 308 additions and 162 deletions

View file

@ -82,7 +82,7 @@ SpriteAsset::SpriteAsset(MADSEngine *vm, const Common::String &resourceName, int
_frameCount, frame.x, frame.y, frame.w, frame.h);
}
frame.frame = MSprite::init(spriteDataStream, Common::Point(frame.x, frame.y),
frame.frame = new MSprite(spriteDataStream, Common::Point(frame.x, frame.y),
frame.w, frame.h, false);
_frames.push_back(frame);
}

View file

@ -39,7 +39,7 @@ Dialog::~Dialog() {
void Dialog::save(MSurface *s) {
_savedSurface = MSurface::init(_width, _height);
_savedSurface = new MSurface(_width, _height);
s->copyTo(_savedSurface,
Common::Rect(_position.x, _position.y, _position.x + _width, _position.y + _height),
Common::Point());

View file

@ -61,7 +61,6 @@ protected:
VisitedScenes _visitedScenes;
byte *_quotes;
int _v1;
int _v2;
int _v3;
int _v4;
int _v5;
@ -109,6 +108,7 @@ public:
Common::Array<uint16> _globalFlags;
InventoryObjects _objects;
Scene _scene;
int _v2;
public:
virtual ~Game();

View file

@ -83,7 +83,7 @@ void MADSEngine::initialise() {
_events = new EventsManager(this);
_palette = new Palette(this);
_font = new Font(this);
_screen = MSurface::init(g_system->getWidth(), g_system->getHeight());
_screen = new MSurface(g_system->getWidth(), g_system->getHeight());
_sound = new SoundManager(this, _mixer);
_userInterface = UserInterface::init(this);
_game = Game::init(this);

View file

@ -35,25 +35,13 @@ enum {
kMarker = 2
};
MADSEngine *MSprite::_vm;
MSprite *MSprite::init(MSurface &s) {
return new MSprite(s);
}
MSprite *MSprite::init(Common::SeekableReadStream *source, const Common::Point &offset,
int widthVal, int heightVal, bool decodeRle, uint8 encodingVal) {
return new MSprite(source, offset, widthVal, heightVal, decodeRle, encodingVal);
}
MSprite::MSprite(MSurface &s): _surface(s) {
MSprite::MSprite(): MSurface() {
_encoding = 0;
}
MSprite::MSprite(Common::SeekableReadStream *source, const Common::Point &offset,
int widthVal, int heightVal, bool decodeRle, uint8 encodingVal)
: _surface(*MSurface::init(widthVal, heightVal)),
: MSurface(widthVal, heightVal),
_encoding(encodingVal), _offset(offset) {
// Load the sprite data
@ -69,14 +57,14 @@ void MSprite::loadSprite(Common::SeekableReadStream *source) {
byte *outp, *lineStart;
bool newLine = false;
outp = _surface.getData();
lineStart = _surface.getData();
outp = getData();
lineStart = getData();
while (1) {
byte cmd1, cmd2, count, pixel;
if (newLine) {
outp = lineStart + _surface.w;
outp = lineStart + getWidth();
lineStart = outp;
newLine = false;
}

View file

@ -95,24 +95,15 @@ struct SpriteFrameHeader {
uint32 reserved8;
};
class MSprite {
public:
static MSprite *init(MSurface &s);
static MSprite *init(Common::SeekableReadStream *source, const Common::Point &offset, int widthVal,
int heightVal, bool decodeRle = true, uint8 encodingVal = 0);
protected:
static MADSEngine *_vm;
MSprite(MSurface &s);
MSprite(Common::SeekableReadStream *source, const Common::Point &offset,
int widthVal, int heightVal, bool decodeRle = true, uint8 encodingVal = 0);
class MSprite: public MSurface {
private:
void loadSprite(Common::SeekableReadStream *source);
public:
static void setVm(MADSEngine *vm) { _vm = vm; }
MSprite();
MSprite(Common::SeekableReadStream *source, const Common::Point &offset,
int widthVal, int heightVal, bool decodeRle = true, uint8 encodingVal = 0);
virtual ~MSprite();
MSurface &_surface;
Common::Point _pos;
Common::Point _offset;
uint8 _encoding;

View file

@ -32,22 +32,6 @@ namespace MADS {
MADSEngine *MSurface::_vm = nullptr;
MSurface *MSurface::init() {
if (_vm->getGameID() == GType_RexNebular) {
return new MSurfaceNebular();
} else {
return new MSurfaceMADS();
}
}
MSurface *MSurface::init(int width, int height) {
if (_vm->getGameID() == GType_RexNebular) {
return new MSurfaceNebular(width, height);
} else {
return new MSurfaceMADS(width, height);
}
}
MSurface::MSurface() {
pixels = nullptr;
}
@ -120,7 +104,7 @@ void MSurface::drawSprite(const Common::Point &pt, SpriteInfo &info, const Commo
return;
int heightAmt = scaledHeight;
byte *src = info.sprite->_surface.getData();
byte *src = info.sprite->getData();
byte *dst = getBasePtr(x - info.hotX - clipX, y - info.hotY - clipY);
int status = kStatusSkip;
@ -278,33 +262,7 @@ void MSurface::translate(RGBList *list, bool isTransparent) {
}
/*------------------------------------------------------------------------*/
void MSurfaceMADS::loadCodes(Common::SeekableReadStream *source) {
if (!source) {
free();
return;
}
uint16 width = MADS_SCREEN_WIDTH;
uint16 height = MADS_SCREEN_HEIGHT - MADS_INTERFACE_HEIGHT;
byte *walkMap = new byte[source->size()];
setSize(width, height);
source->read(walkMap, source->size());
byte *ptr = (byte *)getBasePtr(0, 0);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int ofs = x + (y * width);
if ((walkMap[ofs / 8] << (ofs % 8)) & 0x80)
*ptr++ = 1; // walkable
else
*ptr++ = 0;
}
}
}
/*
void MSurfaceMADS::loadBackground(int roomNumber, RGBList **palData) {
// clear previous data
empty();
@ -386,7 +344,7 @@ void MSurfaceMADS::loadBackground(int roomNumber, RGBList **palData) {
for (i = 0; i < tileCount; i++) {
tileDataUncomp->seek(i * 4, SEEK_SET);
uint32 tileOfs = tileDataUncomp->readUint32LE();
MSurface *newTile = MSurface::init(tileWidth, tileHeight);
MSurface *newTile = new MSurface(tileWidth, tileHeight);
if (i == tileCount - 1)
compressedTileDataSize = tileDataComp->size() - tileOfs;
@ -454,7 +412,7 @@ void MSurfaceMADS::loadInterface(int index, RGBList **palData) {
delete intStream;
}
/*------------------------------------------------------------------------*/
------------------------------------------------------------------------
void MSurfaceNebular::loadBackground(int roomNumber, RGBList **palData) {
// clear previous data
@ -504,5 +462,6 @@ void MSurfaceNebular::loadBackgroundStream(Common::SeekableReadStream *source, R
delete sourceUnc;
}
*/
} // End of namespace MADS

View file

@ -50,24 +50,19 @@ struct SpriteInfo {
* MADS graphics surface
*/
class MSurface : public Graphics::Surface {
public:
private:
static MADSEngine *_vm;
public:
/**
* Sets the engine reference
* Sets the engine refrence used all surfaces
*/
static void setVm(MADSEngine *vm) { _vm = vm; }
/**
* Create a new surface.
* Helper method for calculating new dimensions when scaling a sprite
*/
static MSurface *init();
/**
* Create a surface
*/
static MSurface *init(int width, int height);
protected:
static int scaleValue(int value, int scale, int err);
public:
/**
* Basic constructor
*/
@ -77,12 +72,7 @@ protected:
* Constructor for a surface with fixed dimensions
*/
MSurface(int width, int height);
public:
/**
* Helper method for calculating new dimensions when scaling a sprite
*/
static int scaleValue(int value, int scale, int err);
public:
/**
* Destructor
*/
@ -182,55 +172,6 @@ public:
* Translates the data of a surface using a specified RGBList translation matrix.
*/
void translate(RGBList *list, bool isTransparent = false);
// Base virtual methods
/**
* Loads a background by scene name
*/
virtual void loadBackground(const Common::String &sceneName) {}
/**
* Load background by room number
*/
virtual void loadBackground(int roomNumber, RGBList **palData) = 0;
/**
* Load background from a passed stream
*/
virtual void loadBackground(Common::SeekableReadStream *source, RGBList **palData) {}
/**
* Load scene codes from a passed stream
*/
virtual void loadCodes(Common::SeekableReadStream *source) = 0;
/**
* Load a given user interface by index
*/
virtual void loadInterface(int index, RGBList **palData) {}
};
class MSurfaceMADS: public MSurface {
friend class MSurface;
protected:
MSurfaceMADS(): MSurface() {}
MSurfaceMADS(int width, int height): MSurface(width, height) {}
public:
virtual void loadCodes(Common::SeekableReadStream *source);
virtual void loadBackground(const Common::String &sceneName) {}
virtual void loadBackground(int roomNumber, RGBList **palData);
virtual void loadInterface(int index, RGBList **palData);
};
class MSurfaceNebular: public MSurfaceMADS {
friend class MSurface;
protected:
MSurfaceNebular(): MSurfaceMADS() {}
MSurfaceNebular(int width, int height): MSurfaceMADS(width, height) {}
private:
void loadBackgroundStream(Common::SeekableReadStream *source, RGBList **palData);
public:
virtual void loadBackground(int roomNumber, RGBList **palData);
};
} // End of namespace MADS

View file

@ -34,7 +34,7 @@ namespace MADS {
namespace Nebular {
GameNebular::GameNebular(MADSEngine *vm): Game(vm) {
_surface =MSurface::init(MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT - MADS_INTERFACE_HEIGHT);
_surface = new MSurface(MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT - MADS_INTERFACE_HEIGHT);
}
int GameNebular::checkCopyProtection() {

View file

@ -303,6 +303,19 @@ Common::String Resources::formatName(RESPREFIX resType, int id, const Common::St
return result;
}
Common::String Resources::formatResource(const Common::String &resName,
const Common::String &hagFilename) {
int v1 = 0, v2 = 0;
if (resName.hasPrefix("*")) {
// Resource file specified
error("TODO: formatResource");
} else {
// File outside of hag file
return resName;
}
}
/*------------------------------------------------------------------------*/
void File::openFile(const Common::String &filename) {

View file

@ -47,6 +47,7 @@ public:
static void init(MADSEngine *vm);
static Common::String formatName(RESPREFIX resType, int id, const Common::String &ext);
static Common::String formatResource(const Common::String &resName, const Common::String &hagFilename);
};
/**

View file

@ -33,6 +33,8 @@ Scene::Scene(MADSEngine *vm): _vm(vm), _spriteSlots(vm) {
_currentSceneId = 0;
_vocabBuffer = nullptr;
_sceneLogic = nullptr;
_sceneInfo = nullptr;
_scenePalette = nullptr;
_verbList.push_back(VerbInit(VERB_LOOK, 2, 0));
_verbList.push_back(VerbInit(VERB_TAKE, 2, 0));
@ -50,6 +52,7 @@ Scene::Scene(MADSEngine *vm): _vm(vm), _spriteSlots(vm) {
Scene::~Scene() {
delete[] _vocabBuffer;
delete _sceneLogic;
delete _sceneInfo;
}
void Scene::clearDynamicHotspots() {
@ -84,11 +87,11 @@ int Scene::activeVocabIndexOf(int vocabId) {
}
void Scene::clearSequenceList() {
_sequenceList.clear();
_sequences.clear();
}
void Scene::clearMessageList() {
_messageList.clear();
_messages.clear();
_talkFont = "*FONTCONV.FF";
_textSpacing = -1;
}
@ -114,16 +117,22 @@ void Scene::loadScene(int sceneId, const Common::String &prefix, bool palFlag) {
if (palFlag)
_vm->_palette->resetGamePalette(18, 10);
_spriteSlots.clear(false);
_sequences.clear();
_messages.clear();
setPalette(_nullPalette);
_sceneInfo = SceneInfo::load(_vm, _currentSceneId, _v1, Common::String(), _vm->_game->_v2 ? 17 : 16,
_depthSurface, _backgroundSurface);
}
void Scene::loadHotspots() {
File f(Resources::formatName(RESPREFIX_RM, _currentSceneId, ".HH"));
int count = f.readUint16LE();
_hotspotList.clear();
_hotspots.clear();
for (int i = 0; i < count; ++i)
_hotspotList.push_back(Hotspot(f));
_hotspots.push_back(Hotspot(f));
}
void Scene::loadVocab() {
@ -142,10 +151,10 @@ void Scene::loadVocab() {
}
// Load scene hotspot list vocabs and verbs
for (uint i = 0; i < _hotspotList.size(); ++i) {
addActiveVocab(_hotspotList[i]._vocabId);
if (_hotspotList[i]._verbId)
addActiveVocab(_hotspotList[i]._verbId);
for (uint i = 0; i < _hotspots.size(); ++i) {
addActiveVocab(_hotspots[i]._vocabId);
if (_hotspots[i]._verbId)
addActiveVocab(_hotspots[i]._verbId);
}
loadVocabStrings();
@ -170,7 +179,7 @@ void Scene::free() {
}
void Scene::setPalette(RGB4 *p) {
_scenePalette = p;
// _scenePalette = p;
}
} // End of namespace MADS

View file

@ -27,6 +27,7 @@
#include "common/array.h"
#include "common/rect.h"
#include "mads/assets.h"
#include "mads/msurface.h"
#include "mads/scene_data.h"
namespace MADS {
@ -63,15 +64,18 @@ public:
bool _dynamicHotspotsChanged;
byte *_vocabBuffer;
Common::Array<int> _activeVocabs;
Common::Array<SequenceEntry> _sequenceList;
Common::Array<KernelMessage> _messageList;
Common::Array<SequenceEntry> _sequences;
Common::Array<KernelMessage> _messages;
Common::String _talkFont;
int _textSpacing;
Common::Array<Hotspot> _hotspotList;
Common::Array<Hotspot> _hotspots;
ScreenObjects _screenObjects;
RGB4 *_scenePalette;
ScenePalette *_scenePalette;
RGB4 _nullPalette[2];
int _v1;
SceneInfo *_sceneInfo;
MSurface _backgroundSurface;
MSurface _depthSurface;
/**
* Constructor

View file

@ -23,6 +23,7 @@
#include "common/scummsys.h"
#include "mads/scene_data.h"
#include "mads/mads.h"
#include "mads/resources.h"
#include "mads/nebular/nebular_scenes.h"
namespace MADS {
@ -161,4 +162,176 @@ Hotspot::Hotspot(Common::SeekableReadStream &f) {
_verbId = f.readUint16LE();
}
/*------------------------------------------------------------------------*/
void ARTHeader::load(Common::SeekableReadStream &f) {
_width = f.readUint16LE();
_height = f.readUint16LE();
_palCount = f.readUint16LE();
for (int i = 0; i < 256; ++i) {
RGB6 rgb;
rgb.r = f.readByte();
rgb.g = f.readByte();
rgb.b = f.readByte();
f.read(&rgb.unused[0], 3);
_palette.push_back(rgb);
}
int palCount = f.readUint16LE();
for (int i = 0; i < palCount; ++i) {
RGB4 rgb;
rgb.r = f.readByte();
rgb.g = f.readByte();
rgb.b = f.readByte();
rgb.u = f.readByte();
_palData.push_back(rgb);
}
}
/*------------------------------------------------------------------------*/
SceneInfo *SceneInfo::load(MADSEngine *vm, int sceneId, int v1, const Common::String &resName,
int v3, MSurface &depthSurface, MSurface &bgSurface) {
return new SceneInfo(vm, sceneId, v1, resName, v3, depthSurface, bgSurface);
}
SceneInfo::SceneInfo(MADSEngine *vm, int sceneId, int v1, const Common::String &resName,
int flags, MSurface &depthSurface, MSurface &bgSurface) {
bool flag = true;
bool sceneFlag = sceneId >= 0;
bool ssFlag = false, wsFlag = false;
int handle = 0;
SpriteAsset *spriteSets[10];
int xpList[10];
Common::fill(&spriteSets[0], &spriteSets[10], (SpriteAsset *)nullptr);
Common::fill(&xpList[0], &xpList[10], -1);
// Figure out the resource to use
Common::String resourceName;
if (sceneFlag) {
resourceName = Resources::formatName(RESPREFIX_RM, sceneId, ".DAT");
} else {
resourceName = "*" + Resources::formatResource(resName, resName);
}
// Open the scene info resource for access
File infoFile(resName);
// Read in basic data
_sceneId = infoFile.readUint16LE();
_artFileNum = infoFile.readUint16LE();
_depthStyle = infoFile.readUint16LE();
_width = infoFile.readUint16LE();
_height = infoFile.readUint16LE();
infoFile.skip(24);
_nodeCount = infoFile.readUint16LE();
_yBandsEnd = infoFile.readUint16LE();
_yBandsStart = infoFile.readUint16LE();
_maxScale = infoFile.readUint16LE();
_minScale = infoFile.readUint16LE();
for (int i = 0; i < 15; ++i)
_depthList[i] = infoFile.readUint16LE();
_field4A = infoFile.readUint16LE();
// Load the set of objects that are associated with the scene
for (int i = 0; i < 20; ++i) {
InventoryObject obj;
obj.load(infoFile);
_objects.push_back(obj);
}
int setCount = infoFile.readUint16LE();
int field40E = infoFile.readUint16LE();
for (int i = 0; i < 20; ++i) {
char name[64];
infoFile.read(name, 64);
_setNames.push_back(Common::String(name));
}
infoFile.close();
int width = _width;
int height = _height;
if (!bgSurface.getPixels()) {
bgSurface.setSize(width, height);
ssFlag = true;
}
if (_depthStyle == 2)
width >>= 2;
if (!depthSurface.getPixels()) {
depthSurface.setSize(width, height);
wsFlag = true;
}
// Load the depth surface with the scene codes
loadCodes(depthSurface);
// Get the ART resource
if (sceneFlag) {
resourceName = Resources::formatName(RESPREFIX_RM, sceneId, ".ART");
} else {
resourceName = "*" + Resources::formatResource(resName, resName);
}
// Load in the ART header and palette
File artFile(resourceName);
ARTHeader artHeader;
artHeader.load(artFile);
artFile.close();
// Copy out the palette data
for (int i = 0; i < artHeader._palData.size(); ++i)
_palette.push_back(artHeader._palData[i]);
/*
if (!(flags & 1)) {
if (_vm->_game->_scene->_scenePalette) {
//_vm->_game->_scene->_scenePalette->clean(&artHeader._palCount);
//_vm->_game->_scene->_scenePalette->process(&artHeader._palCount)
}
}
*/
warning("TODO");
}
void SceneInfo::loadCodes(MSurface &depthSurface) {
File f(Resources::formatName(RESPREFIX_RM, _sceneId, ".DAT"));
uint16 width = _width;
uint16 height = _height;
byte *walkMap = new byte[f.size()];
depthSurface.setSize(width, height);
f.read(walkMap, f.size());
byte *ptr = (byte *)depthSurface.getPixels();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int ofs = x + (y * width);
if ((walkMap[ofs / 8] << (ofs % 8)) & 0x80)
*ptr++ = 1; // walkable
else
*ptr++ = 0;
}
}
delete[] walkMap;
}
/*------------------------------------------------------------------------*/
void ScenePalette::clean(int *palCount) {
warning("TODO: ScenePalette::clean");
}
void ScenePalette::process(int *palCount) {
warning("TODO: ScenePalette::process");
}
} // End of namespace MADS

View file

@ -25,8 +25,11 @@
#include "common/scummsys.h"
#include "common/array.h"
#include "common/str.h"
#include "common/str-array.h"
#include "common/rect.h"
#include "mads/assets.h"
#include "mads/game_data.h"
namespace MADS {
@ -242,6 +245,70 @@ public:
virtual void postActions() = 0;
};
struct RGB6 {
byte r;
byte g;
byte b;
byte unused[3];
};
struct ARTHeader {
int _width;
int _height;
int _palCount;
Common::Array<RGB6> _palette;
Common::Array<RGB4> _palData;
void load(Common::SeekableReadStream &f);
};
/**
* Handles general data for a given scene
*/
class SceneInfo {
private:
MADSEngine *_vm;
SceneInfo(MADSEngine *vm, int sceneId, int v1, const Common::String &resName,
int v3, MSurface &depthSurface, MSurface &bgSurface);
/**
* Loads the given surface with depth information of a given scene
*/
void loadCodes(MSurface &depthSurface);
public:
int _sceneId;
int _artFileNum;
int _depthStyle;
int _width;
int _height;
int _nodeCount;
int _yBandsEnd;
int _yBandsStart;
int _maxScale;
int _minScale;
int _depthList[15];
int _field4A;
int _field4C;
Common::Array<InventoryObject> _objects;
Common::StringArray _setNames;
Common::Array<RGB4> _palette;
public:
/**
* Instantiates the class and loads the data
*/
static SceneInfo *load(MADSEngine *vm, int sceneId, int flags,
const Common::String &resName, int v3, MSurface &depthSurface, MSurface &bgSurface);
};
class ScenePalette {
public:
void clean(int *palCount);
void process(int *palCount);
};
} // End of namespace MADS
#endif /* MADS_SCENE_DATA_H */

View file

@ -33,7 +33,7 @@ UserInterface *UserInterface::init(MADSEngine *vm) {
}
UserInterface::UserInterface(MADSEngine *vm): _vm(vm), _surface(
MSurface::init(MADS_SCREEN_WIDTH, MADS_INTERFACE_HEIGHT)) {
new MSurface(MADS_SCREEN_WIDTH, MADS_INTERFACE_HEIGHT)) {
}
UserInterface::~UserInterface() {