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

📄 cgc.cpp

📁 这是一个C++编程文档
💻 CPP
字号:
/* -------------------------------------------------------------------- */
/* Mouse++ Version 4.0            cgc.cpp              Revised 10/05/92 */
/*                                                                      */
/* General mouse class for Turbo C++/Borland C++.                       */
/* Copyright 1991, 1992 by Carl W. Moreland                             */
/* -------------------------------------------------------------------- */
/* This module contains the ColorGraphicsCursor routines for displaying */
/* the color images. It is written entirely in C++ (no assembly) to de- */
/* monstrate exactly how the image is written to video memory and how   */
/* the cursor is masked at the screen edges.                            */
/* -------------------------------------------------------------------- */

#include <dos.h>
#include <mem.h>
#include "mouse.h"

const int screenWidth  = 640;		// VGA/EGA = 640
const int screenHeight = 350;           // VGA = 480, EGA = 350

int            ColorGraphicsCursor::x = -1;
int            ColorGraphicsCursor::y = -1;
void*          ColorGraphicsCursor::tmpImage = NULL;
int            ColorGraphicsCursor::tmpImageSize = 0;
unsigned char* ColorGraphicsCursor::videoAddress;
int            ColorGraphicsCursor::videoLeftMask;
int            ColorGraphicsCursor::videoRightMask;
int            ColorGraphicsCursor::screenLeftMask;
int            ColorGraphicsCursor::screenRightMask;
unsigned char  ColorGraphicsCursor::xStart;
unsigned char  ColorGraphicsCursor::yStart;
unsigned char  ColorGraphicsCursor::xEnd;
unsigned char  ColorGraphicsCursor::yEnd;
unsigned char  ColorGraphicsCursor::iWidth;
unsigned char  ColorGraphicsCursor::iHeight;


ColorGraphicsCursor::ColorGraphicsCursor(unsigned char hotx,
                                         unsigned char hoty,
                                         unsigned char image[],
                                         unsigned char width,
                                         unsigned char height)
{
  this->hotx = hotx;
  this->hoty = hoty;
  cWidth     = width;
  cHeight    = height;
  cBytes     = width/8 + (width%8 ? 1 : 0);

  int nBytes = cHeight * cBytes;	// total # of bytes in each plane

  cMask  = (void *)image;		// screen mask is the first plane
  cImage = (void *)(image + nBytes);	// cursor starts with second plane

  for(int i = 0; i < nBytes; i++)	// invert the screen mask
    image[i] = ~image[i];

  if(5*nBytes > tmpImageSize)		// resize the tmp buffer if
  {					//  necessary
    if(tmpImage)
      delete tmpImage;
    tmpImage = new unsigned char[5*nBytes];
    tmpImageSize = 5*nBytes;
  }
}

void ColorGraphicsCursor::VideoRead(void)
{
  static unsigned char *image, *address;
  static int new_x, new_y;
  register int i, j, k;

  xStart = 0;
  xEnd   = cBytes;
  yStart = 0;
  yEnd   = cHeight;
  new_x  = x - hotx;			// left edge of the image
  new_y  = y - hoty;			// top edge of the image

  videoLeftMask  = 0xFF >> (new_x&7);
  videoRightMask = ~videoLeftMask;

  if(new_x < 0)				// if the left edge < 0
  {
    xStart = -(new_x>>3);		// shift xStart n bytes
    new_x  = 0;
  }                                 	// if the right edge > screenWidth-1
  else if(new_x+(cBytes<<3) > screenWidth-1)
    xEnd = (screenWidth-new_x-1)>>3;	// shift xEnd n bytes

  if(new_y < 0)				// if the top edge < 0
  {
    yStart = -new_y+1;			// shift yStart n rows
    new_y  = 0;
  }                                     // if the bottom edge>screenHeight-1
  else if(new_y+cHeight > screenHeight-1)
    yEnd = screenHeight-new_y;		// shift yEnd n rows

  iWidth  = xEnd - xStart;		// width in bytes
  iHeight = yEnd - yStart;		// height in bytes

  videoAddress = (unsigned char*)MK_FP(0xA000, (new_y*80 + (new_x>>3)));

  image = (unsigned char *)tmpImage;

  outp(0x3CE, 5);			// select read mode 0
  outp(0x3CF, 0);

  for(i = 0; i < 4; i++)		// for each bitplane...
  {
    address = videoAddress;
    outp(0x3CE, 4);			// select the bit plane...
    outp(0x3CF, i);

    for(j = yStart; j < yEnd; j++)	// for each cursor line...
    {
      for(k = xStart; k <= xEnd; k++)	// for each byte...
      {
        *image = *address;		// save the byte
        image++;
        address++;
      }
      address += 79-iWidth;		// go to the next line
    }
  }
}

