HYPNO: state variables, more actions and improved video playback

This commit is contained in:
neuromancer 2021-07-31 16:43:48 +02:00 committed by Eugene Sandulenko
parent 212c177ab3
commit 104a141840
5 changed files with 288 additions and 156 deletions

View File

@ -48,6 +48,7 @@ typedef Common::List<Action*> Actions;
class Hotspot; class Hotspot;
typedef Common::Array<Hotspot> Hotspots; typedef Common::Array<Hotspot> Hotspots;
typedef Common::Array<Hotspots *> HotspotsStack; typedef Common::Array<Hotspots *> HotspotsStack;
typedef Common::List<Common::String> Movies;
class Hotspot { class Hotspot {
public: public:
@ -55,6 +56,7 @@ class Hotspot {
Common::String stype; Common::String stype;
Common::String stypeFlag; Common::String stypeFlag;
Common::Rect rect; Common::Rect rect;
Common::String setting;
Actions actions; Actions actions;
Hotspots *smenu; Hotspots *smenu;
}; };
@ -87,16 +89,45 @@ class Overlay : public Action {
class Escape : public Action { class Escape : public Action {
}; };
class Quit : public Action {
};
class Cutscene : public Action { class Cutscene : public Action {
public: public:
Common::String path; Common::String path;
}; };
class Play : public Action {
public:
Common::String path;
Common::Point origin;
Common::String condition;
Common::String flag;
};
typedef Common::HashMap<Common::String, Hotspots> Settings; class WalN : public Action {
public:
Common::String path;
Common::Point origin;
Common::String condition;
Common::String flag;
};
class Global : public Action {
public:
Common::String variable;
Common::String command;
};
class Level {
public:
Hotspots hots;
Movies intros;
};
typedef Common::HashMap<Common::String, Level> Levels;
extern Hotspots *g_parsedHots; extern Hotspots *g_parsedHots;
extern Settings g_settings; //extern Settings g_settings;
} // End of namespace Hypno } // End of namespace Hypno

View File

@ -82,13 +82,13 @@ using namespace Hypno;
int i; /* integer value */ int i; /* integer value */
} }
%token<s> NAME FILENAME FLAG COMMENT GSSWITCH %token<s> NAME FILENAME FLAG COMMENT GSSWITCH COMMAND
%token<i> NUM %token<i> NUM
%token HOTSTOK CUTSTOK BITMAPTOK BACKTOK RETTOK TIMETOK PALETOK BBOXTOK OVERTOK WALNTOK MICETOK PLAYTOK ENDTOK %token HOTSTOK CUTSTOK BACKTOK RETTOK TIMETOK PALETOK BBOXTOK OVERTOK WALNTOK MICETOK PLAYTOK ENDTOK
%token MENUTOK SMENTOK ESCPTOK NRTOK %token MENUTOK SMENTOK ESCPTOK NRTOK
%token GLOBTOK TONTOK TOFFTOK %token GLOBTOK TONTOK TOFFTOK
%type<s> gsswitch %type<s> gsswitch flag
%% %%
@ -162,8 +162,25 @@ line: MENUTOK NAME mflag {
Hotspot *hot = &cur->back(); Hotspot *hot = &cur->back();
hot->actions.push_back(a); hot->actions.push_back(a);
} }
| GLOBTOK gsswitch command { debug("GLOB."); } | GLOBTOK GSSWITCH NAME {
| PLAYTOK FILENAME NUM NUM gsswitch flag { debug("PLAY %s.", $2); } Global *a = new Global();
a->variable = $2;
a->command = $3;
Hotspots *cur = stack.back();
Hotspot *hot = &cur->back();
hot->actions.push_back(a);
debug("GLOB.");
}
| PLAYTOK FILENAME NUM NUM gsswitch flag {
Play *a = new Play();
a->path = $2;
a->origin = Common::Point($3, $4);
a->condition = $5;
a->flag = $6;
Hotspots *cur = stack.back();
Hotspot *hot = &cur->back();
hot->actions.push_back(a);
debug("PLAY %s.", $2); }
| OVERTOK FILENAME NUM NUM flag { | OVERTOK FILENAME NUM NUM flag {
Overlay *a = new Overlay(); Overlay *a = new Overlay();
a->path = $2; a->path = $2;
@ -187,7 +204,16 @@ line: MENUTOK NAME mflag {
hot->actions.push_back(a); hot->actions.push_back(a);
debug("CUTS %s.", $2); debug("CUTS %s.", $2);
} }
| WALNTOK FILENAME NUM NUM gsswitch flag { debug("WALN %s %d %d.", $2, $3, $4); } | WALNTOK FILENAME NUM NUM gsswitch flag {
WalN *a = new WalN();
a->path = $2;
a->origin = Common::Point($3, $4);
a->condition = $5;
a->flag = $6;
Hotspots *cur = stack.back();
Hotspot *hot = &cur->back();
hot->actions.push_back(a);
debug("WALN %s %d %d.", $2, $3, $4); }
| MICETOK FILENAME NUM { | MICETOK FILENAME NUM {
Mice *a = new Mice(); Mice *a = new Mice();
a->path = $2; a->path = $2;
@ -208,14 +234,10 @@ mflag: NRTOK
| /*nothing*/ | /*nothing*/
; ;
flag: BITMAPTOK { debug("flag: BITMAP"); } flag: FLAG { $$ = $1; debug("flag: %s", $1); }
| /* nothing */ | /* nothing */ { $$ = scumm_strdup(""); }
; ;
gsswitch: GSSWITCH { $$ = $1; debug("flag: GS_SWITCH"); } gsswitch: GSSWITCH { $$ = $1; debug("switch %s", $1); }
| /* nothing */ { $$ = scumm_strdup(""); } | /* nothing */ { $$ = scumm_strdup(""); }
; ;
command: TONTOK
| TOFFTOK
;

View File

@ -42,21 +42,50 @@
namespace Hypno { namespace Hypno {
Hotspots *g_parsedHots; Hotspots *g_parsedHots;
Settings g_settings; //Settings g_settings;
const static char* levelVariables[] = {
"GS_NONE",
"GS_SCTEXT",
"GS_AMBIENT",
"GS_MUSIC",
"GS_VOLUME",
"GS_MOUSESPEED",
"GS_MOUSEON",
"GS_LEVELCOMPLETE",
"GS_LEVELWON",
"GS_CHEATS",
"GS_SWITCH0",
"GS_SWITCH1",
"GS_SWITCH2",
"GS_SWITCH3",
"GS_SWITCH4",
"GS_SWITCH5",
"GS_SWITCH6",
"GS_SWITCH7",
"GS_SWITCH8",
"GS_SWITCH9",
"GS_SWITCH10",
"GS_SWITCH11",
"GS_SWITCH12",
"GS_COMBATJSON",
"GS_COMBATLEVEL",
"GS_PUZZLELEVEL",
NULL
};
extern int parse(const char *); extern int parse(const char *);
HypnoEngine::HypnoEngine(OSystem *syst, const ADGameDescription *gd) HypnoEngine::HypnoEngine(OSystem *syst, const ADGameDescription *gd)
: Engine(syst), _gameDescription(gd), _image(nullptr), _videoDecoder(nullptr), : Engine(syst), _gameDescription(gd), _image(nullptr), _videoDecoder(nullptr),
_compositeSurface(nullptr), _transparentColor(0), _frame(nullptr), _compositeSurface(nullptr), _transparentColor(0),
_nextHotsToAdd(nullptr), _nextHotsToRemove(nullptr), _nextHotsToAdd(nullptr), _nextHotsToRemove(nullptr),
_screenW(640), _screenH(480) { _screenW(640), _screenH(480) {
_rnd = new Common::RandomSource("hypno"); _rnd = new Common::RandomSource("hypno");
} }
HypnoEngine::~HypnoEngine() { HypnoEngine::~HypnoEngine() {
// Dispose your resources here // Dispose your resources
delete _frame;
delete _rnd; delete _rnd;
} }
@ -75,7 +104,9 @@ void HypnoEngine::loadMis(Common::String filename) {
test->read(buf, fileSize); test->read(buf, fileSize);
buf[fileSize] = '\0'; buf[fileSize] = '\0';
parse(buf); parse(buf);
g_settings[filename] = *g_parsedHots; Level level;
level.hots = *g_parsedHots;
_levels[filename] = level;
debug("Loaded hots size: %d", g_parsedHots->size()); debug("Loaded hots size: %d", g_parsedHots->size());
} }
@ -127,6 +158,18 @@ LibData HypnoEngine::loadLib(char *filename) {
return r; return r;
} }
void HypnoEngine::resetLevelState() {
uint32 i = 0;
while (levelVariables[i]) {
_levelState[levelVariables[i]] = 0;
i++;
}
}
bool HypnoEngine::checkLevelCompleted() {
return _levelState["GS_LEVELCOMPLETE"];
}
Common::Error HypnoEngine::run() { Common::Error HypnoEngine::run() {
_language = Common::parseLanguage(ConfMan.get("language")); _language = Common::parseLanguage(ConfMan.get("language"));
_platform = Common::parsePlatform(ConfMan.get("platform")); _platform = Common::parsePlatform(ConfMan.get("platform"));
@ -151,10 +194,27 @@ Common::Error HypnoEngine::run() {
} }
} }
*/ */
// Read assets file
Hotspot q;
q.type = MakeMenu;
Action *a = new Quit();
q.actions.push_back(a);
Level level;
Hotspots quit;
quit.push_back(q);
level.hots = quit;
_levels["mis/quit.mis"] = level;
// Read assets from mis files
loadMis("mis/demo.mis"); loadMis("mis/demo.mis");
_levels["mis/demo.mis"].intros.push_back("demo/dcine1.smk");
_levels["mis/demo.mis"].intros.push_back("demo/dcine2.smk");
_levels["mis/demo.mis"].hots[2].setting = "mis/alley.mis";
_levels["mis/demo.mis"].hots[5].setting = "mis/order.mis";
loadMis("mis/order.mis"); loadMis("mis/order.mis");
_levels["mis/order.mis"].hots[1].setting = "mis/quit.mis";
loadMis("mis/alley.mis"); loadMis("mis/alley.mis");
_levels["mis/alley.mis"].intros.push_back("demo/aleyc01s.smk");
//loadMis("MIS/SHOCTALK.MIS"); //loadMis("MIS/SHOCTALK.MIS");
// Initialize graphics // Initialize graphics
@ -166,8 +226,6 @@ Common::Error HypnoEngine::run() {
_transparentColor = _pixelFormat.RGBToColor(0, 0x82, 0); _transparentColor = _pixelFormat.RGBToColor(0, 0x82, 0);
screenRect = Common::Rect(0, 0, _screenW, _screenH); screenRect = Common::Rect(0, 0, _screenW, _screenH);
//changeCursor("default"); //changeCursor("default");
_origin = Common::Point(0, 0);
_image = new Image::BitmapDecoder();
_compositeSurface = new Graphics::ManagedSurface(); _compositeSurface = new Graphics::ManagedSurface();
_compositeSurface->create(_screenW, _screenH, _pixelFormat); _compositeSurface->create(_screenW, _screenH, _pixelFormat);
_compositeSurface->setTransparentColor(_transparentColor); _compositeSurface->setTransparentColor(_transparentColor);
@ -182,9 +240,17 @@ Common::Error HypnoEngine::run() {
} else { } else {
_nextSetting = getGoIntroSetting(); _nextSetting = getGoIntroSetting();
}*/ }*/
runIntro("DEMO/DCINE1.SMK", "DEMO/DCINE2.SMK");
_nextSetting = "mis/demo.mis";
while (!shouldQuit()) { while (!shouldQuit()) {
runMis("mis/alley.mis"); resetLevelState();
if (!_nextSetting.empty()) {
debug("Executing setting %s", _nextSetting.c_str());
_currentSetting = _nextSetting;
_nextSetting = "";
runMis(_currentSetting);
}
} }
return Common::kNoError; return Common::kNoError;
} }
@ -195,19 +261,30 @@ void HypnoEngine::runMis(Common::String name) {
Common::Point mousePos; Common::Point mousePos;
stack.clear(); stack.clear();
assert(g_settings.contains(name)); assert(_levels.contains(name));
_nextHotsToAdd = &g_settings[name]; _nextHotsToAdd = &_levels[name].hots;
_nextMoviesToPlay = _levels[name].intros;
for (uint32 i = 0; i < _nextMoviesToPlay.size(); i++) {
_nextMoviesPositions.push_back(Common::Point(0, 0));
_nextMoviesScales.push_back(true);
}
changeCursor("mouse/cursor1.smk", 0); changeCursor("mouse/cursor1.smk", 0);
while (!shouldQuit()) { while (!shouldQuit() && _nextSetting.empty()) {
while (g_system->getEventManager()->pollEvent(event)) { while (g_system->getEventManager()->pollEvent(event)) {
mousePos = g_system->getEventManager()->getMousePos(); mousePos = g_system->getEventManager()->getMousePos();
// Events // Events
switch (event.type) { switch (event.type) {
case Common::EVENT_KEYDOWN: case Common::EVENT_KEYDOWN:
if (event.kbd.keycode == Common::KEYCODE_ESCAPE && _videoDecoder) if (event.kbd.keycode == Common::KEYCODE_ESCAPE && _videoDecoder) {
skipVideo(); skipVideo();
if (!stack.empty()) {
runMenu(*stack.back());
drawScreen();
}
}
break; break;
@ -236,29 +313,40 @@ void HypnoEngine::runMis(Common::String name) {
} }
// Movies // Movies
if (!_nextMovie.empty()) { if (_nextMoviesToPlay.size() > 0 && _currentMovie.empty()) {
debug("start playing %s", _nextMoviesToPlay.front().c_str());
//removeTimer(); //removeTimer();
assert(_nextMoviesToPlay.size() == _nextMoviesPositions.size());
_videoDecoder = new Video::SmackerDecoder(); _videoDecoder = new Video::SmackerDecoder();
playVideo(_nextMovie); _currentMovie = _nextMoviesToPlay.front();
_currentMovie = _nextMovie; _moviePosition = _nextMoviesPositions.front();
_nextMovie = ""; _movieScale = _nextMoviesScales.front();
playVideo(_currentMovie);
_nextMoviesToPlay.pop_front();
_nextMoviesPositions.pop_front();
_nextMoviesScales.pop_front();
continue; continue;
} }
if (_videoDecoder && !_videoDecoder->isPaused()) { if (_videoDecoder && !_videoDecoder->isPaused()) {
debug("video decoder active!");
if (_videoDecoder->getCurFrame() == 0) if (_videoDecoder->getCurFrame() == 0)
stopSound(true); stopSound(true);
if (_videoDecoder->endOfVideo()) { if (_videoDecoder->endOfVideo()) {
debug("video still playing");
_videoDecoder->close(); _videoDecoder->close();
delete _videoDecoder; delete _videoDecoder;
_videoDecoder = nullptr; _videoDecoder = nullptr;
_currentMovie = ""; _currentMovie = "";
// refresh current scene // refresh current scene
runMenu(*stack.back()); if (!stack.empty()) {
drawScreen(); runMenu(*stack.back());
drawScreen();
}
} else if (_videoDecoder->needsUpdate()) { } else if (_videoDecoder->needsUpdate()) {
debug("updating screen");
drawScreen(); drawScreen();
g_system->delayMillis(10); g_system->delayMillis(10);
} }
@ -280,67 +368,14 @@ void HypnoEngine::runMis(Common::String name) {
drawScreen(); drawScreen();
} }
g_system->updateScreen(); if (checkLevelCompleted())
g_system->delayMillis(10); _nextSetting = "mis/demo.mis";
}
}
void HypnoEngine::runIntro(Common::String logoIntro, Common::String movieIntro) {
Common::Event event;
_nextMovie = logoIntro;
while ((_nextMovie != "" || _currentMovie != "") && !shouldQuit()) {
while (g_system->getEventManager()->pollEvent(event)) {
// Events
switch (event.type) {
case Common::EVENT_KEYDOWN:
if (event.kbd.keycode == Common::KEYCODE_ESCAPE && _videoDecoder) {
if (_currentMovie == logoIntro)
_nextMovie = movieIntro;
else
skipVideo();
}
break;
default:
break;
}
}
// Movies
if (!_nextMovie.empty()) {
_videoDecoder = new Video::SmackerDecoder();
playVideo(_nextMovie);
_currentMovie = _nextMovie;
_nextMovie = "";
continue;
}
if (_videoDecoder && !_videoDecoder->isPaused()) {
if (_videoDecoder->getCurFrame() == 0)
stopSound(true);
if (_videoDecoder->endOfVideo()) {
_videoDecoder->close();
delete _videoDecoder;
_videoDecoder = nullptr;
if (_currentMovie == logoIntro)
_nextMovie = movieIntro;
else
_nextMovie = "";
} else if (_videoDecoder->needsUpdate()) {
drawScreen();
g_system->delayMillis(10);
}
continue;
}
g_system->updateScreen(); g_system->updateScreen();
g_system->delayMillis(10); g_system->delayMillis(10);
} }
} }
//Actions //Actions
void HypnoEngine::runMenu(Hotspots hs) { void HypnoEngine::runMenu(Hotspots hs) {
@ -350,7 +385,9 @@ void HypnoEngine::runMenu(Hotspots hs) {
debug("hotspot actions size: %d", h.actions.size()); debug("hotspot actions size: %d", h.actions.size());
for (Actions::const_iterator itt = h.actions.begin(); itt != h.actions.end(); ++itt) { for (Actions::const_iterator itt = h.actions.begin(); itt != h.actions.end(); ++itt) {
Action *action = *itt; Action *action = *itt;
if (typeid(*action) == typeid(Background)) if (typeid(*action) == typeid(Quit))
runQuit(h, (Quit*) action);
else if (typeid(*action) == typeid(Background))
runBackground(h, (Background*) action); runBackground(h, (Background*) action);
else if (typeid(*action) == typeid(Overlay)) else if (typeid(*action) == typeid(Overlay))
runOverlay(h, (Overlay*) action); runOverlay(h, (Overlay*) action);
@ -358,16 +395,17 @@ void HypnoEngine::runMenu(Hotspots hs) {
// runMice(h, (Mice*) action); // runMice(h, (Mice*) action);
} }
if (h.stype == "SINGLE_RUN") //if (h.stype == "SINGLE_RUN")
loadImage("int_main/mainbutt.smk", 0, 0); // loadImage("int_main/mainbutt.smk", 0, 0);
else if (h.stype == "AUTO_BUTTONS") if (h.stype == "AUTO_BUTTONS")
loadImage("int_main/resume.smk", 0, 0); loadImage("int_main/resume.smk", 0, 0);
} }
void HypnoEngine::runBackground(const Hotspot h, Background *a) { void HypnoEngine::runBackground(const Hotspot h, Background *a) {
if (a->condition.size() > 0 && !_levelState[a->condition])
return;
Common::Point origin = a->origin; Common::Point origin = a->origin;
if (a->condition.size() == 0) loadImage(a->path, origin.x, origin.y);
loadImage(a->path, origin.x, origin.y);
} }
void HypnoEngine::runOverlay(const Hotspot h, Overlay *a) { void HypnoEngine::runOverlay(const Hotspot h, Overlay *a) {
@ -384,7 +422,49 @@ void HypnoEngine::runEscape(const Hotspot h, Escape *a) {
} }
void HypnoEngine::runCutscene(const Hotspot h, Cutscene *a) { void HypnoEngine::runCutscene(const Hotspot h, Cutscene *a) {
_nextMovie = a->path; _nextMoviesToPlay.push_back(a->path);
_nextMoviesPositions.push_back(Common::Point(0, 0));
_nextMoviesScales.push_back(true);
}
void HypnoEngine::runGlobal(const Hotspot h, Global *a) {
if (a->command == "TURNON")
_levelState[a->variable] = 1;
else if (a->command == "TURNOFF")
_levelState[a->variable] = 0;
else
error("Invalid command %s", a->command.c_str());
}
void HypnoEngine::runPlay(const Hotspot h, Play *a) {
if (a->condition.size() > 0 && !_levelState[a->condition])
return;
Common::Point origin = a->origin;
if (a->flag == "BITMAP")
loadImage(a->path, origin.x, origin.y);
else {
_nextMoviesToPlay.push_back(a->path);
_nextMoviesPositions.push_back(origin);
_nextMoviesScales.push_back(false);
}
}
void HypnoEngine::runWalN(const Hotspot h, WalN *a) {
if (a->condition.size() > 0 && !_levelState[a->condition])
return;
Common::Point origin = a->origin;
if (a->flag == "BITMAP")
loadImage(a->path, origin.x, origin.y);
else {
_nextMoviesToPlay.push_back(a->path);
_nextMoviesPositions.push_back(origin);
_nextMoviesScales.push_back(false);
}
}
void HypnoEngine::runQuit(const Hotspot h, Quit *a) {
quitGame();
} }
// Hotspots // Hotspots
@ -418,6 +498,9 @@ void HypnoEngine::clickedHotspot(Common::Point mousePos) {
_nextHotsToAdd = selected.smenu; _nextHotsToAdd = selected.smenu;
} }
if (!selected.setting.empty())
_nextSetting = selected.setting;
debug("hotspot clicked actions size: %d", selected.actions.size()); debug("hotspot clicked actions size: %d", selected.actions.size());
for (Actions::const_iterator itt = selected.actions.begin(); itt != selected.actions.end(); ++itt) { for (Actions::const_iterator itt = selected.actions.begin(); itt != selected.actions.end(); ++itt) {
Action *action = *itt; Action *action = *itt;
@ -425,12 +508,21 @@ void HypnoEngine::clickedHotspot(Common::Point mousePos) {
runEscape(selected, (Escape*) action); runEscape(selected, (Escape*) action);
if (typeid(*action) == typeid(Cutscene)) if (typeid(*action) == typeid(Cutscene))
runCutscene(selected, (Cutscene*) action); runCutscene(selected, (Cutscene*) action);
if (typeid(*action) == typeid(Play))
runPlay(selected, (Play*) action);
if (typeid(*action) == typeid(WalN))
runWalN(selected, (WalN*) action);
if (typeid(*action) == typeid(Global))
runGlobal(selected, (Global*) action);
} }
} }
} }
bool HypnoEngine::hoverHotspot(Common::Point mousePos) { bool HypnoEngine::hoverHotspot(Common::Point mousePos) {
if (stack.empty())
return false;
Hotspots *hots = stack.back(); Hotspots *hots = stack.back();
Hotspot selected; Hotspot selected;
bool found = false; bool found = false;
@ -466,7 +558,7 @@ bool HypnoEngine::hoverHotspot(Common::Point mousePos) {
void HypnoEngine::loadImage(const Common::String &name, int x, int y) { void HypnoEngine::loadImage(const Common::String &name, int x, int y) {
Graphics::Surface *surf = decodeFrame(name, 0); Graphics::Surface *surf = decodeFrame(name, 0);
_compositeSurface->transBlitFrom(*surf, _origin + Common::Point(x, y), _transparentColor); _compositeSurface->transBlitFrom(*surf, Common::Point(x, y), _transparentColor);
} }
Graphics::Surface *HypnoEngine::decodeFrame(const Common::String &name, int n, bool convert) { Graphics::Surface *HypnoEngine::decodeFrame(const Common::String &name, int n, bool convert) {
@ -476,27 +568,24 @@ Graphics::Surface *HypnoEngine::decodeFrame(const Common::String &name, int n, b
if (!file->open(path)) if (!file->open(path))
error("unable to find video file %s", path.c_str()); error("unable to find video file %s", path.c_str());
_videoDecoder = new Video::SmackerDecoder(); Video::SmackerDecoder vd;
if (!_videoDecoder->loadStream(file)) if (!vd.loadStream(file))
error("unable to load video %s", path.c_str()); error("unable to load video %s", path.c_str());
for(int f = 0; f < n; f++) for(int f = 0; f < n; f++)
_videoDecoder->decodeNextFrame(); vd.decodeNextFrame();
const Graphics::Surface *frame = _videoDecoder->decodeNextFrame(); const Graphics::Surface *frame = vd.decodeNextFrame();
Graphics::Surface *rframe; Graphics::Surface *rframe;
if (convert) { if (convert) {
rframe = frame->convertTo(_pixelFormat, _videoDecoder->getPalette()); rframe = frame->convertTo(_pixelFormat, vd.getPalette());
} else { } else {
rframe = frame->convertTo(frame->format, _videoDecoder->getPalette()); rframe = frame->convertTo(frame->format, vd.getPalette());
//rframe->create(frame->w, frame->h, frame->format); //rframe->create(frame->w, frame->h, frame->format);
//rframe->copyRectToSurface(frame->getPixels(), frame->pitch, 0, 0, frame->w, frame->h); //rframe->copyRectToSurface(frame->getPixels(), frame->pitch, 0, 0, frame->w, frame->h);
} }
delete _videoDecoder;
_videoDecoder = nullptr;
return rframe; return rframe;
} }
@ -506,21 +595,27 @@ void HypnoEngine::drawScreen() {
if (_videoDecoder && !_videoDecoder->isPaused()) { if (_videoDecoder && !_videoDecoder->isPaused()) {
const Graphics::Surface *frame = _videoDecoder->decodeNextFrame(); const Graphics::Surface *frame = _videoDecoder->decodeNextFrame();
Graphics::Surface *sframe = frame->scale(_screenW, _screenH); Graphics::Surface *sframe, *cframe;
Graphics::Surface *cframe = sframe->convertTo(_pixelFormat, _videoDecoder->getPalette());
Common::Point center(0, 0);
surface->blitFrom(*cframe, center);
sframe->free(); if (_movieScale) {
delete sframe; sframe = frame->scale(_screenW, _screenH);
cframe = sframe->convertTo(_pixelFormat, _videoDecoder->getPalette());
} else
cframe = frame->convertTo(_pixelFormat, _videoDecoder->getPalette());
debug("Move position: %d %d", _moviePosition.x, _moviePosition.y);
surface->blitFrom(*cframe, _moviePosition);
if (_movieScale) {
sframe->free();
delete sframe;
}
cframe->free(); cframe->free();
delete cframe; delete cframe;
} }
Common::Rect w(_origin.x, _origin.y, _screenW - _origin.x, _screenH - _origin.y); g_system->copyRectToScreen(surface->getPixels(), surface->pitch, 0, 0, _screenW, _screenH);
Graphics::Surface sa = surface->getSubArea(w);
g_system->copyRectToScreen(sa.getPixels(), sa.pitch, _origin.x, _origin.y, sa.w, sa.h);
g_system->updateScreen(); g_system->updateScreen();
} }

View File

@ -53,7 +53,6 @@ enum {
kHypnoDebugScript = 1 << 2 kHypnoDebugScript = 1 << 2
}; };
typedef Common::Array<byte> ByteArray; typedef Common::Array<byte> ByteArray;
typedef struct LibData { typedef struct LibData {
Common::Array<Common::String> filenames; Common::Array<Common::String> filenames;
@ -82,20 +81,18 @@ public:
Common::InstallShieldV3 _installerArchive; Common::InstallShieldV3 _installerArchive;
Common::Error run() override; Common::Error run() override;
void runIntro(Common::String logoIntro, Common::String movieIntro); Levels _levels;
Common::HashMap<Common::String, int> _levelState;
void resetLevelState();
bool checkLevelCompleted();
void runMis(Common::String name); void runMis(Common::String name);
void restartGame(); void restartGame();
void clearAreas(); void clearAreas();
void initializePath(const Common::FSNode &gamePath) override; void initializePath(const Common::FSNode &gamePath) override;
void loadMis(Common::String filename); void loadMis(Common::String filename);
LibData loadLib(char *filename); LibData loadLib(char *filename);
// Functions
void initFuncs();
// User input // User input
void clickedHotspot(Common::Point); void clickedHotspot(Common::Point);
bool hoverHotspot(Common::Point); bool hoverHotspot(Common::Point);
@ -116,9 +113,6 @@ public:
return true; return true;
} }
void ignoreEvents();
//Common::Error loadGameStream(Common::SeekableReadStream *stream) override;
//Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override;
void syncGameStream(Common::Serializer &s); void syncGameStream(Common::Serializer &s);
Common::String convertPath(const Common::String &); Common::String convertPath(const Common::String &);
@ -128,66 +122,59 @@ public:
Graphics::Surface *decodeImage(const Common::String &file); Graphics::Surface *decodeImage(const Common::String &file);
Graphics::Surface *decodeFrame(const Common::String &name, int frame, bool convert = true); Graphics::Surface *decodeFrame(const Common::String &name, int frame, bool convert = true);
void loadImage(const Common::String &file, int x, int y); void loadImage(const Common::String &file, int x, int y);
void drawScreenFrame();
// Cursors // Cursors
void changeCursor(const Common::String &, uint32); void changeCursor(const Common::String &, uint32);
Common::String getInventoryCursor();
Common::String getExitCursor();
// Actions // Actions
void runIntro();
void runMenu(Hotspots hs); void runMenu(Hotspots hs);
void runBackground(const Hotspot h, Background *a); void runBackground(const Hotspot h, Background *a);
void runOverlay(const Hotspot h, Overlay *a); void runOverlay(const Hotspot h, Overlay *a);
void runMice(const Hotspot h, Mice *a); void runMice(const Hotspot h, Mice *a);
void runEscape(const Hotspot h, Escape *a); void runEscape(const Hotspot h, Escape *a);
void runQuit(const Hotspot h, Quit *a);
void runCutscene(const Hotspot h, Cutscene *a); void runCutscene(const Hotspot h, Cutscene *a);
void runPlay(const Hotspot h, Play *a);
void runWalN(const Hotspot h, WalN *a);
void runGlobal(const Hotspot h, Global *a);
Graphics::ManagedSurface *_compositeSurface; Graphics::ManagedSurface *_compositeSurface;
Graphics::Surface *loadMask(const Common::String &, int, int, bool);
void drawMask(Graphics::Surface *);
void fillRect(uint32, Common::Rect);
bool inMask(Graphics::Surface *, Common::Point);
uint32 _transparentColor; uint32 _transparentColor;
Common::Rect screenRect; Common::Rect screenRect;
Common::String _framePath;
Graphics::Surface *_frame;
Common::String _nextVS;
Common::Point _origin;
void drawScreen(); void drawScreen();
// intros
Common::HashMap<Common::String, Movies> _intros;
// settings
Common::String _nextSetting;
Common::String _currentSetting;
// hotspots // hotspots
Hotspots *_nextHotsToAdd; Hotspots *_nextHotsToAdd;
Hotspots *_nextHotsToRemove; Hotspots *_nextHotsToRemove;
HotspotsStack stack; HotspotsStack stack;
// movies // Movies
Common::String _nextMovie; Movies _nextMoviesToPlay;
Common::List<Common::Point> _nextMoviesPositions;
Common::List<bool> _nextMoviesScales;
Common::Point _moviePosition;
bool _movieScale;
Common::String _currentMovie; Common::String _currentMovie;
// Save/Load games
int _mode;
bool _modified;
Common::String _repeatedMovieExit;
// Masks/Exits
// Sounds // Sounds
void playSound(const Common::String &, uint, bool, bool); void playSound(const Common::String &, uint, bool, bool);
void stopSound(bool); void stopSound(bool);
bool isSoundActive(); bool isSoundActive();
bool _noStopSounds; bool _noStopSounds;
// Random values
bool getRandomBool(uint);
// Timers // Timers
bool installTimer(uint32, Common::String *); bool installTimer(uint32, Common::String *);
void removeTimer(); void removeTimer();
}; };
//extern PrivateEngine *g_private;
} // End of namespace Hypno } // End of namespace Hypno
#endif #endif

View File

@ -54,11 +54,8 @@ OVER return OVERTOK;
SMEN return SMENTOK; SMEN return SMENTOK;
ESCP return ESCPTOK; ESCP return ESCPTOK;
PLAY return PLAYTOK; PLAY return PLAYTOK;
TURNON return TONTOK;
TURNOFF return TOFFTOK;
NO_RETURN return NRTOK; NO_RETURN return NRTOK;
GS_[A-Za-z_0-9]+ HYPNO_lval.s = scumm_strdup(HYPNO_text); return GSSWITCH; GS_[A-Z_0-9]+ HYPNO_lval.s = scumm_strdup(HYPNO_text); return GSSWITCH;
\/BITMAP return BITMAPTOK;
\/BBOX\= return BBOXTOK; \/BBOX\= return BBOXTOK;
\/[A-Za-z_0-9]* HYPNO_lval.s = scumm_strdup(HYPNO_text); return FLAG; \/[A-Za-z_0-9]* HYPNO_lval.s = scumm_strdup(HYPNO_text); return FLAG;
[A-Za-z_][A-Za-z_0-9]* HYPNO_lval.s = scumm_strdup(HYPNO_text); return NAME; [A-Za-z_][A-Za-z_0-9]* HYPNO_lval.s = scumm_strdup(HYPNO_text); return NAME;