Login
Username:

Password:

Remember me



Lost Password?

Register now!

Sections

Who's Online
93 user(s) are online (43 user(s) are browsing Forums)

Members: 1
Guests: 92

beworld, more...

Headlines

 
  Register To Post  

(1) 2 »
another port (was: need little help with big/little endian issues)
Home away from home
Home away from home


See User information
Tried to port another game to our os, and it crashes for me in some function, which is called read_level() , and, looks like quite possible endian issues.. Have anyone clue ? There is:

void read_level() {
  
clear_room();
  
char filestr[512];
  
int musictempbkgtempk;
  
char lcodeacode;
  if (
lvlCode 80) {
    
sprintf(filestrRESOURCE_PATH "rooms/rooms");
  } else {
    
sprintf(filestr"%srooms%sl%dr%d.room"support_pathDIRSEPlvlCodeareaCode);
  }
  
file fopen(filestr"rb");
  if (
file) {
    
hassaved 1;
    do {
      if (
lvlCode 80) {
    
fread(&lcodesizeof(char), 1file);
    
fread(&acodesizeof(char), 1file);
      }
      
fread(&bkgtempsizeof(int), 1file);
      
fread(&musictempsizeof(int), 1file);
      
fread(&lvlWidthsizeof(int), 1file);
      
fread(&lvlHeightsizeof(int), 1file);
      
fread(&startxsizeof(int), 1file);
      
fread(&startysizeof(int), 1file);
      
fread(thingssizeof(Thing), THINGMAXfile);
      for (
i=0;i<lvlWidth/SPR_SIZE;i++)
    for (
j=0;j<lvlHeight/SPR_SIZE;j++)
      for (
k=0;k<3;k++)
      
        
fread(&tilebackup[i][j][k], sizeof(int), 1file);
        
        
    } while ((
lcode != lvlCode || acode != areaCode) &&
         !
feof(file) && lvlCode 80);
    for (
i=0;i<lvlWidth/SPR_SIZE;i++)
      for (
j=0;j<lvlHeight/SPR_SIZE;j++)
    for (
k=0;k<3;k++)
      
tiles[i][j][k] = tilebackup[i][j][k];
    if (
bkgtemp || bkgtemp BKG_MAX 1bkgtemp 1;
    if (
musictemp || musictemp MUSIC_MAX 1musictemp 0;
    
clear_selection();
    
switch_music(musictemp0);
    
switch_background(bkgtemp);
    
fclose(file);
  } else {
    
loaderror 1;
    if (
lvlCode 80 || creatormode
      
set_up_input("The file was not found",1,-1,-1);
    else 
set_up_input("Make the level first!",1,-1,-1);
  }
}


Crashes exactly on the fread(&tilebackup[i][j][k], sizeof(int), 1, file); line, and all that probably because of [i][j][k] and way how it reads and later uses and where endianes can make differences ?


Edited by kas1e on 2018/1/19 7:27:30
Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: need little help with big/little endian issues
Just can't stay away
Just can't stay away


See User information
@kas1e

You have to byte swap each fread item that is bigger than one byte. For example using something like https://wiki.libsdl.org/SDL_SwapLE32

Assuming sizeof(int) gives 4 :)

Sizeof(Thing) complicates...things. You have to investigate this type and swap all its parts that are bigger than byte.

Sizeof(char) you can leave alone assuming that sizeof(char) is 1 byte.

Go to top
Re: need little help with big/little endian issues
Home away from home
Home away from home


See User information
@Capehill

Int4, char 1, yep :) "thing" is structure "Thing", in my case there it was 184 :)

So i converted all stuff which come till fread to "thing" which is declared as "Thing things[THINGMAX]" " . Did you mean i need to byteswap all the items in that structure which are bigger than 1 byte ? There is:

typedef struct thing {
  
float xyvxvystickxstickystartxstarty;
  
int speedjumpjumpdelayteledelay;
  
int widthheight;
  
int dir;
  
int timerstatus;
  
int linkislinked;
  
float anim;

  
int telethingontele;
  
int dead;
  
int collide[4];
  
int colltarget[4];

  
int typesubtype;
  
int pickupicygravmodfloatingsoliddeathtouchcrashspeed;
  
int nomovenohmovenovmoveinfrontinbackanimate;
Thing;


There is also Floats and few arrays :(

I of course can byteswap each elemnt just like:
things->speed = SDL_SwapLE32(things->speed);
and so on, and skip arrays (if they ok to be not byteswapped), and for floats find SDL_SwapFloatLE (yeah!)

Or maybe i can somehow in the .h point out that all strcuts should be endian aware, like maybe pragma packs or how it was..


And that crap worry me as well: fread(&tilebackup[i][j][k], sizeof(int), 1, file);
tilebackup are int tilebackup[LVLMAX][LVLMAX][3]; which in my case int[500][500][3].

Is tht endian problem don't affect arrays, just makes them stored reverse, but still no problems and have no needs to convert ? I mean last string there.



Edited by kas1e on 2018/1/17 21:16:37
Edited by kas1e on 2018/1/17 21:31:44
Edited by kas1e on 2018/1/17 21:48:20
Edited by kas1e on 2018/1/17 21:49:46
Edited by kas1e on 2018/1/17 22:03:49
Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: need little help with big/little endian issues
Quite a regular
Quite a regular


See User information
@kas1e

The endianness difference will cause every multi-byte field (all the ints, floats, etc) in that structure to be stored backwards, that is, all the bytes are stored in the opposite order. The contents of each byte are unaffected.

So, if the structure contains these values:

int speed 0x12345678;
int jump  0x90abcdef;


...then they will be stored (little endian) like this:
speedRel addr 078 56 34 12
jump
:  Rel addr 4ef cd ab 90


Strings are usually OK, as both big- and little-endian store strings starting from the lowest address (This also causes problems when you try to cast string data as a multi-byte integer).

One way to fix it is to read the data as big-endian, then go through and reverse each multi-byte field afterwards. Another is to read all the data with your own version of sscanf(), reversing each field byte by byte.

The simple reversal I am sure you know already:
uint32 BElong = ((LElong 0xFF000000) >> 24) +
                ((
LElong 0x00FF0000) >> 8) +
                ((
LElong 0x0000FF00) << 8) +
                ((
LElong 0x000000FF) << 24);

So that:
0x11223344
becomes
:
0x44332211


cheers
tony
Go to top
Re: need little help with big/little endian issues
Home away from home
Home away from home


See User information
@Tony
Yeah, right. I just use currently those SDL_SwapLE32 and SDL_SwapFloatLE32, which are the same:

For exmaple SDL_SwapLE32 are:

static __inline__ Uint32 SDL_Swap32(Uint32 x) {
    return((
x<<24)|((x<<8)&0x00FF0000)|((x>>8)&0x0000FF00)|(x>>24));



#define SDL_SwapLE32(X)    SDL_Swap32(X)


Kind of the same.

For floats i found they do it like this:

#if SDL_BYTEORDER == SDL_BIG_ENDIAN 

SDL_SwapFloat(float x)
{
    
union
    
{
        
float f;
        
Uint32 ui32;
    } 
swapper;
    
swapper.x;
    
swapper.ui32 SDL_Swap32(swapper.ui32);
    return 
swapper.f;


#define SDL_SwapFloatLE(X)  SDL_SwapFloat(X)
#endif



What worry me, is that i had to convert whole structure ! I mean, before it was just:

fread(things, sizeof(Thing), THINGMAX, file);

Now, i had to make it like:

fread(thingssizeof(Thing), THINGMAXfile);
      
      
things->SDL_SwapFloatLE(things->x);
      
things->SDL_SwapFloatLE(things->y);
      
things->vx SDL_SwapFloatLE(things->vx);
      
things->vy SDL_SwapFloatLE(things->vy);
      
things->stickx SDL_SwapFloatLE(things->stickx);
      
things->sticky SDL_SwapFloatLE(things->sticky);
      
things->startx SDL_SwapFloatLE(things->startx);
      
things->starty SDL_SwapFloatLE(things->starty);

      
things->speed SDL_SwapLE32(things->speed);
      
things->jump SDL_SwapLE32(things->jump);
      
things->jumpdelay SDL_SwapLE32(things->jumpdelay);
      
things->teledelay SDL_SwapLE32(things->teledelay);

      
things->width SDL_SwapLE32(things->width);
      
things->height SDL_SwapLE32(things->height);
      
      
things->dir SDL_SwapLE32(things->dir);

      
things->timer SDL_SwapLE32(things->timer);
      
things->status SDL_SwapLE32(things->status);
      
      
things->link SDL_SwapLE32(things->link);
      
things->islinked SDL_SwapLE32(things->islinked);
 
      
things->anim SDL_SwapFloatLE(things->anim);

      
things->telething SDL_SwapLE32(things->telething);
      
things->ontele SDL_SwapLE32(things->ontele);

      
things->dead SDL_SwapLE32(things->dead);
 
      
things->type SDL_SwapLE32(things->type);
      
things->subtype SDL_SwapLE32(things->subtype);
  
      
things->pickup SDL_SwapLE32(things->pickup);
      
things->icy SDL_SwapLE32(things->icy);
      
things->gravmod SDL_SwapLE32(things->gravmod);
      
things->floating SDL_SwapLE32(things->floating);
      
things->solid SDL_SwapLE32(things->solid);
      
things->deathtouch SDL_SwapLE32(things->deathtouch);
      
things->crashspeed SDL_SwapLE32(things->crashspeed);

      
things->nomove SDL_SwapLE32(things->nomove);
      
things->nohmove SDL_SwapLE32(things->nohmove);
      
things->novmove SDL_SwapLE32(things->novmove);
      
things->infront SDL_SwapLE32(things->infront);
      
things->inback SDL_SwapLE32(things->inback);
      
things->animate SDL_SwapLE32(things->animate);


That suck of course, and, i still skip 2 arrays from that structure, as dunno how to convert them:

int collide[4];
int colltarget[4];


I probably should do it like:

things->collide[0] = SDL_SwapLE32(things->collide[0]);
things->collide[1] = SDL_SwapLE32(things->collide[1]);
things->collide[2] = SDL_SwapLE32(things->collide[2]);
things->collide[3] = SDL_SwapLE32(things->collide[3]);


things->colltarget[0] = SDL_SwapLE32(things->colltarget[0]);
things->colltarget[1] = SDL_SwapLE32(things->colltarget[1]);
things->colltarget[2] = SDL_SwapLE32(things->colltarget[2]);
things->colltarget[3] = SDL_SwapLE32(things->colltarget[3]);


What a crap :)

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: need little help with big/little endian issues
Home away from home
Home away from home


See User information
@capehill,tony
I have another idea: maybe easy route to convert just all data files from which fread happens to big endian order and keep game's code as it ?

edit: but that probably unpossible, as there can be all kind of types, some of which need to swap, some of which don't , as well as it all shifts, so we can't just convert whole data file like "its all ints" ..


Edited by kas1e on 2018/1/18 8:52:13
Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: need little help with big/little endian issues
Home away from home
Home away from home


See User information
Or another idea: wrapper all fread and fwrite. I.e. redefine them like

#undef fread
#define fread lendian_fread
#undef fwrite
#define fwrite lendian_fwrite

size_t lendian_fwrite(const void *ptrsize_t sizesize_t nmemb,
                     
FILE *stream)
{
    if (
size != 4)
    {
        
/* Warn and exit */
    
}

    
int x 1;

    if ( *((
char*)&x) == 1)
    {
        
/* Little endian machine, use fwrite directly */
        
return fwrite(ptrsizenmembstream);
    }
    else
    {
        
/* Big endian machine, pre-process first */

        
unsigned char *buffer = (unsigned char*) ptr;

        for (
int i=0i<nmembi++)
        {           
            
unsigned char a buffer[4*i];
            
unsigned char b buffer[4*1];

            
buffer[4*i] = buffer[4*3];
            
buffer[4*1] = buffer[4*2];
            
buffer[4*2] = b;
            
buffer[4*3] = a;
        }

        return 
fwrite(ptrsizenmembstream);
    }  
}


Then we don't need to worry about manual convert all the time, enough to add it one time and it will deal with all stuff

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: need little help with big/little endian issues
Home away from home
Home away from home


See User information
Tried to make replacement function, but fail. Will back to SDL_Swap32LE() again .. Its just too much of freads there , and they all of different use. For example simple ones are fine to replace are:

fread(&contlvlsizeof(int), 1file);
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
contlvl SDL_SwapLE32(contlvl);
#endif



But what about those ones ?:

fread(&tilebackup[i][j][k], sizeof(int), 1,file);

#define ROOMMAX 100
fread(enemdeadsizeof(int), ROOMMAXfile);

fread(tiles[i][j], sizeof(int), 3file);

if (!
fread(&((get_bossvars())[BOSSMAX-1]), sizeof(int), 1file))


Probably second one can be something like:

#define ROOMMAX 100
fread(enemdeadsizeof(int), ROOMMAXfile);
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
for(int i;i<ROOMMAX;i++)
{
    
enemded[i]=SDL_SwapLE32(enemded[i]);
}
#endif


or kind..

There is current version of that mess if anyone in interst to see, changes i do done via #if SDL_BYTEORDER == SDL_BIG_ENDIAN. You can see how lots of fread and fwrites here, but i firstly want to replace only freads().

There is : game.c and thing.h

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: need little help with big/little endian issues
Just can't stay away
Just can't stay away


See User information
@kas1e

You cannot make a generic replacement for fread. It fails for structs and arrays. fread cannot know the details of your data.

You have to swallow your pride, make a loop when there are multiple items fread and convert all structs field by field.

Yes, it's annoying, boring and and an ultimate proof that the mankind cannot agree on the simplest things, ever.

Go to top
Re: need little help with big/little endian issues
Just can't stay away
Just can't stay away


See User information
@kas1e

http://capehill.kapsi.fi/beret/ I have compiled this game in 2013. Source code was an absolute nightmare.

Seems that some swaps are commented out, I can't remember why.

Check if it is any useful reference.

Go to top
Re: need little help with big/little endian issues
Home away from home
Home away from home


See User information
@capehill
Yeah, code looks like C, but assembler way :) probably you comment swaps in function which read saves, and they write by fwrite() when its all runs on our cpu, so already converted for fread.

Didnt you release it by any reassons ? I may try to compile latest version (1.2.1) and put on os4depot, if you didnt back in past of course :)

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: need little help with big/little endian issues
Home away from home
Home away from home


See User information
@Capehil
Oh i see now, it still was messy so you probably just give up with it. There some parts just missed, and in menu, and in game itself. But i will use your work as reference if you doesn't mind, just want to make it work as it works on win32 :)

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: another port (was: need little help with big/little endian issues)
Home away from home
Home away from home


See User information
@Capehill
Done with :) You was very close, just 2 issues was in your attempt: you just overlook one definition in that Thing structure (int status), so it wasn't byteswapped. And, there was about 7-8 floats, so pure SDL_Swap32LE did't go, and once i use SDL_SwapFloat32LE from SDL2 for them, it all start to works correctly, yeah!

