delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1992/07/15/14:02:45

Date: Wed, 15 Jul 92 19:24:36 +0100
From: buers AT dg1 DOT chemie DOT uni-konstanz DOT de (Dieter Buerssner)
To: djgpp AT sun DOT soe DOT clarkson DOT edu
Cc: dj AT ctron DOT com
Subject: fixed gppconio.c

I had some problems with the conio-library in djgpp. The VIDADDR macro
did not work. Also characters with the high bit set (like the German
"Umlaute") did not work. I also tried to speed up the functions a little
bit. The original version was much slower than the corresponding 
Turbo-C version. Now they are comparable in speed.

Here is my version. I tried some programs, which were originally written
for Turbo-C, they all work now without modification of the sources (exept
for the call of gppconio_init and the different name of the header file).

The context diff is larger than the whole file, therefore I'm sending the 
file here. Try it out. Comments welcome.

	Dieter

/**********************************************************************
 *  
 *  NAME:           gppconio.c
 *  
 *  DESCRIPTION:    simulate Borland text video funcs for GNU C++
 *  
 *  copyright (c) 1991 J. Alan Eldridge
 * 
 *  M O D I F I C A T I O N   H I S T O R Y
 *
 *  when        who                 what
 *  -------------------------------------------------------------------
 *  10/27/91    J. Alan Eldridge    created
 *  01/06/92    D. Buerssner        make it work with extended characters
 * (buers AT dg1 DOT chemie DOT uni-konstanz DOT de) speed-up of cputs
 *                                  some missing brackets in VIDADDR
 *                                  don't need scrollwindow anymore
 *********************************************************************/

#include    <stdlib.h>
#include    <stdarg.h>

#include    <pc.h>
#include    "gppconio.h"

#define DBGGTINFO   0

static struct text_info txinfo;

#define VIDADDR(r,c) (ScreenPrimary + ((r) * txinfo.screenwidth) + (c))

int puttext(int c, int r, int c2, int r2, void *buf)
{
  int     c0;
  short   *pvch = (short *)buf;
  
  r--, r2--, c--, c2--;
  for (c0 = c; r <= r2; r++) 
    for (c = c0; c <= c2; c++)
      *VIDADDR(r,c) = *pvch++;
  return 1;
}

int gettext(int c, int r, int c2, int r2, void *buf)
{
  int     c0;
  short   *pvch = (short *)buf;
  
  r--, r2--, c--, c2--;
  for (c0 = c; r <= r2; r++) {
    for (c = c0; c <= c2; c++)
      *pvch++ = *VIDADDR(r,c);
  }
  return 1;
}
        
void gotoxy(int col, int row)
{
  ScreenSetCursor(row + txinfo.wintop - 2, col + txinfo.winleft - 2);
}

int wherex(void)
{
  int row, col;
  
  ScreenGetCursor(&row, &col);
  
  return col - txinfo.winleft + 2;
}
    
int wherey(void)
{
  int row, col;
  
  ScreenGetCursor(&row, &col);
  
  return row - txinfo.wintop + 2;
}
    
void textmode(int unused_mode)
{
}

void textattr(int attr)
{
  txinfo.attribute=ScreenAttrib = (unsigned char)attr;
}

void textcolor(int color)
{
  ScreenAttrib &= 0xf0;
  txinfo.attribute=(ScreenAttrib |= (color & 0x0f));
}

void textbackground(int color)
{
  ScreenAttrib &= 0x0f;
  txinfo.attribute=(ScreenAttrib |= ((color & 0x0f) << 4));
}

void highvideo(void)
{
  txinfo.attribute=(ScreenAttrib |= 0x08);
}

void lowvideo(void)
{
  txinfo.attribute=(ScreenAttrib &= 0x07);
}

void normvideo(void)
{
  txinfo.attribute = ScreenAttrib = txinfo.normattr;
}

void _setcursortype(int unused_type)
{
}

static void getwincursor(int *row, int *col)
{
  ScreenGetCursor(row, col);
  *col += txinfo.winleft - 1;
  *row += txinfo.wintop - 1;
}

void clreol(void)
{
  short   image[ 256 ];
  short   val = ' ' | (ScreenAttrib << 8);
  int     c, row, col, ncols;
  
  getwincursor(&row, &col);
  ncols = txinfo.winright - col;
  
  for (c = 0; c < ncols; c++)
    image[ c ] = val;
  
  puttext(col + 1, row + 1, txinfo.winright, row + 1, image);
}

static void fillrow(int row, int left, int right, int fill)
{
  int col;
  
  for (col = left; col <= right; col++)
    *VIDADDR(row, col) = fill;
}

void clrscr(void)
{
  int row, col;
  int c =  ' ' | (ScreenAttrib << 8);
  for (row=txinfo.wintop-1; row < txinfo.winbottom; row++)
    for (col=txinfo.winleft-1; col < txinfo.winright; col++)
      *VIDADDR(row,col) = c;
}

int putch(int c)
{
  int     row, col;
  
  ScreenGetCursor(&row, &col);
  
  /*  first, handle the character */
  if (c == '\n')
    {
      row++;
    }
  else if (c == '\r')
    {
      col = txinfo.winleft - 1;
    }
  else {
    short   val = c | (ScreenAttrib << 8);
    /* puttext(col + 1, row + 1, col + 1, row + 1, &val); */
    *VIDADDR(row,col) = val;
    col++;
  }
  
  /* now, readjust the window     */
  
  if (col >= txinfo.winright) {
    col = txinfo.winleft - 1;
    row++;
  }
  
  if (row >= txinfo.winbottom) {
    /* scrollwin(0, txinfo.winbottom - txinfo.wintop, 1); */
    ScreenSetCursor(txinfo.wintop-1,0);
    delline();
    row--;
  }
  
  ScreenSetCursor(row, col);
  return c;
}

