541 lines
13 KiB
C
541 lines
13 KiB
C
/*
|
||
MYLIB2.C
|
||
|
||
These routines are CONDITIONALLY compiled; i.e., only as needed.
|
||
|
||
----------------------------------------------------------------------
|
||
Incorporates special mods used by my Backgammon game, BACKGMMN.C etc.
|
||
----------------------------------------------------------------------
|
||
|
||
A set of common I/O functions that seem to turn up a lot in my programs,
|
||
including terminal functions for Kaypro 10, 4'84, 2X etc.
|
||
|
||
Uses Software Toolworks' C/80 3.1 compiler. Place #include "mylib2.c" at the
|
||
end of your source file for correct CONDITIONAL COMPILATION.
|
||
|
||
David C. Oshel
|
||
1219 Harding Ave.
|
||
Ames, Iowa 50010
|
||
|
||
Last modified: March 25, 1986
|
||
|
||
-----------------------------------------------------------------------------
|
||
** WARNING ** These routines use direct console IO, bdos function 6!
|
||
|
||
YOU MUST CALL INIT_LIB() BEFORE USING THESE ROUTINES!
|
||
|
||
======= UTILITIES =======
|
||
|
||
* init_lib() - CALL THIS FIRST, OR THE RESULT WILL BE VERY STRANGE!
|
||
*
|
||
* puts(p) - unformatted print, e.g., puts("Hello, sailor!\n");
|
||
* gets(p,max) - printable input only, no prompt character
|
||
*
|
||
* ask(p) - demand Yes or No response to question p
|
||
* random() - effective random 16-bit integer IFF gets() is used
|
||
* sleep(n) - sleep n/10ths of a second, roughly (from C80.LIB)
|
||
* rollup() - roll up 23 lines of screen
|
||
* ONscript() - printer echo ON for output via puts, chrout
|
||
* OFFscript() - printer echo OFF for output via puts, chrout
|
||
* ONinterrupt() - Ctl-C, Ctl-B cause program exit
|
||
* OFFinterrupt() - Ctl-C, Ctl-B cause comedy
|
||
* hide_input(p,max) - like gets, but used when entering passwords
|
||
* chrout(c) - if scripting, echo output also to LST:
|
||
* putscreen(p) - like puts, but always and only to screen
|
||
|
||
|
||
======= KAYPRO 10 TERMINAL/VIDEO FUNCTIONS =======
|
||
|
||
* gotoxy(x,y) - 0,0 is top left, horz <= 79 precedes vert <= 24,
|
||
* where 0,24 is on the 25th, status, line.
|
||
* beep() - terminal bell
|
||
* home() - home cursor, do not clear screen
|
||
* clr_screen() - home and clear
|
||
*
|
||
* shadow_box(h,v,x1,y1,x2,y2) - like box, but with shadow, calls box
|
||
* box(tlx,tly,brx,bry) - draw a line box, coords: topleft XY, bottomright XY
|
||
* note that box calls ldraw(x1,y1,x2,y2), below
|
||
*
|
||
* clr_lend() - clear from cursor to end of line
|
||
* clr_send() - clear from cursor to end of screen
|
||
* rev_vid(),
|
||
* nor_vid() - reverse field
|
||
* dim_vid(),
|
||
* bri_vid() - low/high intensity
|
||
* on_blink(),
|
||
* off_blink() - blinking chars
|
||
* ul_start(),
|
||
* ul_stop() - start/stop underline
|
||
* save_cursor(),
|
||
* retn_cursor() - remember/restore current cursor location
|
||
* ins_line(),
|
||
* del_line() - insert/delete screen text line
|
||
* on_cursor(),
|
||
* off_cursor() - hide/show cursor
|
||
* vm_on(),
|
||
* vm_off() - "Video Mode" commands
|
||
* pixel(x,y) - draw pixel at x,y (video coords, x <= 159, y <= 99)
|
||
* no_pixel(x,y) - erase pixel at x,y
|
||
* ldraw(x1,y1,x2,y2) - draw/ erase graphics line, see discussion for box
|
||
* lwipe(x1,y1,x2,y2) - range for video coordinates as for pixel
|
||
*/
|
||
|
||
|
||
#ifndef TRUE
|
||
#define TRUE 1
|
||
#endif
|
||
#ifndef FALSE
|
||
#define FALSE 0
|
||
#endif
|
||
|
||
|
||
/* hide this here so's not to worry about it elsewhere */
|
||
/* "printf.c" collides with one of these, can't remember which */
|
||
/* puts() takes longer to write, but executes faster */
|
||
extern char Cmode, IOpread[4], IOpwrit[4], IOpeof[4];
|
||
|
||
/* make these known only to what follows */
|
||
static int MYbstout, MYscrtp, MYretnirp; /* odd names mark semi-private */
|
||
static unsigned RNDloc; /* effective random location, bumped by gets() */
|
||
/* and scrambled when the LCG random() is called */
|
||
/* makes a decent algorithm for interactive games */
|
||
|
||
|
||
#ifneed init_lib
|
||
init_lib() {
|
||
|
||
MYretnirp = fopen("LST:","w");
|
||
OFFscript();
|
||
ONinterrupt();
|
||
Cmode = 0;
|
||
IOpread[0] = 6; IOpwrit[0] = 6;
|
||
|
||
} /* end: init_lib */
|
||
#endif
|
||
|
||
|
||
|
||
|
||
#ifneed random
|
||
random() { /* depends on effective random location spun by gets() */
|
||
|
||
RNDloc = 2053 * RNDloc + 13849;
|
||
return (RNDloc);
|
||
}
|
||
#endif
|
||
|
||
|
||
|
||
#ifneed ONscript
|
||
ONscript() {
|
||
|
||
MYscrtp = TRUE;
|
||
|
||
}
|
||
#endif
|
||
#ifneed OFFscript
|
||
OFFscript() {
|
||
|
||
MYscrtp = FALSE;
|
||
|
||
}
|
||
#endif
|
||
|
||
|
||
#ifneed ONinterrupt
|
||
ONinterrupt() {
|
||
|
||
MYbstout = TRUE;
|
||
|
||
}
|
||
#endif
|
||
#ifneed OFFinterrupt
|
||
OFFinterrupt() {
|
||
|
||
MYbstout = FALSE;
|
||
|
||
}
|
||
#endif
|
||
|
||
|
||
#ifneed ask
|
||
ask(p) char *p; {
|
||
|
||
char ch, resp[2];
|
||
|
||
loo: puts(p);
|
||
gets(resp,1);
|
||
ch = toupper( *resp );
|
||
if ( !( ch == 'Y' || ch == 'N' )) {
|
||
puts("Please answer the question, Yes or No.\n");
|
||
goto loo;
|
||
}
|
||
return (ch == 'Y');
|
||
|
||
} /* end: ask */
|
||
#endif
|
||
|
||
|
||
#ifneed rollup
|
||
rollup() {
|
||
|
||
int i;
|
||
|
||
for (i=0; i<23; i++) puts("\n");
|
||
|
||
} /* end: rollup */
|
||
#endif
|
||
|
||
|
||
#ifneed sleep
|
||
sleep( n ) int n; { /* sleep for n/10 seconds, 0 <= n < 256 */
|
||
|
||
n; /* get n into HL */
|
||
#asm
|
||
MOV B,L ;delay B/10ths of a second
|
||
__DL0: MVI A,100 ;100 milliseconds, 1/10 second
|
||
__DL1: MVI C,249 ;1 millisecond per unit of A at 4 MHz
|
||
__DL2: DCR C ;Leventhal, Z80 Assembly Language Programming
|
||
JNZ __DL2
|
||
DCR A
|
||
JNZ __DL1
|
||
DCR B
|
||
JNZ __DL0 ;on exit, HL has FALSE if n was 0, else TRUE
|
||
#endasm
|
||
} /* end: sleep */
|
||
#endif
|
||
|
||
|
||
/*========================================*/
|
||
/* GETS(p, maxinput) */
|
||
/* Local getline function with special *---* WARNING: */
|
||
/* input handling, 1 <= len <= maxinput *---* Execute INIT_LIB() first !! */
|
||
/* Updates effective random, RNDloc, */
|
||
/* Forces input from CONSOLE only! */
|
||
/*========================================*/
|
||
|
||
#ifneed gets
|
||
gets(p,maxinput) char *p; int maxinput; {
|
||
|
||
/* This function depends on BDOS Function #6. Init_lib() sets Cmode=0 and
|
||
IOpread[0]=6 and IOpwrit[0]=6 (courtesy of and peculiar to C/80 3.1)
|
||
YOU must ensure that the target string is long enough to collect the
|
||
entire maximum input allowed and specified, INCLUDING FINAL NULL! */
|
||
|
||
static int len;
|
||
static char ch;
|
||
|
||
len = -1;
|
||
if (maxinput < 1 || maxinput > 127) maxinput = 79;
|
||
|
||
/*--------------------------------*/
|
||
/* SPECIAL ROUTINE FOR BACKGAMMON */
|
||
/*--------------------------------*/
|
||
|
||
loo: while ( !(ch = getc(0)) ) acg(); /* keep the game lively */
|
||
|
||
if (len < 0) len = 0; /* don't destroy prompt by backing up */
|
||
if (ch == '\n') { /* end of line? don't store newline */
|
||
*p = '\0'; /* mark it with a B for baby and me */
|
||
/* chrout('\n'); */ /* but DON'T echo newline */
|
||
return ( len ); /* <--- HERE IS THE FUNCTION EXIT! */
|
||
}
|
||
else if (ch == '\b' || ch == 0x7F) { /* backspace? rubout? */
|
||
if (len--) { /* where's the prompt? */
|
||
puts("\008 \008"); /* we're ok, echo erase */
|
||
p--; /* delete from string */
|
||
}
|
||
}
|
||
|
||
/*--------------------------------*/
|
||
/* SPECIAL ROUTINE FOR BACKGAMMON */
|
||
/*--------------------------------*/
|
||
|
||
else if (ch == '\003') { /* user bailout key is Ctrl-C, not ESC */
|
||
if (MYbstout) exit();
|
||
else {
|
||
haltgame(); /* sets whofirst flag and does jumpjack() */
|
||
}
|
||
}
|
||
|
||
else if (ch == '\025' || ch == '\030') { /* Ctl-U, Ctl-X */
|
||
while (len--) {
|
||
p--;
|
||
puts("\008 \008");
|
||
}
|
||
}
|
||
else if (len == maxinput) { /* test specials before testing len */
|
||
chrout('\007');
|
||
}
|
||
else if (ch > 31 && ch < 127) { /* printable char? */
|
||
chrout(ch); /* yes, echo it */
|
||
*p++ = ch; /* collect it */
|
||
len++; /* keep track of it */
|
||
}
|
||
else { /* control chars? */
|
||
chrout('\007');
|
||
}
|
||
goto loo;
|
||
|
||
} /* end: gets */
|
||
#endif
|
||
|
||
|
||
|
||
|
||
#ifneed hide_input
|
||
hide_input(s,len) char *s; int len; {
|
||
|
||
/* receive at most len chars in s buffer,
|
||
terminate string with zero,
|
||
but echo each char with 1, 2, or 3 meaningless dots */
|
||
|
||
char ch; int num;
|
||
|
||
if ((len < 1) || (len > 127)) len = 127;
|
||
num = 0;
|
||
for (;;) { /* forever */
|
||
while ((ch = getc(0)) == 0) /* bdos 6 does not wait, so we do */
|
||
;
|
||
if ((ch == '\r') || (ch == '\n') || (num++ > len)) {
|
||
/* not sure what the CR key actually is to bdos 6 & C/80 */
|
||
*s++ = '\0';
|
||
return; /* this way out */
|
||
}
|
||
if ((num % 2) == 0) putc('.',0); /* deception, illusion */
|
||
if ((num % 5) == 0) putc('.',0);
|
||
putc('.',0);
|
||
*s++ = ch;
|
||
}
|
||
|
||
} /* end: hide_input */
|
||
#endif
|
||
|
||
|
||
|
||
|
||
/*------------------------ kpro stuff -------------------------*/
|
||
|
||
#ifneed shadow_box
|
||
/* like box, but with horizontal & vertical displacement for shadow */
|
||
shadow_box(h,v,x1,y1,x2,y2) int h,v,x1,y1,x2,y2;
|
||
{
|
||
box(x1+h,y1+v,x2+h,y2+v); /* draw the shadow */
|
||
box(x1,y1,x2,y2); /* draw the box */
|
||
ldraw(x1+h,y1+v,x1,y1); /* draw the corners */
|
||
ldraw(x2+h,y2+v,x2,y2);
|
||
ldraw(x2+h,y1+v,x2,y1);
|
||
ldraw(x1+h,y2+v,x1,y2);
|
||
}
|
||
#endif
|
||
|
||
|
||
#ifneed box
|
||
/* parameters are topleft X,Y and bottomright X,Y
|
||
X ranges from 0 to 159, Y ranges from 0 to 99, top left is 0,0
|
||
*/
|
||
box(x1,y1,x2,y2) int x1,y1,x2,y2; {
|
||
ldraw(x1,y1,x1,y2);
|
||
ldraw(x1,y2,x2,y2); /* appears to draw the box anticlockwise */
|
||
ldraw(x2,y1,x2,y2);
|
||
ldraw(x1,y1,x2,y1);
|
||
}
|
||
#endif
|
||
|
||
|
||
|
||
#ifneed gotoxy
|
||
gotoxy (xpos,ypos) int xpos,ypos; { /* 0,0 is top left corner */
|
||
putscreen("\033=");
|
||
putc(ypos+' ',0);
|
||
putc(xpos+' ',0);
|
||
}
|
||
#endif
|
||
|
||
|
||
#ifneed beep
|
||
beep() { putc(7,0); } /* send bell character */
|
||
#endif
|
||
|
||
#ifneed home
|
||
home() { putc(30,0); } /* home cursor to top left */
|
||
#endif
|
||
|
||
#ifneed clr_screen
|
||
clr_screen() { putc(26,0); } /* home and erase screen */
|
||
#endif
|
||
|
||
|
||
#ifneed clr_lend
|
||
clr_lend() { putc(24,0); } /* clear to end of line */
|
||
#endif
|
||
|
||
#ifneed clr_send
|
||
clr_send() { putc(23,0); } /* clear to end of screen */
|
||
#endif
|
||
|
||
|
||
|
||
#ifneed rev_vid
|
||
rev_vid() { putscreen ("\033B0"); } /* reverse background */
|
||
#endif
|
||
|
||
#ifneed nor_vid
|
||
nor_vid() { putscreen ("\033C0"); }
|
||
#endif
|
||
|
||
|
||
|
||
#ifneed dim_vid
|
||
dim_vid() { putscreen ("\033B1"); } /* low intensity */
|
||
#endif
|
||
|
||
#ifneed bri_vid
|
||
bri_vid() { putscreen ("\033C1"); }
|
||
#endif
|
||
|
||
|
||
|
||
#ifneed on_blink
|
||
on_blink() { putscreen ("\033B2"); } /* blinking characters */
|
||
#endif
|
||
|
||
#ifneed off_blink
|
||
off_blink() { putscreen ("\033C2"); }
|
||
#endif
|
||
|
||
|
||
|
||
#ifneed ul_start
|
||
ul_start() { putscreen ("\033B3"); } /* underline */
|
||
#endif
|
||
|
||
#ifneed ul_stop
|
||
ul_stop() { putscreen ("\033C3"); }
|
||
#endif
|
||
|
||
|
||
#ifneed save_cursor
|
||
save_cursor() { putscreen ("\033B6"); } /* remember cursor position */
|
||
#endif
|
||
#ifneed retn_cursor
|
||
retn_cursor() { putscreen ("\033C6"); } /* return to remembered pos */
|
||
#endif
|
||
|
||
|
||
#ifneed on_status
|
||
on_status() { putscreen ("\033B7"); } /* status line preservation on */
|
||
#endif
|
||
#ifneed off_status
|
||
off_status() { putscreen ("\033C7"); }
|
||
#endif
|
||
|
||
|
||
#ifneed ins_line
|
||
ins_line() { /* insert text line */
|
||
putscreen("\033R");
|
||
}
|
||
#endif
|
||
#ifneed del_line
|
||
del_line() { /* delete text line */
|
||
putscreen("\033E");
|
||
}
|
||
#endif
|
||
|
||
|
||
#ifneed on_cursor
|
||
on_cursor() { putscreen ("\033B4"); } /* (in)visible cursor */
|
||
#endif
|
||
#ifneed off_cursor
|
||
off_cursor() { putscreen ("\033C4"); }
|
||
#endif
|
||
|
||
|
||
|
||
/* Video Mode ON/OFF: video WORD, 8 bit video if 15 and 7 are both high */
|
||
/* VM-ON 10000001 11111111 VM-OFF */
|
||
/* ^video ^x^video */
|
||
/* otherwise, video BYTE, high bit 7 interprets bits 0-6 as screen dots */
|
||
/* 11111111 */
|
||
/* ^video */
|
||
/* e.g., */
|
||
/* Non-VideoMode VideoMode */
|
||
/* xx 1 11:0 where % is 1 01:0 1 11:0 xx */
|
||
/* xx 3 11 2 the video 3 00 2 3 11 2 xx */
|
||
/* xx 5 11 4 flag bit, 5 00 4 5 11 4 xx */
|
||
/* x 7:%1 6 x is pixel 7:%0 6 7:%1 6 xx */
|
||
/* ^ ^ ^ */
|
||
/* to set the pixels, first do a gotoxy to character screen position */
|
||
/* this mode is faster than Pixel ON/OFF if values are drawn from table */
|
||
#ifneed vm_on
|
||
vm_on() { putscreen ("\033B5"); } /* video mode on */
|
||
#endif
|
||
#ifneed vm_off
|
||
vm_off() { putscreen ("\033C5"); }
|
||
#endif
|
||
|
||
|
||
#ifneed pixel
|
||
pixel(x,y) int x,y; { /* x <= 159, y <= 99 */
|
||
putscreen("\033*");
|
||
putc(y+' ',0); putc(x+' ',0);
|
||
}
|
||
#endif
|
||
|
||
#ifneed no_pixel
|
||
no_pixel(x,y) int x,y; { /* x <= 159, y <= 99 */
|
||
putscreen("\033 ");
|
||
putc(y+' ',0); putc(x+' ',0);
|
||
}
|
||
#endif
|
||
|
||
|
||
#ifneed ldraw
|
||
/* use x1 <= x2, y1 <= y2, order is significant (Kaypro bug?) */
|
||
ldraw(x1,y1,x2,y2) int x1,x2,y1,y2; { /* x <= 159, y <= 99 */
|
||
putscreen("\033L");
|
||
putc(y1+' ',0); putc(x1+' ',0);
|
||
putc(y2+' ',0); putc(x2+' ',0);
|
||
}
|
||
#endif
|
||
|
||
|
||
#ifneed lwipe
|
||
lwipe(x1,y1,x2,y2) int x1,x2,y1,y2; { /* x <= 159, y <= 99 */
|
||
putscreen("\033D");
|
||
putc(y1+' ',0); putc(x1+' ',0);
|
||
putc(y2+' ',0); putc(x2+' ',0);
|
||
}
|
||
#endif
|
||
|
||
|
||
#ifneed putscreen
|
||
putscreen(p) char *p; {
|
||
|
||
while (*p) putc(*p++,0);
|
||
|
||
} /* end: putscreen */
|
||
#endif
|
||
|
||
|
||
#ifneed puts
|
||
puts(p) char *p; {
|
||
|
||
while (*p) chrout(*p++);
|
||
|
||
} /* end: puts */
|
||
#endif
|
||
|
||
|
||
#ifneed chrout
|
||
chrout(c) char c; { /* SPECIAL FOR SCRIPT OPTION WITH LST: */
|
||
|
||
putc(c,0);
|
||
if ( MYscrtp ) putc(c,MYretnirp);
|
||
|
||
} /* end: chrout */
|
||
#endif
|
||
|
||
/* end: MYLIB.C */
|
||
|
||
|