Free Hero Mesh

Check-in [902bd1a80d]
Login
This is a mirror of the main repository for Free Hero Mesh. New tickets and changes will not be accepted at this mirror.
Overview
Comment:Add a mark type and some instructions dealing with it.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 902bd1a80de225640ec23942cbdd3724fbf198ba
User & Date: user on 2021-02-22 04:53:07
Other Links: manifest | tags
Context
2021-02-23
04:02
Correct a mistake in saving levels in the level editor. check-in: ea89397bdc user: user tags: trunk
2021-02-22
04:53
Add a mark type and some instructions dealing with it. check-in: 902bd1a80d user: user tags: trunk
03:16
Add an assertion to check that the value of N_MESSAGES is correct. Also add a note about unused standard message names in class.doc. check-in: c8c249b7be user: user tags: trunk
Changes

Modified class.c from [52031ab4ec] to [48cf31f9d9].

1054
1055
1056
1057
1058
1059
1060







1061
1062
1063
1064
1065
1066
1067
        case OP_NEXT:
          FlowPop(OP_FOR);
          AddInst2(OP_NEXT,flowptr[flowdepth]);
          cl->codes[flowptr[flowdepth]]=peep=ptr;
          break;
        case OP_STRING:
          AddInst2(OP_STRING,pool_string(tokenstr));







          break;
        default:
          if(Tokenf(TF_ABNORMAL)) ParseError("Invalid instruction token\n");
          if(compat && Tokenf(TF_COMPAT) && Tokenf(TF_EQUAL)) ++tokenv;
          AddInstF(tokenv,tokent);
      }
    } else if(Tokenf(TF_FUNCTION)) {







>
>
>
>
>
>
>







1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
        case OP_NEXT:
          FlowPop(OP_FOR);
          AddInst2(OP_NEXT,flowptr[flowdepth]);
          cl->codes[flowptr[flowdepth]]=peep=ptr;
          break;
        case OP_STRING:
          AddInst2(OP_STRING,pool_string(tokenstr));
          break;
        case OP_MBEGIN:
          FlowPush(OP_BEGIN);
          AddInst(OP_TMARK);
          AddInst(OP_IF);
          FlowPush(OP_WHILE);
          peep=++ptr;
          break;
        default:
          if(Tokenf(TF_ABNORMAL)) ParseError("Invalid instruction token\n");
          if(compat && Tokenf(TF_COMPAT) && Tokenf(TF_EQUAL)) ++tokenv;
          AddInstF(tokenv,tokent);
      }
    } else if(Tokenf(TF_FUNCTION)) {

Modified class.doc from [1c5b1a0868] to [3a9f5e183b].

412
413
414
415
416
417
418


419
420
421
422
423
424
425
* Object: A reference to an object. There are no literals of this type.

* String: A string in quotation marks. There are no string manipulation
functions; the only thing that can be done with a string is to display it.

* Sound: A named sound effect. Values of this type cannot be compared with
anything, even other values of the same type.



Some things are not their own types, and are other uses of numbers:

* Null: A null class or null object is represented as zero.

* Boolean: When a boolean is required as input to some instruction, zero
is false, and most other values (of any type) are true, except for sounds







>
>







412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
* Object: A reference to an object. There are no literals of this type.

* String: A string in quotation marks. There are no string manipulation
functions; the only thing that can be done with a string is to display it.

* Sound: A named sound effect. Values of this type cannot be compared with
anything, even other values of the same type.

* Mark: There is only one value of this type.

Some things are not their own types, and are other uses of numbers:

* Null: A null class or null object is represented as zero.

* Boolean: When a boolean is required as input to some instruction, zero
is false, and most other values (of any type) are true, except for sounds
910
911
912
913
914
915
916



917
918
919
920
921
922
923

/  ( in1 in2 -- out )
  Unsigned divide in1 by in2 producing the quotient.

,/  ( in1 in2 -- out )
  Signed divide in1 by in2 producing the quotient.




Animate  ( flag start end delay -- ) **
  Start or stop an animation for this object. This also sets the Image
  variable equal to the start value. The flag can be STOP to stop an
  animation, ONCE to play the animation once (and to queue a LASTIMAGE
  event if the animation isn't changed before that happens; note that
  the message is sent even before the animation is actually visible),
  LOOP to play it in a loop, or OSCLOOP for an oscillating loop. The







>
>
>







912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928

/  ( in1 in2 -- out )
  Unsigned divide in1 by in2 producing the quotient.

,/  ( in1 in2 -- out )
  Signed divide in1 by in2 producing the quotient.

_  ( -- mark )
  Add a mark to the stack.

Animate  ( flag start end delay -- ) **
  Start or stop an animation for this object. This also sets the Image
  variable equal to the start value. The flag can be STOP to stop an
  animation, ONCE to play the animation once (and to queue a LASTIMAGE
  event if the animation isn't changed before that happens; note that
  the message is sent even before the animation is actually visible),
  LOOP to play it in a loop, or OSCLOOP for an oscillating loop. The
1074
1075
1076
1077
1078
1079
1080




1081
1082
1083
1084
1085
1086
1087
  be entered into the replay. It is an error to ignore inputs which do
  cause state changes. Pop-up messages are still allowed, and unlike in
  EKS Hero Mesh they will not break replayability; the key to dismiss a
  non-quiz popup is not entered into the replay list, and the key to
  dismiss a quiz popup will be treated as a non-quiz input. IgnoreKey
  also causes the rest of the turn after the input phase to be skipped.





IntMove  ( dir -- bool ) **
  Similar to Move but do not initialize Inertia at all; use the current
  value of Inertia instead.

,IntMove  ( obj dir -- bool ) **
  Similar to ,Move but do not initialize Inertia at all; use the current
  value of Inertia instead.







>
>
>
>







1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
  be entered into the replay. It is an error to ignore inputs which do
  cause state changes. Pop-up messages are still allowed, and unlike in
  EKS Hero Mesh they will not break replayability; the key to dismiss a
  non-quiz popup is not entered into the replay list, and the key to
  dismiss a quiz popup will be treated as a non-quiz input. IgnoreKey
  also causes the rest of the turn after the input phase to be skipped.

in  ( x mark ... - bool )
  Check if x is equal to any of the values above the mark; equality is
  tested the same as the "eq" instruction.

IntMove  ( dir -- bool ) **
  Similar to Move but do not initialize Inertia at all; use the current
  value of Inertia instead.

,IntMove  ( obj dir -- bool ) **
  Similar to ,Move but do not initialize Inertia at all; use the current
  value of Inertia instead.
1218
1219
1220
1221
1222
1223
1224




1225
1226
1227
1228
1229
1230
1231

NewXY  ( oldx oldy dir -- newx newy )
  NewX and NewY together.

NewY  ( oldy dir -- newy )
  Advance the number in the direction as though it is a Y coordinate.





nip  ( x y -- y )

o?  ( any -- bool )
  True if the value is an object (whether or not it has been garbage
  collected), or false for any other type. Error if it is a sound.

ObjAbove  ( -- obj )







>
>
>
>







1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244

NewXY  ( oldx oldy dir -- newx newy )
  NewX and NewY together.

NewY  ( oldy dir -- newy )
  Advance the number in the direction as though it is a Y coordinate.

nin  ( x mark ... - bool )
  Check if x is unequal to any of the values above the mark; this is the
  same as "in lnot".

nip  ( x y -- y )

o?  ( any -- bool )
  True if the value is an object (whether or not it has been garbage
  collected), or false for any other type. Error if it is a sound.

ObjAbove  ( -- obj )
1358
1359
1360
1361
1362
1363
1364




1365
1366
1367
1368
1369
1370
1371
swap  ( x y -- y x )

Synchronize  ( slot startimage -- ) **
  Start a synchronized animation. Give the slot number of the animation,
  and the starting image number. The length and speed are defined in a
  global definition, and the animation is always a non-oscillating loop.





Trace  ( obj arg1 arg2 -- )
  If tracing is enabled, sends the three values and some other information
  on stdout. If tracing is disabled, does nothing. This is intended to be
  used for debugging class codes.

tuck  ( x y -- y x y )








>
>
>
>







1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
swap  ( x y -- y x )

Synchronize  ( slot startimage -- ) **
  Start a synchronized animation. Give the slot number of the animation,
  and the starting image number. The length and speed are defined in a
  global definition, and the animation is always a non-oscillating loop.

tmark  ( any -- any true | false )
  If the input is a mark, then it is removed and the result is false.
  Otherwise, the value remains and true is added above it on the stack.

Trace  ( obj arg1 arg2 -- )
  If tracing is enabled, sends the three values and some other information
  on stdout. If tracing is disabled, does nothing. This is intended to be
  used for debugging class codes.

tuck  ( x y -- y x y )

1424
1425
1426
1427
1428
1429
1430




1431
1432
1433
1434
1435
1436
1437
  Once "next" is reached, it finds the next object and goes back.

if <truepart> [el <cond> if <truepart> ...] [else <falsepart>] then  ( bool -- )
  Takes a boolean value from the stack. If true, then <truepart> is executed;
  otherwise it tries the other parts; "el" means to execute <cond> and take
  another boolean, and continue; "else" means always do this if none of the
  previous parts match.






=== Substitution codes ===

%c
  Display a single character whose code is the low 8-bits of the value.








>
>
>
>







1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
  Once "next" is reached, it finds the next object and goes back.

if <truepart> [el <cond> if <truepart> ...] [else <falsepart>] then  ( bool -- )
  Takes a boolean value from the stack. If true, then <truepart> is executed;
  otherwise it tries the other parts; "el" means to execute <cond> and take
  another boolean, and continue; "else" means always do this if none of the
  previous parts match.

mbegin <body> repeat  ( -- any ) ( -- )
  The "mbegin" instruction is a shortcut for "begin tmark while", and it has
  the same behaviour.


=== Substitution codes ===

%c
  Display a single character whose code is the low 8-bits of the value.

Modified exec.c from [ec9055087c] to [21d410450b].

1250
1251
1252
1253
1254
1255
1256










1257
1258
1259
1260
1261
1262
1263
    if(current_key && !v_bool(msgvars.arg3)) key_ignored=all_flushed=1;
    return 0;
  }
  if(!i) return 0;
  if(current_key && !v_bool(msgvars.arg3) && !(keymask[i>>3]&(1<<(i&7)))) key_ignored=all_flushed=1;
  return code[i];
}











