diff --git a/src/core/frontend/cursor.cpp b/src/core/frontend/cursor.cpp index 332f9d4c6..8eac37830 100644 --- a/src/core/frontend/cursor.cpp +++ b/src/core/frontend/cursor.cpp @@ -2,6 +2,7 @@ #include #include #include "common/logging/log.h" +#include "common/logging/types.h" #include "core\hle\service\hid\hid.h" @@ -9,10 +10,12 @@ void Cursor::update(){ if (emuWindow != nullptr){ stylusInput = Service::HID::Module::getStylusInputs(); modButtons = Service::HID::Module::getModButtons(); + setRotation(); if (deviceInUse == 0){ if (inMacro){ runMacro(); } else { + // LOG_INFO(Core, "Stylus X: {:.2f}, Stylus Y: {:.2f}, Stylus Mod: {}, Stylus Touch: {}", stylusInput[0], stylusInput[1], stylusInput[2], stylusInput[3]); // Reset the cursor position if macro was just played if (justFinishedMacro > 0){ justFinishedMacro = 0; @@ -47,7 +50,7 @@ void Cursor::update(){ int maxSpeed = 50; float multiplier = 0.5f * pow(4.0f, maxSpeed / 100.0f); // 0 is 0.5x speed, 100 is 2.0x speed. float heightSpeed = (240.0f / 33.0f) * multiplier; - bool stylusModPressed = stylusInput[3]; + bool stylusModPressed = stylusInput[2]; float responsecurve = 175.0f / 100.0f; float speedupratio = 400.0f / 100.0f; float joystickScaled[2] = {0.0f}; @@ -97,10 +100,10 @@ void Cursor::update(){ updateCursorPos(); // Handle stylus touch button presses - if (stylusInput[5]){ + if (stylusInput[3]){ touchScreen(); wasTouching = true; - } else if (wasTouching && !stylusInput[5]){ + } else if (wasTouching && !stylusInput[3]){ release(); wasTouching = false; } @@ -111,10 +114,10 @@ void Cursor::update(){ updateCursorPos(); // Handle stylus touch button presses - if (stylusInput[5]){ + if (stylusInput[3]){ touchScreen(); wasTouching = true; - } else if (wasTouching && !stylusInput[5]){ + } else if (wasTouching && !stylusInput[3]){ release(); wasTouching = false; } @@ -237,11 +240,12 @@ void Cursor::runMacro(){ } } -void Cursor::setRotation(int rot){ - rotation = rot; -} -void Cursor::setLayout(int lay){ - layout = lay; +void Cursor::setRotation(){ + if (emuWindow->GetFramebufferLayout().is_portrait){ + rotation = 3; + } else { + rotation = 0; + } } std::vector> Cursor::rotateVector(std::vector> input){ diff --git a/src/core/frontend/cursor.h b/src/core/frontend/cursor.h index 5dd50b979..6147944e3 100644 --- a/src/core/frontend/cursor.h +++ b/src/core/frontend/cursor.h @@ -15,8 +15,7 @@ public: void setRawCursorPos(float x, float y); void setDeviceInUse(int device); void setEmuWindow(Frontend::EmuWindow* emuWindow); - void setRotation(int rot); - void setLayout(int layout); + void setRotation(); int cursorPos[2]; float normStylusDirection[2]; bool cursorEnabled = true; @@ -29,7 +28,7 @@ private: void updateCursorPos(); bool wasTouching; std::array stylusInput; - std::array modButtons; + std::array modButtons; void circle(int direction); //0 is clockwise, 1 is counter clockwise void rub(); void runMacro(); @@ -43,7 +42,6 @@ private: int justFinishedMacro; std::array macroInitPos; int rotation; - int layout; int deviceInUse; //0 is Gamepad, 1 is Mouse/Tablet }; diff --git a/src/core/frontend/emu_window.cpp b/src/core/frontend/emu_window.cpp index 0ebfc46e8..5e8266ef5 100644 --- a/src/core/frontend/emu_window.cpp +++ b/src/core/frontend/emu_window.cpp @@ -193,12 +193,13 @@ bool EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { } bool EmuWindow::TouchDirectlyPressed(unsigned internal_x, unsigned internal_y) { + //This assumes 0, 0 is bottom left corner std::scoped_lock guard{touch_state->mutex}; std::clamp(internal_x, 0, 319); std::clamp(internal_y, 0, 239); touch_state->touch_pressed = true; - touch_state->touch_x = internal_x; - touch_state->touch_y = internal_y; + touch_state->touch_x = internal_x/319.0f; + touch_state->touch_y = (239-internal_y)/239.0f; return true; } void EmuWindow::TouchReleased() { diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 5aedda619..74f5258d1 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -30,8 +30,8 @@ SERVICE_CONSTRUCT_IMPL(Service::HID::Module) SERIALIZE_EXPORT_IMPL(Service::HID::Module) namespace Service::HID { -std::array Module::stylusInput = {0}; -std::array Module::modButtons = {0}; +std::array Module::stylusInput = {}; +std::array Module::modButtons = {}; template void Module::serialize(Archive& ar, const unsigned int file_version) { @@ -231,12 +231,11 @@ void Module::UpdatePadCallback(std::uintptr_t user_data, s64 cycles_late) { std::tie(c_stick_x_f, c_stick_y_f) = c_stick->GetStatus(); stylusInput[0] = c_stick_x_f; stylusInput[1] = c_stick_y_f; - stylusInput[2] = zl_button->GetStatus(); - stylusInput[3] = zr_button->GetStatus(); - for (int i = 0; i < 12; i++){ - modButtons[i] = buttons[i - BUTTON_HID_BEGIN]->GetStatus(); + stylusInput[2] = static_cast(zl_button->GetStatus()); + stylusInput[3] = static_cast(zr_button->GetStatus()); + for (int i = 0; i < 4; i++){ + modButtons[i] = zl_button->GetStatus() && buttons[i - BUTTON_HID_BEGIN]->GetStatus(); } - // Get current circle pad position and update circle pad direction float circle_pad_x_f, circle_pad_y_f; std::tie(circle_pad_x_f, circle_pad_y_f) = circle_pad->GetStatus(); @@ -344,7 +343,7 @@ std::array Module::getStylusInputs(){ return stylusInput; } -std::array Module::getModButtons(){ +std::array Module::getModButtons(){ return modButtons; } diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 53ef85741..363bb0350 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -336,7 +336,7 @@ public: void ReloadInputDevices(); static std::array getStylusInputs(); - static std::array getModButtons(); + static std::array getModButtons(); const PadState& GetState() const; // Updating period for each HID device. These empirical values are measured from a 11.2 3DS. @@ -398,7 +398,7 @@ private: std::unique_ptr touch_device; std::unique_ptr touch_btn_device; static std::array stylusInput; - static std::array modButtons; + static std::array modButtons; std::shared_ptr artic_controller; std::shared_ptr artic_client; diff --git a/src/video_core/host_shaders/opengl_present.frag b/src/video_core/host_shaders/opengl_present.frag index ef8610a34..fa996d37b 100644 --- a/src/video_core/host_shaders/opengl_present.frag +++ b/src/video_core/host_shaders/opengl_present.frag @@ -17,7 +17,7 @@ uniform int layer; in vec2 pixelUnit; void main() { vec4 pixel = texture(color_texture, frag_tex_coord); - vec2 rfrag_tex_coord = vec2(frag_tex_coord.y, 1.0 - frag_tex_coord.x); + vec2 rfrag_tex_coord = vec2(frag_tex_coord.y, frag_tex_coord.x); //Cursor if (cursor_enable){ //Black Outline diff --git a/src/video_core/host_shaders/vulkan_present.frag b/src/video_core/host_shaders/vulkan_present.frag index 54d61ea8d..2e412e5ce 100644 --- a/src/video_core/host_shaders/vulkan_present.frag +++ b/src/video_core/host_shaders/vulkan_present.frag @@ -40,7 +40,7 @@ vec4 GetScreen(int screen_id) { void main() { vec4 pixel = GetScreen(screen_id_l); - vec2 rfrag_tex_coord = vec2(frag_tex_coord.y, 1.0 - frag_tex_coord.x); + vec2 rfrag_tex_coord = vec2(frag_tex_coord.y, frag_tex_coord.x); //Cursor if (cursor_enable == 1){ //Black Outline diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index 5a737a37f..dcea9d62e 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h @@ -7,6 +7,8 @@ #include "common/common_types.h" #include "core/frontend/framebuffer_layout.h" #include "video_core/rasterizer_interface.h" +#include "core\frontend\cursor.h" +class Cursor; namespace Frontend { class EmuWindow; @@ -109,6 +111,7 @@ protected: RendererSettings settings; Frontend::EmuWindow& render_window; /// Reference to the render window handle. Frontend::EmuWindow* secondary_window; /// Reference to the secondary render window handle. + Cursor* vCursor; protected: f32 current_fps = 0.0f; /// Current framerate, should be set by the renderer diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index d0eaad708..324792f18 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -78,6 +78,8 @@ RendererOpenGL::RendererOpenGL(Core::System& system, Pica::PicaCore& pica_, rasterizer{system.Memory(), pica, system.CustomTexManager(), *this, driver}, frame_dumper{system, window} { const bool has_debug_tool = driver.HasDebugTool(); + vCursor = new Cursor(); + vCursor->setEmuWindow(&window); window.mailbox = std::make_unique(has_debug_tool); if (secondary_window) { secondary_window->mailbox = std::make_unique(has_debug_tool); @@ -235,6 +237,7 @@ void RendererOpenGL::RenderToMailbox(const Layout::FramebufferLayout& layout, state.draw.draw_framebuffer = frame->render.handle; state.Apply(); + vCursor->update(); DrawScreens(layout, flipped); // Create a fence for the frontend to wait on and swap this frame to OffTex frame->render_fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); @@ -568,7 +571,7 @@ void RendererOpenGL::DrawSingleScreen(const ScreenInfo& screen_info, float x, fl } else { glUniform1i(uniform_cursor_enable, 0); } - glUniform2f(uniform_cursor_pos, cursor_pos[0]/320.0f, cursor_pos[1]/240.0f); + glUniform2f(uniform_cursor_pos, vCursor->cursorPos[0]/320.0f, vCursor->cursorPos[1]/240.0f); state.texture_units[0].texture_2d = screen_info.display_texture; state.texture_units[0].sampler = sampler; state.Apply(); @@ -645,7 +648,7 @@ void RendererOpenGL::DrawSingleScreenStereo(const ScreenInfo& screen_info_l, } else { glUniform1i(uniform_cursor_enable, 0); } - glUniform2f(uniform_cursor_pos, cursor_pos[0]/320.0f, cursor_pos[1]/240.0f); + glUniform2f(uniform_cursor_pos, vCursor->cursorPos[0]/320.0f, vCursor->cursorPos[1]/240.0f); state.texture_units[0].texture_2d = screen_info_l.display_texture; state.texture_units[1].texture_2d = screen_info_r.display_texture; state.texture_units[0].sampler = sampler; @@ -706,8 +709,6 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f } glUniform1i(uniform_layer, 0); - cursor_pos[0] += 1; - cursor_pos[1] += 1; if (!Settings::values.swap_screen.GetValue()) { DrawTopScreen(layout, top_screen); glUniform1i(uniform_layer, 0); diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index a6c56072b..68f0c260d 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h @@ -114,7 +114,6 @@ private: GLuint attrib_position; GLuint attrib_tex_coord; int currScreenDraw; // 0 is Top, 1 is Bottom - std::array cursor_pos = {0,0}; FrameDumperOpenGL frame_dumper; }; diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 4233eed5e..85b1616cd 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -127,6 +127,8 @@ RendererVulkan::RendererVulkan(Core::System& system, Pica::PicaCore& pica_, update_queue, main_present_window.ImageCount()}, present_heap{instance, scheduler.GetMasterSemaphore(), PRESENT_BINDINGS, 32} { + vCursor = new Cursor(); + vCursor->setEmuWindow(&window); CompileShaders(); BuildLayouts(); BuildPipelines(); @@ -249,7 +251,7 @@ void RendererVulkan::RenderToWindow(PresentWindow& window, const Layout::Framebu clear_color.float32[1] = Settings::values.bg_green.GetValue(); clear_color.float32[2] = Settings::values.bg_blue.GetValue(); clear_color.float32[3] = 1.0f; - + vCursor->update(); DrawScreens(frame, layout, flipped); scheduler.Flush(frame->render_ready); @@ -793,7 +795,7 @@ void RendererVulkan::DrawSingleScreen(u32 screen_id, float x, float y, float w, } else { draw_info.cursor_enable = 0; } - draw_info.cursor_pos = Common::MakeVec(cursor_pos[0]/320.0f, cursor_pos[1]/240.0f); + draw_info.cursor_pos = Common::MakeVec(vCursor->cursorPos[0]/320.0f, vCursor->cursorPos[1]/240.0f); draw_info.screen_id_l = screen_id; scheduler.Record([this, offset = offset, info = draw_info](vk::CommandBuffer cmdbuf) { @@ -871,7 +873,7 @@ void RendererVulkan::DrawSingleScreenStereo(u32 screen_id_l, u32 screen_id_r, fl } else { draw_info.cursor_enable = 0; } - draw_info.cursor_pos = Common::MakeVec(cursor_pos[0]/320.0f, cursor_pos[1]/240.0f); + draw_info.cursor_pos = Common::MakeVec(vCursor->cursorPos[0]/320.0f, vCursor->cursorPos[1]/240.0f); draw_info.screen_id_l = screen_id_l; draw_info.screen_id_r = screen_id_r; @@ -1020,8 +1022,6 @@ void RendererVulkan::DrawScreens(Frame* frame, const Layout::FramebufferLayout& if (settings.shader_update_requested.exchange(false)) { ReloadPipeline(layout.render_3d_mode); } - cursor_pos[0] += 1; - cursor_pos[1] += 1; PrepareDraw(frame, layout); const auto& top_screen = layout.top_screen; diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index 481d76187..a5241df6b 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h @@ -6,6 +6,7 @@ #include "common/common_types.h" #include "common/math_util.h" +#include "core/frontend/cursor.h" #include "video_core/renderer_base.h" #ifdef HAVE_LIBRETRO #include "citra_libretro/libretro_vk.h" @@ -154,7 +155,6 @@ private: vk::Pipeline cursor_pipeline{}; vk::UniquePipelineLayout cursor_pipeline_layout{}; int currScreenDraw; // 0 is Top, 1 is Bottom - std::array cursor_pos = {0,0}; }; } // namespace Vulkan