Merge branch 'master' of https://github.com/Tulioh/otclient into mobile_port

This commit is contained in:
BenDol 2015-04-24 15:16:28 +12:00
commit 789f86a778
41 changed files with 3697 additions and 73 deletions

7
.gitignore vendored
View File

@ -4,6 +4,13 @@ CMakeFiles
cmake_install.cmake
Makefile
/otclient
/android/project/build.xml
/android/project/proguard-project.txt
/android/project/gen
/android/project/bin
/android/project/libs
libs*
.idea*
/*.h
/*.cxx
*.o

View File

@ -19,10 +19,6 @@ endif()
option(USE_PCH "Use precompiled header (speed up compile)" OFF)
set(executable_SOURCES
src/main.cpp
)
# add executable icon for win32 platforms
if(WIN32)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/otcicon.o
@ -35,8 +31,22 @@ endif()
add_definitions(-D"VERSION=\\"${VERSION}\\"")
# add client executable
add_executable(${PROJECT_NAME} ${framework_SOURCES} ${client_SOURCES} ${executable_SOURCES})
set(executable_SOURCES
src/main.cpp
)
if(ANDROID)
set( sdl_main
android/SDL_android_main.c
${executable_SOURCES} )
# add shared library for android
add_library(${PROJECT_NAME} SHARED ${framework_SOURCES} ${client_SOURCES} ${sdl_main})
else()
# add client executable
add_executable(${PROJECT_NAME} ${framework_SOURCES} ${client_SOURCES} ${executable_SOURCES})
endif()
target_link_libraries(${PROJECT_NAME} ${framework_LIBRARIES})
if(USE_PCH)

View File

@ -8,6 +8,15 @@ that each functionality is a separated module, giving the possibility to users m
anything easily. Users can also create new mods and extend game interface for their own purposes.
Otclient is written in C++2011, the upcoming C++ standard and heavily scripted in lua.
## The Mobile Project
This is a fork of edubart's otclient. The objective of this fork it's to develop a runnable otclient on mobiles devices.
Tasks that need to do:
- [X] Compile on Android devices
- [ ] Compile on Apple devices
- [ ] Handle input events correctle
- [ ] Adapt the UI reusing the existing lua code
### Where do I download?
The latest commits compiled for Windows can be found here.

View File

@ -0,0 +1,40 @@
/*
SDL_android_main.c, placed in the public domain by Sam Lantinga 3/13/14
*/
#include "SDL_internal.h"
#ifdef __ANDROID__
/* Include the SDL main definition header */
#include "SDL_main.h"
/*******************************************************************************
Functions called by JNI
*******************************************************************************/
#include <jni.h>
/* Called before SDL_main() to initialize JNI bindings in SDL library */
extern void SDL_Android_Init(JNIEnv* env, jclass cls);
/* Start up the SDL app */
void Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobject obj)
{
/* This interface could expand with ABI negotiation, calbacks, etc. */
SDL_Android_Init(env, cls);
SDL_SetMainReady();
/* Run the application code! */
int status;
char *argv[2];
argv[0] = SDL_strdup("SDL_app");
argv[1] = NULL;
status = SDL_main(1, argv);
/* Do not issue an exit or the whole application will terminate instead of just the SDL thread */
/* exit(status); */
}
#endif /* __ANDROID__ */
/* vi: set ts=4 sw=4 expandtab: */

File diff suppressed because it is too large Load Diff

19
android/compile_android.sh Executable file
View File

@ -0,0 +1,19 @@
#!/bin/sh
mkdir -p ../build && cd ../build
cmake -DCMAKE_TOOLCHAIN_FILE=../android/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DANDROID_NATIVE_API_LEVEL=android-16 -DANDROID_TOOLCHAIN_NAME=arm-linux-androideabi-4.6 ..
make
cd ../
cp -r libs android/project/
cd android/project
android update project -p . --name OTClientMob --target android-16
ant debug
cd bin
adb install -r OTClientMob-debug.apk

35
android/main.cpp Normal file
View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2010-2014 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <android_native_app_glue.h>
#include <client/client.h>
void android_main( struct android_app* state ) {
int argc = 1;
const char* argv[1];
argv[0] = "NULL";
Client client( argc, argv );
client.terminateAndFreeMemory();
ANativeActivity_finish(state->activity);
}

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

33
android/project/.project Normal file
View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>NativeActivity</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,4 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.source=1.6

View File

@ -0,0 +1,35 @@
<?xml version="1.0"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.libsdl.app" android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="16"/>
<application android:label="@string/app_name"
android:icon="@drawable/ic_launcher"
android:hardwareAccelerated="true" >
<activity android:name="SDLActivity"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:configChanges="orientation|keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<meta-data android:name="android.app.lib_name" android:value="otclient"/>
</activity>
</application>
<!-- Android 2.3.3 -->
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="12"/>
<!-- OpenGL ES 2.0 -->
<uses-feature android:glEsVersion="0x00020000"/>
<!-- Allow writing to external storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- Allow make internet connections -->
<uses-permission android:name="android.permission.INTERNET" />
</manifest>

View File

@ -0,0 +1,10 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
# location of the SDK. This is only used by Ant
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=/opt/android-sdk/sdk

View File

@ -0,0 +1,20 @@
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

View File

@ -0,0 +1,14 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-16

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

File diff suppressed because it is too large Load Diff

View File

@ -21,29 +21,38 @@
*/
#include "client.h"
#include <framework/core/modulemanager.h>
#include <framework/core/resourcemanager.h>
#include <framework/graphics/graphics.h>
#include "game.h"
#include "map.h"
#include "shadermanager.h"
#include "spritemanager.h"
#include "minimap.h"
#include <framework/luaengine/luainterface.h>
#include <framework/core/application.h>
#include <framework/core/modulemanager.h>
#include <framework/core/resourcemanager.h>
#include <framework/core/configmanager.h>
#include <framework/graphics/graphics.h>
Client g_client;
Client::Client(int argc, char* argv[]) {
std::vector<std::string> args(argv, argv + argc);
initAppFrameworkAndOTClient(args);
}
void Client::init(std::vector<std::string>& args)
void Client::initAppFrameworkAndOTClient(std::vector<std::string>& args)
{
// register needed lua functions
registerLuaFunctions();
setupAppNameAndVersion();
g_app.init(args);
g_map.init();
g_minimap.init();
g_game.init();
g_shaders.init();
g_things.init();
registerLuaFunctions();
findLuaInitScript();
g_app.runAppMainLoop();
//TODO: restore options
/*
if(g_graphics.parseOption(arg))
@ -81,8 +90,28 @@ void Client::init(std::vector<std::string>& args)
*/
}
void Client::terminate()
void Client::setupAppNameAndVersion() {
g_app.setName("OTClient");
g_app.setCompactName("otclient");
g_app.setVersion(VERSION);
}
void Client::findLuaInitScript() {
if(!g_resources.discoverWorkDir("init.lua"))
g_logger.fatal("Unable to find work directory, the application cannot be initialized.");
runLuaInitScript();
}
void Client::runLuaInitScript() {
if(!g_lua.safeRunScript("init.lua"))
g_logger.fatal("Unable to run script init.lua!");
}
void Client::terminateAndFreeMemory()
{
g_app.unloadModules();
g_creatures.terminate();
g_game.terminate();
g_map.terminate();
@ -90,4 +119,5 @@ void Client::terminate()
g_things.terminate();
g_sprites.terminate();
g_shaders.terminate();
g_app.terminate();
}

View File

@ -27,12 +27,14 @@
class Client
{
public:
void init(std::vector<std::string>& args);
void terminate();
void initAppFrameworkAndOTClient(std::vector<std::string>& args);
void setupAppNameAndVersion();
void findLuaInitScript();
void runLuaInitScript();
void registerLuaFunctions();
public:
Client(int argc, char* argv[]);
void terminateAndFreeMemory();
};
extern Client g_client;
#endif

View File

@ -140,7 +140,11 @@ set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/luafunctions.cpp
# some build options
option(LUAJIT "Use lua jit" OFF)
if(NOT APPLE)
option(CRASH_HANDLER "Generate crash reports" ON)
if(ANDROID)
set(CRASH_HANDLER OFF)
else()
option(CRASH_HANDLER "Generate crash reports" ON)
endif()
option(USE_STATIC_LIBS "Don't use shared libraries (dlls)" ON)
option(USE_LIBCPP "Use the new libc++ library instead of stdc++" OFF)
option(USE_LTO "Use link time optimizations" OFF)
@ -226,6 +230,11 @@ find_package(PhysFS REQUIRED)
find_package(OpenSSL REQUIRED)
find_package(ZLIB REQUIRED)
if(ANDROID)
set(framework_LIBRARIES ${framework_LIBRARIES} android log)
find_package(SDL2 REQUIRED)
endif()
set(framework_LIBRARIES ${framework_LIBRARIES}
${Boost_LIBRARIES}
${LUA_LIBRARY}
@ -242,6 +251,11 @@ set(framework_INCLUDE_DIRS ${framework_INCLUDE_DIRS}
${framework_INCLUDE_DIRS}
)
if(ANDROID)
set(framework_LIBRARIES ${framework_LIBRARIES} ${SDL2_LIBRARY})
set(framework_INCLUDE_DIRS ${framework_INCLUDE_DIRS} ${SDL2_INCLUDE_DIR})
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
message(STATUS "Debug information: ON")
else()
@ -281,7 +295,11 @@ else()
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -rdynamic -Wl,-rpath,./libs") # rdynamic is needed by backtrace.h used in crash handler
set(SYSTEM_LIBRARIES dl rt)
if(ANDROID)
set(SYSTEM_LIBRARIES dl)
else()
set(SYSTEM_LIBRARIES dl rt)
endif()
endif()
endif()
set(framework_LIBRARIES ${framework_LIBRARIES} ${SYSTEM_LIBRARIES})
@ -292,13 +310,13 @@ endif()
if(FRAMEWORK_GRAPHICS)
set(OPENGLES "OFF" CACHE "Use OpenGL ES 1.0 or 2.0 (for mobiles devices)" STRING)
if(OPENGLES STREQUAL "2.0")
if(OPENGLES STREQUAL "2.0" OR (ANDROID_NATIVE_API_LEVEL AND ANDROID_NATIVE_API_LEVEL VERSION_GREATER 7))
find_package(OpenGLES2 REQUIRED)
find_package(EGL REQUIRED)
set(framework_DEFINITIONS ${framework_DEFINITIONS} -DOPENGL_ES=2)
set(framework_INCLUDE_DIRS ${framework_INCLUDE_DIRS} ${EGL_INCLUDE_DIR} ${OPENGLES2_INCLUDE_DIR})
set(framework_LIBRARIES ${framework_LIBRARIES} ${EGL_LIBRARY} ${OPENGLES2_LIBRARY})
ELSEif(OPENGLES STREQUAL "1.0")
ELSEif(OPENGLES STREQUAL "1.0" OR (ANDROID_NATIVE_API_LEVEL AND ANDROID_NATIVE_API_LEVEL VERSION_LESS 8))
find_package(OpenGLES1 REQUIRED)
find_package(EGL REQUIRED)
set(framework_DEFINITIONS ${framework_DEFINITIONS} -DOPENGL_ES=1)
@ -341,7 +359,7 @@ if(FRAMEWORK_GRAPHICS)
)
endif()
else()
elseif(NOT ANDROID)
set(framework_LIBRARIES ${framework_LIBRARIES} X11)
endif()
@ -441,6 +459,8 @@ if(FRAMEWORK_GRAPHICS)
${CMAKE_CURRENT_LIST_DIR}/platform/win32window.h
${CMAKE_CURRENT_LIST_DIR}/platform/x11window.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/x11window.h
${CMAKE_CURRENT_LIST_DIR}/platform/sdlwindow.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/sdlwindow.h
# window input
${CMAKE_CURRENT_LIST_DIR}/input/mouse.cpp

View File

@ -0,0 +1,12 @@
# Try to find the SDL2 library
# SDL2_FOUND - system has SDL2
# SDL2_INCLUDE_DIR - the SDL2 include directory
# SDL2_LIBRARY - the SDL2 library
FIND_PATH(SDL2_INCLUDE_DIR NAMES SDL.h PATH_SUFFIXES sdl2)
SET(_SDL2_STATIC_LIBS libSDL2.a)
SET(_SDL2_SHARED_LIBS libSDL2.so SDL2)
FIND_LIBRARY(SDL2_LIBRARY NAMES ${_SDL2_SHARED_LIBS} ${_SDL2_STATIC_LIBS})
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 DEFAULT_MSG SDL2_LIBRARY SDL2_INCLUDE_DIR)
MARK_AS_ADVANCED(SDL2_LIBRARY SDL2_INCLUDE_DIR)

View File

@ -45,6 +45,8 @@
#define BUILD_ARCH "x64"
#elif defined(__i386) || defined(_M_IX86) || defined(_X86_)
#define BUILD_ARCH "x86"
#elif defined(__arm__)
#define BUILD_ARCH "ARM"
#else
#define BUILD_ARCH "unknown"
#endif

View File

@ -101,7 +101,7 @@ void Application::init(std::vector<std::string>& args)
registerLuaFunctions();
}
void Application::deinit()
void Application::unloadModules()
{
g_lua.callGlobalField("g_app", "onTerminate");

View File

@ -34,9 +34,9 @@ public:
virtual ~Application() {}
virtual void init(std::vector<std::string>& args);
virtual void deinit();
virtual void unloadModules();
virtual void terminate();
virtual void run() = 0;
virtual void runAppMainLoop() = 0;
virtual void poll();
virtual void exit();
virtual void close();

View File

@ -31,7 +31,7 @@
ConsoleApplication g_app;
void ConsoleApplication::run()
void ConsoleApplication::runAppMainLoop()
{
m_running = true;

View File

@ -29,7 +29,7 @@
class ConsoleApplication : public Application
{
public:
void run();
void runAppMainLoop();
int getFps() { return m_frameCounter.getLastFps(); }

View File

@ -66,12 +66,12 @@ void GraphicalApplication::init(std::vector<std::string>& args)
#endif
}
void GraphicalApplication::deinit()
void GraphicalApplication::unloadModules()
{
// hide the window because there is no render anymore
g_window.hide();
Application::deinit();
Application::unloadModules();
}
void GraphicalApplication::terminate()
@ -101,7 +101,7 @@ void GraphicalApplication::terminate()
m_terminated = true;
}
void GraphicalApplication::run()
void GraphicalApplication::runAppMainLoop()
{
m_running = true;

View File

@ -36,9 +36,9 @@ class GraphicalApplication : public Application
public:
void init(std::vector<std::string>& args);
void deinit();
void unloadModules();
void terminate();
void run();
void runAppMainLoop();
void poll();
void close();

View File

@ -32,6 +32,10 @@
#include <framework/luaengine/luainterface.h>
#endif
#ifdef ANDROID
#include <android/log.h>
#endif // ANDROID
Logger g_logger;
void Logger::log(Fw::LogLevel level, const std::string& message)
@ -66,6 +70,9 @@ void Logger::log(Fw::LogLevel level, const std::string& message)
outmsg = tmp.str();
#endif
*/
#ifdef ANDROID
__android_log_print(ANDROID_LOG_INFO, "OTClientMobile", outmsg.c_str());
#endif // ANDROID
std::cout << outmsg << std::endl;

View File

@ -48,7 +48,8 @@ bool ResourceManager::discoverWorkDir(const std::string& existentFile)
std::string possiblePaths[] = { g_platform.getCurrentDir(),
g_resources.getBaseDir(),
g_resources.getBaseDir() + "../",
g_resources.getBaseDir() + "../share/" + g_app.getCompactName() + "/" };
g_resources.getBaseDir() + "../share/" + g_app.getCompactName() + "/",
"/sdcard/OTClient/" };
bool found = false;
for(const std::string& dir : possiblePaths) {
@ -71,12 +72,20 @@ bool ResourceManager::setupUserWriteDir(const std::string& appWriteDirName)
{
std::string userDir = getUserDir();
std::string dirName;
#ifndef WIN32
dirName = stdext::format(".%s", appWriteDirName);
#else
dirName = appWriteDirName;
#endif
std::string writeDir = userDir + dirName;
std::string writeDir;
#ifdef ANDROID
writeDir = getWorkDir();
#else
writeDir = userDir + dirName;
#endif
if(!PHYSFS_setWriteDir(writeDir.c_str())) {
if(!PHYSFS_setWriteDir(userDir.c_str()) || !PHYSFS_mkdir(dirName.c_str())) {

View File

@ -35,7 +35,7 @@
#if defined(_MSC_VER) && _MSC_VER >= 1300
#define swap16(data) _byteswap_ushort(data)
#define swap32(data) _byteswap_ulong(data)
#elif __linux__
#elif __linux__ && !defined ANDROID
#include <byteswap.h>
#define swap16(data) bswap_16(data)
#define swap32(data) bswap_32(data)

View File

@ -25,6 +25,9 @@
#ifdef WIN32
#include "win32window.h"
WIN32Window window;
#elif defined ANDROID
#include "sdlwindow.h"
SDLWindow window;
#else
#include "x11window.h"
#include <framework/core/clock.h>

View File

@ -0,0 +1,389 @@
/*
* Copyright (c) 2010-2014 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifdef ANDROID
#include "sdlwindow.h"
SDLWindow::SDLWindow() {
m_minimumSize = Size(600,480);
m_size = Size(600,480);
m_window = 0;
//m_keyMap[SDLK_ESCAPE] = Fw::KeyEscape;
//m_keyMap[SDLK_TAB] = Fw::KeyTab;
m_keyMap[SDLK_RETURN] = Fw::KeyEnter;
m_keyMap[SDLK_BACKSPACE] = Fw::KeyBackspace;
m_keyMap[SDLK_SPACE] = Fw::KeySpace;
/*
m_keyMap[SDLK_PAGEUP] = Fw::KeyPageUp;
m_keyMap[SDLK_PAGEDOWN] = Fw::KeyPageDown;
m_keyMap[SDLK_HOME] = Fw::KeyHome;
m_keyMap[SDLK_END] = Fw::KeyEnd;
m_keyMap[SDLK_INSERT] = Fw::KeyInsert;
m_keyMap[SDLK_DELETE] = Fw::KeyDelete;
m_keyMap[SDLK_UP] = Fw::KeyUp;
m_keyMap[SDLK_DOWN] = Fw::KeyDown;
m_keyMap[SDLK_LEFT] = Fw::KeyLeft;
m_keyMap[SDLK_RIGHT] = Fw::KeyRight;
m_keyMap[SDLK_NUMLOCKCLEAR] = Fw::KeyNumLock;
m_keyMap[SDLK_SCROLLLOCK] = Fw::KeyScrollLock;
m_keyMap[SDLK_CAPSLOCK] = Fw::KeyCapsLock;
m_keyMap[SDLK_PRINTSCREEN] = Fw::KeyPrintScreen;
m_keyMap[SDLK_PAUSE] = Fw::KeyPause;
m_keyMap[SDLK_LCTRL] = Fw::KeyCtrl;
m_keyMap[SDLK_RCTRL] = Fw::KeyCtrl;
m_keyMap[SDLK_LSHIFT] = Fw::KeyShift;
m_keyMap[SDLK_RSHIFT] = Fw::KeyShift;
m_keyMap[SDLK_LALT] = Fw::KeyAlt;
m_keyMap[SDLK_RALT] = Fw::KeyAlt;
m_keyMap[SDLK_LGUI] = Fw::KeyMeta;
m_keyMap[SDLK_RGUI] = Fw::KeyMeta;
*/
// ascii characters
m_keyMap[SDLK_EXCLAIM] = Fw::KeyExclamation;
m_keyMap[SDLK_QUOTEDBL] = Fw::KeyQuote;
m_keyMap[SDLK_HASH] = Fw::KeyNumberSign;
m_keyMap[SDLK_DOLLAR] = Fw::KeyDollar;
m_keyMap[SDLK_PERCENT] = Fw::KeyPercent;
m_keyMap[SDLK_AMPERSAND] = Fw::KeyAmpersand;
m_keyMap[SDLK_QUOTE] = Fw::KeyApostrophe;
m_keyMap[SDLK_LEFTPAREN] = Fw::KeyLeftParen;
m_keyMap[SDLK_RIGHTPAREN] = Fw::KeyRightParen;
m_keyMap[SDLK_ASTERISK] = Fw::KeyAsterisk;
m_keyMap[SDLK_PLUS] = Fw::KeyPlus;
m_keyMap[SDLK_COMMA] = Fw::KeyComma;
m_keyMap[SDLK_MINUS] = Fw::KeyMinus;
m_keyMap[SDLK_PERIOD] = Fw::KeyPeriod;
m_keyMap[SDLK_SLASH] = Fw::KeySlash;
m_keyMap[SDLK_0] = Fw::Key0;
m_keyMap[SDLK_1] = Fw::Key1;
m_keyMap[SDLK_2] = Fw::Key2;
m_keyMap[SDLK_3] = Fw::Key3;
m_keyMap[SDLK_4] = Fw::Key4;
m_keyMap[SDLK_5] = Fw::Key5;
m_keyMap[SDLK_6] = Fw::Key6;
m_keyMap[SDLK_7] = Fw::Key7;
m_keyMap[SDLK_8] = Fw::Key8;
m_keyMap[SDLK_9] = Fw::Key9;
m_keyMap[SDLK_COLON] = Fw::KeyColon;
m_keyMap[SDLK_SEMICOLON] = Fw::KeySemicolon;
m_keyMap[SDLK_LESS] = Fw::KeyLess;
m_keyMap[SDLK_EQUALS] = Fw::KeyEqual;
m_keyMap[SDLK_GREATER] = Fw::KeyGreater;
m_keyMap[SDLK_QUESTION] = Fw::KeyQuestion;
m_keyMap[SDLK_AT] = Fw::KeyAtSign;
m_keyMap[SDLK_a] = Fw::KeyA;
m_keyMap[SDLK_b] = Fw::KeyB;
m_keyMap[SDLK_c] = Fw::KeyC;
m_keyMap[SDLK_d] = Fw::KeyD;
m_keyMap[SDLK_e] = Fw::KeyE;
m_keyMap[SDLK_f] = Fw::KeyF;
m_keyMap[SDLK_g] = Fw::KeyG;
m_keyMap[SDLK_h] = Fw::KeyH;
m_keyMap[SDLK_i] = Fw::KeyI;
m_keyMap[SDLK_j] = Fw::KeyJ;
m_keyMap[SDLK_k] = Fw::KeyK;
m_keyMap[SDLK_l] = Fw::KeyL;
m_keyMap[SDLK_m] = Fw::KeyM;
m_keyMap[SDLK_n] = Fw::KeyN;
m_keyMap[SDLK_o] = Fw::KeyO;
m_keyMap[SDLK_p] = Fw::KeyP;
m_keyMap[SDLK_q] = Fw::KeyQ;
m_keyMap[SDLK_r] = Fw::KeyR;
m_keyMap[SDLK_s] = Fw::KeyS;
m_keyMap[SDLK_t] = Fw::KeyT;
m_keyMap[SDLK_u] = Fw::KeyU;
m_keyMap[SDLK_v] = Fw::KeyV;
m_keyMap[SDLK_w] = Fw::KeyW;
m_keyMap[SDLK_x] = Fw::KeyX;
m_keyMap[SDLK_y] = Fw::KeyY;
m_keyMap[SDLK_z] = Fw::KeyZ;
m_keyMap[SDLK_LGUI] = Fw::KeyLeftBracket;
m_keyMap[SDLK_BACKSLASH] = Fw::KeyBackslash;
m_keyMap[SDLK_RIGHTBRACKET] = Fw::KeyRightBracket;
m_keyMap[SDLK_CARET] = Fw::KeyCaret;
m_keyMap[SDLK_UNDERSCORE] = Fw::KeyUnderscore;
m_keyMap[SDLK_BACKQUOTE] = Fw::KeyGrave;
//m_keyMap['{'] = Fw::KeyLeftCurly;
//m_keyMap['|'] = Fw::KeyBar;
//m_keyMap['}'] = Fw::KeyRightCurly;
//m_keyMap['~'] = Fw::KeyTilde;
// keypad
/*
m_keyMap[SDLK_KP_PLUS] = Fw::KeyPlus;
m_keyMap[SDLK_KP_MINUS] = Fw::KeyMinus;
m_keyMap[SDLK_KP_DECIMAL] = Fw::KeyPeriod;
m_keyMap[SDLK_KP_DIVIDE] = Fw::KeySlash;
m_keyMap[SDLK_KP_MULTIPLY] = Fw::KeyAsterisk;
m_keyMap[VK_OEM_1] = Fw::KeySemicolon;
m_keyMap[VK_OEM_2] = Fw::KeySlash;
m_keyMap[VK_OEM_3] = Fw::KeyGrave;
m_keyMap[VK_OEM_4] = Fw::KeyLeftBracket;
m_keyMap[VK_OEM_5] = Fw::KeyBackslash;
m_keyMap[VK_OEM_6] = Fw::KeyRightBracket;
m_keyMap[VK_OEM_7] = Fw::KeyApostrophe;
m_keyMap[VK_OEM_MINUS] = Fw::KeyMinus;
m_keyMap[VK_OEM_PLUS] = Fw::KeyEqual;
m_keyMap[SDLK_KP_COMMA] = Fw::KeyComma;
m_keyMap[VK_OEM_PERIOD] = Fw::KeyPeriod;
m_keyMap[SDLK_F1] = Fw::KeyF1;
m_keyMap[SDLK_F2] = Fw::KeyF2;
m_keyMap[SDLK_F3] = Fw::KeyF3;
m_keyMap[SDLK_F4] = Fw::KeyF4;
m_keyMap[SDLK_F5] = Fw::KeyF5;
m_keyMap[SDLK_F6] = Fw::KeyF6;
m_keyMap[SDLK_F7] = Fw::KeyF7;
m_keyMap[SDLK_F8] = Fw::KeyF8;
m_keyMap[SDLK_F9] = Fw::KeyF9;
m_keyMap[SDLK_F10] = Fw::KeyF10;
m_keyMap[SDLK_F11] = Fw::KeyF11;
m_keyMap[SDLK_F12] = Fw::KeyF12;
*/
}
void SDLWindow::init() {
initializeSDL();
}
void SDLWindow::initializeSDL() {
if(SDL_Init(SDL_INIT_VIDEO) != 0 ) {
g_logger.fatal( stdext::format("Unable to initialize SDL: %s", SDL_GetError()) );
terminate();
}
setSDLAttributes();
SDL_GetDisplayMode(0, 0, &m_mode);
int width = m_mode.w;
int height = m_mode.h;
m_window = SDL_CreateWindow( NULL, 0, 0, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN | SDL_WINDOW_RESIZABLE );
m_size = Size( width, height );
if( m_window == 0 ) {
g_logger.fatal("Failed to create window");
terminate();
}
m_visible = true;
SDL_GL_CreateContext(m_window);
//SDL_StartTextInput();
}
void SDLWindow::setSDLAttributes() {
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 4);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 4);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 4);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, OPENGL_ES);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
}
void SDLWindow::terminate() {
SDL_Quit();
m_visible = false;
}
void SDLWindow::poll() {
while(SDL_PollEvent(&m_event)) {
processKeydownOrKeyrelease();
if(hasRepeatedKey())
continue;
switch(m_event.type) {
case SDL_TEXTINPUT:
processTextInput();
break;
case SDL_FINGERDOWN:
case SDL_FINGERUP:
processFingerdownAndFingerup();
break;
case SDL_FINGERMOTION:
m_inputEvent.reset();
m_inputEvent.type = Fw::MouseMoveInputEvent;
Point newMousePos(m_event.tfinger.x * m_mode.w, m_event.tfinger.y * m_mode.h);
m_inputEvent.mouseMoved = newMousePos - m_inputEvent.mousePos;
m_inputEvent.mousePos = newMousePos;
if(m_onInputEvent)
m_onInputEvent(m_inputEvent);
break;
}
if(m_inputEvent.type != Fw::NoInputEvent && m_onInputEvent)
m_onInputEvent(m_inputEvent);
}
fireKeysPress();
}
bool SDLWindow::hasRepeatedKey() {
g_logger.info(stdext::format("hasRepeatedKey %i", m_event.key.repeat));
return m_event.key.repeat != 0;
}
void SDLWindow::processKeydownOrKeyrelease() {
if(m_event.key.state == SDL_PRESSED || (m_event.key.state == SDL_RELEASED && !hasRepeatedKey())) {
Fw::Key keyCode = Fw::KeyUnknown;
SDL_Keycode keysym = m_event.key.keysym.sym;
if(m_keyMap.find(keysym) != m_keyMap.end())
keyCode = m_keyMap[keysym];
if(m_event.type == SDL_PRESSED)
processKeyDown(keyCode);
else if(m_event.type == SDL_RELEASED)
processKeyUp(keyCode);
}
}
void SDLWindow::processTextInput() {
std::string text = m_event.text.text;
SDL_Keycode keysym = m_event.key.keysym.sym;
if(text.length() == 0 || keysym == SDLK_BACKSPACE || keysym == SDLK_RETURN)
return;
if(m_onInputEvent) {
m_inputEvent.reset(Fw::KeyTextInputEvent);
m_inputEvent.keyText = text;
m_onInputEvent(m_inputEvent);
}
}
void SDLWindow::processFingerdownAndFingerup() {
bool isFinderdown = m_event.type == SDL_FINGERDOWN;
m_inputEvent.reset();
m_inputEvent.type = isFinderdown ? Fw::MousePressInputEvent : Fw::MouseReleaseInputEvent;
m_inputEvent.mouseButton = Fw::MouseLeftButton;
m_mouseButtonStates[Fw::MouseLeftButton] = isFinderdown;
Point newMousePos(m_event.tfinger.x * m_mode.w, m_event.tfinger.y * m_mode.h);
m_inputEvent.mouseMoved = newMousePos - m_inputEvent.mousePos;
m_inputEvent.mousePos = newMousePos;
if(m_onInputEvent)
m_onInputEvent(m_inputEvent);
}
void SDLWindow::swapBuffers() {
SDL_GL_SwapWindow(m_window);
}
void SDLWindow::setVerticalSync(bool enable) {
// TODO
}
std::string SDLWindow::getClipboardText() {
return SDL_GetClipboardText();
}
void SDLWindow::setClipboardText(const std::string& text) {
SDL_SetClipboardText(text.c_str());
}
Size SDLWindow::getDisplaySize() {
Size size(m_mode.w, m_mode.h);
return size;
}
std::string SDLWindow::getPlatformType() {
return "ANDROID_SDL2";
}
void SDLWindow::show() {
// mobile devices doesn't need to show activity, it's open automatically
}
void SDLWindow::hide() {
// SDL make this for us
}
void SDLWindow::maximize() {
// mobile devices doesn't has window
}
void SDLWindow::move(const Point& pos) {
// mobile devices doesn't has window
}
void SDLWindow::resize(const Size& size) {
// android doesn't resize window
}
void SDLWindow::showMouse() {
// mobile devices doesn't has mouse
}
void SDLWindow::hideMouse() {
// mobile devices doesn't has mouse
}
int SDLWindow::internalLoadMouseCursor(const ImagePtr& image, const Point& hotSpot) {
// mobile devices doesn't has mouse
return 0;
}
void SDLWindow::setMouseCursor(int cursorId) {
// mobile devices doesn't has mouse
}
void SDLWindow::restoreMouseCursor() {
// mobile devices doesn't has mouse
}
void SDLWindow::setTitle(const std::string& title) {
// mobile devices doesn't need to set title, the app make it
}
void SDLWindow::setMinimumSize(const Size& minimumSize) {
// mobile devices doesn't has window
}
void SDLWindow::setFullscreen(bool fullscreen) {
// mobile devices doesn't has window
}
void SDLWindow::setIcon(const std::string& iconFile) {
// mobile devices doesn't has icon
}
#endif // ANDROID

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2010-2014 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef SDL_PLATFORM_H
#define SDL_PLATFORM_H
#include "platformwindow.h"
#include <EGL/egl.h>
#include <SDL.h>
class SDLWindow : public PlatformWindow
{
public:
SDLWindow();
void init();
void terminate();
void move(const Point& pos);
void resize(const Size& size);
void show();
void hide();
void maximize();
void poll();
void swapBuffers();
void showMouse();
void hideMouse();
void setMouseCursor(int cursorId);
void restoreMouseCursor();
void setTitle(const std::string& title);
void setMinimumSize(const Size& minimumSize);
void setFullscreen(bool fullscreen);
void setVerticalSync(bool enable);
void setIcon(const std::string& iconFile);
void setClipboardText(const std::string& text);
Size getDisplaySize();
std::string getClipboardText();
std::string getPlatformType();
void initializeSDL();
void setSDLAttributes();
bool hasRepeatedKey();
void processKeydownOrKeyrelease();
void processTextInput();
void processFingerdownAndFingerup();
protected:
int internalLoadMouseCursor(const ImagePtr& image, const Point& hotSpot);
private:
SDL_Window* m_window;
SDL_DisplayMode m_mode;
SDL_Event m_event;
};
#endif

View File

@ -20,7 +20,7 @@
* THE SOFTWARE.
*/
#if !defined(WIN32) && defined(CRASH_HANDLER)
#if !defined(WIN32) && !defined(ANDROID) && defined(CRASH_HANDLER)
#include "crashhandler.h"
#include <framework/global.h>

View File

@ -29,7 +29,12 @@
#include <framework/stdext/stdext.h>
#include <sys/stat.h>
#ifdef ANDROID
#include <errno.h>
#else
#include <execinfo.h>
#endif
void Platform::processArgs(std::vector<std::string>& args)
{
@ -169,6 +174,7 @@ std::string Platform::getOSName()
return std::string();
}
#ifndef ANDROID
std::string Platform::traceback(const std::string& where, int level, int maxDepth)
{
std::stringstream ss;
@ -199,5 +205,8 @@ std::string Platform::traceback(const std::string& where, int level, int maxDept
return ss.str();
}
#else
std::string Platform::traceback(const std::string& where, int level, int maxDepth){ return " ANDROID TRACEBACK NEED TO DO"; }
#endif
#endif

View File

@ -20,7 +20,7 @@
* THE SOFTWARE.
*/
#ifndef WIN32
#if !defined WIN32 && !defined ANDROID
#include "x11window.h"
#include <framework/core/resourcemanager.h>
@ -590,15 +590,15 @@ void X11Window::poll()
XNextEvent(m_display, &event);
// check for repeated key releases
bool repatedKeyRelease = false;
bool repeatedKeyRelease = false;
if(event.type == KeyRelease && XPending(m_display)) {
XPeekEvent(m_display, &peekEvent);
if((peekEvent.type == KeyPress) && (peekEvent.xkey.keycode == event.xkey.keycode) && ((peekEvent.xkey.time-event.xkey.time) < 2))
repatedKeyRelease = true;
repeatedKeyRelease = true;
}
// process keydown and keyrelease events first
if(event.type == KeyPress || (event.type == KeyRelease && !repatedKeyRelease)) {
if(event.type == KeyPress || (event.type == KeyRelease && !repeatedKeyRelease)) {
// remove caps lock and shift maks
XKeyEvent xkey = event.xkey;
xkey.state &= ~(ShiftMask | LockMask);
@ -623,7 +623,7 @@ void X11Window::poll()
continue;
// discard repated key releases
if(repatedKeyRelease)
if(repeatedKeyRelease)
continue;
switch(event.type) {

View File

@ -20,39 +20,17 @@
* THE SOFTWARE.
*/
#include <framework/core/application.h>
#include <framework/core/resourcemanager.h>
#include <framework/luaengine/luainterface.h>
// The only way that the android sdl library can link a main function it's including SDL.h
#ifdef ANDROID
#include <SDL.h>
#endif
#include <client/client.h>
int main(int argc, const char* argv[])
int main(int argc, char* argv[])
{
std::vector<std::string> args(argv, argv + argc);
Client client(argc, argv);
client.terminateAndFreeMemory();
// setup application name and version
g_app.setName("OTClient");
g_app.setCompactName("otclient");
g_app.setVersion(VERSION);
// initialize application framework and otclient
g_app.init(args);
g_client.init(args);
// find script init.lua and run it
if(!g_resources.discoverWorkDir("init.lua"))
g_logger.fatal("Unable to find work directory, the application cannot be initialized.");
if(!g_lua.safeRunScript("init.lua"))
g_logger.fatal("Unable to run script init.lua!");
// the run application main loop
g_app.run();
// unload modules
g_app.deinit();
// terminate everything and free memory
g_client.terminate();
g_app.terminate();
return 0;
}