mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-09-24 07:06:36 +00:00
Menu work, move VOS queue interface
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include "HostDisplayDriver.h"
|
||||
#include "HostSystemServices.h"
|
||||
#include "HostVOSEventQueue.h"
|
||||
#include "MenuManager.h"
|
||||
#include "WindowManager.h"
|
||||
|
||||
int gpAppMain();
|
||||
@@ -40,6 +41,7 @@ void GpAppInterfaceImpl::PL_IncrementTickCounter(uint32_t count)
|
||||
void GpAppInterfaceImpl::PL_Render(IGpDisplayDriver *displayDriver)
|
||||
{
|
||||
PortabilityLayer::WindowManager::GetInstance()->RenderFrame(displayDriver);
|
||||
PortabilityLayer::MenuManager::GetInstance()->RenderFrame(displayDriver);
|
||||
}
|
||||
|
||||
void GpAppInterfaceImpl::PL_HostFileSystem_SetInstance(PortabilityLayer::HostFileSystem *instance)
|
||||
|
@@ -4,6 +4,7 @@
|
||||
|
||||
struct IGpDisplayDriver;
|
||||
struct IGpFiber;
|
||||
struct IGpVOSEventQueue;
|
||||
|
||||
struct GpDisplayDriverProperties
|
||||
{
|
||||
@@ -29,4 +30,6 @@ struct GpDisplayDriverProperties
|
||||
|
||||
RenderFunc_t m_renderFunc;
|
||||
void *m_renderFuncContext;
|
||||
|
||||
IGpVOSEventQueue *m_eventQueue;
|
||||
};
|
||||
|
@@ -1,5 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
namespace GpKeyModifiers
|
||||
{
|
||||
enum GpKeyModifier
|
||||
{
|
||||
kShift,
|
||||
kCtrl,
|
||||
};
|
||||
}
|
||||
|
||||
namespace GpKeyIDSubsets
|
||||
{
|
||||
enum GpKeyIDSubset
|
||||
@@ -43,9 +52,9 @@ namespace GpKeySpecials
|
||||
|
||||
typedef GpKeySpecials::GpKeySpecial GpKeySpecial_t;
|
||||
|
||||
namespace GpInputEventTypes
|
||||
namespace GpKeyboardInputEventTypes
|
||||
{
|
||||
enum GpInputEventType
|
||||
enum GpKeyboardInputEventType
|
||||
{
|
||||
kDown,
|
||||
kUp,
|
||||
@@ -53,19 +62,9 @@ namespace GpInputEventTypes
|
||||
};
|
||||
}
|
||||
|
||||
typedef GpInputEventTypes::GpInputEventType GpInputEventType_t;
|
||||
typedef GpKeyboardInputEventTypes::GpKeyboardInputEventType GpKeyboardInputEventType_t;
|
||||
|
||||
namespace GpVOSEventTypes
|
||||
{
|
||||
enum GpVOSEventType
|
||||
{
|
||||
kInput,
|
||||
};
|
||||
}
|
||||
|
||||
typedef GpVOSEventTypes::GpVOSEventType GpVOSEventType_t;
|
||||
|
||||
struct GpInputEvent
|
||||
struct GpKeyboardInputEvent
|
||||
{
|
||||
union KeyUnion
|
||||
{
|
||||
@@ -73,17 +72,66 @@ struct GpInputEvent
|
||||
char m_asciiChar;
|
||||
};
|
||||
|
||||
GpInputEventType_t m_eventType;
|
||||
GpKeyboardInputEventType_t m_eventType;
|
||||
GpKeyIDSubset_t m_keyIDSubset;
|
||||
KeyUnion m_key;
|
||||
};
|
||||
|
||||
namespace GpMouseEventTypes
|
||||
{
|
||||
enum GpMouseEventType
|
||||
{
|
||||
kUp,
|
||||
kDown,
|
||||
kMove,
|
||||
kLeave,
|
||||
};
|
||||
}
|
||||
|
||||
typedef GpMouseEventTypes::GpMouseEventType GpMouseEventType_t;
|
||||
|
||||
namespace GpMouseButtons
|
||||
{
|
||||
enum GpMouseButton
|
||||
{
|
||||
kNone,
|
||||
kLeft,
|
||||
kMiddle,
|
||||
kRight,
|
||||
kX1,
|
||||
kX2,
|
||||
};
|
||||
}
|
||||
|
||||
typedef GpMouseButtons::GpMouseButton GpMouseButton_t;
|
||||
|
||||
struct GpMouseInputEvent
|
||||
{
|
||||
int32_t m_x;
|
||||
int32_t m_y;
|
||||
GpMouseEventType_t m_eventType;
|
||||
GpMouseButton_t m_button;
|
||||
};
|
||||
|
||||
namespace GpVOSEventTypes
|
||||
{
|
||||
enum GpVOSEventType
|
||||
{
|
||||
kKeyboardInput,
|
||||
kMouseInput,
|
||||
};
|
||||
}
|
||||
|
||||
typedef GpVOSEventTypes::GpVOSEventType GpVOSEventType_t;
|
||||
|
||||
struct GpVOSEvent
|
||||
{
|
||||
union EventUnion
|
||||
{
|
||||
GpInputEvent m_inputEvent;
|
||||
GpKeyboardInputEvent m_keyboardInputEvent;
|
||||
GpMouseInputEvent m_mouseInputEvent;
|
||||
};
|
||||
|
||||
EventUnion m_event;
|
||||
GpVOSEventType_t m_eventType;
|
||||
};
|
||||
|
@@ -10,6 +10,7 @@
|
||||
|
||||
struct IGpFiber;
|
||||
struct IGpColorCursor_Win32;
|
||||
struct IGpVOSEventQueue;
|
||||
|
||||
struct GpWindowsGlobals
|
||||
{
|
||||
@@ -21,5 +22,6 @@ struct GpWindowsGlobals
|
||||
|
||||
IGpFiber *(*m_createFiberFunc)(LPVOID fiber);
|
||||
IGpColorCursor_Win32 *(*m_loadColorCursorFunc)(const wchar_t *path);
|
||||
void (*m_translateWindowsMessageFunc)(const MSG *msg, IGpVOSEventQueue *eventQueue);
|
||||
};
|
||||
|
||||
|
11
GpCommon/IGpVOSEventQueue.h
Normal file
11
GpCommon/IGpVOSEventQueue.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
struct GpVOSEvent;
|
||||
|
||||
struct IGpVOSEventQueue
|
||||
{
|
||||
virtual const GpVOSEvent *GetNext() = 0;
|
||||
virtual void DischargeOne() = 0;
|
||||
|
||||
virtual GpVOSEvent *QueueEvent() = 0;
|
||||
};
|
@@ -14,6 +14,7 @@ GpAppEnvironment::GpAppEnvironment()
|
||||
, m_displayDriver(nullptr)
|
||||
, m_audioDriver(nullptr)
|
||||
, m_fontHandler(nullptr)
|
||||
, m_vosEventQueue(nullptr)
|
||||
, m_applicationFiber(nullptr)
|
||||
, m_vosFiber(nullptr)
|
||||
, m_suspendCallID(PortabilityLayer::HostSuspendCallID_Unknown)
|
||||
@@ -100,6 +101,11 @@ void GpAppEnvironment::SetFontHandler(PortabilityLayer::HostFontHandler *fontHan
|
||||
m_fontHandler = fontHandler;
|
||||
}
|
||||
|
||||
void GpAppEnvironment::SetVOSEventQueue(GpVOSEventQueue *eventQueue)
|
||||
{
|
||||
m_vosEventQueue = eventQueue;
|
||||
}
|
||||
|
||||
void GpAppEnvironment::StaticAppThreadFunc(void *context)
|
||||
{
|
||||
static_cast<GpAppEnvironment*>(context)->AppThreadFunc();
|
||||
@@ -117,7 +123,7 @@ void GpAppEnvironment::InitializeApplicationState()
|
||||
GpAppInterface_Get()->PL_InstallHostSuspendHook(GpAppEnvironment::StaticSuspendHookFunc, this);
|
||||
|
||||
GpAppInterface_Get()->PL_HostFontHandler_SetInstance(m_fontHandler);
|
||||
GpAppInterface_Get()->PL_HostVOSEventQueue_SetInstance(&m_vosEventQueue);
|
||||
GpAppInterface_Get()->PL_HostVOSEventQueue_SetInstance(m_vosEventQueue);
|
||||
|
||||
SynchronizeState();
|
||||
}
|
||||
|
@@ -30,6 +30,7 @@ public:
|
||||
void SetDisplayDriver(IGpDisplayDriver *displayDriver);
|
||||
void SetAudioDriver(IGpAudioDriver *audioDriver);
|
||||
void SetFontHandler(PortabilityLayer::HostFontHandler *fontHandler);
|
||||
void SetVOSEventQueue(GpVOSEventQueue *eventQueue);
|
||||
|
||||
private:
|
||||
enum ApplicationState
|
||||
@@ -54,7 +55,7 @@ private:
|
||||
IGpDisplayDriver *m_displayDriver;
|
||||
IGpAudioDriver *m_audioDriver;
|
||||
PortabilityLayer::HostFontHandler *m_fontHandler;
|
||||
GpVOSEventQueue m_vosEventQueue;
|
||||
GpVOSEventQueue *m_vosEventQueue;
|
||||
IGpFiber *m_applicationFiber;
|
||||
IGpFiber *m_vosFiber;
|
||||
|
||||
|
BIN
GpD3D/GpD3D.rc
BIN
GpD3D/GpD3D.rc
Binary file not shown.
@@ -26,6 +26,7 @@ namespace
|
||||
|
||||
int GpMain::Run()
|
||||
{
|
||||
GpVOSEventQueue *eventQueue = new GpVOSEventQueue();
|
||||
GpAppEnvironment *appEnvironment = new GpAppEnvironment();
|
||||
|
||||
GpDisplayDriverProperties ddProps;
|
||||
@@ -50,6 +51,7 @@ int GpMain::Run()
|
||||
|
||||
ddProps.m_type = g_gpGlobalConfig.m_displayDriverType;
|
||||
ddProps.m_osGlobals = g_gpGlobalConfig.m_osGlobals;
|
||||
ddProps.m_eventQueue = eventQueue;
|
||||
|
||||
GpAudioDriverProperties adProps;
|
||||
memset(&adProps, 0, sizeof(adProps));
|
||||
@@ -69,6 +71,7 @@ int GpMain::Run()
|
||||
appEnvironment->SetDisplayDriver(displayDriver);
|
||||
appEnvironment->SetAudioDriver(audioDriver);
|
||||
appEnvironment->SetFontHandler(fontHandler);
|
||||
appEnvironment->SetVOSEventQueue(eventQueue);
|
||||
|
||||
// Start the display loop
|
||||
displayDriver->Run();
|
||||
|
@@ -7,18 +7,83 @@
|
||||
#include "GpFileSystem_Win32.h"
|
||||
#include "GpAppInterface.h"
|
||||
#include "GpSystemServices_Win32.h"
|
||||
#include "GpVOSEvent.h"
|
||||
#include "IGpVOSEventQueue.h"
|
||||
|
||||
#include "HostFileSystem.h"
|
||||
|
||||
#include "GpWindows.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
GpWindowsGlobals g_gpWindowsGlobals;
|
||||
|
||||
extern "C" __declspec(dllimport) IGpAudioDriver *GpDriver_CreateAudioDriver_XAudio2(const GpAudioDriverProperties &properties);
|
||||
extern "C" __declspec(dllimport) IGpDisplayDriver *GpDriver_CreateDisplayDriver_D3D11(const GpDisplayDriverProperties &properties);
|
||||
|
||||
static void PostMouseEvent(IGpVOSEventQueue *eventQueue, GpMouseEventType_t eventType, GpMouseButton_t button, int32_t x, int32_t y)
|
||||
{
|
||||
if (GpVOSEvent *evt = eventQueue->QueueEvent())
|
||||
{
|
||||
evt->m_eventType = GpVOSEventTypes::kMouseInput;
|
||||
|
||||
GpMouseInputEvent &mEvent = evt->m_event.m_mouseInputEvent;
|
||||
mEvent.m_button = button;
|
||||
mEvent.m_x = x;
|
||||
mEvent.m_y = y;
|
||||
mEvent.m_eventType = eventType;
|
||||
}
|
||||
}
|
||||
|
||||
static void TranslateWindowsMessage(const MSG *msg, IGpVOSEventQueue *eventQueue)
|
||||
{
|
||||
WPARAM wParam = msg->wParam;
|
||||
LPARAM lParam = msg->lParam;
|
||||
|
||||
switch (msg->message)
|
||||
{
|
||||
case WM_LBUTTONDOWN:
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kLeft, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kLeft, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
break;
|
||||
case WM_MBUTTONDOWN:
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kMiddle, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
break;
|
||||
case WM_MBUTTONUP:
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kMiddle, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kRight, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
break;
|
||||
case WM_RBUTTONUP:
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kRight, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
break;
|
||||
case WM_XBUTTONDOWN:
|
||||
if (GET_XBUTTON_WPARAM(wParam) == XBUTTON1)
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kX1, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
else if (GET_XBUTTON_WPARAM(wParam) == XBUTTON2)
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kX2, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
break;
|
||||
case WM_XBUTTONUP:
|
||||
if (GET_XBUTTON_WPARAM(wParam) == XBUTTON1)
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kX1, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
else if (GET_XBUTTON_WPARAM(wParam) == XBUTTON2)
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kX2, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kMove, GpMouseButtons::kNone, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
break;
|
||||
case WM_MOUSELEAVE:
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kLeave, GpMouseButtons::kNone, 0, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
GpAppInterface_Get()->PL_HostFileSystem_SetInstance(GpFileSystem_Win32::GetInstance());
|
||||
@@ -32,6 +97,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
|
||||
g_gpWindowsGlobals.m_createFiberFunc = GpFiber_Win32::Create;
|
||||
g_gpWindowsGlobals.m_loadColorCursorFunc = GpColorCursor_Win32::Load;
|
||||
g_gpWindowsGlobals.m_translateWindowsMessageFunc = TranslateWindowsMessage;
|
||||
|
||||
g_gpGlobalConfig.m_displayDriverType = EGpDisplayDriverType_D3D11;
|
||||
g_gpGlobalConfig.m_osGlobals = &g_gpWindowsGlobals;
|
||||
|
@@ -1,40 +1,40 @@
|
||||
#include "GpPLGlueDisplayDriver.h"
|
||||
#include "VirtualDirectory.h"
|
||||
#include "IGpDisplayDriver.h"
|
||||
|
||||
GpPLGlueDisplayDriver::GpPLGlueDisplayDriver()
|
||||
: m_displayDriver(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void GpPLGlueDisplayDriver::GetDisplayResolution(unsigned int *width, unsigned int *height, GpPixelFormat_t *bpp)
|
||||
{
|
||||
m_displayDriver->GetDisplayResolution(width, height, bpp);
|
||||
#include "VirtualDirectory.h"
|
||||
#include "IGpDisplayDriver.h"
|
||||
|
||||
GpPLGlueDisplayDriver::GpPLGlueDisplayDriver()
|
||||
: m_displayDriver(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void GpPLGlueDisplayDriver::GetDisplayResolution(unsigned int *width, unsigned int *height, GpPixelFormat_t *bpp)
|
||||
{
|
||||
m_displayDriver->GetDisplayResolution(width, height, bpp);
|
||||
}
|
||||
|
||||
IGpColorCursor *GpPLGlueDisplayDriver::LoadColorCursor(int cursorID)
|
||||
{
|
||||
return m_displayDriver->LoadColorCursor(cursorID);
|
||||
}
|
||||
|
||||
void GpPLGlueDisplayDriver::SetColorCursor(IGpColorCursor *colorCursor)
|
||||
{
|
||||
m_displayDriver->SetColorCursor(colorCursor);
|
||||
return m_displayDriver->LoadColorCursor(cursorID);
|
||||
}
|
||||
|
||||
|
||||
void GpPLGlueDisplayDriver::SetColorCursor(IGpColorCursor *colorCursor)
|
||||
{
|
||||
m_displayDriver->SetColorCursor(colorCursor);
|
||||
}
|
||||
|
||||
void GpPLGlueDisplayDriver::SetStandardCursor(EGpStandardCursor_t standardCursor)
|
||||
{
|
||||
m_displayDriver->SetStandardCursor(standardCursor);
|
||||
}
|
||||
|
||||
GpPLGlueDisplayDriver *GpPLGlueDisplayDriver::GetInstance()
|
||||
{
|
||||
return &ms_instance;
|
||||
}
|
||||
|
||||
void GpPLGlueDisplayDriver::SetGpDisplayDriver(IGpDisplayDriver *displayDriver)
|
||||
{
|
||||
m_displayDriver = displayDriver;
|
||||
}
|
||||
|
||||
GpPLGlueDisplayDriver GpPLGlueDisplayDriver::ms_instance;
|
||||
m_displayDriver->SetStandardCursor(standardCursor);
|
||||
}
|
||||
|
||||
GpPLGlueDisplayDriver *GpPLGlueDisplayDriver::GetInstance()
|
||||
{
|
||||
return &ms_instance;
|
||||
}
|
||||
|
||||
void GpPLGlueDisplayDriver::SetGpDisplayDriver(IGpDisplayDriver *displayDriver)
|
||||
{
|
||||
m_displayDriver = displayDriver;
|
||||
}
|
||||
|
||||
GpPLGlueDisplayDriver GpPLGlueDisplayDriver::ms_instance;
|
||||
|
@@ -3,10 +3,10 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "HostVOSEventQueue.h"
|
||||
#include "GpVOSEvent.h"
|
||||
#include "GpVOSEvent.h"
|
||||
|
||||
class GpVOSEventQueue final : public PortabilityLayer::HostVOSEventQueue
|
||||
{
|
||||
{
|
||||
public:
|
||||
GpVOSEventQueue();
|
||||
~GpVOSEventQueue();
|
||||
@@ -14,7 +14,7 @@ public:
|
||||
const GpVOSEvent *GetNext() override;
|
||||
void DischargeOne() override;
|
||||
|
||||
GpVOSEvent *QueueEvent();
|
||||
GpVOSEvent *QueueEvent() override;
|
||||
|
||||
private:
|
||||
static const size_t kMaxEvents = 10000;
|
||||
|
@@ -565,10 +565,29 @@ void GpDisplayDriverD3D11::Run()
|
||||
|
||||
if (msg.message == WM_QUIT)
|
||||
break;
|
||||
else if (msg.message == WM_MOUSEMOVE)
|
||||
m_mouseIsInClientArea = true;
|
||||
else if (msg.message == WM_MOUSELEAVE)
|
||||
m_mouseIsInClientArea = false;
|
||||
else
|
||||
{
|
||||
if (msg.message == WM_MOUSEMOVE)
|
||||
{
|
||||
if (!m_mouseIsInClientArea)
|
||||
{
|
||||
m_mouseIsInClientArea = true;
|
||||
|
||||
TRACKMOUSEEVENT tme;
|
||||
ZeroMemory(&tme, sizeof(tme));
|
||||
|
||||
tme.cbSize = sizeof(tme);
|
||||
tme.dwFlags = TME_LEAVE;
|
||||
tme.hwndTrack = m_hwnd;
|
||||
tme.dwHoverTime = HOVER_DEFAULT;
|
||||
TrackMouseEvent(&tme);
|
||||
}
|
||||
}
|
||||
else if (msg.message == WM_MOUSELEAVE)
|
||||
m_mouseIsInClientArea = false;
|
||||
|
||||
m_osGlobals->m_translateWindowsMessageFunc(&msg, m_properties.m_eventQueue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -25,6 +25,7 @@ namespace PortabilityLayer
|
||||
FontFamily *GetApplicationFont(int textSize, int variationFlags) const override;
|
||||
|
||||
RenderedFont *GetRenderedFont(HostFont *font, int size, FontHacks fontHacks) override;
|
||||
RenderedFont *GetRenderedFontFromFamily(FontFamily *font, int size, int flags) override;
|
||||
|
||||
static FontManagerImpl *GetInstance();
|
||||
|
||||
@@ -157,6 +158,17 @@ namespace PortabilityLayer
|
||||
return rfont;
|
||||
}
|
||||
|
||||
RenderedFont *FontManagerImpl::GetRenderedFontFromFamily(FontFamily *fontFamily, int size, int flags)
|
||||
{
|
||||
const int variation = fontFamily->GetVariationForFlags(flags);
|
||||
|
||||
PortabilityLayer::HostFont *hostFont = fontFamily->GetFontForVariation(variation);
|
||||
if (!hostFont)
|
||||
return nullptr;
|
||||
|
||||
return PortabilityLayer::FontManager::GetInstance()->GetRenderedFont(hostFont, size, fontFamily->GetHacksForVariation(variation));
|
||||
}
|
||||
|
||||
FontManagerImpl *FontManagerImpl::GetInstance()
|
||||
{
|
||||
return &ms_instance;
|
||||
|
@@ -18,6 +18,7 @@ namespace PortabilityLayer
|
||||
virtual FontFamily *GetApplicationFont(int fontSize, int variationFlags) const = 0;
|
||||
|
||||
virtual RenderedFont *GetRenderedFont(HostFont *font, int size, FontHacks fontHacks) = 0;
|
||||
virtual RenderedFont *GetRenderedFontFromFamily(FontFamily *fontFamily, int fontSize, int flags) = 0;
|
||||
|
||||
static FontManager *GetInstance();
|
||||
};
|
||||
|
@@ -5,6 +5,7 @@
|
||||
#include "HostFontHandler.h"
|
||||
#include "HostFontRenderedGlyph.h"
|
||||
#include "MacRoman.h"
|
||||
#include "PLPasStr.h"
|
||||
#include "RenderedFont.h"
|
||||
#include "RenderedGlyphMetrics.h"
|
||||
|
||||
@@ -19,6 +20,7 @@ namespace PortabilityLayer
|
||||
{
|
||||
public:
|
||||
bool GetGlyph(unsigned int character, const RenderedGlyphMetrics **outMetricsPtr, const void **outData) const override;
|
||||
size_t MeasureString(const uint8_t *chars, size_t len) const override;
|
||||
|
||||
void Destroy() override;
|
||||
|
||||
@@ -59,6 +61,19 @@ namespace PortabilityLayer
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t RenderedFontImpl::MeasureString(const uint8_t *chars, size_t len) const
|
||||
{
|
||||
size_t measure = 0;
|
||||
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
const RenderedGlyphMetrics &metrics = m_metrics[chars[i]];
|
||||
measure += metrics.m_advanceX;
|
||||
}
|
||||
|
||||
return measure;
|
||||
}
|
||||
|
||||
void RenderedFontImpl::Destroy()
|
||||
{
|
||||
this->~RenderedFontImpl();
|
||||
|
@@ -1,15 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
struct GpVOSEvent;
|
||||
#include "IGpVOSEventQueue.h"
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
class HostVOSEventQueue
|
||||
class HostVOSEventQueue : public IGpVOSEventQueue
|
||||
{
|
||||
public:
|
||||
virtual const GpVOSEvent *GetNext() = 0;
|
||||
virtual void DischargeOne() = 0;
|
||||
|
||||
static void SetInstance(HostVOSEventQueue *instance);
|
||||
static HostVOSEventQueue *GetInstance();
|
||||
|
||||
|
@@ -1,7 +1,60 @@
|
||||
#include "MenuManager.h"
|
||||
#include "PLBigEndian.h"
|
||||
#include "DisplayDeviceManager.h"
|
||||
#include "FontFamily.h"
|
||||
#include "FontManager.h"
|
||||
#include "HostDisplayDriver.h"
|
||||
#include "HostFont.h"
|
||||
#include "IGpDisplayDriver.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "SimpleGraphic.h"
|
||||
#include "PLBigEndian.h"
|
||||
#include "PLCore.h"
|
||||
#include "PLPasStr.h"
|
||||
#include "PLResources.h"
|
||||
#include "PLQDOffscreen.h"
|
||||
#include "RenderedFont.h"
|
||||
#include "QDGraf.h"
|
||||
#include "QDManager.h"
|
||||
#include "QDPixMap.h"
|
||||
#include "RGBAColor.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
const PortabilityLayer::RGBAColor gs_barTopLeftCornerGraphicPixels[] =
|
||||
{
|
||||
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 85, 85, 85, 255 }, { 170, 170, 170, 255 },
|
||||
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 85, 85, 85, 255 }, { 255, 255, 255, 255 }, { 255, 255, 255, 255 },
|
||||
{ 0, 0, 0, 255 }, { 85, 85, 85, 255 }, { 255, 255, 255, 255 }, { 221, 221, 221, 255 }, { 221, 221, 221, 255 },
|
||||
{ 85, 85, 85, 255 }, { 255, 255, 255, 255 }, { 221, 221, 221, 255 }, { 221, 221, 221, 255 }, { 221, 221, 221, 255 },
|
||||
{ 170, 170, 170, 255 }, { 255, 255, 255, 255 }, { 221, 221, 221, 255 }, { 221, 221, 221, 255 }, { 221, 221, 221, 255 },
|
||||
};
|
||||
|
||||
const PortabilityLayer::RGBAColor gs_barTopRightCornerGraphicPixels[] =
|
||||
{
|
||||
{ 170, 170, 170, 255 }, { 85, 85, 85, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
|
||||
{ 255, 255, 255, 255 }, { 255, 255, 255, 255 }, { 85, 85, 85, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
|
||||
{ 221, 221, 221, 255 }, { 221, 221, 221, 255 }, { 255, 255, 255, 255 }, { 85, 85, 85, 255 }, { 0, 0, 0, 255 },
|
||||
{ 221, 221, 221, 255 }, { 221, 221, 221, 255 }, { 221, 221, 221, 255 }, { 255, 255, 255, 255 }, { 85, 85, 85, 255 },
|
||||
{ 221, 221, 221, 255 }, { 221, 221, 221, 255 }, { 221, 221, 221, 255 }, { 255, 255, 255, 255 }, { 85, 85, 85, 255 },
|
||||
};
|
||||
|
||||
const PortabilityLayer::RGBAColor gs_barBrightColor = { 255, 255, 255, 255 };
|
||||
const PortabilityLayer::RGBAColor gs_barMidColor = { 221, 221, 221, 255 };
|
||||
const PortabilityLayer::RGBAColor gs_barDarkColor = { 102, 102, 102, 255 };
|
||||
const PortabilityLayer::RGBAColor gs_barBottomEdgeColor = { 0, 0, 0, 255 };
|
||||
const PortabilityLayer::RGBAColor gs_barNormalTextColor = { 0, 0, 0, 255 };
|
||||
|
||||
const PortabilityLayer::RGBAColor gs_barHighlightBrightColor = { 153, 153, 255, 255 };
|
||||
const PortabilityLayer::RGBAColor gs_barHighlightMidColor = { 102, 102, 204, 255 };
|
||||
const PortabilityLayer::RGBAColor gs_barHighlightDarkColor = { 51, 51, 102, 255 };
|
||||
|
||||
PortabilityLayer::SimpleGraphicInstanceRGBA<5, 5> gs_barTopLeftCornerGraphic(gs_barTopLeftCornerGraphicPixels);
|
||||
PortabilityLayer::SimpleGraphicInstanceRGBA<5, 5> gs_barTopRightCornerGraphic(gs_barTopRightCornerGraphicPixels);
|
||||
}
|
||||
|
||||
struct MenuItem
|
||||
{
|
||||
@@ -21,13 +74,20 @@ struct Menu
|
||||
uint16_t height;
|
||||
uint16_t commandID;
|
||||
bool enabled;
|
||||
bool isIcon;
|
||||
|
||||
PortabilityLayer::MMHandleBlock *stringBlobHandle;
|
||||
|
||||
Menu **prevMenu;
|
||||
Menu **nextMenu;
|
||||
|
||||
// Refreshed on layout
|
||||
size_t cumulativeOffset;
|
||||
unsigned int menuIndex;
|
||||
|
||||
size_t numMenuItems;
|
||||
|
||||
// This must be the last item
|
||||
MenuItem menuItems[1];
|
||||
};
|
||||
|
||||
@@ -39,6 +99,9 @@ namespace PortabilityLayer
|
||||
MenuManagerImpl();
|
||||
~MenuManagerImpl();
|
||||
|
||||
virtual void Init() override;
|
||||
virtual void Shutdown() override;
|
||||
|
||||
Menu **DeserializeMenu(const void *resData) const override;
|
||||
Menu **GetMenuByID(int id) const override;
|
||||
void InsertMenuBefore(Menu **insertingMenu, Menu **existingMenu) override;
|
||||
@@ -49,18 +112,46 @@ namespace PortabilityLayer
|
||||
void SetItemEnabled(Menu **menu, unsigned int index, bool enabled) override;
|
||||
void SetItemChecked(Menu **menu, unsigned int index, bool checked) override;
|
||||
|
||||
void DrawMenuBar() override;
|
||||
|
||||
void RenderFrame(IGpDisplayDriver *displayDriver) override;
|
||||
|
||||
static MenuManagerImpl *GetInstance();
|
||||
|
||||
private:
|
||||
void RefreshMenuLayout();
|
||||
|
||||
static const unsigned int kIconResID = 128;
|
||||
static const unsigned int kMenuFontSize = 12;
|
||||
static const unsigned int kMenuBarIconYOffset = 2;
|
||||
static const unsigned int kMenuBarTextYOffset = 14;
|
||||
static const unsigned int kMenuBarHeight = 20;
|
||||
static const unsigned int kMenuBarItemPadding = 6;
|
||||
static const unsigned int kMenuBarInitialPadding = 16;
|
||||
static const int kMenuFontFlags = PortabilityLayer::FontFamilyFlag_Bold;
|
||||
|
||||
CGraf *m_menuBarGraf;
|
||||
|
||||
Menu **m_firstMenu;
|
||||
Menu **m_lastMenu;
|
||||
bool m_haveMenuLayout;
|
||||
bool m_haveIcon;
|
||||
|
||||
uint8_t m_iconColors[16 * 16];
|
||||
uint8_t m_iconMask[32];
|
||||
|
||||
SimpleGraphic *m_iconGraphic;
|
||||
|
||||
static MenuManagerImpl ms_instance;
|
||||
};
|
||||
|
||||
MenuManagerImpl::MenuManagerImpl()
|
||||
: m_firstMenu(nullptr)
|
||||
: m_menuBarGraf(nullptr)
|
||||
, m_firstMenu(nullptr)
|
||||
, m_lastMenu(nullptr)
|
||||
, m_haveMenuLayout(false)
|
||||
, m_haveIcon(false)
|
||||
, m_iconGraphic(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -68,6 +159,26 @@ namespace PortabilityLayer
|
||||
{
|
||||
}
|
||||
|
||||
void MenuManagerImpl::Init()
|
||||
{
|
||||
}
|
||||
|
||||
void MenuManagerImpl::Shutdown()
|
||||
{
|
||||
PortabilityLayer::QDManager *qdManager = PortabilityLayer::QDManager::GetInstance();
|
||||
|
||||
if (m_menuBarGraf)
|
||||
qdManager->DisposeGWorld(m_menuBarGraf);
|
||||
|
||||
if (m_iconGraphic)
|
||||
{
|
||||
m_iconGraphic->~SimpleGraphic();
|
||||
free(m_iconGraphic);
|
||||
}
|
||||
|
||||
// GP TODO: Dispose of menus properly
|
||||
}
|
||||
|
||||
Menu **MenuManagerImpl::DeserializeMenu(const void *resData) const
|
||||
{
|
||||
PortabilityLayer::MemoryManager *mm = PortabilityLayer::MemoryManager::GetInstance();
|
||||
@@ -122,6 +233,9 @@ namespace PortabilityLayer
|
||||
menu->height = header.height;
|
||||
menu->commandID = header.commandID;
|
||||
menu->enabled = ((enableFlags & 1) != 0);
|
||||
menu->menuIndex = 0;
|
||||
menu->cumulativeOffset = 0;
|
||||
menu->isIcon = false;
|
||||
|
||||
uint8_t *stringDataStart = static_cast<uint8_t*>(stringData->m_contents);
|
||||
uint8_t *stringDest = stringDataStart;
|
||||
@@ -172,6 +286,8 @@ namespace PortabilityLayer
|
||||
|
||||
void MenuManagerImpl::InsertMenuBefore(Menu **insertingMenu, Menu **existingMenu)
|
||||
{
|
||||
m_haveMenuLayout = false;
|
||||
|
||||
Menu *insertingMenuPtr = *insertingMenu;
|
||||
Menu *existingMenuPtr = *existingMenu;
|
||||
|
||||
@@ -188,6 +304,8 @@ namespace PortabilityLayer
|
||||
|
||||
void MenuManagerImpl::InsertMenuAfter(Menu **insertingMenu, Menu **existingMenu)
|
||||
{
|
||||
m_haveMenuLayout = false;
|
||||
|
||||
Menu *insertingMenuPtr = *insertingMenu;
|
||||
Menu *existingMenuPtr = *existingMenu;
|
||||
|
||||
@@ -204,6 +322,8 @@ namespace PortabilityLayer
|
||||
|
||||
void MenuManagerImpl::InsertMenuAtEnd(Menu **insertingMenu)
|
||||
{
|
||||
m_haveMenuLayout = false;
|
||||
|
||||
if (m_firstMenu == nullptr)
|
||||
{
|
||||
m_firstMenu = m_lastMenu = insertingMenu;
|
||||
@@ -217,6 +337,8 @@ namespace PortabilityLayer
|
||||
|
||||
void MenuManagerImpl::InsertMenuAtBeginning(Menu **insertingMenu)
|
||||
{
|
||||
m_haveMenuLayout = false;
|
||||
|
||||
if (m_firstMenu == nullptr)
|
||||
{
|
||||
m_firstMenu = m_lastMenu = insertingMenu;
|
||||
@@ -255,6 +377,228 @@ namespace PortabilityLayer
|
||||
menu->menuItems[index].checked = checked;
|
||||
}
|
||||
|
||||
void MenuManagerImpl::DrawMenuBar()
|
||||
{
|
||||
if (!m_haveIcon)
|
||||
{
|
||||
ResourceManager *resManager = ResourceManager::GetInstance();
|
||||
|
||||
Handle icsHandle = GetResource('ics#', kIconResID);
|
||||
Handle ics8Handle = GetResource('ics8', kIconResID);
|
||||
|
||||
if (icsHandle && ics8Handle)
|
||||
{
|
||||
typedef SimpleGraphicInstanceStandardPalette<16, 16> GraphicType_t;
|
||||
|
||||
void *storage = static_cast<GraphicType_t*>(malloc(sizeof(GraphicType_t)));
|
||||
if (storage)
|
||||
{
|
||||
memcpy(m_iconMask, static_cast<const uint8_t*>(*icsHandle) + 32, 32);
|
||||
memcpy(m_iconColors, static_cast<const uint8_t*>(*ics8Handle), 16 * 16);
|
||||
|
||||
GraphicType_t *graphic = new (storage) GraphicType_t(m_iconColors);
|
||||
|
||||
m_iconGraphic = graphic;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (icsHandle)
|
||||
ReleaseResource(icsHandle);
|
||||
|
||||
if (ics8Handle)
|
||||
ReleaseResource(ics8Handle);
|
||||
|
||||
m_haveIcon = true;
|
||||
}
|
||||
|
||||
unsigned int width;
|
||||
GpPixelFormat_t pixelFormat;
|
||||
PortabilityLayer::HostDisplayDriver::GetInstance()->GetDisplayResolution(&width, nullptr, &pixelFormat);
|
||||
|
||||
PortabilityLayer::QDManager *qdManager = PortabilityLayer::QDManager::GetInstance();
|
||||
|
||||
const Rect menuRect = Rect::Create(0, 0, kMenuBarHeight, width);
|
||||
|
||||
if (m_menuBarGraf == nullptr)
|
||||
{
|
||||
int depth = 0;
|
||||
|
||||
switch (pixelFormat)
|
||||
{
|
||||
case GpPixelFormats::k8BitStandard:
|
||||
depth = 8;
|
||||
break;
|
||||
default:
|
||||
PL_NotYetImplemented();
|
||||
return;
|
||||
}
|
||||
|
||||
if (qdManager->NewGWorld(&m_menuBarGraf, depth, menuRect, nullptr, nullptr, 0) != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
CGraf *graf = m_menuBarGraf;
|
||||
|
||||
assert(graf);
|
||||
|
||||
if (static_cast<unsigned int>(graf->m_port.GetRect().right) != width)
|
||||
{
|
||||
if (!graf->m_port.Resize(menuRect))
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
RefreshMenuLayout();
|
||||
|
||||
CGraf *oldGraf;
|
||||
GDHandle oldDevice;
|
||||
GetGWorld(&oldGraf, &oldDevice);
|
||||
|
||||
SetGWorld(m_menuBarGraf, nullptr);
|
||||
|
||||
PortabilityLayer::QDState *qdState = qdManager->GetState();
|
||||
|
||||
qdState->SetForeColor(gs_barMidColor);
|
||||
PaintRect(&menuRect);
|
||||
|
||||
qdState->SetForeColor(gs_barBrightColor);
|
||||
|
||||
// Top stripe
|
||||
{
|
||||
const Rect rect = Rect::Create(0, 0, 1, static_cast<int16_t>(width) - 1);
|
||||
PaintRect(&rect);
|
||||
}
|
||||
|
||||
// Left stripe
|
||||
{
|
||||
const Rect rect = Rect::Create(0, 0, kMenuBarHeight - 1, 1);
|
||||
PaintRect(&rect);
|
||||
}
|
||||
|
||||
qdState->SetForeColor(gs_barDarkColor);
|
||||
|
||||
// Bottom stripe
|
||||
{
|
||||
const Rect rect = Rect::Create(kMenuBarHeight - 2, 1, kMenuBarHeight - 1, width);
|
||||
PaintRect(&rect);
|
||||
}
|
||||
|
||||
// Right stripe
|
||||
{
|
||||
const Rect rect = Rect::Create(0, width - 1, kMenuBarHeight - 1, width);
|
||||
PaintRect(&rect);
|
||||
}
|
||||
|
||||
qdState->SetForeColor(gs_barBottomEdgeColor);
|
||||
|
||||
// Bottom edge
|
||||
{
|
||||
const Rect rect = Rect::Create(kMenuBarHeight - 1, 0, kMenuBarHeight, width);
|
||||
PaintRect(&rect);
|
||||
}
|
||||
|
||||
PixMapHandle pixMap = m_menuBarGraf->m_port.GetPixMap();
|
||||
|
||||
// Round corners
|
||||
gs_barTopLeftCornerGraphic.DrawToPixMap(pixMap, 0, 0);
|
||||
gs_barTopRightCornerGraphic.DrawToPixMap(pixMap, static_cast<int16_t>(width) - static_cast<int16_t>(gs_barTopRightCornerGraphic.m_width), 0);
|
||||
|
||||
qdState->SetForeColor(gs_barNormalTextColor);
|
||||
TextFont(systemFont);
|
||||
TextSize(kMenuFontSize);
|
||||
|
||||
// Text items
|
||||
{
|
||||
Menu **menuHdl = m_firstMenu;
|
||||
while (menuHdl)
|
||||
{
|
||||
Menu *menu = *menuHdl;
|
||||
|
||||
if (menu->stringBlobHandle)
|
||||
{
|
||||
size_t xCoordinate = menu->cumulativeOffset + (menu->menuIndex * 2) * kMenuBarItemPadding + kMenuBarInitialPadding;
|
||||
|
||||
if (menu->isIcon)
|
||||
{
|
||||
if (m_iconGraphic)
|
||||
m_iconGraphic->DrawToPixMapWithMask(pixMap, m_iconMask, xCoordinate, kMenuBarIconYOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
qdState->m_penPos.h = xCoordinate;
|
||||
qdState->m_penPos.v = kMenuBarTextYOffset;
|
||||
DrawString(PLPasStr(static_cast<const uint8_t*>(menu->stringBlobHandle->m_contents)));
|
||||
}
|
||||
}
|
||||
|
||||
menuHdl = menu->nextMenu;
|
||||
}
|
||||
}
|
||||
|
||||
SetGWorld(oldGraf, oldDevice);
|
||||
|
||||
m_menuBarGraf->m_port.SetDirty(QDPortDirtyFlag_Contents);
|
||||
}
|
||||
|
||||
void MenuManagerImpl::RenderFrame(IGpDisplayDriver *displayDriver)
|
||||
{
|
||||
if (m_menuBarGraf)
|
||||
{
|
||||
m_menuBarGraf->PushToDDSurface(displayDriver);
|
||||
|
||||
if (m_menuBarGraf->m_ddSurface)
|
||||
{
|
||||
const PixMap *pixMap = *m_menuBarGraf->m_port.GetPixMap();
|
||||
const size_t width = pixMap->m_rect.right - pixMap->m_rect.left;
|
||||
const size_t height = pixMap->m_rect.bottom - pixMap->m_rect.top;
|
||||
displayDriver->DrawSurface(m_menuBarGraf->m_ddSurface, 0, 0, width, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MenuManagerImpl::RefreshMenuLayout()
|
||||
{
|
||||
if (m_haveMenuLayout)
|
||||
return;
|
||||
|
||||
PortabilityLayer::FontManager *fontManager = PortabilityLayer::FontManager::GetInstance();
|
||||
|
||||
PortabilityLayer::FontFamily *fontFamily = PortabilityLayer::FontManager::GetInstance()->GetSystemFont(kMenuFontSize, kMenuFontFlags);
|
||||
if (!fontFamily)
|
||||
return;
|
||||
|
||||
PortabilityLayer::RenderedFont *rfont = PortabilityLayer::FontManager::GetInstance()->GetRenderedFontFromFamily(fontFamily, kMenuFontSize, kMenuFontFlags);
|
||||
if (!rfont)
|
||||
return;
|
||||
|
||||
unsigned int index = 0;
|
||||
size_t measuredWidth = 0;
|
||||
|
||||
Menu **menuHdl = m_firstMenu;
|
||||
while (menuHdl)
|
||||
{
|
||||
Menu *menu = *menuHdl;
|
||||
|
||||
menu->menuIndex = index++;
|
||||
menu->cumulativeOffset = measuredWidth;
|
||||
|
||||
const PLPasStr pascalStr = PLPasStr(static_cast<const uint8_t*>(menu->stringBlobHandle->m_contents));
|
||||
|
||||
if (pascalStr.Length() == 1 && pascalStr.UChars()[0] == 0x14)
|
||||
{
|
||||
measuredWidth += 16;
|
||||
menu->isIcon = true;
|
||||
}
|
||||
else
|
||||
measuredWidth += rfont->MeasureString(pascalStr.UChars(), pascalStr.Length());
|
||||
|
||||
menuHdl = menu->nextMenu;
|
||||
}
|
||||
|
||||
m_haveMenuLayout = true;
|
||||
}
|
||||
|
||||
MenuManagerImpl *MenuManagerImpl::GetInstance()
|
||||
{
|
||||
return &ms_instance;
|
||||
|
@@ -1,12 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
struct Menu;
|
||||
struct Menu;
|
||||
struct IGpDisplayDriver;
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
class MenuManager
|
||||
{
|
||||
public:
|
||||
virtual void Init() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
virtual Menu **DeserializeMenu(const void *resData) const = 0;
|
||||
virtual Menu **GetMenuByID(int id) const = 0;
|
||||
virtual void InsertMenuBefore(Menu **insertingMenu, Menu **existingMenu) = 0;
|
||||
@@ -17,6 +21,10 @@ namespace PortabilityLayer
|
||||
virtual void SetItemEnabled(Menu **menu, unsigned int index, bool enabled) = 0;
|
||||
virtual void SetItemChecked(Menu **menu, unsigned int index, bool checked) = 0;
|
||||
|
||||
virtual void DrawMenuBar() = 0;
|
||||
|
||||
virtual void RenderFrame(IGpDisplayDriver *displayDriver) = 0;
|
||||
|
||||
static MenuManager *GetInstance();
|
||||
};
|
||||
}
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#include "ResourceManager.h"
|
||||
#include "MacFileInfo.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "MenuManager.h"
|
||||
#include "MemReaderStream.h"
|
||||
#include "MMHandleBlock.h"
|
||||
#include "ResTypeID.h"
|
||||
@@ -61,6 +62,11 @@ static void TranslateVOSEvent(const GpVOSEvent *vosEvent, EventRecord *evt)
|
||||
|
||||
static void ImportVOSEvents()
|
||||
{
|
||||
PortabilityLayer::HostVOSEventQueue *evtQueue = PortabilityLayer::HostVOSEventQueue::GetInstance();
|
||||
while (const GpVOSEvent *evt = evtQueue->GetNext())
|
||||
{
|
||||
evtQueue->DischargeOne();
|
||||
}
|
||||
}
|
||||
|
||||
void InitCursor()
|
||||
@@ -864,6 +870,7 @@ void PL_Init()
|
||||
PortabilityLayer::DisplayDeviceManager::GetInstance()->Init();
|
||||
PortabilityLayer::AEManager::GetInstance()->Init();
|
||||
PortabilityLayer::QDManager::GetInstance()->Init();
|
||||
PortabilityLayer::MenuManager::GetInstance()->Init();
|
||||
}
|
||||
|
||||
WindowPtr PL_GetPutInFrontWindowPtr()
|
||||
|
@@ -1,9 +1,9 @@
|
||||
#include "PLEventQueue.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
{
|
||||
class EventQueueImpl final : public EventQueue
|
||||
{
|
||||
public:
|
||||
|
@@ -2,6 +2,7 @@
|
||||
#include "PLResources.h"
|
||||
|
||||
#include "MenuManager.h"
|
||||
#include "QDManager.h"
|
||||
|
||||
// Menu resource structure:
|
||||
// uint16 menu ID
|
||||
@@ -54,7 +55,7 @@ void DeleteMenu(int menuID)
|
||||
|
||||
void DrawMenuBar()
|
||||
{
|
||||
PL_NotYetImplemented_TODO("Menus");
|
||||
PortabilityLayer::MenuManager::GetInstance()->DrawMenuBar();
|
||||
}
|
||||
|
||||
void HiliteMenu(int menu)
|
||||
|
@@ -239,7 +239,7 @@ OSErr NewGWorld(GWorldPtr *gworld, int depth, Rect *bounds, CTabHandle colorTabl
|
||||
|
||||
void DisposeGWorld(GWorldPtr gworld)
|
||||
{
|
||||
PL_NotYetImplemented();
|
||||
return PortabilityLayer::QDManager::GetInstance()->DisposeGWorld(gworld);
|
||||
}
|
||||
|
||||
PixMapHandle GetGWorldPixMap(GWorldPtr gworld)
|
||||
|
@@ -227,6 +227,7 @@
|
||||
<ClInclude Include="ResTypeIDCodec.h" />
|
||||
<ClInclude Include="RGBAColor.h" />
|
||||
<ClInclude Include="SharedTypes.h" />
|
||||
<ClInclude Include="SimpleGraphic.h" />
|
||||
<ClInclude Include="Vec2i.h" />
|
||||
<ClInclude Include="VirtualDirectory.h" />
|
||||
<ClInclude Include="RCPtr.h" />
|
||||
@@ -296,6 +297,7 @@
|
||||
<ClCompile Include="RandomNumberGenerator.cpp" />
|
||||
<ClCompile Include="ResourceCompiledRef.cpp" />
|
||||
<ClCompile Include="ResourceFile.cpp" />
|
||||
<ClCompile Include="SimpleGraphic.cpp" />
|
||||
<ClCompile Include="WindowDef.cpp" />
|
||||
<ClCompile Include="WindowManager.cpp" />
|
||||
<ClCompile Include="XModemCRC.cpp" />
|
||||
|
@@ -360,6 +360,9 @@
|
||||
<ClInclude Include="MacRoman.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SimpleGraphic.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CFileStream.cpp">
|
||||
@@ -539,5 +542,8 @@
|
||||
<ClCompile Include="MacRoman.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SimpleGraphic.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@@ -0,0 +1,30 @@
|
||||
#include "QDGraf.h"
|
||||
#include "QDPixMap.h"
|
||||
#include "QDPort.h"
|
||||
#include "IGpDisplayDriver.h"
|
||||
#include "IGpDisplayDriverSurface.h"
|
||||
|
||||
void CGraf::PushToDDSurface(IGpDisplayDriver *displayDriver)
|
||||
{
|
||||
const PixMap *pixMap = *m_port.GetPixMap();
|
||||
const size_t width = pixMap->m_rect.right - pixMap->m_rect.left;
|
||||
const size_t height = pixMap->m_rect.bottom - pixMap->m_rect.top;
|
||||
|
||||
if (m_port.IsDirty(PortabilityLayer::QDPortDirtyFlag_Size))
|
||||
{
|
||||
if (m_ddSurface != nullptr)
|
||||
m_ddSurface->Destroy();
|
||||
|
||||
m_ddSurface = nullptr;
|
||||
m_port.ClearDirty(PortabilityLayer::QDPortDirtyFlag_Size);
|
||||
}
|
||||
|
||||
if (m_ddSurface == nullptr)
|
||||
m_ddSurface = displayDriver->CreateSurface(pixMap->m_rect.right - pixMap->m_rect.left, pixMap->m_rect.bottom - pixMap->m_rect.top, pixMap->m_pixelFormat);
|
||||
|
||||
if (m_port.IsDirty(PortabilityLayer::QDPortDirtyFlag_Contents) && m_ddSurface != nullptr)
|
||||
{
|
||||
m_ddSurface->UploadEntire(pixMap->m_data, pixMap->m_pitch);
|
||||
m_port.ClearDirty(PortabilityLayer::QDPortDirtyFlag_Contents);
|
||||
}
|
||||
}
|
||||
|
@@ -8,9 +8,10 @@
|
||||
|
||||
struct PixMap;
|
||||
struct Rect;
|
||||
struct IGpDisplayDriver;
|
||||
struct IGpDisplayDriverSurface;
|
||||
|
||||
struct CGraf
|
||||
struct CGraf final
|
||||
{
|
||||
CGraf()
|
||||
: m_port(PortabilityLayer::QDPortType_CGraf)
|
||||
@@ -37,6 +38,8 @@ struct CGraf
|
||||
return m_port.Resize(rect);
|
||||
}
|
||||
|
||||
void PushToDDSurface(IGpDisplayDriver *displayDriver);
|
||||
|
||||
// Must be the first item
|
||||
PortabilityLayer::QDPort m_port;
|
||||
|
||||
|
@@ -17,6 +17,7 @@ namespace PortabilityLayer
|
||||
void GetPort(QDPort **port, GDevice ***gdHandle) override;
|
||||
void SetPort(QDPort *gw, GDevice **gdHandle) override;
|
||||
int NewGWorld(CGraf **gw, int depth, const Rect &bounds, ColorTable **colorTable, GDevice **device, int flags) override;
|
||||
void DisposeGWorld(CGraf *gw) override;
|
||||
QDState *GetState() override;
|
||||
|
||||
static QDManagerImpl *GetInstance();
|
||||
@@ -93,6 +94,12 @@ namespace PortabilityLayer
|
||||
return noErr;
|
||||
}
|
||||
|
||||
void QDManagerImpl::DisposeGWorld(CGraf *gw)
|
||||
{
|
||||
gw->~CGraf();
|
||||
MemoryManager::GetInstance()->Release(gw);
|
||||
}
|
||||
|
||||
QDState *QDManagerImpl::GetState()
|
||||
{
|
||||
return m_port->GetState();
|
||||
|
@@ -17,6 +17,7 @@ namespace PortabilityLayer
|
||||
virtual void GetPort(QDPort **gw, GDevice ***gdHandle) = 0;
|
||||
virtual void SetPort(QDPort *gw, GDevice **gdHandle) = 0;
|
||||
virtual int NewGWorld(CGraf **gw, int depth, const Rect &bounds, ColorTable **colorTable, GDevice **device, int flags) = 0;
|
||||
virtual void DisposeGWorld(CGraf *gw) = 0;
|
||||
|
||||
virtual QDState *GetState() = 0;
|
||||
|
||||
|
@@ -1,4 +1,6 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
@@ -8,6 +10,7 @@ namespace PortabilityLayer
|
||||
{
|
||||
public:
|
||||
virtual bool GetGlyph(unsigned int character, const RenderedGlyphMetrics **outMetricsPtr, const void **outData) const = 0;
|
||||
virtual size_t MeasureString(const uint8_t *chars, size_t len) const = 0;
|
||||
|
||||
virtual void Destroy() = 0;
|
||||
};
|
||||
|
100
PortabilityLayer/SimpleGraphic.cpp
Normal file
100
PortabilityLayer/SimpleGraphic.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
#include "SimpleGraphic.h"
|
||||
#include "QDStandardPalette.h"
|
||||
#include "QDPixMap.h"
|
||||
#include "SharedTypes.h"
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
SimpleGraphic::SimpleGraphic(unsigned int width, unsigned int height, const RGBAColor *pixelData, uint8_t *standardPaletteData)
|
||||
: m_width(width)
|
||||
, m_height(height)
|
||||
, m_pixelData(pixelData)
|
||||
, m_standardPaletteData(standardPaletteData)
|
||||
{
|
||||
const unsigned int numPixels = width * height;
|
||||
|
||||
for (unsigned int i = 0; i < numPixels; i++)
|
||||
standardPaletteData[i] = PortabilityLayer::StandardPalette::MapColorAnalytic(pixelData[i]);
|
||||
}
|
||||
|
||||
SimpleGraphic::SimpleGraphic(unsigned int width, unsigned int height, const uint8_t *standardPaletteData, RGBAColor *pixelData)
|
||||
: m_width(width)
|
||||
, m_height(height)
|
||||
, m_pixelData(pixelData)
|
||||
, m_standardPaletteData(standardPaletteData)
|
||||
{
|
||||
const unsigned int numPixels = width * height;
|
||||
|
||||
for (unsigned int i = 0; i < numPixels; i++)
|
||||
pixelData[i] = PortabilityLayer::StandardPalette::GetInstance()->GetColors()[standardPaletteData[i]];
|
||||
}
|
||||
|
||||
void SimpleGraphic::DrawToPixMap(PixMap **pixMapH, int16_t x, int16_t y)
|
||||
{
|
||||
DrawToPixMapWithMask(pixMapH, nullptr, x, y);
|
||||
}
|
||||
|
||||
void SimpleGraphic::DrawToPixMapWithMask(PixMap **pixMapH, const uint8_t *maskData, int16_t x, int16_t y)
|
||||
{
|
||||
if (!pixMapH)
|
||||
return;
|
||||
|
||||
PixMap *pixMap = *pixMapH;
|
||||
|
||||
void *pixMapData = pixMap->m_data;
|
||||
const size_t destPitch = pixMap->m_pitch;
|
||||
|
||||
const Rect pixMapRect = pixMap->m_rect;
|
||||
const int32_t right = x + static_cast<int32_t>(m_width);
|
||||
const int32_t bottom = y + static_cast<int32_t>(m_height);
|
||||
|
||||
// Simple graphics must be entirely in bounds
|
||||
if (x < 0 || y < 0 || right > pixMapRect.right || bottom > pixMapRect.bottom)
|
||||
return;
|
||||
|
||||
const size_t destXOffset = (x - pixMapRect.left);
|
||||
const size_t destYOffset = (y - pixMapRect.top);
|
||||
|
||||
const size_t srcHeight = m_height;
|
||||
const size_t srcWidth = m_width;
|
||||
|
||||
size_t maskOffset = 0;
|
||||
|
||||
switch (pixMap->m_pixelFormat)
|
||||
{
|
||||
case GpPixelFormats::k8BitStandard:
|
||||
{
|
||||
uint8_t *destFirstPixel = static_cast<uint8_t*>(pixMapData) + destXOffset + destYOffset * destPitch;
|
||||
const uint8_t *srcPixel = m_standardPaletteData;
|
||||
|
||||
for (size_t row = 0; row < srcHeight; row++)
|
||||
{
|
||||
uint8_t *destRowFirstPixel = destFirstPixel + row * destPitch;
|
||||
|
||||
if (maskData)
|
||||
{
|
||||
for (size_t col = 0; col < srcWidth; col++)
|
||||
{
|
||||
if (maskData[maskOffset / 8] & (0x80 >> (maskOffset & 7)))
|
||||
destRowFirstPixel[col] = *srcPixel;
|
||||
srcPixel++;
|
||||
maskOffset++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t col = 0; col < srcWidth; col++)
|
||||
{
|
||||
destRowFirstPixel[col] = *srcPixel;
|
||||
srcPixel++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PL_NotYetImplemented();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
56
PortabilityLayer/SimpleGraphic.h
Normal file
56
PortabilityLayer/SimpleGraphic.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include "RGBAColor.h"
|
||||
|
||||
struct PixMap;
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
struct SimpleGraphic
|
||||
{
|
||||
unsigned int m_width;
|
||||
unsigned int m_height;
|
||||
|
||||
const RGBAColor *m_pixelData;
|
||||
const uint8_t *m_standardPaletteData;
|
||||
|
||||
void DrawToPixMap(PixMap **pixMap, int16_t x, int16_t y);
|
||||
void DrawToPixMapWithMask(PixMap **pixMap, const uint8_t *maskData, int16_t x, int16_t y);
|
||||
|
||||
protected:
|
||||
SimpleGraphic(unsigned int width, unsigned int height, const RGBAColor *pixelData, uint8_t *standardPaletteData);
|
||||
SimpleGraphic(unsigned int width, unsigned int height, const uint8_t *pixelData, RGBAColor *standardPaletteData);
|
||||
};
|
||||
|
||||
template<unsigned int TWidth, unsigned int THeight>
|
||||
struct SimpleGraphicInstanceRGBA final : public SimpleGraphic
|
||||
{
|
||||
uint8_t m_standardPaletteDataInstance[TWidth * THeight];
|
||||
|
||||
explicit SimpleGraphicInstanceRGBA(const RGBAColor *data);
|
||||
};
|
||||
|
||||
template<unsigned int TWidth, unsigned int THeight>
|
||||
struct SimpleGraphicInstanceStandardPalette final : public SimpleGraphic
|
||||
{
|
||||
RGBAColor m_pixelDataInstance[TWidth * THeight];
|
||||
|
||||
explicit SimpleGraphicInstanceStandardPalette(const uint8_t *data);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
template<unsigned int TWidth, unsigned int THeight>
|
||||
inline SimpleGraphicInstanceRGBA<TWidth, THeight>::SimpleGraphicInstanceRGBA(const RGBAColor *data)
|
||||
: SimpleGraphic(TWidth, THeight, data, m_standardPaletteDataInstance)
|
||||
{
|
||||
}
|
||||
|
||||
template<unsigned int TWidth, unsigned int THeight>
|
||||
inline SimpleGraphicInstanceStandardPalette<TWidth, THeight>::SimpleGraphicInstanceStandardPalette(const uint8_t *data)
|
||||
: SimpleGraphic(TWidth, THeight, data, m_pixelDataInstance)
|
||||
{
|
||||
}
|
||||
}
|
@@ -311,31 +311,13 @@ namespace PortabilityLayer
|
||||
|
||||
void WindowManagerImpl::RenderWindow(WindowImpl *window, IGpDisplayDriver *displayDriver)
|
||||
{
|
||||
GDevice *device = *window->GetDevice();
|
||||
|
||||
CGraf &graf = window->m_graf;
|
||||
|
||||
graf.PushToDDSurface(displayDriver);
|
||||
|
||||
const PixMap *pixMap = *graf.m_port.GetPixMap();
|
||||
const size_t width = pixMap->m_rect.right - pixMap->m_rect.left;
|
||||
const size_t height = pixMap->m_rect.bottom - pixMap->m_rect.top;
|
||||
|
||||
if (graf.m_port.IsDirty(QDPortDirtyFlag_Size))
|
||||
{
|
||||
if (graf.m_ddSurface != nullptr)
|
||||
graf.m_ddSurface->Destroy();
|
||||
|
||||
graf.m_ddSurface = nullptr;
|
||||
graf.m_port.ClearDirty(QDPortDirtyFlag_Size);
|
||||
}
|
||||
|
||||
if (graf.m_ddSurface == nullptr)
|
||||
graf.m_ddSurface = displayDriver->CreateSurface(pixMap->m_rect.right - pixMap->m_rect.left, pixMap->m_rect.bottom - pixMap->m_rect.top, pixMap->m_pixelFormat);
|
||||
|
||||
if (graf.m_port.IsDirty(QDPortDirtyFlag_Contents) && graf.m_ddSurface != nullptr)
|
||||
{
|
||||
graf.m_ddSurface->UploadEntire(pixMap->m_data, pixMap->m_pitch);
|
||||
graf.m_port.ClearDirty(QDPortDirtyFlag_Contents);
|
||||
}
|
||||
|
||||
displayDriver->DrawSurface(graf.m_ddSurface, window->m_wmX, window->m_wmY, width, height);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user