Free Hero Mesh

Check-in [3a5d5440cc]
Login
This is a mirror of the main repository for Free Hero Mesh. New tickets and changes will not be accepted at this mirror.
Overview
Comment:Implement (Rook), (Bishop), and (Queen) blocks in class definition blocks.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 3a5d5440cc1eff827fda23dd3c93f42e46a18a00
User & Date: user on 2022-04-24 20:33:00
Other Links: manifest | tags
Context
2022-04-26
18:27
Add the Walkable instruction. check-in: 4436b9f0d2 user: user tags: trunk
2022-04-24
20:33
Implement (Rook), (Bishop), and (Queen) blocks in class definition blocks. check-in: 3a5d5440cc user: user tags: trunk
2022-04-22
20:11
Some corrections to parsing the (Order) block; the runtime handling still does not quite work properly yet check-in: 345563f394 user: user tags: trunk
Changes

Modified class.c from [8147a9749f] to [17e9f0f3a2].

1947
1948
1949
1950
1951
1952
1953












1954
1955
1956
1957
1958
1959
1960
  cl->collisionLayers|=su->collisionLayers;
  if(cl->nmsg=su->nmsg) {
    cl->messages=malloc(cl->nmsg*sizeof(Uint16));
    if(!cl->messages) fatal("Allocation failed\n");
    for(i=0;i<cl->nmsg;i++) cl->messages[i]=(su->messages[i]==0xFFFF)?0xFFFF:0x0000;
  }
}













static void class_definition(int cla,sqlite3_stmt*vst) {
  Hash*hash=calloc(LOCAL_HASH_SIZE,sizeof(Hash));
  Class*cl=classes[cla];
  int ptr=0;
  int compat=0;
  int i;







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







1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
  cl->collisionLayers|=su->collisionLayers;
  if(cl->nmsg=su->nmsg) {
    cl->messages=malloc(cl->nmsg*sizeof(Uint16));
    if(!cl->messages) fatal("Allocation failed\n");
    for(i=0;i<cl->nmsg;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;
  int compat=0;
  int i;
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
    if(Tokenf(TF_EOF)) {
      ParseError("Unexpected end of file\n");
    } 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;
        }
        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);
          pushback=1;
        }







|
<
<
<
<
<
<
<
<
<
<







1984
1985
1986
1987
1988
1989
1990
1991










1992
1993
1994
1995
1996
1997
1998
    if(Tokenf(TF_EOF)) {
      ParseError("Unexpected end of file\n");
    } else if(Tokenf(TF_MACRO)) {
      ParseError("Unexpected macro token\n");
    } else if(Tokenf(TF_OPEN)) {
      nxttok();
      if(Tokenf(TF_KEY)) {
        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);
          pushback=1;
        }
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081






























2082
2083
2084
2085
2086
2087
2088
            ptr=parse_instructions(cla,ptr,hash,compat);
            break;
          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(!(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 0x0200 ... 0x02FF:
            set_message_ptr(cla,tokenv&255,ptr);
            ptr=parse_instructions(cla,ptr,hash,compat);
            break;
          case 0xC000 ... 0xFFFF:
            set_message_ptr(cla,tokenv+256-0xC000,ptr);
            ptr=parse_instructions(cla,ptr,hash,compat);







|




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







2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
            ptr=parse_instructions(cla,ptr,hash,compat);
            break;
          case OP_COLLISIONLAYERS:
            cl->collisionLayers=i=class_def_misc();
            if(i&~255) ParseError("CollisionLayers out of range\n");
            break;
          case OP_OTHERS:
            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:
            set_message_ptr(cla,tokenv+256-0xC000,ptr);
            ptr=parse_instructions(cla,ptr,hash,compat);

Modified class.doc from [817305dd66] to [706c43e646].

382
383
384
385
386
387
388





389
390
391
392
393
394
395

(Arrivals <numbers...>)
  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.






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

(Climb <number>)
  Define the Climb variable for this class.







>
>
>
>
>







382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400

(Arrivals <numbers...>)
  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 <code...>)
  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.)

(Climb <number>)
  Define the Climb variable for this class.
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499



500
501
502
503
504
505





506
507
508
509
510
511
512
(Misc6 <numbers...>)
  Define the Misc6 variable for this class; see Misc4 above for details.

(Misc7 <numbers...>)
  Define the Misc7 variable for this class; see Misc4 above for details.

(Others <code...>)
  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.

Player
  Set the Player flag for this class.




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.






(Shape <number>)
  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.

(Shape <pairs...>)
  Define the shape of this object per side, similar to the (Hard) block.







<
|
|
|
<




>
>
>






>
>
>
>
>







489
490
491
492
493
494
495

496
497
498

499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
(Misc6 <numbers...>)
  Define the Misc6 variable for this class; see Misc4 above for details.

(Misc7 <numbers...>)
  Define the Misc7 variable for this class; see Misc4 above for details.

(Others <code...>)

  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 <code...>)
  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 <code...>)
  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 <number>)
  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.

(Shape <pairs...>)
  Define the shape of this object per side, similar to the (Hard) block.

Modified default.heromeshrc from [eab9494892] to [8a1fa84fa5].

1
2
3
4
5
6
7
8
9
10
11
12
! Hero Mesh configuration settings
?.screenWidth: 800
?.screenHeight: 600
?.imageSize: 24
?.traceAll: true
?.showInventory: 0
?.maxTrigger: 32767
?.pasteCommand: xclip -o
?.codepage: /home/user/freeheromesh/codepage.har

! Game inputs
?.gameKey.A: 'A




|







1
2
3
4
5
6
7
8
9
10
11
12
! Hero Mesh configuration settings
?.screenWidth: 800
?.screenHeight: 600
?.imageSize: 24
?.traceAll: false
?.showInventory: 0
?.maxTrigger: 32767
?.pasteCommand: xclip -o
?.codepage: /home/user/freeheromesh/codepage.har

! Game inputs
?.gameKey.A: 'A

Modified exec.c from [b0f7b5bc62] to [ee9e164ba7].

3091
3092
3093
3094
3095
3096
3097

3098
3099
3100
3101
3102
3103
3104
    case OP_QC: StackReq(1,1); t1=Pop(); NotSound(t1); if(t1.t==TY_CLASS) Push(NVALUE(1)); else Push(NVALUE(0)); break;
    case OP_QCZ: StackReq(1,1); t1=Pop(); NotSound(t1); if(t1.t==TY_CLASS || (t1.t==TY_NUMBER && !t1.u)) Push(NVALUE(1)); else Push(NVALUE(0)); break;
    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_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;
    case OP_RSH: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t2.u&~31?0:t1.u>>t2.u)); break;
    case OP_RSH_C: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t2.u&~31?(t1.s<0?-1:0):t1.s>>t2.u)); break;







>







3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
    case OP_QC: StackReq(1,1); t1=Pop(); NotSound(t1); if(t1.t==TY_CLASS) Push(NVALUE(1)); else Push(NVALUE(0)); break;
    case OP_QCZ: StackReq(1,1); t1=Pop(); NotSound(t1); if(t1.t==TY_CLASS || (t1.t==TY_NUMBER && !t1.u)) Push(NVALUE(1)); else Push(NVALUE(0)); break;
    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;
    case OP_RSH: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t2.u&~31?0:t1.u>>t2.u)); break;
    case OP_RSH_C: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t2.u&~31?(t1.s<0?-1:0):t1.s>>t2.u)); break;