Free Hero Mesh

Check-in [51526b8cd6]
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:Add the (Pc) block (counting pattern block).
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 51526b8cd66ddf0e5eb8cdaf6e41eccc0adba0fa
User & Date: user on 2023-08-28 19:02:25
Other Links: manifest | tags
Context
2023-08-28
21:46
Add misc/compare/zzt_megazeux.doc check-in: 7e1a7ee925 user: user tags: trunk
19:02
Add the (Pc) block (counting pattern block). check-in: 51526b8cd6 user: user tags: trunk
04:25
Improve the file of comparison of MESH:Hero, and also add file comparing with PuzzleScript. check-in: b2164c4f63 user: user tags: trunk
Changes

Modified class.c from [53fa966b10] to [04b2a8af6c].

1765
1766
1767
1768
1769
1770
1771
1772
1773
1774



1775
1776
1777
1778
1779
1780
1781
1765
1766
1767
1768
1769
1770
1771



1772
1773
1774
1775
1776
1777
1778
1779
1780
1781







-
-
-
+
+
+







        case OP_POPUP:
          nxttok();
          if(tokent!=TF_INT || tokenv<0 || tokenv>32) ParseError("Expected number from 0 to 32");
          if(tokenv) AddInst2(OP_POPUPARGS,tokenv); else AddInst(OP_POPUP);
          nxttok();
          if(tokent!=TF_CLOSE) ParseError("Unterminated (PopUp)\n");
          break;
        case OP_PATTERN: case OP_PATTERNS:
        case OP_PATTERN_C: case OP_PATTERNS_C:
        case OP_PATTERN_E: case OP_PATTERNS_E:
        case OP_PATTERN: case OP_PATTERNS: case OP_PATTERNC:
        case OP_PATTERN_C: case OP_PATTERNS_C: case OP_PATTERNC_C:
        case OP_PATTERN_E: case OP_PATTERNS_E: case OP_PATTERNC_E:
          AddInst(tokenv);
          cl->codes[ptr]=peep=parse_pattern(cla,ptr+1,hash);
          ptr=peep;
          break;
        case OP_BROADCAST:
          nxttok();
          if(Tokenf(TF_MACRO) || !Tokenf(TF_NAME) || tokenv<0x4000 || tokenv>0x7FFF) ParseError("Class name expected\n");

Modified class.doc from [ccc3c5d04b] to [9a7008d58d].

2835
2836
2837
2838
2839
2840
2841










2842
2843
2844
2845
2846
2847
2848
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858







+
+
+
+
+
+
+
+
+
+








,P*
  Like ,P but push all found objects, or pushes nothing if not found.

=P*
  Like =P but push all found objects, or pushes nothing if not found.

Pc
  Like P* but pushes only the number of matches (zero if none are found),
  rather than all of the objects.

,Pc
  Like ,P* but pushes only the number of matches.

=Pc
  Like =P* but pushes only the number of matches.

Inside the pattern, the following commands are allowed (although the
commands that push stuff to the stack should not be used in the patterns
with P* or ,P* or =P*):

<class>
  Match an object of the specified class.

2871
2872
2873
2874
2875
2876
2877
2878


2879
2880
2881


2882
2883
2884
2885
2886
2887
2888
2881
2882
2883
2884
2885
2886
2887

2888
2889
2890
2891

2892
2893
2894
2895
2896
2897
2898
2899
2900







-
+
+


-
+
+







<userflag>
  Match an object with the specified flag.

,<userflag>
  Fail if there are any objects having the specified flag here.

+
  Push the matched object to the stack.
  Push the matched object to the stack. (For the counting modes, instead
  unconditionally increments the total.)

-
  Push zero to the stack.
  Push zero to the stack. (For the counting modes, instead unconditionally
  decrements the total.)

*
  Update the current choice point with the location and direction.

/
  Succeeds only if the pattern prior to this command succeeds but the
  pattern after this command (which still has the same state as the

Modified exec.c from [dbcc43fd0c] to [f9d077868e].

2481
2482
2483
2484
2485
2486
2487

2488
2489
2490
2491
2492
2493

2494
2495
2496
2497
2498
2499
2500
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493

2494
2495
2496
2497
2498
2499
2500
2501







+





-
+







  Uint8 x=objects[obj]->x;
  Uint8 y=objects[obj]->y;
  Uint8 d=objects[obj]->dir;
  Uint32 un=VOIDLINK;
  Uint32 n=VOIDLINK;
  Uint32 m;
  Uint16 g;
  Uint32 total=0;
  Value v;
  ChoicePoint cp[MAXCHOICE];
  Uint8 cpi=0;
  Uint16 ccl=objects[obj]->class;
  Uint8 cim=objects[obj]->image;
  if(!x) return VOIDLINK;
  if(!x) goto stop;
  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;
2536
2537
2538
2539
2540
2541
2542
2543

2544
2545
2546
2547
2548
2549
2550
2551
2552
2553

2554
2555
2556
2557
2558
2559
2560
2537
2538
2539
2540
2541
2542
2543

2544
2545
2546
2547
2548
2549
2550
2551
2552
2553

2554
2555
2556
2557
2558
2559
2560
2561







-
+









-
+







          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;
          if(!x) goto stop;
        } else {
          Throw("Type mismatch");
        }
        m=objects[m]->up;
      }
      break;
    case OP_ADD:
      if(vstackptr>=VSTACKSIZE-1) Throw("Stack overflow");
      m=(n==VOIDLINK?obj_bottom_at(x,y):n);
      Push(OVALUE(m));
      if(all==2) total++; else Push(OVALUE(m));
      break;
    case OP_AGAIN:
      if(cp[cpi].ptr!=ptr+1) {
        if(cpi>=MAXCHOICE-1) Throw("Choice overflow");
        cpi++;
        cp[cpi].ptr=ptr+1;
      }
2628
2629
2630
2631
2632
2633
2634
2635

2636
2637
2638
2639
2640
2641
2642
2629
2630
2631
2632
2633
2634
2635

2636
2637
2638
2639
2640
2641
2642
2643







-
+







        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;
        if(!x) goto stop;
      } 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;
2670
2671
2672
2673
2674
2675
2676
2677

2678
2679
2680
2681
2682
2683
2684
2671
2672
2673
2674
2675
2676
2677

2678
2679
2680
2681
2682
2683
2684
2685







-
+







    case OP_LOC:
      if(vstackptr>=VSTACKSIZE-2) Throw("Stack overflow");
      Push(NVALUE(x));
      Push(NVALUE(y));
      break;
    case OP_MARK:
      if(vstackptr>=VSTACKSIZE-1) Throw("Stack overflow");
      Push(UVALUE(0,TY_MARK));
      if(all!=2) Push(UVALUE(0,TY_MARK));
      break;
    case OP_MUL:
      cp[cpi].x=x;
      cp[cpi].y=y;
      cp[cpi].dir=d;
      break;
    case OP_NEXT:
2718
2719
2720
2721
2722
2723
2724

2725





2726
2727
2728
2729
2730
2731
2732
2719
2720
2721
2722
2723
2724
2725
2726

2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738







+
-
+
+
+
+
+







      cp[cpi-5].dir=6;
      cp[cpi-6].dir=7;
      break;
    case OP_RET:
      if(all) {
        if(vstackptr>=VSTACKSIZE-1) Throw("Stack overflow");
        if(n==VOIDLINK) n=obj_bottom_at(x,y);
        if(all!=2) {
        Push(OVALUE(n));
          Push(OVALUE(n));
        } else {
          if(un==VOIDLINK && n!=VOIDLINK) total++;
          else if(un!=VOIDLINK) return total+(n==VOIDLINK?1:0);
        }
        goto fail;
      } else if(un==VOIDLINK) {
        return n==VOIDLINK?obj_bottom_at(x,y):n;
      } else {
        return VOIDLINK;
      }
      break;
2741
2742
2743
2744
2745
2746
2747
2748

2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769

2770
2771
2772
2773
2774
2775
2776


2777
2778
2779
2780
2781

2782
2783
2784
2785
2786

2787
2788
2789

2790
2791
2792
2793
2794
2795
2796
2747
2748
2749
2750
2751
2752
2753

2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774

2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798

2799
2800
2801
2802
2803
2804
2805
2806







-
+




















-
+







+
+





+





+


