Skip to content

Commit

Permalink
GRAPHICS: Add TextureManager::setDeswizzleSBM()
Browse files Browse the repository at this point in the history
Poking a hole into the texture abstraction, so that the engine can
tell the texture manager that SBM images need to be deswizzled, which
in turn tells the texture, which tells the SBM image decoder.
  • Loading branch information
DrMcCoy committed Jul 29, 2018
1 parent 93a0e23 commit b28f91f
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 34 deletions.
55 changes: 31 additions & 24 deletions src/graphics/aurora/texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,14 @@ namespace Graphics {

namespace Aurora {

Texture::Texture() : _type(::Aurora::kFileTypeNone), _width(0), _height(0) {
Texture::Texture() : _type(::Aurora::kFileTypeNone), _width(0), _height(0), _deswizzle(false) {
}

Texture::Texture(const Common::UString &name, ImageDecoder *image, ::Aurora::FileType type, TXI *txi) :
_name(name), _type(type), _width(0), _height(0) {
Texture::Texture(const Common::UString &name, ImageDecoder *image,
::Aurora::FileType type, TXI *txi, bool deswizzle) :
_name(name), _type(type), _width(0), _height(0), _deswizzle(deswizzle) {

set(name, image, type, txi);
set(name, image, type, txi, deswizzle);
addToQueues();
}

Expand Down Expand Up @@ -119,7 +120,7 @@ bool Texture::reload() {
try {

txi = loadTXI (_name);
image = loadImage(_name, type, txi);
image = loadImage(_name, type, txi, _deswizzle);

} catch (Common::Exception &e) {
delete txi;
Expand All @@ -129,7 +130,7 @@ bool Texture::reload() {
}

removeFromQueues();
set(_name, image, type, txi);
set(_name, image, type, txi, _deswizzle);
addToQueues();

return true;
Expand Down Expand Up @@ -319,7 +320,7 @@ Texture *Texture::createPLT(const Common::UString &name, Common::SeekableReadStr
return texture;
}

Texture *Texture::create(const Common::UString &name) {
Texture *Texture::create(const Common::UString &name, bool deswizzle) {
::Aurora::FileType type = ::Aurora::kFileTypeNone;
ImageDecoder *image = 0;
ImageDecoder *layers[6] = { 0, 0, 0, 0, 0, 0 };
Expand All @@ -338,7 +339,7 @@ Texture *Texture::create(const Common::UString &name) {
if (!imageStream)
throw Common::Exception("No such cube side image resource \"%s\"", side.c_str());

layers[i] = loadImage(imageStream, type, txi);
layers[i] = loadImage(imageStream, type, txi, deswizzle);
}

image = new CubeMapCombiner(layers);
Expand All @@ -355,7 +356,7 @@ Texture *Texture::create(const Common::UString &name) {
return createPLT(name, imageStream);
}

image = loadImage(imageStream, type, txi);
image = loadImage(imageStream, type, txi, deswizzle);
}

} catch (Common::Exception &e) {
Expand All @@ -369,34 +370,38 @@ Texture *Texture::create(const Common::UString &name) {
throw;
}

return new Texture(name, image, type, txi);
return new Texture(name, image, type, txi, deswizzle);
}

Texture *Texture::create(ImageDecoder *image, ::Aurora::FileType type, TXI *txi) {
Texture *Texture::create(ImageDecoder *image, ::Aurora::FileType type, TXI *txi, bool deswizzle) {
if (!image)
throw Common::Exception("Can't create a texture from an empty image");

if (image->getMipMapCount() < 1)
throw Common::Exception("Texture has no images");

return new Texture("", image, type, txi);
return new Texture("", image, type, txi, deswizzle);
}

void Texture::set(const Common::UString &name, ImageDecoder *image, ::Aurora::FileType type, TXI *txi) {
_name = name;
_type = type;
void Texture::set(const Common::UString &name, ImageDecoder *image, ::Aurora::FileType type,
TXI *txi, bool deswizzle) {

_name = name;
_type = type;

_image.reset(image);
_txi.reset(txi);

_width = _image->getMipMap(0).width;
_height = _image->getMipMap(0).height;

_deswizzle = deswizzle;
}

ImageDecoder *Texture::loadImage(const Common::UString &name) {
ImageDecoder *Texture::loadImage(const Common::UString &name, bool deswizzle) {
::Aurora::FileType type;

return loadImage(name, type);
return loadImage(name, type, deswizzle);
}

void Texture::addToQueues() {
Expand All @@ -414,18 +419,20 @@ void Texture::refresh() {
addToQueues();
}

ImageDecoder *Texture::loadImage(const Common::UString &name, ::Aurora::FileType &type) {
return loadImage(name, type, 0);
ImageDecoder *Texture::loadImage(const Common::UString &name, ::Aurora::FileType &type, bool deswizzle) {
return loadImage(name, type, 0, deswizzle);
}

ImageDecoder *Texture::loadImage(const Common::UString &name, ::Aurora::FileType &type, TXI *txi) {
ImageDecoder *Texture::loadImage(const Common::UString &name, ::Aurora::FileType &type,
TXI *txi, bool deswizzle) {

const bool isFileCubeMap = txi && txi->getFeatures().cube && (txi->getFeatures().fileRange == 6);
if (!isFileCubeMap) {
Common::SeekableReadStream *imageStream = ResMan.getResource(::Aurora::kResourceImage, name, &type);
if (!imageStream)
throw Common::Exception("No such image resource \"%s\"", name.c_str());

return loadImage(imageStream, type, txi);
return loadImage(imageStream, type, txi, deswizzle);
}

ImageDecoder *layers[6] = { 0, 0, 0, 0, 0, 0 };
Expand All @@ -437,7 +444,7 @@ ImageDecoder *Texture::loadImage(const Common::UString &name, ::Aurora::FileType
if (!imageStream)
throw Common::Exception("No such cube side image resource \"%s\"", side.c_str());

layers[i] = loadImage(imageStream, type, txi);
layers[i] = loadImage(imageStream, type, txi, deswizzle);
}

return new CubeMapCombiner(layers);
Expand All @@ -451,7 +458,7 @@ ImageDecoder *Texture::loadImage(const Common::UString &name, ::Aurora::FileType
}

ImageDecoder *Texture::loadImage(Common::SeekableReadStream *imageStream, ::Aurora::FileType type,
TXI *txi) {
TXI *txi, bool deswizzle) {

// Check for a cube map, but only those that don't use a file for each side
const bool isCubeMap = txi && txi->getFeatures().cube && (txi->getFeatures().fileRange == 0);
Expand All @@ -468,7 +475,7 @@ ImageDecoder *Texture::loadImage(Common::SeekableReadStream *imageStream, ::Auro
else if (type == ::Aurora::kFileTypeTXB)
image = new TXB(*imageStream);
else if (type == ::Aurora::kFileTypeSBM)
image = new SBM(*imageStream);
image = new SBM(*imageStream, deswizzle);
else if (type == ::Aurora::kFileTypeXEOSITEX)
image = new XEOSITEX(*imageStream);
else
Expand Down
23 changes: 15 additions & 8 deletions src/graphics/aurora/texture.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,16 @@ class Texture : public Graphics::Texture {


/** Load an image in any of the common texture formats. */
static ImageDecoder *loadImage(const Common::UString &name);
static ImageDecoder *loadImage(const Common::UString &name, bool deswizzle = false);
/** Load an image in any of the common texture formats. */
static ImageDecoder *loadImage(const Common::UString &name, ::Aurora::FileType &type);
static ImageDecoder *loadImage(const Common::UString &name, ::Aurora::FileType &type,
bool deswizzle = false);

/** Create a texture from this image resource. */
static Texture *create(const Common::UString &name);
static Texture *create(const Common::UString &name, bool deswizzle = false);
/** Take over the image and create a texture from it. */
static Texture *create(ImageDecoder *image, ::Aurora::FileType type = ::Aurora::kFileTypeNone, TXI *txi = 0);
static Texture *create(ImageDecoder *image, ::Aurora::FileType type = ::Aurora::kFileTypeNone,
TXI *txi = 0, bool deswizzle = false);


protected:
Expand All @@ -90,11 +92,15 @@ class Texture : public Graphics::Texture {
uint32 _width;
uint32 _height;

bool _deswizzle;


Texture();
Texture(const Common::UString &name, ImageDecoder *image, ::Aurora::FileType type, TXI *txi = 0);
Texture(const Common::UString &name, ImageDecoder *image, ::Aurora::FileType type, TXI *txi = 0,
bool deswizzle = false);

void set(const Common::UString &name, ImageDecoder *image, ::Aurora::FileType type, TXI *txi);
void set(const Common::UString &name, ImageDecoder *image, ::Aurora::FileType type, TXI *txi,
bool deswizzle = false);

void addToQueues();
void removeFromQueues();
Expand All @@ -117,9 +123,10 @@ class Texture : public Graphics::Texture {

static TXI *loadTXI(const Common::UString &name);
static ImageDecoder *loadImage(Common::SeekableReadStream *imageStream, ::Aurora::FileType type,
TXI *txi = 0);
TXI *txi = 0, bool deswizzle = false);

static ImageDecoder *loadImage(const Common::UString &name, ::Aurora::FileType &type, TXI *txi);
static ImageDecoder *loadImage(const Common::UString &name, ::Aurora::FileType &type, TXI *txi,
bool deswizzle = false);

static Texture *createPLT(const Common::UString &name, Common::SeekableReadStream *imageStream);
};
Expand Down
10 changes: 8 additions & 2 deletions src/graphics/aurora/textureman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ static GLenum kTextureUnit[] = {
static const size_t kTextureUnitCount = ARRAYSIZE(kTextureUnit);


TextureManager::TextureManager() : _recordNewTextures(false) {
TextureManager::TextureManager() : _deswizzleSBM(false), _recordNewTextures(false) {
}

TextureManager::~TextureManager() {
Expand All @@ -96,6 +96,8 @@ void TextureManager::clear() {
delete t->second;
_textures.clear();

_deswizzleSBM = false;

_recordNewTextures = false;
_newTextureNames.clear();
}
Expand All @@ -106,6 +108,10 @@ void TextureManager::addBogusTexture(const Common::UString &name) {
_bogusTextures.insert(name);
}

void TextureManager::setDeswizzleSBM(bool deswizzle) {
_deswizzleSBM = deswizzle;
}

bool TextureManager::hasTexture(const Common::UString &name) {
Common::StackLock lock(_mutex);

Expand Down Expand Up @@ -153,7 +159,7 @@ TextureHandle TextureManager::get(Common::UString name) {
if (texture == _textures.end()) {
std::pair<TextureMap::iterator, bool> result;

ManagedTexture *managedTexture = new ManagedTexture(Texture::create(name));
ManagedTexture *managedTexture = new ManagedTexture(Texture::create(name, _deswizzleSBM));

if (managedTexture->texture->isDynamic())
name = name + "#" + Common::generateIDRandomString();
Expand Down
11 changes: 11 additions & 0 deletions src/graphics/aurora/textureman.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ class TextureManager : public Common::Singleton<TextureManager> {
*/
void addBogusTexture(const Common::UString &name);

/** Do we need to deswizzle SBM images?
*
* The Xbox version of Jade Empire contains swizzled SBM images,
* used for the font glyphs. Unfortunately, we can't tell from
* the SBM image alone whether it needs deswizzling, so the
* engine needs to tell the TextureManage, which needs to tell
* the Texture, which tells the image decoder.
*/
void setDeswizzleSBM(bool deswizzle);

/** Does this named managed texture exist? */
bool hasTexture(const Common::UString &name);

Expand Down Expand Up @@ -93,6 +103,7 @@ class TextureManager : public Common::Singleton<TextureManager> {
// '---

private:
bool _deswizzleSBM;
TextureMap _textures;

std::set<Common::UString> _bogusTextures;
Expand Down

0 comments on commit b28f91f

Please sign in to comment.