Removed outdated OS/2 support
--HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%403810
This commit is contained in:
parent
303667b4b7
commit
76d2bc3e7f
33 changed files with 8 additions and 6358 deletions
2
README
2
README
|
@ -15,7 +15,7 @@ and 2D framebuffer across multiple platforms.
|
||||||
The current version supports Linux, Windows, Windows CE, BeOS, MacOS,
|
The current version supports Linux, Windows, Windows CE, BeOS, MacOS,
|
||||||
Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX.
|
Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX.
|
||||||
The code contains support for Dreamcast, Atari, AIX, OSF/Tru64,
|
The code contains support for Dreamcast, Atari, AIX, OSF/Tru64,
|
||||||
RISC OS, SymbianOS, and OS/2, but these are not officially supported.
|
RISC OS, SymbianOS, but these are not officially supported.
|
||||||
|
|
||||||
SDL is written in C, but works with C++ natively, and has bindings to
|
SDL is written in C, but works with C++ natively, and has bindings to
|
||||||
several other languages, including Ada, C#, Eiffel, Erlang, Euphoria,
|
several other languages, including Ada, C#, Eiffel, Erlang, Euphoria,
|
||||||
|
|
278
README.OS2
278
README.OS2
|
@ -1,278 +0,0 @@
|
||||||
|
|
||||||
===========
|
|
||||||
SDL on OS/2
|
|
||||||
===========
|
|
||||||
|
|
||||||
Last updated on May. 1, 2006.
|
|
||||||
|
|
||||||
|
|
||||||
1. How to compile?
|
|
||||||
------------------
|
|
||||||
|
|
||||||
To compile this, you'll need the followings installed:
|
|
||||||
- The OS/2 Developer's Toolkit
|
|
||||||
- The OpenWatcom compiler
|
|
||||||
(http://www.openwatcom.org)
|
|
||||||
- The FSLib library
|
|
||||||
(ftp://ftp.netlabs.org/pub/SDL)
|
|
||||||
|
|
||||||
First of all, you have to unzip the Watcom-OS2.zip file. This will result in a
|
|
||||||
file called "makefile" and a file called "setvars.cmd" in this folder (and some
|
|
||||||
more files...).
|
|
||||||
|
|
||||||
Please edit the second, fourth and fifth lines of setvars.cmd file
|
|
||||||
to set the folders where the toolkit, the OW compiler and the FSLib are.
|
|
||||||
You won't need NASM yet (The Netwide Assembler), you can leave that line.
|
|
||||||
Run setvars.cmd, and you should get a shell in which you can
|
|
||||||
compile SDL.
|
|
||||||
|
|
||||||
Check the "makefile" file. There is a line in there which determines if the
|
|
||||||
resulting SDL.DLL will be a 'debug' or a 'release' build. The 'debug' version
|
|
||||||
is full of printf()'s, so if something goes wrong, its output can help a lot
|
|
||||||
for debugging.
|
|
||||||
|
|
||||||
Then run "wmake".
|
|
||||||
This should create the SDL.DLL and the corresponding SDL.LIB file here.
|
|
||||||
|
|
||||||
To test applications, it's a good idea to use the 'debug' build of SDL, and
|
|
||||||
redirect the standard output and standard error output to files, to see what
|
|
||||||
happens internally in SDL.
|
|
||||||
(like: testsprite >stdout.txt 2>stderr.txt)
|
|
||||||
|
|
||||||
To rebuild SDL, use the following commands in this folder:
|
|
||||||
wmake clean
|
|
||||||
wmake
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
2. How to compile the testapps?
|
|
||||||
-------------------------------
|
|
||||||
|
|
||||||
Once you have SDL.DLL compiled, navigate into the 'test' folder, copy in there
|
|
||||||
the newly built SDL.DLL, and copy in there FSLib.DLL.
|
|
||||||
|
|
||||||
Then run "wmake" in there to compile some of the testapps.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
3. What is missing?
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
The following things are missing from this SDL implementation:
|
|
||||||
- MMX, SSE and 3DNOW! optimized video blitters?
|
|
||||||
- HW Video surfaces
|
|
||||||
- OpenGL support
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
4. Special Keys / Full-Screen support
|
|
||||||
-------------------------------------
|
|
||||||
|
|
||||||
There are two special hot-keys implemented:
|
|
||||||
- Alt+Home switches between fullscreen and windowed mode
|
|
||||||
- Alt+End simulates closing the window (can be used as a Panic key)
|
|
||||||
Only the LEFT Alt key will work.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
5. Joysticks on SDL/2
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
The Joystick detection only works for standard joysticks (2 buttons, 2 axes
|
|
||||||
and the like). Therefore, if you use a non-standard joystick, you should
|
|
||||||
specify its features in the SDL_OS2_JOYSTICK environment variable in a batch
|
|
||||||
file or CONFIG.SYS, so SDL applications can provide full capability to your
|
|
||||||
device. The syntax is:
|
|
||||||
|
|
||||||
SET SDL_OS2_JOYSTICK=[JOYSTICK_NAME] [AXES] [BUTTONS] [HATS] [BALLS]
|
|
||||||
|
|
||||||
So, it you have a Gravis GamePad with 4 axes, 2 buttons, 2 hats and 0 balls,
|
|
||||||
the line should be:
|
|
||||||
|
|
||||||
SET SDL_OS2_JOYSTICK=Gravis_GamePad 4 2 2 0
|
|
||||||
|
|
||||||
If you want to add spaces in your joystick name, just surround it with
|
|
||||||
quotes or double-quotes:
|
|
||||||
|
|
||||||
SET SDL_OS2_JOYSTICK='Gravis GamePad' 4 2 2 0
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
SET SDL_OS2_JOYSTICK="Gravis GamePad" 4 2 2 0
|
|
||||||
|
|
||||||
Notive However that Balls and Hats are not supported under OS/2, and the
|
|
||||||
value will be ignored... but it is wise to define these correctly because
|
|
||||||
in the future those can be supported.
|
|
||||||
Also the number of buttons is limited to 2 when using two joysticks,
|
|
||||||
4 when using one joystick with 4 axes, 6 when using a joystick with 3 axes
|
|
||||||
and 8 when using a joystick with 2 axes. Notice however these are limitations
|
|
||||||
of the Joystick Port hardware, not OS/2.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
6. Proportional windows
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
For some SDL applications it can be handy to have proportional windows, so
|
|
||||||
the windows will keep their aspect ratio when resized.
|
|
||||||
This can be achieved in two ways:
|
|
||||||
|
|
||||||
- Before starting the given SDL application, set the
|
|
||||||
SDL_USE_PROPORTIONAL_WINDOW environment variable to something, e.g.:
|
|
||||||
|
|
||||||
SET SDL_USE_PROPORTIONAL_WINDOW=1
|
|
||||||
dosbox.exe
|
|
||||||
|
|
||||||
- If you have a HOME environment variable set, then SDL will look for a file
|
|
||||||
in there called ".sdl.proportionals". If that file contains the name of the
|
|
||||||
currently running SDL executable, then that process will have proportional
|
|
||||||
windows automatically.
|
|
||||||
|
|
||||||
Please note that this file is created automatically with default values
|
|
||||||
at the first run.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
7. Audio in SDL applications
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
Audio effects are one of the most important features in games. Creating audio
|
|
||||||
effects in sync with the game and without hickups and pauses in the audio are
|
|
||||||
very important things.
|
|
||||||
|
|
||||||
However there are multithreaded SDL applications that have tight loops as their
|
|
||||||
main logic loop. This kills performance in OS/2, and takes too much CPU from
|
|
||||||
other threads in the same process, for example from the thread to create the
|
|
||||||
sound effects.
|
|
||||||
|
|
||||||
For this reason, the OS/2 port of SDL can be instructed to run the audio thread
|
|
||||||
in high priority, which makes sure that there will be enough time for the
|
|
||||||
processing of the audio data.
|
|
||||||
|
|
||||||
At default, SDL/2 runs the audio thread at ForegroundServer+0 priority. Well
|
|
||||||
written and well behaving SDL applications should work well in this mode.
|
|
||||||
For other applications, you can tell SDL/2 to run the audio thread at
|
|
||||||
TimeCritical priority by setting an env.variable before starting the SDL app:
|
|
||||||
|
|
||||||
SET SDL_USE_TIMECRITICAL_AUDIO=1
|
|
||||||
|
|
||||||
Please note that this is a bit risky, because if the SDL application runs a
|
|
||||||
tight infinite loop in this thread, this will make the whole system
|
|
||||||
unresponsive, so use it with care, and only for applications that need it!
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
8. Next steps...
|
|
||||||
----------------
|
|
||||||
|
|
||||||
Things to do:
|
|
||||||
- Implement missing stuffs (look for 'TODO' string in source code!)
|
|
||||||
- Finish video driver (the 'wincommon' can be a good example for missing
|
|
||||||
things like application icon and so on...)
|
|
||||||
- Enable MMX/SSE/SSE2 acceleration functions
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
9. Contacts
|
|
||||||
-----------
|
|
||||||
|
|
||||||
You can contact the developers for bugs:
|
|
||||||
|
|
||||||
Area Developer email
|
|
||||||
General (Audio/Video/System) Doodle doodle@scenergy.dfmk.hu
|
|
||||||
CDROM and Joystick Caetano daniel@caetano.eng.br
|
|
||||||
|
|
||||||
Notice however that SDL/2 is 'in development' stage so ... if you want to help,
|
|
||||||
please, be our guest and contact us!
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
10. Changelog of the OS/2 port
|
|
||||||
------------------------------
|
|
||||||
|
|
||||||
Version 1.2 - 2006-05-01 - Doodle
|
|
||||||
- Modified makefile system to have only one makefile
|
|
||||||
- Included FSLib headers, DLL and LIB file
|
|
||||||
|
|
||||||
Version 1.2 - 2006-02-26 - Doodle
|
|
||||||
- Updated the official SDL version with the OS/2 specific changes.
|
|
||||||
- Added support for real unicode keycode conversion.
|
|
||||||
|
|
||||||
Version 1.2.7 - 2006-01-20 - Doodle
|
|
||||||
- Added support for selectively using timecritical priority for
|
|
||||||
audio threads by SDL_USE_TIMECRITICAL_AUDIO environment variable.
|
|
||||||
(e.g.:
|
|
||||||
SET SDL_USE_TIMECRITICAL_AUDIO=1
|
|
||||||
dosbox.exe
|
|
||||||
)
|
|
||||||
|
|
||||||
Version 1.2.7 - 2005-12-22 - Doodle
|
|
||||||
- Added support for proportional SDL windows.
|
|
||||||
There are two ways to have proportional (aspect-keeping) windows for
|
|
||||||
a given SDL application: Either set the SDL_USE_PROPORTIONAL_WINDOW
|
|
||||||
environment variable to something before starting the application
|
|
||||||
(e.g.:
|
|
||||||
SET SDL_USE_PROPORTIONAL_WINDOW=1
|
|
||||||
dosbox.exe
|
|
||||||
)
|
|
||||||
or, if you have the HOME environment variable set, then SDL.DLL will
|
|
||||||
create a file in that directory called .sdl.proportionals, and you can
|
|
||||||
put there the name of executable files that will be automatically made
|
|
||||||
proportional.
|
|
||||||
|
|
||||||
Version 1.2.7 - 2005-10-14 - Doodle
|
|
||||||
- Enabled Exception handler code in FSLib to be able to restore original
|
|
||||||
desktop video mode in case the application crashes.
|
|
||||||
- Added the missing FSLib_Uninitialize() call into SDL.
|
|
||||||
(The lack of it did not cause problems, but it's cleaner this way.)
|
|
||||||
- Fixed a mouse problem in Fullscreen mode where any mouse click
|
|
||||||
re-centered the mouse.
|
|
||||||
|
|
||||||
Version 1.2.7 - 2005-10-09 - Doodle
|
|
||||||
- Implemented window icon support
|
|
||||||
|
|
||||||
Version 1.2.7 - 2005-10-03 - Doodle
|
|
||||||
- Reworked semaphore support again
|
|
||||||
- Tuned thread priorities
|
|
||||||
|
|
||||||
Version 1.2.7 - 2005-10-02 - Doodle
|
|
||||||
- Added support for custom mouse pointers
|
|
||||||
- Fixed WM_CLOSE processing: give a chance to SDL app to ask user...
|
|
||||||
- Added support for MMX-accelerated audio mixers
|
|
||||||
- Other small fixes
|
|
||||||
|
|
||||||
Version 1.2.7 - 2005-09-12 - Doodle
|
|
||||||
- Small fixes for DosBox incorporated into public release
|
|
||||||
- Fixed semaphore support (SDL_syssem.c)
|
|
||||||
- Fixed FSLib to have good clipping in scaled window mode,
|
|
||||||
and to prevent occasional desktop freezes.
|
|
||||||
|
|
||||||
Version 1.2.7 - 2004-09-08a - Caetano
|
|
||||||
- Improved joystick support (general verifications about hardware).
|
|
||||||
- Added support up to 8 buttons in 2 axes joysticks and 6 buttons in 3 axes joysticks.
|
|
||||||
- Added support to environment variable SDL_OS2_JOYSTICK to specify a joystick.
|
|
||||||
- Improved Joystick test to handle every type of joystick and display only relevant information.
|
|
||||||
- Merged with Doodle 2004-09-08
|
|
||||||
- Little tid up in README.OS2
|
|
||||||
- Added explanation about SDL_OS2_JOYSTICK environment variable on README.OS2
|
|
||||||
|
|
||||||
Version 1.2.7 - 2004-09-07 - Caetano
|
|
||||||
- Merged with changes in headers for GCC compiling.
|
|
||||||
- Added Joystick support using basic IBM GAME$ support, allowing it to work with all joystick drivers since OS/2 2.1.
|
|
||||||
- Improved joystick detection (hacked!). OS/2 do not allow real joystick detection, so...
|
|
||||||
- Modified makefile in test to compile "testjoystick". Anyway, it's useless, since it seems to cause a lot of trouble in OS/2 (because os video routines, not Joystick support).
|
|
||||||
- Created separated Joystick test program to test only joystick functions.
|
|
||||||
- Improved joystick auto-centering.
|
|
||||||
- Improved the coordinate correction routine to use two scale factors for each axis.
|
|
||||||
|
|
||||||
Version 1.2.7 - 2004-07-05 - Caetano
|
|
||||||
- Corrected the time returned by status in CDROM support (it was incorrect)
|
|
||||||
- Added the testcdrom.c and corrected the linking directive (it was causing an error)
|
|
||||||
|
|
||||||
Version 1.2.7 - 2004-07-02a - Caetano
|
|
||||||
- Corrected a little problem in a comment at SDL-1.2.7\test\torturethread.c, line 18 (missing */, nested comment)
|
|
||||||
- Added CDROM support to tree (SDL-1.2.7\src\cdrom\os2\SDL_syscdrom.c)
|
|
||||||
- Modified makefile (SDL-1.2.7\src\makefiles.wat and SDL-1.2.7\watcom.mif) to build with CDROM support
|
|
||||||
- Added the "extra" SDL_types.h forgotten in 2004-07-02 version.
|
|
||||||
|
|
||||||
<End-Of-File>
|
|
BIN
Watcom-OS2.zip
BIN
Watcom-OS2.zip
Binary file not shown.
|
@ -163,13 +163,6 @@ SDL 1.2.10 is a major release, featuring a revamp of the build system and many A
|
||||||
Icons set with SDL_WM_SetIcon() now have the proper colors on Intel Macs.
|
Icons set with SDL_WM_SetIcon() now have the proper colors on Intel Macs.
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<H3> OS/2 Notes </H3>
|
|
||||||
|
|
||||||
<BLOCKQUOTE>
|
|
||||||
<P>
|
|
||||||
Projects for building SDL on OS/2 with OpenWatcom have been contributed by Doodle. See the file README.OS2 in the SDL source distribution for details.
|
|
||||||
</BLOCKQUOTE>
|
|
||||||
|
|
||||||
<IMG SRC="docs/images/rainbow.gif" ALT="[separator]" WIDTH="100%">
|
<IMG SRC="docs/images/rainbow.gif" ALT="[separator]" WIDTH="100%">
|
||||||
|
|
||||||
</BODY>
|
</BODY>
|
||||||
|
|
|
@ -39,7 +39,7 @@ and 2D framebuffer across multiple platforms.
|
||||||
The current version supports Linux, Windows, Windows CE, BeOS, MacOS,
|
The current version supports Linux, Windows, Windows CE, BeOS, MacOS,
|
||||||
Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX.
|
Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX.
|
||||||
The code contains support for Dreamcast, Atari, AIX, OSF/Tru64,
|
The code contains support for Dreamcast, Atari, AIX, OSF/Tru64,
|
||||||
RISC OS, SymbianOS, and OS/2, but these are not officially supported.
|
RISC OS, SymbianOS, but these are not officially supported.
|
||||||
|
|
||||||
SDL is written in C, but works with C++ natively, and has bindings to
|
SDL is written in C, but works with C++ natively, and has bindings to
|
||||||
several other languages, including Ada, C#, Eiffel, Erlang, Euphoria,
|
several other languages, including Ada, C#, Eiffel, Erlang, Euphoria,
|
||||||
|
|
|
@ -36,8 +36,6 @@
|
||||||
#include "SDL_config_macosx.h"
|
#include "SDL_config_macosx.h"
|
||||||
#elif defined(__WIN32__)
|
#elif defined(__WIN32__)
|
||||||
#include "SDL_config_win32.h"
|
#include "SDL_config_win32.h"
|
||||||
#elif defined(__OS2__)
|
|
||||||
#include "SDL_config_os2.h"
|
|
||||||
#else
|
#else
|
||||||
#include "SDL_config_minimal.h"
|
#include "SDL_config_minimal.h"
|
||||||
#endif /* platform config */
|
#endif /* platform config */
|
||||||
|
|
|
@ -214,7 +214,6 @@
|
||||||
#undef SDL_JOYSTICK_LINUX
|
#undef SDL_JOYSTICK_LINUX
|
||||||
#undef SDL_JOYSTICK_MINT
|
#undef SDL_JOYSTICK_MINT
|
||||||
#undef SDL_JOYSTICK_NDS
|
#undef SDL_JOYSTICK_NDS
|
||||||
#undef SDL_JOYSTICK_OS2
|
|
||||||
#undef SDL_JOYSTICK_RISCOS
|
#undef SDL_JOYSTICK_RISCOS
|
||||||
#undef SDL_JOYSTICK_WINMM
|
#undef SDL_JOYSTICK_WINMM
|
||||||
#undef SDL_JOYSTICK_USBHID
|
#undef SDL_JOYSTICK_USBHID
|
||||||
|
@ -230,14 +229,12 @@
|
||||||
#undef SDL_LOADSO_DLOPEN
|
#undef SDL_LOADSO_DLOPEN
|
||||||
#undef SDL_LOADSO_DUMMY
|
#undef SDL_LOADSO_DUMMY
|
||||||
#undef SDL_LOADSO_LDG
|
#undef SDL_LOADSO_LDG
|
||||||
#undef SDL_LOADSO_OS2
|
|
||||||
#undef SDL_LOADSO_WIN32
|
#undef SDL_LOADSO_WIN32
|
||||||
|
|
||||||
/* Enable various threading systems */
|
/* Enable various threading systems */
|
||||||
#undef SDL_THREAD_BEOS
|
#undef SDL_THREAD_BEOS
|
||||||
#undef SDL_THREAD_DC
|
#undef SDL_THREAD_DC
|
||||||
#undef SDL_THREAD_NDS
|
#undef SDL_THREAD_NDS
|
||||||
#undef SDL_THREAD_OS2
|
|
||||||
#undef SDL_THREAD_PTH
|
#undef SDL_THREAD_PTH
|
||||||
#undef SDL_THREAD_PTHREAD
|
#undef SDL_THREAD_PTHREAD
|
||||||
#undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX
|
#undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX
|
||||||
|
@ -251,7 +248,6 @@
|
||||||
#undef SDL_TIMER_DUMMY
|
#undef SDL_TIMER_DUMMY
|
||||||
#undef SDL_TIMER_MINT
|
#undef SDL_TIMER_MINT
|
||||||
#undef SDL_TIMER_NDS
|
#undef SDL_TIMER_NDS
|
||||||
#undef SDL_TIMER_OS2
|
|
||||||
#undef SDL_TIMER_RISCOS
|
#undef SDL_TIMER_RISCOS
|
||||||
#undef SDL_TIMER_UNIX
|
#undef SDL_TIMER_UNIX
|
||||||
#undef SDL_TIMER_WIN32
|
#undef SDL_TIMER_WIN32
|
||||||
|
@ -268,7 +264,6 @@
|
||||||
#undef SDL_VIDEO_DRIVER_GEM
|
#undef SDL_VIDEO_DRIVER_GEM
|
||||||
#undef SDL_VIDEO_DRIVER_NANOX
|
#undef SDL_VIDEO_DRIVER_NANOX
|
||||||
#undef SDL_VIDEO_DRIVER_NDS
|
#undef SDL_VIDEO_DRIVER_NDS
|
||||||
#undef SDL_VIDEO_DRIVER_OS2FS
|
|
||||||
#undef SDL_VIDEO_DRIVER_PHOTON
|
#undef SDL_VIDEO_DRIVER_PHOTON
|
||||||
#undef SDL_VIDEO_DRIVER_QNXGF
|
#undef SDL_VIDEO_DRIVER_QNXGF
|
||||||
#undef SDL_VIDEO_DRIVER_PS2GS
|
#undef SDL_VIDEO_DRIVER_PS2GS
|
||||||
|
@ -315,7 +310,6 @@
|
||||||
#undef SDL_POWER_LINUX
|
#undef SDL_POWER_LINUX
|
||||||
#undef SDL_POWER_WINDOWS
|
#undef SDL_POWER_WINDOWS
|
||||||
#undef SDL_POWER_MACOSX
|
#undef SDL_POWER_MACOSX
|
||||||
#undef SDL_POWER_OS2
|
|
||||||
#undef SDL_POWER_BEOS
|
#undef SDL_POWER_BEOS
|
||||||
#undef SDL_POWER_NINTENDODS
|
#undef SDL_POWER_NINTENDODS
|
||||||
#undef SDL_POWER_HARDWIRED
|
#undef SDL_POWER_HARDWIRED
|
||||||
|
|
|
@ -1,145 +0,0 @@
|
||||||
/*
|
|
||||||
SDL - Simple DirectMedia Layer
|
|
||||||
Copyright (C) 1997-2009 Sam Lantinga
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Sam Lantinga
|
|
||||||
slouken@libsdl.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _SDL_config_os2_h
|
|
||||||
#define _SDL_config_os2_h
|
|
||||||
|
|
||||||
#include "SDL_platform.h"
|
|
||||||
|
|
||||||
/* This is a set of defines to configure the SDL features */
|
|
||||||
|
|
||||||
#if !defined(_STDINT_H_) && (!defined(HAVE_STDINT_H) || !_HAVE_STDINT_H)
|
|
||||||
typedef signed char int8_t;
|
|
||||||
typedef unsigned char uint8_t;
|
|
||||||
typedef signed short int16_t;
|
|
||||||
typedef unsigned short uint16_t;
|
|
||||||
typedef signed int int32_t;
|
|
||||||
typedef unsigned int uint32_t;
|
|
||||||
typedef unsigned int size_t;
|
|
||||||
typedef unsigned long uintptr_t;
|
|
||||||
typedef signed long long int64_t;
|
|
||||||
typedef unsigned long long uint64_t;
|
|
||||||
#endif /* !_STDINT_H_ && !HAVE_STDINT_H */
|
|
||||||
|
|
||||||
#define SIZEOF_VOIDP 4
|
|
||||||
#define SDL_HAS_64BIT_TYPE 1
|
|
||||||
|
|
||||||
/* Use Watcom's LIBC */
|
|
||||||
#define HAVE_LIBC 1
|
|
||||||
|
|
||||||
/* Useful headers */
|
|
||||||
#define HAVE_SYS_TYPES_H 1
|
|
||||||
#define HAVE_STDIO_H 1
|
|
||||||
#define STDC_HEADERS 1
|
|
||||||
#define HAVE_STDLIB_H 1
|
|
||||||
#define HAVE_STDARG_H 1
|
|
||||||
#define HAVE_MALLOC_H 1
|
|
||||||
#define HAVE_MEMORY_H 1
|
|
||||||
#define HAVE_STRING_H 1
|
|
||||||
#define HAVE_STRINGS_H 1
|
|
||||||
#define HAVE_INTTYPES_H 1
|
|
||||||
#define HAVE_STDINT_H 1
|
|
||||||
#define HAVE_CTYPE_H 1
|
|
||||||
#define HAVE_MATH_H 1
|
|
||||||
#define HAVE_SIGNAL_H 1
|
|
||||||
|
|
||||||
/* C library functions */
|
|
||||||
#define HAVE_MALLOC 1
|
|
||||||
#define HAVE_CALLOC 1
|
|
||||||
#define HAVE_REALLOC 1
|
|
||||||
#define HAVE_FREE 1
|
|
||||||
#define HAVE_ALLOCA 1
|
|
||||||
#define HAVE_GETENV 1
|
|
||||||
#define HAVE_PUTENV 1
|
|
||||||
#define HAVE_UNSETENV 1
|
|
||||||
#define HAVE_QSORT 1
|
|
||||||
#define HAVE_ABS 1
|
|
||||||
#define HAVE_BCOPY 1
|
|
||||||
#define HAVE_MEMSET 1
|
|
||||||
#define HAVE_MEMCPY 1
|
|
||||||
#define HAVE_MEMMOVE 1
|
|
||||||
#define HAVE_MEMCMP 1
|
|
||||||
#define HAVE_STRLEN 1
|
|
||||||
#define HAVE_STRLCPY 1
|
|
||||||
#define HAVE_STRLCAT 1
|
|
||||||
#define HAVE_STRDUP 1
|
|
||||||
#define HAVE__STRREV 1
|
|
||||||
#define HAVE__STRUPR 1
|
|
||||||
#define HAVE__STRLWR 1
|
|
||||||
#define HAVE_INDEX 1
|
|
||||||
#define HAVE_RINDEX 1
|
|
||||||
#define HAVE_STRCHR 1
|
|
||||||
#define HAVE_STRRCHR 1
|
|
||||||
#define HAVE_STRSTR 1
|
|
||||||
#define HAVE_ITOA 1
|
|
||||||
#define HAVE__LTOA 1
|
|
||||||
#define HAVE__UITOA 1
|
|
||||||
#define HAVE__ULTOA 1
|
|
||||||
#define HAVE_STRTOL 1
|
|
||||||
#define HAVE__I64TOA 1
|
|
||||||
#define HAVE__UI64TOA 1
|
|
||||||
#define HAVE_STRTOLL 1
|
|
||||||
#define HAVE_STRTOD 1
|
|
||||||
#define HAVE_ATOI 1
|
|
||||||
#define HAVE_ATOF 1
|
|
||||||
#define HAVE_STRCMP 1
|
|
||||||
#define HAVE_STRNCMP 1
|
|
||||||
#define HAVE_STRICMP 1
|
|
||||||
#define HAVE_STRCASECMP 1
|
|
||||||
#define HAVE_SSCANF 1
|
|
||||||
#define HAVE_SNPRINTF 1
|
|
||||||
#define HAVE_VSNPRINTF 1
|
|
||||||
#define HAVE_SETJMP 1
|
|
||||||
#define HAVE_CLOCK_GETTIME 1
|
|
||||||
|
|
||||||
/* Enable various audio drivers */
|
|
||||||
#define SDL_AUDIO_DRIVER_DART 1
|
|
||||||
#define SDL_AUDIO_DRIVER_DISK 1
|
|
||||||
#define SDL_AUDIO_DRIVER_DUMMY 1
|
|
||||||
|
|
||||||
/* Enable various input drivers */
|
|
||||||
#define SDL_JOYSTICK_OS2 1
|
|
||||||
#define SDL_HAPTIC_DUMMY 1
|
|
||||||
|
|
||||||
/* Enable various shared object loading systems */
|
|
||||||
#define SDL_LOADSO_OS2 1
|
|
||||||
|
|
||||||
/* Enable various threading systems */
|
|
||||||
#define SDL_THREAD_OS2 1
|
|
||||||
|
|
||||||
/* Enable various timer systems */
|
|
||||||
#define SDL_TIMER_OS2 1
|
|
||||||
|
|
||||||
/* Enable various video drivers */
|
|
||||||
#define SDL_VIDEO_DRIVER_DUMMY 1
|
|
||||||
#define SDL_VIDEO_DRIVER_OS2FS 1
|
|
||||||
|
|
||||||
/* Enable OpenGL support */
|
|
||||||
/* Nothing here yet for OS/2... :( */
|
|
||||||
|
|
||||||
/* Enable system power support */
|
|
||||||
#define SDL_POWER_OS2 1
|
|
||||||
|
|
||||||
/* Enable assembly routines where available */
|
|
||||||
#define SDL_ASSEMBLY_ROUTINES 1
|
|
||||||
|
|
||||||
#endif /* _SDL_config_os2_h */
|
|
|
@ -48,9 +48,9 @@ struct SDL_Thread;
|
||||||
typedef struct SDL_Thread SDL_Thread;
|
typedef struct SDL_Thread SDL_Thread;
|
||||||
|
|
||||||
/* Create a thread */
|
/* Create a thread */
|
||||||
#if (defined(__WIN32__) && !defined(HAVE_LIBC)) || defined(__OS2__)
|
#if defined(__WIN32__) && !defined(HAVE_LIBC)
|
||||||
/*
|
/*
|
||||||
We compile SDL into a DLL on OS/2. This means, that it's the DLL which
|
We compile SDL into a DLL. This means, that it's the DLL which
|
||||||
creates a new thread for the calling process with the SDL_CreateThread()
|
creates a new thread for the calling process with the SDL_CreateThread()
|
||||||
API. There is a problem with this, that only the RTL of the SDL.DLL will
|
API. There is a problem with this, that only the RTL of the SDL.DLL will
|
||||||
be initialized for those threads, and not the RTL of the calling application!
|
be initialized for those threads, and not the RTL of the calling application!
|
||||||
|
@ -67,11 +67,7 @@ typedef struct SDL_Thread SDL_Thread;
|
||||||
#include <process.h> /* This has _beginthread() and _endthread() defined! */
|
#include <process.h> /* This has _beginthread() and _endthread() defined! */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __OS2__
|
#ifdef __GNUC__
|
||||||
typedef int (*pfnSDL_CurrentBeginThread) (void (*func) (void *), void *,
|
|
||||||
unsigned, void *arg);
|
|
||||||
typedef void (*pfnSDL_CurrentEndThread) (void);
|
|
||||||
#elif __GNUC__
|
|
||||||
typedef unsigned long (__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned,
|
typedef unsigned long (__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned,
|
||||||
unsigned
|
unsigned
|
||||||
(__stdcall *
|
(__stdcall *
|
||||||
|
@ -96,9 +92,7 @@ SDL_CreateThread(int (SDLCALL * f) (void *), void *data,
|
||||||
pfnSDL_CurrentBeginThread pfnBeginThread,
|
pfnSDL_CurrentBeginThread pfnBeginThread,
|
||||||
pfnSDL_CurrentEndThread pfnEndThread);
|
pfnSDL_CurrentEndThread pfnEndThread);
|
||||||
|
|
||||||
#ifdef __OS2__
|
#if defined(_WIN32_WCE)
|
||||||
#define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, _beginthread, _endthread)
|
|
||||||
#elif defined(_WIN32_WCE)
|
|
||||||
#define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, NULL, NULL)
|
#define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, NULL, NULL)
|
||||||
#else
|
#else
|
||||||
#define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, _beginthreadex, _endthreadex)
|
#define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, _beginthreadex, _endthreadex)
|
||||||
|
|
|
@ -49,16 +49,6 @@
|
||||||
# else
|
# else
|
||||||
# define DECLSPEC __declspec(dllexport)
|
# define DECLSPEC __declspec(dllexport)
|
||||||
# endif
|
# endif
|
||||||
# elif defined(__OS2__)
|
|
||||||
# ifdef __WATCOMC__
|
|
||||||
# ifdef BUILD_SDL
|
|
||||||
# define DECLSPEC __declspec(dllexport)
|
|
||||||
# else
|
|
||||||
# define DECLSPEC
|
|
||||||
# endif
|
|
||||||
# else
|
|
||||||
# define DECLSPEC
|
|
||||||
# endif
|
|
||||||
# else
|
# else
|
||||||
# if defined(__GNUC__) && __GNUC__ >= 4
|
# if defined(__GNUC__) && __GNUC__ >= 4
|
||||||
# define DECLSPEC __attribute__ ((visibility("default")))
|
# define DECLSPEC __attribute__ ((visibility("default")))
|
||||||
|
@ -73,14 +63,8 @@
|
||||||
#if defined(__WIN32__) && !defined(__GNUC__)
|
#if defined(__WIN32__) && !defined(__GNUC__)
|
||||||
#define SDLCALL __cdecl
|
#define SDLCALL __cdecl
|
||||||
#else
|
#else
|
||||||
#ifdef __OS2__
|
|
||||||
/* But on OS/2, we use the _System calling convention */
|
|
||||||
/* to be compatible with every compiler */
|
|
||||||
#define SDLCALL _System
|
|
||||||
#else
|
|
||||||
#define SDLCALL
|
#define SDLCALL
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
#endif /* SDLCALL */
|
#endif /* SDLCALL */
|
||||||
|
|
||||||
/* Removed DECLSPEC on Symbian OS because SDL cannot be a DLL in EPOC */
|
/* Removed DECLSPEC on Symbian OS because SDL cannot be a DLL in EPOC */
|
||||||
|
|
73
src/SDL.c
73
src/SDL.c
|
@ -277,76 +277,7 @@ SDL_GetRevision(void)
|
||||||
return SDL_REVISION;
|
return SDL_REVISION;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__OS2__)
|
#if defined(__WIN32__)
|
||||||
/* Building for OS/2 */
|
|
||||||
#ifdef __WATCOMC__
|
|
||||||
|
|
||||||
#define INCL_DOSERRORS
|
|
||||||
#define INCL_DOSEXCEPTIONS
|
|
||||||
#include <os2.h>
|
|
||||||
|
|
||||||
/* Exception handler to prevent the Audio thread hanging, making a zombie process! */
|
|
||||||
ULONG _System
|
|
||||||
SDL_Main_ExceptionHandler(PEXCEPTIONREPORTRECORD pERepRec,
|
|
||||||
PEXCEPTIONREGISTRATIONRECORD pERegRec,
|
|
||||||
PCONTEXTRECORD pCtxRec, PVOID p)
|
|
||||||
{
|
|
||||||
if (pERepRec->fHandlerFlags & EH_EXIT_UNWIND)
|
|
||||||
return XCPT_CONTINUE_SEARCH;
|
|
||||||
if (pERepRec->fHandlerFlags & EH_UNWINDING)
|
|
||||||
return XCPT_CONTINUE_SEARCH;
|
|
||||||
if (pERepRec->fHandlerFlags & EH_NESTED_CALL)
|
|
||||||
return XCPT_CONTINUE_SEARCH;
|
|
||||||
|
|
||||||
/* Do cleanup at every fatal exception! */
|
|
||||||
if (((pERepRec->ExceptionNum & XCPT_SEVERITY_CODE) ==
|
|
||||||
XCPT_FATAL_EXCEPTION) && (pERepRec->ExceptionNum != XCPT_BREAKPOINT)
|
|
||||||
&& (pERepRec->ExceptionNum != XCPT_SINGLE_STEP)) {
|
|
||||||
if (SDL_initialized & SDL_INIT_AUDIO) {
|
|
||||||
/* This removes the zombie audio thread in case of emergency. */
|
|
||||||
#ifdef DEBUG_BUILD
|
|
||||||
printf
|
|
||||||
("[SDL_Main_ExceptionHandler] : Calling SDL_CloseAudio()!\n");
|
|
||||||
#endif
|
|
||||||
SDL_CloseAudio();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (XCPT_CONTINUE_SEARCH);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
EXCEPTIONREGISTRATIONRECORD SDL_Main_xcpthand =
|
|
||||||
{ 0, SDL_Main_ExceptionHandler };
|
|
||||||
|
|
||||||
/* The main DLL entry for DLL Initialization and Uninitialization: */
|
|
||||||
unsigned _System
|
|
||||||
LibMain(unsigned hmod, unsigned termination)
|
|
||||||
{
|
|
||||||
if (termination) {
|
|
||||||
#ifdef DEBUG_BUILD
|
|
||||||
/* printf("[SDL DLL Unintialization] : Removing exception handler\n"); */
|
|
||||||
#endif
|
|
||||||
DosUnsetExceptionHandler(&SDL_Main_xcpthand);
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
#ifdef DEBUG_BUILD
|
|
||||||
/* Make stdout and stderr unbuffered! */
|
|
||||||
setbuf(stdout, NULL);
|
|
||||||
setbuf(stderr, NULL);
|
|
||||||
#endif
|
|
||||||
/* Fire up exception handler */
|
|
||||||
#ifdef DEBUG_BUILD
|
|
||||||
/* printf("[SDL DLL Initialization] : Setting exception handler\n"); */
|
|
||||||
#endif
|
|
||||||
/* Set exception handler */
|
|
||||||
DosSetExceptionHandler(&SDL_Main_xcpthand);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* __WATCOMC__ */
|
|
||||||
|
|
||||||
#elif defined(__WIN32__)
|
|
||||||
|
|
||||||
#if !defined(HAVE_LIBC) || (defined(__WATCOMC__) && defined(BUILD_DLL))
|
#if !defined(HAVE_LIBC) || (defined(__WATCOMC__) && defined(BUILD_DLL))
|
||||||
/* Need to include DllMain() on Watcom C for some reason.. */
|
/* Need to include DllMain() on Watcom C for some reason.. */
|
||||||
|
@ -368,6 +299,6 @@ _DllMainCRTStartup(HANDLE hModule,
|
||||||
}
|
}
|
||||||
#endif /* building DLL with Watcom C */
|
#endif /* building DLL with Watcom C */
|
||||||
|
|
||||||
#endif /* OS/2 elif __WIN32__ */
|
#endif /* __WIN32__ */
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -1,448 +0,0 @@
|
||||||
/*
|
|
||||||
SDL - Simple DirectMedia Layer
|
|
||||||
Copyright (C) 1997-2009 Sam Lantinga
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Sam Lantinga
|
|
||||||
slouken@libsdl.org
|
|
||||||
*/
|
|
||||||
#include "SDL_config.h"
|
|
||||||
|
|
||||||
/* Allow access to a raw mixing buffer */
|
|
||||||
|
|
||||||
#include "SDL_timer.h"
|
|
||||||
#include "SDL_audio.h"
|
|
||||||
#include "../SDL_audio_c.h"
|
|
||||||
#include "SDL_dart.h"
|
|
||||||
|
|
||||||
// Buffer states:
|
|
||||||
#define BUFFER_EMPTY 0
|
|
||||||
#define BUFFER_USED 1
|
|
||||||
|
|
||||||
typedef struct _tMixBufferDesc
|
|
||||||
{
|
|
||||||
int iBufferUsage; // BUFFER_EMPTY or BUFFER_USED
|
|
||||||
SDL_AudioDevice *pSDLAudioDevice;
|
|
||||||
} tMixBufferDesc, *pMixBufferDesc;
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
// DARTEventFunc
|
|
||||||
//
|
|
||||||
// This function is called by DART, when an event occurs, like end of
|
|
||||||
// playback of a buffer, etc...
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
static LONG APIENTRY
|
|
||||||
DARTEventFunc(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags)
|
|
||||||
{
|
|
||||||
if (ulFlags && MIX_WRITE_COMPLETE) { // Playback of buffer completed!
|
|
||||||
|
|
||||||
// Get pointer to buffer description
|
|
||||||
pMixBufferDesc pBufDesc;
|
|
||||||
|
|
||||||
if (pBuffer) {
|
|
||||||
pBufDesc = (pMixBufferDesc) (*pBuffer).ulUserParm;
|
|
||||||
|
|
||||||
if (pBufDesc) {
|
|
||||||
SDL_AudioDevice *pSDLAudioDevice = pBufDesc->pSDLAudioDevice;
|
|
||||||
// Set the buffer to be empty
|
|
||||||
pBufDesc->iBufferUsage = BUFFER_EMPTY;
|
|
||||||
// And notify DART feeder thread that it will have to work a bit.
|
|
||||||
if (pSDLAudioDevice)
|
|
||||||
DosPostEventSem(pSDLAudioDevice->
|
|
||||||
hidden->hevAudioBufferPlayed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
DART_OpenDevice(_THIS, const char *devname, int iscapture)
|
|
||||||
{
|
|
||||||
SDL_AudioFormat test_format = SDL_FirstAudioFormat(_this->spec.format);
|
|
||||||
int valid_datatype = 0;
|
|
||||||
MCI_AMP_OPEN_PARMS AmpOpenParms;
|
|
||||||
int iDeviceOrd = 0; // Default device to be used
|
|
||||||
int bOpenShared = 1; // Try opening it shared
|
|
||||||
int iBits = 16; // Default is 16 bits signed
|
|
||||||
int iFreq = 44100; // Default is 44KHz
|
|
||||||
int iChannels = 2; // Default is 2 channels (Stereo)
|
|
||||||
int iNumBufs = 2; // Number of audio buffers: 2
|
|
||||||
int iBufSize;
|
|
||||||
int iOpenMode;
|
|
||||||
int iSilence;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
/* Initialize all variables that we clean on shutdown */
|
|
||||||
_this->hidden = (struct SDL_PrivateAudioData *)
|
|
||||||
SDL_malloc((sizeof *_this->hidden));
|
|
||||||
if (_this->hidden == NULL) {
|
|
||||||
SDL_OutOfMemory();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
SDL_memset(_this->hidden, 0, (sizeof *_this->hidden));
|
|
||||||
|
|
||||||
// First thing is to try to open a given DART device!
|
|
||||||
SDL_memset(&AmpOpenParms, 0, sizeof(MCI_AMP_OPEN_PARMS));
|
|
||||||
// pszDeviceType should contain the device type in low word, and device ordinal in high word!
|
|
||||||
AmpOpenParms.pszDeviceType =
|
|
||||||
(PSZ) (MCI_DEVTYPE_AUDIO_AMPMIX | (iDeviceOrd << 16));
|
|
||||||
|
|
||||||
iOpenMode = MCI_WAIT | MCI_OPEN_TYPE_ID;
|
|
||||||
if (bOpenShared)
|
|
||||||
iOpenMode |= MCI_OPEN_SHAREABLE;
|
|
||||||
|
|
||||||
rc = mciSendCommand(0, MCI_OPEN, iOpenMode, (PVOID) & AmpOpenParms, 0);
|
|
||||||
if (rc != MCIERR_SUCCESS) { // No audio available??
|
|
||||||
DART_CloseDevice(_this);
|
|
||||||
SDL_SetError("DART: Couldn't open audio device.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// Save the device ID we got from DART!
|
|
||||||
// We will use this in the next calls!
|
|
||||||
_this->hidden->iCurrDeviceOrd = iDeviceOrd = AmpOpenParms.usDeviceID;
|
|
||||||
|
|
||||||
// Determine the audio parameters from the AudioSpec
|
|
||||||
if (_this->spec.channels > 4)
|
|
||||||
_this->spec.channels = 4;
|
|
||||||
|
|
||||||
while ((!valid_datatype) && (test_format)) {
|
|
||||||
_this->spec.format = test_format;
|
|
||||||
valid_datatype = 1;
|
|
||||||
switch (test_format) {
|
|
||||||
case AUDIO_U8:
|
|
||||||
// Unsigned 8 bit audio data
|
|
||||||
iSilence = 0x80;
|
|
||||||
_this->hidden->iCurrBits = iBits = 8;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AUDIO_S16LSB:
|
|
||||||
// Signed 16 bit audio data
|
|
||||||
iSilence = 0x00;
|
|
||||||
_this->hidden->iCurrBits = iBits = 16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// !!! FIXME: int32?
|
|
||||||
|
|
||||||
default:
|
|
||||||
valid_datatype = 0;
|
|
||||||
test_format = SDL_NextAudioFormat();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!valid_datatype) { // shouldn't happen, but just in case...
|
|
||||||
// Close DART, and exit with error code!
|
|
||||||
DART_CloseDevice(_this);
|
|
||||||
SDL_SetError("Unsupported audio format");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_this->hidden->iCurrFreq = iFreq = _this->spec.freq;
|
|
||||||
_this->hidden->iCurrChannels = iChannels = _this->spec.channels;
|
|
||||||
/* Update the fragment size as size in bytes */
|
|
||||||
SDL_CalculateAudioSpec(&_this->spec);
|
|
||||||
_this->hidden->iCurrBufSize = iBufSize = _this->spec.size;
|
|
||||||
|
|
||||||
// Now query this device if it supports the given freq/bits/channels!
|
|
||||||
SDL_memset(&(_this->hidden->MixSetupParms), 0,
|
|
||||||
sizeof(MCI_MIXSETUP_PARMS));
|
|
||||||
_this->hidden->MixSetupParms.ulBitsPerSample = iBits;
|
|
||||||
_this->hidden->MixSetupParms.ulFormatTag = MCI_WAVE_FORMAT_PCM;
|
|
||||||
_this->hidden->MixSetupParms.ulSamplesPerSec = iFreq;
|
|
||||||
_this->hidden->MixSetupParms.ulChannels = iChannels;
|
|
||||||
_this->hidden->MixSetupParms.ulFormatMode = MCI_PLAY;
|
|
||||||
_this->hidden->MixSetupParms.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;
|
|
||||||
_this->hidden->MixSetupParms.pmixEvent = DARTEventFunc;
|
|
||||||
rc = mciSendCommand(iDeviceOrd, MCI_MIXSETUP,
|
|
||||||
MCI_WAIT | MCI_MIXSETUP_QUERYMODE,
|
|
||||||
&(_this->hidden->MixSetupParms), 0);
|
|
||||||
if (rc != MCIERR_SUCCESS) { // The device cannot handle this format!
|
|
||||||
// Close DART, and exit with error code!
|
|
||||||
DART_CloseDevice(_this);
|
|
||||||
SDL_SetError("Audio device doesn't support requested audio format");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// The device can handle this format, so initialize!
|
|
||||||
rc = mciSendCommand(iDeviceOrd, MCI_MIXSETUP,
|
|
||||||
MCI_WAIT | MCI_MIXSETUP_INIT,
|
|
||||||
&(_this->hidden->MixSetupParms), 0);
|
|
||||||
if (rc != MCIERR_SUCCESS) { // The device could not be opened!
|
|
||||||
// Close DART, and exit with error code!
|
|
||||||
DART_CloseDevice(_this);
|
|
||||||
SDL_SetError("Audio device could not be set up");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// Ok, the device is initialized.
|
|
||||||
// Now we should allocate buffers. For this, we need a place where
|
|
||||||
// the buffer descriptors will be:
|
|
||||||
_this->hidden->pMixBuffers =
|
|
||||||
(MCI_MIX_BUFFER *) SDL_malloc(sizeof(MCI_MIX_BUFFER) * iNumBufs);
|
|
||||||
if (!(_this->hidden->pMixBuffers)) { // Not enough memory!
|
|
||||||
// Close DART, and exit with error code!
|
|
||||||
DART_CloseDevice(_this);
|
|
||||||
SDL_OutOfMemory();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// Now that we have the place for buffer list, we can ask DART for the
|
|
||||||
// buffers!
|
|
||||||
_this->hidden->BufferParms.ulNumBuffers = iNumBufs; // Number of buffers
|
|
||||||
_this->hidden->BufferParms.ulBufferSize = iBufSize; // each with this size
|
|
||||||
_this->hidden->BufferParms.pBufList = _this->hidden->pMixBuffers; // getting descriptorts into this list
|
|
||||||
// Allocate buffers!
|
|
||||||
rc = mciSendCommand(iDeviceOrd, MCI_BUFFER,
|
|
||||||
MCI_WAIT | MCI_ALLOCATE_MEMORY,
|
|
||||||
&(_this->hidden->BufferParms), 0);
|
|
||||||
if ((rc != MCIERR_SUCCESS)
|
|
||||||
|| (iNumBufs != _this->hidden->BufferParms.ulNumBuffers)
|
|
||||||
|| (_this->hidden->BufferParms.ulBufferSize == 0)) { // Could not allocate memory!
|
|
||||||
// Close DART, and exit with error code!
|
|
||||||
DART_CloseDevice(_this);
|
|
||||||
SDL_SetError("DART could not allocate buffers");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
_this->hidden->iCurrNumBufs = iNumBufs;
|
|
||||||
|
|
||||||
// Ok, we have all the buffers allocated, let's mark them!
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < iNumBufs; i++) {
|
|
||||||
pMixBufferDesc pBufferDesc =
|
|
||||||
(pMixBufferDesc) SDL_malloc(sizeof(tMixBufferDesc));;
|
|
||||||
// Check if this buffer was really allocated by DART
|
|
||||||
if ((!(_this->hidden->pMixBuffers[i].pBuffer))
|
|
||||||
|| (!pBufferDesc)) { // Wrong buffer!
|
|
||||||
DART_CloseDevice(_this);
|
|
||||||
SDL_SetError("Error at internal buffer check");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
pBufferDesc->iBufferUsage = BUFFER_EMPTY;
|
|
||||||
pBufferDesc->pSDLAudioDevice = _this;
|
|
||||||
|
|
||||||
_this->hidden->pMixBuffers[i].ulBufferLength =
|
|
||||||
_this->hidden->BufferParms.ulBufferSize;
|
|
||||||
_this->hidden->pMixBuffers[i].ulUserParm = (ULONG) pBufferDesc; // User parameter: Description of buffer
|
|
||||||
_this->hidden->pMixBuffers[i].ulFlags = 0; // Some stuff should be flagged here for DART, like end of
|
|
||||||
// audio data, but as we will continously send
|
|
||||||
// audio data, there will be no end.:)
|
|
||||||
SDL_memset(_this->hidden->pMixBuffers[i].pBuffer, iSilence,
|
|
||||||
iBufSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_this->hidden->iNextFreeBuffer = 0;
|
|
||||||
_this->hidden->iLastPlayedBuf = -1;
|
|
||||||
// Create event semaphore
|
|
||||||
if (DosCreateEventSem
|
|
||||||
(NULL, &(_this->hidden->hevAudioBufferPlayed), 0, FALSE) != NO_ERROR)
|
|
||||||
{
|
|
||||||
DART_CloseDevice(_this);
|
|
||||||
SDL_SetError("Could not create event semaphore");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
DART_ThreadInit(_THIS)
|
|
||||||
{
|
|
||||||
/* Increase the priority of this thread to make sure that
|
|
||||||
the audio will be continuous all the time! */
|
|
||||||
#ifdef USE_DOSSETPRIORITY
|
|
||||||
if (SDL_getenv("SDL_USE_TIMECRITICAL_AUDIO")) {
|
|
||||||
#ifdef DEBUG_BUILD
|
|
||||||
printf
|
|
||||||
("[DART_ThreadInit] : Setting priority to TimeCritical+0! (TID%d)\n",
|
|
||||||
SDL_ThreadID());
|
|
||||||
#endif
|
|
||||||
DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);
|
|
||||||
} else {
|
|
||||||
#ifdef DEBUG_BUILD
|
|
||||||
printf
|
|
||||||
("[DART_ThreadInit] : Setting priority to ForegroundServer+0! (TID%d)\n",
|
|
||||||
SDL_ThreadID());
|
|
||||||
#endif
|
|
||||||
DosSetPriority(PRTYS_THREAD, PRTYC_FOREGROUNDSERVER, 0, 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This function waits until it is possible to write a full sound buffer */
|
|
||||||
static void
|
|
||||||
DART_WaitDevice(_THIS)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
pMixBufferDesc pBufDesc;
|
|
||||||
ULONG ulPostCount;
|
|
||||||
|
|
||||||
DosResetEventSem(_this->hidden->hevAudioBufferPlayed, &ulPostCount);
|
|
||||||
// If there is already an empty buffer, then return now!
|
|
||||||
for (i = 0; i < _this->hidden->iCurrNumBufs; i++) {
|
|
||||||
pBufDesc = (pMixBufferDesc) _this->hidden->pMixBuffers[i].ulUserParm;
|
|
||||||
if (pBufDesc->iBufferUsage == BUFFER_EMPTY)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// If there is no empty buffer, wait for one to be empty!
|
|
||||||
DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000); // Wait max 1 sec!!! Important!
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
DART_PlayDevice(_THIS)
|
|
||||||
{
|
|
||||||
int iFreeBuf = _this->hidden->iNextFreeBuffer;
|
|
||||||
pMixBufferDesc pBufDesc;
|
|
||||||
|
|
||||||
pBufDesc =
|
|
||||||
(pMixBufferDesc) _this->hidden->pMixBuffers[iFreeBuf].ulUserParm;
|
|
||||||
pBufDesc->iBufferUsage = BUFFER_USED;
|
|
||||||
// Send it to DART to be queued
|
|
||||||
_this->hidden->MixSetupParms.pmixWrite(_this->hidden->
|
|
||||||
MixSetupParms.ulMixHandle,
|
|
||||||
&(_this->
|
|
||||||
hidden->pMixBuffers[iFreeBuf]),
|
|
||||||
1);
|
|
||||||
|
|
||||||
_this->hidden->iLastPlayedBuf = iFreeBuf;
|
|
||||||
iFreeBuf = (iFreeBuf + 1) % _this->hidden->iCurrNumBufs;
|
|
||||||
_this->hidden->iNextFreeBuffer = iFreeBuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Uint8 *
|
|
||||||
DART_GetDeviceBuf(_THIS)
|
|
||||||
{
|
|
||||||
int iFreeBuf;
|
|
||||||
Uint8 *pResult;
|
|
||||||
pMixBufferDesc pBufDesc;
|
|
||||||
|
|
||||||
if (_this) {
|
|
||||||
if (_this->hidden) {
|
|
||||||
iFreeBuf = _this->hidden->iNextFreeBuffer;
|
|
||||||
pBufDesc =
|
|
||||||
(pMixBufferDesc) _this->hidden->
|
|
||||||
pMixBuffers[iFreeBuf].ulUserParm;
|
|
||||||
|
|
||||||
if (pBufDesc) {
|
|
||||||
if (pBufDesc->iBufferUsage == BUFFER_EMPTY) {
|
|
||||||
pResult = _this->hidden->pMixBuffers[iFreeBuf].pBuffer;
|
|
||||||
return pResult;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
printf("[DART_GetDeviceBuf] : ERROR! pBufDesc = %p\n",
|
|
||||||
pBufDesc);
|
|
||||||
} else
|
|
||||||
printf("[DART_GetDeviceBuf] : ERROR! _this->hidden = %p\n",
|
|
||||||
_this->hidden);
|
|
||||||
} else
|
|
||||||
printf("[DART_GetDeviceBuf] : ERROR! _this = %p\n", _this);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
DART_WaitDone(_THIS)
|
|
||||||
{
|
|
||||||
pMixBufferDesc pBufDesc;
|
|
||||||
ULONG ulPostCount = 0;
|
|
||||||
APIRET rc = NO_ERROR;
|
|
||||||
|
|
||||||
pBufDesc = (pMixBufferDesc)
|
|
||||||
_this->hidden->pMixBuffers[_this->hidden->iLastPlayedBuf].ulUserParm;
|
|
||||||
|
|
||||||
while ((pBufDesc->iBufferUsage != BUFFER_EMPTY) && (rc == NO_ERROR)) {
|
|
||||||
DosResetEventSem(_this->hidden->hevAudioBufferPlayed, &ulPostCount);
|
|
||||||
rc = DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000); // 1 sec timeout! Important!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
DART_CloseDevice(_THIS)
|
|
||||||
{
|
|
||||||
MCI_GENERIC_PARMS GenericParms;
|
|
||||||
int rc;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (_this->hidden != NULL) {
|
|
||||||
// Stop DART playback
|
|
||||||
if (_this->hidden->iCurrDeviceOrd) {
|
|
||||||
rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_STOP,
|
|
||||||
MCI_WAIT, &GenericParms, 0);
|
|
||||||
#ifdef SFX_DEBUG_BUILD
|
|
||||||
if (rc != MCIERR_SUCCESS) {
|
|
||||||
printf("Could not stop DART playback!\n");
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
// Close event semaphore
|
|
||||||
if (_this->hidden->hevAudioBufferPlayed) {
|
|
||||||
DosCloseEventSem(_this->hidden->hevAudioBufferPlayed);
|
|
||||||
_this->hidden->hevAudioBufferPlayed = 0;
|
|
||||||
}
|
|
||||||
// Free memory of buffer descriptions
|
|
||||||
for (i = 0; i < _this->hidden->iCurrNumBufs; i++) {
|
|
||||||
SDL_free((void *) (_this->hidden->pMixBuffers[i].ulUserParm));
|
|
||||||
_this->hidden->pMixBuffers[i].ulUserParm = 0;
|
|
||||||
}
|
|
||||||
_this->hidden->iCurrNumBufs = 0;
|
|
||||||
|
|
||||||
// Deallocate buffers
|
|
||||||
if (_this->hidden->iCurrDeviceOrd) {
|
|
||||||
rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_BUFFER,
|
|
||||||
MCI_WAIT | MCI_DEALLOCATE_MEMORY,
|
|
||||||
&(_this->hidden->BufferParms), 0);
|
|
||||||
}
|
|
||||||
// Free bufferlist
|
|
||||||
if (_this->hidden->pMixBuffers != NULL) {
|
|
||||||
SDL_free(_this->hidden->pMixBuffers);
|
|
||||||
_this->hidden->pMixBuffers = NULL;
|
|
||||||
}
|
|
||||||
// Close dart
|
|
||||||
if (_this->hidden->iCurrDeviceOrd) {
|
|
||||||
rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_CLOSE,
|
|
||||||
MCI_WAIT, &(GenericParms), 0);
|
|
||||||
}
|
|
||||||
_this->hidden->iCurrDeviceOrd = 0;
|
|
||||||
|
|
||||||
SDL_free(_this->hidden);
|
|
||||||
_this->hidden = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
DART_Init(SDL_AudioDriverImpl * impl)
|
|
||||||
{
|
|
||||||
/* Set the function pointers */
|
|
||||||
impl->OpenDevice = DART_OpenDevice;
|
|
||||||
impl->ThreadInit = DART_ThreadInit;
|
|
||||||
impl->WaitDevice = DART_WaitDevice;
|
|
||||||
impl->GetDeviceBuf = DART_GetDeviceBuf;
|
|
||||||
impl->PlayDevice = DART_PlayDevice;
|
|
||||||
impl->WaitDone = DART_WaitDone;
|
|
||||||
impl->CloseDevice = DART_CloseDevice;
|
|
||||||
impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: is this right? */
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
AudioBootStrap DART_bootstrap = {
|
|
||||||
"dart", "OS/2 Direct Audio RouTines (DART)", DART_Init, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
SDL - Simple DirectMedia Layer
|
|
||||||
Copyright (C) 1997-2009 Sam Lantinga
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Sam Lantinga
|
|
||||||
slouken@libsdl.org
|
|
||||||
*/
|
|
||||||
#include "SDL_config.h"
|
|
||||||
|
|
||||||
#ifndef _SDL_dart_h
|
|
||||||
#define _SDL_dart_h
|
|
||||||
|
|
||||||
#define INCL_TYPES
|
|
||||||
#define INCL_DOSSEMAPHORES
|
|
||||||
#define INCL_DOSRESOURCES
|
|
||||||
#define INCL_DOSMISC
|
|
||||||
#define INCL_DOSERRORS
|
|
||||||
#define INCL_DOSPROCESS
|
|
||||||
|
|
||||||
#define INCL_OS2MM
|
|
||||||
#define INCL_MMIOOS2
|
|
||||||
#define INCL_MCIOS2
|
|
||||||
#include <os2.h>
|
|
||||||
#include <os2me.h> // DART stuff and MMIO stuff
|
|
||||||
|
|
||||||
#include "../SDL_sysaudio.h"
|
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
|
||||||
#define _THIS SDL_AudioDevice *_this
|
|
||||||
|
|
||||||
/* The DirectSound objects */
|
|
||||||
struct SDL_PrivateAudioData
|
|
||||||
{
|
|
||||||
int iCurrDeviceOrd;
|
|
||||||
int iCurrFreq;
|
|
||||||
int iCurrBits;
|
|
||||||
int iCurrChannels;
|
|
||||||
int iCurrNumBufs;
|
|
||||||
int iCurrBufSize;
|
|
||||||
|
|
||||||
int iLastPlayedBuf;
|
|
||||||
int iNextFreeBuffer;
|
|
||||||
|
|
||||||
MCI_BUFFER_PARMS BufferParms; // Sound buffer parameters
|
|
||||||
MCI_MIX_BUFFER *pMixBuffers; // Sound buffers
|
|
||||||
MCI_MIXSETUP_PARMS MixSetupParms; // Mixer setup parameters
|
|
||||||
HEV hevAudioBufferPlayed; // Event semaphore to indicate that an audio buffer has been played by DART
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _SDL_dart_h */
|
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
|
@ -84,29 +84,11 @@ SDL_Unlock_EventThread(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __OS2__
|
|
||||||
/*
|
|
||||||
* We'll increase the priority of GobbleEvents thread, so it will process
|
|
||||||
* events in time for sure! For this, we need the DosSetPriority() API
|
|
||||||
* from the os2.h include file.
|
|
||||||
*/
|
|
||||||
#define INCL_DOSPROCESS
|
|
||||||
#include <os2.h>
|
|
||||||
#include <time.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int SDLCALL
|
static int SDLCALL
|
||||||
SDL_GobbleEvents(void *unused)
|
SDL_GobbleEvents(void *unused)
|
||||||
{
|
{
|
||||||
event_thread = SDL_ThreadID();
|
event_thread = SDL_ThreadID();
|
||||||
|
|
||||||
#ifdef __OS2__
|
|
||||||
#ifdef USE_DOSSETPRIORITY
|
|
||||||
/* Increase thread priority, so it will process events in time for sure! */
|
|
||||||
DosSetPriority(PRTYS_THREAD, PRTYC_REGULAR, +16, 0);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (SDL_EventQ.active) {
|
while (SDL_EventQ.active) {
|
||||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,4 @@
|
||||||
#define CANT_THREAD_EVENTS
|
#define CANT_THREAD_EVENTS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __OS2__ /* The OS/2 event loop runs in a separate thread */
|
|
||||||
#define MUST_THREAD_EVENTS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -1,698 +0,0 @@
|
||||||
/*
|
|
||||||
SDL - Simple DirectMedia Layer
|
|
||||||
Copyright (C) 1997-2009 Sam Lantinga
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Sam Lantinga
|
|
||||||
slouken@libsdl.org
|
|
||||||
*/
|
|
||||||
#include "SDL_config.h"
|
|
||||||
|
|
||||||
#ifdef SDL_JOYSTICK_OS2
|
|
||||||
|
|
||||||
/* OS/2 Joystick driver, contributed by Daniel Caetano */
|
|
||||||
|
|
||||||
#include <mem.h>
|
|
||||||
|
|
||||||
#define INCL_DOSDEVICES
|
|
||||||
#define INCL_DOSDEVIOCTL
|
|
||||||
#define INCL_DOSMEMMGR
|
|
||||||
#include <os2.h>
|
|
||||||
#include "joyos2.h"
|
|
||||||
|
|
||||||
#include "SDL_joystick.h"
|
|
||||||
#include "SDL_events.h"
|
|
||||||
#include "../SDL_sysjoystick.h"
|
|
||||||
#include "../SDL_joystick_c.h"
|
|
||||||
|
|
||||||
HFILE hJoyPort = NULL; /* Joystick GAME$ Port Address */
|
|
||||||
#define MAX_JOYSTICKS 2 /* Maximum of two joysticks */
|
|
||||||
#define MAX_AXES 4 /* each joystick can have up to 4 axes */
|
|
||||||
#define MAX_BUTTONS 8 /* 8 buttons */
|
|
||||||
#define MAX_HATS 0 /* 0 hats - OS/2 doesn't support it */
|
|
||||||
#define MAX_BALLS 0 /* and 0 balls - OS/2 doesn't support it */
|
|
||||||
#define AXIS_MIN -32768 /* minimum value for axes coordinate */
|
|
||||||
#define AXIS_MAX 32767 /* maximum value for axes coordinate */
|
|
||||||
#define MAX_JOYNAME 128 /* Joystick name may have 128 characters */
|
|
||||||
/* limit axes to 256 possible positions to filter out noise */
|
|
||||||
#define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/256)
|
|
||||||
/* Calc Button Flag for buttons A to D */
|
|
||||||
#define JOY_BUTTON_FLAG(n) (1<<n)
|
|
||||||
|
|
||||||
/* Joystick data... hold information about detected devices */
|
|
||||||
typedef struct SYS_JoyData_s
|
|
||||||
{
|
|
||||||
Sint8 id; // Device ID
|
|
||||||
char szDeviceName[MAX_JOYNAME]; // Device Name
|
|
||||||
char axes; // Number of axes
|
|
||||||
char buttons; // Number of buttons
|
|
||||||
char hats; // Number of buttons
|
|
||||||
char balls; // Number of buttons
|
|
||||||
int axes_min[MAX_AXES]; // minimum callibration value for axes
|
|
||||||
int axes_med[MAX_AXES]; // medium callibration value for axes
|
|
||||||
int axes_max[MAX_AXES]; // maximum callibration value for axes
|
|
||||||
int buttoncalc[4]; // Used for buttons 5, 6, 7 and 8.
|
|
||||||
} SYS_JoyData_t, *SYS_JoyData_p;
|
|
||||||
|
|
||||||
SYS_JoyData_t SYS_JoyData[MAX_JOYSTICKS];
|
|
||||||
|
|
||||||
|
|
||||||
/* Structure used to convert data from OS/2 driver format to SDL format */
|
|
||||||
struct joystick_hwdata
|
|
||||||
{
|
|
||||||
Sint8 id;
|
|
||||||
struct _transaxes
|
|
||||||
{
|
|
||||||
int offset; /* Center Offset */
|
|
||||||
float scale1; /* Center to left/up Scale */
|
|
||||||
float scale2; /* Center to right/down Scale */
|
|
||||||
} transaxes[MAX_AXES];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Structure used to get values from Joystick Environment Variable */
|
|
||||||
struct _joycfg
|
|
||||||
{
|
|
||||||
char name[MAX_JOYNAME];
|
|
||||||
unsigned int axes;
|
|
||||||
unsigned int buttons;
|
|
||||||
unsigned int hats;
|
|
||||||
unsigned int balls;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* OS/2 Implementation Function Prototypes */
|
|
||||||
APIRET joyPortOpen(HFILE * hGame);
|
|
||||||
void joyPortClose(HFILE * hGame);
|
|
||||||
int joyGetData(char *joyenv, char *name, char stopchar, size_t maxchars);
|
|
||||||
int joyGetEnv(struct _joycfg *joydata);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
/* 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)
|
|
||||||
{
|
|
||||||
APIRET rc; /* Generic OS/2 return code */
|
|
||||||
GAME_PORT_STRUCT stJoyStatus; /* Joystick Status Structure */
|
|
||||||
GAME_PARM_STRUCT stGameParms; /* Joystick Parameter Structure */
|
|
||||||
GAME_CALIB_STRUCT stGameCalib; /* Calibration Struct */
|
|
||||||
ULONG ulDataLen; /* Size of data */
|
|
||||||
ULONG ulLastTick; /* Tick Counter for timing operations */
|
|
||||||
Uint8 maxdevs; /* Maximum number of devices */
|
|
||||||
Uint8 numdevs; /* Number of present devices */
|
|
||||||
Uint8 maxbut; /* Maximum number of buttons... */
|
|
||||||
Uint8 i; /* Temporary Count Vars */
|
|
||||||
Uint8 ucNewJoystickMask; /* Mask for Joystick Detection */
|
|
||||||
struct _joycfg joycfg; /* Joy Configuration from envvar */
|
|
||||||
|
|
||||||
|
|
||||||
/* Get Max Number of Devices */
|
|
||||||
rc = joyPortOpen(&hJoyPort); /* Open GAME$ port */
|
|
||||||
if (rc != 0)
|
|
||||||
return 0; /* Cannot open... report no joystick */
|
|
||||||
ulDataLen = sizeof(stGameParms);
|
|
||||||
rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_GET_PARMS, NULL, 0, NULL, &stGameParms, ulDataLen, &ulDataLen); /* Ask device info */
|
|
||||||
if (rc != 0) {
|
|
||||||
joyPortClose(&hJoyPort);
|
|
||||||
SDL_SetError("Could not read joystick port.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (stGameParms.useA != 0)
|
|
||||||
maxdevs++;
|
|
||||||
if (stGameParms.useB != 0)
|
|
||||||
maxdevs++;
|
|
||||||
if (maxdevs > MAX_JOYSTICKS)
|
|
||||||
maxdevs = MAX_JOYSTICKS;
|
|
||||||
|
|
||||||
/* Defines min/max axes values (callibration) */
|
|
||||||
ulDataLen = sizeof(stGameCalib);
|
|
||||||
rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_GET_CALIB,
|
|
||||||
NULL, 0, NULL, &stGameCalib, ulDataLen, &ulDataLen);
|
|
||||||
if (rc != 0) {
|
|
||||||
joyPortClose(&hJoyPort);
|
|
||||||
SDL_SetError("Could not read callibration data.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Determine how many joysticks are active */
|
|
||||||
numdevs = 0; /* Points no device */
|
|
||||||
ucNewJoystickMask = 0x0F; /* read all 4 joystick axis */
|
|
||||||
ulDataLen = sizeof(ucNewJoystickMask);
|
|
||||||
rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_RESET,
|
|
||||||
&ucNewJoystickMask, ulDataLen, &ulDataLen, NULL, 0,
|
|
||||||
NULL);
|
|
||||||
if (rc == 0) {
|
|
||||||
ulDataLen = sizeof(stJoyStatus);
|
|
||||||
rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_GET,
|
|
||||||
NULL, 0, NULL, &stJoyStatus, ulDataLen, &ulDataLen);
|
|
||||||
if (rc != 0) {
|
|
||||||
joyPortClose(&hJoyPort);
|
|
||||||
SDL_SetError("Could not call joystick port.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
ulLastTick = stJoyStatus.ulJs_Ticks;
|
|
||||||
while (stJoyStatus.ulJs_Ticks == ulLastTick) {
|
|
||||||
rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_GET,
|
|
||||||
NULL, 0, NULL, &stJoyStatus, ulDataLen,
|
|
||||||
&ulDataLen);
|
|
||||||
}
|
|
||||||
if ((stJoyStatus.ucJs_JoyStickMask & 0x03) > 0)
|
|
||||||
numdevs++;
|
|
||||||
if (((stJoyStatus.ucJs_JoyStickMask >> 2) & 0x03) > 0)
|
|
||||||
numdevs++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numdevs > maxdevs)
|
|
||||||
numdevs = maxdevs;
|
|
||||||
|
|
||||||
/* If *any* joystick was detected... Let's configure SDL for them */
|
|
||||||
if (numdevs > 0) {
|
|
||||||
/* Verify if it is a "user defined" joystick */
|
|
||||||
if (joyGetEnv(&joycfg)) {
|
|
||||||
GAME_3POS_STRUCT *axis[4];
|
|
||||||
axis[0] = &stGameCalib.Ax;
|
|
||||||
axis[1] = &stGameCalib.Ay;
|
|
||||||
axis[2] = &stGameCalib.Bx;
|
|
||||||
axis[3] = &stGameCalib.By;
|
|
||||||
/* Say it has one device only (user defined is always one device only) */
|
|
||||||
numdevs = 1;
|
|
||||||
/* Define Device 0 as... */
|
|
||||||
SYS_JoyData[0].id = 0;
|
|
||||||
/* Define Number of Axes... up to 4 */
|
|
||||||
if (joycfg.axes > MAX_AXES)
|
|
||||||
joycfg.axes = MAX_AXES;
|
|
||||||
SYS_JoyData[0].axes = joycfg.axes;
|
|
||||||
/* Define number of buttons... 8 if 2 axes, 6 if 3 axes and 4 if 4 axes */
|
|
||||||
maxbut = MAX_BUTTONS;
|
|
||||||
if (joycfg.axes > 2)
|
|
||||||
maxbut -= ((joycfg.axes - 2) << 1); /* MAX_BUTTONS - 2*(axes-2) */
|
|
||||||
if (joycfg.buttons > maxbut)
|
|
||||||
joycfg.buttons = maxbut;
|
|
||||||
SYS_JoyData[0].buttons = joycfg.buttons;
|
|
||||||
/* Define number of hats */
|
|
||||||
if (joycfg.hats > MAX_HATS)
|
|
||||||
joycfg.hats = MAX_HATS;
|
|
||||||
SYS_JoyData[0].hats = joycfg.hats;
|
|
||||||
/* Define number of balls */
|
|
||||||
if (joycfg.balls > MAX_BALLS)
|
|
||||||
joycfg.balls = MAX_BALLS;
|
|
||||||
SYS_JoyData[0].balls = joycfg.balls;
|
|
||||||
/* Initialize Axes Callibration Values */
|
|
||||||
for (i = 0; i < joycfg.axes; i++) {
|
|
||||||
SYS_JoyData[0].axes_min[i] = axis[i]->lower;
|
|
||||||
SYS_JoyData[0].axes_med[i] = axis[i]->centre;
|
|
||||||
SYS_JoyData[0].axes_max[i] = axis[i]->upper;
|
|
||||||
}
|
|
||||||
/* Initialize Buttons 5 to 8 structures */
|
|
||||||
if (joycfg.buttons >= 5)
|
|
||||||
SYS_JoyData[0].buttoncalc[0] =
|
|
||||||
((axis[2]->lower + axis[3]->centre) >> 1);
|
|
||||||
if (joycfg.buttons >= 6)
|
|
||||||
SYS_JoyData[0].buttoncalc[1] =
|
|
||||||
((axis[3]->lower + axis[3]->centre) >> 1);
|
|
||||||
if (joycfg.buttons >= 7)
|
|
||||||
SYS_JoyData[0].buttoncalc[2] =
|
|
||||||
((axis[2]->upper + axis[3]->centre) >> 1);
|
|
||||||
if (joycfg.buttons >= 8)
|
|
||||||
SYS_JoyData[0].buttoncalc[3] =
|
|
||||||
((axis[3]->upper + axis[3]->centre) >> 1);
|
|
||||||
/* Intialize Joystick Name */
|
|
||||||
SDL_strlcpy(SYS_JoyData[0].szDeviceName, joycfg.name,
|
|
||||||
SDL_arraysize(SYS_JoyData[0].szDeviceName));
|
|
||||||
}
|
|
||||||
/* Default Init ... autoconfig */
|
|
||||||
else {
|
|
||||||
/* if two devices were detected... configure as Joy1 4 axis and Joy2 2 axis */
|
|
||||||
if (numdevs == 2) {
|
|
||||||
/* Define Device 0 as 4 axes, 4 buttons */
|
|
||||||
SYS_JoyData[0].id = 0;
|
|
||||||
SYS_JoyData[0].axes = 4;
|
|
||||||
SYS_JoyData[0].buttons = 4;
|
|
||||||
SYS_JoyData[0].hats = 0;
|
|
||||||
SYS_JoyData[0].balls = 0;
|
|
||||||
SYS_JoyData[0].axes_min[0] = stGameCalib.Ax.lower;
|
|
||||||
SYS_JoyData[0].axes_med[0] = stGameCalib.Ax.centre;
|
|
||||||
SYS_JoyData[0].axes_max[0] = stGameCalib.Ax.upper;
|
|
||||||
SYS_JoyData[0].axes_min[1] = stGameCalib.Ay.lower;
|
|
||||||
SYS_JoyData[0].axes_med[1] = stGameCalib.Ay.centre;
|
|
||||||
SYS_JoyData[0].axes_max[1] = stGameCalib.Ay.upper;
|
|
||||||
SYS_JoyData[0].axes_min[2] = stGameCalib.Bx.lower;
|
|
||||||
SYS_JoyData[0].axes_med[2] = stGameCalib.Bx.centre;
|
|
||||||
SYS_JoyData[0].axes_max[2] = stGameCalib.Bx.upper;
|
|
||||||
SYS_JoyData[0].axes_min[3] = stGameCalib.By.lower;
|
|
||||||
SYS_JoyData[0].axes_med[3] = stGameCalib.By.centre;
|
|
||||||
SYS_JoyData[0].axes_max[3] = stGameCalib.By.upper;
|
|
||||||
/* Define Device 1 as 2 axes, 2 buttons */
|
|
||||||
SYS_JoyData[1].id = 1;
|
|
||||||
SYS_JoyData[1].axes = 2;
|
|
||||||
SYS_JoyData[1].buttons = 2;
|
|
||||||
SYS_JoyData[1].hats = 0;
|
|
||||||
SYS_JoyData[1].balls = 0;
|
|
||||||
SYS_JoyData[1].axes_min[0] = stGameCalib.Bx.lower;
|
|
||||||
SYS_JoyData[1].axes_med[0] = stGameCalib.Bx.centre;
|
|
||||||
SYS_JoyData[1].axes_max[0] = stGameCalib.Bx.upper;
|
|
||||||
SYS_JoyData[1].axes_min[1] = stGameCalib.By.lower;
|
|
||||||
SYS_JoyData[1].axes_med[1] = stGameCalib.By.centre;
|
|
||||||
SYS_JoyData[1].axes_max[1] = stGameCalib.By.upper;
|
|
||||||
}
|
|
||||||
/* One joystick only? */
|
|
||||||
else {
|
|
||||||
/* If it is joystick A... */
|
|
||||||
if ((stJoyStatus.ucJs_JoyStickMask & 0x03) > 0) {
|
|
||||||
/* Define Device 0 as 2 axes, 4 buttons */
|
|
||||||
SYS_JoyData[0].id = 0;
|
|
||||||
SYS_JoyData[0].axes = 2;
|
|
||||||
SYS_JoyData[0].buttons = 4;
|
|
||||||
SYS_JoyData[0].hats = 0;
|
|
||||||
SYS_JoyData[0].balls = 0;
|
|
||||||
SYS_JoyData[0].axes_min[0] = stGameCalib.Ax.lower;
|
|
||||||
SYS_JoyData[0].axes_med[0] = stGameCalib.Ax.centre;
|
|
||||||
SYS_JoyData[0].axes_max[0] = stGameCalib.Ax.upper;
|
|
||||||
SYS_JoyData[0].axes_min[1] = stGameCalib.Ay.lower;
|
|
||||||
SYS_JoyData[0].axes_med[1] = stGameCalib.Ay.centre;
|
|
||||||
SYS_JoyData[0].axes_max[1] = stGameCalib.Ay.upper;
|
|
||||||
}
|
|
||||||
/* If not, it is joystick B */
|
|
||||||
else {
|
|
||||||
/* Define Device 1 as 2 axes, 2 buttons */
|
|
||||||
SYS_JoyData[0].id = 1;
|
|
||||||
SYS_JoyData[0].axes = 2;
|
|
||||||
SYS_JoyData[0].buttons = 2;
|
|
||||||
SYS_JoyData[0].hats = 0;
|
|
||||||
SYS_JoyData[0].balls = 0;
|
|
||||||
SYS_JoyData[0].axes_min[0] = stGameCalib.Bx.lower;
|
|
||||||
SYS_JoyData[0].axes_med[0] = stGameCalib.Bx.centre;
|
|
||||||
SYS_JoyData[0].axes_max[0] = stGameCalib.Bx.upper;
|
|
||||||
SYS_JoyData[0].axes_min[1] = stGameCalib.By.lower;
|
|
||||||
SYS_JoyData[0].axes_med[1] = stGameCalib.By.centre;
|
|
||||||
SYS_JoyData[0].axes_max[1] = stGameCalib.By.upper;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Hack to define Joystick Port Names */
|
|
||||||
if (numdevs > maxdevs)
|
|
||||||
numdevs = maxdevs;
|
|
||||||
for (i = 0; i < numdevs; i++)
|
|
||||||
SDL_snprintf(SYS_JoyData[i].szDeviceName,
|
|
||||||
SDL_arraysize(SYS_JoyData[i].szDeviceName),
|
|
||||||
"Default Joystick %c", 'A' + SYS_JoyData[i].id);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Return the number of devices found */
|
|
||||||
return (numdevs);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************/
|
|
||||||
/* Function to get the device-dependent name of a joystick */
|
|
||||||
/***********************************************************/
|
|
||||||
const char *
|
|
||||||
SDL_SYS_JoystickName(int index)
|
|
||||||
{
|
|
||||||
/* No need to verify if device exists, already done in upper layer */
|
|
||||||
return (SYS_JoyData[index].szDeviceName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/* 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 index; /* Index shortcut for index in joystick structure */
|
|
||||||
int i; /* Generic Counter */
|
|
||||||
|
|
||||||
/* allocate memory for system specific hardware data */
|
|
||||||
joystick->hwdata =
|
|
||||||
(struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata));
|
|
||||||
if (joystick->hwdata == NULL) {
|
|
||||||
SDL_OutOfMemory();
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
/* Reset Hardware Data */
|
|
||||||
SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
|
|
||||||
|
|
||||||
/* ShortCut Pointer */
|
|
||||||
index = joystick->index;
|
|
||||||
/* Define offsets and scales for all axes */
|
|
||||||
joystick->hwdata->id = SYS_JoyData[index].id;
|
|
||||||
for (i = 0; i < MAX_AXES; ++i) {
|
|
||||||
if ((i < 2) || i < SYS_JoyData[index].axes) {
|
|
||||||
joystick->hwdata->transaxes[i].offset =
|
|
||||||
((AXIS_MAX + AXIS_MIN) >> 1) - SYS_JoyData[index].axes_med[i];
|
|
||||||
//joystick->hwdata->transaxes[i].scale = (float)((AXIS_MAX - AXIS_MIN)/(SYS_JoyData[index].axes_max[i]-SYS_JoyData[index].axes_min[i]));
|
|
||||||
joystick->hwdata->transaxes[i].scale1 =
|
|
||||||
(float) abs((AXIS_MIN / SYS_JoyData[index].axes_min[i]));
|
|
||||||
joystick->hwdata->transaxes[i].scale2 =
|
|
||||||
(float) abs((AXIS_MAX / SYS_JoyData[index].axes_max[i]));
|
|
||||||
} else {
|
|
||||||
joystick->hwdata->transaxes[i].offset = 0;
|
|
||||||
//joystick->hwdata->transaxes[i].scale = 1.0; /* Just in case */
|
|
||||||
joystick->hwdata->transaxes[i].scale1 = 1.0; /* Just in case */
|
|
||||||
joystick->hwdata->transaxes[i].scale2 = 1.0; /* Just in case */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fill nbuttons, naxes, and nhats fields */
|
|
||||||
joystick->nbuttons = SYS_JoyData[index].buttons;
|
|
||||||
joystick->naxes = SYS_JoyData[index].axes;
|
|
||||||
/* joystick->nhats = SYS_JoyData[index].hats; */
|
|
||||||
joystick->nhats = 0; /* No support for hats at this time */
|
|
||||||
/* joystick->nballs = SYS_JoyData[index].balls; */
|
|
||||||
joystick->nballs = 0; /* No support for balls at this time */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/* 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)
|
|
||||||
{
|
|
||||||
APIRET rc; /* Generic OS/2 return code */
|
|
||||||
int index; /* index shortcurt to joystick index */
|
|
||||||
int i; /* Generic counter */
|
|
||||||
int normbut; /* Number of buttons reported by joystick */
|
|
||||||
int corr; /* Correction for button names */
|
|
||||||
Sint16 value, change; /* Values used to update axis values */
|
|
||||||
struct _transaxes *transaxes; /* Shortcut for Correction structure */
|
|
||||||
Uint32 pos[MAX_AXES]; /* Vector to inform the Axis status */
|
|
||||||
ULONG ulDataLen; /* Size of data */
|
|
||||||
GAME_STATUS_STRUCT stGameStatus; /* Joystick Status Structure */
|
|
||||||
|
|
||||||
ulDataLen = sizeof(stGameStatus);
|
|
||||||
rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_GET_STATUS,
|
|
||||||
NULL, 0, NULL, &stGameStatus, ulDataLen, &ulDataLen);
|
|
||||||
if (rc != 0) {
|
|
||||||
SDL_SetError("Could not read joystick status.");
|
|
||||||
return; /* Could not read data */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Shortcut pointer */
|
|
||||||
index = joystick->index;
|
|
||||||
/* joystick motion events */
|
|
||||||
|
|
||||||
if (SYS_JoyData[index].id == 0) {
|
|
||||||
pos[0] = stGameStatus.curdata.A.x;
|
|
||||||
pos[1] = stGameStatus.curdata.A.y;
|
|
||||||
if (SYS_JoyData[index].axes >= 3)
|
|
||||||
pos[2] = stGameStatus.curdata.B.x;
|
|
||||||
else
|
|
||||||
pos[2] = 0;
|
|
||||||
if (SYS_JoyData[index].axes >= 4)
|
|
||||||
pos[3] = stGameStatus.curdata.B.y;
|
|
||||||
else
|
|
||||||
pos[3] = 0;
|
|
||||||
pos[4] = 0; /* OS/2 basic drivers do not support more than 4 axes joysticks */
|
|
||||||
pos[5] = 0;
|
|
||||||
} else if (SYS_JoyData[index].id == 1) {
|
|
||||||
pos[0] = stGameStatus.curdata.B.x;
|
|
||||||
pos[1] = stGameStatus.curdata.B.y;
|
|
||||||
pos[2] = 0;
|
|
||||||
pos[3] = 0;
|
|
||||||
pos[4] = 0;
|
|
||||||
pos[5] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Corrects the movements using the callibration */
|
|
||||||
transaxes = joystick->hwdata->transaxes;
|
|
||||||
for (i = 0; i < joystick->naxes; i++) {
|
|
||||||
value = pos[i] + transaxes[i].offset;
|
|
||||||
if (value < 0) {
|
|
||||||
value *= transaxes[i].scale1;
|
|
||||||
if (value > 0)
|
|
||||||
value = AXIS_MIN;
|
|
||||||
} else {
|
|
||||||
value *= transaxes[i].scale2;
|
|
||||||
if (value < 0)
|
|
||||||
value = AXIS_MAX;
|
|
||||||
}
|
|
||||||
change = (value - joystick->axes[i]);
|
|
||||||
if ((change < -JOY_AXIS_THRESHOLD) || (change > JOY_AXIS_THRESHOLD)) {
|
|
||||||
SDL_PrivateJoystickAxis(joystick, (Uint8) i, (Sint16) value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* joystick button A to D events */
|
|
||||||
if (SYS_JoyData[index].id == 1)
|
|
||||||
corr = 2;
|
|
||||||
else
|
|
||||||
corr = 0;
|
|
||||||
normbut = 4; /* Number of normal buttons */
|
|
||||||
if (joystick->nbuttons < normbut)
|
|
||||||
normbut = joystick->nbuttons;
|
|
||||||
for (i = corr; (i - corr) < normbut; ++i) {
|
|
||||||
/*
|
|
||||||
Button A: 1110 0000
|
|
||||||
Button B: 1101 0000
|
|
||||||
Button C: 1011 0000
|
|
||||||
Button D: 0111 0000
|
|
||||||
*/
|
|
||||||
if ((~stGameStatus.curdata.butMask) >> 4 & JOY_BUTTON_FLAG(i)) {
|
|
||||||
if (!joystick->buttons[i - corr]) {
|
|
||||||
SDL_PrivateJoystickButton(joystick, (Uint8) (i - corr),
|
|
||||||
SDL_PRESSED);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (joystick->buttons[i - corr]) {
|
|
||||||
SDL_PrivateJoystickButton(joystick, (Uint8) (i - corr),
|
|
||||||
SDL_RELEASED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Joystick button E to H buttons */
|
|
||||||
/*
|
|
||||||
Button E: Axis 2 X Left
|
|
||||||
Button F: Axis 2 Y Up
|
|
||||||
Button G: Axis 2 X Right
|
|
||||||
Button H: Axis 2 Y Down
|
|
||||||
*/
|
|
||||||
if (joystick->nbuttons >= 5) {
|
|
||||||
if (stGameStatus.curdata.B.x < SYS_JoyData[index].buttoncalc[0])
|
|
||||||
SDL_PrivateJoystickButton(joystick, (Uint8) 4, SDL_PRESSED);
|
|
||||||
else
|
|
||||||
SDL_PrivateJoystickButton(joystick, (Uint8) 4, SDL_RELEASED);
|
|
||||||
}
|
|
||||||
if (joystick->nbuttons >= 6) {
|
|
||||||
if (stGameStatus.curdata.B.y < SYS_JoyData[index].buttoncalc[1])
|
|
||||||
SDL_PrivateJoystickButton(joystick, (Uint8) 5, SDL_PRESSED);
|
|
||||||
else
|
|
||||||
SDL_PrivateJoystickButton(joystick, (Uint8) 5, SDL_RELEASED);
|
|
||||||
}
|
|
||||||
if (joystick->nbuttons >= 7) {
|
|
||||||
if (stGameStatus.curdata.B.x > SYS_JoyData[index].buttoncalc[2])
|
|
||||||
SDL_PrivateJoystickButton(joystick, (Uint8) 6, SDL_PRESSED);
|
|
||||||
else
|
|
||||||
SDL_PrivateJoystickButton(joystick, (Uint8) 6, SDL_RELEASED);
|
|
||||||
}
|
|
||||||
if (joystick->nbuttons >= 8) {
|
|
||||||
if (stGameStatus.curdata.B.y > SYS_JoyData[index].buttoncalc[3])
|
|
||||||
SDL_PrivateJoystickButton(joystick, (Uint8) 7, SDL_PRESSED);
|
|
||||||
else
|
|
||||||
SDL_PrivateJoystickButton(joystick, (Uint8) 7, SDL_RELEASED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* joystick hat events */
|
|
||||||
/* Not Supported under OS/2 */
|
|
||||||
/* joystick ball events */
|
|
||||||
/* Not Supported under OS/2 */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************/
|
|
||||||
/* Function to close a joystick after use */
|
|
||||||
/******************************************/
|
|
||||||
void
|
|
||||||
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
|
||||||
{
|
|
||||||
if (joystick->hwdata != NULL) {
|
|
||||||
/* free system specific hardware data */
|
|
||||||
SDL_free(joystick->hwdata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************/
|
|
||||||
/* Function to perform any system-specific joystick related cleanup */
|
|
||||||
/********************************************************************/
|
|
||||||
void
|
|
||||||
SDL_SYS_JoystickQuit(void)
|
|
||||||
{
|
|
||||||
joyPortClose(&hJoyPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************************/
|
|
||||||
/************************/
|
|
||||||
/* OS/2 Implementations */
|
|
||||||
/************************/
|
|
||||||
/************************/
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************/
|
|
||||||
/* Open Joystick Port, if not opened yet */
|
|
||||||
/*****************************************/
|
|
||||||
APIRET
|
|
||||||
joyPortOpen(HFILE * hGame)
|
|
||||||
{
|
|
||||||
APIRET rc; /* Generic Return Code */
|
|
||||||
ULONG ulAction; /* ? */
|
|
||||||
ULONG ulVersion; /* Version of joystick driver */
|
|
||||||
ULONG ulDataLen; /* Size of version data */
|
|
||||||
|
|
||||||
/* Verifies if joyport is not already open... */
|
|
||||||
if (*hGame != NULL)
|
|
||||||
return 0;
|
|
||||||
/* Open GAME$ for read */
|
|
||||||
rc = DosOpen((PSZ) GAMEPDDNAME, hGame, &ulAction, 0, FILE_READONLY,
|
|
||||||
FILE_OPEN, OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, NULL);
|
|
||||||
if (rc != 0) {
|
|
||||||
SDL_SetError("Could not open Joystick Port.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get Joystick Driver Version... must be 2.0 or higher */
|
|
||||||
ulVersion = 0;
|
|
||||||
ulDataLen = sizeof(ulVersion);
|
|
||||||
rc = DosDevIOCtl(*hGame, IOCTL_CAT_USER, GAME_GET_VERSION,
|
|
||||||
NULL, 0, NULL, &ulVersion, ulDataLen, &ulDataLen);
|
|
||||||
if (rc != 0) {
|
|
||||||
joyPortClose(hGame);
|
|
||||||
SDL_SetError("Could not get Joystick Driver version.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (ulVersion < GAME_VERSION) {
|
|
||||||
joyPortClose(hGame);
|
|
||||||
SDL_SetError
|
|
||||||
("Driver too old. At least IBM driver version 2.0 required.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/****************************/
|
|
||||||
/* Close JoyPort, if opened */
|
|
||||||
/****************************/
|
|
||||||
void
|
|
||||||
joyPortClose(HFILE * hGame)
|
|
||||||
{
|
|
||||||
if (*hGame != NULL)
|
|
||||||
DosClose(*hGame);
|
|
||||||
*hGame = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************/
|
|
||||||
/* Get SDL Joystick EnvVar */
|
|
||||||
/***************************/
|
|
||||||
int
|
|
||||||
joyGetEnv(struct _joycfg *joydata)
|
|
||||||
{
|
|
||||||
char *joyenv; /* Pointer to tested character */
|
|
||||||
char tempnumber[5]; /* Temporary place to put numeric texts */
|
|
||||||
|
|
||||||
joyenv = SDL_getenv("SDL_OS2_JOYSTICK");
|
|
||||||
if (joyenv == NULL)
|
|
||||||
return 0;
|
|
||||||
/* Joystick Environment is defined! */
|
|
||||||
while (*joyenv == ' ' && *joyenv != 0)
|
|
||||||
joyenv++; /* jump spaces... */
|
|
||||||
/* If the string name starts with '... get if fully */
|
|
||||||
if (*joyenv == '\'')
|
|
||||||
joyenv +=
|
|
||||||
joyGetData(++joyenv, joydata->name, '\'', sizeof(joydata->name));
|
|
||||||
/* If not, get it until the next space */
|
|
||||||
else if (*joyenv == '\"')
|
|
||||||
joyenv +=
|
|
||||||
joyGetData(++joyenv, joydata->name, '\"', sizeof(joydata->name));
|
|
||||||
else
|
|
||||||
joyenv +=
|
|
||||||
joyGetData(joyenv, joydata->name, ' ', sizeof(joydata->name));
|
|
||||||
/* Now get the number of axes */
|
|
||||||
while (*joyenv == ' ' && *joyenv != 0)
|
|
||||||
joyenv++; /* jump spaces... */
|
|
||||||
joyenv += joyGetData(joyenv, tempnumber, ' ', sizeof(tempnumber));
|
|
||||||
joydata->axes = atoi(tempnumber);
|
|
||||||
/* Now get the number of buttons */
|
|
||||||
while (*joyenv == ' ' && *joyenv != 0)
|
|
||||||
joyenv++; /* jump spaces... */
|
|
||||||
joyenv += joyGetData(joyenv, tempnumber, ' ', sizeof(tempnumber));
|
|
||||||
joydata->buttons = atoi(tempnumber);
|
|
||||||
/* Now get the number of hats */
|
|
||||||
while (*joyenv == ' ' && *joyenv != 0)
|
|
||||||
joyenv++; /* jump spaces... */
|
|
||||||
joyenv += joyGetData(joyenv, tempnumber, ' ', sizeof(tempnumber));
|
|
||||||
joydata->hats = atoi(tempnumber);
|
|
||||||
/* Now get the number of balls */
|
|
||||||
while (*joyenv == ' ' && *joyenv != 0)
|
|
||||||
joyenv++; /* jump spaces... */
|
|
||||||
joyenv += joyGetData(joyenv, tempnumber, ' ', sizeof(tempnumber));
|
|
||||||
joydata->balls = atoi(tempnumber);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
/* Get a text from in the string starting in joyenv until it finds */
|
|
||||||
/* the stopchar or maxchars is reached. The result is placed in name. */
|
|
||||||
/************************************************************************/
|
|
||||||
int
|
|
||||||
joyGetData(char *joyenv, char *name, char stopchar, size_t maxchars)
|
|
||||||
{
|
|
||||||
char *nameptr; /* Pointer to the selected character */
|
|
||||||
int chcnt = 0; /* Count how many characters where copied */
|
|
||||||
|
|
||||||
nameptr = name;
|
|
||||||
while (*joyenv != stopchar && *joyenv != 0) {
|
|
||||||
if (nameptr < (name + (maxchars - 1))) {
|
|
||||||
*nameptr = *joyenv; /* Only copy if smaller than maximum */
|
|
||||||
nameptr++;
|
|
||||||
}
|
|
||||||
chcnt++;
|
|
||||||
joyenv++;
|
|
||||||
}
|
|
||||||
if (*joyenv == stopchar) {
|
|
||||||
joyenv++; /* Jump stopchar */
|
|
||||||
chcnt++;
|
|
||||||
}
|
|
||||||
*nameptr = 0; /* Mark last byte */
|
|
||||||
return chcnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* SDL_JOYSTICK_OS2 */
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
|
@ -1,179 +0,0 @@
|
||||||
/*****************************************************************************/
|
|
||||||
/* */
|
|
||||||
/* COPYRIGHT Copyright (C) 1995 IBM Corporation */
|
|
||||||
/* */
|
|
||||||
/* The following IBM OS/2 source code is provided to you solely for */
|
|
||||||
/* the purpose of assisting you in your development of OS/2 device */
|
|
||||||
/* drivers. You may use this code in accordance with the IBM License */
|
|
||||||
/* Agreement provided in the IBM Device Driver Source Kit for OS/2. This */
|
|
||||||
/* Copyright statement may not be removed. */
|
|
||||||
/* */
|
|
||||||
/*****************************************************************************/
|
|
||||||
#ifndef JOYOS2_H
|
|
||||||
#define JOYOS2_H
|
|
||||||
|
|
||||||
/****** GAMEPORT.SYS joystick definitions, start *****************************/
|
|
||||||
#define GAME_VERSION 0x20 /* 2.0 First IBM version */
|
|
||||||
#define GAMEPDDNAME "GAME$ "
|
|
||||||
#define IOCTL_CAT_USER 0x80
|
|
||||||
#define GAME_PORT_GET 0x20 /* read GAMEPORT.SYS values */
|
|
||||||
#define GAME_PORT_RESET 0x60 /* reset joystick mask with given value */
|
|
||||||
|
|
||||||
#pragma pack(1) /* pack structure size is 1 byte */
|
|
||||||
typedef struct
|
|
||||||
{ /* GAMEPORT.SYS structure */
|
|
||||||
USHORT usJs_AxCnt; /* Joystick_A X position */
|
|
||||||
USHORT usJs_AyCnt; /* Joystick_A Y position */
|
|
||||||
USHORT usJs_BxCnt; /* Joystick_B X position */
|
|
||||||
USHORT usJs_ByCnt; /* Joystick_B Y position */
|
|
||||||
USHORT usJs_ButtonA1Cnt; /* button A1 press count */
|
|
||||||
USHORT usJs_ButtonA2Cnt; /* button A2 press count */
|
|
||||||
USHORT usJs_ButtonB1Cnt; /* button B1 press count */
|
|
||||||
USHORT usJs_ButtonB2Cnt; /* button B2 press count */
|
|
||||||
UCHAR ucJs_JoyStickMask; /* mask of connected joystick pots */
|
|
||||||
UCHAR ucJs_ButtonStatus; /* bits of switches down */
|
|
||||||
ULONG ulJs_Ticks; /* joystick clock ticks */
|
|
||||||
} GAME_PORT_STRUCT;
|
|
||||||
#pragma pack() /*reset to normal pack size */
|
|
||||||
/****** GAMEPORT.SYS joystick definitions, end *******************************/
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
#define GAME_GET_VERSION 0x01
|
|
||||||
#define GAME_GET_PARMS 0x02
|
|
||||||
#define GAME_SET_PARMS 0x03
|
|
||||||
#define GAME_GET_CALIB 0x04
|
|
||||||
#define GAME_SET_CALIB 0x05
|
|
||||||
#define GAME_GET_DIGSET 0x06
|
|
||||||
#define GAME_SET_DIGSET 0x07
|
|
||||||
#define GAME_GET_STATUS 0x10
|
|
||||||
#define GAME_GET_STATUS_BUTWAIT 0x11
|
|
||||||
#define GAME_GET_STATUS_SAMPWAIT 0x12
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
// bit masks for each axis
|
|
||||||
#define JOY_AX_BIT 0x01
|
|
||||||
#define JOY_AY_BIT 0x02
|
|
||||||
#define JOY_A_BITS (JOY_AX_BIT|JOY_AY_BIT)
|
|
||||||
#define JOY_BX_BIT 0x04
|
|
||||||
#define JOY_BY_BIT 0x08
|
|
||||||
#define JOY_B_BITS (JOY_BX_BIT|JOY_BY_BIT)
|
|
||||||
#define JOY_ALLPOS_BITS (JOY_A_BITS|JOY_B_BITS)
|
|
||||||
|
|
||||||
// bit masks for each button
|
|
||||||
#define JOY_BUT1_BIT 0x10
|
|
||||||
#define JOY_BUT2_BIT 0x20
|
|
||||||
#define JOY_BUT3_BIT 0x40
|
|
||||||
#define JOY_BUT4_BIT 0x80
|
|
||||||
#define JOY_ALL_BUTS (JOY_BUT1_BIT|JOY_BUT2_BIT|JOY_BUT3_BIT|JOY_BUT4_BIT)
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
// 1-D position struct used for each axis
|
|
||||||
typedef SHORT GAME_POS; /* some data formats require signed values */
|
|
||||||
|
|
||||||
// simple 2-D position for each joystick
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GAME_POS x;
|
|
||||||
GAME_POS y;
|
|
||||||
}
|
|
||||||
GAME_2DPOS_STRUCT;
|
|
||||||
|
|
||||||
// struct defining the instantaneous state of both sticks and all buttons
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GAME_2DPOS_STRUCT A;
|
|
||||||
GAME_2DPOS_STRUCT B;
|
|
||||||
USHORT butMask;
|
|
||||||
}
|
|
||||||
GAME_DATA_STRUCT;
|
|
||||||
|
|
||||||
// struct to be used for calibration and digital response on each axis
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GAME_POS lower;
|
|
||||||
GAME_POS centre;
|
|
||||||
GAME_POS upper;
|
|
||||||
}
|
|
||||||
GAME_3POS_STRUCT;
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
// status struct returned to OS/2 applications:
|
|
||||||
// current data for all sticks as well as button counts since last read
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GAME_DATA_STRUCT curdata;
|
|
||||||
USHORT b1cnt;
|
|
||||||
USHORT b2cnt;
|
|
||||||
USHORT b3cnt;
|
|
||||||
USHORT b4cnt;
|
|
||||||
}
|
|
||||||
GAME_STATUS_STRUCT;
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
/* in use bitmasks originating in 0.2b */
|
|
||||||
#define GAME_USE_BOTH_OLDMASK 0x01 /* for backward compat with bool */
|
|
||||||
#define GAME_USE_X_NEWMASK 0x02
|
|
||||||
#define GAME_USE_Y_NEWMASK 0x04
|
|
||||||
#define GAME_USE_X_EITHERMASK (GAME_USE_X_NEWMASK|GAME_USE_BOTH_OLDMASK)
|
|
||||||
#define GAME_USE_Y_EITHERMASK (GAME_USE_Y_NEWMASK|GAME_USE_BOTH_OLDMASK)
|
|
||||||
#define GAME_USE_BOTH_NEWMASK (GAME_USE_X_NEWMASK|GAME_USE_Y_NEWMASK)
|
|
||||||
|
|
||||||
/* only timed sampling implemented in version 1.0 */
|
|
||||||
#define GAME_MODE_TIMED 1 /* timed sampling */
|
|
||||||
#define GAME_MODE_REQUEST 2 /* request driven sampling */
|
|
||||||
|
|
||||||
/* only raw implemented in version 1.0 */
|
|
||||||
#define GAME_DATA_FORMAT_RAW 1 /* [l,c,r] */
|
|
||||||
#define GAME_DATA_FORMAT_SIGNED 2 /* [-l,0,+r] */
|
|
||||||
#define GAME_DATA_FORMAT_BINARY 3 /* {-1,0,+1} */
|
|
||||||
#define GAME_DATA_FORMAT_SCALED 4 /* [-10,+10] */
|
|
||||||
|
|
||||||
// parameters defining the operation of the driver
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
USHORT useA; /* new bitmasks: see above */
|
|
||||||
USHORT useB;
|
|
||||||
USHORT mode; /* see consts above */
|
|
||||||
USHORT format; /* see consts above */
|
|
||||||
USHORT sampDiv; /* samp freq = 32 / n */
|
|
||||||
USHORT scale; /* scaling factor */
|
|
||||||
USHORT res1; /* must be 0 */
|
|
||||||
USHORT res2; /* must be 0 */
|
|
||||||
}
|
|
||||||
GAME_PARM_STRUCT;
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
// calibration values for each axis:
|
|
||||||
// - upper limit on value to be considered in lower range
|
|
||||||
// - centre value
|
|
||||||
// - lower limit on value to be considered in upper range
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GAME_3POS_STRUCT Ax;
|
|
||||||
GAME_3POS_STRUCT Ay;
|
|
||||||
GAME_3POS_STRUCT Bx;
|
|
||||||
GAME_3POS_STRUCT By;
|
|
||||||
}
|
|
||||||
GAME_CALIB_STRUCT;
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
// struct defining the digital response values for all axes
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GAME_3POS_STRUCT Ax;
|
|
||||||
GAME_3POS_STRUCT Ay;
|
|
||||||
GAME_3POS_STRUCT Bx;
|
|
||||||
GAME_3POS_STRUCT By;
|
|
||||||
}
|
|
||||||
GAME_DIGSET_STRUCT;
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
|
@ -1,77 +0,0 @@
|
||||||
/*
|
|
||||||
SDL - Simple DirectMedia Layer
|
|
||||||
Copyright (C) 1997-2009 Sam Lantinga
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Sam Lantinga
|
|
||||||
slouken@libsdl.org
|
|
||||||
*/
|
|
||||||
#include "SDL_config.h"
|
|
||||||
|
|
||||||
#ifdef SDL_LOADSO_OS2
|
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
||||||
/* System dependent library loading routines */
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#define INCL_DOSERRORS
|
|
||||||
#define INCL_DOSMODULEMGR
|
|
||||||
#include <os2.h>
|
|
||||||
|
|
||||||
#include "SDL_loadso.h"
|
|
||||||
|
|
||||||
void *
|
|
||||||
SDL_LoadObject(const char *sofile)
|
|
||||||
{
|
|
||||||
HMODULE handle = NULL;
|
|
||||||
char buf[512];
|
|
||||||
APIRET ulrc = DosLoadModule(buf, sizeof(buf), (char *) sofile, &handle);
|
|
||||||
|
|
||||||
/* Generate an error message if all loads failed */
|
|
||||||
if ((ulrc != NO_ERROR) || (handle == NULL))
|
|
||||||
SDL_SetError("Failed loading %s: %s", sofile, buf);
|
|
||||||
|
|
||||||
return ((void *) handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
SDL_LoadFunction(void *handle, const char *name)
|
|
||||||
{
|
|
||||||
const char *loaderror = "Unknown error";
|
|
||||||
void *symbol = NULL;
|
|
||||||
APIRET ulrc =
|
|
||||||
DosQueryProcAddr((HMODULE) handle, 0, (char *) name, &symbol);
|
|
||||||
if (ulrc == ERROR_INVALID_HANDLE)
|
|
||||||
loaderror = "Invalid module handle";
|
|
||||||
else if (ulrc == ERROR_INVALID_NAME)
|
|
||||||
loaderror = "Symbol not found";
|
|
||||||
|
|
||||||
if (symbol == NULL)
|
|
||||||
SDL_SetError("Failed loading %s: %s", name, loaderror);
|
|
||||||
|
|
||||||
return (symbol);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SDL_UnloadObject(void *handle)
|
|
||||||
{
|
|
||||||
if (handle != NULL)
|
|
||||||
DosFreeModule((HMODULE) handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* SDL_LOADSO_OS2 */
|
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
|
@ -34,7 +34,6 @@ SDL_bool SDL_GetPowerInfo_Linux_proc_acpi(SDL_PowerState *, int *, int *);
|
||||||
SDL_bool SDL_GetPowerInfo_Linux_proc_apm(SDL_PowerState *, int *, int *);
|
SDL_bool SDL_GetPowerInfo_Linux_proc_apm(SDL_PowerState *, int *, int *);
|
||||||
SDL_bool SDL_GetPowerInfo_Windows(SDL_PowerState *, int *, int *);
|
SDL_bool SDL_GetPowerInfo_Windows(SDL_PowerState *, int *, int *);
|
||||||
SDL_bool SDL_GetPowerInfo_MacOSX(SDL_PowerState *, int *, int *);
|
SDL_bool SDL_GetPowerInfo_MacOSX(SDL_PowerState *, int *, int *);
|
||||||
SDL_bool SDL_GetPowerInfo_OS2(SDL_PowerState *, int *, int *);
|
|
||||||
SDL_bool SDL_GetPowerInfo_BeOS(SDL_PowerState *, int *, int *);
|
SDL_bool SDL_GetPowerInfo_BeOS(SDL_PowerState *, int *, int *);
|
||||||
SDL_bool SDL_GetPowerInfo_NintendoDS(SDL_PowerState *, int *, int *);
|
SDL_bool SDL_GetPowerInfo_NintendoDS(SDL_PowerState *, int *, int *);
|
||||||
|
|
||||||
|
@ -65,9 +64,6 @@ static SDL_GetPowerInfo_Impl implementations[] = {
|
||||||
#ifdef SDL_POWER_MACOSX /* handles Mac OS X, Darwin, iPhone. */
|
#ifdef SDL_POWER_MACOSX /* handles Mac OS X, Darwin, iPhone. */
|
||||||
SDL_GetPowerInfo_MacOSX,
|
SDL_GetPowerInfo_MacOSX,
|
||||||
#endif
|
#endif
|
||||||
#ifdef SDL_POWER_OS2 /* handles OS/2, Warp, eComStation. */
|
|
||||||
SDL_GetPowerInfo_OS2,
|
|
||||||
#endif
|
|
||||||
#ifdef SDL_POWER_NINTENDODS /* handles Nintendo DS. */
|
#ifdef SDL_POWER_NINTENDODS /* handles Nintendo DS. */
|
||||||
SDL_GetPowerInfo_NintendoDS,
|
SDL_GetPowerInfo_NintendoDS,
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,135 +0,0 @@
|
||||||
/*
|
|
||||||
SDL - Simple DirectMedia Layer
|
|
||||||
Copyright (C) 1997-2009 Sam Lantinga
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Sam Lantinga
|
|
||||||
slouken@libsdl.org
|
|
||||||
*/
|
|
||||||
#include "SDL_config.h"
|
|
||||||
|
|
||||||
/* !!! FIXME:
|
|
||||||
* Please note that this code has not been tested (or even compiled!). It
|
|
||||||
* should, in theory, run on any version of OS/2, and work with any system
|
|
||||||
* that has APM.SYS loaded. I don't know if ACPI.SYS works.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SDL_POWER_DISABLED
|
|
||||||
#ifdef SDL_POWER_OS2
|
|
||||||
|
|
||||||
#define INCL_DOSFILEMGR
|
|
||||||
#define INCL_DOSDEVICES
|
|
||||||
#define INCL_DOSDEVIOCTL
|
|
||||||
#define INCL_DOSERRORS
|
|
||||||
#include <os2.h>
|
|
||||||
|
|
||||||
#include "SDL_power.h"
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
USHORT len;
|
|
||||||
USHORT flags;
|
|
||||||
UCHAR ac_status;
|
|
||||||
UCHAR battery_status;
|
|
||||||
UCHAR battery_life;
|
|
||||||
UCHAR battery_time_form;
|
|
||||||
USHORT battery_time;
|
|
||||||
UCHAR battery_flags;
|
|
||||||
} PowerStatus;
|
|
||||||
extern int CompilerAssertPowerStatus[(sizeof(PowerStatus) == 10) ? 1 : -1];
|
|
||||||
|
|
||||||
|
|
||||||
SDL_bool
|
|
||||||
SDL_GetPowerInfo_OS2(SDL_PowerState * state, int *seconds, int *percent)
|
|
||||||
{
|
|
||||||
PowerStatus status;
|
|
||||||
HFILE hfile = 0;
|
|
||||||
ULONG action = 0;
|
|
||||||
APIRET rc = 0;
|
|
||||||
|
|
||||||
*state = SDL_POWERSTATE_UNKNOWN;
|
|
||||||
*percent = -1;
|
|
||||||
*seconds = -1;
|
|
||||||
|
|
||||||
/* open the power management device */
|
|
||||||
rc = DosOpen("APM$", &hfile, &action, 0, FILE_NORMAL, FILE_OPEN,
|
|
||||||
OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, 0);
|
|
||||||
|
|
||||||
if (rc == NO_ERROR) {
|
|
||||||
USHORT iorc = 0;
|
|
||||||
ULONG iorclen = sizeof(iorc);
|
|
||||||
ULONG statuslen = sizeof(status);
|
|
||||||
|
|
||||||
SDL_memset(&status, '\0', sizeof(status));
|
|
||||||
status.len = sizeof(status);
|
|
||||||
|
|
||||||
rc = DosDevIOCtl(hfile, IOCTL_POWER, POWER_GETPOWERSTATUS, &status,
|
|
||||||
statuslen, &statuslen, &iorc, iorclen, &iorclen);
|
|
||||||
DosClose(hfile);
|
|
||||||
|
|
||||||
/* (status.flags & 0x1) == power subsystem enabled. */
|
|
||||||
if ((rc == NO_ERROR) && (status.flags & 0x1)) {
|
|
||||||
if (statuslen == 7) { /* older OS/2 APM driver? Less fields. */
|
|
||||||
status.battery_time_form = 0xFF;
|
|
||||||
status.battery_time = 0;
|
|
||||||
if (status.battery_status == 0xFF) {
|
|
||||||
status.battery_flags = 0xFF;
|
|
||||||
} else {
|
|
||||||
status.battery_flags = (1 << status.battery_status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status.battery_flags == 0xFF) { /* unknown state */
|
|
||||||
*state = SDL_POWERSTATE_UNKNOWN;
|
|
||||||
} else if (status.battery_flags & (1 << 7)) { /* no battery */
|
|
||||||
*state = SDL_POWERSTATE_NO_BATTERY;
|
|
||||||
} else if (status.battery_flags & (1 << 3)) { /* charging */
|
|
||||||
*state = SDL_POWERSTATE_CHARGING;
|
|
||||||
need_details = SDL_TRUE;
|
|
||||||
} else if (status.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (need_details) {
|
|
||||||
const int pct = (int) status.battery_life;
|
|
||||||
const int secs = (int) status.battery_time;
|
|
||||||
|
|
||||||
if (pct != 0xFF) { /* 255 == unknown */
|
|
||||||
*percent = (pct > 100) ? 100 : pct;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status.battery_time_form == 0xFF) { /* unknown */
|
|
||||||
*seconds = -1;
|
|
||||||
} else if (status.battery_time_form == 1) { /* minutes */
|
|
||||||
*seconds = secs * 60;
|
|
||||||
} else {
|
|
||||||
*seconds = secs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return SDL_TRUE; /* always the definitive answer on OS/2. */
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* SDL_POWER_OS2 */
|
|
||||||
#endif /* SDL_POWER_DISABLED */
|
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
|
@ -33,8 +33,6 @@
|
||||||
#include "dc/SDL_systhread_c.h"
|
#include "dc/SDL_systhread_c.h"
|
||||||
#elif SDL_THREAD_EPOC
|
#elif SDL_THREAD_EPOC
|
||||||
#include "epoc/SDL_systhread_c.h"
|
#include "epoc/SDL_systhread_c.h"
|
||||||
#elif SDL_THREAD_OS2
|
|
||||||
#include "os2/SDL_systhread_c.h"
|
|
||||||
#elif SDL_THREAD_PTH
|
#elif SDL_THREAD_PTH
|
||||||
#include "pth/SDL_systhread_c.h"
|
#include "pth/SDL_systhread_c.h"
|
||||||
#elif SDL_THREAD_PTHREAD
|
#elif SDL_THREAD_PTHREAD
|
||||||
|
|
|
@ -1,223 +0,0 @@
|
||||||
/*
|
|
||||||
SDL - Simple DirectMedia Layer
|
|
||||||
Copyright (C) 1997-2009 Sam Lantinga
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Sam Lantinga
|
|
||||||
slouken@libsdl.org
|
|
||||||
*/
|
|
||||||
#include "SDL_config.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 */
|
|
||||||
DECLSPEC SDL_cond *SDLCALL
|
|
||||||
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 */
|
|
||||||
DECLSPEC void SDLCALL
|
|
||||||
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 */
|
|
||||||
DECLSPEC int SDLCALL
|
|
||||||
SDL_CondSignal(SDL_cond * cond)
|
|
||||||
{
|
|
||||||
if (!cond) {
|
|
||||||
SDL_SetError("Passed a NULL condition variable");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
DECLSPEC int SDLCALL
|
|
||||||
SDL_CondBroadcast(SDL_cond * cond)
|
|
||||||
{
|
|
||||||
if (!cond) {
|
|
||||||
SDL_SetError("Passed a NULL condition variable");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
SDL_UnlockMutex(lock);
|
|
||||||
|
|
||||||
Thread B:
|
|
||||||
SDL_LockMutex(lock);
|
|
||||||
...
|
|
||||||
condition = true;
|
|
||||||
...
|
|
||||||
SDL_UnlockMutex(lock);
|
|
||||||
*/
|
|
||||||
DECLSPEC int SDLCALL
|
|
||||||
SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
|
|
||||||
{
|
|
||||||
int retval;
|
|
||||||
|
|
||||||
if (!cond) {
|
|
||||||
SDL_SetError("Passed a NULL condition variable");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
DECLSPEC int SDLCALL
|
|
||||||
SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
|
|
||||||
{
|
|
||||||
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
|
@ -1,23 +0,0 @@
|
||||||
/*
|
|
||||||
SDL - Simple DirectMedia Layer
|
|
||||||
Copyright (C) 1997-2009 Sam Lantinga
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Sam Lantinga
|
|
||||||
slouken@libsdl.org
|
|
||||||
*/
|
|
||||||
#include "SDL_config.h"
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
|
@ -1,107 +0,0 @@
|
||||||
/*
|
|
||||||
SDL - Simple DirectMedia Layer
|
|
||||||
Copyright (C) 1997-2009 Sam Lantinga
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Sam Lantinga
|
|
||||||
slouken@libsdl.org
|
|
||||||
*/
|
|
||||||
#include "SDL_config.h"
|
|
||||||
|
|
||||||
/* Mutex functions using the OS/2 API */
|
|
||||||
|
|
||||||
#define INCL_DOSERRORS
|
|
||||||
#define INCL_DOSSEMAPHORES
|
|
||||||
#include <os2.h>
|
|
||||||
|
|
||||||
#include "SDL_mutex.h"
|
|
||||||
|
|
||||||
|
|
||||||
struct SDL_mutex
|
|
||||||
{
|
|
||||||
HMTX hmtxID;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Create a mutex */
|
|
||||||
DECLSPEC SDL_mutex *SDLCALL
|
|
||||||
SDL_CreateMutex(void)
|
|
||||||
{
|
|
||||||
SDL_mutex *mutex;
|
|
||||||
APIRET ulrc;
|
|
||||||
|
|
||||||
/* Allocate mutex memory */
|
|
||||||
mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
|
|
||||||
if (mutex) {
|
|
||||||
/* Create the mutex, with initial value signaled */
|
|
||||||
ulrc = DosCreateMutexSem(NULL, // Create unnamed semaphore
|
|
||||||
&(mutex->hmtxID), // Pointer to handle
|
|
||||||
0L, // Flags: create it private (not shared)
|
|
||||||
FALSE); // Initial value: unowned
|
|
||||||
if (ulrc != NO_ERROR) {
|
|
||||||
SDL_SetError("Couldn't create mutex");
|
|
||||||
SDL_free(mutex);
|
|
||||||
mutex = NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SDL_OutOfMemory();
|
|
||||||
}
|
|
||||||
return (mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free the mutex */
|
|
||||||
DECLSPEC void SDLCALL
|
|
||||||
SDL_DestroyMutex(SDL_mutex * mutex)
|
|
||||||
{
|
|
||||||
if (mutex) {
|
|
||||||
if (mutex->hmtxID) {
|
|
||||||
DosCloseMutexSem(mutex->hmtxID);
|
|
||||||
mutex->hmtxID = 0;
|
|
||||||
}
|
|
||||||
SDL_free(mutex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lock the mutex */
|
|
||||||
DECLSPEC int SDLCALL
|
|
||||||
SDL_mutexP(SDL_mutex * mutex)
|
|
||||||
{
|
|
||||||
if (mutex == NULL) {
|
|
||||||
SDL_SetError("Passed a NULL mutex");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (DosRequestMutexSem(mutex->hmtxID, SEM_INDEFINITE_WAIT) != NO_ERROR) {
|
|
||||||
SDL_SetError("Couldn't wait on mutex");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unlock the mutex */
|
|
||||||
DECLSPEC int SDLCALL
|
|
||||||
SDL_mutexV(SDL_mutex * mutex)
|
|
||||||
{
|
|
||||||
if (mutex == NULL) {
|
|
||||||
SDL_SetError("Passed a NULL mutex");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (DosReleaseMutexSem(mutex->hmtxID) != NO_ERROR) {
|
|
||||||
SDL_SetError("Couldn't release mutex");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
|
@ -1,194 +0,0 @@
|
||||||
/*
|
|
||||||
SDL - Simple DirectMedia Layer
|
|
||||||
Copyright (C) 1997-2009 Sam Lantinga
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Sam Lantinga
|
|
||||||
slouken@libsdl.org
|
|
||||||
*/
|
|
||||||
#include "SDL_config.h"
|
|
||||||
|
|
||||||
/* Semaphore functions using the OS/2 API */
|
|
||||||
|
|
||||||
#define INCL_DOS
|
|
||||||
#define INCL_DOSERRORS
|
|
||||||
#define INCL_DOSSEMAPHORES
|
|
||||||
#include <os2.h>
|
|
||||||
|
|
||||||
#include "SDL_thread.h"
|
|
||||||
#include "SDL_timer.h"
|
|
||||||
|
|
||||||
|
|
||||||
struct SDL_semaphore
|
|
||||||
{
|
|
||||||
HMTX id;
|
|
||||||
HEV changed;
|
|
||||||
Uint32 value;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Create a semaphore */
|
|
||||||
DECLSPEC SDL_sem *SDLCALL
|
|
||||||
SDL_CreateSemaphore(Uint32 initial_value)
|
|
||||||
{
|
|
||||||
SDL_sem *sem;
|
|
||||||
ULONG ulrc;
|
|
||||||
|
|
||||||
/* Allocate sem memory */
|
|
||||||
sem = (SDL_sem *) SDL_malloc(sizeof(*sem));
|
|
||||||
if (sem) {
|
|
||||||
/* Create the mutex semaphore */
|
|
||||||
ulrc = DosCreateMutexSem(NULL, &(sem->id), 0, TRUE);
|
|
||||||
if (ulrc) {
|
|
||||||
SDL_SetError("Couldn't create semaphore");
|
|
||||||
SDL_free(sem);
|
|
||||||
sem = NULL;
|
|
||||||
} else {
|
|
||||||
DosCreateEventSem(NULL, &(sem->changed), 0, FALSE);
|
|
||||||
sem->value = initial_value;
|
|
||||||
DosReleaseMutexSem(sem->id);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SDL_OutOfMemory();
|
|
||||||
}
|
|
||||||
return (sem);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free the semaphore */
|
|
||||||
DECLSPEC void SDLCALL
|
|
||||||
SDL_DestroySemaphore(SDL_sem * sem)
|
|
||||||
{
|
|
||||||
if (sem) {
|
|
||||||
if (sem->id) {
|
|
||||||
DosCloseEventSem(sem->changed);
|
|
||||||
DosCloseMutexSem(sem->id);
|
|
||||||
sem->id = 0;
|
|
||||||
}
|
|
||||||
SDL_free(sem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DECLSPEC int SDLCALL
|
|
||||||
SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
|
|
||||||
{
|
|
||||||
ULONG ulrc;
|
|
||||||
|
|
||||||
if (!sem) {
|
|
||||||
SDL_SetError("Passed a NULL sem");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timeout == SDL_MUTEX_MAXWAIT) {
|
|
||||||
while (1) {
|
|
||||||
ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT);
|
|
||||||
if (ulrc) {
|
|
||||||
/* if error waiting mutex */
|
|
||||||
SDL_SetError("DosRequestMutexSem() failed");
|
|
||||||
return -1;
|
|
||||||
} else if (sem->value) {
|
|
||||||
sem->value--;
|
|
||||||
DosReleaseMutexSem(sem->id);
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
ULONG ulPostCount;
|
|
||||||
DosResetEventSem(sem->changed, &ulPostCount);
|
|
||||||
DosReleaseMutexSem(sem->id);
|
|
||||||
/* continue waiting until somebody posts the semaphore */
|
|
||||||
DosWaitEventSem(sem->changed, SEM_INDEFINITE_WAIT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (timeout == 0) {
|
|
||||||
ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT);
|
|
||||||
if (ulrc == NO_ERROR) {
|
|
||||||
if (sem->value) {
|
|
||||||
sem->value--;
|
|
||||||
DosReleaseMutexSem(sem->id);
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
DosReleaseMutexSem(sem->id);
|
|
||||||
return SDL_MUTEX_TIMEDOUT;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SDL_SetError("DosRequestMutexSem() failed");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT);
|
|
||||||
if (ulrc) {
|
|
||||||
/* if error waiting mutex */
|
|
||||||
SDL_SetError("DosRequestMutexSem() failed");
|
|
||||||
return -1;
|
|
||||||
} else if (sem->value) {
|
|
||||||
sem->value--;
|
|
||||||
DosReleaseMutexSem(sem->id);
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
ULONG ulPostCount;
|
|
||||||
DosResetEventSem(sem->changed, &ulPostCount);
|
|
||||||
DosReleaseMutexSem(sem->id);
|
|
||||||
/* continue waiting until somebody posts the semaphore */
|
|
||||||
ulrc = DosWaitEventSem(sem->changed, timeout);
|
|
||||||
if (ulrc == NO_ERROR)
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return SDL_MUTEX_TIMEDOUT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* never reached */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
DECLSPEC int SDLCALL
|
|
||||||
SDL_SemTryWait(SDL_sem * sem)
|
|
||||||
{
|
|
||||||
return SDL_SemWaitTimeout(sem, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
DECLSPEC int SDLCALL
|
|
||||||
SDL_SemWait(SDL_sem * sem)
|
|
||||||
{
|
|
||||||
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns the current count of the semaphore */
|
|
||||||
DECLSPEC Uint32 SDLCALL
|
|
||||||
SDL_SemValue(SDL_sem * sem)
|
|
||||||
{
|
|
||||||
if (!sem) {
|
|
||||||
SDL_SetError("Passed a NULL sem");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return sem->value;
|
|
||||||
}
|
|
||||||
|
|
||||||
DECLSPEC int SDLCALL
|
|
||||||
SDL_SemPost(SDL_sem * sem)
|
|
||||||
{
|
|
||||||
if (!sem) {
|
|
||||||
SDL_SetError("Passed a NULL sem");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT)) {
|
|
||||||
SDL_SetError("DosRequestMutexSem() failed");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
sem->value++;
|
|
||||||
DosPostEventSem(sem->changed);
|
|
||||||
DosReleaseMutexSem(sem->id);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
|
@ -1,105 +0,0 @@
|
||||||
/*
|
|
||||||
SDL - Simple DirectMedia Layer
|
|
||||||
Copyright (C) 1997-2009 Sam Lantinga
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Sam Lantinga
|
|
||||||
slouken@libsdl.org
|
|
||||||
*/
|
|
||||||
#include "SDL_config.h"
|
|
||||||
|
|
||||||
/* OS/2 thread management routines for SDL */
|
|
||||||
|
|
||||||
#include <process.h>
|
|
||||||
#define INCL_DOSERRORS
|
|
||||||
#define INCL_DOSPROCESS
|
|
||||||
#include <os2.h>
|
|
||||||
|
|
||||||
#include "SDL_thread.h"
|
|
||||||
#include "../SDL_systhread.h"
|
|
||||||
#include "../SDL_thread_c.h"
|
|
||||||
|
|
||||||
typedef struct ThreadStartParms
|
|
||||||
{
|
|
||||||
void *args;
|
|
||||||
pfnSDL_CurrentEndThread pfnCurrentEndThread;
|
|
||||||
} tThreadStartParms, *pThreadStartParms;
|
|
||||||
|
|
||||||
static void
|
|
||||||
threadfunc(void *pparm)
|
|
||||||
{
|
|
||||||
pThreadStartParms pThreadParms = pparm;
|
|
||||||
pfnSDL_CurrentEndThread pfnCurrentEndThread = NULL;
|
|
||||||
|
|
||||||
// Call the thread function!
|
|
||||||
SDL_RunThread(pThreadParms->args);
|
|
||||||
|
|
||||||
// Get the current endthread we have to use!
|
|
||||||
if (pThreadParms) {
|
|
||||||
pfnCurrentEndThread = pThreadParms->pfnCurrentEndThread;
|
|
||||||
SDL_free(pThreadParms);
|
|
||||||
}
|
|
||||||
// Call endthread!
|
|
||||||
if (pfnCurrentEndThread)
|
|
||||||
(*pfnCurrentEndThread) ();
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
SDL_SYS_CreateThread(SDL_Thread * thread, void *args,
|
|
||||||
pfnSDL_CurrentBeginThread pfnBeginThread,
|
|
||||||
pfnSDL_CurrentEndThread pfnEndThread)
|
|
||||||
{
|
|
||||||
pThreadStartParms pThreadParms = SDL_malloc(sizeof(tThreadStartParms));
|
|
||||||
if (!pThreadParms) {
|
|
||||||
SDL_SetError("Not enough memory to create thread");
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
// 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;
|
|
||||||
// Start the thread using the runtime library of calling app!
|
|
||||||
thread->threadid = thread->handle =
|
|
||||||
(*pfnBeginThread) (threadfunc, NULL, 512 * 1024, pThreadParms);
|
|
||||||
if ((int) thread->threadid <= 0) {
|
|
||||||
SDL_SetError("Not enough resources to create thread");
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SDL_SYS_SetupThread(void)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DECLSPEC Uint32 SDLCALL
|
|
||||||
SDL_ThreadID(void)
|
|
||||||
{
|
|
||||||
PTIB tib;
|
|
||||||
DosGetInfoBlocks(&tib, NULL);
|
|
||||||
return ((Uint32) (tib->tib_ptib2->tib2_ultid));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SDL_SYS_WaitThread(SDL_Thread * thread)
|
|
||||||
{
|
|
||||||
TID tid = thread->handle;
|
|
||||||
DosWaitThread(&tid, DCWW_WAIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
SDL - Simple DirectMedia Layer
|
|
||||||
Copyright (C) 1997-2009 Sam Lantinga
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Sam Lantinga
|
|
||||||
slouken@libsdl.org
|
|
||||||
*/
|
|
||||||
#include "SDL_config.h"
|
|
||||||
|
|
||||||
#define INCL_DOSPROCESS
|
|
||||||
#include <os2.h>
|
|
||||||
|
|
||||||
typedef TID SYS_ThreadHandle;
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
|
@ -1,235 +0,0 @@
|
||||||
/*
|
|
||||||
SDL - Simple DirectMedia Layer
|
|
||||||
Copyright (C) 1997-2009 Sam Lantinga
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Sam Lantinga
|
|
||||||
slouken@libsdl.org
|
|
||||||
*/
|
|
||||||
#include "SDL_config.h"
|
|
||||||
|
|
||||||
#ifdef SDL_TIMER_OS2
|
|
||||||
|
|
||||||
#define INCL_DOSMISC
|
|
||||||
#define INCL_DOSERRORS
|
|
||||||
#define INCL_DOSSEMAPHORES
|
|
||||||
#define INCL_DOSDATETIME
|
|
||||||
#define INCL_DOSPROCESS
|
|
||||||
#define INCL_DOSPROFILE
|
|
||||||
#define INCL_DOSEXCEPTIONS
|
|
||||||
#include <os2.h>
|
|
||||||
|
|
||||||
#include "SDL_thread.h"
|
|
||||||
#include "SDL_timer.h"
|
|
||||||
#include "../SDL_timer_c.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define TIME_WRAP_VALUE (~(DWORD)0)
|
|
||||||
|
|
||||||
/* The first high-resolution ticks value of the application */
|
|
||||||
static long long hires_start_ticks;
|
|
||||||
/* The number of ticks per second of the high-resolution performance counter */
|
|
||||||
static ULONG hires_ticks_per_second;
|
|
||||||
|
|
||||||
void
|
|
||||||
SDL_StartTicks(void)
|
|
||||||
{
|
|
||||||
DosTmrQueryFreq(&hires_ticks_per_second);
|
|
||||||
DosTmrQueryTime((PQWORD) & hires_start_ticks);
|
|
||||||
}
|
|
||||||
|
|
||||||
DECLSPEC Uint32 SDLCALL
|
|
||||||
SDL_GetTicks(void)
|
|
||||||
{
|
|
||||||
long long hires_now;
|
|
||||||
ULONG ticks = ticks;
|
|
||||||
|
|
||||||
DosTmrQueryTime((PQWORD) & hires_now);
|
|
||||||
/*
|
|
||||||
hires_now -= hires_start_ticks;
|
|
||||||
hires_now *= 1000;
|
|
||||||
hires_now /= hires_ticks_per_second;
|
|
||||||
*/
|
|
||||||
/* inline asm to avoid runtime inclusion */
|
|
||||||
/* *INDENT-OFF* */
|
|
||||||
_asm {
|
|
||||||
push edx
|
|
||||||
push eax
|
|
||||||
mov eax, dword ptr hires_now
|
|
||||||
mov edx, dword ptr hires_now + 4
|
|
||||||
sub eax, dword ptr hires_start_ticks
|
|
||||||
sbb edx, dword ptr hires_start_ticks + 4
|
|
||||||
mov ebx, 1000
|
|
||||||
mov ecx, edx
|
|
||||||
mul ebx
|
|
||||||
push eax
|
|
||||||
push edx
|
|
||||||
mov eax, ecx
|
|
||||||
mul ebx
|
|
||||||
pop eax
|
|
||||||
add edx, eax
|
|
||||||
pop eax
|
|
||||||
mov ebx, dword ptr hires_ticks_per_second
|
|
||||||
div ebx
|
|
||||||
mov dword ptr ticks, eax
|
|
||||||
pop edx
|
|
||||||
pop eax
|
|
||||||
}
|
|
||||||
/* *INDENT-ON* */
|
|
||||||
|
|
||||||
return ticks;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* High resolution sleep, originally made by Ilya Zakharevich */
|
|
||||||
DECLSPEC void SDLCALL
|
|
||||||
SDL_Delay(Uint32 ms)
|
|
||||||
{
|
|
||||||
/* This is similar to DosSleep(), but has 8ms granularity in time-critical
|
|
||||||
threads even on Warp3. */
|
|
||||||
HEV hevEvent1 = 0; /* Event semaphore handle */
|
|
||||||
HTIMER htimerEvent1 = 0; /* Timer handle */
|
|
||||||
APIRET rc = NO_ERROR; /* Return code */
|
|
||||||
int ret = 1;
|
|
||||||
ULONG priority = 0, nesting; /* Shut down the warnings */
|
|
||||||
PPIB pib;
|
|
||||||
PTIB tib;
|
|
||||||
char *e = NULL;
|
|
||||||
APIRET badrc;
|
|
||||||
int switch_priority = 50;
|
|
||||||
|
|
||||||
DosCreateEventSem(NULL, /* Unnamed */
|
|
||||||
&hevEvent1, /* Handle of semaphore returned */
|
|
||||||
DC_SEM_SHARED, /* Shared needed for DosAsyncTimer */
|
|
||||||
FALSE); /* Semaphore is in RESET state */
|
|
||||||
|
|
||||||
if (ms >= switch_priority)
|
|
||||||
switch_priority = 0;
|
|
||||||
if (switch_priority) {
|
|
||||||
if (DosGetInfoBlocks(&tib, &pib) != NO_ERROR)
|
|
||||||
switch_priority = 0;
|
|
||||||
else {
|
|
||||||
/* In Warp3, to switch scheduling to 8ms step, one needs to do
|
|
||||||
DosAsyncTimer() in time-critical thread. On laters versions,
|
|
||||||
more and more cases of wait-for-something are covered.
|
|
||||||
|
|
||||||
It turns out that on Warp3fp42 it is the priority at the time
|
|
||||||
of DosAsyncTimer() which matters. Let's hope that this works
|
|
||||||
with later versions too... XXXX
|
|
||||||
*/
|
|
||||||
priority = (tib->tib_ptib2->tib2_ulpri);
|
|
||||||
if ((priority & 0xFF00) == 0x0300) /* already time-critical */
|
|
||||||
switch_priority = 0;
|
|
||||||
/* Make us time-critical. Just modifying TIB is not enough... */
|
|
||||||
/* tib->tib_ptib2->tib2_ulpri = 0x0300; */
|
|
||||||
/* We do not want to run at high priority if a signal causes us
|
|
||||||
to longjmp() out of this section... */
|
|
||||||
if (DosEnterMustComplete(&nesting))
|
|
||||||
switch_priority = 0;
|
|
||||||
else
|
|
||||||
DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((badrc = DosAsyncTimer(ms, (HSEM) hevEvent1, /* Semaphore to post */
|
|
||||||
&htimerEvent1))) /* Timer handler (returned) */
|
|
||||||
e = "DosAsyncTimer";
|
|
||||||
|
|
||||||
if (switch_priority && tib->tib_ptib2->tib2_ulpri == 0x0300) {
|
|
||||||
/* Nobody switched priority while we slept... Ignore errors... */
|
|
||||||
/* tib->tib_ptib2->tib2_ulpri = priority; *//* Get back... */
|
|
||||||
if (!
|
|
||||||
(rc = DosSetPriority(PRTYS_THREAD, (priority >> 8) & 0xFF, 0, 0)))
|
|
||||||
rc = DosSetPriority(PRTYS_THREAD, 0, priority & 0xFF, 0);
|
|
||||||
}
|
|
||||||
if (switch_priority)
|
|
||||||
rc = DosExitMustComplete(&nesting); /* Ignore errors */
|
|
||||||
|
|
||||||
/* The actual blocking call is made with "normal" priority. This way we
|
|
||||||
should not bother with DosSleep(0) etc. to compensate for us interrupting
|
|
||||||
higher-priority threads. The goal is to prohibit the system spending too
|
|
||||||
much time halt()ing, not to run us "no matter what". */
|
|
||||||
if (!e) /* Wait for AsyncTimer event */
|
|
||||||
badrc = DosWaitEventSem(hevEvent1, SEM_INDEFINITE_WAIT);
|
|
||||||
|
|
||||||
if (e); /* Do nothing */
|
|
||||||
else if (badrc == ERROR_INTERRUPT)
|
|
||||||
ret = 0;
|
|
||||||
else if (badrc)
|
|
||||||
e = "DosWaitEventSem";
|
|
||||||
if ((rc = DosCloseEventSem(hevEvent1)) && !e) { /* Get rid of semaphore */
|
|
||||||
e = "DosCloseEventSem";
|
|
||||||
badrc = rc;
|
|
||||||
}
|
|
||||||
if (e) {
|
|
||||||
SDL_SetError("[SDL_Delay] : Had error in %s(), rc is 0x%x\n", e,
|
|
||||||
badrc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Data to handle a single periodic alarm */
|
|
||||||
static int timer_alive = 0;
|
|
||||||
static SDL_Thread *timer = NULL;
|
|
||||||
|
|
||||||
static int SDLCALL
|
|
||||||
RunTimer(void *unused)
|
|
||||||
{
|
|
||||||
DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);
|
|
||||||
while (timer_alive) {
|
|
||||||
if (SDL_timer_running) {
|
|
||||||
SDL_ThreadedTimerCheck();
|
|
||||||
}
|
|
||||||
SDL_Delay(10);
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is only called if the event thread is not running */
|
|
||||||
int
|
|
||||||
SDL_SYS_TimerInit(void)
|
|
||||||
{
|
|
||||||
timer_alive = 1;
|
|
||||||
timer = SDL_CreateThread(RunTimer, NULL);
|
|
||||||
if (timer == NULL)
|
|
||||||
return (-1);
|
|
||||||
return (SDL_SetTimerThreaded(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SDL_SYS_TimerQuit(void)
|
|
||||||
{
|
|
||||||
timer_alive = 0;
|
|
||||||
if (timer) {
|
|
||||||
SDL_WaitThread(timer, NULL);
|
|
||||||
timer = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
SDL_SYS_StartTimer(void)
|
|
||||||
{
|
|
||||||
SDL_SetError("Internal logic error: OS/2 uses threaded timer");
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SDL_SYS_StopTimer(void)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* SDL_TIMER_OS2 */
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
|
@ -395,9 +395,6 @@ extern VideoBootStrap DC_bootstrap;
|
||||||
#if SDL_VIDEO_DRIVER_RISCOS
|
#if SDL_VIDEO_DRIVER_RISCOS
|
||||||
extern VideoBootStrap RISCOS_bootstrap;
|
extern VideoBootStrap RISCOS_bootstrap;
|
||||||
#endif
|
#endif
|
||||||
#if SDL_VIDEO_DRIVER_OS2FS
|
|
||||||
extern VideoBootStrap OS2FSLib_bootstrap;
|
|
||||||
#endif
|
|
||||||
#if SDL_VIDEO_DRIVER_UIKIT
|
#if SDL_VIDEO_DRIVER_UIKIT
|
||||||
extern VideoBootStrap UIKIT_bootstrap;
|
extern VideoBootStrap UIKIT_bootstrap;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -109,9 +109,6 @@ static VideoBootStrap *bootstrap[] = {
|
||||||
#if SDL_VIDEO_DRIVER_RISCOS
|
#if SDL_VIDEO_DRIVER_RISCOS
|
||||||
&RISCOS_bootstrap,
|
&RISCOS_bootstrap,
|
||||||
#endif
|
#endif
|
||||||
#if SDL_VIDEO_DRIVER_OS2FS
|
|
||||||
&OS2FSLib_bootstrap,
|
|
||||||
#endif
|
|
||||||
#if SDL_VIDEO_DRIVER_NDS
|
#if SDL_VIDEO_DRIVER_NDS
|
||||||
&NDS_bootstrap,
|
&NDS_bootstrap,
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,72 +0,0 @@
|
||||||
/*
|
|
||||||
SDL - Simple DirectMedia Layer
|
|
||||||
Copyright (C) 1997-2009 Sam Lantinga
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
Sam Lantinga
|
|
||||||
slouken@libsdl.org
|
|
||||||
*/
|
|
||||||
#include "SDL_config.h"
|
|
||||||
|
|
||||||
#ifndef _SDL_os2fslib_h
|
|
||||||
#define _SDL_os2fslib_h
|
|
||||||
|
|
||||||
|
|
||||||
// OS2 specific includes
|
|
||||||
#define INCL_TYPES
|
|
||||||
#define INCL_DOS
|
|
||||||
#define INCL_DOSERRORS
|
|
||||||
#define INCL_DOSPROCESS
|
|
||||||
#define INCL_WIN
|
|
||||||
#define INCL_GPI
|
|
||||||
#include <os2.h>
|
|
||||||
|
|
||||||
#include <FSLib.h>
|
|
||||||
|
|
||||||
/* Hidden "this" pointer for the video functions */
|
|
||||||
#define _THIS SDL_VideoDevice *_this
|
|
||||||
|
|
||||||
/* Private display data */
|
|
||||||
struct SDL_PrivateVideoData
|
|
||||||
{
|
|
||||||
FSLib_VideoMode_p pAvailableFSLibVideoModes;
|
|
||||||
SDL_Rect **pListModesResult; // Allocated memory to return list of modes for os2fslib_ListModes() API
|
|
||||||
|
|
||||||
FSLib_VideoMode SrcBufferDesc; // Description of current source image buffer
|
|
||||||
char *pchSrcBuffer; // The source image buffer itself
|
|
||||||
SDL_Surface *pSDLSurface; // The SDL surface describing the buffer
|
|
||||||
HMTX hmtxUseSrcBuffer; // Mutex semaphore to manipulate src buffer
|
|
||||||
HWND hwndFrame, hwndClient; // Window handle of frame and client
|
|
||||||
int iPMThreadStatus; // 0: Not running
|
|
||||||
// 1: Running
|
|
||||||
// Other: Not running, had an error
|
|
||||||
int tidPMThread; // Thread ID of PM Thread
|
|
||||||
int fInFocus; // True if we're in focus!
|
|
||||||
int iSkipWMMOUSEMOVE; // Number of WM_MOUSEMOVE messages to skip!
|
|
||||||
int iMouseVisible; //
|
|
||||||
|
|
||||||
PFNWP pfnOldFrameProc; // Old window frame procedure
|
|
||||||
int bProportionalResize; // 0: No proportional resizing
|
|
||||||
// 1: Do proportional resizing
|
|
||||||
ULONG ulResizingFlag; // First resizing flag value
|
|
||||||
};
|
|
||||||
|
|
||||||
/* OS/2 specific backdoor function to be able to set FrameControlFlags of */
|
|
||||||
/* the SDL window before creating it. */
|
|
||||||
extern DECLSPEC void SDLCALL SDL_OS2FSLIB_SetFCFToUse(ULONG ulFCF);
|
|
||||||
|
|
||||||
#endif /* _SDL_os2fslib_h */
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
|
@ -1,75 +0,0 @@
|
||||||
/*
|
|
||||||
SDL - Simple DirectMedia Layer
|
|
||||||
Copyright (C) 1997-2009 Sam Lantinga
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Sam Lantinga
|
|
||||||
slouken@libsdl.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef VK_0
|
|
||||||
#define VK_0 '0'
|
|
||||||
#define VK_1 '1'
|
|
||||||
#define VK_2 '2'
|
|
||||||
#define VK_3 '3'
|
|
||||||
#define VK_4 '4'
|
|
||||||
#define VK_5 '5'
|
|
||||||
#define VK_6 '6'
|
|
||||||
#define VK_7 '7'
|
|
||||||
#define VK_8 '8'
|
|
||||||
#define VK_9 '9'
|
|
||||||
#define VK_A 'A'
|
|
||||||
#define VK_B 'B'
|
|
||||||
#define VK_C 'C'
|
|
||||||
#define VK_D 'D'
|
|
||||||
#define VK_E 'E'
|
|
||||||
#define VK_F 'F'
|
|
||||||
#define VK_G 'G'
|
|
||||||
#define VK_H 'H'
|
|
||||||
#define VK_I 'I'
|
|
||||||
#define VK_J 'J'
|
|
||||||
#define VK_K 'K'
|
|
||||||
#define VK_L 'L'
|
|
||||||
#define VK_M 'M'
|
|
||||||
#define VK_N 'N'
|
|
||||||
#define VK_O 'O'
|
|
||||||
#define VK_P 'P'
|
|
||||||
#define VK_Q 'Q'
|
|
||||||
#define VK_R 'R'
|
|
||||||
#define VK_S 'S'
|
|
||||||
#define VK_T 'T'
|
|
||||||
#define VK_U 'U'
|
|
||||||
#define VK_V 'V'
|
|
||||||
#define VK_W 'W'
|
|
||||||
#define VK_X 'X'
|
|
||||||
#define VK_Y 'Y'
|
|
||||||
#define VK_Z 'Z'
|
|
||||||
#endif /* VK_0 */
|
|
||||||
|
|
||||||
/* These keys haven't been defined, but were experimentally determined */
|
|
||||||
#define VK_SEMICOLON 0xBA
|
|
||||||
#define VK_EQUALS 0xBB
|
|
||||||
#define VK_COMMA 0xBC
|
|
||||||
#define VK_MINUS 0xBD
|
|
||||||
#define VK_PERIOD 0xBE
|
|
||||||
#define VK_SLASH 0xBF
|
|
||||||
#define VK_GRAVE 0xC0
|
|
||||||
#define VK_LBRACKET 0xDB
|
|
||||||
#define VK_BACKSLASH 0xDC
|
|
||||||
#define VK_RBRACKET 0xDD
|
|
||||||
#define VK_APOSTROPHE 0xDE
|
|
||||||
#define VK_BACKTICK 0xDF
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
Loading…
Add table
Add a link
Reference in a new issue