📄 help.c
字号:
static int find_link_leftright(LINK far *link, int num_link, int curr_link, int left)
{
int ctr,
curr_c2,
best_c2,
temp_c2,
best_dist,
temp_dist;
LINK far *curr,
far *temp,
far *best;
curr = &link[curr_link];
best = NULL;
curr_c2 = curr->c + curr->width - 1;
for (ctr=0, temp=link; ctr<num_link; ctr++, temp++)
{
temp_c2 = temp->c + temp->width - 1;
if ( ctr != curr_link &&
( (left && temp_c2 < curr->c) || (!left && temp->c > curr_c2) ) )
{
temp_dist = dist(curr->r, temp->r);
if (best != NULL)
{
if ( best_dist == 0 && temp_dist == 0 ) /* if both on curr's line... */
{
if ( ( left && dist(curr->c, best_c2) > dist(curr->c, temp_c2) ) ||
( !left && dist(curr_c2, best->c) > dist(curr_c2, temp->c) ) )
best = NULL;
}
else
{
if ( best_dist >= temp_dist ) /* if temp is closer... */
best = NULL;
}
} /* if (best...) */
if (best == NULL)
{
best = temp;
best_dist = temp_dist;
best_c2 = temp_c2;
}
}
} /* for */
return ( (best==NULL) ? -1 : (int)(best-link) );
}
#ifdef __TURBOC__
# pragma warn .def /* back to default */
# pragma warn -par /* now turn off "Parameter not used" warning */
#endif
static int find_link_key(LINK far *link, int num_link, int curr_link, int key)
{
switch (key)
{
case TAB: return ( (curr_link>=num_link-1) ? -1 : curr_link+1 );
case BACK_TAB: return ( (curr_link<=0) ? -1 : curr_link-1 );
default: assert(0); return (-1);
}
}
#ifdef __TURBOC__
# pragma warn .par /* back to default */
#endif
static int do_move_link(LINK far *link, int num_link, int *curr, int (*f)(LINK far *,int,int,int), int val)
{
int t;
if (num_link > 1)
{
if ( f == NULL )
t = val;
else
t = (*f)(link, num_link, *curr, val);
if ( t >= 0 && t != *curr )
{
color_link(&link[*curr], C_HELP_LINK);
*curr = t;
color_link(&link[*curr], C_HELP_CURLINK);
return (1);
}
}
return (0);
}
static int help_topic(HIST *curr, HIST *next, int flags)
{
int len;
int key;
int num_pages;
int num_link;
int page;
int curr_link;
char title[81];
long where;
int draw_page;
int action;
BYTE ch;
where = topic_offset[curr->topic_num]+sizeof(int); /* to skip flags */
curr_link = curr->link;
help_seek(where);
read(help_file, (char *)&num_pages, sizeof(int));
assert(num_pages>0 && num_pages<=max_pages);
farread(help_file, (char far *)page_table, 3*sizeof(int)*num_pages);
read(help_file, &ch, 1);
len = ch;
assert(len<81);
read(help_file, (char *)title, len);
title[len] = '\0';
where += sizeof(int) + num_pages*3*sizeof(int) + 1 + len + sizeof(int);
for(page=0; page<num_pages; page++)
if (curr->topic_off >= page_table[page].offset &&
curr->topic_off < page_table[page].offset+page_table[page].len )
break;
assert(page < num_pages);
action = -1;
draw_page = 2;
do
{
if (draw_page)
{
help_seek(where+page_table[page].offset);
farread(help_file, buffer, page_table[page].len);
num_link = 0;
display_page(title, buffer, page_table[page].len, page, num_pages,
page_table[page].margin, &num_link, link_table);
if (draw_page==2)
{
assert(num_link<=0 || (curr_link>=0 && curr_link<num_link));
}
else if (draw_page==3)
curr_link = num_link - 1;
else
curr_link = 0;
if (num_link > 0)
color_link(&link_table[curr_link], C_HELP_CURLINK);
draw_page = 0;
}
key = getakey();
switch(key)
{
case PAGE_DOWN:
if (page<num_pages-1)
{
page++;
draw_page = 1;
}
break;
case PAGE_UP:
if (page>0)
{
page--;
draw_page = 1;
}
break;
case HOME:
if ( page != 0 )
{
page = 0;
draw_page = 1;
}
else
do_move_link(link_table, num_link, &curr_link, NULL, 0);
break;
case END:
if ( page != num_pages-1 )
{
page = num_pages-1;
draw_page = 3;
}
else
do_move_link(link_table, num_link, &curr_link, NULL, num_link-1);
break;
case TAB:
if ( !do_move_link(link_table, num_link, &curr_link, find_link_key, key) &&
page<num_pages-1 )
{
++page;
draw_page = 1;
}
break;
case BACK_TAB:
if ( !do_move_link(link_table, num_link, &curr_link, find_link_key, key) &&
page>0 )
{
--page;
draw_page = 3;
}
break;
case DOWN_ARROW:
if ( !do_move_link(link_table, num_link, &curr_link, find_link_updown, 0) &&
page<num_pages-1 )
{
++page;
draw_page = 1;
}
break;
case UP_ARROW:
if ( !do_move_link(link_table, num_link, &curr_link, find_link_updown, 1) &&
page>0 )
{
--page;
draw_page = 3;
}
break;
case LEFT_ARROW:
do_move_link(link_table, num_link, &curr_link, find_link_leftright, 1);
break;
case RIGHT_ARROW:
do_move_link(link_table, num_link, &curr_link, find_link_leftright, 0);
break;
case ESC: /* exit help */
action = ACTION_QUIT;
break;
case BACKSPACE: /* prev topic */
case ALT_F1:
if (flags & F_HIST)
action = ACTION_PREV;
break;
case F1: /* help index */
if (!(flags & F_INDEX))
action = ACTION_INDEX;
break;
case ENTER:
case ENTER_2:
if (num_link > 0)
{
next->topic_num = link_table[curr_link].topic_num;
next->topic_off = link_table[curr_link].topic_off;
action = ACTION_CALL;
}
break;
} /* switch */
}
while ( action == -1 );
curr->topic_off = page_table[page].offset;
curr->link = curr_link;
return (action);
}
int help(int action)
{
static char far unknowntopic_msg[] = "Unknown Help Topic";
HIST curr;
int oldlookatmouse;
int oldhelpmode;
int flags;
HIST next;
ENTER_OVLY(OVLY_HELP);
if (helpmode == -1) /* is help disabled? */
{
EXIT_OVLY;
return (0);
}
if (help_file == -1)
{
buzzer(2);
EXIT_OVLY;
return (0);
}
buffer = farmemalloc((long)MAX_PAGE_SIZE + sizeof(LINK)*max_links +
sizeof(PAGE)*max_pages);
if (buffer == NULL)
{
buzzer(2);
EXIT_OVLY;
return (0);
}
link_table = (LINK far *)(&buffer[MAX_PAGE_SIZE]);
page_table = (PAGE far *)(&link_table[max_links]);
oldlookatmouse = lookatmouse;
lookatmouse = 0;
timer_start -= clock_ticks();
stackscreen();
if (helpmode >= 0)
{
next.topic_num = label[helpmode].topic_num;
next.topic_off = label[helpmode].topic_off;
}
else
{
next.topic_num = helpmode;
next.topic_off = 0;
}
oldhelpmode = helpmode;
if (curr_hist <= 0)
action = ACTION_CALL; /* make sure it isn't ACTION_PREV! */
do
{
switch(action)
{
case ACTION_PREV2:
if (curr_hist > 0)
curr = hist[--curr_hist];
/* fall-through */
case ACTION_PREV:
if (curr_hist > 0)
curr = hist[--curr_hist];
break;
case ACTION_QUIT:
break;
case ACTION_INDEX:
next.topic_num = label[HELP_INDEX].topic_num;
next.topic_off = label[HELP_INDEX].topic_off;
/* fall-through */
case ACTION_CALL:
curr = next;
curr.link = 0;
break;
} /* switch */
flags = 0;
if (curr.topic_num == label[HELP_INDEX].topic_num)
flags |= F_INDEX;
if (curr_hist > 0)
flags |= F_HIST;
if ( curr.topic_num >= 0 )
action = help_topic(&curr, &next, flags);
else
{
if ( curr.topic_num == -100 )
{
print_document("FRACTINT.DOC", print_doc_msg_func, 1);
action = ACTION_PREV2;
}
else if ( curr.topic_num == -101 )
action = ACTION_PREV2;
else
{
display_page(unknowntopic_msg, NULL, 0, 0, 1, 0, NULL, NULL);
action = -1;
while (action == -1)
{
switch (getakey())
{
case ESC: action = ACTION_QUIT; break;
case ALT_F1: action = ACTION_PREV; break;
case F1: action = ACTION_INDEX; break;
} /* switch */
} /* while */
}
} /* else */
if ( action != ACTION_PREV && action != ACTION_PREV2 )
{
if (curr_hist >= MAX_HIST)
{
int ctr;
for (ctr=0; ctr<MAX_HIST-1; ctr++)
hist[ctr] = hist[ctr+1];
curr_hist = MAX_HIST-1;
}
hist[curr_hist++] = curr;
}
}
while (action != ACTION_QUIT);
farmemfree((BYTE far *)buffer);
unstackscreen();
lookatmouse = oldlookatmouse;
helpmode = oldhelpmode;
timer_start += clock_ticks();
EXIT_OVLY;
return(0);
}
static int dos_version(void)
{
#ifndef XFRACT
union REGS r;
r.x.ax = 0x3000;
intdos(&r, &r);
return (r.h.al*100 + r.h.ah);
#else
return 0;
#endif
}
static int exe_path(char *filename, char *path)
{
#ifndef XFRACT
char *ptr;
if (dos_version() >= 300) /* DOS version 3.00+ ? */
{
#ifdef __TURBOC__
strcpy(path, _argv[0]);
#else /* assume MSC */
extern char **__argv;
strcpy(path, __argv[0]); /* note: __argv may be undocumented in MSC */
#endif
ptr = strrchr(path, SLASHC);
if (ptr == NULL)
ptr = path;
else
++ptr;
strcpy(ptr, filename);
return (1);
}
return (0);
#else
strcpy(path,SRCDIR);
strcat(path,"/");
strcat(path,filename);
return 1;
#endif
}
static int find_file(char *filename, char *path)
{
int handle;
if ( exe_path(filename, path) )
if ( (handle=open(path, O_RDONLY)) != -1)
{
close(handle);
return (1);
}
findpath(filename,path);
return ( (path[0]) ? 1 : 0);
}
static int _read_help_topic(int topic, int off, int len, VOIDFARPTR buf)
{
static int curr_topic = -1;
static long curr_base;
static int curr_len;
int read_len;
if ( topic != curr_topic )
{
int t;
char ch;
curr_topic = topic;
curr_base = topic_offset[topic];
curr_base += sizeof(int); /* skip flags */
help_seek(curr_base);
read(help_file, (char *)&t, sizeof(int)); /* read num_pages */
curr_base += sizeof(int) + t*3*sizeof(int); /* skip page info */
if (t>0)
help_seek(curr_base);
read(help_file, &ch, 1); /* read title_len */
t = ch;
curr_base += 1 + t; /* skip title */
if (t>0)
help_seek(curr_base);
read(help_file, (char *)&curr_len, sizeof(int)); /* read topic len */
curr_base += sizeof(int);
}
read_len = (off+len > curr_len) ? curr_len - off : len;
if (read_len > 0)
{
help_seek(curr_base + off);
farread(help_file, (char far *)buf, read_len);
}
return ( curr_len - (off+len) );
}
int read_help_topic(int label_num, int off, int len, VOIDFARPTR buf)
/*
* reads text from a help topic. Returns number of bytes from (off+len)
* to end of topic. On "EOF" returns a negative number representing
* number of bytes not read.
*/
{
int ret;
ENTER_OVLY(OVLY_HELP);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -