Esempio n. 1
0
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;
    }
}
Esempio n. 2
0
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);
    }
}