Просмотр исходного кода

Text encoding consistency fixes.

Lasse Öörni 13 лет назад
Родитель
Сommit
fc75dfc964

+ 1 - 1
ThirdParty/GLee/GLee.c

@@ -33,7 +33,7 @@
 *
 ***************************************************************************/
 
-// Modified by Lasse Öörni for Urho3D
+// Modified by Lasse Oorni for Urho3D
 
 #ifdef _MSC_VER
 	#pragma optimize( "g", off )

+ 1 - 1
ThirdParty/GLee/GLee.h

@@ -33,7 +33,7 @@
 *
 ***************************************************************************/
 
-// Modified by Lasse Öörni for Urho3D
+// Modified by Lasse Oorni for Urho3D
 
 #ifndef __glee_h_
 #define __glee_h_

+ 750 - 750
ThirdParty/SDL/src/core/android/SDL_android.cpp

@@ -1,750 +1,750 @@
-/*
-  Simple DirectMedia Layer
-  Copyright (C) 1997-2012 Sam Lantinga <[email protected]>
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-*/
-
-// Modified by Lasse Öörni for Urho3D
-
-#include "SDL_config.h"
-#include "SDL_stdinc.h"
-#include "SDL_assert.h"
-
-#ifdef __ANDROID__
-
-#include "SDL_android.h"
-
-extern "C" {
-#include "../../events/SDL_events_c.h"
-#include "../../video/android/SDL_androidkeyboard.h"
-#include "../../video/android/SDL_androidtouch.h"
-#include "../../video/android/SDL_androidvideo.h"
-
-#include <android/log.h>
-#define LOG_TAG "SDL_android"
-//#define LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
-//#define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
-#define LOGI(...) do {} while (false)
-#define LOGE(...) do {} while (false)
-
-
-/* Implemented in audio/android/SDL_androidaudio.c */
-extern void Android_RunAudioThread();
-} // C
-
-/*******************************************************************************
- This file links the Java side of Android with libsdl
-*******************************************************************************/
-#include <jni.h>
-#include <android/log.h>
-
-
-/*******************************************************************************
-                               Globals
-*******************************************************************************/
-static JNIEnv* mEnv = NULL;
-static JNIEnv* mAudioEnv = NULL;
-static JavaVM* mJavaVM;
-
-// Main activity
-static jclass mActivityClass;
-
-// method signatures
-static jmethodID midCreateGLContext;
-static jmethodID midFlipBuffers;
-static jmethodID midAudioInit;
-static jmethodID midAudioWriteShortBuffer;
-static jmethodID midAudioWriteByteBuffer;
-static jmethodID midAudioQuit;
-
-// Accelerometer data storage
-static float fLastAccelerometer[3];
-static bool bHasNewData;
-
-// Application files dir
-static char* mFilesDir = 0;
-
-/*******************************************************************************
-                 Functions called by JNI
-*******************************************************************************/
-
-// Library init
-extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
-{
-    JNIEnv *env;
-    mJavaVM = vm;
-    LOGI("JNI_OnLoad called");
-    if (mJavaVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
-        LOGE("Failed to get the environment using GetEnv()");
-        return -1;
-    }
-
-    return JNI_VERSION_1_4;
-}
-
-extern "C" const char* SDL_Android_GetFilesDir()
-{
-    return mFilesDir;
-}
-
-// Called before SDL_main() to initialize JNI bindings
-extern "C" void SDL_Android_Init(JNIEnv* env, jclass cls, jstring filesDir)
-{
-    __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL_Android_Init()");
-
-    // Copy the files dir
-    const char *str;
-    str = env->GetStringUTFChars(filesDir, 0);
-    if (str)
-    {
-        if (mFilesDir)
-            free(mFilesDir);
-
-        size_t length = strlen(str) + 1;
-        mFilesDir = (char*)malloc(length);
-        memcpy(mFilesDir, str, length);
-        env->ReleaseStringUTFChars(filesDir, str);
-    }
-
-    mEnv = env;
-    mActivityClass = (jclass)env->NewGlobalRef(cls);
-
-    midCreateGLContext = mEnv->GetStaticMethodID(mActivityClass,
-                                "createGLContext","(II)Z");
-    midFlipBuffers = mEnv->GetStaticMethodID(mActivityClass,
-                                "flipBuffers","()V");
-    midAudioInit = mEnv->GetStaticMethodID(mActivityClass,
-                                "audioInit", "(IZZI)Ljava/lang/Object;");
-    midAudioWriteShortBuffer = mEnv->GetStaticMethodID(mActivityClass,
-                                "audioWriteShortBuffer", "([S)V");
-    midAudioWriteByteBuffer = mEnv->GetStaticMethodID(mActivityClass,
-                                "audioWriteByteBuffer", "([B)V");
-    midAudioQuit = mEnv->GetStaticMethodID(mActivityClass,
-                                "audioQuit", "()V");
-
-    bHasNewData = false;
-
-    if(!midCreateGLContext || !midFlipBuffers || !midAudioInit ||
-       !midAudioWriteShortBuffer || !midAudioWriteByteBuffer || !midAudioQuit) {
-        __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL: Couldn't locate Java callbacks, check that they're named and typed correctly");
-    }
-    __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL_Android_Init() finished!");
-}
-
-// Resize
-extern "C" void NATIVE_FUNCTION(onNativeResize)(
-                                    JNIEnv* env, jclass jcls,
-                                    jint width, jint height, jint format)
-{
-    Android_SetScreenResolution(width, height, format);
-}
-
-// Keydown
-extern "C" void NATIVE_FUNCTION(onNativeKeyDown)(
-                                    JNIEnv* env, jclass jcls, jint keycode)
-{
-    Android_OnKeyDown(keycode);
-}
-
-// Keyup
-extern "C" void NATIVE_FUNCTION(onNativeKeyUp)(
-                                    JNIEnv* env, jclass jcls, jint keycode)
-{
-    Android_OnKeyUp(keycode);
-}
-
-// Touch
-extern "C" void NATIVE_FUNCTION(onNativeTouch)(
-                                    JNIEnv* env, jclass jcls,
-                                    jint touch_device_id_in, jint pointer_finger_id_in,
-                                    jint action, jfloat x, jfloat y, jfloat p)
-{
-    Android_OnTouch(touch_device_id_in, pointer_finger_id_in, action, x, y, p);
-}
-
-// Accelerometer
-extern "C" void NATIVE_FUNCTION(onNativeAccel)(
-                                    JNIEnv* env, jclass jcls,
-                                    jfloat x, jfloat y, jfloat z)
-{
-    fLastAccelerometer[0] = x;
-    fLastAccelerometer[1] = y;
-    fLastAccelerometer[2] = z;
-    bHasNewData = true;
-}
-
-// Quit
-extern "C" void NATIVE_FUNCTION(nativeQuit)(
-                                    JNIEnv* env, jclass cls)
-{    
-    // Inject a SDL_QUIT event
-    SDL_Event event;
-    event.type=SDL_SYSEVENT_TERMINATE;
-    event.sysevent.data=NULL;
-    if (SDL_SysEventHandler)
-        SDL_SysEventHandler(&event);
-    else SDL_SendQuit();
-}
-
-// Pause
-extern "C" void NATIVE_FUNCTION(nativePause)(
-                                    JNIEnv* env, jclass cls)
-{
-    SDL_Event event;
-    event.type=SDL_SYSEVENT_WILL_SUSPEND;
-    event.sysevent.data=NULL;
-    if (SDL_SysEventHandler)
-        SDL_SysEventHandler(&event);
-    event.type=SDL_SYSEVENT_SUSPEND;
-    event.sysevent.data=NULL;
-    if (SDL_SysEventHandler)
-        SDL_SysEventHandler(&event);
-    else if (Android_Window) {
-        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
-        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
-    }
-}
-
-// Resume
-extern "C" void NATIVE_FUNCTION(nativeResume)(
-                                    JNIEnv* env, jclass cls)
-{
-    SDL_Event event;
-    event.type=SDL_SYSEVENT_WILL_RESUME;
-    event.sysevent.data=NULL;
-    if (SDL_SysEventHandler)
-        SDL_SysEventHandler(&event);
-    event.type=SDL_SYSEVENT_RESUME;
-    event.sysevent.data=NULL;
-    if (SDL_SysEventHandler)
-        SDL_SysEventHandler(&event);
-    else if (Android_Window) {
-        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
-        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_RESTORED, 0, 0);
-    }
-}
-
-extern "C" void NATIVE_FUNCTION(nativeRunAudioThread)(
-                                    JNIEnv* env, jclass cls)
-{
-    /* This is the audio thread, with a different environment */
-    mAudioEnv = env;
-
-    Android_RunAudioThread();
-}
-
-// Surface destroyed
-extern "C" void NATIVE_FUNCTION(onNativeSurfaceDestroyed)(
-                                    JNIEnv* env, jclass cls)
-{
-    if (Android_Window) {
-        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_SURFACE_LOST, 0, 0);
-    }
-}
-
-// Surface created
-extern "C" void NATIVE_FUNCTION(onNativeSurfaceCreated)(
-                                    JNIEnv* env, jclass cls)
-{
-    if (Android_Window) {
-        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_SURFACE_CREATED, 0, 0);
-    }
-}
-
-/*******************************************************************************
-             Functions called by SDL into Java
-*******************************************************************************/
-
-class LocalReferenceHolder
-{
-private:
-    static int s_active;
-
-public:
-    static bool IsActive() {
-        return s_active > 0;
-    }
-
-public:
-    LocalReferenceHolder() : m_env(NULL) { }
-    ~LocalReferenceHolder() {
-        if (m_env) {
-            m_env->PopLocalFrame(NULL);
-            --s_active;
-        }
-    }
-
-    bool init(JNIEnv *env, jint capacity = 16) {
-        if (env->PushLocalFrame(capacity) < 0) {
-            SDL_SetError("Failed to allocate enough JVM local references");
-            return false;
-        }
-        ++s_active;
-        m_env = env;
-        return true;
-    }
-
-protected:
-    JNIEnv *m_env;
-};
-int LocalReferenceHolder::s_active;
-
-extern "C" SDL_bool Android_JNI_CreateContext(int majorVersion, int minorVersion)
-{
-    if (mEnv->CallStaticBooleanMethod(mActivityClass, midCreateGLContext, majorVersion, minorVersion)) {
-        return SDL_TRUE;
-    } else {
-        return SDL_FALSE;
-    }
-}
-
-extern "C" void Android_JNI_SwapWindow()
-{
-    mEnv->CallStaticVoidMethod(mActivityClass, midFlipBuffers); 
-}
-
-extern "C" void Android_JNI_SetActivityTitle(const char *title)
-{
-    jmethodID mid;
-
-    mid = mEnv->GetStaticMethodID(mActivityClass,"setActivityTitle","(Ljava/lang/String;)V");
-    if (mid) {
-        jstring jtitle = reinterpret_cast<jstring>(mEnv->NewStringUTF(title));
-        mEnv->CallStaticVoidMethod(mActivityClass, mid, jtitle);
-        mEnv->DeleteLocalRef(jtitle);
-    }
-}
-
-extern "C" SDL_bool Android_JNI_GetAccelerometerValues(float values[3])
-{
-    int i;
-    SDL_bool retval = SDL_FALSE;
-
-    if (bHasNewData) {
-        for (i = 0; i < 3; ++i) {
-            values[i] = fLastAccelerometer[i];
-        }
-        bHasNewData = false;
-        retval = SDL_TRUE;
-    }
-
-    return retval;
-}
-
-//
-// Audio support
-//
-static jboolean audioBuffer16Bit = JNI_FALSE;
-static jboolean audioBufferStereo = JNI_FALSE;
-static jobject audioBuffer = NULL;
-static void* audioBufferPinned = NULL;
-
-extern "C" int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames)
-{
-    int audioBufferFrames;
-
-    int status;
-    JNIEnv *env;
-    static bool isAttached = false;    
-    status = mJavaVM->GetEnv((void **) &env, JNI_VERSION_1_4);
-    if(status < 0) {
-        LOGE("callback_handler: failed to get JNI environment, assuming native thread");
-        status = mJavaVM->AttachCurrentThread(&env, NULL);
-        if(status < 0) {
-            LOGE("callback_handler: failed to attach current thread");
-            return 0;
-        }
-        isAttached = true;
-    }
-
-    
-    __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");
-    audioBuffer16Bit = is16Bit;
-    audioBufferStereo = channelCount > 1;
-
-    audioBuffer = env->CallStaticObjectMethod(mActivityClass, midAudioInit, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames);
-
-    if (audioBuffer == NULL) {
-        __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: didn't get back a good audio buffer!");
-        return 0;
-    }
-    audioBuffer = env->NewGlobalRef(audioBuffer);
-
-    jboolean isCopy = JNI_FALSE;
-    if (audioBuffer16Bit) {
-        audioBufferPinned = env->GetShortArrayElements((jshortArray)audioBuffer, &isCopy);
-        audioBufferFrames = env->GetArrayLength((jshortArray)audioBuffer);
-    } else {
-        audioBufferPinned = env->GetByteArrayElements((jbyteArray)audioBuffer, &isCopy);
-        audioBufferFrames = env->GetArrayLength((jbyteArray)audioBuffer);
-    }
-    if (audioBufferStereo) {
-        audioBufferFrames /= 2;
-    }
- 
-    if (isAttached) {
-        mJavaVM->DetachCurrentThread();
-    }
-
-    return audioBufferFrames;
-}
-
-extern "C" void * Android_JNI_GetAudioBuffer()
-{
-    return audioBufferPinned;
-}
-
-extern "C" void Android_JNI_WriteAudioBuffer()
-{
-    if (audioBuffer16Bit) {
-        mAudioEnv->ReleaseShortArrayElements((jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT);
-        mAudioEnv->CallStaticVoidMethod(mActivityClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer);
-    } else {
-        mAudioEnv->ReleaseByteArrayElements((jbyteArray)audioBuffer, (jbyte *)audioBufferPinned, JNI_COMMIT);
-        mAudioEnv->CallStaticVoidMethod(mActivityClass, midAudioWriteByteBuffer, (jbyteArray)audioBuffer);
-    }
-
-    /* JNI_COMMIT means the changes are committed to the VM but the buffer remains pinned */
-}
-
-extern "C" void Android_JNI_CloseAudioDevice()
-{
-    int status;
-    JNIEnv *env;
-    static bool isAttached = false;    
-    status = mJavaVM->GetEnv((void **) &env, JNI_VERSION_1_4);
-    if(status < 0) {
-        LOGE("callback_handler: failed to get JNI environment, assuming native thread");
-        status = mJavaVM->AttachCurrentThread(&env, NULL);
-        if(status < 0) {
-            LOGE("callback_handler: failed to attach current thread");
-            return;
-        }
-        isAttached = true;
-    }
-
-    env->CallStaticVoidMethod(mActivityClass, midAudioQuit); 
-
-    if (audioBuffer) {
-        env->DeleteGlobalRef(audioBuffer);
-        audioBuffer = NULL;
-        audioBufferPinned = NULL;
-    }
-
-    if (isAttached) {
-        mJavaVM->DetachCurrentThread();
-    }
-}
-
-// Test for an exception and call SDL_SetError with its detail if one occurs
-static bool Android_JNI_ExceptionOccurred()
-{
-    SDL_assert(LocalReferenceHolder::IsActive());
-
-    jthrowable exception = mEnv->ExceptionOccurred();
-    if (exception != NULL) {
-        jmethodID mid;
-
-        // Until this happens most JNI operations have undefined behaviour
-        mEnv->ExceptionClear();
-
-        jclass exceptionClass = mEnv->GetObjectClass(exception);
-        jclass classClass = mEnv->FindClass("java/lang/Class");
-
-        mid = mEnv->GetMethodID(classClass, "getName", "()Ljava/lang/String;");
-        jstring exceptionName = (jstring)mEnv->CallObjectMethod(exceptionClass, mid);
-        const char* exceptionNameUTF8 = mEnv->GetStringUTFChars(exceptionName, 0);
-
-        mid = mEnv->GetMethodID(exceptionClass, "getMessage", "()Ljava/lang/String;");
-        jstring exceptionMessage = (jstring)mEnv->CallObjectMethod(exception, mid);
-
-        if (exceptionMessage != NULL) {
-            const char* exceptionMessageUTF8 = mEnv->GetStringUTFChars(
-                    exceptionMessage, 0);
-            SDL_SetError("%s: %s", exceptionNameUTF8, exceptionMessageUTF8);
-            mEnv->ReleaseStringUTFChars(exceptionMessage, exceptionMessageUTF8);
-        } else {
-            SDL_SetError("%s", exceptionNameUTF8);
-        }
-
-        mEnv->ReleaseStringUTFChars(exceptionName, exceptionNameUTF8);
-
-        return true;
-    }
-
-    return false;
-}
-
-static int Android_JNI_FileOpen(SDL_RWops* ctx)
-{
-    LocalReferenceHolder refs;
-    int result = 0;
-
-    jmethodID mid;
-    jobject context;
-    jobject assetManager;
-    jobject inputStream;
-    jclass channels;
-    jobject readableByteChannel;
-    jstring fileNameJString;
-
-    if (!refs.init(mEnv)) {
-        goto failure;
-    }
-
-    fileNameJString = (jstring)ctx->hidden.androidio.fileNameRef;
-
-    // context = SDLActivity.getContext();
-    mid = mEnv->GetStaticMethodID(mActivityClass,
-            "getContext","()Landroid/content/Context;");
-    context = mEnv->CallStaticObjectMethod(mActivityClass, mid);
-
-    // assetManager = context.getAssets();
-    mid = mEnv->GetMethodID(mEnv->GetObjectClass(context),
-            "getAssets", "()Landroid/content/res/AssetManager;");
-    assetManager = mEnv->CallObjectMethod(context, mid);
-
-    // inputStream = assetManager.open(<filename>);
-    mid = mEnv->GetMethodID(mEnv->GetObjectClass(assetManager),
-            "open", "(Ljava/lang/String;)Ljava/io/InputStream;");
-    inputStream = mEnv->CallObjectMethod(assetManager, mid, fileNameJString);
-    if (Android_JNI_ExceptionOccurred()) {
-        goto failure;
-    }
-
-    ctx->hidden.androidio.inputStreamRef = mEnv->NewGlobalRef(inputStream);
-
-    // Despite all the visible documentation on [Asset]InputStream claiming
-    // that the .available() method is not guaranteed to return the entire file
-    // size, comments in <sdk>/samples/<ver>/ApiDemos/src/com/example/ ...
-    // android/apis/content/ReadAsset.java imply that Android's
-    // AssetInputStream.available() /will/ always return the total file size
-
-    // size = inputStream.available();
-    mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream),
-            "available", "()I");
-    ctx->hidden.androidio.size = mEnv->CallIntMethod(inputStream, mid);
-    if (Android_JNI_ExceptionOccurred()) {
-        goto failure;
-    }
-
-    // readableByteChannel = Channels.newChannel(inputStream);
-    channels = mEnv->FindClass("java/nio/channels/Channels");
-    mid = mEnv->GetStaticMethodID(channels,
-            "newChannel",
-            "(Ljava/io/InputStream;)Ljava/nio/channels/ReadableByteChannel;");
-    readableByteChannel = mEnv->CallStaticObjectMethod(
-            channels, mid, inputStream);
-    if (Android_JNI_ExceptionOccurred()) {
-        goto failure;
-    }
-
-    ctx->hidden.androidio.readableByteChannelRef =
-        mEnv->NewGlobalRef(readableByteChannel);
-
-    // Store .read id for reading purposes
-    mid = mEnv->GetMethodID(mEnv->GetObjectClass(readableByteChannel),
-            "read", "(Ljava/nio/ByteBuffer;)I");
-    ctx->hidden.androidio.readMethod = mid;
-
-    ctx->hidden.androidio.position = 0;
-
-    if (false) {
-failure:
-        result = -1;
-
-        mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.fileNameRef);
-
-        if(ctx->hidden.androidio.inputStreamRef != NULL) {
-            mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.inputStreamRef);
-        }
-
-        if(ctx->hidden.androidio.readableByteChannelRef != NULL) {
-            mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.readableByteChannelRef);
-        }
-
-    }
-
-    return result;
-}
-
-extern "C" int Android_JNI_FileOpen(SDL_RWops* ctx,
-        const char* fileName, const char*)
-{
-    LocalReferenceHolder refs;
-
-    if (!refs.init(mEnv)) {
-        return -1;
-    }
-
-    if (!ctx) {
-        return -1;
-    }
-
-    jstring fileNameJString = mEnv->NewStringUTF(fileName);
-    ctx->hidden.androidio.fileNameRef = mEnv->NewGlobalRef(fileNameJString);
-    ctx->hidden.androidio.inputStreamRef = NULL;
-
-    return Android_JNI_FileOpen(ctx);
-}
-
-extern "C" size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer,
-        size_t size, size_t maxnum)
-{
-    LocalReferenceHolder refs;
-    int bytesRemaining = size * maxnum;
-    int bytesRead = 0;
-
-    if (!refs.init(mEnv)) {
-        return -1;
-    }
-
-    jobject readableByteChannel = (jobject)ctx->hidden.androidio.readableByteChannelRef;
-    jmethodID readMethod = (jmethodID)ctx->hidden.androidio.readMethod;
-    jobject byteBuffer = mEnv->NewDirectByteBuffer(buffer, bytesRemaining);
-
-    while (bytesRemaining > 0) {
-        // result = readableByteChannel.read(...);
-        int result = mEnv->CallIntMethod(readableByteChannel, readMethod, byteBuffer);
-
-        if (Android_JNI_ExceptionOccurred()) {
-            return 0;
-        }
-
-        if (result < 0) {
-            break;
-        }
-
-        bytesRemaining -= result;
-        bytesRead += result;
-        ctx->hidden.androidio.position += result;
-    }
-
-    return bytesRead / size;
-}
-
-extern "C" size_t Android_JNI_FileWrite(SDL_RWops* ctx, const void* buffer,
-        size_t size, size_t num)
-{
-    SDL_SetError("Cannot write to Android package filesystem");
-    return 0;
-}
-
-static int Android_JNI_FileClose(SDL_RWops* ctx, bool release)
-{
-    LocalReferenceHolder refs;
-    int result = 0;
-
-    if (!refs.init(mEnv)) {
-        SDL_SetError("Failed to allocate enough JVM local references");
-        return -1;
-    }
-
-    if (ctx) {
-        if (release) {
-            mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.fileNameRef);
-        }
-
-        jobject inputStream = (jobject)ctx->hidden.androidio.inputStreamRef;
-
-        // inputStream.close();
-        jmethodID mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream),
-                "close", "()V");
-        mEnv->CallVoidMethod(inputStream, mid);
-        mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.inputStreamRef);
-        mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.readableByteChannelRef);
-        if (Android_JNI_ExceptionOccurred()) {
-            result = -1;
-        }
-
-        if (release) {
-            SDL_FreeRW(ctx);
-        }
-    }
-
-    return result;
-}
-
-
-extern "C" long Android_JNI_FileSeek(SDL_RWops* ctx, long offset, int whence)
-{
-    long newPosition;
-
-    switch (whence) {
-        case RW_SEEK_SET:
-            newPosition = offset;
-            break;
-        case RW_SEEK_CUR:
-            newPosition = ctx->hidden.androidio.position + offset;
-            break;
-        case RW_SEEK_END:
-            newPosition = ctx->hidden.androidio.size + offset;
-            break;
-        default:
-            SDL_SetError("Unknown value for 'whence'");
-            return -1;
-    }
-    if (newPosition < 0) {
-        newPosition = 0;
-    }
-    if (newPosition > ctx->hidden.androidio.size) {
-        newPosition = ctx->hidden.androidio.size;
-    }
-
-    long movement = newPosition - ctx->hidden.androidio.position;
-    jobject inputStream = (jobject)ctx->hidden.androidio.inputStreamRef;
-
-    if (movement > 0) {
-        unsigned char buffer[1024];
-
-        // The easy case where we're seeking forwards
-        while (movement > 0) {
-            long amount = (long) sizeof (buffer);
-            if (amount > movement) {
-                amount = movement;
-            }
-            size_t result = Android_JNI_FileRead(ctx, buffer, 1, amount);
-
-            if (result <= 0) {
-                // Failed to read/skip the required amount, so fail
-                return -1;
-            }
-
-            movement -= result;
-        }
-    } else if (movement < 0) {
-        // We can't seek backwards so we have to reopen the file and seek
-        // forwards which obviously isn't very efficient
-        Android_JNI_FileClose(ctx, false);
-        Android_JNI_FileOpen(ctx);
-        Android_JNI_FileSeek(ctx, newPosition, RW_SEEK_SET);
-    }
-
-    ctx->hidden.androidio.position = newPosition;
-
-    return ctx->hidden.androidio.position;
-}
-
-extern "C" int Android_JNI_FileClose(SDL_RWops* ctx)
-{
-    return Android_JNI_FileClose(ctx, true);
-}
-
-#endif /* __ANDROID__ */
-
-/* vi: set ts=4 sw=4 expandtab: */
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 Sam Lantinga <[email protected]>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+// Modified by Lasse Oorni for Urho3D
+
+#include "SDL_config.h"
+#include "SDL_stdinc.h"
+#include "SDL_assert.h"
+
+#ifdef __ANDROID__
+
+#include "SDL_android.h"
+
+extern "C" {
+#include "../../events/SDL_events_c.h"
+#include "../../video/android/SDL_androidkeyboard.h"
+#include "../../video/android/SDL_androidtouch.h"
+#include "../../video/android/SDL_androidvideo.h"
+
+#include <android/log.h>
+#define LOG_TAG "SDL_android"
+//#define LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+//#define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
+#define LOGI(...) do {} while (false)
+#define LOGE(...) do {} while (false)
+
+
+/* Implemented in audio/android/SDL_androidaudio.c */
+extern void Android_RunAudioThread();
+} // C
+
+/*******************************************************************************
+ This file links the Java side of Android with libsdl
+*******************************************************************************/
+#include <jni.h>
+#include <android/log.h>
+
+
+/*******************************************************************************
+                               Globals
+*******************************************************************************/
+static JNIEnv* mEnv = NULL;
+static JNIEnv* mAudioEnv = NULL;
+static JavaVM* mJavaVM;
+
+// Main activity
+static jclass mActivityClass;
+
+// method signatures
+static jmethodID midCreateGLContext;
+static jmethodID midFlipBuffers;
+static jmethodID midAudioInit;
+static jmethodID midAudioWriteShortBuffer;
+static jmethodID midAudioWriteByteBuffer;
+static jmethodID midAudioQuit;
+
+// Accelerometer data storage
+static float fLastAccelerometer[3];
+static bool bHasNewData;
+
+// Application files dir
+static char* mFilesDir = 0;
+
+/*******************************************************************************
+                 Functions called by JNI
+*******************************************************************************/
+
+// Library init
+extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
+{
+    JNIEnv *env;
+    mJavaVM = vm;
+    LOGI("JNI_OnLoad called");
+    if (mJavaVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+        LOGE("Failed to get the environment using GetEnv()");
+        return -1;
+    }
+
+    return JNI_VERSION_1_4;
+}
+
+extern "C" const char* SDL_Android_GetFilesDir()
+{
+    return mFilesDir;
+}
+
+// Called before SDL_main() to initialize JNI bindings
+extern "C" void SDL_Android_Init(JNIEnv* env, jclass cls, jstring filesDir)
+{
+    __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL_Android_Init()");
+
+    // Copy the files dir
+    const char *str;
+    str = env->GetStringUTFChars(filesDir, 0);
+    if (str)
+    {
+        if (mFilesDir)
+            free(mFilesDir);
+
+        size_t length = strlen(str) + 1;
+        mFilesDir = (char*)malloc(length);
+        memcpy(mFilesDir, str, length);
+        env->ReleaseStringUTFChars(filesDir, str);
+    }
+
+    mEnv = env;
+    mActivityClass = (jclass)env->NewGlobalRef(cls);
+
+    midCreateGLContext = mEnv->GetStaticMethodID(mActivityClass,
+                                "createGLContext","(II)Z");
+    midFlipBuffers = mEnv->GetStaticMethodID(mActivityClass,
+                                "flipBuffers","()V");
+    midAudioInit = mEnv->GetStaticMethodID(mActivityClass,
+                                "audioInit", "(IZZI)Ljava/lang/Object;");
+    midAudioWriteShortBuffer = mEnv->GetStaticMethodID(mActivityClass,
+                                "audioWriteShortBuffer", "([S)V");
+    midAudioWriteByteBuffer = mEnv->GetStaticMethodID(mActivityClass,
+                                "audioWriteByteBuffer", "([B)V");
+    midAudioQuit = mEnv->GetStaticMethodID(mActivityClass,
+                                "audioQuit", "()V");
+
+    bHasNewData = false;
+
+    if(!midCreateGLContext || !midFlipBuffers || !midAudioInit ||
+       !midAudioWriteShortBuffer || !midAudioWriteByteBuffer || !midAudioQuit) {
+        __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL: Couldn't locate Java callbacks, check that they're named and typed correctly");
+    }
+    __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL_Android_Init() finished!");
+}
+
+// Resize
+extern "C" void NATIVE_FUNCTION(onNativeResize)(
+                                    JNIEnv* env, jclass jcls,
+                                    jint width, jint height, jint format)
+{
+    Android_SetScreenResolution(width, height, format);
+}
+
+// Keydown
+extern "C" void NATIVE_FUNCTION(onNativeKeyDown)(
+                                    JNIEnv* env, jclass jcls, jint keycode)
+{
+    Android_OnKeyDown(keycode);
+}
+
+// Keyup
+extern "C" void NATIVE_FUNCTION(onNativeKeyUp)(
+                                    JNIEnv* env, jclass jcls, jint keycode)
+{
+    Android_OnKeyUp(keycode);
+}
+
+// Touch
+extern "C" void NATIVE_FUNCTION(onNativeTouch)(
+                                    JNIEnv* env, jclass jcls,
+                                    jint touch_device_id_in, jint pointer_finger_id_in,
+                                    jint action, jfloat x, jfloat y, jfloat p)
+{
+    Android_OnTouch(touch_device_id_in, pointer_finger_id_in, action, x, y, p);
+}
+
+// Accelerometer
+extern "C" void NATIVE_FUNCTION(onNativeAccel)(
+                                    JNIEnv* env, jclass jcls,
+                                    jfloat x, jfloat y, jfloat z)
+{
+    fLastAccelerometer[0] = x;
+    fLastAccelerometer[1] = y;
+    fLastAccelerometer[2] = z;
+    bHasNewData = true;
+}
+
+// Quit
+extern "C" void NATIVE_FUNCTION(nativeQuit)(
+                                    JNIEnv* env, jclass cls)
+{    
+    // Inject a SDL_QUIT event
+    SDL_Event event;
+    event.type=SDL_SYSEVENT_TERMINATE;
+    event.sysevent.data=NULL;
+    if (SDL_SysEventHandler)
+        SDL_SysEventHandler(&event);
+    else SDL_SendQuit();
+}
+
+// Pause
+extern "C" void NATIVE_FUNCTION(nativePause)(
+                                    JNIEnv* env, jclass cls)
+{
+    SDL_Event event;
+    event.type=SDL_SYSEVENT_WILL_SUSPEND;
+    event.sysevent.data=NULL;
+    if (SDL_SysEventHandler)
+        SDL_SysEventHandler(&event);
+    event.type=SDL_SYSEVENT_SUSPEND;
+    event.sysevent.data=NULL;
+    if (SDL_SysEventHandler)
+        SDL_SysEventHandler(&event);
+    else if (Android_Window) {
+        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
+        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
+    }
+}
+
+// Resume
+extern "C" void NATIVE_FUNCTION(nativeResume)(
+                                    JNIEnv* env, jclass cls)
+{
+    SDL_Event event;
+    event.type=SDL_SYSEVENT_WILL_RESUME;
+    event.sysevent.data=NULL;
+    if (SDL_SysEventHandler)
+        SDL_SysEventHandler(&event);
+    event.type=SDL_SYSEVENT_RESUME;
+    event.sysevent.data=NULL;
+    if (SDL_SysEventHandler)
+        SDL_SysEventHandler(&event);
+    else if (Android_Window) {
+        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
+        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_RESTORED, 0, 0);
+    }
+}
+
+extern "C" void NATIVE_FUNCTION(nativeRunAudioThread)(
+                                    JNIEnv* env, jclass cls)
+{
+    /* This is the audio thread, with a different environment */
+    mAudioEnv = env;
+
+    Android_RunAudioThread();
+}
+
+// Surface destroyed
+extern "C" void NATIVE_FUNCTION(onNativeSurfaceDestroyed)(
+                                    JNIEnv* env, jclass cls)
+{
+    if (Android_Window) {
+        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_SURFACE_LOST, 0, 0);
+    }
+}
+
+// Surface created
+extern "C" void NATIVE_FUNCTION(onNativeSurfaceCreated)(
+                                    JNIEnv* env, jclass cls)
+{
+    if (Android_Window) {
+        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_SURFACE_CREATED, 0, 0);
+    }
+}
+
+/*******************************************************************************
+             Functions called by SDL into Java
+*******************************************************************************/
+
+class LocalReferenceHolder
+{
+private:
+    static int s_active;
+
+public:
+    static bool IsActive() {
+        return s_active > 0;
+    }
+
+public:
+    LocalReferenceHolder() : m_env(NULL) { }
+    ~LocalReferenceHolder() {
+        if (m_env) {
+            m_env->PopLocalFrame(NULL);
+            --s_active;
+        }
+    }
+
+    bool init(JNIEnv *env, jint capacity = 16) {
+        if (env->PushLocalFrame(capacity) < 0) {
+            SDL_SetError("Failed to allocate enough JVM local references");
+            return false;
+        }
+        ++s_active;
+        m_env = env;
+        return true;
+    }
+
+protected:
+    JNIEnv *m_env;
+};
+int LocalReferenceHolder::s_active;
+
+extern "C" SDL_bool Android_JNI_CreateContext(int majorVersion, int minorVersion)
+{
+    if (mEnv->CallStaticBooleanMethod(mActivityClass, midCreateGLContext, majorVersion, minorVersion)) {
+        return SDL_TRUE;
+    } else {
+        return SDL_FALSE;
+    }
+}
+
+extern "C" void Android_JNI_SwapWindow()
+{
+    mEnv->CallStaticVoidMethod(mActivityClass, midFlipBuffers); 
+}
+
+extern "C" void Android_JNI_SetActivityTitle(const char *title)
+{
+    jmethodID mid;
+
+    mid = mEnv->GetStaticMethodID(mActivityClass,"setActivityTitle","(Ljava/lang/String;)V");
+    if (mid) {
+        jstring jtitle = reinterpret_cast<jstring>(mEnv->NewStringUTF(title));
+        mEnv->CallStaticVoidMethod(mActivityClass, mid, jtitle);
+        mEnv->DeleteLocalRef(jtitle);
+    }
+}
+
+extern "C" SDL_bool Android_JNI_GetAccelerometerValues(float values[3])
+{
+    int i;
+    SDL_bool retval = SDL_FALSE;
+
+    if (bHasNewData) {
+        for (i = 0; i < 3; ++i) {
+            values[i] = fLastAccelerometer[i];
+        }
+        bHasNewData = false;
+        retval = SDL_TRUE;
+    }
+
+    return retval;
+}
+
+//
+// Audio support
+//
+static jboolean audioBuffer16Bit = JNI_FALSE;
+static jboolean audioBufferStereo = JNI_FALSE;
+static jobject audioBuffer = NULL;
+static void* audioBufferPinned = NULL;
+
+extern "C" int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames)
+{
+    int audioBufferFrames;
+
+    int status;
+    JNIEnv *env;
+    static bool isAttached = false;    
+    status = mJavaVM->GetEnv((void **) &env, JNI_VERSION_1_4);
+    if(status < 0) {
+        LOGE("callback_handler: failed to get JNI environment, assuming native thread");
+        status = mJavaVM->AttachCurrentThread(&env, NULL);
+        if(status < 0) {
+            LOGE("callback_handler: failed to attach current thread");
+            return 0;
+        }
+        isAttached = true;
+    }
+
+    
+    __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");
+    audioBuffer16Bit = is16Bit;
+    audioBufferStereo = channelCount > 1;
+
+    audioBuffer = env->CallStaticObjectMethod(mActivityClass, midAudioInit, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames);
+
+    if (audioBuffer == NULL) {
+        __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: didn't get back a good audio buffer!");
+        return 0;
+    }
+    audioBuffer = env->NewGlobalRef(audioBuffer);
+
+    jboolean isCopy = JNI_FALSE;
+    if (audioBuffer16Bit) {
+        audioBufferPinned = env->GetShortArrayElements((jshortArray)audioBuffer, &isCopy);
+        audioBufferFrames = env->GetArrayLength((jshortArray)audioBuffer);
+    } else {
+        audioBufferPinned = env->GetByteArrayElements((jbyteArray)audioBuffer, &isCopy);
+        audioBufferFrames = env->GetArrayLength((jbyteArray)audioBuffer);
+    }
+    if (audioBufferStereo) {
+        audioBufferFrames /= 2;
+    }
+ 
+    if (isAttached) {
+        mJavaVM->DetachCurrentThread();
+    }
+
+    return audioBufferFrames;
+}
+
+extern "C" void * Android_JNI_GetAudioBuffer()
+{
+    return audioBufferPinned;
+}
+
+extern "C" void Android_JNI_WriteAudioBuffer()
+{
+    if (audioBuffer16Bit) {
+        mAudioEnv->ReleaseShortArrayElements((jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT);
+        mAudioEnv->CallStaticVoidMethod(mActivityClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer);
+    } else {
+        mAudioEnv->ReleaseByteArrayElements((jbyteArray)audioBuffer, (jbyte *)audioBufferPinned, JNI_COMMIT);
+        mAudioEnv->CallStaticVoidMethod(mActivityClass, midAudioWriteByteBuffer, (jbyteArray)audioBuffer);
+    }
+
+    /* JNI_COMMIT means the changes are committed to the VM but the buffer remains pinned */
+}
+
+extern "C" void Android_JNI_CloseAudioDevice()
+{
+    int status;
+    JNIEnv *env;
+    static bool isAttached = false;    
+    status = mJavaVM->GetEnv((void **) &env, JNI_VERSION_1_4);
+    if(status < 0) {
+        LOGE("callback_handler: failed to get JNI environment, assuming native thread");
+        status = mJavaVM->AttachCurrentThread(&env, NULL);
+        if(status < 0) {
+            LOGE("callback_handler: failed to attach current thread");
+            return;
+        }
+        isAttached = true;
+    }
+
+    env->CallStaticVoidMethod(mActivityClass, midAudioQuit); 
+
+    if (audioBuffer) {
+        env->DeleteGlobalRef(audioBuffer);
+        audioBuffer = NULL;
+        audioBufferPinned = NULL;
+    }
+
+    if (isAttached) {
+        mJavaVM->DetachCurrentThread();
+    }
+}
+
+// Test for an exception and call SDL_SetError with its detail if one occurs
+static bool Android_JNI_ExceptionOccurred()
+{
+    SDL_assert(LocalReferenceHolder::IsActive());
+
+    jthrowable exception = mEnv->ExceptionOccurred();
+    if (exception != NULL) {
+        jmethodID mid;
+
+        // Until this happens most JNI operations have undefined behaviour
+        mEnv->ExceptionClear();
+
+        jclass exceptionClass = mEnv->GetObjectClass(exception);
+        jclass classClass = mEnv->FindClass("java/lang/Class");
+
+        mid = mEnv->GetMethodID(classClass, "getName", "()Ljava/lang/String;");
+        jstring exceptionName = (jstring)mEnv->CallObjectMethod(exceptionClass, mid);
+        const char* exceptionNameUTF8 = mEnv->GetStringUTFChars(exceptionName, 0);
+
+        mid = mEnv->GetMethodID(exceptionClass, "getMessage", "()Ljava/lang/String;");
+        jstring exceptionMessage = (jstring)mEnv->CallObjectMethod(exception, mid);
+
+        if (exceptionMessage != NULL) {
+            const char* exceptionMessageUTF8 = mEnv->GetStringUTFChars(
+                    exceptionMessage, 0);
+            SDL_SetError("%s: %s", exceptionNameUTF8, exceptionMessageUTF8);
+            mEnv->ReleaseStringUTFChars(exceptionMessage, exceptionMessageUTF8);
+        } else {
+            SDL_SetError("%s", exceptionNameUTF8);
+        }
+
+        mEnv->ReleaseStringUTFChars(exceptionName, exceptionNameUTF8);
+
+        return true;
+    }
+
+    return false;
+}
+
+static int Android_JNI_FileOpen(SDL_RWops* ctx)
+{
+    LocalReferenceHolder refs;
+    int result = 0;
+
+    jmethodID mid;
+    jobject context;
+    jobject assetManager;
+    jobject inputStream;
+    jclass channels;
+    jobject readableByteChannel;
+    jstring fileNameJString;
+
+    if (!refs.init(mEnv)) {
+        goto failure;
+    }
+
+    fileNameJString = (jstring)ctx->hidden.androidio.fileNameRef;
+
+    // context = SDLActivity.getContext();
+    mid = mEnv->GetStaticMethodID(mActivityClass,
+            "getContext","()Landroid/content/Context;");
+    context = mEnv->CallStaticObjectMethod(mActivityClass, mid);
+
+    // assetManager = context.getAssets();
+    mid = mEnv->GetMethodID(mEnv->GetObjectClass(context),
+            "getAssets", "()Landroid/content/res/AssetManager;");
+    assetManager = mEnv->CallObjectMethod(context, mid);
+
+    // inputStream = assetManager.open(<filename>);
+    mid = mEnv->GetMethodID(mEnv->GetObjectClass(assetManager),
+            "open", "(Ljava/lang/String;)Ljava/io/InputStream;");
+    inputStream = mEnv->CallObjectMethod(assetManager, mid, fileNameJString);
+    if (Android_JNI_ExceptionOccurred()) {
+        goto failure;
+    }
+
+    ctx->hidden.androidio.inputStreamRef = mEnv->NewGlobalRef(inputStream);
+
+    // Despite all the visible documentation on [Asset]InputStream claiming
+    // that the .available() method is not guaranteed to return the entire file
+    // size, comments in <sdk>/samples/<ver>/ApiDemos/src/com/example/ ...
+    // android/apis/content/ReadAsset.java imply that Android's
+    // AssetInputStream.available() /will/ always return the total file size
+
+    // size = inputStream.available();
+    mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream),
+            "available", "()I");
+    ctx->hidden.androidio.size = mEnv->CallIntMethod(inputStream, mid);
+    if (Android_JNI_ExceptionOccurred()) {
+        goto failure;
+    }
+
+    // readableByteChannel = Channels.newChannel(inputStream);
+    channels = mEnv->FindClass("java/nio/channels/Channels");
+    mid = mEnv->GetStaticMethodID(channels,
+            "newChannel",
+            "(Ljava/io/InputStream;)Ljava/nio/channels/ReadableByteChannel;");
+    readableByteChannel = mEnv->CallStaticObjectMethod(
+            channels, mid, inputStream);
+    if (Android_JNI_ExceptionOccurred()) {
+        goto failure;
+    }
+
+    ctx->hidden.androidio.readableByteChannelRef =
+        mEnv->NewGlobalRef(readableByteChannel);
+
+    // Store .read id for reading purposes
+    mid = mEnv->GetMethodID(mEnv->GetObjectClass(readableByteChannel),
+            "read", "(Ljava/nio/ByteBuffer;)I");
+    ctx->hidden.androidio.readMethod = mid;
+
+    ctx->hidden.androidio.position = 0;
+
+    if (false) {
+failure:
+        result = -1;
+
+        mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.fileNameRef);
+
+        if(ctx->hidden.androidio.inputStreamRef != NULL) {
+            mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.inputStreamRef);
+        }
+
+        if(ctx->hidden.androidio.readableByteChannelRef != NULL) {
+            mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.readableByteChannelRef);
+        }
+
+    }
+
+    return result;
+}
+
+extern "C" int Android_JNI_FileOpen(SDL_RWops* ctx,
+        const char* fileName, const char*)
+{
+    LocalReferenceHolder refs;
+
+    if (!refs.init(mEnv)) {
+        return -1;
+    }
+
+    if (!ctx) {
+        return -1;
+    }
+
+    jstring fileNameJString = mEnv->NewStringUTF(fileName);
+    ctx->hidden.androidio.fileNameRef = mEnv->NewGlobalRef(fileNameJString);
+    ctx->hidden.androidio.inputStreamRef = NULL;
+
+    return Android_JNI_FileOpen(ctx);
+}
+
+extern "C" size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer,
+        size_t size, size_t maxnum)
+{
+    LocalReferenceHolder refs;
+    int bytesRemaining = size * maxnum;
+    int bytesRead = 0;
+
+    if (!refs.init(mEnv)) {
+        return -1;
+    }
+
+    jobject readableByteChannel = (jobject)ctx->hidden.androidio.readableByteChannelRef;
+    jmethodID readMethod = (jmethodID)ctx->hidden.androidio.readMethod;
+    jobject byteBuffer = mEnv->NewDirectByteBuffer(buffer, bytesRemaining);
+
+    while (bytesRemaining > 0) {
+        // result = readableByteChannel.read(...);
+        int result = mEnv->CallIntMethod(readableByteChannel, readMethod, byteBuffer);
+
+        if (Android_JNI_ExceptionOccurred()) {
+            return 0;
+        }
+
+        if (result < 0) {
+            break;
+        }
+
+        bytesRemaining -= result;
+        bytesRead += result;
+        ctx->hidden.androidio.position += result;
+    }
+
+    return bytesRead / size;
+}
+
+extern "C" size_t Android_JNI_FileWrite(SDL_RWops* ctx, const void* buffer,
+        size_t size, size_t num)
+{
+    SDL_SetError("Cannot write to Android package filesystem");
+    return 0;
+}
+
+static int Android_JNI_FileClose(SDL_RWops* ctx, bool release)
+{
+    LocalReferenceHolder refs;
+    int result = 0;
+
+    if (!refs.init(mEnv)) {
+        SDL_SetError("Failed to allocate enough JVM local references");
+        return -1;
+    }
+
+    if (ctx) {
+        if (release) {
+            mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.fileNameRef);
+        }
+
+        jobject inputStream = (jobject)ctx->hidden.androidio.inputStreamRef;
+
+        // inputStream.close();
+        jmethodID mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream),
+                "close", "()V");
+        mEnv->CallVoidMethod(inputStream, mid);
+        mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.inputStreamRef);
+        mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.readableByteChannelRef);
+        if (Android_JNI_ExceptionOccurred()) {
+            result = -1;
+        }
+
+        if (release) {
+            SDL_FreeRW(ctx);
+        }
+    }
+
+    return result;
+}
+
+
+extern "C" long Android_JNI_FileSeek(SDL_RWops* ctx, long offset, int whence)
+{
+    long newPosition;
+
+    switch (whence) {
+        case RW_SEEK_SET:
+            newPosition = offset;
+            break;
+        case RW_SEEK_CUR:
+            newPosition = ctx->hidden.androidio.position + offset;
+            break;
+        case RW_SEEK_END:
+            newPosition = ctx->hidden.androidio.size + offset;
+            break;
+        default:
+            SDL_SetError("Unknown value for 'whence'");
+            return -1;
+    }
+    if (newPosition < 0) {
+        newPosition = 0;
+    }
+    if (newPosition > ctx->hidden.androidio.size) {
+        newPosition = ctx->hidden.androidio.size;
+    }
+
+    long movement = newPosition - ctx->hidden.androidio.position;
+    jobject inputStream = (jobject)ctx->hidden.androidio.inputStreamRef;
+
+    if (movement > 0) {
+        unsigned char buffer[1024];
+
+        // The easy case where we're seeking forwards
+        while (movement > 0) {
+            long amount = (long) sizeof (buffer);
+            if (amount > movement) {
+                amount = movement;
+            }
+            size_t result = Android_JNI_FileRead(ctx, buffer, 1, amount);
+
+            if (result <= 0) {
+                // Failed to read/skip the required amount, so fail
+                return -1;
+            }
+
+            movement -= result;
+        }
+    } else if (movement < 0) {
+        // We can't seek backwards so we have to reopen the file and seek
+        // forwards which obviously isn't very efficient
+        Android_JNI_FileClose(ctx, false);
+        Android_JNI_FileOpen(ctx);
+        Android_JNI_FileSeek(ctx, newPosition, RW_SEEK_SET);
+    }
+
+    ctx->hidden.androidio.position = newPosition;
+
+    return ctx->hidden.androidio.position;
+}
+
+extern "C" int Android_JNI_FileClose(SDL_RWops* ctx)
+{
+    return Android_JNI_FileClose(ctx, true);
+}
+
+#endif /* __ANDROID__ */
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 1 - 1
ThirdParty/SDL/src/main/android/SDL_android_main.cpp

