1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
|
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
|
-
+
+
|
#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)
#define GetFlagOf(a) t2=Pop(),Push(t2.t==TY_CLASS?NVALUE(classes[t2.u]->oflags&a?1:0):(i=v_object(t2),i==VOIDLINK?NVALUE(0):NVALUE(objects[i]->oflags&a?1:0)))
#define GetClassFlagOf(a) t2=Pop(),Push(t2.t==TY_CLASS?NVALUE(classes[t2.u]->cflags&a?1:0):(i=v_object(t2),i==VOIDLINK?NVALUE(0):NVALUE(classes[objects[i]->class]->cflags&a?1:0)))
#define SetFlagOf(a) do { t2=Pop(); i=v_object(Pop()); if(i!=VOIDLINK) { if(v_bool(t2)) objects[i]->oflags|=a; else objects[i]->oflags&=~a; } }while(0)
#define SetFlagOf(a) do{ t2=Pop(); i=v_object(Pop()); if(i!=VOIDLINK) { if(v_bool(t2)) objects[i]->oflags|=a; else objects[i]->oflags&=~a; } }while(0)
#define NotSound(a) do{ if((a).t==TY_SOUND || (a).t==TY_USOUND) Throw("Cannot convert sound to type"); }while(0)
static void execute_program(Uint16*code,int ptr,Uint32 obj) {
Uint32 i,j;
Object*o=objects[obj];
Value t1,t2;
static Value t3,t4,t5;
if(StackProtection()) Throw("Call stack overflow");
// Note about bit shifting: At least when running Hero Mesh in DOSBOX, out of range bit shifts produce zero.
|
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
|
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
|
+
+
+
+
+
+
+
|
case OP_OBJDIR_C: StackReq(2,1); t2=Pop(); Numeric(t2); i=obj_dir(v_object(Pop()),t2.u); Push(OVALUE(i)); break;
case OP_OBJLAYERAT: StackReq(3,1); t3=Pop(); Numeric(t3); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); i=obj_layer_at(t1.u,t2.u,t3.u); Push(OVALUE(i)); break;
case OP_OBJTOPAT: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); i=obj_top_at(t1.u,t2.u); Push(OVALUE(i)); break;
case OP_PLAYER: StackReq(0,1); if(classes[o->class]->cflags&CF_PLAYER) Push(NVALUE(1)); else Push(NVALUE(0)); break;
case OP_PLAYER_C: StackReq(1,1); GetClassFlagOf(CF_PLAYER); break;
case OP_POPUP: StackReq(1,0); v_set_popup(obj,0); break;
case OP_POPUPARGS: i=code[ptr++]; StackReq(i+1,0); v_set_popup(obj,i); break;
case OP_QC: StackReq(1,1); t1=Pop(); NotSound(t1); if(t1.t==TY_CLASS) Push(NVALUE(1)); else Push(NVALUE(0)); break;
case OP_QCZ: StackReq(1,1); t1=Pop(); NotSound(t1); if(t1.t==TY_CLASS || (t1.t==TY_NUMBER && !t1.u)) Push(NVALUE(1)); else Push(NVALUE(0)); break;
case OP_QM: StackReq(1,1); t1=Pop(); NotSound(t1); if(t1.t==TY_MESSAGE) Push(NVALUE(1)); else Push(NVALUE(0)); break;
case OP_QN: StackReq(1,1); t1=Pop(); NotSound(t1); if(t1.t==TY_NUMBER) Push(NVALUE(1)); else Push(NVALUE(0)); break;
case OP_QO: StackReq(1,1); t1=Pop(); NotSound(t1); if(t1.t>TY_MAXTYPE) Push(NVALUE(1)); else Push(NVALUE(0)); break;
case OP_QOZ: StackReq(1,1); t1=Pop(); NotSound(t1); if(t1.t>TY_MAXTYPE || (t1.t==TY_NUMBER && !t1.u)) Push(NVALUE(1)); else Push(NVALUE(0)); break;
case OP_QS: StackReq(1,1); t1=Pop(); NotSound(t1); if(t1.t==TY_STRING || t1.t==TY_LEVELSTRING) Push(NVALUE(1)); else Push(NVALUE(0)); break;
case OP_RET: return;
case OP_ROT: StackReq(3,3); t3=Pop(); t2=Pop(); t1=Pop(); Push(t2); Push(t3); Push(t1); break;
case OP_ROTBACK: StackReq(3,3); t3=Pop(); t2=Pop(); t1=Pop(); Push(t3); Push(t1); Push(t2); break;
case OP_RSH: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t2.u&~31?0:t1.u>>t2.u)); break;
case OP_RSH_C: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t2.u&~31?(t1.s<0?-1:0):t1.s>>t2.u)); break;
case OP_SELF: StackReq(0,1); Push(OVALUE(obj)); break;
case OP_SEND: StackReq(3,1); t4=Pop(); t3=Pop(); t2=Pop(); Push(v_send_self(obj,t2,t3,t4,NVALUE(0))); break;
|