NamcoGuncon: Add an option to scale X coordinates

Fixes what appears to be curvature correction at the edges of the
screen.
This commit is contained in:
Connor McLaughlin 2020-12-19 14:22:59 +10:00
parent fad3d79895
commit 4860313bef
4 changed files with 24 additions and 6 deletions

View File

@ -917,11 +917,21 @@ void GPU::UpdateCommandTickEvent()
m_command_tick_event->SetIntervalAndSchedule(GPUTicksToSystemTicks(m_pending_command_ticks)); 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(), window_x, window_y, m_host_display->GetWindowWidth(), m_host_display->GetWindowHeight(),
m_host_display->GetDisplayTopMargin()); m_host_display->GetDisplayTopMargin());
if (x_scale != 1.0f)
{
const float dw = static_cast<float>(m_crtc_state.display_width);
float scaled_x = ((static_cast<float>(display_x) / dw) * 2.0f) - 1.0f; // 0..1 -> -1..1
scaled_x *= x_scale;
display_x = static_cast<s32>(((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, 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, m_crtc_state.display_width, m_crtc_state.display_height,
static_cast<float>(display_x) / static_cast<float>(m_crtc_state.display_width), static_cast<float>(display_x) / static_cast<float>(m_crtc_state.display_width),

View File

@ -154,7 +154,8 @@ public:
static std::unique_ptr<GPU> CreateSoftwareRenderer(); static std::unique_ptr<GPU> CreateSoftwareRenderer();
// Converts window coordinates into horizontal ticks and scanlines. Returns false if out of range. Used for lightguns. // 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. // Returns the video clock frequency.
TickCount GetCRTCFrequency() const; TickCount GetCRTCFrequency() const;

View File

@ -177,7 +177,8 @@ void NamcoGunCon::UpdatePosition()
// are we within the active display area? // are we within the active display area?
u32 tick, line; u32 tick, line;
if (mouse_x < 0 || mouse_y < 0 || 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); Log_DebugPrintf("Lightgun out of range for window coordinates %d,%d", mouse_x, mouse_y);
m_position_x = 0x01; m_position_x = 0x01;
@ -241,11 +242,14 @@ u32 NamcoGunCon::StaticGetVibrationMotorCount()
Controller::SettingList NamcoGunCon::StaticGetSettings() Controller::SettingList NamcoGunCon::StaticGetSettings()
{ {
static constexpr std::array<SettingInfo, 2> settings = { static constexpr std::array<SettingInfo, 3> settings = {
{{SettingInfo::Type::Path, "CrosshairImagePath", TRANSLATABLE("NamcoGunCon", "Crosshair Image Path"), {{SettingInfo::Type::Path, "CrosshairImagePath", TRANSLATABLE("NamcoGunCon", "Crosshair Image Path"),
TRANSLATABLE("NamcoGunCon", "Path to an image to use as a crosshair/cursor.")}, TRANSLATABLE("NamcoGunCon", "Path to an image to use as a crosshair/cursor.")},
{SettingInfo::Type::Float, "CrosshairScale", TRANSLATABLE("NamcoGunCon", "Crosshair Image Scale"), {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()); 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_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) bool NamcoGunCon::GetSoftwareCursor(const Common::RGBA8Image** image, float* image_scale)

View File

@ -62,6 +62,7 @@ private:
Common::RGBA8Image m_crosshair_image; Common::RGBA8Image m_crosshair_image;
std::string m_crosshair_image_path; std::string m_crosshair_image_path;
float m_crosshair_image_scale = 1.0f; float m_crosshair_image_scale = 1.0f;
float m_x_scale = 1.0f;
// buttons are active low // buttons are active low
u16 m_button_state = UINT16_C(0xFFFF); u16 m_button_state = UINT16_C(0xFFFF);