The one thing that was good about SR was the freedom to create...
Code:
#include <box3d_v4.h>
/* globals used only for this library */
int SavedVideoMode;
int VideoRam;
int GraphInit=FALSE;
char cutpastebuf[256];
RasterBlock *ImageBuffer;
/* end globals
/*
** determine the size of the memory area required to store an image
**
** return value - unsigned long number of bytes for screen image
*/
unsigned long ImageSize(int x1, int y1, int x2, int y2)
{
return((unsigned long)(((long)(x2-x1+1) * (long)(y2-y1+1)) + 4));
}
/*
** check processor type - return FALSE if less than I386
** determine video card - return FALSE if not supported
** store video ram size
** save current video mode
** create a buffer for misc usgage
** enable box3dfnt font
** set initialized flag
**
** on success - return TRUE
** on failure - return FALSE
*/
int InitGraphics()
{
if(GraphInit==TRUE)
return(FALSE);
GraphInit=FALSE;
if(whichcpu() < I386)
return(FALSE);
if(whichvga()==0)
return(FALSE);
/* Build an 8k buffer for misc. graphic functions */
ImageBuffer=(RasterBlock *)farmalloc(MEM8K);
if(ImageBuffer==NULL)
return(FALSE);
/*
** returns video mode to previous state
**
** return value - none
*/
void CloseGraphics()
{
if(GraphInit==TRUE)
{
farfree(ImageBuffer);
videomodeset(SavedVideoMode);
}
}
/*
** set the graphics mode
**
** on success - return TRUE
** on failure - return FALSE
** invalid Mode or unable to set video mode
*/
int SetVideoMode(int Mode)
{
PaletteData pal;
if(GraphInit==FALSE)
return(FALSE);
switch(Mode)
{
case RES320:
res320();
break;
case RES640:
if(!res640())
return(FALSE);
break;
case RES640L:
if(!res640l())
return(FALSE);
break;
case RES800:
if(!res800())
return(FALSE);
break;
case RES1024:
if(!res1024())
return(FALSE);
break;
case RES1280:
if(!res1280())
return(FALSE);
break;
BOX3D *CreateBox(int left,
int top,
int right,
int bottom,
int highlight,
int fill,
int shadow,
BOOL title,
char justify,
char *titletext,
char titletextcolor,
char titlebackground,
BOOL saveimage,
BOOL waitforsync)
{
int Vert;
/* the box needs to be high enough and long enough to hold a titlebar */
if(title)
{
if(bottom-top < TITLEBAR)
{
bottom=top + TITLEBAR;
if(bottom > maxy)
{
top-=bottom - maxy;
bottom=maxy;
}
}
/* create a titlebar */
if(title)
{
drwfillbox(SET, titlebackground, left + BORDERSPACE,
top + BORDERSPACE,
right - BORDERSPACE,
top + BORDERSPACE + TITLEAREA);
drwline(SET, shadow, left + BORDERSPACE,
top + BORDERSPACE,
right - BORDERSPACE,
top + BORDERSPACE);
drwline(SET, shadow, left + BORDERSPACE,
top + BORDERSPACE,
left + BORDERSPACE,
top + BORDERSPACE + TITLEAREA);
drwline(SET, highlight, right - BORDERSPACE,
top + BORDERSPACE + TITLEAREA,
right - BORDERSPACE,
top + BORDERSPACE);
drwline(SET, highlight, right - BORDERSPACE,
top + BORDERSPACE + TITLEAREA,
left + BORDERSPACE,
top + BORDERSPACE + TITLEAREA);
/* make sure we don't exceed the number of characters */
if(strlen(titletext) >= TITLELEN)
titletext[TITLELEN-1]=0x00;
/* truncate any text that will not fit nicely in the titlebar */
while(((strlen(titletext)+1)*CHARSPACE) > (right-BORDERSPACE)-(left+BORDERSPACE))
{
titletext[strlen(titletext)-1]=0x00;
justify=LEFT;
}
if(justify==LEFT)
drwstring(SET, titletextcolor, titlebackground, titletext,
left + CHARSPACE, top + CHARSPACE);
else if(justify==CENTERED)
drwstring(SET, titletextcolor, titlebackground, titletext,
left + (((right-left) - (strlen(titletext) * CHARSPACE)) / 2),
top + CHARSPACE);
else if(justify==RIGHT)
drwstring(SET, titletextcolor, titlebackground, titletext,
right - (strlen(titletext) * CHARSPACE) - CHARSPACE,
top + CHARSPACE);
}
/* copy the variables into the structure */
Box->left=left;
Box->top=top;
Box->right=right;
Box->bottom=bottom;
Box->highlight=highlight;
Box->fill=fill;
Box->shadow=shadow;
Box->title=title;
Box->justify=justify;
Box->titletextcolor=titletextcolor;
Box->titlebackground=titlebackground;
Box->saveimage=saveimage;
Box->waitforsync=waitforsync;
strcpy(Box->titletext, titletext);
return(Box);
}
/*
** removes boxes off screen that were created with the save command
** restores previous background image
** cleans up memory allocation or temporary disk files
*/
int DestroyBox(BOX3D *Box)
{
int Vert;
FILE *FilePtr;
/* remove the box and replace the background */
if(Box->image!=NULL)
{
/* nackground image was stored in memory */
/* replace image and clean-up variables */
blkput(SET, Box->left, Box->top, Box->image);
farfree(Box->image);
Box->image=NULL;
memset(&Box, 0x00, sizeof(Box));
return(TRUE);
}
else if(Box->imagefile!=NULL)
{
/* background image was stored on disk in a temporary file */
FilePtr=_fsopen(Box->imagefile, "rb", SH_DENYNO);
if(FilePtr==NULL)
return(TRUE);
/* restore the image one line at a time */
for(Vert=Box->top; Vert <= Box->bottom; Vert++)
{
fread(ImageBuffer, (size_t)ImageSize(Box->left, Vert, Box->right, Vert), 1, FilePtr);
blkput(SET, Box->left, Vert, ImageBuffer);
}
/*
** frees up allocated memory associated with createbox
*/
void DestroyBoxPtr(BOX3D *Box)
{
if(Box!=NULL)
{
farfree(Box);
Box=NULL;
}
}
/*
** create a border frame within a box. coordinates are relative
** to the left/top of the box which the border is being created in.
** the title bar area if exists is taken into account.
*/
int Bump3D(BOX3D *box, int left, int top, int right, int bottom)
{
/* adjust to coordinates when a title bar exists */
if(box->title)
top+=TITLEBAR;
/* check coordinates to make sure they will fit */
if(left < box->left || right > box->right-1 ||
top < box->top || bottom > box->bottom-1)
return(FALSE);
/*
** create a border frame with a label within a box. coordinates are relative
** to the left/top of the box which the border is being created in.
** the title bar area if exists is taken into account.
*/
int Bump3DTitle(BOX3D *box, int left, int top, int right, int bottom, int titlecolor, char *title, int is3d)
{
if(Bump3D(box, left, top, right, bottom))
{
/* adjust to coordinates when a title bar exists */
if(box->title)
top+=TITLEBAR;
/* Remove the area of the frame where the title will be displayed */
drwline(SET, box->fill, left+BORDERSPACE+CHARSPACE,
top,
left+BORDERSPACE+CHARSPACE + ((strlen(title)+2)*CHARSPACE),
top);
drwline(SET, box->fill, left+BORDERSPACE+CHARSPACE,
top+1,
left+BORDERSPACE+CHARSPACE+((strlen(title)+2)*CHARSPACE),
top+1);
/* 3d style forces text to white with black shadow */
if(is3d)
{
drwstring(SET, BLACK, box->fill, title,
left+BORDERSPACE + (CHARSPACE*2)+1,
top - (BORDERSPACE-1)+1);
drwstring(OR, WHITE, BLACK, title,
left+BORDERSPACE + (CHARSPACE*2),
top - (BORDERSPACE-1));
}
else
drwstring(SET, titlecolor, box->fill, title,
left+BORDERSPACE + (CHARSPACE*2)+1,
top - (BORDERSPACE-1)+1);
}
else
return(FALSE);
return(TRUE);
}
/*
** BoxText allows text to be placed in a pseudo column/row within a box.
**
** The dot parameters specify how many dots down/right to adjust the text
** for. Valid entries are between 0-CHARSPACE.
**
** If the word wrap option is on, text strings that are longer than the box
** will be wrapped to the next line. Otherwise, the string will be truncated
** to fit on one line.
**
** \FE Function returns TRUE success.
** \FE Function returns FALSE when invalid coordinates are given.
*/
int BoxText(BOX3D *box, int column, char dotc, int row, char dotr, int textcolor, char *text, int wordwrap)
{
char *headptr;
char *tailptr;
char *tempbuffer;
char *outputtext;
int tempcol;
int stringlen;
int templen;
/* don't print it if it doesn't exist */
if(strlen(text)==0)
return(FALSE);
/* truncate any text that will not fit in the box */
if(!wordwrap)
{
while(column + ((stringlen=strlen(text))*CHARSPACE) > box->right)
text[stringlen-1]=NULL;
strcpy(outputtext, text);
}
else
{
if(column + (stringlen*CHARSPACE) > box->right-BORDERSPACE)
{
/* find where to start truncate */
while(headptr!=tailptr)
{
stringlen=strlen(headptr);
/* find one line */
while(column + (stringlen*CHARSPACE) > box->right-BORDERSPACE)
stringlen--;
/* search for a [SPACE] if line needs to be truncated */
templen=stringlen;
if(column + (stringlen*CHARSPACE) >= box->right-(BORDERSPACE * 2))
{
while(headptr[stringlen]!=0x20 && stringlen!=0)
stringlen--;
/* if no space was found and column not at 0, move line down */
if(stringlen==0 && tempcol!=0)
{
column=box->left+BORDERSPACE+dotc;
strncpy(tempbuffer, headptr, templen);
tempbuffer[templen]=0x00;
headptr+=templen;
}
/* if no space was found and column is at 0, truncate at end */
else if(stringlen==0 && tempcol==0)
{
stringlen=templen;
headptr+=templen;
strncpy(tempbuffer, headptr, templen);
tempbuffer[templen]=0x00;
}
else
{
strncpy(tempbuffer, headptr, stringlen);
tempbuffer[stringlen]=0x00;
headptr+=stringlen+1;
}
}
else
{
/* no truncating left to do */
strncpy(tempbuffer, headptr, stringlen);
tempbuffer[stringlen]=0x00;
headptr+=stringlen;
}
drwstring(SET, textcolor, box->fill, tempbuffer, column, row);
column=box->left+BORDERSPACE;
row+=CHARROW;
if(row > box->bottom-(CHARROW))
break;
/* check for bottom of box */
/*
** This will allow the user to enter text into a box at a specified
** column and row using any text color they want. The *textedit
** variable will hold the users entry. The length of the text is
** is specified in int len. There are various flags that can be OR'd
** together to allow a little more diversity in the type of
** characters the user can enter. There is also a PASSWORD option
** that when enabled, echos back the '*' (asterik) character.
**
** \FE Flags
** ALPHA A-Z || a-z
** DIGIT 0-9
** LOWER a-z
** UPPER A-Z
** PRINT 0x20 - 0x7E
** EXTENDED 0x7F - 0xFF
** PWORD display * instead of character
** NOWAIT returns even when no character is ready
**
** \FE Returns
** ASCII characters (0x20 - 0xFF) return thier value.
** Extended key presses (F1-F12, ALT-key) return hi-byte=0xFF lo-byte=val
**
** \FE Remarks
** Full function editing is enabled (cut & paste are disabled if the
** PASSWORD flag is set). Left and Right arrow key presses, Home, End,
** Insert and Delete do not return. Page Up, Page Down, Up and Down
** arrow return thier normal extended values. The cut and paste buffer
** is set at 80 characters (including the NULL terminator). This function
** was not meant to be a full-blown word processor.
*/
unsigned int BoxEdit(BOX3D *box, int color, int col, int row, char *textedit, int len, int flag)
{
int i; // temp interger
int k=0; // character buffer
int kb; // BIOS keyboard status
int lastkey=0; // storage of last extended keypress
int mark=FALSE; // text marking flag
int bufinuse=FALSE; // is anything in the cut & paste buffer
int flash=0; // determine status of cursor
int delayf=1000; // cursor blink dealy
int cdelay=0; // increment to test when to blink
int validflag; // check for a valid character key press
int functionkey; // stores all extended keypresses
int left; // left coordinate in pixels
int top; // top coordinate in pixels
int insert=0; // insert flag
int keystatus; // SHIFT/CONTROL flag
int cursorpos; // cursor position
char blockpos[2]={0xFF,
0xFF}; // text marking positions [0]=start [1]=stop
unsigned int retvalue; // return value of function
cursorpos=strlen(textedit);
/* return on C/R, TAB, ESC or function key press (F1-F12) */
/* also returns on any extended key press (ie; ALT-X) */
while(k!=13 && k!=9 && k!=27 && k!=-1)
{
/* place text in the box */
if((flag & PWORD)==PWORD)
{
/* if the password flag is set, echo back an asterik. */
if(!mark)
if(strlen(textedit)!=0)
BoxText(box, col+strlen(textedit)-1, 0, row, 0, color, "*", FALSE);
}
else
{
/* display the text as it should be seen. */
if(!mark)
BoxText(box, col, 0, row, 0, color, textedit, FALSE);
}
/* get a keypress */
/* if the NOWAIT flag is set, the cursor will appear in the "on" */
/* state at all times. */
while(!kbhit())
{
left=box->left + ((col+cursorpos) * CHARSPACE);
if(left > box->right-(CHARSPACE*2))
len=cursorpos;
/* if NOWAIT flag is set, remove the cursor and return. */
if((flag & NOWAIT)==NOWAIT)
{
if(flash)
blkput(XOR, left+4, top+4, (RasterBlock *)cursor);
return(FALSE);
}
}
/* if the character was acceptable, append it to the string and */
/* display it. */
if(validflag)
{
/* remove cursor from the screen. */
if(flash)
{
blkput(XOR, left+4, top+4, (RasterBlock *)cursor);
flash^=1;
}
/* copy marked text into copy/paste buffer, remove text */
strncpy(cutpastebuf, textedit+blockpos[0], (blockpos[1]-blockpos[0])+1);
cutpastebuf[blockpos[1]-blockpos[0]+1]=NULL;
bufinuse=TRUE;
/* clear trailing text */
if(cursorpos!=strlen(textedit))
{
BoxText(box, col+cursorpos-1, 0, row, 0, box->fill, textedit+cursorpos-1, FALSE);
movmem(textedit+cursorpos, textedit+cursorpos-1, strlen(textedit+cursorpos));
textedit[strlen(textedit)-1]=NULL;
}
else
{
/* remove last character from the string */
BoxText(box, col+strlen(textedit)-1, 0, row, 0, box->fill, "\DB", FALSE);
textedit[strlen(textedit)-1]=NULL;
}
/* Track cursor position */
cursorpos--;
}
}
/* return value is a 2 byte code. If the hi-byte is NULL, the next */
/* byte equals a character (0x20 - 0xFF). Else, hi-byte is 0xFF */
/* lo-byte equals an extened character (F1-F12, ALT+key). */
if(k==-1)
retvalue=0xFF00 | functionkey;
else
retvalue=k;
/*
** Clear the entire contents of a box. If there are any other objects such
** as a titlebar, effects, text or any overlapping boxes, they will be
** cleared or clipped with no redraw. This function is mainly used whe
** working with the BoxEdit function.
*/
void ClrBox(BOX3D *box, int sync)
{
/* avoid screen flicker... wait for vertical retrace */
if(sync)
sdelay(1);
/*
** Create a message box to display on the screen.
** Delay sets the number of seconds to display the message for.
** A keypress will override the delay, and a delay set for 0 will
** disable the timer, requiring a keypress before proceeding.
** The *message text can contain up to five newline '\n' characters.
** The color passed should be in the range 0-7
*/
int MessageBox(char color, char *title, char *message, int delay)
{
BOX3D *messagebox;
int kp;
int l;
int lines;
int longest;
int xcentertext;
int xcharlength;
char linemessage[5][80];
time_t first, second;
l=0;
lines=0;
memset(linemessage, 0x00, sizeof(linemessage));
for(kp=0; kp<strlen(message); kp++)
{
if(message[kp]=='\n')
{
/* found a new line character. NULL terminate the message */
/* line and increment to the next message line. */
linemessage[lines][l]=NULL;
lines++;
/* make sure we don't exceed our number of lines. */
if(lines==5)
{
lines--;
break;
}
/* set the character line position back to the begining. */
l=0;
}
else
{
/* keep appending the message characters. */
linemessage[lines][l]=message[kp];
linemessage[lines][l+1]=NULL;
l++;
}
}
/* truncate any long lines. */
kp=0;
longest=0;
for(l=0; l<=lines; l++)
{
while(strlen(linemessage[l]) > 76)
linemessage[l][strlen(linemessage[l])-1]=NULL;
/* get the longest line. */
if(strlen(linemessage[l]) > kp)
{
kp=strlen(linemessage[l]);
longest=l;
}
}
That's because they hung onto that mainframe until the bitter end. They had another group of developers that were writing programs for their own facility that were developing in C. It's only the group that developed for remote facilities that were writing OBOL...
and so what uranus is a star - Rob
-----------------------
Kruger
I haven't touched any BOL since a couple of Rottenchester's programs made it to the facility here and got converted to C. In fact, there isn't much programming that I do anymore anyway. A little Python when I was at Doxee, and some bits of JS when there isn't a plugin that will do what I need...
and so what uranus is a star - Rob
-----------------------
Kruger