Merge remote-tracking branch 'upstream/master' into zip_support
This commit is contained in:
commit
1e44a4056c
12
Makefile
12
Makefile
|
@ -40,10 +40,10 @@ OBJ = frontend/frontend.o \
|
|||
gfx/scaler/scaler_filter.o \
|
||||
gfx/image/image_rpng.o \
|
||||
gfx/fonts/fonts.o \
|
||||
audio/resampler.o \
|
||||
audio/resamplers/resampler.o \
|
||||
audio/dsp_filter.o \
|
||||
audio/sinc.o \
|
||||
audio/cc_resampler.o \
|
||||
audio/resamplers/sinc.o \
|
||||
audio/resamplers/cc_resampler.o \
|
||||
location/nulllocation.o \
|
||||
camera/nullcamera.o \
|
||||
gfx/nullgfx.o \
|
||||
|
@ -116,6 +116,10 @@ ifeq ($(HAVE_RGUI), 1)
|
|||
OBJ += frontend/menu/disp/rgui.o
|
||||
DEFINES += -DHAVE_MENU -DHAVE_RGUI
|
||||
HAVE_MENU_COMMON = 1
|
||||
ifeq ($(HAVE_GLUI), 1)
|
||||
OBJ += frontend/menu/disp/glui.o
|
||||
DEFINES += -DHAVE_GLUI
|
||||
endif
|
||||
ifeq ($(HAVE_LAKKA), 1)
|
||||
OBJ += frontend/menu/backend/menu_lakka_backend.o frontend/menu/disp/lakka.o
|
||||
DEFINES += -DHAVE_LAKKA
|
||||
|
@ -461,7 +465,7 @@ ifeq ($(HAVE_XKBCOMMON), 1)
|
|||
endif
|
||||
|
||||
ifeq ($(HAVE_NEON),1)
|
||||
OBJ += audio/sinc_neon.o
|
||||
OBJ += audio/resamplers/sinc_neon.o
|
||||
# When compiled without this, tries to attempt to compile sinc lerp,
|
||||
# which will error out
|
||||
DEFINES += -DSINC_LOWER_QUALITY
|
||||
|
|
|
@ -45,9 +45,9 @@ OBJ = frontend/platform/platform_emscripten.o \
|
|||
gfx/fonts/bitmapfont.o \
|
||||
gfx/image/image_rpng.o \
|
||||
gfx/filter.o \
|
||||
audio/resampler.o \
|
||||
audio/sinc.o \
|
||||
audio/cc_resampler.o \
|
||||
audio/resamplers/resampler.o \
|
||||
audio/resamplers/sinc.o \
|
||||
audio/resamplers/cc_resampler.o \
|
||||
audio/nullaudio.o \
|
||||
performance.o \
|
||||
core_info.o \
|
||||
|
|
|
@ -10,7 +10,7 @@ TARGET := retroarch-pandora
|
|||
LDDIRS = -L. -L$(PNDSDK)/usr/lib
|
||||
INCDIRS = -I. -I$(PNDSDK)/usr/include
|
||||
|
||||
OBJ = griffin/griffin.o audio/sinc_neon.o audio/utils_neon.o
|
||||
OBJ = griffin/griffin.o audio/resamplers/sinc_neon.o audio/utils_neon.o
|
||||
LDFLAGS = -L$(PNDSDK)/usr/lib -Wl,-rpath,$(PNDSDK)/usr/lib
|
||||
|
||||
LIBS = -lGLESv2 -lEGL -ldl -lm -lpthread -lrt -lasound
|
||||
|
|
|
@ -45,10 +45,10 @@ OBJ = frontend/frontend.o \
|
|||
gfx/fonts/fonts.o \
|
||||
gfx/fonts/bitmapfont.o \
|
||||
gfx/image/image_rpng.o \
|
||||
audio/resampler.o \
|
||||
audio/resamplers/resampler.o \
|
||||
audio/dsp_filter.o \
|
||||
audio/sinc.o \
|
||||
audio/cc_resampler.o \
|
||||
audio/resamplers/sinc.o \
|
||||
audio/resamplers/cc_resampler.o \
|
||||
location/nulllocation.o \
|
||||
camera/nullcamera.o \
|
||||
gfx/nullgfx.o \
|
||||
|
|
|
@ -27,7 +27,7 @@ ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
|||
ifeq ($(HAVE_NEON),1)
|
||||
LOCAL_CFLAGS += -D__ARM_NEON__
|
||||
LOCAL_SRC_FILES += $(RARCH_DIR)/audio/utils_neon.S.neon
|
||||
LOCAL_SRC_FILES += $(RARCH_DIR)/audio/sinc_neon.S.neon
|
||||
LOCAL_SRC_FILES += $(RARCH_DIR)/audio/resamplers/sinc_neon.S.neon
|
||||
endif
|
||||
LOCAL_CFLAGS += -DSINC_LOWER_QUALITY
|
||||
|
||||
|
|
|
@ -352,6 +352,7 @@
|
|||
"-DHAVE_COMPRESSION",
|
||||
"-D_7ZIP_ST",
|
||||
"-DHAVE_7ZIP",
|
||||
"-DHAVE_LAKKA",
|
||||
);
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
|
@ -421,7 +422,7 @@
|
|||
"-D_7ZIP_ST",
|
||||
"-DHAVE_COMPRESSION",
|
||||
"-DHAVE_7ZIP",
|
||||
"-DHAVE_7ZIP",
|
||||
"-DHAVE_LAKKA",
|
||||
);
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
|
|
|
@ -24,11 +24,6 @@
|
|||
static void* const associated_name_tag = (void*)&associated_name_tag;
|
||||
|
||||
@interface RAInputBinder : NSWindow
|
||||
{
|
||||
NSTimer* _timer;
|
||||
const rarch_setting_t* _setting;
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) NSTimer* timer;
|
||||
@property (nonatomic, assign) const rarch_setting_t* setting;
|
||||
@end
|
||||
|
@ -93,15 +88,6 @@ static void* const associated_name_tag = (void*)&associated_name_tag;
|
|||
NSOutlineViewDataSource, NSOutlineViewDelegate,
|
||||
NSWindowDelegate>
|
||||
#endif
|
||||
{
|
||||
RAInputBinder* _binderWindow;
|
||||
NSButtonCell* _booleanCell;
|
||||
NSTextFieldCell* _binderCell;
|
||||
NSTableView* _table;
|
||||
NSOutlineView* _outline;
|
||||
NSMutableArray* _settings;
|
||||
NSMutableArray* _currentGroup;
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) RAInputBinder IBOutlet* binderWindow;
|
||||
@property (nonatomic, retain) NSButtonCell IBOutlet* booleanCell;
|
||||
|
@ -259,9 +245,9 @@ NSWindowDelegate>
|
|||
else
|
||||
{
|
||||
char buffer[PATH_MAX];
|
||||
const rarch_setting_t* setting_data, *setting;
|
||||
setting_data = (const rarch_setting_t*)setting_data_get_list();
|
||||
setting = (const rarch_setting_t*)&setting_data[[item intValue]];
|
||||
rarch_setting_t* setting_data, *setting = NULL;
|
||||
setting_data = (rarch_setting_t*)setting_data_get_list();
|
||||
setting = (rarch_setting_t*)&setting_data[[item intValue]];
|
||||
|
||||
if ([[tableColumn identifier] isEqualToString:BOXSTRING("left")])
|
||||
return BOXSTRING(setting->short_description);
|
||||
|
|
|
@ -70,7 +70,7 @@ static bool ios_camera_poll(void *data, retro_camera_frame_raw_framebuffer_t fra
|
|||
return true;
|
||||
}
|
||||
|
||||
const camera_driver_t camera_ios = {
|
||||
camera_driver_t camera_ios = {
|
||||
ios_camera_init,
|
||||
ios_camera_free,
|
||||
ios_camera_start,
|
||||
|
|
|
@ -71,7 +71,7 @@ fail:
|
|||
return false;
|
||||
}
|
||||
|
||||
const location_driver_t location_apple = {
|
||||
location_driver_t location_apple = {
|
||||
apple_location_init,
|
||||
apple_location_free,
|
||||
apple_location_start,
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
/* Begin PBXFileReference section */
|
||||
501232C7192E5FB00063A359 /* apple_gamecontroller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = apple_gamecontroller.m; path = ../common/apple_gamecontroller.m; sourceTree = "<group>"; };
|
||||
501232C9192E5FC40063A359 /* griffin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = griffin.c; path = ../../griffin/griffin.c; sourceTree = "<group>"; };
|
||||
501232CB192E5FDC0063A359 /* sinc_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = sinc_neon.S; path = ../../audio/sinc_neon.S; sourceTree = "<group>"; };
|
||||
501232CB192E5FDC0063A359 /* sinc_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = sinc_neon.S; path = ../../audio/resamplers/sinc_neon.S; sourceTree = "<group>"; };
|
||||
501232CD192E5FE30063A359 /* utils_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = utils_neon.S; path = ../../audio/utils_neon.S; sourceTree = "<group>"; };
|
||||
501232D5192E60580063A359 /* platform.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = platform.m; sourceTree = "<group>"; };
|
||||
501232D7192E605F0063A359 /* browser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = browser.m; sourceTree = "<group>"; };
|
||||
|
|
39
audio/alsa.c
39
audio/alsa.c
|
@ -71,23 +71,28 @@ static void *alsa_init(const char *device, unsigned rate, unsigned latency)
|
|||
|
||||
snd_pcm_uframes_t buffer_size;
|
||||
|
||||
TRY_ALSA(snd_pcm_open(&alsa->pcm, alsa_dev, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK));
|
||||
TRY_ALSA(snd_pcm_open(
|
||||
&alsa->pcm, alsa_dev, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK));
|
||||
TRY_ALSA(snd_pcm_hw_params_malloc(¶ms));
|
||||
alsa->has_float = find_float_format(alsa->pcm, params);
|
||||
format = alsa->has_float ? SND_PCM_FORMAT_FLOAT : SND_PCM_FORMAT_S16;
|
||||
|
||||
TRY_ALSA(snd_pcm_hw_params_any(alsa->pcm, params));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_access(alsa->pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_access(
|
||||
alsa->pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_format(alsa->pcm, params, format));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_channels(alsa->pcm, params, channels));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_rate(alsa->pcm, params, rate, 0));
|
||||
|
||||
TRY_ALSA(snd_pcm_hw_params_set_buffer_time_near(alsa->pcm, params, &latency_usec, NULL));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_periods_near(alsa->pcm, params, &periods, NULL));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_buffer_time_near(
|
||||
alsa->pcm, params, &latency_usec, NULL));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_periods_near(
|
||||
alsa->pcm, params, &periods, NULL));
|
||||
|
||||
TRY_ALSA(snd_pcm_hw_params(alsa->pcm, params));
|
||||
|
||||
// Shouldn't have to bother with this, but some drivers are apparently broken.
|
||||
/* Shouldn't have to bother with this,
|
||||
* but some drivers are apparently broken. */
|
||||
if (snd_pcm_hw_params_get_period_size(params, &buffer_size, NULL))
|
||||
snd_pcm_hw_params_get_period_size_min(params, &buffer_size, NULL);
|
||||
RARCH_LOG("ALSA: Period size: %d frames\n", (int)buffer_size);
|
||||
|
@ -100,7 +105,8 @@ static void *alsa_init(const char *device, unsigned rate, unsigned latency)
|
|||
|
||||
TRY_ALSA(snd_pcm_sw_params_malloc(&sw_params));
|
||||
TRY_ALSA(snd_pcm_sw_params_current(alsa->pcm, sw_params));
|
||||
TRY_ALSA(snd_pcm_sw_params_set_start_threshold(alsa->pcm, sw_params, buffer_size / 2));
|
||||
TRY_ALSA(snd_pcm_sw_params_set_start_threshold(
|
||||
alsa->pcm, sw_params, buffer_size / 2));
|
||||
TRY_ALSA(snd_pcm_sw_params(alsa->pcm, sw_params));
|
||||
|
||||
snd_pcm_hw_params_free(params);
|
||||
|
@ -165,8 +171,9 @@ static ssize_t alsa_write(void *data, const void *buf_, size_t size_)
|
|||
|
||||
break;
|
||||
}
|
||||
else if (frames == -EAGAIN && !alsa->nonblock) // Definitely not supposed to happen.
|
||||
else if (frames == -EAGAIN && !alsa->nonblock)
|
||||
{
|
||||
/* Definitely not supposed to happen. */
|
||||
RARCH_WARN("[ALSA]: poll() was signaled, but EAGAIN returned from write.\n"
|
||||
"Your ALSA driver might be subtly broken.\n");
|
||||
|
||||
|
@ -177,16 +184,18 @@ static ssize_t alsa_write(void *data, const void *buf_, size_t size_)
|
|||
}
|
||||
return written;
|
||||
}
|
||||
else if (frames == -EAGAIN) // Expected if we're running nonblock.
|
||||
else if (frames == -EAGAIN) /* Expected if we're running nonblock. */
|
||||
return written;
|
||||
else if (frames < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA]: Unknown error occured (%s).\n", snd_strerror(frames));
|
||||
RARCH_ERR("[ALSA]: Unknown error occured (%s).\n",
|
||||
snd_strerror(frames));
|
||||
return -1;
|
||||
}
|
||||
|
||||
written += frames;
|
||||
buf += (frames << 1) * (alsa->has_float ? sizeof(float) : sizeof(int16_t));
|
||||
buf += (frames << 1) *
|
||||
(alsa->has_float ? sizeof(float) : sizeof(int16_t));
|
||||
size -= frames;
|
||||
}
|
||||
|
||||
|
@ -224,7 +233,8 @@ static bool alsa_start(void *data)
|
|||
int ret = snd_pcm_pause(alsa->pcm, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA]: Failed to unpause: %s.\n", snd_strerror(ret));
|
||||
RARCH_ERR("[ALSA]: Failed to unpause: %s.\n",
|
||||
snd_strerror(ret));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
@ -258,7 +268,10 @@ static size_t alsa_write_avail(void *data)
|
|||
snd_pcm_sframes_t avail = snd_pcm_avail(alsa->pcm);
|
||||
if (avail < 0)
|
||||
{
|
||||
//RARCH_WARN("[ALSA]: snd_pcm_avail() failed: %s\n", snd_strerror(avail));
|
||||
#if 0
|
||||
RARCH_WARN("[ALSA]: snd_pcm_avail() failed: %s\n",
|
||||
snd_strerror(avail));
|
||||
#endif
|
||||
return alsa->buffer_size;
|
||||
}
|
||||
|
||||
|
@ -271,7 +284,7 @@ static size_t alsa_buffer_size(void *data)
|
|||
return alsa->buffer_size;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_alsa = {
|
||||
audio_driver_t audio_alsa = {
|
||||
alsa_init,
|
||||
alsa_write,
|
||||
alsa_stop,
|
||||
|
|
|
@ -45,7 +45,8 @@ typedef struct alsa
|
|||
|
||||
typedef long snd_pcm_sframes_t;
|
||||
|
||||
static void *alsa_qsa_init(const char *device, unsigned rate, unsigned latency)
|
||||
static void *alsa_qsa_init(const char *device,
|
||||
unsigned rate, unsigned latency)
|
||||
{
|
||||
int err, card, dev, i;
|
||||
snd_pcm_channel_params_t params = {0};
|
||||
|
@ -64,13 +65,15 @@ static void *alsa_qsa_init(const char *device, unsigned rate, unsigned latency)
|
|||
if ((err = snd_pcm_open_preferred(&alsa->pcm, &card, &dev,
|
||||
SND_PCM_OPEN_PLAYBACK)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA]: Audio open error: %s\n", snd_strerror(err));
|
||||
RARCH_ERR("[ALSA QSA]: Audio open error: %s\n",
|
||||
snd_strerror(err));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if((err = snd_pcm_nonblock_mode(alsa->pcm, 1)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA]: Can't set blocking mode: %s\n", snd_strerror(err));
|
||||
RARCH_ERR("[ALSA QSA]: Can't set blocking mode: %s\n",
|
||||
snd_strerror(err));
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -106,7 +109,8 @@ static void *alsa_qsa_init(const char *device, unsigned rate, unsigned latency)
|
|||
|
||||
if ((err = snd_pcm_channel_params(alsa->pcm, ¶ms)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA]: Channel Parameter Error: %s\n", snd_strerror(err));
|
||||
RARCH_ERR("[ALSA QSA]: Channel Parameter Error: %s\n",
|
||||
snd_strerror(err));
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -114,7 +118,8 @@ static void *alsa_qsa_init(const char *device, unsigned rate, unsigned latency)
|
|||
|
||||
if ((err = snd_pcm_channel_setup(alsa->pcm, &setup)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA]: Channel Parameter Read Back Error: %s\n", snd_strerror(err));
|
||||
RARCH_ERR("[ALSA QSA]: Channel Parameter Read Back Error: %s\n",
|
||||
snd_strerror(err));
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -128,9 +133,11 @@ static void *alsa_qsa_init(const char *device, unsigned rate, unsigned latency)
|
|||
alsa->buf_count = (latency * 4 * rate + 500) / 1000;
|
||||
alsa->buf_count = (alsa->buf_count + alsa->buf_size / 2) / alsa->buf_size;
|
||||
|
||||
if ((err = snd_pcm_channel_prepare(alsa->pcm, SND_PCM_CHANNEL_PLAYBACK)) < 0)
|
||||
if ((err = snd_pcm_channel_prepare(alsa->pcm,
|
||||
SND_PCM_CHANNEL_PLAYBACK)) < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA]: Channel Prepare Error: %s\n", snd_strerror(err));
|
||||
RARCH_ERR("[ALSA QSA]: Channel Prepare Error: %s\n",
|
||||
snd_strerror(err));
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -147,7 +154,8 @@ static void *alsa_qsa_init(const char *device, unsigned rate, unsigned latency)
|
|||
|
||||
alsa->has_float = false;
|
||||
alsa->can_pause = true;
|
||||
RARCH_LOG("[ALSA QSA]: Can pause: %s.\n", alsa->can_pause ? "yes" : "no");
|
||||
RARCH_LOG("[ALSA QSA]: Can pause: %s.\n",
|
||||
alsa->can_pause ? "yes" : "no");
|
||||
|
||||
return alsa;
|
||||
|
||||
|
@ -176,7 +184,8 @@ static int check_pcm_status(void *data, int channel_type)
|
|||
RARCH_LOG("check_pcm_status: SNDP_CM_STATUS_UNDERRUN.\n");
|
||||
if ((ret = snd_pcm_channel_prepare(alsa->pcm, channel_type)) < 0)
|
||||
{
|
||||
RARCH_ERR("Invalid state detected for underrun on snd_pcm_channel_prepare: %s\n", snd_strerror(ret));
|
||||
RARCH_ERR("Invalid state detected for underrun on snd_pcm_channel_prepare: %s\n",
|
||||
snd_strerror(ret));
|
||||
ret = -EPROTO;
|
||||
}
|
||||
}
|
||||
|
@ -185,7 +194,8 @@ static int check_pcm_status(void *data, int channel_type)
|
|||
RARCH_LOG("check_pcm_status: SNDP_CM_STATUS_OVERRUN.\n");
|
||||
if ((ret = snd_pcm_channel_prepare(alsa->pcm, channel_type)) < 0)
|
||||
{
|
||||
RARCH_ERR("Invalid state detected for overrun on snd_pcm_channel_prepare: %s\n", snd_strerror(ret));
|
||||
RARCH_ERR("Invalid state detected for overrun on snd_pcm_channel_prepare: %s\n",
|
||||
snd_strerror(ret));
|
||||
ret = -EPROTO;
|
||||
}
|
||||
}
|
||||
|
@ -194,7 +204,8 @@ static int check_pcm_status(void *data, int channel_type)
|
|||
RARCH_LOG("check_pcm_status: SNDP_CM_STATUS_CHANGE.\n");
|
||||
if ((ret = snd_pcm_channel_prepare(alsa->pcm, channel_type)) < 0)
|
||||
{
|
||||
RARCH_ERR("Invalid state detected for change on snd_pcm_channel_prepare: %s\n", snd_strerror(ret));
|
||||
RARCH_ERR("Invalid state detected for change on snd_pcm_channel_prepare: %s\n",
|
||||
snd_strerror(ret));
|
||||
ret = -EPROTO;
|
||||
}
|
||||
}
|
||||
|
@ -216,13 +227,13 @@ static ssize_t alsa_qsa_write(void *data, const void *buf, size_t size)
|
|||
snd_pcm_channel_status_t cstatus = {0};
|
||||
snd_pcm_sframes_t written = 0;
|
||||
|
||||
|
||||
while (size)
|
||||
{
|
||||
size_t avail_write = min(alsa->buf_size - alsa->buffer_ptr, size);
|
||||
if (avail_write)
|
||||
{
|
||||
memcpy(alsa->buffer[alsa->buffer_index] + alsa->buffer_ptr, buf, avail_write);
|
||||
memcpy(alsa->buffer[alsa->buffer_index] +
|
||||
alsa->buffer_ptr, buf, avail_write);
|
||||
alsa->buffer_ptr += avail_write;
|
||||
buf += avail_write;
|
||||
size -= avail_write;
|
||||
|
@ -231,7 +242,8 @@ static ssize_t alsa_qsa_write(void *data, const void *buf, size_t size)
|
|||
|
||||
if (alsa->buffer_ptr >= alsa->buf_size)
|
||||
{
|
||||
snd_pcm_sframes_t frames = snd_pcm_write(alsa->pcm, alsa->buffer[alsa->buffer_index], alsa->buf_size);
|
||||
snd_pcm_sframes_t frames = snd_pcm_write(alsa->pcm,
|
||||
alsa->buffer[alsa->buffer_index], alsa->buf_size);
|
||||
|
||||
alsa->buffer_index = (alsa->buffer_index + 1) % alsa->buf_count;
|
||||
alsa->buffer_ptr = 0;
|
||||
|
@ -297,7 +309,8 @@ static bool alsa_qsa_start(void *data)
|
|||
int ret = snd_pcm_playback_resume(alsa->pcm);
|
||||
if (ret < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA]: Failed to unpause: %s.\n", snd_strerror(ret));
|
||||
RARCH_ERR("[ALSA QSA]: Failed to unpause: %s.\n",
|
||||
snd_strerror(ret));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
@ -336,7 +349,9 @@ static void alsa_qsa_free(void *data)
|
|||
static size_t alsa_qsa_write_avail(void *data)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
size_t avail = (alsa->buf_count - (int)alsa->buffered_blocks - 1) * alsa->buf_size + (alsa->buf_size - (int)alsa->buffer_ptr);
|
||||
size_t avail = (alsa->buf_count -
|
||||
(int)alsa->buffered_blocks - 1) * alsa->buf_size +
|
||||
(alsa->buf_size - (int)alsa->buffer_ptr);
|
||||
return avail;
|
||||
}
|
||||
|
||||
|
@ -346,7 +361,7 @@ static size_t alsa_qsa_buffer_size(void *data)
|
|||
return alsa->buf_size * alsa->buf_count;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_alsa = {
|
||||
audio_driver_t audio_alsa = {
|
||||
alsa_qsa_init,
|
||||
alsa_qsa_write,
|
||||
alsa_qsa_stop,
|
||||
|
|
|
@ -64,12 +64,14 @@ static void alsa_worker_thread(void *data)
|
|||
scond_signal(alsa->cond);
|
||||
slock_unlock(alsa->fifo_lock);
|
||||
|
||||
// If underrun, fill rest with silence.
|
||||
/* If underrun, fill rest with silence. */
|
||||
memset(buf + fifo_size, 0, alsa->period_size - fifo_size);
|
||||
|
||||
snd_pcm_sframes_t frames = snd_pcm_writei(alsa->pcm, buf, alsa->period_frames);
|
||||
snd_pcm_sframes_t frames = snd_pcm_writei(
|
||||
alsa->pcm, buf, alsa->period_frames);
|
||||
|
||||
if (frames == -EPIPE || frames == -EINTR || frames == -ESTRPIPE)
|
||||
if (frames == -EPIPE || frames == -EINTR ||
|
||||
frames == -ESTRPIPE)
|
||||
{
|
||||
if (snd_pcm_recover(alsa->pcm, frames, 1) < 0)
|
||||
{
|
||||
|
@ -82,7 +84,8 @@ static void alsa_worker_thread(void *data)
|
|||
}
|
||||
else if (frames < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA]: Unknown error occured (%s).\n", snd_strerror(frames));
|
||||
RARCH_ERR("[ALSA]: Unknown error occured (%s).\n",
|
||||
snd_strerror(frames));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +104,8 @@ static bool alsa_thread_use_float(void *data)
|
|||
return alsa->has_float;
|
||||
}
|
||||
|
||||
static bool alsathread_find_float_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
||||
static bool alsathread_find_float_format(snd_pcm_t *pcm,
|
||||
snd_pcm_hw_params_t *params)
|
||||
{
|
||||
if (snd_pcm_hw_params_test_format(pcm, params, SND_PCM_FORMAT_FLOAT) == 0)
|
||||
{
|
||||
|
@ -140,7 +144,8 @@ static void alsa_thread_free(void *data)
|
|||
}
|
||||
}
|
||||
|
||||
static void *alsa_thread_init(const char *device, unsigned rate, unsigned latency)
|
||||
static void *alsa_thread_init(const char *device,
|
||||
unsigned rate, unsigned latency)
|
||||
{
|
||||
alsa_thread_t *alsa = (alsa_thread_t*)calloc(1, sizeof(alsa_thread_t));
|
||||
if (!alsa)
|
||||
|
@ -167,19 +172,24 @@ static void *alsa_thread_init(const char *device, unsigned rate, unsigned latenc
|
|||
format = alsa->has_float ? SND_PCM_FORMAT_FLOAT : SND_PCM_FORMAT_S16;
|
||||
|
||||
TRY_ALSA(snd_pcm_hw_params_any(alsa->pcm, params));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_access(alsa->pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_access(
|
||||
alsa->pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_format(alsa->pcm, params, format));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_channels(alsa->pcm, params, channels));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_rate(alsa->pcm, params, rate, 0));
|
||||
|
||||
TRY_ALSA(snd_pcm_hw_params_set_buffer_time_near(alsa->pcm, params, &latency_usec, NULL));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_periods_near(alsa->pcm, params, &periods, NULL));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_buffer_time_near(
|
||||
alsa->pcm, params, &latency_usec, NULL));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_periods_near(
|
||||
alsa->pcm, params, &periods, NULL));
|
||||
|
||||
TRY_ALSA(snd_pcm_hw_params(alsa->pcm, params));
|
||||
|
||||
// Shouldn't have to bother with this, but some drivers are apparently broken.
|
||||
/* Shouldn't have to bother with this,
|
||||
* but some drivers are apparently broken. */
|
||||
if (snd_pcm_hw_params_get_period_size(params, &alsa->period_frames, NULL))
|
||||
snd_pcm_hw_params_get_period_size_min(params, &alsa->period_frames, NULL);
|
||||
snd_pcm_hw_params_get_period_size_min(
|
||||
params, &alsa->period_frames, NULL);
|
||||
RARCH_LOG("ALSA: Period size: %d frames\n", (int)alsa->period_frames);
|
||||
if (snd_pcm_hw_params_get_buffer_size(params, &buffer_size))
|
||||
snd_pcm_hw_params_get_buffer_size_max(params, &buffer_size);
|
||||
|
@ -190,7 +200,8 @@ static void *alsa_thread_init(const char *device, unsigned rate, unsigned latenc
|
|||
|
||||
TRY_ALSA(snd_pcm_sw_params_malloc(&sw_params));
|
||||
TRY_ALSA(snd_pcm_sw_params_current(alsa->pcm, sw_params));
|
||||
TRY_ALSA(snd_pcm_sw_params_set_start_threshold(alsa->pcm, sw_params, buffer_size / 2));
|
||||
TRY_ALSA(snd_pcm_sw_params_set_start_threshold(
|
||||
alsa->pcm, sw_params, buffer_size / 2));
|
||||
TRY_ALSA(snd_pcm_sw_params(alsa->pcm, sw_params));
|
||||
|
||||
snd_pcm_hw_params_free(params);
|
||||
|
@ -305,7 +316,7 @@ static size_t alsa_thread_buffer_size(void *data)
|
|||
return alsa->buffer_size;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_alsathread = {
|
||||
audio_driver_t audio_alsathread = {
|
||||
alsa_thread_init,
|
||||
alsa_thread_write,
|
||||
alsa_thread_stop,
|
||||
|
|
|
@ -76,7 +76,8 @@ static void coreaudio_free(void *data)
|
|||
free(dev);
|
||||
}
|
||||
|
||||
static OSStatus audio_write_cb(void *userdata, AudioUnitRenderActionFlags *action_flags,
|
||||
static OSStatus audio_write_cb(void *userdata,
|
||||
AudioUnitRenderActionFlags *action_flags,
|
||||
const AudioTimeStamp *time_stamp, UInt32 bus_number,
|
||||
UInt32 number_frames, AudioBufferList *io_data)
|
||||
{
|
||||
|
@ -97,9 +98,14 @@ static OSStatus audio_write_cb(void *userdata, AudioUnitRenderActionFlags *actio
|
|||
if (fifo_read_avail(dev->buffer) < write_avail)
|
||||
{
|
||||
*action_flags = kAudioUnitRenderAction_OutputIsSilence;
|
||||
memset(outbuf, 0, write_avail); // Seems to be needed.
|
||||
|
||||
/* Seems to be needed. */
|
||||
memset(outbuf, 0, write_avail);
|
||||
|
||||
pthread_mutex_unlock(&dev->lock);
|
||||
pthread_cond_signal(&dev->cond); // Technically possible to deadlock without.
|
||||
|
||||
/* Technically possible to deadlock without. */
|
||||
pthread_cond_signal(&dev->cond);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
@ -121,13 +127,15 @@ static void choose_output_device(coreaudio_t *dev, const char* device)
|
|||
|
||||
UInt32 size = 0;
|
||||
|
||||
if (AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propaddr, 0, 0, &size) != noErr)
|
||||
if (AudioObjectGetPropertyDataSize(kAudioObjectSystemObject,
|
||||
&propaddr, 0, 0, &size) != noErr)
|
||||
return;
|
||||
|
||||
UInt32 deviceCount = size / sizeof(AudioDeviceID);
|
||||
AudioDeviceID *devices = malloc(size);
|
||||
|
||||
if (!devices || AudioObjectGetPropertyData(kAudioObjectSystemObject, &propaddr, 0, 0, &size, devices) != noErr)
|
||||
if (!devices || AudioObjectGetPropertyData(kAudioObjectSystemObject,
|
||||
&propaddr, 0, 0, &size, devices) != noErr)
|
||||
goto done;
|
||||
|
||||
propaddr.mScope = kAudioDevicePropertyScopeOutput;
|
||||
|
@ -139,9 +147,12 @@ static void choose_output_device(coreaudio_t *dev, const char* device)
|
|||
char device_name[1024];
|
||||
device_name[0] = 0;
|
||||
|
||||
if (AudioObjectGetPropertyData(devices[i], &propaddr, 0, 0, &size, device_name) == noErr && strcmp(device_name, device) == 0)
|
||||
if (AudioObjectGetPropertyData(devices[i],
|
||||
&propaddr, 0, 0, &size, device_name) == noErr
|
||||
&& !strcmp(device_name, device))
|
||||
{
|
||||
AudioUnitSetProperty(dev->dev, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &devices[i], sizeof(AudioDeviceID));
|
||||
AudioUnitSetProperty(dev->dev, kAudioOutputUnitProperty_CurrentDevice,
|
||||
kAudioUnitScope_Global, 0, &devices[i], sizeof(AudioDeviceID));
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +170,8 @@ static void coreaudio_interrupt_listener(void *data, UInt32 interrupt_state)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void *coreaudio_init(const char *device, unsigned rate, unsigned latency)
|
||||
static void *coreaudio_init(const char *device,
|
||||
unsigned rate, unsigned latency)
|
||||
{
|
||||
(void)device;
|
||||
|
||||
|
@ -227,15 +239,18 @@ static void *coreaudio_init(const char *device, unsigned rate, unsigned latency)
|
|||
stream_desc.mBytesPerFrame = 2 * sizeof(float);
|
||||
stream_desc.mFramesPerPacket = 1;
|
||||
stream_desc.mFormatID = kAudioFormatLinearPCM;
|
||||
stream_desc.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked | (is_little_endian() ? 0 : kAudioFormatFlagIsBigEndian);
|
||||
stream_desc.mFormatFlags = kAudioFormatFlagIsFloat |
|
||||
kAudioFormatFlagIsPacked | (is_little_endian() ?
|
||||
0 : kAudioFormatFlagIsBigEndian);
|
||||
|
||||
if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input, 0, &stream_desc, sizeof(stream_desc)) != noErr)
|
||||
goto error;
|
||||
|
||||
// Check returned audio format
|
||||
/* Check returned audio format. */
|
||||
UInt32 i_size = sizeof(real_desc);;
|
||||
if (AudioUnitGetProperty(dev->dev, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &real_desc, &i_size) != noErr)
|
||||
if (AudioUnitGetProperty(dev->dev, kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input, 0, &real_desc, &i_size) != noErr)
|
||||
goto error;
|
||||
|
||||
if (real_desc.mChannelsPerFrame != stream_desc.mChannelsPerFrame)
|
||||
|
@ -247,11 +262,12 @@ static void *coreaudio_init(const char *device, unsigned rate, unsigned latency)
|
|||
if (real_desc.mFormatID != stream_desc.mFormatID)
|
||||
goto error;
|
||||
|
||||
RARCH_LOG("[CoreAudio]: Using output sample rate of %.1f Hz\n", (float)real_desc.mSampleRate);
|
||||
RARCH_LOG("[CoreAudio]: Using output sample rate of %.1f Hz\n",
|
||||
(float)real_desc.mSampleRate);
|
||||
g_settings.audio.out_rate = real_desc.mSampleRate;
|
||||
|
||||
|
||||
// Set channel layout (fails on iOS)
|
||||
/* Set channel layout (fails on iOS). */
|
||||
#ifndef IOS
|
||||
AudioChannelLayout layout = {0};
|
||||
|
||||
|
@ -261,7 +277,7 @@ static void *coreaudio_init(const char *device, unsigned rate, unsigned latency)
|
|||
goto error;
|
||||
#endif
|
||||
|
||||
// Set callbacks and finish up
|
||||
/* Set callbacks and finish up. */
|
||||
AURenderCallbackStruct cb = {0};
|
||||
cb.inputProc = audio_write_cb;
|
||||
cb.inputProcRefCon = dev;
|
||||
|
@ -283,7 +299,8 @@ static void *coreaudio_init(const char *device, unsigned rate, unsigned latency)
|
|||
if (!dev->buffer)
|
||||
goto error;
|
||||
|
||||
RARCH_LOG("[CoreAudio]: Using buffer size of %u bytes: (latency = %u ms)\n", (unsigned)fifo_size, latency);
|
||||
RARCH_LOG("[CoreAudio]: Using buffer size of %u bytes: (latency = %u ms)\n",
|
||||
(unsigned)fifo_size, latency);
|
||||
|
||||
if (AudioOutputUnitStart(dev->dev) != noErr)
|
||||
goto error;
|
||||
|
@ -333,7 +350,8 @@ static ssize_t coreaudio_write(void *data, const void *buf_, size_t size)
|
|||
}
|
||||
|
||||
#ifdef IOS
|
||||
if (write_avail == 0 && pthread_cond_timedwait(&dev->cond, &dev->lock, &timeout) == ETIMEDOUT)
|
||||
if (write_avail == 0 && pthread_cond_timedwait(
|
||||
&dev->cond, &dev->lock, &timeout) == ETIMEDOUT)
|
||||
g_interrupted = true;
|
||||
#else
|
||||
if (write_avail == 0)
|
||||
|
@ -384,7 +402,7 @@ static size_t coreaudio_buffer_size(void *data)
|
|||
return dev->buffer_size;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_coreaudio = {
|
||||
audio_driver_t audio_coreaudio = {
|
||||
coreaudio_init,
|
||||
coreaudio_write,
|
||||
coreaudio_stop,
|
||||
|
@ -396,4 +414,3 @@ const audio_driver_t audio_coreaudio = {
|
|||
coreaudio_write_avail,
|
||||
coreaudio_buffer_size,
|
||||
};
|
||||
|
||||
|
|
|
@ -451,16 +451,21 @@ static size_t dsound_buffer_size(void *data)
|
|||
return 4 * 1024;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_dsound = {
|
||||
static bool dsound_use_float(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return false;
|
||||
}
|
||||
|
||||
audio_driver_t audio_dsound = {
|
||||
dsound_init,
|
||||
dsound_write,
|
||||
dsound_stop,
|
||||
dsound_start,
|
||||
dsound_set_nonblock_state,
|
||||
dsound_free,
|
||||
NULL,
|
||||
dsound_use_float,
|
||||
"dsound",
|
||||
dsound_write_avail,
|
||||
dsound_buffer_size,
|
||||
};
|
||||
|
||||
|
|
|
@ -60,7 +60,8 @@ static volatile gx_audio_t *gx_audio_data;
|
|||
static void dma_callback(void)
|
||||
{
|
||||
gx_audio_t *wa = (gx_audio_t*)gx_audio_data;
|
||||
// erase last chunk to avoid repeating audio
|
||||
|
||||
/* Erase last chunk to avoid repeating audio. */
|
||||
memset(wa->data[wa->dma_busy], 0, CHUNK_SIZE);
|
||||
|
||||
wa->dma_busy = wa->dma_next;
|
||||
|
@ -72,7 +73,8 @@ static void dma_callback(void)
|
|||
OSSignalCond(wa->cond);
|
||||
}
|
||||
|
||||
static void *gx_audio_init(const char *device, unsigned rate, unsigned latency)
|
||||
static void *gx_audio_init(const char *device,
|
||||
unsigned rate, unsigned latency)
|
||||
{
|
||||
gx_audio_t *wa = (gx_audio_t*)memalign(32, sizeof(*wa));
|
||||
if (!wa)
|
||||
|
@ -106,8 +108,9 @@ static void *gx_audio_init(const char *device, unsigned rate, unsigned latency)
|
|||
return wa;
|
||||
}
|
||||
|
||||
// Wii uses silly R, L, R, L interleaving ...
|
||||
static inline void copy_swapped(uint32_t * restrict dst, const uint32_t * restrict src, size_t size)
|
||||
/* Wii uses silly R, L, R, L interleaving. */
|
||||
static inline void copy_swapped(uint32_t * restrict dst,
|
||||
const uint32_t * restrict src, size_t size)
|
||||
{
|
||||
do
|
||||
{
|
||||
|
@ -128,8 +131,10 @@ static ssize_t gx_audio_write(void *data, const void *buf_, size_t size)
|
|||
if (frames < to_write)
|
||||
to_write = frames;
|
||||
|
||||
// FIXME: Nonblocking audio should break out of loop when it has nothing to write.
|
||||
while ((wa->dma_write == wa->dma_next || wa->dma_write == wa->dma_busy) && !wa->nonblock)
|
||||
/* FIXME: Nonblocking audio should break out of loop
|
||||
* when it has nothing to write. */
|
||||
while ((wa->dma_write == wa->dma_next ||
|
||||
wa->dma_write == wa->dma_busy) && !wa->nonblock)
|
||||
OSSleepThread(wa->cond);
|
||||
|
||||
copy_swapped(wa->data[wa->dma_write] + wa->write_ptr, buf, to_write);
|
||||
|
@ -198,7 +203,8 @@ static void gx_audio_free(void *data)
|
|||
static size_t gx_audio_write_avail(void *data)
|
||||
{
|
||||
gx_audio_t *wa = (gx_audio_t*)data;
|
||||
return ((wa->dma_busy - wa->dma_write + BLOCKS) & (BLOCKS - 1)) * CHUNK_SIZE;
|
||||
return ((wa->dma_busy - wa->dma_write + BLOCKS)
|
||||
& (BLOCKS - 1)) * CHUNK_SIZE;
|
||||
}
|
||||
|
||||
static size_t gx_audio_buffer_size(void *data)
|
||||
|
@ -214,7 +220,7 @@ static bool gx_audio_use_float(void *data)
|
|||
return false;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_gx = {
|
||||
audio_driver_t audio_gx = {
|
||||
gx_audio_init,
|
||||
gx_audio_write,
|
||||
gx_audio_stop,
|
||||
|
|
|
@ -330,7 +330,7 @@ static size_t ja_buffer_size(void *data)
|
|||
return jd->buffer_size;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_jack = {
|
||||
audio_driver_t audio_jack = {
|
||||
ja_init,
|
||||
ja_write,
|
||||
ja_stop,
|
||||
|
@ -342,4 +342,3 @@ const audio_driver_t audio_jack = {
|
|||
ja_write_avail,
|
||||
ja_buffer_size,
|
||||
};
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ static bool null_audio_use_float(void *data)
|
|||
return true;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_null = {
|
||||
audio_driver_t audio_null = {
|
||||
null_audio_init,
|
||||
null_audio_write,
|
||||
null_audio_stop,
|
||||
|
@ -70,5 +70,6 @@ const audio_driver_t audio_null = {
|
|||
null_audio_free,
|
||||
null_audio_use_float,
|
||||
"null",
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -233,16 +233,21 @@ static size_t al_buffer_size(void *data)
|
|||
return (al->num_buffers + 1) * BUFSIZE; // Also got tmpbuf.
|
||||
}
|
||||
|
||||
const audio_driver_t audio_openal = {
|
||||
static bool al_use_float(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return false;
|
||||
}
|
||||
|
||||
audio_driver_t audio_openal = {
|
||||
al_init,
|
||||
al_write,
|
||||
al_stop,
|
||||
al_start,
|
||||
al_set_nonblock_state,
|
||||
al_free,
|
||||
NULL,
|
||||
al_use_float,
|
||||
"openal",
|
||||
al_write_avail,
|
||||
al_buffer_size,
|
||||
};
|
||||
|
||||
|
|
|
@ -284,7 +284,7 @@ static bool sl_use_float(void *data)
|
|||
return false;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_opensl = {
|
||||
audio_driver_t audio_opensl = {
|
||||
sl_init,
|
||||
sl_write,
|
||||
sl_stop,
|
||||
|
@ -296,4 +296,3 @@ const audio_driver_t audio_opensl = {
|
|||
sl_write_avail,
|
||||
sl_buffer_size,
|
||||
};
|
||||
|
||||
|
|
11
audio/oss.c
11
audio/oss.c
|
@ -181,16 +181,21 @@ static size_t oss_buffer_size(void *data)
|
|||
return info.fragsize * info.fragstotal;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_oss = {
|
||||
static bool oss_use_float(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return false;
|
||||
}
|
||||
|
||||
audio_driver_t audio_oss = {
|
||||
oss_init,
|
||||
oss_write,
|
||||
oss_stop,
|
||||
oss_start,
|
||||
oss_set_nonblock_state,
|
||||
oss_free,
|
||||
NULL,
|
||||
oss_use_float,
|
||||
"oss",
|
||||
oss_write_avail,
|
||||
oss_buffer_size,
|
||||
};
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
|
||||
#include "../ps3/sdk_defines.h"
|
||||
|
||||
#define AUDIO_BLOCKS 8 // 8 or 16. Guess what we choose? :)
|
||||
#define AUDIO_CHANNELS 2 // All hail glorious stereo!
|
||||
#define AUDIO_BLOCKS 8
|
||||
#define AUDIO_CHANNELS 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -54,7 +54,8 @@ static void event_loop(uint64_t data)
|
|||
cellAudioCreateNotifyEventQueue(&id, &key);
|
||||
cellAudioSetNotifyEventQueue(key);
|
||||
|
||||
float out_tmp[CELL_AUDIO_BLOCK_SAMPLES * AUDIO_CHANNELS] __attribute__((aligned(16)));
|
||||
float out_tmp[CELL_AUDIO_BLOCK_SAMPLES * AUDIO_CHANNELS]
|
||||
__attribute__((aligned(16)));
|
||||
|
||||
while (!aud->quit_thread)
|
||||
{
|
||||
|
@ -68,14 +69,16 @@ static void event_loop(uint64_t data)
|
|||
sys_lwmutex_unlock(&aud->lock);
|
||||
sys_lwcond_signal(&aud->cond);
|
||||
|
||||
cellAudioAddData(aud->audio_port, out_tmp, CELL_AUDIO_BLOCK_SAMPLES, 1.0);
|
||||
cellAudioAddData(aud->audio_port, out_tmp,
|
||||
CELL_AUDIO_BLOCK_SAMPLES, 1.0);
|
||||
}
|
||||
|
||||
cellAudioRemoveNotifyEventQueue(key);
|
||||
sys_ppu_thread_exit(0);
|
||||
}
|
||||
|
||||
static void *ps3_audio_init(const char *device, unsigned rate, unsigned latency)
|
||||
static void *ps3_audio_init(const char *device,
|
||||
unsigned rate, unsigned latency)
|
||||
{
|
||||
(void)latency;
|
||||
(void)device;
|
||||
|
@ -103,11 +106,14 @@ static void *ps3_audio_init(const char *device, unsigned rate, unsigned latency)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
data->buffer = fifo_new(CELL_AUDIO_BLOCK_SAMPLES * AUDIO_CHANNELS * AUDIO_BLOCKS * sizeof(float));
|
||||
data->buffer = fifo_new(CELL_AUDIO_BLOCK_SAMPLES *
|
||||
AUDIO_CHANNELS * AUDIO_BLOCKS * sizeof(float));
|
||||
|
||||
#ifdef __PSL1GHT__
|
||||
sys_lwmutex_attr_t lock_attr = {SYS_LWMUTEX_ATTR_PROTOCOL, SYS_LWMUTEX_ATTR_RECURSIVE, "\0"};
|
||||
sys_lwmutex_attr_t cond_lock_attr = {SYS_LWMUTEX_ATTR_PROTOCOL, SYS_LWMUTEX_ATTR_RECURSIVE, "\0"};
|
||||
sys_lwmutex_attr_t lock_attr =
|
||||
{SYS_LWMUTEX_ATTR_PROTOCOL, SYS_LWMUTEX_ATTR_RECURSIVE, "\0"};
|
||||
sys_lwmutex_attr_t cond_lock_attr =
|
||||
{SYS_LWMUTEX_ATTR_PROTOCOL, SYS_LWMUTEX_ATTR_RECURSIVE, "\0"};
|
||||
sys_lwcond_attribute_t cond_attr = {"\0"};
|
||||
#else
|
||||
sys_lwmutex_attribute_t lock_attr;
|
||||
|
@ -212,7 +218,7 @@ static bool ps3_audio_use_float(void *data)
|
|||
return true;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_ps3 = {
|
||||
audio_driver_t audio_ps3 = {
|
||||
ps3_audio_init,
|
||||
ps3_audio_write,
|
||||
ps3_audio_stop,
|
||||
|
@ -220,6 +226,7 @@ const audio_driver_t audio_ps3 = {
|
|||
ps3_audio_set_nonblock_state,
|
||||
ps3_audio_free,
|
||||
ps3_audio_use_float,
|
||||
"ps3"
|
||||
"ps3",
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include <pspaudio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
//ToDO
|
||||
typedef struct psp1_audio
|
||||
{
|
||||
bool nonblocking;
|
||||
|
@ -48,13 +47,16 @@ static int audioMainLoop(SceSize args, void* argp)
|
|||
|
||||
while (psp->running)
|
||||
{
|
||||
uint16_t readPos = psp->readPos; // get a non volatile copy
|
||||
/* Get a non-volatile copy. */
|
||||
uint16_t readPos = psp->readPos;
|
||||
|
||||
if (((uint16_t)(psp->writePos - readPos) & AUDIO_BUFFER_SIZE_MASK) < (AUDIO_OUT_COUNT * 2))
|
||||
if (((uint16_t)(psp->writePos - readPos) & AUDIO_BUFFER_SIZE_MASK)
|
||||
< (AUDIO_OUT_COUNT * 2))
|
||||
sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX, psp->zeroBuffer);
|
||||
else
|
||||
{
|
||||
sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX, psp->buffer + readPos);
|
||||
sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX,
|
||||
psp->buffer + readPos);
|
||||
readPos += AUDIO_OUT_COUNT;
|
||||
readPos &= AUDIO_BUFFER_SIZE_MASK;
|
||||
psp->readPos = readPos;
|
||||
|
@ -66,7 +68,8 @@ static int audioMainLoop(SceSize args, void* argp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void *psp_audio_init(const char *device, unsigned rate, unsigned latency)
|
||||
static void *psp_audio_init(const char *device,
|
||||
unsigned rate, unsigned latency)
|
||||
{
|
||||
(void)device;
|
||||
(void)latency;
|
||||
|
@ -76,16 +79,20 @@ static void *psp_audio_init(const char *device, unsigned rate, unsigned latency)
|
|||
if (!psp)
|
||||
return NULL;
|
||||
|
||||
psp->buffer = (uint32_t*)memalign(64, AUDIO_BUFFER_SIZE * sizeof(uint32_t)); // cache aligned, not necessary but helpful
|
||||
/* Cache aligned, not necessary but helpful. */
|
||||
psp->buffer = (uint32_t*)
|
||||
memalign(64, AUDIO_BUFFER_SIZE * sizeof(uint32_t));
|
||||
memset(psp->buffer, 0, AUDIO_BUFFER_SIZE * sizeof(uint32_t));
|
||||
|
||||
psp->zeroBuffer = (uint32_t*)memalign(64, AUDIO_OUT_COUNT * sizeof(uint32_t));
|
||||
psp->zeroBuffer = (uint32_t*)
|
||||
memalign(64, AUDIO_OUT_COUNT * sizeof(uint32_t));
|
||||
memset(psp->zeroBuffer, 0, AUDIO_OUT_COUNT * sizeof(uint32_t));
|
||||
|
||||
psp->readPos = 0;
|
||||
psp->writePos = 0;
|
||||
psp->rate = rate;
|
||||
psp->thread = sceKernelCreateThread ("audioMainLoop", audioMainLoop, 0x08, 0x10000, 0, NULL);
|
||||
psp->thread = sceKernelCreateThread
|
||||
("audioMainLoop", audioMainLoop, 0x08, 0x10000, 0, NULL);
|
||||
psp->nonblocking = false;
|
||||
|
||||
psp->running = true;
|
||||
|
@ -118,15 +125,20 @@ static ssize_t psp_audio_write(void *data, const void *buf, size_t size)
|
|||
|
||||
sampleCount= size / sizeof(uint32_t);
|
||||
|
||||
// if (psp->nonblocking)
|
||||
// {
|
||||
// /* TODO */
|
||||
// }
|
||||
#if 0
|
||||
if (psp->nonblocking)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
#endif
|
||||
|
||||
if((writePos + sampleCount) > AUDIO_BUFFER_SIZE)
|
||||
{
|
||||
memcpy(psp->buffer + writePos, buf, (AUDIO_BUFFER_SIZE - writePos) * sizeof(uint32_t));
|
||||
memcpy(psp->buffer, (uint32_t*) buf + (AUDIO_BUFFER_SIZE - writePos), (writePos + sampleCount - AUDIO_BUFFER_SIZE) * sizeof(uint32_t));
|
||||
memcpy(psp->buffer + writePos, buf,
|
||||
(AUDIO_BUFFER_SIZE - writePos) * sizeof(uint32_t));
|
||||
memcpy(psp->buffer, (uint32_t*) buf +
|
||||
(AUDIO_BUFFER_SIZE - writePos),
|
||||
(writePos + sampleCount - AUDIO_BUFFER_SIZE) * sizeof(uint32_t));
|
||||
}
|
||||
else
|
||||
memcpy(psp->buffer + writePos, buf, size);
|
||||
|
@ -145,7 +157,8 @@ static bool psp_audio_stop(void *data)
|
|||
|
||||
runStatus.size = sizeof(SceKernelThreadRunStatus);
|
||||
|
||||
if (sceKernelReferThreadRunStatus(psp->thread, &runStatus) < 0) // error
|
||||
if (sceKernelReferThreadRunStatus(
|
||||
psp->thread, &runStatus) < 0) /* Error */
|
||||
return false;
|
||||
if (runStatus.status == PSP_THREAD_STOPPED)
|
||||
return false;
|
||||
|
@ -164,7 +177,8 @@ static bool psp_audio_start(void *data)
|
|||
|
||||
runStatus.size = sizeof(SceKernelThreadRunStatus);
|
||||
|
||||
if (sceKernelReferThreadRunStatus(psp->thread, &runStatus) < 0) // error
|
||||
if (sceKernelReferThreadRunStatus(
|
||||
psp->thread, &runStatus) < 0) /* Error */
|
||||
return false;
|
||||
if (runStatus.status != PSP_THREAD_STOPPED)
|
||||
return false;
|
||||
|
@ -192,7 +206,8 @@ static size_t psp_write_avail(void *data)
|
|||
{
|
||||
/* TODO */
|
||||
psp1_audio_t* psp = (psp1_audio_t*)data;
|
||||
return AUDIO_BUFFER_SIZE - ((uint16_t)(psp->writePos - psp->readPos) & AUDIO_BUFFER_SIZE_MASK);
|
||||
return AUDIO_BUFFER_SIZE - ((uint16_t)
|
||||
(psp->writePos - psp->readPos) & AUDIO_BUFFER_SIZE_MASK);
|
||||
}
|
||||
|
||||
static size_t psp_buffer_size(void *data)
|
||||
|
@ -202,7 +217,7 @@ static size_t psp_buffer_size(void *data)
|
|||
}
|
||||
|
||||
|
||||
const audio_driver_t audio_psp1 = {
|
||||
audio_driver_t audio_psp1 = {
|
||||
psp_audio_init,
|
||||
psp_audio_write,
|
||||
psp_audio_stop,
|
||||
|
|
|
@ -298,7 +298,7 @@ static size_t pulse_buffer_size(void *data)
|
|||
return pa->buffer_size;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_pulse = {
|
||||
audio_driver_t audio_pulse = {
|
||||
pulse_init,
|
||||
pulse_write,
|
||||
pulse_stop,
|
||||
|
@ -310,4 +310,3 @@ const audio_driver_t audio_pulse = {
|
|||
pulse_write_avail,
|
||||
pulse_buffer_size,
|
||||
};
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#if !defined(RESAMPLER_TEST) && defined(RARCH_INTERNAL)
|
||||
#include "../general.h"
|
||||
#include "../../general.h"
|
||||
#else
|
||||
#define RARCH_LOG(...) fprintf(stderr, __VA_ARGS__)
|
||||
#endif
|
||||
|
@ -47,7 +47,8 @@ static void resampler_CC_process(void *re_, struct resampler_data *data)
|
|||
float ratio, fraction;
|
||||
|
||||
audio_frame_float_t *inp = (audio_frame_float_t*)data->data_in;
|
||||
audio_frame_float_t *inp_max = (audio_frame_float_t*)(inp + data->input_frames);
|
||||
audio_frame_float_t *inp_max = (audio_frame_float_t*)
|
||||
(inp + data->input_frames);
|
||||
audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out;
|
||||
|
||||
__asm__ (
|
||||
|
@ -126,7 +127,8 @@ static void resampler_CC_process(void *re_, struct resampler_data *data)
|
|||
outp++;
|
||||
}
|
||||
|
||||
// The VFPU state is assumed to remain intact in-between calls to resampler_CC_process.
|
||||
/* The VFPU state is assumed to remain intact
|
||||
* in-between calls to resampler_CC_process. */
|
||||
|
||||
done:
|
||||
data->output_frames = outp - (audio_frame_float_t*)data->data_out;
|
||||
|
@ -144,8 +146,8 @@ static void *resampler_CC_init(double bandwidth_mod)
|
|||
".set push\n"
|
||||
".set noreorder\n"
|
||||
|
||||
"vcst.s s710, VFPU_PI \n" // 710 = pi
|
||||
"vcst.s s711, VFPU_1_PI \n" // 711 = 1.0 / (pi)
|
||||
"vcst.s s710, VFPU_PI \n" /* 710 = pi */
|
||||
"vcst.s s711, VFPU_1_PI \n" /* 711 = 1.0 / (pi) */
|
||||
|
||||
"vzero.q c720 \n"
|
||||
"vzero.q c730 \n"
|
||||
|
@ -157,7 +159,7 @@ static void *resampler_CC_init(double bandwidth_mod)
|
|||
}
|
||||
#else
|
||||
|
||||
// C reference version. Not optimized.
|
||||
/* C reference version. Not optimized. */
|
||||
typedef struct rarch_CC_resampler
|
||||
{
|
||||
audio_frame_float_t buffer[4];
|
||||
|
@ -176,7 +178,8 @@ static inline float cc_kernel(float x, float b)
|
|||
return (cc_int(x + 0.5, b) - cc_int(x - 0.5, b)) / (2.0 * M_PI);
|
||||
}
|
||||
|
||||
static inline void add_to(const audio_frame_float_t *source, audio_frame_float_t *target, float ratio)
|
||||
static inline void add_to(const audio_frame_float_t *source,
|
||||
audio_frame_float_t *target, float ratio)
|
||||
{
|
||||
target->l += source->l * ratio;
|
||||
target->r += source->r * ratio;
|
||||
|
@ -192,7 +195,7 @@ static void resampler_CC_downsample(void *re_, struct resampler_data *data)
|
|||
audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out;
|
||||
|
||||
ratio = 1.0 / data->ratio;
|
||||
b = data->ratio; // cutoff frequency
|
||||
b = data->ratio; /* cutoff frequency. */
|
||||
|
||||
while (inp != inp_max)
|
||||
{
|
||||
|
@ -234,7 +237,7 @@ static void resampler_CC_upsample(void *re_, struct resampler_data *data)
|
|||
audio_frame_float_t *inp_max = (audio_frame_float_t*)(inp + data->input_frames);
|
||||
audio_frame_float_t *outp = (audio_frame_float_t*)data->data_out;
|
||||
|
||||
b = min(data->ratio, 1.00); // cutoff frequency
|
||||
b = min(data->ratio, 1.00); /* cutoff frequency. */
|
||||
ratio = 1.0 / data->ratio;
|
||||
|
||||
while (inp != inp_max)
|
||||
|
@ -285,7 +288,8 @@ static void resampler_CC_free(void *re_)
|
|||
static void *resampler_CC_init(double bandwidth_mod)
|
||||
{
|
||||
int i;
|
||||
rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)calloc(1, sizeof(rarch_CC_resampler_t));
|
||||
rarch_CC_resampler_t *re = (rarch_CC_resampler_t*)
|
||||
calloc(1, sizeof(rarch_CC_resampler_t));
|
||||
if (!re)
|
||||
return NULL;
|
||||
|
||||
|
@ -297,7 +301,9 @@ static void *resampler_CC_init(double bandwidth_mod)
|
|||
|
||||
RARCH_LOG("Convoluted Cosine resampler (C) : ");
|
||||
|
||||
if (bandwidth_mod < 0.75) // variations of data->ratio around 0.75 are safer than around 1.0 for both up/downsampler.
|
||||
/* variations of data->ratio around 0.75 are safer
|
||||
* than around 1.0 for both up/downsampler. */
|
||||
if (bandwidth_mod < 0.75)
|
||||
{
|
||||
RARCH_LOG("CC_downsample @%f \n", bandwidth_mod);
|
||||
re->process = resampler_CC_downsample;
|
|
@ -17,10 +17,10 @@
|
|||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../config.h"
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "../general.h"
|
||||
#include "../../general.h"
|
||||
|
||||
static const rarch_resampler_t *resampler_drivers[] = {
|
||||
&sinc_resampler,
|
|
@ -18,13 +18,13 @@
|
|||
#define __RARCH_RESAMPLER_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../config.h"
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include "../boolean.h"
|
||||
#include "../../boolean.h"
|
||||
|
||||
#ifndef M_PI
|
||||
/* M_PI is left out of ISO C99 :( */
|
|
@ -13,20 +13,20 @@
|
|||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Bog-standard windowed SINC implementation.
|
||||
/* Bog-standard windowed SINC implementation. */
|
||||
|
||||
#include "resampler.h"
|
||||
#include "../libretro.h"
|
||||
#include "../performance.h"
|
||||
#include "../../libretro.h"
|
||||
#include "../../performance.h"
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "../msvc/msvc_compat.h"
|
||||
#include "../../msvc/msvc_compat.h"
|
||||
|
||||
#ifndef RESAMPLER_TEST
|
||||
#include "../general.h"
|
||||
#include "../../general.h"
|
||||
#else
|
||||
#define RARCH_LOG(...) fprintf(stderr, __VA_ARGS__)
|
||||
#endif
|
||||
|
@ -35,14 +35,15 @@
|
|||
#include <xmmintrin.h>
|
||||
#endif
|
||||
|
||||
// Rough SNR values for upsampling:
|
||||
// LOWEST: 40 dB
|
||||
// LOWER: 55 dB
|
||||
// NORMAL: 70 dB
|
||||
// HIGHER: 110 dB
|
||||
// HIGHEST: 140 dB
|
||||
/* Rough SNR values for upsampling:
|
||||
* LOWEST: 40 dB
|
||||
* LOWER: 55 dB
|
||||
* NORMAL: 70 dB
|
||||
* HIGHER: 110 dB
|
||||
* HIGHEST: 140 dB
|
||||
*/
|
||||
|
||||
// TODO, make all this more configurable.
|
||||
/* TODO, make all this more configurable. */
|
||||
#if defined(SINC_LOWEST_QUALITY)
|
||||
#define SINC_WINDOW_LANCZOS
|
||||
#define CUTOFF 0.98
|
||||
|
@ -88,10 +89,11 @@
|
|||
#define ENABLE_AVX 0
|
||||
#endif
|
||||
|
||||
// For the little amount of taps we're using,
|
||||
// SSE1 is faster than AVX for some reason.
|
||||
// AVX code is kept here though as by increasing number
|
||||
// of sinc taps, the AVX code is clearly faster than SSE1.
|
||||
/* For the little amount of taps we're using,
|
||||
* SSE1 is faster than AVX for some reason.
|
||||
* AVX code is kept here though as by increasing number
|
||||
* of sinc taps, the AVX code is clearly faster than SSE1.
|
||||
*/
|
||||
|
||||
#if defined(__AVX__) && ENABLE_AVX
|
||||
#include <immintrin.h>
|
||||
|
@ -114,8 +116,9 @@ typedef struct rarch_sinc_resampler
|
|||
unsigned ptr;
|
||||
uint32_t time;
|
||||
|
||||
// A buffer for phase_table, buffer_l and buffer_r are created in a single calloc().
|
||||
// Ensure that we get as good cache locality as we can hope for.
|
||||
/* A buffer for phase_table, buffer_l and buffer_r
|
||||
* are created in a single calloc().
|
||||
* Ensure that we get as good cache locality as we can hope for. */
|
||||
float *main_buffer;
|
||||
} rarch_sinc_resampler_t;
|
||||
|
||||
|
@ -132,8 +135,8 @@ static inline double window_function(double index)
|
|||
return sinc(M_PI * index);
|
||||
}
|
||||
#elif defined(SINC_WINDOW_KAISER)
|
||||
// Modified Bessel function of first order.
|
||||
// Check Wiki for mathematical definition ...
|
||||
/* Modified Bessel function of first order.
|
||||
* Check Wiki for mathematical definition ... */
|
||||
static inline double besseli0(double x)
|
||||
{
|
||||
unsigned i;
|
||||
|
@ -145,8 +148,8 @@ static inline double besseli0(double x)
|
|||
double two_div_pow = 1.0;
|
||||
double x_sqr = x * x;
|
||||
|
||||
// Approximate. This is an infinite sum.
|
||||
// Luckily, it converges rather fast.
|
||||
/* Approximate. This is an infinite sum.
|
||||
* Luckily, it converges rather fast. */
|
||||
for (i = 0; i < 18; i++)
|
||||
{
|
||||
sum += x_pow * two_div_pow / (factorial * factorial);
|
||||
|
@ -172,7 +175,7 @@ static void init_sinc_table(rarch_sinc_resampler_t *resamp, double cutoff,
|
|||
float *phase_table, int phases, int taps, bool calculate_delta)
|
||||
{
|
||||
int i, j, p;
|
||||
double window_mod = window_function(0.0); // Need to normalize w(0) to 1.0.
|
||||
double window_mod = window_function(0.0); /* Need to normalize w(0) to 1.0. */
|
||||
int stride = calculate_delta ? 2 : 1;
|
||||
|
||||
double sidelobes = taps / 2.0;
|
||||
|
@ -181,11 +184,12 @@ static void init_sinc_table(rarch_sinc_resampler_t *resamp, double cutoff,
|
|||
for (j = 0; j < taps; j++)
|
||||
{
|
||||
int n = j * phases + i;
|
||||
double window_phase = (double)n / (phases * taps); // [0, 1).
|
||||
window_phase = 2.0 * window_phase - 1.0; // [-1, 1)
|
||||
double window_phase = (double)n / (phases * taps); /* [0, 1). */
|
||||
window_phase = 2.0 * window_phase - 1.0; /* [-1, 1) */
|
||||
double sinc_phase = sidelobes * window_phase;
|
||||
|
||||
float val = cutoff * sinc(M_PI * sinc_phase * cutoff) * window_function(window_phase) / window_mod;
|
||||
float val = cutoff * sinc(M_PI * sinc_phase * cutoff) *
|
||||
window_function(window_phase) / window_mod;
|
||||
phase_table[i * stride * taps + j] = val;
|
||||
}
|
||||
}
|
||||
|
@ -196,7 +200,8 @@ static void init_sinc_table(rarch_sinc_resampler_t *resamp, double cutoff,
|
|||
{
|
||||
for (j = 0; j < taps; j++)
|
||||
{
|
||||
float delta = phase_table[(p + 1) * stride * taps + j] - phase_table[p * stride * taps + j];
|
||||
float delta = phase_table[(p + 1) * stride * taps + j] -
|
||||
phase_table[p * stride * taps + j];
|
||||
phase_table[(p * stride + 1) * taps + j] = delta;
|
||||
}
|
||||
}
|
||||
|
@ -205,25 +210,27 @@ static void init_sinc_table(rarch_sinc_resampler_t *resamp, double cutoff,
|
|||
for (j = 0; j < taps; j++)
|
||||
{
|
||||
int n = j * phases + (phase + 1);
|
||||
double window_phase = (double)n / (phases * taps); // (0, 1].
|
||||
window_phase = 2.0 * window_phase - 1.0; // (-1, 1]
|
||||
double window_phase = (double)n / (phases * taps); /* (0, 1]. */
|
||||
window_phase = 2.0 * window_phase - 1.0; /* (-1, 1] */
|
||||
double sinc_phase = sidelobes * window_phase;
|
||||
|
||||
float val = cutoff * sinc(M_PI * sinc_phase * cutoff) * window_function(window_phase) / window_mod;
|
||||
float val = cutoff * sinc(M_PI * sinc_phase * cutoff) *
|
||||
window_function(window_phase) / window_mod;
|
||||
float delta = (val - phase_table[phase * stride * taps + j]);
|
||||
phase_table[(phase * stride + 1) * taps + j] = delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No memalign() for us on Win32 ...
|
||||
/* No memalign() for us on Win32 ... */
|
||||
static void *aligned_alloc__(size_t boundary, size_t size)
|
||||
{
|
||||
void *ptr = malloc(boundary + size + sizeof(uintptr_t));
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
|
||||
uintptr_t addr = ((uintptr_t)ptr + sizeof(uintptr_t) + boundary) & ~(boundary - 1);
|
||||
uintptr_t addr = ((uintptr_t)ptr +
|
||||
sizeof(uintptr_t) + boundary) & ~(boundary - 1);
|
||||
void **place = (void**)addr;
|
||||
place[-1] = ptr;
|
||||
|
||||
|
@ -237,7 +244,8 @@ static void aligned_free__(void *ptr)
|
|||
}
|
||||
|
||||
#if !(defined(__AVX__) && ENABLE_AVX) && !defined(__SSE__)
|
||||
static inline void process_sinc_C(rarch_sinc_resampler_t *resamp, float *out_buffer)
|
||||
static inline void process_sinc_C(rarch_sinc_resampler_t *resamp,
|
||||
float *out_buffer)
|
||||
{
|
||||
unsigned i;
|
||||
float sum_l = 0.0f;
|
||||
|
@ -287,7 +295,8 @@ static void process_sinc(rarch_sinc_resampler_t *resamp, float *out_buffer)
|
|||
#if SINC_COEFF_LERP
|
||||
const float *phase_table = resamp->phase_table + phase * taps * 2;
|
||||
const float *delta_table = phase_table + taps;
|
||||
__m256 delta = _mm256_set1_ps((float)(resamp->time & SUBPHASE_MASK) * SUBPHASE_MOD);
|
||||
__m256 delta = _mm256_set1_ps((float)
|
||||
(resamp->time & SUBPHASE_MASK) * SUBPHASE_MOD);
|
||||
#else
|
||||
const float *phase_table = resamp->phase_table + phase * taps;
|
||||
#endif
|
||||
|
@ -299,7 +308,8 @@ static void process_sinc(rarch_sinc_resampler_t *resamp, float *out_buffer)
|
|||
|
||||
#if SINC_COEFF_LERP
|
||||
__m256 deltas = _mm256_load_ps(delta_table + i);
|
||||
__m256 sinc = _mm256_add_ps(_mm256_load_ps(phase_table + i), _mm256_mul_ps(deltas, delta));
|
||||
__m256 sinc = _mm256_add_ps(_mm256_load_ps(phase_table + i),
|
||||
_mm256_mul_ps(deltas, delta));
|
||||
#else
|
||||
__m256 sinc = _mm256_load_ps(phase_table + i);
|
||||
#endif
|
||||
|
@ -307,7 +317,8 @@ static void process_sinc(rarch_sinc_resampler_t *resamp, float *out_buffer)
|
|||
sum_r = _mm256_add_ps(sum_r, _mm256_mul_ps(buf_r, sinc));
|
||||
}
|
||||
|
||||
// hadd on AVX is weird, and acts on low-lanes and high-lanes separately.
|
||||
/* hadd on AVX is weird, and acts on low-lanes
|
||||
* and high-lanes separately. */
|
||||
__m256 res_l = _mm256_hadd_ps(sum_l, sum_l);
|
||||
__m256 res_r = _mm256_hadd_ps(sum_r, sum_r);
|
||||
res_l = _mm256_hadd_ps(res_l, res_l);
|
||||
|
@ -315,8 +326,8 @@ static void process_sinc(rarch_sinc_resampler_t *resamp, float *out_buffer)
|
|||
res_l = _mm256_add_ps(_mm256_permute2f128_ps(res_l, res_l, 1), res_l);
|
||||
res_r = _mm256_add_ps(_mm256_permute2f128_ps(res_r, res_r, 1), res_r);
|
||||
|
||||
// This is optimized to mov %xmmN, [mem].
|
||||
// There doesn't seem to be any _mm256_store_ss intrinsic.
|
||||
/* This is optimized to mov %xmmN, [mem].
|
||||
* There doesn't seem to be any _mm256_store_ss intrinsic. */
|
||||
_mm_store_ss(out_buffer + 0, _mm256_extractf128_ps(res_l, 0));
|
||||
_mm_store_ss(out_buffer + 1, _mm256_extractf128_ps(res_r, 0));
|
||||
}
|
||||
|
@ -336,7 +347,8 @@ static void process_sinc(rarch_sinc_resampler_t *resamp, float *out_buffer)
|
|||
#if SINC_COEFF_LERP
|
||||
const float *phase_table = resamp->phase_table + phase * taps * 2;
|
||||
const float *delta_table = phase_table + taps;
|
||||
__m128 delta = _mm_set1_ps((float)(resamp->time & SUBPHASE_MASK) * SUBPHASE_MOD);
|
||||
__m128 delta = _mm_set1_ps((float)
|
||||
(resamp->time & SUBPHASE_MASK) * SUBPHASE_MOD);
|
||||
#else
|
||||
const float *phase_table = resamp->phase_table + phase * taps;
|
||||
#endif
|
||||
|
@ -348,7 +360,8 @@ static void process_sinc(rarch_sinc_resampler_t *resamp, float *out_buffer)
|
|||
|
||||
#if SINC_COEFF_LERP
|
||||
__m128 deltas = _mm_load_ps(delta_table + i);
|
||||
__m128 sinc = _mm_add_ps(_mm_load_ps(phase_table + i), _mm_mul_ps(deltas, delta));
|
||||
__m128 sinc = _mm_add_ps(_mm_load_ps(phase_table + i),
|
||||
_mm_mul_ps(deltas, delta));
|
||||
#else
|
||||
__m128 sinc = _mm_load_ps(phase_table + i);
|
||||
#endif
|
||||
|
@ -356,25 +369,29 @@ static void process_sinc(rarch_sinc_resampler_t *resamp, float *out_buffer)
|
|||
sum_r = _mm_add_ps(sum_r, _mm_mul_ps(buf_r, sinc));
|
||||
}
|
||||
|
||||
// Them annoying shuffles :V
|
||||
// sum_l = { l3, l2, l1, l0 }
|
||||
// sum_r = { r3, r2, r1, r0 }
|
||||
/* Them annoying shuffles :V
|
||||
* sum_l = { l3, l2, l1, l0 }
|
||||
* sum_r = { r3, r2, r1, r0 }
|
||||
*/
|
||||
|
||||
__m128 sum = _mm_add_ps(_mm_shuffle_ps(sum_l, sum_r, _MM_SHUFFLE(1, 0, 1, 0)),
|
||||
__m128 sum = _mm_add_ps(_mm_shuffle_ps(sum_l, sum_r,
|
||||
_MM_SHUFFLE(1, 0, 1, 0)),
|
||||
_mm_shuffle_ps(sum_l, sum_r, _MM_SHUFFLE(3, 2, 3, 2)));
|
||||
|
||||
// sum = { r1, r0, l1, l0 } + { r3, r2, l3, l2 }
|
||||
// sum = { R1, R0, L1, L0 }
|
||||
/* sum = { r1, r0, l1, l0 } + { r3, r2, l3, l2 }
|
||||
* sum = { R1, R0, L1, L0 }
|
||||
*/
|
||||
|
||||
sum = _mm_add_ps(_mm_shuffle_ps(sum, sum, _MM_SHUFFLE(3, 3, 1, 1)), sum);
|
||||
|
||||
// sum = {R1, R1, L1, L1 } + { R1, R0, L1, L0 }
|
||||
// sum = { X, R, X, L }
|
||||
/* sum = {R1, R1, L1, L1 } + { R1, R0, L1, L0 }
|
||||
* sum = { X, R, X, L }
|
||||
*/
|
||||
|
||||
// Store L
|
||||
/* Store L */
|
||||
_mm_store_ss(out_buffer + 0, sum);
|
||||
|
||||
// movehl { X, R, X, L } == { X, R, X, R }
|
||||
/* movehl { X, R, X, L } == { X, R, X, R } */
|
||||
_mm_store_ss(out_buffer + 1, _mm_movehl_ps(sum, sum));
|
||||
}
|
||||
#elif defined(__ARM_NEON__)
|
||||
|
@ -383,14 +400,18 @@ static void process_sinc(rarch_sinc_resampler_t *resamp, float *out_buffer)
|
|||
#error "NEON asm does not support SINC lerp."
|
||||
#endif
|
||||
|
||||
// Need to make this function pointer as Android doesn't have built-in targets
|
||||
// for NEON and plain ARMv7a.
|
||||
static void (*process_sinc_func)(rarch_sinc_resampler_t *resamp, float *out_buffer);
|
||||
/* Need to make this function pointer as Android doesn't
|
||||
* have built-in targets for NEON and plain ARMv7a.
|
||||
*/
|
||||
static void (*process_sinc_func)(rarch_sinc_resampler_t *resamp,
|
||||
float *out_buffer);
|
||||
|
||||
// Assumes that taps >= 8, and that taps is a multiple of 8.
|
||||
void process_sinc_neon_asm(float *out, const float *left, const float *right, const float *coeff, unsigned taps);
|
||||
/* Assumes that taps >= 8, and that taps is a multiple of 8. */
|
||||
void process_sinc_neon_asm(float *out, const float *left,
|
||||
const float *right, const float *coeff, unsigned taps);
|
||||
|
||||
static void process_sinc_neon(rarch_sinc_resampler_t *resamp, float *out_buffer)
|
||||
static void process_sinc_neon(rarch_sinc_resampler_t *resamp,
|
||||
float *out_buffer)
|
||||
{
|
||||
const float *buffer_l = resamp->buffer_l + resamp->ptr;
|
||||
const float *buffer_r = resamp->buffer_r + resamp->ptr;
|
||||
|
@ -401,7 +422,7 @@ static void process_sinc_neon(rarch_sinc_resampler_t *resamp, float *out_buffer)
|
|||
|
||||
process_sinc_neon_asm(out_buffer, buffer_l, buffer_r, phase_table, taps);
|
||||
}
|
||||
#else // Plain ol' C99
|
||||
#else /* Plain ol' C99 */
|
||||
#define process_sinc_func process_sinc_C
|
||||
#endif
|
||||
|
||||
|
@ -420,7 +441,7 @@ static void resampler_sinc_process(void *re_, struct resampler_data *data)
|
|||
{
|
||||
while (frames && re->time >= PHASES)
|
||||
{
|
||||
// Push in reverse to make filter more obvious.
|
||||
/* Push in reverse to make filter more obvious. */
|
||||
if (!re->ptr)
|
||||
re->ptr = re->taps;
|
||||
re->ptr--;
|
||||
|
@ -454,7 +475,8 @@ static void resampler_sinc_free(void *re)
|
|||
|
||||
static void *resampler_sinc_new(double bandwidth_mod)
|
||||
{
|
||||
rarch_sinc_resampler_t *re = (rarch_sinc_resampler_t*)calloc(1, sizeof(*re));
|
||||
rarch_sinc_resampler_t *re = (rarch_sinc_resampler_t*)
|
||||
calloc(1, sizeof(*re));
|
||||
if (!re)
|
||||
return NULL;
|
||||
|
||||
|
@ -463,14 +485,15 @@ static void *resampler_sinc_new(double bandwidth_mod)
|
|||
re->taps = TAPS;
|
||||
double cutoff = CUTOFF;
|
||||
|
||||
// Downsampling, must lower cutoff, and extend number of taps accordingly to keep same stopband attenuation.
|
||||
/* Downsampling, must lower cutoff, and extend number of
|
||||
* taps accordingly to keep same stopband attenuation. */
|
||||
if (bandwidth_mod < 1.0)
|
||||
{
|
||||
cutoff *= bandwidth_mod;
|
||||
re->taps = (unsigned)ceil(re->taps / bandwidth_mod);
|
||||
}
|
||||
|
||||
// Be SIMD-friendly.
|
||||
/* Be SIMD-friendly. */
|
||||
#if (defined(__AVX__) && ENABLE_AVX) || defined(__ARM_NEON__)
|
||||
re->taps = (re->taps + 7) & ~7;
|
||||
#else
|
||||
|
@ -483,7 +506,8 @@ static void *resampler_sinc_new(double bandwidth_mod)
|
|||
#endif
|
||||
size_t elems = phase_elems + 4 * re->taps;
|
||||
|
||||
re->main_buffer = (float*)aligned_alloc__(128, sizeof(float) * elems);
|
||||
re->main_buffer = (float*)
|
||||
aligned_alloc__(128, sizeof(float) * elems);
|
||||
if (!re->main_buffer)
|
||||
goto error;
|
||||
|
||||
|
@ -491,7 +515,8 @@ static void *resampler_sinc_new(double bandwidth_mod)
|
|||
re->buffer_l = re->main_buffer + phase_elems;
|
||||
re->buffer_r = re->buffer_l + 2 * re->taps;
|
||||
|
||||
init_sinc_table(re, cutoff, re->phase_table, 1 << PHASE_BITS, re->taps, SINC_COEFF_LERP);
|
||||
init_sinc_table(re, cutoff, re->phase_table,
|
||||
1 << PHASE_BITS, re->taps, SINC_COEFF_LERP);
|
||||
|
||||
#if defined(__AVX__) && ENABLE_AVX
|
||||
RARCH_LOG("Sinc resampler [AVX]\n");
|
||||
|
@ -499,13 +524,16 @@ static void *resampler_sinc_new(double bandwidth_mod)
|
|||
RARCH_LOG("Sinc resampler [SSE]\n");
|
||||
#elif defined(__ARM_NEON__)
|
||||
unsigned cpu = rarch_get_cpu_features();
|
||||
process_sinc_func = cpu & RETRO_SIMD_NEON ? process_sinc_neon : process_sinc_C;
|
||||
RARCH_LOG("Sinc resampler [%s]\n", cpu & RETRO_SIMD_NEON ? "NEON" : "C");
|
||||
process_sinc_func = cpu & RETRO_SIMD_NEON
|
||||
? process_sinc_neon : process_sinc_C;
|
||||
RARCH_LOG("Sinc resampler [%s]\n",
|
||||
cpu & RETRO_SIMD_NEON ? "NEON" : "C");
|
||||
#else
|
||||
RARCH_LOG("Sinc resampler [C]\n");
|
||||
#endif
|
||||
|
||||
RARCH_LOG("SINC params (%u phase bits, %u taps).\n", PHASE_BITS, re->taps);
|
||||
RARCH_LOG("SINC params (%u phase bits, %u taps).\n",
|
||||
PHASE_BITS, re->taps);
|
||||
return re;
|
||||
|
||||
error:
|
13
audio/roar.c
13
audio/roar.c
|
@ -103,14 +103,21 @@ static void ra_free(void *data)
|
|||
free(data);
|
||||
}
|
||||
|
||||
const audio_driver_t audio_roar = {
|
||||
static bool ra_use_float(void *data)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
return false;
|
||||
}
|
||||
|
||||
audio_driver_t audio_roar = {
|
||||
ra_init,
|
||||
ra_write,
|
||||
ra_stop,
|
||||
ra_start,
|
||||
ra_set_nonblock_state,
|
||||
ra_free,
|
||||
ra_use_float,
|
||||
"roar",
|
||||
NULL,
|
||||
"roar"
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -197,16 +197,21 @@ static size_t rs_buffer_size(void *data)
|
|||
return 1024 * 4;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_rsound = {
|
||||
static bool rs_use_float(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return false;
|
||||
}
|
||||
|
||||
audio_driver_t audio_rsound = {
|
||||
rs_init,
|
||||
rs_write,
|
||||
rs_stop,
|
||||
rs_start,
|
||||
rs_set_nonblock_state,
|
||||
rs_free,
|
||||
NULL,
|
||||
rs_use_float,
|
||||
"rsound",
|
||||
rs_write_avail,
|
||||
rs_buffer_size,
|
||||
};
|
||||
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
|
||||
#include "../emscripten/RWebAudio.h"
|
||||
|
||||
static void ra_free(void *data)
|
||||
static void rwebaudio_free(void *data)
|
||||
{
|
||||
RWebAudioFree();
|
||||
}
|
||||
|
||||
static void *ra_init(const char *device, unsigned rate, unsigned latency)
|
||||
static void *rwebaudio_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
(void)device;
|
||||
(void)rate;
|
||||
|
@ -33,58 +33,57 @@ static void *ra_init(const char *device, unsigned rate, unsigned latency)
|
|||
return data;
|
||||
}
|
||||
|
||||
static ssize_t ra_write(void *data, const void *buf, size_t size)
|
||||
static ssize_t rwebaudio_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
(void)data;
|
||||
return RWebAudioWrite(buf, size);
|
||||
}
|
||||
|
||||
static bool ra_stop(void *data)
|
||||
static bool rwebaudio_stop(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return RWebAudioStop();
|
||||
}
|
||||
|
||||
static void ra_set_nonblock_state(void *data, bool state)
|
||||
static void rwebaudio_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
(void)data;
|
||||
RWebAudioSetNonblockState(state);
|
||||
}
|
||||
|
||||
static bool ra_start(void *data)
|
||||
static bool rwebaudio_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return RWebAudioStart();
|
||||
}
|
||||
|
||||
static bool ra_use_float(void *data)
|
||||
static bool rwebaudio_use_float(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static size_t ra_write_avail(void *data)
|
||||
static size_t rwebaudio_write_avail(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return RWebAudioWriteAvail();
|
||||
}
|
||||
|
||||
static size_t ra_buffer_size(void *data)
|
||||
static size_t rwebaudio_buffer_size(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return RWebAudioBufferSize();
|
||||
}
|
||||
|
||||
const audio_driver_t audio_rwebaudio = {
|
||||
ra_init,
|
||||
ra_write,
|
||||
ra_stop,
|
||||
ra_start,
|
||||
ra_set_nonblock_state,
|
||||
ra_free,
|
||||
ra_use_float,
|
||||
audio_driver_t audio_rwebaudio = {
|
||||
rwebaudio_init,
|
||||
rwebaudio_write,
|
||||
rwebaudio_stop,
|
||||
rwebaudio_start,
|
||||
rwebaudio_set_nonblock_state,
|
||||
rwebaudio_free,
|
||||
rwebaudio_use_float,
|
||||
"rwebaudio",
|
||||
ra_write_avail,
|
||||
ra_buffer_size,
|
||||
rwebaudio_write_avail,
|
||||
rwebaudio_buffer_size,
|
||||
};
|
||||
|
||||
|
|
|
@ -190,18 +190,25 @@ static void sdl_audio_free(void *data)
|
|||
free(sdl);
|
||||
}
|
||||
|
||||
const audio_driver_t audio_sdl = {
|
||||
static bool sdl_use_float(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return false;
|
||||
}
|
||||
|
||||
audio_driver_t audio_sdl = {
|
||||
sdl_audio_init,
|
||||
sdl_audio_write,
|
||||
sdl_audio_stop,
|
||||
sdl_audio_start,
|
||||
sdl_audio_set_nonblock_state,
|
||||
sdl_audio_free,
|
||||
NULL,
|
||||
sdl_use_float,
|
||||
#ifdef HAVE_SDL2
|
||||
"sdl2"
|
||||
"sdl2",
|
||||
#else
|
||||
"sdl"
|
||||
"sdl",
|
||||
#endif
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -82,7 +82,8 @@ void audio_convert_float_to_s16_SSE2(int16_t *out,
|
|||
for (i = 0; i + 8 <= samples; i += 8, in += 8, out += 8)
|
||||
{
|
||||
__m128 input[2] = { _mm_loadu_ps(in + 0), _mm_loadu_ps(in + 4) };
|
||||
__m128 res[2] = { _mm_mul_ps(input[0], factor), _mm_mul_ps(input[1], factor) };
|
||||
__m128 res[2] = { _mm_mul_ps(input[0], factor),
|
||||
_mm_mul_ps(input[1], factor) };
|
||||
|
||||
__m128i ints[2] = { _mm_cvtps_epi32(res[0]), _mm_cvtps_epi32(res[1]) };
|
||||
__m128i packed = _mm_packs_epi32(ints[0], ints[1]);
|
||||
|
|
|
@ -125,7 +125,7 @@ static size_t xa_buffer_size(void *data)
|
|||
return xa->bufsize;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_xa = {
|
||||
audio_driver_t audio_xa = {
|
||||
xa_init,
|
||||
xa_write,
|
||||
xa_stop,
|
||||
|
|
|
@ -30,7 +30,8 @@ typedef struct
|
|||
bool nonblock;
|
||||
} xenon_audio_t;
|
||||
|
||||
static void *xenon360_audio_init(const char *device, unsigned rate, unsigned latency)
|
||||
static void *xenon360_audio_init(const char *device,
|
||||
unsigned rate, unsigned latency)
|
||||
{
|
||||
static bool inited = false;
|
||||
if (!inited)
|
||||
|
@ -45,7 +46,8 @@ static void *xenon360_audio_init(const char *device, unsigned rate, unsigned lat
|
|||
|
||||
static inline uint32_t bswap_32(uint32_t val)
|
||||
{
|
||||
return (val >> 24) | (val << 24) | ((val >> 8) & 0xff00) | ((val << 8) & 0xff0000);
|
||||
return (val >> 24) | (val << 24) |
|
||||
((val >> 8) & 0xff00) | ((val << 8) & 0xff0000);
|
||||
}
|
||||
|
||||
static ssize_t xenon360_audio_write(void *data, const void *buf, size_t size)
|
||||
|
@ -62,7 +64,8 @@ static ssize_t xenon360_audio_write(void *data, const void *buf, size_t size)
|
|||
{
|
||||
while (xenon_sound_get_unplayed() >= MAX_BUFFER)
|
||||
{
|
||||
// libxenon doesn't have proper synchronization primitives for this :(
|
||||
/* libxenon doesn't have proper
|
||||
* synchronization primitives for this... */
|
||||
udelay(50);
|
||||
}
|
||||
|
||||
|
@ -105,13 +108,21 @@ static void xenon360_audio_free(void *data)
|
|||
free(data);
|
||||
}
|
||||
|
||||
const audio_driver_t audio_xenon360 = {
|
||||
.init = xenon360_audio_init,
|
||||
.write = xenon360_audio_write,
|
||||
.stop = xenon360_audio_stop,
|
||||
.start = xenon360_audio_start,
|
||||
.set_nonblock_state = xenon360_audio_set_nonblock_state,
|
||||
.free = xenon360_audio_free,
|
||||
.ident = "xenon360"
|
||||
};
|
||||
static bool xenon360_use_float(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return false;
|
||||
}
|
||||
|
||||
audio_driver_t audio_xenon360 = {
|
||||
xenon360_audio_init,
|
||||
xenon360_audio_write,
|
||||
xenon360_audio_stop,
|
||||
xenon360_audio_start,
|
||||
xenon360_audio_set_nonblock_state,
|
||||
xenon360_audio_free,
|
||||
xenon360_use_float,
|
||||
"xenon360",
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
|
|
@ -187,7 +187,7 @@ static bool android_camera_poll(void *data,
|
|||
return false;
|
||||
}
|
||||
|
||||
const camera_driver_t camera_android = {
|
||||
camera_driver_t camera_android = {
|
||||
android_camera_init,
|
||||
android_camera_free,
|
||||
android_camera_start,
|
||||
|
@ -195,4 +195,3 @@ const camera_driver_t camera_android = {
|
|||
android_camera_poll,
|
||||
"android",
|
||||
};
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ static bool nullcamera_poll(void *data, retro_camera_frame_raw_framebuffer_t fra
|
|||
return true;
|
||||
}
|
||||
|
||||
const camera_driver_t camera_null = {
|
||||
camera_driver_t camera_null = {
|
||||
nullcamera_init,
|
||||
nullcamera_free,
|
||||
nullcamera_start,
|
||||
|
|
|
@ -43,7 +43,7 @@ static bool rwebcam_poll(void *data, retro_camera_frame_raw_framebuffer_t frame_
|
|||
return RWebCamPoll(data, frame_raw_cb, frame_gl_cb);
|
||||
}
|
||||
|
||||
const camera_driver_t camera_rwebcam = {
|
||||
camera_driver_t camera_rwebcam = {
|
||||
rwebcam_init,
|
||||
rwebcam_free,
|
||||
rwebcam_start,
|
||||
|
|
|
@ -434,7 +434,7 @@ static bool v4l_poll(void *data,
|
|||
return false;
|
||||
}
|
||||
|
||||
const camera_driver_t camera_v4l2 = {
|
||||
camera_driver_t camera_v4l2 = {
|
||||
v4l_init,
|
||||
v4l_free,
|
||||
v4l_start,
|
||||
|
@ -442,4 +442,3 @@ const camera_driver_t camera_v4l2 = {
|
|||
v4l_poll,
|
||||
"video4linux2",
|
||||
};
|
||||
|
||||
|
|
|
@ -104,6 +104,7 @@ enum
|
|||
MENU_RMENU,
|
||||
MENU_RMENU_XUI,
|
||||
MENU_LAKKA,
|
||||
MENU_GLUI,
|
||||
};
|
||||
|
||||
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) || defined(__CELLOS_LV2__)
|
||||
|
|
|
@ -184,6 +184,9 @@ core_info_list_t *core_info_list_new(const char *modules_path)
|
|||
&core_info[i].notes) &&
|
||||
core_info[i].notes)
|
||||
core_info[i].note_list = string_split(core_info[i].notes, "|");
|
||||
|
||||
config_get_bool(core_info[i].data, "supports_no_game",
|
||||
&core_info[i].supports_no_game);
|
||||
}
|
||||
|
||||
if (!core_info[i].display_name)
|
||||
|
|
|
@ -55,6 +55,7 @@ typedef struct
|
|||
|
||||
core_info_firmware_t *firmware;
|
||||
size_t firmware_count;
|
||||
bool supports_no_game;
|
||||
} core_info_t;
|
||||
|
||||
typedef struct
|
||||
|
|
|
@ -46,7 +46,8 @@ static int Buf_EnsureSize(CBuf *dest, size_t size)
|
|||
|
||||
static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||
|
||||
static Bool Utf16_To_Utf8(Byte *dest, size_t *destLen, const UInt16 *src, size_t srcLen)
|
||||
static Bool Utf16_To_Utf8(Byte *dest, size_t *destLen,
|
||||
const UInt16 *src, size_t srcLen)
|
||||
{
|
||||
size_t destPos = 0, srcPos = 0;
|
||||
for (;;)
|
||||
|
@ -80,13 +81,15 @@ static Bool Utf16_To_Utf8(Byte *dest, size_t *destLen, const UInt16 *src, size_t
|
|||
if (value < (((UInt32)1) << (numAdds * 5 + 6)))
|
||||
break;
|
||||
if (dest)
|
||||
dest[destPos] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
|
||||
dest[destPos] = (char)(kUtf8Limits[numAdds - 1]
|
||||
+ (value >> (6 * numAdds)));
|
||||
destPos++;
|
||||
do
|
||||
{
|
||||
numAdds--;
|
||||
if (dest)
|
||||
dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
|
||||
dest[destPos] = (char)(0x80
|
||||
+ ((value >> (6 * numAdds)) & 0x3F));
|
||||
destPos++;
|
||||
}
|
||||
while (numAdds != 0);
|
||||
|
@ -95,7 +98,8 @@ static Bool Utf16_To_Utf8(Byte *dest, size_t *destLen, const UInt16 *src, size_t
|
|||
return False;
|
||||
}
|
||||
|
||||
static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen)
|
||||
static SRes Utf16_To_Utf8Buf(CBuf *dest,
|
||||
const UInt16 *src, size_t srcLen)
|
||||
{
|
||||
size_t destLen = 0;
|
||||
Bool res;
|
||||
|
@ -158,9 +162,10 @@ static SRes ConvertUtf16toCharString(const UInt16 *s, char *outstring)
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
// Extract the relative path relative_path from a 7z archive archive_path and allocate a buf for it to write it in.
|
||||
int read_7zip_file(const char * archive_path, const char *relative_path, void **buf)
|
||||
/* Extract the relative path relative_path from a 7z archive
|
||||
* archive_path and allocate a buf for it to write it in. */
|
||||
int read_7zip_file(const char * archive_path,
|
||||
const char *relative_path, void **buf)
|
||||
{
|
||||
CFileInStream archiveStream;
|
||||
CLookToRead lookStream;
|
||||
|
@ -172,7 +177,8 @@ int read_7zip_file(const char * archive_path, const char *relative_path, void **
|
|||
size_t tempSize = 0;
|
||||
long outsize = -1;
|
||||
|
||||
//These are the allocation routines - currently using the non-standard 7zip choices.
|
||||
/*These are the allocation routines.
|
||||
* Currently using the non-standard 7zip choices. */
|
||||
allocImp.Alloc = SzAlloc;
|
||||
allocImp.Free = SzFree;
|
||||
allocTempImp.Alloc = SzAllocTemp;
|
||||
|
@ -185,7 +191,8 @@ int read_7zip_file(const char * archive_path, const char *relative_path, void **
|
|||
}
|
||||
else
|
||||
{
|
||||
RARCH_LOG_OUTPUT("Openend archive %s. Now trying to extract %s\n",archive_path,relative_path);
|
||||
RARCH_LOG_OUTPUT("Openend archive %s. Now trying to extract %s\n",
|
||||
archive_path,relative_path);
|
||||
}
|
||||
FileInStream_CreateVTable(&archiveStream);
|
||||
LookToRead_CreateVTable(&lookStream, False);
|
||||
|
@ -209,9 +216,11 @@ int read_7zip_file(const char * archive_path, const char *relative_path, void **
|
|||
size_t len;
|
||||
if (f->IsDir)
|
||||
{
|
||||
//we skip over everything, which is not a directory.
|
||||
/* We skip over everything which is not a directory.
|
||||
* FIXME: Why continue then if f->IsDir is true?*/
|
||||
continue;
|
||||
}
|
||||
|
||||
len = SzArEx_GetFileNameUtf16(&db, i, NULL);
|
||||
if (len > tempSize)
|
||||
{
|
||||
|
@ -234,16 +243,21 @@ int read_7zip_file(const char * archive_path, const char *relative_path, void **
|
|||
|
||||
if (strcmp(infile,relative_path) == 0)
|
||||
{
|
||||
res = SzArEx_Extract(&db, &lookStream.s, i,&blockIndex, &outBuffer, &outBufferSize,&offset, &outSizeProcessed,&allocImp, &allocTempImp);
|
||||
res = SzArEx_Extract(&db, &lookStream.s, i,&blockIndex,
|
||||
&outBuffer, &outBufferSize,&offset, &outSizeProcessed,
|
||||
&allocImp, &allocTempImp);
|
||||
if (res != SZ_OK)
|
||||
{
|
||||
break; //This goes to the error section.
|
||||
break; /* This goes to the error section. */
|
||||
}
|
||||
outsize = outSizeProcessed;
|
||||
*buf = outBuffer+offset;
|
||||
|
||||
//We could either use the 7Zip allocated buffer or create our own and use it.
|
||||
//We would however need to realloc anyways, because RetroArch expects a \0 at the end, therefore we allocate new, copy and free the old one.
|
||||
/*We could either use the 7Zip allocated buffer,
|
||||
* or create our own and use it.
|
||||
* We would however need to realloc anyways, because RetroArch
|
||||
* expects a \0 at the end, therefore we allocate new,
|
||||
* copy and free the old one. */
|
||||
*buf = malloc(outsize + 1);
|
||||
|
||||
((char*)(*buf))[outsize] = '\0';
|
||||
|
@ -301,7 +315,8 @@ struct string_list *compressed_7zip_file_list_new(const char *path,
|
|||
|
||||
(void)outsize;
|
||||
|
||||
//These are the allocation routines - currently using the non-standard 7zip choices.
|
||||
/* These are the allocation routines - currently using
|
||||
* the non-standard 7zip choices. */
|
||||
allocImp.Alloc = SzAlloc;
|
||||
allocImp.Free = SzFree;
|
||||
allocTempImp.Alloc = SzAllocTemp;
|
||||
|
@ -391,7 +406,7 @@ struct string_list *compressed_7zip_file_list_new(const char *path,
|
|||
|
||||
if (res != SZ_OK)
|
||||
{
|
||||
//Error handling:
|
||||
/* Error handling */
|
||||
if (res == SZ_ERROR_UNSUPPORTED)
|
||||
{
|
||||
RARCH_ERR("7Zip decoder doesn't support this archive\n");
|
||||
|
|
13
driver.c
13
driver.c
|
@ -24,7 +24,6 @@
|
|||
#include <math.h>
|
||||
#include "compat/posix_string.h"
|
||||
#include "audio/utils.h"
|
||||
#include "audio/resampler.h"
|
||||
#include "gfx/thread_wrapper.h"
|
||||
#include "audio/thread_wrapper.h"
|
||||
#include "gfx/gfx_common.h"
|
||||
|
@ -238,6 +237,9 @@ static const menu_ctx_driver_t *menu_ctx_drivers[] = {
|
|||
#if defined(HAVE_LAKKA)
|
||||
&menu_ctx_lakka,
|
||||
#endif
|
||||
#if defined(HAVE_GLUI)
|
||||
&menu_ctx_glui,
|
||||
#endif
|
||||
#if defined(HAVE_RGUI)
|
||||
&menu_ctx_rgui,
|
||||
#endif
|
||||
|
@ -1060,14 +1062,14 @@ void init_audio(void)
|
|||
}
|
||||
|
||||
g_extern.audio_data.use_float = false;
|
||||
if (g_extern.audio_active && driver.audio->use_float &&
|
||||
driver.audio->use_float(driver.audio_data))
|
||||
if (g_extern.audio_active && driver.audio->use_float(driver.audio_data))
|
||||
g_extern.audio_data.use_float = true;
|
||||
|
||||
if (!g_settings.audio.sync && g_extern.audio_active)
|
||||
{
|
||||
rarch_main_command(RARCH_CMD_AUDIO_SET_NONBLOCKING_STATE);
|
||||
g_extern.audio_data.chunk_size = g_extern.audio_data.nonblock_chunk_size;
|
||||
g_extern.audio_data.chunk_size =
|
||||
g_extern.audio_data.nonblock_chunk_size;
|
||||
}
|
||||
|
||||
/* Should never happen. */
|
||||
|
@ -1269,9 +1271,6 @@ void rarch_init_filter(enum retro_pixel_format colfmt)
|
|||
geom = (struct retro_game_geometry*)&g_extern.system.av_info.geometry;
|
||||
width = geom->max_width;
|
||||
height = geom->max_height;
|
||||
pow2_x = 0;
|
||||
pow2_y = 0;
|
||||
maxsize = 0;
|
||||
|
||||
g_extern.filter.filter = rarch_softfilter_new(
|
||||
g_settings.video.softfilter_plugin,
|
||||
|
|
135
driver.h
135
driver.h
|
@ -588,74 +588,79 @@ bool driver_update_system_av_info(const struct retro_system_av_info *info);
|
|||
extern driver_t driver;
|
||||
|
||||
/* Backends */
|
||||
extern const audio_driver_t audio_rsound;
|
||||
extern const audio_driver_t audio_oss;
|
||||
extern const audio_driver_t audio_alsa;
|
||||
extern const audio_driver_t audio_alsathread;
|
||||
extern const audio_driver_t audio_roar;
|
||||
extern const audio_driver_t audio_openal;
|
||||
extern const audio_driver_t audio_opensl;
|
||||
extern const audio_driver_t audio_jack;
|
||||
extern const audio_driver_t audio_sdl;
|
||||
extern const audio_driver_t audio_xa;
|
||||
extern const audio_driver_t audio_pulse;
|
||||
extern const audio_driver_t audio_dsound;
|
||||
extern const audio_driver_t audio_coreaudio;
|
||||
extern const audio_driver_t audio_xenon360;
|
||||
extern const audio_driver_t audio_ps3;
|
||||
extern const audio_driver_t audio_gx;
|
||||
extern const audio_driver_t audio_psp1;
|
||||
extern const audio_driver_t audio_rwebaudio;
|
||||
extern const audio_driver_t audio_null;
|
||||
extern const video_driver_t video_gl;
|
||||
extern const video_driver_t video_psp1;
|
||||
extern const video_driver_t video_vita;
|
||||
extern const video_driver_t video_d3d;
|
||||
extern const video_driver_t video_gx;
|
||||
extern const video_driver_t video_xenon360;
|
||||
extern const video_driver_t video_xvideo;
|
||||
extern const video_driver_t video_xdk_d3d;
|
||||
extern const video_driver_t video_sdl;
|
||||
extern const video_driver_t video_sdl2;
|
||||
extern const video_driver_t video_vg;
|
||||
extern const video_driver_t video_null;
|
||||
extern const video_driver_t video_omap;
|
||||
extern const video_driver_t video_exynos;
|
||||
extern const input_driver_t input_android;
|
||||
extern const input_driver_t input_sdl;
|
||||
extern const input_driver_t input_dinput;
|
||||
extern const input_driver_t input_x;
|
||||
extern const input_driver_t input_wayland;
|
||||
extern const input_driver_t input_ps3;
|
||||
extern const input_driver_t input_psp;
|
||||
extern const input_driver_t input_xenon360;
|
||||
extern const input_driver_t input_gx;
|
||||
extern const input_driver_t input_xinput;
|
||||
extern const input_driver_t input_linuxraw;
|
||||
extern const input_driver_t input_udev;
|
||||
extern const input_driver_t input_apple;
|
||||
extern const input_driver_t input_qnx;
|
||||
extern const input_driver_t input_rwebinput;
|
||||
extern const input_driver_t input_null;
|
||||
extern const camera_driver_t camera_v4l2;
|
||||
extern const camera_driver_t camera_android;
|
||||
extern const camera_driver_t camera_rwebcam;
|
||||
extern const camera_driver_t camera_ios;
|
||||
extern const camera_driver_t camera_null;
|
||||
extern const location_driver_t location_apple;
|
||||
extern const location_driver_t location_android;
|
||||
extern const location_driver_t location_null;
|
||||
extern audio_driver_t audio_rsound;
|
||||
extern audio_driver_t audio_oss;
|
||||
extern audio_driver_t audio_alsa;
|
||||
extern audio_driver_t audio_alsathread;
|
||||
extern audio_driver_t audio_roar;
|
||||
extern audio_driver_t audio_openal;
|
||||
extern audio_driver_t audio_opensl;
|
||||
extern audio_driver_t audio_jack;
|
||||
extern audio_driver_t audio_sdl;
|
||||
extern audio_driver_t audio_xa;
|
||||
extern audio_driver_t audio_pulse;
|
||||
extern audio_driver_t audio_dsound;
|
||||
extern audio_driver_t audio_coreaudio;
|
||||
extern audio_driver_t audio_xenon360;
|
||||
extern audio_driver_t audio_ps3;
|
||||
extern audio_driver_t audio_gx;
|
||||
extern audio_driver_t audio_psp1;
|
||||
extern audio_driver_t audio_rwebaudio;
|
||||
extern audio_driver_t audio_null;
|
||||
|
||||
extern const input_osk_driver_t input_ps3_osk;
|
||||
extern const input_osk_driver_t input_null_osk;
|
||||
extern video_driver_t video_gl;
|
||||
extern video_driver_t video_psp1;
|
||||
extern video_driver_t video_vita;
|
||||
extern video_driver_t video_d3d;
|
||||
extern video_driver_t video_gx;
|
||||
extern video_driver_t video_xenon360;
|
||||
extern video_driver_t video_xvideo;
|
||||
extern video_driver_t video_xdk_d3d;
|
||||
extern video_driver_t video_sdl;
|
||||
extern video_driver_t video_sdl2;
|
||||
extern video_driver_t video_vg;
|
||||
extern video_driver_t video_null;
|
||||
extern video_driver_t video_omap;
|
||||
extern video_driver_t video_exynos;
|
||||
|
||||
extern const menu_ctx_driver_t menu_ctx_rmenu;
|
||||
extern const menu_ctx_driver_t menu_ctx_rmenu_xui;
|
||||
extern const menu_ctx_driver_t menu_ctx_rgui;
|
||||
extern const menu_ctx_driver_t menu_ctx_lakka;
|
||||
extern input_driver_t input_android;
|
||||
extern input_driver_t input_sdl;
|
||||
extern input_driver_t input_dinput;
|
||||
extern input_driver_t input_x;
|
||||
extern input_driver_t input_wayland;
|
||||
extern input_driver_t input_ps3;
|
||||
extern input_driver_t input_psp;
|
||||
extern input_driver_t input_xenon360;
|
||||
extern input_driver_t input_gx;
|
||||
extern input_driver_t input_xinput;
|
||||
extern input_driver_t input_linuxraw;
|
||||
extern input_driver_t input_udev;
|
||||
extern input_driver_t input_apple;
|
||||
extern input_driver_t input_qnx;
|
||||
extern input_driver_t input_rwebinput;
|
||||
extern input_driver_t input_null;
|
||||
|
||||
extern const menu_ctx_driver_backend_t menu_ctx_backend_common;
|
||||
extern const menu_ctx_driver_backend_t menu_ctx_backend_lakka;
|
||||
extern camera_driver_t camera_v4l2;
|
||||
extern camera_driver_t camera_android;
|
||||
extern camera_driver_t camera_rwebcam;
|
||||
extern camera_driver_t camera_ios;
|
||||
extern camera_driver_t camera_null;
|
||||
|
||||
extern location_driver_t location_apple;
|
||||
extern location_driver_t location_android;
|
||||
extern location_driver_t location_null;
|
||||
|
||||
extern input_osk_driver_t input_ps3_osk;
|
||||
extern input_osk_driver_t input_null_osk;
|
||||
|
||||
extern menu_ctx_driver_t menu_ctx_rmenu;
|
||||
extern menu_ctx_driver_t menu_ctx_rmenu_xui;
|
||||
extern menu_ctx_driver_t menu_ctx_rgui;
|
||||
extern menu_ctx_driver_t menu_ctx_glui;
|
||||
extern menu_ctx_driver_t menu_ctx_lakka;
|
||||
|
||||
extern menu_ctx_driver_backend_t menu_ctx_backend_common;
|
||||
extern menu_ctx_driver_backend_t menu_ctx_backend_lakka;
|
||||
|
||||
static inline bool input_key_pressed_func(int key)
|
||||
{
|
||||
|
|
|
@ -134,13 +134,16 @@ typedef struct menu_ctx_driver_backend
|
|||
{
|
||||
int (*iterate)(unsigned);
|
||||
void (*shader_manager_init)(menu_handle_t *);
|
||||
void (*shader_manager_get_str)(struct gfx_shader *, char *, size_t, const char *, const char *, unsigned);
|
||||
void (*shader_manager_set_preset)(struct gfx_shader *, unsigned, const char*);
|
||||
void (*shader_manager_get_str)(struct gfx_shader *, char *,
|
||||
size_t, const char *, const char *, unsigned);
|
||||
void (*shader_manager_set_preset)(struct gfx_shader *,
|
||||
unsigned, const char*);
|
||||
void (*shader_manager_save_preset)(const char *, bool);
|
||||
unsigned (*shader_manager_get_type)(const struct gfx_shader *);
|
||||
int (*shader_manager_setting_toggle)(unsigned, const char *, unsigned);
|
||||
unsigned (*type_is)(const char *, unsigned);
|
||||
void (*setting_set_label)(char *, size_t, unsigned *, unsigned, const char *, const char *, unsigned);
|
||||
void (*setting_set_label)(char *, size_t, unsigned *,
|
||||
unsigned, const char *, const char *, unsigned);
|
||||
const char *ident;
|
||||
} menu_ctx_driver_backend_t;
|
||||
|
||||
|
|
|
@ -71,8 +71,11 @@ extern const frontend_ctx_driver_t frontend_ctx_android;
|
|||
extern const frontend_ctx_driver_t frontend_ctx_psp;
|
||||
extern const frontend_ctx_driver_t frontend_ctx_null;
|
||||
|
||||
const frontend_ctx_driver_t *frontend_ctx_find_driver(const char *ident); // Finds driver with ident. Does not initialize.
|
||||
const frontend_ctx_driver_t *frontend_ctx_init_first(void); // Finds first suitable driver and initializes.
|
||||
/* Finds driver with ident. Does not initialize. */
|
||||
const frontend_ctx_driver_t *frontend_ctx_find_driver(const char *ident);
|
||||
|
||||
/* Finds first suitable driver and initialize. */
|
||||
const frontend_ctx_driver_t *frontend_ctx_init_first(void);
|
||||
|
||||
int main_entry_iterate_clear_input(signature(), args_type() args);
|
||||
int main_entry_iterate_load_content(signature(), args_type() args);
|
||||
|
|
|
@ -480,12 +480,6 @@ static void handle_setting(rarch_setting_t *setting,
|
|||
else if (action == MENU_ACTION_START)
|
||||
*setting->value.string = '\0';
|
||||
}
|
||||
else if (!strcmp(setting->name, "video_driver"))
|
||||
handle_driver(setting->name, g_settings.video.driver,
|
||||
sizeof(g_settings.video.driver), action);
|
||||
else if (!strcmp(setting->name, "audio_driver"))
|
||||
handle_driver(setting->name, g_settings.audio.driver,
|
||||
sizeof(g_settings.audio.driver), action);
|
||||
else if (!strcmp(setting->name, "audio_resampler_driver"))
|
||||
{
|
||||
if (action == MENU_ACTION_LEFT)
|
||||
|
@ -493,18 +487,9 @@ static void handle_setting(rarch_setting_t *setting,
|
|||
else if (action == MENU_ACTION_RIGHT)
|
||||
find_next_resampler_driver();
|
||||
}
|
||||
else if (!strcmp(setting->name, "input_driver"))
|
||||
handle_driver(setting->name, g_settings.input.driver,
|
||||
sizeof(g_settings.input.driver), action);
|
||||
else if (!strcmp(setting->name, "camera_driver"))
|
||||
handle_driver(setting->name, g_settings.camera.driver,
|
||||
sizeof(g_settings.camera.driver), action);
|
||||
else if (!strcmp(setting->name, "location_driver"))
|
||||
handle_driver(setting->name, g_settings.location.driver,
|
||||
sizeof(g_settings.location.driver), action);
|
||||
else if (!strcmp(setting->name, "menu_driver"))
|
||||
handle_driver(setting->name, g_settings.menu.driver,
|
||||
sizeof(g_settings.menu.driver), action);
|
||||
else if (id == MENU_FILE_DRIVER)
|
||||
handle_driver(setting->name, setting->value.string,
|
||||
setting->size, action);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1366,6 +1351,12 @@ static int menu_custom_bind_iterate_keyboard(void *data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void menu_common_load_content(void)
|
||||
{
|
||||
rarch_main_command(RARCH_CMD_LOAD_CONTENT);
|
||||
menu_flush_stack_type(driver.menu->menu_stack,MENU_SETTINGS);
|
||||
driver.menu->msg_force = true;
|
||||
}
|
||||
|
||||
static int menu_action_ok(const char *menu_path,
|
||||
const char *menu_label, unsigned menu_type)
|
||||
|
@ -1390,173 +1381,201 @@ static int menu_action_ok(const char *menu_path,
|
|||
RARCH_LOG("type id : %d\n", type);
|
||||
#endif
|
||||
|
||||
if (type == MENU_FILE_PLAYLIST_ENTRY)
|
||||
switch (type)
|
||||
{
|
||||
rarch_playlist_load_content(g_extern.history,
|
||||
driver.menu->selection_ptr);
|
||||
menu_flush_stack_type(driver.menu->menu_stack, MENU_SETTINGS);
|
||||
return -1;
|
||||
}
|
||||
else if (!strcmp(menu_label, "detect_core_list")
|
||||
&& type == MENU_FILE_PLAIN)
|
||||
{
|
||||
int ret = rarch_defer_core(g_extern.core_info,
|
||||
menu_path, path, driver.menu->deferred_path,
|
||||
sizeof(driver.menu->deferred_path));
|
||||
case MENU_FILE_PLAYLIST_ENTRY:
|
||||
|
||||
if (ret == -1)
|
||||
{
|
||||
|
||||
rarch_main_command(RARCH_CMD_LOAD_CONTENT);
|
||||
rarch_main_command(RARCH_CMD_LOAD_CORE);
|
||||
menu_flush_stack_type(driver.menu->menu_stack,MENU_SETTINGS);
|
||||
driver.menu->msg_force = true;
|
||||
rarch_playlist_load_content(g_extern.history,
|
||||
driver.menu->selection_ptr);
|
||||
menu_flush_stack_type(driver.menu->menu_stack, MENU_SETTINGS);
|
||||
return -1;
|
||||
}
|
||||
else if (ret == 0)
|
||||
menu_entries_push(driver.menu->menu_stack,
|
||||
g_settings.libretro_directory, "deferred_core_list",
|
||||
0, driver.menu->selection_ptr);
|
||||
}
|
||||
else if ((setting && setting->type == ST_DIR)
|
||||
&& (type == MENU_FILE_USE_DIRECTORY))
|
||||
{
|
||||
menu_common_setting_set_current_string(setting, menu_path);
|
||||
menu_entries_pop_stack(driver.menu->menu_stack, setting->name);
|
||||
}
|
||||
else if ((setting && setting->type == ST_PATH)
|
||||
&& (type == MENU_FILE_PLAIN))
|
||||
{
|
||||
menu_common_setting_set_current_string_path(setting, menu_path, path);
|
||||
menu_entries_pop_stack(driver.menu->menu_stack, setting->name);
|
||||
}
|
||||
|
||||
case MENU_FILE_PLAIN:
|
||||
if (!strcmp(menu_label, "detect_core_list"))
|
||||
{
|
||||
int ret = rarch_defer_core(g_extern.core_info,
|
||||
menu_path, path, driver.menu->deferred_path,
|
||||
sizeof(driver.menu->deferred_path));
|
||||
|
||||
if (ret == -1)
|
||||
{
|
||||
|
||||
rarch_main_command(RARCH_CMD_LOAD_CORE);
|
||||
|
||||
menu_common_load_content();
|
||||
|
||||
return -1;
|
||||
}
|
||||
else if (ret == 0)
|
||||
menu_entries_push(driver.menu->menu_stack,
|
||||
g_settings.libretro_directory, "deferred_core_list",
|
||||
0, driver.menu->selection_ptr);
|
||||
}
|
||||
else if ((setting && setting->type == ST_PATH))
|
||||
{
|
||||
menu_common_setting_set_current_string_path(setting, menu_path, path);
|
||||
menu_entries_pop_stack(driver.menu->menu_stack, setting->name);
|
||||
}
|
||||
else if (!strcmp(menu_label, "disk_image_append"))
|
||||
{
|
||||
char image[PATH_MAX];
|
||||
fill_pathname_join(image, menu_path, path, sizeof(image));
|
||||
rarch_disk_control_append_image(image);
|
||||
|
||||
rarch_main_command(RARCH_CMD_RESUME);
|
||||
|
||||
menu_flush_stack_type(driver.menu->menu_stack,MENU_SETTINGS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
case MENU_FILE_CONFIG:
|
||||
|
||||
{
|
||||
char config[PATH_MAX];
|
||||
fill_pathname_join(config, menu_path, path, sizeof(config));
|
||||
menu_flush_stack_type(driver.menu->menu_stack,MENU_SETTINGS);
|
||||
driver.menu->msg_force = true;
|
||||
if (rarch_replace_config(config))
|
||||
{
|
||||
menu_clear_navigation(driver.menu);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
case MENU_FILE_FONT:
|
||||
case MENU_FILE_OVERLAY:
|
||||
case MENU_FILE_AUDIOFILTER:
|
||||
case MENU_FILE_VIDEOFILTER:
|
||||
|
||||
menu_common_setting_set_current_string_path(setting, menu_path, path);
|
||||
menu_entries_pop_stack(driver.menu->menu_stack, setting->name);
|
||||
|
||||
return 0;
|
||||
|
||||
case MENU_FILE_SHADER_PRESET:
|
||||
#ifdef HAVE_SHADER_MANAGER
|
||||
else if (!strcmp(menu_label, "video_shader_preset")
|
||||
&& type == MENU_FILE_PLAIN)
|
||||
{
|
||||
char shader_path[PATH_MAX];
|
||||
fill_pathname_join(shader_path, menu_path, path, sizeof(shader_path));
|
||||
if (driver.menu_ctx && driver.menu_ctx->backend &&
|
||||
driver.menu_ctx->backend->shader_manager_set_preset)
|
||||
driver.menu_ctx->backend->shader_manager_set_preset(
|
||||
driver.menu->shader,
|
||||
gfx_shader_parse_type(shader_path, RARCH_SHADER_NONE),
|
||||
shader_path);
|
||||
menu_flush_stack_label(driver.menu->menu_stack, "Shader Options");
|
||||
}
|
||||
else if (!strcmp(menu_label, "video_shader_pass")
|
||||
&& type == MENU_FILE_PLAIN)
|
||||
{
|
||||
fill_pathname_join(driver.menu->shader->pass[hack_shader_pass].source.path,
|
||||
menu_path, path,
|
||||
sizeof(driver.menu->shader->pass[hack_shader_pass].source.path));
|
||||
|
||||
/* This will reset any changed parameters. */
|
||||
gfx_shader_resolve_parameters(NULL, driver.menu->shader);
|
||||
menu_flush_stack_label(driver.menu->menu_stack, "Shader Options");
|
||||
}
|
||||
{
|
||||
char shader_path[PATH_MAX];
|
||||
fill_pathname_join(shader_path, menu_path, path, sizeof(shader_path));
|
||||
if (driver.menu_ctx && driver.menu_ctx->backend &&
|
||||
driver.menu_ctx->backend->shader_manager_set_preset)
|
||||
driver.menu_ctx->backend->shader_manager_set_preset(
|
||||
driver.menu->shader,
|
||||
gfx_shader_parse_type(shader_path, RARCH_SHADER_NONE),
|
||||
shader_path);
|
||||
menu_flush_stack_label(driver.menu->menu_stack, "Shader Options");
|
||||
}
|
||||
#endif
|
||||
else if (!strcmp(menu_label, "deferred_core_list")
|
||||
&& type == MENU_FILE_CORE)
|
||||
{
|
||||
strlcpy(g_settings.libretro, path, sizeof(g_settings.libretro));
|
||||
strlcpy(g_extern.fullpath, driver.menu->deferred_path,
|
||||
sizeof(g_extern.fullpath));
|
||||
rarch_main_command(RARCH_CMD_LOAD_CONTENT);
|
||||
driver.menu->msg_force = true;
|
||||
menu_flush_stack_type(driver.menu->menu_stack,MENU_SETTINGS);
|
||||
return -1;
|
||||
}
|
||||
else if (!strcmp(menu_label, "core_list")
|
||||
&& type == MENU_FILE_CORE)
|
||||
{
|
||||
fill_pathname_join(g_settings.libretro, menu_path, path,
|
||||
sizeof(g_settings.libretro));
|
||||
rarch_main_command(RARCH_CMD_LOAD_CORE);
|
||||
menu_flush_stack_type(driver.menu->menu_stack,MENU_SETTINGS);
|
||||
return 0;
|
||||
case MENU_FILE_SHADER:
|
||||
#ifdef HAVE_SHADER_MANAGER
|
||||
fill_pathname_join(driver.menu->shader->pass[hack_shader_pass].source.path,
|
||||
menu_path, path,
|
||||
sizeof(driver.menu->shader->pass[hack_shader_pass].source.path));
|
||||
|
||||
/* This will reset any changed parameters. */
|
||||
gfx_shader_resolve_parameters(NULL, driver.menu->shader);
|
||||
menu_flush_stack_label(driver.menu->menu_stack, "Shader Options");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
case MENU_FILE_CORE:
|
||||
|
||||
if (!strcmp(menu_label, "deferred_core_list"))
|
||||
{
|
||||
strlcpy(g_settings.libretro, path, sizeof(g_settings.libretro));
|
||||
strlcpy(g_extern.fullpath, driver.menu->deferred_path,
|
||||
sizeof(g_extern.fullpath));
|
||||
|
||||
menu_common_load_content();
|
||||
|
||||
return -1;
|
||||
}
|
||||
else if (!strcmp(menu_label, "core_list"))
|
||||
{
|
||||
fill_pathname_join(g_settings.libretro, menu_path, path,
|
||||
sizeof(g_settings.libretro));
|
||||
rarch_main_command(RARCH_CMD_LOAD_CORE);
|
||||
menu_flush_stack_type(driver.menu->menu_stack,MENU_SETTINGS);
|
||||
#if defined(HAVE_DYNAMIC)
|
||||
/* No content needed for this core, load core immediately. */
|
||||
if (driver.menu->load_no_content)
|
||||
{
|
||||
rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT);
|
||||
*g_extern.fullpath = '\0';
|
||||
driver.menu->msg_force = true;
|
||||
return -1;
|
||||
}
|
||||
/* No content needed for this core, load core immediately. */
|
||||
if (driver.menu->load_no_content)
|
||||
{
|
||||
*g_extern.fullpath = '\0';
|
||||
menu_common_load_content();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Core selection on non-console just updates directory listing.
|
||||
* Will take effect on new content load. */
|
||||
/* Core selection on non-console just updates directory listing.
|
||||
* Will take effect on new content load. */
|
||||
#elif defined(RARCH_CONSOLE)
|
||||
rarch_main_command(RARCH_CMD_RESTART_RETROARCH);
|
||||
return -1;
|
||||
rarch_main_command(RARCH_CMD_RESTART_RETROARCH);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
else if (!strcmp(menu_label, "configurations")
|
||||
&& type == MENU_FILE_PLAIN)
|
||||
{
|
||||
char config[PATH_MAX];
|
||||
fill_pathname_join(config, menu_path, path, sizeof(config));
|
||||
menu_flush_stack_type(driver.menu->menu_stack,MENU_SETTINGS);
|
||||
driver.menu->msg_force = true;
|
||||
if (rarch_replace_config(config))
|
||||
{
|
||||
menu_clear_navigation(driver.menu);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(menu_label, "disk_image_append")
|
||||
&& type == MENU_FILE_PLAIN)
|
||||
{
|
||||
char image[PATH_MAX];
|
||||
fill_pathname_join(image, menu_path, path, sizeof(image));
|
||||
rarch_disk_control_append_image(image);
|
||||
}
|
||||
|
||||
rarch_main_command(RARCH_CMD_RESUME);
|
||||
return 0;
|
||||
|
||||
menu_flush_stack_type(driver.menu->menu_stack,MENU_SETTINGS);
|
||||
return -1;
|
||||
}
|
||||
else if (menu_parse_check(label, type) == 0)
|
||||
{
|
||||
char cat_path[PATH_MAX];
|
||||
fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path));
|
||||
case MENU_FILE_USE_DIRECTORY:
|
||||
|
||||
menu_entries_push(driver.menu->menu_stack,
|
||||
cat_path, menu_label, type, driver.menu->selection_ptr);
|
||||
}
|
||||
else if (type == MENU_FILE_CARCHIVE)
|
||||
{
|
||||
char cat_path[PATH_MAX];
|
||||
fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path));
|
||||
if (setting && setting->type == ST_DIR)
|
||||
{
|
||||
menu_common_setting_set_current_string(setting, menu_path);
|
||||
menu_entries_pop_stack(driver.menu->menu_stack, setting->name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
case MENU_FILE_DIRECTORY:
|
||||
case MENU_FILE_CARCHIVE:
|
||||
|
||||
{
|
||||
char cat_path[PATH_MAX];
|
||||
fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path));
|
||||
|
||||
menu_entries_push(driver.menu->menu_stack,
|
||||
cat_path, menu_label, type, driver.menu->selection_ptr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
menu_entries_push(driver.menu->menu_stack,
|
||||
cat_path, menu_label, type, driver.menu->selection_ptr);
|
||||
return 0;
|
||||
}
|
||||
#ifdef HAVE_COMPRESSION
|
||||
else if (type == MENU_FILE_IN_CARCHIVE)
|
||||
{
|
||||
fill_pathname_join(g_extern.fullpath, menu_path, path,
|
||||
sizeof(g_extern.fullpath));
|
||||
case MENU_FILE_IN_CARCHIVE:
|
||||
|
||||
g_extern.is_carchive = true;
|
||||
strncpy(g_extern.carchive_path, menu_path,
|
||||
sizeof(g_extern.carchive_path));
|
||||
fill_pathname_join(g_extern.fullpath, menu_path, path,
|
||||
sizeof(g_extern.fullpath));
|
||||
|
||||
rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT);
|
||||
menu_flush_stack_type(driver.menu->menu_stack,MENU_SETTINGS);
|
||||
driver.menu->msg_force = true;
|
||||
return -1;
|
||||
}
|
||||
g_extern.is_carchive = true;
|
||||
strncpy(g_extern.carchive_path, menu_path,
|
||||
sizeof(g_extern.carchive_path));
|
||||
|
||||
menu_common_load_content();
|
||||
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
if (menu_parse_check(label, type) == 0)
|
||||
{
|
||||
char cat_path[PATH_MAX];
|
||||
fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path));
|
||||
|
||||
menu_entries_push(driver.menu->menu_stack,
|
||||
cat_path, menu_label, type, driver.menu->selection_ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
fill_pathname_join(g_extern.fullpath, menu_path, path,
|
||||
sizeof(g_extern.fullpath));
|
||||
rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT);
|
||||
|
||||
menu_flush_stack_type(driver.menu->menu_stack,MENU_SETTINGS);
|
||||
driver.menu->msg_force = true;
|
||||
menu_common_load_content();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1720,7 +1739,7 @@ static void menu_common_setting_set_label(char *type_str,
|
|||
type, menu_label, label, index);
|
||||
}
|
||||
|
||||
const menu_ctx_driver_backend_t menu_ctx_backend_common = {
|
||||
menu_ctx_driver_backend_t menu_ctx_backend_common = {
|
||||
menu_common_iterate,
|
||||
#ifdef HAVE_SHADER_MANAGER
|
||||
menu_common_shader_manager_init,
|
||||
|
|
|
@ -45,7 +45,7 @@ static void lakka_switch_categories(void)
|
|||
int i, j;
|
||||
|
||||
// translation
|
||||
add_tween(DELAY, -menu_active_category * hspacing, &all_categories_x, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, -menu_active_category * hspacing, &all_categories_x, &inOutQuad, NULL);
|
||||
|
||||
// alpha tweening
|
||||
for (i = 0; i < num_categories; i++)
|
||||
|
@ -58,15 +58,15 @@ static void lakka_switch_categories(void)
|
|||
|
||||
ca = (i == menu_active_category) ? 1.0 : 0.5;
|
||||
cz = (i == menu_active_category) ? c_active_zoom : c_passive_zoom;
|
||||
add_tween(DELAY, ca, &category->alpha, &inOutQuad, NULL);
|
||||
add_tween(DELAY, cz, &category->zoom, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, ca, &category->alpha, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, cz, &category->zoom, &inOutQuad, NULL);
|
||||
|
||||
for (j = 0; j < category->num_items; j++)
|
||||
{
|
||||
float ia = (i != menu_active_category ) ? 0 :
|
||||
(j == category->active_item) ? 1.0 : 0.5;
|
||||
|
||||
add_tween(DELAY, ia, &category->items[j].alpha, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, ia, &category->items[j].alpha, &inOutQuad, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,9 +90,9 @@ static void lakka_switch_items(void)
|
|||
(j < active_category->active_item) ? vspacing*(j - active_category->active_item + above_item_offset) :
|
||||
vspacing*(j - active_category->active_item + under_item_offset);
|
||||
|
||||
add_tween(DELAY, ia, &active_item->alpha, &inOutQuad, NULL);
|
||||
add_tween(DELAY, iz, &active_item->zoom, &inOutQuad, NULL);
|
||||
add_tween(DELAY, iy, &active_item->y, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, ia, &active_item->alpha, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, iz, &active_item->zoom, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, iy, &active_item->y, &inOutQuad, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,24 +111,24 @@ static void lakka_switch_subitems(void)
|
|||
|
||||
if (k < item->active_subitem)
|
||||
{
|
||||
// Above items
|
||||
add_tween(DELAY, 0.5, &subitem->alpha, &inOutQuad, NULL);
|
||||
add_tween(DELAY, vspacing*(k - item->active_subitem + above_subitem_offset), &subitem->y, &inOutQuad, NULL);
|
||||
add_tween(DELAY, i_passive_zoom, &subitem->zoom, &inOutQuad, NULL);
|
||||
/* Above items */
|
||||
add_tween(LAKKA_DELAY, 0.5, &subitem->alpha, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, vspacing*(k - item->active_subitem + above_subitem_offset), &subitem->y, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, i_passive_zoom, &subitem->zoom, &inOutQuad, NULL);
|
||||
}
|
||||
else if (k == item->active_subitem)
|
||||
{
|
||||
// Active item
|
||||
add_tween(DELAY, 1.0, &subitem->alpha, &inOutQuad, NULL);
|
||||
add_tween(DELAY, vspacing*active_item_factor, &subitem->y, &inOutQuad, NULL);
|
||||
add_tween(DELAY, i_active_zoom, &subitem->zoom, &inOutQuad, NULL);
|
||||
/* Active item */
|
||||
add_tween(LAKKA_DELAY, 1.0, &subitem->alpha, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, vspacing*active_item_factor, &subitem->y, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, i_active_zoom, &subitem->zoom, &inOutQuad, NULL);
|
||||
}
|
||||
else if (k > item->active_subitem)
|
||||
{
|
||||
// Under items
|
||||
add_tween(DELAY, 0.5, &subitem->alpha, &inOutQuad, NULL);
|
||||
add_tween(DELAY, vspacing*(k - item->active_subitem + under_item_offset), &subitem->y, &inOutQuad, NULL);
|
||||
add_tween(DELAY, i_passive_zoom, &subitem->zoom, &inOutQuad, NULL);
|
||||
/* Under items */
|
||||
add_tween(LAKKA_DELAY, 0.5, &subitem->alpha, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, vspacing*(k - item->active_subitem + under_item_offset), &subitem->y, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, i_passive_zoom, &subitem->zoom, &inOutQuad, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,8 +174,9 @@ static void lakka_reset_submenu(void)
|
|||
static void lakka_open_submenu(void)
|
||||
{
|
||||
int i, j, k;
|
||||
add_tween(DELAY, -hspacing * (menu_active_category+1), &all_categories_x, &inOutQuad, NULL);
|
||||
add_tween(DELAY, 1.0, &arrow_alpha, &inOutQuad, NULL);
|
||||
|
||||
add_tween(LAKKA_DELAY, -hspacing * (menu_active_category+1), &all_categories_x, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, 1.0, &arrow_alpha, &inOutQuad, NULL);
|
||||
|
||||
// Reset contextual menu style
|
||||
lakka_reset_submenu();
|
||||
|
@ -188,10 +189,10 @@ static void lakka_open_submenu(void)
|
|||
continue;
|
||||
|
||||
if (i != menu_active_category)
|
||||
add_tween(DELAY, 0, &category->alpha, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, 0, &category->alpha, &inOutQuad, NULL);
|
||||
else
|
||||
{
|
||||
add_tween(DELAY, 1.0, &category->alpha, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, 1.0, &category->alpha, &inOutQuad, NULL);
|
||||
|
||||
for (j = 0; j < category->num_items; j++)
|
||||
{
|
||||
|
@ -203,18 +204,18 @@ static void lakka_open_submenu(void)
|
|||
|
||||
if (k == category->items[j].active_subitem)
|
||||
{
|
||||
add_tween(DELAY, 1.0, &subitem->alpha, &inOutQuad, NULL);
|
||||
add_tween(DELAY, i_active_zoom, &subitem->zoom, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, 1.0, &subitem->alpha, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, i_active_zoom, &subitem->zoom, &inOutQuad, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
add_tween(DELAY, 0.5, &subitem->alpha, &inOutQuad, NULL);
|
||||
add_tween(DELAY, i_passive_zoom, &subitem->zoom, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, 0.5, &subitem->alpha, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, i_passive_zoom, &subitem->zoom, &inOutQuad, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
add_tween(DELAY, 0, &category->items[j].alpha, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, 0, &category->items[j].alpha, &inOutQuad, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -223,8 +224,9 @@ static void lakka_open_submenu(void)
|
|||
static void lakka_close_submenu(void)
|
||||
{
|
||||
int i, j, k;
|
||||
add_tween(DELAY, -hspacing * menu_active_category, &all_categories_x, &inOutQuad, NULL);
|
||||
add_tween(DELAY, 0.0, &arrow_alpha, &inOutQuad, NULL);
|
||||
|
||||
add_tween(LAKKA_DELAY, -hspacing * menu_active_category, &all_categories_x, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, 0.0, &arrow_alpha, &inOutQuad, NULL);
|
||||
|
||||
for (i = 0; i < num_categories; i++)
|
||||
{
|
||||
|
@ -235,29 +237,29 @@ static void lakka_close_submenu(void)
|
|||
|
||||
if (i == menu_active_category)
|
||||
{
|
||||
add_tween(DELAY, 1.0, &category->alpha, &inOutQuad, NULL);
|
||||
add_tween(DELAY, c_active_zoom, &category->zoom, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, 1.0, &category->alpha, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, c_active_zoom, &category->zoom, &inOutQuad, NULL);
|
||||
|
||||
for (j = 0; j < category->num_items; j++)
|
||||
{
|
||||
if (j == category->active_item)
|
||||
{
|
||||
add_tween(DELAY, 1.0, &category->items[j].alpha, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, 1.0, &category->items[j].alpha, &inOutQuad, NULL);
|
||||
|
||||
for (k = 0; k < category->items[j].num_subitems; k++)
|
||||
add_tween(DELAY, 0, &category->items[j].subitems[k].alpha, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, 0, &category->items[j].subitems[k].alpha, &inOutQuad, NULL);
|
||||
}
|
||||
else
|
||||
add_tween(DELAY, 0.5, &category->items[j].alpha, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, 0.5, &category->items[j].alpha, &inOutQuad, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
add_tween(DELAY, 0.5, &category->alpha, &inOutQuad, NULL);
|
||||
add_tween(DELAY, c_passive_zoom, &category->zoom, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, 0.5, &category->alpha, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, c_passive_zoom, &category->zoom, &inOutQuad, NULL);
|
||||
|
||||
for (j = 0; j < category->num_items; j++)
|
||||
add_tween(DELAY, 0, &category->items[j].alpha, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, 0, &category->items[j].alpha, &inOutQuad, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -295,6 +297,13 @@ static int menu_lakka_iterate(unsigned action)
|
|||
menu_active_category--;
|
||||
lakka_switch_categories();
|
||||
}
|
||||
else if (depth == 1 && menu_active_category > 0
|
||||
&& (active_item->active_subitem == 1
|
||||
|| active_item->active_subitem == 2)
|
||||
&& g_settings.state_slot > -1)
|
||||
{
|
||||
g_settings.state_slot--;
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_ACTION_RIGHT:
|
||||
|
@ -303,6 +312,13 @@ static int menu_lakka_iterate(unsigned action)
|
|||
menu_active_category++;
|
||||
lakka_switch_categories();
|
||||
}
|
||||
else if (depth == 1 && menu_active_category > 0
|
||||
&& (active_item->active_subitem == 1
|
||||
|| active_item->active_subitem == 2)
|
||||
&& g_settings.state_slot < 255)
|
||||
{
|
||||
g_settings.state_slot++;
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_ACTION_DOWN:
|
||||
|
@ -385,7 +401,7 @@ static int menu_lakka_iterate(unsigned action)
|
|||
}
|
||||
else if (depth == 0 && menu_active_category == 0 && active_category->active_item == active_category->num_items-1)
|
||||
{
|
||||
add_tween(DELAY, 1.0, &global_alpha, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, 1.0, &global_alpha, &inOutQuad, NULL);
|
||||
rarch_main_set_state(RARCH_ACTION_STATE_RUNNING_FINISHED);
|
||||
return -1;
|
||||
}
|
||||
|
@ -411,7 +427,7 @@ static int menu_lakka_iterate(unsigned action)
|
|||
return 0;
|
||||
}
|
||||
|
||||
const menu_ctx_driver_backend_t menu_ctx_backend_lakka = {
|
||||
menu_ctx_driver_backend_t menu_ctx_backend_lakka = {
|
||||
menu_lakka_iterate,
|
||||
//#ifndef HAVE_SHADER_MANAGER
|
||||
NULL,
|
||||
|
|
|
@ -0,0 +1,340 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2014 - Daniel De Matteis
|
||||
* Copyright (C) 2012-2014 - Michael Lelli
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "../backend/menu_common_backend.h"
|
||||
#include "../menu_common.h"
|
||||
#include "../../../general.h"
|
||||
#include "../../../gfx/gfx_common.h"
|
||||
#include "../../../config.def.h"
|
||||
#include "../../../file.h"
|
||||
#include "../../../dynamic.h"
|
||||
#include "../../../compat/posix_string.h"
|
||||
#include "../../../performance.h"
|
||||
#include "../../../input/input_common.h"
|
||||
|
||||
#include "../../../settings_data.h"
|
||||
#include "../../../screenshot.h"
|
||||
#include "../../../gfx/fonts/bitmap.h"
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
#define GLUI_FONT_HEIGHT_STRIDE 40
|
||||
#define GLUI_FONT_WIDTH_STRIDE 20
|
||||
#define GLUI_TERM_START_X (gl->win_width / 21)
|
||||
#define GLUI_TERM_START_Y (gl->win_height / 9)
|
||||
#define GLUI_TERM_WIDTH (((gl->win_width - GLUI_TERM_START_X - GLUI_TERM_START_X) / (GLUI_FONT_WIDTH_STRIDE)))
|
||||
#define GLUI_TERM_HEIGHT (((gl->win_height - GLUI_TERM_START_Y) / (GLUI_FONT_HEIGHT_STRIDE)) - 1)
|
||||
|
||||
const gl_font_renderer_t *font_driver;
|
||||
|
||||
static void blit_line(float x, float y, const char *message, bool green)
|
||||
{
|
||||
gl_t *gl = (gl_t*)driver.video_data;
|
||||
if (!driver.menu || !gl)
|
||||
return;
|
||||
|
||||
gl_set_viewport(gl, gl->win_width, gl->win_height, false, false);
|
||||
|
||||
struct font_params params = {0};
|
||||
params.x = x / gl->win_width;
|
||||
params.y = 1.0f - y / gl->win_height;
|
||||
|
||||
params.scale = 1.0;
|
||||
params.color = green ? FONT_COLOR_RGBA(100, 255, 100, 255)
|
||||
: FONT_COLOR_RGBA(255, 255, 255, 255);
|
||||
params.full_screen = true;
|
||||
|
||||
if (font_driver)
|
||||
font_driver->render_msg((void*)driver.menu->font, message, ¶ms);
|
||||
}
|
||||
|
||||
static void glui_render_background(void)
|
||||
{
|
||||
GLfloat color[] = {
|
||||
0.0f, 0.0f, 0.0f, 0.9f,
|
||||
0.0f, 0.0f, 0.0f, 0.9f,
|
||||
0.0f, 0.0f, 0.0f, 0.9f,
|
||||
0.0f, 0.0f, 0.0f, 0.9f,
|
||||
};
|
||||
|
||||
gl_t *gl = (gl_t*)driver.video_data;
|
||||
if (!gl)
|
||||
return;
|
||||
|
||||
gl_set_viewport(gl, gl->win_width, gl->win_height, false, false);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
gl->coords.vertex = gl->vertex_ptr;
|
||||
gl->coords.tex_coord = (GLfloat*)calloc(4, sizeof(GLfloat));
|
||||
gl->coords.color = color;
|
||||
|
||||
gl->coords.vertices = 4;
|
||||
gl_shader_set_coords(gl, &gl->coords, &gl->mvp);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glDisable(GL_BLEND);
|
||||
gl->coords.color = gl->white_color_ptr;
|
||||
}
|
||||
|
||||
static void glui_render_messagebox(const char *message)
|
||||
{
|
||||
}
|
||||
|
||||
static void glui_frame(void)
|
||||
{
|
||||
gl_t *gl = (gl_t*)driver.video_data;
|
||||
|
||||
if (!driver.menu || !gl)
|
||||
return;
|
||||
|
||||
glViewport(0, 0, gl->win_width, gl->win_height);
|
||||
|
||||
size_t begin = 0;
|
||||
size_t end;
|
||||
|
||||
if (driver.menu->selection_ptr >= GLUI_TERM_HEIGHT / 2)
|
||||
begin = driver.menu->selection_ptr - GLUI_TERM_HEIGHT / 2;
|
||||
end = (driver.menu->selection_ptr + GLUI_TERM_HEIGHT <=
|
||||
file_list_get_size(driver.menu->selection_buf)) ?
|
||||
driver.menu->selection_ptr + GLUI_TERM_HEIGHT :
|
||||
file_list_get_size(driver.menu->selection_buf);
|
||||
|
||||
/* Do not scroll if all items are visible. */
|
||||
if (file_list_get_size(driver.menu->selection_buf) <= GLUI_TERM_HEIGHT)
|
||||
begin = 0;
|
||||
|
||||
if (end - begin > GLUI_TERM_HEIGHT)
|
||||
end = begin + GLUI_TERM_HEIGHT;
|
||||
|
||||
glui_render_background();
|
||||
|
||||
char title[256];
|
||||
const char *dir = NULL;
|
||||
const char *label = NULL;
|
||||
unsigned menu_type = 0;
|
||||
unsigned menu_type_is = 0;
|
||||
file_list_get_last(driver.menu->menu_stack, &dir, &label, &menu_type);
|
||||
|
||||
if (driver.menu_ctx && driver.menu_ctx->backend &&
|
||||
driver.menu_ctx->backend->type_is)
|
||||
menu_type_is = driver.menu_ctx->backend->type_is(label, menu_type);
|
||||
|
||||
#if 0
|
||||
RARCH_LOG("Dir is: %s\n", label);
|
||||
#endif
|
||||
|
||||
get_title(label, dir, menu_type, menu_type_is,
|
||||
title, sizeof(title));
|
||||
|
||||
char title_buf[256];
|
||||
menu_ticker_line(title_buf, GLUI_TERM_WIDTH - 3,
|
||||
g_extern.frame_count / GLUI_TERM_START_X, title, true);
|
||||
blit_line(GLUI_TERM_START_X + GLUI_TERM_START_X, GLUI_TERM_START_X, title_buf, true);
|
||||
|
||||
char title_msg[64];
|
||||
const char *core_name = g_extern.menu.info.library_name;
|
||||
if (!core_name)
|
||||
core_name = g_extern.system.info.library_name;
|
||||
if (!core_name)
|
||||
core_name = "No Core";
|
||||
|
||||
const char *core_version = g_extern.menu.info.library_version;
|
||||
if (!core_version)
|
||||
core_version = g_extern.system.info.library_version;
|
||||
if (!core_version)
|
||||
core_version = "";
|
||||
|
||||
snprintf(title_msg, sizeof(title_msg), "%s - %s %s", PACKAGE_VERSION,
|
||||
core_name, core_version);
|
||||
blit_line(
|
||||
GLUI_TERM_START_X + GLUI_TERM_START_X,
|
||||
(GLUI_TERM_HEIGHT * GLUI_FONT_HEIGHT_STRIDE) +
|
||||
GLUI_TERM_START_Y + 2, title_msg, true);
|
||||
|
||||
unsigned x, y;
|
||||
size_t i;
|
||||
|
||||
x = GLUI_TERM_START_X;
|
||||
y = GLUI_TERM_START_Y;
|
||||
|
||||
for (i = begin; i < end; i++, y += GLUI_FONT_HEIGHT_STRIDE)
|
||||
{
|
||||
char message[PATH_MAX], type_str[PATH_MAX],
|
||||
entry_title_buf[PATH_MAX], type_str_buf[PATH_MAX],
|
||||
path_buf[PATH_MAX];
|
||||
const char *path = NULL, *entry_label = NULL;
|
||||
unsigned type = 0, w = 0;
|
||||
bool selected = false;
|
||||
|
||||
file_list_get_at_offset(driver.menu->selection_buf, i, &path,
|
||||
&entry_label, &type);
|
||||
rarch_setting_t *setting = (rarch_setting_t*)setting_data_find_setting(
|
||||
setting_data_get_list(),
|
||||
driver.menu->selection_buf->list[i].label);
|
||||
(void)setting;
|
||||
|
||||
disp_set_label(&w, type, i, label,
|
||||
type_str, sizeof(type_str),
|
||||
entry_label, path,
|
||||
path_buf, sizeof(path_buf));
|
||||
|
||||
selected = (i == driver.menu->selection_ptr);
|
||||
|
||||
menu_ticker_line(entry_title_buf, GLUI_TERM_WIDTH - (w + 1 + 2),
|
||||
g_extern.frame_count / GLUI_TERM_START_X, path_buf, selected);
|
||||
menu_ticker_line(type_str_buf, w, g_extern.frame_count / GLUI_TERM_START_X,
|
||||
type_str, selected);
|
||||
|
||||
snprintf(message, sizeof(message), "%c %-*.*s %-*s",
|
||||
selected ? '>' : ' ',
|
||||
GLUI_TERM_WIDTH - (w + 1 + 2),
|
||||
GLUI_TERM_WIDTH - (w + 1 + 2),
|
||||
entry_title_buf,
|
||||
w,
|
||||
type_str_buf);
|
||||
|
||||
blit_line(x, y, message, selected);
|
||||
}
|
||||
|
||||
#ifdef GEKKO
|
||||
const char *message_queue;
|
||||
|
||||
if (driver.menu->msg_force)
|
||||
{
|
||||
message_queue = msg_queue_pull(g_extern.msg_queue);
|
||||
driver.menu->msg_force = false;
|
||||
}
|
||||
else
|
||||
message_queue = driver.current_msg;
|
||||
|
||||
glui_render_messagebox(message_queue);
|
||||
#endif
|
||||
|
||||
if (driver.menu->keyboard.display)
|
||||
{
|
||||
char msg[PATH_MAX];
|
||||
const char *str = *driver.menu->keyboard.buffer;
|
||||
if (!str)
|
||||
str = "";
|
||||
snprintf(msg, sizeof(msg), "%s\n%s", driver.menu->keyboard.label, str);
|
||||
glui_render_messagebox(msg);
|
||||
}
|
||||
|
||||
gl_set_viewport(gl, gl->win_width, gl->win_height, false, false);
|
||||
}
|
||||
|
||||
static void glui_init_core_info(void *data)
|
||||
{
|
||||
(void)data;
|
||||
|
||||
core_info_list_free(g_extern.core_info);
|
||||
g_extern.core_info = NULL;
|
||||
if (*g_settings.libretro_directory)
|
||||
{
|
||||
g_extern.core_info = core_info_list_new(g_settings.libretro_directory);
|
||||
}
|
||||
}
|
||||
|
||||
static void *glui_init(void)
|
||||
{
|
||||
menu_handle_t *menu = (menu_handle_t*)calloc(1, sizeof(*menu));
|
||||
gl_t *gl = (gl_t*)driver.video_data;
|
||||
|
||||
if (!menu || !gl)
|
||||
return NULL;
|
||||
|
||||
glui_init_core_info(menu);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
static void glui_free(void *data)
|
||||
{
|
||||
menu_handle_t *menu = (menu_handle_t*)data;
|
||||
|
||||
if (menu->alloc_font)
|
||||
free((uint8_t*)menu->font);
|
||||
|
||||
if (g_extern.core_info)
|
||||
core_info_list_free(g_extern.core_info);
|
||||
g_extern.core_info = NULL;
|
||||
}
|
||||
|
||||
static int glui_input_postprocess(uint64_t old_state)
|
||||
{
|
||||
(void)old_state;
|
||||
|
||||
if ((driver.menu->trigger_state & (1ULL << RARCH_MENU_TOGGLE)) &&
|
||||
g_extern.main_is_init &&
|
||||
!g_extern.libretro_dummy)
|
||||
{
|
||||
rarch_main_command(RARCH_CMD_RESUME);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void glui_context_reset(void *data)
|
||||
{
|
||||
char mediapath[256], themepath[256], iconpath[256];
|
||||
menu_handle_t *menu = (menu_handle_t*)data;
|
||||
gl_t *gl = (gl_t*)driver.video_data;
|
||||
|
||||
driver.gfx_use_rgba = true;
|
||||
|
||||
if (!menu)
|
||||
return;
|
||||
|
||||
gl_font_init_first(&font_driver, (void*)&menu->font, gl, g_settings.video.font_path,
|
||||
g_settings.video.font_size);
|
||||
}
|
||||
|
||||
menu_ctx_driver_t menu_ctx_glui = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
glui_frame,
|
||||
glui_init,
|
||||
glui_free,
|
||||
glui_context_reset,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
glui_input_postprocess,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
glui_init_core_info,
|
||||
&menu_ctx_backend_common,
|
||||
"glui",
|
||||
};
|
|
@ -482,7 +482,7 @@ static void lakka_draw_subitems(int i, int j)
|
|||
if (!subitem)
|
||||
continue;
|
||||
|
||||
if (k == 0 && g_extern.main_is_init
|
||||
if (i && k == 0 && g_extern.main_is_init
|
||||
&& !g_extern.libretro_dummy
|
||||
&& strcmp(g_extern.fullpath, active_item->rom) == 0)
|
||||
{
|
||||
|
@ -500,7 +500,7 @@ static void lakka_draw_subitems(int i, int j)
|
|||
1,
|
||||
subitem->alpha);
|
||||
}
|
||||
else if(k == 0 ||
|
||||
else if (k == 0 ||
|
||||
menu_active_category == 0 ||
|
||||
(g_extern.main_is_init &&
|
||||
!g_extern.libretro_dummy &&
|
||||
|
@ -519,8 +519,32 @@ static void lakka_draw_subitems(int i, int j)
|
|||
margin_top + subitem->y + label_margin_top,
|
||||
1,
|
||||
subitem->alpha);
|
||||
|
||||
if (i && (k == 1 || k == 2))
|
||||
{
|
||||
char slot[256];
|
||||
if (g_settings.state_slot == -1)
|
||||
snprintf(slot, sizeof(slot), "%d (auto)", g_settings.state_slot);
|
||||
else
|
||||
snprintf(slot, sizeof(slot), "%d", g_settings.state_slot);
|
||||
lakka_draw_text(slot,
|
||||
margin_left + hspacing * (i+2.25) +
|
||||
all_categories_x + label_margin_left + 400,
|
||||
margin_top + subitem->y + label_margin_top,
|
||||
1,
|
||||
subitem->alpha);
|
||||
}
|
||||
}
|
||||
|
||||
if (subitem->value)
|
||||
{
|
||||
lakka_draw_text(subitem->value,
|
||||
margin_left + hspacing * (i+2.25) +
|
||||
all_categories_x + label_margin_left + 400,
|
||||
margin_top + subitem->y + label_margin_top,
|
||||
1,
|
||||
subitem->alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -532,6 +556,8 @@ static void lakka_draw_items(int i)
|
|||
&categories[menu_active_category];
|
||||
menu_item_t *active_item = (menu_item_t*)
|
||||
&active_category->items[active_category->active_item];
|
||||
|
||||
(void)active_item;
|
||||
|
||||
for(j = 0; j < category->num_items; j++)
|
||||
{
|
||||
|
@ -653,6 +679,8 @@ static void lakka_context_destroy(void *data)
|
|||
int i, j, k;
|
||||
gl_t *gl = (gl_t*)driver.video_data;
|
||||
|
||||
(void)gl;
|
||||
|
||||
for (i = 0; i < TEXTURE_LAST; i++)
|
||||
glDeleteTextures(1, &textures[i].id);
|
||||
|
||||
|
@ -711,6 +739,7 @@ void lakka_init_settings(void)
|
|||
calloc(category->num_items, sizeof(menu_item_t));
|
||||
|
||||
int j, k, jj, kk;
|
||||
jj = 0;
|
||||
for (j = 0; j <= 512; j++)
|
||||
{
|
||||
rarch_setting_t group = (rarch_setting_t)setting_data[j];
|
||||
|
@ -730,30 +759,33 @@ void lakka_init_settings(void)
|
|||
vspacing*(under_item_offset+jj) : vspacing * active_item_factor;
|
||||
item->active_subitem = 0;
|
||||
item->num_subitems = 0;
|
||||
item->subitems = NULL;
|
||||
|
||||
kk = 0;
|
||||
for (k = 0; k <= 512; k++)
|
||||
{
|
||||
rarch_setting_t subgroup = (rarch_setting_t)setting_data[k];
|
||||
rarch_setting_t setting = (rarch_setting_t)setting_data[k];
|
||||
|
||||
if (subgroup.type == ST_SUB_GROUP) // TODO filter on parent
|
||||
if (setting.type != ST_SUB_GROUP && setting.group == group.name)
|
||||
{
|
||||
item->num_subitems++;
|
||||
#if 0
|
||||
|
||||
item->subitems = (menu_subitem_t*)
|
||||
realloc(item->subitems, item->num_subitems * sizeof(menu_subitem_t));
|
||||
#endif
|
||||
item->subitems = (menu_subitem_t*)
|
||||
calloc(item->num_subitems, sizeof(menu_subitem_t));
|
||||
realloc(item->subitems,
|
||||
item->num_subitems * sizeof(menu_subitem_t));
|
||||
|
||||
menu_subitem_t *subitem = (menu_subitem_t*)&item->subitems[kk];
|
||||
|
||||
strlcpy(subitem->name, subgroup.name, sizeof(subitem->name));
|
||||
strlcpy(subitem->name, setting.short_description,
|
||||
sizeof(subitem->name));
|
||||
subitem->alpha = kk ? 1.0 : 0.5;
|
||||
subitem->zoom = kk ? i_active_zoom : i_passive_zoom;
|
||||
subitem->y = kk ? vspacing * (kk + under_item_offset)
|
||||
: vspacing * active_item_factor;
|
||||
|
||||
setting_data_get_string_representation(&setting, subitem->value,
|
||||
sizeof(subitem->value));
|
||||
|
||||
kk++;
|
||||
}
|
||||
}
|
||||
|
@ -925,10 +957,72 @@ static void lakka_context_reset(void *data)
|
|||
}
|
||||
}
|
||||
|
||||
static void lakka_init_subitems(menu_item_t *item)
|
||||
{
|
||||
int k;
|
||||
for (k = 0; k < item->num_subitems; k++)
|
||||
{
|
||||
menu_subitem_t *subitem = (menu_subitem_t*)&item->subitems[k];
|
||||
|
||||
if (!subitem)
|
||||
continue;
|
||||
|
||||
switch (k)
|
||||
{
|
||||
case 0:
|
||||
strlcpy(subitem->name, "Run", sizeof(subitem->name));
|
||||
break;
|
||||
case 1:
|
||||
strlcpy(subitem->name, "Save State", sizeof(subitem->name));
|
||||
break;
|
||||
case 2:
|
||||
strlcpy(subitem->name, "Load State", sizeof(subitem->name));
|
||||
break;
|
||||
case 3:
|
||||
strlcpy(subitem->name, "Take Screenshot", sizeof(subitem->name));
|
||||
break;
|
||||
case 4:
|
||||
strlcpy(subitem->name, "Reset", sizeof(subitem->name));
|
||||
break;
|
||||
}
|
||||
subitem->alpha = 0;
|
||||
subitem->zoom = k ? i_passive_zoom : i_active_zoom;
|
||||
subitem->y = k ? vspacing * (k+under_item_offset) :
|
||||
vspacing * active_item_factor;
|
||||
}
|
||||
}
|
||||
|
||||
static void lakka_init_item(int i, int j, menu_category_t *category,
|
||||
core_info_t *info, struct string_list *list, const char * name)
|
||||
{
|
||||
menu_item_t *item;
|
||||
|
||||
int n = category->num_items;
|
||||
|
||||
category->num_items++;
|
||||
category->items = (menu_item_t*)realloc(category->items,
|
||||
category->num_items * sizeof(menu_item_t));
|
||||
item = (menu_item_t*)&category->items[n];
|
||||
|
||||
strlcpy(item->name, name, sizeof(item->name));
|
||||
if (list != NULL)
|
||||
strlcpy(item->rom, list->elems[j].data, sizeof(item->rom));
|
||||
item->alpha = i != menu_active_category ? 0 : n ? 0.5 : 1;
|
||||
item->zoom = n ? i_passive_zoom : i_active_zoom;
|
||||
item->y = n ? vspacing*(under_item_offset+n) :
|
||||
vspacing*active_item_factor;
|
||||
item->active_subitem = 0;
|
||||
item->num_subitems = 5;
|
||||
item->subitems = (menu_subitem_t*)
|
||||
calloc(item->num_subitems, sizeof(menu_subitem_t));
|
||||
|
||||
lakka_init_subitems(item);
|
||||
}
|
||||
|
||||
static void lakka_init_items(int i, menu_category_t *category,
|
||||
core_info_t *info, const char* path)
|
||||
{
|
||||
int num_items, j, n, k;
|
||||
int num_items, j;
|
||||
struct string_list *list;
|
||||
|
||||
if (category == NULL || info == NULL)
|
||||
|
@ -946,57 +1040,8 @@ static void lakka_init_items(int i, menu_category_t *category,
|
|||
lakka_init_items(i, category, info, list->elems[j].data);
|
||||
else
|
||||
{
|
||||
menu_item_t *item;
|
||||
|
||||
n = category->num_items;
|
||||
|
||||
category->num_items++;
|
||||
category->items = (menu_item_t*)realloc(category->items,
|
||||
category->num_items * sizeof(menu_item_t));
|
||||
item = (menu_item_t*)&category->items[n];
|
||||
|
||||
strlcpy(item->name, path_basename(list->elems[j].data),
|
||||
sizeof(item->name));
|
||||
strlcpy(item->rom, list->elems[j].data, sizeof(item->rom));
|
||||
item->alpha = i != menu_active_category ? 0 : n ? 0.5 : 1;
|
||||
item->zoom = n ? i_passive_zoom : i_active_zoom;
|
||||
item->y = n ? vspacing*(under_item_offset+n) :
|
||||
vspacing*active_item_factor;
|
||||
item->active_subitem = 0;
|
||||
item->num_subitems = 5;
|
||||
item->subitems = (menu_subitem_t*)
|
||||
calloc(item->num_subitems, sizeof(menu_subitem_t));
|
||||
|
||||
for (k = 0; k < item->num_subitems; k++)
|
||||
{
|
||||
menu_subitem_t *subitem = (menu_subitem_t*)&item->subitems[k];
|
||||
|
||||
if (!subitem)
|
||||
continue;
|
||||
|
||||
switch (k)
|
||||
{
|
||||
case 0:
|
||||
strlcpy(subitem->name, "Run", sizeof(subitem->name));
|
||||
break;
|
||||
case 1:
|
||||
strlcpy(subitem->name, "Save State", sizeof(subitem->name));
|
||||
break;
|
||||
case 2:
|
||||
strlcpy(subitem->name, "Load State", sizeof(subitem->name));
|
||||
break;
|
||||
case 3:
|
||||
strlcpy(subitem->name, "Take Screenshot", sizeof(subitem->name));
|
||||
break;
|
||||
case 4:
|
||||
strlcpy(subitem->name, "Reset", sizeof(subitem->name));
|
||||
break;
|
||||
}
|
||||
subitem->alpha = 0;
|
||||
subitem->zoom = k ? i_passive_zoom : i_active_zoom;
|
||||
subitem->y = k ? vspacing * (k+under_item_offset) :
|
||||
vspacing * active_item_factor;
|
||||
}
|
||||
lakka_init_item(i, j, category, info, list,
|
||||
path_basename(list->elems[j].data));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1028,7 +1073,7 @@ static int lakka_input_postprocess(uint64_t old_state)
|
|||
}
|
||||
|
||||
if (! global_alpha)
|
||||
add_tween(DELAY, 1.0, &global_alpha, &inOutQuad, NULL);
|
||||
add_tween(LAKKA_DELAY, 1.0, &global_alpha, &inOutQuad, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1095,13 +1140,17 @@ static void *lakka_init(void)
|
|||
category->items = (menu_item_t*)
|
||||
calloc(category->num_items + 1, sizeof(menu_item_t));
|
||||
|
||||
lakka_init_items(i, category, info, g_settings.content_directory);
|
||||
if (! info->supports_no_game)
|
||||
lakka_init_items(i, category, info, g_settings.content_directory);
|
||||
else
|
||||
lakka_init_item(i, 0, category, info, NULL,
|
||||
info->display_name);
|
||||
}
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
const menu_ctx_driver_t menu_ctx_lakka = {
|
||||
menu_ctx_driver_t menu_ctx_lakka = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
|
|
@ -21,8 +21,11 @@
|
|||
#include "../../../gfx/gl_common.h"
|
||||
#include "../../../gfx/fonts/fonts.h"
|
||||
|
||||
#define THEME "flatui" // flatui or monochrome themes are available
|
||||
#define DELAY 0.02
|
||||
#define THEME "monochrome" // flatui or monochrome themes are available
|
||||
|
||||
#ifndef LAKKA_DELAY
|
||||
#define LAKKA_DELAY 0.02
|
||||
#endif
|
||||
|
||||
extern int depth;
|
||||
extern int num_categories;
|
||||
|
@ -48,6 +51,7 @@ typedef struct
|
|||
float alpha;
|
||||
float zoom;
|
||||
float y;
|
||||
char value[256];
|
||||
} menu_subitem_t;
|
||||
|
||||
typedef struct
|
||||
|
|
|
@ -344,73 +344,29 @@ static void rgui_render(void)
|
|||
|
||||
for (i = begin; i < end; i++, y += FONT_HEIGHT_STRIDE)
|
||||
{
|
||||
char message[256], type_str[256];
|
||||
const char *path = NULL;
|
||||
const char *entry_label = NULL;
|
||||
unsigned type = 0;
|
||||
char message[PATH_MAX], type_str[PATH_MAX],
|
||||
entry_title_buf[PATH_MAX], type_str_buf[PATH_MAX],
|
||||
path_buf[PATH_MAX];
|
||||
const char *path = NULL, *entry_label = NULL;
|
||||
unsigned type = 0, w = 0;
|
||||
bool selected = false;
|
||||
|
||||
file_list_get_at_offset(driver.menu->selection_buf, i, &path,
|
||||
&entry_label, &type);
|
||||
rarch_setting_t *setting = (rarch_setting_t*)setting_data_find_setting(
|
||||
setting_data_get_list(),
|
||||
driver.menu->selection_buf->list[i].label);
|
||||
|
||||
unsigned w = 19;
|
||||
(void)setting;
|
||||
|
||||
if (!strcmp(label, "performance_counters"))
|
||||
w = 28;
|
||||
disp_set_label(&w, type, i, label,
|
||||
type_str, sizeof(type_str),
|
||||
entry_label, path,
|
||||
path_buf, sizeof(path_buf));
|
||||
|
||||
if (type == MENU_FILE_CORE)
|
||||
{
|
||||
strlcpy(type_str, "(CORE)", sizeof(type_str));
|
||||
file_list_get_alt_at_offset(driver.menu->selection_buf, i, &path);
|
||||
w = 6;
|
||||
}
|
||||
else if (type == MENU_FILE_PLAIN)
|
||||
{
|
||||
strlcpy(type_str, "(FILE)", sizeof(type_str));
|
||||
w = 6;
|
||||
}
|
||||
else if (type == MENU_FILE_USE_DIRECTORY)
|
||||
{
|
||||
*type_str = '\0';
|
||||
w = 0;
|
||||
}
|
||||
else if (type == MENU_FILE_DIRECTORY)
|
||||
{
|
||||
strlcpy(type_str, "(DIR)", sizeof(type_str));
|
||||
type = MENU_FILE_DIRECTORY;
|
||||
w = 5;
|
||||
}
|
||||
else if (type == MENU_FILE_CARCHIVE)
|
||||
{
|
||||
strlcpy(type_str, "(COMP)", sizeof(type_str));
|
||||
w = 6;
|
||||
}
|
||||
else if (type == MENU_FILE_IN_CARCHIVE)
|
||||
{
|
||||
strlcpy(type_str, "(CFILE)", sizeof(type_str));
|
||||
w = 7;
|
||||
}
|
||||
else if (type >= MENU_SETTINGS_CORE_OPTION_START)
|
||||
strlcpy(
|
||||
type_str,
|
||||
core_option_get_val(g_extern.system.core_options,
|
||||
type - MENU_SETTINGS_CORE_OPTION_START),
|
||||
sizeof(type_str));
|
||||
else if (type == MENU_FILE_SWITCH || type == MENU_FILE_LINEFEED_SWITCH)
|
||||
strlcpy(type_str, "...", sizeof(type_str));
|
||||
else if (driver.menu_ctx && driver.menu_ctx->backend &&
|
||||
driver.menu_ctx->backend->setting_set_label)
|
||||
driver.menu_ctx->backend->setting_set_label(type_str,
|
||||
sizeof(type_str), &w, type, label, entry_label, i);
|
||||
|
||||
char entry_title_buf[256];
|
||||
char type_str_buf[64];
|
||||
bool selected = i == driver.menu->selection_ptr;
|
||||
selected = (i == driver.menu->selection_ptr);
|
||||
|
||||
menu_ticker_line(entry_title_buf, RGUI_TERM_WIDTH - (w + 1 + 2),
|
||||
g_extern.frame_count / RGUI_TERM_START_X, path, selected);
|
||||
g_extern.frame_count / RGUI_TERM_START_X, path_buf, selected);
|
||||
menu_ticker_line(type_str_buf, w, g_extern.frame_count / RGUI_TERM_START_X,
|
||||
type_str, selected);
|
||||
|
||||
|
@ -513,7 +469,7 @@ void rgui_set_texture(void *data)
|
|||
menu_framebuf, false, menu->width, menu->height, 1.0f);
|
||||
}
|
||||
|
||||
const menu_ctx_driver_t menu_ctx_rgui = {
|
||||
menu_ctx_driver_t menu_ctx_rgui = {
|
||||
rgui_set_texture,
|
||||
rgui_render_messagebox,
|
||||
rgui_render,
|
||||
|
|
|
@ -217,53 +217,22 @@ static void rmenu_render(void)
|
|||
|
||||
for (i = begin; i < end; i++, j++)
|
||||
{
|
||||
const char *path = NULL;
|
||||
const char *entry_label = NULL;
|
||||
unsigned type = 0;
|
||||
char message[PATH_MAX], type_str[PATH_MAX],
|
||||
entry_title_buf[PATH_MAX], type_str_buf[PATH_MAX],
|
||||
path_buf[PATH_MAX];
|
||||
const char *path = NULL, *entry_label = NULL;
|
||||
unsigned type = 0, w = 0;
|
||||
bool selected = false;
|
||||
|
||||
file_list_get_at_offset(menu->selection_buf, i,
|
||||
&path, &entry_label, &type);
|
||||
char message[256];
|
||||
char type_str[256];
|
||||
|
||||
unsigned w = 19;
|
||||
|
||||
if (type == MENU_FILE_CORE)
|
||||
{
|
||||
strlcpy(type_str, "(CORE)", sizeof(type_str));
|
||||
file_list_get_alt_at_offset(driver.menu->selection_buf, i, &path);
|
||||
w = 6;
|
||||
}
|
||||
else if (type == MENU_FILE_PLAIN)
|
||||
{
|
||||
strlcpy(type_str, "(FILE)", sizeof(type_str));
|
||||
w = 6;
|
||||
}
|
||||
else if (type == MENU_FILE_USE_DIRECTORY)
|
||||
{
|
||||
*type_str = '\0';
|
||||
w = 0;
|
||||
}
|
||||
else if (type == MENU_FILE_DIRECTORY)
|
||||
{
|
||||
strlcpy(type_str, "(DIR)", sizeof(type_str));
|
||||
type = MENU_FILE_DIRECTORY;
|
||||
w = 5;
|
||||
}
|
||||
else if (type >= MENU_SETTINGS_CORE_OPTION_START)
|
||||
strlcpy(type_str,
|
||||
core_option_get_val(g_extern.system.core_options,
|
||||
type - MENU_SETTINGS_CORE_OPTION_START),
|
||||
sizeof(type_str));
|
||||
else if (type == MENU_FILE_SWITCH || type == MENU_FILE_LINEFEED_SWITCH)
|
||||
strlcpy(type_str, "...", sizeof(type_str));
|
||||
else if (driver.menu_ctx && driver.menu_ctx->backend
|
||||
&& driver.menu_ctx->backend->setting_set_label)
|
||||
driver.menu_ctx->backend->setting_set_label(type_str,
|
||||
sizeof(type_str), &w, type, label, entry_label, i);
|
||||
|
||||
char entry_title_buf[256];
|
||||
char type_str_buf[64];
|
||||
bool selected = i == menu->selection_ptr;
|
||||
disp_set_label(&w, type, i, label,
|
||||
type_str, sizeof(type_str),
|
||||
entry_label, path,
|
||||
path_buf, sizeof(path_buf));
|
||||
|
||||
selected = (i == driver.menu->selection_ptr);
|
||||
|
||||
menu_ticker_line(entry_title_buf, RMENU_TERM_WIDTH - (w + 1 + 2),
|
||||
g_extern.frame_count / 15, path, selected);
|
||||
|
@ -372,7 +341,7 @@ static int rmenu_input_postprocess(uint64_t old_state)
|
|||
return 0;
|
||||
}
|
||||
|
||||
const menu_ctx_driver_t menu_ctx_rmenu = {
|
||||
menu_ctx_driver_t menu_ctx_rmenu = {
|
||||
rmenu_set_texture,
|
||||
rmenu_render_messagebox,
|
||||
rmenu_render,
|
||||
|
|
|
@ -429,53 +429,22 @@ static void rmenu_xui_render(void)
|
|||
|
||||
for (i = begin; i < end; i++/*, y += FONT_HEIGHT_STRIDE */)
|
||||
{
|
||||
const char *path = NULL;
|
||||
const char *entry_label = NULL;
|
||||
unsigned type = 0;
|
||||
file_list_get_at_offset(driver.menu->selection_buf, i,
|
||||
&path, &entry_label, &type);
|
||||
char message[256];
|
||||
char type_str[256];
|
||||
char message[PATH_MAX], type_str[PATH_MAX],
|
||||
entry_title_buf[PATH_MAX], type_str_buf[PATH_MAX],
|
||||
path_buf[PATH_MAX];
|
||||
const char *path = NULL, *entry_label = NULL;
|
||||
unsigned type = 0, w = 0;
|
||||
bool selected = false;
|
||||
|
||||
unsigned w = 19;
|
||||
file_list_get_at_offset(driver.menu->selection_buf, i, &path,
|
||||
&entry_label, &type);
|
||||
|
||||
if (type == MENU_FILE_CORE)
|
||||
{
|
||||
strlcpy(type_str, "(CORE)", sizeof(type_str));
|
||||
file_list_get_alt_at_offset(driver.menu->selection_buf, i, &path);
|
||||
w = 6;
|
||||
}
|
||||
else if (type == MENU_FILE_PLAIN)
|
||||
{
|
||||
strlcpy(type_str, "(FILE)", sizeof(type_str));
|
||||
w = 6;
|
||||
}
|
||||
else if (type == MENU_FILE_USE_DIRECTORY)
|
||||
{
|
||||
*type_str = '\0';
|
||||
w = 0;
|
||||
}
|
||||
else if (type == MENU_FILE_DIRECTORY)
|
||||
{
|
||||
strlcpy(type_str, "(DIR)", sizeof(type_str));
|
||||
type = MENU_FILE_DIRECTORY;
|
||||
w = 5;
|
||||
}
|
||||
else if (type >= MENU_SETTINGS_CORE_OPTION_START)
|
||||
strlcpy(type_str,
|
||||
core_option_get_val(g_extern.system.core_options,
|
||||
type - MENU_SETTINGS_CORE_OPTION_START),
|
||||
sizeof(type_str));
|
||||
else if (type == MENU_FILE_SWITCH || type == MENU_FILE_LINEFEED_SWITCH)
|
||||
strlcpy(type_str, "...", sizeof(type_str));
|
||||
else if (driver.menu_ctx && driver.menu_ctx->backend
|
||||
&& driver.menu_ctx->backend->setting_set_label)
|
||||
driver.menu_ctx->backend->setting_set_label(type_str,
|
||||
sizeof(type_str), &w, type, label, entry_label, i);
|
||||
disp_set_label(&w, type, i, label,
|
||||
type_str, sizeof(type_str),
|
||||
entry_label, path,
|
||||
path_buf, sizeof(path_buf));
|
||||
|
||||
char entry_title_buf[256];
|
||||
char type_str_buf[64];
|
||||
bool selected = i == driver.menu->selection_ptr;
|
||||
selected = (i == driver.menu->selection_ptr);
|
||||
|
||||
#if 0
|
||||
if ((type == MENU_FILE_PLAIN || type == MENU_FILE_DIRECTORY))
|
||||
|
@ -562,7 +531,7 @@ static void rmenu_xui_list_set_selection(void *data)
|
|||
XuiListSetCurSel(m_menulist, file_list_get_directory_ptr(list));
|
||||
}
|
||||
|
||||
const menu_ctx_driver_t menu_ctx_rmenu_xui = {
|
||||
menu_ctx_driver_t menu_ctx_rmenu_xui = {
|
||||
NULL,
|
||||
rmenu_xui_render_messagebox,
|
||||
rmenu_xui_render,
|
||||
|
|
|
@ -72,6 +72,8 @@ static void get_title(const char *label, const char *dir,
|
|||
strlcpy(title, "INFO", sizeof_title);
|
||||
else if (!strcmp(label, "input_overlay"))
|
||||
snprintf(title, sizeof_title, "OVERLAY %s", dir);
|
||||
else if (!strcmp(label, "video_font_path"))
|
||||
snprintf(title, sizeof_title, "FONT %s", dir);
|
||||
else if (!strcmp(label, "video_filter"))
|
||||
snprintf(title, sizeof_title, "FILTER %s", dir);
|
||||
else if (!strcmp(label, "audio_dsp_plugin"))
|
||||
|
@ -124,4 +126,95 @@ static void get_title(const char *label, const char *dir,
|
|||
}
|
||||
}
|
||||
|
||||
static void disp_set_label(unsigned *w, unsigned type, unsigned i,
|
||||
const char *label,
|
||||
char *type_str, size_t type_str_size,
|
||||
const char *entry_label,
|
||||
const char *path,
|
||||
char *path_buf, size_t path_buf_size)
|
||||
{
|
||||
*w = 19;
|
||||
|
||||
if (!strcmp(label, "performance_counters"))
|
||||
*w = 28;
|
||||
|
||||
if (type == MENU_FILE_CORE)
|
||||
{
|
||||
strlcpy(type_str, "(CORE)", type_str_size);
|
||||
file_list_get_alt_at_offset(driver.menu->selection_buf, i, &path);
|
||||
*w = 6;
|
||||
}
|
||||
else if (type == MENU_FILE_PLAIN)
|
||||
{
|
||||
strlcpy(type_str, "(FILE)", type_str_size);
|
||||
*w = 6;
|
||||
}
|
||||
else if (type == MENU_FILE_USE_DIRECTORY)
|
||||
{
|
||||
*type_str = '\0';
|
||||
*w = 0;
|
||||
}
|
||||
else if (type == MENU_FILE_DIRECTORY)
|
||||
{
|
||||
strlcpy(type_str, "(DIR)", type_str_size);
|
||||
*w = 5;
|
||||
}
|
||||
else if (type == MENU_FILE_CARCHIVE)
|
||||
{
|
||||
strlcpy(type_str, "(COMP)", type_str_size);
|
||||
*w = 6;
|
||||
}
|
||||
else if (type == MENU_FILE_IN_CARCHIVE)
|
||||
{
|
||||
strlcpy(type_str, "(CFILE)", type_str_size);
|
||||
*w = 7;
|
||||
}
|
||||
else if (type == MENU_FILE_FONT)
|
||||
{
|
||||
strlcpy(type_str, "(FONT)", type_str_size);
|
||||
*w = 7;
|
||||
}
|
||||
else if (type == MENU_FILE_SHADER_PRESET)
|
||||
{
|
||||
strlcpy(type_str, "(PRESET)", type_str_size);
|
||||
*w = 8;
|
||||
}
|
||||
else if (type == MENU_FILE_SHADER)
|
||||
{
|
||||
strlcpy(type_str, "(SHADER)", type_str_size);
|
||||
*w = 8;
|
||||
}
|
||||
else if (
|
||||
type == MENU_FILE_VIDEOFILTER ||
|
||||
type == MENU_FILE_AUDIOFILTER)
|
||||
{
|
||||
strlcpy(type_str, "(FILTER)", type_str_size);
|
||||
*w = 8;
|
||||
}
|
||||
else if (type == MENU_FILE_CONFIG)
|
||||
{
|
||||
strlcpy(type_str, "(CONFIG)", type_str_size);
|
||||
*w = 8;
|
||||
}
|
||||
else if (type == MENU_FILE_OVERLAY)
|
||||
{
|
||||
strlcpy(type_str, "(OVERLAY)", type_str_size);
|
||||
*w = 9;
|
||||
}
|
||||
else if (type >= MENU_SETTINGS_CORE_OPTION_START)
|
||||
strlcpy(
|
||||
type_str,
|
||||
core_option_get_val(g_extern.system.core_options,
|
||||
type - MENU_SETTINGS_CORE_OPTION_START),
|
||||
type_str_size);
|
||||
else if (type == MENU_FILE_SWITCH || type == MENU_FILE_LINEFEED_SWITCH)
|
||||
strlcpy(type_str, "...", type_str_size);
|
||||
else if (driver.menu_ctx && driver.menu_ctx->backend &&
|
||||
driver.menu_ctx->backend->setting_set_label)
|
||||
driver.menu_ctx->backend->setting_set_label(type_str,
|
||||
type_str_size, w, type, label, entry_label, i);
|
||||
|
||||
strlcpy(path_buf, path, path_buf_size);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -59,11 +59,20 @@ typedef enum
|
|||
MENU_FILE_NONE,
|
||||
MENU_FILE_PLAIN,
|
||||
MENU_FILE_DIRECTORY,
|
||||
MENU_FILE_PATH,
|
||||
MENU_FILE_DEVICE,
|
||||
MENU_FILE_DRIVER,
|
||||
MENU_FILE_LINEFEED,
|
||||
MENU_FILE_LINEFEED_SWITCH,
|
||||
MENU_FILE_CORE,
|
||||
MENU_FILE_PLAYLIST_ENTRY,
|
||||
MENU_FILE_SHADER_PRESET,
|
||||
MENU_FILE_SHADER,
|
||||
MENU_FILE_VIDEOFILTER,
|
||||
MENU_FILE_AUDIOFILTER,
|
||||
MENU_FILE_OVERLAY,
|
||||
MENU_FILE_FONT,
|
||||
MENU_FILE_CONFIG,
|
||||
MENU_FILE_USE_DIRECTORY,
|
||||
MENU_FILE_SWITCH,
|
||||
MENU_FILE_CARCHIVE,
|
||||
|
|
|
@ -151,6 +151,10 @@ static int setting_set_flags(rarch_setting_t *setting)
|
|||
return MENU_FILE_LINEFEED;
|
||||
if (setting->flags & SD_FLAG_PUSH_ACTION)
|
||||
return MENU_FILE_SWITCH;
|
||||
if (setting->flags & SD_FLAG_IS_DRIVER)
|
||||
return MENU_FILE_DRIVER;
|
||||
if (setting->type == ST_PATH)
|
||||
return MENU_FILE_PATH;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -539,10 +543,7 @@ int menu_parse_check(const char *label, unsigned menu_type)
|
|||
menu_type == MENU_FILE_CARCHIVE ||
|
||||
menu_common_type_is(label, menu_type) == MENU_SETTINGS_SHADER_OPTIONS ||
|
||||
menu_common_type_is(label, menu_type) == MENU_FILE_DIRECTORY ||
|
||||
!strcmp(label, "input_overlay") ||
|
||||
!strcmp(label, "game_history_path") ||
|
||||
!strcmp(label, "video_filter") ||
|
||||
!strcmp(label, "audio_dsp_plugin") ||
|
||||
menu_type == MENU_FILE_PATH ||
|
||||
!strcmp(label, "core_list") ||
|
||||
!strcmp(label, "configurations") ||
|
||||
!strcmp(label, "disk_image_append"))))
|
||||
|
@ -553,10 +554,12 @@ int menu_parse_check(const char *label, unsigned menu_type)
|
|||
int menu_parse_and_resolve(file_list_t *list, file_list_t *menu_list)
|
||||
{
|
||||
size_t i, list_size;
|
||||
unsigned menu_type = 0;
|
||||
unsigned menu_type = 0, default_type_plain = MENU_FILE_PLAIN;
|
||||
|
||||
const char *dir = NULL;
|
||||
const char *label = NULL;
|
||||
const char *exts = NULL;
|
||||
char ext_buf[PATH_MAX];
|
||||
|
||||
file_list_get_last(menu_list, &dir, &label, &menu_type);
|
||||
|
||||
|
@ -664,24 +667,44 @@ int menu_parse_and_resolve(file_list_t *list, file_list_t *menu_list)
|
|||
LWP_MutexUnlock(gx_device_mutex);
|
||||
#endif
|
||||
|
||||
const char *exts;
|
||||
char ext_buf[1024];
|
||||
|
||||
//RARCH_LOG("LABEL: %s\n", label);
|
||||
if (!strcmp(label, "core_list"))
|
||||
exts = EXT_EXECUTABLES;
|
||||
else if (!strcmp(label, "configurations"))
|
||||
{
|
||||
exts = "cfg";
|
||||
default_type_plain = MENU_FILE_CONFIG;
|
||||
}
|
||||
else if (!strcmp(label, "video_shader_preset"))
|
||||
{
|
||||
exts = "cgp|glslp";
|
||||
default_type_plain = MENU_FILE_SHADER_PRESET;
|
||||
}
|
||||
else if (!strcmp(label, "video_shader_pass"))
|
||||
{
|
||||
exts = "cg|glsl";
|
||||
default_type_plain = MENU_FILE_SHADER;
|
||||
}
|
||||
else if (!strcmp(label, "video_filter"))
|
||||
{
|
||||
exts = "filt";
|
||||
default_type_plain = MENU_FILE_VIDEOFILTER;
|
||||
}
|
||||
else if (!strcmp(label, "audio_dsp_plugin"))
|
||||
{
|
||||
exts = "dsp";
|
||||
default_type_plain = MENU_FILE_AUDIOFILTER;
|
||||
}
|
||||
else if (!strcmp(label, "input_overlay"))
|
||||
{
|
||||
exts = "cfg";
|
||||
default_type_plain = MENU_FILE_OVERLAY;
|
||||
}
|
||||
else if (!strcmp(label, "video_font_path"))
|
||||
{
|
||||
exts = "ttf";
|
||||
default_type_plain = MENU_FILE_FONT;
|
||||
}
|
||||
else if (!strcmp(label, "game_history_path"))
|
||||
exts = "cfg";
|
||||
else if (menu_common_type_is(label, menu_type) == MENU_FILE_DIRECTORY)
|
||||
|
@ -738,7 +761,7 @@ int menu_parse_and_resolve(file_list_t *list, file_list_t *menu_list)
|
|||
break;
|
||||
case RARCH_PLAIN_FILE:
|
||||
default:
|
||||
file_type = MENU_FILE_PLAIN;
|
||||
file_type = (menu_file_type_t)default_type_plain;
|
||||
break;
|
||||
}
|
||||
bool is_dir = (file_type == MENU_FILE_DIRECTORY);
|
||||
|
@ -808,8 +831,7 @@ int menu_parse_and_resolve(file_list_t *list, file_list_t *menu_list)
|
|||
}
|
||||
|
||||
driver.menu->scroll_indices_size = 0;
|
||||
if (strcmp(label, "history_list") != 0)
|
||||
menu_build_scroll_indices(list);
|
||||
menu_build_scroll_indices(list);
|
||||
|
||||
entries_refresh(list);
|
||||
|
||||
|
|
|
@ -320,7 +320,8 @@ JNIEnv *jni_thread_getenv(void)
|
|||
{
|
||||
JNIEnv *env;
|
||||
struct android_app* android_app = (struct android_app*)g_android;
|
||||
int status = (*android_app->activity->vm)->AttachCurrentThread(android_app->activity->vm, &env, 0);
|
||||
int status = (*android_app->activity->vm)->
|
||||
AttachCurrentThread(android_app->activity->vm, &env, 0);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
|
@ -342,7 +343,8 @@ static void jni_thread_destruct(void *value)
|
|||
return;
|
||||
|
||||
if (android_app)
|
||||
(*android_app->activity->vm)->DetachCurrentThread(android_app->activity->vm);
|
||||
(*android_app->activity->vm)->
|
||||
DetachCurrentThread(android_app->activity->vm);
|
||||
pthread_setspecific(thread_key, NULL);
|
||||
}
|
||||
|
||||
|
@ -490,7 +492,8 @@ static void frontend_android_get_environment_settings(int *argc,
|
|||
args->state_path = NULL;
|
||||
}
|
||||
|
||||
CALL_OBJ_METHOD(env, obj, android_app->activity->clazz, android_app->getIntent);
|
||||
CALL_OBJ_METHOD(env, obj, android_app->activity->clazz,
|
||||
android_app->getIntent);
|
||||
RARCH_LOG("Checking arguments passed from intent ...\n");
|
||||
|
||||
// Config file
|
||||
|
|
|
@ -151,7 +151,8 @@ static void frontend_ps3_get_environment_settings(int *argc, char *argv[],
|
|||
{
|
||||
RARCH_LOG("cellGameBootCheck() OK.\n");
|
||||
RARCH_LOG("Directory name: [%s].\n", dirName);
|
||||
RARCH_LOG(" HDD Free Size (in KB) = [%d] Size (in KB) = [%d] System Size (in KB) = [%d].\n", size.hddFreeSizeKB, size.sizeKB, size.sysSizeKB);
|
||||
RARCH_LOG(" HDD Free Size (in KB) = [%d] Size (in KB) = [%d] System Size (in KB) = [%d].\n",
|
||||
size.hddFreeSizeKB, size.sizeKB, size.sysSizeKB);
|
||||
|
||||
switch(get_type)
|
||||
{
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
#include "command.h"
|
||||
#endif
|
||||
|
||||
#include "audio/resampler.h"
|
||||
#include "audio/resamplers/resampler.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -811,7 +811,8 @@ int rarch_main(int argc, char *argv[]);
|
|||
|
||||
bool rarch_replace_config(const char *path);
|
||||
|
||||
void rarch_main_init_wrap(const struct rarch_main_wrap *args, int *argc, char **argv);
|
||||
void rarch_main_init_wrap(const struct rarch_main_wrap *args,
|
||||
int *argc, char **argv);
|
||||
|
||||
int rarch_main_init(int argc, char *argv[]);
|
||||
void rarch_main_set_state(unsigned action);
|
||||
|
|
489
gfx/d3d9/d3d.cpp
489
gfx/d3d9/d3d.cpp
|
@ -39,6 +39,8 @@ static bool d3d_process_shader(d3d_video_t *d3d);
|
|||
static bool d3d_init_multipass(d3d_video_t *d3d);
|
||||
static void d3d_deinit_chain(d3d_video_t *d3d);
|
||||
|
||||
#include "d3d_shared.h"
|
||||
|
||||
#ifdef HAVE_MONITOR
|
||||
#define IDI_ICON 1
|
||||
#define MAX_MONITORS 9
|
||||
|
@ -370,241 +372,18 @@ static bool d3d_init_luts(d3d_video_t *d3d)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void d3d_deinit_chain(d3d_video_t *d3d)
|
||||
{
|
||||
if (d3d->chain)
|
||||
delete (renderchain_t *)d3d->chain;
|
||||
d3d->chain = NULL;
|
||||
}
|
||||
|
||||
static void d3d_deinitialize(void *data)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
if (d3d->font_ctx && d3d->font_ctx->deinit)
|
||||
d3d->font_ctx->deinit(d3d);
|
||||
d3d->font_ctx = NULL;
|
||||
d3d_deinit_chain(d3d);
|
||||
#ifdef HAVE_SHADERS
|
||||
d3d_deinit_shader(d3d);
|
||||
#endif
|
||||
|
||||
d3d->needs_restore = false;
|
||||
}
|
||||
|
||||
#ifdef HAVE_WINDOW
|
||||
extern LRESULT CALLBACK WindowProc(HWND hWnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam);
|
||||
#endif
|
||||
|
||||
static bool d3d_init_base(void *data, const video_info_t *info)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
D3DPRESENT_PARAMETERS d3dpp;
|
||||
d3d_make_d3dpp(d3d, info, &d3dpp);
|
||||
|
||||
d3d->g_pD3D = D3DCREATE_CTX(D3D_SDK_VERSION);
|
||||
if (!d3d->g_pD3D)
|
||||
{
|
||||
RARCH_ERR("Failed to create D3D interface!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FAILED(d3d->d3d_err = d3d->g_pD3D->CreateDevice(
|
||||
d3d->cur_mon_id,
|
||||
D3DDEVTYPE_HAL,
|
||||
d3d->hWnd,
|
||||
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
||||
&d3dpp,
|
||||
&d3d->dev)))
|
||||
{
|
||||
RARCH_WARN("[D3D]: Failed to init device with hardware vertex processing (code: 0x%x). Trying to fall back to software vertex processing.\n",
|
||||
(unsigned)d3d->d3d_err);
|
||||
|
||||
if (FAILED(d3d->d3d_err = d3d->g_pD3D->CreateDevice(
|
||||
d3d->cur_mon_id,
|
||||
D3DDEVTYPE_HAL,
|
||||
d3d->hWnd,
|
||||
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
|
||||
&d3dpp,
|
||||
&d3d->dev)))
|
||||
{
|
||||
RARCH_ERR("Failed to initialize device.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void d3d_calculate_rect(d3d_video_t *d3d, unsigned width,
|
||||
unsigned height, bool keep, float desired_aspect);
|
||||
|
||||
static bool d3d_initialize(void *data, const video_info_t *info)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
bool ret = true;
|
||||
if (!d3d->g_pD3D)
|
||||
ret = d3d_init_base(d3d, info);
|
||||
else if (d3d->needs_restore)
|
||||
{
|
||||
D3DPRESENT_PARAMETERS d3dpp;
|
||||
d3d_make_d3dpp(d3d, info, &d3dpp);
|
||||
if (d3d->dev->Reset(&d3dpp) != D3D_OK)
|
||||
{
|
||||
HRESULT res = d3d->dev->TestCooperativeLevel();
|
||||
const char *err;
|
||||
switch (res)
|
||||
{
|
||||
case D3DERR_DEVICELOST:
|
||||
err = "DEVICELOST";
|
||||
break;
|
||||
|
||||
case D3DERR_DEVICENOTRESET:
|
||||
err = "DEVICENOTRESET";
|
||||
break;
|
||||
|
||||
case D3DERR_DRIVERINTERNALERROR:
|
||||
err = "DRIVERINTERNALERROR";
|
||||
break;
|
||||
|
||||
default:
|
||||
err = "Unknown";
|
||||
}
|
||||
// Try to recreate the device completely ...
|
||||
RARCH_WARN("[D3D]: Attempting to recover from dead state (%s).\n", err);
|
||||
d3d_deinitialize(d3d);
|
||||
d3d->g_pD3D->Release();
|
||||
d3d->g_pD3D = NULL;
|
||||
ret = d3d_init_base(d3d, info);
|
||||
if (ret)
|
||||
RARCH_LOG("[D3D]: Recovered from dead state.\n");
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
d3d_calculate_rect(d3d, d3d->screen_width, d3d->screen_height,
|
||||
info->force_aspect, g_extern.system.aspect_ratio);
|
||||
|
||||
#ifdef HAVE_SHADERS
|
||||
if (!d3d_init_shader(d3d))
|
||||
{
|
||||
RARCH_ERR("Failed to initialize shader subsystem.\n");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!d3d_init_chain(d3d, info))
|
||||
{
|
||||
RARCH_ERR("Failed to initialize render chain.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(_XBOX360)
|
||||
strlcpy(g_settings.video.font_path, "game:\\media\\Arial_12.xpr",
|
||||
sizeof(g_settings.video.font_path));
|
||||
#endif
|
||||
d3d->font_ctx = d3d_font_init_first(d3d, g_settings.video.font_path,
|
||||
g_settings.video.font_size);
|
||||
if (!d3d->font_ctx)
|
||||
{
|
||||
RARCH_ERR("Failed to initialize font.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool d3d_restore(d3d_video_t *d3d)
|
||||
{
|
||||
#ifdef _XBOX
|
||||
d3d->needs_restore = false;
|
||||
#else
|
||||
d3d_deinitialize(d3d);
|
||||
d3d->needs_restore = !d3d_initialize(d3d, &d3d->video_info);
|
||||
#endif
|
||||
|
||||
if (d3d->needs_restore)
|
||||
RARCH_ERR("[D3D]: Restore error.\n");
|
||||
|
||||
return !d3d->needs_restore;
|
||||
}
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
#include "d3d_overlays.cpp"
|
||||
#endif
|
||||
|
||||
static void d3d_set_viewport(d3d_video_t *d3d, int x, int y,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
D3DVIEWPORT viewport;
|
||||
|
||||
/* D3D doesn't support negative X/Y viewports ... */
|
||||
if (x < 0)
|
||||
x = 0;
|
||||
if (y < 0)
|
||||
y = 0;
|
||||
|
||||
viewport.X = x;
|
||||
viewport.Y = y;
|
||||
viewport.Width = width;
|
||||
viewport.Height = height;
|
||||
viewport.MinZ = 0.0f;
|
||||
viewport.MaxZ = 1.0f;
|
||||
|
||||
d3d->final_viewport = viewport;
|
||||
|
||||
d3d_set_font_rect(d3d, NULL);
|
||||
}
|
||||
|
||||
static void d3d_calculate_rect(d3d_video_t *d3d,
|
||||
unsigned width, unsigned height,
|
||||
bool keep, float desired_aspect)
|
||||
{
|
||||
if (g_settings.video.scale_integer)
|
||||
{
|
||||
struct rarch_viewport vp = {0};
|
||||
gfx_scale_integer(&vp, width, height, desired_aspect, keep);
|
||||
d3d_set_viewport(d3d, vp.x, vp.y, vp.width, vp.height);
|
||||
}
|
||||
else if (!keep)
|
||||
d3d_set_viewport(d3d, 0, 0, width, height);
|
||||
else
|
||||
{
|
||||
if (g_settings.video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
|
||||
{
|
||||
const rarch_viewport_t &custom =
|
||||
g_extern.console.screen.viewports.custom_vp;
|
||||
d3d_set_viewport(d3d, custom.x, custom.y,
|
||||
custom.width, custom.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
float device_aspect = static_cast<float>(width) /
|
||||
static_cast<float>(height);
|
||||
|
||||
if (fabsf(device_aspect - desired_aspect) < 0.0001f)
|
||||
d3d_set_viewport(d3d, 0, 0, width, height);
|
||||
else if (device_aspect > desired_aspect)
|
||||
{
|
||||
float delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f;
|
||||
d3d_set_viewport(d3d, int(roundf(width * (0.5f - delta))),
|
||||
0, unsigned(roundf(2.0f * width * delta)), height);
|
||||
}
|
||||
else
|
||||
{
|
||||
float delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f;
|
||||
d3d_set_viewport(d3d, 0, int(roundf(height * (0.5f - delta))),
|
||||
width, unsigned(roundf(2.0f * height * delta)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool d3d_frame(void *data, const void *frame,
|
||||
unsigned width, unsigned height, unsigned pitch,
|
||||
const char *msg)
|
||||
|
@ -716,49 +495,6 @@ static bool d3d_frame(void *data, const void *frame,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void d3d_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
d3d->video_info.vsync = !state;
|
||||
|
||||
if (d3d->ctx_driver && d3d->ctx_driver->swap_interval)
|
||||
d3d->ctx_driver->swap_interval(d3d, state ? 0 : 1);
|
||||
}
|
||||
|
||||
static bool d3d_alive(void *data)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
bool quit, resize;
|
||||
|
||||
quit = false;
|
||||
resize = false;
|
||||
|
||||
if (d3d->ctx_driver && d3d->ctx_driver->check_window)
|
||||
d3d->ctx_driver->check_window(d3d, &quit, &resize, &d3d->screen_width,
|
||||
&d3d->screen_height, g_extern.frame_count);
|
||||
|
||||
if (quit)
|
||||
d3d->quitting = quit;
|
||||
else if (resize)
|
||||
d3d->should_resize = true;
|
||||
|
||||
return !quit;
|
||||
}
|
||||
|
||||
static bool d3d_focus(void *data)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
if (d3d && d3d->ctx_driver && d3d->ctx_driver->has_focus)
|
||||
return d3d->ctx_driver->has_focus(d3d);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void d3d_set_rotation(void *data, unsigned rot)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
d3d->dev_rotation = rot;
|
||||
}
|
||||
|
||||
static void d3d_free(void *data)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
@ -788,19 +524,6 @@ static void d3d_free(void *data)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void d3d_viewport_info(void *data, struct rarch_viewport *vp)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
vp->x = d3d->final_viewport.X;
|
||||
vp->y = d3d->final_viewport.Y;
|
||||
vp->width = d3d->final_viewport.Width;
|
||||
vp->height = d3d->final_viewport.Height;
|
||||
|
||||
vp->full_width = d3d->screen_width;
|
||||
vp->full_height = d3d->screen_height;
|
||||
}
|
||||
|
||||
static bool d3d_read_viewport(void *data, uint8_t *buffer)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
@ -901,61 +624,6 @@ static void d3d_get_poke_interface(void *data,
|
|||
const video_poke_interface_t **iface);
|
||||
#endif
|
||||
|
||||
static void d3d_set_aspect_ratio(void *data, unsigned aspect_ratio_idx)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
switch (aspect_ratio_idx)
|
||||
{
|
||||
case ASPECT_RATIO_SQUARE:
|
||||
gfx_set_square_pixel_viewport(
|
||||
g_extern.system.av_info.geometry.base_width,
|
||||
g_extern.system.av_info.geometry.base_height);
|
||||
break;
|
||||
|
||||
case ASPECT_RATIO_CORE:
|
||||
gfx_set_core_viewport();
|
||||
break;
|
||||
|
||||
case ASPECT_RATIO_CONFIG:
|
||||
gfx_set_config_viewport();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_extern.system.aspect_ratio = aspectratio_lut[aspect_ratio_idx].value;
|
||||
d3d->video_info.force_aspect = true;
|
||||
d3d->should_resize = true;
|
||||
}
|
||||
|
||||
static void d3d_apply_state_changes(void *data)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
d3d->should_resize = true;
|
||||
}
|
||||
|
||||
static void d3d_set_osd_msg(void *data, const char *msg,
|
||||
const struct font_params *params)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
if (params)
|
||||
d3d_set_font_rect(d3d, params);
|
||||
|
||||
if (d3d && d3d->font_ctx && d3d->font_ctx->render_msg)
|
||||
d3d->font_ctx->render_msg(d3d, msg, params);
|
||||
}
|
||||
|
||||
static void d3d_show_mouse(void *data, bool state)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
if (d3d && d3d->ctx_driver && d3d->ctx_driver->show_mouse)
|
||||
d3d->ctx_driver->show_mouse(d3d, state);
|
||||
}
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
static void d3d_set_menu_texture_frame(void *data,
|
||||
const void *frame, bool rgb32, unsigned width, unsigned height,
|
||||
|
@ -1063,157 +731,6 @@ static void d3d_get_poke_interface(void *data,
|
|||
*iface = &d3d_poke_interface;
|
||||
}
|
||||
|
||||
/* Delay constructor due to lack of exceptions. */
|
||||
|
||||
static bool d3d_construct(d3d_video_t *d3d,
|
||||
const video_info_t *info, const input_driver_t **input,
|
||||
void **input_data)
|
||||
{
|
||||
d3d->should_resize = false;
|
||||
#ifndef _XBOX
|
||||
gfx_set_dwm();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
if (d3d->menu)
|
||||
free(d3d->menu);
|
||||
|
||||
d3d->menu = (overlay_t*)calloc(1, sizeof(overlay_t));
|
||||
d3d->menu->tex_coords.x = 0;
|
||||
d3d->menu->tex_coords.y = 0;
|
||||
d3d->menu->tex_coords.w = 1;
|
||||
d3d->menu->tex_coords.h = 1;
|
||||
d3d->menu->vert_coords.x = 0;
|
||||
d3d->menu->vert_coords.y = 1;
|
||||
d3d->menu->vert_coords.w = 1;
|
||||
d3d->menu->vert_coords.h = -1;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINDOW
|
||||
memset(&d3d->windowClass, 0, sizeof(d3d->windowClass));
|
||||
d3d->windowClass.cbSize = sizeof(d3d->windowClass);
|
||||
d3d->windowClass.style = CS_HREDRAW | CS_VREDRAW;
|
||||
d3d->windowClass.lpfnWndProc = WindowProc;
|
||||
d3d->windowClass.hInstance = NULL;
|
||||
d3d->windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
d3d->windowClass.lpszClassName = "RetroArch";
|
||||
d3d->windowClass.hIcon = LoadIcon(GetModuleHandle(NULL),
|
||||
MAKEINTRESOURCE(IDI_ICON));
|
||||
d3d->windowClass.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL),
|
||||
MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, 0);
|
||||
if (!info->fullscreen)
|
||||
d3d->windowClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
||||
|
||||
RegisterClassEx(&d3d->windowClass);
|
||||
#endif
|
||||
|
||||
unsigned full_x, full_y;
|
||||
#ifdef HAVE_MONITOR
|
||||
RECT mon_rect = d3d_monitor_rect(d3d);
|
||||
|
||||
bool windowed_full = g_settings.video.windowed_fullscreen;
|
||||
|
||||
full_x = (windowed_full || info->width == 0) ?
|
||||
(mon_rect.right - mon_rect.left) : info->width;
|
||||
full_y = (windowed_full || info->height == 0) ?
|
||||
(mon_rect.bottom - mon_rect.top) : info->height;
|
||||
RARCH_LOG("[D3D]: Monitor size: %dx%d.\n",
|
||||
(int)(mon_rect.right - mon_rect.left),
|
||||
(int)(mon_rect.bottom - mon_rect.top));
|
||||
#else
|
||||
if (d3d->ctx_driver && d3d->ctx_driver->get_video_size)
|
||||
d3d->ctx_driver->get_video_size(&full_x, &full_y);
|
||||
#endif
|
||||
d3d->screen_width = info->fullscreen ? full_x : info->width;
|
||||
d3d->screen_height = info->fullscreen ? full_y : info->height;
|
||||
|
||||
#ifdef HAVE_WINDOW
|
||||
unsigned win_width = d3d->screen_width;
|
||||
unsigned win_height = d3d->screen_height;
|
||||
|
||||
if (!info->fullscreen)
|
||||
{
|
||||
RECT rect = {0};
|
||||
rect.right = d3d->screen_width;
|
||||
rect.bottom = d3d->screen_height;
|
||||
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
|
||||
win_width = rect.right - rect.left;
|
||||
win_height = rect.bottom - rect.top;
|
||||
}
|
||||
|
||||
char buffer[128];
|
||||
gfx_get_fps(buffer, sizeof(buffer), NULL, 0);
|
||||
std::string title = buffer;
|
||||
title += " || Direct3D";
|
||||
|
||||
d3d->hWnd = CreateWindowEx(0, "RetroArch", title.c_str(),
|
||||
info->fullscreen ?
|
||||
(WS_EX_TOPMOST | WS_POPUP) : WS_OVERLAPPEDWINDOW,
|
||||
info->fullscreen ? mon_rect.left : CW_USEDEFAULT,
|
||||
info->fullscreen ? mon_rect.top : CW_USEDEFAULT,
|
||||
win_width, win_height,
|
||||
NULL, NULL, NULL, d3d);
|
||||
|
||||
driver.display_type = RARCH_DISPLAY_WIN32;
|
||||
driver.video_display = 0;
|
||||
driver.video_window = (uintptr_t)d3d->hWnd;
|
||||
#endif
|
||||
|
||||
if (d3d && d3d->ctx_driver && d3d->ctx_driver->show_mouse)
|
||||
d3d->ctx_driver->show_mouse(d3d, !info->fullscreen
|
||||
#ifdef HAVE_OVERLAY
|
||||
|| d3d->overlays_enabled
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef HAVE_WINDOW
|
||||
ShowWindow(d3d->hWnd, SW_RESTORE);
|
||||
UpdateWindow(d3d->hWnd);
|
||||
SetForegroundWindow(d3d->hWnd);
|
||||
SetFocus(d3d->hWnd);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SHADERS
|
||||
/* This should only be done once here
|
||||
* to avoid set_shader() to be overridden
|
||||
* later. */
|
||||
enum rarch_shader_type type =
|
||||
gfx_shader_parse_type(g_settings.video.shader_path, RARCH_SHADER_NONE);
|
||||
if (g_settings.video.shader_enable && type == RARCH_SHADER_CG)
|
||||
d3d->cg_shader = g_settings.video.shader_path;
|
||||
|
||||
if (!d3d_process_shader(d3d))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
d3d->video_info = *info;
|
||||
if (!d3d_initialize(d3d, &d3d->video_info))
|
||||
return false;
|
||||
|
||||
if (input && input_data &&
|
||||
d3d->ctx_driver && d3d->ctx_driver->input_driver)
|
||||
d3d->ctx_driver->input_driver(d3d, input, input_data);
|
||||
|
||||
RARCH_LOG("[D3D]: Init complete.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
static const gfx_ctx_driver_t *d3d_get_context(void)
|
||||
{
|
||||
/* TODO: GL core contexts through ANGLE? */
|
||||
enum gfx_ctx_api api;
|
||||
unsigned major, minor;
|
||||
#if defined(_XBOX1)
|
||||
api = GFX_CTX_DIRECT3D8_API;
|
||||
major = 8;
|
||||
#else
|
||||
api = GFX_CTX_DIRECT3D9_API;
|
||||
major = 9;
|
||||
#endif
|
||||
minor = 0;
|
||||
return gfx_ctx_init_first(driver.video_data, api, major, minor, false);
|
||||
}
|
||||
|
||||
static void *d3d_init(const video_info_t *info, const input_driver_t **input,
|
||||
void **input_data)
|
||||
{
|
||||
|
@ -1255,7 +772,7 @@ static void *d3d_init(const video_info_t *info, const input_driver_t **input,
|
|||
return vid;
|
||||
}
|
||||
|
||||
const video_driver_t video_d3d = {
|
||||
video_driver_t video_d3d = {
|
||||
d3d_init,
|
||||
d3d_frame,
|
||||
d3d_set_nonblock_state,
|
||||
|
|
|
@ -0,0 +1,500 @@
|
|||
|
||||
static void d3d_deinit_chain(void *data)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
#ifdef _XBOX
|
||||
renderchain_free(d3d);
|
||||
#else
|
||||
if (d3d->chain)
|
||||
delete (renderchain_t *)d3d->chain;
|
||||
d3d->chain = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void d3d_deinitialize(void *data)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
if (d3d->font_ctx && d3d->font_ctx->deinit)
|
||||
d3d->font_ctx->deinit(d3d);
|
||||
d3d->font_ctx = NULL;
|
||||
d3d_deinit_chain(d3d);
|
||||
#ifdef HAVE_SHADERS
|
||||
d3d_deinit_shader(d3d);
|
||||
#endif
|
||||
|
||||
#ifndef _XBOX
|
||||
d3d->needs_restore = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool d3d_init_base(void *data, const video_info_t *info)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
D3DPRESENT_PARAMETERS d3dpp;
|
||||
d3d_make_d3dpp(d3d, info, &d3dpp);
|
||||
|
||||
d3d->g_pD3D = D3DCREATE_CTX(D3D_SDK_VERSION);
|
||||
if (!d3d->g_pD3D)
|
||||
{
|
||||
RARCH_ERR("Failed to create D3D interface.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FAILED(d3d->d3d_err = d3d->g_pD3D->CreateDevice(
|
||||
d3d->cur_mon_id,
|
||||
D3DDEVTYPE_HAL,
|
||||
d3d->hWnd,
|
||||
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
||||
&d3dpp,
|
||||
&d3d->dev)))
|
||||
{
|
||||
RARCH_WARN("[D3D]: Failed to init device with hardware vertex processing (code: 0x%x). Trying to fall back to software vertex processing.\n",
|
||||
(unsigned)d3d->d3d_err);
|
||||
|
||||
if (FAILED(d3d->d3d_err = d3d->g_pD3D->CreateDevice(
|
||||
d3d->cur_mon_id,
|
||||
D3DDEVTYPE_HAL,
|
||||
d3d->hWnd,
|
||||
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
|
||||
&d3dpp,
|
||||
&d3d->dev)))
|
||||
{
|
||||
RARCH_ERR("Failed to initialize device.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool d3d_initialize(void *data, const video_info_t *info)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
bool ret = true;
|
||||
if (!d3d->g_pD3D)
|
||||
ret = d3d_init_base(d3d, info);
|
||||
else if (d3d->needs_restore)
|
||||
{
|
||||
D3DPRESENT_PARAMETERS d3dpp;
|
||||
d3d_make_d3dpp(d3d, info, &d3dpp);
|
||||
if (d3d->dev->Reset(&d3dpp) != D3D_OK)
|
||||
{
|
||||
// Try to recreate the device completely ..
|
||||
#ifndef _XBOX
|
||||
HRESULT res = d3d->dev->TestCooperativeLevel();
|
||||
const char *err;
|
||||
switch (res)
|
||||
{
|
||||
case D3DERR_DEVICELOST:
|
||||
err = "DEVICELOST";
|
||||
break;
|
||||
|
||||
case D3DERR_DEVICENOTRESET:
|
||||
err = "DEVICENOTRESET";
|
||||
break;
|
||||
|
||||
case D3DERR_DRIVERINTERNALERROR:
|
||||
err = "DRIVERINTERNALERROR";
|
||||
break;
|
||||
|
||||
default:
|
||||
err = "Unknown";
|
||||
}
|
||||
RARCH_WARN(
|
||||
"[D3D]: Attempting to recover from dead state (%s).\n", err);
|
||||
#else
|
||||
RARCH_WARN("[D3D]: Attempting to recover from dead state.\n");
|
||||
#endif
|
||||
d3d_deinitialize(d3d);
|
||||
d3d->g_pD3D->Release();
|
||||
d3d->g_pD3D = NULL;
|
||||
ret = d3d_init_base(d3d, info);
|
||||
if (ret)
|
||||
RARCH_LOG("[D3D]: Recovered from dead state.\n");
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
d3d_calculate_rect(d3d, d3d->screen_width, d3d->screen_height,
|
||||
info->force_aspect, g_extern.system.aspect_ratio);
|
||||
|
||||
#ifdef HAVE_SHADERS
|
||||
if (!d3d_init_shader(d3d))
|
||||
{
|
||||
RARCH_ERR("Failed to initialize shader subsystem.\n");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!d3d_init_chain(d3d, info))
|
||||
{
|
||||
RARCH_ERR("Failed to initialize render chain.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(_XBOX360)
|
||||
strlcpy(g_settings.video.font_path, "game:\\media\\Arial_12.xpr",
|
||||
sizeof(g_settings.video.font_path));
|
||||
#endif
|
||||
d3d->font_ctx = d3d_font_init_first(d3d, g_settings.video.font_path, 0);
|
||||
if (!d3d->font_ctx)
|
||||
{
|
||||
RARCH_ERR("Failed to initialize font.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void d3d_set_viewport(d3d_video_t *d3d, int x, int y,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
D3DVIEWPORT viewport;
|
||||
|
||||
/* D3D doesn't support negative X/Y viewports ... */
|
||||
if (x < 0)
|
||||
x = 0;
|
||||
if (y < 0)
|
||||
y = 0;
|
||||
|
||||
viewport.X = x;
|
||||
viewport.Y = y;
|
||||
viewport.Width = width;
|
||||
viewport.Height = height;
|
||||
viewport.MinZ = 0.0f;
|
||||
viewport.MaxZ = 1.0f;
|
||||
|
||||
d3d->final_viewport = viewport;
|
||||
|
||||
#ifndef _XBOX
|
||||
d3d_set_font_rect(d3d, NULL);
|
||||
#endif
|
||||
}
|
||||
bool d3d_restore(void *data)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
d3d_deinitialize(d3d);
|
||||
d3d->needs_restore = !d3d_initialize(d3d, &d3d->video_info);
|
||||
|
||||
if (d3d->needs_restore)
|
||||
RARCH_ERR("[D3D]: Restore error.\n");
|
||||
|
||||
return !d3d->needs_restore;
|
||||
}
|
||||
|
||||
static void d3d_calculate_rect(d3d_video_t *d3d,
|
||||
unsigned width, unsigned height,
|
||||
bool keep, float desired_aspect)
|
||||
{
|
||||
if (g_settings.video.scale_integer)
|
||||
{
|
||||
struct rarch_viewport vp = {0};
|
||||
gfx_scale_integer(&vp, width, height, desired_aspect, keep);
|
||||
d3d_set_viewport(d3d, vp.x, vp.y, vp.width, vp.height);
|
||||
}
|
||||
else if (!keep)
|
||||
d3d_set_viewport(d3d, 0, 0, width, height);
|
||||
else
|
||||
{
|
||||
if (g_settings.video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
|
||||
{
|
||||
const rarch_viewport_t &custom =
|
||||
g_extern.console.screen.viewports.custom_vp;
|
||||
d3d_set_viewport(d3d, custom.x, custom.y,
|
||||
custom.width, custom.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
float device_aspect = static_cast<float>(width) /
|
||||
static_cast<float>(height);
|
||||
|
||||
if (fabsf(device_aspect - desired_aspect) < 0.0001f)
|
||||
d3d_set_viewport(d3d, 0, 0, width, height);
|
||||
else if (device_aspect > desired_aspect)
|
||||
{
|
||||
float delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f;
|
||||
d3d_set_viewport(d3d, int(roundf(width * (0.5f - delta))),
|
||||
0, unsigned(roundf(2.0f * width * delta)), height);
|
||||
}
|
||||
else
|
||||
{
|
||||
float delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f;
|
||||
d3d_set_viewport(d3d, 0, int(roundf(height * (0.5f - delta))),
|
||||
width, unsigned(roundf(2.0f * height * delta)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void d3d_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
d3d->video_info.vsync = !state;
|
||||
|
||||
if (d3d->ctx_driver && d3d->ctx_driver->swap_interval)
|
||||
d3d->ctx_driver->swap_interval(d3d, state ? 0 : 1);
|
||||
}
|
||||
|
||||
static bool d3d_alive(void *data)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
bool quit, resize;
|
||||
|
||||
quit = false;
|
||||
resize = false;
|
||||
|
||||
if (d3d->ctx_driver && d3d->ctx_driver->check_window)
|
||||
d3d->ctx_driver->check_window(d3d, &quit, &resize,
|
||||
&d3d->screen_width, &d3d->screen_height, g_extern.frame_count);
|
||||
|
||||
if (quit)
|
||||
d3d->quitting = quit;
|
||||
else if (resize)
|
||||
d3d->should_resize = true;
|
||||
|
||||
return !quit;
|
||||
}
|
||||
|
||||
static bool d3d_focus(void *data)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
if (d3d && d3d->ctx_driver && d3d->ctx_driver->has_focus)
|
||||
return d3d->ctx_driver->has_focus(d3d);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void d3d_set_aspect_ratio(void *data, unsigned aspect_ratio_idx)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
switch (aspect_ratio_idx)
|
||||
{
|
||||
case ASPECT_RATIO_SQUARE:
|
||||
gfx_set_square_pixel_viewport(
|
||||
g_extern.system.av_info.geometry.base_width,
|
||||
g_extern.system.av_info.geometry.base_height);
|
||||
break;
|
||||
|
||||
case ASPECT_RATIO_CORE:
|
||||
gfx_set_core_viewport();
|
||||
break;
|
||||
|
||||
case ASPECT_RATIO_CONFIG:
|
||||
gfx_set_config_viewport();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_extern.system.aspect_ratio = aspectratio_lut[aspect_ratio_idx].value;
|
||||
d3d->video_info.force_aspect = true;
|
||||
d3d->should_resize = true;
|
||||
}
|
||||
|
||||
static void d3d_apply_state_changes(void *data)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
d3d->should_resize = true;
|
||||
}
|
||||
|
||||
static void d3d_set_osd_msg(void *data, const char *msg,
|
||||
const struct font_params *params)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
#ifndef _XBOX
|
||||
if (params)
|
||||
d3d_set_font_rect(d3d, params);
|
||||
#endif
|
||||
|
||||
if (d3d && d3d->font_ctx && d3d->font_ctx->render_msg)
|
||||
d3d->font_ctx->render_msg(d3d, msg, params);
|
||||
}
|
||||
|
||||
/* Delay constructor due to lack of exceptions. */
|
||||
|
||||
static bool d3d_construct(d3d_video_t *d3d,
|
||||
const video_info_t *info, const input_driver_t **input,
|
||||
void **input_data)
|
||||
{
|
||||
d3d->should_resize = false;
|
||||
#ifndef _XBOX
|
||||
gfx_set_dwm();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
if (d3d->menu)
|
||||
free(d3d->menu);
|
||||
|
||||
d3d->menu = (overlay_t*)calloc(1, sizeof(overlay_t));
|
||||
d3d->menu->tex_coords.x = 0;
|
||||
d3d->menu->tex_coords.y = 0;
|
||||
d3d->menu->tex_coords.w = 1;
|
||||
d3d->menu->tex_coords.h = 1;
|
||||
d3d->menu->vert_coords.x = 0;
|
||||
d3d->menu->vert_coords.y = 1;
|
||||
d3d->menu->vert_coords.w = 1;
|
||||
d3d->menu->vert_coords.h = -1;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINDOW
|
||||
memset(&d3d->windowClass, 0, sizeof(d3d->windowClass));
|
||||
d3d->windowClass.cbSize = sizeof(d3d->windowClass);
|
||||
d3d->windowClass.style = CS_HREDRAW | CS_VREDRAW;
|
||||
d3d->windowClass.lpfnWndProc = WindowProc;
|
||||
d3d->windowClass.hInstance = NULL;
|
||||
d3d->windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
d3d->windowClass.lpszClassName = "RetroArch";
|
||||
d3d->windowClass.hIcon = LoadIcon(GetModuleHandle(NULL),
|
||||
MAKEINTRESOURCE(IDI_ICON));
|
||||
d3d->windowClass.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL),
|
||||
MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, 0);
|
||||
if (!info->fullscreen)
|
||||
d3d->windowClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
||||
|
||||
RegisterClassEx(&d3d->windowClass);
|
||||
#endif
|
||||
|
||||
unsigned full_x, full_y;
|
||||
#ifdef HAVE_MONITOR
|
||||
RECT mon_rect = d3d_monitor_rect(d3d);
|
||||
|
||||
bool windowed_full = g_settings.video.windowed_fullscreen;
|
||||
|
||||
full_x = (windowed_full || info->width == 0) ?
|
||||
(mon_rect.right - mon_rect.left) : info->width;
|
||||
full_y = (windowed_full || info->height == 0) ?
|
||||
(mon_rect.bottom - mon_rect.top) : info->height;
|
||||
RARCH_LOG("[D3D]: Monitor size: %dx%d.\n",
|
||||
(int)(mon_rect.right - mon_rect.left),
|
||||
(int)(mon_rect.bottom - mon_rect.top));
|
||||
#else
|
||||
if (d3d->ctx_driver && d3d->ctx_driver->get_video_size)
|
||||
d3d->ctx_driver->get_video_size(&full_x, &full_y);
|
||||
#endif
|
||||
d3d->screen_width = info->fullscreen ? full_x : info->width;
|
||||
d3d->screen_height = info->fullscreen ? full_y : info->height;
|
||||
|
||||
#ifdef HAVE_WINDOW
|
||||
unsigned win_width = d3d->screen_width;
|
||||
unsigned win_height = d3d->screen_height;
|
||||
|
||||
if (!info->fullscreen)
|
||||
{
|
||||
RECT rect = {0};
|
||||
rect.right = d3d->screen_width;
|
||||
rect.bottom = d3d->screen_height;
|
||||
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
|
||||
win_width = rect.right - rect.left;
|
||||
win_height = rect.bottom - rect.top;
|
||||
}
|
||||
|
||||
char buffer[128];
|
||||
gfx_get_fps(buffer, sizeof(buffer), NULL, 0);
|
||||
std::string title = buffer;
|
||||
title += " || Direct3D";
|
||||
|
||||
d3d->hWnd = CreateWindowEx(0, "RetroArch", title.c_str(),
|
||||
info->fullscreen ?
|
||||
(WS_EX_TOPMOST | WS_POPUP) : WS_OVERLAPPEDWINDOW,
|
||||
info->fullscreen ? mon_rect.left : CW_USEDEFAULT,
|
||||
info->fullscreen ? mon_rect.top : CW_USEDEFAULT,
|
||||
win_width, win_height,
|
||||
NULL, NULL, NULL, d3d);
|
||||
|
||||
driver.display_type = RARCH_DISPLAY_WIN32;
|
||||
driver.video_display = 0;
|
||||
driver.video_window = (uintptr_t)d3d->hWnd;
|
||||
#endif
|
||||
|
||||
if (d3d && d3d->ctx_driver && d3d->ctx_driver->show_mouse)
|
||||
d3d->ctx_driver->show_mouse(d3d, !info->fullscreen
|
||||
#ifdef HAVE_OVERLAY
|
||||
|| d3d->overlays_enabled
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef HAVE_WINDOW
|
||||
ShowWindow(d3d->hWnd, SW_RESTORE);
|
||||
UpdateWindow(d3d->hWnd);
|
||||
SetForegroundWindow(d3d->hWnd);
|
||||
SetFocus(d3d->hWnd);
|
||||
#endif
|
||||
|
||||
#ifndef _XBOX
|
||||
#ifdef HAVE_SHADERS
|
||||
/* This should only be done once here
|
||||
* to avoid set_shader() to be overridden
|
||||
* later. */
|
||||
enum rarch_shader_type type =
|
||||
gfx_shader_parse_type(g_settings.video.shader_path, RARCH_SHADER_NONE);
|
||||
if (g_settings.video.shader_enable && type == RARCH_SHADER_CG)
|
||||
d3d->cg_shader = g_settings.video.shader_path;
|
||||
|
||||
if (!d3d_process_shader(d3d))
|
||||
return false;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
d3d->video_info = *info;
|
||||
if (!d3d_initialize(d3d, &d3d->video_info))
|
||||
return false;
|
||||
|
||||
if (input && input_data &&
|
||||
d3d->ctx_driver && d3d->ctx_driver->input_driver)
|
||||
d3d->ctx_driver->input_driver(d3d, input, input_data);
|
||||
|
||||
RARCH_LOG("[D3D]: Init complete.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
static void d3d_viewport_info(void *data, struct rarch_viewport *vp)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
vp->x = d3d->final_viewport.X;
|
||||
vp->y = d3d->final_viewport.Y;
|
||||
vp->width = d3d->final_viewport.Width;
|
||||
vp->height = d3d->final_viewport.Height;
|
||||
|
||||
vp->full_width = d3d->screen_width;
|
||||
vp->full_height = d3d->screen_height;
|
||||
}
|
||||
|
||||
static void d3d_set_rotation(void *data, unsigned rot)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
d3d->dev_rotation = rot;
|
||||
}
|
||||
|
||||
static void d3d_show_mouse(void *data, bool state)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
if (d3d && d3d->ctx_driver && d3d->ctx_driver->show_mouse)
|
||||
d3d->ctx_driver->show_mouse(d3d, state);
|
||||
}
|
||||
|
||||
static const gfx_ctx_driver_t *d3d_get_context(void *data)
|
||||
{
|
||||
/* TODO: GL core contexts through ANGLE? */
|
||||
enum gfx_ctx_api api;
|
||||
unsigned major, minor;
|
||||
#if defined(_XBOX1)
|
||||
api = GFX_CTX_DIRECT3D8_API;
|
||||
major = 8;
|
||||
#elif defined(_XBOX360)
|
||||
api = GFX_CTX_DIRECT3D9_API;
|
||||
major = 9;
|
||||
#endif
|
||||
minor = 0;
|
||||
return gfx_ctx_init_first(driver.video_data, api,
|
||||
major, minor, false);
|
||||
}
|
|
@ -34,37 +34,7 @@
|
|||
|
||||
#include "render_chain_xdk.h"
|
||||
|
||||
//OK
|
||||
static void d3d_deinit_chain(void *data)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
#ifdef _XBOX
|
||||
renderchain_free(d3d);
|
||||
#else
|
||||
if (d3d->chain)
|
||||
delete (renderchain_t *)d3d->chain;
|
||||
d3d->chain = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
//OK
|
||||
static void d3d_deinitialize(void *data)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
if (d3d->font_ctx && d3d->font_ctx->deinit)
|
||||
d3d->font_ctx->deinit(d3d);
|
||||
d3d->font_ctx = NULL;
|
||||
d3d_deinit_chain(d3d);
|
||||
#ifdef HAVE_SHADERS
|
||||
d3d_deinit_shader(d3d);
|
||||
#endif
|
||||
|
||||
#ifndef _XBOX
|
||||
d3d->needs_restore = false;
|
||||
#endif
|
||||
}
|
||||
#include "d3d_shared.h"
|
||||
|
||||
static void d3d_free(void *data)
|
||||
{
|
||||
|
@ -81,7 +51,8 @@ static void d3d_free(void *data)
|
|||
d3d->g_pD3D->Release();
|
||||
|
||||
#ifdef HAVE_MONITOR
|
||||
Monitor::last_hm = MonitorFromWindow(d3d->hWnd, MONITOR_DEFAULTTONEAREST);
|
||||
Monitor::last_hm = MonitorFromWindow(d3d->hWnd,
|
||||
MONITOR_DEFAULTTONEAREST);
|
||||
DestroyWindow(d3d->hWnd);
|
||||
#endif
|
||||
|
||||
|
@ -93,29 +64,8 @@ static void d3d_free(void *data)
|
|||
#endif
|
||||
}
|
||||
|
||||
//OK
|
||||
static void d3d_viewport_info(void *data, struct rarch_viewport *vp)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
vp->x = d3d->final_viewport.X;
|
||||
vp->y = d3d->final_viewport.Y;
|
||||
vp->width = d3d->final_viewport.Width;
|
||||
vp->height = d3d->final_viewport.Height;
|
||||
|
||||
vp->full_width = d3d->screen_width;
|
||||
vp->full_height = d3d->screen_height;
|
||||
}
|
||||
|
||||
//OK
|
||||
static void d3d_set_rotation(void *data, unsigned rot)
|
||||
{
|
||||
(void)data;
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
d3d->dev_rotation = rot;
|
||||
}
|
||||
|
||||
static bool d3d_set_shader(void *data, enum rarch_shader_type type, const char *path)
|
||||
static bool d3d_set_shader(void *data,
|
||||
enum rarch_shader_type type, const char *path)
|
||||
{
|
||||
/* TODO - stub */
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
@ -154,7 +104,8 @@ static bool d3d_init_chain(void *data, const video_info_t *info)
|
|||
if (!d3d->chain)
|
||||
return false;
|
||||
|
||||
if (!renderchain_init(d3d->chain, &d3d->video_info, d3dr, d3d->cgCtx, &d3d->final_viewport, &link_info,
|
||||
if (!renderchain_init(d3d->chain, &d3d->video_info, d3dr, d3d->cgCtx,
|
||||
&d3d->final_viewport, &link_info,
|
||||
d3d->video_info.rgb32 ? ARGB : RGB565))
|
||||
{
|
||||
RARCH_ERR("[D3D]: Failed to init render chain.\n");
|
||||
|
@ -206,67 +157,32 @@ static bool d3d_init_chain(void *data, const video_info_t *info)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void d3d_reinit_renderchain(void *data, const video_info_t *video)
|
||||
static void d3d_reinit_renderchain(void *data,
|
||||
const video_info_t *video)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
d3d->pixel_size = video->rgb32 ? sizeof(uint32_t) : sizeof(uint16_t);
|
||||
d3d->tex_w = d3d->tex_h = RARCH_SCALE_BASE * video->input_scale;
|
||||
d3d->pixel_size = video->rgb32 ?
|
||||
sizeof(uint32_t) : sizeof(uint16_t);
|
||||
d3d->tex_w = d3d->tex_h =
|
||||
RARCH_SCALE_BASE * video->input_scale;
|
||||
|
||||
RARCH_LOG(
|
||||
"Reinitializing renderchain - and textures (%u x %u @ %u bpp)\n",
|
||||
d3d->tex_w, d3d->tex_h, d3d->pixel_size * CHAR_BIT);
|
||||
|
||||
RARCH_LOG("Reinitializing renderchain - and textures (%u x %u @ %u bpp)\n", d3d->tex_w,
|
||||
d3d->tex_h, d3d->pixel_size * CHAR_BIT);
|
||||
d3d_deinit_chain(d3d);
|
||||
d3d_init_chain(d3d, video);
|
||||
}
|
||||
|
||||
//OK
|
||||
static bool d3d_init_base(void *data, const video_info_t *info)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
D3DPRESENT_PARAMETERS d3dpp;
|
||||
d3d_make_d3dpp(d3d, info, &d3dpp);
|
||||
|
||||
d3d->g_pD3D = direct3d_create_ctx(D3D_SDK_VERSION);
|
||||
if (!d3d->g_pD3D)
|
||||
{
|
||||
RARCH_ERR("Failed to create D3D interface.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FAILED(d3d->d3d_err = d3d->g_pD3D->CreateDevice(
|
||||
d3d->cur_mon_id,
|
||||
D3DDEVTYPE_HAL,
|
||||
d3d->hWnd,
|
||||
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
||||
&d3dpp,
|
||||
&d3d->dev)))
|
||||
{
|
||||
RARCH_WARN("[D3D]: Failed to init device with hardware vertex processing (code: 0x%x). Trying to fall back to software vertex processing.\n",
|
||||
(unsigned)d3d->d3d_err);
|
||||
|
||||
if (FAILED(d3d->d3d_err = d3d->g_pD3D->CreateDevice(
|
||||
d3d->cur_mon_id,
|
||||
D3DDEVTYPE_HAL,
|
||||
d3d->hWnd,
|
||||
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
|
||||
&d3dpp,
|
||||
&d3d->dev)))
|
||||
{
|
||||
RARCH_ERR("Failed to initialize device.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef HAVE_RMENU
|
||||
extern struct texture_image *menu_texture;
|
||||
#endif
|
||||
|
||||
#ifdef _XBOX1
|
||||
static bool texture_image_render(void *data, struct texture_image *out_img,
|
||||
int x, int y, int w, int h, bool force_fullscreen)
|
||||
static bool texture_image_render(void *data,
|
||||
struct texture_image *out_img,
|
||||
int x, int y, int w, int h, bool force_fullscreen)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)d3d->dev;
|
||||
|
@ -290,7 +206,8 @@ static bool texture_image_render(void *data, struct texture_image *out_img,
|
|||
// load the existing vertices
|
||||
Vertex *pCurVerts;
|
||||
|
||||
HRESULT ret = out_img->vertex_buf->Lock(0, 0, (unsigned char**)&pCurVerts, 0);
|
||||
HRESULT ret = out_img->vertex_buf->Lock(0, 0,
|
||||
(unsigned char**)&pCurVerts, 0);
|
||||
|
||||
if (FAILED(ret))
|
||||
return false;
|
||||
|
@ -303,14 +220,15 @@ static bool texture_image_render(void *data, struct texture_image *out_img,
|
|||
d3d->dev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
d3d->dev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
|
||||
// also blend the texture with the set alpha value
|
||||
/* Also blend the texture with the set alpha value. */
|
||||
d3d->dev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
d3d->dev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
|
||||
d3d->dev->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
|
||||
|
||||
// draw the quad
|
||||
/* Draw the quad. */
|
||||
d3dr->SetTexture(0, out_img->pixels);
|
||||
D3DDevice_SetStreamSources(d3dr, 0, out_img->vertex_buf, 0, sizeof(Vertex));
|
||||
D3DDevice_SetStreamSources(d3dr, 0,
|
||||
out_img->vertex_buf, 0, sizeof(Vertex));
|
||||
d3dr->SetVertexShader(D3DFVF_CUSTOMVERTEX);
|
||||
|
||||
if (force_fullscreen)
|
||||
|
@ -344,7 +262,8 @@ static void d3d_draw_texture(void *data)
|
|||
d3d->dev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
|
||||
d3d->dev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
d3d->dev->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
|
||||
texture_image_render(d3d, menu_texture, menu_texture->x, menu_texture->y,
|
||||
texture_image_render(d3d, menu_texture,
|
||||
menu_texture->x, menu_texture->y,
|
||||
d3d->screen_width, d3d->screen_height, true);
|
||||
d3d->dev->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
|
||||
}
|
||||
|
@ -352,173 +271,8 @@ static void d3d_draw_texture(void *data)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void d3d_calculate_rect(void *data, unsigned width, unsigned height,
|
||||
bool keep, float desired_aspect);
|
||||
|
||||
//OK
|
||||
static bool d3d_initialize(void *data, const video_info_t *info)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
bool ret = true;
|
||||
if (!d3d->g_pD3D)
|
||||
ret = d3d_init_base(d3d, info);
|
||||
else if (d3d->needs_restore)
|
||||
{
|
||||
D3DPRESENT_PARAMETERS d3dpp;
|
||||
d3d_make_d3dpp(d3d, info, &d3dpp);
|
||||
if (d3d->dev->Reset(&d3dpp) != D3D_OK)
|
||||
{
|
||||
// Try to recreate the device completely ..
|
||||
#ifndef _XBOX
|
||||
HRESULT res = d3d->dev->TestCooperativeLevel();
|
||||
const char *err;
|
||||
switch (res)
|
||||
{
|
||||
case D3DERR_DEVICELOST:
|
||||
err = "DEVICELOST";
|
||||
break;
|
||||
|
||||
case D3DERR_DEVICENOTRESET:
|
||||
err = "DEVICENOTRESET";
|
||||
break;
|
||||
|
||||
case D3DERR_DRIVERINTERNALERROR:
|
||||
err = "DRIVERINTERNALERROR";
|
||||
break;
|
||||
|
||||
default:
|
||||
err = "Unknown";
|
||||
}.
|
||||
RARCH_WARN("[D3D]: Attempting to recover from dead state (%s).\n", err);
|
||||
#else
|
||||
RARCH_WARN("[D3D]: Attempting to recover from dead state.\n");
|
||||
#endif
|
||||
d3d_deinitialize(d3d);
|
||||
d3d->g_pD3D->Release();
|
||||
d3d->g_pD3D = NULL;
|
||||
ret = d3d_init_base(d3d, info);
|
||||
if (ret)
|
||||
RARCH_LOG("[D3D]: Recovered from dead state.\n");
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
d3d_calculate_rect(d3d, d3d->screen_width, d3d->screen_height, info->force_aspect, g_extern.system.aspect_ratio);
|
||||
|
||||
#ifdef HAVE_SHADERS
|
||||
if (!d3d_init_shader(d3d))
|
||||
{
|
||||
RARCH_ERR("Failed to initialize shader subsystem.\n");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!d3d_init_chain(d3d, info))
|
||||
{
|
||||
RARCH_ERR("Failed to initialize render chain.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(_XBOX360)
|
||||
strlcpy(g_settings.video.font_path, "game:\\media\\Arial_12.xpr", sizeof(g_settings.video.font_path));
|
||||
#endif
|
||||
d3d->font_ctx = d3d_font_init_first(d3d, g_settings.video.font_path, 0);
|
||||
if (!d3d->font_ctx)
|
||||
{
|
||||
RARCH_ERR("Failed to initialize font.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//OK
|
||||
bool d3d_restore(void *data)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
#ifdef _XBOX
|
||||
d3d_deinitialize(d3d);
|
||||
d3d->needs_restore = !d3d_initialize(d3d, &d3d->video_info);
|
||||
#else
|
||||
d3d->needs_restore = false;
|
||||
#endif
|
||||
|
||||
if (d3d->needs_restore)
|
||||
RARCH_ERR("[D3D]: Restore error.\n");
|
||||
|
||||
return !d3d->needs_restore;
|
||||
}
|
||||
|
||||
//OK
|
||||
static void d3d_set_viewport(void *data, int x, int y, unsigned width, unsigned height)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
D3DVIEWPORT viewport;
|
||||
|
||||
// D3D doesn't support negative X/Y viewports ...
|
||||
if (x < 0)
|
||||
x = 0;
|
||||
if (y < 0)
|
||||
y = 0;
|
||||
|
||||
viewport.Width = width;
|
||||
viewport.Height = height;
|
||||
viewport.X = x;
|
||||
viewport.Y = y;
|
||||
viewport.MinZ = 0.0f;
|
||||
viewport.MaxZ = 1.0f;
|
||||
|
||||
d3d->final_viewport = viewport;
|
||||
|
||||
#ifndef _XBOX
|
||||
d3d_set_font_rect(d3d, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
//OK
|
||||
static void d3d_calculate_rect(void *data, unsigned width, unsigned height,
|
||||
bool keep, float desired_aspect)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
if (g_settings.video.scale_integer)
|
||||
{
|
||||
struct rarch_viewport vp = {0};
|
||||
gfx_scale_integer(&vp, width, height, desired_aspect, keep);
|
||||
d3d_set_viewport(d3d, vp.x, vp.y, vp.width, vp.height);
|
||||
}
|
||||
else if (!keep)
|
||||
d3d_set_viewport(d3d, 0, 0, width, height);
|
||||
else
|
||||
{
|
||||
if (g_settings.video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
|
||||
{
|
||||
const rarch_viewport_t &custom = g_extern.console.screen.viewports.custom_vp;
|
||||
d3d_set_viewport(d3d, custom.x, custom.y, custom.width, custom.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
float device_aspect = static_cast<float>(width) / static_cast<float>(height);
|
||||
if (fabsf(device_aspect - desired_aspect) < 0.0001f)
|
||||
d3d_set_viewport(d3d, 0, 0, width, height);
|
||||
else if (device_aspect > desired_aspect)
|
||||
{
|
||||
float delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f;
|
||||
d3d_set_viewport(d3d, int(roundf(width * (0.5f - delta))), 0, unsigned(roundf(2.0f * width * delta)), height);
|
||||
}
|
||||
else
|
||||
{
|
||||
float delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f;
|
||||
d3d_set_viewport(d3d, 0, int(roundf(height * (0.5f - delta))), width, unsigned(roundf(2.0f * height * delta)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static void d3d_calculate_rect(void *data, unsigned width,
|
||||
unsigned height, bool keep, float desired_aspect);
|
||||
|
||||
static bool d3d_frame(void *data, const void *frame,
|
||||
unsigned width, unsigned height, unsigned pitch,
|
||||
|
@ -535,7 +289,7 @@ static bool d3d_frame(void *data, const void *frame,
|
|||
RARCH_PERFORMANCE_START(d3d_frame);
|
||||
|
||||
#ifndef _XBOX
|
||||
// We cannot recover in fullscreen.
|
||||
/* We cannot recover in fullscreen. */
|
||||
if (d3d->needs_restore && IsIconic(d3d->hWnd))
|
||||
return true;
|
||||
#endif
|
||||
|
@ -547,7 +301,8 @@ static bool d3d_frame(void *data, const void *frame,
|
|||
|
||||
if (d3d->should_resize)
|
||||
{
|
||||
d3d_calculate_rect(d3d, d3d->screen_width, d3d->screen_height, d3d->video_info.force_aspect, g_extern.system.aspect_ratio);
|
||||
d3d_calculate_rect(d3d, d3d->screen_width, d3d->screen_height,
|
||||
d3d->video_info.force_aspect, g_extern.system.aspect_ratio);
|
||||
#ifndef _XBOX
|
||||
renderchain_set_final_viewport(d3d->chain, &d3d->final_viewport);
|
||||
d3d_recompute_pass_sizes(d3d);
|
||||
|
@ -556,7 +311,8 @@ static bool d3d_frame(void *data, const void *frame,
|
|||
d3d->should_resize = false;
|
||||
}
|
||||
|
||||
// render_chain() only clears out viewport, clear out everything
|
||||
/* render_chain() only clears out viewport,
|
||||
* clear out everything. */
|
||||
screen_vp.X = 0;
|
||||
screen_vp.Y = 0;
|
||||
screen_vp.MinZ = 0;
|
||||
|
@ -566,7 +322,7 @@ static bool d3d_frame(void *data, const void *frame,
|
|||
d3dr->SetViewport(&screen_vp);
|
||||
d3dr->Clear(0, 0, D3DCLEAR_TARGET, 0, 1, 0);
|
||||
|
||||
// Insert black frame first, so we can screenshot, etc.
|
||||
/* Insert black frame first, so we can screenshot, etc. */
|
||||
if (g_settings.video.black_frame_insertion)
|
||||
{
|
||||
D3DDevice_Presents(d3d, d3dr);
|
||||
|
@ -576,9 +332,11 @@ static bool d3d_frame(void *data, const void *frame,
|
|||
}
|
||||
|
||||
#ifdef _XBOX
|
||||
renderchain_render_pass(d3d, frame, width, height, pitch, d3d->dev_rotation);
|
||||
renderchain_render_pass(d3d, frame, width, height,
|
||||
pitch, d3d->dev_rotation);
|
||||
#else
|
||||
if (!renderchain_render(d3d->chain, frame, width, height, pitch, d3d->dev_rotation))
|
||||
if (!renderchain_render(d3d->chain, frame, width, height,
|
||||
pitch, d3d->dev_rotation))
|
||||
{
|
||||
RARCH_ERR("[D3D]: Failed to render scene.\n");
|
||||
return false;
|
||||
|
@ -602,7 +360,8 @@ static bool d3d_frame(void *data, const void *frame,
|
|||
}
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
if (g_extern.lifecycle_state & (1ULL << MODE_MENU) && driver.menu_ctx && driver.menu_ctx->frame)
|
||||
if (g_extern.lifecycle_state & (1ULL << MODE_MENU)
|
||||
&& driver.menu_ctx && driver.menu_ctx->frame)
|
||||
driver.menu_ctx->frame();
|
||||
|
||||
if (d3d && d3d->menu_texture_enable)
|
||||
|
@ -620,81 +379,6 @@ static bool d3d_frame(void *data, const void *frame,
|
|||
return true;
|
||||
}
|
||||
|
||||
//OK
|
||||
static void d3d_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
d3d->video_info.vsync = !state;
|
||||
|
||||
if (d3d->ctx_driver && d3d->ctx_driver->swap_interval)
|
||||
d3d->ctx_driver->swap_interval(d3d, state ? 0 : 1);
|
||||
}
|
||||
|
||||
//OK
|
||||
static bool d3d_alive(void *data)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
bool quit, resize;
|
||||
|
||||
quit = false;
|
||||
resize = false;
|
||||
|
||||
if (d3d->ctx_driver && d3d->ctx_driver->check_window)
|
||||
d3d->ctx_driver->check_window(d3d, &quit, &resize, &d3d->screen_width,
|
||||
&d3d->screen_height, g_extern.frame_count);
|
||||
|
||||
if (quit)
|
||||
d3d->quitting = quit;
|
||||
else if (resize)
|
||||
d3d->should_resize = true;
|
||||
|
||||
return !quit;
|
||||
}
|
||||
|
||||
//OK
|
||||
static bool d3d_focus(void *data)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
if (d3d && d3d->ctx_driver && d3d->ctx_driver->has_focus)
|
||||
return d3d->ctx_driver->has_focus(d3d);
|
||||
return false;
|
||||
}
|
||||
|
||||
//OK
|
||||
static void d3d_set_aspect_ratio(void *data, unsigned aspect_ratio_idx)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
switch (aspect_ratio_idx)
|
||||
{
|
||||
case ASPECT_RATIO_SQUARE:
|
||||
gfx_set_square_pixel_viewport(g_extern.system.av_info.geometry.base_width, g_extern.system.av_info.geometry.base_height);
|
||||
break;
|
||||
|
||||
case ASPECT_RATIO_CORE:
|
||||
gfx_set_core_viewport();
|
||||
break;
|
||||
|
||||
case ASPECT_RATIO_CONFIG:
|
||||
gfx_set_config_viewport();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_extern.system.aspect_ratio = aspectratio_lut[aspect_ratio_idx].value;
|
||||
d3d->video_info.force_aspect = true;
|
||||
d3d->should_resize = true;
|
||||
}
|
||||
|
||||
//OK
|
||||
static void d3d_apply_state_changes(void *data)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
d3d->should_resize = true;
|
||||
}
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
static void d3d_set_texture_frame(void *data,
|
||||
const void *frame, bool rgb32, unsigned width, unsigned height,
|
||||
|
@ -715,20 +399,6 @@ static void d3d_set_texture_enable(void *data, bool state, bool full_screen)
|
|||
}
|
||||
#endif
|
||||
|
||||
//OK
|
||||
static void d3d_set_osd_msg(void *data, const char *msg, const struct font_params *params)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
|
||||
#ifndef _XBOX
|
||||
if (params)
|
||||
d3d_set_font_rect(d3d, params);
|
||||
#endif
|
||||
|
||||
if (d3d && d3d->font_ctx && d3d->font_ctx->render_msg)
|
||||
d3d->font_ctx->render_msg(d3d, msg, params);
|
||||
}
|
||||
|
||||
static const video_poke_interface_t d3d_poke_interface = {
|
||||
NULL,
|
||||
#ifdef HAVE_FBO
|
||||
|
@ -742,169 +412,29 @@ static const video_poke_interface_t d3d_poke_interface = {
|
|||
d3d_set_texture_enable,
|
||||
#endif
|
||||
d3d_set_osd_msg,
|
||||
|
||||
d3d_show_mouse,
|
||||
};
|
||||
|
||||
static void d3d_get_poke_interface(void *data, const video_poke_interface_t **iface)
|
||||
static void d3d_get_poke_interface(void *data,
|
||||
const video_poke_interface_t **iface)
|
||||
{
|
||||
(void)data;
|
||||
*iface = &d3d_poke_interface;
|
||||
}
|
||||
|
||||
// Delay constructor due to lack of exceptions.
|
||||
static bool d3d_construct(void *data, const video_info_t *info, const input_driver_t **input,
|
||||
void **input_data)
|
||||
{
|
||||
d3d_video_t *d3d = (d3d_video_t*)data;
|
||||
d3d->should_resize = false;
|
||||
#ifndef _XBOX
|
||||
gfx_set_dwm();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
if (d3d->menu)
|
||||
free(d3d->menu);
|
||||
|
||||
d3d->menu = (overlay_t*)calloc(1, sizeof(overlay_t));
|
||||
d3d->menu->tex_coords.x = 0;
|
||||
d3d->menu->tex_coords.y = 0;
|
||||
d3d->menu->tex_coords.w = 1;
|
||||
d3d->menu->tex_coords.h = 1;
|
||||
d3d->menu->vert_coords.x = 0;
|
||||
d3d->menu->vert_coords.y = 1;
|
||||
d3d->menu->vert_coords.w = 1;
|
||||
d3d->menu->vert_coords.h = -1;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINDOW
|
||||
memset(&d3d->windowClass, 0, sizeof(d3d->windowClass));
|
||||
d3d->windowClass.cbSize = sizeof(d3d->windowClass);
|
||||
d3d->windowClass.style = CS_HREDRAW | CS_VREDRAW;
|
||||
d3d->windowClass.lpfnWndProc = WindowProc;
|
||||
d3d->windowClass.hInstance = NULL;
|
||||
d3d->windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
d3d->windowClass.lpszClassName = "RetroArch";
|
||||
d3d->windowClass.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON));
|
||||
d3d->windowClass.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, 0);
|
||||
if (!info->fullscreen)
|
||||
d3d->windowClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
||||
|
||||
RegisterClassEx(&d3d->windowClass);
|
||||
#endif
|
||||
|
||||
unsigned full_x, full_y;
|
||||
#ifdef HAVE_MONITOR
|
||||
RECT mon_rect = d3d_monitor_rect(d3d);
|
||||
|
||||
bool windowed_full = g_settings.video.windowed_fullscreen;
|
||||
|
||||
full_x = (windowed_full || info->width == 0) ? (mon_rect.right - mon_rect.left) : info->width;
|
||||
full_y = (windowed_full || info->height == 0) ? (mon_rect.bottom - mon_rect.top) : info->height;
|
||||
RARCH_LOG("[D3D]: Monitor size: %dx%d.\n", (int)(mon_rect.right - mon_rect.left), (int)(mon_rect.bottom - mon_rect.top));
|
||||
#else
|
||||
if (d3d->ctx_driver && d3d->ctx_driver->get_video_size)
|
||||
d3d->ctx_driver->get_video_size(d3d, &full_x, &full_y);
|
||||
#endif
|
||||
|
||||
d3d->screen_width = info->fullscreen ? full_x : info->width;
|
||||
d3d->screen_height = info->fullscreen ? full_y : info->height;
|
||||
|
||||
#ifdef HAVE_WINDOW
|
||||
unsigned win_width = d3d->screen_width;
|
||||
unsigned win_height = d3d->screen_height;
|
||||
|
||||
if (!info->fullscreen)
|
||||
{
|
||||
RECT rect = {0};
|
||||
rect.right = d3d->screen_width;
|
||||
rect.bottom = d3d->screen_height;
|
||||
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
|
||||
win_width = rect.right - rect.left;
|
||||
win_height = rect.bottom - rect.top;
|
||||
}
|
||||
|
||||
char buffer[128];
|
||||
gfx_get_fps(buffer, sizeof(buffer), NULL, 0);
|
||||
std::string title = buffer;
|
||||
title += " || Direct3D";
|
||||
|
||||
d3d->hWnd = CreateWindowEx(0, "RetroArch", title.c_str(),
|
||||
info->fullscreen ?
|
||||
(WS_EX_TOPMOST | WS_POPUP) : WS_OVERLAPPEDWINDOW,
|
||||
info->fullscreen ? mon_rect.left : CW_USEDEFAULT,
|
||||
info->fullscreen ? mon_rect.top : CW_USEDEFAULT,
|
||||
win_width, win_height,
|
||||
NULL, NULL, NULL, d3d);
|
||||
|
||||
driver.display_type = RARCH_DISPLAY_WIN32;
|
||||
driver.video_display = 0;
|
||||
driver.video_window = (uintptr_t)d3d->hWnd;
|
||||
#endif
|
||||
|
||||
if (d3d && d3d->ctx_driver && d3d->ctx_driver->show_mouse)
|
||||
d3d->ctx_driver->show_mouse(d3d, !info->fullscreen
|
||||
#ifdef HAVE_OVERLAY
|
||||
|| d3d->overlays_enabled
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef HAVE_WINDOW
|
||||
ShowWindow(d3d->hWnd, SW_RESTORE);
|
||||
UpdateWindow(d3d->hWnd);
|
||||
SetForegroundWindow(d3d->hWnd);
|
||||
SetFocus(d3d->hWnd);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#ifdef HAVE_SHADERS
|
||||
// This should only be done once here
|
||||
// to avoid set_shader() to be overridden
|
||||
// later.
|
||||
enum rarch_shader_type type = gfx_shader_parse_type(g_settings.video.shader_path, RARCH_SHADER_NONE);
|
||||
if (g_settings.video.shader_enable && type == RARCH_SHADER_CG)
|
||||
d3d->cg_shader = g_settings.video.shader_path;
|
||||
|
||||
if (!d3d_process_shader(d3d))
|
||||
return false;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
d3d->video_info = *info;
|
||||
if (!d3d_initialize(d3d, &d3d->video_info))
|
||||
return false;
|
||||
|
||||
if (input && input_data &&
|
||||
d3d->ctx_driver && d3d->ctx_driver->input_driver)
|
||||
d3d->ctx_driver->input_driver(d3d, input, input_data);
|
||||
|
||||
RARCH_LOG("[D3D]: Init complete.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
//OK
|
||||
static const gfx_ctx_driver_t *d3d_get_context(void *data)
|
||||
{
|
||||
// TODO: GL core contexts through ANGLE?
|
||||
enum gfx_ctx_api api;
|
||||
unsigned major, minor;
|
||||
#if defined(_XBOX1)
|
||||
api = GFX_CTX_DIRECT3D8_API;
|
||||
major = 8;
|
||||
#elif defined(_XBOX360)
|
||||
api = GFX_CTX_DIRECT3D9_API;
|
||||
major = 9;
|
||||
#endif
|
||||
minor = 0;
|
||||
return gfx_ctx_init_first(driver.video_data, api, major, minor, false);
|
||||
}
|
||||
|
||||
static void *d3d_init(const video_info_t *info, const input_driver_t **input, void **input_data)
|
||||
static void *d3d_init(const video_info_t *info,
|
||||
const input_driver_t **input, void **input_data)
|
||||
{
|
||||
#ifdef _XBOX
|
||||
if (driver.video_data)
|
||||
{
|
||||
d3d_video_t *vid = (d3d_video_t*)driver.video_data;
|
||||
// Reinitialize renderchain as we might have changed pixel formats.
|
||||
|
||||
/* Reinitialize renderchain as we
|
||||
* might have changed pixel formats.*/
|
||||
d3d_reinit_renderchain(vid, info);
|
||||
|
||||
if (input && input_data)
|
||||
{
|
||||
*input = driver.input;
|
||||
|
@ -928,7 +458,7 @@ static void *d3d_init(const video_info_t *info, const input_driver_t **input, vo
|
|||
return NULL;
|
||||
}
|
||||
|
||||
//default values
|
||||
/* Default values */
|
||||
vid->g_pD3D = NULL;
|
||||
vid->dev = NULL;
|
||||
#ifndef _XBOX
|
||||
|
@ -961,7 +491,15 @@ static void *d3d_init(const video_info_t *info, const input_driver_t **input, vo
|
|||
return vid;
|
||||
}
|
||||
|
||||
const video_driver_t video_d3d = {
|
||||
static bool d3d_read_viewport(void *data, uint8_t *buffer)
|
||||
{
|
||||
(void)data;
|
||||
(void)buffer;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
video_driver_t video_d3d = {
|
||||
d3d_init,
|
||||
d3d_frame,
|
||||
d3d_set_nonblock_state,
|
||||
|
@ -972,7 +510,7 @@ const video_driver_t video_d3d = {
|
|||
"d3d",
|
||||
d3d_set_rotation,
|
||||
d3d_viewport_info,
|
||||
NULL, /* read_viewport */
|
||||
d3d_read_viewport,
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL, /* overlay_interface */
|
||||
#endif
|
||||
|
|
|
@ -1341,13 +1341,14 @@ static bool exynos_gfx_focus(void *data) {
|
|||
return true; /* drm device always has focus */
|
||||
}
|
||||
|
||||
static void exynos_gfx_set_rotation(void *data, unsigned rotation) {
|
||||
static void exynos_gfx_set_rotation(void *data, unsigned rotation)
|
||||
{
|
||||
struct exynos_video *vid = data;
|
||||
|
||||
vid->menu_rotation = rotation;
|
||||
}
|
||||
|
||||
static void exynos_gfx_viewport_info(void *data, struct rarch_viewport *vp) {
|
||||
static void exynos_gfx_viewport_info(void *data, struct rarch_viewport *vp)
|
||||
{
|
||||
struct exynos_video *vid = data;
|
||||
|
||||
vp->x = vp->y = 0;
|
||||
|
@ -1449,23 +1450,43 @@ static const video_poke_interface_t exynos_poke_interface = {
|
|||
exynos_show_mouse
|
||||
};
|
||||
|
||||
static void exynos_gfx_get_poke_interface(void *data, const video_poke_interface_t **iface) {
|
||||
(void)data;
|
||||
*iface = &exynos_poke_interface;
|
||||
static void exynos_gfx_get_poke_interface(void *data,
|
||||
const video_poke_interface_t **iface)
|
||||
{
|
||||
(void)data;
|
||||
*iface = &exynos_poke_interface;
|
||||
}
|
||||
|
||||
const video_driver_t video_exynos = {
|
||||
static bool exynos_gfx_set_shader(void *data,
|
||||
enum rarch_shader_type type, const char *path)
|
||||
{
|
||||
(void)data;
|
||||
(void)type;
|
||||
(void)path;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool exynos_gfx_read_viewport(void *data, uint8_t *buffer)
|
||||
{
|
||||
(void)data;
|
||||
(void)buffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
video_driver_t video_exynos = {
|
||||
exynos_gfx_init,
|
||||
exynos_gfx_frame,
|
||||
exynos_gfx_set_nonblock_state,
|
||||
exynos_gfx_alive,
|
||||
exynos_gfx_focus,
|
||||
NULL, /* set_shader */
|
||||
exynos_gfx_set_shader,
|
||||
exynos_gfx_free,
|
||||
"exynos",
|
||||
exynos_gfx_set_rotation,
|
||||
exynos_gfx_viewport_info,
|
||||
NULL, /* read_viewport */
|
||||
exynos_gfx_read_viewport,
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL, /* overlay_interface */
|
||||
|
|
2
gfx/gl.c
2
gfx/gl.c
|
@ -2963,7 +2963,7 @@ static void gl_get_poke_interface(void *data, const video_poke_interface_t **ifa
|
|||
*iface = &gl_poke_interface;
|
||||
}
|
||||
|
||||
const video_driver_t video_gl = {
|
||||
video_driver_t video_gl = {
|
||||
gl_init,
|
||||
gl_frame,
|
||||
gl_set_nonblock_state,
|
||||
|
|
|
@ -1128,6 +1128,13 @@ static void gx_viewport_info(void *data, struct rarch_viewport *vp)
|
|||
*vp = gx->vp;
|
||||
}
|
||||
|
||||
static bool gx_read_viewport(void *data, uint8_t *buffer)
|
||||
{
|
||||
(void)data;
|
||||
(void)buffer;
|
||||
return true;
|
||||
}
|
||||
|
||||
static const video_poke_interface_t gx_poke_interface = {
|
||||
NULL,
|
||||
gx_set_aspect_ratio,
|
||||
|
@ -1312,18 +1319,28 @@ static void gx_get_overlay_interface(void *data, const video_overlay_interface_t
|
|||
}
|
||||
#endif
|
||||
|
||||
const video_driver_t video_gx = {
|
||||
static bool gx_set_shader(void *data,
|
||||
enum rarch_shader_type type, const char *path)
|
||||
{
|
||||
(void)data;
|
||||
(void)type;
|
||||
(void)path;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
video_driver_t video_gx = {
|
||||
gx_init,
|
||||
gx_frame,
|
||||
gx_set_nonblock_state,
|
||||
gx_alive,
|
||||
gx_focus,
|
||||
NULL,
|
||||
gx_set_shader,
|
||||
gx_free,
|
||||
"gx",
|
||||
gx_set_rotation,
|
||||
gx_viewport_info,
|
||||
NULL,
|
||||
gx_read_viewport,
|
||||
#ifdef HAVE_OVERLAY
|
||||
gx_get_overlay_interface,
|
||||
#endif
|
||||
|
|
|
@ -62,15 +62,60 @@ static void null_gfx_free(void *data)
|
|||
(void)data;
|
||||
}
|
||||
|
||||
const video_driver_t video_null = {
|
||||
static bool null_gfx_set_shader(void *data,
|
||||
enum rarch_shader_type type, const char *path)
|
||||
{
|
||||
(void)data;
|
||||
(void)type;
|
||||
(void)path;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void null_gfx_set_rotation(void *data,
|
||||
unsigned rotation)
|
||||
{
|
||||
(void)data;
|
||||
(void)rotation;
|
||||
}
|
||||
|
||||
static void null_gfx_viewport_info(void *data,
|
||||
struct rarch_viewport *vp)
|
||||
{
|
||||
(void)data;
|
||||
(void)vp;
|
||||
}
|
||||
|
||||
static bool null_gfx_read_viewport(void *data, uint8_t *buffer)
|
||||
{
|
||||
(void)data;
|
||||
(void)buffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void null_gfx_get_poke_interface(void *data,
|
||||
const video_poke_interface_t **iface)
|
||||
{
|
||||
(void)data;
|
||||
(void)iface;
|
||||
}
|
||||
|
||||
video_driver_t video_null = {
|
||||
null_gfx_init,
|
||||
null_gfx_frame,
|
||||
null_gfx_set_nonblock_state,
|
||||
null_gfx_alive,
|
||||
null_gfx_focus,
|
||||
NULL,
|
||||
null_gfx_set_shader,
|
||||
null_gfx_free,
|
||||
"null",
|
||||
null_gfx_set_rotation,
|
||||
null_gfx_viewport_info,
|
||||
null_gfx_read_viewport,
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL, /* overlay_interface */
|
||||
#endif
|
||||
null_gfx_get_poke_interface,
|
||||
};
|
||||
|
||||
|
|
|
@ -879,22 +879,53 @@ static void omap_gfx_viewport_info(void *data, struct rarch_viewport *vp) {
|
|||
vp->height = vp->full_height = vid->height;
|
||||
}
|
||||
|
||||
const video_driver_t video_omap = {
|
||||
static bool omap_gfx_set_shader(void *data,
|
||||
enum rarch_shader_type type, const char *path)
|
||||
{
|
||||
(void)data;
|
||||
(void)type;
|
||||
(void)path;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void omap_gfx_set_rotation(void *data, unsigned rotation)
|
||||
{
|
||||
(void)data;
|
||||
(void)rotation;
|
||||
}
|
||||
|
||||
static bool omap_gfx_read_viewport(void *data, uint8_t *buffer)
|
||||
{
|
||||
(void)data;
|
||||
(void)buffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void omap_gfx_get_poke_interface(void *data,
|
||||
const video_poke_interface_t **iface)
|
||||
{
|
||||
(void)data;
|
||||
(void)iface;
|
||||
}
|
||||
|
||||
video_driver_t video_omap = {
|
||||
omap_gfx_init,
|
||||
omap_gfx_frame,
|
||||
omap_gfx_set_nonblock_state,
|
||||
omap_gfx_alive,
|
||||
omap_gfx_focus,
|
||||
NULL, /* set_shader */
|
||||
omap_gfx_set_shader,
|
||||
omap_gfx_free,
|
||||
"omap",
|
||||
|
||||
NULL, /* set_rotation */
|
||||
omap_gfx_set_rotation,
|
||||
omap_gfx_viewport_info,
|
||||
NULL, /* read_viewport */
|
||||
omap_gfx_read_viewport,
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL, /* overlay_interface */
|
||||
#endif
|
||||
NULL /* poke_interface */
|
||||
omap_gfx_get_poke_interface
|
||||
};
|
||||
|
|
|
@ -773,7 +773,7 @@ static void psp_viewport_info(void *data, struct rarch_viewport *vp)
|
|||
|
||||
static bool psp_read_viewport(void *data, uint8_t *buffer)
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static const video_poke_interface_t psp_poke_interface = {
|
||||
|
@ -796,19 +796,37 @@ static void psp_get_poke_interface(void *data,
|
|||
*iface = &psp_poke_interface;
|
||||
}
|
||||
|
||||
const video_driver_t video_psp1 = {
|
||||
static bool psp_read_viewport(void *data, uint8_t *buffer)
|
||||
{
|
||||
(void)data;
|
||||
(void)buffer;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool psp_set_shader(void *data,
|
||||
enum rarch_shader_type type, const char *path)
|
||||
{
|
||||
(void)data;
|
||||
(void)type;
|
||||
(void)path;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
video_driver_t video_psp1 = {
|
||||
psp_init,
|
||||
psp_frame,
|
||||
psp_set_nonblock_state,
|
||||
psp_alive,
|
||||
psp_focus,
|
||||
NULL,
|
||||
psp_set_shader,
|
||||
psp_free,
|
||||
"psp1",
|
||||
|
||||
psp_set_rotation,
|
||||
psp_viewport_info,
|
||||
NULL, /* psp_read_viewport */
|
||||
psp_read_viewport,
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL,
|
||||
#endif
|
||||
|
|
|
@ -704,13 +704,23 @@ void sdl2_gfx_poke_interface(void *data, const video_poke_interface_t **iface)
|
|||
*iface = &sdl2_video_poke_interface;
|
||||
}
|
||||
|
||||
const video_driver_t video_sdl2 = {
|
||||
static bool sdl2_gfx_set_shader(void *data,
|
||||
enum rarch_shader_type type, const char *path)
|
||||
{
|
||||
(void)data;
|
||||
(void)type;
|
||||
(void)path;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
video_driver_t video_sdl2 = {
|
||||
sdl2_gfx_init,
|
||||
sdl2_gfx_frame,
|
||||
sdl2_gfx_set_nonblock_state,
|
||||
sdl2_gfx_alive,
|
||||
sdl2_gfx_focus,
|
||||
NULL,
|
||||
sdl2_gfx_set_shader,
|
||||
sdl2_gfx_free,
|
||||
"sdl2",
|
||||
|
||||
|
|
|
@ -492,22 +492,44 @@ static void sdl_get_poke_interface(void *data, const video_poke_interface_t **if
|
|||
*iface = &sdl_poke_interface;
|
||||
}
|
||||
|
||||
const video_driver_t video_sdl = {
|
||||
static bool sdl_gfx_set_shader(void *data,
|
||||
enum rarch_shader_type type, const char *path)
|
||||
{
|
||||
(void)data;
|
||||
(void)type;
|
||||
(void)path;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void sdl_gfx_set_rotation(void *data, unsigned rotation)
|
||||
{
|
||||
(void)data;
|
||||
(void)rotation;
|
||||
}
|
||||
|
||||
static bool sdl_gfx_read_viewport(void *data, uint8_t *buffer)
|
||||
{
|
||||
(void)data;
|
||||
(void)buffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
video_driver_t video_sdl = {
|
||||
sdl_gfx_init,
|
||||
sdl_gfx_frame,
|
||||
sdl_gfx_set_nonblock_state,
|
||||
sdl_gfx_alive,
|
||||
sdl_gfx_focus,
|
||||
NULL,
|
||||
sdl_gfx_set_shader,
|
||||
sdl_gfx_free,
|
||||
"sdl",
|
||||
|
||||
NULL,
|
||||
sdl_gfx_set_rotation,
|
||||
sdl_gfx_viewport_info,
|
||||
NULL,
|
||||
sdl_gfx_read_viewport,
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL,
|
||||
#endif
|
||||
sdl_get_poke_interface
|
||||
};
|
||||
|
||||
|
|
51
gfx/vg.c
51
gfx/vg.c
|
@ -413,13 +413,58 @@ static bool vg_focus(void *data)
|
|||
return vg->driver->has_focus(vg);
|
||||
}
|
||||
|
||||
const video_driver_t video_vg = {
|
||||
static bool vg_set_shader(void *data,
|
||||
enum rarch_shader_type type, const char *path)
|
||||
{
|
||||
(void)data;
|
||||
(void)type;
|
||||
(void)path;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void vg_set_rotation(void *data, unsigned rotation)
|
||||
{
|
||||
(void)data;
|
||||
(void)rotation;
|
||||
}
|
||||
|
||||
static void vg_viewport_info(void *data,
|
||||
struct rarch_viewport *vp)
|
||||
{
|
||||
(void)data;
|
||||
(void)vp;
|
||||
}
|
||||
|
||||
static bool vg_read_viewport(void *data, uint8_t *buffer)
|
||||
{
|
||||
(void)data;
|
||||
(void)buffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void vg_get_poke_interface(void *data,
|
||||
const video_poke_interface_t **iface)
|
||||
{
|
||||
(void)data;
|
||||
(void)iface;
|
||||
}
|
||||
|
||||
video_driver_t video_vg = {
|
||||
vg_init,
|
||||
vg_frame,
|
||||
vg_set_nonblock_state,
|
||||
vg_alive,
|
||||
vg_focus,
|
||||
NULL,
|
||||
vg_set_shader,
|
||||
vg_free,
|
||||
"vg"
|
||||
"vg",
|
||||
vg_set_rotation,
|
||||
vg_viewport_info,
|
||||
vg_read_viewport,
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL, /* overlay_interface */
|
||||
#endif
|
||||
vg_get_poke_interface
|
||||
};
|
||||
|
|
|
@ -263,14 +263,58 @@ static void xenon360_gfx_set_rotation(void *data, unsigned rotation)
|
|||
(void)rotation;
|
||||
}
|
||||
|
||||
const video_driver_t video_xenon360 = {
|
||||
static bool xenon360_gfx_set_shader(void *data,
|
||||
enum rarch_shader_type type, const char *path)
|
||||
{
|
||||
(void)data;
|
||||
(void)type;
|
||||
(void)path;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void xenon360_gfx_set_rotation(void *data, unsigned rotation)
|
||||
{
|
||||
(void)data;
|
||||
(void)rotation;
|
||||
}
|
||||
|
||||
static void xenon360_gfx_viewport_info(void *data, struct rarch_viewport *vp)
|
||||
{
|
||||
(void)data;
|
||||
(void)vp;
|
||||
}
|
||||
|
||||
static bool xenon360_gfx_read_viewport(void *data, uint8_t *buffer)
|
||||
{
|
||||
(void)data;
|
||||
(void)buffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void xenon360_gfx_get_poke_interface(void *data,
|
||||
const video_poke_interface_t **iface)
|
||||
{
|
||||
(void)data;
|
||||
(void)iface;
|
||||
}
|
||||
|
||||
video_driver_t video_xenon360 = {
|
||||
xenon360_gfx_init,
|
||||
xenon360_gfx_frame,
|
||||
xenon360_gfx_set_nonblock_state,
|
||||
xenon360_gfx_alive,
|
||||
xenon360_gfx_focus,
|
||||
NULL,
|
||||
xenon360_gfx_set_shader,
|
||||
xenon360_gfx_free,
|
||||
"xenon360"
|
||||
};
|
||||
"xenon360",
|
||||
xenon360_gfx_set_rotation,
|
||||
xenon360_gfx_viewport_info,
|
||||
xenon360_gfx_read_viewport,
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL, /* overlay_interface */
|
||||
#endif
|
||||
xenon360_gfx_get_poke_interface
|
||||
};
|
||||
|
|
44
gfx/xvideo.c
44
gfx/xvideo.c
|
@ -809,17 +809,51 @@ static void xv_viewport_info(void *data, struct rarch_viewport *vp)
|
|||
*vp = xv->vp;
|
||||
}
|
||||
|
||||
const video_driver_t video_xvideo = {
|
||||
static void xv_set_rotation(void *data, unsigned rotation)
|
||||
{
|
||||
(void)data;
|
||||
(void)rotation;
|
||||
}
|
||||
|
||||
static bool xv_read_viewport(void *data, uint8_t *buffer)
|
||||
{
|
||||
(void)data;
|
||||
(void)buffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void xv_get_poke_interface(void *data,
|
||||
const video_poke_interface_t **iface)
|
||||
{
|
||||
(void)data;
|
||||
(void)iface;
|
||||
}
|
||||
|
||||
static bool xv_set_shader(void *data,
|
||||
enum rarch_shader_type type, const char *path)
|
||||
{
|
||||
(void)data;
|
||||
(void)type;
|
||||
(void)path;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
video_driver_t video_xvideo = {
|
||||
xv_init,
|
||||
xv_frame,
|
||||
xv_set_nonblock_state,
|
||||
xv_alive,
|
||||
xv_focus,
|
||||
NULL,
|
||||
xv_set_shader,
|
||||
xv_free,
|
||||
"xvideo",
|
||||
|
||||
NULL,
|
||||
xv_set_rotation,
|
||||
xv_viewport_info,
|
||||
xv_read_viewport,
|
||||
#ifdef HAVE_OVERLAY
|
||||
NULL, /* overlay_interface */
|
||||
#endif
|
||||
xv_get_poke_interface
|
||||
};
|
||||
|
||||
|
|
|
@ -355,10 +355,10 @@ FIFO BUFFER
|
|||
/*============================================================
|
||||
AUDIO RESAMPLER
|
||||
============================================================ */
|
||||
#include "../audio/resampler.c"
|
||||
#include "../audio/sinc.c"
|
||||
#include "../audio/resamplers/resampler.c"
|
||||
#include "../audio/resamplers/sinc.c"
|
||||
#ifdef HAVE_CC_RESAMPLER
|
||||
#include "../audio/cc_resampler.c"
|
||||
#include "../audio/resamplers/cc_resampler.c"
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
|
@ -622,6 +622,7 @@ MENU
|
|||
#endif
|
||||
|
||||
#if defined(HAVE_LAKKA) && defined(HAVE_OPENGL)
|
||||
#include "../frontend/menu/backend/menu_lakka_backend.c"
|
||||
#include "../frontend/menu/disp/lakka.c"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -752,7 +752,7 @@ static const rarch_joypad_driver_t *android_input_get_joypad_driver(void *data)
|
|||
return android->joypad;
|
||||
}
|
||||
|
||||
const input_driver_t input_android = {
|
||||
input_driver_t input_android = {
|
||||
android_input_init,
|
||||
android_input_poll,
|
||||
android_input_state,
|
||||
|
|
|
@ -64,13 +64,19 @@ static bool android_joypad_button(unsigned port_num, uint16_t joykey)
|
|||
unsigned h = GET_HAT(joykey);
|
||||
if (h > 0)
|
||||
return false;
|
||||
|
||||
switch (GET_HAT_DIR(joykey))
|
||||
{
|
||||
case HAT_LEFT_MASK: return android->hat_state[port_num][0] == -1;
|
||||
case HAT_RIGHT_MASK: return android->hat_state[port_num][0] == 1;
|
||||
case HAT_UP_MASK: return android->hat_state[port_num][1] == -1;
|
||||
case HAT_DOWN_MASK: return android->hat_state[port_num][1] == 1;
|
||||
default: return false;
|
||||
case HAT_LEFT_MASK:
|
||||
return android->hat_state[port_num][0] == -1;
|
||||
case HAT_RIGHT_MASK:
|
||||
return android->hat_state[port_num][0] == 1;
|
||||
case HAT_UP_MASK:
|
||||
return android->hat_state[port_num][1] == -1;
|
||||
case HAT_DOWN_MASK:
|
||||
return android->hat_state[port_num][1] == 1;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return joykey < LAST_KEYCODE && get_bit(android->pad_state[port_num],
|
||||
|
@ -125,7 +131,7 @@ static void android_joypad_destroy(void)
|
|||
{
|
||||
}
|
||||
|
||||
const rarch_joypad_driver_t android_joypad = {
|
||||
rarch_joypad_driver_t android_joypad = {
|
||||
android_joypad_init,
|
||||
android_joypad_query_pad,
|
||||
android_joypad_destroy,
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "input_common.h"
|
||||
|
@ -248,7 +248,7 @@ static const rarch_joypad_driver_t *joypad;
|
|||
apple_input_data_t g_current_input_data;
|
||||
|
||||
#ifdef OSX // Taken from https://github.com/depp/keycode, check keycode.h for license
|
||||
const unsigned char MAC_NATIVE_TO_HID[128] = {
|
||||
static const unsigned char MAC_NATIVE_TO_HID[128] = {
|
||||
4, 22, 7, 9, 11, 10, 29, 27, 6, 25,255, 5, 20, 26, 8, 21,
|
||||
28, 23, 30, 31, 32, 33, 35, 34, 46, 38, 36, 45, 37, 39, 48, 18,
|
||||
24, 47, 12, 19, 40, 15, 13, 52, 14, 51, 49, 54, 56, 17, 16, 55,
|
||||
|
@ -498,14 +498,14 @@ static void *apple_input_init(void)
|
|||
|
||||
static void apple_input_poll(void *data)
|
||||
{
|
||||
int i;
|
||||
uint32_t i;
|
||||
(void)data;
|
||||
|
||||
#ifdef IOS
|
||||
apple_gamecontroller_poll_all();
|
||||
#endif
|
||||
|
||||
for (i = 0; i < g_current_input_data.touch_count; i ++)
|
||||
for (i = 0; i < g_current_input_data.touch_count; i++)
|
||||
{
|
||||
input_translate_coord_viewport(g_current_input_data.touches[i].screen_x, g_current_input_data.touches[i].screen_y,
|
||||
&g_current_input_data.touches[i].fixed_x, &g_current_input_data.touches[i].fixed_y,
|
||||
|
@ -623,7 +623,7 @@ static const rarch_joypad_driver_t *apple_get_joypad_driver(void *data)
|
|||
return joypad;
|
||||
}
|
||||
|
||||
const input_driver_t input_apple = {
|
||||
input_driver_t input_apple = {
|
||||
apple_input_init,
|
||||
apple_input_poll,
|
||||
apple_input_state,
|
||||
|
|
|
@ -35,24 +35,31 @@ struct apple_pad_connection
|
|||
|
||||
static IOHIDManagerRef g_hid_manager;
|
||||
|
||||
static void apple_pad_send_control(struct apple_pad_connection* connection, uint8_t* data, size_t size)
|
||||
static void apple_pad_send_control(struct apple_pad_connection* connection,
|
||||
uint8_t* data, size_t size)
|
||||
{
|
||||
IOHIDDeviceSetReport(connection->device, kIOHIDReportTypeOutput, 0x01, data + 1, size - 1);
|
||||
IOHIDDeviceSetReport(connection->device,
|
||||
kIOHIDReportTypeOutput, 0x01, data + 1, size - 1);
|
||||
}
|
||||
|
||||
// NOTE: I pieced this together through trial and error, any corrections are welcome
|
||||
static void hid_device_input_callback(void* context, IOReturn result, void* sender, IOHIDValueRef value)
|
||||
/* NOTE: I pieced this together through trial and error,
|
||||
* any corrections are welcome. */
|
||||
|
||||
static void hid_device_input_callback(void* context, IOReturn result,
|
||||
void* sender, IOHIDValueRef value)
|
||||
{
|
||||
IOHIDElementRef element;
|
||||
uint32_t type, page, use;
|
||||
struct apple_pad_connection* connection = (struct apple_pad_connection*)context;
|
||||
struct apple_pad_connection* connection = (struct apple_pad_connection*)
|
||||
context;
|
||||
|
||||
element = IOHIDValueGetElement(value);
|
||||
type = IOHIDElementGetType(element);
|
||||
page = IOHIDElementGetUsagePage(element);
|
||||
use = IOHIDElementGetUsage(element);
|
||||
|
||||
// Joystick handler: TODO: Can GamePad work the same?
|
||||
/* Joystick handler.
|
||||
* TODO: Can GamePad work the same? */
|
||||
if (type == kIOHIDElementTypeInput_Button && page == kHIDPage_Button)
|
||||
{
|
||||
CFIndex state = IOHIDValueGetIntegerValue(value);
|
||||
|
@ -79,7 +86,8 @@ static void hid_device_input_callback(void* context, IOReturn result, void* send
|
|||
state = IOHIDValueGetIntegerValue(value) - min;
|
||||
|
||||
val = (float)state / (float)max;
|
||||
g_current_input_data.pad_axis[connection->slot][i] = ((val * 2.0f) - 1.0f) * 32767.0f;
|
||||
g_current_input_data.pad_axis[connection->slot][i] =
|
||||
((val * 2.0f) - 1.0f) * 32767.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,12 +95,14 @@ static void hid_device_input_callback(void* context, IOReturn result, void* send
|
|||
|
||||
static void hid_device_removed(void* context, IOReturn result, void* sender)
|
||||
{
|
||||
struct apple_pad_connection* connection = (struct apple_pad_connection*)context;
|
||||
struct apple_pad_connection* connection = (struct apple_pad_connection*)
|
||||
context;
|
||||
|
||||
if (connection && connection->slot < MAX_PLAYERS)
|
||||
{
|
||||
g_current_input_data.pad_buttons[connection->slot] = 0;
|
||||
memset(g_current_input_data.pad_axis[connection->slot], 0, sizeof(g_current_input_data.pad_axis));
|
||||
memset(g_current_input_data.pad_axis[connection->slot],
|
||||
0, sizeof(g_current_input_data.pad_axis));
|
||||
|
||||
apple_joypad_disconnect(connection->slot);
|
||||
free(connection);
|
||||
|
@ -101,49 +111,63 @@ static void hid_device_removed(void* context, IOReturn result, void* sender)
|
|||
IOHIDDeviceClose(sender, kIOHIDOptionsTypeNone);
|
||||
}
|
||||
|
||||
static void hid_device_report(void* context, IOReturn result, void *sender, IOHIDReportType type, uint32_t reportID, uint8_t *report, CFIndex reportLength)
|
||||
static void hid_device_report(void* context, IOReturn result, void *sender,
|
||||
IOHIDReportType type, uint32_t reportID, uint8_t *report,
|
||||
CFIndex reportLength)
|
||||
{
|
||||
struct apple_pad_connection* connection = (struct apple_pad_connection*)context;
|
||||
struct apple_pad_connection* connection = (struct apple_pad_connection*)
|
||||
context;
|
||||
apple_joypad_packet(connection->slot, connection->data, reportLength + 1);
|
||||
}
|
||||
|
||||
static void hid_manager_device_attached(void* context, IOReturn result, void* sender, IOHIDDeviceRef device)
|
||||
static void hid_manager_device_attached(void* context, IOReturn result,
|
||||
void* sender, IOHIDDeviceRef device)
|
||||
{
|
||||
char device_name[1024];
|
||||
CFStringRef device_name_ref;
|
||||
struct apple_pad_connection* connection = (struct apple_pad_connection*)calloc(1, sizeof(*connection));
|
||||
struct apple_pad_connection* connection = (struct apple_pad_connection*)
|
||||
calloc(1, sizeof(*connection));
|
||||
|
||||
connection->device = device;
|
||||
connection->slot = MAX_PLAYERS;
|
||||
|
||||
IOHIDDeviceOpen(device, kIOHIDOptionsTypeNone);
|
||||
IOHIDDeviceScheduleWithRunLoop(device, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
|
||||
IOHIDDeviceScheduleWithRunLoop(device, CFRunLoopGetCurrent(),
|
||||
kCFRunLoopCommonModes);
|
||||
IOHIDDeviceRegisterRemovalCallback(device, hid_device_removed, connection);
|
||||
|
||||
device_name_ref = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
|
||||
CFStringGetCString(device_name_ref, device_name, sizeof(device_name), kCFStringEncodingUTF8);
|
||||
CFStringGetCString(device_name_ref, device_name,
|
||||
sizeof(device_name), kCFStringEncodingUTF8);
|
||||
|
||||
connection->slot = apple_joypad_connect(device_name, connection);
|
||||
|
||||
if (apple_joypad_has_interface(connection->slot))
|
||||
IOHIDDeviceRegisterInputReportCallback(device, connection->data + 1, sizeof(connection->data) - 1, hid_device_report, connection);
|
||||
IOHIDDeviceRegisterInputReportCallback(device,
|
||||
connection->data + 1, sizeof(connection->data) - 1,
|
||||
hid_device_report, connection);
|
||||
else
|
||||
IOHIDDeviceRegisterInputValueCallback(device, hid_device_input_callback, connection);
|
||||
IOHIDDeviceRegisterInputValueCallback(device,
|
||||
hid_device_input_callback, connection);
|
||||
|
||||
if (device_name[0] != '\0')
|
||||
{
|
||||
strlcpy(g_settings.input.device_names[connection->slot], device_name, sizeof(g_settings.input.device_names));
|
||||
input_config_autoconfigure_joypad(connection->slot, device_name, apple_joypad.ident);
|
||||
strlcpy(g_settings.input.device_names[connection->slot],
|
||||
device_name, sizeof(g_settings.input.device_names));
|
||||
input_config_autoconfigure_joypad(connection->slot,
|
||||
device_name, apple_joypad.ident);
|
||||
RARCH_LOG("Port %d: %s.\n", connection->slot, device_name);
|
||||
}
|
||||
}
|
||||
|
||||
static void append_matching_dictionary(CFMutableArrayRef array, uint32_t page, uint32_t use)
|
||||
static void append_matching_dictionary(CFMutableArrayRef array,
|
||||
uint32_t page, uint32_t use)
|
||||
{
|
||||
CFNumberRef pagen, usen;
|
||||
CFMutableDictionaryRef matcher;
|
||||
|
||||
matcher = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
||||
matcher = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
|
||||
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
||||
|
||||
pagen = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page);
|
||||
CFDictionarySetValue(matcher, CFSTR(kIOHIDDeviceUsagePageKey), pagen);
|
||||
|
@ -188,7 +212,8 @@ static int32_t find_empty_slot(void)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int32_t apple_joypad_connect(const char* name, struct apple_pad_connection* connection)
|
||||
int32_t apple_joypad_connect(const char* name,
|
||||
struct apple_pad_connection* connection)
|
||||
{
|
||||
int32_t slot;
|
||||
slot = find_empty_slot();
|
||||
|
@ -276,7 +301,8 @@ static bool apple_joypad_init(void)
|
|||
|
||||
if (!g_hid_manager)
|
||||
{
|
||||
g_hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
|
||||
g_hid_manager = IOHIDManagerCreate(
|
||||
kCFAllocatorDefault, kIOHIDOptionsTypeNone);
|
||||
|
||||
matcher = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
||||
append_matching_dictionary(matcher, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick);
|
||||
|
@ -316,7 +342,8 @@ static void apple_joypad_destroy(void)
|
|||
if (g_hid_manager)
|
||||
{
|
||||
IOHIDManagerClose(g_hid_manager, kIOHIDOptionsTypeNone);
|
||||
IOHIDManagerUnscheduleFromRunLoop(g_hid_manager, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
|
||||
IOHIDManagerUnscheduleFromRunLoop(g_hid_manager,
|
||||
CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
|
||||
|
||||
CFRelease(g_hid_manager);
|
||||
}
|
||||
|
@ -333,7 +360,8 @@ static bool apple_joypad_button(unsigned port, uint16_t joykey)
|
|||
if (GET_HAT_DIR(joykey))
|
||||
return false;
|
||||
// Check the button
|
||||
return (port < MAX_PLAYERS && joykey < 32) ? (g_current_input_data.pad_buttons[port] & (1 << joykey)) != 0 : false;
|
||||
return (port < MAX_PLAYERS && joykey < 32) ?
|
||||
(g_current_input_data.pad_buttons[port] & (1 << joykey)) != 0 : false;
|
||||
}
|
||||
|
||||
static int16_t apple_joypad_axis(unsigned port, uint32_t joyaxis)
|
||||
|
@ -363,7 +391,8 @@ static void apple_joypad_poll(void)
|
|||
{
|
||||
}
|
||||
|
||||
static bool apple_joypad_rumble(unsigned pad, enum retro_rumble_effect effect, uint16_t strength)
|
||||
static bool apple_joypad_rumble(unsigned pad,
|
||||
enum retro_rumble_effect effect, uint16_t strength)
|
||||
{
|
||||
if (pad < MAX_PLAYERS && slots[pad].used && slots[pad].iface
|
||||
&& slots[pad].iface->set_rumble)
|
||||
|
@ -381,7 +410,7 @@ static const char *apple_joypad_name(unsigned joypad)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
const rarch_joypad_driver_t apple_joypad = {
|
||||
rarch_joypad_driver_t apple_joypad = {
|
||||
apple_joypad_init,
|
||||
apple_joypad_query_pad,
|
||||
apple_joypad_destroy,
|
||||
|
|
184
input/dinput.c
184
input/dinput.c
|
@ -29,7 +29,7 @@
|
|||
#include <string.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
// Context has to be global as joypads also ride on this context.
|
||||
/* Context has to be global as joypads also ride on this context. */
|
||||
static LPDIRECTINPUT8 g_ctx;
|
||||
|
||||
struct pointer_status
|
||||
|
@ -52,7 +52,7 @@ struct dinput_input
|
|||
int mouse_x;
|
||||
int mouse_y;
|
||||
bool mouse_l, mouse_r, mouse_m, mouse_wu, mouse_wd;
|
||||
struct pointer_status pointer_head; // dummy head for easier iteration
|
||||
struct pointer_status pointer_head; /* dummy head for easier iteration */
|
||||
};
|
||||
|
||||
struct dinput_joypad
|
||||
|
@ -81,7 +81,7 @@ static bool dinput_init_context(void)
|
|||
|
||||
CoInitialize(NULL);
|
||||
|
||||
// Who said we shouldn't have same call signature in a COM API? <_<
|
||||
/* Who said we shouldn't have same call signature in a COM API? <_< */
|
||||
#ifdef __cplusplus
|
||||
if (FAILED(DirectInput8Create(
|
||||
GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8,
|
||||
|
@ -165,10 +165,12 @@ static void dinput_poll(void *data)
|
|||
memset(di->state, 0, sizeof(di->state));
|
||||
if (di->keyboard)
|
||||
{
|
||||
if (FAILED(IDirectInputDevice8_GetDeviceState(di->keyboard, sizeof(di->state), di->state)))
|
||||
if (FAILED(IDirectInputDevice8_GetDeviceState(
|
||||
di->keyboard, sizeof(di->state), di->state)))
|
||||
{
|
||||
IDirectInputDevice8_Acquire(di->keyboard);
|
||||
if (FAILED(IDirectInputDevice8_GetDeviceState(di->keyboard, sizeof(di->state), di->state)))
|
||||
if (FAILED(IDirectInputDevice8_GetDeviceState(
|
||||
di->keyboard, sizeof(di->state), di->state)))
|
||||
memset(di->state, 0, sizeof(di->state));
|
||||
}
|
||||
}
|
||||
|
@ -178,10 +180,12 @@ static void dinput_poll(void *data)
|
|||
DIMOUSESTATE2 mouse_state;
|
||||
memset(&mouse_state, 0, sizeof(mouse_state));
|
||||
|
||||
if (FAILED(IDirectInputDevice8_GetDeviceState(di->mouse, sizeof(mouse_state), &mouse_state)))
|
||||
if (FAILED(IDirectInputDevice8_GetDeviceState(
|
||||
di->mouse, sizeof(mouse_state), &mouse_state)))
|
||||
{
|
||||
IDirectInputDevice8_Acquire(di->mouse);
|
||||
if (FAILED(IDirectInputDevice8_GetDeviceState(di->mouse, sizeof(mouse_state), &mouse_state)))
|
||||
if (FAILED(IDirectInputDevice8_GetDeviceState(
|
||||
di->mouse, sizeof(mouse_state), &mouse_state)))
|
||||
memset(&mouse_state, 0, sizeof(mouse_state));
|
||||
}
|
||||
|
||||
|
@ -193,7 +197,8 @@ static void dinput_poll(void *data)
|
|||
di->mouse_wu = mouse_state.rgbButtons[3];
|
||||
di->mouse_wd = mouse_state.rgbButtons[4];
|
||||
|
||||
// No simple way to get absolute coordinates for RETRO_DEVICE_POINTER. Just use Win32 APIs.
|
||||
/* No simple way to get absolute coordinates
|
||||
* for RETRO_DEVICE_POINTER. Just use Win32 APIs. */
|
||||
POINT point = {0};
|
||||
GetCursorPos(&point);
|
||||
ScreenToClient((HWND)driver.video_window, &point);
|
||||
|
@ -214,14 +219,16 @@ static bool dinput_keyboard_pressed(struct dinput_input *di, unsigned key)
|
|||
return di->state[sym] & 0x80;
|
||||
}
|
||||
|
||||
static bool dinput_is_pressed(struct dinput_input *di, const struct retro_keybind *binds,
|
||||
static bool dinput_is_pressed(struct dinput_input *di,
|
||||
const struct retro_keybind *binds,
|
||||
unsigned port, unsigned id)
|
||||
{
|
||||
if (id >= RARCH_BIND_LIST_END)
|
||||
return false;
|
||||
|
||||
const struct retro_keybind *bind = &binds[id];
|
||||
return dinput_keyboard_pressed(di, bind->key) || input_joypad_pressed(di->joypad, port, binds, id);
|
||||
return dinput_keyboard_pressed(di, bind->key) ||
|
||||
input_joypad_pressed(di->joypad, port, binds, id);
|
||||
}
|
||||
|
||||
static int16_t dinput_pressed_analog(struct dinput_input *di,
|
||||
|
@ -237,14 +244,17 @@ static int16_t dinput_pressed_analog(struct dinput_input *di,
|
|||
if (!bind_minus->valid || !bind_plus->valid)
|
||||
return 0;
|
||||
|
||||
int16_t pressed_minus = dinput_keyboard_pressed(di, bind_minus->key) ? -0x7fff : 0;
|
||||
int16_t pressed_plus = dinput_keyboard_pressed(di, bind_plus->key) ? 0x7fff : 0;
|
||||
int16_t pressed_minus =
|
||||
dinput_keyboard_pressed(di, bind_minus->key) ? -0x7fff : 0;
|
||||
int16_t pressed_plus =
|
||||
dinput_keyboard_pressed(di, bind_plus->key) ? 0x7fff : 0;
|
||||
return pressed_plus + pressed_minus;
|
||||
}
|
||||
|
||||
static bool dinput_key_pressed(void *data, int key)
|
||||
{
|
||||
return dinput_is_pressed((struct dinput_input*)data, g_settings.input.binds[0], 0, key);
|
||||
return dinput_is_pressed((struct dinput_input*)data,
|
||||
g_settings.input.binds[0], 0, key);
|
||||
}
|
||||
|
||||
static int16_t dinput_lightgun_state(struct dinput_input *di, unsigned id)
|
||||
|
@ -265,9 +275,9 @@ static int16_t dinput_lightgun_state(struct dinput_input *di, unsigned id)
|
|||
return di->mouse_m && di->mouse_r;
|
||||
case RETRO_DEVICE_ID_LIGHTGUN_PAUSE:
|
||||
return di->mouse_m && di->mouse_l;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int16_t dinput_mouse_state(struct dinput_input *di, unsigned id)
|
||||
|
@ -288,12 +298,13 @@ static int16_t dinput_mouse_state(struct dinput_input *di, unsigned id)
|
|||
return di->mouse_wd;
|
||||
case RETRO_DEVICE_ID_MOUSE_MIDDLE:
|
||||
return di->mouse_m;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int16_t dinput_pointer_state(struct dinput_input *di, unsigned index, unsigned id, bool screen)
|
||||
static int16_t dinput_pointer_state(struct dinput_input *di,
|
||||
unsigned index, unsigned id, bool screen)
|
||||
{
|
||||
int16_t res_x = 0, res_y = 0, res_screen_x = 0, res_screen_y = 0;
|
||||
unsigned num = 0;
|
||||
|
@ -303,7 +314,7 @@ static int16_t dinput_pointer_state(struct dinput_input *di, unsigned index, uns
|
|||
num++;
|
||||
check_pos = check_pos->next;
|
||||
}
|
||||
if (!check_pos && index > 0) // index = 0 has mouse fallback
|
||||
if (!check_pos && index > 0) /* index = 0 has mouse fallback. */
|
||||
return 0;
|
||||
|
||||
int x = check_pos ? check_pos->pointer_x : di->mouse_x;
|
||||
|
@ -358,7 +369,8 @@ static int16_t dinput_input_state(void *data,
|
|||
case RETRO_DEVICE_ANALOG:
|
||||
ret = dinput_pressed_analog(di, binds[port], index, id);
|
||||
if (!ret)
|
||||
ret = input_joypad_analog(di->joypad, port, index, id, g_settings.input.binds[port]);
|
||||
ret = input_joypad_analog(di->joypad, port,
|
||||
index, id, g_settings.input.binds[port]);
|
||||
return ret;
|
||||
|
||||
case RETRO_DEVICE_MOUSE:
|
||||
|
@ -366,7 +378,8 @@ static int16_t dinput_input_state(void *data,
|
|||
|
||||
case RETRO_DEVICE_POINTER:
|
||||
case RARCH_DEVICE_POINTER_SCREEN:
|
||||
return dinput_pointer_state(di, index, id, device == RARCH_DEVICE_POINTER_SCREEN);
|
||||
return dinput_pointer_state(di, index, id,
|
||||
device == RARCH_DEVICE_POINTER_SCREEN);
|
||||
|
||||
case RETRO_DEVICE_LIGHTGUN:
|
||||
return dinput_lightgun_state(di, id);
|
||||
|
@ -376,7 +389,7 @@ static int16_t dinput_input_state(void *data,
|
|||
}
|
||||
}
|
||||
|
||||
// these are defined in later SDKs, thus ifdeffed
|
||||
/* these are defined in later SDKs, thus ifdeffed. */
|
||||
#ifndef WM_POINTERUPDATE
|
||||
#define WM_POINTERUPDATE 0x0245
|
||||
#endif
|
||||
|
@ -387,10 +400,10 @@ static int16_t dinput_input_state(void *data,
|
|||
#define WM_POINTERUP 0x0247
|
||||
#endif
|
||||
#ifndef GET_POINTERID_WPARAM
|
||||
#define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam))
|
||||
#define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam))
|
||||
#endif
|
||||
|
||||
// stores x/y in client coordinates
|
||||
/* Stores x/y in client coordinates. */
|
||||
void dinput_pointer_store_pos(struct pointer_status *pointer, WPARAM lParam)
|
||||
{
|
||||
POINT point;
|
||||
|
@ -401,7 +414,8 @@ void dinput_pointer_store_pos(struct pointer_status *pointer, WPARAM lParam)
|
|||
pointer->pointer_y = point.y;
|
||||
}
|
||||
|
||||
void dinput_add_pointer(struct dinput_input *di, struct pointer_status *new_pointer)
|
||||
void dinput_add_pointer(struct dinput_input *di,
|
||||
struct pointer_status *new_pointer)
|
||||
{
|
||||
new_pointer->next = NULL;
|
||||
struct pointer_status *insert_pos = &di->pointer_head;
|
||||
|
@ -425,7 +439,8 @@ void dinput_delete_pointer(struct dinput_input *di, int pointer_id)
|
|||
}
|
||||
}
|
||||
|
||||
struct pointer_status *dinput_find_pointer(struct dinput_input *di, int pointer_id)
|
||||
struct pointer_status *dinput_find_pointer(struct dinput_input *di,
|
||||
int pointer_id)
|
||||
{
|
||||
struct pointer_status *check_pos = di->pointer_head.next;
|
||||
while (check_pos)
|
||||
|
@ -454,15 +469,20 @@ extern "C"
|
|||
bool dinput_handle_message(void *dinput, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
struct dinput_input *di = (struct dinput_input *)dinput;
|
||||
/* WM_POINTERDOWN arrives for each new touch event with a new id - add to list
|
||||
WM_POINTERUP arrives once the pointer is no longer down - remove from list
|
||||
WM_POINTERUPDATE arrives for both pressed and hovering pointers - ignore hovering
|
||||
/* WM_POINTERDOWN : Arrives for each new touch event
|
||||
* with a new ID - add to list.
|
||||
* WM_POINTERUP : Arrives once the pointer is no
|
||||
* longer down - remove from list.
|
||||
* WM_POINTERUPDATE : arrives for both pressed and
|
||||
* hovering pointers - ignore hovering
|
||||
*/
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_POINTERDOWN:
|
||||
{
|
||||
struct pointer_status *new_pointer = (struct pointer_status *)malloc(sizeof(struct pointer_status));
|
||||
struct pointer_status *new_pointer =
|
||||
(struct pointer_status *)malloc(sizeof(struct pointer_status));
|
||||
new_pointer->pointer_id = GET_POINTERID_WPARAM(wParam);
|
||||
dinput_pointer_store_pos(new_pointer, lParam);
|
||||
dinput_add_pointer(di, new_pointer);
|
||||
|
@ -500,12 +520,14 @@ static void dinput_free(void *data)
|
|||
|
||||
if (di)
|
||||
{
|
||||
g_ctx = NULL; // Prevent a joypad driver to kill our context prematurely.
|
||||
/* Prevent a joypad driver to kill our context prematurely. */
|
||||
g_ctx = NULL;
|
||||
if (di->joypad)
|
||||
di->joypad->destroy();
|
||||
g_ctx = hold_ctx;
|
||||
|
||||
dinput_clear_pointers(di); // clear any leftover pointers
|
||||
/* Clear any leftover pointers. */
|
||||
dinput_clear_pointers(di);
|
||||
|
||||
if (di->keyboard)
|
||||
IDirectInputDevice8_Release(di->keyboard);
|
||||
|
@ -531,7 +553,8 @@ static void dinput_grab_mouse(void *data, bool state)
|
|||
IDirectInputDevice8_Acquire(di->mouse);
|
||||
}
|
||||
|
||||
static bool dinput_set_rumble(void *data, unsigned port, enum retro_rumble_effect effect, uint16_t strength)
|
||||
static bool dinput_set_rumble(void *data, unsigned port,
|
||||
enum retro_rumble_effect effect, uint16_t strength)
|
||||
{
|
||||
struct dinput_input *di = (struct dinput_input*)data;
|
||||
return input_joypad_set_rumble(di->joypad, port, effect, strength);
|
||||
|
@ -557,7 +580,7 @@ static uint64_t dinput_get_capabilities(void *data)
|
|||
return caps;
|
||||
}
|
||||
|
||||
const input_driver_t input_dinput = {
|
||||
input_driver_t input_dinput = {
|
||||
dinput_init,
|
||||
dinput_poll,
|
||||
dinput_input_state,
|
||||
|
@ -573,9 +596,11 @@ const input_driver_t input_dinput = {
|
|||
dinput_get_joypad_driver,
|
||||
};
|
||||
|
||||
// Keep track of which pad indexes are 360 controllers
|
||||
// not static, will be read in winxinput_joypad.c
|
||||
// -1 = not xbox pad, otherwise 0..3
|
||||
/* Keep track of which pad indexes are 360 controllers.
|
||||
* Not static, will be read in winxinput_joypad.c
|
||||
* -1 = not xbox pad, otherwise 0..3
|
||||
*/
|
||||
|
||||
int g_xinput_pad_indexes[MAX_PLAYERS];
|
||||
bool g_xinput_block_pads;
|
||||
|
||||
|
@ -598,11 +623,12 @@ static void dinput_joypad_destroy(void)
|
|||
g_joypad_cnt = 0;
|
||||
memset(g_pads, 0, sizeof(g_pads));
|
||||
|
||||
// Can be blocked by global Dinput context.
|
||||
/* Can be blocked by global Dinput context. */
|
||||
dinput_destroy_context();
|
||||
}
|
||||
|
||||
static BOOL CALLBACK enum_axes_cb(const DIDEVICEOBJECTINSTANCE *inst, void *p)
|
||||
static BOOL CALLBACK enum_axes_cb(
|
||||
const DIDEVICEOBJECTINSTANCE *inst, void *p)
|
||||
{
|
||||
LPDIRECTINPUTDEVICE8 joypad = (LPDIRECTINPUTDEVICE8)p;
|
||||
|
||||
|
@ -625,15 +651,20 @@ static const GUID common_xinput_guids[] = {
|
|||
{MAKELONG(0x045E, 0x028E),0x0000,0x0000,{0x00,0x00,0x50,0x49,0x44,0x56,0x49,0x44}} // wireless 360 pad
|
||||
};
|
||||
|
||||
// Based on SDL2's implementation
|
||||
/* Based on SDL2's implementation. */
|
||||
static bool guid_is_xinput_device(const GUID* product_guid)
|
||||
{
|
||||
PRAWINPUTDEVICELIST raw_devs = NULL;
|
||||
unsigned num_raw_devs = 0;
|
||||
unsigned i;
|
||||
|
||||
// Check for well known XInput device GUIDs, thereby removing the need for the IG_ check.
|
||||
// This lets us skip RAWINPUT for popular devices. Also, we need to do this for the Valve Streaming Gamepad because it's virtualized and doesn't show up in the device list.
|
||||
/* Check for well known XInput device GUIDs,
|
||||
* thereby removing the need for the IG_ check.
|
||||
* This lets us skip RAWINPUT for popular devices.
|
||||
*
|
||||
* Also, we need to do this for the Valve Streaming Gamepad
|
||||
* because it's virtualized and doesn't show up in the device list. */
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(common_xinput_guids); ++i)
|
||||
{
|
||||
if (memcmp(product_guid, &common_xinput_guids[i], sizeof(GUID)) == 0)
|
||||
|
@ -643,14 +674,17 @@ static bool guid_is_xinput_device(const GUID* product_guid)
|
|||
/* Go through RAWINPUT (WinXP and later) to find HID devices. */
|
||||
if (!raw_devs)
|
||||
{
|
||||
if ((GetRawInputDeviceList(NULL, &num_raw_devs, sizeof(RAWINPUTDEVICELIST)) == (UINT)-1) || (!num_raw_devs))
|
||||
if ((GetRawInputDeviceList(NULL, &num_raw_devs,
|
||||
sizeof(RAWINPUTDEVICELIST)) == (UINT)-1) || (!num_raw_devs))
|
||||
return false;
|
||||
|
||||
raw_devs = (PRAWINPUTDEVICELIST)malloc(sizeof(RAWINPUTDEVICELIST) * num_raw_devs);
|
||||
raw_devs = (PRAWINPUTDEVICELIST)
|
||||
malloc(sizeof(RAWINPUTDEVICELIST) * num_raw_devs);
|
||||
if (!raw_devs)
|
||||
return false;
|
||||
|
||||
if (GetRawInputDeviceList(raw_devs, &num_raw_devs, sizeof (RAWINPUTDEVICELIST)) == (UINT)-1)
|
||||
if (GetRawInputDeviceList(raw_devs, &num_raw_devs,
|
||||
sizeof(RAWINPUTDEVICELIST)) == (UINT)-1)
|
||||
{
|
||||
free(raw_devs);
|
||||
raw_devs = NULL;
|
||||
|
@ -683,8 +717,9 @@ static bool guid_is_xinput_device(const GUID* product_guid)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Forward declaration
|
||||
/* Forward declaration */
|
||||
static const char *dinput_joypad_name(unsigned pad);
|
||||
|
||||
static unsigned g_last_xinput_pad_index;
|
||||
|
||||
static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p)
|
||||
|
@ -696,17 +731,23 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p)
|
|||
LPDIRECTINPUTDEVICE8 *pad = &g_pads[g_joypad_cnt].joypad;
|
||||
|
||||
#ifdef __cplusplus
|
||||
if (FAILED(IDirectInput8_CreateDevice(g_ctx, inst->guidInstance, pad, NULL)))
|
||||
if (FAILED(IDirectInput8_CreateDevice(
|
||||
g_ctx, inst->guidInstance, pad, NULL)))
|
||||
#else
|
||||
if (FAILED(IDirectInput8_CreateDevice(g_ctx, &inst->guidInstance, pad, NULL)))
|
||||
if (FAILED(IDirectInput8_CreateDevice(
|
||||
g_ctx, &inst->guidInstance, pad, NULL)))
|
||||
#endif
|
||||
return DIENUM_CONTINUE;
|
||||
|
||||
g_pads[g_joypad_cnt].joy_name = strdup(inst->tszProductName);
|
||||
|
||||
#ifdef HAVE_WINXINPUT
|
||||
//bool is_xinput_pad = g_xinput_block_pads && name_is_xinput_pad(inst->tszProductName);
|
||||
bool is_xinput_pad = g_xinput_block_pads && guid_is_xinput_device(&inst->guidProduct);
|
||||
#if 0
|
||||
bool is_xinput_pad = g_xinput_block_pads
|
||||
&& name_is_xinput_pad(inst->tszProductName);
|
||||
#endif
|
||||
bool is_xinput_pad = g_xinput_block_pads
|
||||
&& guid_is_xinput_device(&inst->guidProduct);
|
||||
|
||||
if (is_xinput_pad)
|
||||
{
|
||||
|
@ -727,8 +768,12 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p)
|
|||
if (!is_xinput_pad)
|
||||
#endif
|
||||
{
|
||||
strlcpy(g_settings.input.device_names[g_joypad_cnt], dinput_joypad_name(g_joypad_cnt), sizeof(g_settings.input.device_names[g_joypad_cnt]));
|
||||
input_config_autoconfigure_joypad(g_joypad_cnt, dinput_joypad_name(g_joypad_cnt), dinput_joypad.ident);
|
||||
strlcpy(g_settings.input.device_names[g_joypad_cnt],
|
||||
dinput_joypad_name(g_joypad_cnt),
|
||||
sizeof(g_settings.input.device_names[g_joypad_cnt]));
|
||||
input_config_autoconfigure_joypad(g_joypad_cnt,
|
||||
dinput_joypad_name(g_joypad_cnt),
|
||||
dinput_joypad.ident);
|
||||
}
|
||||
|
||||
enum_iteration_done:
|
||||
|
@ -771,7 +816,9 @@ static bool dinput_joypad_button(unsigned port_num, uint16_t joykey)
|
|||
{
|
||||
unsigned hat = GET_HAT(joykey);
|
||||
|
||||
unsigned elems = sizeof(pad->joy_state.rgdwPOV) / sizeof(pad->joy_state.rgdwPOV[0]);
|
||||
unsigned elems = sizeof(pad->joy_state.rgdwPOV) /
|
||||
sizeof(pad->joy_state.rgdwPOV[0]);
|
||||
|
||||
if (hat >= elems)
|
||||
return false;
|
||||
|
||||
|
@ -797,7 +844,8 @@ static bool dinput_joypad_button(unsigned port_num, uint16_t joykey)
|
|||
}
|
||||
else
|
||||
{
|
||||
unsigned elems = sizeof(pad->joy_state.rgbButtons) / sizeof(pad->joy_state.rgbButtons[0]);
|
||||
unsigned elems = sizeof(pad->joy_state.rgbButtons) /
|
||||
sizeof(pad->joy_state.rgbButtons[0]);
|
||||
|
||||
if (joykey < elems)
|
||||
return pad->joy_state.rgbButtons[joykey];
|
||||
|
@ -834,12 +882,24 @@ static int16_t dinput_joypad_axis(unsigned port_num, uint32_t joyaxis)
|
|||
|
||||
switch (axis)
|
||||
{
|
||||
case 0: val = pad->joy_state.lX; break;
|
||||
case 1: val = pad->joy_state.lY; break;
|
||||
case 2: val = pad->joy_state.lZ; break;
|
||||
case 3: val = pad->joy_state.lRx; break;
|
||||
case 4: val = pad->joy_state.lRy; break;
|
||||
case 5: val = pad->joy_state.lRz; break;
|
||||
case 0:
|
||||
val = pad->joy_state.lX;
|
||||
break;
|
||||
case 1:
|
||||
val = pad->joy_state.lY;
|
||||
break;
|
||||
case 2:
|
||||
val = pad->joy_state.lZ;
|
||||
break;
|
||||
case 3:
|
||||
val = pad->joy_state.lRx;
|
||||
break;
|
||||
case 4:
|
||||
val = pad->joy_state.lRy;
|
||||
break;
|
||||
case 5:
|
||||
val = pad->joy_state.lRz;
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_neg && val > 0)
|
||||
|
@ -869,7 +929,7 @@ static void dinput_joypad_poll(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
// If this fails, something *really* bad must have happened.
|
||||
/* If this fails, something *really* bad must have happened. */
|
||||
if (FAILED(IDirectInputDevice8_Poll(pad->joypad)))
|
||||
{
|
||||
memset(&pad->joy_state, 0, sizeof(DIJOYSTATE2));
|
||||
|
@ -896,7 +956,7 @@ static const char *dinput_joypad_name(unsigned pad)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
const rarch_joypad_driver_t dinput_joypad = {
|
||||
rarch_joypad_driver_t dinput_joypad = {
|
||||
dinput_joypad_init,
|
||||
dinput_joypad_query_pad,
|
||||
dinput_joypad_destroy,
|
||||
|
|
|
@ -89,7 +89,9 @@ enum
|
|||
GX_WIIMOTE_2 = 46,
|
||||
GX_WIIMOTE_PLUS = 47,
|
||||
GX_WIIMOTE_MINUS = 48,
|
||||
//GX_WIIMOTE_HOME = 49,
|
||||
#if 0
|
||||
GX_WIIMOTE_HOME = 49,
|
||||
#endif
|
||||
GX_WIIMOTE_UP = 50,
|
||||
GX_WIIMOTE_DOWN = 51,
|
||||
GX_WIIMOTE_LEFT = 52,
|
||||
|
@ -101,7 +103,7 @@ enum
|
|||
GX_NUNCHUK_LEFT = 58,
|
||||
GX_NUNCHUK_RIGHT = 59,
|
||||
#endif
|
||||
GX_WIIMOTE_HOME = 49, // needed on GameCube as "fake" menu button
|
||||
GX_WIIMOTE_HOME = 49, /* needed on GameCube as "fake" menu button. */
|
||||
GX_QUIT_KEY = 60,
|
||||
};
|
||||
|
||||
|
@ -250,8 +252,12 @@ static void *gx_input_init(void)
|
|||
for (autoconf_pad = 0; autoconf_pad < MAX_PADS; autoconf_pad++)
|
||||
{
|
||||
gx->ptype[autoconf_pad] = WPAD_EXP_GAMECUBE;
|
||||
strlcpy(g_settings.input.device_names[autoconf_pad], gx_joypad_name_static(gx, autoconf_pad), sizeof(g_settings.input.device_names[autoconf_pad]));
|
||||
input_config_autoconfigure_joypad(autoconf_pad, gx_joypad_name_static(gx, autoconf_pad), gx->joypad->ident);
|
||||
strlcpy(g_settings.input.device_names[autoconf_pad],
|
||||
gx_joypad_name_static(gx, autoconf_pad),
|
||||
sizeof(g_settings.input.device_names[autoconf_pad]));
|
||||
input_config_autoconfigure_joypad(autoconf_pad,
|
||||
gx_joypad_name_static(gx, autoconf_pad),
|
||||
gx->joypad->ident);
|
||||
}
|
||||
|
||||
driver.input_data_own = true;
|
||||
|
@ -267,8 +273,11 @@ static void handle_hotplug(void *data, unsigned port, uint32_t ptype)
|
|||
if (!g_settings.input.autodetect_enable)
|
||||
return;
|
||||
|
||||
strlcpy(g_settings.input.device_names[port], gx_joypad_name(port), sizeof(g_settings.input.device_names[port]));
|
||||
input_config_autoconfigure_joypad(port, gx_joypad_name(port), gx_joypad.ident);
|
||||
strlcpy(g_settings.input.device_names[port],
|
||||
gx_joypad_name(port),
|
||||
sizeof(g_settings.input.device_names[port]));
|
||||
input_config_autoconfigure_joypad(port,
|
||||
gx_joypad_name(port), gx_joypad.ident);
|
||||
}
|
||||
|
||||
static void gx_input_poll(void *data)
|
||||
|
@ -314,7 +323,7 @@ static void gx_input_poll(void *data)
|
|||
|
||||
if (ptype != WPAD_EXP_NUNCHUK)
|
||||
{
|
||||
// rotated d-pad on Wiimote
|
||||
/* Rotated d-pad on Wiimote. */
|
||||
*state_cur |= (down & WPAD_BUTTON_UP) ? (1ULL << GX_WIIMOTE_LEFT) : 0;
|
||||
*state_cur |= (down & WPAD_BUTTON_DOWN) ? (1ULL << GX_WIIMOTE_RIGHT) : 0;
|
||||
*state_cur |= (down & WPAD_BUTTON_LEFT) ? (1ULL << GX_WIIMOTE_DOWN) : 0;
|
||||
|
@ -375,7 +384,8 @@ static void gx_input_poll(void *data)
|
|||
}
|
||||
else if (ptype == WPAD_EXP_NUNCHUK)
|
||||
{
|
||||
// wiimote is held upright with nunchuk, do not change d-pad orientation
|
||||
/* Wiimote is held upright with nunchuk,
|
||||
* do not change d-pad orientation. */
|
||||
*state_cur |= (down & WPAD_BUTTON_UP) ? (1ULL << GX_WIIMOTE_UP) : 0;
|
||||
*state_cur |= (down & WPAD_BUTTON_DOWN) ? (1ULL << GX_WIIMOTE_DOWN) : 0;
|
||||
*state_cur |= (down & WPAD_BUTTON_LEFT) ? (1ULL << GX_WIIMOTE_LEFT) : 0;
|
||||
|
@ -511,7 +521,8 @@ static void gx_input_poll(void *data)
|
|||
|
||||
static bool gx_input_key_pressed(void *data, int key)
|
||||
{
|
||||
return (g_extern.lifecycle_state & (1ULL << key)) || input_joypad_pressed(&gx_joypad, 0, g_settings.input.binds[0], key);
|
||||
return (g_extern.lifecycle_state & (1ULL << key)) ||
|
||||
input_joypad_pressed(&gx_joypad, 0, g_settings.input.binds[0], key);
|
||||
}
|
||||
|
||||
static uint64_t gx_input_get_capabilities(void *data)
|
||||
|
@ -529,7 +540,7 @@ static const rarch_joypad_driver_t *gx_input_get_joypad_driver(void *data)
|
|||
return &gx_joypad;
|
||||
}
|
||||
|
||||
const input_driver_t input_gx = {
|
||||
input_driver_t input_gx = {
|
||||
gx_input_init,
|
||||
gx_input_poll,
|
||||
gx_input_state,
|
||||
|
|
|
@ -29,7 +29,6 @@ static bool gx_joypad_init(void)
|
|||
ss_initialize(&dev[i]);
|
||||
#endif
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -68,10 +67,18 @@ static int16_t gx_joypad_axis(unsigned port_num, uint32_t joyaxis)
|
|||
|
||||
switch (axis)
|
||||
{
|
||||
case 0: val = gx->analog_state[port_num][0][0]; break;
|
||||
case 1: val = gx->analog_state[port_num][0][1]; break;
|
||||
case 2: val = gx->analog_state[port_num][1][0]; break;
|
||||
case 3: val = gx->analog_state[port_num][1][1]; break;
|
||||
case 0:
|
||||
val = gx->analog_state[port_num][0][0];
|
||||
break;
|
||||
case 1:
|
||||
val = gx->analog_state[port_num][0][1];
|
||||
break;
|
||||
case 2:
|
||||
val = gx->analog_state[port_num][1][0];
|
||||
break;
|
||||
case 3:
|
||||
val = gx->analog_state[port_num][1][1];
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_neg && val > 0)
|
||||
|
@ -109,7 +116,7 @@ static void gx_joypad_destroy(void)
|
|||
}
|
||||
}
|
||||
|
||||
const rarch_joypad_driver_t gx_joypad = {
|
||||
rarch_joypad_driver_t gx_joypad = {
|
||||
gx_joypad_init,
|
||||
gx_joypad_query_pad,
|
||||
gx_joypad_destroy,
|
||||
|
|
|
@ -36,312 +36,329 @@ static int _ss_send_attributes_payload(struct ss_device *dev);
|
|||
|
||||
int ss_init(void)
|
||||
{
|
||||
if (!_ss_inited)
|
||||
{
|
||||
_ss_heap_id = iosCreateHeap(SS_HEAP_SIZE);
|
||||
_ss_inited = 1;
|
||||
}
|
||||
return 1;
|
||||
if (!_ss_inited)
|
||||
{
|
||||
_ss_heap_id = iosCreateHeap(SS_HEAP_SIZE);
|
||||
_ss_inited = 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int ss_initialize(struct ss_device *dev)
|
||||
{
|
||||
dev->device_id = -1;
|
||||
dev->fd = -1;
|
||||
dev->connected = 0;
|
||||
dev->enabled = 0;
|
||||
dev->reading = 0;
|
||||
dev->removal_callback = NULL;
|
||||
dev->removal_usrdata = NULL;
|
||||
dev->read_callback = NULL;
|
||||
dev->read_usrdata = NULL;
|
||||
memset(&dev->pad, 0x0, sizeof(struct SS_GAMEPAD));
|
||||
memset(&dev->attributes, 0x0, sizeof(struct SS_ATTRIBUTES));
|
||||
return 1;
|
||||
dev->device_id = -1;
|
||||
dev->fd = -1;
|
||||
dev->connected = 0;
|
||||
dev->enabled = 0;
|
||||
dev->reading = 0;
|
||||
dev->removal_callback = NULL;
|
||||
dev->removal_usrdata = NULL;
|
||||
dev->read_callback = NULL;
|
||||
dev->read_usrdata = NULL;
|
||||
memset(&dev->pad, 0x0, sizeof(struct SS_GAMEPAD));
|
||||
memset(&dev->attributes, 0x0, sizeof(struct SS_ATTRIBUTES));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ss_open(struct ss_device *dev)
|
||||
{
|
||||
if (!_ss_inited) return -1;
|
||||
if (dev->connected) ss_close(dev);
|
||||
|
||||
usb_device_entry dev_entry[8];
|
||||
unsigned char dev_count;
|
||||
if (USB_GetDeviceList(dev_entry, 8, USB_CLASS_HID, &dev_count) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < dev_count; ++i) {
|
||||
|
||||
if ((dev_entry[i].vid == SS_VENDOR_ID) && (dev_entry[i].pid == SS_PRODUCT_ID)) {
|
||||
|
||||
if (!_ss_dev_id_list_exists(dev_entry[i].device_id)) {
|
||||
if (USB_OpenDevice(dev_entry[i].device_id, SS_VENDOR_ID, SS_PRODUCT_ID, &dev->fd) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
dev->device_id = dev_entry[i].device_id;
|
||||
dev->connected = 1;
|
||||
dev->enabled = 0;
|
||||
dev->reading = 0;
|
||||
|
||||
_ss_set_operational(dev);
|
||||
ss_set_led(dev, _ss_dev_number);
|
||||
|
||||
_ss_dev_id_list_add(dev_entry[i].device_id);
|
||||
_ss_dev_number++;
|
||||
|
||||
USB_DeviceRemovalNotifyAsync(dev->fd, &_ss_removal_cb, dev);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -4;
|
||||
usb_device_entry dev_entry[8];
|
||||
unsigned char dev_count;
|
||||
if (!_ss_inited)
|
||||
return -1;
|
||||
if (dev->connected)
|
||||
ss_close(dev);
|
||||
|
||||
if (USB_GetDeviceList(dev_entry, 8, USB_CLASS_HID, &dev_count) < 0)
|
||||
return -2;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < dev_count; ++i)
|
||||
{
|
||||
if ((dev_entry[i].vid == SS_VENDOR_ID) &&
|
||||
(dev_entry[i].pid == SS_PRODUCT_ID))
|
||||
{
|
||||
if (!_ss_dev_id_list_exists(dev_entry[i].device_id))
|
||||
{
|
||||
if (USB_OpenDevice(dev_entry[i].device_id,
|
||||
SS_VENDOR_ID, SS_PRODUCT_ID, &dev->fd) < 0)
|
||||
return -3;
|
||||
|
||||
dev->device_id = dev_entry[i].device_id;
|
||||
dev->connected = 1;
|
||||
dev->enabled = 0;
|
||||
dev->reading = 0;
|
||||
|
||||
_ss_set_operational(dev);
|
||||
ss_set_led(dev, _ss_dev_number);
|
||||
|
||||
_ss_dev_id_list_add(dev_entry[i].device_id);
|
||||
_ss_dev_number++;
|
||||
|
||||
USB_DeviceRemovalNotifyAsync(dev->fd, &_ss_removal_cb, dev);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -4;
|
||||
}
|
||||
|
||||
int ss_close(struct ss_device *dev)
|
||||
{
|
||||
if (dev && dev->fd > 0) {
|
||||
USB_CloseDevice(&dev->fd);
|
||||
}
|
||||
return 1;
|
||||
if (dev && dev->fd > 0)
|
||||
USB_CloseDevice(&dev->fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ss_is_connected(struct ss_device *dev)
|
||||
{
|
||||
return dev->connected;
|
||||
return dev->connected;
|
||||
}
|
||||
|
||||
int ss_set_read_cb(struct ss_device *dev,ss_usb_callback cb, void *usrdata)
|
||||
int ss_set_read_cb(struct ss_device *dev,ss_usb_callback cb,
|
||||
void *userdata)
|
||||
{
|
||||
dev->read_callback = cb;
|
||||
dev->read_usrdata = usrdata;
|
||||
return 1;
|
||||
dev->read_callback = cb;
|
||||
dev->read_usrdata = userdata;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ss_set_removal_cb(struct ss_device *dev, ss_usb_callback cb, void *usrdata)
|
||||
int ss_set_removal_cb(struct ss_device *dev, ss_usb_callback cb,
|
||||
void *usrdata)
|
||||
{
|
||||
dev->removal_callback = cb;
|
||||
dev->removal_usrdata = usrdata;
|
||||
dev->removal_usrdata = userdata;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ss_start_reading(struct ss_device *dev)
|
||||
{
|
||||
if (dev) {
|
||||
dev->reading = 1;
|
||||
if (dev->enabled) {
|
||||
_ss_read(dev);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
if (dev)
|
||||
{
|
||||
dev->reading = 1;
|
||||
if (dev->enabled)
|
||||
_ss_read(dev);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ss_stop_reading(struct ss_device *dev)
|
||||
{
|
||||
if (dev) {
|
||||
dev->reading = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
if (dev)
|
||||
{
|
||||
dev->reading = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _ss_build_attributes_payload(struct ss_device *dev)
|
||||
{
|
||||
_ss_attributes_payload[1] = dev->attributes.rumble.duration_right;
|
||||
_ss_attributes_payload[2] = dev->attributes.rumble.power_right;
|
||||
_ss_attributes_payload[3] = dev->attributes.rumble.duration_left;
|
||||
_ss_attributes_payload[4] = dev->attributes.rumble.power_left;
|
||||
_ss_attributes_payload[9] = _ss_led_pattern[dev->attributes.led];
|
||||
return 1;
|
||||
_ss_attributes_payload[1] = dev->attributes.rumble.duration_right;
|
||||
_ss_attributes_payload[2] = dev->attributes.rumble.power_right;
|
||||
_ss_attributes_payload[3] = dev->attributes.rumble.duration_left;
|
||||
_ss_attributes_payload[4] = dev->attributes.rumble.power_left;
|
||||
_ss_attributes_payload[9] = _ss_led_pattern[dev->attributes.led];
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _ss_send_attributes_payload(struct ss_device *dev)
|
||||
{
|
||||
if (!dev->connected) return 0;
|
||||
_ss_build_attributes_payload(dev);
|
||||
return USB_WriteCtrlMsgAsync(dev->fd,
|
||||
USB_REQTYPE_INTERFACE_SET,
|
||||
USB_REQ_SETREPORT,
|
||||
(USB_REPTYPE_OUTPUT<<8) | 0x01,
|
||||
0x0,
|
||||
sizeof(_ss_attributes_payload),
|
||||
_ss_attributes_payload,
|
||||
NULL, NULL);
|
||||
if (!dev->connected)
|
||||
return 0;
|
||||
|
||||
_ss_build_attributes_payload(dev);
|
||||
|
||||
return USB_WriteCtrlMsgAsync(dev->fd,
|
||||
USB_REQTYPE_INTERFACE_SET,
|
||||
USB_REQ_SETREPORT,
|
||||
(USB_REPTYPE_OUTPUT<<8) | 0x01,
|
||||
0x0,
|
||||
sizeof(_ss_attributes_payload),
|
||||
_ss_attributes_payload,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
inline int ss_set_led(struct ss_device *dev, int led)
|
||||
{
|
||||
dev->attributes.led = led;
|
||||
return _ss_send_attributes_payload(dev);
|
||||
dev->attributes.led = led;
|
||||
return _ss_send_attributes_payload(dev);
|
||||
}
|
||||
|
||||
inline int ss_set_rumble(struct ss_device *dev, uint8_t duration_right, uint8_t power_right, uint8_t duration_left, uint8_t power_left)
|
||||
inline int ss_set_rumble(struct ss_device *dev, uint8_t duration_right,
|
||||
uint8_t power_right, uint8_t duration_left, uint8_t power_left)
|
||||
{
|
||||
dev->attributes.rumble.duration_right = duration_right;
|
||||
dev->attributes.rumble.power_right = power_right;
|
||||
dev->attributes.rumble.duration_left = duration_left;
|
||||
dev->attributes.rumble.power_left = power_left;
|
||||
return _ss_send_attributes_payload(dev);
|
||||
dev->attributes.rumble.duration_right = duration_right;
|
||||
dev->attributes.rumble.power_right = power_right;
|
||||
dev->attributes.rumble.duration_left = duration_left;
|
||||
dev->attributes.rumble.power_left = power_left;
|
||||
return _ss_send_attributes_payload(dev);
|
||||
}
|
||||
|
||||
int ss_get_bd_address(struct ss_device *dev, uint8_t *mac)
|
||||
{
|
||||
uint8_t ATTRIBUTE_ALIGN(32) msg[17];
|
||||
int ret = USB_WriteCtrlMsgAsync(dev->fd,
|
||||
USB_REQTYPE_INTERFACE_GET,
|
||||
USB_REQ_GETREPORT,
|
||||
(USB_REPTYPE_FEATURE<<8) | 0xf2,
|
||||
0,
|
||||
sizeof(msg),
|
||||
msg,
|
||||
NULL, NULL);
|
||||
uint8_t ATTRIBUTE_ALIGN(32) msg[17];
|
||||
int ret = USB_WriteCtrlMsgAsync(dev->fd,
|
||||
USB_REQTYPE_INTERFACE_GET,
|
||||
USB_REQ_GETREPORT,
|
||||
(USB_REPTYPE_FEATURE<<8) | 0xf2,
|
||||
0,
|
||||
sizeof(msg),
|
||||
msg,
|
||||
NULL, NULL);
|
||||
|
||||
mac[0] = msg[4];
|
||||
mac[1] = msg[5];
|
||||
mac[2] = msg[6];
|
||||
mac[3] = msg[7];
|
||||
mac[4] = msg[8];
|
||||
mac[5] = msg[9];
|
||||
return ret;
|
||||
mac[0] = msg[4];
|
||||
mac[1] = msg[5];
|
||||
mac[2] = msg[6];
|
||||
mac[3] = msg[7];
|
||||
mac[4] = msg[8];
|
||||
mac[5] = msg[9];
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ss_get_mac(struct ss_device *dev, uint8_t *mac)
|
||||
{
|
||||
uint8_t ATTRIBUTE_ALIGN(32) msg[8];
|
||||
int ret = USB_WriteCtrlMsgAsync(dev->fd,
|
||||
USB_REQTYPE_INTERFACE_GET,
|
||||
USB_REQ_GETREPORT,
|
||||
(USB_REPTYPE_FEATURE<<8) | 0xf5,
|
||||
0,
|
||||
sizeof(msg),
|
||||
msg,
|
||||
NULL, NULL);
|
||||
uint8_t ATTRIBUTE_ALIGN(32) msg[8];
|
||||
int ret = USB_WriteCtrlMsgAsync(dev->fd,
|
||||
USB_REQTYPE_INTERFACE_GET,
|
||||
USB_REQ_GETREPORT,
|
||||
(USB_REPTYPE_FEATURE<<8) | 0xf5,
|
||||
0,
|
||||
sizeof(msg),
|
||||
msg,
|
||||
NULL, NULL);
|
||||
|
||||
mac[0] = msg[2];
|
||||
mac[1] = msg[3];
|
||||
mac[2] = msg[4];
|
||||
mac[3] = msg[5];
|
||||
mac[4] = msg[6];
|
||||
mac[5] = msg[7];
|
||||
return ret;
|
||||
mac[0] = msg[2];
|
||||
mac[1] = msg[3];
|
||||
mac[2] = msg[4];
|
||||
mac[3] = msg[5];
|
||||
mac[4] = msg[6];
|
||||
mac[5] = msg[7];
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ss_set_mac(struct ss_device *dev, const uint8_t *mac)
|
||||
{
|
||||
uint8_t ATTRIBUTE_ALIGN(32) msg[] = {0x01, 0x00, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]};
|
||||
int ret = USB_WriteCtrlMsgAsync(dev->fd,
|
||||
USB_REQTYPE_INTERFACE_SET,
|
||||
USB_REQ_SETREPORT,
|
||||
(USB_REPTYPE_FEATURE<<8) | 0xf5,
|
||||
0,
|
||||
sizeof(msg),
|
||||
msg,
|
||||
NULL, NULL);
|
||||
return ret;
|
||||
uint8_t ATTRIBUTE_ALIGN(32) msg[] = {0x01, 0x00, mac[0], mac[1],
|
||||
mac[2], mac[3], mac[4], mac[5]};
|
||||
int ret = USB_WriteCtrlMsgAsync(dev->fd,
|
||||
USB_REQTYPE_INTERFACE_SET,
|
||||
USB_REQ_SETREPORT,
|
||||
(USB_REPTYPE_FEATURE<<8) | 0xf5,
|
||||
0,
|
||||
sizeof(msg),
|
||||
msg,
|
||||
NULL, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int _ss_read(struct ss_device *dev)
|
||||
{
|
||||
return USB_WriteCtrlMsgAsync(
|
||||
dev->fd,
|
||||
USB_REQTYPE_INTERFACE_GET,
|
||||
USB_REQ_GETREPORT,
|
||||
(USB_REPTYPE_INPUT<<8) | 0x01,
|
||||
0x0,
|
||||
SS_PAYLOAD_SIZE,
|
||||
&dev->pad,
|
||||
&_ss_read_cb,
|
||||
dev);
|
||||
return USB_WriteCtrlMsgAsync(
|
||||
dev->fd,
|
||||
USB_REQTYPE_INTERFACE_GET,
|
||||
USB_REQ_GETREPORT,
|
||||
(USB_REPTYPE_INPUT<<8) | 0x01,
|
||||
0x0,
|
||||
SS_PAYLOAD_SIZE,
|
||||
&dev->pad,
|
||||
&_ss_read_cb,
|
||||
dev);
|
||||
}
|
||||
|
||||
static int _ss_removal_cb(int result, void *usrdata)
|
||||
{
|
||||
struct ss_device *dev = (struct ss_device*)usrdata;
|
||||
if (dev->device_id > 0) {
|
||||
_ss_dev_id_list_remove(dev->device_id);
|
||||
_ss_dev_number--;
|
||||
if (dev->removal_callback)
|
||||
dev->removal_callback(dev->removal_usrdata);
|
||||
ss_initialize(dev);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
struct ss_device *dev = (struct ss_device*)usrdata;
|
||||
if (dev->device_id > 0)
|
||||
{
|
||||
_ss_dev_id_list_remove(dev->device_id);
|
||||
_ss_dev_number--;
|
||||
if (dev->removal_callback)
|
||||
dev->removal_callback(dev->removal_usrdata);
|
||||
ss_initialize(dev);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _ss_set_operational(struct ss_device *dev)
|
||||
{
|
||||
uint8_t ATTRIBUTE_ALIGN(32) buf[17];
|
||||
return USB_WriteCtrlMsgAsync(
|
||||
dev->fd,
|
||||
USB_REQTYPE_INTERFACE_GET,
|
||||
USB_REQ_GETREPORT,
|
||||
(USB_REPTYPE_FEATURE<<8) | 0xf2,
|
||||
0x0,
|
||||
17,
|
||||
buf,
|
||||
&_ss_operational_cb,
|
||||
dev);
|
||||
uint8_t ATTRIBUTE_ALIGN(32) buf[17];
|
||||
return USB_WriteCtrlMsgAsync(
|
||||
dev->fd,
|
||||
USB_REQTYPE_INTERFACE_GET,
|
||||
USB_REQ_GETREPORT,
|
||||
(USB_REPTYPE_FEATURE<<8) | 0xf2,
|
||||
0x0,
|
||||
17,
|
||||
buf,
|
||||
&_ss_operational_cb,
|
||||
dev);
|
||||
}
|
||||
|
||||
static int _ss_read_cb(int result, void *usrdata)
|
||||
static int _ss_read_cb(int result, void *userdata)
|
||||
{
|
||||
if (usrdata) {
|
||||
struct ss_device *dev = (struct ss_device*)usrdata;
|
||||
if (dev->reading) {
|
||||
_ss_read(dev);
|
||||
if (dev->read_callback)
|
||||
if (userdata)
|
||||
{
|
||||
struct ss_device *dev = (struct ss_device*)userdata;
|
||||
if (dev->reading)
|
||||
{
|
||||
_ss_read(dev);
|
||||
if (dev->read_callback)
|
||||
dev->read_callback(dev->read_usrdata);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _ss_operational_cb(int result, void *usrdata)
|
||||
static int _ss_operational_cb(int result, void *userdata)
|
||||
{
|
||||
struct ss_device *dev = (struct ss_device*)usrdata;
|
||||
dev->enabled = 1;
|
||||
if (dev->reading) {
|
||||
_ss_read(dev);
|
||||
}
|
||||
return 1;
|
||||
struct ss_device *dev = (struct ss_device*)userdata;
|
||||
dev->enabled = 1;
|
||||
if (dev->reading)
|
||||
_ss_read(dev);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int _ss_dev_id_list_exists(int id)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < SS_MAX_DEV; ++i) {
|
||||
if (_ss_dev_id_list[i] == id) return 1;
|
||||
}
|
||||
return 0;
|
||||
int i;
|
||||
for (i = 0; i < SS_MAX_DEV; ++i)
|
||||
{
|
||||
if (_ss_dev_id_list[i] == id)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _ss_dev_id_list_add(int id)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < SS_MAX_DEV; ++i) {
|
||||
if (_ss_dev_id_list[i] == 0) {
|
||||
_ss_dev_id_list[i] = id;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
int i;
|
||||
for (i = 0; i < SS_MAX_DEV; ++i)
|
||||
{
|
||||
if (_ss_dev_id_list[i] == 0)
|
||||
{
|
||||
_ss_dev_id_list[i] = id;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _ss_dev_id_list_remove(int id)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < SS_MAX_DEV; ++i) {
|
||||
if (_ss_dev_id_list[i] == id) {
|
||||
_ss_dev_id_list[i] = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
int i;
|
||||
for (i = 0; i < SS_MAX_DEV; ++i)
|
||||
{
|
||||
if (_ss_dev_id_list[i] == id)
|
||||
{
|
||||
_ss_dev_id_list[i] = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -122,20 +122,34 @@ struct ss_device {
|
|||
|
||||
|
||||
int ss_init(void);
|
||||
|
||||
int ss_initialize(struct ss_device *dev);
|
||||
|
||||
int ss_open(struct ss_device *dev);
|
||||
|
||||
int ss_close(struct ss_device *dev);
|
||||
|
||||
int ss_is_connected(struct ss_device *dev);
|
||||
|
||||
int ss_set_read_cb(struct ss_device *dev, ss_usb_callback cb, void *usrdata);
|
||||
int ss_set_removal_cb(struct ss_device *dev, ss_usb_callback cb, void *usrdata);
|
||||
int ss_set_read_cb(struct ss_device *dev,
|
||||
ss_usb_callback cb, void *usrdata);
|
||||
|
||||
int ss_set_removal_cb(struct ss_device *dev,
|
||||
ss_usb_callback cb, void *usrdata);
|
||||
|
||||
int ss_start_reading(struct ss_device *dev);
|
||||
|
||||
int ss_stop_reading(struct ss_device *dev);
|
||||
|
||||
int ss_set_led(struct ss_device *dev, int led);
|
||||
int ss_set_rumble(struct ss_device *dev, uint8_t duration_right, uint8_t power_right, uint8_t duration_left, uint8_t power_left);
|
||||
|
||||
int ss_set_rumble(struct ss_device *dev, uint8_t duration_right,
|
||||
uint8_t power_right, uint8_t duration_left, uint8_t power_left);
|
||||
|
||||
int ss_get_bd_address(struct ss_device *dev, uint8_t *mac);
|
||||
|
||||
int ss_get_paired_mac(struct ss_device *dev, uint8_t *mac);
|
||||
|
||||
int ss_set_paired_mac(struct ss_device *dev, const uint8_t *mac);
|
||||
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
#include "../file.h"
|
||||
|
||||
static const rarch_joypad_driver_t *joypad_drivers[] = {
|
||||
static rarch_joypad_driver_t *joypad_drivers[] = {
|
||||
#ifndef IS_RETROLAUNCH
|
||||
#ifdef __CELLOS_LV2__
|
||||
&ps3_joypad,
|
||||
|
@ -275,9 +275,9 @@ bool input_translate_coord_viewport(int mouse_x, int mouse_y,
|
|||
int scaled_screen_x = (2 * mouse_x * 0x7fff) / (int)vp.full_width - 0x7fff;
|
||||
int scaled_screen_y = (2 * mouse_y * 0x7fff) / (int)vp.full_height - 0x7fff;
|
||||
if (scaled_screen_x < -0x7fff || scaled_screen_x > 0x7fff)
|
||||
scaled_screen_x = -0x8000; // OOB
|
||||
scaled_screen_x = -0x8000; /* OOB */
|
||||
if (scaled_screen_y < -0x7fff || scaled_screen_y > 0x7fff)
|
||||
scaled_screen_y = -0x8000; // OOB
|
||||
scaled_screen_y = -0x8000; /* OOB */
|
||||
|
||||
mouse_x -= vp.x;
|
||||
mouse_y -= vp.y;
|
||||
|
@ -285,9 +285,9 @@ bool input_translate_coord_viewport(int mouse_x, int mouse_y,
|
|||
int scaled_x = (2 * mouse_x * 0x7fff) / (int)vp.width - 0x7fff;
|
||||
int scaled_y = (2 * mouse_y * 0x7fff) / (int)vp.height - 0x7fff;
|
||||
if (scaled_x < -0x7fff || scaled_x > 0x7fff)
|
||||
scaled_x = -0x8000; // OOB
|
||||
scaled_x = -0x8000; /* OOB */
|
||||
if (scaled_y < -0x7fff || scaled_y > 0x7fff)
|
||||
scaled_y = -0x8000; // OOB
|
||||
scaled_y = -0x8000; /* OOB */
|
||||
|
||||
*res_x = scaled_x;
|
||||
*res_y = scaled_y;
|
||||
|
@ -1193,7 +1193,8 @@ const struct input_key_map input_config_key_map[] = {
|
|||
{ "rctrl", RETROK_RCTRL },
|
||||
{ "ralt", RETROK_RALT },
|
||||
|
||||
/* Keys not referenced in any keyboard mapping (except perhaps apple_key_map_hidusage) */
|
||||
/* Keys not referenced in any keyboard mapping
|
||||
* (except perhaps apple_key_map_hidusage) */
|
||||
{ "caret", RETROK_CARET },
|
||||
{ "underscore", RETROK_UNDERSCORE },
|
||||
{ "exclaim", RETROK_EXCLAIM },
|
||||
|
@ -1450,8 +1451,10 @@ void input_config_autoconfigure_joypad(unsigned index,
|
|||
/* First internal */
|
||||
for (i = 0; input_builtin_autoconfs[i]; i++)
|
||||
{
|
||||
config_file_t *conf = config_file_new_from_string(input_builtin_autoconfs[i]);
|
||||
bool success = input_try_autoconfigure_joypad_from_conf(conf, index, name, driver, block_osd_spam);
|
||||
config_file_t *conf = (config_file_t*)
|
||||
config_file_new_from_string(input_builtin_autoconfs[i]);
|
||||
bool success = input_try_autoconfigure_joypad_from_conf(conf,
|
||||
index, name, driver, block_osd_spam);
|
||||
config_file_free(conf);
|
||||
if (success)
|
||||
break;
|
||||
|
|
|
@ -106,18 +106,18 @@ bool input_joypad_hat_raw(const rarch_joypad_driver_t *driver,
|
|||
const char *input_joypad_name(const rarch_joypad_driver_t *driver,
|
||||
unsigned joypad);
|
||||
|
||||
extern const rarch_joypad_driver_t dinput_joypad;
|
||||
extern const rarch_joypad_driver_t linuxraw_joypad;
|
||||
extern const rarch_joypad_driver_t udev_joypad;
|
||||
extern const rarch_joypad_driver_t winxinput_joypad;
|
||||
extern const rarch_joypad_driver_t sdl_joypad;
|
||||
extern const rarch_joypad_driver_t ps3_joypad;
|
||||
extern const rarch_joypad_driver_t psp_joypad;
|
||||
extern const rarch_joypad_driver_t xdk_joypad;
|
||||
extern const rarch_joypad_driver_t gx_joypad;
|
||||
extern const rarch_joypad_driver_t apple_joypad;
|
||||
extern const rarch_joypad_driver_t android_joypad;
|
||||
extern const rarch_joypad_driver_t qnx_joypad;
|
||||
extern rarch_joypad_driver_t dinput_joypad;
|
||||
extern rarch_joypad_driver_t linuxraw_joypad;
|
||||
extern rarch_joypad_driver_t udev_joypad;
|
||||
extern rarch_joypad_driver_t winxinput_joypad;
|
||||
extern rarch_joypad_driver_t sdl_joypad;
|
||||
extern rarch_joypad_driver_t ps3_joypad;
|
||||
extern rarch_joypad_driver_t psp_joypad;
|
||||
extern rarch_joypad_driver_t xdk_joypad;
|
||||
extern rarch_joypad_driver_t gx_joypad;
|
||||
extern rarch_joypad_driver_t apple_joypad;
|
||||
extern rarch_joypad_driver_t android_joypad;
|
||||
extern rarch_joypad_driver_t qnx_joypad;
|
||||
|
||||
struct rarch_key_map
|
||||
{
|
||||
|
|
|
@ -54,7 +54,8 @@ void input_keyboard_line_free(input_keyboard_line_t *state);
|
|||
void input_keyboard_event(bool down, unsigned code, uint32_t character,
|
||||
uint16_t mod);
|
||||
|
||||
const char **input_keyboard_start_line(void *userdata, input_keyboard_line_complete_t cb);
|
||||
const char **input_keyboard_start_line(void *userdata,
|
||||
input_keyboard_line_complete_t cb);
|
||||
|
||||
/* Wait for keys to be pressed (used for binding keys in the menu).
|
||||
* Callback returns false when all polling is done. */
|
||||
|
|
|
@ -236,7 +236,7 @@ static uint64_t linuxraw_get_capabilities(void *data)
|
|||
return caps;
|
||||
}
|
||||
|
||||
const input_driver_t input_linuxraw = {
|
||||
input_driver_t input_linuxraw = {
|
||||
linuxraw_input_init,
|
||||
linuxraw_input_poll,
|
||||
linuxraw_input_state,
|
||||
|
|
|
@ -305,7 +305,7 @@ static const char *linuxraw_joypad_name(unsigned pad)
|
|||
return *g_pads[pad].ident ? g_pads[pad].ident : NULL;
|
||||
}
|
||||
|
||||
const rarch_joypad_driver_t linuxraw_joypad = {
|
||||
rarch_joypad_driver_t linuxraw_joypad = {
|
||||
linuxraw_joypad_init,
|
||||
linuxraw_joypad_query_pad,
|
||||
linuxraw_joypad_destroy,
|
||||
|
@ -316,4 +316,3 @@ const rarch_joypad_driver_t linuxraw_joypad = {
|
|||
linuxraw_joypad_name,
|
||||
"linuxraw",
|
||||
};
|
||||
|
||||
|
|
|
@ -26,7 +26,9 @@ static void nullinput_input_poll(void *data)
|
|||
(void)data;
|
||||
}
|
||||
|
||||
static int16_t nullinput_input_state(void *data, const struct retro_keybind **retro_keybinds, unsigned port, unsigned device, unsigned index, unsigned id)
|
||||
static int16_t nullinput_input_state(void *data,
|
||||
const struct retro_keybind **retro_keybinds, unsigned port,
|
||||
unsigned device, unsigned index, unsigned id)
|
||||
{
|
||||
(void)data;
|
||||
(void)retro_keybinds;
|
||||
|
@ -60,12 +62,13 @@ static uint64_t nullinput_get_capabilities(void *data)
|
|||
return caps;
|
||||
}
|
||||
|
||||
static bool nullinput_set_sensor_state(void *data, unsigned port, enum retro_sensor_action action, unsigned event_rate)
|
||||
static bool nullinput_set_sensor_state(void *data,
|
||||
unsigned port, enum retro_sensor_action action, unsigned event_rate)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const input_driver_t input_null = {
|
||||
input_driver_t input_null = {
|
||||
nullinput_input_init,
|
||||
nullinput_input_poll,
|
||||
nullinput_input_state,
|
||||
|
|
|
@ -59,7 +59,7 @@ static void nullosk_lifecycle(void *data, uint64_t status)
|
|||
{
|
||||
}
|
||||
|
||||
const input_osk_driver_t input_null_osk = {
|
||||
input_osk_driver_t input_null_osk = {
|
||||
nullosk_init,
|
||||
nullosk_free,
|
||||
nullosk_enable_key_layout,
|
||||
|
|
|
@ -183,7 +183,7 @@ static void oskutil_lifecycle(void *data, uint64_t status)
|
|||
}
|
||||
}
|
||||
|
||||
const input_osk_driver_t input_ps3_osk = {
|
||||
input_osk_driver_t input_ps3_osk = {
|
||||
oskutil_init,
|
||||
oskutil_free,
|
||||
oskutil_enable_key_layout,
|
||||
|
|
|
@ -24,11 +24,14 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Overlay driver acts as a medium between input drivers and video driver.
|
||||
* Coordinates are fetched from input driver, and an overlay with pressable actions are
|
||||
* displayed on-screen.
|
||||
/* Overlay driver acts as a medium between input drivers
|
||||
* and video driver.
|
||||
*
|
||||
* This interface requires that the video driver has support for the overlay interface.
|
||||
* Coordinates are fetched from input driver, and an
|
||||
* overlay with pressable actions are displayed on-screen.
|
||||
*
|
||||
* This interface requires that the video driver has support
|
||||
* for the overlay interface.
|
||||
*/
|
||||
typedef struct input_overlay input_overlay_t;
|
||||
|
||||
|
|
|
@ -351,7 +351,7 @@ static const rarch_joypad_driver_t *ps3_input_get_joypad_driver(void *data)
|
|||
return ps3->joypad;
|
||||
}
|
||||
|
||||
const input_driver_t input_ps3 = {
|
||||
input_driver_t input_ps3 = {
|
||||
ps3_input_init,
|
||||
ps3_input_poll,
|
||||
ps3_input_state,
|
||||
|
|
|
@ -25,8 +25,12 @@ static bool ps3_joypad_init(void)
|
|||
|
||||
for (autoconf_pad = 0; autoconf_pad < MAX_PLAYERS; autoconf_pad++)
|
||||
{
|
||||
strlcpy(g_settings.input.device_names[autoconf_pad], "SixAxis Controller", sizeof(g_settings.input.device_names[autoconf_pad]));
|
||||
input_config_autoconfigure_joypad(autoconf_pad, ps3_joypad_name(autoconf_pad), ps3_joypad.ident);
|
||||
strlcpy(g_settings.input.device_names[autoconf_pad],
|
||||
"SixAxis Controller",
|
||||
sizeof(g_settings.input.device_names[autoconf_pad]));
|
||||
input_config_autoconfigure_joypad(autoconf_pad,
|
||||
ps3_joypad_name(autoconf_pad),
|
||||
ps3_joypad.ident);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -68,10 +72,18 @@ static int16_t ps3_joypad_axis(unsigned port_num, uint32_t joyaxis)
|
|||
|
||||
switch (axis)
|
||||
{
|
||||
case 0: val = ps3->analog_state[port_num][0][0]; break;
|
||||
case 1: val = ps3->analog_state[port_num][0][1]; break;
|
||||
case 2: val = ps3->analog_state[port_num][1][0]; break;
|
||||
case 3: val = ps3->analog_state[port_num][1][1]; break;
|
||||
case 0:
|
||||
val = ps3->analog_state[port_num][0][0];
|
||||
break;
|
||||
case 1:
|
||||
val = ps3->analog_state[port_num][0][1];
|
||||
break;
|
||||
case 2:
|
||||
val = ps3->analog_state[port_num][1][0];
|
||||
break;
|
||||
case 3:
|
||||
val = ps3->analog_state[port_num][1][1];
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_neg && val > 0)
|
||||
|
@ -97,7 +109,7 @@ static void ps3_joypad_destroy(void)
|
|||
{
|
||||
}
|
||||
|
||||
const rarch_joypad_driver_t ps3_joypad = {
|
||||
rarch_joypad_driver_t ps3_joypad = {
|
||||
ps3_joypad_init,
|
||||
ps3_joypad_query_pad,
|
||||
ps3_joypad_destroy,
|
||||
|
|
|
@ -60,7 +60,8 @@ static void psp_input_poll(void *data)
|
|||
#endif
|
||||
(void)ret;
|
||||
|
||||
psp->analog_state[0][0][0] = psp->analog_state[0][0][1] = psp->analog_state[0][1][0] = psp->analog_state[0][1][1] = 0;
|
||||
psp->analog_state[0][0][0] = psp->analog_state[0][0][1] =
|
||||
psp->analog_state[0][1][0] = psp->analog_state[0][1][1] = 0;
|
||||
psp->pad_state = 0;
|
||||
psp->pad_state |= (STATE_BUTTON(state_tmp) & PSP_CTRL_LEFT) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0;
|
||||
psp->pad_state |= (STATE_BUTTON(state_tmp) & PSP_CTRL_DOWN) ? (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0;
|
||||
|
@ -146,7 +147,8 @@ static void* psp_input_initialize(void)
|
|||
static bool psp_input_key_pressed(void *data, int key)
|
||||
{
|
||||
psp_input_t *psp = (psp_input_t*)data;
|
||||
return (g_extern.lifecycle_state & (1ULL << key)) || input_joypad_pressed(psp->joypad, 0, g_settings.input.binds[0], key);
|
||||
return (g_extern.lifecycle_state & (1ULL << key)) ||
|
||||
input_joypad_pressed(psp->joypad, 0, g_settings.input.binds[0], key);
|
||||
}
|
||||
|
||||
static uint64_t psp_input_get_capabilities(void *data)
|
||||
|
@ -165,7 +167,7 @@ static const rarch_joypad_driver_t *psp_input_get_joypad_driver(void *data)
|
|||
return psp->joypad;
|
||||
}
|
||||
|
||||
const input_driver_t input_psp = {
|
||||
input_driver_t input_psp = {
|
||||
psp_input_initialize,
|
||||
psp_input_poll,
|
||||
psp_input_state,
|
||||
|
|
|
@ -25,8 +25,12 @@ static bool psp_joypad_init(void)
|
|||
|
||||
for (autoconf_pad = 0; autoconf_pad < MAX_PADS; autoconf_pad++)
|
||||
{
|
||||
strlcpy(g_settings.input.device_names[autoconf_pad], psp_joypad_name(autoconf_pad), sizeof(g_settings.input.device_names[autoconf_pad]));
|
||||
input_config_autoconfigure_joypad(autoconf_pad, psp_joypad_name(autoconf_pad), psp_joypad.ident);
|
||||
strlcpy(g_settings.input.device_names[autoconf_pad],
|
||||
psp_joypad_name(autoconf_pad),
|
||||
sizeof(g_settings.input.device_names[autoconf_pad]));
|
||||
input_config_autoconfigure_joypad(autoconf_pad,
|
||||
psp_joypad_name(autoconf_pad),
|
||||
psp_joypad.ident);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -67,10 +71,18 @@ static int16_t psp_joypad_axis(unsigned port_num, uint32_t joyaxis)
|
|||
|
||||
switch (axis)
|
||||
{
|
||||
case 0: val = psp->analog_state[port_num][0][0]; break;
|
||||
case 1: val = psp->analog_state[port_num][0][1]; break;
|
||||
case 2: val = psp->analog_state[port_num][1][0]; break;
|
||||
case 3: val = psp->analog_state[port_num][1][1]; break;
|
||||
case 0:
|
||||
val = psp->analog_state[port_num][0][0];
|
||||
break;
|
||||
case 1:
|
||||
val = psp->analog_state[port_num][0][1];
|
||||
break;
|
||||
case 2:
|
||||
val = psp->analog_state[port_num][1][0];
|
||||
break;
|
||||
case 3:
|
||||
val = psp->analog_state[port_num][1][1];
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_neg && val > 0)
|
||||
|
@ -96,7 +108,7 @@ static void psp_joypad_destroy(void)
|
|||
{
|
||||
}
|
||||
|
||||
const rarch_joypad_driver_t psp_joypad = {
|
||||
rarch_joypad_driver_t psp_joypad = {
|
||||
psp_joypad_init,
|
||||
psp_joypad_query_pad,
|
||||
psp_joypad_destroy,
|
||||
|
|
|
@ -67,7 +67,9 @@ typedef struct qnx_input
|
|||
unsigned pointer_count;
|
||||
|
||||
int touch_map[MAX_TOUCH];
|
||||
/*The first pointer_count indices of touch_map will be a valid, active index in pointer array.
|
||||
/*
|
||||
* The first pointer_count indices of touch_map will be a valid,
|
||||
* active index in pointer array.
|
||||
* Saves us from searching through pointer array when polling state.
|
||||
*/
|
||||
input_device_t *port_device[MAX_PADS];
|
||||
|
@ -77,11 +79,14 @@ typedef struct qnx_input
|
|||
uint64_t pad_state[MAX_PADS];
|
||||
} qnx_input_t;
|
||||
|
||||
static void qnx_input_autodetect_gamepad(void *data, input_device_t* controller, int port);
|
||||
static void qnx_input_autodetect_gamepad(void *data,
|
||||
input_device_t* controller, int port);
|
||||
|
||||
static void initController(void *data, input_device_t* controller);
|
||||
|
||||
#ifdef HAVE_BB10
|
||||
static void process_gamepad_event(void *data, screen_event_t screen_event, int type)
|
||||
static void process_gamepad_event(void *data,
|
||||
screen_event_t screen_event, int type)
|
||||
{
|
||||
int i;
|
||||
screen_device_t device;
|
||||
|
@ -90,7 +95,8 @@ static void process_gamepad_event(void *data, screen_event_t screen_event, int t
|
|||
qnx_input_t *qnx = (qnx_input_t*)data;
|
||||
(void)type;
|
||||
|
||||
screen_get_event_property_pv(screen_event, SCREEN_PROPERTY_DEVICE, (void**)&device);
|
||||
screen_get_event_property_pv(screen_event,
|
||||
SCREEN_PROPERTY_DEVICE, (void**)&device);
|
||||
|
||||
for (i = 0; i < MAX_PADS; ++i)
|
||||
{
|
||||
|
@ -104,25 +110,30 @@ static void process_gamepad_event(void *data, screen_event_t screen_event, int t
|
|||
if (!controller)
|
||||
return;
|
||||
|
||||
// Store the controller's new state.
|
||||
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_BUTTONS, &controller->buttons);
|
||||
/* Store the controller's new state. */
|
||||
screen_get_event_property_iv(screen_event,
|
||||
SCREEN_PROPERTY_BUTTONS, &controller->buttons);
|
||||
|
||||
uint64_t *state_cur = (uint64_t*)&qnx->pad_state[controller->port];
|
||||
//int i;
|
||||
|
||||
*state_cur = 0;
|
||||
for (i = 0; i < 20; i++)
|
||||
*state_cur |= (controller->buttons & (1 << i) ? (1 << i) : 0);
|
||||
|
||||
if (controller->analogCount > 0)
|
||||
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_ANALOG0, controller->analog0);
|
||||
screen_get_event_property_iv(screen_event,
|
||||
SCREEN_PROPERTY_ANALOG0, controller->analog0);
|
||||
|
||||
if (controller->analogCount == 2)
|
||||
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_ANALOG1, controller->analog1);
|
||||
screen_get_event_property_iv(screen_event,
|
||||
SCREEN_PROPERTY_ANALOG1, controller->analog1);
|
||||
|
||||
//Only player 1
|
||||
//TODO: Am I missing something? Is there a better way?
|
||||
if((controller->port == 0) && (controller->buttons & g_settings.input.binds[0][RARCH_MENU_TOGGLE].joykey))
|
||||
/* Only player 1
|
||||
* TODO: Am I missing something? Is there a better way?
|
||||
*/
|
||||
if((controller->port == 0) &&
|
||||
(controller->buttons &
|
||||
g_settings.input.binds[0][RARCH_MENU_TOGGLE].joykey))
|
||||
g_extern.lifecycle_state ^= (1ULL << RARCH_MENU_TOGGLE);
|
||||
}
|
||||
|
||||
|
@ -136,25 +147,34 @@ static void loadController(void *data, input_device_t* controller)
|
|||
if (!qnx)
|
||||
return;
|
||||
|
||||
// Query libscreen for information about this device.
|
||||
screen_get_device_property_iv(controller->handle, SCREEN_PROPERTY_TYPE, &controller->type);
|
||||
screen_get_device_property_cv(controller->handle, SCREEN_PROPERTY_ID_STRING, sizeof(controller->id), controller->id);
|
||||
screen_get_device_property_cv(controller->handle, SCREEN_PROPERTY_VENDOR, sizeof(controller->id), controller->vendor);
|
||||
screen_get_device_property_cv(controller->handle, SCREEN_PROPERTY_PRODUCT, sizeof(controller->id), controller->product);
|
||||
/* Query libscreen for information about this device. */
|
||||
screen_get_device_property_iv(controller->handle,
|
||||
SCREEN_PROPERTY_TYPE, &controller->type);
|
||||
screen_get_device_property_cv(controller->handle,
|
||||
SCREEN_PROPERTY_ID_STRING, sizeof(controller->id), controller->id);
|
||||
screen_get_device_property_cv(controller->handle,
|
||||
SCREEN_PROPERTY_VENDOR, sizeof(controller->id), controller->vendor);
|
||||
screen_get_device_property_cv(controller->handle,
|
||||
SCREEN_PROPERTY_PRODUCT, sizeof(controller->id), controller->product);
|
||||
|
||||
if (controller->type == SCREEN_EVENT_GAMEPAD || controller->type == SCREEN_EVENT_JOYSTICK)
|
||||
if (controller->type == SCREEN_EVENT_GAMEPAD ||
|
||||
controller->type == SCREEN_EVENT_JOYSTICK)
|
||||
{
|
||||
screen_get_device_property_iv(controller->handle, SCREEN_PROPERTY_BUTTON_COUNT, &controller->buttonCount);
|
||||
screen_get_device_property_iv(controller->handle,
|
||||
SCREEN_PROPERTY_BUTTON_COUNT, &controller->buttonCount);
|
||||
|
||||
// Check for the existence of analog sticks.
|
||||
if (!screen_get_device_property_iv(controller->handle, SCREEN_PROPERTY_ANALOG0, controller->analog0))
|
||||
/* Check for the existence of analog sticks. */
|
||||
if (!screen_get_device_property_iv(controller->handle,
|
||||
SCREEN_PROPERTY_ANALOG0, controller->analog0))
|
||||
++controller->analogCount;
|
||||
|
||||
if (!screen_get_device_property_iv(controller->handle, SCREEN_PROPERTY_ANALOG1, controller->analog1))
|
||||
if (!screen_get_device_property_iv(controller->handle,
|
||||
SCREEN_PROPERTY_ANALOG1, controller->analog1))
|
||||
++controller->analogCount;
|
||||
}
|
||||
|
||||
//Screen service will map supported controllers, we still might need to adjust.
|
||||
/* Screen service will map supported controllers,
|
||||
* we still might need to adjust. */
|
||||
qnx_input_autodetect_gamepad(qnx, controller, controller->port);
|
||||
|
||||
if (controller->type == SCREEN_EVENT_GAMEPAD)
|
||||
|
@ -175,7 +195,7 @@ extern screen_context_t screen_ctx;
|
|||
|
||||
static void discoverControllers(void *data)
|
||||
{
|
||||
// Get an array of all available devices.
|
||||
/* Get an array of all available devices. */
|
||||
int deviceCount;
|
||||
unsigned i;
|
||||
screen_event_t *event;
|
||||
|
@ -183,11 +203,14 @@ static void discoverControllers(void *data)
|
|||
|
||||
(void)event;
|
||||
|
||||
screen_get_context_property_iv(screen_ctx, SCREEN_PROPERTY_DEVICE_COUNT, &deviceCount);
|
||||
screen_device_t* devices_found = (screen_device_t*)calloc(deviceCount, sizeof(screen_device_t));
|
||||
screen_get_context_property_pv(screen_ctx, SCREEN_PROPERTY_DEVICES, (void**)devices_found);
|
||||
screen_get_context_property_iv(screen_ctx,
|
||||
SCREEN_PROPERTY_DEVICE_COUNT, &deviceCount);
|
||||
screen_device_t* devices_found = (screen_device_t*)
|
||||
calloc(deviceCount, sizeof(screen_device_t));
|
||||
screen_get_context_property_pv(screen_ctx,
|
||||
SCREEN_PROPERTY_DEVICES, (void**)devices_found);
|
||||
|
||||
// Scan the list for gamepad and joystick devices.
|
||||
/* Scan the list for gamepad and joystick devices. */
|
||||
for(i = 0; i < qnx->pads_connected; ++i)
|
||||
initController(qnx, &qnx->devices[i]);
|
||||
|
||||
|
@ -196,9 +219,13 @@ static void discoverControllers(void *data)
|
|||
for (i = 0; i < deviceCount; i++)
|
||||
{
|
||||
int type;
|
||||
screen_get_device_property_iv(devices_found[i], SCREEN_PROPERTY_TYPE, &type);
|
||||
screen_get_device_property_iv(
|
||||
devices_found[i], SCREEN_PROPERTY_TYPE, &type);
|
||||
|
||||
if (type == SCREEN_EVENT_GAMEPAD || type == SCREEN_EVENT_JOYSTICK || type == SCREEN_EVENT_KEYBOARD)
|
||||
if (
|
||||
type == SCREEN_EVENT_GAMEPAD ||
|
||||
type == SCREEN_EVENT_JOYSTICK ||
|
||||
type == SCREEN_EVENT_KEYBOARD)
|
||||
{
|
||||
qnx->devices[qnx->pads_connected].handle = devices_found[i];
|
||||
qnx->devices[qnx->pads_connected].index = qnx->pads_connected;
|
||||
|
@ -219,7 +246,7 @@ static void initController(void *data, input_device_t* controller)
|
|||
|
||||
if (qnx)
|
||||
{
|
||||
// Initialize controller values.
|
||||
/* Initialize controller values. */
|
||||
#ifdef HAVE_BB10
|
||||
controller->handle = 0;
|
||||
#endif
|
||||
|
@ -227,8 +254,12 @@ static void initController(void *data, input_device_t* controller)
|
|||
controller->analogCount = 0;
|
||||
controller->buttonCount = 0;
|
||||
controller->buttons = 0;
|
||||
controller->analog0[0] = controller->analog0[1] = controller->analog0[2] = 0;
|
||||
controller->analog1[0] = controller->analog1[1] = controller->analog1[2] = 0;
|
||||
controller->analog0[0] = 0;
|
||||
controller->analog0[1] = 0;
|
||||
controller->analog0[2] = 0;
|
||||
controller->analog1[0] = 0;
|
||||
controller->analog1[1] = 0;
|
||||
controller->analog1[2] = 0;
|
||||
controller->port = -1;
|
||||
controller->device = -1;
|
||||
controller->index = -1;
|
||||
|
@ -237,7 +268,8 @@ static void initController(void *data, input_device_t* controller)
|
|||
}
|
||||
}
|
||||
|
||||
static void qnx_input_autodetect_gamepad(void *data, input_device_t* controller, int port)
|
||||
static void qnx_input_autodetect_gamepad(void *data,
|
||||
input_device_t* controller, int port)
|
||||
{
|
||||
char name_buf[256];
|
||||
qnx_input_t *qnx = (qnx_input_t*)data;
|
||||
|
@ -247,11 +279,13 @@ static void qnx_input_autodetect_gamepad(void *data, input_device_t* controller,
|
|||
|
||||
name_buf[0] = '\0';
|
||||
|
||||
//ID: A-BBBB-CCCC-D.D
|
||||
//A is the device's index in the array returned by screen_get_context_property_pv()
|
||||
//BBBB is the device's Vendor ID (in hexadecimal)
|
||||
//CCCC is the device's Product ID (also in hexadecimal)
|
||||
//D.D is the device's version number
|
||||
/* ID: A-BBBB-CCCC-D.D
|
||||
* A is the device's index in the array
|
||||
* returned by screen_get_context_property_pv()
|
||||
* BBBB is the device's Vendor ID (in hexadecimal)
|
||||
* CCCC is the device's Product ID (also in hexadecimal)
|
||||
* D.D is the device's version number
|
||||
*/
|
||||
if (controller)
|
||||
{
|
||||
#ifdef HAVE_BB10
|
||||
|
@ -269,7 +303,8 @@ static void qnx_input_autodetect_gamepad(void *data, input_device_t* controller,
|
|||
|
||||
if (name_buf[0] != '\0')
|
||||
{
|
||||
strlcpy(g_settings.input.device_names[port], name_buf, sizeof(g_settings.input.device_names[port]));
|
||||
strlcpy(g_settings.input.device_names[port],
|
||||
name_buf, sizeof(g_settings.input.device_names[port]));
|
||||
input_config_autoconfigure_joypad(port, name_buf, qnx->joypad);
|
||||
|
||||
controller->port = port;
|
||||
|
@ -293,18 +328,24 @@ static void process_keyboard_event(void *data, screen_event_t event, int type)
|
|||
scan = 0;
|
||||
cap = 0;
|
||||
|
||||
//Get Keyboard state
|
||||
screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SYM, &sym);
|
||||
screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_MODIFIERS, &modifiers);
|
||||
screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_FLAGS, &flags);
|
||||
screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SCAN, &scan);
|
||||
screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_CAP, &cap);
|
||||
/* Get Keyboard state. */
|
||||
screen_get_event_property_iv(event,
|
||||
SCREEN_PROPERTY_KEY_SYM, &sym);
|
||||
screen_get_event_property_iv(event,
|
||||
SCREEN_PROPERTY_KEY_MODIFIERS, &modifiers);
|
||||
screen_get_event_property_iv(event,
|
||||
SCREEN_PROPERTY_KEY_FLAGS, &flags);
|
||||
screen_get_event_property_iv(event,
|
||||
SCREEN_PROPERTY_KEY_SCAN, &scan);
|
||||
screen_get_event_property_iv(event,
|
||||
SCREEN_PROPERTY_KEY_CAP, &cap);
|
||||
|
||||
#ifdef HAVE_BB10
|
||||
//Find device that pressed the key
|
||||
/* Find device that pressed the key. */
|
||||
screen_device_t device;
|
||||
|
||||
screen_get_event_property_pv(event, SCREEN_PROPERTY_DEVICE, (void**)&device);
|
||||
screen_get_event_property_pv(event,
|
||||
SCREEN_PROPERTY_DEVICE, (void**)&device);
|
||||
|
||||
for (i = 0; i < MAX_PADS; ++i)
|
||||
{
|
||||
|
@ -329,7 +370,9 @@ static void process_keyboard_event(void *data, screen_event_t event, int type)
|
|||
|
||||
for (b = 0; b < RARCH_FIRST_CUSTOM_BIND; ++b)
|
||||
{
|
||||
if ((unsigned int)g_settings.input.binds[controller->port][b].joykey == (unsigned int)(sym & 0xFF))
|
||||
if ((unsigned int)
|
||||
g_settings.input.binds[controller->port][b].joykey
|
||||
== (unsigned int)(sym & 0xFF))
|
||||
{
|
||||
if (flags & KEY_DOWN)
|
||||
{
|
||||
|
@ -341,8 +384,10 @@ static void process_keyboard_event(void *data, screen_event_t event, int type)
|
|||
}
|
||||
}
|
||||
|
||||
//TODO: Am I missing something? Is there a better way?
|
||||
if((controller->port == 0) && ((unsigned int)g_settings.input.binds[0][RARCH_MENU_TOGGLE].joykey == (unsigned int)(sym&0xFF)))
|
||||
/* TODO: Am I missing something? Is there a better way? */
|
||||
if((controller->port == 0) && ((unsigned int)
|
||||
g_settings.input.binds[0][RARCH_MENU_TOGGLE].joykey
|
||||
== (unsigned int)(sym&0xFF)))
|
||||
{
|
||||
if (flags & KEY_DOWN)
|
||||
g_extern.lifecycle_state ^= (1ULL << RARCH_MENU_TOGGLE);
|
||||
|
@ -355,13 +400,15 @@ static void process_touch_event(void *data, screen_event_t event, int type)
|
|||
unsigned i, j;
|
||||
qnx_input_t *qnx = (qnx_input_t*)data;
|
||||
|
||||
screen_get_event_property_iv(event, SCREEN_PROPERTY_TOUCH_ID, (int*)&contact_id);
|
||||
screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, pos);
|
||||
screen_get_event_property_iv(event,
|
||||
SCREEN_PROPERTY_TOUCH_ID, (int*)&contact_id);
|
||||
screen_get_event_property_iv(event,
|
||||
SCREEN_PROPERTY_SOURCE_POSITION, pos);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case SCREEN_EVENT_MTOUCH_TOUCH:
|
||||
//Find a free touch struct
|
||||
/* Find a free touch struct. */
|
||||
for(i = 0; i < MAX_TOUCH; ++i)
|
||||
{
|
||||
if(qnx->pointer[i].contact_id == -1)
|
||||
|
@ -370,25 +417,34 @@ static void process_touch_event(void *data, screen_event_t event, int type)
|
|||
input_translate_coord_viewport(pos[0], pos[1],
|
||||
&qnx->pointer[i].x, &qnx->pointer[i].y,
|
||||
&qnx->pointer[i].full_x, &qnx->pointer[i].full_y);
|
||||
//Add this pointer to the map to signal it's valid
|
||||
|
||||
/* Add this pointer to the map to signal it's valid. */
|
||||
qnx->pointer[i].map = qnx->pointer_count;
|
||||
qnx->touch_map[qnx->pointer_count] = i;
|
||||
qnx->pointer_count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//printf("New Touch: x:%d, y:%d, id:%d\n", pos[0], pos[1], contact_id);fflush(stdout);
|
||||
//printf("Map: %d %d %d %d %d %d\n", qnx->touch_map[0], qnx->touch_map[1], qnx->touch_map[2], qnx->touch_map[3], qnx->touch_map[4], qnx->touch_map[5]);fflush(stdout);
|
||||
#if 0
|
||||
printf("New Touch: x:%d, y:%d, id:%d\n", pos[0], pos[1], contact_id);
|
||||
fflush(stdout);
|
||||
printf("Map: %d %d %d %d %d %d\n", qnx->touch_map[0], qnx->touch_map[1],
|
||||
qnx->touch_map[2], qnx->touch_map[3], qnx->touch_map[4],
|
||||
qnx->touch_map[5]);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case SCREEN_EVENT_MTOUCH_RELEASE:
|
||||
for(i = 0; i < MAX_TOUCH; ++i)
|
||||
{
|
||||
if(qnx->pointer[i].contact_id == contact_id)
|
||||
{
|
||||
//Invalidate the finger
|
||||
/* Invalidate the finger. */
|
||||
qnx->pointer[i].contact_id = -1;
|
||||
|
||||
//Remove pointer from map and shift remaining valid ones to the front
|
||||
/* Remove pointer from map and shift
|
||||
* remaining valid ones to the front. */
|
||||
qnx->touch_map[qnx->pointer[i].map] = -1;
|
||||
for(j = qnx->pointer[i].map; j < qnx->pointer_count; ++j)
|
||||
{
|
||||
|
@ -400,19 +456,29 @@ static void process_touch_event(void *data, screen_event_t event, int type)
|
|||
break;
|
||||
}
|
||||
}
|
||||
//printf("Release: x:%d, y:%d, id:%d\n", pos[0], pos[1], contact_id);fflush(stdout);
|
||||
//printf("Map: %d %d %d %d %d %d\n", qnx->touch_map[0], qnx->touch_map[1], qnx->touch_map[2], qnx->touch_map[3], qnx->touch_map[4], qnx->touch_map[5]);fflush(stdout);
|
||||
#if 0
|
||||
printf("Release: x:%d, y:%d, id:%d\n", pos[0], pos[1], contact_id);
|
||||
fflush(stdout);
|
||||
printf("Map: %d %d %d %d %d %d\n", qnx->touch_map[0], qnx->touch_map[1],
|
||||
qnx->touch_map[2], qnx->touch_map[3], qnx->touch_map[4],
|
||||
qnx->touch_map[5]);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case SCREEN_EVENT_MTOUCH_MOVE:
|
||||
//Find the finger we're tracking and update
|
||||
/* Find the finger we're tracking and update. */
|
||||
for(i = 0; i < qnx->pointer_count; ++i)
|
||||
{
|
||||
if(qnx->pointer[i].contact_id == contact_id)
|
||||
{
|
||||
gl_t *gl = (gl_t*)driver.video_data;
|
||||
|
||||
//During a move, we can go ~30 pixel into the bezel which gives negative
|
||||
//numbers or numbers larger than the screen res. Normalize.
|
||||
/*During a move, we can go ~30 pixel into the
|
||||
* bezel which gives negative numbers or
|
||||
* numbers larger than the screen resolution.
|
||||
*
|
||||
* Normalize. */
|
||||
if(pos[0] < 0)
|
||||
pos[0] = 0;
|
||||
if(pos[0] > gl->full_x)
|
||||
|
@ -426,7 +492,11 @@ static void process_touch_event(void *data, screen_event_t event, int type)
|
|||
input_translate_coord_viewport(pos[0], pos[1],
|
||||
&qnx->pointer[i].x, &qnx->pointer[i].y,
|
||||
&qnx->pointer[i].full_x, &qnx->pointer[i].full_y);
|
||||
//printf("Move: x:%d, y:%d, id:%d\n", pos[0], pos[1], contact_id);fflush(stdout);
|
||||
#if 0
|
||||
printf("Move: x:%d, y:%d, id:%d\n", pos[0], pos[1],
|
||||
contact_id);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -459,7 +529,7 @@ static void handle_screen_event(void *data, bps_event_t *event)
|
|||
break;
|
||||
case SCREEN_EVENT_DEVICE:
|
||||
{
|
||||
// A device was attached or removed.
|
||||
/* A device was attached or removed. */
|
||||
screen_device_t device;
|
||||
int attached, type, i;
|
||||
|
||||
|
@ -472,7 +542,11 @@ static void handle_screen_event(void *data, bps_event_t *event)
|
|||
screen_get_device_property_iv(device,
|
||||
SCREEN_PROPERTY_TYPE, &type);
|
||||
|
||||
if (attached && (type == SCREEN_EVENT_GAMEPAD || type == SCREEN_EVENT_JOYSTICK || type == SCREEN_EVENT_KEYBOARD))
|
||||
if (attached && (
|
||||
type == SCREEN_EVENT_GAMEPAD ||
|
||||
type == SCREEN_EVENT_JOYSTICK ||
|
||||
type == SCREEN_EVENT_KEYBOARD)
|
||||
)
|
||||
{
|
||||
for (i = 0; i < MAX_PADS; ++i)
|
||||
{
|
||||
|
@ -490,7 +564,8 @@ static void handle_screen_event(void *data, bps_event_t *event)
|
|||
{
|
||||
if (device == qnx->devices[i].handle)
|
||||
{
|
||||
RARCH_LOG("Device %s: Disconnected.\n", qnx->devices[i].id);
|
||||
RARCH_LOG("Device %s: Disconnected.\n",
|
||||
qnx->devices[i].id);
|
||||
initController(data, &qnx->devices[i]);
|
||||
break;
|
||||
}
|
||||
|
@ -519,7 +594,7 @@ static void handle_navigator_event(void *data, bps_event_t *event)
|
|||
g_extern.lifecycle_state ^= (1ULL << RARCH_MENU_TOGGLE);
|
||||
break;
|
||||
case NAVIGATOR_EXIT:
|
||||
//Catch this in thumbnail loop
|
||||
/* Catch this in thumbnail loop. */
|
||||
break;
|
||||
case NAVIGATOR_WINDOW_STATE:
|
||||
state = navigator_event_get_window_state(event);
|
||||
|
@ -529,7 +604,7 @@ static void handle_navigator_event(void *data, bps_event_t *event)
|
|||
case NAVIGATOR_WINDOW_THUMBNAIL:
|
||||
for(;;)
|
||||
{
|
||||
//Block until we get a resume or exit event
|
||||
/* Block until we get a resume or exit event. */
|
||||
rc = bps_get_event(&event_pause, -1);
|
||||
|
||||
if(bps_event_get_code(event_pause) == NAVIGATOR_WINDOW_STATE)
|
||||
|
@ -556,7 +631,6 @@ static void handle_navigator_event(void *data, bps_event_t *event)
|
|||
}
|
||||
}
|
||||
|
||||
//External Functions
|
||||
static void *qnx_input_init(void)
|
||||
{
|
||||
int i;
|
||||
|
@ -579,11 +653,12 @@ static void *qnx_input_init(void)
|
|||
}
|
||||
|
||||
#ifdef HAVE_BB10
|
||||
//Find currently connected gamepads
|
||||
/* Find currently connected gamepads. */
|
||||
discoverControllers(qnx);
|
||||
#else
|
||||
//Initialize Playbook keyboard
|
||||
strlcpy(qnx->devices[0].id, "0A5C-8502", sizeof(qnx->devices[0].id));
|
||||
/* Initialize Playbook keyboard. */
|
||||
strlcpy(qnx->devices[0].id, "0A5C-8502",
|
||||
sizeof(qnx->devices[0].id));
|
||||
qnx_input_autodetect_gamepad(qnx, &qnx->devices[0], 0);
|
||||
qnx->pads_connected = 1;
|
||||
#endif
|
||||
|
@ -594,7 +669,7 @@ static void *qnx_input_init(void)
|
|||
static void qnx_input_poll(void *data)
|
||||
{
|
||||
(void)data;
|
||||
//Request and process all available BPS events
|
||||
/* Request and process all available BPS events. */
|
||||
|
||||
int rc, domain;
|
||||
|
||||
|
@ -620,19 +695,23 @@ static void qnx_input_poll(void *data)
|
|||
}
|
||||
}
|
||||
|
||||
static int16_t qnx_input_state(void *data, const struct retro_keybind **retro_keybinds, unsigned port, unsigned device, unsigned index, unsigned id)
|
||||
static int16_t qnx_input_state(void *data,
|
||||
const struct retro_keybind **retro_keybinds,
|
||||
unsigned port, unsigned device, unsigned index, unsigned id)
|
||||
{
|
||||
qnx_input_t *qnx = (qnx_input_t*)data;
|
||||
|
||||
switch (device)
|
||||
{
|
||||
case RETRO_DEVICE_JOYPAD:
|
||||
return input_joypad_pressed(qnx->joypad, port, (unsigned int)g_settings.input.binds[port], id);
|
||||
return input_joypad_pressed(qnx->joypad, port,
|
||||
(unsigned int)g_settings.input.binds[port], id);
|
||||
#ifdef HAVE_BB10
|
||||
case RETRO_DEVICE_ANALOG:
|
||||
//Need to return [-0x8000, 0x7fff]
|
||||
//Gamepad API gives us [-128, 127] with (0,0) center
|
||||
//Untested
|
||||
/* Need to return [-0x8000, 0x7fff].
|
||||
* Gamepad API gives us [-128, 127] with (0,0) center
|
||||
* Untested
|
||||
*/
|
||||
if(qnx->port_device[port])
|
||||
{
|
||||
switch ((index << 1) | id)
|
||||
|
@ -659,7 +738,10 @@ static int16_t qnx_input_state(void *data, const struct retro_keybind **retro_ke
|
|||
case RETRO_DEVICE_ID_POINTER_Y:
|
||||
return qnx->pointer[qnx->touch_map[index]].full_y;
|
||||
case RETRO_DEVICE_ID_POINTER_PRESSED:
|
||||
return (index < qnx->pointer_count) && (qnx->pointer[index].full_x != -0x8000) && (qnx->pointer[index].full_y != -0x8000);
|
||||
return (
|
||||
index < qnx->pointer_count)
|
||||
&& (qnx->pointer[index].full_x != -0x8000)
|
||||
&& (qnx->pointer[index].full_y != -0x8000);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -672,7 +754,10 @@ static int16_t qnx_input_state(void *data, const struct retro_keybind **retro_ke
|
|||
case RETRO_DEVICE_ID_POINTER_Y:
|
||||
return qnx->pointer[qnx->touch_map[index]].y;
|
||||
case RETRO_DEVICE_ID_POINTER_PRESSED:
|
||||
return (index < qnx->pointer_count) && (qnx->pointer[index].x != -0x8000) && (qnx->pointer[index].y != -0x8000);
|
||||
return (
|
||||
index < qnx->pointer_count)
|
||||
&& (qnx->pointer[index].x != -0x8000)
|
||||
&& (qnx->pointer[index].y != -0x8000);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -717,7 +802,7 @@ static const rarch_joypad_driver_t *qnx_input_get_joypad_driver(void *data)
|
|||
return qnx->joypad;
|
||||
}
|
||||
|
||||
const input_driver_t input_qnx = {
|
||||
input_driver_t input_qnx = {
|
||||
qnx_input_init,
|
||||
qnx_input_poll,
|
||||
qnx_input_state,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue