mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-22 23:49:50 +00:00
Preemptive Frames updates (#17003)
* Preemptive Frames: input_poll and input_state improvements - Check pointing devices when used by core; ignore input_libretro_device - Use stored mouse x,y input state (lower level call might flush deltas) - Remove port mapping code (unnecessary now) - Fewer memsets * Add Preemptive Frames to Qt options menu
This commit is contained in:
parent
7601df9a4c
commit
53081f1794
115
runahead.c
115
runahead.c
@ -1332,26 +1332,29 @@ force_input_dirty:
|
||||
static int16_t preempt_input_state(unsigned port,
|
||||
unsigned device, unsigned index, unsigned id)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
runloop_state_t *runloop_st = runloop_state_get_ptr();
|
||||
preempt_t *preempt = runloop_st->preempt_data;
|
||||
unsigned device_class = device & RETRO_DEVICE_MASK;
|
||||
unsigned *port_map = settings->uints.input_remap_port_map[port];
|
||||
uint8_t p;
|
||||
runloop_state_t *runloop_st = runloop_state_get_ptr();
|
||||
preempt_t *preempt = runloop_st->preempt_data;
|
||||
unsigned device_class = device & RETRO_DEVICE_MASK;
|
||||
|
||||
switch (device_class)
|
||||
{
|
||||
case RETRO_DEVICE_ANALOG:
|
||||
/* Add requested inputs to mask */
|
||||
while ((p = *(port_map++)) < MAX_USERS)
|
||||
preempt->analog_mask[p] |= (1 << (id + index * 2));
|
||||
preempt->analog_mask[port] |= (1 << (id + index * 2));
|
||||
break;
|
||||
case RETRO_DEVICE_LIGHTGUN:
|
||||
case RETRO_DEVICE_MOUSE:
|
||||
case RETRO_DEVICE_POINTER:
|
||||
/* Set pointing device for this port */
|
||||
while ((p = *(port_map++)) < MAX_USERS)
|
||||
preempt->ptr_dev[p] = device_class;
|
||||
preempt->ptr_dev_needed[port] = device_class;
|
||||
break;
|
||||
case RETRO_DEVICE_MOUSE:
|
||||
/* Set pointing device and return stored x,y */
|
||||
if (id <= RETRO_DEVICE_ID_MOUSE_Y)
|
||||
{
|
||||
preempt->ptr_dev_needed[port] = device_class;
|
||||
if (preempt->ptr_dev_polled[port] == device_class)
|
||||
return preempt->ptrdev_state[port][id];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1480,7 +1483,7 @@ error:
|
||||
}
|
||||
|
||||
static INLINE bool preempt_analog_input_dirty(preempt_t *preempt,
|
||||
retro_input_state_t state_cb, unsigned port, unsigned mapped_port)
|
||||
retro_input_state_t state_cb, unsigned port)
|
||||
{
|
||||
int16_t state[20] = {0};
|
||||
uint8_t base, i;
|
||||
@ -1490,17 +1493,20 @@ static INLINE bool preempt_analog_input_dirty(preempt_t *preempt,
|
||||
{
|
||||
base = i * 2;
|
||||
if (preempt->analog_mask[port] & (1 << (base )))
|
||||
state[base ] = state_cb(mapped_port, RETRO_DEVICE_ANALOG, i, 0);
|
||||
state[base ] = state_cb(port, RETRO_DEVICE_ANALOG, i, 0);
|
||||
if (preempt->analog_mask[port] & (1 << (base + 1)))
|
||||
state[base + 1] = state_cb(mapped_port, RETRO_DEVICE_ANALOG, i, 1);
|
||||
state[base + 1] = state_cb(port, RETRO_DEVICE_ANALOG, i, 1);
|
||||
}
|
||||
|
||||
/* buttons */
|
||||
for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++)
|
||||
if (preempt->analog_mask[port] & 0xfff0)
|
||||
{
|
||||
if (preempt->analog_mask[port] & (1 << (i + 4)))
|
||||
state[i + 4] = state_cb(mapped_port, RETRO_DEVICE_ANALOG,
|
||||
RETRO_DEVICE_INDEX_ANALOG_BUTTON, i);
|
||||
for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++)
|
||||
{
|
||||
if (preempt->analog_mask[port] & (1 << (i + 4)))
|
||||
state[i + 4] = state_cb(port, RETRO_DEVICE_ANALOG,
|
||||
RETRO_DEVICE_INDEX_ANALOG_BUTTON, i);
|
||||
}
|
||||
}
|
||||
|
||||
if (memcmp(preempt->analog_state[port], state, sizeof(state)) == 0)
|
||||
@ -1511,8 +1517,7 @@ static INLINE bool preempt_analog_input_dirty(preempt_t *preempt,
|
||||
}
|
||||
|
||||
static INLINE bool preempt_ptr_input_dirty(preempt_t *preempt,
|
||||
retro_input_state_t state_cb, unsigned device,
|
||||
unsigned port, unsigned mapped_port)
|
||||
retro_input_state_t state_cb, unsigned device, unsigned port)
|
||||
{
|
||||
int16_t state[4] = {0};
|
||||
unsigned count_id = 0;
|
||||
@ -1537,16 +1542,16 @@ static INLINE bool preempt_ptr_input_dirty(preempt_t *preempt,
|
||||
}
|
||||
|
||||
/* x, y */
|
||||
state[0] = state_cb(mapped_port, device, 0, x_id );
|
||||
state[1] = state_cb(mapped_port, device, 0, x_id + 1);
|
||||
state[0] = state_cb(port, device, 0, x_id );
|
||||
state[1] = state_cb(port, device, 0, x_id + 1);
|
||||
|
||||
/* buttons */
|
||||
for (id = 2; id <= max_id; id++)
|
||||
state[2] |= state_cb(mapped_port, device, 0, id) ? 1 << id : 0;
|
||||
state[2] |= state_cb(port, device, 0, id) ? 1 << id : 0;
|
||||
|
||||
/* ptr count */
|
||||
if (count_id)
|
||||
state[3] = state_cb(mapped_port, device, 0, count_id);
|
||||
state[3] = state_cb(port, device, 0, count_id);
|
||||
|
||||
if (memcmp(preempt->ptrdev_state[port], state, sizeof(state)) == 0)
|
||||
return false;
|
||||
@ -1560,52 +1565,42 @@ static INLINE void preempt_input_poll(preempt_t *preempt,
|
||||
{
|
||||
size_t p;
|
||||
int16_t joypad_state;
|
||||
retro_input_state_t state_cb = input_driver_state_wrapper;
|
||||
unsigned max_users = settings->uints.input_max_users;
|
||||
retro_input_state_t state_cb = input_driver_state_wrapper;
|
||||
unsigned max_users = settings->uints.input_max_users;
|
||||
|
||||
input_driver_poll();
|
||||
|
||||
/* Check for input state changes */
|
||||
for (p = 0; p < max_users; p++)
|
||||
{
|
||||
unsigned mapped_port = settings->uints.input_remap_ports[p];
|
||||
unsigned device = settings->uints.input_libretro_device[mapped_port]
|
||||
& RETRO_DEVICE_MASK;
|
||||
|
||||
switch (device)
|
||||
/* Check full digital joypad */
|
||||
joypad_state = state_cb(p, RETRO_DEVICE_JOYPAD,
|
||||
0, RETRO_DEVICE_ID_JOYPAD_MASK);
|
||||
if (joypad_state != preempt->joypad_state[p])
|
||||
{
|
||||
case RETRO_DEVICE_JOYPAD:
|
||||
case RETRO_DEVICE_ANALOG:
|
||||
/* Check full digital joypad */
|
||||
joypad_state = state_cb(mapped_port, RETRO_DEVICE_JOYPAD,
|
||||
0, RETRO_DEVICE_ID_JOYPAD_MASK);
|
||||
if (joypad_state != preempt->joypad_state[p])
|
||||
{
|
||||
preempt->joypad_state[p] = joypad_state;
|
||||
runloop_st->flags |= RUNLOOP_FLAG_INPUT_IS_DIRTY;
|
||||
}
|
||||
preempt->joypad_state[p] = joypad_state;
|
||||
runloop_st->flags |= RUNLOOP_FLAG_INPUT_IS_DIRTY;
|
||||
}
|
||||
|
||||
/* Check requested analogs */
|
||||
if ( preempt->analog_mask[p]
|
||||
&& preempt_analog_input_dirty(preempt, state_cb, (unsigned)p, mapped_port))
|
||||
runloop_st->flags |= RUNLOOP_FLAG_INPUT_IS_DIRTY;
|
||||
break;
|
||||
case RETRO_DEVICE_MOUSE:
|
||||
case RETRO_DEVICE_LIGHTGUN:
|
||||
case RETRO_DEVICE_POINTER:
|
||||
/* Check full device state */
|
||||
if (preempt_ptr_input_dirty(
|
||||
preempt, state_cb, preempt->ptr_dev[p], (unsigned)p, mapped_port))
|
||||
runloop_st->flags |= RUNLOOP_FLAG_INPUT_IS_DIRTY;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
/* Check requested analogs */
|
||||
if ( preempt->analog_mask[p]
|
||||
&& preempt_analog_input_dirty(preempt, state_cb, (unsigned)p))
|
||||
{
|
||||
runloop_st->flags |= RUNLOOP_FLAG_INPUT_IS_DIRTY;
|
||||
preempt->analog_mask[p] = 0;
|
||||
}
|
||||
|
||||
/* Check requested pointing device */
|
||||
if (preempt->ptr_dev_needed[p])
|
||||
{
|
||||
if (preempt_ptr_input_dirty(
|
||||
preempt, state_cb, preempt->ptr_dev_needed[p], (unsigned)p))
|
||||
runloop_st->flags |= RUNLOOP_FLAG_INPUT_IS_DIRTY;
|
||||
|
||||
preempt->ptr_dev_polled[p] = preempt->ptr_dev_needed[p];
|
||||
preempt->ptr_dev_needed[p] = RETRO_DEVICE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear requested inputs */
|
||||
memset(preempt->analog_mask, 0, max_users * sizeof(uint32_t));
|
||||
memset(preempt->ptr_dev, 0, max_users * sizeof(uint8_t));
|
||||
}
|
||||
|
||||
/* macro for preempt_run */
|
||||
|
@ -56,7 +56,9 @@ typedef struct preemptive_frames_data
|
||||
int16_t ptrdev_state[MAX_USERS][4];
|
||||
|
||||
/* Pointing device requested */
|
||||
uint8_t ptr_dev[MAX_USERS];
|
||||
uint8_t ptr_dev_needed[MAX_USERS];
|
||||
/* Device ID of ptrdev_state */
|
||||
uint8_t ptr_dev_polled[MAX_USERS];
|
||||
/* Buffer indexes for replays */
|
||||
uint8_t start_ptr;
|
||||
uint8_t replay_ptr;
|
||||
|
@ -385,9 +385,10 @@ LatencyPage::LatencyPage(QObject *parent) :
|
||||
|
||||
QWidget *LatencyPage::widget()
|
||||
{
|
||||
QWidget *widget = new QWidget;
|
||||
FormLayout *layout = new FormLayout;
|
||||
CheckableSettingsGroup *runAheadGpuSync = new CheckableSettingsGroup(MENU_ENUM_LABEL_RUN_AHEAD_ENABLED);
|
||||
QWidget *widget = new QWidget;
|
||||
FormLayout *layout = new FormLayout;
|
||||
CheckableSettingsGroup *runAheadGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_RUN_AHEAD_ENABLED);
|
||||
CheckableSettingsGroup *preemptGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_PREEMPT_ENABLE);
|
||||
|
||||
rarch_setting_t *hardSyncSetting = menu_setting_find_enum(MENU_ENUM_LABEL_VIDEO_HARD_SYNC);
|
||||
|
||||
@ -408,10 +409,14 @@ QWidget *LatencyPage::widget()
|
||||
layout->add(menu_setting_find_enum(MENU_ENUM_LABEL_AUDIO_LATENCY));
|
||||
layout->add(menu_setting_find_enum(MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR));
|
||||
|
||||
runAheadGpuSync->add(menu_setting_find_enum(MENU_ENUM_LABEL_RUN_AHEAD_FRAMES));
|
||||
runAheadGpuSync->add(menu_setting_find_enum(MENU_ENUM_LABEL_RUN_AHEAD_SECONDARY_INSTANCE));
|
||||
runAheadGpuSync->add(menu_setting_find_enum(MENU_ENUM_LABEL_RUN_AHEAD_HIDE_WARNINGS));
|
||||
layout->addRow(runAheadGpuSync);
|
||||
runAheadGroup->add(menu_setting_find_enum(MENU_ENUM_LABEL_RUN_AHEAD_FRAMES));
|
||||
runAheadGroup->add(menu_setting_find_enum(MENU_ENUM_LABEL_RUN_AHEAD_SECONDARY_INSTANCE));
|
||||
runAheadGroup->add(menu_setting_find_enum(MENU_ENUM_LABEL_RUN_AHEAD_HIDE_WARNINGS));
|
||||
layout->addRow(runAheadGroup);
|
||||
|
||||
preemptGroup->add(menu_setting_find_enum(MENU_ENUM_LABEL_PREEMPT_FRAMES));
|
||||
preemptGroup->add(menu_setting_find_enum(MENU_ENUM_LABEL_PREEMPT_HIDE_WARNINGS));
|
||||
layout->addRow(preemptGroup);
|
||||
|
||||
widget->setLayout(layout);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user