⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cgagraf.c

📁 MSC TURBO-C图形库
💻 C
字号:
/*
 * grafix --- cgagraf.c
 *
 * CGA graphics driver
 *
 * Written 4/87 by Scott Snyder (ssnyder@romeo.caltech.edu or @citromeo.bitnet)
 *
 */

#include <dos.h>
#include "macros.h"
#include "grafsys.h"

/* parameters that don't depend on graphics mode */

#define int_cga 16
#define cga_setmode 0
#define cga_setpal 11
#define mde_80bw 2
#define mde_80co 3
#define mde_320 4
#define mde_640 6
#define cid_back 0
#define cid_pal 1

#define g_linsiz 80
#define g_oddoff 0x2000
#define g_allmask 0xff
#define g_bufsiz 0x4000
#define g_screenaddr (g_obj far *)0xb8000000
#define g_charbase (g_obj far *)0xf000fa6e

/* parameters that DO depend on graphics mode */

unsigned g_mode;

/* these must be near so the .asm routines can get to them */

unsigned NEAR g_pixbyte;
unsigned NEAR g_bitpix;
g_obj NEAR g_colormask;
g_obj NEAR g_hicolormask;
g_obj NEAR g_cmask_tbl[8];

/* utility macros */

#define swap(a, b) {int _tmp; _tmp=a; a=b; b=_tmp;}
#define trimcolor(c) c &= g_colormask
#define get_cmask(c) g_cmask_tbl[c&g_colormask]

/* plot a point */
#define plot(ptr, mask, cmask) \
  *ptr = g_xor ? ( *ptr          ^ (cmask & mask)) \
               : ((*ptr & ~mask) | (cmask & mask))

/* move one to right */
#define bumpx(ptr,mask) 	    \
  if ((mask >>= g_bitpix) == 0) {   \
    mask = g_hicolormask;           \
    ptr++;                          \
  }

/* move one line */
#define bumpy(ptr,ydir)         \
  if (ptr >= (g_obj far *)(g_drawbuf+g_oddoff)) { \
    ptr-=g_oddoff;              \
    if (!ydir)                  \
      ptr+=g_linsiz;            \
  }                             \
  else {                        \
    ptr+=g_oddoff;              \
    if (ydir)                   \
      ptr-=g_linsiz;            \
  }

/*****************************************************************************
 *                            internal utilities                             *
 *****************************************************************************/

/* calculate byte and bit offsets in the graphics buffer for a point */

STATIC void goffs(x, y, offs, pix)
unsigned x, y, *offs, *pix;
{
  int y0;

  y0 = y/2;
  *offs = y0 * g_linsiz + x/g_pixbyte + ((y0*2 != y) ? g_oddoff : 0);
  *pix = g_pixbyte - 1 - x%g_pixbyte;
}

/* fill a mask with the given color value */

g_obj make_cmask(c)
unsigned c;
{
  int i;
  g_obj mask = 0;

  trimcolor(c);
  for (i=0; i<g_pixbyte; i++)
    mask = (mask<<g_bitpix) | c;
  return (mask);
}

/****************************************************************************
 *                     externally callable functions                        *
 ****************************************************************************/

/* fill a region with the specified color */

#ifdef __TURBOC__
# pragma warn -rch
#endif
void CGA_regfill(x1, y1, x2, y2, c)
unsigned x1, y1, x2, y2, c;
{
  unsigned offs1, offs2, pix1, pix2, y;
  int wholeobjs;
  g_obj far *ptr1, far *ptr2;
  g_obj cmask, begmask, endmask, mask;

  if (y2 < y1) swap(y1, y2);
  if (x2 < x1) swap(x1, x2);

  goffs(x1, y1, &offs1, &pix1);
  goffs(x2, y1, &offs2, &pix2);
  wholeobjs = offs2 - offs1 - 1;
  ptr1 = g_drawbuf + offs1;
  ptr2 = g_drawbuf + offs2;

  cmask = get_cmask(c);
  begmask = g_allmask >> (g_pixbyte - 1 - pix1)*g_bitpix;
  endmask = g_allmask << pix2*g_bitpix;

  if (wholeobjs < 0) {
    mask = begmask & endmask;
    cmask &= mask;
    for (y=y1; y<=y2; y++) {
      *ptr1 = (*ptr1 & ~mask) | cmask;
      bumpy(ptr1, 0);
    }
  }
  else {
    for (y=y1; y<=y2; y++) {
      *ptr1 = (*ptr1 & ~begmask) | (cmask & begmask);
      g_fmemset(ptr1+1, cmask, wholeobjs);
      *ptr2 = (*ptr2 & ~endmask) | (cmask & endmask);
      bumpy(ptr1, 0);
      ptr2 = ptr1 + wholeobjs + 1;
    }
  }
}
#ifdef __TURBOC__
# pragma warn .rch
#endif

/* fill the entire buffer with a color fast */

void CGA_clearall(c)
unsigned c;
{
  g_fmemset(g_drawbuf, get_cmask(c), g_bufsiz);
}

/* make the drawing buffer visible */

void CGA_show()
{
  g_fmemcpy(g_physbuf, g_drawbuf, g_bufsiz);
}

/* set the background color */

void CGA_setback(c)
unsigned c;
{
  union REGS inregs, outregs;

  if (g_mode == CGA_320) {
    inregs.h.ah = cga_setpal;
    inregs.h.bh = cid_back;
    inregs.h.bl = c;
    int86(int_cga, &inregs, &outregs);
  }
}

/* set the color pallette */

void CGA_setpal(p, v)	/* pallette register number is ignored here */
unsigned p, v;
{
  union REGS inregs, outregs;

  inregs.h.ah = cga_setpal;
  if (g_mode == 2) {
    inregs.h.bh = cid_pal;
    inregs.h.bl = p;
  }
  else {
    inregs.h.bh = cid_back;
    inregs.h.bl = v;
  }
  int86(int_cga, &inregs, &outregs);
}

/* turn on graphics mode. mode=1 is 640, mode=2 is 320 */

void CGA_gopen(mode)
unsigned mode;
{
  union REGS inregs, outregs;
  unsigned i;

  g_mode = mode;
  inregs.h.ah = cga_setmode;
  inregs.h.al = (mode == CGA_640) ? mde_640 : mde_320;
  int86(int_cga, &inregs, &outregs);
  g_physbuf = g_screenaddr;
#if defined(__TURBOC__)
  g_virtbuf = (g_obj far *)MK_FP(g_bufseg(), 0);
#else
  FP_SEG(g_virtbuf) = g_bufseg();
  FP_OFF(g_virtbuf) = 0;
#endif

  /* set up mode-dependent parameters */

  if (mode == 1) {
    g_xsize = 640;
    g_ysize = 200;
    g_bitpix = 1;
    g_aspect = 0.42;
  }
  else {
    g_xsize = 320;
    g_ysize = 200;
    g_bitpix = 2;
    g_aspect = 0.85;
  }
  g_pixbyte = 8/g_bitpix;
  g_xchsize = g_xsize/8;
  g_ychsize = g_ysize/8;
  g_colormask = (1<<g_bitpix) - 1;
  g_hicolormask = g_colormask << (g_pixbyte-1)*g_bitpix;
  g_colormax = g_colormask;
  g_pages = 1;
  g_curpage = 0;

  for (i=0; i<=g_colormask; i++)
    g_cmask_tbl[i] = make_cmask(i);
}

/* turn off graphics mode */

void CGA_gclose()
{
  union REGS inregs, outregs;

  inregs.h.ah = cga_setmode;
  inregs.h.al = mde_80co;
  int86(int_cga, &inregs, &outregs);
}

/* plot a point */

