diff --git a/src/core/gpu.cpp b/src/core/gpu.cpp index 8392249e2..56ac5dc9d 100644 --- a/src/core/gpu.cpp +++ b/src/core/gpu.cpp @@ -917,11 +917,21 @@ void GPU::UpdateCommandTickEvent() m_command_tick_event->SetIntervalAndSchedule(GPUTicksToSystemTicks(m_pending_command_ticks)); } -bool GPU::ConvertScreenCoordinatesToBeamTicksAndLines(s32 window_x, s32 window_y, u32* out_tick, u32* out_line) const +bool GPU::ConvertScreenCoordinatesToBeamTicksAndLines(s32 window_x, s32 window_y, float x_scale, u32* out_tick, + u32* out_line) const { - const auto [display_x, display_y] = m_host_display->ConvertWindowCoordinatesToDisplayCoordinates( + auto [display_x, display_y] = m_host_display->ConvertWindowCoordinatesToDisplayCoordinates( window_x, window_y, m_host_display->GetWindowWidth(), m_host_display->GetWindowHeight(), m_host_display->GetDisplayTopMargin()); + + if (x_scale != 1.0f) + { + const float dw = static_cast(m_crtc_state.display_width); + float scaled_x = ((static_cast(display_x) / dw) * 2.0f) - 1.0f; // 0..1 -> -1..1 + scaled_x *= x_scale; + display_x = static_cast(((scaled_x + 1.0f) * 0.5f) * dw); // -1..1 -> 0..1 + } + Log_DebugPrintf("win %d,%d -> disp %d,%d (size %u,%u frac %f,%f)", window_x, window_y, display_x, display_y, m_crtc_state.display_width, m_crtc_state.display_height, static_cast(display_x) / static_cast(m_crtc_state.display_width), diff --git a/src/core/gpu.h b/src/core/gpu.h index 12ff76b93..15f5f7cca 100644 --- a/src/core/gpu.h +++ b/src/core/gpu.h @@ -154,7 +154,8 @@ public: static std::unique_ptr CreateSoftwareRenderer(); // Converts window coordinates into horizontal ticks and scanlines. Returns false if out of range. Used for lightguns. - bool ConvertScreenCoordinatesToBeamTicksAndLines(s32 window_x, s32 window_y, u32* out_tick, u32* out_line) const; + bool ConvertScreenCoordinatesToBeamTicksAndLines(s32 window_x, s32 window_y, float x_scale, u32* out_tick, + u32* out_line) const; // Returns the video clock frequency. TickCount GetCRTCFrequency() const; diff --git a/src/core/namco_guncon.cpp b/src/core/namco_guncon.cpp index eda538f28..35edca366 100644 --- a/src/core/namco_guncon.cpp +++ b/src/core/namco_guncon.cpp @@ -177,7 +177,8 @@ void NamcoGunCon::UpdatePosition() // are we within the active display area? u32 tick, line; if (mouse_x < 0 || mouse_y < 0 || - !g_gpu->ConvertScreenCoordinatesToBeamTicksAndLines(mouse_x, mouse_y, &tick, &line) || m_shoot_offscreen) + !g_gpu->ConvertScreenCoordinatesToBeamTicksAndLines(mouse_x, mouse_y, m_x_scale, &tick, &line) || + m_shoot_offscreen) { Log_DebugPrintf("Lightgun out of range for window coordinates %d,%d", mouse_x, mouse_y); m_position_x = 0x01; @@ -241,11 +242,14 @@ u32 NamcoGunCon::StaticGetVibrationMotorCount() Controller::SettingList NamcoGunCon::StaticGetSettings() { - static constexpr std::array settings = { + static constexpr std::array settings = { {{SettingInfo::Type::Path, "CrosshairImagePath", TRANSLATABLE("NamcoGunCon", "Crosshair Image Path"), TRANSLATABLE("NamcoGunCon", "Path to an image to use as a crosshair/cursor.")}, {SettingInfo::Type::Float, "CrosshairScale", TRANSLATABLE("NamcoGunCon", "Crosshair Image Scale"), - TRANSLATABLE("NamcoGunCon", "Scale of crosshair image on screen."), "1.0", "0.0001", "100.0"}}}; + TRANSLATABLE("NamcoGunCon", "Scale of crosshair image on screen."), "1.0", "0.0001", "100.0"}, + {SettingInfo::Type::Float, "XScale", TRANSLATABLE("NamcoGunCon", "X Scale"), + TRANSLATABLE("NamcoGunCon", "Scales X coordinates relative to the center of the screen."), "1.0", "0.01", "2.0", + "0.01"}}}; return SettingList(settings.begin(), settings.end()); } @@ -272,6 +276,8 @@ void NamcoGunCon::LoadSettings(const char* section) } m_crosshair_image_scale = g_host_interface->GetFloatSettingValue(section, "CrosshairScale", 1.0f); + + m_x_scale = g_host_interface->GetFloatSettingValue(section, "XScale", 1.0f); } bool NamcoGunCon::GetSoftwareCursor(const Common::RGBA8Image** image, float* image_scale) diff --git a/src/core/namco_guncon.h b/src/core/namco_guncon.h index c813d969c..210996119 100644 --- a/src/core/namco_guncon.h +++ b/src/core/namco_guncon.h @@ -62,6 +62,7 @@ private: Common::RGBA8Image m_crosshair_image; std::string m_crosshair_image_path; float m_crosshair_image_scale = 1.0f; + float m_x_scale = 1.0f; // buttons are active low u16 m_button_state = UINT16_C(0xFFFF);