vgavideo.c

来自「一个类似windows」· C语言 代码 · 共 1,029 行 · 第 1/2 页

C
1,029
字号
  LONG x2 = x + w;
  LONG y2 = y + h;
  ULONG offset;
  UCHAR a;

  for (i = x; i < x2; i++)
    {
      pb = opb;
      offset = xconv[i] + y80[y];

      WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08);       // set the mask
      WRITE_PORT_UCHAR((PUCHAR)GRA_D, maskbit[i]);

      if (StartMod == ((i - x) % 2))
	{
	  for (j = y; j < y2; j++)
	    {
	      a = READ_REGISTER_UCHAR(vidmem + offset);
	      WRITE_REGISTER_UCHAR(vidmem + offset, (*pb & 0xf0) >> 4);
	      offset += 80;
	      pb += Source_lDelta;
	    }
	}
      else
	{
	  for (j = y; j < y2; j++)
	    {
	      a = READ_REGISTER_UCHAR(vidmem + offset);
	      WRITE_REGISTER_UCHAR(vidmem + offset, *pb & 0x0f);
	      offset += 80;
	      pb += Source_lDelta;
	    }
	}

      if (StartMod != ((i - x) % 2))
	{
	  opb++;
	}
    }
}


/* DIB blt to the VGA. */
void DIB_BltToVGAWithXlate(int x, int y, int w, int h, void *b, int Source_lDelta, XLATEOBJ* Xlate)
{
  PBYTE pb, opb = b;
  ULONG i, j;
  ULONG x2 = x + w;
  ULONG y2 = y + h;
  ULONG offset;
  UCHAR a;

  for (i = x; i < x2; i++)
    {
      pb = opb;
      offset = xconv[i] + y80[y];

      WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08);       // set the mask
      WRITE_PORT_UCHAR((PUCHAR)GRA_D, maskbit[i]);

      if (0 == ((i - x) % 2))
	{
	  for (j = y; j < y2; j++)
	    {
	      a = READ_REGISTER_UCHAR(vidmem + offset);
	      WRITE_REGISTER_UCHAR(vidmem + offset, XLATEOBJ_iXlate(Xlate, (*pb & 0xf0) >> 4));
	      offset += 80;
	      pb += Source_lDelta;
	    }
	}
      else
	{
	  for (j = y; j < y2; j++)
	    {
	      a = READ_REGISTER_UCHAR(vidmem + offset);
	      WRITE_REGISTER_UCHAR(vidmem + offset, XLATEOBJ_iXlate(Xlate, *pb & 0x0f));
	      offset += 80;
	      pb += Source_lDelta;
	    }
	}

      if (0 != ((i - x) % 2))
	{
	  opb++;
	}
    }
}

void DIB_TransparentBltToVGA(int x, int y, int w, int h, void *b, int Source_lDelta, ULONG trans)

//  DIB blt to the VGA.
//  For now we just do slow writes -- pixel by pixel, packing each one into the correct 4BPP format.
{
  PBYTE  pb = b, opb = b;
  BOOLEAN  edgePixel = FALSE;
  ULONG  i, j;
  ULONG  x2 = x + w;
  ULONG  y2 = y + h;
  BYTE  b1, b2;

  // Check if the width is odd
  if(mod2(w)>0)
  {
    edgePixel = TRUE;
    x2 -= 1;
  }

  for (j=y; j<y2; j++)
  {
    for (i=x; i<x2; i+=2)
    {
      b1 = (*pb & 0xf0) >> 4;
      b2 = *pb & 0x0f;
      if(b1 != trans) vgaPutPixel(i,   j, b1);
      if(b2 != trans) vgaPutPixel(i+1, j, b2);
      pb++;
    }

    if(edgePixel == TRUE)
    {
      b1 = *pb;
      if(b1 != trans) vgaPutPixel(x2, j, b1);
      pb++;
    }

    opb += Source_lDelta;
    pb = opb; // new test code

  }
}

// This algorithm goes from left to right, storing each 4BPP pixel
// in an entire byte.
void FASTCALL
vgaReadScan ( int x, int y, int w, void *b )
{
  unsigned char *vp, *vpP;
  unsigned char data, mask, maskP;
  unsigned char *bp;
  unsigned char plane_mask;
  int plane, i;

  ASSIGNVP4(x, y, vpP)
  ASSIGNMK4(x, y, maskP)
  get_masks(x, w);
  WRITE_PORT_USHORT((PUSHORT)GRA_I, 0x0005);  // read mode 0
  WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x04);  // read map select

  memset ( b, 0, w );

  for ( plane=0, plane_mask=1; plane < 4; plane++, plane_mask<<=1 )
  {
    WRITE_PORT_UCHAR((PUCHAR)GRA_D, plane);  // read map select

    vp = vpP;
    bp = b;
    if ( leftMask )
    {
      mask = maskP;
      data = *vp++;
      do
      {
	if (data & mask)
	  *bp |= plane_mask;
	bp++;
	mask >>= 1;
      } while (mask & leftMask);

    }
    if (byteCounter)
    {
      for (i=byteCounter; i>0; i--)
      {
	data = *vp++;
	if (data & 0x80) *bp |= plane_mask;
	bp++;
	if (data & 0x40) *bp |= plane_mask;
	bp++;
	if (data & 0x20) *bp |= plane_mask;
	bp++;
	if (data & 0x10) *bp |= plane_mask;
	bp++;
	if (data & 0x08) *bp |= plane_mask;
	bp++;
	if (data & 0x04) *bp |= plane_mask;
	bp++;
	if (data & 0x02) *bp |= plane_mask;
	bp++;
	if (data & 0x01) *bp |= plane_mask;
	bp++;
      }
    }
    if (rightMask)
    {
      mask = 0x80;
      data = *vp;
      do
      {
	if (data & mask)
	  *bp |= plane_mask;
	bp++;
	mask >>= 1;
      } while (mask & rightMask);
    }
  }

  // We don't need this if the next call is a DFB blt to VGA (as in the case of moving the mouse pointer)
  //WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);      // write mode 2
  //WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
  //WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);      // replace
  //WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
}

//  This algorithm goes from left to right
//  It stores each 4BPP pixel in an entire byte.
void FASTCALL
vgaWriteScan ( int x, int y, int w, void *b )
{
  unsigned char *bp;
  unsigned char *vp;
  unsigned char init_mask;
  volatile unsigned char dummy;
  int byte_per_line;
  int i, j, off, init_off = x&7;

  bp = b;
  ASSIGNVP4(x, y, vp)
  ASSIGNMK4(x, y, init_mask)
  byte_per_line = SCREEN_X >> 3;

  WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);      // write mode 2
  WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
  WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);      // replace
  WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
  WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08);      // bit mask

  //DbgPrint("vgaWriteScan(%i,%i,%i...)\n",x,y,w);
  for ( j = 0; j < 8; j++ )
  {
    unsigned int mask = 0x80 >> j;
    //DbgPrint("j=%i\n",j);
    WRITE_PORT_UCHAR ( (PUCHAR)GRA_D, (unsigned char)mask );
    i = j - init_off;
    off = 0;
    if ( j < init_off )
      i += 8, off++;
    while ( i < w )
    {
      //DbgPrint("(%i)",i);
      dummy = vp[off];
      //DbgPrint(".");
      dummy = bp[i];
      //DbgPrint(".");
      vp[off] = dummy;
      //DbgPrint(".");
      i += 8;
      off++;
    }
    //DbgPrint("\n");
  }
}

void DFB_BltFromVGA(int x, int y, int w, int h, void *b, int bw)

//  This algorithm goes from left to right, and inside that loop, top to bottom.
//  It also stores each 4BPP pixel in an entire byte.
{
  unsigned char *vp, *vpY, *vpP;
  unsigned char data, mask, maskP;
  unsigned char *bp, *bpY;
  unsigned char plane_mask;
  int byte_per_line = SCREEN_X >> 3;
  int plane, i, j;

  ASSIGNVP4(x, y, vpP)
  ASSIGNMK4(x, y, maskP)
  get_masks(x, w);
  WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);  // read mode 0
  WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
  WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x04);  // read map select

  // clear buffer
  bp=b;
  for (j=h; j>0; j--)
  {
    memset(bp, 0, w);
    bp += bw;
  }

  for ( plane=0, plane_mask=1; plane < 4; plane++, plane_mask<<=1 )
  {
    WRITE_PORT_UCHAR((PUCHAR)GRA_D, plane);  // read map select
    vpY = vpP;
    bpY = b;
    for ( j=h; j>0; j-- )
    {
      vp = vpY;
      bp = bpY;
      if ( leftMask )
      {
        mask = maskP;
        data = *vp++;
        do
	{
          if (data & mask)
	    *bp |= plane_mask;
          bp++;
          mask >>= 1;
        } while (mask & leftMask);

      }
      if (byteCounter)
      {
        for (i=byteCounter; i>0; i--)
	{
          data = *vp++;
          if (data & 0x80) *bp |= plane_mask;
          bp++;
          if (data & 0x40) *bp |= plane_mask;
          bp++;
          if (data & 0x20) *bp |= plane_mask;
          bp++;
          if (data & 0x10) *bp |= plane_mask;
          bp++;
          if (data & 0x08) *bp |= plane_mask;
          bp++;
          if (data & 0x04) *bp |= plane_mask;
          bp++;
          if (data & 0x02) *bp |= plane_mask;
          bp++;
          if (data & 0x01) *bp |= plane_mask;
          bp++;
        }
      }
      if (rightMask)
      {
        mask = 0x80;
        data = *vp;
        do
	{
          if (data & mask) *bp |= plane_mask;
          bp++;
          mask >>= 1;
        } while (mask & rightMask);
      }
      bpY += bw;
      vpY += byte_per_line;
    }
  }

  // We don't need this if the next call is a DFB blt to VGA (as in the case of moving the mouse pointer)
  WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);      // write mode 2
  WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
  WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);      // replace
  WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
}

void DFB_BltToVGA(int x, int y, int w, int h, void *b, int bw)

//  This algorithm goes from left to right, and inside that loop, top to bottom.
//  It also stores each 4BPP pixel in an entire byte.
{
  unsigned char *bp, *bpX;
  unsigned char *vp, *vpX;
  unsigned char mask;
  volatile unsigned char dummy;
  int byte_per_line;
  int i, j;

  bpX = b;
  ASSIGNVP4(x, y, vpX)
  ASSIGNMK4(x, y, mask)
  byte_per_line = SCREEN_X >> 3;

  WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);      // write mode 2
  WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
  WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);      // replace
  WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
  WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08);      // bit mask

  for (i=w; i>0; i--)
  {
    WRITE_PORT_UCHAR((PUCHAR)GRA_D, mask);
    bp = bpX;
    vp = vpX;
    for (j=h; j>0; j--)
    {
      dummy = *vp;
      *vp = *bp;
      bp += bw;
      vp += byte_per_line;
    }
    bpX++;
    if ((mask >>= 1) == 0)
    {
      vpX++;
      mask = 0x80;
    }
  }
}

void DFB_BltToVGA_Transparent(int x, int y, int w, int h, void *b, int bw, char Trans)

//  This algorithm goes from goes from left to right, and inside that loop, top to bottom.
//  It also stores each 4BPP pixel in an entire byte.
{
  unsigned char *bp, *bpX;
  unsigned char *vp, *vpX;
  unsigned char mask;
  volatile unsigned char dummy;
  int byte_per_line;
  int i, j;

  bpX = b;
  ASSIGNVP4(x, y, vpX)
  ASSIGNMK4(x, y, mask)
  byte_per_line = SCREEN_X >> 3;

  WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);      // write mode 2
  WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
  WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);      // replace
  WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
  WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08);      // bit mask

  for (i=w; i>0; i--)
  {
    WRITE_PORT_UCHAR((PUCHAR)GRA_D, mask);
    bp = bpX;
    vp = vpX;
    for (j=h; j>0; j--)
    {
      if (*bp != Trans)
      {
        dummy = *vp;
        *vp = *bp;
      }
      bp += bw;
      vp += byte_per_line;
    }
    bpX++;
    if ((mask >>= 1) == 0)
    {
      vpX++;
      mask = 0x80;
    }
  }
}

void DFB_BltToDIB(int x, int y, int w, int h, void *b, int bw, void *bdib, int dibw)

// This algorithm converts a DFB into a DIB
// WARNING: This algorithm is buggy
{
  unsigned char *bp, *bpX, *dib, *dibTmp;
  int i, j, dib_shift;

  bpX = b;
  dib = (unsigned char *)bdib + y * dibw + (x / 2);

  for (i=w; i>0; i--) {

    // determine the bit shift for the DIB pixel
    dib_shift = mod2(w-i);
    if(dib_shift > 0) dib_shift = 4;
    dibTmp = dib;

    bp = bpX;
    for (j=h; j>0; j--) {
      *dibTmp = *bp << dib_shift | *(bp + 1);
      dibTmp += dibw;
      bp += bw;
    }
    bpX++;
    if(dib_shift == 0) dib++;
  }
}


void DIB_BltToDFB(int x, int y, int w, int h, void *b, int bw, void *bdib, int dibw)

// This algorithm converts a DIB into a DFB
{
  unsigned char *bp, *bpX, *dib, *dibTmp;
  int i, j, dib_shift, dib_and;

  bpX = b;
  dib = (unsigned char *)bdib + y * dibw + (x / 2);

  for (i=w; i>0; i--) {

    // determine the bit shift for the DIB pixel
    dib_shift = mod2(w-i);
    if(dib_shift > 0) {
      dib_shift = 0;
      dib_and = 0x0f;
    } else {
      dib_shift = 4;
      dib_and = 0xf0;
    }

    dibTmp = dib;
    bp = bpX;

    for (j=h; j>0; j--) {
      *bp = (*dibTmp & dib_and) >> dib_shift;
      dibTmp += dibw;
      bp += bw;
    }

    bpX++;
    if(dib_shift == 0) dib++;
  }
}

⌨️ 快捷键说明

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