@@ -40,8 +40,8 @@ public: | |||||
virtual void *GetData() const; | virtual void *GetData() const; | ||||
private: | 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; | 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<String> 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 | #if !LOL_RELEASE | ||||
Log::Error("invalid image name %s\n", &fullpath[0]); | |||||
Log::Error("invalid image name %s\n", pathlist[i].C()); | |||||
#endif | #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 !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 | #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 | #if !LOL_RELEASE | ||||
Log::Error("could not load %s\n", path); | Log::Error("could not load %s\n", path); | ||||
@@ -102,24 +109,24 @@ bool GdiPlusImageData::Open(char const *path) | |||||
return false; | return false; | ||||
} | } | ||||
size = ivec2(bitmap->GetWidth(), bitmap->GetHeight()); | |||||
size = ivec2(m_bitmap->GetWidth(), m_bitmap->GetHeight()); | |||||
format = Image::FORMAT_RGBA; | format = Image::FORMAT_RGBA; | ||||
Gdiplus::Rect rect(0, 0, size.x, size.y); | 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 | #if !LOL_RELEASE | ||||
Log::Error("could not lock bits in %s\n", path); | Log::Error("could not lock bits in %s\n", path); | ||||
#endif | #endif | ||||
delete bitmap; | |||||
delete m_bitmap; | |||||
return false; | return false; | ||||
} | } | ||||
/* FIXME: GDI+ doesn't know about RGBA, only ARGB. And OpenGL doesn't | /* 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 | * know about ARGB, only RGBA. So we swap bytes. We could also fix | ||||
* this in the shader. */ | * this in the shader. */ | ||||
uint8_t *p = static_cast<uint8_t *>(bdata.Scan0); | |||||
uint8_t *p = static_cast<uint8_t *>(m_bdata.Scan0); | |||||
for (int y = 0; y < size.y; y++) | for (int y = 0; y < size.y; y++) | ||||
for (int x = 0; x < size.x; x++) | for (int x = 0; x < size.x; x++) | ||||
{ | { | ||||
@@ -134,15 +141,15 @@ bool GdiPlusImageData::Open(char const *path) | |||||
bool GdiPlusImageData::Close() | bool GdiPlusImageData::Close() | ||||
{ | { | ||||
bitmap->UnlockBits(&bdata); | |||||
delete bitmap; | |||||
m_bitmap->UnlockBits(&m_bdata); | |||||
delete m_bitmap; | |||||
return true; | return true; | ||||
} | } | ||||
void * GdiPlusImageData::GetData() const | void * GdiPlusImageData::GetData() const | ||||
{ | { | ||||
return bdata.Scan0; | |||||
return m_bdata.Scan0; | |||||
} | } | ||||
} /* namespace lol */ | } /* namespace lol */ | ||||
@@ -57,12 +57,18 @@ private: | |||||
bool SdlImageData::Open(char const *path) | bool SdlImageData::Open(char const *path) | ||||
{ | { | ||||
String fullpath = String(System::GetDataDir()) + String(path); | |||||
m_img = IMG_Load(&fullpath[0]); | |||||
Array<String> 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 (!m_img) | ||||
{ | { | ||||
#if !LOL_RELEASE | #if !LOL_RELEASE | ||||
Log::Error("could not load %s\n", &fullpath[0]); | |||||
Log::Error("could not load image %s\n", path); | |||||
#endif | #endif | ||||
return false; | return false; | ||||
} | } | ||||
@@ -46,8 +46,8 @@ extern void Init(int argc, char *argv[], | |||||
String const &projectdir = LOL_CONFIG_PROJECTDIR, | String const &projectdir = LOL_CONFIG_PROJECTDIR, | ||||
String const &solutiondir = LOL_CONFIG_SOLUTIONDIR); | String const &solutiondir = LOL_CONFIG_SOLUTIONDIR); | ||||
extern void SetDataDir(String const &dir); | |||||
extern String const &GetDataDir(); | |||||
extern void AddDataDir(String const &dir); | |||||
extern Array<String> GetPathList(String const &file); | |||||
} /* namespace System */ | } /* namespace System */ | ||||
@@ -63,12 +63,17 @@ Sample::Sample(char const *path) | |||||
sprintf(data->name, "<sample> %s", path); | sprintf(data->name, "<sample> %s", path); | ||||
#if defined USE_SDL_MIXER | #if defined USE_SDL_MIXER | ||||
String fullpath = String(System::GetDataDir()) + String(path); | |||||
data->chunk = Mix_LoadWAV(&fullpath[0]); | |||||
Array<String> 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 (!data->chunk) | ||||
{ | { | ||||
#if !LOL_RELEASE | #if !LOL_RELEASE | ||||
Log::Error("could not load %s\n", &fullpath[0]); | |||||
Log::Error("could not load sample %s\n", path); | |||||
#endif | #endif | ||||
SDL_Quit(); | SDL_Quit(); | ||||
exit(1); | exit(1); | ||||
@@ -35,6 +35,8 @@ namespace System | |||||
# define SEPARATOR '/' | # define SEPARATOR '/' | ||||
#endif | #endif | ||||
static Array<String> data_dir; | |||||
void Init(int argc, char *argv[], | void Init(int argc, char *argv[], | ||||
String const &projectdir, String const &solutiondir) | String const &projectdir, String const &solutiondir) | ||||
{ | { | ||||
@@ -77,7 +79,7 @@ void Init(int argc, char *argv[], | |||||
String rootdir = projectdir; | String rootdir = projectdir; | ||||
if (rootdir.Last() != SEPARATOR) | if (rootdir.Last() != SEPARATOR) | ||||
rootdir += SEPARATOR; | rootdir += SEPARATOR; | ||||
SetDataDir(&rootdir[0]); | |||||
AddDataDir(rootdir); | |||||
got_rootdir = true; | got_rootdir = true; | ||||
} | } | ||||
break; | break; | ||||
@@ -87,28 +89,36 @@ void Init(int argc, char *argv[], | |||||
/* If no rootdir found, use the executable location */ | /* If no rootdir found, use the executable location */ | ||||
if (!got_rootdir) | if (!got_rootdir) | ||||
{ | { | ||||
SetDataDir(&binarydir[0]); | |||||
AddDataDir(binarydir); | |||||
got_rootdir = true; | 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 | * 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<String> GetPathList(String const &file) | |||||
{ | { | ||||
return data_dir; | |||||
Array<String> 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 */ | } /* namespace System */ | ||||