home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Phoenix Heaven Sunny 2
/
APPARE2.BIN
/
oh_towns
/
dic
/
src
/
scrn.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-20
|
14KB
|
678 lines
/********************************************
Screen Display Func
*********************************************/
#include "defs.h"
#include "scrn.h"
#ifdef MSDOS
static char far *FAR_STRCPY(char far *buf, register char *s)
{
register char far *p = buf;
while ( *s != '\0' )
*(p++) = *(s++);
*p = '\0';
return buf;
}
static char *NEAR_STRCPY(char *buf, register char far *s)
{
register char *p = buf;
while ( *s != '\0' )
*(p++) = *(s++);
*p = '\0';
return buf;
}
#endif /* MSDOS */
typedef struct _LINPTR {
struct _LINPTR FAR *next;
struct _LINPTR FAR *back;
int line;
char str[1];
} LINPTR;
static LINPTR FAR *dic_line_now = NULL;
static int dic_line_count = 0;
static int dic_mem_flag = FALSE;
static char dic_str_tmp[COLS_MAX + 2];
static LINPTR FAR *dic_alloc_line(char *str, int line)
{
LINPTR FAR *lp;
if ( (lp = (LINPTR FAR *)MALLOC(sizeof(LINPTR) + strlen(str))) == NULL )
return NULL;
lp->next = lp->back = NULL;
lp->line = line;
FAR_STRCPY(lp->str, str);
return lp;
}
static void dic_free_line()
{
LINPTR FAR *lp;
if ( dic_line_now != NULL ) {
while ( (lp = dic_line_now->back) != NULL )
dic_line_now = lp;
}
while ( (lp = dic_line_now) != NULL ) {
dic_line_now = lp->next;
FREE(lp);
}
}
static char *dic_next_line()
{
LINPTR FAR *lp;
if ( cd_gets(dic_str_tmp, cols_max - 1, dic_line_count) == NULL ) {
while ( menu_top != NULL ) {
menu_max--;
menu_top = menu_top->next;
}
while ( betu_top != NULL ) {
betu_max--;
betu_top = betu_top->next;
}
return NULL;
}
if ( dic_mem_flag )
return dic_str_tmp;
if ( (lp = dic_alloc_line(dic_str_tmp, dic_line_count)) == NULL ) {
dic_mem_flag = TRUE;
dic_free_line();
return dic_str_tmp;
}
dic_line_count++;
if ( dic_line_now != NULL ) {
dic_line_now->next = lp;
lp->back = dic_line_now;
}
dic_line_now = lp;
return NEAR_STRCPY(dic_str_tmp, lp->str);
}
static char *dic_goto_line(int line)
{
if ( dic_line_now == NULL )
return NULL;
while ( line < dic_line_now->line ) {
if ( dic_line_now->back == NULL )
return NULL;
dic_line_now = dic_line_now->back;
}
while ( line > dic_line_now->line ) {
if ( dic_line_now->next == NULL )
return NULL;
dic_line_now = dic_line_now->next;
}
return NEAR_STRCPY(dic_str_tmp, dic_line_now->str);
}
static LINPTR FAR *dic_set_line(char *str)
{
LINPTR FAR *lp;
if ( (lp = dic_alloc_line(str, dic_line_count)) == NULL )
return NULL;
dic_line_count++;
if ( dic_line_now != NULL ) {
dic_line_now->next = lp;
lp->back = dic_line_now;
}
dic_line_now = lp;
return lp;
}
static void dic_set_menu(int line, int sx, int bx)
{
if ( menu_max >= MENU_MAX )
return;
menu_tab[menu_max].sx = sx;
menu_tab[menu_max].bx = bx;
menu_tab[menu_max].sy = menu_tab[menu_max].by = line;
menu_max++;
}
static void dic_init_line(int sw)
{
dic_free_line();
dic_line_count = 0;
dic_mem_flag = sw ? FALSE:TRUE;
}
static struct {
short flag;
int line;
} scrn_tab[LINE_MAX];
static void dic_scrn_clear()
{
int n;
for ( n = 0 ; n < lines_max ; n++ ) {
scrn_tab[n].flag = (-3);
scrn_tab[n].line = (-1);
}
}
static int dic_menu_screen(int top, int menu)
{
int n;
int line;
int ps, st, ed;
int ex, flag;
uchar *p;
while ( top > menu_tab[menu].sy )
top--;
while ( (menu_tab[menu].by - top) >= (lines_max - 1) )
top++;
line = top;
st = menu_tab[menu].sy * COLS_MAX + menu_tab[menu].sx;
ed = menu_tab[menu].by * COLS_MAX + menu_tab[menu].bx;
CUROFF();
for ( n = 0 ; n < (lines_max - 1) ; n++, line++ ) {
flag = (line >= menu_tab[menu].sy &&
line <= menu_tab[menu].by ? menu : (-1));
if ( scrn_tab[n].flag == flag && scrn_tab[n].line == line )
continue;
scrn_tab[n].line = line;
scrn_tab[n].flag = flag;
LOCATE(0, n);
if ( (p = dic_goto_line(line)) == NULL ) {
ERALINE();
continue;
}
ex = FALSE;
ps = line * COLS_MAX;
while ( *p != '\n' && *p != '\0' ) {
if ( ex == FALSE && ps >= st && ps < ed ) {
REVCOL();
ex = TRUE;
}
if ( ex != FALSE && ps >= ed ) {
STDCOL();
ex = FALSE;
}
if ( *p >= ' ' )
PUTC(*p);
p++;
ps++;
}
if ( ex != FALSE )
STDCOL();
if ( *p == '\n' )
ERALINE();
}
LOCATE(0, n);
ERALINE();
CURON();
FLUSH();
return top;
}
static int dic_menu_select(int top, int menu)
{
int ch;
#ifdef CURSES
#ifdef NEWS
setlocale(LC_CTYPE, "");
#endif
initscr();
cbreak();
noecho();
scrollok(stdscr, TRUE);
idlok(stdscr, TRUE);
cols_max = COLS;
lines_max = LINES;
#endif /* CURSES */
dic_scrn_clear();
for ( ; ; ) {
top = dic_menu_screen(top, menu);
ch = GETCH();
switch(ch) {
case '\n': case '\r':
goto ENDOF;
case '\033':
case 'q': case 'Q': case 'Q'-'@':
menu = ERR;
goto ENDOF;
case ' ':
case '\x1F': case '\x1C':
case 'd': case 'D': case 'D'-'@':
case 'n': case 'N': case 'N'-'@':
case 'j': case 'J': /* case 'J'-'@': */
if ( ++menu >= menu_max )
menu = 0;
break;
case '\b':
case '\x1E': case '\x1D':
case 'u': case 'U': case 'U'-'@':
case 'p': case 'P': case 'P'-'@':
case 'k': case 'K': case 'K'-'@':
if ( --menu < 0 )
menu = menu_max - 1;
break;
case 'L'-'@':
REFRESH();
break;
}
}
ENDOF:
CLS();
FLUSH();
#ifdef CURSES
endwin();
#endif
return menu;
}
static void dic_puts(uchar *str, FILE *fp)
{
for ( ; *str != '\0' ; str++ ) {
if ( fp != NULL ) {
if ( tex_out_flag ) {
switch(*str) {
case CH_BOLD_ON:
fputs("\\bold{", fp);
break;
case CH_BOLD_OFF:
putc('}', fp);
break;
case CH_ITALIC_ON:
fputs("\\slide{", fp);
break;
case CH_ITALIC_OFF:
putc('}', fp);
break;
default:
putc(*str, fp);
break;
}
} else {
if ( *str >= '\n' )
putc(*str, fp);
}
} else if ( color_flag ) {
switch(*str) {
case CH_BOLD_ON: BOLD_ON(); break;
case CH_BOLD_OFF: BOLD_OFF(); break;
case CH_ITALIC_ON: ITALIC_ON(); break;
case CH_ITALIC_OFF: ITALIC_OFF(); break;
case '\n': ERALINE(); PUTC('\n'); break;
default: PUTC(*str); break;
}
} else {
if ( *str > '\n' )
PUTC(*str);
else if ( *str == '\n' ) {
ERALINE();
PUTC('\n');
}
}
}
}
int dic_display(ulong block, ushort offset)
{
int ch;
int line, max, menu;
int fg = FALSE;
char *p;
POINT tab[1];
#ifdef MORE
FILE *fp;
#endif /* MORE */
LOOP:
if ( dic_seek(block, offset) )
return ERR;
dic_init_line(menu_disp_flg);
if ( menu_disp_flg == FALSE )
goto NOMENU;
for ( max = 0 ; max < MENU_CHK_LINE &&
(p = dic_next_line()) != NULL ; max++ )
;
if ( dic_mem_flag ) {
fprintf(stderr, "Menu Memory Alloc Error\n");
return ERR;
}
if ( menu_max > 0 ) {
while ( max < HONBUN_MAX_LINE && (p = dic_next_line()) != NULL )
max++;
if ( dic_mem_flag ) {
fprintf(stderr, "Menu Memory Alloc Error\n");
return ERR;
}
line = max - lines_max + 1;
if ( (menu = dic_menu_select(0, 0)) < 0 )
return ERR;
dic_display(menu_tab[menu].pos.block,
menu_tab[menu].pos.offset);
goto LOOP;
}
fg = TRUE;
NOMENU:
if ( extdisp_flag ) {
tab[0].block = block;
tab[0].offset = offset;
pager(tab, 1, menu_disp_flg);
return FALSE;
}
#ifdef MORE
if ( pause_flg == FALSE || (fp = popen(MORE, "w")) == NULL )
fp = stdout;
#endif /* MORE */
for ( max = line = 0 ; max < HONBUN_MAX_LINE ; max++ ) {
if ( fg == TRUE && (p = dic_goto_line(max)) == NULL ) {
dic_mem_flag = TRUE;
dic_free_line();
fg = FALSE;
}
if ( fg == FALSE && (p = dic_next_line()) == NULL )
break;
if ( ext_out_fp != NULL )
dic_puts(p, ext_out_fp);
#ifdef MORE
dic_puts(p, fp);
#else
if ( ++line >= lines_max ) {
if ( pause_flg ) {
printf("--- more ---"); fflush(stdout);
ch = INKEY();
printf("\r \r"); fflush(stdout);
if ( ch == '\033' )
return ERR;
}
line = 0;
}
dic_puts(p, color_flag ? NULL:stdout);
#endif /* !MORE */
}
#ifdef MORE
if ( fp != stdout )
pclose(fp);
#endif
/*
if ( color_flag ) {
BOLD_OFF();
ITALIC_OFF();
}
*/
if ( pause_flg ) {
printf("Hit Return Key >"); fflush(stdout);
ch = INKEY();
#ifndef MORE
printf("\r \r"); fflush(stdout);
#endif
}
return FALSE;
}
static uchar *pager_get_line(int line, POINT *tab, int *no, int max)
{
uchar *p;
if ( dic_mem_flag )
return NULL;
while ( (p = dic_goto_line(line)) == NULL ) {
while ( (p = dic_next_line()) == NULL ) {
if ( *no >= max )
return "\n";
if ( dic_seek(tab[*no].block, tab[*no].offset) )
return NULL;
*no += 1;
}
}
return p;
}
void pager(POINT *tab, int max, int fg)
{
int ch, n;
int no = 0;
int line = 0;
int top = 0;
uchar *p;
if ( no >= max )
return;
#ifdef CURSES
#ifdef NEWS
setlocale(LC_CTYPE, "");
#endif
initscr();
cbreak();
noecho();
scrollok(stdscr, TRUE);
idlok(stdscr, TRUE);
cols_max = COLS;
lines_max = LINES;
#endif
if ( !fg ) {
dic_seek(tab[no].block, tab[no].offset);
dic_init_line(TRUE);
}
no++;
CUROFF();
for ( n = 0 ; n < (lines_max - 1) ; n++ ) {
if ( (p = pager_get_line(n, tab, &no, max)) == NULL )
goto ENDOF;
LOCATE(0, n);
dic_puts(p, NULL);
}
LOCATE(0, lines_max - 1);
ERALINE();
FLUSH();
for ( ; ; ) {
if ( color_flag ) {
if ( top != line ) {
/****************************
BOLD_OFF();
ITALIC_OFF();
*****************************/
for ( n = 0 ; n < (lines_max - 1) ; n++ ) {
if ( (p = pager_get_line(line + n,
tab, &no, max)) == NULL )
goto ENDOF;
LOCATE(0, n);
dic_puts(p, NULL);
}
LOCATE(0, lines_max - 1);
ERALINE();
FLUSH();
top = line;
}
} else {
while ( top < line ) {
top++;
if ( (p = pager_get_line(top + lines_max - 2,
tab, &no, max)) == NULL )
goto ENDOF;
FORSCROOL();
LOCATE(0, lines_max - 2);
dic_puts(p, NULL);
FLUSH();
}
while ( top > line ) {
top--;
if ( (p = pager_get_line(top, tab, &no, max)) == NULL )
goto ENDOF;
BACKSCROOL();
LOCATE(0, 0);
dic_puts(p, NULL);
LOCATE(0, lines_max - 1);
ERALINE();
FLUSH();
}
}
ch = GETCH();
switch(ch) {
case '\n': case '\r':
case '\x1F':
case 'x': case 'X': case 'X'-'@':
case 'u': case 'U': case 'U'-'@':
case 'j': case 'J': /* case 'J'-'@': */
line++;
break;
case '\x1E':
case 'e': case 'E': case 'E'-'@':
case 'd': case 'D': case 'D'-'@':
case 'k': case 'K': case 'K'-'@':
if ( line > 0 )
line--;
break;
case ' ':
case 'c': case 'C': case 'C'-'@':
case 'n': case 'N': case 'N'-'@':
case 'f': case 'F': case 'F'-'@':
line += (lines_max - 3);
break;
case '\b':
case 'r': case 'R': case 'R'-'@':
case 'b': case 'B': case 'B'-'@':
case 'p': case 'P': case 'P'-'@':
if ( (line -= (lines_max - 3)) < 0 )
line = 0;
break;
case '\033':
case 'q': case 'Q': case 'Q'-'@':
goto ENDOF;
case 's': case 'S': case 'S'-'@':
case 'l': case 'L': /* case 'L'-'@': */
if ( ext_out_fp != NULL ) {
for ( n = 0 ; n < (lines_max - 1) ; n++ ) {
if ( (p = pager_get_line(line + n,
tab, &no, max)) == NULL )
goto ENDOF;
dic_puts(p, ext_out_fp);
}
}
break;
case 'L'-'@':
REFRESH();
break;
}
}
ENDOF:
/*
if ( color_flag ) {
BOLD_OFF();
ITALIC_OFF();
}
*/
LOCATE(0, lines_max - 1);
CURON();
FLUSH();
#ifdef CURSES
endwin();
#endif
if ( dic_mem_flag )
fprintf(stderr, "Memory Alloc Error\n");
}
int more(POINT *tab, int max)
{
int n;
uchar *p;
#ifdef MORE
FILE *fp;
#else
int ch;
int line = 0;
#endif
#ifdef MORE
if ( pause_flg == FALSE || (fp = popen(MORE, "w")) == NULL )
fp = stdout;
#endif /* MORE */
for ( n = 0 ; n < max ; n++ ) {
if ( dic_seek(tab[n].block, tab[n].offset) )
return ERR;
dic_init_line(FALSE);
while ( (p = dic_next_line()) != NULL ) {
#ifdef MORE
if ( ferror(fp) )
goto ENDOF;
dic_puts(p, fp);
#else
if ( ++line >= lines_max ) {
if ( pause_flg ) {
printf("--- more ---"); fflush(stdout);
ch = INKEY();
printf("\r \r"); fflush(stdout);
if ( ch == '\033' )
return ERR;
}
line = 0;
}
dic_puts(p, color_flag ? NULL:stdout);
#endif
if ( ext_out_fp != NULL )
dic_puts(p, ext_out_fp);
}
}
#ifdef MORE
ENDOF:
if ( fp != stdout )
pclose(fp);
#endif
return FALSE;
}