mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 23:55:40 +00:00
HostInterface: Better configuration of custom crosshair/software cursor
This commit is contained in:
parent
f0c1dfefe7
commit
e374853cf5
|
@ -41,6 +41,11 @@ float Controller::GetVibrationMotorStrength(u32 motor)
|
|||
|
||||
void Controller::LoadSettings(HostInterface* host_interface, const char* section) {}
|
||||
|
||||
bool Controller::GetSoftwareCursor(const Common::RGBA8Image** image, float* image_scale)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<Controller> Controller::Create(System* system, ControllerType type, u32 index)
|
||||
{
|
||||
switch (type)
|
||||
|
@ -208,6 +213,9 @@ Controller::SettingList Controller::GetSettings(ControllerType type)
|
|||
case ControllerType::AnalogController:
|
||||
return AnalogController::StaticGetSettings();
|
||||
|
||||
case ControllerType::NamcoGunCon:
|
||||
return NamcoGunCon::StaticGetSettings();
|
||||
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include "common/image.h"
|
||||
#include "settings.h"
|
||||
#include "types.h"
|
||||
#include <memory>
|
||||
|
@ -54,6 +55,9 @@ public:
|
|||
/// Loads/refreshes any per-controller settings.
|
||||
virtual void LoadSettings(HostInterface* host_interface, const char* section);
|
||||
|
||||
/// Returns the software cursor to use for this controller, if any.
|
||||
virtual bool GetSoftwareCursor(const Common::RGBA8Image** image, float* image_scale);
|
||||
|
||||
/// Creates a new controller of the specified type.
|
||||
static std::unique_ptr<Controller> Create(System* system, ControllerType type, u32 index);
|
||||
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
#include "common/audio_stream.h"
|
||||
#include "common/byte_stream.h"
|
||||
#include "common/file_system.h"
|
||||
#include "common/image.h"
|
||||
#include "common/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "controller.h"
|
||||
#include "dma.h"
|
||||
#include "gpu.h"
|
||||
#include "host_display.h"
|
||||
|
@ -89,6 +91,7 @@ bool HostInterface::BootSystem(const SystemBootParameters& parameters)
|
|||
return false;
|
||||
}
|
||||
|
||||
UpdateSoftwareCursor();
|
||||
OnSystemCreated();
|
||||
|
||||
m_audio_stream->PauseOutput(false);
|
||||
|
@ -117,6 +120,7 @@ void HostInterface::DestroySystem()
|
|||
|
||||
m_system.reset();
|
||||
m_audio_stream.reset();
|
||||
UpdateSoftwareCursor();
|
||||
ReleaseHostDisplay();
|
||||
OnSystemDestroyed();
|
||||
OnRunningGameChanged();
|
||||
|
@ -352,8 +356,6 @@ void HostInterface::SetDefaultSettings(SettingsInterface& si)
|
|||
si.SetBoolValue("Display", "ShowSpeed", false);
|
||||
si.SetBoolValue("Display", "Fullscreen", false);
|
||||
si.SetBoolValue("Display", "VSync", true);
|
||||
si.SetStringValue("Display", "SoftwareCursorPath", "");
|
||||
si.SetFloatValue("Display", "SoftwareCursorScale", 1.0f);
|
||||
|
||||
si.SetBoolValue("CDROM", "ReadThread", true);
|
||||
si.SetBoolValue("CDROM", "RegionCheck", true);
|
||||
|
@ -476,6 +478,7 @@ void HostInterface::CheckForSettingsChanges(const Settings& old_settings)
|
|||
if (m_system && !controllers_updated)
|
||||
{
|
||||
m_system->UpdateControllers();
|
||||
UpdateSoftwareCursor();
|
||||
controllers_updated = true;
|
||||
}
|
||||
|
||||
|
@ -483,7 +486,10 @@ void HostInterface::CheckForSettingsChanges(const Settings& old_settings)
|
|||
}
|
||||
|
||||
if (m_system && !controllers_updated)
|
||||
{
|
||||
m_system->UpdateControllerSettings();
|
||||
UpdateSoftwareCursor();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_display && m_settings.display_linear_filtering != old_settings.display_linear_filtering)
|
||||
|
@ -491,21 +497,6 @@ void HostInterface::CheckForSettingsChanges(const Settings& old_settings)
|
|||
|
||||
if (m_display && m_settings.display_integer_scaling != old_settings.display_integer_scaling)
|
||||
m_display->SetDisplayIntegerScaling(m_settings.display_integer_scaling);
|
||||
|
||||
if (m_software_cursor_use_count > 0 && m_display &&
|
||||
(m_settings.display_software_cursor_path != old_settings.display_software_cursor_path ||
|
||||
m_settings.display_software_cursor_scale != old_settings.display_software_cursor_scale))
|
||||
{
|
||||
if (m_settings.display_software_cursor_path.empty())
|
||||
{
|
||||
m_display->ClearSoftwareCursor();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_display->SetSoftwareCursor(m_settings.display_software_cursor_path.c_str(),
|
||||
m_settings.display_software_cursor_scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HostInterface::SetUserDirectoryToProgramDirectory()
|
||||
|
@ -580,7 +571,7 @@ bool HostInterface::GetBooleanSettingValue(const char* section, const char* key,
|
|||
return bool_value.value_or(default_value);
|
||||
}
|
||||
|
||||
bool HostInterface::GetIntegerSettingValue(const char* section, const char* key, s32 default_value /*= 0*/)
|
||||
s32 HostInterface::GetIntegerSettingValue(const char* section, const char* key, s32 default_value /*= 0*/)
|
||||
{
|
||||
std::string value = GetSettingValue(section, key, "");
|
||||
if (value.empty())
|
||||
|
@ -590,7 +581,7 @@ bool HostInterface::GetIntegerSettingValue(const char* section, const char* key,
|
|||
return int_value.value_or(default_value);
|
||||
}
|
||||
|
||||
bool HostInterface::GetFloatSettingValue(const char* section, const char* key, float default_value /*= 0.0f*/)
|
||||
float HostInterface::GetFloatSettingValue(const char* section, const char* key, float default_value /*= 0.0f*/)
|
||||
{
|
||||
std::string value = GetSettingValue(section, key, "");
|
||||
if (value.empty())
|
||||
|
@ -628,6 +619,35 @@ void HostInterface::ModifyResolutionScale(s32 increment)
|
|||
m_system->GetGPU()->UpdateSettings();
|
||||
}
|
||||
|
||||
void HostInterface::UpdateSoftwareCursor()
|
||||
{
|
||||
if (!m_system)
|
||||
{
|
||||
m_display->ClearSoftwareCursor();
|
||||
return;
|
||||
}
|
||||
|
||||
const Common::RGBA8Image* image = nullptr;
|
||||
float image_scale = 1.0f;
|
||||
|
||||
for (u32 i = 0; i < NUM_CONTROLLER_AND_CARD_PORTS; i++)
|
||||
{
|
||||
Controller* controller = m_system->GetController(i);
|
||||
if (controller && controller->GetSoftwareCursor(&image, &image_scale))
|
||||
break;
|
||||
}
|
||||
|
||||
if (image && image->IsValid())
|
||||
{
|
||||
m_display->SetSoftwareCursor(image->GetPixels(), image->GetWidth(), image->GetHeight(), image->GetByteStride(),
|
||||
image_scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_display->ClearSoftwareCursor();
|
||||
}
|
||||
}
|
||||
|
||||
void HostInterface::RecreateSystem()
|
||||
{
|
||||
std::unique_ptr<ByteStream> stream = ByteStream_CreateGrowableMemoryStream(nullptr, 8 * 1024);
|
||||
|
@ -657,22 +677,4 @@ void HostInterface::DisplayLoadingScreen(const char* message, int progress_min /
|
|||
Log_InfoPrintf("Loading: %s %d of %d-%d", message, progress_value, progress_min, progress_max);
|
||||
}
|
||||
|
||||
void HostInterface::EnableSoftwareCursor()
|
||||
{
|
||||
if (m_software_cursor_use_count++ > 0 || m_settings.display_software_cursor_path.empty())
|
||||
return;
|
||||
|
||||
m_display->SetSoftwareCursor(m_settings.display_software_cursor_path.c_str(),
|
||||
m_settings.display_software_cursor_scale);
|
||||
}
|
||||
|
||||
void HostInterface::DisableSoftwareCursor()
|
||||
{
|
||||
DebugAssert(m_software_cursor_use_count > 0);
|
||||
if (--m_software_cursor_use_count > 0)
|
||||
return;
|
||||
|
||||
m_display->ClearSoftwareCursor();
|
||||
}
|
||||
|
||||
void HostInterface::GetGameInfo(const char* path, CDImage* image, std::string* code, std::string* title) {}
|
||||
|
|
|
@ -110,17 +110,10 @@ public:
|
|||
bool GetBooleanSettingValue(const char* section, const char* key, bool default_value = false);
|
||||
|
||||
/// Returns an integer setting from the configuration.
|
||||
bool GetIntegerSettingValue(const char* section, const char* key, s32 default_value = 0);
|
||||
s32 GetIntegerSettingValue(const char* section, const char* key, s32 default_value = 0);
|
||||
|
||||
/// Returns a float setting from the configuration.
|
||||
bool GetFloatSettingValue(const char* section, const char* key, float default_value = 0.0f);
|
||||
|
||||
/// Enables the software cursor. Can be called multiple times, but must be matched by a call to
|
||||
/// DisableSoftwareCursor().
|
||||
void EnableSoftwareCursor();
|
||||
|
||||
/// Disables the software cursor, preventing it from being renderered.
|
||||
void DisableSoftwareCursor();
|
||||
float GetFloatSettingValue(const char* section, const char* key, float default_value = 0.0f);
|
||||
|
||||
protected:
|
||||
virtual bool AcquireHostDisplay() = 0;
|
||||
|
@ -164,6 +157,9 @@ protected:
|
|||
/// Adjusts the internal (render) resolution of the hardware backends.
|
||||
void ModifyResolutionScale(s32 increment);
|
||||
|
||||
/// Updates software cursor state, based on controllers.
|
||||
void UpdateSoftwareCursor();
|
||||
|
||||
bool SaveState(const char* filename);
|
||||
void CreateAudioStream();
|
||||
|
||||
|
@ -173,6 +169,4 @@ protected:
|
|||
Settings m_settings;
|
||||
std::string m_program_directory;
|
||||
std::string m_user_directory;
|
||||
|
||||
u32 m_software_cursor_use_count = 0;
|
||||
};
|
||||
|
|
|
@ -5,19 +5,14 @@
|
|||
#include "gpu.h"
|
||||
#include "host_display.h"
|
||||
#include "host_interface.h"
|
||||
#include "resources.h"
|
||||
#include "system.h"
|
||||
#include <array>
|
||||
Log_SetChannel(NamcoGunCon);
|
||||
|
||||
NamcoGunCon::NamcoGunCon(System* system) : m_system(system)
|
||||
{
|
||||
m_system->GetHostInterface()->EnableSoftwareCursor();
|
||||
}
|
||||
NamcoGunCon::NamcoGunCon(System* system) : m_system(system) {}
|
||||
|
||||
NamcoGunCon::~NamcoGunCon()
|
||||
{
|
||||
m_system->GetHostInterface()->DisableSoftwareCursor();
|
||||
}
|
||||
NamcoGunCon::~NamcoGunCon() = default;
|
||||
|
||||
ControllerType NamcoGunCon::GetType() const
|
||||
{
|
||||
|
@ -226,3 +221,48 @@ u32 NamcoGunCon::StaticGetVibrationMotorCount()
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Controller::SettingList NamcoGunCon::StaticGetSettings()
|
||||
{
|
||||
static constexpr std::array<SettingInfo, 2> settings = {
|
||||
{{SettingInfo::Type::Path, "CrosshairImagePath", "Crosshair Image Path",
|
||||
"Path to an image to use as a crosshair/cursor."},
|
||||
{SettingInfo::Type::Float, "CrosshairScale", "Crosshair Image Scale", "Scale of crosshair image on screen.", "1.0",
|
||||
"0.0001", "100.0"}}};
|
||||
|
||||
return SettingList(settings.begin(), settings.end());
|
||||
}
|
||||
|
||||
void NamcoGunCon::LoadSettings(HostInterface* host_interface, const char* section)
|
||||
{
|
||||
Controller::LoadSettings(host_interface, section);
|
||||
|
||||
std::string path = host_interface->GetSettingValue(section, "CrosshairImagePath");
|
||||
if (path != m_crosshair_image_path)
|
||||
{
|
||||
m_crosshair_image_path = std::move(path);
|
||||
if (m_crosshair_image_path.empty() ||
|
||||
!Common::LoadImageFromFile(&m_crosshair_image, m_crosshair_image_path.c_str()))
|
||||
{
|
||||
m_crosshair_image.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_crosshair_image.IsValid())
|
||||
{
|
||||
m_crosshair_image.SetPixels(Resources::CROSSHAIR_IMAGE_WIDTH, Resources::CROSSHAIR_IMAGE_HEIGHT,
|
||||
Resources::CROSSHAIR_IMAGE_DATA.data());
|
||||
}
|
||||
|
||||
m_crosshair_image_scale = host_interface->GetFloatSettingValue(section, "CrosshairScale", 1.0f);
|
||||
}
|
||||
|
||||
bool NamcoGunCon::GetSoftwareCursor(const Common::RGBA8Image** image, float* image_scale)
|
||||
{
|
||||
if (!m_crosshair_image.IsValid())
|
||||
return false;
|
||||
|
||||
*image = &m_crosshair_image;
|
||||
*image_scale = m_crosshair_image_scale;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ public:
|
|||
static AxisList StaticGetAxisNames();
|
||||
static ButtonList StaticGetButtonNames();
|
||||
static u32 StaticGetVibrationMotorCount();
|
||||
static SettingList StaticGetSettings();
|
||||
|
||||
ControllerType GetType() const override;
|
||||
std::optional<s32> GetAxisCodeByName(std::string_view axis_name) const override;
|
||||
|
@ -31,6 +32,8 @@ public:
|
|||
|
||||
void Reset() override;
|
||||
bool DoState(StateWrapper& sw) override;
|
||||
void LoadSettings(HostInterface* host_interface, const char* section) override;
|
||||
bool GetSoftwareCursor(const Common::RGBA8Image** image, float* image_scale) override;
|
||||
|
||||
void SetAxisState(s32 axis_code, float value) override;
|
||||
void SetButtonState(s32 button_code, bool pressed) override;
|
||||
|
@ -56,6 +59,9 @@ private:
|
|||
};
|
||||
|
||||
System* m_system;
|
||||
Common::RGBA8Image m_crosshair_image;
|
||||
std::string m_crosshair_image_path;
|
||||
float m_crosshair_image_scale = 1.0f;
|
||||
|
||||
// buttons are active low
|
||||
u16 m_button_state = UINT16_C(0xFFFF);
|
||||
|
|
|
@ -113,8 +113,6 @@ void Settings::Load(SettingsInterface& si)
|
|||
display_show_vps = si.GetBoolValue("Display", "ShowVPS", false);
|
||||
display_show_speed = si.GetBoolValue("Display", "ShowSpeed", false);
|
||||
video_sync_enabled = si.GetBoolValue("Display", "VSync", true);
|
||||
display_software_cursor_path = si.GetStringValue("Display", "SoftwareCursorPath", "");
|
||||
display_software_cursor_scale = si.GetFloatValue("Display", "SoftwareCursorScale", 1.0f);
|
||||
|
||||
cdrom_read_thread = si.GetBoolValue("CDROM", "ReadThread", true);
|
||||
cdrom_region_check = si.GetBoolValue("CDROM", "RegionCheck", true);
|
||||
|
@ -211,8 +209,6 @@ void Settings::Save(SettingsInterface& si) const
|
|||
si.SetBoolValue("Display", "ShowVPS", display_show_vps);
|
||||
si.SetBoolValue("Display", "ShowSpeed", display_show_speed);
|
||||
si.SetBoolValue("Display", "VSync", video_sync_enabled);
|
||||
si.SetStringValue("Display", "SoftwareCursorPath", display_software_cursor_path.c_str());
|
||||
si.SetFloatValue("Display", "SoftwareCursorScale", display_software_cursor_scale);
|
||||
|
||||
si.SetBoolValue("CDROM", "ReadThread", cdrom_read_thread);
|
||||
si.SetBoolValue("CDROM", "RegionCheck", cdrom_region_check);
|
||||
|
|
|
@ -97,8 +97,6 @@ struct Settings
|
|||
bool display_show_vps = false;
|
||||
bool display_show_speed = false;
|
||||
bool video_sync_enabled = true;
|
||||
std::string display_software_cursor_path;
|
||||
float display_software_cursor_scale = 1.0f;
|
||||
|
||||
bool cdrom_read_thread = true;
|
||||
bool cdrom_region_check = true;
|
||||
|
|
Loading…
Reference in a new issue