Category : C Source Code
Archive   : FRASRC18.ZIP
Filename : REALDOS.C

 
Output of file : REALDOS.C contained in archive : FRASRC18.ZIP
/*
Miscellaneous C routines used only in DOS Fractint.
*/

#include
#include
#ifndef XFRACT
#include
#include
#include
#endif
#include
#include
#include
#include
#include
#include
#include "fractint.h"
#include "fractype.h"
#include "helpdefs.h"
#include "prototyp.h"

/* routines in this module */

static int menu_checkkey(int curkey,int choice);

int release=1800; /* this has 2 implied decimals; increment it every synch */
int patchlevel=0; /* patchlevel for DOS version */
int xrelease=109;

/* fullscreen_choice options */
#define CHOICERETURNKEY 1
#define CHOICEMENU 2
#define CHOICEHELP 4

extern char diskfilename[];
extern int using_jiim;
extern int xdots, ydots, sxdots, sydots, sxoffs, syoffs;
extern int colors;
extern int dotmode;
extern int oktoprint;
extern int textrow, textcol, textrbase, textcbase;
extern int debugflag;
extern int fractype;
extern int calc_status;
extern double param[];
extern int tabmode;
extern int color_dark,color_medium,color_bright;
extern int lookatmouse;
extern int gotrealdac;
extern int reallyega;
extern int extraseg;
extern int active_system;
extern int first_init;
extern int initbatch; /* 1 if batch run (no kbd) */


/* int stopmsg(flags,message) displays message and waits for a key:
message should be a max of 9 lines with \n's separating them;
no leading or trailing \n's in message;
no line longer than 76 chars for best appearance;
flag options:
&1 if already in text display mode, stackscreen is not called
and message is displayed at (12,0) instead of (4,0)
&2 if continue/cancel indication is to be returned;
when not set, "Any key to continue..." is displayed
when set, "Escape to cancel, any other key to continue..."
-1 is returned for cancel, 0 for continue
&4 set to suppress buzzer
&8 for Fractint for Windows & parser - use a fixed pitch font
&16 for info only message (green box instead of red in DOS vsn)
*/
int stopmsg (int flags, CHAR far *msg)
{
int ret,toprow,color,savelookatmouse;
if (active_system == 0 /* DOS */
&& first_init) { /* & cmdfiles hasn't finished 1st try */
setvideotext();
buzzer(2);
putstring(0,0,15,"*** Error during startup:");
putstring(2,0,15,msg);
movecursor(8,0);
#ifdef XFRACT
sleep(1);
UnixDone();
#endif
exit(1);
}
if (initbatch == 1) { /* in batch mode */
initbatch = 4; /* used to set errorlevel */
return (-1);
}
ret = 0;
savelookatmouse = lookatmouse;
lookatmouse = -13;
if ((flags & 1))
blankrows(toprow=12,10,7);
else {
stackscreen();
toprow = 4;
movecursor(4,0);
}
textcbase = 2; /* left margin is 2 */
putstring(toprow,0,7,msg);
if (flags & 2)
putstring(textrow+2,0,7,"Escape to cancel, any other key to continue...");
else
putstring(textrow+2,0,7,"Any key to continue...");
textcbase = 0; /* back to full line */
color = (flags & 16) ? C_STOP_INFO : C_STOP_ERR;
setattr(toprow,0,color,(textrow+1-toprow)*80);
movecursor(25,80); /* cursor off */
if ((flags & 4) == 0)
buzzer((flags & 16) ? 0 : 2);
while (keypressed()) /* flush any keyahead */
getakey();
if (getakeynohelp() == ESC)
ret = -1;
if ((flags & 1))
blankrows(toprow,10,7);
else
unstackscreen();
lookatmouse = savelookatmouse;
return ret;
}


static char far *temptextsave = NULL;
static int textxdots,textydots;

/* texttempmsg(msg) displays a text message of up to 40 characters, waits
for a key press, restores the prior display, and returns (without
eating the key).
It works in almost any video mode - does nothing in some very odd cases
(HCGA hi-res with old bios), or when there isn't 10k of temp mem free. */
int texttempmsg(char *msgparm)
{
if (showtempmsg(msgparm))
return(-1);
#ifndef XFRACT
while (!keypressed()) {} /* wait for a keystroke but don't eat it */
#else
waitkeypressed(0); /* wait for a keystroke but don't eat it */
#endif
cleartempmsg();
return(0);
}

void freetempmsg()
{
if(temptextsave != NULL)
farmemfree(temptextsave);
temptextsave = NULL;
}

int showtempmsg(char *msgparm)
{
static long size = 0;
extern int color_dark,color_medium;
CHAR msg[41];
BYTE buffer[640];
char far *fartmp;
BYTE far *fontptr;
BYTE *bufptr;
int i,j,k,xrepeat,yrepeat,fontchar,charnum;
int save_sxoffs,save_syoffs;
strncpy(msg,msgparm,40);
msg[40] = 0; /* ensure max message len of 40 chars */
if (dotmode == 11) { /* disk video, screen in text mode, easy */
dvid_status(0,msg);
return(0);
}
if ((fontptr = findfont(0)) == NULL) { /* old bios, no font table? */
if (oktoprint == 0 /* can't printf */
|| sxdots > 640 || sydots > 200) /* not willing to trust char cell size */
return(-1); /* sorry, message not displayed */
textydots = 8;
textxdots = sxdots;
}
else {
xrepeat = (sxdots >= 640) ? 2 : 1;
yrepeat = (sydots >= 300) ? 2 : 1;
textxdots = strlen(msg) * xrepeat * 8;
textydots = yrepeat * 8;
}
/* worst case needs 10k */
if(temptextsave !=NULL)
if(size != (long)textxdots * (long)textydots)
freetempmsg();
size = (long)textxdots * (long)textydots;
save_sxoffs = sxoffs;
save_syoffs = syoffs;
sxoffs = syoffs = 0;
if(temptextsave == NULL) /* only save screen first time called */
{
if ((temptextsave = farmemalloc(size)) == NULL)
return(-1); /* sorry, message not displayed */
fartmp = temptextsave;
for (i = 0; i < textydots; ++i) {
get_line(i,0,textxdots-1,buffer);
for (j = 0; j < textxdots; ++j) /* copy it out to far memory */
*(fartmp++) = buffer[j];
}
}
if (fontptr == NULL) { /* bios must do it for us */
home();
printf(msg);
}
else { /* generate the characters */
find_special_colors(); /* get color_dark & color_medium set */
for (i = 0; i < 8; ++i) {
memset(buffer,color_dark,640);
bufptr = buffer;
charnum = -1;
while (msg[++charnum] != 0) {
fontchar = *(fontptr + msg[charnum]*8 + i);
for (j = 0; j < 8; ++j) {
for (k = 0; k < xrepeat; ++k) {
if ((fontchar & 0x80) != 0)
*bufptr = color_medium;
++bufptr;
}
fontchar <<= 1;
}
}
for (j = 0; j < yrepeat; ++j)
put_line(i*yrepeat+j,0,textxdots-1,buffer);
}
}
sxoffs = save_sxoffs;
syoffs = save_syoffs;
return(0);
}

void cleartempmsg()
{
BYTE buffer[640];
char far *fartmp;
int i,j;
int save_sxoffs,save_syoffs;
if (dotmode == 11) /* disk video, easy */
dvid_status(0,"");
else if (temptextsave != NULL) {
save_sxoffs = sxoffs;
save_syoffs = syoffs;
sxoffs = syoffs = 0;
fartmp = temptextsave;
for (i = 0; i < textydots; ++i) {
for (j = 0; j < textxdots; ++j) /* copy back from far memory */
buffer[j] = *(fartmp++);
put_line(i,0,textxdots-1,buffer);
}
if(using_jiim == 0) /* jiim frees memory with freetempmsg() */
{
farmemfree(temptextsave);
temptextsave = NULL;
}
sxoffs = save_sxoffs;
syoffs = save_syoffs;
}
}


void blankrows(int row,int rows,int attr)
{
char buf[81];
memset(buf,' ',80);
buf[80] = 0;
while (--rows >= 0)
putstring(row++,0,attr,buf);
}


void helptitle()
{
char msg[80],buf[80];
setclear(); /* clear the screen */
#ifdef XFRACT
sprintf(msg,"XFRACTINT Version %d.%02d (FRACTINT Version %d.%02d)",
xrelease/100,xrelease%100, release/100,release%100);
putstringcenter(0,0,80,C_TITLE,msg);
#else
#ifdef WAITE
release=1811;
patchlevel = 0;
sprintf(msg,"Special FRACTINT Version %d.%01d",release/100,(release%100)/10);
#else
sprintf(msg,"FRACTINT Version %d.%01d",release/100,(release%100)/10);
#endif
if (release%10) {
sprintf(buf,"%01d",release%10);
strcat(msg,buf);
}
#ifndef XFRACT
if (patchlevel) {
sprintf(buf," Patch %d",patchlevel);
strcat(msg,buf);
}
#endif
#ifdef WAITE /* realdos.c */
strcat(msg," for the Waite Group's Fractal Creations 2nd Ed.");
#endif /* WAITE - realdos.c */
putstringcenter(0,0,80,C_TITLE,msg);
#ifdef WAITE
return;
#endif
#endif
/* uncomment next for production executable: */
/* return; */
/*NOTREACHED*/
if (debugflag == 3002) return;
/* putstring(0,2,C_TITLE_DEV,"Development Version"); */
/* replace above by next after creating production release, for release source */
putstring(0,3,C_TITLE_DEV, "Customized Version");
putstring(0,55,C_TITLE_DEV,"Not for Public Release");
}


int putstringcenter(int row, int col, int width, int attr, char far *msg)
{
char buf[81];
int i,j,k;
i = 0;
#ifdef XFRACT
if (width==80) width=79; /* Some systems choke in column 80 */
#endif
while (msg[i]) ++i; /* strlen for a far */
if (i == 0) return(-1);
j = (width - i) / 2;
j -= (width + 10 - i) / 20; /* when wide a bit left of center looks better */
memset(buf,' ',width);
buf[width] = 0;
i = 0;
k = j;
while (msg[i]) buf[k++] = msg[i++]; /* strcpy for a far */
putstring(row,col,attr,buf);
return j;
}


#ifndef XFRACT
static int screenctr=-1;
#else
static int screenctr=0;
#endif
#define MAXSCREENS 3
static BYTE far *savescreen[MAXSCREENS];
static int saverc[MAXSCREENS+1];
static FILE *savescf=NULL;
static char scsvfile[]="fractscr.tmp";
extern int text_type;
extern int textaddr;

void stackscreen()
{
#ifndef XFRACT
BYTE far *vidmem;
int savebytes;
int i;
BYTE far *ptr;
char buf[100];
saverc[screenctr+1] = textrow*80 + textcol;
if (++screenctr) { /* already have some stacked */
static char far msg[]={"stackscreen overflow"};
if ((i = screenctr - 1) >= MAXSCREENS) { /* bug, missing unstack? */
stopmsg(1,msg);
exit(1);
}
vidmem = MK_FP(textaddr,0);
savebytes = (text_type == 0) ? 4000 : 16384;
if ((ptr = savescreen[i] = farmemalloc((long)savebytes)))
far_memcpy(ptr,vidmem,savebytes);
else {
if (savescf == NULL) { /* create file just once */
if ((savescf = fopen(scsvfile,"wb")) == NULL)
goto fileproblem;
if (fwrite(buf,MAXSCREENS,16384,savescf) != 16384)
goto fileproblem;
fclose(savescf);
if ((savescf = fopen(scsvfile,"r+b")) == NULL) {
static char far msg[]={"insufficient memory, aborting"};
fileproblem: stopmsg(1,msg);
exit(1);
}
}
fseek(savescf,(long)(savebytes*i),SEEK_SET);
while (--savebytes >= 0)
putc(*(vidmem++),savescf);
}
setclear();
}
else
setfortext();
#else
int i;
BYTE far *ptr;
saverc[screenctr+1] = textrow*80 + textcol;
if (++screenctr) { /* already have some stacked */
static char far msg[]={"stackscreen overflow"};
if ((i = screenctr - 1) >= MAXSCREENS) { /* bug, missing unstack? */
stopmsg(1,msg);
exit(1);
}
if (ptr = savescreen[i] = farmemalloc(sizeof(int *)))
savecurses(ptr);
else {
stopmsg(1,msg);
exit(1);
}
setclear();
}
else
setfortext();
#endif
}

void unstackscreen()
{
#ifndef XFRACT
char far *vidmem;
int savebytes;
BYTE far *ptr;
textrow = saverc[screenctr] / 80;
textcol = saverc[screenctr] % 80;
if (--screenctr >= 0) { /* unstack */
vidmem = MK_FP(textaddr,0);
savebytes = (text_type == 0) ? 4000 : 16384;
if ((ptr = savescreen[screenctr])) {
far_memcpy(vidmem,ptr,savebytes);
farmemfree(ptr);
}
else {
fseek(savescf,(long)(savebytes*screenctr),SEEK_SET);
while (--savebytes >= 0)
*(vidmem++) = getc(savescf);
}
}
else
setforgraphics();
movecursor(-1,-1);
#else
BYTE far *ptr;
textrow = saverc[screenctr] / 80;
textcol = saverc[screenctr] % 80;
if (--screenctr >= 0) { /* unstack */
ptr = savescreen[screenctr];
restorecurses(ptr);
farmemfree(ptr);
}
else
setforgraphics();
movecursor(-1,-1);
#endif
}

void discardscreen()
{
if (--screenctr >= 0) { /* unstack */
if (savescreen[screenctr])
farmemfree(savescreen[screenctr]);
}
else
discardgraphics();
}


/* --------------------------------------------------------------------- */

char speed_prompt[]="Speed key string";

int fullscreen_choice(
int options, /* &2 use menu coloring scheme */
/* &4 include F1 for help in instructions */
/* &8 add caller's instr after normal set */
char far *hdg, /* heading info, \n delimited */
char far *hdg2, /* column heading or NULL */
char far *instr, /* instructions, \n delimited, or NULL */
int numchoices, /* How many choices in list */
char **choices, /* array of choice strings */
int *attributes, /* &3: 0 normal color, 1,3 highlight */
/* &256 marks a dummy entry */
int boxwidth, /* box width, 0 for calc (in items) */
int boxdepth, /* box depth, 0 for calc, 99 for max */
int colwidth, /* data width of a column, 0 for calc */
int current, /* start with this item */
void (*formatitem)(),/* routine to display an item or NULL */
char *speedstring, /* returned speed key value, or NULL >[30]*/
int (*speedprompt)(),/* routine to display prompt or NULL */
int (*checkkey)() /* routine to check keystroke or NULL */
)
/* return is: n>=0 for choice n selected,
-1 for escape
k for checkkey routine return value k (if not 0 nor -1)
speedstring[0] != 0 on return if string is present
*/
{
static char far choiceinstr1a[]="Use the cursor keys to highlight your selection";
static char far choiceinstr1b[]="Use the cursor keys or type a value to make a selection";
static char far choiceinstr2a[]="Press ENTER for highlighted choice, or ESCAPE to back out";
static char far choiceinstr2b[]="Press ENTER for highlighted choice, ESCAPE to back out, or F1 for help";
static char far choiceinstr2c[]="Press ENTER for highlighted choice, or F1 for help";

int titlelines,titlewidth;
int reqdrows;
int topleftrow,topleftcol;
int topleftchoice;
int speedrow; /* speed key prompt */
int boxitems; /* boxwidth*boxdepth */
int curkey,increment,rev_increment;
int redisplay;
int i,j,k;
char far *charptr;
char buf[81];
int speed_match = 0;
char curitem[81];
char *itemptr;
int ret,savelookatmouse;

savelookatmouse = lookatmouse;
lookatmouse = 0;
ret = -1;
if (speedstring
&& (i = strlen(speedstring)) > 0) { /* preset current to passed string */
current = 0;
while (current < numchoices
&& (k = strncasecmp(speedstring,choices[current],i)) > 0)
++current;
if (k < 0 && current > 0) /* oops - overshot */
--current;
if (current >= numchoices) /* bumped end of list */
current = numchoices - 1;
}

while (1) {
if (current >= numchoices) /* no real choice in the list? */
goto fs_choice_end;
if ((attributes[current] & 256) == 0)
break;
++current; /* scan for a real choice */
}

titlelines = titlewidth = 0;
if (hdg) {
charptr = hdg; /* count title lines, find widest */
i = 0;
titlelines = 1;
while (*charptr) {
if (*(charptr++) == '\n') {
++titlelines;
i = -1;
}
if (++i > titlewidth)
titlewidth = i;
}
}

if (colwidth == 0) /* find widest column */
for (i = 0; i < numchoices; ++i)
if (strlen(choices[i]) > colwidth)
colwidth = strlen(choices[i]);

/* title(1), blank(1), hdg(n), blank(1), body(n), blank(1), instr(?) */
reqdrows = 3; /* calc rows available */
if (hdg)
reqdrows += titlelines + 1;
if (instr) { /* count instructions lines */
charptr = instr;
++reqdrows;
while (*charptr)
if (*(charptr++) == '\n')
++reqdrows;
if ((options & 8)) /* show std instr too */
reqdrows += 2;
}
else
reqdrows += 2; /* standard instructions */
if (speedstring) ++reqdrows; /* a row for speedkey prompt */
if (boxdepth > (i = 25 - reqdrows)) /* limit the depth to max */
boxdepth = i;
if (boxwidth == 0) { /* pick box width and depth */
if (numchoices <= i - 2) { /* single column is 1st choice if we can */
boxdepth = numchoices;
boxwidth = 1;
}
else { /* sort-of-wide is 2nd choice */
boxwidth = 60 / (colwidth + 1);
if (boxwidth == 0
|| (boxdepth = (numchoices+boxwidth-1)/boxwidth) > i - 2) {
boxwidth = 80 / (colwidth + 1); /* last gasp, full width */
if ((boxdepth = (numchoices+boxwidth-1)/boxwidth) > i)
boxdepth = i;
}
}
}
if ((i = 77 / boxwidth - colwidth) > 3) /* spaces to add @ left each choice */
i = 3;
j = boxwidth * (colwidth += i) + i; /* overall width of box */
if (j < titlewidth+2)
j = titlewidth + 2;
if (j > 80)
j = 80;
if (j <= 70 && boxwidth == 2) { /* special case makes menus nicer */
++j;
++colwidth;
}
k = (80 - j) / 2; /* center the box */
k -= (90 - j) / 20;
topleftcol = k + i; /* column of topleft choice */
i = (25 - reqdrows - boxdepth) / 2;
i -= i / 4; /* higher is better if lots extra */
topleftrow = 3 + titlelines + i; /* row of topleft choice */

/* now set up the overall display */
helptitle(); /* clear, display title line */
setattr(1,0,C_PROMPT_BKGRD,24*80); /* init rest to background */
for (i = topleftrow-1-titlelines; i < topleftrow+boxdepth+1; ++i)
setattr(i,k,C_PROMPT_LO,j); /* draw empty box */
if (hdg) {
textcbase = (80 - titlewidth) / 2; /* set left margin for putstring */
textcbase -= (90 - titlewidth) / 20; /* put heading into box */
putstring(topleftrow-titlelines-1,0,C_PROMPT_HI,hdg);
textcbase = 0;
}
if (hdg2) /* display 2nd heading */
putstring(topleftrow-1,topleftcol,C_PROMPT_MED,hdg2);
i = topleftrow + boxdepth + 1;
if (instr == NULL || (options & 8)) { /* display default instructions */
if (i < 20) ++i;
if (speedstring) {
speedrow = i;
*speedstring = 0;
if (++i < 22) ++i;
}
putstringcenter(i++,0,80,C_PROMPT_BKGRD,
(speedstring) ? choiceinstr1b : choiceinstr1a);
putstringcenter(i++,0,80,C_PROMPT_BKGRD,
(options&CHOICEMENU) ? choiceinstr2c
: ((options&CHOICEHELP) ? choiceinstr2b : choiceinstr2a));
}
if (instr) { /* display caller's instructions */
charptr = instr;
j = -1;
while ((buf[++j] = *(charptr++)))
if (buf[j] == '\n') {
buf[j] = 0;
putstringcenter(i++,0,80,C_PROMPT_BKGRD,buf);
j = -1;
}
putstringcenter(i,0,80,C_PROMPT_BKGRD,buf);
}

boxitems = boxwidth * boxdepth;
topleftchoice = 0; /* pick topleft for init display */
while (current - topleftchoice >= boxitems
|| (current - topleftchoice > boxitems/2
&& topleftchoice + boxitems < numchoices))
topleftchoice += boxwidth;
redisplay = 1;

while (1) { /* main loop */

if (redisplay) { /* display the current choices */
if ((options & CHOICEMENU) == 0) {
memset(buf,' ',80);
buf[boxwidth*colwidth] = 0;
for (i = (hdg2) ? 0 : -1; i <= boxdepth; ++i) /* blank the box */
putstring(topleftrow+i,topleftcol,C_PROMPT_LO,buf);
}
for (i = 0; i+topleftchoice < numchoices && i < boxitems; ++i) {
/* display the choices */
if ((k = attributes[j = i+topleftchoice] & 3) == 1)
k = C_PROMPT_LO;
else if (k == 3)
k = C_PROMPT_HI;
else
k = C_PROMPT_MED;
if (formatitem)
(*formatitem)(j,charptr=buf);
else
charptr = choices[j];
putstring(topleftrow+i/boxwidth,topleftcol+(i%boxwidth)*colwidth,
k,charptr);
}
/***
... format differs for summary/detail, whups, force box width to
... be 72 when detail toggle available? (2 grey margin each
... side, 1 blue margin each side)
***/
if (topleftchoice > 0 && hdg2 == NULL)
putstring(topleftrow-1,topleftcol,C_PROMPT_LO,"(more)");
if (topleftchoice + boxitems < numchoices)
putstring(topleftrow+boxdepth,topleftcol,C_PROMPT_LO,"(more)");
redisplay = 0;
}

i = current - topleftchoice; /* highlight the current choice */
if (formatitem)
(*formatitem)(current,itemptr=curitem);
else
itemptr = choices[current];
putstring(topleftrow+i/boxwidth,topleftcol+(i%boxwidth)*colwidth,
C_CHOICE_CURRENT,itemptr);

if (speedstring) { /* show speedstring if any */
memset(buf,' ',80);
buf[80] = 0;
putstring(speedrow,0,C_PROMPT_BKGRD,buf);
if (*speedstring) { /* got a speedstring on the go */
putstring(speedrow,15,C_CHOICE_SP_INSTR," ");
if (speedprompt)
j = speedprompt(speedrow,16,C_CHOICE_SP_INSTR,speedstring,speed_match);
else {
putstring(speedrow,16,C_CHOICE_SP_INSTR,speed_prompt);
j = strlen(speed_prompt);
}
strcpy(buf,speedstring);
i = strlen(buf);
while (i < 30)
buf[i++] = ' ';
buf[i] = 0;
putstring(speedrow,16+j,C_CHOICE_SP_INSTR," ");
putstring(speedrow,17+j,C_CHOICE_SP_KEYIN,buf);
movecursor(speedrow,17+j+strlen(speedstring));
}
else
movecursor(25,80);
}
else
movecursor(25,80);

#ifndef XFRACT
while (!keypressed()) { } /* enables help */
#else
waitkeypressed(0); /* enables help */
#endif
curkey = getakey();
#ifdef XFRACT
if (curkey==F10) curkey=')';
if (curkey==F9) curkey='(';
if (curkey==F8) curkey='*';
#endif

i = current - topleftchoice; /* unhighlight current choice */
if ((k = attributes[current] & 3) == 1)
k = C_PROMPT_LO;
else if (k == 3)
k = C_PROMPT_HI;
else
k = C_PROMPT_MED;
putstring(topleftrow+i/boxwidth,topleftcol+(i%boxwidth)*colwidth,
k,itemptr);

increment = 0;
switch (curkey) { /* deal with input key */
case ENTER:
case ENTER_2:
ret = current;
goto fs_choice_end;
case ESC:
goto fs_choice_end;
case DOWN_ARROW:
case DOWN_ARROW_2:
rev_increment = 0 - (increment = boxwidth);
break;
case UP_ARROW:
case UP_ARROW_2:
increment = 0 - (rev_increment = boxwidth);
break;
case RIGHT_ARROW:
case RIGHT_ARROW_2:
if (boxwidth == 1) break;
increment = 1; rev_increment = -1;
break;
case LEFT_ARROW:
case LEFT_ARROW_2:
if (boxwidth == 1) break;
increment = -1; rev_increment = 1;
break;
case PAGE_UP:
if (numchoices > boxitems) {
topleftchoice -= boxitems;
increment = -boxitems;
rev_increment = boxwidth;
redisplay = 1;
}
break;
case PAGE_DOWN:
if (numchoices > boxitems) {
topleftchoice += boxitems;
increment = boxitems;
rev_increment = -boxwidth;
redisplay = 1;
}
break;
case CTL_HOME:
case HOME:
current = -1;
increment = rev_increment = 1;
break;
case CTL_END:
case END:
current = numchoices;
increment = rev_increment = -1;
break;
default:
if (checkkey) {
if ((ret = (*checkkey)(curkey,current)) < -1 || ret > 0)
goto fs_choice_end;
if (ret == -1)
redisplay = -1;
}
ret = -1;
if (speedstring) {
i = strlen(speedstring);
if (curkey == 8 && i > 0) /* backspace */
speedstring[--i] = 0;
if (33 <= curkey && curkey <= 126 && i < 30) {
curkey = tolower(curkey);
speedstring[i] = curkey;
speedstring[++i] = 0;
}
if (i > 0) { /* locate matching type */
current = 0;
while (current < numchoices
&& (speed_match = strncasecmp(speedstring,choices[current],i)) > 0)
++current;
if (speed_match < 0 && current > 0) /* oops - overshot */
--current;
if (current >= numchoices) /* bumped end of list */
current = numchoices - 1;
}
}
break;
}

if (increment) { /* apply cursor movement */
current += increment;
if (speedstring) /* zap speedstring */
speedstring[0] = 0;
}
while (1) { /* adjust to a non-comment choice */
if (current < 0 || current >= numchoices)
increment = rev_increment;
else if ((attributes[current] & 256) == 0)
break;
current += increment;
}
if (topleftchoice > numchoices - boxitems)
topleftchoice = ((numchoices+boxwidth-1)/boxwidth)*boxwidth - boxitems;
if (topleftchoice < 0)
topleftchoice = 0;
while (current < topleftchoice) {
topleftchoice -= boxwidth;
redisplay = 1;
}
while (current >= topleftchoice + boxitems) {
topleftchoice += boxwidth;
redisplay = 1;
}
}

fs_choice_end:
lookatmouse = savelookatmouse;
return(ret);

}


