/****************************************************************************\ * * * ENGINE1.CPP - Source Code Module * * * * (c)Copyright 2001 Indotek, LLC. All Rights Reserved. * * * \****************************************************************************/ #define GLOBALS_DEFINED #include "internal.h" D3DMATRIX R3D_STDCALL _r3d_IdentityMatrix(void) { return D3DMATRIX(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0); } D3DMATRIX R3D_STDCALL _r3d_ZeroMatrix(void) { D3DMATRIX ret; for (int i = 0;i < 4;i++) for (int j = 0;j < 4;j++) ret(i, j) = 0.0f; return ret; } // near_plane, // distance to near clipping plane // far_plane, // distance to far clipping plane // fov_horiz, // horizontal field of view angle, in radians // float fov_vert, // vertical field of view angle, in radians D3DMATRIX R3D_STDCALL _r3d_ProjectionMatrix(double near_plane, double far_plane, double fov) { double fov_horiz, aspect_ratio, x, z; float h, w, Q; #define cot(a) (1.0/tan((a))) aspect_ratio = (double)_r3d_dwRenderHeight / (double)_r3d_dwRenderWidth; if (_r3d_gbWindowed == TRUE) { // Constrain to Max Vertical and Horizontal FOV if (aspect_ratio <= 0.75) { fov_horiz = fov * 0.5F; } else { // Height is greater than width for a 0.75 aspect ratio. // We will base fov_horiz on aspect ratio fov_horiz = ((fov * 0.75F) / aspect_ratio) * 0.5F; } } else fov_horiz = fov * 0.5F; x = sin(fov_horiz); z = cos(fov_horiz); if (_r3d_gbWindowed == TRUE) x *= aspect_ratio; else x *= 0.75; w = (float)cot(fov_horiz); h = (float)(z / x); Q = (float)(far_plane / (far_plane - near_plane)); D3DMATRIX ret = _r3d_ZeroMatrix(); ret(0, 0) = w; ret(1, 1) = h; ret(2, 2) = Q; ret(3, 2) = (float)(-Q * near_plane); ret(2, 3) = 1; return ret; } int R3D_STDCALL r3d_MessageBox(LPCTSTR lpMessage, LPCTSTR lpTitle, UINT uType) { int returnval; // Need to end a potential 3D render state if (_r3d_bInsideRenderBeginEnd == TRUE) _r3d_Device->EndScene(); // Neccessary even on 3DFX if (_r3d_DirectDraw4 != NULL) _r3d_DirectDraw4->FlipToGDISurface(); //return (MessageBox(_r3d_ghWnd, lpMessage, lpTitle, uType|MB_DEFAULT_DESKTOP_ONLY)); returnval = MessageBox(_r3d_ghWnd, lpMessage, lpTitle, uType | MB_SYSTEMMODAL); if (_r3d_bInsideRenderBeginEnd == TRUE) _r3d_Device->BeginScene(); return returnval; } BOOL R3D_STDCALL r3d_SurfaceDestroyAll(void) { int LoopVar; // We loop through all allocated surfaces // and delete all. for (LoopVar = 0;LoopVar < _R3D_MAX_SURFACES;LoopVar++) { r3d_SurfaceDestroy(LoopVar); // Ignore errors! } return TRUE; } BOOL R3D_STDCALL r3d_SurfaceDestroy(int handle) { if (_r3d_bSurfaceDoesNotExist[handle] == TRUE) { _r3d_FormulateErrorString("r3d_SurfaceDestroy", "Invalid Surface Handle", DD_OK); return FALSE; } _R3D_DELETE(_r3d_Surface[handle]->RGBA); _R3D_DELETE(_r3d_Surface[handle]); _r3d_bSurfaceDoesNotExist[handle] = TRUE; return TRUE; } BOOL R3D_STDCALL r3d_SurfaceCreate(int *handle, int Width, int Height) { int LoopVar; for (LoopVar = 0;LoopVar < _R3D_MAX_SURFACES;LoopVar++) { if (_r3d_bSurfaceDoesNotExist[LoopVar] == TRUE) { // Allocate Surface Structure Memory if (NULL == (_r3d_Surface[LoopVar] = new _R3D_SURFACE)) { _r3d_FormulateErrorString("r3d_SurfaceCreate", "Can not allocate memory", DD_OK); return FALSE; } // Allocate Surface Memory if (NULL == (_r3d_Surface[LoopVar]->RGBA = new unsigned char[Width * Height*4])) { //_R3D_DELETE(_r3d_Surface[LoopVar]); _r3d_FormulateErrorString("r3d_SurfaceCreate", "Can not allocate memory", DD_OK); return FALSE; } _r3d_bSurfaceDoesNotExist[LoopVar] = FALSE; _r3d_Surface[LoopVar]->dwWidth = (DWORD)Width; _r3d_Surface[LoopVar]->dwHeight = (DWORD)Height; *handle = LoopVar; break; } } // Let's initialize the alpha channel to 255 and the // set the background color to black. unsigned long *SurfaceRGBA, dwColor; SurfaceRGBA = (unsigned long *)r3d_SurfaceGet(*handle); dwColor = r3d_SurfaceColorMakeRGBA(0, 0, 0, 255); //memset(SurfaceRGBA,dwColor,(Width*Height)); for (LoopVar = 0;LoopVar < (Width * Height);LoopVar++) SurfaceRGBA[LoopVar] = dwColor; return TRUE; } BOOL R3D_STDCALL _r3d_BMPGetInfo(char *pFilename, char *FunctionNameString, DWORD *BMPWidth, DWORD *BMPHeight, BOOL *bPalette256) { HANDLE hTemp; char buffer[512]; BITMAPFILEHEADER bFileHead; BITMAPINFOHEADER bFileInfo; if ((hTemp = r3d_FileOpen(pFilename, R3D_READ)) == INVALID_HANDLE_VALUE) { sprintf(buffer, "Can not load %s", pFilename); _r3d_FormulateErrorString(FunctionNameString, buffer, DD_OK); return FALSE; } if (r3d_FileRead(hTemp, &bFileHead, sizeof(bFileHead)) == FALSE) { sprintf(buffer, "%s: Error reading file", pFilename); _r3d_FormulateErrorString(FunctionNameString, buffer, DD_OK); return FALSE; } if (r3d_FileRead(hTemp, &bFileInfo, sizeof(bFileInfo)) == FALSE) { sprintf(buffer, "%s: Error reading file", pFilename); _r3d_FormulateErrorString(FunctionNameString, buffer, DD_OK); return FALSE; } if (bFileInfo.biBitCount != 8 && bFileInfo.biBitCount != 24) // Stored as B,G, and R, respectively { // Not 8 or 24 bit sprintf(buffer, "%s : Not a 256 color or 24-bit BMP", pFilename); _r3d_FormulateErrorString(FunctionNameString, buffer, DD_OK); r3d_FileClose(hTemp); return FALSE; } if (bFileInfo.biCompression != BI_RGB) { // Not an uncompressed bitmap sprintf(buffer, "%s : Not an uncompressed BMP", pFilename); _r3d_FormulateErrorString(FunctionNameString, buffer, DD_OK); r3d_FileClose(hTemp); return FALSE; } r3d_FileClose(hTemp); //hmmmm... why is this not working.... if (bFileInfo.biBitCount == 8) *bPalette256 = TRUE; else //if (bFileInfo.biBitCount==24) *bPalette256 = FALSE; *BMPWidth = (DWORD)bFileInfo.biWidth; *BMPHeight = (DWORD)bFileInfo.biHeight; return TRUE; } BOOL R3D_STDCALL _r3d_BMPLoad(char *pFilename, char *FunctionNameString, unsigned char *pBGRImage, unsigned char *p256Image) { HANDLE hTemp; char buffer[512]; BITMAPFILEHEADER bFileHead; BITMAPINFOHEADER bFileInfo; RGBQUAD Palette[256]; int counter, LoopVar; unsigned long dwPaddedBytes; // A DIB consists of two parts: a BITMAPCOREINFO structure describing // the dimensions and colors of the bitmap, and an array of bytes // defining the pixels of the bitmap. The bits in the array are packed // together, but each scan line must be padded with zeroes to end on a // LONG boundary. The origin of the bitmap is the lower left corner. // First, let's load the bitmap to our temporary buffer if ((hTemp = r3d_FileOpen(pFilename, R3D_READ)) == INVALID_HANDLE_VALUE) { sprintf(buffer, "Can not load %s", pFilename); _r3d_FormulateErrorString(FunctionNameString, buffer, DD_OK); return FALSE; } if (r3d_FileRead(hTemp, &bFileHead, sizeof(bFileHead)) == FALSE) { sprintf(buffer, "%s: Error reading file", pFilename); _r3d_FormulateErrorString(FunctionNameString, buffer, DD_OK); return FALSE; } if (r3d_FileRead(hTemp, &bFileInfo, sizeof(bFileInfo)) == FALSE) { sprintf(buffer, "%s: Error reading file", pFilename); _r3d_FormulateErrorString(FunctionNameString, buffer, DD_OK); return FALSE; } if (bFileInfo.biBitCount != 8 && bFileInfo.biBitCount != 24) // Stored as B,G, and R, respectively { // Not 8 or 24 bit sprintf(buffer, "%s : Not a 256 color or 24-bit BMP", pFilename); _r3d_FormulateErrorString(FunctionNameString, buffer, DD_OK); r3d_FileClose(hTemp); return FALSE; } if (bFileInfo.biCompression != BI_RGB) { // Not an uncompressed bitmap sprintf(buffer, "%s : Not an uncompressed BMP", pFilename); _r3d_FormulateErrorString(FunctionNameString, buffer, DD_OK); r3d_FileClose(hTemp); return FALSE; } if (bFileInfo.biBitCount == 8) { // We need to read the palette if (r3d_FileRead(hTemp, Palette, (DWORD)(256 * 4)) == FALSE) { sprintf(buffer, "%s: Error reading file", pFilename); _r3d_FormulateErrorString(FunctionNameString, buffer, DD_OK); return FALSE; } // Actual B,G,R Bitmap data may start somewhere other // than you think and is specified in bFileHead.bfOffBits if (r3d_FileSeek(hTemp, bFileHead.bfOffBits, R3D_BEGINNING) == FALSE) { sprintf(buffer, "%s: Error seeking RGB data in file", pFilename); _r3d_FormulateErrorString(FunctionNameString, buffer, DD_OK); return FALSE; } dwPaddedBytes = ((bFileInfo.biWidth * 1) % 4); if (dwPaddedBytes) dwPaddedBytes = 4 - dwPaddedBytes; for (LoopVar = 0;LoopVar < bFileInfo.biHeight;LoopVar++) { if (r3d_FileRead(hTemp, &p256Image[LoopVar * bFileInfo.biWidth], (DWORD)(bFileInfo.biWidth)) == FALSE) { sprintf(buffer, "%s: Error reading file", pFilename); _r3d_FormulateErrorString(FunctionNameString, buffer, DD_OK); return FALSE; } if (dwPaddedBytes && LoopVar < bFileInfo.biHeight - 1) { if (r3d_FileSeek(hTemp, dwPaddedBytes, R3D_CURRENT) == FALSE) { sprintf(buffer, "%s: Error seeking in file", pFilename); _r3d_FormulateErrorString(FunctionNameString, buffer, DD_OK); return FALSE; } } } // Now convert to BGR and store in pBGRImage counter = 0; for (LoopVar = 0;LoopVar < bFileInfo.biWidth * bFileInfo.biHeight;LoopVar++) { // Blue pBGRImage[counter] = Palette[p256Image[LoopVar]].rgbBlue; counter++; // Green pBGRImage[counter] = Palette[p256Image[LoopVar]].rgbGreen; counter++; // Red pBGRImage[counter] = Palette[p256Image[LoopVar]].rgbRed; counter++; } } else if (bFileInfo.biBitCount == 24) { // Actual B,G,R Bitmap data may start somewhere other // than you think and is specified in bFileHead.bfOffBits if (r3d_FileSeek(hTemp, bFileHead.bfOffBits, R3D_BEGINNING) == FALSE) { sprintf(buffer, "%s: Error seeking RGB data in file", pFilename); _r3d_FormulateErrorString(FunctionNameString, buffer, DD_OK); return FALSE; } // Safe to read now dwPaddedBytes = ((bFileInfo.biWidth * 3) % 4); if (dwPaddedBytes) dwPaddedBytes = 4 - dwPaddedBytes; for (LoopVar = 0;LoopVar < bFileInfo.biHeight;LoopVar++) { if (r3d_FileRead(hTemp, &pBGRImage[LoopVar * bFileInfo.biWidth*3], (DWORD)(bFileInfo.biWidth * 3)) == FALSE) { sprintf(buffer, "%s: Error reading file", pFilename); _r3d_FormulateErrorString(FunctionNameString, buffer, DD_OK); return FALSE; } if (dwPaddedBytes && LoopVar < bFileInfo.biHeight - 1) { if (r3d_FileSeek(hTemp, dwPaddedBytes, R3D_CURRENT) == FALSE) { sprintf(buffer, "%s: Error seeking in file", pFilename); _r3d_FormulateErrorString(FunctionNameString, buffer, DD_OK); return FALSE; } } } } r3d_FileClose(hTemp); //hmmmm... why is this not working.... #ifdef EVALUATIONVERSION int x, y, x01, y01, x02, y02; // Horizontal lines y01 = bFileInfo.biHeight / 3; y02 = y01 * 2; for (x = 0;x < bFileInfo.biWidth;x++) { *(pBGRImage + (y01 * bFileInfo.biWidth * 3) + (x * 3) + 0) = 0; *(pBGRImage + (y01 * bFileInfo.biWidth * 3) + (x * 3) + 1) = 0; *(pBGRImage + (y01 * bFileInfo.biWidth * 3) + (x * 3) + 2) = 0; *(pBGRImage + (y02 * bFileInfo.biWidth * 3) + (x * 3) + 0) = 0; *(pBGRImage + (y02 * bFileInfo.biWidth * 3) + (x * 3) + 1) = 0; *(pBGRImage + (y02 * bFileInfo.biWidth * 3) + (x * 3) + 2) = 0; } // Vertical lines x01 = bFileInfo.biWidth / 3; x02 = x01 * 2; for (y = 0;y < bFileInfo.biHeight;y++) { *(pBGRImage + (y * bFileInfo.biWidth * 3) + (x01 * 3) + 0) = 0; *(pBGRImage + (y * bFileInfo.biWidth * 3) + (x01 * 3) + 1) = 0; *(pBGRImage + (y * bFileInfo.biWidth * 3) + (x01 * 3) + 2) = 0; *(pBGRImage + (y * bFileInfo.biWidth * 3) + (x02 * 3) + 0) = 0; *(pBGRImage + (y * bFileInfo.biWidth * 3) + (x02 * 3) + 1) = 0; *(pBGRImage + (y * bFileInfo.biWidth * 3) + (x02 * 3) + 2) = 0; } #endif return TRUE; } BOOL R3D_STDCALL r3d_SurfaceSetColorKey(int handle, unsigned char Red, unsigned char Green, unsigned char Blue) { int LoopVarX, LoopVarY; unsigned char *UCptr; unsigned char r, g, b, a; if (_r3d_bSurfaceDoesNotExist[handle] == TRUE) { _r3d_FormulateErrorString("r3d_SurfaceSetColorKey", "Invalid Surface Handle", DD_OK); return FALSE; } // We loop through the size of the virtual surface since // we can avoid pointer underflow and overflow this way. UCptr = (unsigned char *)r3d_SurfaceGet(handle); //UCptr+=3; // Alpha channel for RGBA for (LoopVarY = 0;LoopVarY < (int)_r3d_Surface[handle]->dwHeight;LoopVarY++) { for (LoopVarX = 0;LoopVarX < (int)_r3d_Surface[handle]->dwWidth;LoopVarX++) { r = *(UCptr); g = *(UCptr + 1); b = *(UCptr + 2); a = *(UCptr + 3); if (r == Red && g == Green && b == Blue) *(UCptr + 3) = 0; else *(UCptr + 3) = 255; UCptr += 4; } } return TRUE; } BOOL R3D_STDCALL r3d_SurfaceSetAlphaFromBMP(int handle, char *BitmapFilename) { int LoopVarX, LoopVarY; unsigned char *UCptr; DWORD dwWidth, dwHeight; char buffer[256]; BOOL bPalette256; if (_r3d_bSurfaceDoesNotExist[handle] == TRUE) { _r3d_FormulateErrorString("r3d_SurfaceSetAlphaFromBMP", "Invalid Surface Handle", DD_OK); return FALSE; } // First, we get the BMP width and height if (_r3d_BMPGetInfo(BitmapFilename, "r3d_SurfaceSetAlphaFromBMP", &dwWidth, &dwHeight, &bPalette256) == FALSE) { // Error string already defined return FALSE; } // Lets return with error if sizes are not equal if (dwWidth != _r3d_Surface[handle]->dwWidth && dwHeight != _r3d_Surface[handle]->dwHeight) { sprintf(buffer, "%s : File is not the same size as surface at handle # %d", BitmapFilename, handle); _r3d_FormulateErrorString("r3d_SurfaceSetAlphaFromBMP", buffer, DD_OK); return FALSE; } // Now, allocate memory if (NULL == (_r3d_A = new unsigned char[dwWidth * dwHeight*3])) { _r3d_FormulateErrorString("r3d_SurfaceSetAlphaFromBMP", "Can not allocate memory", DD_OK); return FALSE; } if (bPalette256 == TRUE) { if (NULL == (_r3d_256 = new unsigned char[dwWidth * dwHeight])) { _r3d_FormulateErrorString("r3d_SurfaceSetAlphaFromBMP", "Can not allocate memory", DD_OK); _R3D_DELETE(_r3d_A); return FALSE; } } // Now, load the bitmap image if (_r3d_BMPLoad(BitmapFilename, "r3d_SurfaceSetAlphaFromBMP", _r3d_A, _r3d_256) == FALSE) { // Error string already defined _R3D_DELETE(_r3d_A); _R3D_DELETE(_r3d_256); return FALSE; } // We can delete this after we call _r3d_BMPLoad() _R3D_DELETE(_r3d_256); // We loop through the size of the virtual surface since // we can avoid pointer underflow and overflow this way. UCptr = (unsigned char *)r3d_SurfaceGet(handle); UCptr += 3; // Alpha channel for RGBA //for ( LoopVarY=0; LoopVarY<(int)_r3d_Surface[handle]->dwHeight; LoopVarY++) for (LoopVarY = (int)dwHeight - 1;LoopVarY >= 0;LoopVarY--) { for (LoopVarX = 0;LoopVarX < (int)_r3d_Surface[handle]->dwWidth;LoopVarX++) { // We take alpha from the second channel... Should be green *UCptr = _r3d_A[(LoopVarY * dwWidth*3) + (LoopVarX*3)+1]; UCptr += 4; } } // We're done, we can delete this now... _R3D_DELETE(_r3d_A); return TRUE; } // If we use a color key and a getpixel function we can get the same // results and allow for custom colorkeying. BOOL R3D_STDCALL r3d_SurfaceCreateFromBMP(int *handle, char *BitmapFilename) { //char buffer[512]; int LoopVarX, LoopVarY; unsigned char *UCptr; int hBitmap; DWORD dwWidth, dwHeight; BOOL bPalette256; // First, we get the BMP width and height if (_r3d_BMPGetInfo(BitmapFilename, "r3d_SurfaceCreateFromBMP", &dwWidth, &dwHeight, &bPalette256) == FALSE) { // Error string already defined return FALSE; } // Now, allocate memory if (NULL == (_r3d_BGR = new unsigned char[dwWidth * dwHeight*3])) { _r3d_FormulateErrorString("r3d_SurfaceCreateFromBMP", "Can not allocate memory", DD_OK); return FALSE; } if (bPalette256 == TRUE) { if (NULL == (_r3d_256 = new unsigned char[dwWidth * dwHeight])) { _r3d_FormulateErrorString("r3d_SurfaceCreateFromBMP", "Can not allocate memory", DD_OK); _R3D_DELETE(_r3d_BGR); return FALSE; } } // Now, load the bitmap image if (_r3d_BMPLoad(BitmapFilename, "r3d_SurfaceCreateFromBMP", _r3d_BGR, _r3d_256) == FALSE) { // Error string already defined _R3D_DELETE(_r3d_BGR); _R3D_DELETE(_r3d_256); return FALSE; } // We can delete this after we call _r3d_BMPLoad() _R3D_DELETE(_r3d_256); // Now let's create a surface for the bitmap if (r3d_SurfaceCreate(&hBitmap, (int)dwWidth, (int)dwHeight) == FALSE) { // Error string already defined _R3D_DELETE(_r3d_BGR); return FALSE; } *handle = hBitmap; // Now let's copy it to our nice RGBA surface UCptr = (unsigned char *)r3d_SurfaceGet(hBitmap); for (LoopVarY = (int)dwHeight - 1;LoopVarY >= 0;LoopVarY--) //for ( LoopVarY=0; LoopVarY<(int)dwHeight; LoopVarY++ ) { for (LoopVarX = 0;LoopVarX < (int)dwWidth;LoopVarX++) { *UCptr = _r3d_BGR[(LoopVarY * dwWidth*3) + (LoopVarX*3)+2]; // Red Component UCptr++; *UCptr = _r3d_BGR[(LoopVarY * dwWidth*3) + (LoopVarX*3)+1]; // Green Component UCptr++; *UCptr = _r3d_BGR[(LoopVarY * dwWidth*3) + (LoopVarX*3)+0]; // Blue Component UCptr++; *UCptr = 255; UCptr++; } } // We're done, we can delete this now... _R3D_DELETE(_r3d_BGR); return TRUE; } // Returns a pointer to the base of the virtual surface memory array DWORD *R3D_STDCALL r3d_SurfaceGet(int handle) { if (_r3d_bSurfaceDoesNotExist[handle] == TRUE) { _r3d_FormulateErrorString("r3d_SurfaceGet", "Invalid Surface Handle", DD_OK); return NULL; } return (DWORD *)(&_r3d_Surface[handle]->RGBA[0]); } BOOL R3D_STDCALL r3d_2DBegin(unsigned char **pMem, int *Pitch, int *PixelFormat) { if (_r3d_bInsideRenderBeginEnd == TRUE) { _r3d_FormulateErrorString("r3d_2DBegin", "Can not call r3d_2D...() series of functions between an r3d_RenderBegin() and r3d_RenderEnd() pair.", _r3d_hResult); return FALSE; } if (_r3d_2DBeginEnd.bIsLocked == TRUE) { _r3d_FormulateErrorString("r3d_2DBegin", "r3d_2DBegin() can not be called twice without first calling r3d_2DEnd().", _r3d_hResult); return FALSE; } // Lock back buffer //memset(&_r3d_2DBeginEnd.ddsd, 0, sizeof(_r3d_2DBeginEnd.ddsd)); //_r3d_2DBeginEnd.ddsd.dwSize = sizeof(_r3d_2DBeginEnd.ddsd); //_r3d_2DBeginEnd.ddsd.dwFlags = DDSD_PITCH; _r3d_ProperlyInitDDSD(&_r3d_2DBeginEnd.ddsd); if ((_r3d_hResult = _r3d_BackBuffer4->Lock(NULL, &_r3d_2DBeginEnd.ddsd, DDLOCK_NOSYSLOCK | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL)) != DD_OK) { _r3d_FormulateErrorString("r3d_2DBegin", "_r3d_BackBuffer4->Lock()", _r3d_hResult); return FALSE; } //_r3d_2DBeginEnd.ddsd.lPitch=_r3d_gpCurrentDriver->pCurrentDevice->pCurrentMode->ddsd.lPitch; _r3d_2DBeginEnd.bIsLocked = TRUE; // Set this before we leave if (pMem != NULL) *pMem = (unsigned char *)_r3d_2DBeginEnd.ddsd.lpSurface; if (Pitch != NULL) *Pitch = (int)_r3d_2DBeginEnd.ddsd.lPitch; if (PixelFormat != NULL) *PixelFormat = _r3d_PixelFormatCode; return TRUE; } BOOL R3D_STDCALL r3d_2DEnd(void) { if (_r3d_bInsideRenderBeginEnd == TRUE) { _r3d_FormulateErrorString("r3d_2DEnd", "Can not call r3d_2D...() series of functions between an r3d_RenderBegin() and r3d_RenderEnd() pair.", _r3d_hResult); return FALSE; } if (_r3d_2DBeginEnd.bIsLocked == FALSE) { _r3d_FormulateErrorString("r3d_2DEnd", "r3d_2DEnd() not preceeded by r3d_2DBegin().", _r3d_hResult); return FALSE; } if ((_r3d_hResult = _r3d_BackBuffer4->Unlock(NULL)) != DD_OK) { _r3d_FormulateErrorString("r3d_2DEnd", "_r3d_BackBuffer4->Unlock()", _r3d_hResult); return FALSE; } _r3d_2DBeginEnd.bIsLocked = FALSE; return TRUE; } BOOL R3D_STDCALL r3d_2DSetPixel(int x, int y, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { unsigned char br, bg, bb; int DstR, DstG, DstB; // Clip if (x < _r3d_2DClipMinX) return TRUE; if (x > _r3d_2DClipMaxX) return TRUE; if (y < _r3d_2DClipMinY) return TRUE; if (y > _r3d_2DClipMaxY) return TRUE; // Lock back buffer, if required BOOL bUnlockRequired = FALSE; if (_r3d_2DBeginEnd.bIsLocked == FALSE) { if (r3d_2DBegin(NULL, NULL, NULL) == FALSE) { // Error string already defined... return FALSE; } bUnlockRequired = TRUE; } if (a == 255) { switch (_r3d_PixelFormatCode) { case 0: _r3d_Unsupported_SetPixelRGB0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r, g, b); break; case 1: _r3d_Unsupported_SetPixelRGB1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r, g, b); break; case 2: _r3d_Unsupported_SetPixelR2Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r); _r3d_Unsupported_SetPixelG2Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, g); _r3d_Unsupported_SetPixelB2Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, b); break; case 3: _r3d_Unsupported_SetPixelR3Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r); _r3d_Unsupported_SetPixelG3Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, g); _r3d_Unsupported_SetPixelB3Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, b); break; case 4: _r3d_Unsupported_SetPixelRGB4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r, g, b); break; case 5: _r3d_Unsupported_SetPixelRGB5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r, g, b); break; } } else { switch (_r3d_PixelFormatCode) { case 0: DstR = _r3d_Unsupported_GetPixelRed0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstG = _r3d_Unsupported_GetPixelGreen0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstB = _r3d_Unsupported_GetPixelBlue0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); br = (unsigned char)(DstR + ((((int)r - DstR) * (int)a) / 255)); bg = (unsigned char)(DstG + ((((int)g - DstG) * (int)a) / 255)); bb = (unsigned char)(DstB + ((((int)b - DstB) * (int)a) / 255)); _r3d_Unsupported_SetPixelRGB0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, br, bg, bb); break; case 1: DstR = _r3d_Unsupported_GetPixelRed1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstG = _r3d_Unsupported_GetPixelGreen1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstB = _r3d_Unsupported_GetPixelBlue1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); br = (unsigned char)(DstR + ((((int)r - DstR) * (int)a) / 255)); bg = (unsigned char)(DstG + ((((int)g - DstG) * (int)a) / 255)); bb = (unsigned char)(DstB + ((((int)b - DstB) * (int)a) / 255)); _r3d_Unsupported_SetPixelRGB1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r, g, b); break; case 2: DstR = _r3d_Unsupported_GetPixelRed2(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstG = _r3d_Unsupported_GetPixelGreen2(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstB = _r3d_Unsupported_GetPixelBlue2(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); br = (unsigned char)(DstR + ((((int)r - DstR) * (int)a) / 255)); bg = (unsigned char)(DstG + ((((int)g - DstG) * (int)a) / 255)); bb = (unsigned char)(DstB + ((((int)b - DstB) * (int)a) / 255)); _r3d_Unsupported_SetPixelR2Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r); _r3d_Unsupported_SetPixelG2Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, g); _r3d_Unsupported_SetPixelB2Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, b); break; case 3: DstR = _r3d_Unsupported_GetPixelRed3(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstG = _r3d_Unsupported_GetPixelGreen3(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstB = _r3d_Unsupported_GetPixelBlue3(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); br = (unsigned char)(DstR + ((((int)r - DstR) * (int)a) / 255)); bg = (unsigned char)(DstG + ((((int)g - DstG) * (int)a) / 255)); bb = (unsigned char)(DstB + ((((int)b - DstB) * (int)a) / 255)); _r3d_Unsupported_SetPixelR3Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r); _r3d_Unsupported_SetPixelG3Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, g); _r3d_Unsupported_SetPixelB3Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, b); break; case 4: DstR = _r3d_Unsupported_GetPixelRed4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstG = _r3d_Unsupported_GetPixelGreen4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstB = _r3d_Unsupported_GetPixelBlue4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); br = (unsigned char)(DstR + ((((int)r - DstR) * (int)a) / 255)); bg = (unsigned char)(DstG + ((((int)g - DstG) * (int)a) / 255)); bb = (unsigned char)(DstB + ((((int)b - DstB) * (int)a) / 255)); _r3d_Unsupported_SetPixelRGB4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r, g, b); break; case 5: DstR = _r3d_Unsupported_GetPixelRed5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstG = _r3d_Unsupported_GetPixelGreen5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstB = _r3d_Unsupported_GetPixelBlue5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); br = (unsigned char)(DstR + ((((int)r - DstR) * (int)a) / 255)); bg = (unsigned char)(DstG + ((((int)g - DstG) * (int)a) / 255)); bb = (unsigned char)(DstB + ((((int)b - DstB) * (int)a) / 255)); _r3d_Unsupported_SetPixelRGB5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r, g, b); break; } } if (bUnlockRequired == TRUE) { if (r3d_2DEnd() == FALSE) { // Error string already defined... return FALSE; } } return TRUE; } unsigned char R3D_STDCALL r3d_2DGetPixelRed(int x, int y) { unsigned char r; // Clip if (x < _r3d_2DClipMinX) return 0; if (x > _r3d_2DClipMaxX) return 0; if (y < _r3d_2DClipMinY) return 0; if (y > _r3d_2DClipMaxY) return 0; // Lock back buffer, if required BOOL bUnlockRequired = FALSE; if (_r3d_2DBeginEnd.bIsLocked == FALSE) { if (r3d_2DBegin(NULL, NULL, NULL) == FALSE) { // Error string already defined... return FALSE; } bUnlockRequired = TRUE; } switch (_r3d_PixelFormatCode) { case 0: r = _r3d_Unsupported_GetPixelRed0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 1: r = _r3d_Unsupported_GetPixelRed1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 2: r = _r3d_Unsupported_GetPixelRed2(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 3: r = _r3d_Unsupported_GetPixelRed3(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 4: r = _r3d_Unsupported_GetPixelRed4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 5: r = _r3d_Unsupported_GetPixelRed5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; } if (bUnlockRequired == TRUE) { if (r3d_2DEnd() == FALSE) { // Error string already defined... return FALSE; } } return r; } unsigned char R3D_STDCALL r3d_2DGetPixelGreen(int x, int y) { unsigned char g; // Clip if (x < _r3d_2DClipMinX) return 0; if (x > _r3d_2DClipMaxX) return 0; if (y < _r3d_2DClipMinY) return 0; if (y > _r3d_2DClipMaxY) return 0; // Lock back buffer, if required BOOL bUnlockRequired = FALSE; if (_r3d_2DBeginEnd.bIsLocked == FALSE) { if (r3d_2DBegin(NULL, NULL, NULL) == FALSE) { // Error string already defined... return FALSE; } bUnlockRequired = TRUE; } switch (_r3d_PixelFormatCode) { case 0: g = _r3d_Unsupported_GetPixelGreen0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 1: g = _r3d_Unsupported_GetPixelGreen1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 2: g = _r3d_Unsupported_GetPixelGreen2(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 3: g = _r3d_Unsupported_GetPixelGreen3(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 4: g = _r3d_Unsupported_GetPixelGreen4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 5: g = _r3d_Unsupported_GetPixelGreen5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; } if (bUnlockRequired == TRUE) { if (r3d_2DEnd() == FALSE) { // Error string already defined... return FALSE; } } return g; } unsigned char R3D_STDCALL r3d_2DGetPixelBlue(int x, int y) { unsigned char b; // Clip if (x < _r3d_2DClipMinX) return 0; if (x > _r3d_2DClipMaxX) return 0; if (y < _r3d_2DClipMinY) return 0; if (y > _r3d_2DClipMaxY) return 0; // Lock back buffer, if required BOOL bUnlockRequired = FALSE; if (_r3d_2DBeginEnd.bIsLocked == FALSE) { if (r3d_2DBegin(NULL, NULL, NULL) == FALSE) { // Error string already defined... return FALSE; } bUnlockRequired = TRUE; } switch (_r3d_PixelFormatCode) { case 0: b = _r3d_Unsupported_GetPixelBlue0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 1: b = _r3d_Unsupported_GetPixelBlue1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 2: b = _r3d_Unsupported_GetPixelBlue2(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 3: b = _r3d_Unsupported_GetPixelBlue3(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 4: b = _r3d_Unsupported_GetPixelBlue4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 5: b = _r3d_Unsupported_GetPixelBlue5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; } if (bUnlockRequired == TRUE) { if (r3d_2DEnd() == FALSE) { // Error string already defined... return FALSE; } } return b; } int R3D_STDCALL r3d_SurfaceGetWidth(int handle) { if (_r3d_bSurfaceDoesNotExist[handle] == TRUE) { _r3d_FormulateErrorString("r3d_SurfaceGetWidth", "Invalid Surface Handle", DD_OK); return FALSE; } return (int)_r3d_Surface[handle]->dwWidth; } int R3D_STDCALL r3d_SurfaceGetHeight(int handle) { if (_r3d_bSurfaceDoesNotExist[handle] == TRUE) { _r3d_FormulateErrorString("r3d_SurfaceGetHeight", "Invalid Surface Handle", DD_OK); return FALSE; } return (int)_r3d_Surface[handle]->dwHeight; } BOOL R3D_STDCALL r3d_SurfaceCreateFromBackBuffer(int *hSrc) { unsigned char *pSurface; unsigned long x, y; int hBitmap; if (r3d_SurfaceCreate(&hBitmap, (int)_r3d_dwRenderWidth, (int)_r3d_dwRenderHeight) == FALSE) { // Error string already defined return FALSE; } *hSrc = hBitmap; // Lock back buffer, if required BOOL bUnlockRequired = FALSE; if (_r3d_2DBeginEnd.bIsLocked == FALSE) { if (r3d_2DBegin(NULL, NULL, NULL) == FALSE) { // Error string already defined... return FALSE; } bUnlockRequired = TRUE; } pSurface = (unsigned char *)r3d_SurfaceGet(hBitmap); for (y = 0;y < _r3d_dwRenderHeight;y++) { for (x = 0;x < _r3d_dwRenderWidth;x++) { switch (_r3d_PixelFormatCode) { case 0: pSurface[(y * (_r3d_dwRenderWidth << 2)) + (x << 2)] = _r3d_Unsupported_GetPixelRed0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); pSurface[(y * (_r3d_dwRenderWidth << 2)) + (x << 2)+1] = _r3d_Unsupported_GetPixelGreen0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); pSurface[(y * (_r3d_dwRenderWidth << 2)) + (x << 2)+2] = _r3d_Unsupported_GetPixelBlue0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 1: pSurface[(y * (_r3d_dwRenderWidth << 2)) + (x << 2)] = _r3d_Unsupported_GetPixelRed1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); pSurface[(y * (_r3d_dwRenderWidth << 2)) + (x << 2)+1] = _r3d_Unsupported_GetPixelGreen1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); pSurface[(y * (_r3d_dwRenderWidth << 2)) + (x << 2)+2] = _r3d_Unsupported_GetPixelBlue1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 2: pSurface[(y * (_r3d_dwRenderWidth << 2)) + (x << 2)] = _r3d_Unsupported_GetPixelRed2(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); pSurface[(y * (_r3d_dwRenderWidth << 2)) + (x << 2)+1] = _r3d_Unsupported_GetPixelGreen2(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); pSurface[(y * (_r3d_dwRenderWidth << 2)) + (x << 2)+2] = _r3d_Unsupported_GetPixelBlue2(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 3: pSurface[(y * (_r3d_dwRenderWidth << 2)) + (x << 2)] = _r3d_Unsupported_GetPixelRed3(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); pSurface[(y * (_r3d_dwRenderWidth << 2)) + (x << 2)+1] = _r3d_Unsupported_GetPixelGreen3(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); pSurface[(y * (_r3d_dwRenderWidth << 2)) + (x << 2)+2] = _r3d_Unsupported_GetPixelBlue3(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 4: pSurface[(y * (_r3d_dwRenderWidth << 2)) + (x << 2)] = _r3d_Unsupported_GetPixelRed4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); pSurface[(y * (_r3d_dwRenderWidth << 2)) + (x << 2)+1] = _r3d_Unsupported_GetPixelGreen4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); pSurface[(y * (_r3d_dwRenderWidth << 2)) + (x << 2)+2] = _r3d_Unsupported_GetPixelBlue4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 5: pSurface[(y * (_r3d_dwRenderWidth << 2)) + (x << 2)] = _r3d_Unsupported_GetPixelRed5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); pSurface[(y * (_r3d_dwRenderWidth << 2)) + (x << 2)+1] = _r3d_Unsupported_GetPixelGreen5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); pSurface[(y * (_r3d_dwRenderWidth << 2)) + (x << 2)+2] = _r3d_Unsupported_GetPixelBlue5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; } } } if (bUnlockRequired == TRUE) { if (r3d_2DEnd() == FALSE) { // Error string already defined... return FALSE; } } return TRUE; } BOOL R3D_STDCALL r3d_2DFadeIn(int hSrc, int SrcMinx, int SrcMaxx, int SrcMiny, int SrcMaxy, int DstMinx, int DstMaxx, int DstMiny, int DstMaxy, int StepSize) { unsigned long x, y, SrcY, LookUp; unsigned long SrcA, SrcR, SrcG, SrcB; unsigned long DstR, DstG, DstB; unsigned char r, g, b; BOOL bScale; unsigned char *SrcRGBA; unsigned long DstW, DstH, SrcW, SrcH; unsigned long HRatio, WRatio; if (_r3d_bSurfaceDoesNotExist[hSrc] == TRUE) { _r3d_FormulateErrorString("r3d_2DFadeIn", "Invalid Surface Handle", DD_OK); return FALSE; } _R3D_BLITCLIP((int)(_r3d_Surface[hSrc]->dwWidth), (int)(_r3d_Surface[hSrc]->dwHeight), (int)(_r3d_2DClipMaxX + 1), (int)(_r3d_2DClipMaxY + 1), SrcMinx, SrcMaxx, SrcMiny, SrcMaxy, DstMinx, DstMaxx, DstMiny, DstMaxy); // Determine Scale Size DstW = (DstMaxx - DstMinx) + 1; DstH = (DstMaxy - DstMiny) + 1; SrcW = (SrcMaxx - SrcMinx) + 1; SrcH = (SrcMaxy - SrcMiny) + 1; if (DstW == SrcW && DstH == SrcH) { bScale = FALSE; } else { bScale = TRUE; WRatio = (SrcW << 16) / DstW; HRatio = (SrcH << 16) / DstH; } // Lock back buffer, if required BOOL bLockStatus; bLockStatus = _r3d_2DBeginEnd.bIsLocked; if (bLockStatus == FALSE) { if (r3d_2DBegin(NULL, NULL, NULL) == FALSE) { // Error string already defined... return FALSE; } } // We also need to keep a copy of the back buffer somewhere else if (NULL == (_r3d_FadeInBackBufferCopy = new unsigned char[DstW * DstH*4])) { _r3d_FormulateErrorString("r3d_2DFadeIn", "Can not allocate memory", DD_OK); return FALSE; } for (y = (unsigned long)DstMiny;y <= (unsigned long)DstMaxy;y++) { for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { switch (_r3d_PixelFormatCode) { case 0: _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)] = _r3d_Unsupported_GetPixelRed0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+1] = _r3d_Unsupported_GetPixelGreen0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+2] = _r3d_Unsupported_GetPixelBlue0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 1: _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)] = _r3d_Unsupported_GetPixelRed1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+1] = _r3d_Unsupported_GetPixelGreen1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+2] = _r3d_Unsupported_GetPixelBlue1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 2: _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)] = _r3d_Unsupported_GetPixelRed2(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+1] = _r3d_Unsupported_GetPixelGreen2(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+2] = _r3d_Unsupported_GetPixelBlue2(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 3: _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)] = _r3d_Unsupported_GetPixelRed3(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+1] = _r3d_Unsupported_GetPixelGreen3(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+2] = _r3d_Unsupported_GetPixelBlue3(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 4: _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)] = _r3d_Unsupported_GetPixelRed4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+1] = _r3d_Unsupported_GetPixelGreen4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+2] = _r3d_Unsupported_GetPixelBlue4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; case 5: _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)] = _r3d_Unsupported_GetPixelRed5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+1] = _r3d_Unsupported_GetPixelGreen5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+2] = _r3d_Unsupported_GetPixelBlue5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); break; } } } // Unlock if (r3d_2DEnd() == FALSE) { // Error string already defined... return FALSE; } // Let's build the scanline lookup table // if (bScale == TRUE) { for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) _r3d_ScanLineLookUpTable[x - DstMinx] = (((((x - DstMinx) * WRatio) >> 16) + SrcMinx) << 2); } else { // We could actually create a pre built table when we initialize R3D for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) _r3d_ScanLineLookUpTable[x - DstMinx] = (((x - DstMinx) + SrcMinx) << 2); } // Fade it in SrcRGBA = (unsigned char *)r3d_SurfaceGet(hSrc); for (SrcA = 0;SrcA <= 255;SrcA += StepSize) { if (r3d_2DBegin(NULL, NULL, NULL) == FALSE) { // Error string already defined... return FALSE; } switch (_r3d_PixelFormatCode) { case 0: for (y = (unsigned long)DstMiny;y <= (unsigned long)DstMaxy;y++) { if (bScale == TRUE) SrcY = ((((y - DstMiny) * HRatio) >> 16) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); else SrcY = ((y - DstMiny) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; SrcR = SrcRGBA[LookUp]; SrcG = SrcRGBA[LookUp+1]; SrcB = SrcRGBA[LookUp+2]; DstR = _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)]; DstG = _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+1]; DstB = _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+2]; r = (unsigned char)(DstR + (((SrcR - DstR) * SrcA) / 255)); g = (unsigned char)(DstG + (((SrcG - DstG) * SrcA) / 255)); b = (unsigned char)(DstB + (((SrcB - DstB) * SrcA) / 255)); _r3d_Unsupported_SetPixelRGB0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r, g, b); } } break; case 1: for (y = (unsigned long)DstMiny;y <= (unsigned long)DstMaxy;y++) { if (bScale == TRUE) SrcY = ((((y - DstMiny) * HRatio) >> 16) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); else SrcY = ((y - DstMiny) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; SrcR = SrcRGBA[LookUp]; SrcG = SrcRGBA[LookUp+1]; SrcB = SrcRGBA[LookUp+2]; DstR = _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)]; DstG = _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+1]; DstB = _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+2]; r = (unsigned char)(DstR + (((SrcR - DstR) * SrcA) / 255)); g = (unsigned char)(DstG + (((SrcG - DstG) * SrcA) / 255)); b = (unsigned char)(DstB + (((SrcB - DstB) * SrcA) / 255)); _r3d_Unsupported_SetPixelRGB1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r, g, b); } } break; case 2: for (y = (unsigned long)DstMiny;y <= (unsigned long)DstMaxy;y++) { if (bScale == TRUE) SrcY = ((((y - DstMiny) * HRatio) >> 16) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); else SrcY = ((y - DstMiny) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; SrcR = SrcRGBA[LookUp]; SrcG = SrcRGBA[LookUp+1]; SrcB = SrcRGBA[LookUp+2]; DstR = _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)]; DstG = _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+1]; DstB = _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+2]; r = (unsigned char)(DstR + (((SrcR - DstR) * SrcA) / 255)); g = (unsigned char)(DstG + (((SrcG - DstG) * SrcA) / 255)); b = (unsigned char)(DstB + (((SrcB - DstB) * SrcA) / 255)); _r3d_Unsupported_SetPixelR2Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r); _r3d_Unsupported_SetPixelG2Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, g); _r3d_Unsupported_SetPixelB2Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, b); } } break; case 3: for (y = (unsigned long)DstMiny;y <= (unsigned long)DstMaxy;y++) { if (bScale == TRUE) SrcY = ((((y - DstMiny) * HRatio) >> 16) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); else SrcY = ((y - DstMiny) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; SrcR = SrcRGBA[LookUp]; SrcG = SrcRGBA[LookUp+1]; SrcB = SrcRGBA[LookUp+2]; DstR = _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)]; DstG = _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+1]; DstB = _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+2]; r = (unsigned char)(DstR + (((SrcR - DstR) * SrcA) / 255)); g = (unsigned char)(DstG + (((SrcG - DstG) * SrcA) / 255)); b = (unsigned char)(DstB + (((SrcB - DstB) * SrcA) / 255)); _r3d_Unsupported_SetPixelR3Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r); _r3d_Unsupported_SetPixelG3Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, g); _r3d_Unsupported_SetPixelB3Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, b); } } break; case 4: for (y = (unsigned long)DstMiny;y <= (unsigned long)DstMaxy;y++) { if (bScale == TRUE) SrcY = ((((y - DstMiny) * HRatio) >> 16) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); else SrcY = ((y - DstMiny) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; SrcR = SrcRGBA[LookUp]; SrcG = SrcRGBA[LookUp+1]; SrcB = SrcRGBA[LookUp+2]; DstR = _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)]; DstG = _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+1]; DstB = _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+2]; r = (unsigned char)(DstR + (((SrcR - DstR) * SrcA) / 255)); g = (unsigned char)(DstG + (((SrcG - DstG) * SrcA) / 255)); b = (unsigned char)(DstB + (((SrcB - DstB) * SrcA) / 255)); _r3d_Unsupported_SetPixelRGB4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r, g, b); } } break; case 5: for (y = (unsigned long)DstMiny;y <= (unsigned long)DstMaxy;y++) { if (bScale == TRUE) SrcY = ((((y - DstMiny) * HRatio) >> 16) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); else SrcY = ((y - DstMiny) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; SrcR = SrcRGBA[LookUp]; SrcG = SrcRGBA[LookUp+1]; SrcB = SrcRGBA[LookUp+2]; DstR = _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)]; DstG = _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+1]; DstB = _r3d_FadeInBackBufferCopy[(y * (DstW << 2)) + (x << 2)+2]; r = (unsigned char)(DstR + (((SrcR - DstR) * SrcA) / 255)); g = (unsigned char)(DstG + (((SrcG - DstG) * SrcA) / 255)); b = (unsigned char)(DstB + (((SrcB - DstB) * SrcA) / 255)); _r3d_Unsupported_SetPixelRGB5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r, g, b); } } break; } // Unlock and page flip if (r3d_2DEnd() == FALSE) { // Error string already defined... return FALSE; } r3d_PageFlip(FALSE, FALSE); } _R3D_DELETE(_r3d_FadeInBackBufferCopy); // We do a final blit and page flip r3d_2DBlit(hSrc, SrcMinx, SrcMaxx, SrcMiny, SrcMaxy, DstMinx, DstMaxx, DstMiny, DstMaxy, FALSE); r3d_PageFlip(FALSE, FALSE); r3d_2DBlit(hSrc, SrcMinx, SrcMaxx, SrcMiny, SrcMaxy, DstMinx, DstMaxx, DstMiny, DstMaxy, FALSE); r3d_PageFlip(FALSE, FALSE); if (bLockStatus == TRUE) { if (r3d_2DBegin(NULL, NULL, NULL) == FALSE) { // Error string already defined... return FALSE; } } return TRUE; } BOOL R3D_STDCALL r3d_2DBlit(int hSrc, int SrcMinx, int SrcMaxx, int SrcMiny, int SrcMaxy, int DstMinx, int DstMaxx, int DstMiny, int DstMaxy, BOOL BlendAlphaChannel) { unsigned long x, y, SrcY, LookUp; unsigned long SrcA, SrcR, SrcG, SrcB; unsigned long DstR, DstG, DstB; unsigned char r, g, b; BOOL bScale; unsigned char *SrcRGBA; unsigned long DstW, DstH, SrcW, SrcH; unsigned long HRatio, WRatio; if (_r3d_bSurfaceDoesNotExist[hSrc] == TRUE) { _r3d_FormulateErrorString("r3d_2DBlit", "Invalid Surface Handle", DD_OK); return FALSE; } _R3D_BLITCLIP((int)(_r3d_Surface[hSrc]->dwWidth), (int)(_r3d_Surface[hSrc]->dwHeight), (int)(_r3d_2DClipMaxX + 1), (int)(_r3d_2DClipMaxY + 1), SrcMinx, SrcMaxx, SrcMiny, SrcMaxy, DstMinx, DstMaxx, DstMiny, DstMaxy); // Determine Scale Size DstW = (DstMaxx - DstMinx) + 1; DstH = (DstMaxy - DstMiny) + 1; SrcW = (SrcMaxx - SrcMinx) + 1; SrcH = (SrcMaxy - SrcMiny) + 1; if (DstW == SrcW && DstH == SrcH) { bScale = FALSE; } else { bScale = TRUE; WRatio = (SrcW << 16) / DstW; HRatio = (SrcH << 16) / DstH; } // Lock back buffer, if required BOOL bUnlockRequired = FALSE; if (_r3d_2DBeginEnd.bIsLocked == FALSE) { if (r3d_2DBegin(NULL, NULL, NULL) == FALSE) { // Error string already defined... return FALSE; } bUnlockRequired = TRUE; } // Let's build the scanline lookup table // if (bScale == TRUE) { for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) _r3d_ScanLineLookUpTable[x - DstMinx] = (((((x - DstMinx) * WRatio) >> 16) + SrcMinx) << 2); } else { // We could actually create a pre built table when we initialize R3D for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) _r3d_ScanLineLookUpTable[x - DstMinx] = (((x - DstMinx) + SrcMinx) << 2); } // Blit it SrcRGBA = (unsigned char *)r3d_SurfaceGet(hSrc); switch (_r3d_PixelFormatCode) { case 0: for (y = (unsigned long)DstMiny;y <= (unsigned long)DstMaxy;y++) { if (bScale == TRUE) SrcY = ((((y - DstMiny) * HRatio) >> 16) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); else SrcY = ((y - DstMiny) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); if (BlendAlphaChannel) { for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; //if ( 255==(SrcA=SrcRGBA[LookUp+3]) ) SrcA = SrcRGBA[LookUp+3]; if (SrcA == 255) { _r3d_Unsupported_SetPixelRGB0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp], SrcRGBA[LookUp+1], SrcRGBA[LookUp+2]); } else { SrcR = SrcRGBA[LookUp]; SrcG = SrcRGBA[LookUp+1]; SrcB = SrcRGBA[LookUp+2]; DstR = _r3d_Unsupported_GetPixelRed0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstG = _r3d_Unsupported_GetPixelGreen0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstB = _r3d_Unsupported_GetPixelBlue0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); r = (unsigned char)(DstR + (((SrcR - DstR) * SrcA) / 255)); g = (unsigned char)(DstG + (((SrcG - DstG) * SrcA) / 255)); b = (unsigned char)(DstB + (((SrcB - DstB) * SrcA) / 255)); _r3d_Unsupported_SetPixelRGB0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r, g, b); } } } else { for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; _r3d_Unsupported_SetPixelRGB0(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp], SrcRGBA[LookUp+1], SrcRGBA[LookUp+2]); } } } break; case 1: for (y = (unsigned long)DstMiny;y <= (unsigned long)DstMaxy;y++) { if (bScale == TRUE) SrcY = ((((y - DstMiny) * HRatio) >> 16) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); else SrcY = ((y - DstMiny) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); if (BlendAlphaChannel) { for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; //if ( 255==(SrcA=SrcRGBA[LookUp+3]) ) SrcA = SrcRGBA[LookUp+3]; if (SrcA == 255) { _r3d_Unsupported_SetPixelRGB1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp], SrcRGBA[LookUp+1], SrcRGBA[LookUp+2]); } else { SrcR = SrcRGBA[LookUp]; SrcG = SrcRGBA[LookUp+1]; SrcB = SrcRGBA[LookUp+2]; DstR = _r3d_Unsupported_GetPixelRed1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstG = _r3d_Unsupported_GetPixelGreen1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstB = _r3d_Unsupported_GetPixelBlue1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); r = (unsigned char)(DstR + (((SrcR - DstR) * SrcA) / 255)); g = (unsigned char)(DstG + (((SrcG - DstG) * SrcA) / 255)); b = (unsigned char)(DstB + (((SrcB - DstB) * SrcA) / 255)); _r3d_Unsupported_SetPixelRGB1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r, g, b); } } } else { for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; _r3d_Unsupported_SetPixelRGB1(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp], SrcRGBA[LookUp+1], SrcRGBA[LookUp+2]); } } } break; case 2: for (y = (unsigned long)DstMiny;y <= (unsigned long)DstMaxy;y++) { if (bScale == TRUE) SrcY = ((((y - DstMiny) * HRatio) >> 16) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); else SrcY = ((y - DstMiny) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); if (BlendAlphaChannel) { for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; //if ( 255==(SrcA=SrcRGBA[LookUp+3]) ) SrcA = SrcRGBA[LookUp+3]; if (SrcA == 255) { _r3d_Unsupported_SetPixelR2Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp]); _r3d_Unsupported_SetPixelG2Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp+1]); _r3d_Unsupported_SetPixelB2Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp+2]); } else { SrcR = SrcRGBA[LookUp]; SrcG = SrcRGBA[LookUp+1]; SrcB = SrcRGBA[LookUp+2]; DstR = _r3d_Unsupported_GetPixelRed2(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstG = _r3d_Unsupported_GetPixelGreen2(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstB = _r3d_Unsupported_GetPixelBlue2(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); r = (unsigned char)(DstR + (((SrcR - DstR) * SrcA) / 255)); g = (unsigned char)(DstG + (((SrcG - DstG) * SrcA) / 255)); b = (unsigned char)(DstB + (((SrcB - DstB) * SrcA) / 255)); _r3d_Unsupported_SetPixelR2Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r); _r3d_Unsupported_SetPixelG2Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, g); _r3d_Unsupported_SetPixelB2Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, b); } } } else { for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; _r3d_Unsupported_SetPixelR2Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp]); _r3d_Unsupported_SetPixelG2Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp+1]); _r3d_Unsupported_SetPixelB2Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp+2]); } } } break; case 3: for (y = (unsigned long)DstMiny;y <= (unsigned long)DstMaxy;y++) { if (bScale == TRUE) SrcY = ((((y - DstMiny) * HRatio) >> 16) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); else SrcY = ((y - DstMiny) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); if (BlendAlphaChannel) { for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; //if ( 255==(SrcA=SrcRGBA[LookUp+3]) ) SrcA = SrcRGBA[LookUp+3]; if (SrcA == 255) { _r3d_Unsupported_SetPixelR3Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp]); _r3d_Unsupported_SetPixelG3Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp+1]); _r3d_Unsupported_SetPixelB3Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp+2]); } else { SrcR = SrcRGBA[LookUp]; SrcG = SrcRGBA[LookUp+1]; SrcB = SrcRGBA[LookUp+2]; DstR = _r3d_Unsupported_GetPixelRed3(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstG = _r3d_Unsupported_GetPixelGreen3(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstB = _r3d_Unsupported_GetPixelBlue3(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); r = (unsigned char)(DstR + (((SrcR - DstR) * SrcA) / 255)); g = (unsigned char)(DstG + (((SrcG - DstG) * SrcA) / 255)); b = (unsigned char)(DstB + (((SrcB - DstB) * SrcA) / 255)); _r3d_Unsupported_SetPixelR3Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r); _r3d_Unsupported_SetPixelG3Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, g); _r3d_Unsupported_SetPixelB3Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, b); } } } else { for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; _r3d_Unsupported_SetPixelR3Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp]); _r3d_Unsupported_SetPixelG3Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp+1]); _r3d_Unsupported_SetPixelB3Safe(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp+2]); } } } break; case 4: for (y = (unsigned long)DstMiny;y <= (unsigned long)DstMaxy;y++) { if (bScale == TRUE) SrcY = ((((y - DstMiny) * HRatio) >> 16) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); else SrcY = ((y - DstMiny) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); if (BlendAlphaChannel) { for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; //if ( 255==(SrcA=SrcRGBA[LookUp+3]) ) SrcA = SrcRGBA[LookUp+3]; if (SrcA == 255) { _r3d_Unsupported_SetPixelRGB4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp], SrcRGBA[LookUp+1], SrcRGBA[LookUp+2]); } else { SrcR = SrcRGBA[LookUp]; SrcG = SrcRGBA[LookUp+1]; SrcB = SrcRGBA[LookUp+2]; DstR = _r3d_Unsupported_GetPixelRed4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstG = _r3d_Unsupported_GetPixelGreen4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstB = _r3d_Unsupported_GetPixelBlue4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); r = (unsigned char)(DstR + (((SrcR - DstR) * SrcA) / 255)); g = (unsigned char)(DstG + (((SrcG - DstG) * SrcA) / 255)); b = (unsigned char)(DstB + (((SrcB - DstB) * SrcA) / 255)); _r3d_Unsupported_SetPixelRGB4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r, g, b); } } } else { for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; _r3d_Unsupported_SetPixelRGB4(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp], SrcRGBA[LookUp+1], SrcRGBA[LookUp+2]); } } } break; case 5: for (y = (unsigned long)DstMiny;y <= (unsigned long)DstMaxy;y++) { if (bScale == TRUE) SrcY = ((((y - DstMiny) * HRatio) >> 16) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); else SrcY = ((y - DstMiny) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); if (BlendAlphaChannel) { for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; //if ( 255==(SrcA=SrcRGBA[LookUp+3]) ) SrcA = SrcRGBA[LookUp+3]; if (SrcA == 255) { _r3d_Unsupported_SetPixelRGB5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp], SrcRGBA[LookUp+1], SrcRGBA[LookUp+2]); } else { SrcR = SrcRGBA[LookUp]; SrcG = SrcRGBA[LookUp+1]; SrcB = SrcRGBA[LookUp+2]; DstR = _r3d_Unsupported_GetPixelRed5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstG = _r3d_Unsupported_GetPixelGreen5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); DstB = _r3d_Unsupported_GetPixelBlue5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y); r = (unsigned char)(DstR + (((SrcR - DstR) * SrcA) / 255)); g = (unsigned char)(DstG + (((SrcG - DstG) * SrcA) / 255)); b = (unsigned char)(DstB + (((SrcB - DstB) * SrcA) / 255)); _r3d_Unsupported_SetPixelRGB5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, r, g, b); } } } else { for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; _r3d_Unsupported_SetPixelRGB5(_r3d_2DBeginEnd.ddsd.lpSurface, _r3d_2DBeginEnd.ddsd.lPitch, x, y, SrcRGBA[LookUp], SrcRGBA[LookUp+1], SrcRGBA[LookUp+2]); } } } break; } if (bUnlockRequired == TRUE) { if (r3d_2DEnd() == FALSE) { // Error string already defined... return FALSE; } } return TRUE; } BOOL R3D_STDCALL r3d_SurfaceBlit(int hSrc, int hDst, int SrcMinx, int SrcMaxx, int SrcMiny, int SrcMaxy, int DstMinx, int DstMaxx, int DstMiny, int DstMaxy, BOOL BlendAlphaChannel) { unsigned long x, y, SrcY, LookUp, DstY; unsigned long SrcA; unsigned long DstR, DstG, DstB; BOOL bScale; unsigned char *SrcRGBA, *DstRGBA; unsigned long DstW, DstH, SrcW, SrcH; unsigned long HRatio, WRatio; if (_r3d_bSurfaceDoesNotExist[hSrc] == TRUE) { _r3d_FormulateErrorString("r3d_SurfaceBlit", "hSrc: Invalid Surface Handle", DD_OK); return FALSE; } if (_r3d_bSurfaceDoesNotExist[hDst] == TRUE) { _r3d_FormulateErrorString("r3d_SurfaceBlit", "hDst: Invalid Surface Handle", DD_OK); return FALSE; } _R3D_BLITCLIP((int)(_r3d_Surface[hSrc]->dwWidth), (int)(_r3d_Surface[hSrc]->dwHeight), (int)(_r3d_Surface[hDst]->dwWidth), (int)(_r3d_Surface[hDst]->dwHeight), SrcMinx, SrcMaxx, SrcMiny, SrcMaxy, DstMinx, DstMaxx, DstMiny, DstMaxy); // Determine Scale Size DstW = (DstMaxx - DstMinx) + 1; DstH = (DstMaxy - DstMiny) + 1; SrcW = (SrcMaxx - SrcMinx) + 1; SrcH = (SrcMaxy - SrcMiny) + 1; if (DstW == SrcW && DstH == SrcH) { bScale = FALSE; } else { bScale = TRUE; WRatio = (SrcW << 16) / DstW; HRatio = (SrcH << 16) / DstH; } // Let's build the scanline lookup table // if (bScale == TRUE) { for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) _r3d_ScanLineLookUpTable[x - DstMinx] = (((((x - DstMinx) * WRatio) >> 16) + SrcMinx) << 2); } else { // We could actually create a pre built table when we initialize R3D for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) _r3d_ScanLineLookUpTable[x - DstMinx] = (((x - DstMinx) + SrcMinx) << 2); } // Blit it SrcRGBA = (unsigned char *)r3d_SurfaceGet(hSrc); DstRGBA = (unsigned char *)r3d_SurfaceGet(hDst); for (y = (unsigned long)DstMiny;y <= (unsigned long)DstMaxy;y++) { if (bScale == TRUE) SrcY = ((((y - DstMiny) * HRatio) >> 16) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); else SrcY = ((y - DstMiny) + SrcMiny) * (_r3d_Surface[hSrc]->dwWidth << 2); //SrcY*=(_r3d_Surface[hSrc]->dwWidth<<2); DstY = ((_r3d_Surface[hDst]->dwWidth << 2) * y); if (BlendAlphaChannel) { for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; if (255 == (SrcA = SrcRGBA[LookUp+3])) { DstRGBA[DstY + (x << 2)] = SrcRGBA[LookUp]; DstRGBA[DstY + (x << 2)+1] = SrcRGBA[LookUp+1]; DstRGBA[DstY + (x << 2)+2] = SrcRGBA[LookUp+2]; } else { //SrcR=SrcRGBA[LookUp]; //SrcG=SrcRGBA[LookUp+1]; //SrcB=SrcRGBA[LookUp+2]; DstR = DstRGBA[DstY + (x << 2)]; DstG = DstRGBA[DstY + (x << 2)+1]; DstB = DstRGBA[DstY + (x << 2)+2]; //r=(unsigned char)(DstR+(((SrcR-DstR)*SrcA)/255)); //g=(unsigned char)(DstG+(((SrcG-DstG)*SrcA)/255)); //b=(unsigned char)(DstB+(((SrcB-DstB)*SrcA)/255)); //DstRGBA[DstY+(x<<2)]=r; //DstRGBA[DstY+(x<<2)+1]=b; //DstRGBA[DstY+(x<<2)+2]=g; //DstRGBA[DstY+(x<<2)]=(unsigned char)(DstR+(((SrcR-DstR)*SrcA)/255)); //DstRGBA[DstY+(x<<2)+1]=(unsigned char)(DstG+(((SrcG-DstG)*SrcA)/255)); //DstRGBA[DstY+(x<<2)+2]=(unsigned char)(DstB+(((SrcB-DstB)*SrcA)/255)); DstRGBA[DstY + (x << 2)] = (unsigned char)(DstR + (((SrcRGBA[LookUp] - DstR) * SrcA) / 255)); DstRGBA[DstY + (x << 2)+1] = (unsigned char)(DstG + (((SrcRGBA[LookUp+1] - DstG) * SrcA) / 255)); DstRGBA[DstY + (x << 2)+2] = (unsigned char)(DstB + (((SrcRGBA[LookUp+2] - DstB) * SrcA) / 255)); } } } else { for (x = (unsigned long)DstMinx;x <= (unsigned long)DstMaxx;x++) { LookUp = SrcY + _r3d_ScanLineLookUpTable[x - DstMinx]; DstRGBA[DstY + (x << 2)] = SrcRGBA[LookUp]; DstRGBA[DstY + (x << 2)+1] = SrcRGBA[LookUp+1]; DstRGBA[DstY + (x << 2)+2] = SrcRGBA[LookUp+2]; DstRGBA[DstY + (x << 2)+3] = SrcRGBA[LookUp+3]; } } } return TRUE; } BOOL R3D_STDCALL r3d_SurfaceExportToBMP(int hSrc, char *lpFilename) { // Header used for 640x480x24 bpp image without compression unsigned char bmp_24_hdr[54] = { 66, 77, 54, 16, 14, 0, 0, 0, 0, 0, 54, 0, 0, 0, 40, 0, 0, 0, 128, 2, 0, 0, 224, 1, 0, 0, 1, 0, 24, 0, 0, 0, 0, 0, 0, 16, 14, 0, 206, 14, 0, 0, 216, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; unsigned long dwPaddedBytes; unsigned char UCTemp[4] = {0, 0, 0, 0}; char ErrorBuffer[256]; HANDLE hFile; long LoopVar, LoopVarX; if (_r3d_bSurfaceDoesNotExist[hSrc] == TRUE) { _r3d_FormulateErrorString("r3d_SurfaceToBMP", "hSrc: Invalid Surface Handle", DD_OK); return FALSE; } // Write the header our way if ((hFile = r3d_FileOpen(lpFilename, R3D_WRITE | R3D_CREATE | R3D_TRUNCATE)) == INVALID_HANDLE_VALUE) { sprintf(ErrorBuffer, "%s: Error opening file", lpFilename); _r3d_FormulateErrorString("r3d_SurfaceToBMP", ErrorBuffer, DD_OK); return FALSE; } if (r3d_FileWrite(hFile, bmp_24_hdr, (DWORD)2) == FALSE) { sprintf(ErrorBuffer, "%s: Error writing file", lpFilename); _r3d_FormulateErrorString("r3d_SurfaceToBMP", ErrorBuffer, DD_OK); return FALSE; } LoopVar = ((long)(_r3d_Surface[hSrc]->dwWidth * _r3d_Surface[hSrc]->dwHeight) * 3L) + 54L; if (r3d_FileWrite(hFile, &LoopVar, (DWORD)4) == FALSE) { sprintf(ErrorBuffer, "%s: Error writing file", lpFilename); _r3d_FormulateErrorString("r3d_SurfaceToBMP", ErrorBuffer, DD_OK); return FALSE; } if (r3d_FileWrite(hFile, &bmp_24_hdr[6], (DWORD)12) == FALSE) { sprintf(ErrorBuffer, "%s: Error writing file", lpFilename); _r3d_FormulateErrorString("r3d_SurfaceToBMP", ErrorBuffer, DD_OK); return FALSE; } if (r3d_FileWrite(hFile, &_r3d_Surface[hSrc]->dwWidth, (DWORD)4) == FALSE) { sprintf(ErrorBuffer, "%s: Error writing file", lpFilename); _r3d_FormulateErrorString("r3d_SurfaceToBMP", ErrorBuffer, DD_OK); return FALSE; } if (r3d_FileWrite(hFile, &_r3d_Surface[hSrc]->dwHeight, (DWORD)4) == FALSE) { sprintf(ErrorBuffer, "%s: Error writing file", lpFilename); _r3d_FormulateErrorString("r3d_SurfaceToBMP", ErrorBuffer, DD_OK); return FALSE; } if (r3d_FileWrite(hFile, &bmp_24_hdr[26], (DWORD)12) == FALSE) { sprintf(ErrorBuffer, "%s: Error writing file", lpFilename); _r3d_FormulateErrorString("r3d_SurfaceToBMP", ErrorBuffer, DD_OK); return FALSE; } LoopVar = 3930L; // 100x100 dpi if (r3d_FileWrite(hFile, &LoopVar, (DWORD)4) == FALSE) { sprintf(ErrorBuffer, "%s: Error writing file", lpFilename); _r3d_FormulateErrorString("r3d_SurfaceToBMP", ErrorBuffer, DD_OK); return FALSE; } if (r3d_FileWrite(hFile, &LoopVar, (DWORD)4) == FALSE) { sprintf(ErrorBuffer, "%s: Error writing file", lpFilename); _r3d_FormulateErrorString("r3d_SurfaceToBMP", ErrorBuffer, DD_OK); return FALSE; } if (r3d_FileWrite(hFile, &bmp_24_hdr[46], (DWORD)(54 - 46)) == FALSE) { sprintf(ErrorBuffer, "%s: Error writing file", lpFilename); _r3d_FormulateErrorString("r3d_SurfaceToBMP", ErrorBuffer, DD_OK); return FALSE; } // Scanlines in BMP's must be padded with zero bytes on long boundries dwPaddedBytes = ((_r3d_Surface[hSrc]->dwWidth * 3) % 4); if (dwPaddedBytes) dwPaddedBytes = 4 - dwPaddedBytes; // Allocate a scanline if (NULL == (_r3d_BGR = new unsigned char[(_r3d_Surface[hSrc]->dwWidth*3) + dwPaddedBytes])) { _r3d_FormulateErrorString("r3d_SurfaceToBMP", "Can not allocate memory", DD_OK); return FALSE; } // Set entire allocated scanline to 0, this also ensures that // the padded bytes will be zero ZeroMemory(&_r3d_BGR[0], (_r3d_Surface[hSrc]->dwWidth * 3) + dwPaddedBytes); // Write one scan line at a time unsigned long *SurfaceRGBA, dwColor; SurfaceRGBA = (unsigned long *)r3d_SurfaceGet(hSrc); for (LoopVar = (int)_r3d_Surface[hSrc]->dwHeight - 1;LoopVar >= 0;LoopVar--) { for (LoopVarX = 0;LoopVarX < (int)_r3d_Surface[hSrc]->dwWidth;LoopVarX++) { dwColor = SurfaceRGBA[(LoopVar * _r3d_Surface[hSrc]->dwWidth) + LoopVarX]; _r3d_BGR[(LoopVarX*3)] = r3d_SurfaceColorGetB(dwColor); _r3d_BGR[(LoopVarX*3)+1] = r3d_SurfaceColorGetG(dwColor); _r3d_BGR[(LoopVarX*3)+2] = r3d_SurfaceColorGetR(dwColor); } if (r3d_FileWrite(hFile, &_r3d_BGR[0], (_r3d_Surface[hSrc]->dwWidth * 3) + dwPaddedBytes) == FALSE) { sprintf(ErrorBuffer, "%s: Error writing file", lpFilename); _r3d_FormulateErrorString("r3d_SurfaceToBMP", ErrorBuffer, DD_OK); return FALSE; } } r3d_FileClose(hFile); _R3D_DELETE(_r3d_BGR); return TRUE; } LPDIRECTDRAW4 R3D_STDCALL r3d_GetDirectDraw(void) { return (_r3d_DirectDraw4); } LPDIRECTDRAWSURFACE4 R3D_STDCALL r3d_GetFrontBufferSurface(void) { return (_r3d_FrontBuffer4); } LPDIRECTDRAWSURFACE4 R3D_STDCALL r3d_GetBackBufferSurface(void) { return (_r3d_BackBuffer4); } LPDIRECTDRAWSURFACE4 R3D_STDCALL r3d_GetZBufferSurface(void) { return (_r3d_ZBuffer4); } LPDIRECT3D3 R3D_STDCALL r3d_GetDirect3D(void) { return (_r3d_Direct3D); } LPDIRECT3DDEVICE3 R3D_STDCALL r3d_GetDevice(void) { return (_r3d_Device); } LPDIRECT3DLIGHT R3D_STDCALL r3d_GetLight(void) { return (_r3d_Light); } LPDIRECT3DVIEWPORT3 R3D_STDCALL r3d_GetViewport(void) { return (_r3d_Viewport); } BOOL R3D_STDCALL r3d_SetFogAttributes(float fFogZStart, float fFogZEnd, float r, float g, float b) { //unsigned char a=0; _r3d_state.FogStart = fFogZStart; _r3d_state.FogEnd = fFogZEnd; // The render state values can be any RGB color, specified as an // RGBA color (the alpha component is ignored). // WRONG! _r3d_state.FogColor=(D3DCOLOR)D3DRGBA(D3DVAL(r),D3DVAL(g),D3DVAL(b),D3DVAL(a)); //_r3d_state.FogColor=((((unsigned long)(a)) << 24) | (((unsigned long)(r)) << 16) | (((unsigned long)(g)) << 8) | (unsigned long)(b)); _r3d_state.FogColor = ((((unsigned long)((r) * 255)) << 16) | (((unsigned long)((g) * 255)) << 8) | (unsigned long)((b) * 255)); if ((_r3d_hResult = _r3d_Device->SetRenderState(D3DRENDERSTATE_FOGENABLE, (DWORD)_r3d_state.bFog)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFogAttributes", "D3DRENDERSTATE_FOGENABLE", _r3d_hResult); return FALSE; } if ((_r3d_hResult = _r3d_Device->SetLightState(D3DLIGHTSTATE_FOGMODE, (DWORD)_r3d_state.bFog ? D3DFOG_LINEAR : D3DFOG_NONE)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFogAttributes", "D3DLIGHTSTATE_FOGMODE", _r3d_hResult); return FALSE; } if ((_r3d_hResult = _r3d_Device->SetLightState(D3DLIGHTSTATE_FOGSTART, *(DWORD *)(&_r3d_state.FogStart))) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFogAttributes", "D3DLIGHTSTATE_FOGSTART", _r3d_hResult); return FALSE; } if ((_r3d_hResult = _r3d_Device->SetLightState(D3DLIGHTSTATE_FOGEND, *(DWORD *)(&_r3d_state.FogEnd))) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFogAttributes", "D3DLIGHTSTATE_FOGEND", _r3d_hResult); return FALSE; } if ((_r3d_hResult = _r3d_Device->SetRenderState(D3DRENDERSTATE_FOGCOLOR, (DWORD)_r3d_state.FogColor)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFogAttributes", "D3DRENDERSTATE_FOGCOLOR", _r3d_hResult); return FALSE; } return TRUE; } BOOL R3D_STDCALL r3d_EnableFog(BOOL bEnable) { _r3d_state.bFog = bEnable; if ((_r3d_hResult = _r3d_Device->SetRenderState(D3DRENDERSTATE_FOGENABLE, (DWORD)_r3d_state.bFog)) != D3D_OK) { _r3d_FormulateErrorString("r3d_EnableFog", "D3DRENDERSTATE_FOGENABLE", _r3d_hResult); return FALSE; } if ((_r3d_hResult = _r3d_Device->SetLightState(D3DLIGHTSTATE_FOGMODE, (DWORD)_r3d_state.bFog ? D3DFOG_LINEAR : D3DFOG_NONE)) != D3D_OK) { _r3d_FormulateErrorString("r3d_EnableFog", "D3DLIGHTSTATE_FOGMODE", _r3d_hResult); return FALSE; } if ((_r3d_hResult = _r3d_Device->SetLightState(D3DLIGHTSTATE_FOGSTART, *(DWORD *)(&_r3d_state.FogStart))) != D3D_OK) { _r3d_FormulateErrorString("r3d_EnableFog", "D3DLIGHTSTATE_FOGSTART", _r3d_hResult); return FALSE; } if ((_r3d_hResult = _r3d_Device->SetLightState(D3DLIGHTSTATE_FOGEND, *(DWORD *)(&_r3d_state.FogEnd))) != D3D_OK) { _r3d_FormulateErrorString("r3d_EnableFog", "D3DLIGHTSTATE_FOGEND", _r3d_hResult); return FALSE; } if ((_r3d_hResult = _r3d_Device->SetRenderState(D3DRENDERSTATE_FOGCOLOR, (DWORD)_r3d_state.FogColor)) != D3D_OK) { _r3d_FormulateErrorString("r3d_EnableFog", "D3DRENDERSTATE_FOGCOLOR", _r3d_hResult); return FALSE; } return TRUE; } BOOL R3D_STDCALL r3d_EnableSpecular(BOOL bEnable) { _r3d_state.bSpecular = bEnable; if ((_r3d_hResult = _r3d_Device->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, (DWORD)_r3d_state.bSpecular)) != D3D_OK) { _r3d_FormulateErrorString("r3d_EnableSpecular", "SetRenderState(D3DRENDERSTATE_SPECULARENABLE, (DWORD)bEnable)", _r3d_hResult); return FALSE; } return TRUE; } BOOL R3D_STDCALL r3d_SetFilteringAndMipMapOptions(int Method) { // Texture-map filtering capabilities. General texture filtering flags // reflect which texture filtering modes you can set for the // D3DRENDERSTATE_TEXTUREMAG, D3DRENDERSTATE_TEXTUREMIN render states. // // D3DPTFILTERCAPS_NEAREST // Point sampling. The texel with coordinates nearest to the desired pixel // value is used. This applies to both zooming in and zooming out. If // either zooming in or zooming out is supported, then both must be // supported. // // D3DPTFILTERCAPS_LINEAR // Bilinear filtering. Chooses the texel that has nearest coordinates, // then performs a weighted average with the four surrounding texels to // determine the final color. This applies to both zooming in and zooming // out. If either zooming in or zooming out is supported, then both must // be supported. // // D3DPTFILTERCAPS_MIPNEAREST // Nearest mipmapping. Chooses the texel from the appropriate mipmap with // coordinates nearest to the desired pixel value. // // D3DPTFILTERCAPS_MIPLINEAR // Nearest mipmapping, with bilinear filtering applied to the result. // Chooses the texel from the appropriate mipmap that has nearest // coordinates, then performs a weighted average with the four surrounding // texels to determine the final color. // // D3DPTFILTERCAPS_LINEARMIPNEAREST // Linear interpolation between two point sampled mipmaps. Chooses the // nearest texel from the two closest mipmap levels, then performs linear // interpolation between them. // // D3DPTFILTERCAPS_LINEARMIPLINEAR // Trilinear interpolation between mipmaps. Performs bilinear filtering on // the two nearest mipmaps, then interpolates linearly between the two // colors to determine a final color. int iSupported[6]; // Assume FALSE iSupported[0] = iSupported[1] = iSupported[2] = iSupported[3] = iSupported[4] = iSupported[5] = 0; if (r3d_GetDeviceDesc()->dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_NEAREST) iSupported[0] = 1; if (r3d_GetDeviceDesc()->dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEAR) iSupported[1] = 1; if (r3d_GetDeviceDesc()->dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MIPNEAREST) iSupported[2] = 1; if (r3d_GetDeviceDesc()->dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_MIPLINEAR) iSupported[3] = 1; if (r3d_GetDeviceDesc()->dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEARMIPNEAREST) iSupported[4] = 1; if (r3d_GetDeviceDesc()->dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEARMIPLINEAR) iSupported[5] = 1; // If none are supported... return quietly if (iSupported[0] + iSupported[1] + iSupported[2] + iSupported[3] + iSupported[4] + iSupported[5] == 0) return TRUE; // If requested method is >=3 but is not supported, find // the highest available texture filtering method... // Find next highest method... If none available, select first // available BOOL bFound = FALSE; int LoopVar; if (iSupported[Method] == 0) { // Find the next available texture filtering method... for (LoopVar = Method;LoopVar < 6;LoopVar++) { if (iSupported[LoopVar] == 1) { bFound = TRUE; Method = LoopVar; break; } } if (bFound == FALSE) { // Find the first available texture filtering method... for (LoopVar = 0;LoopVar < 6;LoopVar++) { if (iSupported[LoopVar] == 1) { Method = LoopVar; break; } } } } // Level 0 is no mipmapping and no texture filtering // Level 1 is no mipmapping and texture filtering // Level 2 is mipmapping and no texture filtering // Level 3 is mipmapping and texture filtering // Level 4 is mipmapping+filtering and no texture filtering // Level 5 is mipmapping+filtering and texture filtering switch (Method) { case 0: // Kill Filtering if ((_r3d_hResult = _r3d_Device->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_POINT)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFilteringAndMipMapOptions", "SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_POINT )", _r3d_hResult); return FALSE; } if ((_r3d_hResult = _r3d_Device->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_POINT)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFilteringAndMipMapOptions", "SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_POINT )", _r3d_hResult); return FALSE; } // Kill MipMapping : RULE: ALWAYS ALTER MIPMAPPING OPTIONS BEFORE FILTERING OPTIONS! if ((_r3d_hResult = _r3d_Device->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTFP_NONE)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFilteringAndMipMapOptions", "SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTFP_NONE )", _r3d_hResult); return FALSE; } _r3d_state.FilterMethod = Method; break; case 1: // Kill MipMapping : RULE: ALWAYS ALTER MIPMAPPING OPTIONS BEFORE FILTERING OPTIONS! if ((_r3d_hResult = _r3d_Device->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTFP_NONE)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFilteringAndMipMapOptions", "SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTFP_NONE )", _r3d_hResult); return FALSE; } // Enable Filtering, if supported... if ((r3d_GetDeviceDesc()->dwFlags & D3DDD_TRICAPS) && (r3d_GetDeviceDesc()->dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEAR)) { if ((_r3d_hResult = _r3d_Device->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_LINEAR)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFilteringAndMipMapOptions", "SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR )", _r3d_hResult); return FALSE; } if ((_r3d_hResult = _r3d_Device->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_LINEAR)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFilteringAndMipMapOptions", "SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR )", _r3d_hResult); return FALSE; } } _r3d_state.FilterMethod = Method; break; case 2: // Kill Filtering if ((_r3d_hResult = _r3d_Device->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_POINT)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFilteringAndMipMapOptions", "SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_POINT )", _r3d_hResult); return FALSE; } if ((_r3d_hResult = _r3d_Device->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_POINT)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFilteringAndMipMapOptions", "SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_POINT )", _r3d_hResult); return FALSE; } // Enable POINT MipMapping : RULE: ALWAYS ALTER MIPMAPPING OPTIONS BEFORE FILTERING OPTIONS! if ((_r3d_hResult = _r3d_Device->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTFP_POINT)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFilteringAndMipMapOptions", "SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR )", _r3d_hResult); return FALSE; } _r3d_state.FilterMethod = Method; break; case 3: // Enable POINT MipMapping : RULE: ALWAYS ALTER MIPMAPPING OPTIONS BEFORE FILTERING OPTIONS! if ((_r3d_hResult = _r3d_Device->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTFP_POINT)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFilteringAndMipMapOptions", "SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR )", _r3d_hResult); return FALSE; } // Enable Filtering, if supported... if ((r3d_GetDeviceDesc()->dwFlags & D3DDD_TRICAPS) && (r3d_GetDeviceDesc()->dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEAR)) { if ((_r3d_hResult = _r3d_Device->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_LINEAR)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFilteringAndMipMapOptions", "SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR )", _r3d_hResult); return FALSE; } if ((_r3d_hResult = _r3d_Device->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_LINEAR)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFilteringAndMipMapOptions", "SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR )", _r3d_hResult); return FALSE; } } _r3d_state.FilterMethod = Method; break; case 4: // Kill Filtering if ((_r3d_hResult = _r3d_Device->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_POINT)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFilteringAndMipMapOptions", "SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_POINT )", _r3d_hResult); return FALSE; } if ((_r3d_hResult = _r3d_Device->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_POINT)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFilteringAndMipMapOptions", "SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_POINT )", _r3d_hResult); return FALSE; } // Enable LINEAR MipMapping : RULE: ALWAYS ALTER MIPMAPPING OPTIONS BEFORE FILTERING OPTIONS! if ((_r3d_hResult = _r3d_Device->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTFP_LINEAR)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFilteringAndMipMapOptions", "SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR )", _r3d_hResult); return FALSE; } _r3d_state.FilterMethod = Method; break; case 5: // Enable LINEAR MipMapping : RULE: ALWAYS ALTER MIPMAPPING OPTIONS BEFORE FILTERING OPTIONS! if ((_r3d_hResult = _r3d_Device->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTFP_LINEAR)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFilteringAndMipMapOptions", "SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR )", _r3d_hResult); return FALSE; } // Enable Filtering, if supported... if ((r3d_GetDeviceDesc()->dwFlags & D3DDD_TRICAPS) && (r3d_GetDeviceDesc()->dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEAR)) { if ((_r3d_hResult = _r3d_Device->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_LINEAR)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFilteringAndMipMapOptions", "SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR )", _r3d_hResult); return FALSE; } if ((_r3d_hResult = _r3d_Device->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_LINEAR)) != D3D_OK) { _r3d_FormulateErrorString("r3d_SetFilteringAndMipMapOptions", "SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR )", _r3d_hResult); return FALSE; } } _r3d_state.FilterMethod = Method; break; } return TRUE; } BOOL R3D_STDCALL r3d_SetBackgroundColor(float r, float g, float b) { _r3d_BackGroundRed = r; _r3d_BackGroundGreen = g; _r3d_BackGroundBlue = b; return TRUE; } void R3D_STDCALL r3d_GetVersion(int *major, int *tenths, int *hundredths) { // 3.00 = first beta release // 3.01 = final beta release // 3.02 = final release // 3.03 = bug fixes // 3.04 = added support for more than 32 video modes *major = 3; *tenths = 0; *hundredths = 3; } LPDIRECTDRAWSURFACE4 R3D_STDCALL r3d_DDSurfaceGet(int hDDSurface) { return (_r3d_DDSurface[hDDSurface]->lpSurface); } BOOL R3D_STDCALL r3d_DDSurfaceBlit(LPDIRECTDRAWSURFACE4 Src, LPDIRECTDRAWSURFACE4 Dst, int SrcWidth, int SrcHeight, int DstWidth, int DstHeight, int SrcMinx, int SrcMaxx, int SrcMiny, int SrcMaxy, int DstMinx, int DstMaxx, int DstMiny, int DstMaxy, BOOL bSrcColorKey, BOOL bDstColorKey) { RECT rectSrc, rectDst; DWORD dwFlags; _R3D_BLITCLIP((int)SrcWidth, (int)SrcHeight, (int)DstWidth, (int)DstHeight, SrcMinx, SrcMaxx, SrcMiny, SrcMaxy, DstMinx, DstMaxx, DstMiny, DstMaxy); rectSrc.left = SrcMinx; rectSrc.top = SrcMiny; rectSrc.right = SrcMaxx + 1; // Rect's must be Inclusive rectSrc.bottom = SrcMaxy + 1; // Rect's must be Inclusive rectDst.left = DstMinx; rectDst.top = DstMiny; rectDst.right = DstMaxx + 1; // Rect's must be Inclusive rectDst.bottom = DstMaxy + 1; // Rect's must be Inclusive if ((rectDst.bottom - rectDst.top) == (rectSrc.bottom - rectSrc.top) && (rectDst.right - rectDst.left) == (rectSrc.right - rectSrc.left)) { // BltFast candidate dwFlags = DDBLTFAST_NOCOLORKEY; if (bSrcColorKey || bDstColorKey) { dwFlags = 0; if (bSrcColorKey) dwFlags |= DDBLTFAST_SRCCOLORKEY; if (bDstColorKey) dwFlags |= DDBLTFAST_DESTCOLORKEY; } dwFlags |= DDBLTFAST_WAIT; if (Dst->BltFast(DstMinx, DstMiny, Src, &rectSrc, dwFlags) == DD_OK) { //r3d_MessageBox("It worked!","HEY!",MB_OK); return TRUE; } } // We can fall through down to here if BltFast fails (both surfaces // are not in video memory) or if the blit was never a BltFast // candidate dwFlags = DDBLT_WAIT; if (bSrcColorKey) dwFlags |= DDBLT_KEYSRC; if (bDstColorKey) dwFlags |= DDBLT_KEYDEST; if ((_r3d_hResult = Dst->Blt(&rectDst, Src, &rectSrc, dwFlags, NULL)) != DD_OK) { _r3d_FormulateErrorString("r3d_DDSurfaceBlit", "Dst->Blt()", _r3d_hResult); return FALSE; } return TRUE; } // MemoryLocation = 0 = System Memory // MemoryLocation = 1 = Display Memory BOOL R3D_STDCALL r3d_DDSurfaceCreateFromSurface(int *handle, int hSrc, int MemoryType) { DDSURFACEDESC2 ddsd; unsigned long *SurfaceRGBA, dwColor, x, y; unsigned char r, g, b; int LoopVar, TmpHandle; for (LoopVar = 0;LoopVar < _R3D_MAX_DDSURFACES;LoopVar++) { if (_r3d_bDDSurfaceDoesNotExist[LoopVar] == TRUE) { // Allocate Surface Structure Memory TmpHandle = LoopVar; if (NULL == (_r3d_DDSurface[TmpHandle] = new _R3D_DDSURFACE)) { _r3d_FormulateErrorString("r3d_DDSurfaceCreateFromSurface", "Can not allocate memory", DD_OK); return FALSE; } _r3d_DDSurface[TmpHandle]->lpSurface = NULL; // Allocate DirectDraw Surface _r3d_ProperlyInitDDSD(&ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; //ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; if (MemoryType == 0) ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; else if (MemoryType == 1) ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; ddsd.dwWidth = _r3d_Surface[hSrc]->dwWidth; ddsd.dwHeight = _r3d_Surface[hSrc]->dwHeight; //memcpy( &ddsd.ddpfPixelFormat, &_r3d_gpCurrentDriver->pCurrentDevice->pCurrentMode->ddsd.ddpfPixelFormat, sizeof(_r3d_gpCurrentDriver->pCurrentDevice->pCurrentMode->ddsd.ddpfPixelFormat) ); if ((_r3d_hResult = _r3d_DirectDraw4->CreateSurface(&ddsd, &_r3d_DDSurface[TmpHandle]->lpSurface, NULL)) != DD_OK) { _R3D_DELETE(_r3d_DDSurface[TmpHandle]); _r3d_FormulateErrorString("r3d_DDSurfaceCreateFromSurface", "_r3d_DirectDraw4->CreateSurface()", _r3d_hResult); return FALSE; } _r3d_bDDSurfaceDoesNotExist[TmpHandle] = FALSE; _r3d_DDSurface[TmpHandle]->dwWidth = _r3d_Surface[hSrc]->dwWidth; _r3d_DDSurface[TmpHandle]->dwHeight = _r3d_Surface[hSrc]->dwHeight; *handle = TmpHandle; break; } } // Copy _r3d_Surface to _r3d_DDSurface... // // Search on "Step 2.2: Set Up DirectDraw Surfaces" in DX docs // // "As when creating the primary surface, the pixel format for the // off-screen surface is assumed to be the same as the display mode // when it isn't provided in the surface description." // // Lock the surface _r3d_ProperlyInitDDSD(&ddsd); if ((_r3d_hResult = _r3d_DDSurface[TmpHandle]->lpSurface->Lock(NULL, &ddsd, DDLOCK_NOSYSLOCK | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL)) != DD_OK) { _R3D_RELEASE(_r3d_DDSurface[TmpHandle]->lpSurface); _R3D_DELETE(_r3d_DDSurface[TmpHandle]); _r3d_bDDSurfaceDoesNotExist[TmpHandle] = TRUE; _r3d_FormulateErrorString("r3d_DDSurfaceCreateFromSurface", "lpSurface->Lock", _r3d_hResult); return FALSE; } SurfaceRGBA = (unsigned long *)r3d_SurfaceGet(hSrc); for (y = 0;y < _r3d_DDSurface[TmpHandle]->dwHeight;y++) { for (x = 0;x < _r3d_DDSurface[TmpHandle]->dwWidth;x++) { dwColor = SurfaceRGBA[(y * (int)_r3d_Surface[hSrc]->dwWidth) + x]; r = r3d_SurfaceColorGetR(dwColor); g = r3d_SurfaceColorGetG(dwColor); b = r3d_SurfaceColorGetB(dwColor); switch (_r3d_PixelFormatCode) { case 0: _r3d_Unsupported_SetPixelRGB0(ddsd.lpSurface, ddsd.lPitch, x, y, r, g, b); break; case 1: _r3d_Unsupported_SetPixelRGB1(ddsd.lpSurface, ddsd.lPitch, x, y, r, g, b); break; case 2: _r3d_Unsupported_SetPixelR2Safe(ddsd.lpSurface, ddsd.lPitch, x, y, r); _r3d_Unsupported_SetPixelG2Safe(ddsd.lpSurface, ddsd.lPitch, x, y, g); _r3d_Unsupported_SetPixelB2Safe(ddsd.lpSurface, ddsd.lPitch, x, y, b); break; case 3: _r3d_Unsupported_SetPixelR3Safe(ddsd.lpSurface, ddsd.lPitch, x, y, r); _r3d_Unsupported_SetPixelG3Safe(ddsd.lpSurface, ddsd.lPitch, x, y, g); _r3d_Unsupported_SetPixelB3Safe(ddsd.lpSurface, ddsd.lPitch, x, y, b); break; case 4: _r3d_Unsupported_SetPixelRGB4(ddsd.lpSurface, ddsd.lPitch, x, y, r, g, b); break; case 5: _r3d_Unsupported_SetPixelRGB5(ddsd.lpSurface, ddsd.lPitch, x, y, r, g, b); break; } } } // Unlock and leave _r3d_DDSurface[TmpHandle]->lpSurface->Unlock(NULL); return TRUE; } int R3D_STDCALL r3d_DDSurfaceGetWidth(int handle) { if (_r3d_bDDSurfaceDoesNotExist[handle] == TRUE) { _r3d_FormulateErrorString("r3d_DDSurfaceGetWidth", "Invalid Surface Handle", DD_OK); return FALSE; } return (int)_r3d_DDSurface[handle]->dwWidth; } int R3D_STDCALL r3d_DDSurfaceGetHeight(int handle) { if (_r3d_bDDSurfaceDoesNotExist[handle] == TRUE) { _r3d_FormulateErrorString("r3d_DDSurfaceGetHeight", "Invalid Surface Handle", DD_OK); return FALSE; } return (int)_r3d_DDSurface[handle]->dwHeight; } BOOL R3D_STDCALL r3d_DDSurfaceDestroyAll(void) { int LoopVar; // We loop through all allocated surfaces // and delete all. for (LoopVar = 0;LoopVar < _R3D_MAX_DDSURFACES;LoopVar++) { r3d_DDSurfaceDestroy(LoopVar); // Ignore errors! } return TRUE; } BOOL R3D_STDCALL r3d_DDSurfaceDestroy(int handle) { if (_r3d_bDDSurfaceDoesNotExist[handle] == TRUE) { _r3d_FormulateErrorString("r3d_DDSurfaceDestroy", "Invalid Surface Handle", DD_OK); return FALSE; } _R3D_RELEASE(_r3d_DDSurface[handle]->lpSurface); _R3D_DELETE(_r3d_DDSurface[handle]); _r3d_bDDSurfaceDoesNotExist[handle] = TRUE; return TRUE; }