void hrInitBackground(void) { char CurDir[PATH_MAX], NewDir[PATH_MAX]; char hrImageName[PATH_MAX]; filehandle handle; JPEGDATA jp; unsigned char *pTempImage; udword i; getcwd(CurDir, PATH_MAX); hrImageName[0] = 0; if (singlePlayerGame) { hrChooseSinglePlayerBitmap(hrImageName); } else { hrChooseRandomBitmap(hrImageName); } getcwd(NewDir, PATH_MAX); dbgAssertOrIgnore(strcasecmp(CurDir,NewDir) == 0); // Load the bitmap image handle = fileOpen(hrImageName, FF_ReturnNULLOnFail|FF_IgnorePrepend); if (handle) { memset(&jp, 0, sizeof(jp)); jp.input_file = handle; JpegInfo(&jp); fileSeek(handle, 0, SEEK_SET); hrBackXSize = jp.width; hrBackYSize = jp.height; jp.ptr = (unsigned char *)memAllocAttempt((hrBackXSize) * (hrBackYSize) * 3, "BackgroundTemp", NonVolatile); if (jp.ptr == NULL) { return; } JpegRead(&jp); fileClose(handle); hrBackXSize = 1; hrBackYSize = 1; while (hrBackXSize < jp.width) hrBackXSize <<= 1; while (hrBackYSize < jp.height) hrBackYSize <<= 1; pTempImage = (unsigned char *)memAllocAttempt(hrBackXSize * hrBackYSize * 3, "BackgroundTemp", NonVolatile); memset(pTempImage, 0, hrBackXSize * hrBackYSize * 3); for (i = 0; i < jp.height; i++) memcpy(pTempImage + (hrBackXSize * 3 * i), jp.ptr + (jp.width * 3 * i), jp.width * 3); glGenTextures(1, &hrBackgroundTexture); trClearCurrent(); glBindTexture(GL_TEXTURE_2D, hrBackgroundTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, hrBackXSize, hrBackYSize, 0, GL_RGB, GL_UNSIGNED_BYTE, pTempImage); memFree(jp.ptr); memFree(pTempImage); hrBackXFrac = (GLfloat)jp.width / (GLfloat)hrBackXSize; hrBackYFrac = (GLfloat)jp.height / (GLfloat)hrBackYSize; hrBackXSize = jp.width; hrBackYSize = jp.height; } }
void hrInitBackground(void) { char CurDir[PATH_MAX], NewDir[PATH_MAX]; char hrImageName[PATH_MAX]; filehandle handle; JPEGDATA jp; udword imageWidth, imageHeight, i; udword pixelX, pixelY; udword screenWidth, screenHeight, Size, Top, Bottom; udword scaledImageGapSizeX, scaledImageGapSizeY; udword *pDest; unsigned char *pTempImage, *pTempLine, *pRGB; real32 subPixelX, subPixelY, scaleFactor; real32 subPixelIncrement; // used when scanning across the image for rescaling bool interpolatingImage = FALSE; // at screen position that rescaled image covers bool interpolatedImageLine = FALSE; // used image information during horizontal scan line /*GetCurrentDirectory(511, CurDir);*/ getcwd(CurDir, PATH_MAX); hrImageName[0] = 0; if (singlePlayerGame) { hrChooseSinglePlayerBitmap(hrImageName); } else { hrChooseRandomBitmap(hrImageName); } /*GetCurrentDirectory(511, NewDir);*/ getcwd(NewDir, PATH_MAX); dbgAssertOrIgnore(strcasecmp(CurDir,NewDir) == 0); // Load the bitmap image handle = fileOpen(hrImageName, FF_ReturnNULLOnFail|FF_IgnorePrepend); if (handle) { memset(&jp, 0, sizeof(jp)); jp.input_file = handle; JpegInfo(&jp); fileSeek(handle, 0, SEEK_SET); imageWidth = jp.width; imageHeight = jp.height; pTempImage = (unsigned char *)memAllocAttempt((imageWidth+1) * (imageHeight+1) * 3, "BackgroundTemp", NonVolatile); if (pTempImage == NULL) { return; } jp.ptr = pTempImage; JpegRead(&jp); fileClose(handle); Size = imageWidth*3; pTempLine = (unsigned char *)malloc(Size); for(i=0; i<(imageHeight/2); i++) { Top = i; Bottom = (imageHeight - 1) - i; memcpy(pTempLine, pTempImage + (Size * Top), Size); memcpy(pTempImage + (Size * Top), pTempImage + (Size * Bottom), Size); memcpy(pTempImage + (Size * Bottom), pTempLine, Size); } free(pTempLine); // Replicate the last line to appease the filter algorithm memcpy(&pTempImage[imageHeight * imageWidth * 3], &pTempImage[(imageHeight-1) * imageWidth * 3], imageWidth*3); if (!hrScaleMissionLoadingScreens || !hrDrawPixelsSupported()) { //no DrawPixels support, must use glcompat 640x480 quilting screenWidth = 640; screenHeight = 480; hrBackgroundImage = (udword*)malloc(screenWidth * screenHeight * 4); } else { scaleFactor = 1.1f; do { scaleFactor -= 0.1f; screenWidth = (udword)((real32)MAIN_WindowWidth * scaleFactor); screenHeight = (udword)((real32)MAIN_WindowHeight * scaleFactor); hrBackgroundImage = (udword *)malloc(screenWidth * screenHeight * 4); } while((hrBackgroundImage == NULL) && (scaleFactor > 0.4f)); } // if the memory was not succesfully allocated if (hrBackgroundImage == NULL) { memFree(pTempImage); return; } // scale (not stretch) the image to fit the current display size scaleFactor = (hrScaleMissionLoadingScreens || imageWidth > screenWidth || imageHeight > screenHeight) ? FE_SCALE_TO_FIT_FACTOR(screenWidth, screenHeight, imageWidth, imageHeight) : 1; subPixelIncrement = 1 / scaleFactor; scaledImageGapSizeX = (screenWidth - (imageWidth * scaleFactor)) / 2; scaledImageGapSizeY = (screenHeight - (imageHeight * scaleFactor)) / 2; pDest = (unsigned long*)hrBackgroundImage; if (pDest != NULL) { subPixelY = 0.0f; for (pixelY = 0; pixelY < screenHeight; pixelY++) { interpolatedImageLine = FALSE; subPixelX = 0.0f; for (pixelX = 0; pixelX < screenWidth; pixelX++) { interpolatingImage = TRUE; // blank area that a proportional resize won't cover if (pixelX < (scaledImageGapSizeX) || pixelY < (scaledImageGapSizeY) || pixelX > (screenWidth - scaledImageGapSizeX) || pixelY > (screenHeight - scaledImageGapSizeY)) { interpolatingImage = FALSE; pDest[pixelX] = 0xff000000; // AGBR (black) } // upscaling image (common case) else if (subPixelIncrement < 1.0f) { interpolatedImageLine = TRUE; pDest[pixelX] = hrGetInterpPixel(pTempImage, imageWidth, subPixelX, subPixelY); } // downscaling image (direct pixel sampling so won't be particularly smooth...) else { interpolatedImageLine = TRUE; pRGB = &pTempImage[(((unsigned long)subPixelY * imageWidth) + (unsigned long)subPixelX) * 3 ]; // RGBA -> ABGR pDest[pixelX] = 0xff000000 // A + ((unsigned long)pRGB[2] << 16) // B + ((unsigned long)pRGB[1] << 8 ) // G + ((unsigned long)pRGB[0] ); // R } #if FIX_ENDIAN pDest[pixelX] = FIX_ENDIAN_INT_32( pDest[pixelX] ); #endif if (interpolatingImage) { subPixelX += subPixelIncrement; } } if (interpolatedImageLine) { subPixelY += subPixelIncrement; } pDest += screenWidth; } } hrBackXSize = screenWidth; hrBackYSize = screenHeight; memFree(pTempImage); } }