Free Hero Mesh

Check-in [ccc683e688]
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 .autoWin option (to do something if you have won, e.g. auto advance to next level).
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ccc683e6888af8966029fffc1f6659261d4d576a
User & Date: user on 2021-11-25 01:17:41
Other Links: manifest | tags
Context
2021-11-26
04:57
A few minor corrections in config.doc (no changes to the program code). check-in: fe6e5facdc user: user tags: trunk
2021-11-25
01:17
Implement .autoWin option (to do something if you have won, e.g. auto advance to next level). check-in: ccc683e688 user: user tags: trunk
2021-11-18
19:39
Add FAQ entry about -lsqlite3 vs sqlite3.o check-in: 3a26643be9 user: user tags: trunk
Changes

Modified README from [b7083ca7e5] to [3010869d52].

421
422
423
424
425
426
427
428





** It cannot find sqlite3.o when compiling. Why not use -lsqlite3 instead?

 The version of SQLite in the package manager is not always the newest
 version. Sometimes I use features that are in released versions of SQLite
 but not necessarily in the package manager (and which versions are in the
 package manager may vary according to the distribution). The version in
 the package manager might or might not work; it is untested.














>
>
>
>
>
421
422
423
424
425
426
427
428
429
430
431
432
433
** It cannot find sqlite3.o when compiling. Why not use -lsqlite3 instead?

 The version of SQLite in the package manager is not always the newest
 version. Sometimes I use features that are in released versions of SQLite
 but not necessarily in the package manager (and which versions are in the
 package manager may vary according to the distribution). The version in
 the package manager might or might not work; it is untested.

** How to make it to automatically advance to next level if you win?

 Add the following into the .heromeshrc file:
   .?.autoWin: select 'go',-(level()+1) where level()<max_level();

Modified TODO from [c76392904d] to [10a2af48e5].

28
29
30
31
32
33
34

35
36
37
38
39
40
41
* Inventory/replay hybrid view
* Bookmarks
* Message trace menu to enable/disable
* Bugs
  * Figure out why the $SeekerCloser class doesn't seem to work properly
  * Level 232 of SUPERHRO puzzle set (the Lava shouldn't expand? why?)
  * Animation stopping unexpectedly (until a key is pushed)

* Display solution comments/timestamp
* VCR mode
* Command-line switch for batch export levels
* SQL
  * Implement the GROUP column in the CLASSES table
  * Allow multiple SQL statements in one binding
* Fonts/text







>







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
* Inventory/replay hybrid view
* Bookmarks
* Message trace menu to enable/disable
* Bugs
  * Figure out why the $SeekerCloser class doesn't seem to work properly
  * Level 232 of SUPERHRO puzzle set (the Lava shouldn't expand? why?)
  * Animation stopping unexpectedly (until a key is pushed)
  * ObjLF.Volume+ObjRF.Volume+obj.Volume if ObjLF and/or ObjRF doesn't exist?
* Display solution comments/timestamp
* VCR mode
* Command-line switch for batch export levels
* SQL
  * Implement the GROUP column in the CLASSES table
  * Allow multiple SQL statements in one binding
* Fonts/text
61
62
63
64
65
66
67
68
  * Escape
  * Chroma
  * Xsok
  * PuzzleScript (limited; not everything is or will be capable)
  * Sokoban
  * Puzzle Boy
  * Pitman/Catrap
* Auto advance next level option







<
62
63
64
65
66
67
68

  * Escape
  * Chroma
  * Xsok
  * PuzzleScript (limited; not everything is or will be capable)
  * Sokoban
  * Puzzle Boy
  * Pitman/Catrap

Modified config.doc from [ffd3ca386e] to [181b1267e0].

23
24
25
26
27
28
29






30
31
32
33
34
35
36

.autoSave
  If true, saves changes to the level and solution files when the program
  terminates. If false (default), they are only saved to the user cache
  database; to copy the changes to the level and solution files, you must
  use the .u command in SQL mode (-x), or use the -f switch.







.codepage
  The path to the code page file. If not specified, then code pages other
  than 437 are not available (code page 437 is built-in).

.editTitle
  The window title to use in edit mode. A tilde is replaced by the name of
  the puzzle set.







>
>
>
>
>
>







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

.autoSave
  If true, saves changes to the level and solution files when the program
  terminates. If false (default), they are only saved to the user cache
  database; to copy the changes to the level and solution files, you must
  use the .u command in SQL mode (-x), or use the -f switch.

.autoWin
  SQL statement to execute if you win a level. The format is the same as
  for a key/mouse binding, but must be a SQL statement, and the only valid
  parameters are $LEVEL and $LEVEL_ID. Furthermore, '^E', '^Q', ':s', and
  ':x' are not valid.

.codepage
  The path to the code page file. If not specified, then code pages other
  than 437 are not available (code page 437 is built-in).

.editTitle
  The window title to use in edit mode. A tilde is replaced by the name of
  the puzzle set.

Modified default.heromeshrc from [9cfd006fc7] to [8008201b1c].

1
2
3
4
5
6
7
8
! hERo Mesh configuration settings
?.screenWidth: 800
?.screenHeight: 600
?.imageSize: 24
?.traceAll: true
?.showInventory: 0
?.maxTrigger: 32767
?.pasteCommand: xclip -o
|







1
2
3
4
5
6
7
8
! Hero Mesh configuration settings
?.screenWidth: 800
?.screenHeight: 600
?.imageSize: 24
?.traceAll: true
?.showInventory: 0
?.maxTrigger: 32767
?.pasteCommand: xclip -o

Modified game.c from [17a420d135] to [2ace16c827].

29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54



55
56
57
58
59
60
61
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)?:"";
  side_mode=boolxrm(v,1);
  optionquery[1]=Q_replaySpeed;
  v=xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"";
  replay_speed=strtol(v,0,10)?:16;
  if(main_options['r']) {
    should_record_solution=0;
  } else {
    optionquery[1]=Q_saveSolutions;
    v=xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"";
    should_record_solution=boolxrm(v,0);
  }
  solution_replay=0;



}

static void redraw_game(void) {
  char buf[32];
  SDL_Rect r;
  int x,y;
  r.x=r.y=0;







>



















>
>
>







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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 sqlite3_stmt*autowin;

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)?:"";
  side_mode=boolxrm(v,1);
  optionquery[1]=Q_replaySpeed;
  v=xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"";
  replay_speed=strtol(v,0,10)?:16;
  if(main_options['r']) {
    should_record_solution=0;
  } else {
    optionquery[1]=Q_saveSolutions;
    v=xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"";
    should_record_solution=boolxrm(v,0);
  }
  solution_replay=0;
  optionquery[1]=Q_autoWin;
  v=xrm_get_resource(resourcedb,optionquery,optionquery,2);
  if(v && *v) sqlite3_prepare_v3(userdb,v,-1,SQLITE_PREPARE_PERSISTENT,&autowin,0);
}

static void redraw_game(void) {
  char buf[32];
  SDL_Rect r;
  int x,y;
  r.x=r.y=0;
818
819
820
821
822
823
824









































825
826
827
828
829
830
831
      if(number<1) number=1; else if(number>255) number=255;
      replay_speed=number;
      return prev;
    default:
      return prev;
  }
}










































static void set_caption(void) {
  const char*r;
  char*s;
  sqlite3_str*m;
  int c;
  optionquery[1]=Q_gameTitle;







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







822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
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
870
871
872
873
874
875
876
      if(number<1) number=1; else if(number>255) number=255;
      replay_speed=number;
      return prev;
    default:
      return prev;
  }
}

