Beispiel #1
0
unsigned long fileSize(FILE *stream, char *name)
{
    long    n   = 0;
    FILE    *f  = stream;
    
    if (!stream) {
        if (!name)
            return 0;
        
        f = fileOpen(name, "r");
        if (!f)
            return 0;
    }
    
    fileSeek(f, 0, SEEK_END);
    n = fileTell(f);
    
    if (!stream) {
        fileClose(f);
    } else {
        fileSeek(f, 0, SEEK_SET);
    }
    
    return n;
}
size_t FileStream::write(const uint8_t *buffer, size_t size)
{
	if (!fileExist()) return 0;

	bool result = fileSeek(handle, 0, eSO_FileEnd);
	return fileWrite(handle, buffer, size);
}
uint16_t FileStream::readMemoryBlock(char* data, int bufSize)
{
	int len = min(bufSize, size - pos);
	int available = fileRead(handle, data, len);
	fileSeek(handle, pos, eSO_FileStart); // Don't move cursor now (waiting seek)
	return available;
}
Beispiel #4
0
/** IndexInput methods */
void FSDirectory::FSIndexInput::readInternal(uint8_t* b, const int32_t len) {
	SCOPED_LOCK_MUTEX(handle->THIS_LOCK)
	CND_PRECONDITION(handle!=NULL,"shared file handle has closed");
	CND_PRECONDITION(handle->fhandle>=0,"file is not open");

	if ( handle->_fpos != _pos ){
		if ( fileSeek(handle->fhandle,_pos,SEEK_SET) != _pos ){
			_CLTHROWA( CL_ERR_IO, "File IO Seek error");
		}
		handle->_fpos = _pos;
	}

	bufferLength = _read(handle->fhandle,b,len); // 2004.10.31:SF 1037836
	if (bufferLength == 0){
		_CLTHROWA(CL_ERR_IO, "read past EOF");
	}
	if (bufferLength == -1){
		//if (EINTR == errno) we could do something else... but we have
		//to guarantee some return, or throw EOF
		
		_CLTHROWA(CL_ERR_IO, "read error");
	}
	_pos+=bufferLength;
	handle->_fpos=_pos;
}
Beispiel #5
0
  void FSDirectory::FSIndexOutput::seek(const int64_t pos) {
    CND_PRECONDITION(fhandle>=0,"file is not open");
    BufferedIndexOutput::seek(pos);
	int64_t ret = fileSeek(fhandle,pos,SEEK_SET);
	if ( ret != pos ){
      _CLTHROWA(CL_ERR_IO, "File IO Seek error");
	}
  }
uint16_t FileStream::getDataPointer(char** data)
{
	int len = min(NETWORK_SEND_BUFFER_SIZE, size - pos);
	int available = fileRead(handle, buffer, len);
	fileSeek(handle, pos, eSO_FileStart); // Don't move cursor now
	*data = buffer;
	return available;
}
Beispiel #7
0
bool SdFileStream::seek(int len)
{
	if (len < 0) return false;

	bool result = fileSeek(handle, len, eSO_CurrentPos) >= 0;
	if (result) pos += len;
	return result;
}
Beispiel #8
0
uint32_t fileGetSize(const String fileName)
{
	file_t file = fileOpen(fileName.c_str(), eFO_ReadOnly);
	// Get size
	fileSeek(file, 0, eSO_FileEnd);
	int size = fileTell(file);
	fileClose(file);
	return size;
}
Beispiel #9
0
/**
 * Shell command () prints existing files or creates new ones.
 * @param args array of arguments
 * @return OK for success, SYSERR for syntax error
 */
command xsh_cat(int nargs, char *args[])
{
    int fd = 0;
    char c = 0;

    /* Output help, if '--help' argument was supplied */
    if ((nargs == 2 && strncmp(args[1], "--help", 6) == 0) || (nargs > 3) || (nargs < 2))
    {
        printf("Usage: cat [filename] or cat > [filename]\n");
        printf("Print file contents or copy console input into new file.\n");
        printf("\t--help\t display this help and exit\n");

        return OK;
    }
    if (nargs == 2)
    { /* Cat a file */
	fd = fileOpen(args[1]);
	if (SYSERR != fd)
	{
		fileSeek(fd, 0);
		while ((c = fileGetChar(fd)) != (char)SYSERR)
		{
			printf("%c", c);
		}
	}
	else
	{
		printf("File \"%s\" not found.\n", args[1]);
	}
	printf("\n\n");
	return OK;
    }
    if (strncmp(args[1], ">", 2))
    {
	    printf("ERROR: Cannot read from \"%s\", only CONSOLE!\n", args[1]);
	    return SYSERR;
    }
    if (SYSERR != fileOpen(args[2]))
    {
	    printf("ERROR: file \"%s\" already exists!\n", args[2]);
	    return SYSERR;
    }
    fd = fileCreate(args[2]);
    if (SYSERR == fd)
    {
	    printf("ERROR creating file \"%s\"\n", args[2]);
	    return SYSERR;
    }
    printf("Creating new file \"%s\".  Enter ~ to exit.\n", args[2]);
    while ((c = getc(CONSOLE)) != '~')
    {
	    filePutChar(fd, c);
    }
    fileClose(fd);

    return OK;
}
Beispiel #10
0
void fileSeekAbsNotBuffered(Card32 offset)
	{
#if OLD
	  sysSeek(file.id, offset, 0, file.name);
	  file.next = file.end;
#else
	 fileSeek(offset, 0);
#endif
	}
