GP2X Sdl_endian.h


Pickle

Mega GP Mania
Joined
May 30, 2006
Messages
5,527
Location
Detroit, Michigan
Website
Visit site
I believe that SDL_endian.h doesnt compile properly in the devkitGP2X. This file is supposed to fix any endianness of the data being read from a buffer to the native endianness. Either im not providing the correct flags or it just doesnt work.

In the xBak project im porting the a file is opened and the data is loaded into a buffer array. The program then calls different functions depending on the size of data needed. These function's then call the SDL functions to do the byte swap's. The code worked on a win32, but it didnt work on the GP2X. The reason turned out to be that I was getting the wrong data bytes throwing everything off. I got around by doing the swap myself and not uses SDL_endian calls, but I consider only a temp hack.
Here a detailed description of what I see:

Part of the raw data: (rmfBuffer)
CODE

01 00 00 00 04 00 6B 72 6F 6E 64 6F 72 2E 30 30
31 00 00 E8 06 34 59 42 64 00 00 00 00 34 59 52



A rough sample of the code with the data bytes returned:
CODE

rmfBuffer.GetUint32LE(); // 00 00 00 01
rmfBuffer.GetUint16LE(); // 00 04
resourceFilename = rmfBuffer.GetString(RES_FILENAME_LEN); // 6B 72 6F 6E 64 6F 72 2E 30 30 31 00 00
numResources = rmfBuffer.GetUint16LE(); // 00 E8 (this should have been 06 E8)
bytesrmfBuffer.Skip(4); // 06 34 59 42 (skips 4)
unsigned int uintOffset = rmfBuffer.GetUint32LE(); // 64 00 00 00 (should have been all 0's)



Heres an example of one of the functions that then call the function in SDL_endian
CODE

uint16_t
FileBuffer::GetUint16LE()
{
if ((current) && (current + 2 <= buffer + size)) {
uint16_t n = 0;
n = SDL_SwapLE16(*((uint16_t *)current));
current += 2;
return n;
} else {
throw BufferEmpty(__FILE__, __LINE__);
}
return 0;
}
 
Pickle said:
CODE

resourceFilename = rmfBuffer.GetString(RES_FILENAME_LEN); // 6B 72 6F 6E 64 6F 72 2E 30 30 31 00 00
numResources = rmfBuffer.GetUint16LE(); // 00 E8 (this should have been 06 E8)
Are you sure rmfBuffer.GetString reads BOTH 0x00 bytes? Normally, only one end-of-string character is read (or I'm missing something). If so, that would screw up the alignment of the stream. Not sure though why it would work on win32.
 
Last edited by a moderator:
Sebastian said:
Pickle said:
CODE

resourceFilename = rmfBuffer.GetString(RES_FILENAME_LEN); // 6B 72 6F 6E 64 6F 72 2E 30 30 31 00 00
numResources = rmfBuffer.GetUint16LE(); // 00 E8 (this should have been 06 E8)
Are you sure rmfBuffer.GetString reads BOTH 0x00 bytes? Normally, only one end-of-string character is read (or I'm missing something). If so, that would screw up the alignment of the stream. Not sure though why it would work on win32.


I was suspect of the same thing, so I tried setting the buffer to the correct location. But it still wouldnt give me the correct data
But heres the that function.

CODE

std::string
FileBuffer::GetString(const unsigned int len)
{
if ((current) && (current + len <= buffer + size)) {
std::string s((char *)current);
current += len;
return s;
} else {
throw BufferEmpty(__FILE__, __LINE__);
}
return "";
}
 
Last edited by a moderator:
yeah your get string is coming back with 1 extra 00.

that or you passing in the wrong length.
 
YakumoFuji said:
yeah your get string is coming back with 1 extra 00.

that or you passing in the wrong length.
This the length
CODE

#define RES_FILENAME_LEN 13



the string is krondor.001
 
Last edited by a moderator:
Pickle said:
YakumoFuji said:
yeah your get string is coming back with 1 extra 00.

that or you passing in the wrong length.
This the length
CODE

#define RES_FILENAME_LEN 13



the string is krondor.001

Ok, that should read the string plus two 0x00 bytes. Do you know how to use a debugger, like OllyDebug? Usually, that visualizes the problem somewhat faster (for me, at least). I could do it for you, if you give me a stripped-down binary with those functions and the data file.
 
Last edited by a moderator:
Sebastian said:
Pickle said:
YakumoFuji said:
yeah your get string is coming back with 1 extra 00.

that or you passing in the wrong length.
This the length
CODE

#define RES_FILENAME_LEN 13



the string is krondor.001

Ok, that should read the string plus two 0x00 bytes. Do you know how to use a debugger, like OllyDebug? Usually, that visualizes the problem somewhat faster (for me, at least). I could do it for you, if you give me a stripped-down binary with those functions and the data file.


I have debugging setup with GDB, plus I cant do printf's to the command line. Ill run through the code again and put up some better results.
 
Last edited by a moderator:
Pickle said:
Sebastian said:
Pickle said:
YakumoFuji said:
yeah your get string is coming back with 1 extra 00.

that or you passing in the wrong length.
This the length
CODE

#define RES_FILENAME_LEN 13



the string is krondor.001

Ok, that should read the string plus two 0x00 bytes. Do you know how to use a debugger, like OllyDebug? Usually, that visualizes the problem somewhat faster (for me, at least). I could do it for you, if you give me a stripped-down binary with those functions and the data file.


I have debugging setup with GDB, plus I cant do printf's to the command line. Ill run through the code again and put up some better results.


I did a little more debugging, it actually looks like the bad values come in at the pointer code, so its messed up even before it gets to the SDL_endian functions. At this point, maybe its a bug in the compilier. The code works for windows, but wont for ARM. If anyone wants to play with this I think it will happen with a buffer and getting the data through the pointer as in the code above, you dont need a binary file or SDL_endian.h, i might at some point, but I have workaround code thats does the job.
 
Last edited by a moderator:
Perhaps this comes from unaligned casts, which you cant/shouldn't be doing. I don't see anything suggesting that current is aligned to 2 bytes, so the result is expected to be wrong.
 
Micket said:
Perhaps this comes from unaligned casts, which you cant/shouldn't be doing. I don't see anything suggesting that current is aligned to 2 bytes, so the result is expected to be wrong.
The original author recoded this functions and now it works.
I think it was because of this alignment problem, personally ive never used a pointer in that way.
Heres a sample of the code that works:

CODE

uint16_t n = *((uint8_t *)current);
current++;
n += *((uint8_t *)current) << 8;
current++;
return SDL_SwapLE16(n);
 
Last edited by a moderator:
Back
Top