@@ -1,4 +1,4 @@
-// Modified by Lasse Öörni for Urho3D
+// Modified by Lasse Oorni for Urho3D
 
 #include "SDL_config.h"
 

+ 1 - 1
ThirdParty/SDL/src/video/android/SDL_androidwindow.c

@@ -19,7 +19,7 @@
   3. This notice may not be removed or altered from any source distribution.
 */
 
-// Modified by Lasse Öörni for Urho3D
+// Modified by Lasse Oorni for Urho3D
 
 #include "SDL_config.h"
 

+ 198 - 198
ThirdParty/SDL/src/video/cocoa/SDL_cocoamouse.m

@@ -1,198 +1,198 @@
-/*
-  Simple DirectMedia Layer
-  Copyright (C) 1997-2012 Sam Lantinga <[email protected]>
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-*/
-
-// Modified by Lasse Öörni for Urho3D
-
-#include "SDL_config.h"
-
-#if SDL_VIDEO_DRIVER_COCOA
-
-#include "SDL_events.h"
-#include "SDL_cocoavideo.h"
-
-#include "../../events/SDL_mouse_c.h"
-
-
-static SDL_Cursor *
-Cocoa_CreateDefaultCursor()
-{
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSCursor *nscursor;
-    SDL_Cursor *cursor = NULL;
-
-    nscursor = [NSCursor arrowCursor];
-
-    if (nscursor) {
-        cursor = SDL_calloc(1, sizeof(*cursor));
-        if (cursor) {
-            cursor->driverdata = nscursor;
-            [nscursor retain];
-        }
-    }
-
-    [pool release];
-
-    return cursor;
-}
-
-static SDL_Cursor *
-Cocoa_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
-{
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSImage *nsimage;
-    NSCursor *nscursor = NULL;
-    SDL_Cursor *cursor = NULL;
-
-    nsimage = Cocoa_CreateImage(surface);
-    if (nsimage) {
-        nscursor = [[NSCursor alloc] initWithImage: nsimage hotSpot: NSMakePoint(hot_x, hot_y)];
-    }
-
-    if (nscursor) {
-        cursor = SDL_calloc(1, sizeof(*cursor));
-        if (cursor) {
-            cursor->driverdata = nscursor;
-        }
-    }
-
-    [pool release];
-
-    return cursor;
-}
-
-static void
-Cocoa_FreeCursor(SDL_Cursor * cursor)
-{
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSCursor *nscursor = (NSCursor *)cursor->driverdata;
-
-    [nscursor release];
-    SDL_free(cursor);
-
-    [pool release];
-}
-
-static int
-Cocoa_ShowCursor(SDL_Cursor * cursor)
-{
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
-    if (cursor) {
-        NSCursor *nscursor = (NSCursor *)cursor->driverdata;
-
-        [nscursor set];
-        [NSCursor unhide];
-    } else {
-        [NSCursor hide];
-    }
-
-    [pool release];
-
-    return 0;
-}
-
-static void
-Cocoa_WarpMouse(SDL_Window * window, int x, int y)
-{
-    CGPoint point;
-
-    point.x = (float)window->x + x;
-    point.y = (float)window->y + y;
-    CGWarpMouseCursorPosition(point);
-}
-
-static int
-Cocoa_SetRelativeMouseMode(SDL_bool enabled)
-{
-    CGError result;
-
-    if (enabled) {
-        result = CGAssociateMouseAndMouseCursorPosition(NO);
-    } else {
-        result = CGAssociateMouseAndMouseCursorPosition(YES);
-    }
-    if (result != kCGErrorSuccess) {
-        SDL_SetError("CGAssociateMouseAndMouseCursorPosition() failed");
-        return -1;
-    }
-    return 0;
-}
-
-void
-Cocoa_InitMouse(_THIS)
-{
-    SDL_Mouse *mouse = SDL_GetMouse();
-
-    mouse->CreateCursor = Cocoa_CreateCursor;
-    mouse->ShowCursor = Cocoa_ShowCursor;
-    mouse->FreeCursor = Cocoa_FreeCursor;
-    mouse->WarpMouse = Cocoa_WarpMouse;
-    mouse->SetRelativeMouseMode = Cocoa_SetRelativeMouseMode;
-
-    SDL_SetDefaultCursor(Cocoa_CreateDefaultCursor());
-
-    // Urho3D: disable event suppression interval, otherwise mouse moves will be disabled for some time
-    CGSetLocalEventsSuppressionInterval(0.0);
-}
-
-void
-Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
-{
-    SDL_Mouse *mouse = SDL_GetMouse();
-
-    if (mouse->relative_mode &&
-        ([event type] == NSMouseMoved ||
-         [event type] == NSLeftMouseDragged ||
-         [event type] == NSRightMouseDragged ||
-         [event type] == NSOtherMouseDragged)) {
-        float x = [event deltaX];
-        float y = [event deltaY];
-        SDL_SendMouseMotion(mouse->focus, 1, (int)x, (int)y);
-    }
-}
-
-void
-Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
-{
-    float x = [event deltaX];
-    float y = [event deltaY];
-
-    if (x > 0) {
-        x += 0.9f;
-    } else if (x < 0) {
-        x -= 0.9f;
-    }
-    if (y > 0) {
-        y += 0.9f;
-    } else if (y < 0) {
-        y -= 0.9f;
-    }
-    SDL_SendMouseWheel(window, (int)x, (int)y);
-}
-
-void
-Cocoa_QuitMouse(_THIS)
-{
-}
-
-#endif /* SDL_VIDEO_DRIVER_COCOA */
-
-/* vi: set ts=4 sw=4 expandtab: */
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 Sam Lantinga <[email protected]>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+// Modified by Lasse Oorni for Urho3D
+
+#include "SDL_config.h"
+
+#if SDL_VIDEO_DRIVER_COCOA
+
+#include "SDL_events.h"
+#include "SDL_cocoavideo.h"
+
+#include "../../events/SDL_mouse_c.h"
+
+
+static SDL_Cursor *
+Cocoa_CreateDefaultCursor()
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    NSCursor *nscursor;
+    SDL_Cursor *cursor = NULL;
+
+    nscursor = [NSCursor arrowCursor];
+
+    if (nscursor) {
+        cursor = SDL_calloc(1, sizeof(*cursor));
+        if (cursor) {
+            cursor->driverdata = nscursor;
+            [nscursor retain];
+        }
+    }
+
+    [pool release];
+
+    return cursor;
+}
+
+static SDL_Cursor *
+Cocoa_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    NSImage *nsimage;
+    NSCursor *nscursor = NULL;
+    SDL_Cursor *cursor = NULL;
+
+    nsimage = Cocoa_CreateImage(surface);
+    if (nsimage) {
+        nscursor = [[NSCursor alloc] initWithImage: nsimage hotSpot: NSMakePoint(hot_x, hot_y)];
+    }
+
+    if (nscursor) {
+        cursor = SDL_calloc(1, sizeof(*cursor));
+        if (cursor) {
+            cursor->driverdata = nscursor;
+        }
+    }
+
+    [pool release];
+
+    return cursor;
+}
+
+static void
+Cocoa_FreeCursor(SDL_Cursor * cursor)
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    NSCursor *nscursor = (NSCursor *)cursor->driverdata;
+
+    [nscursor release];
+    SDL_free(cursor);
+
+    [pool release];
+}
+
+static int
+Cocoa_ShowCursor(SDL_Cursor * cursor)
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+    if (cursor) {
+        NSCursor *nscursor = (NSCursor *)cursor->driverdata;
+
+        [nscursor set];
+        [NSCursor unhide];
+    } else {
+        [NSCursor hide];
+    }
+
+    [pool release];
+
+    return 0;
+}
+
+static void
+Cocoa_WarpMouse(SDL_Window * window, int x, int y)
+{
+    CGPoint point;
+
+    point.x = (float)window->x + x;
+    point.y = (float)window->y + y;
+    CGWarpMouseCursorPosition(point);
+}
+
+static int
+Cocoa_SetRelativeMouseMode(SDL_bool enabled)
+{
+    CGError result;
+
+    if (enabled) {
+        result = CGAssociateMouseAndMouseCursorPosition(NO);
+    } else {
+        result = CGAssociateMouseAndMouseCursorPosition(YES);
+    }
+    if (result != kCGErrorSuccess) {
+        SDL_SetError("CGAssociateMouseAndMouseCursorPosition() failed");
+        return -1;
+    }
+    return 0;
+}
+
+void
+Cocoa_InitMouse(_THIS)
+{
+    SDL_Mouse *mouse = SDL_GetMouse();
+
+    mouse->CreateCursor = Cocoa_CreateCursor;
+    mouse->ShowCursor = Cocoa_ShowCursor;
+    mouse->FreeCursor = Cocoa_FreeCursor;
+    mouse->WarpMouse = Cocoa_WarpMouse;
+    mouse->SetRelativeMouseMode = Cocoa_SetRelativeMouseMode;
+
+    SDL_SetDefaultCursor(Cocoa_CreateDefaultCursor());
+
+    // Urho3D: disable event suppression interval, otherwise mouse moves will be disabled for some time
+    CGSetLocalEventsSuppressionInterval(0.0);
+}
+
+void
+Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
+{
+    SDL_Mouse *mouse = SDL_GetMouse();
+
+    if (mouse->relative_mode &&
+        ([event type] == NSMouseMoved ||
+         [event type] == NSLeftMouseDragged ||
+         [event type] == NSRightMouseDragged ||
+         [event type] == NSOtherMouseDragged)) {
+        float x = [event deltaX];
+        float y = [event deltaY];
+        SDL_SendMouseMotion(mouse->focus, 1, (int)x, (int)y);
+    }
+}
+
+void
+Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
+{
+    float x = [event deltaX];
+    float y = [event deltaY];
+
+    if (x > 0) {
+        x += 0.9f;
+    } else if (x < 0) {
+        x -= 0.9f;
+    }
+    if (y > 0) {
+        y += 0.9f;
+    } else if (y < 0) {
+        y -= 0.9f;
+    }
+    SDL_SendMouseWheel(window, (int)x, (int)y);
+}
+
+void
+Cocoa_QuitMouse(_THIS)
+{
+}
+
+#endif /* SDL_VIDEO_DRIVER_COCOA */
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 1 - 1
ThirdParty/SDL/src/video/cocoa/SDL_cocoawindow.m