Beispiel #11
0
int64_t fgetsize(FILE *f)
{
    if (!f) return 0;
    
    int64_t size;
    // int64_t pos = _ftelli64(f);
    int64_t pos = fileTell(f);

    fileSeek(f, 0, SEEK_END);
    size = fileTell(f);
    fileSeek(f, pos, SEEK_SET);
    
    /*_fseeki64(f, 0, SEEK_END);
    size = _ftelli64(f);
    _fseeki64(f, pos, SEEK_SET);
    */
    return size;
}
Beispiel #12
0
FileStream::FileStream(String fileName)
{
	handle = fileOpen(fileName.c_str(), eFO_ReadOnly);
	if (handle == -1)
	{
		debugf("File wasn't found: %s", fileName.c_str());
		size = -1;
		pos = 0;
	}

	// Get size
	fileSeek(handle, 0, eSO_FileEnd);
	size = fileTell(handle);

	fileSeek(handle, 0, eSO_FileStart);
	pos = 0;

	debugf("send file: %s (%d bytes)", fileName.c_str(), size);
}
Beispiel #13
0
String fileGetContent(const String fileName)
{
	file_t file = fileOpen(fileName.c_str(), eFO_ReadOnly);
	// Get size
	fileSeek(file, 0, eSO_FileEnd);
	int size = fileTell(file);
	if (size <= 0)
	{
		fileClose(file);
		return "";
	}
	fileSeek(file, 0, eSO_FileStart);
	char* buffer = new char[size + 1];
	buffer[size] = 0;
	fileRead(file, buffer, size);
	fileClose(file);
	String res = buffer;
	delete[] buffer;
	return res;
}
Beispiel #14
0
int fileGetContent(const String fileName, char* buffer, int bufSize)
{
	if (buffer == NULL || bufSize == 0) return 0;
	*buffer = 0;

	file_t file = fileOpen(fileName.c_str(), eFO_ReadOnly);
	// Get size
	fileSeek(file, 0, eSO_FileEnd);
	int size = fileTell(file);
	if (size <= 0 || bufSize <= size)
	{
		fileClose(file);
		return 0;
	}
	buffer[size] = 0;
	fileSeek(file, 0, eSO_FileStart);
	fileRead(file, buffer, size);
	fileClose(file);
	return size;
}
Beispiel #15
0
/* Process AppleSingle/Double format data. */
static void doASDFormats(ctlTag magic)
	{
	long junk;
	long i;
	Card16 entryCount = 0;
	struct					/* AppleSingle/Double data */
		{
		unsigned long magic;/* Magic #, 00051600-single, 00051607-double */
		unsigned long version;/* Format version */
		da_DCL(EntryDesc, entries);/* Entry descriptors */
	} asd;

	asd.magic = magic;
	IN1(asd.version);

	/* Skip filler of 16 bytes*/
	IN1(junk);
	IN1(junk);
	IN1(junk);
	IN1(junk);

	/* Read number of entries */
	IN1(entryCount);
	da_INIT(asd.entries, entryCount,10);
	
	/* Read entry descriptors */
	for (i = 0; i < entryCount; i++)
		{
		EntryDesc *entry = da_INDEX(asd.entries,i);
	 	IN1(entry->id);
	 	IN1(entry->offset);
	 	IN1(entry->length);
		}

		for (i = 0; i < entryCount; i++)
			{
			EntryDesc  *entry = da_INDEX(asd.entries,i);
			if (entry->length > 0)
				switch (entry->id)
					{
				case 1:
					/* Data fork (AppleSingle); see if it's an sfnt */
		  			sfntRead(entry->offset + 4, -1);	/* Read plain sfnt file */
					  sfntDump();
					  sfntFree(1);		  
					break;
				case 2:
					/* Resource fork (AppleSingle/Double) */
					fileSeek(entry->offset, 0);
		 			resRead(entry->offset);			/* Read and dump Macintosh resource file */
					break;
					}
			}
	}
bool FileStream::attach(String fileName, FileOpenFlags openFlags)
{
	handle = fileOpen(fileName.c_str(), openFlags);
	if (handle == -1)
	{
		debugf("File wasn't found: %s", fileName.c_str());
		size = -1;
		pos = 0;
		return false;
	}

	// Get size
	fileSeek(handle, 0, eSO_FileEnd);
	size = fileTell(handle);

	fileSeek(handle, 0, eSO_FileStart);
	pos = 0;

	debugf("attached file: %s (%d bytes)", fileName.c_str(), size);
	return true;
}
Beispiel #17
0
FileStream::FileStream(String fileName)
{
	handle = fileOpen(fileName.c_str(), eFO_ReadOnly);
	if (handle == -1)
	{
		debugf("File wasn't found: %s", fileName.c_str());
		buffer = NULL;
		size = -1;
		pos = 0;
	}

	// Get size
	fileSeek(handle, 0, eSO_FileEnd);
	size = fileTell(handle);

	fileSeek(handle, 0, eSO_FileStart);
	pos = 0;
	buffer = new char[min(size, NETWORK_SEND_BUFFER_SIZE)];

	debugf("send file: %s (%d bytes)", fileName.c_str(), size);
}
Beispiel #18
0
unsigned long fileSize(FILE *stream, char *name)
{
#ifdef USE_FILE_API
    long    n = 0;
    FILE    *f = stream;
    
    if (!f) {
        if (!name)
            return 0;
        
        f = fileOpen(name, "r");
        if (!f)
            return 0;
    }
    
    fileSeek(f, 0, SEEK_END);
    n = fileTell(f);
    
    if (!stream) {
        fileClose(f);
    } else {
        fileSeek(f, 0, SEEK_SET);
    }
    
    return n;
#else
    FILE    *f      = stream;
    Err     error   = errNone;
    UInt32  size    = 0;
    
    if (!f || !f->fileRef)
        return 0;
        
    error = VFSFileSize(f->fileRef, &size);
    
    return (error)?-1:size;
#endif
}
Beispiel #19
0
static void DispSosu(void)
{
	uint64 count;

	cout("2\n");
	cout("3\n");
	cout("5\n");
	cout("7\n");

	fileSeek(SosuFp, SEEK_SET, 0);

	for(count = 0; count < SosuCnt; count++)
	{
		cout("%I64u\n", readValue64(SosuFp));
	}
}
Beispiel #20
0
static int IsSosu(uint64 value)
{
	uint64 count;

	fileSeek(SosuFp, SEEK_SET, 0);

	for(count = 0; count < SosuCnt; count++)
	{
		uint64 sosu = readValue64(SosuFp);

		if(0xffffffff < sosu) // 2bs
			break;

		if(value < sosu * sosu)
			break;

		if(value % sosu == 0)
			return 0;
	}
	return 1;
}
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;
    }
}
Beispiel #22
0
static void AddSosu(uint64 value)
{
	fileSeek(SosuFp, SEEK_END, 0);
	writeValue64(SosuFp, value);
	SosuCnt++;
}
Beispiel #23
0
void bmpDraw(Adafruit_ST7735 tft, String fileName, uint8_t x, uint8_t y) {

	file_t handle;

	int bmpWidth, bmpHeight;   		// W+H in pixels
	uint8_t bmpDepth;              	// Bit depth (currently must be 24)
	uint32_t bmpImageoffset;        // Start of image data in file
	uint32_t rowSize;               // Not always = bmpWidth; may have padding
	uint8_t sdbuffer[3 * BUFFPIXEL]; // pixel buffer (R+G+B per pixel)
	uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer
	boolean goodBmp = false;       	// Set to true on valid header parse
	boolean flip = true;        	// BMP is stored bottom-to-top
	int w, h, row, col;
	uint8_t r, g, b;
	uint32_t pos = 0, startTime = millis();

	if ((x >= tft.width()) || (y >= tft.height()))
		return;

	Serial.println();
	Serial.print("Loading image '");
	Serial.print(fileName);
	Serial.println('\'');

	handle = fileOpen(fileName.c_str(), eFO_ReadOnly);
	if (handle == -1)
	{
		debugf("File wasn't found: %s", fileName.c_str());
		fileClose(handle);
		return;
	}

	// Parse BMP header
	if (read16(handle) == 0x4D42) { 				// BMP signature
		debugf("File size: %d\n", read32(handle));	// get File Size
	    (void)read32(handle); 						// Read & ignore creator bytes
	    bmpImageoffset = read32(handle); 			// Start of image data
	    debugf("Image Offset: %d\n", bmpImageoffset);
	    debugf("Header size: %d\n", read32(handle));	// Read DIB header
	    bmpWidth  = read32(handle);
	    bmpHeight = read32(handle);
	    if(read16(handle) == 1) { 					// # planes -- must be '1'
	    	bmpDepth = read16(handle); 				// bits per pixel
	    	debugf("Bit Depth: %d\n", bmpDepth);
	    	if((bmpDepth == 24) && (read32(handle) == 0)) { // 0 = uncompressed
	    		goodBmp = true; 					// Supported BMP format -- proceed!

	    		debugf("Image size: %d x %d\n", bmpWidth, bmpHeight);

	            // BMP rows are padded (if needed) to 4-byte boundary
	            rowSize = (bmpWidth * 3 + 3) & ~3;

	            // If bmpHeight is negative, image is in top-down order.
	            // This is not canon but has been observed in the wild.
	            if(bmpHeight < 0) {
	              bmpHeight = -bmpHeight;
	              flip      = false;
	            }

	            // Crop area to be loaded
	            w = bmpWidth;
	            h = bmpHeight;
	            if((x+w-1) >= tft.width())  w = tft.width()  - x;
	            if((y+h-1) >= tft.height()) h = tft.height() - y;

	            // Set TFT address window to clipped image bounds
	            tft.setAddrWindow(x, y, x+w-1, y+h-1);

	            for (row=0; row<h; row++) { // For each scanline...

	              // Seek to start of scan line.  It might seem labor-
	              // intensive to be doing this on every line, but this
	              // method covers a lot of gritty details like cropping
	              // and scanline padding.  Also, the seek only takes
	              // place if the file position actually needs to change
	              // (avoids a lot of cluster math in SD library).
	              if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
	                pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
	              else     // Bitmap is stored top-to-bottom
	                pos = bmpImageoffset + row * rowSize;
	              if (fileTell(handle) != pos) {
	            	  fileSeek(handle, pos, eSO_FileStart);
		              buffidx = sizeof(sdbuffer); // Force buffer reload
	              }
	              for (col=0; col<w; col++) { // For each pixel...
	                // Time to read more pixel data?
	                if (buffidx >= sizeof(sdbuffer)) { // Indeed
	                  fileRead(handle, sdbuffer, sizeof(sdbuffer));
	                  buffidx = 0; // Set index to beginning
	                }

	                // Convert pixel from BMP to TFT format, push to display
	                b = sdbuffer[buffidx++];
	                g = sdbuffer[buffidx++];
	                r = sdbuffer[buffidx++];
	                tft.pushColor(tft.Color565(r,g,b));
	              } // end pixel
	            } // end scanline
	            Serial.printf("Loaded in %d ms\n", millis() - startTime);
	          } // end goodBmp
	    }
	}

	fileClose(handle);
	if(!goodBmp) Serial.println("BMP format not recognized.");
}
Beispiel #24
0
/* Split font set file into arg list */
static void makeArgs(char *filename) {
	int state;
	long i;
	long length;
	File file;
	char *start = NULL;	/* Suppress optimizer warning */

	/* Read whole file into buffer */
	fileOpen(&file, cbctx, filename, "r");
	fileSeek(&file, 0, SEEK_END);

	length = fileTell(&file);
	script.buf = cbMemNew(cbctx, length + 1);

	fileSeek(&file, 0, SEEK_SET);
	fileReadN(&file, length, script.buf);
	fileClose(&file);

	script.buf[length] = '\n';	/* Ensure termination */

	/* Parse buffer into args */
	state = 0;
	for (i = 0; i < length + 1; i++) {
		int c = script.buf[i];
		switch (state) {
			case 0:
				switch (c) {
					case ' ':
					case '\n':
					case '\t':
					case '\r':
					case '\f':
						break;

					case '#':
						state = 1;
						break;

					case '"':
						start = &script.buf[i + 1];
						state = 2;
						break;

					default:
						start = &script.buf[i];
						state = 3;
						break;
				}
				break;

			case 1:	/* Comment */
				if (c == '\n' || c == '\r') {
					state = 0;
				}
				break;

			case 2:	/* Quoted string */
				if (c == '"') {
					script.buf[i] = '\0';	/* Terminate string */
					*dnaNEXT(script.args) = start;
					state = 0;
				}
				break;

			case 3:	/* Space-delimited string */
				if (isspace(c)) {
					script.buf[i] = '\0';	/* Terminate string */
					*dnaNEXT(script.args) = start;
					state = 0;
				}
				break;
		}
	}
}
Beispiel #25
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);
    }
}