[Scummvm-git-logs] scummvm master -> a17f406bef2d19931685f139f8c352df5a486360

moralrecordings code at moral.net.au
Mon Dec 2 14:15:22 UTC 2019


This automated email contains information about 12 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
97caeed249 DIRECTOR: Change kTheLast to a TheFieldType
f2bb49397b DIRECTOR: Add bytecode lookup table for TheEntity functions
993fbf5a4f DIRECTOR: Add c_v4theentitypush and c_v4theentityassign
a45da2eb03 DIRECTOR: Add c_constpush
13cffcd6a2 DIRECTOR: Add stubs for c_jump and c_jumpif
f7fee0145b DIRECTOR: Replace code int/double parsing with inline function
29be7c0fa6 DIRECTOR: Implement c_jump and c_jumpif
473a2b7463 DIRECTOR: Add readString and getString
f1b0c10fe4 DIRECTOR: Show code offsets for stack printouts in Lingo::execute
237a5f97a8 DIRECTOR: Comments for bytecode argument parser
472e7f1380 DIRECTOR: Correct rebase mistake
a17f406bef DIRECTOR: Adjust naming of some instructions


Commit: 97caeed249f48f3d4316d9451e0b23c39855ee41
    https://github.com/scummvm/scummvm/commit/97caeed249f48f3d4316d9451e0b23c39855ee41
Author: Scott Percival (code at moral.net.au)
Date: 2019-12-02T21:57:09+08:00

Commit Message:
DIRECTOR: Change kTheLast to a TheFieldType

Changed paths:
    engines/director/lingo/lingo-the.cpp
    engines/director/lingo/lingo-the.h


diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 4ba8eec..fb95284 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -65,7 +65,6 @@ TheEntity entities[] = {
 	{ kTheKeyDownScript,	"keyDownScript",	false },	// D2 p
 	{ kTheKeyUpScript,		"keyUpScript",		false },	//				D4 p
 	{ kTheLabelList,		"labelList",		false },	//		D3 f
-	{ kTheLast,				"last",				false },	//				D4 f
 	{ kTheLastClick,		"lastClick",		false },	// D2 f
 	{ kTheLastEvent,		"lastEvent",		false },	// D2 f
 	{ kTheLastFrame,		"lastFrame",		false },	//				D4 p
@@ -128,7 +127,7 @@ TheEntity entities[] = {
 	{ kTheStillDown,		"stillDown",		false },	// D2 f
 	{ kTheSwitchColorDepth,	"switchColorDepth",	false },	// D2 p
 	{ kTheTicks,			"ticks",			false },	// D2 f
-	{ kTheTimeoutKeydown,	"timeoutKeydown",	false },	// D2 p
+	{ kTheTimeoutKeyDown,	"timeoutKeyDown",	false },	// D2 p
 	{ kTheTimeoutLapsed,	"timeoutLapsed",	false },	// D2 p
 	{ kTheTimeoutLength,	"timeoutLength",	false },	// D2 p
 	{ kTheTimeoutMouse,		"timeoutMouse",		false },	// D2 p
@@ -224,7 +223,7 @@ TheEntityField fields[] = {
 	// Field fields
 	{ kTheField,	"textAlign",	kTheTextAlign },	//		D3 p
 	{ kTheField,	"textFont",		kTheTextFont },		//		D3 p
-	{ kTheField,	"textHeight",	kTheTextheight },	//		D3 p
+	{ kTheField,	"textHeight",	kTheTextHeight },	//		D3 p
 	{ kTheField,	"textSize",		kTheTextSize },		//		D3 p
 	{ kTheField,	"textStyle",	kTheTextStyle },	//		D3 p
 
@@ -247,11 +246,15 @@ TheEntityField fields[] = {
 
 	{ kTheCastMembers,	"number",	kTheNumber },		// 		D3 p
 	{ kTheChars,	"number",		kTheNumber },		//		D3 p
+	{ kTheChars,	"last",			kTheLast },			//				D4 f
 	{ kTheItems,	"number",		kTheNumber },		//		D3 p
+	{ kTheItems,	"last",			kTheLast },			//				D4 f
 	{ kTheLines,	"number",		kTheNumber },		//		D3 p
+	{ kTheLines,	"last",			kTheLast },			//				D4 f
 	{ kTheMenuItems,"number",		kTheNumber },		//		D3 p
 	{ kTheMenus,	"number",		kTheNumber },		//		D3 p
 	{ kTheWords,	"number",		kTheNumber },		//		D3 p
+	{ kTheWords,	"last",			kTheLast },			//				D4 f
 
 	{ kTheDate,		"short",		kTheShort },		//		D3 f
 	{ kTheDate,		"long",			kTheLong },			//		D3 f
diff --git a/engines/director/lingo/lingo-the.h b/engines/director/lingo/lingo-the.h
index 173efe6..9cedbbb 100644
--- a/engines/director/lingo/lingo-the.h
+++ b/engines/director/lingo/lingo-the.h
@@ -63,7 +63,6 @@ enum TheEntityType {
 	kTheKeyDownScript,
 	kTheKeyUpScript,
 	kTheLabelList,
-	kTheLast,
 	kTheLastClick,
 	kTheLastEvent,
 	kTheLastFrame,
@@ -127,7 +126,7 @@ enum TheEntityType {
 	kTheSwitchColorDepth,
 	kTheTicks,
 	kTheTime,
-	kTheTimeoutKeydown,
+	kTheTimeoutKeyDown,
 	kTheTimeoutLapsed,
 	kTheTimeoutLength,
 	kTheTimeoutMouse,
@@ -170,6 +169,7 @@ enum TheFieldType {
 	kTheHilite,
 	kTheImmediate,
 	kTheInk,
+	kTheLast,
 	kTheLeft,
 	kTheLineSize,
 	kTheLoaded,
@@ -209,7 +209,7 @@ enum TheFieldType {
 	kTheText,
 	kTheTextAlign,
 	kTheTextFont,
-	kTheTextheight,
+	kTheTextHeight,
 	kTheTextSize,
 	kTheTextStyle,
 	kTheTitle,


Commit: f2bb49397b1c7f9369adf85fb40a3819f507970b
    https://github.com/scummvm/scummvm/commit/f2bb49397b1c7f9369adf85fb40a3819f507970b
Author: Scott Percival (code at moral.net.au)
Date: 2019-12-02T21:57:09+08:00

Commit Message:
DIRECTOR: Add bytecode lookup table for TheEntity functions

Changed paths:
    engines/director/lingo/lingo-bytecode.cpp
    engines/director/lingo/lingo-bytecode.h
    engines/director/lingo/lingo.h


diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 19b149f..cfe0630 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -24,11 +24,7 @@
 
 namespace Director {
 
-static struct LingoV4Bytecode {
-	const uint8 opcode;
-	const inst func;
-	const char *proto;
-} lingoV4[] = {
+static LingoV4Bytecode lingoV4[] = {
 	{ 0x01, STOP, "" },
 	{ 0x03, Lingo::c_voidpush, "" },
 	{ 0x04, Lingo::c_mul, "" },
@@ -61,9 +57,110 @@ static struct LingoV4Bytecode {
 	{ 0, 0, 0 }
 };
 
+static LingoV4TheEntity lingoV4TheEntity[] {
+	{ 0x00, 0x00, kTheFloatPrecision, kTheNOField, false, kTEANOArgs },
+	{ 0x00, 0x01, kTheMouseDownScript, kTheNOField, true, kTEANOArgs },
+	{ 0x00, 0x02, kTheMouseUpScript, kTheNOField, true, kTEANOArgs },
+	{ 0x00, 0x03, kTheKeyDownScript, kTheNOField, true, kTEANOArgs },
+	{ 0x00, 0x04, kTheKeyUpScript, kTheNOField, true, kTEANOArgs },
+	{ 0x00, 0x05, kTheTimeoutScript, kTheNOField, true, kTEANOArgs },
+	{ 0x00, 0x06, kTheTime, kTheShort, false, kTEANOArgs },
+	{ 0x00, 0x07, kTheTime, kTheAbbr, false, kTEANOArgs },
+	{ 0x00, 0x08, kTheTime, kTheLong, false, kTEANOArgs },
+	{ 0x00, 0x09, kTheDate, kTheShort, false, kTEANOArgs },
+	{ 0x00, 0x0a, kTheDate, kTheAbbr, false, kTEANOArgs },
+	{ 0x00, 0x0b, kTheDate, kTheLong, false, kTEANOArgs },
+	{ 0x00, 0x0c, kTheChars, kTheLast, false, kTEAString },
+	{ 0x00, 0x0d, kTheWords, kTheLast, false, kTEAString },
+	{ 0x00, 0x0e, kTheItems, kTheLast, false, kTEAString },
+	{ 0x00, 0x0f, kTheLines, kTheLast, false, kTEAString },
+	{ 0x01, 0x01, kTheChars, kTheNumber, false, kTEAString },
+	{ 0x01, 0x02, kTheWords, kTheNumber, false, kTEAString },
+	{ 0x01, 0x03, kTheItems, kTheNumber, false, kTEAString },
+	{ 0x01, 0x04, kTheLines, kTheNumber, false, kTEAString },
+	{ 0x02, 0x01, kTheMenu, kTheName, false, kTEAItemId },
+	{ 0x02, 0x02, kTheMenuItems, kTheNumber, false, kTEAItemId },
+	{ 0x03, 0x01, kTheMenuItem, kTheName, true, kTEAMenuIdItemId },
+	{ 0x03, 0x02, kTheMenuItem, kTheCheckMark, true, kTEAMenuIdItemId },
+	{ 0x03, 0x03, kTheMenuItem, kTheEnabled, true, kTEAMenuIdItemId },
+	{ 0x03, 0x04, kTheMenuItem, kTheScript, true, kTEAMenuIdItemId },
+	{ 0x04, 0x01, kTheSound, kTheVolume, true, kTEAItemId },
+	{ 0x06, 0x01, kTheSprite, kTheCursor, true, kTEAItemId },
+	{ 0x06, 0x02, kTheSprite, kTheBackColor, true, kTEAItemId },
+	{ 0x06, 0x03, kTheSprite, kTheBottom, true, kTEAItemId },
+	{ 0x06, 0x04, kTheSprite, kTheCastNum, true, kTEAItemId },
+	{ 0x06, 0x05, kTheSprite, kTheConstraint, true, kTEAItemId },
+	{ 0x06, 0x06, kTheSprite, kTheCursor, true, kTEAItemId },
+	{ 0x06, 0x07, kTheSprite, kTheForeColor, true, kTEAItemId },
+	{ 0x06, 0x08, kTheSprite, kTheHeight, true, kTEAItemId },
+	{ 0x06, 0x0a, kTheSprite, kTheInk, true, kTEAItemId },
+	{ 0x06, 0x0b, kTheSprite, kTheLeft, true, kTEAItemId },
+	{ 0x06, 0x0c, kTheSprite, kTheLineSize, true, kTEAItemId },
+	{ 0x06, 0x0d, kTheSprite, kTheLocH, true, kTEAItemId },
+	{ 0x06, 0x0e, kTheSprite, kTheLocV, true, kTEAItemId },
+	{ 0x06, 0x0f, kTheSprite, kTheMovieRate, true, kTEAItemId },
+	{ 0x06, 0x10, kTheSprite, kTheMovieTime, true, kTEAItemId },
+	{ 0x06, 0x12, kTheSprite, kThePuppet, true, kTEAItemId },
+	{ 0x06, 0x13, kTheSprite, kTheRight, true, kTEAItemId },
+	{ 0x06, 0x14, kTheSprite, kTheStartTime, true, kTEAItemId },
+	{ 0x06, 0x15, kTheSprite, kTheStopTime, true, kTEAItemId },
+	{ 0x06, 0x16, kTheSprite, kTheStretch, true, kTEAItemId },
+	{ 0x06, 0x17, kTheSprite, kTheTop, true, kTEAItemId },
+	{ 0x06, 0x18, kTheSprite, kTheTrails, true, kTEAItemId },
+	{ 0x06, 0x19, kTheSprite, kTheVisible, true, kTEAItemId },
+	{ 0x06, 0x1a, kTheSprite, kTheVolume, true, kTEAItemId },
+	{ 0x06, 0x1b, kTheSprite, kTheWidth, true, kTEAItemId },
+	{ 0x06, 0x1d, kTheSprite, kTheScriptNum, true, kTEAItemId },
+	{ 0x06, 0x1e, kTheSprite, kTheMoveableSprite, true, kTEAItemId },
+	{ 0x06, 0x20, kTheSprite, kTheScoreColor, true, kTEAItemId },
+	{ 0x07, 0x01, kTheBeepOn, kTheNOField, true, kTEANOArgs },
+	{ 0x07, 0x02, kTheButtonStyle, kTheNOField, true, kTEANOArgs },
+	{ 0x07, 0x03, kTheCenterStage, kTheNOField, true, kTEANOArgs },
+	{ 0x07, 0x04, kTheCheckBoxAccess, kTheNOField, true, kTEANOArgs },
+	{ 0x07, 0x05, kTheCheckBoxType, kTheNOField, true, kTEANOArgs },
+	{ 0x07, 0x06, kTheColorDepth, kTheNOField, true, kTEANOArgs },
+	{ 0x07, 0x08, kTheExitLock, kTheNOField, true, kTEANOArgs },
+	{ 0x07, 0x09, kTheFixStageSize, kTheNOField, true, kTEANOArgs },
+	{ 0x07, 0x13, kTheTimeoutLapsed, kTheNOField, true, kTEANOArgs },
+	{ 0x07, 0x17, kTheSelEnd, kTheNOField, true, kTEANOArgs },
+	{ 0x07, 0x18, kTheSelStart, kTheNOField, true, kTEANOArgs },
+	{ 0x07, 0x19, kTheSoundEnabled, kTheNOField, true, kTEANOArgs },
+	{ 0x07, 0x1a, kTheSoundLevel, kTheNOField, true, kTEANOArgs },
+	{ 0x07, 0x1b, kTheStageColor, kTheNOField, true, kTEANOArgs },
+	{ 0x07, 0x1d, kTheStillDown, kTheNOField, true, kTEANOArgs },
+	{ 0x07, 0x1e, kTheTimeoutKeyDown, kTheNOField, true, kTEANOArgs },
+	{ 0x07, 0x1f, kTheTimeoutLength, kTheNOField, true, kTEANOArgs },
+	{ 0x07, 0x20, kTheTimeoutMouse, kTheNOField, true, kTEANOArgs },
+	{ 0x07, 0x21, kTheTimeoutPlay, kTheNOField, true, kTEANOArgs },
+	{ 0x07, 0x22, kTheTimer, kTheNOField, true, kTEANOArgs },
+	{ 0x08, 0x01, kThePerFrameHook, kTheNOField, false, kTEANOArgs },
+	{ 0x08, 0x02, kTheCastMembers, kTheNumber, false, kTEANOArgs },
+	{ 0x08, 0x03, kTheMenus, kTheNumber, false, kTEANOArgs },
+	{ 0x09, 0x01, kTheCast, kTheName, true, kTEAItemId },
+	{ 0x09, 0x02, kTheCast, kTheText, true, kTEAItemId },
+	{ 0x09, 0x08, kTheCast, kThePicture, true, kTEAItemId },
+	{ 0x09, 0x0a, kTheCast, kTheNumber, true, kTEAItemId },
+	{ 0x09, 0x0b, kTheCast, kTheSize, true, kTEAItemId },
+	{ 0x09, 0x11, kTheCast, kTheForeColor, true, kTEAItemId },
+	{ 0x09, 0x12, kTheCast, kTheBackColor, true, kTEAItemId },
+	{ 0x0c, 0x03, kTheField, kTheTextStyle, true, kTEAItemId },
+	{ 0x0c, 0x04, kTheField, kTheTextFont, true, kTEAItemId },
+	{ 0x0c, 0x05, kTheField, kTheTextHeight, true, kTEAItemId },
+	{ 0x0c, 0x06, kTheField, kTheTextAlign, true, kTEAItemId },
+	{ 0x0c, 0x07, kTheField, kTheTextSize, true, kTEAItemId },
+	{ 0x0d, 0x0f, kTheCast, kTheDirectToStage, true, kTEAItemId },
+	{ 0x0d, 0x10, kTheCast, kTheSound, true, kTEAItemId },
+	{ -1, 0, 0, 0, false, kTEANOArgs },
+};
+
+
 void Lingo::initBytecode() {
 	for (LingoV4Bytecode *op = lingoV4; op->opcode; op++) {
-		_lingoV4[op->opcode] = new Opcode( op->func, op->proto );
+		_lingoV4[op->opcode] = op;
+	}
+
+	for (LingoV4TheEntity *ent = lingoV4TheEntity; ent->bank != -1; ent++) {
+		_lingoV4TheEntity[(ent->bank << 16) + ent->firstArg] = ent;
 	}
 }
 
diff --git a/engines/director/lingo/lingo-bytecode.h b/engines/director/lingo/lingo-bytecode.h
index e69de29..0e5f9b4 100644
--- a/engines/director/lingo/lingo-bytecode.h
+++ b/engines/director/lingo/lingo-bytecode.h
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef DIRECTOR_LINGO_LINGO_BYTECODE_H
+#define DIRECTOR_LINGO_LINGO_BYTECODE_H
+
+namespace Director {
+
+typedef void (*inst)(void);
+
+struct LingoV4Bytecode {
+	const uint8 opcode;
+	const inst func;
+	const char *proto;
+};
+
+enum TheEntityArgsType {
+	kTEANOArgs = 0,
+	kTEAItemId = 1,
+	kTEAString,
+	kTEAMenuIdItemId
+};
+
+struct LingoV4TheEntity {
+	const int bank;
+	const int firstArg;
+	const int entity;
+	const int field;
+	const bool writable;
+	const TheEntityArgsType type;
+};
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 6a0f087..7d485c0 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -31,6 +31,7 @@
 #include "director/score.h"
 #include "director/lingo/lingo-gr.h"
 #include "director/lingo/lingo-the.h"
+#include "director/lingo/lingo-bytecode.h"
 
 namespace Director {
 
@@ -89,14 +90,6 @@ struct FuncDesc {
 
 typedef Common::HashMap<void *, FuncDesc *> FuncHash;
 
-struct Opcode {
-	inst func;
-	const char *proto;
-
-	Opcode(inst f, const char *p) { func = f; proto = p; }
-};
-typedef Common::HashMap<int, Opcode *> OpcodeHash;
-
 struct Symbol {	/* symbol table entry */
 	Common::String name;
 	int type;
@@ -589,7 +582,8 @@ private:
 
 	FuncHash _functions;
 
-	OpcodeHash _lingoV4;
+	Common::HashMap<int, LingoV4Bytecode *> _lingoV4;
+	Common::HashMap<int, LingoV4TheEntity *> _lingoV4TheEntity;
 
 	uint _pc;
 


Commit: 993fbf5a4f0ea93f7e4d5b387a188298ac05f2b5
    https://github.com/scummvm/scummvm/commit/993fbf5a4f0ea93f7e4d5b387a188298ac05f2b5
Author: Scott Percival (code at moral.net.au)
Date: 2019-12-02T21:57:09+08:00

Commit Message:
DIRECTOR: Add c_v4theentitypush and c_v4theentityassign

Changed paths:
    engines/director/lingo/lingo-bytecode.cpp
    engines/director/lingo/lingo-code.cpp
    engines/director/lingo/lingo.h


diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index cfe0630..ae008e0 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -54,10 +54,18 @@ static LingoV4Bytecode lingoV4[] = {
 	{ 0x1c, Lingo::c_tell, "" },
 	{ 0x1d, Lingo::c_telldone, "" },
 	{ 0x41, Lingo::c_intpush, "b" },
+	{ 0x42, Lingo::c_argspush, "b" },
+	{ 0x43, Lingo::c_arraypush, "b" },
+	{ 0x45, Lingo::c_symbolpush, "b" },
+	{ 0x5c, Lingo::c_v4theentitypush, "b" },
+	{ 0x5d, Lingo::c_v4theentityassign, "b" },
+	{ 0x81, Lingo::c_intpush, "w" },
+	{ 0x82, Lingo::c_argspush, "w" },
+	{ 0x83, Lingo::c_arraypush, "w" },
 	{ 0, 0, 0 }
 };
 
-static LingoV4TheEntity lingoV4TheEntity[] {
+static LingoV4TheEntity lingoV4TheEntity[] = {
 	{ 0x00, 0x00, kTheFloatPrecision, kTheNOField, false, kTEANOArgs },
 	{ 0x00, 0x01, kTheMouseDownScript, kTheNOField, true, kTEANOArgs },
 	{ 0x00, 0x02, kTheMouseUpScript, kTheNOField, true, kTEANOArgs },
@@ -150,7 +158,7 @@ static LingoV4TheEntity lingoV4TheEntity[] {
 	{ 0x0c, 0x07, kTheField, kTheTextSize, true, kTEAItemId },
 	{ 0x0d, 0x0f, kTheCast, kTheDirectToStage, true, kTEAItemId },
 	{ 0x0d, 0x10, kTheCast, kTheSound, true, kTEAItemId },
-	{ -1, 0, 0, 0, false, kTEANOArgs },
+	{ -1, 0, 0, 0, false, kTEANOArgs }
 };
 
 
@@ -160,7 +168,126 @@ void Lingo::initBytecode() {
 	}
 
 	for (LingoV4TheEntity *ent = lingoV4TheEntity; ent->bank != -1; ent++) {
-		_lingoV4TheEntity[(ent->bank << 16) + ent->firstArg] = ent;
+		_lingoV4TheEntity[(ent->bank << 8) + ent->firstArg] = ent;
+	}
+}
+
+
+void Lingo::c_v4theentitypush() {
+	inst b = (*g_lingo->_currentScript)[g_lingo->_pc++];
+	int bank = (int)READ_UINT32(&b);
+
+	Datum firstArg = g_lingo->pop();
+	Datum result;
+	result.u.s = NULL;
+	result.type = VOID;
+
+	if (firstArg.type == INT) {
+		int key = (bank << 8) + firstArg.u.i;
+		if (g_lingo->_lingoV4TheEntity.contains(key)) {
+			int entity = g_lingo->_lingoV4TheEntity[key]->entity;
+			int field = g_lingo->_lingoV4TheEntity[key]->field;
+			switch (g_lingo->_lingoV4TheEntity[key]->type) {
+			case kTEANOArgs:
+				{
+					Datum id;
+					id.u.s = NULL;
+					id.type = VOID;
+					result = g_lingo->getTheEntity(entity, id, field);
+				}
+				break;
+			case kTEAItemId:
+				{
+					Datum id = g_lingo->pop();
+					result = g_lingo->getTheEntity(entity, id, field);
+				}
+				break;
+			case kTEAString:
+				{
+					/*Datum stringArg = */g_lingo->pop();
+					warning("c_v4theentitypush: STUB: mapping 0x%02x 0x%02x kTEAString", bank, firstArg.u.i);
+				}
+				break;
+			case kTEAMenuIdItemId:
+				{
+					/*Datum menuId = */g_lingo->pop();
+					/*Datum itemId = */g_lingo->pop();
+					warning("c_v4theentitypush: STUB: mapping 0x%02x 0x%02x kTEAMenuIdItemId", bank, firstArg.u.i);
+				}
+				break;
+			default:
+				warning("c_v4theentitypush: unknown call type %d", g_lingo->_lingoV4TheEntity[key]->type);
+				break;
+			}
+		} else {
+			warning("c_v4theentitypush: unhandled mapping 0x%02x 0x%02x", bank, firstArg.u.i);
+		}
+
+	} else {
+		warning("c_v4theentitypush: first arg should be of type INT, not %s", firstArg.type2str());
+	}
+
+	g_lingo->push(result);
+}
+
+
+void Lingo::c_v4theentityassign() {
+	inst b = (*g_lingo->_currentScript)[g_lingo->_pc++];
+	int bank = (int)READ_UINT32(&b);
+
+	Datum firstArg = g_lingo->pop();
+	Datum value = g_lingo->pop();
+	Datum result;
+	result.u.s = NULL;
+	result.type = VOID;
+
+	if (firstArg.type == INT) {
+		int key = (bank << 8) + firstArg.u.i;
+		if (g_lingo->_lingoV4TheEntity.contains(key)) {
+			if (g_lingo->_lingoV4TheEntity[key]->writable) {
+				int entity = g_lingo->_lingoV4TheEntity[key]->entity;
+				int field = g_lingo->_lingoV4TheEntity[key]->field;
+				switch (g_lingo->_lingoV4TheEntity[key]->type) {
+				case kTEANOArgs:
+					{
+						Datum id;
+						id.u.s = NULL;
+						id.type = VOID;
+						g_lingo->setTheEntity(entity, id, field, value);
+					}
+					break;
+				case kTEAItemId:
+					{
+						Datum id = g_lingo->pop();
+						g_lingo->setTheEntity(entity, id, field, value);
+					}
+					break;
+				case kTEAString:
+					{
+						/*Datum stringArg = */g_lingo->pop();
+						warning("c_v4theentityassign: STUB: mapping 0x%02x 0x%02x kTEAString", bank, firstArg.u.i);
+					}
+					break;
+				case kTEAMenuIdItemId:
+					{
+						/*Datum menuId = */g_lingo->pop();
+						/*Datum itemId = */g_lingo->pop();
+						warning("c_v4theentityassign: STUB: mapping 0x%02x 0x%02x kTEAMenuIdItemId", bank, firstArg.u.i);
+					}
+					break;
+				default:
+					warning("c_v4theentityassign: unknown call type %d", g_lingo->_lingoV4TheEntity[key]->type);
+					break;
+				}
+			} else {
+				warning("c_v4theentityassign: non-writable mapping 0x%02x 0x%02x", bank, firstArg.u.i);
+			}
+		} else {
+			warning("c_v4theentityassign: unhandled mapping 0x%02x 0x%02x", bank, firstArg.u.i);
+		}
+
+	} else {
+		warning("c_v4theentityassign: first arg should be of type INT, not %s", firstArg.type2str());
 	}
 }
 
@@ -368,7 +495,6 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 						break;
 					}
 				}
-
 			} else {
 				// unimplemented instruction
 				if (opcode < 0x40) { // 1 byte instruction
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 9c25c35..5bab70c 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -71,6 +71,8 @@ static struct FuncDescr {
 	{ Lingo::c_eval,		"c_eval",		"s" },
 	{ Lingo::c_theentitypush,"c_theentitypush","ii" }, // entity, field
 	{ Lingo::c_theentityassign,"c_theentityassign","ii" },
+	{ Lingo::c_v4theentitypush,"c_v4theentitypush","i" },
+	{ Lingo::c_v4theentityassign,"c_v4theentityassign","i" },
 	{ Lingo::c_swap,		"c_swap",		"" },
 	{ Lingo::c_add,			"c_add",		"" },
 	{ Lingo::c_sub,			"c_sub",		"" },
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 7d485c0..1d4e8cf 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -290,6 +290,8 @@ public:
 
 	static void c_theentitypush();
 	static void c_theentityassign();
+	static void c_v4theentitypush();
+	static void c_v4theentityassign();
 
 	static void c_repeatwhilecode();
 	static void c_repeatwithcode();


Commit: a45da2eb03139d48b98f3f520cfdf23b164a77c1
    https://github.com/scummvm/scummvm/commit/a45da2eb03139d48b98f3f520cfdf23b164a77c1
Author: Scott Percival (code at moral.net.au)
Date: 2019-12-02T21:57:09+08:00

Commit Message:
DIRECTOR: Add c_constpush

Changed paths:
    engines/director/lingo/lingo-bytecode.cpp
    engines/director/lingo/lingo-code.cpp
    engines/director/lingo/lingo.h


diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index ae008e0..6155c3d 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -56,12 +56,14 @@ static LingoV4Bytecode lingoV4[] = {
 	{ 0x41, Lingo::c_intpush, "b" },
 	{ 0x42, Lingo::c_argspush, "b" },
 	{ 0x43, Lingo::c_arraypush, "b" },
+	{ 0x44, Lingo::c_constpush, "bv" },
 	{ 0x45, Lingo::c_symbolpush, "b" },
 	{ 0x5c, Lingo::c_v4theentitypush, "b" },
 	{ 0x5d, Lingo::c_v4theentityassign, "b" },
 	{ 0x81, Lingo::c_intpush, "w" },
 	{ 0x82, Lingo::c_argspush, "w" },
 	{ 0x83, Lingo::c_arraypush, "w" },
+	{ 0x84, Lingo::c_constpush, "wv" },
 	{ 0, 0, 0 }
 };
 
@@ -185,6 +187,7 @@ void Lingo::c_v4theentitypush() {
 	if (firstArg.type == INT) {
 		int key = (bank << 8) + firstArg.u.i;
 		if (g_lingo->_lingoV4TheEntity.contains(key)) {
+			debugC(3, kDebugLingoExec, "c_v4theentitypush: mapping 0x%02x, 0x%02x", bank, firstArg.u.i);
 			int entity = g_lingo->_lingoV4TheEntity[key]->entity;
 			int field = g_lingo->_lingoV4TheEntity[key]->field;
 			switch (g_lingo->_lingoV4TheEntity[key]->type) {
@@ -193,26 +196,28 @@ void Lingo::c_v4theentitypush() {
 					Datum id;
 					id.u.s = NULL;
 					id.type = VOID;
+					debugC(3, kDebugLingoExec, "c_v4theentitypush: calling getTheEntity(0x%02x, NULL, 0x%02x)", entity, field);
 					result = g_lingo->getTheEntity(entity, id, field);
 				}
 				break;
 			case kTEAItemId:
 				{
 					Datum id = g_lingo->pop();
+					debugC(3, kDebugLingoExec, "c_v4theentitypush: calling getTheEntity(0x%02x, id, 0x%02x)", entity, field);
 					result = g_lingo->getTheEntity(entity, id, field);
 				}
 				break;
 			case kTEAString:
 				{
 					/*Datum stringArg = */g_lingo->pop();
-					warning("c_v4theentitypush: STUB: mapping 0x%02x 0x%02x kTEAString", bank, firstArg.u.i);
+					warning("c_v4theentitypush: STUB: kTEAString");
 				}
 				break;
 			case kTEAMenuIdItemId:
 				{
 					/*Datum menuId = */g_lingo->pop();
 					/*Datum itemId = */g_lingo->pop();
-					warning("c_v4theentitypush: STUB: mapping 0x%02x 0x%02x kTEAMenuIdItemId", bank, firstArg.u.i);
+					warning("c_v4theentitypush: STUB: kTEAMenuIdItemId");
 				}
 				break;
 			default:
@@ -244,6 +249,7 @@ void Lingo::c_v4theentityassign() {
 	if (firstArg.type == INT) {
 		int key = (bank << 8) + firstArg.u.i;
 		if (g_lingo->_lingoV4TheEntity.contains(key)) {
+			debugC(3, kDebugLingoExec, "c_v4theentityassign: mapping 0x%02x, 0x%02x", bank, firstArg.u.i);
 			if (g_lingo->_lingoV4TheEntity[key]->writable) {
 				int entity = g_lingo->_lingoV4TheEntity[key]->entity;
 				int field = g_lingo->_lingoV4TheEntity[key]->field;
@@ -253,26 +259,28 @@ void Lingo::c_v4theentityassign() {
 						Datum id;
 						id.u.s = NULL;
 						id.type = VOID;
+						debugC(3, kDebugLingoExec, "c_v4theentityassign: calling setTheEntity(0x%02x, NULL, 0x%02x, value)", entity, field);
 						g_lingo->setTheEntity(entity, id, field, value);
 					}
 					break;
 				case kTEAItemId:
 					{
 						Datum id = g_lingo->pop();
+						debugC(3, kDebugLingoExec, "c_v4theentityassign: calling setTheEntity(0x%02x, id, 0x%02x, value)", entity, field);
 						g_lingo->setTheEntity(entity, id, field, value);
 					}
 					break;
 				case kTEAString:
 					{
 						/*Datum stringArg = */g_lingo->pop();
-						warning("c_v4theentityassign: STUB: mapping 0x%02x 0x%02x kTEAString", bank, firstArg.u.i);
+						warning("c_v4theentityassign: STUB: kTEAString");
 					}
 					break;
 				case kTEAMenuIdItemId:
 					{
 						/*Datum menuId = */g_lingo->pop();
 						/*Datum itemId = */g_lingo->pop();
-						warning("c_v4theentityassign: STUB: mapping 0x%02x 0x%02x kTEAMenuIdItemId", bank, firstArg.u.i);
+						warning("c_v4theentityassign: STUB: kTEAMenuIdItemId");
 					}
 					break;
 				default:
@@ -355,8 +363,6 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 	byte *constsStore = (byte *)malloc(constsStoreSize);
 	stream.read(constsStore, constsStoreSize);
 
-	Common::Array<Datum> constsData;
-
 	// read each entry in the reference table.
 	stream.seek(constsOffset);
 	for (uint16 i = 0; i < constsCount; i++) {
@@ -412,7 +418,7 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 			break;
 		}
 
-		constsData.push_back(constant);
+		_currentScriptContext->constants.push_back(constant);
 	}
 	free(constsStore);
 
@@ -477,23 +483,34 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 			if (_lingoV4.contains(opcode)) {
 				offsetList.push_back(_currentScript->size());
 				g_lingo->code1(_lingoV4[opcode]->func);
+
 				size_t argc = strlen(_lingoV4[opcode]->proto);
-				for (uint c = 0; c < argc; c++) {
-					switch (_lingoV4[opcode]->proto[c]) {
-					case 'b':
-						offsetList.push_back(_currentScript->size());
-						g_lingo->codeInt((int8)codeStore[pointer]);
-						pointer += 1;
-						break;
-					case 'w':
-						offsetList.push_back(_currentScript->size());
-						offsetList.push_back(_currentScript->size());
-						g_lingo->codeInt((int16)READ_UINT16(&codeStore[pointer]));
-						pointer += 2;
-						break;
-					default:
-						break;
+				if (argc) {
+					int arg = 0;
+					for (uint c = 0; c < argc; c++) {
+						switch (_lingoV4[opcode]->proto[c]) {
+						case 'b':
+							offsetList.push_back(_currentScript->size());
+							arg = (int8)codeStore[pointer];
+							pointer += 1;
+							break;
+						case 'w':
+							offsetList.push_back(_currentScript->size());
+							offsetList.push_back(_currentScript->size());
+							arg = (int16)READ_UINT16(&codeStore[pointer]);
+							pointer += 2;
+							break;
+						case 'v':
+							if (arg % 6) {
+								warning("Opcode 0x%02x arg %d not multiple of 6!", opcode, arg);
+							}
+							arg /= 6;
+							break;
+						default:
+							break;
+						}
 					}
+					g_lingo->codeInt(arg);
 				}
 			} else {
 				// unimplemented instruction
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 5bab70c..ff9ae24 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -65,6 +65,7 @@ static struct FuncDescr {
 	{ Lingo::c_floatpush,	"c_floatpush",	"f" },
 	{ Lingo::c_stringpush,	"c_stringpush",	"s" },
 	{ Lingo::c_symbolpush,	"c_symbolpush",	"s" },	// D3
+	{ Lingo::c_constpush,	"c_constpush",	"i" },
 	{ Lingo::c_varpush,		"c_varpush",	"s" },
 	{ Lingo::c_setImmediate,"c_setImmediate","i" },
 	{ Lingo::c_assign,		"c_assign",		"" },
@@ -249,6 +250,14 @@ void Lingo::c_symbolpush() {
 	g_lingo->push(Datum(new Common::String(s)));
 }
 
+void Lingo::c_constpush() {
+	Datum d;
+	inst in = (*g_lingo->_currentScript)[g_lingo->_pc++];
+	int i = READ_UINT32(&in);
+	d = g_lingo->_currentScriptContext->constants[i];
+	g_lingo->push(d);
+}
+
 void Lingo::c_argspush() {
 	Datum d;
 	inst v = (*g_lingo->_currentScript)[g_lingo->_pc++];
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 1d4e8cf..e4f8a59 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -143,6 +143,7 @@ struct Builtin {
 
 struct ScriptContext {
 	Common::Array<ScriptData *> functions;
+	Common::Array<Datum> constants;
 };
 
 typedef Common::HashMap<int32, ScriptContext *> ScriptContextHash;
@@ -278,6 +279,7 @@ public:
 	static void c_floatpush();
 	static void c_stringpush();
 	static void c_symbolpush();
+	static void c_constpush();
 	static void c_varpush();
 	static void c_argspush();
 	static void c_arraypush();


Commit: 13cffcd6a2a910eb28ea62e7b7531daa625f6c20
    https://github.com/scummvm/scummvm/commit/13cffcd6a2a910eb28ea62e7b7531daa625f6c20
Author: Scott Percival (code at moral.net.au)
Date: 2019-12-02T21:57:09+08:00

Commit Message:
DIRECTOR: Add stubs for c_jump and c_jumpif

Changed paths:
    engines/director/lingo/lingo-bytecode.cpp
    engines/director/lingo/lingo-code.cpp
    engines/director/lingo/lingo.h


diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 6155c3d..c08a845 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -58,12 +58,17 @@ static LingoV4Bytecode lingoV4[] = {
 	{ 0x43, Lingo::c_arraypush, "b" },
 	{ 0x44, Lingo::c_constpush, "bv" },
 	{ 0x45, Lingo::c_symbolpush, "b" },
+	{ 0x53, Lingo::c_jump, "bj" },
+	{ 0x54, Lingo::c_jump, "bnj" },
+	{ 0x55, Lingo::c_jumpif, "bj" },
 	{ 0x5c, Lingo::c_v4theentitypush, "b" },
 	{ 0x5d, Lingo::c_v4theentityassign, "b" },
 	{ 0x81, Lingo::c_intpush, "w" },
 	{ 0x82, Lingo::c_argspush, "w" },
 	{ 0x83, Lingo::c_arraypush, "w" },
 	{ 0x84, Lingo::c_constpush, "wv" },
+	{ 0x93, Lingo::c_jump, "wj" },
+	{ 0x95, Lingo::c_jumpif, "wj" },
 	{ 0, 0, 0 }
 };
 
@@ -476,6 +481,7 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 
 		uint16 pointer = startOffset - codeStoreOffset;
 		Common::Array<uint32> offsetList;
+		Common::Array<uint32> jumpList;
 		while (pointer < startOffset + length - codeStoreOffset) {
 			uint8 opcode = codeStore[pointer];
 
@@ -502,10 +508,16 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 							break;
 						case 'v':
 							if (arg % 6) {
-								warning("Opcode 0x%02x arg %d not multiple of 6!", opcode, arg);
+								warning("Opcode 0x%02x arg %d not a multiple of 6!", opcode, arg);
 							}
 							arg /= 6;
 							break;
+						case 'n':
+							arg *= -1;
+							break;
+						case 'j':
+							jumpList.push_back(offsetList.size());
+							break;
 						default:
 							break;
 						}
@@ -540,7 +552,6 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 				}
 			}
 		}
-
 	}
 	free(codeStore);
 }
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index ff9ae24..0fc99b3 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -108,6 +108,8 @@ static struct FuncDescr {
 	{ Lingo::c_lt,			"c_lt",			"" },
 	{ Lingo::c_ge,			"c_ge",			"" },
 	{ Lingo::c_le,			"c_le",			"" },
+	{ Lingo::c_jump,		"c_jump",		"i" },
+	{ Lingo::c_jumpif,		"c_jumpif",		"i" },
 	{ Lingo::c_repeatwhilecode,"c_repeatwhilecode","oo" },
 	{ Lingo::c_repeatwithcode,"c_repeatwithcode","ooooos" },
 	{ Lingo::c_exitRepeat,	"c_exitRepeat",	"" },
@@ -892,6 +894,15 @@ void Lingo::c_le() {
 	g_lingo->push(d1);
 }
 
+void Lingo::c_jump() {
+	warning("STUB: c_jump()");
+}
+
+void Lingo::c_jumpif() {
+	g_lingo->pop();
+	warning("STUB: c_jumpif()");
+}
+
 void Lingo::c_repeatwhilecode(void) {
 	Datum d;
 	int savepc = g_lingo->_pc;
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index e4f8a59..937d2ef 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -309,6 +309,8 @@ public:
 	static void c_lt();
 	static void c_ge();
 	static void c_le();
+	static void c_jump();
+	static void c_jumpif();
 	static void c_call();
 
 	void call(Common::String name, int nargs);


Commit: f7fee0145b755782c190203c3aa9a2cd54ee95a1
    https://github.com/scummvm/scummvm/commit/f7fee0145b755782c190203c3aa9a2cd54ee95a1
Author: Scott Percival (code at moral.net.au)
Date: 2019-12-02T21:57:09+08:00

Commit Message:
DIRECTOR: Replace code int/double parsing with inline function

Changed paths:
    engines/director/lingo/lingo-bytecode.cpp
    engines/director/lingo/lingo-code.cpp
    engines/director/lingo/lingo-codegen.cpp
    engines/director/lingo/lingo.h


diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index c08a845..131a182 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -181,8 +181,7 @@ void Lingo::initBytecode() {
 
 
 void Lingo::c_v4theentitypush() {
-	inst b = (*g_lingo->_currentScript)[g_lingo->_pc++];
-	int bank = (int)READ_UINT32(&b);
+	int bank = g_lingo->readInt();
 
 	Datum firstArg = g_lingo->pop();
 	Datum result;
@@ -242,8 +241,7 @@ void Lingo::c_v4theentitypush() {
 
 
 void Lingo::c_v4theentityassign() {
-	inst b = (*g_lingo->_currentScript)[g_lingo->_pc++];
-	int bank = (int)READ_UINT32(&b);
+	int bank = g_lingo->readInt();
 
 	Datum firstArg = g_lingo->pop();
 	Datum value = g_lingo->pop();
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 0fc99b3..7c05385 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -60,7 +60,7 @@ static struct FuncDescr {
 	{ Lingo::c_argspush,	"c_argspush",	"i" },
 	{ Lingo::c_arraypush,	"c_arraypush",	"i" },
 	{ Lingo::c_printtop,	"c_printtop",	"" },
-	{ Lingo::c_intpush,	"c_intpush",	"i" },
+	{ Lingo::c_intpush,		"c_intpush",	"i" },
 	{ Lingo::c_voidpush,	"c_voidpush",	"" },
 	{ Lingo::c_floatpush,	"c_floatpush",	"f" },
 	{ Lingo::c_stringpush,	"c_stringpush",	"s" },
@@ -211,8 +211,7 @@ void Lingo::c_printtop(void) {
 
 void Lingo::c_intpush() {
 	Datum d;
-	inst i = (*g_lingo->_currentScript)[g_lingo->_pc++];
-	d.u.i = READ_UINT32(&i);
+	d.u.i = g_lingo->readInt();
 	d.type = INT;
 	g_lingo->push(d);
 }
@@ -226,12 +225,8 @@ void Lingo::c_voidpush() {
 
 void Lingo::c_floatpush() {
 	Datum d;
-	inst i = (*g_lingo->_currentScript)[g_lingo->_pc];
-	d.u.f = *(double *)(&i);
+	d.u.f = g_lingo->readFloat();
 	d.type = FLOAT;
-
-	g_lingo->_pc += g_lingo->calcCodeAlignment(sizeof(double));
-
 	g_lingo->push(d);
 }
 
@@ -254,16 +249,14 @@ void Lingo::c_symbolpush() {
 
 void Lingo::c_constpush() {
 	Datum d;
-	inst in = (*g_lingo->_currentScript)[g_lingo->_pc++];
-	int i = READ_UINT32(&in);
+	int i = g_lingo->readInt();
 	d = g_lingo->_currentScriptContext->constants[i];
 	g_lingo->push(d);
 }
 
 void Lingo::c_argspush() {
 	Datum d;
-	inst v = (*g_lingo->_currentScript)[g_lingo->_pc++];
-	int argsSize = READ_UINT32(&v);
+	int argsSize = g_lingo->readInt();
 
 	warning("STUB: c_argspush()");
 
@@ -277,8 +270,7 @@ void Lingo::c_argspush() {
 
 void Lingo::c_arraypush() {
 	Datum d;
-	inst v = (*g_lingo->_currentScript)[g_lingo->_pc++];
-	int arraySize = READ_UINT32(&v);
+	int arraySize = g_lingo->readInt();
 
 	warning("STUB: c_arraypush()");
 
@@ -327,9 +319,7 @@ void Lingo::c_varpush() {
 }
 
 void Lingo::c_setImmediate() {
-	inst i = (*g_lingo->_currentScript)[g_lingo->_pc++];
-
-	g_lingo->_immediateMode = READ_UINT32(&i);
+	g_lingo->_immediateMode = g_lingo->readInt();
 }
 
 void Lingo::c_assign() {
@@ -448,24 +438,20 @@ void Lingo::c_eval() {
 }
 
 void Lingo::c_theentitypush() {
-	inst e = (*g_lingo->_currentScript)[g_lingo->_pc++];
-	inst f = (*g_lingo->_currentScript)[g_lingo->_pc++];
 	Datum id = g_lingo->pop();
 
-	int entity = READ_UINT32(&e);
-	int field  = READ_UINT32(&f);
+	int entity = g_lingo->readInt();
+	int field  = g_lingo->readInt();
 
 	Datum d = g_lingo->getTheEntity(entity, id, field);
 	g_lingo->push(d);
 }
 
 void Lingo::c_theentityassign() {
-	inst e = (*g_lingo->_currentScript)[g_lingo->_pc++];
-	inst f = (*g_lingo->_currentScript)[g_lingo->_pc++];
 	Datum id = g_lingo->pop();
 
-	int entity = READ_UINT32(&e);
-	int field  = READ_UINT32(&f);
+	int entity = g_lingo->readInt();
+	int field  = g_lingo->readInt();
 
 	Datum d = g_lingo->pop();
 	g_lingo->setTheEntity(entity, id, field, d);
@@ -907,8 +893,8 @@ void Lingo::c_repeatwhilecode(void) {
 	Datum d;
 	int savepc = g_lingo->_pc;
 
-	uint body = READ_UINT32(&(*g_lingo->_currentScript)[savepc]);
-	uint end =  READ_UINT32(&(*g_lingo->_currentScript)[savepc + 1]);
+	uint body = g_lingo->getInt(savepc);
+	uint end =  g_lingo->getInt(savepc + 1);
 
 	g_lingo->execute(savepc + 2);	/* condition */
 	d = g_lingo->pop();
@@ -937,11 +923,11 @@ void Lingo::c_repeatwithcode(void) {
 	Datum d;
 	int savepc = g_lingo->_pc;
 
-	uint init = READ_UINT32(&(*g_lingo->_currentScript)[savepc]);
-	uint finish =  READ_UINT32(&(*g_lingo->_currentScript)[savepc + 1]);
-	uint body = READ_UINT32(&(*g_lingo->_currentScript)[savepc + 2]);
-	int inc = (int32)READ_UINT32(&(*g_lingo->_currentScript)[savepc + 3]);
-	uint end =  READ_UINT32(&(*g_lingo->_currentScript)[savepc + 4]);
+	uint init = g_lingo->getInt(savepc);
+	uint finish =  g_lingo->getInt(savepc + 1);
+	uint body = g_lingo->getInt(savepc + 2);
+	int inc = (int32)g_lingo->getInt(savepc + 3);
+	uint end = g_lingo->getInt(savepc + 4);
 	Common::String countername((char *)&(*g_lingo->_currentScript)[savepc + 5]);
 	Symbol *counter = g_lingo->lookupVar(countername.c_str());
 
@@ -986,10 +972,10 @@ void Lingo::c_ifcode() {
 	Datum d;
 	int savepc = g_lingo->_pc;	/* then part */
 
-	uint then =    READ_UINT32(&(*g_lingo->_currentScript)[savepc]);
-	uint elsep =   READ_UINT32(&(*g_lingo->_currentScript)[savepc + 1]);
-	uint end =     READ_UINT32(&(*g_lingo->_currentScript)[savepc + 2]);
-	uint skipEnd = READ_UINT32(&(*g_lingo->_currentScript)[savepc + 3]);
+	uint then =    g_lingo->getInt(savepc);
+	uint elsep =   g_lingo->getInt(savepc+1);
+	uint end =     g_lingo->getInt(savepc+2);
+	uint skipEnd = g_lingo->getInt(savepc+3);
 
 	debugC(8, kDebugLingoExec, "executing cond (have to %s end)", skipEnd ? "skip" : "execute");
 	g_lingo->execute(savepc + 4);	/* condition */
@@ -1015,7 +1001,7 @@ void Lingo::c_ifcode() {
 void Lingo::c_whencode() {
 	Datum d;
 	uint start = g_lingo->_pc;
-	uint end = READ_UINT32(&(*g_lingo->_currentScript)[start]) + start - 1;
+	uint end = g_lingo->getInt(start) + start - 1;
 	Common::String eventname((char *)&(*g_lingo->_currentScript)[start + 1]);
 
 	start += g_lingo->calcStringAlignment(eventname.c_str()) + 1;
@@ -1103,7 +1089,7 @@ void Lingo::c_call() {
 	Common::String name((char *)&(*g_lingo->_currentScript)[g_lingo->_pc]);
 	g_lingo->_pc += g_lingo->calcStringAlignment(name.c_str());
 
-	int nargs = READ_UINT32(&(*g_lingo->_currentScript)[g_lingo->_pc++]);
+	int nargs = g_lingo->readInt();
 
 	g_lingo->call(name, nargs);
 }
@@ -1289,27 +1275,21 @@ void Lingo::c_hilite() {
 }
 
 void Lingo::c_unk() {
-	int savepc = g_lingo->_pc;
-	uint opcode = READ_UINT32(&(*g_lingo->_currentScript)[savepc]);
+	uint opcode = g_lingo->readInt();
 	warning("STUB: opcode 0x%02x", opcode);
-	g_lingo->_pc += 1;
 }
 
 void Lingo::c_unk1() {
-	int savepc = g_lingo->_pc;
-	uint opcode = READ_UINT32(&(*g_lingo->_currentScript)[savepc]);
-	uint arg1 = READ_UINT32(&(*g_lingo->_currentScript)[savepc+1]);
+	uint opcode = g_lingo->readInt();
+	uint arg1 = g_lingo->readInt();
 	warning("STUB: opcode 0x%02x (%d)", opcode, arg1);
-	g_lingo->_pc += 2;
 }
 
 void Lingo::c_unk2() {
-	int savepc = g_lingo->_pc;
-	uint opcode = READ_UINT32(&(*g_lingo->_currentScript)[savepc]);
-	uint arg1 = READ_UINT32(&(*g_lingo->_currentScript)[savepc+1]);
-	uint arg2 = READ_UINT32(&(*g_lingo->_currentScript)[savepc+2]);
+	uint opcode = g_lingo->readInt();
+	uint arg1 = g_lingo->readInt();
+	uint arg2 = g_lingo->readInt();
 	warning("STUB: opcode 0x%02x (%d, %d)", opcode, arg1, arg2);
-	g_lingo->_pc += 3;
 }
 
 
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index e08844e..c317e42 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -93,7 +93,6 @@ Common::String Lingo::decodeInstruction(ScriptData *sd, uint pc, uint *newPc) {
 	if (_functions.contains((void *)sym.u.s)) {
 		res = _functions[(void *)sym.u.s]->name;
 		const char *pars = _functions[(void *)sym.u.s]->proto;
-		inst i;
 
 		while (*pars) {
 			switch (*pars++) {
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 937d2ef..fb5345b 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -238,6 +238,13 @@ public:
 	int codeFloat(double f);
 	void codeFactory(Common::String &s);
 
+	inst readInst() { return getInst(_pc++); }
+	inst getInst(uint pc) { return (*_currentScript)[pc]; }
+	int readInt() { return getInt(_pc++); }
+	int getInt(uint pc) { return (int)READ_UINT32(&((*_currentScript)[pc])); }
+	double readFloat() { double d = getFloat(_pc); _pc += calcCodeAlignment(sizeof(double)); return d; }
+	double getFloat(uint pc) { return *(double *)(&((*_currentScript)[pc])); }
+
 	void pushVoid();
 
 	static void c_xpop();


Commit: 29be7c0fa6af06fed0965348e880e908273e05f1
    https://github.com/scummvm/scummvm/commit/29be7c0fa6af06fed0965348e880e908273e05f1
Author: Scott Percival (code at moral.net.au)
Date: 2019-12-02T21:57:09+08:00

Commit Message:
DIRECTOR: Implement c_jump and c_jumpif

Changed paths:
    engines/director/lingo/lingo-bytecode.cpp
    engines/director/lingo/lingo-code.cpp


diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 131a182..f606d72 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -58,17 +58,18 @@ static LingoV4Bytecode lingoV4[] = {
 	{ 0x43, Lingo::c_arraypush, "b" },
 	{ 0x44, Lingo::c_constpush, "bv" },
 	{ 0x45, Lingo::c_symbolpush, "b" },
-	{ 0x53, Lingo::c_jump, "bj" },
-	{ 0x54, Lingo::c_jump, "bnj" },
-	{ 0x55, Lingo::c_jumpif, "bj" },
+	{ 0x53, Lingo::c_jump, "jb" },
+	{ 0x54, Lingo::c_jump, "jbn" },
+	{ 0x55, Lingo::c_jumpif, "jb" },
 	{ 0x5c, Lingo::c_v4theentitypush, "b" },
 	{ 0x5d, Lingo::c_v4theentityassign, "b" },
 	{ 0x81, Lingo::c_intpush, "w" },
 	{ 0x82, Lingo::c_argspush, "w" },
 	{ 0x83, Lingo::c_arraypush, "w" },
 	{ 0x84, Lingo::c_constpush, "wv" },
-	{ 0x93, Lingo::c_jump, "wj" },
-	{ 0x95, Lingo::c_jumpif, "wj" },
+	{ 0x93, Lingo::c_jump, "jw" },
+	{ 0x94, Lingo::c_jump, "jwn" },
+	{ 0x95, Lingo::c_jumpif, "jw" },
 	{ 0, 0, 0 }
 };
 
@@ -501,7 +502,7 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 						case 'w':
 							offsetList.push_back(_currentScript->size());
 							offsetList.push_back(_currentScript->size());
-							arg = (int16)READ_UINT16(&codeStore[pointer]);
+							arg = (int16)READ_BE_UINT16(&codeStore[pointer]);
 							pointer += 2;
 							break;
 						case 'v':
@@ -550,6 +551,22 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 				}
 			}
 		}
+
+		// Rewrite every offset flagged as a jump based on the new code alignment.
+		// This converts the relative offset from the bytecode to an absolute one.
+		for (uint j = 0; j < jumpList.size(); j++) {
+			int originalJumpAddressLoc = jumpList[j];
+			int originalJumpInstructionLoc = originalJumpAddressLoc-1;
+			int jumpAddressPc = offsetList[originalJumpAddressLoc];
+			int jump = getInt(jumpAddressPc);
+			int oldTarget = originalJumpInstructionLoc + jump;
+			if ((oldTarget >= 0) && (oldTarget < (int)offsetList.size())) {
+				int newJump = offsetList[oldTarget];
+				WRITE_UINT32(&((*_currentScript)[jumpAddressPc]), newJump);
+			} else {
+				warning("Jump of %d from position %d is outside the function!", jump, originalJumpAddressLoc);
+			}
+		}
 	}
 	free(codeStore);
 }
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 7c05385..9e11480 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -881,12 +881,17 @@ void Lingo::c_le() {
 }
 
 void Lingo::c_jump() {
-	warning("STUB: c_jump()");
+	uint jump = g_lingo->readInt();
+	g_lingo->_pc = jump;
 }
 
 void Lingo::c_jumpif() {
-	g_lingo->pop();
-	warning("STUB: c_jumpif()");
+	uint jump = g_lingo->readInt();
+	Datum test = g_lingo->pop();
+	test.toInt();
+	if (test.u.i) {
+		g_lingo->_pc = jump;
+	}
 }
 
 void Lingo::c_repeatwhilecode(void) {


Commit: 473a2b7463bc44a2535c61e7efad2157120d2daf
    https://github.com/scummvm/scummvm/commit/473a2b7463bc44a2535c61e7efad2157120d2daf
Author: Scott Percival (code at moral.net.au)
Date: 2019-12-02T21:57:10+08:00

Commit Message:
DIRECTOR: Add readString and getString

Changed paths:
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-code.cpp
    engines/director/lingo/lingo.h


diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 95b83e9..9f29d4c 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -1316,10 +1316,10 @@ void Lingo::b_point(int nargs) {
 	x.toFloat();
 	y.toFloat();
 
-	d.u.arr = new FloatArray;
+	d.u.farr = new FloatArray;
 
-	d.u.arr->push_back(x.u.f);
-	d.u.arr->push_back(y.u.f);
+	d.u.farr->push_back(x.u.f);
+	d.u.farr->push_back(y.u.f);
 	d.type = POINT;
 
 	g_lingo->push(d);
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 9e11480..38bd6e4 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -196,7 +196,7 @@ void Lingo::c_printtop(void) {
 		warning("%s", d.u.s->c_str());
 		break;
 	case POINT:
-		warning("point(%d, %d)", (int)((*d.u.arr)[0]), (int)((*d.u.arr)[1]));
+		warning("point(%d, %d)", (int)((*d.u.farr)[0]), (int)((*d.u.farr)[1]));
 		break;
 	case SYMBOL:
 		warning("%s", d.type2str(true));
@@ -231,15 +231,13 @@ void Lingo::c_floatpush() {
 }
 
 void Lingo::c_stringpush() {
-	char *s = (char *)&(*g_lingo->_currentScript)[g_lingo->_pc];
-	g_lingo->_pc += g_lingo->calcStringAlignment(s);
+	char *s = g_lingo->readString();
 
 	g_lingo->push(Datum(new Common::String(s)));
 }
 
 void Lingo::c_symbolpush() {
-	char *s = (char *)&(*g_lingo->_currentScript)[g_lingo->_pc];
-	g_lingo->_pc += g_lingo->calcStringAlignment(s);
+	char *s = g_lingo->readString();
 
 	warning("STUB: c_symbolpush()");
 
@@ -283,11 +281,9 @@ void Lingo::c_arraypush() {
 }
 
 void Lingo::c_varpush() {
-	Common::String name((char *)&(*g_lingo->_currentScript)[g_lingo->_pc]);
+	Common::String name(g_lingo->readString());
 	Datum d;
 
-	g_lingo->_pc += g_lingo->calcStringAlignment(name.c_str());
-
 	// In immediate mode we will push variables as strings
 	// This is used for playAccel
 	if (g_lingo->_immediateMode) {
@@ -360,7 +356,7 @@ void Lingo::c_assign() {
 		delete d1.u.sym->u.s;
 
 	if (d1.u.sym->type == POINT || d1.u.sym->type == RECT || d1.u.sym->type == ARRAY)
-		delete d1.u.sym->u.arr;
+		delete d1.u.sym->u.farr;
 
 	if (d2.type == INT) {
 		d1.u.sym->u.i = d2.u.i;
@@ -370,8 +366,8 @@ void Lingo::c_assign() {
 		d1.u.sym->u.s = new Common::String(*d2.u.s);
 		delete d2.u.s;
 	} else if (d2.type == POINT) {
-		d1.u.sym->u.arr = new FloatArray(*d2.u.arr);
-		delete d2.u.arr;
+		d1.u.sym->u.farr = new FloatArray(*d2.u.farr);
+		delete d2.u.farr;
 	} else if (d2.type == SYMBOL) {
 		d1.u.sym->u.i = d2.u.i;
 	} else if (d2.type == OBJECT) {
@@ -426,7 +422,7 @@ void Lingo::c_eval() {
 	else if (d.u.sym->type == STRING)
 		d.u.s = new Common::String(*d.u.sym->u.s);
 	else if (d.u.sym->type == POINT)
-		d.u.arr = d.u.sym->u.arr;
+		d.u.farr = d.u.sym->u.farr;
 	else if (d.u.sym->type == SYMBOL)
 		d.u.i = d.u.sym->u.i;
 	else if (d.u.sym->type == VOID)
@@ -889,7 +885,7 @@ void Lingo::c_jumpif() {
 	uint jump = g_lingo->readInt();
 	Datum test = g_lingo->pop();
 	test.toInt();
-	if (test.u.i) {
+	if (test.u.i == 0) {
 		g_lingo->_pc = jump;
 	}
 }
@@ -1006,10 +1002,10 @@ void Lingo::c_ifcode() {
 void Lingo::c_whencode() {
 	Datum d;
 	uint start = g_lingo->_pc;
-	uint end = g_lingo->getInt(start) + start - 1;
-	Common::String eventname((char *)&(*g_lingo->_currentScript)[start + 1]);
+	uint end = g_lingo->readInt() + start - 1;
+	Common::String eventname(g_lingo->readString())
 
-	start += g_lingo->calcStringAlignment(eventname.c_str()) + 1;
+	start = g_lingo->_pc;
 
 	debugC(1, kDebugLingoExec, "c_whencode([%5d][%5d], %s)", start, end, eventname.c_str());
 
@@ -1091,8 +1087,7 @@ void Lingo::c_playdone() {
 }
 
 void Lingo::c_call() {
-	Common::String name((char *)&(*g_lingo->_currentScript)[g_lingo->_pc]);
-	g_lingo->_pc += g_lingo->calcStringAlignment(name.c_str());
+	Common::String name(g_lingo->readString());
 
 	int nargs = g_lingo->readInt();
 
@@ -1223,7 +1218,7 @@ void Lingo::c_procret() {
 }
 
 void Lingo::c_global() {
-	Common::String name((char *)&(*g_lingo->_currentScript)[g_lingo->_pc]);
+	Common::String name(g_lingo->readString());
 
 	Symbol *s = g_lingo->lookupVar(name.c_str(), false);
 	if (s && !s->global) {
@@ -1232,24 +1227,18 @@ void Lingo::c_global() {
 
 	s = g_lingo->lookupVar(name.c_str(), true, true);
 	s->global = true;
-
-	g_lingo->_pc += g_lingo->calcStringAlignment(name.c_str());
 }
 
 void Lingo::c_property() {
-	Common::String name((char *)&(*g_lingo->_currentScript)[g_lingo->_pc]);
-
-	g_lingo->_pc += g_lingo->calcStringAlignment(name.c_str());
+	Common::String name(g_lingo->readString());
 
 	warning("STUB: c_property()");
 }
 
 void Lingo::c_instance() {
-	Common::String name((char *)&(*g_lingo->_currentScript)[g_lingo->_pc]);
+	Common::String name(g_lingo->readString());
 
 	warning("STUB: c_instance(%s)", name.c_str());
-
-	g_lingo->_pc += g_lingo->calcStringAlignment(name.c_str());
 }
 
 void Lingo::c_open() {
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index fb5345b..1256671 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -100,7 +100,7 @@ struct Symbol {	/* symbol table entry */
 		void (*func)();		/* OPCODE */
 		void (*bltin)(int);	/* BUILTIN */
 		Common::String	*s;	/* STRING */
-		FloatArray *arr;	/* ARRAY, POINT, RECT */
+		FloatArray *farr;	/* ARRAY, POINT, RECT */
 	} u;
 	int nargs;		/* number of arguments */
 	int maxArgs;	/* maximal number of arguments, for builtins */
@@ -119,7 +119,7 @@ struct Datum {	/* interpreter stack type */
 		double f;
 		Common::String *s;
 		Symbol	*sym;
-		FloatArray *arr;	/* ARRAY, POINT, RECT */
+		FloatArray *farr;	/* ARRAY, POINT, RECT */
 	} u;
 
 	Datum() { u.sym = NULL; type = VOID; }
@@ -244,6 +244,8 @@ public:
 	int getInt(uint pc) { return (int)READ_UINT32(&((*_currentScript)[pc])); }
 	double readFloat() { double d = getFloat(_pc); _pc += calcCodeAlignment(sizeof(double)); return d; }
 	double getFloat(uint pc) { return *(double *)(&((*_currentScript)[pc])); }
+	char *readString() { char *s = getString(_pc); _pc += calcStringAlignment(s); return s; }
+	char *getString(uint pc) { return (char *)(&((*_currentScript)[pc])); }
 
 	void pushVoid();
 


Commit: f1b0c10fe4f810527e73b58642eed0e512243ae0
    https://github.com/scummvm/scummvm/commit/f1b0c10fe4f810527e73b58642eed0e512243ae0
Author: Scott Percival (code at moral.net.au)
Date: 2019-12-02T21:57:10+08:00

Commit Message:
DIRECTOR: Show code offsets for stack printouts in Lingo::execute

Changed paths:
    engines/director/lingo/lingo-code.cpp
    engines/director/lingo/lingo-codegen.cpp
    engines/director/lingo/lingo.h


diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 38bd6e4..f823209 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -1003,7 +1003,7 @@ void Lingo::c_whencode() {
 	Datum d;
 	uint start = g_lingo->_pc;
 	uint end = g_lingo->readInt() + start - 1;
-	Common::String eventname(g_lingo->readString())
+	Common::String eventname(g_lingo->readString());
 
 	start = g_lingo->_pc;
 
diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index c317e42..0e3904e 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -55,17 +55,18 @@ namespace Director {
 void Lingo::execute(uint pc) {
 	for (_pc = pc; !_returning && (*_currentScript)[_pc] != STOP;) {
 		Common::String instr = decodeInstruction(_currentScript, _pc);
+		uint current = _pc;
 
 		if (debugChannelSet(5, kDebugLingoExec))
-			printStack("Stack before: ");
+			printStack("Stack before: ", current);
 
-		debugC(1, kDebugLingoExec, "[%3d]: %s", _pc, instr.c_str());
+		debugC(1, kDebugLingoExec, "[%3d]: %s", current, instr.c_str());
 
 		_pc++;
 		(*((*_currentScript)[_pc - 1]))();
 
 		if (debugChannelSet(5, kDebugLingoExec))
-			printStack("Stack after: ");
+			printStack("Stack after: ", current);
 
 		if (_pc >= (*_currentScript).size()) {
 			warning("Lingo::execute(): Bad PC (%d)", _pc);
@@ -74,7 +75,7 @@ void Lingo::execute(uint pc) {
 	}
 }
 
-void Lingo::printStack(const char *s) {
+void Lingo::printStack(const char *s, uint pc) {
 	Common::String stack(s);
 
 	for (uint i = 0; i < _stack.size(); i++) {
@@ -82,7 +83,7 @@ void Lingo::printStack(const char *s) {
 		d.toString();
 		stack += Common::String::format("<%s> ", d.u.s->c_str());
 	}
-	debugC(5, kDebugLingoExec, "%s", stack.c_str());
+	debugC(5, kDebugLingoExec, "[%3d]: %s", pc, stack.c_str());
 }
 
 Common::String Lingo::decodeInstruction(ScriptData *sd, uint pc, uint *newPc) {
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 1256671..d434bda 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -172,7 +172,7 @@ public:
 	void addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType type, uint16 id);
 	void addNamesV4(Common::SeekableSubReadStreamEndian &stream);
 	void executeScript(ScriptType type, uint16 id, uint16 function);
-	void printStack(const char *s);
+	void printStack(const char *s, uint pc);
 	Common::String decodeInstruction(ScriptData *sd, uint pc, uint *newPC = NULL);
 
 	void initBuiltIns();


Commit: 237a5f97a84c19d2b3aedf45bf1049413da701ba
    https://github.com/scummvm/scummvm/commit/237a5f97a84c19d2b3aedf45bf1049413da701ba
Author: Scott Percival (code at moral.net.au)
Date: 2019-12-02T21:57:10+08:00

Commit Message:
DIRECTOR: Comments for bytecode argument parser

Changed paths:
    engines/director/lingo/lingo-bytecode.cpp


diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index f606d72..131dbb7 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -495,26 +495,31 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
 					for (uint c = 0; c < argc; c++) {
 						switch (_lingoV4[opcode]->proto[c]) {
 						case 'b':
+							// read one uint8 as an argument
 							offsetList.push_back(_currentScript->size());
-							arg = (int8)codeStore[pointer];
+							arg = (uint8)codeStore[pointer];
 							pointer += 1;
 							break;
 						case 'w':
+							// read one uint16 as an argument
 							offsetList.push_back(_currentScript->size());
 							offsetList.push_back(_currentScript->size());
-							arg = (int16)READ_BE_UINT16(&codeStore[pointer]);
+							arg = (uint16)READ_BE_UINT16(&codeStore[pointer]);
 							pointer += 2;
 							break;
 						case 'v':
+							// argument refers to a variable; remove struct size alignment
 							if (arg % 6) {
 								warning("Opcode 0x%02x arg %d not a multiple of 6!", opcode, arg);
 							}
 							arg /= 6;
 							break;
 						case 'n':
+							// argument is negative
 							arg *= -1;
 							break;
 						case 'j':
+							// argument refers to a code offset; fix alignment in post
 							jumpList.push_back(offsetList.size());
 							break;
 						default:


Commit: 472e7f138051be17533b878be2efc6fa1111e1c5
    https://github.com/scummvm/scummvm/commit/472e7f138051be17533b878be2efc6fa1111e1c5
Author: Scott Percival (code at moral.net.au)
Date: 2019-12-02T21:57:10+08:00

Commit Message:
DIRECTOR: Correct rebase mistake

Changed paths:
    engines/director/lingo/lingo-codegen.cpp


diff --git a/engines/director/lingo/lingo-codegen.cpp b/engines/director/lingo/lingo-codegen.cpp
index 0e3904e..446c5fa 100644
--- a/engines/director/lingo/lingo-codegen.cpp
+++ b/engines/director/lingo/lingo-codegen.cpp
@@ -94,6 +94,7 @@ Common::String Lingo::decodeInstruction(ScriptData *sd, uint pc, uint *newPc) {
 	if (_functions.contains((void *)sym.u.s)) {
 		res = _functions[(void *)sym.u.s]->name;
 		const char *pars = _functions[(void *)sym.u.s]->proto;
+		inst i;
 
 		while (*pars) {
 			switch (*pars++) {


Commit: a17f406bef2d19931685f139f8c352df5a486360
    https://github.com/scummvm/scummvm/commit/a17f406bef2d19931685f139f8c352df5a486360
Author: Scott Percival (code at moral.net.au)
Date: 2019-12-02T21:57:10+08:00

Commit Message:
DIRECTOR: Adjust naming of some instructions

Changed paths:
    engines/director/lingo/lingo-bytecode.cpp
    engines/director/lingo/lingo-bytecode.h
    engines/director/lingo/lingo-code.cpp
    engines/director/lingo/lingo.h


diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 131dbb7..462650e 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -60,16 +60,16 @@ static LingoV4Bytecode lingoV4[] = {
 	{ 0x45, Lingo::c_symbolpush, "b" },
 	{ 0x53, Lingo::c_jump, "jb" },
 	{ 0x54, Lingo::c_jump, "jbn" },
-	{ 0x55, Lingo::c_jumpif, "jb" },
-	{ 0x5c, Lingo::c_v4theentitypush, "b" },
-	{ 0x5d, Lingo::c_v4theentityassign, "b" },
+	{ 0x55, Lingo::c_jumpifz, "jb" },
+	{ 0x5c, Lingo::cb_v4theentitypush, "b" },
+	{ 0x5d, Lingo::cb_v4theentityassign, "b" },
 	{ 0x81, Lingo::c_intpush, "w" },
 	{ 0x82, Lingo::c_argspush, "w" },
 	{ 0x83, Lingo::c_arraypush, "w" },
 	{ 0x84, Lingo::c_constpush, "wv" },
 	{ 0x93, Lingo::c_jump, "jw" },
 	{ 0x94, Lingo::c_jump, "jwn" },
-	{ 0x95, Lingo::c_jumpif, "jw" },
+	{ 0x95, Lingo::c_jumpifz, "jw" },
 	{ 0, 0, 0 }
 };
 
@@ -166,7 +166,7 @@ static LingoV4TheEntity lingoV4TheEntity[] = {
 	{ 0x0c, 0x07, kTheField, kTheTextSize, true, kTEAItemId },
 	{ 0x0d, 0x0f, kTheCast, kTheDirectToStage, true, kTEAItemId },
 	{ 0x0d, 0x10, kTheCast, kTheSound, true, kTEAItemId },
-	{ -1, 0, 0, 0, false, kTEANOArgs }
+	{ 0xff, 0, 0, 0, false, kTEANOArgs }
 };
 
 
@@ -175,13 +175,13 @@ void Lingo::initBytecode() {
 		_lingoV4[op->opcode] = op;
 	}
 
-	for (LingoV4TheEntity *ent = lingoV4TheEntity; ent->bank != -1; ent++) {
+	for (LingoV4TheEntity *ent = lingoV4TheEntity; ent->bank != 0xff; ent++) {
 		_lingoV4TheEntity[(ent->bank << 8) + ent->firstArg] = ent;
 	}
 }
 
 
-void Lingo::c_v4theentitypush() {
+void Lingo::cb_v4theentitypush() {
 	int bank = g_lingo->readInt();
 
 	Datum firstArg = g_lingo->pop();
@@ -192,7 +192,7 @@ void Lingo::c_v4theentitypush() {
 	if (firstArg.type == INT) {
 		int key = (bank << 8) + firstArg.u.i;
 		if (g_lingo->_lingoV4TheEntity.contains(key)) {
-			debugC(3, kDebugLingoExec, "c_v4theentitypush: mapping 0x%02x, 0x%02x", bank, firstArg.u.i);
+			debugC(3, kDebugLingoExec, "cb_v4theentitypush: mapping 0x%02x, 0x%02x", bank, firstArg.u.i);
 			int entity = g_lingo->_lingoV4TheEntity[key]->entity;
 			int field = g_lingo->_lingoV4TheEntity[key]->field;
 			switch (g_lingo->_lingoV4TheEntity[key]->type) {
@@ -201,47 +201,47 @@ void Lingo::c_v4theentitypush() {
 					Datum id;
 					id.u.s = NULL;
 					id.type = VOID;
-					debugC(3, kDebugLingoExec, "c_v4theentitypush: calling getTheEntity(0x%02x, NULL, 0x%02x)", entity, field);
+					debugC(3, kDebugLingoExec, "cb_v4theentitypush: calling getTheEntity(0x%02x, NULL, 0x%02x)", entity, field);
 					result = g_lingo->getTheEntity(entity, id, field);
 				}
 				break;
 			case kTEAItemId:
 				{
 					Datum id = g_lingo->pop();
-					debugC(3, kDebugLingoExec, "c_v4theentitypush: calling getTheEntity(0x%02x, id, 0x%02x)", entity, field);
+					debugC(3, kDebugLingoExec, "cb_v4theentitypush: calling getTheEntity(0x%02x, id, 0x%02x)", entity, field);
 					result = g_lingo->getTheEntity(entity, id, field);
 				}
 				break;
 			case kTEAString:
 				{
 					/*Datum stringArg = */g_lingo->pop();
-					warning("c_v4theentitypush: STUB: kTEAString");
+					warning("cb_v4theentitypush: STUB: kTEAString");
 				}
 				break;
 			case kTEAMenuIdItemId:
 				{
 					/*Datum menuId = */g_lingo->pop();
 					/*Datum itemId = */g_lingo->pop();
-					warning("c_v4theentitypush: STUB: kTEAMenuIdItemId");
+					warning("cb_v4theentitypush: STUB: kTEAMenuIdItemId");
 				}
 				break;
 			default:
-				warning("c_v4theentitypush: unknown call type %d", g_lingo->_lingoV4TheEntity[key]->type);
+				warning("cb_v4theentitypush: unknown call type %d", g_lingo->_lingoV4TheEntity[key]->type);
 				break;
 			}
 		} else {
-			warning("c_v4theentitypush: unhandled mapping 0x%02x 0x%02x", bank, firstArg.u.i);
+			warning("cb_v4theentitypush: unhandled mapping 0x%02x 0x%02x", bank, firstArg.u.i);
 		}
 
 	} else {
-		warning("c_v4theentitypush: first arg should be of type INT, not %s", firstArg.type2str());
+		warning("cb_v4theentitypush: first arg should be of type INT, not %s", firstArg.type2str());
 	}
 
 	g_lingo->push(result);
 }
 
 
-void Lingo::c_v4theentityassign() {
+void Lingo::cb_v4theentityassign() {
 	int bank = g_lingo->readInt();
 
 	Datum firstArg = g_lingo->pop();
@@ -253,7 +253,7 @@ void Lingo::c_v4theentityassign() {
 	if (firstArg.type == INT) {
 		int key = (bank << 8) + firstArg.u.i;
 		if (g_lingo->_lingoV4TheEntity.contains(key)) {
-			debugC(3, kDebugLingoExec, "c_v4theentityassign: mapping 0x%02x, 0x%02x", bank, firstArg.u.i);
+			debugC(3, kDebugLingoExec, "cb_v4theentityassign: mapping 0x%02x, 0x%02x", bank, firstArg.u.i);
 			if (g_lingo->_lingoV4TheEntity[key]->writable) {
 				int entity = g_lingo->_lingoV4TheEntity[key]->entity;
 				int field = g_lingo->_lingoV4TheEntity[key]->field;
@@ -263,43 +263,43 @@ void Lingo::c_v4theentityassign() {
 						Datum id;
 						id.u.s = NULL;
 						id.type = VOID;
-						debugC(3, kDebugLingoExec, "c_v4theentityassign: calling setTheEntity(0x%02x, NULL, 0x%02x, value)", entity, field);
+						debugC(3, kDebugLingoExec, "cb_v4theentityassign: calling setTheEntity(0x%02x, NULL, 0x%02x, value)", entity, field);
 						g_lingo->setTheEntity(entity, id, field, value);
 					}
 					break;
 				case kTEAItemId:
 					{
 						Datum id = g_lingo->pop();
-						debugC(3, kDebugLingoExec, "c_v4theentityassign: calling setTheEntity(0x%02x, id, 0x%02x, value)", entity, field);
+						debugC(3, kDebugLingoExec, "cb_v4theentityassign: calling setTheEntity(0x%02x, id, 0x%02x, value)", entity, field);
 						g_lingo->setTheEntity(entity, id, field, value);
 					}
 					break;
 				case kTEAString:
 					{
 						/*Datum stringArg = */g_lingo->pop();
-						warning("c_v4theentityassign: STUB: kTEAString");
+						warning("cb_v4theentityassign: STUB: kTEAString");
 					}
 					break;
 				case kTEAMenuIdItemId:
 					{
 						/*Datum menuId = */g_lingo->pop();
 						/*Datum itemId = */g_lingo->pop();
-						warning("c_v4theentityassign: STUB: kTEAMenuIdItemId");
+						warning("cb_v4theentityassign: STUB: kTEAMenuIdItemId");
 					}
 					break;
 				default:
-					warning("c_v4theentityassign: unknown call type %d", g_lingo->_lingoV4TheEntity[key]->type);
+					warning("cb_v4theentityassign: unknown call type %d", g_lingo->_lingoV4TheEntity[key]->type);
 					break;
 				}
 			} else {
-				warning("c_v4theentityassign: non-writable mapping 0x%02x 0x%02x", bank, firstArg.u.i);
+				warning("cb_v4theentityassign: non-writable mapping 0x%02x 0x%02x", bank, firstArg.u.i);
 			}
 		} else {
-			warning("c_v4theentityassign: unhandled mapping 0x%02x 0x%02x", bank, firstArg.u.i);
+			warning("cb_v4theentityassign: unhandled mapping 0x%02x 0x%02x", bank, firstArg.u.i);
 		}
 
 	} else {
-		warning("c_v4theentityassign: first arg should be of type INT, not %s", firstArg.type2str());
+		warning("cb_v4theentityassign: first arg should be of type INT, not %s", firstArg.type2str());
 	}
 }
 
diff --git a/engines/director/lingo/lingo-bytecode.h b/engines/director/lingo/lingo-bytecode.h
index 0e5f9b4..1f21f21 100644
--- a/engines/director/lingo/lingo-bytecode.h
+++ b/engines/director/lingo/lingo-bytecode.h
@@ -41,8 +41,8 @@ enum TheEntityArgsType {
 };
 
 struct LingoV4TheEntity {
-	const int bank;
-	const int firstArg;
+	const uint8 bank;
+	const uint8 firstArg;
 	const int entity;
 	const int field;
 	const bool writable;
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index f823209..fd00205 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -72,8 +72,6 @@ static struct FuncDescr {
 	{ Lingo::c_eval,		"c_eval",		"s" },
 	{ Lingo::c_theentitypush,"c_theentitypush","ii" }, // entity, field
 	{ Lingo::c_theentityassign,"c_theentityassign","ii" },
-	{ Lingo::c_v4theentitypush,"c_v4theentitypush","i" },
-	{ Lingo::c_v4theentityassign,"c_v4theentityassign","i" },
 	{ Lingo::c_swap,		"c_swap",		"" },
 	{ Lingo::c_add,			"c_add",		"" },
 	{ Lingo::c_sub,			"c_sub",		"" },
@@ -109,7 +107,7 @@ static struct FuncDescr {
 	{ Lingo::c_ge,			"c_ge",			"" },
 	{ Lingo::c_le,			"c_le",			"" },
 	{ Lingo::c_jump,		"c_jump",		"i" },
-	{ Lingo::c_jumpif,		"c_jumpif",		"i" },
+	{ Lingo::c_jumpifz,		"c_jumpifz",	"i" },
 	{ Lingo::c_repeatwhilecode,"c_repeatwhilecode","oo" },
 	{ Lingo::c_repeatwithcode,"c_repeatwithcode","ooooos" },
 	{ Lingo::c_exitRepeat,	"c_exitRepeat",	"" },
@@ -134,6 +132,8 @@ static struct FuncDescr {
 	{ Lingo::c_unk,         "c_unk",        "i" },
 	{ Lingo::c_unk1,        "c_unk1",       "ii" },
 	{ Lingo::c_unk2,        "c_unk2",       "iii" },
+	{ Lingo::cb_v4theentitypush,"c_v4theentitypush","i" },
+	{ Lingo::cb_v4theentityassign,"c_v4theentityassign","i" },
 	{ 0, 0, 0 }
 };
 
@@ -881,7 +881,7 @@ void Lingo::c_jump() {
 	g_lingo->_pc = jump;
 }
 
-void Lingo::c_jumpif() {
+void Lingo::c_jumpifz() {
 	uint jump = g_lingo->readInt();
 	Datum test = g_lingo->pop();
 	test.toInt();
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index d434bda..633f78b 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -301,8 +301,6 @@ public:
 
 	static void c_theentitypush();
 	static void c_theentityassign();
-	static void c_v4theentitypush();
-	static void c_v4theentityassign();
 
 	static void c_repeatwhilecode();
 	static void c_repeatwithcode();
@@ -319,7 +317,7 @@ public:
 	static void c_ge();
 	static void c_le();
 	static void c_jump();
-	static void c_jumpif();
+	static void c_jumpifz();
 	static void c_call();
 
 	void call(Common::String name, int nargs);
@@ -347,11 +345,16 @@ public:
 	static void c_unk1();
 	static void c_unk2();
 
+	// bytecode-related instructions
+	static void cb_v4theentitypush();
+	static void cb_v4theentityassign();
+
 	void printSTUBWithArglist(const char *funcname, int nargs, const char *prefix = "STUB:");
 	void convertVOIDtoString(int arg, int nargs);
 	void dropStack(int nargs);
 	void drop(uint num);
 
+	// builtin functions
 	static void b_abs(int nargs);
 	static void b_atan(int nargs);
 	static void b_cos(int nargs);




More information about the Scummvm-git-logs mailing list