mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-12-14 12:09:36 +00:00
Fix house data corruption, progress to first screen
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -22,3 +22,4 @@
|
|||||||
*.res
|
*.res
|
||||||
.vs/*
|
.vs/*
|
||||||
Packaged/*
|
Packaged/*
|
||||||
|
DebugData/*
|
||||||
@@ -176,6 +176,9 @@ void BringUpBanner (void)
|
|||||||
|
|
||||||
DrawBanner(&topLeft);
|
DrawBanner(&topLeft);
|
||||||
DrawBannerMessage(topLeft);
|
DrawBannerMessage(topLeft);
|
||||||
|
|
||||||
|
DumpScreenOn(&justRoomsRect);
|
||||||
|
|
||||||
// if (quickerTransitions)
|
// if (quickerTransitions)
|
||||||
// DissBitsChunky(&justRoomsRect); // was workSrcRect
|
// DissBitsChunky(&justRoomsRect); // was workSrcRect
|
||||||
// else
|
// else
|
||||||
@@ -187,6 +190,7 @@ void BringUpBanner (void)
|
|||||||
(BitMap *)*GetGWorldPixMap(workSrcMap),
|
(BitMap *)*GetGWorldPixMap(workSrcMap),
|
||||||
&wholePage, &wholePage, srcCopy, nil);
|
&wholePage, &wholePage, srcCopy, nil);
|
||||||
|
|
||||||
|
|
||||||
if (demoGoing)
|
if (demoGoing)
|
||||||
WaitForInputEvent(4);
|
WaitForInputEvent(4);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -474,6 +474,8 @@ void DoDiedGameOver (void)
|
|||||||
pagesStuck = 8;
|
pagesStuck = 8;
|
||||||
userAborted = true;
|
userAborted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Delay(1, nullptr);
|
||||||
}
|
}
|
||||||
while (TickCount() < nextLoop);
|
while (TickCount() < nextLoop);
|
||||||
nextLoop = TickCount() + 2;
|
nextLoop = TickCount() + 2;
|
||||||
|
|||||||
@@ -194,7 +194,11 @@ typedef struct
|
|||||||
Boolean unusedBoolean; // 1
|
Boolean unusedBoolean; // 1
|
||||||
int16_t firstRoom; // 2
|
int16_t firstRoom; // 2
|
||||||
int16_t nRooms; // 2
|
int16_t nRooms; // 2
|
||||||
|
|
||||||
|
int16_t padding;
|
||||||
roomType rooms[1]; // 348 * nRooms
|
roomType rooms[1]; // 348 * nRooms
|
||||||
|
|
||||||
|
static const size_t kBinaryDataSize = 866;
|
||||||
} houseType, *housePtr, **houseHand; // total = 866 +
|
} houseType, *housePtr, **houseHand; // total = 866 +
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|||||||
@@ -598,7 +598,7 @@ bool ByteSwapHouse(housePtr house, size_t sizeInBytes)
|
|||||||
PortabilityLayer::ByteSwap::BigInt16(house->firstRoom);
|
PortabilityLayer::ByteSwap::BigInt16(house->firstRoom);
|
||||||
PortabilityLayer::ByteSwap::BigInt16(house->nRooms);
|
PortabilityLayer::ByteSwap::BigInt16(house->nRooms);
|
||||||
|
|
||||||
const size_t roomDataSize = sizeInBytes + sizeof(roomType) - sizeof(houseType);
|
const size_t roomDataSize = sizeInBytes - houseType::kBinaryDataSize;
|
||||||
if (house->nRooms < 1 || roomDataSize / sizeof(roomType) < static_cast<size_t>(house->nRooms))
|
if (house->nRooms < 1 || roomDataSize / sizeof(roomType) < static_cast<size_t>(house->nRooms))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -615,6 +615,9 @@ Boolean ReadHouse (void)
|
|||||||
OSErr theErr;
|
OSErr theErr;
|
||||||
short whichRoom;
|
short whichRoom;
|
||||||
|
|
||||||
|
// There should be no padding remaining the house type
|
||||||
|
PL_STATIC_ASSERT(sizeof(houseType) - sizeof(roomType) == houseType::kBinaryDataSize + 2);
|
||||||
|
|
||||||
if (!houseOpen)
|
if (!houseOpen)
|
||||||
{
|
{
|
||||||
YellowAlert(kYellowUnaccounted, 2);
|
YellowAlert(kYellowUnaccounted, 2);
|
||||||
@@ -650,7 +653,10 @@ Boolean ReadHouse (void)
|
|||||||
if (thisHouse != nil)
|
if (thisHouse != nil)
|
||||||
DisposeHandle((Handle)thisHouse);
|
DisposeHandle((Handle)thisHouse);
|
||||||
|
|
||||||
thisHouse = (houseHand)NewHandle(byteCount);
|
// GP: Correct for padding
|
||||||
|
const size_t alignmentPadding = sizeof(houseType) - sizeof(roomType) - houseType::kBinaryDataSize;
|
||||||
|
|
||||||
|
thisHouse = (houseHand)NewHandle(byteCount + alignmentPadding);
|
||||||
if (thisHouse == nil)
|
if (thisHouse == nil)
|
||||||
{
|
{
|
||||||
YellowAlert(kYellowNoMemory, 10);
|
YellowAlert(kYellowNoMemory, 10);
|
||||||
@@ -666,14 +672,24 @@ Boolean ReadHouse (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
HLock((Handle)thisHouse);
|
HLock((Handle)thisHouse);
|
||||||
theErr = FSRead(houseRefNum, &byteCount, *thisHouse);
|
long readByteCount = byteCount;
|
||||||
if (theErr != noErr)
|
theErr = FSRead(houseRefNum, &readByteCount, *thisHouse);
|
||||||
|
if (theErr != noErr || readByteCount != byteCount || byteCount < static_cast<long>(houseType::kBinaryDataSize))
|
||||||
{
|
{
|
||||||
CheckFileError(theErr, thisHouseName);
|
CheckFileError(theErr, thisHouseName);
|
||||||
HUnlock((Handle)thisHouse);
|
HUnlock((Handle)thisHouse);
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (alignmentPadding != 0)
|
||||||
|
{
|
||||||
|
// GP: Correct for padding
|
||||||
|
const size_t roomDataSize = byteCount - houseType::kBinaryDataSize;
|
||||||
|
|
||||||
|
uint8_t *houseDataBytes = reinterpret_cast<uint8_t*>(*thisHouse);
|
||||||
|
memmove((*thisHouse)->rooms, houseDataBytes + houseType::kBinaryDataSize, roomDataSize);
|
||||||
|
}
|
||||||
|
|
||||||
ByteSwapHouse(*thisHouse, static_cast<size_t>(byteCount));
|
ByteSwapHouse(*thisHouse, static_cast<size_t>(byteCount));
|
||||||
|
|
||||||
numberRooms = (*thisHouse)->nRooms;
|
numberRooms = (*thisHouse)->nRooms;
|
||||||
@@ -791,10 +807,23 @@ Boolean WriteHouse (Boolean checkIt)
|
|||||||
|
|
||||||
ByteSwapHouse(*thisHouse, static_cast<size_t>(byteCount));
|
ByteSwapHouse(*thisHouse, static_cast<size_t>(byteCount));
|
||||||
|
|
||||||
theErr = FSWrite(houseRefNum, &byteCount, *thisHouse);
|
long headerSize = houseType::kBinaryDataSize;
|
||||||
|
long roomsSize = sizeof(roomType) * (*thisHouse)->nRooms;
|
||||||
|
|
||||||
|
theErr = FSWrite(houseRefNum, &headerSize, *thisHouse);
|
||||||
if (theErr != noErr)
|
if (theErr != noErr)
|
||||||
{
|
{
|
||||||
CheckFileError(theErr, thisHouseName);
|
CheckFileError(theErr, thisHouseName);
|
||||||
|
ByteSwapHouse(*thisHouse, static_cast<size_t>(byteCount));
|
||||||
|
HUnlock((Handle)thisHouse);
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
theErr = FSWrite(houseRefNum, &roomsSize, (*thisHouse)->rooms);
|
||||||
|
if (theErr != noErr)
|
||||||
|
{
|
||||||
|
CheckFileError(theErr, thisHouseName);
|
||||||
|
ByteSwapHouse(*thisHouse, static_cast<size_t>(byteCount));
|
||||||
HUnlock((Handle)thisHouse);
|
HUnlock((Handle)thisHouse);
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ extern Boolean switchedOut;
|
|||||||
void NewGame (short mode)
|
void NewGame (short mode)
|
||||||
{
|
{
|
||||||
Rect tempRect;
|
Rect tempRect;
|
||||||
Size freeBytes, growBytes;
|
|
||||||
OSErr theErr;
|
OSErr theErr;
|
||||||
Boolean wasPlayMusicPref;
|
Boolean wasPlayMusicPref;
|
||||||
|
|
||||||
@@ -192,8 +191,6 @@ void NewGame (short mode)
|
|||||||
InitTelephone();
|
InitTelephone();
|
||||||
wasPlayMusicPref = isPlayMusicGame;
|
wasPlayMusicPref = isPlayMusicGame;
|
||||||
|
|
||||||
freeBytes = MaxMem(&growBytes);
|
|
||||||
|
|
||||||
#ifdef CREATEDEMODATA
|
#ifdef CREATEDEMODATA
|
||||||
SysBeep(1);
|
SysBeep(1);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -617,14 +617,18 @@ void CopyRectsQD (void)
|
|||||||
{
|
{
|
||||||
short i;
|
short i;
|
||||||
|
|
||||||
|
CGrafPtr mainWindowGraf = GetWindowPort(mainWindow);
|
||||||
|
|
||||||
for (i = 0; i < numWork2Main; i++)
|
for (i = 0; i < numWork2Main; i++)
|
||||||
{
|
{
|
||||||
CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap),
|
CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap),
|
||||||
GetPortBitMapForCopyBits(GetWindowPort(mainWindow)),
|
GetPortBitMapForCopyBits(mainWindowGraf),
|
||||||
&work2MainRects[i], &work2MainRects[i],
|
&work2MainRects[i], &work2MainRects[i],
|
||||||
srcCopy, nil);
|
srcCopy, nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mainWindowGraf->m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents);
|
||||||
|
|
||||||
for (i = 0; i < numBack2Work; i++)
|
for (i = 0; i < numBack2Work; i++)
|
||||||
{
|
{
|
||||||
CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap),
|
CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap),
|
||||||
@@ -661,6 +665,7 @@ void RenderFrame (void)
|
|||||||
|
|
||||||
while (TickCount() < nextFrame)
|
while (TickCount() < nextFrame)
|
||||||
{
|
{
|
||||||
|
Delay(1, nullptr);
|
||||||
}
|
}
|
||||||
nextFrame = TickCount() + kTicksPerFrame;
|
nextFrame = TickCount() + kTicksPerFrame;
|
||||||
|
|
||||||
|
|||||||
@@ -138,8 +138,12 @@ void WipeScreenOn (short direction, Rect *theRect)
|
|||||||
|
|
||||||
void DumpScreenOn (Rect *theRect)
|
void DumpScreenOn (Rect *theRect)
|
||||||
{
|
{
|
||||||
|
CGrafPtr graf = GetWindowPort(mainWindow);
|
||||||
|
|
||||||
CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap),
|
CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap),
|
||||||
GetPortBitMapForCopyBits(GetWindowPort(mainWindow)),
|
GetPortBitMapForCopyBits(graf),
|
||||||
theRect, theRect, srcCopy, nil);
|
theRect, theRect, srcCopy, nil);
|
||||||
|
|
||||||
|
graf->m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -249,6 +249,7 @@ OSErr CreateOffScreenGWorld (GWorldPtr *theGWorld, Rect *bounds, short depth)
|
|||||||
if (theErr)
|
if (theErr)
|
||||||
theErr = NewGWorld(theGWorld, depth, bounds, nil, nil, 0);
|
theErr = NewGWorld(theGWorld, depth, bounds, nil, nil, 0);
|
||||||
|
|
||||||
|
if (!theErr)
|
||||||
LockPixels(GetGWorldPixMap(*theGWorld));
|
LockPixels(GetGWorldPixMap(*theGWorld));
|
||||||
|
|
||||||
return theErr;
|
return theErr;
|
||||||
@@ -450,6 +451,8 @@ Boolean WaitForInputEvent (short seconds)
|
|||||||
}
|
}
|
||||||
if ((seconds != -1) && (TickCount() >= timeToBail))
|
if ((seconds != -1) && (TickCount() >= timeToBail))
|
||||||
waiting = false;
|
waiting = false;
|
||||||
|
|
||||||
|
Delay(1, nullptr);
|
||||||
}
|
}
|
||||||
FlushEvents(everyEvent, 0);
|
FlushEvents(everyEvent, 0);
|
||||||
return (didResume);
|
return (didResume);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ namespace GpPixelFormats
|
|||||||
{
|
{
|
||||||
kInvalid,
|
kInvalid,
|
||||||
|
|
||||||
|
kBW1,
|
||||||
k8BitStandard,
|
k8BitStandard,
|
||||||
k8BitCustom,
|
k8BitCustom,
|
||||||
kRGB555,
|
kRGB555,
|
||||||
|
|||||||
@@ -18,39 +18,44 @@
|
|||||||
#include "QDManager.h"
|
#include "QDManager.h"
|
||||||
#include "QDPixMap.h"
|
#include "QDPixMap.h"
|
||||||
#include "RGBAColor.h"
|
#include "RGBAColor.h"
|
||||||
|
#include "Vec2i.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
static const int kMidGray = 187;
|
||||||
|
|
||||||
const PortabilityLayer::RGBAColor gs_barTopLeftCornerGraphicPixels[] =
|
const PortabilityLayer::RGBAColor gs_barTopLeftCornerGraphicPixels[] =
|
||||||
{
|
{
|
||||||
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 85, 85, 85, 255 }, { 170, 170, 170, 255 },
|
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 85, 85, 85, 255 }, { 170, 170, 170, 255 },
|
||||||
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 85, 85, 85, 255 }, { 255, 255, 255, 255 }, { 255, 255, 255, 255 },
|
{ 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 85, 85, 85, 255 }, { 255, 255, 255, 255 }, { 255, 255, 255, 255 },
|
||||||
{ 0, 0, 0, 255 }, { 85, 85, 85, 255 }, { 255, 255, 255, 255 }, { 221, 221, 221, 255 }, { 221, 221, 221, 255 },
|
{ 0, 0, 0, 255 }, { 85, 85, 85, 255 }, { 255, 255, 255, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 },
|
||||||
{ 85, 85, 85, 255 }, { 255, 255, 255, 255 }, { 221, 221, 221, 255 }, { 221, 221, 221, 255 }, { 221, 221, 221, 255 },
|
{ 85, 85, 85, 255 }, { 255, 255, 255, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 },
|
||||||
{ 170, 170, 170, 255 }, { 255, 255, 255, 255 }, { 221, 221, 221, 255 }, { 221, 221, 221, 255 }, { 221, 221, 221, 255 },
|
{ 170, 170, 170, 255 }, { 255, 255, 255, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 },
|
||||||
};
|
};
|
||||||
|
|
||||||
const PortabilityLayer::RGBAColor gs_barTopRightCornerGraphicPixels[] =
|
const PortabilityLayer::RGBAColor gs_barTopRightCornerGraphicPixels[] =
|
||||||
{
|
{
|
||||||
{ 170, 170, 170, 255 }, { 85, 85, 85, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
|
{ 170, 170, 170, 255 }, { 85, 85, 85, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
|
||||||
{ 255, 255, 255, 255 }, { 255, 255, 255, 255 }, { 85, 85, 85, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
|
{ 255, 255, 255, 255 }, { 255, 255, 255, 255 }, { 85, 85, 85, 255 }, { 0, 0, 0, 255 }, { 0, 0, 0, 255 },
|
||||||
{ 221, 221, 221, 255 }, { 221, 221, 221, 255 }, { 255, 255, 255, 255 }, { 85, 85, 85, 255 }, { 0, 0, 0, 255 },
|
{ kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { 255, 255, 255, 255 }, { 85, 85, 85, 255 }, { 0, 0, 0, 255 },
|
||||||
{ 221, 221, 221, 255 }, { 221, 221, 221, 255 }, { 221, 221, 221, 255 }, { 255, 255, 255, 255 }, { 85, 85, 85, 255 },
|
{ kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { 255, 255, 255, 255 }, { 85, 85, 85, 255 },
|
||||||
{ 221, 221, 221, 255 }, { 221, 221, 221, 255 }, { 221, 221, 221, 255 }, { 255, 255, 255, 255 }, { 85, 85, 85, 255 },
|
{ kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { kMidGray, kMidGray, kMidGray, 255 }, { 255, 255, 255, 255 }, { 85, 85, 85, 255 },
|
||||||
};
|
};
|
||||||
|
|
||||||
const PortabilityLayer::RGBAColor gs_barBrightColor = { 255, 255, 255, 255 };
|
const PortabilityLayer::RGBAColor gs_barBrightColor = { 255, 255, 255, 255 };
|
||||||
const PortabilityLayer::RGBAColor gs_barMidColor = { 221, 221, 221, 255 };
|
const PortabilityLayer::RGBAColor gs_barMidColor = { kMidGray, kMidGray, kMidGray, 255 };
|
||||||
const PortabilityLayer::RGBAColor gs_barDarkColor = { 102, 102, 102, 255 };
|
const PortabilityLayer::RGBAColor gs_barDarkColor = { 102, 102, 102, 255 };
|
||||||
const PortabilityLayer::RGBAColor gs_barBottomEdgeColor = { 0, 0, 0, 255 };
|
const PortabilityLayer::RGBAColor gs_barBottomEdgeColor = { 0, 0, 0, 255 };
|
||||||
const PortabilityLayer::RGBAColor gs_barNormalTextColor = { 0, 0, 0, 255 };
|
const PortabilityLayer::RGBAColor gs_barNormalTextColor = { 0, 0, 0, 255 };
|
||||||
|
const PortabilityLayer::RGBAColor gs_barHighlightTextColor = { 255, 255, 255, 255 };
|
||||||
|
|
||||||
const PortabilityLayer::RGBAColor gs_barHighlightBrightColor = { 153, 153, 255, 255 };
|
const PortabilityLayer::RGBAColor gs_barHighlightBrightColor = { 153, 204, 255, 255 };
|
||||||
const PortabilityLayer::RGBAColor gs_barHighlightMidColor = { 102, 102, 204, 255 };
|
const PortabilityLayer::RGBAColor gs_barHighlightMidColor = { 51, 102, 204, 255 };
|
||||||
const PortabilityLayer::RGBAColor gs_barHighlightDarkColor = { 51, 51, 102, 255 };
|
const PortabilityLayer::RGBAColor gs_barHighlightDarkColor = { 0, 51, 102, 255 };
|
||||||
|
|
||||||
PortabilityLayer::SimpleGraphicInstanceRGBA<5, 5> gs_barTopLeftCornerGraphic(gs_barTopLeftCornerGraphicPixels);
|
PortabilityLayer::SimpleGraphicInstanceRGBA<5, 5> gs_barTopLeftCornerGraphic(gs_barTopLeftCornerGraphicPixels);
|
||||||
PortabilityLayer::SimpleGraphicInstanceRGBA<5, 5> gs_barTopRightCornerGraphic(gs_barTopRightCornerGraphicPixels);
|
PortabilityLayer::SimpleGraphicInstanceRGBA<5, 5> gs_barTopRightCornerGraphic(gs_barTopRightCornerGraphicPixels);
|
||||||
@@ -65,6 +70,9 @@ struct MenuItem
|
|||||||
uint8_t textStyle;
|
uint8_t textStyle;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
bool checked;
|
bool checked;
|
||||||
|
|
||||||
|
uint16_t layoutYOffset;
|
||||||
|
uint16_t layoutHeight;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Menu
|
struct Menu
|
||||||
@@ -75,6 +83,10 @@ struct Menu
|
|||||||
uint16_t commandID;
|
uint16_t commandID;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
bool isIcon;
|
bool isIcon;
|
||||||
|
bool haveMenuLayout;
|
||||||
|
|
||||||
|
size_t layoutWidth;
|
||||||
|
size_t layoutHeight;
|
||||||
|
|
||||||
PortabilityLayer::MMHandleBlock *stringBlobHandle;
|
PortabilityLayer::MMHandleBlock *stringBlobHandle;
|
||||||
|
|
||||||
@@ -83,6 +95,7 @@ struct Menu
|
|||||||
|
|
||||||
// Refreshed on layout
|
// Refreshed on layout
|
||||||
size_t cumulativeOffset;
|
size_t cumulativeOffset;
|
||||||
|
size_t unpaddedTitleWidth;
|
||||||
unsigned int menuIndex;
|
unsigned int menuIndex;
|
||||||
|
|
||||||
size_t numMenuItems;
|
size_t numMenuItems;
|
||||||
@@ -112,6 +125,9 @@ namespace PortabilityLayer
|
|||||||
void SetItemEnabled(Menu **menu, unsigned int index, bool enabled) override;
|
void SetItemEnabled(Menu **menu, unsigned int index, bool enabled) override;
|
||||||
void SetItemChecked(Menu **menu, unsigned int index, bool checked) override;
|
void SetItemChecked(Menu **menu, unsigned int index, bool checked) override;
|
||||||
|
|
||||||
|
bool IsPointInMenuBar(const Vec2i &point) const override;
|
||||||
|
void MenuSelect(const Vec2i &initialPoint, int16_t *outMenu, uint16_t *outItem) override;
|
||||||
|
|
||||||
void DrawMenuBar() override;
|
void DrawMenuBar() override;
|
||||||
|
|
||||||
void RenderFrame(IGpDisplayDriver *displayDriver) override;
|
void RenderFrame(IGpDisplayDriver *displayDriver) override;
|
||||||
@@ -119,7 +135,36 @@ namespace PortabilityLayer
|
|||||||
static MenuManagerImpl *GetInstance();
|
static MenuManagerImpl *GetInstance();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void RefreshMenuLayout();
|
class MenuSelectionState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MenuSelectionState();
|
||||||
|
~MenuSelectionState();
|
||||||
|
|
||||||
|
void HandleSelectionOfMenu(MenuManagerImpl *mm, Menu **menuHdl, bool &outNeedRedraw);
|
||||||
|
void Dismiss();
|
||||||
|
|
||||||
|
Menu **GetSelectedMenu() const;
|
||||||
|
CGraf *GetRenderedMenu() const;
|
||||||
|
const unsigned int *GetSelectedItem() const;
|
||||||
|
|
||||||
|
void SelectItem(size_t item);
|
||||||
|
void ClearSelection();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void RenderMenu(Menu *menu);
|
||||||
|
|
||||||
|
Menu **m_currentMenu;
|
||||||
|
CGraf *m_menuGraf;
|
||||||
|
unsigned int m_itemIndex;
|
||||||
|
bool m_haveItem;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RefreshMenuBarLayout();
|
||||||
|
void RefreshMenuLayout(Menu *menu);
|
||||||
|
void ProcessMouseMoveTo(const Vec2i &point);
|
||||||
|
void ProcessMouseMoveToMenuBar(const Vec2i &point);
|
||||||
|
void ProcessMouseMoveToMenu(const Vec2i &point);
|
||||||
|
|
||||||
static const unsigned int kIconResID = 128;
|
static const unsigned int kIconResID = 128;
|
||||||
static const unsigned int kMenuFontSize = 12;
|
static const unsigned int kMenuFontSize = 12;
|
||||||
@@ -128,13 +173,21 @@ namespace PortabilityLayer
|
|||||||
static const unsigned int kMenuBarHeight = 20;
|
static const unsigned int kMenuBarHeight = 20;
|
||||||
static const unsigned int kMenuBarItemPadding = 6;
|
static const unsigned int kMenuBarItemPadding = 6;
|
||||||
static const unsigned int kMenuBarInitialPadding = 16;
|
static const unsigned int kMenuBarInitialPadding = 16;
|
||||||
|
|
||||||
|
static const unsigned int kMenuItemHeight = 18;
|
||||||
|
static const unsigned int kMenuItemTextYOffset = 13;
|
||||||
|
static const unsigned int kMenuSeparatorHeight = 6;
|
||||||
|
|
||||||
|
static const unsigned int kMenuItemRightPadding = 8;
|
||||||
|
static const unsigned int kMenuItemLeftPadding = 16 + 2 + 2; // 2 for left border, 16 for icon, 2 for spacing
|
||||||
|
|
||||||
static const int kMenuFontFlags = PortabilityLayer::FontFamilyFlag_Bold;
|
static const int kMenuFontFlags = PortabilityLayer::FontFamilyFlag_Bold;
|
||||||
|
|
||||||
CGraf *m_menuBarGraf;
|
CGraf *m_menuBarGraf;
|
||||||
|
|
||||||
Menu **m_firstMenu;
|
Menu **m_firstMenu;
|
||||||
Menu **m_lastMenu;
|
Menu **m_lastMenu;
|
||||||
bool m_haveMenuLayout;
|
bool m_haveMenuBarLayout;
|
||||||
bool m_haveIcon;
|
bool m_haveIcon;
|
||||||
|
|
||||||
uint8_t m_iconColors[16 * 16];
|
uint8_t m_iconColors[16 * 16];
|
||||||
@@ -142,6 +195,8 @@ namespace PortabilityLayer
|
|||||||
|
|
||||||
SimpleGraphic *m_iconGraphic;
|
SimpleGraphic *m_iconGraphic;
|
||||||
|
|
||||||
|
MenuSelectionState m_menuSelectionState;
|
||||||
|
|
||||||
static MenuManagerImpl ms_instance;
|
static MenuManagerImpl ms_instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -149,7 +204,7 @@ namespace PortabilityLayer
|
|||||||
: m_menuBarGraf(nullptr)
|
: m_menuBarGraf(nullptr)
|
||||||
, m_firstMenu(nullptr)
|
, m_firstMenu(nullptr)
|
||||||
, m_lastMenu(nullptr)
|
, m_lastMenu(nullptr)
|
||||||
, m_haveMenuLayout(false)
|
, m_haveMenuBarLayout(false)
|
||||||
, m_haveIcon(false)
|
, m_haveIcon(false)
|
||||||
, m_iconGraphic(nullptr)
|
, m_iconGraphic(nullptr)
|
||||||
{
|
{
|
||||||
@@ -235,7 +290,9 @@ namespace PortabilityLayer
|
|||||||
menu->enabled = ((enableFlags & 1) != 0);
|
menu->enabled = ((enableFlags & 1) != 0);
|
||||||
menu->menuIndex = 0;
|
menu->menuIndex = 0;
|
||||||
menu->cumulativeOffset = 0;
|
menu->cumulativeOffset = 0;
|
||||||
|
menu->unpaddedTitleWidth = 0;
|
||||||
menu->isIcon = false;
|
menu->isIcon = false;
|
||||||
|
menu->haveMenuLayout = false;
|
||||||
|
|
||||||
uint8_t *stringDataStart = static_cast<uint8_t*>(stringData->m_contents);
|
uint8_t *stringDataStart = static_cast<uint8_t*>(stringData->m_contents);
|
||||||
uint8_t *stringDest = stringDataStart;
|
uint8_t *stringDest = stringDataStart;
|
||||||
@@ -258,6 +315,7 @@ namespace PortabilityLayer
|
|||||||
currentItem->nameOffsetInStringBlob = static_cast<uint32_t>(stringDest - stringDataStart);
|
currentItem->nameOffsetInStringBlob = static_cast<uint32_t>(stringDest - stringDataStart);
|
||||||
currentItem->enabled = ((enableFlags & 1) != 0);
|
currentItem->enabled = ((enableFlags & 1) != 0);
|
||||||
currentItem->checked = false;
|
currentItem->checked = false;
|
||||||
|
currentItem->layoutYOffset = 0;
|
||||||
|
|
||||||
enableFlags >>= 1;
|
enableFlags >>= 1;
|
||||||
|
|
||||||
@@ -269,6 +327,8 @@ namespace PortabilityLayer
|
|||||||
menu->stringBlobHandle = stringData;
|
menu->stringBlobHandle = stringData;
|
||||||
menu->prevMenu = nullptr;
|
menu->prevMenu = nullptr;
|
||||||
menu->nextMenu = nullptr;
|
menu->nextMenu = nullptr;
|
||||||
|
menu->layoutWidth = 0;
|
||||||
|
menu->layoutHeight = 0;
|
||||||
|
|
||||||
return reinterpret_cast<Menu**>(&menuData->m_contents);
|
return reinterpret_cast<Menu**>(&menuData->m_contents);
|
||||||
}
|
}
|
||||||
@@ -286,7 +346,7 @@ namespace PortabilityLayer
|
|||||||
|
|
||||||
void MenuManagerImpl::InsertMenuBefore(Menu **insertingMenu, Menu **existingMenu)
|
void MenuManagerImpl::InsertMenuBefore(Menu **insertingMenu, Menu **existingMenu)
|
||||||
{
|
{
|
||||||
m_haveMenuLayout = false;
|
m_haveMenuBarLayout = false;
|
||||||
|
|
||||||
Menu *insertingMenuPtr = *insertingMenu;
|
Menu *insertingMenuPtr = *insertingMenu;
|
||||||
Menu *existingMenuPtr = *existingMenu;
|
Menu *existingMenuPtr = *existingMenu;
|
||||||
@@ -304,7 +364,7 @@ namespace PortabilityLayer
|
|||||||
|
|
||||||
void MenuManagerImpl::InsertMenuAfter(Menu **insertingMenu, Menu **existingMenu)
|
void MenuManagerImpl::InsertMenuAfter(Menu **insertingMenu, Menu **existingMenu)
|
||||||
{
|
{
|
||||||
m_haveMenuLayout = false;
|
m_haveMenuBarLayout = false;
|
||||||
|
|
||||||
Menu *insertingMenuPtr = *insertingMenu;
|
Menu *insertingMenuPtr = *insertingMenu;
|
||||||
Menu *existingMenuPtr = *existingMenu;
|
Menu *existingMenuPtr = *existingMenu;
|
||||||
@@ -322,7 +382,7 @@ namespace PortabilityLayer
|
|||||||
|
|
||||||
void MenuManagerImpl::InsertMenuAtEnd(Menu **insertingMenu)
|
void MenuManagerImpl::InsertMenuAtEnd(Menu **insertingMenu)
|
||||||
{
|
{
|
||||||
m_haveMenuLayout = false;
|
m_haveMenuBarLayout = false;
|
||||||
|
|
||||||
if (m_firstMenu == nullptr)
|
if (m_firstMenu == nullptr)
|
||||||
{
|
{
|
||||||
@@ -337,7 +397,7 @@ namespace PortabilityLayer
|
|||||||
|
|
||||||
void MenuManagerImpl::InsertMenuAtBeginning(Menu **insertingMenu)
|
void MenuManagerImpl::InsertMenuAtBeginning(Menu **insertingMenu)
|
||||||
{
|
{
|
||||||
m_haveMenuLayout = false;
|
m_haveMenuBarLayout = false;
|
||||||
|
|
||||||
if (m_firstMenu == nullptr)
|
if (m_firstMenu == nullptr)
|
||||||
{
|
{
|
||||||
@@ -377,6 +437,72 @@ namespace PortabilityLayer
|
|||||||
menu->menuItems[index].checked = checked;
|
menu->menuItems[index].checked = checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MenuManagerImpl::IsPointInMenuBar(const Vec2i &point) const
|
||||||
|
{
|
||||||
|
return point.m_y >= 0 && static_cast<uint32_t>(point.m_y) < kMenuBarHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MenuManagerImpl::MenuSelect(const Vec2i &initialPoint, int16_t *outMenu, uint16_t *outItem)
|
||||||
|
{
|
||||||
|
RefreshMenuBarLayout();
|
||||||
|
|
||||||
|
ProcessMouseMoveTo(initialPoint);
|
||||||
|
|
||||||
|
if (m_menuSelectionState.GetSelectedMenu() == nullptr)
|
||||||
|
{
|
||||||
|
if (outMenu)
|
||||||
|
*outMenu = 0;
|
||||||
|
|
||||||
|
if (outItem)
|
||||||
|
*outItem = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EventRecord evt;
|
||||||
|
bool canDismiss = false;
|
||||||
|
while (!canDismiss)
|
||||||
|
{
|
||||||
|
if (WaitNextEvent(everyEvent, &evt, 1, nullptr))
|
||||||
|
{
|
||||||
|
const EventCode eventCode = static_cast<EventCode>(evt.what);
|
||||||
|
|
||||||
|
switch (eventCode)
|
||||||
|
{
|
||||||
|
case mouseMove:
|
||||||
|
case mouseDown: // It's possible to get a mouse down event again if the mouse leaves the window and is downed again inside
|
||||||
|
ProcessMouseMoveTo(PortabilityLayer::Vec2i(evt.where.h, evt.where.v));
|
||||||
|
break;
|
||||||
|
case mouseUp:
|
||||||
|
canDismiss = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outMenu)
|
||||||
|
*outMenu = 0;
|
||||||
|
|
||||||
|
if (outItem)
|
||||||
|
*outItem = 0;
|
||||||
|
|
||||||
|
if (Menu **menuHdl = m_menuSelectionState.GetSelectedMenu())
|
||||||
|
{
|
||||||
|
if (const unsigned int *selectedItem = m_menuSelectionState.GetSelectedItem())
|
||||||
|
{
|
||||||
|
if (outMenu)
|
||||||
|
*outMenu = (*menuHdl)->menuID;
|
||||||
|
|
||||||
|
if (outItem)
|
||||||
|
*outItem = (*selectedItem) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_menuSelectionState.Dismiss();
|
||||||
|
this->DrawMenuBar();
|
||||||
|
}
|
||||||
|
|
||||||
void MenuManagerImpl::DrawMenuBar()
|
void MenuManagerImpl::DrawMenuBar()
|
||||||
{
|
{
|
||||||
if (!m_haveIcon)
|
if (!m_haveIcon)
|
||||||
@@ -422,17 +548,7 @@ namespace PortabilityLayer
|
|||||||
|
|
||||||
if (m_menuBarGraf == nullptr)
|
if (m_menuBarGraf == nullptr)
|
||||||
{
|
{
|
||||||
int depth = 0;
|
int depth = PortabilityLayer::QDManager::GetInstance()->DepthForPixelFormat(pixelFormat);
|
||||||
|
|
||||||
switch (pixelFormat)
|
|
||||||
{
|
|
||||||
case GpPixelFormats::k8BitStandard:
|
|
||||||
depth = 8;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
PL_NotYetImplemented();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qdManager->NewGWorld(&m_menuBarGraf, depth, menuRect, nullptr, nullptr, 0) != 0)
|
if (qdManager->NewGWorld(&m_menuBarGraf, depth, menuRect, nullptr, nullptr, 0) != 0)
|
||||||
return;
|
return;
|
||||||
@@ -448,8 +564,7 @@ namespace PortabilityLayer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RefreshMenuBarLayout();
|
||||||
RefreshMenuLayout();
|
|
||||||
|
|
||||||
CGraf *oldGraf;
|
CGraf *oldGraf;
|
||||||
GDHandle oldDevice;
|
GDHandle oldDevice;
|
||||||
@@ -504,11 +619,44 @@ namespace PortabilityLayer
|
|||||||
gs_barTopLeftCornerGraphic.DrawToPixMap(pixMap, 0, 0);
|
gs_barTopLeftCornerGraphic.DrawToPixMap(pixMap, 0, 0);
|
||||||
gs_barTopRightCornerGraphic.DrawToPixMap(pixMap, static_cast<int16_t>(width) - static_cast<int16_t>(gs_barTopRightCornerGraphic.m_width), 0);
|
gs_barTopRightCornerGraphic.DrawToPixMap(pixMap, static_cast<int16_t>(width) - static_cast<int16_t>(gs_barTopRightCornerGraphic.m_width), 0);
|
||||||
|
|
||||||
|
Menu **selectedMenuHdl = m_menuSelectionState.GetSelectedMenu();
|
||||||
|
|
||||||
|
if (selectedMenuHdl)
|
||||||
|
{
|
||||||
|
Menu *menu = *selectedMenuHdl;
|
||||||
|
|
||||||
|
const size_t xCoordinate = menu->cumulativeOffset + (menu->menuIndex * 2) * kMenuBarItemPadding + kMenuBarInitialPadding - kMenuBarItemPadding;
|
||||||
|
const size_t width = menu->unpaddedTitleWidth + kMenuBarItemPadding * 2;
|
||||||
|
|
||||||
|
const int16_t left = static_cast<int16_t>(xCoordinate);
|
||||||
|
const int16_t right = static_cast<int16_t>(xCoordinate + width);
|
||||||
|
|
||||||
|
// Top edge
|
||||||
|
qdState->SetForeColor(gs_barHighlightBrightColor);
|
||||||
|
{
|
||||||
|
const Rect rect = Rect::Create(0, left, 1, right);
|
||||||
|
PaintRect(&rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Middle
|
||||||
|
qdState->SetForeColor(gs_barHighlightMidColor);
|
||||||
|
{
|
||||||
|
const Rect rect = Rect::Create(1, left, kMenuBarHeight - 2, right);
|
||||||
|
PaintRect(&rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
qdState->SetForeColor(gs_barHighlightDarkColor);
|
||||||
|
{
|
||||||
|
const Rect rect = Rect::Create(kMenuBarHeight - 2, left, kMenuBarHeight - 1, right);
|
||||||
|
PaintRect(&rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text items
|
||||||
qdState->SetForeColor(gs_barNormalTextColor);
|
qdState->SetForeColor(gs_barNormalTextColor);
|
||||||
TextFont(systemFont);
|
TextFont(systemFont);
|
||||||
TextSize(kMenuFontSize);
|
TextSize(kMenuFontSize);
|
||||||
|
|
||||||
// Text items
|
|
||||||
{
|
{
|
||||||
Menu **menuHdl = m_firstMenu;
|
Menu **menuHdl = m_firstMenu;
|
||||||
while (menuHdl)
|
while (menuHdl)
|
||||||
@@ -522,20 +670,38 @@ namespace PortabilityLayer
|
|||||||
if (menu->isIcon)
|
if (menu->isIcon)
|
||||||
{
|
{
|
||||||
if (m_iconGraphic)
|
if (m_iconGraphic)
|
||||||
m_iconGraphic->DrawToPixMapWithMask(pixMap, m_iconMask, xCoordinate, kMenuBarIconYOffset);
|
m_iconGraphic->DrawToPixMapWithMask(pixMap, m_iconMask, static_cast<int16_t>(xCoordinate), kMenuBarIconYOffset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qdState->m_penPos.h = xCoordinate;
|
if (menuHdl != selectedMenuHdl)
|
||||||
|
{
|
||||||
|
qdState->m_penPos.h = static_cast<int16_t>(xCoordinate);
|
||||||
qdState->m_penPos.v = kMenuBarTextYOffset;
|
qdState->m_penPos.v = kMenuBarTextYOffset;
|
||||||
DrawString(PLPasStr(static_cast<const uint8_t*>(menu->stringBlobHandle->m_contents)));
|
DrawString(PLPasStr(static_cast<const uint8_t*>(menu->stringBlobHandle->m_contents)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
menuHdl = menu->nextMenu;
|
menuHdl = menu->nextMenu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selectedMenuHdl)
|
||||||
|
{
|
||||||
|
Menu *menu = *selectedMenuHdl;
|
||||||
|
|
||||||
|
if (menu->stringBlobHandle && !menu->isIcon)
|
||||||
|
{
|
||||||
|
qdState->SetForeColor(gs_barHighlightTextColor);
|
||||||
|
size_t xCoordinate = menu->cumulativeOffset + (menu->menuIndex * 2) * kMenuBarItemPadding + kMenuBarInitialPadding;
|
||||||
|
|
||||||
|
qdState->m_penPos.h = static_cast<int16_t>(xCoordinate);
|
||||||
|
qdState->m_penPos.v = kMenuBarTextYOffset;
|
||||||
|
DrawString(PLPasStr(static_cast<const uint8_t*>(menu->stringBlobHandle->m_contents)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SetGWorld(oldGraf, oldDevice);
|
SetGWorld(oldGraf, oldDevice);
|
||||||
|
|
||||||
m_menuBarGraf->m_port.SetDirty(QDPortDirtyFlag_Contents);
|
m_menuBarGraf->m_port.SetDirty(QDPortDirtyFlag_Contents);
|
||||||
@@ -555,11 +721,23 @@ namespace PortabilityLayer
|
|||||||
displayDriver->DrawSurface(m_menuBarGraf->m_ddSurface, 0, 0, width, height);
|
displayDriver->DrawSurface(m_menuBarGraf->m_ddSurface, 0, 0, width, height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CGraf *renderedMenu = m_menuSelectionState.GetRenderedMenu())
|
||||||
|
{
|
||||||
|
renderedMenu->PushToDDSurface(displayDriver);
|
||||||
|
|
||||||
|
Menu *selectedMenu = *m_menuSelectionState.GetSelectedMenu();
|
||||||
|
const PixMap *pixMap = *renderedMenu->m_port.GetPixMap();
|
||||||
|
|
||||||
|
const size_t xCoordinate = kMenuBarInitialPadding + selectedMenu->menuIndex * kMenuBarItemPadding * 2 + selectedMenu->cumulativeOffset - kMenuBarItemPadding;
|
||||||
|
|
||||||
|
displayDriver->DrawSurface(renderedMenu->m_ddSurface, xCoordinate, kMenuBarHeight, pixMap->m_rect.right, pixMap->m_rect.bottom);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuManagerImpl::RefreshMenuLayout()
|
void MenuManagerImpl::RefreshMenuBarLayout()
|
||||||
{
|
{
|
||||||
if (m_haveMenuLayout)
|
if (m_haveMenuBarLayout)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PortabilityLayer::FontManager *fontManager = PortabilityLayer::FontManager::GetInstance();
|
PortabilityLayer::FontManager *fontManager = PortabilityLayer::FontManager::GetInstance();
|
||||||
@@ -587,16 +765,141 @@ namespace PortabilityLayer
|
|||||||
|
|
||||||
if (pascalStr.Length() == 1 && pascalStr.UChars()[0] == 0x14)
|
if (pascalStr.Length() == 1 && pascalStr.UChars()[0] == 0x14)
|
||||||
{
|
{
|
||||||
measuredWidth += 16;
|
menu->unpaddedTitleWidth = 16;
|
||||||
menu->isIcon = true;
|
menu->isIcon = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
measuredWidth += rfont->MeasureString(pascalStr.UChars(), pascalStr.Length());
|
menu->unpaddedTitleWidth = rfont->MeasureString(pascalStr.UChars(), pascalStr.Length());
|
||||||
|
|
||||||
|
measuredWidth += menu->unpaddedTitleWidth;
|
||||||
|
|
||||||
menuHdl = menu->nextMenu;
|
menuHdl = menu->nextMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_haveMenuLayout = true;
|
m_haveMenuBarLayout = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuManagerImpl::RefreshMenuLayout(Menu *menu)
|
||||||
|
{
|
||||||
|
if (menu->haveMenuLayout)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PortabilityLayer::FontManager *fontManager = PortabilityLayer::FontManager::GetInstance();
|
||||||
|
|
||||||
|
PortabilityLayer::FontFamily *fontFamily = PortabilityLayer::FontManager::GetInstance()->GetSystemFont(kMenuFontSize, kMenuFontFlags);
|
||||||
|
if (!fontFamily)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PortabilityLayer::RenderedFont *rfont = PortabilityLayer::FontManager::GetInstance()->GetRenderedFontFromFamily(fontFamily, kMenuFontSize, kMenuFontFlags);
|
||||||
|
if (!rfont)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const uint8_t *strBlob = static_cast<const uint8_t*>(menu->stringBlobHandle->m_contents);
|
||||||
|
|
||||||
|
size_t cumulativeHeight = 0;
|
||||||
|
size_t width = menu->width;
|
||||||
|
|
||||||
|
const size_t numItems = menu->numMenuItems;
|
||||||
|
for (size_t i = 0; i < numItems; i++)
|
||||||
|
{
|
||||||
|
MenuItem &item = menu->menuItems[i];
|
||||||
|
item.layoutYOffset = cumulativeHeight;
|
||||||
|
item.layoutHeight = kMenuItemHeight;
|
||||||
|
|
||||||
|
const uint8_t *itemName = strBlob + item.nameOffsetInStringBlob;
|
||||||
|
const PLPasStr itemNamePStr = PLPasStr(itemName);
|
||||||
|
|
||||||
|
const size_t nameWidth = rfont->MeasureString(itemNamePStr.UChars(), itemNamePStr.Length());
|
||||||
|
|
||||||
|
const size_t paddedWidth = nameWidth + kMenuItemLeftPadding + kMenuItemRightPadding;
|
||||||
|
|
||||||
|
width = std::max<size_t>(width, paddedWidth);
|
||||||
|
|
||||||
|
cumulativeHeight += item.layoutHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
menu->haveMenuLayout = true;
|
||||||
|
menu->layoutWidth = width;
|
||||||
|
menu->layoutHeight = cumulativeHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuManagerImpl::ProcessMouseMoveTo(const Vec2i &point)
|
||||||
|
{
|
||||||
|
if (point.m_y < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (point.m_y < static_cast<int>(kMenuBarHeight))
|
||||||
|
ProcessMouseMoveToMenuBar(point);
|
||||||
|
else
|
||||||
|
ProcessMouseMoveToMenu(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuManagerImpl::ProcessMouseMoveToMenuBar(const Vec2i &point)
|
||||||
|
{
|
||||||
|
if (point.m_x < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const uint32_t mouseXCoordinate = static_cast<uint32_t>(point.m_x);
|
||||||
|
|
||||||
|
Menu **selectedMenu = nullptr;
|
||||||
|
|
||||||
|
Menu **menuHdl = m_firstMenu;
|
||||||
|
|
||||||
|
while (menuHdl)
|
||||||
|
{
|
||||||
|
Menu *menu = *menuHdl;
|
||||||
|
|
||||||
|
uint32_t menuLeftXCoordinate = kMenuBarInitialPadding + menu->cumulativeOffset + menu->menuIndex * kMenuBarItemPadding * 2 - kMenuBarItemPadding;
|
||||||
|
uint32_t menuRightXCoordinate = menuLeftXCoordinate + menu->unpaddedTitleWidth + kMenuBarItemPadding * 2;
|
||||||
|
|
||||||
|
if (mouseXCoordinate >= menuLeftXCoordinate && mouseXCoordinate < menuRightXCoordinate)
|
||||||
|
{
|
||||||
|
selectedMenu = menuHdl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
menuHdl = menu->nextMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedMenu)
|
||||||
|
{
|
||||||
|
bool needRedraw = false;
|
||||||
|
m_menuSelectionState.HandleSelectionOfMenu(this, menuHdl, needRedraw);
|
||||||
|
|
||||||
|
if (needRedraw)
|
||||||
|
DrawMenuBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuManagerImpl::ProcessMouseMoveToMenu(const Vec2i &point)
|
||||||
|
{
|
||||||
|
Menu **selectedMenuHandle = m_menuSelectionState.GetSelectedMenu();
|
||||||
|
|
||||||
|
if (selectedMenuHandle)
|
||||||
|
{
|
||||||
|
Menu *menu = *selectedMenuHandle;
|
||||||
|
const int32_t xCoordinate = kMenuBarInitialPadding + menu->menuIndex * kMenuBarItemPadding * 2 + menu->cumulativeOffset - kMenuBarItemPadding;
|
||||||
|
|
||||||
|
const Vec2i localPoint = point - Vec2i(xCoordinate, kMenuBarHeight);
|
||||||
|
|
||||||
|
if (localPoint.m_x < 0 || localPoint.m_y < 0 || static_cast<size_t>(localPoint.m_x) >= menu->layoutWidth || static_cast<size_t>(localPoint.m_y) >= menu->layoutHeight)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const size_t localY = localPoint.m_y;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < menu->numMenuItems; i++)
|
||||||
|
{
|
||||||
|
const MenuItem &item = menu->menuItems[i];
|
||||||
|
|
||||||
|
if (localY >= item.layoutYOffset && localY - item.layoutYOffset < item.layoutHeight)
|
||||||
|
{
|
||||||
|
m_menuSelectionState.SelectItem(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_menuSelectionState.ClearSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuManagerImpl *MenuManagerImpl::GetInstance()
|
MenuManagerImpl *MenuManagerImpl::GetInstance()
|
||||||
@@ -606,6 +909,166 @@ namespace PortabilityLayer
|
|||||||
|
|
||||||
MenuManagerImpl MenuManagerImpl::ms_instance;
|
MenuManagerImpl MenuManagerImpl::ms_instance;
|
||||||
|
|
||||||
|
MenuManagerImpl::MenuSelectionState::MenuSelectionState()
|
||||||
|
: m_currentMenu(nullptr)
|
||||||
|
, m_menuGraf(nullptr)
|
||||||
|
, m_haveItem(false)
|
||||||
|
, m_itemIndex(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuManagerImpl::MenuSelectionState::~MenuSelectionState()
|
||||||
|
{
|
||||||
|
Dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuManagerImpl::MenuSelectionState::HandleSelectionOfMenu(MenuManagerImpl *mm, Menu **menuHdl, bool &outNeedRedraw)
|
||||||
|
{
|
||||||
|
outNeedRedraw = false;
|
||||||
|
|
||||||
|
if (!menuHdl)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (menuHdl != m_currentMenu)
|
||||||
|
{
|
||||||
|
Dismiss();
|
||||||
|
m_currentMenu = menuHdl;
|
||||||
|
|
||||||
|
Menu *menu = *menuHdl;
|
||||||
|
|
||||||
|
outNeedRedraw = true;
|
||||||
|
|
||||||
|
mm->RefreshMenuLayout(menu);
|
||||||
|
|
||||||
|
RenderMenu(menu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuManagerImpl::MenuSelectionState::Dismiss()
|
||||||
|
{
|
||||||
|
if (m_menuGraf)
|
||||||
|
{
|
||||||
|
DisposeGWorld(m_menuGraf);
|
||||||
|
m_menuGraf = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_currentMenu = nullptr;
|
||||||
|
m_haveItem = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu **MenuManagerImpl::MenuSelectionState::GetSelectedMenu() const
|
||||||
|
{
|
||||||
|
return m_currentMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGraf *MenuManagerImpl::MenuSelectionState::GetRenderedMenu() const
|
||||||
|
{
|
||||||
|
return m_menuGraf;
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned int *MenuManagerImpl::MenuSelectionState::GetSelectedItem() const
|
||||||
|
{
|
||||||
|
if (!m_haveItem)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return &m_itemIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuManagerImpl::MenuSelectionState::SelectItem(size_t item)
|
||||||
|
{
|
||||||
|
if (m_haveItem && m_itemIndex == item)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_haveItem = true;
|
||||||
|
m_itemIndex = item;
|
||||||
|
|
||||||
|
if (m_currentMenu)
|
||||||
|
RenderMenu(*m_currentMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuManagerImpl::MenuSelectionState::ClearSelection()
|
||||||
|
{
|
||||||
|
if (!m_haveItem)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_haveItem = false;
|
||||||
|
|
||||||
|
if (m_currentMenu)
|
||||||
|
RenderMenu(*m_currentMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuManagerImpl::MenuSelectionState::RenderMenu(Menu *menu)
|
||||||
|
{
|
||||||
|
PortabilityLayer::QDManager *qdManager = PortabilityLayer::QDManager::GetInstance();
|
||||||
|
|
||||||
|
const Rect menuRect = Rect::Create(0, 0, menu->layoutHeight, menu->layoutWidth);
|
||||||
|
|
||||||
|
if (m_menuGraf == nullptr)
|
||||||
|
{
|
||||||
|
GpPixelFormat_t pixelFormat;
|
||||||
|
PortabilityLayer::HostDisplayDriver::GetInstance()->GetDisplayResolution(nullptr, nullptr, &pixelFormat);
|
||||||
|
|
||||||
|
if (qdManager->NewGWorld(&m_menuGraf, qdManager->DepthForPixelFormat(pixelFormat), menuRect, nullptr, nullptr, 0) != 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGrafPtr oldGraf = nullptr;
|
||||||
|
GDHandle oldDevice = nullptr;
|
||||||
|
GetGWorld(&oldGraf, &oldDevice);
|
||||||
|
|
||||||
|
SetGWorld(m_menuGraf, nullptr);
|
||||||
|
|
||||||
|
QDState *qdState = qdManager->GetState();
|
||||||
|
|
||||||
|
qdState->SetForeColor(gs_barMidColor);
|
||||||
|
|
||||||
|
{
|
||||||
|
const Rect rect = Rect::Create(0, 0, menu->layoutHeight, menu->layoutWidth);
|
||||||
|
PaintRect(&rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFont(systemFont);
|
||||||
|
TextSize(kMenuFontSize);
|
||||||
|
|
||||||
|
const uint8_t *strBlob = static_cast<const uint8_t*>(menu->stringBlobHandle->m_contents);
|
||||||
|
|
||||||
|
qdState->m_penPos.h = kMenuItemLeftPadding;
|
||||||
|
|
||||||
|
qdState->SetForeColor(gs_barNormalTextColor);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < menu->numMenuItems; i++)
|
||||||
|
{
|
||||||
|
if (m_haveItem && i == m_itemIndex)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const MenuItem &item = menu->menuItems[i];
|
||||||
|
|
||||||
|
qdState->m_penPos.v = item.layoutYOffset + kMenuItemTextYOffset;
|
||||||
|
|
||||||
|
DrawString(PLPasStr(strBlob + item.nameOffsetInStringBlob));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_haveItem)
|
||||||
|
{
|
||||||
|
const MenuItem &selectedItem = menu->menuItems[m_itemIndex];
|
||||||
|
qdState->SetForeColor(gs_barHighlightMidColor);
|
||||||
|
const Rect itemRect = Rect::Create(selectedItem.layoutYOffset, 0, selectedItem.layoutYOffset + selectedItem.layoutHeight, menu->layoutWidth);
|
||||||
|
PaintRect(&itemRect);
|
||||||
|
|
||||||
|
qdState->SetForeColor(gs_barHighlightTextColor);
|
||||||
|
|
||||||
|
const MenuItem &item = menu->menuItems[m_itemIndex];
|
||||||
|
|
||||||
|
qdState->m_penPos.v = item.layoutYOffset + kMenuItemTextYOffset;
|
||||||
|
|
||||||
|
DrawString(PLPasStr(strBlob + item.nameOffsetInStringBlob));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_menuGraf->m_port.SetDirty(QDPortDirtyFlag_Contents);
|
||||||
|
|
||||||
|
SetGWorld(oldGraf, oldDevice);
|
||||||
|
}
|
||||||
|
|
||||||
MenuManager *MenuManager::GetInstance()
|
MenuManager *MenuManager::GetInstance()
|
||||||
{
|
{
|
||||||
return MenuManagerImpl::GetInstance();
|
return MenuManagerImpl::GetInstance();
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
struct Menu;
|
#include <stdint.h>
|
||||||
|
|
||||||
struct IGpDisplayDriver;
|
struct IGpDisplayDriver;
|
||||||
|
struct Menu;
|
||||||
|
|
||||||
namespace PortabilityLayer
|
namespace PortabilityLayer
|
||||||
{
|
{
|
||||||
|
struct Vec2i;
|
||||||
|
|
||||||
class MenuManager
|
class MenuManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -21,6 +25,10 @@ namespace PortabilityLayer
|
|||||||
virtual void SetItemEnabled(Menu **menu, unsigned int index, bool enabled) = 0;
|
virtual void SetItemEnabled(Menu **menu, unsigned int index, bool enabled) = 0;
|
||||||
virtual void SetItemChecked(Menu **menu, unsigned int index, bool checked) = 0;
|
virtual void SetItemChecked(Menu **menu, unsigned int index, bool checked) = 0;
|
||||||
|
|
||||||
|
virtual bool IsPointInMenuBar(const Vec2i &point) const = 0;
|
||||||
|
|
||||||
|
virtual void MenuSelect(const Vec2i &initialPoint, int16_t *outMenu, uint16_t *outItem) = 0;
|
||||||
|
|
||||||
virtual void DrawMenuBar() = 0;
|
virtual void DrawMenuBar() = 0;
|
||||||
|
|
||||||
virtual void RenderFrame(IGpDisplayDriver *displayDriver) = 0;
|
virtual void RenderFrame(IGpDisplayDriver *displayDriver) = 0;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "FileManager.h"
|
#include "FileManager.h"
|
||||||
#include "FilePermission.h"
|
#include "FilePermission.h"
|
||||||
#include "FontManager.h"
|
#include "FontManager.h"
|
||||||
|
#include "GpVOSEvent.h"
|
||||||
#include "HostDirectoryCursor.h"
|
#include "HostDirectoryCursor.h"
|
||||||
#include "HostFileSystem.h"
|
#include "HostFileSystem.h"
|
||||||
#include "HostSuspendCallArgument.h"
|
#include "HostSuspendCallArgument.h"
|
||||||
@@ -27,10 +28,12 @@
|
|||||||
#include "PLBigEndian.h"
|
#include "PLBigEndian.h"
|
||||||
#include "PLEventQueue.h"
|
#include "PLEventQueue.h"
|
||||||
#include "QDManager.h"
|
#include "QDManager.h"
|
||||||
|
#include "Vec2i.h"
|
||||||
#include "WindowDef.h"
|
#include "WindowDef.h"
|
||||||
#include "WindowManager.h"
|
#include "WindowManager.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
static bool ConvertFilenameToSafePStr(const char *str, uint8_t *pstr)
|
static bool ConvertFilenameToSafePStr(const char *str, uint8_t *pstr)
|
||||||
{
|
{
|
||||||
@@ -55,16 +58,65 @@ static bool ConvertFilenameToSafePStr(const char *str, uint8_t *pstr)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TranslateVOSEvent(const GpVOSEvent *vosEvent, EventRecord *evt)
|
static void TranslateMouseInputEvent(const GpMouseInputEvent &vosEvent, PortabilityLayer::EventQueue *queue)
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
if (vosEvent.m_button == GpMouseButtons::kLeft)
|
||||||
|
{
|
||||||
|
if (vosEvent.m_eventType == GpMouseEventTypes::kDown)
|
||||||
|
{
|
||||||
|
if (EventRecord *evt = queue->Enqueue())
|
||||||
|
{
|
||||||
|
evt->what = mouseDown;
|
||||||
|
evt->where.h = std::min<int32_t>(INT16_MAX, std::max<int32_t>(INT16_MIN, vosEvent.m_x));
|
||||||
|
evt->where.v = std::min<int32_t>(INT16_MAX, std::max<int32_t>(INT16_MIN, vosEvent.m_y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (vosEvent.m_eventType == GpMouseEventTypes::kUp)
|
||||||
|
{
|
||||||
|
if (EventRecord *evt = queue->Enqueue())
|
||||||
|
{
|
||||||
|
evt->what = mouseUp;
|
||||||
|
evt->where.h = std::min<int32_t>(INT16_MAX, std::max<int32_t>(INT16_MIN, vosEvent.m_x));
|
||||||
|
evt->where.v = std::min<int32_t>(INT16_MAX, std::max<int32_t>(INT16_MIN, vosEvent.m_y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (vosEvent.m_eventType == GpMouseEventTypes::kMove)
|
||||||
|
{
|
||||||
|
if (EventRecord *evt = queue->Enqueue())
|
||||||
|
{
|
||||||
|
evt->what = mouseMove;
|
||||||
|
evt->where.h = std::min<int32_t>(INT16_MAX, std::max<int32_t>(INT16_MIN, vosEvent.m_x));
|
||||||
|
evt->where.v = std::min<int32_t>(INT16_MAX, std::max<int32_t>(INT16_MIN, vosEvent.m_y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TranslateKeyboardInputEvent(const GpKeyboardInputEvent &vosEvent, PortabilityLayer::EventQueue *queue)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TranslateVOSEvent(const GpVOSEvent *vosEvent, PortabilityLayer::EventQueue *queue)
|
||||||
|
{
|
||||||
|
switch (vosEvent->m_eventType)
|
||||||
|
{
|
||||||
|
case GpVOSEventTypes::kMouseInput:
|
||||||
|
TranslateMouseInputEvent(vosEvent->m_event.m_mouseInputEvent, queue);
|
||||||
|
break;
|
||||||
|
case GpVOSEventTypes::kKeyboardInput:
|
||||||
|
TranslateKeyboardInputEvent(vosEvent->m_event.m_keyboardInputEvent, queue);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImportVOSEvents()
|
static void ImportVOSEvents()
|
||||||
{
|
{
|
||||||
|
PortabilityLayer::EventQueue *plQueue = PortabilityLayer::EventQueue::GetInstance();
|
||||||
|
|
||||||
PortabilityLayer::HostVOSEventQueue *evtQueue = PortabilityLayer::HostVOSEventQueue::GetInstance();
|
PortabilityLayer::HostVOSEventQueue *evtQueue = PortabilityLayer::HostVOSEventQueue::GetInstance();
|
||||||
while (const GpVOSEvent *evt = evtQueue->GetNext())
|
while (const GpVOSEvent *evt = evtQueue->GetNext())
|
||||||
{
|
{
|
||||||
|
TranslateVOSEvent(evt, plQueue);
|
||||||
evtQueue->DischargeOne();
|
evtQueue->DischargeOne();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,8 +236,10 @@ Handle GetResource(const char(&resTypeLiteral)[5], int id)
|
|||||||
|
|
||||||
short FindWindow(Point point, WindowPtr *window)
|
short FindWindow(Point point, WindowPtr *window)
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
short part = 0;
|
||||||
return 0;
|
PortabilityLayer::WindowManager::GetInstance()->FindWindow(point, window, &part);
|
||||||
|
|
||||||
|
return part;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DragWindow(WindowPtr window, Point start, Rect *bounds)
|
void DragWindow(WindowPtr window, Point start, Rect *bounds)
|
||||||
@@ -309,6 +363,22 @@ void SetWTitle(WindowPtr window, const PLPasStr &title)
|
|||||||
PL_NotYetImplemented();
|
PL_NotYetImplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PeekNextEvent(int32_t eventMask, EventRecord *event)
|
||||||
|
{
|
||||||
|
assert(eventMask == everyEvent); // We don't support other use cases
|
||||||
|
|
||||||
|
PortabilityLayer::EventQueue *queue = PortabilityLayer::EventQueue::GetInstance();
|
||||||
|
const EventRecord *record = queue->Peek();
|
||||||
|
|
||||||
|
if (record)
|
||||||
|
{
|
||||||
|
*event = *record;
|
||||||
|
return PL_TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return PL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
bool GetNextEvent(int32_t eventMask, EventRecord *event)
|
bool GetNextEvent(int32_t eventMask, EventRecord *event)
|
||||||
{
|
{
|
||||||
assert(eventMask == everyEvent); // We don't support other use cases
|
assert(eventMask == everyEvent); // We don't support other use cases
|
||||||
@@ -319,8 +389,12 @@ bool GetNextEvent(int32_t eventMask, EventRecord *event)
|
|||||||
|
|
||||||
long MenuSelect(Point point)
|
long MenuSelect(Point point)
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
int16_t menuID = 0;
|
||||||
return noErr;
|
uint16_t menuItem = 0;
|
||||||
|
|
||||||
|
PortabilityLayer::MenuManager::GetInstance()->MenuSelect(PortabilityLayer::Vec2i(point.h, point.v), &menuID, &menuItem);
|
||||||
|
|
||||||
|
return (static_cast<int32_t>(menuID) << 16) | (static_cast<int32_t>(menuItem));
|
||||||
}
|
}
|
||||||
|
|
||||||
long MenuKey(int charCode)
|
long MenuKey(int charCode)
|
||||||
@@ -357,7 +431,8 @@ bool BitTst(const KeyMap *keyMap, int bit)
|
|||||||
|
|
||||||
void NumToString(long number, unsigned char *str)
|
void NumToString(long number, unsigned char *str)
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
PL_NotYetImplemented_TODO("Strings");
|
||||||
|
str[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParamText(const PLPasStr &title, const PLPasStr &a, const PLPasStr &b, const PLPasStr &c)
|
void ParamText(const PLPasStr &title, const PLPasStr &a, const PLPasStr &b, const PLPasStr &c)
|
||||||
@@ -701,7 +776,11 @@ UInt32 GetDblTime()
|
|||||||
|
|
||||||
void FlushEvents(int mask, int unknown)
|
void FlushEvents(int mask, int unknown)
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
PortabilityLayer::EventQueue *queue = PortabilityLayer::EventQueue::GetInstance();
|
||||||
|
|
||||||
|
while (queue->Dequeue(nullptr))
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExitToShell()
|
void ExitToShell()
|
||||||
@@ -783,12 +862,6 @@ void DisposePtr(void *ptr)
|
|||||||
PL_NotYetImplemented();
|
PL_NotYetImplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
Size MaxMem(Size *growBytes)
|
|
||||||
{
|
|
||||||
PL_NotYetImplemented();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PurgeSpace(long *totalFree, long *contiguousFree)
|
void PurgeSpace(long *totalFree, long *contiguousFree)
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
PL_NotYetImplemented();
|
||||||
|
|||||||
@@ -186,8 +186,7 @@ typedef unsigned char KeyMap[16];
|
|||||||
|
|
||||||
enum RegionID
|
enum RegionID
|
||||||
{
|
{
|
||||||
inDesk,
|
inMenuBar = 1,
|
||||||
inMenuBar,
|
|
||||||
inSysWindow,
|
inSysWindow,
|
||||||
inContent,
|
inContent,
|
||||||
inDrag,
|
inDrag,
|
||||||
@@ -206,6 +205,7 @@ enum EventCode
|
|||||||
{
|
{
|
||||||
mouseDown,
|
mouseDown,
|
||||||
mouseUp,
|
mouseUp,
|
||||||
|
mouseMove,
|
||||||
keyDown,
|
keyDown,
|
||||||
autoKey,
|
autoKey,
|
||||||
updateEvt,
|
updateEvt,
|
||||||
@@ -307,6 +307,7 @@ void MoveWindow(WindowPtr window, int x, int y, Boolean moveToFront);
|
|||||||
void ShowWindow(WindowPtr window);
|
void ShowWindow(WindowPtr window);
|
||||||
void SetWTitle(WindowPtr window, const PLPasStr &title);
|
void SetWTitle(WindowPtr window, const PLPasStr &title);
|
||||||
|
|
||||||
|
bool PeekNextEvent(int32_t eventMask, EventRecord *event);
|
||||||
bool GetNextEvent(int32_t eventMask, EventRecord *event);
|
bool GetNextEvent(int32_t eventMask, EventRecord *event);
|
||||||
|
|
||||||
long MenuSelect(Point point); // Breaks into menu select routine (in practice we'll just forward one from the queue?)
|
long MenuSelect(Point point); // Breaks into menu select routine (in practice we'll just forward one from the queue?)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ namespace PortabilityLayer
|
|||||||
~EventQueueImpl();
|
~EventQueueImpl();
|
||||||
|
|
||||||
bool Dequeue(EventRecord *evt) override;
|
bool Dequeue(EventRecord *evt) override;
|
||||||
|
const EventRecord *Peek() const override;
|
||||||
EventRecord *Enqueue() override;
|
EventRecord *Enqueue() override;
|
||||||
|
|
||||||
static EventQueueImpl *GetInstance();
|
static EventQueueImpl *GetInstance();
|
||||||
@@ -40,6 +41,7 @@ namespace PortabilityLayer
|
|||||||
if (m_numQueuedEvents == 0)
|
if (m_numQueuedEvents == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (evt)
|
||||||
*evt = m_events[m_firstEvent];
|
*evt = m_events[m_firstEvent];
|
||||||
|
|
||||||
m_firstEvent++;
|
m_firstEvent++;
|
||||||
@@ -51,6 +53,15 @@ namespace PortabilityLayer
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const EventRecord *EventQueueImpl::Peek() const
|
||||||
|
{
|
||||||
|
if (m_numQueuedEvents == 0)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return m_events + m_firstEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
EventRecord *EventQueueImpl::Enqueue()
|
EventRecord *EventQueueImpl::Enqueue()
|
||||||
{
|
{
|
||||||
if (m_numQueuedEvents == kMaxEvents)
|
if (m_numQueuedEvents == kMaxEvents)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ namespace PortabilityLayer
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual bool Dequeue(EventRecord *evt) = 0;
|
virtual bool Dequeue(EventRecord *evt) = 0;
|
||||||
|
virtual const EventRecord *Peek() const = 0;
|
||||||
virtual EventRecord *Enqueue() = 0;
|
virtual EventRecord *Enqueue() = 0;
|
||||||
|
|
||||||
static EventQueue *GetInstance();
|
static EventQueue *GetInstance();
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ void DrawMenuBar()
|
|||||||
|
|
||||||
void HiliteMenu(int menu)
|
void HiliteMenu(int menu)
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
// Don't know what this does
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnableMenuItem(MenuHandle menu, int index)
|
void EnableMenuItem(MenuHandle menu, int index)
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ namespace PortabilityLayer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OSErr NewGWorld(GWorldPtr *gworld, int depth, Rect *bounds, CTabHandle colorTable, GDHandle device, int flags)
|
OSErr NewGWorld(GWorldPtr *gworld, int depth, const Rect *bounds, CTabHandle colorTable, GDHandle device, int flags)
|
||||||
{
|
{
|
||||||
return PortabilityLayer::QDManager::GetInstance()->NewGWorld(gworld, depth, *bounds, colorTable, device, flags);
|
return PortabilityLayer::QDManager::GetInstance()->NewGWorld(gworld, depth, *bounds, colorTable, device, flags);
|
||||||
}
|
}
|
||||||
@@ -301,6 +301,7 @@ void DrawPicture(PicHandle pict, Rect *bounds)
|
|||||||
|
|
||||||
switch (pixMap->GetPixelFormat())
|
switch (pixMap->GetPixelFormat())
|
||||||
{
|
{
|
||||||
|
case GpPixelFormats::kBW1:
|
||||||
case GpPixelFormats::k8BitStandard:
|
case GpPixelFormats::k8BitStandard:
|
||||||
{
|
{
|
||||||
PortabilityLayer::PixMapBlitEmitter blitEmitter(PortabilityLayer::Vec2i(bounds->left, bounds->top), pixMap);
|
PortabilityLayer::PixMapBlitEmitter blitEmitter(PortabilityLayer::Vec2i(bounds->left, bounds->top), pixMap);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ enum QDFlags
|
|||||||
useTempMem = 1,
|
useTempMem = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
OSErr NewGWorld(GWorldPtr *gworld, int depth, Rect *bounds, CTabHandle colorTable, GDHandle device, int flags);
|
OSErr NewGWorld(GWorldPtr *gworld, int depth, const Rect *bounds, CTabHandle colorTable, GDHandle device, int flags);
|
||||||
void DisposeGWorld(GWorldPtr gworld);
|
void DisposeGWorld(GWorldPtr gworld);
|
||||||
|
|
||||||
PixMapHandle GetGWorldPixMap(GWorldPtr gworld);
|
PixMapHandle GetGWorldPixMap(GWorldPtr gworld);
|
||||||
|
|||||||
@@ -534,9 +534,7 @@ void GetIndPattern(Pattern *pattern, int patListID, int index)
|
|||||||
memcpy(pattern, patternRes + 2 + (index - 1) * 8, 8);
|
memcpy(pattern, patternRes + 2 + (index - 1) * 8, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CopyBitsComplete(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBitmap, const Rect *srcRectBase, const Rect *maskRectBase, const Rect *destRectBase, RgnHandle maskRegion)
|
||||||
|
|
||||||
void CopyBits(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRect, const Rect *destRect, CopyBitsMode copyMode, RgnHandle maskRegion)
|
|
||||||
{
|
{
|
||||||
assert(srcBitmap->m_pixelFormat == destBitmap->m_pixelFormat);
|
assert(srcBitmap->m_pixelFormat == destBitmap->m_pixelFormat);
|
||||||
|
|
||||||
@@ -546,30 +544,84 @@ void CopyBits(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRect,
|
|||||||
const size_t srcPitch = srcBitmap->m_pitch;
|
const size_t srcPitch = srcBitmap->m_pitch;
|
||||||
const size_t destPitch = destBitmap->m_pitch;
|
const size_t destPitch = destBitmap->m_pitch;
|
||||||
|
|
||||||
assert(srcRect->top >= srcBounds.top);
|
assert(srcRectBase->right - srcRectBase->left == destRectBase->right - destRectBase->left);
|
||||||
assert(srcRect->bottom <= srcBounds.bottom);
|
assert(srcRectBase->bottom - srcRectBase->top == destRectBase->bottom - destRectBase->top);
|
||||||
assert(srcRect->left >= srcBounds.left);
|
|
||||||
assert(srcRect->right <= srcBounds.right);
|
|
||||||
|
|
||||||
assert(destRect->top >= destBounds.top);
|
if (maskBitmap)
|
||||||
assert(destRect->bottom <= destBounds.bottom);
|
{
|
||||||
assert(destRect->left >= destBounds.left);
|
assert(maskRectBase);
|
||||||
assert(destRect->right <= destBounds.right);
|
assert(maskRectBase->right - maskRectBase->left == destRectBase->right - destRectBase->left);
|
||||||
|
}
|
||||||
|
|
||||||
assert(srcRect->right - srcRect->left == destRect->right - destRect->left);
|
assert((maskBitmap == nullptr) == (maskRectBase == nullptr));
|
||||||
assert(srcRect->bottom - srcRect->top == destRect->bottom - destRect->top);
|
|
||||||
|
|
||||||
const Region *mask = *maskRegion;
|
Rect srcRect;
|
||||||
|
Rect destRect;
|
||||||
|
Rect maskRect;
|
||||||
|
|
||||||
const Rect constrainedDestRect = destRect->Intersect(mask->rect);
|
{
|
||||||
|
const Rect constrainedSrcRect = srcRectBase->Intersect(srcBounds);
|
||||||
|
const Rect constrainedDestRect = destRectBase->Intersect(destBounds);
|
||||||
|
|
||||||
|
const int32_t leftNudge = std::max(constrainedSrcRect.left - srcRectBase->left, constrainedDestRect.left - destRectBase->left);
|
||||||
|
const int32_t topNudge = std::max(constrainedSrcRect.top - srcRectBase->top, constrainedDestRect.top - destRectBase->top);
|
||||||
|
const int32_t bottomNudge = std::min(constrainedSrcRect.bottom - srcRectBase->bottom, constrainedDestRect.bottom - destRectBase->bottom);
|
||||||
|
const int32_t rightNudge = std::min(constrainedSrcRect.right - srcRectBase->right, constrainedDestRect.right - destRectBase->right);
|
||||||
|
|
||||||
|
const int32_t srcLeft = srcRectBase->left + leftNudge;
|
||||||
|
const int32_t srcRight = srcRectBase->right + rightNudge;
|
||||||
|
const int32_t srcTop = srcRectBase->top + topNudge;
|
||||||
|
const int32_t srcBottom = srcRectBase->bottom + bottomNudge;
|
||||||
|
|
||||||
|
if (srcTop >= srcBottom)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (srcLeft >= srcRight)
|
||||||
|
return;
|
||||||
|
|
||||||
|
srcRect.left = srcLeft;
|
||||||
|
srcRect.right = srcRight;
|
||||||
|
srcRect.top = srcTop;
|
||||||
|
srcRect.bottom = srcBottom;
|
||||||
|
|
||||||
|
destRect.left = destRectBase->left + leftNudge;
|
||||||
|
destRect.right = destRectBase->right + rightNudge;
|
||||||
|
destRect.top = destRectBase->top + topNudge;
|
||||||
|
destRect.bottom = destRectBase->bottom + bottomNudge;
|
||||||
|
|
||||||
|
if (maskRectBase)
|
||||||
|
{
|
||||||
|
maskRect.left = maskRectBase->left + leftNudge;
|
||||||
|
maskRect.right = maskRectBase->right + rightNudge;
|
||||||
|
maskRect.top = maskRectBase->top + topNudge;
|
||||||
|
maskRect.bottom = maskRectBase->bottom + bottomNudge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
const Region *mask = nullptr;
|
||||||
|
|
||||||
|
if (maskRegion)
|
||||||
|
mask = *maskRegion;
|
||||||
|
|
||||||
|
const Rect constrainedDestRect = mask ? destRect.Intersect(mask->rect) : destRect;
|
||||||
if (!constrainedDestRect.IsValid())
|
if (!constrainedDestRect.IsValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Rect constrainedSrcRect = *srcRect;
|
Rect constrainedSrcRect = srcRect;
|
||||||
constrainedSrcRect.left += constrainedDestRect.left - destRect->left;
|
constrainedSrcRect.left += constrainedDestRect.left - destRect.left;
|
||||||
constrainedSrcRect.right += constrainedDestRect.right - destRect->right;
|
constrainedSrcRect.right += constrainedDestRect.right - destRect.right;
|
||||||
constrainedSrcRect.top += constrainedDestRect.top - destRect->top;
|
constrainedSrcRect.top += constrainedDestRect.top - destRect.top;
|
||||||
constrainedSrcRect.bottom += constrainedDestRect.bottom - destRect->bottom;
|
constrainedSrcRect.bottom += constrainedDestRect.bottom - destRect.bottom;
|
||||||
|
|
||||||
const size_t srcFirstCol = constrainedSrcRect.left - srcBitmap->m_rect.left;
|
const size_t srcFirstCol = constrainedSrcRect.left - srcBitmap->m_rect.left;
|
||||||
const size_t srcFirstRow = constrainedSrcRect.top - srcBitmap->m_rect.top;
|
const size_t srcFirstRow = constrainedSrcRect.top - srcBitmap->m_rect.top;
|
||||||
@@ -577,7 +629,7 @@ void CopyBits(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRect,
|
|||||||
const size_t destFirstCol = constrainedDestRect.left - destBitmap->m_rect.left;
|
const size_t destFirstCol = constrainedDestRect.left - destBitmap->m_rect.left;
|
||||||
const size_t destFirstRow = constrainedDestRect.top - destBitmap->m_rect.top;
|
const size_t destFirstRow = constrainedDestRect.top - destBitmap->m_rect.top;
|
||||||
|
|
||||||
if (mask->size != sizeof(Region))
|
if (mask && mask->size != sizeof(Region))
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
PL_NotYetImplemented();
|
||||||
}
|
}
|
||||||
@@ -608,8 +660,8 @@ void CopyBits(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRect,
|
|||||||
const size_t firstSrcByte = srcFirstRow * srcPitch + srcFirstCol * pixelSizeBytes;
|
const size_t firstSrcByte = srcFirstRow * srcPitch + srcFirstCol * pixelSizeBytes;
|
||||||
const size_t firstDestByte = destFirstRow * destPitch + destFirstCol * pixelSizeBytes;
|
const size_t firstDestByte = destFirstRow * destPitch + destFirstCol * pixelSizeBytes;
|
||||||
|
|
||||||
const size_t numCopiedRows = srcRect->bottom - srcRect->top;
|
const size_t numCopiedRows = srcRect.bottom - srcRect.top;
|
||||||
const size_t numCopiedCols = srcRect->right - srcRect->left;
|
const size_t numCopiedCols = srcRect.right - srcRect.left;
|
||||||
const size_t numCopiedBytesPerScanline = numCopiedCols * pixelSizeBytes;
|
const size_t numCopiedBytesPerScanline = numCopiedCols * pixelSizeBytes;
|
||||||
|
|
||||||
for (size_t i = 0; i < numCopiedRows; i++)
|
for (size_t i = 0; i < numCopiedRows; i++)
|
||||||
@@ -617,11 +669,15 @@ void CopyBits(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRect,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyMask(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBitmap, const Rect *srcRect, const Rect *maskRect, const Rect *destRect)
|
void CopyBits(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRectBase, const Rect *destRectBase, CopyBitsMode copyMode, RgnHandle maskRegion)
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
CopyBitsComplete(srcBitmap, nullptr, destBitmap, srcRectBase, nullptr, destRectBase, maskRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CopyMask(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBitmap, const Rect *srcRectBase, const Rect *maskRectBase, const Rect *destRectBase)
|
||||||
|
{
|
||||||
|
CopyBitsComplete(srcBitmap, maskBitmap, destBitmap, srcRectBase, maskRectBase, destRectBase, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
RgnHandle NewRgn()
|
RgnHandle NewRgn()
|
||||||
{
|
{
|
||||||
@@ -725,8 +781,9 @@ void SubPt(Point srcPoint, Point *destPoint)
|
|||||||
|
|
||||||
Boolean SectRect(const Rect *rectA, const Rect *rectB, Rect *outIntersection)
|
Boolean SectRect(const Rect *rectA, const Rect *rectB, Rect *outIntersection)
|
||||||
{
|
{
|
||||||
PL_NotYetImplemented();
|
*outIntersection = rectA->Intersect(*rectB);
|
||||||
return false;
|
|
||||||
|
return outIntersection->IsValid() ? PL_TRUE : PL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -760,3 +817,15 @@ void BitMap::Init(const Rect &rect, GpPixelFormat_t pixelFormat, size_t pitch, v
|
|||||||
m_pitch = pitch;
|
m_pitch = pitch;
|
||||||
m_data = dataPtr;
|
m_data = dataPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "stb_image_write.h"
|
||||||
|
|
||||||
|
void DebugPixMap(PixMap **pixMapH, const char *outName)
|
||||||
|
{
|
||||||
|
PixMap *pixMap = *pixMapH;
|
||||||
|
char outPath[1024];
|
||||||
|
strcpy_s(outPath, outName);
|
||||||
|
strcat_s(outPath, ".png");
|
||||||
|
|
||||||
|
stbi_write_png(outPath, pixMap->m_rect.right - pixMap->m_rect.left, pixMap->m_rect.bottom - pixMap->m_rect.top, 1, pixMap->m_data, pixMap->m_pitch);
|
||||||
|
}
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ Pattern *GetQDGlobalsBlack(Pattern *pattern);
|
|||||||
// Index is 1-based
|
// Index is 1-based
|
||||||
void GetIndPattern(Pattern *pattern, int patListID, int index);
|
void GetIndPattern(Pattern *pattern, int patListID, int index);
|
||||||
|
|
||||||
|
void DebugPixMap(PixMap **pixMap, const char *outName);
|
||||||
|
|
||||||
void CopyBits(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRect, const Rect *destRect, CopyBitsMode copyMode, RgnHandle maskRegion);
|
void CopyBits(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRect, const Rect *destRect, CopyBitsMode copyMode, RgnHandle maskRegion);
|
||||||
void CopyMask(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBitmap, const Rect *srcRect, const Rect *maskRect, const Rect *destRect);
|
void CopyMask(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBitmap, const Rect *srcRect, const Rect *maskRect, const Rect *destRect);
|
||||||
|
|||||||
@@ -60,21 +60,25 @@
|
|||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
<Import Project="..\Common.props" />
|
<Import Project="..\Common.props" />
|
||||||
<Import Project="..\GpCommon.props" />
|
<Import Project="..\GpCommon.props" />
|
||||||
|
<Import Project="..\stb.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<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="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
<Import Project="..\Common.props" />
|
<Import Project="..\Common.props" />
|
||||||
<Import Project="..\GpCommon.props" />
|
<Import Project="..\GpCommon.props" />
|
||||||
|
<Import Project="..\stb.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<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="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
<Import Project="..\Common.props" />
|
<Import Project="..\Common.props" />
|
||||||
<Import Project="..\GpCommon.props" />
|
<Import Project="..\GpCommon.props" />
|
||||||
|
<Import Project="..\stb.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<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="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
<Import Project="..\Common.props" />
|
<Import Project="..\Common.props" />
|
||||||
<Import Project="..\GpCommon.props" />
|
<Import Project="..\GpCommon.props" />
|
||||||
|
<Import Project="..\stb.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup />
|
<PropertyGroup />
|
||||||
@@ -241,6 +245,7 @@
|
|||||||
<ClInclude Include="XModemCRC.h" />
|
<ClInclude Include="XModemCRC.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\stb\stb_image_write.c" />
|
||||||
<ClCompile Include="AEManager.cpp" />
|
<ClCompile Include="AEManager.cpp" />
|
||||||
<ClCompile Include="BinHex4.cpp" />
|
<ClCompile Include="BinHex4.cpp" />
|
||||||
<ClCompile Include="ByteSwap.cpp" />
|
<ClCompile Include="ByteSwap.cpp" />
|
||||||
|
|||||||
@@ -361,7 +361,7 @@
|
|||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="SimpleGraphic.h">
|
<ClInclude Include="SimpleGraphic.h">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -545,5 +545,8 @@
|
|||||||
<ClCompile Include="SimpleGraphic.cpp">
|
<ClCompile Include="SimpleGraphic.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\stb\stb_image_write.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -6,6 +6,8 @@
|
|||||||
#include "QDGraf.h"
|
#include "QDGraf.h"
|
||||||
#include "QDState.h"
|
#include "QDState.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
namespace PortabilityLayer
|
namespace PortabilityLayer
|
||||||
{
|
{
|
||||||
class QDManagerImpl final : public QDManager
|
class QDManagerImpl final : public QDManager
|
||||||
@@ -20,6 +22,8 @@ namespace PortabilityLayer
|
|||||||
void DisposeGWorld(CGraf *gw) override;
|
void DisposeGWorld(CGraf *gw) override;
|
||||||
QDState *GetState() override;
|
QDState *GetState() override;
|
||||||
|
|
||||||
|
int DepthForPixelFormat(GpPixelFormat_t pixelFormat) const override;
|
||||||
|
|
||||||
static QDManagerImpl *GetInstance();
|
static QDManagerImpl *GetInstance();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -59,6 +63,9 @@ namespace PortabilityLayer
|
|||||||
|
|
||||||
switch (depth)
|
switch (depth)
|
||||||
{
|
{
|
||||||
|
case 1:
|
||||||
|
pixelFormat = GpPixelFormats::kBW1;
|
||||||
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
pixelFormat = (colorTable == nullptr) ? GpPixelFormats::k8BitStandard : GpPixelFormats::k8BitCustom;
|
pixelFormat = (colorTable == nullptr) ? GpPixelFormats::k8BitStandard : GpPixelFormats::k8BitCustom;
|
||||||
break;
|
break;
|
||||||
@@ -72,9 +79,6 @@ namespace PortabilityLayer
|
|||||||
return genericErr;
|
return genericErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (depth != 8)
|
|
||||||
return genericErr;
|
|
||||||
|
|
||||||
void *grafStorage = MemoryManager::GetInstance()->Alloc(sizeof(CGraf));
|
void *grafStorage = MemoryManager::GetInstance()->Alloc(sizeof(CGraf));
|
||||||
if (!grafStorage)
|
if (!grafStorage)
|
||||||
return mFulErr;
|
return mFulErr;
|
||||||
@@ -105,6 +109,25 @@ namespace PortabilityLayer
|
|||||||
return m_port->GetState();
|
return m_port->GetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int QDManagerImpl::DepthForPixelFormat(GpPixelFormat_t pixelFormat) const
|
||||||
|
{
|
||||||
|
switch (pixelFormat)
|
||||||
|
{
|
||||||
|
case GpPixelFormats::k8BitStandard:
|
||||||
|
case GpPixelFormats::k8BitCustom:
|
||||||
|
return 8;
|
||||||
|
case GpPixelFormats::kRGB555:
|
||||||
|
return 16;
|
||||||
|
case GpPixelFormats::kRGB24:
|
||||||
|
return 24;
|
||||||
|
case GpPixelFormats::kRGB32:
|
||||||
|
return 32;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QDManagerImpl *QDManagerImpl::GetInstance()
|
QDManagerImpl *QDManagerImpl::GetInstance()
|
||||||
{
|
{
|
||||||
return &ms_instance;
|
return &ms_instance;
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "GpPixelFormat.h"
|
||||||
|
|
||||||
struct ColorTable;
|
struct ColorTable;
|
||||||
struct CGraf;
|
struct CGraf;
|
||||||
struct GDevice;
|
struct GDevice;
|
||||||
@@ -21,6 +23,8 @@ namespace PortabilityLayer
|
|||||||
|
|
||||||
virtual QDState *GetState() = 0;
|
virtual QDState *GetState() = 0;
|
||||||
|
|
||||||
|
virtual int DepthForPixelFormat(GpPixelFormat_t pixelFormat) const = 0;
|
||||||
|
|
||||||
static QDManager *GetInstance();
|
static QDManager *GetInstance();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ namespace PortabilityLayer
|
|||||||
{
|
{
|
||||||
case GpPixelFormats::k8BitCustom:
|
case GpPixelFormats::k8BitCustom:
|
||||||
case GpPixelFormats::k8BitStandard:
|
case GpPixelFormats::k8BitStandard:
|
||||||
|
case GpPixelFormats::kBW1:
|
||||||
rowByteCount = width;
|
rowByteCount = width;
|
||||||
break;
|
break;
|
||||||
case GpPixelFormats::kRGB555:
|
case GpPixelFormats::kRGB555:
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ namespace PortabilityLayer
|
|||||||
const int gGrayDelta = static_cast<int>(g * 3) - static_cast<int>(grayscaleTimes3);
|
const int gGrayDelta = static_cast<int>(g * 3) - static_cast<int>(grayscaleTimes3);
|
||||||
const int bGrayDelta = static_cast<int>(b * 3) - static_cast<int>(grayscaleTimes3);
|
const int bGrayDelta = static_cast<int>(b * 3) - static_cast<int>(grayscaleTimes3);
|
||||||
|
|
||||||
if (rGrayDelta >= -3 && rGrayDelta <= 3 && gGrayDelta >= -3 && gGrayDelta <= -3 && bGrayDelta >= -3 && bGrayDelta <= -3)
|
if (rGrayDelta >= -3 && rGrayDelta <= 3 && gGrayDelta >= -3 && gGrayDelta <= 3 && bGrayDelta >= -3 && bGrayDelta <= 3)
|
||||||
{
|
{
|
||||||
// Divide down to 0..15 range
|
// Divide down to 0..15 range
|
||||||
const unsigned int grayscaleValue = (grayscaleTimes3 * 21 + 36) >> 6;
|
const unsigned int grayscaleValue = (grayscaleTimes3 * 21 + 36) >> 6;
|
||||||
@@ -167,7 +167,7 @@ namespace PortabilityLayer
|
|||||||
else if (grayscale6Step == 5)
|
else if (grayscale6Step == 5)
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
return 180 - 36 * grayscale6Step;
|
return 215 - 43 * grayscale6Step;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return 255 - grayscale6Step * 2 - grayscale6StepRemainder;
|
return 255 - grayscale6Step * 2 - grayscale6StepRemainder;
|
||||||
|
|||||||
@@ -7,9 +7,11 @@
|
|||||||
#include "PLCore.h"
|
#include "PLCore.h"
|
||||||
#include "PLEventQueue.h"
|
#include "PLEventQueue.h"
|
||||||
#include "MemoryManager.h"
|
#include "MemoryManager.h"
|
||||||
|
#include "MenuManager.h"
|
||||||
#include "QDGraf.h"
|
#include "QDGraf.h"
|
||||||
#include "QDManager.h"
|
#include "QDManager.h"
|
||||||
#include "QDPixMap.h"
|
#include "QDPixMap.h"
|
||||||
|
#include "Vec2i.h"
|
||||||
#include "WindowDef.h"
|
#include "WindowDef.h"
|
||||||
|
|
||||||
struct GDevice;
|
struct GDevice;
|
||||||
@@ -58,6 +60,7 @@ namespace PortabilityLayer
|
|||||||
void ShowWindow(Window *window) override;
|
void ShowWindow(Window *window) override;
|
||||||
void HideWindow(Window *window) override;
|
void HideWindow(Window *window) override;
|
||||||
GDevice **GetWindowDevice(Window *window) override;
|
GDevice **GetWindowDevice(Window *window) override;
|
||||||
|
void FindWindow(const Point &point, Window **outWindow, short *outRegion) const override;
|
||||||
|
|
||||||
void RenderFrame(IGpDisplayDriver *displayDriver) override;
|
void RenderFrame(IGpDisplayDriver *displayDriver) override;
|
||||||
|
|
||||||
@@ -245,6 +248,60 @@ namespace PortabilityLayer
|
|||||||
return static_cast<WindowImpl*>(window)->GetDevice();
|
return static_cast<WindowImpl*>(window)->GetDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowManagerImpl::FindWindow(const Point &point, Window **outWindow, short *outRegion) const
|
||||||
|
{
|
||||||
|
// outRegion = One of:
|
||||||
|
/*
|
||||||
|
inMenuBar,
|
||||||
|
inSysWindow,
|
||||||
|
inContent,
|
||||||
|
inDrag,
|
||||||
|
inGrow,
|
||||||
|
inGoAway,
|
||||||
|
inZoomIn,
|
||||||
|
inZoomOut,
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (PortabilityLayer::MenuManager::GetInstance()->IsPointInMenuBar(PortabilityLayer::Vec2i(point.h, point.v)))
|
||||||
|
{
|
||||||
|
if (outWindow)
|
||||||
|
*outWindow = nullptr;
|
||||||
|
|
||||||
|
if (outRegion)
|
||||||
|
*outRegion = inMenuBar;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowImpl *window = m_windowStackTop;
|
||||||
|
while (window)
|
||||||
|
{
|
||||||
|
const Rect windowRect = window->m_graf.m_port.GetRect();
|
||||||
|
|
||||||
|
const int32_t localX = point.h - window->m_wmX;
|
||||||
|
const int32_t localY = point.v - window->m_wmY;
|
||||||
|
|
||||||
|
if (localX >= 0 && localY >= 0 && localX < windowRect.right && localY < windowRect.bottom)
|
||||||
|
{
|
||||||
|
if (outWindow)
|
||||||
|
*outWindow = window;
|
||||||
|
|
||||||
|
if (outRegion)
|
||||||
|
*outRegion = inContent;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window = window->GetWindowBelow();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outWindow)
|
||||||
|
*outWindow = nullptr;
|
||||||
|
|
||||||
|
if (outRegion)
|
||||||
|
*outRegion = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void WindowManagerImpl::RenderFrame(IGpDisplayDriver *displayDriver)
|
void WindowManagerImpl::RenderFrame(IGpDisplayDriver *displayDriver)
|
||||||
{
|
{
|
||||||
GDevice **mainDeviceHdl = PortabilityLayer::DisplayDeviceManager::GetInstance()->GetMainDevice();
|
GDevice **mainDeviceHdl = PortabilityLayer::DisplayDeviceManager::GetInstance()->GetMainDevice();
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ struct Window;
|
|||||||
struct CGraf;
|
struct CGraf;
|
||||||
struct GDevice;
|
struct GDevice;
|
||||||
struct IGpDisplayDriver;
|
struct IGpDisplayDriver;
|
||||||
|
struct Point;
|
||||||
|
struct Window;
|
||||||
|
|
||||||
namespace PortabilityLayer
|
namespace PortabilityLayer
|
||||||
{
|
{
|
||||||
@@ -20,6 +22,7 @@ namespace PortabilityLayer
|
|||||||
virtual void ShowWindow(Window *window) = 0;
|
virtual void ShowWindow(Window *window) = 0;
|
||||||
virtual void HideWindow(Window *window) = 0;
|
virtual void HideWindow(Window *window) = 0;
|
||||||
virtual GDevice **GetWindowDevice(Window *window) = 0;
|
virtual GDevice **GetWindowDevice(Window *window) = 0;
|
||||||
|
virtual void FindWindow(const Point &point, Window **outWindow, short *outRegion) const = 0;
|
||||||
|
|
||||||
virtual void RenderFrame(IGpDisplayDriver *displayDriver) = 0;
|
virtual void RenderFrame(IGpDisplayDriver *displayDriver) = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -17,3 +17,12 @@ Other parts:
|
|||||||
- FTagData: Copies a data-only file to a .gpd and creates a .gpf for it
|
- FTagData: Copies a data-only file to a .gpd and creates a .gpf for it
|
||||||
- ImportCharSet: Imports the Unicode MacRoman description into a code page table.
|
- ImportCharSet: Imports the Unicode MacRoman description into a code page table.
|
||||||
- PictChecker: Experimental app that extracts all of the PICT resources from all of the houses and dumps them to PNG. Used to verify that the PICT loader works.
|
- PictChecker: Experimental app that extracts all of the PICT resources from all of the houses and dumps them to PNG. Used to verify that the PICT loader works.
|
||||||
|
|
||||||
|
|
||||||
|
GlidePort is intended to be primarily a straight port, retaining most of the look and feel of the original.
|
||||||
|
|
||||||
|
Planned additions:
|
||||||
|
- 32-bit color support (mainly matters for houses that have higher-resolution PICT resources)
|
||||||
|
- Resolution changes while the game is running
|
||||||
|
- Bring back the gray-to-color intro fade that was removed in later versions
|
||||||
|
- Gamepad support
|
||||||
|
|||||||
Reference in New Issue
Block a user