⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 help.c

📁 frasr200的win 版本源码(18.21),使用make文件,使用的vc版本较低,在我的环境下编译有问题! 很不错的分形程序代码!
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * help.c
 *
 * This module is linked as an overlay, use ENTER_OVLY and EXIT_OVLY.
 *
 *
 * Revision history:
 *
 *   2-26-90  EAN     Initial version.
 *
 *
 */


#ifndef TEST /* kills all those assert macros in production version */
#define NDEBUG
#endif

#define INCLUDE_COMMON	/* include common code in helpcom.h */


#include <stdio.h>
#include <stdlib.h>
#ifndef XFRACT
#include <io.h>
#include <dos.h>
#endif
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef XFRACT
#include <unistd.h>
#endif
#include "fractint.h"
#include "helpcom.h"
#include "helpdefs.h"
#include "prototyp.h"


#define MAX_HIST	   16	     /* number of pages we'll remember */

#define ALT_F1		 1104
#define BACK_TAB	 1015
#define BACKSPACE	    8

#define ACTION_CALL	    0	     /* values returned by help_topic() */
#define ACTION_PREV	    1
#define ACTION_PREV2	    2	     /* special - go back two topics */
#define ACTION_INDEX	    3
#define ACTION_QUIT	    4

#define F_HIST		    (1<<0)   /* flags for help_topic() */
#define F_INDEX 	    (1<<1)

#define MAX_PAGE_SIZE	    (80*25)  /* no page of text may be larger */

#define TEXT_START_ROW	    2	     /* start print the help text here */


typedef struct
   {
   BYTE r, c;
   int		 width;
   unsigned	 offset;
   int		 topic_num;
   unsigned	 topic_off;
   } LINK;


typedef struct
   {
   int	    topic_num;
   unsigned topic_off;
   } LABEL;


typedef struct
   {
   unsigned	 offset;
   unsigned	 len;
   int		 margin;
   } PAGE;


typedef struct
   {
   int	    topic_num;
   unsigned topic_off;
   int	    link;
   } HIST;


struct help_sig_info
   {
   unsigned long sig;
   int		 version;
   unsigned long base;	   /* only if added to fractint.exe */
   } ;


void print_document(char *outfname, int (*msg_func)(int,int), int save_extraseg );
static int print_doc_msg_func(int pnum, int num_pages);



void help_overlay(void) { }



/* stuff from fractint */

extern int  lookatmouse;
extern long timer_start;
extern int  helpmode;
extern int  text_type;	 /* 0=real color text, 1=640x200x2, 2=??mono?? */
extern int  textcbase;
extern int  textrbase;
extern SEGTYPE  extraseg;
extern int  release;

int  putstringcenter (int row, int col, int width, int attr, char far *msg);
void helptitle	     (void);
void stackscreen     (void);
void unstackscreen   (void);
void findpath	     (char *filename, char *path);


static int	      help_file = -1; /* help file handle */
static long	      base_off;       /* offset to help info in help file */
static int	      max_links;      /* max # of links in any page */
static int	      max_pages;      /* max # of pages in any topic */
static int	      num_label;      /* number of labels */
static int	      num_topic;      /* number of topics */
static int	      curr_hist = 0;  /* current pos in history */

/* these items alloc'ed in init_help... */

static long	 far *topic_offset;	   /* 4*num_topic */
static LABEL	 far *label;		   /* 4*num_label */
static HIST	 far *hist;		   /* 6*MAX_HIST (96 bytes) */

/* these items alloc'ed only while help is active... */

static char	  far *buffer;		 /* MAX_PAGE_SIZE (2048 bytes) */
static LINK	  far *link_table;	 /* 10*max_links */
static PAGE	  far *page_table;	 /* 4*max_pages  */


static void help_seek(long pos)
   {
   lseek(help_file, base_off+pos, SEEK_SET);
   }


static void displayc(int row, int col, int color, int ch)
   {
#ifndef XFRACT
   static char *s = "?";
#else
   static char s[] = "?";
#endif

   if (text_type == 1)	 /* if 640x200x2 mode */
      {
      /*
       * This is REALLY ugly, but it works.  Non-current links (ones that
       * would be bold if 640x200 supported it) are in upper-case and the
       * current item is inversed.
       *
       */

      if (color & INVERSE)
	 color = (signed int)INVERSE;
      else if (color & BRIGHT)
	 {
	 color = 0;   /* normal */
	 if (ch>='a' && ch<='z')
	    ch += 'A' - 'a';
	 }
      else
	 color = 0;   /* normal */
      }

   s[0] = ch;
   putstring(row, col, color, s);
   }


static void display_text(int row, int col, int color, char far *text, unsigned len)
   {
   while (len-- > 0)
      {
      if (*text == CMD_LITERAL)
	 {
	 ++text;
	 --len;
	 }
      displayc(row, col++, color, *text++);
      }
   }


static void display_parse_text(char far *text, unsigned len, int start_margin, int *num_link, LINK far *link)
   {
   char far  *curr;
   int	      row, col;
   int	      tok;
   int	      size,
	      width;

   textcbase = SCREEN_INDENT;
   textrbase = TEXT_START_ROW;

   curr = text;
   row = 0;
   col = 0;

   size = width = 0;

   if (start_margin >= 0)
      tok = TOK_PARA;
   else
      tok = -1;

   while ( 1 )
      {
      switch ( tok )
	 {
	 case TOK_PARA:
	    {
	    int indent,
		margin;

	    if (size > 0)
	       {
	       ++curr;
	       indent = *curr++;
	       margin = *curr++;
	       len  -= 3;
	       }
	    else
	       {
	       indent = start_margin;
	       margin = start_margin;
	       }

	    col = indent;

	    while (1)
	       {
	       tok = find_token_length(ONLINE, curr, len, &size, &width);

	       if (tok == TOK_DONE || tok == TOK_NL || tok == TOK_FF )
		  break;

	       if (tok == TOK_PARA)
		  {
		  col = 0;   /* fake a new-line */
		  row++;
		  break;
		  }

	       if (tok == TOK_XONLINE || tok == TOK_XDOC)
		  {
		  curr += size;
		  len  -= size;
		  continue;
		  }

	       /* now tok is TOK_SPACE or TOK_LINK or TOK_WORD */

	       if (col+width > SCREEN_WIDTH)
		  {	     /* go to next line... */
		  col = margin;
		  ++row;

		  if ( tok == TOK_SPACE )
		     width = 0;   /* skip spaces at start of a line */
		  }

	       if (tok == TOK_LINK)
		  {
		  display_text(row, col, C_HELP_LINK, curr+1+3*sizeof(int), width);
		  if (num_link != NULL)
		     {
		     link[*num_link].r	       = row;
		     link[*num_link].c	       = col;
                     link[*num_link].topic_num = getint(curr+1);
                     link[*num_link].topic_off = getint(curr+1+sizeof(int));
                     link[*num_link].offset    = (unsigned) ((curr+1+3*sizeof(int)) - text);
		     link[*num_link].width     = width;
		     ++(*num_link);
		     }
		  }
	       else if (tok == TOK_WORD )
		  display_text(row, col, C_HELP_BODY, curr, width);

	       col += width;
	       curr += size;
	       len -= size;
	       }

	    width = size = 0;
	    break;
	    }

	 case TOK_CENTER:
	    col = find_line_width(ONLINE, curr, len);
	    col = (SCREEN_WIDTH-col)/2;
	    if (col < 0)
	       col = 0;
	    break;

	 case TOK_NL:
	    col = 0;
	    ++row;
	    break;

	 case TOK_LINK:
            display_text(row, col, C_HELP_LINK, curr+1+3*sizeof(int), width);
	    if (num_link != NULL)
	       {
	       link[*num_link].r	 = row;
	       link[*num_link].c	 = col;
               link[*num_link].topic_num = getint(curr+1);
               link[*num_link].topic_off = getint(curr+1+sizeof(int));
               link[*num_link].offset    = (unsigned) ((curr+1+3*sizeof(int)) - text);
	       link[*num_link].width	 = width;
	       ++(*num_link);
	       }
	    break;

	 case TOK_XONLINE:  /* skip */
	 case TOK_FF:	    /* ignore */
	 case TOK_XDOC:     /* ignore */
	 case TOK_DONE:
	 case TOK_SPACE:
	    break;

	 case TOK_WORD:
	    display_text(row, col, C_HELP_BODY, curr, width);
	    break;
	 } /* switch */

      curr += size;
      len  -= size;
      col  += width;

      if (len == 0)
	 break;

      tok = find_token_length(ONLINE, curr, len, &size, &width);
      } /* while */

   textcbase = 0;
   textrbase = 0;
   }


static void color_link(LINK far *link, int color)
   {
   textcbase = SCREEN_INDENT;
   textrbase = TEXT_START_ROW;

   if (text_type == 1)	 /* if 640x200x2 mode */
      display_text(link->r, link->c, color, buffer+link->offset, link->width);
   else
      setattr(link->r, link->c, color, link->width);

   textcbase = 0;
   textrbase = 0;
   }



/* #define PUT_KEY(name, descrip) putstring(-1,-1,C_HELP_INSTR_KEYS,name), putstring(-1,-1,C_HELP_INSTR," "descrip"  ") */
#ifndef XFRACT
#define PUT_KEY(name, descrip) putstring(-1,-1,C_HELP_INSTR,name); putstring(-1,-1,C_HELP_INSTR,":"descrip"  ")
#else
#define PUT_KEY(name, descrip) putstring(-1,-1,C_HELP_INSTR,name);\
putstring(-1,-1,C_HELP_INSTR,":");\
putstring(-1,-1,C_HELP_INSTR,descrip);\
putstring(-1,-1,C_HELP_INSTR,"  ")
#endif


static void helpinstr(void)
   {
   int ctr;

   for (ctr=0; ctr<80; ctr++)
     putstring(24, ctr, C_HELP_INSTR, " ");

   movecursor(24, 1);
   PUT_KEY("F1",               "Index");
#ifndef XFRACT
   PUT_KEY("\030\031\033\032", "Select");
#else
   PUT_KEY("K J H L", "Select");
#endif
   PUT_KEY("Enter",            "Go to");
   PUT_KEY("Backspace",        "Last topic");
   PUT_KEY("Escape",           "Exit help");
   }


static void printinstr(void)
   {
   int ctr;

   for (ctr=0; ctr<80; ctr++)
     putstring(24, ctr, C_HELP_INSTR, " ");

   movecursor(24, 1);
   PUT_KEY("Escape", "Abort");
   }


#undef PUT_KEY


static void display_page(char far *title, char far *text, unsigned text_len, int page, int num_pages, int start_margin, int *num_link, LINK far *link)
   {
   char temp[9];

   helptitle();
   helpinstr();
   setattr(2, 0, C_HELP_BODY, 80*22);
   putstringcenter(1, 0, 80, C_HELP_HDG, title);
   sprintf(temp, "%2d of %d", page+1, num_pages);
#ifndef XFRACT
   putstring(1, 79-(6 + ((num_pages>=10)?2:1)), C_HELP_INSTR, temp);
#else
   /* Some systems (Ultrix) mess up if you write to column 80 */
   putstring(1, 78-(6 + ((num_pages>=10)?2:1)), C_HELP_INSTR, temp);
#endif

   if (text != NULL)
      display_parse_text(text, text_len, start_margin, num_link, link);

   movecursor(25, 80);	 /* hide cursor */
   }



/*
 * int overlap(int a, int a2, int b, int b2);
 *
 * If a, a2, b, and b2 are points on a line, this function returns the
 * distance of intersection between a-->a2 and b-->b2.	If there is no
 * intersection between the lines this function will return a negative number
 * representing the distance between the two lines.
 *
 * There are six possible cases of intersection between the lines:
 *
 *			a		      a2
 *			|		      |
 *     b	 b2	|		      |       b 	b2
 *     |---(1)---|	|		      |       |---(2)---|
 *			|		      |
 *		b	|     b2      b       |      b2
 *		|------(3)----|       |------(4)-----|
 *			|		      |
 *		 b	|		      |   b2
 *		 |------+--------(5)----------+---|
 *			|		      |
 *			|     b       b2      |
 *			|     |--(6)--|       |
 *			|		      |
 *			|		      |
 *
 */


static int overlap(int a, int a2, int b, int b2)
   {
   if ( b < a )
      {
      if ( b2 >= a2 )
	 return ( a2 - a );	       /* case (5) */

      return ( b2 - a );	       /* case (1), case (3) */
      }

   if ( b2 <= a2 )
      return ( b2 - b );	       /* case (6) */

   return ( a2 - b );		       /* case (2), case (4) */
   }


static int dist(int a, int b)
   {
   int t = a - b;

   return (abs(t));
   }


#ifdef __TURBOC__
#   pragma warn -def /* turn off "Possible use before definition" warning */
#endif




static int find_link_updown(LINK far *link, int num_link, int curr_link, int up)
   {
   int	     ctr,
	     curr_c2,
	     best_overlap,
	     temp_overlap;
   LINK far *curr,
	far *temp,
	far *best;
   int	     temp_dist;

   curr    = &link[curr_link];
   best    = NULL;
   curr_c2 = curr->c + curr->width - 1;

   for (ctr=0, temp=link; ctr<num_link; ctr++, temp++)
      {
      if ( ctr != curr_link &&
	   ( (up && temp->r < curr->r) || (!up && temp->r > curr->r) ) )
	 {
	 temp_overlap = overlap(curr->c, curr_c2, temp->c, temp->c+temp->width-1);
	 /* if >= 3 lines between, prioritize on vertical distance: */
	 if ((temp_dist = dist(temp->r, curr->r)) >= 4)
	    temp_overlap -= temp_dist * 100;

	 if (best != NULL)
	    {
	    if ( best_overlap >= 0 && temp_overlap >= 0 )
	       {     /* if they're both under curr set to closest in y dir */
	       if ( dist(best->r, curr->r) > temp_dist )
		  best = NULL;
	       }
	    else
	       {
	       if ( best_overlap < temp_overlap )
		  best = NULL;
	       }
	    }

	 if (best == NULL)
	    {
	    best = temp;
	    best_overlap = temp_overlap;
	    }
	 }
      }

   return ( (best==NULL) ? -1 : (int)(best-link) );
   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -