Free Hero Mesh

Check-in [89cc6486f6]
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 CONFIG_NO_STATUS
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 89cc6486f65f15788d7d54998dc3dcb002a3fb6b
User & Date: user on 2022-08-10 05:45:57
Other Links: manifest | tags
Context
2022-08-11
04:25
Implement CONFIG_EXTRA_SCREEN_INIT check-in: 831a8baa13 user: user tags: trunk
2022-08-10
05:45
Implement CONFIG_NO_STATUS check-in: 89cc6486f6 user: user tags: trunk
2022-08-06
07:47
Implement CONFIG_OMIT_SOUND check-in: c8c053656e user: user tags: trunk
Changes

Modified bindings.c from [59715bfb2c] to [dcc38ad60c].

116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140







-
+









-
+








static void*cb_1(xrm_db*db,void*usr) {
  xrm_enumerate(db,cb_2,usr);
  return 0;
}

void load_key_bindings(void) {
  fprintf(stderr,"Loading key bindings...\n");
  printStatus("Loading key bindings...\n");
  cur_modifiers=loose_modifiers=0;
  optionquery[1]=Q_editKey;
  xrm_search(resourcedb,optionquery,optionquery,2,cb_1,editor_bindings);
  optionquery[1]=Q_gameKey;
  xrm_search(resourcedb,optionquery,optionquery,2,cb_1,game_bindings);
  optionquery[1]=Q_editClick;
  xrm_search(resourcedb,optionquery,optionquery,2,cb_1,editor_mouse_bindings);
  optionquery[1]=Q_gameClick;
  xrm_search(resourcedb,optionquery,optionquery,2,cb_1,game_mouse_bindings);
  fprintf(stderr,"Done\n");
  printStatus("Done\n");
}

