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
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
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
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
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,"~~",0xF0,0xFE);
      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
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
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
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
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
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
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
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)