PRIVATE: more functions and fixes

This commit is contained in:
neuromancer 2021-01-04 08:14:40 -03:00 committed by Eugene Sandulenko
parent 68ad8f1ad0
commit fc71730e17
6 changed files with 104 additions and 44 deletions

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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<s> NAME
%token<sym> STRING NUM
//%type <inst> value cond expr if
%type <inst> 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<narg> 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 '%' ')'
;

View File

@ -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<int>(surface->w, 0, _screenW);
int h = surface->h; //CLIP<int>(surface->h, 0, _screenH);

View File

@ -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: