From a39576d921a3b8c06887d6aa54886815c0a69c05 Mon Sep 17 00:00:00 2001 From: Pawel Kolodziejski Date: Thu, 24 Jul 2014 15:37:11 +0200 Subject: [PATCH] GRIM/EMI: attempt to fix over read buffer. cleanup types --- engines/grim/emi/lua_v2.cpp | 2 +- engines/grim/gfx_base.cpp | 7 ++++--- engines/grim/gfx_base.h | 8 ++++---- engines/grim/gfx_opengl.cpp | 10 +++++----- engines/grim/gfx_opengl.h | 6 ++++-- engines/grim/gfx_opengl_shaders.cpp | 4 ++-- engines/grim/gfx_opengl_shaders.h | 4 ++-- engines/grim/gfx_tinygl.cpp | 28 ++++++++++++++++++---------- engines/grim/gfx_tinygl.h | 4 ++-- engines/grim/material.cpp | 6 +++--- engines/grim/material.h | 2 +- 11 files changed, 46 insertions(+), 35 deletions(-) diff --git a/engines/grim/emi/lua_v2.cpp b/engines/grim/emi/lua_v2.cpp index 23067105dcb..1c84fcc7753 100644 --- a/engines/grim/emi/lua_v2.cpp +++ b/engines/grim/emi/lua_v2.cpp @@ -425,7 +425,7 @@ void Lua_V2::ThumbnailFromFile() { } screenshot->_data->convertToColorFormat(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)); - g_driver->createSpecialtyTexture(index, (char*)screenshot->getData(0).getRawBuffer(), width, height); + g_driver->createSpecialtyTexture(index, screenshot->getData(0).getRawBuffer(), width, height); delete[] data; savedState->endSection(); delete savedState; diff --git a/engines/grim/gfx_base.cpp b/engines/grim/gfx_base.cpp index b9367f0839a..2919b9c8f3c 100644 --- a/engines/grim/gfx_base.cpp +++ b/engines/grim/gfx_base.cpp @@ -161,8 +161,9 @@ Math::Matrix4 GfxBase::makeProjMatrix(float fov, float nclip, float fclip) { } -void GfxBase::createSpecialtyTexture(unsigned int id, const char *data, int width, int height) { - if (id >= _numSpecialtyTextures) return; +void GfxBase::createSpecialtyTexture(uint id, const uint8 *data, int width, int height) { + if (id >= _numSpecialtyTextures) + return; if (_specialtyTextures[id]._texture) { destroyTexture(&_specialtyTextures[id]); } @@ -214,7 +215,7 @@ Bitmap *GfxBase::createScreenshotBitmap(const Graphics::PixelBuffer src, int w, void GfxBase::makeScreenTextures() { //make a buffer big enough to hold any of the textures - char *buffer = new char[256 * 256 * 4]; + uint8 *buffer = new uint8[256 * 256 * 4]; // TODO: Handle screen resolutions other than 640 x 480 createSpecialtyTextureFromScreen(0, buffer, 0, 0, 256, 256); diff --git a/engines/grim/gfx_base.h b/engines/grim/gfx_base.h index c4ac3e8f392..a94d4b1af45 100644 --- a/engines/grim/gfx_base.h +++ b/engines/grim/gfx_base.h @@ -150,7 +150,7 @@ public: virtual void setupLight(Light *light, int lightId) = 0; virtual void turnOffLight(int lightId) = 0; - virtual void createTexture(Texture *texture, const char *data, const CMap *cmap, bool clamp) = 0; + virtual void createTexture(Texture *texture, const uint8 *data, const CMap *cmap, bool clamp) = 0; virtual void selectTexture(const Texture *texture) = 0; virtual void destroyTexture(Texture *texture) = 0; @@ -270,12 +270,12 @@ public: virtual void drawBuffers() {} virtual void refreshBuffers() {} - virtual void createSpecialtyTexture(unsigned int id, const char *data, int width, int height); - virtual void createSpecialtyTextureFromScreen(unsigned int id, char *data, int x, int y, int width, int height) = 0; + virtual void createSpecialtyTexture(uint id, const uint8 *data, int width, int height); + virtual void createSpecialtyTextureFromScreen(uint id, uint8 *data, int x, int y, int width, int height) = 0; static Math::Matrix4 makeLookMatrix(const Math::Vector3d& pos, const Math::Vector3d& interest, const Math::Vector3d& up); static Math::Matrix4 makeProjMatrix(float fov, float nclip, float fclip); - Texture *getSpecialtyTexturePtr(unsigned int id) { if (id >= _numSpecialtyTextures) return nullptr; return &_specialtyTextures[id]; }; + Texture *getSpecialtyTexturePtr(uint id) { if (id >= _numSpecialtyTextures) return nullptr; return &_specialtyTextures[id]; }; Texture *getSpecialtyTexturePtr(Common::String name); protected: Bitmap *createScreenshotBitmap(const Graphics::PixelBuffer src, int w, int h, bool flipOrientation); diff --git a/engines/grim/gfx_opengl.cpp b/engines/grim/gfx_opengl.cpp index 214e4d08e60..1a1e076db7d 100644 --- a/engines/grim/gfx_opengl.cpp +++ b/engines/grim/gfx_opengl.cpp @@ -1399,7 +1399,7 @@ void GfxOpenGL::drawTextObject(const TextObject *text) { void GfxOpenGL::destroyTextObject(TextObject *text) { } -void GfxOpenGL::createTexture(Texture *texture, const char *data, const CMap *cmap, bool clamp) { +void GfxOpenGL::createTexture(Texture *texture, const uint8 *data, const CMap *cmap, bool clamp) { texture->_texture = new GLuint[1]; glGenTextures(1, (GLuint *)texture->_texture); uint8 *texdata = new uint8[texture->_width * texture->_height * 4]; @@ -1974,15 +1974,15 @@ void GfxOpenGL::drawPolygon(const PrimitiveObject *primitive) { glEnable(GL_LIGHTING); } -static void readPixels(int x, int y, int width, int height, char *buffer) { - char *p = buffer; +void GfxOpenGL::readPixels(int x, int y, int width, int height, uint8 *buffer) { + uint8 *p = buffer; for (int i = y; i < y + height; i++) { - glReadPixels(x, 479 - i, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, p); + glReadPixels(x, _screenHeight - i, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, p); p += width * 4; } } -void GfxOpenGL::createSpecialtyTextureFromScreen(unsigned int id, char *data, int x, int y, int width, int height) { +void GfxOpenGL::createSpecialtyTextureFromScreen(uint id, uint8 *data, int x, int y, int width, int height) { readPixels(x, y, width, height, data); createSpecialtyTexture(id, data, width, height); } diff --git a/engines/grim/gfx_opengl.h b/engines/grim/gfx_opengl.h index 42423c4ee85..e6584c42ca2 100644 --- a/engines/grim/gfx_opengl.h +++ b/engines/grim/gfx_opengl.h @@ -91,7 +91,7 @@ public: void setupLight(Light *light, int lightId) override; void turnOffLight(int lightId) override; - void createTexture(Texture *texture, const char *data, const CMap *cmap, bool clamp) override; + void createTexture(Texture *texture, const uint8 *data, const CMap *cmap, bool clamp) override; void selectTexture(const Texture *texture) override; void destroyTexture(Texture *texture) override; @@ -125,7 +125,7 @@ public: void releaseMovieFrame() override; protected: - void createSpecialtyTextureFromScreen(unsigned int id, char *data, int x, int y, int width, int height) override; + void createSpecialtyTextureFromScreen(uint id, uint8 *data, int x, int y, int width, int height) override; void drawDepthBitmap(int x, int y, int w, int h, char *data); void initExtensions(); private: @@ -143,6 +143,8 @@ private: float _alpha; const Actor *_currentActor; GLenum _depthFunc; + + void readPixels(int x, int y, int width, int height, uint8 *buffer); }; } // end of namespace Grim diff --git a/engines/grim/gfx_opengl_shaders.cpp b/engines/grim/gfx_opengl_shaders.cpp index 4ce7da4904d..00539ec9503 100644 --- a/engines/grim/gfx_opengl_shaders.cpp +++ b/engines/grim/gfx_opengl_shaders.cpp @@ -1023,7 +1023,7 @@ void GfxOpenGLS::turnOffLight(int lightId) { } -void GfxOpenGLS::createTexture(Texture *texture, const char *data, const CMap *cmap, bool clamp) { +void GfxOpenGLS::createTexture(Texture *texture, const uint8 *data, const CMap *cmap, bool clamp) { texture->_texture = new GLuint[1]; glGenTextures(1, (GLuint *)texture->_texture); char *texdata = new char[texture->_width * texture->_height * 4]; @@ -1949,7 +1949,7 @@ Bitmap *GfxOpenGLS::getScreenshot(int w, int h, bool useStored) { return createScreenshotBitmap(src, w, h, false); } -void GfxOpenGLS::createSpecialtyTextureFromScreen(unsigned int id, char *data, int x, int y, int width, int height) { +void GfxOpenGLS::createSpecialtyTextureFromScreen(uint id, uint8 *data, int x, int y, int width, int height) { readPixels(x, y, width, height, data); createSpecialtyTexture(id, data, width, height); } diff --git a/engines/grim/gfx_opengl_shaders.h b/engines/grim/gfx_opengl_shaders.h index 30bc76a6faf..806a1c82c71 100644 --- a/engines/grim/gfx_opengl_shaders.h +++ b/engines/grim/gfx_opengl_shaders.h @@ -96,7 +96,7 @@ public: virtual void setupLight(Light *light, int lightId) override; virtual void turnOffLight(int lightId) override; - virtual void createTexture(Texture *texture, const char *data, const CMap *cmap, bool clamp) override; + virtual void createTexture(Texture *texture, const uint8 *data, const CMap *cmap, bool clamp) override; virtual void selectTexture(const Texture *texture) override; virtual void destroyTexture(Texture *texture) override; @@ -207,7 +207,7 @@ protected: void setupShaders(); GLuint compileShader(const char *vertex, const char *fragment); GLuint compileShader(const char *shader) { return compileShader(shader, shader); } - void createSpecialtyTextureFromScreen(unsigned int id, char *data, int x, int y, int width, int height) override; + void createSpecialtyTextureFromScreen(uint id, uint8 *data, int x, int y, int width, int height) override; private: const Actor *_currentActor; diff --git a/engines/grim/gfx_tinygl.cpp b/engines/grim/gfx_tinygl.cpp index 74a82708a0d..230adc77d70 100644 --- a/engines/grim/gfx_tinygl.cpp +++ b/engines/grim/gfx_tinygl.cpp @@ -1164,7 +1164,6 @@ void GfxTinyGL::blitScreen(const Graphics::PixelFormat &format, BlitImage *image } void GfxTinyGL::drawBitmap(const Bitmap *bitmap, int x, int y, uint32 layer) { - // PS2 EMI uses a TGA for it's splash-screen, avoid using the following // code for drawing that (as it has no tiles). if (g_grim->getGameType() == GType_MONKEY4 && bitmap->_data->_numImages > 1) { @@ -1336,7 +1335,7 @@ void GfxTinyGL::destroyTextObject(TextObject *text) { } } -void GfxTinyGL::createTexture(Texture *texture, const char *data, const CMap *cmap, bool clamp) { +void GfxTinyGL::createTexture(Texture *texture, const uint8 *data, const CMap *cmap, bool clamp) { texture->_texture = new TGLuint[1]; tglGenTextures(1, (TGLuint *)texture->_texture); uint8 *texdata = new uint8[texture->_width * texture->_height * 4]; @@ -1472,8 +1471,8 @@ Bitmap *GfxTinyGL::getScreenshot(int w, int h, bool useStored) { } } -void GfxTinyGL::createSpecialtyTextureFromScreen(unsigned int id, char *data, int x, int y, int width, int height) { - readPixels(x, y, width, height, (uint8*)data); +void GfxTinyGL::createSpecialtyTextureFromScreen(uint id, uint8 *data, int x, int y, int width, int height) { + readPixels(x, y, width, height, data); createSpecialtyTexture(id, data, width, height); } @@ -1608,18 +1607,27 @@ void GfxTinyGL::drawPolygon(const PrimitiveObject *primitive) { } void GfxTinyGL::readPixels(int x, int y, int width, int height, uint8 *buffer) { + assert(x >= 0); + assert(y >= 0); + assert(x < _screenWidth); + assert(y < _screenHeight); + uint8 r, g, b; - int pos = x + y * 640; + int pos = x + y * _screenWidth; for (int i = 0; i < height; ++i) { for (int j = 0; j < width; ++j) { - _zb->readPixelRGB(pos + j, r, g, b); - buffer[0] = r; - buffer[1] = g; - buffer[2] = b; + if ((j + x) >= _screenWidth || (i + y) >= _screenHeight) { + buffer[0] = buffer[1] = buffer[2] = 0; + } else { + _zb->readPixelRGB(pos + j, r, g, b); + buffer[0] = r; + buffer[1] = g; + buffer[2] = b; + } buffer[3] = 255; buffer += 4; } - pos += 640; + pos += _screenWidth; } } diff --git a/engines/grim/gfx_tinygl.h b/engines/grim/gfx_tinygl.h index bf1fd37989b..01f11be278d 100644 --- a/engines/grim/gfx_tinygl.h +++ b/engines/grim/gfx_tinygl.h @@ -89,7 +89,7 @@ public: void setupLight(Light *light, int lightId) override; void turnOffLight(int lightId) override; - void createTexture(Texture *texture, const char *data, const CMap *cmap, bool clamp) override; + void createTexture(Texture *texture, const uint8 *data, const CMap *cmap, bool clamp) override; void selectTexture(const Texture *texture) override; void destroyTexture(Texture *texture) override; @@ -131,7 +131,7 @@ public: void refreshBuffers() override; protected: - void createSpecialtyTextureFromScreen(unsigned int id, char *data, int x, int y, int width, int height); + void createSpecialtyTextureFromScreen(uint id, uint8 *data, int x, int y, int width, int height); private: TinyGL::FrameBuffer *_zb; diff --git a/engines/grim/material.cpp b/engines/grim/material.cpp index 52b4fc681e0..761140a228c 100644 --- a/engines/grim/material.cpp +++ b/engines/grim/material.cpp @@ -80,7 +80,7 @@ void MaterialData::initGrim(Common::SeekableReadStream *data) { t->_width, t->_height, i, _fname.c_str()); break; } - t->_data = new char[t->_width * t->_height]; + t->_data = new uint8[t->_width * t->_height]; data->seek(12, SEEK_CUR); data->read(t->_data, t->_width * t->_height); } @@ -109,7 +109,7 @@ void loadTGA(Common::SeekableReadStream *data, Texture *t) { assert(bpp == 3 || bpp == 4); // Assure we have 24/32 bpp // Allocate room for the texture. - t->_data = new char[t->_width * t->_height * (bpp)]; + t->_data = new uint8[t->_width * t->_height * (bpp)]; // Copy the texture data, as the decoder owns the current copy. memcpy(t->_data, tgaSurface->getPixels(), t->_width * t->_height * (bpp)); @@ -240,7 +240,7 @@ void Material::select() const { Texture *t = _data->_textures[_currImage]; if (t && t->_width && t->_height) { if (!t->_texture) { - g_driver->createTexture(t, t->_data, _data->_cmap, _clampTexture); + g_driver->createTexture(t, (uint8 *)t->_data, _data->_cmap, _clampTexture); delete[] t->_data; t->_data = nullptr; } diff --git a/engines/grim/material.h b/engines/grim/material.h index 74e378c1ad7..ad3cf104d5a 100644 --- a/engines/grim/material.h +++ b/engines/grim/material.h @@ -39,7 +39,7 @@ public: int _bpp; bool _hasAlpha; void *_texture; - char *_data; + uint8 *_data; bool _isShared; };