mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-23 16:09:47 +00:00
Merge branch 'master' into Shader_Save_Load
This commit is contained in:
commit
5008ac6eb0
@ -99,8 +99,8 @@ matrix:
|
||||
android:
|
||||
components:
|
||||
- tools
|
||||
- build-tools-28.0.3
|
||||
- android-28
|
||||
- build-tools-29.0.3
|
||||
- android-29
|
||||
install:
|
||||
- echo y | sdkmanager "ndk-bundle"
|
||||
before_script:
|
||||
|
@ -156,8 +156,8 @@ endif
|
||||
ifeq ($(TARGET), retroarch_3ds)
|
||||
OBJ += frontend/drivers/platform_ctr.o
|
||||
endif
|
||||
|
||||
# Git Version
|
||||
ifeq ($(HAVE_GIT_VERSION), 1)
|
||||
GIT_VERSION_CACHEDIR = $(if $(OBJDIR),$(OBJDIR),$(CURDIR))
|
||||
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)
|
||||
OBJ += version_git.o
|
||||
endif
|
||||
endif
|
||||
|
||||
# General object files
|
||||
ifeq ($(HAVE_DR_MP3), 1)
|
||||
@ -2260,6 +2261,7 @@ ifeq ($(HAVE_STATIC_VIDEO_FILTERS), 1)
|
||||
gfx/video_filters/normal2x.o \
|
||||
gfx/video_filters/normal2x_width.o \
|
||||
gfx/video_filters/normal2x_height.o \
|
||||
gfx/video_filters/normal4x.o \
|
||||
gfx/video_filters/scanline2x.o \
|
||||
gfx/video_filters/grid2x.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)
|
||||
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)
|
||||
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(
|
||||
alsa->pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0)
|
||||
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_hw_params_malloc(¶ms));
|
||||
TRY_ALSA(snd_pcm_hw_params_any(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;
|
||||
|
||||
TRY_ALSA(snd_pcm_hw_params_any(alsa->pcm, params));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_access(
|
||||
alsa->pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_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)
|
||||
{
|
||||
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();
|
||||
if (!system->library_name || !rcheevos_hardcore_active())
|
||||
return;
|
||||
@ -1610,29 +1611,36 @@ void rcheevos_validate_config_settings(void)
|
||||
|
||||
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 allowed = 1;
|
||||
size_t key_len;
|
||||
const char *key = NULL;
|
||||
const char *val = NULL;
|
||||
const rc_disallowed_setting_t
|
||||
*disallowed_setting = core_filter->disallowed_settings;
|
||||
int allowed = 1;
|
||||
|
||||
for (; disallowed_setting->setting; ++disallowed_setting)
|
||||
{
|
||||
key = disallowed_setting->setting;
|
||||
key_len = strlen(key);
|
||||
size_t key_len;
|
||||
key = disallowed_setting->setting;
|
||||
key_len = strlen(key);
|
||||
|
||||
if (key[key_len - 1] == '*')
|
||||
{
|
||||
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);
|
||||
if (rcheevos_match_value(val, disallowed_setting->value))
|
||||
const char* val =core_option_manager_get_val(coreopts, i);
|
||||
if (val)
|
||||
{
|
||||
key = coreopts->opts[i].key;
|
||||
allowed = 0;
|
||||
break;
|
||||
if (rcheevos_match_value(
|
||||
val, disallowed_setting->value))
|
||||
{
|
||||
key = coreopts->opts[i].key;
|
||||
allowed = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -196,6 +196,7 @@ enum event_command
|
||||
CMD_EVENT_OSK_TOGGLE,
|
||||
CMD_EVENT_RECORDING_TOGGLE,
|
||||
CMD_EVENT_STREAMING_TOGGLE,
|
||||
CMD_EVENT_RUNAHEAD_TOGGLE,
|
||||
CMD_EVENT_AI_SERVICE_TOGGLE,
|
||||
CMD_EVENT_BSV_RECORDING_TOGGLE,
|
||||
CMD_EVENT_SHADER_NEXT,
|
||||
|
@ -1146,7 +1146,11 @@ static const int default_content_favorites_size = 200;
|
||||
|
||||
/* Default scale factor for non-frambuffer-based display
|
||||
* drivers and display widgets */
|
||||
#if defined(VITA)
|
||||
#define DEFAULT_MENU_SCALE_FACTOR 1.5f
|
||||
#else
|
||||
#define DEFAULT_MENU_SCALE_FACTOR 1.0f
|
||||
#endif
|
||||
/* Specifies whether display widgets should be scaled
|
||||
* automatically using the default menu scale factor */
|
||||
#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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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 maxAmount;
|
||||
int64_t current;
|
||||
int fails;
|
||||
std::mt19937_64 randGenerator;
|
||||
std::uniform_real_distribution<> randDistribution;
|
||||
|
||||
double rand01() { return randDistribution(randGenerator); }
|
||||
|
||||
Backoff(int64_t min, int64_t max)
|
||||
: minAmount(min)
|
||||
, maxAmount(max)
|
||||
, current(min)
|
||||
, fails(0)
|
||||
, randGenerator((uint64_t)time(0))
|
||||
{
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
fails = 0;
|
||||
current = minAmount;
|
||||
}
|
||||
|
||||
int64_t nextDelay()
|
||||
{
|
||||
++fails;
|
||||
int64_t delay = (int64_t)((double)current * 2.0 * rand01());
|
||||
int64_t delay = (int64_t)((double)current * 2.0 *
|
||||
randDistribution(randGenerator));
|
||||
current = std::min(current + delay, maxAmount);
|
||||
return current;
|
||||
}
|
||||
|
192
deps/discord-rpc/src/discord_rpc.cpp
vendored
192
deps/discord-rpc/src/discord_rpc.cpp
vendored
@ -10,22 +10,10 @@
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
|
||||
#ifndef DISCORD_DISABLE_IO_THREAD
|
||||
#include <condition_variable>
|
||||
#include <thread>
|
||||
#endif
|
||||
|
||||
struct QueuedMessage
|
||||
{
|
||||
size_t length;
|
||||
char buffer[16384];
|
||||
|
||||
void Copy(const QueuedMessage& other)
|
||||
{
|
||||
length = other.length;
|
||||
if (length)
|
||||
memcpy(buffer, other.buffer, length);
|
||||
}
|
||||
};
|
||||
|
||||
struct User
|
||||
@ -80,66 +68,13 @@ static User connectedUser;
|
||||
static Backoff ReconnectTimeMs(500, 60 * 1000);
|
||||
static auto NextConnect = std::chrono::system_clock::now();
|
||||
|
||||
#ifndef DISCORD_DISABLE_IO_THREAD
|
||||
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)
|
||||
static void update_reconnect_time(void)
|
||||
{
|
||||
NextConnect = std::chrono::system_clock::now() +
|
||||
std::chrono::duration<int64_t, std::milli>{ReconnectTimeMs.nextDelay()};
|
||||
}
|
||||
|
||||
#ifdef DISCORD_DISABLE_IO_THREAD
|
||||
extern "C" void Discord_UpdateConnection(void)
|
||||
#else
|
||||
static void Discord_UpdateConnection(void)
|
||||
#endif
|
||||
{
|
||||
if (!Connection)
|
||||
return;
|
||||
@ -148,7 +83,7 @@ static void Discord_UpdateConnection(void)
|
||||
{
|
||||
if (std::chrono::system_clock::now() >= NextConnect)
|
||||
{
|
||||
UpdateReconnectTime();
|
||||
update_reconnect_time();
|
||||
Connection->Open();
|
||||
}
|
||||
}
|
||||
@ -268,16 +203,19 @@ static void Discord_UpdateConnection(void)
|
||||
if (QueuedPresence.length)
|
||||
{
|
||||
QueuedMessage local;
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(PresenceMutex);
|
||||
local.Copy(QueuedPresence);
|
||||
QueuedPresence.length = 0;
|
||||
}
|
||||
std::lock_guard<std::mutex> guard(PresenceMutex);
|
||||
local.length = QueuedPresence.length;
|
||||
if (local.length)
|
||||
memcpy(local.buffer, QueuedPresence.buffer, local.length);
|
||||
QueuedPresence.length = 0;
|
||||
|
||||
if (!Connection->Write(local.buffer, local.length))
|
||||
{
|
||||
/* if we fail to send, requeue */
|
||||
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 =
|
||||
JsonWriteSubscribeCommand(qmessage->buffer, sizeof(qmessage->buffer), Nonce++, evtName);
|
||||
SendQueue.CommitAdd();
|
||||
if (IoThread)
|
||||
IoThread->Notify();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -313,8 +249,6 @@ static bool DeregisterForEvent(const char* evtName)
|
||||
qmessage->length =
|
||||
JsonWriteUnsubscribeCommand(qmessage->buffer, sizeof(qmessage->buffer), Nonce++, evtName);
|
||||
SendQueue.CommitAdd();
|
||||
if (IoThread)
|
||||
IoThread->Notify();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -326,10 +260,6 @@ extern "C" void Discord_Initialize(
|
||||
int autoRegister,
|
||||
const char* optionalSteamId)
|
||||
{
|
||||
IoThread = new (std::nothrow) IoThreadHolder();
|
||||
if (!IoThread)
|
||||
return;
|
||||
|
||||
if (autoRegister)
|
||||
{
|
||||
if (optionalSteamId && optionalSteamId[0])
|
||||
@ -354,34 +284,38 @@ extern "C" void Discord_Initialize(
|
||||
if (Connection)
|
||||
return;
|
||||
|
||||
Connection = RpcConnection::Create(applicationId);
|
||||
Connection = RpcConnection::Create(applicationId);
|
||||
Connection->onConnect = [](JsonDocument& readyMessage)
|
||||
{
|
||||
Discord_UpdateHandlers(&QueuedHandlers);
|
||||
char *userId = NULL;
|
||||
char *username = NULL;
|
||||
char *avatar = 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();)
|
||||
{
|
||||
if (r.depth == 1)
|
||||
{
|
||||
in_data = !strcmp(r.key,"data");
|
||||
in_user = false;
|
||||
}
|
||||
else if (r.depth == 2 && in_data)
|
||||
{
|
||||
in_user = !strcmp(r.key, "user");
|
||||
}
|
||||
else if (r.depth == 3 && in_user)
|
||||
{
|
||||
if (!strcmp(r.key, "id" )) r.NextStrDup(&userId);
|
||||
else if (!strcmp(r.key, "username" )) r.NextStrDup(&username);
|
||||
else if (!strcmp(r.key, "avatar" )) r.NextStrDup(&avatar);
|
||||
else if (!strcmp(r.key, "discriminator")) r.NextStrDup(&discriminator);
|
||||
}
|
||||
if (r.depth == 1)
|
||||
{
|
||||
in_data = !strcmp(r.key,"data");
|
||||
in_user = false;
|
||||
}
|
||||
else if (r.depth == 2 && in_data)
|
||||
in_user = !strcmp(r.key, "user");
|
||||
else if (r.depth == 3 && in_user)
|
||||
{
|
||||
if (!strcmp(r.key, "id" ))
|
||||
r.NextStrDup(&userId);
|
||||
else if (!strcmp(r.key, "username" ))
|
||||
r.NextStrDup(&username);
|
||||
else if (!strcmp(r.key, "avatar" ))
|
||||
r.NextStrDup(&avatar);
|
||||
else if (!strcmp(r.key, "discriminator"))
|
||||
r.NextStrDup(&discriminator);
|
||||
}
|
||||
}
|
||||
|
||||
if (userId && username)
|
||||
@ -398,10 +332,14 @@ extern "C" void Discord_Initialize(
|
||||
WasJustConnected.exchange(true);
|
||||
ReconnectTimeMs.reset();
|
||||
|
||||
if (userId ) free(userId );
|
||||
if (username ) free(username );
|
||||
if (avatar ) free(avatar );
|
||||
if (discriminator) free(discriminator);
|
||||
if (userId)
|
||||
free(userId);
|
||||
if (username)
|
||||
free(username);
|
||||
if (avatar)
|
||||
free(avatar);
|
||||
if (discriminator)
|
||||
free(discriminator);
|
||||
};
|
||||
Connection->onDisconnect = [](int err, const char* message)
|
||||
{
|
||||
@ -412,10 +350,8 @@ extern "C" void Discord_Initialize(
|
||||
Handlers = {};
|
||||
}
|
||||
WasJustDisconnected.exchange(true);
|
||||
UpdateReconnectTime();
|
||||
update_reconnect_time();
|
||||
};
|
||||
|
||||
IoThread->Start();
|
||||
}
|
||||
|
||||
extern "C" void Discord_Shutdown(void)
|
||||
@ -424,26 +360,17 @@ extern "C" void Discord_Shutdown(void)
|
||||
return;
|
||||
Connection->onConnect = nullptr;
|
||||
Connection->onDisconnect = nullptr;
|
||||
Handlers = {};
|
||||
if (IoThread)
|
||||
{
|
||||
IoThread->Stop();
|
||||
delete IoThread;
|
||||
IoThread = nullptr;
|
||||
}
|
||||
Handlers = {};
|
||||
|
||||
RpcConnection::Destroy(Connection);
|
||||
}
|
||||
|
||||
extern "C" void Discord_UpdatePresence(const DiscordRichPresence* presence)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(PresenceMutex);
|
||||
QueuedPresence.length = JsonWriteRichPresenceObj(
|
||||
QueuedPresence.buffer, sizeof(QueuedPresence.buffer), Nonce++, Pid, presence);
|
||||
}
|
||||
if (IoThread)
|
||||
IoThread->Notify();
|
||||
std::lock_guard<std::mutex> guard(PresenceMutex);
|
||||
QueuedPresence.length = JsonWriteRichPresenceObj(
|
||||
QueuedPresence.buffer, sizeof(QueuedPresence.buffer),
|
||||
Nonce++, Pid, presence);
|
||||
}
|
||||
|
||||
extern "C" void Discord_ClearPresence(void)
|
||||
@ -451,7 +378,8 @@ extern "C" void Discord_ClearPresence(void)
|
||||
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 (!Connection || !Connection->IsOpen())
|
||||
@ -462,8 +390,6 @@ extern "C" void Discord_Respond(const char* userId, /* DISCORD_REPLY_ */ int rep
|
||||
qmessage->length =
|
||||
JsonWriteJoinReply(qmessage->buffer, sizeof(qmessage->buffer), userId, reply, Nonce++);
|
||||
SendQueue.CommitAdd();
|
||||
if (IoThread)
|
||||
IoThread->Notify();
|
||||
}
|
||||
}
|
||||
|
||||
@ -530,16 +456,14 @@ extern "C" void Discord_RunCallbacks(void)
|
||||
*/
|
||||
while (JoinAskQueue.HavePendingSends())
|
||||
{
|
||||
auto req = JoinAskQueue.GetNextSendMessage();
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(HandlerMutex);
|
||||
if (Handlers.joinRequest)
|
||||
{
|
||||
DiscordUser du{req->userId, req->username, req->discriminator, req->avatar};
|
||||
Handlers.joinRequest(&du);
|
||||
}
|
||||
}
|
||||
JoinAskQueue.CommitSend();
|
||||
auto req = JoinAskQueue.GetNextSendMessage();
|
||||
std::lock_guard<std::mutex> guard(HandlerMutex);
|
||||
if (Handlers.joinRequest)
|
||||
{
|
||||
DiscordUser du{req->userId, req->username, req->discriminator, req->avatar};
|
||||
Handlers.joinRequest(&du);
|
||||
}
|
||||
JoinAskQueue.CommitSend();
|
||||
}
|
||||
|
||||
if (!isConnected)
|
||||
|
@ -324,6 +324,7 @@ static void frontend_psp_exec(const char *path, bool should_load_game)
|
||||
#endif
|
||||
char argp[512] = {0};
|
||||
SceSize args = 0;
|
||||
int ret;
|
||||
|
||||
#if !defined(VITA)
|
||||
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);
|
||||
if (strstr(boot_params,"psgm:play"))
|
||||
{
|
||||
int ret;
|
||||
char *param1 = strstr(boot_params, "¶m=")+7;
|
||||
char *param1 = strstr(boot_params, "¶m=");
|
||||
char *param2 = strstr(boot_params, "¶m2=");
|
||||
memcpy(core_name, param1, param2 - param1);
|
||||
core_name[param2-param1] = 0;
|
||||
sprintf(argp, param2 + 8);
|
||||
ret = sceAppMgrLoadExec(core_name, (char * const*)((const char*[]){argp, 0}), NULL);
|
||||
RARCH_LOG("Attempt to load executable: [%d].\n", ret);
|
||||
if (param1 != NULL && param2 != NULL)
|
||||
{
|
||||
param1 += 7;
|
||||
memcpy(core_name, param1, param2 - param1);
|
||||
core_name[param2-param1] = 0;
|
||||
sprintf(argp, param2 + 8);
|
||||
ret = sceAppMgrLoadExec(core_name, (char * const*)((const char*[]){argp, 0}), NULL);
|
||||
RARCH_LOG("Attempt to load executable: [%d].\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
RARCH_LOG("Required boot params missing. Continue nornal boot.");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
int ret = sceAppMgrLoadExec(path, args == 0 ? NULL : (char * const*)((const char*[]){argp, 0}), NULL);
|
||||
RARCH_LOG("Attempt to load executable: [%d].\n", ret);
|
||||
}
|
||||
ret = sceAppMgrLoadExec(path, args == 0 ? NULL : (char * const*)((const char*[]){argp, 0}), NULL);
|
||||
RARCH_LOG("Attempt to load executable: [%d].\n", ret);
|
||||
exit:
|
||||
return;
|
||||
#else
|
||||
exitspawn_kernel(path, args, argp);
|
||||
#endif
|
||||
|
@ -1054,6 +1054,13 @@ static LRESULT CALLBACK wnd_proc_common_dinput_internal(HWND hwnd,
|
||||
keysym |= 0x80;
|
||||
|
||||
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,
|
||||
0, mod, RETRO_DEVICE_KEYBOARD);
|
||||
|
@ -600,8 +600,10 @@ bool slang_reflect(
|
||||
}
|
||||
else if (index == SLANG_INVALID_TEXTURE_SEMANTIC)
|
||||
{
|
||||
RARCH_ERR("[slang]: Non-semantic textures not supported yet, "
|
||||
"Probably a texture name or pass alias is not found. \n");
|
||||
RARCH_ERR("[slang]: Texture name '%s' not found in semantic map, "
|
||||
"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;
|
||||
}
|
||||
|
||||
|
@ -802,22 +802,30 @@ static bool font_init_first(
|
||||
* Neutral :
|
||||
* 0020 - 002F : 001xxxxx (c & 0xE0) == 0x20
|
||||
* Arabic:
|
||||
* 0600 - 07FF : 11011xxx (c & 0xF8) == 0xD8 (2 bytes)
|
||||
* 0800 - 08FF : 11100000 101000xx c == 0xE0 && (c1 & 0xAC) == 0xA0 (3 bytes) */
|
||||
* 0600 - 06FF : 110110xx (c & 0xFC) == 0xD8 (2 bytes) */
|
||||
|
||||
/* clang-format off */
|
||||
#define IS_ASCII(p) ((*(p)&0x80) == 0x00)
|
||||
#define IS_MBSTART(p) ((*(p)&0xC0) == 0xC0)
|
||||
#define IS_MBCONT(p) ((*(p)&0xC0) == 0x80)
|
||||
#define IS_DIR_NEUTRAL(p) ((*(p)&0xE0) == 0x20)
|
||||
#define IS_ARABIC0(p) ((*(p)&0xF8) == 0xD8)
|
||||
#define IS_ARABIC1(p) ((*(p) == 0xE0) && ((*((p) + 1) & 0xAC) == 0xA0))
|
||||
#define IS_ARABIC(p) (IS_ARABIC0(p) || IS_ARABIC1(p))
|
||||
#define IS_ARABIC(p) ((*(p)&0xFC) == 0xD8)
|
||||
#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 */
|
||||
static const unsigned arabic_shape_map[0x50 - 0x20][0x4] = {
|
||||
{ 0 }, /* 0x0620 */
|
||||
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 */
|
||||
{ 0xFE80 },
|
||||
{ 0xFE81, 0xFE82 },
|
||||
{ 0xFE83, 0xFE84 },
|
||||
@ -843,99 +851,189 @@ static const unsigned arabic_shape_map[0x50 - 0x20][0x4] = {
|
||||
{ 0xFEB9, 0xFEBA, 0xFEBB, 0xFEBC },
|
||||
{ 0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0 },
|
||||
{ 0xFEC1, 0xFEC2, 0xFEC3, 0xFEC4 },
|
||||
{ 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8 },
|
||||
|
||||
{ 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8 },
|
||||
{ 0xFEC9, 0xFECA, 0xFECB, 0xFECC },
|
||||
{ 0xFECD, 0xFECE, 0xFECF, 0xFED0 },
|
||||
{ 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 },
|
||||
{ 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC },
|
||||
{ 0xFEDD, 0xFEDE, 0xFEDF, 0xFEE0 },
|
||||
{ 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4 },
|
||||
{ 0xFEE5, 0xFEE6, 0xFEE7, 0xFEE8 },
|
||||
{ 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC },
|
||||
{ 0xFEED, 0xFEEE },
|
||||
|
||||
{ 0xFEED, 0xFEEE },
|
||||
{ 0xFEEF, 0xFEF0, 0xFBE8, 0xFBE9 },
|
||||
{ 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 */
|
||||
|
||||
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;
|
||||
bool prev_connected = false;
|
||||
bool next_connected = false;
|
||||
unsigned char id = ((unsigned char)src[0] << 6) | ((unsigned char)src[1] & 0x3F);
|
||||
const char* prev1 = src - 2;
|
||||
const char* prev2 = src - 4;
|
||||
unsigned char id = GET_ID_ARABIC(src);
|
||||
const char* prev = src - 2;
|
||||
const char* next = src + 2;
|
||||
|
||||
if (id < 0x21 || id > 0x4A)
|
||||
return 0;
|
||||
|
||||
if (prev2 < start)
|
||||
if ((prev >= start) && IS_ARABIC(prev))
|
||||
{
|
||||
prev2 = NULL;
|
||||
if (prev1 < start)
|
||||
prev1 = NULL;
|
||||
}
|
||||
unsigned char prev_id = GET_ID_ARABIC(prev);
|
||||
|
||||
if (prev1 && (*prev1 & 0xFC) == 0xD8)
|
||||
{
|
||||
unsigned char prev1_id = 0;
|
||||
/* 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_id = ((unsigned char)prev1[0] << 6) | ((unsigned char)prev1[1] & 0x3F);
|
||||
|
||||
if (prev1_id == 0x44)
|
||||
if (prev_id == 0x44) /* Arabic Letter Lam */
|
||||
{
|
||||
unsigned char prev2_id = 0;
|
||||
const char* prev2 = prev - 2;
|
||||
|
||||
if (prev2)
|
||||
if (prev2 >= start)
|
||||
prev2_id = (prev2[0] << 6) | (prev2[1] & 0x3F);
|
||||
|
||||
if (prev2_id > 0x20 || prev2_id < 0x50)
|
||||
prev_connected = !!arabic_shape_map[prev2_id - 0x20][2];
|
||||
/* nonspacing diacritics 0x4b -- 0x5f */
|
||||
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)
|
||||
{
|
||||
case 0x22:
|
||||
case 0x22: /* Arabic Letter Alef with Madda Above */
|
||||
return 0xFEF5 + prev_connected;
|
||||
case 0x23:
|
||||
case 0x23: /* Arabic Letter Alef with Hamza Above */
|
||||
return 0xFEF7 + prev_connected;
|
||||
case 0x25:
|
||||
case 0x25: /* Arabic Letter Alef with Hamza Below */
|
||||
return 0xFEF9 + prev_connected;
|
||||
case 0x27:
|
||||
case 0x27: /* Arabic Letter Alef */
|
||||
return 0xFEFB + prev_connected;
|
||||
}
|
||||
}
|
||||
if (prev1_id > 0x20 || prev1_id < 0x50)
|
||||
prev_connected = !!arabic_shape_map[prev1_id - 0x20][2];
|
||||
prev_connected = !!arabic_shape_map[prev_id][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)
|
||||
next_connected = true;
|
||||
/* nonspacing diacritics 0x4b -- 0x5f */
|
||||
while (next_id > 0x4A && next_id < 0x60)
|
||||
{
|
||||
next += 2;
|
||||
if (IS_ARABIC(next))
|
||||
next_id = GET_ID_ARABIC(next);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
next_connected = !!arabic_shape_map[next_id][1];
|
||||
}
|
||||
|
||||
result = arabic_shape_map[id - 0x20][prev_connected | (next_connected << 1)];
|
||||
result = arabic_shape_map[id][prev_connected | (next_connected << 1)];
|
||||
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
return arabic_shape_map[id - 0x20][prev_connected];
|
||||
return arabic_shape_map[id][prev_connected];
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -961,22 +1059,17 @@ static char* font_driver_reshape_msg(const char* msg, unsigned char *buffer, siz
|
||||
if (reverse)
|
||||
{
|
||||
src--;
|
||||
while (IS_MBCONT(src))
|
||||
{
|
||||
while (src > (const unsigned char*)msg && IS_MBCONT(src))
|
||||
src--;
|
||||
|
||||
if (src == (const unsigned char*)msg)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (IS_RTL(src) || IS_DIR_NEUTRAL(src))
|
||||
if (src >= (const unsigned char*)msg && (IS_RTL(src) || IS_DIR_NEUTRAL(src)))
|
||||
{
|
||||
unsigned replacement = font_get_replacement((const char*)src, msg);
|
||||
if (replacement)
|
||||
{
|
||||
if (replacement < 0x80)
|
||||
*dst++ = replacement;
|
||||
else if (replacement < 0x8000)
|
||||
else if (replacement < 0x800)
|
||||
{
|
||||
*dst++ = 0xC0 | (replacement >> 6);
|
||||
*dst++ = 0x80 | (replacement & 0x3F);
|
||||
@ -1030,7 +1123,7 @@ static char* font_driver_reshape_msg(const char* msg, unsigned char *buffer, siz
|
||||
*dst++ = *src++;
|
||||
}
|
||||
}
|
||||
end:
|
||||
|
||||
*dst = '\0';
|
||||
|
||||
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_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 *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 *grid2x_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_width_get_implementation,
|
||||
normal2x_height_get_implementation,
|
||||
normal4x_get_implementation,
|
||||
scanline2x_get_implementation,
|
||||
grid2x_get_implementation,
|
||||
grid3x_get_implementation,
|
||||
|
@ -70,7 +70,7 @@ endif
|
||||
objects += blargg_ntsc_snes.$(DYLIB) phosphor2x.$(DYLIB) epx.$(DYLIB) lq2x.$(DYLIB) \
|
||||
2xsai.$(DYLIB) super2xsai.$(DYLIB) supereagle.$(DYLIB) 2xbr.$(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) \
|
||||
gameboy3x.$(DYLIB) gameboy4x.$(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
|
||||
|
||||
#ifndef GFX_MAX_PARAMETERS
|
||||
#define GFX_MAX_PARAMETERS 256
|
||||
#define GFX_MAX_PARAMETERS 512
|
||||
#endif
|
||||
|
||||
#ifndef GFX_MAX_FRAME_HISTORY
|
||||
|
@ -1003,6 +1003,7 @@ FILTERS
|
||||
#include "../gfx/video_filters/normal2x.c"
|
||||
#include "../gfx/video_filters/normal2x_width.c"
|
||||
#include "../gfx/video_filters/normal2x_height.c"
|
||||
#include "../gfx/video_filters/normal4x.c"
|
||||
#include "../gfx/video_filters/scanline2x.c"
|
||||
#include "../gfx/video_filters/grid2x.c"
|
||||
#include "../gfx/video_filters/grid3x.c"
|
||||
|
@ -81,6 +81,7 @@ struct dinput_input
|
||||
int mouse_x;
|
||||
int mouse_y;
|
||||
uint8_t state[256];
|
||||
bool shift_l, shift_r, alt_l;
|
||||
bool doubleclick_on_titlebar;
|
||||
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_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);
|
||||
}
|
||||
|
||||
@ -181,6 +182,50 @@ static void *dinput_init(const char *joypad_driver)
|
||||
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)
|
||||
{
|
||||
struct dinput_input *di = (struct dinput_input*)data;
|
||||
@ -211,6 +256,12 @@ static void dinput_poll(void *data)
|
||||
*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)
|
||||
|
@ -117,6 +117,7 @@ enum
|
||||
|
||||
RARCH_RECORDING_TOGGLE,
|
||||
RARCH_STREAMING_TOGGLE,
|
||||
RARCH_RUNAHEAD_TOGGLE,
|
||||
|
||||
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,
|
||||
"Toggle between recording and not.");
|
||||
break;
|
||||
case RARCH_RUNAHEAD_TOGGLE:
|
||||
snprintf(s, len,
|
||||
"Toggles Run-Ahead mode on/off.");
|
||||
break;
|
||||
default:
|
||||
if (string_is_empty(s))
|
||||
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,
|
||||
"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(
|
||||
MENU_ENUM_LABEL_VALUE_INPUT_META_AI_SERVICE,
|
||||
"AI Service"
|
||||
@ -11276,6 +11284,18 @@ MSG_HASH(
|
||||
MSG_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_RUNAHEAD_CORE_DOES_NOT_SUPPORT_SAVESTATES,
|
||||
"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)
|
||||
{
|
||||
/* An entry corresponding to 'key' already exists
|
||||
* > Check if it's read only */
|
||||
if (entry->readonly)
|
||||
return;
|
||||
|
||||
/* Check whether value is currently set */
|
||||
* > Check whether value is currently set */
|
||||
if (entry->value)
|
||||
{
|
||||
/* Do nothing if value is unchanged */
|
||||
@ -1120,9 +1116,12 @@ void config_set_string(config_file_t *conf, const char *key, const char *val)
|
||||
free(entry->value);
|
||||
}
|
||||
|
||||
/* Update value */
|
||||
entry->value = strdup(val);
|
||||
conf->modified = true;
|
||||
/* Update value
|
||||
* > Note that once a value is set, it
|
||||
* is no longer considered 'read only' */
|
||||
entry->value = strdup(val);
|
||||
entry->readonly = false;
|
||||
conf->modified = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1296,18 +1295,10 @@ void config_file_dump_orbis(config_file_t *conf, int fd)
|
||||
{
|
||||
struct config_entry_list *list = NULL;
|
||||
struct config_include_list *includes = conf->includes;
|
||||
|
||||
|
||||
if (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(
|
||||
(struct config_entry_list*)conf->entries,
|
||||
@ -1325,6 +1316,21 @@ void config_file_dump_orbis(config_file_t *conf, int fd)
|
||||
}
|
||||
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
|
||||
|
||||
@ -1336,12 +1342,6 @@ void config_file_dump(config_file_t *conf, FILE *file, bool sort)
|
||||
if (conf->reference)
|
||||
fprintf(file, "#reference \"%s\"\n", conf->reference);
|
||||
|
||||
while (includes)
|
||||
{
|
||||
fprintf(file, "#include \"%s\"\n", includes->path);
|
||||
includes = includes->next;
|
||||
}
|
||||
|
||||
if (sort)
|
||||
list = config_file_merge_sort_linked_list(
|
||||
(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);
|
||||
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)
|
||||
|
@ -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)
|
||||
{
|
||||
int scan;
|
||||
uint32_t *addr = NULL;
|
||||
uint32_t *addr = NULL;
|
||||
lzma_allocator *codec = (lzma_allocator *)(p);
|
||||
uintptr_t vaddr = 0;
|
||||
|
||||
/* compute the size, rounding to the nearest 1k */
|
||||
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 */
|
||||
*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 */
|
||||
addr = (uint32_t *)malloc(sizeof(uint32_t) * size + sizeof(uintptr_t));
|
||||
if (!addr)
|
||||
addr = (uint32_t *)malloc(size + sizeof(uint32_t) + LZMA_MIN_ALIGNMENT_BYTES);
|
||||
if (addr==NULL)
|
||||
return NULL;
|
||||
|
||||
for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
|
||||
{
|
||||
if (codec->allocptr[scan] == NULL)
|
||||
{
|
||||
/* store block address */
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* set the low bit of the size so we don't match next time */
|
||||
*addr = (uint32_t)(size | 1);
|
||||
return addr + (sizeof(uint32_t) == sizeof(uintptr_t) ? 1 : 2);
|
||||
*addr = size | 1;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
int scan;
|
||||
uint32_t *ptr;
|
||||
lzma_allocator *codec;
|
||||
uint32_t *ptr = NULL;
|
||||
lzma_allocator *codec = NULL;
|
||||
|
||||
if (address == NULL)
|
||||
return;
|
||||
|
||||
codec = (lzma_allocator *)(p);
|
||||
|
||||
/* find the hunk */
|
||||
ptr = (uint32_t *)(address) - 1;
|
||||
ptr = (uint32_t *)address;
|
||||
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 */
|
||||
*ptr &= ~1;
|
||||
*codec->allocptr[scan] &= ~1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -241,9 +241,14 @@ chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t comple
|
||||
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)
|
||||
{
|
||||
zlib_allocator *alloc = (zlib_allocator *)opaque;
|
||||
uintptr_t paddr = 0;
|
||||
UINT32 *ptr;
|
||||
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 */
|
||||
*ptr |= 1;
|
||||
return ptr + 1;
|
||||
|
||||
/* return aligned block address */
|
||||
return (voidpf)(alloc->allocptr2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* alloc a new one */
|
||||
ptr = (UINT32 *)malloc(size + sizeof(uintptr_t));
|
||||
ptr = (UINT32 *)malloc(size + sizeof(UINT32) + ZLIB_MIN_ALIGNMENT_BYTES);
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
|
||||
@ -272,12 +279,16 @@ voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
|
||||
if (!alloc->allocptr[i])
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/* set the low bit of the size so we don't match next time */
|
||||
*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)
|
||||
{
|
||||
zlib_allocator *alloc = (zlib_allocator *)opaque;
|
||||
UINT32 *ptr = (UINT32 *)address - (sizeof(uint32_t) == sizeof(uintptr_t) ? 1 : 2);
|
||||
UINT32 *ptr = (UINT32 *)address;
|
||||
int i;
|
||||
|
||||
/* find the hunk */
|
||||
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 */
|
||||
*ptr &= ~1;
|
||||
*(alloc->allocptr[i]) &= ~1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -143,16 +143,6 @@ rxml_document_t *rxml_load_document_string(const char *str)
|
||||
if (!doc)
|
||||
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);
|
||||
|
||||
for (; *str; ++str)
|
||||
@ -256,30 +246,14 @@ rxml_document_t *rxml_load_document_string(const char *str)
|
||||
|
||||
case YXML_ATTRSTART:
|
||||
if (attr)
|
||||
{
|
||||
struct rxml_attrib_node
|
||||
*new_node = (struct rxml_attrib_node*)
|
||||
calloc(1, sizeof(*attr));
|
||||
attr = new_node;
|
||||
attr->next = new_node ;
|
||||
}
|
||||
attr = attr->next = (struct rxml_attrib_node*)
|
||||
calloc(1, sizeof(*attr));
|
||||
else
|
||||
{
|
||||
struct rxml_attrib_node
|
||||
*new_node = (struct rxml_attrib_node*)
|
||||
calloc(1, sizeof(*attr));
|
||||
attr = new_node;
|
||||
|
||||
if (node)
|
||||
node->attrib = new_node;
|
||||
}
|
||||
attr = node->attrib = (struct rxml_attrib_node*)calloc(1, sizeof(*attr));
|
||||
|
||||
if (attr)
|
||||
{
|
||||
if (attr->attrib)
|
||||
free(attr->attrib);
|
||||
attr->attrib = strdup(x.attr);
|
||||
}
|
||||
if (attr->attrib)
|
||||
free(attr->attrib);
|
||||
attr->attrib = strdup(x.attr);
|
||||
|
||||
valptr = buf->val;
|
||||
break;
|
||||
|
@ -27,6 +27,7 @@ typedef struct _zlib_allocator zlib_allocator;
|
||||
struct _zlib_allocator
|
||||
{
|
||||
UINT32 * allocptr[MAX_ZLIB_ALLOCS];
|
||||
UINT32 * allocptr2[MAX_ZLIB_ALLOCS];
|
||||
};
|
||||
|
||||
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 (*FreeSz)(void *p, void *address, size_t size); /* address can be 0 */
|
||||
uint32_t* allocptr[MAX_LZMA_ALLOCS];
|
||||
uint32_t* allocptr2[MAX_LZMA_ALLOCS];
|
||||
};
|
||||
|
||||
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_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_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_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)
|
||||
@ -1694,6 +1695,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
case RARCH_STREAMING_TOGGLE:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_streaming_toggle);
|
||||
return 0;
|
||||
case RARCH_RUNAHEAD_TOGGLE:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_runahead_toggle);
|
||||
return 0;
|
||||
case RARCH_AI_SERVICE:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_ai_service);
|
||||
return 0;
|
||||
|
@ -459,6 +459,9 @@ enum msg_hash_enums
|
||||
MSG_GAME_REMAP_FILE_LOADED,
|
||||
MSG_DIRECTORY_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_FAILED_TO_SAVE_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_RECORDING_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_MENU_TOGGLE,
|
||||
|
||||
@ -903,6 +907,7 @@ enum msg_hash_enums
|
||||
MENU_ENUM_SUBLABEL_INPUT_META_UI_COMPANION_TOGGLE,
|
||||
MENU_ENUM_SUBLABEL_INPUT_META_RECORDING_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_MENU_TOGGLE,
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
android:isGame="true"
|
||||
android:banner="@drawable/banner"
|
||||
android:extractNativeLibs="true"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
tools:ignore="UnusedAttribute">
|
||||
<activity android:name="com.retroarch.browser.mainmenu.MainMenuActivity" android:exported="true" android:launchMode="singleInstance">
|
||||
<intent-filter>
|
||||
|
@ -25,8 +25,8 @@ allprojects {
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
buildToolsVersion "28.0.3"
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion "29.0.3"
|
||||
|
||||
flavorDimensions "variant"
|
||||
|
||||
@ -37,7 +37,7 @@ android {
|
||||
arguments "-j${Runtime.runtime.availableProcessors()}"
|
||||
}
|
||||
}
|
||||
targetSdkVersion 28
|
||||
targetSdkVersion 29
|
||||
}
|
||||
|
||||
productFlavors {
|
||||
|
@ -1,10 +1,10 @@
|
||||
apply plugin: 'com.android.dynamic-feature'
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
compileSdkVersion 29
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 28
|
||||
targetSdkVersion 29
|
||||
}
|
||||
|
||||
flavorDimensions "variant"
|
||||
|
@ -85,6 +85,8 @@ HAVE_VIVANTE_FBDEV=no # Vivante fbdev context support
|
||||
HAVE_OPENDINGUX_FBDEV=no # Opendingux fbdev context support
|
||||
HAVE_OPENGLES=no # Use GLESv2 instead of desktop GL
|
||||
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_XRANDR=auto # Xrandr support.
|
||||
HAVE_OMAP=no # OMAP video support
|
||||
@ -187,3 +189,4 @@ C89_METAL=no
|
||||
HAVE_NETWORK_VIDEO=no
|
||||
HAVE_STEAM=no # Enable Steam build
|
||||
HAVE_ODROIDGO2=no # ODROID-GO Advance rotation support (requires librga)
|
||||
HAVE_GIT_VERSION=yes # Git version support
|
||||
|
118
retroarch.c
118
retroarch.c
@ -2730,6 +2730,7 @@ static const struct input_bind_map input_config_bind_map[RARCH_BIND_LIST_END_NUL
|
||||
#endif
|
||||
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, 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),
|
||||
};
|
||||
|
||||
@ -12982,6 +12983,7 @@ static const struct cmd_map map[] = {
|
||||
{ "MENU_TOGGLE", RARCH_MENU_TOGGLE },
|
||||
{ "RECORDING_TOGGLE", RARCH_RECORDING_TOGGLE },
|
||||
{ "STREAMING_TOGGLE", RARCH_STREAMING_TOGGLE },
|
||||
{ "RUNAHEAD_TOGGLE", RARCH_RUNAHEAD_TOGGLE },
|
||||
{ "MENU_UP", RETRO_DEVICE_ID_JOYPAD_UP },
|
||||
{ "MENU_DOWN", RETRO_DEVICE_ID_JOYPAD_DOWN },
|
||||
{ "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);
|
||||
}
|
||||
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:
|
||||
if (recording_is_enabled())
|
||||
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)
|
||||
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",
|
||||
major, minor);
|
||||
break;
|
||||
@ -24503,41 +24552,43 @@ static void input_driver_poll(void)
|
||||
{
|
||||
unsigned remap_button =
|
||||
settings->uints.input_keymapper_ids[i][j];
|
||||
bool remap_valid =
|
||||
remap_button != RETROK_UNKNOWN;
|
||||
if (remap_valid)
|
||||
{
|
||||
unsigned current_button_value =
|
||||
BIT256_GET_PTR(p_new_state, j);
|
||||
bool remap_valid =
|
||||
remap_button != RETROK_UNKNOWN &&
|
||||
!handle->keys[remap_button / 32];
|
||||
|
||||
if (!remap_valid)
|
||||
continue;
|
||||
|
||||
unsigned current_button_value =
|
||||
BIT256_GET_PTR(p_new_state, j);
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
if (poll_overlay && i == 0)
|
||||
{
|
||||
input_overlay_state_t *ol_state =
|
||||
overlay_pointer
|
||||
? &overlay_pointer->overlay_state
|
||||
: NULL;
|
||||
if (ol_state)
|
||||
current_button_value |=
|
||||
BIT256_GET(ol_state->buttons, j);
|
||||
}
|
||||
if (poll_overlay && i == 0)
|
||||
{
|
||||
input_overlay_state_t *ol_state =
|
||||
overlay_pointer
|
||||
? &overlay_pointer->overlay_state
|
||||
: NULL;
|
||||
if (ol_state)
|
||||
current_button_value |=
|
||||
BIT256_GET(ol_state->buttons, j);
|
||||
}
|
||||
#endif
|
||||
if ((current_button_value == 1)
|
||||
&& (j != remap_button))
|
||||
{
|
||||
MAPPER_SET_KEY (handle,
|
||||
remap_button);
|
||||
input_keyboard_event(true,
|
||||
remap_button,
|
||||
0, 0, RETRO_DEVICE_KEYBOARD);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Release keyboard event*/
|
||||
input_keyboard_event(false,
|
||||
if ((current_button_value == 1)
|
||||
&& (j != remap_button))
|
||||
{
|
||||
MAPPER_SET_KEY (handle,
|
||||
remap_button);
|
||||
input_keyboard_event(true,
|
||||
remap_button,
|
||||
0, 0, RETRO_DEVICE_KEYBOARD);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Release keyboard event*/
|
||||
input_keyboard_event(false,
|
||||
remap_button,
|
||||
0, 0, RETRO_DEVICE_KEYBOARD);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -39679,12 +39730,15 @@ static enum runloop_state runloop_check_state(
|
||||
/* Check if we have pressed the recording toggle button */
|
||||
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 */
|
||||
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))
|
||||
command_event(CMD_EVENT_VOLUME_UP, NULL);
|
||||
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
|
||||
)
|
||||
{
|
||||
char db_crc[PATH_MAX_LENGTH];
|
||||
char db_playlist_base_str[PATH_MAX_LENGTH];
|
||||
char db_playlist_path[PATH_MAX_LENGTH];
|
||||
char entry_path_str[PATH_MAX_LENGTH];
|
||||
/* TODO/FIXME - heap allocations are done here to avoid
|
||||
* running out of stack space on systems with a limited stack size.
|
||||
* We should use less fullsize paths in the future so that we don't
|
||||
* 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;
|
||||
playlist_t *playlist = NULL;
|
||||
const char *db_path =
|
||||
@ -727,25 +732,25 @@ static int database_info_list_iterate_found_match(
|
||||
entry_path_str[0] = '\0';
|
||||
|
||||
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))
|
||||
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 = 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)
|
||||
strlcpy(entry_path_str, entry_path, sizeof(entry_path_str));
|
||||
strlcpy(entry_path_str, entry_path, str_len);
|
||||
|
||||
if (!string_is_empty(archive_name))
|
||||
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(
|
||||
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;
|
||||
}
|
||||
|
||||
free(db_crc);
|
||||
free(db_playlist_base_str);
|
||||
free(db_playlist_path);
|
||||
free(entry_path_str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -860,7 +860,11 @@ static void task_load_handler(retro_task_t *task)
|
||||
{
|
||||
if (state->autoload)
|
||||
{
|
||||
#ifdef __CELLOS_LV2__
|
||||
char *msg = (char*)malloc(8192 * sizeof(char));
|
||||
#else
|
||||
char msg[8192];
|
||||
#endif
|
||||
|
||||
msg[0] = '\0';
|
||||
|
||||
@ -871,6 +875,9 @@ static void task_load_handler(retro_task_t *task)
|
||||
state->path,
|
||||
msg_hash_to_str(MSG_FAILED));
|
||||
task_set_error(task, strdup(msg));
|
||||
#ifdef __CELLOS_LV2__
|
||||
free(msg);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
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;
|
||||
QHash<QString, QString> hash;
|
||||
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_display_name"] = core->display_name;
|
||||
@ -278,8 +278,7 @@ const QStringList PlaylistEntryDialog::getSelectedExtensions()
|
||||
|
||||
/* Otherwise it would create a QStringList with a single blank entry... */
|
||||
if (!text.isEmpty())
|
||||
list = text.split(' ');
|
||||
|
||||
list = string_split_to_qt(text, ' ');
|
||||
return list;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <QButtonGroup>
|
||||
|
||||
#include "settingswidgets.h"
|
||||
#include "../ui_qt.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
@ -442,7 +443,7 @@ StringComboBox::StringComboBox(rarch_setting_t *setting, QWidget *parent) :
|
||||
,m_setting(setting)
|
||||
,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&)));
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "ui_qt_load_core_window.h"
|
||||
#include "../ui_qt.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QDesktopWidget>
|
||||
@ -235,8 +236,7 @@ void LoadCoreWindow::initCoreList(const QStringList &extensionFilters)
|
||||
name_item = new QTableWidgetItem(name);
|
||||
|
||||
hash["path"] = core->path;
|
||||
hash["extensions"] = QString(
|
||||
core->supported_extensions).split("|");
|
||||
hash["extensions"] = string_split_to_qt(QString(core->supported_extensions), '|');
|
||||
|
||||
name_item->setData(Qt::UserRole, hash);
|
||||
name_item->setFlags(name_item->flags() & ~Qt::ItemIsEditable);
|
||||
|
@ -764,3 +764,26 @@ ui_companion_driver_t ui_companion_qt = {
|
||||
&ui_application_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;
|
||||
} ui_window_qt_t;
|
||||
|
||||
QStringList string_split_to_qt(QString str, char delim);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user