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: |
3bac20132497bea833459eb750080adc |
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 | 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. 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 | > > > > > > > > | 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 | * 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. * 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. | > > | 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 | DisplayColumn*ll_disp; Uint8 ll_ndisp; DataColumn*ll_data; Uint8 ll_ndata; Uint8 ll_naggregate; Uint16*ll_code; #define HASH_SIZE 8888 #define LOCAL_HASH_SIZE 5555 typedef struct { Uint16 id; char*txt; } Hash; /* Global hash: | > > > > > > > > > | 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 | 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 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' | > | 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 | 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); 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); | > > > > > > > > > | 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 | /* This file is part of Free Hero Mesh and is public domain. */ // == 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 | > > | 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 | 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; | | | 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 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 | 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; static const char schema[]= "BEGIN;" | > > > | | 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("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 | unsigned char*level_title; Uint16*level_index; int level_nindex; char level_changed; FILE*levelfp; FILE*solutionfp; | | | 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 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 | 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; } 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; } 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) { | > > > > < | > > > | 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=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 | } if(n>=m) fatal("Too long SQL statement\n"); } if(n) fatal("Unterminated SQL statement\n"); free(txt); } | | | 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 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 | 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; | | | 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 CONFIG_WITH_STACK_PROTECTION stack_protect_mark=__builtin_frame_address(0); set_stack_protection(); #endif if(main_options['c']) { load_classes(); return 0; } |
︙ | ︙ |