Free Hero Mesh

Check-in [28b482dea1]
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 SOLUTION_MOVE_LIST function, F9 to flash player location, shift and middle mouse button, and a documentation correction.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 28b482dea1da55d06d30bc613cfe1ed148237780
User & Date: user on 2021-09-30 21:08:35
Other Links: manifest | tags
Context
2021-10-02
01:55
Implement composite puzzle sets check-in: 4919d2c22e user: user tags: trunk
2021-09-30
21:08
Add SOLUTION_MOVE_LIST function, F9 to flash player location, shift and middle mouse button, and a documentation correction. check-in: 28b482dea1 user: user tags: trunk
03:21
Implement selection rectangles, and PLAYFIELD virtual table. check-in: 2119a02b07 user: user tags: trunk
Changes

Modified bindings.doc from [057f589131] to [8c762c044c].

93
94
95
96
97
98
99



100
101
102
103
104
105
106

'^p'
  Start or stop slow replay. Any move input also interrupts slow replay.

'^s'
  Toggle solution replay.




'mi' <command>
  Import a move list. The argument is a operating system command, that
  when executed will write the move list to stdout, with one byte per
  move (the Hero Mesh key codes).

'ml' <blob>
  Load a move list from a SQL blob.







>
>
>







93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

'^p'
  Start or stop slow replay. Any move input also interrupts slow replay.

'^s'
  Toggle solution replay.

'lo' <location>
  Flash the specified location briefly.

'mi' <command>
  Import a move list. The argument is a operating system command, that
  when executed will write the move list to stdout, with one byte per
  move (the Hero Mesh key codes).

'ml' <blob>
  Load a move list from a SQL blob.

Modified default.heromeshrc from [4827705334] to [663dcd3e34].

122
123
124
125
126
127
128


129
130
131
132
133
134
135
?.gameKey.shift.f2: -10
?.gameKey.shift.f3: -100
?.gameKey.shift.f4: -1000
?.gameKey.f5: ^M
?.gameKey.f6: ^<
?.gameKey.f7: ^>
?.gameKey.f8: ^s


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







>
>







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
?.gameKey.shift.f2: -10
?.gameKey.shift.f3: -100
?.gameKey.shift.f4: -1000
?.gameKey.f5: ^M
?.gameKey.f6: ^<
?.gameKey.f7: ^>
?.gameKey.f8: ^s
?.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
161
162
163
164
165
166
167

168
169
170
171
172
173
174
?.editKey.shift.F: select '^a',xy(x,y) from playfield where inrect(x,y);
?.editClick.left: ^a
?.editClick.ctrl.left: select 'em',id from objects where x=$X and y=$Y and up is null;
?.editClick.alt.left: ^u
?.editClick.right: delete from objects where x=$X and y=$Y and up is null;
?.editClick.ctrl.right: select 'am',class,image,misc1,misc2,misc3,dir from objects where x=$X and y=$Y and up is null;
?.editClick.shift.left: ^<

?.editClick.shift.right: ^>

! Global key bindings
?.?.kp_minus: select 'go',-(level()-1) where level()>1;
?.?.kp_plus: select 'go',-(level()+1) where level()<max_level();
?.?.shift.kp_minus: select 'go',-1;
?.?.shift.kp_plus: select 'go',-max_level();







>







163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
?.editKey.shift.F: select '^a',xy(x,y) from playfield where inrect(x,y);
?.editClick.left: ^a
?.editClick.ctrl.left: select 'em',id from objects where x=$X and y=$Y and up is null;
?.editClick.alt.left: ^u
?.editClick.right: delete from objects where x=$X and y=$Y and up is null;
?.editClick.ctrl.right: select 'am',class,image,misc1,misc2,misc3,dir from objects where x=$X and y=$Y and up is null;
?.editClick.shift.left: ^<
?.editClick.shift.middle: values('^Z',null),('^<',xy($X,$Y));
?.editClick.shift.right: ^>

! Global key bindings
?.?.kp_minus: select 'go',-(level()-1) where level()>1;
?.?.kp_plus: select 'go',-(level()+1) where level()<max_level();
?.?.shift.kp_minus: select 'go',-1;
?.?.shift.kp_plus: select 'go',-max_level();

Modified function.c from [567c012195] to [e8f3bec2de].

386
387
388
389
390
391
392

















393
394
395
396
397
398
399

static void fn_sign_extend(sqlite3_context*cxt,int argc,sqlite3_value**argv) {
  sqlite3_int64 a;
  if(sqlite3_value_type(*argv)==SQLITE_NULL) return;
  a=sqlite3_value_int64(*argv)&0xFFFFFFFF;
  sqlite3_result_int64(cxt,a-(a&0x80000000?0x100000000LL:0));
}


