static void do_autowin(void) {
  const char*name;
  int i,j,k;
  int prev=0;
  sqlite3_reset(autowin);
  if(sqlite3_bind_parameter_count(autowin)) {
    for(i=sqlite3_bind_parameter_count(autowin);i;--i) if(name=sqlite3_bind_parameter_name(autowin,i)) {
      if(*name=='$') {
        if(!sqlite3_stricmp(name+1,"LEVEL")) {
          sqlite3_bind_int(autowin,i,level_ord);
        } else if(!sqlite3_stricmp(name+1,"LEVEL_ID")) {
          sqlite3_bind_int(autowin,i,level_id);
        }
      }
    }
  }
  while((i=sqlite3_step(autowin))==SQLITE_ROW) {
    if(i=sqlite3_data_count(autowin)) {
      j=(i>1&&sqlite3_column_type(autowin,1)!=SQLITE_NULL)?sqlite3_column_int(autowin,1):0;
      if((name=sqlite3_column_text(autowin,0)) && *name) {
        if(name[0]==':') {
          switch(name[1]) {
            case '!': if(i>1) i=system(sqlite3_column_text(autowin,1)?:(const unsigned char*)"# "); break;
            case ';': goto done;
            case '?': if(i>1) puts(sqlite3_column_text(autowin,1)?:(const unsigned char*)"(null)"); break;
            case 'm': if(i>1) screen_message(sqlite3_column_text(autowin,1)?:(const unsigned char*)"(null)"); break;
          }
        } else {
          k=name[0]*'\1\0'+name[1]*'\0\1';
          while(i && sqlite3_column_type(autowin,i-1)==SQLITE_NULL) i--;
          prev=game_command(prev,k,j,i,autowin,0);
          if(prev<0) goto done;
        }
      }
    }
  }
  if(i!=SQLITE_DONE) screen_message("SQL error");
  done:
  sqlite3_reset(autowin);
}

static void set_caption(void) {
  const char*r;
  char*s;
  sqlite3_str*m;
  int c;
  optionquery[1]=Q_gameTitle;
987
988
989
990
991
992
993

994


995
996
997
998
999
1000
1001
        }
      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;
    }
  }
  quit:







>
|
>
>







1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
        }
      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) {
            if(should_record_solution) record_solution();
            if(autowin) do_autowin();
          }
        }
        redraw_game();
        timerflag=0; // ensure we have not missed a timer event
        break;
    }
  }
  quit:

Modified quarks from [31753fde64] to [6c4bb42f1f].

218
219
220
221
222
223
224

225
showInventory
progress
autoSave
maxTrigger
pasteCommand
codepage
replaySpeed









>

218
219
220
221
222
223
224
225
226
showInventory
progress
autoSave
maxTrigger
pasteCommand
codepage
replaySpeed
autoWin

Modified quarks.h from [8c36a586cf] to [2d3b356f67].

183
184
185
186
187
188
189

190
191
192
193
194
195
196
#define Q_showInventory 184
#define Q_progress 185
#define Q_autoSave 186
#define Q_maxTrigger 187
#define Q_pasteCommand 188
#define Q_codepage 189
#define Q_replaySpeed 190

static const char*const global_quarks[]={
  "screenWidth",
  "screenHeight",
  "margin",
  "palette",
  "popupColors",
  "imageSize",







>







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#define Q_showInventory 184
#define Q_progress 185
#define Q_autoSave 186
#define Q_maxTrigger 187
#define Q_pasteCommand 188
#define Q_codepage 189
#define Q_replaySpeed 190
#define Q_autoWin 191
static const char*const global_quarks[]={
  "screenWidth",
  "screenHeight",
  "margin",
  "palette",
  "popupColors",
  "imageSize",
373
374
375
376
377
378
379

380
381
382
383
384
385
386
  "showInventory",
  "progress",
  "autoSave",
  "maxTrigger",
  "pasteCommand",
  "codepage",
  "replaySpeed",

0};
#ifdef HEROMESH_BINDINGS
static const SDLKey quark_to_key[Q_undo+1-Q_backspace]={
SDLK_BACKSPACE,
SDLK_TAB,
SDLK_CLEAR,
SDLK_RETURN,







>







374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
  "showInventory",
  "progress",
  "autoSave",
  "maxTrigger",
  "pasteCommand",
  "codepage",
  "replaySpeed",
  "autoWin",
0};
#ifdef HEROMESH_BINDINGS
static const SDLKey quark_to_key[Q_undo+1-Q_backspace]={
SDLK_BACKSPACE,
SDLK_TAB,
SDLK_CLEAR,
SDLK_RETURN,