There is:

Menu:
Resized Image
(press open in new tab for fullscreen)

In game:
Resized Image
(press open in new tab for fullscreen)

And ready port with all fancy things like icons and crap:
Beret_os4


@All
If someone have time, plz give it a test. It through will take a little of your time to unerstand contol (check options and read helpers), but once you done, game is fun enough.

There you can find more screenshots and videos:
http://www.indiedb.com/games/beret

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: another port (was: need little help with big/little endian issues)
Not too shy to talk
Not too shy to talk


See User information
@kas1e
Cool game Unfortunately can't save or exit game - "The file was not opened".

Go to top
Re: another port (was: need little help with big/little endian issues)
Home away from home
Home away from home


See User information
@mufa
Damn, that because when i made archive, i just use "a -r", without "-e" (pack empty directories), and lha just skip packing empty folder "saves", so game's code didn't find it, and can't create save files, and because of that also can't open a menu in the game.

In other words, just create in root of beret "saves" directory and all should be fine, i.e. saving will works, and you will have a tasty menu in the game as well when press "esc".
(btw, alt+enter to switch to window mode).

I reupload new fixed archive in same location:
Beret fixed

If you doesn't mind check if all is ok afer unpacking now. Thanks for testing!


Edited by kas1e on 2018/1/19 11:12:53
Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: another port (was: need little help with big/little endian issues)
Home away from home
Home away from home


See User information
@all
After a while of playing in Beret, i find it VERY worth of time we spend on porting !

Its really good stuff, remind me some modern "bolder-dash" + "incridebly machine" combo. Levels are very well polished, mathematic and physic in control very nice too. Checking the forums and thread about game, its one of good games for all times for some of them.

But that not all ! Game itself have inside custom level editor, which is unlockable. I.e. you can't just open it right away, you should complite the game first (get 120 midalions). But for those who can't, there is cheatcode : in the "map title", type "evilevilevil", and editor will opens.

And that not all, once you do so (i.e. open level editor), you can play other's ppls levels and maps. There was lots of level and maps, and the best ones are there: http://www.moddb.com/games/beret/addons

Through, usage of them are not easy enough (you unpacking any of addons to your "rooms" directory, then once you run game, with unlocked level editor, you can go to that level editor, and play levels like they only designed). Yeah, kind of suck, but author didn't make it all be structured better when he works on, and now probably will not.

For example i grabs few screebshots from different addons:

Advanced Mathematic:
Resized Image
(press open in new tab for full size)

Deception LCC:
Resized Image
(press open in new tab for full size)

Spin Cycle:
Resized Image
(press open in new tab for full size)

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: another port (was: need little help with big/little endian issues)
Just popping in
Just popping in


See User information
@kas1e

Wow very nice - perseverance pays off! :)

Go to top
Re: another port (was: need little help with big/little endian issues)
Not too shy to talk
Not too shy to talk


See User information
@kas1e
Quote:
I reupload new fixed archive in same location:


Thank you, now everything works fine

Go to top
Re: another port (was: need little help with big/little endian issues)
Home away from home
Home away from home


See User information
@mufa
Ok good then, uploaded to os4depot.

@All
Thanks for help and tests!

Join us to improve dopus5!
AmigaOS4 on youtube
Go to top
Re: another port (was: need little help with big/little endian issues)
Just can't stay away
Just can't stay away


See User information
@kas1e

I haven't had a chance to try your version yet but my old binary is quite slow on Sam440. It seems to draw lots alphablended stuff so if it uses actually SDL_BlitSurface, compositing might help.

Go to top

  Register To Post
(1) 2 »

 




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




Powered by XOOPS 2.0 © 2001-2023 The XOOPS Project