home *** CD-ROM | disk | FTP | other *** search
/ Phoenix Heaven Sunny 2 / APPARE2.BIN / oh_towns / dic / src / gaiji.c < prev    next >
Text File  |  1995-06-20  |  12KB  |  511 lines

  1. /********************************************
  2.  
  3.     Gaiji Func
  4.  
  5. *********************************************/
  6. #include    "defs.h"
  7.  
  8. #define    GAIJI_TOP    0x7521
  9. #define    GAIJI_MAX    188
  10.  
  11. #define    ZEN_SIZE    32        /* 16x16 */
  12. #define    ZEN_BLOCK    32        /* 1024 / ZEN_SIZE */
  13.  
  14. #define    HAN_SIZE    16        /* 8x16 */
  15. #define    HAN_BLOCK    64        /* 1024 / ZEN_SIZE */
  16.  
  17. #define    MAP_HASH    16
  18. #define    MAP_MASK    (MAP_HASH - 1)
  19.  
  20. #define    HAN_MATCH    001
  21. #define    ZEN_MATCH    002
  22.  
  23. typedef    struct _GP {
  24.     struct    _GP    *next;
  25.     ushort        code;
  26.     ushort        extc;
  27.     short        id;
  28. } GAITAB;
  29.  
  30. typedef    struct _GMP {
  31.     struct    _GMP    *next;
  32.     ushort        extc;
  33.     char        hzflag;
  34.     char        str[1];
  35. } GAIMAP;
  36.  
  37.     int    dicin_gaiji_flag = 0;
  38.     ulong    zen_gaiji_start_block = 0L;
  39.     ulong    zen_gaiji_end_block   = 0L;
  40.     ulong    han_gaiji_start_block = 0L;
  41.     ulong    han_gaiji_end_block   = 0L;
  42.     char    *gaiji_map_file = NULL;
  43.  
  44. static    GAIMAP    *gaiji_map[MAP_HASH] = {
  45.         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  46.         NULL, NULL, NULL, NULL,    NULL, NULL, NULL, NULL
  47.     };
  48. static    ushort    zen_gaiji_top_code = 0xA121;
  49. static    ushort    han_gaiji_top_code = 0xA1A1;
  50. static    GAITAB    gaiji_tab[GAIJI_MAX];
  51. static    GAITAB    *gaiji_top = NULL;
  52. static    uchar    gaiji_buf[BLOCK_SIZE + ZEN_SIZE];
  53.  
  54. /***************************************
  55.  
  56.     外字フォントの設定
  57.  
  58. ****************************************/
  59. static    int    Gaiji_set(int code, char *font)
  60. {
  61. #ifdef    FMRGAIJI
  62.     union REGS regs;
  63.     struct SREGS segs;
  64.     char far     *p;
  65.  
  66.     p = (char far *)font;
  67.     regs.h.ah = 0x08;
  68.     regs.h.dh = 16;
  69.     regs.h.dl = 16;
  70.     regs.h.bh = (uchar)code;
  71.     regs.h.bl = (uchar)(code >> 8);
  72.     regs.x.di = FP_OFF(p);
  73.     segs.ds   = FP_SEG(p);
  74.     int86x(0x91, ®s, ®s, &segs);        /* VDBIOS */
  75.     return (regs.h.ah);
  76. #else
  77.     return ERR;
  78. #endif
  79. }
  80. static    void    Gaiji_bitmap(ushort code, int w, int h, uchar *map)
  81. {
  82.     int     wb, x, y, b;
  83.     uchar   *p;
  84.  
  85.     printf("Code : %04X\n", code);
  86.  
  87.     wb = (w + 7) / 8;
  88.     for ( y = 0 ; y < h ; y++ ) {
  89.     p = map;
  90.     b = 0x80;
  91.     for ( x = 0 ; x < w ; x++ ) {
  92.         putchar((*p & b) ? '#':'-');
  93.         if ( (b >>= 1) == 0 ) {
  94.         p++;
  95.         b = 0x80;
  96.         }
  97.     }
  98.     map += wb;
  99.         putchar('\n');
  100.     }
  101. }
  102. void    Gaiji_zenkaku_bitmap()
  103. {
  104.     int     n, max;
  105.     int     wd, he;
  106.     ushort  code = 0xA121;
  107.     ulong   block;
  108.  
  109.     if ( zen_gaiji_end_block == 0L )
  110.     return;
  111.  
  112.     block = zen_gaiji_start_block;
  113.     if ( CD_read_sect(block++, 1, gaiji_buf) )
  114.     return;
  115.  
  116.     wd = gaiji_buf[8];
  117.     he = gaiji_buf[9];
  118.     code = toshort(gaiji_buf + 10);
  119.     max = toshort(gaiji_buf + 12);
  120.  
  121.     while ( max > 0 && block <= zen_gaiji_end_block ) {
  122.     if ( CD_read_sect(block++, 1, gaiji_buf) )
  123.         return;
  124.     for ( n = 0 ; n < ZEN_BLOCK && max > 0 ; n++,max-- ) {
  125.         Gaiji_bitmap(code++, wd, he, gaiji_buf + n * ZEN_SIZE);
  126.         if ( (code & 0x00FF) > 0x007E )
  127.         code = (code & 0xFF00) + 0x0121;
  128.     }
  129.     for ( n = 0 ; n < ZEN_BLOCK && max > 0 ; n++,max-- ) {
  130.         Gaiji_bitmap(code++, wd, he, gaiji_buf + 1024 + n * ZEN_SIZE);
  131.         if ( (code & 0x00FF) > 0x007E )
  132.         code = (code & 0xFF00) + 0x0121;
  133.     }
  134.     }
  135. }
  136. void    Gaiji_hankaku_bitmap()
  137. {
  138.     int     n, max;
  139.     int     wd, he;
  140.     ushort  code = 0xA121;
  141.     ulong   block;
  142.  
  143.     if ( han_gaiji_end_block == 0L )
  144.     return;
  145.  
  146.     block = han_gaiji_start_block;
  147.     if ( CD_read_sect(block++, 1, gaiji_buf) )
  148.     return;
  149.  
  150.     wd = gaiji_buf[8];
  151.     he = gaiji_buf[9];
  152.     code = toshort(gaiji_buf + 10);
  153.     max = toshort(gaiji_buf + 12);
  154.  
  155.     while ( max > 0 && block <= han_gaiji_end_block ) {
  156.     if ( CD_read_sect(block++, 1, gaiji_buf) )
  157.         return;
  158.     for ( n = 0 ; n < HAN_BLOCK && max > 0 ; n++,max-- ) {
  159.         Gaiji_bitmap(code++ | 0x80, wd, he, gaiji_buf + n * HAN_SIZE);
  160.         if ( (code & 0x00FF) > 0x007E )
  161.         code = (code & 0xFF00) + 0x0121;
  162.     }
  163.     for ( n = 0 ; n < HAN_BLOCK && max > 0 ; n++,max-- ) {
  164.         Gaiji_bitmap(code++ | 0x80, wd, he, 
  165.                 gaiji_buf + 1024 + n * HAN_SIZE);
  166.         if ( (code & 0x00FF) > 0x007E )
  167.         code = (code & 0xFF00) + 0x0121;
  168.     }
  169.     }
  170. }
  171. void    Gaiji_tab_init()
  172. {
  173.     int    n, code;
  174.  
  175.     gaiji_top = NULL;
  176.     code = GAIJI_TOP;
  177.     for ( n = 0 ; n < GAIJI_MAX ; n++ ) {
  178.     gaiji_tab[n].next = gaiji_top;
  179.     gaiji_top = &(gaiji_tab[n]);
  180.     gaiji_tab[n].id   = (-1);
  181.     gaiji_tab[n].extc = 0;
  182.     gaiji_tab[n].code = code++;
  183.     if ( (code & 0x00FF) > 0x007E )
  184.         code = (code & 0xFF00) + 0x0121;
  185.     }
  186. }
  187. void    Gaiji_init(int zen, int han)
  188. {
  189.     ulong  start_block;
  190.     ulong  end_block;
  191.  
  192.     if ( dicin_gaiji_flag != 0 ) {
  193.     if ( (dicin_gaiji_flag & 1) == 0 )
  194.         zen_gaiji_end_block   = 0L;
  195.     if ( (dicin_gaiji_flag & 2) == 0 )
  196.         han_gaiji_end_block   = 0L;
  197.     goto INIT;
  198.     }
  199.  
  200.     zen_gaiji_end_block   = 0L;
  201.     han_gaiji_end_block   = 0L;
  202.  
  203.     start_block = file_start_block;
  204.     end_block   = file_end_block;
  205.  
  206.     if ( zen != 0 && !CD_file_open(zen) ) {
  207.     zen_gaiji_start_block = file_start_block;
  208.     zen_gaiji_end_block   = file_end_block;
  209.     }
  210.     if ( han != 0 && !CD_file_open(han) ) {
  211.     han_gaiji_start_block = file_start_block;
  212.     han_gaiji_end_block   = file_end_block;
  213.     }
  214.  
  215.     file_start_block = start_block;
  216.     file_end_block   = end_block;
  217.  
  218. INIT:
  219.     if ( zen_gaiji_end_block != 0L ) {
  220.     if ( CD_read_sect(zen_gaiji_start_block, 1, gaiji_buf) )
  221.         zen_gaiji_end_block = 0L;
  222.     else
  223.         zen_gaiji_top_code = toshort(gaiji_buf + 10);
  224.     }
  225.  
  226.     if ( han_gaiji_end_block != 0L ) {
  227.     if ( CD_read_sect(han_gaiji_start_block, 1, gaiji_buf) )
  228.         han_gaiji_end_block = 0L;
  229.     else
  230.         han_gaiji_top_code = toshort(gaiji_buf + 10) | 0x0080;
  231.     }
  232. }
  233. void    Gaiji_close()
  234. {
  235.     zen_gaiji_end_block   = 0L;
  236.     han_gaiji_end_block   = 0L;
  237. }
  238. uchar    *Gaiji_convert(uint *extc)
  239. {
  240.     int     n;
  241.     uint    a, b;
  242.     ulong   block;
  243.     uint    offset;
  244.     int     len;
  245.     GAITAB  *gp, *bp;
  246.     GAIMAP  *mp;
  247.  
  248.     mp = gaiji_map[*extc & MAP_MASK];
  249.     while ( mp != NULL ) {
  250.     switch(mp->hzflag) {
  251.     case HAN_MATCH:
  252.     case ZEN_MATCH:
  253.         if ( *extc == mp->extc )
  254.         return mp->str;
  255.         break;
  256.     case HAN_MATCH | ZEN_MATCH:
  257.         if ( (*extc & 0xFF7F) == mp->extc )
  258.         return mp->str;
  259.         break;
  260.     }
  261.     mp = mp->next;
  262.     }
  263.  
  264.     if ( gaiji_flag == FALSE || gaiji_top == NULL )
  265.     goto ERROR2;
  266.  
  267.     bp = gp = gaiji_top;
  268.     for ( ; ; ) {
  269.     if ( gp->extc == *extc && gp->id == now_dev_id ) {
  270.         if ( gp != bp ) {
  271.             bp->next = gp->next;
  272.             gp->next = gaiji_top;
  273.             gaiji_top = gp;
  274.         }
  275.         *extc = gp->code;
  276.         return NULL;
  277.     }
  278.     if ( gp->next == NULL )
  279.         break;
  280.     bp = gp;
  281.     gp = gp->next;
  282.     }
  283.     bp->next = gp->next;
  284.     gp->next = gaiji_top;
  285.     gaiji_top = gp;
  286.     gp->extc = *extc;
  287.     gp->id   = now_dev_id;
  288.  
  289.     if ( (*extc & 0x0080) == 0 ) {        /* ZenKaku */
  290.     a = *extc - zen_gaiji_top_code;
  291.     b = ((a >> 8) & 0x00FF) * 94 + (a & 0x00FF);
  292.     a = b / ZEN_BLOCK;
  293.     b = b % ZEN_BLOCK;
  294.     block  = zen_gaiji_start_block + (a / 2) + 1;
  295.     offset = b * ZEN_SIZE + (a & 1) * 1024;
  296.     len    = ZEN_SIZE;
  297.     if ( block < zen_gaiji_start_block || block > zen_gaiji_end_block )
  298.         goto ERROR;
  299.  
  300.     } else {                    /* HanKaku */
  301.     a = *extc - han_gaiji_top_code;
  302.     b = ((a >> 8) & 0x00FF) * 94 + (a & 0x00FF);
  303.     a = b / HAN_BLOCK;
  304.     b = b % HAN_BLOCK;
  305.     block  = han_gaiji_start_block + (a / 2) + 1;
  306.     offset = b * HAN_SIZE + (a & 1) * 1024;
  307.     len    = HAN_SIZE;
  308.     if ( block < han_gaiji_start_block || block > han_gaiji_end_block )
  309.         goto ERROR;
  310.     }
  311.  
  312.     if ( CD_read_sect(block, 1, gaiji_buf) )
  313.     goto ERROR;
  314.  
  315.     if ( len == HAN_SIZE ) {        /* 8x16 Onry */
  316.     for ( n = HAN_SIZE - 1 ; n >= 0 ; n-- ) {
  317.         gaiji_buf[offset + n * 2 + 1] = gaiji_buf[offset + n] << 4;
  318.         gaiji_buf[offset + n * 2 + 0] = gaiji_buf[offset + n] >> 4;
  319.     }
  320.     }
  321.  
  322.     if ( Gaiji_set(gp->code, gaiji_buf + offset) )
  323.     goto ERROR;
  324.  
  325.     *extc = gp->code;
  326.     return NULL;
  327.  
  328. ERROR:
  329.     gp->extc = 0;
  330.  
  331. ERROR2:
  332.     if ( gaiji_map_file == NULL ) {
  333.         *extc = 0x2222;
  334.         return NULL;
  335.     }
  336.     sprintf(gaiji_buf, "[%04X]", *extc);
  337.     return gaiji_buf;
  338. }
  339. int    Gaiji_config(char *file)
  340. {
  341.     int     n, ch;
  342.     int     hzflag;
  343.     FILE    *fp;
  344.     GAIMAP  *gp;
  345.     char    *p;
  346.     int     code;
  347.  
  348.     if ( gaiji_map_file != NULL )
  349.     free(gaiji_map_file);
  350.  
  351.     for ( n = 0 ; n < MAP_HASH ; n++ ) {
  352.     while ( (gp = gaiji_map[n]) != NULL ) {
  353.         gaiji_map[n] = gp->next;
  354.         free(gp);
  355.     }
  356.     }
  357.  
  358.     gaiji_map_file = strdup(file);
  359.  
  360.     if ( (fp = fopen(file, "r")) == NULL )
  361.     return ERR;
  362.  
  363.     while ( fgets(gaiji_buf, 128, fp) != NULL ) {
  364.     if ( (p = strchr(gaiji_buf, '\n')) != NULL )
  365.         *p = '\0';
  366.     for ( p = gaiji_buf ; isspace((uchar)*p) ; p++ )
  367.         ;
  368.  
  369.     if ( (ch = toupper(*p)) == 'H' || ch == 'Z' )
  370.         p++;
  371.  
  372.     if ( (code = htoi(p)) == 0 )
  373.         continue;
  374.  
  375.     while ( isxdigit(*p) )
  376.         p++;
  377.  
  378.     if ( *p == 'h' || *p == 'H' || ch == 'H' ) {
  379.         hzflag = HAN_MATCH;
  380.         code |= 0x0080;
  381.         p++;
  382.     } else if ( *p == 'z' || *p == 'Z' || ch == 'Z' ) {
  383.         hzflag = ZEN_MATCH;
  384.         code &= 0xFF7F;
  385.         p++;
  386.     } else if ( (code & 0x0080) != 0 ) {
  387.         hzflag = HAN_MATCH;
  388.     } else {
  389.         hzflag = HAN_MATCH | ZEN_MATCH;
  390.     }
  391.  
  392.     while ( isspace((uchar)*p) || *p == '=' )
  393.         p++;
  394.  
  395.     if ( (gp = (GAIMAP *)malloc(sizeof(GAIMAP) + strlen(p))) == NULL ) {
  396.         fprintf(stderr, "Gaiji Maping Memory Alloc Error\n");
  397.         fclose(fp);
  398.         return ERR;
  399.     }
  400.  
  401.     gp->next = gaiji_map[code & MAP_MASK];
  402.     gaiji_map[code & MAP_MASK] = gp;
  403.     gp->extc = code;
  404.     gp->hzflag = hzflag;
  405.     strcpy(gp->str, p);
  406.     }
  407.  
  408.     fclose(fp);
  409.     return FALSE;
  410. }
  411. int    Gaiji_maping(int code, char *str)
  412. {
  413.     int     n;
  414.     FILE    *fp;
  415.     GAIMAP  *gp;
  416.  
  417.     for ( gp = gaiji_map[code & MAP_MASK] ; gp != NULL ; gp = gp->next ) {
  418.     if ( gp->extc == code )
  419.         gp->extc = 0;
  420.     }
  421.  
  422.     if ( (gp = (GAIMAP *)malloc(sizeof(GAIMAP) + strlen(str))) == NULL ) {
  423.     fprintf(stderr, "Gaiji Maping Memory Alloc Error\n");
  424.     return ERR;
  425.     }
  426.  
  427.     gp->next = gaiji_map[code & MAP_MASK];
  428.     gaiji_map[code & MAP_MASK] = gp;
  429.     gp->extc = code;
  430.     gp->hzflag = (code & 0x0080) ? HAN_MATCH:ZEN_MATCH;
  431.     strcpy(gp->str, str);
  432.  
  433.     if ( gaiji_map_file == NULL )
  434.     return FALSE;
  435.  
  436.     if ( (fp = fopen(gaiji_map_file, "w")) == NULL )
  437.     return ERR;
  438.  
  439.     for ( n = 0 ; n < MAP_HASH ; n++ ) {
  440.         for ( gp = gaiji_map[n] ; gp != NULL ; gp = gp->next ) {
  441.         if ( gp->extc != 0 )
  442.             fprintf(fp, "%04X%s=%s\n", 
  443.             gp->extc & 0xFF7F, 
  444.             gp->hzflag == HAN_MATCH ? "h":
  445.             gp->hzflag == ZEN_MATCH ? "z":"",
  446.             gp->str);
  447.     }
  448.     }
  449.  
  450.     fclose(fp);
  451.  
  452.     return FALSE;
  453. }
  454. int    Gaiji_display(ushort extc)
  455. {
  456.     uint    a, b;
  457.     ulong   block;
  458.     uint    offset;
  459.     int     wd;
  460.  
  461.     if ( extc < 0xA121U || extc > 0xFEFEU )
  462.     goto ERROR;
  463.  
  464.     if ( zen_gaiji_end_block == 0L && han_gaiji_end_block == 0L ) {
  465.     if ( now_dic_menu != NULL )
  466.         Gaiji_init(now_dic_menu->gaz, now_dic_menu->gah);
  467.     else if ( dicin_gaiji_flag != 0 )
  468.         Gaiji_init(0, 0);
  469.     }
  470.  
  471.     if ( (extc & 0x0080) == 0 ) {        /* ZenKaku */
  472.     a = extc - zen_gaiji_top_code;
  473.     b = ((a >> 8) & 0x00FF) * 94 + (a & 0x00FF);
  474.     a = b / ZEN_BLOCK;
  475.     b = b % ZEN_BLOCK;
  476.     block  = zen_gaiji_start_block + (a / 2) + 1;
  477.     offset = b * ZEN_SIZE + (a & 1) * 1024;
  478.     wd = 16;
  479.     if ( block < zen_gaiji_start_block || block > zen_gaiji_end_block )
  480.         goto ERROR;
  481.  
  482.     } else {                    /* HanKaku */
  483.     a = extc - han_gaiji_top_code;
  484.     b = ((a >> 8) & 0x00FF) * 94 + (a & 0x00FF);
  485.     a = b / HAN_BLOCK;
  486.     b = b % HAN_BLOCK;
  487.     block  = han_gaiji_start_block + (a / 2) + 1;
  488.     offset = b * HAN_SIZE + (a & 1) * 1024;
  489.     wd = 8;
  490.     if ( block < han_gaiji_start_block || block > han_gaiji_end_block )
  491.         goto ERROR;
  492.     }
  493.  
  494.     if ( CD_read_sect(block, 1, gaiji_buf) )
  495.     goto ERROR;
  496.  
  497.     Gaiji_bitmap(extc, wd, 16, gaiji_buf + offset);
  498.     return FALSE;
  499.  
  500. ERROR:
  501.  
  502. #ifdef    DEBUG
  503. printf("%04x %08lx \n%08lx %08lx \n%08lx %08lx\n",
  504.     extc, block,
  505.     zen_gaiji_start_block, zen_gaiji_end_block,
  506.     han_gaiji_start_block, han_gaiji_end_block);
  507. #endif
  508.  
  509.     return ERR;
  510. }
  511.