dx11: fix modifier volumes, rotation. sdl: on-screen keyboard support
dx11: Back face stencil ops need to be set dx11: Rotate CCW instead of CW dx11: Present with NO_WAIT when fast forwarding sdl: support for on-screen keyboard. Delay keys up by one frame to allow quick key presses. ui: better fix to wait for future on UWP
This commit is contained in:
parent
3d7455316f
commit
d071adea9a
|
@ -72,11 +72,11 @@ public:
|
|||
desc.DepthWriteMask = depthWrite ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
|
||||
desc.DepthFunc = Zfunction[depthFunc];
|
||||
desc.StencilEnable = stencil;
|
||||
desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
|
||||
desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
|
||||
desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
|
||||
desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
|
||||
desc.BackFace = desc.FrontFace;
|
||||
desc.StencilWriteMask = 0xFF;
|
||||
desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
|
||||
theDX11Context.getDevice()->CreateDepthStencilState(&desc, &state.get());
|
||||
}
|
||||
return state;
|
||||
|
|
|
@ -287,7 +287,7 @@ VertexOut main(in VertexIn vin)
|
|||
#if ROTATE == 0
|
||||
vo.pos = float4(vin.pos, 0.f, 1.f);
|
||||
#else
|
||||
vo.pos = float4(vin.pos.y, -vin.pos.x, 0.f, 1.f);
|
||||
vo.pos = float4(-vin.pos.y, vin.pos.x, 0.f, 1.f);
|
||||
#endif
|
||||
vo.uv = vin.uv;
|
||||
|
||||
|
|
|
@ -179,13 +179,13 @@ void DX11Context::Present()
|
|||
return;
|
||||
frameRendered = false;
|
||||
bool swapOnVSync = !settings.input.fastForwardMode && config::VSync;
|
||||
HRESULT hr = swapchain->Present(swapOnVSync ? 1 : 0, 0);
|
||||
HRESULT hr = swapchain->Present(swapOnVSync ? 1 : 0, !swapOnVSync ? DXGI_PRESENT_DO_NOT_WAIT : 0);
|
||||
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
|
||||
{
|
||||
WARN_LOG(RENDERER, "Present failed: device removed/reset");
|
||||
handleDeviceLost();
|
||||
}
|
||||
else if (FAILED(hr))
|
||||
else if (hr != DXGI_ERROR_WAS_STILL_DRAWING && FAILED(hr))
|
||||
WARN_LOG(RENDERER, "Present failed %x", hr);
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,8 @@ static bool error_msg_shown;
|
|||
static std::string osd_message;
|
||||
static double osd_message_end;
|
||||
static std::mutex osd_message_mutex;
|
||||
static void (*showOnScreenKeyboard)(bool show);
|
||||
static bool keysUpNextFrame[512];
|
||||
|
||||
static int map_system = 0;
|
||||
static void reset_vmus();
|
||||
|
@ -278,6 +280,11 @@ void gui_keyboard_key(u8 keyCode, bool pressed, u8 modifiers)
|
|||
if (!inited)
|
||||
return;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (!pressed && io.KeysDown[keyCode])
|
||||
{
|
||||
keysUpNextFrame[keyCode] = true;
|
||||
return;
|
||||
}
|
||||
io.KeyCtrl = (modifiers & (0x01 | 0x10)) != 0;
|
||||
io.KeyShift = (modifiers & (0x02 | 0x20)) != 0;
|
||||
io.KeysDown[keyCode] = pressed;
|
||||
|
@ -314,7 +321,7 @@ void gui_set_mouse_wheel(float delta)
|
|||
mouseWheel += delta;
|
||||
}
|
||||
|
||||
static void ImGui_Impl_NewFrame()
|
||||
static void gui_newFrame()
|
||||
{
|
||||
imguiDriver->newFrame();
|
||||
ImGui::GetIO().DisplaySize.x = settings.display.width;
|
||||
|
@ -367,6 +374,30 @@ static void ImGui_Impl_NewFrame()
|
|||
io.NavInputs[ImGuiNavInput_LStickDown] = 0.f;
|
||||
|
||||
ImGui::GetStyle().Colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.94f);
|
||||
|
||||
if (showOnScreenKeyboard != nullptr)
|
||||
showOnScreenKeyboard(io.WantTextInput);
|
||||
}
|
||||
|
||||
static void delayedKeysUp()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
for (int i = 0; i < ARRAY_SIZE(keysUpNextFrame); i++)
|
||||
if (keysUpNextFrame[i])
|
||||
io.KeysDown[i] = false;
|
||||
memset(keysUpNextFrame, 0, sizeof(keysUpNextFrame));
|
||||
}
|
||||
|
||||
static void gui_endFrame()
|
||||
{
|
||||
ImGui::Render();
|
||||
imguiDriver->renderDrawData(ImGui::GetDrawData());
|
||||
delayedKeysUp();
|
||||
}
|
||||
|
||||
void gui_setOnScreenKeyboardCallback(void (*callback)(bool show))
|
||||
{
|
||||
showOnScreenKeyboard = callback;
|
||||
}
|
||||
|
||||
void gui_set_insets(int left, int right, int top, int bottom)
|
||||
|
@ -2275,23 +2306,25 @@ static void gui_network_start()
|
|||
|
||||
if (networkStatus.wait_for(std::chrono::milliseconds(0)) == std::future_status::ready)
|
||||
{
|
||||
try {
|
||||
if (networkStatus.get())
|
||||
{
|
||||
gui_state = GuiState::Closed;
|
||||
ImGui::Text("Starting...");
|
||||
}
|
||||
else
|
||||
{
|
||||
gui_state = GuiState::Main;
|
||||
ImGui::Text("Starting...");
|
||||
gui_deAsync([] {
|
||||
try {
|
||||
if (networkStatus.get())
|
||||
{
|
||||
gui_state = GuiState::Closed;
|
||||
}
|
||||
else
|
||||
{
|
||||
emu.unloadGame();
|
||||
gui_state = GuiState::Main;
|
||||
}
|
||||
} catch (const FlycastException& e) {
|
||||
NetworkHandshake::instance->stop();
|
||||
emu.unloadGame();
|
||||
gui_error(e.what());
|
||||
gui_state = GuiState::Main;
|
||||
}
|
||||
} catch (const FlycastException& e) {
|
||||
NetworkHandshake::instance->stop();
|
||||
gui_state = GuiState::Main;
|
||||
emu.unloadGame();
|
||||
gui_error(e.what());
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2307,9 +2340,7 @@ static void gui_network_start()
|
|||
if (ImGui::Button("Cancel", ImVec2(100.f * scaling, 0.f)))
|
||||
{
|
||||
NetworkHandshake::instance->stop();
|
||||
#ifdef TARGET_UWP
|
||||
static std::future<void> f;
|
||||
f = std::async(std::launch::async, [] {
|
||||
gui_deAsync([] {
|
||||
try {
|
||||
networkStatus.get();
|
||||
}
|
||||
|
@ -2318,14 +2349,6 @@ static void gui_network_start()
|
|||
emu.unloadGame();
|
||||
gui_state = GuiState::Main;
|
||||
});
|
||||
#else
|
||||
try {
|
||||
networkStatus.get();
|
||||
} catch (const FlycastException& e) {
|
||||
}
|
||||
gui_state = GuiState::Main;
|
||||
emu.unloadGame();
|
||||
#endif
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
|
@ -2405,7 +2428,7 @@ void gui_display_ui()
|
|||
}
|
||||
}
|
||||
|
||||
ImGui_Impl_NewFrame();
|
||||
gui_newFrame();
|
||||
ImGui::NewFrame();
|
||||
error_msg_shown = false;
|
||||
|
||||
|
@ -2450,8 +2473,7 @@ void gui_display_ui()
|
|||
break;
|
||||
}
|
||||
error_popup();
|
||||
ImGui::Render();
|
||||
imguiDriver->renderDrawData(ImGui::GetDrawData());
|
||||
gui_endFrame();
|
||||
|
||||
if (gui_state == GuiState::Closed)
|
||||
emu.start();
|
||||
|
@ -2491,7 +2513,7 @@ void gui_display_osd()
|
|||
|
||||
// if (!message.empty() || config::FloatVMUs || crosshairsNeeded() || (ggpo::active() && config::NetworkStats))
|
||||
{
|
||||
ImGui_Impl_NewFrame();
|
||||
gui_newFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
if (!message.empty())
|
||||
|
@ -2518,8 +2540,7 @@ void gui_display_osd()
|
|||
}
|
||||
lua::overlay();
|
||||
|
||||
ImGui::Render();
|
||||
imguiDriver->renderDrawData(ImGui::GetDrawData());
|
||||
gui_endFrame();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ void gui_set_insets(int left, int right, int top, int bottom);
|
|||
void gui_stop_game(const std::string& message = "");
|
||||
void gui_start_game(const std::string& path);
|
||||
void gui_error(const std::string& what);
|
||||
void gui_setOnScreenKeyboardCallback(void (*callback)(bool show));
|
||||
|
||||
extern int screen_dpi;
|
||||
extern float scaling;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "imgui/imgui_internal.h"
|
||||
#include "gui.h"
|
||||
#include "emulator.h"
|
||||
#include "stdclass.h"
|
||||
|
||||
typedef bool (*StringCallback)(bool cancelled, std::string selection);
|
||||
|
||||
|
@ -66,6 +67,30 @@ static inline bool operator!=(const ImVec2& l, const ImVec2& r)
|
|||
void fullScreenWindow(bool modal);
|
||||
void windowDragScroll();
|
||||
|
||||
// UWP doesn't allow the UI thread to wait on a future
|
||||
template<typename F>
|
||||
void gui_deAsync(F f)
|
||||
{
|
||||
#ifdef TARGET_UWP
|
||||
static cResetEvent event;
|
||||
static std::future<void> future;
|
||||
|
||||
event.Reset();
|
||||
future = std::async(std::launch::async, [&f] {
|
||||
try {
|
||||
f();
|
||||
event.Set();
|
||||
} catch (...) {
|
||||
event.Set();
|
||||
throw;
|
||||
}
|
||||
});
|
||||
event.Wait();
|
||||
#else
|
||||
f();
|
||||
#endif
|
||||
}
|
||||
|
||||
class BackgroundGameLoader
|
||||
{
|
||||
public:
|
||||
|
@ -80,30 +105,13 @@ public:
|
|||
void cancel()
|
||||
{
|
||||
progress.cancelled = true;
|
||||
#ifdef TARGET_UWP
|
||||
if (future.valid())
|
||||
{
|
||||
if (progress.cancelled)
|
||||
return;
|
||||
static std::future<void> f;
|
||||
f = std::async(std::launch::async, [this] {
|
||||
gui_deAsync([this] {
|
||||
if (future.valid())
|
||||
try {
|
||||
future.get();
|
||||
} catch (const FlycastException& e) {
|
||||
}
|
||||
catch (const FlycastException& e) {
|
||||
}
|
||||
emu.unloadGame();
|
||||
gui_state = GuiState::Main;
|
||||
});
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (future.valid())
|
||||
try {
|
||||
future.get();
|
||||
} catch (const FlycastException& e) {
|
||||
}
|
||||
#endif
|
||||
});
|
||||
emu.unloadGame();
|
||||
gui_state = GuiState::Main;
|
||||
}
|
||||
|
@ -114,7 +122,9 @@ public:
|
|||
return true;
|
||||
if (future.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
|
||||
{
|
||||
future.get();
|
||||
gui_deAsync([this] {
|
||||
future.get();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -195,6 +195,22 @@ void input_sdl_init()
|
|||
for (int joy = 0; joy < 4; joy++)
|
||||
sdl_open_joystick(joy);
|
||||
#endif
|
||||
if (SDL_HasScreenKeyboardSupport())
|
||||
{
|
||||
NOTICE_LOG(INPUT, "On-screen keyboard supported");
|
||||
gui_setOnScreenKeyboardCallback([](bool show) {
|
||||
// We should be able to use SDL_IsScreenKeyboardShown() but it doesn't seem to work on Xbox
|
||||
static bool visible;
|
||||
if (window != nullptr && visible != show)
|
||||
{
|
||||
visible = show;
|
||||
if (show)
|
||||
SDL_StartTextInput();
|
||||
else
|
||||
SDL_StopTextInput();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
inline void SDLMouse::setAbsPos(int x, int y) {
|
||||
|
@ -248,9 +264,11 @@ void input_sdl_handle()
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_TEXTINPUT:
|
||||
gui_keyboard_inputUTF8(event.text.text);
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED
|
||||
|| event.window.event == SDL_WINDOWEVENT_RESTORED
|
||||
|
|
Loading…
Reference in New Issue