mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-09-23 06:53:43 +00:00
Add FreeType, progress to title screen
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
68
PortabilityLayer/FontManager.cpp
Normal file
68
PortabilityLayer/FontManager.cpp
Normal 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();
|
||||
}
|
||||
}
|
13
PortabilityLayer/FontManager.h
Normal file
13
PortabilityLayer/FontManager.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
class FontManager
|
||||
{
|
||||
public:
|
||||
virtual void Init() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
static FontManager *GetInstance();
|
||||
};
|
||||
}
|
@@ -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;
|
||||
};
|
||||
|
||||
|
@@ -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
|
||||
|
10
PortabilityLayer/HostFont.h
Normal file
10
PortabilityLayer/HostFont.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
class HostFont
|
||||
{
|
||||
public:
|
||||
virtual void Destroy() = 0;
|
||||
};
|
||||
}
|
16
PortabilityLayer/HostFontHandler.cpp
Normal file
16
PortabilityLayer/HostFontHandler.cpp
Normal 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;
|
||||
}
|
21
PortabilityLayer/HostFontHandler.h
Normal file
21
PortabilityLayer/HostFontHandler.h
Normal 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;
|
||||
};
|
||||
}
|
17
PortabilityLayer/HostInputDriver.h
Normal file
17
PortabilityLayer/HostInputDriver.h
Normal 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;
|
||||
};
|
||||
}
|
@@ -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
|
||||
|
16
PortabilityLayer/HostVOSEventQueue.cpp
Normal file
16
PortabilityLayer/HostVOSEventQueue.cpp
Normal 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;
|
||||
}
|
19
PortabilityLayer/HostVOSEventQueue.h
Normal file
19
PortabilityLayer/HostVOSEventQueue.h
Normal 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;
|
||||
};
|
||||
}
|
44
PortabilityLayer/InputManager.cpp
Normal file
44
PortabilityLayer/InputManager.cpp
Normal 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();
|
||||
}
|
||||
}
|
12
PortabilityLayer/InputManager.h
Normal file
12
PortabilityLayer/InputManager.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
class InputManager
|
||||
{
|
||||
public:
|
||||
virtual void GetKeys(unsigned char *keys16) const = 0;
|
||||
|
||||
static InputManager *GetInstance();
|
||||
};
|
||||
}
|
229
PortabilityLayer/MenuManager.cpp
Normal file
229
PortabilityLayer/MenuManager.cpp
Normal 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();
|
||||
}
|
||||
}
|
19
PortabilityLayer/MenuManager.h
Normal file
19
PortabilityLayer/MenuManager.h
Normal 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();
|
||||
};
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
#include "PLControlDefinitions.h"
|
||||
|
||||
#include "PLControlDefinitions.h"
|
||||
|
||||
|
||||
int FindControl(Point point, WindowPtr window, ControlHandle *outControl)
|
||||
{
|
||||
|
@@ -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)
|
||||
{
|
||||
}
|
||||
|
@@ -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();
|
||||
|
||||
|
||||
|
82
PortabilityLayer/PLEventQueue.cpp
Normal file
82
PortabilityLayer/PLEventQueue.cpp
Normal 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();
|
||||
}
|
||||
}
|
17
PortabilityLayer/PLEventQueue.h
Normal file
17
PortabilityLayer/PLEventQueue.h
Normal 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();
|
||||
};
|
||||
}
|
@@ -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");
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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" />
|
||||
|
@@ -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>
|
@@ -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;
|
||||
};
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
};
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -10,5 +10,6 @@ namespace PortabilityLayer
|
||||
EVirtualDirectory_GameData,
|
||||
EVirtualDirectory_UserData,
|
||||
EVirtualDirectory_Prefs,
|
||||
EVirtualDirectory_Fonts,
|
||||
};
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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();
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user