/*******************************************************
$Id$
*******************************************************/
#include "objgfx30.h"
#include <stdlib.h>
#include <string.h>
//#include <math.h>
#include "../include/types.h"
// TGfx0 constructor
TGfx0::TGfx0(void) {
DataState = og_None;
Buffer = NULL;
LineOfs = NULL;
pal = NULL;
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;
AntiAlias = TRUE;
return;
} // TGfx0::TGfx0()
bool
TGfx0::alias(TGfx0& SrcObject, UInt32 x1, UInt32 y1, UInt32 x2, UInt32 y2) {
UInt32 tmp;
if (DataState==og_Owner) return FALSE;
if (x2<x1) {
tmp= x2;
x2 = x1;
x1 = tmp;
} // if
if (y2<y1) {
tmp= y2;
y2 = y1;
y1 = tmp;
} // if
Owner = &SrcObject;
Buffer =((unsigned char *)(SrcObject.Buffer)+x1*((SrcObject.BPP+7) >> 3));
LineOfs=((UInt32 *)SrcObject.LineOfs)+y1;
pal = SrcObject.pal;
xRes = SrcObject.xRes;
yRes = SrcObject.yRes;
MaxX = (x2-x1);
MaxY = (y2-y1);
bSize = 0;
lSize = 0;
TransparentColor = SrcObject.TransparentColor;
DataState = og_Aliasing;
BPP = SrcObject.BPP;
// For 8bpp modes the next part doesn't matter
RedFieldPosition = SrcObject.RedFieldPosition;
GreenFieldPosition = SrcObject.GreenFieldPosition;
BlueFieldPosition = SrcObject.BlueFieldPosition;
// The next part is only used by 15/16bpp
RedShifter = SrcObject.RedShifter;
GreenShifter = SrcObject.GreenShifter;
BlueShifter = SrcObject.BlueShifter;
AntiAlias = SrcObject.AntiAlias;
return TRUE;
} // TGfx0::alias
void
TGfx0::arc(UInt32 x_center, UInt32 y_center, UInt32 radius,
UInt32 s_angle, UInt32 e_angle, UInt32 colour) {
Int32 p;
UInt32 x, y, tmp;
double alpha;
if (radius==0) {
putPixel(x_center, y_center, colour);
return;
} // if
s_angle%=361;
e_angle%=361;
if (s_angle>e_angle) {
tmp = s_angle;
s_angle = e_angle;
e_angle = tmp;
} // if
x = 0;
y = radius;
p = 3-2*radius;
while (x<=y) {
// mjikaboom alpha = RadToDeg(atan(x/y));
if ((alpha>=s_angle) && (alpha<=e_angle))
putPixel(x_center-x, y_center-y, colour);
if ((90-alpha>=s_angle) && (90-alpha<=e_angle))
putPixel(x_center-y, y_center-x, colour);
if ((90+alpha>=s_angle) && (90+alpha<=e_angle))
putPixel(x_center-y, y_center+x,colour);
if ((180-alpha>=s_angle) && (180-alpha<=e_angle))
putPixel(x_center-x, y_center+y,colour);
if ((180+alpha>=s_angle) && (180+alpha<=e_angle))
putPixel(x_center+x, y_center+y,colour);
if ((270-alpha>=s_angle) && (270-alpha<=e_angle))
putPixel(x_center+y, y_center+x,colour);
if ((270+alpha>=s_angle) && (270+alpha<=e_angle))
putPixel(x_center+y, y_center-x,colour);
if ((360-alpha>=s_angle) && (360-alpha<=e_angle))
putPixel(x_center+x, y_center-y,colour);
if (p<0) p+=4*x+6;
else {
p+=4*(x-y)+10;
y--;
}
x++;
} // while
} // TGfx0::arc
void
TGfx0::bar(Int32 x1, Int32 y1, Int32 x2, Int32 y2, UInt32 colour) {
Int32 yy;
Int32 tmp;
if (x2<x1) {
tmp= x2;
x2 = x1;
x1 = tmp;
} // if
if (y2<y1) {
tmp= y2;
y2 = y1;
y1 = tmp;
} // if
if ((y2<0) || (y1>(Int32)MaxY)) return;
if (y1<0) y1=0;
if (y2>(Int32)MaxY) y2=MaxY;
for (yy=y1; yy<=y2; yy++)
hLine(x1,x2,yy,colour);
} // TGfx0::bar
void
TGfx0::circle(Int32 x_center, Int32 y_center, UInt32 radius, UInt32 colour) {
Int32 x, y, d;
x = 0;
y = radius;
d = 2*(1-radius);
while (y>=0) {
putPixel(x_center+x,y_center+y,colour);
putPixel(x_center+x,y_center-y,colour);
putPixel(x_center-x,y_center+y,colour);
putPixel(x_center-x,y_center-y,colour);
if (d + y > 0) {
y--;
d -= 2*y+1;
} // if
if (x > d) {
x++;
d += 2*x+1;
} // if
} // while
} // TGfx0::circle
void
TGfx0::clear(UInt32 colour) {
UInt32 height;
if ((Buffer==NULL) || (LineOfs==NULL)) return;
asm("cld\n");
switch (BPP) {
case 8:
asm(
" add (%%esi), %%edi \n" // add edi, [esi]
" mov %%ecx, %%esi \n" // mov esi, ecx
" inc %%edx \n" // inc edx (MaxY)
" inc %%ebx \n" // inc ebx (MaxX)
" sub %%edx, %%esi \n" // sub esi, edx
" mov %%al, %%ah \n" // mov ah, al
" mov %%ax, %%cx \n" // mov cx, ax
" shl $16, %%eax \n" // shl eax, 16
" mov %%cx, %%ax \n" // mov ax, cx
"loop8: \n"
" push %%edx \n"
" mov %%edx, %%ecx \n" // mov ecx, edx
" and $3, %%edx \n" // and edx, 3
" shr $2, %%ecx \n" // shr ecx, 2
" rep \n"
" stosl \n"
" mov %%edx, %%ecx \n" // mov ecx, edx
" rep \n"
" stosb \n"
" pop %%edx \n"
" add %%esi, %%edi \n" // add edi, esi
" dec %%ebx \n"
" jnz loop8 \n"
:
: "D" (Buffer), "S" (LineOfs), // %0, %1
"a" (colour), "b" (MaxY), // %2, %3
"c" (xRes), "d" (MaxX) // %4, %5
);
break;
case 15:
case 16:
asm(
" add (%%esi), %%edi \n" // add edi, [esi]
" mov %%ecx, %%esi \n" // mov esi, ecx
" inc %%edx \n" // inc edx (MaxX)
" inc %%ebx \n" // inc ebx (MaxY)
" sub %%edx, %%esi \n" // sub esi, edx
" sub %%edx, %%esi \n" // sub esi, edx // adjust for pix size
" mov %%ax, %%cx \n" // mov cx, ax
" shl $16, %%eax \n" // shl eax, 16
" mov %%cx, %%ax \n" // mov ax, cx
"loop16: \n"
" mov %%edx, %%ecx \n" // mov ecx, edx
" shr $1, %%ecx \n" // shr ecx, 1
" rep \n"
" stosl \n"
" jnc noc16 \n"
" stosw \n"
"noc16: \n"
" add %%esi, %%edi \n" // add edi, esi
" dec %%ebx \n"
" jnz loop16 \n"
:
: "D" (Buffer), "S" (LineOfs), // %0, %1
"a" (colour), "b" (MaxY), // %2, %3
"c" (xRes), "d" (MaxX) // %4, %5
);
break;
case 24:
asm(
" add (%%esi), %%edi \n" // add edi, [esi]
" mov %%ecx, %%esi \n" // mov esi, ecx
" inc %%edx \n" // inc edx (MaxX)
" inc %%ebx \n" // inc ebx (MaxY)
" sub %%edx, %%esi \n" // sub esi, edx // adjust for pix size
" mov %%ebx, %6 \n" // mov height, ebx
" sub %%edx, %%esi \n" // sub esi, edx // adjust for pix size
" mov %%eax, %%ebx \n" // mov ebx, eax
" sub %%edx, %%esi \n" // sub esi, edx // adjust for pix size
" shr $16, %%ebx \n" // shr ebx, 16
"oloop24: \n"
" mov %%edx, %%ecx \n" // mov ecx, edx
"iloop24: \n"
" mov %%ax,(%%edi) \n" // mov [edi],ax
" movb %%bl,2(%%edi) \n" // mov [edi+2],bl
" add $3, %%edi \n" // add edi, 3
" dec %%ecx \n" // dec ecx
" jnz iloop24 \n"
" add %%esi, %%edi \n" // add edi, esi
" decl %6 \n" // dec height
" jnz oloop24 \n"
:
: "D" (Buffer), "S" (LineOfs), // %0, %1
"a" (colour), "b" (MaxY), // %2, %3
"c" (xRes), "d" (MaxX), // %4, %5
"g" (height) // %6
);
break;
case 32:
asm(
" add (%%esi), %%edi \n" // add edi, [esi]
" mov %%ecx, %%esi \n" // mov esi, ecx
" inc %%edx \n" // inc edx (MaxX)
" inc %%ebx \n" // inc ebx (MaxY)
" mov %%edx, %%ecx \n" // mov ecx, edx
" shl $2, %%ecx \n" // shl ecx, 2
" sub %%ecx, %%esi \n" // sub esi, ecx // adjust for pix size
"loop32: \n"
" mov %%edx, %%ecx \n" // mov ecx, edx
" rep \n"
" stosl \n"
" add %%esi, %%edi \n" // add edi, esi
" dec %%ebx \n"
" jnz loop32 \n"
:
: "D" (Buffer), "S" (LineOfs), // %0, %1
"a" (colour), "b" (MaxY), // %2, %3
"c" (xRes), "d" (MaxX) // %4, %5
);
}
} // TGfx0::clear
bool
TGfx0::clipLine(Int32& x1, Int32& y1, Int32& x2, Int32& y2) {
/*
* clipLine()
*
* private method; clips a line to (0,0),(MaxX,MaxY); returns true if
* the line segment is in bounds, false if none of the line segment is
* on the screen. Uses HJI's line clipping algorithm.
*/
Int32 tx1, ty1, tx2, ty2;
Int32 OutCode;
UInt32 AndResult, OrResult;
AndResult = 15;
OrResult = 0;
OutCode = 0;
if (x1<0) OutCode+=8;
if (x1>(Int32)MaxX) OutCode+=4;
if (y1<0) OutCode+=2;
if (y1>(Int32)MaxY) OutCode++;
AndResult &= OutCode;
OrResult |= OutCode;
OutCode = 0;
if (x2<0) OutCode+=8;
if (x2>(Int32)MaxX) OutCode+=4;
if (y2<0) OutCode+=2;
if (y2>(Int32)MaxY) OutCode++;
AndResult &= OutCode;
OrResult |= OutCode;
if (AndResult>0) return FALSE;
if (OrResult==0) return TRUE;
// some clipping is required here.
tx1 = x1;
ty1 = y1;
tx2 = x2;
ty2 = y2;
if (x1<0) {
ty1 = (x2*y1-x1*y2) / (x2-x1);
tx1 = 0;
} // if
else
if (x2<0) {
ty2 = (x2*y1-x1*y2) / (x2-x1);
tx2 = 0;
} // elseif
if (x1>(Int32)MaxX) {
ty1 = (y1*(x2-MaxX)+y2*(MaxX-x1)) / (x2-x1);
tx1 = MaxX;
} // if
else
if (x2>(Int32)MaxX) {
ty2 = (y1*(x2-MaxX)+y2*(MaxX-x1)) / (x2-x1);
tx2 = MaxX;
} // elseif
if (((ty1<0) && (ty2<0)) ||
((ty1>(Int32)MaxY) && (ty2>(Int32)MaxY))) return FALSE;
if (ty1<0) {
tx1 = (x1*y2-x2*y1) / (y2-y1);
ty1 = 0;
} // if
else
if (ty2<0) {
tx2 = (x1*y2-x2*y1) / (y2-y1);
ty2 = 0;
} // elseif
if (ty1>(Int32)MaxY) {
tx1 = (x1*(y2-MaxY)+x2*(MaxY-y1)) / (y2-y1);
ty1 = MaxY;
} // if
else
if (ty2>(Int32)MaxY) {
tx2 = (x1*(y2-MaxY)+x2*(MaxY-y1)) / (y2-y1);
ty2 = MaxY;
} // elseif
if (((UInt32)tx1>MaxX) || ((UInt32)tx2>MaxX)) return FALSE;
x1 = tx1;
y1 = ty1;
x2 = tx2;
y2 = ty2;
return TRUE;
} // TGfx0::clipLine
void
TGfx0::clone(TGfx0& SrcObject) {
TPixelFmt pixfmt;
if (SrcObject.DataState==og_None) return;
SrcObject.getPixFmt(pixfmt);
create(SrcObject.MaxX+1,SrcObject.MaxY+1,pixfmt);
if (pal!=NULL) memcpy(pal, SrcObject.pal, sizeof(TRGB)*256);
TransparentColor = SrcObject.TransparentColor;
AntiAlias = SrcObject.AntiAlias;
copy(SrcObject);
} // TGfx0::clone
void
TGfx0::copy(TGfx0& SrcObject) {
UInt32 count, xCount, yCount;
UInt32 xx, yy;
UInt8 r, g, b;
if ((Buffer==NULL) || (LineOfs==NULL)) return;
if ((SrcObject.Buffer==NULL) || (SrcObject.LineOfs==NULL)) return;
xCount = SrcObject.MaxX+1;
if (xCount>MaxX+1) xCount=MaxX+1;
yCount = SrcObject.MaxY+1;
if (yCount>MaxY+1) yCount=MaxY+1;
if ((BPP!=SrcObject.BPP) || (RedShifter!=SrcObject.RedShifter) ||
(BlueShifter!=SrcObject.BlueShifter) ||
(GreenShifter!=SrcObject.GreenShifter)) {
for (yy=0; yy<=yCount-1; yy++)
for (xx=0; xx<=xCount-1; xx++) {
SrcObject.unpackRGB(SrcObject.getPixel(xx,yy),r,g,b);
putPixel(xx,yy,RGB(r,g,b));
} // for
} // if
else
{
xCount *= ((BPP+7) >> 3); // adjust for bpp
for (count=0; count<=yCount-1; count++) ;
memcpy(((char*)Buffer+LineOfs[count]), // dest
((char*)SrcObject.Buffer+SrcObject.LineOfs[count]), // src
xCount); // len
} // else
} // TGfx0::copy
void
TGfx0::copyBuf(Int32 DestX, Int32 DestY,
TGfx0& SrcObject, Int32 x1, Int32 y1, Int32 x2, Int32 y2) {
UInt32 pixmap[256];
Int32 xx,yy,count,xCount, yCount;
UInt32 bm; // bit multiplyer
UInt8 r, g, b;
if ((Buffer==NULL) || (LineOfs==NULL)) return;
if ((SrcObject.Buffer==NULL) || (SrcObject.LineOfs==NULL)) return;
if ((DestX>(Int32)MaxX) || (DestY>(Int32)MaxY)) return;
if (x1>x2) {
xx = x1;
x1 = x2;
x2 = xx;
} // if
if (y1>y2) {
yy = y1;
y1 = y2;
y2 = yy;
} // if
xCount = abs(x2-x1)+1;
yCount = abs(y2-y1)+1;
if (DestX+xCount>(Int32)MaxX+1) xCount=MaxX-DestX+1;
if (DestY+yCount>(Int32)MaxY+1) yCount=MaxY-DestY+1;
if (DestX<0) {
xCount += DestX;
x1 -= DestX;
DestX = 0;
} // if
if (DestY<0) {
yCount += DestY;
y1 -= DestY;
DestY = 0;
} // if
if ((DestX+xCount<0) || (DestY+yCount<0)) return;
if ((BPP!=SrcObject.BPP) || (RedShifter!=SrcObject.RedShifter) ||
(BlueShifter!=SrcObject.BlueShifter) ||
(GreenShifter!=SrcObject.GreenShifter)) {
if (SrcObject.BPP==8) {
for (xx=0; xx<256; xx++)
pixmap[xx] = RGB(SrcObject.pal[xx].red,
SrcObject.pal[xx].green,
SrcObject.pal[xx].blue);
for (yy=0; yy<=yCount-1; yy++)
for (xx=0; xx<=xCount-1; xx++)
putPixel(DestX+xx,DestY+yy,pixmap[SrcObject.getPixel(x1+xx,y1+yy)]);
} // if srcobject->bpp
else
{
for (yy=0; yy<=yCount-1; yy++)
for (xx=0; xx<=xCount-1; xx++) {
SrcObject.unpackRGB(SrcObject.getPixel(x1+xx,y1+yy),r,g,b);
putPixel(DestX+xx,DestY+yy,RGB(r,g,b));
} // for
} // else
} // if
else
{
bm = (BPP+7) >> 3;
x1 *= bm;
DestX *= bm;
xCount *= bm;
for (count=0; count<=yCount-1; count++) {
memcpy(((char*)Buffer+LineOfs[DestY+count]+DestX), // dest
((char*)SrcObject.Buffer+SrcObject.LineOfs[y1+count]+x1), // src
xCount); // len
}
} // else
} // TGfx0::copyBuf
bool
TGfx0::create(UInt32 _xRes, UInt32 _yRes,TPixelFmt _pixformat) {
/*
* constructor TGfx0::create()
* Allocates memory for a buffer of size _xRes by _yRes with
* the pixel format defined in _pixformat. Allocates memory
* for pal and LineOfs.
*/
UInt32 yy;
if (DataState==og_Owner) {
if (Buffer!=NULL) free(Buffer);
if (LineOfs!=NULL) free(LineOfs);
if (pal!=NULL) free(pal);
} // if datastate
BPP = _pixformat.BPP;
bSize=_xRes*_yRes*((BPP+7) >> 3);
Buffer = malloc(bSize);
if (Buffer==NULL) return FALSE;
memset(Buffer,0,bSize);
lSize = _yRes*sizeof(UInt32);
LineOfs = (UInt32*)malloc(lSize);
if (LineOfs == NULL) return FALSE;
pal = (TRGB*)malloc(256*sizeof(TRGB));
if (pal == NULL) return FALSE;
memset(pal,0,sizeof(TRGB)*256);
MaxX=_xRes-1;
xRes=_xRes*((BPP+7) >> 3);
MaxY=_yRes-1;
yRes=_yRes;
LineOfs[0]=0;
for (yy=1; yy<=MaxY; yy++)
LineOfs[yy]=LineOfs[yy-1]+xRes;
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
UInt8
TGfx0::getBPP(void) {
return BPP;
} // TGfx0::getBPP
void*
TGfx0::getBufferPtr(void) {
return Buffer;
} // TGfx0::getBufferPtr
og_DataState
TGfx0::getDataState(void) {
return DataState;
} // TGfx0::getDataState(void)
UInt32*
TGfx0::getLineOfsPtr(void) {
return LineOfs;
} // TGfx0::getLineOfsPtr
TRGB *
TGfx0::getPalPtr(void) {
return pal;
} // TGfx0::getPalPtr
UInt32
TGfx0::getMaxX(void) {
return MaxX;
} // TGfx0::getMaxX
UInt32
TGfx0::getMaxY(void) {
return MaxY;
} // TGfx0::getMaxY
UInt32
TGfx0::getPixel(Int32 x, Int32 y) {
UInt32 result;
result = 42;
if ((Buffer==NULL) || (LineOfs==NULL)) return TransparentColor;
if (((UInt32)x>MaxX) || ((UInt32)y>MaxY))
return TransparentColor;
switch (BPP) {
case 8:
asm(
" add %%esi, %%edi \n" // add edi, esi
" add %%ecx, %%edi \n" // add edi, ecx
" movzbl (%%edi),%%eax \n" // movzx edx,byte ptr [edi]
" mov %%eax, %3 \n" // mov result, eax
:
: "D" (Buffer), "S" (LineOfs[y]), // %0, %1
"c" (x), "m" (result) // %2, %3
);
break;
case 15:
case 16:
asm(
" add %%esi, %%edi \n" // add edi, esi
" add %%ecx, %%ecx \n" // add ecx, ecx {adjust for pixel size}
" add %%ecx, %%edi \n" // add edi, ecx
" movzwl (%%edi),%%eax \n" // movzx edx,word ptr [edi]
" mov %%eax, %3 \n" // mov result, eax
:
: "D" (Buffer), "S" (LineOfs[y]), // %0, %1
"c" (x), "m" (result) // %2, %3
);
break;
case 24:
asm(
" mov %%ecx, %%eax \n" // mov eax, ecx - adjust for pixel size
" add %%ecx, %%ecx \n" // add ecx, ecx - adjust for pixel size
" add %%eax, %%ecx \n" // add ecx, eax - adjust for pixel size
" add %%esi, %%edi \n" // add edi, esi
// " add (%%esi,%%ebx,4), %%edi \n" // add edi, [esi + ebx*4]
" add %%ecx, %%edi \n" // add edi, ecx
" movzwl (%%edi),%%eax \n" // edx,word ptr [edi]
" xor %%eax, %%eax \n"
" mov 2(%%edi), %%al \n" // mov al, [edi+2]
" shl $16, %%eax \n" // shl eax, 16
" mov (%%edi), %%ax \n" // mov ax, [edi]
" mov %%eax, %3 \n" // mov result, eax
:
: "D" (Buffer), "S" (LineOfs[y]), // %0, %1
"c" (x), "m" (result) // %2, %3
);
break;
case 32:
asm(
" shl $2, %%ecx \n" // shl ecx, 2 {adjust for pixel size}
// " add (%%esi,%%ebx,4), %%edi \n" // add edi, [esi + ebx*4]
" add %%esi, %%edi \n" // add edi, esi
" add %%ecx, %%edi \n" // add edi, ecx
" mov (%%edi),%%eax \n" // eax,word ptr [edi]
" mov %%eax, %3 \n" // mov result, eax
:
: "D" (Buffer), "S" (LineOfs[y]), // %0, %1
"c" (x), "m" (result) // %2, %3
);
} // switch
return result;
} // TGfx0::getPixel
void
TGfx0::getPixFmt(TPixelFmt& pixfmt) {
pixfmt.BPP=BPP;
pixfmt.RedFieldPosition=RedFieldPosition;
pixfmt.GreenFieldPosition=GreenFieldPosition;
pixfmt.BlueFieldPosition=BlueFieldPosition;
pixfmt.RedMaskSize=8-RedShifter;
pixfmt.GreenMaskSize=8-GreenShifter;
pixfmt.BlueMaskSize=8-BlueShifter;
} // TGfx0::getPixFmt
UInt32
TGfx0::getTransparentColor(void) {
return TransparentColor;
} // TGfx0::getTransparentColor
void
TGfx0::hFlip(void) {
void * tmpBuf;
UInt32 xWidth, count;
if ((Buffer==NULL) || (LineOfs==NULL)) return;
xWidth = (MaxX+1)*((BPP+7) >> 3);
tmpBuf = malloc(xWidth);
if (tmpBuf == NULL) return;
for (count=0; count<=(MaxY/2); count++) {
memcpy(tmpBuf,((char*)Buffer+LineOfs[count]),xWidth);
memcpy(((char*)Buffer+LineOfs[count]),
((char*)Buffer+LineOfs[MaxY-count]),
xWidth);
memcpy(((char*)Buffer+LineOfs[MaxY-count]),tmpBuf,xWidth);
} // for
free(tmpBuf);
return;
} // TGfx0::hFlip
void
TGfx0::hLine(Int32 x1, Int32 x2, Int32 y, UInt32 colour) {
Int32 tmp;
if ((Buffer==NULL) || (LineOfs==NULL)) return;
if ((UInt32)y>MaxY) return;
if (x1>x2) {
tmp= x1;
x1 = x2;
x2 = tmp;
} // if
if (x1<0) x1 = 0;
if (x2>(Int32)MaxX) x1=MaxX;
if (x2<x1) return;
asm("cld \n");
switch (BPP) {
case 8:
asm(
" add %%ebx, %%edi \n" // add edi, ebx
" add %%esi, %%edi \n" // add edi, esi
" and $0xff, %%eax \n" // and eax, 0ffh
" sub %%ebx, %%ecx \n" // sub ecx, ebx
" mov %%al, %%ah \n" // mov ah, al
" inc %%ecx \n" // inc ecx
" mov %%eax, %%ebx \n" // mov ebx, eax
" shl $16, %%ebx \n" // shl ebx, 16
" add %%ebx, %%eax \n" // add eax, ebx
" mov %%ecx, %%edx \n" // mov edx, ecx
" mov $4, %%ecx \n" // mov ecx, 4
" sub %%edi, %%ecx \n" // sub ecx, edi
" and $3, %%ecx \n" // and ecx, 3
" sub %%ecx, %%edx \n" // sub edx, ecx
" jle LEndBytes \n"
" rep \n"
" stosb \n"
" mov %%edx, %%ecx \n" // mov ecx, edx
" and $3, %%edx \n" // and edx, 3
" shr $2, %%ecx \n" // shr ecx, 2
" rep \n"
" stosl \n"
"LEndBytes: \n"
" add %%edx, %%ecx \n" // add ecx, edx
" rep \n"
" stosb \n"
:
: "D" (Buffer), "S" (LineOfs[y]), // %0, %1
"a" (colour), "b" (x1), // %2, %3
"c" (x2)
);
break;
case 15:
case 16:
asm(
" sub %%ebx, %%ecx \n" // sub ecx, ebx
" add %%ebx, %%ebx \n" // add ebx, ebx - pix size
" inc %%ecx \n" // inc ecx
" add %%ebx, %%edi \n" // add edi, ebx
" add %%esi, %%edi \n" // add edi, esi
" xor %%edx, %%edx \n" // xor edx, edx
" mov %%ax, %%dx \n" // mov dx, ax
" shl $16, %%eax \n" // shl eax, 16
" add %%edx, %%eax \n" // add eax, edx
" shr $1, %%ecx \n" // shr ecx, 1
" rep \n"
" stosl \n"
" jnc hLnoc16 \n"
" stosw \n"
"hLnoc16: \n"
:
: "D" (Buffer), "S" (LineOfs[y]), // %0, %1
"a" (colour), "b" (x1), // %2, %3
"c" (x2) // %4
);
break;
case 24:
asm(
" sub %%ebx, %%ecx \n" // sub ecx, ebx
" add %%esi, %%edi \n" // add edi, esi
" add %%ebx, %%ebx \n" // add ebx, ebx - pix size
" inc %%ecx \n" // inc ecx
" add %%edx, %%ebx \n" // add ebx, edx - pix size
" add %%ebx, %%edi \n" // add edi, ebx
" mov %%eax, %%ebx \n" // mov ebx, eax
" shr $16, %%ebx \n" // shr ebx, 16
"hLlop24: \n"
" mov %%ax, (%%edi) \n" // mov [edi], ax
" mov %%bl, 2(%%edi)\n" // mov [edi+2], bl
" add $3, %%edi \n" // add edi, 3
" dec %%ecx \n" // dec ecx
" jnz hLlop24 \n"
:
: "D" (Buffer), "S" (LineOfs[y]), // %0, %1
"a" (colour), "b" (x1), // %2, %3
"c" (x2), "d" (x1) // %4, %5
);
break;
case 32:
asm(
" sub %%ebx, %%ecx \n" // sub ecx, ebx
" add %%esi, %%edi \n" // add edi, esi
" inc %%ecx \n"
" shl $2, %%ebx \n" // shl ebx, 2
" add %%ebx, %%edi \n" // add edi, ebx
" rep \n"
" stosl \n"
:
: "D" (Buffer), "S" (LineOfs[y]), // %0, %1
"a" (colour), "b" (x1), // %2, %3
"c" (x2) // %4
);
break;
} // switch
return;
} // TGfx0::hLine
void
TGfx0::line(Int32 x1, Int32 y1, Int32 x2, Int32 y2, UInt32 colour) {
if (clipLine(x1,y1,x2,y2)) rawLine(x1,y1,x2,y2,colour);
return;
} // TGfx0::line
void
TGfx0::putPixel(UInt32 x, UInt32 y, UInt32 colour) {
if ((Buffer==NULL) || (LineOfs==NULL)) return;
if (((UInt32)x>MaxX) || ((UInt32)y>MaxY)) return;
switch (BPP) {
case 8:
asm(
// { Calculate offset, prepare the pixel to be drawn }
// " add (%%esi,%%ebx,4), %%edi \n" // add edi, [esi + ebx * 4]
" add %%esi, %%edi \n" // add edi, esi
" mov %3, %%eax \n" // mov eax, colour
" add %%ecx, %%edi \n" // add edi, ecx
// { Draw the pixel }
" mov %%al, (%%edi) \n" // mov [edi], al
:
: "D" (Buffer), "S" (LineOfs[y]), // %0, %1
"c" (x), "m" (colour) // %2, %3
);
break;
case 15:
case 16:
asm(
// { Calculate offset, prepare the pixel to be drawn }
// " add (%%esi,%%ebx,4), %%edi \n" // add edi, [esi + ebx * 4]
" add %%ecx, %%ecx \n" // add ecx, ecx {adjust for pixel size}
" add %%esi, %%edi \n" // add edi, esi
" mov %3, %%eax \n" // mov eax, colour
" add %%ecx, %%edi \n" // add edi, ecx
// { Draw the pixel }
" mov %%ax, (%%edi) \n" // mov [edi], al
:
: "D" (Buffer), "S" (LineOfs[y]), // %0, %1
"c" (x), "m" (colour) // %2, %3
);
break;
case 24:
asm(
// { Calculate offset, prepare the pixel to be drawn }
// " add (%%esi,%%ebx,4),%%edi \n" // add edi, [esi + ebx * 4]
" add %%esi, %%edi \n" // add edi, esi
" add %%ecx, %%edi \n" // add edi, ecx
" add %%ecx, %%edi \n" // add edi, ecx {adjust for pixel size}
" add %%ecx, %%edi \n" // add edi, ecx {adjust for pixel size}
// { Draw the pixel }
" mov %%ax, (%%edi) \n" // mov [edi], ax
" shr $16, %%eax \n" // shr eax, 16
" mov %%al, 2(%%edi)\n" // mov [edi+2],al
:
: "D" (Buffer), "S" (LineOfs[y]), // %0, %1
"c" (x), "a" (colour) // %2, %3
);
break;
case 32:
asm(
// { Calculate offset, prepare the pixel to be drawn }
" shl $2, %%ecx \n" // shl eax, 2 {adjust for pixel size}
" add %%esi, %%edi \n" // add edi, esi
" add %%ecx, %%edi \n" // add edi, ecx
// { Draw the pixel }
" mov %%eax, (%%edi) \n" // mov [edi], eax
:
: "D" (Buffer), "S" (LineOfs[y]), // %0, %1
"c" (x), "a" (colour) // %2, %3
);
} // switch
return;
} // TGfx0::putPixel
void
TGfx0::rawLine(UInt32 x1, UInt32 y1, UInt32 x2, UInt32 y2, UInt32 colour) {
/*
* TGfx0::rawLine()
*
* private method; draws an unclipped line from (x1,y1) to (x2,y2)
*
*/
Int32 tc;
if ((Buffer==NULL) || (LineOfs==NULL)) return;
switch (BPP) {
case 8:
asm(
" mov $1, %%ecx \n" // mov ecx, 1
" bt $15, %%eax \n" // bt eax, 15
" jnc rlxPositive8 \n"
" or $-1, %%ecx \n" // or ecx, -1
" neg %%eax \n" // neg eax
"rlxPositive8: \n"
" add %%eax, %%eax \n" // add eax, eax
" bt $15, %%ebx \n" // bt ebx, 15
" jnc rlyPositive8 \n"
" neg %%edx \n" // neg edx
" neg %%ebx \n" // neg ebx
"rlyPositive8: \n"
" add %%ebx, %%ebx \n" // add ebx, ebx
" cmp %%ebx, %%eax \n" // cmp eax, ebx
" jle rlyGreater8 \n"
" push %%ecx \n" // push ecx
" mov %%eax, %%ecx \n" // mov ecx, eax
" mov %%ebx, %6 \n" // mov tc, ebx
" shr $1, %%ecx \n" // shr ecx, 1
" sub %%ecx, %6 \n" // sub tc, ecx
" pop %%ecx \n" // pop ecx
"rlxTop8: \n"
" push %%eax \n" // push eax
" mov %5, %%eax \n" // mov eax, colour
" mov %%al, (%%edi) \n" // mov [edi], al
" pop %%eax \n" // pop eax
" cmp %%edi, %%esi \n" // cmp esi, edi
" je rlDone8 \n"
" cmp $0, %6 \n" // cmp tc, 0
" jl rlNoAddY8 \n"
" add %%edx, %%edi \n" // add edi, edx
" sub %%eax, %6 \n" // sub tc, eax
"rlNoAddY8: \n"
" add %%ecx, %%edi \n" // add edi, ecx
" add %%ebx, %6 \n" // add tc, ebx
" jmp rlxTop8 \n"
"rlyGreater8: \n"
" push %%ecx \n" // push ecx
" mov %%ebx, %%ecx \n" // mov ecx, ebx
" mov %%eax, %6 \n" // mov tc, eax
" shr $1, %%ecx \n" // shr ecx, 1
" sub %%ecx, %6 \n" // sub tc, ecx
" pop %%ecx \n"
"rlyTop8: \n"
" push %%eax \n" // push eax
" mov %5, %%eax \n" // mov eax, colour
" mov %%al, (%%edi) \n" // mov [edi], al
" pop %%eax \n" // pop eax
" cmp %%edi, %%esi \n" // cmp esi, edi
" je rlDone8 \n"
" cmp $0, %6 \n" // cmp tc, 0
" jl rlNoAddX8 \n"
" add %%ecx, %%edi \n" // add edi, ecx
" sub %%ebx, %6 \n" // sub tc, ebx
"rlNoAddX8: \n"
" add %%edx, %%edi \n" // add edi, edx
" add %%eax, %6 \n" // add tc, eax
" jmp rlyTop8 \n"
"rlDone8: \n"
:
: "D" ((UInt8 *)Buffer+LineOfs[y1]+x1), // %0
"S" ((UInt8 *)Buffer+LineOfs[y2]+x2), // %1
"a" (x2-x1), "b" (y2-y1), // %2, %3
"d" (xRes), "g" (colour), // %4, %5
"g" (tc) // %6
);
break;
case 15:
case 16:
asm(
" mov $1, %%ecx \n" // mov ecx, 1
" bt $15, %%eax \n" // bt eax, 15
" jnc rlxPositive16 \n"
" or $-1, %%ecx \n" // or ecx, -1
" neg %%eax \n" // neg eax
"rlxPositive16: \n"
" add %%eax, %%eax \n" // add eax, eax
" bt $15, %%ebx \n" // bt ebx, 15
" jnc rlyPositive16 \n"
" neg %%edx \n" // neg edx
" neg %%ebx \n" // neg ebx
"rlyPositive16: \n"
" add %%ebx, %%ebx \n" // add ebx, ebx
" cmp %%ebx, %%eax \n" // cmp eax, ebx
" jle rlyGreater16 \n"
" push %%ecx \n" // push ecx
" mov %%eax, %%ecx \n" // mov ecx, eax
" mov %%ebx, %6 \n" // mov tc, ebx
" shr $1, %%ecx \n" // shr ecx, 1
" sub %%ecx, %6 \n" // sub tc, ecx
" pop %%ecx \n" // pop ecx
"rlxTop16: \n"
" push %%eax \n" // push eax
" mov %5, %%eax \n" // mov eax, colour
" mov %%ax, (%%edi) \n" // mov [edi], ax
" pop %%eax \n" // pop eax
" cmp %%edi, %%esi \n" // cmp esi, edi
" je rlDone16 \n"
" cmp $0, %6 \n" // cmp tc, 0
" jl rlNoAddY16 \n"
" add %%edx, %%edi \n" // add edi, edx
" sub %%eax, %6 \n" // sub tc, eax
"rlNoAddY16: \n"
" add %%ecx, %%edi \n" // add edi, ecx
" add %%ecx, %%edi \n" // add edi, ecx - pix size
" add %%ebx, %6 \n" // add tc, ebx
" jmp rlxTop16 \n"
"rlyGreater16: \n"
" push %%ecx \n" // push ecx
" mov %%ebx, %%ecx \n" // mov ecx, ebx
" mov %%eax, %6 \n" // mov tc, eax
" shr $1, %%ecx \n" // shr ecx, 1
" sub %%ecx, %6 \n" // sub tc, ecx
" pop %%ecx \n"
"rlyTop16: \n"
" push %%eax \n" // push eax
" mov %5, %%eax \n" // mov eax, colour
" mov %%ax, (%%edi) \n" // mov [edi], ax
" pop %%eax \n" // pop eax
" cmp %%edi, %%esi \n" // cmp esi, edi
" je rlDone16 \n"
" cmp $0, %6 \n" // cmp tc, 0
" jl rlNoAddX16 \n"
" add %%ecx, %%edi \n" // add edi, ecx
" add %%ecx, %%edi \n" // add edi, ecx - pix size
" sub %%ebx, %6 \n" // sub tc, ebx
"rlNoAddX16: \n"
" add %%edx, %%edi \n" // add edi, edx
" add %%eax, %6 \n" // add tc, eax
" jmp rlyTop16 \n"
"rlDone16: \n"
:
: "D" ((UInt8 *)Buffer+LineOfs[y1]+(x1 << 1)), // %0
"S" ((UInt8 *)Buffer+LineOfs[y2]+(x2 << 1)), // %1
"a" (x2-x1), "b" (y2-y1), // %2, %3
"d" (xRes), "g" (colour), // %4, %5
"g" (tc) // %6
);
break;
case 24:
asm(
" mov $1, %%ecx \n" // mov ecx, 1
" bt $15, %%eax \n" // bt eax, 15
" jnc rlxPositive24 \n"
" or $-1, %%ecx \n" // or ecx, -1
" neg %%eax \n" // neg eax
"rlxPositive24: \n"
" add %%eax, %%eax \n" // add eax, eax
" bt $15, %%ebx \n" // bt ebx, 15
" jnc rlyPositive24 \n"
" neg %%edx \n" // neg edx
" neg %%ebx \n" // neg ebx
"rlyPositive24: \n"
" add %%ebx, %%ebx \n" // add ebx, ebx
" cmp %%ebx, %%eax \n" // cmp eax, ebx
" jle rlyGreater24 \n"
" push %%ecx \n" // push ecx
" mov %%eax, %%ecx \n" // mov ecx, eax
" mov %%ebx, %6 \n" // mov tc, ebx
" shr $1, %%ecx \n" // shr ecx, 1
" sub %%ecx, %6 \n" // sub tc, ecx
" pop %%ecx \n" // pop ecx
"rlxTop24: \n"
" push %%eax \n" // push eax
" mov %5, %%eax \n" // mov eax, colour
" mov %%ax, (%%edi) \n" // mov [edi], ax
" shr $16, %%eax \n" // shr eax, 16
" mov %%al, 2(%%edi)\n" // mov [edi+2],al
" pop %%eax \n" // pop eax
" cmp %%edi, %%esi \n" // cmp esi, edi
" je rlDone24 \n"
" cmp $0, %6 \n" // cmp tc, 0
" jl rlNoAddY24 \n"
" add %%edx, %%edi \n" // add edi, edx
" sub %%eax, %6 \n" // sub tc, eax
"rlNoAddY24: \n"
" add %%ecx, %%edi \n" // add edi, ecx
" add %%ecx, %%edi \n" // add edi, ecx - pix size
" add %%ecx, %%edi \n" // add edi, ecx
" add %%ebx, %6 \n" // add tc, ebx
" jmp rlxTop24 \n"
"rlyGreater24: \n"
" push %%ecx \n" // push ecx
" mov %%ebx, %%ecx \n" // mov ecx, ebx
" mov %%eax, %6 \n" // mov tc, eax
" shr $1, %%ecx \n" // shr ecx, 1
" sub %%ecx, %6 \n" // sub tc, ecx
" pop %%ecx \n"
"rlyTop24: \n"
" push %%eax \n" // push eax
" mov %5, %%eax \n" // mov eax, colour
" mov %%ax, (%%edi) \n" // mov [edi], ax
" shr $16, %%eax \n" // shr eax, 16
" mov %%al, 2(%%edi)\n" // mov [edi+2],al
" pop %%eax \n" // pop eax
" cmp %%edi, %%esi \n" // cmp esi, edi
" je rlDone24 \n"
" cmp $0, %6 \n" // cmp tc, 0
" jl rlNoAddX24 \n"
" add %%ecx, %%edi \n" // add edi, ecx
" add %%ecx, %%edi \n" // add edi, ecx - pix size
" add %%ecx, %%edi \n" // add edi, ecx
" sub %%ebx, %6 \n" // sub tc, ebx
"rlNoAddX24: \n"
" add %%edx, %%edi \n" // add edi, edx
" add %%eax, %6 \n" // add tc, eax
" jmp rlyTop24 \n"
"rlDone24: \n"
:
: "D" ((UInt8 *)Buffer+LineOfs[y1]+(x1*3)), // %0
"S" ((UInt8 *)Buffer+LineOfs[y2]+(x2*3)), // %1
"a" (x2-x1), "b" (y2-y1), // %2, %3
"d" (xRes), "g" (colour), // %4, %5
"g" (tc) // %6
);
break;
case 32:
asm(
" mov $1, %%ecx \n" // mov ecx, 1
" bt $15, %%eax \n" // bt eax, 15
" jnc rlxPositive32 \n"
" or $-1, %%ecx \n" // or ecx, -1
" neg %%eax \n" // neg eax
"rlxPositive32: \n"
" add %%eax, %%eax \n" // add eax, eax
" bt $15, %%ebx \n" // bt ebx, 15
" jnc rlyPositive32 \n"
" neg %%edx \n" // neg edx
" neg %%ebx \n" // neg ebx
"rlyPositive32: \n"
" add %%ebx, %%ebx \n" // add ebx, ebx
" cmp %%ebx, %%eax \n" // cmp eax, ebx
" jle rlyGreater32 \n"
" push %%ecx \n" // push ecx
" mov %%eax, %%ecx \n" // mov ecx, eax
" mov %%ebx, %6 \n" // mov tc, ebx
" shr $1, %%ecx \n" // shr ecx, 1
" sub %%ecx, %6 \n" // sub tc, ecx
" pop %%ecx \n" // pop ecx
"rlxTop32: \n"
" push %%eax \n" // push eax
" mov %5, %%eax \n" // mov eax, colour
" mov %%eax, (%%edi)\n" // mov [edi], eax
" pop %%eax \n" // pop eax
" cmp %%edi, %%esi \n" // cmp esi, edi
" je rlDone32 \n"
" cmp $0, %6 \n" // cmp tc, 0
" jl rlNoAddY32 \n"
" add %%edx, %%edi \n" // add edi, edx
" sub %%eax, %6 \n" // sub tc, eax
"rlNoAddY32: \n"
" add %%ecx, %%edi \n" // add edi, ecx
" add %%ecx, %%edi \n" // add edi, ecx - pix size
" add %%ecx, %%edi \n" // add edi, ecx
" add %%ecx, %%edi \n" // add edi, ecx - pix size
" add %%ebx, %6 \n" // add tc, ebx
" jmp rlxTop32 \n"
"rlyGreater32: \n"
" push %%ecx \n" // push ecx
" mov %%ebx, %%ecx \n" // mov ecx, ebx
" mov %%eax, %6 \n" // mov tc, eax
" shr $1, %%ecx \n" // shr ecx, 1
" sub %%ecx, %6 \n" // sub tc, ecx
" pop %%ecx \n"
"rlyTop32: \n"
" push %%eax \n" // push eax
" mov %5, %%eax \n" // mov eax, colour
" mov %%eax, (%%edi)\n" // mov [edi], eax
" pop %%eax \n" // pop eax
" cmp %%edi, %%esi \n" // cmp esi, edi
" je rlDone32 \n"
" cmp $0, %6 \n" // cmp tc, 0
" jl rlNoAddX32 \n"
" add %%ecx, %%edi \n" // add edi, ecx - pix size
" add %%ecx, %%edi \n" // add edi, ecx
" add %%ecx, %%edi \n" // add edi, ecx - pix size
" add %%ecx, %%edi \n" // add edi, ecx
" sub %%ebx, %6 \n" // sub tc, ebx
"rlNoAddX32: \n"
" add %%edx, %%edi \n" // add edi, edx
" add %%eax, %6 \n" // add tc, eax
" jmp rlyTop32 \n"
"rlDone32: \n"
:
: "D" ((UInt8 *)Buffer+LineOfs[y1]+(x1 << 2)), // %0
"S" ((UInt8 *)Buffer+LineOfs[y2]+(x2 << 2)), // %1
"a" (x2-x1), "b" (y2-y1), // %2, %3
"d" (xRes), "g" (colour), // %4, %5
"g" (tc) // %6
);
break;
} // switch
return;
} // TGfx0::rawLine
UInt32
TGfx0::RGB(UInt8 red, UInt8 green, UInt8 blue) {
UInt32 lastclr;
lastclr=0;
switch (BPP) {
case 8:
asm(
" movl $256,%%ecx \n"
" movl $256*3+1,%%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;
case 15:
case 16:
asm(
" xor %%eax, %%eax \n"
" xor %%ebx, %%ebx \n"
" xor %%ecx, %%ecx \n"
" mov %0, %%al \n" // mov al, red
" mov %3, %%cl \n" // mov cl, RedShifter
" shr %%cl, %%al \n" // shr al, cl
" mov %4, %%cl \n" // mov cl, RedFieldPosition
" shl %%cl, %%eax \n" // shl eax, cl
" mov %%eax, %%ebx \n" // mov ebx, eax
" xor %%eax, %%eax \n" // xor eax, eax
" mov %1, %%al \n" // mov al, green
" mov %5, %%cl \n" // mov cl, GreenShifter
" shr %%cl, %%al \n" // shr al, cl
" mov %6, %%cl \n" // mov cl, GreenFieldPosition
" shl %%cl, %%eax \n" // shl eax, cl
" or %%eax, %%ebx \n" // or eax, ebx
" xor %%eax, %%eax \n" // xor eax, eax
" mov %2, %%al \n" // mov al, blue
" mov %7, %%cl \n" // mov cl, BlueShifter
" shr %%cl, %%al \n" // shr al, cl
" mov %8, %%cl \n" // mov cl, BlueFieldPosition
" shl %%cl, %%eax \n" // shl eax, cl
" or %%ebx, %%eax \n" // or eax, ebx
" mov %%eax, %9 \n" // mov lastclr, eax
:
: "m" (red), "m" (green), "m" (blue), // %0, %1, %2
"m" (RedShifter), "m" (RedFieldPosition), // %3, %4
"m" (GreenShifter), "m" (GreenFieldPosition), // %5, %6
"m" (BlueShifter), "m" (BlueFieldPosition), // %7, %8
"m" (lastclr) // %9
);
break;
case 24:
case 32:
asm(
" xor %%eax, %%eax \n" // xor eax, eax
" xor %%ebx, %%ebx \n" // xor ebx, ebx
" xor %%ecx, %%ecx \n" // xor ecx, ecx
" mov %0, %%al \n" // mov al, red
" mov %3, %%cl \n" // mov cl, RedFieldPosition
" shl %%cl, %%eax \n" // shl eax, cl
" mov %%eax, %%ebx \n" // mov ebx, eax
" xor %%eax, %%eax \n" // xor eax, eax
" mov %1, %%al \n" // mov al, green
" mov %4, %%cl \n" // mov cl, GreenFieldPosition
" shl %%cl, %%eax \n" // shl eax, cl
" or %%eax, %%ebx \n" // or ebx, eax
" xor %%eax, %%eax \n" // xor eax, eax
" mov %2, %%al \n" // mov al, blue
" mov %5, %%cl \n" // mov cl, BlueFieldPosition
" shl %%cl, %%eax \n" // shl eax, cl
" or %%ebx, %%eax \n" // or eax, ebx
" mov %%eax, %6 \n" // mov lastclr, eax
:
: "m" (red), "m" (green), "m" (blue), // %0, %1, %2
"m" (RedFieldPosition), // %3
"m" (GreenFieldPosition), // %4
"m" (BlueFieldPosition), // %5
"m" (lastclr) // %6
);
} // switch
//asm("": "=a" (lastclr));
return lastclr;
} // TGfx0::RGB
void
TGfx0::setRGBPalette(UInt8 colour, UInt8 red, UInt8 green, UInt8 blue) {
if (!pal) return;
pal[colour].red = red;
pal[colour].green = green;
pal[colour].blue = blue;
return;
} // TGfx0::setRGBPalette
void
TGfx0::rect(Int32 x1, Int32 y1, Int32 x2, Int32 y2, UInt32 colour) {
hLine(x1,x2,y1,colour); // Horizline has built in clipping
vLine(x2,y1,y2,colour); // vertline has built in clipping too
vLine(x1,y1,y2,colour);
hLine(x1,x2,y2,colour);
return;
} // TGfx0::rectangle
void
TGfx0::unpackRGB(UInt32 colour, UInt8& red, UInt8& green, UInt8& blue) {
switch (BPP) {
case 8:
if (!pal) {
red = 0;
green = 0;
blue = 0;
return;
}
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);
if ((red) && (RedShifter)) red+=(1 << RedShifter)-1;
if ((green) && (GreenShifter)) green+=(1 << GreenShifter)-1;
if ((blue) && (BlueShifter)) blue+=(1 << BlueShifter)-1;
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
void
TGfx0::vFlip(void) {
return;
} // TGfx0::vFlip
void
TGfx0::vLine(Int32 x, Int32 y1, Int32 y2, UInt32 colour) {
Int32 tmp;
if ((Buffer==NULL) || (LineOfs==NULL)) return;
if ((UInt32)x>MaxX) return;
if (y1>y2) {
tmp= y1;
y1 = y2;
y2 = tmp;
} // if
if (y1<0) y1 = 0;
if (y2>(Int32)MaxY) y2 = MaxY;
if (y2<y1) return;
switch (BPP) {
case 8:
asm(
" add %%esi, %%edi \n" // add edi, esi
" mov %6, %%esi \n" // mov esi, y1
" sub %%esi, %%ecx \n" // sub ecx, esi
" add %%ebx, %%edi \n" // add edi, ebx
" inc %%ecx \n" // inc ecx
"vLlop8: \n"
" mov %%al, (%%edi) \n" // mov [edi], al
" add %%edx, %%edi \n" // add edi, edx
" dec %%ecx \n" // dec ecx
" jnz vLlop8 \n"
:
: "D" (Buffer), "S" (LineOfs[y1]), // %0, %1
"a" (colour), "b" (x), // %2, %3
"c" (y2), "d" (xRes), // %4, %5
"m" (y1) // %6
);
break;
case 15:
case 16:
asm(
" add %%esi, %%edi \n" // add edi, esi
" add %%ebx, %%ebx \n" // add ebx, ebx - pix size
" mov %6, %%esi \n" // mov esi, y1
" sub %%esi, %%ecx \n" // sub ecx, esi
" add %%ebx, %%edi \n" // add edi, ebx
" inc %%ecx \n" // inc ecx
"vLlop16: \n"
" mov %%ax, (%%edi) \n" // mov [edi], ax
" add %%edx, %%edi \n" // add edi, edx
" dec %%ecx \n" // dec ecx
" jnz vLlop16 \n"
:
: "D" (Buffer), "S" (LineOfs[y1]), // %0, %1
"a" (colour), "b" (x), // %2, %3
"c" (y2), "d" (xRes), // %4, %5
"m" (y1) // %6
);
break;
case 24:
asm(
" add %%esi, %%edi \n" // add edi, esi
" mov %%ebx, %%esi \n" // mov esi, ebx - pix size
" add %%ebx, %%ebx \n" // add ebx, ebx - pix size
" add %%esi, %%ebx \n" // add ebx, esi - pix size
" mov %6, %%esi \n" // mov esi, y1
" sub %%esi, %%ecx \n" // sub ecx, esi
" add %%ebx, %%edi \n" // add edi, ebx
" inc %%ecx \n" // inc ecx
" mov %%eax, %%ebx \n" // mov ebx, eax
" shr $16, %%ebx \n" // shr ebx, 16
"vLlop24: \n"
" mov %%ax, (%%edi) \n" // mov [edi], eax
" mov %%bl, 2(%%edi)\n" // mov [edi+2], bl
" add %%edx, %%edi \n" // add edi, edx
" dec %%ecx \n" // dec ecx
" jnz vLlop24 \n"
:
: "D" (Buffer), "S" (LineOfs[y1]), // %0, %1
"a" (colour), "b" (x), // %2, %3
"c" (y2), "d" (xRes), // %4, %5
"m" (y1) // %6
);
break;
case 32:
asm(
" add %%esi, %%edi \n" // add edi, esi
" shl $2, %%ebx \n" // shl ebx, 2 - pix size
" mov %6, %%esi \n" // mov esi, y1
" sub %%esi, %%ecx \n" // sub ecx, esi
" add %%ebx, %%edi \n" // add edi, ebx
" inc %%ecx \n" // inc ecx
"vLlop32: \n"
" mov %%eax, (%%edi)\n" // mov [edi],al
" add %%edx, %%edi \n" // add edi, edx
" dec %%ecx \n" // dec ecx
" jnz vLlop32 \n"
:
: "D" (Buffer), "S" (LineOfs[y1]), // %0, %1
"a" (colour), "b" (x), // %2, %3
"c" (y2), "d" (xRes), // %4, %5
"m" (y1) // %6
);
} // switch
return;
} // TGfx0::vLine
TGfx0::~TGfx0(void) {
if (DataState == og_Owner) {
if (pal!=NULL) free(pal);
if (Buffer!=NULL) free(Buffer);
if (LineOfs!=NULL) free(LineOfs);
} // if datastate
pal = NULL;
LineOfs= NULL;
Buffer = NULL;
bSize = 0;
lSize = 0;
DataState = og_None;
return;
} // TGfx0::~TGfx0
/*
*
* TSCREEN METHODS
*
*/
TScreen::TScreen(void) {
InGraphics = FALSE;
VESARec = NULL;
ModeRec = NULL;
return;
} // TScreen::TScreen
void
TScreen::setupMode(UInt16 mode) {
UInt32 size, count;
// IsVesaInstalled();
if (mode==gm320x200x256) {
xRes = 320;
yRes = 200;
MaxX = 319;
MaxY = 199;
BPP = 8;
Buffer = (void *)0xA0000;
RedFieldPosition = 0;
GreenFieldPosition = 0;
BlueFieldPosition = 0;
RedShifter = 0;
GreenShifter = 0;
BlueShifter = 0;
} // if
else {
mode |= 0x4000; // attempt lfb
// GetModeInfo(mode);
// mjikaboom
ModeRec = (TMode_Rec *)0x1000;
if (ModeRec->PhysBasePtr == 0) return;
size = ModeRec->yRes*ModeRec->BytesPerLine;
// Buffer = MapPhysicalToLinear(ModeRec->PhysBasePtr,size);
// mjikaboom
Buffer = (void *)0x40000000;
xRes = ModeRec->BytesPerLine;
yRes = ModeRec->yRes;
MaxX = ModeRec->xRes-1;
MaxY = yRes-1;
RedFieldPosition = ModeRec->RedFieldPosition;
GreenFieldPosition = ModeRec->GreenFieldPosition;
BlueFieldPosition = ModeRec->BlueFieldPosition;
RedShifter = 8-ModeRec->RedMaskSize;
GreenShifter = 8-ModeRec->GreenMaskSize;
BlueShifter = 8-ModeRec->BlueMaskSize;
BPP = ModeRec->BitsPerPixel;
} // else
Owner = this;
DataState = og_Aliasing;
InGraphics = TRUE;
if ((LineOfs!=NULL) && (lSize!=0)) free(LineOfs);
lSize = yRes*sizeof(UInt32);
LineOfs = (UInt32*)malloc(lSize);
if (LineOfs == NULL) return;
LineOfs[0] = 0;
for (count=1; count<=yRes-1; count++)
LineOfs[count] = LineOfs[count-1]+xRes;
// InitVESAMode(mode);
if (pal==NULL) pal = (TRGB*)malloc(256*sizeof(TRGB));
// getPal();
return;
} // TScreen::setupMode
TScreen::~TScreen(void) {
return;
}