const UserCommand*find_key_binding(SDL_Event*ev,int editing) {
  KeyBinding*kb;
  static const UserCommand nul={cmd:0};
  SDLMod m;
  int i;

Modified class.c from [7edc77ca68] to [fe260125ee].

2558
2559
2560
2561
2562
2563
2564
2565

2566
2567
2568
2569
2570
2571
2572
2558
2559
2560
2561
2562
2563
2564

2565
2566
2567
2568
2569
2570
2571
2572







-
+








void load_classes(void) {
  int i;
  int gloptr=0;
  Hash*glolocalhash;
  char*nam=sqlite3_mprintf("%s.class",basefilename);
  sqlite3_stmt*vst=0;
  fprintf(stderr,"Loading class definitions...\n");
  printStatus("Loading class definitions...\n");
  if(!nam) fatal("Allocation failed\n");
  classfp=main_options['z']?composite_slice(".class",1):fopen(nam,"r");
  sqlite3_free(nam);
  if(!classfp) fatal("Cannot open class file '%s': %m\n",nam);
  glohash=calloc(HASH_SIZE,sizeof(Hash));
  if(!glohash) fatal("Allocation failed\n");
  glolocalhash=calloc(LOCAL_HASH_SIZE,sizeof(Hash));
2778
2779
2780
2781
2782
2783
2784
2785

2786
2778
2779
2780
2781
2782
2783
2784

2785
2786







-
+

  if(macros) for(i=0;i<MAX_MACRO;i++) if(macros[i]) free_macro(macros[i]);
  free(macros);
  if(array_size) {
    array_data=malloc(array_size*sizeof(Value));
    if(!array_data) fatal("Array allocation failed\n");
  }
  if(norders) set_class_orders();
  fprintf(stderr,"Done\n");
  printStatus("Done\n");
}

Modified comconfig.doc from [0c26897a26] to [06f1d3453e].

23
24
25
26
27
28
29




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







+
+
+
+







  Size of local hash table when reading class definition file. This must
  be less than 65535.

CONFIG_NO_PORTABLE
  If defined, then portable mode by checking argv[0] is disabled. (It is
  still possible to use portable mode by HEROMESH_PREFIX)

CONFIG_NO_STATUS
  If defined, then most status output is omitted unless -v is specified.
  (Some status output, such as most error messages, are still displayed.)

CONFIG_OMIT_SOUND
  If defined, omit all sound capabilities (including music). (Even if it
  is not defined, it can still be disabled at runtime.)

CONFIG_USING_32BIT_TIMESTAMPS
  If defined, force use of 32-bit timestamps. (This is needed in order to
  avoid compiler warnings on some systems, such as some versions of the
47
48
49
50
51
52
53




54
55
56
57
58




59
60
61
62
63
64
65
66
67
68











69
70
71
72

73
74
75
76
77
78
79
80
81
82
83





84
85
86
87
88



89
90
91
92
93
94
95
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87
88
89
90
91
92
93

94





95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120







+
+
+
+





+
+
+
+









-
+
+
+
+
+
+
+
+
+
+
+



-
+
-
-
-
-
-






+
+
+
+
+





+
+
+









=== Unimplemented options ===

The below options are not implemented and are subject to being changed
in future when they are implemented.

CONFIG_DOUBLE_PRECISION_AUDIO
  If defined, use double precision for some math calculations in audio
  processing. Some calculations are not affected by this option.

CONFIG_ERROR_CHECKING
  Define error checking level, where 9 is maximum. Lower numbers might
  improve speed but may make the program crash in some cases and may also
  cause security vulnerabilities.

CONFIG_EXTRA_SCREEN_INIT
  Can be a C code to be executed after the video mode is set, but before
  any other screen initialization is done.

CONFIG_LAUNCHER_PATH
  If defined, then it is the full path to a file to execute if Free Hero
  Mesh has been invoked with no command-line arguments, or if it is given
  the flag to run the launcher program instead.

CONFIG_MULTIUSER_SCORES
  (Meant for storing scores on a multiuser system, somehow)

CONFIG_OMIT_EDITOR
  If defined, omit the level editor and picture editor.
  If defined, omit the level editor and picture editor, as well as the
  ability to import and export levels and pictures.

CONFIG_OMIT_GUI
  If defined, omit the GUI. Autotest mode can still be used, and the
  batch import/export works if CONFIG_OMIT_EDITOR is not defined. Any
  other feature which does not require the GUI also can still be used.

CONFIG_OMIT_MBCS
  If defined, omit the capability of multibyte character encodings. (This
  only affects displaying text, not the behaviour of the game.)

CONFIG_OMIT_MUSIC
  If defined, omit background music playback capabilities. (Even if this
  is not defined, it can still be disabled at runtime.
  is not defined, it can still be disabled at runtime.)

CONFIG_PRIVATE_USERCACHE
  If defined as a octal number, set the default file permissions of the
  user cache database when creating it. (The user can still change them
  afterward by using chmod.)

CONFIG_RANDOM_SOURCE
  Device to read random numbers from instead of using the random number
  generator built in to SQLite. (This will override the definition of the
  SQL RANDOM() function if it is defined.)

CONFIG_USERCACHE_PERMISSIONS
  If defined as a octal number, set the default file permissions of the
  user cache database when creating it. (The user can still change them
  afterward by using chmod.)

CONFIG_USING_APPIMAGE
  If defined, it will check the environment variables having to do with
  AppImage and will be able to load the default resources from there, as
  well as allow the configuration file to reference the AppImage directory.

CONFIG_USING_ARM_NEON
  If defined, use ARM NEON extensions. This only works on ARM.

CONFIG_USING_BSD_FUNCTIONS
  If defined, use BSD functions (such as funopen) instead of GNU functions
  (such as fopencookie), by adding emulations into the program. (It is
  still necessary to use a C compiler with GNU extensions though, even if
  the GNU library is not available.)

CONFIG_USING_SDL12_COMPAT
103
104
105
106
107
108
109





110
111
112
113
114
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144







+
+
+
+
+





  some parts of the program to improve compatibility.)

CONFIG_USING_X86_BMI2
  If defined, use PDEP and PEXT instructions. This only works on x86 and
  only on some processor models. (Apparently this is fast on Intel but slow
  on AMD, so it should not be used on AMD, even if it is available.)

CONFIG_WITH_NETWORK
  If defined, include code for network/internet access. Even if this is
  defined, it must still be enabled by the end user; it will not connect
  to any remote services unless the user explicitly commands it to do so.

CONFIG_WITH_VIDEO_RECORDING
  If defined, then include code to implement video recording, which will
  override some of the SDL functions (and some other functions), and might
  make them more slowly even if the video recording is not enabled.

Modified commandline.doc from [0d7234c266] to [91980e1714].

127
128
129
130
131
132
133



134
127
128
129
130
131
132
133
134
135
136
137







+
+
+

not end with a slash, it will be a prefix to the file name too).

