/******************************************************* $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; }