-
+







      cp[cpi-1]=cp[cpi-2]=cp[cpi];
      cp[cpi].dir=2;
      cp[cpi-1].dir=4;
      cp[cpi-2].dir=6;
      break;
    case OP_SUB:
      if(vstackptr>=VSTACKSIZE-1) Throw("Stack overflow");
      Push(NVALUE(0));
      if(all==2) total--; else Push(NVALUE(0));
      break;
    case OP_THEN:
      // This opcode does nothing
      break;
    case OP_TRACE:
      if(main_options['t']) {
        printf("ptr=%d cpi=%d x=%d y=%d dir=%d obj=%lu ",ptr,cpi,x,y,d,(long)n);
        printf("[ptr=%d x=%d y=%d dir=%d]\n",cp[cpi].ptr,cp[cpi].x,cp[cpi].y,cp[cpi].dir);
      }
      break;
    default:
      fprintf(stderr,"Unrecognized opcode 0x%04X at 0x%04X in pattern\n",code[ptr-1],ptr-1);
      Throw("Internal error: Unimplemented opcode in pattern");
  }
  goto again;
  fail:
  if(!all) {
    if(vstackptr<cp->depth) Throw("Stack underflow in pattern matching");
    vstackptr=cp[cpi].depth;
  }
  if(!cpi) return un;
  if(!cpi) return (all==2?total+(un==VOIDLINK?0:1):un);
  x=cp[cpi].x;
  y=cp[cpi].y;
  d=cp[cpi].dir;
  ptr=cp[cpi].ptr;
  n=VOIDLINK;
  cpi--;
  goto again;
  stop:
  return (all==2?total:VOIDLINK);
}

static Uint32 v_pattern_anywhere(Uint16*code,int ptr,char all) {
  int i;
  Uint32 n;
  Uint32 t=0;
  for(i=0;i<pfheight*64;i++) {
    n=playfield[i];
    if(n!=VOIDLINK) {
      n=v_pattern(code,ptr,n,all);
      if(n!=VOIDLINK && !all) return n;
      if(all==2) t+=n;
    }
  }
  return VOIDLINK;
  return (all==2?t:VOIDLINK);
}

static int v_case(Uint16*code,int ptr,Value v) {
  int n=(code[ptr]&255)+1;
  int t0=(code[ptr]>>12)&15;
  int t1=(code[ptr]>>8)&15;
  int i,j,v0,v1;
3498
3499
3500
3501
3502
3503
3504



3505
3506
3507
3508
3509
3510
3511
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524







+
+
+







    case OP_OVER: StackReq(2,3); t2=Pop(); t1=Pop(); Push(t1); Push(t2); Push(t1); break;
    case OP_PATTERN: StackReq(0,1); i=code[ptr++]; j=v_pattern(code,ptr,obj,0); ptr=i; Push(OVALUE(j)); break;
    case OP_PATTERN_C: StackReq(1,1); i=code[ptr++]; j=v_object(Pop()); if(j!=VOIDLINK) j=v_pattern(code,ptr,j,0); ptr=i; Push(OVALUE(j)); break;
    case OP_PATTERN_E: StackReq(0,1); i=code[ptr++]; j=v_pattern_anywhere(code,ptr,0); ptr=i; Push(OVALUE(j)); break;
    case OP_PATTERNS: StackReq(0,1); i=code[ptr++]; v_pattern(code,ptr,obj,1); ptr=i; break;
    case OP_PATTERNS_C: StackReq(1,1); i=code[ptr++]; j=v_object(Pop()); if(j!=VOIDLINK) v_pattern(code,ptr,j,1); ptr=i; break;
    case OP_PATTERNS_E: StackReq(0,1); i=code[ptr++]; v_pattern_anywhere(code,ptr,1); ptr=i; break;
    case OP_PATTERNC: StackReq(0,1); i=code[ptr++]; j=v_pattern(code,ptr,obj,2); ptr=i; Push(NVALUE(j)); break;
    case OP_PATTERNC_C: StackReq(1,1); i=code[ptr++]; j=v_object(Pop()); if(j!=VOIDLINK) j=v_pattern(code,ptr,j,2); else j=0; Push(NVALUE(j)); ptr=i; break;
    case OP_PATTERNC_E: StackReq(0,1); i=code[ptr++]; j=v_pattern_anywhere(code,ptr,2); ptr=i; Push(NVALUE(j)); break;
    case OP_PICK: StackReq(0,1); t1=Pop(); Numeric(t1); if(t1.u>=vstackptr) Throw("Stack index out of range"); t1=vstack[vstackptr-t1.u-1]; Push(t1); break;
    case OP_PLAYER: StackReq(0,1); if(classes[o->class]->cflags&CF_PLAYER) Push(NVALUE(1)); else Push(NVALUE(0)); break;
    case OP_PLAYER_C: StackReq(1,1); GetClassFlagOf(CF_PLAYER); break;
    case OP_PLUSMOVE: StackReq(1,1); t1=Pop(); Numeric(t1); i=defer_move(obj,t1.u,1); Push(NVALUE(i)); break;
    case OP_PLUSMOVE_C: StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); i=defer_move(i,t1.u,1); Push(NVALUE(i)); break;
    case OP_PLUSMOVE_D: StackReq(1,0); t1=Pop(); Numeric(t1); defer_move(obj,t1.u,1); break;
    case OP_PLUSMOVE_CD: StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); defer_move(i,t1.u,1); break;

Modified instruc from [f96da63b9c] to [43b3c154cd].

330
331
332
333
334
335
336

337
338
339
340
341
342
343
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344







+







ArraySlice
CopyArray
DotProduct

; Pattern matching
-,=Pattern "P"
-,=PatternS "P*"
-,=PatternC "Pc"
-Rook
-Bishop
-Queen
-cut

; Bizarro world
,=Bizarro

Modified instruc.h from [37c1270125] to [de573b2b32].

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
524
525






















526
527
528
529
530
531
532
533
534
535
536
537
538
539

540
541
542
543
544
545
546
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
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542

543
544
545
546
547
548
549
550







+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+













-
+







#define OP_PATTERN_C 35069
#define OP_PATTERN_E 37117
#define OP_PATTERN_EC 39165
#define OP_PATTERNS 33022
#define OP_PATTERNS_C 35070
#define OP_PATTERNS_E 37118
#define OP_PATTERNS_EC 39166
#define OP_PATTERNC 33023
#define OP_PATTERNC_C 35071
#define OP_PATTERNC_E 37119
#define OP_PATTERNC_EC 39167
#define OP_ROOK 33023
#define OP_BISHOP 33024
#define OP_QUEEN 33025
#define OP_CUT 33026
#define OP_BIZARRO 33027
#define OP_BIZARRO_C 35075
#define OP_BIZARRO_E 37123
#define OP_BIZARRO_EC 39171
#define OP_BIZARROSWAP 33028
#define OP_BIZARROSWAP_D 41220
#define OP_SWAPWORLD 33029
#define OP_ABSTRACT 33030
#define OP_SUPER 33031
#define OP_SUPER_C 35079
#define OP_FUNCTION 33032
#define OP_LOCAL 33033
#define OP_LABEL 33034
#define OP_STRING 33035
#define OP_INT16 33036
#define OP_INT32 33037
#define OP_DISPATCH 33038
#define OP_USERFLAG 33039
#define OP_ROOK 33024
#define OP_BISHOP 33025
#define OP_QUEEN 33026
#define OP_CUT 33027
#define OP_BIZARRO 33028
#define OP_BIZARRO_C 35076
#define OP_BIZARRO_E 37124
#define OP_BIZARRO_EC 39172
#define OP_BIZARROSWAP 33029
#define OP_BIZARROSWAP_D 41221
#define OP_SWAPWORLD 33030
#define OP_ABSTRACT 33031
#define OP_SUPER 33032
#define OP_SUPER_C 35080
#define OP_FUNCTION 33033
#define OP_LOCAL 33034
#define OP_LABEL 33035
#define OP_STRING 33036
#define OP_INT16 33037
#define OP_INT32 33038
#define OP_DISPATCH 33039
#define OP_USERFLAG 33040
#ifdef HEROMESH_CLASS
static const Op_Names op_names[]={
{"*",8486945},
{"+",8421407},
{"+Move",10584262},
{"-",8421408},
{"-Move",10584263},
{"-rot",8421382},
{".",10518528},
{"/",8486946},
{"/mod",8486948},
{"ANHH",8389393},
{"ARRIVED",8389124},
{"Abstract",8683782},
{"Abstract",8683783},
{"Animate",8552604},
{"AnimateDead",8552605},
{"Arg1",8552580},
{"Arg2",8552581},
{"Arg3",8552582},
{"Array",8683765},
{"ArrayCell",8487161},
557
558
559
560
561
562
563
564
565
566



567
568
569
570
571
572
573
561
562
563
564
565
566
567



568
569
570
571
572
573
574
575
576
577







-
-
-
+
+
+







{"BOOOM",8389409},
{"BOUNCE",8389414},
{"BRRREEET",8389395},
{"BRRRT",8389394},
{"BUZZER",8389419},
{"BWEEP",8389396},
{"Background",8683662},
{"Bishop",8683776},
{"Bizarro",8618243},
{"BizarroSwap",10518788},
{"Bishop",8683777},
{"Bizarro",8618244},
{"BizarroSwap",10518789},
{"Broadcast",10518687},
{"BroadcastAnd",8421536},
{"BroadcastAndEx",8421537},
{"BroadcastEx",10518691},
{"BroadcastList",8421540},
{"BroadcastListEx",8421541},
{"BroadcastSum",8421542},
720
721
722
723
724
725
726

727
728
729

730
731
732
733
734
735
736
737
738
739

740
741
742
743
744
745
746
724
725
726
727
728
729
730
731
732
733

734
735
736
737
738
739
740
741
742
743

744
745
746
747
748
749
750
751







+


-
+









-
+







{"Others",8683674},
{"P",8880381},
{"P*",8880382},
{"PLAYERMOVING",8389133},
{"POSTINIT",8389138},
{"POUR",8389377},
{"POWER",8389386},
{"Pc",8880383},
{"Player",8487037},
{"PopUp",8421587},
{"Queen",8683777},
{"Queen",8683778},
{"Quiz",8487061},
{"R",9437198},
{"RATCHET1",8389417},
{"RATCHET2",8389411},
{"RATTLE",8389402},
{"RB",9437197},
{"RF",9437199},
{"Rel",8487125},
{"Replace",10518742},
{"Rook",8683775},
{"Rook",8683776},
{"S",9437190},
{"SE",9437191},
{"SMALL_POP",8389388},
{"SPLASH",8389376},
{"STEAM",8389423},
{"STOP",8388608},
{"SUBS",8683675},
755
756
757
758
759
760
761
762
763


764
765
766
767
768
769
770
760
761
762
763
764
765
766


767
768
769
770
771
772
773
774
775







-
-
+
+







{"Shape",8618054},
{"ShapeDir",8618077},
{"Sharp",8618076},
{"Shovable",8618078},
{"Sound",8421595},
{"Stealthy",8618103},
{"Strength",9142361},
{"Super",8487175},
{"SwapWorld",8421637},
{"Super",8487176},
{"SwapWorld",8421638},
{"Sweep",8421596},
{"SweepEx",8421597},
{"Synchronize",8421598},
{"TAHTASHH",8389408},
{"THMP_thmp",8389404},
{"THWIT",8389384},
{"TICK",8389390},
843
844
845
846
847
848
849
850

851
852
853
854
855
856
857
848
849
850
851
852
853
854

855
856
857
858
859
860
861
862







-
+







{"bor",8421419},
{"bxor",8421420},
{"c?",8421436},
{"case",8683544},
{"chain",8421545},
{"clear",8421619},
{"count",8421618},
{"cut",8683778},
{"cut",8683779},
{"cz?",8421437},
{"dup",8421377},
{"else",8683530},
{"eq",8421427},
{"eq2",8421428},
{"exec",8486942},
{"flip",8421617},
898
899
900
901
902
903
904
905

906
903
904
905
906
907
908
909

910
911







-
+

{"then",8683531},
{"tmark",8421613},
{"tuck",8421380},
{"uniq",8421620},
{"until",8749070},
{"while",8749071},
};
#define N_OP_NAMES 376
#define N_OP_NAMES 377
#endif

Modified misc/compare/puzzlescript.doc from [f03e7b59e9] to [00d29c2af9].

327
328
329
330
331
332
333
334
335
336



337
338
339
327
328
329
330
331
332
333



334
335
336
337
338
339







-
-
-
+
+
+



* Win conditions: You cannot currently define them in their own block;
you must use the WinLevel command. (In future, a separate block to allow
defining winning conditions like PuzzleScript might be implemented, but
currently it is not implemented.)

Also, some of the features listed in the GitHub issue tracker for
PuzzleScript and PuzzleScript+ are already implemented in Free Hero Mesh,
although some are planned to be implemented, are unnecessary (for whatever
reasons), or are deliberately not implemented. There are also many features
that PuzzleScript does not have.
although some are planned to be implemented, or are unnecessary (for
whatever reasons), or are deliberately not implemented. There are also many
features that PuzzleScript does not have.

Certainly further improvements are also possible, too.