diff --git a/CMakeLists.txt b/CMakeLists.txt index f83453cbf..0d380aea0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,10 @@ endif(EXISTS ${PROJECT_SOURCE_DIR}/.git) # Macros include(OpenMWMacros) +if (ANDROID) + set(CMAKE_FIND_ROOT_PATH ${OPENMW_DEPENDENCIES_DIR} "${CMAKE_FIND_ROOT_PATH}") +endif (ANDROID) + # doxygen main page configure_file ("${OpenMW_SOURCE_DIR}/docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/docs/mainpage.hpp") @@ -232,7 +236,12 @@ if(OGRE_STATIC) list(APPEND OGRE_STATIC_PLUGINS ${Cg_LIBRARIES}) endif(Cg_FOUND) +if (ANDROID) + add_static_ogre_plugin(RenderSystem_GLES2) +else () add_static_ogre_plugin(RenderSystem_GL) +endif () + if(WIN32) add_static_ogre_plugin(RenderSystem_Direct3D9) endif(WIN32) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 14bf0ba17..9e4a8a0ac 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -1,9 +1,17 @@ # local files -set(GAME - main.cpp - engine.cpp -) -if(NOT WIN32) +if (NOT ANDROID) + set(GAME + main.cpp + engine.cpp + ) +else() + set(GAME + main.cpp + android_main.c + engine.cpp + ) +endif() +if(NOT WIN32 AND NOT ANDROID) set(GAME ${GAME} crashcatcher.cpp) endif() set(GAME_HEADER @@ -82,19 +90,33 @@ add_openmw_dir (mwbase ) # Main executable -set(BOOST_COMPONENTS system filesystem program_options thread wave) +if (ANDROID) + set(BOOST_COMPONENTS system filesystem program_options thread wave atomic) +else () + set(BOOST_COMPONENTS system filesystem program_options thread wave) +endif () + if(WIN32) set(BOOST_COMPONENTS ${BOOST_COMPONENTS} locale) endif(WIN32) find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS}) -add_executable(openmw - ${OPENMW_LIBS} ${OPENMW_LIBS_HEADER} - ${OPENMW_FILES} - ${GAME} ${GAME_HEADER} - ${APPLE_BUNDLE_RESOURCES} -) +if (NOT ANDROID) + add_executable(openmw + ${OPENMW_LIBS} ${OPENMW_LIBS_HEADER} + ${OPENMW_FILES} + ${GAME} ${GAME_HEADER} + ${APPLE_BUNDLE_RESOURCES} + ) +else () + add_library(openmw + SHARED + ${OPENMW_LIBS} ${OPENMW_LIBS_HEADER} + ${OPENMW_FILES} + ${GAME} ${GAME_HEADER} + ) +endif () # Sound stuff - here so CMake doesn't stupidly recompile EVERYTHING # when we change the backend. @@ -116,6 +138,23 @@ target_link_libraries(openmw components ) +if (ANDROID) + target_link_libraries(openmw + ${OGRE_STATIC_PLUGINS} + EGL + android + log + dl + MyGUI.OgrePlatform + MyGUIEngineStatic + Plugin_StrangeButtonStatic + cpufeatures + BulletCollision + BulletDynamics + LinearMath + ) +endif (ANDROID) + if (USE_SYSTEM_TINYXML) target_link_libraries(openmw ${TINYXML_LIBRARIES}) endif() diff --git a/apps/openmw/android_main.c b/apps/openmw/android_main.c new file mode 100644 index 000000000..76da91c4f --- /dev/null +++ b/apps/openmw/android_main.c @@ -0,0 +1,43 @@ + +#include "../../SDL_internal.h" + +#ifdef __ANDROID__ +#include "SDL_main.h" + + +/******************************************************************************* + Functions called by JNI +*******************************************************************************/ +#include + +/* Called before to initialize JNI bindings */ + + + +extern void SDL_Android_Init(JNIEnv* env, jclass cls); + + +int Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobject obj) +{ + + SDL_Android_Init(env, cls); + + SDL_SetMainReady(); + + +/* Run the application code! */ + + int status; + char *argv[2]; + argv[0] = SDL_strdup("openmw"); + argv[1] = NULL; + status = main(1, argv); + + /* Do not issue an exit or the whole application will terminate instead of just the SDL thread */ + /* exit(status); */ + + return status; +} + +#endif /* __ANDROID__ */ + diff --git a/cmake/FindOGRE.cmake b/cmake/FindOGRE.cmake index 81b52b1b7..4a7f0f3cc 100644 --- a/cmake/FindOGRE.cmake +++ b/cmake/FindOGRE.cmake @@ -127,7 +127,7 @@ endif () set(OGRE_COMPONENTS Paging Terrain Plugin_BSPSceneManager Plugin_CgProgramManager Plugin_OctreeSceneManager Plugin_OctreeZone Plugin_PCZSceneManager Plugin_ParticleFX - RenderSystem_Direct3D10 RenderSystem_Direct3D9 RenderSystem_GL RenderSystem_GLES) + RenderSystem_Direct3D10 RenderSystem_Direct3D9 RenderSystem_GL RenderSystem_GLES2) set(OGRE_RESET_VARS OGRE_CONFIG_INCLUDE_DIR OGRE_INCLUDE_DIR OGRE_LIBRARY_FWK OGRE_LIBRARY_REL OGRE_LIBRARY_DBG @@ -234,10 +234,10 @@ if (OGRE_STATIC) find_package(FreeImage QUIET) find_package(Freetype QUIET) find_package(OpenGL QUIET) - find_package(OpenGLES QUIET) + find_package(OpenGLES2 QUIET) find_package(ZLIB QUIET) find_package(ZZip QUIET) - if (UNIX AND NOT APPLE) + if (UNIX AND NOT APPLE OR NOT ANDROID) find_package(X11 QUIET) find_library(XAW_LIBRARY NAMES Xaw Xaw7 PATHS ${DEP_LIB_SEARCH_DIR} ${X11_LIB_SEARCH_PATH}) if (NOT XAW_LIBRARY OR NOT X11_Xt_FOUND) @@ -258,10 +258,16 @@ if (OGRE_STATIC) endif () endif () - set(OGRE_LIBRARIES ${OGRE_LIBRARIES} ${OGRE_LIBRARY_FWK} ${ZZip_LIBRARIES} ${ZLIB_LIBRARIES} +if (ANDROID) + set(OGRE_LIBRARIES ${OGRE_LIBRARIES} ${OGRE_LIBRARY_FWK} ${ZZip_LIBRARIES} ${ZLIB_LIBRARIES} ${FreeImage_LIBRARIES} ${FREETYPE_LIBRARIES} - ${X11_LIBRARIES} ${X11_Xt_LIBRARIES} ${XAW_LIBRARY} ${X11_Xrandr_LIB} ${Cocoa_LIBRARIES} ${Carbon_LIBRARIES}) +else () + set(OGRE_LIBRARIES ${OGRE_LIBRARIES} ${OGRE_LIBRARY_FWK} ${ZZip_LIBRARIES} ${ZLIB_LIBRARIES} + ${FreeImage_LIBRARIES} ${FREETYPE_LIBRARIES} + ${X11_LIBRARIES} ${X11_Xt_LIBRARIES} ${XAW_LIBRARY} ${X11_Xrandr_LIB} + ${Cocoa_LIBRARIES} ${Carbon_LIBRARIES}) +endif() if (NOT ZLIB_FOUND OR NOT ZZip_FOUND) set(OGRE_DEPS_FOUND FALSE) @@ -272,7 +278,7 @@ if (OGRE_STATIC) if (NOT FREETYPE_FOUND) set(OGRE_DEPS_FOUND FALSE) endif () - if (UNIX AND NOT APPLE) + if (UNIX AND NOT APPLE AND NOT ANDROID) if (NOT X11_FOUND) set(OGRE_DEPS_FOUND FALSE) endif () @@ -486,7 +492,7 @@ ogre_find_plugin(Plugin_CgProgramManager OgreCgProgram.h PlugIns/CgProgramManage ogre_find_plugin(Plugin_OctreeSceneManager OgreOctreeSceneManager.h PlugIns/OctreeSceneManager/include) ogre_find_plugin(Plugin_ParticleFX OgreParticleFXPrerequisites.h PlugIns/ParticleFX/include) ogre_find_plugin(RenderSystem_GL OgreGLRenderSystem.h RenderSystems/GL/include) -ogre_find_plugin(RenderSystem_GLES OgreGLESRenderSystem.h RenderSystems/GLES/include) +ogre_find_plugin(RenderSystem_GLES2 OgreGLES2RenderSystem.h RenderSystems/GLES2/include) ogre_find_plugin(RenderSystem_Direct3D9 OgreD3D9RenderSystem.h RenderSystems/Direct3D9/include) ogre_find_plugin(RenderSystem_Direct3D10 OgreD3D10RenderSystem.h RenderSystems/Direct3D10/include) ogre_find_plugin(RenderSystem_Direct3D11 OgreD3D11RenderSystem.h RenderSystems/Direct3D11/include) @@ -528,8 +534,8 @@ if (OGRE_STATIC) set(OGRE_RenderSystem_GL_LIBRARIES ${OGRE_RenderSystem_GL_LIBRARIES} ${OPENGL_LIBRARIES} ) - set(OGRE_RenderSystem_GLES_LIBRARIES ${OGRE_RenderSystem_GLES_LIBRARIES} - ${OPENGLES_LIBRARIES} + set(OGRE_RenderSystem_GLES2_LIBRARIES ${OGRE_RenderSystem_GLES2_LIBRARIES} + ${OPENGLES2_LIBRARIES} ) set(OGRE_Plugin_CgProgramManager_LIBRARIES ${OGRE_Plugin_CgProgramManager_LIBRARIES} ${Cg_LIBRARIES} diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index efe432227..f343ca8ed 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -50,7 +50,7 @@ add_component_dir (misc ) add_component_dir (files - linuxpath windowspath macospath fixedpath multidircollection collections configurationmanager + linuxpath androidpath windowspath macospath fixedpath multidircollection collections configurationmanager constrainedfiledatastream lowlevelfile ) diff --git a/components/files/androidpath.cpp b/components/files/androidpath.cpp new file mode 100644 index 000000000..52ae73803 --- /dev/null +++ b/components/files/androidpath.cpp @@ -0,0 +1,94 @@ +#include "androidpath.hpp" + +#if defined(__ANDROID__) + +#include +#include +#include +#include +#include + +namespace +{ + boost::filesystem::path getUserHome() + { + const char* dir = getenv("HOME"); + if (dir == NULL) + { + struct passwd* pwd = getpwuid(getuid()); + if (pwd != NULL) + { + dir = pwd->pw_dir; + } + } + if (dir == NULL) + return boost::filesystem::path(); + else + return boost::filesystem::path(dir); + } + + boost::filesystem::path getEnv(const std::string& envVariable, const boost::filesystem::path& fallback) + { + const char* result = getenv(envVariable.c_str()); + if (!result) + return fallback; + boost::filesystem::path dir(result); + if (dir.empty()) + return fallback; + else + return dir; + } +} + +/** + * \namespace Files + */ +namespace Files +{ + +AndroidPath::AndroidPath(const std::string& application_name) + : mName(application_name) +{ +} + +boost::filesystem::path AndroidPath::getUserConfigPath() const +{ + return getEnv("XDG_CONFIG_HOME", "/sdcard/morrowind/config") / mName; +} + +boost::filesystem::path AndroidPath::getUserDataPath() const +{ + return getEnv("XDG_DATA_HOME", "/sdcard/morrowind/share") / mName; +} + +boost::filesystem::path AndroidPath::getCachePath() const +{ + return getEnv("XDG_CACHE_HOME", "/sdcard/morrowind/cache") / mName; +} + +boost::filesystem::path AndroidPath::getGlobalConfigPath() const +{ + boost::filesystem::path globalPath("/sdcard/morrowind/"); + return globalPath / mName; +} + +boost::filesystem::path AndroidPath::getLocalPath() const +{ + return boost::filesystem::path("./"); +} + +boost::filesystem::path AndroidPath::getGlobalDataPath() const +{ + boost::filesystem::path globalDataPath("/sdcard/morrowind/data"); + return globalDataPath / mName; +} + +boost::filesystem::path AndroidPath::getInstallPath() const +{ + return boost::filesystem::path(); +} + + +} /* namespace Files */ + +#endif /* defined(__Android__) */ diff --git a/components/files/androidpath.hpp b/components/files/androidpath.hpp new file mode 100644 index 000000000..792462fc6 --- /dev/null +++ b/components/files/androidpath.hpp @@ -0,0 +1,54 @@ +#ifndef COMPONENTS_FILES_ANDROIDPATH_H +#define COMPONENTS_FILES_ANDROIDPATH_H + +#if defined(__ANDROID__) + +#include +/** + * \namespace Files + */ +namespace Files +{ + +struct AndroidPath +{ + AndroidPath(const std::string& application_name); + + /** + * \brief Return path to the user directory. + */ + boost::filesystem::path getUserConfigPath() const; + + boost::filesystem::path getUserDataPath() const; + + /** + * \brief Return path to the global (system) directory where config files can be placed. + */ + boost::filesystem::path getGlobalConfigPath() const; + + /** + * \brief Return path to the runtime configuration directory which is the + * place where an application was started. + */ + boost::filesystem::path getLocalPath() const; + + /** + * \brief Return path to the global (system) directory where game files can be placed. + */ + boost::filesystem::path getGlobalDataPath() const; + + /** + * \brief + */ + boost::filesystem::path getCachePath() const; + + boost::filesystem::path getInstallPath() const; + + std::string mName; +}; + +} /* namespace Files */ + +#endif /* defined(__Android__) */ + +#endif /* COMPONENTS_FILES_ANDROIDPATH_H */ diff --git a/components/files/fixedpath.hpp b/components/files/fixedpath.hpp index cfd3458ce..86571442a 100644 --- a/components/files/fixedpath.hpp +++ b/components/files/fixedpath.hpp @@ -4,10 +4,14 @@ #include #include -#if defined(__linux__) || defined(__FreeBSD__) +#if defined(__linux__) || defined(__FreeBSD__) +#ifndef ANDROID #include namespace Files { typedef LinuxPath TargetPathType; } - +#else + #include + namespace Files { typedef AndroidPath TargetPathType; } +#endif #elif defined(__WIN32) || defined(__WINDOWS__) || defined(_WIN32) #include namespace Files { typedef WindowsPath TargetPathType; } @@ -87,6 +91,7 @@ struct FixedPath return mLocalPath; } + const boost::filesystem::path& getInstallPath() const { return mInstallPath; diff --git a/components/ogreinit/ogreinit.cpp b/components/ogreinit/ogreinit.cpp index 515c0875a..cd3723354 100644 --- a/components/ogreinit/ogreinit.cpp +++ b/components/ogreinit/ogreinit.cpp @@ -22,6 +22,7 @@ #include "ogreplugin.hpp" + namespace bfs = boost::filesystem; namespace @@ -82,28 +83,34 @@ namespace OgreInit #ifdef ENABLE_PLUGIN_GL , mGLPlugin(NULL) #endif - #ifdef ENABLE_PLUGIN_Direct3D9 + #ifdef ENABLE_PLUGIN_GLES2 + , mGLES2Plugin(NULL) + #endif + + #ifdef ENABLE_PLUGIN_Direct3D9 , mD3D9Plugin(NULL) #endif {} Ogre::Root* OgreInit::init(const std::string &logPath) { + + #ifndef ANDROID // Set up logging first new Ogre::LogManager; Ogre::Log *log = Ogre::LogManager::getSingleton().createLog(logPath); - #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 + #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 // Use custom listener only on Windows log->addListener(new LogListener(logPath)); - #endif + #endif // Disable logging to cout/cerr log->setDebugOutputEnabled(false); - + #endif mRoot = new Ogre::Root("", "", ""); - #if defined(ENABLE_PLUGIN_GL) || defined(ENABLE_PLUGIN_Direct3D9) || defined(ENABLE_PLUGIN_CgProgramManager) || defined(ENABLE_PLUGIN_OctreeSceneManager) || defined(ENABLE_PLUGIN_ParticleFX) + #if defined(ENABLE_PLUGIN_GL) || (ENABLE_PLUGIN_GLES2) || defined(ENABLE_PLUGIN_Direct3D9) || defined(ENABLE_PLUGIN_CgProgramManager) || defined(ENABLE_PLUGIN_OctreeSceneManager) || defined(ENABLE_PLUGIN_ParticleFX) loadStaticPlugins(); #else loadPlugins(); @@ -133,6 +140,10 @@ namespace OgreInit delete mGLPlugin; mGLPlugin = NULL; #endif + #ifdef ENABLE_PLUGIN_GLES2 + delete mGLES2Plugin; + mGLES2Plugin = NULL; + #endif #ifdef ENABLE_PLUGIN_Direct3D9 delete mD3D9Plugin; mD3D9Plugin = NULL; @@ -157,6 +168,10 @@ namespace OgreInit mGLPlugin = new Ogre::GLPlugin(); mRoot->installPlugin(mGLPlugin); #endif + #ifdef ENABLE_PLUGIN_GLES2 + mGLES2Plugin = new Ogre::GLES2Plugin(); + mRoot->installPlugin(mGLES2Plugin); + #endif #ifdef ENABLE_PLUGIN_Direct3D9 mD3D9Plugin = new Ogre::D3D9Plugin(); mRoot->installPlugin(mD3D9Plugin); diff --git a/components/ogreinit/ogreinit.hpp b/components/ogreinit/ogreinit.hpp index b6fe4631a..9613421f7 100644 --- a/components/ogreinit/ogreinit.hpp +++ b/components/ogreinit/ogreinit.hpp @@ -17,6 +17,10 @@ #ifdef ENABLE_PLUGIN_GL # include "OgreGLPlugin.h" #endif +#ifdef ENABLE_PLUGIN_GLES2 +# include "OgreGLES2Plugin.h" +#endif + #ifdef ENABLE_PLUGIN_Direct3D9 # include "OgreD3D9Plugin.h" #endif @@ -52,7 +56,6 @@ namespace OgreInit void loadPlugins(); void loadParticleFactories(); - #ifdef ENABLE_PLUGIN_CgProgramManager Ogre::CgPlugin* mCgPlugin; #endif @@ -65,6 +68,9 @@ namespace OgreInit #ifdef ENABLE_PLUGIN_GL Ogre::GLPlugin* mGLPlugin; #endif + #ifdef ENABLE_PLUGIN_GLES2 + Ogre::GLES2Plugin* mGLES2Plugin; + #endif #ifdef ENABLE_PLUGIN_Direct3D9 Ogre::D3D9Plugin* mD3D9Plugin; #endif diff --git a/extern/sdl4ogre/sdlwindowhelper.cpp b/extern/sdl4ogre/sdlwindowhelper.cpp index 3ea39cff7..f30362d78 100644 --- a/extern/sdl4ogre/sdlwindowhelper.cpp +++ b/extern/sdl4ogre/sdlwindowhelper.cpp @@ -26,6 +26,7 @@ SDLWindowHelper::SDLWindowHelper (SDL_Window* window, int w, int h, throw std::runtime_error("Couldn't get WM Info!"); Ogre::String winHandle; + Ogre::String winHandleSurface; switch (wmInfo.subsystem) { @@ -39,10 +40,15 @@ SDLWindowHelper::SDLWindowHelper (SDL_Window* window, int w, int h, //required to make OGRE play nice with our window params.insert(std::make_pair("macAPI", "cocoa")); params.insert(std::make_pair("macAPICocoaUseNSView", "true")); - winHandle = Ogre::StringConverter::toString(WindowContentViewHandle(wmInfo)); break; -#else +#elif ANDROID + case SDL_SYSWM_ANDROID: + winHandle = Ogre::StringConverter::toString((unsigned long)wmInfo.info.android.window); + winHandleSurface = Ogre::StringConverter::toString((unsigned long)wmInfo.info.android.surface); + + break; + #else case SDL_SYSWM_X11: winHandle = Ogre::StringConverter::toString((unsigned long)wmInfo.info.x11.window); break; @@ -54,7 +60,11 @@ SDLWindowHelper::SDLWindowHelper (SDL_Window* window, int w, int h, /// \todo externalWindowHandle is deprecated according to the source code. Figure out a way to get parentWindowHandle /// to work properly. On Linux/X11 it causes an occasional GLXBadDrawable error. - params.insert(std::make_pair("externalWindowHandle", winHandle)); + +#ifdef ANDROID + params.insert(std::make_pair("externalSurface", winHandleSurface)); +#endif + params.insert(std::make_pair("externalWindowHandle", winHandle)); mWindow = Ogre::Root::getSingleton().createRenderWindow(title, w, h, fullscreen, ¶ms); } diff --git a/libs/openengine/gui/manager.cpp b/libs/openengine/gui/manager.cpp index 028192e9f..ca4067ca1 100644 --- a/libs/openengine/gui/manager.cpp +++ b/libs/openengine/gui/manager.cpp @@ -653,7 +653,9 @@ void MyGUIManager::updateWindow (Ogre::RenderWindow *wnd) void MyGUIManager::windowResized() { +#ifndef ANDROID mRenderManager->setActiveViewport(0); +#endif } void MyGUIManager::shutdown()