Ok, now for the factories. These are what generate the images:
TerrainArtFactory.h
Code:
// Copyright (c) 2006, Charles M. Kerr
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// ? Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// ? Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// ? Neither the name of WorldMaker nor the names of its contributors may be used
// to endorse or promote products derived from this software without specific
// prior written permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//
#ifndef TerrainArtFactory_H
#define TerrainArtFactory_H
#include <string>
#include <vector>
#include <fstream>
#include "uoenum.h"
#include "PtrCache.h"
class ArtImage;
class TerrainImage;
class Hue;
class TileData;
class Image;
class TerrainArtFactory
{
public:
TerrainArtFactory(const std::string &idx, const std::string &mul, Hue *hue, TileData *tile);
bool setFile(const std::string &idx, const std::string &mul);
~TerrainArtFactory();
bool valid() const;
std::vector<long> validIds(enTileType type) const;
ArtImage* getArt(long id);
TerrainImage *getTerrain(long id);
protected:
void buildValid();
protected:
long *data;
std::fstream mulfile;
PtrCache<long, Image> cache[2];
Hue *hueData;
TileData *tileData;
std::vector<long> valid_id[2];
};
#endif
Impementation
Code:
// Copyright (c) 2006, Charles M. Kerr
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// ? Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// ? Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// ? Neither the name of WorldMaker nor the names of its contributors may be used
// to endorse or promote products derived from this software without specific
// prior written permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//
#include "TerrainArtFactory.h"
#include "Hue.h"
#include "TileData.h"
#include "TerrainImage.h"
#include "ArtImage.h"
signed long swapLongToN(signed long data);
void initEndian();
#define MAX_ID 0x4000
TerrainArtFactory::TerrainArtFactory(const std::string &idx, const std::string &mul, Hue *hue, TileData *tile)
{
data = NULL;
hueData = hue;
tileData = tile;
setFile(idx,mul);
initEndian();
}
bool TerrainArtFactory::setFile(const std::string &idx, const std::string &mul)
{
bool status = false;
// We dont anticipate a lot of file changing, so we are not going to worry
// about optimizing memory reuse here
if (data!=NULL)
delete[] data;
if (mulfile.is_open())
mulfile.close();
mulfile.open(mul.c_str(),std::ios_base::in | std::ios_base::binary) ;
if (mulfile.is_open())
{
std::fstream idxfile;
idxfile.open(idx.c_str(), std::ios_base::in | std::ios_base::binary) ;
if (!idxfile.is_open())
{
mulfile.close();
}
else
{
idxfile.seekg(0,std::ios::end);
std::size_t filesize= idxfile.tellg();
idxfile.seekg(0,std::ios::beg);
// The art file is larger then we need (it has old beta sprite animations)
// The larget valid tile id is 0x4000 for either Terrain or Art.
if (filesize >= (0x4000*24))
{
status=true;
data = new long[0x8000];
idxfile.read(reinterpret_cast<char*>(data),0x8000*4);
idxfile.close();
buildValid();
}
}
}
return status;
}
TerrainArtFactory::~TerrainArtFactory()
{
if (data !=NULL)
delete[] data;
if (mulfile.is_open())
mulfile.close();
cache[0].clear();
cache[1].clear();
}
bool TerrainArtFactory::valid() const
{
if (data!=NULL && mulfile.is_open())
return true;
else
return false;
}
std::vector<long> TerrainArtFactory::validIds(enTileType type) const
{
switch (type)
{
case enTerrain:
return valid_id[type];
break;
case enArt:
return valid_id[type];
break;
default:
return std::vector<long>();
}
}
void TerrainArtFactory::buildValid()
{
valid_id[0].clear();
valid_id[1].clear();
long *ptr=data;
long index;
long length;
for (int i=0;i<2;++i)
{
for (long j=0;j<MAX_ID;++j)
{
index = swapLongToN(*ptr);
++ptr;
length = swapLongToN(*ptr);
ptr +=2;
if (index >-1 && length >0)
valid_id[i].push_back(j);
}
}
}
ArtImage* TerrainArtFactory::getArt(long id)
{
ArtImage *rvalue=NULL;
long *ptr = data+0x4000*3;
if (valid() && id >=0 && id < MAX_ID)
{
// first check the cache see if it is in there
if (cache[1].contains(id))
rvalue=reinterpret_cast<ArtImage*>(cache[1].fetch(id));
else
{
long index = swapLongToN(*(ptr+3*id));
long length = swapLongToN(*(ptr+3*id+1));
if (index >-1 && length >0)
{
mulfile.seekg(index,std::ios::beg);
char *buffer = new char[length];
mulfile.read(buffer,length);
// Now great a ArtImage
rvalue = new ArtImage(id,buffer,hueData, (*tileData).flag(enArt,id,enPartialHue) );
// and insert into the cache for next time
cache[1].insert(id,rvalue);
}
}
}
return rvalue;
}
TerrainImage* TerrainArtFactory::getTerrain(long id)
{
TerrainImage *rvalue=NULL;
long *ptr = data;
if (valid() && id >=0 && id < MAX_ID)
{
// first check the cache see if it is in there
if (cache[0].contains(id))
rvalue=reinterpret_cast<TerrainImage*>(cache[1].fetch(id));
else
{
long index = swapLongToN(*(ptr+3*id));
long length = swapLongToN(*(ptr+3*id+1));
if (index >-1 && length >0)
{
mulfile.seekg(index,std::ios::beg);
char *buffer = new char[length];
mulfile.read(buffer,length);
// Now great a TerrainImage
rvalue = new TerrainImage(id,buffer,hueData, (*tileData).flag(enTerrain,id,enPartialHue) );
// and insert into the cache for next time
cache[0].insert(id,rvalue);
}
}
}
return rvalue;
}
Texture factory
Code:
// Copyright (c) 2006, Charles M. Kerr
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// ? Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// ? Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// ? Neither the name of WorldMaker nor the names of its contributors may be used
// to endorse or promote products derived from this software without specific
// prior written permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//
#ifndef TexFactory_H
#define TexFactory_H
#include <fstream>
#include <string>
#include <vector>
class TexImage;
class Hue;
class TileData;
#include "PtrCache.h"
class TexFactory
{
public:
TexFactory(const std::string &idx, const std::string &mul, Hue *hue, TileData *tile);
bool setFile(const std::string &idx, const std::string &mul);
~TexFactory();
bool valid() const;
std::vector<long> validIds() const;
long maxId() const;
TexImage* getTexture(long id);
protected:
void buildValid();
protected:
long *data;
std::fstream mulfile;
long max_id;
PtrCache<long, TexImage> cache;
Hue *hueData;
TileData *tileData;
std::vector<long> valid_id;
};
#endif
And implementation
Code:
// Copyright (c) 2006, Charles M. Kerr
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// ? Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// ? Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// ? Neither the name of WorldMaker nor the names of its contributors may be used
// to endorse or promote products derived from this software without specific
// prior written permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//
#include "TexFactory.h"
#include "Hue.h"
#include "TileData.h"
#include "TexImage.h"
signed long swapLongToN(signed long data);
void initEndian();
TexFactory::TexFactory(const std::string &idx, const std::string &mul, Hue * hue, TileData *tile)
{
data = NULL;
max_id=0;
hueData = hue;
tileData = tile;
setFile(idx,mul);
initEndian();
}
bool TexFactory::setFile(const std::string &idx, const std::string &mul)
{
bool status = false;
// We dont anticipate a lot of file changing, so we are not going to worry
// about optimizing memory reuse here
if (data!=NULL)
delete[] data;
if (mulfile.is_open())
mulfile.close();
mulfile.open(mul.c_str(),std::ios_base::in | std::ios_base::binary) ;
if (mulfile.is_open())
{
std::fstream idxfile;
idxfile.open(idx.c_str(), std::ios_base::in | std::ios_base::binary) ;
if (!idxfile.is_open())
{
mulfile.close();
}
else
{
status=true;
idxfile.seekg(0,std::ios::end);
std::size_t filesize= idxfile.tellg();
idxfile.seekg(0,std::ios::beg);
max_id = filesize/12;
data = new long[filesize/4];
idxfile.read(reinterpret_cast<char*>(data),filesize);
idxfile.close();
buildValid();
}
}
return status;
}
TexFactory::~TexFactory()
{
if (data !=NULL)
delete[] data;
if (mulfile.is_open())
mulfile.close();
cache.clear();
}
bool TexFactory::valid() const
{
if (data!=NULL && mulfile.is_open())
return true;
else
return false;
}
std::vector<long> TexFactory::validIds() const
{
return valid_id;
}
long TexFactory::maxId() const
{
if (valid())
return max_id-1;
else
return 0;
}
void TexFactory::buildValid()
{
valid_id.clear();
long *ptr=data;
long index;
long length;
for (long j=0;j<max_id;++j)
{
index = swapLongToN(*ptr);
++ptr;
length = swapLongToN(*ptr);
ptr +=2;
if (index >-1 && length >0)
valid_id.push_back(j);
}
}
TexImage* TexFactory::getTexture(long id)
{
TexImage *rvalue=NULL;
if (valid() && id >=0 && id < max_id)
{
// first check the cache see if it is in there
if (cache.contains(id))
rvalue=cache.fetch(id);
else
{
long index = swapLongToN(*(data+3*id));
long length = swapLongToN(*(data+3*id+1));
long extra = swapLongToN(*(data+3+id+2));
if (index >-1 && length >0)
{
mulfile.seekg(index,std::ios::beg);
char *buffer = new char[length];
mulfile.read(buffer,length);
// Now great a TexImage
rvalue = new TexImage(id,extra,buffer,hueData);
// and insert into the cache for next time
cache.insert(id,rvalue);
}
}
}
return rvalue;
}
Now a little class to wrapper all the factories, user convience:
Code:
// Copyright (c) 2006, Charles M. Kerr
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// ? Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// ? Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// ? Neither the name of WorldMaker nor the names of its contributors may be used
// to endorse or promote products derived from this software without specific
// prior written permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//
#ifndef ImageFactory_H
#define ImageFactory_H
class Hue;
class TileData;
class TerrainArtFactory;
class TexFactory;
class Image;
#include <string>
#include <vector>
#include "uoenum.h"
class ImageFactory
{
public:
ImageFactory(TileData * t, const std::string &huefile, const std::string &texidx, const std::string &texmul,
const std::string &artidx, const std::string &artmul);
~ImageFactory();
Image *getImage(enTileType type,long id);
std::vector<long> getValid(enTileType type) const;
bool valid() const;
bool setHueFile(const std::string &name);
bool setTexmap(const std::string &idx, const std::string &mul);
bool setArt(const std::string &idx, const std::string &mul);
protected:
Hue *hueData;
TileData *tileData;
TexFactory *texFactory;
TerrainArtFactory *artFactory;
};
#endif
Implementation
Code:
// Copyright (c) 2006, Charles M. Kerr
// All rights reserved.
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// ? Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// ? Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// ? Neither the name of WorldMaker nor the names of its contributors may be used
// to endorse or promote products derived from this software without specific
// prior written permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//
#include "ImageFactory.h"
#include "Hue.h"
#include "TileData.h"
#include "TexFactory.h"
#include "TerrainArtFactory.h"
#include "Image.h"
#include "ArtImage.h"
#include "TerrainImage.h"
ImageFactory::ImageFactory(TileData * t, const std::string &huefile, const std::string &texidx, const std::string &texmul,
const std::string &artidx, const std::string &artmul)
{
hueData = new Hue(huefile);
texFactory = new TexFactory(texidx,texmul,hueData,t);
artFactory = new TerrainArtFactory(artidx,artmul,hueData,t);
}
ImageFactory::~ImageFactory()
{
delete hueData;
delete texFactory;
delete artFactory;
}
Image *ImageFactory::getImage(enTileType type,long id)
{
Image *rvalue=NULL;
if (valid())
{
switch(type)
{
case enTerrain:
rvalue = ( ((*artFactory).getTerrain(id)) );
break;
case enArt:
rvalue= ( ((*artFactory).getArt(id)) );
break;
case enTexture:
rvalue= reinterpret_cast<Image*>( ((*texFactory).getTexture(id)) );
break;
}
}
return rvalue;
}
std::vector<long> ImageFactory::getValid(enTileType type) const
{
if (valid())
{
switch(type)
{
case enTerrain:
case enArt:
return (*artFactory).validIds(type);
case enTexture:
return (*texFactory).validIds();
default:
return std::vector<long>();
}
}
else
return std::vector<long>();
}
bool ImageFactory::valid() const
{
return (*hueData).valid() && (*texFactory).valid() && (*artFactory).valid() ;
}
bool ImageFactory::setHueFile(const std::string &name)
{
return (*hueData).setFile(name);
}
bool ImageFactory::setTexmap(const std::string &idx, const std::string &mul)
{
return (*texFactory).setFile(idx,mul);
}
bool ImageFactory::setArt(const std::string &idx, const std::string &mul)
{
return (*artFactory).setFile(idx,mul);
}
This is all pure c++, and should work on any platform.
I acknowneldge I could have done endian swapping via compile (and would have been faster for little endian machines). For me however, I have to build universal binaries on the Mac, and dont want to worry about compilier defines at the moment (perhaps later I will or someone will retrofit that, it is easy enough).
Again, if any questions, please feel free to ask. The goal is for this to be a community project. As I don't/can't run windows anymore, clearly one will need to test and build for the windows platform as we progress. This project will be layed out to only require free tools (one can use others as they desire). So mingw, QT GPL version, XCode (mac), etc. This basiclly is all the graphics data code that is needed. The only other mul data code would be the map/static file handlers.