Index: class.c ================================================================== --- class.c +++ class.c @@ -909,15 +909,15 @@ if(tokent!=TF_INT) ParseError("Number expected\n"); x=tokenv; nxttok(); if(tokent!=TF_INT) ParseError("Number expected\n"); y=tokenv; - if(x<1 || x>64 || y<1 || y>255) ParseError("Array dimension out of range\n"); + if(x<1 || x>64 || y<1 || y>1024) ParseError("Array dimension out of range\n"); z=array_size; if(z+x*y>0xFFFE) ParseError("Out of array memory\n"); array_size+=x*y; - return z|(y<<16)|(x<<24); + return z|((y-1)<<16)|((x-1)<<26); } static void begin_label_stack(void) { labelstack=0; labelptr=malloc(0x8000*sizeof(Uint16)); Index: class.doc ================================================================== --- class.doc +++ class.doc @@ -216,15 +216,15 @@ Define a class. See the section about class definitions for details. (@ ) Define a global variable and its initial value. -(@ Array ) +(@ Array ) Define a global variable whose value is a reference to a new array, with - the specified dimensions. The maximum number of columns is 64, and the - maximum number of rows is 255, and he maximum number of cells in all - arrays in total is 65534. + the specified dimensions. The maximum number of rows is 64, and the + maximum number of columns is 1024, and the maximum number of cells in + all arrays in total is 65534. ( ) Defines a default message code for all classes which do not specify their own code for this message. Index: exec.c ================================================================== --- exec.c +++ exec.c @@ -1127,10 +1127,37 @@ if(!inventory) fatal("Allocation failed\n"); inventory[i].class=cl.u; inventory[i].image=im.u; inventory[i].value=va.u; } + +static void v_init_array(Value ar,Value v) { + Uint32 s,n; + if(ar.t!=TY_ARRAY) Throw("Type mismatch"); + s=ar.u&0xFFFF; + n=((ar.u>>16)&0x3FF)+1; + n*=((ar.u>>26)&0x3F)+1; + while(n--) array_data[s++]=v; +} + +static Value v_get_array(Value ar,Uint32 x,Uint32 y) { + Uint32 s; + if(ar.t!=TY_ARRAY) Throw("Type mismatch"); + s=ar.u&0xFFFF; + if(y>((ar.u>>16)&0x3FF) || x>((ar.u>>26)&0x3F)) Throw("Array index out of bounds"); + s+=x+y+((ar.u>>26)&0x3F)*y; + return array_data[s]; +} + +static void v_set_array(Value ar,Uint32 x,Uint32 y,Value v) { + Uint32 s; + if(ar.t!=TY_ARRAY) Throw("Type mismatch"); + s=ar.u&0xFFFF; + if(y>((ar.u>>16)&0x3FF) || x>((ar.u>>26)&0x3F)) Throw("Array index out of bounds"); + s+=x+y+((ar.u>>26)&0x3F)*y; + array_data[s]=v; +} static void v_set_popup(Uint32 from,int argc) { const unsigned char*t; const unsigned char*u; sqlite3_str*s; @@ -1417,10 +1444,11 @@ 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_FROM: StackReq(0,1); Push(OVALUE(msgvars.from)); 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; case OP_GT: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_unsigned_greater(t1,t2)?1:0)); break; case OP_GT_C: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_signed_greater(t1,t2)?1:0)); break; case OP_HARD: StackReq(1,1); j=v_sh_dir(Pop()); Push(NVALUE(o->hard[j])); break; @@ -1445,10 +1473,11 @@ case OP_INERTIA_C: StackReq(1,1); Push(GetVariableOf(inertia,NVALUE)); break; case OP_INERTIA_E: StackReq(1,0); t1=Pop(); Numeric(t1); o->inertia=t1.u; break; case OP_INERTIA_E16: StackReq(1,0); t1=Pop(); Numeric(t1); o->inertia=t1.u&0xFFFF; break; case OP_INERTIA_EC: StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->inertia=t1.u; break; case OP_INERTIA_EC16: StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->inertia=t1.u&0xFFFF; break; + case OP_INITARRAY: StackReq(2,0); t2=Pop(); t1=Pop(); v_init_array(t1,t2); break; case OP_INT16: StackReq(0,1); Push(NVALUE(code[ptr++])); break; case OP_INT32: StackReq(0,1); t1=UVALUE(code[ptr++]<<16,TY_NUMBER); t1.u|=code[ptr++]; Push(t1); break; case OP_INTMOVE: NoIgnore(); StackReq(1,1); t1=Pop(); Numeric(t1); Push(NVALUE(move_dir(obj,obj,t1.u))); break; case OP_INTMOVE_C: NoIgnore(); StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i==VOIDLINK) Push(NVALUE(0)); else Push(NVALUE(move_dir(obj,i,t1.u))); break; case OP_INTMOVE_D: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); move_dir(obj,obj,t1.u); break; @@ -1547,10 +1576,11 @@ case OP_SEND_CD: StackReq(4,0); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); v_send_message(obj,t1,t2,t3,t4,NVALUE(0)); break; case OP_SENDEX: StackReq(4,1); t5=Pop(); t4=Pop(); t3=Pop(); t2=Pop(); Push(v_send_self(obj,t2,t3,t4,t5)); break; case OP_SENDEX_C: StackReq(5,1); t5=Pop(); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); Push(v_send_message(obj,t1,t2,t3,t4,t5)); break; case OP_SENDEX_D: StackReq(4,0); t5=Pop(); t4=Pop(); t3=Pop(); t2=Pop(); v_send_self(obj,t2,t3,t4,t5); break; case OP_SENDEX_CD: StackReq(5,0); t5=Pop(); t4=Pop(); t3=Pop(); t2=Pop(); t1=Pop(); v_send_message(obj,t1,t2,t3,t4,t5); break; + case OP_SETARRAY: StackReq(4,0); t4=Pop(); t3=Pop(); Numeric(t3); t2=Pop(); Numeric(t2); t1=Pop(); v_set_array(t1,t2.u,t3.u,t4); break; case OP_SETINVENTORY: StackReq(3,0); t3=Pop(); t2=Pop(); t1=Pop(); v_set_inventory(t1,t2,t3); break; case OP_SHAPE: StackReq(0,1); Push(NVALUE(o->shape)); break; case OP_SHAPE_C: StackReq(1,1); Push(GetVariableOrAttributeOf(shape,NVALUE)); break; case OP_SHAPE_E: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->shape=t1.u; break; case OP_SHAPE_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->shape=t1.u; break; @@ -1936,10 +1966,11 @@ } else { traced_obj.t=TY_FOR; } } } + if(array_size) memset(array_data,0,array_size*sizeof(Value)); memcpy(globals,initglobals,sizeof(globals)); quiz_obj=NVALUE(0); gameover=0; changed=0; key_ignored=0; Index: instruc ================================================================== --- instruc +++ instruc @@ -255,13 +255,13 @@ nin -mbegin ; Arrays -Array -,GetArray +GetArray InitArray -,SetArray +SetArray ; Specials *Function *Local *Label Index: instruc.h ================================================================== --- instruc.h +++ instruc.h @@ -367,14 +367,12 @@ #define OP_IN 32948 #define OP_NIN 32949 #define OP_MBEGIN 32950 #define OP_ARRAY 32951 #define OP_GETARRAY 32952 -#define OP_GETARRAY_C 35000 #define OP_INITARRAY 32953 #define OP_SETARRAY 32954 -#define OP_SETARRAY_C 35002 #define OP_FUNCTION 32955 #define OP_LOCAL 32956 #define OP_LABEL 32957 #define OP_STRING 32958 #define OP_INT16 32959 @@ -459,11 +457,11 @@ {"FlushClass",8421516}, {"FlushObj",8487053}, {"From",8421490}, {"GLASS",8389379}, {"GLISSANT",8389419}, -{"GetArray",8487096}, +{"GetArray",8421560}, {"GetInventory",8421518}, {"HAWK",8389425}, {"HEARTBEAT",8389407}, {"HIT",8389134}, {"HITBY",8389135}, @@ -556,11 +554,11 @@ {"SUNK",8389131}, {"SW",9437189}, {"Self",8421488}, {"Send",10584231}, {"SendEx",10584232}, -{"SetArray",8487098}, +{"SetArray",8421562}, {"SetInventory",8421545}, {"Shape",8618040}, {"ShapeDir",8618063}, {"Sharp",8618062}, {"Shovable",8618064}, Index: mbtofhm.c ================================================================== --- mbtofhm.c +++ mbtofhm.c @@ -755,11 +755,11 @@ y--; x+=10; } x=op[1]|(op[2]<<8); y=op[3]|(op[4]<<8); - if(z!=-1) fprintf(fp,"{Array @%s.%s %d %d}",cname,lbl+z,x,y); + if(z!=-1) fprintf(fp," {Array @%s.%s %d %d}",cname,lbl+z,x,y); len+=4*(x*y+1); has_array=1; } st=0; break; case 126: