1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-15 01:24:45 +02:00

Added endian aware macros read_le_u16 and read_le_u32 to replace readNormalNR(). Fixes a couple of issues on big endian machines.

This commit is contained in:
Frank Zago
2011-10-08 01:23:46 +00:00
parent 8963293c07
commit 8403d177aa
11 changed files with 200 additions and 201 deletions

View File

@ -6,6 +6,8 @@
#include "../lib/CLodHandler.h" #include "../lib/CLodHandler.h"
#include "../lib/JsonNode.h" #include "../lib/JsonNode.h"
#include "../lib/vcmi_endian.h"
#include "CBitmapHandler.h" #include "CBitmapHandler.h"
#include "Graphics.h" #include "Graphics.h"
#include "CAnimation.h" #include "CAnimation.h"
@ -95,12 +97,12 @@ CDefFile::CDefFile(std::string Name):
palette = new SDL_Color[256]; palette = new SDL_Color[256];
int it = 0; int it = 0;
unsigned int type = readNormalNr(data, it); unsigned int type = read_le_u32(data + it);
it+=4; it+=4;
//int width = readNormalNr(data, it); it+=4;//not used //int width = read_le_u32(data + it); it+=4;//not used
//int height = readNormalNr(data, it); it+=4; //int height = read_le_u32(data + it); it+=4;
it+=8; it+=8;
unsigned int totalBlocks = readNormalNr(data, it); unsigned int totalBlocks = read_le_u32(data + it);
it+=4; it+=4;
for (unsigned int i= 0; i<256; i++) for (unsigned int i= 0; i<256; i++)
@ -117,9 +119,9 @@ CDefFile::CDefFile(std::string Name):
for (unsigned int i=0; i<totalBlocks; i++) for (unsigned int i=0; i<totalBlocks; i++)
{ {
size_t blockID = readNormalNr(data, it); size_t blockID = read_le_u32(data + it);
it+=4; it+=4;
size_t totalEntries = readNormalNr(data, it); size_t totalEntries = read_le_u32(data + it);
it+=12; it+=12;
//8 unknown bytes - skipping //8 unknown bytes - skipping
@ -128,7 +130,7 @@ CDefFile::CDefFile(std::string Name):
for (unsigned int j=0; j<totalEntries; j++) for (unsigned int j=0; j<totalEntries; j++)
{ {
size_t currOffset = readNormalNr(data, it); size_t currOffset = read_le_u32(data + it);
offset[blockID].push_back(currOffset); offset[blockID].push_back(currOffset);
it += 4; it += 4;
} }
@ -185,7 +187,7 @@ void CDefFile::loadFrame(size_t frame, size_t group, ImageLoader &loader) const
for (unsigned int i=0; i<sprite.height; i++) for (unsigned int i=0; i<sprite.height; i++)
{ {
//get position of the line //get position of the line
currentOffset=BaseOffset + SDL_SwapLE32(read_unaligned_u32(RWEntriesLoc + i)); currentOffset=BaseOffset + read_le_u32(RWEntriesLoc + i);
unsigned int TotalRowLength = 0; unsigned int TotalRowLength = 0;
while (TotalRowLength<sprite.width) while (TotalRowLength<sprite.width)
@ -211,7 +213,7 @@ void CDefFile::loadFrame(size_t frame, size_t group, ImageLoader &loader) const
} }
case 2: case 2:
{ {
currentOffset = BaseOffset + SDL_SwapLE16(read_unaligned_u16(FDef + BaseOffset)); currentOffset = BaseOffset + read_le_u16(FDef + BaseOffset);
for (unsigned int i=0; i<sprite.height; i++) for (unsigned int i=0; i<sprite.height; i++)
{ {
@ -242,7 +244,7 @@ void CDefFile::loadFrame(size_t frame, size_t group, ImageLoader &loader) const
{ {
for (unsigned int i=0; i<sprite.height; i++) for (unsigned int i=0; i<sprite.height; i++)
{ {
currentOffset = BaseOffset + SDL_SwapLE16(read_unaligned_u16(FDef + BaseOffset+i*2*(sprite.width/32))); currentOffset = BaseOffset + read_le_u16(FDef + BaseOffset+i*2*(sprite.width/32));
unsigned int TotalRowLength=0; unsigned int TotalRowLength=0;
while (TotalRowLength<sprite.width) while (TotalRowLength<sprite.width)

View File

@ -4,6 +4,7 @@
#include "CBitmapHandler.h" #include "CBitmapHandler.h"
#include "CDefHandler.h" #include "CDefHandler.h"
#include "../lib/CLodHandler.h" #include "../lib/CLodHandler.h"
#include "../lib/vcmi_endian.h"
#include <sstream> #include <sstream>
#include <boost/thread.hpp> #include <boost/thread.hpp>
@ -57,9 +58,9 @@ SDL_Surface * CPCXConv::getSurface() const
unsigned char add; unsigned char add;
int it=0; int it=0;
fSize = readNormalNr(pcx, it); it+=4; fSize = read_le_u32(pcx + it); it+=4;
width = readNormalNr(pcx, it); it+=4; width = read_le_u32(pcx + it); it+=4;
height = readNormalNr(pcx, it); it+=4; height = read_le_u32(pcx + it); it+=4;
if (fSize==width*height*3) if (fSize==width*height*3)
check1=true; check1=true;
else else
@ -142,9 +143,9 @@ SDL_Surface * CPCXConv::getSurface() const
bool isPCX(const unsigned char *header)//check whether file can be PCX according to 1st 12 bytes bool isPCX(const unsigned char *header)//check whether file can be PCX according to 1st 12 bytes
{ {
int fSize = readNormalNr(header, 0); int fSize = read_le_u32(header + 0);
int width = readNormalNr(header, 4); int width = read_le_u32(header + 4);
int height = readNormalNr(header, 8); int height = read_le_u32(header + 8);
return fSize == width*height || fSize == width*height*3; return fSize == width*height || fSize == width*height*3;
} }

View File

@ -1,6 +1,7 @@
#include "CCreatureAnimation.h" #include "CCreatureAnimation.h"
#include "../lib/CLodHandler.h" #include "../lib/CLodHandler.h"
#include "../lib/VCMI_Lib.h" #include "../lib/VCMI_Lib.h"
#include "../lib/vcmi_endian.h"
#include <assert.h> #include <assert.h>
#include "SDL_Extensions.h" #include "SDL_Extensions.h"
@ -46,11 +47,11 @@ CCreatureAnimation::CCreatureAnimation(std::string name) : internalFrame(0), onc
defName=name; defName=name;
i = 0; i = 0;
DEFType = readNormalNr<4>(i,FDef); i+=4; DEFType = read_le_u32(FDef + i); i+=4;
fullWidth = readNormalNr<4>(i,FDef); i+=4; fullWidth = read_le_u32(FDef + i); i+=4;
fullHeight = readNormalNr<4>(i,FDef); i+=4; fullHeight = read_le_u32(FDef + i); i+=4;
i=0xc; i=0xc;
totalBlocks = readNormalNr<4>(i,FDef); i+=4; totalBlocks = read_le_u32(FDef + i); i+=4;
i=0x10; i=0x10;
for (int it=0;it<256;it++) for (int it=0;it<256;it++)
@ -65,20 +66,20 @@ CCreatureAnimation::CCreatureAnimation(std::string name) : internalFrame(0), onc
for (int z=0; z<totalBlocks; z++) for (int z=0; z<totalBlocks; z++)
{ {
std::vector<int> frameIDs; std::vector<int> frameIDs;
int group = readNormalNr<4>(i,FDef); i+=4; //block ID int group = read_le_u32(FDef + i); i+=4; //block ID
totalInBlock = readNormalNr<4>(i,FDef); i+=4; totalInBlock = read_le_u32(FDef + i); i+=4;
for (j=SEntries.size(); j<totalEntries+totalInBlock; j++) for (j=SEntries.size(); j<totalEntries+totalInBlock; j++)
{ {
SEntries.push_back(SEntry()); SEntries.push_back(SEntry());
SEntries[j].group = group; SEntries[j].group = group;
frameIDs.push_back(j); frameIDs.push_back(j);
} }
/*int unknown2 = readNormalNr<4>(i,FDef);*/ i+=4; //TODO use me /*int unknown2 = read_le_u32(FDef + i);*/ i+=4; //TODO use me
/*int unknown3 = readNormalNr<4>(i,FDef);*/ i+=4; //TODO use me /*int unknown3 = read_le_u32(FDef + i);*/ i+=4; //TODO use me
i+=13*totalInBlock; //omitting names i+=13*totalInBlock; //omitting names
for (j=0; j<totalInBlock; j++) for (j=0; j<totalInBlock; j++)
{ {
SEntries[totalEntries+j].offset = readNormalNr<4>(i,FDef); i+=4; SEntries[totalEntries+j].offset = read_le_u32(FDef + i); i+=4;
} }
//totalEntries+=totalInBlock; //totalEntries+=totalInBlock;
for(int hh=0; hh<totalInBlock; ++hh) for(int hh=0; hh<totalInBlock; ++hh)
@ -173,14 +174,15 @@ int CCreatureAnimation::nextFrameT(SDL_Surface * dest, int x, int y, bool attack
unsigned char SegmentType, SegmentLength; unsigned char SegmentType, SegmentLength;
i = BaseOffset = SEntries[SIndex].offset; i = BaseOffset = SEntries[SIndex].offset;
/*int prSize = readNormalNr<4>(i, FDef);*/ i += 4; //TODO use me
int defType2 = readNormalNr<4>(i, FDef); i += 4; /*int prSize = read_le_u32(FDef + i);*/ i += 4; //TODO use me
FullWidth = readNormalNr<4>(i, FDef); i += 4; int defType2 = read_le_u32(FDef + i); i += 4;
FullHeight = readNormalNr<4>(i, FDef); i += 4; FullWidth = read_le_u32(FDef + i); i += 4;
SpriteWidth = readNormalNr<4>(i, FDef); i += 4; FullHeight = read_le_u32(FDef + i); i += 4;
SpriteHeight = readNormalNr<4>(i, FDef); i += 4; SpriteWidth = read_le_u32(FDef + i); i += 4;
LeftMargin = readNormalNr<4>(i, FDef); i += 4; SpriteHeight = read_le_u32(FDef + i); i += 4;
TopMargin = readNormalNr<4>(i, FDef); i += 4; LeftMargin = read_le_u32(FDef + i); i += 4;
TopMargin = read_le_u32(FDef + i); i += 4;
RightMargin = FullWidth - SpriteWidth - LeftMargin; RightMargin = FullWidth - SpriteWidth - LeftMargin;
BottomMargin = FullHeight - SpriteHeight - TopMargin; BottomMargin = FullHeight - SpriteHeight - TopMargin;
@ -194,11 +196,11 @@ int CCreatureAnimation::nextFrameT(SDL_Surface * dest, int x, int y, bool attack
{ {
ftcp += FullWidth * TopMargin; ftcp += FullWidth * TopMargin;
} }
int *RLEntries = (int*)(FDef + BaseOffset); ui32 *RLEntries = (ui32*)(FDef + BaseOffset);
BaseOffset += sizeof(int) * SpriteHeight; BaseOffset += sizeof(int) * SpriteHeight;
for (int i = 0; i < SpriteHeight; i++) for (int i = 0; i < SpriteHeight; i++)
{ {
BaseOffset = BaseOffsetor + RLEntries[i]; BaseOffset = BaseOffsetor + SDL_SwapLE32(RLEntries[i]);
if (LeftMargin > 0) if (LeftMargin > 0)
{ {
ftcp += LeftMargin; ftcp += LeftMargin;

View File

@ -4,6 +4,7 @@
#include <sstream> #include <sstream>
#include "../lib/CLodHandler.h" #include "../lib/CLodHandler.h"
#include "../lib/VCMI_Lib.h" #include "../lib/VCMI_Lib.h"
#include "../lib/vcmi_endian.h"
#include "CBitmapHandler.h" #include "CBitmapHandler.h"
/* /*
@ -80,7 +81,7 @@ void CDefHandler::openFromMemory(unsigned char *table, const std::string & name)
SDefEntryBlock &block = * reinterpret_cast<SDefEntryBlock *>(p); SDefEntryBlock &block = * reinterpret_cast<SDefEntryBlock *>(p);
unsigned int totalInBlock; unsigned int totalInBlock;
totalInBlock = SDL_SwapLE32(read_unaligned_u32(&block.totalInBlock)); totalInBlock = read_le_u32(&block.totalInBlock);
for (unsigned int j=SEntries.size(); j<totalEntries+totalInBlock; j++) for (unsigned int j=SEntries.size(); j<totalEntries+totalInBlock; j++)
SEntries.push_back(SEntry()); SEntries.push_back(SEntry());
@ -96,7 +97,7 @@ void CDefHandler::openFromMemory(unsigned char *table, const std::string & name)
} }
for (unsigned int j=0; j<totalInBlock; j++) for (unsigned int j=0; j<totalInBlock; j++)
{ {
SEntries[totalEntries+j].offset = SDL_SwapLE32(read_unaligned_u32(p)); SEntries[totalEntries+j].offset = read_le_u32(p);
p += 4; p += 4;
} }
//totalEntries+=totalInBlock; //totalEntries+=totalInBlock;
@ -222,7 +223,7 @@ SDL_Surface * CDefHandler::getSprite (int SIndex, const unsigned char * FDef, co
BaseOffset += sizeof(int) * SpriteHeight; BaseOffset += sizeof(int) * SpriteHeight;
for (unsigned int i=0;i<SpriteHeight;i++) for (unsigned int i=0;i<SpriteHeight;i++)
{ {
BaseOffset=BaseOffsetor + SDL_SwapLE32(read_unaligned_u32(RWEntriesLoc + i)); BaseOffset=BaseOffsetor + read_le_u32(RWEntriesLoc + i);
if (LeftMargin>0) if (LeftMargin>0)
ftcp += LeftMargin; ftcp += LeftMargin;
@ -260,7 +261,7 @@ SDL_Surface * CDefHandler::getSprite (int SIndex, const unsigned char * FDef, co
case 2: case 2:
{ {
BaseOffset = BaseOffsetor + SDL_SwapLE16(read_unaligned_u16(FDef + BaseOffsetor)); BaseOffset = BaseOffsetor + read_le_u16(FDef + BaseOffsetor);
for (unsigned int i=0;i<SpriteHeight;i++) for (unsigned int i=0;i<SpriteHeight;i++)
{ {
@ -304,7 +305,7 @@ SDL_Surface * CDefHandler::getSprite (int SIndex, const unsigned char * FDef, co
{ {
for (unsigned int i=0;i<SpriteHeight;i++) for (unsigned int i=0;i<SpriteHeight;i++)
{ {
BaseOffset = BaseOffsetor + SDL_SwapLE16(read_unaligned_u16(FDef + BaseOffsetor+i*2*(SpriteWidth/32))); BaseOffset = BaseOffsetor + read_le_u16(FDef + BaseOffsetor+i*2*(SpriteWidth/32));
if (LeftMargin>0) if (LeftMargin>0)
ftcp += LeftMargin; ftcp += LeftMargin;

View File

@ -24,6 +24,7 @@
#include "../lib/CDefObjInfoHandler.h" #include "../lib/CDefObjInfoHandler.h"
#include "../lib/CGameState.h" #include "../lib/CGameState.h"
#include "../lib/JsonNode.h" #include "../lib/JsonNode.h"
#include "../lib/vcmi_endian.h"
using namespace boost::assign; using namespace boost::assign;
using namespace CSDL_Ext; using namespace CSDL_Ext;
@ -670,7 +671,7 @@ Font * Graphics::loadFont( const char * name )
return NULL; return NULL;
} }
int magic = *(const int*)hlp; int magic = SDL_SwapLE32(*(const Uint32*)hlp);
if(len < 10000 || (magic != 589598 && magic != 589599)) if(len < 10000 || (magic != 589598 && magic != 589599))
{ {
tlog1 << "Suspicious font file (length " << len <<", fname " << name << "), logging to suspicious_" << name << ".fnt\n"; tlog1 << "Suspicious font file (length " << len <<", fname " << name << "), logging to suspicious_" << name << ".fnt\n";
@ -731,16 +732,16 @@ Font::Font(unsigned char *Data)
i = 32; i = 32;
for(int ci = 0; ci < 256; ci++) for(int ci = 0; ci < 256; ci++)
{ {
chars[ci].unknown1 = readNormalNr(data, i); i+=4; chars[ci].unknown1 = read_le_u32(data + i); i+=4;
chars[ci].width = readNormalNr(data, i); i+=4; chars[ci].width = read_le_u32(data + i); i+=4;
chars[ci].unknown2 =readNormalNr(data, i); i+=4; chars[ci].unknown2 = read_le_u32(data + i); i+=4;
//if(ci>=30) //if(ci>=30)
// tlog0 << ci << ". (" << (char)ci << "). Width: " << chars[ci].width << " U1/U2:" << chars[ci].unknown1 << "/" << chars[ci].unknown2 << std::endl; // tlog0 << ci << ". (" << (char)ci << "). Width: " << chars[ci].width << " U1/U2:" << chars[ci].unknown1 << "/" << chars[ci].unknown2 << std::endl;
} }
for(int ci = 0; ci < 256; ci++) for(int ci = 0; ci < 256; ci++)
{ {
chars[ci].offset = readNormalNr(data, i); i+=4; chars[ci].offset = read_le_u32(data + i); i+=4;
chars[ci].pixels = data + 4128 + chars[ci].offset; chars[ci].pixels = data + 4128 + chars[ci].offset;
} }
} }

View File

@ -1063,23 +1063,6 @@ void CSDL_Ext::setPlayerColor(SDL_Surface * sur, unsigned char player)
else else
tlog3 << "Warning, setPlayerColor called on not 8bpp surface!\n"; tlog3 << "Warning, setPlayerColor called on not 8bpp surface!\n";
} }
int readNormalNr (std::istream &in, int bytCon)
{
int ret=0;
int amp=1;
unsigned char byte;
if (in.good())
{
for (int i=0; i<bytCon; i++)
{
in.read((char*)&byte,1);
ret+=byte*amp;
amp<<=8;
}
}
else return -1;
return ret;
}
const TColorPutter CSDL_Ext::getPutterFor(SDL_Surface * const &dest, int incrementing) const TColorPutter CSDL_Ext::getPutterFor(SDL_Surface * const &dest, int incrementing)
{ {

View File

@ -722,30 +722,6 @@ extern DLL_EXPORT CLogger tlog6; //teal - AI info
throw; \ throw; \
} }
#if defined(linux) && defined(sparc)
/* SPARC does not support unaligned memory access. Let gcc know when
* to emit the right code. */
struct unaligned_Uint16 { ui16 val __attribute__(( packed )); };
struct unaligned_Uint32 { ui32 val __attribute__(( packed )); };
static inline ui16 read_unaligned_u16(const void *p)
{
const struct unaligned_Uint16 *v = (const struct unaligned_Uint16 *)p;
return v->val;
}
static inline ui32 read_unaligned_u32(const void *p)
{
const struct unaligned_Uint32 *v = (const struct unaligned_Uint32 *)p;
return v->val;
}
#else
#define read_unaligned_u16(p) (* reinterpret_cast<const Uint16 *>(p))
#define read_unaligned_u32(p) (* reinterpret_cast<const Uint32 *>(p))
#endif
//for explicit overrides //for explicit overrides
#ifdef _MSC_VER #ifdef _MSC_VER
#define OVERRIDE override #define OVERRIDE override

View File

@ -6,6 +6,7 @@
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
#include "CLodHandler.h" #include "CLodHandler.h"
#include "../lib/VCMI_Lib.h" #include "../lib/VCMI_Lib.h"
#include "../lib/vcmi_endian.h"
#include "CGeneralTextHandler.h" #include "CGeneralTextHandler.h"
#include "../StartInfo.h" #include "../StartInfo.h"
#include "CArtHandler.h" //for hero crossover #include "CArtHandler.h" //for hero crossover
@ -141,8 +142,8 @@ CCampaign * CCampaignHandler::getCampaign( const std::string & name, bool fromLo
CCampaignHeader CCampaignHandler::readHeaderFromMemory( const unsigned char *buffer, int & outIt ) CCampaignHeader CCampaignHandler::readHeaderFromMemory( const unsigned char *buffer, int & outIt )
{ {
CCampaignHeader ret; CCampaignHeader ret;
ret.version = readNormalNr(buffer, outIt); outIt+=4; ret.version = read_le_u32(buffer + outIt); outIt+=4;
ret.mapVersion = readChar(buffer, outIt); ret.mapVersion = read_le_u32(buffer + outIt);
ret.mapVersion -= 1; //change range of it from [1, 20] to [0, 19] ret.mapVersion -= 1; //change range of it from [1, 20] to [0, 19]
ret.name = readString(buffer, outIt); ret.name = readString(buffer, outIt);
ret.description = readString(buffer, outIt); ret.description = readString(buffer, outIt);
@ -177,10 +178,10 @@ CCampaignScenario CCampaignHandler::readScenarioFromMemory( const unsigned char
CCampaignScenario ret; CCampaignScenario ret;
ret.conquered = false; ret.conquered = false;
ret.mapName = readString(buffer, outIt); ret.mapName = readString(buffer, outIt);
ret.packedMapSize = readNormalNr(buffer, outIt); outIt += 4; ret.packedMapSize = read_le_u32(buffer + outIt); outIt += 4;
if(mapVersion == 18)//unholy alliance if(mapVersion == 18)//unholy alliance
{ {
ret.preconditionRegion = readNormalNr(buffer, outIt, 2); outIt += 2; ret.preconditionRegion = read_le_u16(buffer + outIt); outIt += 2;
} }
else else
{ {
@ -237,15 +238,15 @@ CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const unsigned c
{ {
case 0: //spell case 0: //spell
{ {
bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero bonus.info1 = read_le_u16(buffer + outIt); outIt += 2; //hero
bonus.info2 = buffer[outIt++]; //spell ID bonus.info2 = buffer[outIt++]; //spell ID
break; break;
} }
case 1: //monster case 1: //monster
{ {
bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero bonus.info1 = read_le_u16(buffer + outIt); outIt += 2; //hero
bonus.info2 = readNormalNr(buffer, outIt, 2); outIt += 2; //monster type bonus.info2 = read_le_u16(buffer + outIt); outIt += 2; //monster type
bonus.info3 = readNormalNr(buffer, outIt, 2); outIt += 2; //monster count bonus.info3 = read_le_u16(buffer + outIt); outIt += 2; //monster count
break; break;
} }
case 2: //building case 2: //building
@ -255,25 +256,25 @@ CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const unsigned c
} }
case 3: //artifact case 3: //artifact
{ {
bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero bonus.info1 = read_le_u16(buffer + outIt); outIt += 2; //hero
bonus.info2 = readNormalNr(buffer, outIt, 2); outIt += 2; //artifact ID bonus.info2 = read_le_u16(buffer + outIt); outIt += 2; //artifact ID
break; break;
} }
case 4: //spell scroll case 4: //spell scroll
{ {
bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero bonus.info1 = read_le_u16(buffer + outIt); outIt += 2; //hero
bonus.info2 = buffer[outIt++]; //spell ID bonus.info2 = buffer[outIt++]; //spell ID
break; break;
} }
case 5: //prim skill case 5: //prim skill
{ {
bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero bonus.info1 = read_le_u16(buffer + outIt); outIt += 2; //hero
bonus.info2 = readNormalNr(buffer, outIt, 4); outIt += 4; //bonuses (4 bytes for 4 skills) bonus.info2 = read_le_u32(buffer + outIt); outIt += 4; //bonuses (4 bytes for 4 skills)
break; break;
} }
case 6: //sec skills case 6: //sec skills
{ {
bonus.info1 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero bonus.info1 = read_le_u16(buffer + outIt); outIt += 2; //hero
bonus.info2 = buffer[outIt++]; //skill ID bonus.info2 = buffer[outIt++]; //skill ID
bonus.info3 = buffer[outIt++]; //skill level bonus.info3 = buffer[outIt++]; //skill level
break; break;
@ -283,7 +284,7 @@ CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const unsigned c
bonus.info1 = buffer[outIt++]; //type bonus.info1 = buffer[outIt++]; //type
//FD - wood+ore //FD - wood+ore
//FE - mercury+sulfur+crystal+gem //FE - mercury+sulfur+crystal+gem
bonus.info2 = readNormalNr(buffer, outIt, 4); outIt += 4; //count bonus.info2 = read_le_u32(buffer + outIt); outIt += 4; //count
break; break;
} }
} }
@ -313,7 +314,7 @@ CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const unsigned c
CScenarioTravel::STravelBonus bonus; CScenarioTravel::STravelBonus bonus;
bonus.type = 9; bonus.type = 9;
bonus.info1 = buffer[outIt++]; //player color bonus.info1 = buffer[outIt++]; //player color
bonus.info2 = readNormalNr(buffer, outIt, 2); outIt += 2; //hero, FF FF - random bonus.info2 = read_le_u16(buffer + outIt); outIt += 2; //hero, FF FF - random
ret.bonusesToChoose.push_back(bonus); ret.bonusesToChoose.push_back(bonus);
} }
@ -378,7 +379,7 @@ bool CCampaignHandler::startsAt( const unsigned char * buffer, int size, int pos
return false; return false;
} }
//size of map //size of map
int mapsize = readNormalNr(buffer, pos+5); int mapsize = read_le_u32(buffer + pos+5);
if(mapsize < 10 || mapsize > 530) if(mapsize < 10 || mapsize > 530)
{ {
return false; return false;
@ -392,7 +393,7 @@ bool CCampaignHandler::startsAt( const unsigned char * buffer, int size, int pos
} }
//map name //map name
int len = readNormalNr(buffer, pos+10); int len = read_le_u32(buffer + pos+10);
if(len < 0 || len > 100) if(len < 0 || len > 100)
{ {
return false; return false;

View File

@ -12,7 +12,7 @@
#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/replace.hpp>
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <SDL_endian.h> #include "vcmi_endian.h"
#ifdef max #ifdef max
#undef max #undef max
#endif #endif
@ -31,6 +31,7 @@ int readNormalNr (const unsigned char * bufor, int pos, int bytCon, bool cyclic)
{ {
int ret=0; int ret=0;
int amp=1; int amp=1;
for (int ir=0; ir<bytCon; ir++) for (int ir=0; ir<bytCon; ir++)
{ {
ret+=bufor[pos+ir]*amp; ret+=bufor[pos+ir]*amp;
@ -50,7 +51,7 @@ char readChar(const unsigned char * bufor, int &i)
std::string readString(const unsigned char * bufor, int &i) std::string readString(const unsigned char * bufor, int &i)
{ {
int len = readNormalNr(bufor,i); i+=4; int len = read_le_u32(bufor + i); i+=4;
assert(len >= 0 && len <= 500000); //not too long assert(len >= 0 && len <= 500000); //not too long
std::string ret; ret.reserve(len); std::string ret; ret.reserve(len);
for(int gg=0; gg<len; ++gg) for(int gg=0; gg<len; ++gg)

View File

@ -14,6 +14,7 @@
#include "CSpellHandler.h" #include "CSpellHandler.h"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include "../lib/JsonNode.h" #include "../lib/JsonNode.h"
#include "vcmi_endian.h"
/* /*
* map.cpp, part of VCMI engine * map.cpp, part of VCMI engine
@ -137,13 +138,13 @@ CMapHeader::CMapHeader()
void CMapHeader::initFromMemory( const unsigned char *bufor, int &i ) void CMapHeader::initFromMemory( const unsigned char *bufor, int &i )
{ {
version = (Eformat)(readNormalNr(bufor,i)); i+=4; //map version version = (Eformat)(read_le_u32(bufor + i)); i+=4; //map version
if(version != RoE && version != AB && version != SoD && version != WoG) if(version != RoE && version != AB && version != SoD && version != WoG)
{ {
throw std::string("Invalid map format!"); throw std::string("Invalid map format!");
} }
areAnyPLayers = readChar(bufor,i); //invalid on some maps areAnyPLayers = readChar(bufor,i); //invalid on some maps
height = width = (readNormalNr(bufor,i)); i+=4; // dimensions of map height = width = (read_le_u32(bufor + i)); i+=4; // dimensions of map
twoLevel = readChar(bufor,i); //if there is underground twoLevel = readChar(bufor,i); //if there is underground
int pom; int pom;
name = readString(bufor,i); name = readString(bufor,i);
@ -184,7 +185,7 @@ void CMapHeader::initFromMemory( const unsigned char *bufor, int &i )
} }
if(version>RoE) //probably reserved for further heroes if(version>RoE) //probably reserved for further heroes
{ {
int placeholdersQty = readNormalNr(bufor, i); i+=4; int placeholdersQty = read_le_u32(bufor + i); i+=4;
for(int p = 0; p < placeholdersQty; p++) for(int p = 0; p < placeholdersQty; p++)
placeholdedHeroes.push_back(bufor[i++]); placeholdedHeroes.push_back(bufor[i++]);
} }
@ -296,14 +297,14 @@ void CMapHeader::loadViCLossConditions( const unsigned char * bufor, int &i)
// int temp1 = bufor[i+2]; // int temp1 = bufor[i+2];
// int temp2 = bufor[i+3]; // int temp2 = bufor[i+3];
victoryCondition.ID = bufor[i+2]; victoryCondition.ID = bufor[i+2];
victoryCondition.count = readNormalNr(bufor, i+(version==RoE ? 3 : 4)); victoryCondition.count = read_le_u32(bufor + i+(version==RoE ? 3 : 4));
nr=(version==RoE ? 5 : 6); nr=(version==RoE ? 5 : 6);
break; break;
} }
case gatherResource: case gatherResource:
{ {
victoryCondition.ID = bufor[i+2]; victoryCondition.ID = bufor[i+2];
victoryCondition.count = readNormalNr(bufor, i+3); victoryCondition.count = read_le_u32(bufor + i+3);
nr = 5; nr = 5;
break; break;
} }
@ -373,8 +374,8 @@ void CMapHeader::loadViCLossConditions( const unsigned char * bufor, int &i)
} }
case timeExpires: case timeExpires:
{ {
lossCondition.timeLimit = readNormalNr(bufor,i++,2); lossCondition.timeLimit = read_le_u16(bufor + i);
i++; i+=2;
break; break;
} }
} }
@ -575,12 +576,12 @@ int Mapa::loadSeerHut( const unsigned char * bufor, int i, CGObjectInstance *& n
{ {
case 1: case 1:
{ {
hut->rVal = readNormalNr(bufor,i); i+=4; hut->rVal = read_le_u32(bufor + i); i+=4;
break; break;
} }
case 2: case 2:
{ {
hut->rVal = readNormalNr(bufor,i); i+=4; hut->rVal = read_le_u32(bufor + i); i+=4;
break; break;
} }
case 3: case 3:
@ -626,13 +627,13 @@ int Mapa::loadSeerHut( const unsigned char * bufor, int i, CGObjectInstance *& n
{ {
if(version>RoE) if(version>RoE)
{ {
hut->rID = readNormalNr(bufor,i, 2); i+=2; hut->rID = read_le_u16(bufor + i); i+=2;
hut->rVal = readNormalNr(bufor,i, 2); i+=2; hut->rVal = read_le_u16(bufor + i); i+=2;
} }
else else
{ {
hut->rID = bufor[i]; ++i; hut->rID = bufor[i]; ++i;
hut->rVal = readNormalNr(bufor,i, 2); i+=2; hut->rVal = read_le_u16(bufor + i); i+=2;
} }
break; break;
} }
@ -655,7 +656,7 @@ void Mapa::loadTown( CGObjectInstance * &nobj, const unsigned char * bufor, int
nt->identifier = 0; nt->identifier = 0;
if(version>RoE) if(version>RoE)
{ {
nt->identifier = readNormalNr(bufor,i); i+=4; nt->identifier = read_le_u32(bufor + i); i+=4;
} }
nt->tempOwner = bufor[i]; ++i; nt->tempOwner = bufor[i]; ++i;
if(readChar(bufor,i)) //has name if(readChar(bufor,i)) //has name
@ -724,7 +725,7 @@ void Mapa::loadTown( CGObjectInstance * &nobj, const unsigned char * bufor, int
/////// reading castle events ////////////////////////////////// /////// reading castle events //////////////////////////////////
int numberOfEvent = readNormalNr(bufor,i); i+=4; int numberOfEvent = read_le_u32(bufor + i); i+=4;
for(int gh = 0; gh<numberOfEvent; ++gh) for(int gh = 0; gh<numberOfEvent; ++gh)
{ {
@ -734,7 +735,7 @@ void Mapa::loadTown( CGObjectInstance * &nobj, const unsigned char * bufor, int
nce->message = readString(bufor,i); nce->message = readString(bufor,i);
for(int x=0; x < 7; x++) for(int x=0; x < 7; x++)
{ {
nce->resources[x] = readNormalNr(bufor,i); nce->resources[x] = read_le_u32(bufor + i);
i+=4; i+=4;
} }
@ -747,7 +748,7 @@ void Mapa::loadTown( CGObjectInstance * &nobj, const unsigned char * bufor, int
nce->humanAffected = true; nce->humanAffected = true;
nce->computerAffected = bufor[i]; ++i; nce->computerAffected = bufor[i]; ++i;
nce->firstOccurence = readNormalNr(bufor,i, 2); i+=2; nce->firstOccurence = read_le_u16(bufor + i); i+=2;
nce->nextOccurence = bufor[i]; ++i; nce->nextOccurence = bufor[i]; ++i;
i+=17; i+=17;
@ -765,7 +766,7 @@ void Mapa::loadTown( CGObjectInstance * &nobj, const unsigned char * bufor, int
nce->creatures.resize(7); nce->creatures.resize(7);
for(int vv=0; vv<7; ++vv) for(int vv=0; vv<7; ++vv)
{ {
nce->creatures[vv] = readNormalNr(bufor,i, 2);i+=2; nce->creatures[vv] = read_le_u16(bufor + i);i+=2;
} }
i+=4; i+=4;
nt->events.push_back(nce); nt->events.push_back(nce);
@ -791,12 +792,12 @@ CGObjectInstance * Mapa::loadHero(const unsigned char * bufor, int &i, int idToB
int identifier = 0; int identifier = 0;
if(version > RoE) if(version > RoE)
{ {
identifier = readNormalNr(bufor,i, 4); i+=4; identifier = read_le_u32(bufor + i); i+=4;
questIdentifierToId[identifier] = idToBeGiven; questIdentifierToId[identifier] = idToBeGiven;
} }
ui8 owner = bufor[i++]; ui8 owner = bufor[i++];
nhi->subID = readNormalNr(bufor,i, 1); ++i; nhi->subID = bufor[i++];
for(unsigned int j=0; j<predefinedHeroes.size(); j++) for(unsigned int j=0; j<predefinedHeroes.size(); j++)
{ {
@ -826,13 +827,13 @@ CGObjectInstance * Mapa::loadHero(const unsigned char * bufor, int &i, int idToB
if(version>AB) if(version>AB)
{ {
if(readChar(bufor,i))//true if hero's experience is greater than 0 if(readChar(bufor,i))//true if hero's experience is greater than 0
{ nhi->exp = readNormalNr(bufor,i); i+=4; } { nhi->exp = read_le_u32(bufor + i); i+=4; }
else else
nhi->exp = 0xffffffff; nhi->exp = 0xffffffff;
} }
else else
{ {
nhi->exp = readNormalNr(bufor,i); i+=4; nhi->exp = read_le_u32(bufor + i); i+=4;
if(!nhi->exp) //0 means "not set" in <=AB maps if(!nhi->exp) //0 means "not set" in <=AB maps
nhi->exp = 0xffffffff; nhi->exp = 0xffffffff;
} }
@ -842,12 +843,12 @@ CGObjectInstance * Mapa::loadHero(const unsigned char * bufor, int &i, int idToB
nhi->portrait = bufor[i++]; nhi->portrait = bufor[i++];
if(readChar(bufor,i))//true if hero has specified abilities if(readChar(bufor,i))//true if hero has specified abilities
{ {
int howMany = readNormalNr(bufor,i); i+=4; int howMany = read_le_u32(bufor + i); i+=4;
nhi->secSkills.resize(howMany); nhi->secSkills.resize(howMany);
for(int yy=0; yy<howMany; ++yy) for(int yy=0; yy<howMany; ++yy)
{ {
nhi->secSkills[yy].first = readNormalNr(bufor,i, 1); ++i; nhi->secSkills[yy].first = bufor[i++];
nhi->secSkills[yy].second = readNormalNr(bufor,i, 1); ++i; nhi->secSkills[yy].second = bufor[i++];
} }
} }
if(readChar(bufor,i))//true if hero has nonstandard garrison if(readChar(bufor,i))//true if hero has nonstandard garrison
@ -855,7 +856,7 @@ CGObjectInstance * Mapa::loadHero(const unsigned char * bufor, int &i, int idToB
nhi->formation =bufor[i]; ++i; //formation nhi->formation =bufor[i]; ++i; //formation
loadArtifactsOfHero(bufor, i, nhi); loadArtifactsOfHero(bufor, i, nhi);
nhi->patrol.patrolRadious = readNormalNr(bufor,i, 1); ++i; nhi->patrol.patrolRadious = bufor[i]; ++i;
if(nhi->patrol.patrolRadious == 0xff) if(nhi->patrol.patrolRadious == 0xff)
nhi->patrol.patrolling = false; nhi->patrol.patrolling = false;
else else
@ -921,14 +922,14 @@ CGObjectInstance * Mapa::loadHero(const unsigned char * bufor, int &i, int idToB
void Mapa::readRumors( const unsigned char * bufor, int &i) void Mapa::readRumors( const unsigned char * bufor, int &i)
{ {
int rumNr = readNormalNr(bufor,i,4);i+=4; int rumNr = read_le_u32(bufor + i);i+=4;
for (int it=0;it<rumNr;it++) for (int it=0;it<rumNr;it++)
{ {
Rumor ourRumor; Rumor ourRumor;
int nameL = readNormalNr(bufor,i,4);i+=4; //read length of name of rumor int nameL = read_le_u32(bufor + i);i+=4; //read length of name of rumor
for (int zz=0; zz<nameL; zz++) for (int zz=0; zz<nameL; zz++)
ourRumor.name+=bufor[i++]; ourRumor.name+=bufor[i++];
nameL = readNormalNr(bufor,i,4);i+=4; //read length of rumor nameL = read_le_u32(bufor + i);i+=4; //read length of rumor
for (int zz=0; zz<nameL; zz++) for (int zz=0; zz<nameL; zz++)
ourRumor.text+=bufor[i++]; ourRumor.text+=bufor[i++];
rumors.push_back(ourRumor); //add to our list rumors.push_back(ourRumor); //add to our list
@ -949,7 +950,7 @@ void Mapa::readHeader( const unsigned char * bufor, int &i)
{ {
disposedHeroes[g].ID = bufor[i++]; disposedHeroes[g].ID = bufor[i++];
disposedHeroes[g].portrait = bufor[i++]; disposedHeroes[g].portrait = bufor[i++];
int lenbuf = readNormalNr(bufor,i); i+=4; int lenbuf = read_le_u32(bufor + i); i+=4;
for (int zz=0; zz<lenbuf; zz++) for (int zz=0; zz<lenbuf; zz++)
disposedHeroes[g].name+=bufor[i++]; disposedHeroes[g].name+=bufor[i++];
disposedHeroes[g].players = bufor[i++]; disposedHeroes[g].players = bufor[i++];
@ -1046,17 +1047,17 @@ void Mapa::readPredefinedHeroes( const unsigned char * bufor, int &i)
cgh->ID = HEROI_TYPE; cgh->ID = HEROI_TYPE;
cgh->subID = z; cgh->subID = z;
if(readChar(bufor,i))//true if hore's experience is greater than 0 if(readChar(bufor,i))//true if hore's experience is greater than 0
{ cgh->exp = readNormalNr(bufor,i); i+=4; } { cgh->exp = read_le_u32(bufor + i); i+=4; }
else else
cgh->exp = 0; cgh->exp = 0;
if(readChar(bufor,i))//true if hero has specified abilities if(readChar(bufor,i))//true if hero has specified abilities
{ {
int howMany = readNormalNr(bufor,i); i+=4; int howMany = read_le_u32(bufor + i); i+=4;
cgh->secSkills.resize(howMany); cgh->secSkills.resize(howMany);
for(int yy=0; yy<howMany; ++yy) for(int yy=0; yy<howMany; ++yy)
{ {
cgh->secSkills[yy].first = readNormalNr(bufor,i, 1); ++i; cgh->secSkills[yy].first = bufor[i]; ++i;
cgh->secSkills[yy].second = readNormalNr(bufor,i, 1); ++i; cgh->secSkills[yy].second = bufor[i]; ++i;
} }
} }
@ -1143,14 +1144,14 @@ void Mapa::readTerrain( const unsigned char * bufor, int &i)
void Mapa::readDefInfo( const unsigned char * bufor, int &i) void Mapa::readDefInfo( const unsigned char * bufor, int &i)
{ {
int defAmount = readNormalNr(bufor,i); i+=4; int defAmount = read_le_u32(bufor + i); i+=4;
defy.reserve(defAmount+8); defy.reserve(defAmount+8);
for (int idd = 0 ; idd<defAmount; idd++) // reading defs for (int idd = 0 ; idd<defAmount; idd++) // reading defs
{ {
CGDefInfo * vinya = new CGDefInfo(); // info about new def CGDefInfo * vinya = new CGDefInfo(); // info about new def
//reading name //reading name
int nameLength = readNormalNr(bufor,i,4);i+=4; int nameLength = read_le_u32(bufor + i);i+=4;
vinya->name.reserve(nameLength); vinya->name.reserve(nameLength);
for (int cd=0;cd<nameLength;cd++) for (int cd=0;cd<nameLength;cd++)
{ {
@ -1164,10 +1165,10 @@ void Mapa::readDefInfo( const unsigned char * bufor, int &i)
{ {
bytes[v] = bufor[i++]; bytes[v] = bufor[i++];
} }
vinya->terrainAllowed = readNormalNr(bufor,i,2);i+=2; vinya->terrainAllowed = read_le_u16(bufor + i);i+=2;
vinya->terrainMenu = readNormalNr(bufor,i,2);i+=2; vinya->terrainMenu = read_le_u16(bufor + i);i+=2;
vinya->id = readNormalNr(bufor,i,4);i+=4; vinya->id = read_le_u32(bufor + i);i+=4;
vinya->subid = readNormalNr(bufor,i,4);i+=4; vinya->subid = read_le_u32(bufor + i);i+=4;
vinya->type = bufor[i++]; vinya->type = bufor[i++];
vinya->printPriority = bufor[i++]; vinya->printPriority = bufor[i++];
for (int zi=0; zi<6; zi++) for (int zi=0; zi<6; zi++)
@ -1227,7 +1228,7 @@ public:
void Mapa::readObjects( const unsigned char * bufor, int &i) void Mapa::readObjects( const unsigned char * bufor, int &i)
{ {
int howManyObjs = readNormalNr(bufor,i, 4); i+=4; int howManyObjs = read_le_u32(bufor + i); i+=4;
for(int ww=0; ww<howManyObjs; ++ww) //comment this line to turn loading objects off for(int ww=0; ww<howManyObjs; ++ww) //comment this line to turn loading objects off
{ {
CGObjectInstance * nobj = 0; CGObjectInstance * nobj = 0;
@ -1237,7 +1238,7 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
pos.y = bufor[i++]; pos.y = bufor[i++];
pos.z = bufor[i++]; pos.z = bufor[i++];
int defnum = readNormalNr(bufor,i, 4); i+=4; int defnum = read_le_u32(bufor + i); i+=4;
int idToBeGiven = objects.size(); int idToBeGiven = objects.size();
CGDefInfo * defInfo = defy[defnum]; CGDefInfo * defInfo = defy[defnum];
@ -1253,7 +1254,7 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
bool guardMess = bufor[i]; ++i; bool guardMess = bufor[i]; ++i;
if(guardMess) if(guardMess)
{ {
int messLong = readNormalNr(bufor,i, 4); i+=4; int messLong = read_le_u32(bufor + i); i+=4;
if(messLong>0) if(messLong>0)
{ {
for(int yy=0; yy<messLong; ++yy) for(int yy=0; yy<messLong; ++yy)
@ -1268,52 +1269,52 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
} }
i+=4; i+=4;
} }
evnt->gainedExp = readNormalNr(bufor,i, 4); i+=4; evnt->gainedExp = read_le_u32(bufor + i); i+=4;
evnt->manaDiff = readNormalNr(bufor,i, 4); i+=4; evnt->manaDiff = read_le_u32(bufor + i); i+=4;
evnt->moraleDiff = readNormalNr(bufor,i, 1, true); ++i; evnt->moraleDiff = readNormalNr(bufor,i, 1, true); ++i;
evnt->luckDiff = readNormalNr(bufor,i, 1, true); ++i; evnt->luckDiff = readNormalNr(bufor,i, 1, true); ++i;
evnt->resources.resize(RESOURCE_QUANTITY); evnt->resources.resize(RESOURCE_QUANTITY);
for(int x=0; x<7; x++) for(int x=0; x<7; x++)
{ {
evnt->resources[x] = readNormalNr(bufor,i); evnt->resources[x] = read_le_u32(bufor + i);
i+=4; i+=4;
} }
evnt->primskills.resize(PRIMARY_SKILLS); evnt->primskills.resize(PRIMARY_SKILLS);
for(int x=0; x<4; x++) for(int x=0; x<4; x++)
{ {
evnt->primskills[x] = readNormalNr(bufor,i, 1); evnt->primskills[x] = bufor[i];
i++; i++;
} }
int gabn; //number of gained abilities int gabn; //number of gained abilities
gabn = readNormalNr(bufor,i, 1); ++i; gabn = bufor[i]; ++i;
for(int oo = 0; oo<gabn; ++oo) for(int oo = 0; oo<gabn; ++oo)
{ {
evnt->abilities.push_back(readNormalNr(bufor,i, 1)); ++i; evnt->abilities.push_back(bufor[i]); ++i;
evnt->abilityLevels.push_back(readNormalNr(bufor,i, 1)); ++i; evnt->abilityLevels.push_back(bufor[i]); ++i;
} }
int gart = readNormalNr(bufor,i, 1); ++i; //number of gained artifacts int gart = bufor[i]; ++i; //number of gained artifacts
for(int oo = 0; oo<gart; ++oo) for(int oo = 0; oo<gart; ++oo)
{ {
evnt->artifacts.push_back(readNormalNr(bufor,i, (version == RoE ? 1 : 2))); i+=(version == RoE ? 1 : 2); evnt->artifacts.push_back(readNormalNr(bufor,i, (version == RoE ? 1 : 2))); i+=(version == RoE ? 1 : 2);
} }
int gspel = readNormalNr(bufor,i, 1); ++i; //number of gained spells int gspel = bufor[i]; ++i; //number of gained spells
for(int oo = 0; oo<gspel; ++oo) for(int oo = 0; oo<gspel; ++oo)
{ {
evnt->spells.push_back(readNormalNr(bufor,i, 1)); ++i; evnt->spells.push_back(bufor[i]); ++i;
} }
int gcre = readNormalNr(bufor,i, 1); ++i; //number of gained creatures int gcre = bufor[i]; ++i; //number of gained creatures
readCreatureSet(&evnt->creatures, bufor,i,gcre,(version>RoE)); readCreatureSet(&evnt->creatures, bufor,i,gcre,(version>RoE));
i+=8; i+=8;
evnt->availableFor = readNormalNr(bufor,i, 1); ++i; evnt->availableFor = bufor[i]; ++i;
evnt->computerActivate = readNormalNr(bufor,i, 1); ++i; evnt->computerActivate = bufor[i]; ++i;
evnt->removeAfterVisit = readNormalNr(bufor,i, 1); ++i; evnt->removeAfterVisit = bufor[i]; ++i;
evnt->humanActivate = true; evnt->humanActivate = true;
i+=4; i+=4;
@ -1372,13 +1373,13 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
if(version>RoE) if(version>RoE)
{ {
cre->identifier = readNormalNr(bufor,i); i+=4; cre->identifier = read_le_u32(bufor + i); i+=4;
questIdentifierToId[cre->identifier] = idToBeGiven; questIdentifierToId[cre->identifier] = idToBeGiven;
//monsters[cre->identifier] = cre; //monsters[cre->identifier] = cre;
} }
CStackInstance *hlp = new CStackInstance(); CStackInstance *hlp = new CStackInstance();
hlp->count = readNormalNr(bufor,i, 2); i+=2; hlp->count = read_le_u16(bufor + i); i+=2;
//type will be set during initialization //type will be set during initialization
cre->putStack(0, hlp); cre->putStack(0, hlp);
@ -1390,7 +1391,7 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
cre->resources.resize(RESOURCE_QUANTITY); cre->resources.resize(RESOURCE_QUANTITY);
for(int j=0; j<7; j++) for(int j=0; j<7; j++)
{ {
cre->resources[j] = readNormalNr(bufor,i); i+=4; cre->resources[j] = read_le_u32(bufor + i); i+=4;
} }
int artID = readNormalNr(bufor,i, (version == RoE ? 1 : 2)); i+=(version == RoE ? 1 : 2); int artID = readNormalNr(bufor,i, (version == RoE ? 1 : 2)); i+=(version == RoE ? 1 : 2);
@ -1504,7 +1505,7 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
if(defInfo->id==93) if(defInfo->id==93)
{ {
spellID = readNormalNr(bufor,i); i+=4; spellID = read_le_u32(bufor + i); i+=4;
artID = 1; artID = 1;
} }
else if(defInfo->id == 5) //specific artifact else if(defInfo->id == 5) //specific artifact
@ -1530,7 +1531,7 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
} }
i+=4; i+=4;
} }
res->amount = readNormalNr(bufor,i); i+=4; res->amount = read_le_u32(bufor + i); i+=4;
if (defInfo->subid == 6) // Gold is multiplied by 100. if (defInfo->subid == 6) // Gold is multiplied by 100.
res->amount *= 100; res->amount *= 100;
i+=4; i+=4;
@ -1585,50 +1586,50 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
i+=4; i+=4;
} }
box->gainedExp = readNormalNr(bufor,i, 4); i+=4; box->gainedExp = read_le_u32(bufor + i); i+=4;
box->manaDiff = readNormalNr(bufor,i, 4); i+=4; box->manaDiff = read_le_u32(bufor + i); i+=4;
box->moraleDiff = readNormalNr(bufor,i, 1, true); ++i; box->moraleDiff = readNormalNr(bufor,i, 1, true); ++i;
box->luckDiff = readNormalNr(bufor,i, 1, true); ++i; box->luckDiff = readNormalNr(bufor,i, 1, true); ++i;
box->resources.resize(RESOURCE_QUANTITY); box->resources.resize(RESOURCE_QUANTITY);
for(int x=0; x<7; x++) for(int x=0; x<7; x++)
{ {
box->resources[x] = readNormalNr(bufor,i); box->resources[x] = read_le_u32(bufor + i);
i+=4; i+=4;
} }
box->primskills.resize(PRIMARY_SKILLS); box->primskills.resize(PRIMARY_SKILLS);
for(int x=0; x<4; x++) for(int x=0; x<4; x++)
{ {
box->primskills[x] = readNormalNr(bufor,i, 1); box->primskills[x] = bufor[i];
i++; i++;
} }
int gabn; //number of gained abilities int gabn; //number of gained abilities
gabn = readNormalNr(bufor,i, 1); ++i; gabn = bufor[i]; ++i;
for(int oo = 0; oo<gabn; ++oo) for(int oo = 0; oo<gabn; ++oo)
{ {
box->abilities.push_back(readNormalNr(bufor,i, 1)); ++i; box->abilities.push_back(bufor[i]); ++i;
box->abilityLevels.push_back(readNormalNr(bufor,i, 1)); ++i; box->abilityLevels.push_back(bufor[i]); ++i;
} }
int gart = readNormalNr(bufor,i, 1); ++i; //number of gained artifacts int gart = bufor[i]; ++i; //number of gained artifacts
for(int oo = 0; oo<gart; ++oo) for(int oo = 0; oo<gart; ++oo)
{ {
if(version > RoE) if(version > RoE)
{ {
box->artifacts.push_back(readNormalNr(bufor,i, 2)); i+=2; box->artifacts.push_back(read_le_u16(bufor + i)); i+=2;
} }
else else
{ {
box->artifacts.push_back(readNormalNr(bufor,i, 1)); i+=1; box->artifacts.push_back(bufor[i]); i+=1;
} }
} }
int gspel = readNormalNr(bufor,i, 1); ++i; //number of gained spells int gspel = bufor[i]; ++i; //number of gained spells
for(int oo = 0; oo<gspel; ++oo) for(int oo = 0; oo<gspel; ++oo)
{ {
box->spells.push_back(readNormalNr(bufor,i, 1)); ++i; box->spells.push_back(bufor[i]); ++i;
} }
int gcre = readNormalNr(bufor,i, 1); ++i; //number of gained creatures int gcre = bufor[i]; ++i; //number of gained creatures
readCreatureSet(&box->creatures, bufor,i,gcre,(version>RoE)); readCreatureSet(&box->creatures, bufor,i,gcre,(version>RoE));
i+=8; i+=8;
break; break;
@ -1636,15 +1637,15 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
case 36: //grail case 36: //grail
{ {
grailPos = pos; grailPos = pos;
grailRadious = readNormalNr(bufor,i); i+=4; grailRadious = read_le_u32(bufor + i); i+=4;
continue; continue;
} }
case 217: case 217:
{ {
nobj = new CGDwelling(); nobj = new CGDwelling();
CCreGenObjInfo * spec = new CCreGenObjInfo; CCreGenObjInfo * spec = new CCreGenObjInfo;
spec->player = readNormalNr(bufor,i); i+=4; spec->player = read_le_u32(bufor + i); i+=4;
spec->identifier = readNormalNr(bufor,i); i+=4; spec->identifier = read_le_u32(bufor + i); i+=4;
if(!spec->identifier) if(!spec->identifier)
{ {
spec->asCastle = false; spec->asCastle = false;
@ -1663,8 +1664,8 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
{ {
nobj = new CGDwelling(); nobj = new CGDwelling();
CCreGen2ObjInfo * spec = new CCreGen2ObjInfo; CCreGen2ObjInfo * spec = new CCreGen2ObjInfo;
spec->player = readNormalNr(bufor,i); i+=4; spec->player = read_le_u32(bufor + i); i+=4;
spec->identifier = readNormalNr(bufor,i); i+=4; spec->identifier = read_le_u32(bufor + i); i+=4;
if(!spec->identifier) if(!spec->identifier)
{ {
spec->asCastle = false; spec->asCastle = false;
@ -1753,7 +1754,7 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
case 87: //Shipyard case 87: //Shipyard
{ {
nobj = new CGShipyard(); nobj = new CGShipyard();
nobj->setOwner(readNormalNr(bufor,i)); i+=4; nobj->setOwner(read_le_u32(bufor + i)); i+=4;
break; break;
} }
case 214: //hero placeholder case 214: //hero placeholder
@ -1827,7 +1828,7 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
case 42: //Lighthouse case 42: //Lighthouse
{ {
nobj = new CGLighthouse(); nobj = new CGLighthouse();
nobj->tempOwner = readNormalNr(bufor,i); i+=4; nobj->tempOwner = read_le_u32(bufor + i); i+=4;
break; break;
} }
case 2: //Altar of Sacrifice case 2: //Altar of Sacrifice
@ -1876,25 +1877,25 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
void Mapa::readEvents( const unsigned char * bufor, int &i ) void Mapa::readEvents( const unsigned char * bufor, int &i )
{ {
int numberOfEvents = readNormalNr(bufor,i); i+=4; int numberOfEvents = read_le_u32(bufor + i); i+=4;
for(int yyoo=0; yyoo<numberOfEvents; ++yyoo) for(int yyoo=0; yyoo<numberOfEvents; ++yyoo)
{ {
CMapEvent *ne = new CMapEvent(); CMapEvent *ne = new CMapEvent();
ne->name = std::string(); ne->name = std::string();
ne->message = std::string(); ne->message = std::string();
int nameLen = readNormalNr(bufor,i); i+=4; int nameLen = read_le_u32(bufor + i); i+=4;
for(int qq=0; qq<nameLen; ++qq) for(int qq=0; qq<nameLen; ++qq)
{ {
ne->name += bufor[i]; ++i; ne->name += bufor[i]; ++i;
} }
int messLen = readNormalNr(bufor,i); i+=4; int messLen = read_le_u32(bufor + i); i+=4;
for(int qq=0; qq<messLen; ++qq) for(int qq=0; qq<messLen; ++qq)
{ {
ne->message +=bufor[i]; ++i; ne->message +=bufor[i]; ++i;
} }
for(int k=0; k < 7; k++) for(int k=0; k < 7; k++)
{ {
ne->resources[k] = readNormalNr(bufor,i); i+=4; ne->resources[k] = read_le_u32(bufor + i); i+=4;
} }
ne->players = bufor[i]; ++i; ne->players = bufor[i]; ++i;
if(version>AB) if(version>AB)
@ -1904,7 +1905,7 @@ void Mapa::readEvents( const unsigned char * bufor, int &i )
else else
ne->humanAffected = true; ne->humanAffected = true;
ne->computerAffected = bufor[i]; ++i; ne->computerAffected = bufor[i]; ++i;
ne->firstOccurence = readNormalNr(bufor,i, 2); i+=2; ne->firstOccurence = read_le_u16(bufor + i); i+=2;
ne->nextOccurence = bufor[i]; ++i; ne->nextOccurence = bufor[i]; ++i;
char unknown[17]; char unknown[17];
@ -1943,7 +1944,7 @@ void Mapa::loadQuest(CQuest * guard, const unsigned char * bufor, int & i)
case 3: case 3:
case 4: case 4:
{ {
guard->m13489val = readNormalNr(bufor,i); i+=4; guard->m13489val = read_le_u32(bufor + i); i+=4;
break; break;
} }
case 5: case 5:
@ -1951,7 +1952,7 @@ void Mapa::loadQuest(CQuest * guard, const unsigned char * bufor, int & i)
int artNumber = bufor[i]; ++i; int artNumber = bufor[i]; ++i;
for(int yy=0; yy<artNumber; ++yy) for(int yy=0; yy<artNumber; ++yy)
{ {
int artid = readNormalNr(bufor,i, 2); i+=2; int artid = read_le_u16(bufor + i); i+=2;
guard->m5arts.push_back(artid); guard->m5arts.push_back(artid);
allowedArtifact[artid] = false; //these are unavailable for random generation allowedArtifact[artid] = false; //these are unavailable for random generation
} }
@ -1963,8 +1964,8 @@ void Mapa::loadQuest(CQuest * guard, const unsigned char * bufor, int & i)
guard->m6creatures.resize(typeNumber); guard->m6creatures.resize(typeNumber);
for(int hh=0; hh<typeNumber; ++hh) for(int hh=0; hh<typeNumber; ++hh)
{ {
guard->m6creatures[hh].type = VLC->creh->creatures[readNormalNr(bufor,i, 2)]; i+=2; guard->m6creatures[hh].type = VLC->creh->creatures[read_le_u16(bufor + i)]; i+=2;
guard->m6creatures[hh].count = readNormalNr(bufor,i, 2); i+=2; guard->m6creatures[hh].count = read_le_u16(bufor + i); i+=2;
} }
break; break;
} }
@ -1973,7 +1974,7 @@ void Mapa::loadQuest(CQuest * guard, const unsigned char * bufor, int & i)
guard->m7resources.resize(7); guard->m7resources.resize(7);
for(int x=0; x<7; x++) for(int x=0; x<7; x++)
{ {
guard->m7resources[x] = readNormalNr(bufor,i); guard->m7resources[x] = read_le_u32(bufor + i);
i+=4; i+=4;
} }
break; break;
@ -1987,7 +1988,7 @@ void Mapa::loadQuest(CQuest * guard, const unsigned char * bufor, int & i)
} }
int limit = readNormalNr(bufor,i); i+=4; int limit = read_le_u32(bufor + i); i+=4;
if(limit == ((int)0xffffffff)) if(limit == ((int)0xffffffff))
{ {
guard->lastDay = -1; guard->lastDay = -1;
@ -2098,7 +2099,7 @@ void Mapa::loadArtifactsOfHero(const unsigned char * bufor, int & i, CGHeroInsta
i+=1; i+=1;
//bag artifacts //20 //bag artifacts //20
int amount = readNormalNr(bufor,i, 2); i+=2; //number of artifacts in hero's bag int amount = read_le_u16(bufor + i); i+=2; //number of artifacts in hero's bag
for(int ss = 0; ss < amount; ++ss) for(int ss = 0; ss < amount; ++ss)
loadArtifactToSlot(nhi, Arts::BACKPACK_START + nhi->artifactsInBackpack.size(), bufor, i); loadArtifactToSlot(nhi, Arts::BACKPACK_START + nhi->artifactsInBackpack.size(), bufor, i);
} //artifacts } //artifacts

30
lib/vcmi_endian.h Normal file
View File

@ -0,0 +1,30 @@
#include <SDL_endian.h>
/* Reading values from memory.
*
* read_le_u16, read_le_u32 : read a little endian value from
* memory. On big endian machines, the value will be byteswapped.
*/
#if defined(linux) && defined(sparc)
/* SPARC does not support unaligned memory access. Let gcc know when
* to emit the right code. */
struct unaligned_Uint16 { ui16 val __attribute__(( packed )); };
struct unaligned_Uint32 { ui32 val __attribute__(( packed )); };
static inline ui16 read_unaligned_u16(const void *p)
{
const struct unaligned_Uint16 *v = (const struct unaligned_Uint16 *)p;
return v->val;
}
static inline ui32 read_unaligned_u32(const void *p)
{
const struct unaligned_Uint32 *v = (const struct unaligned_Uint32 *)p;
return v->val;
}
#else
#define read_le_u16(p) (SDL_SwapLE16(* reinterpret_cast<const ui16 *>(p)))
#define read_le_u32(p) (SDL_SwapLE32(* reinterpret_cast<const ui32 *>(p)))
#endif