int getche(void)
{
  int c = getch();
  
  if (!c || c == 0xE0)
    c = getch();
  
  return putch(c);
}

void insline(void)
{
  int row, col, left, right, nbytes, bot, fill;
  ScreenGetCursor(&row, &col);
  left = txinfo.winleft - 1;
  right = txinfo.winright - 1;
  nbytes = (right-left+1)*2;
  bot = txinfo.winbottom-1;
  fill = ' ' | (ScreenAttrib << 8);
  while(bot > row+1)
    {
      memcpy(VIDADDR(bot,left), VIDADDR(bot-1,left), nbytes);
      bot--;
    }
  if (row < txinfo.winbottom -1)
    {
      fillrow(row+1,left,right,fill);
    }
}


void delline(void)
{
  int row, col, left, right, nbytes, bot, fill;
  ScreenGetCursor(&row, &col);
  left = txinfo.winleft - 1;
  right = txinfo.winright - 1;
  nbytes = (right-left+1)*2;
  bot = txinfo.winbottom-1;
  fill = ' ' | (ScreenAttrib << 8);
  while(row < bot)
    {
      memcpy(VIDADDR(row,left), VIDADDR(row+1,left), nbytes);
      row++;
    }
  fillrow(bot,left,right,fill);
}


void window(int left, int top, int right, int bottom)
{
  if (top < 1 || left < 1 || right > txinfo.screenwidth ||
      bottom > txinfo.screenheight)
    return;
  
  txinfo.wintop = top;
  txinfo.winleft = left;
  txinfo.winright = right;
  txinfo.winbottom = bottom;
}


int cputs(const char *s)
{
  int     row, col,c;
  const unsigned char *ss = (const unsigned char *)s;
  short *viaddr;
  short sa = ScreenAttrib << 8;
  ScreenGetCursor(&row, &col);
  viaddr = (short *)VIDADDR(row,col);
  /* 
   * Instead of just calling putch; we do everything by hand here,
   * This is much faster. We don't move the cursor after each character,
   * only after the whole string is written, because ScreenSetCursor
   * needs to long. You won't recognize the differenc.
   */
  while (c = *ss++)
    {
      /*  first, handle the character */
      if (c == '\n')
	{
	  row++;
	  viaddr += txinfo.screenwidth;
	}
      else if (c == '\r')
	{
	  col = txinfo.winleft - 1;
	  viaddr = (short *)VIDADDR(row,col);
	}
      else {
	*viaddr++ = c | sa;
	col++;
      }
      
      /* now, readjust the window     */
      
      if (col >= txinfo.winright) {
	col = txinfo.winleft - 1;
	row++;
	viaddr = (short *)VIDADDR(row,col);
      }
      
      if (row >= txinfo.winbottom) {
	ScreenSetCursor(txinfo.wintop-1,0); /* goto first line in window */
	delline();                          /* and delete it */
	row--;
	viaddr -= txinfo.screenwidth;
      }
    }
  
  ScreenSetCursor(row, col);
  return(*(--ss));
}


int cprintf(const char *fmt, ...)
{
  int     cnt;
  char    buf[ 2048 ];
  va_list ap;
  
  va_start(ap, fmt);
  cnt = vsprintf(buf, fmt, ap);
  va_end(ap);
  
  cputs(buf);
  return cnt;
}

int movetext(int left, int top, int right, int bottom, int dleft, int dtop)
{
  char    *buf = malloc((right - left + 1) * (bottom - top + 1) * 2);
  
  if (!buf)
    return 0;
  
  gettext(left, top, right, bottom, buf);
  puttext(dleft, dtop, dleft + right - left, dtop + bottom - top, buf);
  free(buf);
  return 1;
}

static void _gettextinfo(struct text_info *t)
{
  int row, col;
  
  t->winleft = t->wintop = 1;
  t->winright = t->screenwidth = ScreenCols();
  t->winbottom = t->screenheight = ScreenRows();
  t->normattr = 0x07;
  t->currmode = ScreenMode();
  ScreenGetCursor(&row, &col);
  t->curx = col;
  t->cury = row;
  
#if DBGGTINFO
  printf("left=%2d,right=%2d,top=%2d,bottom=%2d\n",t->winleft,
	 t->winright,t->wintop,t->winbottom);
  printf("scrht=%2d,scrwid=%2d,norm=%2x,mode=%2d,x=%2d,y=%2d\n",
	 t->screenheight, t->screenwidth, t->normattr, t->currmode,
	 t->curx, t->cury);
#endif
}

void gettextinfo(struct text_info *t)
{
  *t = txinfo; 
#if DBGGTINFO
  printf("left=%2d,right=%2d,top=%2d,bottom=%2d\n",t->winleft,
	 t->winright,t->wintop,t->winbottom);
  printf("scrht=%2d,scrwid=%2d,norm=%2x,mode=%2d,x=%2d,y=%2d\n",
	 t->screenheight, t->screenwidth, t->normattr, t->currmode,
	 t->curx, t->cury);
#endif
}

extern int _gppconio_init;

void gppconio_init(void)
{
  _gettextinfo(&txinfo);
  _gppconio_init = 1;
}




- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019