From 6a6e46cf0d3d5ec85678e75029338213bc383b40 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sun, 20 Jan 2013 23:28:22 +0000 Subject: [PATCH] system: try to autodetect the data directory from the executable path; currently works for images (SDL and GDI+ loaders) and sound samples. --- configure.ac | 8 ++-- src/Makefile.am | 3 ++ src/core.h | 2 + src/image/codec/gdiplus-image.cpp | 20 +++++----- src/image/codec/sdl-image.cpp | 30 +++++++------- src/lol/sys/init.h | 46 +++++++++++++++++++++ src/sample.cpp | 5 ++- src/sys/init.cpp | 66 +++++++++++++++++++++++++++++++ test/BtPhysTest.cpp | 4 +- tutorial/01_triangle.cpp | 4 +- tutorial/02_cube.cpp | 2 + tutorial/03_noise.cpp | 4 +- tutorial/04_texture.cpp | 4 +- tutorial/05_easymesh.cpp | 15 +++---- tutorial/08_fbo.cpp | 4 +- tutorial/11_fractal.cpp | 1 + 16 files changed, 175 insertions(+), 43 deletions(-) create mode 100644 src/lol/sys/init.h create mode 100644 src/sys/init.cpp diff --git a/configure.ac b/configure.ac index f8fe42ed..85dda77d 100644 --- a/configure.ac +++ b/configure.ac @@ -405,16 +405,18 @@ dnl Can we build neercs? AM_CONDITIONAL(BUILD_NEERCS, test "${ac_cv_my_have_caca}" != "no") -dnl Extra libraries we may need +dnl Extra libraries we may need AC_SUBST(MATH_LIBS) AC_SUBST(PAM_LIBS) AC_SUBST(UTIL_LIBS) -dnl How to use the Lol Engine inside this tree -LOL_CFLAGS="$LOL_CFLAGS -I \$(top_srcdir)/src" +dnl How to use the Lol Engine inside this tree +LOL_CFLAGS="$LOL_CFLAGS -I\$(top_srcdir)/src" +LOL_CFLAGS="$LOL_CFLAGS -DLOL_SOURCE_SUBDIR=\\\"\$(subdir)\\\"" LOL_CFLAGS="$LOL_CFLAGS $SDL_CFLAGS $GL_CFLAGS $EGL_CFLAGS $LIBPNG_CFLAGS" LOL_LIBS="$LOL_LIBS $SDL_LIBS $GL_LIBS $EGL_LIBS $LIBPNG_LIBS $D3D_LIBS" +dnl Extra flags AC_SUBST(LOL_CFLAGS) AC_SUBST(LOL_LIBS) diff --git a/src/Makefile.am b/src/Makefile.am index 10cd1845..72d463c4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,6 +22,7 @@ liblol_a_SOURCES = \ lol/math/vector.h lol/math/half.h lol/math/real.h lol/math/remez.h \ lol/math/math.h \ lol/math/geometry.h \ + lol/sys/init.h \ lol/image/color.h \ \ generated/location.hh generated/position.hh generated/stack.hh \ @@ -72,6 +73,8 @@ liblol_a_SOURCES = \ \ mesh/mesh.cpp mesh/mesh.h \ \ + sys/init.cpp \ + \ image/image.cpp image/image.h image/image-private.h \ image/codec/gdiplus-image.cpp \ image/codec/ios-image.cpp \ diff --git a/src/core.h b/src/core.h index 8f147800..0bb7bf7b 100644 --- a/src/core.h +++ b/src/core.h @@ -88,6 +88,8 @@ static inline int isnan(float f) #include #include +#include + #include #include "numeric.h" diff --git a/src/image/codec/gdiplus-image.cpp b/src/image/codec/gdiplus-image.cpp index 59013099..a47f792e 100644 --- a/src/image/codec/gdiplus-image.cpp +++ b/src/image/codec/gdiplus-image.cpp @@ -1,7 +1,7 @@ // // Lol Engine // -// Copyright: (c) 2010-2011 Sam Hocevar +// Copyright: (c) 2010-2013 Sam Hocevar // This program is free software; you can redistribute it and/or // modify it under the terms of the Do What The Fuck You Want To // Public License, Version 2, as published by Sam Hocevar. See @@ -62,13 +62,14 @@ bool GdiPlusImageData::Open(char const *path) return false; } + String fullpath = String(System::GetDataDir()) + String(path); size_t len; - len = mbstowcs(NULL, path, 0); + len = mbstowcs(NULL, &fullpath[0], 0); wchar_t *wpath = new wchar_t[len + 1]; - if (mbstowcs(wpath, path, len + 1) == (size_t)-1) + if (mbstowcs(wpath, &fullpath[0], len + 1) == (size_t)-1) { #if !LOL_RELEASE - Log::Error("invalid image name %s\n", path); + Log::Error("invalid image name %s\n", &fullpath[0]); #endif delete[] wpath; return false; @@ -76,19 +77,18 @@ bool GdiPlusImageData::Open(char const *path) bitmap = NULL; status = Gdiplus::Ok; - for (wchar_t const *wname = wpath; *wname; wname++) + bitmap = Gdiplus::Bitmap::FromFile(wpath, 0); + if (bitmap) { - bitmap = Gdiplus::Bitmap::FromFile(wname, 0); - if (bitmap) + status = bitmap->GetLastStatus(); + if (status != Gdiplus::Ok) { - status = bitmap->GetLastStatus(); - if (status == Gdiplus::Ok) - break; #if !LOL_RELEASE if (status != Gdiplus::InvalidParameter) Log::Error("error %d loading %s\n", status, path); #endif delete bitmap; + bitmap = NULL; } } diff --git a/src/image/codec/sdl-image.cpp b/src/image/codec/sdl-image.cpp index 9a3b9862..869b0f1d 100644 --- a/src/image/codec/sdl-image.cpp +++ b/src/image/codec/sdl-image.cpp @@ -1,7 +1,7 @@ // // Lol Engine // -// Copyright: (c) 2010-2011 Sam Hocevar +// Copyright: (c) 2010-2013 Sam Hocevar // This program is free software; you can redistribute it and/or // modify it under the terms of the Do What The Fuck You Want To // Public License, Version 2, as published by Sam Hocevar. See @@ -48,7 +48,7 @@ public: static SDL_Surface *Create32BppSurface(ivec2 size); private: - SDL_Surface *img; + SDL_Surface *m_img; }; /* @@ -57,43 +57,41 @@ private: bool SdlImageData::Open(char const *path) { - for (char const *name = path; *name; name++) - if ((img = IMG_Load(name))) - break; - - if (!img) + String fullpath = String(System::GetDataDir()) + String(path); + m_img = IMG_Load(&fullpath[0]); + if (!m_img) { #if !LOL_RELEASE - Log::Error("could not load %s\n", path); + Log::Error("could not load %s\n", &fullpath[0]); #endif return false; } - size = ivec2(img->w, img->h); + size = ivec2(m_img->w, m_img->h); - if (img->format->BytesPerPixel != 4) + if (m_img->format->BytesPerPixel != 4) { SDL_Surface *tmp = Create32BppSurface(size); - SDL_BlitSurface(img, NULL, tmp, NULL); - SDL_FreeSurface(img); - img = tmp; + SDL_BlitSurface(m_img, NULL, tmp, NULL); + SDL_FreeSurface(m_img); + m_img = tmp; } - format = img->format->Amask ? Image::FORMAT_RGBA : Image::FORMAT_RGB; + format = m_img->format->Amask ? Image::FORMAT_RGBA : Image::FORMAT_RGB; return true; } bool SdlImageData::Close() { - SDL_FreeSurface(img); + SDL_FreeSurface(m_img); return true; } void * SdlImageData::GetData() const { - return img->pixels; + return m_img->pixels; } SDL_Surface *SdlImageData::Create32BppSurface(ivec2 size) diff --git a/src/lol/sys/init.h b/src/lol/sys/init.h new file mode 100644 index 00000000..77846326 --- /dev/null +++ b/src/lol/sys/init.h @@ -0,0 +1,46 @@ +// +// Lol Engine +// +// Copyright: (c) 2010-2013 Sam Hocevar +// This program is free software; you can redistribute it and/or +// modify it under the terms of the Do What The Fuck You Want To +// Public License, Version 2, as published by Sam Hocevar. See +// http://www.wtfpl.net/ for more details. +// + +// +// Various system helper functions +// ------------------------------- +// + +#if !defined __LOL_SYS_INIT_H__ +#define __LOL_SYS_INIT_H__ + +#include + +namespace lol +{ + +namespace System +{ + +extern void Init(Array &args); +extern void SetDataDir(char const *dir); +extern char const *GetDataDir(); + +static inline void Init(int argc, char *argv[]) +{ + Array args; + + for (int i = 0; i < argc; i++) + args << argv[i]; + + Init(args); +} + +} /* namespace System */ + +} /* namespace lol */ + +#endif // __LOL_SYS_INIT_H__ + diff --git a/src/sample.cpp b/src/sample.cpp index d5be2a37..a322854d 100644 --- a/src/sample.cpp +++ b/src/sample.cpp @@ -63,11 +63,12 @@ Sample::Sample(char const *path) sprintf(data->name, " %s", path); #if defined USE_SDL_MIXER - data->chunk = Mix_LoadWAV(path); + String fullpath = String(System::GetDataDir()) + String(path); + data->chunk = Mix_LoadWAV(&fullpath[0]); if (!data->chunk) { #if !LOL_RELEASE - Log::Error("could not load %s\n", path); + Log::Error("could not load %s\n", &fullpath[0]); #endif SDL_Quit(); exit(1); diff --git a/src/sys/init.cpp b/src/sys/init.cpp new file mode 100644 index 00000000..d74a4eed --- /dev/null +++ b/src/sys/init.cpp @@ -0,0 +1,66 @@ +// +// Lol Engine +// +// Copyright: (c) 2010-2013 Sam Hocevar +// This program is free software; you can redistribute it and/or +// modify it under the terms of the Do What The Fuck You Want To +// Public License, Version 2, as published by Sam Hocevar. See +// http://www.wtfpl.net/ for more details. +// + +#if defined HAVE_CONFIG_H +# include "config.h" +#endif + +#include "core.h" + +namespace lol +{ + +namespace System +{ + +void Init(Array &args) +{ + /* Try to guess the data directory from the executable location. */ + if (args.Count() > 0) + { +#if defined _WIN32 +# define SEPARATOR '\\' +#else +# define SEPARATOR '/' +#endif + char const *last_slash = strrchr(args[0], SEPARATOR); + + if (last_slash) + { + String dir; + dir.Resize(last_slash - args[0] + 1); + memcpy(&dir[0], args[0], last_slash - args[0] + 1); + + SetDataDir(&dir[0]); + } + } +} + +/* + * Data directory handling + */ + +String data_dir = ""; + +void SetDataDir(char const *dir) +{ + data_dir = dir; +} + +char const *GetDataDir() +{ + return &data_dir[0]; +} + + +} /* namespace System */ + +} /* namespace lol */ + diff --git a/test/BtPhysTest.cpp b/test/BtPhysTest.cpp index 01d37f78..f5f2a471 100644 --- a/test/BtPhysTest.cpp +++ b/test/BtPhysTest.cpp @@ -2,7 +2,7 @@ // BtPhysTest // // Copyright: (c) 2009-2013 Benjamin "Touky" Huet -// (c) 2012 Sam Hocevar +// (c) 2012-2013 Sam Hocevar // #if defined HAVE_CONFIG_H @@ -475,6 +475,8 @@ BtPhysTest::~BtPhysTest() int main(int argc, char **argv) { + System::Init(argc, argv); + Application app("BtPhysTest", ivec2(1280, 720), 60.0f); #if defined _MSC_VER && !defined _XBOX diff --git a/tutorial/01_triangle.cpp b/tutorial/01_triangle.cpp index 4a7cfb1f..d2311bb3 100644 --- a/tutorial/01_triangle.cpp +++ b/tutorial/01_triangle.cpp @@ -1,7 +1,7 @@ // // Lol Engine - Triangle tutorial // -// Copyright: (c) 2012 Sam Hocevar +// Copyright: (c) 2012-2013 Sam Hocevar // This program is free software; you can redistribute it and/or // modify it under the terms of the Do What The Fuck You Want To // Public License, Version 2, as published by Sam Hocevar. See @@ -74,6 +74,8 @@ private: int main(int argc, char **argv) { + System::Init(argc, argv); + Application app("Tutorial 1: Triangle", ivec2(640, 480), 60.0f); #if defined _MSC_VER && !defined _XBOX diff --git a/tutorial/02_cube.cpp b/tutorial/02_cube.cpp index 3276a72c..4adaa56b 100644 --- a/tutorial/02_cube.cpp +++ b/tutorial/02_cube.cpp @@ -135,6 +135,8 @@ private: int main(int argc, char **argv) { + System::Init(argc, argv); + Application app("Tutorial 2: Cube", ivec2(640, 480), 60.0f); #if defined _MSC_VER && !defined _XBOX diff --git a/tutorial/03_noise.cpp b/tutorial/03_noise.cpp index 565397ba..06986d03 100644 --- a/tutorial/03_noise.cpp +++ b/tutorial/03_noise.cpp @@ -1,7 +1,7 @@ // // Lol Engine - Noise tutorial // -// Copyright: (c) 2012 Sam Hocevar +// Copyright: (c) 2012-2013 Sam Hocevar // This program is free software; you can redistribute it and/or // modify it under the terms of the Do What The Fuck You Want To // Public License, Version 2, as published by Sam Hocevar. See @@ -85,6 +85,8 @@ private: int main(int argc, char **argv) { + System::Init(argc, argv); + Application app("Tutorial 3: Noise", ivec2(1280, 720), 60.0f); #if defined _MSC_VER && !defined _XBOX diff --git a/tutorial/04_texture.cpp b/tutorial/04_texture.cpp index a9c98f4e..d9501a26 100644 --- a/tutorial/04_texture.cpp +++ b/tutorial/04_texture.cpp @@ -1,7 +1,7 @@ // // Lol Engine - Graphing tutorial // -// Copyright: (c) 2012 Sam Hocevar +// Copyright: (c) 2012-2013 Sam Hocevar // This program is free software; you can redistribute it and/or // modify it under the terms of the Do What The Fuck You Want To // Public License, Version 2, as published by Sam Hocevar. See @@ -115,6 +115,8 @@ private: int main(int argc, char **argv) { + System::Init(argc, argv); + Application app("Tutorial 4: Texture", ivec2(640, 480), 60.0f); new TextureDemo(); diff --git a/tutorial/05_easymesh.cpp b/tutorial/05_easymesh.cpp index 85a04c5d..7cd42dbf 100644 --- a/tutorial/05_easymesh.cpp +++ b/tutorial/05_easymesh.cpp @@ -29,13 +29,12 @@ public: m_gears.Push(EasyMesh(), mat4(1.0f), 180.0f / 18); m_gears.Push(EasyMesh(), mat4(1.0f), 180.0f / 18); - m_gears[0].m1.Compile("[sc#00f ab 8 1 8 ty -.25]\ - [sc#f9f scb#f9f acg 12 10 5 5 20 20 5 5 0.1 0 s .1 .1 .1 ty -.1 csgu]\ - [sc#fff scb#000 acg 12 10 10 10 20 20 5 5 0.1 0 s .05 .05 .05 tx -1.5 ty .3 csgu]\ - [sc#00f ab 5 3 9 tx 2.5 csgs]\ - [[ sc#fff ab 3 1.4 2 tx -2 tz -2 \ - [sc#fff ab 2.1 .7 1.1 ty .5 tx -1.4 tz -1.4 csgs] mz] csgu] \ - "); + m_gears[0].m1.Compile("[sc#00f ab 8 1 8 ty -.25]" + "[sc#f9f scb#f9f acg 12 10 5 5 20 20 5 5 0.1 0 s .1 .1 .1 ty -.1 csgu]" + "[sc#fff scb#000 acg 12 10 10 10 20 20 5 5 0.1 0 s .05 .05 .05 tx -1.5 ty .3 csgu]" + "[sc#00f ab 5 3 9 tx 2.5 csgs]" + "[[ sc#fff ab 3 1.4 2 tx -2 tz -2 " + "[sc#fff ab 2.1 .7 1.1 ty .5 tx -1.4 tz -1.4 csgs] mz] csgu]"); //m_gears[0].m1.Compile("[sc#f9f scb#f9f acg 12 10 5 5 20 20 5 5 0.1 0 s .1 .1 .1 [sc#00f ab 3 1 2 ty .25 tx 1 csgs]]"); m_gears[1].m1.Compile("sc#ff9 scb#ff9 acg 54 10 95 95 90 90 -5 -5 0.1 0 s .1 .1 .1"); //m_gears[2].m1.Compile("sc#9ff scb#9ff acg 18 10 5 5 30 30 5 5 0.1 0 s .1 .1 .1 [sc#00f scb#00f ab 2 2 2 tx 1.5]"); @@ -121,6 +120,8 @@ private: int main(int argc, char **argv) { + System::Init(argc, argv); + Application app("Tutorial 5: EasyMesh", ivec2(960, 600), 60.0f); new EasyMeshTutorial(); app.Run(); diff --git a/tutorial/08_fbo.cpp b/tutorial/08_fbo.cpp index a3c0f159..43cf84f7 100644 --- a/tutorial/08_fbo.cpp +++ b/tutorial/08_fbo.cpp @@ -1,7 +1,7 @@ // // Lol Engine - Framebuffer Object tutorial // -// Copyright: (c) 2012 Sam Hocevar +// Copyright: (c) 2012-2013 Sam Hocevar // This program is free software; you can redistribute it and/or // modify it under the terms of the Do What The Fuck You Want To // Public License, Version 2, as published by Sam Hocevar. See @@ -138,6 +138,8 @@ private: int main(int argc, char **argv) { + System::Init(argc, argv); + Application app("Tutorial 08: Framebuffer Object", ivec2(640, 480), 60.0f); #if defined _MSC_VER && !defined _XBOX diff --git a/tutorial/11_fractal.cpp b/tutorial/11_fractal.cpp index 8968d913..53f42b29 100644 --- a/tutorial/11_fractal.cpp +++ b/tutorial/11_fractal.cpp @@ -553,6 +553,7 @@ int main(int argc, char **argv) { ivec2 window_size(640, 480); + System::Init(argc, argv); Application app("Tutorial 3: Fractal", window_size, 60.0f); #if defined _MSC_VER && !defined _XBOX