Login
Username:

Password:

Remember me



Lost Password?

Register now!

Sections

Who's Online
42 user(s) are online (31 user(s) are browsing Forums)

Members: 1
Guests: 41

nbache, more...

Headlines

 
  Register To Post  

Endianes, again
Home away from home
Home away from home


See User information
@all
Can somebody explain this for me please. We do have such kind of structure:

// irrb header
        
struct IrrbHeader
        
{
            
c8      hSig[12];   // 'irrb vh.vl' eof
            
u32     hSigCheck;
            
u16     hVersion;
            
u16     hFill1;
            
u32     hFlags;     // compression/encryption/endianess/int bits
            
c8      hCreator[32];
            
u32     hMeshCount;
            
u32     hMeshBufferCount;
            
u32     hCRC;
        } 
PACK_STRUCT;


Now, we do:

struct irr::scene::IrrbHeader ih;
    
u32    sigCheck MAKE_IRR_ID('i','r','r','b');

    
Reader reader;

    
Reader->seek(0);
    if(
Reader->read(&ih,sizeof(ih)) != sizeof(ih))
        return 
0;

    
// sanity checks
    
   
printf("ih.hSigCheck=%s\n",&ih.hSigCheck);fflush(stdout);    

    if(
ih.hSigCheck != sigCheck)
        return 
0;

    
printf("pass the sanity check\n");



Problem is that for both little endian (win32) and big endian (os4), we do have first normal printf as ih.hSigCheck=irrb (so it correctly reads from binary file , and correctly print what is in buffer), but then, when we do this "if(ih.hSigCheck != sigCheck)" we fail on os4, but not on win32.

Should be MAKE_IRR_ID be reversed instead, like:
#ifdef __amigaos4__
    
u32    sigCheck MAKE_IRR_ID('b','r','r','i');
#else
    
u32    sigCheck MAKE_IRR_ID('i','r','r','b');
#endif


or something ?

But then, maybe it better to change whole structure after loading , like after reading header, we just do something like:

#ifdef __BIG_ENDIAN__
le2be(ih.hSig[12]);
le2be(ih.hSigCheck);
le2be(ih.hVersion);
le2be(ih.hFill1);
le2be(ih.hFlags); 
le2be(ih.hCreator[32]);
le2be(ih.hMeshCount);
le2be(ih.hMeshBufferCount);
le2be(ih.hCRC);
#endif


or kind of, so things will be swapped out already and no need for any more ifdefs and co ?

Go to top
Re: Endianes, again
Amigans Defender
Amigans Defender


See User information
I don't know how l2be functions works, but usually swap 16 bits and 32 bits has different functions. Not only. Single byte doesn't needs to be swapped if read is done byte by byte. And I don't think also that sigCheck needs to be swapped.
Only stuff read from disk needs to be swapped if saved in little endian mode. But if you create a variable at runtime it is already in big endian

i'm really tired...
Go to top
Re: Endianes, again
Home away from home
Home away from home


See User information
@Andrea
le2be it just my big function handle all stuf:

// generic little->big conversion
inline void littleBigEndian (void *xint sz) {
    
unsigned char *toConvert reinterpret_cast<unsigned char *>(x);
    
unsigned char tmp;
    for (
size_t i 0sz/2; ++i) {
        
tmp toConvert[i];
        
toConvert[i] = toConvert[sz 1];
        
toConvert[sz 1] = tmp;
    }
}
template <class Tinline void littleBigEndian (*x) {
    const 
int sz sizeof(T);
    
littleBigEndian(xsz);
}


As for sigCheck - yea, of course, only the on header itself need to be swapped. So i just doing now that:

//c8      hSig[12];   // 'irrb vh.vl' eof
    
littleBigEndian(&ih.hSigCheck);
    
littleBigEndian(&ih.hVersion);
    
littleBigEndian(&ih.hFill1);
    
littleBigEndian(&ih.hFlags);
    
//           c8      hCreator[32];

    
littleBigEndian(&ih.hMeshCount);
    
littleBigEndian(&ih.hMeshBufferCount);
    
littleBigEndian(&ih.hCRC);


But those 2 char array of 12 and 32 size need to be byteswapped too (not ourselfs, but their place inside of the arrays, like maybe something like for loop for size of hsig[12] and of hcreator[32]

Go to top
Re: Endianes, again
Quite a regular
Quite a regular


See User information
@kas1e

Hi,can you show how's MAKE_IRR_ID() defined?


In AmigaOS we have in iffparse.h:
#define MAKE_ID(a,b,c,d) \
((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d))

Go to top
Re: Endianes, again
Home away from home
Home away from home


See User information
@kas1e

Quote:
But those 2 char array of 12 and 32 size need to be byteswapped too


no, should not be swaped, only 16bit and 32bit needs swaping, I'm not sure about floats and doubles, but I guess so.

i was going to suggest something like:

swap_s("c8[12];u32;u16;u16;u32;c8[32];u32;u32;u32",&ih);

(NutsAboutAmiga)

Basilisk II for AmigaOS4
AmigaInputAnywhere
Excalibur
and other tools and apps.
Go to top
Re: Endianes, again
Home away from home
Home away from home


See User information
@All
Basically that the file i need to fix:

https://github.com/rxantos/tubras/blob ... s/CIrrBMeshFileLoader.cpp

And it's header with structures here:

https://github.com/rxantos/tubras/blob ... ons/CIrrBMeshFileLoader.h

If somebody can give it a go that will be very helpfull for faster port.

The important functions probably at first will be :

readmesh() and _readMesh() one.

Go to top
Re: Endianes, again
Just popping in
Just popping in


See User information
@kas1e

Quote:
Hi,can you show how's MAKE_IRR_ID() defined?

I'm with jabirulo-- I suspect that MAKE_IRR_ID() is designed for a little-endian system, and so swaps the order of the arguments compared to something like MAKE_ID() that's designed for a big-endian system.

Quote:
Should be MAKE_IRR_ID be reversed instead, like:
#ifdef __amigaos4__
    u32    sigCheck = MAKE_IRR_ID('b','r','r','i');
#else
    u32    sigCheck = MAKE_IRR_ID('i','r','r','b');
#endif

That would be a quick way of confirming that we're on the right track. But if we are, I think that conditionally defining MAKE_IRR_ID() would be a better way to deal with the problem.

Go to top
Re: Endianes, again
Home away from home
Home away from home


See User information
@msteed
Quote:

That would be a quick way of confirming that we're on the right track. But if we are, I think that conditionally defining MAKE_IRR_ID() would be a better way to deal with the problem.


Yeah, tested yesterday and it did pass the first check.

But anyway MAKE_IRR_ID() is:

#define MAKE_IRR_ID(c0, c1, c2, c3) \
        
((irr::u32)(irr::u8)(c0) | ((irr::u32)(irr::u8)(c1) << 8) | \
        
((irr::u32)(irr::u8)(c2) << 16) | ((irr::u32)(irr::u8)(c3) << 24 ))


But then, if i will just convert all the files of structures after they read by readchunk() , then it needs no worry about then..

Go to top

  Register To Post

 




Currently Active Users Viewing This Thread: 1 ( 0 members and 1 Anonymous Users )




Powered by XOOPS 2.0 © 2001-2016 The XOOPS Project