︙ | | | ︙ | |
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
static Uint8 lastimage_processing,changed,all_flushed;
static Value vstack[VSTACKSIZE];
static int vstackptr;
static const char*traceprefix;
static Uint8 current_key;
static Value quiz_obj;
static Value traced_obj;
#define Throw(x) (my_error=(x),longjmp(my_env,1))
#define StackReq(x,y) do{ if(vstackptr<(x)) Throw("Stack underflow"); if(vstackptr-(x)+(y)>=VSTACKSIZE) Throw("Stack overflow"); }while(0)
#define Push(x) (vstack[vstackptr++]=(x))
#define Pop() (vstack[--vstackptr])
// For arrival/departure masks
|
>
|
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
static Uint8 lastimage_processing,changed,all_flushed;
static Value vstack[VSTACKSIZE];
static int vstackptr;
static const char*traceprefix;
static Uint8 current_key;
static Value quiz_obj;
static Value traced_obj;
static Uint32 control_obj=VOIDLINK;
#define Throw(x) (my_error=(x),longjmp(my_env,1))
#define StackReq(x,y) do{ if(vstackptr<(x)) Throw("Stack underflow"); if(vstackptr-(x)+(y)>=VSTACKSIZE) Throw("Stack overflow"); }while(0)
#define Push(x) (vstack[vstackptr++]=(x))
#define Pop() (vstack[--vstackptr])
// For arrival/departure masks
|
︙ | | | ︙ | |
531
532
533
534
535
536
537
538
539
540
541
542
543
544
|
if(!((o->oflags|p->oflags)&(OF_VISUALONLY|OF_DESTROYED))) send_message(y,x,MSG_SUNK,NVALUE(0),NVALUE(0),v);
}
static void change_density(Uint32 n,Sint32 v) {
Object*o=objects[n];
Uint32 i;
if(o->oflags&OF_BIZARRO) return;
if(v<o->density) {
o->density=v;
for(;;) {
i=o->up;
if(i==VOIDLINK || objects[i]->density<=v) return;
sink(i,n);
}
|
>
>
>
>
|
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
|
if(!((o->oflags|p->oflags)&(OF_VISUALONLY|OF_DESTROYED))) send_message(y,x,MSG_SUNK,NVALUE(0),NVALUE(0),v);
}
static void change_density(Uint32 n,Sint32 v) {
Object*o=objects[n];
Uint32 i;
if(o->oflags&OF_BIZARRO) return;
if(n==control_obj) {
o->density=v;
return;
}
if(v<o->density) {
o->density=v;
for(;;) {
i=o->up;
if(i==VOIDLINK || objects[i]->density<=v) return;
sink(i,n);
}
|
︙ | | | ︙ | |
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
|
static Uint32 create(Uint32 from,Uint16 c,Uint32 x,Uint32 y,Uint32 im,Uint32 d) {
Uint32 m,n;
int i,xx,yy;
Object*o;
Object*p;
Value v;
if(d>7) d=0;
if(x<1 || y<1 || x>pfwidth || y>pfheight) return VOIDLINK;
if(!(classes[c]->oflags&OF_BIZARRO) && (i=classes[c]->collisionLayers) && (xx=collisions_at(x,y)&i)) {
if(collide_with(xx,VOIDLINK,x,y,c)&0x01) return VOIDLINK;
}
n=objalloc(c);
if(n==VOIDLINK) Throw("Error creating object");
o=objects[n];
o->x=x;
|
|
|
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
|
static Uint32 create(Uint32 from,Uint16 c,Uint32 x,Uint32 y,Uint32 im,Uint32 d) {
Uint32 m,n;
int i,xx,yy;
Object*o;
Object*p;
Value v;
if(d>7) d=0;
if(x<1 || y<1 || x>pfwidth || y>pfheight || c==control_class) return VOIDLINK;
if(!(classes[c]->oflags&OF_BIZARRO) && (i=classes[c]->collisionLayers) && (xx=collisions_at(x,y)&i)) {
if(collide_with(xx,VOIDLINK,x,y,c)&0x01) return VOIDLINK;
}
n=objalloc(c);
if(n==VOIDLINK) Throw("Error creating object");
o=objects[n];
o->x=x;
|
︙ | | | ︙ | |
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
|
}
static Value destroy(Uint32 from,Uint32 to,Uint32 why) {
Object*o;
Value v;
int i,x,y,xx,yy;
Uint32 n;
if(to==VOIDLINK) return NVALUE(0);
o=objects[to];
// EKS Hero Mesh doesn't check if it already destroyed.
v=why==8?NVALUE(0):send_message(from,to,MSG_DESTROY,NVALUE(0),NVALUE(0),NVALUE(why));
if(!v_bool(v)) {
if(!(o->oflags&OF_DESTROYED)) {
if(firstobj==to) firstobj=o->next;
if(lastobj==to) lastobj=o->prev;
|
|
|
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
|
}
static Value destroy(Uint32 from,Uint32 to,Uint32 why) {
Object*o;
Value v;
int i,x,y,xx,yy;
Uint32 n;
if(to==VOIDLINK || to==control_obj) return NVALUE(0);
o=objects[to];
// EKS Hero Mesh doesn't check if it already destroyed.
v=why==8?NVALUE(0):send_message(from,to,MSG_DESTROY,NVALUE(0),NVALUE(0),NVALUE(why));
if(!v_bool(v)) {
if(!(o->oflags&OF_DESTROYED)) {
if(firstobj==to) firstobj=o->next;
if(lastobj==to) lastobj=o->prev;
|
︙ | | | ︙ | |
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
|
static int move_to(Uint32 from,Uint32 n,Uint32 x,Uint32 y) {
Uint32 m;
int i,xx,yy;
Object*o;
Object*p;
Value v;
if(n==VOIDLINK || (objects[n]->oflags&OF_DESTROYED)) return 0;
o=objects[n];
if(lastimage_processing) Throw("Can't move during animation processing");
if(x<1 || y<1 || x>pfwidth || y>pfheight) return 0;
if(v_bool(send_message(from,n,MSG_MOVING,NVALUE(x),NVALUE(y),NVALUE(0)))) return 0;
if(classes[o->class]->cflags&CF_PLAYER) {
m=lastobj;
while(m!=VOIDLINK) {
|
|
|
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
|
static int move_to(Uint32 from,Uint32 n,Uint32 x,Uint32 y) {
Uint32 m;
int i,xx,yy;
Object*o;
Object*p;
Value v;
if(n==VOIDLINK || (objects[n]->oflags&OF_DESTROYED) || n==control_obj) return 0;
o=objects[n];
if(lastimage_processing) Throw("Can't move during animation processing");
if(x<1 || y<1 || x>pfwidth || y>pfheight) return 0;
if(v_bool(send_message(from,n,MSG_MOVING,NVALUE(x),NVALUE(y),NVALUE(0)))) return 0;
if(classes[o->class]->cflags&CF_PLAYER) {
m=lastobj;
while(m!=VOIDLINK) {
|
︙ | | | ︙ | |
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
|
static int defer_move(Uint32 obj,Uint32 dir,Uint8 plus) {
Object*o;
Object*q;
Uint32 n;
Value v;
if(StackProtection()) Throw("Call stack overflow during movement");
if(obj==VOIDLINK) return 0;
o=objects[obj];
if(o->oflags&(OF_DESTROYED|OF_BIZARRO)) return 0;
dir=resolve_dir(obj,dir);
if(plus) {
if(o->oflags&OF_MOVING) {
if(o->dir==dir) return 1;
v=send_message(VOIDLINK,obj,MSG_CONFLICT,NVALUE(dir),NVALUE(0),NVALUE(0));
|
|
|
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
|
static int defer_move(Uint32 obj,Uint32 dir,Uint8 plus) {
Object*o;
Object*q;
Uint32 n;
Value v;
if(StackProtection()) Throw("Call stack overflow during movement");
if(obj==VOIDLINK || obj==control_obj) return 0;
o=objects[obj];
if(o->oflags&(OF_DESTROYED|OF_BIZARRO)) return 0;
dir=resolve_dir(obj,dir);
if(plus) {
if(o->oflags&OF_MOVING) {
if(o->dir==dir) return 1;
v=send_message(VOIDLINK,obj,MSG_CONFLICT,NVALUE(dir),NVALUE(0),NVALUE(0));
|
︙ | | | ︙ | |
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
|
if(current_key) all_flushed=255;
flush_class(0);
}
static void set_bizarro(Uint32 n,Uint32 v) {
Object*o;
Uint8 b;
if(n==VOIDLINK) return;
o=objects[n];
if(o->oflags&OF_DESTROYED) return;
if(v) {
if(o->oflags&OF_BIZARRO) return;
pfunlink(n);
o->oflags|=OF_BIZARRO;
pflink(n);
|
|
|
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
|
if(current_key) all_flushed=255;
flush_class(0);
}
static void set_bizarro(Uint32 n,Uint32 v) {
Object*o;
Uint8 b;
if(n==VOIDLINK || n==control_obj) return;
o=objects[n];
if(o->oflags&OF_DESTROYED) return;
if(v) {
if(o->oflags&OF_BIZARRO) return;
pfunlink(n);
o->oflags|=OF_BIZARRO;
pflink(n);
|
︙ | | | ︙ | |
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
|
Uint8 d=objects[obj]->dir;
Uint32 n=VOIDLINK;
Uint32 m;
Uint16 g;
Value v;
static ChoicePoint cp[MAXCHOICE];
Uint8 cpi=0;
cp->depth=vstackptr;
again: switch(code[ptr++]) {
case 0 ... 7:
n=VOIDLINK;
x+=x_delta[code[ptr-1]];
y+=y_delta[code[ptr-1]];
if(x<1 || x>pfwidth || y<1 || y>pfheight) goto fail;
|
>
|
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
|
Uint8 d=objects[obj]->dir;
Uint32 n=VOIDLINK;
Uint32 m;
Uint16 g;
Value v;
static ChoicePoint cp[MAXCHOICE];
Uint8 cpi=0;
if(!x) return VOIDLINK;
cp->depth=vstackptr;
again: switch(code[ptr++]) {
case 0 ... 7:
n=VOIDLINK;
x+=x_delta[code[ptr-1]];
y+=y_delta[code[ptr-1]];
if(x<1 || x>pfwidth || y<1 || y>pfheight) goto fail;
|
︙ | | | ︙ | |
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
|
if(v.u==1) goto fail;
else if(v.u==2) break;
else if(v.u) Throw("Invalid return value from message in pattern matching");
} else if(v.t>TY_MAXTYPE) {
n=v_object(v);
x=objects[n]->x;
y=objects[n]->y;
} else {
Throw("Type mismatch");
}
m=objects[m]->up;
}
break;
case OP_ADD:
|
>
|
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
|
if(v.u==1) goto fail;
else if(v.u==2) break;
else if(v.u) Throw("Invalid return value from message in pattern matching");
} else if(v.t>TY_MAXTYPE) {
n=v_object(v);
x=objects[n]->x;
y=objects[n]->y;
if(!x) return VOIDLINK;
} else {
Throw("Type mismatch");
}
m=objects[m]->up;
}
break;
case OP_ADD:
|
︙ | | | ︙ | |
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
|
d=v.u&7;
} else if(v.t==TY_MARK) {
goto fail;
} else if(v.t>TY_MAXTYPE) {
n=v_object(v);
x=objects[n]->x;
y=objects[n]->y;
} else {
Throw("Type mismatch");
}
break;
case OP_HEIGHT:
if(playfield[x+y*64-65]==VOIDLINK || height_at(x,y)<=objects[obj]->climb) goto fail;
break;
|
>
|
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
|
d=v.u&7;
} else if(v.t==TY_MARK) {
goto fail;
} else if(v.t>TY_MAXTYPE) {
n=v_object(v);
x=objects[n]->x;
y=objects[n]->y;
if(!x) return VOIDLINK;
} else {
Throw("Type mismatch");
}
break;
case OP_HEIGHT:
if(playfield[x+y*64-65]==VOIDLINK || height_at(x,y)<=objects[obj]->climb) goto fail;
break;
|
︙ | | | ︙ | |
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
|
case OP_CLIMB_EC16: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) o->climb=t1.u&0xFFFF; break;
case OP_COLLISIONLAYERS: StackReq(0,1); Push(NVALUE(classes[o->class]->collisionLayers)); break;
case OP_COLLISIONLAYERS_C: StackReq(1,1); i=v_object(Pop()); if(i==VOIDLINK) Push(NVALUE(0)); else Push(NVALUE(classes[objects[i]->class]->collisionLayers)); break;
case OP_COLOC: StackReq(1,1); t1=Pop(); i=colocation(obj,v_object(t1)); Push(NVALUE(i)); break;
case OP_COLOC_C: StackReq(2,1); t1=Pop(); t2=Pop(); i=colocation(v_object(t1),v_object(t2)); Push(NVALUE(i)); break;
case OP_COMPATIBLE: StackReq(0,1); if(classes[o->class]->cflags&CF_COMPATIBLE) Push(NVALUE(1)); else Push(NVALUE(0)); break;
case OP_COMPATIBLE_C: StackReq(1,1); GetClassFlagOf(CF_COMPATIBLE); break;
case OP_COPYARRAY: NoIgnore(); StackReq(2,0); t2=Pop(); t1=Pop(); v_copy_array(t1,t2); break;
case OP_COUNT: StackReq(1,2); i=v_count(); Push(NVALUE(i)); break;
case OP_CREATE: NoIgnore(); StackReq(5,1); t5=Pop(); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); Push(v_create(obj,t1,t2,t3,t4,t5)); break;
case OP_CREATE_D: NoIgnore(); StackReq(5,0); t5=Pop(); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); v_create(obj,t1,t2,t3,t4,t5); break;
case OP_DATA: StackReq(2,1); t2=Pop(); t1=Pop(); v_data(t1,t2); break;
case OP_DELINVENTORY: StackReq(2,0); t2=Pop(); t1=Pop(); v_delete_inventory(t1,t2); break;
case OP_DELTA: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.u>t2.u?t1.u-t2.u:t2.u-t1.u)); break;
|
>
|
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
|
case OP_CLIMB_EC16: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) o->climb=t1.u&0xFFFF; break;
case OP_COLLISIONLAYERS: StackReq(0,1); Push(NVALUE(classes[o->class]->collisionLayers)); break;
case OP_COLLISIONLAYERS_C: StackReq(1,1); i=v_object(Pop()); if(i==VOIDLINK) Push(NVALUE(0)); else Push(NVALUE(classes[objects[i]->class]->collisionLayers)); break;
case OP_COLOC: StackReq(1,1); t1=Pop(); i=colocation(obj,v_object(t1)); Push(NVALUE(i)); break;
case OP_COLOC_C: StackReq(2,1); t1=Pop(); t2=Pop(); i=colocation(v_object(t1),v_object(t2)); Push(NVALUE(i)); break;
case OP_COMPATIBLE: StackReq(0,1); if(classes[o->class]->cflags&CF_COMPATIBLE) Push(NVALUE(1)); else Push(NVALUE(0)); break;
case OP_COMPATIBLE_C: StackReq(1,1); GetClassFlagOf(CF_COMPATIBLE); break;
case OP_CONTROL: StackReq(0,1); Push(OVALUE(control_obj)); break;
case OP_COPYARRAY: NoIgnore(); StackReq(2,0); t2=Pop(); t1=Pop(); v_copy_array(t1,t2); break;
case OP_COUNT: StackReq(1,2); i=v_count(); Push(NVALUE(i)); break;
case OP_CREATE: NoIgnore(); StackReq(5,1); t5=Pop(); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); Push(v_create(obj,t1,t2,t3,t4,t5)); break;
case OP_CREATE_D: NoIgnore(); StackReq(5,0); t5=Pop(); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); v_create(obj,t1,t2,t3,t4,t5); break;
case OP_DATA: StackReq(2,1); t2=Pop(); t1=Pop(); v_data(t1,t2); break;
case OP_DELINVENTORY: StackReq(2,0); t2=Pop(); t1=Pop(); v_delete_inventory(t1,t2); break;
case OP_DELTA: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.u>t2.u?t1.u-t2.u:t2.u-t1.u)); break;
|
︙ | | | ︙ | |
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
|
gameover=0;
clear_inventory();
for(i=0;i<nlevelstrings;i++) free(levelstrings[i]);
nlevelstrings=0;
free(deadanim);
deadanim=0;
ndeadanim=0;
}
static inline int try_sharp(Uint32 n1,Uint32 n2) {
Object*o=objects[n1];
Object*p=objects[n2];
if((o->oflags|p->oflags)&OF_DESTROYED) return 0;
if(o->dir&1) return 0;
|
>
|
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
|
gameover=0;
clear_inventory();
for(i=0;i<nlevelstrings;i++) free(levelstrings[i]);
nlevelstrings=0;
free(deadanim);
deadanim=0;
ndeadanim=0;
control_obj=VOIDLINK;
}
static inline int try_sharp(Uint32 n1,Uint32 n2) {
Object*o=objects[n1];
Object*p=objects[n2];
if((o->oflags|p->oflags)&OF_DESTROYED) return 0;
if(o->dir&1) return 0;
|
︙ | | | ︙ | |
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
|
changed=0;
key_ignored=0;
all_flushed=0;
lastimage_processing=0;
vstackptr=0;
move_number=0;
current_key=0;
n=lastobj;
while(n!=VOIDLINK && !(objects[n]->oflags&OF_ORDERED)) {
send_message(VOIDLINK,n,MSG_INIT,NVALUE(0),NVALUE(0),NVALUE(0));
if(classes[objects[n]->class]->order && !(objects[n]->oflags&OF_DESTROYED)) set_order(n);
n=objects[n]->prev;
}
broadcast(VOIDLINK,0,MSG_POSTINIT,NVALUE(0),NVALUE(0),NVALUE(0),0);
if(gameover) return 0;
return execute_turn(0);
}
|
>
>
>
>
|
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
|
changed=0;
key_ignored=0;
all_flushed=0;
lastimage_processing=0;
vstackptr=0;
move_number=0;
current_key=0;
if(control_class) {
control_obj=objalloc(control_class);
if(control_obj==VOIDLINK) Throw("Error creating object");
}
n=lastobj;
while(n!=VOIDLINK && !(objects[n]->oflags&OF_ORDERED)) {
send_message(VOIDLINK,n,MSG_INIT,NVALUE(0),NVALUE(0),NVALUE(0));
if(classes[objects[n]->class]->order && !(objects[n]->oflags&OF_DESTROYED)) set_order(n);
n=objects[n]->prev;
}
broadcast(VOIDLINK,0,MSG_POSTINIT,NVALUE(0),NVALUE(0),NVALUE(0),0);
if(gameover) return 0;
return execute_turn(0);
}
|