@@ -30,10 +30,13 @@ class Opcodes(IntEnum):
30
30
NotEquals = 208
31
31
LessThan = 209
32
32
GreaterThan = 210
33
+ LessThanOrEqualTo = 211
34
+ GreaterThanOrEqualTo = 212
33
35
Add = 213
34
36
Subtract = 214
35
37
Divide = 216
36
- Unk2 = 218
38
+ Modulo = 217
39
+ Unk2 = 218 # TODO: Likely something with ## constants like ##DOWN?
37
40
CallRoutine = 219
38
41
# Method calls are like routine calls, but they have an implicit "self"
39
42
# parameter that is always the first. For example:
@@ -45,6 +48,8 @@ class Opcodes(IntEnum):
45
48
# given, then the next instructions are variable assignments for that number
46
49
# of variables.
47
50
DeclareVariables = 221
51
+ While = 224
52
+ Return = 222
48
53
49
54
class BuiltInFunction (IntEnum ):
50
55
# TODO: Split out routines and methods into different enums.
@@ -57,11 +62,12 @@ class BuiltInFunction(IntEnum):
57
62
# Currently it's only in var_7be1_cursor_currentTool in
58
63
# IBM/Crayola.
59
64
cursorSet = 200 # PARAMS: 0
60
- SpatialHide = 203 # PARAMS: 1
61
- SpatialShow = 202 # PARAMS: 1
62
- TimePlay = 206 # PARAMS: 1
63
- TimeStop = 207 # PARAMS: 0
64
- GetAt = 253 # PARAMS: 1
65
+ spatialHide = 203 # PARAMS: 1
66
+ spatialMoveTo = 204 # PARAMS: 2
67
+ # spatialZMoveTo
68
+ spatialShow = 202 # PARAMS: 1
69
+ timePlay = 206 # PARAMS: 1
70
+ timeStop = 207 # PARAMS: 0
65
71
isPlaying = 372
66
72
# debugBeep
67
73
# quit
@@ -74,10 +80,12 @@ class BuiltInFunction(IntEnum):
74
80
yPosiion = 234 # PARAMS: 0
75
81
TriggerAbsXPosition = 321 # PARAMS: 0
76
82
TriggerAbsYPosition = 322 # PARAMS: 0
83
+ isActive = 371 # PARAMS: 0
77
84
78
85
# IMAGE METHODS.
79
86
Width = 235 # PARAMS: 0
80
87
Height = 236 # PARAMS: 0
88
+ # isVisible
81
89
82
90
# SPRITE METHODS.
83
91
movieReset = 219 # PARAMS: 0
@@ -98,10 +106,33 @@ class BuiltInFunction(IntEnum):
98
106
# DOCUMENT METHODS.
99
107
loadContext = 374 # PARAMS: 1
100
108
releaseContext = 375 # PARAMS: 1
109
+ branchToScreen = 201 # PARAMS: 1
110
+ isLoaded = 376 # PARAMS: 1
101
111
102
112
# PATH METHODS.
103
113
percentComplete = 263
104
114
115
+ # TEXT METHODS.
116
+ text = 290
117
+ setText = 291
118
+ setMaximumTextLength = 293 # PARAM: 1
119
+
120
+ # COLLECTION METHODS.
121
+ # These aren't assets but arrays used in Media Script.
122
+ # isEmpty
123
+ empty = 252 # PARAMS: 0
124
+ append = 247 # PARAMS: 1+
125
+ getAt = 253 # PARAMS: 1
126
+ count = 249 # PARAMS: 0
127
+ # Looks like this lets you call a method on all the items in a collection.
128
+ # Examples look like : var_7be1_collect_shapes.send(spatialHide);
129
+ send = 257 # PARAMS: 1+. Looks like the first param is the function,
130
+ # and the next params are any arguments you want to send.
131
+ # Seeking seems to be finding the index where a certain item is.
132
+ seek = 256 # PARAMS: 1
133
+ sort = 266 # PARAMS: 0
134
+ deleteAt = 258 # PARAMS: 1
135
+
105
136
class OperandType (IntEnum ):
106
137
# TODO: Figure out the difference between these two.
107
138
Literal = 151
@@ -115,10 +146,12 @@ class OperandType(IntEnum):
115
146
DollarSignVariable = 155
116
147
AssetId = 156
117
148
Float = 157
118
- Unk = 158 # Appears when we are declaring collections.
149
+ VariableType = 158
150
+ Function = 160
119
151
120
152
class VariableScope (IntEnum ):
121
153
Local = 1
154
+ Parameter = 2
122
155
Global = 4
123
156
124
157
# TODO: This is a debugging script to help decompile the bytecode
@@ -327,6 +360,15 @@ def read_statement(self, stream):
327
360
code_if_false = self .read_statement (stream )
328
361
statement = [instruction_type , opcode , values_to_compare , code_if_true , code_if_false ]
329
362
363
+ elif Opcodes .While == opcode :
364
+ condition = self .read_statement (stream )
365
+ code = self .read_statement (stream )
366
+ statement = [instruction_type , opcode , condition , code ]
367
+
368
+ elif Opcodes .Return == opcode :
369
+ value = self .read_statement (stream )
370
+ statement = [instruction_type , opcode , value ]
371
+
330
372
elif Opcodes .Unk2 == opcode :
331
373
lhs = self .read_statement (stream )
332
374
statement = [instruction_type , opcode , lhs ]
@@ -336,9 +378,12 @@ def read_statement(self, stream):
336
378
(Opcodes .Add == opcode ) or \
337
379
(Opcodes .Subtract == opcode ) or \
338
380
(Opcodes .Divide == opcode ) or \
381
+ (Opcodes .Modulo == opcode ) or \
339
382
(Opcodes .And == opcode ) or \
340
383
(Opcodes .LessThan == opcode ) or \
341
- (Opcodes .GreaterThan == opcode ):
384
+ (Opcodes .LessThanOrEqualTo == opcode ) or \
385
+ (Opcodes .GreaterThan == opcode ) or \
386
+ (Opcodes .GreaterThanOrEqualTo == opcode ):
342
387
lhs = self .read_statement (stream )
343
388
rhs = self .read_statement (stream )
344
389
statement = [instruction_type , opcode , lhs , rhs ]
@@ -394,6 +439,11 @@ def read_statement(self, stream):
394
439
elif OperandType .AssetId == operand_type :
395
440
value = Datum (stream ).d
396
441
442
+ elif OperandType .Function == operand_type :
443
+ # TODO: Can we replace this with just a datum? Is there any
444
+ # instance where the function is an expression?
445
+ value = maybe_cast_to_enum (self .read_statement (stream ), BuiltInFunction )
446
+
397
447
else :
398
448
value = self .read_statement (stream )
399
449
0 commit comments