Index: TODO ================================================================== --- TODO +++ TODO @@ -8,11 +8,10 @@ * Multiple connected objects moving as a unit * Bizarro world * Testing the deferred movement * String data (?) * A ,PopUp command to use a popup with arguments starting from a mark - * Operations with marks (duplicate a list, length of a list, etc) * "Goto message" instruction * Class inheritance (abstract) * Returning a class from COLLIDE/COLLIDEBY to transform * Editor * Mouse dragging Index: class.doc ================================================================== --- class.doc +++ class.doc @@ -1164,10 +1164,13 @@ ,Chebyshev ( obj1 obj2 -- number ) Calculate the Chebyshev distance between thie two specified objects. If either specified object is zero, then the result is also zero. +clear ( mark ... -- ) + Remove everything above the mark including the mark itself. + Coloc ( obj -- bool ) True if this object and the specified object are in the same place, or false otherwise. Always false if the object is destroyed, or if one object is in the bizarro world and the other one isn't. @@ -1177,10 +1180,13 @@ is in the bizarro world and the other one isn't. CopyArray ( src dest -- ) ** Copy one array to another. It is OK if the two references overlap. +count ( mark ... -- mark ... count ) + Count how many values are above the mark on the stack. + Create ( class x y image dir -- obj ) ** Creates a new object at the specified location, and returns it. The result is zero if the class is zero, the coordinates are out of range, the object cannot be created due to the CollisionLayers, or if the new object is destroyed before its CREATE message returns. @@ -1662,10 +1668,15 @@ on stdout. If tracing is disabled, does nothing. This is intended to be used for debugging class codes. tuck ( x y -- y x y ) +uniq ( mark ... value -- mark ... value true | mark ... false ) + Check if the top value matches any others in the list above the mark. If + it doesn't match any, then the value remains and it pushes true; if it + does match, then the top value is removed and it pushes false instead. + VolumeAt ( x y -- volume ) Finds the greatest volume among objects at the specified location. WinLevel ( -- ) Ends all execution and accepts the input sequence that resulted in the Index: exec.c ================================================================== --- exec.c +++ exec.c @@ -1524,19 +1524,41 @@ static inline void v_flip(void) { int p=vstackptr; int n; Value v; - while(p-- && vstack[p].t!=TY_MARK); + while(p>0 && vstack[p-1].t!=TY_MARK) p--; if(!p) Throw("No mark"); p++; for(n=0;n<(vstackptr-p)/2;n++) { v=vstack[p+n]; vstack[p+n]=vstack[vstackptr-n-1]; vstack[vstackptr-n-1]=v; } } + +static int v_count(void) { + int p=vstackptr; + while(p>0 && vstack[p-1].t!=TY_MARK) p--; + if(!p) Throw("No mark"); + return vstackptr-p; +} + +static int v_uniq(Value v) { + int p=vstackptr; + if(v.t==TY_SOUND || v.t==TY_USOUND) Throw("Cannot compare sounds"); + while(p>0) { + p--; + if(vstack[p].t==TY_MARK) return 1; + if(vstack[p].t==TY_SOUND || vstack[p].t==TY_USOUND) Throw("Cannot compare sounds"); + if(v.t==vstack[p].t && v.u==vstack[p].u) return 0; + if((v.t==TY_STRING || v.t==TY_LEVELSTRING) && (vstack[p].t==TY_STRING || vstack[p].t==TY_LEVELSTRING)) { + if(!strcmp(value_string_ptr(v),value_string_ptr(vstack[p]))) return 1; + } + } + Throw("No mark"); +} static inline void v_obj_moving_to(Uint32 x,Uint32 y) { int d; Uint32 n,xx,yy; Object*o; @@ -1988,10 +2010,11 @@ case OP_CHAIN: StackReq(1,1); t1=Pop(); i=v_chain(t1,o->class); if(i==VOIDLINK) { Push(NVALUE(1)); } else { o=objects[obj=i]; Push(NVALUE(0)); } break; case OP_CHEBYSHEV: StackReq(1,1); t1=Pop(); i=chebyshev(obj,v_object(t1)); Push(NVALUE(i)); break; case OP_CHEBYSHEV_C: StackReq(2,1); t2=Pop(); t1=Pop(); i=chebyshev(v_object(t1),v_object(t2)); Push(NVALUE(i)); break; case OP_CLASS: StackReq(0,1); Push(CVALUE(o->class)); break; case OP_CLASS_C: StackReq(1,1); Push(GetVariableOf(class,CVALUE)); break; + case OP_CLEAR: t1.t=TY_NUMBER; while(vstackptr>0) { t1=Pop(); if(t1.t==TY_MARK) break; } if(t1.t!=TY_MARK) Throw("No mark"); break; case OP_CLIMB: StackReq(0,1); Push(NVALUE(o->climb)); break; case OP_CLIMB_C: StackReq(1,1); Push(GetVariableOrAttributeOf(climb,NVALUE)); break; case OP_CLIMB_E: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->climb=t1.u; break; case OP_CLIMB_E16: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->climb=t1.u&0xFFFF; break; case OP_CLIMB_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) o->climb=t1.u; break; @@ -2001,10 +2024,11 @@ 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_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; case OP_DENSITY: StackReq(0,1); Push(NVALUE(o->density)); break; @@ -2264,10 +2288,11 @@ case OP_TEMPERATURE_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->temperature=t1.u; break; case OP_TEMPERATURE_EC16: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->temperature=t1.u&0xFFFF; break; case OP_TMARK: StackReq(1,2); t1=Pop(); if(t1.t==TY_MARK) { Push(NVALUE(0)); } else { Push(t1); Push(NVALUE(1)); } break; case OP_TRACE: StackReq(3,0); trace_stack(obj); break; case OP_TUCK: StackReq(2,3); t2=Pop(); t1=Pop(); Push(t2); Push(t1); Push(t2); break; + case OP_UNIQ: StackReq(2,3); t1=Pop(); i=v_uniq(t1); if(i) Push(t1); Push(NVALUE(i)); break; case OP_USERSIGNAL: StackReq(0,1); if(o->oflags&OF_USERSIGNAL) Push(NVALUE(1)); else Push(NVALUE(0)); break; case OP_USERSIGNAL_C: StackReq(1,1); GetFlagOf(OF_USERSIGNAL); break; case OP_USERSIGNAL_E: NoIgnore(); StackReq(1,0); if(v_bool(Pop())) o->oflags|=OF_USERSIGNAL; else o->oflags&=~OF_USERSIGNAL; break; case OP_USERSIGNAL_EC: NoIgnore(); StackReq(2,0); SetFlagOf(OF_USERSIGNAL); break; case OP_USERSTATE: StackReq(0,1); if(o->oflags&OF_USERSTATE) Push(NVALUE(1)); else Push(NVALUE(0)); break; Index: instruc ================================================================== --- instruc +++ instruc @@ -275,10 +275,13 @@ tmark in nin -mbegin flip +count +clear +uniq ; Arrays -Array GetArray InitArray Index: instruc.h ================================================================== --- instruc.h +++ instruc.h @@ -405,37 +405,40 @@ #define OP_TMARK 32969 #define OP_IN 32970 #define OP_NIN 32971 #define OP_MBEGIN 32972 #define OP_FLIP 32973 -#define OP_ARRAY 32974 -#define OP_GETARRAY 32975 -#define OP_INITARRAY 32976 -#define OP_SETARRAY 32977 -#define OP_ARRAYCELL 32978 -#define OP_ARRAYSLICE 32979 -#define OP_COPYARRAY 32980 -#define OP_DOTPRODUCT 32981 -#define OP_PATTERN 32982 -#define OP_PATTERN_C 35030 -#define OP_PATTERN_E 37078 -#define OP_PATTERN_EC 39126 -#define OP_PATTERNS 32983 -#define OP_PATTERNS_C 35031 -#define OP_PATTERNS_E 37079 -#define OP_PATTERNS_EC 39127 -#define OP_FOUR 32984 -#define OP_EIGHT 32985 -#define OP_CUT 32986 -#define OP_FUNCTION 32987 -#define OP_LOCAL 32988 -#define OP_LABEL 32989 -#define OP_STRING 32990 -#define OP_INT16 32991 -#define OP_INT32 32992 -#define OP_DISPATCH 32993 -#define OP_USERFLAG 32994 +#define OP_COUNT 32974 +#define OP_CLEAR 32975 +#define OP_UNIQ 32976 +#define OP_ARRAY 32977 +#define OP_GETARRAY 32978 +#define OP_INITARRAY 32979 +#define OP_SETARRAY 32980 +#define OP_ARRAYCELL 32981 +#define OP_ARRAYSLICE 32982 +#define OP_COPYARRAY 32983 +#define OP_DOTPRODUCT 32984 +#define OP_PATTERN 32985 +#define OP_PATTERN_C 35033 +#define OP_PATTERN_E 37081 +#define OP_PATTERN_EC 39129 +#define OP_PATTERNS 32986 +#define OP_PATTERNS_C 35034 +#define OP_PATTERNS_E 37082 +#define OP_PATTERNS_EC 39130 +#define OP_FOUR 32987 +#define OP_EIGHT 32988 +#define OP_CUT 32989 +#define OP_FUNCTION 32990 +#define OP_LOCAL 32991 +#define OP_LABEL 32992 +#define OP_STRING 32993 +#define OP_INT16 32994 +#define OP_INT32 32995 +#define OP_DISPATCH 32996 +#define OP_USERFLAG 32997 #ifdef HEROMESH_CLASS static const Op_Names op_names[]={ {"*",8486937}, {"+",8421399}, {"+Move",10584235}, @@ -449,13 +452,13 @@ {"Animate",8421513}, {"AnimateDead",8421514}, {"Arg1",8552569}, {"Arg2",8552570}, {"Arg3",8552571}, -{"Array",8683726}, -{"ArrayCell",8421586}, -{"ArraySlice",8421587}, +{"Array",8683729}, +{"ArrayCell",8421589}, +{"ArraySlice",8421590}, {"Arrivals",8618086}, {"Arrived",8618084}, {"Assassinate",8487051}, {"B",9437196}, {"BANG",8389380}, @@ -493,11 +496,11 @@ {"Climb",9142350}, {"CodePage",8683649}, {"CollisionLayers",8487029}, {"Coloc",8487063}, {"Compatible",8487028}, -{"CopyArray",8421588}, +{"CopyArray",8421591}, {"Create",10518680}, {"DEEP_POP",8389417}, {"DEPARTED",8389125}, {"DESTROY",8389122}, {"DESTROYED",8389136}, @@ -514,28 +517,28 @@ {"Destroy",10584219}, {"Destroyed",8487026}, {"Dir",8618048}, {"Distance",9142340}, {"Done",8618097}, -{"DotProduct",8421589}, +{"DotProduct",8421592}, {"E",9437184}, {"END_TURN",8389139}, {"EditorHelp",8683655}, -{"Eight",8683737}, +{"Eight",8683740}, {"F",9437192}, {"FAROUT",8389421}, {"FFFFTT",8389399}, {"FLOATED",8389132}, {"FROG",8389383}, {"Finished",8552575}, {"FlushClass",8421532}, {"FlushObj",8487069}, -{"Four",8683736}, +{"Four",8683739}, {"From",8421496}, {"GLASS",8389379}, {"GLISSANT",8389419}, -{"GetArray",8421583}, +{"GetArray",8421586}, {"GetInventory",8421534}, {"HAWK",8389425}, {"HEARTBEAT",8389407}, {"HIT",8389134}, {"HITBY",8389135}, @@ -546,11 +549,11 @@ {"INIT",8389120}, {"IgnoreKey",8421536}, {"Image",8618049}, {"InPlace",8683652}, {"Inertia",9142338}, -{"InitArray",8421584}, +{"InitArray",8421587}, {"Input",8683650}, {"IntMove",10584225}, {"Invisible",8618089}, {"JAYAYAYNG",8389416}, {"JUMPED",8389128}, @@ -605,12 +608,12 @@ {"ObjClassAt",8421555}, {"ObjDir",8487092}, {"ObjLayerAt",8421557}, {"ObjMovingTo",8421558}, {"ObjTopAt",8421559}, -{"P",8880342}, -{"P*",8880343}, +{"P",8880345}, +{"P*",8880346}, {"PLAYERMOVING",8389133}, {"POSTINIT",8389138}, {"POUR",8389377}, {"POWER",8389386}, {"Player",8487027}, @@ -634,11 +637,11 @@ {"SW",9437189}, {"Seek",8487099}, {"Self",8421494}, {"Send",10584252}, {"SendEx",10584253}, -{"SetArray",8421585}, +{"SetArray",8421588}, {"SetInventory",8421566}, {"Shape",8618045}, {"ShapeDir",8618068}, {"Sharp",8618067}, {"Shovable",8618069}, @@ -715,11 +718,13 @@ {"bor",8421410}, {"bxor",8421411}, {"c?",8421427}, {"case",8683542}, {"chain",8421525}, -{"cut",8683738}, +{"clear",8421583}, +{"count",8421582}, +{"cut",8683741}, {"cz?",8421428}, {"dup",8421377}, {"else",8683530}, {"eq",8421418}, {"eq2",8421419}, @@ -759,10 +764,11 @@ {"s?",8421430}, {"swap",8421378}, {"then",8683531}, {"tmark",8421577}, {"tuck",8421380}, +{"uniq",8421584}, {"until",8683534}, {"while",8683535}, }; -#define N_OP_NAMES 327 +#define N_OP_NAMES 330 #endif