#ifndef XFRACT
/* case independent version of strncmp */
int strncasecmp(char *s,char *t,int ct)
{
for(; (tolower(*s) == tolower(*t)) && --ct ; s++,t++)
if(*s == '\0')
return(0);
return(tolower(*s) - tolower(*t));
}
#endif


static int menutype;
#define MENU_HDG 3
#define MENU_ITEM 1

int main_menu(int fullmenu)
{
char *choices[44]; /* 2 columns * 22 rows */
int attributes[44];
int choicekey[44];
int i;
int nextleft,nextright;
int oldtabmode,oldhelpmode;
oldtabmode = tabmode;
oldhelpmode = helpmode;
top:
menutype = fullmenu;
tabmode = 0;
for (i = 0; i < 44; ++i) {
attributes[i] = 256;
choices[i] = "";
choicekey[i] = -1;
}
nextleft = -2;
nextright = -1;

if (fullmenu) {
choices[nextleft+=2] = " CURRENT IMAGE";
attributes[nextleft] = 256+MENU_HDG;
choicekey[nextleft+=2] = 13; /* enter */
attributes[nextleft] = MENU_ITEM;
if (calc_status == 2)
choices[nextleft] = "continue calculation";
else
choices[nextleft] = "return to image";
choicekey[nextleft+=2] = 9; /* tab */
attributes[nextleft] = MENU_ITEM;
choices[nextleft] = "info about image ";
choicekey[nextleft+=2] = -10;
attributes[nextleft] = MENU_ITEM;
choices[nextleft] = "zoom box functions...";
choicekey[nextleft+=2] = 'o';
attributes[nextleft] = MENU_ITEM;
choices[nextleft] = "orbits window ";
if(!(fractype==JULIA || fractype==JULIAFP || fractype==INVERSEJULIA))
nextleft+=2;
}
choices[nextleft+=2] = " NEW IMAGE";
attributes[nextleft] = 256+MENU_HDG;
choicekey[nextleft+=2] = DELETE;
attributes[nextleft] = MENU_ITEM;
choices[nextleft] = "select video mode... ";
choicekey[nextleft+=2] = 't';
attributes[nextleft] = MENU_ITEM;
choices[nextleft] = "select fractal type ";
if (fullmenu) {
if ((curfractalspecific->tojulia != NOFRACTAL
&& param[0] == 0.0 && param[1] == 0.0)
|| curfractalspecific->tomandel != NOFRACTAL) {
choicekey[nextleft+=2] = ' ';
attributes[nextleft] = MENU_ITEM;
choices[nextleft] = "toggle to/from julia ";
}
if(fractype==JULIA || fractype==JULIAFP || fractype==INVERSEJULIA) {
choicekey[nextleft+=2] = 'j';
attributes[nextleft] = MENU_ITEM;
choices[nextleft] = "toggle to/from inverse ";
}
choicekey[nextleft+=2] = '\\';
attributes[nextleft] = MENU_ITEM;
choices[nextleft] = "return to prior image <\\>";
}
nextleft += 2;
choices[nextleft+=2] = " OPTIONS";
attributes[nextleft] = 256+MENU_HDG;
choicekey[nextleft+=2] = 'x';
attributes[nextleft] = MENU_ITEM;
choices[nextleft] = "basic options... ";
choicekey[nextleft+=2] = 'y';
attributes[nextleft] = MENU_ITEM;
choices[nextleft] = "extended options... ";
choicekey[nextleft+=2] = 'z';
attributes[nextleft] = MENU_ITEM;
choices[nextleft] = "type-specific parms... ";
choicekey[nextleft+=2] = 'v';
attributes[nextleft] = MENU_ITEM;
choices[nextleft] = "view window options... ";
choicekey[nextleft+=2] = 'i';
attributes[nextleft] = MENU_ITEM;
choices[nextleft] = "fractal 3D parms... ";

choices[nextright+=2] = " FILE";
attributes[nextright] = 256+MENU_HDG;
choicekey[nextright+=2] = '@';
attributes[nextright] = MENU_ITEM;
choices[nextright] = "run saved command set... <@>";
if (fullmenu) {
choicekey[nextright+=2] = 's';
attributes[nextright] = MENU_ITEM;
choices[nextright] = "save image to file ";
}
choicekey[nextright+=2] = 'r';
attributes[nextright] = MENU_ITEM;
choices[nextright] = "load image from file... ";
choicekey[nextright+=2] = '3';
attributes[nextright] = MENU_ITEM;
choices[nextright] = "3d transform from file...<3>";
if (fullmenu) {
choicekey[nextright+=2] = '#';
attributes[nextright] = MENU_ITEM;
choices[nextright] = "3d overlay from file.....<#>";
choicekey[nextright+=2] = 'b';
attributes[nextright] = MENU_ITEM;
choices[nextright] = "save current parameters..";
choicekey[nextright+=2] = 'p';
attributes[nextright] = MENU_ITEM;
choices[nextright] = "print image

";
}
choicekey[nextright+=2] = 'd';
attributes[nextright] = MENU_ITEM;
choices[nextright] = "shell to dos ";
choicekey[nextright+=2] = 'g';
attributes[nextright] = MENU_ITEM;

choices[nextright] = "give command string ";
choicekey[nextright+=2] = ESC;
attributes[nextright] = MENU_ITEM;
choices[nextright] = "quit Fractint ";
choicekey[nextright+=2] = INSERT;
attributes[nextright] = MENU_ITEM;
choices[nextright] = "restart Fractint ";
if (fullmenu && gotrealdac && colors >= 16) {
nextright += 2;
choices[nextright+=2] = " COLORS";
attributes[nextright] = 256+MENU_HDG;
/*** choicekey[nextright+=2] = -12;
attributes[nextright] = MENU_ITEM;
choices[nextright] = "color cycling menu...";
choicekey[nextright+=2] = -13;
attributes[nextright] = MENU_ITEM;
choices[nextright] = "palette editing menu..."; ***/
choicekey[nextright+=2] = 'c';
attributes[nextright] = MENU_ITEM;
choices[nextright] = "color cycling mode ";
choicekey[nextright+=2] = '+';
attributes[nextright] = MENU_ITEM;
choices[nextright] = "rotate palette <+>, <->";
if (colors > 16) {
if (!reallyega) {
choicekey[nextright+=2] = 'e';
attributes[nextright] = MENU_ITEM;
choices[nextright] = "palette editing mode ";
}
choicekey[nextright+=2] = 'a';
attributes[nextright] = MENU_ITEM;
choices[nextright] = "make starfield ";
}
}

i = (keypressed()) ? getakey() : 0;
if (menu_checkkey(i,0) == 0) {
helpmode = HELPMAIN; /* switch help modes */
if ((nextleft += 2) < nextright)
nextleft = nextright + 1;
i = fullscreen_choice(CHOICEMENU,
"MAIN MENU",
NULL,NULL,nextleft,choices,attributes,
2,nextleft/2,29,0,NULL,NULL,NULL,menu_checkkey);
if (i == -1) /* escape */
i = ESC;
else if (i < 0)
i = 0 - i;
else { /* user selected a choice */
i = choicekey[i];
switch (i) { /* check for special cases */
case -10: /* zoombox functions */
helpmode = HELPZOOM;
help(0);
i = 0;
break;
}
}
}
if (i == ESC) { /* escape from menu exits Fractint */
static char far s[] = "Exit from Fractint (y/n)? y";
helptitle();
setattr(1,0,C_GENERAL_MED,24*80);
for (i = 9; i <= 11; ++i)
setattr(i,18,C_GENERAL_INPUT,40);
putstringcenter(10,18,40,C_GENERAL_INPUT,s);
movecursor(25,80);
while ((i = getakey()) != 'y' && i != 'Y' && i != 13) {
if (i == 'n' || i == 'N')
goto top;
}
goodbye();
}
if (i == TAB) {
tab_display();
i = 0;
}
if (i == ENTER || i == ENTER_2)
i = 0; /* don't trigger new calc */
tabmode = oldtabmode;
return(i);
}

