Overview
Comment: | Begin to implement multibyte character codes (it is not enough to be used, so far) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
9087ab78961938dad613c181bdef9124 |
User & Date: | user on 2023-04-28 18:02:10 |
Other Links: | manifest | tags |
Context
2023-05-09
| ||
20:06 | Implement (untested and incomplete) MBCS character substitutions in popups in exec.c. check-in: b39b71353a user: user tags: trunk | |
2023-04-28
| ||
18:02 | Begin to implement multibyte character codes (it is not enough to be used, so far) check-in: 9087ab7896 user: user tags: trunk | |
2023-03-31
| ||
17:21 | Fix {edit <number>} so that it replaces the entire argument if it begins with an opening delimiter ("{" or "("). check-in: 563de83a02 user: user tags: trunk | |
Changes
Modified class.c from [0574e75b7a] to [3f858bcddb].
︙ | ︙ | |||
50 51 52 53 54 55 56 57 58 59 60 61 62 63 | AnimationSlot anim_slot[8]; Uint8 keymask[256/8]; Uint16 array_size; Uint16*orders; Uint8 norders; Uint16 control_class; Uint8 has_xy_input; char*ll_head; DisplayColumn*ll_disp; Uint8 ll_ndisp; DataColumn*ll_data; Uint8 ll_ndata; Uint8 ll_naggregate; | > | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | AnimationSlot anim_slot[8]; Uint8 keymask[256/8]; Uint16 array_size; Uint16*orders; Uint8 norders; Uint16 control_class; Uint8 has_xy_input; Uint8 has_mbcs=0; char*ll_head; DisplayColumn*ll_disp; Uint8 ll_ndisp; DataColumn*ll_data; Uint8 ll_ndata; Uint8 ll_naggregate; |
︙ | ︙ | |||
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | if(!o->ref--) { free(o->str); free(o); } return p; } static void read_quoted_string(void) { int c,i,n; int isimg=0; for(i=0;i<0x1FFD;) { c=fgetc(classfp); if(c==EOF) { ParseError("Unterminated string literal\n"); } else if(c=='\\') { | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 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 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 | if(!o->ref--) { free(o->str); free(o); } return p; } #ifndef CONFIG_OMIT_MBCS static inline void valid_part_of_code(Uint8 b) { if(b<0x21 || b>0xFD || b==0x7F) ParseError("Improper TRON code\n"); } static Uint32 read_euc_tron_1(const Uint8*s,int*p) { Uint32 r=0; Uint8 h=0; int i=*p; int c=s[i++]; if(c==0x90 || c==0x91) h=c,c=s[i++]; while(c==0x80) r+=0x1000000,c=s[i++]; if(c<0xA1) ParseError("Improper TRON code\n"); if(h) { if(h==0x90) c-=0x40; r|=c<<16; } else { r|=(c-0x80)<<16; } c=s[i++]; if(c<0xA0) ParseError("Improper TRON code\n"); r|=(c<<8)|s[i++]; *p=i; return r; } static void convert_euctron_to_tron8(void) { static const Uint8 jisx[0x80]={ 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xA1, 0xA3,0xA4,0xA5,0xA8, 0xAC,0xAD,0xAE,0xAF, 0xEE,0xEF,0xF0,0xF1, 0xF2,0xF3,0xF4,0xF5, 0xF6,0xF7,0xF8,0xF9, 0xFA,0xFB,0xFC,0xFD, 0xFE,0x87,0x00,0x88, 0x89,0x8A,0x00,0x00, 0x8B,0x00,0x00,0x00, 0x8C,0x8D,0x8E,0x8F, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x90,0x91, 0x92,0x93,0x94,0x95, 0x96,0x97,0x98,0x99, 0x9A,0x9B,0x9C,0x9D, 0x9E,0x9F,0xA0,0x00, }; Uint8 s[0x2000]; int i,o,p,x,y; Uint32 c; strcpy(s,tokenstr); i=o=p=0; if(*s<=0x20) tokenstr[0]=0xFE,tokenstr[1]=p=0x21,o=2; while(i<0x1FFF && s[i] && o<0x1FFD) { if(s[i]==27) { i++; c=0; for(;;) switch(x=s[i++]) { case '0' ... '9': c=16*c+x-'0'; break; case 'A' ... 'F': c=16*c+x+10-'A'; break; case 'a' ... 'f': c=16*c+x+10-'a'; break; case ';': goto code; default: ParseError("Invalid \\T escape\n"); } } else if(s[i]<=32) { tokenstr[o++]=c=s[i++]; if(c==16 || c==31) { if(!s[i]) ParseError("Invalid string\n"); tokenstr[o++]=s[i++]; } else if(c==14 || c==30) { x=strcspn(s+i,"\\"); if(!s[i+x]) ParseError("Invalid string\n"); if(o+x+1>=0x1FFC) ParseError("Converted string too long\n"); memcpy(tokenstr+o,s+i,x+1); o+=x+1; } } else if(s[i]=='%') { tokenstr[o++]=0x7F; i++; x=s[i++]; if(!x) break; tokenstr[o++]=x; p=0; // ensure not being shifted to the wrong code set after a substitution } else if(s[i]<127) { // Note that the non-official plane 0x70 is used, rather than conversion to JIS or Unicode. // This might be changed in future to convert to JIS. c=0x702200+s[i++]; goto code; } else if(s[i]>=0x88 && s[i]<=0x8D) { x=s[i++]; c=read_euc_tron_1(s,&i); y=(c>>8)&0xFF; switch(x) { case 0x88: c-=0x8080; break; case 0x89: c-=0x0080; break; case 0x8A: c-=0x8000; break; case 0x8B: break; case 0x8C: c=(y<0xC0?c-0x2080:(c&~0xFFFF)+((c>>8)&0xFF)+(y<<8)-0x8040); break; case 0x8D: c=(y<0xC0?c-0x2000:y<0xE0?(c&~0xFFFF)+((c>>8)&0xFF)+(y<<8)-0x0040:c-0x6060); break; } goto code; } else if(s[i]==0x8E) { // Half width katakana; see comments in the (s[i]<127) block c=0x702300+s[i++]; goto code; } else if(s[i]==0x8F) { i++; if(!s[i] || !s[i+1]) break; x=s[i++]; if(!x) ParseError("Invalid TRON code\n"); c=s[i++]^((jisx[x&0x7F]?:x)<<8)^0x210080; goto code; } else { c=0x210000+(s[i++]<<8); if(s[i]<0x80) ParseError("Invalid EUC-JP character\n"); c+=s[i++]-0x8080; code: valid_part_of_code(c&0xFF); valid_part_of_code((c>>8)&0xFF); valid_part_of_code((c>>16)&0xFF); if((c>>16)!=p) { if(o+(c>>24)>=0x1FFB) ParseError("Converted string too long\n"); memset(tokenstr+o,0xFE,x=(c>>24)+1); o+=x; tokenstr[o++]=c>>16; } tokenstr[o++]=c>>8; tokenstr[o++]=c; } } tokenstr[o]=0; } #endif // CONFIG_OMIT_MBCS static void read_quoted_string(void) { char y=0; int c,i,n; int isimg=0; for(i=0;i<0x1FFD;) { c=fgetc(classfp); if(c==EOF) { ParseError("Unterminated string literal\n"); } else if(c=='\\') { |
︙ | ︙ | |||
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | if(c>='0' && c<='9') n|=c-'0'; else if(c>='A' && c<='F') n|=c+10-'A'; else if(c>='a' && c<='f') n|=c+10-'a'; else ParseError("Invalid string escape: \\x%X%c\n",n>>4,c); if(n<32) tokenstr[i++]=31; tokenstr[i++]=n?:255; break; default: ParseError("Invalid string escape: \\%c\n",c); } } else if(c=='"') { if(isimg) ParseError("Unterminated \\i escape in string literal\n"); tokenstr[i]=0; return; } else if(c!='\r') { tokenstr[i++]=c; if(c=='\n') ++linenum; } } ParseError("Too long string literal\n"); } static int name_compar(const void*a,const void*b) { const Op_Names*x=a; | > > > > > > > > > > > > > > | 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | if(c>='0' && c<='9') n|=c-'0'; else if(c>='A' && c<='F') n|=c+10-'A'; else if(c>='a' && c<='f') n|=c+10-'a'; else ParseError("Invalid string escape: \\x%X%c\n",n>>4,c); if(n<32) tokenstr[i++]=31; tokenstr[i++]=n?:255; break; #ifndef CONFIG_OMIT_MBCS case 'T': if(has_mbcs) { y=1; tokenstr[i++]=27; break; } // else fall through #endif default: ParseError("Invalid string escape: \\%c\n",c); } } else if(c=='"') { if(isimg) ParseError("Unterminated \\i escape in string literal\n"); tokenstr[i]=0; #ifndef CONFIG_OMIT_MBCS if(y) convert_euctron_to_tron8(); #endif return; } else if(c!='\r') { tokenstr[i++]=c; if(c=='\n') ++linenum; #ifndef CONFIG_OMIT_MBCS if((c&0x80) && has_mbcs) y=1; #endif } } ParseError("Too long string literal\n"); } static int name_compar(const void*a,const void*b) { const Op_Names*x=a; |
︙ | ︙ | |||
2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 | case OP_MISC5: define_user_flags(0x1020,0x103F); break; case OP_MISC6: define_user_flags(0x1040,0x105F); break; case OP_MISC7: define_user_flags(0x1060,0x107F); break; case OP_COLLISIONLAYERS: define_user_flags(0x1080,0x1087); break; case OP_CODEPAGE: nxttok(); if(tokent!=TF_INT || tokenv<1 || tokenv>0x7FFFFF) ParseError("Number from 1 to 8388607 expected\n"); set_code_page(tokenv); nxttok(); if(tokent!=TF_CLOSE) ParseError("Expected close parenthesis\n"); break; case OP_ORDER: if(norders) ParseError("Extra (Order) block\n"); parse_order_block(); | > | 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 | case OP_MISC5: define_user_flags(0x1020,0x103F); break; case OP_MISC6: define_user_flags(0x1040,0x105F); break; case OP_MISC7: define_user_flags(0x1060,0x107F); break; case OP_COLLISIONLAYERS: define_user_flags(0x1080,0x1087); break; case OP_CODEPAGE: nxttok(); if(tokent!=TF_INT || tokenv<1 || tokenv>0x7FFFFF) ParseError("Number from 1 to 8388607 expected\n"); if(tokenv==460800 || tokenv==954) has_mbcs=1; set_code_page(tokenv); nxttok(); if(tokent!=TF_CLOSE) ParseError("Expected close parenthesis\n"); break; case OP_ORDER: if(norders) ParseError("Extra (Order) block\n"); parse_order_block(); |
︙ | ︙ |
Modified class.doc from [ec268e12e1] to [9c6147b27a].
︙ | ︙ | |||
112 113 114 115 116 117 118 119 120 121 122 123 124 125 | \" Literal quotation mark. \\ Literal backslash. === Preprocessor === Free Hero Mesh includes a macro preprocessor, which you may use if wanted. All preprocessor commands are in braces; that constitutes a preprocessor token, which may contain other tokens as arguments. | > > > > > > | 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | \" Literal quotation mark. \\ Literal backslash. \Txxxxxx; Only valid when using multibyte character encoding. Follow \T by six or more hex digits and then a semicolon; this is like the "&T code" but is using a backslash instead of a ampersand. (This feature is not fully implemented yet.) === Preprocessor === Free Hero Mesh includes a macro preprocessor, which you may use if wanted. All preprocessor commands are in braces; that constitutes a preprocessor token, which may contain other tokens as arguments. |
︙ | ︙ |
Modified comconfig.doc from [0ab9c905fe] to [40fa378679].
︙ | ︙ | |||
43 44 45 46 47 48 49 50 51 52 53 54 55 56 | 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_INCLUDE If defined, then the {include} macro is not implemented. 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 | > > > > | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | 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_INCLUDE If defined, then the {include} macro is not implemented. 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_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 |
︙ | ︙ | |||
99 100 101 102 103 104 105 | 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. | < < < < | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | 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_MUSIC If defined, omit background music playback capabilities. (Even if this is not defined, it can still be disabled at runtime.) CONFIG_OMIT_PIPE If defined, then any features that use popen are omitted. Some operating systems may require this; otherwise, you should avoid using this. |
︙ | ︙ |
Modified heromesh.h from [a48c2379a0] to [cbb8688147].
︙ | ︙ | |||
191 192 193 194 195 196 197 198 199 200 201 202 203 204 | extern AnimationSlot anim_slot[8]; extern Uint8 keymask[256/8]; extern Uint16 array_size; extern Uint16*orders; extern Uint8 norders; extern Uint16 control_class; extern Uint8 has_xy_input; // zero if not, nonzero if it has typedef struct { // Flags: 1=fill-width, 2=multi-colours, 4=built-in-data Uint8 width,data,color,flag; Uint8 form[2]; Uint16 ptr; } DisplayColumn; | > | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | extern AnimationSlot anim_slot[8]; extern Uint8 keymask[256/8]; extern Uint16 array_size; extern Uint16*orders; extern Uint8 norders; extern Uint16 control_class; extern Uint8 has_xy_input; // zero if not, nonzero if it has extern Uint8 has_mbcs; // nonzero if multibyte character encoding is in use typedef struct { // Flags: 1=fill-width, 2=multi-colours, 4=built-in-data Uint8 width,data,color,flag; Uint8 form[2]; Uint16 ptr; } DisplayColumn; |
︙ | ︙ |
Modified internals.doc from [ef174d2e9e] to [3a19f06428].
︙ | ︙ | |||
128 129 130 131 132 133 134 135 136 137 138 139 140 141 | 1-8 (\0-\7) = Colours 10 (\n) = Line break 11 (\l) = Left 12 (\c) = Centre 14 (\i) = Icon 15 (\b) = Horizontal rule 16 (\q) = Quiz button 30 (\d) = Data 31 (\x) = Next byte is a character to display as graphic Codes 32-255 are displayed as is, but characters 1-31 cannot be displayed as a graphic unless a \x escape is present. | > | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | 1-8 (\0-\7) = Colours 10 (\n) = Line break 11 (\l) = Left 12 (\c) = Centre 14 (\i) = Icon 15 (\b) = Horizontal rule 16 (\q) = Quiz button 27 (\T) = Multibyte character escape; used only during parsing 30 (\d) = Data 31 (\x) = Next byte is a character to display as graphic Codes 32-255 are displayed as is, but characters 1-31 cannot be displayed as a graphic unless a \x escape is present. |
︙ | ︙ |