BinaryReader and Big-Endian encoding on Xbox 360

by thomas 21. September 2010 17:13

While developing the low graphics system of my 3d engine, I encountered some issues while running my code on the Xbox 360.

The problem was that the PowerPC chip that powers the Xbox 360 runs in Big Endian Mode. This is a problem because windows programmers typically deal with Little Endian systems.

As explained in the following blog post:

Consider 67305985 in base 10 = 04030201 in base 16.
This value would be stored in a 4 byte integer as follows
        Little Endian: 0x01 0x02 0x03 0x04
           Big Endian: 0x04 0x03 0x02 0x01

This difference can lead to a lot a problems when reading data files on the Xbox360 that were generated on a PC.

There are 2 solutions to deal with this problem:

  1. You can convert the data you read at runtime. Note that you need to reverse the data by its logical data type. So if you read 4 int32, you have to reverse each integers individually.
  2. The second solution is to convert your data while compiling your resource files to the Xbox 360. With this method, you can directly read the data without additional processing.

XNA Content pipeline use the second solution but if you use your own resource compiling system, you need to know this.

 

The solution seems quite simple to implement but there is one big subtlety that you need to be aware of:

All standard IO classes of the .net framework like Stream or BitConverter use the platform endian format to read and write data except the BinaryReader and BinaryWriter classes!

You can have a lot of confusing errors if you don’t know that. Indeed if you look at the documentation, it says:


“BinaryReader reads this data type in little-endian format.”

I don’t understand why Microsoft made this choice. Unfortunatly, there is no way to configure the endian format of those classes.

So for example, if you write vertex buffer data to a memory stream with the BinaryWriter on the Xbox360 and then upload the byte array to the graphics card, this will not work because the byte array was encoded in little endian format.

The only solution I found was to create my own BinaryReader and BinaryWriter classes that use BitConverter which use the system endian format.

Tags:

Xbox 360 | Xna

Comments (2) -

Adam
Adam United States
11/29/2010 8:51:27 PM #

Hi, first off, great article. I think it really pin-pointed what my problem is.
That said, I was wondering if you'd be able to post your implementation of the BinaryReader/BinaryWriter classes that use BitConverter?

This would be greatly appreciated.
Thanks.

Michael Cummings
Michael Cummings United States
12/2/2010 2:12:22 PM #

My experience with BinaryReader on the XBox is that if you use BinaryReader.Read( byte, int, int) or it's overloads, it does not respect the systems Endianess. However the BinaryReader.Read[Type] methods do.

Month List