/* This fine piece of code has now been supplanted by a weenie hunk
   of assembly.....

void CGA_point(x1,y1,c)
unsigned x1,y1,c;
{
  long p;
  unsigned pixoff, offs;
  g_obj far *ptr;
  g_obj mask, cmask;
 
  goffs(x1, y1, &offs, &pixoff);
  ptr = g_drawbuf + offs;
  cmask = get_cmask(c);
  mask = g_colormask << pixoff*g_bitpix;
  plot(ptr, mask, cmask);	/* plot pt. *
}
*/

/* draw a line... */

void CGA_line(x1,y1,x2,y2,c)
unsigned x1,y1,x2,y2,c;
{
  unsigned pixoff, offs;
  g_obj far *ptr;
  int delx,dely;
  int xyswap=0;
  int ydir=0;
  int i,ydelx;
  g_obj mask, cmask;
 
  if (x1 > x2) { 		/* sort into left-right order */
    register int tmp;
    tmp=x1; x1=x2; x2=tmp;
    tmp=y1; y1=y2; y2=tmp;
  }
  goffs(x1, y1, &offs, &pixoff);
  ptr = g_drawbuf+offs;
  cmask = get_cmask(c);
  mask = g_colormask << pixoff*g_bitpix;
  plot(ptr, mask, cmask);	/* plot pt. */
  if (x1==x2 && y1==y2)		/* handle 1 pt. correctly */
    return;
  delx=x2-x1;
  dely=y2-y1;
  if (dely < 0)	{		/* handle lines from up to down */
    ydir=1;
    dely=-dely;
  }
  if (abs(dely) > delx) {	/* handle slopes > 1 */
    register int tmp;
    tmp=x1;   x1=y1;     y1=tmp;
    tmp=x2;   x2=y2;     y2=tmp;
    tmp=delx; delx=dely; dely=tmp;
    xyswap=1;
  }
  ydelx=0;
  for (i=1; i<=delx; i++) {
    if ((ydelx+=dely) >= delx) {
      bumpx(ptr, mask);		/* bump both x & y */
      bumpy(ptr, ydir);
      ydelx-=delx;
    }
    else
      if (xyswap)		/* bump x only */
        bumpy(ptr, ydir)
      else
        bumpx(ptr, mask);
    plot(ptr, mask, cmask);	/* plot point, go around again */
  }
}

/* print a character. this is really kind of cheap, and can/should
   be expanded later... */

#ifdef __TURBOC__
# pragma warn -par /* TC */
# pragma warn -rch
#endif
void CGA_writech(row, col, ch, c, page)
unsigned row, col, c;
char ch;
int page;
{
  unsigned x, y, pixoff, offs;
  g_obj cmask, chdat, gdat;
  g_obj far *ptr, far *pptr, far *chpt;
  int i, j, k;

  x = col*8;			/* character is 8 X 8 */
  y = row*8;
  if (x >= g_xsize || y >= g_ysize)
    return;
  trimcolor(c);
  cmask = get_cmask(c);
  goffs(x, y, &offs, &pixoff);	/* pixoff should be 0 */
  ptr = g_drawbuf + offs;
  chpt = g_charbase + 8*ch;	/* pointer to character data */
  for (i=0; i<8; i++) {		/* loop for each line        */
    chdat = *chpt++;		/* get character data        */
    if (g_bitpix == 1)
      *ptr = chdat & cmask;
    else {
      pptr = ptr;
      for (j=0; j<g_bitpix; j++) { /* g_bitpix is the # of bytes per ch */
        gdat = 0;
        for (k=0; k<g_pixbyte; k++) {
          gdat = (gdat << g_bitpix) + (chdat&0x80 ? c : 0);
          chdat <<= 1;
        }
        *pptr++ = gdat;
      }
    }
    bumpy(ptr, 0);
  }
}
#ifdef __TURBOC__
# pragma warn .par /* TC */
# pragma warn .rch
#endif

/* these two thingamabobs don't do anything */

#ifdef __TURBOC__
# pragma warn -par /* TC */
#endif
void CGA_point_set(c)
unsigned c;
{
}
#ifdef __TURBOC__
# pragma warn .par /* TC */
#endif

void CGA_point_res()
{
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -