C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 02-03-2006, 09:16 PM   #1
Registered User
 
Join Date: Feb 2006
Posts: 6
Question Game Pointer Trouble?

I currently writing a game for DOS to help me learn the BIOS interrupts for the VGA. I'm having trouble loading graphics from my file format. The code compiles without any warnings. I'm using DJGPP for my compiler.

Here's the code I have...

The macros and structures for the graphics memory I currently have.
Code:
#define GraphicsSize(Block)	(Block->Size + 1)
#define GraphicsNumber(Block)	(Block->Number + 1)

struct GraphicsBlock
{
	unsigned char Size;		// Width & Height
	unsigned char Number;
	unsigned char **Images;
} Tiles;
The function to load the graphics into memory.
Code:
int LoadGraphics(const char *Filename, struct GraphicsBlock *Block)
{
	FILE *File;
	int Character;
	unsigned char Number;

	if ((File = fopen(Filename, "rb")) == NULL)
	{
		// Couldn't open the file: "Filename".
		return 1;
	}

	if ((Character = fgetc(File)) == EOF)
	{
		// Couldn't get the images sizes.
		fclose(File); return 1;
	}
	Block->Size = Character;

	if ((Character = fgetc(File)) == EOF)
	{
		// Couldn't get the number of images.
		fclose(File); return 1;
	}
	Block->Number = Character;

	Block->Images = malloc(GraphicsNumber(Block) * sizeof(unsigned char *));
	if (Block->Images == NULL)
	{
		// Out of memory for storing image locations.
		fclose(File); return 1;
	}

	for (Number = 0; Number <= Block->Number; Number++)
	{
		Block->Images[Number] = malloc(GraphicsSize(Block) * GraphicsSize(Block));
		if (Block->Images[Number] == NULL)
		{
			// Not enough memory for storing the images.
			for (Character = 0; Character < Number; Character++)
				free(Block->Images[Character]);
			fclose(File); free(Block->Images); return 1;
		}

		if (fread(Block->Images[Number], GraphicsSize(Block) * GraphicsSize(Block), 1, File)
			!= GraphicsSize(Block) * GraphicsSize(Block))
		{
			// Couldn't read images from the file.
			for (Character = 0; Character <= Number; Character++)
				free(Block->Images[Character]);
			fclose(File); free(Block->Images); return 1;
		}
	}

	fclose(File); return 0;
}
As you can see; the graphics is stored in an array of pointers that points to each graphics' location in memory. I wish to get this running on the lowest specs possible, so memory isn't stored in one long storage space.

My problem is with the fread() function. It's only is reading a single byte from the file, when it should be reading 64 bytes for the file I'm loading. Both feof() & ferror() reports that nothing is wrong.

I don't have any real ideas why this is happening. Anybody else know?

Thanks in advance.
Drahcir is offline   Reply With Quote
Old 02-03-2006, 09:29 PM   #2
Just Lurking
 
Dave_Sinkula's Avatar
 
Join Date: Oct 2002
Posts: 4,990
Why are you using this idiom?
Code:
for (Number = 0; Number <= Block->Number; Number++)
A minimal snippet of compileable code is always the fastest path to a solution.

Where are the calls to feof and ferror? Why not check for success instead of failure; i.e., you received the amount of data you expected?
__________________
7. It is easier to write an incorrect program than understand a correct one.
40. There are two ways to write error-free programs; only the third one works.*
Dave_Sinkula is offline   Reply With Quote
Old 02-03-2006, 09:52 PM   #3
Registered User
 
Join Date: Feb 2006
Posts: 6
Code:
for (Number = 0; Number <= Block->Number; Number++)
That the loop to load each tile. To allow more images in a GraphicsBlock, Block.Number starts at zero. The macro GraphicsNumber(Block) returns the correct amount.

Quote:
Originally Posted by Dave_Sinkula
A minimal snippet of compileable code is always the fastest path to a solution.
I haven't touched C code in quite a while now and to me, the code looks pretty minimal and readable to me. But I'm always open to ideas. Can you suggest a better way of doing this?

I just added and removed the feof() and ferror() functions to try to find out the reason for my trouble. Both functions returned 0 (for no errors).
Drahcir is offline   Reply With Quote
Old 02-03-2006, 09:56 PM   #4
Just Lurking
 
Dave_Sinkula's Avatar
 
Join Date: Oct 2002
Posts: 4,990
By compileable, I meant something that can compile.

[edit]Since for an array of size N, it is addressable from 0 to N-1. Or
Code:
for ( i =0; i < N; ++i)
[/edit]

Your idiom generally overshoots the array size by one.

[edit=2 or 3]But then I'm having an off night.
__________________
7. It is easier to write an incorrect program than understand a correct one.
40. There are two ways to write error-free programs; only the third one works.*

Last edited by Dave_Sinkula; 02-03-2006 at 09:58 PM.
Dave_Sinkula is offline   Reply With Quote
Old 02-03-2006, 10:18 PM   #5
Registered User
 
Join Date: Feb 2006
Posts: 6
The code is correct on my end. I have 7 images in my file. Which means when Block.Number is loaded, it should be set to 6 (just like the raw byte in the file). It's set this way since this function could never load a graphics file with zero images contained within it.

When the program needs to find out the total number of images loaded within a block, it'll use the GraphicsNumber() macro. The loop uses the Block->Number which is already the total number of images - 1.

So these two lines of code end up with the completely same outcome...
Code:
for (Number = 0; Number <= Block->Number; Number++)
Code:
for (Number = 0; Number < GraphicsNumber(Block); Number++)
Drahcir is offline   Reply With Quote
Old 02-03-2006, 10:24 PM   #6
Just Lurking
 
Dave_Sinkula's Avatar
 
Join Date: Oct 2002
Posts: 4,990
Code:
#define GraphicsSize(Block)	(Block->Size + 1)
#define GraphicsNumber(Block)	(Block->Number + 1)

struct GraphicsBlock
{
	unsigned char Size;		// Width & Height
	unsigned char Number;
	unsigned char **Images;
} Tiles;

int LoadGraphics(const char *Filename, struct GraphicsBlock *Block)
{
	FILE *File;
	int Character;
	unsigned char Number;

	if ((File = fopen(Filename, "rb")) == NULL)
	{
		// Couldn't open the file: "Filename".
		return 1;
	}

	if ((Character = fgetc(File)) == EOF)
	{
		// Couldn't get the images sizes.
		fclose(File); return 1;
	}
	Block->Size = Character;

	if ((Character = fgetc(File)) == EOF)
	{
		// Couldn't get the number of images.
		fclose(File); return 1;
	}
	Block->Number = Character;

	Block->Images = malloc(GraphicsNumber(Block) * sizeof(unsigned char *));
	if (Block->Images == NULL)
	{
		// Out of memory for storing image locations.
		fclose(File); return 1;
	}

	for (Number = 0; Number <= Block->Number; Number++)
	{
		Block->Images[Number] = malloc(GraphicsSize(Block) * GraphicsSize(Block));
		if (Block->Images[Number] == NULL)
		{
			// Not enough memory for storing the images.
			for (Character = 0; Character < Number; Character++)
				free(Block->Images[Character]);
			fclose(File); free(Block->Images); return 1;
		}

		if (fread(Block->Images[Number], GraphicsSize(Block) * GraphicsSize(Block), 1, File)
			!= GraphicsSize(Block) * GraphicsSize(Block))
		{
			// Couldn't read images from the file.
			for (Character = 0; Character <= Number; Character++)
				free(Block->Images[Character]);
			fclose(File); free(Block->Images); return 1;
		}
	}

	fclose(File); return 0;
}
Quote:
MAKE Version 5.2 Copyright (c) 1987, 2000 Borland
c:\progra~1\lint\lint-nt.exe -Ic:\progra~1\borland\bcc55\include -Ic:\progra~1\lint std.lnt env-sled.lnt co-bc5.lnt -zero test.c -oo(test.lob)
PC-lint for C/C++ (NT) Ver. 8.00e, Copyright Gimpel Software 1985-2001

--- Module: test.c
test.c 13 error [Error 40] Undeclared identifier 'FILE'
test.c 13 error [Error 40] Undeclared identifier 'File'
test.c 13 error [Warning 522] Expected void type, assignment, increment or decrement
test.c 14 error [Error 42] Expected a statement
test.c 15 error [Error 42] Expected a statement
test.c 17 error [Error 40] Undeclared identifier 'File'
test.c 17 error [Info 718] Symbol 'fopen' undeclared, assumed to return int
test.c 17 error [Info 746] call to function 'fopen()' not made in the presence of a prototype
test.c 17 error [Error 63] Expected an lvalue
test.c 17 error [Error 40] Undeclared identifier 'NULL'
test.c 23 error [Error 40] Undeclared identifier 'Character'
test.c 23 error [Info 718] Symbol 'fgetc' undeclared, assumed to return int
test.c 23 error [Info 746] call to function 'fgetc()' not made in the presence of a prototype
test.c 23 error [Error 40] Undeclared identifier 'File'
test.c 23 error [Error 63] Expected an lvalue
test.c 23 error [Error 40] Undeclared identifier 'EOF'
test.c 26 error [Info 718] Symbol 'fclose' undeclared, assumed to return int
test.c 26 error [Info 746] call to function 'fclose()' not made in the presence of a prototype
test.c 26 error [Error 40] Undeclared identifier 'File'
test.c 28 error [Error 40] Undeclared identifier 'Character'
test.c 30 error [Error 40] Undeclared identifier 'Character'
test.c 30 error [Error 40] Undeclared identifier 'File'
test.c 30 error [Error 63] Expected an lvalue
test.c 30 error [Error 40] Undeclared identifier 'EOF'
test.c 33 error [Error 40] Undeclared identifier 'File'
test.c 35 error [Error 40] Undeclared identifier 'Character'
test.c 37 error [Info 718] Symbol 'malloc' undeclared, assumed to return int
test.c 37 error [Info 746] call to function 'malloc()' not made in the presence of a prototype
test.c 37 error [Error 64] Type mismatch (assignment) (unsigned char ** = int)
test.c 38 error [Error 40] Undeclared identifier 'NULL'
test.c 41 error [Error 40] Undeclared identifier 'File'
test.c 44 error [Error 40] Undeclared identifier 'Number'
test.c 44 error [Error 63] Expected an lvalue
test.c 44 error [Error 40] Undeclared identifier 'Number'
test.c 44 error [Error 40] Undeclared identifier 'Number'
test.c 44 error [Error 52] Expected an lvalue
test.c 46 error [Error 40] Undeclared identifier 'Number'
test.c 46 error [Warning 516] 'Symbol malloc()' has arg. type conflict (arg. no. 1 -- signed/unsigned) with line 37
test.c 37 error [Info 830] Location cited in prior message
test.c 46 error [Error 63] Expected an lvalue
test.c 47 error [Error 40] Undeclared identifier 'Number'
test.c 47 error [Error 40] Undeclared identifier 'NULL'
test.c 50 error [Error 40] Undeclared identifier 'Character'
test.c 50 error [Error 63] Expected an lvalue
test.c 50 error [Error 40] Undeclared identifier 'Character'
test.c 50 error [Error 40] Undeclared identifier 'Number'
test.c 50 error [Error 40] Undeclared identifier 'Character'
test.c 50 error [Error 52] Expected an lvalue
test.c 51 error [Info 718] Symbol 'free' undeclared, assumed to return int
test.c 51 error [Info 746] call to function 'free()' not made in the presence of a prototype
test.c 51 error [Error 40] Undeclared identifier 'Character'
test.c 52 error [Error 40] Undeclared identifier 'File'
test.c 52 error [Warning 516] 'Symbol free()' has arg. type conflict (arg. no. 1 -- basic) with line 51
test.c 51 error [Info 830] Location cited in prior message
test.c 55 error [Info 718] Symbol 'fread' undeclared, assumed to return int
test.c 55 error [Info 746] call to function 'fread()' not made in the presence of a prototype
test.c 55 error [Error 40] Undeclared identifier 'Number'
test.c 55 error [Error 40] Undeclared identifier 'File'
test.c 59 error [Error 40] Undeclared identifier 'Character'
test.c 59 error [Error 63] Expected an lvalue
test.c 59 error [Error 40] Undeclared identifier 'Character'
test.c 59 error [Error 40] Undeclared identifier 'Number'
test.c 59 error [Error 40] Undeclared identifier 'Character'
test.c 59 error [Error 52] Expected an lvalue
test.c 60 error [Error 40] Undeclared identifier 'Character'
test.c 61 error [Error 40] Undeclared identifier 'File'
test.c 61 error [Warning 516] 'Symbol free()' has arg. type conflict (arg. no. 1 -- basic) with line 51
test.c 51 error [Info 830] Location cited in prior message
test.c 65 error [Error 40] Undeclared identifier 'File'

--- Global Wrap-up

test.c 11 error [Info 714] Symbol 'LoadGraphics(const char *, struct GraphicsBlock *)' (line 11, file test.c) not referenced
test.c 51 error [Warning 526] 'free()' (line 51, file test.c) not defined
test.c 51 error [Warning 628] no argument information provided for function 'free()' (line 51, file test.c)
test.c 26 error [Warning 526] 'fclose()' (line 26, file test.c) not defined
test.c 26 error [Warning 628] no argument information provided for function 'fclose()' (line 26, file test.c)
test.c 23 error [Warning 526] 'fgetc()' (line 23, file test.c) not defined
test.c 23 error [Warning 628] no argument information provided for function 'fgetc()' (line 23, file test.c)
test.c 37 error [Warning 526] 'malloc()' (line 37, file test.c) not defined
test.c 37 error [Warning 628] no argument information provided for function 'malloc()' (line 37, file test.c)
test.c 17 error [Warning 526] 'fopen()' (line 17, file test.c) not defined
test.c 17 error [Warning 628] no argument information provided for function 'fopen()' (line 17, file test.c)
test.c 9 error [Info 714] Symbol 'Tiles' (line 9, file test.c) not referenced
test.c 55 error [Warning 526] 'fread()' (line 55, file test.c) not defined
test.c 55 error [Warning 628] no argument information provided for function 'fread()' (line 55, file test.c)
Outputting to file test.lob
c:\progra~1\borland\bcc55\bin\bcc32 -P- -c @MAKE0000.@@@
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
test.c:
Error E2303 test.c 6: Type name expected
Error E2040 test.c 6: Declaration terminated incorrectly
Error E2451 test.c 13: Undefined symbol 'FILE' in function LoadGraphics
Error E2451 test.c 13: Undefined symbol 'File' in function LoadGraphics
Error E2140 test.c 14: Declaration is not allowed here in function LoadGraphics
Error E2140 test.c 15: Declaration is not allowed here in function LoadGraphics
Error E2451 test.c 17: Undefined symbol 'NULL' in function LoadGraphics
Error E2188 test.c 19: Expression syntax in function LoadGraphics
Error E2380 test.c 19: Unterminated string or character constant in function LoadGraphics
Error E2129 test.c 19: Character constant must be one or two characters long in function LoadGraphics
Error E2451 test.c 23: Undefined symbol 'EOF' in function LoadGraphics
Error E2188 test.c 25: Expression syntax in function LoadGraphics
Error E2380 test.c 25: Unterminated string or character constant in function LoadGraphics
Error E2129 test.c 25: Character constant must be one or two characters long in function LoadGraphics
Error E2188 test.c 32: Expression syntax in function LoadGraphics
Error E2380 test.c 32: Unterminated string or character constant in function LoadGraphics
Error E2129 test.c 32: Character constant must be one or two characters long in function LoadGraphics
Error E2451 test.c 35: Undefined symbol 'Number' in function LoadGraphics
Error E2451 test.c 37: Undefined symbol 'Number' in function LoadGraphics
Warning W8069 test.c 37: Nonportable pointer conversion in function LoadGraphics
Error E2188 test.c 40: Expression syntax in function LoadGraphics
Error E2451 test.c 44: Undefined symbol 'Number' in function LoadGraphics
Warning W8069 test.c 46: Nonportable pointer conversion in function LoadGraphics
Error E2188 test.c 49: Expression syntax in function LoadGraphics
Error E2379 test.c 50: Statement missing ; in function LoadGraphics
Error E2188 test.c 58: Expression syntax in function LoadGraphics
Error E2380 test.c 58: Unterminated string or character constant in function LoadGraphics
Error E2228 test.c 58: Too many error or warning messages in function LoadGraphics
*** 26 errors in Compile ***

** error 1 ** deleting test.obj
It's less easy this way.
__________________
7. It is easier to write an incorrect program than understand a correct one.
40. There are two ways to write error-free programs; only the third one works.*
Dave_Sinkula is offline   Reply With Quote
Old 02-03-2006, 10:31 PM   #7
Registered User
 
Join Date: Feb 2006
Posts: 6
That code wasn't complete. I only posted the structure and function because that's all I having trouble with. The code can compile correctly.

The fread() function is what I'm was having trouble with. The arrays are working correctly (well on my side at least)
Drahcir is offline   Reply With Quote
Old 02-04-2006, 01:04 AM   #8
and the hat of vanishing
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,214
> My problem is with the fread() function. It's only is reading a single byte from the file, when it should be reading 64 bytes for the file
But it is reading 64 bytes from the file, your call and your test are inconsistent.

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size = GraphicsSize(Block) * GraphicsSize(Block),
nmemb = 1,
You told it to read 1 element of whatever size that is, 64 I guess.

Written like this, it's an all or nothing deal, you either get the whole record or you get nothing, and the return result is either 0 or 1 records read.

If you want to go the other way and swap the middle two parameters, do this
fread(Block->Images[Number], 1, GraphicsSize(Block) * GraphicsSize(Block), File )
Then you can partially read a record and get any return result from 0 to say 64 (in this case)
Salem is offline   Reply With Quote
Old 02-04-2006, 02:53 AM   #9
Registered User
 
Join Date: Feb 2006
Posts: 6
Thanks for you help Salem. I've expected the function to return the total bytes read.
Drahcir is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
sorting number Leslie C Programming 8 05-20-2009 04:23 AM
Trouble Generating Game Algorithm justlivelife15 Game Programming 3 06-13-2007 09:58 AM
2D Game project requires extra C++ programmers, new or experienced drallstars Projects and Job Recruitment 2 05-16-2007 10:46 AM
PC Game project requires c++ programmers drallstars Projects and Job Recruitment 2 02-22-2006 12:23 AM
trouble with pointer to object drb2k2 C++ Programming 3 04-16-2003 03:10 PM


All times are GMT -6. The time now is 12:13 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22