From 6d92cd24c8b38324014501af36ef44d5e541c78e Mon Sep 17 00:00:00 2001 From: fgenesis Date: Thu, 14 Jun 2012 17:40:01 +0200 Subject: [PATCH 1/3] Fixed more weirdness in functions using glGetTexImage(), add proper bounds checking --- Aquaria/Game.cpp | 77 ++++++++++++++++++++---------------------------- BBGE/Texture.cpp | 75 +++++++++++++++++++++------------------------- 2 files changed, 65 insertions(+), 87 deletions(-) diff --git a/Aquaria/Game.cpp b/Aquaria/Game.cpp index 1fa21df..fe662f8 100644 --- a/Aquaria/Game.cpp +++ b/Aquaria/Game.cpp @@ -1977,8 +1977,8 @@ void Game::fillGridFromQuad(Quad *q, ObsType obsType, bool trim) glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h); //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPONENTS, &c);// assume 4 - int size = w*h*4; - if(size <= 0) + unsigned int size = w*h*4; + if (!size || w <= 0 || h <= 0) return; unsigned char *data = (unsigned char*)malloc(size + 6); memcpy(data + size, "SAFE", 5); @@ -2014,12 +2014,12 @@ void Game::fillGridFromQuad(Quad *q, ObsType obsType, bool trim) { // starting position = // tx / scale.x - int px = int(tx/q->scale.x) + x; - int py = int(ty/q->scale.y) + y; - if (px < w && py < h) + unsigned int px = int(tx/q->scale.x) + x; + unsigned int py = int(ty/q->scale.y) + y; + if (px < unsigned(w) && py < unsigned(h)) { - int p = (py*w*4) + px*4; - if (data[p+3] >= 254) + unsigned int p = (py*unsigned(w)*4) + (px*4) + 3; // position of alpha component + if (p < size && data[p] >= 254) { num ++; } @@ -2794,32 +2794,27 @@ void Game::generateCollisionMask(Quad *q, int overrideCollideRadius) else q->collideRadius = TILE_SIZE/2; q->collisionMask.clear(); - std::vector obs; TileVector tpos(q->position); - int w2 = int(q->getWidth()*q->scale.x)>>1; - int h2 = int(q->getHeight()*q->scale.y)>>1; + int widthscale = q->getWidth()*q->scale.x; + int heightscale = q->getHeight()*q->scale.y; + int w2 = widthscale/2; + int h2 = heightscale/2; w2/=TILE_SIZE; h2/=TILE_SIZE; tpos.x -= w2; tpos.y -= h2; GLuint id = q->texture->textures[0]; - float w, h, c=4; + int w = 0, h = 0; glBindTexture(GL_TEXTURE_2D, id); - glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); - glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h); - //glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPONENTS, &c);// assume 4 - int size = w*h*c; - unsigned char *data=0; + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h); + //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPONENTS, &c);// assume 4 - int sz = size*sizeof(unsigned char); + unsigned int size = w*h*4; + if (!size || w <= 0 || h <= 0) + return; - /* - std::ostringstream os; - os << "size: " << sz; - debugLog(os.str()); - */ - - data = (unsigned char*)malloc(sz); + unsigned char *data = (unsigned char*)malloc(size); if (!data) { @@ -2832,15 +2827,16 @@ void Game::generateCollisionMask(Quad *q, int overrideCollideRadius) Vector collisionMaskHalfVector = Vector(q->getWidth()/2, q->getHeight()/2); - for (int tx = 0; tx < (q->getWidth()*q->scale.x); tx+=TILE_SIZE) + int szx = TILE_SIZE/q->scale.x; + int szy = TILE_SIZE/q->scale.y; + if (szx < 1) szx = 1; + if (szy < 1) szy = 1; + + for (int tx = 0; tx < widthscale; tx+=TILE_SIZE) { - for (int ty = 0; ty < (q->getHeight()*q->scale.y); ty+=TILE_SIZE) + for (int ty = 0; ty < heightscale; ty+=TILE_SIZE) { int num = 0; - int szx = TILE_SIZE/q->scale.x; - int szy = TILE_SIZE/q->scale.y; - if (szx < 1) szx = 1; - if (szy < 1) szy = 1; for (int x = 0; x < szx; x++) { @@ -2848,18 +2844,12 @@ void Game::generateCollisionMask(Quad *q, int overrideCollideRadius) { // starting position = // tx / scale.x - int px = int(tx/q->scale.x) + x; - int py = int(ty/q->scale.y) + y; - if (px < w && py < h) + unsigned int px = int(tx/q->scale.x) + x; + unsigned int py = int(ty/q->scale.y) + y; + if (px < unsigned(w) && py < unsigned(h)) { - int p = (py*w*c) + px*c; - /* - std::ostringstream os; - os << "data(" << int(data[p]) << ", " << int(data[p+1]); - os << ", " << int(data[p+2]) << ", " << int(data[p+3]) << ")"; - debugLog(os.str()); - */ - if (int(data[p+3]) >= 250) + unsigned int p = (py*unsigned(w)*4) + (px*4) + 3; // position of alpha component + if (p < size && data[p] >= 250) { num ++; } @@ -2869,9 +2859,6 @@ void Game::generateCollisionMask(Quad *q, int overrideCollideRadius) if (num >= int((szx*szy)*0.25f)) { TileVector tile(int((tx+TILE_SIZE/2)/TILE_SIZE), int((ty+TILE_SIZE/2)/TILE_SIZE)); - - obs.push_back(tile); - // + Vector(0,TILE_SIZE) q->collisionMask.push_back(tile.worldVector() - collisionMaskHalfVector); } @@ -2903,7 +2890,7 @@ void Game::generateCollisionMask(Quad *q, int overrideCollideRadius) q->collisionMaskRadius = 512; glBindTexture(GL_TEXTURE_2D, 0); - if (data) free(data); + free(data); /* int rot = rotation.z; while (rot > 360) diff --git a/BBGE/Texture.cpp b/BBGE/Texture.cpp index c3e01fc..7951a40 100644 --- a/BBGE/Texture.cpp +++ b/BBGE/Texture.cpp @@ -194,34 +194,31 @@ void Texture::destroy() int Texture::getPixelWidth() { #ifdef BBGE_BUILD_OPENGL - float w, h, c; + int w = 0, h = 0; glBindTexture(GL_TEXTURE_2D, textures[0]); - glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); - glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h); - glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPONENTS, &c);// assume 4 - int size = w*h*c; - unsigned char *data=0; - data = (unsigned char*)malloc(size*sizeof(char)); - if (c == 4) - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - /* - else if (c == 3) - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, data); - */ - else + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h); + //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPONENTS, &c);// assume 4 + unsigned int size = w*h*4; + if (!size || w <= 0 || h <= 0) + return 0; + + unsigned char *data = (unsigned char*)malloc(size*sizeof(char)); + if (!data) { - if (data) - free(data); + debugLog("Texture::getPixelWidth() malloc failed"); return 0; } + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + int smallestx = -1, largestx = -1; - for (int x = 0; x < w; x++) + for (unsigned int x = 0; x < unsigned(w); x++) { - for (int y = 0; y < h; y++) + for (unsigned int y = 0; y < unsigned(h); y++) { - int p = (y*w*c) + x*c; - if (data[p+3] >= 254) + unsigned int p = (y*unsigned(w)*4) + (x*4) + 3; + if (p < size && data[p] >= 254) { if (smallestx == -1 || x < smallestx) smallestx = x; @@ -241,33 +238,28 @@ int Texture::getPixelWidth() int Texture::getPixelHeight() { #ifdef BBGE_BUILD_OPENGL - float w, h, c; + int w = 0, h = 0; glBindTexture(GL_TEXTURE_2D, textures[0]); - glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); - glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h); - glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPONENTS, &c);// assume 4 - int size = w*h*c; - unsigned char *data=0; - data = (unsigned char*)malloc(size*sizeof(char)); - if (c == 4) - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - /* - else if (c == 3) - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, data); - */ - else + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h); + //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPONENTS, &c);// assume 4 + unsigned int size = w*h*4; + if (!size || w <= 0 || h <= 0) + return 0; + unsigned char *data = (unsigned char*)malloc(size*sizeof(char)); + if (!data) { - if (data) - free(data); + debugLog("Texture::getPixelHeight() malloc failed"); return 0; } + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); int smallesty = -1, largesty = -1; - for (int x = 0; x < w; x++) + for (unsigned int x = 0; x < unsigned(w); x++) { - for (int y = 0; y < h; y++) + for (unsigned int y = 0; y < unsigned(h); y++) { - int p = (y*w*c) + x*c; - if (data[p+3] >= 254) + int p = (y*unsigned(w)*4) + (x*4) + 3; + if (p < size && data[p] >= 254) { if (smallesty == -1 || y < smallesty) smallesty = y; @@ -277,8 +269,7 @@ int Texture::getPixelHeight() } } glBindTexture(GL_TEXTURE_2D, 0); - if (data) - free(data); + free(data); return largesty - smallesty; #elif defined(BBGE_BUILD_DIRECTX) return 0; From 8f2279e28a0b35013af4ed45ceffc4135dc0d1f5 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Thu, 14 Jun 2012 17:54:40 +0200 Subject: [PATCH 2/3] Fix problems with loading saves after saving over them. This was caused by the VFS caching file sizes, and not noticing that the file size had changed, which confused zlib because the data stream ended too early. --- BBGE/Base.cpp | 6 ++++-- ExternalLibs/ttvfs/VFSFile.cpp | 18 +++--------------- ExternalLibs/ttvfs/VFSFile.h | 3 +-- ExternalLibs/ttvfs/VFSTools.cpp | 29 +++++++++++++++++++---------- 4 files changed, 27 insertions(+), 29 deletions(-) diff --git a/BBGE/Base.cpp b/BBGE/Base.cpp index 888a960..7d2d4e6 100644 --- a/BBGE/Base.cpp +++ b/BBGE/Base.cpp @@ -458,9 +458,9 @@ char *readFile(const std::string& path, unsigned long *size_ret) VFILE *vf = vfs.GetFile(path.c_str()); if (!vf) return NULL; - fileSize = vf->size(); char *buffer = (char*)vf->getBuf(NULL, NULL); - vf->dropBuf(false); + fileSize = vf->size(); + vf->dropBuf(false); // unlink buffer from file #else FILE *f = fopen(path.c_str(), "rb"); if (!f) @@ -1128,6 +1128,8 @@ char *readCompressedFile(std::string path, unsigned long *size_ret) { unsigned long size = 0; char *buf = readFile(path, &size); + if(!buf) + return NULL; ZlibCompressor z; // allocates with new[] by default z.init(buf, size, ByteBuffer::TAKE_OVER); z.Compressed(true); diff --git a/ExternalLibs/ttvfs/VFSFile.cpp b/ExternalLibs/ttvfs/VFSFile.cpp index 74a328f..275fa75 100644 --- a/ExternalLibs/ttvfs/VFSFile.cpp +++ b/ExternalLibs/ttvfs/VFSFile.cpp @@ -76,7 +76,7 @@ void VFSFile::dropBuf(bool del) } VFSFileReal::VFSFileReal(const char *name /* = NULL */) -: VFSFile(name), _fh(NULL), _size(npos), _buf(NULL) +: VFSFile(name), _fh(NULL), _buf(NULL) { } @@ -94,14 +94,8 @@ bool VFSFileReal::open(const char *mode /* = NULL */) dropBuf(true); _fh = real_fopen(fullname(), mode ? mode : "rb"); - if(!_fh) - return false; - real_fseek((FILE*)_fh, 0, SEEK_END); - _size = getpos(); - real_fseek((FILE*)_fh, 0, SEEK_SET); - - return true; + return !!_fh; } bool VFSFileReal::isopen(void) const @@ -177,13 +171,7 @@ unsigned int VFSFileReal::write(const void *src, unsigned int bytes) vfspos VFSFileReal::size(void) { - VFS_GUARD_OPT(this); - if(_size != npos) - return _size; - open(); - close(); - // now size is known. - return _size; + return GetFileSize(fullname()); } // ------------- VFSFileMem ----------------------- diff --git a/ExternalLibs/ttvfs/VFSFile.h b/ExternalLibs/ttvfs/VFSFile.h index 2ed3273..5aef550 100644 --- a/ExternalLibs/ttvfs/VFSFile.h +++ b/ExternalLibs/ttvfs/VFSFile.h @@ -73,7 +73,7 @@ public: virtual const void *getBuf(allocator_func alloc = NULL, delete_func del = NULL); /** If del is true, delete internal buffer. If false, unregister internal buffer from the file, - but do not delete. Use free() or an appropriate deletion function later. */ + but do not delete. Use delete[] or an appropriate deletion function later. */ virtual void dropBuf(bool del); /** Basic RTTI, for debugging purposes */ @@ -117,7 +117,6 @@ public: protected: void *_fh; // FILE* - vfspos _size; void *_buf; }; diff --git a/ExternalLibs/ttvfs/VFSTools.cpp b/ExternalLibs/ttvfs/VFSTools.cpp index 11165c1..5bb5e03 100644 --- a/ExternalLibs/ttvfs/VFSTools.cpp +++ b/ExternalLibs/ttvfs/VFSTools.cpp @@ -18,11 +18,12 @@ # include #else # include -# include -# include # include #endif +#include +#include + VFS_NAMESPACE_START std::string stringToLower(std::string s) @@ -259,16 +260,24 @@ bool CreateDirRec(const char *dir) vfspos GetFileSize(const char* fn) { - if(!fn || !*fn) +#ifdef VFS_LARGEFILE_SUPPORT +# ifdef _MSC_VER + struct _stat64 st; + if(_stat64(fn, &st)) return 0; - void *fp = real_fopen(fn, "rb"); - if(!fp) + return st.st_size; +# else // _MSC_VER + struct stat64 st; + if(stat64(fn, &st)) return 0; - real_fseek(fp, 0, SEEK_END); - vfspos s = real_ftell(fp); - real_fclose(fp); - - return s == npos ? 0 : s; + return st.st_size; +# endif +#else // VFS_LARGEFILE_SUPPORT + struct stat st; + if(stat(fn, &st)) + return 0; + return st.st_size; +#endif } std::string FixSlashes(const std::string& s) From 5b7757530f5d333456e510f5be88997b85ed9a8a Mon Sep 17 00:00:00 2001 From: fgenesis Date: Thu, 14 Jun 2012 19:06:06 +0200 Subject: [PATCH 3/3] More linux file name case issues... --- BBGE/SoundManager.cpp | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/BBGE/SoundManager.cpp b/BBGE/SoundManager.cpp index f6fdc50..b5a5ae8 100644 --- a/BBGE/SoundManager.cpp +++ b/BBGE/SoundManager.cpp @@ -925,15 +925,13 @@ bool SoundManager::playVoice(const std::string &name, SoundVoiceType svt, float if (!voicePath2.empty()) { - fn = voicePath2 + name + fileType; - stringToLower(fn); + fn = core->adjustFilenameCase(voicePath2 + name + fileType); if (exists(fn)) checkOther = false; } if (checkOther) { - fn = voicePath + name + fileType; - stringToLower(fn); + fn = core->adjustFilenameCase(voicePath + name + fileType); if (!exists(fn)) { debugLog("Could not find voice file [" + fn + "]"); @@ -1281,27 +1279,25 @@ bool SoundManager::playMusic(const std::string &name, SoundLoopType slt, SoundFa if (!name.empty() && name[0] == '.') { fn = name; - stringToLower(fn); } else { if (!audioPath2.empty()) { fn = audioPath2 + name + fileType; - stringToLower(fn); if (!exists(fn)) { fn = musicPath + name + fileType; - stringToLower(fn); } } else { fn = musicPath + name + fileType; - stringToLower(fn); } } + fn = core->adjustFilenameCase(fn); + lastMusic = name; stringToLower(lastMusic); @@ -1498,14 +1494,8 @@ void loadCacheSoundsCallback (const std::string &filename, intptr_t param) } if (fileType==".ogg") { - - std::string f = filename; - stringToLower(f); - - debugLog("trying to load sound " + f); - - sm->loadSoundIntoBank(f, "", ""); - + debugLog("trying to load sound " + filename); + sm->loadSoundIntoBank(filename, "", ""); } } @@ -1525,21 +1515,18 @@ Buffer SoundManager::loadSoundIntoBank(const std::string &filename, const std::s // WARNING: local sounds should go here! - debugLog(filename); + debugLog(filename); if (slt == SFXLOAD_LOCAL && !audioPath2.empty()) { - f = audioPath2 + filename + format; - stringToLower(f); + f = core->adjustFilenameCase(audioPath2 + filename + format); if (!exists(f)) { - f = path + filename + format; - stringToLower(f); + f = core->adjustFilenameCase(path + filename + format); } } else { - f = path + filename + format; - stringToLower(f); + f = core->adjustFilenameCase(path + filename + format); } bool loop = false; @@ -1561,6 +1548,8 @@ Buffer SoundManager::loadSoundIntoBank(const std::string &filename, const std::s return Buffer(); } + stringToLower(name); + #ifdef BBGE_BUILD_FMODEX FMOD::Sound * sound = SoundCore::soundMap[name];