Index: README ================================================================== --- README +++ README @@ -65,10 +65,18 @@ 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: @@ -105,10 +113,12 @@ * 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. Index: class.c ================================================================== --- class.c +++ class.c @@ -61,12 +61,21 @@ 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; ADDED comconfig.doc Index: comconfig.doc ================================================================== --- /dev/null +++ comconfig.doc @@ -0,0 +1,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 Index: comconfig.h ================================================================== --- /dev/null +++ comconfig.h @@ -0,0 +1,1 @@ +// This file intentionally left blank. Index: compile ================================================================== --- compile +++ compile @@ -28,10 +28,11 @@ 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' Index: game.c ================================================================== --- game.c +++ game.c @@ -1526,10 +1526,19 @@ 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); Index: heromesh.h ================================================================== --- heromesh.h +++ heromesh.h @@ -1,9 +1,11 @@ /* 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) @@ -56,11 +58,11 @@ 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 && ( \ Index: main.c ================================================================== --- main.c +++ main.c @@ -28,13 +28,16 @@ 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;" @@ -56,11 +59,11 @@ 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 @@ -771,26 +774,32 @@ 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); } @@ -1027,11 +1036,11 @@ } 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) { @@ -1113,11 +1122,11 @@ 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();