mirror of
https://github.com/love2d/love-android.git
synced 2026-08-13 17:11:01 +02:00
Compare commits
53 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5048f3ff8c | |||
| 66f600b5ab | |||
| 659b312121 | |||
| b875fffedb | |||
| 45b1fc2509 | |||
| c6ac06c366 | |||
| abb819335b | |||
| aba2f47b31 | |||
| ea459a43da | |||
| 6110de0fa8 | |||
| 8f20cb7cc5 | |||
| b25af54383 | |||
| c27f19c141 | |||
| d1ad6cc5a3 | |||
| afe33f06d2 | |||
| 70cb26bb2a | |||
| 8cb7bac09f | |||
| 49265f0596 | |||
| 1d29da2d80 | |||
| 6459889d32 | |||
| 6be242ef03 | |||
| 97d9154e48 | |||
| c40250e565 | |||
| 684adff826 | |||
| ec9be8a383 | |||
| d637b5c11d | |||
| adc4042d8b | |||
| e96eef4435 | |||
| 8acfb8d91a | |||
| cc829bdd1e | |||
| 7593d64761 | |||
| f09239788a | |||
| c0fd9a6e1b | |||
| 539ca8d4f2 | |||
| fab725ad8b | |||
| 5f6fa8c2b5 | |||
| 4c2846f4bb | |||
| cb2c852f58 | |||
| 60a58f9240 | |||
| 5849e8d369 | |||
| 1703660617 | |||
| 0db55463c9 | |||
| 288b25c585 | |||
| a5284dccf6 | |||
| 8069dc02c6 | |||
| 0bde453b2e | |||
| 667c4750ea | |||
| 38727b5c25 | |||
| 288a851a65 | |||
| 5e3579f680 | |||
| 1dd859c9d1 | |||
| 53d45533e0 | |||
| 3f13dc653f |
+52
-16
@@ -1,29 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="org.love2d.android"
|
||||
android:versionCode="9"
|
||||
android:versionName="0.9.0-alpha9"
|
||||
android:versionCode="14"
|
||||
android:versionName="0.9.1b"
|
||||
android:installLocation="auto" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<!-- Allow writing to external storage -->
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:allowBackup="true"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="LÖVE for Android"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
|
||||
<service android:name=".DownloadService" />
|
||||
<activity
|
||||
android:name="GameActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:label="LÖVE for Android"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
|
||||
<activity
|
||||
android:name="GameActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:label="LÖVE for Android"
|
||||
android:screenOrientation="landscape" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
<category android:name="tv.ouya.intent.category.GAME"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
android:screenOrientation="landscape" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
<category android:name="tv.ouya.intent.category.GAME"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:scheme="file" />
|
||||
<data android:scheme="content" />
|
||||
<data android:mimeType="application/x-love-game" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:scheme="file" />
|
||||
<data android:mimeType="*/*" />
|
||||
<data android:pathPattern=".*\\.love" />
|
||||
<data android:host="*" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name="DownloadActivity"
|
||||
android:noHistory="true" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="http"
|
||||
android:host="*"
|
||||
android:pathPrefix="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.love" />
|
||||
<data android:scheme="https"
|
||||
android:host="*"
|
||||
android:pathPrefix="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.love" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
<!-- Android 2.3.3 -->
|
||||
|
||||
@@ -4,7 +4,7 @@ Copyright (c) 2013-2014 Martin Felis <martin@fysx.org>
|
||||
Instructions:
|
||||
-------------
|
||||
|
||||
For detailed instructions please refer to the [wiki](wiki).
|
||||
For detailed instructions please refer to the wiki at [https://bitbucket.org/MartinFelis/love-android-sdl2/wiki/Home](https://bitbucket.org/MartinFelis/love-android-sdl2/wiki/Home).
|
||||
|
||||
Quick Start:
|
||||
------------
|
||||
@@ -26,12 +26,44 @@ install on your phone.
|
||||
Bugs:
|
||||
-----
|
||||
|
||||
Bugs and feature requests should be reported to the [issue
|
||||
tracker](issues?status=new&status=open).
|
||||
Bugs and feature requests should be reported to the issue tracker at [https://bitbucket.org/MartinFelis/love-android-sdl2/issues?status=new&status=open](https://bitbucket.org/MartinFelis/love-android-sdl2/issues?status=new&status=open).
|
||||
|
||||
Changelog:
|
||||
----------
|
||||
|
||||
0.9.1b:
|
||||
|
||||
* added love.system.vibrate(seconds)
|
||||
* print statements are now redirected to logcat. Output is prefixed with "[LOVE] "
|
||||
* removed DevIL, libpng, libjpeg, libmng, and libtiff
|
||||
* pngs are loaded using lodepng and jpegs using libturbo-jpeg
|
||||
* repeatedly fixed a bug which caused Release builds to crash
|
||||
* update to latest mobile-common branch
|
||||
|
||||
0.9.1a:
|
||||
|
||||
* using latest SDL\_androidgl.c (fixes some random performance issues)
|
||||
* using latest love-android @ changeset 8659be0e75a3 (adds support for
|
||||
compressed textures)
|
||||
|
||||
0.9.1:
|
||||
|
||||
* uses 0.9.1 API
|
||||
* fixed crash on Moto G (and possibly other devices). This was a nasty bug that would just show a blue screen without an error message. The bug was resolved using the help of headchant
|
||||
* fixed loading of jpegs (it probably hasn't worked up to now)
|
||||
* fixed issues with looping over active touches. This fix was sponsored by slime!
|
||||
|
||||
beta2:
|
||||
|
||||
* fixed bug with canvases
|
||||
* fixed writing of files when no identity in conf.lua was set
|
||||
* added file association (somewhat experimental)
|
||||
|
||||
beta1:
|
||||
|
||||
* fixed nasty crash on startup bug
|
||||
* fixed love.filesystem.getDirectoryItems()
|
||||
|
||||
alpha9:
|
||||
|
||||
* Packaged games do not get duplicated for loading, instead are loaded from memory (!!!)
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
###########################
|
||||
#
|
||||
# SDL shared library
|
||||
#
|
||||
###########################
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := SDL2
|
||||
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
|
||||
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(subst $(LOCAL_PATH)/,, \
|
||||
$(wildcard $(LOCAL_PATH)/src/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/audio/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/audio/android/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/audio/dummy/*.c) \
|
||||
$(LOCAL_PATH)/src/atomic/SDL_atomic.c \
|
||||
$(LOCAL_PATH)/src/atomic/SDL_spinlock.c.arm \
|
||||
$(wildcard $(LOCAL_PATH)/src/core/android/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/cpuinfo/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/dynapi/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/events/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/file/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/haptic/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/haptic/dummy/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/joystick/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/joystick/android/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/loadso/dlopen/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/power/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/power/android/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/filesystem/dummy/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/render/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/render/*/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/stdlib/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/thread/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/thread/pthread/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/timer/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/timer/unix/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/video/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/video/android/*.c))
|
||||
|
||||
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES
|
||||
LOCAL_LDLIBS := -ldl -lGLESv1_CM -lGLESv2 -llog -landroid
|
||||
|
||||
# include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
###########################
|
||||
#
|
||||
# SDL static library
|
||||
#
|
||||
###########################
|
||||
|
||||
LOCAL_MODULE := SDL2_static
|
||||
|
||||
LOCAL_MODULE_FILENAME := libSDL2
|
||||
|
||||
LOCAL_SRC_FILES += src/main/android/SDL_android_main.c
|
||||
|
||||
LOCAL_LDLIBS :=
|
||||
LOCAL_EXPORT_LDLIBS := -Wl,--undefined=Java_org_libsdl_app_SDLActivity_nativeInit -ldl -lGLESv1_CM -lGLESv2 -llog -landroid
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,20 +0,0 @@
|
||||
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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.
|
||||
|
||||
@@ -1,222 +0,0 @@
|
||||
==============================================================================
|
||||
Using the Simple DirectMedia Layer with Mac OS X
|
||||
==============================================================================
|
||||
|
||||
These instructions are for people using Apple's Mac OS X (pronounced
|
||||
"ten").
|
||||
|
||||
From the developer's point of view, OS X is a sort of hybrid Mac and
|
||||
Unix system, and you have the option of using either traditional
|
||||
command line tools or Apple's IDE Xcode.
|
||||
|
||||
To build SDL using the command line, use the standard configure and make
|
||||
process:
|
||||
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
|
||||
You can also build SDL as a Universal library (a single binary for both
|
||||
PowerPC and Intel architectures), on Mac OS X 10.4 and newer, by using
|
||||
the fatbuild.sh script in build-scripts:
|
||||
sh build-scripts/fatbuild.sh
|
||||
sudo build-scripts/fatbuild.sh install
|
||||
This script builds SDL with 10.2 ABI compatibility on PowerPC and 10.4
|
||||
ABI compatibility on Intel architectures. For best compatibility you
|
||||
should compile your application the same way. A script which wraps
|
||||
gcc to make this easy is provided in test/gcc-fat.sh
|
||||
|
||||
To use the library once it's built, you essential have two possibilities:
|
||||
use the traditional autoconf/automake/make method, or use Xcode.
|
||||
|
||||
==============================================================================
|
||||
Caveats for using SDL with Mac OS X
|
||||
==============================================================================
|
||||
|
||||
Some things you have to be aware of when using SDL on Mac OS X:
|
||||
|
||||
- If you register your own NSApplicationDelegate (using [NSApp setDelegate:]),
|
||||
SDL will not register its own. This means that SDL will not terminate using
|
||||
SDL_Quit if it receives a termination request, it will terminate like a
|
||||
normal app, and it will not send a SDL_DROPFILE when you request to open a
|
||||
file with the app. To solve these issues, put the following code in your
|
||||
NSApplicationDelegate implementation:
|
||||
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
|
||||
{
|
||||
if (SDL_GetEventState(SDL_QUIT) == SDL_ENABLE) {
|
||||
SDL_Event event;
|
||||
event.type = SDL_QUIT;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
|
||||
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
|
||||
{
|
||||
if (SDL_GetEventState(SDL_DROPFILE) == SDL_ENABLE) {
|
||||
SDL_Event event;
|
||||
event.type = SDL_DROPFILE;
|
||||
event.drop.file = SDL_strdup([filename UTF8String]);
|
||||
return (SDL_PushEvent(&event) > 0);
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
==============================================================================
|
||||
Using the Simple DirectMedia Layer with a traditional Makefile
|
||||
==============================================================================
|
||||
|
||||
An existing autoconf/automake build system for your SDL app has good chances
|
||||
to work almost unchanged on OS X. However, to produce a "real" Mac OS X binary
|
||||
that you can distribute to users, you need to put the generated binary into a
|
||||
so called "bundle", which basically is a fancy folder with a name like
|
||||
"MyCoolGame.app".
|
||||
|
||||
To get this build automatically, add something like the following rule to
|
||||
your Makefile.am:
|
||||
|
||||
bundle_contents = APP_NAME.app/Contents
|
||||
APP_NAME_bundle: EXE_NAME
|
||||
mkdir -p $(bundle_contents)/MacOS
|
||||
mkdir -p $(bundle_contents)/Resources
|
||||
echo "APPL????" > $(bundle_contents)/PkgInfo
|
||||
$(INSTALL_PROGRAM) $< $(bundle_contents)/MacOS/
|
||||
|
||||
You should replace EXE_NAME with the name of the executable. APP_NAME is what
|
||||
will be visible to the user in the Finder. Usually it will be the same
|
||||
as EXE_NAME but capitalized. E.g. if EXE_NAME is "testgame" then APP_NAME
|
||||
usually is "TestGame". You might also want to use @PACKAGE@ to use the package
|
||||
name as specified in your configure.in file.
|
||||
|
||||
If your project builds more than one application, you will have to do a bit
|
||||
more. For each of your target applications, you need a separate rule.
|
||||
|
||||
If you want the created bundles to be installed, you may want to add this
|
||||
rule to your Makefile.am:
|
||||
|
||||
install-exec-hook: APP_NAME_bundle
|
||||
rm -rf $(DESTDIR)$(prefix)/Applications/APP_NAME.app
|
||||
mkdir -p $(DESTDIR)$(prefix)/Applications/
|
||||
cp -r $< /$(DESTDIR)$(prefix)Applications/
|
||||
|
||||
This rule takes the Bundle created by the rule from step 3 and installs them
|
||||
into $(DESTDIR)$(prefix)/Applications/.
|
||||
|
||||
Again, if you want to install multiple applications, you will have to augment
|
||||
the make rule accordingly.
|
||||
|
||||
|
||||
But beware! That is only part of the story! With the above, you end up with
|
||||
a bare bone .app bundle, which is double clickable from the Finder. But
|
||||
there are some more things you should do before shipping your product...
|
||||
|
||||
1) The bundle right now probably is dynamically linked against SDL. That
|
||||
means that when you copy it to another computer, *it will not run*,
|
||||
unless you also install SDL on that other computer. A good solution
|
||||
for this dilemma is to static link against SDL. On OS X, you can
|
||||
achieve that by linking against the libraries listed by
|
||||
sdl-config --static-libs
|
||||
instead of those listed by
|
||||
sdl-config --libs
|
||||
Depending on how exactly SDL is integrated into your build systems, the
|
||||
way to achieve that varies, so I won't describe it here in detail
|
||||
2) Add an 'Info.plist' to your application. That is a special XML file which
|
||||
contains some meta-information about your application (like some copyright
|
||||
information, the version of your app, the name of an optional icon file,
|
||||
and other things). Part of that information is displayed by the Finder
|
||||
when you click on the .app, or if you look at the "Get Info" window.
|
||||
More information about Info.plist files can be found on Apple's homepage.
|
||||
|
||||
|
||||
As a final remark, let me add that I use some of the techniques (and some
|
||||
variations of them) in Exult and ScummVM; both are available in source on
|
||||
the net, so feel free to take a peek at them for inspiration!
|
||||
|
||||
|
||||
==============================================================================
|
||||
Using the Simple DirectMedia Layer with Xcode
|
||||
==============================================================================
|
||||
|
||||
These instructions are for using Apple's Xcode IDE to build SDL applications.
|
||||
|
||||
- First steps
|
||||
|
||||
The first thing to do is to unpack the Xcode.tar.gz archive in the
|
||||
top level SDL directory (where the Xcode.tar.gz archive resides).
|
||||
Because Stuffit Expander will unpack the archive into a subdirectory,
|
||||
you should unpack the archive manually from the command line:
|
||||
cd [path_to_SDL_source]
|
||||
tar zxf Xcode.tar.gz
|
||||
This will create a new folder called Xcode, which you can browse
|
||||
normally from the Finder.
|
||||
|
||||
- Building the Framework
|
||||
|
||||
The SDL Library is packaged as a framework bundle, an organized
|
||||
relocatable folder hierarchy of executable code, interface headers,
|
||||
and additional resources. For practical purposes, you can think of a
|
||||
framework as a more user and system-friendly shared library, whose library
|
||||
file behaves more or less like a standard UNIX shared library.
|
||||
|
||||
To build the framework, simply open the framework project and build it.
|
||||
By default, the framework bundle "SDL.framework" is installed in
|
||||
/Library/Frameworks. Therefore, the testers and project stationary expect
|
||||
it to be located there. However, it will function the same in any of the
|
||||
following locations:
|
||||
|
||||
~/Library/Frameworks
|
||||
/Local/Library/Frameworks
|
||||
/System/Library/Frameworks
|
||||
|
||||
- Build Options
|
||||
There are two "Build Styles" (See the "Targets" tab) for SDL.
|
||||
"Deployment" should be used if you aren't tweaking the SDL library.
|
||||
"Development" should be used to debug SDL apps or the library itself.
|
||||
|
||||
- Building the Testers
|
||||
Open the SDLTest project and build away!
|
||||
|
||||
- Using the Project Stationary
|
||||
Copy the stationary to the indicated folders to access it from
|
||||
the "New Project" and "Add target" menus. What could be easier?
|
||||
|
||||
- Setting up a new project by hand
|
||||
Some of you won't want to use the Stationary so I'll give some tips:
|
||||
* Create a new "Cocoa Application"
|
||||
* Add src/main/macosx/SDLMain.m , .h and .nib to your project
|
||||
* Remove "main.c" from your project
|
||||
* Remove "MainMenu.nib" from your project
|
||||
* Add "$(HOME)/Library/Frameworks/SDL.framework/Headers" to include path
|
||||
* Add "$(HOME)/Library/Frameworks" to the frameworks search path
|
||||
* Add "-framework SDL -framework Foundation -framework AppKit" to "OTHER_LDFLAGS"
|
||||
* Set the "Main Nib File" under "Application Settings" to "SDLMain.nib"
|
||||
* Add your files
|
||||
* Clean and build
|
||||
|
||||
- Building from command line
|
||||
Use pbxbuild in the same directory as your .pbproj file
|
||||
|
||||
- Running your app
|
||||
You can send command line args to your app by either invoking it from
|
||||
the command line (in *.app/Contents/MacOS) or by entering them in the
|
||||
"Executables" panel of the target settings.
|
||||
|
||||
- Implementation Notes
|
||||
Some things that may be of interest about how it all works...
|
||||
* Working directory
|
||||
As defined in the SDL_main.m file, the working directory of your SDL app
|
||||
is by default set to its parent. You may wish to change this to better
|
||||
suit your needs.
|
||||
* You have a Cocoa App!
|
||||
Your SDL app is essentially a Cocoa application. When your app
|
||||
starts up and the libraries finish loading, a Cocoa procedure is called,
|
||||
which sets up the working directory and calls your main() method.
|
||||
You are free to modify your Cocoa app with generally no consequence
|
||||
to SDL. You cannot, however, easily change the SDL window itself.
|
||||
Functionality may be added in the future to help this.
|
||||
|
||||
|
||||
Known bugs are listed in the file "BUGS"
|
||||
@@ -1,9 +0,0 @@
|
||||
|
||||
Windows CE is no longer supported by SDL.
|
||||
|
||||
We have left the CE support in SDL 1.2 for those that must have it, and we
|
||||
will accept patches that support more modern Windows Mobile platforms for
|
||||
SDL 2.0.
|
||||
|
||||
--ryan.
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
================================================================================
|
||||
Simple DirectMedia Layer for Windows
|
||||
================================================================================
|
||||
|
||||
================================================================================
|
||||
OpenGL ES 2.x support
|
||||
================================================================================
|
||||
|
||||
SDL has support for OpenGL ES 2.x under Windows via two alternative
|
||||
implementations.
|
||||
The most straightforward method consists in running your app in a system with
|
||||
a graphic card paired with a relatively recent (as of November of 2013) driver
|
||||
which supports the WGL_EXT_create_context_es2_profile extension. Vendors known
|
||||
to ship said extension on Windows currently include nVidia and Intel.
|
||||
|
||||
The other method involves using the ANGLE library (https://code.google.com/p/angleproject/)
|
||||
If an OpenGL ES 2.x context is requested and no WGL_EXT_create_context_es2_profile
|
||||
extension is found, SDL will try to load the libEGL.dll library provided by
|
||||
ANGLE.
|
||||
To obtain the ANGLE binaries, you can either compile from source from
|
||||
https://chromium.googlesource.com/angle/angle or copy the relevant binaries from
|
||||
a recent Chrome/Chromium install for Windows. The files you need are:
|
||||
|
||||
* libEGL.dll
|
||||
* libGLESv2.dll
|
||||
* d3dcompiler_46.dll (supports Windows Vista or later, better shader compiler)
|
||||
or...
|
||||
* d3dcompiler_43.dll (supports Windows XP or later)
|
||||
|
||||
If you compile ANGLE from source, you can configure it so it does not need the
|
||||
d3dcompiler_* DLL at all (for details on this, see their documentation).
|
||||
However, by default SDL will try to preload the d3dcompiler_46.dll to
|
||||
comply with ANGLE's requirements. If you wish SDL to preload d3dcompiler_43.dll (to
|
||||
support Windows XP) or to skip this step at all, you can use the
|
||||
SDL_VIDEO_WIN_D3DCOMPILER hint (see SDL_hints.h for more details).
|
||||
|
||||
Known Bugs:
|
||||
|
||||
* SDL_GL_SetSwapInterval is currently a no op when using ANGLE. It appears
|
||||
that there's a bug in the library which prevents the window contents from
|
||||
refreshing if this is set to anything other than the default value.
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
|
||||
This is a list of major changes in SDL's version history.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
2.0.2:
|
||||
---------------------------------------------------------------------------
|
||||
General:
|
||||
* Added an API to load a database of Game Controller mappings from a file:
|
||||
SDL_GameControllerAddMappingsFromFile
|
||||
* EGL can now create/manage OpenGL and OpenGL ES 1.x/2.x contexts, and share
|
||||
them using SDL_GL_SHARE_WITH_CURRENT_CONTEXT
|
||||
* Added testgles2. testgl2 does not need to link with libGL anymore.
|
||||
|
||||
Windows:
|
||||
* Support for OpenGL ES 2.x contexts using either WGL or EGL (natively via
|
||||
the driver or emulated through ANGLE)
|
||||
|
||||
Android:
|
||||
* Joystick support (minimum SDK version required to build SDL is now 12,
|
||||
the required runtime version remains at 10, but on such devices joystick
|
||||
support won't be available).
|
||||
* Hotplugging support for joysticks
|
||||
|
||||
Linux:
|
||||
* Fixed fullscreen and focused behavior when receiving NotifyGrab events
|
||||
* Wayland support
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
2.0.1:
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
General:
|
||||
* Added an API to get common filesystem paths in SDL_filesystem.h:
|
||||
SDL_GetBasePath(), SDL_GetPrefPath()
|
||||
* Added an API to do optimized YV12 and IYUV texture updates:
|
||||
SDL_UpdateYUVTexture()
|
||||
* Added an API to get the amount of RAM on the system:
|
||||
SDL_GetSystemRAM()
|
||||
* Added a macro to perform timestamp comparisons with SDL_GetTicks():
|
||||
SDL_TICKS_PASSED()
|
||||
* Dramatically improved OpenGL ES 2.0 rendering performance
|
||||
* Added OpenGL attribute SDL_GL_FRAMEBUFFER_SRGB_CAPABLE
|
||||
|
||||
Windows:
|
||||
* Created a static library configuration for the Visual Studio 2010 project
|
||||
* Added a hint to create the Direct3D device with support for multi-threading:
|
||||
SDL_HINT_RENDER_DIRECT3D_THREADSAFE
|
||||
* Added a function to get the D3D9 adapter index for a display:
|
||||
SDL_Direct3D9GetAdapterIndex()
|
||||
* Added a function to get the D3D9 device for a D3D9 renderer:
|
||||
SDL_RenderGetD3D9Device()
|
||||
* Fixed building SDL with the mingw32 toolchain (mingw-w64 is preferred)
|
||||
* Fixed crash when using two XInput controllers at the same time
|
||||
* Fixed detecting a mixture of XInput and DirectInput controllers
|
||||
* Fixed clearing a D3D render target larger than the window
|
||||
* Improved support for format specifiers in SDL_snprintf()
|
||||
|
||||
Mac OS X:
|
||||
* Added support for retina displays:
|
||||
Create your window with the SDL_WINDOW_ALLOW_HIGHDPI flag, and then use SDL_GL_GetDrawableSize() to find the actual drawable size. You are responsible for scaling mouse and drawing coordinates appropriately.
|
||||
* Fixed mouse warping in fullscreen mode
|
||||
* Right mouse click is emulated by holding the Ctrl key while left clicking
|
||||
|
||||
Linux:
|
||||
* Fixed float audio support with the PulseAudio driver
|
||||
* Fixed missing line endpoints in the OpenGL renderer on some drivers
|
||||
* X11 symbols are no longer defined to avoid collisions when linking statically
|
||||
|
||||
iOS:
|
||||
* Fixed status bar visibility on iOS 7
|
||||
* Flipped the accelerometer Y axis to match expected values
|
||||
|
||||
Android:
|
||||
IMPORTANT: You MUST get the updated SDLActivity.java to match C code
|
||||
* Moved EGL initialization to native code
|
||||
* Fixed the accelerometer axis rotation relative to the device rotation
|
||||
* Fixed race conditions when handling the EGL context on pause/resume
|
||||
* Touch devices are available for enumeration immediately after init
|
||||
|
||||
Raspberry Pi:
|
||||
* Added support for the Raspberry Pi, see README-raspberrypi.txt for details
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Vendored
-25607
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,72 +0,0 @@
|
||||
libsdl2 (2.0.1) UNRELEASED; urgency=low
|
||||
|
||||
* Updated SDL to version 2.0.1
|
||||
|
||||
-- Sam Lantinga <slouken@libsdl.org> Wed, 23 Oct 2013 16:31:38 -0800
|
||||
|
||||
libsdl2 (2.0.0) UNRELEASED; urgency=low
|
||||
|
||||
* SDL is now a native debian package.
|
||||
* Removed udeb package
|
||||
* Disabled DirectFB support by default, to avoid runtime dependencies
|
||||
|
||||
-- Sam Lantinga <slouken@libsdl.org> Fri, 15 Feb 2013 08:55:04 -0800
|
||||
|
||||
libsdl2 (2.0.0~20130127-1) UNRELEASED; urgency=low
|
||||
|
||||
* New upstream snapshot.
|
||||
|
||||
-- Sam Hocevar <sho@debian.org> Wed, 30 Jan 2013 23:01:12 +0100
|
||||
|
||||
libsdl2 (2.0.0~20130103-1) unstable; urgency=low
|
||||
|
||||
[ Manuel A. Fernandez Montecelo ]
|
||||
* debian/control:
|
||||
- Updating maintainers/permissions:
|
||||
- Add myself and Felix Geyer
|
||||
- Update Build-Depends:
|
||||
- Remove a few obsolete items
|
||||
- Add items added lately to libsdl1.2, such as libts (touch screen)
|
||||
support
|
||||
- Add "libsdl2-dbg", analog to libsdl1.2-dbg
|
||||
- Change "XC-Package-Type: udeb" to "Package-Type"
|
||||
* debian/compat: set level 9
|
||||
* debian/source/format: Set to "3.0 (quilt)"
|
||||
- Remove README.source, not needed with new format
|
||||
* debian/sdl2-config.1: Fix typo, "progams"->"programs"
|
||||
* debian/libsdl2-dev.install:
|
||||
- Remove "usr/lib/*/*.la", discouraged
|
||||
- Add man pages: "usr/share/man/man3/*"
|
||||
* debian/libsdl2-dev.manpages: add file to install local "sdl2-config.1"
|
||||
* debian/sources: Removed, possible obsolete file from long ago?
|
||||
* debian/copyright:
|
||||
- Upstream updated to zlib/libpng
|
||||
- Copyright-file format conversion to 1.0
|
||||
- Complete revamp and detailed research about copyright and licenses used,
|
||||
it's very messy but hopefully complete
|
||||
|
||||
[ Felix Geyer ]
|
||||
* Simplify debian/rules by using dh(1).
|
||||
|
||||
-- Manuel A. Fernandez Montecelo <manuel.montezelo@gmail.com> Sun, 27 Jan 2013 16:40:49 +0100
|
||||
|
||||
libsdl2 (2.0~20120220c-1) experimental; urgency=low
|
||||
|
||||
* Upstream version was renamed to 2.0 (Closes: #669367).
|
||||
* New upstream snapshot (Closes: #671506).
|
||||
* This package no longer conflicts with libsdl-1.2.
|
||||
* debian/rules: add multiarch support (Closes: #669364).
|
||||
|
||||
* debian/patches/fix_joystick_misc_axes.diff: fix a joystick remapping
|
||||
bug causing some axes to malfunction.
|
||||
* debian/patches/external_header_paths.diff: provide additional CFLAGS
|
||||
so that headers such as SDL_syswm.h can be included (Closes: #669363).
|
||||
|
||||
-- Sam Hocevar <sho@debian.org> Thu, 17 May 2012 19:03:59 +0200
|
||||
|
||||
libsdl-1.3 (1.3.0~20111204-1) experimental; urgency=low
|
||||
|
||||
* Initial upload from upstream snapshot.
|
||||
|
||||
-- Sam Hocevar <sho@debian.org> Sun, 04 Dec 2011 14:35:05 +0100
|
||||
|
||||
@@ -1,409 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file SDL_hints.h
|
||||
*
|
||||
* Official documentation for SDL configuration variables
|
||||
*
|
||||
* This file contains functions to set and get configuration hints,
|
||||
* as well as listing each of them alphabetically.
|
||||
*
|
||||
* The convention for naming hints is SDL_HINT_X, where "SDL_X" is
|
||||
* the environment variable that can be used to override the default.
|
||||
*
|
||||
* In general these hints are just that - they may or may not be
|
||||
* supported or applicable on any given platform, but they provide
|
||||
* a way for an application or user to give the library a hint as
|
||||
* to how they would like the library to work.
|
||||
*/
|
||||
|
||||
#ifndef _SDL_hints_h
|
||||
#define _SDL_hints_h
|
||||
|
||||
#include "SDL_stdinc.h"
|
||||
|
||||
#include "begin_code.h"
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief A variable controlling how 3D acceleration is used to accelerate the SDL screen surface.
|
||||
*
|
||||
* SDL can try to accelerate the SDL screen surface by using streaming
|
||||
* textures with a 3D rendering engine. This variable controls whether and
|
||||
* how this is done.
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - Disable 3D acceleration
|
||||
* "1" - Enable 3D acceleration, using the default renderer.
|
||||
* "X" - Enable 3D acceleration, using X where X is one of the valid rendering drivers. (e.g. "direct3d", "opengl", etc.)
|
||||
*
|
||||
* By default SDL tries to make a best guess for each platform whether
|
||||
* to use acceleration or not.
|
||||
*/
|
||||
#define SDL_HINT_FRAMEBUFFER_ACCELERATION "SDL_FRAMEBUFFER_ACCELERATION"
|
||||
|
||||
/**
|
||||
* \brief A variable specifying which render driver to use.
|
||||
*
|
||||
* If the application doesn't pick a specific renderer to use, this variable
|
||||
* specifies the name of the preferred renderer. If the preferred renderer
|
||||
* can't be initialized, the normal default renderer is used.
|
||||
*
|
||||
* This variable is case insensitive and can be set to the following values:
|
||||
* "direct3d"
|
||||
* "opengl"
|
||||
* "opengles2"
|
||||
* "opengles"
|
||||
* "software"
|
||||
*
|
||||
* The default varies by platform, but it's the first one in the list that
|
||||
* is available on the current platform.
|
||||
*/
|
||||
#define SDL_HINT_RENDER_DRIVER "SDL_RENDER_DRIVER"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling whether the OpenGL render driver uses shaders if they are available.
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - Disable shaders
|
||||
* "1" - Enable shaders
|
||||
*
|
||||
* By default shaders are used if OpenGL supports them.
|
||||
*/
|
||||
#define SDL_HINT_RENDER_OPENGL_SHADERS "SDL_RENDER_OPENGL_SHADERS"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling whether the Direct3D device is initialized for thread-safe operations.
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - Thread-safety is not enabled (faster)
|
||||
* "1" - Thread-safety is enabled
|
||||
*
|
||||
* By default the Direct3D device is created with thread-safety disabled.
|
||||
*/
|
||||
#define SDL_HINT_RENDER_DIRECT3D_THREADSAFE "SDL_RENDER_DIRECT3D_THREADSAFE"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling the scaling quality
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" or "nearest" - Nearest pixel sampling
|
||||
* "1" or "linear" - Linear filtering (supported by OpenGL and Direct3D)
|
||||
* "2" or "best" - Currently this is the same as "linear"
|
||||
*
|
||||
* By default nearest pixel sampling is used
|
||||
*/
|
||||
#define SDL_HINT_RENDER_SCALE_QUALITY "SDL_RENDER_SCALE_QUALITY"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling whether updates to the SDL screen surface should be synchronized with the vertical refresh, to avoid tearing.
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - Disable vsync
|
||||
* "1" - Enable vsync
|
||||
*
|
||||
* By default SDL does not sync screen surface updates with vertical refresh.
|
||||
*/
|
||||
#define SDL_HINT_RENDER_VSYNC "SDL_RENDER_VSYNC"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling whether the X11 VidMode extension should be used.
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - Disable XVidMode
|
||||
* "1" - Enable XVidMode
|
||||
*
|
||||
* By default SDL will use XVidMode if it is available.
|
||||
*/
|
||||
#define SDL_HINT_VIDEO_X11_XVIDMODE "SDL_VIDEO_X11_XVIDMODE"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling whether the X11 Xinerama extension should be used.
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - Disable Xinerama
|
||||
* "1" - Enable Xinerama
|
||||
*
|
||||
* By default SDL will use Xinerama if it is available.
|
||||
*/
|
||||
#define SDL_HINT_VIDEO_X11_XINERAMA "SDL_VIDEO_X11_XINERAMA"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling whether the X11 XRandR extension should be used.
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - Disable XRandR
|
||||
* "1" - Enable XRandR
|
||||
*
|
||||
* By default SDL will not use XRandR because of window manager issues.
|
||||
*/
|
||||
#define SDL_HINT_VIDEO_X11_XRANDR "SDL_VIDEO_X11_XRANDR"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling whether grabbing input grabs the keyboard
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - Grab will affect only the mouse
|
||||
* "1" - Grab will affect mouse and keyboard
|
||||
*
|
||||
* By default SDL will not grab the keyboard so system shortcuts still work.
|
||||
*/
|
||||
#define SDL_HINT_GRAB_KEYBOARD "SDL_GRAB_KEYBOARD"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling whether relative mouse mode is implemented using mouse warping
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - Relative mouse mode uses raw input
|
||||
* "1" - Relative mouse mode uses mouse warping
|
||||
*
|
||||
* By default SDL will use raw input for relative mouse mode
|
||||
*/
|
||||
#define SDL_HINT_MOUSE_RELATIVE_MODE_WARP "SDL_MOUSE_RELATIVE_MODE_WARP"
|
||||
|
||||
/**
|
||||
* \brief Minimize your SDL_Window if it loses key focus when in fullscreen mode. Defaults to true.
|
||||
*
|
||||
*/
|
||||
#define SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS "SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS"
|
||||
|
||||
/**
|
||||
* \brief Set whether windows go fullscreen in their own spaces on Mac OS X
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - Fullscreen windows will use the classic fullscreen mode
|
||||
* "1" - Fullscreen windows will use fullscreen spaces
|
||||
*
|
||||
* By default SDL will use the classic fullscreen mode.
|
||||
*/
|
||||
#define SDL_HINT_VIDEO_FULLSCREEN_SPACES "SDL_VIDEO_FULLSCREEN_SPACES"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling whether the idle timer is disabled on iOS.
|
||||
*
|
||||
* When an iOS app does not receive touches for some time, the screen is
|
||||
* dimmed automatically. For games where the accelerometer is the only input
|
||||
* this is problematic. This functionality can be disabled by setting this
|
||||
* hint.
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - Enable idle timer
|
||||
* "1" - Disable idle timer
|
||||
*/
|
||||
#define SDL_HINT_IDLE_TIMER_DISABLED "SDL_IOS_IDLE_TIMER_DISABLED"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling which orientations are allowed on iOS.
|
||||
*
|
||||
* In some circumstances it is necessary to be able to explicitly control
|
||||
* which UI orientations are allowed.
|
||||
*
|
||||
* This variable is a space delimited list of the following values:
|
||||
* "LandscapeLeft", "LandscapeRight", "Portrait" "PortraitUpsideDown"
|
||||
*/
|
||||
#define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling whether an Android built-in accelerometer should be
|
||||
* listed as a joystick device, rather than listing actual joysticks only.
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - List only real joysticks and accept input from them
|
||||
* "1" - List real joysticks along with the accelerometer as if it were a 3 axis joystick (the default).
|
||||
*/
|
||||
#define SDL_HINT_ACCEL_AS_JOY "SDL_ACCEL_AS_JOY"
|
||||
|
||||
|
||||
/**
|
||||
* \brief A variable that lets you disable the detection and use of Xinput gamepad devices
|
||||
*
|
||||
* The variable can be set to the following values:
|
||||
* "0" - Disable XInput timer (only uses direct input)
|
||||
* "1" - Enable XInput timer (the default)
|
||||
*/
|
||||
#define SDL_HINT_XINPUT_ENABLED "SDL_XINPUT_ENABLED"
|
||||
|
||||
|
||||
/**
|
||||
* \brief A variable that lets you manually hint extra gamecontroller db entries
|
||||
*
|
||||
* The variable should be newline delimited rows of gamecontroller config data, see SDL_gamecontroller.h
|
||||
*
|
||||
* This hint must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER)
|
||||
* You can update mappings after the system is initialized with SDL_GameControllerMappingForGUID() and SDL_GameControllerAddMapping()
|
||||
*/
|
||||
#define SDL_HINT_GAMECONTROLLERCONFIG "SDL_GAMECONTROLLERCONFIG"
|
||||
|
||||
|
||||
/**
|
||||
* \brief A variable that lets you enable joystick (and gamecontroller) events even when your app is in the background.
|
||||
*
|
||||
* The variable can be set to the following values:
|
||||
* "0" - Disable joystick & gamecontroller input events when the
|
||||
* application is in the background.
|
||||
* "1" - Enable joystick & gamecontroller input events when the
|
||||
* 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"
|
||||
|
||||
|
||||
/**
|
||||
* \brief If set to 0 then never set the top most bit on a SDL Window, even if the video mode expects it.
|
||||
* This is a debugging aid for developers and not expected to be used by end users. The default is "1"
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - don't allow topmost
|
||||
* "1" - 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 If set to 1, then do not allow high-DPI windows. ("Retina" on Mac)
|
||||
*/
|
||||
#define SDL_HINT_VIDEO_HIGHDPI_DISABLED "SDL_VIDEO_HIGHDPI_DISABLED"
|
||||
|
||||
/**
|
||||
* \brief A variable that determines whether ctrl+click should generate a right-click event on Mac
|
||||
*
|
||||
* If present, holding ctrl while left clicking will generate a right click
|
||||
* event when on Mac.
|
||||
*/
|
||||
#define SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK "SDL_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK"
|
||||
|
||||
/**
|
||||
* \brief A variable specifying which shader compiler to preload when using the Chrome ANGLE binaries
|
||||
*
|
||||
* SDL has EGL and OpenGL ES2 support on Windows via the ANGLE project. It
|
||||
* can use two different sets of binaries, those compiled by the user from source
|
||||
* or those provided by the Chrome browser. In the later case, these binaries require
|
||||
* that SDL loads
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "d3dcompiler_46.dll" - default, best for Vista or later.
|
||||
* "d3dcompiler_43.dll" - for XP support.
|
||||
* "none" - do not load any library, useful if you compiled ANGLE from source and included the compiler in your binaries.
|
||||
*
|
||||
*/
|
||||
#define SDL_HINT_VIDEO_WIN_D3DCOMPILER "SDL_VIDEO_WIN_D3DCOMPILER"
|
||||
|
||||
/**
|
||||
* \brief An enumeration of hint priorities
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
SDL_HINT_DEFAULT,
|
||||
SDL_HINT_NORMAL,
|
||||
SDL_HINT_OVERRIDE
|
||||
} SDL_HintPriority;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Set a hint with a specific priority
|
||||
*
|
||||
* The priority controls the behavior when setting a hint that already
|
||||
* has a value. Hints will replace existing hints of their priority and
|
||||
* lower. Environment variables are considered to have override priority.
|
||||
*
|
||||
* \return SDL_TRUE if the hint was set, SDL_FALSE otherwise
|
||||
*/
|
||||
extern DECLSPEC SDL_bool SDLCALL SDL_SetHintWithPriority(const char *name,
|
||||
const char *value,
|
||||
SDL_HintPriority priority);
|
||||
|
||||
/**
|
||||
* \brief Set a hint with normal priority
|
||||
*
|
||||
* \return SDL_TRUE if the hint was set, SDL_FALSE otherwise
|
||||
*/
|
||||
extern DECLSPEC SDL_bool SDLCALL SDL_SetHint(const char *name,
|
||||
const char *value);
|
||||
|
||||
/**
|
||||
* \brief Get a hint
|
||||
*
|
||||
* \return The string value of a hint variable.
|
||||
*/
|
||||
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
|
||||
*
|
||||
* This function is called during SDL_Quit() to free stored hints.
|
||||
*/
|
||||
extern DECLSPEC void SDLCALL SDL_ClearHints(void);
|
||||
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include "close_code.h"
|
||||
|
||||
#endif /* _SDL_hints_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef _SDL_main_h
|
||||
#define _SDL_main_h
|
||||
|
||||
#include "SDL_stdinc.h"
|
||||
|
||||
/**
|
||||
* \file SDL_main.h
|
||||
*
|
||||
* Redefine main() on some platforms so that it is called by SDL.
|
||||
*/
|
||||
|
||||
#ifndef SDL_MAIN_HANDLED
|
||||
#if defined(__WIN32__)
|
||||
/* On Windows SDL provides WinMain(), which parses the command line and passes
|
||||
the arguments to your main function.
|
||||
|
||||
If you provide your own WinMain(), you may define SDL_MAIN_HANDLED
|
||||
*/
|
||||
#define SDL_MAIN_AVAILABLE
|
||||
|
||||
#elif defined(__IPHONEOS__)
|
||||
/* On iOS SDL provides a main function that creates an application delegate
|
||||
and starts the iOS application run loop.
|
||||
|
||||
See src/video/uikit/SDL_uikitappdelegate.m for more details.
|
||||
*/
|
||||
#define SDL_MAIN_NEEDED
|
||||
|
||||
#elif defined(__ANDROID__)
|
||||
/* On Android SDL provides a Java class in SDLActivity.java that is the
|
||||
main activity entry point.
|
||||
|
||||
See README-android.txt for more details on extending that class.
|
||||
*/
|
||||
#define SDL_MAIN_NEEDED
|
||||
|
||||
#endif
|
||||
#endif /* SDL_MAIN_HANDLED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define C_LINKAGE "C"
|
||||
#else
|
||||
#define C_LINKAGE
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* \file SDL_main.h
|
||||
*
|
||||
* The application's main() function must be called with C linkage,
|
||||
* and should be declared like this:
|
||||
* \code
|
||||
* #ifdef __cplusplus
|
||||
* extern "C"
|
||||
* #endif
|
||||
* int main(int argc, char *argv[])
|
||||
* {
|
||||
* }
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
#if defined(SDL_MAIN_NEEDED) || defined(SDL_MAIN_AVAILABLE)
|
||||
#define main SDL_main
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The prototype for the application's main() function
|
||||
*/
|
||||
extern C_LINKAGE int SDL_main(int argc, char *argv[]);
|
||||
|
||||
|
||||
#include "begin_code.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This is called by the real SDL main function to let the rest of the
|
||||
* library know that initialization was done properly.
|
||||
*
|
||||
* Calling this yourself without knowing what you're doing can cause
|
||||
* crashes and hard to diagnose problems with your application.
|
||||
*/
|
||||
extern DECLSPEC void SDLCALL SDL_SetMainReady(void);
|
||||
|
||||
#ifdef __WIN32__
|
||||
|
||||
/**
|
||||
* This can be called to set the application class at startup
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_RegisterApp(char *name, Uint32 style,
|
||||
void *hInst);
|
||||
extern DECLSPEC void SDLCALL SDL_UnregisterApp(void);
|
||||
|
||||
#endif /* __WIN32__ */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include "close_code.h"
|
||||
|
||||
#endif /* _SDL_main_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,11 +0,0 @@
|
||||
|
||||
#ifndef _SDLname_h_
|
||||
#define _SDLname_h_
|
||||
|
||||
#if defined(__STDC__) || defined(__cplusplus)
|
||||
#define NeedFunctionPrototypes 1
|
||||
#endif
|
||||
|
||||
#define SDL_NAME(X) SDL_##X
|
||||
|
||||
#endif /* _SDLname_h_ */
|
||||
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file SDL_system.h
|
||||
*
|
||||
* Include file for platform specific SDL API functions
|
||||
*/
|
||||
|
||||
#ifndef _SDL_system_h
|
||||
#define _SDL_system_h
|
||||
|
||||
#include "SDL_stdinc.h"
|
||||
#include "SDL_keyboard.h"
|
||||
#include "SDL_render.h"
|
||||
#include "SDL_video.h"
|
||||
|
||||
#include "begin_code.h"
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Platform specific functions for Windows */
|
||||
#ifdef __WIN32__
|
||||
|
||||
/* Returns the D3D9 adapter index that matches the specified display index.
|
||||
This adapter index can be passed to IDirect3D9::CreateDevice and controls
|
||||
on which monitor a full screen application will appear.
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_Direct3D9GetAdapterIndex( int displayIndex );
|
||||
|
||||
/* Returns the D3D device associated with a renderer, or NULL if it's not a D3D renderer.
|
||||
Once you are done using the device, you should release it to avoid a resource leak.
|
||||
*/
|
||||
typedef struct IDirect3DDevice9 IDirect3DDevice9;
|
||||
extern DECLSPEC IDirect3DDevice9* SDLCALL SDL_RenderGetD3D9Device(SDL_Renderer * renderer);
|
||||
|
||||
#endif /* __WIN32__ */
|
||||
|
||||
|
||||
/* Platform specific functions for iOS */
|
||||
#if defined(__IPHONEOS__) && __IPHONEOS__
|
||||
|
||||
extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam);
|
||||
extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled);
|
||||
|
||||
#endif /* __IPHONEOS__ */
|
||||
|
||||
|
||||
/* Platform specific functions for Android */
|
||||
#if defined(__ANDROID__) && __ANDROID__
|
||||
|
||||
/* Get the JNI environment for the current thread
|
||||
This returns JNIEnv*, but the prototype is void* so we don't need jni.h
|
||||
*/
|
||||
extern DECLSPEC void * SDLCALL SDL_AndroidGetJNIEnv();
|
||||
|
||||
/* Get the SDL Activity object for the application
|
||||
This returns jobject, but the prototype is void* so we don't need jni.h
|
||||
The jobject returned by SDL_AndroidGetActivity is a local reference.
|
||||
It is the caller's responsibility to properly release it
|
||||
(using env->Push/PopLocalFrame or manually with env->DeleteLocalRef)
|
||||
*/
|
||||
extern DECLSPEC void * SDLCALL SDL_AndroidGetActivity();
|
||||
|
||||
/* See the official Android developer guide for more information:
|
||||
http://developer.android.com/guide/topics/data/data-storage.html
|
||||
*/
|
||||
#define SDL_ANDROID_EXTERNAL_STORAGE_READ 0x01
|
||||
#define SDL_ANDROID_EXTERNAL_STORAGE_WRITE 0x02
|
||||
|
||||
/* Get the path used for internal storage for this application.
|
||||
This path is unique to your application and cannot be written to
|
||||
by other applications.
|
||||
*/
|
||||
extern DECLSPEC const char * SDLCALL SDL_AndroidGetInternalStoragePath();
|
||||
|
||||
/* Get the current state of external storage, a bitmask of these values:
|
||||
SDL_ANDROID_EXTERNAL_STORAGE_READ
|
||||
SDL_ANDROID_EXTERNAL_STORAGE_WRITE
|
||||
If external storage is currently unavailable, this will return 0.
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_AndroidGetExternalStorageState();
|
||||
|
||||
/* Get the path used for external storage for this application.
|
||||
This path is unique to your application, but is public and can be
|
||||
written to by other applications.
|
||||
*/
|
||||
extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath();
|
||||
|
||||
#endif /* __ANDROID__ */
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include "close_code.h"
|
||||
|
||||
#endif /* _SDL_system_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file SDL_test_font.h
|
||||
*
|
||||
* Include file for SDL test framework.
|
||||
*
|
||||
* This code is a part of the SDL2_test library, not the main SDL library.
|
||||
*/
|
||||
|
||||
#ifndef _SDL_test_font_h
|
||||
#define _SDL_test_font_h
|
||||
|
||||
#include "begin_code.h"
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Function prototypes */
|
||||
|
||||
/**
|
||||
* \brief Draw a string in the currently set font.
|
||||
*
|
||||
* \param renderer The renderer to draw on.
|
||||
* \param x The X coordinate of the upper left corner of the string.
|
||||
* \param y The Y coordinate of the upper left corner of the string.
|
||||
* \param s The string to draw.
|
||||
*
|
||||
* \returns Returns 0 on success, -1 on failure.
|
||||
*/
|
||||
int SDLTest_DrawString(SDL_Renderer * renderer, int x, int y, const char *s);
|
||||
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include "close_code.h"
|
||||
|
||||
#endif /* _SDL_test_font_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,81 +0,0 @@
|
||||
|
||||
#ifndef _directx_h
|
||||
#define _directx_h
|
||||
|
||||
/* Include all of the DirectX 8.0 headers and adds any necessary tweaks */
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#include <mmsystem.h>
|
||||
#ifndef WIN32
|
||||
#define WIN32
|
||||
#endif
|
||||
#undef WINNT
|
||||
|
||||
/* Far pointers don't exist in 32-bit code */
|
||||
#ifndef FAR
|
||||
#define FAR
|
||||
#endif
|
||||
|
||||
/* Error codes not yet included in Win32 API header files */
|
||||
#ifndef MAKE_HRESULT
|
||||
#define MAKE_HRESULT(sev,fac,code) \
|
||||
((HRESULT)(((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))))
|
||||
#endif
|
||||
|
||||
#ifndef S_OK
|
||||
#define S_OK (HRESULT)0x00000000L
|
||||
#endif
|
||||
|
||||
#ifndef SUCCEEDED
|
||||
#define SUCCEEDED(x) ((HRESULT)(x) >= 0)
|
||||
#endif
|
||||
#ifndef FAILED
|
||||
#define FAILED(x) ((HRESULT)(x)<0)
|
||||
#endif
|
||||
|
||||
#ifndef E_FAIL
|
||||
#define E_FAIL (HRESULT)0x80000008L
|
||||
#endif
|
||||
#ifndef E_NOINTERFACE
|
||||
#define E_NOINTERFACE (HRESULT)0x80004002L
|
||||
#endif
|
||||
#ifndef E_OUTOFMEMORY
|
||||
#define E_OUTOFMEMORY (HRESULT)0x8007000EL
|
||||
#endif
|
||||
#ifndef E_INVALIDARG
|
||||
#define E_INVALIDARG (HRESULT)0x80070057L
|
||||
#endif
|
||||
#ifndef E_NOTIMPL
|
||||
#define E_NOTIMPL (HRESULT)0x80004001L
|
||||
#endif
|
||||
#ifndef REGDB_E_CLASSNOTREG
|
||||
#define REGDB_E_CLASSNOTREG (HRESULT)0x80040154L
|
||||
#endif
|
||||
|
||||
/* Severity codes */
|
||||
#ifndef SEVERITY_ERROR
|
||||
#define SEVERITY_ERROR 1
|
||||
#endif
|
||||
|
||||
/* Error facility codes */
|
||||
#ifndef FACILITY_WIN32
|
||||
#define FACILITY_WIN32 7
|
||||
#endif
|
||||
|
||||
#ifndef FIELD_OFFSET
|
||||
#define FIELD_OFFSET(type, field) ((LONG)&(((type *)0)->field))
|
||||
#endif
|
||||
|
||||
/* DirectX headers (if it isn't included, I haven't tested it yet)
|
||||
*/
|
||||
/* We need these defines to mark what version of DirectX API we use */
|
||||
#define DIRECTDRAW_VERSION 0x0700
|
||||
#define DIRECTSOUND_VERSION 0x0800
|
||||
#define DIRECTINPUT_VERSION 0x0500
|
||||
|
||||
#include <ddraw.h>
|
||||
#include <dsound.h>
|
||||
#include <dinput.h>
|
||||
|
||||
#endif /* _directx_h */
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifdef __WIN32__
|
||||
|
||||
#include "SDL_windows.h"
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_assert.h"
|
||||
|
||||
#include <objbase.h> /* for CoInitialize/CoUninitialize */
|
||||
|
||||
/* Sets an error message based on GetLastError() */
|
||||
int
|
||||
WIN_SetError(const char *prefix)
|
||||
{
|
||||
TCHAR buffer[1024];
|
||||
char *message;
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,
|
||||
buffer, SDL_arraysize(buffer), NULL);
|
||||
message = WIN_StringToUTF8(buffer);
|
||||
SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ": " : "", message);
|
||||
SDL_free(message);
|
||||
return -1;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WIN_CoInitialize(void)
|
||||
{
|
||||
/* SDL handles any threading model, so initialize with the default, which
|
||||
is compatible with OLE and if that doesn't work, try multi-threaded mode.
|
||||
|
||||
If you need multi-threaded mode, call CoInitializeEx() before SDL_Init()
|
||||
*/
|
||||
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
if (hr == RPC_E_CHANGED_MODE) {
|
||||
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
}
|
||||
|
||||
/* S_FALSE means success, but someone else already initialized. */
|
||||
/* You still need to call CoUninitialize in this case! */
|
||||
if (hr == S_FALSE) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
void
|
||||
WIN_CoUninitialize(void)
|
||||
{
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
#endif /* __WIN32__ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/* This is an include file for windows.h with the SDL build settings */
|
||||
|
||||
#ifndef _INCLUDED_WINDOWS_H
|
||||
#define _INCLUDED_WINDOWS_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define STRICT
|
||||
#ifndef UNICODE
|
||||
#define UNICODE 1
|
||||
#endif
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x501 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices(), 0x501 for raw input */
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/* Routines to convert from UTF8 to native Windows text */
|
||||
#if UNICODE
|
||||
#define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "UTF-16LE", (char *)(S), (SDL_wcslen(S)+1)*sizeof(WCHAR))
|
||||
#define WIN_UTF8ToString(S) (WCHAR *)SDL_iconv_string("UTF-16LE", "UTF-8", (char *)(S), SDL_strlen(S)+1)
|
||||
#else
|
||||
/* !!! FIXME: UTF8ToString() can just be a SDL_strdup() here. */
|
||||
#define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "ASCII", (char *)(S), (SDL_strlen(S)+1))
|
||||
#define WIN_UTF8ToString(S) SDL_iconv_string("ASCII", "UTF-8", (char *)(S), SDL_strlen(S)+1)
|
||||
#endif
|
||||
|
||||
/* Sets an error message based on GetLastError(). Always return -1. */
|
||||
extern int WIN_SetError(const char *prefix);
|
||||
|
||||
/* Wrap up the oddities of CoInitialize() into a common function. */
|
||||
extern HRESULT WIN_CoInitialize(void);
|
||||
extern void WIN_CoUninitialize(void);
|
||||
|
||||
#endif /* _INCLUDED_WINDOWS_H */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,9 +0,0 @@
|
||||
#ifdef __APPLE__
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef SDL_rwopsbundlesupport_h
|
||||
#define SDL_rwopsbundlesupport_h
|
||||
FILE* SDL_OpenFPFromBundleOrFallback(const char *file, const char *mode);
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,45 +0,0 @@
|
||||
#ifdef __APPLE__
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include "SDL_rwopsbundlesupport.h"
|
||||
|
||||
/* For proper OS X applications, the resources are contained inside the application bundle.
|
||||
So the strategy is to first check the application bundle for the file, then fallback to the current working directory.
|
||||
Note: One additional corner-case is if the resource is in a framework's resource bundle instead of the app.
|
||||
We might want to use bundle identifiers, e.g. org.libsdl.sdl to get the bundle for the framework,
|
||||
but we would somehow need to know what the bundle identifiers we need to search are.
|
||||
Also, note the bundle layouts are different for iPhone and Mac.
|
||||
*/
|
||||
FILE* SDL_OpenFPFromBundleOrFallback(const char *file, const char *mode)
|
||||
{
|
||||
FILE* fp = NULL;
|
||||
|
||||
/* If the file mode is writable, skip all the bundle stuff because generally the bundle is read-only. */
|
||||
if(strcmp("r", mode) && strcmp("rb", mode))
|
||||
{
|
||||
return fopen(file, mode);
|
||||
}
|
||||
|
||||
NSAutoreleasePool* autorelease_pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
|
||||
NSFileManager* file_manager = [NSFileManager defaultManager];
|
||||
NSString* resource_path = [[NSBundle mainBundle] resourcePath];
|
||||
|
||||
NSString* ns_string_file_component = [file_manager stringWithFileSystemRepresentation:file length:strlen(file)];
|
||||
|
||||
NSString* full_path_with_file_to_try = [resource_path stringByAppendingPathComponent:ns_string_file_component];
|
||||
if([file_manager fileExistsAtPath:full_path_with_file_to_try])
|
||||
{
|
||||
fp = fopen([full_path_with_file_to_try fileSystemRepresentation], mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
fp = fopen(file, mode);
|
||||
}
|
||||
|
||||
[autorelease_pool drain];
|
||||
|
||||
return fp;
|
||||
}
|
||||
#endif
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifdef SDL_FILESYSTEM_DUMMY
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
/* System dependent filesystem routines */
|
||||
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_filesystem.h"
|
||||
|
||||
char *
|
||||
SDL_GetBasePath(void)
|
||||
{
|
||||
SDL_Unsupported();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *
|
||||
SDL_GetPrefPath(const char *org, const char *app)
|
||||
{
|
||||
SDL_Unsupported();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* SDL_FILESYSTEM_DUMMY */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,210 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifdef SDL_FILESYSTEM_UNIX
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
/* System dependent filesystem routines */
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef __FREEBSD__
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_stdinc.h"
|
||||
#include "SDL_filesystem.h"
|
||||
|
||||
static char *
|
||||
readSymLink(const char *path)
|
||||
{
|
||||
char *retval = NULL;
|
||||
ssize_t len = 64;
|
||||
ssize_t rc = -1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
char *ptr = (char *) SDL_realloc(retval, (size_t) len);
|
||||
if (ptr == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
break;
|
||||
}
|
||||
|
||||
retval = ptr;
|
||||
|
||||
rc = readlink(path, retval, len);
|
||||
if (rc == -1) {
|
||||
break; /* not a symlink, i/o error, etc. */
|
||||
} else if (rc < len) {
|
||||
retval[rc] = '\0'; /* readlink doesn't null-terminate. */
|
||||
return retval; /* we're good to go. */
|
||||
}
|
||||
|
||||
len *= 2; /* grow buffer, try again. */
|
||||
}
|
||||
|
||||
SDL_free(retval);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
SDL_GetBasePath(void)
|
||||
{
|
||||
char *retval = NULL;
|
||||
|
||||
#if defined(__FREEBSD__)
|
||||
char fullpath[PATH_MAX];
|
||||
size_t buflen = sizeof (fullpath);
|
||||
const int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
|
||||
if (sysctl(mib, SDL_arraysize(mib), fullpath, &buflen, NULL, 0) != -1) {
|
||||
retval = SDL_strdup(fullpath);
|
||||
if (!retval) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#elif defined(__SOLARIS__)
|
||||
const char *path = getexecname();
|
||||
if ((path != NULL) && (path[0] == '/')) { /* must be absolute path... */
|
||||
retval = SDL_strdup(path);
|
||||
if (!retval) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* is a Linux-style /proc filesystem available? */
|
||||
if (!retval && (access("/proc", F_OK) == 0)) {
|
||||
#if defined(__FREEBSD__)
|
||||
retval = readSymLink("/proc/curproc/file");
|
||||
#elif defined(__NETBSD__)
|
||||
retval = readSymLink("/proc/curproc/exe");
|
||||
#else
|
||||
retval = readSymLink("/proc/self/exe"); /* linux. */
|
||||
#endif
|
||||
if (retval == NULL) {
|
||||
/* older kernels don't have /proc/self ... try PID version... */
|
||||
char path[64];
|
||||
const int rc = (int) SDL_snprintf(path, sizeof(path),
|
||||
"/proc/%llu/exe",
|
||||
(unsigned long long) getpid());
|
||||
if ( (rc > 0) && (rc < sizeof(path)) ) {
|
||||
retval = readSymLink(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If we had access to argv[0] here, we could check it for a path,
|
||||
or troll through $PATH looking for it, too. */
|
||||
|
||||
if (retval != NULL) { /* chop off filename. */
|
||||
char *ptr = SDL_strrchr(retval, '/');
|
||||
if (ptr != NULL) {
|
||||
*(ptr+1) = '\0';
|
||||
} else { /* shouldn't happen, but just in case... */
|
||||
SDL_free(retval);
|
||||
retval = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (retval != NULL) {
|
||||
/* try to shrink buffer... */
|
||||
char *ptr = (char *) SDL_realloc(retval, strlen(retval) + 1);
|
||||
if (ptr != NULL)
|
||||
retval = ptr; /* oh well if it failed. */
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
char *
|
||||
SDL_GetPrefPath(const char *org, const char *app)
|
||||
{
|
||||
/*
|
||||
* We use XDG's base directory spec, even if you're not on Linux.
|
||||
* This isn't strictly correct, but the results are relatively sane
|
||||
* in any case.
|
||||
*
|
||||
* http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
|
||||
*/
|
||||
const char *envr = SDL_getenv("XDG_DATA_HOME");
|
||||
const char *append;
|
||||
char *retval = NULL;
|
||||
char *ptr = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
if (!envr) {
|
||||
/* You end up with "$HOME/.local/share/Game Name 2" */
|
||||
envr = SDL_getenv("HOME");
|
||||
if (!envr) {
|
||||
/* we could take heroic measures with /etc/passwd, but oh well. */
|
||||
SDL_SetError("neither XDG_DATA_HOME nor HOME environment is set");
|
||||
return NULL;
|
||||
}
|
||||
append = "/.local/share/";
|
||||
} else {
|
||||
append = "/";
|
||||
}
|
||||
|
||||
len = SDL_strlen(envr);
|
||||
if (envr[len - 1] == '/')
|
||||
append += 1;
|
||||
|
||||
len += SDL_strlen(append) + SDL_strlen(org) + SDL_strlen(app) + 3;
|
||||
retval = (char *) SDL_malloc(len);
|
||||
if (!retval) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SDL_snprintf(retval, len, "%s%s%s/%s/", envr, append, org, app);
|
||||
|
||||
for (ptr = retval+1; *ptr; ptr++) {
|
||||
if (*ptr == '/') {
|
||||
*ptr = '\0';
|
||||
if (mkdir(retval, 0700) != 0 && errno != EEXIST)
|
||||
goto error;
|
||||
*ptr = '/';
|
||||
}
|
||||
}
|
||||
if (mkdir(retval, 0700) != 0 && errno != EEXIST) {
|
||||
error:
|
||||
SDL_SetError("Couldn't create directory '%s': ", retval, strerror(errno));
|
||||
SDL_free(retval);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif /* SDL_FILESYSTEM_UNIX */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifdef SDL_FILESYSTEM_WINDOWS
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
/* System dependent filesystem routines */
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#include <shlobj.h>
|
||||
|
||||
#include "SDL_assert.h"
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_stdinc.h"
|
||||
#include "SDL_filesystem.h"
|
||||
|
||||
char *
|
||||
SDL_GetBasePath(void)
|
||||
{
|
||||
TCHAR path[MAX_PATH];
|
||||
const DWORD len = GetModuleFileName(NULL, path, SDL_arraysize(path));
|
||||
size_t i;
|
||||
|
||||
SDL_assert(len < SDL_arraysize(path));
|
||||
|
||||
if (len == 0) {
|
||||
WIN_SetError("Couldn't locate our .exe");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = len-1; i > 0; i--) {
|
||||
if (path[i] == '\\') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_assert(i > 0); /* Should have been an absolute path. */
|
||||
path[i+1] = '\0'; /* chop off filename. */
|
||||
return WIN_StringToUTF8(path);
|
||||
}
|
||||
|
||||
char *
|
||||
SDL_GetPrefPath(const char *org, const char *app)
|
||||
{
|
||||
/*
|
||||
* Vista and later has a new API for this, but SHGetFolderPath works there,
|
||||
* and apparently just wraps the new API. This is the new way to do it:
|
||||
*
|
||||
* SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_CREATE,
|
||||
* NULL, &wszPath);
|
||||
*/
|
||||
|
||||
TCHAR path[MAX_PATH];
|
||||
char *utf8 = NULL;
|
||||
char *retval = NULL;
|
||||
|
||||
if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path))) {
|
||||
WIN_SetError("Couldn't locate our prefpath");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
utf8 = WIN_StringToUTF8(path);
|
||||
if (utf8) {
|
||||
const size_t len = SDL_strlen(utf8) + SDL_strlen(org) + SDL_strlen(app) + 4;
|
||||
retval = (char *) SDL_malloc(len);
|
||||
if (!retval) {
|
||||
SDL_free(utf8);
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
SDL_snprintf(retval, len, "%s\\%s\\%s\\", utf8, org, app);
|
||||
SDL_free(utf8);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif /* SDL_FILESYSTEM_WINDOWS */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,179 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#if defined(SDL_HAPTIC_DUMMY) || defined(SDL_HAPTIC_DISABLED)
|
||||
|
||||
#include "SDL_haptic.h"
|
||||
#include "../SDL_syshaptic.h"
|
||||
|
||||
|
||||
static int
|
||||
SDL_SYS_LogicError(void)
|
||||
{
|
||||
return SDL_SetError("Logic error: No haptic devices available.");
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SDL_SYS_HapticInit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
SDL_SYS_HapticName(int index)
|
||||
{
|
||||
SDL_SYS_LogicError();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SDL_SYS_HapticOpen(SDL_Haptic * haptic)
|
||||
{
|
||||
return SDL_SYS_LogicError();
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
return SDL_SYS_LogicError();
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
return SDL_SYS_LogicError();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic,
|
||||
struct haptic_effect *effect,
|
||||
SDL_HapticEffect * data)
|
||||
{
|
||||
return SDL_SYS_LogicError();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
|
||||
Uint32 iterations)
|
||||
{
|
||||
return SDL_SYS_LogicError();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
|
||||
{
|
||||
return SDL_SYS_LogicError();
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
return SDL_SYS_LogicError();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain)
|
||||
{
|
||||
return SDL_SYS_LogicError();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
|
||||
{
|
||||
return SDL_SYS_LogicError();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SYS_HapticPause(SDL_Haptic * haptic)
|
||||
{
|
||||
return SDL_SYS_LogicError();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SYS_HapticUnpause(SDL_Haptic * haptic)
|
||||
{
|
||||
return SDL_SYS_LogicError();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SYS_HapticStopAll(SDL_Haptic * haptic)
|
||||
{
|
||||
return SDL_SYS_LogicError();
|
||||
}
|
||||
|
||||
#endif /* SDL_HAPTIC_DUMMY || SDL_HAPTIC_DISABLED */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,563 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifdef SDL_JOYSTICK_ANDROID
|
||||
|
||||
#include <stdio.h> /* For the definition of NULL */
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_events.h"
|
||||
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
#include "../../events/SDL_events_c.h"
|
||||
#endif
|
||||
|
||||
#include "SDL_joystick.h"
|
||||
#include "SDL_hints.h"
|
||||
#include "SDL_assert.h"
|
||||
#include "SDL_timer.h"
|
||||
#include "SDL_log.h"
|
||||
#include "SDL_sysjoystick_c.h"
|
||||
#include "../SDL_joystick_c.h"
|
||||
#include "../../core/android/SDL_android.h"
|
||||
|
||||
#include "android/keycodes.h"
|
||||
|
||||
/* As of platform android-14, android/keycodes.h is missing these defines */
|
||||
#ifndef AKEYCODE_BUTTON_1
|
||||
#define AKEYCODE_BUTTON_1 188
|
||||
#define AKEYCODE_BUTTON_2 189
|
||||
#define AKEYCODE_BUTTON_3 190
|
||||
#define AKEYCODE_BUTTON_4 191
|
||||
#define AKEYCODE_BUTTON_5 192
|
||||
#define AKEYCODE_BUTTON_6 193
|
||||
#define AKEYCODE_BUTTON_7 194
|
||||
#define AKEYCODE_BUTTON_8 195
|
||||
#define AKEYCODE_BUTTON_9 196
|
||||
#define AKEYCODE_BUTTON_10 197
|
||||
#define AKEYCODE_BUTTON_11 198
|
||||
#define AKEYCODE_BUTTON_12 199
|
||||
#define AKEYCODE_BUTTON_13 200
|
||||
#define AKEYCODE_BUTTON_14 201
|
||||
#define AKEYCODE_BUTTON_15 202
|
||||
#define AKEYCODE_BUTTON_16 203
|
||||
#endif
|
||||
|
||||
#define ANDROID_ACCELEROMETER_NAME "Android Accelerometer"
|
||||
#define ANDROID_ACCELEROMETER_DEVICE_ID INT_MIN
|
||||
#define ANDROID_MAX_NBUTTONS 36
|
||||
|
||||
static SDL_joylist_item * JoystickByDeviceId(int device_id);
|
||||
|
||||
static SDL_joylist_item *SDL_joylist = NULL;
|
||||
static SDL_joylist_item *SDL_joylist_tail = NULL;
|
||||
static int numjoysticks = 0;
|
||||
static int instance_counter = 0;
|
||||
|
||||
|
||||
/* Function to convert Android keyCodes into SDL ones.
|
||||
* This code manipulation is done to get a sequential list of codes.
|
||||
* FIXME: This is only suited for the case where we use a fixed number of buttons determined by ANDROID_MAX_NBUTTONS
|
||||
*/
|
||||
static int
|
||||
keycode_to_SDL(int keycode)
|
||||
{
|
||||
/* FIXME: If this function gets too unwiedly in the future, replace with a lookup table */
|
||||
int button = 0;
|
||||
switch(keycode)
|
||||
{
|
||||
/* Some gamepad buttons (API 9) */
|
||||
case AKEYCODE_BUTTON_A:
|
||||
button = SDL_CONTROLLER_BUTTON_A;
|
||||
break;
|
||||
case AKEYCODE_BUTTON_B:
|
||||
button = SDL_CONTROLLER_BUTTON_B;
|
||||
break;
|
||||
case AKEYCODE_BUTTON_X:
|
||||
button = SDL_CONTROLLER_BUTTON_X;
|
||||
break;
|
||||
case AKEYCODE_BUTTON_Y:
|
||||
button = SDL_CONTROLLER_BUTTON_Y;
|
||||
break;
|
||||
case AKEYCODE_BUTTON_L1:
|
||||
button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER;
|
||||
break;
|
||||
case AKEYCODE_BUTTON_R1:
|
||||
button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
|
||||
break;
|
||||
case AKEYCODE_BUTTON_THUMBL:
|
||||
button = SDL_CONTROLLER_BUTTON_LEFTSTICK;
|
||||
break;
|
||||
case AKEYCODE_BUTTON_THUMBR:
|
||||
button = SDL_CONTROLLER_BUTTON_RIGHTSTICK;
|
||||
break;
|
||||
case AKEYCODE_BUTTON_START:
|
||||
button = SDL_CONTROLLER_BUTTON_START;
|
||||
break;
|
||||
case AKEYCODE_BUTTON_SELECT:
|
||||
button = SDL_CONTROLLER_BUTTON_BACK;
|
||||
break;
|
||||
case AKEYCODE_BUTTON_MODE:
|
||||
button = SDL_CONTROLLER_BUTTON_GUIDE;
|
||||
break;
|
||||
case AKEYCODE_BUTTON_L2:
|
||||
button = SDL_CONTROLLER_BUTTON_MAX; /* Not supported by GameController */
|
||||
break;
|
||||
case AKEYCODE_BUTTON_R2:
|
||||
button = SDL_CONTROLLER_BUTTON_MAX+1; /* Not supported by GameController */
|
||||
break;
|
||||
case AKEYCODE_BUTTON_C:
|
||||
button = SDL_CONTROLLER_BUTTON_MAX+2; /* Not supported by GameController */
|
||||
break;
|
||||
case AKEYCODE_BUTTON_Z:
|
||||
button = SDL_CONTROLLER_BUTTON_MAX+3; /* Not supported by GameController */
|
||||
break;
|
||||
|
||||
/* D-Pad key codes (API 1) */
|
||||
case AKEYCODE_DPAD_UP:
|
||||
button = SDL_CONTROLLER_BUTTON_DPAD_UP;
|
||||
break;
|
||||
case AKEYCODE_DPAD_DOWN:
|
||||
button = SDL_CONTROLLER_BUTTON_DPAD_DOWN;
|
||||
break;
|
||||
case AKEYCODE_DPAD_LEFT:
|
||||
button = SDL_CONTROLLER_BUTTON_DPAD_LEFT;
|
||||
break;
|
||||
case AKEYCODE_DPAD_RIGHT:
|
||||
button = SDL_CONTROLLER_BUTTON_DPAD_RIGHT;
|
||||
break;
|
||||
case AKEYCODE_DPAD_CENTER:
|
||||
button = SDL_CONTROLLER_BUTTON_MAX+4; /* Not supported by GameController */
|
||||
break;
|
||||
|
||||
/* More gamepad buttons (API 12), these get mapped to 20...35*/
|
||||
case AKEYCODE_BUTTON_1:
|
||||
case AKEYCODE_BUTTON_2:
|
||||
case AKEYCODE_BUTTON_3:
|
||||
case AKEYCODE_BUTTON_4:
|
||||
case AKEYCODE_BUTTON_5:
|
||||
case AKEYCODE_BUTTON_6:
|
||||
case AKEYCODE_BUTTON_7:
|
||||
case AKEYCODE_BUTTON_8:
|
||||
case AKEYCODE_BUTTON_9:
|
||||
case AKEYCODE_BUTTON_10:
|
||||
case AKEYCODE_BUTTON_11:
|
||||
case AKEYCODE_BUTTON_12:
|
||||
case AKEYCODE_BUTTON_13:
|
||||
case AKEYCODE_BUTTON_14:
|
||||
case AKEYCODE_BUTTON_15:
|
||||
case AKEYCODE_BUTTON_16:
|
||||
button = keycode - AKEYCODE_BUTTON_1 + SDL_CONTROLLER_BUTTON_MAX + 5;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* This is here in case future generations, probably with six fingers per hand,
|
||||
* happily add new cases up above and forget to update the max number of buttons.
|
||||
*/
|
||||
SDL_assert(button < ANDROID_MAX_NBUTTONS);
|
||||
return button;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
Android_OnPadDown(int device_id, int keycode)
|
||||
{
|
||||
SDL_joylist_item *item;
|
||||
int button = keycode_to_SDL(keycode);
|
||||
if (button >= 0) {
|
||||
item = JoystickByDeviceId(device_id);
|
||||
if (item && item->joystick) {
|
||||
SDL_PrivateJoystickButton(item->joystick, button , SDL_PRESSED);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
Android_OnPadUp(int device_id, int keycode)
|
||||
{
|
||||
SDL_joylist_item *item;
|
||||
int button = keycode_to_SDL(keycode);
|
||||
if (button >= 0) {
|
||||
item = JoystickByDeviceId(device_id);
|
||||
if (item && item->joystick) {
|
||||
SDL_PrivateJoystickButton(item->joystick, button, SDL_RELEASED);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
Android_OnJoy(int device_id, int axis, float value)
|
||||
{
|
||||
/* Android gives joy info normalized as [-1.0, 1.0] or [0.0, 1.0] */
|
||||
SDL_joylist_item *item = JoystickByDeviceId(device_id);
|
||||
if (item && item->joystick) {
|
||||
SDL_PrivateJoystickAxis(item->joystick, axis, (Sint16) (32767.*value) );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Android_AddJoystick(int device_id, const char *name, SDL_bool is_accelerometer, int nbuttons, int naxes, int nhats, int nballs)
|
||||
{
|
||||
SDL_JoystickGUID guid;
|
||||
SDL_joylist_item *item;
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
SDL_Event event;
|
||||
#endif
|
||||
|
||||
if(JoystickByDeviceId(device_id) != NULL || name == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* the GUID is just the first 16 chars of the name for now */
|
||||
SDL_zero( guid );
|
||||
SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
|
||||
|
||||
item = (SDL_joylist_item *) SDL_malloc(sizeof (SDL_joylist_item));
|
||||
if (item == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_zerop(item);
|
||||
item->guid = guid;
|
||||
item->device_id = device_id;
|
||||
item->name = SDL_strdup(name);
|
||||
if ( item->name == NULL ) {
|
||||
SDL_free(item);
|
||||
return -1;
|
||||
}
|
||||
|
||||
item->is_accelerometer = is_accelerometer;
|
||||
if (nbuttons > -1) {
|
||||
item->nbuttons = nbuttons;
|
||||
}
|
||||
else {
|
||||
item->nbuttons = ANDROID_MAX_NBUTTONS;
|
||||
}
|
||||
item->naxes = naxes;
|
||||
item->nhats = nhats;
|
||||
item->nballs = nballs;
|
||||
item->device_instance = instance_counter++;
|
||||
if (SDL_joylist_tail == NULL) {
|
||||
SDL_joylist = SDL_joylist_tail = item;
|
||||
} else {
|
||||
SDL_joylist_tail->next = item;
|
||||
SDL_joylist_tail = item;
|
||||
}
|
||||
|
||||
/* Need to increment the joystick count before we post the event */
|
||||
++numjoysticks;
|
||||
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
event.type = SDL_JOYDEVICEADDED;
|
||||
|
||||
if (SDL_GetEventState(event.type) == SDL_ENABLE) {
|
||||
event.jdevice.which = (numjoysticks - 1);
|
||||
if ( (SDL_EventOK == NULL) ||
|
||||
(*SDL_EventOK) (SDL_EventOKParam, &event) ) {
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
#endif /* !SDL_EVENTS_DISABLED */
|
||||
|
||||
SDL_Log("Added joystick %s with device_id %d", name, device_id);
|
||||
|
||||
return numjoysticks;
|
||||
}
|
||||
|
||||
int
|
||||
Android_RemoveJoystick(int device_id)
|
||||
{
|
||||
SDL_joylist_item *item = SDL_joylist;
|
||||
SDL_joylist_item *prev = NULL;
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
SDL_Event event;
|
||||
#endif
|
||||
|
||||
/* Don't call JoystickByDeviceId here or there'll be an infinite loop! */
|
||||
while (item != NULL) {
|
||||
if (item->device_id == device_id) {
|
||||
break;
|
||||
}
|
||||
prev = item;
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
if (item == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const int retval = item->device_instance;
|
||||
if (item->joystick) {
|
||||
item->joystick->hwdata = NULL;
|
||||
}
|
||||
|
||||
if (prev != NULL) {
|
||||
prev->next = item->next;
|
||||
} else {
|
||||
SDL_assert(SDL_joylist == item);
|
||||
SDL_joylist = item->next;
|
||||
}
|
||||
if (item == SDL_joylist_tail) {
|
||||
SDL_joylist_tail = prev;
|
||||
}
|
||||
|
||||
/* Need to decrement the joystick count before we post the event */
|
||||
--numjoysticks;
|
||||
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
event.type = SDL_JOYDEVICEREMOVED;
|
||||
|
||||
if (SDL_GetEventState(event.type) == SDL_ENABLE) {
|
||||
event.jdevice.which = item->device_instance;
|
||||
if ( (SDL_EventOK == NULL) ||
|
||||
(*SDL_EventOK) (SDL_EventOKParam, &event) ) {
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
#endif /* !SDL_EVENTS_DISABLED */
|
||||
|
||||
SDL_Log("Removed joystick with device_id %d", device_id);
|
||||
|
||||
SDL_free(item->name);
|
||||
SDL_free(item);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SDL_SYS_JoystickInit(void)
|
||||
{
|
||||
const char *env;
|
||||
SDL_SYS_JoystickDetect();
|
||||
|
||||
env = SDL_GetHint(SDL_HINT_ACCEL_AS_JOY);
|
||||
if (!env || SDL_atoi(env)) {
|
||||
/* Default behavior, accelerometer as joystick */
|
||||
Android_AddJoystick(ANDROID_ACCELEROMETER_DEVICE_ID, ANDROID_ACCELEROMETER_NAME, SDL_TRUE, 0, 3, 0, 0);
|
||||
}
|
||||
|
||||
return (numjoysticks);
|
||||
|
||||
}
|
||||
|
||||
int SDL_SYS_NumJoysticks()
|
||||
{
|
||||
return numjoysticks;
|
||||
}
|
||||
|
||||
void SDL_SYS_JoystickDetect()
|
||||
{
|
||||
/* Support for device connect/disconnect is API >= 16 only,
|
||||
* so we poll every three seconds
|
||||
* Ref: http://developer.android.com/reference/android/hardware/input/InputManager.InputDeviceListener.html
|
||||
*/
|
||||
static Uint32 timeout = 0;
|
||||
if (SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) {
|
||||
timeout = SDL_GetTicks() + 3000;
|
||||
Android_JNI_PollInputDevices();
|
||||
}
|
||||
}
|
||||
|
||||
SDL_bool SDL_SYS_JoystickNeedsPolling()
|
||||
{
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static SDL_joylist_item *
|
||||
JoystickByDevIndex(int device_index)
|
||||
{
|
||||
SDL_joylist_item *item = SDL_joylist;
|
||||
|
||||
if ((device_index < 0) || (device_index >= numjoysticks)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (device_index > 0) {
|
||||
SDL_assert(item != NULL);
|
||||
device_index--;
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
static SDL_joylist_item *
|
||||
JoystickByDeviceId(int device_id)
|
||||
{
|
||||
SDL_joylist_item *item = SDL_joylist;
|
||||
|
||||
while (item != NULL) {
|
||||
if (item->device_id == device_id) {
|
||||
return item;
|
||||
}
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
/* Joystick not found, try adding it */
|
||||
SDL_SYS_JoystickDetect();
|
||||
|
||||
while (item != NULL) {
|
||||
if (item->device_id == device_id) {
|
||||
return item;
|
||||
}
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Function to get the device-dependent name of a joystick */
|
||||
const char *
|
||||
SDL_SYS_JoystickNameForDeviceIndex(int device_index)
|
||||
{
|
||||
return JoystickByDevIndex(device_index)->name;
|
||||
}
|
||||
|
||||
/* Function to perform the mapping from device index to the instance id for this index */
|
||||
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
|
||||
{
|
||||
return JoystickByDevIndex(device_index)->device_instance;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
SDL_joylist_item *item = JoystickByDevIndex(device_index);
|
||||
|
||||
if (item == NULL ) {
|
||||
return SDL_SetError("No such device");
|
||||
}
|
||||
|
||||
if (item->joystick != NULL) {
|
||||
return SDL_SetError("Joystick already opened");
|
||||
}
|
||||
|
||||
joystick->instance_id = item->device_instance;
|
||||
joystick->hwdata = (struct joystick_hwdata *) item;
|
||||
item->joystick = joystick;
|
||||
joystick->nhats = item->nhats;
|
||||
joystick->nballs = item->nballs;
|
||||
joystick->nbuttons = item->nbuttons;
|
||||
joystick->naxes = item->naxes;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Function to determine is this joystick is attached to the system right now */
|
||||
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
|
||||
{
|
||||
return !joystick->closed && (joystick->hwdata != NULL);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
|
||||
{
|
||||
int i;
|
||||
Sint16 value;
|
||||
float values[3];
|
||||
SDL_joylist_item *item = SDL_joylist;
|
||||
|
||||
while (item) {
|
||||
if (item->is_accelerometer) {
|
||||
if (item->joystick) {
|
||||
SDL_bool updated = Android_JNI_GetAccelerometerValues(values);
|
||||
if (updated) {
|
||||
for ( i = 0; i < 3; i++ ) {
|
||||
value = (Sint16)(values[i] * 32767.0f);
|
||||
SDL_PrivateJoystickAxis(item->joystick, i, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
item = item->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Function to close a joystick after use */
|
||||
void
|
||||
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
||||
{
|
||||
if (joystick->hwdata) {
|
||||
((SDL_joylist_item*)joystick->hwdata)->joystick = NULL;
|
||||
joystick->hwdata = NULL;
|
||||
}
|
||||
joystick->closed = 1;
|
||||
}
|
||||
|
||||
/* Function to perform any system-specific joystick related cleanup */
|
||||
void
|
||||
SDL_SYS_JoystickQuit(void)
|
||||
{
|
||||
SDL_joylist_item *item = NULL;
|
||||
SDL_joylist_item *next = NULL;
|
||||
|
||||
for (item = SDL_joylist; item; item = next) {
|
||||
next = item->next;
|
||||
SDL_free(item->name);
|
||||
SDL_free(item);
|
||||
}
|
||||
|
||||
SDL_joylist = SDL_joylist_tail = NULL;
|
||||
|
||||
numjoysticks = 0;
|
||||
instance_counter = 0;
|
||||
}
|
||||
|
||||
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
|
||||
{
|
||||
return JoystickByDevIndex(device_index)->guid;
|
||||
}
|
||||
|
||||
SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
|
||||
{
|
||||
SDL_JoystickGUID guid;
|
||||
|
||||
if (joystick->hwdata != NULL) {
|
||||
return ((SDL_joylist_item*)joystick->hwdata)->guid;
|
||||
}
|
||||
|
||||
SDL_zero(guid);
|
||||
return guid;
|
||||
}
|
||||
|
||||
#endif /* SDL_JOYSTICK_ANDROID */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_ANDROID
|
||||
#include "../SDL_sysjoystick.h"
|
||||
|
||||
extern int Android_OnPadDown(int device_id, int keycode);
|
||||
extern int Android_OnPadUp(int device_id, int keycode);
|
||||
extern int Android_OnJoy(int device_id, int axisnum, float value);
|
||||
extern int Android_AddJoystick(int device_id, const char *name, SDL_bool is_accelerometer, int nbuttons, int naxes, int nhats, int nballs);
|
||||
extern int Android_RemoveJoystick(int device_id);
|
||||
|
||||
/* A linked list of available joysticks */
|
||||
typedef struct SDL_joylist_item
|
||||
{
|
||||
int device_instance;
|
||||
int device_id; /* Android's device id */
|
||||
char *name; /* "SideWinder 3D Pro" or whatever */
|
||||
SDL_JoystickGUID guid;
|
||||
SDL_bool is_accelerometer;
|
||||
SDL_Joystick *joystick;
|
||||
int nbuttons, naxes, nhats, nballs;
|
||||
|
||||
struct SDL_joylist_item *next;
|
||||
} SDL_joylist_item;
|
||||
|
||||
typedef SDL_joylist_item joystick_hwdata;
|
||||
|
||||
#endif /* SDL_JOYSTICK_ANDROID */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,660 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifdef SDL_JOYSTICK_USBHID
|
||||
|
||||
/*
|
||||
* Joystick driver for the uhid(4) interface found in OpenBSD,
|
||||
* NetBSD and FreeBSD.
|
||||
*
|
||||
* Maintainer: <vedge at csoft.org>
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef __FreeBSD_kernel_version
|
||||
#define __FreeBSD_kernel_version __FreeBSD_version
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_USB_H)
|
||||
#include <usb.h>
|
||||
#endif
|
||||
#ifdef __DragonFly__
|
||||
#include <bus/usb/usb.h>
|
||||
#include <bus/usb/usbhid.h>
|
||||
#else
|
||||
#include <dev/usb/usb.h>
|
||||
#include <dev/usb/usbhid.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_USBHID_H)
|
||||
#include <usbhid.h>
|
||||
#elif defined(HAVE_LIBUSB_H)
|
||||
#include <libusb.h>
|
||||
#elif defined(HAVE_LIBUSBHID_H)
|
||||
#include <libusbhid.h>
|
||||
#endif
|
||||
|
||||
#if defined(__FREEBSD__) || defined(__FreeBSD_kernel__)
|
||||
#ifndef __DragonFly__
|
||||
#include <osreldate.h>
|
||||
#endif
|
||||
#if __FreeBSD_kernel_version > 800063
|
||||
#include <dev/usb/usb_ioctl.h>
|
||||
#endif
|
||||
#include <sys/joystick.h>
|
||||
#endif
|
||||
|
||||
#if SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H
|
||||
#include <machine/joystick.h>
|
||||
#endif
|
||||
|
||||
#include "SDL_joystick.h"
|
||||
#include "../SDL_sysjoystick.h"
|
||||
#include "../SDL_joystick_c.h"
|
||||
|
||||
#define MAX_UHID_JOYS 16
|
||||
#define MAX_JOY_JOYS 2
|
||||
#define MAX_JOYS (MAX_UHID_JOYS + MAX_JOY_JOYS)
|
||||
|
||||
|
||||
struct report
|
||||
{
|
||||
#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000)
|
||||
void *buf; /* Buffer */
|
||||
#elif defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063)
|
||||
struct usb_gen_descriptor *buf; /* Buffer */
|
||||
#else
|
||||
struct usb_ctl_report *buf; /* Buffer */
|
||||
#endif
|
||||
size_t size; /* Buffer size */
|
||||
int rid; /* Report ID */
|
||||
enum
|
||||
{
|
||||
SREPORT_UNINIT,
|
||||
SREPORT_CLEAN,
|
||||
SREPORT_DIRTY
|
||||
} status;
|
||||
};
|
||||
|
||||
static struct
|
||||
{
|
||||
int uhid_report;
|
||||
hid_kind_t kind;
|
||||
const char *name;
|
||||
} const repinfo[] = {
|
||||
{UHID_INPUT_REPORT, hid_input, "input"},
|
||||
{UHID_OUTPUT_REPORT, hid_output, "output"},
|
||||
{UHID_FEATURE_REPORT, hid_feature, "feature"}
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
REPORT_INPUT = 0,
|
||||
REPORT_OUTPUT = 1,
|
||||
REPORT_FEATURE = 2
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
JOYAXE_X,
|
||||
JOYAXE_Y,
|
||||
JOYAXE_Z,
|
||||
JOYAXE_SLIDER,
|
||||
JOYAXE_WHEEL,
|
||||
JOYAXE_RX,
|
||||
JOYAXE_RY,
|
||||
JOYAXE_RZ,
|
||||
JOYAXE_count
|
||||
};
|
||||
|
||||
struct joystick_hwdata
|
||||
{
|
||||
int fd;
|
||||
char *path;
|
||||
enum
|
||||
{
|
||||
BSDJOY_UHID, /* uhid(4) */
|
||||
BSDJOY_JOY /* joy(4) */
|
||||
} type;
|
||||
struct report_desc *repdesc;
|
||||
struct report inreport;
|
||||
int axis_map[JOYAXE_count]; /* map present JOYAXE_* to 0,1,.. */
|
||||
};
|
||||
|
||||
static char *joynames[MAX_JOYS];
|
||||
static char *joydevnames[MAX_JOYS];
|
||||
|
||||
static int report_alloc(struct report *, struct report_desc *, int);
|
||||
static void report_free(struct report *);
|
||||
|
||||
#if defined(USBHID_UCR_DATA) || (defined(__FreeBSD_kernel__) && __FreeBSD_kernel_version <= 800063)
|
||||
#define REP_BUF_DATA(rep) ((rep)->buf->ucr_data)
|
||||
#elif (defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000))
|
||||
#define REP_BUF_DATA(rep) ((rep)->buf)
|
||||
#elif (defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063))
|
||||
#define REP_BUF_DATA(rep) ((rep)->buf->ugd_data)
|
||||
#else
|
||||
#define REP_BUF_DATA(rep) ((rep)->buf->data)
|
||||
#endif
|
||||
|
||||
static int SDL_SYS_numjoysticks = 0;
|
||||
|
||||
int
|
||||
SDL_SYS_JoystickInit(void)
|
||||
{
|
||||
char s[16];
|
||||
int i, fd;
|
||||
|
||||
SDL_SYS_numjoysticks = 0;
|
||||
|
||||
SDL_memset(joynames, 0, sizeof(joynames));
|
||||
SDL_memset(joydevnames, 0, sizeof(joydevnames));
|
||||
|
||||
for (i = 0; i < MAX_UHID_JOYS; i++) {
|
||||
SDL_Joystick nj;
|
||||
|
||||
SDL_snprintf(s, SDL_arraysize(s), "/dev/uhid%d", i);
|
||||
|
||||
joynames[SDL_SYS_numjoysticks] = strdup(s);
|
||||
|
||||
if (SDL_SYS_JoystickOpen(&nj, SDL_SYS_numjoysticks) == 0) {
|
||||
SDL_SYS_JoystickClose(&nj);
|
||||
SDL_SYS_numjoysticks++;
|
||||
} else {
|
||||
SDL_free(joynames[SDL_SYS_numjoysticks]);
|
||||
joynames[SDL_SYS_numjoysticks] = NULL;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAX_JOY_JOYS; i++) {
|
||||
SDL_snprintf(s, SDL_arraysize(s), "/dev/joy%d", i);
|
||||
fd = open(s, O_RDONLY);
|
||||
if (fd != -1) {
|
||||
joynames[SDL_SYS_numjoysticks++] = strdup(s);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the default USB HID usage table. */
|
||||
hid_init(NULL);
|
||||
|
||||
return (SDL_SYS_numjoysticks);
|
||||
}
|
||||
|
||||
int SDL_SYS_NumJoysticks()
|
||||
{
|
||||
return SDL_SYS_numjoysticks;
|
||||
}
|
||||
|
||||
void SDL_SYS_JoystickDetect()
|
||||
{
|
||||
}
|
||||
|
||||
SDL_bool SDL_SYS_JoystickNeedsPolling()
|
||||
{
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
const char *
|
||||
SDL_SYS_JoystickNameForDeviceIndex(int device_index)
|
||||
{
|
||||
if (joydevnames[device_index] != NULL) {
|
||||
return (joydevnames[device_index]);
|
||||
}
|
||||
return (joynames[device_index]);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
static int
|
||||
usage_to_joyaxe(unsigned usage)
|
||||
{
|
||||
int joyaxe;
|
||||
switch (usage) {
|
||||
case HUG_X:
|
||||
joyaxe = JOYAXE_X;
|
||||
break;
|
||||
case HUG_Y:
|
||||
joyaxe = JOYAXE_Y;
|
||||
break;
|
||||
case HUG_Z:
|
||||
joyaxe = JOYAXE_Z;
|
||||
break;
|
||||
case HUG_SLIDER:
|
||||
joyaxe = JOYAXE_SLIDER;
|
||||
break;
|
||||
case HUG_WHEEL:
|
||||
joyaxe = JOYAXE_WHEEL;
|
||||
break;
|
||||
case HUG_RX:
|
||||
joyaxe = JOYAXE_RX;
|
||||
break;
|
||||
case HUG_RY:
|
||||
joyaxe = JOYAXE_RY;
|
||||
break;
|
||||
case HUG_RZ:
|
||||
joyaxe = JOYAXE_RZ;
|
||||
break;
|
||||
default:
|
||||
joyaxe = -1;
|
||||
}
|
||||
return joyaxe;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
hatval_to_sdl(Sint32 hatval)
|
||||
{
|
||||
static const unsigned hat_dir_map[8] = {
|
||||
SDL_HAT_UP, SDL_HAT_RIGHTUP, SDL_HAT_RIGHT, SDL_HAT_RIGHTDOWN,
|
||||
SDL_HAT_DOWN, SDL_HAT_LEFTDOWN, SDL_HAT_LEFT, SDL_HAT_LEFTUP
|
||||
};
|
||||
unsigned result;
|
||||
if ((hatval & 7) == hatval)
|
||||
result = hat_dir_map[hatval];
|
||||
else
|
||||
result = SDL_HAT_CENTERED;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SDL_SYS_JoystickOpen(SDL_Joystick * joy, int device_index)
|
||||
{
|
||||
char *path = joynames[device_index];
|
||||
struct joystick_hwdata *hw;
|
||||
struct hid_item hitem;
|
||||
struct hid_data *hdata;
|
||||
struct report *rep;
|
||||
int fd;
|
||||
int i;
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
return SDL_SetError("%s: %s", path, strerror(errno));
|
||||
}
|
||||
|
||||
joy->instance_id = device_index;
|
||||
hw = (struct joystick_hwdata *)
|
||||
SDL_malloc(sizeof(struct joystick_hwdata));
|
||||
if (hw == NULL) {
|
||||
close(fd);
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
joy->hwdata = hw;
|
||||
hw->fd = fd;
|
||||
hw->path = strdup(path);
|
||||
if (!SDL_strncmp(path, "/dev/joy", 8)) {
|
||||
hw->type = BSDJOY_JOY;
|
||||
joy->naxes = 2;
|
||||
joy->nbuttons = 2;
|
||||
joy->nhats = 0;
|
||||
joy->nballs = 0;
|
||||
joydevnames[device_index] = strdup("Gameport joystick");
|
||||
goto usbend;
|
||||
} else {
|
||||
hw->type = BSDJOY_UHID;
|
||||
}
|
||||
|
||||
{
|
||||
int ax;
|
||||
for (ax = 0; ax < JOYAXE_count; ax++)
|
||||
hw->axis_map[ax] = -1;
|
||||
}
|
||||
hw->repdesc = hid_get_report_desc(fd);
|
||||
if (hw->repdesc == NULL) {
|
||||
SDL_SetError("%s: USB_GET_REPORT_DESC: %s", hw->path,
|
||||
strerror(errno));
|
||||
goto usberr;
|
||||
}
|
||||
rep = &hw->inreport;
|
||||
#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063) || defined(__FreeBSD_kernel__)
|
||||
rep->rid = hid_get_report_id(fd);
|
||||
if (rep->rid < 0) {
|
||||
#else
|
||||
if (ioctl(fd, USB_GET_REPORT_ID, &rep->rid) < 0) {
|
||||
#endif
|
||||
rep->rid = -1; /* XXX */
|
||||
}
|
||||
if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) {
|
||||
goto usberr;
|
||||
}
|
||||
if (rep->size <= 0) {
|
||||
SDL_SetError("%s: Input report descriptor has invalid length",
|
||||
hw->path);
|
||||
goto usberr;
|
||||
}
|
||||
#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__)
|
||||
hdata = hid_start_parse(hw->repdesc, 1 << hid_input, rep->rid);
|
||||
#else
|
||||
hdata = hid_start_parse(hw->repdesc, 1 << hid_input);
|
||||
#endif
|
||||
if (hdata == NULL) {
|
||||
SDL_SetError("%s: Cannot start HID parser", hw->path);
|
||||
goto usberr;
|
||||
}
|
||||
joy->naxes = 0;
|
||||
joy->nbuttons = 0;
|
||||
joy->nhats = 0;
|
||||
joy->nballs = 0;
|
||||
for (i = 0; i < JOYAXE_count; i++)
|
||||
hw->axis_map[i] = -1;
|
||||
|
||||
while (hid_get_item(hdata, &hitem) > 0) {
|
||||
char *sp;
|
||||
const char *s;
|
||||
|
||||
switch (hitem.kind) {
|
||||
case hid_collection:
|
||||
switch (HID_PAGE(hitem.usage)) {
|
||||
case HUP_GENERIC_DESKTOP:
|
||||
switch (HID_USAGE(hitem.usage)) {
|
||||
case HUG_JOYSTICK:
|
||||
case HUG_GAME_PAD:
|
||||
s = hid_usage_in_page(hitem.usage);
|
||||
sp = SDL_malloc(SDL_strlen(s) + 5);
|
||||
SDL_snprintf(sp, SDL_strlen(s) + 5, "%s (%d)",
|
||||
s, device_index);
|
||||
joydevnames[device_index] = sp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case hid_input:
|
||||
switch (HID_PAGE(hitem.usage)) {
|
||||
case HUP_GENERIC_DESKTOP:
|
||||
{
|
||||
unsigned usage = HID_USAGE(hitem.usage);
|
||||
int joyaxe = usage_to_joyaxe(usage);
|
||||
if (joyaxe >= 0) {
|
||||
hw->axis_map[joyaxe] = 1;
|
||||
} else if (usage == HUG_HAT_SWITCH) {
|
||||
joy->nhats++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HUP_BUTTON:
|
||||
joy->nbuttons++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
hid_end_parse(hdata);
|
||||
for (i = 0; i < JOYAXE_count; i++)
|
||||
if (hw->axis_map[i] > 0)
|
||||
hw->axis_map[i] = joy->naxes++;
|
||||
|
||||
usbend:
|
||||
/* The poll blocks the event thread. */
|
||||
fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
|
||||
return (0);
|
||||
usberr:
|
||||
close(hw->fd);
|
||||
SDL_free(hw->path);
|
||||
SDL_free(hw);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Function to determine is this joystick is attached to the system right now */
|
||||
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_SYS_JoystickUpdate(SDL_Joystick * joy)
|
||||
{
|
||||
struct hid_item hitem;
|
||||
struct hid_data *hdata;
|
||||
struct report *rep;
|
||||
int nbutton, naxe = -1;
|
||||
Sint32 v;
|
||||
|
||||
#if defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H || defined(__FreeBSD_kernel__)
|
||||
struct joystick gameport;
|
||||
static int x, y, xmin = 0xffff, ymin = 0xffff, xmax = 0, ymax = 0;
|
||||
|
||||
if (joy->hwdata->type == BSDJOY_JOY) {
|
||||
while (read(joy->hwdata->fd, &gameport, sizeof gameport) == sizeof gameport) {
|
||||
if (abs(x - gameport.x) > 8) {
|
||||
x = gameport.x;
|
||||
if (x < xmin) {
|
||||
xmin = x;
|
||||
}
|
||||
if (x > xmax) {
|
||||
xmax = x;
|
||||
}
|
||||
if (xmin == xmax) {
|
||||
xmin--;
|
||||
xmax++;
|
||||
}
|
||||
v = (Sint32) x;
|
||||
v -= (xmax + xmin + 1) / 2;
|
||||
v *= 32768 / ((xmax - xmin + 1) / 2);
|
||||
SDL_PrivateJoystickAxis(joy, 0, v);
|
||||
}
|
||||
if (abs(y - gameport.y) > 8) {
|
||||
y = gameport.y;
|
||||
if (y < ymin) {
|
||||
ymin = y;
|
||||
}
|
||||
if (y > ymax) {
|
||||
ymax = y;
|
||||
}
|
||||
if (ymin == ymax) {
|
||||
ymin--;
|
||||
ymax++;
|
||||
}
|
||||
v = (Sint32) y;
|
||||
v -= (ymax + ymin + 1) / 2;
|
||||
v *= 32768 / ((ymax - ymin + 1) / 2);
|
||||
SDL_PrivateJoystickAxis(joy, 1, v);
|
||||
}
|
||||
if (gameport.b1 != joy->buttons[0]) {
|
||||
SDL_PrivateJoystickButton(joy, 0, gameport.b1);
|
||||
}
|
||||
if (gameport.b2 != joy->buttons[1]) {
|
||||
SDL_PrivateJoystickButton(joy, 1, gameport.b2);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif /* defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H */
|
||||
|
||||
rep = &joy->hwdata->inreport;
|
||||
|
||||
while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size) {
|
||||
#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__)
|
||||
hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid);
|
||||
#else
|
||||
hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input);
|
||||
#endif
|
||||
if (hdata == NULL) {
|
||||
/*fprintf(stderr, "%s: Cannot start HID parser\n", joy->hwdata->path);*/
|
||||
continue;
|
||||
}
|
||||
|
||||
for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) {
|
||||
switch (hitem.kind) {
|
||||
case hid_input:
|
||||
switch (HID_PAGE(hitem.usage)) {
|
||||
case HUP_GENERIC_DESKTOP:
|
||||
{
|
||||
unsigned usage = HID_USAGE(hitem.usage);
|
||||
int joyaxe = usage_to_joyaxe(usage);
|
||||
if (joyaxe >= 0) {
|
||||
naxe = joy->hwdata->axis_map[joyaxe];
|
||||
/* scaleaxe */
|
||||
v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
|
||||
v -= (hitem.logical_maximum +
|
||||
hitem.logical_minimum + 1) / 2;
|
||||
v *= 32768 /
|
||||
((hitem.logical_maximum -
|
||||
hitem.logical_minimum + 1) / 2);
|
||||
if (v != joy->axes[naxe]) {
|
||||
SDL_PrivateJoystickAxis(joy, naxe, v);
|
||||
}
|
||||
} else if (usage == HUG_HAT_SWITCH) {
|
||||
v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
|
||||
SDL_PrivateJoystickHat(joy, 0,
|
||||
hatval_to_sdl(v) -
|
||||
hitem.logical_minimum);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HUP_BUTTON:
|
||||
v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
|
||||
if (joy->buttons[nbutton] != v) {
|
||||
SDL_PrivateJoystickButton(joy, nbutton, v);
|
||||
}
|
||||
nbutton++;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
hid_end_parse(hdata);
|
||||
}
|
||||
}
|
||||
|
||||
/* Function to close a joystick after use */
|
||||
void
|
||||
SDL_SYS_JoystickClose(SDL_Joystick * joy)
|
||||
{
|
||||
if (SDL_strncmp(joy->hwdata->path, "/dev/joy", 8)) {
|
||||
report_free(&joy->hwdata->inreport);
|
||||
hid_dispose_report_desc(joy->hwdata->repdesc);
|
||||
}
|
||||
close(joy->hwdata->fd);
|
||||
SDL_free(joy->hwdata->path);
|
||||
SDL_free(joy->hwdata);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_SYS_JoystickQuit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_JOYS; i++) {
|
||||
SDL_free(joynames[i]);
|
||||
SDL_free(joydevnames[i]);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static int
|
||||
report_alloc(struct report *r, struct report_desc *rd, int repind)
|
||||
{
|
||||
int len;
|
||||
|
||||
#ifdef __DragonFly__
|
||||
len = hid_report_size(rd, r->rid, repinfo[repind].kind);
|
||||
#elif __FREEBSD__
|
||||
# if (__FreeBSD_kernel_version >= 460000) || defined(__FreeBSD_kernel__)
|
||||
# if (__FreeBSD_kernel_version <= 500111)
|
||||
len = hid_report_size(rd, r->rid, repinfo[repind].kind);
|
||||
# else
|
||||
len = hid_report_size(rd, repinfo[repind].kind, r->rid);
|
||||
# endif
|
||||
# else
|
||||
len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
|
||||
# endif
|
||||
#else
|
||||
# ifdef USBHID_NEW
|
||||
len = hid_report_size(rd, repinfo[repind].kind, r->rid);
|
||||
# else
|
||||
len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
if (len < 0) {
|
||||
return SDL_SetError("Negative HID report size");
|
||||
}
|
||||
r->size = len;
|
||||
|
||||
if (r->size > 0) {
|
||||
#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000)
|
||||
r->buf = SDL_malloc(r->size);
|
||||
#else
|
||||
r->buf = SDL_malloc(sizeof(*r->buf) - sizeof(REP_BUF_DATA(r)) +
|
||||
r->size);
|
||||
#endif
|
||||
if (r->buf == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
} else {
|
||||
r->buf = NULL;
|
||||
}
|
||||
|
||||
r->status = SREPORT_CLEAN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
report_free(struct report *r)
|
||||
{
|
||||
SDL_free(r->buf);
|
||||
r->status = SREPORT_UNINIT;
|
||||
}
|
||||
|
||||
#endif /* SDL_JOYSTICK_USBHID */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifndef SDL_JOYSTICK_IOKIT_H
|
||||
|
||||
|
||||
#include <IOKit/hid/IOHIDLib.h>
|
||||
#include <IOKit/hid/IOHIDKeys.h>
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
|
||||
struct recElement
|
||||
{
|
||||
IOHIDElementCookie cookie; /* unique value which identifies element, will NOT change */
|
||||
long usagePage, usage; /* HID usage */
|
||||
long min; /* reported min value possible */
|
||||
long max; /* reported max value possible */
|
||||
#if 0
|
||||
/* TODO: maybe should handle the following stuff somehow? */
|
||||
|
||||
long scaledMin; /* reported scaled min value possible */
|
||||
long scaledMax; /* reported scaled max value possible */
|
||||
long size; /* size in bits of data return from element */
|
||||
Boolean relative; /* are reports relative to last report (deltas) */
|
||||
Boolean wrapping; /* does element wrap around (one value higher than max is min) */
|
||||
Boolean nonLinear; /* are the values reported non-linear relative to element movement */
|
||||
Boolean preferredState; /* does element have a preferred state (such as a button) */
|
||||
Boolean nullState; /* does element have null state */
|
||||
#endif /* 0 */
|
||||
|
||||
/* runtime variables used for auto-calibration */
|
||||
long minReport; /* min returned value */
|
||||
long maxReport; /* max returned value */
|
||||
|
||||
struct recElement *pNext; /* next element in list */
|
||||
};
|
||||
typedef struct recElement recElement;
|
||||
|
||||
struct joystick_hwdata
|
||||
{
|
||||
io_service_t ffservice; /* Interface for force feedback, 0 = no ff */
|
||||
IOHIDDeviceInterface **interface; /* interface to device, NULL = no interface */
|
||||
IONotificationPortRef notificationPort; /* port to be notified on joystick removal */
|
||||
io_iterator_t portIterator; /* iterator for removal callback */
|
||||
|
||||
char product[256]; /* name of product */
|
||||
long usage; /* usage page from IOUSBHID Parser.h which defines general usage */
|
||||
long usagePage; /* usage within above page from IOUSBHID Parser.h which defines specific usage */
|
||||
|
||||
long axes; /* number of axis (calculated, not reported by device) */
|
||||
long buttons; /* number of buttons (calculated, not reported by device) */
|
||||
long hats; /* number of hat switches (calculated, not reported by device) */
|
||||
long elements; /* number of total elements (should be total of above) (calculated, not reported by device) */
|
||||
|
||||
recElement *firstAxis;
|
||||
recElement *firstButton;
|
||||
recElement *firstHat;
|
||||
|
||||
int removed;
|
||||
int uncentered;
|
||||
|
||||
int instance_id;
|
||||
SDL_JoystickGUID guid;
|
||||
Uint8 send_open_event; /* 1 if we need to send an Added event for this device */
|
||||
|
||||
struct joystick_hwdata *pNext; /* next device */
|
||||
};
|
||||
typedef struct joystick_hwdata recDevice;
|
||||
|
||||
|
||||
#endif /* SDL_JOYSTICK_IOKIT_H */
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#if defined(SDL_JOYSTICK_DUMMY) || defined(SDL_JOYSTICK_DISABLED)
|
||||
|
||||
/* This is the system specific header for the SDL joystick API */
|
||||
|
||||
#include "SDL_joystick.h"
|
||||
#include "../SDL_sysjoystick.h"
|
||||
#include "../SDL_joystick_c.h"
|
||||
|
||||
/* Function to scan the system for joysticks.
|
||||
* It should return 0, or -1 on an unrecoverable fatal error.
|
||||
*/
|
||||
int
|
||||
SDL_SYS_JoystickInit(void)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int SDL_SYS_NumJoysticks()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
SDL_SetError("Logic error: No joysticks available");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
return SDL_SetError("Logic error: No joysticks available");
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Function to close a joystick after use */
|
||||
void
|
||||
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Function to perform any system-specific joystick related cleanup */
|
||||
void
|
||||
SDL_SYS_JoystickQuit(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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_DUMMY || SDL_JOYSTICK_DISABLED */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,894 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifdef SDL_JOYSTICK_LINUX
|
||||
|
||||
#ifndef SDL_INPUT_LINUXEV
|
||||
#error SDL now requires a Linux 2.4+ kernel with /dev/input/event support.
|
||||
#endif
|
||||
|
||||
/* This is the system specific header for the SDL joystick API */
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <limits.h> /* For the definition of PATH_MAX */
|
||||
#include <linux/joystick.h>
|
||||
|
||||
#include "SDL_assert.h"
|
||||
#include "SDL_joystick.h"
|
||||
#include "SDL_endian.h"
|
||||
#include "../SDL_sysjoystick.h"
|
||||
#include "../SDL_joystick_c.h"
|
||||
#include "SDL_sysjoystick_c.h"
|
||||
|
||||
/* !!! FIXME: move this somewhere else. */
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
#include "../../events/SDL_events_c.h"
|
||||
#endif
|
||||
|
||||
/* This isn't defined in older Linux kernel headers */
|
||||
#ifndef SYN_DROPPED
|
||||
#define SYN_DROPPED 3
|
||||
#endif
|
||||
|
||||
#include "../../core/linux/SDL_udev.h"
|
||||
|
||||
static int MaybeAddDevice(const char *path);
|
||||
#if SDL_USE_LIBUDEV
|
||||
static int MaybeRemoveDevice(const char *path);
|
||||
void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath);
|
||||
#endif /* SDL_USE_LIBUDEV */
|
||||
|
||||
|
||||
/* A linked list of available joysticks */
|
||||
typedef struct SDL_joylist_item
|
||||
{
|
||||
int device_instance;
|
||||
char *path; /* "/dev/input/event2" or whatever */
|
||||
char *name; /* "SideWinder 3D Pro" or whatever */
|
||||
SDL_JoystickGUID guid;
|
||||
dev_t devnum;
|
||||
struct joystick_hwdata *hwdata;
|
||||
struct SDL_joylist_item *next;
|
||||
} SDL_joylist_item;
|
||||
|
||||
static SDL_joylist_item *SDL_joylist = NULL;
|
||||
static SDL_joylist_item *SDL_joylist_tail = NULL;
|
||||
static int numjoysticks = 0;
|
||||
static int instance_counter = 0;
|
||||
|
||||
#define test_bit(nr, addr) \
|
||||
(((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0)
|
||||
#define NBITS(x) ((((x)-1)/(sizeof(long) * 8))+1)
|
||||
|
||||
static int
|
||||
IsJoystick(int fd, char *namebuf, const size_t namebuflen, SDL_JoystickGUID *guid)
|
||||
{
|
||||
struct input_id inpid;
|
||||
Uint16 *guid16 = (Uint16 *) ((char *) &guid->data);
|
||||
|
||||
#if !SDL_USE_LIBUDEV
|
||||
/* When udev is enabled we only get joystick devices here, so there's no need to test them */
|
||||
unsigned long evbit[NBITS(EV_MAX)] = { 0 };
|
||||
unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
|
||||
unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
|
||||
|
||||
if ((ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||
|
||||
(ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) ||
|
||||
(ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0)) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!(test_bit(EV_KEY, evbit) && test_bit(EV_ABS, evbit) &&
|
||||
test_bit(ABS_X, absbit) && test_bit(ABS_Y, absbit))) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ioctl(fd, EVIOCGNAME(namebuflen), namebuf) < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ioctl(fd, EVIOCGID, &inpid) < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_JOYSTICK
|
||||
printf("Joystick: %s, bustype = %d, vendor = 0x%x, product = 0x%x, version = %d\n", namebuf, inpid.bustype, inpid.vendor, inpid.product, inpid.version);
|
||||
#endif
|
||||
|
||||
SDL_memset(guid->data, 0, sizeof(guid->data));
|
||||
|
||||
/* We only need 16 bits for each of these; space them out to fill 128. */
|
||||
/* Byteswap so devices get same GUID on little/big endian platforms. */
|
||||
*(guid16++) = SDL_SwapLE16(inpid.bustype);
|
||||
*(guid16++) = 0;
|
||||
|
||||
if (inpid.vendor && inpid.product && inpid.version) {
|
||||
*(guid16++) = SDL_SwapLE16(inpid.vendor);
|
||||
*(guid16++) = 0;
|
||||
*(guid16++) = SDL_SwapLE16(inpid.product);
|
||||
*(guid16++) = 0;
|
||||
*(guid16++) = SDL_SwapLE16(inpid.version);
|
||||
*(guid16++) = 0;
|
||||
} else {
|
||||
SDL_strlcpy((char*)guid16, namebuf, sizeof(guid->data) - 4);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if SDL_USE_LIBUDEV
|
||||
void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath)
|
||||
{
|
||||
if (devpath == NULL || !(udev_class & SDL_UDEV_DEVICE_JOYSTICK)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch( udev_type )
|
||||
{
|
||||
case SDL_UDEV_DEVICEADDED:
|
||||
MaybeAddDevice(devpath);
|
||||
break;
|
||||
|
||||
case SDL_UDEV_DEVICEREMOVED:
|
||||
MaybeRemoveDevice(devpath);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* SDL_USE_LIBUDEV */
|
||||
|
||||
|
||||
/* !!! FIXME: I would love to dump this code and use libudev instead. */
|
||||
static int
|
||||
MaybeAddDevice(const char *path)
|
||||
{
|
||||
struct stat sb;
|
||||
int fd = -1;
|
||||
int isstick = 0;
|
||||
char namebuf[128];
|
||||
SDL_JoystickGUID guid;
|
||||
SDL_joylist_item *item;
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
SDL_Event event;
|
||||
#endif
|
||||
|
||||
if (path == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stat(path, &sb) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check to make sure it's not already in list. */
|
||||
for (item = SDL_joylist; item != NULL; item = item->next) {
|
||||
if (sb.st_rdev == item->devnum) {
|
||||
return -1; /* already have this one */
|
||||
}
|
||||
}
|
||||
|
||||
fd = open(path, O_RDONLY, 0);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
printf("Checking %s\n", path);
|
||||
#endif
|
||||
|
||||
isstick = IsJoystick(fd, namebuf, sizeof (namebuf), &guid);
|
||||
close(fd);
|
||||
if (!isstick) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
item = (SDL_joylist_item *) SDL_malloc(sizeof (SDL_joylist_item));
|
||||
if (item == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_zerop(item);
|
||||
item->devnum = sb.st_rdev;
|
||||
item->path = SDL_strdup(path);
|
||||
item->name = SDL_strdup(namebuf);
|
||||
item->guid = guid;
|
||||
|
||||
if ( (item->path == NULL) || (item->name == NULL) ) {
|
||||
SDL_free(item->path);
|
||||
SDL_free(item->name);
|
||||
SDL_free(item);
|
||||
return -1;
|
||||
}
|
||||
|
||||
item->device_instance = instance_counter++;
|
||||
if (SDL_joylist_tail == NULL) {
|
||||
SDL_joylist = SDL_joylist_tail = item;
|
||||
} else {
|
||||
SDL_joylist_tail->next = item;
|
||||
SDL_joylist_tail = item;
|
||||
}
|
||||
|
||||
/* Need to increment the joystick count before we post the event */
|
||||
++numjoysticks;
|
||||
|
||||
/* !!! FIXME: Move this to an SDL_PrivateJoyDeviceAdded() function? */
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
event.type = SDL_JOYDEVICEADDED;
|
||||
|
||||
if (SDL_GetEventState(event.type) == SDL_ENABLE) {
|
||||
event.jdevice.which = (numjoysticks - 1);
|
||||
if ( (SDL_EventOK == NULL) ||
|
||||
(*SDL_EventOK) (SDL_EventOKParam, &event) ) {
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
#endif /* !SDL_EVENTS_DISABLED */
|
||||
|
||||
return numjoysticks;
|
||||
}
|
||||
|
||||
#if SDL_USE_LIBUDEV
|
||||
/* !!! FIXME: I would love to dump this code and use libudev instead. */
|
||||
static int
|
||||
MaybeRemoveDevice(const char *path)
|
||||
{
|
||||
SDL_joylist_item *item;
|
||||
SDL_joylist_item *prev = NULL;
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
SDL_Event event;
|
||||
#endif
|
||||
|
||||
if (path == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (item = SDL_joylist; item != NULL; item = item->next) {
|
||||
/* found it, remove it. */
|
||||
if (SDL_strcmp(path, item->path) == 0) {
|
||||
const int retval = item->device_instance;
|
||||
if (item->hwdata) {
|
||||
item->hwdata->item = NULL;
|
||||
}
|
||||
if (prev != NULL) {
|
||||
prev->next = item->next;
|
||||
} else {
|
||||
SDL_assert(SDL_joylist == item);
|
||||
SDL_joylist = item->next;
|
||||
}
|
||||
if (item == SDL_joylist_tail) {
|
||||
SDL_joylist_tail = prev;
|
||||
}
|
||||
|
||||
/* Need to decrement the joystick count before we post the event */
|
||||
--numjoysticks;
|
||||
|
||||
/* !!! FIXME: Move this to an SDL_PrivateJoyDeviceRemoved() function? */
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
event.type = SDL_JOYDEVICEREMOVED;
|
||||
|
||||
if (SDL_GetEventState(event.type) == SDL_ENABLE) {
|
||||
event.jdevice.which = item->device_instance;
|
||||
if ( (SDL_EventOK == NULL) ||
|
||||
(*SDL_EventOK) (SDL_EventOKParam, &event) ) {
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
#endif /* !SDL_EVENTS_DISABLED */
|
||||
|
||||
SDL_free(item->path);
|
||||
SDL_free(item->name);
|
||||
SDL_free(item);
|
||||
return retval;
|
||||
}
|
||||
prev = item;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
JoystickInitWithoutUdev(void)
|
||||
{
|
||||
int i;
|
||||
char path[PATH_MAX];
|
||||
|
||||
/* !!! FIXME: only finds sticks if they're called /dev/input/event[0..31] */
|
||||
/* !!! FIXME: we could at least readdir() through /dev/input...? */
|
||||
/* !!! FIXME: (or delete this and rely on libudev?) */
|
||||
for (i = 0; i < 32; i++) {
|
||||
SDL_snprintf(path, SDL_arraysize(path), "/dev/input/event%d", i);
|
||||
MaybeAddDevice(path);
|
||||
}
|
||||
|
||||
return numjoysticks;
|
||||
}
|
||||
|
||||
|
||||
#if SDL_USE_LIBUDEV
|
||||
static int
|
||||
JoystickInitWithUdev(void)
|
||||
{
|
||||
|
||||
if (SDL_UDEV_Init() < 0) {
|
||||
return SDL_SetError("Could not initialize UDEV");
|
||||
}
|
||||
|
||||
/* Set up the udev callback */
|
||||
if ( SDL_UDEV_AddCallback(joystick_udev_callback) < 0) {
|
||||
SDL_UDEV_Quit();
|
||||
return SDL_SetError("Could not set up joystick <-> udev callback");
|
||||
}
|
||||
|
||||
/* Force a scan to build the initial device list */
|
||||
SDL_UDEV_Scan();
|
||||
|
||||
return numjoysticks;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
SDL_SYS_JoystickInit(void)
|
||||
{
|
||||
/* First see if the user specified one or more joysticks to use */
|
||||
if (SDL_getenv("SDL_JOYSTICK_DEVICE") != NULL) {
|
||||
char *envcopy, *envpath, *delim;
|
||||
envcopy = SDL_strdup(SDL_getenv("SDL_JOYSTICK_DEVICE"));
|
||||
envpath = envcopy;
|
||||
while (envpath != NULL) {
|
||||
delim = SDL_strchr(envpath, ':');
|
||||
if (delim != NULL) {
|
||||
*delim++ = '\0';
|
||||
}
|
||||
MaybeAddDevice(envpath);
|
||||
envpath = delim;
|
||||
}
|
||||
SDL_free(envcopy);
|
||||
}
|
||||
|
||||
#if SDL_USE_LIBUDEV
|
||||
return JoystickInitWithUdev();
|
||||
#endif
|
||||
|
||||
return JoystickInitWithoutUdev();
|
||||
}
|
||||
|
||||
int SDL_SYS_NumJoysticks()
|
||||
{
|
||||
return numjoysticks;
|
||||
}
|
||||
|
||||
void SDL_SYS_JoystickDetect()
|
||||
{
|
||||
#if SDL_USE_LIBUDEV
|
||||
SDL_UDEV_Poll();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
SDL_bool SDL_SYS_JoystickNeedsPolling()
|
||||
{
|
||||
#if SDL_USE_LIBUDEV
|
||||
return SDL_TRUE;
|
||||
#endif
|
||||
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static SDL_joylist_item *
|
||||
JoystickByDevIndex(int device_index)
|
||||
{
|
||||
SDL_joylist_item *item = SDL_joylist;
|
||||
|
||||
if ((device_index < 0) || (device_index >= numjoysticks)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (device_index > 0) {
|
||||
SDL_assert(item != NULL);
|
||||
device_index--;
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/* Function to get the device-dependent name of a joystick */
|
||||
const char *
|
||||
SDL_SYS_JoystickNameForDeviceIndex(int device_index)
|
||||
{
|
||||
return JoystickByDevIndex(device_index)->name;
|
||||
}
|
||||
|
||||
/* Function to perform the mapping from device index to the instance id for this index */
|
||||
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
|
||||
{
|
||||
return JoystickByDevIndex(device_index)->device_instance;
|
||||
}
|
||||
|
||||
static int
|
||||
allocate_hatdata(SDL_Joystick * joystick)
|
||||
{
|
||||
int i;
|
||||
|
||||
joystick->hwdata->hats =
|
||||
(struct hwdata_hat *) SDL_malloc(joystick->nhats *
|
||||
sizeof(struct hwdata_hat));
|
||||
if (joystick->hwdata->hats == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
for (i = 0; i < joystick->nhats; ++i) {
|
||||
joystick->hwdata->hats[i].axis[0] = 1;
|
||||
joystick->hwdata->hats[i].axis[1] = 1;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
allocate_balldata(SDL_Joystick * joystick)
|
||||
{
|
||||
int i;
|
||||
|
||||
joystick->hwdata->balls =
|
||||
(struct hwdata_ball *) SDL_malloc(joystick->nballs *
|
||||
sizeof(struct hwdata_ball));
|
||||
if (joystick->hwdata->balls == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
for (i = 0; i < joystick->nballs; ++i) {
|
||||
joystick->hwdata->balls[i].axis[0] = 0;
|
||||
joystick->hwdata->balls[i].axis[1] = 0;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
ConfigJoystick(SDL_Joystick * joystick, int fd)
|
||||
{
|
||||
int i, t;
|
||||
unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
|
||||
unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
|
||||
unsigned long relbit[NBITS(REL_MAX)] = { 0 };
|
||||
|
||||
/* See if this device uses the new unified event API */
|
||||
if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&
|
||||
(ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) &&
|
||||
(ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0)) {
|
||||
|
||||
/* Get the number of buttons, axes, and other thingamajigs */
|
||||
for (i = BTN_JOYSTICK; i < KEY_MAX; ++i) {
|
||||
if (test_bit(i, keybit)) {
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
printf("Joystick has button: 0x%x\n", i);
|
||||
#endif
|
||||
joystick->hwdata->key_map[i - BTN_MISC] = joystick->nbuttons;
|
||||
++joystick->nbuttons;
|
||||
}
|
||||
}
|
||||
for (i = BTN_MISC; i < BTN_JOYSTICK; ++i) {
|
||||
if (test_bit(i, keybit)) {
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
printf("Joystick has button: 0x%x\n", i);
|
||||
#endif
|
||||
joystick->hwdata->key_map[i - BTN_MISC] = joystick->nbuttons;
|
||||
++joystick->nbuttons;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ABS_MISC; ++i) {
|
||||
/* Skip hats */
|
||||
if (i == ABS_HAT0X) {
|
||||
i = ABS_HAT3Y;
|
||||
continue;
|
||||
}
|
||||
if (test_bit(i, absbit)) {
|
||||
struct input_absinfo absinfo;
|
||||
|
||||
if (ioctl(fd, EVIOCGABS(i), &absinfo) < 0) {
|
||||
continue;
|
||||
}
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
printf("Joystick has absolute axis: 0x%.2x\n", i);
|
||||
printf("Values = { %d, %d, %d, %d, %d }\n",
|
||||
absinfo.value, absinfo.minimum, absinfo.maximum,
|
||||
absinfo.fuzz, absinfo.flat);
|
||||
#endif /* DEBUG_INPUT_EVENTS */
|
||||
joystick->hwdata->abs_map[i] = joystick->naxes;
|
||||
if (absinfo.minimum == absinfo.maximum) {
|
||||
joystick->hwdata->abs_correct[i].used = 0;
|
||||
} else {
|
||||
joystick->hwdata->abs_correct[i].used = 1;
|
||||
joystick->hwdata->abs_correct[i].coef[0] =
|
||||
(absinfo.maximum + absinfo.minimum) - 2 * absinfo.flat;
|
||||
joystick->hwdata->abs_correct[i].coef[1] =
|
||||
(absinfo.maximum + absinfo.minimum) + 2 * absinfo.flat;
|
||||
t = ((absinfo.maximum - absinfo.minimum) - 4 * absinfo.flat);
|
||||
if (t != 0) {
|
||||
joystick->hwdata->abs_correct[i].coef[2] =
|
||||
(1 << 28) / t;
|
||||
} else {
|
||||
joystick->hwdata->abs_correct[i].coef[2] = 0;
|
||||
}
|
||||
}
|
||||
++joystick->naxes;
|
||||
}
|
||||
}
|
||||
for (i = ABS_HAT0X; i <= ABS_HAT3Y; i += 2) {
|
||||
if (test_bit(i, absbit) || test_bit(i + 1, absbit)) {
|
||||
struct input_absinfo absinfo;
|
||||
|
||||
if (ioctl(fd, EVIOCGABS(i), &absinfo) < 0) {
|
||||
continue;
|
||||
}
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
printf("Joystick has hat %d\n", (i - ABS_HAT0X) / 2);
|
||||
printf("Values = { %d, %d, %d, %d, %d }\n",
|
||||
absinfo.value, absinfo.minimum, absinfo.maximum,
|
||||
absinfo.fuzz, absinfo.flat);
|
||||
#endif /* DEBUG_INPUT_EVENTS */
|
||||
++joystick->nhats;
|
||||
}
|
||||
}
|
||||
if (test_bit(REL_X, relbit) || test_bit(REL_Y, relbit)) {
|
||||
++joystick->nballs;
|
||||
}
|
||||
|
||||
/* Allocate data to keep track of these thingamajigs */
|
||||
if (joystick->nhats > 0) {
|
||||
if (allocate_hatdata(joystick) < 0) {
|
||||
joystick->nhats = 0;
|
||||
}
|
||||
}
|
||||
if (joystick->nballs > 0) {
|
||||
if (allocate_balldata(joystick) < 0) {
|
||||
joystick->nballs = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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)
|
||||
{
|
||||
SDL_joylist_item *item = JoystickByDevIndex(device_index);
|
||||
char *fname = NULL;
|
||||
int fd = -1;
|
||||
|
||||
if (item == NULL) {
|
||||
return SDL_SetError("No such device");
|
||||
}
|
||||
|
||||
fname = item->path;
|
||||
fd = open(fname, O_RDONLY, 0);
|
||||
if (fd < 0) {
|
||||
return SDL_SetError("Unable to open %s", fname);
|
||||
}
|
||||
|
||||
joystick->instance_id = item->device_instance;
|
||||
joystick->hwdata = (struct joystick_hwdata *)
|
||||
SDL_malloc(sizeof(*joystick->hwdata));
|
||||
if (joystick->hwdata == NULL) {
|
||||
close(fd);
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
|
||||
joystick->hwdata->item = item;
|
||||
joystick->hwdata->guid = item->guid;
|
||||
joystick->hwdata->fd = fd;
|
||||
joystick->hwdata->fname = SDL_strdup(item->path);
|
||||
if (joystick->hwdata->fname == NULL) {
|
||||
SDL_free(joystick->hwdata);
|
||||
joystick->hwdata = NULL;
|
||||
close(fd);
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
SDL_assert(item->hwdata == NULL);
|
||||
item->hwdata = joystick->hwdata;
|
||||
|
||||
/* Set the joystick to non-blocking read mode */
|
||||
fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
|
||||
/* Get the number of buttons and axes on the joystick */
|
||||
ConfigJoystick(joystick, fd);
|
||||
|
||||
/* mark joystick as fresh and ready */
|
||||
joystick->hwdata->fresh = 1;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Function to determine is this joystick is attached to the system right now */
|
||||
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
|
||||
{
|
||||
return !joystick->closed && (joystick->hwdata->item != NULL);
|
||||
}
|
||||
|
||||
static SDL_INLINE void
|
||||
HandleHat(SDL_Joystick * stick, Uint8 hat, int axis, int value)
|
||||
{
|
||||
struct hwdata_hat *the_hat;
|
||||
const Uint8 position_map[3][3] = {
|
||||
{SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP},
|
||||
{SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT},
|
||||
{SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN}
|
||||
};
|
||||
|
||||
the_hat = &stick->hwdata->hats[hat];
|
||||
if (value < 0) {
|
||||
value = 0;
|
||||
} else if (value == 0) {
|
||||
value = 1;
|
||||
} else if (value > 0) {
|
||||
value = 2;
|
||||
}
|
||||
if (value != the_hat->axis[axis]) {
|
||||
the_hat->axis[axis] = value;
|
||||
SDL_PrivateJoystickHat(stick, hat,
|
||||
position_map[the_hat->
|
||||
axis[1]][the_hat->axis[0]]);
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_INLINE void
|
||||
HandleBall(SDL_Joystick * stick, Uint8 ball, int axis, int value)
|
||||
{
|
||||
stick->hwdata->balls[ball].axis[axis] += value;
|
||||
}
|
||||
|
||||
|
||||
static SDL_INLINE int
|
||||
AxisCorrect(SDL_Joystick * joystick, int which, int value)
|
||||
{
|
||||
struct axis_correct *correct;
|
||||
|
||||
correct = &joystick->hwdata->abs_correct[which];
|
||||
if (correct->used) {
|
||||
value *= 2;
|
||||
if (value > correct->coef[0]) {
|
||||
if (value < correct->coef[1]) {
|
||||
return 0;
|
||||
}
|
||||
value -= correct->coef[1];
|
||||
} else {
|
||||
value -= correct->coef[0];
|
||||
}
|
||||
value *= correct->coef[2];
|
||||
value >>= 13;
|
||||
}
|
||||
|
||||
/* Clamp and return */
|
||||
if (value < -32768)
|
||||
return -32768;
|
||||
if (value > 32767)
|
||||
return 32767;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static SDL_INLINE void
|
||||
PollAllValues(SDL_Joystick * joystick)
|
||||
{
|
||||
struct input_absinfo absinfo;
|
||||
int a, b = 0;
|
||||
|
||||
/* Poll all axis */
|
||||
for (a = ABS_X; b < ABS_MAX; a++) {
|
||||
switch (a) {
|
||||
case ABS_HAT0X:
|
||||
case ABS_HAT0Y:
|
||||
case ABS_HAT1X:
|
||||
case ABS_HAT1Y:
|
||||
case ABS_HAT2X:
|
||||
case ABS_HAT2Y:
|
||||
case ABS_HAT3X:
|
||||
case ABS_HAT3Y:
|
||||
/* ingore hats */
|
||||
break;
|
||||
default:
|
||||
if (joystick->hwdata->abs_correct[b].used) {
|
||||
if (ioctl(joystick->hwdata->fd, EVIOCGABS(a), &absinfo) >= 0) {
|
||||
absinfo.value = AxisCorrect(joystick, b, absinfo.value);
|
||||
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
printf("Joystick : Re-read Axis %d (%d) val= %d\n",
|
||||
joystick->hwdata->abs_map[b], a, absinfo.value);
|
||||
#endif
|
||||
SDL_PrivateJoystickAxis(joystick,
|
||||
joystick->hwdata->abs_map[b],
|
||||
absinfo.value);
|
||||
}
|
||||
}
|
||||
b++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_INLINE void
|
||||
HandleInputEvents(SDL_Joystick * joystick)
|
||||
{
|
||||
struct input_event events[32];
|
||||
int i, len;
|
||||
int code;
|
||||
|
||||
if (joystick->hwdata->fresh) {
|
||||
PollAllValues(joystick);
|
||||
joystick->hwdata->fresh = 0;
|
||||
}
|
||||
|
||||
while ((len = read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
|
||||
len /= sizeof(events[0]);
|
||||
for (i = 0; i < len; ++i) {
|
||||
code = events[i].code;
|
||||
switch (events[i].type) {
|
||||
case EV_KEY:
|
||||
if (code >= BTN_MISC) {
|
||||
code -= BTN_MISC;
|
||||
SDL_PrivateJoystickButton(joystick,
|
||||
joystick->hwdata->key_map[code],
|
||||
events[i].value);
|
||||
}
|
||||
break;
|
||||
case EV_ABS:
|
||||
if (code >= ABS_MISC) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
case ABS_HAT0X:
|
||||
case ABS_HAT0Y:
|
||||
case ABS_HAT1X:
|
||||
case ABS_HAT1Y:
|
||||
case ABS_HAT2X:
|
||||
case ABS_HAT2Y:
|
||||
case ABS_HAT3X:
|
||||
case ABS_HAT3Y:
|
||||
code -= ABS_HAT0X;
|
||||
HandleHat(joystick, code / 2, code % 2, events[i].value);
|
||||
break;
|
||||
default:
|
||||
events[i].value =
|
||||
AxisCorrect(joystick, code, events[i].value);
|
||||
SDL_PrivateJoystickAxis(joystick,
|
||||
joystick->hwdata->abs_map[code],
|
||||
events[i].value);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case EV_REL:
|
||||
switch (code) {
|
||||
case REL_X:
|
||||
case REL_Y:
|
||||
code -= REL_X;
|
||||
HandleBall(joystick, code / 2, code % 2, events[i].value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case EV_SYN:
|
||||
switch (code) {
|
||||
case SYN_DROPPED :
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
printf("Event SYN_DROPPED detected\n");
|
||||
#endif
|
||||
PollAllValues(joystick);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
|
||||
{
|
||||
int i;
|
||||
|
||||
HandleInputEvents(joystick);
|
||||
|
||||
/* Deliver ball motion updates */
|
||||
for (i = 0; i < joystick->nballs; ++i) {
|
||||
int xrel, yrel;
|
||||
|
||||
xrel = joystick->hwdata->balls[i].axis[0];
|
||||
yrel = joystick->hwdata->balls[i].axis[1];
|
||||
if (xrel || yrel) {
|
||||
joystick->hwdata->balls[i].axis[0] = 0;
|
||||
joystick->hwdata->balls[i].axis[1] = 0;
|
||||
SDL_PrivateJoystickBall(joystick, (Uint8) i, xrel, yrel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Function to close a joystick after use */
|
||||
void
|
||||
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
||||
{
|
||||
if (joystick->hwdata) {
|
||||
close(joystick->hwdata->fd);
|
||||
if (joystick->hwdata->item) {
|
||||
joystick->hwdata->item->hwdata = NULL;
|
||||
}
|
||||
SDL_free(joystick->hwdata->hats);
|
||||
SDL_free(joystick->hwdata->balls);
|
||||
SDL_free(joystick->hwdata->fname);
|
||||
SDL_free(joystick->hwdata);
|
||||
joystick->hwdata = NULL;
|
||||
}
|
||||
joystick->closed = 1;
|
||||
}
|
||||
|
||||
/* Function to perform any system-specific joystick related cleanup */
|
||||
void
|
||||
SDL_SYS_JoystickQuit(void)
|
||||
{
|
||||
SDL_joylist_item *item = NULL;
|
||||
SDL_joylist_item *next = NULL;
|
||||
|
||||
for (item = SDL_joylist; item; item = next) {
|
||||
next = item->next;
|
||||
SDL_free(item->path);
|
||||
SDL_free(item->name);
|
||||
SDL_free(item);
|
||||
}
|
||||
|
||||
SDL_joylist = SDL_joylist_tail = NULL;
|
||||
|
||||
numjoysticks = 0;
|
||||
instance_counter = 0;
|
||||
|
||||
#if SDL_USE_LIBUDEV
|
||||
SDL_UDEV_DelCallback(joystick_udev_callback);
|
||||
SDL_UDEV_Quit();
|
||||
#endif
|
||||
}
|
||||
|
||||
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
|
||||
{
|
||||
return JoystickByDevIndex(device_index)->guid;
|
||||
}
|
||||
|
||||
SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
|
||||
{
|
||||
return joystick->hwdata->guid;
|
||||
}
|
||||
|
||||
#endif /* SDL_JOYSTICK_LINUX */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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 <linux/input.h>
|
||||
|
||||
struct SDL_joylist_item;
|
||||
|
||||
/* The private structure used to keep track of a joystick */
|
||||
struct joystick_hwdata
|
||||
{
|
||||
int fd;
|
||||
struct SDL_joylist_item *item;
|
||||
SDL_JoystickGUID guid;
|
||||
char *fname; /* Used in haptic subsystem */
|
||||
|
||||
/* The current Linux joystick driver maps hats to two axes */
|
||||
struct hwdata_hat
|
||||
{
|
||||
int axis[2];
|
||||
} *hats;
|
||||
/* The current Linux joystick driver maps balls to two axes */
|
||||
struct hwdata_ball
|
||||
{
|
||||
int axis[2];
|
||||
} *balls;
|
||||
|
||||
/* Support for the Linux 2.4 unified input interface */
|
||||
Uint8 key_map[KEY_MAX - BTN_MISC];
|
||||
Uint8 abs_map[ABS_MAX];
|
||||
struct axis_correct
|
||||
{
|
||||
int used;
|
||||
int coef[3];
|
||||
} abs_correct[ABS_MAX];
|
||||
|
||||
int fresh;
|
||||
};
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,274 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/* This is the system specific header for the SDL joystick API */
|
||||
#include <pspctrl.h>
|
||||
#include <pspkernel.h>
|
||||
|
||||
#include <stdio.h> /* For the definition of NULL */
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../SDL_sysjoystick.h"
|
||||
#include "../SDL_joystick_c.h"
|
||||
|
||||
#include "SDL_events.h"
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_mutex.h"
|
||||
#include "SDL_timer.h"
|
||||
|
||||
/* Current pad state */
|
||||
static SceCtrlData pad = { .Lx = 0, .Ly = 0, .Buttons = 0 };
|
||||
static SDL_sem *pad_sem = NULL;
|
||||
static SDL_Thread *thread = NULL;
|
||||
static int running = 0;
|
||||
static const enum PspCtrlButtons button_map[] = {
|
||||
PSP_CTRL_TRIANGLE, PSP_CTRL_CIRCLE, PSP_CTRL_CROSS, PSP_CTRL_SQUARE,
|
||||
PSP_CTRL_LTRIGGER, PSP_CTRL_RTRIGGER,
|
||||
PSP_CTRL_DOWN, PSP_CTRL_LEFT, PSP_CTRL_UP, PSP_CTRL_RIGHT,
|
||||
PSP_CTRL_SELECT, PSP_CTRL_START, PSP_CTRL_HOME, PSP_CTRL_HOLD };
|
||||
static int analog_map[256]; /* Map analog inputs to -32768 -> 32767 */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
} point;
|
||||
|
||||
/* 4 points define the bezier-curve. */
|
||||
static point a = { 0, 0 };
|
||||
static point b = { 50, 0 };
|
||||
static point c = { 78, 32767 };
|
||||
static point d = { 128, 32767 };
|
||||
|
||||
/* simple linear interpolation between two points */
|
||||
static SDL_INLINE void lerp (point *dest, point *a, point *b, float t)
|
||||
{
|
||||
dest->x = a->x + (b->x - a->x)*t;
|
||||
dest->y = a->y + (b->y - a->y)*t;
|
||||
}
|
||||
|
||||
/* evaluate a point on a bezier-curve. t goes from 0 to 1.0 */
|
||||
static int calc_bezier_y(float t)
|
||||
{
|
||||
point ab, bc, cd, abbc, bccd, dest;
|
||||
lerp (&ab, &a, &b, t); /* point between a and b */
|
||||
lerp (&bc, &b, &c, t); /* point between b and c */
|
||||
lerp (&cd, &c, &d, t); /* point between c and d */
|
||||
lerp (&abbc, &ab, &bc, t); /* point between ab and bc */
|
||||
lerp (&bccd, &bc, &cd, t); /* point between bc and cd */
|
||||
lerp (&dest, &abbc, &bccd, t); /* point on the bezier-curve */
|
||||
return dest.y;
|
||||
}
|
||||
|
||||
/*
|
||||
* Collect pad data about once per frame
|
||||
*/
|
||||
int JoystickUpdate(void *data)
|
||||
{
|
||||
while (running) {
|
||||
SDL_SemWait(pad_sem);
|
||||
sceCtrlPeekBufferPositive(&pad, 1);
|
||||
SDL_SemPost(pad_sem);
|
||||
/* Delay 1/60th of a second */
|
||||
sceKernelDelayThread(1000000 / 60);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Function to scan the system for joysticks.
|
||||
* This function should set SDL_numjoysticks to the number of available
|
||||
* joysticks. Joystick 0 should be the system default joystick.
|
||||
* It should return number of joysticks, or -1 on an unrecoverable fatal error.
|
||||
*/
|
||||
int SDL_SYS_JoystickInit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* SDL_numjoysticks = 1; */
|
||||
|
||||
/* Setup input */
|
||||
sceCtrlSetSamplingCycle(0);
|
||||
sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
|
||||
|
||||
/* Start thread to read data */
|
||||
if((pad_sem = SDL_CreateSemaphore(1)) == NULL) {
|
||||
return SDL_SetError("Can't create input semaphore");
|
||||
}
|
||||
running = 1;
|
||||
if((thread = SDL_CreateThread(JoystickUpdate, "JoySitckThread",NULL)) == NULL) {
|
||||
return SDL_SetError("Can't create input thread");
|
||||
}
|
||||
|
||||
/* Create an accurate map from analog inputs (0 to 255)
|
||||
to SDL joystick positions (-32768 to 32767) */
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
float t = (float)i/127.0f;
|
||||
analog_map[i+128] = calc_bezier_y(t);
|
||||
analog_map[127-i] = -1 * analog_map[i+128];
|
||||
}
|
||||
|
||||
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 "PSP 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 get the device-dependent name of a joystick */
|
||||
const char *SDL_SYS_JoystickName(int index)
|
||||
{
|
||||
if (index == 0)
|
||||
return "PSP controller";
|
||||
|
||||
SDL_SetError("No joystick available with that index");
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* 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 = 14;
|
||||
joystick->naxes = 2;
|
||||
joystick->nhats = 0;
|
||||
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
enum PspCtrlButtons buttons;
|
||||
enum PspCtrlButtons changed;
|
||||
unsigned char x, y;
|
||||
static enum PspCtrlButtons old_buttons = 0;
|
||||
static unsigned char old_x = 0, old_y = 0;
|
||||
|
||||
SDL_SemWait(pad_sem);
|
||||
buttons = pad.Buttons;
|
||||
x = pad.Lx;
|
||||
y = pad.Ly;
|
||||
SDL_SemPost(pad_sem);
|
||||
|
||||
/* Axes */
|
||||
if(old_x != x) {
|
||||
SDL_PrivateJoystickAxis(joystick, 0, analog_map[x]);
|
||||
old_x = x;
|
||||
}
|
||||
if(old_y != y) {
|
||||
SDL_PrivateJoystickAxis(joystick, 1, analog_map[y]);
|
||||
old_y = y;
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
changed = old_buttons ^ buttons;
|
||||
old_buttons = buttons;
|
||||
if(changed) {
|
||||
for(i=0; i<sizeof(button_map)/sizeof(button_map[0]); i++) {
|
||||
if(changed & button_map[i]) {
|
||||
SDL_PrivateJoystickButton(
|
||||
joystick, i,
|
||||
(buttons & button_map[i]) ?
|
||||
SDL_PRESSED : SDL_RELEASED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sceKernelDelayThread(0);
|
||||
}
|
||||
|
||||
/* Function to close a joystick after use */
|
||||
void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
|
||||
{
|
||||
/* Do nothing. */
|
||||
}
|
||||
|
||||
/* Function to perform any system-specific joystick related cleanup */
|
||||
void SDL_SYS_JoystickQuit(void)
|
||||
{
|
||||
/* Cleanup Threads and Semaphore. */
|
||||
running = 0;
|
||||
SDL_WaitThread(thread, NULL);
|
||||
SDL_DestroySemaphore(pad_sem);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* vim: ts=4 sw=4
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifndef SDL_JOYSTICK_DINPUT_H
|
||||
|
||||
/* DirectInput joystick driver; written by Glenn Maynard, based on Andrei de
|
||||
* A. Formiga's WINMM driver.
|
||||
*
|
||||
* Hats and sliders are completely untested; the app I'm writing this for mostly
|
||||
* doesn't use them and I don't own any joysticks with them.
|
||||
*
|
||||
* We don't bother to use event notification here. It doesn't seem to work
|
||||
* with polled devices, and it's fine to call IDirectInputDevice2_GetDeviceData and
|
||||
* let it return 0 events. */
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
|
||||
#define DIRECTINPUT_VERSION 0x0800 /* Need version 7 for force feedback. Need version 8 so IDirectInput8_EnumDevices doesn't leak like a sieve... */
|
||||
#include <dinput.h>
|
||||
#define COBJMACROS
|
||||
#include <wbemcli.h>
|
||||
#include <oleauto.h>
|
||||
#include <xinput.h>
|
||||
#include <devguid.h>
|
||||
#include <dbt.h>
|
||||
|
||||
|
||||
#ifndef XUSER_MAX_COUNT
|
||||
#define XUSER_MAX_COUNT 4
|
||||
#endif
|
||||
#ifndef XUSER_INDEX_ANY
|
||||
#define XUSER_INDEX_ANY 0x000000FF
|
||||
#endif
|
||||
#ifndef XINPUT_CAPS_FFB_SUPPORTED
|
||||
#define XINPUT_CAPS_FFB_SUPPORTED 0x0001
|
||||
#endif
|
||||
|
||||
|
||||
/* typedef's for XInput structs we use */
|
||||
typedef struct
|
||||
{
|
||||
WORD wButtons;
|
||||
BYTE bLeftTrigger;
|
||||
BYTE bRightTrigger;
|
||||
SHORT sThumbLX;
|
||||
SHORT sThumbLY;
|
||||
SHORT sThumbRX;
|
||||
SHORT sThumbRY;
|
||||
DWORD dwPaddingReserved;
|
||||
} XINPUT_GAMEPAD_EX;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DWORD dwPacketNumber;
|
||||
XINPUT_GAMEPAD_EX Gamepad;
|
||||
} XINPUT_STATE_EX;
|
||||
|
||||
/* Forward decl's for XInput API's we load dynamically and use if available */
|
||||
typedef DWORD (WINAPI *XInputGetState_t)
|
||||
(
|
||||
DWORD dwUserIndex, /* [in] Index of the gamer associated with the device */
|
||||
XINPUT_STATE_EX* pState /* [out] Receives the current state */
|
||||
);
|
||||
|
||||
typedef DWORD (WINAPI *XInputSetState_t)
|
||||
(
|
||||
DWORD dwUserIndex, /* [in] Index of the gamer associated with the device */
|
||||
XINPUT_VIBRATION* pVibration /* [in, out] The vibration information to send to the controller */
|
||||
);
|
||||
|
||||
typedef DWORD (WINAPI *XInputGetCapabilities_t)
|
||||
(
|
||||
DWORD dwUserIndex, /* [in] Index of the gamer associated with the device */
|
||||
DWORD dwFlags, /* [in] Input flags that identify the device type */
|
||||
XINPUT_CAPABILITIES* pCapabilities /* [out] Receives the capabilities */
|
||||
);
|
||||
|
||||
extern int WIN_LoadXInputDLL(void);
|
||||
extern void WIN_UnloadXInputDLL(void);
|
||||
|
||||
extern XInputGetState_t SDL_XInputGetState;
|
||||
extern XInputSetState_t SDL_XInputSetState;
|
||||
extern XInputGetCapabilities_t SDL_XInputGetCapabilities;
|
||||
extern DWORD SDL_XInputVersion; /* ((major << 16) & 0xFF00) | (minor & 0xFF) */
|
||||
|
||||
#define XINPUTGETSTATE SDL_XInputGetState
|
||||
#define XINPUTSETSTATE SDL_XInputSetState
|
||||
#define XINPUTGETCAPABILITIES SDL_XInputGetCapabilities
|
||||
#define INVALID_XINPUT_USERID XUSER_INDEX_ANY
|
||||
#define SDL_XINPUT_MAX_DEVICES XUSER_MAX_COUNT
|
||||
|
||||
#define MAX_INPUTS 256 /* each joystick can have up to 256 inputs */
|
||||
|
||||
|
||||
/* local types */
|
||||
typedef enum Type
|
||||
{ BUTTON, AXIS, HAT } Type;
|
||||
|
||||
typedef struct input_t
|
||||
{
|
||||
/* DirectInput offset for this input type: */
|
||||
DWORD ofs;
|
||||
|
||||
/* Button, axis or hat: */
|
||||
Type type;
|
||||
|
||||
/* SDL input offset: */
|
||||
Uint8 num;
|
||||
} input_t;
|
||||
|
||||
/* The private structure used to keep track of a joystick */
|
||||
struct joystick_hwdata
|
||||
{
|
||||
LPDIRECTINPUTDEVICE8 InputDevice;
|
||||
DIDEVCAPS Capabilities;
|
||||
int buffered;
|
||||
SDL_JoystickGUID guid;
|
||||
|
||||
input_t Inputs[MAX_INPUTS];
|
||||
int NumInputs;
|
||||
int NumSliders;
|
||||
Uint8 removed;
|
||||
Uint8 send_remove_event;
|
||||
Uint8 bXInputDevice; /* 1 if this device supports using the xinput API rather than DirectInput */
|
||||
Uint8 bXInputHaptic; /* Supports force feedback via XInput. */
|
||||
Uint8 userid; /* XInput userid index for this joystick */
|
||||
Uint8 currentXInputSlot; /* the current position to write to in XInputState below, used so we can compare old and new values */
|
||||
XINPUT_STATE_EX XInputState[2];
|
||||
};
|
||||
|
||||
#endif /* SDL_JOYSTICK_DINPUT_H */
|
||||
@@ -1,475 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifdef SDL_JOYSTICK_WINMM
|
||||
|
||||
/* Win32 MultiMedia Joystick driver, contributed by Andrei de A. Formiga */
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#include <mmsystem.h>
|
||||
#include <regstr.h>
|
||||
|
||||
#include "SDL_events.h"
|
||||
#include "SDL_joystick.h"
|
||||
#include "../SDL_sysjoystick.h"
|
||||
#include "../SDL_joystick_c.h"
|
||||
|
||||
#ifdef REGSTR_VAL_JOYOEMNAME
|
||||
#undef REGSTR_VAL_JOYOEMNAME
|
||||
#endif
|
||||
#define REGSTR_VAL_JOYOEMNAME "OEMName"
|
||||
|
||||
#define MAX_JOYSTICKS 16
|
||||
#define MAX_AXES 6 /* each joystick can have up to 6 axes */
|
||||
#define MAX_BUTTONS 32 /* and 32 buttons */
|
||||
#define AXIS_MIN -32768 /* minimum value for axis coordinate */
|
||||
#define AXIS_MAX 32767 /* maximum value for axis coordinate */
|
||||
/* limit axis to 256 possible positions to filter out noise */
|
||||
#define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/256)
|
||||
#define JOY_BUTTON_FLAG(n) (1<<n)
|
||||
|
||||
|
||||
/* array to hold joystick ID values */
|
||||
static UINT SYS_JoystickID[MAX_JOYSTICKS];
|
||||
static JOYCAPSA SYS_Joystick[MAX_JOYSTICKS];
|
||||
static char *SYS_JoystickName[MAX_JOYSTICKS];
|
||||
|
||||
/* The private structure used to keep track of a joystick */
|
||||
struct joystick_hwdata
|
||||
{
|
||||
/* joystick ID */
|
||||
UINT id;
|
||||
|
||||
/* values used to translate device-specific coordinates into
|
||||
SDL-standard ranges */
|
||||
struct _transaxis
|
||||
{
|
||||
int offset;
|
||||
float scale;
|
||||
} transaxis[6];
|
||||
};
|
||||
|
||||
/* Convert a Windows Multimedia API return code to a text message */
|
||||
static void SetMMerror(char *function, int code);
|
||||
|
||||
|
||||
static char *
|
||||
GetJoystickName(int index, const char *szRegKey)
|
||||
{
|
||||
/* added 7/24/2004 by Eckhard Stolberg */
|
||||
/*
|
||||
see if there is a joystick for the current
|
||||
index (1-16) listed in the registry
|
||||
*/
|
||||
char *name = NULL;
|
||||
HKEY hTopKey;
|
||||
HKEY hKey;
|
||||
DWORD regsize;
|
||||
LONG regresult;
|
||||
char regkey[256];
|
||||
char regvalue[256];
|
||||
char regname[256];
|
||||
|
||||
SDL_snprintf(regkey, SDL_arraysize(regkey), "%s\\%s\\%s",
|
||||
REGSTR_PATH_JOYCONFIG, szRegKey, REGSTR_KEY_JOYCURR);
|
||||
hTopKey = HKEY_LOCAL_MACHINE;
|
||||
regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey);
|
||||
if (regresult != ERROR_SUCCESS) {
|
||||
hTopKey = HKEY_CURRENT_USER;
|
||||
regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey);
|
||||
}
|
||||
if (regresult != ERROR_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* find the registry key name for the joystick's properties */
|
||||
regsize = sizeof(regname);
|
||||
SDL_snprintf(regvalue, SDL_arraysize(regvalue), "Joystick%d%s", index + 1,
|
||||
REGSTR_VAL_JOYOEMNAME);
|
||||
regresult =
|
||||
RegQueryValueExA(hKey, regvalue, 0, 0, (LPBYTE) regname, ®size);
|
||||
RegCloseKey(hKey);
|
||||
|
||||
if (regresult != ERROR_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* open that registry key */
|
||||
SDL_snprintf(regkey, SDL_arraysize(regkey), "%s\\%s", REGSTR_PATH_JOYOEM,
|
||||
regname);
|
||||
regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey);
|
||||
if (regresult != ERROR_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* find the size for the OEM name text */
|
||||
regsize = sizeof(regvalue);
|
||||
regresult =
|
||||
RegQueryValueExA(hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, NULL, ®size);
|
||||
if (regresult == ERROR_SUCCESS) {
|
||||
/* allocate enough memory for the OEM name text ... */
|
||||
name = (char *) SDL_malloc(regsize);
|
||||
if (name) {
|
||||
/* ... and read it from the registry */
|
||||
regresult = RegQueryValueExA(hKey,
|
||||
REGSTR_VAL_JOYOEMNAME, 0, 0,
|
||||
(LPBYTE) name, ®size);
|
||||
}
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
|
||||
return (name);
|
||||
}
|
||||
|
||||
static int SDL_SYS_numjoysticks = 0;
|
||||
|
||||
/* Function to scan the system for joysticks.
|
||||
* This function should set SDL_numjoysticks to the number of available
|
||||
* joysticks. Joystick 0 should be the system default joystick.
|
||||
* It should return 0, or -1 on an unrecoverable fatal error.
|
||||
*/
|
||||
int
|
||||
SDL_SYS_JoystickInit(void)
|
||||
{
|
||||
int i;
|
||||
int maxdevs;
|
||||
JOYINFOEX joyinfo;
|
||||
JOYCAPSA joycaps;
|
||||
MMRESULT result;
|
||||
|
||||
/* Reset the joystick ID & name mapping tables */
|
||||
for (i = 0; i < MAX_JOYSTICKS; ++i) {
|
||||
SYS_JoystickID[i] = 0;
|
||||
SYS_JoystickName[i] = NULL;
|
||||
}
|
||||
|
||||
/* Loop over all potential joystick devices */
|
||||
SDL_SYS_numjoysticks = 0;
|
||||
maxdevs = joyGetNumDevs();
|
||||
for (i = JOYSTICKID1; i < maxdevs && SDL_SYS_numjoysticks < MAX_JOYSTICKS; ++i) {
|
||||
|
||||
joyinfo.dwSize = sizeof(joyinfo);
|
||||
joyinfo.dwFlags = JOY_RETURNALL;
|
||||
result = joyGetPosEx(i, &joyinfo);
|
||||
if (result == JOYERR_NOERROR) {
|
||||
result = joyGetDevCapsA(i, &joycaps, sizeof(joycaps));
|
||||
if (result == JOYERR_NOERROR) {
|
||||
SYS_JoystickID[SDL_SYS_numjoysticks] = i;
|
||||
SYS_Joystick[SDL_SYS_numjoysticks] = joycaps;
|
||||
SYS_JoystickName[SDL_SYS_numjoysticks] =
|
||||
GetJoystickName(i, joycaps.szRegKey);
|
||||
SDL_SYS_numjoysticks++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (SDL_SYS_numjoysticks);
|
||||
}
|
||||
|
||||
int SDL_SYS_NumJoysticks()
|
||||
{
|
||||
return SDL_SYS_numjoysticks;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (SYS_JoystickName[device_index] != NULL) {
|
||||
return (SYS_JoystickName[device_index]);
|
||||
} else {
|
||||
return (SYS_Joystick[device_index].szPname);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
int index, i;
|
||||
int caps_flags[MAX_AXES - 2] =
|
||||
{ JOYCAPS_HASZ, JOYCAPS_HASR, JOYCAPS_HASU, JOYCAPS_HASV };
|
||||
int axis_min[MAX_AXES], axis_max[MAX_AXES];
|
||||
|
||||
|
||||
/* shortcut */
|
||||
index = device_index;
|
||||
axis_min[0] = SYS_Joystick[index].wXmin;
|
||||
axis_max[0] = SYS_Joystick[index].wXmax;
|
||||
axis_min[1] = SYS_Joystick[index].wYmin;
|
||||
axis_max[1] = SYS_Joystick[index].wYmax;
|
||||
axis_min[2] = SYS_Joystick[index].wZmin;
|
||||
axis_max[2] = SYS_Joystick[index].wZmax;
|
||||
axis_min[3] = SYS_Joystick[index].wRmin;
|
||||
axis_max[3] = SYS_Joystick[index].wRmax;
|
||||
axis_min[4] = SYS_Joystick[index].wUmin;
|
||||
axis_max[4] = SYS_Joystick[index].wUmax;
|
||||
axis_min[5] = SYS_Joystick[index].wVmin;
|
||||
axis_max[5] = SYS_Joystick[index].wVmax;
|
||||
|
||||
/* allocate memory for system specific hardware data */
|
||||
joystick->instance_id = device_index;
|
||||
joystick->hwdata =
|
||||
(struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata));
|
||||
if (joystick->hwdata == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
|
||||
|
||||
/* set hardware data */
|
||||
joystick->hwdata->id = SYS_JoystickID[index];
|
||||
for (i = 0; i < MAX_AXES; ++i) {
|
||||
if ((i < 2) || (SYS_Joystick[index].wCaps & caps_flags[i - 2])) {
|
||||
joystick->hwdata->transaxis[i].offset = AXIS_MIN - axis_min[i];
|
||||
joystick->hwdata->transaxis[i].scale =
|
||||
(float) (AXIS_MAX - AXIS_MIN) / (axis_max[i] - axis_min[i]);
|
||||
} else {
|
||||
joystick->hwdata->transaxis[i].offset = 0;
|
||||
joystick->hwdata->transaxis[i].scale = 1.0; /* Just in case */
|
||||
}
|
||||
}
|
||||
|
||||
/* fill nbuttons, naxes, and nhats fields */
|
||||
joystick->nbuttons = SYS_Joystick[index].wNumButtons;
|
||||
joystick->naxes = SYS_Joystick[index].wNumAxes;
|
||||
if (SYS_Joystick[index].wCaps & JOYCAPS_HASPOV) {
|
||||
joystick->nhats = 1;
|
||||
} else {
|
||||
joystick->nhats = 0;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
static Uint8
|
||||
TranslatePOV(DWORD value)
|
||||
{
|
||||
Uint8 pos;
|
||||
|
||||
pos = SDL_HAT_CENTERED;
|
||||
if (value != JOY_POVCENTERED) {
|
||||
if ((value > JOY_POVLEFT) || (value < JOY_POVRIGHT)) {
|
||||
pos |= SDL_HAT_UP;
|
||||
}
|
||||
if ((value > JOY_POVFORWARD) && (value < JOY_POVBACKWARD)) {
|
||||
pos |= SDL_HAT_RIGHT;
|
||||
}
|
||||
if ((value > JOY_POVRIGHT) && (value < JOY_POVLEFT)) {
|
||||
pos |= SDL_HAT_DOWN;
|
||||
}
|
||||
if (value > JOY_POVBACKWARD) {
|
||||
pos |= SDL_HAT_LEFT;
|
||||
}
|
||||
}
|
||||
return (pos);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
MMRESULT result;
|
||||
int i;
|
||||
DWORD flags[MAX_AXES] = { JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ,
|
||||
JOY_RETURNR, JOY_RETURNU, JOY_RETURNV
|
||||
};
|
||||
DWORD pos[MAX_AXES];
|
||||
struct _transaxis *transaxis;
|
||||
int value, change;
|
||||
JOYINFOEX joyinfo;
|
||||
|
||||
joyinfo.dwSize = sizeof(joyinfo);
|
||||
joyinfo.dwFlags = JOY_RETURNALL | JOY_RETURNPOVCTS;
|
||||
if (!joystick->hats) {
|
||||
joyinfo.dwFlags &= ~(JOY_RETURNPOV | JOY_RETURNPOVCTS);
|
||||
}
|
||||
result = joyGetPosEx(joystick->hwdata->id, &joyinfo);
|
||||
if (result != JOYERR_NOERROR) {
|
||||
SetMMerror("joyGetPosEx", result);
|
||||
return;
|
||||
}
|
||||
|
||||
/* joystick motion events */
|
||||
pos[0] = joyinfo.dwXpos;
|
||||
pos[1] = joyinfo.dwYpos;
|
||||
pos[2] = joyinfo.dwZpos;
|
||||
pos[3] = joyinfo.dwRpos;
|
||||
pos[4] = joyinfo.dwUpos;
|
||||
pos[5] = joyinfo.dwVpos;
|
||||
|
||||
transaxis = joystick->hwdata->transaxis;
|
||||
for (i = 0; i < joystick->naxes; i++) {
|
||||
if (joyinfo.dwFlags & flags[i]) {
|
||||
value =
|
||||
(int) (((float) pos[i] +
|
||||
transaxis[i].offset) * transaxis[i].scale);
|
||||
change = (value - joystick->axes[i]);
|
||||
if ((change < -JOY_AXIS_THRESHOLD)
|
||||
|| (change > JOY_AXIS_THRESHOLD)) {
|
||||
SDL_PrivateJoystickAxis(joystick, (Uint8) i, (Sint16) value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* joystick button events */
|
||||
if (joyinfo.dwFlags & JOY_RETURNBUTTONS) {
|
||||
for (i = 0; i < joystick->nbuttons; ++i) {
|
||||
if (joyinfo.dwButtons & JOY_BUTTON_FLAG(i)) {
|
||||
if (!joystick->buttons[i]) {
|
||||
SDL_PrivateJoystickButton(joystick, (Uint8) i,
|
||||
SDL_PRESSED);
|
||||
}
|
||||
} else {
|
||||
if (joystick->buttons[i]) {
|
||||
SDL_PrivateJoystickButton(joystick, (Uint8) i,
|
||||
SDL_RELEASED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* joystick hat events */
|
||||
if (joyinfo.dwFlags & JOY_RETURNPOV) {
|
||||
Uint8 pos;
|
||||
|
||||
pos = TranslatePOV(joyinfo.dwPOV);
|
||||
if (pos != joystick->hats[0]) {
|
||||
SDL_PrivateJoystickHat(joystick, 0, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Function to close a joystick after use */
|
||||
void
|
||||
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
||||
{
|
||||
/* free system specific hardware data */
|
||||
SDL_free(joystick->hwdata);
|
||||
joystick->hwdata = NULL;
|
||||
}
|
||||
|
||||
/* Function to perform any system-specific joystick related cleanup */
|
||||
void
|
||||
SDL_SYS_JoystickQuit(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAX_JOYSTICKS; i++) {
|
||||
SDL_free(SYS_JoystickName[i]);
|
||||
SYS_JoystickName[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/* implementation functions */
|
||||
void
|
||||
SetMMerror(char *function, int code)
|
||||
{
|
||||
static char *error;
|
||||
static char errbuf[1024];
|
||||
|
||||
errbuf[0] = 0;
|
||||
switch (code) {
|
||||
case MMSYSERR_NODRIVER:
|
||||
error = "Joystick driver not present";
|
||||
break;
|
||||
|
||||
case MMSYSERR_INVALPARAM:
|
||||
case JOYERR_PARMS:
|
||||
error = "Invalid parameter(s)";
|
||||
break;
|
||||
|
||||
case MMSYSERR_BADDEVICEID:
|
||||
error = "Bad device ID";
|
||||
break;
|
||||
|
||||
case JOYERR_UNPLUGGED:
|
||||
error = "Joystick not attached";
|
||||
break;
|
||||
|
||||
case JOYERR_NOCANDO:
|
||||
error = "Can't capture joystick input";
|
||||
break;
|
||||
|
||||
default:
|
||||
SDL_snprintf(errbuf, SDL_arraysize(errbuf),
|
||||
"%s: Unknown Multimedia system error: 0x%x",
|
||||
function, code);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!errbuf[0]) {
|
||||
SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function,
|
||||
error);
|
||||
}
|
||||
SDL_SetError("%s", errbuf);
|
||||
}
|
||||
|
||||
#endif /* SDL_JOYSTICK_WINMM */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifdef SDL_LOADSO_DLOPEN
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
/* System dependent library loading routines */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "SDL_loadso.h"
|
||||
|
||||
void *
|
||||
SDL_LoadObject(const char *sofile)
|
||||
{
|
||||
void *handle = dlopen(sofile, RTLD_NOW|RTLD_LOCAL);
|
||||
const char *loaderror = (char *) dlerror();
|
||||
if (handle == NULL) {
|
||||
SDL_SetError("Failed loading %s: %s", sofile, loaderror);
|
||||
}
|
||||
return (handle);
|
||||
}
|
||||
|
||||
void *
|
||||
SDL_LoadFunction(void *handle, const char *name)
|
||||
{
|
||||
void *symbol = dlsym(handle, name);
|
||||
if (symbol == NULL) {
|
||||
/* append an underscore for platforms that need that. */
|
||||
size_t len = 1 + SDL_strlen(name) + 1;
|
||||
char *_name = SDL_stack_alloc(char, len);
|
||||
_name[0] = '_';
|
||||
SDL_strlcpy(&_name[1], name, len);
|
||||
symbol = dlsym(handle, _name);
|
||||
SDL_stack_free(_name);
|
||||
if (symbol == NULL) {
|
||||
SDL_SetError("Failed loading %s: %s", name,
|
||||
(const char *) dlerror());
|
||||
}
|
||||
}
|
||||
return (symbol);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_UnloadObject(void *handle)
|
||||
{
|
||||
if (handle != NULL) {
|
||||
dlclose(handle);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_LOADSO_DLOPEN */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#if defined(SDL_LOADSO_DUMMY) || defined(SDL_LOADSO_DISABLED)
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
/* System dependent library loading routines */
|
||||
|
||||
#include "SDL_loadso.h"
|
||||
|
||||
void *
|
||||
SDL_LoadObject(const char *sofile)
|
||||
{
|
||||
const char *loaderror = "SDL_LoadObject() not implemented";
|
||||
SDL_SetError("Failed loading %s: %s", sofile, loaderror);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
void *
|
||||
SDL_LoadFunction(void *handle, const char *name)
|
||||
{
|
||||
const char *loaderror = "SDL_LoadFunction() not implemented";
|
||||
SDL_SetError("Failed loading %s: %s", name, loaderror);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_UnloadObject(void *handle)
|
||||
{
|
||||
/* no-op. */
|
||||
}
|
||||
|
||||
#endif /* SDL_LOADSO_DUMMY || SDL_LOADSO_DISABLED */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifdef SDL_LOADSO_HAIKU
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
/* System dependent library loading routines */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <os/kernel/image.h>
|
||||
|
||||
#include "SDL_loadso.h"
|
||||
|
||||
void *
|
||||
SDL_LoadObject(const char *sofile)
|
||||
{
|
||||
void *handle = NULL;
|
||||
image_id library_id = load_add_on(sofile);
|
||||
if (library_id < 0) {
|
||||
SDL_SetError(strerror((int) library_id));
|
||||
} else {
|
||||
handle = (void *) (library_id);
|
||||
}
|
||||
return (handle);
|
||||
}
|
||||
|
||||
void *
|
||||
SDL_LoadFunction(void *handle, const char *name)
|
||||
{
|
||||
void *sym = NULL;
|
||||
image_id library_id = (image_id) handle;
|
||||
status_t rc =
|
||||
get_image_symbol(library_id, name, B_SYMBOL_TYPE_TEXT, &sym);
|
||||
if (rc != B_NO_ERROR) {
|
||||
SDL_SetError(strerror(rc));
|
||||
}
|
||||
return (sym);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_UnloadObject(void *handle)
|
||||
{
|
||||
image_id library_id;
|
||||
if (handle != NULL) {
|
||||
library_id = (image_id) handle;
|
||||
unload_add_on(library_id);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_LOADSO_HAIKU */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifdef SDL_LOADSO_WINDOWS
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
/* System dependent library loading routines */
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
|
||||
#include "SDL_loadso.h"
|
||||
|
||||
void *
|
||||
SDL_LoadObject(const char *sofile)
|
||||
{
|
||||
LPTSTR tstr = WIN_UTF8ToString(sofile);
|
||||
void *handle = (void *) LoadLibrary(tstr);
|
||||
SDL_free(tstr);
|
||||
|
||||
/* Generate an error message if all loads failed */
|
||||
if (handle == NULL) {
|
||||
char errbuf[512];
|
||||
SDL_strlcpy(errbuf, "Failed loading ", SDL_arraysize(errbuf));
|
||||
SDL_strlcat(errbuf, sofile, SDL_arraysize(errbuf));
|
||||
WIN_SetError(errbuf);
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
void *
|
||||
SDL_LoadFunction(void *handle, const char *name)
|
||||
{
|
||||
void *symbol = (void *) GetProcAddress((HMODULE) handle, name);
|
||||
if (symbol == NULL) {
|
||||
char errbuf[512];
|
||||
SDL_strlcpy(errbuf, "Failed loading ", SDL_arraysize(errbuf));
|
||||
SDL_strlcat(errbuf, name, SDL_arraysize(errbuf));
|
||||
WIN_SetError(errbuf);
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_UnloadObject(void *handle)
|
||||
{
|
||||
if (handle != NULL) {
|
||||
FreeLibrary((HMODULE) handle);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_LOADSO_WINDOWS */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_main.h"
|
||||
#include <pspkernel.h>
|
||||
#include <pspdebug.h>
|
||||
#include <pspsdk.h>
|
||||
#include <pspthreadman.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* If application's main() is redefined as SDL_main, and libSDLmain is
|
||||
linked, then this file will create the standard exit callback,
|
||||
define the PSP_MODULE_INFO macro, and exit back to the browser when
|
||||
the program is finished.
|
||||
|
||||
You can still override other parameters in your own code if you
|
||||
desire, such as PSP_HEAP_SIZE_KB, PSP_MAIN_THREAD_ATTR,
|
||||
PSP_MAIN_THREAD_STACK_SIZE, etc.
|
||||
*/
|
||||
|
||||
PSP_MODULE_INFO("SDL App", 0, 1, 1);
|
||||
|
||||
int sdl_psp_exit_callback(int arg1, int arg2, void *common)
|
||||
{
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sdl_psp_callback_thread(SceSize args, void *argp)
|
||||
{
|
||||
int cbid;
|
||||
cbid = sceKernelCreateCallback("Exit Callback",
|
||||
sdl_psp_exit_callback, NULL);
|
||||
sceKernelRegisterExitCallback(cbid);
|
||||
sceKernelSleepThreadCB();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sdl_psp_setup_callbacks(void)
|
||||
{
|
||||
int thid = 0;
|
||||
thid = sceKernelCreateThread("update_thread",
|
||||
sdl_psp_callback_thread, 0x11, 0xFA0, 0, 0);
|
||||
if(thid >= 0)
|
||||
sceKernelStartThread(thid, 0, 0);
|
||||
return thid;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
pspDebugScreenInit();
|
||||
sdl_psp_setup_callbacks();
|
||||
|
||||
/* Register sceKernelExitGame() to be called when we exit */
|
||||
atexit(sceKernelExitGame);
|
||||
|
||||
SDL_SetMainReady();
|
||||
|
||||
(void)SDL_main(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
|
||||
#include "winresrc.h"
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 2,0,1,0
|
||||
PRODUCTVERSION 2,0,1,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
FILEFLAGS 0x0L
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "\0"
|
||||
VALUE "FileDescription", "SDL\0"
|
||||
VALUE "FileVersion", "2, 0, 1, 0\0"
|
||||
VALUE "InternalName", "SDL\0"
|
||||
VALUE "LegalCopyright", "Copyright © 2013 Sam Lantinga\0"
|
||||
VALUE "OriginalFilename", "SDL2.dll\0"
|
||||
VALUE "ProductName", "Simple DirectMedia Layer\0"
|
||||
VALUE "ProductVersion", "2, 0, 1, 0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifndef SDL_POWER_DISABLED
|
||||
#if SDL_POWER_ANDROID
|
||||
|
||||
#include "SDL_power.h"
|
||||
|
||||
#include "../../core/android/SDL_android.h"
|
||||
|
||||
SDL_bool
|
||||
SDL_GetPowerInfo_Android(SDL_PowerState * state, int *seconds, int *percent)
|
||||
{
|
||||
int battery;
|
||||
int plugged;
|
||||
int charged;
|
||||
|
||||
if (Android_JNI_GetPowerInfo(&plugged, &charged, &battery, seconds, percent) != -1) {
|
||||
if (plugged) {
|
||||
if (charged) {
|
||||
*state = SDL_POWERSTATE_CHARGED;
|
||||
} else if (battery) {
|
||||
*state = SDL_POWERSTATE_CHARGING;
|
||||
} else {
|
||||
*state = SDL_POWERSTATE_NO_BATTERY;
|
||||
*seconds = -1;
|
||||
*percent = -1;
|
||||
}
|
||||
} else {
|
||||
*state = SDL_POWERSTATE_ON_BATTERY;
|
||||
}
|
||||
} else {
|
||||
*state = SDL_POWERSTATE_UNKNOWN;
|
||||
*seconds = -1;
|
||||
*percent = -1;
|
||||
}
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
#endif /* SDL_POWER_ANDROID */
|
||||
#endif /* SDL_POWER_DISABLED */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,126 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
/* !!! FIXME: does this thing even work on Haiku? */
|
||||
#ifndef SDL_POWER_DISABLED
|
||||
#if SDL_POWER_HAIKU
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <drivers/Drivers.h>
|
||||
|
||||
/* These values are from apm.h ... */
|
||||
#define APM_DEVICE_PATH "/dev/misc/apm"
|
||||
#define APM_FUNC_OFFSET 0x5300
|
||||
#define APM_FUNC_GET_POWER_STATUS 10
|
||||
#define APM_DEVICE_ALL 1
|
||||
#define APM_BIOS_CALL (B_DEVICE_OP_CODES_END + 3)
|
||||
|
||||
#include "SDL_power.h"
|
||||
|
||||
SDL_bool
|
||||
SDL_GetPowerInfo_Haiku(SDL_PowerState * state, int *seconds, int *percent)
|
||||
{
|
||||
const int fd = open("/dev/misc/apm", O_RDONLY);
|
||||
SDL_bool need_details = SDL_FALSE;
|
||||
uint16 regs[6];
|
||||
uint8 ac_status;
|
||||
uint8 battery_status;
|
||||
uint8 battery_flags;
|
||||
uint8 battery_life;
|
||||
uint32 battery_time;
|
||||
int rc;
|
||||
|
||||
if (fd == -1) {
|
||||
return SDL_FALSE; /* maybe some other method will work? */
|
||||
}
|
||||
|
||||
memset(regs, '\0', sizeof(regs));
|
||||
regs[0] = APM_FUNC_OFFSET + APM_FUNC_GET_POWER_STATUS;
|
||||
regs[1] = APM_DEVICE_ALL;
|
||||
rc = ioctl(fd, APM_BIOS_CALL, regs);
|
||||
close(fd);
|
||||
|
||||
if (rc < 0) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
ac_status = regs[1] >> 8;
|
||||
battery_status = regs[1] & 0xFF;
|
||||
battery_flags = regs[2] >> 8;
|
||||
battery_life = regs[2] & 0xFF;
|
||||
battery_time = (uint32) regs[3];
|
||||
|
||||
/* in theory, _something_ should be set in battery_flags, right? */
|
||||
if (battery_flags == 0x00) { /* older APM BIOS? Less fields. */
|
||||
battery_time = 0xFFFF;
|
||||
if (battery_status == 0xFF) {
|
||||
battery_flags = 0xFF;
|
||||
} else {
|
||||
battery_flags = (1 << battery_status);
|
||||
}
|
||||
}
|
||||
|
||||
if ((battery_time != 0xFFFF) && (battery_time & (1 << 15))) {
|
||||
/* time is in minutes, not seconds */
|
||||
battery_time = (battery_time & 0x7FFF) * 60;
|
||||
}
|
||||
|
||||
if (battery_flags == 0xFF) { /* unknown state */
|
||||
*state = SDL_POWERSTATE_UNKNOWN;
|
||||
} else if (battery_flags & (1 << 7)) { /* no battery */
|
||||
*state = SDL_POWERSTATE_NO_BATTERY;
|
||||
} else if (battery_flags & (1 << 3)) { /* charging */
|
||||
*state = SDL_POWERSTATE_CHARGING;
|
||||
need_details = SDL_TRUE;
|
||||
} else if (ac_status == 1) {
|
||||
*state = SDL_POWERSTATE_CHARGED; /* on AC, not charging. */
|
||||
need_details = SDL_TRUE;
|
||||
} else {
|
||||
*state = SDL_POWERSTATE_ON_BATTERY; /* not on AC. */
|
||||
need_details = SDL_TRUE;
|
||||
}
|
||||
|
||||
*percent = -1;
|
||||
*seconds = -1;
|
||||
if (need_details) {
|
||||
const int pct = (int) battery_life;
|
||||
const int secs = (int) battery_time;
|
||||
|
||||
if (pct != 255) { /* 255 == unknown */
|
||||
*percent = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */
|
||||
}
|
||||
if (secs != 0xFFFF) { /* 0xFFFF == unknown */
|
||||
*seconds = secs;
|
||||
}
|
||||
}
|
||||
|
||||
return SDL_TRUE; /* the definitive answer if APM driver replied. */
|
||||
}
|
||||
|
||||
#endif /* SDL_POWER_HAIKU */
|
||||
#endif /* SDL_POWER_DISABLED */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,429 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifndef SDL_POWER_DISABLED
|
||||
#if SDL_POWER_LINUX
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "SDL_power.h"
|
||||
|
||||
static const char *proc_apm_path = "/proc/apm";
|
||||
static const char *proc_acpi_battery_path = "/proc/acpi/battery";
|
||||
static const char *proc_acpi_ac_adapter_path = "/proc/acpi/ac_adapter";
|
||||
|
||||
static int open_acpi_file(const char *base, const char *node, const char *key)
|
||||
{
|
||||
const size_t pathlen = strlen(base) + strlen(node) + strlen(key) + 3;
|
||||
char *path = (char *) alloca(pathlen);
|
||||
if (path == NULL) {
|
||||
return -1; /* oh well. */
|
||||
}
|
||||
|
||||
snprintf(path, pathlen, "%s/%s/%s", base, node, key);
|
||||
return open(path, O_RDONLY);
|
||||
}
|
||||
|
||||
|
||||
static SDL_bool
|
||||
load_acpi_file(const char *base, const char *node, const char *key,
|
||||
char *buf, size_t buflen)
|
||||
{
|
||||
ssize_t br = 0;
|
||||
const int fd = open_acpi_file(base, node, key);
|
||||
if (fd == -1) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
br = read(fd, buf, buflen-1);
|
||||
close(fd);
|
||||
if (br < 0) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
buf[br] = '\0'; /* null-terminate the string. */
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static SDL_bool
|
||||
make_proc_acpi_key_val(char **_ptr, char **_key, char **_val)
|
||||
{
|
||||
char *ptr = *_ptr;
|
||||
|
||||
while (*ptr == ' ') {
|
||||
ptr++; /* skip whitespace. */
|
||||
}
|
||||
|
||||
if (*ptr == '\0') {
|
||||
return SDL_FALSE; /* EOF. */
|
||||
}
|
||||
|
||||
*_key = ptr;
|
||||
|
||||
while ((*ptr != ':') && (*ptr != '\0')) {
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if (*ptr == '\0') {
|
||||
return SDL_FALSE; /* (unexpected) EOF. */
|
||||
}
|
||||
|
||||
*(ptr++) = '\0'; /* terminate the key. */
|
||||
|
||||
while ((*ptr == ' ') && (*ptr != '\0')) {
|
||||
ptr++; /* skip whitespace. */
|
||||
}
|
||||
|
||||
if (*ptr == '\0') {
|
||||
return SDL_FALSE; /* (unexpected) EOF. */
|
||||
}
|
||||
|
||||
*_val = ptr;
|
||||
|
||||
while ((*ptr != '\n') && (*ptr != '\0')) {
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if (*ptr != '\0') {
|
||||
*(ptr++) = '\0'; /* terminate the value. */
|
||||
}
|
||||
|
||||
*_ptr = ptr; /* store for next time. */
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
check_proc_acpi_battery(const char * node, SDL_bool * have_battery,
|
||||
SDL_bool * charging, int *seconds, int *percent)
|
||||
{
|
||||
const char *base = proc_acpi_battery_path;
|
||||
char info[1024];
|
||||
char state[1024];
|
||||
char *ptr = NULL;
|
||||
char *key = NULL;
|
||||
char *val = NULL;
|
||||
SDL_bool charge = SDL_FALSE;
|
||||
SDL_bool choose = SDL_FALSE;
|
||||
int maximum = -1;
|
||||
int remaining = -1;
|
||||
int secs = -1;
|
||||
int pct = -1;
|
||||
|
||||
if (!load_acpi_file(base, node, "state", state, sizeof (state))) {
|
||||
return;
|
||||
} else if (!load_acpi_file(base, node, "info", info, sizeof (info))) {
|
||||
return;
|
||||
}
|
||||
|
||||
ptr = &state[0];
|
||||
while (make_proc_acpi_key_val(&ptr, &key, &val)) {
|
||||
if (strcmp(key, "present") == 0) {
|
||||
if (strcmp(val, "yes") == 0) {
|
||||
*have_battery = SDL_TRUE;
|
||||
}
|
||||
} else if (strcmp(key, "charging state") == 0) {
|
||||
/* !!! FIXME: what exactly _does_ charging/discharging mean? */
|
||||
if (strcmp(val, "charging/discharging") == 0) {
|
||||
charge = SDL_TRUE;
|
||||
} else if (strcmp(val, "charging") == 0) {
|
||||
charge = SDL_TRUE;
|
||||
}
|
||||
} else if (strcmp(key, "remaining capacity") == 0) {
|
||||
char *endptr = NULL;
|
||||
const int cvt = (int) strtol(val, &endptr, 10);
|
||||
if (*endptr == ' ') {
|
||||
remaining = cvt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ptr = &info[0];
|
||||
while (make_proc_acpi_key_val(&ptr, &key, &val)) {
|
||||
if (strcmp(key, "design capacity") == 0) {
|
||||
char *endptr = NULL;
|
||||
const int cvt = (int) strtol(val, &endptr, 10);
|
||||
if (*endptr == ' ') {
|
||||
maximum = cvt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((maximum >= 0) && (remaining >= 0)) {
|
||||
pct = (int) ((((float) remaining) / ((float) maximum)) * 100.0f);
|
||||
if (pct < 0) {
|
||||
pct = 0;
|
||||
} else if (pct > 100) {
|
||||
pct = 100;
|
||||
}
|
||||
}
|
||||
|
||||
/* !!! FIXME: calculate (secs). */
|
||||
|
||||
/*
|
||||
* We pick the battery that claims to have the most minutes left.
|
||||
* (failing a report of minutes, we'll take the highest percent.)
|
||||
*/
|
||||
if ((secs < 0) && (*seconds < 0)) {
|
||||
if ((pct < 0) && (*percent < 0)) {
|
||||
choose = SDL_TRUE; /* at least we know there's a battery. */
|
||||
}
|
||||
if (pct > *percent) {
|
||||
choose = SDL_TRUE;
|
||||
}
|
||||
} else if (secs > *seconds) {
|
||||
choose = SDL_TRUE;
|
||||
}
|
||||
|
||||
if (choose) {
|
||||
*seconds = secs;
|
||||
*percent = pct;
|
||||
*charging = charge;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
check_proc_acpi_ac_adapter(const char * node, SDL_bool * have_ac)
|
||||
{
|
||||
const char *base = proc_acpi_ac_adapter_path;
|
||||
char state[256];
|
||||
char *ptr = NULL;
|
||||
char *key = NULL;
|
||||
char *val = NULL;
|
||||
|
||||
if (!load_acpi_file(base, node, "state", state, sizeof (state))) {
|
||||
return;
|
||||
}
|
||||
|
||||
ptr = &state[0];
|
||||
while (make_proc_acpi_key_val(&ptr, &key, &val)) {
|
||||
if (strcmp(key, "state") == 0) {
|
||||
if (strcmp(val, "on-line") == 0) {
|
||||
*have_ac = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SDL_bool
|
||||
SDL_GetPowerInfo_Linux_proc_acpi(SDL_PowerState * state,
|
||||
int *seconds, int *percent)
|
||||
{
|
||||
struct dirent *dent = NULL;
|
||||
DIR *dirp = NULL;
|
||||
SDL_bool have_battery = SDL_FALSE;
|
||||
SDL_bool have_ac = SDL_FALSE;
|
||||
SDL_bool charging = SDL_FALSE;
|
||||
|
||||
*seconds = -1;
|
||||
*percent = -1;
|
||||
*state = SDL_POWERSTATE_UNKNOWN;
|
||||
|
||||
dirp = opendir(proc_acpi_battery_path);
|
||||
if (dirp == NULL) {
|
||||
return SDL_FALSE; /* can't use this interface. */
|
||||
} else {
|
||||
while ((dent = readdir(dirp)) != NULL) {
|
||||
const char *node = dent->d_name;
|
||||
check_proc_acpi_battery(node, &have_battery, &charging,
|
||||
seconds, percent);
|
||||
}
|
||||
closedir(dirp);
|
||||
}
|
||||
|
||||
dirp = opendir(proc_acpi_ac_adapter_path);
|
||||
if (dirp == NULL) {
|
||||
return SDL_FALSE; /* can't use this interface. */
|
||||
} else {
|
||||
while ((dent = readdir(dirp)) != NULL) {
|
||||
const char *node = dent->d_name;
|
||||
check_proc_acpi_ac_adapter(node, &have_ac);
|
||||
}
|
||||
closedir(dirp);
|
||||
}
|
||||
|
||||
if (!have_battery) {
|
||||
*state = SDL_POWERSTATE_NO_BATTERY;
|
||||
} else if (charging) {
|
||||
*state = SDL_POWERSTATE_CHARGING;
|
||||
} else if (have_ac) {
|
||||
*state = SDL_POWERSTATE_CHARGED;
|
||||
} else {
|
||||
*state = SDL_POWERSTATE_ON_BATTERY;
|
||||
}
|
||||
|
||||
return SDL_TRUE; /* definitive answer. */
|
||||
}
|
||||
|
||||
|
||||
static SDL_bool
|
||||
next_string(char **_ptr, char **_str)
|
||||
{
|
||||
char *ptr = *_ptr;
|
||||
char *str = *_str;
|
||||
|
||||
while (*ptr == ' ') { /* skip any spaces... */
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if (*ptr == '\0') {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
str = ptr;
|
||||
while ((*ptr != ' ') && (*ptr != '\n') && (*ptr != '\0'))
|
||||
ptr++;
|
||||
|
||||
if (*ptr != '\0')
|
||||
*(ptr++) = '\0';
|
||||
|
||||
*_str = str;
|
||||
*_ptr = ptr;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
int_string(char *str, int *val)
|
||||
{
|
||||
char *endptr = NULL;
|
||||
*val = (int) strtol(str, &endptr, 0);
|
||||
return ((*str != '\0') && (*endptr == '\0'));
|
||||
}
|
||||
|
||||
/* http://lxr.linux.no/linux+v2.6.29/drivers/char/apm-emulation.c */
|
||||
SDL_bool
|
||||
SDL_GetPowerInfo_Linux_proc_apm(SDL_PowerState * state,
|
||||
int *seconds, int *percent)
|
||||
{
|
||||
SDL_bool need_details = SDL_FALSE;
|
||||
int ac_status = 0;
|
||||
int battery_status = 0;
|
||||
int battery_flag = 0;
|
||||
int battery_percent = 0;
|
||||
int battery_time = 0;
|
||||
const int fd = open(proc_apm_path, O_RDONLY);
|
||||
char buf[128];
|
||||
char *ptr = &buf[0];
|
||||
char *str = NULL;
|
||||
ssize_t br;
|
||||
|
||||
if (fd == -1) {
|
||||
return SDL_FALSE; /* can't use this interface. */
|
||||
}
|
||||
|
||||
br = read(fd, buf, sizeof (buf) - 1);
|
||||
close(fd);
|
||||
|
||||
if (br < 0) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
buf[br] = '\0'; /* null-terminate the string. */
|
||||
if (!next_string(&ptr, &str)) { /* driver version */
|
||||
return SDL_FALSE;
|
||||
}
|
||||
if (!next_string(&ptr, &str)) { /* BIOS version */
|
||||
return SDL_FALSE;
|
||||
}
|
||||
if (!next_string(&ptr, &str)) { /* APM flags */
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!next_string(&ptr, &str)) { /* AC line status */
|
||||
return SDL_FALSE;
|
||||
} else if (!int_string(str, &ac_status)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!next_string(&ptr, &str)) { /* battery status */
|
||||
return SDL_FALSE;
|
||||
} else if (!int_string(str, &battery_status)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
if (!next_string(&ptr, &str)) { /* battery flag */
|
||||
return SDL_FALSE;
|
||||
} else if (!int_string(str, &battery_flag)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
if (!next_string(&ptr, &str)) { /* remaining battery life percent */
|
||||
return SDL_FALSE;
|
||||
}
|
||||
if (str[strlen(str) - 1] == '%') {
|
||||
str[strlen(str) - 1] = '\0';
|
||||
}
|
||||
if (!int_string(str, &battery_percent)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!next_string(&ptr, &str)) { /* remaining battery life time */
|
||||
return SDL_FALSE;
|
||||
} else if (!int_string(str, &battery_time)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!next_string(&ptr, &str)) { /* remaining battery life time units */
|
||||
return SDL_FALSE;
|
||||
} else if (strcmp(str, "min") == 0) {
|
||||
battery_time *= 60;
|
||||
}
|
||||
|
||||
if (battery_flag == 0xFF) { /* unknown state */
|
||||
*state = SDL_POWERSTATE_UNKNOWN;
|
||||
} else if (battery_flag & (1 << 7)) { /* no battery */
|
||||
*state = SDL_POWERSTATE_NO_BATTERY;
|
||||
} else if (battery_flag & (1 << 3)) { /* charging */
|
||||
*state = SDL_POWERSTATE_CHARGING;
|
||||
need_details = SDL_TRUE;
|
||||
} else if (ac_status == 1) {
|
||||
*state = SDL_POWERSTATE_CHARGED; /* on AC, not charging. */
|
||||
need_details = SDL_TRUE;
|
||||
} else {
|
||||
*state = SDL_POWERSTATE_ON_BATTERY;
|
||||
need_details = SDL_TRUE;
|
||||
}
|
||||
|
||||
*percent = -1;
|
||||
*seconds = -1;
|
||||
if (need_details) {
|
||||
const int pct = battery_percent;
|
||||
const int secs = battery_time;
|
||||
|
||||
if (pct >= 0) { /* -1 == unknown */
|
||||
*percent = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */
|
||||
}
|
||||
if (secs >= 0) { /* -1 == unknown */
|
||||
*seconds = secs;
|
||||
}
|
||||
}
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
#endif /* SDL_POWER_LINUX */
|
||||
#endif /* SDL_POWER_DISABLED */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,192 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifndef SDL_POWER_DISABLED
|
||||
#if SDL_POWER_MACOSX
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <IOKit/ps/IOPowerSources.h>
|
||||
#include <IOKit/ps/IOPSKeys.h>
|
||||
|
||||
#include "SDL_power.h"
|
||||
|
||||
/* Carbon is so verbose... */
|
||||
#define STRMATCH(a,b) (CFStringCompare(a, b, 0) == kCFCompareEqualTo)
|
||||
#define GETVAL(k,v) \
|
||||
CFDictionaryGetValueIfPresent(dict, CFSTR(k), (const void **) v)
|
||||
|
||||
/* Note that AC power sources also include a laptop battery it is charging. */
|
||||
static void
|
||||
checkps(CFDictionaryRef dict, SDL_bool * have_ac, SDL_bool * have_battery,
|
||||
SDL_bool * charging, int *seconds, int *percent)
|
||||
{
|
||||
CFStringRef strval; /* don't CFRelease() this. */
|
||||
CFBooleanRef bval;
|
||||
CFNumberRef numval;
|
||||
SDL_bool charge = SDL_FALSE;
|
||||
SDL_bool choose = SDL_FALSE;
|
||||
SDL_bool is_ac = SDL_FALSE;
|
||||
int secs = -1;
|
||||
int maxpct = -1;
|
||||
int pct = -1;
|
||||
|
||||
if ((GETVAL(kIOPSIsPresentKey, &bval)) && (bval == kCFBooleanFalse)) {
|
||||
return; /* nothing to see here. */
|
||||
}
|
||||
|
||||
if (!GETVAL(kIOPSPowerSourceStateKey, &strval)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (STRMATCH(strval, CFSTR(kIOPSACPowerValue))) {
|
||||
is_ac = *have_ac = SDL_TRUE;
|
||||
} else if (!STRMATCH(strval, CFSTR(kIOPSBatteryPowerValue))) {
|
||||
return; /* not a battery? */
|
||||
}
|
||||
|
||||
if ((GETVAL(kIOPSIsChargingKey, &bval)) && (bval == kCFBooleanTrue)) {
|
||||
charge = SDL_TRUE;
|
||||
}
|
||||
|
||||
if (GETVAL(kIOPSMaxCapacityKey, &numval)) {
|
||||
SInt32 val = -1;
|
||||
CFNumberGetValue(numval, kCFNumberSInt32Type, &val);
|
||||
if (val > 0) {
|
||||
*have_battery = SDL_TRUE;
|
||||
maxpct = (int) val;
|
||||
}
|
||||
}
|
||||
|
||||
if (GETVAL(kIOPSMaxCapacityKey, &numval)) {
|
||||
SInt32 val = -1;
|
||||
CFNumberGetValue(numval, kCFNumberSInt32Type, &val);
|
||||
if (val > 0) {
|
||||
*have_battery = SDL_TRUE;
|
||||
maxpct = (int) val;
|
||||
}
|
||||
}
|
||||
|
||||
if (GETVAL(kIOPSTimeToEmptyKey, &numval)) {
|
||||
SInt32 val = -1;
|
||||
CFNumberGetValue(numval, kCFNumberSInt32Type, &val);
|
||||
|
||||
/* Mac OS X reports 0 minutes until empty if you're plugged in. :( */
|
||||
if ((val == 0) && (is_ac)) {
|
||||
val = -1; /* !!! FIXME: calc from timeToFull and capacity? */
|
||||
}
|
||||
|
||||
secs = (int) val;
|
||||
if (secs > 0) {
|
||||
secs *= 60; /* value is in minutes, so convert to seconds. */
|
||||
}
|
||||
}
|
||||
|
||||
if (GETVAL(kIOPSCurrentCapacityKey, &numval)) {
|
||||
SInt32 val = -1;
|
||||
CFNumberGetValue(numval, kCFNumberSInt32Type, &val);
|
||||
pct = (int) val;
|
||||
}
|
||||
|
||||
if ((pct > 0) && (maxpct > 0)) {
|
||||
pct = (int) ((((double) pct) / ((double) maxpct)) * 100.0);
|
||||
}
|
||||
|
||||
if (pct > 100) {
|
||||
pct = 100;
|
||||
}
|
||||
|
||||
/*
|
||||
* We pick the battery that claims to have the most minutes left.
|
||||
* (failing a report of minutes, we'll take the highest percent.)
|
||||
*/
|
||||
if ((secs < 0) && (*seconds < 0)) {
|
||||
if ((pct < 0) && (*percent < 0)) {
|
||||
choose = SDL_TRUE; /* at least we know there's a battery. */
|
||||
}
|
||||
if (pct > *percent) {
|
||||
choose = SDL_TRUE;
|
||||
}
|
||||
} else if (secs > *seconds) {
|
||||
choose = SDL_TRUE;
|
||||
}
|
||||
|
||||
if (choose) {
|
||||
*seconds = secs;
|
||||
*percent = pct;
|
||||
*charging = charge;
|
||||
}
|
||||
}
|
||||
|
||||
#undef GETVAL
|
||||
#undef STRMATCH
|
||||
|
||||
|
||||
SDL_bool
|
||||
SDL_GetPowerInfo_MacOSX(SDL_PowerState * state, int *seconds, int *percent)
|
||||
{
|
||||
CFTypeRef blob = IOPSCopyPowerSourcesInfo();
|
||||
|
||||
*seconds = -1;
|
||||
*percent = -1;
|
||||
*state = SDL_POWERSTATE_UNKNOWN;
|
||||
|
||||
if (blob != NULL) {
|
||||
CFArrayRef list = IOPSCopyPowerSourcesList(blob);
|
||||
if (list != NULL) {
|
||||
/* don't CFRelease() the list items, or dictionaries! */
|
||||
SDL_bool have_ac = SDL_FALSE;
|
||||
SDL_bool have_battery = SDL_FALSE;
|
||||
SDL_bool charging = SDL_FALSE;
|
||||
const CFIndex total = CFArrayGetCount(list);
|
||||
CFIndex i;
|
||||
for (i = 0; i < total; i++) {
|
||||
CFTypeRef ps = (CFTypeRef) CFArrayGetValueAtIndex(list, i);
|
||||
CFDictionaryRef dict =
|
||||
IOPSGetPowerSourceDescription(blob, ps);
|
||||
if (dict != NULL) {
|
||||
checkps(dict, &have_ac, &have_battery, &charging,
|
||||
seconds, percent);
|
||||
}
|
||||
}
|
||||
|
||||
if (!have_battery) {
|
||||
*state = SDL_POWERSTATE_NO_BATTERY;
|
||||
} else if (charging) {
|
||||
*state = SDL_POWERSTATE_CHARGING;
|
||||
} else if (have_ac) {
|
||||
*state = SDL_POWERSTATE_CHARGED;
|
||||
} else {
|
||||
*state = SDL_POWERSTATE_ON_BATTERY;
|
||||
}
|
||||
|
||||
CFRelease(list);
|
||||
}
|
||||
CFRelease(blob);
|
||||
}
|
||||
|
||||
return SDL_TRUE; /* always the definitive answer on Mac OS X. */
|
||||
}
|
||||
|
||||
#endif /* SDL_POWER_MACOSX */
|
||||
#endif /* SDL_POWER_DISABLED */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifndef SDL_POWER_DISABLED
|
||||
#if SDL_POWER_PSP
|
||||
|
||||
#include "SDL_power.h"
|
||||
#include <psppower.h>
|
||||
|
||||
|
||||
SDL_bool
|
||||
SDL_GetPowerInfo_PSP(SDL_PowerState * state, int *seconds,
|
||||
int *percent)
|
||||
{
|
||||
int battery = scePowerIsBatteryExist();
|
||||
int plugged = scePowerIsPowerOnline();
|
||||
int charging = scePowerIsBatteryCharging();
|
||||
|
||||
*state = SDL_POWERSTATE_UNKNOWN;
|
||||
*seconds = -1;
|
||||
*percent = -1;
|
||||
|
||||
if (!battery) {
|
||||
*state = SDL_POWERSTATE_NO_BATTERY;
|
||||
*seconds = -1;
|
||||
*percent = -1;
|
||||
} else if (charging) {
|
||||
*state = SDL_POWERSTATE_CHARGING;
|
||||
*percent = scePowerGetBatteryLifePercent();
|
||||
*seconds = scePowerGetBatteryLifeTime()*60;
|
||||
} else if (plugged) {
|
||||
*state = SDL_POWERSTATE_CHARGED;
|
||||
*percent = scePowerGetBatteryLifePercent();
|
||||
*seconds = scePowerGetBatteryLifeTime()*60;
|
||||
} else {
|
||||
*state = SDL_POWERSTATE_ON_BATTERY;
|
||||
*percent = scePowerGetBatteryLifePercent();
|
||||
*seconds = scePowerGetBatteryLifeTime()*60;
|
||||
}
|
||||
|
||||
|
||||
return SDL_TRUE; /* always the definitive answer on PSP. */
|
||||
}
|
||||
|
||||
#endif /* SDL_POWER_PSP */
|
||||
#endif /* SDL_POWER_DISABLED */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifndef SDL_POWER_DISABLED
|
||||
#if SDL_POWER_WINDOWS
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
|
||||
#include "SDL_power.h"
|
||||
|
||||
SDL_bool
|
||||
SDL_GetPowerInfo_Windows(SDL_PowerState * state, int *seconds, int *percent)
|
||||
{
|
||||
SYSTEM_POWER_STATUS status;
|
||||
SDL_bool need_details = SDL_FALSE;
|
||||
|
||||
/* This API should exist back to Win95. */
|
||||
if (!GetSystemPowerStatus(&status))
|
||||
{
|
||||
/* !!! FIXME: push GetLastError() into SDL_GetError() */
|
||||
*state = SDL_POWERSTATE_UNKNOWN;
|
||||
} else if (status.BatteryFlag == 0xFF) { /* unknown state */
|
||||
*state = SDL_POWERSTATE_UNKNOWN;
|
||||
} else if (status.BatteryFlag & (1 << 7)) { /* no battery */
|
||||
*state = SDL_POWERSTATE_NO_BATTERY;
|
||||
} else if (status.BatteryFlag & (1 << 3)) { /* charging */
|
||||
*state = SDL_POWERSTATE_CHARGING;
|
||||
need_details = SDL_TRUE;
|
||||
} else if (status.ACLineStatus == 1) {
|
||||
*state = SDL_POWERSTATE_CHARGED; /* on AC, not charging. */
|
||||
need_details = SDL_TRUE;
|
||||
} else {
|
||||
*state = SDL_POWERSTATE_ON_BATTERY; /* not on AC. */
|
||||
need_details = SDL_TRUE;
|
||||
}
|
||||
|
||||
*percent = -1;
|
||||
*seconds = -1;
|
||||
if (need_details) {
|
||||
const int pct = (int) status.BatteryLifePercent;
|
||||
const int secs = (int) status.BatteryLifeTime;
|
||||
|
||||
if (pct != 255) { /* 255 == unknown */
|
||||
*percent = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */
|
||||
}
|
||||
if (secs != 0xFFFFFFFF) { /* ((DWORD)-1) == unknown */
|
||||
*seconds = secs;
|
||||
}
|
||||
}
|
||||
|
||||
return SDL_TRUE; /* always the definitive answer on Windows. */
|
||||
}
|
||||
|
||||
#endif /* SDL_POWER_WINDOWS */
|
||||
#endif /* SDL_POWER_DISABLED */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,42 +0,0 @@
|
||||
SDL_PROC(void, glBindTexture, (GLenum, GLuint))
|
||||
SDL_PROC(void, glBlendFunc, (GLenum, GLenum))
|
||||
SDL_PROC_OES(void, glBlendFuncSeparateOES, (GLenum, GLenum, GLenum, GLenum))
|
||||
SDL_PROC(void, glClear, (GLbitfield))
|
||||
SDL_PROC(void, glClearColor, (GLclampf, GLclampf, GLclampf, GLclampf))
|
||||
SDL_PROC(void, glColor4f, (GLfloat, GLfloat, GLfloat, GLfloat))
|
||||
SDL_PROC(void, glDeleteTextures, (GLsizei, const GLuint *))
|
||||
SDL_PROC(void, glDisable, (GLenum))
|
||||
SDL_PROC(void, glDisableClientState, (GLenum array))
|
||||
SDL_PROC(void, glDrawArrays, (GLenum, GLint, GLsizei))
|
||||
SDL_PROC_OES(void, glDrawTexfOES, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat))
|
||||
SDL_PROC(void, glEnable, (GLenum))
|
||||
SDL_PROC(void, glEnableClientState, (GLenum))
|
||||
SDL_PROC(void, glFinish, (void))
|
||||
SDL_PROC_OES(void, glGenFramebuffersOES, (GLsizei, GLuint *))
|
||||
SDL_PROC(void, glGenTextures, (GLsizei, GLuint *))
|
||||
SDL_PROC(GLenum, glGetError, (void))
|
||||
SDL_PROC(void, glGetIntegerv, (GLenum, GLint *))
|
||||
SDL_PROC(void, glLoadIdentity, (void))
|
||||
SDL_PROC(void, glMatrixMode, (GLenum))
|
||||
SDL_PROC(void, glOrthof, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat))
|
||||
SDL_PROC(void, glPixelStorei, (GLenum, GLint))
|
||||
SDL_PROC(void, glReadPixels, (GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid*))
|
||||
SDL_PROC(void, glScissor, (GLint, GLint, GLsizei, GLsizei))
|
||||
SDL_PROC(void, glTexCoordPointer, (GLint, GLenum, GLsizei, const GLvoid *))
|
||||
SDL_PROC(void, glTexEnvf, (GLenum, GLenum, GLfloat))
|
||||
SDL_PROC(void, glTexImage2D, (GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *))
|
||||
SDL_PROC(void, glTexParameteri, (GLenum, GLenum, GLint))
|
||||
SDL_PROC(void, glTexParameteriv, (GLenum, GLenum, const GLint *))
|
||||
SDL_PROC(void, glTexSubImage2D, (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *))
|
||||
SDL_PROC(void, glVertexPointer, (GLint, GLenum, GLsizei, const GLvoid *))
|
||||
SDL_PROC(void, glViewport, (GLint, GLint, GLsizei, GLsizei))
|
||||
SDL_PROC_OES(void, glBindFramebufferOES, (GLenum, GLuint))
|
||||
SDL_PROC_OES(void, glFramebufferTexture2DOES, (GLenum, GLenum, GLenum, GLuint, GLint))
|
||||
SDL_PROC_OES(GLenum, glCheckFramebufferStatusOES, (GLenum))
|
||||
SDL_PROC(void, glPushMatrix, (void))
|
||||
SDL_PROC(void, glTranslatef, (GLfloat, GLfloat, GLfloat))
|
||||
SDL_PROC(void, glRotatef, (GLfloat, GLfloat, GLfloat, GLfloat))
|
||||
SDL_PROC(void, glPopMatrix, (void))
|
||||
SDL_PROC_OES(void, glDeleteFramebuffersOES, (GLsizei, const GLuint*))
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,7 +0,0 @@
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
extern SDL_Surface *SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, int smooth, int flipx, int flipy, int dstwidth, int dstheight, double cangle, double sangle);
|
||||
extern void SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, int *dstwidth, int *dstheight, double *cangle, double *sangle);
|
||||
|
||||
@@ -1,220 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
/* An implementation of condition variables using semaphores and mutexes */
|
||||
/*
|
||||
This implementation borrows heavily from the BeOS condition variable
|
||||
implementation, written by Christopher Tate and Owen Smith. Thanks!
|
||||
*/
|
||||
|
||||
#include "SDL_thread.h"
|
||||
|
||||
struct SDL_cond
|
||||
{
|
||||
SDL_mutex *lock;
|
||||
int waiting;
|
||||
int signals;
|
||||
SDL_sem *wait_sem;
|
||||
SDL_sem *wait_done;
|
||||
};
|
||||
|
||||
/* Create a condition variable */
|
||||
SDL_cond *
|
||||
SDL_CreateCond(void)
|
||||
{
|
||||
SDL_cond *cond;
|
||||
|
||||
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
|
||||
if (cond) {
|
||||
cond->lock = SDL_CreateMutex();
|
||||
cond->wait_sem = SDL_CreateSemaphore(0);
|
||||
cond->wait_done = SDL_CreateSemaphore(0);
|
||||
cond->waiting = cond->signals = 0;
|
||||
if (!cond->lock || !cond->wait_sem || !cond->wait_done) {
|
||||
SDL_DestroyCond(cond);
|
||||
cond = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return (cond);
|
||||
}
|
||||
|
||||
/* Destroy a condition variable */
|
||||
void
|
||||
SDL_DestroyCond(SDL_cond * cond)
|
||||
{
|
||||
if (cond) {
|
||||
if (cond->wait_sem) {
|
||||
SDL_DestroySemaphore(cond->wait_sem);
|
||||
}
|
||||
if (cond->wait_done) {
|
||||
SDL_DestroySemaphore(cond->wait_done);
|
||||
}
|
||||
if (cond->lock) {
|
||||
SDL_DestroyMutex(cond->lock);
|
||||
}
|
||||
SDL_free(cond);
|
||||
}
|
||||
}
|
||||
|
||||
/* Restart one of the threads that are waiting on the condition variable */
|
||||
int
|
||||
SDL_CondSignal(SDL_cond * cond)
|
||||
{
|
||||
if (!cond) {
|
||||
return SDL_SetError("Passed a NULL condition variable");
|
||||
}
|
||||
|
||||
/* If there are waiting threads not already signalled, then
|
||||
signal the condition and wait for the thread to respond.
|
||||
*/
|
||||
SDL_LockMutex(cond->lock);
|
||||
if (cond->waiting > cond->signals) {
|
||||
++cond->signals;
|
||||
SDL_SemPost(cond->wait_sem);
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
SDL_SemWait(cond->wait_done);
|
||||
} else {
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Restart all threads that are waiting on the condition variable */
|
||||
int
|
||||
SDL_CondBroadcast(SDL_cond * cond)
|
||||
{
|
||||
if (!cond) {
|
||||
return SDL_SetError("Passed a NULL condition variable");
|
||||
}
|
||||
|
||||
/* If there are waiting threads not already signalled, then
|
||||
signal the condition and wait for the thread to respond.
|
||||
*/
|
||||
SDL_LockMutex(cond->lock);
|
||||
if (cond->waiting > cond->signals) {
|
||||
int i, num_waiting;
|
||||
|
||||
num_waiting = (cond->waiting - cond->signals);
|
||||
cond->signals = cond->waiting;
|
||||
for (i = 0; i < num_waiting; ++i) {
|
||||
SDL_SemPost(cond->wait_sem);
|
||||
}
|
||||
/* Now all released threads are blocked here, waiting for us.
|
||||
Collect them all (and win fabulous prizes!) :-)
|
||||
*/
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
for (i = 0; i < num_waiting; ++i) {
|
||||
SDL_SemWait(cond->wait_done);
|
||||
}
|
||||
} else {
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable for at most 'ms' milliseconds.
|
||||
The mutex must be locked before entering this function!
|
||||
The mutex is unlocked during the wait, and locked again after the wait.
|
||||
|
||||
Typical use:
|
||||
|
||||
Thread A:
|
||||
SDL_LockMutex(lock);
|
||||
while ( ! condition ) {
|
||||
SDL_CondWait(cond, lock);
|
||||
}
|
||||
SDL_UnlockMutex(lock);
|
||||
|
||||
Thread B:
|
||||
SDL_LockMutex(lock);
|
||||
...
|
||||
condition = true;
|
||||
...
|
||||
SDL_CondSignal(cond);
|
||||
SDL_UnlockMutex(lock);
|
||||
*/
|
||||
int
|
||||
SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!cond) {
|
||||
return SDL_SetError("Passed a NULL condition variable");
|
||||
}
|
||||
|
||||
/* Obtain the protection mutex, and increment the number of waiters.
|
||||
This allows the signal mechanism to only perform a signal if there
|
||||
are waiting threads.
|
||||
*/
|
||||
SDL_LockMutex(cond->lock);
|
||||
++cond->waiting;
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
|
||||
/* Unlock the mutex, as is required by condition variable semantics */
|
||||
SDL_UnlockMutex(mutex);
|
||||
|
||||
/* Wait for a signal */
|
||||
if (ms == SDL_MUTEX_MAXWAIT) {
|
||||
retval = SDL_SemWait(cond->wait_sem);
|
||||
} else {
|
||||
retval = SDL_SemWaitTimeout(cond->wait_sem, ms);
|
||||
}
|
||||
|
||||
/* Let the signaler know we have completed the wait, otherwise
|
||||
the signaler can race ahead and get the condition semaphore
|
||||
if we are stopped between the mutex unlock and semaphore wait,
|
||||
giving a deadlock. See the following URL for details:
|
||||
http://web.archive.org/web/20010914175514/http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html#Workshop
|
||||
*/
|
||||
SDL_LockMutex(cond->lock);
|
||||
if (cond->signals > 0) {
|
||||
/* If we timed out, we need to eat a condition signal */
|
||||
if (retval > 0) {
|
||||
SDL_SemWait(cond->wait_sem);
|
||||
}
|
||||
/* We always notify the signal thread that we are done */
|
||||
SDL_SemPost(cond->wait_done);
|
||||
|
||||
/* Signal handshake complete */
|
||||
--cond->signals;
|
||||
}
|
||||
--cond->waiting;
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
|
||||
/* Lock the mutex, as is required by condition variable semantics */
|
||||
SDL_LockMutex(mutex);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable forever */
|
||||
int
|
||||
SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
|
||||
{
|
||||
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,165 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
/* An implementation of mutexes using semaphores */
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_systhread_c.h"
|
||||
|
||||
|
||||
struct SDL_mutex
|
||||
{
|
||||
int recursive;
|
||||
SDL_threadID owner;
|
||||
SDL_sem *sem;
|
||||
};
|
||||
|
||||
/* Create a mutex */
|
||||
SDL_mutex *
|
||||
SDL_CreateMutex(void)
|
||||
{
|
||||
SDL_mutex *mutex;
|
||||
|
||||
/* Allocate mutex memory */
|
||||
mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
|
||||
if (mutex) {
|
||||
/* Create the mutex semaphore, with initial value 1 */
|
||||
mutex->sem = SDL_CreateSemaphore(1);
|
||||
mutex->recursive = 0;
|
||||
mutex->owner = 0;
|
||||
if (!mutex->sem) {
|
||||
SDL_free(mutex);
|
||||
mutex = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return mutex;
|
||||
}
|
||||
|
||||
/* Free the mutex */
|
||||
void
|
||||
SDL_DestroyMutex(SDL_mutex * mutex)
|
||||
{
|
||||
if (mutex) {
|
||||
if (mutex->sem) {
|
||||
SDL_DestroySemaphore(mutex->sem);
|
||||
}
|
||||
SDL_free(mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock the mutex */
|
||||
int
|
||||
SDL_LockMutex(SDL_mutex * mutex)
|
||||
{
|
||||
#if SDL_THREADS_DISABLED
|
||||
return 0;
|
||||
#else
|
||||
SDL_threadID this_thread;
|
||||
|
||||
if (mutex == NULL) {
|
||||
return SDL_SetError("Passed a NULL mutex");
|
||||
}
|
||||
|
||||
this_thread = SDL_ThreadID();
|
||||
if (mutex->owner == this_thread) {
|
||||
++mutex->recursive;
|
||||
} else {
|
||||
/* The order of operations is important.
|
||||
We set the locking thread id after we obtain the lock
|
||||
so unlocks from other threads will fail.
|
||||
*/
|
||||
SDL_SemWait(mutex->sem);
|
||||
mutex->owner = this_thread;
|
||||
mutex->recursive = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif /* SDL_THREADS_DISABLED */
|
||||
}
|
||||
|
||||
/* try Lock the mutex */
|
||||
int
|
||||
SDL_TryLockMutex(SDL_mutex * mutex)
|
||||
{
|
||||
#if SDL_THREADS_DISABLED
|
||||
return 0;
|
||||
#else
|
||||
int retval = 0;
|
||||
SDL_threadID this_thread;
|
||||
|
||||
if (mutex == NULL) {
|
||||
return SDL_SetError("Passed a NULL mutex");
|
||||
}
|
||||
|
||||
this_thread = SDL_ThreadID();
|
||||
if (mutex->owner == this_thread) {
|
||||
++mutex->recursive;
|
||||
} else {
|
||||
/* The order of operations is important.
|
||||
We set the locking thread id after we obtain the lock
|
||||
so unlocks from other threads will fail.
|
||||
*/
|
||||
retval = SDL_SemWait(mutex->sem);
|
||||
if (retval == 0) {
|
||||
mutex->owner = this_thread;
|
||||
mutex->recursive = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
#endif /* SDL_THREADS_DISABLED */
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
int
|
||||
SDL_mutexV(SDL_mutex * mutex)
|
||||
{
|
||||
#if SDL_THREADS_DISABLED
|
||||
return 0;
|
||||
#else
|
||||
if (mutex == NULL) {
|
||||
return SDL_SetError("Passed a NULL mutex");
|
||||
}
|
||||
|
||||
/* If we don't own the mutex, we can't unlock it */
|
||||
if (SDL_ThreadID() != mutex->owner) {
|
||||
return SDL_SetError("mutex not owned by this thread");
|
||||
}
|
||||
|
||||
if (mutex->recursive) {
|
||||
--mutex->recursive;
|
||||
} else {
|
||||
/* The order of operations is important.
|
||||
First reset the owner so another thread doesn't lock
|
||||
the mutex and set the ownership before we reset it,
|
||||
then release the lock semaphore.
|
||||
*/
|
||||
mutex->owner = 0;
|
||||
SDL_SemPost(mutex->sem);
|
||||
}
|
||||
return 0;
|
||||
#endif /* SDL_THREADS_DISABLED */
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,217 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
/* An implementation of semaphores using mutexes and condition variables */
|
||||
|
||||
#include "SDL_timer.h"
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_systhread_c.h"
|
||||
|
||||
|
||||
#if SDL_THREADS_DISABLED
|
||||
|
||||
SDL_sem *
|
||||
SDL_CreateSemaphore(Uint32 initial_value)
|
||||
{
|
||||
SDL_SetError("SDL not built with thread support");
|
||||
return (SDL_sem *) 0;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_DestroySemaphore(SDL_sem * sem)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SemTryWait(SDL_sem * sem)
|
||||
{
|
||||
return SDL_SetError("SDL not built with thread support");
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
|
||||
{
|
||||
return SDL_SetError("SDL not built with thread support");
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SemWait(SDL_sem * sem)
|
||||
{
|
||||
return SDL_SetError("SDL not built with thread support");
|
||||
}
|
||||
|
||||
Uint32
|
||||
SDL_SemValue(SDL_sem * sem)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SemPost(SDL_sem * sem)
|
||||
{
|
||||
return SDL_SetError("SDL not built with thread support");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct SDL_semaphore
|
||||
{
|
||||
Uint32 count;
|
||||
Uint32 waiters_count;
|
||||
SDL_mutex *count_lock;
|
||||
SDL_cond *count_nonzero;
|
||||
};
|
||||
|
||||
SDL_sem *
|
||||
SDL_CreateSemaphore(Uint32 initial_value)
|
||||
{
|
||||
SDL_sem *sem;
|
||||
|
||||
sem = (SDL_sem *) SDL_malloc(sizeof(*sem));
|
||||
if (!sem) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
sem->count = initial_value;
|
||||
sem->waiters_count = 0;
|
||||
|
||||
sem->count_lock = SDL_CreateMutex();
|
||||
sem->count_nonzero = SDL_CreateCond();
|
||||
if (!sem->count_lock || !sem->count_nonzero) {
|
||||
SDL_DestroySemaphore(sem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sem;
|
||||
}
|
||||
|
||||
/* WARNING:
|
||||
You cannot call this function when another thread is using the semaphore.
|
||||
*/
|
||||
void
|
||||
SDL_DestroySemaphore(SDL_sem * sem)
|
||||
{
|
||||
if (sem) {
|
||||
sem->count = 0xFFFFFFFF;
|
||||
while (sem->waiters_count > 0) {
|
||||
SDL_CondSignal(sem->count_nonzero);
|
||||
SDL_Delay(10);
|
||||
}
|
||||
SDL_DestroyCond(sem->count_nonzero);
|
||||
if (sem->count_lock) {
|
||||
SDL_LockMutex(sem->count_lock);
|
||||
SDL_UnlockMutex(sem->count_lock);
|
||||
SDL_DestroyMutex(sem->count_lock);
|
||||
}
|
||||
SDL_free(sem);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SemTryWait(SDL_sem * sem)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!sem) {
|
||||
return SDL_SetError("Passed a NULL semaphore");
|
||||
}
|
||||
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
SDL_LockMutex(sem->count_lock);
|
||||
if (sem->count > 0) {
|
||||
--sem->count;
|
||||
retval = 0;
|
||||
}
|
||||
SDL_UnlockMutex(sem->count_lock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!sem) {
|
||||
return SDL_SetError("Passed a NULL semaphore");
|
||||
}
|
||||
|
||||
/* A timeout of 0 is an easy case */
|
||||
if (timeout == 0) {
|
||||
return SDL_SemTryWait(sem);
|
||||
}
|
||||
|
||||
SDL_LockMutex(sem->count_lock);
|
||||
++sem->waiters_count;
|
||||
retval = 0;
|
||||
while ((sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT)) {
|
||||
retval = SDL_CondWaitTimeout(sem->count_nonzero,
|
||||
sem->count_lock, timeout);
|
||||
}
|
||||
--sem->waiters_count;
|
||||
if (retval == 0) {
|
||||
--sem->count;
|
||||
}
|
||||
SDL_UnlockMutex(sem->count_lock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SemWait(SDL_sem * sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
Uint32
|
||||
SDL_SemValue(SDL_sem * sem)
|
||||
{
|
||||
Uint32 value;
|
||||
|
||||
value = 0;
|
||||
if (sem) {
|
||||
SDL_LockMutex(sem->count_lock);
|
||||
value = sem->count;
|
||||
SDL_UnlockMutex(sem->count_lock);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SemPost(SDL_sem * sem)
|
||||
{
|
||||
if (!sem) {
|
||||
return SDL_SetError("Passed a NULL semaphore");
|
||||
}
|
||||
|
||||
SDL_LockMutex(sem->count_lock);
|
||||
if (sem->waiters_count > 0) {
|
||||
SDL_CondSignal(sem->count_nonzero);
|
||||
}
|
||||
++sem->count;
|
||||
SDL_UnlockMutex(sem->count_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_THREADS_DISABLED */
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
/* Thread management routines for SDL */
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "../SDL_systhread.h"
|
||||
|
||||
#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
|
||||
int
|
||||
SDL_SYS_CreateThread(SDL_Thread * thread, void *args,
|
||||
pfnSDL_CurrentBeginThread pfnBeginThread,
|
||||
pfnSDL_CurrentEndThread pfnEndThread)
|
||||
#else
|
||||
int
|
||||
SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
|
||||
#endif /* SDL_PASSED_BEGINTHREAD_ENDTHREAD */
|
||||
{
|
||||
return SDL_SetError("Threads are not supported on this platform");
|
||||
}
|
||||
|
||||
void
|
||||
SDL_SYS_SetupThread(const char *name)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_threadID
|
||||
SDL_ThreadID(void)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_SYS_WaitThread(SDL_Thread * thread)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_SYS_DetachThread(SDL_Thread * thread)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
/* Stub until we implement threads on this platform */
|
||||
typedef int SYS_ThreadHandle;
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
#include "../SDL_thread_c.h"
|
||||
|
||||
|
||||
SDL_TLSData *
|
||||
SDL_SYS_GetTLSData()
|
||||
{
|
||||
return SDL_Generic_GetTLSData();
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SYS_SetTLSData(SDL_TLSData *data)
|
||||
{
|
||||
return SDL_Generic_SetTLSData(data);
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,220 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
/* An implementation of condition variables using semaphores and mutexes */
|
||||
/*
|
||||
This implementation borrows heavily from the BeOS condition variable
|
||||
implementation, written by Christopher Tate and Owen Smith. Thanks!
|
||||
*/
|
||||
|
||||
#include "SDL_thread.h"
|
||||
|
||||
struct SDL_cond
|
||||
{
|
||||
SDL_mutex *lock;
|
||||
int waiting;
|
||||
int signals;
|
||||
SDL_sem *wait_sem;
|
||||
SDL_sem *wait_done;
|
||||
};
|
||||
|
||||
/* Create a condition variable */
|
||||
SDL_cond *
|
||||
SDL_CreateCond(void)
|
||||
{
|
||||
SDL_cond *cond;
|
||||
|
||||
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
|
||||
if (cond) {
|
||||
cond->lock = SDL_CreateMutex();
|
||||
cond->wait_sem = SDL_CreateSemaphore(0);
|
||||
cond->wait_done = SDL_CreateSemaphore(0);
|
||||
cond->waiting = cond->signals = 0;
|
||||
if (!cond->lock || !cond->wait_sem || !cond->wait_done) {
|
||||
SDL_DestroyCond(cond);
|
||||
cond = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return (cond);
|
||||
}
|
||||
|
||||
/* Destroy a condition variable */
|
||||
void
|
||||
SDL_DestroyCond(SDL_cond * cond)
|
||||
{
|
||||
if (cond) {
|
||||
if (cond->wait_sem) {
|
||||
SDL_DestroySemaphore(cond->wait_sem);
|
||||
}
|
||||
if (cond->wait_done) {
|
||||
SDL_DestroySemaphore(cond->wait_done);
|
||||
}
|
||||
if (cond->lock) {
|
||||
SDL_DestroyMutex(cond->lock);
|
||||
}
|
||||
SDL_free(cond);
|
||||
}
|
||||
}
|
||||
|
||||
/* Restart one of the threads that are waiting on the condition variable */
|
||||
int
|
||||
SDL_CondSignal(SDL_cond * cond)
|
||||
{
|
||||
if (!cond) {
|
||||
return SDL_SetError("Passed a NULL condition variable");
|
||||
}
|
||||
|
||||
/* If there are waiting threads not already signalled, then
|
||||
signal the condition and wait for the thread to respond.
|
||||
*/
|
||||
SDL_LockMutex(cond->lock);
|
||||
if (cond->waiting > cond->signals) {
|
||||
++cond->signals;
|
||||
SDL_SemPost(cond->wait_sem);
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
SDL_SemWait(cond->wait_done);
|
||||
} else {
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Restart all threads that are waiting on the condition variable */
|
||||
int
|
||||
SDL_CondBroadcast(SDL_cond * cond)
|
||||
{
|
||||
if (!cond) {
|
||||
return SDL_SetError("Passed a NULL condition variable");
|
||||
}
|
||||
|
||||
/* If there are waiting threads not already signalled, then
|
||||
signal the condition and wait for the thread to respond.
|
||||
*/
|
||||
SDL_LockMutex(cond->lock);
|
||||
if (cond->waiting > cond->signals) {
|
||||
int i, num_waiting;
|
||||
|
||||
num_waiting = (cond->waiting - cond->signals);
|
||||
cond->signals = cond->waiting;
|
||||
for (i = 0; i < num_waiting; ++i) {
|
||||
SDL_SemPost(cond->wait_sem);
|
||||
}
|
||||
/* Now all released threads are blocked here, waiting for us.
|
||||
Collect them all (and win fabulous prizes!) :-)
|
||||
*/
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
for (i = 0; i < num_waiting; ++i) {
|
||||
SDL_SemWait(cond->wait_done);
|
||||
}
|
||||
} else {
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable for at most 'ms' milliseconds.
|
||||
The mutex must be locked before entering this function!
|
||||
The mutex is unlocked during the wait, and locked again after the wait.
|
||||
|
||||
Typical use:
|
||||
|
||||
Thread A:
|
||||
SDL_LockMutex(lock);
|
||||
while ( ! condition ) {
|
||||
SDL_CondWait(cond, lock);
|
||||
}
|
||||
SDL_UnlockMutex(lock);
|
||||
|
||||
Thread B:
|
||||
SDL_LockMutex(lock);
|
||||
...
|
||||
condition = true;
|
||||
...
|
||||
SDL_CondSignal(cond);
|
||||
SDL_UnlockMutex(lock);
|
||||
*/
|
||||
int
|
||||
SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!cond) {
|
||||
return SDL_SetError("Passed a NULL condition variable");
|
||||
}
|
||||
|
||||
/* Obtain the protection mutex, and increment the number of waiters.
|
||||
This allows the signal mechanism to only perform a signal if there
|
||||
are waiting threads.
|
||||
*/
|
||||
SDL_LockMutex(cond->lock);
|
||||
++cond->waiting;
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
|
||||
/* Unlock the mutex, as is required by condition variable semantics */
|
||||
SDL_UnlockMutex(mutex);
|
||||
|
||||
/* Wait for a signal */
|
||||
if (ms == SDL_MUTEX_MAXWAIT) {
|
||||
retval = SDL_SemWait(cond->wait_sem);
|
||||
} else {
|
||||
retval = SDL_SemWaitTimeout(cond->wait_sem, ms);
|
||||
}
|
||||
|
||||
/* Let the signaler know we have completed the wait, otherwise
|
||||
the signaler can race ahead and get the condition semaphore
|
||||
if we are stopped between the mutex unlock and semaphore wait,
|
||||
giving a deadlock. See the following URL for details:
|
||||
http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html
|
||||
*/
|
||||
SDL_LockMutex(cond->lock);
|
||||
if (cond->signals > 0) {
|
||||
/* If we timed out, we need to eat a condition signal */
|
||||
if (retval > 0) {
|
||||
SDL_SemWait(cond->wait_sem);
|
||||
}
|
||||
/* We always notify the signal thread that we are done */
|
||||
SDL_SemPost(cond->wait_done);
|
||||
|
||||
/* Signal handshake complete */
|
||||
--cond->signals;
|
||||
}
|
||||
--cond->waiting;
|
||||
SDL_UnlockMutex(cond->lock);
|
||||
|
||||
/* Lock the mutex, as is required by condition variable semantics */
|
||||
SDL_LockMutex(mutex);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable forever */
|
||||
int
|
||||
SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
|
||||
{
|
||||
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
/* An implementation of mutexes using semaphores */
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_systhread_c.h"
|
||||
|
||||
|
||||
struct SDL_mutex
|
||||
{
|
||||
int recursive;
|
||||
SDL_threadID owner;
|
||||
SDL_sem *sem;
|
||||
};
|
||||
|
||||
/* Create a mutex */
|
||||
SDL_mutex *
|
||||
SDL_CreateMutex(void)
|
||||
{
|
||||
SDL_mutex *mutex;
|
||||
|
||||
/* Allocate mutex memory */
|
||||
mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
|
||||
if (mutex) {
|
||||
/* Create the mutex semaphore, with initial value 1 */
|
||||
mutex->sem = SDL_CreateSemaphore(1);
|
||||
mutex->recursive = 0;
|
||||
mutex->owner = 0;
|
||||
if (!mutex->sem) {
|
||||
SDL_free(mutex);
|
||||
mutex = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return mutex;
|
||||
}
|
||||
|
||||
/* Free the mutex */
|
||||
void
|
||||
SDL_DestroyMutex(SDL_mutex * mutex)
|
||||
{
|
||||
if (mutex) {
|
||||
if (mutex->sem) {
|
||||
SDL_DestroySemaphore(mutex->sem);
|
||||
}
|
||||
SDL_free(mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock the semaphore */
|
||||
int
|
||||
SDL_mutexP(SDL_mutex * mutex)
|
||||
{
|
||||
#if SDL_THREADS_DISABLED
|
||||
return 0;
|
||||
#else
|
||||
SDL_threadID this_thread;
|
||||
|
||||
if (mutex == NULL) {
|
||||
return SDL_SetError("Passed a NULL mutex");
|
||||
}
|
||||
|
||||
this_thread = SDL_ThreadID();
|
||||
if (mutex->owner == this_thread) {
|
||||
++mutex->recursive;
|
||||
} else {
|
||||
/* The order of operations is important.
|
||||
We set the locking thread id after we obtain the lock
|
||||
so unlocks from other threads will fail.
|
||||
*/
|
||||
SDL_SemWait(mutex->sem);
|
||||
mutex->owner = this_thread;
|
||||
mutex->recursive = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif /* SDL_THREADS_DISABLED */
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
int
|
||||
SDL_mutexV(SDL_mutex * mutex)
|
||||
{
|
||||
#if SDL_THREADS_DISABLED
|
||||
return 0;
|
||||
#else
|
||||
if (mutex == NULL) {
|
||||
return SDL_SetError("Passed a NULL mutex");
|
||||
}
|
||||
|
||||
/* If we don't own the mutex, we can't unlock it */
|
||||
if (SDL_ThreadID() != mutex->owner) {
|
||||
return SDL_SetError("mutex not owned by this thread");
|
||||
}
|
||||
|
||||
if (mutex->recursive) {
|
||||
--mutex->recursive;
|
||||
} else {
|
||||
/* The order of operations is important.
|
||||
First reset the owner so another thread doesn't lock
|
||||
the mutex and set the ownership before we reset it,
|
||||
then release the lock semaphore.
|
||||
*/
|
||||
mutex->owner = 0;
|
||||
SDL_SemPost(mutex->sem);
|
||||
}
|
||||
return 0;
|
||||
#endif /* SDL_THREADS_DISABLED */
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,156 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/* Semaphore functions for the PSP. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_thread.h"
|
||||
|
||||
#include <pspthreadman.h>
|
||||
#include <pspkerror.h>
|
||||
|
||||
struct SDL_semaphore {
|
||||
SceUID semid;
|
||||
};
|
||||
|
||||
|
||||
/* Create a semaphore */
|
||||
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
|
||||
{
|
||||
SDL_sem *sem;
|
||||
|
||||
sem = (SDL_sem *) malloc(sizeof(*sem));
|
||||
if (sem != NULL) {
|
||||
/* TODO: Figure out the limit on the maximum value. */
|
||||
sem->semid = sceKernelCreateSema("SDL sema", 0, initial_value, 255, NULL);
|
||||
if (sem->semid < 0) {
|
||||
SDL_SetError("Couldn't create semaphore");
|
||||
free(sem);
|
||||
sem = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
return sem;
|
||||
}
|
||||
|
||||
/* Free the semaphore */
|
||||
void SDL_DestroySemaphore(SDL_sem *sem)
|
||||
{
|
||||
if (sem != NULL) {
|
||||
if (sem->semid > 0) {
|
||||
sceKernelDeleteSema(sem->semid);
|
||||
sem->semid = 0;
|
||||
}
|
||||
|
||||
free(sem);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: This routine is a bit overloaded.
|
||||
* If the timeout is 0 then just poll the semaphore; if it's SDL_MUTEX_MAXWAIT, pass
|
||||
* NULL to sceKernelWaitSema() so that it waits indefinitely; and if the timeout
|
||||
* is specified, convert it to microseconds. */
|
||||
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
{
|
||||
Uint32 *pTimeout;
|
||||
unsigned int res;
|
||||
|
||||
if (sem == NULL) {
|
||||
SDL_SetError("Passed a NULL sem");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (timeout == 0) {
|
||||
res = sceKernelPollSema(sem->semid, 1);
|
||||
if (res < 0) {
|
||||
return SDL_MUTEX_TIMEDOUT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (timeout == SDL_MUTEX_MAXWAIT) {
|
||||
pTimeout = NULL;
|
||||
} else {
|
||||
timeout *= 1000; /* Convert to microseconds. */
|
||||
pTimeout = &timeout;
|
||||
}
|
||||
|
||||
res = sceKernelWaitSema(sem->semid, 1, pTimeout);
|
||||
switch (res) {
|
||||
case SCE_KERNEL_ERROR_OK:
|
||||
return 0;
|
||||
case SCE_KERNEL_ERROR_WAIT_TIMEOUT:
|
||||
return SDL_MUTEX_TIMEDOUT;
|
||||
default:
|
||||
return SDL_SetError("WaitForSingleObject() failed");
|
||||
}
|
||||
}
|
||||
|
||||
int SDL_SemTryWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, 0);
|
||||
}
|
||||
|
||||
int SDL_SemWait(SDL_sem *sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
/* Returns the current count of the semaphore */
|
||||
Uint32 SDL_SemValue(SDL_sem *sem)
|
||||
{
|
||||
SceKernelSemaInfo info;
|
||||
|
||||
if (sem == NULL) {
|
||||
SDL_SetError("Passed a NULL sem");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sceKernelReferSemaStatus(sem->semid, &info) >= 0) {
|
||||
return info.currentCount;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_SemPost(SDL_sem *sem)
|
||||
{
|
||||
int res;
|
||||
|
||||
if (sem == NULL) {
|
||||
return SDL_SetError("Passed a NULL sem");
|
||||
}
|
||||
|
||||
res = sceKernelSignalSema(sem->semid, 1);
|
||||
if (res < 0) {
|
||||
return SDL_SetError("sceKernelSignalSema() failed");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vim: ts=4 sw=4
|
||||
*/
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
/* PSP thread management routines for SDL */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_thread.h"
|
||||
#include "../SDL_systhread.h"
|
||||
#include "../SDL_thread_c.h"
|
||||
#include <pspkerneltypes.h>
|
||||
#include <pspthreadman.h>
|
||||
|
||||
|
||||
static int ThreadEntry(SceSize args, void *argp)
|
||||
{
|
||||
SDL_RunThread(*(void **) argp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
|
||||
{
|
||||
SceKernelThreadInfo status;
|
||||
int priority = 32;
|
||||
|
||||
/* Set priority of new thread to the same as the current thread */
|
||||
status.size = sizeof(SceKernelThreadInfo);
|
||||
if (sceKernelReferThreadStatus(sceKernelGetThreadId(), &status) == 0) {
|
||||
priority = status.currentPriority;
|
||||
}
|
||||
|
||||
thread->handle = sceKernelCreateThread("SDL thread", ThreadEntry,
|
||||
priority, 0x8000,
|
||||
PSP_THREAD_ATTR_VFPU, NULL);
|
||||
if (thread->handle < 0) {
|
||||
return SDL_SetError("sceKernelCreateThread() failed");
|
||||
}
|
||||
|
||||
sceKernelStartThread(thread->handle, 4, &args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SDL_SYS_SetupThread(const char *name)
|
||||
{
|
||||
/* Do nothing. */
|
||||
}
|
||||
|
||||
SDL_threadID SDL_ThreadID(void)
|
||||
{
|
||||
return (SDL_threadID) sceKernelGetThreadId();
|
||||
}
|
||||
|
||||
void SDL_SYS_WaitThread(SDL_Thread *thread)
|
||||
{
|
||||
sceKernelWaitThreadEnd(thread->handle, NULL);
|
||||
sceKernelDeleteThread(thread->handle);
|
||||
}
|
||||
|
||||
void SDL_SYS_DetachThread(SDL_Thread *thread)
|
||||
{
|
||||
/* !!! FIXME: is this correct? */
|
||||
sceKernelDeleteThread(thread->handle);
|
||||
}
|
||||
|
||||
void SDL_SYS_KillThread(SDL_Thread *thread)
|
||||
{
|
||||
sceKernelTerminateDeleteThread(thread->handle);
|
||||
}
|
||||
|
||||
int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
|
||||
{
|
||||
int value;
|
||||
|
||||
if (priority == SDL_THREAD_PRIORITY_LOW) {
|
||||
value = 19;
|
||||
} else if (priority == SDL_THREAD_PRIORITY_HIGH) {
|
||||
value = -20;
|
||||
} else {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
return sceKernelChangeThreadPriority(sceKernelGetThreadId(),value);
|
||||
|
||||
}
|
||||
|
||||
/* vim: ts=4 sw=4
|
||||
*/
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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 <pspkerneltypes.h>
|
||||
|
||||
typedef SceUID SYS_ThreadHandle;
|
||||
@@ -1,148 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_sysmutex_c.h"
|
||||
|
||||
struct SDL_cond
|
||||
{
|
||||
pthread_cond_t cond;
|
||||
};
|
||||
|
||||
/* Create a condition variable */
|
||||
SDL_cond *
|
||||
SDL_CreateCond(void)
|
||||
{
|
||||
SDL_cond *cond;
|
||||
|
||||
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
|
||||
if (cond) {
|
||||
if (pthread_cond_init(&cond->cond, NULL) < 0) {
|
||||
SDL_SetError("pthread_cond_init() failed");
|
||||
SDL_free(cond);
|
||||
cond = NULL;
|
||||
}
|
||||
}
|
||||
return (cond);
|
||||
}
|
||||
|
||||
/* Destroy a condition variable */
|
||||
void
|
||||
SDL_DestroyCond(SDL_cond * cond)
|
||||
{
|
||||
if (cond) {
|
||||
pthread_cond_destroy(&cond->cond);
|
||||
SDL_free(cond);
|
||||
}
|
||||
}
|
||||
|
||||
/* Restart one of the threads that are waiting on the condition variable */
|
||||
int
|
||||
SDL_CondSignal(SDL_cond * cond)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!cond) {
|
||||
return SDL_SetError("Passed a NULL condition variable");
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
if (pthread_cond_signal(&cond->cond) != 0) {
|
||||
return SDL_SetError("pthread_cond_signal() failed");
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Restart all threads that are waiting on the condition variable */
|
||||
int
|
||||
SDL_CondBroadcast(SDL_cond * cond)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!cond) {
|
||||
return SDL_SetError("Passed a NULL condition variable");
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
if (pthread_cond_broadcast(&cond->cond) != 0) {
|
||||
return SDL_SetError("pthread_cond_broadcast() failed");
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
|
||||
{
|
||||
int retval;
|
||||
struct timeval delta;
|
||||
struct timespec abstime;
|
||||
|
||||
if (!cond) {
|
||||
return SDL_SetError("Passed a NULL condition variable");
|
||||
}
|
||||
|
||||
gettimeofday(&delta, NULL);
|
||||
|
||||
abstime.tv_sec = delta.tv_sec + (ms / 1000);
|
||||
abstime.tv_nsec = (delta.tv_usec + (ms % 1000) * 1000) * 1000;
|
||||
if (abstime.tv_nsec > 1000000000) {
|
||||
abstime.tv_sec += 1;
|
||||
abstime.tv_nsec -= 1000000000;
|
||||
}
|
||||
|
||||
tryagain:
|
||||
retval = pthread_cond_timedwait(&cond->cond, &mutex->id, &abstime);
|
||||
switch (retval) {
|
||||
case EINTR:
|
||||
goto tryagain;
|
||||
break;
|
||||
case ETIMEDOUT:
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
retval = SDL_SetError("pthread_cond_timedwait() failed");
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable, unlocking the provided mutex.
|
||||
The mutex must be locked before entering this function!
|
||||
*/
|
||||
int
|
||||
SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
|
||||
{
|
||||
if (!cond) {
|
||||
return SDL_SetError("Passed a NULL condition variable");
|
||||
} else if (pthread_cond_wait(&cond->cond, &mutex->id) != 0) {
|
||||
return SDL_SetError("pthread_cond_wait() failed");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,193 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "SDL_thread.h"
|
||||
|
||||
#if !SDL_THREAD_PTHREAD_RECURSIVE_MUTEX && \
|
||||
!SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP
|
||||
#define FAKE_RECURSIVE_MUTEX 1
|
||||
#endif
|
||||
|
||||
struct SDL_mutex
|
||||
{
|
||||
pthread_mutex_t id;
|
||||
#if FAKE_RECURSIVE_MUTEX
|
||||
int recursive;
|
||||
pthread_t owner;
|
||||
#endif
|
||||
};
|
||||
|
||||
SDL_mutex *
|
||||
SDL_CreateMutex(void)
|
||||
{
|
||||
SDL_mutex *mutex;
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
/* Allocate the structure */
|
||||
mutex = (SDL_mutex *) SDL_calloc(1, sizeof(*mutex));
|
||||
if (mutex) {
|
||||
pthread_mutexattr_init(&attr);
|
||||
#if SDL_THREAD_PTHREAD_RECURSIVE_MUTEX
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
#elif SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP
|
||||
pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
|
||||
#else
|
||||
/* No extra attributes necessary */
|
||||
#endif
|
||||
if (pthread_mutex_init(&mutex->id, &attr) != 0) {
|
||||
SDL_SetError("pthread_mutex_init() failed");
|
||||
SDL_free(mutex);
|
||||
mutex = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return (mutex);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_DestroyMutex(SDL_mutex * mutex)
|
||||
{
|
||||
if (mutex) {
|
||||
pthread_mutex_destroy(&mutex->id);
|
||||
SDL_free(mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock the mutex */
|
||||
int
|
||||
SDL_LockMutex(SDL_mutex * mutex)
|
||||
{
|
||||
#if FAKE_RECURSIVE_MUTEX
|
||||
pthread_t this_thread;
|
||||
#endif
|
||||
|
||||
if (mutex == NULL) {
|
||||
return SDL_SetError("Passed a NULL mutex");
|
||||
}
|
||||
|
||||
#if FAKE_RECURSIVE_MUTEX
|
||||
this_thread = pthread_self();
|
||||
if (mutex->owner == this_thread) {
|
||||
++mutex->recursive;
|
||||
} else {
|
||||
/* The order of operations is important.
|
||||
We set the locking thread id after we obtain the lock
|
||||
so unlocks from other threads will fail.
|
||||
*/
|
||||
if (pthread_mutex_lock(&mutex->id) == 0) {
|
||||
mutex->owner = this_thread;
|
||||
mutex->recursive = 0;
|
||||
} else {
|
||||
return SDL_SetError("pthread_mutex_lock() failed");
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (pthread_mutex_lock(&mutex->id) < 0) {
|
||||
return SDL_SetError("pthread_mutex_lock() failed");
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_TryLockMutex(SDL_mutex * mutex)
|
||||
{
|
||||
int retval;
|
||||
#if FAKE_RECURSIVE_MUTEX
|
||||
pthread_t this_thread;
|
||||
#endif
|
||||
|
||||
if (mutex == NULL) {
|
||||
return SDL_SetError("Passed a NULL mutex");
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
#if FAKE_RECURSIVE_MUTEX
|
||||
this_thread = pthread_self();
|
||||
if (mutex->owner == this_thread) {
|
||||
++mutex->recursive;
|
||||
} else {
|
||||
/* The order of operations is important.
|
||||
We set the locking thread id after we obtain the lock
|
||||
so unlocks from other threads will fail.
|
||||
*/
|
||||
if (pthread_mutex_lock(&mutex->id) == 0) {
|
||||
mutex->owner = this_thread;
|
||||
mutex->recursive = 0;
|
||||
} else if (errno == EBUSY) {
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
} else {
|
||||
retval = SDL_SetError("pthread_mutex_trylock() failed");
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (pthread_mutex_trylock(&mutex->id) != 0) {
|
||||
if (errno == EBUSY) {
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
} else {
|
||||
retval = SDL_SetError("pthread_mutex_trylock() failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_UnlockMutex(SDL_mutex * mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return SDL_SetError("Passed a NULL mutex");
|
||||
}
|
||||
|
||||
#if FAKE_RECURSIVE_MUTEX
|
||||
/* We can only unlock the mutex if we own it */
|
||||
if (pthread_self() == mutex->owner) {
|
||||
if (mutex->recursive) {
|
||||
--mutex->recursive;
|
||||
} else {
|
||||
/* The order of operations is important.
|
||||
First reset the owner so another thread doesn't lock
|
||||
the mutex and set the ownership before we reset it,
|
||||
then release the lock semaphore.
|
||||
*/
|
||||
mutex->owner = 0;
|
||||
pthread_mutex_unlock(&mutex->id);
|
||||
}
|
||||
} else {
|
||||
return SDL_SetError("mutex not owned by this thread");
|
||||
}
|
||||
|
||||
#else
|
||||
if (pthread_mutex_unlock(&mutex->id) < 0) {
|
||||
return SDL_SetError("pthread_mutex_unlock() failed");
|
||||
}
|
||||
#endif /* FAKE_RECURSIVE_MUTEX */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifndef _SDL_mutex_c_h
|
||||
#define _SDL_mutex_c_h
|
||||
|
||||
struct SDL_mutex
|
||||
{
|
||||
pthread_mutex_t id;
|
||||
};
|
||||
|
||||
#endif /* _SDL_mutex_c_h */
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,199 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_timer.h"
|
||||
|
||||
/* Wrapper around POSIX 1003.1b semaphores */
|
||||
|
||||
#if defined(__MACOSX__) || defined(__IPHONEOS__)
|
||||
/* Mac OS X doesn't support sem_getvalue() as of version 10.4 */
|
||||
#include "../generic/SDL_syssem.c"
|
||||
#else
|
||||
|
||||
struct SDL_semaphore
|
||||
{
|
||||
sem_t sem;
|
||||
};
|
||||
|
||||
/* Create a semaphore, initialized with value */
|
||||
SDL_sem *
|
||||
SDL_CreateSemaphore(Uint32 initial_value)
|
||||
{
|
||||
SDL_sem *sem = (SDL_sem *) SDL_malloc(sizeof(SDL_sem));
|
||||
if (sem) {
|
||||
if (sem_init(&sem->sem, 0, initial_value) < 0) {
|
||||
SDL_SetError("sem_init() failed");
|
||||
SDL_free(sem);
|
||||
sem = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return sem;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_DestroySemaphore(SDL_sem * sem)
|
||||
{
|
||||
if (sem) {
|
||||
sem_destroy(&sem->sem);
|
||||
SDL_free(sem);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SemTryWait(SDL_sem * sem)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!sem) {
|
||||
return SDL_SetError("Passed a NULL semaphore");
|
||||
}
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
if (sem_trywait(&sem->sem) == 0) {
|
||||
retval = 0;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SemWait(SDL_sem * sem)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!sem) {
|
||||
return SDL_SetError("Passed a NULL semaphore");
|
||||
}
|
||||
|
||||
retval = sem_wait(&sem->sem);
|
||||
if (retval < 0) {
|
||||
retval = SDL_SetError("sem_wait() failed");
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
|
||||
{
|
||||
int retval;
|
||||
#ifdef HAVE_SEM_TIMEDWAIT
|
||||
struct timeval now;
|
||||
struct timespec ts_timeout;
|
||||
#else
|
||||
Uint32 end;
|
||||
#endif
|
||||
|
||||
if (!sem) {
|
||||
return SDL_SetError("Passed a NULL semaphore");
|
||||
}
|
||||
|
||||
/* Try the easy cases first */
|
||||
if (timeout == 0) {
|
||||
return SDL_SemTryWait(sem);
|
||||
}
|
||||
if (timeout == SDL_MUTEX_MAXWAIT) {
|
||||
return SDL_SemWait(sem);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SEM_TIMEDWAIT
|
||||
/* Setup the timeout. sem_timedwait doesn't wait for
|
||||
* a lapse of time, but until we reach a certain time.
|
||||
* This time is now plus the timeout.
|
||||
*/
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
/* Add our timeout to current time */
|
||||
now.tv_usec += (timeout % 1000) * 1000;
|
||||
now.tv_sec += timeout / 1000;
|
||||
|
||||
/* Wrap the second if needed */
|
||||
if ( now.tv_usec >= 1000000 ) {
|
||||
now.tv_usec -= 1000000;
|
||||
now.tv_sec ++;
|
||||
}
|
||||
|
||||
/* Convert to timespec */
|
||||
ts_timeout.tv_sec = now.tv_sec;
|
||||
ts_timeout.tv_nsec = now.tv_usec * 1000;
|
||||
|
||||
/* Wait. */
|
||||
do {
|
||||
retval = sem_timedwait(&sem->sem, &ts_timeout);
|
||||
} while (retval < 0 && errno == EINTR);
|
||||
|
||||
if (retval < 0) {
|
||||
if (errno == ETIMEDOUT) {
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
} else {
|
||||
SDL_SetError(strerror(errno));
|
||||
}
|
||||
}
|
||||
#else
|
||||
end = SDL_GetTicks() + timeout;
|
||||
while ((retval = SDL_SemTryWait(sem)) == SDL_MUTEX_TIMEDOUT) {
|
||||
if (SDL_TICKS_PASSED(SDL_GetTicks(), end)) {
|
||||
break;
|
||||
}
|
||||
SDL_Delay(1);
|
||||
}
|
||||
#endif /* HAVE_SEM_TIMEDWAIT */
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
Uint32
|
||||
SDL_SemValue(SDL_sem * sem)
|
||||
{
|
||||
int ret = 0;
|
||||
if (sem) {
|
||||
sem_getvalue(&sem->sem, &ret);
|
||||
if (ret < 0) {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
return (Uint32) ret;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SemPost(SDL_sem * sem)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!sem) {
|
||||
return SDL_SetError("Passed a NULL semaphore");
|
||||
}
|
||||
|
||||
retval = sem_post(&sem->sem);
|
||||
if (retval < 0) {
|
||||
SDL_SetError("sem_post() failed");
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif /* __MACOSX__ */
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,222 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#if HAVE_PTHREAD_NP_H
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef __LINUX__
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
#endif /* __LINUX__ */
|
||||
|
||||
#if defined(__LINUX__) || defined(__MACOSX__) || defined(__IPHONEOS__)
|
||||
#include <dlfcn.h>
|
||||
#ifndef RTLD_DEFAULT
|
||||
#define RTLD_DEFAULT NULL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "SDL_platform.h"
|
||||
#include "SDL_thread.h"
|
||||
#include "../SDL_thread_c.h"
|
||||
#include "../SDL_systhread.h"
|
||||
#ifdef __ANDROID__
|
||||
#include "../../core/android/SDL_android.h"
|
||||
#endif
|
||||
|
||||
#ifdef __HAIKU__
|
||||
#include <be/kernel/OS.h>
|
||||
#endif
|
||||
|
||||
#include "SDL_assert.h"
|
||||
|
||||
/* List of signals to mask in the subthreads */
|
||||
static const int sig_list[] = {
|
||||
SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH,
|
||||
SIGVTALRM, SIGPROF, 0
|
||||
};
|
||||
|
||||
static void *
|
||||
RunThread(void *data)
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
Android_JNI_SetupThread();
|
||||
#endif
|
||||
SDL_RunThread(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(__MACOSX__) || defined(__IPHONEOS__)
|
||||
static SDL_bool checked_setname = SDL_FALSE;
|
||||
static int (*ppthread_setname_np)(const char*) = NULL;
|
||||
#elif defined(__LINUX__)
|
||||
static SDL_bool checked_setname = SDL_FALSE;
|
||||
static int (*ppthread_setname_np)(pthread_t, const char*) = NULL;
|
||||
#endif
|
||||
int
|
||||
SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
|
||||
{
|
||||
pthread_attr_t type;
|
||||
|
||||
/* do this here before any threads exist, so there's no race condition. */
|
||||
#if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)
|
||||
if (!checked_setname) {
|
||||
void *fn = dlsym(RTLD_DEFAULT, "pthread_setname_np");
|
||||
#if defined(__MACOSX__) || defined(__IPHONEOS__)
|
||||
ppthread_setname_np = (int(*)(const char*)) fn;
|
||||
#elif defined(__LINUX__)
|
||||
ppthread_setname_np = (int(*)(pthread_t, const char*)) fn;
|
||||
#endif
|
||||
checked_setname = SDL_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set the thread attributes */
|
||||
if (pthread_attr_init(&type) != 0) {
|
||||
return SDL_SetError("Couldn't initialize pthread attributes");
|
||||
}
|
||||
pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE);
|
||||
|
||||
/* Create the thread and go! */
|
||||
if (pthread_create(&thread->handle, &type, RunThread, args) != 0) {
|
||||
return SDL_SetError("Not enough resources to create thread");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_SYS_SetupThread(const char *name)
|
||||
{
|
||||
int i;
|
||||
sigset_t mask;
|
||||
|
||||
if (name != NULL) {
|
||||
#if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)
|
||||
SDL_assert(checked_setname);
|
||||
if (ppthread_setname_np != NULL) {
|
||||
#if defined(__MACOSX__) || defined(__IPHONEOS__)
|
||||
ppthread_setname_np(name);
|
||||
#elif defined(__LINUX__)
|
||||
ppthread_setname_np(pthread_self(), name);
|
||||
#endif
|
||||
}
|
||||
#elif HAVE_PTHREAD_SETNAME_NP
|
||||
pthread_setname_np(pthread_self(), name);
|
||||
#elif HAVE_PTHREAD_SET_NAME_NP
|
||||
pthread_set_name_np(pthread_self(), name);
|
||||
#elif defined(__HAIKU__)
|
||||
/* The docs say the thread name can't be longer than B_OS_NAME_LENGTH. */
|
||||
char namebuf[B_OS_NAME_LENGTH];
|
||||
SDL_snprintf(namebuf, sizeof (namebuf), "%s", name);
|
||||
namebuf[sizeof (namebuf) - 1] = '\0';
|
||||
rename_thread(find_thread(NULL), namebuf);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Mask asynchronous signals for this thread */
|
||||
sigemptyset(&mask);
|
||||
for (i = 0; sig_list[i]; ++i) {
|
||||
sigaddset(&mask, sig_list[i]);
|
||||
}
|
||||
pthread_sigmask(SIG_BLOCK, &mask, 0);
|
||||
|
||||
#ifdef PTHREAD_CANCEL_ASYNCHRONOUS
|
||||
/* Allow ourselves to be asynchronously cancelled */
|
||||
{
|
||||
int oldstate;
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SDL_threadID
|
||||
SDL_ThreadID(void)
|
||||
{
|
||||
return ((SDL_threadID) pthread_self());
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
|
||||
{
|
||||
#ifdef __LINUX__
|
||||
int value;
|
||||
|
||||
if (priority == SDL_THREAD_PRIORITY_LOW) {
|
||||
value = 19;
|
||||
} else if (priority == SDL_THREAD_PRIORITY_HIGH) {
|
||||
value = -20;
|
||||
} else {
|
||||
value = 0;
|
||||
}
|
||||
if (setpriority(PRIO_PROCESS, syscall(SYS_gettid), value) < 0) {
|
||||
/* Note that this fails if you're trying to set high priority
|
||||
and you don't have root permission. BUT DON'T RUN AS ROOT!
|
||||
*/
|
||||
return SDL_SetError("setpriority() failed");
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
struct sched_param sched;
|
||||
int policy;
|
||||
pthread_t thread = pthread_self();
|
||||
|
||||
if (pthread_getschedparam(thread, &policy, &sched) < 0) {
|
||||
return SDL_SetError("pthread_getschedparam() failed");
|
||||
}
|
||||
if (priority == SDL_THREAD_PRIORITY_LOW) {
|
||||
sched.sched_priority = sched_get_priority_min(policy);
|
||||
} else if (priority == SDL_THREAD_PRIORITY_HIGH) {
|
||||
sched.sched_priority = sched_get_priority_max(policy);
|
||||
} else {
|
||||
int min_priority = sched_get_priority_min(policy);
|
||||
int max_priority = sched_get_priority_max(policy);
|
||||
sched.sched_priority = (min_priority + (max_priority - min_priority) / 2);
|
||||
}
|
||||
if (pthread_setschedparam(thread, policy, &sched) < 0) {
|
||||
return SDL_SetError("pthread_setschedparam() failed");
|
||||
}
|
||||
return 0;
|
||||
#endif /* linux */
|
||||
}
|
||||
|
||||
void
|
||||
SDL_SYS_WaitThread(SDL_Thread * thread)
|
||||
{
|
||||
pthread_join(thread->handle, 0);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_SYS_DetachThread(SDL_Thread * thread)
|
||||
{
|
||||
pthread_detach(thread->handle);
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
typedef pthread_t SYS_ThreadHandle;
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
#include "SDL_thread.h"
|
||||
#include "../SDL_thread_c.h"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
|
||||
#define INVALID_PTHREAD_KEY ((pthread_key_t)-1)
|
||||
|
||||
static pthread_key_t thread_local_storage = INVALID_PTHREAD_KEY;
|
||||
static SDL_bool generic_local_storage = SDL_FALSE;
|
||||
|
||||
SDL_TLSData *
|
||||
SDL_SYS_GetTLSData()
|
||||
{
|
||||
if (thread_local_storage == INVALID_PTHREAD_KEY && !generic_local_storage) {
|
||||
static SDL_SpinLock lock;
|
||||
SDL_AtomicLock(&lock);
|
||||
if (thread_local_storage == INVALID_PTHREAD_KEY && !generic_local_storage) {
|
||||
pthread_key_t storage;
|
||||
if (pthread_key_create(&storage, NULL) == 0) {
|
||||
SDL_MemoryBarrierRelease();
|
||||
thread_local_storage = storage;
|
||||
} else {
|
||||
generic_local_storage = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
SDL_AtomicUnlock(&lock);
|
||||
}
|
||||
if (generic_local_storage) {
|
||||
return SDL_Generic_GetTLSData();
|
||||
}
|
||||
SDL_MemoryBarrierAcquire();
|
||||
return (SDL_TLSData *)pthread_getspecific(thread_local_storage);
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SYS_SetTLSData(SDL_TLSData *data)
|
||||
{
|
||||
if (generic_local_storage) {
|
||||
return SDL_Generic_SetTLSData(data);
|
||||
}
|
||||
if (pthread_setspecific(thread_local_storage, data) != 0) {
|
||||
return SDL_SetError("pthread_setspecific() failed");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#if SDL_THREAD_WINDOWS
|
||||
|
||||
/* Mutex functions using the Win32 API */
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
|
||||
#include "SDL_mutex.h"
|
||||
|
||||
|
||||
struct SDL_mutex
|
||||
{
|
||||
CRITICAL_SECTION cs;
|
||||
};
|
||||
|
||||
/* Create a mutex */
|
||||
SDL_mutex *
|
||||
SDL_CreateMutex(void)
|
||||
{
|
||||
SDL_mutex *mutex;
|
||||
|
||||
/* Allocate mutex memory */
|
||||
mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
|
||||
if (mutex) {
|
||||
/* Initialize */
|
||||
/* On SMP systems, a non-zero spin count generally helps performance */
|
||||
InitializeCriticalSectionAndSpinCount(&mutex->cs, 2000);
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return (mutex);
|
||||
}
|
||||
|
||||
/* Free the mutex */
|
||||
void
|
||||
SDL_DestroyMutex(SDL_mutex * mutex)
|
||||
{
|
||||
if (mutex) {
|
||||
DeleteCriticalSection(&mutex->cs);
|
||||
SDL_free(mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock the mutex */
|
||||
int
|
||||
SDL_LockMutex(SDL_mutex * mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return SDL_SetError("Passed a NULL mutex");
|
||||
}
|
||||
|
||||
EnterCriticalSection(&mutex->cs);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* TryLock the mutex */
|
||||
int
|
||||
SDL_TryLockMutex(SDL_mutex * mutex)
|
||||
{
|
||||
int retval = 0;
|
||||
if (mutex == NULL) {
|
||||
return SDL_SetError("Passed a NULL mutex");
|
||||
}
|
||||
|
||||
if (TryEnterCriticalSection(&mutex->cs) == 0) {
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Unlock the mutex */
|
||||
int
|
||||
SDL_UnlockMutex(SDL_mutex * mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return SDL_SetError("Passed a NULL mutex");
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&mutex->cs);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif /* SDL_THREAD_WINDOWS */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,148 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#if SDL_THREAD_WINDOWS
|
||||
|
||||
/* Semaphore functions using the Win32 API */
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
|
||||
#include "SDL_thread.h"
|
||||
|
||||
struct SDL_semaphore
|
||||
{
|
||||
HANDLE id;
|
||||
LONG count;
|
||||
};
|
||||
|
||||
|
||||
/* Create a semaphore */
|
||||
SDL_sem *
|
||||
SDL_CreateSemaphore(Uint32 initial_value)
|
||||
{
|
||||
SDL_sem *sem;
|
||||
|
||||
/* Allocate sem memory */
|
||||
sem = (SDL_sem *) SDL_malloc(sizeof(*sem));
|
||||
if (sem) {
|
||||
/* Create the semaphore, with max value 32K */
|
||||
sem->id = CreateSemaphore(NULL, initial_value, 32 * 1024, NULL);
|
||||
sem->count = initial_value;
|
||||
if (!sem->id) {
|
||||
SDL_SetError("Couldn't create semaphore");
|
||||
SDL_free(sem);
|
||||
sem = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return (sem);
|
||||
}
|
||||
|
||||
/* Free the semaphore */
|
||||
void
|
||||
SDL_DestroySemaphore(SDL_sem * sem)
|
||||
{
|
||||
if (sem) {
|
||||
if (sem->id) {
|
||||
CloseHandle(sem->id);
|
||||
sem->id = 0;
|
||||
}
|
||||
SDL_free(sem);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
|
||||
{
|
||||
int retval;
|
||||
DWORD dwMilliseconds;
|
||||
|
||||
if (!sem) {
|
||||
return SDL_SetError("Passed a NULL sem");
|
||||
}
|
||||
|
||||
if (timeout == SDL_MUTEX_MAXWAIT) {
|
||||
dwMilliseconds = INFINITE;
|
||||
} else {
|
||||
dwMilliseconds = (DWORD) timeout;
|
||||
}
|
||||
switch (WaitForSingleObject(sem->id, dwMilliseconds)) {
|
||||
case WAIT_OBJECT_0:
|
||||
InterlockedDecrement(&sem->count);
|
||||
retval = 0;
|
||||
break;
|
||||
case WAIT_TIMEOUT:
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
break;
|
||||
default:
|
||||
retval = SDL_SetError("WaitForSingleObject() failed");
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SemTryWait(SDL_sem * sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, 0);
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SemWait(SDL_sem * sem)
|
||||
{
|
||||
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
/* Returns the current count of the semaphore */
|
||||
Uint32
|
||||
SDL_SemValue(SDL_sem * sem)
|
||||
{
|
||||
if (!sem) {
|
||||
SDL_SetError("Passed a NULL sem");
|
||||
return 0;
|
||||
}
|
||||
return (Uint32)sem->count;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SemPost(SDL_sem * sem)
|
||||
{
|
||||
if (!sem) {
|
||||
return SDL_SetError("Passed a NULL sem");
|
||||
}
|
||||
/* Increase the counter in the first place, because
|
||||
* after a successful release the semaphore may
|
||||
* immediately get destroyed by another thread which
|
||||
* is waiting for this semaphore.
|
||||
*/
|
||||
InterlockedIncrement(&sem->count);
|
||||
if (ReleaseSemaphore(sem->id, 1, NULL) == FALSE) {
|
||||
InterlockedDecrement(&sem->count); /* restore */
|
||||
return SDL_SetError("ReleaseSemaphore() failed");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_THREAD_WINDOWS */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,245 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#if SDL_THREAD_WINDOWS
|
||||
|
||||
/* Win32 thread management routines for SDL */
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "../SDL_thread_c.h"
|
||||
#include "../SDL_systhread.h"
|
||||
#include "SDL_systhread_c.h"
|
||||
|
||||
#ifndef SDL_PASSED_BEGINTHREAD_ENDTHREAD
|
||||
/* We'll use the C library from this DLL */
|
||||
#include <process.h>
|
||||
|
||||
/* Cygwin gcc-3 ... MingW64 (even with a i386 host) does this like MSVC. */
|
||||
#if (defined(__MINGW32__) && (__GNUC__ < 4))
|
||||
typedef unsigned long (__cdecl *pfnSDL_CurrentBeginThread) (void *, unsigned,
|
||||
unsigned (__stdcall *func)(void *), void *arg,
|
||||
unsigned, unsigned *threadID);
|
||||
typedef void (__cdecl *pfnSDL_CurrentEndThread)(unsigned code);
|
||||
|
||||
#elif defined(__WATCOMC__)
|
||||
/* This is for Watcom targets except OS2 */
|
||||
#if __WATCOMC__ < 1240
|
||||
#define __watcall
|
||||
#endif
|
||||
typedef unsigned long (__watcall * pfnSDL_CurrentBeginThread) (void *,
|
||||
unsigned,
|
||||
unsigned
|
||||
(__stdcall *
|
||||
func) (void
|
||||
*),
|
||||
void *arg,
|
||||
unsigned,
|
||||
unsigned
|
||||
*threadID);
|
||||
typedef void (__watcall * pfnSDL_CurrentEndThread) (unsigned code);
|
||||
|
||||
#else
|
||||
typedef uintptr_t(__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned,
|
||||
unsigned (__stdcall *
|
||||
func) (void
|
||||
*),
|
||||
void *arg, unsigned,
|
||||
unsigned *threadID);
|
||||
typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code);
|
||||
#endif
|
||||
#endif /* !SDL_PASSED_BEGINTHREAD_ENDTHREAD */
|
||||
|
||||
|
||||
typedef struct ThreadStartParms
|
||||
{
|
||||
void *args;
|
||||
pfnSDL_CurrentEndThread pfnCurrentEndThread;
|
||||
} tThreadStartParms, *pThreadStartParms;
|
||||
|
||||
static DWORD
|
||||
RunThread(void *data)
|
||||
{
|
||||
pThreadStartParms pThreadParms = (pThreadStartParms) data;
|
||||
pfnSDL_CurrentEndThread pfnEndThread = pThreadParms->pfnCurrentEndThread;
|
||||
void *args = pThreadParms->args;
|
||||
SDL_free(pThreadParms);
|
||||
SDL_RunThread(args);
|
||||
if (pfnEndThread != NULL)
|
||||
pfnEndThread(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static DWORD WINAPI
|
||||
RunThreadViaCreateThread(LPVOID data)
|
||||
{
|
||||
return RunThread(data);
|
||||
}
|
||||
|
||||
static unsigned __stdcall
|
||||
RunThreadViaBeginThreadEx(void *data)
|
||||
{
|
||||
return (unsigned) RunThread(data);
|
||||
}
|
||||
|
||||
#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
|
||||
int
|
||||
SDL_SYS_CreateThread(SDL_Thread * thread, void *args,
|
||||
pfnSDL_CurrentBeginThread pfnBeginThread,
|
||||
pfnSDL_CurrentEndThread pfnEndThread)
|
||||
{
|
||||
#elif defined(__CYGWIN__)
|
||||
int
|
||||
SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
|
||||
{
|
||||
pfnSDL_CurrentBeginThread pfnBeginThread = NULL;
|
||||
pfnSDL_CurrentEndThread pfnEndThread = NULL;
|
||||
#else
|
||||
int
|
||||
SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
|
||||
{
|
||||
pfnSDL_CurrentBeginThread pfnBeginThread = (pfnSDL_CurrentBeginThread)_beginthreadex;
|
||||
pfnSDL_CurrentEndThread pfnEndThread = (pfnSDL_CurrentEndThread)_endthreadex;
|
||||
#endif /* SDL_PASSED_BEGINTHREAD_ENDTHREAD */
|
||||
pThreadStartParms pThreadParms =
|
||||
(pThreadStartParms) SDL_malloc(sizeof(tThreadStartParms));
|
||||
if (!pThreadParms) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
/* Save the function which we will have to call to clear the RTL of calling app! */
|
||||
pThreadParms->pfnCurrentEndThread = pfnEndThread;
|
||||
/* Also save the real parameters we have to pass to thread function */
|
||||
pThreadParms->args = args;
|
||||
|
||||
if (pfnBeginThread) {
|
||||
unsigned threadid = 0;
|
||||
thread->handle = (SYS_ThreadHandle)
|
||||
((size_t) pfnBeginThread(NULL, 0, RunThreadViaBeginThreadEx,
|
||||
pThreadParms, 0, &threadid));
|
||||
} else {
|
||||
DWORD threadid = 0;
|
||||
thread->handle = CreateThread(NULL, 0, RunThreadViaCreateThread,
|
||||
pThreadParms, 0, &threadid);
|
||||
}
|
||||
if (thread->handle == NULL) {
|
||||
return SDL_SetError("Not enough resources to create thread");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0 /* !!! FIXME: revisit this later. See https://bugzilla.libsdl.org/show_bug.cgi?id=2089 */
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4733)
|
||||
#pragma pack(push,8)
|
||||
typedef struct tagTHREADNAME_INFO
|
||||
{
|
||||
DWORD dwType; /* must be 0x1000 */
|
||||
LPCSTR szName; /* pointer to name (in user addr space) */
|
||||
DWORD dwThreadID; /* thread ID (-1=caller thread) */
|
||||
DWORD dwFlags; /* reserved for future use, must be zero */
|
||||
} THREADNAME_INFO;
|
||||
#pragma pack(pop)
|
||||
|
||||
static EXCEPTION_DISPOSITION
|
||||
ignore_exception(void *a, void *b, void *c, void *d)
|
||||
{
|
||||
return ExceptionContinueExecution;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void
|
||||
SDL_SYS_SetupThread(const char *name)
|
||||
{
|
||||
if (name != NULL) {
|
||||
#if 0 /* !!! FIXME: revisit this later. See https://bugzilla.libsdl.org/show_bug.cgi?id=2089 */
|
||||
#if (defined(_MSC_VER) && defined(_M_IX86))
|
||||
/* This magic tells the debugger to name a thread if it's listening.
|
||||
The inline asm sets up SEH (__try/__except) without C runtime
|
||||
support. See Microsoft Systems Journal, January 1997:
|
||||
http://www.microsoft.com/msj/0197/exception/exception.aspx */
|
||||
INT_PTR handler = (INT_PTR) ignore_exception;
|
||||
THREADNAME_INFO inf;
|
||||
|
||||
inf.dwType = 0x1000;
|
||||
inf.szName = name;
|
||||
inf.dwThreadID = (DWORD) -1;
|
||||
inf.dwFlags = 0;
|
||||
|
||||
__asm { /* set up SEH */
|
||||
push handler
|
||||
push fs:[0]
|
||||
mov fs:[0],esp
|
||||
}
|
||||
|
||||
/* The program itself should ignore this bogus exception. */
|
||||
RaiseException(0x406D1388, 0, sizeof(inf)/sizeof(DWORD), (DWORD*)&inf);
|
||||
|
||||
__asm { /* tear down SEH. */
|
||||
mov eax,[esp]
|
||||
mov fs:[0], eax
|
||||
add esp, 8
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
SDL_threadID
|
||||
SDL_ThreadID(void)
|
||||
{
|
||||
return ((SDL_threadID) GetCurrentThreadId());
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
|
||||
{
|
||||
int value;
|
||||
|
||||
if (priority == SDL_THREAD_PRIORITY_LOW) {
|
||||
value = THREAD_PRIORITY_LOWEST;
|
||||
} else if (priority == SDL_THREAD_PRIORITY_HIGH) {
|
||||
value = THREAD_PRIORITY_HIGHEST;
|
||||
} else {
|
||||
value = THREAD_PRIORITY_NORMAL;
|
||||
}
|
||||
if (!SetThreadPriority(GetCurrentThread(), value)) {
|
||||
return WIN_SetError("SetThreadPriority()");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_SYS_WaitThread(SDL_Thread * thread)
|
||||
{
|
||||
WaitForSingleObject(thread->handle, INFINITE);
|
||||
CloseHandle(thread->handle);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_SYS_DetachThread(SDL_Thread * thread)
|
||||
{
|
||||
CloseHandle(thread->handle);
|
||||
}
|
||||
|
||||
#endif /* SDL_THREAD_WINDOWS */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifndef _SDL_systhread_c_h
|
||||
#define _SDL_systhread_c_h
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
|
||||
typedef HANDLE SYS_ThreadHandle;
|
||||
|
||||
#endif /* _SDL_systhread_c_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#if SDL_THREAD_WINDOWS
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "../SDL_thread_c.h"
|
||||
|
||||
static DWORD thread_local_storage = TLS_OUT_OF_INDEXES;
|
||||
static SDL_bool generic_local_storage = SDL_FALSE;
|
||||
|
||||
SDL_TLSData *
|
||||
SDL_SYS_GetTLSData()
|
||||
{
|
||||
if (thread_local_storage == TLS_OUT_OF_INDEXES && !generic_local_storage) {
|
||||
static SDL_SpinLock lock;
|
||||
SDL_AtomicLock(&lock);
|
||||
if (thread_local_storage == TLS_OUT_OF_INDEXES && !generic_local_storage) {
|
||||
DWORD storage = TlsAlloc();
|
||||
if (storage != TLS_OUT_OF_INDEXES) {
|
||||
SDL_MemoryBarrierRelease();
|
||||
thread_local_storage = storage;
|
||||
} else {
|
||||
generic_local_storage = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
SDL_AtomicUnlock(&lock);
|
||||
}
|
||||
if (generic_local_storage) {
|
||||
return SDL_Generic_GetTLSData();
|
||||
}
|
||||
SDL_MemoryBarrierAcquire();
|
||||
return (SDL_TLSData *)TlsGetValue(thread_local_storage);
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SYS_SetTLSData(SDL_TLSData *data)
|
||||
{
|
||||
if (generic_local_storage) {
|
||||
return SDL_Generic_SetTLSData(data);
|
||||
}
|
||||
if (!TlsSetValue(thread_local_storage, data)) {
|
||||
return SDL_SetError("TlsSetValue() failed");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_THREAD_WINDOWS */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#if defined(SDL_TIMER_DUMMY) || defined(SDL_TIMERS_DISABLED)
|
||||
|
||||
#include "SDL_timer.h"
|
||||
|
||||
static SDL_bool ticks_started = SDL_FALSE;
|
||||
|
||||
void
|
||||
SDL_InitTicks(void)
|
||||
{
|
||||
if (ticks_started) {
|
||||
return;
|
||||
}
|
||||
ticks_started = SDL_TRUE;
|
||||
}
|
||||
|
||||
Uint32
|
||||
SDL_GetTicks(void)
|
||||
{
|
||||
if (!ticks_started) {
|
||||
SDL_InitTicks();
|
||||
}
|
||||
|
||||
SDL_Unsupported();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Uint64
|
||||
SDL_GetPerformanceCounter(void)
|
||||
{
|
||||
return SDL_GetTicks();
|
||||
}
|
||||
|
||||
Uint64
|
||||
SDL_GetPerformanceFrequency(void)
|
||||
{
|
||||
return 1000;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_Delay(Uint32 ms)
|
||||
{
|
||||
SDL_Unsupported();
|
||||
}
|
||||
|
||||
#endif /* SDL_TIMER_DUMMY || SDL_TIMERS_DISABLED */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifdef SDL_TIMER_HAIKU
|
||||
|
||||
#include <os/kernel/OS.h>
|
||||
|
||||
#include "SDL_timer.h"
|
||||
|
||||
static bigtime_t start;
|
||||
static SDL_bool ticks_started = SDL_FALSE;
|
||||
|
||||
void
|
||||
SDL_InitTicks(void)
|
||||
{
|
||||
if (ticks_started) {
|
||||
return;
|
||||
}
|
||||
ticks_started = SDL_TRUE;
|
||||
|
||||
/* Set first ticks value */
|
||||
start = system_time();
|
||||
}
|
||||
|
||||
Uint32
|
||||
SDL_GetTicks(void)
|
||||
{
|
||||
if (!ticks_started) {
|
||||
SDL_InitTicks();
|
||||
}
|
||||
|
||||
return ((system_time() - start) / 1000);
|
||||
}
|
||||
|
||||
Uint64
|
||||
SDL_GetPerformanceCounter(void)
|
||||
{
|
||||
return system_time();
|
||||
}
|
||||
|
||||
Uint64
|
||||
SDL_GetPerformanceFrequency(void)
|
||||
{
|
||||
return 1000000;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_Delay(Uint32 ms)
|
||||
{
|
||||
snooze(ms * 1000);
|
||||
}
|
||||
|
||||
#endif /* SDL_TIMER_HAIKU */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_thread.h"
|
||||
#include "SDL_timer.h"
|
||||
#include "SDL_error.h"
|
||||
#include "../SDL_timer_c.h"
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <pspthreadman.h>
|
||||
|
||||
static struct timeval start;
|
||||
static SDL_bool ticks_started = SDL_FALSE;
|
||||
|
||||
void SDL_InitTicks(void)
|
||||
{
|
||||
if (ticks_started) {
|
||||
return;
|
||||
}
|
||||
ticks_started = SDL_TRUE;
|
||||
|
||||
gettimeofday(&start, NULL);
|
||||
}
|
||||
|
||||
Uint32 SDL_GetTicks(void)
|
||||
{
|
||||
if (!ticks_started) {
|
||||
SDL_InitTicks();
|
||||
}
|
||||
|
||||
struct timeval now;
|
||||
Uint32 ticks;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
ticks=(now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000;
|
||||
return(ticks);
|
||||
}
|
||||
|
||||
Uint64
|
||||
SDL_GetPerformanceCounter(void)
|
||||
{
|
||||
return SDL_GetTicks();
|
||||
}
|
||||
|
||||
Uint64
|
||||
SDL_GetPerformanceFrequency(void)
|
||||
{
|
||||
return 1000;
|
||||
}
|
||||
|
||||
void SDL_Delay(Uint32 ms)
|
||||
{
|
||||
const Uint32 max_delay = 0xffffffffUL / 1000;
|
||||
if(ms > max_delay)
|
||||
ms = max_delay;
|
||||
sceKernelDelayThreadCB(ms * 1000);
|
||||
}
|
||||
|
||||
/* vim: ts=4 sw=4
|
||||
*/
|
||||
@@ -1,211 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifdef SDL_TIMER_UNIX
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "SDL_timer.h"
|
||||
|
||||
/* The clock_gettime provides monotonous time, so we should use it if
|
||||
it's available. The clock_gettime function is behind ifdef
|
||||
for __USE_POSIX199309
|
||||
Tommi Kyntola (tommi.kyntola@ray.fi) 27/09/2005
|
||||
*/
|
||||
/* Reworked monotonic clock to not assume the current system has one
|
||||
as not all linux kernels provide a monotonic clock (yeah recent ones
|
||||
probably do)
|
||||
Also added OS X Monotonic clock support
|
||||
Based on work in https://github.com/ThomasHabets/monotonic_clock
|
||||
*/
|
||||
#if HAVE_NANOSLEEP || HAVE_CLOCK_GETTIME
|
||||
#include <time.h>
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#include <mach/mach_time.h>
|
||||
#endif
|
||||
|
||||
/* The first ticks value of the application */
|
||||
#if HAVE_CLOCK_GETTIME
|
||||
static struct timespec start_ts;
|
||||
#elif defined(__APPLE__)
|
||||
static uint64_t start_mach;
|
||||
mach_timebase_info_data_t mach_base_info;
|
||||
#endif
|
||||
static SDL_bool has_monotonic_time = SDL_FALSE;
|
||||
static struct timeval start_tv;
|
||||
static SDL_bool ticks_started = SDL_FALSE;
|
||||
|
||||
void
|
||||
SDL_InitTicks(void)
|
||||
{
|
||||
if (ticks_started) {
|
||||
return;
|
||||
}
|
||||
ticks_started = SDL_TRUE;
|
||||
|
||||
/* Set first ticks value */
|
||||
#if HAVE_CLOCK_GETTIME
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &start_ts) == 0) {
|
||||
has_monotonic_time = SDL_TRUE;
|
||||
} else
|
||||
#elif defined(__APPLE__)
|
||||
kern_return_t ret = mach_timebase_info(&mach_base_info);
|
||||
if (ret == 0) {
|
||||
has_monotonic_time = SDL_TRUE;
|
||||
start_mach = mach_absolute_time();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
gettimeofday(&start_tv, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
Uint32
|
||||
SDL_GetTicks(void)
|
||||
{
|
||||
Uint32 ticks;
|
||||
if (!ticks_started) {
|
||||
SDL_InitTicks();
|
||||
}
|
||||
|
||||
if (has_monotonic_time) {
|
||||
#if HAVE_CLOCK_GETTIME
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
ticks = (now.tv_sec - start_ts.tv_sec) * 1000 + (now.tv_nsec -
|
||||
start_ts.tv_nsec) / 1000000;
|
||||
#elif defined(__APPLE__)
|
||||
uint64_t now = mach_absolute_time();
|
||||
ticks = (((now - start_mach) * mach_base_info.numer) / mach_base_info.denom) / 1000000;
|
||||
#endif
|
||||
} else {
|
||||
struct timeval now;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
ticks =
|
||||
(now.tv_sec - start_tv.tv_sec) * 1000 + (now.tv_usec -
|
||||
start_tv.tv_usec) / 1000;
|
||||
}
|
||||
return (ticks);
|
||||
}
|
||||
|
||||
Uint64
|
||||
SDL_GetPerformanceCounter(void)
|
||||
{
|
||||
Uint64 ticks;
|
||||
if (!ticks_started) {
|
||||
SDL_InitTicks();
|
||||
}
|
||||
|
||||
if (has_monotonic_time) {
|
||||
#if HAVE_CLOCK_GETTIME
|
||||
struct timespec now;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
ticks = now.tv_sec;
|
||||
ticks *= 1000000000;
|
||||
ticks += now.tv_nsec;
|
||||
#elif defined(__APPLE__)
|
||||
ticks = mach_absolute_time();
|
||||
#endif
|
||||
} else {
|
||||
struct timeval now;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
ticks = now.tv_sec;
|
||||
ticks *= 1000000;
|
||||
ticks += now.tv_usec;
|
||||
}
|
||||
return (ticks);
|
||||
}
|
||||
|
||||
Uint64
|
||||
SDL_GetPerformanceFrequency(void)
|
||||
{
|
||||
if (!ticks_started) {
|
||||
SDL_InitTicks();
|
||||
}
|
||||
|
||||
if (has_monotonic_time) {
|
||||
#if HAVE_CLOCK_GETTIME
|
||||
return 1000000000;
|
||||
#elif defined(__APPLE__)
|
||||
Uint64 freq = mach_base_info.denom;
|
||||
freq *= 1000000000;
|
||||
freq /= mach_base_info.numer;
|
||||
return freq;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 1000000;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_Delay(Uint32 ms)
|
||||
{
|
||||
int was_error;
|
||||
|
||||
#if HAVE_NANOSLEEP
|
||||
struct timespec elapsed, tv;
|
||||
#else
|
||||
struct timeval tv;
|
||||
Uint32 then, now, elapsed;
|
||||
#endif
|
||||
|
||||
/* Set the timeout interval */
|
||||
#if HAVE_NANOSLEEP
|
||||
elapsed.tv_sec = ms / 1000;
|
||||
elapsed.tv_nsec = (ms % 1000) * 1000000;
|
||||
#else
|
||||
then = SDL_GetTicks();
|
||||
#endif
|
||||
do {
|
||||
errno = 0;
|
||||
|
||||
#if HAVE_NANOSLEEP
|
||||
tv.tv_sec = elapsed.tv_sec;
|
||||
tv.tv_nsec = elapsed.tv_nsec;
|
||||
was_error = nanosleep(&tv, &elapsed);
|
||||
#else
|
||||
/* Calculate the time interval left (in case of interrupt) */
|
||||
now = SDL_GetTicks();
|
||||
elapsed = (now - then);
|
||||
then = now;
|
||||
if (elapsed >= ms) {
|
||||
break;
|
||||
}
|
||||
ms -= elapsed;
|
||||
tv.tv_sec = ms / 1000;
|
||||
tv.tv_usec = (ms % 1000) * 1000;
|
||||
|
||||
was_error = select(0, NULL, NULL, NULL, &tv);
|
||||
#endif /* HAVE_NANOSLEEP */
|
||||
} while (was_error && (errno == EINTR));
|
||||
}
|
||||
|
||||
#endif /* SDL_TIMER_UNIX */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,169 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#ifdef SDL_TIMER_WINDOWS
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include "SDL_timer.h"
|
||||
#include "SDL_hints.h"
|
||||
|
||||
|
||||
/* The first (low-resolution) ticks value of the application */
|
||||
static DWORD start;
|
||||
static BOOL ticks_started = FALSE;
|
||||
|
||||
#ifndef USE_GETTICKCOUNT
|
||||
/* Store if a high-resolution performance counter exists on the system */
|
||||
static BOOL hires_timer_available;
|
||||
/* The first high-resolution ticks value of the application */
|
||||
static LARGE_INTEGER hires_start_ticks;
|
||||
/* The number of ticks per second of the high-resolution performance counter */
|
||||
static LARGE_INTEGER hires_ticks_per_second;
|
||||
#endif
|
||||
|
||||
static void
|
||||
timeSetPeriod(UINT uPeriod)
|
||||
{
|
||||
static UINT timer_period = 0;
|
||||
|
||||
if (uPeriod != timer_period) {
|
||||
if (timer_period) {
|
||||
timeEndPeriod(timer_period);
|
||||
}
|
||||
|
||||
timer_period = uPeriod;
|
||||
|
||||
if (timer_period) {
|
||||
timeBeginPeriod(timer_period);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_TimerResolutionChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
|
||||
{
|
||||
UINT uPeriod;
|
||||
|
||||
/* Unless the hint says otherwise, let's have good sleep precision */
|
||||
if (hint && *hint) {
|
||||
uPeriod = SDL_atoi(hint);
|
||||
} else {
|
||||
uPeriod = 1;
|
||||
}
|
||||
if (uPeriod || oldValue != hint) {
|
||||
timeSetPeriod(uPeriod);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SDL_InitTicks(void)
|
||||
{
|
||||
if (ticks_started) {
|
||||
return;
|
||||
}
|
||||
ticks_started = TRUE;
|
||||
|
||||
/* Set first ticks value */
|
||||
#ifdef USE_GETTICKCOUNT
|
||||
start = GetTickCount();
|
||||
#else
|
||||
/* QueryPerformanceCounter has had problems in the past, but lots of games
|
||||
use it, so we'll rely on it here.
|
||||
*/
|
||||
if (QueryPerformanceFrequency(&hires_ticks_per_second) == TRUE) {
|
||||
hires_timer_available = TRUE;
|
||||
QueryPerformanceCounter(&hires_start_ticks);
|
||||
} else {
|
||||
hires_timer_available = FALSE;
|
||||
timeSetPeriod(1); /* use 1 ms timer precision */
|
||||
start = timeGetTime();
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_AddHintCallback(SDL_HINT_TIMER_RESOLUTION,
|
||||
SDL_TimerResolutionChanged, NULL);
|
||||
}
|
||||
|
||||
Uint32
|
||||
SDL_GetTicks(void)
|
||||
{
|
||||
DWORD now;
|
||||
#ifndef USE_GETTICKCOUNT
|
||||
LARGE_INTEGER hires_now;
|
||||
#endif
|
||||
|
||||
if (!ticks_started) {
|
||||
SDL_InitTicks();
|
||||
}
|
||||
|
||||
#ifdef USE_GETTICKCOUNT
|
||||
now = GetTickCount();
|
||||
#else
|
||||
if (hires_timer_available) {
|
||||
QueryPerformanceCounter(&hires_now);
|
||||
|
||||
hires_now.QuadPart -= hires_start_ticks.QuadPart;
|
||||
hires_now.QuadPart *= 1000;
|
||||
hires_now.QuadPart /= hires_ticks_per_second.QuadPart;
|
||||
|
||||
return (DWORD) hires_now.QuadPart;
|
||||
} else {
|
||||
now = timeGetTime();
|
||||
}
|
||||
#endif
|
||||
|
||||
return (now - start);
|
||||
}
|
||||
|
||||
Uint64
|
||||
SDL_GetPerformanceCounter(void)
|
||||
{
|
||||
LARGE_INTEGER counter;
|
||||
|
||||
if (!QueryPerformanceCounter(&counter)) {
|
||||
return SDL_GetTicks();
|
||||
}
|
||||
return counter.QuadPart;
|
||||
}
|
||||
|
||||
Uint64
|
||||
SDL_GetPerformanceFrequency(void)
|
||||
{
|
||||
LARGE_INTEGER frequency;
|
||||
|
||||
if (!QueryPerformanceFrequency(&frequency)) {
|
||||
return 1000;
|
||||
}
|
||||
return frequency.QuadPart;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_Delay(Uint32 ms)
|
||||
{
|
||||
Sleep(ms);
|
||||
}
|
||||
|
||||
#endif /* SDL_TIMER_WINDOWS */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,325 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_COCOA
|
||||
|
||||
#include "SDL_assert.h"
|
||||
#include "SDL_events.h"
|
||||
#include "SDL_cocoamouse.h"
|
||||
#include "SDL_cocoamousetap.h"
|
||||
|
||||
#include "../../events/SDL_mouse_c.h"
|
||||
|
||||
@implementation NSCursor (InvisibleCursor)
|
||||
+ (NSCursor *)invisibleCursor
|
||||
{
|
||||
static NSCursor *invisibleCursor = NULL;
|
||||
if (!invisibleCursor) {
|
||||
/* RAW 16x16 transparent GIF */
|
||||
static unsigned char cursorBytes[] = {
|
||||
0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x10, 0x00, 0x10, 0x00, 0x80,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xF9, 0x04,
|
||||
0x01, 0x00, 0x00, 0x01, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x10,
|
||||
0x00, 0x10, 0x00, 0x00, 0x02, 0x0E, 0x8C, 0x8F, 0xA9, 0xCB, 0xED,
|
||||
0x0F, 0xA3, 0x9C, 0xB4, 0xDA, 0x8B, 0xB3, 0x3E, 0x05, 0x00, 0x3B
|
||||
};
|
||||
|
||||
NSData *cursorData = [NSData dataWithBytesNoCopy:&cursorBytes[0]
|
||||
length:sizeof(cursorBytes)
|
||||
freeWhenDone:NO];
|
||||
NSImage *cursorImage = [[[NSImage alloc] initWithData:cursorData] autorelease];
|
||||
invisibleCursor = [[NSCursor alloc] initWithImage:cursorImage
|
||||
hotSpot:NSZeroPoint];
|
||||
}
|
||||
|
||||
return invisibleCursor;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
static SDL_Cursor *
|
||||
Cocoa_CreateDefaultCursor()
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
NSCursor *nscursor;
|
||||
SDL_Cursor *cursor = NULL;
|
||||
|
||||
nscursor = [NSCursor arrowCursor];
|
||||
|
||||
if (nscursor) {
|
||||
cursor = SDL_calloc(1, sizeof(*cursor));
|
||||
if (cursor) {
|
||||
cursor->driverdata = nscursor;
|
||||
[nscursor retain];
|
||||
}
|
||||
}
|
||||
|
||||
[pool release];
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
static SDL_Cursor *
|
||||
Cocoa_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
NSImage *nsimage;
|
||||
NSCursor *nscursor = NULL;
|
||||
SDL_Cursor *cursor = NULL;
|
||||
|
||||
nsimage = Cocoa_CreateImage(surface);
|
||||
if (nsimage) {
|
||||
nscursor = [[NSCursor alloc] initWithImage: nsimage hotSpot: NSMakePoint(hot_x, hot_y)];
|
||||
}
|
||||
|
||||
if (nscursor) {
|
||||
cursor = SDL_calloc(1, sizeof(*cursor));
|
||||
if (cursor) {
|
||||
cursor->driverdata = nscursor;
|
||||
} else {
|
||||
[nscursor release];
|
||||
}
|
||||
}
|
||||
|
||||
[pool release];
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
static SDL_Cursor *
|
||||
Cocoa_CreateSystemCursor(SDL_SystemCursor id)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
NSCursor *nscursor = NULL;
|
||||
SDL_Cursor *cursor = NULL;
|
||||
|
||||
switch(id)
|
||||
{
|
||||
case SDL_SYSTEM_CURSOR_ARROW:
|
||||
nscursor = [NSCursor arrowCursor];
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_IBEAM:
|
||||
nscursor = [NSCursor IBeamCursor];
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_WAIT:
|
||||
nscursor = [NSCursor arrowCursor];
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_CROSSHAIR:
|
||||
nscursor = [NSCursor crosshairCursor];
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_WAITARROW:
|
||||
nscursor = [NSCursor arrowCursor];
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_SIZENWSE:
|
||||
case SDL_SYSTEM_CURSOR_SIZENESW:
|
||||
nscursor = [NSCursor closedHandCursor];
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_SIZEWE:
|
||||
nscursor = [NSCursor resizeLeftRightCursor];
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_SIZENS:
|
||||
nscursor = [NSCursor resizeUpDownCursor];
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_SIZEALL:
|
||||
nscursor = [NSCursor closedHandCursor];
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_NO:
|
||||
nscursor = [NSCursor operationNotAllowedCursor];
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_HAND:
|
||||
nscursor = [NSCursor pointingHandCursor];
|
||||
break;
|
||||
default:
|
||||
SDL_assert(!"Unknown system cursor");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (nscursor) {
|
||||
cursor = SDL_calloc(1, sizeof(*cursor));
|
||||
if (cursor) {
|
||||
/* We'll free it later, so retain it here */
|
||||
[nscursor retain];
|
||||
cursor->driverdata = nscursor;
|
||||
}
|
||||
}
|
||||
|
||||
[pool release];
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
static void
|
||||
Cocoa_FreeCursor(SDL_Cursor * cursor)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
NSCursor *nscursor = (NSCursor *)cursor->driverdata;
|
||||
|
||||
[nscursor release];
|
||||
SDL_free(cursor);
|
||||
|
||||
[pool release];
|
||||
}
|
||||
|
||||
static int
|
||||
Cocoa_ShowCursor(SDL_Cursor * cursor)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
SDL_VideoDevice *device = SDL_GetVideoDevice();
|
||||
SDL_Window *window = (device ? device->windows : NULL);
|
||||
for (; window != NULL; window = window->next) {
|
||||
SDL_WindowData *driverdata = (SDL_WindowData *)window->driverdata;
|
||||
if (driverdata) {
|
||||
[driverdata->nswindow performSelectorOnMainThread:@selector(invalidateCursorRectsForView:)
|
||||
withObject:[driverdata->nswindow contentView]
|
||||
waitUntilDone:NO];
|
||||
}
|
||||
}
|
||||
|
||||
[pool release];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
Cocoa_WarpMouse(SDL_Window * window, int x, int y)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
CGPoint point = CGPointMake(x + (float)window->x, y + (float)window->y);
|
||||
|
||||
{
|
||||
/* This makes Cocoa_HandleMouseEvent ignore this delta in the next
|
||||
* movement event.
|
||||
*/
|
||||
SDL_MouseData *driverdata = (SDL_MouseData*)mouse->driverdata;
|
||||
NSPoint location = [NSEvent mouseLocation];
|
||||
driverdata->deltaXOffset = location.x - point.x;
|
||||
driverdata->deltaYOffset = point.y - location.y;
|
||||
}
|
||||
|
||||
/* According to the docs, this was deprecated in 10.6, but it's still
|
||||
* around. The substitute requires a CGEventSource, but I'm not entirely
|
||||
* sure how we'd procure the right one for this event.
|
||||
*/
|
||||
CGSetLocalEventsSuppressionInterval(0.0);
|
||||
CGWarpMouseCursorPosition(point);
|
||||
CGSetLocalEventsSuppressionInterval(0.25);
|
||||
|
||||
if (!mouse->relative_mode) {
|
||||
/* CGWarpMouseCursorPosition doesn't generate a window event, unlike our
|
||||
* other implementations' APIs.
|
||||
*/
|
||||
SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
Cocoa_SetRelativeMouseMode(SDL_bool enabled)
|
||||
{
|
||||
CGError result;
|
||||
|
||||
if (enabled) {
|
||||
result = CGAssociateMouseAndMouseCursorPosition(NO);
|
||||
} else {
|
||||
result = CGAssociateMouseAndMouseCursorPosition(YES);
|
||||
}
|
||||
if (result != kCGErrorSuccess) {
|
||||
return SDL_SetError("CGAssociateMouseAndMouseCursorPosition() failed");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Cocoa_InitMouse(_THIS)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
|
||||
mouse->driverdata = SDL_calloc(1, sizeof(SDL_MouseData));
|
||||
|
||||
mouse->CreateCursor = Cocoa_CreateCursor;
|
||||
mouse->CreateSystemCursor = Cocoa_CreateSystemCursor;
|
||||
mouse->ShowCursor = Cocoa_ShowCursor;
|
||||
mouse->FreeCursor = Cocoa_FreeCursor;
|
||||
mouse->WarpMouse = Cocoa_WarpMouse;
|
||||
mouse->SetRelativeMouseMode = Cocoa_SetRelativeMouseMode;
|
||||
|
||||
SDL_SetDefaultCursor(Cocoa_CreateDefaultCursor());
|
||||
|
||||
Cocoa_InitMouseEventTap(mouse->driverdata);
|
||||
}
|
||||
|
||||
void
|
||||
Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
|
||||
if (mouse->relative_mode &&
|
||||
([event type] == NSMouseMoved ||
|
||||
[event type] == NSLeftMouseDragged ||
|
||||
[event type] == NSRightMouseDragged ||
|
||||
[event type] == NSOtherMouseDragged)) {
|
||||
SDL_MouseData *driverdata = (SDL_MouseData*)mouse->driverdata;
|
||||
float x = [event deltaX] + driverdata->deltaXOffset;
|
||||
float y = [event deltaY] + driverdata->deltaYOffset;
|
||||
driverdata->deltaXOffset = driverdata->deltaYOffset = 0;
|
||||
|
||||
SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 1, (int)x, (int)y);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
|
||||
float x = [event deltaX];
|
||||
float y = [event deltaY];
|
||||
|
||||
if (x > 0) {
|
||||
x += 0.9f;
|
||||
} else if (x < 0) {
|
||||
x -= 0.9f;
|
||||
}
|
||||
if (y > 0) {
|
||||
y += 0.9f;
|
||||
} else if (y < 0) {
|
||||
y -= 0.9f;
|
||||
}
|
||||
SDL_SendMouseWheel(window, mouse->mouseID, (int)x, (int)y);
|
||||
}
|
||||
|
||||
void
|
||||
Cocoa_QuitMouse(_THIS)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
if (mouse) {
|
||||
if (mouse->driverdata) {
|
||||
Cocoa_QuitMouseEventTap(((SDL_MouseData*)mouse->driverdata));
|
||||
}
|
||||
|
||||
SDL_free(mouse->driverdata);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_COCOA */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,252 +0,0 @@
|
||||
# Makefile to build the SDL tests
|
||||
|
||||
srcdir = @srcdir@
|
||||
|
||||
CC = @CC@
|
||||
EXE = @EXE@
|
||||
CFLAGS = @CFLAGS@ -g
|
||||
LIBS = @LIBS@
|
||||
|
||||
TARGETS = \
|
||||
checkkeys$(EXE) \
|
||||
loopwave$(EXE) \
|
||||
testaudioinfo$(EXE) \
|
||||
testautomation$(EXE) \
|
||||
testdraw2$(EXE) \
|
||||
testdrawchessboard$(EXE) \
|
||||
testdropfile$(EXE) \
|
||||
testerror$(EXE) \
|
||||
testfile$(EXE) \
|
||||
testgamecontroller$(EXE) \
|
||||
testgesture$(EXE) \
|
||||
testgl2$(EXE) \
|
||||
testgles$(EXE) \
|
||||
testgles2$(EXE) \
|
||||
testhaptic$(EXE) \
|
||||
testrumble$(EXE) \
|
||||
testthread$(EXE) \
|
||||
testiconv$(EXE) \
|
||||
testime$(EXE) \
|
||||
testintersections$(EXE) \
|
||||
testrelative$(EXE) \
|
||||
testjoystick$(EXE) \
|
||||
testkeys$(EXE) \
|
||||
testloadso$(EXE) \
|
||||
testlock$(EXE) \
|
||||
testmultiaudio$(EXE) \
|
||||
testnative$(EXE) \
|
||||
testoverlay2$(EXE) \
|
||||
testplatform$(EXE) \
|
||||
testpower$(EXE) \
|
||||
testfilesystem$(EXE) \
|
||||
testrendertarget$(EXE) \
|
||||
testresample$(EXE) \
|
||||
testscale$(EXE) \
|
||||
testsem$(EXE) \
|
||||
testshader$(EXE) \
|
||||
testshape$(EXE) \
|
||||
testsprite2$(EXE) \
|
||||
testspriteminimal$(EXE) \
|
||||
teststreaming$(EXE) \
|
||||
testtimer$(EXE) \
|
||||
testver$(EXE) \
|
||||
testviewport$(EXE) \
|
||||
testwm2$(EXE) \
|
||||
torturethread$(EXE) \
|
||||
testrendercopyex$(EXE) \
|
||||
testmessage$(EXE) \
|
||||
controllermap$(EXE) \
|
||||
|
||||
all: Makefile $(TARGETS)
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in
|
||||
$(SHELL) config.status $@
|
||||
|
||||
checkkeys$(EXE): $(srcdir)/checkkeys.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
loopwave$(EXE): $(srcdir)/loopwave.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testresample$(EXE): $(srcdir)/testresample.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testaudioinfo$(EXE): $(srcdir)/testaudioinfo.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testautomation$(EXE): $(srcdir)/testautomation.c \
|
||||
$(srcdir)/testautomation_audio.c \
|
||||
$(srcdir)/testautomation_clipboard.c \
|
||||
$(srcdir)/testautomation_events.c \
|
||||
$(srcdir)/testautomation_keyboard.c \
|
||||
$(srcdir)/testautomation_main.c \
|
||||
$(srcdir)/testautomation_mouse.c \
|
||||
$(srcdir)/testautomation_pixels.c \
|
||||
$(srcdir)/testautomation_platform.c \
|
||||
$(srcdir)/testautomation_rect.c \
|
||||
$(srcdir)/testautomation_render.c \
|
||||
$(srcdir)/testautomation_rwops.c \
|
||||
$(srcdir)/testautomation_sdltest.c \
|
||||
$(srcdir)/testautomation_stdlib.c \
|
||||
$(srcdir)/testautomation_surface.c \
|
||||
$(srcdir)/testautomation_syswm.c \
|
||||
$(srcdir)/testautomation_timer.c \
|
||||
$(srcdir)/testautomation_video.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testmultiaudio$(EXE): $(srcdir)/testmultiaudio.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testatomic$(EXE): $(srcdir)/testatomic.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testintersections$(EXE): $(srcdir)/testintersections.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testrelative$(EXE): $(srcdir)/testrelative.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testdraw2$(EXE): $(srcdir)/testdraw2.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testdrawchessboard$(EXE): $(srcdir)/testdrawchessboard.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testdropfile$(EXE): $(srcdir)/testdropfile.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testerror$(EXE): $(srcdir)/testerror.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testfile$(EXE): $(srcdir)/testfile.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testgamecontroller$(EXE): $(srcdir)/testgamecontroller.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testgesture$(EXE): $(srcdir)/testgesture.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@
|
||||
|
||||
testgl2$(EXE): $(srcdir)/testgl2.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@
|
||||
|
||||
testgles$(EXE): $(srcdir)/testgles.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @GLESLIB@ @MATHLIB@
|
||||
|
||||
testgles2$(EXE): $(srcdir)/testgles2.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@
|
||||
|
||||
testhaptic$(EXE): $(srcdir)/testhaptic.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testrumble$(EXE): $(srcdir)/testrumble.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testthread$(EXE): $(srcdir)/testthread.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testiconv$(EXE): $(srcdir)/testiconv.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testime$(EXE): $(srcdir)/testime.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @SDL_TTF_LIB@
|
||||
|
||||
testjoystick$(EXE): $(srcdir)/testjoystick.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testkeys$(EXE): $(srcdir)/testkeys.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testloadso$(EXE): $(srcdir)/testloadso.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testlock$(EXE): $(srcdir)/testlock.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
ifeq (@ISMACOSX@,true)
|
||||
testnative$(EXE): $(srcdir)/testnative.c \
|
||||
$(srcdir)/testnativecocoa.m \
|
||||
$(srcdir)/testnativex11.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) -framework Cocoa @XLIB@
|
||||
endif
|
||||
|
||||
ifeq (@ISWINDOWS@,true)
|
||||
testnative$(EXE): $(srcdir)/testnative.c \
|
||||
$(srcdir)/testnativew32.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
endif
|
||||
|
||||
ifeq (@ISUNIX@,true)
|
||||
testnative$(EXE): $(srcdir)/testnative.c \
|
||||
$(srcdir)/testnativex11.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @XLIB@
|
||||
endif
|
||||
|
||||
testoverlay2$(EXE): $(srcdir)/testoverlay2.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testplatform$(EXE): $(srcdir)/testplatform.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testpower$(EXE): $(srcdir)/testpower.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testfilesystem$(EXE): $(srcdir)/testfilesystem.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testrendertarget$(EXE): $(srcdir)/testrendertarget.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testscale$(EXE): $(srcdir)/testscale.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testsem$(EXE): $(srcdir)/testsem.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testshader$(EXE): $(srcdir)/testshader.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @GLLIB@ @MATHLIB@
|
||||
|
||||
testshape$(EXE): $(srcdir)/testshape.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testsprite2$(EXE): $(srcdir)/testsprite2.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testspriteminimal$(EXE): $(srcdir)/testspriteminimal.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@
|
||||
|
||||
teststreaming$(EXE): $(srcdir)/teststreaming.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@
|
||||
|
||||
testtimer$(EXE): $(srcdir)/testtimer.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testver$(EXE): $(srcdir)/testver.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testviewport$(EXE): $(srcdir)/testviewport.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testwm2$(EXE): $(srcdir)/testwm2.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
torturethread$(EXE): $(srcdir)/torturethread.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testrendercopyex$(EXE): $(srcdir)/testrendercopyex.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@
|
||||
|
||||
testmessage$(EXE): $(srcdir)/testmessage.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
controllermap$(EXE): $(srcdir)/controllermap.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
|
||||
clean:
|
||||
rm -f $(TARGETS)
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile
|
||||
rm -f config.status config.cache config.log
|
||||
rm -rf $(srcdir)/autom4te*
|
||||
@@ -1,314 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/* Simple program to test the SDL game controller routines */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "SDL.h"
|
||||
|
||||
#ifndef SDL_JOYSTICK_DISABLED
|
||||
|
||||
#ifdef __IPHONEOS__
|
||||
#define SCREEN_WIDTH 320
|
||||
#define SCREEN_HEIGHT 480
|
||||
#else
|
||||
#define SCREEN_WIDTH 640
|
||||
#define SCREEN_HEIGHT 480
|
||||
#endif
|
||||
|
||||
#define MAX_NUM_AXES 6
|
||||
#define MAX_NUM_HATS 2
|
||||
|
||||
static void
|
||||
DrawRect(SDL_Renderer *r, const int x, const int y, const int w, const int h)
|
||||
{
|
||||
const SDL_Rect area = { x, y, w, h };
|
||||
SDL_RenderFillRect(r, &area);
|
||||
}
|
||||
|
||||
static const char *
|
||||
ControllerAxisName(const SDL_GameControllerAxis axis)
|
||||
{
|
||||
switch (axis)
|
||||
{
|
||||
#define AXIS_CASE(ax) case SDL_CONTROLLER_AXIS_##ax: return #ax
|
||||
AXIS_CASE(INVALID);
|
||||
AXIS_CASE(LEFTX);
|
||||
AXIS_CASE(LEFTY);
|
||||
AXIS_CASE(RIGHTX);
|
||||
AXIS_CASE(RIGHTY);
|
||||
AXIS_CASE(TRIGGERLEFT);
|
||||
AXIS_CASE(TRIGGERRIGHT);
|
||||
#undef AXIS_CASE
|
||||
default: return "???";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
ControllerButtonName(const SDL_GameControllerButton button)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
#define BUTTON_CASE(btn) case SDL_CONTROLLER_BUTTON_##btn: return #btn
|
||||
BUTTON_CASE(INVALID);
|
||||
BUTTON_CASE(A);
|
||||
BUTTON_CASE(B);
|
||||
BUTTON_CASE(X);
|
||||
BUTTON_CASE(Y);
|
||||
BUTTON_CASE(BACK);
|
||||
BUTTON_CASE(GUIDE);
|
||||
BUTTON_CASE(START);
|
||||
BUTTON_CASE(LEFTSTICK);
|
||||
BUTTON_CASE(RIGHTSTICK);
|
||||
BUTTON_CASE(LEFTSHOULDER);
|
||||
BUTTON_CASE(RIGHTSHOULDER);
|
||||
BUTTON_CASE(DPAD_UP);
|
||||
BUTTON_CASE(DPAD_DOWN);
|
||||
BUTTON_CASE(DPAD_LEFT);
|
||||
BUTTON_CASE(DPAD_RIGHT);
|
||||
#undef BUTTON_CASE
|
||||
default: return "???";
|
||||
}
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
WatchGameController(SDL_GameController * gamecontroller)
|
||||
{
|
||||
const char *name = SDL_GameControllerName(gamecontroller);
|
||||
const char *basetitle = "Game Controller Test: ";
|
||||
const size_t titlelen = SDL_strlen(basetitle) + SDL_strlen(name) + 1;
|
||||
char *title = (char *)SDL_malloc(titlelen);
|
||||
SDL_Window *window = NULL;
|
||||
SDL_Renderer *screen = NULL;
|
||||
SDL_bool retval = SDL_FALSE;
|
||||
SDL_bool done = SDL_FALSE;
|
||||
SDL_Event event;
|
||||
int i;
|
||||
|
||||
if (title) {
|
||||
SDL_snprintf(title, titlelen, "%s%s", basetitle, name);
|
||||
}
|
||||
|
||||
/* Create a window to display controller axis position */
|
||||
window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED,
|
||||
SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH,
|
||||
SCREEN_HEIGHT, 0);
|
||||
if (window == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError());
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
screen = SDL_CreateRenderer(window, -1, 0);
|
||||
if (screen == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError());
|
||||
SDL_DestroyWindow(window);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE);
|
||||
SDL_RenderClear(screen);
|
||||
SDL_RenderPresent(screen);
|
||||
SDL_RaiseWindow(window);
|
||||
|
||||
/* Print info about the controller we are watching */
|
||||
SDL_Log("Watching controller %s\n", name ? name : "Unknown Controller");
|
||||
|
||||
/* Loop, getting controller events! */
|
||||
while (!done) {
|
||||
/* blank screen, set up for drawing this frame. */
|
||||
SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE);
|
||||
SDL_RenderClear(screen);
|
||||
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
SDL_Log("Controller %d axis %d ('%s') value: %d\n",
|
||||
event.caxis.which,
|
||||
event.caxis.axis,
|
||||
ControllerAxisName((SDL_GameControllerAxis)event.caxis.axis),
|
||||
event.caxis.value);
|
||||
break;
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
SDL_Log("Controller %d button %d ('%s') down\n",
|
||||
event.cbutton.which, event.cbutton.button,
|
||||
ControllerButtonName((SDL_GameControllerButton)event.cbutton.button));
|
||||
break;
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
SDL_Log("Controller %d button %d ('%s') up\n",
|
||||
event.cbutton.which, event.cbutton.button,
|
||||
ControllerButtonName((SDL_GameControllerButton)event.cbutton.button));
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
if (event.key.keysym.sym != SDLK_ESCAPE) {
|
||||
break;
|
||||
}
|
||||
/* Fall through to signal quit */
|
||||
case SDL_QUIT:
|
||||
done = SDL_TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Update visual controller state */
|
||||
SDL_SetRenderDrawColor(screen, 0x00, 0xFF, 0x00, SDL_ALPHA_OPAQUE);
|
||||
for (i = 0; i <SDL_CONTROLLER_BUTTON_MAX; ++i) {
|
||||
if (SDL_GameControllerGetButton(gamecontroller, (SDL_GameControllerButton)i) == SDL_PRESSED) {
|
||||
DrawRect(screen, i * 34, SCREEN_HEIGHT - 34, 32, 32);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_SetRenderDrawColor(screen, 0xFF, 0x00, 0x00, SDL_ALPHA_OPAQUE);
|
||||
for (i = 0; i < SDL_CONTROLLER_AXIS_MAX / 2; ++i) {
|
||||
/* Draw the X/Y axis */
|
||||
int x, y;
|
||||
x = (((int) SDL_GameControllerGetAxis(gamecontroller, (SDL_GameControllerAxis)(i * 2 + 0))) + 32768);
|
||||
x *= SCREEN_WIDTH;
|
||||
x /= 65535;
|
||||
if (x < 0) {
|
||||
x = 0;
|
||||
} else if (x > (SCREEN_WIDTH - 16)) {
|
||||
x = SCREEN_WIDTH - 16;
|
||||
}
|
||||
y = (((int) SDL_GameControllerGetAxis(gamecontroller, (SDL_GameControllerAxis)(i * 2 + 1))) + 32768);
|
||||
y *= SCREEN_HEIGHT;
|
||||
y /= 65535;
|
||||
if (y < 0) {
|
||||
y = 0;
|
||||
} else if (y > (SCREEN_HEIGHT - 16)) {
|
||||
y = SCREEN_HEIGHT - 16;
|
||||
}
|
||||
|
||||
DrawRect(screen, x, y, 16, 16);
|
||||
}
|
||||
|
||||
SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0xFF, SDL_ALPHA_OPAQUE);
|
||||
|
||||
SDL_RenderPresent(screen);
|
||||
|
||||
if (!SDL_GameControllerGetAttached(gamecontroller)) {
|
||||
done = SDL_TRUE;
|
||||
retval = SDL_TRUE; /* keep going, wait for reattach. */
|
||||
}
|
||||
}
|
||||
|
||||
SDL_DestroyRenderer(screen);
|
||||
SDL_DestroyWindow(window);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
int nController = 0;
|
||||
int retcode = 0;
|
||||
char guid[64];
|
||||
SDL_GameController *gamecontroller;
|
||||
|
||||
/* Enable standard application logging */
|
||||
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
|
||||
|
||||
/* Initialize SDL (Note: video is required to start event loop) */
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER ) < 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt");
|
||||
|
||||
/* Print information about the controller */
|
||||
for (i = 0; i < SDL_NumJoysticks(); ++i) {
|
||||
const char *name;
|
||||
const char *description;
|
||||
|
||||
SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(i),
|
||||
guid, sizeof (guid));
|
||||
|
||||
if ( SDL_IsGameController(i) )
|
||||
{
|
||||
nController++;
|
||||
name = SDL_GameControllerNameForIndex(i);
|
||||
description = "Controller";
|
||||
} else {
|
||||
name = SDL_JoystickNameForIndex(i);
|
||||
description = "Joystick";
|
||||
}
|
||||
SDL_Log("%s %d: %s (guid %s)\n", description, i, name ? name : "Unknown", guid);
|
||||
}
|
||||
SDL_Log("There are %d game controller(s) attached (%d joystick(s))\n", nController, SDL_NumJoysticks());
|
||||
|
||||
if (argv[1]) {
|
||||
SDL_bool reportederror = SDL_FALSE;
|
||||
SDL_bool keepGoing = SDL_TRUE;
|
||||
SDL_Event event;
|
||||
int device = atoi(argv[1]);
|
||||
if (device >= SDL_NumJoysticks()) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%i is an invalid joystick index.\n", device);
|
||||
retcode = 1;
|
||||
} else {
|
||||
SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(device),
|
||||
guid, sizeof (guid));
|
||||
SDL_Log("Attempting to open device %i, guid %s\n", device, guid);
|
||||
gamecontroller = SDL_GameControllerOpen(device);
|
||||
while (keepGoing) {
|
||||
if (gamecontroller == NULL) {
|
||||
if (!reportederror) {
|
||||
if (gamecontroller == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open gamecontroller %d: %s\n", device, SDL_GetError());
|
||||
retcode = 1;
|
||||
}
|
||||
keepGoing = SDL_FALSE;
|
||||
reportederror = SDL_TRUE;
|
||||
}
|
||||
} else {
|
||||
reportederror = SDL_FALSE;
|
||||
keepGoing = WatchGameController(gamecontroller);
|
||||
SDL_GameControllerClose(gamecontroller);
|
||||
}
|
||||
|
||||
gamecontroller = NULL;
|
||||
if (keepGoing) {
|
||||
SDL_Log("Waiting for attach\n");
|
||||
}
|
||||
while (keepGoing) {
|
||||
SDL_WaitEvent(&event);
|
||||
if ((event.type == SDL_QUIT) || (event.type == SDL_FINGERDOWN)
|
||||
|| (event.type == SDL_MOUSEBUTTONDOWN)) {
|
||||
keepGoing = SDL_FALSE;
|
||||
} else if (event.type == SDL_CONTROLLERDEVICEADDED) {
|
||||
gamecontroller = SDL_GameControllerOpen(event.cdevice.which);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL compiled without Joystick support.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,5 @@
|
||||
repo: 74212992fb0868a6929180cd74dd67e38507340a
|
||||
node: aa058c87737b9bf9f87b187d68b648428daa3830
|
||||
branch: default
|
||||
latesttag: release-2.0.3
|
||||
latesttagdistance: 348
|
||||
@@ -0,0 +1,123 @@
|
||||
syntax:glob
|
||||
aclocal.m4
|
||||
autom4te*
|
||||
config.cache
|
||||
config.log
|
||||
config.status
|
||||
Makefile
|
||||
sdl-config
|
||||
SDL2.spec
|
||||
build
|
||||
|
||||
# for Xcode
|
||||
*.orig
|
||||
*.swp
|
||||
*.tmp
|
||||
*.rej
|
||||
*~
|
||||
*.o
|
||||
*.mode1*
|
||||
*.model*
|
||||
*.perspective*
|
||||
*.perspective*
|
||||
*.pbxuser
|
||||
(^|/)build($|/)
|
||||
.DS_Store
|
||||
Xcode/SDL/SDL.xcodeproj/xcuserdata
|
||||
Xcode/SDL/SDL.xcodeproj/project.xcworkspace
|
||||
Xcode/SDLTest/SDLTest.xcodeproj/xcuserdata
|
||||
Xcode/SDLTest/SDLTest.xcodeproj/project.xcworkspace
|
||||
Xcode-iOS/SDL/SDL.xcodeproj/xcuserdata
|
||||
Xcode-iOS/SDL/SDL.xcodeproj/project.xcworkspace
|
||||
Xcode-iOS/Demos/Demos.xcodeproj/xcuserdata
|
||||
Xcode-iOS/Demos/Demos.xcodeproj/project.xcworkspace
|
||||
|
||||
# for Visual C++
|
||||
Debug
|
||||
Release
|
||||
*.user
|
||||
*.ncb
|
||||
*.suo
|
||||
*.sdf
|
||||
VisualC/tests/loopwave/sample.wav
|
||||
VisualC/tests/testautomation/CompareSurfaces0001_Reference.bmp
|
||||
VisualC/tests/testautomation/CompareSurfaces0001_TestOutput.bmp
|
||||
VisualC/tests/testgamecontroller/axis.bmp
|
||||
VisualC/tests/testgamecontroller/button.bmp
|
||||
VisualC/tests/testgamecontroller/controllermap.bmp
|
||||
VisualC/tests/testoverlay2/moose.dat
|
||||
VisualC/tests/testrendertarget/icon.bmp
|
||||
VisualC/tests/testrendertarget/sample.bmp
|
||||
VisualC/tests/testscale/icon.bmp
|
||||
VisualC/tests/testscale/sample.bmp
|
||||
VisualC/tests/testsprite2/icon.bmp
|
||||
VisualC/visualtest/icon.bmp
|
||||
VisualC/visualtest/testquit.actions
|
||||
VisualC/visualtest/testquit.config
|
||||
VisualC/visualtest/testquit.exe
|
||||
VisualC/visualtest/testquit.parameters
|
||||
VisualC/visualtest/testsprite2.exe
|
||||
VisualC/visualtest/testsprite2_sample.actions
|
||||
VisualC/visualtest/testsprite2_sample.config
|
||||
VisualC/visualtest/testsprite2_sample.parameters
|
||||
|
||||
# for Android
|
||||
android-project/local.properties
|
||||
|
||||
sdl.pc
|
||||
test/autom4te*
|
||||
test/config.cache
|
||||
test/config.log
|
||||
test/config.status
|
||||
test/Makefile
|
||||
test/SDL2.dll
|
||||
test/checkkeys
|
||||
test/loopwave
|
||||
test/loopwavequeue
|
||||
test/testatomic
|
||||
test/testaudioinfo
|
||||
test/testautomation
|
||||
test/testdraw2
|
||||
test/testerror
|
||||
test/testfile
|
||||
test/testgamecontroller
|
||||
test/testgesture
|
||||
test/testgl2
|
||||
test/testgles
|
||||
test/testhaptic
|
||||
test/testhittesting
|
||||
test/testiconv
|
||||
test/testime
|
||||
test/testintersections
|
||||
test/testjoystick
|
||||
test/testkeys
|
||||
test/testloadso
|
||||
test/testlock
|
||||
test/testmessage
|
||||
test/testmultiaudio
|
||||
test/testnative
|
||||
test/testoverlay2
|
||||
test/testplatform
|
||||
test/testpower
|
||||
test/testfilesystem
|
||||
test/testrelative
|
||||
test/testrendercopyex
|
||||
test/testrendertarget
|
||||
test/testresample
|
||||
test/testrumble
|
||||
test/testscale
|
||||
test/testsem
|
||||
test/testshader
|
||||
test/testshape
|
||||
test/testsprite2
|
||||
test/testspriteminimal
|
||||
test/teststreaming
|
||||
test/testthread
|
||||
test/testtimer
|
||||
test/testver
|
||||
test/testwm2
|
||||
test/torturethread
|
||||
test/*.exe
|
||||
test/*.dSYM
|
||||
buildbot
|
||||
test/buildbot
|
||||
@@ -0,0 +1,30 @@
|
||||
0afe0e38e02cf2048e93582f01c52fbb91d3c7bb release-1.2.7
|
||||
230b156829ed13b31134d96f689c917981f57b84 release-1.2.5
|
||||
27cab50ec9c746e886ce0f3fdaa0b0cdc55a594f release-1.2.11
|
||||
2fe3fbd2bff50165b3cad33bf40d70b3bb3c9fd0 release-1.2.3
|
||||
3c052d3bcc76c899dfd4846be76243a78e8c7180 release-1.2.4
|
||||
3c5eed71a3320962551af3b3dfbee0c99fcf0086 release-1.2.10
|
||||
4867f7f7dd3426d1dbbeef48b3f3b3aa19590cc4 release-1.2.12
|
||||
6e28dae59e3baf4447c83e833a8d2ac912536f5b release-1.2.1
|
||||
7c2589fb8d4df54c6faabd3faebd0c0e73f67879 release-1.2.13
|
||||
86de11faf082881ad9b73a1a1d78733ca07f8db8 release-1.2.6
|
||||
bb051fa871aa0b53ea57df56a446cec3bb85924c release-1.2.2
|
||||
cfcb2e1c36ebe9809577adf768b0ec53e8768af9 release-1.2.8
|
||||
e044e7c70a50a2f54d14ee20d0933e904e5853b6 release-1.2.9
|
||||
f14cf9d71233934811774f941d0de121d5f96ccf release-1.2.14
|
||||
39c22a953456f6c9e2c8993c8ff973824104102a pre-touch-removal
|
||||
ccf5fbfa2afabab429ad911308f362201a94d810 macosx_10_4_supported
|
||||
d6a8fa507a45d9de7258e51585eab3e45c415149 release-2.0.0
|
||||
a8bd63b33636715f2cf6e7d36ab7201acbd478fe release-2.0.1
|
||||
a8bd63b33636715f2cf6e7d36ab7201acbd478fe release-2.0.1
|
||||
715a01415ac9305b9f8ec72b99fcf8cc9dd64dde release-2.0.1
|
||||
715a01415ac9305b9f8ec72b99fcf8cc9dd64dde release-2.0.1
|
||||
9ec71e56071cc80eda6691a3f8719ed5395dfcfb release-2.0.1
|
||||
9ec71e56071cc80eda6691a3f8719ed5395dfcfb release-2.0.1
|
||||
0000000000000000000000000000000000000000 release-2.0.1
|
||||
0000000000000000000000000000000000000000 release-2.0.1
|
||||
b9663c77f5c95ebf05f3c18e80619caae8ae1460 release-2.0.1
|
||||
be2102f000d0d2d9bab75e9703a1d503d0f6bb33 release-2.0.2
|
||||
f285b9487756ff681f76c85644222c03a7bfa1c7 release-2.0.3
|
||||
f285b9487756ff681f76c85644222c03a7bfa1c7 release-2.0.3
|
||||
704a0bfecf754e4e1383f83c7d5118b00cae26ea release-2.0.3
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
###########################
|
||||
#
|
||||
# SDL shared library
|
||||
#
|
||||
###########################
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := SDL2
|
||||
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
|
||||
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(subst $(LOCAL_PATH)/,, \
|
||||
$(wildcard $(LOCAL_PATH)/src/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/audio/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/audio/android/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/audio/dummy/*.c) \
|
||||
$(LOCAL_PATH)/src/atomic/SDL_atomic.c \
|
||||
$(LOCAL_PATH)/src/atomic/SDL_spinlock.c.arm \
|
||||
$(wildcard $(LOCAL_PATH)/src/core/android/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/cpuinfo/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/dynapi/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/events/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/file/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/haptic/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/haptic/dummy/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/joystick/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/joystick/android/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/loadso/dlopen/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/power/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/power/android/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/filesystem/dummy/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/render/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/render/*/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/stdlib/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/thread/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/thread/pthread/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/timer/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/timer/unix/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/video/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/video/android/*.c) \
|
||||
$(wildcard $(LOCAL_PATH)/src/test/*.c))
|
||||
|
||||
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES
|
||||
LOCAL_LDLIBS := -ldl -lGLESv1_CM -lGLESv2 -llog -landroid
|
||||
|
||||
# include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
###########################
|
||||
#
|
||||
# SDL static library
|
||||
#
|
||||
###########################
|
||||
|
||||
LOCAL_MODULE := SDL2_static
|
||||
|
||||
LOCAL_MODULE_FILENAME := libSDL2
|
||||
|
||||
LOCAL_SRC_FILES += ./src/main/android/SDL_android_main.c
|
||||
|
||||
LOCAL_LDLIBS :=
|
||||
LOCAL_EXPORT_LDLIBS := -Wl,--undefined=Java_org_libsdl_app_SDLActivity_nativeInit -ldl -lGLESv1_CM -lGLESv2 -llog -landroid
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,20 @@
|
||||
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
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.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user