PRINCE: midi music player added. mob and object lists added
This commit is contained in:
parent
5357724657
commit
84784add68
16 changed files with 864 additions and 53 deletions
|
@ -31,6 +31,8 @@ Debugger::Debugger(PrinceEngine *vm) : GUI::Debugger(), _vm(vm) {
|
||||||
DCmd_Register("getflag", WRAP_METHOD(Debugger, Cmd_GetFlag));
|
DCmd_Register("getflag", WRAP_METHOD(Debugger, Cmd_GetFlag));
|
||||||
DCmd_Register("clearflag", WRAP_METHOD(Debugger, Cmd_ClearFlag));
|
DCmd_Register("clearflag", WRAP_METHOD(Debugger, Cmd_ClearFlag));
|
||||||
DCmd_Register("viewflc", WRAP_METHOD(Debugger, Cmd_ViewFlc));
|
DCmd_Register("viewflc", WRAP_METHOD(Debugger, Cmd_ViewFlc));
|
||||||
|
DCmd_Register("initroom", WRAP_METHOD(Debugger, Cmd_InitRoom));
|
||||||
|
DCmd_Register("changecursor", WRAP_METHOD(Debugger, Cmd_ChangeCursor));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int strToInt(const char *s) {
|
static int strToInt(const char *s) {
|
||||||
|
@ -108,4 +110,29 @@ bool Debugger::Cmd_ViewFlc(int argc, const char **argv) {
|
||||||
_vm->loadAnim(flagNum);
|
_vm->loadAnim(flagNum);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Debugger::Cmd_InitRoom(int argc, const char **argv) {
|
||||||
|
// Check for a flag to clear
|
||||||
|
if (argc != 2) {
|
||||||
|
DebugPrintf("Usage: %s <anim number>\n", argv[0]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int flagNum = strToInt(argv[1]);
|
||||||
|
_vm->loadLocation(flagNum);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Debugger::Cmd_ChangeCursor(int argc, const char **argv) {
|
||||||
|
// Check for a flag to clear
|
||||||
|
if (argc != 2) {
|
||||||
|
DebugPrintf("Usage: %s <curId>\n", argv[0]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int flagNum = strToInt(argv[1]);
|
||||||
|
_vm->changeCursor(flagNum);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,8 @@ private:
|
||||||
bool Cmd_GetFlag(int argc, const char **argv);
|
bool Cmd_GetFlag(int argc, const char **argv);
|
||||||
bool Cmd_ClearFlag(int argc, const char **argv);
|
bool Cmd_ClearFlag(int argc, const char **argv);
|
||||||
bool Cmd_ViewFlc(int argc, const char **argv);
|
bool Cmd_ViewFlc(int argc, const char **argv);
|
||||||
|
bool Cmd_InitRoom(int argc, const char **argv);
|
||||||
|
bool Cmd_ChangeCursor(int argc, const char **argv);
|
||||||
|
|
||||||
PrinceEngine *_vm;
|
PrinceEngine *_vm;
|
||||||
};
|
};
|
||||||
|
|
|
@ -46,7 +46,6 @@ bool Font::load(Common::SeekableReadStream &stream) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int Font::getFontHeight() const {
|
int Font::getFontHeight() const {
|
||||||
debug("Font::getFontHeight %d", _fontData[5]);
|
|
||||||
return _fontData[5];
|
return _fontData[5];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,15 +69,20 @@ int Font::getCharWidth(byte chr) const {
|
||||||
return getChrData(chr)._width;
|
return getChrData(chr)._width;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Font::drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const {
|
void Font::drawChar(Graphics::Surface *dst, byte chr, int posX, int posY, uint32 color) const {
|
||||||
const ChrData chrData = getChrData(chr);
|
const ChrData chrData = getChrData(chr);
|
||||||
const byte *src = chrData._pixels;
|
|
||||||
byte *target = (byte *)dst->getBasePtr(x, y);
|
|
||||||
|
|
||||||
for (int i = 0; i < chrData._height; i++) {
|
for (int y = 0; y < chrData._height; ++y) {
|
||||||
memcpy(target, src, chrData._width);
|
for (int x = 0; x < chrData._width; ++x) {
|
||||||
src += chrData._width;
|
byte d = chrData._pixels[x + (chrData._width * y)];
|
||||||
target += dst->pitch;
|
if (d == 0) d = 255;
|
||||||
|
else if (d == 1) d = 0;
|
||||||
|
else if (d == 2) d = color;
|
||||||
|
else if (d == 3) d = 0;
|
||||||
|
if (d != 255) {
|
||||||
|
*(byte*)dst->getBasePtr(posX + x, posY + y) = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ void GraphicsMan::update() {
|
||||||
_vm->_system->copyRectToScreen((byte*)_frontScreen->getBasePtr(0,0), 640, 0, 0, 640, 480);
|
_vm->_system->copyRectToScreen((byte*)_frontScreen->getBasePtr(0,0), 640, 0, 0, 640, 480);
|
||||||
|
|
||||||
_vm->_system->updateScreen();
|
_vm->_system->updateScreen();
|
||||||
|
_changed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,15 +54,19 @@ void GraphicsMan::change() {
|
||||||
|
|
||||||
void GraphicsMan::draw(const Graphics::Surface *s)
|
void GraphicsMan::draw(const Graphics::Surface *s)
|
||||||
{
|
{
|
||||||
for (uint y = 0; y < 480; y++)
|
uint16 w = MIN(_frontScreen->w, s->w);
|
||||||
memcpy((byte*)_frontScreen->getBasePtr(0, y), (byte*)s->getBasePtr(0, y), 640);
|
for (uint y = 0; y < s->h; y++) {
|
||||||
change();
|
if (y < _frontScreen->h) {
|
||||||
|
memcpy((byte*)_frontScreen->getBasePtr(0, y), (byte*)s->getBasePtr(0, y), w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
change();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsMan::drawTransparent(const Graphics::Surface *s)
|
void GraphicsMan::drawTransparent(const Graphics::Surface *s)
|
||||||
{
|
{
|
||||||
for (uint y = 0; y < 480; ++y) {
|
for (uint y = 0; y < s->h; ++y) {
|
||||||
for (uint x = 0; x < 640; ++x) {
|
for (uint x = 0; x < s->w; ++x) {
|
||||||
byte pixel = *((byte*)s->getBasePtr(x,y));
|
byte pixel = *((byte*)s->getBasePtr(x,y));
|
||||||
if (pixel != 255) {
|
if (pixel != 255) {
|
||||||
*((byte*)_frontScreen->getBasePtr(x, y)) = pixel;
|
*((byte*)_frontScreen->getBasePtr(x, y)) = pixel;
|
||||||
|
|
|
@ -53,7 +53,6 @@ private:
|
||||||
PrinceEngine *_vm;
|
PrinceEngine *_vm;
|
||||||
|
|
||||||
bool _changed;
|
bool _changed;
|
||||||
byte _palette[3 * 256];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,7 @@
|
||||||
|
|
||||||
namespace Prince {
|
namespace Prince {
|
||||||
|
|
||||||
class MhwanhDecoder : public Graphics::ImageDecoder
|
class MhwanhDecoder : public Graphics::ImageDecoder {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
MhwanhDecoder();
|
MhwanhDecoder();
|
||||||
virtual ~MhwanhDecoder();
|
virtual ~MhwanhDecoder();
|
||||||
|
|
63
engines/prince/mob.cpp
Normal file
63
engines/prince/mob.cpp
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/* 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 "prince/mob.h"
|
||||||
|
|
||||||
|
#include "common/stream.h"
|
||||||
|
|
||||||
|
namespace Prince {
|
||||||
|
|
||||||
|
bool Mob::loadFromStream(Common::SeekableReadStream &stream) {
|
||||||
|
int32 pos = stream.pos();
|
||||||
|
|
||||||
|
uint16 visible = stream.readUint16LE();
|
||||||
|
|
||||||
|
if (visible == 0xFFFF)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_visible = visible;
|
||||||
|
_type = stream.readUint16LE();
|
||||||
|
_rect.left = stream.readUint16LE();
|
||||||
|
_rect.top = stream.readUint16LE();
|
||||||
|
_rect.right = stream.readUint16LE();
|
||||||
|
_rect.bottom = stream.readUint16LE();
|
||||||
|
|
||||||
|
stream.skip(6 * sizeof(uint16));
|
||||||
|
uint32 nameOffset = stream.readUint32LE();
|
||||||
|
uint32 examTextOffset = stream.readUint32LE();
|
||||||
|
|
||||||
|
byte c;
|
||||||
|
stream.seek(nameOffset);
|
||||||
|
_name.clear();
|
||||||
|
while ((c = stream.readByte()))
|
||||||
|
_name += c;
|
||||||
|
|
||||||
|
stream.seek(examTextOffset);
|
||||||
|
_examText.clear();
|
||||||
|
while ((c = stream.readByte()))
|
||||||
|
_examText += c;
|
||||||
|
stream.seek(pos + 32);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
48
engines/prince/mob.h
Normal file
48
engines/prince/mob.h
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/* 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 "common/scummsys.h"
|
||||||
|
#include "common/rect.h"
|
||||||
|
#include "common/str.h"
|
||||||
|
|
||||||
|
namespace Common {
|
||||||
|
class SeekableReadStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Prince {
|
||||||
|
|
||||||
|
class Mob {
|
||||||
|
public:
|
||||||
|
Mob() {}
|
||||||
|
|
||||||
|
bool loadFromStream(Common::SeekableReadStream &stream);
|
||||||
|
|
||||||
|
|
||||||
|
bool _visible;
|
||||||
|
uint16 _type;
|
||||||
|
Common::Rect _rect;
|
||||||
|
Common::String _name;
|
||||||
|
Common::String _examText;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,9 @@ MODULE_OBJS = \
|
||||||
mhwanh.o \
|
mhwanh.o \
|
||||||
detection.o \
|
detection.o \
|
||||||
font.o \
|
font.o \
|
||||||
|
mob.o \
|
||||||
|
object.o \
|
||||||
|
sound.o \
|
||||||
prince.o
|
prince.o
|
||||||
|
|
||||||
# This module can be built as a plugin
|
# This module can be built as a plugin
|
||||||
|
|
77
engines/prince/object.cpp
Normal file
77
engines/prince/object.cpp
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/* 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 "common/archive.h"
|
||||||
|
#include "common/debug-channels.h"
|
||||||
|
#include "common/debug.h"
|
||||||
|
#include "common/stream.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "graphics/surface.h"
|
||||||
|
|
||||||
|
#include "prince/object.h"
|
||||||
|
|
||||||
|
namespace Prince {
|
||||||
|
|
||||||
|
Object::Object() : _surface(NULL) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::loadSurface(Common::SeekableReadStream &stream) {
|
||||||
|
stream.skip(4);
|
||||||
|
|
||||||
|
_surface = new Graphics::Surface();
|
||||||
|
_surface->create(stream.readUint16LE(), stream.readUint16LE(), Graphics::PixelFormat::createFormatCLUT8());
|
||||||
|
for (int h = 0; h < _surface->h; ++h) {
|
||||||
|
stream.read(_surface->getBasePtr(0, h), _surface->w);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Object::loadFromStream(Common::SeekableReadStream &stream) {
|
||||||
|
|
||||||
|
int32 pos = stream.pos();
|
||||||
|
uint16 x = stream.readUint16LE();
|
||||||
|
if (x == 0xFFFF)
|
||||||
|
return false;
|
||||||
|
_x = x;
|
||||||
|
_y = stream.readUint16LE();
|
||||||
|
|
||||||
|
const Common::String obStreamName = Common::String::format("OB%02d", stream.readUint16LE());
|
||||||
|
Common::SeekableReadStream *obStream = SearchMan.createReadStreamForMember(obStreamName);
|
||||||
|
if (!obStream) {
|
||||||
|
error("Can't load %s", obStreamName.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadSurface(*obStream);
|
||||||
|
delete obStream;
|
||||||
|
|
||||||
|
_z = stream.readUint16LE();
|
||||||
|
|
||||||
|
stream.seek(pos + 16);
|
||||||
|
|
||||||
|
debug("Object x %d, y %d, z %d", _x, _y, _z);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
47
engines/prince/object.h
Normal file
47
engines/prince/object.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PRINCE_OBJECT_H
|
||||||
|
#define PRINCE_OBJECT_H
|
||||||
|
|
||||||
|
#include "graphics/decoders/image_decoder.h"
|
||||||
|
#include "graphics/surface.h"
|
||||||
|
|
||||||
|
namespace Prince {
|
||||||
|
|
||||||
|
class Object {
|
||||||
|
public:
|
||||||
|
Object();
|
||||||
|
|
||||||
|
bool loadFromStream(Common::SeekableReadStream &stream);
|
||||||
|
Graphics::Surface *getSurface() const { return _surface; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void loadSurface(Common::SeekableReadStream &stream);
|
||||||
|
|
||||||
|
Graphics::Surface *_surface;
|
||||||
|
uint16 _x, _y, _z;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -47,17 +47,46 @@
|
||||||
#include "prince/graphics.h"
|
#include "prince/graphics.h"
|
||||||
#include "prince/script.h"
|
#include "prince/script.h"
|
||||||
#include "prince/debugger.h"
|
#include "prince/debugger.h"
|
||||||
|
#include "prince/object.h"
|
||||||
|
#include "prince/mob.h"
|
||||||
|
#include "prince/sound.h"
|
||||||
|
|
||||||
#include "video/flic_decoder.h"
|
#include "video/flic_decoder.h"
|
||||||
|
|
||||||
namespace Prince {
|
namespace Prince {
|
||||||
|
|
||||||
|
Graphics::Surface *loadCursor(const char *curName)
|
||||||
|
{
|
||||||
|
Common::SeekableReadStream *curStream = SearchMan.createReadStreamForMember(curName);
|
||||||
|
if (!curStream) {
|
||||||
|
error("Can't load %s", curName);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
curStream->skip(4);
|
||||||
|
uint16 w = curStream->readUint16LE();
|
||||||
|
uint16 h = curStream->readUint16LE();
|
||||||
|
|
||||||
|
debug("Loading cursor %s, w %d, h %d", curName, w, h);
|
||||||
|
|
||||||
|
Graphics::Surface *curSurface = new Graphics::Surface();
|
||||||
|
curSurface->create(w, h, Graphics::PixelFormat::createFormatCLUT8());
|
||||||
|
for (int ih = 0; ih < h; ++ih) {
|
||||||
|
curStream->read(curSurface->getBasePtr(0, ih), w);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete curStream;
|
||||||
|
return curSurface;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) :
|
PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) :
|
||||||
Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL),
|
Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL),
|
||||||
_locationNr(0), _debugger(NULL) {
|
_locationNr(0), _debugger(NULL), _objectList(NULL), _mobList(NULL), _midiPlayer(NULL) {
|
||||||
_rnd = new Common::RandomSource("prince");
|
_rnd = new Common::RandomSource("prince");
|
||||||
_debugger = new Debugger(this);
|
_debugger = new Debugger(this);
|
||||||
|
_midiPlayer = new MusicPlayer(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
PrinceEngine::~PrinceEngine() {
|
PrinceEngine::~PrinceEngine() {
|
||||||
|
@ -65,6 +94,9 @@ PrinceEngine::~PrinceEngine() {
|
||||||
|
|
||||||
delete _rnd;
|
delete _rnd;
|
||||||
delete _debugger;
|
delete _debugger;
|
||||||
|
delete _cur1;
|
||||||
|
delete _cur2;
|
||||||
|
delete _midiPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
GUI::Debugger *PrinceEngine::getDebugger() {
|
GUI::Debugger *PrinceEngine::getDebugger() {
|
||||||
|
@ -108,23 +140,59 @@ Common::Error PrinceEngine::run() {
|
||||||
|
|
||||||
delete skryptStream;
|
delete skryptStream;
|
||||||
|
|
||||||
Common::SeekableReadStream *logoStrema = SearchMan.createReadStreamForMember("logo.raw");
|
|
||||||
if (logoStrema)
|
_cur1 = loadCursor("mouse1.cur");
|
||||||
|
_cur2 = loadCursor("mouse2.cur");
|
||||||
|
|
||||||
|
Common::SeekableReadStream *logoStream = SearchMan.createReadStreamForMember("logo.raw");
|
||||||
|
if (logoStream)
|
||||||
{
|
{
|
||||||
MhwanhDecoder logo;
|
MhwanhDecoder logo;
|
||||||
logo.loadStream(*logoStrema);
|
logo.loadStream(*logoStream);
|
||||||
_graph->setPalette(logo.getPalette());
|
_graph->setPalette(logo.getPalette());
|
||||||
_graph->draw(logo.getSurface());
|
_graph->draw(logo.getSurface());
|
||||||
_graph->update();
|
_graph->update();
|
||||||
_system->delayMillis(700);
|
_system->delayMillis(700);
|
||||||
}
|
}
|
||||||
delete logoStrema;
|
delete logoStream;
|
||||||
|
|
||||||
mainLoop();
|
mainLoop();
|
||||||
|
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MobList {
|
||||||
|
public:
|
||||||
|
bool loadFromStream(Common::SeekableReadStream &stream);
|
||||||
|
|
||||||
|
Common::Array<Mob> _mobList;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool MobList::loadFromStream(Common::SeekableReadStream &stream)
|
||||||
|
{
|
||||||
|
Mob mob;
|
||||||
|
while (mob.loadFromStream(stream))
|
||||||
|
_mobList.push_back(mob);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ObjectList {
|
||||||
|
public:
|
||||||
|
bool loadFromStream(Common::SeekableReadStream &stream);
|
||||||
|
|
||||||
|
Common::Array<Object> _objList;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool ObjectList::loadFromStream(Common::SeekableReadStream &stream)
|
||||||
|
{
|
||||||
|
Object obj;
|
||||||
|
while (obj.loadFromStream(stream))
|
||||||
|
_objList.push_back(obj);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool PrinceEngine::loadLocation(uint16 locationNr) {
|
bool PrinceEngine::loadLocation(uint16 locationNr) {
|
||||||
debug("PrinceEngine::loadLocation %d", locationNr);
|
debug("PrinceEngine::loadLocation %d", locationNr);
|
||||||
const Common::FSNode gameDataDir(ConfMan.get("path"));
|
const Common::FSNode gameDataDir(ConfMan.get("path"));
|
||||||
|
@ -145,14 +213,75 @@ bool PrinceEngine::loadLocation(uint16 locationNr) {
|
||||||
|
|
||||||
if(_roomBmp.loadStream(*room)) {
|
if(_roomBmp.loadStream(*room)) {
|
||||||
debug("Room bitmap loaded");
|
debug("Room bitmap loaded");
|
||||||
_system->getPaletteManager()->setPalette(_roomBmp.getPalette(), 0, 256);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete room;
|
delete room;
|
||||||
|
|
||||||
|
delete _mobList;
|
||||||
|
_mobList = NULL;
|
||||||
|
|
||||||
|
Common::SeekableReadStream *mobListStream = SearchMan.createReadStreamForMember("mob.lst");
|
||||||
|
if (!mobListStream) {
|
||||||
|
error("Can't read mob.lst");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_mobList = new MobList();
|
||||||
|
_mobList->loadFromStream(*mobListStream);
|
||||||
|
|
||||||
|
delete mobListStream;
|
||||||
|
|
||||||
|
delete _objectList;
|
||||||
|
_objectList = NULL;
|
||||||
|
|
||||||
|
Common::SeekableReadStream *objListStream = SearchMan.createReadStreamForMember("obj.lst");
|
||||||
|
if (!objListStream) {
|
||||||
|
error("Can't read obj.lst");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_objectList = new ObjectList();
|
||||||
|
_objectList->loadFromStream(*objListStream);
|
||||||
|
delete objListStream;
|
||||||
|
|
||||||
|
const char *musName = MusicPlayer::_musTable[MusicPlayer::_musRoomTable[locationNr]];
|
||||||
|
_midiPlayer->loadMidi(musName);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrinceEngine::changeCursor(uint16 curId)
|
||||||
|
{
|
||||||
|
Graphics::Surface *curSurface = NULL;
|
||||||
|
|
||||||
|
uint16 hotspotX = 0;
|
||||||
|
uint16 hotspotY = 0;
|
||||||
|
|
||||||
|
switch(curId) {
|
||||||
|
case 0:
|
||||||
|
CursorMan.showMouse(false);
|
||||||
|
return;
|
||||||
|
case 1:
|
||||||
|
curSurface = _cur1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
curSurface = _cur2;
|
||||||
|
hotspotX = curSurface->w >> 1;
|
||||||
|
hotspotY = curSurface->h >> 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CursorMan.replaceCursorPalette(_roomBmp.getPalette(), 0, 255);
|
||||||
|
CursorMan.replaceCursor(
|
||||||
|
curSurface->getBasePtr(0, 0),
|
||||||
|
curSurface->w, curSurface->h,
|
||||||
|
hotspotX, hotspotY,
|
||||||
|
255, false,
|
||||||
|
&curSurface->format
|
||||||
|
);
|
||||||
|
CursorMan.showMouse(true);
|
||||||
|
}
|
||||||
|
|
||||||
bool PrinceEngine::playNextFrame() {
|
bool PrinceEngine::playNextFrame() {
|
||||||
const Graphics::Surface *s = _flicPlayer.decodeNextFrame();
|
const Graphics::Surface *s = _flicPlayer.decodeNextFrame();
|
||||||
if (s) {
|
if (s) {
|
||||||
|
@ -193,9 +322,46 @@ void PrinceEngine::keyHandler(Common::Event event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrinceEngine::hotspot() {
|
||||||
|
Common::Point mousepos = _system->getEventManager()->getMousePos();
|
||||||
|
|
||||||
|
Common::Array<Mob>::iterator it = _mobList->_mobList.begin();
|
||||||
|
for (; it != _mobList->_mobList.end(); ++it) {
|
||||||
|
if (it->_visible)
|
||||||
|
continue;
|
||||||
|
if (it->_rect.contains(mousepos)) {
|
||||||
|
uint16 textW = 0;
|
||||||
|
for (int i = 0; i < it->_name.size(); ++i)
|
||||||
|
textW += _font.getCharWidth(it->_name[i]);
|
||||||
|
|
||||||
|
uint16 x = mousepos.x - textW/2;
|
||||||
|
if (x > _graph->_frontScreen->w)
|
||||||
|
x = 0;
|
||||||
|
|
||||||
|
if (x + textW > _graph->_frontScreen->w)
|
||||||
|
x = _graph->_frontScreen->w - textW;
|
||||||
|
|
||||||
|
_font.drawString(
|
||||||
|
_graph->_frontScreen,
|
||||||
|
it->_name,
|
||||||
|
x,
|
||||||
|
mousepos.y - _font.getFontHeight(),
|
||||||
|
_graph->_frontScreen->w,
|
||||||
|
216
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PrinceEngine::mainLoop() {
|
void PrinceEngine::mainLoop() {
|
||||||
|
|
||||||
|
loadLocation(1);
|
||||||
|
changeCursor(1);
|
||||||
|
CursorMan.showMouse(true);
|
||||||
|
|
||||||
while (!shouldQuit()) {
|
while (!shouldQuit()) {
|
||||||
|
_debugger->onFrame();
|
||||||
Common::Event event;
|
Common::Event event;
|
||||||
Common::EventManager *eventMan = _system->getEventManager();
|
Common::EventManager *eventMan = _system->getEventManager();
|
||||||
while (eventMan->pollEvent(event)) {
|
while (eventMan->pollEvent(event)) {
|
||||||
|
@ -223,13 +389,22 @@ void PrinceEngine::mainLoop() {
|
||||||
if (shouldQuit())
|
if (shouldQuit())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_script->step();
|
//_script->step();
|
||||||
|
|
||||||
if (_roomBmp.getSurface())
|
if (_roomBmp.getSurface()) {
|
||||||
|
_graph->setPalette(_roomBmp.getPalette());
|
||||||
_graph->draw(_roomBmp.getSurface());
|
_graph->draw(_roomBmp.getSurface());
|
||||||
|
}
|
||||||
|
|
||||||
playNextFrame();
|
playNextFrame();
|
||||||
|
|
||||||
|
//debug("Cursor visible %d", CursorMan.isVisible());
|
||||||
|
|
||||||
|
//if (_objectList)
|
||||||
|
// _graph->drawTransparent(_objectList->getSurface());
|
||||||
|
|
||||||
|
hotspot();
|
||||||
|
|
||||||
_graph->update();
|
_graph->update();
|
||||||
|
|
||||||
_system->delayMillis(40);
|
_system->delayMillis(40);
|
||||||
|
|
|
@ -53,6 +53,9 @@ class PrinceEngine;
|
||||||
class GraphicsMan;
|
class GraphicsMan;
|
||||||
class Script;
|
class Script;
|
||||||
class Debugger;
|
class Debugger;
|
||||||
|
class ObjectList;
|
||||||
|
class MobList;
|
||||||
|
class MusicPlayer;
|
||||||
|
|
||||||
class PrinceEngine : public Engine {
|
class PrinceEngine : public Engine {
|
||||||
protected:
|
protected:
|
||||||
|
@ -77,19 +80,28 @@ public:
|
||||||
|
|
||||||
virtual GUI::Debugger *getDebugger();
|
virtual GUI::Debugger *getDebugger();
|
||||||
|
|
||||||
|
void changeCursor(uint16 curId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool playNextFrame();
|
bool playNextFrame();
|
||||||
void keyHandler(Common::Event event);
|
void keyHandler(Common::Event event);
|
||||||
|
void hotspot();
|
||||||
|
|
||||||
Common::RandomSource *_rnd;
|
Common::RandomSource *_rnd;
|
||||||
Graphics::BitmapDecoder _roomBmp;
|
Graphics::BitmapDecoder _roomBmp;
|
||||||
uint16 _locationNr;
|
uint16 _locationNr;
|
||||||
MhwanhDecoder _walizkaBmp;
|
MhwanhDecoder _walizkaBmp;
|
||||||
|
|
||||||
|
Graphics::Surface *_cur1;
|
||||||
|
Graphics::Surface *_cur2;
|
||||||
|
|
||||||
Debugger *_debugger;
|
Debugger *_debugger;
|
||||||
GraphicsMan *_graph;
|
GraphicsMan *_graph;
|
||||||
Script *_script;
|
Script *_script;
|
||||||
Font _font;
|
Font _font;
|
||||||
|
ObjectList *_objectList;
|
||||||
|
MobList *_mobList;
|
||||||
|
MusicPlayer *_midiPlayer;
|
||||||
|
|
||||||
void mainLoop();
|
void mainLoop();
|
||||||
|
|
||||||
|
|
|
@ -206,24 +206,48 @@ void Script::O_REMBACKANIM() {
|
||||||
debugScript("O_REMBACKANIM roomId %d, slot %d", roomId, slot);
|
debugScript("O_REMBACKANIM roomId %d, slot %d", roomId, slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script::O_CHECKBACKANIMFRAME() {}
|
void Script::O_CHECKBACKANIMFRAME() {
|
||||||
|
uint16 slotId = readScript16bits();
|
||||||
|
uint16 frameId = readScript16bits();
|
||||||
|
|
||||||
void Script::O_FREEALLSAMPLES() {}
|
debugScript("O_CHECKBACKANIMFRAME slotId %d, frameId %d", slotId, frameId);
|
||||||
|
}
|
||||||
|
|
||||||
void Script::O_SETMUSIC() {}
|
void Script::O_FREEALLSAMPLES() {
|
||||||
|
debugScript("O_FREEALLSAMPLES");
|
||||||
|
}
|
||||||
|
|
||||||
void Script::O_STOPMUSIC() {}
|
void Script::O_SETMUSIC() {
|
||||||
|
uint16 musicId = readScript16bits();
|
||||||
|
|
||||||
void Script::O__WAIT() {}
|
debugScript("O_SETMUSIC musicId %d", musicId);
|
||||||
|
}
|
||||||
|
|
||||||
void Script::O_UPDATEOFF() {}
|
void Script::O_STOPMUSIC() {
|
||||||
|
debugScript("O_STOPMUSIC");
|
||||||
|
}
|
||||||
|
|
||||||
void Script::O_UPDATEON() {}
|
void Script::O__WAIT() {
|
||||||
|
uint16 pause = readScript16bits();
|
||||||
|
|
||||||
void Script::O_UPDATE () {}
|
debugScript("O__WAIT pause %d", pause);
|
||||||
|
}
|
||||||
|
|
||||||
void Script::O_CLS() {}
|
void Script::O_UPDATEOFF() {
|
||||||
|
debugScript("O_UPDATEOFF");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Script::O_UPDATEON() {
|
||||||
|
debugScript("O_UPDATEON");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Script::O_UPDATE () {
|
||||||
|
debugScript("O_UPDATE");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Script::O_CLS() {
|
||||||
|
debugScript("O_CLS");
|
||||||
|
}
|
||||||
|
|
||||||
void Script::O__CALL() {
|
void Script::O__CALL() {
|
||||||
int32 address = readScript32bits();
|
int32 address = readScript32bits();
|
||||||
|
@ -247,7 +271,10 @@ void Script::O_GO() {
|
||||||
debugScript("O_GO 0x%04X", opPC);
|
debugScript("O_GO 0x%04X", opPC);
|
||||||
_currentInstruction += opPC - 4;
|
_currentInstruction += opPC - 4;
|
||||||
}
|
}
|
||||||
void Script::O_BACKANIMUPDATEOFF() {}
|
void Script::O_BACKANIMUPDATEOFF() {
|
||||||
|
uint16 slotId = readScript32bits();
|
||||||
|
debugScript("O_BACKANIMUPDATEOFF slotId %d", slotId);
|
||||||
|
}
|
||||||
|
|
||||||
void Script::O_BACKANIMUPDATEON() {
|
void Script::O_BACKANIMUPDATEON() {
|
||||||
uint16 slot = readScript16bits();
|
uint16 slot = readScript16bits();
|
||||||
|
@ -258,26 +285,39 @@ void Script::O_CHANGECURSOR() {
|
||||||
uint16 cursorId = readScript16bits();
|
uint16 cursorId = readScript16bits();
|
||||||
debugScript("O_CHANGECURSOR %x", cursorId);
|
debugScript("O_CHANGECURSOR %x", cursorId);
|
||||||
}
|
}
|
||||||
void Script::O_CHANGEANIMTYPE() {}
|
|
||||||
|
void Script::O_CHANGEANIMTYPE() {
|
||||||
|
// NOT IMPLEMENTED
|
||||||
|
}
|
||||||
|
|
||||||
void Script::O__SETFLAG() {
|
void Script::O__SETFLAG() {
|
||||||
uint16 flagId = readScript16bits();
|
uint16 flagId = readScript16bits();
|
||||||
uint16 value = readScript16bits();
|
uint16 value = readScript16bits();
|
||||||
|
|
||||||
|
if (value & 0x8000) {
|
||||||
|
value = _flags[value - 0x8000];
|
||||||
|
}
|
||||||
|
|
||||||
debugScript("O__SETFLAG 0x%04X %d", flagId, value);
|
debugScript("O__SETFLAG 0x%04X %d", flagId, value);
|
||||||
_flags[flagId-0x8000] = value;
|
_flags[flagId - 0x8000] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script::O_COMPARE() {
|
void Script::O_COMPARE() {
|
||||||
uint16 flagId = readScript16bits();
|
uint16 flagId = readScript16bits();
|
||||||
uint16 value = readScript16bits();
|
uint16 value = readScript16bits();
|
||||||
|
|
||||||
|
if (value & 0x8000) {
|
||||||
|
value = _flags[value - 0x8000];
|
||||||
|
}
|
||||||
|
|
||||||
debugScript("O_COMPARE flagId 0x%04X, value %d", flagId, value);
|
debugScript("O_COMPARE flagId 0x%04X, value %d", flagId, value);
|
||||||
_result = (_flags[flagId-0x8000] == value);
|
_result = (_flags[flagId - 0x8000] == value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script::O_JUMPZ() {
|
void Script::O_JUMPZ() {
|
||||||
int32 offset = readScript32bits();
|
int32 offset = readScript32bits();
|
||||||
debugScript("O_JUMPZ offset 0x%04X", offset);
|
debugScript("O_JUMPZ offset 0x%04X", offset);
|
||||||
if (_result == 0)
|
if (! _result) {
|
||||||
{
|
|
||||||
_currentInstruction += offset - 4;
|
_currentInstruction += offset - 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,20 +325,26 @@ void Script::O_JUMPZ() {
|
||||||
void Script::O_JUMPNZ() {
|
void Script::O_JUMPNZ() {
|
||||||
int32 offset = readScript32bits();
|
int32 offset = readScript32bits();
|
||||||
debugScript("O_JUMPNZ offset 0x%04X", offset);
|
debugScript("O_JUMPNZ offset 0x%04X", offset);
|
||||||
if (_result)
|
if (_result) {
|
||||||
{
|
|
||||||
_currentInstruction += offset - 4;
|
_currentInstruction += offset - 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script::O_EXIT() {}
|
void Script::O_EXIT() {
|
||||||
|
uint16 exitCode = readScript16bits();
|
||||||
|
debugScript("O_EXIT exitCode %d", exitCode);
|
||||||
|
}
|
||||||
|
|
||||||
void Script::O_ADDFLAG() {
|
void Script::O_ADDFLAG() {
|
||||||
uint16 flagId = readScript16bits();
|
uint16 flagId = readScript16bits();
|
||||||
uint16 value = readScript16bits();
|
uint16 value = readScript16bits();
|
||||||
|
|
||||||
_flags[flagId-0x8000] += value;
|
if (value & 0x8000) {
|
||||||
if (_flags[flagId-0x8000])
|
value = _flags[value - 0x8000];
|
||||||
|
}
|
||||||
|
|
||||||
|
_flags[flagId - 0x8000] += value;
|
||||||
|
if (_flags[flagId - 0x8000])
|
||||||
_result = 1;
|
_result = 1;
|
||||||
else
|
else
|
||||||
_result = 0;
|
_result = 0;
|
||||||
|
@ -317,8 +363,12 @@ void Script::O_SUBFLAG() {
|
||||||
uint16 flagId = readScript16bits();
|
uint16 flagId = readScript16bits();
|
||||||
uint16 value = readScript16bits();
|
uint16 value = readScript16bits();
|
||||||
|
|
||||||
_flags[flagId-0x8000] -= value;
|
if (value & 0x8000) {
|
||||||
if (_flags[flagId-0x8000])
|
value = _flags[value - 0x8000];
|
||||||
|
}
|
||||||
|
|
||||||
|
_flags[flagId - 0x8000] -= value;
|
||||||
|
if (_flags[flagId - 0x8000])
|
||||||
_result = 1;
|
_result = 1;
|
||||||
else
|
else
|
||||||
_result = 0;
|
_result = 0;
|
||||||
|
@ -332,17 +382,84 @@ void Script::O_SETSTRING() {
|
||||||
debugScript("O_SETSTRING 0x%04X", offset);
|
debugScript("O_SETSTRING 0x%04X", offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script::O_ANDFLAG() {}
|
void Script::O_ANDFLAG() {
|
||||||
|
uint16 flagId = readScript16bits();
|
||||||
|
uint16 value = readScript16bits();
|
||||||
|
|
||||||
void Script::O_GETMOBDATA() {}
|
debugScript("O_ANDFLAG flagId %d, value %d", flagId, value);
|
||||||
|
|
||||||
void Script::O_ORFLAG() {}
|
if (value & 0x8000) {
|
||||||
|
value = _flags[value - 0x8000];
|
||||||
|
}
|
||||||
|
|
||||||
void Script::O_SETMOBDATA() {}
|
_flags[flagId - 0x8000] &= value;
|
||||||
|
|
||||||
void Script::O_XORFLAG() {}
|
if (_flags[flagId - 0x8000]) {
|
||||||
|
_result = 1;
|
||||||
|
} else {
|
||||||
|
_result = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Script::O_GETMOBTEXT() {}
|
void Script::O_GETMOBDATA() {
|
||||||
|
uint16 flagId = readScript16bits();
|
||||||
|
uint16 mobId = readScript16bits();
|
||||||
|
uint16 mobOffset = readScript16bits();
|
||||||
|
|
||||||
|
debugScript("O_GETMOBDATA flagId %d, modId %d, mobOffset %d", flagId, mobId, mobOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Script::O_ORFLAG() {
|
||||||
|
uint16 flagId = readScript16bits();
|
||||||
|
uint16 value = readScript16bits();
|
||||||
|
|
||||||
|
debugScript("O_ORFLAG flagId %d, value %d", flagId, value);
|
||||||
|
|
||||||
|
if (value & 0x8000) {
|
||||||
|
value = _flags[value - 0x8000];
|
||||||
|
}
|
||||||
|
|
||||||
|
_flags[flagId - 0x8000] |= value;
|
||||||
|
|
||||||
|
if (_flags[flagId - 0x8000]) {
|
||||||
|
_result = 1;
|
||||||
|
} else {
|
||||||
|
_result = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Script::O_SETMOBDATA() {
|
||||||
|
uint16 mobId = readScript16bits();
|
||||||
|
uint16 mobOffset = readScript16bits();
|
||||||
|
uint16 value = readScript16bits();
|
||||||
|
|
||||||
|
debugScript("O_SETMOBDATA mobId %d, mobOffset %d, value %d", mobId, mobOffset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Script::O_XORFLAG() {
|
||||||
|
uint16 flagId = readScript16bits();
|
||||||
|
uint16 value = readScript16bits();
|
||||||
|
|
||||||
|
debugScript("O_XORFLAG flagId %d, value %d", flagId, value);
|
||||||
|
|
||||||
|
if (value & 0x8000) {
|
||||||
|
value = _flags[value - 0x8000];
|
||||||
|
}
|
||||||
|
|
||||||
|
_flags[flagId - 0x8000] ^= value;
|
||||||
|
|
||||||
|
if (_flags[flagId - 0x8000]) {
|
||||||
|
_result = 1;
|
||||||
|
} else {
|
||||||
|
_result = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Script::O_GETMOBTEXT() {
|
||||||
|
uint16 value = readScript16bits();
|
||||||
|
|
||||||
|
debugScript("O_GETMOBTEXT value %d", value);
|
||||||
|
}
|
||||||
|
|
||||||
void Script::O_MOVEHERO() {
|
void Script::O_MOVEHERO() {
|
||||||
uint16 heroId = readScript16bits();
|
uint16 heroId = readScript16bits();
|
||||||
|
|
160
engines/prince/sound.cpp
Normal file
160
engines/prince/sound.cpp
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
/* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This code is based on original Soltys source code
|
||||||
|
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "prince/prince.h"
|
||||||
|
#include "prince/sound.h"
|
||||||
|
#include "common/config-manager.h"
|
||||||
|
#include "common/memstream.h"
|
||||||
|
#include "common/archive.h"
|
||||||
|
#include "audio/decoders/raw.h"
|
||||||
|
#include "audio/audiostream.h"
|
||||||
|
|
||||||
|
namespace Prince {
|
||||||
|
|
||||||
|
const char * MusicPlayer::_musTable[] = {
|
||||||
|
"",
|
||||||
|
"Battlfld.mid",
|
||||||
|
"Cave.mid",
|
||||||
|
"Cemetery.mid",
|
||||||
|
"Credits.mid",
|
||||||
|
"Fjord.mid",
|
||||||
|
"Guitar.mid",
|
||||||
|
"Hell.mid",
|
||||||
|
"Jingle.mid",
|
||||||
|
"Main.mid",
|
||||||
|
"Night.mid",
|
||||||
|
"Reality.mid",
|
||||||
|
"Sunlord.mid",
|
||||||
|
"Tavern.mid",
|
||||||
|
"Temple.mid",
|
||||||
|
"Boruta.mid",
|
||||||
|
"Intro.mid"
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8 MusicPlayer::_musRoomTable[] = {
|
||||||
|
0,
|
||||||
|
3,
|
||||||
|
9,
|
||||||
|
9,
|
||||||
|
9,
|
||||||
|
13,
|
||||||
|
9,
|
||||||
|
9
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
MusicPlayer::MusicPlayer(PrinceEngine *vm) : _vm(vm) {
|
||||||
|
_data = NULL;
|
||||||
|
_isGM = false;
|
||||||
|
|
||||||
|
MidiPlayer::createDriver();
|
||||||
|
|
||||||
|
int ret = _driver->open();
|
||||||
|
if (ret == 0) {
|
||||||
|
if (_nativeMT32)
|
||||||
|
_driver->sendMT32Reset();
|
||||||
|
else
|
||||||
|
_driver->sendGMReset();
|
||||||
|
|
||||||
|
// TODO: Load cmf.ins with the instrument table. It seems that an
|
||||||
|
// interface for such an operation is supported for AdLib. Maybe for
|
||||||
|
// this card, setting instruments is necessary.
|
||||||
|
|
||||||
|
_driver->setTimerCallback(this, &timerCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MusicPlayer::~MusicPlayer() {
|
||||||
|
killMidi();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MusicPlayer::killMidi() {
|
||||||
|
Audio::MidiPlayer::stop();
|
||||||
|
|
||||||
|
free(_data);
|
||||||
|
_data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MusicPlayer::loadMidi(const char * name) {
|
||||||
|
Common::SeekableReadStream * stream = SearchMan.createReadStreamForMember(name);
|
||||||
|
if (!stream)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Stop any currently playing MIDI file
|
||||||
|
killMidi();
|
||||||
|
|
||||||
|
// Read in the data for the file
|
||||||
|
_dataSize = stream->size();
|
||||||
|
_data = (byte *)malloc(_dataSize);
|
||||||
|
stream->read(_data, _dataSize);
|
||||||
|
|
||||||
|
// Start playing the music
|
||||||
|
sndMidiStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MusicPlayer::sndMidiStart() {
|
||||||
|
_isGM = true;
|
||||||
|
|
||||||
|
MidiParser *parser = MidiParser::createParser_SMF();
|
||||||
|
if (parser->loadMusic(_data, _dataSize)) {
|
||||||
|
parser->setTrack(0);
|
||||||
|
parser->setMidiDriver(this);
|
||||||
|
parser->setTimerRate(_driver->getBaseTempo());
|
||||||
|
parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
|
||||||
|
|
||||||
|
_parser = parser;
|
||||||
|
|
||||||
|
syncVolume();
|
||||||
|
|
||||||
|
// Al the tracks are supposed to loop
|
||||||
|
_isLooping = true;
|
||||||
|
_isPlaying = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MusicPlayer::send(uint32 b) {
|
||||||
|
if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) {
|
||||||
|
b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
Audio::MidiPlayer::send(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MusicPlayer::sendToChannel(byte channel, uint32 b) {
|
||||||
|
if (!_channelsTable[channel]) {
|
||||||
|
_channelsTable[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
|
||||||
|
// If a new channel is allocated during the playback, make sure
|
||||||
|
// its volume is correctly initialized.
|
||||||
|
if (_channelsTable[channel])
|
||||||
|
_channelsTable[channel]->volume(_channelsVolume[channel] * _masterVolume / 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_channelsTable[channel])
|
||||||
|
_channelsTable[channel]->send(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace CGE
|
73
engines/prince/sound.h
Normal file
73
engines/prince/sound.h
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
/* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This code is based on original Soltys source code
|
||||||
|
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PRINCE_SOUND_H
|
||||||
|
#define PRINCE_SOUND_H
|
||||||
|
|
||||||
|
#include "audio/audiostream.h"
|
||||||
|
#include "audio/decoders/wave.h"
|
||||||
|
#include "audio/fmopl.h"
|
||||||
|
#include "audio/mididrv.h"
|
||||||
|
#include "audio/midiparser.h"
|
||||||
|
#include "audio/midiplayer.h"
|
||||||
|
#include "audio/mixer.h"
|
||||||
|
#include "common/memstream.h"
|
||||||
|
|
||||||
|
namespace Prince {
|
||||||
|
|
||||||
|
class PrinceEngine;
|
||||||
|
|
||||||
|
class MusicPlayer: public Audio::MidiPlayer {
|
||||||
|
private:
|
||||||
|
PrinceEngine *_vm;
|
||||||
|
byte *_data;
|
||||||
|
int _dataSize;
|
||||||
|
bool _isGM;
|
||||||
|
|
||||||
|
// Start MIDI File
|
||||||
|
void sndMidiStart();
|
||||||
|
|
||||||
|
// Stop MIDI File
|
||||||
|
void sndMidiStop();
|
||||||
|
public:
|
||||||
|
MusicPlayer(PrinceEngine *vm);
|
||||||
|
~MusicPlayer();
|
||||||
|
|
||||||
|
void loadMidi(const char *);
|
||||||
|
void killMidi();
|
||||||
|
|
||||||
|
virtual void send(uint32 b);
|
||||||
|
virtual void sendToChannel(byte channel, uint32 b);
|
||||||
|
|
||||||
|
static const char * _musTable[];
|
||||||
|
static const uint8 _musRoomTable[];
|
||||||
|
};
|
||||||
|
|
||||||
|
} // End of namespace Prince
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue