Index: class.c ================================================================== --- class.c +++ class.c @@ -1949,10 +1949,22 @@ cl->messages=malloc(cl->nmsg*sizeof(Uint16)); if(!cl->messages) fatal("Allocation failed\n"); for(i=0;inmsg;i++) cl->messages[i]=(su->messages[i]==0xFFFF)?0xFFFF:0x0000; } } + +static int make_dispatch_block(int cla,Class*cl,int ptr) { + int i; + cl->codes=realloc(cl->codes,0x10000*sizeof(Uint16)); + if(!cl->codes) fatal("Allocation failed\n"); + if(get_message_ptr(cla,MSG_KEY)!=0xFFFF) ParseError("Class $%s has a KEY message already\n",cl->name); + if(ptr>0xFDFE) ParseError("Out of code space\n"); + set_message_ptr(cla,MSG_KEY,ptr); + cl->codes[ptr]=OP_DISPATCH; + for(i=1;i<257;i++) cl->codes[ptr+i]=0; + return ptr+257; +} static void class_definition(int cla,sqlite3_stmt*vst) { Hash*hash=calloc(LOCAL_HASH_SIZE,sizeof(Hash)); Class*cl=classes[cla]; int ptr=0; @@ -1974,21 +1986,11 @@ } else if(Tokenf(TF_MACRO)) { ParseError("Unexpected macro token\n"); } else if(Tokenf(TF_OPEN)) { nxttok(); if(Tokenf(TF_KEY)) { - if(!disp) { - cl->codes=realloc(cl->codes,0x10000*sizeof(Uint16)); - if(!cl->codes) fatal("Allocation failed\n"); - if(get_message_ptr(cla,MSG_KEY)!=0xFFFF) ParseError("Class $%s has a KEY message already\n",cl->name); - if(ptr>0xFDFE) ParseError("Out of code space\n"); - disp=1; - set_message_ptr(cla,MSG_KEY,ptr); - cl->codes[ptr]=OP_DISPATCH; - for(i=1;i<257;i++) cl->codes[ptr+i]=0; - ptr+=257; - } + if(!disp) disp=1,ptr=make_dispatch_block(cla,cl,ptr); i=tokenv&255; cl->codes[cl->messages[MSG_KEY]+i]=ptr; if(cl->cflags&CF_INPUT) { nxttok(); if(tokent!=TF_NAME || tokenv!=OP_IGNOREKEY) keymask[i>>3]|=1<<(i&7); @@ -2072,15 +2074,45 @@ case OP_COLLISIONLAYERS: cl->collisionLayers=i=class_def_misc(); if(i&~255) ParseError("CollisionLayers out of range\n"); break; case OP_OTHERS: - if(!disp) ParseError("Others block without key dispatch block\n"); + if(!disp) disp=1,ptr=make_dispatch_block(cla,cl,ptr); if(!(cl->cflags&CF_INPUT)) ParseError("Others block without Input flag\n"); cl->codes[cl->messages[MSG_KEY]+256]=ptr; ptr=parse_instructions(cla,ptr,hash,compat); break; + case OP_ROOK: + if(!disp) disp=1,ptr=make_dispatch_block(cla,cl,ptr); + if(ptr>=0xFFED) ParseError("Out of code space\n"); + for(i=37;i<=40;i++) { + cl->codes[cl->messages[MSG_KEY]+i]=ptr; + if(cl->cflags&CF_INPUT) keymask[i>>3]|=1<<(i&7); + } + cl->codes[ptr++]=OP_QUEEN; + ptr=parse_instructions(cla,ptr,hash,compat); + break; + case OP_BISHOP: + if(!disp) disp=1,ptr=make_dispatch_block(cla,cl,ptr); + if(ptr>=0xFFED) ParseError("Out of code space\n"); + for(i=33;i<=36;i++) { + cl->codes[cl->messages[MSG_KEY]+i]=ptr; + if(cl->cflags&CF_INPUT) keymask[i>>3]|=1<<(i&7); + } + cl->codes[ptr++]=OP_QUEEN; + ptr=parse_instructions(cla,ptr,hash,compat); + break; + case OP_QUEEN: + if(!disp) disp=1,ptr=make_dispatch_block(cla,cl,ptr); + if(ptr>=0xFFED) ParseError("Out of code space\n"); + for(i=33;i<=40;i++) { + cl->codes[cl->messages[MSG_KEY]+i]=ptr; + if(cl->cflags&CF_INPUT) keymask[i>>3]|=1<<(i&7); + } + cl->codes[ptr++]=OP_QUEEN; + ptr=parse_instructions(cla,ptr,hash,compat); + break; case 0x0200 ... 0x02FF: set_message_ptr(cla,tokenv&255,ptr); ptr=parse_instructions(cla,ptr,hash,compat); break; case 0xC000 ... 0xFFFF: Index: class.doc ================================================================== --- class.doc +++ class.doc @@ -384,10 +384,15 @@ Define the Arrivals variable for this class. This is twenty-five numbers each of which is either zero or one. They are meant to be on five lines of five numbers each, making a 5x5 matrix, where the centre means this object's location. +(Bishop ) + Same as four key dispatch blocks: 'PGUP, 'PGDN, 'HOME, and 'END; the + corresponding direction will be pushed to the stack before the code + will be executed. + Bizarro Means that objects of this class created using the Create instruction will be created in the bizarro world by default. (This has no effect on objects placed in the level editor.) @@ -486,25 +491,31 @@ (Misc7 ) Define the Misc7 variable for this class; see Misc4 above for details. (Others ) - This block must be preceded by another key dispatch block (although not - necessarily directly preceded), and it is only allowed in classes with - the Input flag. If no key dispatch block matches and it is not a key - which is implicitly ignored, and Arg3 is both zero, then it will execute - this block instead. + This block is only allowed in classes with the Input flag. If no key + dispatch block matches and it is not a key which is implicitly ignored, + and Arg3 is both zero, then it will execute this block instead. Player Set the Player flag for this class. +(Queen ) + Combines the effects of the (Rook) and (Queen) blocks. + Quiz If specified, the internal variables of objects of this class cannot normally be examined by the player. However, the player can override this definition at run time; you cannot rely on it. Class codes cannot read the value of this flag. +(Rook ) + Same as four key dispatch blocks: 'UP, 'LEFT, 'DOWN, and 'RIGHT; the + corresponding direction will be pushed to the stack before the code + will be executed. + (Shape ) Define the shape of this object on all four sides, where 0 means flat, 1 means slanted to left, 2 means slanted to right, and 3 means slanted both left and right. Index: default.heromeshrc ================================================================== --- default.heromeshrc +++ default.heromeshrc @@ -1,10 +1,10 @@ ! Hero Mesh configuration settings ?.screenWidth: 800 ?.screenHeight: 600 ?.imageSize: 24 -?.traceAll: true +?.traceAll: false ?.showInventory: 0 ?.maxTrigger: 32767 ?.pasteCommand: xclip -o ?.codepage: /home/user/freeheromesh/codepage.har Index: exec.c ================================================================== --- exec.c +++ exec.c @@ -3093,10 +3093,11 @@ case OP_QM: StackReq(1,1); t1=Pop(); NotSound(t1); if(t1.t==TY_MESSAGE) Push(NVALUE(1)); else Push(NVALUE(0)); break; case OP_QN: StackReq(1,1); t1=Pop(); NotSound(t1); if(t1.t==TY_NUMBER) Push(NVALUE(1)); else Push(NVALUE(0)); break; case OP_QO: StackReq(1,1); t1=Pop(); NotSound(t1); if(t1.t>TY_MAXTYPE) Push(NVALUE(1)); else Push(NVALUE(0)); break; case OP_QOZ: StackReq(1,1); t1=Pop(); NotSound(t1); if(t1.t>TY_MAXTYPE || (t1.t==TY_NUMBER && !t1.u)) Push(NVALUE(1)); else Push(NVALUE(0)); break; case OP_QS: StackReq(1,1); t1=Pop(); NotSound(t1); if(t1.t==TY_STRING || t1.t==TY_LEVELSTRING) Push(NVALUE(1)); else Push(NVALUE(0)); break; + case OP_QUEEN: StackReq(0,1); Numeric(msgvars.arg1); i="\x06\x01\x07\x05\x03\x04\x02\x00"[msgvars.arg1.u&7]; Push(NVALUE(i)); break; case OP_REL: StackReq(1,1); t1=Pop(); Numeric(t1); i=resolve_dir(obj,t1.u); Push(NVALUE(i)); break; case OP_REL_C: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); i=v_object(t1); i=(i==VOIDLINK?t2.u:resolve_dir(i,t2.u)); Push(NVALUE(i)); break; case OP_RET: return; case OP_ROT: StackReq(3,3); t3=Pop(); t2=Pop(); t1=Pop(); Push(t2); Push(t3); Push(t1); break; case OP_ROTBACK: StackReq(3,3); t3=Pop(); t2=Pop(); t1=Pop(); Push(t3); Push(t1); Push(t2); break;