Overview
Comment: | Implement level hashes calculation. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
a9af94f292aad2806d0f77ddc38cd975 |
User & Date: | user on 2022-08-11 20:11:07 |
Other Links: | manifest | tags |
Context
2022-08-17
| ||
01:15 | Implement hue/shade filter in dependent pictures. check-in: 0aa4ff0fdf user: user tags: trunk | |
2022-08-11
| ||
20:11 | Implement level hashes calculation. check-in: a9af94f292 user: user tags: trunk | |
04:38 | Ensure that class/message names made by {make} do not contain invalid characters. check-in: eaea2c00a7 user: user tags: trunk | |
Changes
Modified class.c from [dbf58fd0d2] to [2a869824f7].
︙ | ︙ | |||
643 644 645 646 647 648 649 650 651 652 653 654 655 656 | InputStack*nxt=inpstack; inpstack=malloc(sizeof(InputStack)); if(!inpstack) fatal("Allocation failed\n"); inpstack->classfp=classfp; inpstack->linenum=linenum; inpstack->next=nxt; linenum=1; if(*name=='.' || *name=='_' || *name=='-' || !*name || name[strspn(name,"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-abcdefghijklmnopqrstuvwxyz.")]) ParseError("Improper name of include file \"%s\"\n",name); if(main_options['z']) { if(strlen(name)<9 || memcmp(name-strlen(name),".include",8)) ParseError("Include file name doesn't end with .include\n"); classfp=composite_slice(name,0)?:fopen(name,"r"); } else { classfp=fopen(name,"r"); | > | 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 | InputStack*nxt=inpstack; inpstack=malloc(sizeof(InputStack)); if(!inpstack) fatal("Allocation failed\n"); inpstack->classfp=classfp; inpstack->linenum=linenum; inpstack->next=nxt; linenum=1; if(main_options['S']) fatal("Cannot use {include} with level hash calculation mode\n"); if(*name=='.' || *name=='_' || *name=='-' || !*name || name[strspn(name,"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-abcdefghijklmnopqrstuvwxyz.")]) ParseError("Improper name of include file \"%s\"\n",name); if(main_options['z']) { if(strlen(name)<9 || memcmp(name-strlen(name),".include",8)) ParseError("Include file name doesn't end with .include\n"); classfp=composite_slice(name,0)?:fopen(name,"r"); } else { classfp=fopen(name,"r"); |
︙ | ︙ |
Modified commandline.doc from [91980e1714] to [862853a4a5].
︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 31 32 33 | -M Write details of macro expansion to stdout. -O Write a solution Hamster archive with private solutions to stdout. -T Mode for testing some internal functions of Free Hero Mesh and SDL. You probably do not need to use this mode yourself. -U Enable unstable/experimental features. These features may change in future and may later be made not needing this switch; but for now you | > > > > > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | -M Write details of macro expansion to stdout. -O Write a solution Hamster archive with private solutions to stdout. -S Compute level hashes. The level hashes depend on the class definitions and on the level itself, except for the title. It does not depend on any other files, including other levels, nor the level number. -T Mode for testing some internal functions of Free Hero Mesh and SDL. You probably do not need to use this mode yourself. -U Enable unstable/experimental features. These features may change in future and may later be made not needing this switch; but for now you |
︙ | ︙ |
Modified config.doc from [b4646fa155] to [a7e06c877f].
︙ | ︙ | |||
74 75 76 77 78 79 80 81 82 83 84 85 86 87 | The window title to use in game mode. A tilde is replaced by the name of the puzzle set. .gamma Gamma setting. If this is set, colours are gamma corrected by the number specified here. The default setting is 1.0. .imageSize The picture size to use, up to 255. If the puzzle set contains pictures of the requested size, it will use those, otherwise it will try to make the pictures it does have larger by integer scaling; if that also does not work, then it is an error. .keyRepeat | > > > > > | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | The window title to use in game mode. A tilde is replaced by the name of the puzzle set. .gamma Gamma setting. If this is set, colours are gamma corrected by the number specified here. The default setting is 1.0. .hash Hash algorithm to use for some features; this must be one of the numbers for hash algorithms listed in the hash.h source file. Can be decimal, or hexadecimal if it starts with "0x". .imageSize The picture size to use, up to 255. If the puzzle set contains pictures of the requested size, it will use those, otherwise it will try to make the pictures it does have larger by integer scaling; if that also does not work, then it is an error. .keyRepeat |
︙ | ︙ |
Modified edit.c from [3f10c9de85] to [50c4e83094].
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include <stdlib.h> #include <string.h> #include "sqlite3.h" #include "smallxrm.h" #include "heromesh.h" #include "quarks.h" #include "cursorshapes.h" EditorRect editrect; typedef struct { Uint16 class; Uint8 img,dir; Value misc1,misc2,misc3; | > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include <stdlib.h> #include <string.h> #include "sqlite3.h" #include "smallxrm.h" #include "heromesh.h" #include "quarks.h" #include "cursorshapes.h" #include "hash.h" EditorRect editrect; typedef struct { Uint16 class; Uint8 img,dir; Value misc1,misc2,misc3; |
︙ | ︙ | |||
848 849 850 851 852 853 854 | case TY_CLASS: fprintf(fp," $%s",classes[v.u]->name); break; case TY_MESSAGE: fprintf(fp," %s%s",v.u<256?"":"#",v.u<256?standard_message_names[v.u]:messages[v.u-256]); case TY_LEVELSTRING: fprintf(fp," %%%u",(int)v.u); break; default: fprintf(fp," ???"); break; } } | | < < < < < < < < | | 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 | case TY_CLASS: fprintf(fp," $%s",classes[v.u]->name); break; case TY_MESSAGE: fprintf(fp," %s%s",v.u<256?"":"#",v.u<256?standard_message_names[v.u]:messages[v.u-256]); case TY_LEVELSTRING: fprintf(fp," %%%u",(int)v.u); break; default: fprintf(fp," ???"); break; } } static void export_level_stream(FILE*fp) { Uint32*p=playfield; int i; Uint32 n; Object*o; if(!main_options['S']) fprint_esc(fp,'@',level_title); fprintf(fp,"C %d\nD %d %d\n",level_code,pfwidth,pfheight); again: for(i=0;i<64*64;i++) { n=p[i]; while(n!=VOIDLINK) { o=objects[n]; fprintf(fp,"%d %d $%s %d",o->x,o->y,classes[o->class]->name,o->image); |
︙ | ︙ | |||
886 887 888 889 890 891 892 893 894 895 896 897 898 899 | fprintf(fp,"W\n"); goto again; } } else { fprintf(fp,"W\n"); } for(i=0;i<nlevelstrings;i++) fprint_esc(fp,'%',levelstrings[i]); pclose(fp); } static char*import_numbers(char*p,int*x,int*y) { if(!p) return 0; while(*p==' ' || *p=='\t') p++; if(*p<'0' || *p>'9') return 0; | > > > > > > > > > > > > | 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 | fprintf(fp,"W\n"); goto again; } } else { fprintf(fp,"W\n"); } for(i=0;i<nlevelstrings;i++) fprint_esc(fp,'%',levelstrings[i]); } static void export_level(const char*cmd) { FILE*fp; if(!cmd || !*cmd) return; fp=popen(cmd,"w"); if(!fp) { screen_message("Cannot open pipe"); return; } fprintf(fp,"; Free Hero Mesh exported level ID=%d ORD=%d\n",level_id,level_ord); export_level_stream(fp); pclose(fp); } static char*import_numbers(char*p,int*x,int*y) { if(!p) return 0; while(*p==' ' || *p=='\t') p++; if(*p<'0' || *p>'9') return 0; |
︙ | ︙ | |||
2040 2041 2042 2043 2044 2045 2046 | import_level("#"); if(nobjects) { save_level(); if(!feof(stdin)) new_level(); } } } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 | import_level("#"); if(nobjects) { save_level(); if(!feof(stdin)) new_level(); } } } static inline void hexout(const unsigned char*p,int n) { while(n--) printf("%02x",*p++); } void make_level_hashes(void) { char*v; FILE*in; FILE*out; unsigned char h1[128]; unsigned char h2[128]; long long alg; int hn,c,n; optionquery[1]=Q_hash; alg=strtol(xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"",0,0)?:HASH_SHA3_256; hn=hash_length(alg); if(hn<1 || hn>128) fatal("Hash algorithm not valid or too long: %llu (length %d)\n",alg,hn); // Class hash if(main_options['z']) { in=composite_slice(".class",1); } else { v=sqlite3_mprintf("%s.class",basefilename); if(!v) fatal("Allocation failed\n"); in=fopen(v,"r"); sqlite3_free(v); } if(!in) fatal("Cannot open class file\n"); out=hash_stream(alg,0,h1); if(!out) fatal("Allocation failed\n"); while((c=fgetc(in))!=EOF) { if(c=='\t') c=' '; if(c!='\r') fputc(c,out); } fclose(in); fclose(out); printf("-1 0 %llx ",alg); hexout(h1,hn); putchar('\n'); for(n=0;n<level_nindex;n++) { if(load_level(level_index[n])) fatal("Level load error\n"); out=hash_stream(alg,0,h2); if(!out) fatal("Allocation failed\n"); fprintf(out,"\x01%llx %x\n",alg,hn); fwrite(h1,1,hn,out); export_level_stream(out); fclose(out); printf("%d 0 %llx ",level_id,alg); hexout(h2,hn); putchar('\n'); } exit(0); } |
Modified heromesh.h from [fb2fb6b1fb] to [f41b1c99d8].
︙ | ︙ | |||
361 362 363 364 365 366 367 368 369 370 371 372 373 374 | } EditorRect; extern EditorRect editrect; void run_editor(void); void write_empty_level_set(FILE*); void batch_import(void); // == picedit == void run_picture_editor(void); // == sound == | > | 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 | } EditorRect; extern EditorRect editrect; void run_editor(void); void write_empty_level_set(FILE*); void batch_import(void); void make_level_hashes(void); // == picedit == void run_picture_editor(void); // == sound == |
︙ | ︙ |
Modified main.c from [71b6e89339] to [db5cb1b03f].
︙ | ︙ | |||
1111 1112 1113 1114 1115 1116 1117 | main_options['r']=1; } if(main_options['n'] && main_options['i']) fatal("Switches -n and -i are conflicting\n"); if(main_options['n'] || main_options['i']) { if(main_options['r']) fatal("Switches -r and -%c are conflicting\n",main_options['i']?'i':'n'); main_options['x']=1; } | | | 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 | main_options['r']=1; } if(main_options['n'] && main_options['i']) fatal("Switches -n and -i are conflicting\n"); if(main_options['n'] || main_options['i']) { if(main_options['r']) fatal("Switches -r and -%c are conflicting\n",main_options['i']?'i':'n'); main_options['x']=1; } if(main_options['a'] || main_options['O'] || main_options['S']) main_options['r']=main_options['x']=1; if(main_options['p']) main_options['r']=1; 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); |
︙ | ︙ | |||
1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 | if(level_ord>level_nindex) level_ord=level_nindex; log_if_error(load_level(-level_ord)); } optionquery[1]=Q_maxTrigger; max_trigger=strtol(xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"",0,10); if(main_options['a']) run_auto_test(); if(main_options['O']) export_private_solutions(); if(main_options['x']) { if(main_options['i']) { batch_import(); 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"); | > | 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 | if(level_ord>level_nindex) level_ord=level_nindex; log_if_error(load_level(-level_ord)); } optionquery[1]=Q_maxTrigger; max_trigger=strtol(xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"",0,10); if(main_options['a']) run_auto_test(); if(main_options['O']) export_private_solutions(); if(main_options['S']) make_level_hashes(); if(main_options['x']) { if(main_options['i']) { batch_import(); 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"); |
︙ | ︙ |
Modified man6/heromesh.6 from [fe215be8ba] to [fbe3c2a7bd].
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 | Dump all class data. .IP -H Dump the hash table. .IP -L Display all tokens being read from the class definition file. .IP -O Output a solution Hamster archive with private solutions to stdout and then terminate. .IP -U Enable experimental/unstable features. .IP -a Autotest levels, ensuring that the provided solution is valid. .IP -c Only load classes and then terminate. This can be used to verify that the class definition file does not contain syntax errors. | > > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | Dump all class data. .IP -H Dump the hash table. .IP -L Display all tokens being read from the class definition file. .IP -O Output a solution Hamster archive with private solutions to stdout and then terminate. .IP -S Compute level hashes. Level hashes depend only on the class definition and on the level being hashed, except the title. .IP -U Enable experimental/unstable features. .IP -a Autotest levels, ensuring that the provided solution is valid. .IP -c Only load classes and then terminate. This can be used to verify that the class definition file does not contain syntax errors. |
︙ | ︙ |