mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-05 13:34:41 +00:00
Merge SDL-ryan-batching-renderer branch to default.
This commit is contained in:
14
src/SDL.c
14
src/SDL.c
@@ -124,11 +124,11 @@ SDL_InitSubSystem(Uint32 flags)
|
||||
}
|
||||
|
||||
#if SDL_VIDEO_DRIVER_WINDOWS
|
||||
if ((flags & (SDL_INIT_HAPTIC|SDL_INIT_JOYSTICK))) {
|
||||
if (SDL_HelperWindowCreate() < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if ((flags & (SDL_INIT_HAPTIC|SDL_INIT_JOYSTICK))) {
|
||||
if (SDL_HelperWindowCreate() < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !SDL_TIMERS_DISABLED
|
||||
@@ -263,8 +263,8 @@ SDL_QuitSubSystem(Uint32 flags)
|
||||
#if !SDL_SENSOR_DISABLED
|
||||
if ((flags & SDL_INIT_SENSOR)) {
|
||||
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_SENSOR)) {
|
||||
SDL_SensorQuit();
|
||||
}
|
||||
SDL_SensorQuit();
|
||||
}
|
||||
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_SENSOR);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_assert_c_h_
|
||||
#define SDL_assert_c_h_
|
||||
|
||||
extern void SDL_AssertionsQuit(void);
|
||||
|
||||
#endif /* SDL_assert_c_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -53,10 +53,11 @@
|
||||
#endif
|
||||
|
||||
#if defined(__WATCOMC__) && defined(__386__)
|
||||
SDL_COMPILE_TIME_ASSERT(intsize, 4==sizeof(int));
|
||||
#define HAVE_WATCOM_ATOMICS
|
||||
extern _inline int _SDL_xchg_watcom(volatile int *a, int v);
|
||||
#pragma aux _SDL_xchg_watcom = \
|
||||
"xchg [ecx], eax" \
|
||||
"lock xchg [ecx], eax" \
|
||||
parm [ecx] [eax] \
|
||||
value [eax] \
|
||||
modify exact [eax];
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
SDL_COMPILE_TIME_ASSERT(locksize, 4==sizeof(SDL_SpinLock));
|
||||
extern _inline int _SDL_xchg_watcom(volatile int *a, int v);
|
||||
#pragma aux _SDL_xchg_watcom = \
|
||||
"xchg [ecx], eax" \
|
||||
"lock xchg [ecx], eax" \
|
||||
parm [ecx] [eax] \
|
||||
value [eax] \
|
||||
modify exact [eax];
|
||||
|
||||
@@ -378,21 +378,57 @@ static int
|
||||
add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount)
|
||||
{
|
||||
int retval = -1;
|
||||
const size_t size = sizeof (SDL_AudioDeviceItem) + SDL_strlen(name) + 1;
|
||||
SDL_AudioDeviceItem *item = (SDL_AudioDeviceItem *) SDL_malloc(size);
|
||||
if (item == NULL) {
|
||||
return -1;
|
||||
}
|
||||
SDL_AudioDeviceItem *item;
|
||||
const SDL_AudioDeviceItem *i;
|
||||
int dupenum = 0;
|
||||
|
||||
SDL_assert(handle != NULL); /* we reserve NULL, audio backends can't use it. */
|
||||
SDL_assert(name != NULL);
|
||||
|
||||
item = (SDL_AudioDeviceItem *) SDL_malloc(sizeof (SDL_AudioDeviceItem));
|
||||
if (!item) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
item->original_name = SDL_strdup(name);
|
||||
if (!item->original_name) {
|
||||
SDL_free(item);
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
item->dupenum = 0;
|
||||
item->name = item->original_name;
|
||||
item->handle = handle;
|
||||
SDL_strlcpy(item->name, name, size - sizeof (SDL_AudioDeviceItem));
|
||||
|
||||
SDL_LockMutex(current_audio.detectionLock);
|
||||
|
||||
for (i = *devices; i != NULL; i = i->next) {
|
||||
if (SDL_strcmp(name, i->original_name) == 0) {
|
||||
dupenum = i->dupenum + 1;
|
||||
break; /* stop at the highest-numbered dupe. */
|
||||
}
|
||||
}
|
||||
|
||||
if (dupenum) {
|
||||
const size_t len = SDL_strlen(name) + 16;
|
||||
char *replacement = (char *) SDL_malloc(len);
|
||||
if (!replacement) {
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
SDL_free(item->original_name);
|
||||
SDL_free(item);
|
||||
SDL_OutOfMemory();
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_snprintf(replacement, len, "%s (%d)", name, dupenum + 1);
|
||||
item->dupenum = dupenum;
|
||||
item->name = replacement;
|
||||
}
|
||||
|
||||
item->next = *devices;
|
||||
*devices = item;
|
||||
retval = (*devCount)++;
|
||||
retval = (*devCount)++; /* !!! FIXME: this should be an atomic increment */
|
||||
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
|
||||
return retval;
|
||||
@@ -420,6 +456,11 @@ free_device_list(SDL_AudioDeviceItem **devices, int *devCount)
|
||||
if (item->handle != NULL) {
|
||||
current_audio.impl.FreeDeviceHandle(item->handle);
|
||||
}
|
||||
/* these two pointers are the same if not a duplicate devname */
|
||||
if (item->name != item->original_name) {
|
||||
SDL_free(item->name);
|
||||
}
|
||||
SDL_free(item->original_name);
|
||||
SDL_free(item);
|
||||
}
|
||||
*devices = NULL;
|
||||
@@ -977,6 +1018,11 @@ clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *re
|
||||
} else {
|
||||
*devices = next;
|
||||
}
|
||||
/* these two pointers are the same if not a duplicate devname */
|
||||
if (item->name != item->original_name) {
|
||||
SDL_free(item->name);
|
||||
}
|
||||
SDL_free(item->original_name);
|
||||
SDL_free(item);
|
||||
}
|
||||
item = next;
|
||||
@@ -1003,7 +1049,6 @@ SDL_GetNumAudioDevices(int iscapture)
|
||||
|
||||
if (!iscapture && current_audio.outputDevicesRemoved) {
|
||||
clean_out_device_list(¤t_audio.outputDevices, ¤t_audio.outputDeviceCount, ¤t_audio.outputDevicesRemoved);
|
||||
current_audio.outputDevicesRemoved = SDL_FALSE;
|
||||
}
|
||||
|
||||
retval = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
|
||||
@@ -1130,8 +1175,9 @@ prepare_audiospec(const SDL_AudioSpec * orig, SDL_AudioSpec * prepared)
|
||||
}
|
||||
case 1: /* Mono */
|
||||
case 2: /* Stereo */
|
||||
case 4: /* surround */
|
||||
case 6: /* surround with center and lfe */
|
||||
case 4: /* Quadrophonic */
|
||||
case 6: /* 5.1 surround */
|
||||
case 8: /* 7.1 surround */
|
||||
break;
|
||||
default:
|
||||
SDL_SetError("Unsupported number of audio channels.");
|
||||
@@ -1324,15 +1370,12 @@ open_audio_device(const char *devname, int iscapture,
|
||||
build_stream = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* !!! FIXME in 2.1: add SDL_AUDIO_ALLOW_SAMPLES_CHANGE flag?
|
||||
As of 2.0.6, we will build a stream to buffer the difference between
|
||||
what the app wants to feed and the device wants to eat, so everyone
|
||||
gets their way. In prior releases, SDL would force the callback to
|
||||
feed at the rate the device requested, adjusted for resampling.
|
||||
*/
|
||||
if (device->spec.samples != obtained->samples) {
|
||||
build_stream = SDL_TRUE;
|
||||
if (allowed_changes & SDL_AUDIO_ALLOW_SAMPLES_CHANGE) {
|
||||
obtained->samples = device->spec.samples;
|
||||
} else {
|
||||
build_stream = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_CalculateAudioSpec(obtained); /* recalc after possible changes. */
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_audiodev_c_h_
|
||||
#define SDL_audiodev_c_h_
|
||||
|
||||
#include "SDL.h"
|
||||
#include "../SDL_internal.h"
|
||||
#include "SDL_sysaudio.h"
|
||||
@@ -35,4 +39,6 @@
|
||||
|
||||
extern void SDL_EnumUnixAudioDevices(const int classic, int (*test)(int));
|
||||
|
||||
#endif /* SDL_audiodev_c_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
#include "SDL_cpuinfo.h"
|
||||
#include "SDL_assert.h"
|
||||
|
||||
#ifdef __ARM_NEON__
|
||||
/* !!! FIXME: disabled until we fix https://bugzilla.libsdl.org/show_bug.cgi?id=4186 */
|
||||
#if 0 /*def __ARM_NEON__*/
|
||||
#define HAVE_NEON_INTRINSICS 1
|
||||
#endif
|
||||
|
||||
|
||||
@@ -98,8 +98,10 @@ typedef struct SDL_AudioDriverImpl
|
||||
typedef struct SDL_AudioDeviceItem
|
||||
{
|
||||
void *handle;
|
||||
char *name;
|
||||
char *original_name;
|
||||
int dupenum;
|
||||
struct SDL_AudioDeviceItem *next;
|
||||
char name[SDL_VARIABLE_LENGTH_ARRAY];
|
||||
} SDL_AudioDeviceItem;
|
||||
|
||||
|
||||
|
||||
@@ -445,7 +445,7 @@ static void
|
||||
ALSA_CloseDevice(_THIS)
|
||||
{
|
||||
if (this->hidden->pcm_handle) {
|
||||
/* Wait for the submitted audio to drain
|
||||
/* Wait for the submitted audio to drain
|
||||
ALSA_snd_pcm_drop() can hang, so don't use that.
|
||||
*/
|
||||
Uint32 delay = ((this->spec.samples * 1000) / this->spec.freq) * 2;
|
||||
|
||||
@@ -57,7 +57,9 @@ ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
|
||||
test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
while (test_format != 0) { /* no "UNKNOWN" constant */
|
||||
if ((test_format == AUDIO_U8) || (test_format == AUDIO_S16LSB)) {
|
||||
if ((test_format == AUDIO_U8) ||
|
||||
(test_format == AUDIO_S16) ||
|
||||
(test_format == AUDIO_F32)) {
|
||||
this->spec.format = test_format;
|
||||
break;
|
||||
}
|
||||
@@ -69,25 +71,8 @@ ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
return SDL_SetError("No compatible audio format!");
|
||||
}
|
||||
|
||||
if (this->spec.channels > 1) {
|
||||
this->spec.channels = 2;
|
||||
} else {
|
||||
this->spec.channels = 1;
|
||||
}
|
||||
|
||||
if (this->spec.freq < 8000) {
|
||||
this->spec.freq = 8000;
|
||||
}
|
||||
if (this->spec.freq > 48000) {
|
||||
this->spec.freq = 48000;
|
||||
}
|
||||
|
||||
/* TODO: pass in/return a (Java) device ID */
|
||||
this->spec.samples = Android_JNI_OpenAudioDevice(iscapture, this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples);
|
||||
|
||||
if (this->spec.samples == 0) {
|
||||
/* Init failed? */
|
||||
return SDL_SetError("Java-side initialization failed!");
|
||||
if (Android_JNI_OpenAudioDevice(iscapture, &this->spec) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#include "SDL_name.h"
|
||||
#include "SDL_loadso.h"
|
||||
#else
|
||||
#define SDL_NAME(X) X
|
||||
#define SDL_NAME(X) X
|
||||
#endif
|
||||
|
||||
#ifdef SDL_AUDIO_DRIVER_ARTS_DYNAMIC
|
||||
|
||||
@@ -477,8 +477,8 @@ DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
SDL_bool tried_format = SDL_FALSE;
|
||||
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
LPGUID guid = (LPGUID) handle;
|
||||
DWORD bufsize;
|
||||
|
||||
DWORD bufsize;
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
SDL_malloc((sizeof *this->hidden));
|
||||
@@ -526,7 +526,7 @@ DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
(int) (DSBSIZE_MAX / numchunks));
|
||||
} else {
|
||||
int rc;
|
||||
WAVEFORMATEX wfmt;
|
||||
WAVEFORMATEX wfmt;
|
||||
SDL_zero(wfmt);
|
||||
if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
|
||||
wfmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
|
||||
|
||||
@@ -109,7 +109,7 @@ static pa_operation * (*PULSEAUDIO_pa_stream_drain) (pa_stream *,
|
||||
pa_stream_success_cb_t, void *);
|
||||
static int (*PULSEAUDIO_pa_stream_peek) (pa_stream *, const void **, size_t *);
|
||||
static int (*PULSEAUDIO_pa_stream_drop) (pa_stream *);
|
||||
static pa_operation * (*PULSEAUDIO_pa_stream_flush) (pa_stream *,
|
||||
static pa_operation * (*PULSEAUDIO_pa_stream_flush) (pa_stream *,
|
||||
pa_stream_success_cb_t, void *);
|
||||
static int (*PULSEAUDIO_pa_stream_disconnect) (pa_stream *);
|
||||
static void (*PULSEAUDIO_pa_stream_unref) (pa_stream *);
|
||||
|
||||
@@ -725,6 +725,12 @@ WASAPI_ThreadDeinit(_THIS)
|
||||
WASAPI_PlatformThreadDeinit(this);
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_BeginLoopIteration(_THIS)
|
||||
{
|
||||
/* no-op. */
|
||||
}
|
||||
|
||||
static void
|
||||
WASAPI_Deinitialize(void)
|
||||
{
|
||||
|
||||
@@ -351,10 +351,42 @@ WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
|
||||
}
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LPWSTR devid;
|
||||
char *devname;
|
||||
} EndpointItem;
|
||||
|
||||
static int sort_endpoints(const void *_a, const void *_b)
|
||||
{
|
||||
LPWSTR a = ((const EndpointItem *) _a)->devid;
|
||||
LPWSTR b = ((const EndpointItem *) _b)->devid;
|
||||
if (!a && b) {
|
||||
return -1;
|
||||
} else if (a && !b) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (SDL_TRUE) {
|
||||
if (*a < *b) {
|
||||
return -1;
|
||||
} else if (*a > *b) {
|
||||
return 1;
|
||||
} else if (*a == 0) {
|
||||
break;
|
||||
}
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
WASAPI_EnumerateEndpointsForFlow(const SDL_bool iscapture)
|
||||
{
|
||||
IMMDeviceCollection *collection = NULL;
|
||||
EndpointItem *items;
|
||||
UINT i, total;
|
||||
|
||||
/* Note that WASAPI separates "adapter devices" from "audio endpoint devices"
|
||||
@@ -369,22 +401,36 @@ WASAPI_EnumerateEndpointsForFlow(const SDL_bool iscapture)
|
||||
return;
|
||||
}
|
||||
|
||||
items = (EndpointItem *) SDL_calloc(total, sizeof (EndpointItem));
|
||||
if (!items) {
|
||||
return; /* oh well. */
|
||||
}
|
||||
|
||||
for (i = 0; i < total; i++) {
|
||||
EndpointItem *item = items + i;
|
||||
IMMDevice *device = NULL;
|
||||
if (SUCCEEDED(IMMDeviceCollection_Item(collection, i, &device))) {
|
||||
LPWSTR devid = NULL;
|
||||
if (SUCCEEDED(IMMDevice_GetId(device, &devid))) {
|
||||
char *devname = GetWasapiDeviceName(device);
|
||||
if (devname) {
|
||||
WASAPI_AddDevice(iscapture, devname, devid);
|
||||
SDL_free(devname);
|
||||
}
|
||||
CoTaskMemFree(devid);
|
||||
if (SUCCEEDED(IMMDevice_GetId(device, &item->devid))) {
|
||||
item->devname = GetWasapiDeviceName(device);
|
||||
}
|
||||
IMMDevice_Release(device);
|
||||
}
|
||||
}
|
||||
|
||||
/* sort the list of devices by their guid so list is consistent between runs */
|
||||
SDL_qsort(items, total, sizeof (*items), sort_endpoints);
|
||||
|
||||
/* Send the sorted list on to the SDL's higher level. */
|
||||
for (i = 0; i < total; i++) {
|
||||
EndpointItem *item = items + i;
|
||||
if ((item->devid) && (item->devname)) {
|
||||
WASAPI_AddDevice(iscapture, item->devname, item->devid);
|
||||
}
|
||||
SDL_free(item->devname);
|
||||
CoTaskMemFree(item->devid);
|
||||
}
|
||||
|
||||
SDL_free(items);
|
||||
IMMDeviceCollection_Release(collection);
|
||||
}
|
||||
|
||||
@@ -405,12 +451,6 @@ WASAPI_PlatformDeleteActivationHandler(void *handler)
|
||||
SDL_assert(!"This function should have only been called on WinRT.");
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_BeginLoopIteration(_THIS)
|
||||
{
|
||||
/* no-op. */
|
||||
}
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_WASAPI && !defined(__WINRT__) */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -185,20 +185,9 @@ struct SDL_WasapiActivationHandler : public RuntimeClass< RuntimeClassFlags< Cla
|
||||
HRESULT
|
||||
SDL_WasapiActivationHandler::ActivateCompleted(IActivateAudioInterfaceAsyncOperation *async)
|
||||
{
|
||||
HRESULT result = S_OK;
|
||||
IUnknown *iunknown = nullptr;
|
||||
const HRESULT ret = async->GetActivateResult(&result, &iunknown);
|
||||
|
||||
if (SUCCEEDED(ret) && SUCCEEDED(result)) {
|
||||
iunknown->QueryInterface(IID_PPV_ARGS(&device->hidden->client));
|
||||
if (device->hidden->client) {
|
||||
// Just set a flag, since we're probably in a different thread. We'll pick it up and init everything on our own thread to prevent races.
|
||||
SDL_AtomicSet(&device->hidden->just_activated, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Just set a flag, since we're probably in a different thread. We'll pick it up and init everything on our own thread to prevent races.
|
||||
SDL_AtomicSet(&device->hidden->just_activated, 1);
|
||||
WASAPI_UnrefDevice(device);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -236,27 +225,47 @@ WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
|
||||
IActivateAudioInterfaceAsyncOperation *async = nullptr;
|
||||
const HRESULT ret = ActivateAudioInterfaceAsync(devid, __uuidof(IAudioClient), nullptr, handler.Get(), &async);
|
||||
|
||||
if (async != nullptr) {
|
||||
async->Release();
|
||||
}
|
||||
|
||||
if (FAILED(ret)) {
|
||||
if (FAILED(ret) || async == nullptr) {
|
||||
if (async != nullptr) {
|
||||
async->Release();
|
||||
}
|
||||
handler.Get()->Release();
|
||||
WASAPI_UnrefDevice(_this);
|
||||
return WIN_SetErrorFromHRESULT("WASAPI can't activate requested audio endpoint", ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_BeginLoopIteration(_THIS)
|
||||
{
|
||||
if (SDL_AtomicCAS(&_this->hidden->just_activated, 1, 0)) {
|
||||
if (WASAPI_PrepDevice(_this, SDL_TRUE) == -1) {
|
||||
SDL_OpenedAudioDeviceDisconnected(_this);
|
||||
}
|
||||
/* Spin until the async operation is complete.
|
||||
* If we don't PrepDevice before leaving this function, the bug list gets LONG:
|
||||
* - device.spec is not filled with the correct information
|
||||
* - The 'obtained' spec will be wrong for ALLOW_CHANGE properties
|
||||
* - SDL_AudioStreams will/will not be allocated at the right time
|
||||
* - SDL_assert(device->callbackspec.size == device->spec.size) will fail
|
||||
* - When the assert is ignored, skipping or a buffer overflow will occur
|
||||
*/
|
||||
while (!SDL_AtomicCAS(&_this->hidden->just_activated, 1, 0)) {
|
||||
SDL_Delay(1);
|
||||
}
|
||||
|
||||
HRESULT activateRes = S_OK;
|
||||
IUnknown *iunknown = nullptr;
|
||||
const HRESULT getActivateRes = async->GetActivateResult(&activateRes, &iunknown);
|
||||
async->Release();
|
||||
if (FAILED(getActivateRes)) {
|
||||
return WIN_SetErrorFromHRESULT("Failed to get WASAPI activate result", getActivateRes);
|
||||
} else if (FAILED(activateRes)) {
|
||||
return WIN_SetErrorFromHRESULT("Failed to activate WASAPI device", activateRes);
|
||||
}
|
||||
|
||||
iunknown->QueryInterface(IID_PPV_ARGS(&_this->hidden->client));
|
||||
if (!_this->hidden->client) {
|
||||
return SDL_SetError("Failed to query WASAPI client interface");
|
||||
}
|
||||
|
||||
if (WASAPI_PrepDevice(_this, isrecovery) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -78,7 +78,7 @@ static void DetectWave##typ##Devs(void) { \
|
||||
capstyp##2W caps; \
|
||||
UINT i; \
|
||||
for (i = 0; i < devcount; i++) { \
|
||||
if (wave##typ##GetDevCaps(i,(LP##capstyp##W)&caps,sizeof(caps))==MMSYSERR_NOERROR) { \
|
||||
if (wave##typ##GetDevCaps(i,(LP##capstyp##W)&caps,sizeof(caps))==MMSYSERR_NOERROR) { \
|
||||
char *name = WIN_LookupAudioDeviceName(caps.szPname,&caps.NameGuid); \
|
||||
if (name != NULL) { \
|
||||
SDL_AddAudioDevice((int) iscapture, name, (void *) ((size_t) i+1)); \
|
||||
@@ -375,8 +375,7 @@ WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
#endif
|
||||
|
||||
/* Create the audio buffer semaphore */
|
||||
this->hidden->audio_sem =
|
||||
CreateSemaphore(NULL, iscapture ? 0 : NUM_BUFFERS - 1, NUM_BUFFERS, NULL);
|
||||
this->hidden->audio_sem = CreateSemaphore(NULL, iscapture ? 0 : NUM_BUFFERS - 1, NUM_BUFFERS, NULL);
|
||||
if (this->hidden->audio_sem == NULL) {
|
||||
return SDL_SetError("Couldn't create semaphore");
|
||||
}
|
||||
|
||||
@@ -61,6 +61,10 @@
|
||||
#define SDL_JAVA_CONTROLLER_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLControllerManager, function)
|
||||
#define SDL_JAVA_INTERFACE_INPUT_CONNECTION(function) CONCAT1(SDL_JAVA_PREFIX, SDLInputConnection, function)
|
||||
|
||||
/* Audio encoding definitions */
|
||||
#define ENCODING_PCM_8BIT 3
|
||||
#define ENCODING_PCM_16BIT 2
|
||||
#define ENCODING_PCM_FLOAT 4
|
||||
|
||||
/* Java class SDLActivity */
|
||||
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(
|
||||
@@ -77,7 +81,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)(
|
||||
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)(
|
||||
JNIEnv* env, jclass jcls,
|
||||
jint surfaceWidth, jint surfaceHeight,
|
||||
jint deviceWidth, jint deviceHeight, jint format, jfloat rate);
|
||||
jint deviceWidth, jint deviceHeight, jint format, jfloat rate);
|
||||
|
||||
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(
|
||||
JNIEnv* env, jclass jcls);
|
||||
@@ -144,6 +148,10 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)(
|
||||
JNIEnv* env, jclass cls,
|
||||
jstring text, jint newCursorPosition);
|
||||
|
||||
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)(
|
||||
JNIEnv* env, jclass cls,
|
||||
jchar chUnicode);
|
||||
|
||||
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)(
|
||||
JNIEnv* env, jclass cls,
|
||||
jstring text, jint newCursorPosition);
|
||||
@@ -195,6 +203,7 @@ JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)(
|
||||
/* #define DEBUG_JNI */
|
||||
|
||||
static void Android_JNI_ThreadDestroyed(void*);
|
||||
static void checkJNIReady(void);
|
||||
|
||||
/*******************************************************************************
|
||||
This file links the Java side of Android with libsdl
|
||||
@@ -243,12 +252,14 @@ static jclass mAudioManagerClass;
|
||||
|
||||
/* method signatures */
|
||||
static jmethodID midAudioOpen;
|
||||
static jmethodID midAudioWriteShortBuffer;
|
||||
static jmethodID midAudioWriteByteBuffer;
|
||||
static jmethodID midAudioWriteShortBuffer;
|
||||
static jmethodID midAudioWriteFloatBuffer;
|
||||
static jmethodID midAudioClose;
|
||||
static jmethodID midCaptureOpen;
|
||||
static jmethodID midCaptureReadShortBuffer;
|
||||
static jmethodID midCaptureReadByteBuffer;
|
||||
static jmethodID midCaptureReadShortBuffer;
|
||||
static jmethodID midCaptureReadFloatBuffer;
|
||||
static jmethodID midCaptureClose;
|
||||
|
||||
/* controller manager */
|
||||
@@ -392,24 +403,28 @@ JNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jc
|
||||
mAudioManagerClass = (jclass)((*mEnv)->NewGlobalRef(mEnv, cls));
|
||||
|
||||
midAudioOpen = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
|
||||
"audioOpen", "(IZZI)I");
|
||||
midAudioWriteShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
|
||||
"audioWriteShortBuffer", "([S)V");
|
||||
"audioOpen", "(IIII)[I");
|
||||
midAudioWriteByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
|
||||
"audioWriteByteBuffer", "([B)V");
|
||||
midAudioWriteShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
|
||||
"audioWriteShortBuffer", "([S)V");
|
||||
midAudioWriteFloatBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
|
||||
"audioWriteFloatBuffer", "([F)V");
|
||||
midAudioClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
|
||||
"audioClose", "()V");
|
||||
midCaptureOpen = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
|
||||
"captureOpen", "(IZZI)I");
|
||||
midCaptureReadShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
|
||||
"captureReadShortBuffer", "([SZ)I");
|
||||
"captureOpen", "(IIII)[I");
|
||||
midCaptureReadByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
|
||||
"captureReadByteBuffer", "([BZ)I");
|
||||
midCaptureReadShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
|
||||
"captureReadShortBuffer", "([SZ)I");
|
||||
midCaptureReadFloatBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
|
||||
"captureReadFloatBuffer", "([FZ)I");
|
||||
midCaptureClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
|
||||
"captureClose", "()V");
|
||||
|
||||
if (!midAudioOpen || !midAudioWriteShortBuffer || !midAudioWriteByteBuffer || !midAudioClose ||
|
||||
!midCaptureOpen || !midCaptureReadShortBuffer || !midCaptureReadByteBuffer || !midCaptureClose) {
|
||||
if (!midAudioOpen || !midAudioWriteByteBuffer || !midAudioWriteShortBuffer || !midAudioWriteFloatBuffer || !midAudioClose ||
|
||||
!midCaptureOpen || !midCaptureReadByteBuffer || !midCaptureReadShortBuffer || !midCaptureReadFloatBuffer || !midCaptureClose) {
|
||||
__android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLAudioManager.java?");
|
||||
}
|
||||
|
||||
@@ -430,7 +445,7 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(JNIEnv* mEn
|
||||
midPollHapticDevices = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass,
|
||||
"pollHapticDevices", "()V");
|
||||
midHapticRun = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass,
|
||||
"hapticRun", "(II)V");
|
||||
"hapticRun", "(IFI)V");
|
||||
midHapticStop = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass,
|
||||
"hapticStop", "(I)V");
|
||||
|
||||
@@ -538,7 +553,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)(
|
||||
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)(
|
||||
JNIEnv* env, jclass jcls,
|
||||
jint surfaceWidth, jint surfaceHeight,
|
||||
jint deviceWidth, jint deviceHeight, jint format, jfloat rate)
|
||||
jint deviceWidth, jint deviceHeight, jint format, jfloat rate)
|
||||
{
|
||||
Android_SetScreenResolution(surfaceWidth, surfaceHeight, deviceWidth, deviceHeight, format, rate);
|
||||
}
|
||||
@@ -1039,17 +1054,19 @@ int Android_JNI_SetupThread(void)
|
||||
/*
|
||||
* Audio support
|
||||
*/
|
||||
static jboolean audioBuffer16Bit = JNI_FALSE;
|
||||
static int audioBufferFormat = 0;
|
||||
static jobject audioBuffer = NULL;
|
||||
static void* audioBufferPinned = NULL;
|
||||
static jboolean captureBuffer16Bit = JNI_FALSE;
|
||||
static int captureBufferFormat = 0;
|
||||
static jobject captureBuffer = NULL;
|
||||
|
||||
int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames)
|
||||
int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec)
|
||||
{
|
||||
jboolean audioBufferStereo;
|
||||
int audioBufferFrames;
|
||||
int audioformat;
|
||||
int numBufferFrames;
|
||||
jobject jbufobj = NULL;
|
||||
jobject result;
|
||||
int *resultElements;
|
||||
jboolean isCopy;
|
||||
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
@@ -1059,74 +1076,123 @@ int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int
|
||||
}
|
||||
Android_JNI_SetupThread();
|
||||
|
||||
audioBufferStereo = channelCount > 1;
|
||||
switch (spec->format) {
|
||||
case AUDIO_U8:
|
||||
audioformat = ENCODING_PCM_8BIT;
|
||||
break;
|
||||
case AUDIO_S16:
|
||||
audioformat = ENCODING_PCM_16BIT;
|
||||
break;
|
||||
case AUDIO_F32:
|
||||
audioformat = ENCODING_PCM_FLOAT;
|
||||
break;
|
||||
default:
|
||||
return SDL_SetError("Unsupported audio format: 0x%x", spec->format);
|
||||
}
|
||||
|
||||
if (iscapture) {
|
||||
__android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for capture");
|
||||
captureBuffer16Bit = is16Bit;
|
||||
if ((*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureOpen, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) {
|
||||
/* Error during audio initialization */
|
||||
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: error on AudioRecord initialization!");
|
||||
return 0;
|
||||
}
|
||||
result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midCaptureOpen, spec->freq, audioformat, spec->channels, spec->samples);
|
||||
} else {
|
||||
__android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for output");
|
||||
audioBuffer16Bit = is16Bit;
|
||||
if ((*env)->CallStaticIntMethod(env, mAudioManagerClass, midAudioOpen, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) {
|
||||
/* Error during audio initialization */
|
||||
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: error on AudioTrack initialization!");
|
||||
return 0;
|
||||
}
|
||||
result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midAudioOpen, spec->freq, audioformat, spec->channels, spec->samples);
|
||||
}
|
||||
if (result == NULL) {
|
||||
/* Error during audio initialization, error printed from Java */
|
||||
return SDL_SetError("Java-side initialization failed");
|
||||
}
|
||||
|
||||
if ((*env)->GetArrayLength(env, (jintArray)result) != 4) {
|
||||
return SDL_SetError("Unexpected results from Java, expected 4, got %d", (*env)->GetArrayLength(env, (jintArray)result));
|
||||
}
|
||||
isCopy = JNI_FALSE;
|
||||
resultElements = (*env)->GetIntArrayElements(env, (jintArray)result, &isCopy);
|
||||
spec->freq = resultElements[0];
|
||||
audioformat = resultElements[1];
|
||||
switch (audioformat) {
|
||||
case ENCODING_PCM_8BIT:
|
||||
spec->format = AUDIO_U8;
|
||||
break;
|
||||
case ENCODING_PCM_16BIT:
|
||||
spec->format = AUDIO_S16;
|
||||
break;
|
||||
case ENCODING_PCM_FLOAT:
|
||||
spec->format = AUDIO_F32;
|
||||
break;
|
||||
default:
|
||||
return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat);
|
||||
}
|
||||
spec->channels = resultElements[2];
|
||||
spec->samples = resultElements[3];
|
||||
(*env)->ReleaseIntArrayElements(env, (jintArray)result, resultElements, JNI_ABORT);
|
||||
(*env)->DeleteLocalRef(env, result);
|
||||
|
||||
/* Allocating the audio buffer from the Java side and passing it as the return value for audioInit no longer works on
|
||||
* Android >= 4.2 due to a "stale global reference" error. So now we allocate this buffer directly from this side. */
|
||||
|
||||
if (is16Bit) {
|
||||
jshortArray audioBufferLocal = (*env)->NewShortArray(env, desiredBufferFrames * (audioBufferStereo ? 2 : 1));
|
||||
if (audioBufferLocal) {
|
||||
jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
|
||||
(*env)->DeleteLocalRef(env, audioBufferLocal);
|
||||
switch (audioformat) {
|
||||
case ENCODING_PCM_8BIT:
|
||||
{
|
||||
jbyteArray audioBufferLocal = (*env)->NewByteArray(env, spec->samples * spec->channels);
|
||||
if (audioBufferLocal) {
|
||||
jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
|
||||
(*env)->DeleteLocalRef(env, audioBufferLocal);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
jbyteArray audioBufferLocal = (*env)->NewByteArray(env, desiredBufferFrames * (audioBufferStereo ? 2 : 1));
|
||||
if (audioBufferLocal) {
|
||||
jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
|
||||
(*env)->DeleteLocalRef(env, audioBufferLocal);
|
||||
break;
|
||||
case ENCODING_PCM_16BIT:
|
||||
{
|
||||
jshortArray audioBufferLocal = (*env)->NewShortArray(env, spec->samples * spec->channels);
|
||||
if (audioBufferLocal) {
|
||||
jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
|
||||
(*env)->DeleteLocalRef(env, audioBufferLocal);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ENCODING_PCM_FLOAT:
|
||||
{
|
||||
jfloatArray audioBufferLocal = (*env)->NewFloatArray(env, spec->samples * spec->channels);
|
||||
if (audioBufferLocal) {
|
||||
jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
|
||||
(*env)->DeleteLocalRef(env, audioBufferLocal);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat);
|
||||
}
|
||||
|
||||
if (jbufobj == NULL) {
|
||||
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: could not allocate an audio buffer!");
|
||||
return 0;
|
||||
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: could not allocate an audio buffer");
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
if (iscapture) {
|
||||
captureBufferFormat = audioformat;
|
||||
captureBuffer = jbufobj;
|
||||
} else {
|
||||
audioBufferFormat = audioformat;
|
||||
audioBuffer = jbufobj;
|
||||
}
|
||||
numBufferFrames = (*env)->GetArrayLength(env, (jarray)jbufobj);
|
||||
|
||||
isCopy = JNI_FALSE;
|
||||
if (!iscapture) {
|
||||
isCopy = JNI_FALSE;
|
||||
|
||||
if (is16Bit) {
|
||||
if (!iscapture) {
|
||||
audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy);
|
||||
}
|
||||
audioBufferFrames = (*env)->GetArrayLength(env, (jshortArray)audioBuffer);
|
||||
} else {
|
||||
if (!iscapture) {
|
||||
switch (audioformat) {
|
||||
case ENCODING_PCM_8BIT:
|
||||
audioBufferPinned = (*env)->GetByteArrayElements(env, (jbyteArray)audioBuffer, &isCopy);
|
||||
break;
|
||||
case ENCODING_PCM_16BIT:
|
||||
audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy);
|
||||
break;
|
||||
case ENCODING_PCM_FLOAT:
|
||||
audioBufferPinned = (*env)->GetFloatArrayElements(env, (jfloatArray)audioBuffer, &isCopy);
|
||||
break;
|
||||
default:
|
||||
return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat);
|
||||
}
|
||||
audioBufferFrames = (*env)->GetArrayLength(env, (jbyteArray)audioBuffer);
|
||||
}
|
||||
|
||||
if (audioBufferStereo) {
|
||||
audioBufferFrames /= 2;
|
||||
}
|
||||
|
||||
return audioBufferFrames;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi)
|
||||
@@ -1170,12 +1236,22 @@ void Android_JNI_WriteAudioBuffer(void)
|
||||
{
|
||||
JNIEnv *mAudioEnv = Android_JNI_GetEnv();
|
||||
|
||||
if (audioBuffer16Bit) {
|
||||
(*mAudioEnv)->ReleaseShortArrayElements(mAudioEnv, (jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT);
|
||||
(*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer);
|
||||
} else {
|
||||
switch (audioBufferFormat) {
|
||||
case ENCODING_PCM_8BIT:
|
||||
(*mAudioEnv)->ReleaseByteArrayElements(mAudioEnv, (jbyteArray)audioBuffer, (jbyte *)audioBufferPinned, JNI_COMMIT);
|
||||
(*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteByteBuffer, (jbyteArray)audioBuffer);
|
||||
break;
|
||||
case ENCODING_PCM_16BIT:
|
||||
(*mAudioEnv)->ReleaseShortArrayElements(mAudioEnv, (jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT);
|
||||
(*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer);
|
||||
break;
|
||||
case ENCODING_PCM_FLOAT:
|
||||
(*mAudioEnv)->ReleaseFloatArrayElements(mAudioEnv, (jfloatArray)audioBuffer, (jfloat *)audioBufferPinned, JNI_COMMIT);
|
||||
(*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteFloatBuffer, (jfloatArray)audioBuffer);
|
||||
break;
|
||||
default:
|
||||
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: unhandled audio buffer format");
|
||||
break;
|
||||
}
|
||||
|
||||
/* JNI_COMMIT means the changes are committed to the VM but the buffer remains pinned */
|
||||
@@ -1187,16 +1263,8 @@ int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen)
|
||||
jboolean isCopy = JNI_FALSE;
|
||||
jint br;
|
||||
|
||||
if (captureBuffer16Bit) {
|
||||
SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == (buflen / 2));
|
||||
br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_TRUE);
|
||||
if (br > 0) {
|
||||
jshort *ptr = (*env)->GetShortArrayElements(env, (jshortArray)captureBuffer, &isCopy);
|
||||
br *= 2;
|
||||
SDL_memcpy(buffer, ptr, br);
|
||||
(*env)->ReleaseShortArrayElements(env, (jshortArray)captureBuffer, (jshort *)ptr, JNI_ABORT);
|
||||
}
|
||||
} else {
|
||||
switch (captureBufferFormat) {
|
||||
case ENCODING_PCM_8BIT:
|
||||
SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == buflen);
|
||||
br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_TRUE);
|
||||
if (br > 0) {
|
||||
@@ -1204,27 +1272,75 @@ int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen)
|
||||
SDL_memcpy(buffer, ptr, br);
|
||||
(*env)->ReleaseByteArrayElements(env, (jbyteArray)captureBuffer, (jbyte *)ptr, JNI_ABORT);
|
||||
}
|
||||
break;
|
||||
case ENCODING_PCM_16BIT:
|
||||
SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == (buflen / sizeof(Sint16)));
|
||||
br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_TRUE);
|
||||
if (br > 0) {
|
||||
jshort *ptr = (*env)->GetShortArrayElements(env, (jshortArray)captureBuffer, &isCopy);
|
||||
br *= sizeof(Sint16);
|
||||
SDL_memcpy(buffer, ptr, br);
|
||||
(*env)->ReleaseShortArrayElements(env, (jshortArray)captureBuffer, (jshort *)ptr, JNI_ABORT);
|
||||
}
|
||||
break;
|
||||
case ENCODING_PCM_FLOAT:
|
||||
SDL_assert((*env)->GetArrayLength(env, (jfloatArray)captureBuffer) == (buflen / sizeof(float)));
|
||||
br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_TRUE);
|
||||
if (br > 0) {
|
||||
jfloat *ptr = (*env)->GetFloatArrayElements(env, (jfloatArray)captureBuffer, &isCopy);
|
||||
br *= sizeof(float);
|
||||
SDL_memcpy(buffer, ptr, br);
|
||||
(*env)->ReleaseFloatArrayElements(env, (jfloatArray)captureBuffer, (jfloat *)ptr, JNI_ABORT);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: unhandled capture buffer format");
|
||||
break;
|
||||
}
|
||||
|
||||
return (int) br;
|
||||
return br;
|
||||
}
|
||||
|
||||
void Android_JNI_FlushCapturedAudio(void)
|
||||
{
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
#if 0 /* !!! FIXME: this needs API 23, or it'll do blocking reads and never end. */
|
||||
if (captureBuffer16Bit) {
|
||||
const jint len = (*env)->GetArrayLength(env, (jshortArray)captureBuffer);
|
||||
while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE) == len) { /* spin */ }
|
||||
} else {
|
||||
const jint len = (*env)->GetArrayLength(env, (jbyteArray)captureBuffer);
|
||||
while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE) == len) { /* spin */ }
|
||||
switch (captureBufferFormat) {
|
||||
case ENCODING_PCM_8BIT:
|
||||
{
|
||||
const jint len = (*env)->GetArrayLength(env, (jbyteArray)captureBuffer);
|
||||
while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE) == len) { /* spin */ }
|
||||
}
|
||||
break;
|
||||
case ENCODING_PCM_16BIT:
|
||||
{
|
||||
const jint len = (*env)->GetArrayLength(env, (jshortArray)captureBuffer);
|
||||
while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE) == len) { /* spin */ }
|
||||
}
|
||||
break;
|
||||
case ENCODING_PCM_FLOAT:
|
||||
{
|
||||
const jint len = (*env)->GetArrayLength(env, (jfloatArray)captureBuffer);
|
||||
while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE) == len) { /* spin */ }
|
||||
}
|
||||
break;
|
||||
default:
|
||||
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: flushing unhandled capture buffer format");
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if (captureBuffer16Bit) {
|
||||
(*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE);
|
||||
} else {
|
||||
switch (captureBufferFormat) {
|
||||
case ENCODING_PCM_8BIT:
|
||||
(*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE);
|
||||
break;
|
||||
case ENCODING_PCM_16BIT:
|
||||
(*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE);
|
||||
break;
|
||||
case ENCODING_PCM_FLOAT:
|
||||
(*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE);
|
||||
break;
|
||||
default:
|
||||
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: flushing unhandled capture buffer format");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1890,10 +2006,10 @@ void Android_JNI_PollHapticDevices(void)
|
||||
(*env)->CallStaticVoidMethod(env, mControllerManagerClass, midPollHapticDevices);
|
||||
}
|
||||
|
||||
void Android_JNI_HapticRun(int device_id, int length)
|
||||
void Android_JNI_HapticRun(int device_id, float intensity, int length)
|
||||
{
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
(*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticRun, device_id, length);
|
||||
(*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticRun, device_id, intensity, length);
|
||||
}
|
||||
|
||||
void Android_JNI_HapticStop(int device_id)
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
#include "SDL_system.h"
|
||||
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
@@ -30,6 +31,7 @@ extern "C" {
|
||||
#include <EGL/eglplatform.h>
|
||||
#include <android/native_window_jni.h>
|
||||
|
||||
#include "SDL_audio.h"
|
||||
#include "SDL_rect.h"
|
||||
|
||||
/* Interface from the SDL library into the Android Java activity */
|
||||
@@ -46,13 +48,17 @@ extern ANativeWindow* Android_JNI_GetNativeWindow(void);
|
||||
extern int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi);
|
||||
|
||||
/* Audio support */
|
||||
extern int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames);
|
||||
extern int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec);
|
||||
extern void* Android_JNI_GetAudioBuffer(void);
|
||||
extern void Android_JNI_WriteAudioBuffer(void);
|
||||
extern int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen);
|
||||
extern void Android_JNI_FlushCapturedAudio(void);
|
||||
extern void Android_JNI_CloseAudioDevice(const int iscapture);
|
||||
|
||||
/* Detecting device type */
|
||||
extern SDL_bool Android_IsDeXMode();
|
||||
extern SDL_bool Android_IsChromebook();
|
||||
|
||||
#include "SDL_rwops.h"
|
||||
|
||||
int Android_JNI_FileOpen(SDL_RWops* ctx, const char* fileName, const char* mode);
|
||||
@@ -78,15 +84,16 @@ void Android_JNI_PollInputDevices(void);
|
||||
|
||||
/* Haptic support */
|
||||
void Android_JNI_PollHapticDevices(void);
|
||||
void Android_JNI_HapticRun(int device_id, int length);
|
||||
void Android_JNI_HapticRun(int device_id, float intensity, int length);
|
||||
void Android_JNI_HapticStop(int device_id);
|
||||
|
||||
/* Video */
|
||||
void Android_JNI_SuspendScreenSaver(SDL_bool suspend);
|
||||
|
||||
/* Touch support */
|
||||
int Android_JNI_GetTouchDeviceIds(int **ids);
|
||||
int Android_JNI_InitTouch(void);
|
||||
void Android_JNI_SetSeparateMouseAndTouch(SDL_bool new_value);
|
||||
int Android_JNI_GetTouchDeviceIds(int **ids);
|
||||
|
||||
/* Threads */
|
||||
#include <jni.h>
|
||||
@@ -109,9 +116,15 @@ SDL_bool Android_JNI_SetCustomCursor(int cursorID);
|
||||
SDL_bool Android_JNI_SetSystemCursor(int cursorID);
|
||||
|
||||
/* Relative mouse support */
|
||||
SDL_bool Android_JNI_SupportsRelativeMouse();
|
||||
SDL_bool Android_JNI_SupportsRelativeMouse(void);
|
||||
SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled);
|
||||
|
||||
|
||||
SDL_bool SDL_IsAndroidTablet(void);
|
||||
SDL_bool SDL_IsAndroidTV(void);
|
||||
SDL_bool SDL_IsChromebook(void);
|
||||
SDL_bool SDL_IsDeXMode(void);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
@@ -39,9 +39,8 @@ typedef struct SDL_DBusContext {
|
||||
void (*bus_add_match)(DBusConnection *, const char *, DBusError *);
|
||||
DBusConnection * (*connection_open_private)(const char *, DBusError *);
|
||||
void (*connection_set_exit_on_disconnect)(DBusConnection *, dbus_bool_t);
|
||||
dbus_bool_t (*connection_get_is_connected)(DBusConnection *);
|
||||
dbus_bool_t (*connection_add_filter)(DBusConnection *, DBusHandleMessageFunction,
|
||||
void *, DBusFreeFunction);
|
||||
dbus_bool_t (*connection_get_is_connected)(DBusConnection *);
|
||||
dbus_bool_t (*connection_add_filter)(DBusConnection *, DBusHandleMessageFunction, void *, DBusFreeFunction);
|
||||
dbus_bool_t (*connection_try_register_object_path)(DBusConnection *, const char *,
|
||||
const DBusObjectPathVTable *, void *, DBusError *);
|
||||
dbus_bool_t (*connection_send)(DBusConnection *, DBusMessage *, dbus_uint32_t *);
|
||||
@@ -51,7 +50,7 @@ typedef struct SDL_DBusContext {
|
||||
void (*connection_flush)(DBusConnection *);
|
||||
dbus_bool_t (*connection_read_write)(DBusConnection *, int);
|
||||
DBusDispatchStatus (*connection_dispatch)(DBusConnection *);
|
||||
dbus_bool_t (*message_is_signal)(DBusMessage *, const char *, const char *);
|
||||
dbus_bool_t (*message_is_signal)(DBusMessage *, const char *, const char *);
|
||||
DBusMessage *(*message_new_method_call)(const char *, const char *, const char *, const char *);
|
||||
dbus_bool_t (*message_append_args)(DBusMessage *, int, ...);
|
||||
dbus_bool_t (*message_append_args_valist)(DBusMessage *, int, va_list);
|
||||
@@ -61,7 +60,7 @@ typedef struct SDL_DBusContext {
|
||||
dbus_bool_t (*message_iter_next)(DBusMessageIter *);
|
||||
void (*message_iter_get_basic)(DBusMessageIter *, void *);
|
||||
int (*message_iter_get_arg_type)(DBusMessageIter *);
|
||||
void (*message_iter_recurse)(DBusMessageIter *, DBusMessageIter *);
|
||||
void (*message_iter_recurse)(DBusMessageIter *, DBusMessageIter *);
|
||||
void (*message_unref)(DBusMessage *);
|
||||
void (*error_init)(DBusError *);
|
||||
dbus_bool_t (*error_is_set)(const DBusError *);
|
||||
|
||||
@@ -198,7 +198,7 @@ static SDL_EVDEV_keyboard_state * kbd_cleanup_state = NULL;
|
||||
static int kbd_cleanup_sigactions_installed = 0;
|
||||
static int kbd_cleanup_atexit_installed = 0;
|
||||
|
||||
static struct sigaction old_sigaction[NSIG] = { 0 };
|
||||
static struct sigaction old_sigaction[NSIG];
|
||||
|
||||
static int fatal_signals[] =
|
||||
{
|
||||
@@ -510,17 +510,19 @@ static unsigned int handle_diacr(SDL_EVDEV_keyboard_state *kbd, unsigned int ch)
|
||||
|
||||
static int vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag)
|
||||
{
|
||||
return ((kbd->ledflagstate >> flag) & 1);
|
||||
return (kbd->ledflagstate & flag) != 0;
|
||||
}
|
||||
|
||||
static void set_vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag)
|
||||
{
|
||||
kbd->ledflagstate |= 1 << flag;
|
||||
kbd->ledflagstate |= flag;
|
||||
ioctl(kbd->console_fd, KDSETLED, (unsigned long)(kbd->ledflagstate));
|
||||
}
|
||||
|
||||
static void clr_vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag)
|
||||
{
|
||||
kbd->ledflagstate &= ~(1 << flag);
|
||||
kbd->ledflagstate &= ~flag;
|
||||
ioctl(kbd->console_fd, KDSETLED, (unsigned long)(kbd->ledflagstate));
|
||||
}
|
||||
|
||||
static void chg_vc_kbd_lock(SDL_EVDEV_keyboard_state *kbd, int flag)
|
||||
@@ -535,7 +537,8 @@ static void chg_vc_kbd_slock(SDL_EVDEV_keyboard_state *kbd, int flag)
|
||||
|
||||
static void chg_vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag)
|
||||
{
|
||||
kbd->ledflagstate ^= 1 << flag;
|
||||
kbd->ledflagstate ^= flag;
|
||||
ioctl(kbd->console_fd, KDSETLED, (unsigned long)(kbd->ledflagstate));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_evdev_kbd_h_
|
||||
#define SDL_evdev_kbd_h_
|
||||
|
||||
struct SDL_EVDEV_keyboard_state;
|
||||
typedef struct SDL_EVDEV_keyboard_state SDL_EVDEV_keyboard_state;
|
||||
|
||||
@@ -26,4 +29,6 @@ extern SDL_EVDEV_keyboard_state *SDL_EVDEV_kbd_init(void);
|
||||
extern void SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *state, unsigned int keycode, int down);
|
||||
extern void SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *state);
|
||||
|
||||
#endif /* SDL_evdev_kbd_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -63,7 +63,7 @@ SDL_UDEV_load_syms(void)
|
||||
{
|
||||
/* cast funcs to char* first, to please GCC's strict aliasing rules. */
|
||||
#define SDL_UDEV_SYM(x) \
|
||||
if (!SDL_UDEV_load_sym(#x, (void **) (char *) & _this->x)) return -1
|
||||
if (!SDL_UDEV_load_sym(#x, (void **) (char *) & _this->syms.x)) return -1
|
||||
|
||||
SDL_UDEV_SYM(udev_device_get_action);
|
||||
SDL_UDEV_SYM(udev_device_get_devnode);
|
||||
@@ -100,7 +100,7 @@ static SDL_bool
|
||||
SDL_UDEV_hotplug_update_available(void)
|
||||
{
|
||||
if (_this->udev_mon != NULL) {
|
||||
const int fd = _this->udev_monitor_get_fd(_this->udev_mon);
|
||||
const int fd = _this->syms.udev_monitor_get_fd(_this->udev_mon);
|
||||
if (SDL_IOReady(fd, SDL_FALSE, 0)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
@@ -130,21 +130,21 @@ SDL_UDEV_Init(void)
|
||||
* Listen for input devices (mouse, keyboard, joystick, etc) and sound devices
|
||||
*/
|
||||
|
||||
_this->udev = _this->udev_new();
|
||||
_this->udev = _this->syms.udev_new();
|
||||
if (_this->udev == NULL) {
|
||||
SDL_UDEV_Quit();
|
||||
return SDL_SetError("udev_new() failed");
|
||||
}
|
||||
|
||||
_this->udev_mon = _this->udev_monitor_new_from_netlink(_this->udev, "udev");
|
||||
_this->udev_mon = _this->syms.udev_monitor_new_from_netlink(_this->udev, "udev");
|
||||
if (_this->udev_mon == NULL) {
|
||||
SDL_UDEV_Quit();
|
||||
return SDL_SetError("udev_monitor_new_from_netlink() failed");
|
||||
}
|
||||
|
||||
_this->udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "input", NULL);
|
||||
_this->udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "sound", NULL);
|
||||
_this->udev_monitor_enable_receiving(_this->udev_mon);
|
||||
_this->syms.udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "input", NULL);
|
||||
_this->syms.udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "sound", NULL);
|
||||
_this->syms.udev_monitor_enable_receiving(_this->udev_mon);
|
||||
|
||||
/* Do an initial scan of existing devices */
|
||||
SDL_UDEV_Scan();
|
||||
@@ -170,11 +170,11 @@ SDL_UDEV_Quit(void)
|
||||
if (_this->ref_count < 1) {
|
||||
|
||||
if (_this->udev_mon != NULL) {
|
||||
_this->udev_monitor_unref(_this->udev_mon);
|
||||
_this->syms.udev_monitor_unref(_this->udev_mon);
|
||||
_this->udev_mon = NULL;
|
||||
}
|
||||
if (_this->udev != NULL) {
|
||||
_this->udev_unref(_this->udev);
|
||||
_this->syms.udev_unref(_this->udev);
|
||||
_this->udev = NULL;
|
||||
}
|
||||
|
||||
@@ -202,28 +202,28 @@ SDL_UDEV_Scan(void)
|
||||
return;
|
||||
}
|
||||
|
||||
enumerate = _this->udev_enumerate_new(_this->udev);
|
||||
enumerate = _this->syms.udev_enumerate_new(_this->udev);
|
||||
if (enumerate == NULL) {
|
||||
SDL_UDEV_Quit();
|
||||
SDL_SetError("udev_enumerate_new() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
_this->udev_enumerate_add_match_subsystem(enumerate, "input");
|
||||
_this->udev_enumerate_add_match_subsystem(enumerate, "sound");
|
||||
_this->syms.udev_enumerate_add_match_subsystem(enumerate, "input");
|
||||
_this->syms.udev_enumerate_add_match_subsystem(enumerate, "sound");
|
||||
|
||||
_this->udev_enumerate_scan_devices(enumerate);
|
||||
devs = _this->udev_enumerate_get_list_entry(enumerate);
|
||||
for (item = devs; item; item = _this->udev_list_entry_get_next(item)) {
|
||||
const char *path = _this->udev_list_entry_get_name(item);
|
||||
struct udev_device *dev = _this->udev_device_new_from_syspath(_this->udev, path);
|
||||
_this->syms.udev_enumerate_scan_devices(enumerate);
|
||||
devs = _this->syms.udev_enumerate_get_list_entry(enumerate);
|
||||
for (item = devs; item; item = _this->syms.udev_list_entry_get_next(item)) {
|
||||
const char *path = _this->syms.udev_list_entry_get_name(item);
|
||||
struct udev_device *dev = _this->syms.udev_device_new_from_syspath(_this->udev, path);
|
||||
if (dev != NULL) {
|
||||
device_event(SDL_UDEV_DEVICEADDED, dev);
|
||||
_this->udev_device_unref(dev);
|
||||
_this->syms.udev_device_unref(dev);
|
||||
}
|
||||
}
|
||||
|
||||
_this->udev_enumerate_unref(enumerate);
|
||||
_this->syms.udev_enumerate_unref(enumerate);
|
||||
}
|
||||
|
||||
|
||||
@@ -305,7 +305,7 @@ static void get_caps(struct udev_device *dev, struct udev_device *pdev, const ch
|
||||
unsigned long v;
|
||||
|
||||
SDL_memset(bitmask, 0, bitmask_len*sizeof(*bitmask));
|
||||
value = _this->udev_device_get_sysattr_value(pdev, attr);
|
||||
value = _this->syms.udev_device_get_sysattr_value(pdev, attr);
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
@@ -340,8 +340,8 @@ guess_device_class(struct udev_device *dev)
|
||||
/* walk up the parental chain until we find the real input device; the
|
||||
* argument is very likely a subdevice of this, like eventN */
|
||||
pdev = dev;
|
||||
while (pdev && !_this->udev_device_get_sysattr_value(pdev, "capabilities/ev")) {
|
||||
pdev = _this->udev_device_get_parent_with_subsystem_devtype(pdev, "input", NULL);
|
||||
while (pdev && !_this->syms.udev_device_get_sysattr_value(pdev, "capabilities/ev")) {
|
||||
pdev = _this->syms.udev_device_get_parent_with_subsystem_devtype(pdev, "input", NULL);
|
||||
}
|
||||
if (!pdev) {
|
||||
return 0;
|
||||
@@ -405,28 +405,28 @@ device_event(SDL_UDEV_deviceevent type, struct udev_device *dev)
|
||||
const char *path;
|
||||
SDL_UDEV_CallbackList *item;
|
||||
|
||||
path = _this->udev_device_get_devnode(dev);
|
||||
path = _this->syms.udev_device_get_devnode(dev);
|
||||
if (path == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
subsystem = _this->udev_device_get_subsystem(dev);
|
||||
subsystem = _this->syms.udev_device_get_subsystem(dev);
|
||||
if (SDL_strcmp(subsystem, "sound") == 0) {
|
||||
devclass = SDL_UDEV_DEVICE_SOUND;
|
||||
} else if (SDL_strcmp(subsystem, "input") == 0) {
|
||||
/* udev rules reference: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c */
|
||||
|
||||
val = _this->udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK");
|
||||
val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK");
|
||||
if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
|
||||
devclass |= SDL_UDEV_DEVICE_JOYSTICK;
|
||||
}
|
||||
|
||||
val = _this->udev_device_get_property_value(dev, "ID_INPUT_MOUSE");
|
||||
val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_MOUSE");
|
||||
if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
|
||||
devclass |= SDL_UDEV_DEVICE_MOUSE;
|
||||
}
|
||||
|
||||
val = _this->udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN");
|
||||
val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN");
|
||||
if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
|
||||
devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN;
|
||||
}
|
||||
@@ -437,14 +437,14 @@ device_event(SDL_UDEV_deviceevent type, struct udev_device *dev)
|
||||
|
||||
Ref: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c#n183
|
||||
*/
|
||||
val = _this->udev_device_get_property_value(dev, "ID_INPUT_KEY");
|
||||
val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_KEY");
|
||||
if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
|
||||
devclass |= SDL_UDEV_DEVICE_KEYBOARD;
|
||||
}
|
||||
|
||||
if (devclass == 0) {
|
||||
/* Fall back to old style input classes */
|
||||
val = _this->udev_device_get_property_value(dev, "ID_CLASS");
|
||||
val = _this->syms.udev_device_get_property_value(dev, "ID_CLASS");
|
||||
if (val != NULL) {
|
||||
if (SDL_strcmp(val, "joystick") == 0) {
|
||||
devclass = SDL_UDEV_DEVICE_JOYSTICK;
|
||||
@@ -481,11 +481,11 @@ SDL_UDEV_Poll(void)
|
||||
}
|
||||
|
||||
while (SDL_UDEV_hotplug_update_available()) {
|
||||
dev = _this->udev_monitor_receive_device(_this->udev_mon);
|
||||
dev = _this->syms.udev_monitor_receive_device(_this->udev_mon);
|
||||
if (dev == NULL) {
|
||||
break;
|
||||
}
|
||||
action = _this->udev_device_get_action(dev);
|
||||
action = _this->syms.udev_device_get_action(dev);
|
||||
|
||||
if (SDL_strcmp(action, "add") == 0) {
|
||||
/* Wait for the device to finish initialization */
|
||||
@@ -496,7 +496,7 @@ SDL_UDEV_Poll(void)
|
||||
device_event(SDL_UDEV_DEVICEREMOVED, dev);
|
||||
}
|
||||
|
||||
_this->udev_device_unref(dev);
|
||||
_this->syms.udev_device_unref(dev);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,6 +547,22 @@ SDL_UDEV_DelCallback(SDL_UDEV_Callback cb)
|
||||
|
||||
}
|
||||
|
||||
const SDL_UDEV_Symbols *
|
||||
SDL_UDEV_GetUdevSyms(void)
|
||||
{
|
||||
if (SDL_UDEV_Init() < 0) {
|
||||
SDL_SetError("Could not initialize UDEV");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &_this->syms;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_UDEV_ReleaseUdevSyms(void)
|
||||
{
|
||||
SDL_UDEV_Quit();
|
||||
}
|
||||
|
||||
#endif /* SDL_USE_LIBUDEV */
|
||||
|
||||
|
||||
@@ -64,22 +64,13 @@ typedef struct SDL_UDEV_CallbackList {
|
||||
struct SDL_UDEV_CallbackList *next;
|
||||
} SDL_UDEV_CallbackList;
|
||||
|
||||
typedef struct SDL_UDEV_PrivateData
|
||||
{
|
||||
const char *udev_library;
|
||||
void *udev_handle;
|
||||
struct udev *udev;
|
||||
struct udev_monitor *udev_mon;
|
||||
int ref_count;
|
||||
SDL_UDEV_CallbackList *first, *last;
|
||||
|
||||
/* Function pointers */
|
||||
typedef struct SDL_UDEV_Symbols {
|
||||
const char *(*udev_device_get_action)(struct udev_device *);
|
||||
const char *(*udev_device_get_devnode)(struct udev_device *);
|
||||
const char *(*udev_device_get_subsystem)(struct udev_device *);
|
||||
struct udev_device *(*udev_device_get_parent_with_subsystem_devtype)(struct udev_device *udev_device, const char *subsystem, const char *devtype);
|
||||
struct udev_device *(*udev_device_get_parent_with_subsystem_devtype)(struct udev_device *udev_device, const char *subsystem, const char *devtype);
|
||||
const char *(*udev_device_get_property_value)(struct udev_device *, const char *);
|
||||
const char *(*udev_device_get_sysattr_value)(struct udev_device *udev_device, const char *sysattr);
|
||||
const char *(*udev_device_get_sysattr_value)(struct udev_device *udev_device, const char *sysattr);
|
||||
struct udev_device *(*udev_device_new_from_syspath)(struct udev *, const char *);
|
||||
void (*udev_device_unref)(struct udev_device *);
|
||||
int (*udev_enumerate_add_match_property)(struct udev_enumerate *, const char *, const char *);
|
||||
@@ -100,6 +91,19 @@ typedef struct SDL_UDEV_PrivateData
|
||||
void (*udev_unref)(struct udev *);
|
||||
struct udev_device * (*udev_device_new_from_devnum)(struct udev *udev, char type, dev_t devnum);
|
||||
dev_t (*udev_device_get_devnum) (struct udev_device *udev_device);
|
||||
} SDL_UDEV_Symbols;
|
||||
|
||||
typedef struct SDL_UDEV_PrivateData
|
||||
{
|
||||
const char *udev_library;
|
||||
void *udev_handle;
|
||||
struct udev *udev;
|
||||
struct udev_monitor *udev_mon;
|
||||
int ref_count;
|
||||
SDL_UDEV_CallbackList *first, *last;
|
||||
|
||||
/* Function pointers */
|
||||
SDL_UDEV_Symbols syms;
|
||||
} SDL_UDEV_PrivateData;
|
||||
|
||||
extern int SDL_UDEV_Init(void);
|
||||
@@ -110,8 +114,8 @@ extern void SDL_UDEV_Poll(void);
|
||||
extern void SDL_UDEV_Scan(void);
|
||||
extern int SDL_UDEV_AddCallback(SDL_UDEV_Callback cb);
|
||||
extern void SDL_UDEV_DelCallback(SDL_UDEV_Callback cb);
|
||||
|
||||
|
||||
extern const SDL_UDEV_Symbols *SDL_UDEV_GetUdevSyms(void);
|
||||
extern void SDL_UDEV_ReleaseUdevSyms(void);
|
||||
|
||||
|
||||
#endif /* HAVE_LIBUDEV_H */
|
||||
|
||||
@@ -44,7 +44,7 @@ SDL_bool WINRT_XAMLWasEnabled = SDL_FALSE;
|
||||
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
|
||||
extern "C"
|
||||
ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative = NULL;
|
||||
static Windows::Foundation::EventRegistrationToken WINRT_XAMLAppEventToken;
|
||||
static Windows::Foundation::EventRegistrationToken WINRT_XAMLAppEventToken;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "SDL_config.h"
|
||||
#else
|
||||
#include "../SDL_internal.h"
|
||||
#include "SDL_simd.h"
|
||||
#endif
|
||||
|
||||
#if defined(__WIN32__)
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#if defined(__OS2__)
|
||||
#define INCL_DOS
|
||||
#define INCL_DOSERRORS
|
||||
#include <os2.h>
|
||||
#include <dos.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -696,6 +696,11 @@
|
||||
#define SDL_SensorUpdate SDL_SensorUpdate_REAL
|
||||
#define SDL_IsTablet SDL_IsTablet_REAL
|
||||
#define SDL_GetDisplayOrientation SDL_GetDisplayOrientation_REAL
|
||||
#define SDL_HasColorKey SDL_HasColorKey_REAL
|
||||
#define SDL_CreateThreadWithStackSize SDL_CreateThreadWithStackSize_REAL
|
||||
#define SDL_JoystickGetDevicePlayerIndex SDL_JoystickGetDevicePlayerIndex_REAL
|
||||
#define SDL_JoystickGetPlayerIndex SDL_JoystickGetPlayerIndex_REAL
|
||||
#define SDL_GameControllerGetPlayerIndex SDL_GameControllerGetPlayerIndex_REAL
|
||||
#define SDL_RenderFlush SDL_RenderFlush_REAL
|
||||
#define SDL_RenderDrawPointF SDL_RenderDrawPointF_REAL
|
||||
#define SDL_RenderDrawPointsF SDL_RenderDrawPointsF_REAL
|
||||
|
||||
@@ -738,6 +738,23 @@ SDL_DYNAPI_PROC(void,SDL_SensorClose,(SDL_Sensor *a),(a),)
|
||||
SDL_DYNAPI_PROC(void,SDL_SensorUpdate,(void),(),)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_IsTablet,(void),(),return)
|
||||
SDL_DYNAPI_PROC(SDL_DisplayOrientation,SDL_GetDisplayOrientation,(int a),(a),return)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_HasColorKey,(SDL_Surface *a),(a),return)
|
||||
|
||||
#ifdef SDL_CreateThreadWithStackSize
|
||||
#undef SDL_CreateThreadWithStackSize
|
||||
#endif
|
||||
|
||||
#if defined(__WIN32__) && !defined(HAVE_LIBC)
|
||||
SDL_DYNAPI_PROC(SDL_Thread*,SDL_CreateThreadWithStackSize,(SDL_ThreadFunction a, const char *b, const size_t c, void *d, pfnSDL_CurrentBeginThread e, pfnSDL_CurrentEndThread f),(a,b,c,d,e,f),return)
|
||||
#elif defined(__OS2__)
|
||||
SDL_DYNAPI_PROC(SDL_Thread*,SDL_CreateThreadWithStackSize,(SDL_ThreadFunction a, const char *b, const size_t c, void *d, pfnSDL_CurrentBeginThread e, pfnSDL_CurrentEndThread f),(a,b,c,d,e,f),return)
|
||||
#else
|
||||
SDL_DYNAPI_PROC(SDL_Thread*,SDL_CreateThreadWithStackSize,(SDL_ThreadFunction a, const char *b, const size_t c, void *d),(a,b,c,d),return)
|
||||
#endif
|
||||
|
||||
SDL_DYNAPI_PROC(int,SDL_JoystickGetDevicePlayerIndex,(int a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_JoystickGetPlayerIndex,(SDL_Joystick *a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_GameControllerGetPlayerIndex,(SDL_GameController *a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_RenderFlush,(SDL_Renderer *a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_RenderDrawPointF,(SDL_Renderer *a, float b, float c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_RenderDrawPointsF,(SDL_Renderer *a, const SDL_FPoint *b, int c),(a,b,c),return)
|
||||
|
||||
@@ -417,8 +417,10 @@ SDL_StartEventLoop(void)
|
||||
SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE);
|
||||
SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE);
|
||||
SDL_EventState(SDL_SYSWMEVENT, SDL_DISABLE);
|
||||
#if 0 /* Leave these events enabled so apps can respond to items being dragged onto them at startup */
|
||||
SDL_EventState(SDL_DROPFILE, SDL_DISABLE);
|
||||
SDL_EventState(SDL_DROPTEXT, SDL_DISABLE);
|
||||
#endif
|
||||
|
||||
SDL_AtomicSet(&SDL_EventQ.active, 1);
|
||||
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_events_c_h_
|
||||
#define SDL_events_c_h_
|
||||
|
||||
#include "../SDL_internal.h"
|
||||
|
||||
/* Useful functions and variables from SDL_events.c */
|
||||
@@ -49,4 +53,6 @@ extern void SDL_QuitQuit(void);
|
||||
|
||||
extern void SDL_SendPendingQuit(void);
|
||||
|
||||
#endif /* SDL_events_c_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -33,12 +33,38 @@
|
||||
|
||||
/* The mouse state */
|
||||
static SDL_Mouse SDL_mouse;
|
||||
static Uint32 SDL_double_click_time = 500;
|
||||
static int SDL_double_click_radius = 1;
|
||||
|
||||
static int
|
||||
SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y);
|
||||
|
||||
static void SDLCALL
|
||||
SDL_MouseDoubleClickTimeChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
|
||||
{
|
||||
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
|
||||
|
||||
if (hint && *hint) {
|
||||
mouse->double_click_time = SDL_atoi(hint);
|
||||
} else {
|
||||
#ifdef __WIN32__
|
||||
mouse->double_click_time = GetDoubleClickTime();
|
||||
#else
|
||||
mouse->double_click_time = 500;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void SDLCALL
|
||||
SDL_MouseDoubleClickRadiusChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
|
||||
{
|
||||
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
|
||||
|
||||
if (hint && *hint) {
|
||||
mouse->double_click_radius = SDL_atoi(hint);
|
||||
} else {
|
||||
mouse->double_click_radius = 32; /* 32 pixels seems about right for touch interfaces */
|
||||
}
|
||||
}
|
||||
|
||||
static void SDLCALL
|
||||
SDL_MouseNormalSpeedScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
|
||||
{
|
||||
@@ -83,6 +109,12 @@ SDL_MouseInit(void)
|
||||
|
||||
SDL_zerop(mouse);
|
||||
|
||||
SDL_AddHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_TIME,
|
||||
SDL_MouseDoubleClickTimeChanged, mouse);
|
||||
|
||||
SDL_AddHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS,
|
||||
SDL_MouseDoubleClickRadiusChanged, mouse);
|
||||
|
||||
SDL_AddHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE,
|
||||
SDL_MouseNormalSpeedScaleChanged, mouse);
|
||||
|
||||
@@ -114,12 +146,6 @@ SDL_GetMouse(void)
|
||||
return &SDL_mouse;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_SetDoubleClickTime(Uint32 interval)
|
||||
{
|
||||
SDL_double_click_time = interval;
|
||||
}
|
||||
|
||||
SDL_Window *
|
||||
SDL_GetMouseFocus(void)
|
||||
{
|
||||
@@ -454,9 +480,9 @@ SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state
|
||||
if (state == SDL_PRESSED) {
|
||||
Uint32 now = SDL_GetTicks();
|
||||
|
||||
if (SDL_TICKS_PASSED(now, clickstate->last_timestamp + SDL_double_click_time) ||
|
||||
SDL_abs(mouse->x - clickstate->last_x) > SDL_double_click_radius ||
|
||||
SDL_abs(mouse->y - clickstate->last_y) > SDL_double_click_radius) {
|
||||
if (SDL_TICKS_PASSED(now, clickstate->last_timestamp + mouse->double_click_time) ||
|
||||
SDL_abs(mouse->x - clickstate->last_x) > mouse->double_click_radius ||
|
||||
SDL_abs(mouse->y - clickstate->last_y) > mouse->double_click_radius) {
|
||||
clickstate->click_count = 0;
|
||||
}
|
||||
clickstate->last_timestamp = now;
|
||||
|
||||
@@ -90,6 +90,8 @@ typedef struct
|
||||
float relative_speed_scale;
|
||||
float scale_accum_x;
|
||||
float scale_accum_y;
|
||||
Uint32 double_click_time;
|
||||
int double_click_radius;
|
||||
SDL_bool touch_mouse_events;
|
||||
|
||||
/* Data for double-click tracking */
|
||||
@@ -112,9 +114,6 @@ extern int SDL_MouseInit(void);
|
||||
/* Get the mouse state structure */
|
||||
SDL_Mouse *SDL_GetMouse(void);
|
||||
|
||||
/* Set the default double-click interval */
|
||||
extern void SDL_SetDoubleClickTime(Uint32 interval);
|
||||
|
||||
/* Set the default mouse cursor */
|
||||
extern void SDL_SetDefaultCursor(SDL_Cursor * cursor);
|
||||
|
||||
|
||||
@@ -28,26 +28,13 @@
|
||||
|
||||
|
||||
static int SDLCALL
|
||||
RemovePendingResizedEvents(void * userdata, SDL_Event *event)
|
||||
RemovePendingSizeChangedAndResizedEvents(void * userdata, SDL_Event *event)
|
||||
{
|
||||
SDL_Event *new_event = (SDL_Event *)userdata;
|
||||
|
||||
if (event->type == SDL_WINDOWEVENT &&
|
||||
event->window.event == SDL_WINDOWEVENT_RESIZED &&
|
||||
event->window.windowID == new_event->window.windowID) {
|
||||
/* We're about to post a new size event, drop the old one */
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int SDLCALL
|
||||
RemovePendingSizeChangedEvents(void * userdata, SDL_Event *event)
|
||||
{
|
||||
SDL_Event *new_event = (SDL_Event *)userdata;
|
||||
|
||||
if (event->type == SDL_WINDOWEVENT &&
|
||||
event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED &&
|
||||
(event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED ||
|
||||
event->window.event == SDL_WINDOWEVENT_RESIZED) &&
|
||||
event->window.windowID == new_event->window.windowID) {
|
||||
/* We're about to post a new size event, drop the old one */
|
||||
return 0;
|
||||
@@ -199,11 +186,8 @@ SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1,
|
||||
event.window.windowID = window->id;
|
||||
|
||||
/* Fixes queue overflow with resize events that aren't processed */
|
||||
if (windowevent == SDL_WINDOWEVENT_RESIZED) {
|
||||
SDL_FilterEvents(RemovePendingResizedEvents, &event);
|
||||
}
|
||||
if (windowevent == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||
SDL_FilterEvents(RemovePendingSizeChangedEvents, &event);
|
||||
SDL_FilterEvents(RemovePendingSizeChangedAndResizedEvents, &event);
|
||||
}
|
||||
if (windowevent == SDL_WINDOWEVENT_MOVED) {
|
||||
SDL_FilterEvents(RemovePendingMoveEvents, &event);
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef scancodes_xfree86_h_
|
||||
#define scancodes_xfree86_h_
|
||||
|
||||
#include "../../include/SDL_scancode.h"
|
||||
|
||||
/* XFree86 key code to SDL scancode mapping table
|
||||
@@ -503,4 +507,6 @@ static const SDL_Scancode xvnc_scancode_table[] = {
|
||||
/* 80 */ SDL_SCANCODE_F12,
|
||||
};
|
||||
|
||||
#endif /* scancodes_xfree86_h_ */
|
||||
|
||||
/* *INDENT-ON* */
|
||||
|
||||
@@ -389,9 +389,11 @@ SDL_HapticClose(SDL_Haptic * haptic)
|
||||
void
|
||||
SDL_HapticQuit(void)
|
||||
{
|
||||
while (SDL_haptics) {
|
||||
SDL_HapticClose(SDL_haptics);
|
||||
}
|
||||
|
||||
SDL_SYS_HapticQuit();
|
||||
SDL_assert(SDL_haptics == NULL);
|
||||
SDL_haptics = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -19,7 +19,12 @@
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_haptic_c_h_
|
||||
#define SDL_haptic_c_h_
|
||||
|
||||
extern int SDL_HapticInit(void);
|
||||
extern void SDL_HapticQuit(void);
|
||||
|
||||
#endif /* SDL_haptic_c_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -195,6 +195,10 @@ SDL_SYS_HapticClose(SDL_Haptic * haptic)
|
||||
void
|
||||
SDL_SYS_HapticQuit(void)
|
||||
{
|
||||
/* We don't have any way to scan for joysticks (and their vibrators) at init, so don't wipe the list
|
||||
* of joysticks here in case this is a reinit.
|
||||
*/
|
||||
#if 0
|
||||
SDL_hapticlist_item *item = NULL;
|
||||
SDL_hapticlist_item *next = NULL;
|
||||
|
||||
@@ -206,6 +210,7 @@ SDL_SYS_HapticQuit(void)
|
||||
SDL_hapticlist = SDL_hapticlist_tail = NULL;
|
||||
numhaptics = 0;
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -230,7 +235,12 @@ int
|
||||
SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
|
||||
Uint32 iterations)
|
||||
{
|
||||
Android_JNI_HapticRun (((SDL_hapticlist_item *)haptic->hwdata)->device_id, effect->effect.leftright.length);
|
||||
float large = effect->effect.leftright.large_magnitude / 32767.0f;
|
||||
float small = effect->effect.leftright.small_magnitude / 32767.0f;
|
||||
|
||||
float total = (large * 0.6f) + (small * 0.4f);
|
||||
|
||||
Android_JNI_HapticRun (((SDL_hapticlist_item *)haptic->hwdata)->device_id, total, effect->effect.leftright.length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -801,7 +801,8 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src)
|
||||
else if (periodic->type == SDL_HAPTIC_SAWTOOTHDOWN)
|
||||
dest->u.periodic.waveform = FF_SAW_DOWN;
|
||||
dest->u.periodic.period = CLAMP(periodic->period);
|
||||
dest->u.periodic.magnitude = periodic->magnitude;
|
||||
/* Linux expects 0-65535, so multiply by 2 */
|
||||
dest->u.periodic.magnitude = CLAMP(periodic->magnitude) * 2;
|
||||
dest->u.periodic.offset = periodic->offset;
|
||||
/* Linux phase is defined in interval "[0x0000, 0x10000[", corresponds with "[0deg, 360deg[" phase shift. */
|
||||
dest->u.periodic.phase = ((Uint32)periodic->phase * 0x10000U) / 36000;
|
||||
@@ -908,9 +909,9 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src)
|
||||
dest->trigger.button = 0;
|
||||
dest->trigger.interval = 0;
|
||||
|
||||
/* Rumble */
|
||||
dest->u.rumble.strong_magnitude = leftright->large_magnitude;
|
||||
dest->u.rumble.weak_magnitude = leftright->small_magnitude;
|
||||
/* Rumble (Linux expects 0-65535, so multiply by 2) */
|
||||
dest->u.rumble.strong_magnitude = CLAMP(leftright->large_magnitude) * 2;
|
||||
dest->u.rumble.weak_magnitude = CLAMP(leftright->small_magnitude) * 2;
|
||||
|
||||
break;
|
||||
|
||||
|
||||
@@ -11,8 +11,13 @@
|
||||
#include <pthread.h>
|
||||
#include <errno.h> // For ETIMEDOUT and ECONNRESET
|
||||
#include <stdlib.h> // For malloc() and free()
|
||||
#include <string.h> // For memcpy()
|
||||
|
||||
#define TAG "hidapi"
|
||||
|
||||
// Have error log always available
|
||||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
|
||||
|
||||
#ifdef DEBUG
|
||||
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
|
||||
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
|
||||
@@ -27,13 +32,15 @@
|
||||
#define HID_DEVICE_MANAGER_JAVA_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, HIDDeviceManager, function)
|
||||
|
||||
#include "../hidapi/hidapi.h"
|
||||
|
||||
typedef uint32_t uint32;
|
||||
typedef uint64_t uint64;
|
||||
|
||||
|
||||
struct hid_device_
|
||||
{
|
||||
int nId;
|
||||
int m_nId;
|
||||
int m_nDeviceRefCount;
|
||||
};
|
||||
|
||||
static JavaVM *g_JVM;
|
||||
@@ -333,7 +340,7 @@ static jmethodID g_midHIDDeviceManagerSendFeatureReport;
|
||||
static jmethodID g_midHIDDeviceManagerGetFeatureReport;
|
||||
static jmethodID g_midHIDDeviceManagerClose;
|
||||
|
||||
uint64_t get_timespec_ms( const struct timespec &ts )
|
||||
static uint64_t get_timespec_ms( const struct timespec &ts )
|
||||
{
|
||||
return (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
|
||||
}
|
||||
@@ -364,12 +371,20 @@ public:
|
||||
|
||||
int IncrementRefCount()
|
||||
{
|
||||
return ++m_nRefCount;
|
||||
int nValue;
|
||||
pthread_mutex_lock( &m_refCountLock );
|
||||
nValue = ++m_nRefCount;
|
||||
pthread_mutex_unlock( &m_refCountLock );
|
||||
return nValue;
|
||||
}
|
||||
|
||||
int DecrementRefCount()
|
||||
{
|
||||
return --m_nRefCount;
|
||||
int nValue;
|
||||
pthread_mutex_lock( &m_refCountLock );
|
||||
nValue = --m_nRefCount;
|
||||
pthread_mutex_unlock( &m_refCountLock );
|
||||
return nValue;
|
||||
}
|
||||
|
||||
int GetId()
|
||||
@@ -387,19 +402,31 @@ public:
|
||||
return m_pDevice;
|
||||
}
|
||||
|
||||
int GetDeviceRefCount()
|
||||
void ExceptionCheck( JNIEnv *env, const char *pszMethodName )
|
||||
{
|
||||
return m_nDeviceRefCount;
|
||||
}
|
||||
if ( env->ExceptionCheck() )
|
||||
{
|
||||
// Get our exception
|
||||
jthrowable jExcept = env->ExceptionOccurred();
|
||||
|
||||
int IncrementDeviceRefCount()
|
||||
{
|
||||
return ++m_nDeviceRefCount;
|
||||
}
|
||||
// Clear the exception so we can call JNI again
|
||||
env->ExceptionClear();
|
||||
|
||||
int DecrementDeviceRefCount()
|
||||
{
|
||||
return --m_nDeviceRefCount;
|
||||
// Get our exception message
|
||||
jclass jExceptClass = env->GetObjectClass( jExcept );
|
||||
jmethodID jMessageMethod = env->GetMethodID( jExceptClass, "getMessage", "()Ljava/lang/String;" );
|
||||
jstring jMessage = (jstring)( env->CallObjectMethod( jExcept, jMessageMethod ) );
|
||||
const char *pszMessage = env->GetStringUTFChars( jMessage, NULL );
|
||||
|
||||
// ...and log it.
|
||||
LOGE( "CHIDDevice::%s threw an exception: %s", pszMethodName, pszMessage );
|
||||
|
||||
// Cleanup
|
||||
env->ReleaseStringUTFChars( jMessage, pszMessage );
|
||||
env->DeleteLocalRef( jMessage );
|
||||
env->DeleteLocalRef( jExceptClass );
|
||||
env->DeleteLocalRef( jExcept );
|
||||
}
|
||||
}
|
||||
|
||||
bool BOpen()
|
||||
@@ -411,6 +438,7 @@ public:
|
||||
|
||||
m_bIsWaitingForOpen = false;
|
||||
m_bOpenResult = env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerOpen, m_nId );
|
||||
ExceptionCheck( env, "BOpen" );
|
||||
|
||||
if ( m_bIsWaitingForOpen )
|
||||
{
|
||||
@@ -445,8 +473,9 @@ public:
|
||||
}
|
||||
|
||||
m_pDevice = new hid_device;
|
||||
m_pDevice->nId = m_nId;
|
||||
m_nDeviceRefCount = 1;
|
||||
m_pDevice->m_nId = m_nId;
|
||||
m_pDevice->m_nDeviceRefCount = 1;
|
||||
LOGD("Creating device %d (%p), refCount = 1\n", m_pDevice->m_nId, m_pDevice);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -518,6 +547,8 @@ public:
|
||||
|
||||
jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
|
||||
int nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendOutputReport, m_nId, pBuf );
|
||||
ExceptionCheck( env, "SendOutputReport" );
|
||||
|
||||
env->DeleteLocalRef( pBuf );
|
||||
return nRet;
|
||||
}
|
||||
@@ -531,6 +562,7 @@ public:
|
||||
|
||||
jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
|
||||
int nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendFeatureReport, m_nId, pBuf );
|
||||
ExceptionCheck( env, "SendFeatureReport" );
|
||||
env->DeleteLocalRef( pBuf );
|
||||
return nRet;
|
||||
}
|
||||
@@ -567,6 +599,7 @@ public:
|
||||
|
||||
jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
|
||||
int nRet = env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerGetFeatureReport, m_nId, pBuf ) ? 0 : -1;
|
||||
ExceptionCheck( env, "GetFeatureReport" );
|
||||
env->DeleteLocalRef( pBuf );
|
||||
if ( nRet < 0 )
|
||||
{
|
||||
@@ -625,7 +658,8 @@ public:
|
||||
pthread_setspecific( g_ThreadKey, (void*)env );
|
||||
|
||||
env->CallVoidMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerClose, m_nId );
|
||||
|
||||
ExceptionCheck( env, "Close" );
|
||||
|
||||
hid_mutex_guard dataLock( &m_dataLock );
|
||||
m_vecData.clear();
|
||||
|
||||
@@ -644,12 +678,12 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
pthread_mutex_t m_refCountLock = PTHREAD_MUTEX_INITIALIZER;
|
||||
int m_nRefCount = 0;
|
||||
int m_nId = 0;
|
||||
hid_device_info *m_pInfo = nullptr;
|
||||
hid_device *m_pDevice = nullptr;
|
||||
bool m_bIsBLESteamController = false;
|
||||
int m_nDeviceRefCount = 0;
|
||||
|
||||
pthread_mutex_t m_dataLock = PTHREAD_MUTEX_INITIALIZER; // This lock has to be held to access m_vecData
|
||||
hid_buffer_pool m_vecData;
|
||||
@@ -669,6 +703,7 @@ public:
|
||||
|
||||
class CHIDDevice;
|
||||
static pthread_mutex_t g_DevicesMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_mutex_t g_DevicesRefCountMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static hid_device_ref<CHIDDevice> g_Devices;
|
||||
|
||||
static hid_device_ref<CHIDDevice> FindDevice( int nDeviceId )
|
||||
@@ -696,8 +731,34 @@ static void ThreadDestroyed(void* value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz, jobject callbackHandler)
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz);
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz);
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, int nDeviceID, jstring sIdentifier, int nVendorId, int nProductId, jstring sSerialNumber, int nReleaseNumber, jstring sManufacturer, jstring sProduct, int nInterface );
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending)(JNIEnv *env, jobject thiz, int nDeviceID);
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult)(JNIEnv *env, jobject thiz, int nDeviceID, bool bOpened);
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected)(JNIEnv *env, jobject thiz, int nDeviceID);
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceInputReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value);
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceFeatureReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value);
|
||||
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz )
|
||||
{
|
||||
LOGV( "HIDDeviceRegisterCallback()");
|
||||
|
||||
@@ -711,11 +772,19 @@ JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallba
|
||||
__android_log_print(ANDROID_LOG_ERROR, TAG, "Error initializing pthread key");
|
||||
}
|
||||
|
||||
g_HIDDeviceManagerCallbackHandler = env->NewGlobalRef( callbackHandler );
|
||||
jclass objClass = env->GetObjectClass( callbackHandler );
|
||||
if ( g_HIDDeviceManagerCallbackHandler != NULL )
|
||||
{
|
||||
env->DeleteGlobalRef( g_HIDDeviceManagerCallbackClass );
|
||||
g_HIDDeviceManagerCallbackClass = NULL;
|
||||
env->DeleteGlobalRef( g_HIDDeviceManagerCallbackHandler );
|
||||
g_HIDDeviceManagerCallbackHandler = NULL;
|
||||
}
|
||||
|
||||
g_HIDDeviceManagerCallbackHandler = env->NewGlobalRef( thiz );
|
||||
jclass objClass = env->GetObjectClass( thiz );
|
||||
if ( objClass )
|
||||
{
|
||||
g_HIDDeviceManagerCallbackClass = reinterpret_cast< jclass >( env->NewGlobalRef(objClass) );
|
||||
g_HIDDeviceManagerCallbackClass = reinterpret_cast< jclass >( env->NewGlobalRef( objClass ) );
|
||||
g_midHIDDeviceManagerOpen = env->GetMethodID( g_HIDDeviceManagerCallbackClass, "openDevice", "(I)Z" );
|
||||
if ( !g_midHIDDeviceManagerOpen )
|
||||
{
|
||||
@@ -749,8 +818,13 @@ extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz)
|
||||
{
|
||||
LOGV("HIDDeviceReleaseCallback");
|
||||
env->DeleteGlobalRef( g_HIDDeviceManagerCallbackClass );
|
||||
env->DeleteGlobalRef( g_HIDDeviceManagerCallbackHandler );
|
||||
if ( env->IsSameObject( thiz, g_HIDDeviceManagerCallbackHandler ) )
|
||||
{
|
||||
env->DeleteGlobalRef( g_HIDDeviceManagerCallbackClass );
|
||||
g_HIDDeviceManagerCallbackClass = NULL;
|
||||
env->DeleteGlobalRef( g_HIDDeviceManagerCallbackHandler );
|
||||
g_HIDDeviceManagerCallbackHandler = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
@@ -924,14 +998,18 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bEx
|
||||
|
||||
hid_device_ref< CHIDDevice > pDevice;
|
||||
{
|
||||
hid_mutex_guard r( &g_DevicesRefCountMutex );
|
||||
hid_mutex_guard l( &g_DevicesMutex );
|
||||
for ( hid_device_ref<CHIDDevice> pCurr = g_Devices; pCurr; pCurr = pCurr->next )
|
||||
{
|
||||
if ( strcmp( pCurr->GetDeviceInfo()->path, path ) == 0 )
|
||||
{
|
||||
if ( pCurr->GetDevice() ) {
|
||||
pCurr->IncrementDeviceRefCount();
|
||||
return pCurr->GetDevice();
|
||||
hid_device *pValue = pCurr->GetDevice();
|
||||
if ( pValue )
|
||||
{
|
||||
++pValue->m_nDeviceRefCount;
|
||||
LOGD("Incrementing device %d (%p), refCount = %d\n", pValue->m_nId, pValue, pValue->m_nDeviceRefCount);
|
||||
return pValue;
|
||||
}
|
||||
|
||||
// Hold a shared pointer to the controller for the duration
|
||||
@@ -949,8 +1027,8 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bEx
|
||||
|
||||
int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length)
|
||||
{
|
||||
LOGV( "hid_write id=%d length=%u", device->nId, length );
|
||||
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId );
|
||||
LOGV( "hid_write id=%d length=%u", device->m_nId, length );
|
||||
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
|
||||
if ( pDevice )
|
||||
{
|
||||
return pDevice->SendOutputReport( data, length );
|
||||
@@ -961,8 +1039,8 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned ch
|
||||
// TODO: Implement timeout?
|
||||
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds)
|
||||
{
|
||||
// LOGV( "hid_read_timeout id=%d length=%u timeout=%d", device->nId, length, milliseconds );
|
||||
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId );
|
||||
// LOGV( "hid_read_timeout id=%d length=%u timeout=%d", device->m_nId, length, milliseconds );
|
||||
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
|
||||
if ( pDevice )
|
||||
{
|
||||
return pDevice->GetInput( data, length );
|
||||
@@ -974,7 +1052,7 @@ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned ch
|
||||
// TODO: Implement blocking
|
||||
int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length)
|
||||
{
|
||||
LOGV( "hid_read id=%d length=%u", device->nId, length );
|
||||
LOGV( "hid_read id=%d length=%u", device->m_nId, length );
|
||||
return hid_read_timeout( device, data, length, 0 );
|
||||
}
|
||||
|
||||
@@ -986,8 +1064,8 @@ int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int non
|
||||
|
||||
int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length)
|
||||
{
|
||||
LOGV( "hid_send_feature_report id=%d length=%u", device->nId, length );
|
||||
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId );
|
||||
LOGV( "hid_send_feature_report id=%d length=%u", device->m_nId, length );
|
||||
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
|
||||
if ( pDevice )
|
||||
{
|
||||
return pDevice->SendFeatureReport( data, length );
|
||||
@@ -999,8 +1077,8 @@ int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, cons
|
||||
// Synchronous operation. Will block until completed.
|
||||
int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length)
|
||||
{
|
||||
LOGV( "hid_get_feature_report id=%d length=%u", device->nId, length );
|
||||
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId );
|
||||
LOGV( "hid_get_feature_report id=%d length=%u", device->m_nId, length );
|
||||
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
|
||||
if ( pDevice )
|
||||
{
|
||||
return pDevice->GetFeatureReport( data, length );
|
||||
@@ -1011,26 +1089,28 @@ int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsig
|
||||
|
||||
void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device)
|
||||
{
|
||||
LOGV( "hid_close id=%d", device->nId );
|
||||
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId );
|
||||
if ( pDevice )
|
||||
LOGV( "hid_close id=%d", device->m_nId );
|
||||
hid_mutex_guard r( &g_DevicesRefCountMutex );
|
||||
LOGD("Decrementing device %d (%p), refCount = %d\n", device->m_nId, device, device->m_nDeviceRefCount - 1);
|
||||
if ( --device->m_nDeviceRefCount == 0 )
|
||||
{
|
||||
pDevice->DecrementDeviceRefCount();
|
||||
if ( pDevice->GetDeviceRefCount() == 0 ) {
|
||||
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
|
||||
if ( pDevice )
|
||||
{
|
||||
pDevice->Close( true );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Couldn't find it, it's already closed
|
||||
delete device;
|
||||
else
|
||||
{
|
||||
delete device;
|
||||
}
|
||||
LOGD("Deleted device %p\n", device);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen)
|
||||
{
|
||||
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId );
|
||||
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
|
||||
if ( pDevice )
|
||||
{
|
||||
wcsncpy( string, pDevice->GetDeviceInfo()->manufacturer_string, maxlen );
|
||||
@@ -1041,7 +1121,7 @@ int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t
|
||||
|
||||
int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen)
|
||||
{
|
||||
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId );
|
||||
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
|
||||
if ( pDevice )
|
||||
{
|
||||
wcsncpy( string, pDevice->GetDeviceInfo()->product_string, maxlen );
|
||||
@@ -1052,7 +1132,7 @@ int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *stri
|
||||
|
||||
int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen)
|
||||
{
|
||||
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId );
|
||||
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
|
||||
if ( pDevice )
|
||||
{
|
||||
wcsncpy( string, pDevice->GetDeviceInfo()->serial_number, maxlen );
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(NAMESPACE)
|
||||
#if defined(_WIN32) && !defined(NAMESPACE) && (0) /* SDL: don't export hidapi syms */
|
||||
#define HID_API_EXPORT __declspec(dllexport)
|
||||
#define HID_API_CALL
|
||||
#else
|
||||
@@ -225,7 +225,7 @@ namespace NAMESPACE {
|
||||
-1 on error. If no packet was available to be read within
|
||||
the timeout period, this function returns 0.
|
||||
*/
|
||||
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds);
|
||||
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds);
|
||||
|
||||
/** @brief Read an Input report from a HID device.
|
||||
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
// Purpose: HID device abstraction temporary stub
|
||||
//
|
||||
//=============================================================================
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI
|
||||
|
||||
#include <CoreBluetooth/CoreBluetooth.h>
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
@@ -907,3 +910,5 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* SDL_JOYSTICK_HIDAPI */
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
code repository located at:
|
||||
http://github.com/signal11/hidapi .
|
||||
********************************************************/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE /* needed for wcsdup() before glibc 2.10 */
|
||||
@@ -1613,3 +1616,5 @@ uint16_t get_usb_code_for_current_locale(void)
|
||||
#ifdef NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SDL_JOYSTICK_HIDAPI */
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
code repository located at:
|
||||
http://github.com/signal11/hidapi .
|
||||
********************************************************/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE /* needed for wcsdup() before glibc 2.10 */
|
||||
@@ -891,3 +894,5 @@ HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
|
||||
#ifdef NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SDL_JOYSTICK_HIDAPI */
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
code repository located at:
|
||||
http://github.com/signal11/hidapi .
|
||||
********************************************************/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI
|
||||
|
||||
/* See Apple Technical Note TN2187 for details on IOHidManager. */
|
||||
|
||||
@@ -1184,3 +1187,5 @@ int main(void)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SDL_JOYSTICK_HIDAPI */
|
||||
|
||||
@@ -19,13 +19,13 @@
|
||||
code repository located at:
|
||||
http://github.com/signal11/hidapi .
|
||||
********************************************************/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifndef _NTDEF_
|
||||
typedef LONG NTSTATUS;
|
||||
#endif
|
||||
|
||||
#if 0 /* can cause redefinition errors on some toolchains */
|
||||
#ifdef __MINGW32__
|
||||
#include <ntdef.h>
|
||||
#include <winbase.h>
|
||||
@@ -35,6 +35,11 @@ typedef LONG NTSTATUS;
|
||||
#include <ntdef.h>
|
||||
#define _wcsdup wcsdup
|
||||
#endif
|
||||
#endif /* */
|
||||
|
||||
#ifndef _NTDEF_
|
||||
typedef LONG NTSTATUS;
|
||||
#endif
|
||||
|
||||
/* SDL C runtime functions */
|
||||
#include "SDL_stdinc.h"
|
||||
@@ -905,17 +910,18 @@ int HID_API_EXPORT_CALL HID_API_CALL hid_get_indexed_string(hid_device *dev, int
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
|
||||
{
|
||||
return (wchar_t*)dev->last_error_str;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
/*#define PICPGM*/
|
||||
/*#define S11*/
|
||||
#define P32
|
||||
#ifdef S11
|
||||
#ifdef S11
|
||||
unsigned short VendorID = 0xa0a0;
|
||||
unsigned short ProductID = 0x0001;
|
||||
#endif
|
||||
@@ -925,14 +931,11 @@ HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
|
||||
unsigned short ProductID = 0x3f;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef PICPGM
|
||||
unsigned short VendorID = 0x04d8;
|
||||
unsigned short ProductID = 0x0033;
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
int __cdecl main(int argc, char* argv[])
|
||||
{
|
||||
int res;
|
||||
@@ -981,3 +984,5 @@ int __cdecl main(int argc, char* argv[])
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* SDL_JOYSTICK_HIDAPI */
|
||||
|
||||
@@ -111,7 +111,6 @@ struct _SDL_GameController
|
||||
SDL_Joystick *joystick; /* underlying joystick device */
|
||||
int ref_count;
|
||||
|
||||
SDL_JoystickGUID guid;
|
||||
const char *name;
|
||||
int num_bindings;
|
||||
SDL_ExtendedGameControllerBind *bindings;
|
||||
@@ -433,12 +432,12 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickG
|
||||
pSupportedController = pSupportedController->next;
|
||||
}
|
||||
if (!exact_match) {
|
||||
if (guid->data[14] == 'h') {
|
||||
if (SDL_IsJoystickHIDAPI(*guid)) {
|
||||
/* This is a HIDAPI device */
|
||||
return s_pHIDAPIMapping;
|
||||
}
|
||||
#if SDL_JOYSTICK_XINPUT
|
||||
if (guid->data[14] == 'x') {
|
||||
if (SDL_IsJoystickXInput(*guid)) {
|
||||
/* This is an XInput device */
|
||||
return s_pXInputMapping;
|
||||
}
|
||||
@@ -684,11 +683,10 @@ SDL_PrivateGameControllerParseControllerConfigString(SDL_GameController *gamecon
|
||||
/*
|
||||
* Make a new button mapping struct
|
||||
*/
|
||||
static void SDL_PrivateLoadButtonMapping(SDL_GameController *gamecontroller, SDL_JoystickGUID guid, const char *pchName, const char *pchMapping)
|
||||
static void SDL_PrivateLoadButtonMapping(SDL_GameController *gamecontroller, const char *pchName, const char *pchMapping)
|
||||
{
|
||||
int i;
|
||||
|
||||
gamecontroller->guid = guid;
|
||||
gamecontroller->name = pchName;
|
||||
gamecontroller->num_bindings = 0;
|
||||
SDL_memset(gamecontroller->last_match_axis, 0, gamecontroller->joystick->naxes * sizeof(*gamecontroller->last_match_axis));
|
||||
@@ -802,14 +800,16 @@ static void SDL_PrivateGameControllerRefreshMapping(ControllerMapping_t *pContro
|
||||
{
|
||||
SDL_GameController *gamecontrollerlist = SDL_gamecontrollers;
|
||||
while (gamecontrollerlist) {
|
||||
if (!SDL_memcmp(&gamecontrollerlist->guid, &pControllerMapping->guid, sizeof(pControllerMapping->guid))) {
|
||||
SDL_Event event;
|
||||
event.type = SDL_CONTROLLERDEVICEREMAPPED;
|
||||
event.cdevice.which = gamecontrollerlist->joystick->instance_id;
|
||||
SDL_PushEvent(&event);
|
||||
|
||||
if (!SDL_memcmp(&gamecontrollerlist->joystick->guid, &pControllerMapping->guid, sizeof(pControllerMapping->guid))) {
|
||||
/* Not really threadsafe. Should this lock access within SDL_GameControllerEventWatcher? */
|
||||
SDL_PrivateLoadButtonMapping(gamecontrollerlist, pControllerMapping->guid, pControllerMapping->name, pControllerMapping->mapping);
|
||||
SDL_PrivateLoadButtonMapping(gamecontrollerlist, pControllerMapping->name, pControllerMapping->mapping);
|
||||
|
||||
{
|
||||
SDL_Event event;
|
||||
event.type = SDL_CONTROLLERDEVICEREMAPPED;
|
||||
event.cdevice.which = gamecontrollerlist->joystick->instance_id;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
|
||||
gamecontrollerlist = gamecontrollerlist->next;
|
||||
@@ -1027,7 +1027,7 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForNameAndGUID(const
|
||||
}
|
||||
}
|
||||
#ifdef __ANDROID__
|
||||
if (!mapping) {
|
||||
if (!mapping && name && !SDL_IsJoystickHIDAPI(guid)) {
|
||||
mapping = SDL_CreateMappingForAndroidController(name, guid);
|
||||
}
|
||||
#endif
|
||||
@@ -1274,7 +1274,7 @@ SDL_GameControllerMapping(SDL_GameController * gamecontroller)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return SDL_GameControllerMappingForGUID(gamecontroller->guid);
|
||||
return SDL_GameControllerMappingForGUID(gamecontroller->joystick->guid);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1463,6 +1463,7 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
|
||||
int i;
|
||||
Uint16 vendor;
|
||||
Uint16 product;
|
||||
Uint16 version;
|
||||
Uint32 vidpid;
|
||||
|
||||
if (SDL_allowed_controllers.num_entries == 0 &&
|
||||
@@ -1470,7 +1471,7 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);
|
||||
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, &version);
|
||||
|
||||
if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE)) {
|
||||
/* We shouldn't ignore Steam's virtual gamepad since it's using the hints to filter out the real controllers so it can remap input for the virtual controller */
|
||||
@@ -1478,7 +1479,7 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
|
||||
#if defined(__LINUX__)
|
||||
bSteamVirtualGamepad = (vendor == 0x28DE && product == 0x11FF);
|
||||
#elif defined(__MACOSX__)
|
||||
bSteamVirtualGamepad = (SDL_strncmp(name, "GamePad-", 8) == 0);
|
||||
bSteamVirtualGamepad = (vendor == 0x045E && product == 0x028E && version == 1);
|
||||
#elif defined(__WIN32__)
|
||||
/* We can't tell on Windows, but Steam will block others in input hooks */
|
||||
bSteamVirtualGamepad = SDL_TRUE;
|
||||
@@ -1582,7 +1583,7 @@ SDL_GameControllerOpen(int device_index)
|
||||
}
|
||||
}
|
||||
|
||||
SDL_PrivateLoadButtonMapping(gamecontroller, pSupportedController->guid, pSupportedController->name, pSupportedController->mapping);
|
||||
SDL_PrivateLoadButtonMapping(gamecontroller, pSupportedController->name, pSupportedController->mapping);
|
||||
|
||||
/* Add the controller to list */
|
||||
++gamecontroller->ref_count;
|
||||
@@ -1716,6 +1717,12 @@ SDL_GameControllerName(SDL_GameController * gamecontroller)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller)
|
||||
{
|
||||
return SDL_JoystickGetPlayerIndex(SDL_GameControllerGetJoystick(gamecontroller));
|
||||
}
|
||||
|
||||
Uint16
|
||||
SDL_GameControllerGetVendor(SDL_GameController * gamecontroller)
|
||||
{
|
||||
|
||||
@@ -362,6 +362,7 @@ static const char *s_ControllerMappings [] =
|
||||
"03000000022000000090000011010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,",
|
||||
"05000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,",
|
||||
"05000000c82d00002038000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,",
|
||||
"05000000c82d00000061000000010000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,",
|
||||
"05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,",
|
||||
"05000000c82d00003028000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,",
|
||||
"05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,",
|
||||
@@ -548,6 +549,7 @@ static const char *s_ControllerMappings [] =
|
||||
"0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
|
||||
"050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||
"030000005e040000ea02000001030000,Xbox One Wireless Controller (Model 1708),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,",
|
||||
"03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,",
|
||||
"03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
|
||||
@@ -227,6 +227,21 @@ SDL_JoystickNameForIndex(int device_index)
|
||||
return name;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
SDL_JoystickDriver *driver;
|
||||
int player_index = -1;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) {
|
||||
player_index = driver->GetDevicePlayerIndex(device_index);
|
||||
}
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
return player_index;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if this joystick is known to have all axes centered at zero
|
||||
* This isn't generally needed unless the joystick never generates an initial axis value near zero,
|
||||
@@ -307,6 +322,7 @@ SDL_JoystickOpen(int device_index)
|
||||
joystick->driver = driver;
|
||||
joystick->instance_id = instance_id;
|
||||
joystick->attached = SDL_TRUE;
|
||||
joystick->player_index = -1;
|
||||
|
||||
if (driver->Open(joystick, device_index) < 0) {
|
||||
SDL_free(joystick);
|
||||
@@ -602,6 +618,15 @@ SDL_JoystickName(SDL_Joystick * joystick)
|
||||
return SDL_FixupJoystickName(joystick->name);
|
||||
}
|
||||
|
||||
int
|
||||
SDL_JoystickGetPlayerIndex(SDL_Joystick * joystick)
|
||||
{
|
||||
if (!SDL_PrivateJoystickValid(joystick)) {
|
||||
return -1;
|
||||
}
|
||||
return joystick->player_index;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
|
||||
{
|
||||
@@ -1136,19 +1161,19 @@ SDL_IsJoystickNintendoSwitchPro(Uint16 vendor, Uint16 product)
|
||||
SDL_bool
|
||||
SDL_IsJoystickSteamController(Uint16 vendor, Uint16 product)
|
||||
{
|
||||
return BIsSteamController(GuessControllerType(vendor, product)) ? SDL_TRUE : SDL_FALSE;
|
||||
return BIsSteamController(GuessControllerType(vendor, product));
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_IsJoystickXbox360(Uint16 vendor, Uint16 product)
|
||||
{
|
||||
/* Filter out some bogus values here */
|
||||
if (vendor == 0x0000 && product == 0x0000) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
if (vendor == 0x0001 && product == 0x0001) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
/* Filter out some bogus values here */
|
||||
if (vendor == 0x0000 && product == 0x0000) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
if (vendor == 0x0001 && product == 0x0001) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
return (GuessControllerType(vendor, product) == k_eControllerType_XBox360Controller);
|
||||
}
|
||||
|
||||
@@ -1158,6 +1183,18 @@ SDL_IsJoystickXboxOne(Uint16 vendor, Uint16 product)
|
||||
return (GuessControllerType(vendor, product) == k_eControllerType_XBoxOneController);
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_IsJoystickXInput(SDL_JoystickGUID guid)
|
||||
{
|
||||
return (guid.data[14] == 'x') ? SDL_TRUE : SDL_FALSE;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_IsJoystickHIDAPI(SDL_JoystickGUID guid)
|
||||
{
|
||||
return (guid.data[14] == 'h') ? SDL_TRUE : SDL_FALSE;
|
||||
}
|
||||
|
||||
static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid)
|
||||
{
|
||||
static Uint32 wheel_joysticks[] = {
|
||||
@@ -1223,7 +1260,7 @@ static SDL_JoystickType SDL_GetJoystickGUIDType(SDL_JoystickGUID guid)
|
||||
Uint16 product;
|
||||
Uint32 vidpid;
|
||||
|
||||
if (guid.data[14] == 'x') {
|
||||
if (SDL_IsJoystickXInput(guid)) {
|
||||
/* XInput GUID, get the type based on the XInput device subtype */
|
||||
switch (guid.data[15]) {
|
||||
case 0x01: /* XINPUT_DEVSUBTYPE_GAMEPAD */
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_joystick_c_h_
|
||||
#define SDL_joystick_c_h_
|
||||
|
||||
#include "../SDL_internal.h"
|
||||
|
||||
/* Useful functions and variables from SDL_joystick.c */
|
||||
@@ -62,6 +66,12 @@ extern SDL_bool SDL_IsJoystickXbox360(Uint16 vendor_id, Uint16 product_id);
|
||||
/* Function to return whether a joystick is an Xbox One controller */
|
||||
extern SDL_bool SDL_IsJoystickXboxOne(Uint16 vendor_id, Uint16 product_id);
|
||||
|
||||
/* Function to return whether a joystick guid comes from the XInput driver */
|
||||
extern SDL_bool SDL_IsJoystickXInput(SDL_JoystickGUID guid);
|
||||
|
||||
/* Function to return whether a joystick guid comes from the HIDAPI driver */
|
||||
extern SDL_bool SDL_IsJoystickHIDAPI(SDL_JoystickGUID guid);
|
||||
|
||||
/* Function to return whether a joystick should be ignored */
|
||||
extern SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid);
|
||||
|
||||
@@ -91,4 +101,6 @@ extern void SDL_PrivateJoystickBatteryLevel(SDL_Joystick * joystick,
|
||||
/* Internal sanity checking functions */
|
||||
extern int SDL_PrivateJoystickValid(SDL_Joystick * joystick);
|
||||
|
||||
#endif /* SDL_joystick_c_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -42,6 +42,7 @@ struct _SDL_Joystick
|
||||
{
|
||||
SDL_JoystickID instance_id; /* Device instance, monotonically increasing from 0 */
|
||||
char *name; /* Joystick name - system dependent */
|
||||
int player_index; /* Joystick player index, or -1 if unavailable */
|
||||
SDL_JoystickGUID guid; /* Joystick guid */
|
||||
|
||||
int naxes; /* Number of axis controls on the joystick */
|
||||
@@ -105,6 +106,9 @@ typedef struct _SDL_JoystickDriver
|
||||
/* Function to get the device-dependent name of a joystick */
|
||||
const char *(*GetDeviceName)(int device_index);
|
||||
|
||||
/* Function to get the player index of a joystick */
|
||||
int (*GetDevicePlayerIndex)(int device_index);
|
||||
|
||||
/* Function to return the stable GUID for a plugged in device */
|
||||
SDL_JoystickGUID (*GetDeviceGUID)(int device_index);
|
||||
|
||||
|
||||
@@ -581,6 +581,12 @@ ANDROID_JoystickGetDeviceName(int device_index)
|
||||
return JoystickByDevIndex(device_index)->name;
|
||||
}
|
||||
|
||||
static int
|
||||
ANDROID_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static SDL_JoystickGUID
|
||||
ANDROID_JoystickGetDeviceGUID(int device_index)
|
||||
{
|
||||
@@ -689,6 +695,7 @@ SDL_JoystickDriver SDL_ANDROID_JoystickDriver =
|
||||
ANDROID_JoystickGetCount,
|
||||
ANDROID_JoystickDetect,
|
||||
ANDROID_JoystickGetDeviceName,
|
||||
ANDROID_JoystickGetDevicePlayerIndex,
|
||||
ANDROID_JoystickGetDeviceGUID,
|
||||
ANDROID_JoystickGetDeviceInstanceID,
|
||||
ANDROID_JoystickOpen,
|
||||
|
||||
@@ -227,6 +227,12 @@ BSD_JoystickGetDeviceName(int device_index)
|
||||
return (joynames[device_index]);
|
||||
}
|
||||
|
||||
static int
|
||||
BSD_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Function to perform the mapping from device index to the instance id for this index */
|
||||
static SDL_JoystickID
|
||||
BSD_JoystickGetDeviceInstanceID(int device_index)
|
||||
@@ -293,6 +299,10 @@ BSD_JoystickOpen(SDL_Joystick * joy, int device_index)
|
||||
struct hid_item hitem;
|
||||
struct hid_data *hdata;
|
||||
struct report *rep = NULL;
|
||||
#if defined(__NetBSD__)
|
||||
usb_device_descriptor_t udd;
|
||||
struct usb_string_desc usd;
|
||||
#endif
|
||||
int fd;
|
||||
int i;
|
||||
|
||||
@@ -344,8 +354,6 @@ BSD_JoystickOpen(SDL_Joystick * joy, int device_index)
|
||||
rep->rid = -1; /* XXX */
|
||||
}
|
||||
#if defined(__NetBSD__)
|
||||
usb_device_descriptor_t udd;
|
||||
struct usb_string_desc usd;
|
||||
if (ioctl(fd, USB_GET_DEVICE_DESC, &udd) == -1)
|
||||
goto desc_failed;
|
||||
|
||||
@@ -687,6 +695,7 @@ SDL_JoystickDriver SDL_BSD_JoystickDriver =
|
||||
BSD_JoystickGetCount,
|
||||
BSD_JoystickDetect,
|
||||
BSD_JoystickGetDeviceName,
|
||||
BSD_JoystickGetDevicePlayerIndex,
|
||||
BSD_JoystickGetDeviceGUID,
|
||||
BSD_JoystickGetDeviceInstanceID,
|
||||
BSD_JoystickOpen,
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus
|
||||
typedef enum { false, true } bool;
|
||||
#define inline SDL_INLINE
|
||||
#endif
|
||||
|
||||
@@ -43,9 +42,6 @@ typedef enum
|
||||
k_eControllerType_SteamController = 2,
|
||||
k_eControllerType_SteamControllerV2 = 3,
|
||||
|
||||
// IR Remote controls on Steambox
|
||||
k_eControllerType_FrontPanelBoard = 20,
|
||||
|
||||
// Other Controllers
|
||||
k_eControllerType_UnknownNonSteamController = 30,
|
||||
k_eControllerType_XBox360Controller = 31,
|
||||
@@ -68,54 +64,11 @@ typedef enum
|
||||
k_eControllertype_GenericMouse = 800,
|
||||
} EControllerType;
|
||||
|
||||
static inline bool BIsSteamController( EControllerType eType )
|
||||
static inline SDL_bool BIsSteamController( EControllerType eType )
|
||||
{
|
||||
return ( eType == k_eControllerType_SteamController || eType == k_eControllerType_SteamControllerV2 );
|
||||
}
|
||||
|
||||
#if 0 /* these are currently unused, so #if 0'd out to prevent compiler warnings for now */
|
||||
static inline bool BIsSteamHardwareDevice( EControllerType eType )
|
||||
{
|
||||
return ( eType == k_eControllerType_SteamController || eType == k_eControllerType_SteamControllerV2 || eType == k_eControllerType_FrontPanelBoard );
|
||||
}
|
||||
|
||||
static inline bool BIsXInputController( EControllerType eType )
|
||||
{
|
||||
return ( eType == k_eControllerType_XBox360Controller || eType == k_eControllerType_XBoxOneController || eType == k_eControllerType_UnknownNonSteamController );
|
||||
}
|
||||
|
||||
static inline bool BIsSwitchController( EControllerType eType )
|
||||
{
|
||||
return ( eType == k_eControllerType_SwitchJoyConLeft || eType == k_eControllerType_SwitchJoyConRight ||
|
||||
eType == k_eControllerType_SwitchJoyConPair || eType == k_eControllerType_SwitchProController ||
|
||||
eType == k_eControllerType_SwitchInputOnlyController );
|
||||
}
|
||||
|
||||
/* XXX: this should be updated when we ship nintentdo switch controller support */
|
||||
static inline bool BIsRawHIDDevice( EControllerType eType )
|
||||
{
|
||||
return BIsSteamHardwareDevice( eType) || eType == k_eControllerType_PS4Controller || BIsSwitchController( eType );
|
||||
}
|
||||
|
||||
// 'Full' here means that the controller has a full complement of buttons, joysticks, etc, as compared to
|
||||
// the single Joy-Con's that only have around half of the controls that a normal controller has
|
||||
static inline bool BIsFullSwitchController( EControllerType eType )
|
||||
{
|
||||
return ( eType == k_eControllerType_SwitchJoyConPair || eType == k_eControllerType_SwitchProController );
|
||||
}
|
||||
|
||||
static inline bool BIsCompatibleType( EControllerType eTypeA, EControllerType eTypeB )
|
||||
{
|
||||
if ( BIsSteamController( eTypeA ) && BIsSteamController( eTypeB ) )
|
||||
return true;
|
||||
if ( BIsXInputController( eTypeA ) && BIsXInputController( eTypeB ) )
|
||||
return true;
|
||||
if ( eTypeA == eTypeB )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MAKE_CONTROLLER_ID( nVID, nPID ) (unsigned int)( nVID << 16 | nPID )
|
||||
typedef struct
|
||||
{
|
||||
@@ -168,7 +121,6 @@ static const ControllerDescription_t arrControllers[] = {
|
||||
{ MAKE_CONTROLLER_ID( 0x146b, 0x0603 ), k_eControllerType_PS3Controller }, // From SDL
|
||||
{ MAKE_CONTROLLER_ID( 0x044f, 0xb315 ), k_eControllerType_PS3Controller }, // Firestorm Dual Analog 3
|
||||
{ MAKE_CONTROLLER_ID( 0x0925, 0x8888 ), k_eControllerType_PS3Controller }, // Actually ps2 -maybe break out later Lakeview Research WiseGroup Ltd, MP-8866 Dual Joypad
|
||||
{ MAKE_CONTROLLER_ID( 0x146b, 0x0602 ), k_eControllerType_PS3Controller }, // From SDL
|
||||
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x004d ), k_eControllerType_PS3Controller }, // Horipad 3
|
||||
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0009 ), k_eControllerType_PS3Controller }, // HORI BDA GP1
|
||||
{ MAKE_CONTROLLER_ID( 0x0e8f, 0x0008 ), k_eControllerType_PS3Controller }, // Green Asia
|
||||
@@ -214,8 +166,8 @@ static const ControllerDescription_t arrControllers[] = {
|
||||
{ MAKE_CONTROLLER_ID( 0x1532, 0x1000 ), k_eControllerType_PS4Controller }, // Razer Raiju PS4 Controller
|
||||
{ MAKE_CONTROLLER_ID( 0x1532, 0X0401 ), k_eControllerType_PS4Controller }, // Razer Panthera PS4 Controller
|
||||
{ MAKE_CONTROLLER_ID( 0x054c, 0x05c5 ), k_eControllerType_PS4Controller }, // STRIKEPAD PS4 Grip Add-on
|
||||
{ MAKE_CONTROLLER_ID( 0x146b, 0x0d01 ), k_eControllerType_PS4Controller }, // Nacon Revolution Pro Controller
|
||||
{ MAKE_CONTROLLER_ID( 0x146b, 0x0d02 ), k_eControllerType_PS4Controller }, // Nacon Revolution Pro Controller v2
|
||||
{ MAKE_CONTROLLER_ID( 0x146b, 0x0d01 ), k_eControllerType_PS4Controller }, // Nacon Revolution Pro Controller - has gyro
|
||||
{ MAKE_CONTROLLER_ID( 0x146b, 0x0d02 ), k_eControllerType_PS4Controller }, // Nacon Revolution Pro Controller v2 - has gyro
|
||||
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00a0 ), k_eControllerType_PS4Controller }, // HORI TAC4 mousething
|
||||
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x009c ), k_eControllerType_PS4Controller }, // HORI TAC PRO mousething
|
||||
{ MAKE_CONTROLLER_ID( 0x0c12, 0x0ef6 ), k_eControllerType_PS4Controller }, // Hitbox Arcade Stick
|
||||
@@ -224,7 +176,15 @@ static const ControllerDescription_t arrControllers[] = {
|
||||
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00ee ), k_eControllerType_PS4Controller }, // Hori mini wired https://www.playstation.com/en-us/explore/accessories/gaming-controllers/mini-wired-gamepad/
|
||||
{ MAKE_CONTROLLER_ID( 0x0738, 0x8481 ), k_eControllerType_PS4Controller }, // Mad Catz FightStick TE 2+ PS4
|
||||
{ MAKE_CONTROLLER_ID( 0x0738, 0x8480 ), k_eControllerType_PS4Controller }, // Mad Catz FightStick TE 2 PS4
|
||||
{ MAKE_CONTROLLER_ID( 0x7545, 0x0104 ), k_eControllerType_PS4Controller }, // Armor 3 or Level Up Cobra
|
||||
{ MAKE_CONTROLLER_ID( 0x7545, 0x0104 ), k_eControllerType_PS4Controller }, // Armor 3 or Level Up Cobra - At least one variant has gyro
|
||||
{ MAKE_CONTROLLER_ID( 0x0c12, 0x0e15 ), k_eControllerType_PS4Controller }, // Game:Pad 4
|
||||
{ MAKE_CONTROLLER_ID( 0x11c0, 0x4001 ), k_eControllerType_PS4Controller }, // "PS4 Fun Controller" added from user log
|
||||
|
||||
{ MAKE_CONTROLLER_ID( 0x1532, 0x1007 ), k_eControllerType_PS4Controller }, // Razer Raiju 2 Tournament edition USB- untested and added for razer
|
||||
{ MAKE_CONTROLLER_ID( 0x1532, 0x100A ), k_eControllerType_PS4Controller }, // Razer Raiju 2 Tournament edition BT - untested and added for razer
|
||||
{ MAKE_CONTROLLER_ID( 0x1532, 0x1004 ), k_eControllerType_PS4Controller }, // Razer Raiju 2 Ultimate USB - untested and added for razer
|
||||
{ MAKE_CONTROLLER_ID( 0x1532, 0x1009 ), k_eControllerType_PS4Controller }, // Razer Raiju 2 Ultimate BT - untested and added for razer
|
||||
{ MAKE_CONTROLLER_ID( 0x1532, 0x1008 ), k_eControllerType_PS4Controller }, // Razer Panthera Evo Fightstick - untested and added for razer
|
||||
|
||||
{ MAKE_CONTROLLER_ID( 0x056e, 0x2004 ), k_eControllerType_XBox360Controller }, // Elecom JC-U3613M
|
||||
{ MAKE_CONTROLLER_ID( 0x06a3, 0xf51a ), k_eControllerType_XBox360Controller }, // Saitek P3600
|
||||
@@ -400,32 +360,42 @@ static const ControllerDescription_t arrControllers[] = {
|
||||
{ MAKE_CONTROLLER_ID( 0x0079, 0x187c ), k_eControllerType_XBox360Controller }, // Unknown Controller
|
||||
{ MAKE_CONTROLLER_ID( 0x0079, 0x189c ), k_eControllerType_XBox360Controller }, // Unknown Controller
|
||||
{ MAKE_CONTROLLER_ID( 0x0079, 0x1874 ), k_eControllerType_XBox360Controller }, // Unknown Controller
|
||||
|
||||
{ MAKE_CONTROLLER_ID( 0x1038, 0xb360 ), k_eControllerType_XBox360Controller }, // SteelSeries Nimbus/Stratus XL
|
||||
|
||||
|
||||
//{ MAKE_CONTROLLER_ID( 0x1949, 0x0402 ), /*android*/ }, // Unknown Controller
|
||||
|
||||
{ MAKE_CONTROLLER_ID( 0x05ac, 0x0001 ), k_eControllerType_AppleController }, // MFI Extended Gamepad (generic entry for iOS/tvOS)
|
||||
{ MAKE_CONTROLLER_ID( 0x05ac, 0x0002 ), k_eControllerType_AppleController }, // MFI Standard Gamepad (generic entry for iOS/tvOS)
|
||||
{ MAKE_CONTROLLER_ID( 0x1038, 0xb360 ), k_eControllerType_AppleController }, // SteelSeries Nimbus
|
||||
|
||||
// We currently don't support using a pair of Switch Joy-Con's as a single
|
||||
// controller and we don't want to support using them individually for the
|
||||
// time being, so these should be disabled until one of the above is true
|
||||
// { MAKE_CONTROLLER_ID( 0x057e, 0x2006 ), k_eControllerType_SwitchJoyConLeft }, // Nintendo Switch Joy-Con (Left)
|
||||
// { MAKE_CONTROLLER_ID( 0x057e, 0x2007 ), k_eControllerType_SwitchJoyConRight }, // Nintendo Switch Joy-Con (Right)
|
||||
|
||||
// This same controller ID is spoofed by many 3rd-party Switch controllers.
|
||||
// The ones we currently know of are:
|
||||
// * Any 8bitdo controller with Switch support
|
||||
// * ORTZ Gaming Wireless Pro Controller
|
||||
// * ZhiXu Gamepad Wireless
|
||||
// * Sunwaytek Wireless Motion Controller for Nintendo Switch
|
||||
{ MAKE_CONTROLLER_ID( 0x057e, 0x2009 ), k_eControllerType_SwitchProController }, // Nintendo Switch Pro Controller
|
||||
|
||||
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00c1 ), k_eControllerType_SwitchInputOnlyController }, // HORIPAD for Nintendo Switch
|
||||
{ MAKE_CONTROLLER_ID( 0x20d6, 0xa711 ), k_eControllerType_SwitchInputOnlyController }, // PowerA Wired Controller Plus
|
||||
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0092 ), k_eControllerType_SwitchInputOnlyController }, // HORI Pokken Tournament DX Pro Pad
|
||||
|
||||
|
||||
// Valve products - don't add to public list
|
||||
{ MAKE_CONTROLLER_ID( 0x0000, 0x11fa ), k_eControllerType_MobileTouch }, // Streaming mobile touch virtual controls
|
||||
{ MAKE_CONTROLLER_ID( 0x0000, 0x11fb ), k_eControllerType_MobileTouch }, // Streaming mobile touch virtual controls
|
||||
{ MAKE_CONTROLLER_ID( 0x28de, 0x1101 ), k_eControllerType_SteamController }, // Valve Legacy Steam Controller (CHELL)
|
||||
{ MAKE_CONTROLLER_ID( 0x28de, 0x1102 ), k_eControllerType_SteamController }, // Valve wired Steam Controller (D0G)
|
||||
{ MAKE_CONTROLLER_ID( 0x28de, 0x1105 ), k_eControllerType_SteamControllerV2 }, // Valve Bluetooth Steam Controller (D0G)
|
||||
{ MAKE_CONTROLLER_ID( 0x28de, 0x1106 ), k_eControllerType_SteamControllerV2 }, // Valve Bluetooth Steam Controller (D0G)
|
||||
{ MAKE_CONTROLLER_ID( 0x28de, 0x1142 ), k_eControllerType_SteamController }, // Valve wireless Steam Controller
|
||||
{ MAKE_CONTROLLER_ID( 0x28de, 0x1201 ), k_eControllerType_SteamController }, // Valve wired Steam Controller (HEADCRAB)
|
||||
{ MAKE_CONTROLLER_ID( 0x28de, 0x1202 ), k_eControllerType_SteamControllerV2 }, // Valve Bluetooth Steam Controller (HEADCRAB)
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -700,6 +700,12 @@ DARWIN_JoystickGetDeviceName(int device_index)
|
||||
return device ? device->product : "UNKNOWN";
|
||||
}
|
||||
|
||||
static int
|
||||
DARWIN_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static SDL_JoystickGUID
|
||||
DARWIN_JoystickGetDeviceGUID( int device_index )
|
||||
{
|
||||
@@ -998,6 +1004,7 @@ SDL_JoystickDriver SDL_DARWIN_JoystickDriver =
|
||||
DARWIN_JoystickGetCount,
|
||||
DARWIN_JoystickDetect,
|
||||
DARWIN_JoystickGetDeviceName,
|
||||
DARWIN_JoystickGetDevicePlayerIndex,
|
||||
DARWIN_JoystickGetDeviceGUID,
|
||||
DARWIN_JoystickGetDeviceInstanceID,
|
||||
DARWIN_JoystickOpen,
|
||||
|
||||
@@ -52,6 +52,12 @@ DUMMY_JoystickGetDeviceName(int device_index)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
DUMMY_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static SDL_JoystickGUID
|
||||
DUMMY_JoystickGetDeviceGUID(int device_index)
|
||||
{
|
||||
@@ -99,6 +105,7 @@ SDL_JoystickDriver SDL_DUMMY_JoystickDriver =
|
||||
DUMMY_JoystickGetCount,
|
||||
DUMMY_JoystickDetect,
|
||||
DUMMY_JoystickGetDeviceName,
|
||||
DUMMY_JoystickGetDevicePlayerIndex,
|
||||
DUMMY_JoystickGetDeviceGUID,
|
||||
DUMMY_JoystickGetDeviceInstanceID,
|
||||
DUMMY_JoystickOpen,
|
||||
|
||||
@@ -279,6 +279,12 @@ EMSCRIPTEN_JoystickGetDeviceName(int device_index)
|
||||
return JoystickByDeviceIndex(device_index)->name;
|
||||
}
|
||||
|
||||
static int
|
||||
EMSCRIPTEN_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static SDL_JoystickID
|
||||
EMSCRIPTEN_JoystickGetDeviceInstanceID(int device_index)
|
||||
{
|
||||
@@ -394,6 +400,7 @@ SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver =
|
||||
EMSCRIPTEN_JoystickGetCount,
|
||||
EMSCRIPTEN_JoystickDetect,
|
||||
EMSCRIPTEN_JoystickGetDeviceName,
|
||||
EMSCRIPTEN_JoystickGetDevicePlayerIndex,
|
||||
EMSCRIPTEN_JoystickGetDeviceGUID,
|
||||
EMSCRIPTEN_JoystickGetDeviceInstanceID,
|
||||
EMSCRIPTEN_JoystickOpen,
|
||||
@@ -404,3 +411,5 @@ SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver =
|
||||
};
|
||||
|
||||
#endif /* SDL_JOYSTICK_EMSCRIPTEN */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -36,7 +36,7 @@ extern "C"
|
||||
|
||||
|
||||
/* The maximum number of joysticks we'll detect */
|
||||
#define MAX_JOYSTICKS 16
|
||||
#define MAX_JOYSTICKS 16
|
||||
|
||||
/* A list of available joysticks */
|
||||
static char *SDL_joyport[MAX_JOYSTICKS];
|
||||
@@ -99,6 +99,11 @@ extern "C"
|
||||
return SDL_joyname[device_index];
|
||||
}
|
||||
|
||||
static int HAIKU_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Function to perform the mapping from device index to the instance id for this index */
|
||||
static SDL_JoystickID HAIKU_JoystickGetDeviceInstanceID(int device_index)
|
||||
{
|
||||
@@ -256,6 +261,7 @@ extern "C"
|
||||
HAIKU_JoystickGetCount,
|
||||
HAIKU_JoystickDetect,
|
||||
HAIKU_JoystickGetDeviceName,
|
||||
HAIKU_JoystickGetDevicePlayerIndex,
|
||||
HAIKU_JoystickGetDeviceGUID,
|
||||
HAIKU_JoystickGetDeviceInstanceID,
|
||||
HAIKU_JoystickOpen,
|
||||
|
||||
@@ -140,7 +140,7 @@ static Uint32 crc32(Uint32 crc, const void *data, int count)
|
||||
return crc;
|
||||
}
|
||||
|
||||
#ifdef __WIN32__
|
||||
#if defined(__WIN32__) && defined(HAVE_ENDPOINTVOLUME_H)
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
|
||||
#ifndef NTDDI_VISTA
|
||||
@@ -162,9 +162,9 @@ static Uint32 crc32(Uint32 crc, const void *data, int count)
|
||||
|
||||
#undef DEFINE_GUID
|
||||
#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) static const GUID n = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
|
||||
DEFINE_GUID(CLSID_MMDeviceEnumerator, 0xBCDE0395, 0xE52F, 0x467C, 0x8E, 0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E);
|
||||
DEFINE_GUID(IID_IMMDeviceEnumerator, 0xA95664D2, 0x9614, 0x4F35, 0xA7, 0x46, 0xDE, 0x8D, 0xB6, 0x36, 0x17, 0xE6);
|
||||
DEFINE_GUID(IID_IAudioEndpointVolume, 0x5CDF2C82, 0x841E, 0x4546, 0x97, 0x22, 0x0C, 0xF7, 0x40, 0x78, 0x22, 0x9A);
|
||||
DEFINE_GUID(SDL_CLSID_MMDeviceEnumerator, 0xBCDE0395, 0xE52F, 0x467C, 0x8E, 0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E);
|
||||
DEFINE_GUID(SDL_IID_IMMDeviceEnumerator, 0xA95664D2, 0x9614, 0x4F35, 0xA7, 0x46, 0xDE, 0x8D, 0xB6, 0x36, 0x17, 0xE6);
|
||||
DEFINE_GUID(SDL_IID_IAudioEndpointVolume, 0x5CDF2C82, 0x841E, 0x4546, 0x97, 0x22, 0x0C, 0xF7, 0x40, 0x78, 0x22, 0x9A);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -173,13 +173,13 @@ static float GetSystemVolume(void)
|
||||
{
|
||||
float volume = -1.0f; /* Return this if we can't get system volume */
|
||||
|
||||
#ifdef __WIN32__
|
||||
#if defined(__WIN32__) && defined(HAVE_ENDPOINTVOLUME_H)
|
||||
HRESULT hr = WIN_CoInitialize();
|
||||
if (SUCCEEDED(hr)) {
|
||||
IMMDeviceEnumerator *pEnumerator;
|
||||
|
||||
/* This should gracefully fail on XP and succeed on everything Vista and above */
|
||||
hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &IID_IMMDeviceEnumerator, (LPVOID*)&pEnumerator);
|
||||
hr = CoCreateInstance(&SDL_CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &SDL_IID_IMMDeviceEnumerator, (LPVOID*)&pEnumerator);
|
||||
if (SUCCEEDED(hr)) {
|
||||
IMMDevice *pDevice;
|
||||
|
||||
@@ -187,7 +187,7 @@ static float GetSystemVolume(void)
|
||||
if (SUCCEEDED(hr)) {
|
||||
IAudioEndpointVolume *pEndpointVolume;
|
||||
|
||||
hr = IMMDevice_Activate(pDevice, &IID_IAudioEndpointVolume, CLSCTX_ALL, NULL, (LPVOID*)&pEndpointVolume);
|
||||
hr = IMMDevice_Activate(pDevice, &SDL_IID_IAudioEndpointVolume, CLSCTX_ALL, NULL, (LPVOID*)&pEndpointVolume);
|
||||
if (SUCCEEDED(hr)) {
|
||||
IAudioEndpointVolume_GetMasterVolumeLevelScalar(pEndpointVolume, &volume);
|
||||
IUnknown_Release(pEndpointVolume);
|
||||
|
||||
@@ -35,23 +35,41 @@
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_XBOX360
|
||||
|
||||
#ifdef __WIN32__
|
||||
#define SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT
|
||||
/* This requires the Windows 10 SDK to build */
|
||||
/*#define SDL_JOYSTICK_HIDAPI_WINDOWS_GAMING_INPUT*/
|
||||
#endif
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT
|
||||
#include "../../core/windows/SDL_xinput.h"
|
||||
#endif
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_GAMING_INPUT
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#define COBJMACROS
|
||||
#include "windows.gaming.input.h"
|
||||
#endif
|
||||
|
||||
#define USB_PACKET_LENGTH 64
|
||||
|
||||
|
||||
typedef struct {
|
||||
Uint8 last_state[USB_PACKET_LENGTH];
|
||||
Uint32 rumble_expiration;
|
||||
#ifdef __WIN32__
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT
|
||||
SDL_bool xinput_enabled;
|
||||
Uint8 xinput_slot;
|
||||
#endif
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_GAMING_INPUT
|
||||
SDL_bool coinitialized;
|
||||
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics *gamepad_statics;
|
||||
__x_ABI_CWindows_CGaming_CInput_CIGamepad *gamepad;
|
||||
struct __x_ABI_CWindows_CGaming_CInput_CGamepadVibration vibration;
|
||||
#endif
|
||||
} SDL_DriverXbox360_Context;
|
||||
|
||||
|
||||
#ifdef __WIN32__
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT
|
||||
static Uint8 xinput_slots;
|
||||
|
||||
static void
|
||||
@@ -104,7 +122,129 @@ HIDAPI_DriverXbox360_GuessXInputSlot(WORD wButtons)
|
||||
return XUSER_INDEX_ANY;
|
||||
}
|
||||
|
||||
#endif /* __WIN32__ */
|
||||
#endif /* SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT */
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_GAMING_INPUT
|
||||
|
||||
static void
|
||||
HIDAPI_DriverXbox360_InitWindowsGamingInput(SDL_DriverXbox360_Context *ctx)
|
||||
{
|
||||
/* I think this takes care of RoInitialize() in a way that is compatible with the rest of SDL */
|
||||
if (FAILED(WIN_CoInitialize())) {
|
||||
return;
|
||||
}
|
||||
ctx->coinitialized = SDL_TRUE;
|
||||
|
||||
{
|
||||
static const IID SDL_IID_IGamepadStatics = { 0x8BBCE529, 0xD49C, 0x39E9, { 0x95, 0x60, 0xE4, 0x7D, 0xDE, 0x96, 0xB7, 0xC8 } };
|
||||
HRESULT hr;
|
||||
HMODULE hModule = LoadLibraryA("combase.dll");
|
||||
if (hModule != NULL) {
|
||||
typedef HRESULT (WINAPI *WindowsCreateString_t)(PCNZWCH sourceString, UINT32 length, HSTRING* string);
|
||||
typedef HRESULT (WINAPI *WindowsDeleteString_t)(HSTRING string);
|
||||
typedef HRESULT (WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void** factory);
|
||||
|
||||
WindowsCreateString_t WindowsCreateStringFunc = (WindowsCreateString_t)GetProcAddress(hModule, "WindowsCreateString");
|
||||
WindowsDeleteString_t WindowsDeleteStringFunc = (WindowsDeleteString_t)GetProcAddress(hModule, "WindowsDeleteString");
|
||||
RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory");
|
||||
if (WindowsCreateStringFunc && WindowsDeleteStringFunc && RoGetActivationFactoryFunc) {
|
||||
LPTSTR pNamespace = L"Windows.Gaming.Input.Gamepad";
|
||||
HSTRING hNamespaceString;
|
||||
|
||||
hr = WindowsCreateStringFunc(pNamespace, SDL_wcslen(pNamespace), &hNamespaceString);
|
||||
if (SUCCEEDED(hr)) {
|
||||
RoGetActivationFactoryFunc(hNamespaceString, &SDL_IID_IGamepadStatics, &ctx->gamepad_statics);
|
||||
WindowsDeleteStringFunc(hNamespaceString);
|
||||
}
|
||||
}
|
||||
FreeLibrary(hModule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Uint8
|
||||
HIDAPI_DriverXbox360_GetGamepadButtonsForMatch(__x_ABI_CWindows_CGaming_CInput_CIGamepad *gamepad)
|
||||
{
|
||||
HRESULT hr;
|
||||
struct __x_ABI_CWindows_CGaming_CInput_CGamepadReading state;
|
||||
Uint8 buttons = 0;
|
||||
|
||||
hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_GetCurrentReading(gamepad, &state);
|
||||
if (SUCCEEDED(hr)) {
|
||||
if (state.Buttons & GamepadButtons_A) {
|
||||
buttons |= (1 << SDL_CONTROLLER_BUTTON_A);
|
||||
}
|
||||
if (state.Buttons & GamepadButtons_B) {
|
||||
buttons |= (1 << SDL_CONTROLLER_BUTTON_B);
|
||||
}
|
||||
if (state.Buttons & GamepadButtons_X) {
|
||||
buttons |= (1 << SDL_CONTROLLER_BUTTON_X);
|
||||
}
|
||||
if (state.Buttons & GamepadButtons_Y) {
|
||||
buttons |= (1 << SDL_CONTROLLER_BUTTON_Y);
|
||||
}
|
||||
}
|
||||
return buttons;
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverXbox360_GuessGamepad(SDL_DriverXbox360_Context *ctx, Uint8 buttons)
|
||||
{
|
||||
HRESULT hr;
|
||||
__FIVectorView_1_Windows__CGaming__CInput__CGamepad *gamepads;
|
||||
|
||||
hr = __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_get_Gamepads(ctx->gamepad_statics, &gamepads);
|
||||
if (SUCCEEDED(hr)) {
|
||||
unsigned int i, num_gamepads;
|
||||
|
||||
hr = __FIVectorView_1_Windows__CGaming__CInput__CGamepad_get_Size(gamepads, &num_gamepads);
|
||||
if (SUCCEEDED(hr)) {
|
||||
int match_count;
|
||||
unsigned int match_slot;
|
||||
|
||||
match_count = 0;
|
||||
for (i = 0; i < num_gamepads; ++i) {
|
||||
__x_ABI_CWindows_CGaming_CInput_CIGamepad *gamepad;
|
||||
|
||||
hr = __FIVectorView_1_Windows__CGaming__CInput__CGamepad_GetAt(gamepads, i, &gamepad);
|
||||
if (SUCCEEDED(hr)) {
|
||||
Uint8 gamepad_buttons = HIDAPI_DriverXbox360_GetGamepadButtonsForMatch(gamepad);
|
||||
if (buttons == gamepad_buttons) {
|
||||
++match_count;
|
||||
match_slot = i;
|
||||
}
|
||||
__x_ABI_CWindows_CGaming_CInput_CIGamepad_Release(gamepad);
|
||||
}
|
||||
}
|
||||
if (match_count == 1) {
|
||||
hr = __FIVectorView_1_Windows__CGaming__CInput__CGamepad_GetAt(gamepads, match_slot, &ctx->gamepad);
|
||||
if (SUCCEEDED(hr)) {
|
||||
}
|
||||
}
|
||||
}
|
||||
__FIVectorView_1_Windows__CGaming__CInput__CGamepad_Release(gamepads);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverXbox360_QuitWindowsGamingInput(SDL_DriverXbox360_Context *ctx)
|
||||
{
|
||||
if (ctx->gamepad_statics) {
|
||||
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_Release(ctx->gamepad_statics);
|
||||
ctx->gamepad_statics = NULL;
|
||||
}
|
||||
if (ctx->gamepad) {
|
||||
__x_ABI_CWindows_CGaming_CInput_CIGamepad_Release(ctx->gamepad);
|
||||
ctx->gamepad = NULL;
|
||||
}
|
||||
|
||||
if (ctx->coinitialized) {
|
||||
WIN_CoUninitialize();
|
||||
ctx->coinitialized = SDL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_JOYSTICK_HIDAPI_WINDOWS_GAMING_INPUT */
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverXbox360_IsSupportedDevice(Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number)
|
||||
@@ -146,12 +286,15 @@ HIDAPI_DriverXbox360_Init(SDL_Joystick *joystick, hid_device *dev, Uint16 vendor
|
||||
SDL_OutOfMemory();
|
||||
return SDL_FALSE;
|
||||
}
|
||||
#ifdef __WIN32__
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT
|
||||
ctx->xinput_enabled = SDL_GetHintBoolean(SDL_HINT_XINPUT_ENABLED, SDL_TRUE);
|
||||
if (ctx->xinput_enabled && WIN_LoadXInputDLL() < 0) {
|
||||
ctx->xinput_enabled = SDL_FALSE;
|
||||
}
|
||||
ctx->xinput_slot = XUSER_INDEX_ANY;
|
||||
#endif
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_GAMING_INPUT
|
||||
HIDAPI_DriverXbox360_InitWindowsGamingInput(ctx);
|
||||
#endif
|
||||
*context = ctx;
|
||||
|
||||
@@ -170,8 +313,25 @@ static int
|
||||
HIDAPI_DriverXbox360_Rumble(SDL_Joystick *joystick, hid_device *dev, void *context, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
|
||||
{
|
||||
SDL_DriverXbox360_Context *ctx = (SDL_DriverXbox360_Context *)context;
|
||||
|
||||
#ifdef __WIN32__
|
||||
if (ctx->xinput_slot != XUSER_INDEX_ANY) {
|
||||
SDL_bool rumbled = SDL_FALSE;
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_GAMING_INPUT
|
||||
if (!rumbled && ctx->gamepad) {
|
||||
HRESULT hr;
|
||||
|
||||
ctx->vibration.LeftMotor = (DOUBLE)low_frequency_rumble / SDL_MAX_UINT16;
|
||||
ctx->vibration.RightMotor = (DOUBLE)high_frequency_rumble / SDL_MAX_UINT16;
|
||||
hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(ctx->gamepad, ctx->vibration);
|
||||
if (SUCCEEDED(hr)) {
|
||||
rumbled = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT
|
||||
if (!rumbled && ctx->xinput_slot != XUSER_INDEX_ANY) {
|
||||
XINPUT_VIBRATION XVibration;
|
||||
|
||||
if (!XINPUTSETSTATE) {
|
||||
@@ -180,11 +340,16 @@ HIDAPI_DriverXbox360_Rumble(SDL_Joystick *joystick, hid_device *dev, void *conte
|
||||
|
||||
XVibration.wLeftMotorSpeed = low_frequency_rumble;
|
||||
XVibration.wRightMotorSpeed = high_frequency_rumble;
|
||||
if (XINPUTSETSTATE(ctx->xinput_slot, &XVibration) != ERROR_SUCCESS) {
|
||||
if (XINPUTSETSTATE(ctx->xinput_slot, &XVibration) == ERROR_SUCCESS) {
|
||||
rumbled = SDL_TRUE;
|
||||
} else {
|
||||
return SDL_SetError("XInputSetState() failed");
|
||||
}
|
||||
}
|
||||
#else
|
||||
#endif /* SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT */
|
||||
|
||||
#else /* !__WIN32__ */
|
||||
|
||||
#ifdef __MACOSX__
|
||||
/* On Mac OS X the 360Controller driver uses this short report,
|
||||
and we need to prefix it with a magic token so hidapi passes it through untouched
|
||||
@@ -217,11 +382,14 @@ HIDAPI_DriverXbox360_Rumble(SDL_Joystick *joystick, hid_device *dev, void *conte
|
||||
/* This is the packet format for Xbox 360 and Xbox One controllers on Windows,
|
||||
however with this interface there is no rumble support, no guide button,
|
||||
and the left and right triggers are tied together as a single axis.
|
||||
|
||||
We use XInput and Windows.Gaming.Input to make up for these shortcomings.
|
||||
*/
|
||||
static void
|
||||
HIDAPI_DriverXbox360_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverXbox360_Context *ctx, Uint8 *data, int size)
|
||||
{
|
||||
Sint16 axis;
|
||||
SDL_bool has_trigger_data = SDL_FALSE;
|
||||
|
||||
if (ctx->last_state[10] != data[10]) {
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[10] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
|
||||
@@ -290,31 +458,81 @@ HIDAPI_DriverXbox360_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev,
|
||||
axis = (int)*(Uint16*)(&data[6]) - 0x8000;
|
||||
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
|
||||
|
||||
if (ctx->xinput_slot == XUSER_INDEX_ANY && HIDAPI_DriverXbox360_MissingXInputSlot()) {
|
||||
WORD wButtons = 0;
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_GAMING_INPUT
|
||||
if (ctx->gamepad_statics && !ctx->gamepad) {
|
||||
Uint8 buttons = 0;
|
||||
|
||||
if (data[10] & 0x01) {
|
||||
wButtons |= XINPUT_GAMEPAD_A;
|
||||
buttons |= (1 << SDL_CONTROLLER_BUTTON_A);
|
||||
}
|
||||
if (data[10] & 0x02) {
|
||||
wButtons |= XINPUT_GAMEPAD_B;
|
||||
buttons |= (1 << SDL_CONTROLLER_BUTTON_B);
|
||||
}
|
||||
if (data[10] & 0x04) {
|
||||
wButtons |= XINPUT_GAMEPAD_X;
|
||||
buttons |= (1 << SDL_CONTROLLER_BUTTON_X);
|
||||
}
|
||||
if (data[10] & 0x08) {
|
||||
wButtons |= XINPUT_GAMEPAD_Y;
|
||||
buttons |= (1 << SDL_CONTROLLER_BUTTON_Y);
|
||||
}
|
||||
if (wButtons != 0) {
|
||||
Uint8 xinput_slot = HIDAPI_DriverXbox360_GuessXInputSlot(wButtons);
|
||||
if (xinput_slot != XUSER_INDEX_ANY) {
|
||||
HIDAPI_DriverXbox360_MarkXInputSlotUsed(xinput_slot);
|
||||
ctx->xinput_slot = xinput_slot;
|
||||
}
|
||||
if (buttons != 0) {
|
||||
HIDAPI_DriverXbox360_GuessGamepad(ctx, buttons);
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->xinput_slot == XUSER_INDEX_ANY) {
|
||||
if (ctx->gamepad) {
|
||||
HRESULT hr;
|
||||
struct __x_ABI_CWindows_CGaming_CInput_CGamepadReading state;
|
||||
|
||||
hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_GetCurrentReading(ctx->gamepad, &state);
|
||||
if (SUCCEEDED(hr)) {
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (state.Buttons & 0x40000000) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, ((int)(state.LeftTrigger * SDL_MAX_UINT16)) - 32768);
|
||||
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, ((int)(state.RightTrigger * SDL_MAX_UINT16)) - 32768);
|
||||
has_trigger_data = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
#endif /* SDL_JOYSTICK_HIDAPI_WINDOWS_GAMING_INPUT */
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT
|
||||
if (ctx->xinput_enabled) {
|
||||
if (ctx->xinput_slot == XUSER_INDEX_ANY && HIDAPI_DriverXbox360_MissingXInputSlot()) {
|
||||
WORD wButtons = 0;
|
||||
|
||||
if (data[10] & 0x01) {
|
||||
wButtons |= XINPUT_GAMEPAD_A;
|
||||
}
|
||||
if (data[10] & 0x02) {
|
||||
wButtons |= XINPUT_GAMEPAD_B;
|
||||
}
|
||||
if (data[10] & 0x04) {
|
||||
wButtons |= XINPUT_GAMEPAD_X;
|
||||
}
|
||||
if (data[10] & 0x08) {
|
||||
wButtons |= XINPUT_GAMEPAD_Y;
|
||||
}
|
||||
if (wButtons != 0) {
|
||||
Uint8 xinput_slot = HIDAPI_DriverXbox360_GuessXInputSlot(wButtons);
|
||||
if (xinput_slot != XUSER_INDEX_ANY) {
|
||||
HIDAPI_DriverXbox360_MarkXInputSlotUsed(xinput_slot);
|
||||
ctx->xinput_slot = xinput_slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_trigger_data && ctx->xinput_slot != XUSER_INDEX_ANY) {
|
||||
XINPUT_STATE_EX xinput_state;
|
||||
|
||||
if (XINPUTGETSTATE(ctx->xinput_slot, &xinput_state) == ERROR_SUCCESS) {
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (xinput_state.Gamepad.wButtons & XINPUT_GAMEPAD_GUIDE) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, ((int)xinput_state.Gamepad.bLeftTrigger * 257) - 32768);
|
||||
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, ((int)xinput_state.Gamepad.bRightTrigger * 257) - 32768);
|
||||
has_trigger_data = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT */
|
||||
|
||||
if (!has_trigger_data) {
|
||||
axis = (data[9] * 257) - 32768;
|
||||
if (data[9] < 0x80) {
|
||||
axis = -axis * 2 - 32769;
|
||||
@@ -326,14 +544,6 @@ HIDAPI_DriverXbox360_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev,
|
||||
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, SDL_MIN_SINT16);
|
||||
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, SDL_MIN_SINT16);
|
||||
}
|
||||
} else {
|
||||
XINPUT_STATE_EX xinput_state;
|
||||
|
||||
if (XINPUTGETSTATE(ctx->xinput_slot, &xinput_state) == ERROR_SUCCESS) {
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (xinput_state.Gamepad.wButtons & XINPUT_GAMEPAD_GUIDE) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, ((int)xinput_state.Gamepad.bLeftTrigger * 257) - 32768);
|
||||
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, ((int)xinput_state.Gamepad.bRightTrigger * 257) - 32768);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
|
||||
@@ -542,13 +752,18 @@ HIDAPI_DriverXbox360_Update(SDL_Joystick *joystick, hid_device *dev, void *conte
|
||||
static void
|
||||
HIDAPI_DriverXbox360_Quit(SDL_Joystick *joystick, hid_device *dev, void *context)
|
||||
{
|
||||
#ifdef __WIN32__
|
||||
#if defined(SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT) || defined(SDL_JOYSTICK_HIDAPI_WINDOWS_GAMING_INPUT)
|
||||
SDL_DriverXbox360_Context *ctx = (SDL_DriverXbox360_Context *)context;
|
||||
#endif
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_XINPUT
|
||||
if (ctx->xinput_enabled) {
|
||||
HIDAPI_DriverXbox360_MarkXInputSlotFree(ctx->xinput_slot);
|
||||
WIN_UnloadXInputDLL();
|
||||
}
|
||||
#endif
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_WINDOWS_GAMING_INPUT
|
||||
HIDAPI_DriverXbox360_InitWindowsGamingInput(ctx);
|
||||
#endif
|
||||
SDL_free(context);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "SDL_endian.h"
|
||||
#include "SDL_hints.h"
|
||||
#include "SDL_log.h"
|
||||
#include "SDL_mutex.h"
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_timer.h"
|
||||
#include "SDL_joystick.h"
|
||||
@@ -54,6 +55,7 @@ struct joystick_hwdata
|
||||
SDL_HIDAPI_DeviceDriver *driver;
|
||||
void *context;
|
||||
|
||||
SDL_mutex *mutex;
|
||||
hid_device *dev;
|
||||
};
|
||||
|
||||
@@ -97,6 +99,10 @@ static SDL_HIDAPI_DeviceDriver *SDL_HIDAPI_drivers[] = {
|
||||
static SDL_HIDAPI_Device *SDL_HIDAPI_devices;
|
||||
static int SDL_HIDAPI_numjoysticks = 0;
|
||||
|
||||
#if defined(SDL_USE_LIBUDEV)
|
||||
static const SDL_UDEV_Symbols * usyms = NULL;
|
||||
#endif
|
||||
|
||||
static struct
|
||||
{
|
||||
SDL_bool m_bHaveDevicesChanged;
|
||||
@@ -272,13 +278,16 @@ HIDAPI_InitializeDiscovery()
|
||||
SDL_HIDAPI_discovery.m_pUdevMonitor = NULL;
|
||||
SDL_HIDAPI_discovery.m_nUdevFd = -1;
|
||||
|
||||
SDL_HIDAPI_discovery.m_pUdev = udev_new();
|
||||
usyms = SDL_UDEV_GetUdevSyms();
|
||||
if (usyms) {
|
||||
SDL_HIDAPI_discovery.m_pUdev = usyms->udev_new();
|
||||
}
|
||||
if (SDL_HIDAPI_discovery.m_pUdev) {
|
||||
SDL_HIDAPI_discovery.m_pUdevMonitor = udev_monitor_new_from_netlink(SDL_HIDAPI_discovery.m_pUdev, "udev");
|
||||
SDL_HIDAPI_discovery.m_pUdevMonitor = usyms->udev_monitor_new_from_netlink(SDL_HIDAPI_discovery.m_pUdev, "udev");
|
||||
if (SDL_HIDAPI_discovery.m_pUdevMonitor) {
|
||||
udev_monitor_enable_receiving(SDL_HIDAPI_discovery.m_pUdevMonitor);
|
||||
SDL_HIDAPI_discovery.m_nUdevFd = udev_monitor_get_fd(SDL_HIDAPI_discovery.m_pUdevMonitor);
|
||||
SDL_HIDAPI_discovery.m_bCanGetNotifications = true;
|
||||
usyms->udev_monitor_enable_receiving(SDL_HIDAPI_discovery.m_pUdevMonitor);
|
||||
SDL_HIDAPI_discovery.m_nUdevFd = usyms->udev_monitor_get_fd(SDL_HIDAPI_discovery.m_pUdevMonitor);
|
||||
SDL_HIDAPI_discovery.m_bCanGetNotifications = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,6 +308,7 @@ HIDAPI_UpdateDiscovery()
|
||||
}
|
||||
|
||||
#if defined(__WIN32__)
|
||||
#if 0 /* just let the usual SDL_PumpEvents loop dispatch these, fixing bug 4286. --ryan. */
|
||||
/* We'll only get messages on the same thread that created the window */
|
||||
if (SDL_ThreadID() == SDL_HIDAPI_discovery.m_nThreadID) {
|
||||
MSG msg;
|
||||
@@ -310,6 +320,7 @@ HIDAPI_UpdateDiscovery()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* __WIN32__ */
|
||||
|
||||
#if defined(__MACOSX__)
|
||||
if (SDL_HIDAPI_discovery.m_notificationPort) {
|
||||
@@ -329,6 +340,7 @@ HIDAPI_UpdateDiscovery()
|
||||
*/
|
||||
for (;;) {
|
||||
struct pollfd PollUdev;
|
||||
struct udev_device *pUdevDevice;
|
||||
|
||||
PollUdev.fd = SDL_HIDAPI_discovery.m_nUdevFd;
|
||||
PollUdev.events = POLLIN;
|
||||
@@ -336,11 +348,11 @@ HIDAPI_UpdateDiscovery()
|
||||
break;
|
||||
}
|
||||
|
||||
SDL_HIDAPI_discovery.m_bHaveDevicesChanged = true;
|
||||
SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_TRUE;
|
||||
|
||||
struct udev_device *pUdevDevice = udev_monitor_receive_device(SDL_HIDAPI_discovery.m_pUdevMonitor);
|
||||
pUdevDevice = usyms->udev_monitor_receive_device(SDL_HIDAPI_discovery.m_pUdevMonitor);
|
||||
if (pUdevDevice) {
|
||||
udev_device_unref(pUdevDevice);
|
||||
usyms->udev_device_unref(pUdevDevice);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -368,11 +380,15 @@ HIDAPI_ShutdownDiscovery()
|
||||
#endif
|
||||
|
||||
#if defined(SDL_USE_LIBUDEV)
|
||||
if (SDL_HIDAPI_discovery.m_pUdevMonitor) {
|
||||
udev_monitor_unref(SDL_HIDAPI_discovery.m_pUdevMonitor);
|
||||
}
|
||||
if (SDL_HIDAPI_discovery.m_pUdev) {
|
||||
udev_unref(SDL_HIDAPI_discovery.m_pUdev);
|
||||
if (usyms) {
|
||||
if (SDL_HIDAPI_discovery.m_pUdevMonitor) {
|
||||
usyms->udev_monitor_unref(SDL_HIDAPI_discovery.m_pUdevMonitor);
|
||||
}
|
||||
if (SDL_HIDAPI_discovery.m_pUdev) {
|
||||
usyms->udev_unref(SDL_HIDAPI_discovery.m_pUdev);
|
||||
}
|
||||
SDL_UDEV_ReleaseUdevSyms();
|
||||
usyms = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -735,15 +751,8 @@ HIDAPI_AddDevice(struct hid_device_info *info)
|
||||
device->guid.data[14] = 'h';
|
||||
device->guid.data[15] = 0;
|
||||
}
|
||||
device->driver = HIDAPI_GetDeviceDriver(device);
|
||||
|
||||
if (device->driver) {
|
||||
const char *name = device->driver->GetDeviceName(device->vendor_id, device->product_id);
|
||||
if (name) {
|
||||
device->name = SDL_strdup(name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Need the device name before getting the driver to know whether to ignore this device */
|
||||
if (!device->name && info->manufacturer_string && info->product_string) {
|
||||
char *manufacturer_string = SDL_iconv_string("UTF-8", "WCHAR_T", (char*)info->manufacturer_string, (SDL_wcslen(info->manufacturer_string)+1)*sizeof(wchar_t));
|
||||
char *product_string = SDL_iconv_string("UTF-8", "WCHAR_T", (char*)info->product_string, (SDL_wcslen(info->product_string)+1)*sizeof(wchar_t));
|
||||
@@ -780,6 +789,16 @@ HIDAPI_AddDevice(struct hid_device_info *info)
|
||||
SDL_snprintf(device->name, name_size, "0x%.4x/0x%.4x", info->vendor_id, info->product_id);
|
||||
}
|
||||
|
||||
device->driver = HIDAPI_GetDeviceDriver(device);
|
||||
|
||||
if (device->driver) {
|
||||
const char *name = device->driver->GetDeviceName(device->vendor_id, device->product_id);
|
||||
if (name) {
|
||||
SDL_free(device->name);
|
||||
device->name = SDL_strdup(name);
|
||||
}
|
||||
}
|
||||
|
||||
device->path = SDL_strdup(info->path);
|
||||
if (!device->path) {
|
||||
SDL_free(device->name);
|
||||
@@ -788,7 +807,7 @@ HIDAPI_AddDevice(struct hid_device_info *info)
|
||||
}
|
||||
|
||||
#ifdef DEBUG_HIDAPI
|
||||
SDL_Log("Adding HIDAPI device '%s' VID 0x%.4x, PID 0x%.4x, version %d, interface %d, usage page 0x%.4x, usage 0x%.4x\n", device->name, device->vendor_id, device->product_id, device->version, device->interface_number, device->usage_page, device->usage);
|
||||
SDL_Log("Adding HIDAPI device '%s' VID 0x%.4x, PID 0x%.4x, version %d, interface %d, usage page 0x%.4x, usage 0x%.4x, driver = %s\n", device->name, device->vendor_id, device->product_id, device->version, device->interface_number, device->usage_page, device->usage, device->driver ? device->driver->hint : "NONE");
|
||||
#endif
|
||||
|
||||
/* Add it to the list */
|
||||
@@ -915,6 +934,12 @@ HIDAPI_JoystickGetDeviceName(int device_index)
|
||||
return HIDAPI_GetJoystickByIndex(device_index)->name;
|
||||
}
|
||||
|
||||
static int
|
||||
HIDAPI_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static SDL_JoystickGUID
|
||||
HIDAPI_JoystickGetDeviceGUID(int device_index)
|
||||
{
|
||||
@@ -944,6 +969,7 @@ HIDAPI_JoystickOpen(SDL_Joystick * joystick, int device_index)
|
||||
SDL_free(hwdata);
|
||||
return SDL_SetError("Couldn't open HID device %s", device->path);
|
||||
}
|
||||
hwdata->mutex = SDL_CreateMutex();
|
||||
|
||||
if (!device->driver->Init(joystick, hwdata->dev, device->vendor_id, device->product_id, &hwdata->context)) {
|
||||
hid_close(hwdata->dev);
|
||||
@@ -960,7 +986,12 @@ HIDAPI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint
|
||||
{
|
||||
struct joystick_hwdata *hwdata = joystick->hwdata;
|
||||
SDL_HIDAPI_DeviceDriver *driver = hwdata->driver;
|
||||
return driver->Rumble(joystick, hwdata->dev, hwdata->context, low_frequency_rumble, high_frequency_rumble, duration_ms);
|
||||
int result;
|
||||
|
||||
SDL_LockMutex(hwdata->mutex);
|
||||
result = driver->Rumble(joystick, hwdata->dev, hwdata->context, low_frequency_rumble, high_frequency_rumble, duration_ms);
|
||||
SDL_UnlockMutex(hwdata->mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -968,7 +999,13 @@ HIDAPI_JoystickUpdate(SDL_Joystick * joystick)
|
||||
{
|
||||
struct joystick_hwdata *hwdata = joystick->hwdata;
|
||||
SDL_HIDAPI_DeviceDriver *driver = hwdata->driver;
|
||||
if (!driver->Update(joystick, hwdata->dev, hwdata->context)) {
|
||||
SDL_bool succeeded;
|
||||
|
||||
SDL_LockMutex(hwdata->mutex);
|
||||
succeeded = driver->Update(joystick, hwdata->dev, hwdata->context);
|
||||
SDL_UnlockMutex(hwdata->mutex);
|
||||
|
||||
if (!succeeded) {
|
||||
SDL_HIDAPI_Device *device;
|
||||
for (device = SDL_HIDAPI_devices; device; device = device->next) {
|
||||
if (device->instance_id == joystick->instance_id) {
|
||||
@@ -987,6 +1024,7 @@ HIDAPI_JoystickClose(SDL_Joystick * joystick)
|
||||
driver->Quit(joystick, hwdata->dev, hwdata->context);
|
||||
|
||||
hid_close(hwdata->dev);
|
||||
SDL_DestroyMutex(hwdata->mutex);
|
||||
SDL_free(hwdata);
|
||||
joystick->hwdata = NULL;
|
||||
}
|
||||
@@ -1018,6 +1056,7 @@ SDL_JoystickDriver SDL_HIDAPI_JoystickDriver =
|
||||
HIDAPI_JoystickGetCount,
|
||||
HIDAPI_JoystickDetect,
|
||||
HIDAPI_JoystickGetDeviceName,
|
||||
HIDAPI_JoystickGetDevicePlayerIndex,
|
||||
HIDAPI_JoystickGetDeviceGUID,
|
||||
HIDAPI_JoystickGetDeviceInstanceID,
|
||||
HIDAPI_JoystickOpen,
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
#ifdef __WINDOWS__
|
||||
/* On Windows, Xbox One controllers are handled by the Xbox 360 driver */
|
||||
#undef SDL_JOYSTICK_HIDAPI_XBOXONE
|
||||
/* It turns out HIDAPI for Xbox controllers doesn't allow background input */
|
||||
#undef SDL_JOYSTICK_HIDAPI_XBOX360
|
||||
#endif
|
||||
|
||||
#ifdef __MACOSX__
|
||||
|
||||
@@ -358,6 +358,12 @@ IOS_JoystickGetDeviceName(int device_index)
|
||||
return device ? device->name : "Unknown";
|
||||
}
|
||||
|
||||
static int
|
||||
IOS_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static SDL_JoystickGUID
|
||||
IOS_JoystickGetDeviceGUID( int device_index )
|
||||
{
|
||||
@@ -715,6 +721,7 @@ SDL_JoystickDriver SDL_IOS_JoystickDriver =
|
||||
IOS_JoystickGetCount,
|
||||
IOS_JoystickDetect,
|
||||
IOS_JoystickGetDeviceName,
|
||||
IOS_JoystickGetDevicePlayerIndex,
|
||||
IOS_JoystickGetDeviceGUID,
|
||||
IOS_JoystickGetDeviceInstanceID,
|
||||
IOS_JoystickOpen,
|
||||
|
||||
@@ -582,6 +582,12 @@ LINUX_JoystickGetDeviceName(int device_index)
|
||||
return JoystickByDevIndex(device_index)->name;
|
||||
}
|
||||
|
||||
static int
|
||||
LINUX_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static SDL_JoystickGUID
|
||||
LINUX_JoystickGetDeviceGUID( int device_index )
|
||||
{
|
||||
@@ -814,26 +820,24 @@ LINUX_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint1
|
||||
{
|
||||
struct input_event event;
|
||||
|
||||
if (joystick->hwdata->effect.id < 0) {
|
||||
if (joystick->hwdata->ff_rumble) {
|
||||
struct ff_effect *effect = &joystick->hwdata->effect;
|
||||
if (joystick->hwdata->ff_rumble) {
|
||||
struct ff_effect *effect = &joystick->hwdata->effect;
|
||||
|
||||
effect->type = FF_RUMBLE;
|
||||
effect->replay.length = SDL_min(duration_ms, 32767);
|
||||
effect->u.rumble.strong_magnitude = low_frequency_rumble;
|
||||
effect->u.rumble.weak_magnitude = high_frequency_rumble;
|
||||
} else if (joystick->hwdata->ff_sine) {
|
||||
/* Scale and average the two rumble strengths */
|
||||
Sint16 magnitude = (Sint16)(((low_frequency_rumble / 2) + (high_frequency_rumble / 2)) / 2);
|
||||
struct ff_effect *effect = &joystick->hwdata->effect;
|
||||
effect->type = FF_RUMBLE;
|
||||
effect->replay.length = SDL_min(duration_ms, 32767);
|
||||
effect->u.rumble.strong_magnitude = low_frequency_rumble;
|
||||
effect->u.rumble.weak_magnitude = high_frequency_rumble;
|
||||
} else if (joystick->hwdata->ff_sine) {
|
||||
/* Scale and average the two rumble strengths */
|
||||
Sint16 magnitude = (Sint16)(((low_frequency_rumble / 2) + (high_frequency_rumble / 2)) / 2);
|
||||
struct ff_effect *effect = &joystick->hwdata->effect;
|
||||
|
||||
effect->type = FF_PERIODIC;
|
||||
effect->replay.length = SDL_min(duration_ms, 32767);
|
||||
effect->u.periodic.waveform = FF_SINE;
|
||||
effect->u.periodic.magnitude = magnitude;
|
||||
} else {
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
effect->type = FF_PERIODIC;
|
||||
effect->replay.length = SDL_min(duration_ms, 32767);
|
||||
effect->u.periodic.waveform = FF_SINE;
|
||||
effect->u.periodic.magnitude = magnitude;
|
||||
} else {
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
if (ioctl(joystick->hwdata->fd, EVIOCSFF, &joystick->hwdata->effect) < 0) {
|
||||
@@ -1102,6 +1106,7 @@ SDL_JoystickDriver SDL_LINUX_JoystickDriver =
|
||||
LINUX_JoystickGetCount,
|
||||
LINUX_JoystickDetect,
|
||||
LINUX_JoystickGetDeviceName,
|
||||
LINUX_JoystickGetDevicePlayerIndex,
|
||||
LINUX_JoystickGetDeviceGUID,
|
||||
LINUX_JoystickGetDeviceInstanceID,
|
||||
LINUX_JoystickOpen,
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_sysjoystick_c_h_
|
||||
#define SDL_sysjoystick_c_h_
|
||||
|
||||
#include <linux/input.h>
|
||||
|
||||
struct SDL_joylist_item;
|
||||
@@ -61,4 +64,6 @@ struct joystick_hwdata
|
||||
SDL_bool m_bSteamController;
|
||||
};
|
||||
|
||||
#endif /* SDL_sysjoystick_c_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_steamcontroller_h_
|
||||
#define SDL_steamcontroller_h_
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
typedef SDL_bool (*SteamControllerConnectedCallback_t)(const char *name, SDL_JoystickGUID guid, int *device_instance);
|
||||
@@ -30,4 +34,6 @@ void SDL_UpdateSteamControllers(void);
|
||||
void SDL_UpdateSteamController(SDL_Joystick *joystick);
|
||||
void SDL_QuitSteamControllers(void);
|
||||
|
||||
#endif /* SDL_steamcontroller_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -255,7 +255,7 @@ SDL_JoystickThread(void *_data)
|
||||
/* WM_DEVICECHANGE not working, no XINPUT, no point in keeping thread alive */
|
||||
break;
|
||||
#endif /* SDL_JOYSTICK_XINPUT */
|
||||
}
|
||||
}
|
||||
|
||||
if (s_bWindowsDeviceChanged || bXInputChanged) {
|
||||
s_bDeviceRemoved = SDL_TRUE;
|
||||
@@ -407,6 +407,18 @@ WINDOWS_JoystickGetDeviceName(int device_index)
|
||||
return device->joystickname;
|
||||
}
|
||||
|
||||
static int
|
||||
WINDOWS_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
JoyStick_DeviceData *device = SYS_Joystick;
|
||||
int index;
|
||||
|
||||
for (index = device_index; index > 0; index--)
|
||||
device = device->pNext;
|
||||
|
||||
return device->bXInputDevice ? (int)device->XInputUserId : -1;
|
||||
}
|
||||
|
||||
/* return the stable device guid for this device index */
|
||||
static SDL_JoystickGUID
|
||||
WINDOWS_JoystickGetDeviceGUID(int device_index)
|
||||
@@ -544,6 +556,7 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver =
|
||||
WINDOWS_JoystickGetCount,
|
||||
WINDOWS_JoystickDetect,
|
||||
WINDOWS_JoystickGetDeviceName,
|
||||
WINDOWS_JoystickGetDevicePlayerIndex,
|
||||
WINDOWS_JoystickGetDeviceGUID,
|
||||
WINDOWS_JoystickGetDeviceInstanceID,
|
||||
WINDOWS_JoystickOpen,
|
||||
|
||||
@@ -312,6 +312,8 @@ SDL_XINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickde
|
||||
SDL_assert(XINPUTSETSTATE);
|
||||
SDL_assert(userId < XUSER_MAX_COUNT);
|
||||
|
||||
joystick->player_index = userId;
|
||||
|
||||
joystick->hwdata->bXInputDevice = SDL_TRUE;
|
||||
|
||||
if (XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities) != ERROR_SUCCESS) {
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef math_libm_h_
|
||||
#define math_libm_h_
|
||||
|
||||
#include "../SDL_internal.h"
|
||||
|
||||
/* Math routines from uClibc: http://www.uclibc.org */
|
||||
@@ -38,4 +42,6 @@ double SDL_uclibc_sin(double x);
|
||||
double SDL_uclibc_sqrt(double x);
|
||||
double SDL_uclibc_tan(double x);
|
||||
|
||||
#endif /* math_libm_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -198,7 +198,7 @@ public:
|
||||
_current_context->UnlockGL();
|
||||
_current_context = newContext;
|
||||
if (_current_context)
|
||||
_current_context->LockGL();
|
||||
_current_context->LockGL();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <storage/File.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "SDL_BApp.h" /* SDL_BApp class definition */
|
||||
#include "SDL_BApp.h" /* SDL_BApp class definition */
|
||||
#include "SDL_BeApp.h"
|
||||
#include "SDL_timer.h"
|
||||
#include "SDL_error.h"
|
||||
@@ -53,24 +53,24 @@ StartBeApp(void *unused)
|
||||
{
|
||||
BApplication *App;
|
||||
|
||||
// default application signature
|
||||
const char *signature = "application/x-SDL-executable";
|
||||
// dig resources for correct signature
|
||||
image_info info;
|
||||
int32 cookie = 0;
|
||||
if (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) {
|
||||
BFile f(info.name, O_RDONLY);
|
||||
if (f.InitCheck() == B_OK) {
|
||||
BAppFileInfo app_info(&f);
|
||||
if (app_info.InitCheck() == B_OK) {
|
||||
char sig[B_MIME_TYPE_LENGTH];
|
||||
if (app_info.GetSignature(sig) == B_OK)
|
||||
signature = strndup(sig, B_MIME_TYPE_LENGTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
// default application signature
|
||||
const char *signature = "application/x-SDL-executable";
|
||||
// dig resources for correct signature
|
||||
image_info info;
|
||||
int32 cookie = 0;
|
||||
if (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) {
|
||||
BFile f(info.name, O_RDONLY);
|
||||
if (f.InitCheck() == B_OK) {
|
||||
BAppFileInfo app_info(&f);
|
||||
if (app_info.InitCheck() == B_OK) {
|
||||
char sig[B_MIME_TYPE_LENGTH];
|
||||
if (app_info.GetSignature(sig) == B_OK)
|
||||
signature = strndup(sig, B_MIME_TYPE_LENGTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
App = new SDL_BApp(signature);
|
||||
App = new SDL_BApp(signature);
|
||||
|
||||
App->Run();
|
||||
delete App;
|
||||
@@ -144,12 +144,12 @@ SDL_QuitBeApp(void)
|
||||
|
||||
/* SDL_BApp functions */
|
||||
void SDL_BApp::ClearID(SDL_BWin *bwin) {
|
||||
_SetSDLWindow(NULL, bwin->GetID());
|
||||
int32 i = _GetNumWindowSlots() - 1;
|
||||
while(i >= 0 && GetSDLWindow(i) == NULL) {
|
||||
_PopBackWindow();
|
||||
--i;
|
||||
}
|
||||
_SetSDLWindow(NULL, bwin->GetID());
|
||||
int32 i = _GetNumWindowSlots() - 1;
|
||||
while(i >= 0 && GetSDLWindow(i) == NULL) {
|
||||
_PopBackWindow();
|
||||
--i;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __HAIKU__ */
|
||||
|
||||
@@ -116,51 +116,66 @@ OutOfMemory(void)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* WinMain, main, and wmain eventually call into here. */
|
||||
static int
|
||||
main_utf8(int argc, char *argv[])
|
||||
{
|
||||
SDL_SetMainReady();
|
||||
|
||||
/* Run the application main() code */
|
||||
return SDL_main(argc, argv);
|
||||
}
|
||||
|
||||
/* Gets the arguments with GetCommandLine, converts them to argc and argv
|
||||
and calls main_utf8 */
|
||||
and calls SDL_main */
|
||||
static int
|
||||
main_getcmdline()
|
||||
{
|
||||
SDL_bool isstack;
|
||||
char **argv;
|
||||
int argc;
|
||||
char *cmdline;
|
||||
char *cmdline = NULL;
|
||||
int retval = 0;
|
||||
int cmdalloc = 0;
|
||||
const TCHAR *text = GetCommandLine();
|
||||
const TCHAR *ptr;
|
||||
int argc_guess = 2; /* space for NULL and initial argument. */
|
||||
int rc;
|
||||
|
||||
/* make a rough guess of command line arguments. Overestimates if there
|
||||
are quoted things. */
|
||||
for (ptr = text; *ptr; ptr++) {
|
||||
if ((*ptr == ' ') || (*ptr == '\t')) {
|
||||
argc_guess++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Grab the command line */
|
||||
TCHAR *text = GetCommandLine();
|
||||
#if UNICODE
|
||||
cmdline = WIN_StringToUTF8(text);
|
||||
rc = WideCharToMultiByte(CP_UTF8, 0, text, -1, NULL, 0, NULL, NULL);
|
||||
if (rc > 0) {
|
||||
cmdalloc = rc + (sizeof (char *) * argc_guess);
|
||||
argv = (char **) VirtualAlloc(NULL, cmdalloc, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
|
||||
if (argv) {
|
||||
int rc2;
|
||||
cmdline = (char *) (argv + argc_guess);
|
||||
rc2 = WideCharToMultiByte(CP_UTF8, 0, text, -1, cmdline, rc, NULL, NULL);
|
||||
SDL_assert(rc2 == rc);
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* !!! FIXME: are these in the system codepage? We need to convert to UTF-8. */
|
||||
cmdline = SDL_strdup(text);
|
||||
rc = ((int) SDL_strlen(text)) + 1;
|
||||
cmdalloc = rc + (sizeof (char *) * argc_guess);
|
||||
argv = (char **) VirtualAlloc(NULL, cmdalloc, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
|
||||
if (argv) {
|
||||
cmdline = (char *) (argv + argc_guess);
|
||||
SDL_strcpy(cmdline, text);
|
||||
}
|
||||
#endif
|
||||
if (cmdline == NULL) {
|
||||
return OutOfMemory();
|
||||
}
|
||||
|
||||
/* Parse it into argv and argc */
|
||||
argc = ParseCommandLine(cmdline, NULL);
|
||||
argv = SDL_small_alloc(char *, argc + 1, &isstack);
|
||||
if (argv == NULL) {
|
||||
return OutOfMemory();
|
||||
}
|
||||
ParseCommandLine(cmdline, argv);
|
||||
SDL_assert(ParseCommandLine(cmdline, NULL) <= argc_guess);
|
||||
argc = ParseCommandLine(cmdline, argv);
|
||||
|
||||
retval = main_utf8(argc, argv);
|
||||
SDL_SetMainReady();
|
||||
|
||||
SDL_small_free(argv, isstack);
|
||||
SDL_free(cmdline);
|
||||
/* Run the application main() code */
|
||||
retval = SDL_main(argc, argv);
|
||||
|
||||
VirtualFree(argv, cmdalloc, MEM_DECOMMIT);
|
||||
VirtualFree(argv, 0, MEM_RELEASE);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -178,22 +193,7 @@ console_ansi_main(int argc, char *argv[])
|
||||
int
|
||||
console_wmain(int argc, wchar_t *wargv[], wchar_t *wenvp)
|
||||
{
|
||||
SDL_bool isstack;
|
||||
int retval = 0;
|
||||
char **argv = SDL_small_alloc(char*, argc + 1, &isstack);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < argc; ++i) {
|
||||
argv[i] = WIN_StringToUTF8(wargv[i]);
|
||||
}
|
||||
argv[argc] = NULL;
|
||||
|
||||
retval = main_utf8(argc, argv);
|
||||
|
||||
/* !!! FIXME: we are leaking all the elements of argv we allocated. */
|
||||
SDL_small_free(argv, isstack);
|
||||
|
||||
return retval;
|
||||
return main_getcmdline();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 2,0,8,0
|
||||
PRODUCTVERSION 2,0,8,0
|
||||
FILEVERSION 2,0,9,0
|
||||
PRODUCTVERSION 2,0,9,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
FILEFLAGS 0x0L
|
||||
FILEOS 0x40004L
|
||||
@@ -23,12 +23,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "\0"
|
||||
VALUE "FileDescription", "SDL\0"
|
||||
VALUE "FileVersion", "2, 0, 8, 0\0"
|
||||
VALUE "FileVersion", "2, 0, 9, 0\0"
|
||||
VALUE "InternalName", "SDL\0"
|
||||
VALUE "LegalCopyright", "Copyright <20> 2018 Sam Lantinga\0"
|
||||
VALUE "OriginalFilename", "SDL2.dll\0"
|
||||
VALUE "ProductName", "Simple DirectMedia Layer\0"
|
||||
VALUE "ProductVersion", "2, 0, 8, 0\0"
|
||||
VALUE "ProductVersion", "2, 0, 9, 0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -42,11 +42,8 @@ SDL_GetPowerInfo_Hardwired(SDL_PowerState * state, int *seconds, int *percent)
|
||||
return SDL_TRUE;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
static SDL_GetPowerInfo_Impl implementations[] = {
|
||||
#ifndef SDL_POWER_DISABLED
|
||||
#ifdef SDL_POWER_LINUX /* in order of preference. More than could work. */
|
||||
SDL_GetPowerInfo_Linux_org_freedesktop_upower,
|
||||
SDL_GetPowerInfo_Linux_sys_class_power_supply,
|
||||
@@ -81,31 +78,34 @@ static SDL_GetPowerInfo_Impl implementations[] = {
|
||||
#ifdef SDL_POWER_HARDWIRED
|
||||
SDL_GetPowerInfo_Hardwired,
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
SDL_PowerState
|
||||
SDL_GetPowerInfo(int *seconds, int *percent)
|
||||
{
|
||||
#ifndef SDL_POWER_DISABLED
|
||||
const int total = sizeof(implementations) / sizeof(implementations[0]);
|
||||
int _seconds, _percent;
|
||||
SDL_PowerState retval = SDL_POWERSTATE_UNKNOWN;
|
||||
int i;
|
||||
#endif
|
||||
|
||||
int _seconds, _percent;
|
||||
/* Make these never NULL for platform-specific implementations. */
|
||||
if (seconds == NULL) {
|
||||
seconds = &_seconds;
|
||||
}
|
||||
|
||||
if (percent == NULL) {
|
||||
percent = &_percent;
|
||||
}
|
||||
|
||||
#ifndef SDL_POWER_DISABLED
|
||||
for (i = 0; i < total; i++) {
|
||||
if (implementations[i](&retval, seconds, percent)) {
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* nothing was definitive. */
|
||||
*seconds = -1;
|
||||
|
||||
@@ -40,7 +40,9 @@ SDL_bool SDL_GetPowerInfo_Android(SDL_PowerState *, int *, int *);
|
||||
SDL_bool SDL_GetPowerInfo_PSP(SDL_PowerState *, int *, int *);
|
||||
SDL_bool SDL_GetPowerInfo_WinRT(SDL_PowerState *, int *, int *);
|
||||
SDL_bool SDL_GetPowerInfo_Emscripten(SDL_PowerState *, int *, int *);
|
||||
SDL_bool SDL_GetPowerInfo_Hardwired(SDL_PowerState *, int *, int *);
|
||||
|
||||
/* this one is static in SDL_power.c */
|
||||
/* SDL_bool SDL_GetPowerInfo_Hardwired(SDL_PowerState *, int *, int *);*/
|
||||
|
||||
#endif /* SDL_syspower_h_ */
|
||||
|
||||
|
||||
@@ -1071,7 +1071,8 @@ GetClosestSupportedFormat(SDL_Renderer * renderer, Uint32 format)
|
||||
return renderer->info.texture_formats[0];
|
||||
}
|
||||
|
||||
SDL_ScaleMode SDL_GetScaleMode(void)
|
||||
|
||||
static SDL_ScaleMode SDL_GetScaleMode(void)
|
||||
{
|
||||
const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
|
||||
|
||||
@@ -1199,7 +1200,7 @@ SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface)
|
||||
|
||||
/* See what the best texture format is */
|
||||
fmt = surface->format;
|
||||
if (fmt->Amask || SDL_GetColorKey(surface, NULL) == 0) {
|
||||
if (fmt->Amask || SDL_HasColorKey(surface)) {
|
||||
needAlpha = SDL_TRUE;
|
||||
} else {
|
||||
needAlpha = SDL_FALSE;
|
||||
@@ -1258,7 +1259,7 @@ SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface)
|
||||
SDL_GetSurfaceAlphaMod(surface, &a);
|
||||
SDL_SetTextureAlphaMod(texture, a);
|
||||
|
||||
if (SDL_GetColorKey(surface, NULL) == 0) {
|
||||
if (SDL_HasColorKey(surface)) {
|
||||
/* We converted to a texture with alpha format */
|
||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||
} else {
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_yuv_sw_c_h_
|
||||
#define SDL_yuv_sw_c_h_
|
||||
|
||||
#include "../SDL_internal.h"
|
||||
|
||||
#include "SDL_video.h"
|
||||
@@ -64,4 +68,6 @@ void SDL_SW_DestroyYUVTexture(SDL_SW_YUVTexture * swdata);
|
||||
#define USE_MMX_ASSEMBLY 1
|
||||
#endif
|
||||
|
||||
#endif /* SDL_yuv_sw_c_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -456,11 +456,6 @@ METAL_ActivateRenderCommandEncoder(SDL_Renderer * renderer, MTLLoadAction load,
|
||||
static void
|
||||
METAL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
|
||||
{
|
||||
if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||
METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
|
||||
data.mtllayer.drawableSize = CGSizeMake(event->data1, event->data2);
|
||||
}
|
||||
|
||||
if (event->event == SDL_WINDOWEVENT_SHOWN ||
|
||||
event->event == SDL_WINDOWEVENT_HIDDEN) {
|
||||
// !!! FIXME: write me
|
||||
@@ -552,12 +547,20 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
mtltexdesc.height = (texture->h + 1) / 2;
|
||||
mtltexdesc.textureType = MTLTextureType2DArray;
|
||||
mtltexdesc.arrayLength = 2;
|
||||
mtltexture_uv = [data.mtldevice newTextureWithDescriptor:mtltexdesc];
|
||||
} else if (nv12) {
|
||||
mtltexdesc.pixelFormat = MTLPixelFormatRG8Unorm;
|
||||
mtltexdesc.width = (texture->w + 1) / 2;
|
||||
mtltexdesc.height = (texture->h + 1) / 2;
|
||||
}
|
||||
|
||||
if (yuv || nc12) {
|
||||
mtltexture_uv = [data.mtldevice newTextureWithDescriptor:mtltexdesc];
|
||||
if (mtltexture_uv == nil) {
|
||||
#if !__has_feature(objc_arc)
|
||||
[mtltexture release];
|
||||
#endif
|
||||
return SDL_SetError("Texture allocation failed");
|
||||
}
|
||||
}
|
||||
|
||||
METAL_TextureData *texturedata = [[METAL_TextureData alloc] init];
|
||||
|
||||
@@ -1529,7 +1529,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
|
||||
data = (GL_RenderData *) SDL_calloc(1, sizeof(*data));
|
||||
if (!data) {
|
||||
GL_DestroyRenderer(renderer);
|
||||
SDL_free(renderer);
|
||||
SDL_OutOfMemory();
|
||||
goto error;
|
||||
}
|
||||
@@ -1563,16 +1563,21 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
|
||||
data->context = SDL_GL_CreateContext(window);
|
||||
if (!data->context) {
|
||||
GL_DestroyRenderer(renderer);
|
||||
SDL_free(renderer);
|
||||
SDL_free(data);
|
||||
goto error;
|
||||
}
|
||||
if (SDL_GL_MakeCurrent(window, data->context) < 0) {
|
||||
GL_DestroyRenderer(renderer);
|
||||
SDL_GL_DeleteContext(data->context);
|
||||
SDL_free(renderer);
|
||||
SDL_free(data);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (GL_LoadFunctions(data) < 0) {
|
||||
GL_DestroyRenderer(renderer);
|
||||
SDL_GL_DeleteContext(data->context);
|
||||
SDL_free(renderer);
|
||||
SDL_free(data);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_shaders_gl_h_
|
||||
#define SDL_shaders_gl_h_
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
/* OpenGL shader implementation */
|
||||
@@ -45,4 +49,6 @@ extern GL_ShaderContext * GL_CreateShaderContext(void);
|
||||
extern void GL_SelectShader(GL_ShaderContext *ctx, GL_Shader shader);
|
||||
extern void GL_DestroyShaderContext(GL_ShaderContext *ctx);
|
||||
|
||||
#endif /* SDL_shaders_gl_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -1942,7 +1942,7 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
|
||||
|
||||
data = (GLES2_RenderData *)SDL_calloc(1, sizeof(GLES2_RenderData));
|
||||
if (!data) {
|
||||
GLES2_DestroyRenderer(renderer);
|
||||
SDL_free(renderer);
|
||||
SDL_OutOfMemory();
|
||||
goto error;
|
||||
}
|
||||
@@ -1954,16 +1954,21 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
|
||||
/* Create an OpenGL ES 2.0 context */
|
||||
data->context = SDL_GL_CreateContext(window);
|
||||
if (!data->context) {
|
||||
GLES2_DestroyRenderer(renderer);
|
||||
SDL_free(renderer);
|
||||
SDL_free(data);
|
||||
goto error;
|
||||
}
|
||||
if (SDL_GL_MakeCurrent(window, data->context) < 0) {
|
||||
GLES2_DestroyRenderer(renderer);
|
||||
SDL_GL_DeleteContext(data->context);
|
||||
SDL_free(renderer);
|
||||
SDL_free(data);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (GLES2_LoadFunctions(data) < 0) {
|
||||
GLES2_DestroyRenderer(renderer);
|
||||
SDL_GL_DeleteContext(data->context);
|
||||
SDL_free(renderer);
|
||||
SDL_free(data);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,10 +18,16 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_blendfillrect_h_
|
||||
#define SDL_blendfillrect_h_
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
|
||||
extern int SDL_BlendFillRect(SDL_Surface * dst, const SDL_Rect * rect, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
||||
extern int SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect * rects, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
||||
|
||||
#endif /* SDL_blendfillrect_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -18,10 +18,16 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_blendline_h_
|
||||
#define SDL_blendline_h_
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
|
||||
extern int SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
||||
extern int SDL_BlendLines(SDL_Surface * dst, const SDL_Point * points, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
||||
|
||||
#endif /* SDL_blendline_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -18,10 +18,16 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_blendpoint_h_
|
||||
#define SDL_blendpoint_h_
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
|
||||
extern int SDL_BlendPoint(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
||||
extern int SDL_BlendPoints(SDL_Surface * dst, const SDL_Point * points, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
|
||||
|
||||
#endif /* SDL_blendpoint_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -18,10 +18,16 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_drawline_h_
|
||||
#define SDL_drawline_h_
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
|
||||
extern int SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color);
|
||||
extern int SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count, Uint32 color);
|
||||
|
||||
#endif /* SDL_drawline_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -18,10 +18,16 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_drawpoint_h_
|
||||
#define SDL_drawpoint_h_
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
|
||||
extern int SDL_DrawPoint(SDL_Surface * dst, int x, int y, Uint32 color);
|
||||
extern int SDL_DrawPoints(SDL_Surface * dst, const SDL_Point * points, int count, Uint32 color);
|
||||
|
||||
#endif /* SDL_drawpoint_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -377,6 +377,11 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex
|
||||
blitRequired = SDL_TRUE;
|
||||
}
|
||||
|
||||
/* srcrect is not selecting the whole src surface, so cropping is needed */
|
||||
if (!(srcrect->w == src->w && srcrect->h == src->h && srcrect->x == 0 && srcrect->y == 0)) {
|
||||
blitRequired = SDL_TRUE;
|
||||
}
|
||||
|
||||
/* The color and alpha modulation has to be applied before the rotation when using the NONE and MOD blend modes. */
|
||||
if ((blendmode == SDL_BLENDMODE_NONE || blendmode == SDL_BLENDMODE_MOD) && (alphaMod & rMod & gMod & bMod) != 255) {
|
||||
applyModulation = SDL_TRUE;
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_render_sw_c_h_
|
||||
#define SDL_render_sw_c_h_
|
||||
|
||||
extern SDL_Renderer * SW_CreateRendererForSurface(SDL_Surface * surface);
|
||||
|
||||
#endif /* SDL_render_sw_c_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -83,7 +83,9 @@ static Uint32
|
||||
_colorkey(SDL_Surface *src)
|
||||
{
|
||||
Uint32 key = 0;
|
||||
SDL_GetColorKey(src, &key);
|
||||
if (SDL_HasColorKey(src)) {
|
||||
SDL_GetColorKey(src, &key);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
@@ -424,8 +426,10 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery,
|
||||
if (src == NULL)
|
||||
return NULL;
|
||||
|
||||
if (SDL_GetColorKey(src, &colorkey) == 0) {
|
||||
colorKeyAvailable = SDL_TRUE;
|
||||
if (SDL_HasColorKey(src)) {
|
||||
if (SDL_GetColorKey(src, &colorkey) == 0) {
|
||||
colorKeyAvailable = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function requires a 32-bit surface or 8-bit surface with a colorkey */
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_rotate_h_
|
||||
#define SDL_rotate_h_
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
@@ -26,3 +29,4 @@
|
||||
extern SDL_Surface *SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, int smooth, int flipx, int flipy, int dstwidth, int dstheight, double cangle, double sangle);
|
||||
extern void SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, int *dstwidth, int *dstheight, double *cangle, double *sangle);
|
||||
|
||||
#endif /* SDL_rotate_h_ */
|
||||
|
||||
@@ -48,7 +48,7 @@ static SDL_bool SDL_updating_sensor = SDL_FALSE;
|
||||
static SDL_mutex *SDL_sensor_lock = NULL; /* This needs to support recursive locks */
|
||||
static SDL_atomic_t SDL_next_sensor_instance_id;
|
||||
|
||||
void
|
||||
static void
|
||||
SDL_LockSensors(void)
|
||||
{
|
||||
if (SDL_sensor_lock) {
|
||||
@@ -56,7 +56,7 @@ SDL_LockSensors(void)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
SDL_UnlockSensors(void)
|
||||
{
|
||||
if (SDL_sensor_lock) {
|
||||
@@ -118,7 +118,7 @@ SDL_SensorID SDL_GetNextSensorInstanceID()
|
||||
* Get the driver and device index for an API device index
|
||||
* This should be called while the sensor lock is held, to prevent another thread from updating the list
|
||||
*/
|
||||
SDL_bool
|
||||
static SDL_bool
|
||||
SDL_GetDriverAndSensorIndex(int device_index, SDL_SensorDriver **driver, int *driver_index)
|
||||
{
|
||||
int i, num_sensors, total_sensors = 0;
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_sensor_c_h_
|
||||
#define SDL_sensor_c_h_
|
||||
|
||||
#include "SDL_config.h"
|
||||
|
||||
struct _SDL_SensorDriver;
|
||||
@@ -35,4 +39,6 @@ extern void SDL_SensorQuit(void);
|
||||
/* Internal event queueing functions */
|
||||
extern int SDL_PrivateSensorUpdate(SDL_Sensor *sensor, float *data, int num_values);
|
||||
|
||||
#endif /* SDL_sensor_c_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_syssensor_c_h_
|
||||
#define SDL_syssensor_c_h_
|
||||
|
||||
#include "SDL_config.h"
|
||||
|
||||
/* This is the system specific header for the SDL sensor API */
|
||||
@@ -96,4 +100,6 @@ extern SDL_SensorDriver SDL_ANDROID_SensorDriver;
|
||||
extern SDL_SensorDriver SDL_COREMOTION_SensorDriver;
|
||||
extern SDL_SensorDriver SDL_DUMMY_SensorDriver;
|
||||
|
||||
#endif /* SDL_syssensor_c_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -89,13 +89,13 @@ SDL_iconv(SDL_iconv_t cd,
|
||||
#else
|
||||
|
||||
/* Lots of useful information on Unicode at:
|
||||
http://www.cl.cam.ac.uk/~mgk25/unicode.html
|
||||
http://www.cl.cam.ac.uk/~mgk25/unicode.html
|
||||
*/
|
||||
|
||||
#define UNICODE_BOM 0xFEFF
|
||||
#define UNICODE_BOM 0xFEFF
|
||||
|
||||
#define UNKNOWN_ASCII '?'
|
||||
#define UNKNOWN_UNICODE 0xFFFD
|
||||
#define UNKNOWN_ASCII '?'
|
||||
#define UNKNOWN_UNICODE 0xFFFD
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -115,13 +115,13 @@ enum
|
||||
ENCODING_UCS4LE,
|
||||
};
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
#define ENCODING_UTF16NATIVE ENCODING_UTF16BE
|
||||
#define ENCODING_UTF32NATIVE ENCODING_UTF32BE
|
||||
#define ENCODING_UTF16NATIVE ENCODING_UTF16BE
|
||||
#define ENCODING_UTF32NATIVE ENCODING_UTF32BE
|
||||
#define ENCODING_UCS2NATIVE ENCODING_UCS2BE
|
||||
#define ENCODING_UCS4NATIVE ENCODING_UCS4BE
|
||||
#else
|
||||
#define ENCODING_UTF16NATIVE ENCODING_UTF16LE
|
||||
#define ENCODING_UTF32NATIVE ENCODING_UTF32LE
|
||||
#define ENCODING_UTF16NATIVE ENCODING_UTF16LE
|
||||
#define ENCODING_UTF32NATIVE ENCODING_UTF32LE
|
||||
#define ENCODING_UCS2NATIVE ENCODING_UCS2LE
|
||||
#define ENCODING_UCS4NATIVE ENCODING_UCS4LE
|
||||
#endif
|
||||
|
||||
@@ -271,12 +271,16 @@ SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len)
|
||||
size_t left;
|
||||
Uint32 *dstp4;
|
||||
Uint8 *dstp1 = (Uint8 *) dst;
|
||||
Uint32 value4 = (c | (c << 8) | (c << 16) | (c << 24));
|
||||
Uint8 value1 = (Uint8) c;
|
||||
Uint8 value1;
|
||||
Uint32 value4;
|
||||
|
||||
/* The value used in memset() is a byte, passed as an int */
|
||||
c &= 0xff;
|
||||
|
||||
/* The destination pointer needs to be aligned on a 4-byte boundary to
|
||||
* execute a 32-bit set. Set first bytes manually if needed until it is
|
||||
* aligned. */
|
||||
value1 = (Uint8)c;
|
||||
while ((intptr_t)dstp1 & 0x3) {
|
||||
if (len--) {
|
||||
*dstp1++ = value1;
|
||||
@@ -285,6 +289,7 @@ SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len)
|
||||
}
|
||||
}
|
||||
|
||||
value4 = (c | (c << 8) | (c << 16) | (c << 24));
|
||||
dstp4 = (Uint32 *) dstp1;
|
||||
left = (len % 4);
|
||||
len /= 4;
|
||||
@@ -1360,9 +1365,9 @@ typedef enum
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SDL_bool left_justify;
|
||||
SDL_bool left_justify; /* for now: ignored. */
|
||||
SDL_bool force_sign;
|
||||
SDL_bool force_type;
|
||||
SDL_bool force_type; /* for now: used only by float printer, ignored otherwise. */
|
||||
SDL_bool pad_zeroes;
|
||||
SDL_letter_case force_case;
|
||||
int width;
|
||||
@@ -1374,15 +1379,18 @@ static size_t
|
||||
SDL_PrintString(char *text, size_t maxlen, SDL_FormatInfo *info, const char *string)
|
||||
{
|
||||
size_t length = 0;
|
||||
size_t slen;
|
||||
size_t slen, sz;
|
||||
|
||||
if (string == NULL) {
|
||||
string = "(null)";
|
||||
}
|
||||
|
||||
if (info && info->width && (size_t)info->width > SDL_strlen(string)) {
|
||||
sz = SDL_strlen(string);
|
||||
if (info && info->width > 0 && (size_t)info->width > sz) {
|
||||
char fill = info->pad_zeroes ? '0' : ' ';
|
||||
size_t width = info->width - SDL_strlen(string);
|
||||
size_t width = info->width - sz;
|
||||
if (info->precision >= 0 && (size_t)info->precision < sz)
|
||||
width += sz - (size_t)info->precision;
|
||||
while (width-- > 0 && maxlen > 0) {
|
||||
*text++ = fill;
|
||||
++length;
|
||||
@@ -1394,6 +1402,13 @@ SDL_PrintString(char *text, size_t maxlen, SDL_FormatInfo *info, const char *str
|
||||
length += SDL_min(slen, maxlen);
|
||||
|
||||
if (info) {
|
||||
if (info->precision >= 0 && (size_t)info->precision < sz) {
|
||||
slen = (size_t)info->precision;
|
||||
if (slen < maxlen) {
|
||||
text[slen] = 0;
|
||||
length -= (sz - slen);
|
||||
}
|
||||
}
|
||||
if (info->force_case == SDL_CASE_LOWER) {
|
||||
SDL_strlwr(text);
|
||||
} else if (info->force_case == SDL_CASE_UPPER) {
|
||||
@@ -1403,12 +1418,54 @@ SDL_PrintString(char *text, size_t maxlen, SDL_FormatInfo *info, const char *str
|
||||
return length;
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_IntPrecisionAdjust(char *num, size_t maxlen, SDL_FormatInfo *info)
|
||||
{/* left-pad num with zeroes. */
|
||||
size_t sz, pad, have_sign;
|
||||
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
have_sign = 0;
|
||||
if (*num == '-' || *num == '+') {
|
||||
have_sign = 1;
|
||||
++num;
|
||||
--maxlen;
|
||||
}
|
||||
sz = SDL_strlen(num);
|
||||
if (info->precision > 0 && sz < (size_t)info->precision) {
|
||||
pad = (size_t)info->precision - sz;
|
||||
if (pad + sz + 1 <= maxlen) { /* otherwise ignore the precision */
|
||||
SDL_memmove(num + pad, num, sz + 1);
|
||||
SDL_memset(num, '0', pad);
|
||||
}
|
||||
}
|
||||
info->precision = -1;/* so that SDL_PrintString() doesn't make a mess. */
|
||||
|
||||
if (info->pad_zeroes && info->width > 0 && (size_t)info->width > sz + have_sign) {
|
||||
/* handle here: spaces are added before the sign
|
||||
but zeroes must be placed _after_ the sign. */
|
||||
/* sz hasn't changed: we ignore pad_zeroes if a precision is given. */
|
||||
pad = (size_t)info->width - sz - have_sign;
|
||||
if (pad + sz + 1 <= maxlen) {
|
||||
SDL_memmove(num + pad, num, sz + 1);
|
||||
SDL_memset(num, '0', pad);
|
||||
}
|
||||
info->width = 0; /* so that SDL_PrintString() doesn't make a mess. */
|
||||
}
|
||||
}
|
||||
|
||||
static size_t
|
||||
SDL_PrintLong(char *text, size_t maxlen, SDL_FormatInfo *info, long value)
|
||||
{
|
||||
char num[130];
|
||||
char num[130], *p = num;
|
||||
|
||||
SDL_ltoa(value, num, info ? info->radix : 10);
|
||||
if (info->force_sign && value >= 0L) {
|
||||
*p++ = '+';
|
||||
}
|
||||
|
||||
SDL_ltoa(value, p, info ? info->radix : 10);
|
||||
SDL_IntPrecisionAdjust(num, maxlen, info);
|
||||
return SDL_PrintString(text, maxlen, info, num);
|
||||
}
|
||||
|
||||
@@ -1418,15 +1475,21 @@ SDL_PrintUnsignedLong(char *text, size_t maxlen, SDL_FormatInfo *info, unsigned
|
||||
char num[130];
|
||||
|
||||
SDL_ultoa(value, num, info ? info->radix : 10);
|
||||
SDL_IntPrecisionAdjust(num, maxlen, info);
|
||||
return SDL_PrintString(text, maxlen, info, num);
|
||||
}
|
||||
|
||||
static size_t
|
||||
SDL_PrintLongLong(char *text, size_t maxlen, SDL_FormatInfo *info, Sint64 value)
|
||||
{
|
||||
char num[130];
|
||||
char num[130], *p = num;
|
||||
|
||||
SDL_lltoa(value, num, info ? info->radix : 10);
|
||||
if (info->force_sign && value >= (Sint64)0) {
|
||||
*p++ = '+';
|
||||
}
|
||||
|
||||
SDL_lltoa(value, p, info ? info->radix : 10);
|
||||
SDL_IntPrecisionAdjust(num, maxlen, info);
|
||||
return SDL_PrintString(text, maxlen, info, num);
|
||||
}
|
||||
|
||||
@@ -1436,6 +1499,7 @@ SDL_PrintUnsignedLongLong(char *text, size_t maxlen, SDL_FormatInfo *info, Uint6
|
||||
char num[130];
|
||||
|
||||
SDL_ulltoa(value, num, info ? info->radix : 10);
|
||||
SDL_IntPrecisionAdjust(num, maxlen, info);
|
||||
return SDL_PrintString(text, maxlen, info, num);
|
||||
}
|
||||
|
||||
@@ -1593,14 +1657,24 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt,
|
||||
if (*fmt >= '0' && *fmt <= '9') {
|
||||
info.width = SDL_strtol(fmt, (char **)&fmt, 0);
|
||||
}
|
||||
else if (*fmt == '*') {
|
||||
++fmt;
|
||||
info.width = va_arg(ap, int);
|
||||
}
|
||||
|
||||
if (*fmt == '.') {
|
||||
++fmt;
|
||||
if (*fmt >= '0' && *fmt <= '9') {
|
||||
info.precision = SDL_strtol(fmt, (char **)&fmt, 0);
|
||||
} else if (*fmt == '*') {
|
||||
++fmt;
|
||||
info.precision = va_arg(ap, int);
|
||||
} else {
|
||||
info.precision = 0;
|
||||
}
|
||||
if (info.precision < 0) {
|
||||
info.precision = 0;
|
||||
}
|
||||
}
|
||||
|
||||
while (!done) {
|
||||
@@ -1636,6 +1710,9 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt,
|
||||
break;
|
||||
case 'i':
|
||||
case 'd':
|
||||
if (info.precision >= 0) {
|
||||
info.pad_zeroes = SDL_FALSE;
|
||||
}
|
||||
switch (inttype) {
|
||||
case DO_INT:
|
||||
len = SDL_PrintLong(text, left, &info,
|
||||
@@ -1673,7 +1750,10 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt,
|
||||
}
|
||||
/* Fall through to unsigned handling */
|
||||
case 'u':
|
||||
info.pad_zeroes = SDL_TRUE;
|
||||
info.force_sign = SDL_FALSE;
|
||||
if (info.precision >= 0) {
|
||||
info.pad_zeroes = SDL_FALSE;
|
||||
}
|
||||
switch (inttype) {
|
||||
case DO_INT:
|
||||
len = SDL_PrintUnsignedLong(text, left, &info,
|
||||
@@ -1700,12 +1780,14 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt,
|
||||
/* In practice this is used on Windows for WCHAR strings */
|
||||
wchar_t *wide_arg = va_arg(ap, wchar_t *);
|
||||
char *arg = SDL_iconv_string("UTF-8", "UTF-16LE", (char *)(wide_arg), (SDL_wcslen(wide_arg)+1)*sizeof(*wide_arg));
|
||||
info.pad_zeroes = SDL_FALSE;
|
||||
len = SDL_PrintString(text, left, &info, arg);
|
||||
SDL_free(arg);
|
||||
done = SDL_TRUE;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
info.pad_zeroes = SDL_FALSE;
|
||||
len = SDL_PrintString(text, left, &info, va_arg(ap, char *));
|
||||
done = SDL_TRUE;
|
||||
break;
|
||||
|
||||
@@ -299,19 +299,21 @@ SDL_RunThread(void *data)
|
||||
|
||||
#ifdef SDL_CreateThread
|
||||
#undef SDL_CreateThread
|
||||
#undef SDL_CreateThreadWithStackSize
|
||||
#endif
|
||||
#if SDL_DYNAMIC_API
|
||||
#define SDL_CreateThread SDL_CreateThread_REAL
|
||||
#define SDL_CreateThreadWithStackSize SDL_CreateThreadWithStackSize_REAL
|
||||
#endif
|
||||
|
||||
#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
|
||||
static SDL_Thread *
|
||||
SDL_Thread *
|
||||
SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *),
|
||||
const char *name, const size_t stacksize, void *data,
|
||||
pfnSDL_CurrentBeginThread pfnBeginThread,
|
||||
pfnSDL_CurrentEndThread pfnEndThread)
|
||||
#else
|
||||
static SDL_Thread *
|
||||
SDL_Thread *
|
||||
SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *),
|
||||
const char *name, const size_t stacksize, void *data)
|
||||
#endif
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_timer_c_h_
|
||||
#define SDL_timer_c_h_
|
||||
|
||||
#include "../SDL_internal.h"
|
||||
|
||||
/* Useful functions and variables from SDL_timer.c */
|
||||
@@ -31,4 +35,6 @@ extern void SDL_TicksQuit(void);
|
||||
extern int SDL_TimerInit(void);
|
||||
extern void SDL_TimerQuit(void);
|
||||
|
||||
#endif /* SDL_timer_c_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_RLEaccel_c_h_
|
||||
#define SDL_RLEaccel_c_h_
|
||||
|
||||
#include "../SDL_internal.h"
|
||||
|
||||
/* Useful functions and variables from SDL_RLEaccel.c */
|
||||
@@ -28,4 +32,7 @@ extern int SDLCALL SDL_RLEBlit (SDL_Surface * src, SDL_Rect * srcrect,
|
||||
extern int SDLCALL SDL_RLEAlphaBlit(SDL_Surface * src, SDL_Rect * srcrect,
|
||||
SDL_Surface * dst, SDL_Rect * dstrect);
|
||||
extern void SDL_UnRLESurface(SDL_Surface * surface, int recode);
|
||||
|
||||
#endif /* SDL_RLEaccel_c_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -126,7 +126,7 @@ extern SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface * surface);
|
||||
b = SDL_expand_byte[fmt->Bloss][((Pixel&fmt->Bmask)>>fmt->Bshift)]; \
|
||||
}
|
||||
#define RGB_FROM_RGB565(Pixel, r, g, b) \
|
||||
{ \
|
||||
{ \
|
||||
r = SDL_expand_byte[3][((Pixel&0xF800)>>11)]; \
|
||||
g = SDL_expand_byte[2][((Pixel&0x07E0)>>5)]; \
|
||||
b = SDL_expand_byte[3][(Pixel&0x001F)]; \
|
||||
@@ -262,18 +262,18 @@ do { \
|
||||
{ \
|
||||
switch (bpp) { \
|
||||
case 1: { \
|
||||
Uint8 Pixel; \
|
||||
Uint8 _Pixel; \
|
||||
\
|
||||
PIXEL_FROM_RGB(Pixel, fmt, r, g, b); \
|
||||
*((Uint8 *)(buf)) = Pixel; \
|
||||
PIXEL_FROM_RGB(_Pixel, fmt, r, g, b); \
|
||||
*((Uint8 *)(buf)) = _Pixel; \
|
||||
} \
|
||||
break; \
|
||||
\
|
||||
case 2: { \
|
||||
Uint16 Pixel; \
|
||||
Uint16 _Pixel; \
|
||||
\
|
||||
PIXEL_FROM_RGB(Pixel, fmt, r, g, b); \
|
||||
*((Uint16 *)(buf)) = Pixel; \
|
||||
PIXEL_FROM_RGB(_Pixel, fmt, r, g, b); \
|
||||
*((Uint16 *)(buf)) = _Pixel; \
|
||||
} \
|
||||
break; \
|
||||
\
|
||||
@@ -291,10 +291,10 @@ do { \
|
||||
break; \
|
||||
\
|
||||
case 4: { \
|
||||
Uint32 Pixel; \
|
||||
Uint32 _Pixel; \
|
||||
\
|
||||
PIXEL_FROM_RGB(Pixel, fmt, r, g, b); \
|
||||
*((Uint32 *)(buf)) = Pixel; \
|
||||
PIXEL_FROM_RGB(_Pixel, fmt, r, g, b); \
|
||||
*((Uint32 *)(buf)) = _Pixel; \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
|
||||
@@ -49,13 +49,13 @@ Blit1to1(SDL_BlitInfo * info)
|
||||
while (height--) {
|
||||
#ifdef USE_DUFFS_LOOP
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
{
|
||||
*dst = map[*src];
|
||||
}
|
||||
dst++;
|
||||
src++;
|
||||
, width);
|
||||
DUFFS_LOOP(
|
||||
{
|
||||
*dst = map[*src];
|
||||
}
|
||||
dst++;
|
||||
src++;
|
||||
, width);
|
||||
/* *INDENT-ON* */
|
||||
#else
|
||||
for (c = width; c; --c) {
|
||||
@@ -72,11 +72,11 @@ Blit1to1(SDL_BlitInfo * info)
|
||||
/* This is now endian dependent */
|
||||
#ifndef USE_DUFFS_LOOP
|
||||
# if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
|
||||
# define HI 1
|
||||
# define LO 0
|
||||
# define HI 1
|
||||
# define LO 0
|
||||
# else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */
|
||||
# define HI 0
|
||||
# define LO 1
|
||||
# define HI 0
|
||||
# define LO 1
|
||||
# endif
|
||||
#endif
|
||||
static void
|
||||
@@ -101,14 +101,14 @@ Blit1to2(SDL_BlitInfo * info)
|
||||
|
||||
#ifdef USE_DUFFS_LOOP
|
||||
while (height--) {
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
{
|
||||
*(Uint16 *)dst = map[*src++];
|
||||
dst += 2;
|
||||
},
|
||||
width);
|
||||
/* *INDENT-ON* */
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
{
|
||||
*(Uint16 *)dst = map[*src++];
|
||||
dst += 2;
|
||||
},
|
||||
width);
|
||||
/* *INDENT-ON* */
|
||||
src += srcskip;
|
||||
dst += dstskip;
|
||||
}
|
||||
@@ -208,18 +208,18 @@ Blit1to3(SDL_BlitInfo * info)
|
||||
|
||||
while (height--) {
|
||||
#ifdef USE_DUFFS_LOOP
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
{
|
||||
o = *src * 4;
|
||||
dst[0] = map[o++];
|
||||
dst[1] = map[o++];
|
||||
dst[2] = map[o++];
|
||||
}
|
||||
src++;
|
||||
dst += 3;
|
||||
, width);
|
||||
/* *INDENT-ON* */
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
{
|
||||
o = *src * 4;
|
||||
dst[0] = map[o++];
|
||||
dst[1] = map[o++];
|
||||
dst[2] = map[o++];
|
||||
}
|
||||
src++;
|
||||
dst += 3;
|
||||
, width);
|
||||
/* *INDENT-ON* */
|
||||
#else
|
||||
for (c = width; c; --c) {
|
||||
o = *src * 4;
|
||||
@@ -257,11 +257,11 @@ Blit1to4(SDL_BlitInfo * info)
|
||||
|
||||
while (height--) {
|
||||
#ifdef USE_DUFFS_LOOP
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
*dst++ = map[*src++];
|
||||
, width);
|
||||
/* *INDENT-ON* */
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
*dst++ = map[*src++];
|
||||
, width);
|
||||
/* *INDENT-ON* */
|
||||
#else
|
||||
for (c = width / 4; c; --c) {
|
||||
*dst++ = map[*src++];
|
||||
@@ -297,33 +297,33 @@ Blit1to1Key(SDL_BlitInfo * info)
|
||||
|
||||
if (palmap) {
|
||||
while (height--) {
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
{
|
||||
if ( *src != ckey ) {
|
||||
*dst = palmap[*src];
|
||||
}
|
||||
dst++;
|
||||
src++;
|
||||
},
|
||||
width);
|
||||
/* *INDENT-ON* */
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
{
|
||||
if ( *src != ckey ) {
|
||||
*dst = palmap[*src];
|
||||
}
|
||||
dst++;
|
||||
src++;
|
||||
},
|
||||
width);
|
||||
/* *INDENT-ON* */
|
||||
src += srcskip;
|
||||
dst += dstskip;
|
||||
}
|
||||
} else {
|
||||
while (height--) {
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
{
|
||||
if ( *src != ckey ) {
|
||||
*dst = *src;
|
||||
}
|
||||
dst++;
|
||||
src++;
|
||||
},
|
||||
width);
|
||||
/* *INDENT-ON* */
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
{
|
||||
if ( *src != ckey ) {
|
||||
*dst = *src;
|
||||
}
|
||||
dst++;
|
||||
src++;
|
||||
},
|
||||
width);
|
||||
/* *INDENT-ON* */
|
||||
src += srcskip;
|
||||
dst += dstskip;
|
||||
}
|
||||
@@ -346,17 +346,17 @@ Blit1to2Key(SDL_BlitInfo * info)
|
||||
dstskip /= 2;
|
||||
|
||||
while (height--) {
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
{
|
||||
if ( *src != ckey ) {
|
||||
*dstp=palmap[*src];
|
||||
}
|
||||
src++;
|
||||
dstp++;
|
||||
},
|
||||
width);
|
||||
/* *INDENT-ON* */
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
{
|
||||
if ( *src != ckey ) {
|
||||
*dstp=palmap[*src];
|
||||
}
|
||||
src++;
|
||||
dstp++;
|
||||
},
|
||||
width);
|
||||
/* *INDENT-ON* */
|
||||
src += srcskip;
|
||||
dstp += dstskip;
|
||||
}
|
||||
@@ -376,20 +376,20 @@ Blit1to3Key(SDL_BlitInfo * info)
|
||||
int o;
|
||||
|
||||
while (height--) {
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
{
|
||||
if ( *src != ckey ) {
|
||||
o = *src * 4;
|
||||
dst[0] = palmap[o++];
|
||||
dst[1] = palmap[o++];
|
||||
dst[2] = palmap[o++];
|
||||
}
|
||||
src++;
|
||||
dst += 3;
|
||||
},
|
||||
width);
|
||||
/* *INDENT-ON* */
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
{
|
||||
if ( *src != ckey ) {
|
||||
o = *src * 4;
|
||||
dst[0] = palmap[o++];
|
||||
dst[1] = palmap[o++];
|
||||
dst[2] = palmap[o++];
|
||||
}
|
||||
src++;
|
||||
dst += 3;
|
||||
},
|
||||
width);
|
||||
/* *INDENT-ON* */
|
||||
src += srcskip;
|
||||
dst += dstskip;
|
||||
}
|
||||
@@ -411,17 +411,17 @@ Blit1to4Key(SDL_BlitInfo * info)
|
||||
dstskip /= 4;
|
||||
|
||||
while (height--) {
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
{
|
||||
if ( *src != ckey ) {
|
||||
*dstp = palmap[*src];
|
||||
}
|
||||
src++;
|
||||
dstp++;
|
||||
},
|
||||
width);
|
||||
/* *INDENT-ON* */
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
{
|
||||
if ( *src != ckey ) {
|
||||
*dstp = palmap[*src];
|
||||
}
|
||||
src++;
|
||||
dstp++;
|
||||
},
|
||||
width);
|
||||
/* *INDENT-ON* */
|
||||
src += srcskip;
|
||||
dstp += dstskip;
|
||||
}
|
||||
@@ -489,22 +489,22 @@ Blit1toNAlphaKey(SDL_BlitInfo * info)
|
||||
dstbpp = dstfmt->BytesPerPixel;
|
||||
|
||||
while (height--) {
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
{
|
||||
if ( *src != ckey ) {
|
||||
sR = srcpal[*src].r;
|
||||
sG = srcpal[*src].g;
|
||||
sB = srcpal[*src].b;
|
||||
DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
|
||||
ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA);
|
||||
ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
|
||||
}
|
||||
src++;
|
||||
dst += dstbpp;
|
||||
},
|
||||
width);
|
||||
/* *INDENT-ON* */
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
{
|
||||
if ( *src != ckey ) {
|
||||
sR = srcpal[*src].r;
|
||||
sG = srcpal[*src].g;
|
||||
sB = srcpal[*src].b;
|
||||
DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
|
||||
ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA);
|
||||
ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
|
||||
}
|
||||
src++;
|
||||
dst += dstbpp;
|
||||
},
|
||||
width);
|
||||
/* *INDENT-ON* */
|
||||
src += srcskip;
|
||||
dst += dstskip;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user