mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-08-14 17:27:48 +00:00
Merge pull request #118 from mihaip/upstream-hidpi
Enable HiDPI mode for SDL and ensure that we use nearest-neighbor scaling
This commit is contained in:
@@ -35,6 +35,12 @@ public:
|
|||||||
uint32_t window_id;
|
uint32_t window_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum : uint16_t {
|
||||||
|
// Standard SDL window event types are uint8_t's, we add our own custom
|
||||||
|
// events after that.
|
||||||
|
WINDOW_SCALE_QUALITY_TOGGLE = 1 << 8,
|
||||||
|
};
|
||||||
|
|
||||||
enum : uint32_t {
|
enum : uint32_t {
|
||||||
MOUSE_EVENT_MOTION = 1 << 0,
|
MOUSE_EVENT_MOTION = 1 << 0,
|
||||||
MOUSE_EVENT_BUTTON = 1 << 1,
|
MOUSE_EVENT_BUTTON = 1 << 1,
|
||||||
|
@@ -54,14 +54,24 @@ void EventManager::poll_events()
|
|||||||
|
|
||||||
case SDL_KEYDOWN:
|
case SDL_KEYDOWN:
|
||||||
case SDL_KEYUP: {
|
case SDL_KEYUP: {
|
||||||
// Internal shortcuts to trigger mouse grab, intentionally not
|
// Internal shortcuts, intentionally not sent to the host.
|
||||||
// sent to the host.
|
// Control-G: mouse grab
|
||||||
if (event.key.keysym.sym == SDLK_g && SDL_GetModState() & KMOD_LCTRL) {
|
if (event.key.keysym.sym == SDLK_g && SDL_GetModState() & KMOD_LCTRL) {
|
||||||
if (event.type == SDL_KEYUP) {
|
if (event.type == SDL_KEYUP) {
|
||||||
toggle_mouse_grab(event.key);
|
toggle_mouse_grab(event.key);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Control-S: scale quality
|
||||||
|
if (event.key.keysym.sym == SDLK_s && SDL_GetModState() & KMOD_LCTRL) {
|
||||||
|
if (event.type == SDL_KEYUP) {
|
||||||
|
WindowEvent we;
|
||||||
|
we.sub_type = WINDOW_SCALE_QUALITY_TOGGLE;
|
||||||
|
we.window_id = event.window.windowID;
|
||||||
|
this->_window_signal.emit(we);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
int key_code = get_sdl_event_key_code(event.key);
|
int key_code = get_sdl_event_key_code(event.key);
|
||||||
if (key_code != -1) {
|
if (key_code != -1) {
|
||||||
KeyboardEvent ke;
|
KeyboardEvent ke;
|
||||||
|
@@ -29,12 +29,15 @@ public:
|
|||||||
uint32_t disp_wnd_id = 0;
|
uint32_t disp_wnd_id = 0;
|
||||||
SDL_Window* display_wnd = 0;
|
SDL_Window* display_wnd = 0;
|
||||||
SDL_Renderer* renderer = 0;
|
SDL_Renderer* renderer = 0;
|
||||||
|
double renderer_scale_x; // scaling factor from guest OS to host OS
|
||||||
|
double renderer_scale_y;
|
||||||
SDL_Texture* disp_texture = 0;
|
SDL_Texture* disp_texture = 0;
|
||||||
SDL_Texture* cursor_texture = 0;
|
SDL_Texture* cursor_texture = 0;
|
||||||
SDL_Rect cursor_rect; // destination rectangle for cursor drawing
|
SDL_Rect cursor_rect; // destination rectangle for cursor drawing
|
||||||
};
|
};
|
||||||
|
|
||||||
Display::Display(): impl(std::make_unique<Impl>()) {
|
Display::Display(): impl(std::make_unique<Impl>()) {
|
||||||
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
|
||||||
}
|
}
|
||||||
|
|
||||||
Display::~Display() {
|
Display::~Display() {
|
||||||
@@ -61,7 +64,7 @@ bool Display::configure(int width, int height) {
|
|||||||
SDL_WINDOWPOS_UNDEFINED,
|
SDL_WINDOWPOS_UNDEFINED,
|
||||||
SDL_WINDOWPOS_UNDEFINED,
|
SDL_WINDOWPOS_UNDEFINED,
|
||||||
width, height,
|
width, height,
|
||||||
SDL_WINDOW_OPENGL
|
SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI
|
||||||
);
|
);
|
||||||
|
|
||||||
impl->disp_wnd_id = SDL_GetWindowID(impl->display_wnd);
|
impl->disp_wnd_id = SDL_GetWindowID(impl->display_wnd);
|
||||||
@@ -72,6 +75,11 @@ bool Display::configure(int width, int height) {
|
|||||||
if (impl->renderer == NULL)
|
if (impl->renderer == NULL)
|
||||||
ABORT_F("Display: SDL_CreateRenderer failed with %s", SDL_GetError());
|
ABORT_F("Display: SDL_CreateRenderer failed with %s", SDL_GetError());
|
||||||
|
|
||||||
|
int drawable_width, drawable_height;
|
||||||
|
SDL_GetRendererOutputSize(impl->renderer, &drawable_width, &drawable_height);
|
||||||
|
impl->renderer_scale_x = static_cast<double>(drawable_width) / width;
|
||||||
|
impl->renderer_scale_y = static_cast<float>(drawable_height) / height;
|
||||||
|
|
||||||
is_initialization = true;
|
is_initialization = true;
|
||||||
} else { // resize display window
|
} else { // resize display window
|
||||||
SDL_SetWindowSize(impl->display_wnd, width, height);
|
SDL_SetWindowSize(impl->display_wnd, width, height);
|
||||||
@@ -100,6 +108,16 @@ void Display::handle_events(const WindowEvent& wnd_event) {
|
|||||||
if (wnd_event.sub_type == SDL_WINDOWEVENT_EXPOSED &&
|
if (wnd_event.sub_type == SDL_WINDOWEVENT_EXPOSED &&
|
||||||
wnd_event.window_id == impl->disp_wnd_id)
|
wnd_event.window_id == impl->disp_wnd_id)
|
||||||
SDL_RenderPresent(impl->renderer);
|
SDL_RenderPresent(impl->renderer);
|
||||||
|
if (wnd_event.sub_type == WINDOW_SCALE_QUALITY_TOGGLE &&
|
||||||
|
wnd_event.window_id == impl->disp_wnd_id) {
|
||||||
|
auto current_quality = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
|
||||||
|
auto new_quality = current_quality == NULL || strcmp(current_quality, "nearest") == 0 ? "best" : "nearest";
|
||||||
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, new_quality);
|
||||||
|
// We need the window/texture to be recreated to pick up the hint change.
|
||||||
|
int width, height;
|
||||||
|
SDL_GetWindowSize(impl->display_wnd, &width, &height);
|
||||||
|
this->configure(width, height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Display::blank() {
|
void Display::blank() {
|
||||||
@@ -133,8 +151,8 @@ void Display::update(std::function<void(uint8_t *dst_buf, int dst_pitch)> conver
|
|||||||
|
|
||||||
// draw HW cursor if enabled
|
// draw HW cursor if enabled
|
||||||
if (draw_hw_cursor) {
|
if (draw_hw_cursor) {
|
||||||
impl->cursor_rect.x = cursor_x;
|
impl->cursor_rect.x = cursor_x * impl->renderer_scale_x;
|
||||||
impl->cursor_rect.y = cursor_y;
|
impl->cursor_rect.y = cursor_y * impl->renderer_scale_y;
|
||||||
SDL_RenderCopy(impl->renderer, impl->cursor_texture, NULL, &impl->cursor_rect);
|
SDL_RenderCopy(impl->renderer, impl->cursor_texture, NULL, &impl->cursor_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,6 +188,6 @@ void Display::setup_hw_cursor(std::function<void(uint8_t *dst_buf, int dst_pitch
|
|||||||
|
|
||||||
impl->cursor_rect.x = 0;
|
impl->cursor_rect.x = 0;
|
||||||
impl->cursor_rect.y = 0;
|
impl->cursor_rect.y = 0;
|
||||||
impl->cursor_rect.w = cursor_width;
|
impl->cursor_rect.w = cursor_width * impl->renderer_scale_x;
|
||||||
impl->cursor_rect.h = cursor_height;
|
impl->cursor_rect.h = cursor_height * impl->renderer_scale_y;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user