aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Zbróg2013-11-02 01:29:26 +0000
committerKamil Zbróg2013-11-02 01:29:26 +0000
commitcb31768e3df03b7ed0f5740ee7c46e8987a54154 (patch)
tree26b4e41e424bf068005e955ce1dcf4eadb8d6d5b
parentfcd2273d78d81bdd91d05ef28a0c349415a7317b (diff)
downloadscummvm-rg350-cb31768e3df03b7ed0f5740ee7c46e8987a54154.tar.gz
scummvm-rg350-cb31768e3df03b7ed0f5740ee7c46e8987a54154.tar.bz2
scummvm-rg350-cb31768e3df03b7ed0f5740ee7c46e8987a54154.zip
PRINCE: Arivald's monolog during intro kinda works
-rw-r--r--engines/prince/font.h2
-rw-r--r--engines/prince/prince.cpp60
-rw-r--r--engines/prince/prince.h25
-rw-r--r--engines/prince/script.cpp68
-rw-r--r--engines/prince/script.h2
5 files changed, 131 insertions, 26 deletions
diff --git a/engines/prince/font.h b/engines/prince/font.h
index 54e6b6b0a5..629b5d61eb 100644
--- a/engines/prince/font.h
+++ b/engines/prince/font.h
@@ -49,6 +49,8 @@ public:
virtual void drawChar(Graphics::Surface *dst, byte chr, int x, int y, uint32 color) const override;
+ virtual int getKerningOffset(byte left, byte right) const { return -2; }
+
private:
struct ChrData {
byte * _pixels;
diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp
index 9ca7a62fad..98bf4b7178 100644
--- a/engines/prince/prince.cpp
+++ b/engines/prince/prince.cpp
@@ -86,10 +86,17 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc)
Engine(syst), _gameDescription(gameDesc), _graph(NULL), _script(NULL),
_locationNr(0), _debugger(NULL), _objectList(NULL), _mobList(NULL), _midiPlayer(NULL),
_cameraX(0), _newCameraX(0) {
+
+ // Debug/console setup
+ DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel");
+ DebugMan.addDebugChannel(DebugChannel::kEngine, "engine", "Prince Engine debug channel");
+
+ DebugMan.enableDebugChannel("script");
+
_rnd = new Common::RandomSource("prince");
_debugger = new Debugger(this);
_midiPlayer = new MusicPlayer(this);
- _textSlots[0] = "";
+
}
PrinceEngine::~PrinceEngine() {
@@ -114,6 +121,7 @@ Common::Error PrinceEngine::run() {
debug("Adding all path: %s", gameDataDir.getPath().c_str());
SearchMan.addSubDirectoryMatching(gameDataDir, "all", 0, 2);
+ SearchMan.addSubDirectoryMatching(gameDataDir, "data/voices/output", 0, 2);
Common::SeekableReadStream *font1stream = SearchMan.createReadStreamForMember("font1.raw");
if (!font1stream)
@@ -415,19 +423,49 @@ void PrinceEngine::hotspot() {
}
}
-void PrinceEngine::printAt(const char *s, uint16 x, uint16 y) {
- _textSlots[0] = s;
+void PrinceEngine::printAt(uint32 slot, uint8 color, const char *s, uint16 x, uint16 y) {
+
+ debugC(1, DebugChannel::kEngine, "PrinceEngine::printAt slot %d, color %d, x %02d, y %02d, str %s", slot, color, x, y, s);
+
+ Text &text = _textSlots[slot];
+ text._str = s;
+ text._x = x;
+ text._y = y;
+ text._color = color;
}
uint32 PrinceEngine::getTextWidth(const char *s) {
uint16 textW = 0;
- while (*s) {
- textW += *s;
- ++s;
+ while (*s) {
+ textW += _font.getCharWidth(*s) + _font.getKerningOffset(0, 0);
+ ++s;
}
return textW;
}
+void PrinceEngine::showTexts() {
+ for (uint32 slot = 0; slot < MAXTEXTS; ++slot) {
+ Text& text = _textSlots[slot];
+ if (!text._str && !text._time)
+ continue;
+
+ Common::Array<Common::String> lines;
+ _font.wordWrapText(text._str, _graph->_frontScreen->w, lines);
+
+ for (int i = 0; i < lines.size(); ++i) {
+ _font.drawString(
+ _graph->_frontScreen,
+ lines[i],
+ text._x - getTextWidth(lines[i].c_str())/2,
+ text._y - (lines.size() - i) * (_font.getFontHeight()),
+ _graph->_frontScreen->w,
+ text._color
+ );
+ }
+
+ --text._time;
+ }
+}
void PrinceEngine::drawScreen() {
const Graphics::Surface *roomSurface = _roomBmp.getSurface();
@@ -443,15 +481,7 @@ void PrinceEngine::drawScreen() {
// _graph->drawTransparent(_objectList->getSurface());
hotspot();
- _font.drawString(
- _graph->_frontScreen,
- _textSlots[0],
- 320 - getTextWidth(_textSlots[0])/2,
- 470 - _font.getFontHeight(),
- _graph->_frontScreen->w,
- 216
- );
-
+ showTexts();
getDebugger()->onFrame();
diff --git a/engines/prince/prince.h b/engines/prince/prince.h
index 080eca5ead..43d94654c7 100644
--- a/engines/prince/prince.h
+++ b/engines/prince/prince.h
@@ -58,6 +58,25 @@ class MobList;
class MusicPlayer;
class VariaTxt;
+struct Text {
+ const char *_str;
+ uint16 _x, _y;
+ uint16 _time;
+ uint32 _color;
+
+ Text() : _str(NULL), _x(0), _y(0), _time(0), _color(255){
+ }
+};
+
+struct DebugChannel {
+
+enum Type {
+ kScript,
+ kEngine
+};
+
+};
+
class PrinceEngine : public Engine {
protected:
Common::Error run();
@@ -86,9 +105,10 @@ public:
virtual GUI::Debugger *getDebugger();
void changeCursor(uint16 curId);
- void printAt(const char *s, uint16 x, uint16 y);
+ void printAt(uint32 slot, uint8 color, const char *s, uint16 x, uint16 y);
- const char * _textSlots[1000];
+ static const uint8 MAXTEXTS = 32;
+ Text _textSlots[MAXTEXTS];
private:
bool playNextFrame();
@@ -97,6 +117,7 @@ private:
void scrollCameraRight(int16 delta);
void scrollCameraLeft(int16 delta);
void drawScreen();
+ void showTexts();
uint32 getTextWidth(const char *s);
diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp
index 7ab723a4fb..5e2b095b65 100644
--- a/engines/prince/script.cpp
+++ b/engines/prince/script.cpp
@@ -29,6 +29,7 @@
#include "common/debug.h"
#include "common/debug-channels.h"
#include "common/stream.h"
+#include "common/archive.h"
namespace Prince {
@@ -66,7 +67,7 @@ void Script::debugScript(const char *s, ...) {
Common::String str = Common::String::format("@0x%04X: ", _lastInstruction);
str += Common::String::format("op %02d: ", _lastOpcode);
- debug("%s %s", str.c_str(), buf);
+ debugC(10, DebugChannel::kScript, "PrinceEngine::Script %s %s", str.c_str(), buf);
}
void Script::step() {
@@ -85,7 +86,7 @@ void Script::step() {
error("Trying to execute unknown opcode %s", dstr.c_str());
- debug("%s", dstr.c_str());
+ debugScript("%s", dstr.c_str());
// Execute the current opcode
OpcodeFunc op = _opcodes[_lastOpcode];
@@ -330,7 +331,7 @@ void Script::O_COMPARE() {
value = val;
}
- debugScript("O_COMPARE flagId 0x%04X (%s), value %d", flagId, Flags::getFlagName(flagId), value);
+ debugScript("O_COMPARE flagId 0x%04X (%s), value %d ?= %d", flagId, Flags::getFlagName(flagId), value, _flags[flagId - 0x8000]);
_result = (_flags[flagId - 0x8000] == value);
}
@@ -398,6 +399,7 @@ void Script::O_SUBFLAG() {
void Script::O_SETSTRING() {
int32 offset = readScript32bits();
+ _currentString = offset;
if (offset >= 80000) {
debug("GetVaria %s", _vm->_variaTxt->getString(offset - 80000));
@@ -409,7 +411,7 @@ void Script::O_SETSTRING() {
debug("TalkTxt %d %s", of, txt);
}
- debugScript("O_SETSTRING 0x%04X", offset);
+ debugScript("O_SETSTRING %04d", offset);
}
void Script::O_ANDFLAG() {
@@ -545,8 +547,15 @@ void Script::O_TALKHERO() {}
void Script::O_WAITTEXT() {
uint16 slot = readScript16bits();
- debugScript("O_WAITTEXT slot %d", slot);
- _opcodeNF = 1;
+ if (slot & 0x8000) {
+ slot = _flags[slot - 0x8000];
+ }
+ //debugScript("O_WAITTEXT slot %d", slot);
+ Text &text = _vm->_textSlots[slot];
+ if (text._time) {
+ _opcodeNF = 1;
+ _currentInstruction -= 4;
+ }
}
void Script::O_SETHEROANIM() {}
@@ -568,10 +577,11 @@ void Script::O_LOADPATH() {}
void Script::O_GETCHAR() {
uint16 flagId = readScript16bits();
- debugScript("O_GETCHAR %04X (%s)", flagId, Flags::getFlagName(flagId));
_flags[flagId - 0x8000] = *_string;
+ debugScript("O_GETCHAR %04X (%s) %02x", flagId, Flags::getFlagName(flagId), _flags[flagId - 0x8000]);
+
_string++;
}
@@ -585,12 +595,15 @@ void Script::O_PRINTAT() {
debugScript("O_PRINTAT slot %d, fr1 %d, fr2 %d", slot, fr1, fr2);
- _vm->printAt((const char *)_string, 0, fr1);
+ uint8 color = _flags[Flags::KOLOR - 0x8000];
+
+ _vm->printAt(slot, color, (const char *)_string, fr1, fr2);
while (*_string) {
++_string;
}
++_string;
+ debug("O_PRINTAT %x", *_string);
}
void Script::O_ZOOMIN() {}
@@ -732,7 +745,7 @@ void Script::O_CHECKFLCFRAME() {
void Script::O_CHECKFLCEND() {
- debugScript("O_CHECKFLCEND");
+ //debugScript("O_CHECKFLCEND");
const Video::FlicDecoder &flicPlayer = _vm->_flicPlayer;
@@ -795,24 +808,60 @@ void Script::O_SKIPTEXT() {
debugScript("O_SKIPTEXT");
}
+void Script::SetVoice(uint32 slot) {
+ const Common::String streamName = Common::String::format("%03d-01.WAV", _currentString);
+ debugScript("Loading wav %s slot %d", streamName.c_str(), slot);
+
+ Common::SeekableReadStream *voiceStream = SearchMan.createReadStreamForMember(streamName);
+ if (!voiceStream) {
+ error("Can't open %s", streamName.c_str());
+ }
+ uint32 id = voiceStream->readUint32LE();
+ if (id != 0x46464952) {
+ error("It's not RIFF file %s", streamName.c_str());
+ return;
+ }
+
+ voiceStream->skip(0x20);
+ id = voiceStream->readUint32LE();
+ if (id != 0x61746164) {
+ error("No data section in %s id %04x", streamName.c_str(), id);
+ return;
+ }
+
+ id = voiceStream->readUint32LE();
+ id <<= 3;
+ id /= 22050;
+ id += 2;
+
+ _vm->_textSlots[slot]._time = voiceStream->readUint32LE();
+
+ debugScript("SetVoice slot %d time %04x", slot, _vm->_textSlots[slot]._time);
+ delete voiceStream;
+}
+
void Script::O_SETVOICEH() {
uint16 txn = readScript16bits();
debugScript("O_SETVOICEH txn %d", txn);
+ SetVoice(txn);
}
void Script::O_SETVOICEA() {
uint16 txn = readScript16bits();
debugScript("O_SETVOICEA txn %d", txn);
+ SetVoice(txn);
}
void Script::O_SETVOICEB() {
uint16 txn = readScript16bits();
debugScript("O_SETVOICEB txn %d", txn);
+ SetVoice(txn);
}
void Script::O_SETVOICEC() {
uint16 txn = readScript16bits();
debugScript("O_SETVOICEC txn %d", txn);
+ SetVoice(txn);
}
void Script::O_VIEWFLCLOOP() {
@@ -858,6 +907,7 @@ void Script::O_INPUTLINE() {
void Script::O_SETVOICED() {
uint16 txn = readScript16bits();
debugScript("O_SETVOICED txn %d", txn);
+ SetVoice(txn);
}
void Script::O_BREAK_POINT() {
diff --git a/engines/prince/script.h b/engines/prince/script.h
index dc050daeea..68b44cb1e3 100644
--- a/engines/prince/script.h
+++ b/engines/prince/script.h
@@ -61,6 +61,7 @@ private:
uint8 _savedStacktop;
const byte * _string;
+ uint32 _currentString;
// Helper functions
void checkPC(uint32 address);
@@ -70,6 +71,7 @@ private:
uint32 readScript32bits();
uint16 readScript8or16bits();
void debugScript(const char *s, ...);
+ void SetVoice(uint32 slot);
typedef void (Script::*OpcodeFunc)();
static OpcodeFunc _opcodes[];