3. If argv[0] contains a forward slash, use portable mode; it will use
files "current.heromeshrc" and "current.heromeshsession" in the directory
where the executable file is allegedly found.

4. Otherwise, home mode is used.

Determining portable mode by argv[0] can be disabled at compile-time. Even
if it is disabled, HEROMESH_PREFIX environment variable can still be used.

Modified function.c from [793458f469] to [311098a0c7].

1714
1715
1716
1717
1718
1719
1720
1721

1722
1723
1724
1725
1726
1727
1728
1714
1715
1716
1717
1718
1719
1720

1721
1722
1723
1724
1725
1726
1727
1728







-
+







  const unsigned char*d;
  unsigned char*p;
  int i,j;
  long n;
  int txn=sqlite3_get_autocommit(userdb)?sqlite3_exec(userdb,"BEGIN;",0,0,0):1;
  if(!levels_schema) return SQLITE_CORRUPT_VTAB;
  if(screen) set_cursor(XC_coffee_mug);
  fprintf(stderr,"Loading level table...\n");
  printStatus("Loading level table...\n");
  if(sqlite3_exec(userdb,levels_schema,0,0,0)) {
    err: fatal("SQL error while loading LEVELS table: %s\n",sqlite3_errmsg(userdb));
  }
  if(sqlite3_prepare_v2(userdb,"SELECT `LEVEL`, IFNULL(`DATA`,READ_LUMP_AT(`OFFSET`,?1)), `USERSTATE` FROM `USERCACHEDATA`"
   " WHERE `FILE` = LEVEL_CACHEID() AND `LEVEL` NOT NULL AND `LEVEL` >= 0 ORDER BY `LEVEL`;",-1,&st1,0))
   goto err;
  // ?1=ID, ?2=CODE, ?3=WIDTH, ?4=HEIGHT, ?5=TITLE, ?6=SOLVED, ?7=SOLVABLE
1773
1774
1775
1776
1777
1778
1779
1780

1781
1782
1783
1784
1785
1786
1787
1773
1774
1775
1776
1777
1778
1779

1780
1781
1782
1783
1784
1785
1786
1787







-
+







    sqlite3_bind_int(st2,2,level_index[j]);
    while((i=sqlite3_step(st2))==SQLITE_ROW);
    if(i!=SQLITE_DONE) goto err;
  }
  sqlite3_finalize(st2);
  sqlite3_exec(userdb,"CREATE UNIQUE INDEX `LEVELS_ORD` ON `LEVELS`(`ORD`) WHERE `ORD` NOT NULL;",0,0,0);
  if(!txn) sqlite3_exec(userdb,"COMMIT;",0,0,0);
  fprintf(stderr,"Done\n");
  printStatus("Done\n");
  if(screen) set_cursor(XC_arrow);
  return SQLITE_SCHEMA;
}

