diff options
Diffstat (limited to 'util/alevt/lang.c')
-rw-r--r-- | util/alevt/lang.c | 393 |
1 files changed, 393 insertions, 0 deletions
diff --git a/util/alevt/lang.c b/util/alevt/lang.c new file mode 100644 index 0000000..3a49307 --- /dev/null +++ b/util/alevt/lang.c @@ -0,0 +1,393 @@ +#include <string.h> +#include <ctype.h> +#include "misc.h" +#include "vt.h" +#include "lang.h" + +int latin1 = -1; + + +static u8 lang_char[256]; +static u8 lang_chars[1+8+8][16] = +{ + { 0, 0x23,0x24,0x40,0x5b,0x5c,0x5d,0x5e,0x5f,0x60,0x7b,0x7c,0x7d,0x7e }, + + // for latin-1 font + // English (100%) + { 0, '£', '$', '@', '«', '½', '»', '¬', '#', '', '¼', '¦', '¾', '÷' }, + // German (100%) + { 0, '#', '$', '§', 'Ä', 'Ö', 'Ü', '^', '_', '°', 'ä', 'ö', 'ü', 'ß' }, + // Swedish/Finnish/Hungarian (100%) + { 0, '#', '¤', 'É', 'Ä', 'Ö', 'Å', 'Ü', '_', 'é', 'ä', 'ö', 'å', 'ü' }, + // Italian (100%) + { 0, '£', '$', 'é', '°', 'ç', '»', '¬', '#', 'ù', 'à', 'ò', 'è', 'ì' }, + // French (100%) + { 0, 'é', 'ï', 'à', 'ë', 'ê', 'ù', 'î', '#', 'è', 'â', 'ô', 'û', 'ç' }, + // Portuguese/Spanish (100%) + { 0, 'ç', '$', '¡', 'á', 'é', 'í', 'ó', 'ú', '¿', 'ü', 'ñ', 'è', 'à' }, + // Czech/Slovak (60%) + { 0, '#', 'u', 'c', 't', 'z', 'ý', 'í', 'r', 'é', 'á', 'e', 'ú', 's' }, + // reserved (English mapping) + { 0, '£', '$', '@', '«', '½', '»', '¬', '#', '', '¼', '¦', '¾', '÷' }, + + // for latin-2 font + // Polish (100%) + { 0, '#', 'ñ', '±', '¯', '¦', '£', 'æ', 'ó', 'ê', '¿', '¶', '³', '¼' }, + // German (100%) + { 0, '#', '$', '§', 'Ä', 'Ö', 'Ü', '^', '_', '°', 'ä', 'ö', 'ü', 'ß' }, + // Estonian (100%) + { 0, '#', 'õ', '©', 'Ä', 'Ö', '®', 'Ü', 'Õ', '¹', 'ä', 'ö', '¾', 'ü' }, + // Lettish/Lithuanian (90%) + { 0, '#', '$', '©', 'ë', 'ê', '®', 'è', 'ü', '¹', '±', 'u', '¾', 'i' }, + // French (90%) + { 0, 'é', 'i', 'a', 'ë', 'ì', 'u', 'î', '#', 'e', 'â', 'ô', 'u', 'ç' }, + // Serbian/Croation/Slovenian (100%) + { 0, '#', 'Ë', 'È', 'Æ', '®', 'Ð', '©', 'ë', 'è', 'æ', '®', 'ð', '¹' }, + // Czech/Slovak (100%) + { 0, '#', 'ù', 'è', '»', '¾', 'ý', 'í', 'ø', 'é', 'á', 'ì', 'ú', '¹' }, + // Rumanian (95%) + { 0, '#', '¢', 'Þ', 'Â', 'ª', 'Ã', 'Î', 'i', 'þ', 'â', 'º', 'ã', 'î' }, +}; + +/* Yankable latin charset :-) + !"#$%&'()*+,-./0123456789:;<=>? + @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ + `abcdefghijklmnopqrstuvwxyz{|}~ + ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ + ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß + àáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ +*/ + + +static struct mark { u8 *g0, *latin1, *latin2; } marks[16] = +{ + /* none */ { "#", + "¤", + "$" }, + /* grave - ` */ { " aeiouAEIOU", + "`àèìòùÀÈÌÒÙ", + "`aeiouAEIOU" }, + /* acute - ' */ { " aceilnorsuyzACEILNORSUYZ", + "'ácéílnórsúýzÁCÉÍLNÓRSÚÝZ", + "'áæéíåñóà¶úý¼ÁÆÉÍÅÑÓÀ¦Úݬ" }, + /* cirumflex - ^ */ { " aeiouAEIOU", + "^âêîôûÂÊÎÔÛ", + "^âeîôuÂEÎÔU" }, + /* tilde - ~ */ { " anoANO", + "~ãñõÃÑÕ", + "~anoANO" }, + /* ??? - ¯ */ { "", + "", + "" }, + /* breve - u */ { "aA", + "aA", + "ãÃ" }, + /* abovedot - · */ { "zZ", + "zZ", + "¿¯" }, + /* diaeresis ¨ */ { "aeiouAEIOU", + "äëïöüÄËÏÖÜ", + "äëiöüÄËIÖÜ" }, + /* ??? - . */ { "", + "", + "" }, + /* ringabove - ° */ { " auAU", + "°åuÅU", + "°aùAÙ" }, + /* cedilla - ¸ */ { "cstCST", + "çstÇST", + "çºþǪÞ" }, + /* ??? - _ */ { " ", + "_", + "_" }, + /* dbl acute - " */ { " ouOU", + "\"ouOU", + "\"õûÕÛ" }, + /* ogonek - \, */ { "aeAE", + "aeAE", + "±ê¡Ê" }, + /* caron - v */ { "cdelnrstzCDELNRSTZ", + "cdelnrstzCDELNRSTZ", + "èïìµòø¹»¾ÈÏÌ¥ÒØ©«®" }, +}; + + +static u8 g2map_latin1[] = + /*0123456789abcdef*/ + " ¡¢£$¥#§¤'\"« " + "°±²³×µ¶·÷'\"»¼½¾¿" + " `´^~ ¨.°¸_\" " + "_¹®© " + " ÆЪH ILLØ ºÞTNn" + "Kædðhiillø ßþtn\x7f"; + + +static u8 g2map_latin2[] = + /*0123456789abcdef*/ + " icL$Y#§¤'\"< " + "° ×u ÷'\"> " + " `´^~ ¢ÿ¨.°¸_½²·" + "- RC " + " ÐaH iL£O opTNn" + "K ðdhiil³o ßptn\x7f"; + + +void lang_init(void) +{ + int i; + + memset(lang_char, 0, sizeof(lang_char)); + for (i = 1; i <= 13; i++) + lang_char[lang_chars[0][i]] = i; +} + + +void conv2latin(u8 *p, int n, int lang) +{ + int c, gfx = 0, lat=0; + + if ((latin1 == KOI8) && lang==12) { /* russian */ + while (n--) { + c=*p; + + if(c==0x1b) lat = !lat; /* ESC switches languages inside page */ + + if ( is_koi(c)) { + if (not gfx || (c & 0xa0) != 0x20) { + if(!lat) conv2koi8(p); + } + } + else if ((c & 0xe8) == 0) + gfx = c & 0x10; + p++; + } + } +else if ((latin1 == GREEK) && lang==15) { /* Hellas */ + while (n--) { + c=*p; + + if(c==0x1b) lat = !lat; /* ESC switches languages inside page */ + + if ( is_greek(c)) { + if (not gfx || (c & 0xa0) != 0x20) { + if(!lat) conv2greek(p); + } + } + else if ((c & 0xe8) == 0) + gfx = c & 0x10; + p++; + } + } + + else { + while (n--) + { + if (lang_char[c = *p]) + { + if (not gfx || (c & 0xa0) != 0x20) + *p = lang_chars[lang + 1][lang_char[c]]; + } + else if ((c & 0xe8) == 0) + gfx = c & 0x10; + p++; + } + } +} + + +/* check for Greek chars - needs locale iso8859-7 set */ +int is_greek(int c) +{ + if( isalpha(c | 0x80)) return 1; + return 0; +} + + +/* check for russian chars - needs locale KOI8-R set */ +int is_koi(int c) +{ + if( isalpha(c | 0x80)) return 1; + if( c=='&' ) return 1; + return 0; +} + + +/* teletext to koi8-r conversion */ +void conv2koi8(u8 *p) +{ + u8 c; + static u8 l2koi[]={ + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, + 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, + 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xFF, 0xFA, 0xFB, 0xFC, 0xFD, + 0xFE, 0xF9, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, + 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, + 0xDC, 0xDD, 0xDE, 0xDF + }; + + c= *p; + if ( (c >= 0x40) && (c <= 0x7f)) *p=l2koi[(c & 0x7f) - 0x40]; + if (c=='&') *p='Ù'; +} + + +/* teletext to iso8859-7 conversion */ +void conv2greek(u8 *p) +{ + u8 c; + static u8 l2greek[]={ +/* 1 @ 0x40->ú*/0xc0, +/* 2 A 0x41->Á*/0xc1, +/* 3 B 0x42->Â*/0xc2, +/* 4 C 0x43->Ã*/0xc3, +/* 5 D 0x44->Ä*/0xc4, +/* 6 E 0x45->Å*/0xc5, +/* 7 F 0x46->Æ*/0xc6, +/* 8 G 0x47->Ç*/0xc7, +/* 9 H 0x48->È*/0xc8, +/*10 I 0x49->É*/0xc9, +/*11 J 0x4a->Ê*/0xca, +/*12 K 0x4b->Ë*/0xcb, +/*13 L 0x4c->Ì*/0xcc, +/*14 M 0x4d->Í*/0xcd, +/*15 N 0x4e->Î*/0xce, +/*16 O 0x4f->Ï*/0xcf, +/*17 P 0x50->Ð*/0xd0, +/*18 Q 0x51->Ñ*/0xd1, +/*19 R 0x52->?*/0x52, +/*20 S 0x53->Ó*/0xd3, +/*21 T 0x54->Ô*/0xd4, +/*22 U 0x55->Õ*/0xd5, +/*23 V 0x56->Ö*/0xd6, +/*24 W 0x57->÷*/0xd7, +/*25 X 0x58->Ø*/0xd8, +/*26 Y 0x59->Ù*/0xd9, +/*27 Z 0x5a->?*/0x5a, +/*28 [ 0x5b->?*/0x5b, +/*!29 \ 0x5c->Ü*/0xdc, +/*!30 ] 0x5d->Ý*/0xdd, +/*!31 ^ 0x5e->Þ*/0xde, +/*!32 _ 0x5f->ß*/0xdf, +/*33 ` 0x60->?*/0x60, +/*!34 a 0x61->á*/0xe1, +/*!35 b 0x62->â*/0xe2, +/*!36 c 0x63->ã*/0xe3, +/*!37 d 0x64->ä*/0xe4, +/*!38 e 0x65->å*/0xe5, +/*!39 f 0x66->æ*/0xe6, +/*!40 g 0x67->ç*/0xe7, +/*!41 h 0x68->è*/0xe8, +/*!42 i 0x69->é*/0xe9, +/*!43 j 0x6a->ê*/0xea, +/*!44 k 0x6b->ë*/0xeb, +/*!45 l 0x6c->ì*/0xec, +/*!46 m 0x6d->í*/0xed, +/*!47 n 0x6e->î*/0xee, +/*!48 o 0x6f->ï*/0xef, +/*!49 p 0x70->ð*/0xf0, +/*!50 q 0x71->ñ*/0xf1, +/*!51 r 0x72->ò*/0xf2, +/*!52 s 0x73->ó*/0xf3, +/*!53 t 0x74->ô*/0xf4, +/*!54 u 0x75->õ*/0xf5, +/*!55 v 0x76->ö*/0xf6, +/*!56 w 0x77->÷*/0xf7, +/*!57 x 0x78->ø*/0xf8, +/*!58 y 0x79->ù*/0xf9, +/*59 z 0x7a->ú(ìå ôüíï)*/0xc0, +/*60 { 0x7b->?*/0x7b, +/*!61 | 0x7c->ü*/0xfc, +/*!62 } 0x7d->ý*/0xfd, +/*!63 ~ 0x7e->þ*/0xfe, +/*64 0x7f->?*/0x7f + }; + c= *p; + if ( (c >= 0x40) && (c <= 0x7f)) *p=l2greek[(c & 0x7f) - 0x40]; +} + + +void init_enhance(struct enhance *eh) +{ + eh->next_des = 0; +} + + +void add_enhance(struct enhance *eh, int dcode, u32 *t) +{ + + if (dcode == eh->next_des) + { + memcpy(eh->trip + dcode * 13, t, 13 * sizeof(*t)); + eh->next_des++; + } + else + eh->next_des = -1; +} + + +void enhance(struct enhance *eh, struct vt_page *vtp) +{ + int row = 0; + u32 *p, *e; + + if (eh->next_des < 1) + return; + + for (p = eh->trip, e = p + eh->next_des * 13; p < e; p++) + if (*p % 2048 != 2047) + { + int adr = *p % 64; + int mode = *p / 64 % 32; + int data = *p / 2048 % 128; + + if (adr < 40) + { + // col functions + switch (mode) + { + case 15: // char from G2 set + if (adr < W && row < H) + if (latin1==LATIN1) + vtp->data[row][adr] = g2map_latin1[data-32]; + else if (latin1==LATIN2) + vtp->data[row][adr] = g2map_latin2[data-32]; + break; + case 16 ... 31: // char from G0 set with diacritical mark + if (adr < W && row < H) + { + struct mark *mark = marks + (mode - 16); + u8 *x; + + if (x = strchr(mark->g0, data)) + if (latin1==LATIN1) + data = mark->latin1[x - mark->g0]; + else if (latin1==LATIN2) + data = mark->latin2[x - mark->g0]; + vtp->data[row][adr] = data; + } + break; + } + } + else + { + // row functions + if ((adr -= 40) == 0) + adr = 24; + + switch (mode) + { + case 1: // full row color + row = adr; + break; + case 4: // set active position + row = adr; + break; + case 7: // address row 0 (+ full row color) + if (adr == 23) + row = 0; + break; + } + } + } +} |