Free Hero Mesh

Check-in [d950a4244a]
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 move list deletion/insertion mode.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d950a4244a09b76e4af35c842863da99afca4fcb
User & Date: user on 2021-10-23 05:43:55
Other Links: manifest | tags
Context
2021-10-24
07:41
Disallow inserting/deleting moves during the solution replay check-in: 730d600d55 user: user tags: trunk
2021-10-23
05:43
Implement move list deletion/insertion mode. check-in: d950a4244a user: user tags: trunk
2021-10-22
21:23
Improve ARCHITECTURE and internals.doc (documentation only) check-in: 1967c110f3 user: user tags: trunk
Changes

Modified bindings.doc from [8c762c044c] to [aede3478d9].

62
63
64
65
66
67
68







69
70
71
72
73
74
75

'^<'
  Rewind to mark.

'^>'
  Replay to mark.








'^I'
  Toggle the inventory/move-list display.

'^M'
  Set the replay mark position.

'^S'







>
>
>
>
>
>
>







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

'^<'
  Rewind to mark.

'^>'
  Replay to mark.

'^-'
  Delete one move.

'^+'
  Toggle insertion mode. Insertion mode is automatically reset when
  restarting a level or when accessing a different level.

'^I'
  Toggle the inventory/move-list display.

'^M'
  Set the replay mark position.

'^S'

Modified default.heromeshrc from [663dcd3e34] to [030154443a].

129
130
131
132
133
134
135


136
137
138
139
140
141
142
?.gameKey.shift.f8: select 'ml',solution_move_list(1);
?.gameKey.f9: select 'lo',xy(o.x,o.y) from objects o,classes c on(o.class=c.id) where c.player;
?.gameKey.tab: ^I
?.gameKey.alt.G: ^g
?.gameKey.alt.P: ^p
?.gameKey.alt.leftbracket: select 'rs',-5;
?.gameKey.alt.rightbracket: select 'rs',+5;



! Editor key bindings
?.editKey.1: select 'mr',0;
?.editKey.2: select 'mr',1;
?.editKey.3: select 'mr',2;
?.editKey.4: select 'mr',3;
?.editKey.5: select 'mr',4;







>
>







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
?.gameKey.shift.f8: select 'ml',solution_move_list(1);
?.gameKey.f9: select 'lo',xy(o.x,o.y) from objects o,classes c on(o.class=c.id) where c.player;
?.gameKey.tab: ^I
?.gameKey.alt.G: ^g
?.gameKey.alt.P: ^p
?.gameKey.alt.leftbracket: select 'rs',-5;
?.gameKey.alt.rightbracket: select 'rs',+5;
?.gameKey.delete: ^-
?.gameKey.insert: ^+

! Editor key bindings
?.editKey.1: select 'mr',0;
?.editKey.2: select 'mr',1;
?.editKey.3: select 'mr',2;
?.editKey.4: select 'mr',3;
?.editKey.5: select 'mr',4;

Modified game.c from [25a4dc3668] to [75a646347e].

28
29
30
31
32
33
34

35
36
37
38
39
40
41
static Uint8*inputs;
static int inputs_size,inputs_count;
static Uint8 side_mode=255;
static Uint8 should_record_solution;
static Uint8 replay_speed;
static Uint8 replay_time;
static Uint8 solved;


static void record_solution(void);

static void setup_game(void) {
  const char*v;
  optionquery[1]=Q_showInventory;
  v=xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"";







>







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
static Uint8*inputs;
static int inputs_size,inputs_count;
static Uint8 side_mode=255;
static Uint8 should_record_solution;
static Uint8 replay_speed;
static Uint8 replay_time;
static Uint8 solved;
static Uint8 inserting,saved_inserting;

static void record_solution(void);

static void setup_game(void) {
  const char*v;
  optionquery[1]=Q_showInventory;
  v=xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"";
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
    snprintf(buf,8,"%5d",replay_count);
    draw_text(8,screen->h-8,buf,0xF0,solution_replay?0xFA:0xFC);
    for(y=44,x=replay_pos-(screen->h-68)/32;;x++) {
      y+=16;
      if(y+24>screen->h) break;
      if(x>=0 && x<replay_count) draw_key(16,y,replay_list[x],0xF8,0xFB);
      if(x==replay_count) draw_key(16,y,1,0xF0,0xF8);
      if(x==replay_pos) draw_text(0,y,"~~",0xF0,0xFE);
      if(x==replay_mark) draw_text(32,y,"~~",0xF0,0xFD);
    }
    SDL_UnlockSurface(screen);
  }
  if(quiz_text) draw_popup(quiz_text);
  SDL_Flip(screen);
  set_cursor(XC_arrow);







|







136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
    snprintf(buf,8,"%5d",replay_count);
    draw_text(8,screen->h-8,buf,0xF0,solution_replay?0xFA:0xFC);
    for(y=44,x=replay_pos-(screen->h-68)/32;;x++) {
      y+=16;
      if(y+24>screen->h) break;
      if(x>=0 && x<replay_count) draw_key(16,y,replay_list[x],0xF8,0xFB);
      if(x==replay_count) draw_key(16,y,1,0xF0,0xF8);
      if(x==replay_pos) draw_text(0,y,inserting?"I~":"~~",0xF0,0xFE);
      if(x==replay_mark) draw_text(32,y,"~~",0xF0,0xFD);
    }
    SDL_UnlockSurface(screen);
  }
  if(quiz_text) draw_popup(quiz_text);
  SDL_Flip(screen);
  set_cursor(XC_arrow);
305
306
307
308
309
310
311

312
313
314
315
316
317
318
static void begin_level(int id) {
  const char*t;
  replay_time=0;
  if(replay_count) save_replay();
  inputs_count=0;
  replay_pos=0;
  solved=0;

  t=load_level(id)?:init_level();
  load_replay();
  if(t) {
    gameover=-1;
    screen_message(t);
  } else {
    gameover=0;







>







306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
static void begin_level(int id) {
  const char*t;
  replay_time=0;
  if(replay_count) save_replay();
  inputs_count=0;
  replay_pos=0;
  solved=0;
  inserting=0;
  t=load_level(id)?:init_level();
  load_replay();
  if(t) {
    gameover=-1;
    screen_message(t);
  } else {
    gameover=0;
693
694
695
696
697
698
699

700
701
702
703
704
705
706
707
708
709
710

711
712
713
714
715
716
717
      if(inputs_count>=inputs_size) {
        inputs=realloc(inputs,inputs_size+=32);
        if(!inputs) fatal("Allocation failed\n");
      }
      inputs[inputs_count++]=number;
      return 0;
    case '+ ': replay: // Replay

      replay_time=0;
      if(number>replay_count-replay_pos) number=replay_count-replay_pos;
      if(number<=0) return prev;
      if(inputs_count+number>=inputs_size) {
        inputs=realloc(inputs,inputs_size+=number+1);
        if(!inputs) fatal("Allocation failed\n");
      }
      memcpy(inputs+inputs_count,replay_list+replay_pos,number);
      inputs_count+=number;
      return 0;
    case '- ': // Rewind

      number=replay_pos-number;
      if(number<0) number=0;
      //fallthru
    case '= ': restart: // Restart
      begin_level(level_id);
      if(!number) return 1;
      if(number>replay_count) number=replay_count;







>











>







695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
      if(inputs_count>=inputs_size) {
        inputs=realloc(inputs,inputs_size+=32);
        if(!inputs) fatal("Allocation failed\n");
      }
      inputs[inputs_count++]=number;
      return 0;
    case '+ ': replay: // Replay
      saved_inserting=inserting; inserting=0;
      replay_time=0;
      if(number>replay_count-replay_pos) number=replay_count-replay_pos;
      if(number<=0) return prev;
      if(inputs_count+number>=inputs_size) {
        inputs=realloc(inputs,inputs_size+=number+1);
        if(!inputs) fatal("Allocation failed\n");
      }
      memcpy(inputs+inputs_count,replay_list+replay_pos,number);
      inputs_count+=number;
      return 0;
    case '- ': // Rewind
      saved_inserting=inserting;
      number=replay_pos-number;
      if(number<0) number=0;
      //fallthru
    case '= ': restart: // Restart
      begin_level(level_id);
      if(!number) return 1;
      if(number>replay_count) number=replay_count;
725
726
727
728
729
730
731











732
733
734
735
736
737
738
    case '^<': // Rewind to mark
      number=replay_mark;
      goto restart;
    case '^>': // Replay to mark
      inputs_count=0;
      number=replay_mark-replay_pos;
      goto replay;











    case '^E': // Edit
      return main_options['r']?1:-2;
    case '^I': // Toggle inventory display
      side_mode^=1;
      return prev;
    case '^M': // Mark replay position
      replay_mark=replay_pos+inputs_count;







>
>
>
>
>
>
>
>
>
>
>







729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
    case '^<': // Rewind to mark
      number=replay_mark;
      goto restart;
    case '^>': // Replay to mark
      inputs_count=0;
      number=replay_mark-replay_pos;
      goto replay;
    case '^-': // Delete move
      inputs_count=0;
      if(replay_pos==replay_count) return 0;
      memmove(replay_list+replay_pos,replay_list+replay_pos+1,replay_count-replay_pos-1);
      replay_count--;
      if(replay_mark>replay_pos) replay_mark--;
      return 0;
    case '^+': // Insert moves
      inputs_count=0;
      inserting^=1;
      return 0;
    case '^E': // Edit
      return main_options['r']?1:-2;
    case '^I': // Toggle inventory display
      side_mode^=1;
      return prev;
    case '^M': // Mark replay position
      replay_mark=replay_pos+inputs_count;
828
829
830
831
832
833
834













835
836
837
838
839
840
841
  if(replay_pos==65534 && !gameover) t="Too many moves played";
  if(t) {
    screen_message(t);
    gameover=-1;
    return;
  }
  if(!key_ignored) {













    if(replay_pos>=replay_size) {
      if(replay_size>0xFDFF) replay_size=0xFDFF;
      if(replay_size+0x200<=replay_pos) fatal("Confusion in input_move function\n");
      replay_list=realloc(replay_list,replay_size+=0x200);
      if(!replay_list) fatal("Allocation failed\n");
    }
    replay_list[replay_pos++]=k;







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







843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
  if(replay_pos==65534 && !gameover) t="Too many moves played";
  if(t) {
    screen_message(t);
    gameover=-1;
    return;
  }
  if(!key_ignored) {
    if(inserting) {
      if(replay_pos>=0xFFFE || replay_pos==replay_count) {
        inserting=0;
      } else {
        if(replay_count>=0xFFFE) replay_count=0xFFFD;
        if(replay_size<0xFFFF) {
          replay_list=realloc(replay_list,replay_size=0xFFFF);
          if(!replay_list) fatal("Allocation failed\n");
        }
        memmove(replay_list+replay_pos+1,replay_list+replay_pos,replay_count-replay_pos);
        replay_count++;
      }
    }
    if(replay_pos>=replay_size) {
      if(replay_size>0xFDFF) replay_size=0xFDFF;
      if(replay_size+0x200<=replay_pos) fatal("Confusion in input_move function\n");
      replay_list=realloc(replay_list,replay_size+=0x200);
      if(!replay_list) fatal("Allocation failed\n");
    }
    replay_list[replay_pos++]=k;
944
945
946
947
948
949
950

951
952
953
954
955
956
957
          save_replay();
          return;
        }
      replay:
        if(inputs_count) {
          for(i=0;i<inputs_count && !gameover;i++) if(inputs[i]) input_move(inputs[i]);
          inputs_count=0;

          no_dead_anim=0;
          if(gameover==1 && should_record_solution) record_solution();
        }
        redraw_game();
        timerflag=0; // ensure we have not missed a timer event
        break;
    }







>







972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
          save_replay();
          return;
        }
      replay:
        if(inputs_count) {
          for(i=0;i<inputs_count && !gameover;i++) if(inputs[i]) input_move(inputs[i]);
          inputs_count=0;
          if(saved_inserting) inserting=1,saved_inserting=0;
          no_dead_anim=0;
          if(gameover==1 && should_record_solution) record_solution();
        }
        redraw_game();
        timerflag=0; // ensure we have not missed a timer event
        break;
    }

Modified game.doc from [5a5648e60c] to [fc79222cb9].

67
68
69
70
71
72
73








74
75
76
77
78
79
80
you can also use the keys F1, F2, F3, F4 to replay a specified number of
moves (1, 10, 100, or 1000), or the same keys with SHIFT to rewind that
number of moves.

You can set a mark by pushing F5. You can then push F6 or F7 to rewind or
replay up to this point. The marks are also saved with each level and is
saved in the user cache database too.









You can also import/export move lists. Push CTRL+I to import or CTRL+X
to export, and at the prompt type the operating system command which will
send the move list to stdout or receive the move list from stdin, for
example if you want the file called "Movelist" then you can type "cat
Movelist" to read that file or "cat > Movelist" to write to that file.








>
>
>
>
>
>
>
>







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
you can also use the keys F1, F2, F3, F4 to replay a specified number of
moves (1, 10, 100, or 1000), or the same keys with SHIFT to rewind that
number of moves.

You can set a mark by pushing F5. You can then push F6 or F7 to rewind or
replay up to this point. The marks are also saved with each level and is
saved in the user cache database too.

You can also delete moves by pushing the DELETE key (the next move to be
played in the replay list is deleted), or toggle insertion mode by pushing
the INSERT key. While insertion mode is active, the move list displays
"I~" and any new moves entered will be inserted into the current position
in the move list instead of overwriting it. Insertion mode is reset when
restarting a level or accessing a different level, and will be temporarily
disabled while playing back the replay list.

You can also import/export move lists. Push CTRL+I to import or CTRL+X
to export, and at the prompt type the operating system command which will
send the move list to stdout or receive the move list from stdin, for
example if you want the file called "Movelist" then you can type "cat
Movelist" to read that file or "cat > Movelist" to write to that file.

133
134
135
136
137
138
139


140
141
142
143
144
145
146
  KP -        Previous level
  SHIFT+KP +  Last level
  SHIFT+KP -  First level
  ALT+G       Inspect globals
  ALT+P       Begin slow replay
  ALT+[       Increase slow replay speed
  ALT+]       Decrease slow replay speed



Mouse (in grid):

  MIDDLE       Describe topmost object
  RIGHT        Inspect objects (main world)
  SHIFT+RIGHT  Inspect objects (bizarro world)








>
>







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
  KP -        Previous level
  SHIFT+KP +  Last level
  SHIFT+KP -  First level
  ALT+G       Inspect globals
  ALT+P       Begin slow replay
  ALT+[       Increase slow replay speed
  ALT+]       Decrease slow replay speed
  INS         Toggle insertion mode
  DEL         Delete a move

Mouse (in grid):

  MIDDLE       Describe topmost object
  RIGHT        Inspect objects (main world)
  SHIFT+RIGHT  Inspect objects (bizarro world)