Skip to content

Commit

Permalink
IMAGES: Add support for swizzled Xbox SBM images
Browse files Browse the repository at this point in the history
Unfortunately, there's no way to tell from the image data alone
whether an SBM is swizzled, so the image decoder needs to be told.
  • Loading branch information
DrMcCoy committed Jul 29, 2018
1 parent c8bc2ff commit 06b5f17
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 14 deletions.
22 changes: 11 additions & 11 deletions src/images/sbm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,19 @@

namespace Images {

SBM::SBM(Common::SeekableReadStream &sbm) {
SBM::SBM(Common::SeekableReadStream &sbm, bool deswizzle) {
_format = kPixelFormatB8G8R8A8;

load(sbm);
load(sbm, deswizzle);
}

SBM::~SBM() {
}

void SBM::load(Common::SeekableReadStream &sbm) {
void SBM::load(Common::SeekableReadStream &sbm, bool deswizzle) {
try {

readData(sbm);
readData(sbm, deswizzle);

} catch (Common::Exception &e) {
e.add("Failed reading SBM file");
Expand All @@ -56,11 +56,11 @@ void SBM::load(Common::SeekableReadStream &sbm) {
::Images::flipVertically(_mipMaps[0]->data.get(), _mipMaps[0]->width, _mipMaps[0]->height, 4);
}

void SBM::readData(Common::SeekableReadStream &sbm) {
void SBM::readData(Common::SeekableReadStream &sbm, bool deswizzle) {
if ((sbm.size() % 1024) != 0)
throw Common::Exception("Invalid SBM (%u)", (uint)sbm.size());

size_t rowCount = (sbm.size() / 1024);
const size_t rowCount = (sbm.size() / 1024);

_mipMaps.push_back(new MipMap);

Expand All @@ -75,8 +75,8 @@ void SBM::readData(Common::SeekableReadStream &sbm) {
// coordinates but different planes.
// We'll unpack them and draw them next to each other instead.

int masks [4] = { 0x03, 0x0C, 0x30, 0xC0 };
int shifts[4] = { 0, 2, 4, 6 };
static const int masks [4] = { 0x03, 0x0C, 0x30, 0xC0 };
static const int shifts[4] = { 0, 2, 4, 6 };

byte *data = _mipMaps[0]->data.get();
byte buffer[1024];
Expand All @@ -86,11 +86,11 @@ void SBM::readData(Common::SeekableReadStream &sbm) {
throw Common::Exception(Common::kReadError);

for (int y = 0; y < 32; y++) {
byte *src = buffer + y * 32;

for (int plane = 0; plane < 4; plane++) {
for (int x = 0; x < 32; x++) {
byte a = ((src[x] & masks[plane]) >> shifts[plane]) * 0x55;
const uint32 offset = deswizzle ? deSwizzleOffset(x, y, 32, rowCount) : (y * 32 + x);

const byte a = ((buffer[offset] & masks[plane]) >> shifts[plane]) * 0x55;

*data++ = 0xFF; // B
*data++ = 0xFF; // G
Expand Down
11 changes: 8 additions & 3 deletions src/images/sbm.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,18 @@ namespace Images {
*/
class SBM : public Decoder {
public:
SBM(Common::SeekableReadStream &sbm);
/** Read an SBM image out of a stream.
*
* @param The stream to read out of.
* @param deswizzle This is an Xbox SBM that has swizzled data.
*/
SBM(Common::SeekableReadStream &sbm, bool deswizzle = false);
~SBM();

private:
// Loading helpers
void load(Common::SeekableReadStream &sbm);
void readData(Common::SeekableReadStream &sbm);
void load(Common::SeekableReadStream &sbm, bool deswizzle);
void readData(Common::SeekableReadStream &sbm, bool deswizzle);
};

} // End of namespace Images
Expand Down

0 comments on commit 06b5f17

Please sign in to comment.