Partial resolution change support

This commit is contained in:
elasota
2020-04-01 14:53:44 -04:00
parent e114d5c5dd
commit 6326a0b2d9
24 changed files with 495 additions and 124 deletions

View File

@@ -22,6 +22,9 @@ namespace PortabilityLayer
void IncrementTickCount(uint32_t count) override;
uint32_t GetTickCount() override;
void SetResolutionChangeHandler(IResolutionChangeHandler *handler) override;
IResolutionChangeHandler *GetResolutionChangeHandler() const override;
static DisplayDeviceManagerImpl *GetInstance();
private:
@@ -29,6 +32,8 @@ namespace PortabilityLayer
GpPixelFormat_t m_pixelFormat;
bool m_paletteIsDirty;
IResolutionChangeHandler *m_resChangeHandler;
PortabilityLayer::RGBAColor *m_palette;
uint8_t m_paletteStorage[256 * sizeof(PortabilityLayer::RGBAColor) + GP_SYSTEM_MEMORY_ALIGNMENT];
@@ -39,6 +44,7 @@ namespace PortabilityLayer
: m_tickCount(1)
, m_paletteIsDirty(true)
, m_pixelFormat(GpPixelFormats::k8BitStandard)
, m_resChangeHandler(nullptr)
{
uint8_t *paletteStorage = m_paletteStorage;
while (reinterpret_cast<intptr_t>(paletteStorage) % GP_SYSTEM_MEMORY_ALIGNMENT != 0)
@@ -93,6 +99,15 @@ namespace PortabilityLayer
return m_tickCount;
}
void DisplayDeviceManagerImpl::SetResolutionChangeHandler(IResolutionChangeHandler *handler)
{
m_resChangeHandler = handler;
}
DisplayDeviceManagerImpl::IResolutionChangeHandler *DisplayDeviceManagerImpl::GetResolutionChangeHandler() const
{
return m_resChangeHandler;
}
DisplayDeviceManagerImpl *DisplayDeviceManagerImpl::GetInstance()
{

View File

@@ -8,10 +8,15 @@
struct IGpDisplayDriver;
namespace PortabilityLayer
{
{
class DisplayDeviceManager
{
public:
public:
struct IResolutionChangeHandler
{
virtual void OnResolutionChanged(uint32_t prevWidth, uint32_t prevHeight, uint32_t newWidth, uint32_t newHeight) = 0;
};
virtual void Init() = 0;
virtual void Shutdown() = 0;
@@ -19,9 +24,14 @@ namespace PortabilityLayer
virtual void SyncPalette(IGpDisplayDriver *displayDriver) = 0;
virtual void IncrementTickCount(uint32_t count) = 0;
virtual uint32_t GetTickCount() = 0;
virtual uint32_t GetTickCount() = 0;
virtual void SetResolutionChangeHandler(IResolutionChangeHandler *handler) = 0;
virtual IResolutionChangeHandler *GetResolutionChangeHandler() const = 0;
static DisplayDeviceManager *GetInstance();
static DisplayDeviceManager *GetInstance();
public:
};
}

View File

@@ -47,6 +47,13 @@ static void TranslateGamepadInputEvent(const GpGamepadInputEvent &vosEvent, Port
PL_DEAD(queue);
}
static void TranslateVideoResolutionChangedEvent(const GpVideoResolutionChangedEvent &evt)
{
PortabilityLayer::DisplayDeviceManager::IResolutionChangeHandler *chgHandler = PortabilityLayer::DisplayDeviceManager::GetInstance()->GetResolutionChangeHandler();
if (chgHandler)
chgHandler->OnResolutionChanged(evt.m_prevWidth, evt.m_prevHeight, evt.m_newWidth, evt.m_newHeight);
}
static void TranslateKeyboardInputEvent(const GpVOSEvent &vosEventBase, uint32_t timestamp, PortabilityLayer::EventQueue *queue)
{
const GpKeyboardInputEvent &vosEvent = vosEventBase.m_event.m_keyboardInputEvent;
@@ -108,6 +115,9 @@ static void TranslateVOSEvent(const GpVOSEvent *vosEvent, uint32_t timestamp, Po
case GpVOSEventTypes::kGamepadInput:
TranslateGamepadInputEvent(vosEvent->m_event.m_gamepadInputEvent, queue);
break;
case GpVOSEventTypes::kVideoResolutionChanged:
TranslateVideoResolutionChangedEvent(vosEvent->m_event.m_resolutionChangedEvent);
break;
}
}

View File

@@ -17,6 +17,8 @@
#include "Vec2i.h"
#include "WindowDef.h"
#include <algorithm>
struct GDevice;
namespace PortabilityLayer
@@ -130,6 +132,8 @@ namespace PortabilityLayer
void RenderFrame(IGpDisplayDriver *displayDriver) override;
void HandleScreenResolutionChange(uint32_t prevWidth, uint32_t prevHeight, uint32_t newWidth, uint32_t newHeight) override;
Window *GetPutInFrontSentinel() const override;
static WindowManagerImpl *GetInstance();
@@ -553,7 +557,13 @@ namespace PortabilityLayer
void WindowImpl::GetChromePadding(uint16_t padding[WindowChromeSides::kCount]) const
{
return m_chromeTheme->GetChromePadding(this, padding);
if (m_chromeTheme)
m_chromeTheme->GetChromePadding(this, padding);
else
{
for (int i = 0; i < WindowChromeSides::kCount; i++)
padding[i] = 0;
}
}
void WindowImpl::GetChromeDimensions(int width, int height, Rect dimensions[WindowChromeSides::kCount]) const
@@ -572,6 +582,9 @@ namespace PortabilityLayer
bool WindowImpl::GetChromeInteractionZone(const Vec2i &point, RegionID_t &outRegion) const
{
if (!m_chromeTheme)
return false;
return m_chromeTheme->GetChromeInteractionZone(this, point, outRegion);
}
@@ -798,6 +811,46 @@ namespace PortabilityLayer
}
}
void WindowManagerImpl::HandleScreenResolutionChange(uint32_t prevWidth, uint32_t prevHeight, uint32_t newWidth, uint32_t newHeight)
{
for (PortabilityLayer::WindowImpl *window = m_windowStackTop; window != nullptr; window = window->GetWindowBelow())
{
uint16_t chromePadding[WindowChromeSides::kCount];
window->GetChromePadding(chromePadding);
const Rect surfaceRect = window->GetDrawSurface()->m_port.GetRect();
uint32_t paddedWidth = surfaceRect.Width() + chromePadding[WindowChromeSides::kLeft] + chromePadding[WindowChromeSides::kRight];
uint32_t paddedHeight = surfaceRect.Height() + chromePadding[WindowChromeSides::kTop] + chromePadding[WindowChromeSides::kBottom];
int64_t newX = 0;
if (newWidth <= paddedWidth || prevWidth <= paddedWidth)
newX = (static_cast<int64_t>(newWidth) - paddedWidth) / 2;
else
{
uint32_t prevClearanceX = prevWidth - paddedWidth;
uint32_t newClearanceX = newWidth - paddedWidth;
newX = static_cast<int64_t>(window->m_wmX) * static_cast<int64_t>(newClearanceX) / static_cast<int64_t>(prevClearanceX);
}
int64_t newY = 0;
if (newHeight <= paddedHeight || prevHeight <= paddedHeight)
newY = (static_cast<int64_t>(newHeight) - paddedHeight) / 2;
else
{
uint32_t prevClearanceY = prevHeight - paddedHeight;
uint32_t newClearanceY = newHeight - paddedHeight;
newY = static_cast<int64_t>(window->m_wmY) * static_cast<int64_t>(newClearanceY) / static_cast<int64_t>(prevClearanceY);
}
newX = std::max<int64_t>(0, std::min<int64_t>(newX, newWidth - 1));
newY = std::max<int64_t>(0, std::min<int64_t>(newY, newHeight - 1));
window->m_wmX = static_cast<int32_t>(newX);
window->m_wmY = static_cast<int32_t>(newY);
}
}
void WindowManagerImpl::ResizeWindow(Window *window, int width, int height)
{
static_cast<WindowImpl*>(window)->Resize(width, height);

View File

@@ -1,5 +1,7 @@
#pragma once
#include <stdint.h>
struct Window;
struct DrawSurface;
struct GDevice;
@@ -30,6 +32,8 @@ namespace PortabilityLayer
virtual void RenderFrame(IGpDisplayDriver *displayDriver) = 0;
virtual void HandleScreenResolutionChange(uint32_t prevWidth, uint32_t prevHeight, uint32_t newWidth, uint32_t newHeight) = 0;
static WindowManager *GetInstance();
};
}

View File

@@ -6,7 +6,7 @@ namespace PortabilityLayer
{
class IOStream;
struct ZipCentralDirectoryFileHeader;
class ZipFileProxy
{
public: