I’m converting the following code from C# to C, and I don’t think I’m doing this correctly.
Entry3D and entry_3d are just structs that contain int lookup, length, extra in both cases.
Here’s the C# snippet (and it works perfectly fine):
BinaryReader reader = new BinaryReader(File.Open("artidx.mul", FileMode.Open));
BinaryReader art = new BinaryReader(File.Open("art.mul", FileMode.Open));
int count = (int)(reader.BaseStream.Length / 12);
int length = 0x10000;
Entry3D[] index = new Entry3D[length];
Console.WriteLine("Loading indexes {0}", count);
for (int i = 0; i < count && i < length; i++)
{
index[i].lookup = reader.ReadInt32();
index[i].length = reader.ReadInt32();
index[i].extra = reader.ReadInt32();
}
for (int i = count; i < length; ++i)
{
index[i].lookup = -1;
index[i].length = -1;
index[i].extra = -1;
}
Here’s the part in C that I’m having trouble with.
/* Init everything else */
printf( "Init maps & gfx" );
mapFile = fopen( "sd:/map0.mul", "rb" ),
artIdx = fopen( "sd:/artidx.mul", "rb" ),
art = fopen( "sd:/art.mul", "rb" );
if ( mapFile == NULL || artIdx == NULL || art == NULL )
{
printf( "D'oh, file loading failed: [%d][%d][%d]", mapFile == NULL, artIdx == NULL, art == NULL );
return(1);
}
/* Find artidx count and set length */
printf( "Init art index" );
fseek( artIdx, 0, SEEK_END );
int count = (ftell(artIdx) / 12), length = 0x10000; // 0x10000 entries availible
entry_3d entries[length];
fseek( artIdx, 0, SEEK_SET );
printf( "Reading art-idx, count=%d", count );
int i;
for( i = 0; i < count && i < length; i++ )
{
//printf( "loc: %u i: %u", ftell( artIdx ), i );
//fread( &entries[i], 12, 1, artIdx );
fread( &(entries[i].lookup), 4, 1, artIdx ); // read 12 bytes total
fread( &(entries[i].length), 4, 1, artIdx );
fread( &(entries[i].extra), 4, 1, artIdx );
}
printf( "Setting aidx remainders" );
for ( i = count; i < length; i++ )
{
entries[i].lookup = -1;
entries[i].length = -1;
entries[i].extra = -1;
}
It’s a bit impossible for me to debug the C part, but I can tell that it “dies” somewhere in the first for-loop. I’m guessing that it’s possibly reading past the end of the stream (even though it shouldn’t)?
I don’t see much wrong here. The code will work correctly on a linux/windows box.
Error handling could be improved.
It will not fail gracefully when the artidx file is not a multiple of 12 bytes.
I suppose this code could quite easily run out of memory on the Wii console. Try allocating the entry_3d array dynamically (using calloc/malloc). Also, try reducing the length to see whether you are running out of memory. It is not impossible that the libc implementation on the Wii doesn’t warn you when stack will overlap heap; embedded systems sometimes assume the programmers know all the intricacies and limits of the device (The Wii with it’s many processing chips is a very fine example of that in many respects, so I’d really consider this).
I’m pretty sure you know how to find the forums where the homebrew devs lurk. They might be able to shed some light here.