From fc71730e174cbe106f1cd3a9be3dd1c72c3c9864 Mon Sep 17 00:00:00 2001 From: neuromancer Date: Mon, 4 Jan 2021 08:14:40 -0300 Subject: [PATCH] PRIVATE: more functions and fixes --- engines/private/code.cpp | 17 +++++++---- engines/private/funcs.cpp | 23 ++++++++++++++- engines/private/grammar.h | 5 ++-- engines/private/grammar.y | 56 ++++++++++++++++++++++--------------- engines/private/private.cpp | 45 +++++++++++++++++++---------- engines/private/private.h | 2 ++ 6 files changed, 104 insertions(+), 44 deletions(-) diff --git a/engines/private/code.cpp b/engines/private/code.cpp index 4ba7d6cfdad..2331b52bf40 100644 --- a/engines/private/code.cpp +++ b/engines/private/code.cpp @@ -125,8 +125,8 @@ int eval() /* evaluate variable on stack */ else if (d.sym->type == STRING) d.str = d.sym->u.str; else if (d.sym->type == NAME) { - debug("NAME"); - d.sym = d.sym; + //debug("NAME %s", d.sym->name->c_str()); + //d.sym = d.sym; } else assert(0); @@ -151,7 +151,9 @@ int negate() { Datum d; d = pop(); - d.val = !d.val; + debug("negating %s", d.sym->name->c_str()); + int v = d.sym->u.val; + d.val = !v; push(d); return 0; } @@ -232,6 +234,7 @@ int ne() Inst *code(Inst f) /* install one instruction or operand */ { + //debug("pushing code at %d", progp); Inst *oprogp = progp; assert (!(progp >= &prog[NPROG])); *progp++ = f; @@ -245,14 +248,18 @@ int ifcode() execute(savepc+3); /* condition */ d = pop(); - debug("ifcode %s %d", d.sym->name->c_str(), d.sym->u.val); + debug("ifcode %s", d.sym->name->c_str()); //, d.sym->u.val); d.val = d.sym->u.val; - debug("then: %x", *((Inst **)(savepc))); + //debug("ptr: %x", *((Inst **)(savepc+1))); + //debug("ptr: %x", *((Inst **)(savepc+2))); + //debug("ptr: %x", *((Inst **)(savepc+3))); + //assert(0); if (d.val) execute(*((Inst **)(savepc))); else if (*((Inst **)(savepc+1))) /* else part? */ execute(*((Inst **)(savepc+1))); + debug("finish if"); pc = *((Inst **)(savepc+2)); /* next stmt */ return 0; } diff --git a/engines/private/funcs.cpp b/engines/private/funcs.cpp index 960d14e42ba..f304d006c64 100644 --- a/engines/private/funcs.cpp +++ b/engines/private/funcs.cpp @@ -25,6 +25,13 @@ void SetFlag(ArgArray args) { args[0].sym->u.val = args[1].val; } +void SetModifiedFlag(ArgArray args) { + debug("SetModifiedFlag(%d)", args[0].val); + _modified = (bool) args[0].val; +} + + + void Sound(ArgArray args) { debug("Sound(%s)", args[0].str); if (strcmp("\"\"", args[0].str) != 0) { @@ -36,6 +43,12 @@ void Sound(ArgArray args) { } } +void Transition(ArgArray args) { + debug("Transition(%s, %s)", args[0].str, args[1].str); + _nextMovie = new Common::String(args[0].str); + _nextSetting = new Common::String(args[1].str); +} + void Bitmap(ArgArray args) { assert(args.size() == 1 || args.size() == 3); @@ -81,11 +94,19 @@ void execFunction(char *name, ArgArray args) { else if (strcmp(name, "Timer") == 0) { Timer(args); } + else if (strcmp(name, "Transition") == 0) { + Transition(args); + } + else if (strcmp(name, "SetModifiedFlag") == 0) { + SetModifiedFlag(args); + } else if (strcmp(name, "Exit") == 0) { ; } - else + else { + debug("I don't know how to exec %s", name); assert(0); + } } diff --git a/engines/private/grammar.h b/engines/private/grammar.h index 5bcf53ae0df..393309f44c2 100644 --- a/engines/private/grammar.h +++ b/engines/private/grammar.h @@ -74,8 +74,7 @@ extern void execFunction(char *, ArgArray); // Code Generation extern Datum pop(); -extern int pushString(char *); -extern int pushInt(int); +extern Inst *progp; extern Inst *code(Inst); extern Inst *prog; @@ -94,6 +93,8 @@ extern int ifcode(); extern int fail(); extern int lt(); extern int gt(); +extern int le(); +extern int ge(); // Code Execution diff --git a/engines/private/grammar.y b/engines/private/grammar.y index 687ae6400a6..eb4af459272 100644 --- a/engines/private/grammar.y +++ b/engines/private/grammar.y @@ -37,7 +37,7 @@ int yywrap() %union { struct Symbol *sym; /* symbol table pointer */ - int (*inst)(); /* machine instruction */ + int (**inst)(); /* machine instruction */ char *s; int *i; int narg; @@ -45,7 +45,7 @@ int yywrap() %token NAME %token STRING NUM -//%type value cond expr if +%type body if cond end expr statements statement fcall value %token LTE GTE NEQ EQ FALSETOK TRUETOK IFTOK ELSETOK RECTTOK GOTOTOK DEBUGTOK DEFINETOK SETTINGTOK RANDOMTOK %type params @@ -64,30 +64,40 @@ debug: /* nothing */ | NAME ',' debug ; -statements: /* nothing */ - | statements statement +statements: /* nothing */ { $$ = progp; } + | statement statements -statement: GOTOTOK expr ';' - | fcall ';' - | if cond statement end - | if cond body end ELSETOK body end - | if cond body end - | if cond body end ELSETOK statement end - | if cond statement end ELSETOK statement end - | if cond statement end ELSETOK body end +statement: GOTOTOK expr ';' { code(fail); } + | fcall ';' { $$ = $1; } + | if cond statement end { /* else-less if */ + ($1)[1] = (Inst)$3; /* thenpart */ + ($1)[3] = (Inst)$4; } /* end, if cond fails */ + | if cond body end ELSETOK body end { /* if with else */ + ($1)[1] = (Inst)$3; /* thenpart */ + ($1)[2] = (Inst)$6; /* elsepart */ + ($1)[3] = (Inst)$7; } /* end, if cond fails */ + | if cond body end { /* else-less if */ + ($1)[1] = (Inst)$3; /* thenpart */ + ($1)[3] = (Inst)$4; } /* end, if cond fails */ + | if cond body end ELSETOK statement end { /* if with else */ + ($1)[1] = (Inst)$3; /* thenpart */ + ($1)[2] = (Inst)$6; /* elsepart */ + ($1)[3] = (Inst)$7; } /* end, if cond fails */ + | if cond statement end ELSETOK statement end { code(fail); } + | if cond statement end ELSETOK body end { code(fail); } ; -body: '{' statements '}' +body: '{' statements '}' { $$ = $2; } ; -end: /* nothing */ { code(STOP);} +end: /* nothing */ { code(STOP); $$ = progp; } ; -if: IFTOK { code(ifcode); code3(STOP, STOP, STOP); /*code(fail);*/ } +if: IFTOK { $$ = code(ifcode); code3(STOP, STOP, STOP); } ; -cond: '(' expr ')' { code(STOP); } +cond: '(' expr ')' { code(STOP); $$ = $2; } ; define: /* nothing */ @@ -98,14 +108,16 @@ define: /* nothing */ ; fcall: GOTOTOK '(' NAME ')' { + $$ = progp; code2(Private::strpush, (Private::Inst) Private::addconstant(STRING, 0, $NAME)); code2(Private::constpush, (Private::Inst) Private::addconstant(NUM, 1, NULL)); code2(Private::strpush, (Private::Inst) Private::addconstant(STRING, 0, "goto")); - code1(Private::funcpush); + code1(Private::funcpush); } | RECTTOK '(' NUM ',' NUM ',' NUM ',' NUM ')' | NAME '(' params ')' { + $$ = progp; code2(Private::constpush, (Private::Inst) Private::addconstant(NUM, $params, NULL)); code2(Private::strpush, (Private::Inst) Private::addconstant(STRING, 0, $NAME)); code1(Private::funcpush); @@ -126,15 +138,15 @@ value: FALSETOK { code2(Private::constpush, (Private::Inst) Private::addconst | NAME { code1(Private::varpush); code1((Private::Inst) lookupName($NAME)); code1(Private::eval); } ; -expr: value - | '!' value { code1(Private::negate); } +expr: value { $$ = $1; } + | '!' value { code1(Private::negate); $$ = $2; } | value EQ value | value NEQ value | value '+' value { code1(Private::add); } | value '<' value { code1(Private::lt); } | value '>' value { code1(Private::gt); } - | value LTE value - | value GTE value - | value '+' + | value LTE value { code1(Private::le); } + | value GTE value { code1(Private::ge); } + | value '+' | RANDOMTOK '(' NUM '%' ')' ; diff --git a/engines/private/private.cpp b/engines/private/private.cpp index 5ab6b8e5b7e..68358b6f0ae 100644 --- a/engines/private/private.cpp +++ b/engines/private/private.cpp @@ -26,6 +26,8 @@ extern int yyparse(); namespace Private { Common::String *_nextSetting = NULL; +Common::String *_nextMovie = NULL; +bool _modified = false; int _mode = -1; PrivateEngine *_private = NULL; @@ -36,7 +38,9 @@ Common::String convertPath(Common::String name) { Common::String s1("\\"); Common::String s2("/"); - Common::replace(path, s1, s2); + while (path.contains(s1)) + Common::replace(path, s1, s2); + s1 = Common::String("\""); s2 = Common::String(""); @@ -103,7 +107,7 @@ Common::Error PrivateEngine::run() { _image = new Image::BitmapDecoder(); _compositeSurface = new Graphics::ManagedSurface(); _compositeSurface->create(_screenW, _screenH, _pixelFormat); - _compositeSurface->setTransparentColor(0); + _compositeSurface->setTransparentColor(0x00ff00); // You could use backend transactions directly as an alternative, // but it isn't recommended, until you want to handle the error values @@ -147,7 +151,17 @@ Common::Error PrivateEngine::run() { g_system->getEventManager()->pollEvent(evt); g_system->delayMillis(10); + + if (_nextMovie != NULL) { + //_videoDecoder = new Video::SmackerDecoder(); + //playVideo(*_nextMovie); + _nextMovie = NULL; + continue; + + } + if (_videoDecoder) { + stopSound(); if (_videoDecoder->endOfVideo()) { _videoDecoder->close(); delete _videoDecoder; @@ -155,6 +169,7 @@ Common::Error PrivateEngine::run() { } else if (_videoDecoder->needsUpdate()) { drawScreen(); } + continue; } //if (_compositeSurface) @@ -216,11 +231,13 @@ void PrivateEngine::playSound(const Common::String &name) { void PrivateEngine::playVideo(const Common::String &name) { debugC(1, kPrivateDebugExample, "%s : %s", __FUNCTION__, name.c_str()); Common::File *file = new Common::File(); - if (!file->open(name)) - error("unable to find video file %s", name.c_str()); + Common::String path = convertPath(name); + + if (!file->open(path)) + error("unable to find video file %s", path.c_str()); if (!_videoDecoder->loadStream(file)) - error("unable to load video %s", name.c_str()); + error("unable to load video %s", path.c_str()); _videoDecoder->start(); } @@ -243,7 +260,7 @@ void PrivateEngine::loadImage(const Common::String &name, int x, int y) { //for (int i = 0; i < 30; i=i+3) // debug("%x %x %x", *(_image->getPalette()+i), *(_image->getPalette()+i+1), *(_image->getPalette()+i+2)); - _compositeSurface->transBlitFrom(*_image->getSurface()->convertTo(_pixelFormat, _image->getPalette()), Common::Point(x,y)); + _compositeSurface->transBlitFrom(*_image->getSurface()->convertTo(_pixelFormat, _image->getPalette()), Common::Point(x,y), _pixelFormat.RGBToColor(0,255,0)); drawScreen(); } @@ -253,14 +270,14 @@ void PrivateEngine::drawScreen() { Graphics::Surface *screen = g_system->lockScreen(); //screen->fillRect(Common::Rect(0, 0, g_system->getWidth(), g_system->getHeight()), 0); - const Graphics::ManagedSurface *surface; - /*if (_videoDecoder) - surface = _videoDecoder->decodeNextFrame(); - else*/ if (_compositeSurface) - surface = _compositeSurface; - else - assert(0); - // surface = _image->getSurface(); + Graphics::ManagedSurface *surface = _compositeSurface; + + if (_videoDecoder) { + Graphics::Surface *frame = new Graphics::Surface; + frame->create(_screenW, _screenH, _pixelFormat); + frame->copyFrom(*_videoDecoder->decodeNextFrame()); + surface->transBlitFrom(*frame->convertTo(_pixelFormat, _videoDecoder->getPalette())); + } int w = surface->w; //CLIP(surface->w, 0, _screenW); int h = surface->h; //CLIP(surface->h, 0, _screenH); diff --git a/engines/private/private.h b/engines/private/private.h index 5e0af55078e..256e042f7fb 100644 --- a/engines/private/private.h +++ b/engines/private/private.h @@ -36,6 +36,8 @@ enum { // global state extern Common::String *_nextSetting; extern int _mode; +extern bool _modified; +extern Common::String *_nextMovie; class PrivateEngine : public Engine { private: