2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
|
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
if(!(oE->oflags&OF_DESTROYED)) o->inertia=oE->inertia;
hit|=0x8000;
}
}
msgvars.arg3.u=hit|7;
return (hit&0x8008)==0x8000?1:0;
}
static Uint32 convert_link(Value v,Uint32 obj,Uint16*code) {
int i;
switch(v.t) {
case TY_NUMBER:
if(v.u) Throw("Type mismatch");
return 0xFFFF;
case TY_MESSAGE:
i=get_message_ptr(objects[obj]->class,v.u);
return i==0xFFFF?get_message_ptr(0,v.u):(i|(objects[obj]->class<<16));
case TY_CODE:
i=v.u>>16;
if(i==objects[obj]->class || !i || code==classes[i]->codes) return v.u;
Throw("Link mismatch");
default: Throw("Type mismatch");
}
}
// 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)
|
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
|
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
|
+
+
-
+
|
case OP_DONE_EC: StackReq(2,0); SetFlagOf(OF_DONE); break;
case OP_DOTPRODUCT: StackReq(2,1); t2=Pop(); t1=Pop(); Push(v_dot_product(t1,t2)); break;
case OP_DROP: StackReq(1,0); Pop(); break;
case OP_DROP_D: StackReq(2,0); Pop(); Pop(); break;
case OP_DUP: StackReq(1,2); t1=Pop(); Push(t1); Push(t1); break;
case OP_EQ: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_equal(t1,t2)?1:0)); break;
case OP_EQ2: StackReq(4,1); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); Push(NVALUE(v_equal(t1,t3)?(v_equal(t2,t4)?1:0):0)); break;
case OP_EXEC: StackReq(1,0); t1=Pop(); i=convert_link(t1,obj,code); if(i==0xFFFF) return; code=classes[i>>16]->codes; ptr=i&0xFFFF; break;
case OP_EXEC_C: StackReq(1,0); t1=Pop(); i=convert_link(t1,obj,code); if(i!=0xFFFF) execute_program(classes[i>>16]->codes,i&0xFFFF,obj); break;
case OP_FINISHED: StackReq(0,1); Push(NVALUE(all_flushed)); break;
case OP_FINISHED_E: StackReq(1,0); t1=Pop(); Numeric(t1); all_flushed=t1.u; break;
case OP_FORK: execute_program(code,ptr+1,obj); ptr=code[ptr]; break;
case OP_FLIP: v_flip(); break;
case OP_FLUSHCLASS: NoIgnore(); StackReq(1,0); t1=Pop(); if(t1.t==TY_CLASS) flush_class(t1.u); else if(t1.t==TY_NUMBER && t1.s==-1) flush_all(); else if(t1.t) Throw("Type mismatch"); break;
case OP_FLUSHOBJ: NoIgnore(); flush_object(obj); break;
case OP_FLUSHOBJ_C: NoIgnore(); StackReq(1,0); i=v_object(Pop()); if(i!=VOIDLINK) flush_object(i); break;
case OP_FOR: NoIgnore(); StackReq(3,1); t3=Pop(); t2=Pop(); t1=Pop(); ptr=v_for(code,ptr,t1,t2,t3); break;
case OP_FORK: execute_program(code,ptr+1,obj); ptr=code[ptr]; break;
case OP_FROM: StackReq(0,1); Push(OVALUE(msgvars.from)); break;
case OP_FUNCTION: execute_program(classes[0]->codes,functions[code[ptr++]],obj); break;
case OP_GE: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_unsigned_greater(t2,t1)?0:1)); break;
case OP_GE_C: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_signed_greater(t2,t1)?0:1)); break;
case OP_GETARRAY: StackReq(3,1); t3=Pop(); Numeric(t3); t2=Pop(); Numeric(t2); t1=Pop(); Push(v_get_array(t1,t2.u,t3.u)); break;
case OP_GETINVENTORY: StackReq(2,2); t2=Pop(); t1=Pop(); v_get_inventory(t1,t2); break;
case OP_GOTO: ptr=code[ptr]; break;
|
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
|
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
|
+
|
case OP_KEYCLEARED_C: StackReq(1,1); GetFlagOf(OF_KEYCLEARED); break;
case OP_KEYCLEARED_E: StackReq(1,0); if(v_bool(Pop())) o->oflags|=OF_KEYCLEARED; else o->oflags&=~OF_KEYCLEARED; break;
case OP_KEYCLEARED_EC: StackReq(2,0); SetFlagOf(OF_KEYCLEARED); break;
case OP_LAND: StackReq(2,1); t1=Pop(); t2=Pop(); if(v_bool(t1) && v_bool(t2)) Push(NVALUE(1)); else Push(NVALUE(0)); break;
case OP_LE: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_unsigned_greater(t1,t2)?0:1)); break;
case OP_LE_C: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_signed_greater(t1,t2)?0:1)); break;
case OP_LEVEL: StackReq(0,1); Push(NVALUE(level_code)); break;
case OP_LINK: StackReq(0,1); Push(UVALUE((ptr+2)|(code[ptr+1]<<16),TY_CODE)); ptr=code[ptr]; break;
case OP_LNOT: StackReq(1,1); if(v_bool(Pop())) Push(NVALUE(0)); else Push(NVALUE(1)); break;
case OP_LOC: StackReq(0,2); Push(NVALUE(o->x)); Push(NVALUE(o->y)); break;
case OP_LOC_C: StackReq(1,2); i=v_object(Pop()); Push(NVALUE(i==VOIDLINK?0:objects[i]->x)); Push(NVALUE(i==VOIDLINK?0:objects[i]->y)); break;
case OP_LOCATEME: locate_me(o->x,o->y); break;
case OP_LOCATEME_C: StackReq(1,0); i=v_object(Pop()); if(i!=VOIDLINK) locate_me(objects[i]->x,objects[i]->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;
|