static int menu_checkkey(int curkey,int choice)
{
int testkey;
testkey = (curkey>='A' && curkey<='Z') ? curkey+('a'-'A') : curkey;
#ifdef XFRACT
/* We use F2 for shift-@, annoyingly enough */
if (testkey == F2) return(0-testkey);
#endif
if (strchr("@txyzgvir3dj",testkey) || testkey == INSERT
|| testkey == ESC || testkey == DELETE)
return(0-testkey);
if (menutype) {
if (strchr("\\sobp",testkey) || testkey == 9)
return(0-testkey);
if (testkey == ' ')
if ((curfractalspecific->tojulia != NOFRACTAL
&& param[0] == 0.0 && param[1] == 0.0)
|| curfractalspecific->tomandel != NOFRACTAL)
return(0-testkey);
if (gotrealdac && colors >= 16) {
if (strchr("c+-",testkey))
return(0-testkey);
if (colors > 16
&& (testkey == 'a' || (!reallyega && testkey == 'e')))
return(0-testkey);
}
}
if (check_vidmode_key(0,testkey) >= 0)
return(0-testkey);
return(0);
}


int input_field(
int options, /* &1 numeric, &2 integer, &4 double */
int attr, /* display attribute */
char *fld, /* the field itself */
int len, /* field length (declare as 1 larger for \0) */
int row, /* display row */
int col, /* display column */
int (*checkkey)(int) /* routine to check non data keys, or NULL */
)
{
char savefld[81];
char buf[81];
int insert, started, offset, curkey, display;
int i, j;
int ret,savelookatmouse;
savelookatmouse = lookatmouse;
lookatmouse = 0;
ret = -1;
strcpy(savefld,fld);
insert = started = offset = 0;
display = 1;
while (1) {
strcpy(buf,fld);
i = strlen(buf);
while (i < len)
buf[i++] = ' ';
buf[len] = 0;
if (display) { /* display current value */
putstring(row,col,attr,buf);
display = 0;
}
curkey = keycursor(row+insert,col+offset); /* get a keystroke */
switch (curkey) {
case ENTER:
case ENTER_2:
ret = 0;
goto inpfld_end;
case ESC:
goto inpfld_end;
case RIGHT_ARROW:
case RIGHT_ARROW_2:
if (offset < len-1) ++offset;
started = 1;
break;
case LEFT_ARROW:
case LEFT_ARROW_2:
if (offset > 0) --offset;
started = 1;
break;
case HOME:
offset = 0;
started = 1;
break;
case END:
offset = strlen(fld);
started = 1;
break;
case 8:
case 127: /* backspace */
if (offset > 0) {
j = strlen(fld);
for (i = offset-1; i < j; ++i)
fld[i] = fld[i+1];
--offset;
}
started = display = 1;
break;
case DELETE: /* delete */
j = strlen(fld);
for (i = offset; i < j; ++i)
fld[i] = fld[i+1];
started = display = 1;
break;
case INSERT: /* insert */
insert ^= 0x8000;
started = 1;
break;
case F5:
strcpy(fld,savefld);
insert = started = offset = 0;
display = 1;
break;
default:
if (nonalpha(curkey)) {
if (checkkey && (ret = (*checkkey)(curkey)))
goto inpfld_end;
break; /* non alphanum char */
}
if (offset >= len) break; /* at end of field */
if (insert && started && strlen(fld) >= len)
break; /* insert & full */
if ((options & 1)
&& (curkey < '0' || curkey > '9')
&& curkey != '+' && curkey != '-') {
if ((options & 2))
break;
/* allow scientific notation, and specials "e" and "p" */
if ( ((curkey != 'e' && curkey != 'E') || offset >= 18)
&& ((curkey != 'p' && curkey != 'P') || offset != 0 )
&& curkey != '.')
break;
}
if (started == 0) /* first char is data, zap field */
fld[0] = 0;
if (insert) {
j = strlen(fld);
while (j >= offset) {
fld[j+1] = fld[j];
--j;
}
}
if (offset >= strlen(fld))
fld[offset+1] = 0;
fld[offset++] = curkey;
/* if "e" or "p" in first col make number e or pi */
if ((options & 3) == 1) { /* floating point */
double tmpd;
int specialv;
char tmpfld[30];
specialv = 0;
if (*fld == 'e' || *fld == 'E') {
tmpd = exp(1.0);
specialv = 1;
}
if (*fld == 'p' || *fld == 'P') {
tmpd = atan(1.0) * 4;
specialv = 1;
}
if (specialv) {
if ((options & 4) == 0)
roundfloatd(&tmpd);
sprintf(tmpfld,"%.15g",tmpd);
tmpfld[len-1] = 0; /* safety, field should be long enough */
strcpy(fld,tmpfld);
offset = 0;
}
}
started = display = 1;
}
}
inpfld_end:
lookatmouse = savelookatmouse;
return(ret);
}

int field_prompt(
int options, /* &1 numeric value, &2 integer */
char *hdg, /* heading, \n delimited lines */
char *instr, /* additional instructions or NULL */
char *fld, /* the field itself */
int len, /* field length (declare as 1 larger for \0) */
int (*checkkey)(int) /* routine to check non data keys, or NULL */
)
{
char *charptr;
int boxwidth,titlelines,titlecol,titlerow;
int promptcol;
int i,j;
char buf[81];
helptitle(); /* clear screen, display title */
setattr(1,0,C_PROMPT_BKGRD,24*80); /* init rest to background */
charptr = hdg; /* count title lines, find widest */
i = boxwidth = 0;
titlelines = 1;
while (*charptr) {
if (*(charptr++) == '\n') {
++titlelines;
i = -1;
}
if (++i > boxwidth)
boxwidth = i;
}
if (len > boxwidth)
boxwidth = len;
i = titlelines + 4; /* total rows in box */
titlerow = (25 - i) / 2; /* top row of it all when centered */
titlerow -= titlerow / 4; /* higher is better if lots extra */
titlecol = (80 - boxwidth) / 2; /* center the box */
titlecol -= (90 - boxwidth) / 20;
promptcol = titlecol - (boxwidth-len)/2;
j = titlecol; /* add margin at each side of box */
if ((i = (82-boxwidth)/4) > 3)
i = 3;
j -= i;
boxwidth += i * 2;
for (i = -1; i < titlelines+3; ++i) /* draw empty box */
setattr(titlerow+i,j,C_PROMPT_LO,boxwidth);
textcbase = titlecol; /* set left margin for putstring */
putstring(titlerow,0,C_PROMPT_HI,hdg); /* display heading */
textcbase = 0;
i = titlerow + titlelines + 4;
if (instr) { /* display caller's instructions */
charptr = instr;
j = -1;
while ((buf[++j] = *(charptr++)))
if (buf[j] == '\n') {
buf[j] = 0;
putstringcenter(i++,0,80,C_PROMPT_BKGRD,buf);
j = -1;
}
putstringcenter(i,0,80,C_PROMPT_BKGRD,buf);
}
else /* default instructions */
putstringcenter(i,0,80,C_PROMPT_BKGRD,
"Press ENTER when finished (or ESCAPE to back out)");
return(input_field(options,C_PROMPT_INPUT,fld,len,
titlerow+titlelines+1,promptcol,checkkey));
}


