Free Hero Mesh

Check-in [bbdc443497]
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 the possibility to add new levels into the puzzle set.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: bbdc443497230124febbe9e291614de41c85c896
User & Date: user on 2021-03-23 05:00:23
Other Links: manifest | tags
Context
2021-03-23
05:06
Fix a bug in game.c causing it to use the wrong replay data when switching between the game and editor. check-in: d0f39b05fa user: user tags: trunk
05:00
Implement the possibility to add new levels into the puzzle set. check-in: bbdc443497 user: user tags: trunk
2021-03-21
20:34
Implement bit23 for HIT/HITBY to prevent cascading after shoving check-in: b572dd834c user: user tags: trunk
Changes

Modified bindings.doc from [ee76aafc91] to [b05d9a34cf].

97
98
99
100
101
102
103





104
105
106
107
108
109
110
'mx' <command>
  Export a move list. The argument is a operating system command that
  will receive the move list (in the same format as above) on stdin.


=== Editor commands ===






'^S'
  Save level.

'^a' <location>
  Add an object with the current MRU values to that location, if there
  is not already another object of the same class there.








>
>
>
>
>







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
'mx' <command>
  Export a move list. The argument is a operating system command that
  will receive the move list (in the same format as above) on stdin.


=== Editor commands ===

'^N'
  Add a new level (after the last one). The new level has the same
  dimensions as the current level, but contains no objects or strings,
  and the title is set to "New Level".

'^S'
  Save level.

'^a' <location>
  Add an object with the current MRU values to that location, if there
  is not already another object of the same class there.

Modified default.heromeshrc from [75fb89c738] to [7cb4207d79].

137
138
139
140
141
142
143
144
145
146
147

148
149
150
151
152
153
154
?.editKey.8: select 'mr',7;
?.editKey.9: select 'mr',8;
?.editKey.up: select 'mR',-1;
?.editKey.down: select 'mR',+1;
?.editKey.C: select 'lc',:level_code where :level_code=cast(:level_code as int);
?.editKey.F: with n(n) as (select 65 union all select n+1 h from n where h<=64*pfheight()+65) select '^a',n from n;
?.editKey.R: select 're',substr(:resize,1,instr(:resize,'x')-1),substr(:resize,instr(:resize,'x')+1) where length(:resize);
?.editKey.ctrl.X: select 're',pfwidth(),pfheight();
?.editKey.ctrl.P: ^P
?.editKey.ctrl.Q: ^Q
?.editKey.ctrl.S: ^S

?.editKey.space: ^c
?.editKey.return: ^e
?.editKey.f1: select 'im',:Import_Level;
?.editKey.f2: select 'ex',:Export_Level;
?.editClick.left: ^a
?.editClick.alt.left: ^u
?.editClick.right: delete from objects where x=$X and y=$Y and up is null;







|



>







137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
?.editKey.8: select 'mr',7;
?.editKey.9: select 'mr',8;
?.editKey.up: select 'mR',-1;
?.editKey.down: select 'mR',+1;
?.editKey.C: select 'lc',:level_code where :level_code=cast(:level_code as int);
?.editKey.F: with n(n) as (select 65 union all select n+1 h from n where h<=64*pfheight()+65) select '^a',n from n;
?.editKey.R: select 're',substr(:resize,1,instr(:resize,'x')-1),substr(:resize,instr(:resize,'x')+1) where length(:resize);
?.editKey.ctrl.N: ^N
?.editKey.ctrl.P: ^P
?.editKey.ctrl.Q: ^Q
?.editKey.ctrl.S: ^S
?.editKey.ctrl.X: select 're',pfwidth(),pfheight();
?.editKey.space: ^c
?.editKey.return: ^e
?.editKey.f1: select 'im',:Import_Level;
?.editKey.f2: select 'ex',:Export_Level;
?.editClick.left: ^a
?.editClick.alt.left: ^u
?.editClick.right: delete from objects where x=$X and y=$Y and up is null;

Modified edit.c from [2aa028c0b1] to [52228f0c2a].

165
166
167
168
169
170
171















172
173
174
175
176
177
178
    }
    if(!((b&0xC0)%0xC0)) {
      sqlite3_str_appendchar(s,1,o->misc3.u&0xFF);
      sqlite3_str_appendchar(s,1,o->misc3.u>>8);
    }
  }
}
















