EMI: Load TIL files correctly

This commit is contained in:
Joel Teichroeb 2012-11-18 09:17:21 -08:00
parent 0116625b75
commit e27a6ad833
3 changed files with 91 additions and 68 deletions

View file

@ -37,61 +37,6 @@ static bool decompress_codec3(const char *compressed, char *result, int maxBytes
Common::HashMap<Common::String, BitmapData *> *BitmapData::_bitmaps = NULL;
// Helper function for makeBitmapFromTile
char *getLine(int lineNum, char *data, unsigned int width, int bpp) {
return data + (lineNum *(width * bpp));
}
#ifdef ENABLE_MONKEY4
char *makeBitmapFromTile(char **bits, int width, int height, int bpp) {
bpp = bpp / 8;
char *fullImage = new char[width * height * bpp];
const int tWidth = 256 * bpp; // All tiles so far are 256 wide
const int tWidth2 = 256;
char *target = fullImage;
int line;
for (int i = 0; i < 256; i++) {
/* This can be modified to actually use the last 32 lines.
* We simply put the lower half on line 223 and down to line 32,
* then skip the last 32.
* While the upper half is put on line 479 and down to line 224.
*/
if (i < 224) { // Skip blank space
line = 224 - i;
target = getLine(479 - i, fullImage, width, bpp);
memcpy(target, getLine(line, bits[3], tWidth2, bpp), tWidth);
target += tWidth;
memcpy(target, getLine(line, bits[4], tWidth2, bpp), tWidth);
target += tWidth;
memcpy(target, getLine(line, bits[2], tWidth2, bpp) + 128 * bpp, 128 * bpp);
}
line = 255 - i;
// Top half of course
target = getLine(line, fullImage, width, bpp);
memcpy(target, getLine(line, bits[0], tWidth2, bpp), tWidth);
target += tWidth;
memcpy(target, getLine(line, bits[1], tWidth2, bpp), tWidth);
target += tWidth;
memcpy(target, getLine(line, bits[2], tWidth2, bpp), 128 * bpp);
}
return fullImage;
}
#endif
BitmapData *BitmapData::getBitmapData(const Common::String &fname) {
Common::String str(fname);
if (_bitmaps && _bitmaps->contains(str)) {
@ -323,12 +268,37 @@ bool BitmapData::loadTile(Common::SeekableReadStream *o) {
_y = 0;
_format = 1;
o->seek(0, SEEK_SET);
//warning("Loading TILE: %s",fname.c_str());
/*uint32 id = */o->readUint32LE();
// Should check that we actually HAVE a TIL
uint32 bmoffset = o->readUint32LE();
o->seek(bmoffset + 16);
_numCoords = o->readUint32LE();
_numOffsets = o->readUint32LE();
_numVerts = o->readUint32LE();
// skip some 0
o->seek(16, SEEK_CUR);
_texc = new float[_numCoords * 4];
for (uint32 i = 0; i < _numCoords * 4; ++i) {
o->read(&_texc[i], sizeof(float));
}
_offsets = new Offset[_numOffsets];
for (uint32 i = 0; i < _numOffsets; ++i) {
_offsets[i]._offset = o->readUint32LE();
_offsets[i]._numImages = o->readUint32LE();
}
_curOffset = _numOffsets - 1;
_verts = new Vert[_numVerts];
for (uint32 i = 0; i < _numVerts; ++i) {
_verts[i]._texid = o->readUint32LE();
_verts[i]._pos = o->readUint32LE();
_verts[i]._verts = o->readUint32LE();
}
o->seek(16, SEEK_CUR);
int numSubImages = o->readUint32LE();
if (numSubImages < 5)
error("Can not handle a tile with less than 5 sub images");
@ -351,11 +321,6 @@ bool BitmapData::loadTile(Common::SeekableReadStream *o) {
o->read(data[i], size);
}
char *bMap = makeBitmapFromTile(data, 640, 480, _bpp);
for (int i = 0; i < numSubImages; ++i) {
delete[] data[i];
}
delete[] data;
Graphics::PixelFormat pixelFormat;
if (_bpp == 16) {
_colorFormat = BM_RGB1555;
@ -366,12 +331,16 @@ bool BitmapData::loadTile(Common::SeekableReadStream *o) {
_colorFormat = BM_RGBA;
}
_width = 640;
_height = 480;
_numImages = 1;
_width = 256;
_height = 256;
_numImages = numSubImages;
_data = new Graphics::PixelBuffer[_numImages];
_data[0].create(pixelFormat, _width * _height, DisposeAfterUse::YES);
_data[0].set(pixelFormat, (byte *)bMap);
for (int i = 0; i < _numImages; ++i) {
_data[i].create(pixelFormat, _width * _height, DisposeAfterUse::YES);
_data[i].set(pixelFormat, (byte *)data[i]);
}
delete[] data;
g_driver->createBitmap(this);
#endif // ENABLE_MONKEY4

View file

@ -102,6 +102,24 @@ public:
int _refCount;
float *_texc;
struct Vert {
uint32 _texid;
uint32 _pos;
uint32 _verts;
};
struct Offset {
uint32 _offset;
uint32 _numImages;
};
Vert *_verts;
Offset *_offsets;
uint32 _numCoords;
uint32 _numVerts;
uint32 _numOffsets;
uint32 _curOffset;
// private:
Graphics::PixelBuffer *_data;
};
@ -153,7 +171,7 @@ public:
virtual ~Bitmap();
private:
//private:
void freeData();
BitmapData *_data;

View file

@ -805,6 +805,42 @@ void GfxOpenGL::createBitmap(BitmapData *bitmap) {
}
void GfxOpenGL::drawBitmap(const Bitmap *bitmap, int dx, int dy) {
if (g_grim->getGameType() == GType_MONKEY4) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1, 1, 0, 1);
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
BitmapData *data = bitmap->_data;
GLuint *textures = (GLuint *)bitmap->getTexIds();
float *texc = data->_texc;
uint32 offset = data->_offsets[data->_curOffset]._offset;
for (uint32 i = offset; i < offset + data->_offsets[data->_curOffset]._numImages; ++i) {
glBindTexture(GL_TEXTURE_2D, textures[data->_verts[i]._texid]);
glBegin(GL_QUADS);
uint32 ntex = data->_verts[i]._pos * 4;
for (uint32 x = 0; x < data->_verts[i]._verts; ++x) {
glTexCoord2f(texc[ntex + 2], texc[ntex + 3]);
glVertex2f(texc[ntex + 0], texc[ntex + 1]);
ntex += 4;
}
glEnd();
}
glDisable(GL_TEXTURE_2D);
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
return;
}
int format = bitmap->getFormat();
if ((format == 1 && !_renderBitmaps) || (format == 5 && !_renderZBitmaps)) {
return;