home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C++ Games Programming
/
CPPGAMES.ISO
/
mt
/
writscrn.c
< prev
Wrap
C/C++ Source or Header
|
1989-01-12
|
7KB
|
228 lines
/* writscrn.c utilities to write chars to any position on screen */
/* uses hi res cursor functions in linedraw.c */
/* `MIDI Sequencing In C', Jim Conger, M&T Books, 1989 */
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include "screenf.h"
#include "standard.h"
/* Moves highlighted cursor block based on arrow key input. first is the */
/* menu array element to start on, last is the last (usually the number of */
/* array elements in the the menu deffinition - 1). */
/* Menu definition is in scrnarray[] (see MTSCREEN.H) */
/* Returns element no selected, -2 for ESC, -3 for help (?), -1 on error. */
int
movescrn(int vidmode, struct selement scrnarray[], int first, int last,
int normal, int hilit)
{
int c, k, i, oldk, curskey;
if (first < 0)
first = 0;
i = k = first;
to_new_csr(vidmode, scrnarray, k, -1, normal, hilit);
while(1){
oldk = k;
while(kbhit()) /* clear keyboard buffer */
getch();
while(!kbhit()) /* wait for new keypress */
;
if(c = getch()){ /* check for cursor keypress code 0 */
curskey = 0;
}
else{
curskey = 1;
c = getch(); /* note null char and get next */
}
if(!curskey){ /* advance to first matching char */
switch(c){
case BACKSP:
k = scrnarray[k].nleft;
break;
case TAB:
k = scrnarray[k].nright;
break;
case ESC:
return(-2);
case CR:
case '+':
to_new_csr(vidmode, scrnarray, k, -1, normal, hilit);
return(k);
}
if (i >= last || i <= 0)
i = 0;
else
i++;
for(; i <= last; i++){ /* see if letter matches command */
if(toupper(c) == toupper(*(scrnarray[i].content))){
k = i;
break;
}
}
if (k != i && oldk != 0){ /* if no match, but started after */
for(i = 0; i <= last; i++){ /* first element - try again */
if(toupper(c) == toupper(*(scrnarray[i].content))){
k = i;
break;
}
}
}
}
else{ /* must be cursor key */
switch(c){
case KUP:
k = scrnarray[k].nup;
break;
case KDOWN:
k = scrnarray[k].ndown;
break;
case KLEFT:
k = scrnarray[k].nleft;
break;
case KRIGHT:
k = scrnarray[k].nright;
break;
case KHOME:
case KPGUP:
k = 0;
break;
case KEND:
case KPGDN:
k = last;
break;
}
}
to_new_csr(vidmode, scrnarray, k, oldk, normal, hilit);
}
return(k);
}
/* Move highlight to new active menu item. Uses vimode (video mode) to */
/* determine if in graphics or character mode. In graphics modes the */
/* string is underlined. In char. modes the string is switched from */
/* normal to hilit video attribute. k is scrnarray[] element number. */
/* oldk is last item highlighted - now needs to be unhighlighted. A -1 */
/* value for oldk skips the unhighlighting step (first time on menu). */
void
to_new_csr(int vidmode, struct selement scrnarray[], int k, int oldk,
int normal, int hilit)
{
if(vidmode < 4 || vidmode == 7){ /* char mode */
if (oldk != -1){ /* if not first time initialization */
writeword(scrnarray[oldk].content, scrnarray[oldk].xpos,
scrnarray[oldk].ypos, normal);
}
writeword(scrnarray[k].content, scrnarray[k].xpos,
scrnarray[k].ypos, hilit);
}
else{ /* graphics mode */
if (oldk != -1){ /* if not first time initialization */
wordul(vidmode, scrnarray[oldk].content, scrnarray[oldk].xpos,
scrnarray[oldk].ypos, hilit & 0x000F);
}
wordul(vidmode, scrnarray[k].content, scrnarray[k].xpos,
scrnarray[k].ypos, hilit & 0x000F);
}
}
/* Put an error message on screen, wait for keypress, then clear line. */
/* String s is written on line lineno with hilit attribute. After the */
/* user hits a key the line is cleared using normal attribute. */
void
writerr(char *s, int lineno, int normal, int hilit)
{
char c, str[SCRNWIDE + 1];
while(kbhit())
getch();
clearline(lineno, normal);
strcpy(str, s);
strcat(str, " [Hit a key]");
writeword(str, 1, lineno, hilit);
while(!kbhit()) /* wait for keypress */
;
clearline(lineno, normal);
}
/* Writes the menu item strings on the screen in color attrib. Starts */
/* on scrnarray[] element first, goes to last. */
/* bios screen write (slow) version - works in all video modes. */
void
initscrn(struct selement scrnarray[], int first, int last, int attrib)
{
int k;
for(k = first; k <= last; k++){
writeword(scrnarray[k].content, scrnarray[k].xpos, scrnarray[k].ypos,
attrib);
}
}
/* direct video (fast) version of initscrn - only for char modes. */
void
finitscrn(struct selement scrnarray[], int first, int last, int attrib,
int mode)
{
int k;
for(k = first; k <= last; k++){
fwriteword(scrnarray[k].content, scrnarray[k].xpos, scrnarray[k].ypos,
attrib, mode);
}
}
/* Write string to x,y on screen, writes to screen memory directly */
/* String is written with color attrib. */
void
fwriteword(char *string, int x, int y, int attrib, int mode)
{
unsigned int offset;
x--; /* To conform with library convention of having */
y--; /* the first row and column position be 1,1 not 0,0. */
offset = (x * 2) + (y * SCRNWIDE * 2);
while(*string != '\n' && *string){
if (mode <= 6){
*(char far *)(CVIDMEM + (offset++)) = *string++;
*(char far *)(CVIDMEM + (offset++)) = attrib;
}
else if (mode == 7){
*(char far *)(HVIDMEM + (offset++)) = *string++;
*(char far *)(HVIDMEM + (offset++)) = attrib;
}
else {
*(char far *)(EVIDMEM + (offset++)) = *string++;
*(char far *)(EVIDMEM + (offset++)) = attrib;
}
}
}
void /* put an integer value on screen at x,y */
write_int(int value, int x, int y, int attrib)
{
char buf[10];
itoa(value, buf, 10);
writeword(buf, x, y, attrib);
}