void ColorGraphicsCursor::VideoWrite(void)
{
  static unsigned char *image, *address, vByte=0;
  register int i, j, k;

  image = (unsigned char *)tmpImage;

  outp(0x3CE, 5);			// select write mode 0
  outp(0x3CF, 0);
  outp(0x3CE, 3);
  outp(0x3CF, 0);

  for(i=0; i<4; i++)			// for each bitplane...
  {
    address = videoAddress;
    outp(0x3C4, 2);			// select the bit plane...
    outp(0x3C5, 1<<i);
    outp(0x3CE, 8);

    for(j = yStart; j < yEnd; j++)	// for each cursor line...
    {
      for(k = xStart; k <= xEnd; k++)	// for each byte...
      {
        vByte = *address;

        if(k == 0)
        {
          outp(0x3CF, videoLeftMask);	// mask off the left byte
        }
        else if(k == cBytes)
        {
          outp(0x3CF, videoRightMask);	// mask off the right byte
        }
        else
        {
          outp(0x3CF, 0xFF);		// middle bytes don't need masking
        }

        *address = *image;		// write the byte
        image++;
        address++;
      }
      address += 79-iWidth;		// next cursor line
    }
  }
  outp(0x3CF, 0xFF);
}

void ColorGraphicsCursor::CursorWrite(void)
{
  static unsigned char *image, *address, *base, *base0;
  static unsigned char vByte, mask, rShift, lShift;
  register int k, j, i;

  image = (unsigned char *)cImage;	// set image to the start of the

  base0 = (unsigned char *)cMask;	// base0 is the screen mask
  for(k=0; k<cBytes; k++)		// clip any part that's < yStart
    base0 += yStart;

  rShift = (x-hotx)&7;
  lShift = 8-((x-hotx)&7);

  outp(0x3CE, 5);			// select write mode 0
  outp(0x3CF, 0);
  outp(0x3CE, 3);
  outp(0x3CF, 0);

  for(i=0; i<4; i++)			// for each bit plane...
  {
    address = videoAddress;
    outp(0x3C4, 2);			// select the bit plane...
    outp(0x3C5, 1<<i);
    outp(0x3CE, 8);

    for(j=0; j<cBytes; j++)		// clip any part that's < yStart
      image += yStart;
    base = base0;

    for(j = yStart; j < yEnd; j++)	// for each cursor line...
    {
      image += xStart;
      base  += xStart;

      for(k = xStart; k <= xEnd; k++)	// for each byte...
      {
        vByte = *address;

        if(k == 0)
        {
          mask  = *base  >> rShift;	// get the shift mask
          vByte = *image >> rShift;	// shift the image byte
        }
        else if(k == cBytes)
        {
          mask  = *(base-1)  << lShift;
          vByte = *(image-1) << lShift;
        }
        else
        {
          mask  =  (*(base-1) << lShift) |  (*base >> rShift);
          vByte = (*(image-1) << lShift) | (*image >> rShift);
        }

        outp(0x3CF, mask);		// mask off the bits
        *address = vByte;		// write the byte to video
        address++;			// next video byte
        image++;			// next image byte
        base++;				// next mask byte
      }
      address += 79-iWidth;		// next cursor line
      image += cBytes-xEnd-1;		// next image line
      base  += cBytes-xEnd-1;		// next mask line
    }
    for(j=0; j<cBytes; j++)		// next bit plane in image
      image += cHeight-yEnd;
  }
  outp(0x3CF, 0xFF);
}

⌨️ 快捷键说明

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