Overview
Comment: | Functions to convert between TRON-8 and TRON-32 (may be used in future for the text editor; currently unused, and may be removed if it is found to be unnecessary) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
198a84f8d88131c37fa8a45fcfbc627b |
User & Date: | user on 2023-07-15 02:07:34 |
Other Links: | manifest | tags |
Context
2023-07-16
| ||
19:46 | Change tron8to32 to handle multibyte characters only if has_mbcs is true. check-in: b175421418 user: user tags: trunk | |
2023-07-15
| ||
02:07 | Functions to convert between TRON-8 and TRON-32 (may be used in future for the text editor; currently unused, and may be removed if it is found to be unnecessary) check-in: 198a84f8d8 user: user tags: trunk | |
2023-07-11
| ||
06:59 | Implement new SQL functions GAMEOVER, LEVEL_CODE, and LEVEL_VERSION. check-in: 032593e3cb user: user tags: trunk | |
Changes
Modified TODO from [31818fb982] to [52cd578fb2].
1 2 3 4 5 6 7 8 9 10 | * Sound effects * Compressed wave sounds (?) * Numeric sounds (?) * Game engine features * String data (partially implemented) * A ,PopUp command to use a popup with arguments starting from a mark * Possibility to define auto-generation levels mode * Popup inventory list (with optional possibility of choice) (?) * Playfield array * Editor | > | 1 2 3 4 5 6 7 8 9 10 11 | * Sound effects * Compressed wave sounds (?) * Numeric sounds (?) * Band limited synthesis * Game engine features * String data (partially implemented) * A ,PopUp command to use a popup with arguments starting from a mark * Possibility to define auto-generation levels mode * Popup inventory list (with optional possibility of choice) (?) * Playfield array * Editor |
︙ | ︙ |
Modified heromesh.h from [cca2629b39] to [99be4437e4].
︙ | ︙ | |||
47 48 49 50 51 52 53 54 55 56 57 58 59 60 | #define ValueEq(x,y) ((x).t==(y).t && (x).u==(y).u) #define N_MESSAGES 30 #define N_STANDARD_SOUNDS 49 extern const char*const standard_message_names[]; extern const char*const standard_sound_names[]; extern const char*const heromesh_key_names[256]; extern sqlite3*userdb; extern xrm_db*resourcedb; extern const char*basefilename; extern xrm_quark optionquery[16]; extern char main_options[128]; extern Uint8 message_trace[0x4100/8]; | > | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | #define ValueEq(x,y) ((x).t==(y).t && (x).u==(y).u) #define N_MESSAGES 30 #define N_STANDARD_SOUNDS 49 extern const char*const standard_message_names[]; extern const char*const standard_sound_names[]; extern const char*const heromesh_key_names[256]; extern const char jispunct[]; extern sqlite3*userdb; extern xrm_db*resourcedb; extern const char*basefilename; extern xrm_quark optionquery[16]; extern char main_options[128]; extern Uint8 message_trace[0x4100/8]; |
︙ | ︙ | |||
87 88 89 90 91 92 93 94 95 96 97 98 99 100 | FILE*composite_slice(const char*suffix,char isfatal); unsigned char*read_lump_or_userstate(int sol,int lvl,long*sz,char us); void write_lump(int sol,int lvl,long sz,const unsigned char*data); void write_userstate(int sol,int lvl,long sz,const unsigned char*data); const char*load_level(int lvl); void set_cursor(int id); const char*log_if_error(const char*t); #define FIL_SOLUTION 1 #define FIL_LEVEL 0 #define LUMP_LEVEL_IDX (-1) #define LUMP_CLASS_DEF (-2) #define LUMP_DIVISION_IDX (-3) | > > | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | FILE*composite_slice(const char*suffix,char isfatal); unsigned char*read_lump_or_userstate(int sol,int lvl,long*sz,char us); void write_lump(int sol,int lvl,long sz,const unsigned char*data); void write_userstate(int sol,int lvl,long sz,const unsigned char*data); const char*load_level(int lvl); void set_cursor(int id); Uint32*tron8to32(const Uint8*); Uint8*tron32to8(const Uint32*); const char*log_if_error(const char*t); #define FIL_SOLUTION 1 #define FIL_LEVEL 0 #define LUMP_LEVEL_IDX (-1) #define LUMP_CLASS_DEF (-2) #define LUMP_DIVISION_IDX (-3) |
︙ | ︙ |
Modified internals.doc from [a66f2d8183] to [e83e2923f9].
︙ | ︙ | |||
140 141 142 143 144 145 146 147 148 149 150 151 152 153 | 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. | > > > > > > > > > > > > > > > > > > | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | 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) Internally a variant of TRON-32 may be used during text editing (N.B.: this feature is not implemented yet). In addition to TRON-32 characters, it also uses the following codes: * Control codes, with the same values and meanings listed above except 16, 27, 31, 254, and 255. * ASCII codes 0x20 to 0x7E. (These may sometimes be converted to/from the corresponding TRON characters, but are usually used within the text of a \i or \d escape, and as the terminator.) * Codes 0x1000 to 0x10FF for quiz buttons. * Codes 0x1F00 to 0x1FFF for graphic characters. * Codes 0x7F20 to 0x7F7E for substitution codes (which converts to the internal variant of TRON-8 as 127 and then the ASCII character). === User state data === The user state data for levels in the user cache database can be in the old format or the new format. |
︙ | ︙ |
Modified main.c from [db5cb1b03f] to [3ffe8990f0].
︙ | ︙ | |||
42 43 44 45 46 47 48 49 50 51 52 53 54 55 | "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, `MISC` BLOB);" "CREATE TEMPORARY TABLE `VARIABLES`(`ID` INTEGER PRIMARY KEY, `NAME` TEXT);" "CREATE TEMPORARY TABLE `DIVISIONS`(`HEADING` BLOB NOT NULL, `FIRST` INT NOT NULL);" "COMMIT;" ; sqlite3*userdb; xrm_db*resourcedb; const char*basefilename; xrm_quark optionquery[16]; char main_options[128]; Uint8 message_trace[0x4100/8]; | > > > > > > > > > | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | "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, `MISC` BLOB);" "CREATE TEMPORARY TABLE `VARIABLES`(`ID` INTEGER PRIMARY KEY, `NAME` TEXT);" "CREATE TEMPORARY TABLE `DIVISIONS`(`HEADING` BLOB NOT NULL, `FIRST` INT NOT NULL);" "COMMIT;" ; const char jispunct[0x60]= " ,.,. :;?! '` " "^~_ ---/" "\\~|| ''\"\"() []" "{}<> +- " " = <> '\" \\" "$ #%#&*@ " ; sqlite3*userdb; xrm_db*resourcedb; const char*basefilename; xrm_quark optionquery[16]; char main_options[128]; Uint8 message_trace[0x4100/8]; |
︙ | ︙ | |||
762 763 764 765 766 767 768 769 770 771 772 773 774 775 | } void set_cursor(int id) { id>>=1; if(!cursor[id]) cursor[id]=SDL_CreateCursor((void*)cursorimg+(id<<6),(void*)cursorimg+(id<<6)+32,16,16,cursorhot[id]>>4,cursorhot[id]&15); SDL_SetCursor(cursor[id]); } static void set_path(const char*arg) { const char*s; if(main_options['h']) goto home; if((s=getenv("HEROMESH_PREFIX")) && *s) { hpath=malloc(strlen(s)+32); if(!hpath) fatal("Allocation failed\n"); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 771 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 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 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 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 | } void set_cursor(int id) { id>>=1; if(!cursor[id]) cursor[id]=SDL_CreateCursor((void*)cursorimg+(id<<6),(void*)cursorimg+(id<<6)+32,16,16,cursorhot[id]>>4,cursorhot[id]&15); SDL_SetCursor(cursor[id]); } Uint32*tron8to32(const Uint8*si) { // This function does not interpret the internal-only 0xFF code, which will be implemented in picture.c instead. Uint16 cs=0; int n=0; Uint32*so=0; int k=0; if(*si==0xFE) { // TRON for(k=0;si[k];k++) { if(si[k]==31 && si[k+1]) { n+=2; k++; } else if(si[k]==14 || si[k]==30) { while(si[k] && si[k]!='\\') { n+=2; k++; } n+=2; } else if(si[k]==0xFE) { n--; while(si[k+1]==0xFE) k++; } else { n++; if(si[k]<=0x20) n++; } } so=calloc(sizeof(Uint32),(n>>=1)+2); if(!so) fatal("Allocation failed\n"); n++; k=0; while(*si && k<n) { if(*si==0xFE) { cs=-0x100; while(*si==0xFE) cs+=0x100,si++; if(*si) cs|=*si++; } else if((*si==16 || *si==31 || *si==127) && si[1]) { so[k++]=(si[0]<<8)|si[1]; si+=2; } else if(*si==14 || *si==30) { while(*si && *si!='\\' && *si!=0xFE) so[k++]=*si++; if(*si=='\\') so[k++]=*si++; } else if(*si<=0x20) { so[k++]=*si++; } else if(*si<0xFE && si[1]<0xFE && si[1]>0x20) { so[k++]=(si[0]<<8)|si[1]|(cs<<16); si+=2; } else { si++; } } } else { // ASCII so=calloc(sizeof(Uint32),(n=strlen(si))+1); if(!so) fatal("Allocation failed\n"); while(*si) { if(*si==16 || *si==31 || *si==127) { if(!si[1]) break; so[k++]=(si[0]<<8)|si[1]; si+=2; } else { so[k++]=*si++; } } } return so; } Uint8*tron32to8(const Uint32*si) { Uint16 cs=0; int i; Uint8*so=0; size_t sz=0; FILE*f=open_memstream((char**)&so,&sz); if(!f) fatal("Allocation failed\n"); for(i=0;si[i];i++) if(si[i]>0x200000) goto nonascii; while(*si) { if(*si<0x7F) { fputc(*si++,f); } else if(*si>=0x1000 && *si<=0x10FF) { fputc(16,f); fputc((*si++&0xFF)?:0x20,f); } else if(*si>=0x1F00 && *si<=0x1FFF) { fputc(31,f); fputc((*si++&0xFF)?:0xFF,f); } else if(*si>=0x7F20 && *si<0x7F7F) { fputc('%',f); fputc(*si++&0xFF,f); } } nonascii: while(*si) { if(*si>0x200000) { if(cs!=(*si>>16)) { cs=*si>>16; for(i=cs>>8;i>=0;i--) fputc(0xFE,f); fputc(cs,f); } fputc(*si>>8,f); fputc(*si++,f); } else if(*si<0x21) { fputc(i=*si++,f); if(i==14 || i==30) while(*si) { if(*si=='\\') { fputc(*si++,f); break; } else if(*si<0xFE || (*si>=0x702221 && *si<0x70227F) || (*si>=0x212330 && *si<0x21237B)) { fputc(*si++,f); } else if(*si>=0x212121 && *si<0x21217F) { fputc(jispunct[*si++-0x212120],f); } else if(*si<0xFE) { fputc(*si++,f); } else { fputc(' ',f); si++; } } } else if(*si<0x7F) { if(cs!=0x70) { cs=0x70; fputc(0xFE,f); fputc(0x70,f); } fputc(0x22,f); fputc(*si++,f); } else if(*si>=0x1000 && *si<=0x10FF) { fputc(16,f); fputc(*si++?:0x20,f); } else if(*si>=0x1F00 && *si<=0x1FFF) { fputc(31,f); fputc(*si++?:0xFF,f); } else if(*si>=0x7F20 && *si<0x7F7F) { fputc(127,f); fputc(*si++,f); } else { si++; } } fputc(0,f); fclose(f); if(!so) fatal("Allocation failed\n"); return so; } static void set_path(const char*arg) { const char*s; if(main_options['h']) goto home; if((s=getenv("HEROMESH_PREFIX")) && *s) { hpath=malloc(strlen(s)+32); if(!hpath) fatal("Allocation failed\n"); |
︙ | ︙ | |||
850 851 852 853 854 855 856 | SDL_UnlockSurface(screen); SDL_Flip(screen); while(SDL_WaitEvent(&ev)) switch(ev.type) { case SDL_KEYDOWN: switch(ev.key.keysym.sym) { case SDLK_BACKSPACE: n/=10; | < < | > > > > > > > > > > > > > > > > > > > > > | 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 | SDL_UnlockSurface(screen); SDL_Flip(screen); while(SDL_WaitEvent(&ev)) switch(ev.type) { case SDL_KEYDOWN: switch(ev.key.keysym.sym) { case SDLK_BACKSPACE: n/=10; goto setnum; case SDLK_SPACE: n=0; SDL_WM_SetCaption("0","0"); break; case SDLK_0 ... SDLK_9: n=10*n+ev.key.keysym.sym-SDLK_0; setnum: snprintf(buf,30,"%u",n); SDL_WM_SetCaption(buf,buf); break; case SDLK_KP_MINUS: if(n) n--; goto setnum; case SDLK_KP_PLUS: n++; goto setnum; case SDLK_c: SDL_FillRect(screen,0,n); SDL_Flip(screen); break; case SDLK_e: n=1; goto keytest; case SDLK_g: n=0; goto keytest; case SDLK_i: SDL_FillRect(screen,0,5); for(i=j=0;;i++) { if(picture_size*(i+1)>screen->w) i=0,j++; if(picture_size*(j+1)>screen->h) break; draw_picture(picture_size*i,picture_size*j,n++); } SDL_Flip(screen); break; case SDLK_o: if(n<0x4000 && classes[n] && classes[n]->gamehelp) { Uint32*a=tron8to32(classes[n]->gamehelp); Uint8*b=tron32to8(a); for(i=0;classes[n]->gamehelp[i];i++) printf("%02X ",classes[n]->gamehelp[i]&0xFF); puts(";"); for(i=0;a[i];i++) printf("%08X ",a[i]); puts(";"); for(i=0;b[i];i++) printf("%02X ",b[i]); puts("."); free(a); free(b); } break; case SDLK_p: sqlite3_exec(userdb,"SELECT * FROM `PICTURES`;",test_sql_callback,0,0); break; case SDLK_q: exit(0); break; |
︙ | ︙ | |||
1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 | return 0; } if(main_options['z']) init_composite(); load_pictures(); if(main_options['T']) { printf("argv[0] = %s\n",argv[0]); init_sound(); test_mode(); return 0; } if(main_options['n']) { new_puzzle_set(); return 0; } | > | 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 | return 0; } if(main_options['z']) init_composite(); load_pictures(); if(main_options['T']) { printf("argv[0] = %s\n",argv[0]); init_sound(); if(main_options['+']) load_classes(); test_mode(); return 0; } if(main_options['n']) { new_puzzle_set(); return 0; } |
︙ | ︙ |
Modified picture.c from [de04341ba7] to [f537a694cd].
︙ | ︙ | |||
986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 | if(!n) return; if(n==367) n=437; if(fontdata && fontdata!=pcfont) fatal("Multiple code page specifications\n"); optionquery[1]=Q_codepage; v=xrm_get_resource(resourcedb,optionquery,optionquery,2); if(!v || !*v) { if(n==437 || ignore_code_page()) return; fatal("Cannot load code page %d; code page file is not configured\n",n); } fp=fopen(v,"r"); if(!fp) { perror(0); fatal("Cannot open code page file\n"); } fontdata=d=malloc(0x800); if(!d) fatal("Allocation failed\n"); memcpy(d,pcfont,0x800); name: s=i=0; for(;;) { c=fgetc(fp); if(c<0) { if(n!=437 && !ignore_code_page()) fatal("Cannot find code page %d\n",n); goto done; } if(!c) break; if(!s) { if(c<'0' || c>'9') s=1; else if(c=='0' && !i) s=1; | > > > | 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 | if(!n) return; if(n==367) n=437; if(fontdata && fontdata!=pcfont) fatal("Multiple code page specifications\n"); optionquery[1]=Q_codepage; v=xrm_get_resource(resourcedb,optionquery,optionquery,2); if(!v || !*v) { if(n==437 || ignore_code_page()) return; if(main_options['T']) goto done; fatal("Cannot load code page %d; code page file is not configured\n",n); } fp=fopen(v,"r"); if(!fp) { perror(0); if(main_options['T']) goto done; fatal("Cannot open code page file\n"); } fontdata=d=malloc(0x800); if(!d) fatal("Allocation failed\n"); memcpy(d,pcfont,0x800); name: s=i=0; for(;;) { c=fgetc(fp); if(c<0) { if(main_options['T']) goto done; if(n!=437 && !ignore_code_page()) fatal("Cannot find code page %d\n",n); goto done; } if(!c) break; if(!s) { if(c<'0' || c>'9') s=1; else if(c=='0' && !i) s=1; |
︙ | ︙ |