mirror of
https://github.com/libretro/RetroArch
synced 2025-02-10 12:40:03 +00:00
Merge branch 'master' into Shader_Save_Load
This commit is contained in:
commit
5008ac6eb0
@ -99,8 +99,8 @@ matrix:
|
|||||||
android:
|
android:
|
||||||
components:
|
components:
|
||||||
- tools
|
- tools
|
||||||
- build-tools-28.0.3
|
- build-tools-29.0.3
|
||||||
- android-28
|
- android-29
|
||||||
install:
|
install:
|
||||||
- echo y | sdkmanager "ndk-bundle"
|
- echo y | sdkmanager "ndk-bundle"
|
||||||
before_script:
|
before_script:
|
||||||
|
@ -156,8 +156,8 @@ endif
|
|||||||
ifeq ($(TARGET), retroarch_3ds)
|
ifeq ($(TARGET), retroarch_3ds)
|
||||||
OBJ += frontend/drivers/platform_ctr.o
|
OBJ += frontend/drivers/platform_ctr.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Git Version
|
# Git Version
|
||||||
|
ifeq ($(HAVE_GIT_VERSION), 1)
|
||||||
GIT_VERSION_CACHEDIR = $(if $(OBJDIR),$(OBJDIR),$(CURDIR))
|
GIT_VERSION_CACHEDIR = $(if $(OBJDIR),$(OBJDIR),$(CURDIR))
|
||||||
GIT_VERSION_CACHEFILE = $(GIT_VERSION_CACHEDIR)/git-version.cache
|
GIT_VERSION_CACHEFILE = $(GIT_VERSION_CACHEDIR)/git-version.cache
|
||||||
|
|
||||||
@ -185,6 +185,7 @@ ifneq ($(GIT_VERSION),) # Enable version_git.o?
|
|||||||
DEFINES += -DHAVE_GIT_VERSION -DGIT_VERSION=$(GIT_VERSION)
|
DEFINES += -DHAVE_GIT_VERSION -DGIT_VERSION=$(GIT_VERSION)
|
||||||
OBJ += version_git.o
|
OBJ += version_git.o
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
# General object files
|
# General object files
|
||||||
ifeq ($(HAVE_DR_MP3), 1)
|
ifeq ($(HAVE_DR_MP3), 1)
|
||||||
@ -2260,6 +2261,7 @@ ifeq ($(HAVE_STATIC_VIDEO_FILTERS), 1)
|
|||||||
gfx/video_filters/normal2x.o \
|
gfx/video_filters/normal2x.o \
|
||||||
gfx/video_filters/normal2x_width.o \
|
gfx/video_filters/normal2x_width.o \
|
||||||
gfx/video_filters/normal2x_height.o \
|
gfx/video_filters/normal2x_height.o \
|
||||||
|
gfx/video_filters/normal4x.o \
|
||||||
gfx/video_filters/scanline2x.o \
|
gfx/video_filters/scanline2x.o \
|
||||||
gfx/video_filters/grid2x.o \
|
gfx/video_filters/grid2x.o \
|
||||||
gfx/video_filters/grid3x.o \
|
gfx/video_filters/grid3x.o \
|
||||||
|
@ -83,12 +83,12 @@ static void *alsa_init(const char *device, unsigned rate, unsigned latency,
|
|||||||
if (snd_pcm_hw_params_malloc(¶ms) < 0)
|
if (snd_pcm_hw_params_malloc(¶ms) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
alsa->has_float = find_float_format(alsa->pcm, params);
|
|
||||||
format = alsa->has_float ? SND_PCM_FORMAT_FLOAT : SND_PCM_FORMAT_S16;
|
|
||||||
|
|
||||||
if (snd_pcm_hw_params_any(alsa->pcm, params) < 0)
|
if (snd_pcm_hw_params_any(alsa->pcm, params) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
alsa->has_float = find_float_format(alsa->pcm, params);
|
||||||
|
format = alsa->has_float ? SND_PCM_FORMAT_FLOAT : SND_PCM_FORMAT_S16;
|
||||||
|
|
||||||
if (snd_pcm_hw_params_set_access(
|
if (snd_pcm_hw_params_set_access(
|
||||||
alsa->pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0)
|
alsa->pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -173,10 +173,11 @@ static void *alsa_thread_init(const char *device,
|
|||||||
TRY_ALSA(snd_pcm_open(&alsa->pcm, alsa_dev, SND_PCM_STREAM_PLAYBACK, 0));
|
TRY_ALSA(snd_pcm_open(&alsa->pcm, alsa_dev, SND_PCM_STREAM_PLAYBACK, 0));
|
||||||
|
|
||||||
TRY_ALSA(snd_pcm_hw_params_malloc(¶ms));
|
TRY_ALSA(snd_pcm_hw_params_malloc(¶ms));
|
||||||
|
TRY_ALSA(snd_pcm_hw_params_any(alsa->pcm, params));
|
||||||
|
|
||||||
alsa->has_float = alsathread_find_float_format(alsa->pcm, params);
|
alsa->has_float = alsathread_find_float_format(alsa->pcm, params);
|
||||||
format = alsa->has_float ? SND_PCM_FORMAT_FLOAT : SND_PCM_FORMAT_S16;
|
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(
|
TRY_ALSA(snd_pcm_hw_params_set_access(
|
||||||
alsa->pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED));
|
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_format(alsa->pcm, params, format));
|
||||||
|
@ -1597,7 +1597,8 @@ static int rcheevos_match_value(const char* val, const char* match)
|
|||||||
|
|
||||||
void rcheevos_validate_config_settings(void)
|
void rcheevos_validate_config_settings(void)
|
||||||
{
|
{
|
||||||
const rc_disallowed_core_settings_t* core_filter = rc_disallowed_core_settings;
|
const rc_disallowed_core_settings_t
|
||||||
|
*core_filter = rc_disallowed_core_settings;
|
||||||
struct retro_system_info* system = runloop_get_libretro_system_info();
|
struct retro_system_info* system = runloop_get_libretro_system_info();
|
||||||
if (!system->library_name || !rcheevos_hardcore_active())
|
if (!system->library_name || !rcheevos_hardcore_active())
|
||||||
return;
|
return;
|
||||||
@ -1610,25 +1611,31 @@ void rcheevos_validate_config_settings(void)
|
|||||||
|
|
||||||
if (rarch_ctl(RARCH_CTL_CORE_OPTIONS_LIST_GET, &coreopts))
|
if (rarch_ctl(RARCH_CTL_CORE_OPTIONS_LIST_GET, &coreopts))
|
||||||
{
|
{
|
||||||
const rc_disallowed_setting_t* disallowed_setting = core_filter->disallowed_settings;
|
|
||||||
const char* key;
|
|
||||||
const char* val;
|
|
||||||
int i;
|
int i;
|
||||||
|
const char *key = NULL;
|
||||||
|
const char *val = NULL;
|
||||||
|
const rc_disallowed_setting_t
|
||||||
|
*disallowed_setting = core_filter->disallowed_settings;
|
||||||
int allowed = 1;
|
int allowed = 1;
|
||||||
size_t key_len;
|
|
||||||
|
|
||||||
for (; disallowed_setting->setting; ++disallowed_setting)
|
for (; disallowed_setting->setting; ++disallowed_setting)
|
||||||
{
|
{
|
||||||
|
size_t key_len;
|
||||||
key = disallowed_setting->setting;
|
key = disallowed_setting->setting;
|
||||||
key_len = strlen(key);
|
key_len = strlen(key);
|
||||||
|
|
||||||
if (key[key_len - 1] == '*')
|
if (key[key_len - 1] == '*')
|
||||||
{
|
{
|
||||||
for (i = 0; i < coreopts->size; i++)
|
for (i = 0; i < coreopts->size; i++)
|
||||||
{
|
{
|
||||||
if (string_starts_with_size(coreopts->opts[i].key, key, key_len - 1))
|
if (string_starts_with_size(
|
||||||
|
coreopts->opts[i].key, key, key_len - 1))
|
||||||
{
|
{
|
||||||
val = core_option_manager_get_val(coreopts, i);
|
const char* val =core_option_manager_get_val(coreopts, i);
|
||||||
if (rcheevos_match_value(val, disallowed_setting->value))
|
if (val)
|
||||||
|
{
|
||||||
|
if (rcheevos_match_value(
|
||||||
|
val, disallowed_setting->value))
|
||||||
{
|
{
|
||||||
key = coreopts->opts[i].key;
|
key = coreopts->opts[i].key;
|
||||||
allowed = 0;
|
allowed = 0;
|
||||||
@ -1637,6 +1644,7 @@ void rcheevos_validate_config_settings(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i = 0; i < coreopts->size; i++)
|
for (i = 0; i < coreopts->size; i++)
|
||||||
|
@ -196,6 +196,7 @@ enum event_command
|
|||||||
CMD_EVENT_OSK_TOGGLE,
|
CMD_EVENT_OSK_TOGGLE,
|
||||||
CMD_EVENT_RECORDING_TOGGLE,
|
CMD_EVENT_RECORDING_TOGGLE,
|
||||||
CMD_EVENT_STREAMING_TOGGLE,
|
CMD_EVENT_STREAMING_TOGGLE,
|
||||||
|
CMD_EVENT_RUNAHEAD_TOGGLE,
|
||||||
CMD_EVENT_AI_SERVICE_TOGGLE,
|
CMD_EVENT_AI_SERVICE_TOGGLE,
|
||||||
CMD_EVENT_BSV_RECORDING_TOGGLE,
|
CMD_EVENT_BSV_RECORDING_TOGGLE,
|
||||||
CMD_EVENT_SHADER_NEXT,
|
CMD_EVENT_SHADER_NEXT,
|
||||||
|
@ -1146,7 +1146,11 @@ static const int default_content_favorites_size = 200;
|
|||||||
|
|
||||||
/* Default scale factor for non-frambuffer-based display
|
/* Default scale factor for non-frambuffer-based display
|
||||||
* drivers and display widgets */
|
* drivers and display widgets */
|
||||||
|
#if defined(VITA)
|
||||||
|
#define DEFAULT_MENU_SCALE_FACTOR 1.5f
|
||||||
|
#else
|
||||||
#define DEFAULT_MENU_SCALE_FACTOR 1.0f
|
#define DEFAULT_MENU_SCALE_FACTOR 1.0f
|
||||||
|
#endif
|
||||||
/* Specifies whether display widgets should be scaled
|
/* Specifies whether display widgets should be scaled
|
||||||
* automatically using the default menu scale factor */
|
* automatically using the default menu scale factor */
|
||||||
#define DEFAULT_MENU_WIDGET_SCALE_AUTO true
|
#define DEFAULT_MENU_WIDGET_SCALE_AUTO true
|
||||||
|
@ -563,6 +563,13 @@ static const struct retro_keybind retro_keybinds_1[] = {
|
|||||||
RARCH_STREAMING_TOGGLE, NO_BTN, NO_BTN, 0,
|
RARCH_STREAMING_TOGGLE, NO_BTN, NO_BTN, 0,
|
||||||
true
|
true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
NULL, NULL,
|
||||||
|
AXIS_NONE, AXIS_NONE, AXIS_NONE,
|
||||||
|
MENU_ENUM_LABEL_VALUE_INPUT_META_RUNAHEAD_TOGGLE, RETROK_UNKNOWN,
|
||||||
|
RARCH_RUNAHEAD_TOGGLE, NO_BTN, NO_BTN, 0,
|
||||||
|
true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
AXIS_NONE, AXIS_NONE, AXIS_NONE,
|
AXIS_NONE, AXIS_NONE, AXIS_NONE,
|
||||||
@ -1110,6 +1117,13 @@ static const struct retro_keybind retro_keybinds_1[] = {
|
|||||||
RARCH_STREAMING_TOGGLE, NO_BTN, NO_BTN, 0,
|
RARCH_STREAMING_TOGGLE, NO_BTN, NO_BTN, 0,
|
||||||
true
|
true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
NULL, NULL,
|
||||||
|
AXIS_NONE, AXIS_NONE, AXIS_NONE,
|
||||||
|
MENU_ENUM_LABEL_VALUE_INPUT_META_RUNAHEAD_TOGGLE, RETROK_UNKNOWN,
|
||||||
|
RARCH_RUNAHEAD_TOGGLE, NO_BTN, NO_BTN, 0,
|
||||||
|
true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
AXIS_NONE, AXIS_NONE, AXIS_NONE,
|
AXIS_NONE, AXIS_NONE, AXIS_NONE,
|
||||||
@ -1667,6 +1681,13 @@ static const struct retro_keybind retro_keybinds_1[] = {
|
|||||||
RARCH_STREAMING_TOGGLE, NO_BTN, NO_BTN, 0,
|
RARCH_STREAMING_TOGGLE, NO_BTN, NO_BTN, 0,
|
||||||
true
|
true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
NULL, NULL,
|
||||||
|
AXIS_NONE, AXIS_NONE, AXIS_NONE,
|
||||||
|
MENU_ENUM_LABEL_VALUE_INPUT_META_RUNAHEAD_TOGGLE, RETROK_UNKNOWN,
|
||||||
|
RARCH_RUNAHEAD_TOGGLE, NO_BTN, NO_BTN, 0,
|
||||||
|
true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
AXIS_NONE, AXIS_NONE, AXIS_NONE,
|
AXIS_NONE, AXIS_NONE, AXIS_NONE,
|
||||||
|
9
deps/discord-rpc/src/backoff.h
vendored
9
deps/discord-rpc/src/backoff.h
vendored
@ -10,31 +10,26 @@ struct Backoff
|
|||||||
int64_t minAmount;
|
int64_t minAmount;
|
||||||
int64_t maxAmount;
|
int64_t maxAmount;
|
||||||
int64_t current;
|
int64_t current;
|
||||||
int fails;
|
|
||||||
std::mt19937_64 randGenerator;
|
std::mt19937_64 randGenerator;
|
||||||
std::uniform_real_distribution<> randDistribution;
|
std::uniform_real_distribution<> randDistribution;
|
||||||
|
|
||||||
double rand01() { return randDistribution(randGenerator); }
|
|
||||||
|
|
||||||
Backoff(int64_t min, int64_t max)
|
Backoff(int64_t min, int64_t max)
|
||||||
: minAmount(min)
|
: minAmount(min)
|
||||||
, maxAmount(max)
|
, maxAmount(max)
|
||||||
, current(min)
|
, current(min)
|
||||||
, fails(0)
|
|
||||||
, randGenerator((uint64_t)time(0))
|
, randGenerator((uint64_t)time(0))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
fails = 0;
|
|
||||||
current = minAmount;
|
current = minAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t nextDelay()
|
int64_t nextDelay()
|
||||||
{
|
{
|
||||||
++fails;
|
int64_t delay = (int64_t)((double)current * 2.0 *
|
||||||
int64_t delay = (int64_t)((double)current * 2.0 * rand01());
|
randDistribution(randGenerator));
|
||||||
current = std::min(current + delay, maxAmount);
|
current = std::min(current + delay, maxAmount);
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
144
deps/discord-rpc/src/discord_rpc.cpp
vendored
144
deps/discord-rpc/src/discord_rpc.cpp
vendored
@ -10,22 +10,10 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#ifndef DISCORD_DISABLE_IO_THREAD
|
|
||||||
#include <condition_variable>
|
|
||||||
#include <thread>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct QueuedMessage
|
struct QueuedMessage
|
||||||
{
|
{
|
||||||
size_t length;
|
size_t length;
|
||||||
char buffer[16384];
|
char buffer[16384];
|
||||||
|
|
||||||
void Copy(const QueuedMessage& other)
|
|
||||||
{
|
|
||||||
length = other.length;
|
|
||||||
if (length)
|
|
||||||
memcpy(buffer, other.buffer, length);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct User
|
struct User
|
||||||
@ -80,66 +68,13 @@ static User connectedUser;
|
|||||||
static Backoff ReconnectTimeMs(500, 60 * 1000);
|
static Backoff ReconnectTimeMs(500, 60 * 1000);
|
||||||
static auto NextConnect = std::chrono::system_clock::now();
|
static auto NextConnect = std::chrono::system_clock::now();
|
||||||
|
|
||||||
#ifndef DISCORD_DISABLE_IO_THREAD
|
static void update_reconnect_time(void)
|
||||||
static void Discord_UpdateConnection(void);
|
|
||||||
class IoThreadHolder
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
std::atomic_bool keepRunning{true};
|
|
||||||
std::mutex waitForIOMutex;
|
|
||||||
std::condition_variable waitForIOActivity;
|
|
||||||
std::thread ioThread;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void Start()
|
|
||||||
{
|
|
||||||
keepRunning.store(true);
|
|
||||||
ioThread = std::thread([&]() {
|
|
||||||
const std::chrono::duration<int64_t, std::milli> maxWait{500LL};
|
|
||||||
Discord_UpdateConnection();
|
|
||||||
while (keepRunning.load()) {
|
|
||||||
std::unique_lock<std::mutex> lock(waitForIOMutex);
|
|
||||||
waitForIOActivity.wait_for(lock, maxWait);
|
|
||||||
Discord_UpdateConnection();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void Notify() { waitForIOActivity.notify_all(); }
|
|
||||||
|
|
||||||
void Stop()
|
|
||||||
{
|
|
||||||
keepRunning.exchange(false);
|
|
||||||
Notify();
|
|
||||||
if (ioThread.joinable())
|
|
||||||
ioThread.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
~IoThreadHolder() { Stop(); }
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
class IoThreadHolder
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void Start() {}
|
|
||||||
void Stop() {}
|
|
||||||
void Notify() {}
|
|
||||||
};
|
|
||||||
#endif /* DISCORD_DISABLE_IO_THREAD */
|
|
||||||
|
|
||||||
static IoThreadHolder* IoThread{nullptr};
|
|
||||||
|
|
||||||
static void UpdateReconnectTime(void)
|
|
||||||
{
|
{
|
||||||
NextConnect = std::chrono::system_clock::now() +
|
NextConnect = std::chrono::system_clock::now() +
|
||||||
std::chrono::duration<int64_t, std::milli>{ReconnectTimeMs.nextDelay()};
|
std::chrono::duration<int64_t, std::milli>{ReconnectTimeMs.nextDelay()};
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DISCORD_DISABLE_IO_THREAD
|
|
||||||
extern "C" void Discord_UpdateConnection(void)
|
extern "C" void Discord_UpdateConnection(void)
|
||||||
#else
|
|
||||||
static void Discord_UpdateConnection(void)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
if (!Connection)
|
if (!Connection)
|
||||||
return;
|
return;
|
||||||
@ -148,7 +83,7 @@ static void Discord_UpdateConnection(void)
|
|||||||
{
|
{
|
||||||
if (std::chrono::system_clock::now() >= NextConnect)
|
if (std::chrono::system_clock::now() >= NextConnect)
|
||||||
{
|
{
|
||||||
UpdateReconnectTime();
|
update_reconnect_time();
|
||||||
Connection->Open();
|
Connection->Open();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -268,16 +203,19 @@ static void Discord_UpdateConnection(void)
|
|||||||
if (QueuedPresence.length)
|
if (QueuedPresence.length)
|
||||||
{
|
{
|
||||||
QueuedMessage local;
|
QueuedMessage local;
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> guard(PresenceMutex);
|
std::lock_guard<std::mutex> guard(PresenceMutex);
|
||||||
local.Copy(QueuedPresence);
|
local.length = QueuedPresence.length;
|
||||||
|
if (local.length)
|
||||||
|
memcpy(local.buffer, QueuedPresence.buffer, local.length);
|
||||||
QueuedPresence.length = 0;
|
QueuedPresence.length = 0;
|
||||||
}
|
|
||||||
if (!Connection->Write(local.buffer, local.length))
|
if (!Connection->Write(local.buffer, local.length))
|
||||||
{
|
{
|
||||||
/* if we fail to send, requeue */
|
/* if we fail to send, requeue */
|
||||||
std::lock_guard<std::mutex> guard(PresenceMutex);
|
std::lock_guard<std::mutex> guard(PresenceMutex);
|
||||||
QueuedPresence.Copy(local);
|
QueuedPresence.length = local.length;
|
||||||
|
if (QueuedPresence.length)
|
||||||
|
memcpy(QueuedPresence.buffer, local.buffer, QueuedPresence.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,8 +236,6 @@ static bool RegisterForEvent(const char* evtName)
|
|||||||
qmessage->length =
|
qmessage->length =
|
||||||
JsonWriteSubscribeCommand(qmessage->buffer, sizeof(qmessage->buffer), Nonce++, evtName);
|
JsonWriteSubscribeCommand(qmessage->buffer, sizeof(qmessage->buffer), Nonce++, evtName);
|
||||||
SendQueue.CommitAdd();
|
SendQueue.CommitAdd();
|
||||||
if (IoThread)
|
|
||||||
IoThread->Notify();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -313,8 +249,6 @@ static bool DeregisterForEvent(const char* evtName)
|
|||||||
qmessage->length =
|
qmessage->length =
|
||||||
JsonWriteUnsubscribeCommand(qmessage->buffer, sizeof(qmessage->buffer), Nonce++, evtName);
|
JsonWriteUnsubscribeCommand(qmessage->buffer, sizeof(qmessage->buffer), Nonce++, evtName);
|
||||||
SendQueue.CommitAdd();
|
SendQueue.CommitAdd();
|
||||||
if (IoThread)
|
|
||||||
IoThread->Notify();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -326,10 +260,6 @@ extern "C" void Discord_Initialize(
|
|||||||
int autoRegister,
|
int autoRegister,
|
||||||
const char* optionalSteamId)
|
const char* optionalSteamId)
|
||||||
{
|
{
|
||||||
IoThread = new (std::nothrow) IoThreadHolder();
|
|
||||||
if (!IoThread)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (autoRegister)
|
if (autoRegister)
|
||||||
{
|
{
|
||||||
if (optionalSteamId && optionalSteamId[0])
|
if (optionalSteamId && optionalSteamId[0])
|
||||||
@ -357,13 +287,15 @@ extern "C" void Discord_Initialize(
|
|||||||
Connection = RpcConnection::Create(applicationId);
|
Connection = RpcConnection::Create(applicationId);
|
||||||
Connection->onConnect = [](JsonDocument& readyMessage)
|
Connection->onConnect = [](JsonDocument& readyMessage)
|
||||||
{
|
{
|
||||||
Discord_UpdateHandlers(&QueuedHandlers);
|
|
||||||
char *userId = NULL;
|
char *userId = NULL;
|
||||||
char *username = NULL;
|
char *username = NULL;
|
||||||
char *avatar = NULL;
|
char *avatar = NULL;
|
||||||
char *discriminator = NULL;
|
char *discriminator = NULL;
|
||||||
|
bool in_data = false;
|
||||||
|
bool in_user = false;
|
||||||
|
|
||||||
|
Discord_UpdateHandlers(&QueuedHandlers);
|
||||||
|
|
||||||
bool in_data = false, in_user = false;
|
|
||||||
for (JsonReader r(readyMessage); r.NextKey();)
|
for (JsonReader r(readyMessage); r.NextKey();)
|
||||||
{
|
{
|
||||||
if (r.depth == 1)
|
if (r.depth == 1)
|
||||||
@ -372,15 +304,17 @@ extern "C" void Discord_Initialize(
|
|||||||
in_user = false;
|
in_user = false;
|
||||||
}
|
}
|
||||||
else if (r.depth == 2 && in_data)
|
else if (r.depth == 2 && in_data)
|
||||||
{
|
|
||||||
in_user = !strcmp(r.key, "user");
|
in_user = !strcmp(r.key, "user");
|
||||||
}
|
|
||||||
else if (r.depth == 3 && in_user)
|
else if (r.depth == 3 && in_user)
|
||||||
{
|
{
|
||||||
if (!strcmp(r.key, "id" )) r.NextStrDup(&userId);
|
if (!strcmp(r.key, "id" ))
|
||||||
else if (!strcmp(r.key, "username" )) r.NextStrDup(&username);
|
r.NextStrDup(&userId);
|
||||||
else if (!strcmp(r.key, "avatar" )) r.NextStrDup(&avatar);
|
else if (!strcmp(r.key, "username" ))
|
||||||
else if (!strcmp(r.key, "discriminator")) r.NextStrDup(&discriminator);
|
r.NextStrDup(&username);
|
||||||
|
else if (!strcmp(r.key, "avatar" ))
|
||||||
|
r.NextStrDup(&avatar);
|
||||||
|
else if (!strcmp(r.key, "discriminator"))
|
||||||
|
r.NextStrDup(&discriminator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,10 +332,14 @@ extern "C" void Discord_Initialize(
|
|||||||
WasJustConnected.exchange(true);
|
WasJustConnected.exchange(true);
|
||||||
ReconnectTimeMs.reset();
|
ReconnectTimeMs.reset();
|
||||||
|
|
||||||
if (userId ) free(userId );
|
if (userId)
|
||||||
if (username ) free(username );
|
free(userId);
|
||||||
if (avatar ) free(avatar );
|
if (username)
|
||||||
if (discriminator) free(discriminator);
|
free(username);
|
||||||
|
if (avatar)
|
||||||
|
free(avatar);
|
||||||
|
if (discriminator)
|
||||||
|
free(discriminator);
|
||||||
};
|
};
|
||||||
Connection->onDisconnect = [](int err, const char* message)
|
Connection->onDisconnect = [](int err, const char* message)
|
||||||
{
|
{
|
||||||
@ -412,10 +350,8 @@ extern "C" void Discord_Initialize(
|
|||||||
Handlers = {};
|
Handlers = {};
|
||||||
}
|
}
|
||||||
WasJustDisconnected.exchange(true);
|
WasJustDisconnected.exchange(true);
|
||||||
UpdateReconnectTime();
|
update_reconnect_time();
|
||||||
};
|
};
|
||||||
|
|
||||||
IoThread->Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void Discord_Shutdown(void)
|
extern "C" void Discord_Shutdown(void)
|
||||||
@ -425,25 +361,16 @@ extern "C" void Discord_Shutdown(void)
|
|||||||
Connection->onConnect = nullptr;
|
Connection->onConnect = nullptr;
|
||||||
Connection->onDisconnect = nullptr;
|
Connection->onDisconnect = nullptr;
|
||||||
Handlers = {};
|
Handlers = {};
|
||||||
if (IoThread)
|
|
||||||
{
|
|
||||||
IoThread->Stop();
|
|
||||||
delete IoThread;
|
|
||||||
IoThread = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
RpcConnection::Destroy(Connection);
|
RpcConnection::Destroy(Connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void Discord_UpdatePresence(const DiscordRichPresence* presence)
|
extern "C" void Discord_UpdatePresence(const DiscordRichPresence* presence)
|
||||||
{
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> guard(PresenceMutex);
|
std::lock_guard<std::mutex> guard(PresenceMutex);
|
||||||
QueuedPresence.length = JsonWriteRichPresenceObj(
|
QueuedPresence.length = JsonWriteRichPresenceObj(
|
||||||
QueuedPresence.buffer, sizeof(QueuedPresence.buffer), Nonce++, Pid, presence);
|
QueuedPresence.buffer, sizeof(QueuedPresence.buffer),
|
||||||
}
|
Nonce++, Pid, presence);
|
||||||
if (IoThread)
|
|
||||||
IoThread->Notify();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void Discord_ClearPresence(void)
|
extern "C" void Discord_ClearPresence(void)
|
||||||
@ -451,7 +378,8 @@ extern "C" void Discord_ClearPresence(void)
|
|||||||
Discord_UpdatePresence(nullptr);
|
Discord_UpdatePresence(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void Discord_Respond(const char* userId, /* DISCORD_REPLY_ */ int reply)
|
extern "C" void Discord_Respond(const char* userId,
|
||||||
|
/* DISCORD_REPLY_ */ int reply)
|
||||||
{
|
{
|
||||||
/* if we are not connected, let's not batch up stale messages for later */
|
/* if we are not connected, let's not batch up stale messages for later */
|
||||||
if (!Connection || !Connection->IsOpen())
|
if (!Connection || !Connection->IsOpen())
|
||||||
@ -462,8 +390,6 @@ extern "C" void Discord_Respond(const char* userId, /* DISCORD_REPLY_ */ int rep
|
|||||||
qmessage->length =
|
qmessage->length =
|
||||||
JsonWriteJoinReply(qmessage->buffer, sizeof(qmessage->buffer), userId, reply, Nonce++);
|
JsonWriteJoinReply(qmessage->buffer, sizeof(qmessage->buffer), userId, reply, Nonce++);
|
||||||
SendQueue.CommitAdd();
|
SendQueue.CommitAdd();
|
||||||
if (IoThread)
|
|
||||||
IoThread->Notify();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -531,14 +457,12 @@ extern "C" void Discord_RunCallbacks(void)
|
|||||||
while (JoinAskQueue.HavePendingSends())
|
while (JoinAskQueue.HavePendingSends())
|
||||||
{
|
{
|
||||||
auto req = JoinAskQueue.GetNextSendMessage();
|
auto req = JoinAskQueue.GetNextSendMessage();
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> guard(HandlerMutex);
|
std::lock_guard<std::mutex> guard(HandlerMutex);
|
||||||
if (Handlers.joinRequest)
|
if (Handlers.joinRequest)
|
||||||
{
|
{
|
||||||
DiscordUser du{req->userId, req->username, req->discriminator, req->avatar};
|
DiscordUser du{req->userId, req->username, req->discriminator, req->avatar};
|
||||||
Handlers.joinRequest(&du);
|
Handlers.joinRequest(&du);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
JoinAskQueue.CommitSend();
|
JoinAskQueue.CommitSend();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,6 +324,7 @@ static void frontend_psp_exec(const char *path, bool should_load_game)
|
|||||||
#endif
|
#endif
|
||||||
char argp[512] = {0};
|
char argp[512] = {0};
|
||||||
SceSize args = 0;
|
SceSize args = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
#if !defined(VITA)
|
#if !defined(VITA)
|
||||||
strlcpy(argp, eboot_path, sizeof(argp));
|
strlcpy(argp, eboot_path, sizeof(argp));
|
||||||
@ -346,21 +347,25 @@ static void frontend_psp_exec(const char *path, bool should_load_game)
|
|||||||
sceAppMgrGetAppParam(boot_params);
|
sceAppMgrGetAppParam(boot_params);
|
||||||
if (strstr(boot_params,"psgm:play"))
|
if (strstr(boot_params,"psgm:play"))
|
||||||
{
|
{
|
||||||
int ret;
|
char *param1 = strstr(boot_params, "¶m=");
|
||||||
char *param1 = strstr(boot_params, "¶m=")+7;
|
|
||||||
char *param2 = strstr(boot_params, "¶m2=");
|
char *param2 = strstr(boot_params, "¶m2=");
|
||||||
|
if (param1 != NULL && param2 != NULL)
|
||||||
|
{
|
||||||
|
param1 += 7;
|
||||||
memcpy(core_name, param1, param2 - param1);
|
memcpy(core_name, param1, param2 - param1);
|
||||||
core_name[param2-param1] = 0;
|
core_name[param2-param1] = 0;
|
||||||
sprintf(argp, param2 + 8);
|
sprintf(argp, param2 + 8);
|
||||||
ret = sceAppMgrLoadExec(core_name, (char * const*)((const char*[]){argp, 0}), NULL);
|
ret = sceAppMgrLoadExec(core_name, (char * const*)((const char*[]){argp, 0}), NULL);
|
||||||
RARCH_LOG("Attempt to load executable: [%d].\n", ret);
|
RARCH_LOG("Attempt to load executable: [%d].\n", ret);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
RARCH_LOG("Required boot params missing. Continue nornal boot.");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
{
|
ret = sceAppMgrLoadExec(path, args == 0 ? NULL : (char * const*)((const char*[]){argp, 0}), NULL);
|
||||||
int ret = sceAppMgrLoadExec(path, args == 0 ? NULL : (char * const*)((const char*[]){argp, 0}), NULL);
|
|
||||||
RARCH_LOG("Attempt to load executable: [%d].\n", ret);
|
RARCH_LOG("Attempt to load executable: [%d].\n", ret);
|
||||||
}
|
exit:
|
||||||
|
return;
|
||||||
#else
|
#else
|
||||||
exitspawn_kernel(path, args, argp);
|
exitspawn_kernel(path, args, argp);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1054,6 +1054,13 @@ static LRESULT CALLBACK wnd_proc_common_dinput_internal(HWND hwnd,
|
|||||||
keysym |= 0x80;
|
keysym |= 0x80;
|
||||||
|
|
||||||
keycode = input_keymaps_translate_keysym_to_rk(keysym);
|
keycode = input_keymaps_translate_keysym_to_rk(keysym);
|
||||||
|
switch (keycode)
|
||||||
|
{
|
||||||
|
/* L+R Shift handling done in dinput_poll */
|
||||||
|
case RETROK_LSHIFT:
|
||||||
|
case RETROK_RSHIFT:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
input_keyboard_event(keydown, keycode,
|
input_keyboard_event(keydown, keycode,
|
||||||
0, mod, RETRO_DEVICE_KEYBOARD);
|
0, mod, RETRO_DEVICE_KEYBOARD);
|
||||||
|
@ -600,8 +600,10 @@ bool slang_reflect(
|
|||||||
}
|
}
|
||||||
else if (index == SLANG_INVALID_TEXTURE_SEMANTIC)
|
else if (index == SLANG_INVALID_TEXTURE_SEMANTIC)
|
||||||
{
|
{
|
||||||
RARCH_ERR("[slang]: Non-semantic textures not supported yet, "
|
RARCH_ERR("[slang]: Texture name '%s' not found in semantic map, "
|
||||||
"Probably a texture name or pass alias is not found. \n");
|
"Probably the texture name or pass alias is not defined "
|
||||||
|
"in the preset (Non-semantic textures not supported yet)\n",
|
||||||
|
fragment.sampled_images[i].name.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -802,21 +802,29 @@ static bool font_init_first(
|
|||||||
* Neutral :
|
* Neutral :
|
||||||
* 0020 - 002F : 001xxxxx (c & 0xE0) == 0x20
|
* 0020 - 002F : 001xxxxx (c & 0xE0) == 0x20
|
||||||
* Arabic:
|
* Arabic:
|
||||||
* 0600 - 07FF : 11011xxx (c & 0xF8) == 0xD8 (2 bytes)
|
* 0600 - 06FF : 110110xx (c & 0xFC) == 0xD8 (2 bytes) */
|
||||||
* 0800 - 08FF : 11100000 101000xx c == 0xE0 && (c1 & 0xAC) == 0xA0 (3 bytes) */
|
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
#define IS_ASCII(p) ((*(p)&0x80) == 0x00)
|
#define IS_ASCII(p) ((*(p)&0x80) == 0x00)
|
||||||
#define IS_MBSTART(p) ((*(p)&0xC0) == 0xC0)
|
#define IS_MBSTART(p) ((*(p)&0xC0) == 0xC0)
|
||||||
#define IS_MBCONT(p) ((*(p)&0xC0) == 0x80)
|
#define IS_MBCONT(p) ((*(p)&0xC0) == 0x80)
|
||||||
#define IS_DIR_NEUTRAL(p) ((*(p)&0xE0) == 0x20)
|
#define IS_DIR_NEUTRAL(p) ((*(p)&0xE0) == 0x20)
|
||||||
#define IS_ARABIC0(p) ((*(p)&0xF8) == 0xD8)
|
#define IS_ARABIC(p) ((*(p)&0xFC) == 0xD8)
|
||||||
#define IS_ARABIC1(p) ((*(p) == 0xE0) && ((*((p) + 1) & 0xAC) == 0xA0))
|
|
||||||
#define IS_ARABIC(p) (IS_ARABIC0(p) || IS_ARABIC1(p))
|
|
||||||
#define IS_RTL(p) IS_ARABIC(p)
|
#define IS_RTL(p) IS_ARABIC(p)
|
||||||
|
#define GET_ID_ARABIC(p) (((unsigned char)(p)[0] << 6) | ((unsigned char)(p)[1] & 0x3F))
|
||||||
|
|
||||||
/* 0x0620 to 0x064F */
|
/* 0x0620 to 0x064F */
|
||||||
static const unsigned arabic_shape_map[0x50 - 0x20][0x4] = {
|
static const unsigned arabic_shape_map[0x100][0x4] = {
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 }, /* 0x0600 */
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 }, /* 0x0610 */
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
|
||||||
{ 0 }, /* 0x0620 */
|
{ 0 }, /* 0x0620 */
|
||||||
{ 0xFE80 },
|
{ 0xFE80 },
|
||||||
{ 0xFE81, 0xFE82 },
|
{ 0xFE81, 0xFE82 },
|
||||||
@ -843,99 +851,189 @@ static const unsigned arabic_shape_map[0x50 - 0x20][0x4] = {
|
|||||||
{ 0xFEB9, 0xFEBA, 0xFEBB, 0xFEBC },
|
{ 0xFEB9, 0xFEBA, 0xFEBB, 0xFEBC },
|
||||||
{ 0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0 },
|
{ 0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0 },
|
||||||
{ 0xFEC1, 0xFEC2, 0xFEC3, 0xFEC4 },
|
{ 0xFEC1, 0xFEC2, 0xFEC3, 0xFEC4 },
|
||||||
{ 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8 },
|
|
||||||
|
|
||||||
|
{ 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8 },
|
||||||
{ 0xFEC9, 0xFECA, 0xFECB, 0xFECC },
|
{ 0xFEC9, 0xFECA, 0xFECB, 0xFECC },
|
||||||
{ 0xFECD, 0xFECE, 0xFECF, 0xFED0 },
|
{ 0xFECD, 0xFECE, 0xFECF, 0xFED0 },
|
||||||
{ 0 },
|
{ 0 },
|
||||||
{ 0 },
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
{ 0 },
|
|
||||||
{ 0 },
|
|
||||||
{ 0 },
|
|
||||||
{ 0 },
|
|
||||||
|
|
||||||
{ 0xFED1, 0xFED2, 0xFED3, 0xFED4 }, /* 0x0640 */
|
{ 0 }, /* 0x0640 */
|
||||||
|
{ 0xFED1, 0xFED2, 0xFED3, 0xFED4 },
|
||||||
{ 0xFED5, 0xFED6, 0xFED7, 0xFED8 },
|
{ 0xFED5, 0xFED6, 0xFED7, 0xFED8 },
|
||||||
{ 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC },
|
{ 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC },
|
||||||
{ 0xFEDD, 0xFEDE, 0xFEDF, 0xFEE0 },
|
{ 0xFEDD, 0xFEDE, 0xFEDF, 0xFEE0 },
|
||||||
{ 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4 },
|
{ 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4 },
|
||||||
{ 0xFEE5, 0xFEE6, 0xFEE7, 0xFEE8 },
|
{ 0xFEE5, 0xFEE6, 0xFEE7, 0xFEE8 },
|
||||||
{ 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC },
|
{ 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC },
|
||||||
{ 0xFEED, 0xFEEE },
|
|
||||||
|
|
||||||
|
{ 0xFEED, 0xFEEE },
|
||||||
{ 0xFEEF, 0xFEF0, 0xFBE8, 0xFBE9 },
|
{ 0xFEEF, 0xFEF0, 0xFBE8, 0xFBE9 },
|
||||||
{ 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4 },
|
{ 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4 },
|
||||||
|
{ 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 }, /* 0x0650 */
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
|
||||||
|
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 }, /* 0x0660 */
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
|
||||||
|
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 }, /* 0x0670 */
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
|
||||||
|
{ 0 }, { 0 },
|
||||||
|
{ 0xFB56, 0xFB57, 0xFB58, 0xFB59 },
|
||||||
|
{ 0 },
|
||||||
|
|
||||||
|
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 }, /* 0x0680 */
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
|
||||||
|
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 }, /* 0x0690 */
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
|
||||||
|
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 }, /* 0x06A0 */
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
|
||||||
|
{ 0 },
|
||||||
|
{ 0xFB8E, 0xFB8F, 0xFB90, 0xFB91 },
|
||||||
|
{ 0 }, { 0 },
|
||||||
|
|
||||||
|
{ 0 }, { 0 }, { 0 },
|
||||||
|
{ 0xFB92, 0xFB93, 0xFB94, 0xFB95 },
|
||||||
|
|
||||||
|
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 }, /* 0x06B0 */
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
|
||||||
|
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 }, /* 0x06C0 */
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
|
||||||
|
{ 0xFBFC, 0xFBFD, 0xFBFE, 0xFBFF },
|
||||||
|
{ 0 }, { 0 }, { 0 },
|
||||||
|
|
||||||
|
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 }, /* 0x06D0 */
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
|
||||||
|
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 }, /* 0x06E0 */
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
|
||||||
|
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 }, /* 0x06F0 */
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
};
|
};
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
static INLINE unsigned font_get_replacement(const char* src, const char* start)
|
static INLINE unsigned font_get_replacement(const char* src, const char* start)
|
||||||
{
|
{
|
||||||
if ((*src & 0xFC) == 0xD8) /* 0x0600 to 0x06FF */
|
if (IS_ARABIC(src)) /* 0x0600 to 0x06FF */
|
||||||
{
|
{
|
||||||
unsigned result = 0;
|
unsigned result = 0;
|
||||||
bool prev_connected = false;
|
bool prev_connected = false;
|
||||||
bool next_connected = false;
|
bool next_connected = false;
|
||||||
unsigned char id = ((unsigned char)src[0] << 6) | ((unsigned char)src[1] & 0x3F);
|
unsigned char id = GET_ID_ARABIC(src);
|
||||||
const char* prev1 = src - 2;
|
const char* prev = src - 2;
|
||||||
const char* prev2 = src - 4;
|
const char* next = src + 2;
|
||||||
|
|
||||||
if (id < 0x21 || id > 0x4A)
|
if ((prev >= start) && IS_ARABIC(prev))
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (prev2 < start)
|
|
||||||
{
|
{
|
||||||
prev2 = NULL;
|
unsigned char prev_id = GET_ID_ARABIC(prev);
|
||||||
if (prev1 < start)
|
|
||||||
prev1 = NULL;
|
/* nonspacing diacritics 0x4b -- 0x5f */
|
||||||
|
while (prev_id > 0x4A && prev_id < 0x60)
|
||||||
|
{
|
||||||
|
prev -= 2;
|
||||||
|
if ((prev >= start) && IS_ARABIC(prev))
|
||||||
|
prev_id = GET_ID_ARABIC(prev);
|
||||||
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prev1 && (*prev1 & 0xFC) == 0xD8)
|
|
||||||
{
|
|
||||||
unsigned char prev1_id = 0;
|
|
||||||
|
|
||||||
if (prev1)
|
if (prev_id == 0x44) /* Arabic Letter Lam */
|
||||||
prev1_id = ((unsigned char)prev1[0] << 6) | ((unsigned char)prev1[1] & 0x3F);
|
|
||||||
|
|
||||||
if (prev1_id == 0x44)
|
|
||||||
{
|
{
|
||||||
unsigned char prev2_id = 0;
|
unsigned char prev2_id = 0;
|
||||||
|
const char* prev2 = prev - 2;
|
||||||
|
|
||||||
if (prev2)
|
if (prev2 >= start)
|
||||||
prev2_id = (prev2[0] << 6) | (prev2[1] & 0x3F);
|
prev2_id = (prev2[0] << 6) | (prev2[1] & 0x3F);
|
||||||
|
|
||||||
if (prev2_id > 0x20 || prev2_id < 0x50)
|
/* nonspacing diacritics 0x4b -- 0x5f */
|
||||||
prev_connected = !!arabic_shape_map[prev2_id - 0x20][2];
|
while (prev2_id > 0x4A && prev2_id < 0x60)
|
||||||
|
{
|
||||||
|
prev2 -= 2;
|
||||||
|
if ((prev2 >= start) && IS_ARABIC(prev2))
|
||||||
|
prev2_id = GET_ID_ARABIC(prev2);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_connected = !!arabic_shape_map[prev2_id][2];
|
||||||
|
|
||||||
switch (id)
|
switch (id)
|
||||||
{
|
{
|
||||||
case 0x22:
|
case 0x22: /* Arabic Letter Alef with Madda Above */
|
||||||
return 0xFEF5 + prev_connected;
|
return 0xFEF5 + prev_connected;
|
||||||
case 0x23:
|
case 0x23: /* Arabic Letter Alef with Hamza Above */
|
||||||
return 0xFEF7 + prev_connected;
|
return 0xFEF7 + prev_connected;
|
||||||
case 0x25:
|
case 0x25: /* Arabic Letter Alef with Hamza Below */
|
||||||
return 0xFEF9 + prev_connected;
|
return 0xFEF9 + prev_connected;
|
||||||
case 0x27:
|
case 0x27: /* Arabic Letter Alef */
|
||||||
return 0xFEFB + prev_connected;
|
return 0xFEFB + prev_connected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (prev1_id > 0x20 || prev1_id < 0x50)
|
prev_connected = !!arabic_shape_map[prev_id][2];
|
||||||
prev_connected = !!arabic_shape_map[prev1_id - 0x20][2];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((src[2] & 0xFC) == 0xD8)
|
if (IS_ARABIC(next))
|
||||||
{
|
{
|
||||||
unsigned char next_id = ((unsigned char)src[2] << 6) | ((unsigned char)src[3] & 0x3F);
|
unsigned char next_id = GET_ID_ARABIC(next);
|
||||||
|
|
||||||
if (next_id > 0x20 || next_id < 0x50)
|
/* nonspacing diacritics 0x4b -- 0x5f */
|
||||||
next_connected = true;
|
while (next_id > 0x4A && next_id < 0x60)
|
||||||
|
{
|
||||||
|
next += 2;
|
||||||
|
if (IS_ARABIC(next))
|
||||||
|
next_id = GET_ID_ARABIC(next);
|
||||||
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = arabic_shape_map[id - 0x20][prev_connected | (next_connected << 1)];
|
next_connected = !!arabic_shape_map[next_id][1];
|
||||||
|
}
|
||||||
|
|
||||||
|
result = arabic_shape_map[id][prev_connected | (next_connected << 1)];
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
return arabic_shape_map[id - 0x20][prev_connected];
|
return arabic_shape_map[id][prev_connected];
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -961,22 +1059,17 @@ static char* font_driver_reshape_msg(const char* msg, unsigned char *buffer, siz
|
|||||||
if (reverse)
|
if (reverse)
|
||||||
{
|
{
|
||||||
src--;
|
src--;
|
||||||
while (IS_MBCONT(src))
|
while (src > (const unsigned char*)msg && IS_MBCONT(src))
|
||||||
{
|
|
||||||
src--;
|
src--;
|
||||||
|
|
||||||
if (src == (const unsigned char*)msg)
|
if (src >= (const unsigned char*)msg && (IS_RTL(src) || IS_DIR_NEUTRAL(src)))
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_RTL(src) || IS_DIR_NEUTRAL(src))
|
|
||||||
{
|
{
|
||||||
unsigned replacement = font_get_replacement((const char*)src, msg);
|
unsigned replacement = font_get_replacement((const char*)src, msg);
|
||||||
if (replacement)
|
if (replacement)
|
||||||
{
|
{
|
||||||
if (replacement < 0x80)
|
if (replacement < 0x80)
|
||||||
*dst++ = replacement;
|
*dst++ = replacement;
|
||||||
else if (replacement < 0x8000)
|
else if (replacement < 0x800)
|
||||||
{
|
{
|
||||||
*dst++ = 0xC0 | (replacement >> 6);
|
*dst++ = 0xC0 | (replacement >> 6);
|
||||||
*dst++ = 0x80 | (replacement & 0x3F);
|
*dst++ = 0x80 | (replacement & 0x3F);
|
||||||
@ -1030,7 +1123,7 @@ static char* font_driver_reshape_msg(const char* msg, unsigned char *buffer, siz
|
|||||||
*dst++ = *src++;
|
*dst++ = *src++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end:
|
|
||||||
*dst = '\0';
|
*dst = '\0';
|
||||||
|
|
||||||
return (char*)dst_buffer;
|
return (char*)dst_buffer;
|
||||||
|
@ -282,6 +282,7 @@ extern const struct softfilter_implementation *scale2x_get_implementation(softfi
|
|||||||
extern const struct softfilter_implementation *normal2x_get_implementation(softfilter_simd_mask_t simd);
|
extern const struct softfilter_implementation *normal2x_get_implementation(softfilter_simd_mask_t simd);
|
||||||
extern const struct softfilter_implementation *normal2x_width_get_implementation(softfilter_simd_mask_t simd);
|
extern const struct softfilter_implementation *normal2x_width_get_implementation(softfilter_simd_mask_t simd);
|
||||||
extern const struct softfilter_implementation *normal2x_height_get_implementation(softfilter_simd_mask_t simd);
|
extern const struct softfilter_implementation *normal2x_height_get_implementation(softfilter_simd_mask_t simd);
|
||||||
|
extern const struct softfilter_implementation *normal4x_get_implementation(softfilter_simd_mask_t simd);
|
||||||
extern const struct softfilter_implementation *scanline2x_get_implementation(softfilter_simd_mask_t simd);
|
extern const struct softfilter_implementation *scanline2x_get_implementation(softfilter_simd_mask_t simd);
|
||||||
extern const struct softfilter_implementation *grid2x_get_implementation(softfilter_simd_mask_t simd);
|
extern const struct softfilter_implementation *grid2x_get_implementation(softfilter_simd_mask_t simd);
|
||||||
extern const struct softfilter_implementation *grid3x_get_implementation(softfilter_simd_mask_t simd);
|
extern const struct softfilter_implementation *grid3x_get_implementation(softfilter_simd_mask_t simd);
|
||||||
@ -304,6 +305,7 @@ static const softfilter_get_implementation_t soft_plugs_builtin[] = {
|
|||||||
normal2x_get_implementation,
|
normal2x_get_implementation,
|
||||||
normal2x_width_get_implementation,
|
normal2x_width_get_implementation,
|
||||||
normal2x_height_get_implementation,
|
normal2x_height_get_implementation,
|
||||||
|
normal4x_get_implementation,
|
||||||
scanline2x_get_implementation,
|
scanline2x_get_implementation,
|
||||||
grid2x_get_implementation,
|
grid2x_get_implementation,
|
||||||
grid3x_get_implementation,
|
grid3x_get_implementation,
|
||||||
|
@ -70,7 +70,7 @@ endif
|
|||||||
objects += blargg_ntsc_snes.$(DYLIB) phosphor2x.$(DYLIB) epx.$(DYLIB) lq2x.$(DYLIB) \
|
objects += blargg_ntsc_snes.$(DYLIB) phosphor2x.$(DYLIB) epx.$(DYLIB) lq2x.$(DYLIB) \
|
||||||
2xsai.$(DYLIB) super2xsai.$(DYLIB) supereagle.$(DYLIB) 2xbr.$(DYLIB) \
|
2xsai.$(DYLIB) super2xsai.$(DYLIB) supereagle.$(DYLIB) 2xbr.$(DYLIB) \
|
||||||
darken.$(DYLIB) scale2x.$(DYLIB) normal2x.$(DYLIB) \
|
darken.$(DYLIB) scale2x.$(DYLIB) normal2x.$(DYLIB) \
|
||||||
normal2x_width.$(DYLIB) normal2x_height.$(DYLIB) \
|
normal2x_width.$(DYLIB) normal2x_height.$(DYLIB) normal4x.$(DYLIB) \
|
||||||
scanline2x.$(DYLIB) grid2x.$(DYLIB) grid3x.$(DYLIB) \
|
scanline2x.$(DYLIB) grid2x.$(DYLIB) grid3x.$(DYLIB) \
|
||||||
gameboy3x.$(DYLIB) gameboy4x.$(DYLIB) \
|
gameboy3x.$(DYLIB) gameboy4x.$(DYLIB) \
|
||||||
dot_matrix_3x.$(DYLIB) dot_matrix_4x.$(DYLIB)
|
dot_matrix_3x.$(DYLIB) dot_matrix_4x.$(DYLIB)
|
||||||
|
1
gfx/video_filters/Normal4x.filt
Normal file
1
gfx/video_filters/Normal4x.filt
Normal file
@ -0,0 +1 @@
|
|||||||
|
filter = normal4x
|
255
gfx/video_filters/normal4x.c
Normal file
255
gfx/video_filters/normal4x.c
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
/* RetroArch - A frontend for libretro.
|
||||||
|
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||||
|
* Copyright (C) 2011-2018 - Daniel De Matteis
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Compile: gcc -o normal4x.so -shared normal4x.c -std=c99 -O3 -Wall -pedantic -fPIC */
|
||||||
|
|
||||||
|
#include "softfilter.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef RARCH_INTERNAL
|
||||||
|
#define softfilter_get_implementation normal4x_get_implementation
|
||||||
|
#define softfilter_thread_data normal4x_softfilter_thread_data
|
||||||
|
#define filter_data normal4x_filter_data
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct softfilter_thread_data
|
||||||
|
{
|
||||||
|
void *out_data;
|
||||||
|
const void *in_data;
|
||||||
|
size_t out_pitch;
|
||||||
|
size_t in_pitch;
|
||||||
|
unsigned colfmt;
|
||||||
|
unsigned width;
|
||||||
|
unsigned height;
|
||||||
|
int first;
|
||||||
|
int last;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct filter_data
|
||||||
|
{
|
||||||
|
unsigned threads;
|
||||||
|
struct softfilter_thread_data *workers;
|
||||||
|
unsigned in_fmt;
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned normal4x_generic_input_fmts(void)
|
||||||
|
{
|
||||||
|
return SOFTFILTER_FMT_XRGB8888 | SOFTFILTER_FMT_RGB565;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned normal4x_generic_output_fmts(unsigned input_fmts)
|
||||||
|
{
|
||||||
|
return input_fmts;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned normal4x_generic_threads(void *data)
|
||||||
|
{
|
||||||
|
struct filter_data *filt = (struct filter_data*)data;
|
||||||
|
return filt->threads;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *normal4x_generic_create(const struct softfilter_config *config,
|
||||||
|
unsigned in_fmt, unsigned out_fmt,
|
||||||
|
unsigned max_width, unsigned max_height,
|
||||||
|
unsigned threads, softfilter_simd_mask_t simd, void *userdata)
|
||||||
|
{
|
||||||
|
struct filter_data *filt = (struct filter_data*)calloc(1, sizeof(*filt));
|
||||||
|
(void)simd;
|
||||||
|
(void)config;
|
||||||
|
(void)userdata;
|
||||||
|
|
||||||
|
if (!filt) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* Apparently the code is not thread-safe,
|
||||||
|
* so force single threaded operation... */
|
||||||
|
filt->workers = (struct softfilter_thread_data*)calloc(1, sizeof(struct softfilter_thread_data));
|
||||||
|
filt->threads = 1;
|
||||||
|
filt->in_fmt = in_fmt;
|
||||||
|
if (!filt->workers) {
|
||||||
|
free(filt);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return filt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void normal4x_generic_output(void *data,
|
||||||
|
unsigned *out_width, unsigned *out_height,
|
||||||
|
unsigned width, unsigned height)
|
||||||
|
{
|
||||||
|
*out_width = width << 2;
|
||||||
|
*out_height = height << 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void normal4x_generic_destroy(void *data)
|
||||||
|
{
|
||||||
|
struct filter_data *filt = (struct filter_data*)data;
|
||||||
|
if (!filt) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
free(filt->workers);
|
||||||
|
free(filt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void normal4x_work_cb_xrgb8888(void *data, void *thread_data)
|
||||||
|
{
|
||||||
|
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
|
||||||
|
const uint32_t *input = (const uint32_t*)thr->in_data;
|
||||||
|
uint32_t *output = (uint32_t*)thr->out_data;
|
||||||
|
uint32_t in_stride = (uint32_t)(thr->in_pitch >> 2);
|
||||||
|
uint32_t out_stride = (uint32_t)(thr->out_pitch >> 2);
|
||||||
|
uint32_t x, y;
|
||||||
|
|
||||||
|
for (y = 0; y < thr->height; ++y)
|
||||||
|
{
|
||||||
|
uint32_t *out_ptr = output;
|
||||||
|
for (x = 0; x < thr->width; ++x)
|
||||||
|
{
|
||||||
|
uint32_t *out_line_ptr = out_ptr;
|
||||||
|
uint32_t color = *(input + x);
|
||||||
|
uint32_t row_color[4];
|
||||||
|
|
||||||
|
row_color[0] = color;
|
||||||
|
row_color[1] = color;
|
||||||
|
row_color[2] = color;
|
||||||
|
row_color[3] = color;
|
||||||
|
|
||||||
|
/* Row 1 */
|
||||||
|
memcpy(out_line_ptr, row_color, sizeof(row_color));
|
||||||
|
out_line_ptr += out_stride;
|
||||||
|
|
||||||
|
/* Row 2 */
|
||||||
|
memcpy(out_line_ptr, row_color, sizeof(row_color));
|
||||||
|
out_line_ptr += out_stride;
|
||||||
|
|
||||||
|
/* Row 3 */
|
||||||
|
memcpy(out_line_ptr, row_color, sizeof(row_color));
|
||||||
|
out_line_ptr += out_stride;
|
||||||
|
|
||||||
|
/* Row 4 */
|
||||||
|
memcpy(out_line_ptr, row_color, sizeof(row_color));
|
||||||
|
|
||||||
|
out_ptr += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
input += in_stride;
|
||||||
|
output += out_stride << 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void normal4x_work_cb_rgb565(void *data, void *thread_data)
|
||||||
|
{
|
||||||
|
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data;
|
||||||
|
const uint16_t *input = (const uint16_t*)thr->in_data;
|
||||||
|
uint16_t *output = (uint16_t*)thr->out_data;
|
||||||
|
uint16_t in_stride = (uint16_t)(thr->in_pitch >> 1);
|
||||||
|
uint16_t out_stride = (uint16_t)(thr->out_pitch >> 1);
|
||||||
|
uint16_t x, y;
|
||||||
|
|
||||||
|
for (y = 0; y < thr->height; ++y)
|
||||||
|
{
|
||||||
|
uint16_t *out_ptr = output;
|
||||||
|
for (x = 0; x < thr->width; ++x)
|
||||||
|
{
|
||||||
|
uint16_t *out_line_ptr = out_ptr;
|
||||||
|
uint16_t color = *(input + x);
|
||||||
|
uint16_t row_color[4];
|
||||||
|
|
||||||
|
row_color[0] = color;
|
||||||
|
row_color[1] = color;
|
||||||
|
row_color[2] = color;
|
||||||
|
row_color[3] = color;
|
||||||
|
|
||||||
|
/* Row 1 */
|
||||||
|
memcpy(out_line_ptr, row_color, sizeof(row_color));
|
||||||
|
out_line_ptr += out_stride;
|
||||||
|
|
||||||
|
/* Row 2 */
|
||||||
|
memcpy(out_line_ptr, row_color, sizeof(row_color));
|
||||||
|
out_line_ptr += out_stride;
|
||||||
|
|
||||||
|
/* Row 3 */
|
||||||
|
memcpy(out_line_ptr, row_color, sizeof(row_color));
|
||||||
|
out_line_ptr += out_stride;
|
||||||
|
|
||||||
|
/* Row 4 */
|
||||||
|
memcpy(out_line_ptr, row_color, sizeof(row_color));
|
||||||
|
|
||||||
|
out_ptr += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
input += in_stride;
|
||||||
|
output += out_stride << 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void normal4x_generic_packets(void *data,
|
||||||
|
struct softfilter_work_packet *packets,
|
||||||
|
void *output, size_t output_stride,
|
||||||
|
const void *input, unsigned width, unsigned height, size_t input_stride)
|
||||||
|
{
|
||||||
|
/* We are guaranteed single threaded operation
|
||||||
|
* (filt->threads = 1) so we don't need to loop
|
||||||
|
* over threads and can cull some code. This only
|
||||||
|
* makes the tiniest performance difference, but
|
||||||
|
* every little helps when running on an o3DS... */
|
||||||
|
struct filter_data *filt = (struct filter_data*)data;
|
||||||
|
struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[0];
|
||||||
|
|
||||||
|
thr->out_data = (uint8_t*)output;
|
||||||
|
thr->in_data = (const uint8_t*)input;
|
||||||
|
thr->out_pitch = output_stride;
|
||||||
|
thr->in_pitch = input_stride;
|
||||||
|
thr->width = width;
|
||||||
|
thr->height = height;
|
||||||
|
|
||||||
|
if (filt->in_fmt == SOFTFILTER_FMT_XRGB8888) {
|
||||||
|
packets[0].work = normal4x_work_cb_xrgb8888;
|
||||||
|
} else if (filt->in_fmt == SOFTFILTER_FMT_RGB565) {
|
||||||
|
packets[0].work = normal4x_work_cb_rgb565;
|
||||||
|
}
|
||||||
|
packets[0].thread_data = thr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct softfilter_implementation normal4x_generic = {
|
||||||
|
normal4x_generic_input_fmts,
|
||||||
|
normal4x_generic_output_fmts,
|
||||||
|
|
||||||
|
normal4x_generic_create,
|
||||||
|
normal4x_generic_destroy,
|
||||||
|
|
||||||
|
normal4x_generic_threads,
|
||||||
|
normal4x_generic_output,
|
||||||
|
normal4x_generic_packets,
|
||||||
|
|
||||||
|
SOFTFILTER_API_VERSION,
|
||||||
|
"Normal4x",
|
||||||
|
"normal4x",
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct softfilter_implementation *softfilter_get_implementation(
|
||||||
|
softfilter_simd_mask_t simd)
|
||||||
|
{
|
||||||
|
(void)simd;
|
||||||
|
return &normal4x_generic;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RARCH_INTERNAL
|
||||||
|
#undef softfilter_get_implementation
|
||||||
|
#undef softfilter_thread_data
|
||||||
|
#undef filter_data
|
||||||
|
#endif
|
@ -38,7 +38,7 @@ RETRO_BEGIN_DECLS
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GFX_MAX_PARAMETERS
|
#ifndef GFX_MAX_PARAMETERS
|
||||||
#define GFX_MAX_PARAMETERS 256
|
#define GFX_MAX_PARAMETERS 512
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GFX_MAX_FRAME_HISTORY
|
#ifndef GFX_MAX_FRAME_HISTORY
|
||||||
|
@ -1003,6 +1003,7 @@ FILTERS
|
|||||||
#include "../gfx/video_filters/normal2x.c"
|
#include "../gfx/video_filters/normal2x.c"
|
||||||
#include "../gfx/video_filters/normal2x_width.c"
|
#include "../gfx/video_filters/normal2x_width.c"
|
||||||
#include "../gfx/video_filters/normal2x_height.c"
|
#include "../gfx/video_filters/normal2x_height.c"
|
||||||
|
#include "../gfx/video_filters/normal4x.c"
|
||||||
#include "../gfx/video_filters/scanline2x.c"
|
#include "../gfx/video_filters/scanline2x.c"
|
||||||
#include "../gfx/video_filters/grid2x.c"
|
#include "../gfx/video_filters/grid2x.c"
|
||||||
#include "../gfx/video_filters/grid3x.c"
|
#include "../gfx/video_filters/grid3x.c"
|
||||||
|
@ -81,6 +81,7 @@ struct dinput_input
|
|||||||
int mouse_x;
|
int mouse_x;
|
||||||
int mouse_y;
|
int mouse_y;
|
||||||
uint8_t state[256];
|
uint8_t state[256];
|
||||||
|
bool shift_l, shift_r, alt_l;
|
||||||
bool doubleclick_on_titlebar;
|
bool doubleclick_on_titlebar;
|
||||||
bool mouse_l, mouse_r, mouse_m, mouse_b4, mouse_b5, mouse_wu, mouse_wd, mouse_hwu, mouse_hwd;
|
bool mouse_l, mouse_r, mouse_m, mouse_b4, mouse_b5, mouse_wu, mouse_wd, mouse_hwu, mouse_hwd;
|
||||||
};
|
};
|
||||||
@ -160,7 +161,7 @@ static void *dinput_init(const char *joypad_driver)
|
|||||||
{
|
{
|
||||||
IDirectInputDevice8_SetDataFormat(di->keyboard, &c_dfDIKeyboard);
|
IDirectInputDevice8_SetDataFormat(di->keyboard, &c_dfDIKeyboard);
|
||||||
IDirectInputDevice8_SetCooperativeLevel(di->keyboard,
|
IDirectInputDevice8_SetCooperativeLevel(di->keyboard,
|
||||||
(HWND)video_driver_window_get(), DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
|
(HWND)video_driver_window_get(), DISCL_NONEXCLUSIVE | DISCL_FOREGROUND | DISCL_NOWINKEY);
|
||||||
IDirectInputDevice8_Acquire(di->keyboard);
|
IDirectInputDevice8_Acquire(di->keyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,6 +182,50 @@ static void *dinput_init(const char *joypad_driver)
|
|||||||
return di;
|
return di;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dinput_keyboard_mods(struct dinput_input *di, int mod)
|
||||||
|
{
|
||||||
|
switch (mod)
|
||||||
|
{
|
||||||
|
case RETROKMOD_SHIFT:
|
||||||
|
{
|
||||||
|
unsigned vk_shift_l = GetAsyncKeyState(VK_LSHIFT) >> 1;
|
||||||
|
unsigned vk_shift_r = GetAsyncKeyState(VK_RSHIFT) >> 1;
|
||||||
|
|
||||||
|
if ( (vk_shift_l && !di->shift_l) ||
|
||||||
|
(!vk_shift_l && di->shift_l))
|
||||||
|
{
|
||||||
|
input_keyboard_event(vk_shift_l, RETROK_LSHIFT,
|
||||||
|
0, RETROKMOD_SHIFT, RETRO_DEVICE_KEYBOARD);
|
||||||
|
di->shift_l = !di->shift_l;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (vk_shift_r && !di->shift_r) ||
|
||||||
|
(!vk_shift_r && di->shift_r))
|
||||||
|
{
|
||||||
|
input_keyboard_event(vk_shift_r, RETROK_RSHIFT,
|
||||||
|
0, RETROKMOD_SHIFT, RETRO_DEVICE_KEYBOARD);
|
||||||
|
di->shift_r = !di->shift_r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RETROKMOD_ALT:
|
||||||
|
{
|
||||||
|
unsigned vk_alt_l = GetAsyncKeyState(VK_LMENU) >> 1;
|
||||||
|
|
||||||
|
if (vk_alt_l && !di->alt_l)
|
||||||
|
di->alt_l = !di->alt_l;
|
||||||
|
else if (!vk_alt_l && di->alt_l)
|
||||||
|
{
|
||||||
|
input_keyboard_event(vk_alt_l, RETROK_LALT,
|
||||||
|
0, RETROKMOD_ALT, RETRO_DEVICE_KEYBOARD);
|
||||||
|
di->alt_l = !di->alt_l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void dinput_poll(void *data)
|
static void dinput_poll(void *data)
|
||||||
{
|
{
|
||||||
struct dinput_input *di = (struct dinput_input*)data;
|
struct dinput_input *di = (struct dinput_input*)data;
|
||||||
@ -211,6 +256,12 @@ static void dinput_poll(void *data)
|
|||||||
*kb_state = 0;
|
*kb_state = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
/* Shifts only when window focused */
|
||||||
|
dinput_keyboard_mods(di, RETROKMOD_SHIFT);
|
||||||
|
|
||||||
|
/* Left alt keyup when unfocused, to prevent alt-tab sticky */
|
||||||
|
dinput_keyboard_mods(di, RETROKMOD_ALT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (di->mouse)
|
if (di->mouse)
|
||||||
|
@ -117,6 +117,7 @@ enum
|
|||||||
|
|
||||||
RARCH_RECORDING_TOGGLE,
|
RARCH_RECORDING_TOGGLE,
|
||||||
RARCH_STREAMING_TOGGLE,
|
RARCH_STREAMING_TOGGLE,
|
||||||
|
RARCH_RUNAHEAD_TOGGLE,
|
||||||
|
|
||||||
RARCH_AI_SERVICE,
|
RARCH_AI_SERVICE,
|
||||||
|
|
||||||
|
@ -225,6 +225,10 @@ int msg_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len)
|
|||||||
snprintf(s, len,
|
snprintf(s, len,
|
||||||
"Toggle between recording and not.");
|
"Toggle between recording and not.");
|
||||||
break;
|
break;
|
||||||
|
case RARCH_RUNAHEAD_TOGGLE:
|
||||||
|
snprintf(s, len,
|
||||||
|
"Toggles Run-Ahead mode on/off.");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (string_is_empty(s))
|
if (string_is_empty(s))
|
||||||
strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE), len);
|
strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE), len);
|
||||||
|
@ -2555,6 +2555,14 @@ MSG_HASH(
|
|||||||
MENU_ENUM_SUBLABEL_INPUT_META_STREAMING_TOGGLE,
|
MENU_ENUM_SUBLABEL_INPUT_META_STREAMING_TOGGLE,
|
||||||
"Starts/stops streaming of the current session to an online video platform."
|
"Starts/stops streaming of the current session to an online video platform."
|
||||||
)
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_LABEL_VALUE_INPUT_META_RUNAHEAD_TOGGLE,
|
||||||
|
"Run-Ahead (Toggle)"
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MENU_ENUM_SUBLABEL_INPUT_META_RUNAHEAD_TOGGLE,
|
||||||
|
"Switches Run-Ahead on/off."
|
||||||
|
)
|
||||||
MSG_HASH(
|
MSG_HASH(
|
||||||
MENU_ENUM_LABEL_VALUE_INPUT_META_AI_SERVICE,
|
MENU_ENUM_LABEL_VALUE_INPUT_META_AI_SERVICE,
|
||||||
"AI Service"
|
"AI Service"
|
||||||
@ -11276,6 +11284,18 @@ MSG_HASH(
|
|||||||
MSG_CORE_REMAP_FILE_LOADED,
|
MSG_CORE_REMAP_FILE_LOADED,
|
||||||
"Core remap file loaded."
|
"Core remap file loaded."
|
||||||
)
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MSG_RUNAHEAD_ENABLED,
|
||||||
|
"Run-Ahead enabled. Latency frames removed: %u."
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MSG_RUNAHEAD_ENABLED_WITH_SECOND_INSTANCE,
|
||||||
|
"Run-Ahead enabled with Secondary Instance. Latency frames removed: %u."
|
||||||
|
)
|
||||||
|
MSG_HASH(
|
||||||
|
MSG_RUNAHEAD_DISABLED,
|
||||||
|
"Run-Ahead disabled."
|
||||||
|
)
|
||||||
MSG_HASH(
|
MSG_HASH(
|
||||||
MSG_RUNAHEAD_CORE_DOES_NOT_SUPPORT_SAVESTATES,
|
MSG_RUNAHEAD_CORE_DOES_NOT_SUPPORT_SAVESTATES,
|
||||||
"Run-Ahead has been disabled because this core does not support save states."
|
"Run-Ahead has been disabled because this core does not support save states."
|
||||||
|
@ -1104,11 +1104,7 @@ void config_set_string(config_file_t *conf, const char *key, const char *val)
|
|||||||
if (entry)
|
if (entry)
|
||||||
{
|
{
|
||||||
/* An entry corresponding to 'key' already exists
|
/* An entry corresponding to 'key' already exists
|
||||||
* > Check if it's read only */
|
* > Check whether value is currently set */
|
||||||
if (entry->readonly)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Check whether value is currently set */
|
|
||||||
if (entry->value)
|
if (entry->value)
|
||||||
{
|
{
|
||||||
/* Do nothing if value is unchanged */
|
/* Do nothing if value is unchanged */
|
||||||
@ -1120,8 +1116,11 @@ void config_set_string(config_file_t *conf, const char *key, const char *val)
|
|||||||
free(entry->value);
|
free(entry->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update value */
|
/* Update value
|
||||||
|
* > Note that once a value is set, it
|
||||||
|
* is no longer considered 'read only' */
|
||||||
entry->value = strdup(val);
|
entry->value = strdup(val);
|
||||||
|
entry->readonly = false;
|
||||||
conf->modified = true;
|
conf->modified = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1300,14 +1299,6 @@ void config_file_dump_orbis(config_file_t *conf, int fd)
|
|||||||
if (conf->reference)
|
if (conf->reference)
|
||||||
fprintf(file, "#reference \"%s\"\n", conf->reference);
|
fprintf(file, "#reference \"%s\"\n", conf->reference);
|
||||||
|
|
||||||
while (includes)
|
|
||||||
{
|
|
||||||
char cad[256];
|
|
||||||
snprintf(cad, sizeof(cad),
|
|
||||||
"#include %s\n", includes->path);
|
|
||||||
orbisWrite(fd, cad, strlen(cad));
|
|
||||||
includes = includes->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
list = config_file_merge_sort_linked_list(
|
list = config_file_merge_sort_linked_list(
|
||||||
(struct config_entry_list*)conf->entries,
|
(struct config_entry_list*)conf->entries,
|
||||||
@ -1325,6 +1316,21 @@ void config_file_dump_orbis(config_file_t *conf, int fd)
|
|||||||
}
|
}
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Config files are read from the top down - if
|
||||||
|
* duplicate entries are found then the topmost
|
||||||
|
* one in the list takes precedence. This means
|
||||||
|
* '#include' directives must go *after* individual
|
||||||
|
* config entries, otherwise they will override
|
||||||
|
* any custom-set values */
|
||||||
|
while (includes)
|
||||||
|
{
|
||||||
|
char cad[256];
|
||||||
|
snprintf(cad, sizeof(cad),
|
||||||
|
"#include %s\n", includes->path);
|
||||||
|
orbisWrite(fd, cad, strlen(cad));
|
||||||
|
includes = includes->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1336,12 +1342,6 @@ void config_file_dump(config_file_t *conf, FILE *file, bool sort)
|
|||||||
if (conf->reference)
|
if (conf->reference)
|
||||||
fprintf(file, "#reference \"%s\"\n", conf->reference);
|
fprintf(file, "#reference \"%s\"\n", conf->reference);
|
||||||
|
|
||||||
while (includes)
|
|
||||||
{
|
|
||||||
fprintf(file, "#include \"%s\"\n", includes->path);
|
|
||||||
includes = includes->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sort)
|
if (sort)
|
||||||
list = config_file_merge_sort_linked_list(
|
list = config_file_merge_sort_linked_list(
|
||||||
(struct config_entry_list*)conf->entries,
|
(struct config_entry_list*)conf->entries,
|
||||||
@ -1357,6 +1357,18 @@ void config_file_dump(config_file_t *conf, FILE *file, bool sort)
|
|||||||
fprintf(file, "%s = \"%s\"\n", list->key, list->value);
|
fprintf(file, "%s = \"%s\"\n", list->key, list->value);
|
||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Config files are read from the top down - if
|
||||||
|
* duplicate entries are found then the topmost
|
||||||
|
* one in the list takes precedence. This means
|
||||||
|
* '#include' directives must go *after* individual
|
||||||
|
* config entries, otherwise they will override
|
||||||
|
* any custom-set values */
|
||||||
|
while (includes)
|
||||||
|
{
|
||||||
|
fprintf(file, "#include \"%s\"\n", includes->path);
|
||||||
|
includes = includes->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool config_entry_exists(config_file_t *conf, const char *entry)
|
bool config_entry_exists(config_file_t *conf, const char *entry)
|
||||||
|
@ -66,11 +66,16 @@
|
|||||||
*-------------------------------------------------
|
*-------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Huge alignment values for possible SIMD optimization by compiler (NEON, SSE, AVX) */
|
||||||
|
#define LZMA_MIN_ALIGNMENT_BITS 512
|
||||||
|
#define LZMA_MIN_ALIGNMENT_BYTES (LZMA_MIN_ALIGNMENT_BITS / 8)
|
||||||
|
|
||||||
static void *lzma_fast_alloc(void *p, size_t size)
|
static void *lzma_fast_alloc(void *p, size_t size)
|
||||||
{
|
{
|
||||||
int scan;
|
int scan;
|
||||||
uint32_t *addr = NULL;
|
uint32_t *addr = NULL;
|
||||||
lzma_allocator *codec = (lzma_allocator *)(p);
|
lzma_allocator *codec = (lzma_allocator *)(p);
|
||||||
|
uintptr_t vaddr = 0;
|
||||||
|
|
||||||
/* compute the size, rounding to the nearest 1k */
|
/* compute the size, rounding to the nearest 1k */
|
||||||
size = (size + 0x3ff) & ~0x3ff;
|
size = (size + 0x3ff) & ~0x3ff;
|
||||||
@ -83,27 +88,36 @@ static void *lzma_fast_alloc(void *p, size_t size)
|
|||||||
{
|
{
|
||||||
/* set the low bit of the size so we don't match next time */
|
/* set the low bit of the size so we don't match next time */
|
||||||
*ptr |= 1;
|
*ptr |= 1;
|
||||||
return ptr + 1;
|
|
||||||
|
/* return aligned address of the block */
|
||||||
|
return codec->allocptr2[scan];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* alloc a new one and put it into the list */
|
/* alloc a new one and put it into the list */
|
||||||
addr = (uint32_t *)malloc(sizeof(uint32_t) * size + sizeof(uintptr_t));
|
addr = (uint32_t *)malloc(size + sizeof(uint32_t) + LZMA_MIN_ALIGNMENT_BYTES);
|
||||||
if (!addr)
|
if (addr==NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
|
for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
|
||||||
{
|
{
|
||||||
if (codec->allocptr[scan] == NULL)
|
if (codec->allocptr[scan] == NULL)
|
||||||
{
|
{
|
||||||
|
/* store block address */
|
||||||
codec->allocptr[scan] = addr;
|
codec->allocptr[scan] = addr;
|
||||||
|
|
||||||
|
/* compute aligned address, store it */
|
||||||
|
vaddr = (uintptr_t)addr;
|
||||||
|
vaddr = (vaddr + sizeof(uint32_t) + (LZMA_MIN_ALIGNMENT_BYTES-1)) & (~(LZMA_MIN_ALIGNMENT_BYTES-1));
|
||||||
|
codec->allocptr2[scan] = (uint32_t*)vaddr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the low bit of the size so we don't match next time */
|
/* set the low bit of the size so we don't match next time */
|
||||||
*addr = (uint32_t)(size | 1);
|
*addr = size | 1;
|
||||||
return addr + (sizeof(uint32_t) == sizeof(uintptr_t) ? 1 : 2);
|
|
||||||
|
/* return aligned address */
|
||||||
|
return (void*)vaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
@ -114,21 +128,22 @@ static void *lzma_fast_alloc(void *p, size_t size)
|
|||||||
static void lzma_fast_free(void *p, void *address)
|
static void lzma_fast_free(void *p, void *address)
|
||||||
{
|
{
|
||||||
int scan;
|
int scan;
|
||||||
uint32_t *ptr;
|
uint32_t *ptr = NULL;
|
||||||
lzma_allocator *codec;
|
lzma_allocator *codec = NULL;
|
||||||
|
|
||||||
if (address == NULL)
|
if (address == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
codec = (lzma_allocator *)(p);
|
codec = (lzma_allocator *)(p);
|
||||||
|
|
||||||
/* find the hunk */
|
/* find the hunk */
|
||||||
ptr = (uint32_t *)(address) - 1;
|
ptr = (uint32_t *)address;
|
||||||
for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
|
for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
|
||||||
{
|
{
|
||||||
if (ptr == codec->allocptr[scan])
|
if (ptr == codec->allocptr2[scan])
|
||||||
{
|
{
|
||||||
/* clear the low bit of the size to allow matches */
|
/* clear the low bit of the size to allow matches */
|
||||||
*ptr &= ~1;
|
*codec->allocptr[scan] &= ~1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,9 +241,14 @@ chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t comple
|
|||||||
allocates and frees memory frequently
|
allocates and frees memory frequently
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Huge alignment values for possible SIMD optimization by compiler (NEON, SSE, AVX) */
|
||||||
|
#define ZLIB_MIN_ALIGNMENT_BITS 512
|
||||||
|
#define ZLIB_MIN_ALIGNMENT_BYTES (ZLIB_MIN_ALIGNMENT_BITS / 8)
|
||||||
|
|
||||||
voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
|
voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
|
||||||
{
|
{
|
||||||
zlib_allocator *alloc = (zlib_allocator *)opaque;
|
zlib_allocator *alloc = (zlib_allocator *)opaque;
|
||||||
|
uintptr_t paddr = 0;
|
||||||
UINT32 *ptr;
|
UINT32 *ptr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -258,12 +263,14 @@ voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
|
|||||||
{
|
{
|
||||||
/* set the low bit of the size so we don't match next time */
|
/* set the low bit of the size so we don't match next time */
|
||||||
*ptr |= 1;
|
*ptr |= 1;
|
||||||
return ptr + 1;
|
|
||||||
|
/* return aligned block address */
|
||||||
|
return (voidpf)(alloc->allocptr2[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* alloc a new one */
|
/* alloc a new one */
|
||||||
ptr = (UINT32 *)malloc(size + sizeof(uintptr_t));
|
ptr = (UINT32 *)malloc(size + sizeof(UINT32) + ZLIB_MIN_ALIGNMENT_BYTES);
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -272,12 +279,16 @@ voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
|
|||||||
if (!alloc->allocptr[i])
|
if (!alloc->allocptr[i])
|
||||||
{
|
{
|
||||||
alloc->allocptr[i] = ptr;
|
alloc->allocptr[i] = ptr;
|
||||||
|
paddr = (((uintptr_t)ptr) + sizeof(UINT32) + (ZLIB_MIN_ALIGNMENT_BYTES-1)) & (~(ZLIB_MIN_ALIGNMENT_BYTES-1));
|
||||||
|
alloc->allocptr2[i] = (uint32_t*)paddr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the low bit of the size so we don't match next time */
|
/* set the low bit of the size so we don't match next time */
|
||||||
*ptr = size | 1;
|
*ptr = size | 1;
|
||||||
return ptr + (sizeof(uint32_t) == sizeof(uintptr_t) ? 1 : 2);
|
|
||||||
|
/* return aligned block address */
|
||||||
|
return (voidpf)paddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
@ -288,15 +299,15 @@ voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
|
|||||||
void zlib_fast_free(voidpf opaque, voidpf address)
|
void zlib_fast_free(voidpf opaque, voidpf address)
|
||||||
{
|
{
|
||||||
zlib_allocator *alloc = (zlib_allocator *)opaque;
|
zlib_allocator *alloc = (zlib_allocator *)opaque;
|
||||||
UINT32 *ptr = (UINT32 *)address - (sizeof(uint32_t) == sizeof(uintptr_t) ? 1 : 2);
|
UINT32 *ptr = (UINT32 *)address;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* find the hunk */
|
/* find the hunk */
|
||||||
for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
|
for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
|
||||||
if (ptr == alloc->allocptr[i])
|
if (ptr == alloc->allocptr2[i])
|
||||||
{
|
{
|
||||||
/* clear the low bit of the size to allow matches */
|
/* clear the low bit of the size to allow matches */
|
||||||
*ptr &= ~1;
|
*(alloc->allocptr[i]) &= ~1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,16 +143,6 @@ rxml_document_t *rxml_load_document_string(const char *str)
|
|||||||
if (!doc)
|
if (!doc)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
doc->root_node = (struct rxml_node *)malloc(
|
|
||||||
sizeof(*doc->root_node));
|
|
||||||
|
|
||||||
doc->root_node->name = NULL;
|
|
||||||
doc->root_node->data = NULL;
|
|
||||||
doc->root_node->attrib = NULL;
|
|
||||||
|
|
||||||
doc->root_node->children = NULL;
|
|
||||||
doc->root_node->next = NULL;
|
|
||||||
|
|
||||||
yxml_init(&x, buf->xml, BUFSIZE);
|
yxml_init(&x, buf->xml, BUFSIZE);
|
||||||
|
|
||||||
for (; *str; ++str)
|
for (; *str; ++str)
|
||||||
@ -256,30 +246,14 @@ rxml_document_t *rxml_load_document_string(const char *str)
|
|||||||
|
|
||||||
case YXML_ATTRSTART:
|
case YXML_ATTRSTART:
|
||||||
if (attr)
|
if (attr)
|
||||||
{
|
attr = attr->next = (struct rxml_attrib_node*)
|
||||||
struct rxml_attrib_node
|
|
||||||
*new_node = (struct rxml_attrib_node*)
|
|
||||||
calloc(1, sizeof(*attr));
|
calloc(1, sizeof(*attr));
|
||||||
attr = new_node;
|
|
||||||
attr->next = new_node ;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
attr = node->attrib = (struct rxml_attrib_node*)calloc(1, sizeof(*attr));
|
||||||
struct rxml_attrib_node
|
|
||||||
*new_node = (struct rxml_attrib_node*)
|
|
||||||
calloc(1, sizeof(*attr));
|
|
||||||
attr = new_node;
|
|
||||||
|
|
||||||
if (node)
|
|
||||||
node->attrib = new_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attr)
|
|
||||||
{
|
|
||||||
if (attr->attrib)
|
if (attr->attrib)
|
||||||
free(attr->attrib);
|
free(attr->attrib);
|
||||||
attr->attrib = strdup(x.attr);
|
attr->attrib = strdup(x.attr);
|
||||||
}
|
|
||||||
|
|
||||||
valptr = buf->val;
|
valptr = buf->val;
|
||||||
break;
|
break;
|
||||||
|
@ -27,6 +27,7 @@ typedef struct _zlib_allocator zlib_allocator;
|
|||||||
struct _zlib_allocator
|
struct _zlib_allocator
|
||||||
{
|
{
|
||||||
UINT32 * allocptr[MAX_ZLIB_ALLOCS];
|
UINT32 * allocptr[MAX_ZLIB_ALLOCS];
|
||||||
|
UINT32 * allocptr2[MAX_ZLIB_ALLOCS];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _zlib_codec_data zlib_codec_data;
|
typedef struct _zlib_codec_data zlib_codec_data;
|
||||||
|
@ -30,6 +30,7 @@ struct _lzma_allocator
|
|||||||
void (*Free)(void *p, void *address); /* address can be 0 */
|
void (*Free)(void *p, void *address); /* address can be 0 */
|
||||||
void (*FreeSz)(void *p, void *address, size_t size); /* address can be 0 */
|
void (*FreeSz)(void *p, void *address, size_t size); /* address can be 0 */
|
||||||
uint32_t* allocptr[MAX_LZMA_ALLOCS];
|
uint32_t* allocptr[MAX_LZMA_ALLOCS];
|
||||||
|
uint32_t* allocptr2[MAX_LZMA_ALLOCS];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _lzma_codec_data lzma_codec_data;
|
typedef struct _lzma_codec_data lzma_codec_data;
|
||||||
|
@ -269,6 +269,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_game_focus_toggle, ME
|
|||||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_ui_companion_toggle, MENU_ENUM_SUBLABEL_INPUT_META_UI_COMPANION_TOGGLE)
|
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_ui_companion_toggle, MENU_ENUM_SUBLABEL_INPUT_META_UI_COMPANION_TOGGLE)
|
||||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_recording_toggle, MENU_ENUM_SUBLABEL_INPUT_META_RECORDING_TOGGLE)
|
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_recording_toggle, MENU_ENUM_SUBLABEL_INPUT_META_RECORDING_TOGGLE)
|
||||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_streaming_toggle, MENU_ENUM_SUBLABEL_INPUT_META_STREAMING_TOGGLE)
|
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_streaming_toggle, MENU_ENUM_SUBLABEL_INPUT_META_STREAMING_TOGGLE)
|
||||||
|
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_runahead_toggle, MENU_ENUM_SUBLABEL_INPUT_META_RUNAHEAD_TOGGLE)
|
||||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_ai_service, MENU_ENUM_SUBLABEL_INPUT_META_AI_SERVICE)
|
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_ai_service, MENU_ENUM_SUBLABEL_INPUT_META_AI_SERVICE)
|
||||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_menu_toggle, MENU_ENUM_SUBLABEL_INPUT_META_MENU_TOGGLE)
|
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_menu_toggle, MENU_ENUM_SUBLABEL_INPUT_META_MENU_TOGGLE)
|
||||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_hotkey_block_delay, MENU_ENUM_SUBLABEL_INPUT_HOTKEY_BLOCK_DELAY)
|
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_hotkey_block_delay, MENU_ENUM_SUBLABEL_INPUT_HOTKEY_BLOCK_DELAY)
|
||||||
@ -1694,6 +1695,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
|||||||
case RARCH_STREAMING_TOGGLE:
|
case RARCH_STREAMING_TOGGLE:
|
||||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_streaming_toggle);
|
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_streaming_toggle);
|
||||||
return 0;
|
return 0;
|
||||||
|
case RARCH_RUNAHEAD_TOGGLE:
|
||||||
|
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_runahead_toggle);
|
||||||
|
return 0;
|
||||||
case RARCH_AI_SERVICE:
|
case RARCH_AI_SERVICE:
|
||||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_ai_service);
|
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_ai_service);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -459,6 +459,9 @@ enum msg_hash_enums
|
|||||||
MSG_GAME_REMAP_FILE_LOADED,
|
MSG_GAME_REMAP_FILE_LOADED,
|
||||||
MSG_DIRECTORY_REMAP_FILE_LOADED,
|
MSG_DIRECTORY_REMAP_FILE_LOADED,
|
||||||
MSG_CORE_REMAP_FILE_LOADED,
|
MSG_CORE_REMAP_FILE_LOADED,
|
||||||
|
MSG_RUNAHEAD_ENABLED,
|
||||||
|
MSG_RUNAHEAD_ENABLED_WITH_SECOND_INSTANCE,
|
||||||
|
MSG_RUNAHEAD_DISABLED,
|
||||||
MSG_RUNAHEAD_CORE_DOES_NOT_SUPPORT_SAVESTATES,
|
MSG_RUNAHEAD_CORE_DOES_NOT_SUPPORT_SAVESTATES,
|
||||||
MSG_RUNAHEAD_FAILED_TO_SAVE_STATE,
|
MSG_RUNAHEAD_FAILED_TO_SAVE_STATE,
|
||||||
MSG_RUNAHEAD_FAILED_TO_LOAD_STATE,
|
MSG_RUNAHEAD_FAILED_TO_LOAD_STATE,
|
||||||
@ -851,6 +854,7 @@ enum msg_hash_enums
|
|||||||
MENU_ENUM_LABEL_VALUE_INPUT_META_UI_COMPANION_TOGGLE,
|
MENU_ENUM_LABEL_VALUE_INPUT_META_UI_COMPANION_TOGGLE,
|
||||||
MENU_ENUM_LABEL_VALUE_INPUT_META_RECORDING_TOGGLE,
|
MENU_ENUM_LABEL_VALUE_INPUT_META_RECORDING_TOGGLE,
|
||||||
MENU_ENUM_LABEL_VALUE_INPUT_META_STREAMING_TOGGLE,
|
MENU_ENUM_LABEL_VALUE_INPUT_META_STREAMING_TOGGLE,
|
||||||
|
MENU_ENUM_LABEL_VALUE_INPUT_META_RUNAHEAD_TOGGLE,
|
||||||
MENU_ENUM_LABEL_VALUE_INPUT_META_AI_SERVICE,
|
MENU_ENUM_LABEL_VALUE_INPUT_META_AI_SERVICE,
|
||||||
MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE,
|
MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE,
|
||||||
|
|
||||||
@ -903,6 +907,7 @@ enum msg_hash_enums
|
|||||||
MENU_ENUM_SUBLABEL_INPUT_META_UI_COMPANION_TOGGLE,
|
MENU_ENUM_SUBLABEL_INPUT_META_UI_COMPANION_TOGGLE,
|
||||||
MENU_ENUM_SUBLABEL_INPUT_META_RECORDING_TOGGLE,
|
MENU_ENUM_SUBLABEL_INPUT_META_RECORDING_TOGGLE,
|
||||||
MENU_ENUM_SUBLABEL_INPUT_META_STREAMING_TOGGLE,
|
MENU_ENUM_SUBLABEL_INPUT_META_STREAMING_TOGGLE,
|
||||||
|
MENU_ENUM_SUBLABEL_INPUT_META_RUNAHEAD_TOGGLE,
|
||||||
MENU_ENUM_SUBLABEL_INPUT_META_AI_SERVICE,
|
MENU_ENUM_SUBLABEL_INPUT_META_AI_SERVICE,
|
||||||
MENU_ENUM_SUBLABEL_INPUT_META_MENU_TOGGLE,
|
MENU_ENUM_SUBLABEL_INPUT_META_MENU_TOGGLE,
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
android:isGame="true"
|
android:isGame="true"
|
||||||
android:banner="@drawable/banner"
|
android:banner="@drawable/banner"
|
||||||
android:extractNativeLibs="true"
|
android:extractNativeLibs="true"
|
||||||
|
android:requestLegacyExternalStorage="true"
|
||||||
tools:ignore="UnusedAttribute">
|
tools:ignore="UnusedAttribute">
|
||||||
<activity android:name="com.retroarch.browser.mainmenu.MainMenuActivity" android:exported="true" android:launchMode="singleInstance">
|
<activity android:name="com.retroarch.browser.mainmenu.MainMenuActivity" android:exported="true" android:launchMode="singleInstance">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
@ -25,8 +25,8 @@ allprojects {
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 28
|
compileSdkVersion 29
|
||||||
buildToolsVersion "28.0.3"
|
buildToolsVersion "29.0.3"
|
||||||
|
|
||||||
flavorDimensions "variant"
|
flavorDimensions "variant"
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ android {
|
|||||||
arguments "-j${Runtime.runtime.availableProcessors()}"
|
arguments "-j${Runtime.runtime.availableProcessors()}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
targetSdkVersion 28
|
targetSdkVersion 29
|
||||||
}
|
}
|
||||||
|
|
||||||
productFlavors {
|
productFlavors {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
apply plugin: 'com.android.dynamic-feature'
|
apply plugin: 'com.android.dynamic-feature'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 28
|
compileSdkVersion 29
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 28
|
targetSdkVersion 29
|
||||||
}
|
}
|
||||||
|
|
||||||
flavorDimensions "variant"
|
flavorDimensions "variant"
|
||||||
|
@ -85,6 +85,8 @@ HAVE_VIVANTE_FBDEV=no # Vivante fbdev context support
|
|||||||
HAVE_OPENDINGUX_FBDEV=no # Opendingux fbdev context support
|
HAVE_OPENDINGUX_FBDEV=no # Opendingux fbdev context support
|
||||||
HAVE_OPENGLES=no # Use GLESv2 instead of desktop GL
|
HAVE_OPENGLES=no # Use GLESv2 instead of desktop GL
|
||||||
HAVE_OPENGLES3=no # OpenGLES3 support
|
HAVE_OPENGLES3=no # OpenGLES3 support
|
||||||
|
HAVE_OPENGLES3_1=no # OpenGLES3.1 support
|
||||||
|
HAVE_OPENGLES3_2=no # OpenGLES3.2 support
|
||||||
HAVE_X11=auto # everything X11.
|
HAVE_X11=auto # everything X11.
|
||||||
HAVE_XRANDR=auto # Xrandr support.
|
HAVE_XRANDR=auto # Xrandr support.
|
||||||
HAVE_OMAP=no # OMAP video support
|
HAVE_OMAP=no # OMAP video support
|
||||||
@ -187,3 +189,4 @@ C89_METAL=no
|
|||||||
HAVE_NETWORK_VIDEO=no
|
HAVE_NETWORK_VIDEO=no
|
||||||
HAVE_STEAM=no # Enable Steam build
|
HAVE_STEAM=no # Enable Steam build
|
||||||
HAVE_ODROIDGO2=no # ODROID-GO Advance rotation support (requires librga)
|
HAVE_ODROIDGO2=no # ODROID-GO Advance rotation support (requires librga)
|
||||||
|
HAVE_GIT_VERSION=yes # Git version support
|
||||||
|
68
retroarch.c
68
retroarch.c
@ -2730,6 +2730,7 @@ static const struct input_bind_map input_config_bind_map[RARCH_BIND_LIST_END_NUL
|
|||||||
#endif
|
#endif
|
||||||
DECLARE_META_BIND(2, recording_toggle, RARCH_RECORDING_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_RECORDING_TOGGLE),
|
DECLARE_META_BIND(2, recording_toggle, RARCH_RECORDING_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_RECORDING_TOGGLE),
|
||||||
DECLARE_META_BIND(2, streaming_toggle, RARCH_STREAMING_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_STREAMING_TOGGLE),
|
DECLARE_META_BIND(2, streaming_toggle, RARCH_STREAMING_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_STREAMING_TOGGLE),
|
||||||
|
DECLARE_META_BIND(2, runahead_toggle, RARCH_RUNAHEAD_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_RUNAHEAD_TOGGLE),
|
||||||
DECLARE_META_BIND(2, ai_service, RARCH_AI_SERVICE, MENU_ENUM_LABEL_VALUE_INPUT_META_AI_SERVICE),
|
DECLARE_META_BIND(2, ai_service, RARCH_AI_SERVICE, MENU_ENUM_LABEL_VALUE_INPUT_META_AI_SERVICE),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -12982,6 +12983,7 @@ static const struct cmd_map map[] = {
|
|||||||
{ "MENU_TOGGLE", RARCH_MENU_TOGGLE },
|
{ "MENU_TOGGLE", RARCH_MENU_TOGGLE },
|
||||||
{ "RECORDING_TOGGLE", RARCH_RECORDING_TOGGLE },
|
{ "RECORDING_TOGGLE", RARCH_RECORDING_TOGGLE },
|
||||||
{ "STREAMING_TOGGLE", RARCH_STREAMING_TOGGLE },
|
{ "STREAMING_TOGGLE", RARCH_STREAMING_TOGGLE },
|
||||||
|
{ "RUNAHEAD_TOGGLE", RARCH_RUNAHEAD_TOGGLE },
|
||||||
{ "MENU_UP", RETRO_DEVICE_ID_JOYPAD_UP },
|
{ "MENU_UP", RETRO_DEVICE_ID_JOYPAD_UP },
|
||||||
{ "MENU_DOWN", RETRO_DEVICE_ID_JOYPAD_DOWN },
|
{ "MENU_DOWN", RETRO_DEVICE_ID_JOYPAD_DOWN },
|
||||||
{ "MENU_LEFT", RETRO_DEVICE_ID_JOYPAD_LEFT },
|
{ "MENU_LEFT", RETRO_DEVICE_ID_JOYPAD_LEFT },
|
||||||
@ -15993,6 +15995,37 @@ bool command_event(enum event_command cmd, void *data)
|
|||||||
command_event(CMD_EVENT_RECORD_INIT, NULL);
|
command_event(CMD_EVENT_RECORD_INIT, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case CMD_EVENT_RUNAHEAD_TOGGLE:
|
||||||
|
settings->bools.run_ahead_enabled = !(settings->bools.run_ahead_enabled);
|
||||||
|
|
||||||
|
char msg[256];
|
||||||
|
msg[0] = '\0';
|
||||||
|
|
||||||
|
if (!settings->bools.run_ahead_enabled)
|
||||||
|
{
|
||||||
|
runloop_msg_queue_push(msg_hash_to_str(MSG_RUNAHEAD_DISABLED),
|
||||||
|
1, 100, false,
|
||||||
|
NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||||
|
}
|
||||||
|
else if (!settings->bools.run_ahead_secondary_instance)
|
||||||
|
{
|
||||||
|
snprintf(msg, sizeof(msg), msg_hash_to_str(MSG_RUNAHEAD_ENABLED),
|
||||||
|
settings->uints.run_ahead_frames);
|
||||||
|
|
||||||
|
runloop_msg_queue_push(
|
||||||
|
msg, 1, 100, false,
|
||||||
|
NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snprintf(msg, sizeof(msg), msg_hash_to_str(MSG_RUNAHEAD_ENABLED_WITH_SECOND_INSTANCE),
|
||||||
|
settings->uints.run_ahead_frames);
|
||||||
|
|
||||||
|
runloop_msg_queue_push(
|
||||||
|
msg, 1, 100, false,
|
||||||
|
NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case CMD_EVENT_RECORDING_TOGGLE:
|
case CMD_EVENT_RECORDING_TOGGLE:
|
||||||
if (recording_is_enabled())
|
if (recording_is_enabled())
|
||||||
command_event(CMD_EVENT_RECORD_DEINIT, NULL);
|
command_event(CMD_EVENT_RECORD_DEINIT, NULL);
|
||||||
@ -18846,6 +18879,22 @@ static bool dynamic_request_hw_context(enum retro_hw_context_type type,
|
|||||||
|
|
||||||
#if defined(HAVE_OPENGLES3)
|
#if defined(HAVE_OPENGLES3)
|
||||||
case RETRO_HW_CONTEXT_OPENGLES_VERSION:
|
case RETRO_HW_CONTEXT_OPENGLES_VERSION:
|
||||||
|
#ifndef HAVE_OPENGLES3_2
|
||||||
|
if (major == 3 && minor == 2)
|
||||||
|
{
|
||||||
|
RARCH_ERR("Requesting OpenGLES%u.%u context, but RetroArch is compiled against a lesser version. Cannot use HW context.\n",
|
||||||
|
major, minor);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if !defined(HAVE_OPENGLES3_2) && !defined(HAVE_OPENGLES3_1)
|
||||||
|
if (major == 3 && minor == 1)
|
||||||
|
{
|
||||||
|
RARCH_ERR("Requesting OpenGLES%u.%u context, but RetroArch is compiled against a lesser version. Cannot use HW context.\n",
|
||||||
|
major, minor);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
RARCH_LOG("Requesting OpenGLES%u.%u context.\n",
|
RARCH_LOG("Requesting OpenGLES%u.%u context.\n",
|
||||||
major, minor);
|
major, minor);
|
||||||
break;
|
break;
|
||||||
@ -24504,9 +24553,12 @@ static void input_driver_poll(void)
|
|||||||
unsigned remap_button =
|
unsigned remap_button =
|
||||||
settings->uints.input_keymapper_ids[i][j];
|
settings->uints.input_keymapper_ids[i][j];
|
||||||
bool remap_valid =
|
bool remap_valid =
|
||||||
remap_button != RETROK_UNKNOWN;
|
remap_button != RETROK_UNKNOWN &&
|
||||||
if (remap_valid)
|
!handle->keys[remap_button / 32];
|
||||||
{
|
|
||||||
|
if (!remap_valid)
|
||||||
|
continue;
|
||||||
|
|
||||||
unsigned current_button_value =
|
unsigned current_button_value =
|
||||||
BIT256_GET_PTR(p_new_state, j);
|
BIT256_GET_PTR(p_new_state, j);
|
||||||
|
|
||||||
@ -24538,7 +24590,6 @@ static void input_driver_poll(void)
|
|||||||
remap_button,
|
remap_button,
|
||||||
0, 0, RETRO_DEVICE_KEYBOARD);
|
0, 0, RETRO_DEVICE_KEYBOARD);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* gamepad remapping */
|
/* gamepad remapping */
|
||||||
@ -39679,12 +39730,15 @@ static enum runloop_state runloop_check_state(
|
|||||||
/* Check if we have pressed the recording toggle button */
|
/* Check if we have pressed the recording toggle button */
|
||||||
HOTKEY_CHECK(RARCH_RECORDING_TOGGLE, CMD_EVENT_RECORDING_TOGGLE, true, NULL);
|
HOTKEY_CHECK(RARCH_RECORDING_TOGGLE, CMD_EVENT_RECORDING_TOGGLE, true, NULL);
|
||||||
|
|
||||||
/* Check if we have pressed the AI Service toggle button */
|
|
||||||
HOTKEY_CHECK(RARCH_AI_SERVICE, CMD_EVENT_AI_SERVICE_TOGGLE, true, NULL);
|
|
||||||
|
|
||||||
/* Check if we have pressed the streaming toggle button */
|
/* Check if we have pressed the streaming toggle button */
|
||||||
HOTKEY_CHECK(RARCH_STREAMING_TOGGLE, CMD_EVENT_STREAMING_TOGGLE, true, NULL);
|
HOTKEY_CHECK(RARCH_STREAMING_TOGGLE, CMD_EVENT_STREAMING_TOGGLE, true, NULL);
|
||||||
|
|
||||||
|
/* Check if we have pressed the Run-Ahead toggle button */
|
||||||
|
HOTKEY_CHECK(RARCH_RUNAHEAD_TOGGLE, CMD_EVENT_RUNAHEAD_TOGGLE, true, NULL);
|
||||||
|
|
||||||
|
/* Check if we have pressed the AI Service toggle button */
|
||||||
|
HOTKEY_CHECK(RARCH_AI_SERVICE, CMD_EVENT_AI_SERVICE_TOGGLE, true, NULL);
|
||||||
|
|
||||||
if (BIT256_GET(current_bits, RARCH_VOLUME_UP))
|
if (BIT256_GET(current_bits, RARCH_VOLUME_UP))
|
||||||
command_event(CMD_EVENT_VOLUME_UP, NULL);
|
command_event(CMD_EVENT_VOLUME_UP, NULL);
|
||||||
else if (BIT256_GET(current_bits, RARCH_VOLUME_DOWN))
|
else if (BIT256_GET(current_bits, RARCH_VOLUME_DOWN))
|
||||||
|
@ -708,10 +708,15 @@ static int database_info_list_iterate_found_match(
|
|||||||
const char *archive_name
|
const char *archive_name
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
char db_crc[PATH_MAX_LENGTH];
|
/* TODO/FIXME - heap allocations are done here to avoid
|
||||||
char db_playlist_base_str[PATH_MAX_LENGTH];
|
* running out of stack space on systems with a limited stack size.
|
||||||
char db_playlist_path[PATH_MAX_LENGTH];
|
* We should use less fullsize paths in the future so that we don't
|
||||||
char entry_path_str[PATH_MAX_LENGTH];
|
* need to have all these big char arrays here */
|
||||||
|
size_t str_len = PATH_MAX_LENGTH * sizeof(char);
|
||||||
|
char* db_crc = (char*)malloc(str_len);
|
||||||
|
char* db_playlist_base_str = (char*)malloc(str_len);
|
||||||
|
char* db_playlist_path = (char*)malloc(str_len);
|
||||||
|
char* entry_path_str = (char*)malloc(str_len);
|
||||||
char *hash = NULL;
|
char *hash = NULL;
|
||||||
playlist_t *playlist = NULL;
|
playlist_t *playlist = NULL;
|
||||||
const char *db_path =
|
const char *db_path =
|
||||||
@ -727,25 +732,25 @@ static int database_info_list_iterate_found_match(
|
|||||||
entry_path_str[0] = '\0';
|
entry_path_str[0] = '\0';
|
||||||
|
|
||||||
fill_short_pathname_representation_noext(db_playlist_base_str,
|
fill_short_pathname_representation_noext(db_playlist_base_str,
|
||||||
db_path, sizeof(db_playlist_base_str));
|
db_path, str_len);
|
||||||
|
|
||||||
strlcat(db_playlist_base_str, ".lpl", sizeof(db_playlist_base_str));
|
strlcat(db_playlist_base_str, ".lpl", str_len);
|
||||||
|
|
||||||
if (!string_is_empty(_db->playlist_directory))
|
if (!string_is_empty(_db->playlist_directory))
|
||||||
fill_pathname_join(db_playlist_path, _db->playlist_directory,
|
fill_pathname_join(db_playlist_path, _db->playlist_directory,
|
||||||
db_playlist_base_str, sizeof(db_playlist_path));
|
db_playlist_base_str, str_len);
|
||||||
|
|
||||||
playlist_config_set_path(&_db->playlist_config, db_playlist_path);
|
playlist_config_set_path(&_db->playlist_config, db_playlist_path);
|
||||||
playlist = playlist_init(&_db->playlist_config);
|
playlist = playlist_init(&_db->playlist_config);
|
||||||
|
|
||||||
snprintf(db_crc, sizeof(db_crc), "%08X|crc", db_info_entry->crc32);
|
snprintf(db_crc, str_len, "%08X|crc", db_info_entry->crc32);
|
||||||
|
|
||||||
if (entry_path)
|
if (entry_path)
|
||||||
strlcpy(entry_path_str, entry_path, sizeof(entry_path_str));
|
strlcpy(entry_path_str, entry_path, str_len);
|
||||||
|
|
||||||
if (!string_is_empty(archive_name))
|
if (!string_is_empty(archive_name))
|
||||||
fill_pathname_join_delim(entry_path_str,
|
fill_pathname_join_delim(entry_path_str,
|
||||||
entry_path_str, archive_name, '#', sizeof(entry_path_str));
|
entry_path_str, archive_name, '#', str_len);
|
||||||
|
|
||||||
if (core_info_database_match_archive_member(
|
if (core_info_database_match_archive_member(
|
||||||
db_state->list->elems[db_state->list_index].data) &&
|
db_state->list->elems[db_state->list_index].data) &&
|
||||||
@ -826,6 +831,10 @@ static int database_info_list_iterate_found_match(
|
|||||||
db_state->list->elems[0] = entry;
|
db_state->list->elems[0] = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(db_crc);
|
||||||
|
free(db_playlist_base_str);
|
||||||
|
free(db_playlist_path);
|
||||||
|
free(entry_path_str);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -860,7 +860,11 @@ static void task_load_handler(retro_task_t *task)
|
|||||||
{
|
{
|
||||||
if (state->autoload)
|
if (state->autoload)
|
||||||
{
|
{
|
||||||
|
#ifdef __CELLOS_LV2__
|
||||||
|
char *msg = (char*)malloc(8192 * sizeof(char));
|
||||||
|
#else
|
||||||
char msg[8192];
|
char msg[8192];
|
||||||
|
#endif
|
||||||
|
|
||||||
msg[0] = '\0';
|
msg[0] = '\0';
|
||||||
|
|
||||||
@ -871,6 +875,9 @@ static void task_load_handler(retro_task_t *task)
|
|||||||
state->path,
|
state->path,
|
||||||
msg_hash_to_str(MSG_FAILED));
|
msg_hash_to_str(MSG_FAILED));
|
||||||
task_set_error(task, strdup(msg));
|
task_set_error(task, strdup(msg));
|
||||||
|
#ifdef __CELLOS_LV2__
|
||||||
|
free(msg);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
task_set_error(task, strdup(msg_hash_to_str(MSG_FAILED_TO_LOAD_STATE)));
|
task_set_error(task, strdup(msg_hash_to_str(MSG_FAILED_TO_LOAD_STATE)));
|
||||||
|
@ -141,7 +141,7 @@ void PlaylistEntryDialog::loadPlaylistOptions()
|
|||||||
QString ui_display_name;
|
QString ui_display_name;
|
||||||
QHash<QString, QString> hash;
|
QHash<QString, QString> hash;
|
||||||
const core_info_t *core = &core_info_list->list[i];
|
const core_info_t *core = &core_info_list->list[i];
|
||||||
QStringList databases = QString(core->databases).split("|");
|
QStringList databases = string_split_to_qt(QString(core->databases), '|');
|
||||||
|
|
||||||
hash["core_name"] = core->core_name;
|
hash["core_name"] = core->core_name;
|
||||||
hash["core_display_name"] = core->display_name;
|
hash["core_display_name"] = core->display_name;
|
||||||
@ -278,8 +278,7 @@ const QStringList PlaylistEntryDialog::getSelectedExtensions()
|
|||||||
|
|
||||||
/* Otherwise it would create a QStringList with a single blank entry... */
|
/* Otherwise it would create a QStringList with a single blank entry... */
|
||||||
if (!text.isEmpty())
|
if (!text.isEmpty())
|
||||||
list = text.split(' ');
|
list = string_split_to_qt(text, ' ');
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <QButtonGroup>
|
#include <QButtonGroup>
|
||||||
|
|
||||||
#include "settingswidgets.h"
|
#include "settingswidgets.h"
|
||||||
|
#include "../ui_qt.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
@ -442,7 +443,7 @@ StringComboBox::StringComboBox(rarch_setting_t *setting, QWidget *parent) :
|
|||||||
,m_setting(setting)
|
,m_setting(setting)
|
||||||
,m_value(setting->value.target.string)
|
,m_value(setting->value.target.string)
|
||||||
{
|
{
|
||||||
addItems(QString(setting->values).split("|"));
|
addItems(string_split_to_qt(QString(setting->values), '|'));
|
||||||
|
|
||||||
connect(this, SIGNAL(currentTextChanged(const QString&)), this, SLOT(onCurrentTextChanged(const QString&)));
|
connect(this, SIGNAL(currentTextChanged(const QString&)), this, SLOT(onCurrentTextChanged(const QString&)));
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ui_qt_load_core_window.h"
|
#include "ui_qt_load_core_window.h"
|
||||||
|
#include "../ui_qt.h"
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
@ -235,8 +236,7 @@ void LoadCoreWindow::initCoreList(const QStringList &extensionFilters)
|
|||||||
name_item = new QTableWidgetItem(name);
|
name_item = new QTableWidgetItem(name);
|
||||||
|
|
||||||
hash["path"] = core->path;
|
hash["path"] = core->path;
|
||||||
hash["extensions"] = QString(
|
hash["extensions"] = string_split_to_qt(QString(core->supported_extensions), '|');
|
||||||
core->supported_extensions).split("|");
|
|
||||||
|
|
||||||
name_item->setData(Qt::UserRole, hash);
|
name_item->setData(Qt::UserRole, hash);
|
||||||
name_item->setFlags(name_item->flags() & ~Qt::ItemIsEditable);
|
name_item->setFlags(name_item->flags() & ~Qt::ItemIsEditable);
|
||||||
|
@ -764,3 +764,26 @@ ui_companion_driver_t ui_companion_qt = {
|
|||||||
&ui_application_qt,
|
&ui_application_qt,
|
||||||
"qt",
|
"qt",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QStringList string_split_to_qt(QString str, char delim)
|
||||||
|
{
|
||||||
|
int at;
|
||||||
|
QStringList list = QStringList();
|
||||||
|
|
||||||
|
for (at = 0;;)
|
||||||
|
{
|
||||||
|
/* Find next split */
|
||||||
|
int spl = str.indexOf(delim, at);
|
||||||
|
|
||||||
|
/* Store split into list of extensions */
|
||||||
|
list << str.mid(at, (spl < 0 ? -1 : spl - at));
|
||||||
|
|
||||||
|
/* No more splits */
|
||||||
|
if (spl < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
at = spl + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
@ -678,6 +678,8 @@ typedef struct ui_window_qt
|
|||||||
MainWindow *qtWindow;
|
MainWindow *qtWindow;
|
||||||
} ui_window_qt_t;
|
} ui_window_qt_t;
|
||||||
|
|
||||||
|
QStringList string_split_to_qt(QString str, char delim);
|
||||||
|
|
||||||
RETRO_END_DECLS
|
RETRO_END_DECLS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user