/******************************************************* $Id$ *******************************************************/ #include "objgfx30.h" #include <stdlib.h> #include <string.h> #include <stdio.h> #include <ubixos/types.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::alias(TGfx0* SrcObject, UInt32 x1, UInt32 y1, UInt32 x2, UInt32 y2) { UInt32 tmp; printf("in alias\n"); 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; return TRUE; } // TGfx0::alias void TGfx0::arc(UInt32 x_center, UInt32 y_center, UInt32 radius, UInt32 s_angle, UInt32 e_angle, UInt32 colour) { } // 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++) horizLine(x1,x2,yy,colour); } // TGfx0::bar void TGfx0::circle(Int32 x_center, Int32 y_center, UInt32 radius, UInt32 colour) { } // 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 void TGfx0::clone(TGfx0* SrcObject) { } // TGfx0::clone 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) 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; memset(Buffer,0,bSize); lSize = _yRes*sizeof(UInt32); LineOfs = (UInt32*)malloc(lSize); if (!LineOfs) return FALSE; pal = (TRGB*)malloc(256*sizeof(TRGB)); if (!pal) 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 void TGfx0::copy(TGfx0* SrcObject) { UInt32 count, xCount, yCount; UInt32 xx, yy; UInt8 r, g, b; if (Buffer==NULL) return; if (SrcObject->Buffer==NULL) 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::copy UInt32 TGfx0::getMaxX(void) { return MaxX; } // TGfx0::getMaxX UInt32 TGfx0::getMaxY(void) { return MaxY; } // TGfx0::getMaxY UInt32 TGfx0::getPixel(UInt32 x, UInt32 y) { UInt32 result; result = 42; if ((Buffer==NULL) || (LineOfs==NULL)) return TransparentColor; if ((x<0) || (x>MaxX) || (y<0) || y>MaxY) return TransparentColor; switch (BPP) { case 8: asm( " add (%%esi,%%ebx,4), %%edi \n" // add edi, [esi + ebx*4] " add %%ecx, %%edi \n" // add edi, ecx " movzbl (%%edi),%%eax \n" // edx,byte ptr [edi] " mov %%eax, %4 \n" // mov result, eax : : "D" (Buffer), "S" (LineOfs), // %0, %1 "c" (x), "b" (y), // %2, %3 "m" (result) // %4 ); break; case 15: case 16: asm( " add %%ecx, %%ecx \n" // add ecx, ecx {adjust for pixel size} " 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] " mov %%eax, %4 \n" // mov result, eax : : "D" (Buffer), "S" (LineOfs), // %0, %1 "c" (x), "b" (y), // %2, %3 "m" (result) // %4 ); 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,%%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, %4 \n" // mov result, eax : : "D" (Buffer), "S" (LineOfs), // %0, %1 "c" (x), "b" (y), // %2, %3 "m" (result) // %4 ); 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 %%ecx, %%edi \n" // add edi, ecx " mov (%%edi),%%eax \n" // eax,word ptr [edi] " mov %%eax, %4 \n" // mov result, eax : : "D" (Buffer), "S" (LineOfs), // %0, %1 "c" (x), "b" (y), // %2, %3 "m" (result) // %4 ); } // switch return result; } // TGfx0::getPixel void TGfx0::horizLine(Int32 x1, Int32 x2, Int32 y, UInt32 colour) { } // TGfx0::horizLine void TGfx0::putPixel(UInt32 x, UInt32 y, UInt32 colour) { if ((Buffer==NULL) || (LineOfs==NULL)) return; if ((x<0) || (x>MaxX) || (y<0) || 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] " mov %4, %%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), // %0, %1 "c" (x), "b" (y), // %2, %3 "m" (colour) // %4 ); 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} " mov %4, %%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), // %0, %1 "c" (x), "b" (y), // %2, %3 "m" (colour) // %4 ); break; case 24: asm( // { Calculate offset, prepare the pixel to be drawn } " add (%%esi,%%ebx,4),%%edi \n" // add edi, [esi + ebx * 4] " 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), // %0, %1 "c" (x), "b" (y), // %2, %3 "a" (colour) // %4 ); 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,%%ebx,4),%%edi \n" // add edi, [esi + ebx * 4] " add %%ecx, %%edi \n" // add edi, ecx // { Draw the pixel } " mov %%eax, (%%edi) \n" // mov [edi], eax : : "D" (Buffer), "S" (LineOfs), // %0, %1 "c" (x), "b" (y), // %2, %3 "a" (colour) // %4 ); } // switch return; } // TGfx0::putPixel 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::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 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()