Index: class.doc ================================================================== --- class.doc +++ class.doc @@ -2304,10 +2304,15 @@ %s Display a string. If the value is not a string, it will display it as whatever type it is. +%T + Only valid if this puzzle set uses MBCS. This is like %c but uses all of + the bits to make a TRON-32 character code. If the code is less than 256 + then this is the same as %c. (This is not fully implemented or tested.) + %u Display a unsigned decimal number. %x Display a unsigned hexadecimal number in lowercase. Index: exec.c ================================================================== --- exec.c +++ exec.c @@ -2098,10 +2098,11 @@ } return NVALUE(r); } static void v_set_popup(Uint32 from,int argc) { + unsigned char y='%'; const unsigned char*t; const unsigned char*u; sqlite3_str*s; Value v; int argi=1; @@ -2115,22 +2116,29 @@ if(argc) { argc++; if(v.t!=TY_STRING && v.t!=TY_LEVELSTRING) Throw("Type mismatch"); s=sqlite3_str_new(userdb); t=value_string_ptr(v); +#ifndef CONFIG_OMIT_MBCS + if(has_mbcs && *t==0xFE) y=0x7F; +#endif while(*t) { - if(u=strchr(t,'%')) { + if(u=strchr(t,y)) { sqlite3_str_append(s,t,u-t); t=u+2; +#ifndef CONFIG_OMIT_MBCS + if(y==0x7F) sqlite3_str_appendchar(s,1,0xFF); +#endif switch(u[1]) { case 0: t=u+1; break; case 'c': if(argi==argc) break; v=vstack[vstackptr+argi++]; if(v.t==TY_NUMBER) { + ascii: sqlite3_str_appendchar(s,1,31); sqlite3_str_appendchar(s,1,v.u&255?:255); } break; case 'C': @@ -2185,10 +2193,26 @@ case TY_MESSAGE: sqlite3_str_appendf(s,"%s",v.u<256?standard_message_names[v.u]:messages[v.u-256]); break; } break; +#ifndef CONFIG_OMIT_MBCS + case 'T': + if(argi==argc) break; + v=vstack[vstackptr+argi++]; + if(v.t==TY_NUMBER) { + if(v.u<256) goto ascii; + if(((v.u>>16)&0xFF)<0x21 || ((v.u>>16)&0xFF)==0x7F || ((v.u>>16)&0xFF)>0xFD) break; + if(((v.u>>8)&0xFF)<0x21 || ((v.u>>8)&0xFF)==0x7F || ((v.u>>8)&0xFF)>0xFD) break; + if(((v.u>>0)&0xFF)<0x21 || ((v.u>>0)&0xFF)==0x7F || ((v.u>>0)&0xFF)>0xFD) break; + sqlite3_str_appendchar(s,((v.u)>>24)+1,0xFE); + sqlite3_str_appendchar(s,1,v.u>>16); + sqlite3_str_appendchar(s,1,v.u>>8); + sqlite3_str_appendchar(s,1,v.u>>0); + } + break; +#endif case 'u': if(argi==argc) break; v=vstack[vstackptr+argi++]; if(v.t==TY_NUMBER) sqlite3_str_appendf(s,"%u",(unsigned int)v.u); break; Index: internals.doc ================================================================== --- internals.doc +++ internals.doc @@ -130,17 +130,23 @@ 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. +A few additional codes are only used in MBCS mode: + +27 (\T) = Multibyte character escape; used only during parsing +127 = Internal representation of % +254 = Plane shift +255 = Switch to ASCII until the next plane shift (internal only) + === User state data === The user state data for levels in the user cache database can be in the old format or the new format.