@@ -19,7 +19,7 @@
   3. This notice may not be removed or altered from any source distribution.
 */
 
-// Modified by Lasse Öörni for Urho3D
+// Modified by Lasse Oorni for Urho3D
 
 #include "SDL_config.h"
 

+ 1 - 1
ThirdParty/SDL/src/video/uikit/SDL_uikitappdelegate.m

@@ -19,7 +19,7 @@
   3. This notice may not be removed or altered from any source distribution.
 */
 
-// Modified by Lasse Öörni for Urho3D
+// Modified by Lasse Oorni for Urho3D
 
 #include "SDL_config.h"
 

+ 1 - 1
ThirdParty/SDL/src/video/uikit/SDL_uikitview.m

@@ -19,7 +19,7 @@
   3. This notice may not be removed or altered from any source distribution.
 */
 
-// Modified by Lasse Öörni for Urho3D
+// Modified by Lasse Oorni for Urho3D
 
 #include "SDL_config.h"
 

+ 4 - 4
ThirdParty/kNet/CMakeLists.txt

@@ -12,7 +12,7 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
-# Modified by Lasse Öörni for Urho3D
+# Modified by Lasse Oorni for Urho3D
 
 # Generate a build configuration file to ensure the build flags match for the user of the library.
 SET(BUILD_CONFIG_FILE include/kNetBuildConfig.h)
@@ -159,13 +159,13 @@ elseif (UNIX)
    add_definitions(-DUNIX)
 endif()
 
-# Urho3D: set DEBUG_CPP_NAME only on Windows, at least Xcode project file can not be opened if this is included
-if (WIN32)
+# Urho3D: set DEBUG_CPP_NAME only on Windows, at least Xcode project file can not be opened if this is included
+if (WIN32)
     foreach(srcFile ${kNetSourceFiles})
         get_filename_component(baseName ${srcFile} NAME)
         set_source_files_properties(${srcFile} PROPERTIES COMPILE_FLAGS "-DDEBUG_CPP_NAME=\"\\\"${baseName}\"\\\"")
     endforeach()
-endif ()
+endif ()
 
 add_library(kNet STATIC ${kNetSourceFiles} ${kNetHeaderFiles})