From ba1824ef833d3cd216b429015f80eff256a30327 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Fri, 8 Feb 2013 02:05:28 +0000 Subject: [PATCH] sys: cycle through all possible directories to load resource files. --- src/image/codec/gdiplus-image.cpp | 73 +++++++++++++++++-------------- src/image/codec/sdl-image.cpp | 12 +++-- src/lol/sys/init.h | 4 +- src/sample.cpp | 11 +++-- src/sys/init.cpp | 30 ++++++++----- 5 files changed, 79 insertions(+), 51 deletions(-) diff --git a/src/image/codec/gdiplus-image.cpp b/src/image/codec/gdiplus-image.cpp index 30e7aa2d..22756255 100644 --- a/src/image/codec/gdiplus-image.cpp +++ b/src/image/codec/gdiplus-image.cpp @@ -40,8 +40,8 @@ public: virtual void *GetData() const; private: - Gdiplus::Bitmap *bitmap; - Gdiplus::BitmapData bdata; + Gdiplus::Bitmap *m_bitmap; + Gdiplus::BitmapData m_bdata; }; /* @@ -62,39 +62,46 @@ bool GdiPlusImageData::Open(char const *path) return false; } - String fullpath = String(System::GetDataDir()) + String(path); - size_t len; - len = mbstowcs(NULL, &fullpath[0], 0); - wchar_t *wpath = new wchar_t[len + 1]; - if (mbstowcs(wpath, &fullpath[0], len + 1) == (size_t)-1) + Array pathlist = System::GetPathList(path); + m_bitmap = NULL; + for (int i = 0; i < pathlist.Count(); ++i) { + size_t len; + len = mbstowcs(NULL, pathlist[i].C(), 0); + wchar_t *wpath = new wchar_t[len + 1]; + if (mbstowcs(wpath, pathlist[i].C(), len + 1) == (size_t)-1) + { #if !LOL_RELEASE - Log::Error("invalid image name %s\n", &fullpath[0]); + Log::Error("invalid image name %s\n", pathlist[i].C()); #endif - delete[] wpath; - return false; - } + delete[] wpath; + continue; + } - bitmap = NULL; - status = Gdiplus::Ok; - bitmap = Gdiplus::Bitmap::FromFile(wpath, 0); - if (bitmap) - { - status = bitmap->GetLastStatus(); - if (status != Gdiplus::Ok) + status = Gdiplus::Ok; + m_bitmap = Gdiplus::Bitmap::FromFile(wpath, 0); + + if (m_bitmap) { + status = m_bitmap->GetLastStatus(); + if (status != Gdiplus::Ok) + { #if !LOL_RELEASE - if (status != Gdiplus::InvalidParameter) - Log::Error("error %d loading %s\n", - status, &fullpath[0]); + if (status != Gdiplus::InvalidParameter) + Log::Error("error %d loading %s\n", + status, pathlist[i].C()); #endif - delete bitmap; - bitmap = NULL; + delete m_bitmap; + m_bitmap = NULL; + } } + + delete[] wpath; + if (m_bitmap) + break; } - delete[] wpath; - if (!bitmap) + if (!m_bitmap) { #if !LOL_RELEASE Log::Error("could not load %s\n", path); @@ -102,24 +109,24 @@ bool GdiPlusImageData::Open(char const *path) return false; } - size = ivec2(bitmap->GetWidth(), bitmap->GetHeight()); + size = ivec2(m_bitmap->GetWidth(), m_bitmap->GetHeight()); format = Image::FORMAT_RGBA; Gdiplus::Rect rect(0, 0, size.x, size.y); - if(bitmap->LockBits(&rect, Gdiplus::ImageLockModeRead, - PixelFormat32bppARGB, &bdata) != Gdiplus::Ok) + if(m_bitmap->LockBits(&rect, Gdiplus::ImageLockModeRead, + PixelFormat32bppARGB, &m_bdata) != Gdiplus::Ok) { #if !LOL_RELEASE Log::Error("could not lock bits in %s\n", path); #endif - delete bitmap; + delete m_bitmap; return false; } /* FIXME: GDI+ doesn't know about RGBA, only ARGB. And OpenGL doesn't * know about ARGB, only RGBA. So we swap bytes. We could also fix * this in the shader. */ - uint8_t *p = static_cast(bdata.Scan0); + uint8_t *p = static_cast(m_bdata.Scan0); for (int y = 0; y < size.y; y++) for (int x = 0; x < size.x; x++) { @@ -134,15 +141,15 @@ bool GdiPlusImageData::Open(char const *path) bool GdiPlusImageData::Close() { - bitmap->UnlockBits(&bdata); - delete bitmap; + m_bitmap->UnlockBits(&m_bdata); + delete m_bitmap; return true; } void * GdiPlusImageData::GetData() const { - return bdata.Scan0; + return m_bdata.Scan0; } } /* namespace lol */ diff --git a/src/image/codec/sdl-image.cpp b/src/image/codec/sdl-image.cpp index 869b0f1d..14192806 100644 --- a/src/image/codec/sdl-image.cpp +++ b/src/image/codec/sdl-image.cpp @@ -57,12 +57,18 @@ private: bool SdlImageData::Open(char const *path) { - String fullpath = String(System::GetDataDir()) + String(path); - m_img = IMG_Load(&fullpath[0]); + Array pathlist = System::GetPathList(path); + for (int i = 0; i < pathlist.Count(); i++) + { + m_img = IMG_Load(pathlist[i].C()); + if (m_img) + break; + } + if (!m_img) { #if !LOL_RELEASE - Log::Error("could not load %s\n", &fullpath[0]); + Log::Error("could not load image %s\n", path); #endif return false; } diff --git a/src/lol/sys/init.h b/src/lol/sys/init.h index 27ff4314..3c2c459c 100644 --- a/src/lol/sys/init.h +++ b/src/lol/sys/init.h @@ -46,8 +46,8 @@ extern void Init(int argc, char *argv[], String const &projectdir = LOL_CONFIG_PROJECTDIR, String const &solutiondir = LOL_CONFIG_SOLUTIONDIR); -extern void SetDataDir(String const &dir); -extern String const &GetDataDir(); +extern void AddDataDir(String const &dir); +extern Array GetPathList(String const &file); } /* namespace System */ diff --git a/src/sample.cpp b/src/sample.cpp index a322854d..086fc00e 100644 --- a/src/sample.cpp +++ b/src/sample.cpp @@ -63,12 +63,17 @@ Sample::Sample(char const *path) sprintf(data->name, " %s", path); #if defined USE_SDL_MIXER - String fullpath = String(System::GetDataDir()) + String(path); - data->chunk = Mix_LoadWAV(&fullpath[0]); + Array pathlist = System::GetPathList(path); + for (int i = 0; i < pathlist.Count(); ++i) + { + data->chunk = Mix_LoadWAV(pathlist[0].C()); + if (data->chunk) + break; + } if (!data->chunk) { #if !LOL_RELEASE - Log::Error("could not load %s\n", &fullpath[0]); + Log::Error("could not load sample %s\n", path); #endif SDL_Quit(); exit(1); diff --git a/src/sys/init.cpp b/src/sys/init.cpp index 56330a6f..416f689f 100644 --- a/src/sys/init.cpp +++ b/src/sys/init.cpp @@ -35,6 +35,8 @@ namespace System # define SEPARATOR '/' #endif +static Array data_dir; + void Init(int argc, char *argv[], String const &projectdir, String const &solutiondir) { @@ -77,7 +79,7 @@ void Init(int argc, char *argv[], String rootdir = projectdir; if (rootdir.Last() != SEPARATOR) rootdir += SEPARATOR; - SetDataDir(&rootdir[0]); + AddDataDir(rootdir); got_rootdir = true; } break; @@ -87,28 +89,36 @@ void Init(int argc, char *argv[], /* If no rootdir found, use the executable location */ if (!got_rootdir) { - SetDataDir(&binarydir[0]); + AddDataDir(binarydir); got_rootdir = true; } - Log::Debug("binary dir: %s\n", &binarydir[0]); - Log::Debug("root dir: %s\n", &GetDataDir()[0]); + Log::Debug("binary dir: %s\n", binarydir.C()); + for (int i = 0; i < data_dir.Count(); ++i) + Log::Debug("data dir %d/%d: %s\n", i + 1, data_dir.Count(), + data_dir[i].C()); } /* * Data directory handling */ -String data_dir = ""; - -void SetDataDir(String const &dir) +void AddDataDir(String const &dir) { - data_dir = dir; + data_dir << dir; } -String const &GetDataDir() +Array GetPathList(String const &file) { - return data_dir; + Array ret; + + for (int i = 0; i < data_dir.Count(); ++i) + ret << data_dir[0] + file; + + if (ret.Count() == 0) + ret << file; + + return ret; } } /* namespace System */