Skip to content

Commit

Permalink
PRINCE: Arivald's monolog during intro kinda works
Browse files Browse the repository at this point in the history
  • Loading branch information
Kamil Zbróg committed Nov 2, 2013
1 parent fcd2273 commit cb31768
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 26 deletions.
2 changes: 2 additions & 0 deletions engines/prince/font.h
Expand Up @@ -49,6 +49,8 @@ class Font : public Graphics::Font {

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;
Expand Down
60 changes: 45 additions & 15 deletions engines/prince/prince.cpp
Expand Up @@ -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() {
Expand All @@ -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)
Expand Down Expand Up @@ -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();
Expand All @@ -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();

Expand Down
25 changes: 23 additions & 2 deletions engines/prince/prince.h
Expand Up @@ -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();
Expand Down Expand Up @@ -86,9 +105,10 @@ class PrinceEngine : public Engine {
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();
Expand All @@ -97,6 +117,7 @@ class PrinceEngine : public Engine {
void scrollCameraRight(int16 delta);
void scrollCameraLeft(int16 delta);
void drawScreen();
void showTexts();

uint32 getTextWidth(const char *s);

Expand Down
68 changes: 59 additions & 9 deletions engines/prince/script.cpp
Expand Up @@ -29,6 +29,7 @@
#include "common/debug.h"
#include "common/debug-channels.h"
#include "common/stream.h"
#include "common/archive.h"

namespace Prince {

Expand Down Expand Up @@ -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() {
Expand All @@ -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];
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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));
Expand All @@ -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() {
Expand Down Expand Up @@ -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() {}
Expand All @@ -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++;
}

Expand All @@ -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() {}
Expand Down Expand Up @@ -732,7 +745,7 @@ void Script::O_CHECKFLCFRAME() {

void Script::O_CHECKFLCEND() {

debugScript("O_CHECKFLCEND");
//debugScript("O_CHECKFLCEND");

const Video::FlicDecoder &flicPlayer = _vm->_flicPlayer;

Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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() {
Expand Down
2 changes: 2 additions & 0 deletions engines/prince/script.h
Expand Up @@ -61,6 +61,7 @@ class Script {
uint8 _savedStacktop;

const byte * _string;
uint32 _currentString;

// Helper functions
void checkPC(uint32 address);
Expand All @@ -70,6 +71,7 @@ class Script {
uint32 readScript32bits();
uint16 readScript8or16bits();
void debugScript(const char *s, ...);
void SetVoice(uint32 slot);

typedef void (Script::*OpcodeFunc)();
static OpcodeFunc _opcodes[];
Expand Down

0 comments on commit cb31768

Please sign in to comment.