27 #include "common/endian.h" 29 #include "saga/font.h" 33 #define COMMON_BUFFER_SIZE 1024 // Why 1024? 35 #define SCRIPT_TBLENTRY_LEN 4 37 #define SCRIPT_MAX 5000 39 #define ITE_SCRIPT_FUNCTION_MAX 78 40 #define IHNM_SCRIPT_FUNCTION_MAX 105 69 #define STHREAD_TIMESLICE 8 73 kThreadVarWithObject = 1,
77 kThreadVarMax = kThreadVarActor + 1
85 kTFlagAsleep = kTFlagWaiting | kTFlagFinished | kTFlagAborted
88 enum ThreadWaitTypes {
92 kWaitTypeDialogEnd = 3,
93 kWaitTypeDialogBegin = 4,
98 kWaitTypeStatusTextInput = 9,
99 kWaitTypeWaitFrames = 10,
106 kCycleRandom = 1 << 2,
107 kCycleReverse = 1 << 3
111 kWalkBackPedal = 1 << 0,
113 kWalkUseAngle = 1 << 2,
119 kReplySummary = 1 << 1,
120 kReplyCondition = 1 << 2
132 int scriptResourceId;
133 int stringsResourceId;
134 int voicesResourceId;
152 ModuleData() : loaded(
false), scriptResourceId(0), stringsResourceId(0), voicesResourceId(0), staticSize(0), staticOffset(0) {
160 uint16 _stackTopIndex = 0;
161 uint16 _frameIndex = 0;
163 uint16 _threadVars[kThreadVarMax];
165 byte *_moduleBase = 0;
166 uint16 _moduleBaseSize = 0;
168 byte *_commonBase =
nullptr;
169 byte *_staticBase =
nullptr;
170 VoiceLUT *_voiceLUT =
nullptr;
176 void *_threadObj =
nullptr;
178 int16 _returnValue = 0;
180 uint16 _instructionOffset = 0;
182 int32 _frameWait = 0;
185 THREAD_STACK_SIZE = 256
189 byte *baseAddress(byte addrMode) {
198 return (byte *)&_stackBuf[_frameIndex];
200 return (byte *)_threadVars;
207 return _stackBuf[_stackTopIndex];
211 return THREAD_STACK_SIZE - _stackTopIndex - 2;
214 void push(int16 value) {
215 if (_stackTopIndex <= 0) {
216 error(
"ScriptThread::push() stack overflow");
218 _stackBuf[--_stackTopIndex] = value;
222 if (_stackTopIndex >= THREAD_STACK_SIZE) {
223 error(
"ScriptThread::pop() stack underflow");
225 return _stackBuf[_stackTopIndex++];
230 void wait(
int waitType) {
231 _waitType = waitType;
232 _flags |= kTFlagWaiting;
235 void waitWalk(
void *threadObj) {
236 debug(3,
"waitWalk()");
238 _threadObj = threadObj;
241 void waitDelay(
int sleepTime) {
242 debug(3,
"waitDelay(%d)", sleepTime);
243 wait(kWaitTypeDelay);
244 _sleepTime = sleepTime;
247 void waitFrames(
int frames) {
248 debug(3,
"waitFrames(%d)", frames);
249 wait(kWaitTypeWaitFrames);
254 memset(&_frameIndex, 0xFE,
sizeof(_frameIndex));
255 memset(_threadVars, 0xFE,
sizeof(_threadVars));
256 memset(&_waitType, 0xFE,
sizeof(_waitType));
257 memset(&_sleepTime, 0xFE,
sizeof(_sleepTime));
258 memset(&_threadObj, 0xFE,
sizeof(_threadObj));
259 memset(&_returnValue, 0xFE,
sizeof(_returnValue));
260 memset(&_frameWait, 0xFE,
sizeof(_frameWait));
268 #define SCRIPTOP_PARAMS ScriptThread *thread, Common::SeekableReadStream *scriptS, bool &stopParsing, bool &breakOut 269 #define SCRIPTFUNC_PARAMS ScriptThread *thread, int nArgs, bool &disContinue 270 #define OPCODE(x) {&Script::x, #x} 279 void loadModule(uint scriptModuleNumber);
283 void showVerb(
int statusColor = -1);
284 void setVerb(
int verb);
285 int getCurrentVerb()
const {
return _currentVerb; }
286 void setPointerVerb();
287 void whichObject(
const Point& mousePoint);
288 void hitObject(
bool leftButton);
289 void playfieldClick(
const Point& mousePoint,
bool leftButton);
291 void setLeftButtonVerb(
int verb);
292 int getLeftButtonVerb()
const {
return _leftButtonVerb; }
293 void setRightButtonVerb(
int verb);
294 int getRightButtonVerb()
const {
return _rightButtonVerb; }
295 void setNonPlayfieldVerb() {
296 setRightButtonVerb(getVerbType(kVerbNone));
297 _pointerObject = ID_NOTHING;
298 _currentObject[_firstObjectSet ? 1 : 0] = ID_NOTHING;
300 void setNoPendingVerb() {
301 _pendingVerb = getVerbType(kVerbNone);
302 _currentObject[0] = _currentObject[1] = ID_NOTHING;
305 int getVerbType(VerbTypes verbType);
306 TextListEntry *getPlacardTextEntry() {
return _placardTextEntry; }
308 bool isNonInteractiveDemo();
319 uint16 readUint16(byte *addr, byte addrMode) {
324 return READ_LE_UINT16(addr);
326 return READ_UINT16(addr);
330 void writeUint16(byte *addr, uint16 value, byte addrMode) {
335 WRITE_LE_UINT16(addr, value);
338 WRITE_UINT16(addr, value);
347 uint16 _modulesLUTEntryLen;
355 ScriptThreadList _threadList;
359 bool _firstObjectSet;
360 bool _secondObjectNeeded;
361 uint16 _currentObject[2];
362 int16 _currentObjectFlags[2];
366 int _rightButtonVerb;
367 int _ihnmDemoCurrentY;
370 uint16 _pendingObject[2];
372 uint16 _pointerObject;
377 VoiceLUT _globalVoiceLUT;
380 ScriptThread &createThread(uint16 scriptModuleNumber, uint16 scriptEntryPointNumber);
381 int executeThread(
ScriptThread *thread,
int entrypointNumber);
382 void executeThreads(uint msec);
383 void completeThread();
384 void abortAllThreads();
386 void wakeUpActorThread(
int waitType,
void *threadObj);
387 void wakeUpThreads(
int waitType);
388 void wakeUpThreadsDelayed(
int waitType,
int sleepTime);
390 void loadVoiceLUT(VoiceLUT &voiceLUT,
const ByteArray &resourceData);
397 void setThreadEntrypoint(
ScriptThread *thread,
int entrypointNumber);
400 void finishDialog(
int strID,
int replyID,
int flags,
int bitOffset);
404 typedef void (
Script::*ScriptOpType)(SCRIPTOP_PARAMS);
406 ScriptOpType scriptOp;
407 const char *scriptOpName;
411 void setupScriptOpcodeList();
412 void opDummy(SCRIPTOP_PARAMS) {
warning(
"Dummy opcode called"); }
413 void opNextBlock(SCRIPTOP_PARAMS) {
414 thread->_instructionOffset = (((thread->_instructionOffset) >> 10) + 1) << 10;
416 void opDup(SCRIPTOP_PARAMS);
417 void opDrop(SCRIPTOP_PARAMS);
418 void opZero(SCRIPTOP_PARAMS);
419 void opOne(SCRIPTOP_PARAMS);
420 void opConstInt(SCRIPTOP_PARAMS);
421 void opStrLit(SCRIPTOP_PARAMS);
422 void opGetFlag(SCRIPTOP_PARAMS);
423 void opGetByte(SCRIPTOP_PARAMS);
424 void opGetInt(SCRIPTOP_PARAMS);
425 void opPutFlag(SCRIPTOP_PARAMS);
426 void opPutByte(SCRIPTOP_PARAMS);
427 void opPutInt(SCRIPTOP_PARAMS);
428 void opPutFlagV(SCRIPTOP_PARAMS);
429 void opPutByteV(SCRIPTOP_PARAMS);
430 void opPutIntV(SCRIPTOP_PARAMS);
431 void opCall(SCRIPTOP_PARAMS);
432 void opCallNear(SCRIPTOP_PARAMS);
433 void opCallFar(SCRIPTOP_PARAMS);
434 void opCcall(SCRIPTOP_PARAMS);
435 void opCcallV(SCRIPTOP_PARAMS);
436 void opCallMember(SCRIPTOP_PARAMS);
437 void opCallMemberV(SCRIPTOP_PARAMS);
438 void opEnter(SCRIPTOP_PARAMS);
439 void opReturn(SCRIPTOP_PARAMS);
440 void opReturnV(SCRIPTOP_PARAMS);
441 void opJmp(SCRIPTOP_PARAMS);
442 void opJmpTrueV(SCRIPTOP_PARAMS);
443 void opJmpFalseV(SCRIPTOP_PARAMS);
444 void opJmpTrue(SCRIPTOP_PARAMS);
445 void opJmpFalse(SCRIPTOP_PARAMS);
446 void opJmpSwitch(SCRIPTOP_PARAMS);
447 void opJmpRandom(SCRIPTOP_PARAMS);
448 void opNegate(SCRIPTOP_PARAMS);
449 void opNot(SCRIPTOP_PARAMS);
450 void opCompl(SCRIPTOP_PARAMS);
451 void opIncV(SCRIPTOP_PARAMS);
452 void opDecV(SCRIPTOP_PARAMS);
453 void opPostInc(SCRIPTOP_PARAMS);
454 void opPostDec(SCRIPTOP_PARAMS);
455 void opAdd(SCRIPTOP_PARAMS);
456 void opSub(SCRIPTOP_PARAMS);
457 void opMul(SCRIPTOP_PARAMS);
458 void opDiv(SCRIPTOP_PARAMS);
459 void opMod(SCRIPTOP_PARAMS);
460 void opEq(SCRIPTOP_PARAMS);
461 void opNe(SCRIPTOP_PARAMS);
462 void opGt(SCRIPTOP_PARAMS);
463 void opLt(SCRIPTOP_PARAMS);
464 void opGe(SCRIPTOP_PARAMS);
465 void opLe(SCRIPTOP_PARAMS);
466 void opRsh(SCRIPTOP_PARAMS);
467 void opLsh(SCRIPTOP_PARAMS);
468 void opAnd(SCRIPTOP_PARAMS);
469 void opOr(SCRIPTOP_PARAMS);
470 void opXor(SCRIPTOP_PARAMS);
471 void opLAnd(SCRIPTOP_PARAMS);
472 void opLOr(SCRIPTOP_PARAMS);
473 void opLXor(SCRIPTOP_PARAMS);
474 void opSpeak(SCRIPTOP_PARAMS);
475 void opDialogBegin(SCRIPTOP_PARAMS);
476 void opDialogEnd(SCRIPTOP_PARAMS);
477 void opReply(SCRIPTOP_PARAMS);
478 void opAnimate(SCRIPTOP_PARAMS);
479 void opJmpSeedRandom(SCRIPTOP_PARAMS);
482 typedef void (
Script::*ScriptFunctionType)(SCRIPTFUNC_PARAMS);
485 ScriptFunctionType scriptFunction;
486 const char *scriptFunctionName;
490 void setupITEScriptFuncList();
491 void setupIHNMScriptFuncList();
493 void sfPutString(SCRIPTFUNC_PARAMS);
494 void sfWait(SCRIPTFUNC_PARAMS);
495 void sfTakeObject(SCRIPTFUNC_PARAMS);
496 void sfIsCarried(SCRIPTFUNC_PARAMS);
497 void sfStatusBar(SCRIPTFUNC_PARAMS);
498 void sfMainMode(SCRIPTFUNC_PARAMS);
499 void sfScriptWalkTo(SCRIPTFUNC_PARAMS);
500 void sfScriptDoAction(SCRIPTFUNC_PARAMS);
501 void sfSetActorFacing(SCRIPTFUNC_PARAMS);
502 void sfStartBgdAnim(SCRIPTFUNC_PARAMS);
503 void sfStopBgdAnim(SCRIPTFUNC_PARAMS);
504 void sfLockUser(SCRIPTFUNC_PARAMS);
505 void sfPreDialog(SCRIPTFUNC_PARAMS);
506 void sfKillActorThreads(SCRIPTFUNC_PARAMS);
507 void sfFaceTowards(SCRIPTFUNC_PARAMS);
508 void sfSetFollower(SCRIPTFUNC_PARAMS);
509 void sfScriptGotoScene(SCRIPTFUNC_PARAMS);
510 void sfSetObjImage(SCRIPTFUNC_PARAMS);
511 void sfSetObjName(SCRIPTFUNC_PARAMS);
512 void sfGetObjImage(SCRIPTFUNC_PARAMS);
513 void sfGetNumber(SCRIPTFUNC_PARAMS);
514 void sfScriptOpenDoor(SCRIPTFUNC_PARAMS);
515 void sfScriptCloseDoor(SCRIPTFUNC_PARAMS);
516 void sfSetBgdAnimSpeed(SCRIPTFUNC_PARAMS);
517 void sfCycleColors(SCRIPTFUNC_PARAMS);
518 void sfDoCenterActor(SCRIPTFUNC_PARAMS);
519 void sfStartBgdAnimSpeed(SCRIPTFUNC_PARAMS);
520 void sfScriptWalkToAsync(SCRIPTFUNC_PARAMS);
521 void sfEnableZone(SCRIPTFUNC_PARAMS);
522 void sfSetActorState(SCRIPTFUNC_PARAMS);
523 void sfScriptMoveTo(SCRIPTFUNC_PARAMS);
524 void sfSceneEq(SCRIPTFUNC_PARAMS);
525 void sfDropObject(SCRIPTFUNC_PARAMS);
526 void sfFinishBgdAnim(SCRIPTFUNC_PARAMS);
527 void sfSwapActors(SCRIPTFUNC_PARAMS);
528 void sfSimulSpeech(SCRIPTFUNC_PARAMS);
529 void sfScriptWalk(SCRIPTFUNC_PARAMS);
530 void sfCycleFrames(SCRIPTFUNC_PARAMS);
531 void sfSetFrame(SCRIPTFUNC_PARAMS);
532 void sfSetPortrait(SCRIPTFUNC_PARAMS);
533 void sfSetProtagPortrait(SCRIPTFUNC_PARAMS);
534 void sfChainBgdAnim(SCRIPTFUNC_PARAMS);
535 void sfScriptSpecialWalk(SCRIPTFUNC_PARAMS);
536 void sfPlaceActor(SCRIPTFUNC_PARAMS);
537 void sfCheckUserInterrupt(SCRIPTFUNC_PARAMS);
538 void sfScriptWalkRelative(SCRIPTFUNC_PARAMS);
539 void sfScriptMoveRelative(SCRIPTFUNC_PARAMS);
540 void sfSimulSpeech2(SCRIPTFUNC_PARAMS);
541 void sfPlacard(SCRIPTFUNC_PARAMS);
542 void sfPlacardOff(SCRIPTFUNC_PARAMS);
543 void sfSetProtagState(SCRIPTFUNC_PARAMS);
544 void sfResumeBgdAnim(SCRIPTFUNC_PARAMS);
545 void sfThrowActor(SCRIPTFUNC_PARAMS);
546 void sfWaitWalk(SCRIPTFUNC_PARAMS);
547 void sfScriptSceneID(SCRIPTFUNC_PARAMS);
548 void sfChangeActorScene(SCRIPTFUNC_PARAMS);
549 void sfScriptClimb(SCRIPTFUNC_PARAMS);
550 void sfSetDoorState(SCRIPTFUNC_PARAMS);
551 void sfSetActorZ(SCRIPTFUNC_PARAMS);
552 void sfScriptText(SCRIPTFUNC_PARAMS);
553 void sfGetActorX(SCRIPTFUNC_PARAMS);
554 void sfGetActorY(SCRIPTFUNC_PARAMS);
555 void sfEraseDelta(SCRIPTFUNC_PARAMS);
556 void sfPlayMusic(SCRIPTFUNC_PARAMS);
557 void sfPickClimbOutPos(SCRIPTFUNC_PARAMS);
558 void sfTossRif(SCRIPTFUNC_PARAMS);
559 void sfShowControls(SCRIPTFUNC_PARAMS);
560 void sfShowMap(SCRIPTFUNC_PARAMS);
561 void sfPuzzleWon(SCRIPTFUNC_PARAMS);
562 void sfEnableEscape(SCRIPTFUNC_PARAMS);
563 void sfPlaySound(SCRIPTFUNC_PARAMS);
564 void sfPlayLoopedSound(SCRIPTFUNC_PARAMS);
565 void sfGetDeltaFrame(SCRIPTFUNC_PARAMS);
566 void sfShowProtect(SCRIPTFUNC_PARAMS);
567 void sfProtectResult(SCRIPTFUNC_PARAMS);
568 void sfRand(SCRIPTFUNC_PARAMS);
569 void sfFadeMusic(SCRIPTFUNC_PARAMS);
570 void sfScriptStartCutAway(SCRIPTFUNC_PARAMS);
571 void sfReturnFromCutAway(SCRIPTFUNC_PARAMS);
572 void sfEndCutAway(SCRIPTFUNC_PARAMS);
573 void sfGetMouseClicks(SCRIPTFUNC_PARAMS);
574 void sfResetMouseClicks(SCRIPTFUNC_PARAMS);
575 void sfWaitFrames(SCRIPTFUNC_PARAMS);
576 void sfScriptFade(SCRIPTFUNC_PARAMS);
577 void sfPlayVoice(SCRIPTFUNC_PARAMS);
578 void sfVstopFX(SCRIPTFUNC_PARAMS);
579 void sfVstopLoopedFX(SCRIPTFUNC_PARAMS);
580 void sfDemoIsInteractive(SCRIPTFUNC_PARAMS);
581 void sfVsetTrack(SCRIPTFUNC_PARAMS);
582 void sfDebugShowData(SCRIPTFUNC_PARAMS);
583 void sfNull(SCRIPTFUNC_PARAMS);
584 void sfWaitFramesEsc(SCRIPTFUNC_PARAMS);
585 void sfPsychicProfile(SCRIPTFUNC_PARAMS);
586 void sfPsychicProfileOff(SCRIPTFUNC_PARAMS);
587 void sfSetSpeechBox(SCRIPTFUNC_PARAMS);
588 void sfSetChapterPoints(SCRIPTFUNC_PARAMS);
589 void sfSetPortraitBgColor(SCRIPTFUNC_PARAMS);
590 void sfScriptStartVideo(SCRIPTFUNC_PARAMS);
591 void sfScriptReturnFromVideo(SCRIPTFUNC_PARAMS);
592 void sfScriptEndVideo(SCRIPTFUNC_PARAMS);
593 void sfShowIHNMDemoHelpBg(SCRIPTFUNC_PARAMS);
594 void sfAddIHNMDemoHelpTextLine(SCRIPTFUNC_PARAMS);
595 void sfShowIHNMDemoHelpPage(SCRIPTFUNC_PARAMS);
596 void sfGetPoints(SCRIPTFUNC_PARAMS);
597 void sfSetGlobalFlag(SCRIPTFUNC_PARAMS);
598 void sfDemoSetInteractive(SCRIPTFUNC_PARAMS);
599 void sfClearGlobalFlag(SCRIPTFUNC_PARAMS);
600 void sfTestGlobalFlag(SCRIPTFUNC_PARAMS);
601 void sfSetPoints(SCRIPTFUNC_PARAMS);
602 void sfQueueMusic(SCRIPTFUNC_PARAMS);
603 void sfDisableAbortSpeeches(SCRIPTFUNC_PARAMS);
605 void sfStub(
const char *name,
ScriptThread *thread,
int nArgs);
Definition: resource.h:105
void warning(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
void clear()
Definition: array.h:320
void debug(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1