#include    <stdio.h>
#include    <ctype.h>
#include    "defs.h"

#define	MAXKAN	240*37

#define	DMYKAN	0x1D
#define TABCHR  0x09
#define CRCHR   0x1F
#define memrcpy _rmemcpy

extern int	Line_no;
extern short	Line_X,Line_Y;

extern void	strcpy();
extern void	memcpy();
extern void	memset();
extern void	Dsp_vram();
extern int	Get_key();
extern void	ins_chr();

        UCHAR   vram[MAX_X*MAX_Y*2];
	short	COLOR=7;
	short   dlp_flg=FALSE;
	short	Woff_X=0,Woff_Y=0; 
	short	Wsiz_X=MAX_X,Wsiz_Y=MAX_Y;
	short	Wscr_X=0,Wscr_Y=0;
	short	Wind_flg=FALSE;
static	UCHAR	dram[MAX_X*MAX_Y*2];
static  int     Line_tmp[MAX_Y];

BOOL	iskan2(ptr)
LONG	ptr;
{
   int    ch;

   ch = *Cnv_ptr(++ptr);
   if ( ptr < btm_ptr && iskanji2(ch) )
	return TRUE;
   else
	return FALSE;
}
UCHAR	*Set_Str(sp,vp,att,str)
UCHAR	*sp,*vp;
int	att;
char	*str;
{
    while ( *str != '\0' ) {
	if ( vp >= (sp+MAX_X*MAX_Y*2) )
	    return vp;
        *(vp++) = att;
	*(vp++) = *(str++);
    }
    return vp;
}
void	Set_vram_wind()
{
    int     x,y;
    UCHAR   *dp,*p;

    dp = vram + Woff_X * 2 + (MAX_X * 2) * Woff_Y;
    if ( Woff_Y > 0 ) {
	p = dp - (MAX_X * 2);
	if ( Woff_X > 0 ) {
	    *(p-2) = COLOR; *(p-1) = 0x98;
	}
	for ( x = 0 ; x < Wsiz_X ; x++ ) {
	    *(p++) = COLOR; *(p++) = 0x95;
	}
	if ( (Woff_X + Wsiz_X) < MAX_X ) {
	    *(p++) = COLOR; *(p++) = 0x99;
	}
    }
    for ( y = 0 ; y < Wsiz_Y ; y++,dp += (MAX_X * 2) ) {
	if ( Woff_X > 0 ) {
	     *(dp-2) = COLOR; *(dp-1) = 0x96;
	}
	if ( (Woff_X + Wsiz_X) < MAX_X ) {
	     *(dp+Wsiz_X*2) = COLOR; *(dp+Wsiz_X*2+1) = 0x96;
	}
    }
    if ( (Woff_Y + Wsiz_Y) < MAX_Y ) {
	if ( Woff_X > 0 ) {
	    *(dp-2) = COLOR; *(dp-1) = 0x9A;
	}
	for ( x = 0 ; x < Wsiz_X ; x++ ) {
	    *(dp++) = COLOR; *(dp++) = 0x95;
	}
	if ( (Woff_X + Wsiz_X) < MAX_X ) {
	    *(dp++) = COLOR; *(dp++) = 0x9B;
	}
    }
}
void    Set_vram_line(vp,no)
UCHAR	*vp;
int	no;
{
    int     i;
    char    tmp[12];

    if ( Line_tmp[no] >= 0 )
	sprintf(tmp,"%-5d\x96",Line_no+Line_tmp[no]+1);
    else
	strcpy(tmp,"+    \x96");
    for ( i = 0 ; i < 6 ; i++ ) {
	*(vp++) = COLOR; *(vp++) = tmp[i];
    }
}
void	Set_vram_sub()
{
    int     y;
    UCHAR   *sp,*dp;

    if ( Wind_flg != ERR ) {
        Set_vram_wind();
        Wind_flg = ERR;
    }

    if ( dlp_flg != FALSE ) {
	Wsiz_X -= 6;
	Woff_X += 6;
    }
    if ( (Wscr_X + Wsiz_X) > MAX_X )
	Wscr_X = 0;
    if ( Wscr_X > Cur_X && (Wscr_X = Cur_X - 10) < 0 )
	Wscr_X = 0;
    if ( (Wscr_X + Wsiz_X) <= Cur_X ) {
	Wscr_X = (Cur_X - Wsiz_X) + 10;
	if ( (Wscr_X + Wsiz_X) > MAX_X )
	    Wscr_X = MAX_X - Wsiz_X;
    }
    if ( (Wscr_Y + Wsiz_Y) > MAX_Y )
	Wscr_Y = 0;
    if ( Wscr_Y > Cur_Y && (Wscr_Y = Cur_Y - 5) < 0 )
	Wscr_Y = 0;
    if ( (Wscr_Y + Wsiz_Y) <= Cur_Y ) {
	Wscr_Y = (Cur_Y - Wsiz_Y) + 5;
	if ( (Wscr_Y + Wsiz_Y) > MAX_Y )
	    Wscr_Y = MAX_Y - Wsiz_Y;
    }

    sp = dram + Wscr_X * 2 + (MAX_X * 2) * Wscr_Y;
    dp = vram + Woff_X * 2 + (MAX_X * 2) * Woff_Y;
    if ( dlp_flg == FALSE ) {
        for ( y = 0 ; y < Wsiz_Y ; y++,sp += (MAX_X * 2),dp += (MAX_X * 2) )
	    memcpy(dp,sp,Wsiz_X * 2);
    } else {
        for ( y = 0 ; y < Wsiz_Y ; y++,sp += (MAX_X * 2),dp += (MAX_X * 2) ) {
	    Set_vram_line(dp-12,y+Wscr_Y);
	    memcpy(dp,sp,Wsiz_X * 2);
	}
    }
    Cur_X = Cur_X + Woff_X - Wscr_X;
    Cur_Y = Cur_Y + Woff_Y - Wscr_Y;

    if ( dlp_flg != FALSE ) {
	Wsiz_X += 6;
	Woff_X -= 6;
    }
}
void	Set_vram()
{
    int      ch,i,x,y,col,ln,ol;
    register UCHAR   *vp;
    register LONG    ptr;
    UCHAR    *sp;

    sp = (Wind_flg != FALSE ? dram : vram);
RESET:
    memset(sp,0,MAX_X * MAX_Y * 2);
    ptr = top_ptr; col = COLOR;
    ol = (-1);
    for ( y = 0 ; y < MAX_Y ; y++ )
	Line_tmp[y] = (-1);
    for ( ln = y = 0 ; y < MAX_Y ; y++ ) {
    	vp = sp + (MAX_X * 2) * y;
	if ( ln == ol )
	    Line_tmp[y] = (-1);
	else
	    ol = Line_tmp[y] = ln;
	for ( x = 0 ; x < MAX_X ; ) {
	    if ( chk_ptr != ERR ) {
		if ( ptr >= chk_ptr && ptr < cke_ptr )
		    col = ((COLOR - 1)&0x0F) | 0x10;
		else
		    col = COLOR;
	    }
	    if ( ptr == ent_ptr ) {
		Line_X = Cur_X = x;
		Cur_Y = y;
		Line_Y = ln;
	    }
	    if ( ptr >= btm_ptr ) {
		vp = Set_Str(sp,vp,col,"[EOF]");
		goto ENDOF;
	    }
	    ch = *Cnv_ptr(ptr);
	    if ( ch == '\x0D' ) {
		if ( CONTRL > 0 ) {
		    *(vp++) = (col-2)&0x0F;
		    *(vp++) = CRCHR;
		}
		ptr += 2;
		ln++;
		break;
	    } else if ( ch == '\t' ) {
		i = TAB - (x % TAB);
		if ( CONTRL > 1 && i-- > 0 ) {
		    *(vp++) = (col-1)&0x0F;
		    *(vp++) = TABCHR;
		    x++;
		}
		if ( CONTRL > 1 ) {
		    while ( i-- > 0 && x < MAX_X ) {
			*(vp++) = (col-1)&0x0F;
			*(vp++) = '.';
		        x++;
		    }
		} else {
		    while ( i-- > 0 && x < MAX_X ) {
			*(vp++) = col;
			*(vp++) = ' ';
		        x++;
		    }
		}
		ptr++;
	    } else if ( iskanji(ch) && iskan2(ptr) != FALSE ) {
		if ( x != (MAX_X - 1) ) {
#ifdef	TOWNS
		    *(vp++) = col|0x40;
		    *(vp++) = ch; ptr++;
		    *(vp++) = col|0x80;
		    *(vp++) = *Cnv_ptr(ptr++);
#else
		    i = (ch << 8); ptr++;
		    i |= (*Cnv_ptr(ptr++) & 0xff);
		    i = sjistojis(i);
		    *(vp++) = col|0x40;
		    *(vp++) = i >> 8;
		    *(vp++) = col|0x80;
		    *(vp++) = i & 0xff;
#endif
		    x += 2;
		} else {
		    *(vp++) = col;
		    *(vp++) = 0x1C;
		    x++;
		}
	    } else {
		*(vp++) = col;
		*(vp++) = ch;
		x++; ptr++;
	    }
	}
    }
    if ( ptr <= lin_ptr ) {
	for ( i = 0 ; top_ptr < btm_ptr && i < 5 ; i++ ) {
	    top_ptr = Nxt_line(top_ptr);
	    Line_no++;
	}
	goto RESET;
    }
ENDOF:
    if ( Wind_flg != FALSE )
	Set_vram_sub();
}
void	ASCII_code()
{
    static int no=0;
    int     i,ch,Bk_X,Bk_Y;
    unsigned int ec;
    char    tmp[8];
    UCHAR   *vp;

    Bk_X = Cur_X; Bk_Y = Cur_Y;
    memset(dram,0,MAX_X * MAX_Y * 2);
    for ( i = 0 ; i < 256 ; i++ ) {
	sprintf(tmp,"%02X %c ",i,i);
        vp = dram + (i / 16) * 10 + (MAX_X * 2) * (i % 16 + 4);
	*(vp++) = 0x0F; *(vp++) = tmp[0];
	*(vp++) = 0x0F; *(vp++) = tmp[1];
	*(vp++) = 0x0F; *(vp++) = tmp[2];
	*(vp++) = 0x05; *(vp++) = tmp[3];
	*(vp++) = 0x0F; *(vp++) = tmp[4];
    }

    for ( ; ; ) {
	Cur_X = (no / 16) * 5 + 3;
	Cur_Y = (no % 16) + 4;
        Dsp_vram(dram);
	ch = Get_key(&ec);
	if ( ch == 0x0D || ec == 0x7300 )
	    ins_chr(&no,1);
	else if ( ch == 0x1B || ec == 0x7200 )
	    break;
	else if ( ec == 0x4D00 )
	    no = (no - 1) & 0xFF;
	else if ( ec == 0x5000 )
	    no = (no + 1) & 0xFF;
	else if ( ec == 0x4F00 )
	    no = (no - 16) & 0xFF;
	else if ( ec == 0x5100 )
	    no = (no + 16) & 0xFF;
    }
    Cur_X = Bk_X; Cur_Y = Bk_Y;
}
int	Kan_code_get(no,arg)
int     no;
char    *arg;
{
    int     cd,hi,lo;

    hi = no / 94 + 0x21;
    lo = no % 94 + 0x21;
    cd = ((hi << 8) | lo);

    if ( (hi & 1) != 0 )
	lo += 0x1F;
    else
	lo += 0x7D;
    if ( lo >= 0x7F )
	lo++;
    hi = (hi - 0x21 >> 1) + 0x81;
    if ( hi > 0x9F )
	hi += 0x40;

    *(arg++) = hi;
    *(arg++) = lo;
    *arg = '\0';

    return cd;
}
void	Kan_code_sub(no)
int	no;
{
    int    i,cd;
    char   tmp[12],str[8];
    UCHAR  *vp;

    memset(dram,0,MAX_X * MAX_Y * 2);
    for ( i = 0 ; no < MAXKAN && i < 240 ; i++,no++ ) {
	cd = Kan_code_get(no,str);
	sprintf(tmp,"%04X",cd);
        vp = dram + (i / 24) * 16 + (MAX_X * 2) * (i % 24 + 2);
	*(vp++) = 0x0F; *(vp++) = tmp[0];
	*(vp++) = 0x0F; *(vp++) = tmp[1];
	*(vp++) = 0x0F; *(vp++) = tmp[2];
	*(vp++) = 0x0F; *(vp++) = tmp[3];
	*(vp++) = 0x0F; *(vp++) = 0x20;
	*(vp++) = 0x45; *(vp++) = str[0];
	*(vp++) = 0x85; *(vp++) = str[1];
	*(vp++) = 0x0F; *(vp++) = 0x20;
    }
}
void	KANJI_code()
{
    static int cs=0,no=0;
    int     ch,od,Bk_X,Bk_Y;
    unsigned int ec;
    char    str[4];

    Bk_X = Cur_X; Bk_Y = Cur_Y;
    for ( od = ERR ; ; ) {
	if ( od != no ) {
	    Kan_code_sub(no);
	    od = no;
	}
	Cur_X = (cs / 24) * 8 + 5;
	Cur_Y = (cs % 24) + 2;
        Dsp_vram(dram);
	ch = Get_key(&ec);
	if ( ch == 0x0D || ec == 0x7300 ) {
	    Kan_code_get(no+cs,str);
	    ins_chr(str,2);
	} else if ( ch == 0x1B || ec == 0x7200 )
	    break;
	else if ( ec == 0x4D00 && --cs < 0 )
	    cs = (240 - 1);
	else if ( ec == 0x5000 && ++cs >= 240 )
	    cs = 0;
	else if ( ec == 0x4F00 && (cs -= 24) < 0 )
	    cs += 240;
	else if ( ec == 0x5100 && (cs += 24) >= 240 )
	    cs -= 240;
	if ( (no + cs) >= MAXKAN )
	    cs = (MAXKAN-1) - no;
	else if ( ec == 0x4D04 && no > 0 )
	    no -= 240;
	else if ( ec == 0x5004 && (no += 240) >= MAXKAN )
	    no -= 240;
    }
    Cur_X = Bk_X; Cur_Y = Bk_Y;
}
