Add FreeType, progress to title screen

This commit is contained in:
elasota
2019-12-21 18:40:17 -05:00
parent c9c6976344
commit 8354d13a84
901 changed files with 444265 additions and 440 deletions

View File

@@ -1,77 +1,95 @@
#include "DisplayDeviceManager.h"
#include "DisplayDeviceManager.h"
#include "HostDisplayDriver.h"
#include "PLQuickdraw.h"
#include "MemoryManager.h"
namespace PortabilityLayer
{
class DisplayDeviceManagerImpl final : public DisplayDeviceManager
{
public:
DisplayDeviceManagerImpl();
void Init() override;
void Shutdown() override;
GDevice **GetMainDevice() override;
void IncrementTickCount(uint32_t count) override;
uint32_t GetTickCount() override;
static DisplayDeviceManagerImpl *GetInstance();
private:
GDHandle m_mainDevice;
uint32_t m_tickCount;
static DisplayDeviceManagerImpl ms_instance;
};
DisplayDeviceManagerImpl::DisplayDeviceManagerImpl()
: m_mainDevice(nullptr)
, m_tickCount(1)
{
}
void DisplayDeviceManagerImpl::Init()
{
#include "HostDisplayDriver.h"
#include "PLQuickdraw.h"
#include "MemoryManager.h"
#include "QDStandardPalette.h"
namespace PortabilityLayer
{
class DisplayDeviceManagerImpl final : public DisplayDeviceManager
{
public:
DisplayDeviceManagerImpl();
void Init() override;
void Shutdown() override;
GDevice **GetMainDevice() override;
void IncrementTickCount(uint32_t count) override;
uint32_t GetTickCount() override;
static DisplayDeviceManagerImpl *GetInstance();
private:
GDHandle m_mainDevice;
uint32_t m_tickCount;
static DisplayDeviceManagerImpl ms_instance;
};
DisplayDeviceManagerImpl::DisplayDeviceManagerImpl()
: m_mainDevice(nullptr)
, m_tickCount(1)
{
}
void DisplayDeviceManagerImpl::Init()
{
m_mainDevice = MemoryManager::GetInstance()->NewHandle<GDevice>();
if (m_mainDevice)
{
GDevice *device = *m_mainDevice;
HostDisplayDriver::GetInstance()->GetDisplayResolution(nullptr, nullptr, &(*m_mainDevice)->pixelFormat);
}
void DisplayDeviceManagerImpl::Shutdown()
{
MemoryManager::GetInstance()->ReleaseHandle(reinterpret_cast<MMHandleBlock*>(m_mainDevice));
}
GDevice **DisplayDeviceManagerImpl::GetMainDevice()
{
return m_mainDevice;
}
void DisplayDeviceManagerImpl::IncrementTickCount(uint32_t count)
{
m_tickCount += count;
}
uint32_t DisplayDeviceManagerImpl::GetTickCount()
{
return m_tickCount;
}
DisplayDeviceManagerImpl *DisplayDeviceManagerImpl::GetInstance()
{
return &ms_instance;
}
DisplayDeviceManagerImpl DisplayDeviceManagerImpl::ms_instance;
DisplayDeviceManager *DisplayDeviceManager::GetInstance()
{
return DisplayDeviceManagerImpl::GetInstance();
}
}
HostDisplayDriver::GetInstance()->GetDisplayResolution(nullptr, nullptr, &device->pixelFormat);
uint8_t *paletteStorage = device->paletteStorage;
while (reinterpret_cast<intptr_t>(paletteStorage) % PL_SYSTEM_MEMORY_ALIGNMENT != 0)
paletteStorage++;
PortabilityLayer::RGBAColor *paletteData = reinterpret_cast<PortabilityLayer::RGBAColor*>(paletteStorage);
device->paletteDataOffset = static_cast<uint8_t>(paletteStorage - device->paletteStorage);
const PortabilityLayer::RGBAColor *spColors = StandardPalette::GetInstance()->GetColors();
for (size_t i = 0; i < 256; i++)
paletteData[i] = spColors[i];
device->paletteIsDirty = true;
}
}
void DisplayDeviceManagerImpl::Shutdown()
{
MemoryManager::GetInstance()->ReleaseHandle(reinterpret_cast<MMHandleBlock*>(m_mainDevice));
}
GDevice **DisplayDeviceManagerImpl::GetMainDevice()
{
return m_mainDevice;
}
void DisplayDeviceManagerImpl::IncrementTickCount(uint32_t count)
{
m_tickCount += count;
}
uint32_t DisplayDeviceManagerImpl::GetTickCount()
{
return m_tickCount;
}
DisplayDeviceManagerImpl *DisplayDeviceManagerImpl::GetInstance()
{
return &ms_instance;
}
DisplayDeviceManagerImpl DisplayDeviceManagerImpl::ms_instance;
DisplayDeviceManager *DisplayDeviceManager::GetInstance()
{
return DisplayDeviceManagerImpl::GetInstance();
}
}

View File

@@ -0,0 +1,68 @@
#include "FontManager.h"
#include "HostFileSystem.h"
#include "HostFont.h"
#include "HostFontHandler.h"
#include "IOStream.h"
void PL_NotYetImplemented();
namespace PortabilityLayer
{
class FontManagerImpl final : public FontManager
{
public:
void Init() override;
void Shutdown() override;
static FontManagerImpl *GetInstance();
private:
FontManagerImpl();
PortabilityLayer::HostFont *m_systemFont;
static FontManagerImpl ms_instance;
};
void FontManagerImpl::Init()
{
m_systemFont = nullptr;
if (IOStream *sysFontStream = HostFileSystem::GetInstance()->OpenFile(EVirtualDirectory_Fonts, "virtue.ttf", false, false))
{
HostFont *font = HostFontHandler::GetInstance()->LoadFont(sysFontStream);
sysFontStream->Close();
m_systemFont = font;
}
}
void FontManagerImpl::Shutdown()
{
HostFontHandler *hfh = HostFontHandler::GetInstance();
if (m_systemFont)
{
m_systemFont->Destroy();
m_systemFont = nullptr;
}
}
FontManagerImpl *FontManagerImpl::GetInstance()
{
return &ms_instance;
}
FontManagerImpl::FontManagerImpl()
: m_systemFont(nullptr)
{
}
FontManagerImpl FontManagerImpl::ms_instance;
FontManager *FontManager::GetInstance()
{
return FontManagerImpl::GetInstance();
}
}

View File

@@ -0,0 +1,13 @@
#pragma once
namespace PortabilityLayer
{
class FontManager
{
public:
virtual void Init() = 0;
virtual void Shutdown() = 0;
static FontManager *GetInstance();
};
}

View File

@@ -25,17 +25,24 @@ namespace PortabilityLayer
class HostFileSystem;
class HostDisplayDriver;
class HostSystemServices;
class HostFontHandler;
class HostVOSEventQueue;
}
struct IGpDisplayDriver;
class GpAppInterface
{
public:
virtual int ApplicationMain() = 0;
virtual void PL_IncrementTickCounter(uint32_t count) = 0;
virtual void PL_Render(IGpDisplayDriver *displayDriver) = 0;
virtual void PL_HostFileSystem_SetInstance(PortabilityLayer::HostFileSystem *instance) = 0;
virtual void PL_HostDisplayDriver_SetInstance(PortabilityLayer::HostDisplayDriver *instance) = 0;
virtual void PL_HostSystemServices_SetInstance(PortabilityLayer::HostSystemServices *instance) = 0;
virtual void PL_HostAudioDriver_SetInstance(PortabilityLayer::HostAudioDriver *instance) = 0;
virtual void PL_HostFontHandler_SetInstance(PortabilityLayer::HostFontHandler *instance) = 0;
virtual void PL_HostVOSEventQueue_SetInstance(PortabilityLayer::HostVOSEventQueue *instance) = 0;
virtual void PL_InstallHostSuspendHook(PortabilityLayer::HostSuspendHook_t hook, void *context) = 0;
};

View File

@@ -1,27 +1,27 @@
#pragma once
#ifndef __PL_HOST_FILESYSTEM_H__
#define __PL_HOST_FILESYSTEM_H__
#include "VirtualDirectory.h"
namespace PortabilityLayer
{
#pragma once
#ifndef __PL_HOST_FILESYSTEM_H__
#define __PL_HOST_FILESYSTEM_H__
#include "VirtualDirectory.h"
namespace PortabilityLayer
{
class IOStream;
class HostDirectoryCursor;
class HostFileSystem
{
public:
virtual bool FileExists(EVirtualDirectory virtualDirectory, const char *path) = 0;
virtual IOStream *OpenFile(EVirtualDirectory virtualDirectory, const char *path, bool writeAccess, bool create) = 0;
class HostDirectoryCursor;
class HostFileSystem
{
public:
virtual bool FileExists(EVirtualDirectory virtualDirectory, const char *path) = 0;
virtual IOStream *OpenFile(EVirtualDirectory virtualDirectory, const char *path, bool writeAccess, bool create) = 0;
virtual HostDirectoryCursor *ScanDirectory(EVirtualDirectory virtualDirectory) = 0;
static HostFileSystem *GetInstance();
static void SetInstance(HostFileSystem *instance);
private:
static HostFileSystem *ms_instance;
};
}
#endif
static HostFileSystem *GetInstance();
static void SetInstance(HostFileSystem *instance);
private:
static HostFileSystem *ms_instance;
};
}
#endif

View File

@@ -0,0 +1,10 @@
#pragma once
namespace PortabilityLayer
{
class HostFont
{
public:
virtual void Destroy() = 0;
};
}

View File

@@ -0,0 +1,16 @@
#include "HostFontHandler.h"
namespace PortabilityLayer
{
void HostFontHandler::SetInstance(HostFontHandler *instance)
{
ms_instance = instance;
}
HostFontHandler *HostFontHandler::GetInstance()
{
return ms_instance;
}
HostFontHandler *HostFontHandler::ms_instance = nullptr;
}

View File

@@ -0,0 +1,21 @@
#pragma once
namespace PortabilityLayer
{
class IOStream;
class HostFont;
class HostFontHandler
{
public:
virtual void Shutdown() = 0;
virtual HostFont *LoadFont(IOStream *stream) = 0;
static void SetInstance(HostFontHandler *instance);
static HostFontHandler *GetInstance();
private:
static HostFontHandler *ms_instance;
};
}

View File

@@ -0,0 +1,17 @@
#pragma once
#include "HostKeyID.h"
namespace PortabilityLayer
{
class HostInputDriver
{
public:
static HostInputDriver *GetInstance();
static void SetInstance(HostInputDriver *instance);
private:
static HostInputDriver *ms_instance;
};
}

View File

@@ -1,31 +1,31 @@
#pragma once
#ifndef __PL_HOST_SYSTEM_SERVICES_H__
#define __PL_HOST_SYSTEM_SERVICES_H__
#pragma once
#ifndef __PL_HOST_SYSTEM_SERVICES_H__
#define __PL_HOST_SYSTEM_SERVICES_H__
#include <stdint.h>
#ifdef CreateMutex
#error "CreateMutex was macrod"
#endif
namespace PortabilityLayer
#endif
namespace PortabilityLayer
{
class HostMutex;
class HostThreadEvent;
class HostSystemServices
{
public:
class HostSystemServices
{
public:
virtual uint32_t GetTime() const = 0;
virtual HostMutex *CreateMutex() = 0;
virtual HostThreadEvent *CreateThreadEvent(bool autoReset, bool startSignaled) = 0;
static void SetInstance(HostSystemServices *instance);
static HostSystemServices *GetInstance();
private:
static HostSystemServices *ms_instance;
};
}
#endif
virtual HostMutex *CreateMutex() = 0;
virtual HostThreadEvent *CreateThreadEvent(bool autoReset, bool startSignaled) = 0;
static void SetInstance(HostSystemServices *instance);
static HostSystemServices *GetInstance();
private:
static HostSystemServices *ms_instance;
};
}
#endif

View File

@@ -0,0 +1,16 @@
#include "HostVOSEventQueue.h"
namespace PortabilityLayer
{
void HostVOSEventQueue::SetInstance(HostVOSEventQueue *instance)
{
ms_instance = instance;
}
HostVOSEventQueue *HostVOSEventQueue::GetInstance()
{
return ms_instance;
}
HostVOSEventQueue *HostVOSEventQueue::ms_instance = nullptr;
}

View File

@@ -0,0 +1,19 @@
#pragma once
struct GpVOSEvent;
namespace PortabilityLayer
{
class HostVOSEventQueue
{
public:
virtual const GpVOSEvent *GetNext() = 0;
virtual void DischargeOne() = 0;
static void SetInstance(HostVOSEventQueue *instance);
static HostVOSEventQueue *GetInstance();
private:
static HostVOSEventQueue *ms_instance;
};
}

View File

@@ -0,0 +1,44 @@
#include "InputManager.h"
#include <string.h>
namespace PortabilityLayer
{
class InputManagerImpl final : public InputManager
{
public:
InputManagerImpl();
void GetKeys(unsigned char *keys16) const override;
static InputManagerImpl *GetInstance();
private:
unsigned char m_keys[16];
static InputManagerImpl ms_instance;
};
void InputManagerImpl::GetKeys(unsigned char *keys16) const
{
memcpy(keys16, m_keys, 16);
}
InputManagerImpl *InputManagerImpl::GetInstance()
{
return &ms_instance;
}
InputManagerImpl::InputManagerImpl()
{
for (int i = 0; i < sizeof(m_keys) / sizeof(m_keys[0]); i++)
m_keys[i] = 0;
}
InputManagerImpl InputManagerImpl::ms_instance;
InputManager *InputManager::GetInstance()
{
return InputManagerImpl::GetInstance();
}
}

View File

@@ -0,0 +1,12 @@
#pragma once
namespace PortabilityLayer
{
class InputManager
{
public:
virtual void GetKeys(unsigned char *keys16) const = 0;
static InputManager *GetInstance();
};
}

View File