static void save_level(void) {
  /*
   Format of objects:
     * bit flags (or 0xFF for end):
       bit7 = MRU (omit everything but position)
       bit6 = Next position







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







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
    }
    if(!((b&0xC0)%0xC0)) {
      sqlite3_str_appendchar(s,1,o->misc3.u&0xFF);
      sqlite3_str_appendchar(s,1,o->misc3.u>>8);
    }
  }
}

static void update_level_index(void) {
  Uint8*data;
  int i;
  if(level_ord>level_nindex) {
    level_index=realloc(level_index,++level_nindex*sizeof(Uint16));
    if(!level_index) fatal("Allocation failed\n");
    level_index[level_ord-1]=level_id;
  }
  data=malloc(level_nindex<<1);
  if(!data) fatal("Allocation failed\n");
  for(i=0;i<level_nindex;i++) data[i+i]=level_index[i]&255,data[i+i+1]=level_index[i]>>8;
  write_lump(FIL_LEVEL,LUMP_LEVEL_IDX,2*level_nindex,data);
  free(data);
}

static void save_level(void) {
  /*
   Format of objects:
     * bit flags (or 0xFF for end):
       bit7 = MRU (omit everything but position)
       bit6 = Next position
226
227
228
229
230
231
232

233
234

235

236
237
238
239
240
241
242
  // Level strings
  for(i=0;i<nlevelstrings;i++) sqlite3_str_appendall(str,levelstrings[i]);
  // Done
  sz=sqlite3_str_length(str);
  if(i=sqlite3_str_errcode(str)) fatal("SQL string error (%d)\n",i);
  data=sqlite3_str_finish(str);
  if(!data) fatal("Allocation failed\n");

  write_lump(FIL_LEVEL,level_id,sz,data);
  sqlite3_free(data);

  rewrite_class_def();

}

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







>


>

>







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
  // Level strings
  for(i=0;i<nlevelstrings;i++) sqlite3_str_appendall(str,levelstrings[i]);
  // Done
  sz=sqlite3_str_length(str);
  if(i=sqlite3_str_errcode(str)) fatal("SQL string error (%d)\n",i);
  data=sqlite3_str_finish(str);
  if(!data) fatal("Allocation failed\n");
  sqlite3_exec(userdb,"BEGIN;",0,0,0);
  write_lump(FIL_LEVEL,level_id,sz,data);
  sqlite3_free(data);
  if(level_ord==level_nindex+1) update_level_index();
  rewrite_class_def();
  sqlite3_exec(userdb,"COMMIT;",0,0,0);
}

static void redraw_editor(void) {
  char buf[32];
  SDL_Rect r;
  int x,y;
  r.x=r.y=0;
970
971
972
973
974
975
976

























977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994




995
996
997
998
999
1000
1001
    }
  }
  done:
  free(buf);
  pclose(fp);
  generation_number_inc=0;
}


























static int editor_command(int prev,int cmd,int number,int argc,sqlite3_stmt*args,void*aux) {
  int x,y;
  switch(cmd) {
    case '^a': // Add object (no duplicates)
      if(prev) return prev;
      add_object_at(number&63?:64,number/64?:64,mru+curmru,1);
      return 0;
    case '^c': // Select class/image
      class_image_select();
      return 0;
    case '^e': // Edit Misc/Dir of MRU slot
      mru_edit(mru+curmru);
      return 0;
    case '^u': // Add object (allow duplicates)
      if(prev) return prev;
      add_object_at(number&63?:64,number/64?:64,mru+curmru,0);
      return 0;




    case '^P': // Play
      return -2;
    case '^Q': // Quit
      return -1;
    case '^S': // Save level
      save_level();
      return 1;







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


















>
>
>
>







988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
    }
  }
  done:
  free(buf);
  pclose(fp);
  generation_number_inc=0;
}

static void new_level(void) {
  sqlite3_stmt*st;
  int i;
  if(i=sqlite3_prepare_v2(userdb,"SELECT COALESCE(MAX(`LEVEL`),-1)+1 FROM `USERCACHEDATA` WHERE `FILE` = LEVEL_CACHEID();",-1,&st,0)) {
    screen_message(sqlite3_errmsg(userdb));
    return;
  }
  i=sqlite3_step(st);
  if(i!=SQLITE_ROW) {
    sqlite3_finalize(st);
    screen_message(sqlite3_errmsg(userdb));
    return;
  }
  i=sqlite3_column_int(st,0);
  sqlite3_finalize(st);
  if(i>0xFFFE) return;
  annihilate();
  level_id=i;
  free(level_title);
  level_title=strdup("New Level");
  if(!level_title) fatal("Allocation failed\n");
  level_changed=level_version=level_code=0;
  level_ord=level_nindex+1;
}

static int editor_command(int prev,int cmd,int number,int argc,sqlite3_stmt*args,void*aux) {
  int x,y;
  switch(cmd) {
    case '^a': // Add object (no duplicates)
      if(prev) return prev;
      add_object_at(number&63?:64,number/64?:64,mru+curmru,1);
      return 0;
    case '^c': // Select class/image
      class_image_select();
      return 0;
    case '^e': // Edit Misc/Dir of MRU slot
      mru_edit(mru+curmru);
      return 0;
    case '^u': // Add object (allow duplicates)
      if(prev) return prev;
      add_object_at(number&63?:64,number/64?:64,mru+curmru,0);
      return 0;
    case '^N': // New level
      if(level_nindex>0xFFFE) return 0;
      new_level();
      return 1;
    case '^P': // Play
      return -2;
    case '^Q': // Quit
      return -1;
    case '^S': // Save level
      save_level();
      return 1;