# Copyright (C) 2007 Miriam Ruiz # Copyright (C) 2007 Jens Seidel # Licensed under the GPL, see /usr/share/common-licenses/GPL Index: hex-a-hop.svn/packfile.h =================================================================== --- hex-a-hop.svn.orig/packfile.h 2007-09-20 00:48:52.000000000 +0200 +++ hex-a-hop.svn/packfile.h 2007-09-20 00:49:01.000000000 +0200 @@ -16,11 +16,21 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include +#include + +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define SWAP16(X) (X) +#define SWAP32(X) (X) +#else +#define SWAP16(X) SDL_Swap16(X) +#define SWAP32(X) SDL_Swap32(X) +#endif struct PackFile1 { class Entry { - int len; + int32_t len; public: char name[1]; @@ -73,10 +83,11 @@ if (numfiles || e || data) FATAL("Calling Packfile1::Read when already initialised."); - int size; + int32_t size; fseek(f, -(int)sizeof(size), SEEK_END); int end_offset = ftell(f); fread(&size, sizeof(size), 1, f); + size = SWAP32(size); fseek(f, end_offset - size, SEEK_SET); data = malloc(size); @@ -88,10 +99,12 @@ while ((void*)i < data_end) { numfiles++; + int32_t *data_length = (int32_t*)i; + *data_length = SWAP32(*data_length); i = i->GetNext(); } - e = new Entry* [numfiles]; + e = new Entry* [numfiles]; // CHECKME: where to delete? i = (Entry*)data; for (int j=0; jGetNext()) Index: hex-a-hop.svn/hex_puzzzle.cpp =================================================================== --- hex-a-hop.svn.orig/hex_puzzzle.cpp 2007-09-20 00:48:52.000000000 +0200 +++ hex-a-hop.svn/hex_puzzzle.cpp 2007-09-20 00:49:01.000000000 +0200 @@ -444,10 +444,12 @@ } -typedef int Tile; +// somewhere else Tile map[][] is assigned to an unsigned char not int32_t +// but the data file format expects it to be 32 bit wide!?? +typedef int32_t Tile; typedef int Dir; struct Pos{ - int x,y; + int32_t x,y; Pos() : x(0), y(0) {} Pos(int a, int b) : x(a), y(b) {} bool operator == (Pos const & p) const @@ -1495,9 +1497,9 @@ #define MAP_SIZE 30 char* special[MAP_SIZE][MAP_SIZE]; Tile map[MAP_SIZE][MAP_SIZE]; - int map_item[MAP_SIZE][MAP_SIZE]; + int32_t map_item[MAP_SIZE][MAP_SIZE]; int tileCount[NumTileTypes]; - int levelPar, levelDiff; + int32_t levelPar, levelDiff; int turboAnim; Pos player; int player_items[2]; @@ -1565,14 +1567,20 @@ fgetc(f); // Remove '\n' character - int par, diff; + int32_t par, diff; unsigned char bounds[4]; Pos playerStart; fread(&par, sizeof(par), 1, f); - if (version >= 4) + par = SWAP32(par); + + if (version >= 4) { fread(&diff, sizeof(diff), 1, f); + diff = SWAP32(diff); + } fread(bounds, sizeof(bounds), 1, f); - fread(&playerStart, sizeof(player), 1, f); + fread(&playerStart, sizeof(playerStart), 1, f); + playerStart.x = SWAP32(playerStart.x); + playerStart.y = SWAP32(playerStart.y); int highval=0; @@ -1821,8 +1829,8 @@ typedef unsigned int _fn(void*, unsigned int, unsigned int, FILE*); _fn * fn = (loadPtr ? (_fn*)fread_replace : (_fn*)fread); - int par = 99999, diff = 0; - int version; + int32_t par = 99999, diff = 0; + int16_t version; if (!f && !loadPtr) return getdiff ? diff : par; @@ -1831,7 +1839,11 @@ if (fn(&par, sizeof(par), 1, f) != 1) par = 99999; - if (fn(&diff, sizeof(diff), 1, f) != 1 || diff<0 || diff>10) + else + par = SWAP32(par); + size_t ret = fn(&diff, sizeof(diff), 1, f); + diff = SWAP32(diff); + if (ret != 1 || diff<0 || diff>10) diff = 0; #ifdef USE_LEVEL_PACKFILE @@ -1902,13 +1914,18 @@ return false; } + /** \brief Writes/reads game status to/from a file + * + * The game data file is written in little endian so it can be shared + * across different machines. + */ void _LoadSave(FILE* f, bool save) { typedef unsigned int _fn(void*, unsigned int, unsigned int, FILE*); _fn * fn = save ? (_fn*)fwrite : (loadPtr ? (_fn*)fread_replace : (_fn*)fread); #define VERSION 4 - int version = VERSION; + int version = VERSION; // 1--9 if (save) fprintf(f, "%d\n", version); else @@ -1935,13 +1952,26 @@ if (version==1) { for (int i=0; i=2 && version<=4) { @@ -1966,18 +1996,28 @@ memset(map_item, 0, sizeof(map_item)); } - if (version>=3) + if (version>=3) { + levelPar = SWAP32(levelPar); fn(&levelPar, 1, sizeof(levelPar), f); + levelPar = SWAP32(levelPar); + } else if (!save) levelPar = 0; - if (version>=4) + if (version>=4) { + levelDiff = SWAP32(levelDiff); fn(&levelDiff, 1, sizeof(levelDiff), f); + levelDiff = SWAP32(levelDiff); + } else if (!save) levelDiff = 0; fn(bounds, sizeof(bounds), 1, f); + player.x = SWAP32(player.x); + player.y = SWAP32(player.y); fn(&player, sizeof(player), 1, f); + player.x = SWAP32(player.x); + player.y = SWAP32(player.y); int offsetx=0, offsety=0; @@ -2016,24 +2056,27 @@ for (int j=bounds[2]; j<=bounds[3]; j++) if (special[i][j]) { - short len = strlen(special[i][j]); + int16_t len = strlen(special[i][j]); unsigned char x=i, y=j; fn(&x, sizeof(x), 1, f); fn(&y, sizeof(y), 1, f); + len = SWAP16(len); fn(&len, sizeof(len), 1, f); + len = SWAP16(len); fn(special[i][j], 1, len, f); } } else { while(1){ - short len; + int16_t len; unsigned char x, y; if (!fn(&x, sizeof(x), 1, f)) break; fn(&y, sizeof(y), 1, f); x += offsetx; y += offsety; fn(&len, sizeof(len), 1, f); + len = SWAP16(len); if (len<0) break; char* tmp = new char[len+1]; tmp[len] = 0; @@ -2398,10 +2441,12 @@ FILE* f = file_open(bmp, "rb"); if (!f) FATAL("Unable to open file", bmp); - short w,h; + int16_t w,h; fread(&w, sizeof(w), 1, f); fread(&h, sizeof(h), 1, f); - if (w>1500 || h>1500) FATAL("Invalid file", bmp); + w = SWAP16(w); + h = SWAP16(h); + if (w>1500 || h>1500 || w<=0 || h<=0) FATAL("Invalid file", bmp); tmp = new uint32[(int)w*h]; @@ -2414,9 +2459,12 @@ else { fread(&c, sizeof(c), 1, f); + c = SWAP32(c); cnt = c >> 24; - if (cnt==255) + if (cnt==255) { fread(&cnt, sizeof(cnt), 1, f); + cnt = SWAP32(cnt); + } } tmp[p] = c | 0xff000000; } Index: hex-a-hop.svn/savestate.h =================================================================== --- hex-a-hop.svn.orig/savestate.h 2007-09-20 00:48:52.000000000 +0200 +++ hex-a-hop.svn/savestate.h 2007-09-20 00:49:01.000000000 +0200 @@ -23,12 +23,16 @@ { friend struct HexPuzzle; + // CHECKME: If char is larger than 8 bits (== 1 byte???) + // the code is no longer big endian safe? SWAP16/32 is necessary? + // Or is a byte always of the same size as char, e.g. 16 bits, so + // that int16_t is equally saved on big and little endian systems? char * bestSolution; - int bestSolutionLength; - int bestScore; + int32_t bestSolutionLength; + int32_t bestScore; #define NUM_LAST_SCORES 19 - int lastScores[NUM_LAST_SCORES]; - int unlocked; + int32_t lastScores[NUM_LAST_SCORES]; + int32_t unlocked; public: LevelSave() { @@ -47,11 +51,24 @@ typedef unsigned int _fn(void*, unsigned int, unsigned int, FILE*); _fn * fn = save ? (_fn*)fwrite : (_fn*)fread; + // we write little endian data + bestSolutionLength = SWAP32(bestSolutionLength); + bestScore = SWAP32(bestScore); + for (int i=0; ilittle endian fwrite(&general, sizeof(general), 1, f); + general.SwapBytes(); // revert changes for(X* x=first; x; x=x->next) { - short len = strlen(x->name); + int16_t len = strlen(x->name); + len = SWAP16(len); fwrite(&len, sizeof(len), 1, f); - fwrite(x->name, len, 1, f); + len = SWAP16(len); + fwrite(x->name, 1, len, f); x->LoadSave(f,save); @@ -214,6 +246,7 @@ if (v=='2') { fread(&general, sizeof(general), 1, f); + general.SwapBytes(); v = '1'; } if (v=='1') @@ -221,8 +254,9 @@ while(!feof(f)) { char temp[1000]; - short len; + int16_t len; fread(&len, sizeof(len), 1, f); + len = SWAP16(len); if (feof(f)) break; fread(temp, len, 1, f); temp[len] = 0;