Free Hero Mesh

Diff
Login
This is a mirror of the main repository for Free Hero Mesh. New tickets and changes will not be accepted at this mirror.

Differences From Artifact [534ed95552]:

To Artifact [85a769bf13]:


2156
2157
2158
2159
2160
2161
2162





























































2163
2164
2165
2166
2167
2168
2169
  n=playfield[x+y*64-65];
  while(n!=VOIDLINK) {
    m=objects[n]->up;
    v_trigger(from,n,v);
    n=m;
  }
}






























































// 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)







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
  n=playfield[x+y*64-65];
  while(n!=VOIDLINK) {
    m=objects[n]->up;
    v_trigger(from,n,v);
    n=m;
  }
}

static void v_sweep(Uint32 from,Value arg3) {
  Value arg2=Pop();
  Value arg1=Pop();
  Value v=Pop();
  Uint8 hv=v_bool(Pop());
  Uint16 msg=v.u;
  Uint8 x0,y0,x1,y1,x,y;
  Uint32 m,n;
  if(v.t!=TY_MESSAGE) Throw("Type mismatch");
  v=Pop(); if(v.t) Throw("Type mismatch"); y1=(v.s<0?0:v.s>pfheight?pfheight+1:v.s);
  v=Pop(); if(v.t) Throw("Type mismatch"); x1=(v.s<0?0:v.s>pfheight?pfheight+1:v.s);
  v=Pop(); if(v.t) Throw("Type mismatch"); y0=(v.s<0?0:v.s>pfheight?pfheight+1:v.s);
  v=Pop(); if(v.t) Throw("Type mismatch"); x0=(v.s<0?0:v.s>pfheight?pfheight+1:v.s);
  if((!x0 && !x1) || (!y0 && !y1) || (x0>pfwidth && x1>pfwidth) || (y0>pfheight && y1>pfheight)) return;
  if(!x0) x0=1;
  if(!x1) x1=1;
  if(!y0) y0=1;
  if(!y1) y1=1;
  if(x0>pfwidth) x0=pfwidth;
  if(y0>pfheight) y0=pfheight;
  if(x1>pfwidth) x1=pfwidth;
  if(y1>pfheight) y1=pfheight;
  for(x=x0,y=y0;;) {
    n=playfield[x+y*64-65];
    while(n!=VOIDLINK) {
      m=objects[n]->up;
      send_message(from,n,msg,arg1,arg2,arg3);
      n=m;
    }
    if(x==x1 && y==y1) break;
    if(hv) {
      if(y==y1) y=y0,x+=(x1>x0?1:-1); else y+=(y1>y0?1:-1);
    } else {
      if(x==x1) x=x0,y+=(y1>y0?1:-1); else x+=(x1>x0?1:-1);
    }
  }
}

static Uint32 v_hitme(Uint32 objE,Uint16 dir) {
  Object*o;
  Object*oE=objects[objE];
  Uint32 hit=msgvars.arg3.u&~0x8000;
  if(msgvars.from==VOIDLINK) return 0;
  if(msgvars.arg3.t) Throw("Type mismatch in HitMe");
  o=objects[msgvars.from];
  if(dir>7) dir=(o->dir+dir)&7;
  if(!(dir&1) && !(hit&0x122)) {
    if(o->sharp[dir>>1]>oE->hard[(dir^4)>>1] && !v_bool(destroy(msgvars.from,objE,2))) hit|=0x8004;
    if(oE->sharp[(dir^4)>>1]>o->hard[dir>>1] && !v_bool(destroy(objE,msgvars.from,1))) hit|=0x4C;
  }
  if(!(hit&0x344) && (oE->shovable&(1<<dir)) && o->inertia>=oE->weight) {
    oE->inertia=o->inertia;
    if(move_dir(msgvars.from,objE,dir)) {
      if(!(oE->oflags&OF_DESTROYED)) o->inertia=oE->inertia;
      hit|=0x8000;
    }
  }
  msgvars.arg3.u=hit|7;
  return (hit&0x8008)==0x8000?1: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)
2358
2359
2360
2361
2362
2363
2364

2365
2366
2367
2368
2369
2370
2371
    case OP_HEIGHT: StackReq(0,1); Push(NVALUE(o->height)); break;
    case OP_HEIGHT_C: StackReq(1,1); Push(GetVariableOrAttributeOf(height,NVALUE)); break;
    case OP_HEIGHT_E: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->height=t1.u; break;
    case OP_HEIGHT_E16: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->height=t1.u&0xFFFF; break;
    case OP_HEIGHT_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->height=t1.u; break;
    case OP_HEIGHT_EC16: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->height=t1.u&0xFFFF; break;
    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;







>







2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
    case OP_HEIGHT: StackReq(0,1); Push(NVALUE(o->height)); break;
    case OP_HEIGHT_C: StackReq(1,1); Push(GetVariableOrAttributeOf(height,NVALUE)); break;
    case OP_HEIGHT_E: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->height=t1.u; break;
    case OP_HEIGHT_E16: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->height=t1.u&0xFFFF; break;
    case OP_HEIGHT_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->height=t1.u; break;
    case OP_HEIGHT_EC16: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->height=t1.u&0xFFFF; break;
    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_HITME: NoIgnore(); StackReq(1,1); t1=Pop(); Numeric(t1); i=v_hitme(obj,t1.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;
2541
2542
2543
2544
2545
2546
2547


2548
2549
2550
2551
2552
2553
2554
    case OP_STRING: StackReq(0,1); Push(UVALUE(code[ptr++],TY_STRING)); break;
    case OP_SOUND: StackReq(2,0); t2=Pop(); t1=Pop(); break; // Sound not implemented at this time
    case OP_SUB: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.u-t2.u)); break;
    case OP_SUPER: i=code[1]; code=classes[i]->codes; ptr=get_message_ptr(i,msgvars.msg); if(ptr==0xFFFF) break; break;
    case OP_SUPER_C: i=code[1]; j=get_message_ptr(i,msgvars.msg); if(j!=0xFFFF) execute_program(classes[i]->codes,j,obj); break;
    case OP_SWAP: StackReq(2,2); t1=Pop(); t2=Pop(); Push(t1); Push(t2); break;
    case OP_SWAPWORLD: NoIgnore(); swap_world(); break;


    case OP_SYNCHRONIZE: StackReq(2,0); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); animate_sync(obj,t1.u,t2.u); break;
    case OP_TARGET: StackReq(0,1); Push(NVALUE(v_target(obj)?1:0)); break;
    case OP_TARGET_C: StackReq(1,1); i=v_object(Pop()); Push(NVALUE(v_target(i)?1:0)); 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;







>
>







2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
    case OP_STRING: StackReq(0,1); Push(UVALUE(code[ptr++],TY_STRING)); break;
    case OP_SOUND: StackReq(2,0); t2=Pop(); t1=Pop(); break; // Sound not implemented at this time
    case OP_SUB: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.u-t2.u)); break;
    case OP_SUPER: i=code[1]; code=classes[i]->codes; ptr=get_message_ptr(i,msgvars.msg); if(ptr==0xFFFF) break; break;
    case OP_SUPER_C: i=code[1]; j=get_message_ptr(i,msgvars.msg); if(j!=0xFFFF) execute_program(classes[i]->codes,j,obj); break;
    case OP_SWAP: StackReq(2,2); t1=Pop(); t2=Pop(); Push(t1); Push(t2); break;
    case OP_SWAPWORLD: NoIgnore(); swap_world(); break;
    case OP_SWEEP: StackReq(8,0); v_sweep(obj,NVALUE(0)); break;
    case OP_SWEEPEX: StackReq(9,0); t1=Pop(); v_sweep(obj,t1); break;
    case OP_SYNCHRONIZE: StackReq(2,0); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); animate_sync(obj,t1.u,t2.u); break;
    case OP_TARGET: StackReq(0,1); Push(NVALUE(v_target(obj)?1:0)); break;
    case OP_TARGET_C: StackReq(1,1); i=v_object(Pop()); Push(NVALUE(v_target(i)?1:0)); 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;