1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
|
case OP_OBJBOTTOMAT:
n=obj_bottom_at(x,y);
break;
case OP_OBJTOPAT:
n=obj_top_at(x,y);
break;
case OP_RET:
return n==VOIDLINK?obj_bottom_at(x,y):n;
case OP_SUB:
if(vstackptr>=VSTACKSIZE-1) Throw("Stack overflow");
Push(NVALUE(0));
break;
case OP_THEN:
// This opcode does nothing
break;
case OP_TRACE:
if(main_options['t']) {
printf("ptr=%d cpi=%d x=%d y=%d dir=%d obj=%lu ",ptr,cpi,x,y,d,(long)n);
printf("[ptr=%d x=%d y=%d dir=%d]\n",cp[cpi].ptr,cp[cpi].x,cp[cpi].y,cp[cpi].dir);
}
break;
default: Throw("Unimplemented opcode in pattern");
}
goto again;
fail:
if(vstackptr<cp->depth) Throw("Stack underflow in pattern matching");
vstackptr=cp[cpi].depth;
if(!cpi) return VOIDLINK;
x=cp[cpi].x;
y=cp[cpi].y;
d=cp[cpi].dir;
ptr=cp[cpi].ptr;
n=VOIDLINK;
cpi--;
goto again;
}
// 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)
|
>
>
>
>
>
>
|
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
|
case OP_OBJBOTTOMAT:
n=obj_bottom_at(x,y);
break;
case OP_OBJTOPAT:
n=obj_top_at(x,y);
break;
case OP_RET:
if(all) {
if(vstackptr>=VSTACKSIZE-1) Throw("Stack overflow");
if(n==VOIDLINK) n=obj_bottom_at(x,y);
Push(OVALUE(n));
goto fail;
} else {
return n==VOIDLINK?obj_bottom_at(x,y):n;
}
break;
case OP_SUB:
if(vstackptr>=VSTACKSIZE-1) Throw("Stack overflow");
Push(NVALUE(0));
break;
case OP_THEN:
// This opcode does nothing
break;
case OP_TRACE:
if(main_options['t']) {
printf("ptr=%d cpi=%d x=%d y=%d dir=%d obj=%lu ",ptr,cpi,x,y,d,(long)n);
printf("[ptr=%d x=%d y=%d dir=%d]\n",cp[cpi].ptr,cp[cpi].x,cp[cpi].y,cp[cpi].dir);
}
break;
default: Throw("Unimplemented opcode in pattern");
}
goto again;
fail:
if(!all) {
if(vstackptr<cp->depth) Throw("Stack underflow in pattern matching");
vstackptr=cp[cpi].depth;
}
if(!cpi) return VOIDLINK;
x=cp[cpi].x;
y=cp[cpi].y;
d=cp[cpi].dir;
ptr=cp[cpi].ptr;
n=VOIDLINK;
cpi--;
goto again;
}
static Uint32 v_pattern_anywhere(Uint16*code,int ptr,char all) {
int i;
Uint32 n;
for(i=0;i<pfheight*64;i++) {
n=playfield[i];
if(n!=VOIDLINK) {
n=v_pattern(code,ptr,n,all);
if(n!=VOIDLINK && !all) return n;
}
}
return VOIDLINK;
}
// 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)
|
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
|
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_OBJMOVINGTO: StackReq(2,0); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); v_obj_moving_to(t1.u,t2.u); 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_OVER: StackReq(2,3); t2=Pop(); t1=Pop(); Push(t1); Push(t2); Push(t1); break;
case OP_PATTERN: StackReq(0,1); i=code[ptr++]; j=v_pattern(code,ptr,obj,0); ptr=i; Push(OVALUE(j)); break;
case OP_PATTERN_C: StackReq(1,1); i=code[ptr++]; j=v_object(Pop()); if(j!=VOIDLINK) j=v_pattern(code,ptr,j,0); ptr=i; Push(OVALUE(j)); break;
case OP_PICK: StackReq(0,1); t1=Pop(); Numeric(t1); if(t1.u>=vstackptr) Throw("Stack index out of range"); t1=vstack[vstackptr-t1.u-1]; Push(t1); 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_PLUSMOVE: StackReq(1,1); t1=Pop(); Numeric(t1); i=defer_move(obj,t1.u,1); Push(NVALUE(i)); break;
case OP_PLUSMOVE_C: StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); i=defer_move(i,t1.u,1); Push(NVALUE(i)); break;
case OP_PLUSMOVE_D: StackReq(1,0); t1=Pop(); Numeric(t1); defer_move(obj,t1.u,1); break;
case OP_PLUSMOVE_CD: StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); defer_move(i,t1.u,1); break;
|
>
>
>
>
|
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
|
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_OBJMOVINGTO: StackReq(2,0); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); v_obj_moving_to(t1.u,t2.u); 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_OVER: StackReq(2,3); t2=Pop(); t1=Pop(); Push(t1); Push(t2); Push(t1); break;
case OP_PATTERN: StackReq(0,1); i=code[ptr++]; j=v_pattern(code,ptr,obj,0); ptr=i; Push(OVALUE(j)); break;
case OP_PATTERN_C: StackReq(1,1); i=code[ptr++]; j=v_object(Pop()); if(j!=VOIDLINK) j=v_pattern(code,ptr,j,0); ptr=i; Push(OVALUE(j)); break;
case OP_PATTERN_E: StackReq(0,1); i=code[ptr++]; j=v_pattern_anywhere(code,ptr,0); ptr=i; Push(OVALUE(j)); break;
case OP_PATTERNS: StackReq(0,1); i=code[ptr++]; v_pattern(code,ptr,obj,1); ptr=i; break;
case OP_PATTERNS_C: StackReq(1,1); i=code[ptr++]; j=v_object(Pop()); if(j!=VOIDLINK) v_pattern(code,ptr,j,1); ptr=i; break;
case OP_PATTERNS_E: StackReq(0,1); i=code[ptr++]; v_pattern_anywhere(code,ptr,1); ptr=i; break;
case OP_PICK: StackReq(0,1); t1=Pop(); Numeric(t1); if(t1.u>=vstackptr) Throw("Stack index out of range"); t1=vstack[vstackptr-t1.u-1]; Push(t1); 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_PLUSMOVE: StackReq(1,1); t1=Pop(); Numeric(t1); i=defer_move(obj,t1.u,1); Push(NVALUE(i)); break;
case OP_PLUSMOVE_C: StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); i=defer_move(i,t1.u,1); Push(NVALUE(i)); break;
case OP_PLUSMOVE_D: StackReq(1,0); t1=Pop(); Numeric(t1); defer_move(obj,t1.u,1); break;
case OP_PLUSMOVE_CD: StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); defer_move(i,t1.u,1); break;
|