Module(vt_levels,
  .xConnect=vt1_levels_connect,
  .xOpen=vt1_levels_open,

Modified heromesh.h from [8560862773] to [fb2fb6b1fb].

1
2
3
4
5
6
7






8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20







+
+
+
+
+
+







/*
  This file is part of Free Hero Mesh and is public domain.
*/

#include "comconfig.h"

// == main ==

#ifdef CONFIG_NO_STATUS
#define printStatus(...) do{ if(main_options['v']) fprintf(stderr,__VA_ARGS__); }while(0)
#else
#define printStatus(...) fprintf(stderr,__VA_ARGS__)
#endif

#define fatal(...) do{ fprintf(stderr,"FATAL: " __VA_ARGS__); exit(1); }while(0)
#define boolxrm(a,b) (*a=='1'||*a=='y'||*a=='t'||*a=='Y'||*a=='T'?1:*a=='0'||*a=='n'||*a=='f'||*a=='N'||*a=='F'?0:b)

#define TY_NUMBER 0
#define TY_CLASS 1
#define TY_MESSAGE 2

Modified main.c from [d5598f7687] to [71b6e89339].

564
565
566
567
568
569
570
571

572
573
574
575
576

577
578
579
580
581
582
583
584
585
586

587
588
589
590
591
592
593
564
565
566
567
568
569
570

571
572
573
574
575

576
577
578
579
580
581
582
583
584
585

586
587
588
589
590
591
592
593







-
+




-
+









-
+







  if(e!=SQLITE_DONE) fatal("SQL error (%d): %s\n",e,sqlite3_errmsg(userdb));
  sqlite3_finalize(st);
}

static void flush_usercache(void) {
  int e;
  if(main_options['r']) return;
  fprintf(stderr,"Flushing user cache...\n");
  printStatus("Flushing user cache...\n");
  if(e=sqlite3_exec(userdb,"BEGIN;",0,0,0)) fatal("SQL error (%d): %s\n",e,sqlite3_errmsg(userdb));
  flush_usercache_1(FIL_LEVEL);
  flush_usercache_1(FIL_SOLUTION);
  if(e=sqlite3_exec(userdb,"COMMIT;",0,0,0)) fatal("SQL error (%d): %s\n",e,sqlite3_errmsg(userdb));
  fprintf(stderr,"Done\n");
  printStatus("Done\n");
}

static void init_composite(void) {
  FILE*fp=compositefp=fopen(basefilename,"r");
  sqlite3_stmt*st;
  sqlite3_int64 t1,t2;
  int z;
  struct stat fst;
  if(!fp) fatal("Cannot open '%s' for reading: %m\n",basefilename);
  fprintf(stderr,"Loading puzzle set...\n");
  printStatus("Loading puzzle set...\n");
  if(z=sqlite3_exec(userdb,"BEGIN;",0,0,0)) fatal("SQL error (%d): %s\n",z,sqlite3_errmsg(userdb));
  if(z=sqlite3_prepare_v2(userdb,"SELECT `ID`, `TIME` FROM `USERCACHEINDEX` WHERE `NAME` = CHAR(?2)||'//'||?1;",-1,&st,0)) fatal("SQL error (%d): %s\n",z,sqlite3_errmsg(userdb));
  basefilename=realpath(basefilename,0);
  if(!basefilename) fatal("Cannot find real path of puzzle set: %m\n");
  sqlite3_bind_text(st,1,basefilename,-1,0);
  levelfp=composite_slice(".level",1);
  solutionfp=composite_slice(".solution",1);
624
625
626
627
628
629
630
631

632
633
634
635
636
637
638
639
640
641
642

643
644
645
646
647
648
649
624
625
626
627
628
629
630

631
632
633
634
635
636
637
638
639
640
641

642
643
644
645
646
647
648
649







-
+










-
+







    sqlite3_free(p);
  }
  if(z=sqlite3_prepare_v3(userdb,"SELECT `OFFSET`, CASE WHEN ?3 THEN `USERSTATE` ELSE `DATA` END "
   "FROM `USERCACHEDATA` WHERE `FILE` = ?1 AND `LEVEL` = ?2;",-1,SQLITE_PREPARE_PERSISTENT,&readusercachest,0)) {
    fatal("SQL error (%d): %s\n",z,sqlite3_errmsg(userdb));
  }
  if(z=sqlite3_exec(userdb,"COMMIT;",0,0,0)) fatal("SQL error (%d): %s\n",z,sqlite3_errmsg(userdb));
  fprintf(stderr,"Done\n");
  printStatus("Done\n");
}

static void init_usercache(void) {
  sqlite3_stmt*st;
  int z;
  sqlite3_int64 t1,t2;
  char*nam1;
  char*nam2;
  char*nam3;
  struct stat fst;
  fprintf(stderr,"Initializing user cache...\n");
  printStatus("Initializing user cache...\n");
  if(z=sqlite3_exec(userdb,"BEGIN;",0,0,0)) fatal("SQL error (%d): %s\n",z,sqlite3_errmsg(userdb));
  if(z=sqlite3_prepare_v2(userdb,"SELECT `ID`, `TIME` FROM `USERCACHEINDEX` WHERE `NAME` = ?1;",-1,&st,0)) fatal("SQL error (%d): %s\n",z,sqlite3_errmsg(userdb));
  nam1=sqlite3_mprintf("%s.level",basefilename);
  if(!nam1) fatal("Allocation failed\n");
  nam2=realpath(nam1,0);
  if(!nam2) fatal("Cannot find real path of '%s': %m\n",nam1);
  levelfp=fopen(nam2,main_options['r']?"r":"r+");
687
688
689
690
691
692
693
694

695
696
697
698
699
700
701
687
688
689
690
691
692
693

694
695
696
697
698
699
700
701







-
+







  free(nam2);
  free(nam3);
  if(z=sqlite3_prepare_v3(userdb,"SELECT `OFFSET`, CASE WHEN ?3 THEN `USERSTATE` ELSE `DATA` END "
   "FROM `USERCACHEDATA` WHERE `FILE` = ?1 AND `LEVEL` = ?2;",-1,SQLITE_PREPARE_PERSISTENT,&readusercachest,0)) {
    fatal("SQL error (%d): %s\n",z,sqlite3_errmsg(userdb));
  }
  if(z=sqlite3_exec(userdb,"COMMIT;",0,0,0)) fatal("SQL error (%d): %s\n",z,sqlite3_errmsg(userdb));
  fprintf(stderr,"Done\n");
  printStatus("Done\n");
}

static void new_puzzle_set(void) {
  char*nam1;
  char*nam2;
  nam1=sqlite3_mprintf("%s.level",basefilename);
  if(!nam1) fatal("Allocation failed\n");
1089
1090
1091
1092
1093
1094
1095
1096

1097
1098
1099
1100
1101
1102
1103
1089
1090
1091
1092
1093
1094
1095

1096
1097
1098
1099
1100
1101
1102
1103







-
+







  while(argc>optind && argv[optind][0]=='-') {
    int i;
    const char*s=argv[optind++];
    if(s[1]=='-' && !s[2]) break;
    for(i=1;s[i];i++) main_options[s[i]&127]=1;
  }
  setbuf(stderr,0);
  if(!main_options['c']) fprintf(stderr,"FREE HERO MESH\n");
  if(!main_options['c']) printStatus("FREE HERO MESH\n");
  if(argc<=optind) fatal("usage: %s [switches] [--] basename [options...]\n",argc?argv[0]:"heromesh");
  if(xrm_init(realloc)) fatal("Failed to initialize resource manager\n");
  if(xrm_init_quarks(global_quarks)) fatal("Failed to initialize resource manager\n");
  resourcedb=xrm_create();
  if(!resourcedb) fatal("Allocation of resource database failed\n");
  basefilename=argv[optind++];
  if(argc>optind && argv[1][0]=='=') {
1177
1178
1179
1180
1181
1182
1183
1184

1185
1186
1187
1188
1189
1190
1191
1177
1178
1179
1180
1181
1182
1183

1184
1185
1186
1187
1188
1189
1190
1191







-
+







      if(main_options['f']) flush_usercache();
      return 0;
    } else if(main_options['f']) {
      if(main_options['r']) fatal("Cannot flush user cache; puzzle set is read-only\n");
      flush_usercache();
      return 0;
    }
    fprintf(stderr,"Ready for executing SQL statements.\n");
    printStatus("Ready for executing SQL statements.\n");
    no_dead_anim=1;
    do_sql_mode();
    return 0;
  }
  set_autosave();
  for(;;) { if(main_options['e']) run_editor(); else run_game(); }
}

Modified picedit.c from [583dab5e00] to [e191836d4c].

209
210
211
212
213
214
215
216

217
218
219
220
221
222
223
209
210
211
212
213
214
215

216
217
218
219
220
221
222
223







-
+







    "BEGIN;"
    "CREATE TEMPORARY TABLE `PICEDIT`(`ID` INTEGER PRIMARY KEY,`NAME` TEXT NOT NULL COLLATE NOCASE,`TYPE` INT,`DATA` BLOB);"
    "CREATE INDEX `PICEDIT_I1` ON `PICEDIT`(`NAME`,`TYPE`);"
  ,0,0,0);
  if(i) fatal("SQL error (%d): %s\n",i,sqlite3_errmsg(userdb));
  nam=sqlite3_mprintf("%s.xclass",basefilename);
  if(!nam) fatal("Allocation failed\n");
  fprintf(stderr,"Loading pictures...\n");
  printStatus("Loading pictures...\n");
  fp=fopen(nam,"r");
  sqlite3_free(nam);
  if(!fp) {
    nam=0;
    fprintf(stderr,"%m\n");
    goto done;
  }
255
256
257
258
259
260
261
262

263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282

283
284
285
286
287
288
289
255
256
257
258
259
260
261

262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281

282
283
284
285
286
287
288
289







-
+



















-
+







    if(i!=SQLITE_DONE) fatal("SQL error (%d): %s\n",i,sqlite3_errmsg(userdb));
  }
done:
  if(st) sqlite3_finalize(st);
  if(fp) fclose(fp);
  free(nam);
  free(buf);
  fprintf(stderr,"Done\n");
  printStatus("Done\n");
  sqlite3_exec(userdb,
    "CREATE TRIGGER `PICEDIT_T1` BEFORE INSERT ON `PICEDIT` BEGIN"
    "  SELECT RAISE(FAIL,'Duplicate name') FROM `PICEDIT` WHERE REPLACE(`NAME`||'*','.IMG*','.DEP*')=REPLACE(NEW.`NAME`||'*','.IMG*','.DEP*');"
    "END;"
    "CREATE TRIGGER `PICEDIT_T2` BEFORE UPDATE OF `NAME` ON `PICEDIT` BEGIN"
    "  SELECT RAISE(FAIL,'Duplicate name') FROM `PICEDIT` WHERE REPLACE(`NAME`||'*','.IMG*','.DEP*')=REPLACE(NEW.`NAME`||'*','.IMG*','.DEP*');"
    "END;"
  ,0,0,0);
  return r;
}

static void save_picture_file(void) {
  sqlite3_stmt*st;
  FILE*fp;
  char*s=sqlite3_mprintf("%s.xclass",basefilename);
  int i;
  const char*nam;
  const char*buf;
  if(!s) fatal("Allocation failed\n");
  fprintf(stderr,"Saving pictures...\n");
  printStatus("Saving pictures...\n");
  fp=fopen(s,"w");
  if(!fp) fatal("Cannot open picture file for writing: %m\n");
  sqlite3_free(s);
  i=sqlite3_prepare_v2(userdb,"SELECT `NAME`,`DATA` FROM `PICEDIT`;",-1,&st,0);
  if(i) fatal("SQL error (%d): %s\n",i,sqlite3_errmsg(userdb));
  while((i=sqlite3_step(st))==SQLITE_ROW) {
    nam=sqlite3_column_text(st,0);
297
298
299
300
301
302
303
304

305
306
307
308
309
310
311
297
298
299
300
301
302
303

304
305
306
307
308
309
310
311







-
+







    fputc(i>>8,fp);
    if(i) fwrite(buf,1,i,fp);
  }
  if(i!=SQLITE_DONE) fprintf(stderr,"SQL error (%d): %s\n",i,sqlite3_errmsg(userdb));
done:
  if(st) sqlite3_finalize(st);
  if(fp) fclose(fp);
  fprintf(stderr,"Done\n");
  printStatus("Done\n");
}