@@ -0,0 +1,229 @@
#include "MenuManager.h"
#include "PLBigEndian.h"
#include "MemoryManager.h"
#include <stdint.h>
struct MenuItem
{
uint32_t nameOffsetInStringBlob;
int8_t iconResID;
uint8_t key;
uint8_t submenuID;
uint8_t textStyle;
};
struct Menu
{
uint16_t menuID;
uint16_t width;
uint16_t height;
uint16_t commandID;
uint32_t itemEnabledMask;
PortabilityLayer::MMHandleBlock *stringBlobHandle;
Menu **prevMenu;
Menu **nextMenu;
size_t numMenuItems;
MenuItem menuItems[1];
};
namespace PortabilityLayer
{
class MenuManagerImpl final : public MenuManager
{
public:
MenuManagerImpl();
~MenuManagerImpl();
Menu **DeserializeMenu(const void *resData) const override;
Menu **GetMenuByID(int id) const override;
void InsertMenuBefore(Menu **insertingMenu, Menu **existingMenu) override;
void InsertMenuAfter(Menu **insertingMenu, Menu **existingMenu) override;
void InsertMenuAtEnd(Menu **insertingMenu) override;
void InsertMenuAtBeginning(Menu **insertingMenu) override;
static MenuManagerImpl *GetInstance();
private:
Menu **m_firstMenu;
Menu **m_lastMenu;
static MenuManagerImpl ms_instance;
};
MenuManagerImpl::MenuManagerImpl()
: m_firstMenu(nullptr)
, m_lastMenu(nullptr)
{
}
MenuManagerImpl::~MenuManagerImpl()
{
}
Menu **MenuManagerImpl::DeserializeMenu(const void *resData) const
{
PortabilityLayer::MemoryManager *mm = PortabilityLayer::MemoryManager::GetInstance();
const uint8_t *resBytes = static_cast<const uint8_t*>(resData);
struct MenuDataSerialized
{
BEUInt16_t menuID;
BEUInt16_t width;
BEUInt16_t height;
BEUInt16_t commandID;
BEUInt16_t padding;
BEUInt32_t enableFlags;
};
MenuDataSerialized header;
memcpy(&header, resBytes, sizeof(header));
const uint8_t titleLength = resBytes[14];
const uint8_t *menuDataStart = resBytes + 14 + 1 + titleLength;
size_t stringDataLength = 1 + titleLength;
size_t numMenuItems = 0;
for (const uint8_t *menuItemStart = menuDataStart; *menuItemStart; menuItemStart += 5 + (*menuItemStart))
{
numMenuItems++;
stringDataLength += 1 + (*menuItemStart);
}
MMHandleBlock *stringData = mm->AllocHandle(stringDataLength);
if (!stringData)
{
mm->ReleaseHandle(stringData);
return nullptr;
}
MMHandleBlock *menuData = mm->AllocHandle(sizeof(Menu) + sizeof(MenuItem) * (numMenuItems - 1));
if (!menuData)
{
mm->ReleaseHandle(stringData);
return nullptr;
}
Menu *menu = static_cast<Menu*>(menuData->m_contents);
menu->menuID = header.menuID;
menu->width = header.width;
menu->height = header.height;
menu->commandID = header.commandID;
menu->itemEnabledMask = header.enableFlags;
uint8_t *stringDataStart = static_cast<uint8_t*>(stringData->m_contents);
uint8_t *stringDest = stringDataStart;
memcpy(stringDest, resBytes + 14, 1 + resBytes[14]);
stringDest += 1 + resBytes[14];
MenuItem *currentItem = menu->menuItems;
for (const uint8_t *menuItemStart = menuDataStart; *menuItemStart; menuItemStart += 5 + (*menuItemStart))
{
uint8_t itemNameLength = *menuItemStart;
memcpy(stringDest, menuItemStart, 1 + itemNameLength);
currentItem->iconResID = static_cast<int8_t>(menuItemStart[1 + itemNameLength]);
currentItem->key = menuItemStart[2 + itemNameLength];
currentItem->submenuID = menuItemStart[3 + itemNameLength];
currentItem->textStyle = menuItemStart[4 + itemNameLength];
currentItem->nameOffsetInStringBlob = stringDest - stringDataStart;
currentItem++;
stringDest += 1 + (*menuItemStart);
}
menu->numMenuItems = numMenuItems;
menu->stringBlobHandle = stringData;
menu->prevMenu = nullptr;
menu->nextMenu = nullptr;
return reinterpret_cast<Menu**>(&menuData->m_contents);
}
Menu **MenuManagerImpl::GetMenuByID(int id) const
{
for (Menu **menuHandle = m_firstMenu; menuHandle; menuHandle = (*menuHandle)->nextMenu)
{
if ((*menuHandle)->menuID == id)
return menuHandle;
}
return nullptr;
}
void MenuManagerImpl::InsertMenuBefore(Menu **insertingMenu, Menu **existingMenu)
{
Menu *insertingMenuPtr = *insertingMenu;
Menu *existingMenuPtr = *existingMenu;
insertingMenuPtr->prevMenu = existingMenuPtr->prevMenu;
insertingMenuPtr->nextMenu = existingMenu;
if (existingMenuPtr->prevMenu)
(*existingMenuPtr->prevMenu)->nextMenu = insertingMenu;
else
m_firstMenu = insertingMenu;
existingMenuPtr->prevMenu = insertingMenu;
}
void MenuManagerImpl::InsertMenuAfter(Menu **insertingMenu, Menu **existingMenu)
{
Menu *insertingMenuPtr = *insertingMenu;
Menu *existingMenuPtr = *existingMenu;
insertingMenuPtr->prevMenu = existingMenu;
insertingMenuPtr->nextMenu = existingMenuPtr->nextMenu;
if (existingMenuPtr->nextMenu)
(*existingMenuPtr->nextMenu)->prevMenu = insertingMenu;
else
m_lastMenu = insertingMenu;
existingMenuPtr->nextMenu = insertingMenu;
}
void MenuManagerImpl::InsertMenuAtEnd(Menu **insertingMenu)
{
if (m_firstMenu == nullptr)
{
m_firstMenu = m_lastMenu = insertingMenu;
return;
}
(*m_lastMenu)->nextMenu = insertingMenu;
(*insertingMenu)->prevMenu = m_lastMenu;
m_lastMenu = insertingMenu;
}
void MenuManagerImpl::InsertMenuAtBeginning(Menu **insertingMenu)
{
if (m_firstMenu == nullptr)
{
m_firstMenu = m_lastMenu = insertingMenu;
return;
}
(*m_firstMenu)->prevMenu = insertingMenu;
(*insertingMenu)->nextMenu = m_firstMenu;
m_firstMenu = insertingMenu;
}
MenuManagerImpl *MenuManagerImpl::GetInstance()
{
return &ms_instance;
}
MenuManagerImpl MenuManagerImpl::ms_instance;
MenuManager *MenuManager::GetInstance()
{
return MenuManagerImpl::GetInstance();
}
}

View File

@@ -0,0 +1,19 @@
#pragma once
struct Menu;
namespace PortabilityLayer
{
class MenuManager
{
public:
virtual Menu **DeserializeMenu(const void *resData) const = 0;
virtual Menu **GetMenuByID(int id) const = 0;
virtual void InsertMenuBefore(Menu **insertingMenu, Menu **existingMenu) = 0;
virtual void InsertMenuAfter(Menu **insertingMenu, Menu **existingMenu) = 0;
virtual void InsertMenuAtEnd(Menu **insertingMenu) = 0;
virtual void InsertMenuAtBeginning(Menu **insertingMenu) = 0;
static MenuManager *GetInstance();
};
}

View File

@@ -1,5 +1,5 @@
#include "PLControlDefinitions.h"
#include "PLControlDefinitions.h"
int FindControl(Point point, WindowPtr window, ControlHandle *outControl)
{

View File

@@ -6,12 +6,15 @@
#include "DisplayDeviceManager.h"
#include "FileManager.h"
#include "FilePermission.h"
#include "FontManager.h"
#include "HostDirectoryCursor.h"
#include "HostFileSystem.h"
#include "HostSuspendCallArgument.h"
#include "HostSuspendHook.h"
#include "HostDisplayDriver.h"
#include "HostSystemServices.h"
#include "HostVOSEventQueue.h"
#include "InputManager.h"
#include "ResourceManager.h"
#include "MacFileInfo.h"
#include "MemoryManager.h"
@@ -20,6 +23,7 @@
#include "ResTypeID.h"
#include "RandomNumberGenerator.h"
#include "PLBigEndian.h"
#include "PLEventQueue.h"
#include "QDManager.h"
#include "WindowDef.h"
#include "WindowManager.h"
@@ -49,6 +53,15 @@ static bool ConvertFilenameToSafePStr(const char *str, uint8_t *pstr)
return true;
}
static void TranslateVOSEvent(const GpVOSEvent *vosEvent, EventRecord *evt)
{
PL_NotYetImplemented();
}
static void ImportVOSEvents()
{
}
void InitCursor()
{
}
@@ -122,6 +135,8 @@ void Delay(int ticks, UInt32 *endTickCount)
args[0].m_uint = static_cast<uint32_t>(ticks);
PortabilityLayer::SuspendApplication(PortabilityLayer::HostSuspendCallID_Delay, args, nullptr);
ImportVOSEvents();
}
if (endTickCount)
@@ -210,7 +225,12 @@ void DisposeWindow(WindowPtr window)
void GetWindowBounds(WindowPtr window, WindowRegionType windowRegion, Rect *rect)
{
PL_NotYetImplemented();
if (windowRegion == kWindowContentRgn)
*rect = window->m_graf.m_port.GetRect();
else
{
PL_NotYetImplemented();
}
}
WindowPtr GetNewCWindow(int resID, void *storage, WindowPtr behind)
@@ -273,8 +293,10 @@ void SetWTitle(WindowPtr window, const PLPasStr &title)
bool GetNextEvent(int32_t eventMask, EventRecord *event)
{
PL_NotYetImplemented();
return noErr;
assert(eventMask == everyEvent); // We don't support other use cases
PortabilityLayer::EventQueue *queue = PortabilityLayer::EventQueue::GetInstance();
return queue->Dequeue(event) ? PL_TRUE : PL_FALSE;
}
long MenuSelect(Point point)
@@ -296,7 +318,7 @@ long TickCount()
void GetKeys(KeyMap keyMap)
{
PL_NotYetImplemented();
PortabilityLayer::InputManager::GetInstance()->GetKeys(keyMap);
}
short LoWord(Int32 v)
@@ -311,8 +333,8 @@ short HiWord(Int32 v)
bool BitTst(const KeyMap *keyMap, int bit)
{
PL_NotYetImplemented();
return noErr;
const unsigned char *keyMapBytes = *keyMap;
return ((keyMapBytes[bit >> 3] >> (7 - (bit & 0x7))) & 1) != 0;
}
void NumToString(long number, unsigned char *str)
@@ -776,8 +798,21 @@ void BlockMove(const void *src, void *dest, Size size)
Boolean WaitNextEvent(int eventMask, EventRecord *eventOut, long sleep, void *unknown)
{
PL_NotYetImplemented();
return 0;
for (;;)
{
Boolean hasEvent = GetNextEvent(eventMask, eventOut);
if (hasEvent)
return hasEvent;
Delay(1, nullptr);
if (sleep == 0)
break;
sleep--;
}
return PL_FALSE;
}
void DrawControls(WindowPtr window)
@@ -804,12 +839,14 @@ void PL_NotYetImplemented_Minor()
{
}
void PL_NotYetImplemented_TODO()
void PL_NotYetImplemented_TODO(const char *category)
{
(void)category;
}
void PL_Init()
{
PortabilityLayer::FontManager::GetInstance()->Init();
PortabilityLayer::MemoryManager::GetInstance()->Init();
PortabilityLayer::ResourceManager::GetInstance()->Init();
PortabilityLayer::DisplayDeviceManager::GetInstance()->Init();
@@ -823,6 +860,8 @@ WindowPtr PL_GetPutInFrontWindowPtr()
}
Window::Window()
: m_port(PortabilityLayer::QDPortType_Window)
: m_graf(PortabilityLayer::QDPortType_Window)
, m_wmX(0)
, m_wmY(0)
{
}

View File

