Browse Source

Updated to stable SDL 2.0.

Lasse Öörni 12 years ago
parent
commit
5bfde24e0b
100 changed files with 10922 additions and 5909 deletions
  1. 920 810
      Source/Android/src/org/libsdl/app/SDLActivity.java
  2. 1 1
      Source/ThirdParty/SDL/CMakeLists.txt
  3. 23 42
      Source/ThirdParty/SDL/CREDITS.txt
  4. 11 12
      Source/ThirdParty/SDL/README.txt
  5. 6 5
      Source/ThirdParty/SDL/include/SDL.h
  6. 47 0
      Source/ThirdParty/SDL/include/SDL_atomic.h
  7. 12 7
      Source/ThirdParty/SDL/include/SDL_audio.h
  8. 11 4
      Source/ThirdParty/SDL/include/SDL_bits.h
  9. 11 4
      Source/ThirdParty/SDL/include/SDL_blendmode.h
  10. 5 5
      Source/ThirdParty/SDL/include/SDL_config.h
  11. 2 4
      Source/ThirdParty/SDL/include/SDL_config_android.h
  12. 0 3
      Source/ThirdParty/SDL/include/SDL_config_macosx.h
  13. 2 3
      Source/ThirdParty/SDL/include/SDL_config_windows.h
  14. 4 0
      Source/ThirdParty/SDL/include/SDL_gamecontroller.h
  15. 42 12
      Source/ThirdParty/SDL/include/SDL_haptic.h
  16. 43 4
      Source/ThirdParty/SDL/include/SDL_hints.h
  17. 4 0
      Source/ThirdParty/SDL/include/SDL_joystick.h
  18. 7 1
      Source/ThirdParty/SDL/include/SDL_platform.h
  19. 4 1
      Source/ThirdParty/SDL/include/SDL_render.h
  20. 2 2
      Source/ThirdParty/SDL/include/SDL_revision.h
  21. 1 1
      Source/ThirdParty/SDL/include/SDL_shape.h
  22. 13 456
      Source/ThirdParty/SDL/include/SDL_stdinc.h
  23. 14 16
      Source/ThirdParty/SDL/include/SDL_surface.h
  24. 1 1
      Source/ThirdParty/SDL/include/SDL_syswm.h
  25. 63 1
      Source/ThirdParty/SDL/include/SDL_thread.h
  26. 11 1
      Source/ThirdParty/SDL/include/SDL_video.h
  27. 63 45
      Source/ThirdParty/SDL/src/SDL.c
  28. 0 6
      Source/ThirdParty/SDL/src/SDL_assert.c
  29. 0 1
      Source/ThirdParty/SDL/src/SDL_assert_c.h
  30. 111 26
      Source/ThirdParty/SDL/src/SDL_hints.c
  31. 19 12
      Source/ThirdParty/SDL/src/SDL_log.c
  32. 14 0
      Source/ThirdParty/SDL/src/atomic/SDL_atomic.c
  33. 32 17
      Source/ThirdParty/SDL/src/audio/SDL_audio.c
  34. 1 2
      Source/ThirdParty/SDL/src/audio/SDL_audiocvt.c
  35. 1 1
      Source/ThirdParty/SDL/src/audio/alsa/SDL_alsa_audio.c
  36. 3 3
      Source/ThirdParty/SDL/src/audio/alsa/SDL_alsa_audio.h
  37. 4 18
      Source/ThirdParty/SDL/src/audio/android/SDL_androidaudio.c
  38. 2 0
      Source/ThirdParty/SDL/src/audio/android/SDL_androidaudio.h
  39. 0 3
      Source/ThirdParty/SDL/src/audio/coreaudio/SDL_coreaudio.h
  40. 44 34
      Source/ThirdParty/SDL/src/audio/directsound/SDL_directsound.c
  41. 4 4
      Source/ThirdParty/SDL/src/audio/disk/SDL_diskaudio.c
  42. 0 129
      Source/ThirdParty/SDL/src/audio/nds/SDL_ndsaudio.c
  43. 39 3
      Source/ThirdParty/SDL/src/audio/pulseaudio/SDL_pulseaudio.c
  44. 329 0
      Source/ThirdParty/SDL/src/audio/sndio/SDL_sndioaudio.c
  45. 13 10
      Source/ThirdParty/SDL/src/audio/sndio/SDL_sndioaudio.h
  46. 43 23
      Source/ThirdParty/SDL/src/audio/winmm/SDL_winmm.c
  47. 1426 1357
      Source/ThirdParty/SDL/src/core/android/SDL_android.c
  48. 1 0
      Source/ThirdParty/SDL/src/core/android/SDL_android.h
  49. 1 1
      Source/ThirdParty/SDL/src/events/SDL_events.c
  50. 2 1
      Source/ThirdParty/SDL/src/events/SDL_gesture.c
  51. 17 0
      Source/ThirdParty/SDL/src/events/SDL_mouse.c
  52. 2 1
      Source/ThirdParty/SDL/src/events/SDL_sysevents.h
  53. 0 41
      Source/ThirdParty/SDL/src/events/nds/SDL_ndsgesture.c
  54. 3 3
      Source/ThirdParty/SDL/src/events/scancodes_darwin.h
  55. 6 6
      Source/ThirdParty/SDL/src/events/scancodes_windows.h
  56. 14 14
      Source/ThirdParty/SDL/src/events/scancodes_xfree86.h
  57. 71 35
      Source/ThirdParty/SDL/src/haptic/SDL_haptic.c
  58. 7 4
      Source/ThirdParty/SDL/src/haptic/darwin/SDL_syshaptic.c
  59. 13 28
      Source/ThirdParty/SDL/src/haptic/dummy/SDL_syshaptic.c
  60. 30 4
      Source/ThirdParty/SDL/src/haptic/linux/SDL_syshaptic.c
  61. 0 330
      Source/ThirdParty/SDL/src/haptic/nds/SDL_syshaptic.c
  62. 105 25
      Source/ThirdParty/SDL/src/haptic/windows/SDL_syshaptic.c
  63. 1 37
      Source/ThirdParty/SDL/src/joystick/SDL_gamecontroller.c
  64. 65 0
      Source/ThirdParty/SDL/src/joystick/SDL_gamecontrollerdb.h
  65. 24 7
      Source/ThirdParty/SDL/src/joystick/SDL_joystick.c
  66. 16 0
      Source/ThirdParty/SDL/src/joystick/darwin/SDL_sysjoystick.c
  67. 0 209
      Source/ThirdParty/SDL/src/joystick/nds/SDL_sysjoystick.c
  68. 11 65
      Source/ThirdParty/SDL/src/libm/math_libm.h
  69. 14 0
      Source/ThirdParty/SDL/src/libm/math_private.h
  70. 1 1
      Source/ThirdParty/SDL/src/loadso/dlopen/SDL_sysloadso.c
  71. 5 0
      Source/ThirdParty/SDL/src/main/android/SDL_android_main.c
  72. 0 19
      Source/ThirdParty/SDL/src/main/android/SDL_android_main.cpp
  73. 4 2
      Source/ThirdParty/SDL/src/main/windows/SDL_windows_main.c
  74. 0 44
      Source/ThirdParty/SDL/src/power/nds/SDL_syspower.c
  75. 26 16
      Source/ThirdParty/SDL/src/render/SDL_render.c
  76. 8 8
      Source/ThirdParty/SDL/src/render/SDL_yuv_sw.c
  77. 376 54
      Source/ThirdParty/SDL/src/render/direct3d/SDL_render_d3d.c
  78. 0 315
      Source/ThirdParty/SDL/src/render/nds/SDL_libgl2D.c
  79. 0 154
      Source/ThirdParty/SDL/src/render/nds/SDL_libgl2D.h
  80. 0 418
      Source/ThirdParty/SDL/src/render/nds/SDL_ndsrender.c
  81. 1 0
      Source/ThirdParty/SDL/src/render/opengl/SDL_glfuncs.h
  82. 11 6
      Source/ThirdParty/SDL/src/render/opengl/SDL_render_gl.c
  83. 1 0
      Source/ThirdParty/SDL/src/render/opengles/SDL_glesfuncs.h
  84. 26 5
      Source/ThirdParty/SDL/src/render/opengles/SDL_render_gles.c
  85. 1 1
      Source/ThirdParty/SDL/src/render/opengles2/SDL_gles2funcs.h
  86. 11 9
      Source/ThirdParty/SDL/src/render/opengles2/SDL_render_gles2.c
  87. 0 2
      Source/ThirdParty/SDL/src/render/software/SDL_render_sw.c
  88. 12 6
      Source/ThirdParty/SDL/src/stdlib/SDL_getenv.c
  89. 4 4
      Source/ThirdParty/SDL/src/stdlib/SDL_iconv.c
  90. 21 10
      Source/ThirdParty/SDL/src/stdlib/SDL_malloc.c
  91. 2 3
      Source/ThirdParty/SDL/src/stdlib/SDL_qsort.c
  92. 123 686
      Source/ThirdParty/SDL/src/stdlib/SDL_stdlib.c
  93. 248 245
      Source/ThirdParty/SDL/src/stdlib/SDL_string.c
  94. 150 0
      Source/ThirdParty/SDL/src/test/SDL_test_assert.c
  95. 1411 0
      Source/ThirdParty/SDL/src/test/SDL_test_common.c
  96. 107 0
      Source/ThirdParty/SDL/src/test/SDL_test_compare.c
  97. 165 0
      Source/ThirdParty/SDL/src/test/SDL_test_crc32.c
  98. 3238 0
      Source/ThirdParty/SDL/src/test/SDL_test_font.c
  99. 524 0
      Source/ThirdParty/SDL/src/test/SDL_test_fuzzer.c
  100. 635 0
      Source/ThirdParty/SDL/src/test/SDL_test_harness.c

+ 920 - 810
Source/Android/src/org/libsdl/app/SDLActivity.java

@@ -1,810 +1,920 @@
-// Modified by Lasse Oorni for Urho3D
-
-package org.libsdl.app;
-
-import javax.microedition.khronos.egl.EGL10;
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.egl.EGLContext;
-import javax.microedition.khronos.egl.EGLDisplay;
-import javax.microedition.khronos.egl.EGLSurface;
-
-import android.app.*;
-import android.content.*;
-import android.view.*;
-import android.view.inputmethod.BaseInputConnection;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputConnection;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.AbsoluteLayout;
-import android.os.*;
-import android.util.Log;
-import android.graphics.*;
-import android.media.*;
-import android.hardware.*;
-
-
-/**
-    SDL Activity
-*/
-public class SDLActivity extends Activity {
-    private static final String TAG = "SDL";
-
-    // Keep track of the paused state
-    public static boolean mIsPaused = false;
-
-    // Main components
-    protected static SDLActivity mSingleton;
-    protected static SDLSurface mSurface;
-    protected static View mTextEdit;
-    protected static ViewGroup mLayout;
-
-    // This is what SDL runs in. It invokes SDL_main(), eventually
-    protected static Thread mSDLThread;
-
-    // Audio
-    protected static Thread mAudioThread;
-    protected static AudioTrack mAudioTrack;
-
-    // EGL objects
-    protected static EGLContext  mEGLContext;
-    protected static EGLSurface  mEGLSurface;
-    protected static EGLDisplay  mEGLDisplay;
-    protected static EGLConfig   mEGLConfig;
-    protected static int mGLMajor, mGLMinor;
-
-    // Load the .so
-    static {
-		// Urho3D: everything resides in urho3d.so
-        System.loadLibrary("Urho3D");
-    }
-
-    // Setup
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        //Log.v("SDL", "onCreate()");
-        super.onCreate(savedInstanceState);
-        
-        // So we can call stuff from static callbacks
-        mSingleton = this;
-        
-        // Urho3D: reset paused status
-        mIsPaused = false;
-
-        // Set up the surface
-        mSurface = new SDLSurface(getApplication());
-
-        mLayout = new AbsoluteLayout(this);
-        mLayout.addView(mSurface);
-
-        setContentView(mLayout);
-    }
-
-    // Events
-    @Override
-    protected void onPause() {
-        Log.v("SDL", "onPause()");
-        super.onPause();
-        // Don't call SDLActivity.nativePause(); here, it will be called by SDLSurface::surfaceDestroyed
-    }
-
-    @Override
-    protected void onResume() {
-        Log.v("SDL", "onResume()");
-        super.onResume();
-        // Don't call SDLActivity.nativeResume(); here, it will be called via SDLSurface::surfaceChanged->SDLActivity::startApp
-    }
-
-    @Override
-    public void onLowMemory() {
-        Log.v("SDL", "onLowMemory()");
-        super.onLowMemory();
-        SDLActivity.nativeLowMemory();
-    }
-
-    @Override
-    protected void onDestroy() {
-        super.onDestroy();
-        Log.v("SDL", "onDestroy()");
-        // Send a quit message to the application
-        SDLActivity.nativeQuit();
-
-        // Now wait for the SDL thread to quit
-        if (mSDLThread != null) {
-            try {
-                mSDLThread.join();
-            } catch(Exception e) {
-                Log.v("SDL", "Problem stopping thread: " + e);
-            }
-            mSDLThread = null;
-
-            //Log.v("SDL", "Finished waiting for SDL thread");
-        }
-    }
-
-    // Messages from the SDLMain thread
-    static final int COMMAND_CHANGE_TITLE = 1;
-    static final int COMMAND_UNUSED = 2;
-    static final int COMMAND_TEXTEDIT_HIDE = 3;
-    // Urho3D: added
-    static final int COMMAND_FINISH = 4;
-
-    protected static final int COMMAND_USER = 0x8000;
-
-    /**
-     * This method is called by SDL if SDL did not handle a message itself.
-     * This happens if a received message contains an unsupported command.
-     * Method can be overwritten to handle Messages in a different class.
-     * @param command the command of the message.
-     * @param param the parameter of the message. May be null.
-     * @return if the message was handled in overridden method.
-     */
-    protected boolean onUnhandledMessage(int command, Object param) {
-        return false;
-    }
-
-    /**
-     * A Handler class for Messages from native SDL applications.
-     * It uses current Activities as target (e.g. for the title).
-     * static to prevent implicit references to enclosing object.
-     */
-    protected static class SDLCommandHandler extends Handler {
-        @Override
-        public void handleMessage(Message msg) {
-            Context context = getContext();
-            if (context == null) {
-                Log.e(TAG, "error handling message, getContext() returned null");
-                return;
-            }
-            switch (msg.arg1) {
-            case COMMAND_CHANGE_TITLE:
-                if (context instanceof Activity) {
-                    ((Activity) context).setTitle((String)msg.obj);
-                } else {
-                    Log.e(TAG, "error handling message, getContext() returned no Activity");
-                }
-                break;
-            case COMMAND_TEXTEDIT_HIDE:
-                if (mTextEdit != null) {
-                    mTextEdit.setVisibility(View.GONE);
-
-                    InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
-                    imm.hideSoftInputFromWindow(mTextEdit.getWindowToken(), 0);
-                }
-                break;
-            // Urho3D: added
-            case COMMAND_FINISH:
-                if (context instanceof Activity)
-                    ((Activity) context).finish();
-                break;
-
-            default:
-                if ((context instanceof SDLActivity) && !((SDLActivity) context).onUnhandledMessage(msg.arg1, msg.obj)) {
-                    Log.e(TAG, "error handling message, command is " + msg.arg1);
-                }
-            }
-        }
-    }
-
-    // Handler for the messages
-    Handler commandHandler = new SDLCommandHandler();
-
-    // Send a message from the SDLMain thread
-    boolean sendCommand(int command, Object data) {
-        Message msg = commandHandler.obtainMessage();
-        msg.arg1 = command;
-        msg.obj = data;
-        return commandHandler.sendMessage(msg);
-    }
-
-    // C functions we call
-    public static native void nativeInit(String filesDir);
-    public static native void nativeLowMemory();
-    public static native void nativeQuit();
-    public static native void nativePause();
-    public static native void nativeResume();
-    public static native void onNativeResize(int x, int y, int format);
-    public static native void onNativeKeyDown(int keycode);
-    public static native void onNativeKeyUp(int keycode);
-    public static native void onNativeTouch(int touchDevId, int pointerFingerId,
-                                            int action, float x, 
-                                            float y, float p);
-    public static native void onNativeAccel(float x, float y, float z);
-    public static native void nativeRunAudioThread();
-
-
-    // Java functions called from C
-
-    public static boolean createGLContext(int majorVersion, int minorVersion, int[] attribs) {
-        return initEGL(majorVersion, minorVersion, attribs);
-    }
-
-    public static void flipBuffers() {
-        flipEGL();
-    }
-
-    public static boolean setActivityTitle(String title) {
-        // Called from SDLMain() thread and can't directly affect the view
-        return mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title);
-    }
-
-    public static void finishActivity()
-    {
-        mSingleton.sendCommand(COMMAND_FINISH, null);
-    }
-
-    public static boolean sendMessage(int command, int param) {
-        return mSingleton.sendCommand(command, Integer.valueOf(param));
-    }
-
-    public static Context getContext() {
-        return mSingleton;
-    }
-
-    public static void startApp() {
-        // Start up the C app thread
-        if (mSDLThread == null) {
-            mSDLThread = new Thread(new SDLMain(), "SDLThread");
-            mSDLThread.start();
-        }
-        else {
-            /*
-             * Some Android variants may send multiple surfaceChanged events, so we don't need to resume every time
-             * every time we get one of those events, only if it comes after surfaceDestroyed
-             */
-            if (mIsPaused) {
-                SDLActivity.nativeResume();
-                SDLActivity.mIsPaused = false;
-            }
-        }
-    }
-    
-    static class ShowTextInputTask implements Runnable {
-        /*
-         * This is used to regulate the pan&scan method to have some offset from
-         * the bottom edge of the input region and the top edge of an input
-         * method (soft keyboard)
-         */
-        static final int HEIGHT_PADDING = 15;
-
-        public int x, y, w, h;
-
-        public ShowTextInputTask(int x, int y, int w, int h) {
-            this.x = x;
-            this.y = y;
-            this.w = w;
-            this.h = h;
-        }
-
-        @Override
-        public void run() {
-            AbsoluteLayout.LayoutParams params = new AbsoluteLayout.LayoutParams(
-                    w, h + HEIGHT_PADDING, x, y);
-
-            if (mTextEdit == null) {
-                mTextEdit = new DummyEdit(getContext());
-
-                mLayout.addView(mTextEdit, params);
-            } else {
-                mTextEdit.setLayoutParams(params);
-            }
-
-            mTextEdit.setVisibility(View.VISIBLE);
-            mTextEdit.requestFocus();
-
-            InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
-            imm.showSoftInput(mTextEdit, 0);
-        }
-    }
-
-    public static boolean showTextInput(int x, int y, int w, int h) {
-        // Transfer the task to the main thread as a Runnable
-        return mSingleton.commandHandler.post(new ShowTextInputTask(x, y, w, h));
-    }
-
-
-    // EGL functions
-    public static boolean initEGL(int majorVersion, int minorVersion, int[] attribs) {
-        try {
-            if (SDLActivity.mEGLDisplay == null) {
-                Log.v("SDL", "Starting up OpenGL ES " + majorVersion + "." + minorVersion);
-
-                EGL10 egl = (EGL10)EGLContext.getEGL();
-
-                EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
-
-                int[] version = new int[2];
-                egl.eglInitialize(dpy, version);
-
-                EGLConfig[] configs = new EGLConfig[1];
-                int[] num_config = new int[1];
-                if (!egl.eglChooseConfig(dpy, attribs, configs, 1, num_config) || num_config[0] == 0) {
-                    Log.e("SDL", "No EGL config available");
-                    return false;
-                }
-                EGLConfig config = configs[0];
-
-                SDLActivity.mEGLDisplay = dpy;
-                SDLActivity.mEGLConfig = config;
-                SDLActivity.mGLMajor = majorVersion;
-                SDLActivity.mGLMinor = minorVersion;
-            }
-            return SDLActivity.createEGLSurface();
-
-        } catch(Exception e) {
-            Log.v("SDL", e + "");
-            for (StackTraceElement s : e.getStackTrace()) {
-                Log.v("SDL", s.toString());
-            }
-            return false;
-        }
-    }
-
-    public static boolean createEGLContext() {
-        EGL10 egl = (EGL10)EGLContext.getEGL();
-        int EGL_CONTEXT_CLIENT_VERSION=0x3098;
-        int contextAttrs[] = new int[] { EGL_CONTEXT_CLIENT_VERSION, SDLActivity.mGLMajor, EGL10.EGL_NONE };
-        SDLActivity.mEGLContext = egl.eglCreateContext(SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, EGL10.EGL_NO_CONTEXT, contextAttrs);
-        if (SDLActivity.mEGLContext == EGL10.EGL_NO_CONTEXT) {
-            Log.e("SDL", "Couldn't create context");
-            return false;
-        }
-        return true;
-    }
-
-    public static boolean createEGLSurface() {
-        if (SDLActivity.mEGLDisplay != null && SDLActivity.mEGLConfig != null) {
-            EGL10 egl = (EGL10)EGLContext.getEGL();
-            if (SDLActivity.mEGLContext == null) createEGLContext();
-
-            Log.v("SDL", "Creating new EGL Surface");
-            EGLSurface surface = egl.eglCreateWindowSurface(SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, SDLActivity.mSurface, null);
-            if (surface == EGL10.EGL_NO_SURFACE) {
-                Log.e("SDL", "Couldn't create surface");
-                return false;
-            }
-
-            if (egl.eglGetCurrentContext() != SDLActivity.mEGLContext) {
-                if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) {
-                    Log.e("SDL", "Old EGL Context doesnt work, trying with a new one");
-                    // TODO: Notify the user via a message that the old context could not be restored, and that textures need to be manually restored.
-                    createEGLContext();
-                    if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) {
-                        Log.e("SDL", "Failed making EGL Context current");
-                        return false;
-                    }
-                }
-            }
-            SDLActivity.mEGLSurface = surface;
-            return true;
-        } else {
-            Log.e("SDL", "Surface creation failed, display = " + SDLActivity.mEGLDisplay + ", config = " + SDLActivity.mEGLConfig);
-            return false;
-        }
-    }
-
-    // EGL buffer flip
-    public static void flipEGL() {
-        try {
-            EGL10 egl = (EGL10)EGLContext.getEGL();
-
-            egl.eglWaitNative(EGL10.EGL_CORE_NATIVE_ENGINE, null);
-
-            // drawing here
-
-            egl.eglWaitGL();
-
-            egl.eglSwapBuffers(SDLActivity.mEGLDisplay, SDLActivity.mEGLSurface);
-
-
-        } catch(Exception e) {
-            Log.v("SDL", "flipEGL(): " + e);
-            for (StackTraceElement s : e.getStackTrace()) {
-                Log.v("SDL", s.toString());
-            }
-        }
-    }
-
-    // Audio
-    public static void audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
-        int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
-        int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
-        int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
-        
-        Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + (sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
-        
-        // Let the user pick a larger buffer if they really want -- but ye
-        // gods they probably shouldn't, the minimums are horrifyingly high
-        // latency already
-        desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize);
-        
-        mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
-                channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
-        
-        audioStartThread();
-        
-        Log.v("SDL", "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
-    }
-    
-    public static void audioStartThread() {
-        mAudioThread = new Thread(new Runnable() {
-            @Override
-            public void run() {
-                mAudioTrack.play();
-                nativeRunAudioThread();
-            }
-        });
-        
-        // I'd take REALTIME if I could get it!
-        mAudioThread.setPriority(Thread.MAX_PRIORITY);
-        mAudioThread.start();
-    }
-    
-    public static void audioWriteShortBuffer(short[] buffer) {
-        for (int i = 0; i < buffer.length; ) {
-            int result = mAudioTrack.write(buffer, i, buffer.length - i);
-            if (result > 0) {
-                i += result;
-            } else if (result == 0) {
-                try {
-                    Thread.sleep(1);
-                } catch(InterruptedException e) {
-                    // Nom nom
-                }
-            } else {
-                Log.w("SDL", "SDL audio: error return from write(short)");
-                return;
-            }
-        }
-    }
-    
-    public static void audioWriteByteBuffer(byte[] buffer) {
-        for (int i = 0; i < buffer.length; ) {
-            int result = mAudioTrack.write(buffer, i, buffer.length - i);
-            if (result > 0) {
-                i += result;
-            } else if (result == 0) {
-                try {
-                    Thread.sleep(1);
-                } catch(InterruptedException e) {
-                    // Nom nom
-                }
-            } else {
-                Log.w("SDL", "SDL audio: error return from write(byte)");
-                return;
-            }
-        }
-    }
-
-    public static void audioQuit() {
-        if (mAudioThread != null) {
-            try {
-                mAudioThread.join();
-            } catch(Exception e) {
-                Log.v("SDL", "Problem stopping audio thread: " + e);
-            }
-            mAudioThread = null;
-
-            //Log.v("SDL", "Finished waiting for audio thread");
-        }
-
-        if (mAudioTrack != null) {
-            mAudioTrack.stop();
-            mAudioTrack = null;
-        }
-    }
-}
-
-/**
-    Simple nativeInit() runnable
-*/
-class SDLMain implements Runnable {
-    @Override
-    public void run() {
-        // Runs SDL_main()
-        SDLActivity.nativeInit(((Activity)SDLActivity.getContext()).getFilesDir().getAbsolutePath());
-
-        //Log.v("SDL", "SDL thread terminated");
-        // Urho3D: finish activity when SDL_main returns
-        SDLActivity.finishActivity();
-    }
-}
-
-
-/**
-    SDLSurface. This is what we draw on, so we need to know when it's created
-    in order to do anything useful. 
-
-    Because of this, that's where we set up the SDL thread
-*/
-class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, 
-    View.OnKeyListener, View.OnTouchListener, SensorEventListener  {
-
-    // Sensors
-    protected static SensorManager mSensorManager;
-
-    // Keep track of the surface size to normalize touch events
-    protected static float mWidth, mHeight;
-
-    // Startup    
-    public SDLSurface(Context context) {
-        super(context);
-        getHolder().addCallback(this); 
-    
-        setFocusable(true);
-        setFocusableInTouchMode(true);
-        requestFocus();
-        setOnKeyListener(this); 
-        setOnTouchListener(this);   
-
-        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
-
-        // Some arbitrary defaults to avoid a potential division by zero
-        mWidth = 1.0f;
-        mHeight = 1.0f;
-    }
-
-    // Called when we have a valid drawing surface
-    @Override
-    public void surfaceCreated(SurfaceHolder holder) {
-        Log.v("SDL", "surfaceCreated()");
-        holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
-        enableSensor(Sensor.TYPE_ACCELEROMETER, true);
-    }
-
-    // Called when we lose the surface
-    @Override
-    public void surfaceDestroyed(SurfaceHolder holder) {
-        Log.v("SDL", "surfaceDestroyed()");
-        if (!SDLActivity.mIsPaused) {
-            SDLActivity.mIsPaused = true;
-            SDLActivity.nativePause();
-        }
-        enableSensor(Sensor.TYPE_ACCELEROMETER, false);
-    }
-
-    // Called when the surface is resized
-    @Override
-    public void surfaceChanged(SurfaceHolder holder,
-                               int format, int width, int height) {
-        Log.v("SDL", "surfaceChanged()");
-
-        int sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565 by default
-        switch (format) {
-        case PixelFormat.A_8:
-            Log.v("SDL", "pixel format A_8");
-            break;
-        case PixelFormat.LA_88:
-            Log.v("SDL", "pixel format LA_88");
-            break;
-        case PixelFormat.L_8:
-            Log.v("SDL", "pixel format L_8");
-            break;
-        case PixelFormat.RGBA_4444:
-            Log.v("SDL", "pixel format RGBA_4444");
-            sdlFormat = 0x15421002; // SDL_PIXELFORMAT_RGBA4444
-            break;
-        case PixelFormat.RGBA_5551:
-            Log.v("SDL", "pixel format RGBA_5551");
-            sdlFormat = 0x15441002; // SDL_PIXELFORMAT_RGBA5551
-            break;
-        case PixelFormat.RGBA_8888:
-            Log.v("SDL", "pixel format RGBA_8888");
-            sdlFormat = 0x16462004; // SDL_PIXELFORMAT_RGBA8888
-            break;
-        case PixelFormat.RGBX_8888:
-            Log.v("SDL", "pixel format RGBX_8888");
-            sdlFormat = 0x16261804; // SDL_PIXELFORMAT_RGBX8888
-            break;
-        case PixelFormat.RGB_332:
-            Log.v("SDL", "pixel format RGB_332");
-            sdlFormat = 0x14110801; // SDL_PIXELFORMAT_RGB332
-            break;
-        case PixelFormat.RGB_565:
-            Log.v("SDL", "pixel format RGB_565");
-            sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565
-            break;
-        case PixelFormat.RGB_888:
-            Log.v("SDL", "pixel format RGB_888");
-            // Not sure this is right, maybe SDL_PIXELFORMAT_RGB24 instead?
-            sdlFormat = 0x16161804; // SDL_PIXELFORMAT_RGB888
-            break;
-        default:
-            Log.v("SDL", "pixel format unknown " + format);
-            break;
-        }
-
-        mWidth = width;
-        mHeight = height;
-        SDLActivity.onNativeResize(width, height, sdlFormat);
-        Log.v("SDL", "Window size:" + width + "x"+height);
-
-        SDLActivity.startApp();
-    }
-
-    // unused
-    @Override
-    public void onDraw(Canvas canvas) {}
-
-
-    // Key events
-    @Override
-    public boolean onKey(View  v, int keyCode, KeyEvent event) {
-
-        // Urho3D: let the home & volume keys be handled by the system
-        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_HOME)
-            return false;
-
-        if (event.getAction() == KeyEvent.ACTION_DOWN) {
-            //Log.v("SDL", "key down: " + keyCode);
-            SDLActivity.onNativeKeyDown(keyCode);
-            return true;
-        }
-        else if (event.getAction() == KeyEvent.ACTION_UP) {
-            //Log.v("SDL", "key up: " + keyCode);
-            SDLActivity.onNativeKeyUp(keyCode);
-            return true;
-        }
-        
-        return false;
-    }
-
-    // Touch events
-    @Override
-    public boolean onTouch(View v, MotionEvent event) {
-             final int touchDevId = event.getDeviceId();
-             final int pointerCount = event.getPointerCount();
-             // touchId, pointerId, action, x, y, pressure
-             int actionPointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT; /* API 8: event.getActionIndex(); */
-             int pointerFingerId = event.getPointerId(actionPointerIndex);
-             int action = (event.getAction() & MotionEvent.ACTION_MASK); /* API 8: event.getActionMasked(); */
-
-             float x = event.getX(actionPointerIndex) / mWidth;
-             float y = event.getY(actionPointerIndex) / mHeight;
-             float p = event.getPressure(actionPointerIndex);
-
-             if (action == MotionEvent.ACTION_MOVE && pointerCount > 1) {
-                // TODO send motion to every pointer if its position has
-                // changed since prev event.
-                for (int i = 0; i < pointerCount; i++) {
-                    pointerFingerId = event.getPointerId(i);
-                    x = event.getX(i) / mWidth;
-                    y = event.getY(i) / mHeight;
-                    p = event.getPressure(i);
-                    SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
-                }
-             } else {
-                SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
-             }
-      return true;
-   } 
-
-    // Sensor events
-    public void enableSensor(int sensortype, boolean enabled) {
-        // TODO: This uses getDefaultSensor - what if we have >1 accels?
-        if (enabled) {
-            mSensorManager.registerListener(this, 
-                            mSensorManager.getDefaultSensor(sensortype), 
-                            SensorManager.SENSOR_DELAY_GAME, null);
-        } else {
-            mSensorManager.unregisterListener(this, 
-                            mSensorManager.getDefaultSensor(sensortype));
-        }
-    }
-    
-    @Override
-    public void onAccuracyChanged(Sensor sensor, int accuracy) {
-        // TODO
-    }
-
-    @Override
-    public void onSensorChanged(SensorEvent event) {
-        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
-            SDLActivity.onNativeAccel(event.values[0] / SensorManager.GRAVITY_EARTH,
-                                      event.values[1] / SensorManager.GRAVITY_EARTH,
-                                      event.values[2] / SensorManager.GRAVITY_EARTH);
-        }
-    }
-    
-}
-
-/* This is a fake invisible editor view that receives the input and defines the
- * pan&scan region
- */
-class DummyEdit extends View implements View.OnKeyListener {
-    InputConnection ic;
-
-    public DummyEdit(Context context) {
-        super(context);
-        setFocusableInTouchMode(true);
-        setFocusable(true);
-        setOnKeyListener(this);
-    }
-
-    @Override
-    public boolean onCheckIsTextEditor() {
-        return true;
-    }
-
-    @Override
-    public boolean onKey(View v, int keyCode, KeyEvent event) {
-
-        // This handles the hardware keyboard input
-        if (event.isPrintingKey()) {
-            if (event.getAction() == KeyEvent.ACTION_DOWN) {
-                ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
-            }
-            return true;
-        }
-
-        if (event.getAction() == KeyEvent.ACTION_DOWN) {
-            SDLActivity.onNativeKeyDown(keyCode);
-            return true;
-        } else if (event.getAction() == KeyEvent.ACTION_UP) {
-            SDLActivity.onNativeKeyUp(keyCode);
-            return true;
-        }
-
-        return false;
-    }
-
-    @Override
-    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
-        ic = new SDLInputConnection(this, true);
-
-        outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI
-                | 33554432 /* API 11: EditorInfo.IME_FLAG_NO_FULLSCREEN */;
-
-        return ic;
-    }
-}
-
-class SDLInputConnection extends BaseInputConnection {
-
-    public SDLInputConnection(View targetView, boolean fullEditor) {
-        super(targetView, fullEditor);
-
-    }
-
-    @Override
-    public boolean sendKeyEvent(KeyEvent event) {
-
-        /*
-         * This handles the keycodes from soft keyboard (and IME-translated
-         * input from hardkeyboard)
-         */
-        int keyCode = event.getKeyCode();
-        if (event.getAction() == KeyEvent.ACTION_DOWN) {
-            if (event.isPrintingKey()) {
-                commitText(String.valueOf((char) event.getUnicodeChar()), 1);
-            }
-            SDLActivity.onNativeKeyDown(keyCode);
-            return true;
-        } else if (event.getAction() == KeyEvent.ACTION_UP) {
-
-            SDLActivity.onNativeKeyUp(keyCode);
-            return true;
-        }
-        return super.sendKeyEvent(event);
-    }
-
-    @Override
-    public boolean commitText(CharSequence text, int newCursorPosition) {
-
-        nativeCommitText(text.toString(), newCursorPosition);
-
-        return super.commitText(text, newCursorPosition);
-    }
-
-    @Override
-    public boolean setComposingText(CharSequence text, int newCursorPosition) {
-
-        nativeSetComposingText(text.toString(), newCursorPosition);
-
-        return super.setComposingText(text, newCursorPosition);
-    }
-
-    public native void nativeCommitText(String text, int newCursorPosition);
-
-    public native void nativeSetComposingText(String text, int newCursorPosition);
-
-}
+// Modified by Lasse Oorni for Urho3D
+
+package org.libsdl.app;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.egl.EGLSurface;
+
+import android.app.*;
+import android.content.*;
+import android.view.*;
+import android.view.inputmethod.BaseInputConnection;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.AbsoluteLayout;
+import android.os.*;
+import android.util.Log;
+import android.graphics.*;
+import android.media.*;
+import android.hardware.*;
+
+
+/**
+    SDL Activity
+*/
+public class SDLActivity extends Activity {
+    private static final String TAG = "SDL";
+
+    // Keep track of the paused state
+    public static boolean mIsPaused = false, mIsSurfaceReady = false, mHasFocus = true;
+
+    // Main components
+    protected static SDLActivity mSingleton;
+    protected static SDLSurface mSurface;
+    protected static View mTextEdit;
+    protected static ViewGroup mLayout;
+
+    // This is what SDL runs in. It invokes SDL_main(), eventually
+    protected static Thread mSDLThread;
+
+    // Audio
+    protected static Thread mAudioThread;
+    protected static AudioTrack mAudioTrack;
+
+    // EGL objects
+    protected static EGLContext  mEGLContext;
+    protected static EGLSurface  mEGLSurface;
+    protected static EGLDisplay  mEGLDisplay;
+    protected static EGLConfig   mEGLConfig;
+    protected static int mGLMajor, mGLMinor;
+
+    // Load the .so
+    static {
+		// Urho3D: everything resides in urho3d.so
+        System.loadLibrary("Urho3D");
+    }
+
+    // Setup
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        //Log.v("SDL", "onCreate()");
+        super.onCreate(savedInstanceState);
+        
+        // So we can call stuff from static callbacks
+        mSingleton = this;
+
+        // Set up the surface
+        mEGLSurface = EGL10.EGL_NO_SURFACE;
+        mSurface = new SDLSurface(getApplication());
+        mEGLContext = EGL10.EGL_NO_CONTEXT;
+
+        mLayout = new AbsoluteLayout(this);
+        mLayout.addView(mSurface);
+
+        setContentView(mLayout);
+    }
+
+    // Events
+    @Override
+    protected void onPause() {
+        Log.v("SDL", "onPause()");
+        super.onPause();
+        SDLActivity.handlePause();
+    }
+
+    @Override
+    protected void onResume() {
+        Log.v("SDL", "onResume()");
+        super.onResume();
+        SDLActivity.handleResume();
+    }
+
+
+    @Override
+    public void onWindowFocusChanged(boolean hasFocus) {
+        super.onWindowFocusChanged(hasFocus);
+        Log.v("SDL", "onWindowFocusChanged(): " + hasFocus);
+
+        SDLActivity.mHasFocus = hasFocus;
+        if (hasFocus) {
+            SDLActivity.handleResume();
+        }
+    }
+
+    @Override
+    public void onLowMemory() {
+        Log.v("SDL", "onLowMemory()");
+        super.onLowMemory();
+        SDLActivity.nativeLowMemory();
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        Log.v("SDL", "onDestroy()");
+        // Send a quit message to the application
+        SDLActivity.nativeQuit();
+
+        // Now wait for the SDL thread to quit
+        if (mSDLThread != null) {
+            try {
+                mSDLThread.join();
+            } catch(Exception e) {
+                Log.v("SDL", "Problem stopping thread: " + e);
+            }
+            mSDLThread = null;
+
+            //Log.v("SDL", "Finished waiting for SDL thread");
+        }
+    }
+
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        int keyCode = event.getKeyCode();
+        // Ignore volume keys so they're handled by Android
+        // Urho3D: also ignore the Home key
+        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ||
+            keyCode == KeyEvent.KEYCODE_VOLUME_UP ||
+			keyCode == KeyEvent.KEYCODE_HOME) {
+            return false;
+        }
+        return super.dispatchKeyEvent(event);
+    }
+
+    /** Called by onPause or surfaceDestroyed. Even if surfaceDestroyed
+     *  is the first to be called, mIsSurfaceReady should still be set
+     *  to 'true' during the call to onPause (in a usual scenario).
+     */
+    public static void handlePause() {
+        if (!SDLActivity.mIsPaused && SDLActivity.mIsSurfaceReady) {
+            SDLActivity.mIsPaused = true;
+            SDLActivity.nativePause();
+            mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, false);
+        }
+    }
+
+    /** Called by onResume or surfaceCreated. An actual resume should be done only when the surface is ready.
+     * Note: Some Android variants may send multiple surfaceChanged events, so we don't need to resume
+     * every time we get one of those events, only if it comes after surfaceDestroyed
+     */
+    public static void handleResume() {
+        if (SDLActivity.mIsPaused && SDLActivity.mIsSurfaceReady && SDLActivity.mHasFocus) {
+            SDLActivity.mIsPaused = false;
+            SDLActivity.nativeResume();
+            mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, true);
+        }
+    }
+
+
+    // Messages from the SDLMain thread
+    static final int COMMAND_CHANGE_TITLE = 1;
+    static final int COMMAND_UNUSED = 2;
+    static final int COMMAND_TEXTEDIT_HIDE = 3;
+    // Urho3D: added
+    static final int COMMAND_FINISH = 4;
+
+    protected static final int COMMAND_USER = 0x8000;
+
+    /**
+     * This method is called by SDL if SDL did not handle a message itself.
+     * This happens if a received message contains an unsupported command.
+     * Method can be overwritten to handle Messages in a different class.
+     * @param command the command of the message.
+     * @param param the parameter of the message. May be null.
+     * @return if the message was handled in overridden method.
+     */
+    protected boolean onUnhandledMessage(int command, Object param) {
+        return false;
+    }
+
+    /**
+     * A Handler class for Messages from native SDL applications.
+     * It uses current Activities as target (e.g. for the title).
+     * static to prevent implicit references to enclosing object.
+     */
+    protected static class SDLCommandHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            Context context = getContext();
+            if (context == null) {
+                Log.e(TAG, "error handling message, getContext() returned null");
+                return;
+            }
+            switch (msg.arg1) {
+            case COMMAND_CHANGE_TITLE:
+                if (context instanceof Activity) {
+                    ((Activity) context).setTitle((String)msg.obj);
+                } else {
+                    Log.e(TAG, "error handling message, getContext() returned no Activity");
+                }
+                break;
+            case COMMAND_TEXTEDIT_HIDE:
+                if (mTextEdit != null) {
+                    mTextEdit.setVisibility(View.GONE);
+
+                    InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
+                    imm.hideSoftInputFromWindow(mTextEdit.getWindowToken(), 0);
+                }
+                break;
+            // Urho3D: added
+            case COMMAND_FINISH:
+                if (context instanceof Activity)
+                    ((Activity) context).finish();
+                break;
+
+            default:
+                if ((context instanceof SDLActivity) && !((SDLActivity) context).onUnhandledMessage(msg.arg1, msg.obj)) {
+                    Log.e(TAG, "error handling message, command is " + msg.arg1);
+                }
+            }
+        }
+    }
+
+    // Handler for the messages
+    Handler commandHandler = new SDLCommandHandler();
+
+    // Send a message from the SDLMain thread
+    boolean sendCommand(int command, Object data) {
+        Message msg = commandHandler.obtainMessage();
+        msg.arg1 = command;
+        msg.obj = data;
+        return commandHandler.sendMessage(msg);
+    }
+
+    // C functions we call
+    public static native void nativeInit(String filesDir);
+    public static native void nativeLowMemory();
+    public static native void nativeQuit();
+    public static native void nativePause();
+    public static native void nativeResume();
+    public static native void onNativeResize(int x, int y, int format);
+    public static native void onNativeKeyDown(int keycode);
+    public static native void onNativeKeyUp(int keycode);
+    public static native void onNativeKeyboardFocusLost();
+    public static native void onNativeTouch(int touchDevId, int pointerFingerId,
+                                            int action, float x, 
+                                            float y, float p);
+    public static native void onNativeAccel(float x, float y, float z);
+
+    // Java functions called from C
+
+    public static boolean createGLContext(int majorVersion, int minorVersion, int[] attribs) {
+        return initEGL(majorVersion, minorVersion, attribs);
+    }
+    
+    public static void deleteGLContext() {
+        if (SDLActivity.mEGLDisplay != null && SDLActivity.mEGLContext != EGL10.EGL_NO_CONTEXT) {
+            EGL10 egl = (EGL10)EGLContext.getEGL();
+            egl.eglMakeCurrent(SDLActivity.mEGLDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
+            egl.eglDestroyContext(SDLActivity.mEGLDisplay, SDLActivity.mEGLContext);
+            SDLActivity.mEGLContext = EGL10.EGL_NO_CONTEXT;
+
+            if (SDLActivity.mEGLSurface != EGL10.EGL_NO_SURFACE) {
+                egl.eglDestroySurface(SDLActivity.mEGLDisplay, SDLActivity.mEGLSurface);
+                SDLActivity.mEGLSurface = EGL10.EGL_NO_SURFACE;
+            }
+        }
+    }
+
+    public static void flipBuffers() {
+        flipEGL();
+    }
+
+    public static boolean setActivityTitle(String title) {
+        // Called from SDLMain() thread and can't directly affect the view
+        return mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title);
+    }
+
+    public static void finishActivity()
+    {
+        mSingleton.sendCommand(COMMAND_FINISH, null);
+    }
+
+    public static boolean sendMessage(int command, int param) {
+        return mSingleton.sendCommand(command, Integer.valueOf(param));
+    }
+
+    public static Context getContext() {
+        return mSingleton;
+    }
+
+    static class ShowTextInputTask implements Runnable {
+        /*
+         * This is used to regulate the pan&scan method to have some offset from
+         * the bottom edge of the input region and the top edge of an input
+         * method (soft keyboard)
+         */
+        static final int HEIGHT_PADDING = 15;
+
+        public int x, y, w, h;
+
+        public ShowTextInputTask(int x, int y, int w, int h) {
+            this.x = x;
+            this.y = y;
+            this.w = w;
+            this.h = h;
+        }
+
+        @Override
+        public void run() {
+            AbsoluteLayout.LayoutParams params = new AbsoluteLayout.LayoutParams(
+                    w, h + HEIGHT_PADDING, x, y);
+
+            if (mTextEdit == null) {
+                mTextEdit = new DummyEdit(getContext());
+
+                mLayout.addView(mTextEdit, params);
+            } else {
+                mTextEdit.setLayoutParams(params);
+            }
+
+            mTextEdit.setVisibility(View.VISIBLE);
+            mTextEdit.requestFocus();
+
+            InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+            imm.showSoftInput(mTextEdit, 0);
+        }
+    }
+
+    public static boolean showTextInput(int x, int y, int w, int h) {
+        // Transfer the task to the main thread as a Runnable
+        return mSingleton.commandHandler.post(new ShowTextInputTask(x, y, w, h));
+    }
+
+
+    // EGL functions
+    public static boolean initEGL(int majorVersion, int minorVersion, int[] attribs) {
+        try {
+            EGL10 egl = (EGL10)EGLContext.getEGL();
+            
+            if (SDLActivity.mEGLDisplay == null) {
+                SDLActivity.mEGLDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+                int[] version = new int[2];
+                egl.eglInitialize(SDLActivity.mEGLDisplay, version);
+            }
+            
+            if (SDLActivity.mEGLDisplay != null && SDLActivity.mEGLContext == EGL10.EGL_NO_CONTEXT) {
+                // No current GL context exists, we will create a new one.
+                Log.v("SDL", "Starting up OpenGL ES " + majorVersion + "." + minorVersion);
+                EGLConfig[] configs = new EGLConfig[128];
+                int[] num_config = new int[1];
+                if (!egl.eglChooseConfig(SDLActivity.mEGLDisplay, attribs, configs, 1, num_config) || num_config[0] == 0) {
+                    Log.e("SDL", "No EGL config available");
+                    return false;
+                }
+                EGLConfig config = null;
+                int bestdiff = -1, bitdiff;
+                int[] value = new int[1];
+                
+                // eglChooseConfig returns a number of configurations that match or exceed the requested attribs.
+                // From those, we select the one that matches our requirements more closely
+                Log.v("SDL", "Got " + num_config[0] + " valid modes from egl");
+                for(int i = 0; i < num_config[0]; i++) {
+                    bitdiff = 0;
+                    // Go through some of the attributes and compute the bit difference between what we want and what we get.
+                    for (int j = 0; ; j += 2) {
+                        if (attribs[j] == EGL10.EGL_NONE)
+                            break;
+
+                        if (attribs[j+1] != EGL10.EGL_DONT_CARE && (attribs[j] == EGL10.EGL_RED_SIZE ||
+                            attribs[j] == EGL10.EGL_GREEN_SIZE ||
+                            attribs[j] == EGL10.EGL_BLUE_SIZE ||
+                            attribs[j] == EGL10.EGL_ALPHA_SIZE ||
+                            attribs[j] == EGL10.EGL_DEPTH_SIZE ||
+                            attribs[j] == EGL10.EGL_STENCIL_SIZE)) {
+                            egl.eglGetConfigAttrib(SDLActivity.mEGLDisplay, configs[i], attribs[j], value);
+                            bitdiff += value[0] - attribs[j + 1]; // value is always >= attrib
+                        }
+                    }
+                    
+                    if (bitdiff < bestdiff || bestdiff == -1) {
+                        config = configs[i];
+                        bestdiff = bitdiff;
+                    }
+                    
+                    if (bitdiff == 0) break; // we found an exact match!
+                }
+                
+                Log.d("SDL", "Selected mode with a total bit difference of " + bestdiff);
+
+                SDLActivity.mEGLConfig = config;
+                SDLActivity.mGLMajor = majorVersion;
+                SDLActivity.mGLMinor = minorVersion;
+            }
+            
+            return SDLActivity.createEGLSurface();
+
+        } catch(Exception e) {
+            Log.v("SDL", e + "");
+            for (StackTraceElement s : e.getStackTrace()) {
+                Log.v("SDL", s.toString());
+            }
+            return false;
+        }
+    }
+
+    public static boolean createEGLContext() {
+        EGL10 egl = (EGL10)EGLContext.getEGL();
+        int EGL_CONTEXT_CLIENT_VERSION=0x3098;
+        int contextAttrs[] = new int[] { EGL_CONTEXT_CLIENT_VERSION, SDLActivity.mGLMajor, EGL10.EGL_NONE };
+        SDLActivity.mEGLContext = egl.eglCreateContext(SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, EGL10.EGL_NO_CONTEXT, contextAttrs);
+        if (SDLActivity.mEGLContext == EGL10.EGL_NO_CONTEXT) {
+            Log.e("SDL", "Couldn't create context");
+            return false;
+        }
+        return true;
+    }
+
+    public static boolean createEGLSurface() {
+        if (SDLActivity.mEGLDisplay != null && SDLActivity.mEGLConfig != null) {
+            EGL10 egl = (EGL10)EGLContext.getEGL();
+            if (SDLActivity.mEGLContext == EGL10.EGL_NO_CONTEXT) createEGLContext();
+
+            if (SDLActivity.mEGLSurface == EGL10.EGL_NO_SURFACE) {
+                Log.v("SDL", "Creating new EGL Surface");
+                SDLActivity.mEGLSurface = egl.eglCreateWindowSurface(SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, SDLActivity.mSurface, null);
+                if (SDLActivity.mEGLSurface == EGL10.EGL_NO_SURFACE) {
+                    Log.e("SDL", "Couldn't create surface");
+                    return false;
+                }
+            }
+            else Log.v("SDL", "EGL Surface remains valid");
+
+            if (egl.eglGetCurrentContext() != SDLActivity.mEGLContext) {
+                if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, SDLActivity.mEGLSurface, SDLActivity.mEGLSurface, SDLActivity.mEGLContext)) {
+                    Log.e("SDL", "Old EGL Context doesnt work, trying with a new one");
+                    // TODO: Notify the user via a message that the old context could not be restored, and that textures need to be manually restored.
+                    createEGLContext();
+                    if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, SDLActivity.mEGLSurface, SDLActivity.mEGLSurface, SDLActivity.mEGLContext)) {
+                        Log.e("SDL", "Failed making EGL Context current");
+                        return false;
+                    }
+                }
+                else Log.v("SDL", "EGL Context made current");
+            }
+            else Log.v("SDL", "EGL Context remains current");
+
+            return true;
+        } else {
+            Log.e("SDL", "Surface creation failed, display = " + SDLActivity.mEGLDisplay + ", config = " + SDLActivity.mEGLConfig);
+            return false;
+        }
+    }
+
+    // EGL buffer flip
+    public static void flipEGL() {
+        try {
+            EGL10 egl = (EGL10)EGLContext.getEGL();
+
+            egl.eglWaitNative(EGL10.EGL_CORE_NATIVE_ENGINE, null);
+
+            // drawing here
+
+            egl.eglWaitGL();
+
+            egl.eglSwapBuffers(SDLActivity.mEGLDisplay, SDLActivity.mEGLSurface);
+
+
+        } catch(Exception e) {
+            Log.v("SDL", "flipEGL(): " + e);
+            for (StackTraceElement s : e.getStackTrace()) {
+                Log.v("SDL", s.toString());
+            }
+        }
+    }
+
+    // Audio
+    public static int audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
+        int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
+        int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
+        int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
+        
+        Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + (sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
+        
+        // Let the user pick a larger buffer if they really want -- but ye
+        // gods they probably shouldn't, the minimums are horrifyingly high
+        // latency already
+        desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize);
+        
+        if (mAudioTrack == null) {
+            mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
+                    channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
+            
+            // Instantiating AudioTrack can "succeed" without an exception and the track may still be invalid
+            // Ref: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/media/java/android/media/AudioTrack.java
+            // Ref: http://developer.android.com/reference/android/media/AudioTrack.html#getState()
+            
+            if (mAudioTrack.getState() != AudioTrack.STATE_INITIALIZED) {
+                Log.e("SDL", "Failed during initialization of Audio Track");
+                mAudioTrack = null;
+                return -1;
+            }
+            
+            mAudioTrack.play();
+        }
+       
+        Log.v("SDL", "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
+        
+        return 0;
+    }
+    
+    public static void audioWriteShortBuffer(short[] buffer) {
+        for (int i = 0; i < buffer.length; ) {
+            int result = mAudioTrack.write(buffer, i, buffer.length - i);
+            if (result > 0) {
+                i += result;
+            } else if (result == 0) {
+                try {
+                    Thread.sleep(1);
+                } catch(InterruptedException e) {
+                    // Nom nom
+                }
+            } else {
+                Log.w("SDL", "SDL audio: error return from write(short)");
+                return;
+            }
+        }
+    }
+    
+    public static void audioWriteByteBuffer(byte[] buffer) {
+        for (int i = 0; i < buffer.length; ) {
+            int result = mAudioTrack.write(buffer, i, buffer.length - i);
+            if (result > 0) {
+                i += result;
+            } else if (result == 0) {
+                try {
+                    Thread.sleep(1);
+                } catch(InterruptedException e) {
+                    // Nom nom
+                }
+            } else {
+                Log.w("SDL", "SDL audio: error return from write(byte)");
+                return;
+            }
+        }
+    }
+
+    public static void audioQuit() {
+        if (mAudioTrack != null) {
+            mAudioTrack.stop();
+            mAudioTrack = null;
+        }
+    }
+}
+
+/**
+    Simple nativeInit() runnable
+*/
+class SDLMain implements Runnable {
+    @Override
+    public void run() {
+        // Runs SDL_main()
+        // Urho3D: pass filesDir
+        SDLActivity.nativeInit(((Activity)SDLActivity.getContext()).getFilesDir().getAbsolutePath());
+        //Log.v("SDL", "SDL thread terminated");
+        // Urho3D: finish activity when SDL_main returns
+        SDLActivity.finishActivity();
+    }
+}
+
+
+/**
+    SDLSurface. This is what we draw on, so we need to know when it's created
+    in order to do anything useful. 
+
+    Because of this, that's where we set up the SDL thread
+*/
+class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, 
+    View.OnKeyListener, View.OnTouchListener, SensorEventListener  {
+
+    // Sensors
+    protected static SensorManager mSensorManager;
+
+    // Keep track of the surface size to normalize touch events
+    protected static float mWidth, mHeight;
+
+    // Startup    
+    public SDLSurface(Context context) {
+        super(context);
+        getHolder().addCallback(this); 
+    
+        setFocusable(true);
+        setFocusableInTouchMode(true);
+        requestFocus();
+        setOnKeyListener(this); 
+        setOnTouchListener(this);   
+
+        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
+
+        // Some arbitrary defaults to avoid a potential division by zero
+        mWidth = 1.0f;
+        mHeight = 1.0f;
+    }
+
+    // Called when we have a valid drawing surface
+    @Override
+    public void surfaceCreated(SurfaceHolder holder) {
+        Log.v("SDL", "surfaceCreated()");
+        holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
+        // Set mIsSurfaceReady to 'true' *before* any call to handleResume
+        SDLActivity.mIsSurfaceReady = true;
+    }
+
+    // Called when we lose the surface
+    @Override
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        Log.v("SDL", "surfaceDestroyed()");
+        // Call this *before* setting mIsSurfaceReady to 'false'
+        SDLActivity.handlePause();
+        SDLActivity.mIsSurfaceReady = false;
+
+        /* We have to clear the current context and destroy the egl surface here
+         * Otherwise there's BAD_NATIVE_WINDOW errors coming from eglCreateWindowSurface on resume
+         * Ref: http://stackoverflow.com/questions/8762589/eglcreatewindowsurface-on-ics-and-switching-from-2d-to-3d
+         */
+        
+        EGL10 egl = (EGL10)EGLContext.getEGL();
+        egl.eglMakeCurrent(SDLActivity.mEGLDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
+        egl.eglDestroySurface(SDLActivity.mEGLDisplay, SDLActivity.mEGLSurface);
+        SDLActivity.mEGLSurface = EGL10.EGL_NO_SURFACE;
+    }
+
+    // Called when the surface is resized
+    @Override
+    public void surfaceChanged(SurfaceHolder holder,
+                               int format, int width, int height) {
+        Log.v("SDL", "surfaceChanged()");
+
+        int sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565 by default
+        switch (format) {
+        case PixelFormat.A_8:
+            Log.v("SDL", "pixel format A_8");
+            break;
+        case PixelFormat.LA_88:
+            Log.v("SDL", "pixel format LA_88");
+            break;
+        case PixelFormat.L_8:
+            Log.v("SDL", "pixel format L_8");
+            break;
+        case PixelFormat.RGBA_4444:
+            Log.v("SDL", "pixel format RGBA_4444");
+            sdlFormat = 0x15421002; // SDL_PIXELFORMAT_RGBA4444
+            break;
+        case PixelFormat.RGBA_5551:
+            Log.v("SDL", "pixel format RGBA_5551");
+            sdlFormat = 0x15441002; // SDL_PIXELFORMAT_RGBA5551
+            break;
+        case PixelFormat.RGBA_8888:
+            Log.v("SDL", "pixel format RGBA_8888");
+            sdlFormat = 0x16462004; // SDL_PIXELFORMAT_RGBA8888
+            break;
+        case PixelFormat.RGBX_8888:
+            Log.v("SDL", "pixel format RGBX_8888");
+            sdlFormat = 0x16261804; // SDL_PIXELFORMAT_RGBX8888
+            break;
+        case PixelFormat.RGB_332:
+            Log.v("SDL", "pixel format RGB_332");
+            sdlFormat = 0x14110801; // SDL_PIXELFORMAT_RGB332
+            break;
+        case PixelFormat.RGB_565:
+            Log.v("SDL", "pixel format RGB_565");
+            sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565
+            break;
+        case PixelFormat.RGB_888:
+            Log.v("SDL", "pixel format RGB_888");
+            // Not sure this is right, maybe SDL_PIXELFORMAT_RGB24 instead?
+            sdlFormat = 0x16161804; // SDL_PIXELFORMAT_RGB888
+            break;
+        default:
+            Log.v("SDL", "pixel format unknown " + format);
+            break;
+        }
+
+        mWidth = width;
+        mHeight = height;
+        SDLActivity.onNativeResize(width, height, sdlFormat);
+        Log.v("SDL", "Window size:" + width + "x"+height);
+
+        // Set mIsSurfaceReady to 'true' *before* making a call to handleResume
+        SDLActivity.mIsSurfaceReady = true;
+
+        if (SDLActivity.mSDLThread == null) {
+            // This is the entry point to the C app.
+            // Start up the C app thread and enable sensor input for the first time
+
+            SDLActivity.mSDLThread = new Thread(new SDLMain(), "SDLThread");
+            enableSensor(Sensor.TYPE_ACCELEROMETER, true);
+            SDLActivity.mSDLThread.start();
+        } else {
+            // The app already exists, we resume via handleResume
+            // Multiple sequential calls to surfaceChanged are handled internally by handleResume
+
+            SDLActivity.handleResume();
+        }
+    }
+
+    // unused
+    @Override
+    public void onDraw(Canvas canvas) {}
+
+
+    // Key events
+    @Override
+    public boolean onKey(View  v, int keyCode, KeyEvent event) {
+        
+        if (event.getAction() == KeyEvent.ACTION_DOWN) {
+            //Log.v("SDL", "key down: " + keyCode);
+            SDLActivity.onNativeKeyDown(keyCode);
+            return true;
+        }
+        else if (event.getAction() == KeyEvent.ACTION_UP) {
+            //Log.v("SDL", "key up: " + keyCode);
+            SDLActivity.onNativeKeyUp(keyCode);
+            return true;
+        }
+        
+        return false;
+    }
+
+    // Touch events
+    @Override
+    public boolean onTouch(View v, MotionEvent event) {
+             final int touchDevId = event.getDeviceId();
+             final int pointerCount = event.getPointerCount();
+             // touchId, pointerId, action, x, y, pressure
+             int actionPointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT; /* API 8: event.getActionIndex(); */
+             int pointerFingerId = event.getPointerId(actionPointerIndex);
+             int action = (event.getAction() & MotionEvent.ACTION_MASK); /* API 8: event.getActionMasked(); */
+
+             float x = event.getX(actionPointerIndex) / mWidth;
+             float y = event.getY(actionPointerIndex) / mHeight;
+             float p = event.getPressure(actionPointerIndex);
+
+             if (action == MotionEvent.ACTION_MOVE && pointerCount > 1) {
+                // TODO send motion to every pointer if its position has
+                // changed since prev event.
+                for (int i = 0; i < pointerCount; i++) {
+                    pointerFingerId = event.getPointerId(i);
+                    x = event.getX(i) / mWidth;
+                    y = event.getY(i) / mHeight;
+                    p = event.getPressure(i);
+                    SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
+                }
+             } else {
+                SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
+             }
+      return true;
+   } 
+
+    // Sensor events
+    public void enableSensor(int sensortype, boolean enabled) {
+        // TODO: This uses getDefaultSensor - what if we have >1 accels?
+        if (enabled) {
+            mSensorManager.registerListener(this, 
+                            mSensorManager.getDefaultSensor(sensortype), 
+                            SensorManager.SENSOR_DELAY_GAME, null);
+        } else {
+            mSensorManager.unregisterListener(this, 
+                            mSensorManager.getDefaultSensor(sensortype));
+        }
+    }
+    
+    @Override
+    public void onAccuracyChanged(Sensor sensor, int accuracy) {
+        // TODO
+    }
+
+    @Override
+    public void onSensorChanged(SensorEvent event) {
+        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
+            SDLActivity.onNativeAccel(event.values[0] / SensorManager.GRAVITY_EARTH,
+                                      event.values[1] / SensorManager.GRAVITY_EARTH,
+                                      event.values[2] / SensorManager.GRAVITY_EARTH);
+        }
+    }
+    
+}
+
+/* This is a fake invisible editor view that receives the input and defines the
+ * pan&scan region
+ */
+class DummyEdit extends View implements View.OnKeyListener {
+    InputConnection ic;
+
+    public DummyEdit(Context context) {
+        super(context);
+        setFocusableInTouchMode(true);
+        setFocusable(true);
+        setOnKeyListener(this);
+    }
+
+    @Override
+    public boolean onCheckIsTextEditor() {
+        return true;
+    }
+
+    @Override
+    public boolean onKey(View v, int keyCode, KeyEvent event) {
+
+        // This handles the hardware keyboard input
+        if (event.isPrintingKey()) {
+            if (event.getAction() == KeyEvent.ACTION_DOWN) {
+                ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
+            }
+            return true;
+        }
+
+        if (event.getAction() == KeyEvent.ACTION_DOWN) {
+            SDLActivity.onNativeKeyDown(keyCode);
+            return true;
+        } else if (event.getAction() == KeyEvent.ACTION_UP) {
+            SDLActivity.onNativeKeyUp(keyCode);
+            return true;
+        }
+
+        return false;
+    }
+        
+    //
+    @Override
+    public boolean onKeyPreIme (int keyCode, KeyEvent event) {
+        // As seen on StackOverflow: http://stackoverflow.com/questions/7634346/keyboard-hide-event
+        // FIXME: Discussion at http://bugzilla.libsdl.org/show_bug.cgi?id=1639
+        // FIXME: This is not a 100% effective solution to the problem of detecting if the keyboard is showing or not
+        // FIXME: A more effective solution would be to change our Layout from AbsoluteLayout to Relative or Linear
+        // FIXME: And determine the keyboard presence doing this: http://stackoverflow.com/questions/2150078/how-to-check-visibility-of-software-keyboard-in-android
+        // FIXME: An even more effective way would be if Android provided this out of the box, but where would the fun be in that :)
+        if (event.getAction()==KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
+            if (SDLActivity.mTextEdit != null && SDLActivity.mTextEdit.getVisibility() == View.VISIBLE) {
+                SDLActivity.onNativeKeyboardFocusLost();
+            }
+        }
+        return super.onKeyPreIme(keyCode, event);
+    }
+
+    @Override
+    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
+        ic = new SDLInputConnection(this, true);
+
+        outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI
+                | 33554432 /* API 11: EditorInfo.IME_FLAG_NO_FULLSCREEN */;
+
+        return ic;
+    }
+}
+
+class SDLInputConnection extends BaseInputConnection {
+
+    public SDLInputConnection(View targetView, boolean fullEditor) {
+        super(targetView, fullEditor);
+
+    }
+
+    @Override
+    public boolean sendKeyEvent(KeyEvent event) {
+
+        /*
+         * This handles the keycodes from soft keyboard (and IME-translated
+         * input from hardkeyboard)
+         */
+        int keyCode = event.getKeyCode();
+        if (event.getAction() == KeyEvent.ACTION_DOWN) {
+            if (event.isPrintingKey()) {
+                commitText(String.valueOf((char) event.getUnicodeChar()), 1);
+            }
+            SDLActivity.onNativeKeyDown(keyCode);
+            return true;
+        } else if (event.getAction() == KeyEvent.ACTION_UP) {
+
+            SDLActivity.onNativeKeyUp(keyCode);
+            return true;
+        }
+        return super.sendKeyEvent(event);
+    }
+
+    @Override
+    public boolean commitText(CharSequence text, int newCursorPosition) {
+
+        nativeCommitText(text.toString(), newCursorPosition);
+
+        return super.commitText(text, newCursorPosition);
+    }
+
+    @Override
+    public boolean setComposingText(CharSequence text, int newCursorPosition) {
+
+        nativeSetComposingText(text.toString(), newCursorPosition);
+
+        return super.setComposingText(text, newCursorPosition);
+    }
+
+    public native void nativeCommitText(String text, int newCursorPosition);
+
+    public native void nativeSetComposingText(String text, int newCursorPosition);
+
+}
+

+ 1 - 1
Source/ThirdParty/SDL/CMakeLists.txt

@@ -37,7 +37,7 @@ elseif (APPLE)
     )
     )
 elseif (ANDROID)
 elseif (ANDROID)
     file (GLOB SYS_C_FILES
     file (GLOB SYS_C_FILES
-        src/audio/android/*.c src/core/android/*.cpp src/joystick/android/*.c src/loadso/dlopen/*.c
+        src/audio/android/*.c src/core/android/*.c src/joystick/android/*.c src/loadso/dlopen/*.c src/main/android/*.c
         src/thread/pthread/*.c src/timer/unix/*.c src/video/android/*.c src/haptic/dummy/*.c
         src/thread/pthread/*.c src/timer/unix/*.c src/video/android/*.c src/haptic/dummy/*.c
     )
     )
 else ()
 else ()

+ 23 - 42
Source/ThirdParty/SDL/CREDITS.txt

@@ -5,64 +5,45 @@ Thanks to everyone who made this possible, including:
 * Cliff Matthews, for giving me a reason to start this project. :)
 * Cliff Matthews, for giving me a reason to start this project. :)
  -- Executor rocks!  *grin*
  -- Executor rocks!  *grin*
 
 
-* The Linux Fund, C Magazine, Educational Technology Resources Inc.,
-  Gareth Noyce, Jesse Pavel, Keith Kitchin, Jeremy Horvath, Thomas Nicholson,
-  Hans-Peter Gygax, the Eternal Lands Development Team, Lars Brubaker,
-  and Phoenix Kokido for financial contributions
-
-* Edgar "bobbens" Simo for his force feedback API development during the
-  Google Summer of Code 2008
-
-* Aaron Wishnick for his work on audio resampling and pitch shifting during
-  the Google Summer of Code 2008
-
-* Holmes Futrell for port of SDL to the iPhone and iPod Touch during the
-  Google Summer of Code 2008
-
-* Szymon "Wilku" Wilczek for adding support for multiple mice and tablets
-  during the Google Summer of Code 2008
+* Ryan Gordon for helping everybody out and keeping the dream alive. :)
 
 
-* Marty Leisner, Andrew, Will, Edgar Simo, Donny Viszneki, Andrea Mazzoleni,
-  Dmytro Bogovych, and Couriersud for helping find SDL 1.3 bugs in the great
-  SDL Bug Hunt of January 2009!
+* Gabriel Jacobo for his work on the Android port and generally helping out all around.
+ 
+* Philipp Wiesemann for his attention to detail reviewing the entire SDL code base and proposes patches.
 
 
-* Donny Viszneki for helping fix SDL 1.3 bugs in the great SDL Bug Hunt of
-  January 2009!
+* Andreas Schiffler for his dedication to unit tests, Visual Studio projects, and managing the Google Summer of Code.
 
 
-* Luke Benstead for OpenGL 3.0 support
+* Mike Sartain for incorporating SDL into Team Fortress 2 and cheering me on at Valve.
 
 
-* Gaëtan de Menten for writing the PHP and SQL behind the SDL website
+* Alfred Reynolds for the game controller API and general (in)sanity
 
 
-* Tim Jones for the new look of the SDL website
+* Jørgen Tjernø for numerous magical Mac OS X fixes.
 
 
-* Ryan Gordon for helping everybody out and keeping the dream alive. :)
+* Pierre-Loup Griffais for his deep knowledge of OpenGL drivers.
+ 
+* Sheena Smith for many months of great work on the SDL wiki creating the API documentation and style guides.
 
 
-* Mattias Engdegård, for help with the Solaris port and lots of other help
+* Paul Hunkin for his port of SDL to Android during the Google Summer of Code 2010.
 
 
-* Eric Wing, Max Horn, and Darrell Walisser for unflagging work on the Mac OS X port
+* Eli Gottlieb for his work on shaped windows during the Google Summer of Code 2010.
 
 
-* David Carré, for the Pandora port
+* Jim Grandpre for his work on multi-touch and gesture recognition during
+  the Google Summer of Code 2010.
 
 
-* Couriersud for the DirectFB driver
+* Edgar "bobbens" Simo for his force feedback API development during the
+  Google Summer of Code 2008.
 
 
-* Jon Atkins for SDL_image, SDL_mixer and SDL_net documentation
+* Aaron Wishnick for his work on audio resampling and pitch shifting during
+  the Google Summer of Code 2008.
 
 
-* Arne Claus, for the 2004 winning SDL logo,
-  and Shandy Brown, Jac, Alex Lyman, Mikkel Gjoel, #Guy, Jonas Hartmann,
-  Daniel Liljeberg,  Ronald Sowa, DocD, Pekka Jaervinen, Patrick Avella,
-  Erkki Kontilla, Levon Gavalian, Hal Emerich, David Wiktorsson,
-  S. Schury and F. Hufsky, Ciska de Ruyver, Shredweat, Tyler Montbriand,
-  Martin Andersson, Merlyn Wysard, Fernando Ibanez, David Miller,
-  Andre Bommele, lovesby.com, Francisco Camenforte Torres, and David Igreja
-  for other logo entries.
+* Holmes Futrell for his port of SDL to the iPhone and iPod Touch during the
+  Google Summer of Code 2008.
 
 
-* Bob Pendleton and David Olofson for being long time contributors to
-  the SDL mailing list.
+* Jon Atkins for SDL_image, SDL_mixer and SDL_net documentation.
 
 
 * Everybody at Loki Software, Inc. for their great contributions!
 * Everybody at Loki Software, Inc. for their great contributions!
 
 
- And a big hand to everyone else who gave me appreciation, advice,
- and suggestions, especially the good folks on the SDL mailing list.
+ And a big hand to everyone else who has contributed over the years.
 
 
 THANKS! :)
 THANKS! :)
 
 

+ 11 - 12
Source/ThirdParty/SDL/README.txt

@@ -8,18 +8,17 @@
 ---
 ---
 http://www.libsdl.org/
 http://www.libsdl.org/
 
 
-This is the Simple DirectMedia Layer, a general API that provides low
-level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL,
-and 2D framebuffer across multiple platforms.
-
-The current version supports Windows, Mac OS X, Linux, FreeBSD,
-NetBSD, OpenBSD, BSD/OS, Solaris, iOS, and Android. The code contains
-support for other operating systems but those are not officially supported.
-
-SDL is written in C, but works with C++ natively, and has bindings to
-several other languages, including Ada, C#, Eiffel, Erlang, Euphoria,
-Go, Guile, Haskell, Java, Lisp, Lua, ML, Objective C, Pascal, Perl, PHP,
-Pike, Pliant, Python, Ruby, and Smalltalk.
+Simple DirectMedia Layer is a cross-platform development library designed
+to provide low level access to audio, keyboard, mouse, joystick, and graphics
+hardware via OpenGL and Direct3D. It is used by video playback software,
+emulators, and popular games including Valve's award winning catalog
+and many Humble Bundle games.
+
+SDL officially supports Windows, Mac OS X, Linux, iOS, and Android.
+Support for other platforms may be found in the source code.
+
+SDL is written in C, works natively with C++, and there are bindings 
+available for several other languages, including C# and Python.
 
 
 This library is distributed under the zlib license, which can be found
 This library is distributed under the zlib license, which can be found
 in the file "COPYING.txt".
 in the file "COPYING.txt".

+ 6 - 5
Source/ThirdParty/SDL/include/SDL.h

@@ -106,13 +106,14 @@ extern "C" {
 /*@{*/
 /*@{*/
 #define SDL_INIT_TIMER          0x00000001
 #define SDL_INIT_TIMER          0x00000001
 #define SDL_INIT_AUDIO          0x00000010
 #define SDL_INIT_AUDIO          0x00000010
-#define SDL_INIT_VIDEO          0x00000020
-#define SDL_INIT_JOYSTICK       0x00000200
+#define SDL_INIT_VIDEO          0x00000020  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
+#define SDL_INIT_JOYSTICK       0x00000200  /**< SDL_INIT_JOYSTICK implies SDL_INIT_EVENTS */
 #define SDL_INIT_HAPTIC         0x00001000
 #define SDL_INIT_HAPTIC         0x00001000
-#define SDL_INIT_GAMECONTROLLER 0x00002000      /**< turn on game controller also implicitly does JOYSTICK */
-#define SDL_INIT_NOPARACHUTE    0x00100000      /**< Don't catch fatal signals */
+#define SDL_INIT_GAMECONTROLLER 0x00002000  /**< SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK */
+#define SDL_INIT_EVENTS         0x00004000
+#define SDL_INIT_NOPARACHUTE    0x00100000  /**< Don't catch fatal signals */
 #define SDL_INIT_EVERYTHING ( \
 #define SDL_INIT_EVERYTHING ( \
-                SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | \
+                SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | \
                 SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER \
                 SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER \
             )
             )
 /*@}*/
 /*@}*/

+ 47 - 0
Source/ThirdParty/SDL/include/SDL_atomic.h

@@ -45,6 +45,7 @@
  *
  *
  * There's also lots of good information here:
  * There's also lots of good information here:
  * http://www.1024cores.net/home/lock-free-algorithms
  * http://www.1024cores.net/home/lock-free-algorithms
+ * http://preshing.com/
  *
  *
  * These operations may or may not actually be implemented using
  * These operations may or may not actually be implemented using
  * processor specific atomic operations. When possible they are
  * processor specific atomic operations. When possible they are
@@ -135,6 +136,52 @@ void _ReadWriteBarrier(void);
 { SDL_SpinLock _tmp = 0; SDL_AtomicLock(&_tmp); SDL_AtomicUnlock(&_tmp); }
 { SDL_SpinLock _tmp = 0; SDL_AtomicLock(&_tmp); SDL_AtomicUnlock(&_tmp); }
 #endif
 #endif
 
 
+/**
+ * Memory barriers are designed to prevent reads and writes from being
+ * reordered by the compiler and being seen out of order on multi-core CPUs.
+ *
+ * A typical pattern would be for thread A to write some data and a flag,
+ * and for thread B to read the flag and get the data. In this case you
+ * would insert a release barrier between writing the data and the flag,
+ * guaranteeing that the data write completes no later than the flag is
+ * written, and you would insert an acquire barrier between reading the
+ * flag and reading the data, to ensure that all the reads associated
+ * with the flag have completed.
+ *
+ * In this pattern you should always see a release barrier paired with
+ * an acquire barrier and you should gate the data reads/writes with a
+ * single flag variable.
+ *
+ * For more information on these semantics, take a look at the blog post:
+ * http://preshing.com/20120913/acquire-and-release-semantics
+ */
+#if defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
+#define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("lwsync" : : : "memory")
+#define SDL_MemoryBarrierAcquire()   __asm__ __volatile__ ("lwsync" : : : "memory")
+#elif defined(__GNUC__) && defined(__arm__)
+#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
+#define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("dmb ish" : : : "memory")
+#define SDL_MemoryBarrierAcquire()   __asm__ __volatile__ ("dmb ish" : : : "memory")
+#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__)
+#ifdef __thumb__
+/* The mcr instruction isn't available in thumb mode, use real functions */
+extern DECLSPEC void SDLCALL SDL_MemoryBarrierRelease();
+extern DECLSPEC void SDLCALL SDL_MemoryBarrierAcquire();
+#else
+#define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory")
+#define SDL_MemoryBarrierAcquire()   __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory")
+#endif /* __thumb__ */
+#else
+#define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("" : : : "memory")
+#define SDL_MemoryBarrierAcquire()   __asm__ __volatile__ ("" : : : "memory")
+#endif /* __GNUC__ && __arm__ */
+#else
+/* This is correct for the x86 and x64 CPUs, and we'll expand this over time. */
+#define SDL_MemoryBarrierRelease()  SDL_CompilerBarrier()
+#define SDL_MemoryBarrierAcquire()  SDL_CompilerBarrier()
+#endif
+
+
 /* Platform specific optimized versions of the atomic functions,
 /* Platform specific optimized versions of the atomic functions,
  * you can disable these by defining SDL_DISABLE_ATOMIC_INLINE
  * you can disable these by defining SDL_DISABLE_ATOMIC_INLINE
  */
  */

+ 12 - 7
Source/ThirdParty/SDL/include/SDL_audio.h

@@ -183,6 +183,17 @@ typedef void (SDLCALL * SDL_AudioFilter) (struct SDL_AudioCVT * cvt,
 /**
 /**
  *  A structure to hold a set of audio conversion filters and buffers.
  *  A structure to hold a set of audio conversion filters and buffers.
  */
  */
+#ifdef __GNUC__
+/* This structure is 84 bytes on 32-bit architectures, make sure GCC doesn't
+   pad it out to 88 bytes to guarantee ABI compatibility between compilers.
+   vvv
+   The next time we rev the ABI, make sure to size the ints and add padding.
+*/
+#define SDL_AUDIOCVT_PACKED __attribute__((packed))
+#else
+#define SDL_AUDIOCVT_PACKED
+#endif
+/* */
 typedef struct SDL_AudioCVT
 typedef struct SDL_AudioCVT
 {
 {
     int needed;                 /**< Set to 1 if conversion possible */
     int needed;                 /**< Set to 1 if conversion possible */
@@ -196,7 +207,7 @@ typedef struct SDL_AudioCVT
     double len_ratio;           /**< Given len, final size is len*len_ratio */
     double len_ratio;           /**< Given len, final size is len*len_ratio */
     SDL_AudioFilter filters[10];        /**< Filter list */
     SDL_AudioFilter filters[10];        /**< Filter list */
     int filter_index;           /**< Current audio conversion function */
     int filter_index;           /**< Current audio conversion function */
-} SDL_AudioCVT;
+} SDL_AUDIOCVT_PACKED SDL_AudioCVT;
 
 
 
 
 /* Function prototypes */
 /* Function prototypes */
@@ -484,12 +495,6 @@ extern DECLSPEC void SDLCALL SDL_UnlockAudioDevice(SDL_AudioDeviceID dev);
 extern DECLSPEC void SDLCALL SDL_CloseAudio(void);
 extern DECLSPEC void SDLCALL SDL_CloseAudio(void);
 extern DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID dev);
 extern DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID dev);
 
 
-/**
- * \return 1 if audio device is still functioning, zero if not, -1 on error.
- */
-extern DECLSPEC int SDLCALL SDL_AudioDeviceConnected(SDL_AudioDeviceID dev);
-
-
 /* Ends C function definitions when using C++ */
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }

+ 11 - 4
Source/ThirdParty/SDL/include/SDL_bits.h

@@ -45,15 +45,18 @@ extern "C" {
  *  with 0. This operation can also be stated as "count leading zeroes" and
  *  with 0. This operation can also be stated as "count leading zeroes" and
  *  "log base 2".
  *  "log base 2".
  *
  *
- *  \return Index of the most significant bit.
+ *  \return Index of the most significant bit, or -1 if the value is 0.
  */
  */
-SDL_FORCE_INLINE Sint8
+SDL_FORCE_INLINE int
 SDL_MostSignificantBitIndex32(Uint32 x)
 SDL_MostSignificantBitIndex32(Uint32 x)
 {
 {
 #if defined(__GNUC__) && __GNUC__ >= 4
 #if defined(__GNUC__) && __GNUC__ >= 4
     /* Count Leading Zeroes builtin in GCC.
     /* Count Leading Zeroes builtin in GCC.
      * http://gcc.gnu.org/onlinedocs/gcc-4.3.4/gcc/Other-Builtins.html
      * http://gcc.gnu.org/onlinedocs/gcc-4.3.4/gcc/Other-Builtins.html
      */
      */
+    if (x == 0) {
+        return -1;
+    }
     return 31 - __builtin_clz(x);
     return 31 - __builtin_clz(x);
 #else
 #else
     /* Based off of Bit Twiddling Hacks by Sean Eron Anderson
     /* Based off of Bit Twiddling Hacks by Sean Eron Anderson
@@ -61,11 +64,15 @@ SDL_MostSignificantBitIndex32(Uint32 x)
      * http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog
      * http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog
      */
      */
     const Uint32 b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
     const Uint32 b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
-    const Uint8  S[] = {1, 2, 4, 8, 16};
+    const int    S[] = {1, 2, 4, 8, 16};
 
 
-    Uint8 msbIndex = 0;
+    int msbIndex = 0;
     int i;
     int i;
 
 
+    if (x == 0) {
+        return -1;
+    }
+
     for (i = 4; i >= 0; i--)
     for (i = 4; i >= 0; i--)
     {
     {
         if (x & b[i])
         if (x & b[i])

+ 11 - 4
Source/ThirdParty/SDL/include/SDL_blendmode.h

@@ -39,10 +39,17 @@ extern "C" {
  */
  */
 typedef enum
 typedef enum
 {
 {
-    SDL_BLENDMODE_NONE = 0x00000000,     /**< No blending */
-    SDL_BLENDMODE_BLEND = 0x00000001,    /**< dst = (src * A) + (dst * (1-A)) */
-    SDL_BLENDMODE_ADD = 0x00000002,      /**< dst = (src * A) + dst */
-    SDL_BLENDMODE_MOD = 0x00000004       /**< dst = src * dst */
+    SDL_BLENDMODE_NONE = 0x00000000,     /**< no blending
+                                              dstRGBA = srcRGBA */
+    SDL_BLENDMODE_BLEND = 0x00000001,    /**< alpha blending
+                                              dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA))
+                                              dstA = srcA + (dstA * (1-srcA)) */
+    SDL_BLENDMODE_ADD = 0x00000002,      /**< additive blending
+                                              dstRGB = (srcRGB * srcA) + dstRGB
+                                              dstA = dstA */
+    SDL_BLENDMODE_MOD = 0x00000004       /**< color modulate
+                                              dstRGB = srcRGB * dstRGB
+                                              dstA = dstA */
 } SDL_BlendMode;
 } SDL_BlendMode;
 
 
 /* Ends C function definitions when using C++ */
 /* Ends C function definitions when using C++ */

+ 5 - 5
Source/ThirdParty/SDL/include/SDL_config.h

@@ -1,6 +1,6 @@
 /*
 /*
   Simple DirectMedia Layer
   Simple DirectMedia Layer
-  Copyright (C) 1997-2011 Sam Lantinga <[email protected]>
+  Copyright (C) 1997-2013 Sam Lantinga <[email protected]>
 
 
   This software is provided 'as-is', without any express or implied
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
   warranty.  In no event will the authors be held liable for any damages
@@ -30,17 +30,17 @@
  *  \file SDL_config.h
  *  \file SDL_config.h
  */
  */
 
 
-// Urho3D: choose from prebuilt config files on all OSes
+// Urho3D: choose from prebuilt config files on all platforms
 #if defined(__WIN32__)
 #if defined(__WIN32__)
 #include "SDL_config_windows.h"
 #include "SDL_config_windows.h"
 #elif defined(__MACOSX__)
 #elif defined(__MACOSX__)
 #include "SDL_config_macosx.h"
 #include "SDL_config_macosx.h"
-#elif defined(__IPHONEOS__) 
+#elif defined(__IPHONEOS__)
 #include "SDL_config_iphoneos.h"
 #include "SDL_config_iphoneos.h"
 #elif defined(__ANDROID__)
 #elif defined(__ANDROID__)
 #include "SDL_config_android.h"
 #include "SDL_config_android.h"
-#elif defined(__NINTENDODS__)
-#include "SDL_config_nintendods.h"
+#elif defined(__PSP__)
+#include "SDL_config_psp.h"
 #else
 #else
 #include "SDL_config_linux.h"
 #include "SDL_config_linux.h"
 #endif /* platform config */
 #endif /* platform config */

+ 2 - 4
Source/ThirdParty/SDL/include/SDL_config_android.h

@@ -19,8 +19,6 @@
   3. This notice may not be removed or altered from any source distribution.
   3. This notice may not be removed or altered from any source distribution.
 */
 */
 
 
-// Modified by Lasse Oorni for Urho3D
-
 #ifndef _SDL_config_android_h
 #ifndef _SDL_config_android_h
 #define _SDL_config_android_h
 #define _SDL_config_android_h
 
 
@@ -34,6 +32,8 @@
 
 
 #include <stdarg.h>
 #include <stdarg.h>
 
 
+#define HAVE_GCC_ATOMICS    1
+
 #define HAVE_ALLOCA_H       1
 #define HAVE_ALLOCA_H       1
 #define HAVE_SYS_TYPES_H    1
 #define HAVE_SYS_TYPES_H    1
 #define HAVE_STDIO_H    1
 #define HAVE_STDIO_H    1
@@ -103,8 +103,6 @@
 #define HAVE_SETJMP 1
 #define HAVE_SETJMP 1
 #define HAVE_NANOSLEEP  1
 #define HAVE_NANOSLEEP  1
 #define HAVE_SYSCONF    1
 #define HAVE_SYSCONF    1
-// Urho3D: enable use of GCC atomics
-#define HAVE_GCC_ATOMICS 1
 
 
 #define SIZEOF_VOIDP 4
 #define SIZEOF_VOIDP 4
 
 

+ 0 - 3
Source/ThirdParty/SDL/include/SDL_config_macosx.h

@@ -36,10 +36,7 @@
 #endif
 #endif
 
 
 /* Useful headers */
 /* Useful headers */
-/* If we specified an SDK or have a post-PowerPC chip, then alloca.h exists. */
-#if ( (MAC_OS_X_VERSION_MIN_REQUIRED >= 1030) || (!defined(__POWERPC__)) )
 #define HAVE_ALLOCA_H       1
 #define HAVE_ALLOCA_H       1
-#endif
 #define HAVE_SYS_TYPES_H    1
 #define HAVE_SYS_TYPES_H    1
 #define HAVE_STDIO_H    1
 #define HAVE_STDIO_H    1
 #define STDC_HEADERS    1
 #define STDC_HEADERS    1

+ 2 - 3
Source/ThirdParty/SDL/include/SDL_config_windows.h

@@ -78,9 +78,8 @@ typedef unsigned int uintptr_t;
 # define SIZEOF_VOIDP 4
 # define SIZEOF_VOIDP 4
 #endif
 #endif
 
 
-/* Enabled for SDL 1.2 (binary compatibility) */
-// Urho3D: enable libc
-#define HAVE_LIBC     1
+/* This is disabled by default to avoid C runtime dependencies and manifest requirements */
+//#define HAVE_LIBC     1
 #ifdef HAVE_LIBC
 #ifdef HAVE_LIBC
 /* Useful headers */
 /* Useful headers */
 #define HAVE_STDIO_H 1
 #define HAVE_STDIO_H 1

+ 4 - 0
Source/ThirdParty/SDL/include/SDL_gamecontroller.h

@@ -44,6 +44,10 @@ extern "C" {
  *  In order to use these functions, SDL_Init() must have been called
  *  In order to use these functions, SDL_Init() must have been called
  *  with the ::SDL_INIT_JOYSTICK flag.  This causes SDL to scan the system
  *  with the ::SDL_INIT_JOYSTICK flag.  This causes SDL to scan the system
  *  for game controllers, and load appropriate drivers.
  *  for game controllers, and load appropriate drivers.
+ *
+ *  If you would like to receive controller updates while the application
+ *  is in the background, you should set the following hint before calling
+ *  SDL_Init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS
  */
  */
 
 
 /* The gamecontroller structure used to identify an SDL game controller */
 /* The gamecontroller structure used to identify an SDL game controller */

+ 42 - 12
Source/ThirdParty/SDL/include/SDL_haptic.h

@@ -166,13 +166,18 @@ typedef struct _SDL_Haptic SDL_Haptic;
 #define SDL_HAPTIC_SINE       (1<<1)
 #define SDL_HAPTIC_SINE       (1<<1)
 
 
 /**
 /**
- *  \brief Square wave effect supported.
+ *  \brief Left/Right effect supported.
  *
  *
- *  Periodic haptic effect that simulates square waves.
+ *  Haptic effect for direct control over high/low frequency motors.
  *
  *
- *  \sa SDL_HapticPeriodic
+ *  \sa SDL_HapticLeftRight
+ * \warning this value was SDL_HAPTIC_SQUARE right before 2.0.0 shipped. Sorry,
+ *          we ran out of bits, and this is important for XInput devices.
  */
  */
-#define SDL_HAPTIC_SQUARE     (1<<2)
+#define SDL_HAPTIC_LEFTRIGHT     (1<<2)
+
+/* !!! FIXME: put this back when we have more bits in 2.1 */
+/*#define SDL_HAPTIC_SQUARE     (1<<2)*/
 
 
 /**
 /**
  *  \brief Triangle wave effect supported.
  *  \brief Triangle wave effect supported.
@@ -478,7 +483,7 @@ typedef struct SDL_HapticConstant
  *
  *
  *  The struct handles the following effects:
  *  The struct handles the following effects:
  *   - ::SDL_HAPTIC_SINE
  *   - ::SDL_HAPTIC_SINE
- *   - ::SDL_HAPTIC_SQUARE
+ *   - ::SDL_HAPTIC_LEFTRIGHT
  *   - ::SDL_HAPTIC_TRIANGLE
  *   - ::SDL_HAPTIC_TRIANGLE
  *   - ::SDL_HAPTIC_SAWTOOTHUP
  *   - ::SDL_HAPTIC_SAWTOOTHUP
  *   - ::SDL_HAPTIC_SAWTOOTHDOWN
  *   - ::SDL_HAPTIC_SAWTOOTHDOWN
@@ -524,7 +529,7 @@ typedef struct SDL_HapticConstant
     \endverbatim
     \endverbatim
  *
  *
  *  \sa SDL_HAPTIC_SINE
  *  \sa SDL_HAPTIC_SINE
- *  \sa SDL_HAPTIC_SQUARE
+ *  \sa SDL_HAPTIC_LEFTRIGHT
  *  \sa SDL_HAPTIC_TRIANGLE
  *  \sa SDL_HAPTIC_TRIANGLE
  *  \sa SDL_HAPTIC_SAWTOOTHUP
  *  \sa SDL_HAPTIC_SAWTOOTHUP
  *  \sa SDL_HAPTIC_SAWTOOTHDOWN
  *  \sa SDL_HAPTIC_SAWTOOTHDOWN
@@ -533,7 +538,7 @@ typedef struct SDL_HapticConstant
 typedef struct SDL_HapticPeriodic
 typedef struct SDL_HapticPeriodic
 {
 {
     /* Header */
     /* Header */
-    Uint16 type;        /**< ::SDL_HAPTIC_SINE, ::SDL_HAPTIC_SQUARE,
+    Uint16 type;        /**< ::SDL_HAPTIC_SINE, ::SDL_HAPTIC_LEFTRIGHT,
                              ::SDL_HAPTIC_TRIANGLE, ::SDL_HAPTIC_SAWTOOTHUP or
                              ::SDL_HAPTIC_TRIANGLE, ::SDL_HAPTIC_SAWTOOTHUP or
                              ::SDL_HAPTIC_SAWTOOTHDOWN */
                              ::SDL_HAPTIC_SAWTOOTHDOWN */
     SDL_HapticDirection direction;  /**< Direction of the effect. */
     SDL_HapticDirection direction;  /**< Direction of the effect. */
@@ -645,6 +650,31 @@ typedef struct SDL_HapticRamp
     Uint16 fade_level;      /**< Level at the end of the fade. */
     Uint16 fade_level;      /**< Level at the end of the fade. */
 } SDL_HapticRamp;
 } SDL_HapticRamp;
 
 
+/**
+ * \brief A structure containing a template for a Left/Right effect.
+ *
+ * This struct is exclusively for the ::SDL_HAPTIC_LEFTRIGHT effect.
+ *
+ * The Left/Right effect is used to explicitly control the large and small
+ * motors, commonly found in modern game controllers. One motor is high
+ * frequency, the other is low frequency.
+ *
+ * \sa SDL_HAPTIC_LEFTRIGHT
+ * \sa SDL_HapticEffect
+ */
+typedef struct SDL_HapticLeftRight
+{
+    /* Header */
+    Uint16 type;            /**< ::SDL_HAPTIC_LEFTRIGHT */
+
+    /* Replay */
+    Uint32 length;          /**< Duration of the effect. */
+
+    /* Rumble */
+    Uint16 large_magnitude; /**< Control of the large controller motor. */
+    Uint16 small_magnitude; /**< Control of the small controller motor. */
+} SDL_HapticLeftRight;
+
 /**
 /**
  *  \brief A structure containing a template for the ::SDL_HAPTIC_CUSTOM effect.
  *  \brief A structure containing a template for the ::SDL_HAPTIC_CUSTOM effect.
  *
  *
@@ -751,6 +781,7 @@ typedef struct SDL_HapticCustom
  *  \sa SDL_HapticPeriodic
  *  \sa SDL_HapticPeriodic
  *  \sa SDL_HapticCondition
  *  \sa SDL_HapticCondition
  *  \sa SDL_HapticRamp
  *  \sa SDL_HapticRamp
+ *  \sa SDL_HapticLeftRight
  *  \sa SDL_HapticCustom
  *  \sa SDL_HapticCustom
  */
  */
 typedef union SDL_HapticEffect
 typedef union SDL_HapticEffect
@@ -761,6 +792,7 @@ typedef union SDL_HapticEffect
     SDL_HapticPeriodic periodic;    /**< Periodic effect. */
     SDL_HapticPeriodic periodic;    /**< Periodic effect. */
     SDL_HapticCondition condition;  /**< Condition effect. */
     SDL_HapticCondition condition;  /**< Condition effect. */
     SDL_HapticRamp ramp;            /**< Ramp effect. */
     SDL_HapticRamp ramp;            /**< Ramp effect. */
+    SDL_HapticLeftRight leftright;  /**< Left/Right effect. */
     SDL_HapticCustom custom;        /**< Custom effect. */
     SDL_HapticCustom custom;        /**< Custom effect. */
 } SDL_HapticEffect;
 } SDL_HapticEffect;
 
 
@@ -926,7 +958,7 @@ extern DECLSPEC int SDLCALL SDL_HapticNumEffectsPlaying(SDL_Haptic * haptic);
  *
  *
  *  Example:
  *  Example:
  *  \code
  *  \code
- *  if (SDL_HapticQueryEffects(haptic) & SDL_HAPTIC_CONSTANT) {
+ *  if (SDL_HapticQuery(haptic) & SDL_HAPTIC_CONSTANT) {
  *      printf("We have constant haptic effect!");
  *      printf("We have constant haptic effect!");
  *  }
  *  }
  *  \endcode
  *  \endcode
@@ -986,7 +1018,7 @@ extern DECLSPEC int SDLCALL SDL_HapticNewEffect(SDL_Haptic * haptic,
  *  \param haptic Haptic device that has the effect.
  *  \param haptic Haptic device that has the effect.
  *  \param effect Effect to update.
  *  \param effect Effect to update.
  *  \param data New effect properties to use.
  *  \param data New effect properties to use.
- *  \return The id of the effect on success or -1 on error.
+ *  \return 0 on success or -1 on error.
  *
  *
  *  \sa SDL_HapticNewEffect
  *  \sa SDL_HapticNewEffect
  *  \sa SDL_HapticRunEffect
  *  \sa SDL_HapticRunEffect
@@ -1132,7 +1164,7 @@ extern DECLSPEC int SDLCALL SDL_HapticUnpause(SDL_Haptic * haptic);
 extern DECLSPEC int SDLCALL SDL_HapticStopAll(SDL_Haptic * haptic);
 extern DECLSPEC int SDLCALL SDL_HapticStopAll(SDL_Haptic * haptic);
 
 
 /**
 /**
- *  \brief Checks to see if rumble is supported on a haptic device..
+ *  \brief Checks to see if rumble is supported on a haptic device.
  *
  *
  *  \param haptic Haptic device to check to see if it supports rumble.
  *  \param haptic Haptic device to check to see if it supports rumble.
  *  \return SDL_TRUE if effect is supported, SDL_FALSE if it isn't or -1 on error.
  *  \return SDL_TRUE if effect is supported, SDL_FALSE if it isn't or -1 on error.
@@ -1182,8 +1214,6 @@ extern DECLSPEC int SDLCALL SDL_HapticRumblePlay(SDL_Haptic * haptic, float stre
  */
  */
 extern DECLSPEC int SDLCALL SDL_HapticRumbleStop(SDL_Haptic * haptic);
 extern DECLSPEC int SDLCALL SDL_HapticRumbleStop(SDL_Haptic * haptic);
 
 
-
-
 /* Ends C function definitions when using C++ */
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }

+ 43 - 4
Source/ThirdParty/SDL/include/SDL_hints.h

@@ -100,7 +100,7 @@ extern "C" {
  *  This variable can be set to the following values:
  *  This variable can be set to the following values:
  *    "0" or "nearest" - Nearest pixel sampling
  *    "0" or "nearest" - Nearest pixel sampling
  *    "1" or "linear"  - Linear filtering (supported by OpenGL and Direct3D)
  *    "1" or "linear"  - Linear filtering (supported by OpenGL and Direct3D)
- *    "2" or "best"    - Anisotropic filtering (supported by Direct3D)
+ *    "2" or "best"    - Currently this is the same as "linear"
  *
  *
  *  By default nearest pixel sampling is used
  *  By default nearest pixel sampling is used
  */
  */
@@ -218,13 +218,13 @@ extern "C" {
 /**
 /**
  *  \brief  A variable that lets you enable joystick (and gamecontroller) events even when your app is in the background.
  *  \brief  A variable that lets you enable joystick (and gamecontroller) events even when your app is in the background.
  *
  *
- * The default value is "0".
- *
  *  The variable can be set to the following values:
  *  The variable can be set to the following values:
  *    "0"       - Disable joystick & gamecontroller input events when the
  *    "0"       - Disable joystick & gamecontroller input events when the
  *                application is in the background.
  *                application is in the background.
  *    "1"       - Enable joystick & gamecontroller input events when the
  *    "1"       - Enable joystick & gamecontroller input events when the
  *                application is in the backgroumd.
  *                application is in the backgroumd.
+ *
+ *  The default value is "0".  This hint may be set at any time.
  */
  */
 #define SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS"
 #define SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS"
 
 
@@ -240,6 +240,23 @@ extern "C" {
 #define SDL_HINT_ALLOW_TOPMOST "SDL_ALLOW_TOPMOST"
 #define SDL_HINT_ALLOW_TOPMOST "SDL_ALLOW_TOPMOST"
 
 
 
 
+/**
+ *  \brief A variable that controls the timer resolution, in milliseconds.
+ *
+ *  The higher resolution the timer, the more frequently the CPU services
+ *  timer interrupts, and the more precise delays are, but this takes up
+ *  power and CPU time.  This hint is only used on Windows 7 and earlier.
+ *
+ *  See this blog post for more information:
+ *  http://randomascii.wordpress.com/2013/07/08/windows-timer-resolution-megawatts-wasted/
+ *
+ *  If this variable is set to "0", the system timer resolution is not set.
+ *
+ *  The default value is "1". This hint may be set at any time.
+ */
+#define SDL_HINT_TIMER_RESOLUTION "SDL_TIMER_RESOLUTION"
+
+
 
 
 /**
 /**
  *  \brief  An enumeration of hint priorities
  *  \brief  An enumeration of hint priorities
@@ -273,7 +290,6 @@ extern DECLSPEC SDL_bool SDLCALL SDL_SetHintWithPriority(const char *name,
 extern DECLSPEC SDL_bool SDLCALL SDL_SetHint(const char *name,
 extern DECLSPEC SDL_bool SDLCALL SDL_SetHint(const char *name,
                                              const char *value);
                                              const char *value);
 
 
-
 /**
 /**
  *  \brief Get a hint
  *  \brief Get a hint
  *
  *
@@ -281,6 +297,29 @@ extern DECLSPEC SDL_bool SDLCALL SDL_SetHint(const char *name,
  */
  */
 extern DECLSPEC const char * SDLCALL SDL_GetHint(const char *name);
 extern DECLSPEC const char * SDLCALL SDL_GetHint(const char *name);
 
 
+/**
+ *  \brief Add a function to watch a particular hint
+ *
+ *  \param name The hint to watch
+ *  \param callback The function to call when the hint value changes
+ *  \param userdata A pointer to pass to the callback function
+ */
+typedef void (*SDL_HintCallback)(void *userdata, const char *name, const char *oldValue, const char *newValue);
+extern DECLSPEC void SDLCALL SDL_AddHintCallback(const char *name,
+                                                 SDL_HintCallback callback,
+                                                 void *userdata);
+
+/**
+ *  \brief Remove a function watching a particular hint
+ *
+ *  \param name The hint being watched
+ *  \param callback The function being called when the hint value changes
+ *  \param userdata A pointer being passed to the callback function
+ */
+extern DECLSPEC void SDLCALL SDL_DelHintCallback(const char *name,
+                                                 SDL_HintCallback callback,
+                                                 void *userdata);
+
 /**
 /**
  *  \brief  Clear all hints
  *  \brief  Clear all hints
  *
  *

+ 4 - 0
Source/ThirdParty/SDL/include/SDL_joystick.h

@@ -54,6 +54,10 @@ extern "C" {
  *  In order to use these functions, SDL_Init() must have been called
  *  In order to use these functions, SDL_Init() must have been called
  *  with the ::SDL_INIT_JOYSTICK flag.  This causes SDL to scan the system
  *  with the ::SDL_INIT_JOYSTICK flag.  This causes SDL to scan the system
  *  for joysticks, and load appropriate drivers.
  *  for joysticks, and load appropriate drivers.
+ *
+ *  If you would like to receive joystick updates while the application
+ *  is in the background, you should set the following hint before calling
+ *  SDL_Init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS
  */
  */
 
 
 /* The joystick structure used to identify an SDL joystick */
 /* The joystick structure used to identify an SDL joystick */

+ 7 - 1
Source/ThirdParty/SDL/include/SDL_platform.h

@@ -83,6 +83,12 @@
 /* if not compiling for iPhone */
 /* if not compiling for iPhone */
 #undef __MACOSX__
 #undef __MACOSX__
 #define __MACOSX__  1
 #define __MACOSX__  1
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
+# error SDL for Mac OS X only supports deploying on 10.5 and above.
+#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1050 */
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060
+# error SDL for Mac OS X must be built with a 10.6 SDK or above.
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1060 */
 #endif /* TARGET_OS_IPHONE */
 #endif /* TARGET_OS_IPHONE */
 #endif /* defined(__APPLE__) */
 #endif /* defined(__APPLE__) */
 
 
@@ -114,7 +120,7 @@
 #undef __SOLARIS__
 #undef __SOLARIS__
 #define __SOLARIS__ 1
 #define __SOLARIS__ 1
 #endif
 #endif
-#if defined(WIN32) || defined(_WIN32)
+#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)
 #undef __WIN32__
 #undef __WIN32__
 #define __WIN32__   1
 #define __WIN32__   1
 #endif
 #endif

+ 4 - 1
Source/ThirdParty/SDL/include/SDL_render.h

@@ -37,9 +37,12 @@
  *  them, and may also be stretched with linear interpolation.
  *  them, and may also be stretched with linear interpolation.
  *
  *
  *  This API is designed to accelerate simple 2D operations. You may
  *  This API is designed to accelerate simple 2D operations. You may
- *  want more functionality such as rotation and particle effects and
+ *  want more functionality such as polygons and particle effects and
  *  in that case you should use SDL's OpenGL/Direct3D support or one
  *  in that case you should use SDL's OpenGL/Direct3D support or one
  *  of the many good 3D engines.
  *  of the many good 3D engines.
+ *
+ *  These functions must be called from the main thread.
+ *  See this bug for details: http://bugzilla.libsdl.org/show_bug.cgi?id=1995
  */
  */
 
 
 #ifndef _SDL_render_h
 #ifndef _SDL_render_h

+ 2 - 2
Source/ThirdParty/SDL/include/SDL_revision.h

@@ -1,2 +1,2 @@
-#define SDL_REVISION "hg-0:aaaaaaaaaaah"
-#define SDL_REVISION_NUMBER 0
+#define SDL_REVISION "hg-7633:d6a8fa507a45"
+#define SDL_REVISION_NUMBER 7633

+ 1 - 1
Source/ThirdParty/SDL/include/SDL_shape.h

@@ -55,7 +55,7 @@ extern "C" {
  *  \param h     The height of the window.
  *  \param h     The height of the window.
  *  \param flags The flags for the window, a mask of SDL_WINDOW_BORDERLESS with any of the following:
  *  \param flags The flags for the window, a mask of SDL_WINDOW_BORDERLESS with any of the following:
  *               ::SDL_WINDOW_OPENGL,     ::SDL_WINDOW_INPUT_GRABBED,
  *               ::SDL_WINDOW_OPENGL,     ::SDL_WINDOW_INPUT_GRABBED,
- *               ::SDL_WINDOW_SHOWN,      ::SDL_WINDOW_RESIZABLE,
+ *               ::SDL_WINDOW_HIDDEN,     ::SDL_WINDOW_RESIZABLE,
  *               ::SDL_WINDOW_MAXIMIZED,  ::SDL_WINDOW_MINIMIZED,
  *               ::SDL_WINDOW_MAXIMIZED,  ::SDL_WINDOW_MINIMIZED,
  *       ::SDL_WINDOW_BORDERLESS is always set, and ::SDL_WINDOW_FULLSCREEN is always unset.
  *       ::SDL_WINDOW_BORDERLESS is always set, and ::SDL_WINDOW_FULLSCREEN is always unset.
  *
  *

+ 13 - 456
Source/ThirdParty/SDL/include/SDL_stdinc.h

@@ -19,8 +19,6 @@
   3. This notice may not be removed or altered from any source distribution.
   3. This notice may not be removed or altered from any source distribution.
 */
 */
 
 
-// Modified by Lasse Oorni for Urho3D
-
 /**
 /**
  *  \file SDL_stdinc.h
  *  \file SDL_stdinc.h
  *
  *
@@ -229,76 +227,17 @@ char *alloca();
 #define SDL_stack_free(data)            SDL_free(data)
 #define SDL_stack_free(data)            SDL_free(data)
 #endif
 #endif
 
 
-
-/* SDL stdinc inline functions:
-
-   The theory here is that by default we forcibly inline what we can, and your
-   app will use the inline version by default. However we expose a non-inline
-   version too, so the symbol is always available in the library even if your app
-   bypassed the inline version. The SDL_*_inline versions aren't guaranteed to
-   exist, so never call them directly; use SDL_* instead, and trust the system
-   to give you the right thing.
-
-   The benefit here is that you can dlsym() these functions, which you
-   couldn't if you had macros, you can link against a foreign build of SDL
-   even if you configured differently, and you can drop the unconfigured SDL
-   headers into a project without #defining HAVE_MALLOC (etc) and still link.
-
-   If you want to disable the inline functions and just use SDL's functions,
-   you can define SDL_STDINC_NO_INLINES before including this file.
-*/
-
 extern DECLSPEC void *SDLCALL SDL_malloc(size_t size);
 extern DECLSPEC void *SDLCALL SDL_malloc(size_t size);
-#if defined(HAVE_MALLOC) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE void *SDL_malloc_inline(size_t size) { return malloc(size); }
-#define SDL_malloc SDL_malloc_inline
-#endif
-
 extern DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size);
 extern DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size);
-#if defined(HAVE_CALLOC) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE void *SDL_calloc_inline(size_t nmemb, size_t size) { return calloc(nmemb, size); }
-#define SDL_calloc SDL_calloc_inline
-#endif
-
 extern DECLSPEC void *SDLCALL SDL_realloc(void *mem, size_t size);
 extern DECLSPEC void *SDLCALL SDL_realloc(void *mem, size_t size);
-#if defined(HAVE_REALLOC) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE void *SDL_realloc_inline(void *mem, size_t size) { return realloc(mem, size); }
-#define SDL_realloc SDL_realloc_inline
-#endif
-
 extern DECLSPEC void SDLCALL SDL_free(void *mem);
 extern DECLSPEC void SDLCALL SDL_free(void *mem);
-#if defined(HAVE_FREE) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE void SDL_free_inline(void *mem) { free(mem); }
-#define SDL_free SDL_free_inline
-#endif
 
 
 extern DECLSPEC char *SDLCALL SDL_getenv(const char *name);
 extern DECLSPEC char *SDLCALL SDL_getenv(const char *name);
-#if defined(HAVE_GETENV) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE char *SDL_getenv_inline(const char *name) { return getenv(name); }
-#define SDL_getenv SDL_getenv_inline
-#endif
-
 extern DECLSPEC int SDLCALL SDL_setenv(const char *name, const char *value, int overwrite);
 extern DECLSPEC int SDLCALL SDL_setenv(const char *name, const char *value, int overwrite);
-#if defined(HAVE_SETENV) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE int SDL_setenv_inline(const char *name, const char *value, int overwrite) { return setenv(name, value, overwrite); }
-#define SDL_setenv SDL_setenv_inline
-#endif
 
 
 extern DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, int (*compare) (const void *, const void *));
 extern DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, int (*compare) (const void *, const void *));
-#if defined(HAVE_QSORT) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE void SDL_qsort_inline(void *base, size_t nmemb, size_t size, int (*compare) (const void *, const void *)) { qsort(base, nmemb, size, compare); }
-#define SDL_qsort SDL_qsort_inline
-#endif
 
 
 extern DECLSPEC int SDLCALL SDL_abs(int x);
 extern DECLSPEC int SDLCALL SDL_abs(int x);
-#ifndef SDL_STDINC_NO_INLINES
-#ifdef HAVE_ABS
-SDL_FORCE_INLINE int SDL_abs_inline(int x) { return abs(x); }
-#else
-SDL_FORCE_INLINE int SDL_abs_inline(int x) { return ((x) < 0 ? -(x) : (x)); }
-#endif
-#define SDL_abs SDL_abs_inline
-#endif /* !SDL_STDINC_NO_INLINES */
 
 
 /* !!! FIXME: these have side effects. You probably shouldn't use them. */
 /* !!! FIXME: these have side effects. You probably shouldn't use them. */
 /* !!! FIXME: Maybe we do forceinline functions of SDL_mini, SDL_minf, etc? */
 /* !!! FIXME: Maybe we do forceinline functions of SDL_mini, SDL_minf, etc? */
@@ -309,35 +248,14 @@ extern DECLSPEC int SDLCALL SDL_isdigit(int x);
 extern DECLSPEC int SDLCALL SDL_isspace(int x);
 extern DECLSPEC int SDLCALL SDL_isspace(int x);
 extern DECLSPEC int SDLCALL SDL_toupper(int x);
 extern DECLSPEC int SDLCALL SDL_toupper(int x);
 extern DECLSPEC int SDLCALL SDL_tolower(int x);
 extern DECLSPEC int SDLCALL SDL_tolower(int x);
-#ifndef SDL_STDINC_NO_INLINES
-#ifdef HAVE_CTYPE_H
-SDL_FORCE_INLINE int SDL_isdigit_inline(int x) { return isdigit(x); }
-SDL_FORCE_INLINE int SDL_isspace_inline(int x) { return isspace(x); }
-SDL_FORCE_INLINE int SDL_toupper_inline(int x) { return toupper(x); }
-SDL_FORCE_INLINE int SDL_tolower_inline(int x) { return tolower(x); }
-#else
-SDL_FORCE_INLINE int SDL_isdigit_inline(int x) { return ((x) >= '0') && ((x) <= '9'); }
-SDL_FORCE_INLINE int SDL_isspace_inline(int x) { return ((x) == ' ') || ((x) == '\t') || ((x) == '\r') || ((x) == '\n'); }
-SDL_FORCE_INLINE int SDL_toupper_inline(int x) { return ((x) >= 'a') && ((x) <= 'z') ? ('A'+((x)-'a')) : (x); }
-SDL_FORCE_INLINE int SDL_tolower_inline(int x) { return ((x) >= 'A') && ((x) <= 'Z') ? ('a'+((x)-'A')) : (x); }
-#endif
-#define SDL_isdigit SDL_isdigit_inline
-#define SDL_isspace SDL_isspace_inline
-#define SDL_toupper SDL_toupper_inline
-#define SDL_tolower SDL_tolower_inline
-#endif /* !SDL_STDINC_NO_INLINES */
 
 
 extern DECLSPEC void *SDLCALL SDL_memset(void *dst, int c, size_t len);
 extern DECLSPEC void *SDLCALL SDL_memset(void *dst, int c, size_t len);
-#if defined(HAVE_MEMSET) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE void *SDL_memset_inline(void *dst, int c, size_t len) { return memset(dst, c, len); }
-#define SDL_memset SDL_memset_inline
-#endif
 
 
 #define SDL_zero(x) SDL_memset(&(x), 0, sizeof((x)))
 #define SDL_zero(x) SDL_memset(&(x), 0, sizeof((x)))
 #define SDL_zerop(x) SDL_memset((x), 0, sizeof(*(x)))
 #define SDL_zerop(x) SDL_memset((x), 0, sizeof(*(x)))
 
 
-/* !!! FIXME: does this _really_ beat memset() on any modern platform? */
-SDL_FORCE_INLINE void SDL_memset4(void *dst, int val, size_t len)
+/* Note that memset() is a byte assignment and this is a 32-bit assignment, so they're not directly equivalent. */
+SDL_FORCE_INLINE void SDL_memset4(void *dst, int val, size_t dwords)
 {
 {
 #if defined(__GNUC__) && defined(i386)
 #if defined(__GNUC__) && defined(i386)
     int u0, u1, u2;
     int u0, u1, u2;
@@ -345,17 +263,16 @@ SDL_FORCE_INLINE void SDL_memset4(void *dst, int val, size_t len)
         "cld \n\t"
         "cld \n\t"
         "rep ; stosl \n\t"
         "rep ; stosl \n\t"
         : "=&D" (u0), "=&a" (u1), "=&c" (u2)
         : "=&D" (u0), "=&a" (u1), "=&c" (u2)
-        : "0" (dst), "1" (val), "2" (SDL_static_cast(Uint32, len))
+        : "0" (dst), "1" (val), "2" (SDL_static_cast(Uint32, dwords))
         : "memory"
         : "memory"
     );
     );
-/* !!! FIXME: amd64? */
 #else
 #else
-    size_t _n = (len + 3) / 4;
+    size_t _n = (dwords + 3) / 4;
     Uint32 *_p = SDL_static_cast(Uint32 *, dst);
     Uint32 *_p = SDL_static_cast(Uint32 *, dst);
     Uint32 _val = (val);
     Uint32 _val = (val);
-    if (len == 0)
+    if (dwords == 0)
         return;
         return;
-    switch (len % 4)
+    switch (dwords % 4)
     {
     {
         case 0: do {    *_p++ = _val;
         case 0: do {    *_p++ = _val;
         case 3:         *_p++ = _val;
         case 3:         *_p++ = _val;
@@ -368,327 +285,54 @@ SDL_FORCE_INLINE void SDL_memset4(void *dst, int val, size_t len)
 
 
 
 
 extern DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, size_t len);
 extern DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, size_t len);
-#if !defined(SDL_STDINC_NO_INLINES)
-#if defined(__MACOSX__) && defined(HAVE_MEMCPY)
-SDL_FORCE_INLINE void *SDL_memcpy_inline(void *dst, const void *src, size_t len)
-{
-    /* We can count on memcpy existing on Mac OS X and being well-tuned. */
-    return memcpy(dst, src, len);
-}
-#define SDL_memcpy SDL_memcpy_inline
-#elif defined(__GNUC__) && defined(i386) && !defined(__WIN32__)
-SDL_FORCE_INLINE void *SDL_memcpy_inline(void *dst, const void *src, size_t len)
-{
-    /* !!! FIXME: does this _really_ beat memcpy() on any modern platform? */
-    /* !!! FIXME: shouldn't we just force the inputs to ecx/edi/esi instead of this tapdance with outputs? */
-    /* !!! FIXME: amd64? */
-    int u0, u1, u2;
-    __asm__ __volatile__ (
-        "cld \n\t"
-        "rep ; movsl \n\t"
-        "testb $2,%b4 \n\t"
-        "je 1f \n\t"
-        "movsw \n"
-        "1:\ttestb $1,%b4 \n\t"
-        "je 2f \n\t"
-        "movsb \n"
-        "2:"
-        : "=&c" (u0), "=&D" (u1), "=&S" (u2)
-        : "0" (SDL_static_cast(unsigned, len)/4), "q" (len), "1" (dst), "2" (src)
-        : "memory"
-    );
-    return dst;
-}
-#define SDL_memcpy SDL_memcpy_inline
-#elif defined(HAVE_MEMCPY)
-SDL_FORCE_INLINE void *SDL_memcpy_inline(void *dst, const void *src, size_t len)
-{
-    return memcpy(dst, src, len);
-}
-#define SDL_memcpy SDL_memcpy_inline
-#elif defined(HAVE_BCOPY)  /* !!! FIXME: is there _really_ ever a time where you have bcopy and not memcpy? */
-SDL_FORCE_INLINE void *SDL_memcpy_inline(void *dst, const void *src, size_t len)
-{
-    bcopy(src, dst, len);
-    return dst;
-}
-#define SDL_memcpy SDL_memcpy_inline
-#endif
-#endif /* !SDL_STDINC_NO_INLINES */
-
 
 
 SDL_FORCE_INLINE void *SDL_memcpy4(void *dst, const void *src, size_t dwords)
 SDL_FORCE_INLINE void *SDL_memcpy4(void *dst, const void *src, size_t dwords)
 {
 {
-#if defined(__GNUC__) && defined(i386)
-    /* !!! FIXME: does this _really_ beat memcpy() on any modern platform? */
-    /* !!! FIXME: shouldn't we just force the inputs to ecx/edi/esi instead of this tapdance with outputs? */
-    int ecx, edi, esi;
-    __asm__ __volatile__ (
-        "cld \n\t"
-        "rep ; movsl \n\t"
-        : "=&c" (ecx), "=&D" (edi), "=&S" (esi)
-        : "0" (SDL_static_cast(unsigned, dwords)), "1" (dst), "2" (src)
-        : "memory"
-    );
-    return dst;
-#else
     return SDL_memcpy(dst, src, dwords * 4);
     return SDL_memcpy(dst, src, dwords * 4);
-#endif
 }
 }
 
 
 extern DECLSPEC void *SDLCALL SDL_memmove(void *dst, const void *src, size_t len);
 extern DECLSPEC void *SDLCALL SDL_memmove(void *dst, const void *src, size_t len);
-#if defined(HAVE_MEMMOVE) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE void *SDL_memmove_inline(void *dst, const void *src, size_t len) { return memmove(dst, src, len); }
-#define SDL_memmove SDL_memmove_inline
-#endif
-
 extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len);
 extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len);
-#if defined(HAVE_MEMCMP) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE int SDL_memcmp_inline(const void *s1, const void *s2, size_t len) { return memcmp(s1, s2, len); }
-#define SDL_memcmp SDL_memcmp_inline
-#endif
-
-extern DECLSPEC size_t SDLCALL SDL_strlen(const char *str);
-#if defined(HAVE_STRLEN) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE size_t SDL_strlen_inline(const char *str) { return strlen(str); }
-#define SDL_strlen SDL_strlen_inline
-#endif
 
 
 extern DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t *wstr);
 extern DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t *wstr);
-#if defined(HAVE_WCSLEN) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE size_t SDL_wcslen_inline(const wchar_t *wstr) { return wcslen(wstr); }
-#define SDL_wcslen SDL_wcslen_inline
-#endif
-
 extern DECLSPEC size_t SDLCALL SDL_wcslcpy(wchar_t *dst, const wchar_t *src, size_t maxlen);
 extern DECLSPEC size_t SDLCALL SDL_wcslcpy(wchar_t *dst, const wchar_t *src, size_t maxlen);
-#if defined(HAVE_WCSLCPY) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE size_t SDL_wcslcpy_inline(wchar_t *dst, const wchar_t *src, size_t maxlen) { return wcslcpy(dst, src, maxlen); }
-#define SDL_wcslcpy SDL_wcslcpy_inline
-#endif
-
 extern DECLSPEC size_t SDLCALL SDL_wcslcat(wchar_t *dst, const wchar_t *src, size_t maxlen);
 extern DECLSPEC size_t SDLCALL SDL_wcslcat(wchar_t *dst, const wchar_t *src, size_t maxlen);
-#if defined(HAVE_WCSLCAT) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE size_t SDL_wcslcat_inline(wchar_t *dst, const wchar_t *src, size_t maxlen) { return wcslcat(dst, src, maxlen); }
-#define SDL_wcslcat SDL_wcslcat_inline
-#endif
 
 
+extern DECLSPEC size_t SDLCALL SDL_strlen(const char *str);
 extern DECLSPEC size_t SDLCALL SDL_strlcpy(char *dst, const char *src, size_t maxlen);
 extern DECLSPEC size_t SDLCALL SDL_strlcpy(char *dst, const char *src, size_t maxlen);
-#if defined(HAVE_STRLCPY) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE size_t SDL_strlcpy_inline(char *dst, const char *src, size_t maxlen) { return strlcpy(dst, src, maxlen); }
-#define SDL_strlcpy SDL_strlcpy_inline
-#else
-#endif
-
 extern DECLSPEC size_t SDLCALL SDL_utf8strlcpy(char *dst, const char *src, size_t dst_bytes);
 extern DECLSPEC size_t SDLCALL SDL_utf8strlcpy(char *dst, const char *src, size_t dst_bytes);
-
 extern DECLSPEC size_t SDLCALL SDL_strlcat(char *dst, const char *src, size_t maxlen);
 extern DECLSPEC size_t SDLCALL SDL_strlcat(char *dst, const char *src, size_t maxlen);
-#if defined(HAVE_STRLCAT) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE size_t SDL_strlcat_inline(char *dst, const char *src, size_t maxlen) { return strlcat(dst, src, maxlen); }
-#define SDL_strlcat SDL_strlcat_inline
-#endif
-
 extern DECLSPEC char *SDLCALL SDL_strdup(const char *str);
 extern DECLSPEC char *SDLCALL SDL_strdup(const char *str);
-#if defined(HAVE_STRDUP) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE char *SDL_strdup_inline(const char *str) { return strdup(str); }
-#define SDL_strdup SDL_strdup_inline
-#endif
-
 extern DECLSPEC char *SDLCALL SDL_strrev(char *str);
 extern DECLSPEC char *SDLCALL SDL_strrev(char *str);
-#if defined(HAVE__STRREV) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE char *SDL_strrev_inline(char *str) { return _strrev(str); }
-#define SDL_strrev SDL_strrev_inline
-#endif
-
 extern DECLSPEC char *SDLCALL SDL_strupr(char *str);
 extern DECLSPEC char *SDLCALL SDL_strupr(char *str);
-#if defined(HAVE__STRUPR) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE char *SDL_strupr_inline(char *str) { return _strupr(str); }
-#define SDL_strupr SDL_strupr_inline
-#endif
-
 extern DECLSPEC char *SDLCALL SDL_strlwr(char *str);
 extern DECLSPEC char *SDLCALL SDL_strlwr(char *str);
-#if defined(HAVE__STRLWR) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE char *SDL_strlwr_inline(char *str) { return _strlwr(str); }
-#define SDL_strlwr SDL_strlwr_inline
-#endif
-
 extern DECLSPEC char *SDLCALL SDL_strchr(const char *str, int c);
 extern DECLSPEC char *SDLCALL SDL_strchr(const char *str, int c);
-#ifndef SDL_STDINC_NO_INLINES
-#ifdef HAVE_STRCHR
-SDL_FORCE_INLINE char *SDL_strchr_inline(const char *str, int c) { return SDL_const_cast(char*,strchr(str, c)); }
-#define SDL_strchr SDL_strchr_inline
-#elif defined(HAVE_INDEX)  /* !!! FIXME: is there anywhere that has this but not strchr? */
-SDL_FORCE_INLINE char *SDL_strchr_inline(const char *str, int c) { return SDL_const_cast(char*,index(str, c)); }
-#define SDL_strchr SDL_strchr_inline
-#endif
-#endif /* !SDL_STDINC_NO_INLINES */
-
 extern DECLSPEC char *SDLCALL SDL_strrchr(const char *str, int c);
 extern DECLSPEC char *SDLCALL SDL_strrchr(const char *str, int c);
-#ifndef SDL_STDINC_NO_INLINES
-#ifdef HAVE_STRRCHR
-SDL_FORCE_INLINE char *SDL_strrchr_inline(const char *str, int c) { return SDL_const_cast(char*,strrchr(str, c)); }
-#define SDL_strrchr SDL_strrchr_inline
-#elif defined(HAVE_RINDEX)  /* !!! FIXME: is there anywhere that has this but not strrchr? */
-SDL_FORCE_INLINE char *SDL_strrchr_inline(const char *str, int c) { return SDL_const_cast(char*,rindex(str, c)); }
-#define SDL_strrchr SDL_strrchr_inline
-#endif
-#endif /* !SDL_STDINC_NO_INLINES */
-
 extern DECLSPEC char *SDLCALL SDL_strstr(const char *haystack, const char *needle);
 extern DECLSPEC char *SDLCALL SDL_strstr(const char *haystack, const char *needle);
-#if defined(HAVE_STRSTR) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE char *SDL_strstr_inline(const char *haystack, const char *needle) { return SDL_const_cast(char*,strstr(haystack, needle)); }
-#define SDL_strstr SDL_strstr_inline
-#endif
-
-extern DECLSPEC char *SDLCALL SDL_ltoa(long value, char *str, int radix);
-#if defined(HAVE__LTOA) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE char *SDL_ltoa_inline(long value, char *str, int radix) { return _ltoa(value, str, radix); }
-#define SDL_ltoa SDL_ltoa_inline
-#endif
 
 
 extern DECLSPEC char *SDLCALL SDL_itoa(int value, char *str, int radix);
 extern DECLSPEC char *SDLCALL SDL_itoa(int value, char *str, int radix);
-#ifndef SDL_STDINC_NO_INLINES
-#ifdef HAVE_ITOA
-// Urho3D: fix deprecation warning
-SDL_FORCE_INLINE char *SDL_itoa_inline(int value, char *str, int radix) { return _itoa(value, str, radix); }
-#else
-SDL_FORCE_INLINE char *SDL_itoa_inline(int value, char *str, int radix) { return SDL_ltoa((long)value, str, radix); }
-#endif
-#define SDL_itoa SDL_itoa_inline
-#endif /* !SDL_STDINC_NO_INLINES */
-
-extern DECLSPEC char *SDLCALL SDL_ultoa(unsigned long value, char *str, int radix);
-#if defined(HAVE__ULTOA) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE char *SDL_ultoa_inline(unsigned long value, char *str, int radix) { return _ultoa(value, str, radix); }
-#define SDL_ultoa SDL_ultoa_inline
-#endif
-
 extern DECLSPEC char *SDLCALL SDL_uitoa(unsigned int value, char *str, int radix);
 extern DECLSPEC char *SDLCALL SDL_uitoa(unsigned int value, char *str, int radix);
-#ifndef SDL_STDINC_NO_INLINES
-#ifdef HAVE__UITOA
-SDL_FORCE_INLINE char *SDL_uitoa_inline(unsigned int value, char *str, int radix) { return _uitoa(value, str, radix); }
-#else
-SDL_FORCE_INLINE char *SDL_uitoa_inline(unsigned int value, char *str, int radix) { return SDL_ultoa((unsigned long)value, str, radix); }
-#endif
-#define SDL_uitoa SDL_uitoa_inline
-#endif /* !SDL_STDINC_NO_INLINES */
-
-
-extern DECLSPEC long SDLCALL SDL_strtol(const char *str, char **endp, int base);
-#if defined(HAVE_STRTOL) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE long SDL_strtol_inline(const char *str, char **endp, int base) { return strtol(str, endp, base); }
-#define SDL_strtol SDL_strtol_inline
-#endif
-
-extern DECLSPEC unsigned long SDLCALL SDL_strtoul(const char *str, char **endp, int base);
-#if defined(HAVE_STRTOUL) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE unsigned long SDLCALL SDL_strtoul_inline(const char *str, char **endp, int base) { return strtoul(str, endp, base); }
-#define SDL_strtoul SDL_strtoul_inline
-#endif
-
+extern DECLSPEC char *SDLCALL SDL_ltoa(long value, char *str, int radix);
+extern DECLSPEC char *SDLCALL SDL_ultoa(unsigned long value, char *str, int radix);
 extern DECLSPEC char *SDLCALL SDL_lltoa(Sint64 value, char *str, int radix);
 extern DECLSPEC char *SDLCALL SDL_lltoa(Sint64 value, char *str, int radix);
-#if defined(HAVE__I64TOA) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE char *SDL_lltoa_inline(Sint64 value, char *str, int radix) { return _i64toa(value, str, radix); }
-#define SDL_lltoa SDL_lltoa_inline
-#endif
-
 extern DECLSPEC char *SDLCALL SDL_ulltoa(Uint64 value, char *str, int radix);
 extern DECLSPEC char *SDLCALL SDL_ulltoa(Uint64 value, char *str, int radix);
-#if defined(HAVE__UI64TOA) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE char *SDL_ulltoa_inline(Uint64 value, char *str, int radix) { return _ui64toa(value, str, radix); }
-#define SDL_ulltoa SDL_ulltoa_inline
-#endif
 
 
-// Urho3D: disabled
-/*
+extern DECLSPEC int SDLCALL SDL_atoi(const char *str);
+extern DECLSPEC double SDLCALL SDL_atof(const char *str);
+extern DECLSPEC long SDLCALL SDL_strtol(const char *str, char **endp, int base);
+extern DECLSPEC unsigned long SDLCALL SDL_strtoul(const char *str, char **endp, int base);
 extern DECLSPEC Sint64 SDLCALL SDL_strtoll(const char *str, char **endp, int base);
 extern DECLSPEC Sint64 SDLCALL SDL_strtoll(const char *str, char **endp, int base);
-#if defined(HAVE_STRTOLL) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE Sint64 SDL_strtoll_inline(const char *str, char **endp, int base) { return strtoll(str, endp, base); }
-#define SDL_strtoll SDL_strtoll_inline
-#endif
-*/
-
 extern DECLSPEC Uint64 SDLCALL SDL_strtoull(const char *str, char **endp, int base);
 extern DECLSPEC Uint64 SDLCALL SDL_strtoull(const char *str, char **endp, int base);
-#if defined(HAVE_STRTOULL) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE Uint64 SDL_strtoull_inline(const char *str, char **endp, int base) { return strtoull(str, endp, base); }
-#define SDL_strtoull SDL_strtoull_inline
-#endif
-
 extern DECLSPEC double SDLCALL SDL_strtod(const char *str, char **endp);
 extern DECLSPEC double SDLCALL SDL_strtod(const char *str, char **endp);
-#if defined(HAVE_STRTOD) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE double SDL_strtod_inline(const char *str, char **endp) { return strtod(str, endp); }
-#define SDL_strtod SDL_strtod_inline
-#endif
-
-extern DECLSPEC int SDLCALL SDL_atoi(const char *str);
-#ifndef SDL_STDINC_NO_INLINES
-#ifdef HAVE_ATOI
-SDL_FORCE_INLINE int SDL_atoi_inline(const char *str) { return atoi(str); }
-#else
-SDL_FORCE_INLINE int SDL_atoi_inline(const char *str) { return SDL_strtol(str, NULL, 0); }
-#endif
-#define SDL_atoi SDL_atoi_inline
-#endif /* !SDL_STDINC_NO_INLINES */
-
-extern DECLSPEC double SDLCALL SDL_atof(const char *str);
-#ifndef SDL_STDINC_NO_INLINES
-#ifdef HAVE_ATOF
-SDL_FORCE_INLINE double SDL_atof_inline(const char *str) { return (double) atof(str); }
-#else
-SDL_FORCE_INLINE double SDL_atof_inline(const char *str) { return SDL_strtod(str, NULL); }
-#endif
-#define SDL_atof SDL_atof_inline
-#endif /* !SDL_STDINC_NO_INLINES */
-
 
 
 extern DECLSPEC int SDLCALL SDL_strcmp(const char *str1, const char *str2);
 extern DECLSPEC int SDLCALL SDL_strcmp(const char *str1, const char *str2);
-#if defined(HAVE_STRCMP) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE int SDL_strcmp_inline(const char *str1, const char *str2) { return strcmp(str1, str2); }
-#define SDL_strcmp SDL_strcmp_inline
-#endif
-
 extern DECLSPEC int SDLCALL SDL_strncmp(const char *str1, const char *str2, size_t maxlen);
 extern DECLSPEC int SDLCALL SDL_strncmp(const char *str1, const char *str2, size_t maxlen);
-#if defined(HAVE_STRNCMP) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE int SDL_strncmp_inline(const char *str1, const char *str2, size_t maxlen) { return strncmp(str1, str2, maxlen); }
-#define SDL_strncmp SDL_strncmp_inline
-#endif
-
 extern DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str2);
 extern DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str2);
-#ifndef SDL_STDINC_NO_INLINES
-#ifdef HAVE_STRCASECMP
-SDL_FORCE_INLINE int SDL_strcasecmp_inline(const char *str1, const char *str2) { return strcasecmp(str1, str2); }
-#define SDL_strcasecmp SDL_strcasecmp_inline
-#elif defined(HAVE__STRICMP)
-SDL_FORCE_INLINE int SDL_strcasecmp_inline(const char *str1, const char *str2) { return _stricmp(str1, str2); }
-#define SDL_strcasecmp SDL_strcasecmp_inline
-#endif
-#endif /* !SDL_STDINC_NO_INLINES */
-
 extern DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *str2, size_t len);
 extern DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *str2, size_t len);
-#ifndef SDL_STDINC_NO_INLINES
-#ifdef HAVE_STRNCASECMP
-SDL_FORCE_INLINE int SDL_strncasecmp_inline(const char *str1, const char *str2, size_t len) { return strncasecmp(str1, str2, len); }
-#define SDL_strncasecmp SDL_strncasecmp_inline
-#elif defined(HAVE__STRNICMP)
-SDL_FORCE_INLINE int SDL_strncasecmp_inline(const char *str1, const char *str2, size_t len) { return _strnicmp(str1, str2, len); }
-#define SDL_strncasecmp SDL_strncasecmp_inline
-#endif
-#endif /* !SDL_STDINC_NO_INLINES */
 
 
-/* Not doing SDL_*_inline functions for these, because of the varargs. */
 extern DECLSPEC int SDLCALL SDL_sscanf(const char *text, const char *fmt, ...);
 extern DECLSPEC int SDLCALL SDL_sscanf(const char *text, const char *fmt, ...);
-#ifdef HAVE_SSCANF
-#define SDL_sscanf sscanf
-#endif
-
 extern DECLSPEC int SDLCALL SDL_snprintf(char *text, size_t maxlen, const char *fmt, ...);
 extern DECLSPEC int SDLCALL SDL_snprintf(char *text, size_t maxlen, const char *fmt, ...);
-#ifdef HAVE_SNPRINTF
-#define SDL_snprintf snprintf
-#endif
-
 extern DECLSPEC int SDLCALL SDL_vsnprintf(char *text, size_t maxlen, const char *fmt, va_list ap);
 extern DECLSPEC int SDLCALL SDL_vsnprintf(char *text, size_t maxlen, const char *fmt, va_list ap);
-#if defined(HAVE_VSNPRINTF) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE int SDL_vsnprintf_inline(char *text, size_t maxlen, const char *fmt, va_list ap) { return vsnprintf(text, maxlen, fmt, ap); }
-#define SDL_vsnprintf SDL_vsnprintf_inline
-#endif
 
 
 #ifndef HAVE_M_PI
 #ifndef HAVE_M_PI
 #ifndef M_PI
 #ifndef M_PI
@@ -697,106 +341,19 @@ SDL_FORCE_INLINE int SDL_vsnprintf_inline(char *text, size_t maxlen, const char
 #endif
 #endif
 
 
 extern DECLSPEC double SDLCALL SDL_atan(double x);
 extern DECLSPEC double SDLCALL SDL_atan(double x);
-#if defined(HAVE_ATAN) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE double SDL_atan_inline(double x) { return atan(x); }
-#define SDL_atan SDL_atan_inline
-#endif
-
 extern DECLSPEC double SDLCALL SDL_atan2(double x, double y);
 extern DECLSPEC double SDLCALL SDL_atan2(double x, double y);
-#if defined(HAVE_ATAN2) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE double SDL_atan2_inline(double x, double y) { return atan2(x, y); }
-#define SDL_atan2 SDL_atan2_inline
-#endif
-
 extern DECLSPEC double SDLCALL SDL_ceil(double x);
 extern DECLSPEC double SDLCALL SDL_ceil(double x);
-#ifndef SDL_STDINC_NO_INLINES
-#ifdef HAVE_CEIL
-SDL_FORCE_INLINE double SDL_ceil_inline(double x) { return ceil(x); }
-#else
-SDL_FORCE_INLINE double SDL_ceil_inline(double x) { return (double)(int)((x)+0.5); }
-#endif
-#define SDL_ceil SDL_ceil_inline
-#endif /* !SDL_STDINC_NO_INLINES */
-
-// Urho3D: disabled
-/*
 extern DECLSPEC double SDLCALL SDL_copysign(double x, double y);
 extern DECLSPEC double SDLCALL SDL_copysign(double x, double y);
-#if defined(HAVE_COPYSIGN) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE double SDL_copysign_inline(double x, double y) { return copysign(x, y); }
-#define SDL_copysign SDL_copysign_inline
-#endif
-*/
-
 extern DECLSPEC double SDLCALL SDL_cos(double x);
 extern DECLSPEC double SDLCALL SDL_cos(double x);
-#if defined(HAVE_COS) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE double SDL_cos_inline(double x) { return cos(x); }
-#define SDL_cos SDL_cos_inline
-#endif
-
 extern DECLSPEC float SDLCALL SDL_cosf(float x);
 extern DECLSPEC float SDLCALL SDL_cosf(float x);
-#ifndef SDL_STDINC_NO_INLINES
-#ifdef HAVE_COSF
-SDL_FORCE_INLINE float SDL_cosf_inline(float x) { return cosf(x); }
-#else
-SDL_FORCE_INLINE float SDL_cosf_inline(float x) { return (float)SDL_cos((double)x); }
-#endif
-#define SDL_cosf SDL_cosf_inline
-#endif /* !SDL_STDINC_NO_INLINES */
-
 extern DECLSPEC double SDLCALL SDL_fabs(double x);
 extern DECLSPEC double SDLCALL SDL_fabs(double x);
-#if defined(HAVE_FABS) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE double SDL_fabs_inline(double x) { return fabs(x); }
-#define SDL_fabs SDL_fabs_inline
-#endif
-
 extern DECLSPEC double SDLCALL SDL_floor(double x);
 extern DECLSPEC double SDLCALL SDL_floor(double x);
-#if defined(HAVE_FLOOR) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE double SDL_floor_inline(double x) { return floor(x); }
-#define SDL_floor SDL_floor_inline
-#endif
-
 extern DECLSPEC double SDLCALL SDL_log(double x);
 extern DECLSPEC double SDLCALL SDL_log(double x);
-#if defined(HAVE_LOG) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE double SDL_log_inline(double x) { return log(x); }
-#define SDL_log SDL_log_inline
-#endif
-
 extern DECLSPEC double SDLCALL SDL_pow(double x, double y);
 extern DECLSPEC double SDLCALL SDL_pow(double x, double y);
-#if defined(HAVE_POW) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE double SDL_pow_inline(double x, double y) { return pow(x, y); }
-#define SDL_pow SDL_pow_inline
-#endif
-
-// Urho3D: disabled
-/*
 extern DECLSPEC double SDLCALL SDL_scalbn(double x, int n);
 extern DECLSPEC double SDLCALL SDL_scalbn(double x, int n);
-#if defined(HAVE_SCALBN) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE double SDL_scalbn_inline(double x, int n) { return scalbn(x, n); }
-#define SDL_scalbn SDL_scalbn_inline
-#endif
-*/
-
 extern DECLSPEC double SDLCALL SDL_sin(double x);
 extern DECLSPEC double SDLCALL SDL_sin(double x);
-#if defined(HAVE_SIN) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE double SDL_sin_inline(double x) { return sin(x); }
-#define SDL_sin SDL_sin_inline
-#endif
-
 extern DECLSPEC float SDLCALL SDL_sinf(float x);
 extern DECLSPEC float SDLCALL SDL_sinf(float x);
-#ifndef SDL_STDINC_NO_INLINES
-#ifdef HAVE_SINF
-SDL_FORCE_INLINE float SDL_sinf_inline(float x) { return sinf(x); }
-#else
-SDL_FORCE_INLINE float SDL_sinf_inline(float x) { return (float)SDL_sin((double)x); }
-#endif
-#define SDL_sinf SDL_sinf_inline
-#endif /* !SDL_STDINC_NO_INLINES */
-
 extern DECLSPEC double SDLCALL SDL_sqrt(double x);
 extern DECLSPEC double SDLCALL SDL_sqrt(double x);
-#if defined(HAVE_SQRT) && !defined(SDL_STDINC_NO_INLINES)
-SDL_FORCE_INLINE double SDL_sqrt_inline(double x) { return sqrt(x); }
-#define SDL_sqrt SDL_sqrt_inline
-#endif
 
 
 /* The SDL implementation of iconv() returns these error codes */
 /* The SDL implementation of iconv() returns these error codes */
 #define SDL_ICONV_ERROR     (size_t)-1
 #define SDL_ICONV_ERROR     (size_t)-1

+ 14 - 16
Source/ThirdParty/SDL/include/SDL_surface.h

@@ -399,44 +399,42 @@ extern DECLSPEC int SDLCALL SDL_FillRects
  *
  *
  *  The blit function should not be called on a locked surface.
  *  The blit function should not be called on a locked surface.
  *
  *
- *  The blit semantics for surfaces with and without alpha and colorkey
+ *  The blit semantics for surfaces with and without blending and colorkey
  *  are defined as follows:
  *  are defined as follows:
  *  \verbatim
  *  \verbatim
     RGBA->RGB:
     RGBA->RGB:
-      SDL_SRCALPHA set:
-        alpha-blend (using alpha-channel).
+      Source surface blend mode set to SDL_BLENDMODE_BLEND:
+        alpha-blend (using the source alpha-channel and per-surface alpha)
         SDL_SRCCOLORKEY ignored.
         SDL_SRCCOLORKEY ignored.
-      SDL_SRCALPHA not set:
+      Source surface blend mode set to SDL_BLENDMODE_NONE:
         copy RGB.
         copy RGB.
         if SDL_SRCCOLORKEY set, only copy the pixels matching the
         if SDL_SRCCOLORKEY set, only copy the pixels matching the
         RGB values of the source color key, ignoring alpha in the
         RGB values of the source color key, ignoring alpha in the
         comparison.
         comparison.
 
 
     RGB->RGBA:
     RGB->RGBA:
-      SDL_SRCALPHA set:
-        alpha-blend (using the source per-surface alpha value);
-        set destination alpha to opaque.
-      SDL_SRCALPHA not set:
+      Source surface blend mode set to SDL_BLENDMODE_BLEND:
+        alpha-blend (using the source per-surface alpha)
+      Source surface blend mode set to SDL_BLENDMODE_NONE:
         copy RGB, set destination alpha to source per-surface alpha value.
         copy RGB, set destination alpha to source per-surface alpha value.
       both:
       both:
         if SDL_SRCCOLORKEY set, only copy the pixels matching the
         if SDL_SRCCOLORKEY set, only copy the pixels matching the
         source color key.
         source color key.
 
 
     RGBA->RGBA:
     RGBA->RGBA:
-      SDL_SRCALPHA set:
-        alpha-blend (using the source alpha channel) the RGB values;
-        leave destination alpha untouched. [Note: is this correct?]
+      Source surface blend mode set to SDL_BLENDMODE_BLEND:
+        alpha-blend (using the source alpha-channel and per-surface alpha)
         SDL_SRCCOLORKEY ignored.
         SDL_SRCCOLORKEY ignored.
-      SDL_SRCALPHA not set:
+      Source surface blend mode set to SDL_BLENDMODE_NONE:
         copy all of RGBA to the destination.
         copy all of RGBA to the destination.
         if SDL_SRCCOLORKEY set, only copy the pixels matching the
         if SDL_SRCCOLORKEY set, only copy the pixels matching the
         RGB values of the source color key, ignoring alpha in the
         RGB values of the source color key, ignoring alpha in the
-       comparison.
+        comparison.
 
 
     RGB->RGB:
     RGB->RGB:
-      SDL_SRCALPHA set:
-        alpha-blend (using the source per-surface alpha value).
-      SDL_SRCALPHA not set:
+      Source surface blend mode set to SDL_BLENDMODE_BLEND:
+        alpha-blend (using the source per-surface alpha)
+      Source surface blend mode set to SDL_BLENDMODE_NONE:
         copy RGB.
         copy RGB.
       both:
       both:
         if SDL_SRCCOLORKEY set, only copy the pixels matching the
         if SDL_SRCCOLORKEY set, only copy the pixels matching the

+ 1 - 1
Source/ThirdParty/SDL/include/SDL_syswm.h

@@ -219,7 +219,7 @@ typedef struct SDL_SysWMinfo SDL_SysWMinfo;
  *  \code
  *  \code
  *  SDL_SysWMinfo info;
  *  SDL_SysWMinfo info;
  *  SDL_VERSION(&info.version);
  *  SDL_VERSION(&info.version);
- *  if ( SDL_GetWindowWMInfo(&info) ) { ... }
+ *  if ( SDL_GetWindowWMInfo(window, &info) ) { ... }
  *  \endcode
  *  \endcode
  */
  */
 extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowWMInfo(SDL_Window * window,
 extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowWMInfo(SDL_Window * window,

+ 63 - 1
Source/ThirdParty/SDL/include/SDL_thread.h

@@ -32,6 +32,7 @@
 #include "SDL_error.h"
 #include "SDL_error.h"
 
 
 /* Thread synchronization primitives */
 /* Thread synchronization primitives */
+#include "SDL_atomic.h"
 #include "SDL_mutex.h"
 #include "SDL_mutex.h"
 
 
 #include "begin_code.h"
 #include "begin_code.h"
@@ -47,6 +48,9 @@ typedef struct SDL_Thread SDL_Thread;
 /* The SDL thread ID */
 /* The SDL thread ID */
 typedef unsigned long SDL_threadID;
 typedef unsigned long SDL_threadID;
 
 
+/* Thread local storage ID, 0 is the invalid ID */
+typedef unsigned int SDL_TLSID;
+
 /* The SDL thread priority
 /* The SDL thread priority
  *
  *
  * Note: On many systems you require special privileges to set high priority.
  * Note: On many systems you require special privileges to set high priority.
@@ -105,7 +109,7 @@ SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
 /**
 /**
  *  Create a thread.
  *  Create a thread.
  */
  */
-#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, _beginthreadex, _endthreadex)
+#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
 
 
 #else
 #else
 
 
@@ -166,6 +170,64 @@ extern DECLSPEC int SDLCALL SDL_SetThreadPriority(SDL_ThreadPriority priority);
  */
  */
 extern DECLSPEC void SDLCALL SDL_WaitThread(SDL_Thread * thread, int *status);
 extern DECLSPEC void SDLCALL SDL_WaitThread(SDL_Thread * thread, int *status);
 
 
+/**
+ *  \brief Create an identifier that is globally visible to all threads but refers to data that is thread-specific.
+ *
+ *  \return The newly created thread local storage identifier, or 0 on error
+ *
+ *  \code
+ *  static SDL_SpinLock tls_lock;
+ *  static SDL_TLSID thread_local_storage;
+ * 
+ *  void SetMyThreadData(void *value)
+ *  {
+ *      if (!thread_local_storage) {
+ *          SDL_AtomicLock(&tls_lock);
+ *          if (!thread_local_storage) {
+ *              thread_local_storage = SDL_TLSCreate();
+ *          }
+ *          SDL_AtomicUnLock(&tls_lock);
+ *      }
+ *      SDL_TLSSet(thread_local_storage, value);
+ *  }
+ *  
+ *  void *GetMyThreadData(void)
+ *  {
+ *      return SDL_TLSGet(thread_local_storage);
+ *  }
+ *  \endcode
+ *
+ *  \sa SDL_TLSGet()
+ *  \sa SDL_TLSSet()
+ */
+extern DECLSPEC SDL_TLSID SDLCALL SDL_TLSCreate(void);
+
+/**
+ *  \brief Get the value associated with a thread local storage ID for the current thread.
+ *
+ *  \param id The thread local storage ID
+ *
+ *  \return The value associated with the ID for the current thread, or NULL if no value has been set.
+ *
+ *  \sa SDL_TLSCreate()
+ *  \sa SDL_TLSSet()
+ */
+extern DECLSPEC void * SDLCALL SDL_TLSGet(SDL_TLSID id);
+
+/**
+ *  \brief Set the value associated with a thread local storage ID for the current thread.
+ *
+ *  \param id The thread local storage ID
+ *  \param value The value to associate with the ID for the current thread
+ *  \param destructor A function called when the thread exits, to free the value.
+ *
+ *  \return 0 on success, -1 on error
+ *
+ *  \sa SDL_TLSCreate()
+ *  \sa SDL_TLSGet()
+ */
+extern DECLSPEC int SDLCALL SDL_TLSSet(SDL_TLSID id, const void *value, void (*destructor)(void*));
+
 
 
 /* Ends C function definitions when using C++ */
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
 #ifdef __cplusplus

+ 11 - 1
Source/ThirdParty/SDL/include/SDL_video.h

@@ -396,7 +396,7 @@ extern DECLSPEC Uint32 SDLCALL SDL_GetWindowPixelFormat(SDL_Window * window);
  *  \param h     The height of the window.
  *  \param h     The height of the window.
  *  \param flags The flags for the window, a mask of any of the following:
  *  \param flags The flags for the window, a mask of any of the following:
  *               ::SDL_WINDOW_FULLSCREEN, ::SDL_WINDOW_OPENGL,
  *               ::SDL_WINDOW_FULLSCREEN, ::SDL_WINDOW_OPENGL,
- *               ::SDL_WINDOW_SHOWN,      ::SDL_WINDOW_BORDERLESS,
+ *               ::SDL_WINDOW_HIDDEN,     ::SDL_WINDOW_BORDERLESS,
  *               ::SDL_WINDOW_RESIZABLE,  ::SDL_WINDOW_MAXIMIZED,
  *               ::SDL_WINDOW_RESIZABLE,  ::SDL_WINDOW_MAXIMIZED,
  *               ::SDL_WINDOW_MINIMIZED,  ::SDL_WINDOW_INPUT_GRABBED.
  *               ::SDL_WINDOW_MINIMIZED,  ::SDL_WINDOW_INPUT_GRABBED.
  *
  *
@@ -892,6 +892,16 @@ extern DECLSPEC SDL_GLContext SDLCALL SDL_GL_CreateContext(SDL_Window *
 extern DECLSPEC int SDLCALL SDL_GL_MakeCurrent(SDL_Window * window,
 extern DECLSPEC int SDLCALL SDL_GL_MakeCurrent(SDL_Window * window,
                                                SDL_GLContext context);
                                                SDL_GLContext context);
 
 
+/**
+ *  \brief Get the currently active OpenGL window.
+ */
+extern DECLSPEC SDL_Window* SDLCALL SDL_GL_GetCurrentWindow(void);
+
+/**
+ *  \brief Get the currently active OpenGL context.
+ */
+extern DECLSPEC SDL_GLContext SDLCALL SDL_GL_GetCurrentContext(void);
+
 /**
 /**
  *  \brief Set the swap interval for the current OpenGL context.
  *  \brief Set the swap interval for the current OpenGL context.
  *
  *

+ 63 - 45
Source/ThirdParty/SDL/src/SDL.c

@@ -25,8 +25,8 @@
 #include "SDL.h"
 #include "SDL.h"
 #include "SDL_bits.h"
 #include "SDL_bits.h"
 #include "SDL_revision.h"
 #include "SDL_revision.h"
-#include "SDL_fatal.h"
 #include "SDL_assert_c.h"
 #include "SDL_assert_c.h"
+#include "events/SDL_events_c.h"
 #include "haptic/SDL_haptic_c.h"
 #include "haptic/SDL_haptic_c.h"
 #include "joystick/SDL_joystick_c.h"
 #include "joystick/SDL_joystick_c.h"
 
 
@@ -107,12 +107,46 @@ SDL_InitSubSystem(Uint32 flags)
         return -1;
         return -1;
     }
     }
 
 
+    /* Clear the error message */
+    SDL_ClearError();
+
+#if SDL_VIDEO_DRIVER_WINDOWS
+    if (SDL_HelperWindowCreate() < 0) {
+        return -1;
+    }
+#endif
+
 #if !SDL_TIMERS_DISABLED
 #if !SDL_TIMERS_DISABLED
     SDL_InitTicks();
     SDL_InitTicks();
 #endif
 #endif
 
 
+    if ((flags & SDL_INIT_GAMECONTROLLER)) {
+        /* game controller implies joystick */
+        flags |= SDL_INIT_JOYSTICK;
+    }
+
+    if ((flags & (SDL_INIT_VIDEO|SDL_INIT_JOYSTICK))) {
+        /* video or joystick implies events */
+        flags |= SDL_INIT_EVENTS;
+    }
+
+    /* Initialize the event subsystem */
+    if ((flags & SDL_INIT_EVENTS)) {
+#if !SDL_EVENTS_DISABLED
+        if (SDL_PrivateShouldInitSubsystem(SDL_INIT_EVENTS)) {
+            if (SDL_StartEventLoop() < 0) {
+                return (-1);
+            }
+            SDL_QuitInit();
+        }
+        SDL_PrivateSubsystemRefCountIncr(SDL_INIT_EVENTS);
+#else
+        return SDL_SetError("SDL not built with events support");
+#endif
+    }
+
     /* Initialize the timer subsystem */
     /* Initialize the timer subsystem */
-    if ((flags & SDL_INIT_TIMER) ){
+    if ((flags & SDL_INIT_TIMER)){
 #if !SDL_TIMERS_DISABLED
 #if !SDL_TIMERS_DISABLED
         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_TIMER)) {
         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_TIMER)) {
             if (SDL_TimerInit() < 0) {
             if (SDL_TimerInit() < 0) {
@@ -125,8 +159,8 @@ SDL_InitSubSystem(Uint32 flags)
 #endif
 #endif
     }
     }
 
 
-    /* Initialize the video/event subsystem */
-    if ((flags & SDL_INIT_VIDEO) ){
+    /* Initialize the video subsystem */
+    if ((flags & SDL_INIT_VIDEO)){
 #if !SDL_VIDEO_DISABLED
 #if !SDL_VIDEO_DISABLED
         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_VIDEO)) {
         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_VIDEO)) {
             if (SDL_VideoInit(NULL) < 0) {
             if (SDL_VideoInit(NULL) < 0) {
@@ -140,7 +174,7 @@ SDL_InitSubSystem(Uint32 flags)
     }
     }
 
 
     /* Initialize the audio subsystem */
     /* Initialize the audio subsystem */
-    if ((flags & SDL_INIT_AUDIO) ){
+    if ((flags & SDL_INIT_AUDIO)){
 #if !SDL_AUDIO_DISABLED
 #if !SDL_AUDIO_DISABLED
         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_AUDIO)) {
         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_AUDIO)) {
             if (SDL_AudioInit(NULL) < 0) {
             if (SDL_AudioInit(NULL) < 0) {
@@ -153,13 +187,8 @@ SDL_InitSubSystem(Uint32 flags)
 #endif
 #endif
     }
     }
 
 
-    if ((flags & SDL_INIT_GAMECONTROLLER)) {
-        /* Game controller implies Joystick. */
-        flags |= SDL_INIT_JOYSTICK;
-    }
-
     /* Initialize the joystick subsystem */
     /* Initialize the joystick subsystem */
-    if ((flags & SDL_INIT_JOYSTICK) ){
+    if ((flags & SDL_INIT_JOYSTICK)){
 #if !SDL_JOYSTICK_DISABLED
 #if !SDL_JOYSTICK_DISABLED
         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_JOYSTICK)) {
         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_JOYSTICK)) {
            if (SDL_JoystickInit() < 0) {
            if (SDL_JoystickInit() < 0) {
@@ -172,7 +201,7 @@ SDL_InitSubSystem(Uint32 flags)
 #endif
 #endif
     }
     }
 
 
-    if ((flags & SDL_INIT_GAMECONTROLLER) ){
+    if ((flags & SDL_INIT_GAMECONTROLLER)){
 #if !SDL_JOYSTICK_DISABLED
 #if !SDL_JOYSTICK_DISABLED
         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_GAMECONTROLLER)) {
         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_GAMECONTROLLER)) {
             if (SDL_GameControllerInit() < 0) {
             if (SDL_GameControllerInit() < 0) {
@@ -186,7 +215,7 @@ SDL_InitSubSystem(Uint32 flags)
     }
     }
 
 
     /* Initialize the haptic subsystem */
     /* Initialize the haptic subsystem */
-    if ((flags & SDL_INIT_HAPTIC) ){
+    if ((flags & SDL_INIT_HAPTIC)){
 #if !SDL_HAPTIC_DISABLED
 #if !SDL_HAPTIC_DISABLED
         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_HAPTIC)) {
         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_HAPTIC)) {
             if (SDL_HapticInit() < 0) {
             if (SDL_HapticInit() < 0) {
@@ -205,30 +234,7 @@ SDL_InitSubSystem(Uint32 flags)
 int
 int
 SDL_Init(Uint32 flags)
 SDL_Init(Uint32 flags)
 {
 {
-    if (SDL_AssertionsInit() < 0) {
-        return -1;
-    }
-
-    /* Clear the error message */
-    SDL_ClearError();
-
-#if SDL_VIDEO_DRIVER_WINDOWS
-    if (SDL_HelperWindowCreate() < 0) {
-        return -1;
-    }
-#endif
-
-    /* Initialize the desired subsystems */
-    if (SDL_InitSubSystem(flags) < 0) {
-        return (-1);
-    }
-
-    /* Everything is initialized */
-    if (!(flags & SDL_INIT_NOPARACHUTE)) {
-        SDL_InstallParachute();
-    }
-
-    return (0);
+    return SDL_InitSubSystem(flags);
 }
 }
 
 
 void
 void
@@ -237,7 +243,7 @@ SDL_QuitSubSystem(Uint32 flags)
     /* Shut down requested initialized subsystems */
     /* Shut down requested initialized subsystems */
 #if !SDL_JOYSTICK_DISABLED
 #if !SDL_JOYSTICK_DISABLED
     if ((flags & SDL_INIT_GAMECONTROLLER)) {
     if ((flags & SDL_INIT_GAMECONTROLLER)) {
-        /* Game controller implies Joystick. */
+        /* game controller implies joystick */
         flags |= SDL_INIT_JOYSTICK;
         flags |= SDL_INIT_JOYSTICK;
 
 
         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_GAMECONTROLLER)) {
         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_GAMECONTROLLER)) {
@@ -247,6 +253,9 @@ SDL_QuitSubSystem(Uint32 flags)
     }
     }
 
 
     if ((flags & SDL_INIT_JOYSTICK)) {
     if ((flags & SDL_INIT_JOYSTICK)) {
+        /* joystick implies events */
+        flags |= SDL_INIT_EVENTS;
+
         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_JOYSTICK)) {
         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_JOYSTICK)) {
             SDL_JoystickQuit();
             SDL_JoystickQuit();
         }
         }
@@ -274,6 +283,9 @@ SDL_QuitSubSystem(Uint32 flags)
 
 
 #if !SDL_VIDEO_DISABLED
 #if !SDL_VIDEO_DISABLED
     if ((flags & SDL_INIT_VIDEO)) {
     if ((flags & SDL_INIT_VIDEO)) {
+        /* video implies events */
+        flags |= SDL_INIT_EVENTS;
+
         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_VIDEO)) {
         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_VIDEO)) {
             SDL_VideoQuit();
             SDL_VideoQuit();
         }
         }
@@ -289,6 +301,16 @@ SDL_QuitSubSystem(Uint32 flags)
         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_TIMER);
         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_TIMER);
     }
     }
 #endif
 #endif
+
+#if !SDL_EVENTS_DISABLED
+    if ((flags & SDL_INIT_EVENTS)) {
+        if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_EVENTS)) {
+            SDL_QuitQuit();
+            SDL_StopEventLoop();
+        }
+        SDL_PrivateSubsystemRefCountDecr(SDL_INIT_EVENTS);
+    }
+#endif
 }
 }
 
 
 Uint32
 Uint32
@@ -327,9 +349,6 @@ SDL_Quit(void)
 #endif
 #endif
     SDL_QuitSubSystem(SDL_INIT_EVERYTHING);
     SDL_QuitSubSystem(SDL_INIT_EVERYTHING);
 
 
-    /* Uninstall any parachute signal handlers */
-    SDL_UninstallParachute();
-
     SDL_ClearHints();
     SDL_ClearHints();
     SDL_AssertionsQuit();
     SDL_AssertionsQuit();
     SDL_LogResetPriorities();
     SDL_LogResetPriorities();
@@ -371,9 +390,6 @@ SDL_GetPlatform()
     return "AIX";
     return "AIX";
 #elif __ANDROID__
 #elif __ANDROID__
     return "Android";
     return "Android";
-#elif __HAIKU__
-/* Haiku must appear here before BeOS, since it also defines __BEOS__ */
-    return "Haiku";
 #elif __BEOS__
 #elif __BEOS__
     return "BeOS";
     return "BeOS";
 #elif __BSDI__
 #elif __BSDI__
@@ -382,6 +398,8 @@ SDL_GetPlatform()
     return "Dreamcast";
     return "Dreamcast";
 #elif __FREEBSD__
 #elif __FREEBSD__
     return "FreeBSD";
     return "FreeBSD";
+#elif __HAIKU__
+    return "Haiku";
 #elif __HPUX__
 #elif __HPUX__
     return "HP-UX";
     return "HP-UX";
 #elif __IRIX__
 #elif __IRIX__
@@ -411,7 +429,7 @@ SDL_GetPlatform()
 #elif __WIN32__
 #elif __WIN32__
     return "Windows";
     return "Windows";
 #elif __IPHONEOS__
 #elif __IPHONEOS__
-    return "iPhone OS";
+    return "iOS";
 #elif __PSP__
 #elif __PSP__
     return "PlayStation Portable";
     return "PlayStation Portable";
 #else
 #else

+ 0 - 6
Source/ThirdParty/SDL/src/SDL_assert.c

@@ -325,12 +325,6 @@ SDL_ReportAssertion(SDL_assert_data *data, const char *func, const char *file,
 }
 }
 
 
 
 
-int SDL_AssertionsInit(void)
-{
-    /* this is a no-op at the moment. */
-    return 0;
-}
-
 void SDL_AssertionsQuit(void)
 void SDL_AssertionsQuit(void)
 {
 {
     SDL_GenerateAssertionReport();
     SDL_GenerateAssertionReport();

+ 0 - 1
Source/ThirdParty/SDL/src/SDL_assert_c.h

@@ -19,7 +19,6 @@
   3. This notice may not be removed or altered from any source distribution.
   3. This notice may not be removed or altered from any source distribution.
 */
 */
 
 
-extern int SDL_AssertionsInit(void);
 extern void SDL_AssertionsQuit(void);
 extern void SDL_AssertionsQuit(void);
 
 
 /* vi: set ts=4 sw=4 expandtab: */
 /* vi: set ts=4 sw=4 expandtab: */

+ 111 - 26
Source/ThirdParty/SDL/src/SDL_hints.c

@@ -21,43 +21,35 @@
 #include "SDL_config.h"
 #include "SDL_config.h"
 
 
 #include "SDL_hints.h"
 #include "SDL_hints.h"
-#include "SDL_hints_c.h"
+#include "SDL_error.h"
 
 
 
 
 /* Assuming there aren't many hints set and they aren't being queried in
 /* Assuming there aren't many hints set and they aren't being queried in
-   critical performance paths, we'll just use a linked list here.
+   critical performance paths, we'll just use linked lists here.
  */
  */
+typedef struct SDL_HintWatch {
+    SDL_HintCallback callback;
+    void *userdata;
+    struct SDL_HintWatch *next;
+} SDL_HintWatch;
+
 typedef struct SDL_Hint {
 typedef struct SDL_Hint {
     char *name;
     char *name;
     char *value;
     char *value;
     SDL_HintPriority priority;
     SDL_HintPriority priority;
-    SDL_HintChangedCb callback;
+    SDL_HintWatch *callbacks;
     struct SDL_Hint *next;
     struct SDL_Hint *next;
 } SDL_Hint;
 } SDL_Hint;
 
 
 static SDL_Hint *SDL_hints;
 static SDL_Hint *SDL_hints;
 
 
-SDL_bool
-SDL_RegisterHintChangedCb(const char *name, SDL_HintChangedCb hintCb)
-{
-    SDL_Hint *hint;
-
-    for (hint = SDL_hints; hint; hint = hint->next) {
-        if (SDL_strcmp(name, hint->name) == 0) {
-            hint->callback = hintCb;
-            return SDL_TRUE;
-        }
-    }
-
-    return SDL_FALSE;
-}
-
 SDL_bool
 SDL_bool
 SDL_SetHintWithPriority(const char *name, const char *value,
 SDL_SetHintWithPriority(const char *name, const char *value,
                         SDL_HintPriority priority)
                         SDL_HintPriority priority)
 {
 {
     const char *env;
     const char *env;
     SDL_Hint *hint;
     SDL_Hint *hint;
+    SDL_HintWatch *entry;
 
 
     if (!name || !value) {
     if (!name || !value) {
         return SDL_FALSE;
         return SDL_FALSE;
@@ -73,12 +65,21 @@ SDL_SetHintWithPriority(const char *name, const char *value,
             if (priority < hint->priority) {
             if (priority < hint->priority) {
                 return SDL_FALSE;
                 return SDL_FALSE;
             }
             }
-            if (SDL_strcmp(hint->value, value) != 0) {
-                if (hint->callback != NULL) {
-                    (*hint->callback)(name, hint->value, value);
+            if (!hint->value || !value || SDL_strcmp(hint->value, value) != 0) {
+                for (entry = hint->callbacks; entry; ) {
+                    /* Save the next entry in case this one is deleted */
+                    SDL_HintWatch *next = entry->next;
+                    entry->callback(entry->userdata, name, hint->value, value);
+                    entry = next;
+                }
+                if (hint->value) {
+                    SDL_free(hint->value);
+                }
+                if (value) {
+                    hint->value = SDL_strdup(value);
+                } else {
+                    hint->value = NULL;
                 }
                 }
-                SDL_free(hint->value);
-                hint->value = SDL_strdup(value);
             }
             }
             hint->priority = priority;
             hint->priority = priority;
             return SDL_TRUE;
             return SDL_TRUE;
@@ -91,9 +92,9 @@ SDL_SetHintWithPriority(const char *name, const char *value,
         return SDL_FALSE;
         return SDL_FALSE;
     }
     }
     hint->name = SDL_strdup(name);
     hint->name = SDL_strdup(name);
-    hint->value = SDL_strdup(value);
+    hint->value = value ? SDL_strdup(value) : NULL;
     hint->priority = priority;
     hint->priority = priority;
-    hint->callback = NULL;
+    hint->callbacks = NULL;
     hint->next = SDL_hints;
     hint->next = SDL_hints;
     SDL_hints = hint;
     SDL_hints = hint;
     return SDL_TRUE;
     return SDL_TRUE;
@@ -123,16 +124,100 @@ SDL_GetHint(const char *name)
     return env;
     return env;
 }
 }
 
 
+void
+SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata)
+{
+    SDL_Hint *hint;
+    SDL_HintWatch *entry;
+    const char *value;
+
+    if (!name || !*name) {
+        SDL_InvalidParamError("name");
+        return;
+    }
+    if (!callback) {
+        SDL_InvalidParamError("callback");
+        return;
+    }
+
+    SDL_DelHintCallback(name, callback, userdata);
+
+    entry = (SDL_HintWatch *)SDL_malloc(sizeof(*entry));
+    entry->callback = callback;
+    entry->userdata = userdata;
+
+    for (hint = SDL_hints; hint; hint = hint->next) {
+        if (SDL_strcmp(name, hint->name) == 0) {
+            break;
+        }
+    }
+    if (!hint) {
+        /* Need to add a hint entry for this watcher */
+        hint = (SDL_Hint *)SDL_malloc(sizeof(*hint));
+        if (!hint) {
+            return;
+        }
+        hint->name = SDL_strdup(name);
+        hint->value = NULL;
+        hint->priority = SDL_HINT_DEFAULT;
+        hint->callbacks = NULL;
+        hint->next = SDL_hints;
+        SDL_hints = hint;
+    }
+
+    /* Add it to the callbacks for this hint */
+    entry->next = hint->callbacks;
+    hint->callbacks = entry;
+
+    /* Now call it with the current value */
+    value = SDL_GetHint(name);
+    callback(userdata, name, value, value);
+}
+
+void
+SDL_DelHintCallback(const char *name, SDL_HintCallback callback, void *userdata)
+{
+    SDL_Hint *hint;
+    SDL_HintWatch *entry, *prev;
+
+    for (hint = SDL_hints; hint; hint = hint->next) {
+        if (SDL_strcmp(name, hint->name) == 0) {
+            prev = NULL;
+            for (entry = hint->callbacks; entry; entry = entry->next) {
+                if (callback == entry->callback && userdata == entry->userdata) {
+                    if (prev) {
+                        prev->next = entry->next;
+                    } else {
+                        hint->callbacks = entry->next;
+                    }
+                    SDL_free(entry);
+                    break;
+                }
+                prev = entry;
+            }
+            return;
+        }
+    }
+}
+
 void SDL_ClearHints(void)
 void SDL_ClearHints(void)
 {
 {
     SDL_Hint *hint;
     SDL_Hint *hint;
+    SDL_HintWatch *entry;
 
 
     while (SDL_hints) {
     while (SDL_hints) {
         hint = SDL_hints;
         hint = SDL_hints;
         SDL_hints = hint->next;
         SDL_hints = hint->next;
 
 
         SDL_free(hint->name);
         SDL_free(hint->name);
-        SDL_free(hint->value);
+        if (hint->value) {
+            SDL_free(hint->value);
+        }
+        for (entry = hint->callbacks; entry; ) {
+            SDL_HintWatch *freeable = entry;
+            entry = entry->next;
+            SDL_free(freeable);
+        }
         SDL_free(hint);
         SDL_free(hint);
     }
     }
 }
 }

+ 19 - 12
Source/ThirdParty/SDL/src/SDL_log.c

@@ -266,6 +266,7 @@ void
 SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list ap)
 SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list ap)
 {
 {
     char *message;
     char *message;
+    size_t len;
 
 
     /* Nothing to do if we don't have an output function */
     /* Nothing to do if we don't have an output function */
     if (!SDL_log_function) {
     if (!SDL_log_function) {
@@ -286,7 +287,18 @@ SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list
     if (!message) {
     if (!message) {
         return;
         return;
     }
     }
+
     SDL_vsnprintf(message, SDL_MAX_LOG_MESSAGE, fmt, ap);
     SDL_vsnprintf(message, SDL_MAX_LOG_MESSAGE, fmt, ap);
+
+    /* Chop off final endline. */
+    len = SDL_strlen(message);
+    if ((len > 0) && (message[len-1] == '\n')) {
+        message[--len] = '\0';
+        if ((len > 0) && (message[len-1] == '\r')) {  /* catch "\r\n", too. */
+            message[--len] = '\0';
+        }
+    }
+
     SDL_log_function(SDL_log_userdata, category, priority, message);
     SDL_log_function(SDL_log_userdata, category, priority, message);
     SDL_stack_free(message);
     SDL_stack_free(message);
 }
 }
@@ -305,6 +317,7 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
 {
 {
 #if defined(__WIN32__)
 #if defined(__WIN32__)
     /* Way too many allocations here, urgh */
     /* Way too many allocations here, urgh */
+    /* Note: One can't call SDL_SetError here, since that function itself logs. */
     {
     {
         char *output;
         char *output;
         size_t length;
         size_t length;
@@ -319,16 +332,16 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
             if (!attachResult) {
             if (!attachResult) {
                     attachError = GetLastError();
                     attachError = GetLastError();
                     if (attachError == ERROR_INVALID_HANDLE) {
                     if (attachError == ERROR_INVALID_HANDLE) {
-                        SDL_SetError("Parent process has no console");
+                        OutputDebugString(TEXT("Parent process has no console"));
                         consoleAttached = -1;
                         consoleAttached = -1;
                     } else if (attachError == ERROR_GEN_FAILURE) {
                     } else if (attachError == ERROR_GEN_FAILURE) {
-                         SDL_SetError("Could not attach to console of parent process");
+                         OutputDebugString(TEXT("Could not attach to console of parent process"));
                          consoleAttached = -1;
                          consoleAttached = -1;
                     } else if (attachError == ERROR_ACCESS_DENIED) {  
                     } else if (attachError == ERROR_ACCESS_DENIED) {  
                          /* Already attached */
                          /* Already attached */
                         consoleAttached = 1;
                         consoleAttached = 1;
                     } else {
                     } else {
-                        SDL_SetError("Error %d attaching console", attachError);
+                        OutputDebugString(TEXT("Error attaching console"));
                         consoleAttached = -1;
                         consoleAttached = -1;
                     }
                     }
                 } else {
                 } else {
@@ -352,10 +365,10 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
         /* Screen output to stderr, if console was attached. */
         /* Screen output to stderr, if console was attached. */
         if (consoleAttached == 1) {
         if (consoleAttached == 1) {
                 if (!WriteConsole(stderrHandle, tstr, lstrlen(tstr), &charsWritten, NULL)) {
                 if (!WriteConsole(stderrHandle, tstr, lstrlen(tstr), &charsWritten, NULL)) {
-                    SDL_SetError("Error %d calling WriteConsole", GetLastError());
+                    OutputDebugString(TEXT("Error calling WriteConsole"));
                 }
                 }
                 if (charsWritten == ERROR_NOT_ENOUGH_MEMORY) {
                 if (charsWritten == ERROR_NOT_ENOUGH_MEMORY) {
-                    SDL_SetError("Insufficient heap memory to write message of size %d", length);
+                    OutputDebugString(TEXT("Insufficient heap memory to write message"));
                 }
                 }
         }
         }
 
 
@@ -386,15 +399,9 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
     }
     }
 #elif defined(__PSP__)
 #elif defined(__PSP__)
     {
     {
-        unsigned int length;
-        char*        output;
         FILE*        pFile;
         FILE*        pFile;
-        length = SDL_strlen(SDL_priority_prefixes[priority]) + 2 + SDL_strlen(message) + 1;
-        output = SDL_stack_alloc(char, length);
-        SDL_snprintf(output, length, "%s: %s", SDL_priority_prefixes[priority], message);
         pFile = fopen ("SDL_Log.txt", "a");
         pFile = fopen ("SDL_Log.txt", "a");
-        fwrite (output, strlen (output), 1, pFile);
-        SDL_stack_free(output);
+        fprintf(pFile, "%s: %s\n", SDL_priority_prefixes[priority], message);
         fclose (pFile);
         fclose (pFile);
     }
     }
 #endif
 #endif

+ 14 - 0
Source/ThirdParty/SDL/src/atomic/SDL_atomic.c

@@ -101,4 +101,18 @@ SDL_AtomicCASPtr(void **a, void *oldval, void *newval)
     return retval;
     return retval;
 }
 }
 
 
+#if defined(__GNUC__) && defined(__arm__) && \
+   (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__))
+__asm__(
+"   .align 2\n"
+"   .globl _SDL_MemoryBarrierRelease\n"
+"   .globl _SDL_MemoryBarrierAcquire\n"
+"_SDL_MemoryBarrierRelease:\n"
+"_SDL_MemoryBarrierAcquire:\n"
+"   mov r0, #0\n"
+"   mcr p15, 0, r0, c7, c10, 5\n"
+"   bx lr\n"
+);
+#endif /* __GNUC__ && __arm__ && ARMV6 */
+
 /* vi: set ts=4 sw=4 expandtab: */
 /* vi: set ts=4 sw=4 expandtab: */

+ 32 - 17
Source/ThirdParty/SDL/src/audio/SDL_audio.c

@@ -67,6 +67,7 @@ extern AudioBootStrap NDSAUD_bootstrap;
 extern AudioBootStrap FUSIONSOUND_bootstrap;
 extern AudioBootStrap FUSIONSOUND_bootstrap;
 extern AudioBootStrap ANDROIDAUD_bootstrap;
 extern AudioBootStrap ANDROIDAUD_bootstrap;
 extern AudioBootStrap PSPAUD_bootstrap;
 extern AudioBootStrap PSPAUD_bootstrap;
+extern AudioBootStrap SNDIO_bootstrap;
 
 
 /* Available audio drivers */
 /* Available audio drivers */
 static const AudioBootStrap *const bootstrap[] = {
 static const AudioBootStrap *const bootstrap[] = {
@@ -76,6 +77,9 @@ static const AudioBootStrap *const bootstrap[] = {
 #if SDL_AUDIO_DRIVER_ALSA
 #if SDL_AUDIO_DRIVER_ALSA
     &ALSA_bootstrap,
     &ALSA_bootstrap,
 #endif
 #endif
+#if SDL_AUDIO_DRIVER_SNDIO
+    &SNDIO_bootstrap,
+#endif
 #if SDL_AUDIO_DRIVER_BSD
 #if SDL_AUDIO_DRIVER_BSD
     &BSD_AUDIO_bootstrap,
     &BSD_AUDIO_bootstrap,
 #endif
 #endif
@@ -356,9 +360,7 @@ SDL_RunAudio(void *devicep)
                 device->convert.len_mult;
                 device->convert.len_mult;
         }
         }
 #endif
 #endif
-
-        /* stream_len = device->convert.len; */
-        stream_len = device->spec.size;
+        stream_len = device->convert.len;
     } else {
     } else {
         stream_len = device->spec.size;
         stream_len = device->spec.size;
     }
     }
@@ -457,15 +459,11 @@ SDL_RunAudio(void *devicep)
         }
         }
     } else {
     } else {
         /* Otherwise, do not use the streamer. This is the old code. */
         /* Otherwise, do not use the streamer. This is the old code. */
+        const int silence = (int) device->spec.silence;
 
 
         /* Loop, filling the audio buffers */
         /* Loop, filling the audio buffers */
         while (device->enabled) {
         while (device->enabled) {
 
 
-            if (device->paused) {
-                SDL_Delay(delay);
-                continue;
-            }
-
             /* Fill the current buffer with sound */
             /* Fill the current buffer with sound */
             if (device->convert.needed) {
             if (device->convert.needed) {
                 if (device->convert.buf) {
                 if (device->convert.buf) {
@@ -481,7 +479,11 @@ SDL_RunAudio(void *devicep)
             }
             }
 
 
             SDL_LockMutex(device->mixer_lock);
             SDL_LockMutex(device->mixer_lock);
-            (*fill) (udata, stream, stream_len);
+            if (device->paused) {
+                SDL_memset(stream, silence, stream_len);
+            } else {
+                (*fill) (udata, stream, stream_len);
+            }
             SDL_UnlockMutex(device->mixer_lock);
             SDL_UnlockMutex(device->mixer_lock);
 
 
             /* Convert the audio if necessary */
             /* Convert the audio if necessary */
@@ -954,12 +956,6 @@ open_audio_device(const char *devname, int iscapture,
         return 0;
         return 0;
     }
     }
 
 
-    /* If the audio driver changes the buffer size, accept it */
-    if (device->spec.samples != obtained->samples) {
-        obtained->samples = device->spec.samples;
-        SDL_CalculateAudioSpec(obtained);
-    }
-
     /* See if we need to do any conversion */
     /* See if we need to do any conversion */
     build_cvt = SDL_FALSE;
     build_cvt = SDL_FALSE;
     if (obtained->freq != device->spec.freq) {
     if (obtained->freq != device->spec.freq) {
@@ -983,6 +979,16 @@ open_audio_device(const char *devname, int iscapture,
             build_cvt = SDL_TRUE;
             build_cvt = SDL_TRUE;
         }
         }
     }
     }
+
+    /* If the audio driver changes the buffer size, accept it.
+       This needs to be done after the format is modified above,
+       otherwise it might not have the correct buffer size.
+     */
+    if (device->spec.samples != obtained->samples) {
+        obtained->samples = device->spec.samples;
+        SDL_CalculateAudioSpec(obtained);
+    }
+
     if (build_cvt) {
     if (build_cvt) {
         /* Build an audio conversion block */
         /* Build an audio conversion block */
         if (SDL_BuildAudioCVT(&device->convert,
         if (SDL_BuildAudioCVT(&device->convert,
@@ -994,7 +1000,7 @@ open_audio_device(const char *devname, int iscapture,
             return 0;
             return 0;
         }
         }
         if (device->convert.needed) {
         if (device->convert.needed) {
-            device->convert.len = (int) (((double) obtained->size) /
+            device->convert.len = (int) (((double) device->spec.size) /
                                          device->convert.len_ratio);
                                          device->convert.len_ratio);
 
 
             device->convert.buf =
             device->convert.buf =
@@ -1110,7 +1116,9 @@ SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on)
 {
 {
     SDL_AudioDevice *device = get_audio_device(devid);
     SDL_AudioDevice *device = get_audio_device(devid);
     if (device) {
     if (device) {
+        current_audio.impl.LockDevice(device);
         device->paused = pause_on;
         device->paused = pause_on;
+        current_audio.impl.UnlockDevice(device);
     }
     }
 }
 }
 
 
@@ -1173,8 +1181,15 @@ void
 SDL_AudioQuit(void)
 SDL_AudioQuit(void)
 {
 {
     SDL_AudioDeviceID i;
     SDL_AudioDeviceID i;
+
+    if (!current_audio.name) {  /* not initialized?! */
+        return;
+    }
+
     for (i = 0; i < SDL_arraysize(open_devices); i++) {
     for (i = 0; i < SDL_arraysize(open_devices); i++) {
-        SDL_CloseAudioDevice(i);
+        if (open_devices[i] != NULL) {
+            SDL_CloseAudioDevice(i+1);
+        }
     }
     }
 
 
     /* Free the driver data */
     /* Free the driver data */

+ 1 - 2
Source/ThirdParty/SDL/src/audio/SDL_audiocvt.c

@@ -293,10 +293,9 @@ SDL_ConvertStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format)
         const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
         const type *src = (const type *) (cvt->buf + cvt->len_cvt); \
         type *dst = (type *) (cvt->buf + cvt->len_cvt * 2); \
         type *dst = (type *) (cvt->buf + cvt->len_cvt * 2); \
         for (i = cvt->len_cvt / sizeof(type); i; --i) { \
         for (i = cvt->len_cvt / sizeof(type); i; --i) { \
-            const type val = *src; \
             src -= 1; \
             src -= 1; \
             dst -= 2; \
             dst -= 2; \
-            dst[0] = dst[1] = val; \
+            dst[0] = dst[1] = *src; \
         } \
         } \
     }
     }
 
 

+ 1 - 1
Source/ThirdParty/SDL/src/audio/alsa/SDL_alsa_audio.c

@@ -643,7 +643,7 @@ ALSA_OpenDevice(_THIS, const char *devname, int iscapture)
         ALSA_CloseDevice(this);
         ALSA_CloseDevice(this);
         return SDL_OutOfMemory();
         return SDL_OutOfMemory();
     }
     }
-    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
+    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen);
 
 
     /* Switch to blocking mode for playback */
     /* Switch to blocking mode for playback */
     ALSA_snd_pcm_nonblock(pcm_handle, 0);
     ALSA_snd_pcm_nonblock(pcm_handle, 0);

+ 3 - 3
Source/ThirdParty/SDL/src/audio/alsa/SDL_alsa_audio.h

@@ -20,8 +20,8 @@
 */
 */
 #include "SDL_config.h"
 #include "SDL_config.h"
 
 
-#ifndef _ALSA_PCM_audio_h
-#define _ALSA_PCM_audio_h
+#ifndef _SDL_ALSA_audio_h
+#define _SDL_ALSA_audio_h
 
 
 #include <alsa/asoundlib.h>
 #include <alsa/asoundlib.h>
 
 
@@ -40,6 +40,6 @@ struct SDL_PrivateAudioData
     int mixlen;
     int mixlen;
 };
 };
 
 
-#endif /* _ALSA_PCM_audio_h */
+#endif /* _SDL_ALSA_audio_h */
 
 
 /* vi: set ts=4 sw=4 expandtab: */
 /* vi: set ts=4 sw=4 expandtab: */

+ 4 - 18
Source/ThirdParty/SDL/src/audio/android/SDL_androidaudio.c

@@ -50,12 +50,6 @@ AndroidAUD_OpenDevice(_THIS, const char *devname, int iscapture)
 
 
     audioDevice = this;
     audioDevice = this;
 
 
-    this->hidden = SDL_malloc(sizeof(*(this->hidden)));
-    if (!this->hidden) {
-        return SDL_OutOfMemory();
-    }
-    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
-
     test_format = SDL_FirstAudioFormat(this->spec.format);
     test_format = SDL_FirstAudioFormat(this->spec.format);
     while (test_format != 0) { /* no "UNKNOWN" constant */
     while (test_format != 0) { /* no "UNKNOWN" constant */
         if ((test_format == AUDIO_U8) || (test_format == AUDIO_S16LSB)) {
         if ((test_format == AUDIO_U8) || (test_format == AUDIO_S16LSB)) {
@@ -110,10 +104,9 @@ AndroidAUD_GetDeviceBuf(_THIS)
 static void
 static void
 AndroidAUD_CloseDevice(_THIS)
 AndroidAUD_CloseDevice(_THIS)
 {
 {
-    if (this->hidden != NULL) {
-        SDL_free(this->hidden);
-        this->hidden = NULL;
-    }
+    /* At this point SDL_CloseAudioDevice via close_audio_device took care of terminating the audio thread
+       so it's safe to terminate the Java side buffer and AudioTrack
+     */
     Android_JNI_CloseAudioDevice();
     Android_JNI_CloseAudioDevice();
 
 
     if (audioDevice == this) {
     if (audioDevice == this) {
@@ -131,7 +124,6 @@ AndroidAUD_Init(SDL_AudioDriverImpl * impl)
     impl->CloseDevice = AndroidAUD_CloseDevice;
     impl->CloseDevice = AndroidAUD_CloseDevice;
 
 
     /* and the capabilities */
     /* and the capabilities */
-    impl->ProvidesOwnCallbackThread = 1;
     impl->HasCaptureSupport = 0; /* TODO */
     impl->HasCaptureSupport = 0; /* TODO */
     impl->OnlyHasDefaultOutputDevice = 1;
     impl->OnlyHasDefaultOutputDevice = 1;
     impl->OnlyHasDefaultInputDevice = 1;
     impl->OnlyHasDefaultInputDevice = 1;
@@ -143,13 +135,7 @@ AudioBootStrap ANDROIDAUD_bootstrap = {
     "android", "SDL Android audio driver", AndroidAUD_Init, 0
     "android", "SDL Android audio driver", AndroidAUD_Init, 0
 };
 };
 
 
-/* Called by the Java code to start the audio processing on a thread */
-void
-Android_RunAudioThread()
-{
-    SDL_RunAudio(audioDevice);
-}
-
 #endif /* SDL_AUDIO_DRIVER_ANDROID */
 #endif /* SDL_AUDIO_DRIVER_ANDROID */
 
 
 /* vi: set ts=4 sw=4 expandtab: */
 /* vi: set ts=4 sw=4 expandtab: */
+

+ 2 - 0
Source/ThirdParty/SDL/src/audio/android/SDL_androidaudio.h

@@ -32,6 +32,8 @@ struct SDL_PrivateAudioData
 {
 {
 };
 };
 
 
+static void AndroidAUD_CloseDevice(_THIS);
+
 #endif /* _SDL_androidaudio_h */
 #endif /* _SDL_androidaudio_h */
 
 
 /* vi: set ts=4 sw=4 expandtab: */
 /* vi: set ts=4 sw=4 expandtab: */

+ 0 - 3
Source/ThirdParty/SDL/src/audio/coreaudio/SDL_coreaudio.h

@@ -32,9 +32,6 @@
 #if MACOSX_COREAUDIO
 #if MACOSX_COREAUDIO
 #include <CoreAudio/CoreAudio.h>
 #include <CoreAudio/CoreAudio.h>
 #include <CoreServices/CoreServices.h>
 #include <CoreServices/CoreServices.h>
-#if MAC_OS_X_VERSION_MAX_ALLOWED <= 1050
-#include <AudioUnit/AUNTComponent.h>
-#endif
 #else
 #else
 #include <AudioToolbox/AudioToolbox.h>
 #include <AudioToolbox/AudioToolbox.h>
 #endif
 #endif

+ 44 - 34
Source/ThirdParty/SDL/src/audio/directsound/SDL_directsound.c

@@ -30,6 +30,10 @@
 #include "../SDL_audio_c.h"
 #include "../SDL_audio_c.h"
 #include "SDL_directsound.h"
 #include "SDL_directsound.h"
 
 
+#ifndef WAVE_FORMAT_IEEE_FLOAT
+#define WAVE_FORMAT_IEEE_FLOAT 0x0003
+#endif
+
 /* DirectX function pointers for audio */
 /* DirectX function pointers for audio */
 static void* DSoundDLL = NULL;
 static void* DSoundDLL = NULL;
 typedef HRESULT(WINAPI*fnDirectSoundCreate8)(LPGUID,LPDIRECTSOUND*,LPUNKNOWN);
 typedef HRESULT(WINAPI*fnDirectSoundCreate8)(LPGUID,LPDIRECTSOUND*,LPUNKNOWN);
@@ -342,7 +346,7 @@ DSOUND_CloseDevice(_THIS)
    number of audio chunks available in the created buffer.
    number of audio chunks available in the created buffer.
 */
 */
 static int
 static int
-CreateSecondary(_THIS, HWND focus, WAVEFORMATEX * wavefmt)
+CreateSecondary(_THIS, HWND focus)
 {
 {
     LPDIRECTSOUND sndObj = this->hidden->sound;
     LPDIRECTSOUND sndObj = this->hidden->sound;
     LPDIRECTSOUNDBUFFER *sndbuf = &this->hidden->mixbuf;
     LPDIRECTSOUNDBUFFER *sndbuf = &this->hidden->mixbuf;
@@ -352,6 +356,24 @@ CreateSecondary(_THIS, HWND focus, WAVEFORMATEX * wavefmt)
     DSBUFFERDESC format;
     DSBUFFERDESC format;
     LPVOID pvAudioPtr1, pvAudioPtr2;
     LPVOID pvAudioPtr1, pvAudioPtr2;
     DWORD dwAudioBytes1, dwAudioBytes2;
     DWORD dwAudioBytes1, dwAudioBytes2;
+    WAVEFORMATEX wfmt;
+
+    SDL_zero(wfmt);
+
+    if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
+        wfmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
+    } else {
+        wfmt.wFormatTag = WAVE_FORMAT_PCM;
+    }
+
+    wfmt.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
+    wfmt.nChannels = this->spec.channels;
+    wfmt.nSamplesPerSec = this->spec.freq;
+    wfmt.nBlockAlign = wfmt.nChannels * (wfmt.wBitsPerSample / 8);
+    wfmt.nAvgBytesPerSec = wfmt.nSamplesPerSec * wfmt.nBlockAlign;
+
+    /* Update the fragment size as size in bytes */
+    SDL_CalculateAudioSpec(&this->spec);
 
 
     /* Try to set primary mixing privileges */
     /* Try to set primary mixing privileges */
     if (focus) {
     if (focus) {
@@ -367,7 +389,7 @@ CreateSecondary(_THIS, HWND focus, WAVEFORMATEX * wavefmt)
     }
     }
 
 
     /* Try to create the secondary buffer */
     /* Try to create the secondary buffer */
-    SDL_memset(&format, 0, sizeof(format));
+    SDL_zero(format);
     format.dwSize = sizeof(format);
     format.dwSize = sizeof(format);
     format.dwFlags = DSBCAPS_GETCURRENTPOSITION2;
     format.dwFlags = DSBCAPS_GETCURRENTPOSITION2;
     if (!focus) {
     if (!focus) {
@@ -382,12 +404,12 @@ CreateSecondary(_THIS, HWND focus, WAVEFORMATEX * wavefmt)
                             DSBSIZE_MIN / numchunks, DSBSIZE_MAX / numchunks);
                             DSBSIZE_MIN / numchunks, DSBSIZE_MAX / numchunks);
     }
     }
     format.dwReserved = 0;
     format.dwReserved = 0;
-    format.lpwfxFormat = wavefmt;
+    format.lpwfxFormat = &wfmt;
     result = IDirectSound_CreateSoundBuffer(sndObj, &format, sndbuf, NULL);
     result = IDirectSound_CreateSoundBuffer(sndObj, &format, sndbuf, NULL);
     if (result != DS_OK) {
     if (result != DS_OK) {
         return SetDSerror("DirectSound CreateSoundBuffer", result);
         return SetDSerror("DirectSound CreateSoundBuffer", result);
     }
     }
-    IDirectSoundBuffer_SetFormat(*sndbuf, wavefmt);
+    IDirectSoundBuffer_SetFormat(*sndbuf, &wfmt);
 
 
     /* Silence the initial audio buffer */
     /* Silence the initial audio buffer */
     result = IDirectSoundBuffer_Lock(*sndbuf, 0, format.dwBufferBytes,
     result = IDirectSoundBuffer_Lock(*sndbuf, 0, format.dwBufferBytes,
@@ -433,8 +455,8 @@ static int
 DSOUND_OpenDevice(_THIS, const char *devname, int iscapture)
 DSOUND_OpenDevice(_THIS, const char *devname, int iscapture)
 {
 {
     HRESULT result;
     HRESULT result;
-    WAVEFORMATEX waveformat;
-    int valid_format = 0;
+    SDL_bool valid_format = SDL_FALSE;
+    SDL_bool tried_format = SDL_FALSE;
     SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
     SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
     FindDevGUIDData devguid;
     FindDevGUIDData devguid;
     LPGUID guid = NULL;
     LPGUID guid = NULL;
@@ -461,13 +483,25 @@ DSOUND_OpenDevice(_THIS, const char *devname, int iscapture)
     }
     }
     SDL_memset(this->hidden, 0, (sizeof *this->hidden));
     SDL_memset(this->hidden, 0, (sizeof *this->hidden));
 
 
+    /* Open the audio device */
+    result = pDirectSoundCreate8(guid, &this->hidden->sound, NULL);
+    if (result != DS_OK) {
+        DSOUND_CloseDevice(this);
+        return SetDSerror("DirectSoundCreate", result);
+    }
+
     while ((!valid_format) && (test_format)) {
     while ((!valid_format) && (test_format)) {
         switch (test_format) {
         switch (test_format) {
         case AUDIO_U8:
         case AUDIO_U8:
         case AUDIO_S16:
         case AUDIO_S16:
         case AUDIO_S32:
         case AUDIO_S32:
+        case AUDIO_F32:
+            tried_format = SDL_TRUE;
             this->spec.format = test_format;
             this->spec.format = test_format;
-            valid_format = 1;
+            this->hidden->num_buffers = CreateSecondary(this, NULL);
+            if (this->hidden->num_buffers > 0) {
+                valid_format = SDL_TRUE;
+            }
             break;
             break;
         }
         }
         test_format = SDL_NextAudioFormat();
         test_format = SDL_NextAudioFormat();
@@ -475,36 +509,12 @@ DSOUND_OpenDevice(_THIS, const char *devname, int iscapture)
 
 
     if (!valid_format) {
     if (!valid_format) {
         DSOUND_CloseDevice(this);
         DSOUND_CloseDevice(this);
+        if (tried_format) {
+            return -1;  // CreateSecondary() should have called SDL_SetError().
+        }
         return SDL_SetError("DirectSound: Unsupported audio format");
         return SDL_SetError("DirectSound: Unsupported audio format");
     }
     }
 
 
-    SDL_memset(&waveformat, 0, sizeof(waveformat));
-    waveformat.wFormatTag = WAVE_FORMAT_PCM;
-    waveformat.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
-    waveformat.nChannels = this->spec.channels;
-    waveformat.nSamplesPerSec = this->spec.freq;
-    waveformat.nBlockAlign =
-        waveformat.nChannels * (waveformat.wBitsPerSample / 8);
-    waveformat.nAvgBytesPerSec =
-        waveformat.nSamplesPerSec * waveformat.nBlockAlign;
-
-    /* Update the fragment size as size in bytes */
-    SDL_CalculateAudioSpec(&this->spec);
-
-    /* Open the audio device */
-    result = pDirectSoundCreate8(guid, &this->hidden->sound, NULL);
-    if (result != DS_OK) {
-        DSOUND_CloseDevice(this);
-        return SetDSerror("DirectSoundCreate", result);
-    }
-
-    /* Create the audio buffer to which we write */
-    this->hidden->num_buffers = CreateSecondary(this, NULL, &waveformat);
-    if (this->hidden->num_buffers < 0) {
-        DSOUND_CloseDevice(this);
-        return -1;
-    }
-
     /* The buffer will auto-start playing in DSOUND_WaitDevice() */
     /* The buffer will auto-start playing in DSOUND_WaitDevice() */
     this->hidden->mixlen = this->spec.size;
     this->hidden->mixlen = this->spec.size;
 
 

+ 4 - 4
Source/ThirdParty/SDL/src/audio/disk/SDL_diskaudio.c

@@ -114,6 +114,10 @@ DISKAUD_OpenDevice(_THIS, const char *devname, int iscapture)
     }
     }
     SDL_memset(this->hidden, 0, sizeof(*this->hidden));
     SDL_memset(this->hidden, 0, sizeof(*this->hidden));
 
 
+    this->hidden->mixlen = this->spec.size;
+    this->hidden->write_delay =
+        (envr) ? SDL_atoi(envr) : DISKDEFAULT_WRITEDELAY;
+
     /* Open the audio device */
     /* Open the audio device */
     this->hidden->output = SDL_RWFromFile(fname, "wb");
     this->hidden->output = SDL_RWFromFile(fname, "wb");
     if (this->hidden->output == NULL) {
     if (this->hidden->output == NULL) {
@@ -129,10 +133,6 @@ DISKAUD_OpenDevice(_THIS, const char *devname, int iscapture)
     }
     }
     SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
     SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
 
 
-    this->hidden->mixlen = this->spec.size;
-    this->hidden->write_delay =
-        (envr) ? SDL_atoi(envr) : DISKDEFAULT_WRITEDELAY;
-
 #if HAVE_STDIO_H
 #if HAVE_STDIO_H
     fprintf(stderr,
     fprintf(stderr,
             "WARNING: You are using the SDL disk writer audio driver!\n"
             "WARNING: You are using the SDL disk writer audio driver!\n"

+ 0 - 129
Source/ThirdParty/SDL/src/audio/nds/SDL_ndsaudio.c

@@ -1,129 +0,0 @@
-/*
-  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.
-*/
-#include "SDL_config.h"
-
-#if SDL_AUDIO_DRIVER_NDS
-
-/* Output audio to NDS */
-
-#include <nds.h>
-
-#include "SDL_audio.h"
-#include "../SDL_audio_c.h"
-#include "SDL_ndsaudio.h"
-
-static int
-NDSAUD_OpenDevice(_THIS, const char *devname, int iscapture)
-{
-    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
-    int valid_datatype = 0;
-
-    this->hidden = SDL_malloc(sizeof(*(this->hidden)));
-    if (!this->hidden) {
-        SDL_OutOfMemory();
-        return 0;
-    }
-    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
-
-    while ((!valid_datatype) && (test_format)) {
-        this->spec.format = test_format;
-        switch (test_format) {
-        case AUDIO_S8:
-            /*case AUDIO_S16LSB: */
-            valid_datatype = 1;
-            break;
-        default:
-            test_format = SDL_NextAudioFormat();
-            break;
-        }
-    }
-
-#if 0
-    /* set the generic sound parameters */
-    setGenericSound(22050,      /* sample rate */
-                    127,        /* volume */
-                    64,         /* panning/balance */
-                    0);         /* sound format */
-#endif
-
-    return 1;
-}
-
-static void
-NDSAUD_PlayDevice(_THIS)
-{
-#if 0
-    playGenericSound(this->hidden->mixbuf, this->hidden->mixlen);
-
-//    sound->data = this->hidden->mixbuf;/* pointer to raw audio data */
-//    sound->len = this->hidden->mixlen; /* size of raw data pointed to above */
-//    sound->rate = 22050; /* sample rate = 22050Hz */
-//    sound->vol = 127;    /* volume [0..127] for [min..max] */
-//    sound->pan = 64;     /* balance [0..127] for [left..right] */
-//    sound->format = 0;   /* 0 for 16-bit, 1 for 8-bit */
-//    playSound(sound);
-#endif
-}
-
-
-static Uint8 *
-NDSAUD_GetDeviceBuf(_THIS)
-{
-    return this->hidden->mixbuf;        /* is this right? */
-}
-
-static void
-NDSAUD_WaitDevice(_THIS)
-{
-    /* stub */
-}
-
-static void
-NDSAUD_CloseDevice(_THIS)
-{
-    /* stub */
-}
-
-static int
-NDSAUD_Init(SDL_AudioDriverImpl * impl)
-{
-    /* Set the function pointers */
-    impl->OpenDevice = NDSAUD_OpenDevice;
-    impl->PlayDevice = NDSAUD_PlayDevice;
-    impl->WaitDevice = NDSAUD_WaitDevice;
-    impl->GetDeviceBuf = NDSAUD_GetDeviceBuf;
-    impl->CloseDevice = NDSAUD_CloseDevice;
-
-    /* and the capabilities */
-    impl->HasCaptureSupport = 1;
-    impl->OnlyHasDefaultOutputDevice = 1;
-    impl->OnlyHasDefaultInputDevice = 1;
-
-    return 1;   /* this audio target is available. */
-}
-
-AudioBootStrap NDSAUD_bootstrap = {
-    "nds", "SDL NDS audio driver", NDSAUD_Init, 0       /*1? */
-};
-
-#endif /* SDL_AUDIO_DRIVER_NDS */
-
-/* vi: set ts=4 sw=4 expandtab: */

+ 39 - 3
Source/ThirdParty/SDL/src/audio/pulseaudio/SDL_pulseaudio.c

@@ -49,7 +49,7 @@
 
 
 #if (PA_API_VERSION < 12)
 #if (PA_API_VERSION < 12)
 /** Return non-zero if the passed state is one of the connected states */
 /** Return non-zero if the passed state is one of the connected states */
-static inline int PA_CONTEXT_IS_GOOD(pa_context_state_t x) {
+static __inline__ int PA_CONTEXT_IS_GOOD(pa_context_state_t x) {
     return
     return
         x == PA_CONTEXT_CONNECTING ||
         x == PA_CONTEXT_CONNECTING ||
         x == PA_CONTEXT_AUTHORIZING ||
         x == PA_CONTEXT_AUTHORIZING ||
@@ -57,7 +57,7 @@ static inline int PA_CONTEXT_IS_GOOD(pa_context_state_t x) {
         x == PA_CONTEXT_READY;
         x == PA_CONTEXT_READY;
 }
 }
 /** Return non-zero if the passed state is one of the connected states */
 /** Return non-zero if the passed state is one of the connected states */
-static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x) {
+static __inline__ int PA_STREAM_IS_GOOD(pa_stream_state_t x) {
     return
     return
         x == PA_STREAM_CREATING ||
         x == PA_STREAM_CREATING ||
         x == PA_STREAM_READY;
         x == PA_STREAM_READY;
@@ -65,6 +65,7 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x) {
 #endif /* pulseaudio <= 0.9.10 */
 #endif /* pulseaudio <= 0.9.10 */
 
 
 
 
+static const char *(*PULSEAUDIO_pa_get_library_version) (void);
 static pa_simple *(*PULSEAUDIO_pa_simple_new) (const char *, const char *,
 static pa_simple *(*PULSEAUDIO_pa_simple_new) (const char *, const char *,
     pa_stream_direction_t, const char *, const char *, const pa_sample_spec *,
     pa_stream_direction_t, const char *, const char *, const pa_sample_spec *,
     const pa_channel_map *, const pa_buffer_attr *, int *);
     const pa_channel_map *, const pa_buffer_attr *, int *);
@@ -177,6 +178,7 @@ LoadPulseAudioLibrary(void)
 static int
 static int
 load_pulseaudio_syms(void)
 load_pulseaudio_syms(void)
 {
 {
+    SDL_PULSEAUDIO_SYM(pa_get_library_version);
     SDL_PULSEAUDIO_SYM(pa_simple_new);
     SDL_PULSEAUDIO_SYM(pa_simple_new);
     SDL_PULSEAUDIO_SYM(pa_simple_free);
     SDL_PULSEAUDIO_SYM(pa_simple_free);
     SDL_PULSEAUDIO_SYM(pa_mainloop_new);
     SDL_PULSEAUDIO_SYM(pa_mainloop_new);
@@ -322,6 +324,28 @@ PULSEAUDIO_CloseDevice(_THIS)
 }
 }
 
 
 
 
+static __inline__ int
+squashVersion(const int major, const int minor, const int patch)
+{
+    return ((major & 0xFF) << 16) | ((minor & 0xFF) << 8) | (patch & 0xFF);
+}
+
+/* Workaround for older pulse: pa_context_new() must have non-NULL appname */
+static const char *
+getAppName(void)
+{
+    const char *verstr = PULSEAUDIO_pa_get_library_version();
+    if (verstr != NULL) {
+        int maj, min, patch;
+        if (SDL_sscanf(verstr, "%d.%d.%d", &maj, &min, &patch) == 3) {
+            if (squashVersion(maj, min, patch) >= squashVersion(0, 9, 15)) {
+                return NULL;  /* 0.9.15+ handles NULL correctly. */
+            }
+        }
+    }
+    return "SDL Application";  /* oh well. */
+}
+
 static int
 static int
 PULSEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
 PULSEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
 {
 {
@@ -360,6 +384,18 @@ PULSEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
         case AUDIO_S16MSB:
         case AUDIO_S16MSB:
             paspec.format = PA_SAMPLE_S16BE;
             paspec.format = PA_SAMPLE_S16BE;
             break;
             break;
+        case AUDIO_S32LSB:
+            paspec.format = PA_SAMPLE_S32LE;
+            break;
+        case AUDIO_S32MSB:
+            paspec.format = PA_SAMPLE_S32BE;
+            break;
+        case AUDIO_F32LSB:
+            paspec.format = PA_SAMPLE_FLOAT32LE;
+            break;
+        case AUDIO_F32MSB:
+            paspec.format = PA_SAMPLE_FLOAT32BE;
+            break;
         default:
         default:
             paspec.format = PA_SAMPLE_INVALID;
             paspec.format = PA_SAMPLE_INVALID;
             break;
             break;
@@ -420,7 +456,7 @@ PULSEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
     }
     }
 
 
     h->mainloop_api = PULSEAUDIO_pa_mainloop_get_api(h->mainloop);
     h->mainloop_api = PULSEAUDIO_pa_mainloop_get_api(h->mainloop);
-    h->context = PULSEAUDIO_pa_context_new(h->mainloop_api, NULL);
+    h->context = PULSEAUDIO_pa_context_new(h->mainloop_api, getAppName());
     if (!h->context) {
     if (!h->context) {
         PULSEAUDIO_CloseDevice(this);
         PULSEAUDIO_CloseDevice(this);
         return SDL_SetError("pa_context_new() failed");
         return SDL_SetError("pa_context_new() failed");

+ 329 - 0
Source/ThirdParty/SDL/src/audio/sndio/SDL_sndioaudio.c

@@ -0,0 +1,329 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2013 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.
+*/
+
+#include "SDL_config.h"
+
+#if SDL_AUDIO_DRIVER_SNDIO
+
+/* OpenBSD sndio target */
+
+#if HAVE_STDIO_H
+#include <stdio.h>
+#endif
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#include <unistd.h>
+
+#include "SDL_audio.h"
+#include "../SDL_audiomem.h"
+#include "../SDL_audio_c.h"
+#include "SDL_sndioaudio.h"
+
+#ifdef SDL_AUDIO_DRIVER_SNDIO_DYNAMIC
+#include "SDL_loadso.h"
+#endif
+
+static struct sio_hdl * (*SNDIO_sio_open)(const char *, unsigned int, int);
+static void (*SNDIO_sio_close)(struct sio_hdl *);
+static int (*SNDIO_sio_setpar)(struct sio_hdl *, struct sio_par *);
+static int (*SNDIO_sio_getpar)(struct sio_hdl *, struct sio_par *);
+static int (*SNDIO_sio_start)(struct sio_hdl *);
+static int (*SNDIO_sio_stop)(struct sio_hdl *);
+static size_t (*SNDIO_sio_read)(struct sio_hdl *, void *, size_t);
+static size_t (*SNDIO_sio_write)(struct sio_hdl *, const void *, size_t);
+static void (*SNDIO_sio_initpar)(struct sio_par *);
+
+#ifdef SDL_AUDIO_DRIVER_SNDIO_DYNAMIC
+static const char *sndio_library = SDL_AUDIO_DRIVER_SNDIO_DYNAMIC;
+static void *sndio_handle = NULL;
+
+static int
+load_sndio_sym(const char *fn, void **addr)
+{
+    *addr = SDL_LoadFunction(sndio_handle, fn);
+    if (*addr == NULL) {
+        /* Don't call SDL_SetError(): SDL_LoadFunction already did. */
+        return 0;
+    }
+
+    return 1;
+}
+
+/* cast funcs to char* first, to please GCC's strict aliasing rules. */
+#define SDL_SNDIO_SYM(x) \
+    if (!load_sndio_sym(#x, (void **) (char *) &SNDIO_##x)) return -1
+#else
+#define SDL_SNDIO_SYM(x) SNDIO_##x = x
+#endif
+
+static int
+load_sndio_syms(void)
+{
+    SDL_SNDIO_SYM(sio_open);
+    SDL_SNDIO_SYM(sio_close);
+    SDL_SNDIO_SYM(sio_setpar);
+    SDL_SNDIO_SYM(sio_getpar);
+    SDL_SNDIO_SYM(sio_start);
+    SDL_SNDIO_SYM(sio_stop);
+    SDL_SNDIO_SYM(sio_read);
+    SDL_SNDIO_SYM(sio_write);
+    SDL_SNDIO_SYM(sio_initpar);
+    return 0;
+}
+
+#undef SDL_SNDIO_SYM
+
+#ifdef SDL_AUDIO_DRIVER_SNDIO_DYNAMIC
+
+static void
+UnloadSNDIOLibrary(void)
+{
+    if (sndio_handle != NULL) {
+        SDL_UnloadObject(sndio_handle);
+        sndio_handle = NULL;
+    }
+}
+
+static int
+LoadSNDIOLibrary(void)
+{
+    int retval = 0;
+    if (sndio_handle == NULL) {
+        sndio_handle = SDL_LoadObject(sndio_library);
+        if (sndio_handle == NULL) {
+            retval = -1;
+            /* Don't call SDL_SetError(): SDL_LoadObject already did. */
+        } else {
+            retval = load_sndio_syms();
+            if (retval < 0) {
+                UnloadSNDIOLibrary();
+            }
+        }
+    }
+    return retval;
+}
+
+#else
+
+static void
+UnloadSNDIOLibrary(void)
+{
+}
+
+static int
+LoadSNDIOLibrary(void)
+{
+    load_sndio_syms();
+    return 0;
+}
+
+#endif /* SDL_AUDIO_DRIVER_SNDIO_DYNAMIC */
+
+
+
+
+static void
+SNDIO_WaitDevice(_THIS)
+{
+    /* no-op; SNDIO_sio_write() blocks if necessary. */
+}
+
+static void
+SNDIO_PlayDevice(_THIS)
+{
+    const int written = SNDIO_sio_write(this->hidden->dev,
+                                        this->hidden->mixbuf,
+                                        this->hidden->mixlen);
+
+    /* If we couldn't write, assume fatal error for now */
+    if ( written == 0 ) {
+        this->enabled = 0;
+    }
+#ifdef DEBUG_AUDIO
+    fprintf(stderr, "Wrote %d bytes of audio data\n", written);
+#endif
+}
+
+static Uint8 *
+SNDIO_GetDeviceBuf(_THIS)
+{
+    return this->hidden->mixbuf;
+}
+
+static void
+SNDIO_WaitDone(_THIS)
+{
+    SNDIO_sio_stop(this->hidden->dev);
+}
+
+static void
+SNDIO_CloseDevice(_THIS)
+{
+    if (this->hidden != NULL) {
+        if (this->hidden->mixbuf != NULL) {
+            SDL_FreeAudioMem(this->hidden->mixbuf);
+            this->hidden->mixbuf = NULL;
+        }
+        if ( this->hidden->dev != NULL ) {
+            SNDIO_sio_close(this->hidden->dev);
+            this->hidden->dev = NULL;
+        }
+        SDL_free(this->hidden);
+        this->hidden = NULL;
+    }
+}
+
+static int
+SNDIO_OpenDevice(_THIS, const char *devname, int iscapture)
+{
+    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
+    struct sio_par par;
+    int status;
+
+    this->hidden = (struct SDL_PrivateAudioData *)
+        SDL_malloc(sizeof(*this->hidden));
+    if (this->hidden == NULL) {
+        return SDL_OutOfMemory();
+    }
+    SDL_memset(this->hidden, 0, sizeof(*this->hidden));
+
+    this->hidden->mixlen = this->spec.size;
+
+    /* !!! FIXME: SIO_DEVANY can be a specific device... */
+    if ((this->hidden->dev = SNDIO_sio_open(NULL, SIO_PLAY, 0)) == NULL) {
+        SNDIO_CloseDevice(this);
+        return SDL_SetError("sio_open() failed");
+    }
+
+    SNDIO_sio_initpar(&par);
+
+    par.rate = this->spec.freq;
+    par.pchan = this->spec.channels;
+    par.round = this->spec.samples;
+    par.appbufsz = par.round * 2;
+
+    /* Try for a closest match on audio format */
+    status = -1;
+    while (test_format && (status < 0)) {
+        if (!SDL_AUDIO_ISFLOAT(test_format)) {
+            par.le = SDL_AUDIO_ISLITTLEENDIAN(test_format) ? 1 : 0;
+            par.sig = SDL_AUDIO_ISSIGNED(test_format) ? 1 : 0;
+            par.bits = SDL_AUDIO_BITSIZE(test_format);
+
+            if (SNDIO_sio_setpar(this->hidden->dev, &par) == 1) {
+                status = 0;
+                break;
+            }
+        }
+        test_format = SDL_NextAudioFormat();
+    }
+
+    if (status < 0) {
+        SNDIO_CloseDevice(this);
+        return SDL_SetError("sndio: Couldn't find any hardware audio formats");
+    }
+
+    if (SNDIO_sio_getpar(this->hidden->dev, &par) == 0) {
+        SNDIO_CloseDevice(this);
+        return SDL_SetError("sio_getpar() failed");
+    }
+
+    if ((par.bits == 32) && (par.sig) && (par.le))
+        this->spec.format = AUDIO_S32LSB;
+    else if ((par.bits == 32) && (par.sig) && (!par.le))
+        this->spec.format = AUDIO_S32MSB;
+    else if ((par.bits == 16) && (par.sig) && (par.le))
+        this->spec.format = AUDIO_S16LSB;
+    else if ((par.bits == 16) && (par.sig) && (!par.le))
+        this->spec.format = AUDIO_S16MSB;
+    else if ((par.bits == 16) && (!par.sig) && (par.le))
+        this->spec.format = AUDIO_U16LSB;
+    else if ((par.bits == 16) && (!par.sig) && (!par.le))
+        this->spec.format = AUDIO_U16MSB;
+    else if ((par.bits == 8) && (par.sig))
+        this->spec.format = AUDIO_S8;
+    else if ((par.bits == 8) && (!par.sig))
+        this->spec.format = AUDIO_U8;
+    else {
+        SNDIO_CloseDevice(this);
+        return SDL_SetError("sndio: Got unsupported hardware audio format.");
+    }
+
+    this->spec.freq = par.rate;
+    this->spec.channels = par.pchan;
+    this->spec.samples = par.round;
+
+    /* Calculate the final parameters for this audio specification */
+    SDL_CalculateAudioSpec(&this->spec);
+
+    /* Allocate mixing buffer */
+    this->hidden->mixlen = this->spec.size;
+    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
+    if (this->hidden->mixbuf == NULL) {
+        SNDIO_CloseDevice(this);
+        return SDL_OutOfMemory();
+    }
+    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen);
+
+    if (!SNDIO_sio_start(this->hidden->dev)) {
+        return SDL_SetError("sio_start() failed");
+    }
+
+    /* We're ready to rock and roll. :-) */
+    return 0;
+}
+
+static void
+SNDIO_Deinitialize(void)
+{
+    UnloadSNDIOLibrary();
+}
+
+static int
+SNDIO_Init(SDL_AudioDriverImpl * impl)
+{
+    if (LoadSNDIOLibrary() < 0) {
+        return 0;
+    }
+
+    /* Set the function pointers */
+    impl->OpenDevice = SNDIO_OpenDevice;
+    impl->WaitDevice = SNDIO_WaitDevice;
+    impl->PlayDevice = SNDIO_PlayDevice;
+    impl->GetDeviceBuf = SNDIO_GetDeviceBuf;
+    impl->WaitDone = SNDIO_WaitDone;
+    impl->CloseDevice = SNDIO_CloseDevice;
+    impl->Deinitialize = SNDIO_Deinitialize;
+    impl->OnlyHasDefaultOutputDevice = 1;  /* !!! FIXME: sndio can handle multiple devices. */
+
+    return 1;   /* this audio target is available. */
+}
+
+AudioBootStrap SNDIO_bootstrap = {
+    "sndio", "OpenBSD sndio", SNDIO_Init, 0
+};
+
+#endif /* SDL_AUDIO_DRIVER_SNDIO */
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 13 - 10
Source/ThirdParty/SDL/src/audio/nds/SDL_ndsaudio.h → Source/ThirdParty/SDL/src/audio/sndio/SDL_sndioaudio.h

@@ -1,6 +1,6 @@
 /*
 /*
   Simple DirectMedia Layer
   Simple DirectMedia Layer
-  Copyright (C) 1997-2012 Sam Lantinga <[email protected]>
+  Copyright (C) 1997-2013 Sam Lantinga <[email protected]>
 
 
   This software is provided 'as-is', without any express or implied
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
   warranty.  In no event will the authors be held liable for any damages
@@ -20,23 +20,26 @@
 */
 */
 #include "SDL_config.h"
 #include "SDL_config.h"
 
 
-#ifndef _SDL_ndsaudio_h
-#define _SDL_ndsaudio_h
+#ifndef _SDL_sndioaudio_h
+#define _SDL_sndioaudio_h
+
+#include <sndio.h>
 
 
 #include "../SDL_sysaudio.h"
 #include "../SDL_sysaudio.h"
-#include <nds/arm9/sound.h>
 
 
 /* Hidden "this" pointer for the audio functions */
 /* Hidden "this" pointer for the audio functions */
-#define _THIS	SDL_AudioDevice *this
+#define _THIS   SDL_AudioDevice *this
 
 
 struct SDL_PrivateAudioData
 struct SDL_PrivateAudioData
 {
 {
-    /* The file descriptor for the audio device */
+    /* The audio device handle */
+    struct sio_hdl *dev;
+
+    /* Raw mixing buffer */
     Uint8 *mixbuf;
     Uint8 *mixbuf;
-    Uint32 mixlen;
-    Uint32 write_delay;
-    Uint32 initial_calls;
+    int mixlen;
 };
 };
 
 
-#endif /* _SDL_ndsaudio_h */
+#endif /* _SDL_sndioaudio_h */
+
 /* vi: set ts=4 sw=4 expandtab: */
 /* vi: set ts=4 sw=4 expandtab: */

+ 43 - 23
Source/ThirdParty/SDL/src/audio/winmm/SDL_winmm.c

@@ -32,6 +32,10 @@
 #include "../SDL_audio_c.h"
 #include "../SDL_audio_c.h"
 #include "SDL_winmm.h"
 #include "SDL_winmm.h"
 
 
+#ifndef WAVE_FORMAT_IEEE_FLOAT
+#define WAVE_FORMAT_IEEE_FLOAT 0x0003
+#endif
+
 #define DETECT_DEV_IMPL(typ, capstyp) \
 #define DETECT_DEV_IMPL(typ, capstyp) \
 static void DetectWave##typ##Devs(SDL_AddAudioDevice addfn) { \
 static void DetectWave##typ##Devs(SDL_AddAudioDevice addfn) { \
     const UINT devcount = wave##typ##GetNumDevs(); \
     const UINT devcount = wave##typ##GetNumDevs(); \
@@ -193,6 +197,30 @@ WINMM_CloseDevice(_THIS)
     }
     }
 }
 }
 
 
+static SDL_bool
+PrepWaveFormat(_THIS, UINT_PTR devId, WAVEFORMATEX *pfmt, const int iscapture)
+{
+    SDL_zerop(pfmt);
+
+    if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
+        pfmt->wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
+    } else {
+        pfmt->wFormatTag = WAVE_FORMAT_PCM;
+    }
+    pfmt->wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
+
+    pfmt->nChannels = this->spec.channels;
+    pfmt->nSamplesPerSec = this->spec.freq;
+    pfmt->nBlockAlign = pfmt->nChannels * (pfmt->wBitsPerSample / 8);
+    pfmt->nAvgBytesPerSec = pfmt->nSamplesPerSec * pfmt->nBlockAlign;
+
+    if (iscapture) {
+        return (waveInOpen(0, devId, pfmt, 0, 0, WAVE_FORMAT_QUERY) == 0);
+    } else {
+        return (waveOutOpen(0, devId, pfmt, 0, 0, WAVE_FORMAT_QUERY) == 0);
+    }
+}
+
 static int
 static int
 WINMM_OpenDevice(_THIS, const char *devname, int iscapture)
 WINMM_OpenDevice(_THIS, const char *devname, int iscapture)
 {
 {
@@ -250,17 +278,28 @@ WINMM_OpenDevice(_THIS, const char *devname, int iscapture)
     for (i = 0; i < NUM_BUFFERS; ++i)
     for (i = 0; i < NUM_BUFFERS; ++i)
         this->hidden->wavebuf[i].dwUser = 0xFFFF;
         this->hidden->wavebuf[i].dwUser = 0xFFFF;
 
 
+    if (this->spec.channels > 2)
+        this->spec.channels = 2;        /* !!! FIXME: is this right? */
+
+    /* Check the buffer size -- minimum of 1/4 second (word aligned) */
+    if (this->spec.samples < (this->spec.freq / 4))
+        this->spec.samples = ((this->spec.freq / 4) + 3) & ~3;
+
     while ((!valid_datatype) && (test_format)) {
     while ((!valid_datatype) && (test_format)) {
-        valid_datatype = 1;
-        this->spec.format = test_format;
         switch (test_format) {
         switch (test_format) {
         case AUDIO_U8:
         case AUDIO_U8:
         case AUDIO_S16:
         case AUDIO_S16:
         case AUDIO_S32:
         case AUDIO_S32:
-            break;              /* valid. */
+        case AUDIO_F32:
+            this->spec.format = test_format;
+            if (PrepWaveFormat(this, devId, &waveformat, iscapture)) {
+                valid_datatype = 1;
+            } else {
+                test_format = SDL_NextAudioFormat();
+            }
+            break;
 
 
         default:
         default:
-            valid_datatype = 0;
             test_format = SDL_NextAudioFormat();
             test_format = SDL_NextAudioFormat();
             break;
             break;
         }
         }
@@ -271,25 +310,6 @@ WINMM_OpenDevice(_THIS, const char *devname, int iscapture)
         return SDL_SetError("Unsupported audio format");
         return SDL_SetError("Unsupported audio format");
     }
     }
 
 
-    /* Set basic WAVE format parameters */
-    SDL_memset(&waveformat, '\0', sizeof(waveformat));
-    waveformat.wFormatTag = WAVE_FORMAT_PCM;
-    waveformat.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
-
-    if (this->spec.channels > 2)
-        this->spec.channels = 2;        /* !!! FIXME: is this right? */
-
-    waveformat.nChannels = this->spec.channels;
-    waveformat.nSamplesPerSec = this->spec.freq;
-    waveformat.nBlockAlign =
-        waveformat.nChannels * (waveformat.wBitsPerSample / 8);
-    waveformat.nAvgBytesPerSec =
-        waveformat.nSamplesPerSec * waveformat.nBlockAlign;
-
-    /* Check the buffer size -- minimum of 1/4 second (word aligned) */
-    if (this->spec.samples < (this->spec.freq / 4))
-        this->spec.samples = ((this->spec.freq / 4) + 3) & ~3;
-
     /* Update the fragment size as size in bytes */
     /* Update the fragment size as size in bytes */
     SDL_CalculateAudioSpec(&this->spec);
     SDL_CalculateAudioSpec(&this->spec);
 
 

+ 1426 - 1357
Source/ThirdParty/SDL/src/core/android/SDL_android.cpp → Source/ThirdParty/SDL/src/core/android/SDL_android.c

@@ -1,1357 +1,1426 @@
-/*
-  Simple DirectMedia Layer
-  Copyright (C) 1997-2013 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"
-#include "SDL_log.h"
-#include "SDL_main.h"
-
-#ifdef __ANDROID__
-
-#include "SDL_system.h"
-#include "SDL_android.h"
-// Urho3D: do not require EGL to allow compiling on API level 8
-// #include <EGL/egl.h>
-#define EGL_BUFFER_SIZE			0x3020
-#define EGL_ALPHA_SIZE			0x3021
-#define EGL_BLUE_SIZE			0x3022
-#define EGL_GREEN_SIZE			0x3023
-#define EGL_RED_SIZE			0x3024
-#define EGL_DEPTH_SIZE			0x3025
-#define EGL_STENCIL_SIZE		0x3026
-#define EGL_SAMPLES			0x3031
-#define EGL_SAMPLE_BUFFERS		0x3032
-#define EGL_RENDERABLE_TYPE		0x3040
-#define EGL_OPENGL_ES_BIT		0x0001	/* EGL_RENDERABLE_TYPE mask bits */
-#define EGL_OPENGL_ES2_BIT		0x0004	/* EGL_RENDERABLE_TYPE mask bits */
-#define EGL_NONE			0x3038	/* Attrib list terminator */
-
-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>
-#include <pthread.h>
-#include <sys/types.h>
-#include <unistd.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)
-
-/* Uncomment this to log messages entering and exiting methods in this file */
-//#define DEBUG_JNI
-
-/* Implemented in audio/android/SDL_androidaudio.c */
-extern void Android_RunAudioThread();
-
-static void Android_JNI_ThreadDestroyed(void*);
-} // C
-
-/*******************************************************************************
- This file links the Java side of Android with libsdl
-*******************************************************************************/
-#include <jni.h>
-#include <android/log.h>
-
-
-/*******************************************************************************
-                               Globals
-*******************************************************************************/
-static pthread_key_t mThreadKey;
-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;
-
-// Urho3D: 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;
-    }
-    /*
-     * Create mThreadKey so we can keep track of the JNIEnv assigned to each thread
-     * Refer to http://developer.android.com/guide/practices/design/jni.html for the rationale behind this
-     */
-    if (pthread_key_create(&mThreadKey, Android_JNI_ThreadDestroyed)) {
-        __android_log_print(ANDROID_LOG_ERROR, "SDL", "Error initializing pthread key");
-    }
-    else {
-        Android_JNI_SetupThread();
-    }
-
-    return JNI_VERSION_1_4;
-}
-
-// Urho3D: added function
-extern "C" const char* SDL_Android_GetFilesDir()
-{
-    return mFilesDir;
-}
-
-// Called before SDL_main() to initialize JNI bindings
-// Urho3D: added passing user files directory from SDLActivity on startup
-extern "C" void SDL_Android_Init(JNIEnv* mEnv, jclass cls, jstring filesDir)
-{
-    __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL_Android_Init()");
-
-    Android_JNI_SetupThread();
-
-    // Copy the files dir
-    const char *str;
-    str = mEnv->GetStringUTFChars(filesDir, 0);
-    if (str)
-    {
-        if (mFilesDir)
-            free(mFilesDir);
-
-        size_t length = strlen(str) + 1;
-        mFilesDir = (char*)malloc(length);
-        memcpy(mFilesDir, str, length);
-        mEnv->ReleaseStringUTFChars(filesDir, str);
-    }
-
-    mActivityClass = (jclass)mEnv->NewGlobalRef(cls);
-
-    midCreateGLContext = mEnv->GetStaticMethodID(mActivityClass,
-                                "createGLContext","(II[I)Z");
-    midFlipBuffers = mEnv->GetStaticMethodID(mActivityClass,
-                                "flipBuffers","()V");
-    midAudioInit = mEnv->GetStaticMethodID(mActivityClass,
-                                "audioInit", "(IZZI)V");
-    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 Java_org_libsdl_app_SDLActivity_onNativeResize(
-                                    JNIEnv* env, jclass jcls,
-                                    jint width, jint height, jint format)
-{
-    Android_SetScreenResolution(width, height, format);
-}
-
-// Keydown
-extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyDown(
-                                    JNIEnv* env, jclass jcls, jint keycode)
-{
-    Android_OnKeyDown(keycode);
-}
-
-// Keyup
-extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyUp(
-                                    JNIEnv* env, jclass jcls, jint keycode)
-{
-    Android_OnKeyUp(keycode);
-}
-
-// Touch
-extern "C" void Java_org_libsdl_app_SDLActivity_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 Java_org_libsdl_app_SDLActivity_onNativeAccel(
-                                    JNIEnv* env, jclass jcls,
-                                    jfloat x, jfloat y, jfloat z)
-{
-    fLastAccelerometer[0] = x;
-    fLastAccelerometer[1] = y;
-    fLastAccelerometer[2] = z;
-    bHasNewData = true;
-}
-
-// Start up the SDL app
-// Urho3D: added passing user files directory from SDLActivity on startup
-extern "C" void Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jstring filesDir)
-{
-    /* This interface could expand with ABI negotiation, calbacks, etc. */
-    SDL_Android_Init(env, cls, filesDir);
-
-    SDL_SetMainReady();
-
-    /* Run the application code! */
-    int status;
-    char *argv[2];
-    argv[0] = 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);
-}
-
-// Low memory
-extern "C" void Java_org_libsdl_app_SDLActivity_nativeLowMemory(
-                                    JNIEnv* env, jclass cls)
-{
-    SDL_SendAppEvent(SDL_APP_LOWMEMORY);
-}
-
-// Quit
-extern "C" void Java_org_libsdl_app_SDLActivity_nativeQuit(
-                                    JNIEnv* env, jclass cls)
-{
-    // Inject a SDL_QUIT event
-    SDL_SendQuit();
-    SDL_SendAppEvent(SDL_APP_TERMINATING);
-}
-
-// Pause
-extern "C" void Java_org_libsdl_app_SDLActivity_nativePause(
-                                    JNIEnv* env, jclass cls)
-{
-    if (Android_Window) {
-        /* Signal the pause semaphore so the event loop knows to pause and (optionally) block itself */
-        if (!SDL_SemValue(Android_PauseSem)) SDL_SemPost(Android_PauseSem);
-        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
-        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
-    }
-
-    __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "nativePause()");
-    SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND);
-    SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND);
-}
-
-// Resume
-extern "C" void Java_org_libsdl_app_SDLActivity_nativeResume(
-                                    JNIEnv* env, jclass cls)
-{
-    __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "nativeResume()");
-    SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND);
-    SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND);
-
-    if (Android_Window) {
-        /* Signal the resume semaphore so the event loop knows to resume and restore the GL Context
-         * We can't restore the GL Context here because it needs to be done on the SDL main thread
-         * and this function will be called from the Java thread instead.
-         */
-        if (!SDL_SemValue(Android_ResumeSem)) SDL_SemPost(Android_ResumeSem);
-        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
-        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_RESTORED, 0, 0);
-    }
-}
-
-extern "C" void Java_org_libsdl_app_SDLActivity_nativeRunAudioThread(
-                                    JNIEnv* env, jclass cls)
-{
-    /* This is the audio thread, with a different environment */
-    Android_JNI_SetupThread();
-
-    Android_RunAudioThread();
-}
-
-extern "C" void Java_org_libsdl_app_SDLInputConnection_nativeCommitText(
-                                    JNIEnv* env, jclass cls,
-                                    jstring text, jint newCursorPosition)
-{
-    const char *utftext = env->GetStringUTFChars(text, NULL);
-
-    SDL_SendKeyboardText(utftext);
-
-    env->ReleaseStringUTFChars(text, utftext);
-}
-
-extern "C" void Java_org_libsdl_app_SDLInputConnection_nativeSetComposingText(
-                                    JNIEnv* env, jclass cls,
-                                    jstring text, jint newCursorPosition)
-{
-    const char *utftext = env->GetStringUTFChars(text, NULL);
-
-    SDL_SendEditingText(utftext, 0, 0);
-
-    env->ReleaseStringUTFChars(text, utftext);
-}
-
-
-
-/*******************************************************************************
-             Functions called by SDL into Java
-*******************************************************************************/
-
-class LocalReferenceHolder
-{
-private:
-    static int s_active;
-
-public:
-    static bool IsActive() {
-        return s_active > 0;
-    }
-
-public:
-    LocalReferenceHolder(const char *func) : m_env(NULL), m_func(func) {
-#ifdef DEBUG_JNI
-        SDL_Log("Entering function %s", m_func);
-#endif
-    }
-    ~LocalReferenceHolder() {
-#ifdef DEBUG_JNI
-        SDL_Log("Leaving function %s", m_func);
-#endif
-        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;
-    const char *m_func;
-};
-int LocalReferenceHolder::s_active;
-
-extern "C" SDL_bool Android_JNI_CreateContext(int majorVersion, int minorVersion,
-                                int red, int green, int blue, int alpha,
-                                int buffer, int depth, int stencil,
-                                int buffers, int samples)
-{
-    JNIEnv *env = Android_JNI_GetEnv();
-
-    jint attribs[] = {
-        EGL_RED_SIZE, red,
-        EGL_GREEN_SIZE, green,
-        EGL_BLUE_SIZE, blue,
-        EGL_ALPHA_SIZE, alpha,
-        EGL_BUFFER_SIZE, buffer,
-        EGL_DEPTH_SIZE, depth,
-        EGL_STENCIL_SIZE, stencil,
-        EGL_SAMPLE_BUFFERS, buffers,
-        EGL_SAMPLES, samples,
-        EGL_RENDERABLE_TYPE, (majorVersion == 1 ? EGL_OPENGL_ES_BIT : EGL_OPENGL_ES2_BIT),
-        EGL_NONE
-    };
-    int len = SDL_arraysize(attribs);
-
-    jintArray array;
-
-    array = env->NewIntArray(len);
-    env->SetIntArrayRegion(array, 0, len, attribs);
-
-    jboolean success = env->CallStaticBooleanMethod(mActivityClass, midCreateGLContext, majorVersion, minorVersion, array);
-
-    env->DeleteLocalRef(array);
-
-    return success ? SDL_TRUE : SDL_FALSE;
-}
-
-extern "C" void Android_JNI_SwapWindow()
-{
-    JNIEnv *mEnv = Android_JNI_GetEnv();
-    mEnv->CallStaticVoidMethod(mActivityClass, midFlipBuffers);
-}
-
-extern "C" void Android_JNI_SetActivityTitle(const char *title)
-{
-    jmethodID mid;
-    JNIEnv *mEnv = Android_JNI_GetEnv();
-    mid = mEnv->GetStaticMethodID(mActivityClass,"setActivityTitle","(Ljava/lang/String;)Z");
-    if (mid) {
-        jstring jtitle = reinterpret_cast<jstring>(mEnv->NewStringUTF(title));
-        mEnv->CallStaticBooleanMethod(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;
-}
-
-static void Android_JNI_ThreadDestroyed(void* value) {
-    /* The thread is being destroyed, detach it from the Java VM and set the mThreadKey value to NULL as required */
-    JNIEnv *env = (JNIEnv*) value;
-    if (env != NULL) {
-        mJavaVM->DetachCurrentThread();
-        pthread_setspecific(mThreadKey, NULL);
-    }
-}
-
-JNIEnv* Android_JNI_GetEnv(void) {
-    /* From http://developer.android.com/guide/practices/jni.html
-     * All threads are Linux threads, scheduled by the kernel.
-     * They're usually started from managed code (using Thread.start), but they can also be created elsewhere and then
-     * attached to the JavaVM. For example, a thread started with pthread_create can be attached with the
-     * JNI AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a thread is attached, it has no JNIEnv,
-     * and cannot make JNI calls.
-     * Attaching a natively-created thread causes a java.lang.Thread object to be constructed and added to the "main"
-     * ThreadGroup, making it visible to the debugger. Calling AttachCurrentThread on an already-attached thread
-     * is a no-op.
-     * Note: You can call this function any number of times for the same thread, there's no harm in it
-     */
-
-    JNIEnv *env;
-    int status = mJavaVM->AttachCurrentThread(&env, NULL);
-    if(status < 0) {
-        LOGE("failed to attach current thread");
-        return 0;
-    }
-
-    return env;
-}
-
-int Android_JNI_SetupThread(void) {
-    /* From http://developer.android.com/guide/practices/jni.html
-     * Threads attached through JNI must call DetachCurrentThread before they exit. If coding this directly is awkward,
-     * in Android 2.0 (Eclair) and higher you can use pthread_key_create to define a destructor function that will be
-     * called before the thread exits, and call DetachCurrentThread from there. (Use that key with pthread_setspecific
-     * to store the JNIEnv in thread-local-storage; that way it'll be passed into your destructor as the argument.)
-     * Note: The destructor is not called unless the stored value is != NULL
-     * Note: You can call this function any number of times for the same thread, there's no harm in it
-     *       (except for some lost CPU cycles)
-     */
-    JNIEnv *env = Android_JNI_GetEnv();
-    pthread_setspecific(mThreadKey, (void*) env);
-    return 1;
-}
-
-//
-// 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;
-
-    JNIEnv *env = Android_JNI_GetEnv();
-
-    if (!env) {
-        LOGE("callback_handler: failed to attach current thread");
-    }
-    Android_JNI_SetupThread();
-
-    __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");
-    audioBuffer16Bit = is16Bit;
-    audioBufferStereo = channelCount > 1;
-
-    env->CallStaticVoidMethod(mActivityClass, midAudioInit, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames);
-
-    /* Allocating the audio buffer from the Java side and passing it as the return value for audioInit no longer works on
-     * Android >= 4.2 due to a "stale global reference" error. So now we allocate this buffer directly from this side. */
-
-    if (is16Bit) {
-        jshortArray audioBufferLocal = env->NewShortArray(desiredBufferFrames * (audioBufferStereo ? 2 : 1));
-        if (audioBufferLocal) {
-            audioBuffer = env->NewGlobalRef(audioBufferLocal);
-            env->DeleteLocalRef(audioBufferLocal);
-        }
-    }
-    else {
-        jbyteArray audioBufferLocal = env->NewByteArray(desiredBufferFrames * (audioBufferStereo ? 2 : 1));
-        if (audioBufferLocal) {
-            audioBuffer = env->NewGlobalRef(audioBufferLocal);
-            env->DeleteLocalRef(audioBufferLocal);
-        }
-    }
-
-    if (audioBuffer == NULL) {
-        __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: could not allocate an audio buffer!");
-        return 0;
-    }
-
-    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;
-    }
-
-    return audioBufferFrames;
-}
-
-extern "C" void * Android_JNI_GetAudioBuffer()
-{
-    return audioBufferPinned;
-}
-
-extern "C" void Android_JNI_WriteAudioBuffer()
-{
-    JNIEnv *mAudioEnv = Android_JNI_GetEnv();
-
-    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()
-{
-    JNIEnv *env = Android_JNI_GetEnv();
-
-    env->CallStaticVoidMethod(mActivityClass, midAudioQuit);
-
-    if (audioBuffer) {
-        env->DeleteGlobalRef(audioBuffer);
-        audioBuffer = NULL;
-        audioBufferPinned = NULL;
-    }
-}
-
-// Test for an exception and call SDL_SetError with its detail if one occurs
-// If optional parameter silent is truthy then SDL_SetError() is not called.
-static bool Android_JNI_ExceptionOccurred(bool silent = false)
-{
-    SDL_assert(LocalReferenceHolder::IsActive());
-    JNIEnv *mEnv = Android_JNI_GetEnv();
-
-    jthrowable exception = mEnv->ExceptionOccurred();
-    if (exception != NULL) {
-        jmethodID mid;
-
-        // Until this happens most JNI operations have undefined behaviour
-        mEnv->ExceptionClear();
-
-        if (!silent) {
-            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(__FUNCTION__);
-    int result = 0;
-
-    jmethodID mid;
-    jobject context;
-    jobject assetManager;
-    jobject inputStream;
-    jclass channels;
-    jobject readableByteChannel;
-    jstring fileNameJString;
-    jobject fd;
-    jclass fdCls;
-    jfieldID descriptor;
-
-    JNIEnv *mEnv = Android_JNI_GetEnv();
-    if (!refs.init(mEnv)) {
-        goto failure;
-    }
-
-    fileNameJString = (jstring)ctx->hidden.androidio.fileNameRef;
-    ctx->hidden.androidio.position = 0;
-
-    // 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);
-
-    /* First let's try opening the file to obtain an AssetFileDescriptor.
-    * This method reads the files directly from the APKs using standard *nix calls
-    */
-    mid = mEnv->GetMethodID(mEnv->GetObjectClass(assetManager), "openFd", "(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;");
-    inputStream = mEnv->CallObjectMethod(assetManager, mid, fileNameJString);
-    if (Android_JNI_ExceptionOccurred(true)) {
-        goto fallback;
-    }
-
-    mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream), "getStartOffset", "()J");
-    ctx->hidden.androidio.offset = mEnv->CallLongMethod(inputStream, mid);
-    if (Android_JNI_ExceptionOccurred(true)) {
-        goto fallback;
-    }
-
-    mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream), "getDeclaredLength", "()J");
-    ctx->hidden.androidio.size = mEnv->CallLongMethod(inputStream, mid);
-    if (Android_JNI_ExceptionOccurred(true)) {
-        goto fallback;
-    }
-
-    mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream), "getFileDescriptor", "()Ljava/io/FileDescriptor;");
-    fd = mEnv->CallObjectMethod(inputStream, mid);
-    fdCls = mEnv->GetObjectClass(fd);
-    descriptor = mEnv->GetFieldID(fdCls, "descriptor", "I");
-    ctx->hidden.androidio.fd = mEnv->GetIntField(fd, descriptor);
-    ctx->hidden.androidio.assetFileDescriptorRef = mEnv->NewGlobalRef(inputStream);
-
-    // Seek to the correct offset in the file.
-    lseek(ctx->hidden.androidio.fd, (off_t)ctx->hidden.androidio.offset, SEEK_SET);
-
-    if (false) {
-fallback:
-        // Disabled log message because of spam on the Nexus 7
-        //__android_log_print(ANDROID_LOG_DEBUG, "SDL", "Falling back to legacy InputStream method for opening file");
-
-        /* Try the old method using InputStream */
-        ctx->hidden.androidio.assetFileDescriptorRef = NULL;
-
-        // inputStream = assetManager.open(<filename>);
-        mid = mEnv->GetMethodID(mEnv->GetObjectClass(assetManager),
-                "open", "(Ljava/lang/String;I)Ljava/io/InputStream;");
-        inputStream = mEnv->CallObjectMethod(assetManager, mid, fileNameJString, 1 /*ACCESS_RANDOM*/);
-        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 = (long)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;
-    }
-
-    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);
-        }
-
-        if(ctx->hidden.androidio.assetFileDescriptorRef != NULL) {
-            mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.assetFileDescriptorRef);
-        }
-
-    }
-
-    return result;
-}
-
-extern "C" int Android_JNI_FileOpen(SDL_RWops* ctx,
-        const char* fileName, const char*)
-{
-    LocalReferenceHolder refs(__FUNCTION__);
-    JNIEnv *mEnv = Android_JNI_GetEnv();
-
-    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;
-    ctx->hidden.androidio.readableByteChannelRef = NULL;
-    ctx->hidden.androidio.readMethod = NULL;
-    ctx->hidden.androidio.assetFileDescriptorRef = 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(__FUNCTION__);
-
-    if (ctx->hidden.androidio.assetFileDescriptorRef) {
-        size_t bytesMax = size * maxnum;
-        if (ctx->hidden.androidio.size != -1 /*UNKNOWN_LENGTH*/ && ctx->hidden.androidio.position + bytesMax > ctx->hidden.androidio.size) {
-            bytesMax = ctx->hidden.androidio.size - ctx->hidden.androidio.position;
-        }
-        size_t result = read(ctx->hidden.androidio.fd, buffer, bytesMax );
-        if (result > 0) {
-            ctx->hidden.androidio.position += result;
-            return result / size;
-        }
-        return 0;
-    } else {
-        jlong bytesRemaining = (jlong) (size * maxnum);
-        jlong bytesMax = (jlong) (ctx->hidden.androidio.size -  ctx->hidden.androidio.position);
-        int bytesRead = 0;
-
-        /* Don't read more bytes than those that remain in the file, otherwise we get an exception */
-        if (bytesRemaining >  bytesMax) bytesRemaining = bytesMax;
-
-        JNIEnv *mEnv = Android_JNI_GetEnv();
-        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(__FUNCTION__);
-    int result = 0;
-    JNIEnv *mEnv = Android_JNI_GetEnv();
-
-    if (!refs.init(mEnv)) {
-        return SDL_SetError("Failed to allocate enough JVM local references");
-    }
-
-    if (ctx) {
-        if (release) {
-            mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.fileNameRef);
-        }
-
-        if (ctx->hidden.androidio.assetFileDescriptorRef) {
-            jobject inputStream = (jobject)ctx->hidden.androidio.assetFileDescriptorRef;
-            jmethodID mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream),
-                    "close", "()V");
-            mEnv->CallVoidMethod(inputStream, mid);
-            mEnv->DeleteGlobalRef((jobject)ctx->hidden.androidio.assetFileDescriptorRef);
-            if (Android_JNI_ExceptionOccurred()) {
-                result = -1;
-            }
-        }
-        else {
-            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" Sint64 Android_JNI_FileSize(SDL_RWops* ctx)
-{
-    return ctx->hidden.androidio.size;
-}
-
-extern "C" Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence)
-{
-    if (ctx->hidden.androidio.assetFileDescriptorRef) {
-        switch (whence) {
-            case RW_SEEK_SET:
-                if (ctx->hidden.androidio.size != -1 /*UNKNOWN_LENGTH*/ && offset > ctx->hidden.androidio.size) offset = ctx->hidden.androidio.size;
-                offset += ctx->hidden.androidio.offset;
-                break;
-            case RW_SEEK_CUR:
-                offset += ctx->hidden.androidio.position;
-                if (ctx->hidden.androidio.size != -1 /*UNKNOWN_LENGTH*/ && offset > ctx->hidden.androidio.size) offset = ctx->hidden.androidio.size;
-                offset += ctx->hidden.androidio.offset;
-                break;
-            case RW_SEEK_END:
-                offset = ctx->hidden.androidio.offset + ctx->hidden.androidio.size + offset;
-                break;
-            default:
-                return SDL_SetError("Unknown value for 'whence'");
-        }
-        whence = SEEK_SET;
-
-        off_t ret = lseek(ctx->hidden.androidio.fd, (off_t)offset, SEEK_SET);
-        if (ret == -1) return -1;
-        ctx->hidden.androidio.position = ret - ctx->hidden.androidio.offset;
-    } else {
-        Sint64 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:
-                return SDL_SetError("Unknown value for 'whence'");
-        }
-
-        /* Validate the new position */
-        if (newPosition < 0) {
-            return SDL_Error(SDL_EFSEEK);
-        }
-        if (newPosition > ctx->hidden.androidio.size) {
-            newPosition = ctx->hidden.androidio.size;
-        }
-
-        Sint64 movement = newPosition - ctx->hidden.androidio.position;
-        if (movement > 0) {
-            unsigned char buffer[4096];
-
-            // The easy case where we're seeking forwards
-            while (movement > 0) {
-                Sint64 amount = 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);
-        }
-    }
-
-    return ctx->hidden.androidio.position;
-
-}
-
-extern "C" int Android_JNI_FileClose(SDL_RWops* ctx)
-{
-    return Android_JNI_FileClose(ctx, true);
-}
-
-// returns a new global reference which needs to be released later
-static jobject Android_JNI_GetSystemServiceObject(const char* name)
-{
-    LocalReferenceHolder refs(__FUNCTION__);
-    JNIEnv* env = Android_JNI_GetEnv();
-    if (!refs.init(env)) {
-        return NULL;
-    }
-
-    jstring service = env->NewStringUTF(name);
-
-    jmethodID mid;
-
-    mid = env->GetStaticMethodID(mActivityClass, "getContext", "()Landroid/content/Context;");
-    jobject context = env->CallStaticObjectMethod(mActivityClass, mid);
-
-    mid = env->GetMethodID(mActivityClass, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
-    jobject manager = env->CallObjectMethod(context, mid, service);
-
-    env->DeleteLocalRef(service);
-
-    return manager ? env->NewGlobalRef(manager) : NULL;
-}
-
-#define SETUP_CLIPBOARD(error) \
-    LocalReferenceHolder refs(__FUNCTION__); \
-    JNIEnv* env = Android_JNI_GetEnv(); \
-    if (!refs.init(env)) { \
-        return error; \
-    } \
-    jobject clipboard = Android_JNI_GetSystemServiceObject("clipboard"); \
-    if (!clipboard) { \
-        return error; \
-    }
-
-extern "C" int Android_JNI_SetClipboardText(const char* text)
-{
-    SETUP_CLIPBOARD(-1)
-
-    jmethodID mid = env->GetMethodID(env->GetObjectClass(clipboard), "setText", "(Ljava/lang/CharSequence;)V");
-    jstring string = env->NewStringUTF(text);
-    env->CallVoidMethod(clipboard, mid, string);
-    env->DeleteGlobalRef(clipboard);
-    env->DeleteLocalRef(string);
-    return 0;
-}
-
-extern "C" char* Android_JNI_GetClipboardText()
-{
-    SETUP_CLIPBOARD(SDL_strdup(""))
-
-    jmethodID mid = env->GetMethodID(env->GetObjectClass(clipboard), "getText", "()Ljava/lang/CharSequence;");
-    jobject sequence = env->CallObjectMethod(clipboard, mid);
-    env->DeleteGlobalRef(clipboard);
-    if (sequence) {
-        mid = env->GetMethodID(env->GetObjectClass(sequence), "toString", "()Ljava/lang/String;");
-        jstring string = reinterpret_cast<jstring>(env->CallObjectMethod(sequence, mid));
-        const char* utf = env->GetStringUTFChars(string, 0);
-        if (utf) {
-            char* text = SDL_strdup(utf);
-            env->ReleaseStringUTFChars(string, utf);
-            return text;
-        }
-    }
-    return SDL_strdup("");
-}
-
-extern "C" SDL_bool Android_JNI_HasClipboardText()
-{
-    SETUP_CLIPBOARD(SDL_FALSE)
-
-    jmethodID mid = env->GetMethodID(env->GetObjectClass(clipboard), "hasText", "()Z");
-    jboolean has = env->CallBooleanMethod(clipboard, mid);
-    env->DeleteGlobalRef(clipboard);
-    return has ? SDL_TRUE : SDL_FALSE;
-}
-
-
-// returns 0 on success or -1 on error (others undefined then)
-// returns truthy or falsy value in plugged, charged and battery
-// returns the value in seconds and percent or -1 if not available
-extern "C" int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seconds, int* percent)
-{
-    LocalReferenceHolder refs(__FUNCTION__);
-    JNIEnv* env = Android_JNI_GetEnv();
-    if (!refs.init(env)) {
-        return -1;
-    }
-
-    jmethodID mid;
-
-    mid = env->GetStaticMethodID(mActivityClass, "getContext", "()Landroid/content/Context;");
-    jobject context = env->CallStaticObjectMethod(mActivityClass, mid);
-
-    jstring action = env->NewStringUTF("android.intent.action.BATTERY_CHANGED");
-
-    jclass cls = env->FindClass("android/content/IntentFilter");
-
-    mid = env->GetMethodID(cls, "<init>", "(Ljava/lang/String;)V");
-    jobject filter = env->NewObject(cls, mid, action);
-
-    env->DeleteLocalRef(action);
-
-    mid = env->GetMethodID(mActivityClass, "registerReceiver", "(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;");
-    jobject intent = env->CallObjectMethod(context, mid, NULL, filter);
-
-    env->DeleteLocalRef(filter);
-
-    cls = env->GetObjectClass(intent);
-
-    jstring iname;
-    jmethodID imid = env->GetMethodID(cls, "getIntExtra", "(Ljava/lang/String;I)I");
-
-#define GET_INT_EXTRA(var, key) \
-    iname = env->NewStringUTF(key); \
-    int var = env->CallIntMethod(intent, imid, iname, -1); \
-    env->DeleteLocalRef(iname);
-
-    jstring bname;
-    jmethodID bmid = env->GetMethodID(cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z");
-
-#define GET_BOOL_EXTRA(var, key) \
-    bname = env->NewStringUTF(key); \
-    int var = env->CallBooleanMethod(intent, bmid, bname, JNI_FALSE); \
-    env->DeleteLocalRef(bname);
-
-    if (plugged) {
-        GET_INT_EXTRA(plug, "plugged") // == BatteryManager.EXTRA_PLUGGED (API 5)
-        if (plug == -1) {
-            return -1;
-        }
-        // 1 == BatteryManager.BATTERY_PLUGGED_AC
-        // 2 == BatteryManager.BATTERY_PLUGGED_USB
-        *plugged = (0 < plug) ? 1 : 0;
-    }
-
-    if (charged) {
-        GET_INT_EXTRA(status, "status") // == BatteryManager.EXTRA_STATUS (API 5)
-        if (status == -1) {
-            return -1;
-        }
-        // 5 == BatteryManager.BATTERY_STATUS_FULL
-        *charged = (status == 5) ? 1 : 0;
-    }
-
-    if (battery) {
-        GET_BOOL_EXTRA(present, "present") // == BatteryManager.EXTRA_PRESENT (API 5)
-        *battery = present ? 1 : 0;
-    }
-
-    if (seconds) {
-        *seconds = -1; // not possible
-    }
-
-    if (percent) {
-        GET_INT_EXTRA(level, "level") // == BatteryManager.EXTRA_LEVEL (API 5)
-        GET_INT_EXTRA(scale, "scale") // == BatteryManager.EXTRA_SCALE (API 5)
-        if ((level == -1) || (scale == -1)) {
-            return -1;
-        }
-        *percent = level * 100 / scale;
-    }
-
-    env->DeleteLocalRef(intent);
-
-    return 0;
-}
-
-// sends message to be handled on the UI event dispatch thread
-extern "C" int Android_JNI_SendMessage(int command, int param)
-{
-    JNIEnv *env = Android_JNI_GetEnv();
-    if (!env) {
-        return -1;
-    }
-    jmethodID mid = env->GetStaticMethodID(mActivityClass, "sendMessage", "(II)Z");
-    if (!mid) {
-        return -1;
-    }
-    jboolean success = env->CallStaticBooleanMethod(mActivityClass, mid, command, param);
-    return success ? 0 : -1;
-}
-
-extern "C" void Android_JNI_ShowTextInput(SDL_Rect *inputRect)
-{
-    JNIEnv *env = Android_JNI_GetEnv();
-    if (!env) {
-        return;
-    }
-
-    jmethodID mid = env->GetStaticMethodID(mActivityClass, "showTextInput", "(IIII)Z");
-    if (!mid) {
-        return;
-    }
-    env->CallStaticBooleanMethod( mActivityClass, mid,
-                               inputRect->x,
-                               inputRect->y,
-                               inputRect->w,
-                               inputRect->h );
-}
-
-extern "C" void Android_JNI_HideTextInput()
-{
-    // has to match Activity constant
-    const int COMMAND_TEXTEDIT_HIDE = 3;
-    Android_JNI_SendMessage(COMMAND_TEXTEDIT_HIDE, 0);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// Functions exposed to SDL applications in SDL_system.h
-//
-
-extern "C" void *SDL_AndroidGetJNIEnv()
-{
-    return Android_JNI_GetEnv();
-}
-
-
-
-extern "C" void *SDL_AndroidGetActivity()
-{
-    /* See SDL_system.h for caveats on using this function. */
-
-    jmethodID mid;
-
-    JNIEnv *env = Android_JNI_GetEnv();
-    if (!env) {
-        return NULL;
-    }
-
-    // return SDLActivity.getContext();
-    mid = env->GetStaticMethodID(mActivityClass,
-            "getContext","()Landroid/content/Context;");
-    return env->CallStaticObjectMethod(mActivityClass, mid);
-}
-
-extern "C" const char * SDL_AndroidGetInternalStoragePath()
-{
-    static char *s_AndroidInternalFilesPath = NULL;
-
-    if (!s_AndroidInternalFilesPath) {
-        LocalReferenceHolder refs(__FUNCTION__);
-        jmethodID mid;
-        jobject context;
-        jobject fileObject;
-        jstring pathString;
-        const char *path;
-
-        JNIEnv *env = Android_JNI_GetEnv();
-        if (!refs.init(env)) {
-            return NULL;
-        }
-
-        // context = SDLActivity.getContext();
-        mid = env->GetStaticMethodID(mActivityClass,
-                "getContext","()Landroid/content/Context;");
-        context = env->CallStaticObjectMethod(mActivityClass, mid);
-
-        // fileObj = context.getFilesDir();
-        mid = env->GetMethodID(env->GetObjectClass(context),
-                "getFilesDir", "()Ljava/io/File;");
-        fileObject = env->CallObjectMethod(context, mid);
-        if (!fileObject) {
-            SDL_SetError("Couldn't get internal directory");
-            return NULL;
-        }
-
-        // path = fileObject.getAbsolutePath();
-        mid = env->GetMethodID(env->GetObjectClass(fileObject),
-                "getAbsolutePath", "()Ljava/lang/String;");
-        pathString = (jstring)env->CallObjectMethod(fileObject, mid);
-
-        path = env->GetStringUTFChars(pathString, NULL);
-        s_AndroidInternalFilesPath = SDL_strdup(path);
-        env->ReleaseStringUTFChars(pathString, path);
-    }
-    return s_AndroidInternalFilesPath;
-}
-
-extern "C" int SDL_AndroidGetExternalStorageState()
-{
-    LocalReferenceHolder refs(__FUNCTION__);
-    jmethodID mid;
-    jclass cls;
-    jstring stateString;
-    const char *state;
-    int stateFlags;
-
-    JNIEnv *env = Android_JNI_GetEnv();
-    if (!refs.init(env)) {
-        return 0;
-    }
-
-    cls = env->FindClass("android/os/Environment");
-    mid = env->GetStaticMethodID(cls,
-            "getExternalStorageState", "()Ljava/lang/String;");
-    stateString = (jstring)env->CallStaticObjectMethod(cls, mid);
-
-    state = env->GetStringUTFChars(stateString, NULL);
-
-    // Print an info message so people debugging know the storage state
-    __android_log_print(ANDROID_LOG_INFO, "SDL", "external storage state: %s", state);
-
-    if (SDL_strcmp(state, "mounted") == 0) {
-        stateFlags = SDL_ANDROID_EXTERNAL_STORAGE_READ |
-                     SDL_ANDROID_EXTERNAL_STORAGE_WRITE;
-    } else if (SDL_strcmp(state, "mounted_ro") == 0) {
-        stateFlags = SDL_ANDROID_EXTERNAL_STORAGE_READ;
-    } else {
-        stateFlags = 0;
-    }
-    env->ReleaseStringUTFChars(stateString, state);
-
-    return stateFlags;
-}
-
-extern "C" const char * SDL_AndroidGetExternalStoragePath()
-{
-    static char *s_AndroidExternalFilesPath = NULL;
-
-    if (!s_AndroidExternalFilesPath) {
-        LocalReferenceHolder refs(__FUNCTION__);
-        jmethodID mid;
-        jobject context;
-        jobject fileObject;
-        jstring pathString;
-        const char *path;
-
-        JNIEnv *env = Android_JNI_GetEnv();
-        if (!refs.init(env)) {
-            return NULL;
-        }
-
-        // context = SDLActivity.getContext();
-        mid = env->GetStaticMethodID(mActivityClass,
-                "getContext","()Landroid/content/Context;");
-        context = env->CallStaticObjectMethod(mActivityClass, mid);
-
-        // fileObj = context.getExternalFilesDir();
-        mid = env->GetMethodID(env->GetObjectClass(context),
-                "getExternalFilesDir", "(Ljava/lang/String;)Ljava/io/File;");
-        fileObject = env->CallObjectMethod(context, mid, NULL);
-        if (!fileObject) {
-            SDL_SetError("Couldn't get external directory");
-            return NULL;
-        }
-
-        // path = fileObject.getAbsolutePath();
-        mid = env->GetMethodID(env->GetObjectClass(fileObject),
-                "getAbsolutePath", "()Ljava/lang/String;");
-        pathString = (jstring)env->CallObjectMethod(fileObject, mid);
-
-        path = env->GetStringUTFChars(pathString, NULL);
-        s_AndroidExternalFilesPath = SDL_strdup(path);
-        env->ReleaseStringUTFChars(pathString, path);
-    }
-    return s_AndroidExternalFilesPath;
-}
-
-#endif /* __ANDROID__ */
-
-/* vi: set ts=4 sw=4 expandtab: */
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2013 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"
+#include "SDL_log.h"
+
+#ifdef __ANDROID__
+
+#include "SDL_system.h"
+#include "SDL_android.h"
+// Urho3D: do not require EGL to allow compiling on API level 8
+// #include <EGL/egl.h>
+#define EGL_BUFFER_SIZE			0x3020
+#define EGL_ALPHA_SIZE			0x3021
+#define EGL_BLUE_SIZE			0x3022
+#define EGL_GREEN_SIZE			0x3023
+#define EGL_RED_SIZE			0x3024
+#define EGL_DEPTH_SIZE			0x3025
+#define EGL_STENCIL_SIZE		0x3026
+#define EGL_SAMPLES			0x3031
+#define EGL_SAMPLE_BUFFERS		0x3032
+#define EGL_RENDERABLE_TYPE		0x3040
+#define EGL_OPENGL_ES_BIT		0x0001	/* EGL_RENDERABLE_TYPE mask bits */
+#define EGL_OPENGL_ES2_BIT		0x0004	/* EGL_RENDERABLE_TYPE mask bits */
+#define EGL_NONE			0x3038	/* Attrib list terminator */
+
+#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>
+#include <pthread.h>
+#include <sys/types.h>
+#include <unistd.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)
+
+/* Uncomment this to log messages entering and exiting methods in this file */
+//#define DEBUG_JNI
+
+static void Android_JNI_ThreadDestroyed(void*);
+
+/*******************************************************************************
+ This file links the Java side of Android with libsdl
+*******************************************************************************/
+#include <jni.h>
+#include <android/log.h>
+#include <stdbool.h>
+
+
+/*******************************************************************************
+                               Globals
+*******************************************************************************/
+static pthread_key_t mThreadKey;
+static JavaVM* mJavaVM;
+
+// Main activity
+static jclass mActivityClass;
+
+// method signatures
+static jmethodID midCreateGLContext;
+static jmethodID midDeleteGLContext;
+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;
+
+// Urho3D: application files dir
+static char* mFilesDir = 0;
+
+/*******************************************************************************
+                 Functions called by JNI
+*******************************************************************************/
+
+// Library init
+jint JNI_OnLoad(JavaVM* vm, void* reserved)
+{
+    JNIEnv *env;
+    mJavaVM = vm;
+    LOGI("JNI_OnLoad called");
+    if ((*mJavaVM)->GetEnv(mJavaVM, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+        LOGE("Failed to get the environment using GetEnv()");
+        return -1;
+    }
+    /*
+     * Create mThreadKey so we can keep track of the JNIEnv assigned to each thread
+     * Refer to http://developer.android.com/guide/practices/design/jni.html for the rationale behind this
+     */
+    if (pthread_key_create(&mThreadKey, Android_JNI_ThreadDestroyed)) {
+        __android_log_print(ANDROID_LOG_ERROR, "SDL", "Error initializing pthread key");
+    }
+    else {
+        Android_JNI_SetupThread();
+    }
+
+    return JNI_VERSION_1_4;
+}
+
+// Urho3D: added function
+const char* SDL_Android_GetFilesDir()
+{
+    return mFilesDir;
+}
+
+// Called before SDL_main() to initialize JNI bindings
+// Urho3D: added passing user files directory from SDLActivity on startup
+void SDL_Android_Init(JNIEnv* mEnv, jclass cls, jstring filesDir)
+{
+    __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL_Android_Init()");
+
+    Android_JNI_SetupThread();
+
+    // Copy the files dir
+    const char *str;
+    str = (*mEnv)->GetStringUTFChars(mEnv, filesDir, 0);
+    if (str)
+    {
+        if (mFilesDir)
+            free(mFilesDir);
+
+        size_t length = strlen(str) + 1;
+        mFilesDir = (char*)malloc(length);
+        memcpy(mFilesDir, str, length);
+        (*mEnv)->ReleaseStringUTFChars(mEnv, filesDir, str);
+    }
+
+    mActivityClass = (jclass)((*mEnv)->NewGlobalRef(mEnv, cls));
+
+    midCreateGLContext = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
+                                "createGLContext","(II[I)Z");
+    midDeleteGLContext = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
+                                "deleteGLContext","()V");
+    midFlipBuffers = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
+                                "flipBuffers","()V");
+    midAudioInit = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
+                                "audioInit", "(IZZI)I");
+    midAudioWriteShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
+                                "audioWriteShortBuffer", "([S)V");
+    midAudioWriteByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
+                                "audioWriteByteBuffer", "([B)V");
+    midAudioQuit = (*mEnv)->GetStaticMethodID(mEnv, 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!");
+}
+
+// Urho3D: moved function here due to link error
+// Start up the SDL app
+void Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jstring filesDir)
+{
+    /* This interface could expand with ABI negotiation, callbacks, etc. */
+    SDL_Android_Init(env, cls, filesDir);
+
+    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);
+}
+
+// Resize
+void Java_org_libsdl_app_SDLActivity_onNativeResize(
+                                    JNIEnv* env, jclass jcls,
+                                    jint width, jint height, jint format)
+{
+    Android_SetScreenResolution(width, height, format);
+}
+
+// Keydown
+void Java_org_libsdl_app_SDLActivity_onNativeKeyDown(
+                                    JNIEnv* env, jclass jcls, jint keycode)
+{
+    Android_OnKeyDown(keycode);
+}
+
+// Keyup
+void Java_org_libsdl_app_SDLActivity_onNativeKeyUp(
+                                    JNIEnv* env, jclass jcls, jint keycode)
+{
+    Android_OnKeyUp(keycode);
+}
+
+// Keyboard Focus Lost
+void Java_org_libsdl_app_SDLActivity_onNativeKeyboardFocusLost(
+                                    JNIEnv* env, jclass jcls)
+{
+    /* Calling SDL_StopTextInput will take care of hiding the keyboard and cleaning up the DummyText widget */
+    SDL_StopTextInput();
+}
+
+
+// Touch
+void Java_org_libsdl_app_SDLActivity_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
+void Java_org_libsdl_app_SDLActivity_onNativeAccel(
+                                    JNIEnv* env, jclass jcls,
+                                    jfloat x, jfloat y, jfloat z)
+{
+    fLastAccelerometer[0] = x;
+    fLastAccelerometer[1] = y;
+    fLastAccelerometer[2] = z;
+    bHasNewData = true;
+}
+
+// Low memory
+void Java_org_libsdl_app_SDLActivity_nativeLowMemory(
+                                    JNIEnv* env, jclass cls)
+{
+    SDL_SendAppEvent(SDL_APP_LOWMEMORY);
+}
+
+// Quit
+void Java_org_libsdl_app_SDLActivity_nativeQuit(
+                                    JNIEnv* env, jclass cls)
+{
+    // Inject a SDL_QUIT event
+    SDL_SendQuit();
+    SDL_SendAppEvent(SDL_APP_TERMINATING);
+}
+
+// Pause
+void Java_org_libsdl_app_SDLActivity_nativePause(
+                                    JNIEnv* env, jclass cls)
+{
+    if (Android_Window) {
+        /* Signal the pause semaphore so the event loop knows to pause and (optionally) block itself */
+        if (!SDL_SemValue(Android_PauseSem)) SDL_SemPost(Android_PauseSem);
+        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
+        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
+    }
+
+    __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "nativePause()");
+    SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND);
+    SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND);
+}
+
+// Resume
+void Java_org_libsdl_app_SDLActivity_nativeResume(
+                                    JNIEnv* env, jclass cls)
+{
+    __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "nativeResume()");
+    SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND);
+    SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND);
+
+    if (Android_Window) {
+        /* Signal the resume semaphore so the event loop knows to resume and restore the GL Context
+         * We can't restore the GL Context here because it needs to be done on the SDL main thread
+         * and this function will be called from the Java thread instead.
+         */
+        if (!SDL_SemValue(Android_ResumeSem)) SDL_SemPost(Android_ResumeSem);
+        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
+        SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_RESTORED, 0, 0);
+    }
+}
+
+void Java_org_libsdl_app_SDLInputConnection_nativeCommitText(
+                                    JNIEnv* env, jclass cls,
+                                    jstring text, jint newCursorPosition)
+{
+    const char *utftext = (*env)->GetStringUTFChars(env, text, NULL);
+
+    SDL_SendKeyboardText(utftext);
+
+    (*env)->ReleaseStringUTFChars(env, text, utftext);
+}
+
+void Java_org_libsdl_app_SDLInputConnection_nativeSetComposingText(
+                                    JNIEnv* env, jclass cls,
+                                    jstring text, jint newCursorPosition)
+{
+    const char *utftext = (*env)->GetStringUTFChars(env, text, NULL);
+
+    SDL_SendEditingText(utftext, 0, 0);
+
+    (*env)->ReleaseStringUTFChars(env, text, utftext);
+}
+
+
+
+/*******************************************************************************
+             Functions called by SDL into Java
+*******************************************************************************/
+
+static int s_active = 0;
+struct LocalReferenceHolder
+{
+    JNIEnv *m_env;
+    const char *m_func;
+};
+
+static struct LocalReferenceHolder LocalReferenceHolder_Setup(const char *func)
+{
+    struct LocalReferenceHolder refholder;
+    refholder.m_env = NULL;
+    refholder.m_func = func;
+#ifdef DEBUG_JNI
+    SDL_Log("Entering function %s", func);
+#endif
+    return refholder;
+}
+
+static SDL_bool LocalReferenceHolder_Init(struct LocalReferenceHolder *refholder, JNIEnv *env)
+{
+    const int capacity = 16;
+    if ((*env)->PushLocalFrame(env, capacity) < 0) {
+        SDL_SetError("Failed to allocate enough JVM local references");
+        return SDL_FALSE;
+    }
+    ++s_active;
+    refholder->m_env = env;
+    return SDL_TRUE;
+}
+
+static void LocalReferenceHolder_Cleanup(struct LocalReferenceHolder *refholder)
+{
+#ifdef DEBUG_JNI
+    SDL_Log("Leaving function %s", refholder->m_func);
+#endif
+    if (refholder->m_env) {
+        JNIEnv* env = refholder->m_env;
+        (*env)->PopLocalFrame(env, NULL);
+        --s_active;
+    }
+}
+
+static SDL_bool LocalReferenceHolder_IsActive()
+{
+    return s_active > 0;    
+}
+
+
+SDL_bool Android_JNI_CreateContext(int majorVersion, int minorVersion,
+                                int red, int green, int blue, int alpha,
+                                int buffer, int depth, int stencil,
+                                int buffers, int samples)
+{
+    JNIEnv *env = Android_JNI_GetEnv();
+
+    jint attribs[] = {
+        EGL_RED_SIZE, red,
+        EGL_GREEN_SIZE, green,
+        EGL_BLUE_SIZE, blue,
+        EGL_ALPHA_SIZE, alpha,
+        EGL_BUFFER_SIZE, buffer,
+        EGL_DEPTH_SIZE, depth,
+        EGL_STENCIL_SIZE, stencil,
+        EGL_SAMPLE_BUFFERS, buffers,
+        EGL_SAMPLES, samples,
+        EGL_RENDERABLE_TYPE, (majorVersion == 1 ? EGL_OPENGL_ES_BIT : EGL_OPENGL_ES2_BIT),
+        EGL_NONE
+    };
+    int len = SDL_arraysize(attribs);
+
+    jintArray array;
+
+    array = (*env)->NewIntArray(env, len);
+    (*env)->SetIntArrayRegion(env, array, 0, len, attribs);
+
+    jboolean success = (*env)->CallStaticBooleanMethod(env, mActivityClass, midCreateGLContext, majorVersion, minorVersion, array);
+
+    (*env)->DeleteLocalRef(env, array);
+
+    return success ? SDL_TRUE : SDL_FALSE;
+}
+
+SDL_bool Android_JNI_DeleteContext(void)
+{
+    /* There's only one context, so no parameter for now */
+    JNIEnv *env = Android_JNI_GetEnv();
+    (*env)->CallStaticVoidMethod(env, mActivityClass, midDeleteGLContext);
+    return SDL_TRUE;
+}
+
+void Android_JNI_SwapWindow()
+{
+    JNIEnv *mEnv = Android_JNI_GetEnv();
+    (*mEnv)->CallStaticVoidMethod(mEnv, mActivityClass, midFlipBuffers);
+}
+
+void Android_JNI_SetActivityTitle(const char *title)
+{
+    jmethodID mid;
+    JNIEnv *mEnv = Android_JNI_GetEnv();
+    mid = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,"setActivityTitle","(Ljava/lang/String;)Z");
+    if (mid) {
+        jstring jtitle = (jstring)((*mEnv)->NewStringUTF(mEnv, title));
+        (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, mid, jtitle);
+        (*mEnv)->DeleteLocalRef(mEnv, jtitle);
+    }
+}
+
+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;
+}
+
+static void Android_JNI_ThreadDestroyed(void* value) {
+    /* The thread is being destroyed, detach it from the Java VM and set the mThreadKey value to NULL as required */
+    JNIEnv *env = (JNIEnv*) value;
+    if (env != NULL) {
+        (*mJavaVM)->DetachCurrentThread(mJavaVM);
+        pthread_setspecific(mThreadKey, NULL);
+    }
+}
+
+JNIEnv* Android_JNI_GetEnv(void) {
+    /* From http://developer.android.com/guide/practices/jni.html
+     * All threads are Linux threads, scheduled by the kernel.
+     * They're usually started from managed code (using Thread.start), but they can also be created elsewhere and then
+     * attached to the JavaVM. For example, a thread started with pthread_create can be attached with the
+     * JNI AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a thread is attached, it has no JNIEnv,
+     * and cannot make JNI calls.
+     * Attaching a natively-created thread causes a java.lang.Thread object to be constructed and added to the "main"
+     * ThreadGroup, making it visible to the debugger. Calling AttachCurrentThread on an already-attached thread
+     * is a no-op.
+     * Note: You can call this function any number of times for the same thread, there's no harm in it
+     */
+
+    JNIEnv *env;
+    int status = (*mJavaVM)->AttachCurrentThread(mJavaVM, &env, NULL);
+    if(status < 0) {
+        LOGE("failed to attach current thread");
+        return 0;
+    }
+
+    return env;
+}
+
+int Android_JNI_SetupThread(void) {
+    /* From http://developer.android.com/guide/practices/jni.html
+     * Threads attached through JNI must call DetachCurrentThread before they exit. If coding this directly is awkward,
+     * in Android 2.0 (Eclair) and higher you can use pthread_key_create to define a destructor function that will be
+     * called before the thread exits, and call DetachCurrentThread from there. (Use that key with pthread_setspecific
+     * to store the JNIEnv in thread-local-storage; that way it'll be passed into your destructor as the argument.)
+     * Note: The destructor is not called unless the stored value is != NULL
+     * Note: You can call this function any number of times for the same thread, there's no harm in it
+     *       (except for some lost CPU cycles)
+     */
+    JNIEnv *env = Android_JNI_GetEnv();
+    pthread_setspecific(mThreadKey, (void*) env);
+    return 1;
+}
+
+//
+// Audio support
+//
+static jboolean audioBuffer16Bit = JNI_FALSE;
+static jboolean audioBufferStereo = JNI_FALSE;
+static jobject audioBuffer = NULL;
+static void* audioBufferPinned = NULL;
+
+int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames)
+{
+    int audioBufferFrames;
+
+    JNIEnv *env = Android_JNI_GetEnv();
+
+    if (!env) {
+        LOGE("callback_handler: failed to attach current thread");
+    }
+    Android_JNI_SetupThread();
+
+    __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");
+    audioBuffer16Bit = is16Bit;
+    audioBufferStereo = channelCount > 1;
+
+    if ((*env)->CallStaticIntMethod(env, mActivityClass, midAudioInit, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) {
+        /* Error during audio initialization */
+        __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: error on AudioTrack initialization!");
+        return 0;
+    }
+
+    /* Allocating the audio buffer from the Java side and passing it as the return value for audioInit no longer works on
+     * Android >= 4.2 due to a "stale global reference" error. So now we allocate this buffer directly from this side. */
+
+    if (is16Bit) {
+        jshortArray audioBufferLocal = (*env)->NewShortArray(env, desiredBufferFrames * (audioBufferStereo ? 2 : 1));
+        if (audioBufferLocal) {
+            audioBuffer = (*env)->NewGlobalRef(env, audioBufferLocal);
+            (*env)->DeleteLocalRef(env, audioBufferLocal);
+        }
+    }
+    else {
+        jbyteArray audioBufferLocal = (*env)->NewByteArray(env, desiredBufferFrames * (audioBufferStereo ? 2 : 1));
+        if (audioBufferLocal) {
+            audioBuffer = (*env)->NewGlobalRef(env, audioBufferLocal);
+            (*env)->DeleteLocalRef(env, audioBufferLocal);
+        }
+    }
+
+    if (audioBuffer == NULL) {
+        __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: could not allocate an audio buffer!");
+        return 0;
+    }
+
+    jboolean isCopy = JNI_FALSE;
+    if (audioBuffer16Bit) {
+        audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy);
+        audioBufferFrames = (*env)->GetArrayLength(env, (jshortArray)audioBuffer);
+    } else {
+        audioBufferPinned = (*env)->GetByteArrayElements(env, (jbyteArray)audioBuffer, &isCopy);
+        audioBufferFrames = (*env)->GetArrayLength(env, (jbyteArray)audioBuffer);
+    }
+    if (audioBufferStereo) {
+        audioBufferFrames /= 2;
+    }
+
+    return audioBufferFrames;
+}
+
+void * Android_JNI_GetAudioBuffer()
+{
+    return audioBufferPinned;
+}
+
+void Android_JNI_WriteAudioBuffer()
+{
+    JNIEnv *mAudioEnv = Android_JNI_GetEnv();
+
+    if (audioBuffer16Bit) {
+        (*mAudioEnv)->ReleaseShortArrayElements(mAudioEnv, (jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT);
+        (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mActivityClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer);
+    } else {
+        (*mAudioEnv)->ReleaseByteArrayElements(mAudioEnv, (jbyteArray)audioBuffer, (jbyte *)audioBufferPinned, JNI_COMMIT);
+        (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mActivityClass, midAudioWriteByteBuffer, (jbyteArray)audioBuffer);
+    }
+
+    /* JNI_COMMIT means the changes are committed to the VM but the buffer remains pinned */
+}
+
+void Android_JNI_CloseAudioDevice()
+{
+    JNIEnv *env = Android_JNI_GetEnv();
+
+    (*env)->CallStaticVoidMethod(env, mActivityClass, midAudioQuit);
+
+    if (audioBuffer) {
+        (*env)->DeleteGlobalRef(env, audioBuffer);
+        audioBuffer = NULL;
+        audioBufferPinned = NULL;
+    }
+}
+
+// Test for an exception and call SDL_SetError with its detail if one occurs
+// If the parameter silent is truthy then SDL_SetError() will not be called.
+static bool Android_JNI_ExceptionOccurred(bool silent)
+{
+    SDL_assert(LocalReferenceHolder_IsActive());
+    JNIEnv *mEnv = Android_JNI_GetEnv();
+
+    jthrowable exception = (*mEnv)->ExceptionOccurred(mEnv);
+    if (exception != NULL) {
+        jmethodID mid;
+
+        // Until this happens most JNI operations have undefined behaviour
+        (*mEnv)->ExceptionClear(mEnv);
+
+        if (!silent) {
+            jclass exceptionClass = (*mEnv)->GetObjectClass(mEnv, exception);
+            jclass classClass = (*mEnv)->FindClass(mEnv, "java/lang/Class");
+
+            mid = (*mEnv)->GetMethodID(mEnv, classClass, "getName", "()Ljava/lang/String;");
+            jstring exceptionName = (jstring)(*mEnv)->CallObjectMethod(mEnv, exceptionClass, mid);
+            const char* exceptionNameUTF8 = (*mEnv)->GetStringUTFChars(mEnv, exceptionName, 0);
+
+            mid = (*mEnv)->GetMethodID(mEnv, exceptionClass, "getMessage", "()Ljava/lang/String;");
+            jstring exceptionMessage = (jstring)(*mEnv)->CallObjectMethod(mEnv, exception, mid);
+
+            if (exceptionMessage != NULL) {
+                const char* exceptionMessageUTF8 = (*mEnv)->GetStringUTFChars(mEnv, exceptionMessage, 0);
+                SDL_SetError("%s: %s", exceptionNameUTF8, exceptionMessageUTF8);
+                (*mEnv)->ReleaseStringUTFChars(mEnv, exceptionMessage, exceptionMessageUTF8);
+            } else {
+                SDL_SetError("%s", exceptionNameUTF8);
+            }
+
+            (*mEnv)->ReleaseStringUTFChars(mEnv, exceptionName, exceptionNameUTF8);
+        }
+
+        return true;
+    }
+
+    return false;
+}
+
+static int Internal_Android_JNI_FileOpen(SDL_RWops* ctx)
+{
+    struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
+
+    int result = 0;
+
+    jmethodID mid;
+    jobject context;
+    jobject assetManager;
+    jobject inputStream;
+    jclass channels;
+    jobject readableByteChannel;
+    jstring fileNameJString;
+    jobject fd;
+    jclass fdCls;
+    jfieldID descriptor;
+
+    JNIEnv *mEnv = Android_JNI_GetEnv();
+    if (!LocalReferenceHolder_Init(&refs, mEnv)) {
+        goto failure;
+    }
+
+    fileNameJString = (jstring)ctx->hidden.androidio.fileNameRef;
+    ctx->hidden.androidio.position = 0;
+
+    // context = SDLActivity.getContext();
+    mid = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
+            "getContext","()Landroid/content/Context;");
+    context = (*mEnv)->CallStaticObjectMethod(mEnv, mActivityClass, mid);
+
+
+    // assetManager = context.getAssets();
+    mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, context),
+            "getAssets", "()Landroid/content/res/AssetManager;");
+    assetManager = (*mEnv)->CallObjectMethod(mEnv, context, mid);
+
+    /* First let's try opening the file to obtain an AssetFileDescriptor.
+    * This method reads the files directly from the APKs using standard *nix calls
+    */
+    mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, assetManager), "openFd", "(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;");
+    inputStream = (*mEnv)->CallObjectMethod(mEnv, assetManager, mid, fileNameJString);
+    if (Android_JNI_ExceptionOccurred(true)) {
+        goto fallback;
+    }
+
+    mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream), "getStartOffset", "()J");
+    ctx->hidden.androidio.offset = (*mEnv)->CallLongMethod(mEnv, inputStream, mid);
+    if (Android_JNI_ExceptionOccurred(true)) {
+        goto fallback;
+    }
+
+    mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream), "getDeclaredLength", "()J");
+    ctx->hidden.androidio.size = (*mEnv)->CallLongMethod(mEnv, inputStream, mid);
+    if (Android_JNI_ExceptionOccurred(true)) {
+        goto fallback;
+    }
+
+    mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream), "getFileDescriptor", "()Ljava/io/FileDescriptor;");
+    fd = (*mEnv)->CallObjectMethod(mEnv, inputStream, mid);
+    fdCls = (*mEnv)->GetObjectClass(mEnv, fd);
+    descriptor = (*mEnv)->GetFieldID(mEnv, fdCls, "descriptor", "I");
+    ctx->hidden.androidio.fd = (*mEnv)->GetIntField(mEnv, fd, descriptor);
+    ctx->hidden.androidio.assetFileDescriptorRef = (*mEnv)->NewGlobalRef(mEnv, inputStream);
+
+    // Seek to the correct offset in the file.
+    lseek(ctx->hidden.androidio.fd, (off_t)ctx->hidden.androidio.offset, SEEK_SET);
+
+    if (false) {
+fallback:
+        // Disabled log message because of spam on the Nexus 7
+        //__android_log_print(ANDROID_LOG_DEBUG, "SDL", "Falling back to legacy InputStream method for opening file");
+
+        /* Try the old method using InputStream */
+        ctx->hidden.androidio.assetFileDescriptorRef = NULL;
+
+        // inputStream = assetManager.open(<filename>);
+        mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, assetManager),
+                "open", "(Ljava/lang/String;I)Ljava/io/InputStream;");
+        inputStream = (*mEnv)->CallObjectMethod(mEnv, assetManager, mid, fileNameJString, 1 /*ACCESS_RANDOM*/);
+        if (Android_JNI_ExceptionOccurred(false)) {
+            goto failure;
+        }
+
+        ctx->hidden.androidio.inputStreamRef = (*mEnv)->NewGlobalRef(mEnv, 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, (*mEnv)->GetObjectClass(mEnv, inputStream),
+                "available", "()I");
+        ctx->hidden.androidio.size = (long)(*mEnv)->CallIntMethod(mEnv, inputStream, mid);
+        if (Android_JNI_ExceptionOccurred(false)) {
+            goto failure;
+        }
+
+        // readableByteChannel = Channels.newChannel(inputStream);
+        channels = (*mEnv)->FindClass(mEnv, "java/nio/channels/Channels");
+        mid = (*mEnv)->GetStaticMethodID(mEnv, channels,
+                "newChannel",
+                "(Ljava/io/InputStream;)Ljava/nio/channels/ReadableByteChannel;");
+        readableByteChannel = (*mEnv)->CallStaticObjectMethod(
+                mEnv, channels, mid, inputStream);
+        if (Android_JNI_ExceptionOccurred(false)) {
+            goto failure;
+        }
+
+        ctx->hidden.androidio.readableByteChannelRef =
+            (*mEnv)->NewGlobalRef(mEnv, readableByteChannel);
+
+        // Store .read id for reading purposes
+        mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, readableByteChannel),
+                "read", "(Ljava/nio/ByteBuffer;)I");
+        ctx->hidden.androidio.readMethod = mid;
+    }
+
+    if (false) {
+failure:
+        result = -1;
+
+        (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.fileNameRef);
+
+        if(ctx->hidden.androidio.inputStreamRef != NULL) {
+            (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.inputStreamRef);
+        }
+
+        if(ctx->hidden.androidio.readableByteChannelRef != NULL) {
+            (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.readableByteChannelRef);
+        }
+
+        if(ctx->hidden.androidio.assetFileDescriptorRef != NULL) {
+            (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.assetFileDescriptorRef);
+        }
+
+    }
+    
+    LocalReferenceHolder_Cleanup(&refs);
+    return result;
+}
+
+int Android_JNI_FileOpen(SDL_RWops* ctx,
+        const char* fileName, const char* mode)
+{
+    struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
+    JNIEnv *mEnv = Android_JNI_GetEnv();
+    int retval;
+
+    if (!LocalReferenceHolder_Init(&refs, mEnv)) {
+        LocalReferenceHolder_Cleanup(&refs);        
+        return -1;
+    }
+
+    if (!ctx) {
+        LocalReferenceHolder_Cleanup(&refs);
+        return -1;
+    }
+
+    jstring fileNameJString = (*mEnv)->NewStringUTF(mEnv, fileName);
+    ctx->hidden.androidio.fileNameRef = (*mEnv)->NewGlobalRef(mEnv, fileNameJString);
+    ctx->hidden.androidio.inputStreamRef = NULL;
+    ctx->hidden.androidio.readableByteChannelRef = NULL;
+    ctx->hidden.androidio.readMethod = NULL;
+    ctx->hidden.androidio.assetFileDescriptorRef = NULL;
+
+    retval = Internal_Android_JNI_FileOpen(ctx);
+    LocalReferenceHolder_Cleanup(&refs);
+    return retval;
+}
+
+size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer,
+        size_t size, size_t maxnum)
+{
+    struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
+
+    if (ctx->hidden.androidio.assetFileDescriptorRef) {
+        size_t bytesMax = size * maxnum;
+        if (ctx->hidden.androidio.size != -1 /*UNKNOWN_LENGTH*/ && ctx->hidden.androidio.position + bytesMax > ctx->hidden.androidio.size) {
+            bytesMax = ctx->hidden.androidio.size - ctx->hidden.androidio.position;
+        }
+        size_t result = read(ctx->hidden.androidio.fd, buffer, bytesMax );
+        if (result > 0) {
+            ctx->hidden.androidio.position += result;
+            LocalReferenceHolder_Cleanup(&refs);
+            return result / size;
+        }
+        LocalReferenceHolder_Cleanup(&refs);
+        return 0;
+    } else {
+        jlong bytesRemaining = (jlong) (size * maxnum);
+        jlong bytesMax = (jlong) (ctx->hidden.androidio.size -  ctx->hidden.androidio.position);
+        int bytesRead = 0;
+
+        /* Don't read more bytes than those that remain in the file, otherwise we get an exception */
+        if (bytesRemaining >  bytesMax) bytesRemaining = bytesMax;
+
+        JNIEnv *mEnv = Android_JNI_GetEnv();
+        if (!LocalReferenceHolder_Init(&refs, mEnv)) {
+            LocalReferenceHolder_Cleanup(&refs);            
+            return 0;
+        }
+
+        jobject readableByteChannel = (jobject)ctx->hidden.androidio.readableByteChannelRef;
+        jmethodID readMethod = (jmethodID)ctx->hidden.androidio.readMethod;
+        jobject byteBuffer = (*mEnv)->NewDirectByteBuffer(mEnv, buffer, bytesRemaining);
+
+        while (bytesRemaining > 0) {
+            // result = readableByteChannel.read(...);
+            int result = (*mEnv)->CallIntMethod(mEnv, readableByteChannel, readMethod, byteBuffer);
+
+            if (Android_JNI_ExceptionOccurred(false)) {
+                LocalReferenceHolder_Cleanup(&refs);            
+                return 0;
+            }
+
+            if (result < 0) {
+                break;
+            }
+
+            bytesRemaining -= result;
+            bytesRead += result;
+            ctx->hidden.androidio.position += result;
+        }
+        LocalReferenceHolder_Cleanup(&refs);                    
+        return bytesRead / size;
+    }
+}
+
+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 Internal_Android_JNI_FileClose(SDL_RWops* ctx, bool release)
+{
+    struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
+
+    int result = 0;
+    JNIEnv *mEnv = Android_JNI_GetEnv();
+
+    if (!LocalReferenceHolder_Init(&refs, mEnv)) {
+        LocalReferenceHolder_Cleanup(&refs);
+        return SDL_SetError("Failed to allocate enough JVM local references");
+    }
+
+    if (ctx) {
+        if (release) {
+            (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.fileNameRef);
+        }
+
+        if (ctx->hidden.androidio.assetFileDescriptorRef) {
+            jobject inputStream = (jobject)ctx->hidden.androidio.assetFileDescriptorRef;
+            jmethodID mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream),
+                    "close", "()V");
+            (*mEnv)->CallVoidMethod(mEnv, inputStream, mid);
+            (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.assetFileDescriptorRef);
+            if (Android_JNI_ExceptionOccurred(false)) {
+                result = -1;
+            }
+        }
+        else {
+            jobject inputStream = (jobject)ctx->hidden.androidio.inputStreamRef;
+
+            // inputStream.close();
+            jmethodID mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream),
+                    "close", "()V");
+            (*mEnv)->CallVoidMethod(mEnv, inputStream, mid);
+            (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.inputStreamRef);
+            (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.readableByteChannelRef);
+            if (Android_JNI_ExceptionOccurred(false)) {
+                result = -1;
+            }
+        }
+
+        if (release) {
+            SDL_FreeRW(ctx);
+        }
+    }
+
+    LocalReferenceHolder_Cleanup(&refs);
+    return result;
+}
+
+
+Sint64 Android_JNI_FileSize(SDL_RWops* ctx)
+{
+    return ctx->hidden.androidio.size;
+}
+
+Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence)
+{
+    if (ctx->hidden.androidio.assetFileDescriptorRef) {
+        switch (whence) {
+            case RW_SEEK_SET:
+                if (ctx->hidden.androidio.size != -1 /*UNKNOWN_LENGTH*/ && offset > ctx->hidden.androidio.size) offset = ctx->hidden.androidio.size;
+                offset += ctx->hidden.androidio.offset;
+                break;
+            case RW_SEEK_CUR:
+                offset += ctx->hidden.androidio.position;
+                if (ctx->hidden.androidio.size != -1 /*UNKNOWN_LENGTH*/ && offset > ctx->hidden.androidio.size) offset = ctx->hidden.androidio.size;
+                offset += ctx->hidden.androidio.offset;
+                break;
+            case RW_SEEK_END:
+                offset = ctx->hidden.androidio.offset + ctx->hidden.androidio.size + offset;
+                break;
+            default:
+                return SDL_SetError("Unknown value for 'whence'");
+        }
+        whence = SEEK_SET;
+
+        off_t ret = lseek(ctx->hidden.androidio.fd, (off_t)offset, SEEK_SET);
+        if (ret == -1) return -1;
+        ctx->hidden.androidio.position = ret - ctx->hidden.androidio.offset;
+    } else {
+        Sint64 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:
+                return SDL_SetError("Unknown value for 'whence'");
+        }
+
+        /* Validate the new position */
+        if (newPosition < 0) {
+            return SDL_Error(SDL_EFSEEK);
+        }
+        if (newPosition > ctx->hidden.androidio.size) {
+            newPosition = ctx->hidden.androidio.size;
+        }
+
+        Sint64 movement = newPosition - ctx->hidden.androidio.position;
+        if (movement > 0) {
+            unsigned char buffer[4096];
+
+            // The easy case where we're seeking forwards
+            while (movement > 0) {
+                Sint64 amount = 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
+            Internal_Android_JNI_FileClose(ctx, false);
+            Internal_Android_JNI_FileOpen(ctx);
+            Android_JNI_FileSeek(ctx, newPosition, RW_SEEK_SET);
+        }
+    }
+
+    return ctx->hidden.androidio.position;
+
+}
+
+int Android_JNI_FileClose(SDL_RWops* ctx)
+{
+    return Internal_Android_JNI_FileClose(ctx, true);
+}
+
+// returns a new global reference which needs to be released later
+static jobject Android_JNI_GetSystemServiceObject(const char* name)
+{
+    struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
+    JNIEnv* env = Android_JNI_GetEnv();
+    jobject retval = NULL;
+
+    if (!LocalReferenceHolder_Init(&refs, env)) {
+        LocalReferenceHolder_Cleanup(&refs);
+        return NULL;
+    }
+
+    jstring service = (*env)->NewStringUTF(env, name);
+
+    jmethodID mid;
+
+    mid = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/content/Context;");
+    jobject context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid);
+
+    mid = (*env)->GetMethodID(env, mActivityClass, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
+    jobject manager = (*env)->CallObjectMethod(env, context, mid, service);
+
+    (*env)->DeleteLocalRef(env, service);
+
+    retval = manager ? (*env)->NewGlobalRef(env, manager) : NULL;
+    LocalReferenceHolder_Cleanup(&refs);
+    return retval;
+}
+
+#define SETUP_CLIPBOARD(error) \
+    struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); \
+    JNIEnv* env = Android_JNI_GetEnv(); \
+    if (!LocalReferenceHolder_Init(&refs, env)) { \
+        LocalReferenceHolder_Cleanup(&refs); \
+        return error; \
+    } \
+    jobject clipboard = Android_JNI_GetSystemServiceObject("clipboard"); \
+    if (!clipboard) { \
+        LocalReferenceHolder_Cleanup(&refs); \
+        return error; \
+    }
+
+#define CLEANUP_CLIPBOARD() \
+    LocalReferenceHolder_Cleanup(&refs);
+
+int Android_JNI_SetClipboardText(const char* text)
+{
+    SETUP_CLIPBOARD(-1)
+
+    jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "setText", "(Ljava/lang/CharSequence;)V");
+    jstring string = (*env)->NewStringUTF(env, text);
+    (*env)->CallVoidMethod(env, clipboard, mid, string);
+    (*env)->DeleteGlobalRef(env, clipboard);
+    (*env)->DeleteLocalRef(env, string);
+
+    CLEANUP_CLIPBOARD();
+
+    return 0;
+}
+
+char* Android_JNI_GetClipboardText()
+{
+    SETUP_CLIPBOARD(SDL_strdup(""))
+
+    jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "getText", "()Ljava/lang/CharSequence;");
+    jobject sequence = (*env)->CallObjectMethod(env, clipboard, mid);
+    (*env)->DeleteGlobalRef(env, clipboard);
+    if (sequence) {
+        mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, sequence), "toString", "()Ljava/lang/String;");
+        jstring string = (jstring)((*env)->CallObjectMethod(env, sequence, mid));
+        const char* utf = (*env)->GetStringUTFChars(env, string, 0);
+        if (utf) {
+            char* text = SDL_strdup(utf);
+            (*env)->ReleaseStringUTFChars(env, string, utf);
+
+            CLEANUP_CLIPBOARD();
+
+            return text;
+        }
+    }
+
+    CLEANUP_CLIPBOARD();    
+
+    return SDL_strdup("");
+}
+
+SDL_bool Android_JNI_HasClipboardText()
+{
+    SETUP_CLIPBOARD(SDL_FALSE)
+
+    jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "hasText", "()Z");
+    jboolean has = (*env)->CallBooleanMethod(env, clipboard, mid);
+    (*env)->DeleteGlobalRef(env, clipboard);
+
+    CLEANUP_CLIPBOARD();
+    
+    return has ? SDL_TRUE : SDL_FALSE;
+}
+
+
+// returns 0 on success or -1 on error (others undefined then)
+// returns truthy or falsy value in plugged, charged and battery
+// returns the value in seconds and percent or -1 if not available
+int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seconds, int* percent)
+{
+    struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
+    JNIEnv* env = Android_JNI_GetEnv();
+    if (!LocalReferenceHolder_Init(&refs, env)) {
+        LocalReferenceHolder_Cleanup(&refs);
+        return -1;
+    }
+
+    jmethodID mid;
+
+    mid = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/content/Context;");
+    jobject context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid);
+
+    jstring action = (*env)->NewStringUTF(env, "android.intent.action.BATTERY_CHANGED");
+
+    jclass cls = (*env)->FindClass(env, "android/content/IntentFilter");
+
+    mid = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/lang/String;)V");
+    jobject filter = (*env)->NewObject(env, cls, mid, action);
+
+    (*env)->DeleteLocalRef(env, action);
+
+    mid = (*env)->GetMethodID(env, mActivityClass, "registerReceiver", "(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;");
+    jobject intent = (*env)->CallObjectMethod(env, context, mid, NULL, filter);
+
+    (*env)->DeleteLocalRef(env, filter);
+
+    cls = (*env)->GetObjectClass(env, intent);
+
+    jstring iname;
+    jmethodID imid = (*env)->GetMethodID(env, cls, "getIntExtra", "(Ljava/lang/String;I)I");
+
+#define GET_INT_EXTRA(var, key) \
+    iname = (*env)->NewStringUTF(env, key); \
+    int var = (*env)->CallIntMethod(env, intent, imid, iname, -1); \
+    (*env)->DeleteLocalRef(env, iname);
+
+    jstring bname;
+    jmethodID bmid = (*env)->GetMethodID(env, cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z");
+
+#define GET_BOOL_EXTRA(var, key) \
+    bname = (*env)->NewStringUTF(env, key); \
+    int var = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \
+    (*env)->DeleteLocalRef(env, bname);
+
+    if (plugged) {
+        GET_INT_EXTRA(plug, "plugged") // == BatteryManager.EXTRA_PLUGGED (API 5)
+        if (plug == -1) {
+            LocalReferenceHolder_Cleanup(&refs);
+            return -1;
+        }
+        // 1 == BatteryManager.BATTERY_PLUGGED_AC
+        // 2 == BatteryManager.BATTERY_PLUGGED_USB
+        *plugged = (0 < plug) ? 1 : 0;
+    }
+
+    if (charged) {
+        GET_INT_EXTRA(status, "status") // == BatteryManager.EXTRA_STATUS (API 5)
+        if (status == -1) {
+            LocalReferenceHolder_Cleanup(&refs);
+            return -1;
+        }
+        // 5 == BatteryManager.BATTERY_STATUS_FULL
+        *charged = (status == 5) ? 1 : 0;
+    }
+
+    if (battery) {
+        GET_BOOL_EXTRA(present, "present") // == BatteryManager.EXTRA_PRESENT (API 5)
+        *battery = present ? 1 : 0;
+    }
+
+    if (seconds) {
+        *seconds = -1; // not possible
+    }
+
+    if (percent) {
+        GET_INT_EXTRA(level, "level") // == BatteryManager.EXTRA_LEVEL (API 5)
+        GET_INT_EXTRA(scale, "scale") // == BatteryManager.EXTRA_SCALE (API 5)
+        if ((level == -1) || (scale == -1)) {
+            LocalReferenceHolder_Cleanup(&refs);
+            return -1;
+        }
+        *percent = level * 100 / scale;
+    }
+
+    (*env)->DeleteLocalRef(env, intent);
+
+    LocalReferenceHolder_Cleanup(&refs);
+    return 0;
+}
+
+// sends message to be handled on the UI event dispatch thread
+int Android_JNI_SendMessage(int command, int param)
+{
+    JNIEnv *env = Android_JNI_GetEnv();
+    if (!env) {
+        return -1;
+    }
+    jmethodID mid = (*env)->GetStaticMethodID(env, mActivityClass, "sendMessage", "(II)Z");
+    if (!mid) {
+        return -1;
+    }
+    jboolean success = (*env)->CallStaticBooleanMethod(env, mActivityClass, mid, command, param);
+    return success ? 0 : -1;
+}
+
+void Android_JNI_ShowTextInput(SDL_Rect *inputRect)
+{
+    JNIEnv *env = Android_JNI_GetEnv();
+    if (!env) {
+        return;
+    }
+
+    jmethodID mid = (*env)->GetStaticMethodID(env, mActivityClass, "showTextInput", "(IIII)Z");
+    if (!mid) {
+        return;
+    }
+    (*env)->CallStaticBooleanMethod(env, mActivityClass, mid,
+                               inputRect->x,
+                               inputRect->y,
+                               inputRect->w,
+                               inputRect->h );
+}
+
+void Android_JNI_HideTextInput()
+{
+    // has to match Activity constant
+    const int COMMAND_TEXTEDIT_HIDE = 3;
+    Android_JNI_SendMessage(COMMAND_TEXTEDIT_HIDE, 0);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Functions exposed to SDL applications in SDL_system.h
+//
+
+void *SDL_AndroidGetJNIEnv()
+{
+    return Android_JNI_GetEnv();
+}
+
+
+
+void *SDL_AndroidGetActivity()
+{
+    /* See SDL_system.h for caveats on using this function. */
+
+    jmethodID mid;
+
+    JNIEnv *env = Android_JNI_GetEnv();
+    if (!env) {
+        return NULL;
+    }
+
+    // return SDLActivity.getContext();
+    mid = (*env)->GetStaticMethodID(env, mActivityClass,
+            "getContext","()Landroid/content/Context;");
+    return (*env)->CallStaticObjectMethod(env, mActivityClass, mid);
+}
+
+const char * SDL_AndroidGetInternalStoragePath()
+{
+    static char *s_AndroidInternalFilesPath = NULL;
+
+    if (!s_AndroidInternalFilesPath) {
+        struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
+        jmethodID mid;
+        jobject context;
+        jobject fileObject;
+        jstring pathString;
+        const char *path;
+
+        JNIEnv *env = Android_JNI_GetEnv();
+        if (!LocalReferenceHolder_Init(&refs, env)) {
+            LocalReferenceHolder_Cleanup(&refs);
+            return NULL;
+        }
+
+        // context = SDLActivity.getContext();
+        mid = (*env)->GetStaticMethodID(env, mActivityClass,
+                "getContext","()Landroid/content/Context;");
+        context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid);
+
+        // fileObj = context.getFilesDir();
+        mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),
+                "getFilesDir", "()Ljava/io/File;");
+        fileObject = (*env)->CallObjectMethod(env, context, mid);
+        if (!fileObject) {
+            SDL_SetError("Couldn't get internal directory");
+            LocalReferenceHolder_Cleanup(&refs);
+            return NULL;
+        }
+
+        // path = fileObject.getAbsolutePath();
+        mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, fileObject),
+                "getAbsolutePath", "()Ljava/lang/String;");
+        pathString = (jstring)(*env)->CallObjectMethod(env, fileObject, mid);
+
+        path = (*env)->GetStringUTFChars(env, pathString, NULL);
+        s_AndroidInternalFilesPath = SDL_strdup(path);
+        (*env)->ReleaseStringUTFChars(env, pathString, path);
+
+        LocalReferenceHolder_Cleanup(&refs);
+    }
+    return s_AndroidInternalFilesPath;
+}
+
+int SDL_AndroidGetExternalStorageState()
+{
+    struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
+    jmethodID mid;
+    jclass cls;
+    jstring stateString;
+    const char *state;
+    int stateFlags;
+
+    JNIEnv *env = Android_JNI_GetEnv();
+    if (!LocalReferenceHolder_Init(&refs, env)) {
+        LocalReferenceHolder_Cleanup(&refs);
+        return 0;
+    }
+
+    cls = (*env)->FindClass(env, "android/os/Environment");
+    mid = (*env)->GetStaticMethodID(env, cls,
+            "getExternalStorageState", "()Ljava/lang/String;");
+    stateString = (jstring)(*env)->CallStaticObjectMethod(env, cls, mid);
+
+    state = (*env)->GetStringUTFChars(env, stateString, NULL);
+
+    // Print an info message so people debugging know the storage state
+    __android_log_print(ANDROID_LOG_INFO, "SDL", "external storage state: %s", state);
+
+    if (SDL_strcmp(state, "mounted") == 0) {
+        stateFlags = SDL_ANDROID_EXTERNAL_STORAGE_READ |
+                     SDL_ANDROID_EXTERNAL_STORAGE_WRITE;
+    } else if (SDL_strcmp(state, "mounted_ro") == 0) {
+        stateFlags = SDL_ANDROID_EXTERNAL_STORAGE_READ;
+    } else {
+        stateFlags = 0;
+    }
+    (*env)->ReleaseStringUTFChars(env, stateString, state);
+
+    LocalReferenceHolder_Cleanup(&refs);
+    return stateFlags;
+}
+
+const char * SDL_AndroidGetExternalStoragePath()
+{
+    static char *s_AndroidExternalFilesPath = NULL;
+
+    if (!s_AndroidExternalFilesPath) {
+        struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
+        jmethodID mid;
+        jobject context;
+        jobject fileObject;
+        jstring pathString;
+        const char *path;
+
+        JNIEnv *env = Android_JNI_GetEnv();
+        if (!LocalReferenceHolder_Init(&refs, env)) {
+            LocalReferenceHolder_Cleanup(&refs);
+            return NULL;
+        }
+
+        // context = SDLActivity.getContext();
+        mid = (*env)->GetStaticMethodID(env, mActivityClass,
+                "getContext","()Landroid/content/Context;");
+        context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid);
+
+        // fileObj = context.getExternalFilesDir();
+        mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),
+                "getExternalFilesDir", "(Ljava/lang/String;)Ljava/io/File;");
+        fileObject = (*env)->CallObjectMethod(env, context, mid, NULL);
+        if (!fileObject) {
+            SDL_SetError("Couldn't get external directory");
+            LocalReferenceHolder_Cleanup(&refs);
+            return NULL;
+        }
+
+        // path = fileObject.getAbsolutePath();
+        mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, fileObject),
+                "getAbsolutePath", "()Ljava/lang/String;");
+        pathString = (jstring)(*env)->CallObjectMethod(env, fileObject, mid);
+
+        path = (*env)->GetStringUTFChars(env, pathString, NULL);
+        s_AndroidExternalFilesPath = SDL_strdup(path);
+        (*env)->ReleaseStringUTFChars(env, pathString, path);
+
+        LocalReferenceHolder_Cleanup(&refs);
+    }
+    return s_AndroidExternalFilesPath;
+}
+
+#endif /* __ANDROID__ */
+
+/* vi: set ts=4 sw=4 expandtab: */
+

+ 1 - 0
Source/ThirdParty/SDL/src/core/android/SDL_android.h

@@ -31,6 +31,7 @@ extern "C" {
 
 
 /* Interface from the SDL library into the Android Java activity */
 /* Interface from the SDL library into the Android Java activity */
 extern SDL_bool Android_JNI_CreateContext(int majorVersion, int minorVersion, int red, int green, int blue, int alpha, int buffer, int depth, int stencil, int buffers, int samples);
 extern SDL_bool Android_JNI_CreateContext(int majorVersion, int minorVersion, int red, int green, int blue, int alpha, int buffer, int depth, int stencil, int buffers, int samples);
+extern SDL_bool Android_JNI_DeleteContext(void);
 extern void Android_JNI_SwapWindow();
 extern void Android_JNI_SwapWindow();
 extern void Android_JNI_SetActivityTitle(const char *title);
 extern void Android_JNI_SetActivityTitle(const char *title);
 extern SDL_bool Android_JNI_GetAccelerometerValues(float values[3]);
 extern SDL_bool Android_JNI_GetAccelerometerValues(float values[3]);

+ 1 - 1
Source/ThirdParty/SDL/src/events/SDL_events.c

@@ -599,7 +599,7 @@ SDL_RegisterEvents(int numevents)
 {
 {
     Uint32 event_base;
     Uint32 event_base;
 
 
-    if (SDL_userevents+numevents <= SDL_LASTEVENT) {
+    if ((numevents > 0) && (SDL_userevents+numevents <= SDL_LASTEVENT)) {
         event_base = SDL_userevents;
         event_base = SDL_userevents;
         SDL_userevents += numevents;
         SDL_userevents += numevents;
     } else {
     } else {

+ 2 - 1
Source/ThirdParty/SDL/src/events/SDL_gesture.c

@@ -398,11 +398,12 @@ static int dollarNormalize(const SDL_DollarPath *path,SDL_FloatPoint *points)
 
 
 static float dollarRecognize(const SDL_DollarPath *path,int *bestTempl,SDL_GestureTouch* touch)
 static float dollarRecognize(const SDL_DollarPath *path,int *bestTempl,SDL_GestureTouch* touch)
 {
 {
-
     SDL_FloatPoint points[DOLLARNPOINTS];
     SDL_FloatPoint points[DOLLARNPOINTS];
     int i;
     int i;
     float bestDiff = 10000;
     float bestDiff = 10000;
 
 
+    SDL_memset(points, 0, sizeof(points));
+
     dollarNormalize(path,points);
     dollarNormalize(path,points);
 
 
     //PrintPath(points);
     //PrintPath(points);

+ 17 - 0
Source/ThirdParty/SDL/src/events/SDL_mouse.c

@@ -364,6 +364,23 @@ SDL_SendMouseWheel(SDL_Window * window, SDL_MouseID mouseID, int x, int y)
 void
 void
 SDL_MouseQuit(void)
 SDL_MouseQuit(void)
 {
 {
+    SDL_Cursor *cursor, *next;
+    SDL_Mouse *mouse = SDL_GetMouse();
+
+    SDL_ShowCursor(1);
+
+    cursor = mouse->cursors;
+    while (cursor) {
+        next = cursor->next;
+        SDL_FreeCursor(cursor);
+        cursor = next;
+    }
+
+    if (mouse->def_cursor && mouse->FreeCursor) {
+        mouse->FreeCursor(mouse->def_cursor);
+    }
+
+    SDL_zerop(mouse);
 }
 }
 
 
 Uint32
 Uint32

+ 2 - 1
Source/ThirdParty/SDL/src/events/SDL_sysevents.h

@@ -24,7 +24,8 @@
 
 
 /* Useful functions and variables from SDL_sysevents.c */
 /* Useful functions and variables from SDL_sysevents.c */
 
 
-#ifdef __BEOS__                 /* The Be event loop runs in a separate thread */
+#if defined(__BEOS__) || defined(__HAIKU__) 
+/* The Be and Haiku event loops run in a separate thread */
 #define MUST_THREAD_EVENTS
 #define MUST_THREAD_EVENTS
 #endif
 #endif
 
 

+ 0 - 41
Source/ThirdParty/SDL/src/events/nds/SDL_ndsgesture.c

@@ -1,41 +0,0 @@
-/*
-  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.
-*/
-
-#include "SDL_config.h"
-
-/* No supported under the NDS because of math operations. */
-
-#include "SDL_events.h"
-#include "../SDL_events_c.h"
-#include "../SDL_gesture_c.h"
-
-int SDL_GestureAddTouch(SDL_Touch* touch)
-{  
-	return 0;
-}
-
-void SDL_GestureProcessEvent(SDL_Event* event)
-{
-	return;
-}
-
-/* vi: set ts=4 sw=4 expandtab: */
-  

+ 3 - 3
Source/ThirdParty/SDL/src/events/scancodes_darwin.h

@@ -91,7 +91,7 @@ static const SDL_Scancode darwin_scancode_table[] = {
     /*  61 */   SDL_SCANCODE_RALT,
     /*  61 */   SDL_SCANCODE_RALT,
     /*  62 */   SDL_SCANCODE_RCTRL,
     /*  62 */   SDL_SCANCODE_RCTRL,
     /*  63 */   SDL_SCANCODE_RGUI, /* fn on portables, acts as a hardware-level modifier already, so we don't generate events for it, also XK_Meta_R */
     /*  63 */   SDL_SCANCODE_RGUI, /* fn on portables, acts as a hardware-level modifier already, so we don't generate events for it, also XK_Meta_R */
-    /*  64 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
+    /*  64 */   SDL_SCANCODE_F17,
     /*  65 */   SDL_SCANCODE_KP_PERIOD,
     /*  65 */   SDL_SCANCODE_KP_PERIOD,
     /*  66 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
     /*  66 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
     /*  67 */   SDL_SCANCODE_KP_MULTIPLY,
     /*  67 */   SDL_SCANCODE_KP_MULTIPLY,
@@ -106,8 +106,8 @@ static const SDL_Scancode darwin_scancode_table[] = {
     /*  76 */   SDL_SCANCODE_KP_ENTER, /* keypad enter on external keyboards, fn-return on portables */
     /*  76 */   SDL_SCANCODE_KP_ENTER, /* keypad enter on external keyboards, fn-return on portables */
     /*  77 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
     /*  77 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
     /*  78 */   SDL_SCANCODE_KP_MINUS,
     /*  78 */   SDL_SCANCODE_KP_MINUS,
-    /*  79 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
-    /*  80 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
+    /*  79 */   SDL_SCANCODE_F18,
+    /*  80 */   SDL_SCANCODE_F19,
     /*  81 */   SDL_SCANCODE_KP_EQUALS,
     /*  81 */   SDL_SCANCODE_KP_EQUALS,
     /*  82 */   SDL_SCANCODE_KP_0,
     /*  82 */   SDL_SCANCODE_KP_0,
     /*  83 */   SDL_SCANCODE_KP_1,
     /*  83 */   SDL_SCANCODE_KP_1,

+ 6 - 6
Source/ThirdParty/SDL/src/events/scancodes_windows.h

@@ -38,18 +38,18 @@ static const SDL_Scancode windows_scancode_table[] =
 	SDL_SCANCODE_APOSTROPHE,	SDL_SCANCODE_GRAVE,			SDL_SCANCODE_LSHIFT,		SDL_SCANCODE_BACKSLASH,		SDL_SCANCODE_Z,			SDL_SCANCODE_X,				SDL_SCANCODE_C,				SDL_SCANCODE_V,			// 2 
 	SDL_SCANCODE_APOSTROPHE,	SDL_SCANCODE_GRAVE,			SDL_SCANCODE_LSHIFT,		SDL_SCANCODE_BACKSLASH,		SDL_SCANCODE_Z,			SDL_SCANCODE_X,				SDL_SCANCODE_C,				SDL_SCANCODE_V,			// 2 
 
 
 	SDL_SCANCODE_B,				SDL_SCANCODE_N,				SDL_SCANCODE_M,				SDL_SCANCODE_COMMA,			SDL_SCANCODE_PERIOD,	SDL_SCANCODE_SLASH,			SDL_SCANCODE_RSHIFT,		SDL_SCANCODE_PRINTSCREEN,// 3
 	SDL_SCANCODE_B,				SDL_SCANCODE_N,				SDL_SCANCODE_M,				SDL_SCANCODE_COMMA,			SDL_SCANCODE_PERIOD,	SDL_SCANCODE_SLASH,			SDL_SCANCODE_RSHIFT,		SDL_SCANCODE_PRINTSCREEN,// 3
-	SDL_SCANCODE_LALT,			SDL_SCANCODE_SPACE,			SDL_SCANCODE_CAPSLOCK,		SDL_SCANCODE_F1,			SDL_SCANCODE_F2,		SDL_SCANCODE_F3,			SDL_SCANCODE_F4,			SDL_SCANCODE_F5,			// 3 
+	SDL_SCANCODE_LALT,			SDL_SCANCODE_SPACE,			SDL_SCANCODE_CAPSLOCK,		SDL_SCANCODE_F1,			SDL_SCANCODE_F2,		SDL_SCANCODE_F3,			SDL_SCANCODE_F4,			SDL_SCANCODE_F5,		// 3 
 
 
 	SDL_SCANCODE_F6,			SDL_SCANCODE_F7,			SDL_SCANCODE_F8,			SDL_SCANCODE_F9,			SDL_SCANCODE_F10,		SDL_SCANCODE_NUMLOCKCLEAR,	SDL_SCANCODE_SCROLLLOCK,	SDL_SCANCODE_HOME,		// 4
 	SDL_SCANCODE_F6,			SDL_SCANCODE_F7,			SDL_SCANCODE_F8,			SDL_SCANCODE_F9,			SDL_SCANCODE_F10,		SDL_SCANCODE_NUMLOCKCLEAR,	SDL_SCANCODE_SCROLLLOCK,	SDL_SCANCODE_HOME,		// 4
 	SDL_SCANCODE_UP,			SDL_SCANCODE_PAGEUP,		SDL_SCANCODE_KP_MINUS,		SDL_SCANCODE_LEFT,			SDL_SCANCODE_KP_5,		SDL_SCANCODE_RIGHT,			SDL_SCANCODE_KP_PLUS,		SDL_SCANCODE_END,		// 4 
 	SDL_SCANCODE_UP,			SDL_SCANCODE_PAGEUP,		SDL_SCANCODE_KP_MINUS,		SDL_SCANCODE_LEFT,			SDL_SCANCODE_KP_5,		SDL_SCANCODE_RIGHT,			SDL_SCANCODE_KP_PLUS,		SDL_SCANCODE_END,		// 4 
 
 
 	SDL_SCANCODE_DOWN,			SDL_SCANCODE_PAGEDOWN,		SDL_SCANCODE_INSERT,		SDL_SCANCODE_DELETE,		SDL_SCANCODE_UNKNOWN,	SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_NONUSBACKSLASH,SDL_SCANCODE_F11,		// 5
 	SDL_SCANCODE_DOWN,			SDL_SCANCODE_PAGEDOWN,		SDL_SCANCODE_INSERT,		SDL_SCANCODE_DELETE,		SDL_SCANCODE_UNKNOWN,	SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_NONUSBACKSLASH,SDL_SCANCODE_F11,		// 5
-	SDL_SCANCODE_F12,			SDL_SCANCODE_PAUSE,			SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_LGUI,			SDL_SCANCODE_RGUI,		SDL_SCANCODE_APPLICATION,	SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		// 5
+	SDL_SCANCODE_F12,			SDL_SCANCODE_PAUSE,			SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_LGUI,			SDL_SCANCODE_RGUI,		SDL_SCANCODE_APPLICATION,	SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,	// 5
 
 
-	SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,	SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		// 6
-	SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,	SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		// 6 
+	SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_F13,		SDL_SCANCODE_F14,			SDL_SCANCODE_F15,			SDL_SCANCODE_F16,		// 6
+	SDL_SCANCODE_F17,			SDL_SCANCODE_F18,			SDL_SCANCODE_F19,			SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,	SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,	// 6 
 	
 	
-	SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,	SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		// 7
-	SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,	SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN		// 7 
+	SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,	SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,	// 7
+	SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,	SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN,		SDL_SCANCODE_UNKNOWN	// 7 
 };
 };
 /* *INDENT-ON* */
 /* *INDENT-ON* */

+ 14 - 14
Source/ThirdParty/SDL/src/events/scancodes_xfree86.h

@@ -141,8 +141,8 @@ static const SDL_Scancode xfree86_scancode_table[] = {
     /*  112 */  SDL_SCANCODE_F15,
     /*  112 */  SDL_SCANCODE_F15,
     /*  113 */  SDL_SCANCODE_F16,
     /*  113 */  SDL_SCANCODE_F16,
     /*  114 */  SDL_SCANCODE_F17,
     /*  114 */  SDL_SCANCODE_F17,
-    /*  115 */	SDL_SCANCODE_UNKNOWN,
-    /*	116 */  SDL_SCANCODE_UNKNOWN, /* is translated to XK_ISO_Level3_Shift by my X server, but I have no keyboard that generates this code, so I don't know what the correct SDL_SCANCODE_* for it is */
+    /*  115 */  SDL_SCANCODE_UNKNOWN,
+    /*  116 */  SDL_SCANCODE_UNKNOWN, /* is translated to XK_ISO_Level3_Shift by my X server, but I have no keyboard that generates this code, so I don't know what the correct SDL_SCANCODE_* for it is */
     /*  117 */  SDL_SCANCODE_UNKNOWN,
     /*  117 */  SDL_SCANCODE_UNKNOWN,
     /*  118 */  SDL_SCANCODE_KP_EQUALS,
     /*  118 */  SDL_SCANCODE_KP_EQUALS,
     /*  119 */  SDL_SCANCODE_UNKNOWN,
     /*  119 */  SDL_SCANCODE_UNKNOWN,
@@ -298,7 +298,7 @@ static const SDL_Scancode xfree86_scancode_table2[] = {
     /* 118 */   SDL_SCANCODE_UNKNOWN,   /* plusminus */
     /* 118 */   SDL_SCANCODE_UNKNOWN,   /* plusminus */
     /* 119 */   SDL_SCANCODE_PAUSE,
     /* 119 */   SDL_SCANCODE_PAUSE,
     /* 120 */   SDL_SCANCODE_UNKNOWN,   /* XF86LaunchA */
     /* 120 */   SDL_SCANCODE_UNKNOWN,   /* XF86LaunchA */
-    /* 121 */   SDL_SCANCODE_UNKNOWN,	/* KP_Decimal */
+    /* 121 */   SDL_SCANCODE_UNKNOWN,   /* KP_Decimal */
     /* 122 */   SDL_SCANCODE_UNKNOWN,   /* Hangul */
     /* 122 */   SDL_SCANCODE_UNKNOWN,   /* Hangul */
     /* 123 */   SDL_SCANCODE_UNKNOWN,   /* Hangul_Hanja */
     /* 123 */   SDL_SCANCODE_UNKNOWN,   /* Hangul_Hanja */
     /* 124 */   SDL_SCANCODE_UNKNOWN,
     /* 124 */   SDL_SCANCODE_UNKNOWN,
@@ -325,15 +325,15 @@ static const SDL_Scancode xfree86_scancode_table2[] = {
     /* 145 */   SDL_SCANCODE_UNKNOWN,   /* XF86Send */
     /* 145 */   SDL_SCANCODE_UNKNOWN,   /* XF86Send */
     /* 146 */   SDL_SCANCODE_UNKNOWN,
     /* 146 */   SDL_SCANCODE_UNKNOWN,
     /* 147 */   SDL_SCANCODE_UNKNOWN,   /* XF86Xfer */
     /* 147 */   SDL_SCANCODE_UNKNOWN,   /* XF86Xfer */
-    /* 148 */   SDL_SCANCODE_UNKNOWN,   /* XF86Launch1 */
-    /* 149 */   SDL_SCANCODE_UNKNOWN,   /* XF86Launch2 */
+    /* 148 */   SDL_SCANCODE_APP1,      /* XF86Launch1 */
+    /* 149 */   SDL_SCANCODE_APP2,      /* XF86Launch2 */
     /* 150 */   SDL_SCANCODE_WWW,
     /* 150 */   SDL_SCANCODE_WWW,
     /* 151 */   SDL_SCANCODE_UNKNOWN,   /* XF86DOS */
     /* 151 */   SDL_SCANCODE_UNKNOWN,   /* XF86DOS */
     /* 152 */   SDL_SCANCODE_UNKNOWN,   /* XF86ScreenSaver */
     /* 152 */   SDL_SCANCODE_UNKNOWN,   /* XF86ScreenSaver */
     /* 153 */   SDL_SCANCODE_UNKNOWN,
     /* 153 */   SDL_SCANCODE_UNKNOWN,
     /* 154 */   SDL_SCANCODE_UNKNOWN,   /* XF86RotateWindows */
     /* 154 */   SDL_SCANCODE_UNKNOWN,   /* XF86RotateWindows */
     /* 155 */   SDL_SCANCODE_MAIL,
     /* 155 */   SDL_SCANCODE_MAIL,
-    /* 156 */   SDL_SCANCODE_UNKNOWN,   /* XF86Favorites */
+    /* 156 */   SDL_SCANCODE_AC_BOOKMARKS,   /* XF86Favorites */
     /* 157 */   SDL_SCANCODE_COMPUTER,
     /* 157 */   SDL_SCANCODE_COMPUTER,
     /* 158 */   SDL_SCANCODE_AC_BACK,
     /* 158 */   SDL_SCANCODE_AC_BACK,
     /* 159 */   SDL_SCANCODE_AC_FORWARD,
     /* 159 */   SDL_SCANCODE_AC_FORWARD,
@@ -348,7 +348,7 @@ static const SDL_Scancode xfree86_scancode_table2[] = {
     /* 168 */   SDL_SCANCODE_UNKNOWN,   /* XF86AudioRewind */
     /* 168 */   SDL_SCANCODE_UNKNOWN,   /* XF86AudioRewind */
     /* 169 */   SDL_SCANCODE_UNKNOWN,   /* XF86Phone */
     /* 169 */   SDL_SCANCODE_UNKNOWN,   /* XF86Phone */
     /* 170 */   SDL_SCANCODE_UNKNOWN,
     /* 170 */   SDL_SCANCODE_UNKNOWN,
-    /* 171 */   SDL_SCANCODE_UNKNOWN,   /* XF86Tools */
+    /* 171 */   SDL_SCANCODE_F13,       /* XF86Tools */
     /* 172 */   SDL_SCANCODE_AC_HOME,
     /* 172 */   SDL_SCANCODE_AC_HOME,
     /* 173 */   SDL_SCANCODE_AC_REFRESH,
     /* 173 */   SDL_SCANCODE_AC_REFRESH,
     /* 174 */   SDL_SCANCODE_UNKNOWN,   /* XF86Close */
     /* 174 */   SDL_SCANCODE_UNKNOWN,   /* XF86Close */
@@ -360,13 +360,13 @@ static const SDL_Scancode xfree86_scancode_table2[] = {
     /* 180 */   SDL_SCANCODE_UNKNOWN,   /* parenright */
     /* 180 */   SDL_SCANCODE_UNKNOWN,   /* parenright */
     /* 181 */   SDL_SCANCODE_UNKNOWN,   /* XF86New */
     /* 181 */   SDL_SCANCODE_UNKNOWN,   /* XF86New */
     /* 182 */   SDL_SCANCODE_AGAIN,
     /* 182 */   SDL_SCANCODE_AGAIN,
-    /* 183 */   SDL_SCANCODE_UNKNOWN,   /* XF86Tools */
-    /* 184 */   SDL_SCANCODE_UNKNOWN,   /* XF86Launch5 */
-    /* 185 */   SDL_SCANCODE_UNKNOWN,   /* XF86MenuKB */
-    /* 186 */   SDL_SCANCODE_UNKNOWN,
-    /* 187 */   SDL_SCANCODE_UNKNOWN,
-    /* 188 */   SDL_SCANCODE_UNKNOWN,
-    /* 189 */   SDL_SCANCODE_UNKNOWN,
+    /* 183 */   SDL_SCANCODE_F13,       /* XF86Tools */
+    /* 184 */   SDL_SCANCODE_F14,       /* XF86Launch5 */
+    /* 185 */   SDL_SCANCODE_F15,       /* XF86Launch6 */
+    /* 186 */   SDL_SCANCODE_F16,       /* XF86Launch7 */
+    /* 187 */   SDL_SCANCODE_F17,       /* XF86Launch8 */
+    /* 188 */   SDL_SCANCODE_F18,       /* XF86Launch9 */
+    /* 189 */   SDL_SCANCODE_F19,       /* null keysym */
     /* 190 */   SDL_SCANCODE_UNKNOWN,
     /* 190 */   SDL_SCANCODE_UNKNOWN,
     /* 191 */   SDL_SCANCODE_UNKNOWN,
     /* 191 */   SDL_SCANCODE_UNKNOWN,
     /* 192 */   SDL_SCANCODE_UNKNOWN,   /* XF86TouchpadToggle */
     /* 192 */   SDL_SCANCODE_UNKNOWN,   /* XF86TouchpadToggle */

+ 71 - 35
Source/ThirdParty/SDL/src/haptic/SDL_haptic.c

@@ -23,7 +23,7 @@
 #include "SDL_syshaptic.h"
 #include "SDL_syshaptic.h"
 #include "SDL_haptic_c.h"
 #include "SDL_haptic_c.h"
 #include "../joystick/SDL_joystick_c.h" /* For SDL_PrivateJoystickValid */
 #include "../joystick/SDL_joystick_c.h" /* For SDL_PrivateJoystickValid */
-
+#include "SDL_assert.h"
 
 
 Uint8 SDL_numhaptics = 0;
 Uint8 SDL_numhaptics = 0;
 SDL_Haptic **SDL_haptics = NULL;
 SDL_Haptic **SDL_haptics = NULL;
@@ -149,18 +149,23 @@ SDL_HapticOpen(int device_index)
         return NULL;
         return NULL;
     }
     }
 
 
+    /* Add haptic to list */
+    for (i = 0; SDL_haptics[i]; i++)
+        /* Skip to next haptic */ ;
+    if (i >= SDL_numhaptics) {
+        SDL_free(haptic);
+        SDL_SetError("Haptic: Trying to add device past the number originally detected");
+        return NULL;
+    }
+    SDL_haptics[i] = haptic;
+    ++haptic->ref_count;
+
     /* Disable autocenter and set gain to max. */
     /* Disable autocenter and set gain to max. */
     if (haptic->supported & SDL_HAPTIC_GAIN)
     if (haptic->supported & SDL_HAPTIC_GAIN)
         SDL_HapticSetGain(haptic, 100);
         SDL_HapticSetGain(haptic, 100);
     if (haptic->supported & SDL_HAPTIC_AUTOCENTER)
     if (haptic->supported & SDL_HAPTIC_AUTOCENTER)
         SDL_HapticSetAutocenter(haptic, 0);
         SDL_HapticSetAutocenter(haptic, 0);
 
 
-    /* Add haptic to list */
-    ++haptic->ref_count;
-    for (i = 0; SDL_haptics[i]; i++)
-        /* Skip to next haptic */ ;
-    SDL_haptics[i] = haptic;
-
     return haptic;
     return haptic;
 }
 }
 
 
@@ -173,6 +178,13 @@ SDL_HapticOpened(int device_index)
 {
 {
     int i, opened;
     int i, opened;
 
 
+    /* Make sure it's valid. */
+    if ((device_index < 0) || (device_index >= SDL_numhaptics)) {
+        SDL_SetError("Haptic: There are %d haptic devices available",
+                     SDL_numhaptics);
+        return 0;
+    }
+
     opened = 0;
     opened = 0;
     for (i = 0; SDL_haptics[i]; i++) {
     for (i = 0; SDL_haptics[i]; i++) {
         if (SDL_haptics[i]->index == (Uint8) device_index) {
         if (SDL_haptics[i]->index == (Uint8) device_index) {
@@ -262,6 +274,13 @@ SDL_HapticOpenFromJoystick(SDL_Joystick * joystick)
     int i;
     int i;
     SDL_Haptic *haptic;
     SDL_Haptic *haptic;
 
 
+    /* Make sure there is room. */
+    if (SDL_numhaptics <= 0) {
+        SDL_SetError("Haptic: There are %d haptic devices available",
+                     SDL_numhaptics);
+        return NULL;
+    }
+
     /* Must be a valid joystick */
     /* Must be a valid joystick */
     if (!SDL_PrivateJoystickValid(joystick)) {
     if (!SDL_PrivateJoystickValid(joystick)) {
         SDL_SetError("Haptic: Joystick isn't valid.");
         SDL_SetError("Haptic: Joystick isn't valid.");
@@ -299,10 +318,15 @@ SDL_HapticOpenFromJoystick(SDL_Joystick * joystick)
     }
     }
 
 
     /* Add haptic to list */
     /* Add haptic to list */
-    ++haptic->ref_count;
     for (i = 0; SDL_haptics[i]; i++)
     for (i = 0; SDL_haptics[i]; i++)
         /* Skip to next haptic */ ;
         /* Skip to next haptic */ ;
+    if (i >= SDL_numhaptics) {
+        SDL_free(haptic);
+        SDL_SetError("Haptic: Trying to add device past the number originally detected");
+        return NULL;
+    }
     SDL_haptics[i] = haptic;
     SDL_haptics[i] = haptic;
+    ++haptic->ref_count;
 
 
     return haptic;
     return haptic;
 }
 }
@@ -699,32 +723,18 @@ SDL_HapticStopAll(SDL_Haptic * haptic)
     return SDL_SYS_HapticStopAll(haptic);
     return SDL_SYS_HapticStopAll(haptic);
 }
 }
 
 
-static void
-SDL_HapticRumbleCreate(SDL_HapticEffect * efx)
-{
-   SDL_memset(efx, 0, sizeof(SDL_HapticEffect));
-   efx->type = SDL_HAPTIC_SINE;
-   efx->periodic.period = 1000;
-   efx->periodic.magnitude = 0x4000;
-   efx->periodic.length = 5000;
-   efx->periodic.attack_length = 0;
-   efx->periodic.fade_length = 0;
-}
-
 /*
 /*
  * Checks to see if rumble is supported.
  * Checks to see if rumble is supported.
  */
  */
 int
 int
 SDL_HapticRumbleSupported(SDL_Haptic * haptic)
 SDL_HapticRumbleSupported(SDL_Haptic * haptic)
 {
 {
-    SDL_HapticEffect efx;
-
     if (!ValidHaptic(haptic)) {
     if (!ValidHaptic(haptic)) {
         return -1;
         return -1;
     }
     }
 
 
-    SDL_HapticRumbleCreate(&efx);
-    return SDL_HapticEffectSupported(haptic, &efx);
+    /* Most things can use SINE, but XInput only has LEFTRIGHT. */
+    return ((haptic->supported & (SDL_HAPTIC_SINE|SDL_HAPTIC_LEFTRIGHT)) != 0);
 }
 }
 
 
 /*
 /*
@@ -733,6 +743,8 @@ SDL_HapticRumbleSupported(SDL_Haptic * haptic)
 int
 int
 SDL_HapticRumbleInit(SDL_Haptic * haptic)
 SDL_HapticRumbleInit(SDL_Haptic * haptic)
 {
 {
+    SDL_HapticEffect *efx = &haptic->rumble_effect;
+
     if (!ValidHaptic(haptic)) {
     if (!ValidHaptic(haptic)) {
         return -1;
         return -1;
     }
     }
@@ -742,8 +754,23 @@ SDL_HapticRumbleInit(SDL_Haptic * haptic)
         return 0;
         return 0;
     }
     }
 
 
-    /* Copy over. */
-    SDL_HapticRumbleCreate(&haptic->rumble_effect);
+    SDL_zerop(efx);
+    if (haptic->supported & SDL_HAPTIC_SINE) {
+        efx->type = SDL_HAPTIC_SINE;
+        efx->periodic.period = 1000;
+        efx->periodic.magnitude = 0x4000;
+        efx->periodic.length = 5000;
+        efx->periodic.attack_length = 0;
+        efx->periodic.fade_length = 0;
+    } else if (haptic->supported & SDL_HAPTIC_LEFTRIGHT) {  /* XInput? */
+        efx->type = SDL_HAPTIC_LEFTRIGHT;
+        efx->leftright.length = 5000;
+        efx->leftright.large_magnitude = 0x4000;
+        efx->leftright.small_magnitude = 0x4000;
+    } else {
+        return SDL_SetError("Device doesn't support rumble");
+    }
+
     haptic->rumble_id = SDL_HapticNewEffect(haptic, &haptic->rumble_effect);
     haptic->rumble_id = SDL_HapticNewEffect(haptic, &haptic->rumble_effect);
     if (haptic->rumble_id >= 0) {
     if (haptic->rumble_id >= 0) {
         return 0;
         return 0;
@@ -757,7 +784,8 @@ SDL_HapticRumbleInit(SDL_Haptic * haptic)
 int
 int
 SDL_HapticRumblePlay(SDL_Haptic * haptic, float strength, Uint32 length)
 SDL_HapticRumblePlay(SDL_Haptic * haptic, float strength, Uint32 length)
 {
 {
-    SDL_HapticPeriodic *efx;
+    SDL_HapticEffect *efx;
+    Sint16 magnitude;
 
 
     if (!ValidHaptic(haptic)) {
     if (!ValidHaptic(haptic)) {
         return -1;
         return -1;
@@ -770,16 +798,25 @@ SDL_HapticRumblePlay(SDL_Haptic * haptic, float strength, Uint32 length)
     /* Clamp strength. */
     /* Clamp strength. */
     if (strength > 1.0f) {
     if (strength > 1.0f) {
         strength = 1.0f;
         strength = 1.0f;
-    }
-    else if (strength < 0.0f) {
+    } else if (strength < 0.0f) {
         strength = 0.0f;
         strength = 0.0f;
     }
     }
+    magnitude = (Sint16)(32767.0f*strength);
 
 
-    /* New effect. */
-    efx = &haptic->rumble_effect.periodic;
-    efx->magnitude = (Sint16)(32767.0f*strength);
-    efx->length = length;
-    SDL_HapticUpdateEffect(haptic, haptic->rumble_id, &haptic->rumble_effect);
+    efx = &haptic->rumble_effect;
+    if (efx->type == SDL_HAPTIC_SINE) {
+        efx->periodic.magnitude = magnitude;
+        efx->periodic.length = length;
+    } else if (efx->type == SDL_HAPTIC_LEFTRIGHT) {
+        efx->leftright.small_magnitude = efx->leftright.large_magnitude = magnitude;
+        efx->leftright.length = length;
+    } else {
+        SDL_assert(0 && "This should have been caught elsewhere");
+    }
+
+    if (SDL_HapticUpdateEffect(haptic, haptic->rumble_id, &haptic->rumble_effect) < 0) {
+        return -1;
+    }
 
 
     return SDL_HapticRunEffect(haptic, haptic->rumble_id, 1);
     return SDL_HapticRunEffect(haptic, haptic->rumble_id, 1);
 }
 }
@@ -801,4 +838,3 @@ SDL_HapticRumbleStop(SDL_Haptic * haptic)
     return SDL_HapticStopEffect(haptic, haptic->rumble_id);
     return SDL_HapticStopEffect(haptic, haptic->rumble_id);
 }
 }
 
 
-

+ 7 - 4
Source/ThirdParty/SDL/src/haptic/darwin/SDL_syshaptic.c

@@ -342,7 +342,8 @@ GetSupportedFeatures(SDL_Haptic * haptic)
     /* Test for effects. */
     /* Test for effects. */
     FF_TEST(FFCAP_ET_CONSTANTFORCE, SDL_HAPTIC_CONSTANT);
     FF_TEST(FFCAP_ET_CONSTANTFORCE, SDL_HAPTIC_CONSTANT);
     FF_TEST(FFCAP_ET_RAMPFORCE, SDL_HAPTIC_RAMP);
     FF_TEST(FFCAP_ET_RAMPFORCE, SDL_HAPTIC_RAMP);
-    FF_TEST(FFCAP_ET_SQUARE, SDL_HAPTIC_SQUARE);
+    /* !!! FIXME: put this back when we have more bits in 2.1 */
+    /*FF_TEST(FFCAP_ET_SQUARE, SDL_HAPTIC_SQUARE);*/
     FF_TEST(FFCAP_ET_SINE, SDL_HAPTIC_SINE);
     FF_TEST(FFCAP_ET_SINE, SDL_HAPTIC_SINE);
     FF_TEST(FFCAP_ET_TRIANGLE, SDL_HAPTIC_TRIANGLE);
     FF_TEST(FFCAP_ET_TRIANGLE, SDL_HAPTIC_TRIANGLE);
     FF_TEST(FFCAP_ET_SAWTOOTHUP, SDL_HAPTIC_SAWTOOTHUP);
     FF_TEST(FFCAP_ET_SAWTOOTHUP, SDL_HAPTIC_SAWTOOTHUP);
@@ -750,7 +751,8 @@ SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest,
         break;
         break;
 
 
     case SDL_HAPTIC_SINE:
     case SDL_HAPTIC_SINE:
-    case SDL_HAPTIC_SQUARE:
+    /* !!! FIXME: put this back when we have more bits in 2.1 */
+    /*case SDL_HAPTIC_SQUARE:*/
     case SDL_HAPTIC_TRIANGLE:
     case SDL_HAPTIC_TRIANGLE:
     case SDL_HAPTIC_SAWTOOTHUP:
     case SDL_HAPTIC_SAWTOOTHUP:
     case SDL_HAPTIC_SAWTOOTHDOWN:
     case SDL_HAPTIC_SAWTOOTHDOWN:
@@ -978,8 +980,9 @@ SDL_SYS_HapticEffectType(Uint16 type)
     case SDL_HAPTIC_RAMP:
     case SDL_HAPTIC_RAMP:
         return kFFEffectType_RampForce_ID;
         return kFFEffectType_RampForce_ID;
 
 
-    case SDL_HAPTIC_SQUARE:
-        return kFFEffectType_Square_ID;
+    /* !!! FIXME: put this back when we have more bits in 2.1 */
+    /*case SDL_HAPTIC_SQUARE:
+        return kFFEffectType_Square_ID;*/
 
 
     case SDL_HAPTIC_SINE:
     case SDL_HAPTIC_SINE:
         return kFFEffectType_Sine_ID;
         return kFFEffectType_Sine_ID;

+ 13 - 28
Source/ThirdParty/SDL/src/haptic/dummy/SDL_syshaptic.c

@@ -29,8 +29,7 @@
 static int
 static int
 SDL_SYS_LogicError(void)
 SDL_SYS_LogicError(void)
 {
 {
-    SDL_SetError("Logic error: No haptic devices available.");
-    return 0;
+    return SDL_SetError("Logic error: No haptic devices available.");
 }
 }
 
 
 
 
@@ -52,8 +51,7 @@ SDL_SYS_HapticName(int index)
 int
 int
 SDL_SYS_HapticOpen(SDL_Haptic * haptic)
 SDL_SYS_HapticOpen(SDL_Haptic * haptic)
 {
 {
-    SDL_SYS_LogicError();
-    return -1;
+    return SDL_SYS_LogicError();
 }
 }
 
 
 
 
@@ -74,8 +72,7 @@ SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick)
 int
 int
 SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
 SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
 {
 {
-    SDL_SYS_LogicError();
-    return -1;
+    return SDL_SYS_LogicError();
 }
 }
 
 
 
 
@@ -104,8 +101,7 @@ int
 SDL_SYS_HapticNewEffect(SDL_Haptic * haptic,
 SDL_SYS_HapticNewEffect(SDL_Haptic * haptic,
                         struct haptic_effect *effect, SDL_HapticEffect * base)
                         struct haptic_effect *effect, SDL_HapticEffect * base)
 {
 {
-    SDL_SYS_LogicError();
-    return -1;
+    return SDL_SYS_LogicError();
 }
 }
 
 
 
 
@@ -114,8 +110,7 @@ SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic,
                            struct haptic_effect *effect,
                            struct haptic_effect *effect,
                            SDL_HapticEffect * data)
                            SDL_HapticEffect * data)
 {
 {
-    SDL_SYS_LogicError();
-    return -1;
+    return SDL_SYS_LogicError();
 }
 }
 
 
 
 
@@ -123,16 +118,14 @@ int
 SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
 SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
                         Uint32 iterations)
                         Uint32 iterations)
 {
 {
-    SDL_SYS_LogicError();
-    return -1;
+    return SDL_SYS_LogicError();
 }
 }
 
 
 
 
 int
 int
 SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
 SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
 {
 {
-    SDL_SYS_LogicError();
-    return -1;
+    return SDL_SYS_LogicError();
 }
 }
 
 
 
 
@@ -148,47 +141,39 @@ int
 SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic,
 SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic,
                               struct haptic_effect *effect)
                               struct haptic_effect *effect)
 {
 {
-    SDL_SYS_LogicError();
-    return -1;
+    return SDL_SYS_LogicError();
 }
 }
 
 
 
 
 int
 int
 SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain)
 SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain)
 {
 {
-    SDL_SYS_LogicError();
-    return -1;
+    return SDL_SYS_LogicError();
 }
 }
 
 
 
 
 int
 int
 SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
 SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
 {
 {
-    SDL_SYS_LogicError();
-    return -1;
+    return SDL_SYS_LogicError();
 }
 }
 
 
 int
 int
 SDL_SYS_HapticPause(SDL_Haptic * haptic)
 SDL_SYS_HapticPause(SDL_Haptic * haptic)
 {
 {
-    SDL_SYS_LogicError();
-    return -1;
+    return SDL_SYS_LogicError();
 }
 }
 
 
 int
 int
 SDL_SYS_HapticUnpause(SDL_Haptic * haptic)
 SDL_SYS_HapticUnpause(SDL_Haptic * haptic)
 {
 {
-    SDL_SYS_LogicError();
-    return -1;
+    return SDL_SYS_LogicError();
 }
 }
 
 
 int
 int
 SDL_SYS_HapticStopAll(SDL_Haptic * haptic)
 SDL_SYS_HapticStopAll(SDL_Haptic * haptic)
 {
 {
-    SDL_SYS_LogicError();
-    return -1;
+    return SDL_SYS_LogicError();
 }
 }
 
 
-
-
 #endif /* SDL_HAPTIC_DUMMY || SDL_HAPTIC_DISABLED */
 #endif /* SDL_HAPTIC_DUMMY || SDL_HAPTIC_DISABLED */

+ 30 - 4
Source/ThirdParty/SDL/src/haptic/linux/SDL_syshaptic.c

@@ -99,7 +99,8 @@ EV_IsHaptic(int fd)
     /* Convert supported features to SDL_HAPTIC platform-neutral features. */
     /* Convert supported features to SDL_HAPTIC platform-neutral features. */
     EV_TEST(FF_CONSTANT, SDL_HAPTIC_CONSTANT);
     EV_TEST(FF_CONSTANT, SDL_HAPTIC_CONSTANT);
     EV_TEST(FF_SINE, SDL_HAPTIC_SINE);
     EV_TEST(FF_SINE, SDL_HAPTIC_SINE);
-    EV_TEST(FF_SQUARE, SDL_HAPTIC_SQUARE);
+    /* !!! FIXME: put this back when we have more bits in 2.1 */
+    /*EV_TEST(FF_SQUARE, SDL_HAPTIC_SQUARE);*/
     EV_TEST(FF_TRIANGLE, SDL_HAPTIC_TRIANGLE);
     EV_TEST(FF_TRIANGLE, SDL_HAPTIC_TRIANGLE);
     EV_TEST(FF_SAW_UP, SDL_HAPTIC_SAWTOOTHUP);
     EV_TEST(FF_SAW_UP, SDL_HAPTIC_SAWTOOTHUP);
     EV_TEST(FF_SAW_DOWN, SDL_HAPTIC_SAWTOOTHDOWN);
     EV_TEST(FF_SAW_DOWN, SDL_HAPTIC_SAWTOOTHDOWN);
@@ -111,6 +112,7 @@ EV_IsHaptic(int fd)
     EV_TEST(FF_CUSTOM, SDL_HAPTIC_CUSTOM);
     EV_TEST(FF_CUSTOM, SDL_HAPTIC_CUSTOM);
     EV_TEST(FF_GAIN, SDL_HAPTIC_GAIN);
     EV_TEST(FF_GAIN, SDL_HAPTIC_GAIN);
     EV_TEST(FF_AUTOCENTER, SDL_HAPTIC_AUTOCENTER);
     EV_TEST(FF_AUTOCENTER, SDL_HAPTIC_AUTOCENTER);
+    EV_TEST(FF_RUMBLE, SDL_HAPTIC_LEFTRIGHT);
 
 
     /* Return what it supports. */
     /* Return what it supports. */
     return ret;
     return ret;
@@ -559,6 +561,7 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src)
     SDL_HapticPeriodic *periodic;
     SDL_HapticPeriodic *periodic;
     SDL_HapticCondition *condition;
     SDL_HapticCondition *condition;
     SDL_HapticRamp *ramp;
     SDL_HapticRamp *ramp;
+    SDL_HapticLeftRight *leftright;
 
 
     /* Clear up */
     /* Clear up */
     SDL_memset(dest, 0, sizeof(struct ff_effect));
     SDL_memset(dest, 0, sizeof(struct ff_effect));
@@ -596,7 +599,8 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src)
         break;
         break;
 
 
     case SDL_HAPTIC_SINE:
     case SDL_HAPTIC_SINE:
-    case SDL_HAPTIC_SQUARE:
+    /* !!! FIXME: put this back when we have more bits in 2.1 */
+    /*case SDL_HAPTIC_SQUARE:*/
     case SDL_HAPTIC_TRIANGLE:
     case SDL_HAPTIC_TRIANGLE:
     case SDL_HAPTIC_SAWTOOTHUP:
     case SDL_HAPTIC_SAWTOOTHUP:
     case SDL_HAPTIC_SAWTOOTHDOWN:
     case SDL_HAPTIC_SAWTOOTHDOWN:
@@ -620,8 +624,9 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src)
         /* Periodic */
         /* Periodic */
         if (periodic->type == SDL_HAPTIC_SINE)
         if (periodic->type == SDL_HAPTIC_SINE)
             dest->u.periodic.waveform = FF_SINE;
             dest->u.periodic.waveform = FF_SINE;
-        else if (periodic->type == SDL_HAPTIC_SQUARE)
-            dest->u.periodic.waveform = FF_SQUARE;
+        /* !!! FIXME: put this back when we have more bits in 2.1 */
+        /*else if (periodic->type == SDL_HAPTIC_SQUARE)
+            dest->u.periodic.waveform = FF_SQUARE;*/
         else if (periodic->type == SDL_HAPTIC_TRIANGLE)
         else if (periodic->type == SDL_HAPTIC_TRIANGLE)
             dest->u.periodic.waveform = FF_TRIANGLE;
             dest->u.periodic.waveform = FF_TRIANGLE;
         else if (periodic->type == SDL_HAPTIC_SAWTOOTHUP)
         else if (periodic->type == SDL_HAPTIC_SAWTOOTHUP)
@@ -725,6 +730,27 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src)
 
 
         break;
         break;
 
 
+    case SDL_HAPTIC_LEFTRIGHT:
+        leftright = &src->leftright;
+
+        /* Header */
+        dest->type = FF_RUMBLE;
+        dest->direction = 0;
+
+        /* Replay */
+        dest->replay.length = (leftright->length == SDL_HAPTIC_INFINITY) ?
+            0 : CLAMP(leftright->length);
+
+        /* Trigger */
+        dest->trigger.button = 0;
+        dest->trigger.interval = 0;
+
+        /* Rumble */
+        dest->u.rumble.strong_magnitude = leftright->large_magnitude;
+        dest->u.rumble.weak_magnitude = leftright->small_magnitude;
+
+	break;
+
 
 
     default:
     default:
         return SDL_SetError("Haptic: Unknown effect type.");
         return SDL_SetError("Haptic: Unknown effect type.");

+ 0 - 330
Source/ThirdParty/SDL/src/haptic/nds/SDL_syshaptic.c

@@ -1,330 +0,0 @@
-/*
-  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.
-*/
-#include "SDL_config.h"
-
-#ifdef SDL_HAPTIC_NDS
-
-#include "SDL_haptic.h"
-#include "../SDL_syshaptic.h"
-#include "SDL_joystick.h"
-#include <nds/memory.h>
-#include <nds/arm9/rumble.h>
-
-#define MAX_HAPTICS  1
-/* right now only the ezf3in1 (and maybe official rumble pak) are supported
-   and there can only be one of those in at a time (in GBA slot.) */
-
-static SDL_Haptic *nds_haptic = NULL;
-
-struct haptic_hwdata
-{
-    enum
-    { NONE, OFFICIAL, EZF3IN1 } type;
-    int pos;
-};
-
-
-void
-NDS_EZF_OpenNorWrite() 
-{
-    GBA_BUS[0x0FF0000] = 0xD200;
-    GBA_BUS[0x0000000] = 0x1500;
-    GBA_BUS[0x0010000] = 0xD200;
-    GBA_BUS[0x0020000] = 0x1500;
-    GBA_BUS[0x0E20000] = 0x1500;
-    GBA_BUS[0x0FE0000] = 0x1500;
-}
-
-void
-NDS_EZF_CloseNorWrite() 
-{
-    GBA_BUS[0x0FF0000] = 0xD200;
-    GBA_BUS[0x0000000] = 0x1500;
-    GBA_BUS[0x0010000] = 0xD200;
-    GBA_BUS[0x0020000] = 0x1500;
-    GBA_BUS[0x0E20000] = 0xD200;
-    GBA_BUS[0x0FE0000] = 0x1500;
-}
-
-void
-NDS_EZF_ChipReset()
-{
-    GBA_BUS[0x0000] = 0x00F0;
-    GBA_BUS[0x1000] = 0x00F0;
-} uint32 NDS_EZF_IsPresent() 
-{
-    vuint16 id1, id2;
-
-    NDS_EZF_OpenNorWrite();
-
-    GBA_BUS[0x0555] = 0x00AA;
-    GBA_BUS[0x02AA] = 0x0055;
-    GBA_BUS[0x0555] = 0x0090;
-    GBA_BUS[0x1555] = 0x00AA;
-    GBA_BUS[0x12AA] = 0x0055;
-    GBA_BUS[0x1555] = 0x0090;
-    id1 = GBA_BUS[0x0001];
-    id2 = GBA_BUS[0x1001];
-    if ((id1 != 0x227E) || (id2 != 0x227E)) {
-        NDS_EZF_CloseNorWrite();
-        return 0;
-    }
-    id1 = GBA_BUS[0x000E];
-    id2 = GBA_BUS[0x100E];
-
-    NDS_EZF_CloseNorWrite();
-    if (id1 == 0x2218 && id2 == 0x2218) {
-        return 1;
-    }
-    return 0;
-}
-void
-NDS_EZF_SetShake(u8 pos) 
-{
-    u16 data = ((pos % 3) | 0x00F0);
-    GBA_BUS[0x0FF0000] = 0xD200;
-    GBA_BUS[0x0000000] = 0x1500;
-    GBA_BUS[0x0010000] = 0xD200;
-    GBA_BUS[0x0020000] = 0x1500;
-    GBA_BUS[0x0F10000] = data;
-    GBA_BUS[0x0FE0000] = 0x1500;
-
-    GBA_BUS[0] = 0x0000;        /* write any value for vibration. */
-    GBA_BUS[0] = 0x0002;
-}
-
-static int
-SDL_SYS_LogicError(void)
-{
-    SDL_SetError("Logic error: No haptic devices available.");
-    return 0;
-}
-
-
-int
-SDL_SYS_HapticInit(void)
-{
-    int ret = 0;
-    if (isRumbleInserted()) {
-        /* official rumble pak is present. */
-        ret = 1;
-        printf("debug: haptic present: nintendo\n");
-    } else if (NDS_EZF_IsPresent()) {
-        /* ezflash 3-in-1 pak is present. */
-        ret = 1;
-        printf("debug: haptic present: ezf3in1\n");
-        NDS_EZF_ChipReset();
-    } else {
-        printf("debug: no haptic found\n");
-    }
-
-    return ret;
-}
-
-
-const char *
-SDL_SYS_HapticName(int index)
-{
-    if (nds_haptic) {
-        switch (nds_haptic->hwdata->type) {
-        case OFFICIAL:
-            return "Nintendo DS Rumble Pak";
-        case EZF3IN1:
-            return "EZFlash 3-in-1 Rumble";
-        default:
-            return NULL;
-        }
-    }
-    return NULL;
-}
-
-
-int
-SDL_SYS_HapticOpen(SDL_Haptic * haptic)
-{
-    if (!haptic) {
-        return -1;
-    }
-
-    haptic->hwdata = SDL_malloc(sizeof(struct haptic_hwdata));
-    if (!haptic->hwdata) {
-        SDL_OutOfMemory();
-        return -1;
-    }
-    nds_haptic = haptic;
-
-    haptic->supported = SDL_HAPTIC_CONSTANT;
-
-    /* determine what is here, if anything */
-    haptic->hwdata->type = NONE;
-    if (isRumbleInserted()) {
-        /* official rumble pak is present. */
-        haptic->hwdata->type = OFFICIAL;
-    } else if (NDS_EZF_IsPresent()) {
-        /* ezflash 3-in-1 pak is present. */
-        haptic->hwdata->type = EZF3IN1;
-        NDS_EZF_ChipReset();
-    } else {
-        /* no haptic present */
-        SDL_SYS_LogicError();
-        return -1;
-    }
-
-    return 0;
-}
-
-
-int
-SDL_SYS_HapticMouse(void)
-{
-    return -1;
-}
-
-
-int
-SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick)
-{
-    return 0;
-}
-
-
-int
-SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
-{
-    /*SDL_SYS_LogicError(); */
-    return -1;
-}
-
-
-int
-SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
-{
-    return 0;
-}
-
-
-void
-SDL_SYS_HapticClose(SDL_Haptic * haptic)
-{
-    return;
-}
-
-
-void
-SDL_SYS_HapticQuit(void)
-{
-    return;
-}
-
-
-int
-SDL_SYS_HapticNewEffect(SDL_Haptic * haptic,
-                        struct haptic_effect *effect, SDL_HapticEffect * base)
-{
-    SDL_SYS_LogicError();
-    return -1;
-}
-
-
-int
-SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic,
-                           struct haptic_effect *effect,
-                           SDL_HapticEffect * data)
-{
-    SDL_SYS_LogicError();
-    return -1;
-}
-
-
-int
-SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
-                        Uint32 iterations)
-{
-    SDL_SYS_LogicError();
-    return -1;
-}
-
-
-int
-SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
-{
-    SDL_SYS_LogicError();
-    return -1;
-}
-
-
-void
-SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
-{
-    SDL_SYS_LogicError();
-    return;
-}
-
-
-int
-SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic,
-                              struct haptic_effect *effect)
-{
-    SDL_SYS_LogicError();
-    return -1;
-}
-
-
-int
-SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain)
-{
-    SDL_SYS_LogicError();
-    return -1;
-}
-
-
-int
-SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
-{
-    SDL_SYS_LogicError();
-    return -1;
-}
-
-int
-SDL_SYS_HapticPause(SDL_Haptic * haptic)
-{
-    SDL_SYS_LogicError();
-    return -1;
-}
-
-int
-SDL_SYS_HapticUnpause(SDL_Haptic * haptic)
-{
-    SDL_SYS_LogicError();
-    return -1;
-}
-
-int
-SDL_SYS_HapticStopAll(SDL_Haptic * haptic)
-{
-    SDL_SYS_LogicError();
-    return -1;
-}
-
-
-
-#endif /* SDL_HAPTIC_NDS */
-/* vi: set ts=4 sw=4 expandtab: */

+ 105 - 25
Source/ThirdParty/SDL/src/haptic/windows/SDL_syshaptic.c

@@ -23,6 +23,9 @@
 #ifdef SDL_HAPTIC_DINPUT
 #ifdef SDL_HAPTIC_DINPUT
 
 
 #include "SDL_assert.h"
 #include "SDL_assert.h"
+#include "SDL_thread.h"
+#include "SDL_mutex.h"
+#include "SDL_timer.h"
 #include "SDL_hints.h"
 #include "SDL_hints.h"
 #include "SDL_haptic.h"
 #include "SDL_haptic.h"
 #include "../SDL_syshaptic.h"
 #include "../SDL_syshaptic.h"
@@ -56,6 +59,10 @@ struct haptic_hwdata
     SDL_bool is_joystick;       /* Device is loaded as joystick. */
     SDL_bool is_joystick;       /* Device is loaded as joystick. */
     Uint8 bXInputHaptic; /* Supports force feedback via XInput. */
     Uint8 bXInputHaptic; /* Supports force feedback via XInput. */
     Uint8 userid; /* XInput userid index for this joystick */
     Uint8 userid; /* XInput userid index for this joystick */
+    SDL_Thread *thread;
+    SDL_mutex *mutex;
+    volatile Uint32 stopTicks;
+    volatile int stopThread;
 };
 };
 
 
 
 
@@ -102,6 +109,8 @@ static int SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest,
                               SDL_HapticEffect * src);
                               SDL_HapticEffect * src);
 static void SDL_SYS_HapticFreeDIEFFECT(DIEFFECT * effect, int type);
 static void SDL_SYS_HapticFreeDIEFFECT(DIEFFECT * effect, int type);
 static REFGUID SDL_SYS_HapticEffectType(SDL_HapticEffect * effect);
 static REFGUID SDL_SYS_HapticEffectType(SDL_HapticEffect * effect);
+static int SDLCALL SDL_RunXInputHaptic(void *arg);
+
 /* Callbacks. */
 /* Callbacks. */
 static BOOL CALLBACK EnumHapticsCallback(const DIDEVICEINSTANCE *
 static BOOL CALLBACK EnumHapticsCallback(const DIDEVICEINSTANCE *
                                          pdidInstance, VOID * pContext);
                                          pdidInstance, VOID * pContext);
@@ -294,7 +303,8 @@ DI_EffectCallback(LPCDIEFFECTINFO pei, LPVOID pv)
     EFFECT_TEST(GUID_ConstantForce, SDL_HAPTIC_CONSTANT);
     EFFECT_TEST(GUID_ConstantForce, SDL_HAPTIC_CONSTANT);
     EFFECT_TEST(GUID_CustomForce, SDL_HAPTIC_CUSTOM);
     EFFECT_TEST(GUID_CustomForce, SDL_HAPTIC_CUSTOM);
     EFFECT_TEST(GUID_Sine, SDL_HAPTIC_SINE);
     EFFECT_TEST(GUID_Sine, SDL_HAPTIC_SINE);
-    EFFECT_TEST(GUID_Square, SDL_HAPTIC_SQUARE);
+    /* !!! FIXME: put this back when we have more bits in 2.1 */
+    /*EFFECT_TEST(GUID_Square, SDL_HAPTIC_SQUARE);*/
     EFFECT_TEST(GUID_Triangle, SDL_HAPTIC_TRIANGLE);
     EFFECT_TEST(GUID_Triangle, SDL_HAPTIC_TRIANGLE);
     EFFECT_TEST(GUID_SawtoothUp, SDL_HAPTIC_SAWTOOTHUP);
     EFFECT_TEST(GUID_SawtoothUp, SDL_HAPTIC_SAWTOOTHUP);
     EFFECT_TEST(GUID_SawtoothDown, SDL_HAPTIC_SAWTOOTHDOWN);
     EFFECT_TEST(GUID_SawtoothDown, SDL_HAPTIC_SAWTOOTHDOWN);
@@ -376,11 +386,11 @@ SDL_SYS_HapticOpenFromInstance(SDL_Haptic * haptic, DIDEVICEINSTANCE instance)
 static int
 static int
 SDL_SYS_HapticOpenFromXInput(SDL_Haptic * haptic, Uint8 userid)
 SDL_SYS_HapticOpenFromXInput(SDL_Haptic * haptic, Uint8 userid)
 {
 {
+    char threadName[32];
     XINPUT_VIBRATION vibration = { 0, 0 };  /* stop any current vibration */
     XINPUT_VIBRATION vibration = { 0, 0 };  /* stop any current vibration */
     XINPUTSETSTATE(userid, &vibration);
     XINPUTSETSTATE(userid, &vibration);
 
 
-    /* !!! FIXME: we can probably do more than SINE if we figure out how to set up the left and right motors properly. */
-    haptic->supported = SDL_HAPTIC_SINE;
+    haptic->supported = SDL_HAPTIC_LEFTRIGHT;
 
 
     haptic->neffects = 1;
     haptic->neffects = 1;
     haptic->nplaying = 1;
     haptic->nplaying = 1;
@@ -406,6 +416,30 @@ SDL_SYS_HapticOpenFromXInput(SDL_Haptic * haptic, Uint8 userid)
     haptic->hwdata->bXInputHaptic = 1;
     haptic->hwdata->bXInputHaptic = 1;
     haptic->hwdata->userid = userid;
     haptic->hwdata->userid = userid;
 
 
+    haptic->hwdata->mutex = SDL_CreateMutex();
+    if (haptic->hwdata->mutex == NULL) {
+        SDL_free(haptic->effects);
+        SDL_free(haptic->hwdata);
+        haptic->effects = NULL;
+        return SDL_SetError("Couldn't create XInput haptic mutex");
+    }
+
+    SDL_snprintf(threadName, sizeof (threadName), "SDLXInputDev%d", (int) userid);
+
+#if defined(__WIN32__) && !defined(HAVE_LIBC)  /* !!! FIXME: this is nasty. */
+    #undef SDL_CreateThread
+    haptic->hwdata->thread = SDL_CreateThread(SDL_RunXInputHaptic, threadName, haptic->hwdata, NULL, NULL);
+#else
+    haptic->hwdata->thread = SDL_CreateThread(SDL_RunXInputHaptic, threadName, haptic->hwdata);
+#endif
+    if (haptic->hwdata->thread == NULL) {
+        SDL_DestroyMutex(haptic->hwdata->mutex);
+        SDL_free(haptic->effects);
+        SDL_free(haptic->hwdata);
+        haptic->effects = NULL;
+        return SDL_SetError("Couldn't create XInput haptic thread");
+    }
+
     return 0;
     return 0;
  }
  }
 
 
@@ -684,7 +718,11 @@ SDL_SYS_HapticClose(SDL_Haptic * haptic)
         haptic->neffects = 0;
         haptic->neffects = 0;
 
 
         /* Clean up */
         /* Clean up */
-        if (!haptic->hwdata->bXInputHaptic) {
+        if (haptic->hwdata->bXInputHaptic) {
+            haptic->hwdata->stopThread = 1;
+            SDL_WaitThread(haptic->hwdata->thread, NULL);
+            SDL_DestroyMutex(haptic->hwdata->mutex);
+        } else {
             IDirectInputDevice8_Unacquire(haptic->hwdata->device);
             IDirectInputDevice8_Unacquire(haptic->hwdata->device);
             /* Only release if isn't grabbed by a joystick. */
             /* Only release if isn't grabbed by a joystick. */
             if (haptic->hwdata->is_joystick == 0) {
             if (haptic->hwdata->is_joystick == 0) {
@@ -897,7 +935,8 @@ SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest,
         break;
         break;
 
 
     case SDL_HAPTIC_SINE:
     case SDL_HAPTIC_SINE:
-    case SDL_HAPTIC_SQUARE:
+    /* !!! FIXME: put this back when we have more bits in 2.1 */
+    /*case SDL_HAPTIC_SQUARE:*/
     case SDL_HAPTIC_TRIANGLE:
     case SDL_HAPTIC_TRIANGLE:
     case SDL_HAPTIC_SAWTOOTHUP:
     case SDL_HAPTIC_SAWTOOTHUP:
     case SDL_HAPTIC_SAWTOOTHDOWN:
     case SDL_HAPTIC_SAWTOOTHDOWN:
@@ -1125,8 +1164,9 @@ SDL_SYS_HapticEffectType(SDL_HapticEffect * effect)
     case SDL_HAPTIC_RAMP:
     case SDL_HAPTIC_RAMP:
         return &GUID_RampForce;
         return &GUID_RampForce;
 
 
-    case SDL_HAPTIC_SQUARE:
-        return &GUID_Square;
+    /* !!! FIXME: put this back when we have more bits in 2.1 */
+    /*case SDL_HAPTIC_SQUARE:
+        return &GUID_Square;*/
 
 
     case SDL_HAPTIC_SINE:
     case SDL_HAPTIC_SINE:
         return &GUID_Sine;
         return &GUID_Sine;
@@ -1172,7 +1212,7 @@ SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
     HRESULT ret;
     HRESULT ret;
     REFGUID type = SDL_SYS_HapticEffectType(base);
     REFGUID type = SDL_SYS_HapticEffectType(base);
 
 
-    if (type == NULL) {
+    if ((type == NULL) && (!haptic->hwdata->bXInputHaptic)) {
         goto err_hweffect;
         goto err_hweffect;
     }
     }
 
 
@@ -1187,7 +1227,7 @@ SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
     SDL_zerop(effect->hweffect);
     SDL_zerop(effect->hweffect);
 
 
     if (haptic->hwdata->bXInputHaptic) {
     if (haptic->hwdata->bXInputHaptic) {
-        SDL_assert(base->type == SDL_HAPTIC_SINE);  /* should catch this at higher level */
+        SDL_assert(base->type == SDL_HAPTIC_LEFTRIGHT);  /* should catch this at higher level */
         return SDL_SYS_HapticUpdateEffect(haptic, effect, base);
         return SDL_SYS_HapticUpdateEffect(haptic, effect, base);
     }
     }
 
 
@@ -1231,20 +1271,15 @@ SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic,
     DIEFFECT temp;
     DIEFFECT temp;
 
 
     if (haptic->hwdata->bXInputHaptic) {
     if (haptic->hwdata->bXInputHaptic) {
-        /* !!! FIXME: this isn't close to right. We only support "sine" effects,
-         * !!! FIXME:  we ignore most of the parameters, and we probably get
-         * !!! FIXME:  the ones we don't ignore wrong, too.
-         * !!! FIXME: if I had a better understanding of how the two motors
-         * !!! FIXME:  could be used in unison, perhaps I could implement other
-         * !!! FIXME:  effect types?
-         */
-        /* From MSDN:
-            "Note that the right motor is the high-frequency motor, the left
-             motor is the low-frequency motor. They do not always need to be
-             set to the same amount, as they provide different effects." */
         XINPUT_VIBRATION *vib = &effect->hweffect->vibration;
         XINPUT_VIBRATION *vib = &effect->hweffect->vibration;
-        SDL_assert(data->type == SDL_HAPTIC_SINE);
-        vib->wLeftMotorSpeed = vib->wRightMotorSpeed = data->periodic.magnitude * 2;
+        SDL_assert(data->type == SDL_HAPTIC_LEFTRIGHT);
+        vib->wLeftMotorSpeed = data->leftright.large_magnitude;
+        vib->wRightMotorSpeed = data->leftright.small_magnitude;
+        SDL_LockMutex(haptic->hwdata->mutex);
+        if (haptic->hwdata->stopTicks) {  /* running right now? Update it. */
+            XINPUTSETSTATE(haptic->hwdata->userid, vib);
+        }
+        SDL_UnlockMutex(haptic->hwdata->mutex);
         return 0;
         return 0;
     }
     }
 
 
@@ -1295,7 +1330,11 @@ SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
 
 
     if (haptic->hwdata->bXInputHaptic) {
     if (haptic->hwdata->bXInputHaptic) {
         XINPUT_VIBRATION *vib = &effect->hweffect->vibration;
         XINPUT_VIBRATION *vib = &effect->hweffect->vibration;
-        return (XINPUTSETSTATE(haptic->hwdata->userid, vib) == ERROR_SUCCESS);
+        SDL_assert(effect->effect.type == SDL_HAPTIC_LEFTRIGHT);  /* should catch this at higher level */
+        SDL_LockMutex(haptic->hwdata->mutex);
+        haptic->hwdata->stopTicks = SDL_GetTicks() + (effect->effect.leftright.length * iterations);
+        SDL_UnlockMutex(haptic->hwdata->mutex);
+        return (XINPUTSETSTATE(haptic->hwdata->userid, vib) == ERROR_SUCCESS) ? 0 : -1;
     }
     }
 
 
     /* Check if it's infinite. */
     /* Check if it's infinite. */
@@ -1324,7 +1363,10 @@ SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
 
 
     if (haptic->hwdata->bXInputHaptic) {
     if (haptic->hwdata->bXInputHaptic) {
         XINPUT_VIBRATION vibration = { 0, 0 };
         XINPUT_VIBRATION vibration = { 0, 0 };
-        return (XINPUTSETSTATE(haptic->hwdata->userid, &vibration) == ERROR_SUCCESS);
+        SDL_LockMutex(haptic->hwdata->mutex);
+        haptic->hwdata->stopTicks = 0;
+        SDL_UnlockMutex(haptic->hwdata->mutex);
+        return (XINPUTSETSTATE(haptic->hwdata->userid, &vibration) == ERROR_SUCCESS) ? 0 : -1;
     }
     }
 
 
     ret = IDirectInputEffect_Stop(effect->hweffect->ref);
     ret = IDirectInputEffect_Stop(effect->hweffect->ref);
@@ -1483,7 +1525,10 @@ SDL_SYS_HapticStopAll(SDL_Haptic * haptic)
 
 
     if (haptic->hwdata->bXInputHaptic) {
     if (haptic->hwdata->bXInputHaptic) {
         XINPUT_VIBRATION vibration = { 0, 0 };
         XINPUT_VIBRATION vibration = { 0, 0 };
-        return (XINPUTSETSTATE(haptic->hwdata->userid, &vibration) == ERROR_SUCCESS);
+        SDL_LockMutex(haptic->hwdata->mutex);
+        haptic->hwdata->stopTicks = 0;
+        SDL_UnlockMutex(haptic->hwdata->mutex);
+        return (XINPUTSETSTATE(haptic->hwdata->userid, &vibration) == ERROR_SUCCESS) ? 0 : -1;
     }
     }
 
 
     /* Try to stop the effects. */
     /* Try to stop the effects. */
@@ -1496,6 +1541,41 @@ SDL_SYS_HapticStopAll(SDL_Haptic * haptic)
     return 0;
     return 0;
 }
 }
 
 
+
+/* !!! FIXME: this is a hack, remove this later. */
+/* Since XInput doesn't offer a way to vibrate for X time, we hook into
+ *  SDL_PumpEvents() to check if it's time to stop vibrating with some
+ *  frequency.
+ * In practice, this works for 99% of use cases. But in an ideal world,
+ *  we do this in a separate thread so that:
+ *    - we aren't bound to when the app chooses to pump the event queue.
+ *    - we aren't adding more polling to the event queue
+ *    - we can emulate all the haptic effects correctly (start on a delay,
+ *      mix multiple effects, etc).
+ *
+ * Mostly, this is here to get rumbling to work, and all the other features
+ *  are absent in the XInput path for now.  :(
+ */
+static int SDLCALL
+SDL_RunXInputHaptic(void *arg)
+{
+    struct haptic_hwdata *hwdata = (struct haptic_hwdata *) arg;
+
+    while (!hwdata->stopThread) {
+        SDL_Delay(50);
+        SDL_LockMutex(hwdata->mutex);
+        /* If we're currently running and need to stop... */
+        if ((hwdata->stopTicks) && (hwdata->stopTicks < SDL_GetTicks())) {
+            XINPUT_VIBRATION vibration = { 0, 0 };
+            hwdata->stopTicks = 0;
+            XINPUTSETSTATE(hwdata->userid, &vibration);
+        }
+        SDL_UnlockMutex(hwdata->mutex);
+    }
+
+    return 0;
+}
+
 #endif /* SDL_HAPTIC_DINPUT */
 #endif /* SDL_HAPTIC_DINPUT */
 
 
 /* vi: set ts=4 sw=4 expandtab: */
 /* vi: set ts=4 sw=4 expandtab: */

+ 1 - 37
Source/ThirdParty/SDL/src/joystick/SDL_gamecontroller.c

@@ -26,6 +26,7 @@
 #include "SDL_assert.h"
 #include "SDL_assert.h"
 #include "SDL_sysjoystick.h"
 #include "SDL_sysjoystick.h"
 #include "SDL_hints.h"
 #include "SDL_hints.h"
+#include "SDL_gamecontrollerdb.h"
 
 
 #if !SDL_EVENTS_DISABLED
 #if !SDL_EVENTS_DISABLED
 #include "../events/SDL_events_c.h"
 #include "../events/SDL_events_c.h"
@@ -85,43 +86,6 @@ typedef struct _ControllerMapping_t
     struct _ControllerMapping_t *next;
     struct _ControllerMapping_t *next;
 } ControllerMapping_t;
 } ControllerMapping_t;
 
 
-
-/* default mappings we support */
-const char *s_ControllerMappings [] =
-{
-#ifdef SDL_JOYSTICK_DINPUT
-    "xinput,X360 Controller,a:b10,b:b11,y:b13,x:b12,start:b4,guide:b14,back:b5,dpup:b0,dpleft:b2,dpdown:b1,dpright:b3,leftshoulder:b8,rightshoulder:b9,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5",
-    "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7",
-    "88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,x:b0,y:b3,start:b11,back:b8,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.4,dpdown:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b6,righttrigger:b7,guide:b12",
-    "4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,",
-    "25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,x:b0,y:b3,start:b8,guide:,back:b9,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.4,dpdown:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5",
-    "ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,y:b3,x:b2,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
-	"6d0419c2000000000000504944564944,Logitech F710 Gamepad,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", /* Guide button doesn't seem to be sent in DInput mode. */
-    "6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
-#elif defined(__MACOSX__)
-    "5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,y:b3,x:b2,start:b8,guide:b10,back:b9,dpup:b11,dpleft:b13,dpdown:b12,dpright:b14,leftshoulder:b4,rightshoulder:b5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5",
-    "4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,x:b15,y:b12,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9",
-    "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,y:b3,x:b2,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
-    "6d040000000000001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,y:b3,x:b2,start:b8,guide:b10,back:b9,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b11,dpleft:b13,dpdown:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
-    "6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", /* Guide button doesn't seem to be sent in DInput mode. */
-    "6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", /* This includes F710 in DInput mode and the "Logitech Cordless RumblePad 2", at the very least. */
-    "6d0400000000000018c2000000000000,Logitech Rumble Gamepad F510(DInput),a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,rightx:a2,lefty:a1,righty:a3,lefttrigger:b6,righttrigger:b7,",
-#elif defined(__LINUX__)
-    "030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5",
-    "030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
-    "030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
-    "030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,x:b15,y:b12,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9",
-    "030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
-    "030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,", /* Guide button doesn't seem to be sent in DInput mode. */
-    "030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
-    "030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
-    "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,y:b3,x:b2,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
-    "03000000ba2200002010000001010000,Jess Technology USB Game Controller,start:b9,a:b2,b:b1,x:b3,y:b0,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b6,righttrigger:b7,leftshoulder:b4,rightshoulder:b5,guide:,back:b8",
-    "030000006d0400001ec2000020200000,Logitech Rumble Gamepad F510 (XInput),a:b0,b:b1,x:b2,y:b3,start:b7,back:b6,guide:b8,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
-#endif
-    NULL
-};
-
 static ControllerMapping_t *s_pSupportedControllers = NULL;
 static ControllerMapping_t *s_pSupportedControllers = NULL;
 #ifdef SDL_JOYSTICK_DINPUT
 #ifdef SDL_JOYSTICK_DINPUT
 static ControllerMapping_t *s_pXInputMapping = NULL;
 static ControllerMapping_t *s_pXInputMapping = NULL;

+ 65 - 0
Source/ThirdParty/SDL/src/joystick/SDL_gamecontrollerdb.h

@@ -0,0 +1,65 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2013 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.
+*/
+#include "SDL_config.h"
+
+
+/* Default mappings we support
+
+   The easiest way to generate a new mapping is to start Steam in Big Picture
+   mode, configure your joystick and then look in config/config.vdf in your
+   Steam installation directory for the "SDL_GamepadBind" entry.
+ */
+static const char *s_ControllerMappings [] =
+{
+#ifdef SDL_JOYSTICK_DINPUT
+    "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
+    "ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
+    "6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
+	"6d0419c2000000000000504944564944,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* Guide button doesn't seem to be sent in DInput mode. */
+    "88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,",
+    "4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
+    "25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,",
+    "xinput,X360 Controller,a:b10,b:b11,back:b5,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,guide:b14,leftshoulder:b8,leftstick:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:a5,rightx:a2,righty:a3,start:b4,x:b12,y:b13,",
+#elif defined(__MACOSX__)
+    "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
+    "6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* Guide button doesn't seem to be sent in DInput mode. */
+    "6d0400000000000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
+    "6d040000000000001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,",
+    "6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* This includes F710 in DInput mode and the "Logitech Cordless RumblePad 2", at the very least. */
+    "4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
+    "5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,",
+#elif defined(__LINUX__)
+    "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
+    "03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,",
+    "030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
+    "030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
+    "030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
+    "030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* Guide button doesn't seem to be sent in DInput mode. */
+    "030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
+    "030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
+    "030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
+    "030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
+    "030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
+#endif
+    NULL
+};
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 24 - 7
Source/ThirdParty/SDL/src/joystick/SDL_joystick.c

@@ -36,17 +36,30 @@ static SDL_bool SDL_joystick_allows_background_events = SDL_FALSE;
 static SDL_Joystick *SDL_joysticks = NULL;
 static SDL_Joystick *SDL_joysticks = NULL;
 static SDL_Joystick *SDL_updating_joystick = NULL;
 static SDL_Joystick *SDL_updating_joystick = NULL;
 
 
+static void
+SDL_JoystickAllowBackgroundEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
+{
+    if (hint && *hint == '1') {
+        SDL_joystick_allows_background_events = SDL_TRUE;
+    } else {
+        SDL_joystick_allows_background_events = SDL_FALSE;
+    }
+}
+
 int
 int
 SDL_JoystickInit(void)
 SDL_JoystickInit(void)
 {
 {
-    const char *hint;
     int status;
     int status;
-	
-    /* Check to see if we should allow joystick events while in the background */
-    hint = SDL_GetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS);
-    if (hint && *hint == '1') {
-        SDL_joystick_allows_background_events = SDL_TRUE;
+
+    /* See if we should allow joystick events while in the background */
+    SDL_AddHintCallback(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS,
+                        SDL_JoystickAllowBackgroundEventsChanged, NULL);
+
+#if !SDL_EVENTS_DISABLED
+    if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0) {
+        return -1;
     }
     }
+#endif /* !SDL_EVENTS_DISABLED */
 
 
     status = SDL_SYS_JoystickInit();
     status = SDL_SYS_JoystickInit();
     if (status >= 0) {
     if (status >= 0) {
@@ -340,7 +353,7 @@ SDL_JoystickGetButton(SDL_Joystick * joystick, int button)
 
 
 /*
 /*
  * Return if the joystick in question is currently attached to the system,
  * Return if the joystick in question is currently attached to the system,
- *  \return 0 if not plugged in, 1 if still present.
+ *  \return SDL_FALSE if not plugged in, SDL_TRUE if still present.
  */
  */
 SDL_bool
 SDL_bool
 SDL_JoystickGetAttached(SDL_Joystick * joystick)
 SDL_JoystickGetAttached(SDL_Joystick * joystick)
@@ -458,6 +471,10 @@ SDL_JoystickQuit(void)
 
 
     /* Quit the joystick setup */
     /* Quit the joystick setup */
     SDL_SYS_JoystickQuit();
     SDL_SYS_JoystickQuit();
+
+#if !SDL_EVENTS_DISABLED
+    SDL_QuitSubSystem(SDL_INIT_EVENTS);
+#endif
 }
 }
 
 
 
 

+ 16 - 0
Source/ThirdParty/SDL/src/joystick/darwin/SDL_sysjoystick.c

@@ -362,6 +362,22 @@ HIDAddElement(CFTypeRef refElement, recDevice * pDevice)
                         }
                         }
                     }
                     }
                     break;
                     break;
+                case kHIDPage_Simulation:
+                    switch (usage) {
+                        case kHIDUsage_Sim_Rudder:
+                        case kHIDUsage_Sim_Throttle:
+                            element = (recElement *)
+                                NewPtrClear(sizeof(recElement));
+                            if (element) {
+                                pDevice->axes++;
+                                headElement = &(pDevice->firstAxis);
+                            }
+                            break;
+
+                        default:
+                            break;
+                    }
+                    break;
                 case kHIDPage_Button:
                 case kHIDPage_Button:
                     element = (recElement *)
                     element = (recElement *)
                         NewPtrClear(sizeof(recElement));
                         NewPtrClear(sizeof(recElement));

+ 0 - 209
Source/ThirdParty/SDL/src/joystick/nds/SDL_sysjoystick.c

@@ -1,209 +0,0 @@
-/*
-  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.
-*/
-
-#include "SDL_config.h"
-
-#ifdef SDL_JOYSTICK_NDS
-
-/* This is the system specific header for the SDL joystick API */
-#include <nds.h>
-#include <stdio.h>              /* For the definition of NULL */
-
-#include "SDL_error.h"
-#include "SDL_events.h"
-#include "SDL_joystick.h"
-#include "../SDL_sysjoystick.h"
-#include "../SDL_joystick_c.h"
-
-#include "../../video/nds/SDL_ndsevents_c.h"
-
-/* Function to scan the system for joysticks.
- */
-int
-SDL_SYS_JoystickInit(void)
-{
-    return (1);
-}
-
-int SDL_SYS_NumJoysticks()
-{
-    return 1;
-}
-
-void SDL_SYS_JoystickDetect()
-{
-}
-
-SDL_bool SDL_SYS_JoystickNeedsPolling()
-{
-    return SDL_FALSE;
-}
-
-/* Function to get the device-dependent name of a joystick */
-const char *
-SDL_SYS_JoystickNameForDeviceIndex(int device_index)
-{
-    return "NDS builtin joypad";
-}
-
-/* Function to perform the mapping from device index to the instance id for this index */
-SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
-{
-    return device_index;
-}
-
-/* Function to open a joystick for use.
-   The joystick to open is specified by the index field of the joystick.
-   This should fill the nbuttons and naxes fields of the joystick structure.
-   It returns 0, or -1 if there is an error.
- */
-int
-SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
-{
-    joystick->nbuttons = 8;
-    joystick->nhats = 0;
-    joystick->nballs = 0;
-    joystick->naxes = 2;
-    return 0;
-}
-
-/* Function to determine is this joystick is attached to the system right now */
-SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
-{
-    return SDL_TRUE;
-}
-
-/* Function to update the state of a joystick - called as a device poll.
- * This function shouldn't update the joystick structure directly,
- * but instead should call SDL_PrivateJoystick*() to deliver events
- * and update joystick device state.
- */
-    void
-SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
-{
-    u32 keysd, keysu;
-    int magnitude = 16384;
-    
-        /*scanKeys(); - this is done in PumpEvents, because touch uses it too */ 
-        keysd = keysDown();
-    keysu = keysUp();
-
-    if ((keysd & KEY_UP)) {
-        SDL_PrivateJoystickAxis(joystick, 1, -magnitude);
-    }
-    if ((keysd & KEY_DOWN)) {
-        SDL_PrivateJoystickAxis(joystick, 1, magnitude);
-    }
-    if ((keysd & KEY_LEFT)) {
-        SDL_PrivateJoystickAxis(joystick, 0, -magnitude);
-    }
-    if ((keysd & KEY_RIGHT)) {
-        SDL_PrivateJoystickAxis(joystick, 0, magnitude);
-    }
-    if ((keysu & (KEY_UP | KEY_DOWN))) {
-        SDL_PrivateJoystickAxis(joystick, 1, 0);
-    }
-    if ((keysu & (KEY_LEFT | KEY_RIGHT))) {
-        SDL_PrivateJoystickAxis(joystick, 0, 0);
-    }
-    if ((keysd & KEY_A)) {
-        SDL_PrivateJoystickButton(joystick, 0, SDL_PRESSED);
-    }
-    if ((keysd & KEY_B)) {
-        SDL_PrivateJoystickButton(joystick, 1, SDL_PRESSED);
-    }
-    if ((keysd & KEY_X)) {
-        SDL_PrivateJoystickButton(joystick, 2, SDL_PRESSED);
-    }
-    if ((keysd & KEY_Y)) {
-        SDL_PrivateJoystickButton(joystick, 3, SDL_PRESSED);
-    }
-    if ((keysd & KEY_L)) {
-        SDL_PrivateJoystickButton(joystick, 4, SDL_PRESSED);
-    }
-    if ((keysd & KEY_R)) {
-        SDL_PrivateJoystickButton(joystick, 5, SDL_PRESSED);
-    }
-    if ((keysd & KEY_SELECT)) {
-        SDL_PrivateJoystickButton(joystick, 6, SDL_PRESSED);
-    }
-    if ((keysd & KEY_START)) {
-        SDL_PrivateJoystickButton(joystick, 7, SDL_PRESSED);
-    }
-    if ((keysu & KEY_A)) {
-        SDL_PrivateJoystickButton(joystick, 0, SDL_RELEASED);
-    }
-    if ((keysu & KEY_B)) {
-        SDL_PrivateJoystickButton(joystick, 1, SDL_RELEASED);
-    }
-    if ((keysu & KEY_X)) {
-        SDL_PrivateJoystickButton(joystick, 2, SDL_RELEASED);
-    }
-    if ((keysu & KEY_Y)) {
-        SDL_PrivateJoystickButton(joystick, 3, SDL_RELEASED);
-    }
-    if ((keysu & KEY_L)) {
-        SDL_PrivateJoystickButton(joystick, 4, SDL_RELEASED);
-    }
-    if ((keysu & KEY_R)) {
-        SDL_PrivateJoystickButton(joystick, 5, SDL_RELEASED);
-    }
-    if ((keysu & KEY_SELECT)) {
-        SDL_PrivateJoystickButton(joystick, 6, SDL_RELEASED);
-    }
-    if ((keysu & KEY_START)) {
-        SDL_PrivateJoystickButton(joystick, 7, SDL_RELEASED);
-    }
-}
-
-/* Function to close a joystick after use */
-void
-SDL_SYS_JoystickClose(SDL_Joystick * joystick)
-{
-}
-
-/* Function to perform any system-specific joystick related cleanup */
-void
-SDL_SYS_JoystickQuit(void)
-{
-}
-
-SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
-{
-    SDL_JoystickGUID guid;
-    // the GUID is just the first 16 chars of the name for now
-    const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index );
-    SDL_zero( guid );
-    SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
-    return guid;
-}
-
-SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
-{
-    SDL_JoystickGUID guid;
-    // the GUID is just the first 16 chars of the name for now
-    const char *name = joystick->name;
-    SDL_zero( guid );
-    SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
-    return guid;
-}
-
-#endif /* SDL_JOYSTICK_NDS */

+ 11 - 65
Source/ThirdParty/SDL/src/libm/math_libm.h

@@ -19,73 +19,19 @@
   3. This notice may not be removed or altered from any source distribution.
   3. This notice may not be removed or altered from any source distribution.
 */
 */
 #include "SDL_config.h"
 #include "SDL_config.h"
-#include "SDL_stdinc.h"
 
 
 /* Math routines from uClibc: http://www.uclibc.org */
 /* Math routines from uClibc: http://www.uclibc.org */
 
 
-#ifdef HAVE_ATAN
-#define atan            SDL_uclibc_atan
-#else
-#define atan            SDL_atan
-#endif
-double atan(double x);
-
-#ifndef HAVE_ATAN2
-#define __ieee754_atan2 SDL_atan2
-#endif
-
-#ifdef HAVE_COPYSIGN
-#define copysign        SDL_uclibc_copysign
-#else
-#define copysign        SDL_copysign
-#endif
-double copysign(double x, double y);
-
-#ifdef HAVE_COS
-#define cos             SDL_uclibc_cos
-#else
-#define cos             SDL_cos
-#endif
-double cos(double x);
-
-#ifdef HAVE_FABS
-#define fabs            SDL_uclibc_fabs
-#else
-#define fabs            SDL_fabs
-#endif
-double fabs(double x);
-
-#ifdef HAVE_FLOOR
-#define floor           SDL_uclibc_floor
-#else
-#define floor           SDL_floor
-#endif
-double floor(double x);
-
-#ifndef HAVE_LOG
-#define __ieee754_log   SDL_log
-#endif
-
-#ifndef HAVE_POW
-#define __ieee754_pow   SDL_pow
-#endif
-
-#ifdef HAVE_SCALBN
-#define scalbn          SDL_uclibc_scalbn
-#else
-#define scalbn          SDL_scalbn
-#endif
-double scalbn(double x, int n);
-
-#ifdef HAVE_SIN
-#define sin             SDL_uclibc_sin
-#else
-#define sin             SDL_sin
-#endif
-double sin(double x);
-
-#ifndef HAVE_SQRT
-#define __ieee754_sqrt  SDL_sqrt
-#endif
+double SDL_uclibc_atan(double x);
+double SDL_uclibc_atan2(double y, double x);    
+double SDL_uclibc_copysign(double x, double y);       
+double SDL_uclibc_cos(double x);         
+double SDL_uclibc_fabs(double x);        
+double SDL_uclibc_floor(double x);
+double SDL_uclibc_log(double x);
+double SDL_uclibc_pow(double x, double y);    
+double SDL_uclibc_scalbn(double x, int n);
+double SDL_uclibc_sin(double x);
+double SDL_uclibc_sqrt(double x);
 
 
 /* vi: set ts=4 sw=4 expandtab: */
 /* vi: set ts=4 sw=4 expandtab: */

+ 14 - 0
Source/ThirdParty/SDL/src/libm/math_private.h

@@ -25,7 +25,21 @@
 #define libm_hidden_proto(x)
 #define libm_hidden_proto(x)
 #define libm_hidden_def(x)
 #define libm_hidden_def(x)
 
 
+#ifndef __HAIKU__ /* already defined in a system header. */
 typedef unsigned int u_int32_t;
 typedef unsigned int u_int32_t;
+#endif
+
+#define atan            SDL_uclibc_atan
+#define __ieee754_atan2 SDL_uclibc_atan2
+#define copysign        SDL_uclibc_copysign
+#define cos             SDL_uclibc_cos
+#define fabs            SDL_uclibc_fabs
+#define floor           SDL_uclibc_floor
+#define __ieee754_log   SDL_uclibc_log
+#define __ieee754_pow   SDL_uclibc_pow
+#define scalbn          SDL_uclibc_scalbn
+#define sin             SDL_uclibc_sin
+#define __ieee754_sqrt  SDL_uclibc_sqrt
 
 
 /* The original fdlibm code used statements like:
 /* The original fdlibm code used statements like:
 	n0 = ((*(int*)&one)>>29)^1;		* index of high word *
 	n0 = ((*(int*)&one)>>29)^1;		* index of high word *

+ 1 - 1
Source/ThirdParty/SDL/src/loadso/dlopen/SDL_sysloadso.c

@@ -33,7 +33,7 @@
 void *
 void *
 SDL_LoadObject(const char *sofile)
 SDL_LoadObject(const char *sofile)
 {
 {
-    void *handle = dlopen(sofile, RTLD_NOW);
+    void *handle = dlopen(sofile, RTLD_NOW|RTLD_LOCAL);
     const char *loaderror = (char *) dlerror();
     const char *loaderror = (char *) dlerror();
     if (handle == NULL) {
     if (handle == NULL) {
         SDL_SetError("Failed loading %s: %s", sofile, loaderror);
         SDL_SetError("Failed loading %s: %s", sofile, loaderror);

+ 5 - 0
Source/ThirdParty/SDL/src/main/android/SDL_android_main.c

@@ -0,0 +1,5 @@
+// Modified by Lasse Oorni for Urho3D
+
+// Urho3D: function moved to SDL_android.c due to link error
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 0 - 19
Source/ThirdParty/SDL/src/main/android/SDL_android_main.cpp

@@ -1,19 +0,0 @@
-// Modified by Lasse Oorni for Urho3D
-
-#include "SDL_config.h"
-
-#ifdef __ANDROID__
-
-/* Include the SDL main definition header */
-#include "SDL_main.h"
-
-/*******************************************************************************
-                 Functions called by JNI
-*******************************************************************************/
-#include <jni.h>
-
-// Urho3D: function moved to SDL_android.cpp
-
-#endif /* __ANDROID__ */
-
-/* vi: set ts=4 sw=4 expandtab: */

+ 4 - 2
Source/ThirdParty/SDL/src/main/windows/SDL_windows_main.c

@@ -54,7 +54,7 @@ ParseCommandLine(char *cmdline, char **argv)
     argc = last_argc = 0;
     argc = last_argc = 0;
     for (bufp = cmdline; *bufp;) {
     for (bufp = cmdline; *bufp;) {
         /* Skip leading whitespace */
         /* Skip leading whitespace */
-        while (isspace(*bufp)) {
+        while (SDL_isspace(*bufp)) {
             ++bufp;
             ++bufp;
         }
         }
         /* Skip over argument */
         /* Skip over argument */
@@ -80,7 +80,7 @@ ParseCommandLine(char *cmdline, char **argv)
                 ++argc;
                 ++argc;
             }
             }
             /* Skip over word */
             /* Skip over word */
-            while (*bufp && !isspace(*bufp)) {
+            while (*bufp && !SDL_isspace(*bufp)) {
                 ++bufp;
                 ++bufp;
             }
             }
         }
         }
@@ -176,6 +176,8 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
     /* Run the main program */
     /* Run the main program */
     console_main(argc, argv);
     console_main(argc, argv);
 
 
+    SDL_stack_free(argv);
+
     SDL_free(cmdline);
     SDL_free(cmdline);
 
 
     /* Hush little compiler, don't you cry... */
     /* Hush little compiler, don't you cry... */

+ 0 - 44
Source/ThirdParty/SDL/src/power/nds/SDL_syspower.c

@@ -1,44 +0,0 @@
-/*
-  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.
-*/
-#include "SDL_config.h"
-
-#ifndef SDL_POWER_DISABLED
-#if SDL_POWER_NINTENDODS
-
-#include "SDL_power.h"
-
-SDL_bool
-SDL_GetPowerInfo_NintendoDS(SDL_PowerState * state, int *seconds,
-                            int *percent)
-{
-    /* !!! FIXME: write me. */
-
-    *state = SDL_POWERSTATE_UNKNOWN;
-    *percent = -1;
-    *seconds = -1;
-
-    return SDL_TRUE;            /* always the definitive answer on Nintendo DS. */
-}
-
-#endif /* SDL_POWER_NINTENDODS */
-#endif /* SDL_POWER_DISABLED */
-
-/* vi: set ts=4 sw=4 expandtab: */

+ 26 - 16
Source/ThirdParty/SDL/src/render/SDL_render.c

@@ -151,6 +151,16 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
             event->motion.y -= renderer->viewport.y;
             event->motion.y -= renderer->viewport.y;
             event->motion.x = (int)(event->motion.x / renderer->scale.x);
             event->motion.x = (int)(event->motion.x / renderer->scale.x);
             event->motion.y = (int)(event->motion.y / renderer->scale.y);
             event->motion.y = (int)(event->motion.y / renderer->scale.y);
+            if (event->motion.xrel > 0) {
+                event->motion.xrel = SDL_max(1, (int)(event->motion.xrel / renderer->scale.x));
+            } else if (event->motion.xrel < 0) {
+                event->motion.xrel = SDL_min(-1, (int)(event->motion.xrel / renderer->scale.x));
+            }
+            if (event->motion.yrel > 0) {
+                event->motion.yrel = SDL_max(1, (int)(event->motion.yrel / renderer->scale.y));
+            } else if (event->motion.yrel < 0) {
+                event->motion.yrel = SDL_min(-1, (int)(event->motion.yrel / renderer->scale.y));
+            }
         }
         }
     } else if (event->type == SDL_MOUSEBUTTONDOWN ||
     } else if (event->type == SDL_MOUSEBUTTONDOWN ||
                event->type == SDL_MOUSEBUTTONUP) {
                event->type == SDL_MOUSEBUTTONUP) {
@@ -764,6 +774,13 @@ SDL_UpdateTexture(SDL_Texture * texture, const SDL_Rect * rect,
 
 
     CHECK_TEXTURE_MAGIC(texture, -1);
     CHECK_TEXTURE_MAGIC(texture, -1);
 
 
+    if (!pixels) {
+        return SDL_InvalidParamError("pixels");
+    }
+    if (!pitch) {
+        return SDL_InvalidParamError("pitch");
+    }
+
     if (!rect) {
     if (!rect) {
         full_rect.x = 0;
         full_rect.x = 0;
         full_rect.y = 0;
         full_rect.y = 0;
@@ -1450,7 +1467,7 @@ SDL_RenderDrawRects(SDL_Renderer * renderer,
 int
 int
 SDL_RenderFillRect(SDL_Renderer * renderer, const SDL_Rect * rect)
 SDL_RenderFillRect(SDL_Renderer * renderer, const SDL_Rect * rect)
 {
 {
-    SDL_Rect full_rect;
+    SDL_Rect full_rect = { 0, 0, 0, 0 };
 
 
     CHECK_RENDERER_MAGIC(renderer, -1);
     CHECK_RENDERER_MAGIC(renderer, -1);
 
 
@@ -1532,22 +1549,10 @@ SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
     real_dstrect.x = 0;
     real_dstrect.x = 0;
     real_dstrect.y = 0;
     real_dstrect.y = 0;
     if (dstrect) {
     if (dstrect) {
-        if (!SDL_IntersectRect(dstrect, &real_dstrect, &real_dstrect)) {
+        if (!SDL_HasIntersection(dstrect, &real_dstrect)) {
             return 0;
             return 0;
         }
         }
-        /* Clip srcrect by the same amount as dstrect was clipped */
-        if (dstrect->w != real_dstrect.w) {
-            int deltax = (real_dstrect.x - dstrect->x);
-            int deltaw = (real_dstrect.w - dstrect->w);
-            real_srcrect.x += (deltax * real_srcrect.w) / dstrect->w;
-            real_srcrect.w += (deltaw * real_srcrect.w) / dstrect->w;
-        }
-        if (dstrect->h != real_dstrect.h) {
-            int deltay = (real_dstrect.y - dstrect->y);
-            int deltah = (real_dstrect.h - dstrect->h);
-            real_srcrect.y += (deltay * real_srcrect.h) / dstrect->h;
-            real_srcrect.h += (deltah * real_srcrect.h) / dstrect->h;
-        }
+        real_dstrect = *dstrect;
     }
     }
 
 
     if (texture->native) {
     if (texture->native) {
@@ -1684,9 +1689,14 @@ SDL_DestroyTexture(SDL_Texture * texture)
     SDL_Renderer *renderer;
     SDL_Renderer *renderer;
 
 
     CHECK_TEXTURE_MAGIC(texture, );
     CHECK_TEXTURE_MAGIC(texture, );
-    texture->magic = NULL;
 
 
     renderer = texture->renderer;
     renderer = texture->renderer;
+    if (texture == renderer->target) {
+        SDL_SetRenderTarget(renderer, NULL);
+    }
+
+    texture->magic = NULL;
+
     if (texture->next) {
     if (texture->next) {
         texture->next->prev = texture->prev;
         texture->next->prev = texture->prev;
     }
     }

+ 8 - 8
Source/ThirdParty/SDL/src/render/SDL_yuv_sw.c

@@ -82,6 +82,7 @@
  * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  */
  */
 
 
+#include "SDL_assert.h"
 #include "SDL_video.h"
 #include "SDL_video.h"
 #include "SDL_cpuinfo.h"
 #include "SDL_cpuinfo.h"
 #include "SDL_yuv_sw_c.h"
 #include "SDL_yuv_sw_c.h"
@@ -1029,12 +1030,6 @@ SDL_SW_CreateYUVTexture(Uint32 format, int w, int h)
     int i;
     int i;
     int CR, CB;
     int CR, CB;
 
 
-    swdata = (SDL_SW_YUVTexture *) SDL_calloc(1, sizeof(*swdata));
-    if (!swdata) {
-        SDL_OutOfMemory();
-        return NULL;
-    }
-
     switch (format) {
     switch (format) {
     case SDL_PIXELFORMAT_YV12:
     case SDL_PIXELFORMAT_YV12:
     case SDL_PIXELFORMAT_IYUV:
     case SDL_PIXELFORMAT_IYUV:
@@ -1043,11 +1038,16 @@ SDL_SW_CreateYUVTexture(Uint32 format, int w, int h)
     case SDL_PIXELFORMAT_YVYU:
     case SDL_PIXELFORMAT_YVYU:
         break;
         break;
     default:
     default:
-        SDL_SW_DestroyYUVTexture(swdata);
         SDL_SetError("Unsupported YUV format");
         SDL_SetError("Unsupported YUV format");
         return NULL;
         return NULL;
     }
     }
 
 
+    swdata = (SDL_SW_YUVTexture *) SDL_calloc(1, sizeof(*swdata));
+    if (!swdata) {
+        SDL_OutOfMemory();
+        return NULL;
+    }
+
     swdata->format = format;
     swdata->format = format;
     swdata->target_format = SDL_PIXELFORMAT_UNKNOWN;
     swdata->target_format = SDL_PIXELFORMAT_UNKNOWN;
     swdata->w = w;
     swdata->w = w;
@@ -1095,7 +1095,7 @@ SDL_SW_CreateYUVTexture(Uint32 format, int w, int h)
         swdata->planes[0] = swdata->pixels;
         swdata->planes[0] = swdata->pixels;
         break;
         break;
     default:
     default:
-        /* We should never get here (caught above) */
+        SDL_assert(0 && "We should never get here (caught above)");
         break;
         break;
     }
     }
 
 

+ 376 - 54
Source/ThirdParty/SDL/src/render/direct3d/SDL_render_d3d.c

@@ -29,7 +29,7 @@
 #include "SDL_loadso.h"
 #include "SDL_loadso.h"
 #include "SDL_syswm.h"
 #include "SDL_syswm.h"
 #include "../SDL_sysrender.h"
 #include "../SDL_sysrender.h"
-#include "stdio.h"
+#include <stdio.h>
 
 
 #if SDL_VIDEO_RENDER_D3D
 #if SDL_VIDEO_RENDER_D3D
 #define D3D_DEBUG_INFO
 #define D3D_DEBUG_INFO
@@ -169,6 +169,32 @@ HRESULT WINAPI
         LPD3DXBUFFER*                   ppShader,
         LPD3DXBUFFER*                   ppShader,
         LPD3DXBUFFER*                   ppErrorMsgs);
         LPD3DXBUFFER*                   ppErrorMsgs);
 
 
+static void PrintShaderData(LPDWORD shader_data, DWORD shader_size)
+{
+    OutputDebugStringA("const DWORD shader_data[] = {\n\t");
+    {
+        SDL_bool newline = SDL_FALSE;
+        unsigned i;
+        for (i = 0; i < shader_size / sizeof(DWORD); ++i) {
+            char dword[11];
+            if (i > 0) {
+                if ((i%6) == 0) {
+                    newline = SDL_TRUE;
+                }
+                if (newline) {
+                    OutputDebugStringA(",\n    ");
+                    newline = SDL_FALSE;
+                } else {
+                    OutputDebugStringA(", ");
+                }
+            }
+            SDL_snprintf(dword, sizeof(dword), "0x%8.8x", shader_data[i]);
+            OutputDebugStringA(dword);
+        }
+        OutputDebugStringA("\n};\n");
+    }
+}
+
 #endif /* ASSEMBLE_SHADER */
 #endif /* ASSEMBLE_SHADER */
 
 
 
 
@@ -227,17 +253,27 @@ typedef struct
     D3DPRESENT_PARAMETERS pparams;
     D3DPRESENT_PARAMETERS pparams;
     SDL_bool updateSize;
     SDL_bool updateSize;
     SDL_bool beginScene;
     SDL_bool beginScene;
-    D3DTEXTUREFILTERTYPE scaleMode;
+    SDL_bool enableSeparateAlphaBlend;
+    D3DTEXTUREFILTERTYPE scaleMode[8];
     IDirect3DSurface9 *defaultRenderTarget;
     IDirect3DSurface9 *defaultRenderTarget;
     IDirect3DSurface9 *currentRenderTarget;
     IDirect3DSurface9 *currentRenderTarget;
     void* d3dxDLL;
     void* d3dxDLL;
     ID3DXMatrixStack *matrixStack;
     ID3DXMatrixStack *matrixStack;
+    LPDIRECT3DPIXELSHADER9 ps_yuv;
 } D3D_RenderData;
 } D3D_RenderData;
 
 
 typedef struct
 typedef struct
 {
 {
     IDirect3DTexture9 *texture;
     IDirect3DTexture9 *texture;
     D3DTEXTUREFILTERTYPE scaleMode;
     D3DTEXTUREFILTERTYPE scaleMode;
+
+    /* YV12 texture support */
+    SDL_bool yuv;
+    IDirect3DTexture9 *utexture;
+    IDirect3DTexture9 *vtexture;
+    Uint8 *pixels;
+    int pitch;
+    SDL_Rect locked_rect;
 } D3D_TextureData;
 } D3D_TextureData;
 
 
 typedef struct
 typedef struct
@@ -336,6 +372,9 @@ PixelFormatToD3DFMT(Uint32 format)
         return D3DFMT_X8R8G8B8;
         return D3DFMT_X8R8G8B8;
     case SDL_PIXELFORMAT_ARGB8888:
     case SDL_PIXELFORMAT_ARGB8888:
         return D3DFMT_A8R8G8B8;
         return D3DFMT_A8R8G8B8;
+    case SDL_PIXELFORMAT_YV12:
+    case SDL_PIXELFORMAT_IYUV:
+        return D3DFMT_L8;
     default:
     default:
         return D3DFMT_UNKNOWN;
         return D3DFMT_UNKNOWN;
     }
     }
@@ -384,7 +423,8 @@ D3D_Reset(SDL_Renderer * renderer)
                                     D3DCULL_NONE);
                                     D3DCULL_NONE);
     IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE);
     IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE);
     IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget);
     IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget);
-    data->scaleMode = D3DTEXF_FORCE_DWORD;
+    SDL_memset(data->scaleMode, 0xFF, sizeof(data->scaleMode));
+    D3D_UpdateViewport(renderer);
     return 0;
     return 0;
 }
 }
 
 
@@ -410,7 +450,6 @@ D3D_ActivateRenderer(SDL_Renderer * renderer)
         if (D3D_Reset(renderer) < 0) {
         if (D3D_Reset(renderer) < 0) {
             return -1;
             return -1;
         }
         }
-        D3D_UpdateViewport(renderer);
 
 
         data->updateSize = SDL_FALSE;
         data->updateSize = SDL_FALSE;
     }
     }
@@ -586,7 +625,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
         return NULL;
         return NULL;
     }
     }
     data->beginScene = SDL_TRUE;
     data->beginScene = SDL_TRUE;
-    data->scaleMode = D3DTEXF_FORCE_DWORD;
+    SDL_memset(data->scaleMode, 0xFF, sizeof(data->scaleMode));
 
 
     /* Get presentation parameters to fill info */
     /* Get presentation parameters to fill info */
     result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain);
     result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain);
@@ -615,6 +654,10 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
         renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE;
         renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE;
     }
     }
 
 
+    if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND) {
+        data->enableSeparateAlphaBlend = SDL_TRUE;
+    }
+
     /* Set up parameters for rendering */
     /* Set up parameters for rendering */
     IDirect3DDevice9_SetVertexShader(data->device, NULL);
     IDirect3DDevice9_SetVertexShader(data->device, NULL);
     IDirect3DDevice9_SetFVF(data->device,
     IDirect3DDevice9_SetFVF(data->device,
@@ -637,6 +680,10 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
                                           D3DTA_TEXTURE);
                                           D3DTA_TEXTURE);
     IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG2,
     IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG2,
                                           D3DTA_DIFFUSE);
                                           D3DTA_DIFFUSE);
+    /* Enable separate alpha blend function, if possible */
+    if (data->enableSeparateAlphaBlend) {
+        IDirect3DDevice9_SetRenderState(data->device, D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
+    }
     /* Disable second texture stage, since we're done */
     /* Disable second texture stage, since we're done */
     IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_COLOROP,
     IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_COLOROP,
                                           D3DTOP_DISABLE);
                                           D3DTOP_DISABLE);
@@ -667,6 +714,136 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
     IDirect3DDevice9_SetTransform(data->device, D3DTS_WORLD, &matrix);
     IDirect3DDevice9_SetTransform(data->device, D3DTS_WORLD, &matrix);
     IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, &matrix);
     IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, &matrix);
 
 
+    if (caps.MaxSimultaneousTextures >= 3)
+    {
+#ifdef ASSEMBLE_SHADER
+        /* This shader was created by running the following HLSL through the fxc compiler
+           and then tuning the generated assembly.
+
+           fxc /T fx_4_0 /O3 /Gfa /Fc yuv.fxc yuv.fx
+
+           --- yuv.fx ---
+           Texture2D g_txY;
+           Texture2D g_txU;
+           Texture2D g_txV;
+
+           SamplerState samLinear
+           {
+               Filter = ANISOTROPIC;
+               AddressU = Clamp;
+               AddressV = Clamp;
+               MaxAnisotropy = 1;
+           };
+
+           struct VS_OUTPUT
+           {
+                float2 TextureUV  : TEXCOORD0;
+           };
+
+           struct PS_OUTPUT
+           {
+                float4 RGBAColor : SV_Target;
+           };
+
+           PS_OUTPUT YUV420( VS_OUTPUT In ) 
+           {
+               const float3 offset = {-0.0625, -0.5, -0.5};
+               const float3 Rcoeff = {1.164,  0.000,  1.596};
+               const float3 Gcoeff = {1.164, -0.391, -0.813};
+               const float3 Bcoeff = {1.164,  2.018,  0.000};
+
+               PS_OUTPUT Output;
+               float2 TextureUV = In.TextureUV;
+
+               float3 yuv;
+               yuv.x = g_txY.Sample( samLinear, TextureUV ).r;
+               yuv.y = g_txU.Sample( samLinear, TextureUV ).r;
+               yuv.z = g_txV.Sample( samLinear, TextureUV ).r;
+
+               yuv += offset;
+               Output.RGBAColor.r = dot(yuv, Rcoeff);
+               Output.RGBAColor.g = dot(yuv, Gcoeff);
+               Output.RGBAColor.b = dot(yuv, Bcoeff);
+               Output.RGBAColor.a = 1.0f;
+
+               return Output;
+           }
+
+           technique10 RenderYUV420
+           {
+               pass P0
+               {
+                    SetPixelShader( CompileShader( ps_4_0_level_9_0, YUV420() ) );
+               }
+           }
+        */
+        const char *shader_text =
+            "ps_2_0\n"
+            "def c0, -0.0625, -0.5, -0.5, 1\n"
+            "def c1, 1.16400003, 0, 1.59599996, 0\n"
+            "def c2, 1.16400003, -0.391000003, -0.813000023, 0\n"
+            "def c3, 1.16400003, 2.01799989, 0, 0\n"
+            "dcl t0.xy\n"
+            "dcl v0.xyzw\n"
+            "dcl_2d s0\n"
+            "dcl_2d s1\n"
+            "dcl_2d s2\n"
+            "texld r0, t0, s0\n"
+            "texld r1, t0, s1\n"
+            "texld r2, t0, s2\n"
+            "mov r0.y, r1.x\n"
+            "mov r0.z, r2.x\n"
+            "add r0.xyz, r0, c0\n"
+            "dp3 r1.x, r0, c1\n"
+            "dp3 r1.y, r0, c2\n"
+            "dp2add r1.z, r0, c3, c3.z\n"   /* Logically this is "dp3 r1.z, r0, c3" but the optimizer did its magic */
+            "mov r1.w, c0.w\n"
+            "mul r0, r1, v0\n"              /* Not in the HLSL, multiply by vertex color */
+            "mov oC0, r0\n"
+        ;
+        LPD3DXBUFFER pCode;
+        LPD3DXBUFFER pErrorMsgs;
+        LPDWORD shader_data = NULL;
+        DWORD   shader_size = 0;
+        result = D3DXAssembleShader(shader_text, SDL_strlen(shader_text), NULL, NULL, 0, &pCode, &pErrorMsgs);
+        if (!FAILED(result)) {
+            shader_data = (DWORD*)pCode->lpVtbl->GetBufferPointer(pCode);
+            shader_size = pCode->lpVtbl->GetBufferSize(pCode);
+            PrintShaderData(shader_data, shader_size);
+        } else {
+            const char *error = (const char *)pErrorMsgs->lpVtbl->GetBufferPointer(pErrorMsgs);
+            SDL_SetError("Couldn't assemble shader: %s", error);
+        }
+#else
+        const DWORD shader_data[] = {
+            0xffff0200, 0x05000051, 0xa00f0000, 0xbd800000, 0xbf000000, 0xbf000000,
+            0x3f800000, 0x05000051, 0xa00f0001, 0x3f94fdf4, 0x00000000, 0x3fcc49ba,
+            0x00000000, 0x05000051, 0xa00f0002, 0x3f94fdf4, 0xbec83127, 0xbf5020c5,
+            0x00000000, 0x05000051, 0xa00f0003, 0x3f94fdf4, 0x400126e9, 0x00000000,
+            0x00000000, 0x0200001f, 0x80000000, 0xb0030000, 0x0200001f, 0x80000000,
+            0x900f0000, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000,
+            0xa00f0801, 0x0200001f, 0x90000000, 0xa00f0802, 0x03000042, 0x800f0000,
+            0xb0e40000, 0xa0e40800, 0x03000042, 0x800f0001, 0xb0e40000, 0xa0e40801,
+            0x03000042, 0x800f0002, 0xb0e40000, 0xa0e40802, 0x02000001, 0x80020000,
+            0x80000001, 0x02000001, 0x80040000, 0x80000002, 0x03000002, 0x80070000,
+            0x80e40000, 0xa0e40000, 0x03000008, 0x80010001, 0x80e40000, 0xa0e40001,
+            0x03000008, 0x80020001, 0x80e40000, 0xa0e40002, 0x0400005a, 0x80040001,
+            0x80e40000, 0xa0e40003, 0xa0aa0003, 0x02000001, 0x80080001, 0xa0ff0000,
+            0x03000005, 0x800f0000, 0x80e40001, 0x90e40000, 0x02000001, 0x800f0800,
+            0x80e40000, 0x0000ffff
+        };
+#endif
+        if (shader_data != NULL) {
+            result = IDirect3DDevice9_CreatePixelShader(data->device, shader_data, &data->ps_yuv);
+            if (!FAILED(result)) {
+                renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_YV12;
+                renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_IYUV;
+            } else {
+                D3D_SetError("CreatePixelShader()", result);
+            }
+        }
+    }
+
     return renderer;
     return renderer;
 }
 }
 
 
@@ -687,10 +864,8 @@ GetScaleQuality(void)
 
 
     if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
     if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
         return D3DTEXF_POINT;
         return D3DTEXF_POINT;
-    } else if (*hint == '1' || SDL_strcasecmp(hint, "linear") == 0) {
+    } else /*if (*hint == '1' || SDL_strcasecmp(hint, "linear") == 0)*/ {
         return D3DTEXF_LINEAR;
         return D3DTEXF_LINEAR;
-    } else {
-        return D3DTEXF_ANISOTROPIC;
     }
     }
 }
 }
 
 
@@ -735,14 +910,35 @@ D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
         return D3D_SetError("CreateTexture()", result);
         return D3D_SetError("CreateTexture()", result);
     }
     }
 
 
+    if (texture->format == SDL_PIXELFORMAT_YV12 ||
+        texture->format == SDL_PIXELFORMAT_IYUV) {
+        data->yuv = SDL_TRUE;
+
+        result =
+            IDirect3DDevice9_CreateTexture(renderdata->device, texture->w / 2,
+                                           texture->h / 2, 1, usage,
+                                           PixelFormatToD3DFMT(texture->format),
+                                           pool, &data->utexture, NULL);
+        if (FAILED(result)) {
+            return D3D_SetError("CreateTexture()", result);
+        }
+
+        result =
+            IDirect3DDevice9_CreateTexture(renderdata->device, texture->w / 2,
+                                           texture->h / 2, 1, usage,
+                                           PixelFormatToD3DFMT(texture->format),
+                                           pool, &data->vtexture, NULL);
+        if (FAILED(result)) {
+            return D3D_SetError("CreateTexture()", result);
+        }
+    }
+
     return 0;
     return 0;
 }
 }
 
 
 static int
 static int
-D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
-                  const SDL_Rect * rect, const void *pixels, int pitch)
+D3D_UpdateTextureInternal(IDirect3DTexture9 *texture, Uint32 format, SDL_bool full_texture, int x, int y, int w, int h, const void *pixels, int pitch)
 {
 {
-    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
     RECT d3drect;
     RECT d3drect;
     D3DLOCKED_RECT locked;
     D3DLOCKED_RECT locked;
     const Uint8 *src;
     const Uint8 *src;
@@ -750,39 +946,70 @@ D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
     int row, length;
     int row, length;
     HRESULT result;
     HRESULT result;
 
 
-#ifdef USE_DYNAMIC_TEXTURE
-    if (texture->access == SDL_TEXTUREACCESS_STREAMING &&
-        rect->x == 0 && rect->y == 0 &&
-        rect->w == texture->w && rect->h == texture->h) {
-        result = IDirect3DTexture9_LockRect(data->texture, 0, &locked, NULL, D3DLOCK_DISCARD);
-    } else
-#endif
-    {
-        d3drect.left = rect->x;
-        d3drect.right = rect->x + rect->w;
-        d3drect.top = rect->y;
-        d3drect.bottom = rect->y + rect->h;
-        result = IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 0);
+    if (full_texture) {
+        result = IDirect3DTexture9_LockRect(texture, 0, &locked, NULL, D3DLOCK_DISCARD);
+    } else {
+        d3drect.left = x;
+        d3drect.right = x + w;
+        d3drect.top = y;
+        d3drect.bottom = y + h;
+        result = IDirect3DTexture9_LockRect(texture, 0, &locked, &d3drect, 0);
     }
     }
 
 
     if (FAILED(result)) {
     if (FAILED(result)) {
         return D3D_SetError("LockRect()", result);
         return D3D_SetError("LockRect()", result);
     }
     }
 
 
-    src = pixels;
+    src = (const Uint8 *)pixels;
     dst = locked.pBits;
     dst = locked.pBits;
-    length = rect->w * SDL_BYTESPERPIXEL(texture->format);
+    length = w * SDL_BYTESPERPIXEL(format);
     if (length == pitch && length == locked.Pitch) {
     if (length == pitch && length == locked.Pitch) {
-        SDL_memcpy(dst, src, length*rect->h);
+        SDL_memcpy(dst, src, length*h);
     } else {
     } else {
-        for (row = 0; row < rect->h; ++row) {
+        for (row = 0; row < h; ++row) {
             SDL_memcpy(dst, src, length);
             SDL_memcpy(dst, src, length);
             src += pitch;
             src += pitch;
             dst += locked.Pitch;
             dst += locked.Pitch;
         }
         }
     }
     }
-    IDirect3DTexture9_UnlockRect(data->texture, 0);
+    IDirect3DTexture9_UnlockRect(texture, 0);
+
+    return 0;
+}
+
+static int
+D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+                  const SDL_Rect * rect, const void *pixels, int pitch)
+{
+    D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
+    SDL_bool full_texture = SDL_FALSE;
+
+#ifdef USE_DYNAMIC_TEXTURE
+    if (texture->access == SDL_TEXTUREACCESS_STREAMING &&
+        rect->x == 0 && rect->y == 0 &&
+        rect->w == texture->w && rect->h == texture->h) {
+        full_texture = SDL_TRUE;
+    }
+#endif
+
+    if (D3D_UpdateTextureInternal(data->texture, texture->format, full_texture, rect->x, rect->y, rect->w, rect->h, pixels, pitch) < 0) {
+        return -1;
+    }
+
+    if (data->yuv) {
+        /* Skip to the correct offset into the next texture */
+        pixels = (const void*)((const Uint8*)pixels + rect->h * pitch);
+
+        if (D3D_UpdateTextureInternal(texture->format == SDL_PIXELFORMAT_YV12 ? data->vtexture : data->utexture, texture->format, full_texture, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, pixels, pitch / 2) < 0) {
+            return -1;
+        }
 
 
+        /* Skip to the correct offset into the next texture */
+        pixels = (const void*)((const Uint8*)pixels + (rect->h * pitch)/4);
+        if (D3D_UpdateTextureInternal(texture->format == SDL_PIXELFORMAT_YV12 ? data->utexture : data->vtexture, texture->format, full_texture, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, pixels, pitch / 2) < 0) {
+            return -1;
+        }
+    }
     return 0;
     return 0;
 }
 }
 
 
@@ -795,17 +1022,33 @@ D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
     D3DLOCKED_RECT locked;
     D3DLOCKED_RECT locked;
     HRESULT result;
     HRESULT result;
 
 
-    d3drect.left = rect->x;
-    d3drect.right = rect->x + rect->w;
-    d3drect.top = rect->y;
-    d3drect.bottom = rect->y + rect->h;
+    if (data->yuv) {
+        // It's more efficient to upload directly...
+        if (!data->pixels) {
+            data->pitch = texture->w;
+            data->pixels = (Uint8 *)SDL_malloc((texture->h * data->pitch * 3) / 2);
+            if (!data->pixels) {
+                return SDL_OutOfMemory();
+            }
+        }
+        data->locked_rect = *rect;
+        *pixels =
+            (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
+                      rect->x * SDL_BYTESPERPIXEL(texture->format));
+        *pitch = data->pitch;
+    } else {
+        d3drect.left = rect->x;
+        d3drect.right = rect->x + rect->w;
+        d3drect.top = rect->y;
+        d3drect.bottom = rect->y + rect->h;
 
 
-    result = IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 0);
-    if (FAILED(result)) {
-        return D3D_SetError("LockRect()", result);
+        result = IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 0);
+        if (FAILED(result)) {
+            return D3D_SetError("LockRect()", result);
+        }
+        *pixels = locked.pBits;
+        *pitch = locked.Pitch;
     }
     }
-    *pixels = locked.pBits;
-    *pitch = locked.Pitch;
     return 0;
     return 0;
 }
 }
 
 
@@ -814,7 +1057,15 @@ D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
 {
 {
     D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
     D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
 
 
-    IDirect3DTexture9_UnlockRect(data->texture, 0);
+    if (data->yuv) {
+        const SDL_Rect *rect = &data->locked_rect;
+        void *pixels =
+            (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
+                      rect->x * SDL_BYTESPERPIXEL(texture->format));
+        D3D_UpdateTexture(renderer, texture, rect, pixels, data->pitch);
+    } else {
+        IDirect3DTexture9_UnlockRect(data->texture, 0);
+    }
 }
 }
 
 
 static int
 static int
@@ -902,7 +1153,7 @@ D3D_UpdateClipRect(SDL_Renderer * renderer)
         IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE, TRUE);
         IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE, TRUE);
         r.left = rect->x;
         r.left = rect->x;
         r.top = rect->y;
         r.top = rect->y;
-        r.right = rect->w + rect->w;
+        r.right = rect->x + rect->w;
         r.bottom = rect->y + rect->h;
         r.bottom = rect->y + rect->h;
 
 
         result = IDirect3DDevice9_SetScissorRect(data->device, &r);
         result = IDirect3DDevice9_SetScissorRect(data->device, &r);
@@ -979,6 +1230,12 @@ D3D_SetBlendMode(D3D_RenderData * data, int blendMode)
                                         D3DBLEND_SRCALPHA);
                                         D3DBLEND_SRCALPHA);
         IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
         IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
                                         D3DBLEND_INVSRCALPHA);
                                         D3DBLEND_INVSRCALPHA);
+        if (data->enableSeparateAlphaBlend) {
+            IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLENDALPHA,
+                                            D3DBLEND_ONE);
+            IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLENDALPHA,
+                                            D3DBLEND_INVSRCALPHA);
+        }
         break;
         break;
     case SDL_BLENDMODE_ADD:
     case SDL_BLENDMODE_ADD:
         IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
         IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
@@ -987,6 +1244,12 @@ D3D_SetBlendMode(D3D_RenderData * data, int blendMode)
                                         D3DBLEND_SRCALPHA);
                                         D3DBLEND_SRCALPHA);
         IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
         IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
                                         D3DBLEND_ONE);
                                         D3DBLEND_ONE);
+        if (data->enableSeparateAlphaBlend) {
+            IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLENDALPHA,
+                                            D3DBLEND_ZERO);
+            IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLENDALPHA,
+                                            D3DBLEND_ONE);
+        }
         break;
         break;
     case SDL_BLENDMODE_MOD:
     case SDL_BLENDMODE_MOD:
         IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
         IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
@@ -995,6 +1258,12 @@ D3D_SetBlendMode(D3D_RenderData * data, int blendMode)
                                         D3DBLEND_ZERO);
                                         D3DBLEND_ZERO);
         IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
         IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
                                         D3DBLEND_SRCCOLOR);
                                         D3DBLEND_SRCCOLOR);
+        if (data->enableSeparateAlphaBlend) {
+            IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLENDALPHA,
+                                            D3DBLEND_ZERO);
+            IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLENDALPHA,
+                                            D3DBLEND_ONE);
+        }
         break;
         break;
     }
     }
 }
 }
@@ -1169,6 +1438,18 @@ D3D_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects,
     return 0;
     return 0;
 }
 }
 
 
+static void
+D3D_UpdateTextureScaleMode(D3D_RenderData *data, D3D_TextureData *texturedata, unsigned index)
+{
+    if (texturedata->scaleMode != data->scaleMode[index]) {
+        IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_MINFILTER,
+                                         texturedata->scaleMode);
+        IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_MAGFILTER,
+                                         texturedata->scaleMode);
+        data->scaleMode[index] = texturedata->scaleMode;
+    }
+}
+
 static int
 static int
 D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
 D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
                const SDL_Rect * srcrect, const SDL_FRect * dstrect)
                const SDL_Rect * srcrect, const SDL_FRect * dstrect)
@@ -1228,13 +1509,7 @@ D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
 
 
     D3D_SetBlendMode(data, texture->blendMode);
     D3D_SetBlendMode(data, texture->blendMode);
 
 
-    if (texturedata->scaleMode != data->scaleMode) {
-        IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER,
-                                         texturedata->scaleMode);
-        IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER,
-                                         texturedata->scaleMode);
-        data->scaleMode = texturedata->scaleMode;
-    }
+    D3D_UpdateTextureScaleMode(data, texturedata, 0);
 
 
     result =
     result =
         IDirect3DDevice9_SetTexture(data->device, 0, (IDirect3DBaseTexture9 *)
         IDirect3DDevice9_SetTexture(data->device, 0, (IDirect3DBaseTexture9 *)
@@ -1242,6 +1517,28 @@ D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
     if (FAILED(result)) {
     if (FAILED(result)) {
         return D3D_SetError("SetTexture()", result);
         return D3D_SetError("SetTexture()", result);
     }
     }
+
+    if (texturedata->yuv) {
+        shader = data->ps_yuv;
+
+        D3D_UpdateTextureScaleMode(data, texturedata, 1);
+        D3D_UpdateTextureScaleMode(data, texturedata, 2);
+
+        result =
+            IDirect3DDevice9_SetTexture(data->device, 1, (IDirect3DBaseTexture9 *)
+                                        texturedata->utexture);
+        if (FAILED(result)) {
+            return D3D_SetError("SetTexture()", result);
+        }
+
+        result =
+            IDirect3DDevice9_SetTexture(data->device, 2, (IDirect3DBaseTexture9 *)
+                                        texturedata->vtexture);
+        if (FAILED(result)) {
+            return D3D_SetError("SetTexture()", result);
+        }
+    }
+
     if (shader) {
     if (shader) {
         result = IDirect3DDevice9_SetPixelShader(data->device, shader);
         result = IDirect3DDevice9_SetPixelShader(data->device, shader);
         if (FAILED(result)) {
         if (FAILED(result)) {
@@ -1348,13 +1645,7 @@ D3D_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
     ID3DXMatrixStack_Translate(data->matrixStack, (float)dstrect->x + centerx, (float)dstrect->y + centery, (float)0.0);
     ID3DXMatrixStack_Translate(data->matrixStack, (float)dstrect->x + centerx, (float)dstrect->y + centery, (float)0.0);
     IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, (D3DMATRIX*)ID3DXMatrixStack_GetTop(data->matrixStack));
     IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, (D3DMATRIX*)ID3DXMatrixStack_GetTop(data->matrixStack));
 
 
-    if (texturedata->scaleMode != data->scaleMode) {
-        IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER,
-                                         texturedata->scaleMode);
-        IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER,
-                                         texturedata->scaleMode);
-        data->scaleMode = texturedata->scaleMode;
-    }
+    D3D_UpdateTextureScaleMode(data, texturedata, 0);
 
 
     result =
     result =
         IDirect3DDevice9_SetTexture(data->device, 0, (IDirect3DBaseTexture9 *)
         IDirect3DDevice9_SetTexture(data->device, 0, (IDirect3DBaseTexture9 *)
@@ -1362,6 +1653,28 @@ D3D_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
     if (FAILED(result)) {
     if (FAILED(result)) {
         return D3D_SetError("SetTexture()", result);
         return D3D_SetError("SetTexture()", result);
     }
     }
+
+    if (texturedata->yuv) {
+        shader = data->ps_yuv;
+
+        D3D_UpdateTextureScaleMode(data, texturedata, 1);
+        D3D_UpdateTextureScaleMode(data, texturedata, 2);
+
+        result =
+            IDirect3DDevice9_SetTexture(data->device, 1, (IDirect3DBaseTexture9 *)
+                                        texturedata->utexture);
+        if (FAILED(result)) {
+            return D3D_SetError("SetTexture()", result);
+        }
+
+        result =
+            IDirect3DDevice9_SetTexture(data->device, 2, (IDirect3DBaseTexture9 *)
+                                        texturedata->vtexture);
+        if (FAILED(result)) {
+            return D3D_SetError("SetTexture()", result);
+        }
+    }
+
     if (shader) {
     if (shader) {
         result = IDirect3DDevice9_SetPixelShader(data->device, shader);
         result = IDirect3DDevice9_SetPixelShader(data->device, shader);
         if (FAILED(result)) {
         if (FAILED(result)) {
@@ -1484,6 +1797,15 @@ D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
     if (data->texture) {
     if (data->texture) {
         IDirect3DTexture9_Release(data->texture);
         IDirect3DTexture9_Release(data->texture);
     }
     }
+    if (data->utexture) {
+        IDirect3DTexture9_Release(data->utexture);
+    }
+    if (data->vtexture) {
+        IDirect3DTexture9_Release(data->vtexture);
+    }
+    if (data->pixels) {
+        SDL_free(data->pixels);
+    }
     SDL_free(data);
     SDL_free(data);
     texture->driverdata = NULL;
     texture->driverdata = NULL;
 }
 }

+ 0 - 315
Source/ThirdParty/SDL/src/render/nds/SDL_libgl2D.c

@@ -1,315 +0,0 @@
-/*
- * Note: The Nintendo DS port to SDL uses excerpts from the libGL2D,
- * with permission of the original author. The following is mostly his
- * code/comments.
- *
- *
- *	Easy GL2D
- *
- *	Relminator 2010 
- *	Richard Eric M. Lope BSN RN
- *
- *	http://rel.betterwebber.com
- *
- *	A very small and simple DS rendering lib using the 3d core to render 2D stuff
- */
-#include "SDL_config.h"
-
-#if SDL_VIDEO_RENDER_NDS
-
-#include "SDL_libgl2D.h"
-
-/*
- * Our static global variable used for Depth values since we cannot
- * disable depth testing in the DS hardware This value is incremented
- * for every draw call. */
-v16 g_depth;
-int gCurrentTexture;
-
-/*
- * !!! PRIVATE !!!  Set orthographic projection at 1:1 correspondence
- * to screen coords glOrtho expects f32 values but if we use the
- * standard f32 values, we need to rescale either every vert or the
- * modelview matrix by the same amount to make it work.  That's gonna
- * give us lots of overflows and headaches.  So we "scale down" and
- * use an all integer value.
- */
-void SetOrtho(void)		
-{
-	glMatrixMode(GL_PROJECTION); // set matrixmode to projection
-	glLoadIdentity();			   // reset
-	glOrthof32(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1 << 12, 1 << 12);  // downscale projection matrix
-}
-
-/*
- * Initializes GL in 2D mode Also initializes GL in 3d mode so that we
- * could combine 2D and 3D later Almost a direct copy from the DS
- * example files
- */
-void glScreen2D(void)
-{
-	// initialize gl
-	glInit();
-	
-	// enable textures
-	glEnable(GL_TEXTURE_2D);
-	
-	// enable antialiasing
-	glEnable(GL_ANTIALIAS);
-		
-	// setup the rear plane
-	glClearColor(0, 0, 0, 31); // BG must be opaque for AA to work
-	glClearPolyID(63); // BG must have a unique polygon ID for AA to work
-	
-	glClearDepth(GL_MAX_DEPTH);
-
-	// this should work the same as the normal gl call
-	glViewport(0,0,255,191);
-
-	// any floating point gl call is being converted to fixed prior to being implemented
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	gluPerspective(70, 256.0 / 192.0, 1, 200);
-
-	gluLookAt(	0.0, 0.0, 1.0,		//camera possition 
-				0.0, 0.0, 0.0,		//look at
-				0.0, 1.0, 0.0);		//up
-
-	glMaterialf(GL_AMBIENT, RGB15(31,31,31));
-	glMaterialf(GL_DIFFUSE, RGB15(31,31,31));
-	glMaterialf(GL_SPECULAR, BIT(15) | RGB15(31,31,31));
-	glMaterialf(GL_EMISSION, RGB15(31,31,31));
-
-	// ds uses a table for shinyness..this generates a half-ass one
-	glMaterialShinyness();
-
-	// not a real gl function and will likely change
-	glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK);
-}
-
-/*
- * Sets up OpenGL for 2d rendering Call this before drawing any of
- * GL2D's drawing or sprite functions.
- */
-void glBegin2D(void)
-{
-	// save 3d perpective projection matrix
-	glMatrixMode(GL_PROJECTION);   
-    glPushMatrix();
-	
-	// save 3d modelview matrix for safety
-	glMatrixMode(GL_MODELVIEW);
-    glPushMatrix();
-	
-	
-	// what?!! No glDisable(GL_DEPTH_TEST)?!!!!!!
-	glEnable(GL_BLEND);
-	glEnable(GL_TEXTURE_2D);
-	glDisable(GL_ANTIALIAS);	// disable AA
-	glDisable(GL_OUTLINE);	// disable edge-marking
-
-	glColor(0x7FFF);			// max color
-	
-	glPolyFmt(POLY_ALPHA(31) | POLY_CULL_NONE);  // no culling
-
-	SetOrtho();
-	
-	glMatrixMode(GL_TEXTURE);	// reset texture matrix just in case we did some funky stuff with it
-	glLoadIdentity();
-	
-	glMatrixMode(GL_MODELVIEW); // reset modelview matrix. No need to scale up by << 12
-	glLoadIdentity();
-
-	gCurrentTexture = 0;		// set current texture to 0 
-	g_depth = 0; // set depth to 0. We need this var since we cannot disable depth testing
-}
-
-/*
- * Issue this after drawing 2d so that we don't mess the matrix stack.
- * The complement of glBegin2D.
- */
-void glEnd2D(void)
-{
-	// restore 3d matrices and set current matrix to modelview
-	glMatrixMode(GL_PROJECTION);    
-    glPopMatrix(1);
-	glMatrixMode(GL_MODELVIEW);
-    glPopMatrix(1);
-}
-
-/*
- * Draws a pixel
- * Parameters:
- *   x,y 	-> First coordinate of the line 
- *   color 	-> RGB15/ARGB16 color 
- */
-void glPutPixel(int x, int y, int color)
-{
-	glBindTexture(0, 0);
-	glColor(color);
-	glBegin(GL_TRIANGLES);
-		gxVertex3i(x, y, g_depth);
-		gxVertex2i(x, y);
-		gxVertex2i(x, y);
-	glEnd();
-	glColor(0x7FFF);
-	g_depth++;
-	gCurrentTexture = 0;
-}
-
-/*
- * Draws a line
- * Parameters:
- *   x1,y1 	-> First coordinate of the line 
- *   x2,y2 	-> Second coordinate of the line 
- *   color 	-> RGB15/ARGB16 color
- */
-void glLine(int x1, int y1, int x2, int y2, int color)
-{
-	x2++;
-	y2++;
-	
-	glBindTexture(0, 0);
-	glColor(color);
-	glBegin(GL_TRIANGLES);
-		gxVertex3i(x1, y1, g_depth);
-		gxVertex2i(x2, y2);
-		gxVertex2i(x2, y2);
-	glEnd();
-	glColor(0x7FFF);
-	g_depth++;
-	gCurrentTexture = 0;
-}
-
-/*
- * Draws a Filled Box
- * Parameters:
- *   x1,y1 	-> Top-left corner of the box 
- *   x2,y2 	-> Bottom-Right corner of the box 
- *   color 	-> RGB15/ARGB16 color 
-*/
-void glBoxFilled(int x1, int y1, int x2, int y2, int color)
-{
-	x2++;
-	y2++;
-	
-	glBindTexture(0, 0);
-	glColor(color);
-	glBegin(GL_QUADS);
-		gxVertex3i(x1, y1, g_depth); // use 3i for first vertex so that we increment HW depth
-		gxVertex2i(x1, y2); // no need for 3 vertices as 2i would share last depth call
-		gxVertex2i(x2, y2);
-		gxVertex2i(x2, y1);
-	glEnd();
-	glColor(0x7FFF);
-	g_depth++;
-	gCurrentTexture = 0;
-}
-
-/*
- *
- * Create a tile.
- * Very rigid and prone to human error.
- *
- * Parameters:
- *   *sprite 		 -> pointer to a glImage
- *   texture_width   -> width/height of the texture;
- *   texture_height  ->  valid sizes are enumerated in GL_TEXTURE_TYPE_ENUM (see glTexImage2d)
- *   sprite_width
- *   sprite_height   -> width/height of the picture in the texture.
- *   type 		     -> The format of the texture (see glTexImage2d)
- *   param 		     -> parameters for the texture (see glTexImage2d)
- */
-int glLoadTile(glImage              *sprite,
-			   int                  texture_width,
-			   int                  texture_height,
-			   int                  sprite_width,
-			   int                  sprite_height,
-			   GL_TEXTURE_TYPE_ENUM type,
-			   int 	                param,
-			   int					pallette_width,
-			   const u16			*palette,
-			   const uint8          *texture)
-{
-	int textureID;
-
-	glGenTextures(1, &textureID);
-	glBindTexture(0, textureID);
-	glTexImage2D(0, 0, type, texture_width, texture_height, 0, param, texture);
-	glColorTableEXT(0, 0, pallette_width, 0, 0, palette);
-
-	sprite->width 			= sprite_width;
-	sprite->height 			= sprite_height;
-	sprite->textureID 		= textureID;
-	
-	return textureID;
-}
-
-/*
- * I made this since the scale wrappers are either the vectorized mode
- * or does not permit you to scale only the axis you want to
- * scale. Needed for sprite scaling.
- */
-static inline void gxScalef32(s32 x, s32 y, s32 z)
-{
-	MATRIX_SCALE = x;
-	MATRIX_SCALE = y;
-	MATRIX_SCALE = z;
-}
-
-/*
- * I this made for future naming conflicts.
- */
-static inline void gxTranslate3f32(int32 x, int32 y, int32 z) 
-{
-	MATRIX_TRANSLATE = x;
-	MATRIX_TRANSLATE = y;
-	MATRIX_TRANSLATE = z;
-}
-
-/*
- * Draws an axis exclusive scaled sprite
- * Parameters:
- *   x 			-> x position of the sprite
- *   y 			-> y position of the sprite
- *   scaleX   	-> 20.12 FP X axis scale value (1 << 12 is normal)
- *   scaleY   	-> 20.12 FP Y axis scale value (1 << 12 is normal)
- *   flipmode 	-> mode for flipping (see GL_FLIP_MODE enum)
- *   *spr 		-> pointer to a glImage
- */
-void glSpriteScaleXY(int x, int y, s32 scaleX, s32 scaleY, int flipmode, const glImage *spr)
-{
-	const int x1 = 0;
-	const int y1 = 0;
-	const int x2 = spr->width;
-	const int y2 = spr->height;
-	const int u1 = ((flipmode & GL_FLIP_H) ? spr->width-1  : 0);
- 	const int u2 = ((flipmode & GL_FLIP_H) ? 0 : spr->width-1);
-	const int v1 = ((flipmode & GL_FLIP_V) ? spr->height-1 : 0);
-	const int v2 = ((flipmode & GL_FLIP_V) ? 0 : spr->height-1);
- 
-    if (spr->textureID != gCurrentTexture)
-    {
-        glBindTexture(GL_TEXTURE_2D, spr->textureID);
-        gCurrentTexture = spr->textureID;
-    }
-
-	glPushMatrix();
-
-		gxTranslate3f32(x, y, 0);
-		gxScalef32(scaleX, scaleY, 1 << 12);
-
-		glBegin(GL_QUADS);
-			
-			gxTexcoord2i(u1, v1); gxVertex3i(x1, y1, g_depth);	
-			gxTexcoord2i(u1, v2); gxVertex2i(x1, y2);
-			gxTexcoord2i(u2, v2); gxVertex2i(x2, y2);
-			gxTexcoord2i(u2, v1); gxVertex2i(x2, y1);
-			
-		glEnd();
-	
-	glPopMatrix(1);
-	g_depth++;
-}
-
-#endif /* SDL_VIDEO_RENDER_NDS */

+ 0 - 154
Source/ThirdParty/SDL/src/render/nds/SDL_libgl2D.h

@@ -1,154 +0,0 @@
-/*
- * Note: The Nintendo DS port to SDL uses excerpts from the libGL2D,
- * with permission of the original author. The following is mostly his
- * code/comments.
- *
- *
- *	Easy GL2D
- *
- *	Relminator 2010 
- *	Richard Eric M. Lope BSN RN
- *
- *	http://rel.betterwebber.com
- *
- *	A very small and simple DS rendering lib using the 3d core to render 2D stuff
- */
-#include "SDL_config.h"
-
-#if SDL_VIDEO_RENDER_NDS
-
-#include <nds/arm9/videoGL.h>
-
-/* LibGL extension(s) */
-static inline void gxTexcoord2i(t16 u, t16 v)
-{
-	GFX_TEX_COORD = (v << 20) | ((u << 4) & 0xFFFF);
-}
-
-static inline void gxVertex3i(v16 x, v16 y, v16 z)
-{
-	GFX_VERTEX16 = (y << 16) | (x & 0xFFFF);
-	GFX_VERTEX16 = ((uint32)(uint16)z);
-}
-
-static inline void gxVertex2i(v16 x, v16 y)
-{
-	GFX_VERTEX_XY = (y << 16) | (x & 0xFFFF);	
-}
-
-/*
- * Enums selecting flipping mode.
- *
- *	These enums are bits for flipping the sprites.
- *	You can "|" (or) GL_FLIP_V and GL_FLIP_H to flip 
- *	both ways.
- */
-typedef enum
-{
-	GL_FLIP_NONE 	= (1 << 0), /* No flipping */
-	GL_FLIP_V 		= (1 << 1), /* Sprite is rendered vertically flipped */
-	GL_FLIP_H 		= (1 << 2), /* Sprite is rendered horizontally flipped */
-} GL_FLIP_MODE;
-
-/* Struct for out GL-Based Images. */
-typedef struct 
-{
-	int		width;		/* Width of the Sprite */      			
-	int 	height;		/* Height of the Sprite */	
-	int		textureID;  /* Texture handle (used in glDeleteTextures())
-						   The texture handle in VRAM (returned by glGenTextures())
-						   ie. This references the actual texture stored in VRAM. */
-} glImage;
-
-extern v16 g_depth;
-extern int gCurrentTexture;
-
-/*
- * Draws an Axis Exclusive Scaled Sprite
- * Parameters:
- *   x X position of the sprite.
- *   y Y position of the sprite.
- *   scaleX 20.12 fixed-point X-Axis scale value (1 << 12 is normal).
- *   scaleY 20.12 fixed-point Y-Axis scale value (1 << 12 is normal).
- *   flipmode mode for flipping (see GL_FLIP_MODE enum).
- *   *spr pointer to a glImage. 
-*/
-void glSpriteScaleXY(int x, int y, s32 scaleX, s32 scaleY, int flipmode, const glImage *spr);
-
-/* Initializes our Tileset (like glInitSpriteset()) but without the use of Texture Packer auto-generated files.
- * Can only be used when tiles in a tilset are of the same dimensions.
- * Parameters:
- *   *sprite Pointer to an array of glImage.
- *   tile_wid Width of each tile in the texture.
- *   tile_hei Height of each tile in the texture.
- *   bmp_wid Width of of the texture or tileset.
- *   bmp_hei height of of the texture or tileset.
- *   type The format of the texture (see glTexImage2d()).
- *   sizeX The horizontal size of the texture; valid sizes are enumerated in GL_TEXTURE_TYPE_ENUM (see glTexImage2d()).
- *   sizeY The vertical size of the texture; valid sizes are enumerated in GL_TEXTURE_TYPE_ENUM (see glTexImage2d()).
- *   param parameters for the texture (see glTexImage2d()). 
- *   pallette_width Length of the palette. Valid values are <b>4, 16, 32, 256</b> (if <b>0</b>, then palette is removed from currently bound texture). 
- *   *palette Pointer to the palette data to load (if NULL, then palette is removed from currently bound texture).
- *   *texture Pointer to the texture data to load.
-*/
-int glLoadTile(glImage              *sprite,
-			   int                  texture_width,
-			   int                  texture_height,
-			   int                  sprite_width,
-			   int                  sprite_height,
-			   GL_TEXTURE_TYPE_ENUM type,
-			   int 	                param,
-			   int					pallette_width,
-			   const u16			*palette,
-			   const uint8          *texture);
-
-/* Initializes GL in 2D mode */
-void glScreen2D(void);
-
-/* 
- * Sets up OpenGL for 2d rendering. 
- *
- * Call this before drawing any of GL2D's drawing or sprite functions.
- */
-void glBegin2D(void);
-
-/*
- * Issue this after drawing 2d so that we don't mess the matrix stack.
- *
- * The complement of glBegin2D().
- */
-void glEnd2D(void);
-
-/*
- * Draws a Pixel
- *   x X position of the pixel.
- *   y Y position of the pixel.
- *   color RGB15/ARGB16 color.
- */
-void glPutPixel(int x, int y, int color);
-
-/*
- * Draws a Line
- *   x1,y1 Top-Left coordinate of the line.
- *   x2,y2 Bottom-Right coordinate of the line.
- *   color RGB15/ARGB16 color.
- */
-void glLine(int x1, int y1, int x2, int y2, int color);
-
-/* 
- * Draws a Box
- *   x1,y1 Top-Left coordinate of the box.
- *   x2,y2 Bottom-Right coordinate of the box.
- *   color RGB15/ARGB16 color.
-*/
-void glBox(int x1, int y1, int x2, int y2, int color);
-
-/*
- * Draws a Filled Box
- *   x1,y1 Top-Left coordinate of the box.
- *   x2,y2 Bottom-Right coordinate of the box.
- *   color RGB15/ARGB16 color.
- */
-void glBoxFilled(int x1, int y1, int x2, int y2, int color);
-
-#endif /* SDL_VIDEO_RENDER_NDS */

+ 0 - 418
Source/ThirdParty/SDL/src/render/nds/SDL_ndsrender.c

@@ -1,418 +0,0 @@
-/*
-  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.
-*/
-#include "SDL_config.h"
-
-#if SDL_VIDEO_RENDER_NDS
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <nds.h>
-
-#include "SDL_libgl2D.h"
-
-#include "SDL_video.h"
-#include "../../video/SDL_sysvideo.h"
-#include "SDL_render.h"
-#include "../SDL_sysrender.h"
-#include "SDL_log.h"
-
-/* Draws a partial sprite. Based on glSprite. */
-static void glSpritePartial(const SDL_Rect * srcrect, int x, int y, int flipmode, const glImage *spr)
-{
-	int x1 = x;
-	int y1 = y;
-	int x2 = x + srcrect->w;
-	int y2 = y + srcrect->h;
-
-	int	u1 = srcrect->x + ((flipmode & GL_FLIP_H) ? spr->width-1  : 0);
- 	int	u2 = srcrect->x + ((flipmode & GL_FLIP_H) ? 0 : srcrect->h);
-	int v1 = srcrect->y + ((flipmode & GL_FLIP_V) ? spr->height-1 : 0);
- 	int v2 = srcrect->y + ((flipmode & GL_FLIP_V) ? 0 : srcrect->h);
-
-    if (spr->textureID != gCurrentTexture) {
-        glBindTexture(GL_TEXTURE_2D, spr->textureID);
-        gCurrentTexture = spr->textureID;
-    }
-
-	glBegin(GL_QUADS);
-		
-		gxTexcoord2i(u1, v1); gxVertex3i(x1, y1, g_depth);	
-		gxTexcoord2i(u1, v2); gxVertex2i(x1, y2);
-		gxTexcoord2i(u2, v2); gxVertex2i(x2, y2);
-		gxTexcoord2i(u2, v1); gxVertex2i(x2, y1);
-		
-	glEnd();
-	
-	g_depth++;
-}
-
-/* SDL NDS renderer implementation */
-
-extern SDL_RenderDriver NDS_RenderDriver;
-
-typedef struct
-{
-	/* Whether current 3D engine is on the main or sub screen. */
-	int is_sub;
-} NDS_RenderData;
-
-typedef struct
-{
-	glImage image[1];
-} NDS_TextureData;
-
-static int NDS_UpdateViewport(SDL_Renderer *renderer)
-{
-	/* Nothing to do. */
-	return 0;
-}
-
-static int
-NDS_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
-               const SDL_Rect * srcrect, const SDL_Rect * dstrect)
-{
-    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
-    NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
-	int dest_y;
-
-	if (data->is_sub) {
-		dest_y = dstrect->y;
-	} else {
-		dest_y = dstrect->y-SCREEN_HEIGHT;
-	}
-
-	if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) {
-		/* No scaling */
-		glSpritePartial(srcrect, dstrect->x, dest_y, GL_FLIP_NONE, txdat->image);
-	} else {
-		/* Convert the scaling proportion into a 20.12 value. */
-		s32 scale_w = divf32(dstrect->w << 12, texture->w << 12);
-		s32 scale_h = divf32(dstrect->h << 12, texture->h << 12);
-
-		glSpriteScaleXY(dstrect->x, dest_y, scale_w, scale_h, GL_FLIP_NONE, txdat->image);
-	}
-
-    return 0;
-}
-
-static int NDS_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
-{
-    NDS_TextureData *txdat = NULL;
-    int i;
-
-	SDL_Log("NDS_CreateTexture: NDS_CreateTexture.\n");
-
-	/* Sanity checks. */
-	for (i=0; i<NDS_RenderDriver.info.num_texture_formats; i++) {
-		if (texture->format == NDS_RenderDriver.info.texture_formats[i])
-			break;
-	}
-	if (i == NDS_RenderDriver.info.num_texture_formats) {
-		SDL_SetError("Unsupported texture format (%x)", texture->format);
-		return -1;
-	}
-
-	if (texture->w > NDS_RenderDriver.info.max_texture_width) {
-		SDL_SetError("Texture too large (%d)", texture->w);
-		return -1;
-	}
-
-	if (texture->h > NDS_RenderDriver.info.max_texture_height) {
-		SDL_SetError("Texture too tall (%d)", texture->h);
-		return -1;
-	}
-
-	texture->driverdata = SDL_calloc(1, sizeof(NDS_TextureData));
-	txdat = (NDS_TextureData *) texture->driverdata;
-	if (!txdat) {
-		SDL_OutOfMemory();
-		return -1;
-	}
-
-    return 0;
-}
-
-static void
-NDS_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
-{
-    NDS_TextureData *txdat = texture->driverdata;
-
-    /* free anything else allocated for texture */
-    SDL_free(txdat);
-}
-
-/* size is no more than 512. */
-static int get_gltexture_size(unsigned int size)
-{
-	if (size > 256)
-		return TEXTURE_SIZE_512;
-	else if (size > 128)
-		return TEXTURE_SIZE_256;
-	else if (size > 64)
-		return TEXTURE_SIZE_128;
-	else if (size > 32)
-		return TEXTURE_SIZE_64;
-	else if (size > 16)
-		return TEXTURE_SIZE_32;
-	else if (size > 8)
-		return TEXTURE_SIZE_16;
-	else
-		return TEXTURE_SIZE_8;
-}
-
-static int NDS_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
-							 const SDL_Rect * rect, const void *pixels, int pitch)
-{
-    NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
-	char *new_pixels = NULL;
-	const int gl_w = get_gltexture_size(rect->w);
-	const int gl_h = get_gltexture_size(rect->h);
-	const int w = 1 << (3+gl_w);	/* Texture sizes must be a power of 2. */
-	const int h = 1 << (3+gl_h);	/* Texture sizes must be a power of 2. */
-
-	if (w != rect->w || h != rect->h) {
-		/* Allocate a temporary surface and copy pixels into it while
-		 * enlarging the pitch. */
-		const char *src;
-		char *dst;
-		int new_pitch = 2 * w;
-		int i;
-
-		new_pixels = malloc(2 * w * h);
-		if (!new_pixels)
-			return SDL_ENOMEM;
-
-		src = pixels;
-		dst = new_pixels;
-		for (i=0; i<rect->h; i++) {
-			memcpy(dst, src, pitch);
-			src += pitch;
-			dst += new_pitch;
-		}
-	}
-
-	glLoadTile(txdat->image,
-				  gl_w, gl_h,
-				  rect->w, rect->h,
-				  texture->format == SDL_PIXELFORMAT_ABGR1555 ? GL_RGBA : GL_RGB,
-				  TEXGEN_OFF, 0, NULL,
-				  new_pixels? new_pixels : pixels);
-
-	if (new_pixels)
-		free(new_pixels);
-
-    return 0;
-}
-
-static int NDS_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
-						   const SDL_Rect *rect, void **pixels, int *pitch)
-{
-	SDL_Log("enter %s (todo)\n", __func__);
-
-    return 0;
-}
-
-static void NDS_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture)
-{
-	SDL_Log("enter %s\n", __func__);
-    /* stub! */
-}
-
-static int NDS_RenderClear(SDL_Renderer *renderer)
-{
-    glClearColor(renderer->r >> 3,
-                 renderer->g >> 3,
-                 renderer->b >> 3,
-                 renderer->a >> 3);
-
-	return 0;
-}
-
-static void NDS_RenderPresent(SDL_Renderer * renderer)
-{
-    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
-
-	glEnd2D();
-		
-	glFlush(0);
-
-	swiWaitForVBlank();
-
-	/* wait for capture unit to be ready */
-	while(REG_DISPCAPCNT & DCAP_ENABLE);
-
-	/* 3D engine can only work on one screen at a time. */
-	data->is_sub = !data->is_sub;
-	if (data->is_sub) {
-		lcdMainOnBottom();
-		vramSetBankC(VRAM_C_LCD);
-		vramSetBankD(VRAM_D_SUB_SPRITE);
-		REG_DISPCAPCNT = DCAP_BANK(2) | DCAP_ENABLE | DCAP_SIZE(3);
-	} else {
-		lcdMainOnTop();
-		vramSetBankD(VRAM_D_LCD);
-		vramSetBankC(VRAM_C_SUB_BG);
-		REG_DISPCAPCNT = DCAP_BANK(3) | DCAP_ENABLE | DCAP_SIZE(3);
-	}
-
-	glBegin2D();
-}
-
-static int NDS_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points,
-								int count)
-{
-    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
-	int i;
-	int color = RGB15(renderer->r >> 3,
-					  renderer->g >> 3,
-					  renderer->b >> 3);
-
-	for (i=0; i < count; i++) {
-		if (data->is_sub) {
-			glPutPixel(points[i].x, points[i].y, color);
-		} else {
-			glPutPixel(points[i].x, points[i].y - SCREEN_HEIGHT, color);
-		}
-	}
-
-	return 0;
-}
-
-static int NDS_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points,
-							   int count)
-{
-    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
-	int i;
-	int color = RGB15(renderer->r >> 3,
-					  renderer->g >> 3,
-					  renderer->b >> 3);
-
-	for (i=0; i < count-1; i++) {
-		if (data->is_sub) {
-			glLine(points[i].x, points[i].y, points[i+1].x, points[i+1].y, color);
-		} else {
-			glLine(points[i].x, points[i].y - SCREEN_HEIGHT, 
-				   points[i+1].x, points[i+1].y - SCREEN_HEIGHT, color);
-		}
-	}
-
-	return 0;
-}
-
-static int NDS_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect *rects,
-							   int count)
-{
-    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
-	int i;
-	int color = RGB15(renderer->r >> 3,
-					  renderer->g >> 3,
-					  renderer->b >> 3);
-
-	for (i=0; i<count; i++) {
-		if (data->is_sub) {
-			glBoxFilled(rects[i].x, rects[i].y, 
-						rects[i].x + rects[i].w,
-						rects[i].y + rects[i].h, color);
-	} else {
-			glBoxFilled(rects[i].x, rects[i].y - SCREEN_HEIGHT,
-						rects[i].x + rects[i].w,
-						rects[i].y + rects[i].h - SCREEN_HEIGHT,
-						color);
-		}
-	}
-
-	return 0;
-}
-
-static SDL_Renderer *
-NDS_CreateRenderer(SDL_Window * window, Uint32 flags)
-{
-    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
-    SDL_DisplayMode *displayMode = &display->current_mode;
-    SDL_Renderer *renderer;
-    NDS_RenderData *data;
-    int bpp;
-    Uint32 Rmask, Gmask, Bmask, Amask;
-
-	if (displayMode->format != SDL_PIXELFORMAT_ABGR1555) {
-		SDL_SetError("Unsupported pixel format (%x)", displayMode->format);
-		return NULL;
-	}
-
-    if (!SDL_PixelFormatEnumToMasks(displayMode->format, &bpp,
-                                    &Rmask, &Gmask, &Bmask, &Amask)) {
-        SDL_SetError("Unknown display format");
-        return NULL;
-    }
-
-    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
-    if (!renderer) {
-        SDL_OutOfMemory();
-        return NULL;
-    }
-
-    data = (NDS_RenderData *) SDL_calloc(1, sizeof(*data));
-    if (!data) {
-        SDL_free(renderer);
-        SDL_OutOfMemory();
-        return NULL;
-    }
-
-    renderer->info = NDS_RenderDriver.info;
-    renderer->info.flags = SDL_RENDERER_ACCELERATED;
-
-	renderer->CreateTexture = NDS_CreateTexture;
-	renderer->UpdateTexture = NDS_UpdateTexture;
-	renderer->LockTexture = NDS_LockTexture;
-	renderer->UnlockTexture = NDS_UnlockTexture;
-	renderer->UpdateViewport = NDS_UpdateViewport;
-	renderer->RenderClear = NDS_RenderClear;
-	renderer->RenderDrawPoints = NDS_RenderDrawPoints;
-	renderer->RenderDrawLines = NDS_RenderDrawLines;
-	renderer->RenderFillRects = NDS_RenderFillRects;
-	renderer->RenderCopy = NDS_RenderCopy;
-	/* renderer->RenderReadPixels = NDS_RenderReadPixels; - todo ? */
-	renderer->RenderPresent = NDS_RenderPresent;
-	renderer->DestroyTexture = NDS_DestroyTexture;
-	/* renderer->DestroyRenderer = NDS_DestroyRenderer; - todo ? */
-
-	renderer->driverdata = data;
-
-    return renderer;
-}
-
-SDL_RenderDriver NDS_RenderDriver = {
-	.CreateRenderer = NDS_CreateRenderer,
-    .info = {
-		.name = "nds",
-		.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC,
-		.num_texture_formats = 2,
-		.texture_formats = { [0] = SDL_PIXELFORMAT_ABGR1555,
-							 [1] = SDL_PIXELFORMAT_BGR555,
-		},
-		.max_texture_width = 512,
-		.max_texture_height = 512,
-     }
-};
-
-#endif /* SDL_VIDEO_RENDER_NDS */
-
-/* vi: set ts=4 sw=4 expandtab: */

+ 1 - 0
Source/ThirdParty/SDL/src/render/opengl/SDL_glfuncs.h

@@ -15,6 +15,7 @@ SDL_PROC_UNUSED(void, glBitmap,
                 (GLsizei, GLsizei, GLfloat, GLfloat, GLfloat, GLfloat,
                 (GLsizei, GLsizei, GLfloat, GLfloat, GLfloat, GLfloat,
                  const GLubyte *))
                  const GLubyte *))
 SDL_PROC(void, glBlendFunc, (GLenum, GLenum))
 SDL_PROC(void, glBlendFunc, (GLenum, GLenum))
+SDL_PROC(void, glBlendFuncSeparate, (GLenum, GLenum, GLenum, GLenum))
 SDL_PROC_UNUSED(void, glCallList, (GLuint))
 SDL_PROC_UNUSED(void, glCallList, (GLuint))
 SDL_PROC_UNUSED(void, glCallLists, (GLsizei, GLenum, const GLvoid *))
 SDL_PROC_UNUSED(void, glCallLists, (GLsizei, GLenum, const GLvoid *))
 SDL_PROC(void, glClear, (GLbitfield))
 SDL_PROC(void, glClear, (GLbitfield))

+ 11 - 6
Source/ThirdParty/SDL/src/render/opengl/SDL_render_gl.c

@@ -277,7 +277,6 @@ GL_ActivateRenderer(SDL_Renderer * renderer)
 {
 {
     GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
     GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
 
 
-    GL_ClearErrors(renderer);
     if (SDL_CurrentContext != data->context) {
     if (SDL_CurrentContext != data->context) {
         if (SDL_GL_MakeCurrent(renderer->window, data->context) < 0) {
         if (SDL_GL_MakeCurrent(renderer->window, data->context) < 0) {
             return -1;
             return -1;
@@ -286,6 +285,9 @@ GL_ActivateRenderer(SDL_Renderer * renderer)
 
 
         GL_UpdateViewport(renderer);
         GL_UpdateViewport(renderer);
     }
     }
+
+    GL_ClearErrors(renderer);
+
     return 0;
     return 0;
 }
 }
 
 
@@ -631,6 +633,10 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
 
 
     GL_CheckError("", renderer);
     GL_CheckError("", renderer);
     renderdata->glGenTextures(1, &data->texture);
     renderdata->glGenTextures(1, &data->texture);
+    if (GL_CheckError("glGenTexures()", renderer) < 0) {
+        SDL_free(data);
+        return -1;
+    }
     if ((renderdata->GL_ARB_texture_rectangle_supported)
     if ((renderdata->GL_ARB_texture_rectangle_supported)
         /*&& texture->access != SDL_TEXTUREACCESS_TARGET*/){
         /*&& texture->access != SDL_TEXTUREACCESS_TARGET*/){
         data->type = GL_TEXTURE_RECTANGLE_ARB;
         data->type = GL_TEXTURE_RECTANGLE_ARB;
@@ -922,17 +928,17 @@ GL_SetBlendMode(GL_RenderData * data, int blendMode)
         case SDL_BLENDMODE_BLEND:
         case SDL_BLENDMODE_BLEND:
             data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
             data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
             data->glEnable(GL_BLEND);
             data->glEnable(GL_BLEND);
-            data->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+            data->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
             break;
             break;
         case SDL_BLENDMODE_ADD:
         case SDL_BLENDMODE_ADD:
             data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
             data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
             data->glEnable(GL_BLEND);
             data->glEnable(GL_BLEND);
-            data->glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+            data->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE);
             break;
             break;
         case SDL_BLENDMODE_MOD:
         case SDL_BLENDMODE_MOD:
             data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
             data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
             data->glEnable(GL_BLEND);
             data->glEnable(GL_BLEND);
-            data->glBlendFunc(GL_ZERO, GL_SRC_COLOR);
+            data->glBlendFuncSeparate(GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE);
             break;
             break;
         }
         }
         data->current.blendMode = blendMode;
         data->current.blendMode = blendMode;
@@ -1233,7 +1239,6 @@ GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
                     Uint32 pixel_format, void * pixels, int pitch)
                     Uint32 pixel_format, void * pixels, int pitch)
 {
 {
     GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
     GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
-    SDL_Window *window = renderer->window;
     Uint32 temp_format = SDL_PIXELFORMAT_ARGB8888;
     Uint32 temp_format = SDL_PIXELFORMAT_ARGB8888;
     void *temp_pixels;
     void *temp_pixels;
     int temp_pitch;
     int temp_pitch;
@@ -1253,7 +1258,7 @@ GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
 
 
     convert_format(data, temp_format, &internalFormat, &format, &type);
     convert_format(data, temp_format, &internalFormat, &format, &type);
 
 
-    SDL_GetWindowSize(window, &w, &h);
+    SDL_GetRendererOutputSize(renderer, &w, &h);
 
 
     data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
     data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
     data->glPixelStorei(GL_PACK_ROW_LENGTH,
     data->glPixelStorei(GL_PACK_ROW_LENGTH,

+ 1 - 0
Source/ThirdParty/SDL/src/render/opengles/SDL_glesfuncs.h

@@ -1,5 +1,6 @@
 SDL_PROC(void, glBindTexture, (GLenum, GLuint))
 SDL_PROC(void, glBindTexture, (GLenum, GLuint))
 SDL_PROC(void, glBlendFunc, (GLenum, GLenum))
 SDL_PROC(void, glBlendFunc, (GLenum, GLenum))
+SDL_PROC(void, glBlendFuncSeparateOES, (GLenum, GLenum, GLenum, GLenum))
 SDL_PROC(void, glClear, (GLbitfield))
 SDL_PROC(void, glClear, (GLbitfield))
 SDL_PROC(void, glClearColor, (GLclampf, GLclampf, GLclampf, GLclampf))
 SDL_PROC(void, glClearColor, (GLclampf, GLclampf, GLclampf, GLclampf))
 SDL_PROC(void, glColor4f, (GLfloat, GLfloat, GLfloat, GLfloat))
 SDL_PROC(void, glColor4f, (GLfloat, GLfloat, GLfloat, GLfloat))

+ 26 - 5
Source/ThirdParty/SDL/src/render/opengles/SDL_render_gles.c

@@ -121,6 +121,7 @@ typedef struct
 
 
     SDL_bool useDrawTexture;
     SDL_bool useDrawTexture;
     SDL_bool GL_OES_draw_texture_supported;
     SDL_bool GL_OES_draw_texture_supported;
+    SDL_bool GL_OES_blend_func_separate_supported;
 } GLES_RenderData;
 } GLES_RenderData;
 
 
 typedef struct
 typedef struct
@@ -376,6 +377,10 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
     }
     }
     data->framebuffers = NULL;
     data->framebuffers = NULL;
 
 
+    if (SDL_GL_ExtensionSupported("GL_OES_blend_func_separate")) {
+        data->GL_OES_blend_func_separate_supported = SDL_TRUE;
+    }
+
     /* Set up parameters for rendering */
     /* Set up parameters for rendering */
     GLES_ResetState(renderer);
     GLES_ResetState(renderer);
 
 
@@ -470,6 +475,11 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
     renderdata->glGetError();
     renderdata->glGetError();
     renderdata->glEnable(GL_TEXTURE_2D);
     renderdata->glEnable(GL_TEXTURE_2D);
     renderdata->glGenTextures(1, &data->texture);
     renderdata->glGenTextures(1, &data->texture);
+    result = renderdata->glGetError();
+    if (result != GL_NO_ERROR) {
+        SDL_free(data);
+        return GLES_SetError("glGenTextures()", result);
+    }
 
 
     data->type = GL_TEXTURE_2D;
     data->type = GL_TEXTURE_2D;
     /* no NPOV textures allowed in OpenGL ES (yet) */
     /* no NPOV textures allowed in OpenGL ES (yet) */
@@ -680,17 +690,29 @@ GLES_SetBlendMode(GLES_RenderData * data, int blendMode)
         case SDL_BLENDMODE_BLEND:
         case SDL_BLENDMODE_BLEND:
             data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
             data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
             data->glEnable(GL_BLEND);
             data->glEnable(GL_BLEND);
-            data->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+            if (data->GL_OES_blend_func_separate_supported) {
+                data->glBlendFuncSeparateOES(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+            } else {
+                data->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+            }
             break;
             break;
         case SDL_BLENDMODE_ADD:
         case SDL_BLENDMODE_ADD:
             data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
             data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
             data->glEnable(GL_BLEND);
             data->glEnable(GL_BLEND);
-            data->glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+            if (data->GL_OES_blend_func_separate_supported) {
+                data->glBlendFuncSeparateOES(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE);
+            } else {
+                data->glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+            }
             break;
             break;
         case SDL_BLENDMODE_MOD:
         case SDL_BLENDMODE_MOD:
             data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
             data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
             data->glEnable(GL_BLEND);
             data->glEnable(GL_BLEND);
-            data->glBlendFunc(GL_ZERO, GL_SRC_COLOR);
+            if (data->GL_OES_blend_func_separate_supported) {
+                data->glBlendFuncSeparateOES(GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE);
+            } else {
+                data->glBlendFunc(GL_ZERO, GL_SRC_COLOR);
+            }
             break;
             break;
         }
         }
         data->current.blendMode = blendMode;
         data->current.blendMode = blendMode;
@@ -1006,7 +1028,6 @@ GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
                     Uint32 pixel_format, void * pixels, int pitch)
                     Uint32 pixel_format, void * pixels, int pitch)
 {
 {
     GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
     GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
-    SDL_Window *window = renderer->window;
     Uint32 temp_format = SDL_PIXELFORMAT_ABGR8888;
     Uint32 temp_format = SDL_PIXELFORMAT_ABGR8888;
     void *temp_pixels;
     void *temp_pixels;
     int temp_pitch;
     int temp_pitch;
@@ -1022,7 +1043,7 @@ GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
         return SDL_OutOfMemory();
         return SDL_OutOfMemory();
     }
     }
 
 
-    SDL_GetWindowSize(window, &w, &h);
+    SDL_GetRendererOutputSize(renderer, &w, &h);
 
 
     data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
     data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
 
 

+ 1 - 1
Source/ThirdParty/SDL/src/render/opengles2/SDL_gles2funcs.h

@@ -2,7 +2,7 @@ SDL_PROC(void, glActiveTexture, (GLenum))
 SDL_PROC(void, glAttachShader, (GLuint, GLuint))
 SDL_PROC(void, glAttachShader, (GLuint, GLuint))
 SDL_PROC(void, glBindAttribLocation, (GLuint, GLuint, const char *))
 SDL_PROC(void, glBindAttribLocation, (GLuint, GLuint, const char *))
 SDL_PROC(void, glBindTexture, (GLenum, GLuint))
 SDL_PROC(void, glBindTexture, (GLenum, GLuint))
-SDL_PROC(void, glBlendFunc, (GLenum, GLenum))
+SDL_PROC(void, glBlendFuncSeparate, (GLenum, GLenum, GLenum, GLenum))
 SDL_PROC(void, glClear, (GLbitfield))
 SDL_PROC(void, glClear, (GLbitfield))
 SDL_PROC(void, glClearColor, (GLclampf, GLclampf, GLclampf, GLclampf))
 SDL_PROC(void, glClearColor, (GLclampf, GLclampf, GLclampf, GLclampf))
 SDL_PROC(void, glCompileShader, (GLuint))
 SDL_PROC(void, glCompileShader, (GLuint))

+ 11 - 9
Source/ThirdParty/SDL/src/render/opengles2/SDL_render_gles2.c

@@ -418,6 +418,10 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
     /* Allocate the texture */
     /* Allocate the texture */
     rdata->glGetError();
     rdata->glGetError();
     rdata->glGenTextures(1, &tdata->texture);
     rdata->glGenTextures(1, &tdata->texture);
+    if (rdata->glGetError() != GL_NO_ERROR) {
+        SDL_free(tdata);
+        return SDL_SetError("Texture creation failed in glGenTextures()");
+    }
     rdata->glActiveTexture(GL_TEXTURE0);
     rdata->glActiveTexture(GL_TEXTURE0);
     rdata->glBindTexture(tdata->texture_type, tdata->texture);
     rdata->glBindTexture(tdata->texture_type, tdata->texture);
     rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode);
     rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode);
@@ -425,8 +429,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
     rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     rdata->glTexImage2D(tdata->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL);
     rdata->glTexImage2D(tdata->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL);
-    if (rdata->glGetError() != GL_NO_ERROR)
-    {
+    if (rdata->glGetError() != GL_NO_ERROR) {
         rdata->glDeleteTextures(1, &tdata->texture);
         rdata->glDeleteTextures(1, &tdata->texture);
         SDL_free(tdata);
         SDL_free(tdata);
         return SDL_SetError("Texture creation failed");
         return SDL_SetError("Texture creation failed");
@@ -994,15 +997,15 @@ GLES2_SetBlendMode(GLES2_DriverContext *rdata, int blendMode)
             break;
             break;
         case SDL_BLENDMODE_BLEND:
         case SDL_BLENDMODE_BLEND:
             rdata->glEnable(GL_BLEND);
             rdata->glEnable(GL_BLEND);
-            rdata->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+            rdata->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
             break;
             break;
         case SDL_BLENDMODE_ADD:
         case SDL_BLENDMODE_ADD:
             rdata->glEnable(GL_BLEND);
             rdata->glEnable(GL_BLEND);
-            rdata->glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+            rdata->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE);
             break;
             break;
         case SDL_BLENDMODE_MOD:
         case SDL_BLENDMODE_MOD:
             rdata->glEnable(GL_BLEND);
             rdata->glEnable(GL_BLEND);
-            rdata->glBlendFunc(GL_ZERO, GL_SRC_COLOR);
+            rdata->glBlendFuncSeparate(GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE);
             break;
             break;
         }
         }
         rdata->current.blendMode = blendMode;
         rdata->current.blendMode = blendMode;
@@ -1086,7 +1089,7 @@ GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_FPoint *points, int cou
     rdata->glDrawArrays(GL_POINTS, 0, count);
     rdata->glDrawArrays(GL_POINTS, 0, count);
     SDL_stack_free(vertices);
     SDL_stack_free(vertices);
     if (rdata->glGetError() != GL_NO_ERROR) {
     if (rdata->glGetError() != GL_NO_ERROR) {
-        return SDL_SetError("Failed to render lines");
+        return SDL_SetError("Failed to render points");
     }
     }
     return 0;
     return 0;
 }
 }
@@ -1160,7 +1163,7 @@ GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
         rdata->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
         rdata->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
     }
     }
     if (rdata->glGetError() != GL_NO_ERROR) {
     if (rdata->glGetError() != GL_NO_ERROR) {
-        return SDL_SetError("Failed to render lines");
+        return SDL_SetError("Failed to render filled rects");
     }
     }
     return 0;
     return 0;
 }
 }
@@ -1508,7 +1511,6 @@ GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
                     Uint32 pixel_format, void * pixels, int pitch)
                     Uint32 pixel_format, void * pixels, int pitch)
 {
 {
     GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
     GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
-    SDL_Window *window = renderer->window;
     Uint32 temp_format = SDL_PIXELFORMAT_ABGR8888;
     Uint32 temp_format = SDL_PIXELFORMAT_ABGR8888;
     void *temp_pixels;
     void *temp_pixels;
     int temp_pitch;
     int temp_pitch;
@@ -1524,7 +1526,7 @@ GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
         return SDL_OutOfMemory();
         return SDL_OutOfMemory();
     }
     }
 
 
-    SDL_GetWindowSize(window, &w, &h);
+    SDL_GetRendererOutputSize(renderer, &w, &h);
 
 
     rdata->glPixelStorei(GL_PACK_ALIGNMENT, 1);
     rdata->glPixelStorei(GL_PACK_ALIGNMENT, 1);
 
 

+ 0 - 2
Source/ThirdParty/SDL/src/render/software/SDL_render_sw.c

@@ -114,8 +114,6 @@ SW_ActivateRenderer(SDL_Renderer * renderer)
         SDL_Surface *surface = SDL_GetWindowSurface(renderer->window);
         SDL_Surface *surface = SDL_GetWindowSurface(renderer->window);
         if (surface) {
         if (surface) {
             data->surface = data->window = surface;
             data->surface = data->window = surface;
-            renderer->viewport.w = surface->w;
-            renderer->viewport.h = surface->h;
 
 
             SW_UpdateViewport(renderer);
             SW_UpdateViewport(renderer);
             SW_UpdateClipRect(renderer);
             SW_UpdateClipRect(renderer);

+ 12 - 6
Source/ThirdParty/SDL/src/stdlib/SDL_getenv.c

@@ -31,9 +31,12 @@ static size_t SDL_envmemlen = 0;
 
 
 
 
 /* Put a variable into the environment */
 /* Put a variable into the environment */
-#ifdef SDL_setenv
-#undef SDL_setenv
-int SDL_setenv(const char *name, const char *value, int overwrite) { return SDL_setenv_inline(name, value, overwrite); }
+#if defined(HAVE_SETENV)
+int
+SDL_setenv(const char *name, const char *value, int overwrite)
+{
+    return setenv(name, value, overwrite);
+}
 #elif defined(__WIN32__)
 #elif defined(__WIN32__)
 int
 int
 SDL_setenv(const char *name, const char *value, int overwrite)
 SDL_setenv(const char *name, const char *value, int overwrite)
@@ -143,9 +146,12 @@ SDL_setenv(const char *name, const char *value, int overwrite)
 #endif
 #endif
 
 
 /* Retrieve a variable named "name" from the environment */
 /* Retrieve a variable named "name" from the environment */
-#ifdef SDL_getenv
-#undef SDL_getenv
-char *SDL_getenv(const char *name) { return SDL_getenv_inline(name); }
+#if defined(HAVE_GETENV)
+char *
+SDL_getenv(const char *name)
+{
+    return getenv(name);
+}
 #elif defined(__WIN32__)
 #elif defined(__WIN32__)
 char *
 char *
 SDL_getenv(const char *name)
 SDL_getenv(const char *name)

+ 4 - 4
Source/ThirdParty/SDL/src/stdlib/SDL_iconv.c

@@ -364,7 +364,7 @@ SDL_iconv(SDL_iconv_t cd,
                          */
                          */
                         ch = UNKNOWN_UNICODE;
                         ch = UNKNOWN_UNICODE;
                     } else {
                     } else {
-                        if (p[0] == 0xFC) {
+                        if (p[0] == 0xFC && srclen > 1 && (p[1] & 0xFC) == 0x80) {
                             overlong = SDL_TRUE;
                             overlong = SDL_TRUE;
                         }
                         }
                         ch = (Uint32) (p[0] & 0x01);
                         ch = (Uint32) (p[0] & 0x01);
@@ -377,7 +377,7 @@ SDL_iconv(SDL_iconv_t cd,
                          */
                          */
                         ch = UNKNOWN_UNICODE;
                         ch = UNKNOWN_UNICODE;
                     } else {
                     } else {
-                        if (p[0] == 0xF8) {
+                        if (p[0] == 0xF8 && srclen > 1 && (p[1] & 0xF8) == 0x80) {
                             overlong = SDL_TRUE;
                             overlong = SDL_TRUE;
                         }
                         }
                         ch = (Uint32) (p[0] & 0x03);
                         ch = (Uint32) (p[0] & 0x03);
@@ -390,7 +390,7 @@ SDL_iconv(SDL_iconv_t cd,
                          */
                          */
                         ch = UNKNOWN_UNICODE;
                         ch = UNKNOWN_UNICODE;
                     } else {
                     } else {
-                        if (p[0] == 0xF0) {
+                        if (p[0] == 0xF0 && srclen > 1 && (p[1] & 0xF0) == 0x80) {
                             overlong = SDL_TRUE;
                             overlong = SDL_TRUE;
                         }
                         }
                         ch = (Uint32) (p[0] & 0x07);
                         ch = (Uint32) (p[0] & 0x07);
@@ -403,7 +403,7 @@ SDL_iconv(SDL_iconv_t cd,
                          */
                          */
                         ch = UNKNOWN_UNICODE;
                         ch = UNKNOWN_UNICODE;
                     } else {
                     } else {
-                        if (p[0] == 0xE0) {
+                        if (p[0] == 0xE0 && srclen > 1 && (p[1] & 0xE0) == 0x80) {
                             overlong = SDL_TRUE;
                             overlong = SDL_TRUE;
                         }
                         }
                         ch = (Uint32) (p[0] & 0x0F);
                         ch = (Uint32) (p[0] & 0x0F);

+ 21 - 10
Source/ThirdParty/SDL/src/stdlib/SDL_malloc.c

@@ -24,16 +24,27 @@
 
 
 #include "SDL_stdinc.h"
 #include "SDL_stdinc.h"
 
 
-#ifdef SDL_malloc
-/* expose the symbol, but use what we figured out elsewhere. */
-#undef SDL_malloc
-#undef SDL_calloc
-#undef SDL_realloc
-#undef SDL_free
-void *SDL_malloc(size_t size) { return SDL_malloc_inline(size); }
-void *SDL_calloc(size_t nmemb, size_t size) { return SDL_calloc_inline(nmemb, size); }
-void *SDL_realloc(void *ptr, size_t size) { return SDL_realloc_inline(ptr, size); }
-void SDL_free(void *ptr) { SDL_free_inline(ptr); }
+#if defined(HAVE_MALLOC)
+
+void *SDL_malloc(size_t size)
+{
+    return malloc(size);
+}
+
+void *SDL_calloc(size_t nmemb, size_t size)
+{
+    return calloc(nmemb, size);
+}
+
+void *SDL_realloc(void *ptr, size_t size)
+{
+    return realloc(ptr, size);
+}
+
+void SDL_free(void *ptr)
+{
+    free(ptr);
+}
 
 
 #else  /* the rest of this is a LOT of tapdancing to implement malloc. :) */
 #else  /* the rest of this is a LOT of tapdancing to implement malloc. :) */
 
 

+ 2 - 3
Source/ThirdParty/SDL/src/stdlib/SDL_qsort.c

@@ -51,12 +51,11 @@
 #include "SDL_stdinc.h"
 #include "SDL_stdinc.h"
 #include "SDL_assert.h"
 #include "SDL_assert.h"
 
 
-#ifdef SDL_qsort
-#undef SDL_qsort
+#if defined(HAVE_QSORT)
 void
 void
 SDL_qsort(void *base, size_t nmemb, size_t size, int (*compare) (const void *, const void *))
 SDL_qsort(void *base, size_t nmemb, size_t size, int (*compare) (const void *, const void *))
 {
 {
-    SDL_qsort_inline(base, nmemb, size, compare);
+    qsort(base, nmemb, size, compare);
 }
 }
 #else
 #else
 
 

+ 123 - 686
Source/ThirdParty/SDL/src/stdlib/SDL_stdlib.c

@@ -18,744 +18,181 @@
      misrepresented as being the original software.
      misrepresented as being the original software.
   3. This notice may not be removed or altered from any source distribution.
   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_config.h"
 
 
 /* This file contains portable stdlib functions for SDL */
 /* This file contains portable stdlib functions for SDL */
 
 
 #include "SDL_stdinc.h"
 #include "SDL_stdinc.h"
+#include "../libm/math_libm.h"
 
 
-/* these are always #defined, make them real symbol in the library, too... */
-#undef SDL_ceil
-#undef SDL_abs
-#undef SDL_sinf
-#undef SDL_cosf
-#undef SDL_isdigit
-#undef SDL_isspace
-#undef SDL_toupper
-#undef SDL_tolower
-double SDL_ceil(double x) { return SDL_ceil_inline(x); }
-float SDL_cosf(float x) { return SDL_cosf_inline(x); }
-float SDL_sinf(float x) { return SDL_sinf_inline(x); }
-int SDL_abs(int x) { return SDL_abs_inline(x); }
-int SDL_isdigit(int x) { return SDL_isdigit_inline(x); }
-int SDL_isspace(int x) { return SDL_isspace_inline(x); }
-int SDL_toupper(int x) { return SDL_toupper_inline(x); }
-int SDL_tolower(int x) { return SDL_tolower_inline(x); }
-
-
-#ifndef HAVE_LIBC
-/* These are some C runtime intrinsics that need to be defined */
-
-#if defined(_MSC_VER)
-
-#ifndef __FLTUSED__
-#define __FLTUSED__
-__declspec(selectany) int _fltused = 1;
-#endif
-
-/* The optimizer on Visual Studio 2010/2012 generates memcpy() calls */
-#if _MSC_VER >= 1600 && defined(_WIN64) && !defined(_DEBUG)
-#include <intrin.h>
 
 
-#pragma function(memcpy)
-void * memcpy ( void * destination, const void * source, size_t num )
+double
+SDL_atan(double x)
 {
 {
-    const Uint8 *src = (const Uint8 *)source;
-    Uint8 *dst = (Uint8 *)destination;
-    size_t i;
-    
-    /* All WIN64 architectures have SSE, right? */
-    if (!((uintptr_t) src & 15) && !((uintptr_t) dst & 15)) {
-        __m128 values[4];
-        for (i = num / 64; i--;) {
-            _mm_prefetch(src, _MM_HINT_NTA);
-            values[0] = *(__m128 *) (src + 0);
-            values[1] = *(__m128 *) (src + 16);
-            values[2] = *(__m128 *) (src + 32);
-            values[3] = *(__m128 *) (src + 48);
-            _mm_stream_ps((float *) (dst + 0), values[0]);
-            _mm_stream_ps((float *) (dst + 16), values[1]);
-            _mm_stream_ps((float *) (dst + 32), values[2]);
-            _mm_stream_ps((float *) (dst + 48), values[3]);
-            src += 64;
-            dst += 64;
-        }
-        num &= 63;
-    }
-
-    while (num--) {
-        *dst++ = *src++;
-    }
-    return destination;
+#ifdef HAVE_ATAN
+    return atan(x);
+#else
+    return SDL_uclibc_atan(x);
+#endif /* HAVE_ATAN */
 }
 }
-#endif /* _MSC_VER == 1600 && defined(_WIN64) && !defined(_DEBUG) */
 
 
-#ifdef _M_IX86
+double
+SDL_atan2(double x, double y)
+{
+#if defined(HAVE_ATAN2)
+    return atan2(x, y);
+#else
+    return SDL_uclibc_atan2(x, y);
+#endif /* HAVE_ATAN2 */
+}
 
 
-void
-__declspec(naked)
-_chkstk()
+double
+SDL_ceil(double x)
 {
 {
+#ifdef HAVE_CEIL
+    return ceil(x);
+#else
+    return (double)(int)((x)+0.5);
+#endif /* HAVE_CEIL */
 }
 }
 
 
-/* Float to long */
-void
-__declspec(naked)
-_ftol()
+double
+SDL_copysign(double x, double y)
 {
 {
-    /* *INDENT-OFF* */
-    __asm {
-        push        ebp
-        mov         ebp,esp
-        sub         esp,20h
-        and         esp,0FFFFFFF0h
-        fld         st(0)
-        fst         dword ptr [esp+18h]
-        fistp       qword ptr [esp+10h]
-        fild        qword ptr [esp+10h]
-        mov         edx,dword ptr [esp+18h]
-        mov         eax,dword ptr [esp+10h]
-        test        eax,eax
-        je          integer_QnaN_or_zero
-arg_is_not_integer_QnaN:
-        fsubp       st(1),st
-        test        edx,edx
-        jns         positive
-        fstp        dword ptr [esp]
-        mov         ecx,dword ptr [esp]
-        xor         ecx,80000000h
-        add         ecx,7FFFFFFFh
-        adc         eax,0
-        mov         edx,dword ptr [esp+14h]
-        adc         edx,0
-        jmp         localexit
-positive:
-        fstp        dword ptr [esp]
-        mov         ecx,dword ptr [esp]
-        add         ecx,7FFFFFFFh
-        sbb         eax,0
-        mov         edx,dword ptr [esp+14h]
-        sbb         edx,0
-        jmp         localexit
-integer_QnaN_or_zero:
-        mov         edx,dword ptr [esp+14h]
-        test        edx,7FFFFFFFh
-        jne         arg_is_not_integer_QnaN
-        fstp        dword ptr [esp+18h]
-        fstp        dword ptr [esp+18h]
-localexit:
-        leave
-        ret
-    }
-    /* *INDENT-ON* */
+#if defined(HAVE_COPYSIGN)
+    return copysign(x, y);
+#else
+    return SDL_uclibc_copysign(x, y);
+#endif /* HAVE_COPYSIGN */
 }
 }
 
 
-void
-_ftol2_sse()
+double
+SDL_cos(double x)
 {
 {
-    _ftol();
+#if defined(HAVE_COS)
+    return cos(x);
+#else
+    return SDL_uclibc_cos(x);
+#endif /* HAVE_COS */
 }
 }
 
 
-/* 64-bit math operators for 32-bit systems */
-void
-__declspec(naked)
-_allmul()
+float
+SDL_cosf(float x)
 {
 {
-    /* *INDENT-OFF* */
-    __asm {
-        push        ebp
-        mov         ebp,esp
-        push        edi
-        push        esi
-        push        ebx
-        sub         esp,0Ch
-        mov         eax,dword ptr [ebp+10h]
-        mov         edi,dword ptr [ebp+8]
-        mov         ebx,eax
-        mov         esi,eax
-        sar         esi,1Fh
-        mov         eax,dword ptr [ebp+8]
-        mul         ebx
-        imul        edi,esi
-        mov         ecx,edx
-        mov         dword ptr [ebp-18h],eax
-        mov         edx,dword ptr [ebp+0Ch]
-        add         ecx,edi
-        imul        ebx,edx
-        mov         eax,dword ptr [ebp-18h]
-        lea         ebx,[ebx+ecx]
-        mov         dword ptr [ebp-14h],ebx
-        mov         edx,dword ptr [ebp-14h]
-        add         esp,0Ch
-        pop         ebx
-        pop         esi
-        pop         edi
-        pop         ebp
-        ret         10h
-    }
-    /* *INDENT-ON* */
+#ifdef HAVE_COSF
+    return cosf(x);
+#else
+    return (float)SDL_cos((double)x);
+#endif
 }
 }
 
 
-void
-__declspec(naked)
-_alldiv()
+double
+SDL_fabs(double x)
 {
 {
-    /* *INDENT-OFF* */
-    __asm {
-        push        edi
-        push        esi
-        push        ebx
-        xor         edi,edi
-        mov         eax,dword ptr [esp+14h]
-        or          eax,eax
-        jge         L1
-        inc         edi
-        mov         edx,dword ptr [esp+10h]
-        neg         eax
-        neg         edx
-        sbb         eax,0
-        mov         dword ptr [esp+14h],eax
-        mov         dword ptr [esp+10h],edx
-L1:
-        mov         eax,dword ptr [esp+1Ch]
-        or          eax,eax
-        jge         L2
-        inc         edi
-        mov         edx,dword ptr [esp+18h]
-        neg         eax
-        neg         edx
-        sbb         eax,0
-        mov         dword ptr [esp+1Ch],eax
-        mov         dword ptr [esp+18h],edx
-L2:
-        or          eax,eax
-        jne         L3
-        mov         ecx,dword ptr [esp+18h]
-        mov         eax,dword ptr [esp+14h]
-        xor         edx,edx
-        div         ecx
-        mov         ebx,eax
-        mov         eax,dword ptr [esp+10h]
-        div         ecx
-        mov         edx,ebx
-        jmp         L4
-L3:
-        mov         ebx,eax
-        mov         ecx,dword ptr [esp+18h]
-        mov         edx,dword ptr [esp+14h]
-        mov         eax,dword ptr [esp+10h]
-L5:
-        shr         ebx,1
-        rcr         ecx,1
-        shr         edx,1
-        rcr         eax,1
-        or          ebx,ebx
-        jne         L5
-        div         ecx
-        mov         esi,eax
-        mul         dword ptr [esp+1Ch]
-        mov         ecx,eax
-        mov         eax,dword ptr [esp+18h]
-        mul         esi
-        add         edx,ecx
-        jb          L6
-        cmp         edx,dword ptr [esp+14h]
-        ja          L6
-        jb          L7
-        cmp         eax,dword ptr [esp+10h]
-        jbe         L7
-L6:
-        dec         esi
-L7:
-        xor         edx,edx
-        mov         eax,esi
-L4:
-        dec         edi
-        jne         L8
-        neg         edx
-        neg         eax
-        sbb         edx,0
-L8:
-        pop         ebx
-        pop         esi
-        pop         edi
-        ret         10h
-    }
-    /* *INDENT-ON* */
+#if defined(HAVE_FABS)
+    return fabs(x); 
+#else
+    return SDL_uclibc_fabs(x);
+#endif /* HAVE_FABS */
 }
 }
 
 
-void
-__declspec(naked)
-_aulldiv()
+double
+SDL_floor(double x)
 {
 {
-    /* *INDENT-OFF* */
-    __asm {
-        push        ebx
-        push        esi
-        mov         eax,dword ptr [esp+18h]
-        or          eax,eax
-        jne         L1
-        mov         ecx,dword ptr [esp+14h]
-        mov         eax,dword ptr [esp+10h]
-        xor         edx,edx
-        div         ecx
-        mov         ebx,eax
-        mov         eax,dword ptr [esp+0Ch]
-        div         ecx
-        mov         edx,ebx
-        jmp         L2
-L1:
-        mov         ecx,eax
-        mov         ebx,dword ptr [esp+14h]
-        mov         edx,dword ptr [esp+10h]
-        mov         eax,dword ptr [esp+0Ch]
-L3:
-        shr         ecx,1
-        rcr         ebx,1
-        shr         edx,1
-        rcr         eax,1
-        or          ecx,ecx
-        jne         L3
-        div         ebx
-        mov         esi,eax
-        mul         dword ptr [esp+18h]
-        mov         ecx,eax
-        mov         eax,dword ptr [esp+14h]
-        mul         esi
-        add         edx,ecx
-        jb          L4
-        cmp         edx,dword ptr [esp+10h]
-        ja          L4
-        jb          L5
-        cmp         eax,dword ptr [esp+0Ch]
-        jbe         L5
-L4:
-        dec         esi
-L5:
-        xor         edx,edx
-        mov         eax,esi
-L2:
-        pop         esi
-        pop         ebx
-        ret         10h
-    }
-    /* *INDENT-ON* */
+#if defined(HAVE_FLOOR)
+    return floor(x);
+#else
+    return SDL_uclibc_floor(x);
+#endif /* HAVE_FLOOR */
 }
 }
 
 
-void
-__declspec(naked)
-_allrem()
+double
+SDL_log(double x)
 {
 {
-    /* *INDENT-OFF* */
-    __asm {
-        push        ebx
-        push        edi
-        xor         edi,edi
-        mov         eax,dword ptr [esp+10h]
-        or          eax,eax
-        jge         L1
-        inc         edi
-        mov         edx,dword ptr [esp+0Ch]
-        neg         eax
-        neg         edx
-        sbb         eax,0
-        mov         dword ptr [esp+10h],eax
-        mov         dword ptr [esp+0Ch],edx
-L1:
-        mov         eax,dword ptr [esp+18h]
-        or          eax,eax
-        jge         L2
-        mov         edx,dword ptr [esp+14h]
-        neg         eax
-        neg         edx
-        sbb         eax,0
-        mov         dword ptr [esp+18h],eax
-        mov         dword ptr [esp+14h],edx
-L2:
-        or          eax,eax
-        jne         L3
-        mov         ecx,dword ptr [esp+14h]
-        mov         eax,dword ptr [esp+10h]
-        xor         edx,edx
-        div         ecx
-        mov         eax,dword ptr [esp+0Ch]
-        div         ecx
-        mov         eax,edx
-        xor         edx,edx
-        dec         edi
-        jns         L4
-        jmp         L8
-L3:
-        mov         ebx,eax
-        mov         ecx,dword ptr [esp+14h]
-        mov         edx,dword ptr [esp+10h]
-        mov         eax,dword ptr [esp+0Ch]
-L5:
-        shr         ebx,1
-        rcr         ecx,1
-        shr         edx,1
-        rcr         eax,1
-        or          ebx,ebx
-        jne         L5
-        div         ecx
-        mov         ecx,eax
-        mul         dword ptr [esp+18h]
-        xchg        eax,ecx
-        mul         dword ptr [esp+14h]
-        add         edx,ecx
-        jb          L6
-        cmp         edx,dword ptr [esp+10h]
-        ja          L6
-        jb          L7
-        cmp         eax,dword ptr [esp+0Ch]
-        jbe         L7
-L6:
-        sub         eax,dword ptr [esp+14h]
-        sbb         edx,dword ptr [esp+18h]
-L7:
-        sub         eax,dword ptr [esp+0Ch]
-        sbb         edx,dword ptr [esp+10h]
-        dec         edi
-        jns         L8
-L4:
-        neg         edx
-        neg         eax
-        sbb         edx,0
-L8:
-        pop         edi
-        pop         ebx
-        ret         10h
-    }
-    /* *INDENT-ON* */
+#if defined(HAVE_LOG)
+    return log(x);
+#else
+    return SDL_uclibc_log(x);
+#endif /* HAVE_LOG */
 }
 }
 
 
-void
-__declspec(naked)
-_aullrem()
+double
+SDL_pow(double x, double y)
 {
 {
-    /* *INDENT-OFF* */
-    __asm {
-        push        ebx
-        mov         eax,dword ptr [esp+14h]
-        or          eax,eax
-        jne         L1
-        mov         ecx,dword ptr [esp+10h]
-        mov         eax,dword ptr [esp+0Ch]
-        xor         edx,edx
-        div         ecx
-        mov         eax,dword ptr [esp+8]
-        div         ecx
-        mov         eax,edx
-        xor         edx,edx
-        jmp         L2
-L1:
-        mov         ecx,eax
-        mov         ebx,dword ptr [esp+10h]
-        mov         edx,dword ptr [esp+0Ch]
-        mov         eax,dword ptr [esp+8]
-L3:
-        shr         ecx,1
-        rcr         ebx,1
-        shr         edx,1
-        rcr         eax,1
-        or          ecx,ecx
-        jne         L3
-        div         ebx
-        mov         ecx,eax
-        mul         dword ptr [esp+14h]
-        xchg        eax,ecx
-        mul         dword ptr [esp+10h]
-        add         edx,ecx
-        jb          L4
-        cmp         edx,dword ptr [esp+0Ch]
-        ja          L4
-        jb          L5
-        cmp         eax,dword ptr [esp+8]
-        jbe         L5
-L4:
-        sub         eax,dword ptr [esp+10h]
-        sbb         edx,dword ptr [esp+14h]
-L5:
-        sub         eax,dword ptr [esp+8]
-        sbb         edx,dword ptr [esp+0Ch]
-        neg         edx
-        neg         eax
-        sbb         edx,0
-L2:
-        pop         ebx
-        ret         10h
-    }
-    /* *INDENT-ON* */
+#if defined(HAVE_POW)
+    return pow(x, y);
+#else
+    return SDL_uclibc_pow(x, y);
+#endif /* HAVE_POW */
 }
 }
 
 
-void
-__declspec(naked)
-_alldvrm()
+double
+SDL_scalbn(double x, int n)
 {
 {
-    /* *INDENT-OFF* */
-    __asm {
-        push        edi
-        push        esi
-        push        ebp
-        xor         edi,edi
-        xor         ebp,ebp
-        mov         eax,dword ptr [esp+14h]
-        or          eax,eax
-        jge         L1
-        inc         edi
-        inc         ebp
-        mov         edx,dword ptr [esp+10h]
-        neg         eax
-        neg         edx
-        sbb         eax,0
-        mov         dword ptr [esp+14h],eax
-        mov         dword ptr [esp+10h],edx
-L1:
-        mov         eax,dword ptr [esp+1Ch]
-        or          eax,eax
-        jge         L2
-        inc         edi
-        mov         edx,dword ptr [esp+18h]
-        neg         eax
-        neg         edx
-        sbb         eax,0
-        mov         dword ptr [esp+1Ch],eax
-        mov         dword ptr [esp+18h],edx
-L2:
-        or          eax,eax
-        jne         L3
-        mov         ecx,dword ptr [esp+18h]
-        mov         eax,dword ptr [esp+14h]
-        xor         edx,edx
-        div         ecx
-        mov         ebx,eax
-        mov         eax,dword ptr [esp+10h]
-        div         ecx
-        mov         esi,eax
-        mov         eax,ebx
-        mul         dword ptr [esp+18h]
-        mov         ecx,eax
-        mov         eax,esi
-        mul         dword ptr [esp+18h]
-        add         edx,ecx
-        jmp         L4
-L3:
-        mov         ebx,eax
-        mov         ecx,dword ptr [esp+18h]
-        mov         edx,dword ptr [esp+14h]
-        mov         eax,dword ptr [esp+10h]
-L5:
-        shr         ebx,1
-        rcr         ecx,1
-        shr         edx,1
-        rcr         eax,1
-        or          ebx,ebx
-        jne         L5
-        div         ecx
-        mov         esi,eax
-        mul         dword ptr [esp+1Ch]
-        mov         ecx,eax
-        mov         eax,dword ptr [esp+18h]
-        mul         esi
-        add         edx,ecx
-        jb          L6
-        cmp         edx,dword ptr [esp+14h]
-        ja          L6
-        jb          L7
-        cmp         eax,dword ptr [esp+10h]
-        jbe         L7
-L6:
-        dec         esi
-        sub         eax,dword ptr [esp+18h]
-        sbb         edx,dword ptr [esp+1Ch]
-L7:
-        xor         ebx,ebx
-L4:
-        sub         eax,dword ptr [esp+10h]
-        sbb         edx,dword ptr [esp+14h]
-        dec         ebp
-        jns         L9
-        neg         edx
-        neg         eax
-        sbb         edx,0
-L9:
-        mov         ecx,edx
-        mov         edx,ebx
-        mov         ebx,ecx
-        mov         ecx,eax
-        mov         eax,esi
-        dec         edi
-        jne         L8
-        neg         edx
-        neg         eax
-        sbb         edx,0
-L8:
-        pop         ebp
-        pop         esi
-        pop         edi
-        ret         10h
-    }
-    /* *INDENT-ON* */
+#if defined(HAVE_SCALBN)
+    return scalbn(x, n);
+#else
+    return SDL_uclibc_scalbn(x, n);
+#endif /* HAVE_SCALBN */
 }
 }
 
 
-void
-__declspec(naked)
-_aulldvrm()
+double
+SDL_sin(double x)
 {
 {
-    /* *INDENT-OFF* */
-    __asm {
-        push        esi
-        mov         eax,dword ptr [esp+14h]
-        or          eax,eax
-        jne         L1
-        mov         ecx,dword ptr [esp+10h]
-        mov         eax,dword ptr [esp+0Ch]
-        xor         edx,edx
-        div         ecx
-        mov         ebx,eax
-        mov         eax,dword ptr [esp+8]
-        div         ecx
-        mov         esi,eax
-        mov         eax,ebx
-        mul         dword ptr [esp+10h]
-        mov         ecx,eax
-        mov         eax,esi
-        mul         dword ptr [esp+10h]
-        add         edx,ecx
-        jmp         L2
-L1:
-        mov         ecx,eax
-        mov         ebx,dword ptr [esp+10h]
-        mov         edx,dword ptr [esp+0Ch]
-        mov         eax,dword ptr [esp+8]
-L3:
-        shr         ecx,1
-        rcr         ebx,1
-        shr         edx,1
-        rcr         eax,1
-        or          ecx,ecx
-        jne         L3
-        div         ebx
-        mov         esi,eax
-        mul         dword ptr [esp+14h]
-        mov         ecx,eax
-        mov         eax,dword ptr [esp+10h]
-        mul         esi
-        add         edx,ecx
-        jb          L4
-        cmp         edx,dword ptr [esp+0Ch]
-        ja          L4
-        jb          L5
-        cmp         eax,dword ptr [esp+8]
-        jbe         L5
-L4:
-        dec         esi
-        sub         eax,dword ptr [esp+10h]
-        sbb         edx,dword ptr [esp+14h]
-L5:
-        xor         ebx,ebx
-L2:
-        sub         eax,dword ptr [esp+8]
-        sbb         edx,dword ptr [esp+0Ch]
-        neg         edx
-        neg         eax
-        sbb         edx,0
-        mov         ecx,edx
-        mov         edx,ebx
-        mov         ebx,ecx
-        mov         ecx,eax
-        mov         eax,esi
-        pop         esi
-        ret         10h
-    }
-    /* *INDENT-ON* */
+#if defined(HAVE_SIN)
+    return sin(x);
+#else
+    return SDL_uclibc_sin(x);
+#endif /* HAVE_SIN */
 }
 }
 
 
-void
-__declspec(naked)
-_allshl()
+float 
+SDL_sinf(float x)
 {
 {
-    /* *INDENT-OFF* */
-    __asm {
-        cmp         cl,40h
-        jae         RETZERO
-        cmp         cl,20h
-        jae         MORE32
-        shld        edx,eax,cl
-        shl         eax,cl
-        ret
-MORE32:
-        mov         edx,eax
-        xor         eax,eax
-        and         cl,1Fh
-        shl         edx,cl
-        ret
-RETZERO:
-        xor         eax,eax
-        xor         edx,edx
-        ret
-    }
-    /* *INDENT-ON* */
+#ifdef HAVE_SINF
+    return sinf(x);
+#else
+    return (float)SDL_sin((double)x);
+#endif /* HAVE_SINF */
 }
 }
 
 
-void
-__declspec(naked)
-_allshr()
+double
+SDL_sqrt(double x)
 {
 {
-    /* *INDENT-OFF* */
-    __asm {
-        cmp         cl,40h
-        jae         RETZERO
-        cmp         cl,20h
-        jae         MORE32
-        shrd        eax,edx,cl
-        sar         edx,cl
-        ret
-MORE32:
-        mov         eax,edx
-        xor         edx,edx
-        and         cl,1Fh
-        sar         eax,cl
-        ret
-RETZERO:
-        xor         eax,eax
-        xor         edx,edx
-        ret
-    }
-    /* *INDENT-ON* */
+#if defined(HAVE_SQRT)
+    return sqrt(x);
+#else
+    return SDL_uclibc_sqrt(x);
+#endif
 }
 }
 
 
-void
-__declspec(naked)
-_aullshr()
+int SDL_abs(int x)
 {
 {
-    /* *INDENT-OFF* */
-    __asm {
-        cmp         cl,40h
-        jae         RETZERO
-        cmp         cl,20h
-        jae         MORE32
-        shrd        eax,edx,cl
-        shr         edx,cl
-        ret
-MORE32:
-        mov         eax,edx
-        xor         edx,edx
-        and         cl,1Fh
-        shr         eax,cl
-        ret
-RETZERO:
-        xor         eax,eax
-        xor         edx,edx
-        ret
-    }
-    /* *INDENT-ON* */
+#ifdef HAVE_ABS
+    return abs(x);
+#else
+    return ((x) < 0 ? -(x) : (x));
+#endif
 }
 }
 
 
-#endif /* _M_IX86 */
+#ifdef HAVE_CTYPE_H
+int SDL_isdigit(int x) { return isdigit(x); }
+int SDL_isspace(int x) { return isspace(x); }
+int SDL_toupper(int x) { return toupper(x); }
+int SDL_tolower(int x) { return tolower(x); }
+#else
+int SDL_isdigit(int x) { return ((x) >= '0') && ((x) <= '9'); }
+int SDL_isspace(int x) { return ((x) == ' ') || ((x) == '\t') || ((x) == '\r') || ((x) == '\n') || ((x) == '\f') || ((x) == '\v'); }
+int SDL_toupper(int x) { return ((x) >= 'a') && ((x) <= 'z') ? ('A'+((x)-'a')) : (x); }
+int SDL_tolower(int x) { return ((x) >= 'A') && ((x) <= 'Z') ? ('a'+((x)-'A')) : (x); }
+#endif
 
 
-#endif /* MSC_VER */
 
 
+#ifndef HAVE_LIBC
+// Urho3D: disable MSVC runtime intrinsic replacements
 #endif /* !HAVE_LIBC */
 #endif /* !HAVE_LIBC */
 
 
 /* vi: set ts=4 sw=4 expandtab: */
 /* vi: set ts=4 sw=4 expandtab: */

+ 248 - 245
Source/ThirdParty/SDL/src/stdlib/SDL_string.c

@@ -18,26 +18,12 @@
      misrepresented as being the original software.
      misrepresented as being the original software.
   3. This notice may not be removed or altered from any source distribution.
   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_config.h"
 
 
 /* This file contains portable string manipulation functions for SDL */
 /* This file contains portable string manipulation functions for SDL */
 
 
 #include "SDL_stdinc.h"
 #include "SDL_stdinc.h"
 
 
-/* these are always #defined, make them real symbol in the library, too... */
-#undef SDL_itoa
-#undef SDL_uitoa
-#undef SDL_atoi
-#undef SDL_atof
-char *SDL_itoa(int value, char *str, int radix) { return SDL_itoa_inline(value, str, radix); }
-char *SDL_uitoa(unsigned int value, char *str, int radix) { return SDL_uitoa_inline(value, str, radix); }
-int SDL_atoi(const char *str) { return SDL_atoi_inline(str); }
-double SDL_atof(const char *str) { return SDL_atof_inline(str); }
-
-
 
 
 #define SDL_isupperhex(X)   (((X) >= 'A') && ((X) <= 'F'))
 #define SDL_isupperhex(X)   (((X) >= 'A') && ((X) <= 'F'))
 #define SDL_islowerhex(X)   (((X) >= 'a') && ((X) <= 'f'))
 #define SDL_islowerhex(X)   (((X) >= 'a') && ((X) <= 'f'))
@@ -57,7 +43,7 @@ static int UTF8_TrailingBytes(unsigned char c)
         return 0;
         return 0;
 }
 }
 
 
-#if !defined(SDL_sscanf) || !defined(SDL_strtol)
+#if !defined(HAVE_SSCANF) || !defined(HAVE_STRTOL)
 static size_t
 static size_t
 SDL_ScanLong(const char *text, int radix, long *valuep)
 SDL_ScanLong(const char *text, int radix, long *valuep)
 {
 {
@@ -98,7 +84,7 @@ SDL_ScanLong(const char *text, int radix, long *valuep)
 }
 }
 #endif
 #endif
 
 
-#if !defined(SDL_sscanf) || !defined(SDL_strtoul) || !defined(SDL_strtod)
+#if !defined(HAVE_SSCANF) || !defined(HAVE_STRTOUL) || !defined(HAVE_STRTOD)
 static size_t
 static size_t
 SDL_ScanUnsignedLong(const char *text, int radix, unsigned long *valuep)
 SDL_ScanUnsignedLong(const char *text, int radix, unsigned long *valuep)
 {
 {
@@ -130,7 +116,7 @@ SDL_ScanUnsignedLong(const char *text, int radix, unsigned long *valuep)
 }
 }
 #endif
 #endif
 
 
-#ifndef SDL_sscanf
+#ifndef HAVE_SSCANF
 static size_t
 static size_t
 SDL_ScanUintPtrT(const char *text, int radix, uintptr_t * valuep)
 SDL_ScanUintPtrT(const char *text, int radix, uintptr_t * valuep)
 {
 {
@@ -162,7 +148,7 @@ SDL_ScanUintPtrT(const char *text, int radix, uintptr_t * valuep)
 }
 }
 #endif
 #endif
 
 
-#if !defined(SDL_sscanf) || !defined(SDL_strtoll)
+#if !defined(HAVE_SSCANF) || !defined(HAVE_STRTOLL)
 static size_t
 static size_t
 SDL_ScanLongLong(const char *text, int radix, Sint64 * valuep)
 SDL_ScanLongLong(const char *text, int radix, Sint64 * valuep)
 {
 {
@@ -203,7 +189,7 @@ SDL_ScanLongLong(const char *text, int radix, Sint64 * valuep)
 }
 }
 #endif
 #endif
 
 
-#if !defined(SDL_sscanf) || !defined(SDL_strtoull)
+#if !defined(HAVE_SSCANF) || !defined(HAVE_STRTOULL)
 static size_t
 static size_t
 SDL_ScanUnsignedLongLong(const char *text, int radix, Uint64 * valuep)
 SDL_ScanUnsignedLongLong(const char *text, int radix, Uint64 * valuep)
 {
 {
@@ -235,7 +221,7 @@ SDL_ScanUnsignedLongLong(const char *text, int radix, Uint64 * valuep)
 }
 }
 #endif
 #endif
 
 
-#if !defined(SDL_sscanf) || !defined(SDL_strtod)
+#if !defined(HAVE_SSCANF) || !defined(HAVE_STRTOD)
 static size_t
 static size_t
 SDL_ScanFloat(const char *text, double *valuep)
 SDL_ScanFloat(const char *text, double *valuep)
 {
 {
@@ -271,14 +257,12 @@ SDL_ScanFloat(const char *text, double *valuep)
 }
 }
 #endif
 #endif
 
 
-
-#ifdef SDL_memset
-#undef SDL_memset
-void *SDL_memset(void *dst, int c, size_t len) { return SDL_memset_inline(dst, c, len); }
-#else
 void *
 void *
 SDL_memset(void *dst, int c, size_t len)
 SDL_memset(void *dst, int c, size_t len)
 {
 {
+#if defined(HAVE_MEMSET)
+    return memset(dst, c, len);
+#else
     size_t left = (len % 4);
     size_t left = (len % 4);
     Uint32 *dstp4;
     Uint32 *dstp4;
     Uint8 *dstp1;
     Uint8 *dstp1;
@@ -302,14 +286,9 @@ SDL_memset(void *dst, int c, size_t len)
     }
     }
 
 
     return dst;
     return dst;
+#endif /* HAVE_MEMSET */
 }
 }
-#endif
-
 
 
-#ifdef SDL_memcpy
-#undef SDL_memcpy
-void *SDL_memcpy(void *dst, const void *src, size_t len) { return SDL_memcpy_inline(dst, src, len); }
-#else
 void *
 void *
 SDL_memcpy(void *dst, const void *src, size_t len)
 SDL_memcpy(void *dst, const void *src, size_t len)
 {
 {
@@ -318,6 +297,11 @@ SDL_memcpy(void *dst, const void *src, size_t len)
        On my machine this is twice as fast as the C code below.
        On my machine this is twice as fast as the C code below.
      */
      */
     return __builtin_memcpy(dst, src, len);
     return __builtin_memcpy(dst, src, len);
+#elif defined(HAVE_MEMCPY)
+    return memcpy(dst, src, len);
+#elif defined(HAVE_BCOPY)
+    bcopy(src, dst, len);
+    return dst;
 #else
 #else
     /* GCC 4.9.0 with -O3 will generate movaps instructions with the loop
     /* GCC 4.9.0 with -O3 will generate movaps instructions with the loop
        using Uint32* pointers, so we need to make sure the pointers are
        using Uint32* pointers, so we need to make sure the pointers are
@@ -357,16 +341,13 @@ SDL_memcpy(void *dst, const void *src, size_t len)
     return dst;
     return dst;
 #endif /* __GNUC__ */
 #endif /* __GNUC__ */
 }
 }
-#endif
-
 
 
-#ifdef SDL_memmove
-#undef SDL_memmove
-void *SDL_memmove(void *dst, const void *src, size_t len) { return SDL_memmove_inline(dst, src, len); }
-#else
 void *
 void *
 SDL_memmove(void *dst, const void *src, size_t len)
 SDL_memmove(void *dst, const void *src, size_t len)
 {
 {
+#if defined(HAVE_MEMMOVE)
+    return memmove(dst, src, len);
+#else
     char *srcp = (char *) src;
     char *srcp = (char *) src;
     char *dstp = (char *) dst;
     char *dstp = (char *) dst;
 
 
@@ -382,16 +363,15 @@ SDL_memmove(void *dst, const void *src, size_t len)
         }
         }
     }
     }
     return dst;
     return dst;
+#endif /* HAVE_MEMMOVE */
 }
 }
-#endif
 
 
-#ifdef SDL_memcmp
-#undef SDL_memcmp
-int SDL_memcmp(const void *s1, const void *s2, size_t len) { return SDL_memcmp_inline(s1, s2, len); }
-#else
 int
 int
 SDL_memcmp(const void *s1, const void *s2, size_t len)
 SDL_memcmp(const void *s1, const void *s2, size_t len)
 {
 {
+#if defined(HAVE_MEMCMP)
+    return memcmp(s1, s2, len);
+#else
     char *s1p = (char *) s1;
     char *s1p = (char *) s1;
     char *s2p = (char *) s2;
     char *s2p = (char *) s2;
     while (len--) {
     while (len--) {
@@ -402,46 +382,43 @@ SDL_memcmp(const void *s1, const void *s2, size_t len)
         ++s2p;
         ++s2p;
     }
     }
     return 0;
     return 0;
+#endif /* HAVE_MEMCMP */
 }
 }
-#endif
 
 
-#ifdef SDL_strlen
-#undef SDL_strlen
-size_t SDL_strlen(const char *string) { return SDL_strlen_inline(string); }
-#else
 size_t
 size_t
 SDL_strlen(const char *string)
 SDL_strlen(const char *string)
 {
 {
+#if defined(HAVE_STRLEN)
+    return strlen(string);
+#else
     size_t len = 0;
     size_t len = 0;
     while (*string++) {
     while (*string++) {
         ++len;
         ++len;
     }
     }
     return len;
     return len;
+#endif /* HAVE_STRLEN */
 }
 }
-#endif
 
 
-#ifdef SDL_wcslen
-#undef SDL_wcslen
-size_t SDL_wcslen(const wchar_t * string) { return SDL_wcslen_inline(string); }
-#else
 size_t
 size_t
 SDL_wcslen(const wchar_t * string)
 SDL_wcslen(const wchar_t * string)
 {
 {
+#if defined(HAVE_WCSLEN)
+    return wcslen(string);
+#else
     size_t len = 0;
     size_t len = 0;
     while (*string++) {
     while (*string++) {
         ++len;
         ++len;
     }
     }
     return len;
     return len;
+#endif /* HAVE_WCSLEN */
 }
 }
-#endif
 
 
-#ifdef SDL_wcslcpy
-#undef SDL_wcslcpy
-size_t SDL_wcslcpy(wchar_t *dst, const wchar_t *src, size_t maxlen) { return SDL_wcslcpy_inline(dst, src, maxlen); }
-#else
 size_t
 size_t
 SDL_wcslcpy(wchar_t *dst, const wchar_t *src, size_t maxlen)
 SDL_wcslcpy(wchar_t *dst, const wchar_t *src, size_t maxlen)
 {
 {
+#if defined(HAVE_WCSLCPY)
+    return wcslcpy(dst, src, maxlen);
+#else
     size_t srclen = SDL_wcslen(src);
     size_t srclen = SDL_wcslen(src);
     if (maxlen > 0) {
     if (maxlen > 0) {
         size_t len = SDL_min(srclen, maxlen - 1);
         size_t len = SDL_min(srclen, maxlen - 1);
@@ -449,32 +426,30 @@ SDL_wcslcpy(wchar_t *dst, const wchar_t *src, size_t maxlen)
         dst[len] = '\0';
         dst[len] = '\0';
     }
     }
     return srclen;
     return srclen;
+#endif /* HAVE_WCSLCPY */
 }
 }
-#endif
 
 
-#ifdef SDL_wcslcat
-#undef SDL_wcslcat
-size_t SDL_wcslcat(wchar_t *dst, const wchar_t *src, size_t maxlen) { return SDL_wcslcat_inline(dst, src, maxlen); }
-#else
 size_t
 size_t
 SDL_wcslcat(wchar_t *dst, const wchar_t *src, size_t maxlen)
 SDL_wcslcat(wchar_t *dst, const wchar_t *src, size_t maxlen)
 {
 {
+#if defined(HAVE_WCSLCAT)
+    return wcslcat(dst, src, maxlen);
+#else
     size_t dstlen = SDL_wcslen(dst);
     size_t dstlen = SDL_wcslen(dst);
     size_t srclen = SDL_wcslen(src);
     size_t srclen = SDL_wcslen(src);
     if (dstlen < maxlen) {
     if (dstlen < maxlen) {
         SDL_wcslcpy(dst + dstlen, src, maxlen - dstlen);
         SDL_wcslcpy(dst + dstlen, src, maxlen - dstlen);
     }
     }
     return dstlen + srclen;
     return dstlen + srclen;
+#endif /* HAVE_WCSLCAT */
 }
 }
-#endif
 
 
-#ifdef SDL_strlcpy
-#undef SDL_strlcpy
-size_t SDL_strlcpy(char *dst, const char *src, size_t maxlen) { return SDL_strlcpy_inline(dst, src, maxlen); }
-#else
 size_t
 size_t
 SDL_strlcpy(char *dst, const char *src, size_t maxlen)
 SDL_strlcpy(char *dst, const char *src, size_t maxlen)
 {
 {
+#if defined(HAVE_STRLCPY)
+    return strlcpy(dst, src, maxlen);
+#else
     size_t srclen = SDL_strlen(src);
     size_t srclen = SDL_strlen(src);
     if (maxlen > 0) {
     if (maxlen > 0) {
         size_t len = SDL_min(srclen, maxlen - 1);
         size_t len = SDL_min(srclen, maxlen - 1);
@@ -482,8 +457,8 @@ SDL_strlcpy(char *dst, const char *src, size_t maxlen)
         dst[len] = '\0';
         dst[len] = '\0';
     }
     }
     return srclen;
     return srclen;
+#endif /* HAVE_STRLCPY */
 }
 }
-#endif
 
 
 size_t SDL_utf8strlcpy(char *dst, const char *src, size_t dst_bytes)
 size_t SDL_utf8strlcpy(char *dst, const char *src, size_t dst_bytes)
 {
 {
@@ -517,45 +492,42 @@ size_t SDL_utf8strlcpy(char *dst, const char *src, size_t dst_bytes)
     return bytes;
     return bytes;
 }
 }
 
 
-#ifdef SDL_strlcat
-#undef SDL_strlcat
-size_t SDL_strlcat(char *dst, const char *src, size_t maxlen) { return SDL_strlcat_inline(dst, src, maxlen); }
-#else
 size_t
 size_t
 SDL_strlcat(char *dst, const char *src, size_t maxlen)
 SDL_strlcat(char *dst, const char *src, size_t maxlen)
 {
 {
+#if defined(HAVE_STRLCAT)
+    return strlcat(dst, src, maxlen);
+#else
     size_t dstlen = SDL_strlen(dst);
     size_t dstlen = SDL_strlen(dst);
     size_t srclen = SDL_strlen(src);
     size_t srclen = SDL_strlen(src);
     if (dstlen < maxlen) {
     if (dstlen < maxlen) {
         SDL_strlcpy(dst + dstlen, src, maxlen - dstlen);
         SDL_strlcpy(dst + dstlen, src, maxlen - dstlen);
     }
     }
     return dstlen + srclen;
     return dstlen + srclen;
+#endif /* HAVE_STRLCAT */
 }
 }
-#endif
 
 
-#ifdef SDL_strdup
-#undef SDL_strdup
-char *SDL_strdup(const char *string) { return SDL_strdup_inline(string); }
-#else
 char *
 char *
 SDL_strdup(const char *string)
 SDL_strdup(const char *string)
 {
 {
+#if defined(HAVE_STRDUP)
+    return strdup(string);
+#else
     size_t len = SDL_strlen(string) + 1;
     size_t len = SDL_strlen(string) + 1;
     char *newstr = SDL_malloc(len);
     char *newstr = SDL_malloc(len);
     if (newstr) {
     if (newstr) {
         SDL_strlcpy(newstr, string, len);
         SDL_strlcpy(newstr, string, len);
     }
     }
     return newstr;
     return newstr;
+#endif /* HAVE_STRDUP */
 }
 }
-#endif
 
 
-#ifdef SDL_strrev
-#undef SDL_strrev
-char *SDL_strrev(char *string) { return SDL_strrev_inline(string); }
-#else
 char *
 char *
 SDL_strrev(char *string)
 SDL_strrev(char *string)
 {
 {
+#if defined(HAVE__STRREV)
+    return _strrev(string);
+#else
     size_t len = SDL_strlen(string);
     size_t len = SDL_strlen(string);
     char *a = &string[0];
     char *a = &string[0];
     char *b = &string[len - 1];
     char *b = &string[len - 1];
@@ -566,48 +538,47 @@ SDL_strrev(char *string)
         *b-- = c;
         *b-- = c;
     }
     }
     return string;
     return string;
+#endif /* HAVE__STRREV */
 }
 }
-#endif
 
 
-#ifdef SDL_strupr
-#undef SDL_strupr
-char *SDL_strupr(char *string) { return SDL_strupr_inline(string); }
-#else
 char *
 char *
 SDL_strupr(char *string)
 SDL_strupr(char *string)
 {
 {
+#if defined(HAVE__STRUPR)
+    return _strupr(string);
+#else
     char *bufp = string;
     char *bufp = string;
     while (*bufp) {
     while (*bufp) {
         *bufp = SDL_toupper((unsigned char) *bufp);
         *bufp = SDL_toupper((unsigned char) *bufp);
         ++bufp;
         ++bufp;
     }
     }
     return string;
     return string;
+#endif /* HAVE__STRUPR */
 }
 }
-#endif
 
 
-#ifdef SDL_strlwr
-#undef SDL_strlwr
-char *SDL_strlwr(char *string) { return SDL_strlwr_inline(string); }
-#else
 char *
 char *
 SDL_strlwr(char *string)
 SDL_strlwr(char *string)
 {
 {
+#if defined(HAVE__STRLWR)
+    return _strlwr(string);
+#else
     char *bufp = string;
     char *bufp = string;
     while (*bufp) {
     while (*bufp) {
         *bufp = SDL_tolower((unsigned char) *bufp);
         *bufp = SDL_tolower((unsigned char) *bufp);
         ++bufp;
         ++bufp;
     }
     }
     return string;
     return string;
+#endif /* HAVE__STRLWR */
 }
 }
-#endif
 
 
-#ifdef SDL_strchr
-#undef SDL_strchr
-char *SDL_strchr(const char *string, int c) { return SDL_strchr_inline(string, c); }
-#else
 char *
 char *
 SDL_strchr(const char *string, int c)
 SDL_strchr(const char *string, int c)
 {
 {
+#ifdef HAVE_STRCHR
+    return SDL_const_cast(char*,strchr(string, c));
+#elif defined(HAVE_INDEX)
+    return SDL_const_cast(char*,index(string, c));
+#else
     while (*string) {
     while (*string) {
         if (*string == c) {
         if (*string == c) {
             return (char *) string;
             return (char *) string;
@@ -615,16 +586,17 @@ SDL_strchr(const char *string, int c)
         ++string;
         ++string;
     }
     }
     return NULL;
     return NULL;
+#endif /* HAVE_STRCHR */
 }
 }
-#endif
 
 
-#ifdef SDL_strrchr
-#undef SDL_strrchr
-char *SDL_strrchr(const char *string, int c) { return SDL_strrchr_inline(string, c); }
-#else
 char *
 char *
 SDL_strrchr(const char *string, int c)
 SDL_strrchr(const char *string, int c)
 {
 {
+#ifdef HAVE_STRRCHR
+    return SDL_const_cast(char*,strrchr(string, c));
+#elif defined(HAVE_RINDEX)
+    return SDL_const_cast(char*,rindex(string, c));
+#else
     const char *bufp = string + SDL_strlen(string) - 1;
     const char *bufp = string + SDL_strlen(string) - 1;
     while (bufp >= string) {
     while (bufp >= string) {
         if (*bufp == c) {
         if (*bufp == c) {
@@ -633,16 +605,15 @@ SDL_strrchr(const char *string, int c)
         --bufp;
         --bufp;
     }
     }
     return NULL;
     return NULL;
+#endif /* HAVE_STRRCHR */
 }
 }
-#endif
 
 
-#ifdef SDL_strstr
-#undef SDL_strstr
-char *SDL_strstr(const char *haystack, const char *needle) { return SDL_strstr_inline(haystack, needle); }
-#else
 char *
 char *
 SDL_strstr(const char *haystack, const char *needle)
 SDL_strstr(const char *haystack, const char *needle)
 {
 {
+#if defined(HAVE_STRSTR)
+    return SDL_const_cast(char*,strstr(haystack, needle));
+#else
     size_t length = SDL_strlen(needle);
     size_t length = SDL_strlen(needle);
     while (*haystack) {
     while (*haystack) {
         if (SDL_strncmp(haystack, needle, length) == 0) {
         if (SDL_strncmp(haystack, needle, length) == 0) {
@@ -651,11 +622,11 @@ SDL_strstr(const char *haystack, const char *needle)
         ++haystack;
         ++haystack;
     }
     }
     return NULL;
     return NULL;
+#endif /* HAVE_STRSTR */
 }
 }
-#endif
 
 
-#if !defined(SDL_ltoa) || !defined(SDL_lltoa) || \
-    !defined(SDL_ultoa) || !defined(SDL_ulltoa)
+#if !defined(HAVE__LTOA) || !defined(HAVE__I64TOA) || \
+    !defined(HAVE__ULTOA) || !defined(HAVE__UI64TOA)
 static const char ntoa_table[] = {
 static const char ntoa_table[] = {
     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
     'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
     'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
@@ -664,13 +635,32 @@ static const char ntoa_table[] = {
 };
 };
 #endif /* ntoa() conversion table */
 #endif /* ntoa() conversion table */
 
 
-#ifdef SDL_ltoa
-#undef SDL_ltoa
-char *SDL_ltoa(long value, char *string, int radix) { return SDL_ltoa_inline(value, string, radix); }
+char *
+SDL_itoa(int value, char *string, int radix)
+{
+#ifdef HAVE_ITOA
+    return itoa(value, string, radix);
+#else
+    return SDL_ltoa((long)value, string, radix);
+#endif /* HAVE_ITOA */
+}
+
+char *
+SDL_uitoa(unsigned int value, char *string, int radix)
+{
+#ifdef HAVE__UITOA
+    return _uitoa(value, string, radix);
 #else
 #else
+    return SDL_ultoa((unsigned long)value, string, radix);
+#endif /* HAVE__UITOA */
+}
+
 char *
 char *
 SDL_ltoa(long value, char *string, int radix)
 SDL_ltoa(long value, char *string, int radix)
 {
 {
+#if defined(HAVE__LTOA)
+    return _ltoa(value, string, radix);
+#else
     char *bufp = string;
     char *bufp = string;
 
 
     if (value < 0) {
     if (value < 0) {
@@ -695,16 +685,15 @@ SDL_ltoa(long value, char *string, int radix)
     }
     }
 
 
     return string;
     return string;
+#endif /* HAVE__LTOA */
 }
 }
-#endif
 
 
-#ifdef SDL_ultoa
-#undef SDL_ultoa
-char *SDL_ultoa(unsigned long value, char *string, int radix) { return SDL_ultoa_inline(value, string, radix); }
-#else
 char *
 char *
 SDL_ultoa(unsigned long value, char *string, int radix)
 SDL_ultoa(unsigned long value, char *string, int radix)
 {
 {
+#if defined(HAVE__ULTOA)
+    return _ultoa(value, string, radix);
+#else
     char *bufp = string;
     char *bufp = string;
 
 
     if (value) {
     if (value) {
@@ -721,68 +710,15 @@ SDL_ultoa(unsigned long value, char *string, int radix)
     SDL_strrev(string);
     SDL_strrev(string);
 
 
     return string;
     return string;
+#endif /* HAVE__ULTOA */
 }
 }
-#endif
-
-#ifdef SDL_strtol
-#undef SDL_strtol
-long SDL_strtol(const char *string, char **endp, int base) { return SDL_strtol_inline(string, endp, base); }
-#else
-long
-SDL_strtol(const char *string, char **endp, int base)
-{
-    size_t len;
-    long value;
-
-    if (!base) {
-        if ((SDL_strlen(string) > 2) && (SDL_strncmp(string, "0x", 2) == 0)) {
-            base = 16;
-        } else {
-            base = 10;
-        }
-    }
-
-    len = SDL_ScanLong(string, base, &value);
-    if (endp) {
-        *endp = (char *) string + len;
-    }
-    return value;
-}
-#endif
 
 
-#ifdef SDL_strtoul
-#undef SDL_strtoul
-unsigned long SDL_strtoul(const char *string, char **endp, int base) { return SDL_strtoul_inline(string, endp, base); }
-#else
-unsigned long
-SDL_strtoul(const char *string, char **endp, int base)
-{
-    size_t len;
-    unsigned long value;
-
-    if (!base) {
-        if ((SDL_strlen(string) > 2) && (SDL_strncmp(string, "0x", 2) == 0)) {
-            base = 16;
-        } else {
-            base = 10;
-        }
-    }
-
-    len = SDL_ScanUnsignedLong(string, base, &value);
-    if (endp) {
-        *endp = (char *) string + len;
-    }
-    return value;
-}
-#endif
-
-#ifdef SDL_lltoa
-#undef SDL_lltoa
-char *SDL_lltoa(Sint64 value, char *string, int radix) { return SDL_lltoa_inline(value, string, radix); }
-#else
 char *
 char *
 SDL_lltoa(Sint64 value, char *string, int radix)
 SDL_lltoa(Sint64 value, char *string, int radix)
 {
 {
+#if defined(HAVE__I64TOA)
+    return _i64toa(value, string, radix);
+#else
     char *bufp = string;
     char *bufp = string;
 
 
     if (value < 0) {
     if (value < 0) {
@@ -807,16 +743,15 @@ SDL_lltoa(Sint64 value, char *string, int radix)
     }
     }
 
 
     return string;
     return string;
+#endif /* HAVE__I64TOA */
 }
 }
-#endif
 
 
-#ifdef SDL_ulltoa
-#undef SDL_ulltoa
-char *SDL_ulltoa(Uint64 value, char *string, int radix) { return SDL_ulltoa_inline(value, string, radix); }
-#else
 char *
 char *
 SDL_ulltoa(Uint64 value, char *string, int radix)
 SDL_ulltoa(Uint64 value, char *string, int radix)
 {
 {
+#if defined(HAVE__UI64TOA)
+    return _ui64toa(value, string, radix);
+#else
     char *bufp = string;
     char *bufp = string;
 
 
     if (value) {
     if (value) {
@@ -833,16 +768,83 @@ SDL_ulltoa(Uint64 value, char *string, int radix)
     SDL_strrev(string);
     SDL_strrev(string);
 
 
     return string;
     return string;
+#endif /* HAVE__UI64TOA */
 }
 }
-#endif
 
 
-#ifdef SDL_strtoll
-#undef SDL_strtoll
-Sint64 SDL_strtoll(const char *string, char **endp, int base) { return SDL_strtoll_inline(string, endp, base); }
+int SDL_atoi(const char *string)
+{
+#ifdef HAVE_ATOI
+    return atoi(string);
+#else
+    return SDL_strtol(string, NULL, 0);
+#endif /* HAVE_ATOI */
+}
+
+double SDL_atof(const char *string)
+{
+#ifdef HAVE_ATOF
+    return (double) atof(string);
+#else
+    return SDL_strtod(string, NULL);
+#endif /* HAVE_ATOF */
+}
+
+long
+SDL_strtol(const char *string, char **endp, int base)
+{
+#if defined(HAVE_STRTOL)
+    return strtol(string, endp, base);
+#else
+    size_t len;
+    long value;
+
+    if (!base) {
+        if ((SDL_strlen(string) > 2) && (SDL_strncmp(string, "0x", 2) == 0)) {
+            base = 16;
+        } else {
+            base = 10;
+        }
+    }
+
+    len = SDL_ScanLong(string, base, &value);
+    if (endp) {
+        *endp = (char *) string + len;
+    }
+    return value;
+#endif /* HAVE_STRTOL */
+}
+
+unsigned long
+SDL_strtoul(const char *string, char **endp, int base)
+{
+#if defined(HAVE_STRTOUL)
+    return strtoul(string, endp, base);
 #else
 #else
+    size_t len;
+    unsigned long value;
+
+    if (!base) {
+        if ((SDL_strlen(string) > 2) && (SDL_strncmp(string, "0x", 2) == 0)) {
+            base = 16;
+        } else {
+            base = 10;
+        }
+    }
+
+    len = SDL_ScanUnsignedLong(string, base, &value);
+    if (endp) {
+        *endp = (char *) string + len;
+    }
+    return value;
+#endif /* HAVE_STRTOUL */
+}
+
 Sint64
 Sint64
 SDL_strtoll(const char *string, char **endp, int base)
 SDL_strtoll(const char *string, char **endp, int base)
 {
 {
+#if defined(HAVE_STRTOLL)
+    return strtoll(string, endp, base);
+#else
     size_t len;
     size_t len;
     Sint64 value;
     Sint64 value;
 
 
@@ -859,16 +861,15 @@ SDL_strtoll(const char *string, char **endp, int base)
         *endp = (char *) string + len;
         *endp = (char *) string + len;
     }
     }
     return value;
     return value;
+#endif /* HAVE_STRTOLL */
 }
 }
-#endif
 
 
-#ifdef SDL_strtoull
-#undef SDL_strtoull
-Uint64 SDL_strtoull(const char *string, char **endp, int base) { return SDL_strtoull_inline(string, endp, base); }
-#else
 Uint64
 Uint64
 SDL_strtoull(const char *string, char **endp, int base)
 SDL_strtoull(const char *string, char **endp, int base)
 {
 {
+#if defined(HAVE_STRTOULL)
+    return strtoull(string, endp, base);
+#else
     size_t len;
     size_t len;
     Uint64 value;
     Uint64 value;
 
 
@@ -885,16 +886,15 @@ SDL_strtoull(const char *string, char **endp, int base)
         *endp = (char *) string + len;
         *endp = (char *) string + len;
     }
     }
     return value;
     return value;
+#endif /* HAVE_STRTOULL */
 }
 }
-#endif
 
 
-#ifdef SDL_strtod
-#undef SDL_strtod
-double SDL_strtod(const char *string, char **endp) { return SDL_strtod_inline(string, endp); }
-#else
 double
 double
 SDL_strtod(const char *string, char **endp)
 SDL_strtod(const char *string, char **endp)
 {
 {
+#if defined(HAVE_STRTOD)
+    return strtod(string, endp);
+#else
     size_t len;
     size_t len;
     double value;
     double value;
 
 
@@ -903,16 +903,15 @@ SDL_strtod(const char *string, char **endp)
         *endp = (char *) string + len;
         *endp = (char *) string + len;
     }
     }
     return value;
     return value;
+#endif /* HAVE_STRTOD */
 }
 }
-#endif
 
 
-#ifdef SDL_strcmp
-#undef SDL_strcmp
-int SDL_strcmp(const char *str1, const char *str2) { return SDL_strcmp_inline(str1, str2); }
-#else
 int
 int
 SDL_strcmp(const char *str1, const char *str2)
 SDL_strcmp(const char *str1, const char *str2)
 {
 {
+#if defined(HAVE_STRCMP)
+    return strcmp(str1, str2);
+#else
     while (*str1 && *str2) {
     while (*str1 && *str2) {
         if (*str1 != *str2)
         if (*str1 != *str2)
             break;
             break;
@@ -920,16 +919,15 @@ SDL_strcmp(const char *str1, const char *str2)
         ++str2;
         ++str2;
     }
     }
     return (int) ((unsigned char) *str1 - (unsigned char) *str2);
     return (int) ((unsigned char) *str1 - (unsigned char) *str2);
+#endif /* HAVE_STRCMP */
 }
 }
-#endif
 
 
-#ifdef SDL_strncmp
-#undef SDL_strncmp
-int SDL_strncmp(const char *str1, const char *str2, size_t maxlen) { return SDL_strncmp_inline(str1, str2, maxlen); }
-#else
 int
 int
 SDL_strncmp(const char *str1, const char *str2, size_t maxlen)
 SDL_strncmp(const char *str1, const char *str2, size_t maxlen)
 {
 {
+#if defined(HAVE_STRNCMP)
+    return strncmp(str1, str2, maxlen);
+#else
     while (*str1 && *str2 && maxlen) {
     while (*str1 && *str2 && maxlen) {
         if (*str1 != *str2)
         if (*str1 != *str2)
             break;
             break;
@@ -941,39 +939,41 @@ SDL_strncmp(const char *str1, const char *str2, size_t maxlen)
         return 0;
         return 0;
     }
     }
     return (int) ((unsigned char) *str1 - (unsigned char) *str2);
     return (int) ((unsigned char) *str1 - (unsigned char) *str2);
+#endif /* HAVE_STRNCMP */
 }
 }
-#endif
 
 
-#ifdef SDL_strcasecmp
-#undef SDL_strcasecmp
-int SDL_strcasecmp(const char *str1, const char *str2) { return SDL_strcasecmp_inline(str1, str2); }
-#else
 int
 int
 SDL_strcasecmp(const char *str1, const char *str2)
 SDL_strcasecmp(const char *str1, const char *str2)
 {
 {
+#ifdef HAVE_STRCASECMP
+    return strcasecmp(str1, str2);
+#elif defined(HAVE__STRICMP)
+    return _stricmp(str1, str2);
+#else
     char a = 0;
     char a = 0;
     char b = 0;
     char b = 0;
     while (*str1 && *str2) {
     while (*str1 && *str2) {
-        a = SDL_tolower((unsigned char) *str1);
-        b = SDL_tolower((unsigned char) *str2);
+        a = SDL_toupper((unsigned char) *str1);
+        b = SDL_toupper((unsigned char) *str2);
         if (a != b)
         if (a != b)
             break;
             break;
         ++str1;
         ++str1;
         ++str2;
         ++str2;
     }
     }
-    a = SDL_tolower(*str1);
-    b = SDL_tolower(*str2);
+    a = SDL_toupper(*str1);
+    b = SDL_toupper(*str2);
     return (int) ((unsigned char) a - (unsigned char) b);
     return (int) ((unsigned char) a - (unsigned char) b);
+#endif /* HAVE_STRCASECMP */
 }
 }
-#endif
 
 
-#ifdef SDL_strncasecmp
-#undef SDL_strncasecmp
-int SDL_strncasecmp(const char *str1, const char *str2, size_t maxlen) { return SDL_strncasecmp_inline(str1, str2, maxlen); }
-#else
 int
 int
 SDL_strncasecmp(const char *str1, const char *str2, size_t maxlen)
 SDL_strncasecmp(const char *str1, const char *str2, size_t maxlen)
 {
 {
+#ifdef HAVE_STRNCASECMP
+    return strncasecmp(str1, str2, maxlen);
+#elif defined(HAVE__STRNICMP)
+    return _strnicmp(str1, str2, maxlen);
+#else
     char a = 0;
     char a = 0;
     char b = 0;
     char b = 0;
     while (*str1 && *str2 && maxlen) {
     while (*str1 && *str2 && maxlen) {
@@ -992,13 +992,11 @@ SDL_strncasecmp(const char *str1, const char *str2, size_t maxlen)
         b = SDL_tolower((unsigned char) *str2);
         b = SDL_tolower((unsigned char) *str2);
         return (int) ((unsigned char) a - (unsigned char) b);
         return (int) ((unsigned char) a - (unsigned char) b);
     }
     }
+#endif /* HAVE_STRNCASECMP */
 }
 }
-#endif
 
 
-#ifdef SDL_sscanf
-#undef SDL_sscanf
-// Urho3D: removed function, as vsscanf is not available on Visual Studio
-/*
+#ifdef HAVE_SSCANF
+int
 SDL_sscanf(const char *text, const char *fmt, ...)
 SDL_sscanf(const char *text, const char *fmt, ...)
 {
 {
     int rc;
     int rc;
@@ -1008,7 +1006,6 @@ SDL_sscanf(const char *text, const char *fmt, ...)
     va_end(ap);
     va_end(ap);
     return rc;
     return rc;
 }
 }
-*/
 #else
 #else
 int
 int
 SDL_sscanf(const char *text, const char *fmt, ...)
 SDL_sscanf(const char *text, const char *fmt, ...)
@@ -1274,12 +1271,8 @@ SDL_sscanf(const char *text, const char *fmt, ...)
 
 
     return retval;
     return retval;
 }
 }
-#endif
+#endif /* HAVE_SSCANF */
 
 
-/* just undef; the headers only define this to snprintf because of varargs. */
-#ifdef SDL_snprintf
-#undef SDL_snprintf
-#endif
 int
 int
 SDL_snprintf(char *text, size_t maxlen, const char *fmt, ...)
 SDL_snprintf(char *text, size_t maxlen, const char *fmt, ...)
 {
 {
@@ -1293,9 +1286,11 @@ SDL_snprintf(char *text, size_t maxlen, const char *fmt, ...)
     return retval;
     return retval;
 }
 }
 
 
-#ifdef SDL_vsnprintf
-#undef SDL_vsnprintf
-int SDL_vsnprintf(char *text, size_t maxlen, const char *fmt, va_list ap) { return SDL_vsnprintf_inline(text, maxlen, fmt, ap); }
+#ifdef HAVE_VSNPRINTF
+int SDL_vsnprintf(char *text, size_t maxlen, const char *fmt, va_list ap)
+{
+    return vsnprintf(text, maxlen, fmt, ap);
+}
 #else
 #else
  /* FIXME: implement more of the format specifiers */
  /* FIXME: implement more of the format specifiers */
 typedef struct
 typedef struct
@@ -1313,7 +1308,24 @@ typedef struct
 static size_t
 static size_t
 SDL_PrintString(char *text, size_t maxlen, SDL_FormatInfo *info, const char *string)
 SDL_PrintString(char *text, size_t maxlen, SDL_FormatInfo *info, const char *string)
 {
 {
-    return SDL_strlcpy(text, string, maxlen);
+    size_t length = 0;
+
+    if (info && info->width && (size_t)info->width > SDL_strlen(string)) {
+        char fill = info->pad_zeroes ? '0' : ' ';
+        size_t width = info->width - SDL_strlen(string);
+        while (width-- > 0 && maxlen > 0) {
+            *text++ = fill;
+            ++length;
+            --maxlen;
+        }
+    }
+
+    length += SDL_strlcpy(text, string, maxlen);
+
+    if (info && info->do_lowercase) {
+        SDL_strlwr(text);
+    }
+    return length;
 }
 }
 
 
 static size_t
 static size_t
@@ -1355,14 +1367,13 @@ SDL_PrintUnsignedLongLong(char *text, size_t maxlen, SDL_FormatInfo *info, Uint6
 static size_t
 static size_t
 SDL_PrintFloat(char *text, size_t maxlen, SDL_FormatInfo *info, double arg)
 SDL_PrintFloat(char *text, size_t maxlen, SDL_FormatInfo *info, double arg)
 {
 {
-    int i, width;
+    int width;
     size_t len;
     size_t len;
     size_t left = maxlen;
     size_t left = maxlen;
     char *textstart = text;
     char *textstart = text;
 
 
     if (arg) {
     if (arg) {
         /* This isn't especially accurate, but hey, it's easy. :) */
         /* This isn't especially accurate, but hey, it's easy. :) */
-        double precision = 1.0;
         unsigned long value;
         unsigned long value;
 
 
         if (arg < 0) {
         if (arg < 0) {
@@ -1391,9 +1402,6 @@ SDL_PrintFloat(char *text, size_t maxlen, SDL_FormatInfo *info, double arg)
         if (info->precision < 0) {
         if (info->precision < 0) {
             info->precision = 6;
             info->precision = 6;
         }
         }
-        for (i = 0; i < info->precision; ++i) {
-            precision *= 0.1;
-        }
         if (info->force_type || info->precision > 0) {
         if (info->force_type || info->precision > 0) {
             int mult = 10;
             int mult = 10;
             if (left > 1) {
             if (left > 1) {
@@ -1581,6 +1589,7 @@ SDL_vsnprintf(char *text, size_t maxlen, const char *fmt, va_list ap)
                     }
                     }
                     /* Fall through to unsigned handling */
                     /* Fall through to unsigned handling */
                 case 'u':
                 case 'u':
+                    info.pad_zeroes = SDL_TRUE;
                     switch (inttype) {
                     switch (inttype) {
                     case DO_INT:
                     case DO_INT:
                         len = SDL_PrintUnsignedLong(text, left, &info,
                         len = SDL_PrintUnsignedLong(text, left, &info,
@@ -1596,12 +1605,6 @@ SDL_vsnprintf(char *text, size_t maxlen, const char *fmt, va_list ap)
                                                         va_arg(ap, Uint64));
                                                         va_arg(ap, Uint64));
                         break;
                         break;
                     }
                     }
-                    if (info.do_lowercase) {
-                        size_t i;
-                        for (i = 0; i < len && i < left; ++i) {
-                            text[i] = SDL_tolower((unsigned char)text[i]);
-                        }
-                    }
                     done = SDL_TRUE;
                     done = SDL_TRUE;
                     break;
                     break;
                 case 'f':
                 case 'f':
@@ -1638,6 +1641,6 @@ SDL_vsnprintf(char *text, size_t maxlen, const char *fmt, va_list ap)
     }
     }
     return (int)(text - textstart);
     return (int)(text - textstart);
 }
 }
-#endif
+#endif /* HAVE_VSNPRINTF */
 
 
 /* vi: set ts=4 sw=4 expandtab: */
 /* vi: set ts=4 sw=4 expandtab: */

+ 150 - 0
Source/ThirdParty/SDL/src/test/SDL_test_assert.c

@@ -0,0 +1,150 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2013 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.
+*/
+
+/*
+
+ Used by the test framework and test cases.
+
+*/
+
+#include "SDL_config.h"
+
+#include "SDL_test.h"
+
+/* Assert check message format */
+const char *SDLTest_AssertCheckFormat = "Assert '%s': %s";
+
+/* Assert summary message format */
+const char *SDLTest_AssertSummaryFormat = "Assert Summary: Total=%d Passed=%d Failed=%d";
+
+/*! \brief counts the failed asserts */
+static Uint32 SDLTest_AssertsFailed = 0;
+
+/*! \brief counts the passed asserts */
+static Uint32 SDLTest_AssertsPassed = 0;
+
+/*
+ *  Assert that logs and break execution flow on failures (i.e. for harness errors).
+ */
+void SDLTest_Assert(int assertCondition, const char *assertDescription, ...)
+{
+        va_list list;
+    char logMessage[SDLTEST_MAX_LOGMESSAGE_LENGTH];
+
+    /* Print assert description into a buffer */
+    SDL_memset(logMessage, 0, SDLTEST_MAX_LOGMESSAGE_LENGTH);
+    va_start(list, assertDescription);
+    SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, assertDescription, list);
+    va_end(list);
+
+    /* Log, then assert and break on failure */
+    SDL_assert((SDLTest_AssertCheck(assertCondition, logMessage)));
+}
+
+/*
+ * Assert that logs but does not break execution flow on failures (i.e. for test cases).
+ */
+int SDLTest_AssertCheck(int assertCondition, const char *assertDescription, ...)
+{
+    va_list list;
+    char logMessage[SDLTEST_MAX_LOGMESSAGE_LENGTH];
+
+    /* Print assert description into a buffer */
+    SDL_memset(logMessage, 0, SDLTEST_MAX_LOGMESSAGE_LENGTH);
+    va_start(list, assertDescription);
+    SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, assertDescription, list);
+    va_end(list);
+
+    /* Log pass or fail message */
+    if (assertCondition == ASSERT_FAIL)
+    {
+        SDLTest_AssertsFailed++;
+        SDLTest_LogError(SDLTest_AssertCheckFormat, logMessage, "Failed");
+    }
+    else
+    {
+        SDLTest_AssertsPassed++;
+        SDLTest_Log(SDLTest_AssertCheckFormat, logMessage, "Passed");
+    }
+
+    return assertCondition;
+}
+
+/*
+ * Explicitly passing Assert that logs (i.e. for test cases).
+ */
+void SDLTest_AssertPass(const char *assertDescription, ...)
+{
+    va_list list;
+    char logMessage[SDLTEST_MAX_LOGMESSAGE_LENGTH];
+
+    /* Print assert description into a buffer */
+    SDL_memset(logMessage, 0, SDLTEST_MAX_LOGMESSAGE_LENGTH);
+    va_start(list, assertDescription);
+    SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, assertDescription, list);
+    va_end(list);
+
+        /* Log pass message */
+    SDLTest_AssertsPassed++;
+    SDLTest_Log(SDLTest_AssertCheckFormat, logMessage, "Pass");
+}
+
+/*
+ * Resets the assert summary counters to zero.
+ */
+void SDLTest_ResetAssertSummary()
+{
+    SDLTest_AssertsPassed = 0;
+    SDLTest_AssertsFailed = 0;
+}
+
+/*
+ * Logs summary of all assertions (total, pass, fail) since last reset
+ * as INFO (failed==0) or ERROR (failed > 0).
+ */
+void SDLTest_LogAssertSummary()
+{
+    Uint32 totalAsserts = SDLTest_AssertsPassed + SDLTest_AssertsFailed;
+    if (SDLTest_AssertsFailed == 0)
+    {
+        SDLTest_Log(SDLTest_AssertSummaryFormat, totalAsserts, SDLTest_AssertsPassed, SDLTest_AssertsFailed);
+    }
+    else
+    {
+        SDLTest_LogError(SDLTest_AssertSummaryFormat, totalAsserts, SDLTest_AssertsPassed, SDLTest_AssertsFailed);
+    }
+}
+
+/*
+ * Converts the current assert state into a test result
+ */
+int SDLTest_AssertSummaryToTestResult()
+{
+    if (SDLTest_AssertsFailed > 0) {
+        return TEST_RESULT_FAILED;
+    } else {
+        if (SDLTest_AssertsPassed > 0) {
+            return TEST_RESULT_PASSED;
+        } else {
+            return TEST_RESULT_NO_ASSERT;
+        }
+    }
+}

+ 1411 - 0
Source/ThirdParty/SDL/src/test/SDL_test_common.c

@@ -0,0 +1,1411 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2013 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.
+*/
+
+/* Ported from original test\common.c file. */
+
+#include "SDL_config.h"
+#include "SDL_test.h"
+
+#include <stdio.h>
+
+#define VIDEO_USAGE \
+"[--video driver] [--renderer driver] [--gldebug] [--info all|video|modes|render|event] [--log all|error|system|audio|video|render|input] [--display N] [--fullscreen | --fullscreen-desktop | --windows N] [--title title] [--icon icon.bmp] [--center | --position X,Y] [--geometry WxH] [--min-geometry WxH] [--max-geometry WxH] [--logical WxH] [--scale N] [--depth N] [--refresh R] [--vsync] [--noframe] [--resize] [--minimize] [--maximize] [--grab]"
+
+#define AUDIO_USAGE \
+"[--rate N] [--format U8|S8|U16|U16LE|U16BE|S16|S16LE|S16BE] [--channels N] [--samples N]"
+
+SDLTest_CommonState *
+SDLTest_CommonCreateState(char **argv, Uint32 flags)
+{
+    SDLTest_CommonState *state = (SDLTest_CommonState *)SDL_calloc(1, sizeof(*state));
+    if (!state) {
+        SDL_OutOfMemory();
+        return NULL;
+    }
+
+    /* Initialize some defaults */
+    state->argv = argv;
+    state->flags = flags;
+    state->window_title = argv[0];
+    state->window_flags = 0;
+    state->window_x = SDL_WINDOWPOS_UNDEFINED;
+    state->window_y = SDL_WINDOWPOS_UNDEFINED;
+    state->window_w = DEFAULT_WINDOW_WIDTH;
+    state->window_h = DEFAULT_WINDOW_HEIGHT;
+    state->num_windows = 1;
+    state->audiospec.freq = 22050;
+    state->audiospec.format = AUDIO_S16;
+    state->audiospec.channels = 2;
+    state->audiospec.samples = 2048;
+
+    /* Set some very sane GL defaults */
+    state->gl_red_size = 3;
+    state->gl_green_size = 3;
+    state->gl_blue_size = 2;
+    state->gl_alpha_size = 0;
+    state->gl_buffer_size = 0;
+    state->gl_depth_size = 16;
+    state->gl_stencil_size = 0;
+    state->gl_double_buffer = 1;
+    state->gl_accum_red_size = 0;
+    state->gl_accum_green_size = 0;
+    state->gl_accum_blue_size = 0;
+    state->gl_accum_alpha_size = 0;
+    state->gl_stereo = 0;
+    state->gl_multisamplebuffers = 0;
+    state->gl_multisamplesamples = 0;
+    state->gl_retained_backing = 1;
+    state->gl_accelerated = -1;
+    state->gl_debug = 0;
+
+    return state;
+}
+
+int
+SDLTest_CommonArg(SDLTest_CommonState * state, int index)
+{
+    char **argv = state->argv;
+
+    if (SDL_strcasecmp(argv[index], "--video") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        state->videodriver = argv[index];
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--renderer") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        state->renderdriver = argv[index];
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--gldebug") == 0) {
+        state->gl_debug = 1;
+        return 1;
+    }
+    if (SDL_strcasecmp(argv[index], "--info") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        if (SDL_strcasecmp(argv[index], "all") == 0) {
+            state->verbose |=
+                (VERBOSE_VIDEO | VERBOSE_MODES | VERBOSE_RENDER |
+                 VERBOSE_EVENT);
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "video") == 0) {
+            state->verbose |= VERBOSE_VIDEO;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "modes") == 0) {
+            state->verbose |= VERBOSE_MODES;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "render") == 0) {
+            state->verbose |= VERBOSE_RENDER;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "event") == 0) {
+            state->verbose |= VERBOSE_EVENT;
+            return 2;
+        }
+        return -1;
+    }
+    if (SDL_strcasecmp(argv[index], "--log") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        if (SDL_strcasecmp(argv[index], "all") == 0) {
+            SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "error") == 0) {
+            SDL_LogSetPriority(SDL_LOG_CATEGORY_ERROR, SDL_LOG_PRIORITY_VERBOSE);
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "system") == 0) {
+            SDL_LogSetPriority(SDL_LOG_CATEGORY_SYSTEM, SDL_LOG_PRIORITY_VERBOSE);
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "audio") == 0) {
+            SDL_LogSetPriority(SDL_LOG_CATEGORY_AUDIO, SDL_LOG_PRIORITY_VERBOSE);
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "video") == 0) {
+            SDL_LogSetPriority(SDL_LOG_CATEGORY_VIDEO, SDL_LOG_PRIORITY_VERBOSE);
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "render") == 0) {
+            SDL_LogSetPriority(SDL_LOG_CATEGORY_RENDER, SDL_LOG_PRIORITY_VERBOSE);
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "input") == 0) {
+            SDL_LogSetPriority(SDL_LOG_CATEGORY_INPUT, SDL_LOG_PRIORITY_VERBOSE);
+            return 2;
+        }
+        return -1;
+    }
+    if (SDL_strcasecmp(argv[index], "--display") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        state->display = SDL_atoi(argv[index]);
+        if (SDL_WINDOWPOS_ISUNDEFINED(state->window_x)) {
+            state->window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display);
+            state->window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display);
+        }
+        if (SDL_WINDOWPOS_ISCENTERED(state->window_x)) {
+            state->window_x = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display);
+            state->window_y = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display);
+        }
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--fullscreen") == 0) {
+        state->window_flags |= SDL_WINDOW_FULLSCREEN;
+        state->num_windows = 1;
+        return 1;
+    }
+    if (SDL_strcasecmp(argv[index], "--fullscreen-desktop") == 0) {
+        state->window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
+        state->num_windows = 1;
+        return 1;
+    }
+    if (SDL_strcasecmp(argv[index], "--windows") == 0) {
+        ++index;
+        if (!argv[index] || !SDL_isdigit(*argv[index])) {
+            return -1;
+        }
+        if (!(state->window_flags & SDL_WINDOW_FULLSCREEN)) {
+            state->num_windows = SDL_atoi(argv[index]);
+        }
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--title") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        state->window_title = argv[index];
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--icon") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        state->window_icon = argv[index];
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--center") == 0) {
+        state->window_x = SDL_WINDOWPOS_CENTERED;
+        state->window_y = SDL_WINDOWPOS_CENTERED;
+        return 1;
+    }
+    if (SDL_strcasecmp(argv[index], "--position") == 0) {
+        char *x, *y;
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        x = argv[index];
+        y = argv[index];
+        while (*y && *y != ',') {
+            ++y;
+        }
+        if (!*y) {
+            return -1;
+        }
+        *y++ = '\0';
+        state->window_x = SDL_atoi(x);
+        state->window_y = SDL_atoi(y);
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--geometry") == 0) {
+        char *w, *h;
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        w = argv[index];
+        h = argv[index];
+        while (*h && *h != 'x') {
+            ++h;
+        }
+        if (!*h) {
+            return -1;
+        }
+        *h++ = '\0';
+        state->window_w = SDL_atoi(w);
+        state->window_h = SDL_atoi(h);
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--min-geometry") == 0) {
+        char *w, *h;
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        w = argv[index];
+        h = argv[index];
+        while (*h && *h != 'x') {
+            ++h;
+        }
+        if (!*h) {
+            return -1;
+        }
+        *h++ = '\0';
+        state->window_minW = SDL_atoi(w);
+        state->window_minH = SDL_atoi(h);
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--max-geometry") == 0) {
+        char *w, *h;
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        w = argv[index];
+        h = argv[index];
+        while (*h && *h != 'x') {
+            ++h;
+        }
+        if (!*h) {
+            return -1;
+        }
+        *h++ = '\0';
+        state->window_maxW = SDL_atoi(w);
+        state->window_maxH = SDL_atoi(h);
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--logical") == 0) {
+        char *w, *h;
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        w = argv[index];
+        h = argv[index];
+        while (*h && *h != 'x') {
+            ++h;
+        }
+        if (!*h) {
+            return -1;
+        }
+        *h++ = '\0';
+        state->logical_w = SDL_atoi(w);
+        state->logical_h = SDL_atoi(h);
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--scale") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        state->scale = (float)SDL_atof(argv[index]);
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--depth") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        state->depth = SDL_atoi(argv[index]);
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--refresh") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        state->refresh_rate = SDL_atoi(argv[index]);
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--vsync") == 0) {
+        state->render_flags |= SDL_RENDERER_PRESENTVSYNC;
+        return 1;
+    }
+    if (SDL_strcasecmp(argv[index], "--noframe") == 0) {
+        state->window_flags |= SDL_WINDOW_BORDERLESS;
+        return 1;
+    }
+    if (SDL_strcasecmp(argv[index], "--resize") == 0) {
+        state->window_flags |= SDL_WINDOW_RESIZABLE;
+        return 1;
+    }
+    if (SDL_strcasecmp(argv[index], "--minimize") == 0) {
+        state->window_flags |= SDL_WINDOW_MINIMIZED;
+        return 1;
+    }
+    if (SDL_strcasecmp(argv[index], "--maximize") == 0) {
+        state->window_flags |= SDL_WINDOW_MAXIMIZED;
+        return 1;
+    }
+    if (SDL_strcasecmp(argv[index], "--grab") == 0) {
+        state->window_flags |= SDL_WINDOW_INPUT_GRABBED;
+        return 1;
+    }
+    if (SDL_strcasecmp(argv[index], "--rate") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        state->audiospec.freq = SDL_atoi(argv[index]);
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--format") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        if (SDL_strcasecmp(argv[index], "U8") == 0) {
+            state->audiospec.format = AUDIO_U8;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "S8") == 0) {
+            state->audiospec.format = AUDIO_S8;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "U16") == 0) {
+            state->audiospec.format = AUDIO_U16;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "U16LE") == 0) {
+            state->audiospec.format = AUDIO_U16LSB;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "U16BE") == 0) {
+            state->audiospec.format = AUDIO_U16MSB;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "S16") == 0) {
+            state->audiospec.format = AUDIO_S16;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "S16LE") == 0) {
+            state->audiospec.format = AUDIO_S16LSB;
+            return 2;
+        }
+        if (SDL_strcasecmp(argv[index], "S16BE") == 0) {
+            state->audiospec.format = AUDIO_S16MSB;
+            return 2;
+        }
+        return -1;
+    }
+    if (SDL_strcasecmp(argv[index], "--channels") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        state->audiospec.channels = (Uint8) SDL_atoi(argv[index]);
+        return 2;
+    }
+    if (SDL_strcasecmp(argv[index], "--samples") == 0) {
+        ++index;
+        if (!argv[index]) {
+            return -1;
+        }
+        state->audiospec.samples = (Uint16) SDL_atoi(argv[index]);
+        return 2;
+    }
+    if ((SDL_strcasecmp(argv[index], "-h") == 0)
+        || (SDL_strcasecmp(argv[index], "--help") == 0)) {
+        /* Print the usage message */
+        return -1;
+    }
+    if (SDL_strcmp(argv[index], "-NSDocumentRevisionsDebugMode") == 0) {
+    /* Debug flag sent by Xcode */
+        return 2;
+    }
+    return 0;
+}
+
+const char *
+SDLTest_CommonUsage(SDLTest_CommonState * state)
+{
+    switch (state->flags & (SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
+    case SDL_INIT_VIDEO:
+        return VIDEO_USAGE;
+    case SDL_INIT_AUDIO:
+        return AUDIO_USAGE;
+    case (SDL_INIT_VIDEO | SDL_INIT_AUDIO):
+        return VIDEO_USAGE " " AUDIO_USAGE;
+    default:
+        return "";
+    }
+}
+
+static void
+SDLTest_PrintRendererFlag(Uint32 flag)
+{
+    switch (flag) {
+    case SDL_RENDERER_PRESENTVSYNC:
+        fprintf(stderr, "PresentVSync");
+        break;
+    case SDL_RENDERER_ACCELERATED:
+        fprintf(stderr, "Accelerated");
+        break;
+    default:
+        fprintf(stderr, "0x%8.8x", flag);
+        break;
+    }
+}
+
+static void
+SDLTest_PrintPixelFormat(Uint32 format)
+{
+    switch (format) {
+    case SDL_PIXELFORMAT_UNKNOWN:
+        fprintf(stderr, "Unknwon");
+        break;
+    case SDL_PIXELFORMAT_INDEX1LSB:
+        fprintf(stderr, "Index1LSB");
+        break;
+    case SDL_PIXELFORMAT_INDEX1MSB:
+        fprintf(stderr, "Index1MSB");
+        break;
+    case SDL_PIXELFORMAT_INDEX4LSB:
+        fprintf(stderr, "Index4LSB");
+        break;
+    case SDL_PIXELFORMAT_INDEX4MSB:
+        fprintf(stderr, "Index4MSB");
+        break;
+    case SDL_PIXELFORMAT_INDEX8:
+        fprintf(stderr, "Index8");
+        break;
+    case SDL_PIXELFORMAT_RGB332:
+        fprintf(stderr, "RGB332");
+        break;
+    case SDL_PIXELFORMAT_RGB444:
+        fprintf(stderr, "RGB444");
+        break;
+    case SDL_PIXELFORMAT_RGB555:
+        fprintf(stderr, "RGB555");
+        break;
+    case SDL_PIXELFORMAT_BGR555:
+        fprintf(stderr, "BGR555");
+        break;
+    case SDL_PIXELFORMAT_ARGB4444:
+        fprintf(stderr, "ARGB4444");
+        break;
+    case SDL_PIXELFORMAT_ABGR4444:
+        fprintf(stderr, "ABGR4444");
+        break;
+    case SDL_PIXELFORMAT_ARGB1555:
+        fprintf(stderr, "ARGB1555");
+        break;
+    case SDL_PIXELFORMAT_ABGR1555:
+        fprintf(stderr, "ABGR1555");
+        break;
+    case SDL_PIXELFORMAT_RGB565:
+        fprintf(stderr, "RGB565");
+        break;
+    case SDL_PIXELFORMAT_BGR565:
+        fprintf(stderr, "BGR565");
+        break;
+    case SDL_PIXELFORMAT_RGB24:
+        fprintf(stderr, "RGB24");
+        break;
+    case SDL_PIXELFORMAT_BGR24:
+        fprintf(stderr, "BGR24");
+        break;
+    case SDL_PIXELFORMAT_RGB888:
+        fprintf(stderr, "RGB888");
+        break;
+    case SDL_PIXELFORMAT_BGR888:
+        fprintf(stderr, "BGR888");
+        break;
+    case SDL_PIXELFORMAT_ARGB8888:
+        fprintf(stderr, "ARGB8888");
+        break;
+    case SDL_PIXELFORMAT_RGBA8888:
+        fprintf(stderr, "RGBA8888");
+        break;
+    case SDL_PIXELFORMAT_ABGR8888:
+        fprintf(stderr, "ABGR8888");
+        break;
+    case SDL_PIXELFORMAT_BGRA8888:
+        fprintf(stderr, "BGRA8888");
+        break;
+    case SDL_PIXELFORMAT_ARGB2101010:
+        fprintf(stderr, "ARGB2101010");
+        break;
+    case SDL_PIXELFORMAT_YV12:
+        fprintf(stderr, "YV12");
+        break;
+    case SDL_PIXELFORMAT_IYUV:
+        fprintf(stderr, "IYUV");
+        break;
+    case SDL_PIXELFORMAT_YUY2:
+        fprintf(stderr, "YUY2");
+        break;
+    case SDL_PIXELFORMAT_UYVY:
+        fprintf(stderr, "UYVY");
+        break;
+    case SDL_PIXELFORMAT_YVYU:
+        fprintf(stderr, "YVYU");
+        break;
+    default:
+        fprintf(stderr, "0x%8.8x", format);
+        break;
+    }
+}
+
+static void
+SDLTest_PrintRenderer(SDL_RendererInfo * info)
+{
+    int i, count;
+
+    fprintf(stderr, "  Renderer %s:\n", info->name);
+
+    fprintf(stderr, "    Flags: 0x%8.8X", info->flags);
+    fprintf(stderr, " (");
+    count = 0;
+    for (i = 0; i < sizeof(info->flags) * 8; ++i) {
+        Uint32 flag = (1 << i);
+        if (info->flags & flag) {
+            if (count > 0) {
+                fprintf(stderr, " | ");
+            }
+            SDLTest_PrintRendererFlag(flag);
+            ++count;
+        }
+    }
+    fprintf(stderr, ")\n");
+
+    fprintf(stderr, "    Texture formats (%d): ", info->num_texture_formats);
+    for (i = 0; i < (int) info->num_texture_formats; ++i) {
+        if (i > 0) {
+            fprintf(stderr, ", ");
+        }
+        SDLTest_PrintPixelFormat(info->texture_formats[i]);
+    }
+    fprintf(stderr, "\n");
+
+    if (info->max_texture_width || info->max_texture_height) {
+        fprintf(stderr, "    Max Texture Size: %dx%d\n",
+                info->max_texture_width, info->max_texture_height);
+    }
+}
+
+static SDL_Surface *
+SDLTest_LoadIcon(const char *file)
+{
+    SDL_Surface *icon;
+
+    /* Load the icon surface */
+    icon = SDL_LoadBMP(file);
+    if (icon == NULL) {
+        fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
+        return (NULL);
+    }
+
+    if (icon->format->palette) {
+        /* Set the colorkey */
+        SDL_SetColorKey(icon, 1, *((Uint8 *) icon->pixels));
+    }
+
+    return (icon);
+}
+
+SDL_bool
+SDLTest_CommonInit(SDLTest_CommonState * state)
+{
+    int i, j, m, n, w, h;
+    SDL_DisplayMode fullscreen_mode;
+
+    if (state->flags & SDL_INIT_VIDEO) {
+        if (state->verbose & VERBOSE_VIDEO) {
+            n = SDL_GetNumVideoDrivers();
+            if (n == 0) {
+                fprintf(stderr, "No built-in video drivers\n");
+            } else {
+                fprintf(stderr, "Built-in video drivers:");
+                for (i = 0; i < n; ++i) {
+                    if (i > 0) {
+                        fprintf(stderr, ",");
+                    }
+                    fprintf(stderr, " %s", SDL_GetVideoDriver(i));
+                }
+                fprintf(stderr, "\n");
+            }
+        }
+        if (SDL_VideoInit(state->videodriver) < 0) {
+            fprintf(stderr, "Couldn't initialize video driver: %s\n",
+                    SDL_GetError());
+            return SDL_FALSE;
+        }
+        if (state->verbose & VERBOSE_VIDEO) {
+            fprintf(stderr, "Video driver: %s\n",
+                    SDL_GetCurrentVideoDriver());
+        }
+
+        /* Upload GL settings */
+        SDL_GL_SetAttribute(SDL_GL_RED_SIZE, state->gl_red_size);
+        SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, state->gl_green_size);
+        SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, state->gl_blue_size);
+        SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, state->gl_alpha_size);
+        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, state->gl_double_buffer);
+        SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, state->gl_buffer_size);
+        SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, state->gl_depth_size);
+        SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, state->gl_stencil_size);
+        SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, state->gl_accum_red_size);
+        SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, state->gl_accum_green_size);
+        SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, state->gl_accum_blue_size);
+        SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, state->gl_accum_alpha_size);
+        SDL_GL_SetAttribute(SDL_GL_STEREO, state->gl_stereo);
+        SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, state->gl_multisamplebuffers);
+        SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, state->gl_multisamplesamples);
+        if (state->gl_accelerated >= 0) {
+            SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL,
+                                state->gl_accelerated);
+        }
+        SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, state->gl_retained_backing);
+        if (state->gl_major_version) {
+            SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, state->gl_major_version);
+            SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, state->gl_minor_version);
+        }
+        if (state->gl_debug) {
+            SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
+        }
+
+        if (state->verbose & VERBOSE_MODES) {
+            SDL_Rect bounds;
+            SDL_DisplayMode mode;
+            int bpp;
+            Uint32 Rmask, Gmask, Bmask, Amask;
+
+            n = SDL_GetNumVideoDisplays();
+            fprintf(stderr, "Number of displays: %d\n", n);
+            for (i = 0; i < n; ++i) {
+                fprintf(stderr, "Display %d: %s\n", i, SDL_GetDisplayName(i));
+
+                SDL_zero(bounds);
+                SDL_GetDisplayBounds(i, &bounds);
+                fprintf(stderr, "Bounds: %dx%d at %d,%d\n", bounds.w, bounds.h, bounds.x, bounds.y);
+
+                SDL_GetDesktopDisplayMode(i, &mode);
+                SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask,
+                                           &Bmask, &Amask);
+                fprintf(stderr,
+                        "  Current mode: %dx%d@%dHz, %d bits-per-pixel (%s)\n",
+                        mode.w, mode.h, mode.refresh_rate, bpp,
+                        SDL_GetPixelFormatName(mode.format));
+                if (Rmask || Gmask || Bmask) {
+                    fprintf(stderr, "      Red Mask   = 0x%.8x\n", Rmask);
+                    fprintf(stderr, "      Green Mask = 0x%.8x\n", Gmask);
+                    fprintf(stderr, "      Blue Mask  = 0x%.8x\n", Bmask);
+                    if (Amask)
+                        fprintf(stderr, "      Alpha Mask = 0x%.8x\n", Amask);
+                }
+
+                /* Print available fullscreen video modes */
+                m = SDL_GetNumDisplayModes(i);
+                if (m == 0) {
+                    fprintf(stderr, "No available fullscreen video modes\n");
+                } else {
+                    fprintf(stderr, "  Fullscreen video modes:\n");
+                    for (j = 0; j < m; ++j) {
+                        SDL_GetDisplayMode(i, j, &mode);
+                        SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask,
+                                                   &Gmask, &Bmask, &Amask);
+                        fprintf(stderr,
+                                "    Mode %d: %dx%d@%dHz, %d bits-per-pixel (%s)\n",
+                                j, mode.w, mode.h, mode.refresh_rate, bpp,
+                                SDL_GetPixelFormatName(mode.format));
+                        if (Rmask || Gmask || Bmask) {
+                            fprintf(stderr, "        Red Mask   = 0x%.8x\n",
+                                    Rmask);
+                            fprintf(stderr, "        Green Mask = 0x%.8x\n",
+                                    Gmask);
+                            fprintf(stderr, "        Blue Mask  = 0x%.8x\n",
+                                    Bmask);
+                            if (Amask)
+                                fprintf(stderr,
+                                        "        Alpha Mask = 0x%.8x\n",
+                                        Amask);
+                        }
+                    }
+                }
+            }
+        }
+
+        if (state->verbose & VERBOSE_RENDER) {
+            SDL_RendererInfo info;
+
+            n = SDL_GetNumRenderDrivers();
+            if (n == 0) {
+                fprintf(stderr, "No built-in render drivers\n");
+            } else {
+                fprintf(stderr, "Built-in render drivers:\n");
+                for (i = 0; i < n; ++i) {
+                    SDL_GetRenderDriverInfo(i, &info);
+                    SDLTest_PrintRenderer(&info);
+                }
+            }
+        }
+
+        SDL_zero(fullscreen_mode);
+        switch (state->depth) {
+        case 8:
+            fullscreen_mode.format = SDL_PIXELFORMAT_INDEX8;
+            break;
+        case 15:
+            fullscreen_mode.format = SDL_PIXELFORMAT_RGB555;
+            break;
+        case 16:
+            fullscreen_mode.format = SDL_PIXELFORMAT_RGB565;
+            break;
+        case 24:
+            fullscreen_mode.format = SDL_PIXELFORMAT_RGB24;
+            break;
+        default:
+            fullscreen_mode.format = SDL_PIXELFORMAT_RGB888;
+            break;
+        }
+        fullscreen_mode.refresh_rate = state->refresh_rate;
+
+        state->windows =
+            (SDL_Window **) SDL_malloc(state->num_windows *
+                                        sizeof(*state->windows));
+        state->renderers =
+            (SDL_Renderer **) SDL_malloc(state->num_windows *
+                                        sizeof(*state->renderers));
+        if (!state->windows || !state->renderers) {
+            fprintf(stderr, "Out of memory!\n");
+            return SDL_FALSE;
+        }
+        for (i = 0; i < state->num_windows; ++i) {
+            char title[1024];
+
+            if (state->num_windows > 1) {
+                SDL_snprintf(title, SDL_arraysize(title), "%s %d",
+                             state->window_title, i + 1);
+            } else {
+                SDL_strlcpy(title, state->window_title, SDL_arraysize(title));
+            }
+            state->windows[i] =
+                SDL_CreateWindow(title, state->window_x, state->window_y,
+                                 state->window_w, state->window_h,
+                                 state->window_flags);
+            if (!state->windows[i]) {
+                fprintf(stderr, "Couldn't create window: %s\n",
+                        SDL_GetError());
+                return SDL_FALSE;
+            }
+            if (state->window_minW || state->window_minH) {
+                SDL_SetWindowMinimumSize(state->windows[i], state->window_minW, state->window_minH);
+            }
+            if (state->window_maxW || state->window_maxH) {
+                SDL_SetWindowMaximumSize(state->windows[i], state->window_maxW, state->window_maxH);
+            }
+            SDL_GetWindowSize(state->windows[i], &w, &h);
+            if (!(state->window_flags & SDL_WINDOW_RESIZABLE) &&
+                (w != state->window_w || h != state->window_h)) {
+                printf("Window requested size %dx%d, got %dx%d\n", state->window_w, state->window_h, w, h);
+                state->window_w = w;
+                state->window_h = h;
+            }
+            if (SDL_SetWindowDisplayMode(state->windows[i], &fullscreen_mode) < 0) {
+                fprintf(stderr, "Can't set up fullscreen display mode: %s\n",
+                        SDL_GetError());
+                return SDL_FALSE;
+            }
+
+            if (state->window_icon) {
+                SDL_Surface *icon = SDLTest_LoadIcon(state->window_icon);
+                if (icon) {
+                    SDL_SetWindowIcon(state->windows[i], icon);
+                    SDL_FreeSurface(icon);
+                }
+            }
+
+            SDL_ShowWindow(state->windows[i]);
+
+            state->renderers[i] = NULL;
+
+            if (!state->skip_renderer
+                && (state->renderdriver
+                    || !(state->window_flags & SDL_WINDOW_OPENGL))) {
+                m = -1;
+                if (state->renderdriver) {
+                    SDL_RendererInfo info;
+                    n = SDL_GetNumRenderDrivers();
+                    for (j = 0; j < n; ++j) {
+                        SDL_GetRenderDriverInfo(j, &info);
+                        if (SDL_strcasecmp(info.name, state->renderdriver) ==
+                            0) {
+                            m = j;
+                            break;
+                        }
+                    }
+                    if (m == n) {
+                        fprintf(stderr,
+                                "Couldn't find render driver named %s",
+                                state->renderdriver);
+                        return SDL_FALSE;
+                    }
+                }
+                state->renderers[i] = SDL_CreateRenderer(state->windows[i],
+                                            m, state->render_flags);
+                if (!state->renderers[i]) {
+                    fprintf(stderr, "Couldn't create renderer: %s\n",
+                            SDL_GetError());
+                    return SDL_FALSE;
+                }
+                if (state->logical_w && state->logical_h) {
+                    SDL_RenderSetLogicalSize(state->renderers[i], state->logical_w, state->logical_h);
+                } else if (state->scale) {
+                    SDL_RenderSetScale(state->renderers[i], state->scale, state->scale);
+                }
+                if (state->verbose & VERBOSE_RENDER) {
+                    SDL_RendererInfo info;
+
+                    fprintf(stderr, "Current renderer:\n");
+                    SDL_GetRendererInfo(state->renderers[i], &info);
+                    SDLTest_PrintRenderer(&info);
+                }
+            }
+        }
+    }
+
+    if (state->flags & SDL_INIT_AUDIO) {
+        if (state->verbose & VERBOSE_AUDIO) {
+            n = SDL_GetNumAudioDrivers();
+            if (n == 0) {
+                fprintf(stderr, "No built-in audio drivers\n");
+            } else {
+                fprintf(stderr, "Built-in audio drivers:");
+                for (i = 0; i < n; ++i) {
+                    if (i > 0) {
+                        fprintf(stderr, ",");
+                    }
+                    fprintf(stderr, " %s", SDL_GetAudioDriver(i));
+                }
+                fprintf(stderr, "\n");
+            }
+        }
+        if (SDL_AudioInit(state->audiodriver) < 0) {
+            fprintf(stderr, "Couldn't initialize audio driver: %s\n",
+                    SDL_GetError());
+            return SDL_FALSE;
+        }
+        if (state->verbose & VERBOSE_VIDEO) {
+            fprintf(stderr, "Audio driver: %s\n",
+                    SDL_GetCurrentAudioDriver());
+        }
+
+        if (SDL_OpenAudio(&state->audiospec, NULL) < 0) {
+            fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
+            return SDL_FALSE;
+        }
+    }
+
+    return SDL_TRUE;
+}
+
+static void
+SDLTest_PrintEvent(SDL_Event * event)
+{
+    if ((event->type == SDL_MOUSEMOTION) || (event->type == SDL_FINGERMOTION)) {
+        /* Mouse and finger motion are really spammy */
+        return;
+    }
+
+    fprintf(stderr, "SDL EVENT: ");
+    switch (event->type) {
+    case SDL_WINDOWEVENT:
+        switch (event->window.event) {
+        case SDL_WINDOWEVENT_SHOWN:
+            fprintf(stderr, "Window %d shown", event->window.windowID);
+            break;
+        case SDL_WINDOWEVENT_HIDDEN:
+            fprintf(stderr, "Window %d hidden", event->window.windowID);
+            break;
+        case SDL_WINDOWEVENT_EXPOSED:
+            fprintf(stderr, "Window %d exposed", event->window.windowID);
+            break;
+        case SDL_WINDOWEVENT_MOVED:
+            fprintf(stderr, "Window %d moved to %d,%d",
+                    event->window.windowID, event->window.data1,
+                    event->window.data2);
+            break;
+        case SDL_WINDOWEVENT_RESIZED:
+            fprintf(stderr, "Window %d resized to %dx%d",
+                    event->window.windowID, event->window.data1,
+                    event->window.data2);
+            break;
+        case SDL_WINDOWEVENT_SIZE_CHANGED:
+            fprintf(stderr, "Window %d changed size to %dx%d",
+                    event->window.windowID, event->window.data1,
+                    event->window.data2);
+            break;
+        case SDL_WINDOWEVENT_MINIMIZED:
+            fprintf(stderr, "Window %d minimized", event->window.windowID);
+            break;
+        case SDL_WINDOWEVENT_MAXIMIZED:
+            fprintf(stderr, "Window %d maximized", event->window.windowID);
+            break;
+        case SDL_WINDOWEVENT_RESTORED:
+            fprintf(stderr, "Window %d restored", event->window.windowID);
+            break;
+        case SDL_WINDOWEVENT_ENTER:
+            fprintf(stderr, "Mouse entered window %d",
+                    event->window.windowID);
+            break;
+        case SDL_WINDOWEVENT_LEAVE:
+            fprintf(stderr, "Mouse left window %d", event->window.windowID);
+            break;
+        case SDL_WINDOWEVENT_FOCUS_GAINED:
+            fprintf(stderr, "Window %d gained keyboard focus",
+                    event->window.windowID);
+            break;
+        case SDL_WINDOWEVENT_FOCUS_LOST:
+            fprintf(stderr, "Window %d lost keyboard focus",
+                    event->window.windowID);
+            break;
+        case SDL_WINDOWEVENT_CLOSE:
+            fprintf(stderr, "Window %d closed", event->window.windowID);
+            break;
+        default:
+            fprintf(stderr, "Window %d got unknown event %d",
+                    event->window.windowID, event->window.event);
+            break;
+        }
+        break;
+    case SDL_KEYDOWN:
+        fprintf(stderr,
+                "Keyboard: key pressed  in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s",
+                event->key.windowID,
+                event->key.keysym.scancode,
+                SDL_GetScancodeName(event->key.keysym.scancode),
+                event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym));
+        break;
+    case SDL_KEYUP:
+        fprintf(stderr,
+                "Keyboard: key released in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s",
+                event->key.windowID,
+                event->key.keysym.scancode,
+                SDL_GetScancodeName(event->key.keysym.scancode),
+                event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym));
+        break;
+    case SDL_TEXTINPUT:
+        fprintf(stderr, "Keyboard: text input \"%s\" in window %d",
+                event->text.text, event->text.windowID);
+        break;
+    case SDL_MOUSEMOTION:
+        fprintf(stderr, "Mouse: moved to %d,%d (%d,%d) in window %d",
+                event->motion.x, event->motion.y,
+                event->motion.xrel, event->motion.yrel,
+                event->motion.windowID);
+        break;
+    case SDL_MOUSEBUTTONDOWN:
+        fprintf(stderr, "Mouse: button %d pressed at %d,%d in window %d",
+                event->button.button, event->button.x, event->button.y,
+                event->button.windowID);
+        break;
+    case SDL_MOUSEBUTTONUP:
+        fprintf(stderr, "Mouse: button %d released at %d,%d in window %d",
+                event->button.button, event->button.x, event->button.y,
+                event->button.windowID);
+        break;
+    case SDL_MOUSEWHEEL:
+        fprintf(stderr,
+                "Mouse: wheel scrolled %d in x and %d in y in window %d",
+                event->wheel.x, event->wheel.y, event->wheel.windowID);
+        break;
+    case SDL_JOYBALLMOTION:
+        fprintf(stderr, "Joystick %d: ball %d moved by %d,%d",
+                event->jball.which, event->jball.ball, event->jball.xrel,
+                event->jball.yrel);
+        break;
+    case SDL_JOYHATMOTION:
+        fprintf(stderr, "Joystick %d: hat %d moved to ", event->jhat.which,
+                event->jhat.hat);
+        switch (event->jhat.value) {
+        case SDL_HAT_CENTERED:
+            fprintf(stderr, "CENTER");
+            break;
+        case SDL_HAT_UP:
+            fprintf(stderr, "UP");
+            break;
+        case SDL_HAT_RIGHTUP:
+            fprintf(stderr, "RIGHTUP");
+            break;
+        case SDL_HAT_RIGHT:
+            fprintf(stderr, "RIGHT");
+            break;
+        case SDL_HAT_RIGHTDOWN:
+            fprintf(stderr, "RIGHTDOWN");
+            break;
+        case SDL_HAT_DOWN:
+            fprintf(stderr, "DOWN");
+            break;
+        case SDL_HAT_LEFTDOWN:
+            fprintf(stderr, "LEFTDOWN");
+            break;
+        case SDL_HAT_LEFT:
+            fprintf(stderr, "LEFT");
+            break;
+        case SDL_HAT_LEFTUP:
+            fprintf(stderr, "LEFTUP");
+            break;
+        default:
+            fprintf(stderr, "UNKNOWN");
+            break;
+        }
+        break;
+    case SDL_JOYBUTTONDOWN:
+        fprintf(stderr, "Joystick %d: button %d pressed",
+                event->jbutton.which, event->jbutton.button);
+        break;
+    case SDL_JOYBUTTONUP:
+        fprintf(stderr, "Joystick %d: button %d released",
+                event->jbutton.which, event->jbutton.button);
+        break;
+    case SDL_CLIPBOARDUPDATE:
+        fprintf(stderr, "Clipboard updated");
+        break;
+
+    case SDL_FINGERDOWN:
+    case SDL_FINGERUP:
+        fprintf(stderr, "Finger: %s touch=%lld, finger=%lld, x=%f, y=%f, dx=%f, dy=%f, pressure=%f",
+                (event->type == SDL_FINGERDOWN) ? "down" : "up",
+                (long long) event->tfinger.touchId,
+                (long long) event->tfinger.fingerId,
+                event->tfinger.x, event->tfinger.y,
+                event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure);
+        break;
+
+    case SDL_QUIT:
+        fprintf(stderr, "Quit requested");
+        break;
+    case SDL_USEREVENT:
+        fprintf(stderr, "User event %d", event->user.code);
+        break;
+    default:
+        fprintf(stderr, "Unknown event %d", event->type);
+        break;
+    }
+    fprintf(stderr, "\n");
+}
+
+static void
+SDLTest_ScreenShot(SDL_Renderer *renderer)
+{
+    SDL_Rect viewport;
+    SDL_Surface *surface;
+
+    if (!renderer) {
+        return;
+    }
+
+    SDL_RenderGetViewport(renderer, &viewport);
+    surface = SDL_CreateRGBSurface(0, viewport.w, viewport.h, 24,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+                    0x00FF0000, 0x0000FF00, 0x000000FF,
+#else
+                    0x000000FF, 0x0000FF00, 0x00FF0000,
+#endif
+                    0x00000000);
+    if (!surface) {
+        fprintf(stderr, "Couldn't create surface: %s\n", SDL_GetError());
+        return;
+    }
+
+    if (SDL_RenderReadPixels(renderer, NULL, surface->format->format,
+                             surface->pixels, surface->pitch) < 0) {
+        fprintf(stderr, "Couldn't read screen: %s\n", SDL_GetError());
+        return;
+    }
+
+    if (SDL_SaveBMP(surface, "screenshot.bmp") < 0) {
+        fprintf(stderr, "Couldn't save screenshot.bmp: %s\n", SDL_GetError());
+        return;
+    }
+}
+
+static void
+FullscreenTo(int index, int windowId)
+{
+    Uint32 flags;
+    struct SDL_Rect rect = { 0, 0, 0, 0 };
+    SDL_Window *window = SDL_GetWindowFromID(windowId);
+    if (!window) {
+        return;
+    }
+
+    SDL_GetDisplayBounds( index, &rect );
+
+    flags = SDL_GetWindowFlags(window);
+    if (flags & SDL_WINDOW_FULLSCREEN) {
+        SDL_SetWindowFullscreen( window, SDL_FALSE );
+        SDL_Delay( 15 );
+    }
+
+    SDL_SetWindowPosition( window, rect.x, rect.y );
+    SDL_SetWindowFullscreen( window, SDL_TRUE );
+}
+
+void
+SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done)
+{
+    int i;
+    static SDL_MouseMotionEvent lastEvent;
+
+    if (state->verbose & VERBOSE_EVENT) {
+        SDLTest_PrintEvent(event);
+    }
+
+    switch (event->type) {
+    case SDL_WINDOWEVENT:
+        switch (event->window.event) {
+        case SDL_WINDOWEVENT_CLOSE:
+            {
+                SDL_Window *window = SDL_GetWindowFromID(event->window.windowID);
+                if (window) {
+                    SDL_DestroyWindow(window);
+                }
+            }
+            break;
+        }
+        break;
+    case SDL_KEYDOWN:
+        switch (event->key.keysym.sym) {
+            /* Add hotkeys here */
+        case SDLK_PRINTSCREEN: {
+                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
+                if (window) {
+                    for (i = 0; i < state->num_windows; ++i) {
+                        if (window == state->windows[i]) {
+                            SDLTest_ScreenShot(state->renderers[i]);
+                        }
+                    }
+                }
+            }
+            break;
+        case SDLK_EQUALS:
+            if (event->key.keysym.mod & KMOD_CTRL) {
+                /* Ctrl-+ double the size of the window */
+                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
+                if (window) {
+                    int w, h;
+                    SDL_GetWindowSize(window, &w, &h);
+                    SDL_SetWindowSize(window, w*2, h*2);
+                }
+            }
+            break;
+        case SDLK_MINUS:
+            if (event->key.keysym.mod & KMOD_CTRL) {
+                /* Ctrl-- half the size of the window */
+                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
+                if (window) {
+                    int w, h;
+                    SDL_GetWindowSize(window, &w, &h);
+                    SDL_SetWindowSize(window, w/2, h/2);
+                }
+            }
+            break;
+        case SDLK_c:
+            if (event->key.keysym.mod & KMOD_CTRL) {
+                /* Ctrl-C copy awesome text! */
+                SDL_SetClipboardText("SDL rocks!\nYou know it!");
+                printf("Copied text to clipboard\n");
+            }
+            if (event->key.keysym.mod & KMOD_ALT) {
+                /* Alt-C toggle a render clip rectangle */
+                for (i = 0; i < state->num_windows; ++i) {
+                    int w, h;
+                    if (state->renderers[i]) {
+                        SDL_Rect clip;
+                        SDL_GetWindowSize(state->windows[i], &w, &h);
+                        SDL_RenderGetClipRect(state->renderers[i], &clip);
+                        if (SDL_RectEmpty(&clip)) {
+                            clip.x = w/4;
+                            clip.y = h/4;
+                            clip.w = w/2;
+                            clip.h = h/2;
+                            SDL_RenderSetClipRect(state->renderers[i], &clip);
+                        } else {
+                            SDL_RenderSetClipRect(state->renderers[i], NULL);
+                        }
+                    }
+                }
+            }
+            break;
+        case SDLK_v:
+            if (event->key.keysym.mod & KMOD_CTRL) {
+                /* Ctrl-V paste awesome text! */
+                char *text = SDL_GetClipboardText();
+                if (*text) {
+                    printf("Clipboard: %s\n", text);
+                } else {
+                    printf("Clipboard is empty\n");
+                }
+                SDL_free(text);
+            }
+            break;
+        case SDLK_g:
+            if (event->key.keysym.mod & KMOD_CTRL) {
+                /* Ctrl-G toggle grab */
+                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
+                if (window) {
+                    SDL_SetWindowGrab(window, !SDL_GetWindowGrab(window) ? SDL_TRUE : SDL_FALSE);
+                }
+            }
+            break;
+        case SDLK_m:
+            if (event->key.keysym.mod & KMOD_CTRL) {
+                /* Ctrl-M maximize */
+                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
+                if (window) {
+                    Uint32 flags = SDL_GetWindowFlags(window);
+                    if (flags & SDL_WINDOW_MAXIMIZED) {
+                        SDL_RestoreWindow(window);
+                    } else {
+                        SDL_MaximizeWindow(window);
+                    }
+                }
+            }
+            break;
+        case SDLK_r:
+            if (event->key.keysym.mod & KMOD_CTRL) {
+                /* Ctrl-R toggle mouse relative mode */
+                SDL_SetRelativeMouseMode(!SDL_GetRelativeMouseMode() ? SDL_TRUE : SDL_FALSE);
+            }
+            break;
+        case SDLK_z:
+            if (event->key.keysym.mod & KMOD_CTRL) {
+                /* Ctrl-Z minimize */
+                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
+                if (window) {
+                    SDL_MinimizeWindow(window);
+                }
+            }
+            break;
+        case SDLK_RETURN:
+            if (event->key.keysym.mod & KMOD_CTRL) {
+                /* Ctrl-Enter toggle fullscreen */
+                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
+                if (window) {
+                    Uint32 flags = SDL_GetWindowFlags(window);
+                    if (flags & SDL_WINDOW_FULLSCREEN) {
+                        SDL_SetWindowFullscreen(window, SDL_FALSE);
+                    } else {
+                        SDL_SetWindowFullscreen(window, SDL_TRUE);
+                    }
+                }
+            } else if (event->key.keysym.mod & KMOD_ALT) {
+                /* Alt-Enter toggle fullscreen desktop */
+                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
+                if (window) {
+                    Uint32 flags = SDL_GetWindowFlags(window);
+                    if (flags & SDL_WINDOW_FULLSCREEN) {
+                        SDL_SetWindowFullscreen(window, SDL_FALSE);
+                    } else {
+                        SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
+                    }
+                }
+            }
+            break;
+        case SDLK_b:
+            if (event->key.keysym.mod & KMOD_CTRL) {
+                /* Ctrl-B toggle window border */
+                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
+                if (window) {
+                    const Uint32 flags = SDL_GetWindowFlags(window);
+                    const SDL_bool b = ((flags & SDL_WINDOW_BORDERLESS) != 0) ? SDL_TRUE : SDL_FALSE;
+                    SDL_SetWindowBordered(window, b);
+                }
+            }
+            break;
+        case SDLK_0:
+            if (event->key.keysym.mod & KMOD_CTRL) {
+                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
+                SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Test Message", "You're awesome!", window);
+            }
+            break;
+        case SDLK_1:
+            if (event->key.keysym.mod & KMOD_CTRL) {
+                FullscreenTo(0, event->key.windowID);
+            }
+            break;
+        case SDLK_2:
+            if (event->key.keysym.mod & KMOD_CTRL) {
+                FullscreenTo(1, event->key.windowID);
+            }
+            break;
+        case SDLK_ESCAPE:
+            *done = 1;
+            break;
+        case SDLK_SPACE:
+        {
+            char message[256];
+            SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
+
+            SDL_snprintf(message, sizeof(message), "(%i, %i), rel (%i, %i)\n", lastEvent.x, lastEvent.y, lastEvent.xrel, lastEvent.yrel);
+            SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Last mouse position", message, window);
+            break;
+        }
+        default:
+            break;
+        }
+        break;
+    case SDL_QUIT:
+        *done = 1;
+        break;
+    case SDL_MOUSEMOTION:
+        lastEvent = event->motion;
+        break;
+    }
+}
+
+void
+SDLTest_CommonQuit(SDLTest_CommonState * state)
+{
+    int i;
+
+    if (state->windows) {
+        SDL_free(state->windows);
+    }
+    if (state->renderers) {
+        for (i = 0; i < state->num_windows; ++i) {
+            if (state->renderers[i]) {
+                SDL_DestroyRenderer(state->renderers[i]);
+            }
+        }
+        SDL_free(state->renderers);
+    }
+    if (state->flags & SDL_INIT_VIDEO) {
+        SDL_VideoQuit();
+    }
+    if (state->flags & SDL_INIT_AUDIO) {
+        SDL_AudioQuit();
+    }
+    SDL_free(state);
+}
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 107 - 0
Source/ThirdParty/SDL/src/test/SDL_test_compare.c

@@ -0,0 +1,107 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2013 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.
+*/
+
+/*
+
+ Based on automated SDL_Surface tests originally written by Edgar Simo 'bobbens'.
+
+ Rewritten for test lib by Andreas Schiffler.
+
+*/
+
+#include "SDL_config.h"
+
+#include "SDL_test.h"
+
+
+/* Counter for _CompareSurface calls; used for filename creation when comparisons fail */
+static int _CompareSurfaceCount = 0;
+
+/* Compare surfaces */
+int SDLTest_CompareSurfaces(SDL_Surface *surface, SDL_Surface *referenceSurface, int allowable_error)
+{
+   int ret;
+   int i,j;
+   int bpp, bpp_reference;
+   Uint8 *p, *p_reference;
+   int dist;
+   Uint8 R, G, B, A;
+   Uint8 Rd, Gd, Bd, Ad;
+   char imageFilename[128];
+   char referenceFilename[128];
+
+   /* Validate input surfaces */
+   if (surface == NULL || referenceSurface == NULL) {
+      return -1;
+   }
+
+   /* Make sure surface size is the same. */
+   if ((surface->w != referenceSurface->w) || (surface->h != referenceSurface->h)) {
+      return -2;
+   }
+
+   /* Sanitize input value */
+   if (allowable_error<0) {
+      allowable_error = 0;
+   }
+
+   SDL_LockSurface( surface );
+   SDL_LockSurface( referenceSurface );
+
+   ret = 0;
+   bpp = surface->format->BytesPerPixel;
+   bpp_reference = referenceSurface->format->BytesPerPixel;
+   /* Compare image - should be same format. */
+   for (j=0; j<surface->h; j++) {
+      for (i=0; i<surface->w; i++) {
+         p  = (Uint8 *)surface->pixels + j * surface->pitch + i * bpp;
+         p_reference = (Uint8 *)referenceSurface->pixels + j * referenceSurface->pitch + i * bpp_reference;
+
+         SDL_GetRGBA(*(Uint32*)p, surface->format, &R, &G, &B, &A);
+         SDL_GetRGBA(*(Uint32*)p_reference, referenceSurface->format, &Rd, &Gd, &Bd, &Ad);
+
+         dist = 0;
+         dist += (R-Rd)*(R-Rd);
+         dist += (G-Gd)*(G-Gd);
+         dist += (B-Bd)*(B-Bd);
+
+         /* Allow some difference in blending accuracy */
+         if (dist > allowable_error) {
+            ret++;
+         }
+      }
+   }
+
+   SDL_UnlockSurface( surface );
+   SDL_UnlockSurface( referenceSurface );
+
+   /* Save test image and reference for analysis on failures */
+   _CompareSurfaceCount++;
+   if (ret != 0) {
+      SDL_snprintf(imageFilename, 127, "CompareSurfaces%04d_TestOutput.bmp", _CompareSurfaceCount);
+      SDL_SaveBMP(surface, imageFilename);
+      SDL_snprintf(referenceFilename, 127, "CompareSurfaces%04d_Reference.bmp", _CompareSurfaceCount);
+      SDL_SaveBMP(referenceSurface, referenceFilename);
+      SDLTest_LogError("Surfaces from failed comparison saved as '%s' and '%s'", imageFilename, referenceFilename);
+   }
+
+   return ret;
+}

+ 165 - 0
Source/ThirdParty/SDL/src/test/SDL_test_crc32.c

@@ -0,0 +1,165 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2013 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.
+*/
+
+/*
+
+ Used by the test execution component.
+ Original source code contributed by A. Schiffler for GSOC project.
+
+*/
+
+#include "SDL_config.h"
+
+#include "SDL_test.h"
+
+
+int SDLTest_Crc32Init(SDLTest_Crc32Context *crcContext)
+{
+  int i,j;
+  CrcUint32 c;
+
+  /* Sanity check context pointer */
+  if (crcContext==NULL) {
+   return -1;
+  }
+
+  /*
+   * Build auxiliary table for parallel byte-at-a-time CRC-32
+   */
+#ifdef ORIGINAL_METHOD
+  for (i = 0; i < 256; ++i) {
+    for (c = i << 24, j = 8; j > 0; --j) {
+      c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1);
+    }
+    crcContext->crc32_table[i] = c;
+  }
+#else
+  for (i=0; i<256; i++) {
+   c = i;
+   for (j=8; j>0; j--) {
+    if (c & 1) {
+     c = (c >> 1) ^ CRC32_POLY;
+    } else {
+     c >>= 1;
+    }
+   }
+   crcContext->crc32_table[i] = c;
+  }
+#endif
+
+  return 0;
+}
+
+/* Complete CRC32 calculation on a memory block */
+
+int SDLTest_Crc32Calc(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32)
+{
+  if (SDLTest_Crc32CalcStart(crcContext,crc32)) {
+   return -1;
+  }
+
+  if (SDLTest_Crc32CalcBuffer(crcContext, inBuf, inLen, crc32)) {
+   return -1;
+  }
+
+  if (SDLTest_Crc32CalcEnd(crcContext, crc32)) {
+   return -1;
+  }
+
+  return 0;
+}
+
+/* Start crc calculation */
+
+int SDLTest_Crc32CalcStart(SDLTest_Crc32Context * crcContext, CrcUint32 *crc32)
+{
+  /* Sanity check pointers */
+  if (crcContext==NULL) {
+   *crc32=0;
+   return -1;
+  }
+
+  /*
+   * Preload shift register, per CRC-32 spec
+   */
+  *crc32 = 0xffffffff;
+
+  return 0;
+}
+
+/* Finish crc calculation */
+
+int SDLTest_Crc32CalcEnd(SDLTest_Crc32Context * crcContext, CrcUint32 *crc32)
+{
+  /* Sanity check pointers */
+  if (crcContext==NULL) {
+   *crc32=0;
+   return -1;
+  }
+
+  /*
+   * Return complement, per CRC-32 spec
+   */
+  *crc32 = (~(*crc32));
+
+  return 0;
+}
+
+/* Include memory block in crc */
+
+int SDLTest_Crc32CalcBuffer(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32)
+{
+  CrcUint8    *p;
+  register CrcUint32    crc;
+
+  if (crcContext==NULL) {
+   *crc32=0;
+   return -1;
+  }
+
+  if (inBuf==NULL) {
+   return -1;
+  }
+
+  /*
+   * Calculate CRC from data
+   */
+  crc = *crc32;
+  for (p = inBuf; inLen > 0; ++p, --inLen) {
+#ifdef ORIGINAL_METHOD
+    crc = (crc << 8) ^ crcContext->crc32_table[(crc >> 24) ^ *p];
+#else
+    crc = ((crc >> 8) & 0x00FFFFFF) ^ crcContext->crc32_table[ (crc ^ *p) & 0xFF ];
+#endif
+  }
+  *crc32 = crc;
+
+  return 0;
+}
+
+int SDLTest_Crc32Done(SDLTest_Crc32Context * crcContext)
+{
+  if (crcContext==NULL) {
+     return -1;
+  }
+
+  return 0;
+}

+ 3238 - 0
Source/ThirdParty/SDL/src/test/SDL_test_font.c

@@ -0,0 +1,3238 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2013 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.
+*/
+#include "SDL_config.h"
+
+#include "SDL_test.h"
+
+/* ---- 8x8 font definition ---- */
+
+/* Originally part of SDL2_gfx */
+
+/* ZLIB (c) A. Schiffler 2012 */
+
+#define SDL_TESTFONTDATAMAX (8*256)
+
+static unsigned char SDLTest_FontData[SDL_TESTFONTDATAMAX] = {
+
+    /*
+    * 0 0x00 '^@'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 1 0x01 '^A'
+    */
+    0x7e,           /* 01111110 */
+    0x81,           /* 10000001 */
+    0xa5,           /* 10100101 */
+    0x81,           /* 10000001 */
+    0xbd,           /* 10111101 */
+    0x99,           /* 10011001 */
+    0x81,           /* 10000001 */
+    0x7e,           /* 01111110 */
+
+    /*
+    * 2 0x02 '^B'
+    */
+    0x7e,           /* 01111110 */
+    0xff,           /* 11111111 */
+    0xdb,           /* 11011011 */
+    0xff,           /* 11111111 */
+    0xc3,           /* 11000011 */
+    0xe7,           /* 11100111 */
+    0xff,           /* 11111111 */
+    0x7e,           /* 01111110 */
+
+    /*
+    * 3 0x03 '^C'
+    */
+    0x6c,           /* 01101100 */
+    0xfe,           /* 11111110 */
+    0xfe,           /* 11111110 */
+    0xfe,           /* 11111110 */
+    0x7c,           /* 01111100 */
+    0x38,           /* 00111000 */
+    0x10,           /* 00010000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 4 0x04 '^D'
+    */
+    0x10,           /* 00010000 */
+    0x38,           /* 00111000 */
+    0x7c,           /* 01111100 */
+    0xfe,           /* 11111110 */
+    0x7c,           /* 01111100 */
+    0x38,           /* 00111000 */
+    0x10,           /* 00010000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 5 0x05 '^E'
+    */
+    0x38,           /* 00111000 */
+    0x7c,           /* 01111100 */
+    0x38,           /* 00111000 */
+    0xfe,           /* 11111110 */
+    0xfe,           /* 11111110 */
+    0xd6,           /* 11010110 */
+    0x10,           /* 00010000 */
+    0x38,           /* 00111000 */
+
+    /*
+    * 6 0x06 '^F'
+    */
+    0x10,           /* 00010000 */
+    0x38,           /* 00111000 */
+    0x7c,           /* 01111100 */
+    0xfe,           /* 11111110 */
+    0xfe,           /* 11111110 */
+    0x7c,           /* 01111100 */
+    0x10,           /* 00010000 */
+    0x38,           /* 00111000 */
+
+    /*
+    * 7 0x07 '^G'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x18,           /* 00011000 */
+    0x3c,           /* 00111100 */
+    0x3c,           /* 00111100 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 8 0x08 '^H'
+    */
+    0xff,           /* 11111111 */
+    0xff,           /* 11111111 */
+    0xe7,           /* 11100111 */
+    0xc3,           /* 11000011 */
+    0xc3,           /* 11000011 */
+    0xe7,           /* 11100111 */
+    0xff,           /* 11111111 */
+    0xff,           /* 11111111 */
+
+    /*
+    * 9 0x09 '^I'
+    */
+    0x00,           /* 00000000 */
+    0x3c,           /* 00111100 */
+    0x66,           /* 01100110 */
+    0x42,           /* 01000010 */
+    0x42,           /* 01000010 */
+    0x66,           /* 01100110 */
+    0x3c,           /* 00111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 10 0x0a '^J'
+    */
+    0xff,           /* 11111111 */
+    0xc3,           /* 11000011 */
+    0x99,           /* 10011001 */
+    0xbd,           /* 10111101 */
+    0xbd,           /* 10111101 */
+    0x99,           /* 10011001 */
+    0xc3,           /* 11000011 */
+    0xff,           /* 11111111 */
+
+    /*
+    * 11 0x0b '^K'
+    */
+    0x0f,           /* 00001111 */
+    0x07,           /* 00000111 */
+    0x0f,           /* 00001111 */
+    0x7d,           /* 01111101 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0x78,           /* 01111000 */
+
+    /*
+    * 12 0x0c '^L'
+    */
+    0x3c,           /* 00111100 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x3c,           /* 00111100 */
+    0x18,           /* 00011000 */
+    0x7e,           /* 01111110 */
+    0x18,           /* 00011000 */
+
+    /*
+    * 13 0x0d '^M'
+    */
+    0x3f,           /* 00111111 */
+    0x33,           /* 00110011 */
+    0x3f,           /* 00111111 */
+    0x30,           /* 00110000 */
+    0x30,           /* 00110000 */
+    0x70,           /* 01110000 */
+    0xf0,           /* 11110000 */
+    0xe0,           /* 11100000 */
+
+    /*
+    * 14 0x0e '^N'
+    */
+    0x7f,           /* 01111111 */
+    0x63,           /* 01100011 */
+    0x7f,           /* 01111111 */
+    0x63,           /* 01100011 */
+    0x63,           /* 01100011 */
+    0x67,           /* 01100111 */
+    0xe6,           /* 11100110 */
+    0xc0,           /* 11000000 */
+
+    /*
+    * 15 0x0f '^O'
+    */
+    0x18,           /* 00011000 */
+    0xdb,           /* 11011011 */
+    0x3c,           /* 00111100 */
+    0xe7,           /* 11100111 */
+    0xe7,           /* 11100111 */
+    0x3c,           /* 00111100 */
+    0xdb,           /* 11011011 */
+    0x18,           /* 00011000 */
+
+    /*
+    * 16 0x10 '^P'
+    */
+    0x80,           /* 10000000 */
+    0xe0,           /* 11100000 */
+    0xf8,           /* 11111000 */
+    0xfe,           /* 11111110 */
+    0xf8,           /* 11111000 */
+    0xe0,           /* 11100000 */
+    0x80,           /* 10000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 17 0x11 '^Q'
+    */
+    0x02,           /* 00000010 */
+    0x0e,           /* 00001110 */
+    0x3e,           /* 00111110 */
+    0xfe,           /* 11111110 */
+    0x3e,           /* 00111110 */
+    0x0e,           /* 00001110 */
+    0x02,           /* 00000010 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 18 0x12 '^R'
+    */
+    0x18,           /* 00011000 */
+    0x3c,           /* 00111100 */
+    0x7e,           /* 01111110 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x7e,           /* 01111110 */
+    0x3c,           /* 00111100 */
+    0x18,           /* 00011000 */
+
+    /*
+    * 19 0x13 '^S'
+    */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x00,           /* 00000000 */
+    0x66,           /* 01100110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 20 0x14 '^T'
+    */
+    0x7f,           /* 01111111 */
+    0xdb,           /* 11011011 */
+    0xdb,           /* 11011011 */
+    0x7b,           /* 01111011 */
+    0x1b,           /* 00011011 */
+    0x1b,           /* 00011011 */
+    0x1b,           /* 00011011 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 21 0x15 '^U'
+    */
+    0x3e,           /* 00111110 */
+    0x61,           /* 01100001 */
+    0x3c,           /* 00111100 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x3c,           /* 00111100 */
+    0x86,           /* 10000110 */
+    0x7c,           /* 01111100 */
+
+    /*
+    * 22 0x16 '^V'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x7e,           /* 01111110 */
+    0x7e,           /* 01111110 */
+    0x7e,           /* 01111110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 23 0x17 '^W'
+    */
+    0x18,           /* 00011000 */
+    0x3c,           /* 00111100 */
+    0x7e,           /* 01111110 */
+    0x18,           /* 00011000 */
+    0x7e,           /* 01111110 */
+    0x3c,           /* 00111100 */
+    0x18,           /* 00011000 */
+    0xff,           /* 11111111 */
+
+    /*
+    * 24 0x18 '^X'
+    */
+    0x18,           /* 00011000 */
+    0x3c,           /* 00111100 */
+    0x7e,           /* 01111110 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 25 0x19 '^Y'
+    */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x7e,           /* 01111110 */
+    0x3c,           /* 00111100 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 26 0x1a '^Z'
+    */
+    0x00,           /* 00000000 */
+    0x18,           /* 00011000 */
+    0x0c,           /* 00001100 */
+    0xfe,           /* 11111110 */
+    0x0c,           /* 00001100 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 27 0x1b '^['
+    */
+    0x00,           /* 00000000 */
+    0x30,           /* 00110000 */
+    0x60,           /* 01100000 */
+    0xfe,           /* 11111110 */
+    0x60,           /* 01100000 */
+    0x30,           /* 00110000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 28 0x1c '^\'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xc0,           /* 11000000 */
+    0xc0,           /* 11000000 */
+    0xc0,           /* 11000000 */
+    0xfe,           /* 11111110 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 29 0x1d '^]'
+    */
+    0x00,           /* 00000000 */
+    0x24,           /* 00100100 */
+    0x66,           /* 01100110 */
+    0xff,           /* 11111111 */
+    0x66,           /* 01100110 */
+    0x24,           /* 00100100 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 30 0x1e '^^'
+    */
+    0x00,           /* 00000000 */
+    0x18,           /* 00011000 */
+    0x3c,           /* 00111100 */
+    0x7e,           /* 01111110 */
+    0xff,           /* 11111111 */
+    0xff,           /* 11111111 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 31 0x1f '^_'
+    */
+    0x00,           /* 00000000 */
+    0xff,           /* 11111111 */
+    0xff,           /* 11111111 */
+    0x7e,           /* 01111110 */
+    0x3c,           /* 00111100 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 32 0x20 ' '
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 33 0x21 '!'
+    */
+    0x18,           /* 00011000 */
+    0x3c,           /* 00111100 */
+    0x3c,           /* 00111100 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 34 0x22 '"'
+    */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x24,           /* 00100100 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 35 0x23 '#'
+    */
+    0x6c,           /* 01101100 */
+    0x6c,           /* 01101100 */
+    0xfe,           /* 11111110 */
+    0x6c,           /* 01101100 */
+    0xfe,           /* 11111110 */
+    0x6c,           /* 01101100 */
+    0x6c,           /* 01101100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 36 0x24 '$'
+    */
+    0x18,           /* 00011000 */
+    0x3e,           /* 00111110 */
+    0x60,           /* 01100000 */
+    0x3c,           /* 00111100 */
+    0x06,           /* 00000110 */
+    0x7c,           /* 01111100 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 37 0x25 '%'
+    */
+    0x00,           /* 00000000 */
+    0xc6,           /* 11000110 */
+    0xcc,           /* 11001100 */
+    0x18,           /* 00011000 */
+    0x30,           /* 00110000 */
+    0x66,           /* 01100110 */
+    0xc6,           /* 11000110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 38 0x26 '&'
+    */
+    0x38,           /* 00111000 */
+    0x6c,           /* 01101100 */
+    0x38,           /* 00111000 */
+    0x76,           /* 01110110 */
+    0xdc,           /* 11011100 */
+    0xcc,           /* 11001100 */
+    0x76,           /* 01110110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 39 0x27 '''
+    */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x30,           /* 00110000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 40 0x28 '('
+    */
+    0x0c,           /* 00001100 */
+    0x18,           /* 00011000 */
+    0x30,           /* 00110000 */
+    0x30,           /* 00110000 */
+    0x30,           /* 00110000 */
+    0x18,           /* 00011000 */
+    0x0c,           /* 00001100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 41 0x29 ')'
+    */
+    0x30,           /* 00110000 */
+    0x18,           /* 00011000 */
+    0x0c,           /* 00001100 */
+    0x0c,           /* 00001100 */
+    0x0c,           /* 00001100 */
+    0x18,           /* 00011000 */
+    0x30,           /* 00110000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 42 0x2a '*'
+    */
+    0x00,           /* 00000000 */
+    0x66,           /* 01100110 */
+    0x3c,           /* 00111100 */
+    0xff,           /* 11111111 */
+    0x3c,           /* 00111100 */
+    0x66,           /* 01100110 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 43 0x2b '+'
+    */
+    0x00,           /* 00000000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x7e,           /* 01111110 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 44 0x2c ','
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x30,           /* 00110000 */
+
+    /*
+    * 45 0x2d '-'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x7e,           /* 01111110 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 46 0x2e '.'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 47 0x2f '/'
+    */
+    0x06,           /* 00000110 */
+    0x0c,           /* 00001100 */
+    0x18,           /* 00011000 */
+    0x30,           /* 00110000 */
+    0x60,           /* 01100000 */
+    0xc0,           /* 11000000 */
+    0x80,           /* 10000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 48 0x30 '0'
+    */
+    0x38,           /* 00111000 */
+    0x6c,           /* 01101100 */
+    0xc6,           /* 11000110 */
+    0xd6,           /* 11010110 */
+    0xc6,           /* 11000110 */
+    0x6c,           /* 01101100 */
+    0x38,           /* 00111000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 49 0x31 '1'
+    */
+    0x18,           /* 00011000 */
+    0x38,           /* 00111000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x7e,           /* 01111110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 50 0x32 '2'
+    */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0x06,           /* 00000110 */
+    0x1c,           /* 00011100 */
+    0x30,           /* 00110000 */
+    0x66,           /* 01100110 */
+    0xfe,           /* 11111110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 51 0x33 '3'
+    */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0x06,           /* 00000110 */
+    0x3c,           /* 00111100 */
+    0x06,           /* 00000110 */
+    0xc6,           /* 11000110 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 52 0x34 '4'
+    */
+    0x1c,           /* 00011100 */
+    0x3c,           /* 00111100 */
+    0x6c,           /* 01101100 */
+    0xcc,           /* 11001100 */
+    0xfe,           /* 11111110 */
+    0x0c,           /* 00001100 */
+    0x1e,           /* 00011110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 53 0x35 '5'
+    */
+    0xfe,           /* 11111110 */
+    0xc0,           /* 11000000 */
+    0xc0,           /* 11000000 */
+    0xfc,           /* 11111100 */
+    0x06,           /* 00000110 */
+    0xc6,           /* 11000110 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 54 0x36 '6'
+    */
+    0x38,           /* 00111000 */
+    0x60,           /* 01100000 */
+    0xc0,           /* 11000000 */
+    0xfc,           /* 11111100 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 55 0x37 '7'
+    */
+    0xfe,           /* 11111110 */
+    0xc6,           /* 11000110 */
+    0x0c,           /* 00001100 */
+    0x18,           /* 00011000 */
+    0x30,           /* 00110000 */
+    0x30,           /* 00110000 */
+    0x30,           /* 00110000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 56 0x38 '8'
+    */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 57 0x39 '9'
+    */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x7e,           /* 01111110 */
+    0x06,           /* 00000110 */
+    0x0c,           /* 00001100 */
+    0x78,           /* 01111000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 58 0x3a ':'
+    */
+    0x00,           /* 00000000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 59 0x3b ';'
+    */
+    0x00,           /* 00000000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x30,           /* 00110000 */
+
+    /*
+    * 60 0x3c '<'
+    */
+    0x06,           /* 00000110 */
+    0x0c,           /* 00001100 */
+    0x18,           /* 00011000 */
+    0x30,           /* 00110000 */
+    0x18,           /* 00011000 */
+    0x0c,           /* 00001100 */
+    0x06,           /* 00000110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 61 0x3d '='
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x7e,           /* 01111110 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x7e,           /* 01111110 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 62 0x3e '>'
+    */
+    0x60,           /* 01100000 */
+    0x30,           /* 00110000 */
+    0x18,           /* 00011000 */
+    0x0c,           /* 00001100 */
+    0x18,           /* 00011000 */
+    0x30,           /* 00110000 */
+    0x60,           /* 01100000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 63 0x3f '?'
+    */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0x0c,           /* 00001100 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 64 0x40 '@'
+    */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xde,           /* 11011110 */
+    0xde,           /* 11011110 */
+    0xde,           /* 11011110 */
+    0xc0,           /* 11000000 */
+    0x78,           /* 01111000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 65 0x41 'A'
+    */
+    0x38,           /* 00111000 */
+    0x6c,           /* 01101100 */
+    0xc6,           /* 11000110 */
+    0xfe,           /* 11111110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 66 0x42 'B'
+    */
+    0xfc,           /* 11111100 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x7c,           /* 01111100 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0xfc,           /* 11111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 67 0x43 'C'
+    */
+    0x3c,           /* 00111100 */
+    0x66,           /* 01100110 */
+    0xc0,           /* 11000000 */
+    0xc0,           /* 11000000 */
+    0xc0,           /* 11000000 */
+    0x66,           /* 01100110 */
+    0x3c,           /* 00111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 68 0x44 'D'
+    */
+    0xf8,           /* 11111000 */
+    0x6c,           /* 01101100 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x6c,           /* 01101100 */
+    0xf8,           /* 11111000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 69 0x45 'E'
+    */
+    0xfe,           /* 11111110 */
+    0x62,           /* 01100010 */
+    0x68,           /* 01101000 */
+    0x78,           /* 01111000 */
+    0x68,           /* 01101000 */
+    0x62,           /* 01100010 */
+    0xfe,           /* 11111110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 70 0x46 'F'
+    */
+    0xfe,           /* 11111110 */
+    0x62,           /* 01100010 */
+    0x68,           /* 01101000 */
+    0x78,           /* 01111000 */
+    0x68,           /* 01101000 */
+    0x60,           /* 01100000 */
+    0xf0,           /* 11110000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 71 0x47 'G'
+    */
+    0x3c,           /* 00111100 */
+    0x66,           /* 01100110 */
+    0xc0,           /* 11000000 */
+    0xc0,           /* 11000000 */
+    0xce,           /* 11001110 */
+    0x66,           /* 01100110 */
+    0x3a,           /* 00111010 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 72 0x48 'H'
+    */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xfe,           /* 11111110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 73 0x49 'I'
+    */
+    0x3c,           /* 00111100 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x3c,           /* 00111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 74 0x4a 'J'
+    */
+    0x1e,           /* 00011110 */
+    0x0c,           /* 00001100 */
+    0x0c,           /* 00001100 */
+    0x0c,           /* 00001100 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0x78,           /* 01111000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 75 0x4b 'K'
+    */
+    0xe6,           /* 11100110 */
+    0x66,           /* 01100110 */
+    0x6c,           /* 01101100 */
+    0x78,           /* 01111000 */
+    0x6c,           /* 01101100 */
+    0x66,           /* 01100110 */
+    0xe6,           /* 11100110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 76 0x4c 'L'
+    */
+    0xf0,           /* 11110000 */
+    0x60,           /* 01100000 */
+    0x60,           /* 01100000 */
+    0x60,           /* 01100000 */
+    0x62,           /* 01100010 */
+    0x66,           /* 01100110 */
+    0xfe,           /* 11111110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 77 0x4d 'M'
+    */
+    0xc6,           /* 11000110 */
+    0xee,           /* 11101110 */
+    0xfe,           /* 11111110 */
+    0xfe,           /* 11111110 */
+    0xd6,           /* 11010110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 78 0x4e 'N'
+    */
+    0xc6,           /* 11000110 */
+    0xe6,           /* 11100110 */
+    0xf6,           /* 11110110 */
+    0xde,           /* 11011110 */
+    0xce,           /* 11001110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 79 0x4f 'O'
+    */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 80 0x50 'P'
+    */
+    0xfc,           /* 11111100 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x7c,           /* 01111100 */
+    0x60,           /* 01100000 */
+    0x60,           /* 01100000 */
+    0xf0,           /* 11110000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 81 0x51 'Q'
+    */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xce,           /* 11001110 */
+    0x7c,           /* 01111100 */
+    0x0e,           /* 00001110 */
+
+    /*
+    * 82 0x52 'R'
+    */
+    0xfc,           /* 11111100 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x7c,           /* 01111100 */
+    0x6c,           /* 01101100 */
+    0x66,           /* 01100110 */
+    0xe6,           /* 11100110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 83 0x53 'S'
+    */
+    0x3c,           /* 00111100 */
+    0x66,           /* 01100110 */
+    0x30,           /* 00110000 */
+    0x18,           /* 00011000 */
+    0x0c,           /* 00001100 */
+    0x66,           /* 01100110 */
+    0x3c,           /* 00111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 84 0x54 'T'
+    */
+    0x7e,           /* 01111110 */
+    0x7e,           /* 01111110 */
+    0x5a,           /* 01011010 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x3c,           /* 00111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 85 0x55 'U'
+    */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 86 0x56 'V'
+    */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x6c,           /* 01101100 */
+    0x38,           /* 00111000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 87 0x57 'W'
+    */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xd6,           /* 11010110 */
+    0xd6,           /* 11010110 */
+    0xfe,           /* 11111110 */
+    0x6c,           /* 01101100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 88 0x58 'X'
+    */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x6c,           /* 01101100 */
+    0x38,           /* 00111000 */
+    0x6c,           /* 01101100 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 89 0x59 'Y'
+    */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x3c,           /* 00111100 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x3c,           /* 00111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 90 0x5a 'Z'
+    */
+    0xfe,           /* 11111110 */
+    0xc6,           /* 11000110 */
+    0x8c,           /* 10001100 */
+    0x18,           /* 00011000 */
+    0x32,           /* 00110010 */
+    0x66,           /* 01100110 */
+    0xfe,           /* 11111110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 91 0x5b '['
+    */
+    0x3c,           /* 00111100 */
+    0x30,           /* 00110000 */
+    0x30,           /* 00110000 */
+    0x30,           /* 00110000 */
+    0x30,           /* 00110000 */
+    0x30,           /* 00110000 */
+    0x3c,           /* 00111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 92 0x5c '\'
+    */
+    0xc0,           /* 11000000 */
+    0x60,           /* 01100000 */
+    0x30,           /* 00110000 */
+    0x18,           /* 00011000 */
+    0x0c,           /* 00001100 */
+    0x06,           /* 00000110 */
+    0x02,           /* 00000010 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 93 0x5d ']'
+    */
+    0x3c,           /* 00111100 */
+    0x0c,           /* 00001100 */
+    0x0c,           /* 00001100 */
+    0x0c,           /* 00001100 */
+    0x0c,           /* 00001100 */
+    0x0c,           /* 00001100 */
+    0x3c,           /* 00111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 94 0x5e '^'
+    */
+    0x10,           /* 00010000 */
+    0x38,           /* 00111000 */
+    0x6c,           /* 01101100 */
+    0xc6,           /* 11000110 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 95 0x5f '_'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xff,           /* 11111111 */
+
+    /*
+    * 96 0x60 '`'
+    */
+    0x30,           /* 00110000 */
+    0x18,           /* 00011000 */
+    0x0c,           /* 00001100 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 97 0x61 'a'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x78,           /* 01111000 */
+    0x0c,           /* 00001100 */
+    0x7c,           /* 01111100 */
+    0xcc,           /* 11001100 */
+    0x76,           /* 01110110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 98 0x62 'b'
+    */
+    0xe0,           /* 11100000 */
+    0x60,           /* 01100000 */
+    0x7c,           /* 01111100 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0xdc,           /* 11011100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 99 0x63 'c'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xc0,           /* 11000000 */
+    0xc6,           /* 11000110 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 100 0x64 'd'
+    */
+    0x1c,           /* 00011100 */
+    0x0c,           /* 00001100 */
+    0x7c,           /* 01111100 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0x76,           /* 01110110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 101 0x65 'e'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xfe,           /* 11111110 */
+    0xc0,           /* 11000000 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 102 0x66 'f'
+    */
+    0x3c,           /* 00111100 */
+    0x66,           /* 01100110 */
+    0x60,           /* 01100000 */
+    0xf8,           /* 11111000 */
+    0x60,           /* 01100000 */
+    0x60,           /* 01100000 */
+    0xf0,           /* 11110000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 103 0x67 'g'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x76,           /* 01110110 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0x7c,           /* 01111100 */
+    0x0c,           /* 00001100 */
+    0xf8,           /* 11111000 */
+
+    /*
+    * 104 0x68 'h'
+    */
+    0xe0,           /* 11100000 */
+    0x60,           /* 01100000 */
+    0x6c,           /* 01101100 */
+    0x76,           /* 01110110 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0xe6,           /* 11100110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 105 0x69 'i'
+    */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+    0x38,           /* 00111000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x3c,           /* 00111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 106 0x6a 'j'
+    */
+    0x06,           /* 00000110 */
+    0x00,           /* 00000000 */
+    0x06,           /* 00000110 */
+    0x06,           /* 00000110 */
+    0x06,           /* 00000110 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x3c,           /* 00111100 */
+
+    /*
+    * 107 0x6b 'k'
+    */
+    0xe0,           /* 11100000 */
+    0x60,           /* 01100000 */
+    0x66,           /* 01100110 */
+    0x6c,           /* 01101100 */
+    0x78,           /* 01111000 */
+    0x6c,           /* 01101100 */
+    0xe6,           /* 11100110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 108 0x6c 'l'
+    */
+    0x38,           /* 00111000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x3c,           /* 00111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 109 0x6d 'm'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xec,           /* 11101100 */
+    0xfe,           /* 11111110 */
+    0xd6,           /* 11010110 */
+    0xd6,           /* 11010110 */
+    0xd6,           /* 11010110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 110 0x6e 'n'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xdc,           /* 11011100 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 111 0x6f 'o'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 112 0x70 'p'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xdc,           /* 11011100 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x7c,           /* 01111100 */
+    0x60,           /* 01100000 */
+    0xf0,           /* 11110000 */
+
+    /*
+    * 113 0x71 'q'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x76,           /* 01110110 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0x7c,           /* 01111100 */
+    0x0c,           /* 00001100 */
+    0x1e,           /* 00011110 */
+
+    /*
+    * 114 0x72 'r'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xdc,           /* 11011100 */
+    0x76,           /* 01110110 */
+    0x60,           /* 01100000 */
+    0x60,           /* 01100000 */
+    0xf0,           /* 11110000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 115 0x73 's'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x7e,           /* 01111110 */
+    0xc0,           /* 11000000 */
+    0x7c,           /* 01111100 */
+    0x06,           /* 00000110 */
+    0xfc,           /* 11111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 116 0x74 't'
+    */
+    0x30,           /* 00110000 */
+    0x30,           /* 00110000 */
+    0xfc,           /* 11111100 */
+    0x30,           /* 00110000 */
+    0x30,           /* 00110000 */
+    0x36,           /* 00110110 */
+    0x1c,           /* 00011100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 117 0x75 'u'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0x76,           /* 01110110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 118 0x76 'v'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x6c,           /* 01101100 */
+    0x38,           /* 00111000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 119 0x77 'w'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xc6,           /* 11000110 */
+    0xd6,           /* 11010110 */
+    0xd6,           /* 11010110 */
+    0xfe,           /* 11111110 */
+    0x6c,           /* 01101100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 120 0x78 'x'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xc6,           /* 11000110 */
+    0x6c,           /* 01101100 */
+    0x38,           /* 00111000 */
+    0x6c,           /* 01101100 */
+    0xc6,           /* 11000110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 121 0x79 'y'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x7e,           /* 01111110 */
+    0x06,           /* 00000110 */
+    0xfc,           /* 11111100 */
+
+    /*
+    * 122 0x7a 'z'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x7e,           /* 01111110 */
+    0x4c,           /* 01001100 */
+    0x18,           /* 00011000 */
+    0x32,           /* 00110010 */
+    0x7e,           /* 01111110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 123 0x7b '{'
+    */
+    0x0e,           /* 00001110 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x70,           /* 01110000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x0e,           /* 00001110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 124 0x7c '|'
+    */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 125 0x7d '}'
+    */
+    0x70,           /* 01110000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x0e,           /* 00001110 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x70,           /* 01110000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 126 0x7e '~'
+    */
+    0x76,           /* 01110110 */
+    0xdc,           /* 11011100 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 127 0x7f ''
+    */
+    0x00,           /* 00000000 */
+    0x10,           /* 00010000 */
+    0x38,           /* 00111000 */
+    0x6c,           /* 01101100 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xfe,           /* 11111110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 128 0x80 '€'
+    */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xc0,           /* 11000000 */
+    0xc0,           /* 11000000 */
+    0xc6,           /* 11000110 */
+    0x7c,           /* 01111100 */
+    0x0c,           /* 00001100 */
+    0x78,           /* 01111000 */
+
+    /*
+    * 129 0x81 '�'
+    */
+    0xcc,           /* 11001100 */
+    0x00,           /* 00000000 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0x76,           /* 01110110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 130 0x82 '‚'
+    */
+    0x0c,           /* 00001100 */
+    0x18,           /* 00011000 */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xfe,           /* 11111110 */
+    0xc0,           /* 11000000 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 131 0x83 'ƒ'
+    */
+    0x7c,           /* 01111100 */
+    0x82,           /* 10000010 */
+    0x78,           /* 01111000 */
+    0x0c,           /* 00001100 */
+    0x7c,           /* 01111100 */
+    0xcc,           /* 11001100 */
+    0x76,           /* 01110110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 132 0x84 '„'
+    */
+    0xc6,           /* 11000110 */
+    0x00,           /* 00000000 */
+    0x78,           /* 01111000 */
+    0x0c,           /* 00001100 */
+    0x7c,           /* 01111100 */
+    0xcc,           /* 11001100 */
+    0x76,           /* 01110110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 133 0x85 '…'
+    */
+    0x30,           /* 00110000 */
+    0x18,           /* 00011000 */
+    0x78,           /* 01111000 */
+    0x0c,           /* 00001100 */
+    0x7c,           /* 01111100 */
+    0xcc,           /* 11001100 */
+    0x76,           /* 01110110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 134 0x86 '†'
+    */
+    0x30,           /* 00110000 */
+    0x30,           /* 00110000 */
+    0x78,           /* 01111000 */
+    0x0c,           /* 00001100 */
+    0x7c,           /* 01111100 */
+    0xcc,           /* 11001100 */
+    0x76,           /* 01110110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 135 0x87 '‡'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x7e,           /* 01111110 */
+    0xc0,           /* 11000000 */
+    0xc0,           /* 11000000 */
+    0x7e,           /* 01111110 */
+    0x0c,           /* 00001100 */
+    0x38,           /* 00111000 */
+
+    /*
+    * 136 0x88 'ˆ'
+    */
+    0x7c,           /* 01111100 */
+    0x82,           /* 10000010 */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xfe,           /* 11111110 */
+    0xc0,           /* 11000000 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 137 0x89 '‰'
+    */
+    0xc6,           /* 11000110 */
+    0x00,           /* 00000000 */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xfe,           /* 11111110 */
+    0xc0,           /* 11000000 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 138 0x8a 'Š'
+    */
+    0x30,           /* 00110000 */
+    0x18,           /* 00011000 */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xfe,           /* 11111110 */
+    0xc0,           /* 11000000 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 139 0x8b '‹'
+    */
+    0x66,           /* 01100110 */
+    0x00,           /* 00000000 */
+    0x38,           /* 00111000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x3c,           /* 00111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 140 0x8c 'Œ'
+    */
+    0x7c,           /* 01111100 */
+    0x82,           /* 10000010 */
+    0x38,           /* 00111000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x3c,           /* 00111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 141 0x8d '�'
+    */
+    0x30,           /* 00110000 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+    0x38,           /* 00111000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x3c,           /* 00111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 142 0x8e 'Ž'
+    */
+    0xc6,           /* 11000110 */
+    0x38,           /* 00111000 */
+    0x6c,           /* 01101100 */
+    0xc6,           /* 11000110 */
+    0xfe,           /* 11111110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 143 0x8f '�'
+    */
+    0x38,           /* 00111000 */
+    0x6c,           /* 01101100 */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xfe,           /* 11111110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 144 0x90 '�'
+    */
+    0x18,           /* 00011000 */
+    0x30,           /* 00110000 */
+    0xfe,           /* 11111110 */
+    0xc0,           /* 11000000 */
+    0xf8,           /* 11111000 */
+    0xc0,           /* 11000000 */
+    0xfe,           /* 11111110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 145 0x91 '‘'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x7e,           /* 01111110 */
+    0x18,           /* 00011000 */
+    0x7e,           /* 01111110 */
+    0xd8,           /* 11011000 */
+    0x7e,           /* 01111110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 146 0x92 '’'
+    */
+    0x3e,           /* 00111110 */
+    0x6c,           /* 01101100 */
+    0xcc,           /* 11001100 */
+    0xfe,           /* 11111110 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0xce,           /* 11001110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 147 0x93 '“'
+    */
+    0x7c,           /* 01111100 */
+    0x82,           /* 10000010 */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 148 0x94 '”'
+    */
+    0xc6,           /* 11000110 */
+    0x00,           /* 00000000 */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 149 0x95 '•'
+    */
+    0x30,           /* 00110000 */
+    0x18,           /* 00011000 */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 150 0x96 '–'
+    */
+    0x78,           /* 01111000 */
+    0x84,           /* 10000100 */
+    0x00,           /* 00000000 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0x76,           /* 01110110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 151 0x97 '—'
+    */
+    0x60,           /* 01100000 */
+    0x30,           /* 00110000 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0x76,           /* 01110110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 152 0x98 '˜'
+    */
+    0xc6,           /* 11000110 */
+    0x00,           /* 00000000 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x7e,           /* 01111110 */
+    0x06,           /* 00000110 */
+    0xfc,           /* 11111100 */
+
+    /*
+    * 153 0x99 '™'
+    */
+    0xc6,           /* 11000110 */
+    0x38,           /* 00111000 */
+    0x6c,           /* 01101100 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x6c,           /* 01101100 */
+    0x38,           /* 00111000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 154 0x9a 'š'
+    */
+    0xc6,           /* 11000110 */
+    0x00,           /* 00000000 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 155 0x9b '›'
+    */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x7e,           /* 01111110 */
+    0xc0,           /* 11000000 */
+    0xc0,           /* 11000000 */
+    0x7e,           /* 01111110 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+
+    /*
+    * 156 0x9c 'œ'
+    */
+    0x38,           /* 00111000 */
+    0x6c,           /* 01101100 */
+    0x64,           /* 01100100 */
+    0xf0,           /* 11110000 */
+    0x60,           /* 01100000 */
+    0x66,           /* 01100110 */
+    0xfc,           /* 11111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 157 0x9d '�'
+    */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x3c,           /* 00111100 */
+    0x7e,           /* 01111110 */
+    0x18,           /* 00011000 */
+    0x7e,           /* 01111110 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+
+    /*
+    * 158 0x9e 'ž'
+    */
+    0xf8,           /* 11111000 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0xfa,           /* 11111010 */
+    0xc6,           /* 11000110 */
+    0xcf,           /* 11001111 */
+    0xc6,           /* 11000110 */
+    0xc7,           /* 11000111 */
+
+    /*
+    * 159 0x9f 'Ÿ'
+    */
+    0x0e,           /* 00001110 */
+    0x1b,           /* 00011011 */
+    0x18,           /* 00011000 */
+    0x3c,           /* 00111100 */
+    0x18,           /* 00011000 */
+    0xd8,           /* 11011000 */
+    0x70,           /* 01110000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 160 0xa0 ' '
+    */
+    0x18,           /* 00011000 */
+    0x30,           /* 00110000 */
+    0x78,           /* 01111000 */
+    0x0c,           /* 00001100 */
+    0x7c,           /* 01111100 */
+    0xcc,           /* 11001100 */
+    0x76,           /* 01110110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 161 0xa1 '¡'
+    */
+    0x0c,           /* 00001100 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+    0x38,           /* 00111000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x3c,           /* 00111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 162 0xa2 '¢'
+    */
+    0x0c,           /* 00001100 */
+    0x18,           /* 00011000 */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 163 0xa3 '£'
+    */
+    0x18,           /* 00011000 */
+    0x30,           /* 00110000 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0x76,           /* 01110110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 164 0xa4 '¤'
+    */
+    0x76,           /* 01110110 */
+    0xdc,           /* 11011100 */
+    0x00,           /* 00000000 */
+    0xdc,           /* 11011100 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 165 0xa5 '¥'
+    */
+    0x76,           /* 01110110 */
+    0xdc,           /* 11011100 */
+    0x00,           /* 00000000 */
+    0xe6,           /* 11100110 */
+    0xf6,           /* 11110110 */
+    0xde,           /* 11011110 */
+    0xce,           /* 11001110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 166 0xa6 '¦'
+    */
+    0x3c,           /* 00111100 */
+    0x6c,           /* 01101100 */
+    0x6c,           /* 01101100 */
+    0x3e,           /* 00111110 */
+    0x00,           /* 00000000 */
+    0x7e,           /* 01111110 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 167 0xa7 '§'
+    */
+    0x38,           /* 00111000 */
+    0x6c,           /* 01101100 */
+    0x6c,           /* 01101100 */
+    0x38,           /* 00111000 */
+    0x00,           /* 00000000 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 168 0xa8 '¨'
+    */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x30,           /* 00110000 */
+    0x63,           /* 01100011 */
+    0x3e,           /* 00111110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 169 0xa9 '©'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xfe,           /* 11111110 */
+    0xc0,           /* 11000000 */
+    0xc0,           /* 11000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 170 0xaa 'ª'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xfe,           /* 11111110 */
+    0x06,           /* 00000110 */
+    0x06,           /* 00000110 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 171 0xab '«'
+    */
+    0x63,           /* 01100011 */
+    0xe6,           /* 11100110 */
+    0x6c,           /* 01101100 */
+    0x7e,           /* 01111110 */
+    0x33,           /* 00110011 */
+    0x66,           /* 01100110 */
+    0xcc,           /* 11001100 */
+    0x0f,           /* 00001111 */
+
+    /*
+    * 172 0xac '¬'
+    */
+    0x63,           /* 01100011 */
+    0xe6,           /* 11100110 */
+    0x6c,           /* 01101100 */
+    0x7a,           /* 01111010 */
+    0x36,           /* 00110110 */
+    0x6a,           /* 01101010 */
+    0xdf,           /* 11011111 */
+    0x06,           /* 00000110 */
+
+    /*
+    * 173 0xad '­'
+    */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x3c,           /* 00111100 */
+    0x3c,           /* 00111100 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 174 0xae '®'
+    */
+    0x00,           /* 00000000 */
+    0x33,           /* 00110011 */
+    0x66,           /* 01100110 */
+    0xcc,           /* 11001100 */
+    0x66,           /* 01100110 */
+    0x33,           /* 00110011 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 175 0xaf '¯'
+    */
+    0x00,           /* 00000000 */
+    0xcc,           /* 11001100 */
+    0x66,           /* 01100110 */
+    0x33,           /* 00110011 */
+    0x66,           /* 01100110 */
+    0xcc,           /* 11001100 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 176 0xb0 '°'
+    */
+    0x22,           /* 00100010 */
+    0x88,           /* 10001000 */
+    0x22,           /* 00100010 */
+    0x88,           /* 10001000 */
+    0x22,           /* 00100010 */
+    0x88,           /* 10001000 */
+    0x22,           /* 00100010 */
+    0x88,           /* 10001000 */
+
+    /*
+    * 177 0xb1 '±'
+    */
+    0x55,           /* 01010101 */
+    0xaa,           /* 10101010 */
+    0x55,           /* 01010101 */
+    0xaa,           /* 10101010 */
+    0x55,           /* 01010101 */
+    0xaa,           /* 10101010 */
+    0x55,           /* 01010101 */
+    0xaa,           /* 10101010 */
+
+    /*
+    * 178 0xb2 '²'
+    */
+    0x77,           /* 01110111 */
+    0xdd,           /* 11011101 */
+    0x77,           /* 01110111 */
+    0xdd,           /* 11011101 */
+    0x77,           /* 01110111 */
+    0xdd,           /* 11011101 */
+    0x77,           /* 01110111 */
+    0xdd,           /* 11011101 */
+
+    /*
+    * 179 0xb3 '³'
+    */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+
+    /*
+    * 180 0xb4 '´'
+    */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0xf8,           /* 11111000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+
+    /*
+    * 181 0xb5 'µ'
+    */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0xf8,           /* 11111000 */
+    0x18,           /* 00011000 */
+    0xf8,           /* 11111000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+
+    /*
+    * 182 0xb6 '¶'
+    */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0xf6,           /* 11110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+
+    /*
+    * 183 0xb7 '·'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xfe,           /* 11111110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+
+    /*
+    * 184 0xb8 '¸'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xf8,           /* 11111000 */
+    0x18,           /* 00011000 */
+    0xf8,           /* 11111000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+
+    /*
+    * 185 0xb9 '¹'
+    */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0xf6,           /* 11110110 */
+    0x06,           /* 00000110 */
+    0xf6,           /* 11110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+
+    /*
+    * 186 0xba 'º'
+    */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+
+    /*
+    * 187 0xbb '»'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xfe,           /* 11111110 */
+    0x06,           /* 00000110 */
+    0xf6,           /* 11110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+
+    /*
+    * 188 0xbc '¼'
+    */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0xf6,           /* 11110110 */
+    0x06,           /* 00000110 */
+    0xfe,           /* 11111110 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 189 0xbd '½'
+    */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0xfe,           /* 11111110 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 190 0xbe '¾'
+    */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0xf8,           /* 11111000 */
+    0x18,           /* 00011000 */
+    0xf8,           /* 11111000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 191 0xbf '¿'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xf8,           /* 11111000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+
+    /*
+    * 192 0xc0 'À'
+    */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x1f,           /* 00011111 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 193 0xc1 'Á'
+    */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0xff,           /* 11111111 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 194 0xc2 'Â'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xff,           /* 11111111 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+
+    /*
+    * 195 0xc3 'Ã'
+    */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x1f,           /* 00011111 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+
+    /*
+    * 196 0xc4 'Ä'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xff,           /* 11111111 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 197 0xc5 'Å'
+    */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0xff,           /* 11111111 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+
+    /*
+    * 198 0xc6 'Æ'
+    */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x1f,           /* 00011111 */
+    0x18,           /* 00011000 */
+    0x1f,           /* 00011111 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+
+    /*
+    * 199 0xc7 'Ç'
+    */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x37,           /* 00110111 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+
+    /*
+    * 200 0xc8 'È'
+    */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x37,           /* 00110111 */
+    0x30,           /* 00110000 */
+    0x3f,           /* 00111111 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 201 0xc9 'É'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x3f,           /* 00111111 */
+    0x30,           /* 00110000 */
+    0x37,           /* 00110111 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+
+    /*
+    * 202 0xca 'Ê'
+    */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0xf7,           /* 11110111 */
+    0x00,           /* 00000000 */
+    0xff,           /* 11111111 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 203 0xcb 'Ë'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xff,           /* 11111111 */
+    0x00,           /* 00000000 */
+    0xf7,           /* 11110111 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+
+    /*
+    * 204 0xcc 'Ì'
+    */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x37,           /* 00110111 */
+    0x30,           /* 00110000 */
+    0x37,           /* 00110111 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+
+    /*
+    * 205 0xcd 'Í'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xff,           /* 11111111 */
+    0x00,           /* 00000000 */
+    0xff,           /* 11111111 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 206 0xce 'Î'
+    */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0xf7,           /* 11110111 */
+    0x00,           /* 00000000 */
+    0xf7,           /* 11110111 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+
+    /*
+    * 207 0xcf 'Ï'
+    */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0xff,           /* 11111111 */
+    0x00,           /* 00000000 */
+    0xff,           /* 11111111 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 208 0xd0 'Ð'
+    */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0xff,           /* 11111111 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 209 0xd1 'Ñ'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xff,           /* 11111111 */
+    0x00,           /* 00000000 */
+    0xff,           /* 11111111 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+
+    /*
+    * 210 0xd2 'Ò'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xff,           /* 11111111 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+
+    /*
+    * 211 0xd3 'Ó'
+    */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x3f,           /* 00111111 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 212 0xd4 'Ô'
+    */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x1f,           /* 00011111 */
+    0x18,           /* 00011000 */
+    0x1f,           /* 00011111 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 213 0xd5 'Õ'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x1f,           /* 00011111 */
+    0x18,           /* 00011000 */
+    0x1f,           /* 00011111 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+
+    /*
+    * 214 0xd6 'Ö'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x3f,           /* 00111111 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+
+    /*
+    * 215 0xd7 '×'
+    */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0xff,           /* 11111111 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+
+    /*
+    * 216 0xd8 'Ø'
+    */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0xff,           /* 11111111 */
+    0x18,           /* 00011000 */
+    0xff,           /* 11111111 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+
+    /*
+    * 217 0xd9 'Ù'
+    */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0xf8,           /* 11111000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 218 0xda 'Ú'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x1f,           /* 00011111 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+
+    /*
+    * 219 0xdb 'Û'
+    */
+    0xff,           /* 11111111 */
+    0xff,           /* 11111111 */
+    0xff,           /* 11111111 */
+    0xff,           /* 11111111 */
+    0xff,           /* 11111111 */
+    0xff,           /* 11111111 */
+    0xff,           /* 11111111 */
+    0xff,           /* 11111111 */
+
+    /*
+    * 220 0xdc 'Ü'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xff,           /* 11111111 */
+    0xff,           /* 11111111 */
+    0xff,           /* 11111111 */
+    0xff,           /* 11111111 */
+
+    /*
+    * 221 0xdd 'Ý'
+    */
+    0xf0,           /* 11110000 */
+    0xf0,           /* 11110000 */
+    0xf0,           /* 11110000 */
+    0xf0,           /* 11110000 */
+    0xf0,           /* 11110000 */
+    0xf0,           /* 11110000 */
+    0xf0,           /* 11110000 */
+    0xf0,           /* 11110000 */
+
+    /*
+    * 222 0xde 'Þ'
+    */
+    0x0f,           /* 00001111 */
+    0x0f,           /* 00001111 */
+    0x0f,           /* 00001111 */
+    0x0f,           /* 00001111 */
+    0x0f,           /* 00001111 */
+    0x0f,           /* 00001111 */
+    0x0f,           /* 00001111 */
+    0x0f,           /* 00001111 */
+
+    /*
+    * 223 0xdf 'ß'
+    */
+    0xff,           /* 11111111 */
+    0xff,           /* 11111111 */
+    0xff,           /* 11111111 */
+    0xff,           /* 11111111 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 224 0xe0 'à'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x76,           /* 01110110 */
+    0xdc,           /* 11011100 */
+    0xc8,           /* 11001000 */
+    0xdc,           /* 11011100 */
+    0x76,           /* 01110110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 225 0xe1 'á'
+    */
+    0x78,           /* 01111000 */
+    0xcc,           /* 11001100 */
+    0xcc,           /* 11001100 */
+    0xd8,           /* 11011000 */
+    0xcc,           /* 11001100 */
+    0xc6,           /* 11000110 */
+    0xcc,           /* 11001100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 226 0xe2 'â'
+    */
+    0xfe,           /* 11111110 */
+    0xc6,           /* 11000110 */
+    0xc0,           /* 11000000 */
+    0xc0,           /* 11000000 */
+    0xc0,           /* 11000000 */
+    0xc0,           /* 11000000 */
+    0xc0,           /* 11000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 227 0xe3 'ã'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0xfe,           /* 11111110 */
+    0x6c,           /* 01101100 */
+    0x6c,           /* 01101100 */
+    0x6c,           /* 01101100 */
+    0x6c,           /* 01101100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 228 0xe4 'ä'
+    */
+    0xfe,           /* 11111110 */
+    0xc6,           /* 11000110 */
+    0x60,           /* 01100000 */
+    0x30,           /* 00110000 */
+    0x60,           /* 01100000 */
+    0xc6,           /* 11000110 */
+    0xfe,           /* 11111110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 229 0xe5 'å'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x7e,           /* 01111110 */
+    0xd8,           /* 11011000 */
+    0xd8,           /* 11011000 */
+    0xd8,           /* 11011000 */
+    0x70,           /* 01110000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 230 0xe6 'æ'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x7c,           /* 01111100 */
+    0xc0,           /* 11000000 */
+
+    /*
+    * 231 0xe7 'ç'
+    */
+    0x00,           /* 00000000 */
+    0x76,           /* 01110110 */
+    0xdc,           /* 11011100 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 232 0xe8 'è'
+    */
+    0x7e,           /* 01111110 */
+    0x18,           /* 00011000 */
+    0x3c,           /* 00111100 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x3c,           /* 00111100 */
+    0x18,           /* 00011000 */
+    0x7e,           /* 01111110 */
+
+    /*
+    * 233 0xe9 'é'
+    */
+    0x38,           /* 00111000 */
+    0x6c,           /* 01101100 */
+    0xc6,           /* 11000110 */
+    0xfe,           /* 11111110 */
+    0xc6,           /* 11000110 */
+    0x6c,           /* 01101100 */
+    0x38,           /* 00111000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 234 0xea 'ê'
+    */
+    0x38,           /* 00111000 */
+    0x6c,           /* 01101100 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x6c,           /* 01101100 */
+    0x6c,           /* 01101100 */
+    0xee,           /* 11101110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 235 0xeb 'ë'
+    */
+    0x0e,           /* 00001110 */
+    0x18,           /* 00011000 */
+    0x0c,           /* 00001100 */
+    0x3e,           /* 00111110 */
+    0x66,           /* 01100110 */
+    0x66,           /* 01100110 */
+    0x3c,           /* 00111100 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 236 0xec 'ì'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x7e,           /* 01111110 */
+    0xdb,           /* 11011011 */
+    0xdb,           /* 11011011 */
+    0x7e,           /* 01111110 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 237 0xed 'í'
+    */
+    0x06,           /* 00000110 */
+    0x0c,           /* 00001100 */
+    0x7e,           /* 01111110 */
+    0xdb,           /* 11011011 */
+    0xdb,           /* 11011011 */
+    0x7e,           /* 01111110 */
+    0x60,           /* 01100000 */
+    0xc0,           /* 11000000 */
+
+    /*
+    * 238 0xee 'î'
+    */
+    0x1e,           /* 00011110 */
+    0x30,           /* 00110000 */
+    0x60,           /* 01100000 */
+    0x7e,           /* 01111110 */
+    0x60,           /* 01100000 */
+    0x30,           /* 00110000 */
+    0x1e,           /* 00011110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 239 0xef 'ï'
+    */
+    0x00,           /* 00000000 */
+    0x7c,           /* 01111100 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0xc6,           /* 11000110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 240 0xf0 'ð'
+    */
+    0x00,           /* 00000000 */
+    0xfe,           /* 11111110 */
+    0x00,           /* 00000000 */
+    0xfe,           /* 11111110 */
+    0x00,           /* 00000000 */
+    0xfe,           /* 11111110 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 241 0xf1 'ñ'
+    */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x7e,           /* 01111110 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+    0x7e,           /* 01111110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 242 0xf2 'ò'
+    */
+    0x30,           /* 00110000 */
+    0x18,           /* 00011000 */
+    0x0c,           /* 00001100 */
+    0x18,           /* 00011000 */
+    0x30,           /* 00110000 */
+    0x00,           /* 00000000 */
+    0x7e,           /* 01111110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 243 0xf3 'ó'
+    */
+    0x0c,           /* 00001100 */
+    0x18,           /* 00011000 */
+    0x30,           /* 00110000 */
+    0x18,           /* 00011000 */
+    0x0c,           /* 00001100 */
+    0x00,           /* 00000000 */
+    0x7e,           /* 01111110 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 244 0xf4 'ô'
+    */
+    0x0e,           /* 00001110 */
+    0x1b,           /* 00011011 */
+    0x1b,           /* 00011011 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+
+    /*
+    * 245 0xf5 'õ'
+    */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0xd8,           /* 11011000 */
+    0xd8,           /* 11011000 */
+    0x70,           /* 01110000 */
+
+    /*
+    * 246 0xf6 'ö'
+    */
+    0x00,           /* 00000000 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+    0x7e,           /* 01111110 */
+    0x00,           /* 00000000 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 247 0xf7 '÷'
+    */
+    0x00,           /* 00000000 */
+    0x76,           /* 01110110 */
+    0xdc,           /* 11011100 */
+    0x00,           /* 00000000 */
+    0x76,           /* 01110110 */
+    0xdc,           /* 11011100 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 248 0xf8 'ø'
+    */
+    0x38,           /* 00111000 */
+    0x6c,           /* 01101100 */
+    0x6c,           /* 01101100 */
+    0x38,           /* 00111000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 249 0xf9 'ù'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x18,           /* 00011000 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 250 0xfa 'ú'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x18,           /* 00011000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 251 0xfb 'û'
+    */
+    0x0f,           /* 00001111 */
+    0x0c,           /* 00001100 */
+    0x0c,           /* 00001100 */
+    0x0c,           /* 00001100 */
+    0xec,           /* 11101100 */
+    0x6c,           /* 01101100 */
+    0x3c,           /* 00111100 */
+    0x1c,           /* 00011100 */
+
+    /*
+    * 252 0xfc 'ü'
+    */
+    0x6c,           /* 01101100 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x36,           /* 00110110 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 253 0xfd 'ý'
+    */
+    0x78,           /* 01111000 */
+    0x0c,           /* 00001100 */
+    0x18,           /* 00011000 */
+    0x30,           /* 00110000 */
+    0x7c,           /* 01111100 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 254 0xfe 'þ'
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x3c,           /* 00111100 */
+    0x3c,           /* 00111100 */
+    0x3c,           /* 00111100 */
+    0x3c,           /* 00111100 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+    /*
+    * 255 0xff ' '
+    */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+    0x00,           /* 00000000 */
+
+};
+
+
+/* ---- Character */
+
+/*!
+\brief Global cache for 8x8 pixel font textures created at runtime.
+*/
+static SDL_Texture *SDLTest_CharTextureCache[256];
+
+int SDLTest_DrawCharacter(SDL_Renderer *renderer, int x, int y, char c)
+{
+    const Uint32 charWidth = 8;
+    const Uint32 charHeight = 8;
+    const Uint32 charSize = 8;
+    SDL_Rect srect;
+    SDL_Rect drect;
+    int result;
+    Uint32 ix, iy;
+    const unsigned char *charpos;
+    Uint8 *curpos;
+    Uint8 patt, mask;
+    Uint8 *linepos;
+    Uint32 pitch;
+    SDL_Surface *character;
+    Uint32 ci;
+    Uint8 r, g, b, a;
+
+    /*
+    * Setup source rectangle
+    */
+    srect.x = 0;
+    srect.y = 0;
+    srect.w = charWidth;
+    srect.h = charHeight;
+
+    /*
+    * Setup destination rectangle
+    */
+    drect.x = x;
+    drect.y = y;
+    drect.w = charWidth;
+    drect.h = charHeight;
+
+    /* Character index in cache */
+    ci = (unsigned char)c;
+
+    /*
+    * Create new charWidth x charHeight bitmap surface if not already present.
+    */
+    if (SDLTest_CharTextureCache[ci] == NULL) {
+        /*
+        * Redraw character into surface
+        */
+        character = SDL_CreateRGBSurface(SDL_SWSURFACE,
+            charWidth, charHeight, 32,
+            0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
+        if (character == NULL) {
+            return (-1);
+        }
+
+        charpos = SDLTest_FontData + ci * charSize;
+        linepos = (Uint8 *)character->pixels;
+        pitch = character->pitch;
+
+        /*
+        * Drawing loop
+        */
+        patt = 0;
+        for (iy = 0; iy < charWidth; iy++) {
+            mask = 0x00;
+            curpos = linepos;
+            for (ix = 0; ix < charWidth; ix++) {
+                if (!(mask >>= 1)) {
+                    patt = *charpos++;
+                    mask = 0x80;
+                }
+                if (patt & mask) {
+                    *(Uint32 *)curpos = 0xffffffff;
+                } else {
+                    *(Uint32 *)curpos = 0;
+                }
+                curpos += 4;
+            }
+            linepos += pitch;
+        }
+
+        /* Convert temp surface into texture */
+        SDLTest_CharTextureCache[ci] = SDL_CreateTextureFromSurface(renderer, character);
+        SDL_FreeSurface(character);
+
+        /*
+        * Check pointer
+        */
+        if (SDLTest_CharTextureCache[ci] == NULL) {
+            return (-1);
+        }
+    }
+
+    /*
+    * Set color
+    */
+    result = 0;
+    result |= SDL_GetRenderDrawColor(renderer, &r, &g, &b, &a);
+    result |= SDL_SetTextureColorMod(SDLTest_CharTextureCache[ci], r, g, b);
+    result |= SDL_SetTextureAlphaMod(SDLTest_CharTextureCache[ci], a);
+
+    /*
+    * Draw texture onto destination
+    */
+    result |= SDL_RenderCopy(renderer, SDLTest_CharTextureCache[ci], &srect, &drect);
+
+    return (result);
+}
+
+int SDLTest_DrawString(SDL_Renderer * renderer, int x, int y, const char *s)
+{
+    const Uint32 charWidth = 8;
+    int result = 0;
+    int curx = x;
+    int cury = y;
+    const char *curchar = s;
+
+    while (*curchar && !result) {
+        result |= SDLTest_DrawCharacter(renderer, curx, cury, *curchar);
+        curx += charWidth;
+        curchar++;
+    }
+
+    return (result);
+}
+

+ 524 - 0
Source/ThirdParty/SDL/src/test/SDL_test_fuzzer.c

@@ -0,0 +1,524 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2013 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.
+*/
+
+/*
+
+  Data generators for fuzzing test data in a reproducible way.
+
+*/
+
+#include "SDL_config.h"
+
+/* Visual Studio 2008 doesn't have stdint.h */
+#if defined(_MSC_VER) && _MSC_VER <= 1500
+#define UINT8_MAX   ~(Uint8)0
+#define UINT16_MAX  ~(Uint16)0
+#define UINT32_MAX  ~(Uint32)0
+#define UINT64_MAX  ~(Uint64)0
+#else
+#include <stdint.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <float.h>
+
+#include "SDL_test.h"
+
+/**
+ * Counter for fuzzer invocations
+ */
+static int fuzzerInvocationCounter = 0;
+
+/**
+ * Context for shared random number generator
+ */
+static SDLTest_RandomContext rndContext;
+
+/*
+ * Note: doxygen documentation markup for functions is in the header file.
+ */
+
+void
+SDLTest_FuzzerInit(Uint64 execKey)
+{
+    Uint32 a = (execKey >> 32) & 0x00000000FFFFFFFF;
+    Uint32 b = execKey & 0x00000000FFFFFFFF;
+    SDL_memset((void *)&rndContext, 0, sizeof(SDLTest_RandomContext));
+    SDLTest_RandomInit(&rndContext, a, b);
+    fuzzerInvocationCounter = 0;
+}
+
+int
+SDLTest_GetFuzzerInvocationCount()
+{
+    return fuzzerInvocationCounter;
+}
+
+Uint8
+SDLTest_RandomUint8()
+{
+    fuzzerInvocationCounter++;
+
+    return (Uint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
+}
+
+Sint8
+SDLTest_RandomSint8()
+{
+    fuzzerInvocationCounter++;
+
+    return (Sint8) SDLTest_RandomInt(&rndContext) & 0x000000FF;
+}
+
+Uint16
+SDLTest_RandomUint16()
+{
+    fuzzerInvocationCounter++;
+
+    return (Uint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
+}
+
+Sint16
+SDLTest_RandomSint16()
+{
+    fuzzerInvocationCounter++;
+
+    return (Sint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF;
+}
+
+Sint32
+SDLTest_RandomSint32()
+{
+    fuzzerInvocationCounter++;
+
+    return (Sint32) SDLTest_RandomInt(&rndContext);
+}
+
+Uint32
+SDLTest_RandomUint32()
+{
+    fuzzerInvocationCounter++;
+
+    return (Uint32) SDLTest_RandomInt(&rndContext);
+}
+
+Uint64
+SDLTest_RandomUint64()
+{
+    Uint64 value = 0;
+    Uint32 *vp = (void *)&value;
+
+    fuzzerInvocationCounter++;
+
+    vp[0] = SDLTest_RandomSint32();
+    vp[1] = SDLTest_RandomSint32();
+
+    return value;
+}
+
+Sint64
+SDLTest_RandomSint64()
+{
+    Uint64 value = 0;
+    Uint32 *vp = (void *)&value;
+
+    fuzzerInvocationCounter++;
+
+    vp[0] = SDLTest_RandomSint32();
+    vp[1] = SDLTest_RandomSint32();
+
+    return value;
+}
+
+
+
+Sint32
+SDLTest_RandomIntegerInRange(Sint32 pMin, Sint32 pMax)
+{
+    Sint64 min = pMin;
+    Sint64 max = pMax;
+    Sint64 temp;
+    Sint64 number;
+
+    if(pMin > pMax) {
+        temp = min;
+        min = max;
+        max = temp;
+    } else if(pMin == pMax) {
+        return (Sint32)min;
+    }
+
+    number = SDLTest_RandomUint32();
+    /* invocation count increment in preceeding call */
+
+    return (Sint32)((number % ((max + 1) - min)) + min);
+}
+
+/*!
+ * Generates a unsigned boundary value between the given boundaries.
+ * Boundary values are inclusive. See the examples below.
+ * If boundary2 < boundary1, the values are swapped.
+ * If boundary1 == boundary2, value of boundary1 will be returned
+ *
+ * Generating boundary values for Uint8:
+ * BoundaryValues(UINT8_MAX, 10, 20, True) -> [10,11,19,20]
+ * BoundaryValues(UINT8_MAX, 10, 20, False) -> [9,21]
+ * BoundaryValues(UINT8_MAX, 0, 15, True) -> [0, 1, 14, 15]
+ * BoundaryValues(UINT8_MAX, 0, 15, False) -> [16]
+ * BoundaryValues(UINT8_MAX, 0, 0xFF, False) -> [0], error set
+ *
+ * Generator works the same for other types of unsigned integers.
+ *
+ * \param maxValue The biggest value that is acceptable for this data type.
+ *                  For instance, for Uint8 -> 255, Uint16 -> 65536 etc.
+ * \param boundary1 defines lower boundary
+ * \param boundary2 defines upper boundary
+ * \param validDomain Generate only for valid domain (for the data type)
+ *
+ * \returns Returns a random boundary value for the domain or 0 in case of error
+ */
+Uint64
+SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue, Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
+{
+        Uint64 b1, b2;
+    Uint64 delta;
+    Uint64 tempBuf[4];
+    Uint8 index;
+
+        /* Maybe swap */
+    if (boundary1 > boundary2) {
+        b1 = boundary2;
+        b2 = boundary1;
+    } else {
+        b1 = boundary1;
+        b2 = boundary2;
+        }
+
+    index = 0;
+    if (validDomain == SDL_TRUE) {
+            if (b1 == b2) {
+                return b1;
+            }
+
+            /* Generate up to 4 values within bounds */
+            delta = b2 - b1;
+            if (delta < 4) {
+                do {
+                tempBuf[index] = b1 + index;
+                index++;
+                    } while (index < delta);
+            } else {
+          tempBuf[index] = b1;
+          index++;
+          tempBuf[index] = b1 + 1;
+          index++;
+          tempBuf[index] = b2 - 1;
+          index++;
+          tempBuf[index] = b2;
+          index++;
+            }
+        } else {
+            /* Generate up to 2 values outside of bounds */
+        if (b1 > 0) {
+            tempBuf[index] = b1 - 1;
+            index++;
+        }
+
+        if (b2 < maxValue) {
+            tempBuf[index] = b2 + 1;
+            index++;
+        }
+    }
+
+    if (index == 0) {
+        /* There are no valid boundaries */
+        SDL_Unsupported();
+        return 0;
+    }
+
+    return tempBuf[SDLTest_RandomUint8() % index];
+}
+
+
+Uint8
+SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain)
+{
+    /* max value for Uint8 */
+    const Uint64 maxValue = UCHAR_MAX;
+    return (Uint8)SDLTest_GenerateUnsignedBoundaryValues(maxValue,
+                (Uint64) boundary1, (Uint64) boundary2,
+                validDomain);
+}
+
+Uint16
+SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain)
+{
+    /* max value for Uint16 */
+    const Uint64 maxValue = USHRT_MAX;
+    return (Uint16)SDLTest_GenerateUnsignedBoundaryValues(maxValue,
+                (Uint64) boundary1, (Uint64) boundary2,
+                validDomain);
+}
+
+Uint32
+SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain)
+{
+    /* max value for Uint32 */
+    #if ((ULONG_MAX) == (UINT_MAX))
+      const Uint64 maxValue = ULONG_MAX;
+        #else
+      const Uint64 maxValue = UINT_MAX;
+        #endif
+    return (Uint32)SDLTest_GenerateUnsignedBoundaryValues(maxValue,
+                (Uint64) boundary1, (Uint64) boundary2,
+                validDomain);
+}
+
+Uint64
+SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain)
+{
+    /* max value for Uint64 */
+    const Uint64 maxValue = ULLONG_MAX;
+    return SDLTest_GenerateUnsignedBoundaryValues(maxValue,
+                (Uint64) boundary1, (Uint64) boundary2,
+                validDomain);
+}
+
+/*!
+ * Generates a signed boundary value between the given boundaries.
+ * Boundary values are inclusive. See the examples below.
+ * If boundary2 < boundary1, the values are swapped.
+ * If boundary1 == boundary2, value of boundary1 will be returned
+ *
+ * Generating boundary values for Sint8:
+ * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -10, 20, True) -> [-10,-9,19,20]
+ * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -10, 20, False) -> [-11,21]
+ * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -30, -15, True) -> [-30, -29, -16, -15]
+ * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -127, 15, False) -> [16]
+ * SignedBoundaryValues(SCHAR_MIN, SCHAR_MAX, -127, 127, False) -> [0], error set
+ *
+ * Generator works the same for other types of signed integers.
+ *
+ * \param minValue The smallest value that is acceptable for this data type.
+ *                  For instance, for Uint8 -> -127, etc.
+ * \param maxValue The biggest value that is acceptable for this data type.
+ *                  For instance, for Uint8 -> 127, etc.
+ * \param boundary1 defines lower boundary
+ * \param boundary2 defines upper boundary
+ * \param validDomain Generate only for valid domain (for the data type)
+ *
+ * \returns Returns a random boundary value for the domain or 0 in case of error
+ */
+Sint64
+SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const Sint64 maxValue, Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
+{
+        Sint64 b1, b2;
+    Sint64 delta;
+    Sint64 tempBuf[4];
+    Uint8 index;
+
+        /* Maybe swap */
+    if (boundary1 > boundary2) {
+        b1 = boundary2;
+        b2 = boundary1;
+    } else {
+        b1 = boundary1;
+        b2 = boundary2;
+        }
+
+    index = 0;
+    if (validDomain == SDL_TRUE) {
+            if (b1 == b2) {
+                return b1;
+            }
+
+            /* Generate up to 4 values within bounds */
+            delta = b2 - b1;
+            if (delta < 4) {
+                do {
+                tempBuf[index] = b1 + index;
+                index++;
+                    } while (index < delta);
+            } else {
+          tempBuf[index] = b1;
+          index++;
+          tempBuf[index] = b1 + 1;
+          index++;
+          tempBuf[index] = b2 - 1;
+          index++;
+          tempBuf[index] = b2;
+          index++;
+            }
+        } else {
+            /* Generate up to 2 values outside of bounds */
+        if (b1 > minValue) {
+            tempBuf[index] = b1 - 1;
+            index++;
+        }
+
+        if (b2 < maxValue) {
+            tempBuf[index] = b2 + 1;
+            index++;
+        }
+    }
+
+    if (index == 0) {
+        /* There are no valid boundaries */
+        SDL_Unsupported();
+        return minValue;
+    }
+
+    return tempBuf[SDLTest_RandomUint8() % index];
+}
+
+
+Sint8
+SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain)
+{
+    /* min & max values for Sint8 */
+    const Sint64 maxValue = SCHAR_MAX;
+    const Sint64 minValue = SCHAR_MIN;
+    return (Sint8)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
+                (Sint64) boundary1, (Sint64) boundary2,
+                validDomain);
+}
+
+Sint16
+SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain)
+{
+    /* min & max values for Sint16 */
+    const Sint64 maxValue = SHRT_MAX;
+    const Sint64 minValue = SHRT_MIN;
+    return (Sint16)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
+                (Sint64) boundary1, (Sint64) boundary2,
+                validDomain);
+}
+
+Sint32
+SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain)
+{
+    /* min & max values for Sint32 */
+    #if ((ULONG_MAX) == (UINT_MAX))
+      const Sint64 maxValue = LONG_MAX;
+      const Sint64 minValue = LONG_MIN;
+        #else
+      const Sint64 maxValue = INT_MAX;
+      const Sint64 minValue = INT_MIN;
+        #endif
+    return (Sint32)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
+                (Sint64) boundary1, (Sint64) boundary2,
+                validDomain);
+}
+
+Sint64
+SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain)
+{
+    /* min & max values for Sint64 */
+    const Sint64 maxValue = LLONG_MAX;
+    const Sint64 minValue = LLONG_MIN;
+    return SDLTest_GenerateSignedBoundaryValues(minValue, maxValue,
+                boundary1, boundary2,
+                validDomain);
+}
+
+float
+SDLTest_RandomUnitFloat()
+{
+    return (float) SDLTest_RandomUint32() / UINT_MAX;
+}
+
+float
+SDLTest_RandomFloat()
+{
+        return (float) (SDLTest_RandomUnitDouble() * (double)2.0 * (double)FLT_MAX - (double)(FLT_MAX));
+}
+
+double
+SDLTest_RandomUnitDouble()
+{
+    return (double) (SDLTest_RandomUint64() >> 11) * (1.0/9007199254740992.0);
+}
+
+double
+SDLTest_RandomDouble()
+{
+    double r = 0.0;
+    double s = 1.0;
+    do {
+      s /= UINT_MAX + 1.0;
+      r += (double)SDLTest_RandomInt(&rndContext) * s;
+    } while (s > DBL_EPSILON);
+
+    fuzzerInvocationCounter++;
+
+    return r;
+}
+
+
+char *
+SDLTest_RandomAsciiString()
+{
+    return SDLTest_RandomAsciiStringWithMaximumLength(255);
+}
+
+char *
+SDLTest_RandomAsciiStringWithMaximumLength(int maxLength)
+{
+    int size;
+
+    if(maxLength < 1) {
+                SDL_InvalidParamError("maxLength");
+        return NULL;
+    }
+
+    size = (SDLTest_RandomUint32() % (maxLength + 1));
+
+    return SDLTest_RandomAsciiStringOfSize(size);
+}
+
+char *
+SDLTest_RandomAsciiStringOfSize(int size)
+{
+    char *string;
+    int counter;
+
+
+    if(size < 1) {
+                SDL_InvalidParamError("size");
+        return NULL;
+    }
+
+    string = (char *)SDL_malloc((size + 1) * sizeof(char));
+    if (string==NULL) {
+      return NULL;
+        }
+
+    for(counter = 0; counter < size; ++counter) {
+        string[counter] = (char)SDLTest_RandomIntegerInRange(32, 126);
+    }
+
+    string[counter] = '\0';
+
+    fuzzerInvocationCounter++;
+
+    return string;
+}

+ 635 - 0
Source/ThirdParty/SDL/src/test/SDL_test_harness.c

@@ -0,0 +1,635 @@
+/*
+Simple DirectMedia Layer
+Copyright (C) 1997-2013 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.
+*/
+
+#include "SDL_config.h"
+
+#include "SDL_test.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+/* Invalid test name/description message format */
+const char *SDLTest_InvalidNameFormat = "(Invalid)";
+
+/* Log summary message format */
+const char *SDLTest_LogSummaryFormat = "%s Summary: Total=%d Passed=%d Failed=%d Skipped=%d";
+
+/* Final result message format */
+const char *SDLTest_FinalResultFormat = ">>> %s '%s': %s\n";
+
+/*! \brief Timeout for single test case execution */
+static Uint32 SDLTest_TestCaseTimeout = 3600;
+
+/**
+* Generates a random run seed string for the harness. The generated seed
+* will contain alphanumeric characters (0-9A-Z).
+*
+* Note: The returned string needs to be deallocated by the caller.
+*
+* \param length The length of the seed string to generate
+*
+* \returns The generated seed string
+*/
+char *
+SDLTest_GenerateRunSeed(const int length)
+{
+    char *seed = NULL;
+    SDLTest_RandomContext randomContext;
+    int counter;
+
+    /* Sanity check input */
+    if (length <= 0) {
+        SDLTest_LogError("The length of the harness seed must be >0.");
+        return NULL;
+    }
+
+    /* Allocate output buffer */
+    seed = (char *)SDL_malloc((length + 1) * sizeof(char));
+    if (seed == NULL) {
+        SDLTest_LogError("SDL_malloc for run seed output buffer failed.");
+        return NULL;
+    }
+
+    /* Generate a random string of alphanumeric characters */
+    SDLTest_RandomInitTime(&randomContext);
+    for (counter = 0; counter < length - 1; ++counter) {
+        unsigned int number = SDLTest_Random(&randomContext);
+        char ch = (char) (number % (91 - 48)) + 48;
+        if (ch >= 58 && ch <= 64) {
+            ch = 65;
+        }
+        seed[counter] = ch;
+    }
+    seed[counter] = '\0';
+
+    return seed;
+}
+
+/**
+* Generates an execution key for the fuzzer.
+*
+* \param runSeed        The run seed to use
+* \param suiteName      The name of the test suite
+* \param testName       The name of the test
+* \param iteration      The iteration count
+*
+* \returns The generated execution key to initialize the fuzzer with.
+*
+*/
+Uint64
+SDLTest_GenerateExecKey(char *runSeed, char *suiteName, char *testName, int iteration)
+{
+    SDLTest_Md5Context md5Context;
+    Uint64 *keys;
+    char iterationString[16];
+    Uint32 runSeedLength;
+    Uint32 suiteNameLength;
+    Uint32 testNameLength;
+    Uint32 iterationStringLength;
+    Uint32 entireStringLength;
+    char *buffer;
+
+    if (runSeed == NULL || SDL_strlen(runSeed)==0) {
+        SDLTest_LogError("Invalid runSeed string.");
+        return -1;
+    }
+
+    if (suiteName == NULL || SDL_strlen(suiteName)==0) {
+        SDLTest_LogError("Invalid suiteName string.");
+        return -1;
+    }
+
+    if (testName == NULL || SDL_strlen(testName)==0) {
+        SDLTest_LogError("Invalid testName string.");
+        return -1;
+    }
+
+    if (iteration <= 0) {
+        SDLTest_LogError("Invalid iteration count.");
+        return -1;
+    }
+
+    /* Convert iteration number into a string */
+    SDL_memset(iterationString, 0, sizeof(iterationString));
+    SDL_snprintf(iterationString, sizeof(iterationString) - 1, "%d", iteration);
+
+    /* Combine the parameters into single string */
+    runSeedLength = SDL_strlen(runSeed);
+    suiteNameLength = SDL_strlen(suiteName);
+    testNameLength = SDL_strlen(testName);
+    iterationStringLength = SDL_strlen(iterationString);
+    entireStringLength  = runSeedLength + suiteNameLength + testNameLength + iterationStringLength + 1;
+    buffer = (char *)SDL_malloc(entireStringLength);
+    if (buffer == NULL) {
+        SDLTest_LogError("SDL_malloc failed to allocate buffer for execKey generation.");
+        return 0;
+    }
+    SDL_snprintf(buffer, entireStringLength, "%s%s%s%d", runSeed, suiteName, testName, iteration);
+
+    /* Hash string and use half of the digest as 64bit exec key */
+    SDLTest_Md5Init(&md5Context);
+    SDLTest_Md5Update(&md5Context, (unsigned char *)buffer, entireStringLength);
+    SDLTest_Md5Final(&md5Context);
+    SDL_free(buffer);
+    keys = (Uint64 *)md5Context.digest;
+
+    return keys[0];
+}
+
+/**
+* \brief Set timeout handler for test.
+*
+* Note: SDL_Init(SDL_INIT_TIMER) will be called if it wasn't done so before.
+*
+* \param timeout Timeout interval in seconds.
+* \param callback Function that will be called after timeout has elapsed.
+*
+* \return Timer id or -1 on failure.
+*/
+SDL_TimerID
+SDLTest_SetTestTimeout(int timeout, void (*callback)())
+{
+    Uint32 timeoutInMilliseconds;
+    SDL_TimerID timerID;
+
+    if (callback == NULL) {
+        SDLTest_LogError("Timeout callback can't be NULL");
+        return -1;
+    }
+
+    if (timeout < 0) {
+        SDLTest_LogError("Timeout value must be bigger than zero.");
+        return -1;
+    }
+
+    /* Init SDL timer if not initialized before */
+    if (SDL_WasInit(SDL_INIT_TIMER) == 0) {
+        if (SDL_InitSubSystem(SDL_INIT_TIMER)) {
+            SDLTest_LogError("Failed to init timer subsystem: %s", SDL_GetError());
+            return -1;
+        }
+    }
+
+    /* Set timer */
+    timeoutInMilliseconds = timeout * 1000;
+    timerID = SDL_AddTimer(timeoutInMilliseconds, (SDL_TimerCallback)callback, 0x0);
+    if (timerID == 0) {
+        SDLTest_LogError("Creation of SDL timer failed: %s", SDL_GetError());
+        return -1;
+    }
+
+    return timerID;
+}
+
+/**
+* \brief Timeout handler. Aborts test run and exits harness process.
+*/
+void
+    SDLTest_BailOut()
+{
+    SDLTest_LogError("TestCaseTimeout timer expired. Aborting test run.");
+    exit(TEST_ABORTED); /* bail out from the test */
+}
+
+/**
+* \brief Execute a test using the given execution key.
+*
+* \param testSuite Suite containing the test case.
+* \param testCase Case to execute.
+* \param execKey Execution key for the fuzzer.
+*
+* \returns Test case result.
+*/
+int
+SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, SDLTest_TestCaseReference *testCase, Uint64 execKey)
+{
+    SDL_TimerID timer = 0;
+    int testCaseResult = 0;
+    int testResult = 0;
+    int fuzzerCount;
+
+    if (testSuite==NULL || testCase==NULL || testSuite->name==NULL || testCase->name==NULL)
+    {
+        SDLTest_LogError("Setup failure: testSuite or testCase references NULL");
+        return TEST_RESULT_SETUP_FAILURE;
+    }
+
+    if (!testCase->enabled)
+    {
+        SDLTest_Log((char *)SDLTest_FinalResultFormat, "Test", testCase->name, "Skipped (Disabled)");
+        return TEST_RESULT_SKIPPED;
+    }
+
+
+    /* Initialize fuzzer */
+    SDLTest_FuzzerInit(execKey);
+
+    /* Reset assert tracker */
+    SDLTest_ResetAssertSummary();
+
+    /* Set timeout timer */
+    timer = SDLTest_SetTestTimeout(SDLTest_TestCaseTimeout, SDLTest_BailOut);
+
+    /* Maybe run suite initalizer function */
+    if (testSuite->testSetUp) {
+        testSuite->testSetUp(0x0);
+        if (SDLTest_AssertSummaryToTestResult() == TEST_RESULT_FAILED) {
+            SDLTest_LogError((char *)SDLTest_FinalResultFormat, "Suite Setup", testSuite->name, "Failed");
+            return TEST_RESULT_SETUP_FAILURE;
+        }
+    }
+
+    /* Run test case function */
+    testCaseResult = testCase->testCase(0x0);
+
+    /* Convert test execution result into harness result */
+    if (testCaseResult == TEST_SKIPPED) {
+        /* Test was programatically skipped */
+        testResult = TEST_RESULT_SKIPPED;
+    } else if (testCaseResult == TEST_STARTED) {
+        /* Test did not return a TEST_COMPLETED value; assume it failed */
+        testResult = TEST_RESULT_FAILED;
+    } else if (testCaseResult == TEST_ABORTED) {
+        /* Test was aborted early; assume it failed */
+        testResult = TEST_RESULT_FAILED;
+    } else {
+        /* Perform failure analysis based on asserts */
+        testResult = SDLTest_AssertSummaryToTestResult();
+    }
+
+    /* Maybe run suite cleanup function (ignore failed asserts) */
+    if (testSuite->testTearDown) {
+        testSuite->testTearDown(0x0);
+    }
+
+    /* Cancel timeout timer */
+    if (timer) {
+        SDL_RemoveTimer(timer);
+    }
+
+    /* Report on asserts and fuzzer usage */
+    fuzzerCount = SDLTest_GetFuzzerInvocationCount();
+    if (fuzzerCount > 0) {
+        SDLTest_Log("Fuzzer invocations: %d", fuzzerCount);
+    }
+
+    /* Final log based on test execution result */
+    if (testCaseResult == TEST_SKIPPED) {
+        /* Test was programatically skipped */
+        SDLTest_Log((char *)SDLTest_FinalResultFormat, "Test", testCase->name, "Skipped (Programmatically)");
+    } else if (testCaseResult == TEST_STARTED) {
+        /* Test did not return a TEST_COMPLETED value; assume it failed */
+        SDLTest_LogError((char *)SDLTest_FinalResultFormat, "Test", testCase->name, "Failed (test started, but did not return TEST_COMPLETED)");
+    } else if (testCaseResult == TEST_ABORTED) {
+        /* Test was aborted early; assume it failed */
+        SDLTest_LogError((char *)SDLTest_FinalResultFormat, "Test", testCase->name, "Failed (Aborted)");
+    } else {
+        SDLTest_LogAssertSummary();
+    }
+
+    return testResult;
+}
+
+/* Prints summary of all suites/tests contained in the given reference */
+void SDLTest_LogTestSuiteSummary(SDLTest_TestSuiteReference *testSuites)
+{
+    int suiteCounter;
+    int testCounter;
+    SDLTest_TestSuiteReference *testSuite;
+    SDLTest_TestCaseReference *testCase;
+
+    /* Loop over all suites */
+    suiteCounter = 0;
+    while(&testSuites[suiteCounter]) {
+        testSuite=&testSuites[suiteCounter];
+        suiteCounter++;
+        SDLTest_Log("Test Suite %i - %s\n", suiteCounter,
+            (testSuite->name) ? testSuite->name : SDLTest_InvalidNameFormat);
+
+        /* Loop over all test cases */
+        testCounter = 0;
+        while(testSuite->testCases[testCounter])
+        {
+            testCase=(SDLTest_TestCaseReference *)testSuite->testCases[testCounter];
+            testCounter++;
+            SDLTest_Log("  Test Case %i - %s: %s", testCounter,
+                (testCase->name) ? testCase->name : SDLTest_InvalidNameFormat,
+                (testCase->description) ? testCase->description : SDLTest_InvalidNameFormat);
+        }
+    }
+}
+
+/* Gets a timer value in seconds */
+float GetClock()
+{
+    float currentClock = (float)clock();
+    return currentClock / (float)CLOCKS_PER_SEC;
+}
+
+/**
+* \brief Execute a test suite using the given run seend and execution key.
+*
+* The filter string is matched to the suite name (full comparison) to select a single suite,
+* or if no suite matches, it is matched to the test names (full comparison) to select a single test.
+*
+* \param testSuites Suites containing the test case.
+* \param userRunSeed Custom run seed provided by user, or NULL to autogenerate one.
+* \param userExecKey Custom execution key provided by user, or 0 to autogenerate one.
+* \param filter Filter specification. NULL disables. Case sensitive.
+* \param testIterations Number of iterations to run each test case.
+*
+* \returns Test run result; 0 when all tests passed, 1 if any tests failed.
+*/
+int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *userRunSeed, Uint64 userExecKey, const char *filter, int testIterations)
+{
+    int suiteCounter;
+    int testCounter;
+    int iterationCounter;
+    SDLTest_TestSuiteReference *testSuite;
+    SDLTest_TestCaseReference *testCase;
+    const char *runSeed = NULL;
+    char *currentSuiteName;
+    char *currentTestName;
+    Uint64 execKey;
+    float runStartSeconds;
+    float suiteStartSeconds;
+    float testStartSeconds;
+    float runEndSeconds;
+    float suiteEndSeconds;
+    float testEndSeconds;
+    float runtime;
+    int suiteFilter = 0;
+    char *suiteFilterName = NULL;
+    int testFilter = 0;
+    char *testFilterName = NULL;
+    int testResult = 0;
+    int runResult = 0;
+    Uint32 totalTestFailedCount = 0;
+    Uint32 totalTestPassedCount = 0;
+    Uint32 totalTestSkippedCount = 0;
+    Uint32 testFailedCount = 0;
+    Uint32 testPassedCount = 0;
+    Uint32 testSkippedCount = 0;
+    Uint32 countSum = 0;
+    char *logFormat = (char *)SDLTest_LogSummaryFormat;
+
+    /* Sanitize test iterations */
+    if (testIterations < 1) {
+        testIterations = 1;
+    }
+
+    /* Generate run see if we don't have one already */
+    if (userRunSeed == NULL || SDL_strlen(userRunSeed) == 0) {
+        runSeed = SDLTest_GenerateRunSeed(16);
+        if (runSeed == NULL) {
+            SDLTest_LogError("Generating a random seed failed");
+            return 2;
+        }
+    } else {
+        runSeed = userRunSeed;
+    }
+
+
+    /* Reset per-run counters */
+    totalTestFailedCount = 0;
+    totalTestPassedCount = 0;
+    totalTestSkippedCount = 0;
+
+    /* Take time - run start */
+    runStartSeconds = GetClock();
+
+    /* Log run with fuzzer parameters */
+    SDLTest_Log("::::: Test Run /w seed '%s' started\n", runSeed);
+
+    /* Initialize filtering */
+    if (filter != NULL && SDL_strlen(filter) > 0) {
+        /* Loop over all suites to check if we have a filter match */
+        suiteCounter = 0;
+        while (testSuites[suiteCounter] && suiteFilter == 0) {
+            testSuite=(SDLTest_TestSuiteReference *)testSuites[suiteCounter];
+            suiteCounter++;
+            if (testSuite->name != NULL && SDL_strcmp(filter, testSuite->name) == 0) {
+                /* Matched a suite name */
+                suiteFilter = 1;
+                suiteFilterName = testSuite->name;
+                SDLTest_Log("Filtering: running only suite '%s'", suiteFilterName);
+                break;
+            }
+
+            /* Within each suite, loop over all test cases to check if we have a filter match */
+            testCounter = 0;
+            while (testSuite->testCases[testCounter] && testFilter == 0)
+            {
+                testCase=(SDLTest_TestCaseReference *)testSuite->testCases[testCounter];
+                testCounter++;
+                if (testCase->name != NULL && SDL_strcmp(filter, testCase->name) == 0) {
+                    /* Matched a test name */
+                    suiteFilter = 1;
+                    suiteFilterName = testSuite->name;
+                    testFilter = 1;
+                    testFilterName = testCase->name;
+                    SDLTest_Log("Filtering: running only test '%s' in suite '%s'", testFilterName, suiteFilterName);
+                    break;
+                }
+            }
+        }
+
+        if (suiteFilter == 0 && testFilter == 0) {
+            SDLTest_LogError("Filter '%s' did not match any test suite/case.", filter);
+            SDLTest_Log("Exit code: 2");
+            return 2;
+        }
+    }
+
+    /* Loop over all suites */
+    suiteCounter = 0;
+    while(testSuites[suiteCounter]) {
+        testSuite=(SDLTest_TestSuiteReference *)testSuites[suiteCounter];
+        currentSuiteName = (char *)((testSuite->name) ? testSuite->name : SDLTest_InvalidNameFormat);
+        suiteCounter++;
+
+        /* Filter suite if flag set and we have a name */
+        if (suiteFilter == 1 && suiteFilterName != NULL && testSuite->name != NULL &&
+            SDL_strcmp(suiteFilterName, testSuite->name) != 0) {
+                /* Skip suite */
+                SDLTest_Log("===== Test Suite %i: '%s' skipped\n",
+                    suiteCounter,
+                    currentSuiteName);
+        } else {
+
+            /* Reset per-suite counters */
+            testFailedCount = 0;
+            testPassedCount = 0;
+            testSkippedCount = 0;
+
+            /* Take time - suite start */
+            suiteStartSeconds = GetClock();
+
+            /* Log suite started */
+            SDLTest_Log("===== Test Suite %i: '%s' started\n",
+                suiteCounter,
+                currentSuiteName);
+
+            /* Loop over all test cases */
+            testCounter = 0;
+            while(testSuite->testCases[testCounter])
+            {
+                testCase=(SDLTest_TestCaseReference *)testSuite->testCases[testCounter];
+                currentTestName = (char *)((testCase->name) ? testCase->name : SDLTest_InvalidNameFormat);
+                testCounter++;
+
+                /* Filter tests if flag set and we have a name */
+                if (testFilter == 1 && testFilterName != NULL && testCase->name != NULL &&
+                    SDL_strcmp(testFilterName, testCase->name) != 0) {
+                        /* Skip test */
+                        SDLTest_Log("===== Test Case %i.%i: '%s' skipped\n",
+                            suiteCounter,
+                            testCounter,
+                            currentTestName);
+                } else {
+                    /* Override 'disabled' flag if we specified a test filter (i.e. force run for debugging) */
+                    if (testFilter == 1 && !testCase->enabled) {
+                        SDLTest_Log("Force run of disabled test since test filter was set");
+                        testCase->enabled = 1;
+                    }
+
+                    /* Take time - test start */
+                    testStartSeconds = GetClock();
+
+                    /* Log test started */
+                    SDLTest_Log("----- Test Case %i.%i: '%s' started",
+                        suiteCounter,
+                        testCounter,
+                        currentTestName);
+                    if (testCase->description != NULL && SDL_strlen(testCase->description)>0) {
+                        SDLTest_Log("Test Description: '%s'",
+                            (testCase->description) ? testCase->description : SDLTest_InvalidNameFormat);
+                    }
+
+                    /* Loop over all iterations */
+                    iterationCounter = 0;
+                    while(iterationCounter < testIterations)
+                    {
+                        iterationCounter++;
+
+                        if (userExecKey != 0) {
+                            execKey = userExecKey;
+                        } else {
+                            execKey = SDLTest_GenerateExecKey((char *)runSeed, testSuite->name, testCase->name, iterationCounter);
+                        }
+
+                        SDLTest_Log("Test Iteration %i: execKey %llu", iterationCounter, execKey);
+                        testResult = SDLTest_RunTest(testSuite, testCase, execKey);
+
+                        if (testResult == TEST_RESULT_PASSED) {
+                            testPassedCount++;
+                            totalTestPassedCount++;
+                        } else if (testResult == TEST_RESULT_SKIPPED) {
+                            testSkippedCount++;
+                            totalTestSkippedCount++;
+                        } else {
+                            testFailedCount++;
+                            totalTestFailedCount++;
+                        }
+                    }
+
+                    /* Take time - test end */
+                    testEndSeconds = GetClock();
+                    runtime = testEndSeconds - testStartSeconds;
+                    if (runtime < 0.0f) runtime = 0.0f;
+
+                    if (testIterations > 1) {
+                        /* Log test runtime */
+                        SDLTest_Log("Runtime of %i iterations: %.1f sec", testIterations, runtime);
+                        SDLTest_Log("Average Test runtime: %.5f sec", runtime / (float)testIterations);
+                    } else {
+                        /* Log test runtime */
+                        SDLTest_Log("Total Test runtime: %.1f sec", runtime);
+                    }
+
+                    /* Log final test result */
+                    switch (testResult) {
+                    case TEST_RESULT_PASSED:
+                        SDLTest_Log((char *)SDLTest_FinalResultFormat, "Test", currentTestName, "Passed");
+                        break;
+                    case TEST_RESULT_FAILED:
+                        SDLTest_LogError((char *)SDLTest_FinalResultFormat, "Test", currentTestName, "Failed");
+                        break;
+                    case TEST_RESULT_NO_ASSERT:
+                        SDLTest_LogError((char *)SDLTest_FinalResultFormat,"Test", currentTestName, "No Asserts");
+                        break;
+                    }
+
+                }
+            }
+
+            /* Take time - suite end */
+            suiteEndSeconds = GetClock();
+            runtime = suiteEndSeconds - suiteStartSeconds;
+            if (runtime < 0.0f) runtime = 0.0f;
+
+            /* Log suite runtime */
+            SDLTest_Log("Total Suite runtime: %.1f sec", runtime);
+
+            /* Log summary and final Suite result */
+            countSum = testPassedCount + testFailedCount + testSkippedCount;
+            if (testFailedCount == 0)
+            {
+                SDLTest_Log(logFormat, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount);
+                SDLTest_Log((char *)SDLTest_FinalResultFormat, "Suite", currentSuiteName, "Passed");
+            }
+            else
+            {
+                SDLTest_LogError(logFormat, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount);
+                SDLTest_LogError((char *)SDLTest_FinalResultFormat, "Suite", currentSuiteName, "Failed");
+            }
+
+        }
+    }
+
+    /* Take time - run end */
+    runEndSeconds = GetClock();
+    runtime = runEndSeconds - runStartSeconds;
+    if (runtime < 0.0f) runtime = 0.0f;
+
+    /* Log total runtime */
+    SDLTest_Log("Total Run runtime: %.1f sec", runtime);
+
+    /* Log summary and final run result */
+    countSum = totalTestPassedCount + totalTestFailedCount + totalTestSkippedCount;
+    if (totalTestFailedCount == 0)
+    {
+        runResult = 0;
+        SDLTest_Log(logFormat, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount);
+        SDLTest_Log((char *)SDLTest_FinalResultFormat, "Run /w seed", runSeed, "Passed");
+    }
+    else
+    {
+        runResult = 1;
+        SDLTest_LogError(logFormat, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount);
+        SDLTest_LogError((char *)SDLTest_FinalResultFormat, "Run /w seed", runSeed, "Failed");
+    }
+
+    SDLTest_Log("Exit code: %d", runResult);
+    return runResult;
+}

Some files were not shown because too many files changed in this diff