PRINCE: flic anim decoder works with room 59 (intro)

This commit is contained in:
Kamil Zbróg 2013-10-21 01:18:27 +01:00
parent 1f0e976ea6
commit 263b02eb61
6 changed files with 131 additions and 208 deletions

View file

@ -9,11 +9,13 @@ namespace Prince {
GraphicsMan::GraphicsMan(PrinceEngine *vm) GraphicsMan::GraphicsMan(PrinceEngine *vm)
: _vm(vm), _changed(false) { : _vm(vm), _changed(false) {
initGraphics(640, 480, true); initGraphics(640, 480, true);
_frontScreen = new Graphics::Surface();
_frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8());
} }
void GraphicsMan::update() { void GraphicsMan::update() {
if (_changed) { if (_changed) {
_vm->_system->copyRectToScreen((byte*)_roomBackground->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();
} }
@ -27,4 +29,25 @@ void GraphicsMan::change() {
_changed = true; _changed = true;
} }
void GraphicsMan::draw(const Graphics::Surface *s)
{
for (uint y = 0; y < 480; y++)
memcpy((byte*)_frontScreen->getBasePtr(0, y), (byte*)s->getBasePtr(0, y), 640);
}
void GraphicsMan::drawTransparent(const Graphics::Surface *s)
{
for (uint y = 0; y < 480; ++y)
{
for (uint x = 0; x < 640; ++x)
{
byte pixel = *((byte*)s->getBasePtr(x,y));
if (pixel != 255)
{
*((byte*)_frontScreen->getBasePtr(x, y)) = pixel;
}
}
}
}
} }

View file

@ -41,6 +41,10 @@ public:
void setPalette(const byte *palette); void setPalette(const byte *palette);
void draw(const Graphics::Surface *s);
void drawTransparent(const Graphics::Surface *s);
Graphics::Surface *_frontScreen;
Graphics::Surface *_backScreen; Graphics::Surface *_backScreen;
const Graphics::Surface *_roomBackground; const Graphics::Surface *_roomBackground;
@ -50,7 +54,6 @@ private:
bool _changed; bool _changed;
byte _palette[3 * 256]; byte _palette[3 * 256];
Graphics::Surface *_frontScreen;
}; };
} }

View file

@ -36,7 +36,6 @@
#include "graphics/surface.h" #include "graphics/surface.h"
#include "graphics/palette.h" #include "graphics/palette.h"
#include "graphics/pixelformat.h" #include "graphics/pixelformat.h"
#include "graphics/decoders/bmp.h"
#include "engines/util.h" #include "engines/util.h"
#include "engines/advancedDetector.h" #include "engines/advancedDetector.h"
@ -49,18 +48,20 @@
#include "prince/graphics.h" #include "prince/graphics.h"
#include "prince/script.h" #include "prince/script.h"
#include "video/flic_decoder.h"
namespace Prince { namespace Prince {
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) {
_rnd = new Common::RandomSource("prince"); _rnd = new Common::RandomSource("prince");
} }
PrinceEngine::~PrinceEngine() { PrinceEngine::~PrinceEngine() {
DebugMan.clearAllDebugChannels(); DebugMan.clearAllDebugChannels();
delete _rnd; delete _rnd;
} }
Common::Error PrinceEngine::run() { Common::Error PrinceEngine::run() {
@ -71,8 +72,8 @@ Common::Error PrinceEngine::run() {
debug("Adding all path: %s", gameDataDir.getPath().c_str()); debug("Adding all path: %s", gameDataDir.getPath().c_str());
SearchMan.addSubDirectoryMatching(gameDataDir, "all", 0, 2); SearchMan.addSubDirectoryMatching(gameDataDir, "all", 0, 2);
SearchMan.addSubDirectoryMatching(gameDataDir, "01", 0, 2); SearchMan.addSubDirectoryMatching(gameDataDir, "59", 0, 2);
Common::SeekableReadStream * walizka = SearchMan.createReadStreamForMember("walizka"); Common::SeekableReadStream * walizka = SearchMan.createReadStreamForMember("walizka");
@ -80,27 +81,24 @@ Common::Error PrinceEngine::run() {
if (!font1stream) if (!font1stream)
return Common::kPathNotFile; return Common::kPathNotFile;
Font font1 = Font(); if (_font.load(*font1stream)) {
if (font1.load(*font1stream)) { _font.getCharWidth(103);
font1.getCharWidth(103);
} }
delete font1stream; delete font1stream;
Common::SeekableReadStream *room = SearchMan.createReadStreamForMember("room"); Common::SeekableReadStream *room = SearchMan.createReadStreamForMember("room");
//_frontScreen = new Graphics::Surface(); //_frontScreen = new Graphics::Surface();
//_frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8()); //_frontScreen->create(640, 480, Graphics::PixelFormat::createFormatCLUT8());
if (room) { if (room) {
Graphics::BitmapDecoder roomBmp; _roomBmp.loadStream(*room);
roomBmp.loadStream(*room);
//_roomBackground = roomBmp.getSurface(); //_roomBackground = roomBmp.getSurface();
_system->getPaletteManager()->setPalette(roomBmp.getPalette(), 0, 256); _system->getPaletteManager()->setPalette(_roomBmp.getPalette(), 0, 256);
//font1.drawString(_frontScreen, "Hello World", 10, 10, 640, 1); //font1.drawString(_frontScreen, "Hello World", 10, 10, 640, 1);
// //
_graph->_roomBackground = roomBmp.getSurface(); #if 0
#if 1
MhwanhDecoder *walizkaBmp = new MhwanhDecoder(); MhwanhDecoder *walizkaBmp = new MhwanhDecoder();
if (walizka) { if (walizka) {
debug("Loading walizka"); debug("Loading walizka");
@ -123,46 +121,77 @@ Common::Error PrinceEngine::run() {
mainLoop(); mainLoop();
delete room; delete room;
delete walizkaBmp; //delete walizkaBmp;
} }
return Common::kNoError; return Common::kNoError;
}
bool PrinceEngine::PlayNextFrame()
{
_graph->draw(_roomBmp.getSurface());
const Graphics::Surface *s = _flicPlayer.decodeNextFrame();
if (s)
{
_graph->drawTransparent(s);
_graph->change();
}
return true;
} }
void PrinceEngine::mainLoop() { void PrinceEngine::mainLoop() {
//uint32 nextFrameTime = 0; //uint32 nextFrameTime = 0;
while (!shouldQuit()) { uint32 an = 1;
Common::Event event;
Common::EventManager *eventMan = _system->getEventManager(); while (!shouldQuit()) {
while (eventMan->pollEvent(event)) { Common::Event event;
switch (event.type) { Common::EventManager *eventMan = _system->getEventManager();
case Common::EVENT_KEYDOWN: while (eventMan->pollEvent(event)) {
break; switch (event.type) {
case Common::EVENT_KEYUP: case Common::EVENT_KEYDOWN:
break; break;
case Common::EVENT_MOUSEMOVE: case Common::EVENT_KEYUP:
break; break;
case Common::EVENT_LBUTTONDOWN: case Common::EVENT_MOUSEMOVE:
case Common::EVENT_RBUTTONDOWN: break;
break; case Common::EVENT_LBUTTONDOWN:
case Common::EVENT_LBUTTONUP: case Common::EVENT_RBUTTONDOWN:
case Common::EVENT_RBUTTONUP: break;
break; case Common::EVENT_LBUTTONUP:
case Common::EVENT_QUIT: case Common::EVENT_RBUTTONUP:
break; break;
default: case Common::EVENT_QUIT:
break; break;
} default:
} break;
}
}
if (shouldQuit()) if (shouldQuit())
return; return;
_script->step(); //_script->step();
if (_flicPlayer.endOfVideo())
{
Common::String streamName = Common::String::format("AN%02d", an++);
Common::SeekableReadStream * flicStream = SearchMan.createReadStreamForMember(streamName);
if (flicStream)
{
if (_flicPlayer.loadStream(flicStream))
{
debug("%s loaded", streamName.c_str());
_flicPlayer.start();
}
}
}
PlayNextFrame();
_graph->update(); _graph->update();
_system->delayMillis(40); _system->delayMillis(40);
} }
} }

View file

@ -30,11 +30,17 @@
#include "common/textconsole.h" #include "common/textconsole.h"
#include "common/rect.h" #include "common/rect.h"
#include "graphics/decoders/bmp.h"
#include "engines/engine.h" #include "engines/engine.h"
#include "engines/util.h" #include "engines/util.h"
#include "audio/mixer.h" #include "audio/mixer.h"
#include "video/flic_decoder.h"
#include "prince/font.h"
namespace Prince { namespace Prince {
struct PrinceGameDescription; struct PrinceGameDescription;
@ -61,9 +67,15 @@ public:
const PrinceGameDescription *_gameDescription; const PrinceGameDescription *_gameDescription;
private: private:
bool PlayNextFrame();
Common::RandomSource *_rnd; Common::RandomSource *_rnd;
Video::FlicDecoder _flicPlayer;
Graphics::BitmapDecoder _roomBmp;
GraphicsMan *_graph; GraphicsMan *_graph;
Script *_script; Script *_script;
Font _font;
void mainLoop(); void mainLoop();

View file

@ -9,7 +9,7 @@ namespace Prince {
static const uint16 NUM_OPCODES = 144; static const uint16 NUM_OPCODES = 144;
Script::Script(PrinceEngine *vm) : Script::Script(PrinceEngine *vm) :
_code(NULL), _stacktop(0), _vm(vm), _random("GroovieScripts") { _code(NULL), _stacktop(0), _vm(vm), _random("GroovieScripts"), _opcodeNF(false) {
} }
Script::~Script() { Script::~Script() {
@ -44,24 +44,27 @@ void Script::debugScript(const char *s, ...) {
} }
void Script::step() { void Script::step() {
_lastInstruction = _currentInstruction; while (!_opcodeNF)
// Prepare the base debug string {
Common::String dstr = Common::String::format("@0x%04X: ", _currentInstruction); _lastInstruction = _currentInstruction;
// Prepare the base debug string
Common::String dstr = Common::String::format("@0x%04X: ", _currentInstruction);
// Get the current opcode // Get the current opcode
_lastOpcode = readScript16bits(); _lastOpcode = readScript16bits();
dstr += Common::String::format("op %02d: ", _lastOpcode); dstr += Common::String::format("op %02d: ", _lastOpcode);
if (_lastOpcode > NUM_OPCODES) if (_lastOpcode > NUM_OPCODES)
error("Trying to execute unknown opcode %s", dstr.c_str()); error("Trying to execute unknown opcode %s", dstr.c_str());
debug("%s", dstr.c_str()); debug("%s", dstr.c_str());
// Execute the current opcode // Execute the current opcode
OpcodeFunc op = _opcodes[_lastOpcode]; OpcodeFunc op = _opcodes[_lastOpcode];
(this->*op)(); (this->*op)();
}
} }
uint8 Script::getCodeByte(uint32 address) { uint8 Script::getCodeByte(uint32 address) {
@ -110,7 +113,7 @@ void Script::O_SETSAMPLE() {
uint16 sampleId = readScript16bits(); uint16 sampleId = readScript16bits();
int32 sampleNameOffset = readScript32bits(); int32 sampleNameOffset = readScript32bits();
const char * sampleName = (const char *)_code + _currentInstruction + sampleNameOffset - 4; const char * sampleName = (const char *)_code + _currentInstruction + sampleNameOffset - 4;
debugScript("O_SETSAMPLE %d %s", sampleName, sampleName); debugScript("O_SETSAMPLE %d %s", sampleId, sampleName);
} }
void Script::O_FREESAMPLE() { void Script::O_FREESAMPLE() {

View file

@ -55,6 +55,7 @@ private:
uint32 _lastInstruction; uint32 _lastInstruction;
byte _result; byte _result;
int16 _flags[2000]; int16 _flags[2000];
bool _opcodeNF;
// Stack // Stack
uint16 _stack[500]; uint16 _stack[500];
@ -217,154 +218,6 @@ private:
void O_INPUTLINE(); void O_INPUTLINE();
void O_SETVOICED(); void O_SETVOICED();
void O_BREAK_POINT(); void O_BREAK_POINT();
#if 0
O_WAITFOREVER ;00
O_BLACKPALETTE ;01
O_SETUPPALETTE ;02
O_INITROOM ;03
O_SETSAMPLE ;04
O_FREESAMPLE ;05
O_PLAYSAMPLE ;06
O_PUTOBJECT ;07
O_REMOBJECT ;08
O_SHOWANIM ;09
O_CHECKANIMEND ;10
O_FREEANIM ;11
O_CHECKANIMFRAME ;12
O_PUTBACKANIM ;13
O_REMBACKANIM ;14
O_CHECKBACKANIMFRAME ;15
O_FREEALLSAMPLES ;16
O_SETMUSIC ;17
O_STOPMUSIC ;18
O__WAIT ;19
O_UPDATEOFF ;20
O_UPDATEON ;21
O_UPDATE ;22
O_CLS ;23
O__CALL ;24
O_RETURN ;25
O_GO ;26
O_BACKANIMUPDATEOFF ;27
O_BACKANIMUPDATEON ;28
O_CHANGECURSOR ;29
O_CHANGEANIMTYPE ;30
O__SETFLAG ;31
O_COMPARE ;32
O_JUMPZ ;33
O_JUMPNZ ;34
O_EXIT ;35
O_ADDFLAG ;36
O_TALKANIM ;37
O_SUBFLAG ;38
O_SETSTRING ;39
O_ANDFLAG ;40
O_GETMOBDATA ;41
O_ORFLAG ;42
O_SETMOBDATA ;43
O_XORFLAG ;44
O_GETMOBTEXT ;45
O_MOVEHERO ;46
O_WALKHERO ;47
O_SETHERO ;48
O_HEROOFF ;49
O_HEROON ;50
O_CLSTEXT ;51
O_CALLTABLE ;52
O_CHANGEMOB ;53
O_ADDINV ;54
O_REMINV ;55
O_REPINV ;56
O_OBSOLETE_GETACTION ;57
O_ADDWALKAREA ;58
O_REMWALKAREA ;59
O_RESTOREWALKAREA ;60
O_WAITFRAME ;61
O_SETFRAME ;62
O_RUNACTION ;63
O_COMPAREHI ;64
O_COMPARELO ;65
O_PRELOADSET ;66
O_FREEPRELOAD ;67
O_CHECKINV ;68
O_TALKHERO ;69
O_WAITTEXT ;70
O_SETHEROANIM ;71
O_WAITHEROANIM ;72
O_GETHERODATA ;73
O_GETMOUSEBUTTON ;74
O_CHANGEFRAMES ;75
O_CHANGEBACKFRAMES ;76
O_GETBACKANIMDATA ;77
O_GETANIMDATA ;78
O_SETBGCODE ;79
O_SETBACKFRAME ;80
O_GETRND ;81
O_TALKBACKANIM ;82
O_LOADPATH ;83
O_GETCHAR ;84
O_SETDFLAG ;85
O_CALLDFLAG ;86
O_PRINTAT ;87
O_ZOOMIN ;88
O_ZOOMOUT ;89
O_SETSTRINGOFFSET ;90
O_GETOBJDATA ;91
O_SETOBJDATA ;92
O_SWAPOBJECTS ;93
O_CHANGEHEROSET ;94
O_ADDSTRING ;95
O_SUBSTRING ;96
O_INITDIALOG ;97
O_ENABLEDIALOGOPT ;98
O_DISABLEDIALOGOPT ;99
O_SHOWDIALOGBOX ;100
O_STOPSAMPLE ;101
O_BACKANIMRANGE ;102
O_CLEARPATH ;103
O_SETPATH ;104
O_GETHEROX ;105
O_GETHEROY ;106
O_GETHEROD ;107
O_PUSHSTRING ;108
O_POPSTRING ;109
O_SETFGCODE ;110
O_STOPHERO ;111
O_ANIMUPDATEOFF ;112
O_ANIMUPDATEON ;113
O_FREECURSOR ;114
O_ADDINVQUIET ;115
O_RUNHERO ;116
O_SETBACKANIMDATA ;117
O_VIEWFLC ;118
O_CHECKFLCFRAME ;119
O_CHECKFLCEND ;120
O_FREEFLC ;121
O_TALKHEROSTOP ;122
O_HEROCOLOR ;123
O_GRABMAPA ;124
O_ENABLENAK ;125
O_DISABLENAK ;126
O_GETMOBNAME ;127
O_SWAPINVENTORY ;128
O_CLEARINVENTORY ;129
O_SKIPTEXT ;130
O_SETVOICEH ;131
O_SETVOICEA ;132
O_SETVOICEB ;133
O_SETVOICEC ;134
O_VIEWFLCLOOP ;135
O_FLCSPEED ;136
O_OPENINVENTORY ;137
O_KRZYWA ;138
O_GETKRZYWA ;139
O_GETMOB ;140
O_INPUTLINE ;141
O_SETVOICED ;142
O_BREAK_POINT ;143
#endif
}; };
} }