/* thinking(1,message):
if thinking message not yet on display, it is displayed;
otherwise the wheel is updated
returns 0 to keep going, -1 if keystroke pending
thinking(0,NULL):
call this when thinking phase is done
*/

int thinking(int options,char *msg)
{
static int thinkstate = -1;
static char *wheel[] = {"-","\\","|","/"};
static int thinkcol;
char buf[81];
if (options == 0) {
if (thinkstate >= 0) {
thinkstate = -1;
unstackscreen();
}
return(0);
}
if (thinkstate < 0) {
stackscreen();
thinkstate = 0;
helptitle();
strcpy(buf," ");
strcat(buf,msg);
strcat(buf," ");
putstring(4,10,C_GENERAL_HI,buf);
thinkcol = textcol - 3;
}
putstring(4,thinkcol,C_GENERAL_HI,wheel[thinkstate]);
movecursor(25,80); /* turn off cursor */
thinkstate = (thinkstate + 1) & 3;
return (keypressed());
}


void clear_screen(void) /* a stub for a windows only subroutine */
{
}


/* savegraphics/restoregraphics: video.asm subroutines */

static BYTE far *swapsavebuf;
static unsigned int memhandle;
unsigned long swaptotlen;
unsigned long swapoffset;
BYTE far *swapvidbuf;
int swaplength;
static int swaptype = -1;
static int swapblklen; /* must be a power of 2 */
#ifndef XFRACT
extern BYTE suffix[4096];
#else
BYTE suffix[4096];
#endif

#ifndef XFRACT

int savegraphics()
{
extern int made_dsktemp;
int i;
struct XMM_Move xmmparms;

discardgraphics(); /* if any emm/xmm in use from prior call, release it */
swaptotlen = (long)sxdots * sydots;
i = colors;
while (i <= 16) {
swaptotlen >>= 1;
i = i * i;
}
swapoffset = 0;
if (debugflag != 420 && debugflag != 422 /* 422=xmm test, 420=disk test */
&& (swapsavebuf = emmquery()) != NULL
&& (memhandle = emmallocate((unsigned int)((swaptotlen + 16383) >> 14)))
!= 0) {
swaptype = 0; /* use expanded memory */
swapblklen = 16384;
}
else if (debugflag != 420
&& xmmquery() !=0
&& (memhandle = xmmallocate((unsigned int)((swaptotlen + 1023) >> 10)))
!= 0) {
swaptype = 1; /* use extended memory */
swapblklen = 16384;
}
else {
swaptype = 2; /* use disk */
swapblklen = 4096;

/* MCP 7-7-91, If 'memhandle' is an 'unsigned int', how is it ever going
to be equal to -1?

if ((memhandle = open(diskfilename,O_CREAT|O_WRONLY|O_BINARY,S_IWRITE))
== -1) {
*/
if ((memhandle = open(diskfilename,O_CREAT|O_WRONLY|O_BINARY,S_IWRITE))
== 0xffff) {


dskfile_error:
setvideotext(); /* text mode */
setclear();
{
extern char diskfilename[];
static char far s1[] = {"error in temp file "};
static char far s2[] = { " (disk full?) - aborted\n\n"};
printf("%Fs%s%Fs",s1,diskfilename,s2);
}
exit(1);
}
made_dsktemp = 1;
}
while (swapoffset < swaptotlen) {
swaplength = swapblklen;
if ((swapoffset & (swapblklen-1)) != 0)
swaplength = swapblklen - (swapoffset & (swapblklen-1));
if (swaplength > swaptotlen - swapoffset)
swaplength = swaptotlen - swapoffset;
(*swapsetup)(); /* swapoffset,swaplength -> sets swapvidbuf,swaplength */
switch(swaptype) {
case 0:
emmgetpage((unsigned int)(swapoffset>>14),memhandle);
movewords(swaplength>>1,swapvidbuf,

swapsavebuf+(swapoffset&(swapblklen-1)));
break;
case 1:
xmmparms.Length = swaplength;
xmmparms.SourceHandle = 0; /* Source is conventional memory */
xmmparms.SourceOffset = (unsigned long)swapvidbuf;
xmmparms.DestHandle = memhandle;
xmmparms.DestOffset = swapoffset;
xmmmoveextended(&xmmparms);
break;
default:
movewords(swaplength>>1,swapvidbuf,(BYTE far *)suffix);
if (write(memhandle,suffix,swaplength) == -1)
goto dskfile_error;
}
swapoffset += swaplength;
}
if (swaptype == 2)
close(memhandle);
return 0;
}

void restoregraphics()
{
struct XMM_Move xmmparms;

swapoffset = 0;
if (swaptype == 2)
memhandle = open(diskfilename,O_RDONLY|O_BINARY,S_IREAD);
swapvidbuf = MK_FP(extraseg+0x1000,0); /* for swapnormwrite case */
while (swapoffset < swaptotlen) {
swaplength = swapblklen;
if ((swapoffset & (swapblklen-1)) != 0)
swaplength = swapblklen - (swapoffset & (swapblklen-1));
if (swaplength > swaptotlen - swapoffset)
swaplength = swaptotlen - swapoffset;
if (swapsetup != swapnormread)
(*swapsetup)(); /* swapoffset,swaplength -> sets swapvidbuf,swaplength */
switch(swaptype) {
case 0:
emmgetpage((unsigned int)(swapoffset>>14),memhandle);
movewords(swaplength>>1,swapsavebuf+(swapoffset&(swapblklen-1)),
swapvidbuf);
break;
case 1:
xmmparms.Length = swaplength;
xmmparms.SourceHandle = memhandle;
xmmparms.SourceOffset = swapoffset;
xmmparms.DestHandle = 0; /* conventional memory */
xmmparms.DestOffset = (unsigned long)swapvidbuf;
xmmmoveextended(&xmmparms);
break;
default:
read(memhandle,suffix,swaplength);
movewords(swaplength>>1,(BYTE far *)suffix,swapvidbuf);
}
if (swapsetup == swapnormread)
swapnormwrite();
swapoffset += swaplength;
}
if (swaptype == 2)
close(memhandle);
discardgraphics();
}

#endif

void discardgraphics() /* release expanded/extended memory if any in use */
{
#ifndef XFRACT
switch(swaptype) {
case 0:
emmdeallocate(memhandle);
break;
case 1:
xmmdeallocate(memhandle);
}
swaptype = -1;
#endif
}

extern int extraseg;
extern int badconfig;
extern struct videoinfo far videotable[];
struct videoinfo far *vidtbl; /* temporarily loaded fractint.cfg info */
int vidtbllen; /* number of entries in above */

int load_fractint_cfg(int options)
{
/* Reads fractint.cfg, loading videoinfo entries into extraseg. */
/* Sets vidtbl pointing to the loaded table, and returns the */
/* number of entries (also sets vidtbllen to this). */
/* Past vidtbl, cfglinenums are stored for update_fractint_cfg. */
/* If fractint.cfg is not found or invalid, issues a message */
/* (first time the problem occurs only, and only if options is */
/* zero) and uses the hard-coded table. */

FILE *cfgfile;
struct videoinfo far *vident;
int far *cfglinenums;
int linenum;
int i, j, keynum, ax, bx, cx, dx, dotmode, xdots, ydots, colors;
int commas[10];
int textsafe2;
char tempstring[150];

vidtbl = MK_FP(extraseg,0);
cfglinenums = (int far *)(&vidtbl[MAXVIDEOMODES]);

#ifdef XFRACT
badconfig = -1;
#endif

if (badconfig) /* fractint.cfg already known to be missing or bad */
goto use_resident_table;

findpath("fractint.cfg",tempstring);
if (tempstring[0] == 0 /* can't find the file */
|| (cfgfile = fopen(tempstring,"r")) == NULL) /* can't open it */
goto bad_fractint_cfg;

vidtbllen = 0;
linenum = 0;
vident = vidtbl;
while (vidtbllen < MAXVIDEOMODES
&& fgets(tempstring, 120, cfgfile)) {
++linenum;
if (tempstring[0] == ';') continue; /* comment line */
tempstring[120] = 0;
tempstring[strlen(tempstring)-1] = 0; /* zap trailing \n */
memset(commas,0,20);
i = j = -1;
while (1) {
if (tempstring[++i] < ' ') {
if (tempstring[i] == 0) break;
tempstring[i] = ' '; /* convert tab (or whatever) to blank */
}
else if (tempstring[i] == ',' && ++j < 10) {
commas[j] = i + 1; /* remember start of next field */
tempstring[i] = 0; /* make field a separate string */
}
}
keynum = check_vidmode_keyname(tempstring);
sscanf(&tempstring[commas[1]],"%x",&ax);
sscanf(&tempstring[commas[2]],"%x",&bx);
sscanf(&tempstring[commas[3]],"%x",&cx);
sscanf(&tempstring[commas[4]],"%x",&dx);
dotmode = atoi(&tempstring[commas[5]]);
xdots = atoi(&tempstring[commas[6]]);
ydots = atoi(&tempstring[commas[7]]);
colors = atoi(&tempstring[commas[8]]);
textsafe2 = dotmode / 100;
dotmode %= 100;
if (j != 9 ||
keynum < 0 ||
dotmode < 0 || dotmode > 30 ||
textsafe2 < 0 || textsafe2 > 4 ||
xdots < 160 || xdots > MAXPIXELS ||
ydots < 160 || ydots > MAXPIXELS ||
(colors != 0 && colors != 2 && colors != 4 && colors != 16 &&
colors != 256)
)
goto bad_fractint_cfg;
cfglinenums[vidtbllen] = linenum; /* for update_fractint_cfg */
far_memcpy(vident->name, (char far *)&tempstring[commas[0]],25);
far_memcpy(vident->comment,(char far *)&tempstring[commas[9]],25);
vident->name[25] = vident->comment[25] = 0;
vident->keynum = keynum;
vident->videomodeax = ax;
vident->videomodebx = bx;
vident->videomodecx = cx;
vident->videomodedx = dx;
vident->dotmode = textsafe2 * 100 + dotmode;
vident->xdots = xdots;
vident->ydots = ydots;
vident->colors = colors;
++vident;
++vidtbllen;
}
fclose(cfgfile);
return (vidtbllen);

bad_fractint_cfg:
badconfig = -1; /* bad, no message issued yet */
if (options == 0)
bad_fractint_cfg_msg();

use_resident_table:
vidtbllen = 0;
vident = vidtbl;
for (i = 0; i < MAXVIDEOTABLE; ++i) {
if (videotable[i].xdots) {
far_memcpy((char far *)vident,(char far *)&videotable[i],
sizeof(*vident));
++vident;
++vidtbllen;
}
}
return (vidtbllen);

}

void bad_fractint_cfg_msg()
{
static char far badcfgmsg[]={"\
File FRACTINT.CFG is missing or invalid.\n\
See Hardware Support and Video Modes in the full documentation for help.\n\
I will continue with only the built-in video modes available."};
stopmsg(0,badcfgmsg);
badconfig = 1; /* bad, message issued */
}

void load_videotable(int options)
{
/* Loads fractint.cfg and copies the video modes which are */
/* assigned to function keys into videotable. */
int keyents,i;
load_fractint_cfg(options); /* load fractint.cfg to extraseg */
keyents = 0;
far_memset((char far *)videotable,0,sizeof(*vidtbl)*MAXVIDEOTABLE);
for (i = 0; i < vidtbllen; ++i) {
if (vidtbl[i].keynum > 0) {
far_memcpy((char far *)&videotable[keyents],(char far *)&vidtbl[i],
sizeof(*vidtbl));
if (++keyents >= MAXVIDEOTABLE)
break;
}
}
}

int check_vidmode_key(int option,int k)
{
int i;
/* returns videotable entry number if the passed keystroke is a */
/* function key currently assigned to a video mode, -1 otherwise */
if (k == 1400) /* special value from select_vid_mode */
return(MAXVIDEOTABLE-1); /* for last entry with no key assigned */
if (k != 0)
if (option == 0) { /* check resident video mode table */
for (i = 0; i < MAXVIDEOTABLE; ++i) {
if (videotable[i].keynum == k)
return(i);
}
}
else { /* check full vidtbl */
for (i = 0; i < vidtbllen; ++i) {
if (vidtbl[i].keynum == k)
return(i);
}
}
return(-1);
}

int check_vidmode_keyname(char *kname)
{
/* returns key number for the passed keyname, 0 if not a keyname */
int i,keyset;
keyset = 1058;
if (*kname == 'S' || *kname == 's') {
keyset = 1083;
++kname;
}
else if (*kname == 'C' || *kname == 'c') {
keyset = 1093;
++kname;
}
else if (*kname == 'A' || *kname == 'a') {
keyset = 1103;
++kname;
}
if (*kname != 'F' && *kname != 'f')
return(0);
if (*++kname < '1' || *kname > '9')
return(0);
i = *kname - '0';
if (*++kname != 0 && *kname != ' ') {
if (*kname != '0' || i != 1)
return(0);
i = 10;
++kname;
}
while (*kname)
if (*(kname++) != ' ')
return(0);
if ((i += keyset) < 2)
i = 0;
return(i);
}

void vidmode_keyname(int k,char *buf)
{
/* set buffer to name of passed key number */
*buf = 0;
if (k > 0) {
if (k > 1103) {
*(buf++) = 'A';
k -= 1103;
}
else if (k > 1093) {
*(buf++) = 'C';
k -= 1093;
}
else if (k > 1083) {
*(buf++) = 'S';
k -= 1083;
}
else
k -= 1058;
sprintf(buf,"F%d",k);
}
}


  3 Responses to “Category : C Source Code
Archive   : FRASRC18.ZIP
Filename : REALDOS.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/