1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef DIRECTOR_LINGO_LINGO_H 24 #define DIRECTOR_LINGO_LINGO_H 25 26 #include "audio/audiostream.h" 27 #include "common/hash-ptr.h" 28 #include "common/hash-str.h" 29 30 #include "director/director.h" 31 #include "director/score.h" 32 #include "director/lingo/lingo-gr.h" 33 #include "director/lingo/lingo-the.h" 34 35 namespace Director { 36 37 enum LEvent { 38 kEventPrepareMovie, 39 kEventStartMovie, 40 kEventStepMovie, 41 kEventStopMovie, 42 43 kEventNew, 44 kEventBeginSprite, 45 kEventEndSprite, 46 47 kEventNone, 48 kEventEnterFrame, 49 kEventPrepareFrame, 50 kEventIdle, 51 kEventStepFrame, 52 kEventExitFrame, 53 kEventTimeout, 54 55 kEventActivateWindow, 56 kEventDeactivateWindow, 57 kEventMoveWindow, 58 kEventResizeWindow, 59 kEventOpenWindow, 60 kEventCloseWindow, 61 62 kEventKeyUp, 63 kEventKeyDown, 64 kEventMouseUp, 65 kEventMouseDown, 66 kEventRightMouseUp, 67 kEventRightMouseDown, 68 kEventMouseEnter, 69 kEventMouseLeave, 70 kEventMouseUpOutSide, 71 kEventMouseWithin, 72 73 kEventStart 74 }; 75 76 typedef void (*inst)(void); 77 #define STOP (inst)0 78 #define ENTITY_INDEX(t,id) ((t) * 100000 + (id)) 79 80 typedef Common::Array<inst> ScriptData; 81 typedef Common::Array<double> FloatArray; 82 83 struct FuncDesc { 84 Common::String name; 85 const char *proto; 86 FuncDescFuncDesc87 FuncDesc(Common::String n, const char *p) { name = n; proto = p; } 88 }; 89 90 typedef Common::HashMap<void *, FuncDesc *> FuncHash; 91 92 struct Symbol { /* symbol table entry */ 93 Common::String name; 94 int type; 95 union { 96 int i; /* VAR */ 97 double f; /* FLOAT */ 98 ScriptData *defn; /* FUNCTION, PROCEDURE */ 99 void (*func)(); /* OPCODE */ 100 void (*bltin)(int); /* BUILTIN */ 101 Common::String *s; /* STRING */ 102 FloatArray *arr; /* ARRAY, POINT, RECT */ 103 } u; 104 int nargs; /* number of arguments */ 105 int maxArgs; /* maximal number of arguments, for builtins */ 106 bool parens; /* whether parens required or not, for builitins */ 107 108 bool global; 109 110 Symbol(); 111 }; 112 113 struct Datum { /* interpreter stack type */ 114 int type; 115 116 union { 117 int i; 118 double f; 119 Common::String *s; 120 Symbol *sym; 121 FloatArray *arr; /* ARRAY, POINT, RECT */ 122 } u; 123 DatumDatum124 Datum() { u.sym = NULL; type = VOID; } DatumDatum125 Datum(int val) { u.i = val; type = INT; } DatumDatum126 Datum(double val) { u.f = val; type = FLOAT; } DatumDatum127 Datum(Common::String *val) { u.s = val; type = STRING; } 128 129 double toFloat(); 130 int toInt(); 131 Common::String *toString(); 132 133 const char *type2str(bool isk = false); 134 }; 135 136 struct Builtin { 137 void (*func)(void); 138 int nargs; 139 BuiltinBuiltin140 Builtin(void (*func1)(void), int nargs1) : func(func1), nargs(nargs1) {} 141 }; 142 143 typedef Common::HashMap<int32, ScriptData *> ScriptHash; 144 typedef Common::Array<Datum> StackData; 145 typedef Common::HashMap<Common::String, Symbol *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SymbolHash; 146 typedef Common::HashMap<Common::String, Builtin *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> BuiltinHash; 147 148 typedef Common::HashMap<Common::String, TheEntity *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> TheEntityHash; 149 typedef Common::HashMap<Common::String, TheEntityField *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> TheEntityFieldHash; 150 151 struct CFrame { /* proc/func call stack frame */ 152 Symbol *sp; /* symbol table entry */ 153 int retpc; /* where to resume after return */ 154 ScriptData *retscript; /* which script to resume after return */ 155 SymbolHash *localvars; 156 }; 157 158 class Lingo { 159 public: 160 Lingo(DirectorEngine *vm); 161 ~Lingo(); 162 163 void restartLingo(); 164 165 void addCode(const char *code, ScriptType type, uint16 id); 166 void executeScript(ScriptType type, uint16 id); 167 void printStack(const char *s); 168 Common::String decodeInstruction(uint pc, uint *newPC = NULL); 169 170 void initBuiltIns(); 171 void initFuncs(); 172 void initTheEntities(); 173 174 void runTests(); 175 176 private: 177 const char *findNextDefinition(const char *s); 178 179 // lingo-events.cpp 180 private: 181 void initEventHandlerTypes(); 182 void primaryEventHandler(LEvent event); 183 void processInputEvent(LEvent event); 184 void processFrameEvent(LEvent event); 185 void processGenericEvent(LEvent event); 186 void runMovieScript(LEvent event); 187 void processSpriteEvent(LEvent event); 188 void processEvent(LEvent event, ScriptType st, int entityId); 189 public: 190 ScriptType event2script(LEvent ev); 191 Symbol *getHandler(Common::String &name); 192 193 void processEvent(LEvent event); 194 195 public: 196 void execute(uint pc); 197 void pushContext(); 198 void popContext(); 199 Symbol *lookupVar(const char *name, bool create = true, bool putInGlobalList = false); 200 void cleanLocalVars(); 201 void define(Common::String &s, int start, int nargs, Common::String *prefix = NULL, int end = -1); 202 void processIf(int elselabel, int endlabel); 203 204 int alignTypes(Datum &d1, Datum &d2); 205 code1(inst code)206 int code1(inst code) { _currentScript->push_back(code); return _currentScript->size() - 1; } code2(inst code_1,inst code_2)207 int code2(inst code_1, inst code_2) { int o = code1(code_1); code1(code_2); return o; } code3(inst code_1,inst code_2,inst code_3)208 int code3(inst code_1, inst code_2, inst code_3) { int o = code1(code_1); code1(code_2); code1(code_3); return o; } 209 int codeString(const char *s); 210 void codeLabel(int label); 211 int codeConst(int val); 212 int codeArray(int arraySize); 213 calcStringAlignment(const char * s)214 int calcStringAlignment(const char *s) { 215 return calcCodeAlignment(strlen(s) + 1); 216 } calcCodeAlignment(int l)217 int calcCodeAlignment(int l) { 218 int instLen = sizeof(inst); 219 return (l + instLen - 1) / instLen; 220 } 221 222 void codeArg(Common::String *s); 223 void codeArgStore(); 224 int codeSetImmediate(bool state); 225 int codeFunc(Common::String *s, int numpar); 226 int codeMe(Common::String *method, int numpar); 227 int codeFloat(double f); 228 void codeFactory(Common::String &s); 229 230 void pushVoid(); 231 232 static void c_xpop(); 233 static void c_printtop(); 234 235 static void c_add(); 236 static void c_sub(); 237 static void c_mul(); 238 static void c_div(); 239 static void c_mod(); 240 static void c_negate(); 241 242 static void c_and(); 243 static void c_or(); 244 static void c_not(); 245 246 static void c_ampersand(); 247 static void c_after(); 248 static void c_before(); 249 static void c_concat(); 250 static void c_contains(); 251 static void c_starts(); 252 253 static void c_intersects(); 254 static void c_within(); 255 static void c_charOf(); 256 static void c_charToOf(); 257 static void c_itemOf(); 258 static void c_itemToOf(); 259 static void c_lineOf(); 260 static void c_lineToOf(); 261 static void c_wordOf(); 262 static void c_wordToOf(); 263 264 static void c_constpush(); 265 static void c_voidpush(); 266 static void c_fconstpush(); 267 static void c_stringpush(); 268 static void c_symbolpush(); 269 static void c_varpush(); 270 static void c_arraypush(); 271 static void c_assign(); 272 bool verify(Symbol *s); 273 static void c_eval(); 274 static void c_setImmediate(); 275 276 static void c_swap(); 277 278 static void c_theentitypush(); 279 static void c_theentityassign(); 280 281 static void c_repeatwhilecode(); 282 static void c_repeatwithcode(); 283 static void c_ifcode(); 284 static void c_whencode(); 285 static void c_tellcode(); 286 static void c_exitRepeat(); 287 static void c_eq(); 288 static void c_neq(); 289 static void c_gt(); 290 static void c_lt(); 291 static void c_ge(); 292 static void c_le(); 293 static void c_call(); 294 295 void call(Common::String name, int nargs); 296 297 static void c_procret(); 298 299 static void c_mci(); 300 static void c_mciwait(); 301 static void c_goto(); 302 static void c_gotoloop(); 303 static void c_gotonext(); 304 static void c_gotoprevious(); 305 static void c_global(); 306 static void c_instance(); 307 static void c_property(); 308 309 static void c_play(); 310 static void c_playdone(); 311 312 static void c_open(); 313 314 void printSTUBWithArglist(const char *funcname, int nargs, const char *prefix = "STUB:"); 315 void convertVOIDtoString(int arg, int nargs); 316 void dropStack(int nargs); 317 void drop(uint num); 318 319 static void b_abs(int nargs); 320 static void b_atan(int nargs); 321 static void b_cos(int nargs); 322 static void b_exp(int nargs); 323 static void b_float(int nargs); 324 static void b_integer(int nargs); 325 static void b_log(int nargs); 326 static void b_pi(int nargs); 327 static void b_power(int nargs); 328 static void b_random(int nargs); 329 static void b_sin(int nargs); 330 static void b_sqrt(int nargs); 331 static void b_tan(int nargs); 332 333 static void b_chars(int nargs); 334 static void b_charToNum(int nargs); 335 static void b_delete(int nargs); 336 static void b_hilite(int nargs); 337 static void b_length(int nargs); 338 static void b_numToChar(int nargs); 339 static void b_offset(int nargs); 340 static void b_string(int nargs); 341 342 static void b_add(int nargs); 343 static void b_addAt(int nargs); 344 static void b_addProp(int nargs); 345 static void b_append(int nargs); 346 static void b_count(int nargs); 347 static void b_deleteAt(int nargs); 348 static void b_deleteProp(int nargs); 349 static void b_findPos(int nargs); 350 static void b_findPosNear(int nargs); 351 static void b_getaProp(int nargs); 352 static void b_getAt(int nargs); 353 static void b_getLast(int nargs); 354 static void b_getOne(int nargs); 355 static void b_getPos(int nargs); 356 static void b_getProp(int nargs); 357 static void b_getPropAt(int nargs); 358 static void b_list(int nargs); 359 static void b_listP(int nargs); 360 static void b_max(int nargs); 361 static void b_min(int nargs); 362 static void b_setaProp(int nargs); 363 static void b_setAt(int nargs); 364 static void b_setProp(int nargs); 365 static void b_sort(int nargs); 366 367 static void b_floatP(int nargs); 368 static void b_ilk(int nargs); 369 static void b_integerp(int nargs); 370 static void b_objectp(int nargs); 371 static void b_pictureP(int nargs); 372 static void b_stringp(int nargs); 373 static void b_symbolp(int nargs); 374 static void b_voidP(int nargs); 375 376 static void b_alert(int nargs); 377 static void b_birth(int nargs); 378 static void b_clearGlobals(int nargs); 379 static void b_cursor(int nargs); 380 static void b_framesToHMS(int nargs); 381 static void b_HMStoFrames(int nargs); 382 static void b_param(int nargs); 383 static void b_printFrom(int nargs); 384 static void b_showGlobals(int nargs); 385 static void b_showLocals(int nargs); 386 static void b_value(int nargs); 387 388 static void b_constrainH(int nargs); 389 static void b_constrainV(int nargs); 390 static void b_copyToClipBoard(int nargs); 391 static void b_duplicate(int nargs); 392 static void b_editableText(int nargs); 393 static void b_erase(int nargs); 394 static void b_findEmpty(int nargs); 395 static void b_importFileInto(int nargs); 396 static void b_installMenu(int nargs); 397 static void b_label(int nargs); 398 static void b_marker(int nargs); 399 static void b_move(int nargs); 400 static void b_moveableSprite(int nargs); 401 static void b_pasteClipBoardInto(int nargs); 402 static void b_puppetPalette(int nargs); 403 static void b_puppetSound(int nargs); 404 static void b_puppetSprite(int nargs); 405 static void b_puppetTempo(int nargs); 406 static void b_puppetTransition(int nargs); 407 static void b_ramNeeded(int nargs); 408 static void b_rollOver(int nargs); 409 static void b_spriteBox(int nargs); 410 static void b_unLoad(int nargs); 411 static void b_unLoadCast(int nargs); 412 static void b_updateStage(int nargs); 413 static void b_zoomBox(int nargs); 414 415 static void b_abort(int nargs); 416 static void b_continue(int nargs); 417 static void b_dontPassEvent(int nargs); 418 static void b_delay(int nargs); 419 static void b_do(int nargs); 420 static void b_halt(int nargs); 421 static void b_nothing(int nargs); 422 static void b_pass(int nargs); 423 static void b_pause(int nargs); 424 static void b_playAccel(int nargs); 425 static void b_preLoad(int nargs); 426 static void b_preLoadCast(int nargs); 427 static void b_quit(int nargs); 428 static void b_restart(int nargs); 429 static void b_shutDown(int nargs); 430 static void b_startTimer(int nargs); 431 432 static void b_closeDA(int nargs); 433 static void b_closeResFile(int nargs); 434 static void b_closeXlib(int nargs); 435 static void b_getNthFileNameInFolder(int nargs); 436 static void b_openDA(int nargs); 437 static void b_openResFile(int nargs); 438 static void b_openXlib(int nargs); 439 static void b_setCallBack(int nargs); 440 static void b_saveMovie(int nargs); 441 static void b_showResFile(int nargs); 442 static void b_showXlib(int nargs); 443 static void b_xFactoryList(int nargs); 444 445 static void b_point(int nargs); 446 static void b_inside(int nargs); 447 static void b_intersect(int nargs); 448 static void b_map(int nargs); 449 static void b_offsetRect(int nargs); 450 static void b_rect(int nargs); 451 static void b_union(int nargs); 452 453 static void b_close(int nargs); 454 static void b_forget(int nargs); 455 static void b_inflate(int nargs); 456 static void b_moveToBack(int nargs); 457 static void b_moveToFront(int nargs); 458 static void b_window(int nargs); 459 460 static void b_beep(int nargs); 461 static void b_mci(int nargs); 462 static void b_mciwait(int nargs); 463 static void b_soundBusy(int nargs); 464 static void b_soundClose(int nargs); 465 static void b_soundFadeIn(int nargs); 466 static void b_soundFadeOut(int nargs); 467 static void b_soundPlayFile(int nargs); 468 static void b_soundStop(int nargs); 469 470 static void b_ancestor(int nargs); 471 static void b_backspace(int nargs); 472 static void b_empty(int nargs); 473 static void b_enter(int nargs); 474 static void b_false(int nargs); 475 static void b_quote(int nargs); 476 static void b_return(int nargs); 477 static void b_tab(int nargs); 478 static void b_true(int nargs); 479 static void b_version(int nargs); 480 481 static void b_factory(int nargs); 482 void factoryCall(Common::String &name, int nargs); 483 484 static void b_cast(int nargs); 485 static void b_field(int nargs); 486 static void b_me(int nargs); 487 static void b_script(int nargs); 488 489 void func_mci(Common::String &s); 490 void func_mciwait(Common::String &s); 491 void func_beep(int repeats); 492 void func_goto(Datum &frame, Datum &movie); 493 void func_gotoloop(); 494 void func_gotonext(); 495 void func_gotoprevious(); 496 void func_play(Datum &frame, Datum &movie); 497 void func_playdone(); 498 void func_cursor(int c); 499 int func_marker(int m); 500 501 public: 502 void setTheEntity(int entity, Datum &id, int field, Datum &d); 503 void setTheSprite(Datum &id, int field, Datum &d); 504 void setTheCast(Datum &id, int field, Datum &d); 505 Datum getTheEntity(int entity, Datum &id, int field); 506 Datum getTheSprite(Datum &id, int field); 507 Datum getTheCast(Datum &id, int field); 508 509 public: 510 ScriptData *_currentScript; 511 ScriptType _currentScriptType; 512 uint16 _currentEntityId; 513 bool _returning; 514 bool _indef; 515 bool _ignoreMe; 516 bool _immediateMode; 517 518 Common::Array<CFrame *> _callstack; 519 Common::Array<Common::String *> _argstack; 520 TheEntityHash _theEntities; 521 TheEntityFieldHash _theEntityFields; 522 Common::Array<int> _labelstack; 523 524 SymbolHash _builtins; 525 Common::HashMap<Common::String, bool> _twoWordBuiltins; 526 Common::HashMap<uint32, Symbol *> _handlers; 527 528 int _linenumber; 529 int _colnumber; 530 531 Common::String _floatPrecisionFormat; 532 533 bool _hadError; 534 535 bool _inFactory; 536 Common::String _currentFactory; 537 538 bool _exitRepeat; 539 540 bool _cursorOnStack; 541 542 private: 543 int parse(const char *code); 544 void parseMenu(const char *code); 545 546 void push(Datum d); 547 Datum pop(void); 548 549 Common::HashMap<uint32, const char *> _eventHandlerTypes; 550 Common::HashMap<Common::String, uint32> _eventHandlerTypeIds; 551 Common::HashMap<Common::String, Audio::AudioStream *> _audioAliases; 552 553 ScriptHash _scripts[kMaxScriptType + 1]; 554 555 SymbolHash _globalvars; 556 SymbolHash *_localvars; 557 558 FuncHash _functions; 559 560 uint _pc; 561 562 StackData _stack; 563 564 DirectorEngine *_vm; 565 566 int _floatPrecision; 567 568 bool dontPassEvent; 569 570 public: 571 void executeImmediateScripts(Frame *frame); 572 }; 573 574 extern Lingo *g_lingo; 575 576 } // End of namespace Director 577 578 #endif 579