static void fn_trace_on(sqlite3_context*cxt,int argc,sqlite3_value**argv) {
  const char*v=sqlite3_user_data(cxt);
  if(main_options['t']=*v) puts("[Tracing enabled]"); else puts("[Tracing disabled]");
}

static void fn_xy(sqlite3_context*cxt,int argc,sqlite3_value**argv) {







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







386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416

static void fn_sign_extend(sqlite3_context*cxt,int argc,sqlite3_value**argv) {
  sqlite3_int64 a;
  if(sqlite3_value_type(*argv)==SQLITE_NULL) return;
  a=sqlite3_value_int64(*argv)&0xFFFFFFFF;
  sqlite3_result_int64(cxt,a-(a&0x80000000?0x100000000LL:0));
}

static void fn_solution_move_list(sqlite3_context*cxt,int argc,sqlite3_value**argv) {
  long sz;
  int i=3;
  unsigned char*d=read_lump(FIL_SOLUTION,level_id,&sz);
  if(sz<4 || !d || ((!argc || !sqlite3_value_int(*argv)) && (d[0]|(d[1]<<8))!=level_version)) {
    free(d);
    return;
  }
  if(d[2]&1) {
    while(i<sz && d[i]) i++;
    i++;
  }
  if(d[2]&2) i+=8;
  if(i<sz) sqlite3_result_blob(cxt,d+i,sz-i,SQLITE_TRANSIENT);
  free(d);
}

static void fn_trace_on(sqlite3_context*cxt,int argc,sqlite3_value**argv) {
  const char*v=sqlite3_user_data(cxt);
  if(main_options['t']=*v) puts("[Tracing enabled]"); else puts("[Tracing disabled]");
}

static void fn_xy(sqlite3_context*cxt,int argc,sqlite3_value**argv) {
1157
1158
1159
1160
1161
1162
1163


1164
1165
1166
1167
1168
1169
1170
  sqlite3_create_function(userdb,"RECT_X0",0,SQLITE_UTF8,&editrect.x0,fn_rect_x0,0,0);
  sqlite3_create_function(userdb,"RECT_X1",0,SQLITE_UTF8,&editrect.x1,fn_rect_x0,0,0);
  sqlite3_create_function(userdb,"RECT_Y0",0,SQLITE_UTF8,&editrect.y0,fn_rect_x0,0,0);
  sqlite3_create_function(userdb,"RECT_Y1",0,SQLITE_UTF8,&editrect.y1,fn_rect_x0,0,0);
  sqlite3_create_function(userdb,"RESOURCE",-1,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_resource,0,0);
  sqlite3_create_function(userdb,"SIGN_EXTEND",1,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_sign_extend,0,0);
  sqlite3_create_function(userdb,"SOLUTION_CACHEID",0,SQLITE_UTF8|SQLITE_DETERMINISTIC,ptr1,fn_cacheid,0,0);


  sqlite3_create_function(userdb,"TRACE_OFF",0,SQLITE_UTF8,"",fn_trace_on,0,0);
  sqlite3_create_function(userdb,"TRACE_ON",0,SQLITE_UTF8,"\x01",fn_trace_on,0,0);
  sqlite3_create_function(userdb,"XY",2,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_xy,0,0);
  sqlite3_create_function(userdb,"ZERO_EXTEND",1,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_zero_extend,0,0);
  bizarro_vtab=""; // ensure that it is not null
  sqlite3_create_module(userdb,"CLASSES",&vt_classes,"CREATE TABLE `CLASSES`(`ID` INTEGER PRIMARY KEY, `NAME` TEXT, `EDITORHELP` TEXT, `HELP` TEXT,"
   "`INPUT` INT, `QUIZ` INT, `TRACEIN` INT, `TRACEOUT` INT, `GROUP` TEXT, `PLAYER` INT);");







>
>







1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
  sqlite3_create_function(userdb,"RECT_X0",0,SQLITE_UTF8,&editrect.x0,fn_rect_x0,0,0);
  sqlite3_create_function(userdb,"RECT_X1",0,SQLITE_UTF8,&editrect.x1,fn_rect_x0,0,0);
  sqlite3_create_function(userdb,"RECT_Y0",0,SQLITE_UTF8,&editrect.y0,fn_rect_x0,0,0);
  sqlite3_create_function(userdb,"RECT_Y1",0,SQLITE_UTF8,&editrect.y1,fn_rect_x0,0,0);
  sqlite3_create_function(userdb,"RESOURCE",-1,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_resource,0,0);
  sqlite3_create_function(userdb,"SIGN_EXTEND",1,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_sign_extend,0,0);
  sqlite3_create_function(userdb,"SOLUTION_CACHEID",0,SQLITE_UTF8|SQLITE_DETERMINISTIC,ptr1,fn_cacheid,0,0);
  sqlite3_create_function(userdb,"SOLUTION_MOVE_LIST",0,SQLITE_UTF8,0,fn_solution_move_list,0,0);
  sqlite3_create_function(userdb,"SOLUTION_MOVE_LIST",1,SQLITE_UTF8,0,fn_solution_move_list,0,0);
  sqlite3_create_function(userdb,"TRACE_OFF",0,SQLITE_UTF8,"",fn_trace_on,0,0);
  sqlite3_create_function(userdb,"TRACE_ON",0,SQLITE_UTF8,"\x01",fn_trace_on,0,0);
  sqlite3_create_function(userdb,"XY",2,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_xy,0,0);
  sqlite3_create_function(userdb,"ZERO_EXTEND",1,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_zero_extend,0,0);
  bizarro_vtab=""; // ensure that it is not null
  sqlite3_create_module(userdb,"CLASSES",&vt_classes,"CREATE TABLE `CLASSES`(`ID` INTEGER PRIMARY KEY, `NAME` TEXT, `EDITORHELP` TEXT, `HELP` TEXT,"
   "`INPUT` INT, `QUIZ` INT, `TRACEIN` INT, `TRACEOUT` INT, `GROUP` TEXT, `PLAYER` INT);");

Modified game.c from [63ee4dfd40] to [2ff75549f9].

764
765
766
767
768
769
770



771
772
773
774
775
776
777
      if(replay_count) save_replay();
      solution_replay^=1;
      if(replay_count) replay_count=0,begin_level(level_id); else load_replay();
      return 1;
    case 'go': // Select level
      begin_level(number);
      return 1;



    case 'mi': // Move list import
      if(argc<2 || solution_replay) break;
      if(replay_pos) begin_level(level_id);
      do_import_moves(sqlite3_column_text(args,1));
      return 1;
    case 'ml': // Move list load
      if(argc<2 || solution_replay) break;







>
>
>







764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
      if(replay_count) save_replay();
      solution_replay^=1;
      if(replay_count) replay_count=0,begin_level(level_id); else load_replay();
      return 1;
    case 'go': // Select level
      begin_level(number);
      return 1;
    case 'lo': // Locate me
      locate_me(number&63?:64,number/64?:64);
      return prev;
    case 'mi': // Move list import
      if(argc<2 || solution_replay) break;
      if(replay_pos) begin_level(level_id);
      do_import_moves(sqlite3_column_text(args,1));
      return 1;
    case 'ml': // Move list load
      if(argc<2 || solution_replay) break;

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

119
120
121
122
123
124
125


126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  SHIFT+F2    Rewind 10 moves
  SHIFT+F3    Rewind 100 moves
  SHIFT+F4    Rewind 1000 moves
  F5          Set mark
  F6          Rewind to mark
  F7          Replay to mark
  F8          Toggle solution replay


  F10         SQL queries
  ESCAPE      Restart level
  TAB         Toggle inventory/replay display
  KP ENTER    Restart level
  KP +        Next level
  KP -        Previous level
  SHIFT+KP +  Last level
  SHIFT+KP -  Previous 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)









>
>

|





|











<
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

  SHIFT+F2    Rewind 10 moves
  SHIFT+F3    Rewind 100 moves
  SHIFT+F4    Rewind 1000 moves
  F5          Set mark
  F6          Rewind to mark
  F7          Replay to mark
  F8          Toggle solution replay
  SHIFT+F8    Copy solution
  F9          Flash player position
  F10         SQL queries
  ESC         Restart level
  TAB         Toggle inventory/replay display
  KP ENTER    Restart level
  KP +        Next level
  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)


Modified sql.doc from [d7c3542661] to [a8f6d9974c].

128
129
130
131
132
133
134




135
136
137
138
139
140
141

SIGN_EXTEND(number)
  Sign extends a 32-bit number to 64-bits.

SOLUTION_CACHEID()
  The user cache ID of the level file.





TRACE_OFF()
  Disables tracing when called.

TRACE_ON()
  Enables tracing when called.

XY(x,y)







>
>
>
>







128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145

SIGN_EXTEND(number)
  Sign extends a 32-bit number to 64-bits.

SOLUTION_CACHEID()
  The user cache ID of the level file.

SOLUTION_MOVE_LIST(boolean)
  Returns the solution move list. If the boolean value is true, then it
  always loads it even if the level version number doesn't match.

TRACE_OFF()
  Disables tracing when called.

TRACE_ON()
  Enables tracing when called.

XY(x,y)