mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 23:55:40 +00:00
HostDisplay: Add an interface for setting software cursor
This commit is contained in:
parent
56c50c6eeb
commit
f98bb033ff
|
@ -1,6 +1,7 @@
|
|||
#include "host_display.h"
|
||||
#include "common/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "stb_image.h"
|
||||
#include "stb_image_resize.h"
|
||||
#include "stb_image_write.h"
|
||||
#include <cmath>
|
||||
|
@ -18,6 +19,50 @@ void HostDisplay::WindowResized(s32 new_window_width, s32 new_window_height)
|
|||
m_window_height = new_window_height;
|
||||
}
|
||||
|
||||
void HostDisplay::SetSoftwareCursor(std::unique_ptr<HostDisplayTexture> texture, float scale /*= 1.0f*/)
|
||||
{
|
||||
m_cursor_texture = std::move(texture);
|
||||
m_cursor_texture_scale = scale;
|
||||
}
|
||||
|
||||
bool HostDisplay::SetSoftwareCursor(const void* pixels, u32 width, u32 height, u32 stride, float scale /*= 1.0f*/)
|
||||
{
|
||||
std::unique_ptr<HostDisplayTexture> tex = CreateTexture(width, height, pixels, stride, false);
|
||||
if (!tex)
|
||||
return false;
|
||||
|
||||
SetSoftwareCursor(std::move(tex), scale);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HostDisplay::SetSoftwareCursor(const char* path, float scale /*= 1.0f*/)
|
||||
{
|
||||
int width, height, file_channels;
|
||||
u8* pixel_data = stbi_load(path, &width, &height, &file_channels, 4);
|
||||
if (!pixel_data)
|
||||
{
|
||||
const char* error_reason = stbi_failure_reason();
|
||||
Log_ErrorPrintf("Failed to load image from '%s': %s", path, error_reason ? error_reason : "unknown error");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<HostDisplayTexture> tex = CreateTexture(static_cast<u32>(width), static_cast<u32>(height), pixel_data,
|
||||
sizeof(u32) * static_cast<u32>(width), false);
|
||||
stbi_image_free(pixel_data);
|
||||
if (!tex)
|
||||
return false;
|
||||
|
||||
Log_InfoPrintf("Loaded %dx%d image from '%s' for software cursor", width, height, path);
|
||||
SetSoftwareCursor(std::move(tex), scale);
|
||||
return true;
|
||||
}
|
||||
|
||||
void HostDisplay::ClearSoftwareCursor()
|
||||
{
|
||||
m_cursor_texture.reset();
|
||||
m_cursor_texture_scale = 1.0f;
|
||||
}
|
||||
|
||||
void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, s32* out_left, s32* out_top, s32* out_width,
|
||||
s32* out_height, s32* out_left_padding, s32* out_top_padding, float* out_scale,
|
||||
float* out_y_scale) const
|
||||
|
@ -88,6 +133,21 @@ std::tuple<s32, s32, s32, s32> HostDisplay::CalculateDrawRect(s32 window_width,
|
|||
return std::make_tuple(left + left_padding, top + top_padding + top_margin, width, height);
|
||||
}
|
||||
|
||||
std::tuple<s32, s32, s32, s32> HostDisplay::CalculateSoftwareCursorDrawRect() const
|
||||
{
|
||||
const u32 cursor_extents_x =
|
||||
static_cast<u32>(static_cast<float>(m_cursor_texture->GetWidth()) * m_cursor_texture_scale * 0.5f);
|
||||
const u32 cursor_extents_y =
|
||||
static_cast<u32>(static_cast<float>(m_cursor_texture->GetHeight()) * m_cursor_texture_scale * 0.5f);
|
||||
|
||||
const s32 out_left = m_mouse_position_x - cursor_extents_x;
|
||||
const s32 out_top = m_mouse_position_y - cursor_extents_y;
|
||||
const s32 out_width = cursor_extents_x * 2u;
|
||||
const s32 out_height = cursor_extents_y * 2u;
|
||||
|
||||
return std::tie(out_left, out_top, out_width, out_height);
|
||||
}
|
||||
|
||||
std::tuple<s32, s32> HostDisplay::ConvertWindowCoordinatesToDisplayCoordinates(s32 window_x, s32 window_y,
|
||||
s32 window_width, s32 window_height,
|
||||
s32 top_margin) const
|
||||
|
|
|
@ -106,6 +106,18 @@ public:
|
|||
void SetDisplayTopMargin(s32 height) { m_display_top_margin = height; }
|
||||
void SetDisplayIntegerScaling(bool enabled) { m_display_integer_scaling = enabled; }
|
||||
|
||||
/// Sets the software cursor to the specified texture. Ownership of the texture is transferred.
|
||||
void SetSoftwareCursor(std::unique_ptr<HostDisplayTexture> texture, float scale = 1.0f);
|
||||
|
||||
/// Sets the software cursor to the specified image.
|
||||
bool SetSoftwareCursor(const void* pixels, u32 width, u32 height, u32 stride, float scale = 1.0f);
|
||||
|
||||
/// Sets the software cursor to the specified path (png image).
|
||||
bool SetSoftwareCursor(const char* path, float scale = 1.0f);
|
||||
|
||||
/// Disables the software cursor.
|
||||
void ClearSoftwareCursor();
|
||||
|
||||
/// Helper function for computing the draw rectangle in a larger window.
|
||||
std::tuple<s32, s32, s32, s32> CalculateDrawRect(s32 window_width, s32 window_height, s32 top_margin) const;
|
||||
|
||||
|
@ -125,10 +137,14 @@ public:
|
|||
bool clear_alpha = true);
|
||||
|
||||
protected:
|
||||
ALWAYS_INLINE bool HasSoftwareCursor() const { return static_cast<bool>(m_cursor_texture); }
|
||||
|
||||
void CalculateDrawRect(s32 window_width, s32 window_height, s32* out_left, s32* out_top, s32* out_width,
|
||||
s32* out_height, s32* out_left_padding, s32* out_top_padding, float* out_scale,
|
||||
float* out_y_scale) const;
|
||||
|
||||
std::tuple<s32, s32, s32, s32> CalculateSoftwareCursorDrawRect() const;
|
||||
|
||||
s32 m_window_width = 0;
|
||||
s32 m_window_height = 0;
|
||||
|
||||
|
@ -153,6 +169,9 @@ protected:
|
|||
|
||||
s32 m_display_top_margin = 0;
|
||||
|
||||
std::unique_ptr<HostDisplayTexture> m_cursor_texture;
|
||||
float m_cursor_texture_scale = 1.0f;
|
||||
|
||||
bool m_display_linear_filtering = false;
|
||||
bool m_display_changed = false;
|
||||
bool m_display_integer_scaling = false;
|
||||
|
|
Loading…
Reference in a new issue