@@ -6,6 +6,7 @@
#include "PLErrorCodes.h"
#include "SharedTypes.h"
#include "QDPort.h"
#include "QDGraf.h"
#ifdef _MSC_VER
#pragma warning(error:4311) // Pointer truncation to int
@@ -37,6 +38,10 @@ typedef unsigned char *StringPtr;
class PLPasStr;
struct CGraf;
struct Region;
struct Menu;
typedef void *Ptr;
typedef Ptr *Handle;
#define PL_DEAD(n) ((void)0)
@@ -89,19 +94,18 @@ struct CCursor
{
};
struct Window
{
Window();
PortabilityLayer::QDPort m_port; // Must be the first item
};
CGraf m_graf; // Must be the first item
struct Menu
{
// The port is always at 0,0
// These are the WM coordinates
int32_t m_wmX;
int32_t m_wmY;
};
struct DateTimeRec
{
int month;
@@ -172,15 +176,11 @@ typedef MenuPtr *MenuHandle;
typedef RgnPtr *RgnHandle;
typedef VersRecPtr *VersRecHndl;
typedef void *Ptr;
typedef Ptr *Handle;
typedef WindowPtr WindowRef; // wtf?
typedef unsigned char KeyMap[16];
enum RegionID
{
inDesk,
@@ -404,7 +404,7 @@ WindowPtr PL_GetPutInFrontWindowPtr();
void PL_NotYetImplemented();
void PL_NotYetImplemented_Minor();
void PL_NotYetImplemented_TODO();
void PL_NotYetImplemented_TODO(const char *category);
void PL_Init();

View File

@@ -0,0 +1,82 @@
#include "PLEventQueue.h"
#include <stdint.h>
namespace PortabilityLayer
{
class EventQueueImpl final : public EventQueue
{
public:
EventQueueImpl();
~EventQueueImpl();
bool Dequeue(EventRecord *evt) override;
EventRecord *Enqueue() override;
static EventQueueImpl *GetInstance();
private:
static const size_t kMaxEvents = 10000;
EventRecord m_events[kMaxEvents];
size_t m_firstEvent;
size_t m_numQueuedEvents;
static EventQueueImpl ms_instance;
};
EventQueueImpl::EventQueueImpl()
: m_firstEvent(0)
, m_numQueuedEvents(0)
{
}
EventQueueImpl::~EventQueueImpl()
{
}
bool EventQueueImpl::Dequeue(EventRecord *evt)
{
if (m_numQueuedEvents == 0)
return false;
*evt = m_events[m_firstEvent];
m_firstEvent++;
if (m_firstEvent == kMaxEvents)
m_firstEvent = 0;
m_numQueuedEvents--;
return true;
}
EventRecord *EventQueueImpl::Enqueue()
{
if (m_numQueuedEvents == kMaxEvents)
return nullptr;
size_t nextEvent = m_firstEvent + m_numQueuedEvents;
if (nextEvent >= kMaxEvents)
nextEvent -= kMaxEvents;
m_numQueuedEvents++;
EventRecord *evt = m_events + nextEvent;
memset(evt, 0, sizeof(EventRecord));
return evt;
}
EventQueueImpl *EventQueueImpl::GetInstance()
{
return &ms_instance;
}
EventQueueImpl EventQueueImpl::ms_instance;
EventQueue *EventQueue::GetInstance()
{
return EventQueueImpl::GetInstance();
}
}

View File

@@ -0,0 +1,17 @@
#pragma once
#include "PLCore.h"
#include <stdint.h>
namespace PortabilityLayer
{
class EventQueue
{
public:
virtual bool Dequeue(EventRecord *evt) = 0;
virtual EventRecord *Enqueue() = 0;
static EventQueue *GetInstance();
};
}

View File

@@ -1,19 +1,50 @@
#include "PLMenus.h"
#include "PLResources.h"
#include "MenuManager.h"
// Menu resource structure:
// uint16 menu ID
// uint16 width
// uint16 height
// uint16 command ID
// uint16 padding
// uint32 enable flags
// pstr title (Apple menu is 0x14)
// Zero-byte terminated list:
// pstr Item text (separator is char 0x2d)
// int8 Icon #
// uint8 key
// uint8 submenu ID
// uint8 text style
MenuHandle GetMenu(int resID)
{
PL_NotYetImplemented();
return nullptr;
Handle menuRes = GetResource('MENU', resID);
if (!menuRes)
return nullptr;
const MenuHandle menu = PortabilityLayer::MenuManager::GetInstance()->DeserializeMenu(*menuRes);
ReleaseResource(menuRes);
return menu;
}
void AppendResMenu(MenuHandle menu, UInt32 resType)
void InsertMenu(MenuHandle menu, int beforeID)
{
PL_NotYetImplemented();
}
PortabilityLayer::MenuManager *mm = PortabilityLayer::MenuManager::GetInstance();
if (beforeID)
{
MenuHandle otherMenu = mm->GetMenuByID(beforeID);
if (otherMenu)
{
mm->InsertMenuBefore(menu, otherMenu);
return;
}
}
void InsertMenu(MenuHandle menu, int index)
{
PL_NotYetImplemented();
mm->InsertMenuAtEnd(menu);
}
void DeleteMenu(int menuID)
@@ -23,30 +54,30 @@ void DeleteMenu(int menuID)
void DrawMenuBar()
{
PL_NotYetImplemented();
PL_NotYetImplemented_TODO("Menus");
}
void HiliteMenu(int menu)
{
PL_NotYetImplemented();
PL_NotYetImplemented_TODO("Menus");
}
void EnableMenuItem(MenuHandle menu, int index)
{
PL_NotYetImplemented();
PL_NotYetImplemented_TODO("Menus");
}
void DisableMenuItem(MenuHandle menu, int index)
{
PL_NotYetImplemented();
PL_NotYetImplemented_TODO("Menus");
}
void CheckMenuItem(MenuHandle menu, int index, Boolean checked)
{
PL_NotYetImplemented();
PL_NotYetImplemented_TODO("Menus");
}
void SetMenuItemText(MenuHandle menu, int index, const PLPasStr &text)
{
PL_NotYetImplemented();
PL_NotYetImplemented_TODO("Menus");
}

View File

@@ -7,8 +7,7 @@
class PLPasStr;
MenuHandle GetMenu(int resID);
void AppendResMenu(MenuHandle menu, UInt32 resType); // Appends all menus of a given type
void InsertMenu(MenuHandle menu, int index);
void InsertMenu(MenuHandle menu, int beforeID);
void DeleteMenu(int menuID); // ???
void DrawMenuBar();
void HiliteMenu(int menu);

View File

@@ -31,13 +31,13 @@ OSErr AddUserData(UserData userData, Handle data, UInt32 type)
OSErr OpenMovieFile(const FSSpec *fsSpec, short *outRefNum, int permissions)
{
PL_NotYetImplemented_TODO();
PL_NotYetImplemented_TODO("Movies");
return noErr;
}
OSErr NewMovieFromFile(Movie *movie, short refNum, const short *optResId, StringPtr resName, int flags, Boolean *unused)
{
PL_NotYetImplemented_TODO();
PL_NotYetImplemented_TODO("Movies");
return noErr;
}

View File

@@ -3,14 +3,18 @@
#include "QDState.h"
#include "DisplayDeviceManager.h"
#include "MMHandleBlock.h"
#include "MemoryManager.h"
#include "ResourceManager.h"
#include "ResTypeID.h"
#include "RGBAColor.h"
#include "QDStandardPalette.h"
#include "WindowManager.h"
#include "QDGraf.h"
#include "QDPixMap.h"
#include "QDUtils.h"
#include <assert.h>
void GetPort(GrafPtr *graf)
{
PL_NotYetImplemented();
@@ -27,12 +31,12 @@ void SetPort(GrafPtr graf)
void BeginUpdate(WindowPtr graf)
{
PL_NotYetImplemented();
(void)graf;
}
void EndUpdate(WindowPtr graf)
{
PL_NotYetImplemented();
graf->m_graf.m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents);
}
OSErr GetIconSuite(Handle *suite, short resID, IconSuiteFlags flags)
@@ -83,7 +87,7 @@ void SetPortWindowPort(WindowPtr window)
GDevice **device = wm->GetWindowDevice(window);
PortabilityLayer::QDManager::GetInstance()->SetPort(&window->m_port, device);
PortabilityLayer::QDManager::GetInstance()->SetPort(&window->m_graf.m_port, device);
}
void SetPortDialogPort(Dialog *dialog)
@@ -114,7 +118,10 @@ int TextWidth(const PLPasStr &str, int firstChar1Based, int length)
void MoveTo(int x, int y)
{
PL_NotYetImplemented();
Point &penPos = PortabilityLayer::QDManager::GetInstance()->GetState()->m_penPos;
penPos.h = x;
penPos.v = y;
}
void LineTo(int x, int y)
@@ -194,22 +201,46 @@ void BackColor(SystemColorID color)
void GetForeColor(RGBColor *color)
{
PL_NotYetImplemented();
const PortabilityLayer::RGBAColor foreColor = PortabilityLayer::QDManager::GetInstance()->GetState()->GetForeColor();
color->red = foreColor.r * 0x0101;
color->green = foreColor.g * 0x0101;
color->blue = foreColor.b * 0x0101;
}
void Index2Color(int index, RGBColor *color)
{
PL_NotYetImplemented();
PortabilityLayer::QDPort *port;
PortabilityLayer::QDManager::GetInstance()->GetPort(&port, nullptr);
PortabilityLayer::PixelFormat pf = port->GetPixelFormat();
if (pf == PortabilityLayer::PixelFormat_8BitCustom)
{
PL_NotYetImplemented();
}
else
{
const PortabilityLayer::RGBAColor color8 = PortabilityLayer::StandardPalette::GetInstance()->GetColors()[index];
color->red = color8.r * 0x0101;
color->green = color8.g * 0x0101;
color->blue = color8.b * 0x0101;
}
}
void RGBForeColor(const RGBColor *color)
{
PL_NotYetImplemented();
PortabilityLayer::RGBAColor truncatedColor;
truncatedColor.r = (color->red >> 8);
truncatedColor.g = (color->green >> 8);
truncatedColor.b = (color->blue >> 8);
truncatedColor.a = 255;
PortabilityLayer::QDManager::GetInstance()->GetState()->SetForeColor(truncatedColor);
}
void DrawString(const PLPasStr &str)
{
PL_NotYetImplemented();
PL_NotYetImplemented_TODO("Text");
}
void PaintRect(const Rect *rect)
@@ -382,7 +413,83 @@ void GetIndPattern(Pattern *pattern, int patListID, int index)
void CopyBits(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRect, const Rect *destRect, CopyBitsMode copyMode, RgnHandle maskRegion)
{
PL_NotYetImplemented();
assert(srcBitmap->m_pixelFormat == destBitmap->m_pixelFormat);
const Rect &srcBounds = srcBitmap->m_rect;
const Rect &destBounds = destBitmap->m_rect;
const PortabilityLayer::PixelFormat pixelFormat = srcBitmap->m_pixelFormat;
const size_t srcPitch = srcBitmap->m_pitch;
const size_t destPitch = destBitmap->m_pitch;
assert(srcRect->top >= srcBounds.top);
assert(srcRect->bottom <= srcBounds.bottom);
assert(srcRect->left >= srcBounds.left);
assert(srcRect->right <= srcBounds.right);
assert(destRect->top >= destBounds.top);
assert(destRect->bottom <= destBounds.bottom);
assert(destRect->left >= destBounds.left);
assert(destRect->right <= destBounds.right);
assert(srcRect->right - srcRect->left == destRect->right - destRect->left);
assert(srcRect->bottom - srcRect->top == destRect->bottom - destRect->top);
const Region *mask = *maskRegion;
const Rect constrainedDestRect = destRect->Intersect(mask->rect);
if (!constrainedDestRect.IsValid())
return;
Rect constrainedSrcRect = *srcRect;
constrainedSrcRect.left += constrainedDestRect.left - destRect->left;
constrainedSrcRect.right += constrainedDestRect.right - destRect->right;
constrainedSrcRect.top += constrainedDestRect.top - destRect->top;
constrainedSrcRect.bottom += constrainedDestRect.bottom - destRect->bottom;
const size_t srcFirstCol = constrainedSrcRect.left - srcBitmap->m_rect.left;
const size_t srcFirstRow = constrainedSrcRect.top - srcBitmap->m_rect.top;
const size_t destFirstCol = constrainedDestRect.left - destBitmap->m_rect.left;
const size_t destFirstRow = constrainedDestRect.top - destBitmap->m_rect.top;
if (mask->size != sizeof(Region))
{
PL_NotYetImplemented();
}
else
{
size_t pixelSizeBytes = 0;
switch (pixelFormat)
{
case PortabilityLayer::PixelFormat_8BitCustom:
case PortabilityLayer::PixelFormat_8BitStandard:
pixelSizeBytes = 1;
break;
case PortabilityLayer::PixelFormat_RGB555:
pixelSizeBytes = 2;
break;
case PortabilityLayer::PixelFormat_RGB24:
pixelSizeBytes = 3;
break;
case PortabilityLayer::PixelFormat_RGB32:
pixelSizeBytes = 4;
break;
};
const uint8_t *srcBytes = static_cast<const uint8_t*>(srcBitmap->m_data);
uint8_t *destBytes = static_cast<uint8_t*>(destBitmap->m_data);
const size_t firstSrcByte = srcFirstRow * srcPitch + srcFirstCol * pixelSizeBytes;
const size_t firstDestByte = destFirstRow * destPitch + destFirstCol * pixelSizeBytes;
const size_t numCopiedRows = srcRect->bottom - srcRect->top;
const size_t numCopiedCols = srcRect->right - srcRect->left;
const size_t numCopiedBytesPerScanline = numCopiedCols * pixelSizeBytes;
for (size_t i = 0; i < numCopiedRows; i++)
memcpy(destBytes + firstDestByte + i * destPitch, srcBytes + firstSrcByte + i * srcPitch, numCopiedBytesPerScanline);
}
}
void CopyMask(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBitmap, const Rect *srcRect, const Rect *maskRect, const Rect *destRect)
@@ -393,13 +500,33 @@ void CopyMask(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBit
RgnHandle NewRgn()
{
PL_NotYetImplemented();
return nullptr;
PortabilityLayer::MMHandleBlock *handle = PortabilityLayer::MemoryManager::GetInstance()->AllocHandle(sizeof(Region));
Region *rgn = static_cast<Region*>(handle->m_contents);
rgn->size = sizeof(Region);
rgn->rect = Rect::Create(0, 0, 0, 0);
return reinterpret_cast<Region**>(&handle->m_contents);
}
void RectRgn(RgnHandle region, const Rect *rect)
{
PL_NotYetImplemented();
Region *rgn = *region;
if (rgn->size != sizeof(Region))
{
PortabilityLayer::MemoryManager *mm = PortabilityLayer::MemoryManager::GetInstance();
PortabilityLayer::MMHandleBlock *hdlBlock = reinterpret_cast<PortabilityLayer::MMHandleBlock*>(region);
// OK if this fails, I guess
if (mm->ResizeHandle(hdlBlock, sizeof(Region)))
rgn = static_cast<Region*>(hdlBlock->m_contents);
rgn->size = sizeof(Region);
}
rgn->rect = *rect;
}
void UnionRgn(RgnHandle regionA, RgnHandle regionB, RgnHandle regionC)
@@ -409,7 +536,7 @@ void UnionRgn(RgnHandle regionA, RgnHandle regionB, RgnHandle regionC)
void DisposeRgn(RgnHandle rgn)
{
PL_NotYetImplemented();
DisposeHandle(reinterpret_cast<Handle>(rgn));
}
void OpenRgn()
@@ -441,20 +568,20 @@ void SetClip(RgnHandle rgn)
BitMap *GetPortBitMapForCopyBits(CGrafPtr grafPtr)
{
PL_NotYetImplemented();
return nullptr;
return *grafPtr->m_port.GetPixMap();
}
CGrafPtr GetWindowPort(WindowPtr window)
{
PL_NotYetImplemented();
return nullptr;
return &window->m_graf;
}
RgnHandle GetPortVisibleRegion(CGrafPtr port, RgnHandle region)
{
PL_NotYetImplemented();
return nullptr;
const Rect rect = port->m_port.GetRect();
RectRgn(region, &rect);
return region;
}
@@ -500,3 +627,11 @@ RgnHandle GetGrayRgn()
PL_NotYetImplemented();
return nullptr;
}
void BitMap::Init(const Rect &rect, PortabilityLayer::PixelFormat pixelFormat, size_t pitch, void *dataPtr)
{
m_rect = rect;
m_pixelFormat = pixelFormat;
m_pitch = pitch;
m_data = dataPtr;
}

View File

@@ -88,6 +88,11 @@ struct CIcon
struct BitMap
{
Rect m_rect;
PortabilityLayer::PixelFormat m_pixelFormat;
size_t m_pitch;
void *m_data;
void Init(const Rect &rect, PortabilityLayer::PixelFormat pixelFormat, size_t pitch, void *dataPtr);
};
struct RGBColor

View File

@@ -59,18 +59,22 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\Common.props" />
<Import Project="..\GpCommon.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\Common.props" />
<Import Project="..\GpCommon.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\Common.props" />
<Import Project="..\GpCommon.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\Common.props" />
<Import Project="..\GpCommon.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
@@ -133,10 +137,14 @@
<ClInclude Include="FileManager.h" />
<ClInclude Include="FilePermission.h" />
<ClInclude Include="FilePos.h" />
<ClInclude Include="FontManager.h" />
<ClInclude Include="GpAppInterface.h" />
<ClInclude Include="HostAudioChannel.h" />
<ClInclude Include="HostAudioDriver.h" />
<ClInclude Include="HostDirectoryCursor.h" />
<ClInclude Include="HostFont.h" />
<ClInclude Include="HostFontHandler.h" />
<ClInclude Include="HostInputDriver.h" />
<ClInclude Include="HostMutex.h" />
<ClInclude Include="HostSuspendCallArgument.h" />
<ClInclude Include="HostSuspendCallID.h" />
@@ -144,6 +152,8 @@
<ClInclude Include="HostDisplayDriver.h" />
<ClInclude Include="HostSystemServices.h" />
<ClInclude Include="HostThreadEvent.h" />
<ClInclude Include="HostVOSEventQueue.h" />
<ClInclude Include="InputManager.h" />
<ClInclude Include="IOStream.h" />
<ClInclude Include="MacBinary2.h" />
<ClInclude Include="MacFileMem.h" />
@@ -170,9 +180,11 @@
<ClInclude Include="PLCore.h" />
<ClInclude Include="PLDialogs.h" />
<ClInclude Include="PLErrorCodes.h" />
<ClInclude Include="PLEventQueue.h" />
<ClInclude Include="PLFolders.h" />
<ClInclude Include="PLLowMem.h" />
<ClInclude Include="PLMacTypes.h" />
<ClInclude Include="MenuManager.h" />
<ClInclude Include="QDGraf.h" />
<ClInclude Include="QDManager.h" />
<ClInclude Include="QDPictEmitContext.h" />
@@ -230,17 +242,22 @@
<ClCompile Include="CFileStream.cpp" />
<ClCompile Include="DisplayDeviceManager.cpp" />
<ClCompile Include="FileManager.cpp" />
<ClCompile Include="FontManager.cpp" />
<ClCompile Include="HostAudioDriver.cpp" />
<ClCompile Include="HostDisplayDriver.cpp" />
<ClCompile Include="HostFileSystem.cpp" />
<ClCompile Include="HostFontHandler.cpp" />
<ClCompile Include="HostSuspendHook.cpp" />
<ClCompile Include="HostSystemServices.cpp" />
<ClCompile Include="HostVOSEventQueue.cpp" />
<ClCompile Include="InputManager.cpp" />
<ClCompile Include="MacBinary2.cpp" />
<ClCompile Include="MacFileInfo.cpp" />
<ClCompile Include="MacFileMem.cpp" />
<ClCompile Include="MacLatin1.cpp" />
<ClCompile Include="MemoryManager.cpp" />
<ClCompile Include="MemReaderStream.cpp" />
<ClCompile Include="MenuManager.cpp" />
<ClCompile Include="MMBlock.cpp" />
<ClCompile Include="MMHandleBlock.cpp" />
<ClCompile Include="PLAliases.cpp" />
@@ -249,6 +266,7 @@
<ClCompile Include="PLControlDefinitions.cpp" />
<ClCompile Include="PLCore.cpp" />
<ClCompile Include="PLDialogs.cpp" />
<ClCompile Include="PLEventQueue.cpp" />
<ClCompile Include="PLMenus.cpp" />
<ClCompile Include="PLMovies.cpp" />
<ClCompile Include="PLNavigation.cpp" />

View File

@@ -324,6 +324,30 @@
<ClInclude Include="FilePos.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MenuManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="HostFontHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FontManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="HostFont.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="HostInputDriver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="InputManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="HostVOSEventQueue.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PLEventQueue.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="CFileStream.cpp">
@@ -479,5 +503,23 @@
<ClCompile Include="MacLatin1.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MenuManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="HostFontHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FontManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="InputManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="HostVOSEventQueue.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PLEventQueue.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -8,11 +8,19 @@
struct PixMap;
struct Rect;
struct IGpDisplayDriverSurface;
struct CGraf
{
CGraf()
: m_port(PortabilityLayer::QDPortType_CGraf)
, m_ddSurface(nullptr)
{
}
explicit CGraf(PortabilityLayer::QDPortType overridePortType)
: m_port(overridePortType)
, m_ddSurface(nullptr)
{
}
@@ -24,13 +32,13 @@ struct CGraf
return 0;
}
bool Resize(const Rect &rect)
{
return m_port.Resize(rect);
}
// Must be the first item
PortabilityLayer::QDPort m_port;
};
namespace PortabilityLayer
{
class CGrafImpl final : public CGraf
{
};
}
IGpDisplayDriverSurface *m_ddSurface;
};

View File

@@ -74,14 +74,14 @@ namespace PortabilityLayer
if (depth != 8)
return genericErr;
void *grafStorage = MemoryManager::GetInstance()->Alloc(sizeof(CGrafImpl));
void *grafStorage = MemoryManager::GetInstance()->Alloc(sizeof(CGraf));
if (!grafStorage)
return mFulErr;
if (!bounds.IsValid())
return genericErr;
CGrafImpl *graf = new (grafStorage) CGrafImpl();
CGraf *graf = new (grafStorage) CGraf();
int initError = graf->Init(bounds, pixelFormat);
if (initError)
{

View File

@@ -10,18 +10,16 @@ namespace PortabilityLayer
, m_top(top)
, m_width(width)
, m_height(height)
, m_pitch(PitchForWidth(width, pixelFormat))
, m_pixelFormat(pixelFormat)
{
m_rect.left = left;
m_rect.top = top;
m_rect.right = static_cast<uint16_t>(left + width);
m_rect.bottom = static_cast<uint16_t>(top + height);
m_pitch = (width + PL_SYSTEM_MEMORY_ALIGNMENT - 1);
m_pitch -= m_pitch % PL_SYSTEM_MEMORY_ALIGNMENT;
m_data = reinterpret_cast<uint8_t*>(this) + AlignedSize();
, m_dataCapacity(0)
{
const Rect rect = Rect::Create(top, left, static_cast<uint16_t>(top + height), static_cast<uint16_t>(left + width));
const size_t pitch = PitchForWidth(width, pixelFormat);
void *dataPtr = reinterpret_cast<uint8_t*>(this) + AlignedSize();
m_dataCapacity = PitchForWidth(width, pixelFormat) * height;
static_cast<PixMap*>(this)->Init(rect, pixelFormat, PitchForWidth(width, pixelFormat), dataPtr);
}
size_t PixMapImpl::SizeForDimensions(uint16_t width, uint16_t height, PixelFormat pixelFormat)
@@ -66,3 +64,8 @@ namespace PortabilityLayer
return szAdjusted;
}
}
void PixMap::Init(const Rect &rect, PortabilityLayer::PixelFormat pixelFormat, size_t pitch, void *dataPtr)
{
BitMap::Init(rect, pixelFormat, pitch, dataPtr);
}

View File

@@ -7,7 +7,8 @@
#include <stdint.h>
struct PixMap : public BitMap
{
{
void Init(const Rect &rect, PortabilityLayer::PixelFormat pixelFormat, size_t pitch, void *dataPtr);
};
namespace PortabilityLayer
@@ -20,7 +21,8 @@ namespace PortabilityLayer
PixelFormat GetPixelFormat() const;
size_t GetPitch() const;
void *GetPixelData();
const void *GetPixelData() const;
const void *GetPixelData() const;
size_t GetDataCapacity() const;
static size_t SizeForDimensions(uint16_t width, uint16_t height, PixelFormat pixelFormat);
@@ -32,10 +34,8 @@ namespace PortabilityLayer
int16_t m_top;
uint16_t m_width;
uint16_t m_height;
PixelFormat m_pixelFormat;
size_t m_pitch;
void *m_data;
size_t m_dataCapacity;
};
}
@@ -57,4 +57,9 @@ inline void *PortabilityLayer::PixMapImpl::GetPixelData()
inline const void *PortabilityLayer::PixMapImpl::GetPixelData() const
{
return m_data;
}
inline size_t PortabilityLayer::PixMapImpl::GetDataCapacity() const
{
return m_dataCapacity;
}

View File

@@ -14,10 +14,16 @@ namespace PortabilityLayer
, m_height(0)
, m_pixMap(nullptr)
, m_pixelFormat(PixelFormat_Invalid)
, m_dirtyFlags(0)
{
}
QDPort::~QDPort()
{
DisposePixMap();
}
void QDPort::DisposePixMap()
{
if (m_pixMap)
{
@@ -29,25 +35,57 @@ namespace PortabilityLayer
int QDPort::Init(const Rect &rect, PixelFormat pixelFormat)
{
m_left = rect.left;
m_top = rect.top;
m_width = static_cast<uint16_t>(rect.right - rect.left);
m_height = static_cast<uint16_t>(rect.bottom - rect.top);
m_pixMap = nullptr;
m_pixelFormat = pixelFormat;
size_t pixMapSize = PixMapImpl::SizeForDimensions(m_width, m_height, m_pixelFormat);
if (pixMapSize == 0)
if (!Resize(rect))
return mFulErr;
return noErr;
}
bool QDPort::Resize(const Rect &rect)
{
const uint16_t width = static_cast<uint16_t>(rect.right - rect.left);
const uint16_t height = static_cast<uint16_t>(rect.bottom - rect.top);
size_t pixMapSize = PixMapImpl::SizeForDimensions(width, height, m_pixelFormat);
if (pixMapSize == 0)
return false;
MMHandleBlock *pmBlock = MemoryManager::GetInstance()->AllocHandle(pixMapSize);
if (!pmBlock)
return mFulErr;
return false;
SetDirty(QDPortDirtyFlag_Size | QDPortDirtyFlag_Contents);
m_left = rect.left;
m_top = rect.top;
m_width = width;
m_height = height;
new (pmBlock->m_contents) PixMapImpl(m_left, m_top, width, height, m_pixelFormat);
DisposePixMap();
new (pmBlock->m_contents) PixMapImpl(m_left, m_top, m_width, m_height, m_pixelFormat);
m_pixMap = reinterpret_cast<PixMap**>(&pmBlock->m_contents);
return noErr;
return true;
}
bool QDPort::IsDirty(uint32_t flag) const
{
return (m_dirtyFlags & flag) != 0;
}
void QDPort::SetDirty(uint32_t flag)
{
m_dirtyFlags |= flag;
}
void QDPort::ClearDirty(uint32_t flag)
{
m_dirtyFlags &= ~flag;
}
PixMap **QDPort::GetPixMap() const
@@ -72,6 +110,6 @@ namespace PortabilityLayer
Rect QDPort::GetRect() const
{
return Rect::Create(0, 0, m_height, m_width);
return Rect::Create(m_top, m_left, m_top + m_height, m_left + m_width);
}
}

View File

@@ -15,6 +15,12 @@ namespace PortabilityLayer
QDPortType_CGraf,
QDPortType_Window,
};
enum QDPortDirtyFlag
{
QDPortDirtyFlag_Size = 1,
QDPortDirtyFlag_Contents = 2,
};
class QDPort
@@ -32,7 +38,15 @@ namespace PortabilityLayer
PixelFormat GetPixelFormat() const;
Rect GetRect() const;
bool Resize(const Rect &rect);
bool IsDirty(uint32_t flag) const;
void SetDirty(uint32_t flag);
void ClearDirty(uint32_t flag);
private:
void DisposePixMap();
QDPortType m_portType;
QDState m_state;
@@ -42,6 +56,7 @@ namespace PortabilityLayer
int16_t m_top;
uint16_t m_width;
uint16_t m_height;
uint32_t m_dirtyFlags;
PixelFormat m_pixelFormat;
};

View File

@@ -17,11 +17,12 @@ namespace PortabilityLayer
, m_isBackResolved16(false)
, m_isForeResolved8(false)
, m_isBackResolved8(false)
, m_clipRegion(nullptr)
, m_clipRegion(nullptr)
{
m_backUnresolvedColor.r = m_backUnresolvedColor.g = m_backUnresolvedColor.b = m_backUnresolvedColor.a = 255;
m_foreUnresolvedColor.r = m_foreUnresolvedColor.g = m_foreUnresolvedColor.b = 0;
m_foreUnresolvedColor.a = 255;
m_foreUnresolvedColor.a = 255;
m_penPos.h = m_penPos.v = 0;
}
void QDState::SetForeColor(const RGBAColor &color)
@@ -38,6 +39,16 @@ namespace PortabilityLayer
m_isBackResolved8 = false;
}
const RGBAColor &QDState::GetForeColor() const
{
return m_foreUnresolvedColor;
}
const RGBAColor &QDState::GetBackColor() const
{
return m_backUnresolvedColor;
}
uint8_t QDState::ResolveForeColor8(const RGBAColor *palette, unsigned int numColors)
{
return ResolveColor8(m_foreUnresolvedColor, m_foreResolvedColor8, m_isForeResolved8, palette, numColors);

View File

@@ -1,23 +1,28 @@
#pragma once
#include "RGBAColor.h"
#include "SharedTypes.h"
struct Region;
namespace PortabilityLayer
{
struct QDState
{
struct Region;
namespace PortabilityLayer
{
struct QDState
{
QDState();
int m_fontID;
int m_textFace;
int m_textSize;
Region **m_clipRegion;
Point m_penPos;
void SetForeColor(const RGBAColor &color);
void SetBackColor(const RGBAColor &color);
const RGBAColor &GetForeColor() const;
const RGBAColor &GetBackColor() const;
uint8_t ResolveForeColor8(const RGBAColor *palette, unsigned int numColors);
uint8_t ResolveBackColor8(const RGBAColor *palette, unsigned int numColors);
@@ -34,7 +39,7 @@ namespace PortabilityLayer
bool m_isForeResolved16;
bool m_isForeResolved8;
bool m_isBackResolved16;
bool m_isBackResolved8;
};
}
bool m_isBackResolved16;
bool m_isBackResolved8;
};
}

View File

@@ -1,7 +1,9 @@
#pragma once
#include "CoreDefs.h"
#include "PLBigEndian.h"
#include "PixelFormat.h"
#include "RGBAColor.h"
struct Point
{
@@ -92,6 +94,10 @@ struct BEColorTableItem
struct GDevice
{
PortabilityLayer::PixelFormat pixelFormat;
uint8_t paletteStorage[256 * 4 + PL_SYSTEM_MEMORY_ALIGNMENT];
uint8_t paletteDataOffset;
bool paletteIsDirty;
};
inline bool Rect::IsValid() const

View File

@@ -10,5 +10,6 @@ namespace PortabilityLayer
EVirtualDirectory_GameData,
EVirtualDirectory_UserData,
EVirtualDirectory_Prefs,
EVirtualDirectory_Fonts,
};
}

View File

@@ -2,10 +2,14 @@
#include "DisplayDeviceManager.h"
#include "HostDisplayDriver.h"
#include "IGpDisplayDriver.h"
#include "IGpDisplayDriverSurface.h"
#include "PLCore.h"
#include "PLEventQueue.h"
#include "MemoryManager.h"
#include "QDGraf.h"
#include "QDManager.h"
#include "QDPixMap.h"
#include "WindowDef.h"
struct GDevice;
@@ -21,7 +25,7 @@ namespace PortabilityLayer
~WindowImpl();
bool Init(const WindowDef &windowDef, GDevice **device);
void Resize(int width, int height);
bool Resize(int width, int height);
WindowImpl *GetWindowAbove() const;
WindowImpl *GetWindowBelow() const;
@@ -55,11 +59,14 @@ namespace PortabilityLayer
void HideWindow(Window *window) override;
GDevice **GetWindowDevice(Window *window) override;
void RenderFrame(IGpDisplayDriver *displayDriver) override;
Window *GetPutInFrontSentinel() const override;
static WindowManagerImpl *GetInstance();
private:
void RenderWindow(WindowImpl *window, IGpDisplayDriver *displayDriver);
void DetachWindow(Window *window);
WindowImpl *m_windowStackTop;
@@ -91,7 +98,7 @@ namespace PortabilityLayer
const Rect adjustedBounds = Rect::Create(0, 0, bounds.bottom - bounds.top, bounds.right - bounds.left);
if (int errorCode = m_port.Init(adjustedBounds, (*device)->pixelFormat))
if (int errorCode = m_graf.Init(adjustedBounds, (*device)->pixelFormat))
return false;
m_device = device;
@@ -99,8 +106,13 @@ namespace PortabilityLayer
return true;
}
void WindowImpl::Resize(int width, int height)
bool WindowImpl::Resize(int width, int height)
{
Rect rect = m_graf.m_port.GetRect();
rect.right = rect.left + width;
rect.bottom = rect.top + height;
return m_graf.Resize(rect);
}
WindowImpl *WindowImpl::GetWindowAbove() const
@@ -164,6 +176,12 @@ namespace PortabilityLayer
return nullptr;
}
if (EventRecord *evt = PortabilityLayer::EventQueue::GetInstance()->Enqueue())
{
evt->what = updateEvt;
evt->message = reinterpret_cast<intptr_t>(static_cast<Window*>(window));
}
return window;
}
@@ -179,6 +197,7 @@ namespace PortabilityLayer
if (m_windowStackTop)
{
m_windowStackTop->SetWindowAbove(window);
window->SetWindowBelow(m_windowStackTop);
m_windowStackTop = window;
}
else
@@ -226,14 +245,44 @@ namespace PortabilityLayer
return static_cast<WindowImpl*>(window)->GetDevice();
}
void WindowManagerImpl::RenderFrame(IGpDisplayDriver *displayDriver)
{
GDevice **mainDeviceHdl = PortabilityLayer::DisplayDeviceManager::GetInstance()->GetMainDevice();
if (mainDeviceHdl)
{
GDevice *mainDevice = *mainDeviceHdl;
if (mainDevice->paletteIsDirty)
{
displayDriver->UpdatePalette(mainDevice->paletteStorage + mainDevice->paletteDataOffset);
mainDevice->paletteIsDirty = false;
}
WindowImpl *window = m_windowStackBottom;
while (window)
{
RenderWindow(window, displayDriver);
window = window->GetWindowAbove();
}
}
}
void WindowManagerImpl::ResizeWindow(Window *window, int width, int height)
{
static_cast<WindowImpl*>(window)->Resize(width, height);
if (EventRecord *evt = PortabilityLayer::EventQueue::GetInstance()->Enqueue())
{
evt->what = updateEvt;
evt->message = reinterpret_cast<intptr_t>(window);
}
}
void WindowManagerImpl::MoveWindow(Window *window, int x, int y)
{
PL_NotYetImplemented_Minor();
window->m_wmX = x;
window->m_wmY = y;
}
void WindowManagerImpl::DetachWindow(Window *window)
@@ -260,6 +309,36 @@ namespace PortabilityLayer
return &ms_putInFront;
}
void WindowManagerImpl::RenderWindow(WindowImpl *window, IGpDisplayDriver *displayDriver)
{
GDevice *device = *window->GetDevice();
CGraf &graf = window->m_graf;
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);
}
WindowManagerImpl *WindowManagerImpl::GetInstance()
{
return &ms_instance;

View File

@@ -3,6 +3,7 @@
struct Window;
struct CGraf;
struct GDevice;
struct IGpDisplayDriver;
namespace PortabilityLayer
{
@@ -20,6 +21,8 @@ namespace PortabilityLayer
virtual void HideWindow(Window *window) = 0;
virtual GDevice **GetWindowDevice(Window *window) = 0;
virtual void RenderFrame(IGpDisplayDriver *displayDriver) = 0;
static WindowManager *GetInstance();
};
}