mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Fix high-DPI rendering/input on Windows
This commit is contained in:
parent
da82237118
commit
8b5048be72
10 changed files with 69 additions and 61 deletions
|
@ -130,12 +130,21 @@ bool Core_GetPowerSaving() {
|
|||
return powerSaving;
|
||||
}
|
||||
|
||||
// TODO: Feels like this belongs elsewhere.
|
||||
bool UpdateScreenScale(int width, int height, bool smallWindow) {
|
||||
g_dpi = 72;
|
||||
#ifdef _WIN32
|
||||
// Use legacy DPI handling, because we still compile as XP compatible we don't get the new SDK, unless
|
||||
// we do unholy tricks.
|
||||
HDC screenDC = GetDC(nullptr);
|
||||
double hPixelsPerInch = GetDeviceCaps(screenDC, LOGPIXELSY);
|
||||
ReleaseDC(nullptr, screenDC);
|
||||
|
||||
g_dpi = hPixelsPerInch;
|
||||
g_dpi_scale = 96.0f / g_dpi;
|
||||
#else
|
||||
g_dpi = 96;
|
||||
g_dpi_scale = 1.0f;
|
||||
if (smallWindow) {
|
||||
g_dpi_scale = 2.0f;
|
||||
}
|
||||
#endif
|
||||
|
||||
pixel_in_dps = 1.0f / g_dpi_scale;
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "base/display.h"
|
||||
#include "base/NativeApp.h"
|
||||
#include "Globals.h"
|
||||
|
||||
|
@ -207,8 +208,8 @@ namespace MainWindow
|
|||
// Can't take this from config as it will not be set if windows is maximized.
|
||||
RECT rc;
|
||||
GetWindowRect(hwndMain, &rc);
|
||||
int width = rc.right - rc.left;
|
||||
int height = rc.bottom - rc.top;
|
||||
int width = (int)((rc.right - rc.left) * g_dpi_scale);
|
||||
int height = (int)((rc.bottom - rc.top) * g_dpi_scale);
|
||||
return g_Config.IsPortrait() ? (height < 480 + 80) : (width < 480 + 80);
|
||||
}
|
||||
|
||||
|
@ -516,8 +517,6 @@ namespace MainWindow
|
|||
}
|
||||
|
||||
LRESULT CALLBACK DisplayProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
// Only apply a factor > 1 in windowed mode.
|
||||
int factor = !IsZoomed(GetHWND()) && !g_Config.bFullScreen && IsWindowSmall() ? 2 : 1;
|
||||
static bool firstErase = true;
|
||||
|
||||
switch (message) {
|
||||
|
@ -555,8 +554,8 @@ namespace MainWindow
|
|||
input_state.mouse_valid = true;
|
||||
input_state.pointer_down[0] = true;
|
||||
|
||||
input_state.pointer_x[0] = GET_X_LPARAM(lParam) * factor;
|
||||
input_state.pointer_y[0] = GET_Y_LPARAM(lParam) * factor;
|
||||
input_state.pointer_x[0] = GET_X_LPARAM(lParam) * g_dpi_scale;
|
||||
input_state.pointer_y[0] = GET_Y_LPARAM(lParam) * g_dpi_scale;
|
||||
}
|
||||
|
||||
TouchInput touch;
|
||||
|
@ -598,8 +597,8 @@ namespace MainWindow
|
|||
|
||||
{
|
||||
lock_guard guard(input_state.lock);
|
||||
input_state.pointer_x[0] = GET_X_LPARAM(lParam) * factor;
|
||||
input_state.pointer_y[0] = GET_Y_LPARAM(lParam) * factor;
|
||||
input_state.pointer_x[0] = GET_X_LPARAM(lParam) * g_dpi_scale;
|
||||
input_state.pointer_y[0] = GET_Y_LPARAM(lParam) * g_dpi_scale;
|
||||
}
|
||||
|
||||
if (wParam & MK_LBUTTON) {
|
||||
|
@ -622,8 +621,8 @@ namespace MainWindow
|
|||
{
|
||||
lock_guard guard(input_state.lock);
|
||||
input_state.pointer_down[0] = false;
|
||||
input_state.pointer_x[0] = GET_X_LPARAM(lParam) * factor;
|
||||
input_state.pointer_y[0] = GET_Y_LPARAM(lParam) * factor;
|
||||
input_state.pointer_x[0] = GET_X_LPARAM(lParam) * g_dpi_scale;
|
||||
input_state.pointer_y[0] = GET_Y_LPARAM(lParam) * g_dpi_scale;
|
||||
}
|
||||
TouchInput touch;
|
||||
touch.id = 0;
|
||||
|
|
|
@ -31,7 +31,8 @@
|
|||
</trustInfo>
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
|
||||
<!-- Should really use True/PM (per-monitor) here but as we are XP-compatible, we don't have access to the headers. -->
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True</dpiAware>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</assembly>
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <vector>
|
||||
#include "base/NativeApp.h"
|
||||
|
||||
#include "base/display.h"
|
||||
#include "Common/Log.h"
|
||||
#include "input/input_state.h"
|
||||
#include "Windows/RawInput.h"
|
||||
|
@ -202,8 +203,8 @@ namespace WindowsRawInput {
|
|||
KeyInput key;
|
||||
key.deviceId = DEVICE_ID_MOUSE;
|
||||
|
||||
mouseDeltaX += raw->data.mouse.lLastX;
|
||||
mouseDeltaY += raw->data.mouse.lLastY;
|
||||
g_mouseDeltaX += raw->data.mouse.lLastX;
|
||||
g_mouseDeltaY += raw->data.mouse.lLastY;
|
||||
|
||||
if (raw->data.mouse.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) {
|
||||
key.flags = KEY_DOWN;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include "base/display.h"
|
||||
#include "Common/CommonWindows.h"
|
||||
#include "input/input_state.h"
|
||||
#include "base/NativeApp.h"
|
||||
|
@ -71,8 +72,8 @@ void TouchInputHandler::handleTouchEvent(HWND hWnd, UINT message, WPARAM wParam,
|
|||
}
|
||||
|
||||
POINT point;
|
||||
point.x = TOUCH_COORD_TO_PIXEL(inputs[i].x);
|
||||
point.y = TOUCH_COORD_TO_PIXEL(inputs[i].y);
|
||||
point.x = (float)(TOUCH_COORD_TO_PIXEL(inputs[i].x)) * g_dpi_scale;
|
||||
point.y = (float)(TOUCH_COORD_TO_PIXEL(inputs[i].y)) * g_dpi_scale;
|
||||
|
||||
if (ScreenToClient(hWnd, &point)){
|
||||
if (inputs[i].dwFlags & TOUCHEVENTF_DOWN)
|
||||
|
|
|
@ -24,10 +24,13 @@
|
|||
#include "objbase.h"
|
||||
#include "objidl.h"
|
||||
#include "shlguid.h"
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4091) // workaround bug in VS2015 headers
|
||||
#include "shlobj.h"
|
||||
#pragma warning(pop)
|
||||
|
||||
// native stuff
|
||||
#include "base/display.h"
|
||||
#include "base/NativeApp.h"
|
||||
#include "file/file_util.h"
|
||||
#include "input/input_state.h"
|
||||
|
@ -62,8 +65,8 @@
|
|||
|
||||
static const int numCPUs = 1;
|
||||
|
||||
float mouseDeltaX = 0;
|
||||
float mouseDeltaY = 0;
|
||||
float g_mouseDeltaX = 0;
|
||||
float g_mouseDeltaY = 0;
|
||||
|
||||
static BOOL PostDialogMessage(Dialog *dialog, UINT message, WPARAM wParam = 0, LPARAM lParam = 0) {
|
||||
return PostMessage(dialog->GetDlgHandle(), message, wParam, lParam);
|
||||
|
@ -74,8 +77,8 @@ WindowsHost::WindowsHost(HINSTANCE hInstance, HWND mainWindow, HWND displayWindo
|
|||
mainWindow_(mainWindow),
|
||||
displayWindow_(displayWindow)
|
||||
{
|
||||
mouseDeltaX = 0;
|
||||
mouseDeltaY = 0;
|
||||
g_mouseDeltaX = 0;
|
||||
g_mouseDeltaY = 0;
|
||||
|
||||
//add first XInput device to respond
|
||||
input.push_back(std::shared_ptr<InputDevice>(new XinputDevice()));
|
||||
|
@ -201,12 +204,14 @@ void WindowsHost::PollControllers(InputState &input_state) {
|
|||
doPad = false;
|
||||
}
|
||||
|
||||
mouseDeltaX *= 0.9f;
|
||||
mouseDeltaY *= 0.9f;
|
||||
g_mouseDeltaX *= 0.9f;
|
||||
g_mouseDeltaY *= 0.9f;
|
||||
|
||||
// TODO: Tweak!
|
||||
float mx = std::max(-1.0f, std::min(1.0f, mouseDeltaX * 0.01f));
|
||||
float my = std::max(-1.0f, std::min(1.0f, mouseDeltaY * 0.01f));
|
||||
float scaleFactor = g_dpi_scale * 0.01f;
|
||||
|
||||
float mx = std::max(-1.0f, std::min(1.0f, g_mouseDeltaX * scaleFactor));
|
||||
float my = std::max(-1.0f, std::min(1.0f, g_mouseDeltaY * scaleFactor));
|
||||
AxisInput axisX, axisY;
|
||||
axisX.axisId = JOYSTICK_AXIS_MOUSE_REL_X;
|
||||
axisX.deviceId = DEVICE_ID_MOUSE;
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
extern float mouseDeltaX;
|
||||
extern float mouseDeltaY;
|
||||
extern float g_mouseDeltaX;
|
||||
extern float g_mouseDeltaY;
|
||||
|
||||
class GraphicsContext;
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <shellapi.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include "base/display.h"
|
||||
#include "file/vfs.h"
|
||||
#include "file/zip_read.h"
|
||||
#include "base/NativeApp.h"
|
||||
|
@ -367,8 +368,7 @@ std::vector<std::wstring> GetWideCmdLine() {
|
|||
return wideArgs;
|
||||
}
|
||||
|
||||
int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
|
||||
{
|
||||
int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow) {
|
||||
setCurrentThreadName("Main");
|
||||
|
||||
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "base/display.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/stringutil.h"
|
||||
#include "thin3d/thin3d.h"
|
||||
|
@ -51,6 +52,7 @@ struct TextDrawerContext {
|
|||
};
|
||||
|
||||
TextDrawer::TextDrawer(Draw::DrawContext *thin3d) : thin3d_(thin3d), ctx_(nullptr) {
|
||||
// These probably shouldn't be state.
|
||||
fontScaleX_ = 1.0f;
|
||||
fontScaleY_ = 1.0f;
|
||||
|
||||
|
@ -73,16 +75,11 @@ TextDrawer::TextDrawer(Draw::DrawContext *thin3d) : thin3d_(thin3d), ctx_(nullpt
|
|||
}
|
||||
|
||||
TextDrawer::~TextDrawer() {
|
||||
for (auto iter : cache_) {
|
||||
for (auto &iter : cache_) {
|
||||
if (iter.second->texture)
|
||||
iter.second->texture->Release();
|
||||
delete iter.second;
|
||||
}
|
||||
cache_.clear();
|
||||
|
||||
for (auto iter : sizeCache_) {
|
||||
delete iter.second;
|
||||
}
|
||||
sizeCache_.clear();
|
||||
|
||||
for (auto iter = fontMap_.begin(); iter != fontMap_.end(); ++iter) {
|
||||
|
@ -118,6 +115,7 @@ uint32_t TextDrawer::SetFont(const char *fontName, int size, int flags) {
|
|||
|
||||
float textScale = 1.0f;
|
||||
|
||||
// TODO: Should the 72 really be 96? Oh well...
|
||||
INT nHeight = -MulDiv( size, (INT)(GetDeviceCaps(ctx_->hDC, LOGPIXELSY) * textScale), 72 );
|
||||
int dwBold = FW_LIGHT; ///FW_BOLD
|
||||
font->hFont = CreateFont(nHeight, 0, 0, 0, dwBold, 0,
|
||||
|
@ -147,7 +145,7 @@ void TextDrawer::MeasureString(const char *str, size_t len, float *w, float *h)
|
|||
TextMeasureEntry *entry;
|
||||
auto iter = sizeCache_.find(entryHash);
|
||||
if (iter != sizeCache_.end()) {
|
||||
entry = iter->second;
|
||||
entry = iter->second.get();
|
||||
} else {
|
||||
auto iter = fontMap_.find(fontHash_);
|
||||
if (iter != fontMap_.end()) {
|
||||
|
@ -161,12 +159,12 @@ void TextDrawer::MeasureString(const char *str, size_t len, float *w, float *h)
|
|||
entry = new TextMeasureEntry();
|
||||
entry->width = size.cx;
|
||||
entry->height = size.cy;
|
||||
sizeCache_[entryHash] = entry;
|
||||
sizeCache_[entryHash] = std::unique_ptr<TextMeasureEntry>(entry);
|
||||
}
|
||||
|
||||
entry->lastUsedFrame = frameCount_;
|
||||
*w = entry->width * fontScaleX_;
|
||||
*h = entry->height * fontScaleY_;
|
||||
*w = entry->width * fontScaleX_ * g_dpi_scale;
|
||||
*h = entry->height * fontScaleY_ * g_dpi_scale;
|
||||
}
|
||||
|
||||
void TextDrawer::MeasureStringRect(const char *str, size_t len, const Bounds &bounds, float *w, float *h, int align) {
|
||||
|
@ -192,7 +190,7 @@ void TextDrawer::MeasureStringRect(const char *str, size_t len, const Bounds &bo
|
|||
TextMeasureEntry *entry;
|
||||
auto iter = sizeCache_.find(entryHash);
|
||||
if (iter != sizeCache_.end()) {
|
||||
entry = iter->second;
|
||||
entry = iter->second.get();
|
||||
} else {
|
||||
SIZE size;
|
||||
std::wstring wstr = ConvertUTF8ToWString(lines[i].length() == 0 ? " " : lines[i]);
|
||||
|
@ -201,7 +199,7 @@ void TextDrawer::MeasureStringRect(const char *str, size_t len, const Bounds &bo
|
|||
entry = new TextMeasureEntry();
|
||||
entry->width = size.cx;
|
||||
entry->height = size.cy;
|
||||
sizeCache_[entryHash] = entry;
|
||||
sizeCache_[entryHash] = std::unique_ptr<TextMeasureEntry>(entry);
|
||||
}
|
||||
entry->lastUsedFrame = frameCount_;
|
||||
|
||||
|
@ -210,8 +208,8 @@ void TextDrawer::MeasureStringRect(const char *str, size_t len, const Bounds &bo
|
|||
}
|
||||
total_h += entry->height * fontScaleY_;
|
||||
}
|
||||
*w = total_w;
|
||||
*h = total_h;
|
||||
*w = total_w * g_dpi_scale;
|
||||
*h = total_h * g_dpi_scale;
|
||||
}
|
||||
|
||||
void TextDrawer::DrawString(DrawBuffer &target, const char *str, float x, float y, uint32_t color, int align) {
|
||||
|
@ -228,7 +226,7 @@ void TextDrawer::DrawString(DrawBuffer &target, const char *str, float x, float
|
|||
|
||||
auto iter = cache_.find(entryHash);
|
||||
if (iter != cache_.end()) {
|
||||
entry = iter->second;
|
||||
entry = iter->second.get();
|
||||
entry->lastUsedFrame = frameCount_;
|
||||
} else {
|
||||
// Render the string to our bitmap and save to a GL texture.
|
||||
|
@ -285,14 +283,14 @@ void TextDrawer::DrawString(DrawBuffer &target, const char *str, float x, float
|
|||
entry->texture->Finalize(0);
|
||||
delete [] bitmapData;
|
||||
|
||||
cache_[entryHash] = entry;
|
||||
cache_[entryHash] = std::unique_ptr<TextStringEntry>(entry);
|
||||
}
|
||||
|
||||
thin3d_->BindTexture(0, entry->texture);
|
||||
|
||||
// Okay, the texture is bound, let's draw.
|
||||
float w = entry->bmWidth * fontScaleX_;
|
||||
float h = entry->bmHeight * fontScaleY_;
|
||||
float w = entry->bmWidth * fontScaleX_ * g_dpi_scale;
|
||||
float h = entry->bmHeight * fontScaleY_ * g_dpi_scale;
|
||||
DrawBuffer::DoAlign(align, &x, &y, &w, &h);
|
||||
target.DrawTexRect(x, y, x + w, y + h, 0.0f, 0.0f, 1.0f, 1.0f, color);
|
||||
target.Flush(true);
|
||||
|
@ -306,16 +304,11 @@ TextDrawer::TextDrawer(Draw::DrawContext *thin3d) : thin3d_(thin3d), ctx_(NULL)
|
|||
}
|
||||
|
||||
TextDrawer::~TextDrawer() {
|
||||
for (auto iter : cache_) {
|
||||
for (auto &iter : cache_) {
|
||||
if (iter.second->texture)
|
||||
iter.second->texture->Release();
|
||||
delete iter.second;
|
||||
}
|
||||
cache_.clear();
|
||||
|
||||
for (auto iter : sizeCache_) {
|
||||
delete iter.second;
|
||||
}
|
||||
sizeCache_.clear();
|
||||
}
|
||||
|
||||
|
@ -398,7 +391,7 @@ void TextDrawer::DrawString(DrawBuffer &target, const char *str, float x, float
|
|||
|
||||
auto iter = cache_.find(entryHash);
|
||||
if (iter != cache_.end()) {
|
||||
entry = iter->second;
|
||||
entry = iter->second.get();
|
||||
entry->lastUsedFrame = frameCount_;
|
||||
thin3d_->BindTexture(0, entry->texture);
|
||||
} else {
|
||||
|
@ -436,7 +429,7 @@ void TextDrawer::DrawString(DrawBuffer &target, const char *str, float x, float
|
|||
|
||||
delete [] bitmapData;
|
||||
|
||||
cache_[entryHash] = entry;
|
||||
cache_[entryHash] = std::unique_ptr<TextStringEntry>(entry);
|
||||
}
|
||||
float w = entry->bmWidth * fontScaleX_;
|
||||
float h = entry->bmHeight * fontScaleY_;
|
||||
|
@ -489,7 +482,6 @@ void TextDrawer::OncePerFrame() {
|
|||
if (frameCount_ - iter->second->lastUsedFrame > 100) {
|
||||
if (iter->second->texture)
|
||||
iter->second->texture->Release();
|
||||
delete iter->second;
|
||||
cache_.erase(iter++);
|
||||
} else {
|
||||
iter++;
|
||||
|
@ -498,7 +490,6 @@ void TextDrawer::OncePerFrame() {
|
|||
|
||||
for (auto iter = sizeCache_.begin(); iter != sizeCache_.end(); ) {
|
||||
if (frameCount_ - iter->second->lastUsedFrame > 100) {
|
||||
delete iter->second;
|
||||
sizeCache_.erase(iter++);
|
||||
} else {
|
||||
iter++;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "gfx_es2/draw_buffer.h"
|
||||
|
@ -82,6 +83,6 @@ private:
|
|||
|
||||
uint32_t fontHash_;
|
||||
// The key is the CityHash of the string xor the fontHash_.
|
||||
std::map<uint32_t, TextStringEntry *> cache_;
|
||||
std::map<uint32_t, TextMeasureEntry *> sizeCache_;
|
||||
std::map<uint32_t, std::unique_ptr<TextStringEntry> > cache_;
|
||||
std::map<uint32_t, std::unique_ptr<TextMeasureEntry> > sizeCache_;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue