Merge remote-tracking branch 'origin/libretro' into net-rollback

This commit is contained in:
Flyinghead 2021-09-07 15:02:39 +02:00
commit a4c14ebef7
8 changed files with 123 additions and 70 deletions

View File

@ -38,6 +38,12 @@ maple_device::~maple_device()
delete config;
}
static inline void mutualExclusion(u32& keycode, u32 mask)
{
if ((keycode & mask) == 0)
keycode |= mask;
}
/*
Sega Dreamcast Controller
No error checking of any kind, but works just fine
@ -53,7 +59,10 @@ struct maple_sega_controller: maple_base
return 0xfe060f00; // 4 analog axes (0-3) X Y A B Start U D L R
}
virtual u32 transform_kcode(u32 kcode) {
virtual u32 transform_kcode(u32 kcode)
{
mutualExclusion(kcode, DC_DPAD_UP | DC_DPAD_DOWN);
mutualExclusion(kcode, DC_DPAD_LEFT | DC_DPAD_RIGHT);
return kcode | 0xF901; // mask off DPad2, C, D and Z;
}
@ -189,7 +198,10 @@ struct maple_atomiswave_controller: maple_sega_controller
return 0xff663f00; // 6 analog axes, X Y L2/D2(?) A B C Start U D L R
}
u32 transform_kcode(u32 kcode) override {
u32 transform_kcode(u32 kcode) override
{
mutualExclusion(kcode, AWAVE_UP_KEY | AWAVE_DOWN_KEY);
mutualExclusion(kcode, AWAVE_LEFT_KEY | AWAVE_RIGHT_KEY);
return kcode | AWAVE_TRIGGER_KEY;
}
@ -215,7 +227,12 @@ struct maple_sega_twinstick: maple_sega_controller
return 0xfefe0000; // no analog axes, X Y A B D Start U/D/L/R U2/D2/L2/R2
}
u32 transform_kcode(u32 kcode) override {
u32 transform_kcode(u32 kcode) override
{
mutualExclusion(kcode, DC_DPAD_UP | DC_DPAD_DOWN);
mutualExclusion(kcode, DC_DPAD_LEFT | DC_DPAD_RIGHT);
mutualExclusion(kcode, DC_DPAD2_UP | DC_DPAD2_DOWN);
mutualExclusion(kcode, DC_DPAD2_LEFT | DC_DPAD2_RIGHT);
return kcode | 0x0101;
}
@ -247,7 +264,10 @@ struct maple_ascii_stick: maple_sega_controller
return 0xff070000; // no analog axes, X Y Z A B C Start U/D/L/R
}
u32 transform_kcode(u32 kcode) override {
u32 transform_kcode(u32 kcode) override
{
mutualExclusion(kcode, DC_DPAD_UP | DC_DPAD_DOWN);
mutualExclusion(kcode, DC_DPAD_LEFT | DC_DPAD_RIGHT);
return kcode | 0xF800;
}
@ -1214,7 +1234,10 @@ struct maple_mouse : maple_base
struct maple_lightgun : maple_base
{
virtual u32 transform_kcode(u32 kcode) {
virtual u32 transform_kcode(u32 kcode)
{
mutualExclusion(kcode, DC_DPAD_UP | DC_DPAD_DOWN);
mutualExclusion(kcode, DC_DPAD_LEFT | DC_DPAD_RIGHT);
if ((kcode & DC_BTN_RELOAD) == 0)
kcode &= ~DC_BTN_A; // trigger
return kcode | 0xFF01;
@ -1311,6 +1334,8 @@ struct maple_lightgun : maple_base
struct atomiswave_lightgun : maple_lightgun
{
u32 transform_kcode(u32 kcode) override {
mutualExclusion(kcode, AWAVE_UP_KEY | AWAVE_DOWN_KEY);
mutualExclusion(kcode, AWAVE_LEFT_KEY | AWAVE_RIGHT_KEY);
// No need for reload on AW
return (kcode & AWAVE_TRIGGER_KEY) == 0 ? ~AWAVE_BTN0_KEY : ~0;
}

View File

@ -1424,6 +1424,13 @@ u32 jvs_io_board::handle_jvs_message(u8 *buffer_in, u32 length_in, u8 *buffer_ou
if ((maple_kcode[p] & (1 << i)) == 0)
buttons[p] |= naomi_button_mapping[i];
#endif
for (u32& button : buttons)
{
if ((button & (NAOMI_UP_KEY | NAOMI_DOWN_KEY)) == (NAOMI_UP_KEY | NAOMI_DOWN_KEY))
button &= ~(NAOMI_UP_KEY | NAOMI_DOWN_KEY);
if ((button & (NAOMI_LEFT_KEY | NAOMI_RIGHT_KEY)) == (NAOMI_LEFT_KEY | NAOMI_RIGHT_KEY))
button &= ~(NAOMI_LEFT_KEY | NAOMI_RIGHT_KEY);
}
JVS_STATUS1(); // status
for (u32 cmdi = 0; cmdi < length_in; )

View File

@ -68,43 +68,7 @@ bool GamepadDevice::gamepad_btn_input(u32 code, bool pressed)
if (key <= DC_BTN_RELOAD)
{
if (pressed)
{
kcode[port] &= ~key;
// Avoid two opposite dpad keys being pressed simultaneously
switch (key)
{
case DC_DPAD_UP:
kcode[port] |= DC_DPAD_DOWN;
break;
case DC_DPAD_DOWN:
kcode[port] |= DC_DPAD_UP;
break;
case DC_DPAD_LEFT:
kcode[port] |= DC_DPAD_RIGHT;
break;
case DC_DPAD_RIGHT:
kcode[port] |= DC_DPAD_LEFT;
break;
case DC_DPAD2_UP:
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
kcode[port] |= DC_DPAD2_DOWN;
break;
case DC_DPAD2_DOWN:
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
kcode[port] |= DC_DPAD2_UP;
break;
case DC_DPAD2_LEFT:
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
kcode[port] |= DC_DPAD2_RIGHT;
break;
case DC_DPAD2_RIGHT:
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
kcode[port] |= DC_DPAD2_LEFT;
break;
default:
break;
}
}
else
kcode[port] |= key;
#ifdef TEST_AUTOMATION
@ -135,16 +99,36 @@ bool GamepadDevice::gamepad_btn_input(u32 code, bool pressed)
rt[port] = pressed ? 255 : 0;
break;
case EMU_BTN_ANA_UP:
joyy[port] = pressed ? -128 : 0;
break;
case EMU_BTN_ANA_DOWN:
joyy[port] = pressed ? 127 : 0;
{
if (pressed)
digitalToAnalogState[port] |= key;
else
digitalToAnalogState[port] &= ~key;
const u32 upDown = digitalToAnalogState[port] & (EMU_BTN_ANA_UP | EMU_BTN_ANA_DOWN);
if (upDown == 0 || upDown == (EMU_BTN_ANA_UP | EMU_BTN_ANA_DOWN))
joyy[port] = 0;
else if (upDown == EMU_BTN_ANA_UP)
joyy[port] = -128;
else
joyy[port] = 127;
}
break;
case EMU_BTN_ANA_LEFT:
joyx[port] = pressed ? -128 : 0;
break;
case EMU_BTN_ANA_RIGHT:
joyx[port] = pressed ? 127 : 0;
{
if (pressed)
digitalToAnalogState[port] |= key;
else
digitalToAnalogState[port] &= ~key;
const u32 leftRight = digitalToAnalogState[port] & (EMU_BTN_ANA_LEFT | EMU_BTN_ANA_RIGHT);
if (leftRight == 0 || leftRight == (EMU_BTN_ANA_LEFT | EMU_BTN_ANA_RIGHT))
joyx[port] = 0;
else if (leftRight == EMU_BTN_ANA_LEFT)
joyx[port] = -128;
else
joyx[port] = 127;
}
break;
default:
return false;
@ -381,6 +365,8 @@ std::string GamepadDevice::make_mapping_filename(bool instance, int system)
bool GamepadDevice::find_mapping(int system)
{
if (!_remappable)
return true;
std::string mapping_file;
mapping_file = make_mapping_filename(false, system);
@ -399,6 +385,8 @@ bool GamepadDevice::find_mapping(int system)
bool GamepadDevice::find_mapping(const char *custom_mapping /* = nullptr */)
{
if (!_remappable)
return true;
std::string mapping_file;
if (custom_mapping != nullptr)
mapping_file = custom_mapping;

View File

@ -73,7 +73,8 @@ public:
bool find_mapping(int system);
protected:
GamepadDevice(int maple_port, const char *api_name, bool remappable = true)
: _api_name(api_name), _maple_port(maple_port), _input_detected(nullptr), _remappable(remappable)
: _api_name(api_name), _maple_port(maple_port), _input_detected(nullptr), _remappable(remappable),
digitalToAnalogState{}
{
}
@ -108,6 +109,7 @@ private:
double _detection_start_time = 0.0;
input_detected_cb _input_detected;
bool _remappable;
u32 digitalToAnalogState[4];
static std::vector<std::shared_ptr<GamepadDevice>> _gamepads;
static std::mutex _gamepads_mutex;

View File

@ -202,6 +202,7 @@ void D3DRenderer::Term()
{
preReset();
resetting = false;
devCache.reset();
shaders.term();
device.reset();
}

View File

@ -24,14 +24,15 @@
#include "sdl/sdl.h"
#endif
#include "hw/pvr/Renderer_if.h"
#include "emulator.h"
DXContext theDXContext;
extern int screen_width, screen_height; // FIXME
bool DXContext::Init()
bool DXContext::Init(bool keepCurrentWindow)
{
#ifdef USE_SDL
if (!sdl_recreate_window(0))
if (!keepCurrentWindow && !sdl_recreate_window(0))
return false;
#endif
@ -45,7 +46,10 @@ bool DXContext::Init()
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.EnableAutoDepthStencil = FALSE; // No need for depth/stencil buffer for the backbuffer
#ifndef TEST_AUTOMATION
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // Present with vsync
swapOnVSync = !settings.input.fastForwardMode && config::VSync;
d3dpp.PresentationInterval = swapOnVSync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
// TODO should be 0 in windowed mode
//d3dpp.FullScreen_RefreshRateInHz = swapOnVSync ? 60 : 0;
#else
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Present without vsync, maximum unthrottled framerate
#endif
@ -77,6 +81,28 @@ void DXContext::Present()
}
else if (FAILED(result))
WARN_LOG(RENDERER, "Present failed %x", result);
else
{
#ifndef TEST_AUTOMATION
if (swapOnVSync != (!settings.input.fastForwardMode && config::VSync))
{
DEBUG_LOG(RENDERER, "Switch vsync %d", !swapOnVSync);
if (renderer != nullptr)
{
renderer->Term();
delete renderer;
}
Term();
Init(true);
if (renderer != nullptr)
{
renderer = new D3DRenderer();
renderer->Init();
dc_resize_renderer();
}
}
#endif
}
}
void DXContext::EndImGuiFrame()

View File

@ -28,7 +28,7 @@
class DXContext
{
public:
bool Init();
bool Init(bool keepCurrentWindow = false);
void Term();
void EndImGuiFrame();
void Present();
@ -60,6 +60,7 @@ private:
bool overlayOnly = false;
HWND hWnd = nullptr;
D3DOverlay overlay;
bool swapOnVSync = false;
};
extern DXContext theDXContext;
#endif

View File

@ -217,29 +217,32 @@ void input_sdl_handle()
case SDL_KEYDOWN:
case SDL_KEYUP:
checkRawInput();
if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_RETURN && (event.key.keysym.mod & KMOD_ALT))
if (event.key.repeat == 0)
{
if (window_fullscreen)
if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_RETURN && (event.key.keysym.mod & KMOD_ALT))
{
SDL_SetWindowFullscreen(window, 0);
if (!gameRunning || !mouseCaptured)
SDL_ShowCursor(SDL_ENABLE);
if (window_fullscreen)
{
SDL_SetWindowFullscreen(window, 0);
if (!gameRunning || !mouseCaptured)
SDL_ShowCursor(SDL_ENABLE);
}
else
{
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
if (gameRunning)
SDL_ShowCursor(SDL_DISABLE);
}
window_fullscreen = !window_fullscreen;
}
else
else if (event.type == SDL_KEYDOWN && (event.key.keysym.mod & KMOD_LALT) && (event.key.keysym.mod & KMOD_LCTRL))
{
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
if (gameRunning)
SDL_ShowCursor(SDL_DISABLE);
captureMouse(!mouseCaptured);
}
else if (!config::UseRawInput)
{
sdl_keyboard->keyboard_input(event.key.keysym.scancode, event.type == SDL_KEYDOWN);
}
window_fullscreen = !window_fullscreen;
}
else if (event.type == SDL_KEYDOWN && (event.key.keysym.mod & KMOD_LALT) && (event.key.keysym.mod & KMOD_LCTRL))
{
captureMouse(!mouseCaptured);
}
else if (!config::UseRawInput)
{
sdl_keyboard->keyboard_input(event.key.keysym.scancode, event.type == SDL_KEYDOWN);
}
break;
case SDL_TEXTINPUT: