Problem with fread
October 02, 2013 11:45PM
I'm trying to port my game to Wii and found a strange problem. Im am testing on Dolphin 3.5, as I do not own a Ninendo Wii.

First, I have to say that, to build it I had to comment out the "typedef unsigned long uintptr_t;" line in devkitpro/libogc/include/SDL/SDL_config_minimal.h.
SDL load images fine, I can show the game intro without a problem.

Then, if I did not have initFatDefault() it did not load the first file, game_data. Adding it, it now reads, well sort of (more on this ahead).

Adding initFatDefault, the code passes the game_data reading and then crashes on second file reading, of stages_data.

Now, if all files were not loaded, I would be "OK, something wrong with the SD card image or libFatInit", right? But the first one did read.. kind of. Looking at the struct loaded from file, it is empty. So it could fopen the file, but fread failed...

I added a checking and the return from fread isn't ok (it should be the same as sizeof(struct)).

I am kind of lost now, don't know what I can modify in the code to try something different. Is there anyone who can give me a hand, even if just some "try this and that"?

The code is at [sourceforge.net]

Relevant parts:
[sourceforge.net]
[sourceforge.net]

Any help is welcome :-P
Re: Problem with fread
October 03, 2013 06:05AM
Structs can be different sizes on different platforms/compilers due to changes in alignment. This is why it's a bad idea to read/write a struct directly to a file instead of reading/writing the individual member values (or the cheap fix, declaring the struct with packed alignment). There also may be problems with data endianess - the wii's PowerPC is a big endian cpu while nearly everything else these days is little endian.
Re: Problem with fread
October 03, 2013 02:46PM
I see. I noticed the problem when I printfed some values and all the short int are multiplied by 256 :-/
But, strangely, the sizeof(short) is the same (2), so maybe its the indian that is causing problem.

I tought that something like this could happen when I started using data in structs, but I tested in several platforms (x86, Playstation 2 Emotion Engine, PSP, Dingoo MIPS) and only now, with the Wii, I have issues. I discarded using something like XML as not all platforms I port support it and because of memory worries.
While I can convert all short to something else (my code already have a kind of versioning on files, so I can upgrade it when needed) like int or byte, what is your suggestion to avoid this issue? I confess, handling file data well is something I lack knowledge.

Thanks!



Edited 1 time(s). Last edit at 10/03/2013 02:49PM by protomank.
Re: Problem with fread
October 03, 2013 03:58PM
Just because individual data types are the same size, it does not mean structs will be the same size due to different alignment padding.
If your shorts look as if they're multiplied by 256 that definitely sounds like an endian problem. You will need to byteswap all variables wider than 1 byte, for example:
// byteswap a short
s = (s>>8) | (s<<8);
// byteswap an int
i = (i<<24)|((i<<8)&0xFF0000)|((i>>8)&0xFF00)|(i>>24);
Re: Problem with fread
October 03, 2013 04:20PM
Yes, I was looking at some examples similar to this you sent. I'll code this during the weekend, its a lot of conversion to do, but I think it will work in the end :)
Thanks again.
Re: Problem with fread
October 03, 2013 06:10PM
Tested the conversion a little bit. Works like a charm! Was able to start a stage, even with incomplete conversion :D
Lots of small short_to_little_endian() calls in my code, but it solves the problem! \o/

Looks like Wii will be gaining a new homebrew soon ;)
Thanks again for the help.
Sorry, only registered users may post in this forum.

Click here to login