Free Hero Mesh

Check-in [3bac201324]
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 (partially) comconfig; also add back into game.c the ability to record solution timestamps (that was removed by mistake in the past), and improve documentation about compiling (in README file).
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 3bac20132497bea833459eb750080adc649e91fa
User & Date: user on 2022-07-18 06:38:56
Other Links: manifest | tags
Context
2022-07-19
18:03
Check if sqlite3_column_text returns a null pointer, in the levels_column function in game.c. check-in: e4569f54cc user: user tags: trunk
2022-07-18
06:38
Implement (partially) comconfig; also add back into game.c the ability to record solution timestamps (that was removed by mistake in the past), and improve documentation about compiling (in README file). check-in: 3bac201324 user: user tags: trunk
03:06
Change some dealing with IMG/DEP lumps; in future the MUL lumps may also be implemented. check-in: d1dcb9242a user: user tags: trunk
Changes

Modified README from [7afab18752] to [9221dc2b68].

63
64
65
66
67
68
69








70
71
72
73
74
75
76
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84







+
+
+
+
+
+
+
+







it as you wish.

If compiled with "./compile p" then it is installed as "bin/heromesh"
(relative to the current directory, which should be the directory where
the source files are) and installs "bin/current.heromeshrc" as well (if it
does not already exist; it won't overwrite an existing file). In this case,
it can be used as a "portable app" mode.

If compiled with "./compile" without "p", then it is installed in the "bin"
subdirectory of your home directory, by default. You can set the EXE
environment variable to override this.

You may edit comconfig.h (based on details on comconfig.doc) if you wish to
customize some of the compile options (other than those which are part of
the compiler itself, and the options mentioned above).

There are optional runtime features that may require other programs in
order to use them, but that you can ignore if you do not use them. Such
optional features include:

* If you want to import/export pictures, you will need an implementation
of farbfeld. ImageMagick 7 includes an implementation of farbfeld, so if
103
104
105
106
107
108
109


110
111
112
113
114
115
116
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126







+
+







* bindings.doc: Describes the configuration of key/mouse bindings.

* class.doc: This document describes the Free Hero Mesh programming
language. Read this if you want to define your own classes of objects.

* codepage.doc: Describes the use of code pages and the file format of the
codepage.har file.

* comconfig.doc: Compile-time configuration options.

* commandline.doc: Describes the command-line arguments. The man page
also describes the command-line arguments, although the commandline.doc
file has a more elaborate description.

* config.doc: Describes the configuration options for Free Hero Mesh.

Modified class.c from [1653acd7e0] to [b256a9488a].

59
60
61
62
63
64
65



66




67


68
69
70
71
72
73
74
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







+
+
+

+
+
+
+

+
+







DisplayColumn*ll_disp;
Uint8 ll_ndisp;
DataColumn*ll_data;
Uint8 ll_ndata;
Uint8 ll_naggregate;
Uint16*ll_code;

#ifdef CONFIG_GLOBAL_HASH_SIZE
#define HASH_SIZE CONFIG_GLOBAL_HASH_SIZE
#else
#define HASH_SIZE 8888
#endif
#ifdef CONFIG_LOCAL_HASH_SIZE
#define LOCAL_HASH_SIZE CONFIG_LOCAL_HASH_SIZE
#else
#define LOCAL_HASH_SIZE 5555
#endif

typedef struct {
  Uint16 id;
  char*txt;
} Hash;

/*
  Global hash:

Added comconfig.doc version [44f21afded].































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This file describes options that you can specify in comconfig.h (by the
#define command), in order to customize the compiled code. All of these
definitions are optional; default values will be used otherwise. (You can
also use -D switches for compiling to control them, too)


=== Implemented options ===

CONFIG_APPLICATION_ID
  Application ID for SQLite database files (if not defined, then the
  default value will be used). Should be a 32-bit integer represented in
  decimal notation, as a string token (not as a numeric token).

CONFIG_DEFAULT_RESOURCES
  If defined, read resource configuration from the specified file if
  it cannot find the configuration file in the home directory.

CONFIG_GLOBAL_HASH_SIZE
  Size of global hash table when reading class definition file.

CONFIG_LOCAL_HASH_SIZE
  Size of local hash table when reading class definition file.

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_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
  Raspberry Pi system. This option will be deprecated in year 2038, so
  you should upgrade your system before that if possible.)

CONFIG_WITH_STACK_PROTECTION
  If defined, allow stack protection to be included in the compiled code.
  (Otherwise, the configuration options dealing with stack protection
  will be ignored and will have no effect.) This requires that the GNU
  __builtin_frame_address function is available. (Note: This feature does
  not seem to work properly at this time. If you are able to fix it, then
  please provide a patch.)


=== Unimplemented options ===

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

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_MULTIUSER_SCORES
  (Meant for storing scores on a multiuser system, somehow)

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_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_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
  Define this if the program is to be compiled for use with the
  "sdl12-compat" SDL compatibility layer.

CONFIG_USING_SDLCL
  Define this if the program is to be compiled for use with the "sdlcl"
  SDL compatibility layer.

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

Added comconfig.h version [64d43e8634].


1
+
// This file intentionally left blank.

Modified compile from [1522779e22] to [bbdbdf26a2].

26
27
28
29
30
31
32

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







+







which node > /dev/null || touch -cm instruc.h names.h quarks.h
test instruc -nt instruc.h && node instruc.js > instruc.h
test instruc.js -nt instruc.h && node instruc.js > instruc.h
test names.js -nt names.h && node names.js > names.h
test names.js -nt instruc.h && node instruc.js > instruc.h
test quarks -nt quarks.h && node quarks.js > quarks.h
test quarks.js -nt quarks.h && node quarks.js > quarks.h
test comconfig.h -nt "$EXE" && rm bindings.o class.o picture.o function.o exec.o game.o edit.o picedit.o sound.o || true
test heromesh.h -nt "$EXE" && rm bindings.o class.o picture.o function.o exec.o game.o edit.o picedit.o sound.o || true
test instruc.h -nt "$EXE" && rm class.o exec.o || true
test pcfont.h -nt "$EXE" && rm picture.o || true
test quarks.h -nt "$EXE" && rm bindings.o edit.o exec.o game.o picture.o picedit.o || true
echo '* smallxrm'
test smallxrm.c -nt smallxrm.o && bash smallxrm.c
echo '* bindings'

Modified game.c from [05d4b7dc52] to [548c7bc0d9].

1524
1525
1526
1527
1528
1529
1530









1531
1532
1533
1534
1535
1536
1537
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546







+
+
+
+
+
+
+
+
+







  if(flag&128) {
    fputc(gameover_score,fp);
    fputc(gameover_score>>8,fp);
    fputc(gameover_score>>16,fp);
    fputc(gameover_score>>24,fp);
  }
  if(flag&1) fwrite(com,1,strlen(com+1),fp);
  if(flag&2) {
    time_t t=time(0);
    fputc(t>>000,fp); fputc(t>>010,fp); fputc(t>>020,fp); fputc(t>>030,fp);
#ifdef CONFIG_USING_32BIT_TIMESTAMPS
    fputc(0,fp); fputc(0,fp); fputc(0,fp); fputc(0,fp);
#else
    fputc(t>>040,fp); fputc(t>>050,fp); fputc(t>>060,fp); fputc(t>>070,fp);
#endif
  }
  n=replay_count;
  replay_count=replay_pos;
  encode_move_list(fp);
  replay_count=n;
  fclose(fp);
  if(!buf) fatal("Allocation failed\n");
  write_lump(FIL_SOLUTION,level_id,sz,buf);

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

1
2
3
4


5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
12
13




+
+







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

#include "comconfig.h"

// == main ==

#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
54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
56
57
58
59
60
61
62

63
64
65
66
67
68
69
70







-
+







extern unsigned char*level_title;
extern Uint16*level_index;
extern int level_nindex;
extern char level_changed; // 1 if solution is potentially invalidated by edits
extern FILE*levelfp;
extern FILE*solutionfp;

#ifdef __GNUC__
#ifdef CONFIG_WITH_STACK_PROTECTION
extern char stack_protect_mode;
extern void*stack_protect_mark;
extern void*stack_protect_low;
extern void*stack_protect_high;
#define StackProtection() (stack_protect_mode && ( \
  stack_protect_mode=='<' ? (__builtin_frame_address(0)<stack_protect_mark) : \
  stack_protect_mode=='>' ? (__builtin_frame_address(0)>stack_protect_mark) : \

Modified main.c from [efe30dc6d5] to [85ed0502be].

26
27
28
29
30
31
32



33
34
35

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

38
39
40
41
42
43
44
45







+
+
+


-
+








typedef struct {
  char a[(N_MESSAGES==sizeof(standard_message_names)/sizeof(*standard_message_names))?1:-9];
  char b[('\1\0'*'x'+'\0\1'*'y'=='xy')?1:-9];
  char c[(N_STANDARD_SOUNDS==sizeof(standard_sound_names)/sizeof(*standard_sound_names))?1:-9];
} ASSERTION;

#ifndef CONFIG_APPLICATION_ID
#define CONFIG_APPLICATION_ID "1296388936"
#endif
static const char schema[]=
  "BEGIN;"
  "PRAGMA APPLICATION_ID(1296388936);"
  "PRAGMA APPLICATION_ID("CONFIG_APPLICATION_ID");"
  "PRAGMA RECURSIVE_TRIGGERS(1);"
  "CREATE TABLE IF NOT EXISTS `USERCACHEINDEX`(`ID` INTEGER PRIMARY KEY, `NAME` TEXT, `TIME` INT);"
  "CREATE TABLE IF NOT EXISTS `USERCACHEDATA`(`ID` INTEGER PRIMARY KEY, `FILE` INT, `LEVEL` INT, `NAME` TEXT COLLATE NOCASE, `OFFSET` INT, `DATA` BLOB, `USERSTATE` BLOB);"
  "CREATE UNIQUE INDEX IF NOT EXISTS `USERCACHEDATA_I1` ON `USERCACHEDATA`(`FILE`, `LEVEL`);"
  "CREATE TRIGGER IF NOT EXISTS `USERCACHEINDEX_DELETION` AFTER DELETE ON `USERCACHEINDEX` BEGIN DELETE FROM `USERCACHEDATA` WHERE `FILE` = OLD.`ID`; END;"
  "CREATE TEMPORARY TABLE `PICTURES`(`ID` INTEGER PRIMARY KEY, `NAME` TEXT COLLATE NOCASE, `OFFSET` INT, `DEPENDENT` INT);"
  "CREATE TEMPORARY TABLE `VARIABLES`(`ID` INTEGER PRIMARY KEY, `NAME` TEXT);"
54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71







-
+







unsigned char*level_title;
Uint16*level_index;
int level_nindex;
char level_changed;
FILE*levelfp;
FILE*solutionfp;

#ifdef __GNUC__
#ifdef CONFIG_WITH_STACK_PROTECTION
char stack_protect_mode=0;
void*stack_protect_mark;
void*stack_protect_low;
void*stack_protect_high;
#endif

static const char*globalclassname;
769
770
771
772
773
774
775


776
777
778
779
780
781


782
783
784
785
786
787
788
789
790
791




792
793
794
795
796
797
798
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796


797
798
799
800
801
802
803
804
805
806
807







+
+






+
+








-
-
+
+
+
+







  if(main_options['h']) goto home;
  if((s=getenv("HEROMESH_PREFIX")) && *s) {
    hpath=malloc(strlen(s)+32);
    if(!hpath) fatal("Allocation failed\n");
    sprintf(hpath,"%s.heromeshrc",s);
    return;
  }
#ifndef CONFIG_NO_PORTABLE
#ifndef CONFIG_USING_APPIMAGE
  if(s=strrchr(arg,'/')) {
    hpath=malloc(s+64-arg);
    if(!hpath) fatal("Allocation failed\n");
    sprintf(hpath,"%.*s/current.heromeshrc",(int)(s-arg),arg);
    return;
  }
#endif
#endif
  home:
  s=getenv("HOME")?:".";
  hpath=malloc(strlen(s)+32);
  if(!hpath) fatal("Allocation failed\n");
  sprintf(hpath,"%s%s.heromeshrc",s,s[strlen(s)-1]=='/'?"":"/");
}

static void load_options(void) {
  FILE*fp;
  fp=fopen(hpath,"r");
  FILE*fp=fopen(hpath,"r");
#ifdef CONFIG_DEFAULT_RESOURCES
  if(!fp) fp=fopen(CONFIG_DEFAULT_RESOURCES,"r");
#endif
  if(!fp) fatal("Failed to open %s (%m)\n",hpath);
  if(xrm_load(resourcedb,fp,1)) fatal("Error while loading .heromeshrc\n");
  fclose(fp);
}

static void read_options(int argc,char**argv) {
  xrm_db*db=xrm_sub(resourcedb,0,xrm_make_quark(globalclassname,0)?:xrm_anyq);
1025
1026
1027
1028
1029
1030
1031
1032

1033
1034
1035
1036
1037
1038
1039
1034
1035
1036
1037
1038
1039
1040

1041
1042
1043
1044
1045
1046
1047
1048







-
+







    }
    if(n>=m) fatal("Too long SQL statement\n");
  }
  if(n) fatal("Unterminated SQL statement\n");
  free(txt);
}

#ifdef __GNUC__
#ifdef CONFIG_WITH_STACK_PROTECTION
static void test_stack_protection(void) {
  fprintf(stderr,"Stack protection final values: %p %p %p\n",stack_protect_mark,stack_protect_low,stack_protect_high);
}

static void set_stack_protection(void) {
  const char*v;
  optionquery[1]=Q_stackProtection;
1111
1112
1113
1114
1115
1116
1117
1118

1119
1120
1121
1122
1123
1124
1125
1120
1121
1122
1123
1124
1125
1126

1127
1128
1129
1130
1131
1132
1133
1134







-
+







  if(main_options['f']) main_options['x']=1;
  if(!main_options['c']) {
    set_path(argv[0]);
    load_options();
  }
  if(argc>optind) read_options(argc-optind,argv+optind);
  *optionquery=xrm_make_quark(globalclassname,0)?:xrm_anyq;
#ifdef __GNUC__
#ifdef CONFIG_WITH_STACK_PROTECTION
  stack_protect_mark=__builtin_frame_address(0);
  set_stack_protection();
#endif
  if(main_options['c']) {
    load_classes();
    return 0;
  }