static sqlite3_int64 ask_picture_id(const char*t) {
  sqlite3_stmt*st;
  const char*r=screen_prompt(t);
  int i;
  sqlite3_int64 id=0;

Modified picture.c from [292dc50f72] to [e253fa7409].

774
775
776
777
778
779
780
781

782
783
784
785
786
787
788
774
775
776
777
778
779
780

781
782
783
784
785
786
787
788







-
+







  Uint8 altImage;
  Uint8 havesize1[256];
  Uint16 havesize[256];
  char*nam=sqlite3_mprintf("%s.xclass",basefilename);
  const char*v;
  int i,j,n;
  if(!nam) fatal("Allocation failed\n");
  fprintf(stderr,"Loading pictures...\n");
  printStatus("Loading pictures...\n");
  fp=main_options['z']?composite_slice(".xclass",1):fopen(nam,"r");
  if(!fp) fatal("Failed to open xclass file (%m)\n");
  sqlite3_free(nam);
  optionquery[1]=Q_altImage;
  altImage=strtol(xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"0",0,10);
  optionquery[1]=Q_imageSize;
  v=xrm_get_resource(resourcedb,optionquery,optionquery,2);
894
895
896
897
898
899
900
901

902
903
904
905
906
907
908
894
895
896
897
898
899
900

901
902
903
904
905
906
907
908







-
+







    }
  }
  sqlite3_finalize(st);
  fclose(fp);
  SDL_SetColorKey(picts,SDL_SRCCOLORKEY|SDL_RLEACCEL,0);
done:
  if(n=sqlite3_exec(userdb,"COMMIT;",0,0,0)) fatal("SQL error (%d): %s\n",n,sqlite3_errmsg(userdb));
  fprintf(stderr,"Done\n");
  printStatus("Done\n");
}

void init_screen(void) {
  const char*v;
  int w,h,i;
  if(main_options['x']) return;
  if(!fontdata) fontdata=pcfont;

Modified sound.c from [feb9ba4e2f] to [f2bb0c2e49].

247
248
249
250
251
252
253
254

255
256
257
258
259
260
261
247
248
249
250
251
252
253

254
255
256
257
258
259
260
261







-
+







  if(!v) return;
  spec.freq=strtol(v,0,10);
  optionquery[2]=Q_buffer;
  v=xrm_get_resource(resourcedb,optionquery,optionquery,3);
  if(!v) return;
  spec.samples=strtol(v,0,10);
  if(!spec.freq || !spec.samples) return;
  fprintf(stderr,"Initializing audio...\n");
  printStatus("Initializing audio...\n");
  spec.channels=1;
  spec.format=AUDIO_S16SYS;
  spec.callback=audio_callback;
  if(SDL_InitSubSystem(SDL_INIT_AUDIO)) {
    fprintf(stderr,"Cannot initalize audio subsystem.\n");
    return;
  }
283
284
285
286
287
288
289
290

291
292
293
294
295
296
297
283
284
285
286
287
288
289

290
291
292
293
294
295
296
297







-
+







    for(i=0;i<190;i++) mmltuning[i]=f*pow(2.0,(i-96)/24.0);
    for(i=0;i<64;i++) mmltuning[i+190]=(((long long)(i+2))<<37)/spec.freq;
    optionquery[2]=Q_mmlTempo;
    if(v=xrm_get_resource(resourcedb,optionquery,optionquery,3)) i=strtol(v,0,10); else i=120;
    // Convert quarter notes per minute to samples per sixty-fourth note
    mmltempo=(spec.freq*60)/(i*16);
  }
  fprintf(stderr,"Done.\n");
  printStatus("Done.\n");
  wavesound=0;
  mmlpos=0;
  SDL_PauseAudio(0);
  sound_on=1;
}

static void set_mml(const unsigned char*s) {