#include "StdAfx.h" #include #include #include // important constants const float PI = 3.14159f; //5358979; const float Trans=(3.14159535 / 180);//Convert to radians becase te computer can not read degrees const float Pd2=(3.14159535 / 2);//Same // generate monocrome mask... void _stdcall MakeMask(HDC srcHDC, long cWidth, long cHeight, HDC destHDC, long srcX, long srcY, unsigned long transColor, long MtColor,long MoColor) { for (long y=0;y<=cHeight;y++) { //begin loop for (long x=0;x<=cWidth;x++) { // for each pixel.. if (GetPixel(srcHDC,x,y)==transColor) //we have a transparent pixel SetPixelV(destHDC,x,y,MtColor); else //non-transparent pixel SetPixelV(destHDC,x,y,MoColor); } //end loop 1 } // end loop 2 } // 2D distance Calculation float _stdcall Distance2D (int x1, int y1, int x2, int y2) { int dx = (x1 - x2), dy = (y1 - y2); return (float)sqrt(dx * dx + dy * dy); } //End Function // 3D distance calculation... float _stdcall Distance3D (int x1, int y1, int z1, int x2, int y2, int z2) { int dx = (x1 - x2), dz = (z1 - z2), dy = (y1 - y2); return (float)sqrt(dx * dx + dy * dy + dz * dz); } // End Function // rotation (fast) void _stdcall RotateAA (HDC HdestDC, HDC HsrcDC, long int srcW, long int srcH, long int destW, long int destH, long int theta) { // HsrcDC is the source HDC (in c++ this isn't a long, its an HDC) // HdestDC is the destination HDC (same thing goes here too) // srcW is the width, in pixels of the source image // srcH is the height, in pixels of the source image // destW is the width, in pixels, of the destination DC // destH is the height, in pixels, of the destination DC // theta is the angle of rotation long int c1x=(srcW / 2); long int c1y=(srcH / 2); long int c2x=(destW / 2); long int c2y=(destH / 2); long int n=0; float p1x = 0; float p1y = 0; float p2x = 0; float p2y = 0; float a=0; float r=0; double thet2 = (theta * Trans); float ApT2=0; // the following are colors (note for when porting to C++, these should be declared as ColorRef) COLORREF c0=0; COLORREF c1=0; COLORREF c2=0; COLORREF c3=0; // start actual code, done declaring vars //========================================================== //If c2x < c2y Then n = c2y Else n = c2x if (c2x < c2y) n = c2y; else n = c2x; n = ((n - 1) * 2) / 2; //For p2x = 0 To n for (p2x=0;p2x<=n;p2x++) { // begin loop... //For p2y = 0 To n for (p2y=0;p2y<=n;p2y++) { // begin inner loop //If p2x = 0 Then a = Pd2 Else a = Atn(p2y / p2x) if (p2x==0) a = Pd2; else a = atan(p2y / p2x); //r = Sqr(p2x * p2x + p2y * p2y) r = sqrt(p2x * p2x + p2y * p2y); // ApT = (a + thet2) // p1x = r * Cos(ApT) 'used to be (a + theta) written twice // p1y = r * Sin(ApT) ApT2 = (a + thet2); p1x = r * cos(ApT2); p1y = r * sin(ApT2); //retrieve pixel color c0 = GetPixel(HsrcDC, (c1x + p1x), (c1y + p1y)); c1 = GetPixel(HsrcDC, (c1x - p1x), (c1y - p1y)); c2 = GetPixel(HsrcDC, (c1x + p1y), (c1y - p1x)); c3 = GetPixel(HsrcDC, (c1x - p1y), (c1y + p1x)); // set pixel color if needed if (c0!=-1) SetPixelV(HdestDC, c2x + p2x, c2y + p2y, c0); if (c1!=-1) SetPixelV(HdestDC, c2x - p2x, c2y - p2y, c1); if (c2!=-1) SetPixelV(HdestDC, c2x + p2y, c2y - p2x, c2); if (c3!=-1) SetPixelV(HdestDC, c2x - p2y, c2y + p2x, c3); } // end nested for loop } // end outer for loop... } void __stdcall GEpixelate (HDC hSrcDC, long srcWidth, long srcHeight, long CellSize, HDC hDestDC) { // ((srcWidth + (CellDiam \ 2)) \ CellDiam) * CellDiam long maxX=((srcWidth + (CellSize / 2)) / CellSize) * CellSize; long maxY=((srcHeight + (CellSize / 2)) / CellSize) * CellSize; long CpX=0; //This following statement should be called //before executing this function: // DeleteObject(SelectObject(hDestDC,CreatePen(5,1,0))); for (long x = 0; x <= maxX; x += CellSize) { //begin loop CpX = (x + CellSize + 1); for (long y = 0; y <= maxY; y += CellSize) { //begin inner loop DeleteObject(SelectObject(hDestDC,CreateSolidBrush(GetPixel(hSrcDC,x,y)))); //Rectangle hdcDest, Xc, Yc, CpX, Yc + CellDiam + 1 Rectangle(hDestDC,x,y,CpX,(y + CellSize + 1)); } // end inner loop } // end outer loop } void __stdcall GERotateSprite (HANDLE hDIB, HANDLE hDIBd, char* bSrcBytes, long SRCbyteCount, HDC hDestDC, char* bDestBytes, long DESTbyteCount, long Angle) { // long int SH=(*SRCbi24BitInfo).bmiHeader.biHeight; // long int SW=(*SRCbi24BitInfo).bmiHeader.biWidth; // long int DH=(*DESTbi24BitInfo).bmiHeader.biHeight; // long int DW=(*DESTbi24BitInfo).bmiHeader.biWidth; // This lets us use the bitmapinfo from the DIB handle BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ; BITMAPINFO &bmInfoD = *(LPBITMAPINFO)hDIBd ; char* SBO = bSrcBytes; //original values of pointers (to reference back to the beggining of the array) char* DBO = bDestBytes; long int c1x = bmInfo.bmiHeader.biWidth / 2; long int c1y= bmInfo.bmiHeader.biHeight / 2; long int c2x= bmInfoD.bmiHeader.biWidth / 2; long int c2y= bmInfoD.bmiHeader.biHeight / 2; long int n=((c1x - 1) * 2) / 2L; float p1x=0; float p1y=0; float p2x=0; float p2y=0; float a=0; float r=0; float theta = (Angle * Trans); float ApT2=0; long int PCoord=0L; long int PCoord2=0L; //For p2x = 0 To n for (p2x=0;p2x<=n;p2x++) { // begin loop... //For p2y = 0 To n for (p2y=0;p2y<=n;p2y++) { // begin inner loop //If p2x = 0 Then a = Pd2 Else a = Atn(p2y / p2x) if (p2x==0) a = Pd2; else a = atan(p2y / p2x); //r = Sqr(p2x * p2x + p2y * p2y) r = sqrt(p2x * p2x + p2y * p2y); // ApT = (a + theta) // p1x = r * Cos(ApT) 'used to be (a + theta) written twice // p1y = r * Sin(ApT) ApT2 = (a + theta); p1x = r * cos(ApT2); p1y = r * sin(ApT2); // 'BOTTOM-RIGHT PCoord = ((( bmInfo.bmiHeader.biHeight - (c1y + p1y)) * bmInfo.bmiHeader.biHeight + (c1x + p1x)) * 3) - 2; if(((PCoord + 1) < SRCbyteCount) && (PCoord > 0)) { //move to pixel position in array, start at blue byte bDestBytes += (long)(((bmInfoD.bmiHeader.biHeight - (c2y + p2y + 1)) * bmInfoD.bmiHeader.biHeight + (c2x + p2x)) * 3) + 1; bSrcBytes += PCoord; //Use memcpy to copy one pointer to another //set blue byte memcpy(bDestBytes,bSrcBytes,strlen(bSrcBytes)+1); //blue //move to green byte bDestBytes++; bSrcBytes++; //set green byte memcpy(bDestBytes,bSrcBytes,strlen(bSrcBytes)+1); //green //move to red byte bDestBytes++; bSrcBytes++; //set red byte memcpy(bDestBytes,bSrcBytes,strlen(bSrcBytes)+1); //red } //reset pointers to the beggining of the array bDestBytes = DBO; bSrcBytes = SBO; //TOP-LEFT PCoord = (((bmInfo.bmiHeader.biHeight - (c1y - p1y)) * bmInfo.bmiHeader.biHeight + (c1x - p1x)) * 3) - 2; if(((PCoord + 1) < SRCbyteCount) && (PCoord > 0)) { bDestBytes += (long)(((bmInfoD.bmiHeader.biHeight - (c2y - p2y)) * bmInfoD.bmiHeader.biHeight + (c2x - p2x)) * 3) - 2; bSrcBytes += PCoord; //set blue byte memcpy(bDestBytes,bSrcBytes,strlen(bSrcBytes)+1); //blue //move to green byte bDestBytes++; bSrcBytes++; //set green byte memcpy(bDestBytes,bSrcBytes,strlen(bSrcBytes)+1); //green //move to red byte bDestBytes++; bSrcBytes++; //set red byte memcpy(bDestBytes,bSrcBytes,strlen(bSrcBytes)+1); //red } //reset pointers to the beggining of the array bDestBytes = DBO; bSrcBytes = SBO; //TOP-RIGHT PCoord = (((bmInfo.bmiHeader.biHeight - (c1y - p1x)) * bmInfo.bmiHeader.biHeight + (c1x + p1y)) * 3) - 2; if(((PCoord + 1) < SRCbyteCount) && (PCoord > 0)) { bDestBytes += (long)(((bmInfoD.bmiHeader.biHeight - (c2y - p2x)) * bmInfoD.bmiHeader.biHeight + (c2x + p2y)) * 3) + 1; bSrcBytes += PCoord; //set blue byte memcpy(bDestBytes,bSrcBytes,strlen(bSrcBytes)+1); //blue //move to green byte bDestBytes++; bSrcBytes++; //set green byte memcpy(bDestBytes,bSrcBytes,strlen(bSrcBytes)+1); //green //move to red byte bDestBytes++; bSrcBytes++; //set red byte memcpy(bDestBytes,bSrcBytes,strlen(bSrcBytes)+1); //red } //reset pointers to the beggining of the array bDestBytes = DBO; bSrcBytes = SBO; //BOTTOM-LEFT PCoord = (((bmInfo.bmiHeader.biHeight - (c1y + p1x)) * bmInfo.bmiHeader.biHeight + (c1x - p1y)) * 3) - 2; if(((PCoord + 1) < SRCbyteCount) && (PCoord > 0)) { bDestBytes += (long)(((bmInfoD.bmiHeader.biHeight - (c2y + p2x + 1)) * bmInfoD.bmiHeader.biHeight + (c2x - p2y)) * 3) - 2; bSrcBytes += PCoord; //set blue byte memcpy(bDestBytes,bSrcBytes,strlen(bSrcBytes)+1); //blue //move to green byte bDestBytes++; bSrcBytes++; //set green byte memcpy(bDestBytes,bSrcBytes,strlen(bSrcBytes)+1); //green //move to red byte bDestBytes++; bSrcBytes++; //set red byte memcpy(bDestBytes,bSrcBytes,strlen(bSrcBytes)+1); //red } } //end inner loop } //end outer loop //LPVOID lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors); SetDIBitsToDevice(hDestDC, 0, 0, bmInfo.bmiHeader.biWidth, bmInfo.bmiHeader.biHeight, 0, 0, 0, bmInfo.bmiHeader.biHeight, bDestBytes, (LPBITMAPINFO)hDIB, 0); } //Function to rotate any sprite using the DIB, will rotate by bytes(not sure if thats right) //Function DIB_rotate Converted by Josh Nixon and Created by Tim Miron void _stdcall DIB_rotate(BITMAPINFO SRCbi24BitInfo, unsigned char bSrcBytes[], long SRCbyteCount, HDC hDestDC, BITMAPINFO DESTbi24BitInfo, unsigned char bDestBytes[], long DESTbyteCount, long angle) //Begin functions code { //_______________________________________________________________________________________________ //Things that should be done by the owner program: //EG. //BITMAPINFO bitmap; // gets passed to this function as SRCbi24BitInfo //iDC = CreateCompatibleDC(0); //iBitmap = CreateDIBSection(iDC, bitmap, DIB_RGB_COLORS, ByVal 0&, ByVal 0&, ByVal 0&); //SelectObject iDC, iBitmap; //________________________________________________________________________________________________ //IDC and iBitmap are not needed by this function // because it bypasses that layer of the GDI and // only deals with the bitarray, HOWEVER - IMPORTANT: // that last step of creating the diBitmap object // and selecting it into the source DC is VERY important! // or else it wont work: NOTE: use DeleteObject and // deleteDC to delete the source & destination diBitmap // objects aswell as the DC... //retrieve source bits //GetDIBits iDC, iBitmap, 0, bitmap.bmiHeader.biHeight, bBytes(1), bitmap, DIB_RGB_COLORS //bBytes() is passed to us as BsrcBYTES() //_________________________________________________________________________________________ //do the same thing for the destination buffer //note for C++ porting: same variable declaration as //the first rotation sub, but plus the definition of bbytes! long c1x = 0.0, c1y = 0.0; long c2x = 0.0, c2y = 0.0; short a = 0.0; long p1x = 0.0,p1y = 0.0; long p2x = 0.0, p2y = 0.0; long n = 0.0, double R = 0.0; short theta = 0.0; // this is angle * trans short ApT2 = 0.0; //A + theta (value=0 at declaration) long PCoord = 0.0, PCoord2 = 0.0; // MUCH OF THE BELOW VARIABLE SETUP //CAN BE THE EXACT SAME AS IN THE EARLIER //C++ VERSION OF THIS FUNCTION... //IMPORTANT NOTICE, THE COLORS ARE NOT COLORREFS ANYMORE! //DOWN TO THE SETUP OF N theta=angle * Trans; theta = (angle * Trans); // Correct != is the same as <> //these can also be calculated when declared //(center of destination) c1x = (SRCbi24BitInfo.bmiHeader.biWidth / 2); c1y = (SRCbi24BitInfo.bmiHeader.biHeight / 2); c2x = (DESTbi24BitInfo.bmiHeader.biWidth / 2); c2y = (DESTbi24BitInfo.bmiHeader.biHeight / 2); n = (c1x - 1);// / 2 // n = (c1x - 1) / 2 //##### //n is used to determine when the for loops //including the nested loop should end... //THE END OF THE SETUP OF VARIABLES for (p2x = 0; p2x <= n; p2x++){//Begin outter loop for (p2y = 0; p2y <= n; p2y++){//Begin nested loop if (p2x = 0) a = Pd2; else { //TO BE optimzed by Tim on a later date a = atan(p2y / p2x); //in c++ this = atan; //r = Sqr(1 * p2x * p2x + 1 * p2y * p2y) R = sqrt((p2x * p2x) + (p2y * p2y)); //minor optimization (avoid doing the same calculation twice) // NOTE: this value can NOT be set when its declared // because the value of A changes in every cycle of this loop ApT2 = (a + theta); p1x = R * cos(ApT2); //used to be (a + theta) written twice p1y = R * sin(ApT2); //retrieve pixel color //c0& = GetPixel(HsrcDC, c1x + p1x, c1y + p1y) //BOTTOM-RIGHT PCoord = (((SRCbi24BitInfo.bmiHeader.biHeight - (c1y + p1y)) * SRCbi24BitInfo.bmiHeader.biHeight + (c1x + p1x)) * 3) - 2; if ( (PCoord + 1) < SRCbyteCount && (PCoord > 0)) { //by eliminating these in-between //variables C0[r][g][b] //we eliminate 3 copy operators //per pixel, AND 9 variable declarations, //AND we avoid processing any pixels outside //of the rotation's 'edges'.. //(however, that may cause some problems //and actually make thigns take longer //if the program has to use a bigger //sprite just to make sure there's enough //padding to fill the edges properly, so I //am questioning whether to keep this or not?) PCoord2 = (((DESTbi24BitInfo.bmiHeader.biHeight - (c2y + p2y + 1)) * DESTbi24BitInfo.bmiHeader.biHeight + (c2x + p2x)) * 3) + 1; bDestBytes[PCoord2] = bSrcBytes[PCoord]; //blue bDestBytes[PCoord2 + 1] = bSrcBytes[PCoord + 1]; //green bDestBytes[PCoord2 + 2] = bSrcBytes[PCoord + 2]; //red }//end if //Top Left PCoord = (((SRCbi24BitInfo.bmiHeader.biHeight - (c1y - p1y)) * SRCbi24BitInfo.bmiHeader.biHeight + (c1x - p1x)) * 3) - 2; if ( (PCoord + 1) < SRCbyteCount && (PCoord > 0) ) { //TOP-LEFT PCoord2 = (((DESTbi24BitInfo.bmiHeader.biHeight - (c2y - p2y)) * DESTbi24BitInfo.bmiHeader.biHeight + (c2x - p2x)) * 3) - 2; bDestBytes[PCoord2] = bSrcBytes[PCoord]; //blue bDestBytes[PCoord2 + 1] = bSrcBytes[PCoord + 1]; //green bDestBytes[PCoord2 + 2] = bSrcBytes[PCoord + 2]; //red }//end if //top-right PCoord = (((SRCbi24BitInfo.bmiHeader.biHeight - (c1y - p1x)) * SRCbi24BitInfo.bmiHeader.biHeight + (c1x + p1y)) * 3) - 2; if ( (PCoord + 1) < SRCbyteCount && (PCoord > 0)) { //TOP RIGHT PCoord2 = (((DESTbi24BitInfo.bmiHeader.biHeight - (c2y - p2x)) * DESTbi24BitInfo.bmiHeader.biHeight + (c2x + p2y)) * 3) + 1; bDestBytes[PCoord2] = bSrcBytes[PCoord]; //blue bDestBytes[PCoord2 + 1] = bSrcBytes[PCoord + 1]; //green bDestBytes[PCoord2 + 2] = bSrcBytes[PCoord + 2]; //red }//end if //bottom-left! PCoord = (((SRCbi24BitInfo.bmiHeader.biHeight - (c1y + p1x)) * SRCbi24BitInfo.bmiHeader.biHeight + (c1x - p1y)) * 3) - 2; if ( (PCoord + 1) < SRCbyteCount && (PCoord > 0)) { //BOTTOM-LEFT PCoord2 = (((DESTbi24BitInfo.bmiHeader.biHeight - (c2y + p2x + 1)) * DESTbi24BitInfo.bmiHeader.biHeight + (c2x - p2y)) * 3) - 2; bDestBytes[PCoord2] = bSrcBytes[PCoord]; //blue bDestBytes[PCoord2 + 1] = bSrcBytes[PCoord + 1]; //green bDestBytes[PCoord2 + 2] = bSrcBytes[PCoord + 2]; //red }//end if }//end nested loop }//end outer loop //changed index number of bits from 1 to 0 SetDIBitsToDevice(hDestDC, 0, 0, SRCbi24BitInfo.bmiHeader.biWidth, SRCbi24BitInfo.bmiHeader.biHeight, 0, 0, 0, SRCbi24BitInfo.bmiHeader.biHeight, bDestBytes[1], SRCbi24BitInfo, DIB_RGB_COLORS); } }//End the function