Newer
Older
ubixos / src / sys / graphics / objgfx30.cpp
@reddawg reddawg on 22 Jun 2002 5 KB Fixed
/*******************************************************
$Id$
*******************************************************/

#include "objgfx30.h"
#include <stdlib.h>

// TGfx0 constructor

TGfx0::TGfx0(void) {
  DataState = og_None;
  Buffer = 0;
  LineOfs = 0;
  pal = 0;
  xRes = 0;
  yRes = 0;
  MaxX = 0;
  MaxY = 0;
  bSize = 0;
  lSize = 0;
  TransparentColor = 0;
  BPP = 0;
  RedShifter = 0;
  GreenShifter = 0;
  BlueShifter = 0;
  RedFieldPosition = 0;
  GreenFieldPosition = 0;
  BlueFieldPosition = 0;
  return;
} // TGfx0::TGfx0()


bool TGfx0::create(UInt32 _xRes, UInt32 _yRes,TPixelFmt* _pixformat) {
  UInt32 yy;
  if (DataState==og_Owner) {
    if (Buffer) free(Buffer);
    if (LineOfs) free(LineOfs);
    if (pal) free(pal);
  }  // if datastate
  BPP = _pixformat->BPP;
  bSize=_xRes*_yRes*((BPP+7) >> 3);
  Buffer = malloc(bSize);
  if (!Buffer) return FALSE;
  lSize = _yRes*sizeof(UInt32);
  LineOfs = (UInt32*)malloc(lSize);
  if (!LineOfs) return FALSE;
  pal = (TRGB*)malloc(256*sizeof(TRGB));
  if (!pal) return FALSE;
  for (yy = 0; yy<=256; yy++) {
    pal[yy].red = 0;
    pal[yy].green = 0;
    pal[yy].blue = 0;
  }  // for
  MaxX=_xRes-1;
  xRes=_xRes;
  MaxY=_yRes-1;
  yRes=_yRes;
  LineOfs[0]=0;
  for (yy=1; yy<=MaxY; yy++)
    LineOfs[yy]=LineOfs[yy-1]+xRes*((BPP+7) >> 3);
  DataState = og_Owner;
  // For 8bpp modes the next part doesn't matter 
  RedFieldPosition=_pixformat->RedFieldPosition;
  GreenFieldPosition=_pixformat->GreenFieldPosition;
  BlueFieldPosition=_pixformat->BlueFieldPosition;
  // The next part is only used by 15/16hpp 
  RedShifter=8-_pixformat->RedMaskSize;
  GreenShifter=8-_pixformat->GreenMaskSize;
  BlueShifter=8-_pixformat->BlueMaskSize; 
  Owner = this;
  return TRUE;
} // TGfx0::create

void TGfx0::flip(TGfx0* SrcObject) {
  UInt32 count, xCount, yCount;
  UInt32 xx, yy;
  UInt8  r, g, b;
  if (!Buffer) return;
  if (!SrcObject->Buffer) return;
  xCount = SrcObject->MaxX+1;
  if (xCount>MaxX+1) xCount=MaxX;
  yCount = SrcObject->MaxY+1;
  if (yCount>MaxY+1) yCount=MaxY;
  if ((BPP!=SrcObject->BPP) || (RedShifter!=SrcObject->RedShifter) ||
      (BlueShifter!=SrcObject->BlueShifter) || 
      (GreenShifter!=SrcObject->GreenShifter)) {
    for (yy=0; yy<=yCount; yy++)
      for (xx=0; xx<=xCount; xx++) {
        SrcObject->unpackRGB(SrcObject->getpixel(xx,yy),&r,&g,&b);
        putpixel(xx,yy,RGB(r,g,b));
      } // for
  }  // if
  else
  {
    xCount=xCount*((BPP+7) >> 3); // adjust for bpp 
    for (count=0; count<=yCount; count++) ;
      memcpy(((char*)Buffer+LineOfs[count]),                        // dest
             ((char*)SrcObject->Buffer+SrcObject->LineOfs[count]),  // src
             xCount);                                        // len
  } // else
} // TGfx0::flip

UInt32 TGfx0::getMaxX(void) {
  return MaxX;
} // TGfx0::getMaxX

UInt32 TGfx0::getMaxY(void) {
  return MaxY;
} // TGfx0::getMaxY

UInt32 TGfx0::getpixel(UInt32 x, UInt32 y) {
  return 0;
} // TGfx0::getpixel

void TGfx0::putpixel(UInt32 x, UInt32 y, UInt32 colour) {
  return;
} // TGfx0::putpixel

UInt32 TGfx0::RGB(UInt8 red, UInt8 green, UInt8 blue) {
  UInt32 lastclr;
  lastclr=1000;
  switch (BPP) {
  case 8:
    asm(
      "movl    $256,%%ecx     \n"
      "movl    $769,%%ebx     \n"
      "xor     %%eax,%%eax    \n"
      "lop:                   \n"
      "  pushl %%eax          \n"
      "  mov   (%%esi),%%al   \n"
      "  incl  %%esi          \n"
      "  sub   %1,%%al        \n"
      "  jns   abs1           \n"
      "  neg   %%al           \n"
      "abs1:                  \n"
      "  movl   %%eax,%%edi   \n"
      "  mov   (%%esi),%%al   \n"
      "  incl  %%esi          \n"
      "  sub   %2,%%al        \n"
      "  jns   abs2           \n"
      "  neg   %%al           \n"
      "abs2:                  \n"
      "  addl  %%eax,%%edi    \n"
      "  mov   (%%esi),%%al   \n"
      "  incl  %%esi          \n"
      "  sub   %3,%%al        \n"
      "  jns   abs3           \n"
      "  neg   %%al           \n"
      "abs3:                  \n"
      "  addl  %%eax,%%edi    \n"
      "  popl  %%eax          \n"
      "  cmpl  %%ebx,%%edi    \n"
      "  jae   no_good_match  \n"
      "  movl  %%edi,%%ebx    \n"
      "  movl  %%eax,%4       \n"
      "no_good_match:         \n"
      "  incl  %%eax          \n"
      "  decl  %%ecx          \n"
      "  jnz   lop            \n"
      : 
      : "S" (pal), "m" (red), "m" (green), "m" (blue), "m" (lastclr)
      );
    break;
  } // switch
  //asm("": "=a" (lastclr));
  return lastclr;
} // TGfx0::RGB

void TGfx0::setRGBPalette(UInt8 colour, UInt8 red, UInt8 green, UInt8 blue) {
  colour = colour & 255;
  pal[colour].red = red;
  pal[colour].green = green;
  pal[colour].blue = blue;
  return;
} // TGfx0::setRGBPalette

void TGfx0::unpackRGB(UInt32 colour, UInt8* red, UInt8* green, UInt8* blue) {
  switch (BPP) {
  case 8:
    if (colour>255) colour=colour & 255;
    *red   = pal[colour].red;
    *green = pal[colour].green;
    *blue  = pal[colour].blue; 
    break;
  case 15:
  case 16:
    *red   = ((colour >> RedFieldPosition) << RedShifter);
    *green = ((colour >> GreenFieldPosition) << GreenShifter);
    *blue  = ((colour >> BlueFieldPosition) << BlueShifter);
    break;
  case 24:
  case 32:
    *red   = colour >> RedFieldPosition;
    *green = colour >> GreenFieldPosition;
    *blue  = colour >> BlueFieldPosition;
    break;
  default:
    *red   = 0;
    *green = 0;
    *blue  = 0;
  }
  return;
} // TGfx0:unpackRGB

TGfx0::~TGfx0(void) {
  if (DataState == og_Owner) {
    if (pal) free(pal);
    if (Buffer) free(Buffer);
    if (LineOfs) free(LineOfs);
  }  // if datastate
  pal=0;
  LineOfs=0;
  Buffer=0;
  bSize=0;
  lSize=0;
  DataState = og_None;
  return;
} // TGfx0::~TGfx0()