home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 3
/
FREEWARE.BIN
/
towns_os
/
whisper
/
source
/
consol.c
< prev
next >
Wrap
Text File
|
1980-01-02
|
11KB
|
566 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "defs.h"
#include "graphic.h"
#include "buff.h"
#include "coldef.h"
#include "wind.h"
#define MAX_X 80
#define MAX_Y 28
#define TAB 8
#define OFF_Y 16
#define MAX_LOG 500
#define BAK_LOG 200
#define DOS_WIND 1 /* JOHN */
#define DOS_CHIL 4 /* Last Wind Buff */
void cons_bios_set(void);
void cons_bios_ret(void);
void vram_scrool(int adr,int lin);
int kan_pos(char *p,int n);
int iskan(char *str);
void wrt_ank(unsigned char ch,int adr);
void wrt_kan(unsigned short ch,int adr);
void wrt_cur(int adr);
extern int act_wind;
extern WIND win[MAX_WIND];
typedef union {
struct {
unsigned int edi;
unsigned int esi;
unsigned int edp;
unsigned int esp;
unsigned int ebx;
unsigned int edx;
unsigned int ecx;
unsigned int eax;
} e;
struct {
unsigned short di;
unsigned short __di;
unsigned short si;
unsigned short __si;
unsigned short bp;
unsigned short __bp;
unsigned short sp;
unsigned short __sp;
unsigned short bx;
unsigned short __bx;
unsigned short dx;
unsigned short __dx;
unsigned short cx;
unsigned short __cx;
unsigned short ax;
unsigned short __ax;
} x;
struct {
unsigned short di;
unsigned short __di;
unsigned short si;
unsigned short __si;
unsigned short bp;
unsigned short __bp;
unsigned short sp;
unsigned short __sp;
unsigned char bl, bh;
unsigned short __bx;
unsigned char dl, dh;
unsigned short __dx;
unsigned char cl, ch;
unsigned short __cx;
unsigned char al, ah;
unsigned short __ax;
} h;
} REGS;
static int cons_rot=ERR;
static int cons_top=ERR;
static int cons_now=ERR;
static int cons_pos=0;
static int cons_x=0;
static int cons_y=0;
static int cons_bak=0;
static int cons_max_y=MAX_Y;
static int cons_off_y=OFF_Y;
static int cons_wind=DOS_WIND;
static int cons_child=DOS_CHIL;
void cons_scrool(void)
{
LIN_PTR *lp;
LIN_PTR *tp;
if ( ++cons_y >= cons_max_y ) {
cons_y = cons_max_y - 1;
vram_scrool(cons_off_y * 512,(cons_max_y - 1) * 16);
}
lp = get_lin(cons_now);
lp->lin[cons_pos] = '\0';
if ( lp->left == ERR ) {
lp->left = cons_top;
tp = get_lin(cons_top);
cons_top = tp->left;
tp->right = cons_now;
tp->left = ERR;
tp = get_lin(cons_top);
tp->right = ERR;
}
cons_now = lp->left;
lp = get_lin(cons_now);
lp->lin[0] = '\0';
cons_pos = 0;
}
void ank_put(unsigned char ch)
{
LIN_PTR *lp;
lp = get_lin(cons_now);
while ( cons_pos <= cons_x )
lp->lin[cons_pos++] = ' ';
lp->lin[cons_x] = ch;
lp->lin[cons_pos] = '\0';
wrt_ank(ch,cons_x * 4 + (cons_y * 16 + cons_off_y) * 512);
if ( ++cons_x >= MAX_X ) {
cons_x = 0;
cons_scrool();
}
}
void kan_put(unsigned short ch)
{
LIN_PTR *lp;
if ( cons_x >= (MAX_X - 1) ) {
cons_x = 0;
cons_scrool();
}
lp = get_lin(cons_now);
while ( cons_pos < (cons_x + 2) )
lp->lin[cons_pos++] = ' ';
lp->lin[cons_x] = ch >> 8;
lp->lin[cons_x+1] = ch;
lp->lin[cons_pos] = '\0';
wrt_kan(ch,cons_x * 4 + (cons_y * 16 + cons_off_y) * 512);
if ( (cons_x += 2) >= MAX_X ) {
cons_x = 0;
cons_scrool();
}
}
void cons_cur(void)
{
wrt_cur((cons_x * 4) + (cons_y * 16 + (cons_off_y + 14)) * 512);
}
void cons_char(unsigned char ch)
{
int n;
LIN_PTR *lp;
cons_cur();
if ( cons_bak != 0 ) {
if ( iskanji2(ch) ) {
kan_put((cons_bak << 8) | ch);
cons_bak = 0;
goto ENDOF;
}
ank_put(cons_bak);
cons_bak = 0;
}
switch(ch) {
case '\x0D':
cons_x = 0;
break;
case '\x0A':
lp = get_lin(cons_now);
lp->lin[cons_pos++] = '\n';
lp->lin[cons_pos] = '\0';
cons_scrool();
break;
case '\x09':
n = TAB - (cons_x % TAB);
while ( n-- > 0 )
ank_put(' ');
break;
case '\x08':
if ( cons_x > 0 )
cons_x--;
else {
cons_x = MAX_X - 1;
if ( cons_y > 0 ) {
cons_y--;
lp = get_lin(cons_now);
if ( lp->right != ERR ) {
cons_now = lp->right;
lp = get_lin(cons_now);
cons_pos = strlen(lp->lin);
if ( cons_pos > 0 && lp->lin[cons_pos-1] == '\n' )
cons_pos--;
}
}
}
break;
case '\x1B':
break;
default:
if ( iskanji(ch) )
cons_bak = ch;
else if ( ch != '\0' )
ank_put(ch);
break;
}
ENDOF:
cur_x = cons_x * 8;
cur_y = cons_y * 16 + cons_off_y;
cons_cur();
}
void cons_bios(REGS *reg)
{
cons_char(reg->h.al);
}
int CON_redisp(int ofs)
{
int i,n,y,fg,c;
LIN_PTR *lp;
if ( ofs < 0 )
ofs = 0;
n = cons_now;
fg = c = 0;
for ( i = cons_y + ofs ; i > 0 ; i-- ) {
lp = get_lin(n);
if ( lp->right == ERR ) {
if ( fg == 0 && cons_rot != ERR ) {
n = cons_rot;
fg = 1;
} else
break;
} else if ( fg == 1 && ++c >= BAK_LOG )
break;
else
n = lp->right;
}
ofs -= i;
y = cons_off_y;
for ( i = 0 ; i < cons_max_y ; i++ ) {
if ( n != ERR ) {
lp = get_lin(n);
putstr(y*512,lp->lin);
if ( n == cons_now ) {
cons_y = i;
cons_cur();
}
if ( (n = lp->left) == ERR && fg != 0 ) {
n = cons_top;
fg = 0;
}
} else
putstr(y*512,"");
y += 16;
}
return ofs;
}
void CON_open(int no)
{
int i,n,y;
WIND *wp;
CHI_PTR *cp;
LIN_PTR *lp;
cons_bios_set();
if ( no == 999 ) {
DSP_box(0,0,639,15,COL_LINE,COL_JOHN);
DSP_string("<< MS-DOS CONSOL JOHN [\x1b\xEC] >>",
208,4,COL_JOHN2,COL_JOHN);
cons_max_y = MAX_Y;
cons_off_y = OFF_Y;
cons_wind = DOS_WIND;
cons_child = DOS_CHIL;
} else {
if ( no > 2 ) no = act_wind;
cons_wind = no;
wp = &(win[cons_wind]);
cons_child = wp->now;
cp = &(wp->child[cons_child]);
cp->wrt_flg = TRUE;
DSP_string("MS-DOS",
296,wp->wind_y + 4,COL_RED,wp->color);
cons_max_y = wp->max_y;
cons_off_y = wp->wind_y + 16;
}
wp = &(win[cons_wind]);
cp = &(wp->child[cons_child]);
n = cp->now_ptr;
if ( n == ERR ) {
y = cons_top = cons_now = xalloc();
lp = get_lin(cons_now);
cons_rot = ERR;
} else {
while ( n != ERR ) {
lp = get_lin(n);
if ( lp->left == ERR )
break;
n = lp->left;
}
y = cons_top = cons_now = n;
if ( (cons_rot = lp->right) != ERR ) {
lp = get_lin(cons_rot);
lp->left = ERR;
lp = get_lin(n);
}
}
lp->left = lp->right = ERR;
for ( i = 0 ; i < MAX_LOG ; i++ ) {
n = lp->left = xalloc();
lp = get_lin(n);
lp->left = ERR;
lp->right = y;
y = n;
}
if ( (n = cons_rot) != ERR ) {
for ( i = BAK_LOG ; n != ERR && i >= 0 ; i-- ) {
lp = get_lin(n);
n = lp->right;
}
}
n = cons_top;
while ( n != ERR ) {
lp = get_lin(n);
n = lp->left;
}
lp = get_lin(cons_now);
cons_pos = strlen(lp->lin);
if ( cons_pos > 0 && lp->lin[cons_pos-1] == '\n' )
cons_pos--;
cons_x = cons_pos;
lp->lin[cons_pos] = '\0';
cons_y = cons_max_y - 1;
CON_redisp(0);
}
void CON_close(void)
{
int i,n,c=0;
WIND *wp;
CHI_PTR *cp;
LIN_PTR *lp;
cons_bios_ret();
lp = get_lin(cons_now);
lp->lin[cons_pos] = '\0';
if ( (n = lp->left) != ERR ) {
lp->left = ERR;
while ( n != ERR ) {
lp = get_lin(n);
i = lp->left;
xfree(n);
n = i;
c++;
}
}
if ( cons_rot != ERR ) {
lp = get_lin(cons_top);
lp->right = cons_rot;
lp = get_lin(cons_rot);
lp->left = cons_top;
}
wp = &(win[cons_wind]);
cp = &(wp->child[cons_child]);
cp->cur_x = cons_x;
cp->cur_y = wp->max_y - 1;
cp->lin_max += MAX_LOG - c;
cp->lin_pos += MAX_LOG - c;
cp->top_ptr = ERR;
cp->now_ptr = cons_now;
wp->wrt_mode = 3;
}
#define MAX_HIS 8
#define MAX_LIN 160
static struct _LB {
int len;
int pos;
char buf[MAX_LIN+4];
} con_buf[MAX_HIS];
static int con_his=0;
static int con_kan=0;
char *CON_input(int ch)
{
int i,n;
char *p;
struct _LB *lp;
lp = &(con_buf[con_his]);
lp->buf[lp->len] = '\0';
if ( con_kan != 0 ) {
if ( iskanji2(ch) )
ch = (con_kan << 8) | ch;
con_kan = 0;
}
if ( ch == '\x08' && lp->pos > 0 ) {
lp->pos = kan_pos(lp->buf,lp->pos-1);
p = &(lp->buf[lp->pos]);
n = (iskan(p) ? 2:1);
strcpy(p,p+n);
lp->len -= n;
while ( n-- > 0 )
putchar('\b');
printf("%s ",p);
n = lp->len - lp->pos + 2;
while ( n-- > 0 )
putchar('\b');
} else if ( ch == 0x7F ) {
if ( lp->pos < lp->len ) {
p = &(lp->buf[lp->pos]);
n = (iskan(p) ? 2:1);
strcpy(p,p+n);
lp->len -= n;
printf("%s ",p);
n = lp->len - lp->pos + 2;
while ( n-- > 0 )
putchar('\b');
}
} else if ( ch == 0x1C ) {
if ( lp->pos < lp->len ) {
n = (iskan(&(lp->buf[lp->pos])) ? 2:1);
p = &(lp->buf[lp->pos]);
lp->pos += n;
while ( n-- > 0 )
putchar(*(p++));
}
} else if ( ch == 0x1D ) {
if ( lp->pos > 0 ) {
lp->pos = kan_pos(lp->buf,lp->pos-1);
p = &(lp->buf[lp->pos]);
n = (iskan(p) ? 2:1);
while ( n-- > 0 )
putchar('\b');
}
} else if ( ch == 0x1E ) {
for ( n = lp->pos ; n > 0 ; n-- )
putchar('\b');
for ( n = lp->len ; n > 0 ; n-- )
putchar(' ');
for ( n = lp->len ; n > 0 ; n-- )
putchar('\b');
if ( --con_his < 0 )
con_his = (MAX_HIS - 1);
lp = &(con_buf[con_his]);
printf("%s",lp->buf);
for ( n = lp->len - lp->pos ; n > 0 ; n-- )
putchar('\b');
} else if ( ch == 0x1F ) {
for ( n = lp->pos ; n > 0 ; n-- )
putchar('\b');
for ( n = lp->len ; n > 0 ; n-- )
putchar(' ');
for ( n = lp->len ; n > 0 ; n-- )
putchar('\b');
if ( ++con_his >= MAX_HIS )
con_his = 0;
lp = &(con_buf[con_his]);
printf("%s",lp->buf);
for ( n = lp->len - lp->pos ; n > 0 ; n-- )
putchar('\b');
} else if ( ch == 0x0D ) {
printf("%s\n",&(lp->buf[lp->pos]));
p = lp->buf;
if ( ++con_his >= MAX_HIS )
con_his = 0;
lp = &(con_buf[con_his]);
lp->pos = lp->len = 0;
lp->buf[0] = '\0';
return p;
} else if ( ch == 0x1B ) {
for ( n = lp->pos ; n > 0 ; n-- )
putchar('\b');
for ( n = lp->len ; n > 0 ; n-- )
putchar(' ');
for ( n = lp->len ; n > 0 ; n-- )
putchar('\b');
lp->pos = lp->len = 0;
lp->buf[0] = '\x1B';
return lp->buf;
} else if ( ch >= ' ' && lp->len < MAX_LIN ) {
n = ((ch & 0xFF00) != 0 ? 2:1);
if ( n == 1 && iskanji(ch) ) {
con_kan = ch;
return FALSE;
}
if ( lp->pos < lp->len ) {
p = &(lp->buf[lp->len + (n - 1)]);
for ( i = lp->len - lp->pos ; i > 0 ; i--,p-- )
*p = *(p - n);
}
i = lp->len - lp->pos;
p = &(lp->buf[lp->pos]);
if ( n == 1 ) {
lp->buf[lp->pos++] = ch;
} else {
lp->buf[lp->pos++] = ch >> 8;
lp->buf[lp->pos++] = ch;
}
lp->len += n;
lp->buf[lp->len] = '\0';
printf("%s",p);
while ( i-- > 0 )
putchar('\b');
}
return NULL;
}