home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 3 / FREEWARE.BIN / towns_os / whisper / source / consol.c < prev    next >
Text File  |  1980-01-02  |  11KB  |  566 lines

  1. #include    <stdio.h>
  2. #include    <stdlib.h>
  3. #include    <string.h>
  4. #include    <ctype.h>
  5. #include    "defs.h"
  6. #include    "graphic.h"
  7. #include    "buff.h"
  8. #include    "coldef.h"
  9. #include    "wind.h"
  10.  
  11. #define    MAX_X    80
  12. #define    MAX_Y    28
  13. #define    TAB    8
  14.  
  15. #define    OFF_Y    16
  16. #define    MAX_LOG    500
  17. #define    BAK_LOG    200
  18.  
  19. #define    DOS_WIND    1    /* JOHN */
  20. #define    DOS_CHIL    4    /* Last Wind Buff */
  21.  
  22. void    cons_bios_set(void);
  23. void    cons_bios_ret(void);
  24. void    vram_scrool(int adr,int lin);
  25. int    kan_pos(char *p,int n);
  26. int    iskan(char *str);
  27. void    wrt_ank(unsigned char ch,int adr);
  28. void    wrt_kan(unsigned short ch,int adr);
  29. void    wrt_cur(int adr);
  30.  
  31. extern int    act_wind;
  32. extern WIND    win[MAX_WIND];
  33.  
  34. typedef union {
  35.     struct {
  36.     unsigned int    edi;
  37.     unsigned int    esi;
  38.     unsigned int    edp;
  39.     unsigned int    esp;
  40.     unsigned int    ebx;
  41.     unsigned int    edx;
  42.     unsigned int    ecx;
  43.     unsigned int    eax;
  44.     } e;
  45.     struct {
  46.     unsigned short di;
  47.     unsigned short __di;
  48.     unsigned short si;
  49.     unsigned short __si;
  50.     unsigned short bp;
  51.     unsigned short __bp;
  52.     unsigned short sp;
  53.     unsigned short __sp;
  54.     unsigned short bx;
  55.     unsigned short __bx;
  56.     unsigned short dx;
  57.     unsigned short __dx;
  58.     unsigned short cx;
  59.     unsigned short __cx;
  60.     unsigned short ax;
  61.     unsigned short __ax;
  62.     } x;
  63.     struct {
  64.     unsigned short di;
  65.     unsigned short __di;
  66.     unsigned short si;
  67.     unsigned short __si;
  68.     unsigned short bp;
  69.     unsigned short __bp;
  70.     unsigned short sp;
  71.     unsigned short __sp;
  72.     unsigned char bl, bh;
  73.     unsigned short __bx;
  74.     unsigned char dl, dh;
  75.     unsigned short __dx;
  76.     unsigned char cl, ch;
  77.     unsigned short __cx;
  78.     unsigned char al, ah;
  79.     unsigned short __ax;
  80.     } h;
  81. } REGS;
  82.  
  83. static int    cons_rot=ERR;
  84. static int    cons_top=ERR;
  85. static int    cons_now=ERR;
  86. static int    cons_pos=0;
  87. static int    cons_x=0;
  88. static int    cons_y=0;
  89. static int    cons_bak=0;
  90. static int    cons_max_y=MAX_Y;
  91. static int    cons_off_y=OFF_Y;
  92. static int    cons_wind=DOS_WIND;
  93. static int    cons_child=DOS_CHIL;
  94.  
  95. void    cons_scrool(void)
  96. {
  97.     LIN_PTR *lp;
  98.     LIN_PTR *tp;
  99.  
  100.     if ( ++cons_y >= cons_max_y ) {
  101.     cons_y = cons_max_y - 1;
  102.     vram_scrool(cons_off_y * 512,(cons_max_y - 1) * 16);
  103.     }
  104.  
  105.     lp = get_lin(cons_now);
  106.     lp->lin[cons_pos] = '\0';
  107.  
  108.     if ( lp->left == ERR ) {
  109.     lp->left = cons_top;
  110.     tp = get_lin(cons_top);
  111.     cons_top = tp->left;
  112.     tp->right = cons_now;
  113.     tp->left = ERR;
  114.     tp = get_lin(cons_top);
  115.     tp->right = ERR;
  116.     }
  117.  
  118.     cons_now = lp->left;
  119.     lp = get_lin(cons_now);
  120.     lp->lin[0] = '\0';
  121.     cons_pos = 0;
  122. }
  123. void    ank_put(unsigned char ch)
  124. {
  125.     LIN_PTR *lp;
  126.  
  127.     lp = get_lin(cons_now);
  128.     while ( cons_pos <= cons_x )
  129.     lp->lin[cons_pos++] = ' ';
  130.     lp->lin[cons_x] = ch;
  131.     lp->lin[cons_pos] = '\0';
  132.  
  133.     wrt_ank(ch,cons_x * 4 + (cons_y * 16 + cons_off_y) * 512);
  134.  
  135.     if ( ++cons_x >= MAX_X ) {
  136.     cons_x = 0;
  137.     cons_scrool();
  138.     }
  139. }
  140. void    kan_put(unsigned short ch)
  141. {
  142.     LIN_PTR *lp;
  143.  
  144.     if ( cons_x >= (MAX_X - 1) ) {
  145.     cons_x = 0;
  146.     cons_scrool();
  147.     }
  148.  
  149.     lp = get_lin(cons_now);
  150.     while ( cons_pos < (cons_x + 2) )
  151.     lp->lin[cons_pos++] = ' ';
  152.     lp->lin[cons_x] = ch >> 8;
  153.     lp->lin[cons_x+1] = ch;
  154.     lp->lin[cons_pos] = '\0';
  155.  
  156.     wrt_kan(ch,cons_x * 4 + (cons_y * 16 + cons_off_y) * 512);
  157.  
  158.     if ( (cons_x += 2) >= MAX_X ) {
  159.     cons_x = 0;
  160.     cons_scrool();
  161.     }
  162. }
  163. void    cons_cur(void)
  164. {
  165.     wrt_cur((cons_x * 4) + (cons_y * 16 + (cons_off_y + 14)) * 512);
  166. }
  167. void    cons_char(unsigned char ch)
  168. {
  169.     int     n;
  170.     LIN_PTR *lp;
  171.  
  172.     cons_cur();
  173.     if ( cons_bak != 0 ) {
  174.     if ( iskanji2(ch) ) {
  175.         kan_put((cons_bak << 8) | ch);
  176.         cons_bak = 0;
  177.         goto ENDOF;
  178.     }
  179.     ank_put(cons_bak);
  180.     cons_bak = 0;
  181.     }
  182.  
  183.     switch(ch) {
  184.     case '\x0D':
  185.     cons_x = 0;
  186.     break;
  187.  
  188.     case '\x0A':
  189.     lp = get_lin(cons_now);
  190.     lp->lin[cons_pos++] = '\n';
  191.     lp->lin[cons_pos] = '\0';
  192.     cons_scrool();
  193.     break;
  194.  
  195.     case '\x09':
  196.     n = TAB - (cons_x % TAB);
  197.     while ( n-- > 0 )
  198.         ank_put(' ');
  199.     break;
  200.  
  201.     case '\x08':
  202.     if ( cons_x > 0 )
  203.         cons_x--;
  204.     else {
  205.         cons_x = MAX_X - 1;
  206.         if ( cons_y > 0 ) {
  207.         cons_y--;
  208.         lp = get_lin(cons_now);
  209.         if ( lp->right != ERR ) {
  210.             cons_now = lp->right;
  211.             lp = get_lin(cons_now);
  212.             cons_pos = strlen(lp->lin);
  213.             if ( cons_pos > 0 && lp->lin[cons_pos-1] == '\n' )
  214.             cons_pos--;
  215.         }
  216.         }
  217.     }
  218.     break;
  219.  
  220.     case '\x1B':
  221.     break;
  222.  
  223.     default:
  224.     if ( iskanji(ch) )
  225.         cons_bak = ch;
  226.     else if ( ch != '\0' )
  227.         ank_put(ch);
  228.     break;
  229.     }
  230.  
  231. ENDOF:
  232.     cur_x = cons_x * 8;
  233.     cur_y = cons_y * 16 + cons_off_y;
  234.     cons_cur();
  235. }
  236. void    cons_bios(REGS *reg)
  237. {
  238.     cons_char(reg->h.al);
  239. }
  240. int    CON_redisp(int ofs)
  241. {
  242.     int     i,n,y,fg,c;
  243.     LIN_PTR *lp;
  244.  
  245.     if ( ofs < 0 )
  246.     ofs = 0;
  247.  
  248.     n = cons_now;
  249.     fg = c = 0;
  250.     for ( i = cons_y + ofs ; i > 0 ; i-- ) {
  251.     lp = get_lin(n);
  252.     if ( lp->right == ERR ) {
  253.         if ( fg == 0 && cons_rot != ERR ) {
  254.         n = cons_rot;
  255.         fg = 1;
  256.         } else
  257.             break;
  258.     } else if ( fg == 1 && ++c >= BAK_LOG )
  259.         break;
  260.     else
  261.         n = lp->right;
  262.     }
  263.  
  264.     ofs -= i;
  265.  
  266.     y = cons_off_y;
  267.     for ( i = 0 ; i < cons_max_y ; i++ ) {
  268.     if ( n != ERR ) {
  269.         lp = get_lin(n);
  270.         putstr(y*512,lp->lin);
  271.         if ( n == cons_now ) {
  272.         cons_y = i;
  273.         cons_cur();
  274.         }
  275.         if ( (n = lp->left) == ERR && fg != 0 ) {
  276.         n = cons_top;
  277.         fg = 0;
  278.         }
  279.     } else
  280.         putstr(y*512,"");
  281.     y += 16;
  282.     }
  283.     return ofs;
  284. }
  285. void    CON_open(int no)
  286. {
  287.     int     i,n,y;
  288.     WIND    *wp;
  289.     CHI_PTR *cp;
  290.     LIN_PTR *lp;
  291.  
  292.     cons_bios_set();
  293.  
  294.     if ( no == 999 ) {
  295.     DSP_box(0,0,639,15,COL_LINE,COL_JOHN);
  296.     DSP_string("<< MS-DOS CONSOL JOHN [\x1b\xEC] >>",
  297.         208,4,COL_JOHN2,COL_JOHN);
  298.     cons_max_y = MAX_Y;
  299.     cons_off_y = OFF_Y;
  300.     cons_wind = DOS_WIND;
  301.     cons_child = DOS_CHIL;
  302.  
  303.     } else {
  304.     if ( no > 2 ) no = act_wind;
  305.     cons_wind = no;
  306.     wp = &(win[cons_wind]);
  307.     cons_child = wp->now;
  308.     cp = &(wp->child[cons_child]);
  309.     cp->wrt_flg = TRUE;
  310.     DSP_string("MS-DOS",
  311.         296,wp->wind_y + 4,COL_RED,wp->color);
  312.     cons_max_y = wp->max_y;
  313.     cons_off_y = wp->wind_y + 16;
  314.     }
  315.  
  316.     wp = &(win[cons_wind]);
  317.     cp = &(wp->child[cons_child]);
  318.     n = cp->now_ptr;
  319.  
  320.     if ( n == ERR ) {
  321.     y = cons_top = cons_now = xalloc();
  322.     lp = get_lin(cons_now);
  323.     cons_rot = ERR;
  324.  
  325.     } else {
  326.     while ( n != ERR ) {
  327.         lp = get_lin(n);
  328.         if ( lp->left == ERR )
  329.            break;
  330.         n = lp->left;
  331.     }
  332.     y = cons_top = cons_now = n;
  333.     if ( (cons_rot = lp->right) != ERR ) {
  334.         lp = get_lin(cons_rot);
  335.         lp->left = ERR;
  336.         lp = get_lin(n);
  337.     }
  338.     }
  339.  
  340.     lp->left = lp->right = ERR;
  341.     for ( i = 0 ; i < MAX_LOG ; i++ ) {
  342.     n = lp->left = xalloc();
  343.     lp = get_lin(n);
  344.     lp->left = ERR;
  345.     lp->right = y;
  346.     y = n;
  347.     }
  348.  
  349.     if ( (n = cons_rot) != ERR ) {
  350.     for ( i = BAK_LOG ; n != ERR && i >= 0 ; i-- ) {
  351.         lp = get_lin(n);
  352.         n = lp->right;
  353.     }
  354.     }
  355.  
  356.     n = cons_top;
  357.     while ( n != ERR ) {
  358.     lp = get_lin(n);
  359.     n = lp->left;
  360.     }
  361.  
  362.     lp = get_lin(cons_now);
  363.     cons_pos = strlen(lp->lin);
  364.     if ( cons_pos > 0 && lp->lin[cons_pos-1] == '\n' )
  365.     cons_pos--;
  366.     cons_x = cons_pos;
  367.     lp->lin[cons_pos] = '\0';
  368.     cons_y = cons_max_y - 1;
  369.  
  370.     CON_redisp(0);
  371. }
  372. void    CON_close(void)
  373. {
  374.     int     i,n,c=0;
  375.     WIND    *wp;
  376.     CHI_PTR *cp;
  377.     LIN_PTR *lp;
  378.  
  379.     cons_bios_ret();
  380.     lp = get_lin(cons_now);
  381.     lp->lin[cons_pos] = '\0';
  382.  
  383.     if ( (n = lp->left) != ERR ) {
  384.     lp->left = ERR;
  385.     while ( n != ERR ) {
  386.         lp = get_lin(n);
  387.         i = lp->left;
  388.         xfree(n);
  389.         n = i;
  390.         c++;
  391.     }
  392.     }
  393.  
  394.     if ( cons_rot != ERR ) {
  395.     lp = get_lin(cons_top);
  396.     lp->right = cons_rot;
  397.     lp = get_lin(cons_rot);
  398.     lp->left = cons_top;
  399.     }
  400.  
  401.     wp = &(win[cons_wind]);
  402.     cp = &(wp->child[cons_child]);
  403.  
  404.     cp->cur_x = cons_x;
  405.     cp->cur_y = wp->max_y - 1;
  406.     cp->lin_max += MAX_LOG - c;
  407.     cp->lin_pos += MAX_LOG - c;
  408.     cp->top_ptr = ERR;
  409.     cp->now_ptr = cons_now;
  410.     wp->wrt_mode = 3;
  411. }
  412.  
  413. #define    MAX_HIS    8
  414. #define    MAX_LIN    160
  415.  
  416. static struct _LB {
  417.     int     len;
  418.     int     pos;
  419.     char    buf[MAX_LIN+4];
  420. } con_buf[MAX_HIS];
  421.  
  422. static    int    con_his=0;
  423. static    int    con_kan=0;
  424.  
  425. char    *CON_input(int ch)
  426. {
  427.     int     i,n;
  428.     char    *p;
  429.     struct _LB *lp;
  430.  
  431.     lp = &(con_buf[con_his]);
  432.     lp->buf[lp->len] = '\0';
  433.  
  434.     if ( con_kan != 0 ) {
  435.     if ( iskanji2(ch) )
  436.         ch = (con_kan << 8) | ch;
  437.     con_kan = 0;
  438.     }
  439.  
  440.     if ( ch == '\x08' && lp->pos > 0 ) {
  441.     lp->pos = kan_pos(lp->buf,lp->pos-1);
  442.     p = &(lp->buf[lp->pos]);
  443.     n = (iskan(p) ? 2:1);
  444.     strcpy(p,p+n);
  445.     lp->len -= n;
  446.  
  447.     while ( n-- > 0 )
  448.         putchar('\b');
  449.     printf("%s  ",p);
  450.     n = lp->len - lp->pos + 2;
  451.     while ( n-- > 0 )
  452.         putchar('\b');
  453.  
  454.     } else if ( ch == 0x7F ) {
  455.     if ( lp->pos < lp->len ) {
  456.         p = &(lp->buf[lp->pos]);
  457.         n = (iskan(p) ? 2:1);
  458.         strcpy(p,p+n);
  459.         lp->len -= n;
  460.  
  461.         printf("%s  ",p);
  462.         n = lp->len - lp->pos + 2;
  463.         while ( n-- > 0 )
  464.         putchar('\b');
  465.     }
  466.  
  467.     } else if ( ch == 0x1C ) {
  468.     if ( lp->pos < lp->len ) {
  469.         n = (iskan(&(lp->buf[lp->pos])) ? 2:1);
  470.         p = &(lp->buf[lp->pos]);
  471.         lp->pos += n;
  472.         while ( n-- > 0 )
  473.         putchar(*(p++));
  474.     }
  475.  
  476.     } else if ( ch == 0x1D ) {
  477.     if ( lp->pos > 0 ) {
  478.         lp->pos = kan_pos(lp->buf,lp->pos-1);
  479.         p = &(lp->buf[lp->pos]);
  480.         n = (iskan(p) ? 2:1);
  481.         while ( n-- > 0 )
  482.         putchar('\b');
  483.     }
  484.  
  485.     } else if ( ch == 0x1E ) {
  486.     for ( n = lp->pos ; n > 0 ; n-- )
  487.         putchar('\b');
  488.     for ( n = lp->len ; n > 0 ; n-- )
  489.         putchar(' ');
  490.     for ( n = lp->len ; n > 0 ; n-- )
  491.         putchar('\b');
  492.  
  493.     if ( --con_his < 0 )
  494.         con_his = (MAX_HIS - 1);
  495.  
  496.     lp = &(con_buf[con_his]);
  497.     printf("%s",lp->buf);
  498.     for ( n = lp->len - lp->pos ; n > 0 ; n-- )
  499.         putchar('\b');
  500.  
  501.     } else if ( ch == 0x1F ) {
  502.     for ( n = lp->pos ; n > 0 ; n-- )
  503.         putchar('\b');
  504.     for ( n = lp->len ; n > 0 ; n-- )
  505.         putchar(' ');
  506.     for ( n = lp->len ; n > 0 ; n-- )
  507.         putchar('\b');
  508.  
  509.     if ( ++con_his >= MAX_HIS )
  510.         con_his = 0;
  511.  
  512.     lp = &(con_buf[con_his]);
  513.     printf("%s",lp->buf);
  514.     for ( n = lp->len - lp->pos ; n > 0 ; n-- )
  515.         putchar('\b');
  516.  
  517.     } else if ( ch == 0x0D ) {
  518.     printf("%s\n",&(lp->buf[lp->pos]));
  519.     p = lp->buf;
  520.     if ( ++con_his >= MAX_HIS )
  521.         con_his = 0;
  522.     lp = &(con_buf[con_his]);
  523.     lp->pos = lp->len = 0;
  524.     lp->buf[0] = '\0';
  525.     return p;
  526.  
  527.     } else if ( ch == 0x1B ) {
  528.     for ( n = lp->pos ; n > 0 ; n-- )
  529.         putchar('\b');
  530.     for ( n = lp->len ; n > 0 ; n-- )
  531.         putchar(' ');
  532.     for ( n = lp->len ; n > 0 ; n-- )
  533.         putchar('\b');
  534.     lp->pos = lp->len = 0;
  535.     lp->buf[0] = '\x1B';
  536.     return lp->buf;
  537.  
  538.     } else if ( ch >= ' ' && lp->len < MAX_LIN ) {
  539.     n = ((ch & 0xFF00) != 0 ? 2:1);
  540.     if ( n == 1 && iskanji(ch) ) {
  541.         con_kan = ch;
  542.         return FALSE;
  543.     }
  544.     if ( lp->pos < lp->len ) {
  545.         p = &(lp->buf[lp->len + (n - 1)]);
  546.         for ( i = lp->len - lp->pos ; i > 0 ; i--,p-- )
  547.         *p = *(p - n);
  548.     }
  549.     i = lp->len - lp->pos;
  550.     p = &(lp->buf[lp->pos]);
  551.     if ( n == 1 ) {
  552.         lp->buf[lp->pos++] = ch;
  553.     } else {
  554.         lp->buf[lp->pos++] = ch >> 8;
  555.         lp->buf[lp->pos++] = ch;
  556.     }
  557.     lp->len += n;
  558.     lp->buf[lp->len] = '\0';
  559.     printf("%s",p);
  560.     while ( i-- > 0 )
  561.         putchar('\b');
  562.     }
  563.  
  564.     return NULL;
  565. }
  566.