// Here is where the execution of a Free Hero Mesh bytecode subroutine is executed.
#define NoIgnore() do{ changed=1; }while(0)
#define GetVariableOf(a,b) (i=v_object(Pop()),i==VOIDLINK?NVALUE(0):b(objects[i]->a))
#define GetVariableOrAttributeOf(a,b) (t2=Pop(),t2.t==TY_CLASS?NVALUE(classes[t2.u]->a):(i=v_object(t2),i==VOIDLINK?NVALUE(0):b(objects[i]->a)))
#define Numeric(a) do{ if((a).t!=TY_NUMBER) Throw("Type mismatch"); }while(0)
#define DivideBy(a) do{ Numeric(a); if(!(a).u) Throw("Division by zero"); }while(0)







>
>
>
>
>
>
>
>
>
>







1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
    if(current_key && !v_bool(msgvars.arg3)) key_ignored=all_flushed=1;
    return 0;
  }
  if(!i) return 0;
  if(current_key && !v_bool(msgvars.arg3) && !(keymask[i>>3]&(1<<(i&7)))) key_ignored=all_flushed=1;
  return code[i];
}

static int v_in(void) {
  int p=vstackptr;
  Value v;
  while(vstackptr-- && vstack[vstackptr].t!=TY_MARK);
  if(!vstackptr) Throw("No mark");
  v=Pop();
  while(--p>vstackptr) if(v_equal(v,vstack[p])) return 1;
  return 0;
}

// Here is where the execution of a Free Hero Mesh bytecode subroutine is executed.
#define NoIgnore() do{ changed=1; }while(0)
#define GetVariableOf(a,b) (i=v_object(Pop()),i==VOIDLINK?NVALUE(0):b(objects[i]->a))
#define GetVariableOrAttributeOf(a,b) (t2=Pop(),t2.t==TY_CLASS?NVALUE(classes[t2.u]->a):(i=v_object(t2),i==VOIDLINK?NVALUE(0):b(objects[i]->a)))
#define Numeric(a) do{ if((a).t!=TY_NUMBER) Throw("Type mismatch"); }while(0)
#define DivideBy(a) do{ Numeric(a); if(!(a).u) Throw("Division by zero"); }while(0)
1425
1426
1427
1428
1429
1430
1431

1432
1433
1434
1435
1436
1437
1438
    case OP_HEIGHTAT: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(height_at(t1.u,t2.u))); break;
    case OP_IF: StackReq(1,0); if(v_bool(Pop())) ptr++; else ptr=code[ptr]; break;
    case OP_IGNOREKEY: if(current_key) key_ignored=all_flushed=1; break;
    case OP_IMAGE: StackReq(0,1); Push(NVALUE(o->image)); break;
    case OP_IMAGE_C: StackReq(1,1); Push(GetVariableOf(image,NVALUE)); break;
    case OP_IMAGE_E: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->image=t1.u; break;
    case OP_IMAGE_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->image=t1.u; break;

    case OP_INERTIA: StackReq(0,1); Push(NVALUE(o->inertia)); break;
    case OP_INERTIA_C: StackReq(1,1); Push(GetVariableOf(inertia,NVALUE)); break;
    case OP_INERTIA_E: StackReq(1,0); t1=Pop(); Numeric(t1); o->inertia=t1.u; break;
    case OP_INERTIA_E16: StackReq(1,0); t1=Pop(); Numeric(t1); o->inertia=t1.u&0xFFFF; break;
    case OP_INERTIA_EC: StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->inertia=t1.u; break;
    case OP_INERTIA_EC16: StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->inertia=t1.u&0xFFFF; break;
    case OP_INT16: StackReq(0,1); Push(NVALUE(code[ptr++])); break;







>







1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
    case OP_HEIGHTAT: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(height_at(t1.u,t2.u))); break;
    case OP_IF: StackReq(1,0); if(v_bool(Pop())) ptr++; else ptr=code[ptr]; break;
    case OP_IGNOREKEY: if(current_key) key_ignored=all_flushed=1; break;
    case OP_IMAGE: StackReq(0,1); Push(NVALUE(o->image)); break;
    case OP_IMAGE_C: StackReq(1,1); Push(GetVariableOf(image,NVALUE)); break;
    case OP_IMAGE_E: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->image=t1.u; break;
    case OP_IMAGE_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->image=t1.u; break;
    case OP_IN: StackReq(2,1); i=v_in(); Push(NVALUE(i?1:0)); break;
    case OP_INERTIA: StackReq(0,1); Push(NVALUE(o->inertia)); break;
    case OP_INERTIA_C: StackReq(1,1); Push(GetVariableOf(inertia,NVALUE)); break;
    case OP_INERTIA_E: StackReq(1,0); t1=Pop(); Numeric(t1); o->inertia=t1.u; break;
    case OP_INERTIA_E16: StackReq(1,0); t1=Pop(); Numeric(t1); o->inertia=t1.u&0xFFFF; break;
    case OP_INERTIA_EC: StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->inertia=t1.u; break;
    case OP_INERTIA_EC16: StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->inertia=t1.u&0xFFFF; break;
    case OP_INT16: StackReq(0,1); Push(NVALUE(code[ptr++])); break;
1465
1466
1467
1468
1469
1470
1471

1472
1473
1474
1475
1476
1477
1478
    case OP_LOCATEME: locate_me(o->x,o->y); break;
    case OP_LOR: StackReq(2,1); t1=Pop(); t2=Pop(); if(v_bool(t1) || v_bool(t2)) Push(NVALUE(1)); else Push(NVALUE(0)); break;
    case OP_LOSELEVEL: gameover=-1; Throw(0); break;
    case OP_LSH: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t2.u&~31?0:t1.u<<t2.u)); break;
    case OP_LT: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_unsigned_greater(t2,t1)?1:0)); break;
    case OP_LT_C: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_signed_greater(t2,t1)?1:0)); break;
    case OP_LXOR: StackReq(2,1); t1=Pop(); t2=Pop(); if(v_bool(t1)?!v_bool(t2):v_bool(t2)) Push(NVALUE(1)); else Push(NVALUE(0)); break;

    case OP_MAXINVENTORY: StackReq(1,0); t1=Pop(); Numeric(t1); if(ninventory>t1.u) Throw("Inventory overflow"); break;
    case OP_MOD: StackReq(2,1); t2=Pop(); DivideBy(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.u%t2.u)); break;
    case OP_MOD_C: StackReq(2,1); t2=Pop(); DivideBy(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.s%t2.s)); break;
    case OP_MOVE: NoIgnore(); StackReq(1,1); t1=Pop(); Numeric(t1); o->inertia=o->strength; Push(NVALUE(move_dir(obj,obj,t1.u))); break;
    case OP_MOVE_C: NoIgnore(); StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i==VOIDLINK) Push(NVALUE(0)); else { objects[i]->inertia=o->strength; Push(NVALUE(move_dir(obj,i,t1.u))); } break;
    case OP_MOVE_D: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->inertia=o->strength; move_dir(obj,obj,t1.u); break;
    case OP_MOVE_CD: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) { objects[i]->inertia=o->strength; move_dir(obj,i,t1.u); } break;







>







1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
    case OP_LOCATEME: locate_me(o->x,o->y); break;
    case OP_LOR: StackReq(2,1); t1=Pop(); t2=Pop(); if(v_bool(t1) || v_bool(t2)) Push(NVALUE(1)); else Push(NVALUE(0)); break;
    case OP_LOSELEVEL: gameover=-1; Throw(0); break;
    case OP_LSH: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t2.u&~31?0:t1.u<<t2.u)); break;
    case OP_LT: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_unsigned_greater(t2,t1)?1:0)); break;
    case OP_LT_C: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_signed_greater(t2,t1)?1:0)); break;
    case OP_LXOR: StackReq(2,1); t1=Pop(); t2=Pop(); if(v_bool(t1)?!v_bool(t2):v_bool(t2)) Push(NVALUE(1)); else Push(NVALUE(0)); break;
    case OP_MARK: StackReq(0,1); Push(UVALUE(0,TY_MARK)); break;
    case OP_MAXINVENTORY: StackReq(1,0); t1=Pop(); Numeric(t1); if(ninventory>t1.u) Throw("Inventory overflow"); break;
    case OP_MOD: StackReq(2,1); t2=Pop(); DivideBy(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.u%t2.u)); break;
    case OP_MOD_C: StackReq(2,1); t2=Pop(); DivideBy(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.s%t2.s)); break;
    case OP_MOVE: NoIgnore(); StackReq(1,1); t1=Pop(); Numeric(t1); o->inertia=o->strength; Push(NVALUE(move_dir(obj,obj,t1.u))); break;
    case OP_MOVE_C: NoIgnore(); StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i==VOIDLINK) Push(NVALUE(0)); else { objects[i]->inertia=o->strength; Push(NVALUE(move_dir(obj,i,t1.u))); } break;
    case OP_MOVE_D: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->inertia=o->strength; move_dir(obj,obj,t1.u); break;
    case OP_MOVE_CD: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) { objects[i]->inertia=o->strength; move_dir(obj,i,t1.u); } break;
1494
1495
1496
1497
1498
1499
1500

1501
1502
1503
1504
1505
1506
1507
    case OP_MUL_C: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.s*t2.s)); break;
    case OP_NE: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_equal(t1,t2)?0:1)); break;
    case OP_NEG: StackReq(1,1); t1=Pop(); Numeric(t1); t1.s=-t1.s; Push(t1); break;
    case OP_NEWX: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(new_x(t1.u,t2.u))); break;
    case OP_NEWXY: StackReq(3,1); t3=Pop(); Numeric(t3); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(new_x(t1.u,t3.u))); Push(NVALUE(new_y(t2.u,t3.u))); break;
    case OP_NEWY: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(new_y(t1.u,t2.u))); break;
    case OP_NEXT: StackReq(0,1); ptr=v_next(code,ptr); break;

    case OP_NIP: StackReq(2,1); t1=Pop(); Pop(); Push(t1); break;
    case OP_OBJABOVE: StackReq(0,1); i=obj_above(obj); Push(OVALUE(i)); break;
    case OP_OBJABOVE_C: StackReq(1,1); i=obj_above(v_object(Pop())); Push(OVALUE(i)); break;
    case OP_OBJBELOW: StackReq(0,1); i=obj_below(obj); Push(OVALUE(i)); break;
    case OP_OBJBELOW_C: StackReq(1,1); i=obj_below(v_object(Pop())); Push(OVALUE(i)); break;
    case OP_OBJBOTTOMAT: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); i=obj_bottom_at(t1.u,t2.u); Push(OVALUE(i)); break;
    case OP_OBJCLASSAT: StackReq(3,1); t3=Pop(); t2=Pop(); t1=Pop(); Push(v_obj_class_at(t1,t2,t3)); break;







>







1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
    case OP_MUL_C: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.s*t2.s)); break;
    case OP_NE: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_equal(t1,t2)?0:1)); break;
    case OP_NEG: StackReq(1,1); t1=Pop(); Numeric(t1); t1.s=-t1.s; Push(t1); break;
    case OP_NEWX: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(new_x(t1.u,t2.u))); break;
    case OP_NEWXY: StackReq(3,1); t3=Pop(); Numeric(t3); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(new_x(t1.u,t3.u))); Push(NVALUE(new_y(t2.u,t3.u))); break;
    case OP_NEWY: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(new_y(t1.u,t2.u))); break;
    case OP_NEXT: StackReq(0,1); ptr=v_next(code,ptr); break;
    case OP_NIN: StackReq(2,1); i=v_in(); Push(NVALUE(i?0:1)); break;
    case OP_NIP: StackReq(2,1); t1=Pop(); Pop(); Push(t1); break;
    case OP_OBJABOVE: StackReq(0,1); i=obj_above(obj); Push(OVALUE(i)); break;
    case OP_OBJABOVE_C: StackReq(1,1); i=obj_above(v_object(Pop())); Push(OVALUE(i)); break;
    case OP_OBJBELOW: StackReq(0,1); i=obj_below(obj); Push(OVALUE(i)); break;
    case OP_OBJBELOW_C: StackReq(1,1); i=obj_below(v_object(Pop())); Push(OVALUE(i)); break;
    case OP_OBJBOTTOMAT: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); i=obj_bottom_at(t1.u,t2.u); Push(OVALUE(i)); break;
    case OP_OBJCLASSAT: StackReq(3,1); t3=Pop(); t2=Pop(); t1=Pop(); Push(v_obj_class_at(t1,t2,t3)); break;
1569
1570
1571
1572
1573
1574
1575

1576
1577
1578
1579
1580
1581
1582
    case OP_SYNCHRONIZE: StackReq(2,0); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); animate_sync(obj,t1.u,t2.u); break;
    case OP_TEMPERATURE: StackReq(0,1); Push(NVALUE(o->temperature)); break;
    case OP_TEMPERATURE_C: StackReq(1,1); Push(GetVariableOrAttributeOf(temperature,NVALUE)); break;
    case OP_TEMPERATURE_E: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->temperature=t1.u; break;
    case OP_TEMPERATURE_E16: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->temperature=t1.u&0xFFFF; break;
    case OP_TEMPERATURE_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->temperature=t1.u; break;
    case OP_TEMPERATURE_EC16: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->temperature=t1.u; break;

    case OP_TRACE: StackReq(3,0); trace_stack(obj); break;
    case OP_TUCK: StackReq(2,3); t2=Pop(); t1=Pop(); Push(t2); Push(t1); Push(t2); break;
    case OP_USERSIGNAL: StackReq(0,1); if(o->oflags&OF_USERSIGNAL) Push(NVALUE(1)); else Push(NVALUE(0)); break;
    case OP_USERSIGNAL_C: StackReq(1,1); GetFlagOf(OF_USERSIGNAL); break;
    case OP_USERSIGNAL_E: NoIgnore(); StackReq(1,0); if(v_bool(Pop())) o->oflags|=OF_USERSIGNAL; else o->oflags&=~OF_USERSIGNAL; break;
    case OP_USERSIGNAL_EC: NoIgnore(); StackReq(2,0); SetFlagOf(OF_USERSIGNAL); break;
    case OP_USERSTATE: StackReq(0,1); if(o->oflags&OF_USERSTATE) Push(NVALUE(1)); else Push(NVALUE(0)); break;







>







1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
    case OP_SYNCHRONIZE: StackReq(2,0); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); animate_sync(obj,t1.u,t2.u); break;
    case OP_TEMPERATURE: StackReq(0,1); Push(NVALUE(o->temperature)); break;
    case OP_TEMPERATURE_C: StackReq(1,1); Push(GetVariableOrAttributeOf(temperature,NVALUE)); break;
    case OP_TEMPERATURE_E: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->temperature=t1.u; break;
    case OP_TEMPERATURE_E16: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->temperature=t1.u&0xFFFF; break;
    case OP_TEMPERATURE_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->temperature=t1.u; break;
    case OP_TEMPERATURE_EC16: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->temperature=t1.u; break;
    case OP_TMARK: StackReq(1,2); t1=Pop(); if(t1.t==TY_MARK) { Push(NVALUE(0)); } else { Push(t1); Push(NVALUE(1)); } break;
    case OP_TRACE: StackReq(3,0); trace_stack(obj); break;
    case OP_TUCK: StackReq(2,3); t2=Pop(); t1=Pop(); Push(t2); Push(t1); Push(t2); break;
    case OP_USERSIGNAL: StackReq(0,1); if(o->oflags&OF_USERSIGNAL) Push(NVALUE(1)); else Push(NVALUE(0)); break;
    case OP_USERSIGNAL_C: StackReq(1,1); GetFlagOf(OF_USERSIGNAL); break;
    case OP_USERSIGNAL_E: NoIgnore(); StackReq(1,0); if(v_bool(Pop())) o->oflags|=OF_USERSIGNAL; else o->oflags&=~OF_USERSIGNAL; break;
    case OP_USERSIGNAL_EC: NoIgnore(); StackReq(2,0); SetFlagOf(OF_USERSIGNAL); break;
    case OP_USERSTATE: StackReq(0,1); if(o->oflags&OF_USERSTATE) Push(NVALUE(1)); else Push(NVALUE(0)); break;

Modified function.c from [33eea068bd] to [a27d6bc1ae].

162
163
164
165
166
167
168

169
170
171
172
173
174
175
    [TY_NUMBER]="number",
    [TY_CLASS]="class",
    [TY_MESSAGE]="message",
    [TY_LEVELSTRING]="string",
    [TY_STRING]="string",
    [TY_SOUND]="sound",
    [TY_USOUND]="sound",

  };
  int i;
  if(sqlite3_value_type(*argv)!=SQLITE_INTEGER) return;
  i=sqlite3_value_int64(*argv)>>32;
  sqlite3_result_text(cxt,i<0||i>TY_MAXTYPE?"object":n[i]?:"???",-1,SQLITE_STATIC);
}








>







162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    [TY_NUMBER]="number",
    [TY_CLASS]="class",
    [TY_MESSAGE]="message",
    [TY_LEVELSTRING]="string",
    [TY_STRING]="string",
    [TY_SOUND]="sound",
    [TY_USOUND]="sound",
    [TY_MARK]="mark",
  };
  int i;
  if(sqlite3_value_type(*argv)!=SQLITE_INTEGER) return;
  i=sqlite3_value_int64(*argv)>>32;
  sqlite3_result_text(cxt,i<0||i>TY_MAXTYPE?"object":n[i]?:"???",-1,SQLITE_STATIC);
}

Modified game.c from [0d57595d6a] to [057f0a96ef].

289
290
291
292
293
294
295



296
297
298
299
300
301
302
      break;
    case TY_LEVELSTRING: case TY_STRING:
      draw_text(200,y,"<String>",0xF0,0xF9);
      break;
    case TY_SOUND: case TY_USOUND:
      draw_text(200,y,"<Sound>",0xF0,0xF6);
      break;



    default:
      snprintf(buf,80,"<%lu:%lu>",(long)v.u,(long)v.t);
      draw_text(200,y,buf,0xF0,0xFA);
      i=strlen(buf)*8+208;
      if(v.u<nobjects && objects[v.u] && objects[v.u]->generation==v.t) {
        snprintf(buf,80,"@ (%d,%d)",objects[v.u]->x,objects[v.u]->y);
        draw_text(i,y,buf,0xF0,0xF2);







>
>
>







289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
      break;
    case TY_LEVELSTRING: case TY_STRING:
      draw_text(200,y,"<String>",0xF0,0xF9);
      break;
    case TY_SOUND: case TY_USOUND:
      draw_text(200,y,"<Sound>",0xF0,0xF6);
      break;
    case TY_MARK:
      draw_text(200,y,"<Mark>",0xF0,0xF3);
      break;
    default:
      snprintf(buf,80,"<%lu:%lu>",(long)v.u,(long)v.t);
      draw_text(200,y,buf,0xF0,0xFA);
      i=strlen(buf)*8+208;
      if(v.u<nobjects && objects[v.u] && objects[v.u]->generation==v.t) {
        snprintf(buf,80,"@ (%d,%d)",objects[v.u]->x,objects[v.u]->y);
        draw_text(i,y,buf,0xF0,0xF2);

Modified heromesh.h from [a29da74068] to [2279de3f22].

11
12
13
14
15
16
17

18
19
20
21
22
23
24
#define TY_CLASS 1
#define TY_MESSAGE 2
#define TY_LEVELSTRING 3
#define TY_STRING 4
#define TY_SOUND 5
#define TY_USOUND 6
#define TY_FOR 7

#define TY_MAXTYPE 15
// The level file format requires type codes 0 to 3 to be as is; other codes may change.

typedef struct {
  union {
    Sint32 s;
    Uint32 u;







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#define TY_CLASS 1
#define TY_MESSAGE 2
#define TY_LEVELSTRING 3
#define TY_STRING 4
#define TY_SOUND 5
#define TY_USOUND 6
#define TY_FOR 7
#define TY_MARK 8
#define TY_MAXTYPE 15
// The level file format requires type codes 0 to 3 to be as is; other codes may change.

typedef struct {
  union {
    Sint32 s;
    Uint32 u;

Modified instruc from [5a715995c3] to [e7d465050e].

243
244
245
246
247
248
249







250
251
252
253
254
255
256
Synchronize
Trace
VolumeAt
WinLevel
,XDir
XYDir
,YDir








; Specials
*Function
*Local
*Label
*String
*Int16







>
>
>
>
>
>
>







243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
Synchronize
Trace
VolumeAt
WinLevel
,XDir
XYDir
,YDir

; Operations with marks
mark "_"
tmark
in
nin
-mbegin

; Specials
*Function
*Local
*Label
*String
*Int16

Modified instruc.h from [a26fee81cf] to [a43f3b2833].

358
359
360
361
362
363
364





365
366
367
368
369
370
371
372
373
374
375
376
377
378
#define OP_VOLUMEAT 32941
#define OP_WINLEVEL 32942
#define OP_XDIR 32943
#define OP_XDIR_C 34991
#define OP_XYDIR 32944
#define OP_YDIR 32945
#define OP_YDIR_C 34993





#define OP_FUNCTION 32946
#define OP_LOCAL 32947
#define OP_LABEL 32948
#define OP_STRING 32949
#define OP_INT16 32950
#define OP_INT32 32951
#define OP_DISPATCH 32952
#ifdef HEROMESH_CLASS
static const Op_Names op_names[]={
{"*",8486936},
{"+",8421398},
{"-",8421399},
{"-rot",8421382},
{".",10518528},







>
>
>
>
>
|
|
|
|
|
|
|







358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
#define OP_VOLUMEAT 32941
#define OP_WINLEVEL 32942
#define OP_XDIR 32943
#define OP_XDIR_C 34991
#define OP_XYDIR 32944
#define OP_YDIR 32945
#define OP_YDIR_C 34993
#define OP_MARK 32946
#define OP_TMARK 32947
#define OP_IN 32948
#define OP_NIN 32949
#define OP_MBEGIN 32950
#define OP_FUNCTION 32951
#define OP_LOCAL 32952
#define OP_LABEL 32953
#define OP_STRING 32954
#define OP_INT16 32955
#define OP_INT32 32956
#define OP_DISPATCH 32957
#ifdef HEROMESH_CLASS
static const Op_Names op_names[]={
{"*",8486936},
{"+",8421398},
{"-",8421399},
{"-rot",8421382},
{".",10518528},
575
576
577
578
579
580
581

582
583
584
585
586
587
588
{"WinLevel",8421550},
{"XDir",8487087},
{"XYDir",8421552},
{"Xloc",8486969},
{"YDir",8487089},
{"YEEHAW",8389401},
{"Yloc",8486970},

{"again",8683533},
{"band",8421406},
{"begin",8683532},
{"bit",8683554},
{"bit0",8388609},
{"bit1",8388610},
{"bit10",8423402},







>







580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
{"WinLevel",8421550},
{"XDir",8487087},
{"XYDir",8421552},
{"Xloc",8486969},
{"YDir",8487089},
{"YEEHAW",8389401},
{"Yloc",8486970},
{"_",8421554},
{"again",8683533},
{"band",8421406},
{"begin",8683532},
{"bit",8683554},
{"bit0",8388609},
{"bit1",8388610},
{"bit10",8423402},
624
625
626
627
628
629
630

631
632
633
634
635
636
637
638
639

640
641
642
643
644

645
646
647
648
649
650
651
652
653
654
655

656
657
658
659
660
661
{"el",8683531},
{"else",8683529},
{"eq",8421415},
{"for",8683537},
{"ge",8486955},
{"gt",8486953},
{"if",8683528},

{"is",8421421},
{"land",8421411},
{"le",8486956},
{"lnot",8421414},
{"lor",8421412},
{"lsh",8421404},
{"lt",8486954},
{"lxor",8421413},
{"m?",8421425},

{"mod",8486938},
{"n?",8421422},
{"ne",8421416},
{"neg",8421403},
{"next",8683538},

{"nip",8421379},
{"o?",8421427},
{"oz?",8421428},
{"pick",8421383},
{"repeat",8683536},
{"ret",8421397},
{"rot",8421381},
{"rsh",8486941},
{"s?",8421426},
{"swap",8421378},
{"then",8683530},

{"tuck",8421380},
{"until",8683534},
{"while",8683535},
};
#define N_OP_NAMES 285
#endif







>









>





>











>




|

630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
{"el",8683531},
{"else",8683529},
{"eq",8421415},
{"for",8683537},
{"ge",8486955},
{"gt",8486953},
{"if",8683528},
{"in",8421556},
{"is",8421421},
{"land",8421411},
{"le",8486956},
{"lnot",8421414},
{"lor",8421412},
{"lsh",8421404},
{"lt",8486954},
{"lxor",8421413},
{"m?",8421425},
{"mbegin",8683702},
{"mod",8486938},
{"n?",8421422},
{"ne",8421416},
{"neg",8421403},
{"next",8683538},
{"nin",8421557},
{"nip",8421379},
{"o?",8421427},
{"oz?",8421428},
{"pick",8421383},
{"repeat",8683536},
{"ret",8421397},
{"rot",8421381},
{"rsh",8486941},
{"s?",8421426},
{"swap",8421378},
{"then",8683530},
{"tmark",8421555},
{"tuck",8421380},
{"until",8683534},
{"while",8683535},
};
#define N_OP_NAMES 290
#endif