Level editor work

This commit is contained in:
elasota
2020-02-23 20:21:04 -05:00
parent d63ac98624
commit c78a20dafd
61 changed files with 1317 additions and 305 deletions

View File

@@ -170,7 +170,7 @@
<ClInclude Include="..\GpCommon\GpDisplayDriverTickStatus.h" />
<ClInclude Include="..\GpCommon\GpFileCreationDisposition.h" />
<ClInclude Include="..\GpCommon\GpInputDriverProperties.h" />
<ClInclude Include="..\GpCommon\IGpColorCursor.h" />
<ClInclude Include="..\GpCommon\IGpCursor.h" />
<ClInclude Include="..\GpCommon\IGpAudioChannelCallbacks.h" />
<ClInclude Include="..\GpCommon\GpColorCursor_Win32.h" />
<ClInclude Include="..\GpCommon\IGpDisplayDriverSurface.h" />

View File

@@ -1,14 +1,14 @@
#include "GpColorCursor_Win32.h"
#include "GpCursor_Win32.h"
#include <stdlib.h>
#include <new>
void GpColorCursor_Win32::Destroy()
void GpCursor_Win32::Destroy()
{
this->DecRef();
}
IGpColorCursor_Win32 *GpColorCursor_Win32::Load(const wchar_t *path)
IGpCursor_Win32 *GpCursor_Win32::Load(const wchar_t *path)
{
HANDLE imageH = LoadImageW(nullptr, path, IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE);
@@ -16,43 +16,43 @@ IGpColorCursor_Win32 *GpColorCursor_Win32::Load(const wchar_t *path)
return nullptr;
HCURSOR cursor = reinterpret_cast<HCURSOR>(imageH);
void *storage = malloc(sizeof(GpColorCursor_Win32));
void *storage = malloc(sizeof(GpCursor_Win32));
if (!storage)
{
DestroyCursor(cursor);
return nullptr;
}
return new (storage) GpColorCursor_Win32(reinterpret_cast<HCURSOR>(cursor));
return new (storage) GpCursor_Win32(reinterpret_cast<HCURSOR>(cursor));
}
GpColorCursor_Win32::GpColorCursor_Win32(HCURSOR cursor)
GpCursor_Win32::GpCursor_Win32(HCURSOR cursor)
: m_cursor(cursor)
, m_refCount(1)
{
}
GpColorCursor_Win32::~GpColorCursor_Win32()
GpCursor_Win32::~GpCursor_Win32()
{
DestroyCursor(m_cursor);
}
const HCURSOR &GpColorCursor_Win32::GetHCursor() const
const HCURSOR &GpCursor_Win32::GetHCursor() const
{
return m_cursor;
}
void GpColorCursor_Win32::IncRef()
void GpCursor_Win32::IncRef()
{
m_refCount++;
}
void GpColorCursor_Win32::DecRef()
void GpCursor_Win32::DecRef()
{
m_refCount--;
if (m_refCount == 0)
{
this->~GpColorCursor_Win32();
this->~GpCursor_Win32();
free(this);
}
}

View File

@@ -1,6 +1,6 @@
#include "GpMain.h"
#include "GpAudioDriverFactory.h"
#include "GpColorCursor_Win32.h"
#include "GpCursor_Win32.h"
#include "GpDisplayDriverFactory.h"
#include "GpGlobalConfig.h"
#include "GpFiber_Win32.h"
@@ -390,7 +390,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
g_gpWindowsGlobals.m_baseDir = GpFileSystem_Win32::GetInstance()->GetBasePath();
g_gpWindowsGlobals.m_createFiberFunc = GpFiber_Win32::Create;
g_gpWindowsGlobals.m_loadColorCursorFunc = GpColorCursor_Win32::Load;
g_gpWindowsGlobals.m_loadCursorFunc = GpCursor_Win32::Load;
g_gpWindowsGlobals.m_translateWindowsMessageFunc = TranslateWindowsMessage;
g_gpGlobalConfig.m_displayDriverType = EGpDisplayDriverType_D3D11;

View File

@@ -1,4 +1,5 @@
#include "CFileStream.h"
#include "BMPFormat.h"
#include "MMHandleBlock.h"
#include "ResourceCompiledTypeList.h"
#include "ResourceFile.h"
@@ -8,6 +9,7 @@
#include <assert.h>
#include <string>
#include <vector>
#include "stb_image_write.h"
@@ -53,6 +55,14 @@ struct CursorHeader
BEUInt32_t m_cursorResourceID;
};
struct BWCursor
{
uint8_t m_pixels[32];
uint8_t m_mask[32];
BEUInt16_t m_hotSpotX;
BEUInt16_t m_hotSpotY;
};
struct IconDir
{
uint16_t m_reserved;
@@ -84,6 +94,108 @@ void WriteToFileCallback(void *context, void *data, int size)
fwrite(data, 1, size, static_cast<FILE*>(context));
}
void WriteToVectorCallback(void *context, void *data, int size)
{
std::vector<uint8_t> *vec = static_cast<std::vector<uint8_t>*>(context);
for (int i = 0; i < size; i++)
vec->push_back(static_cast<const uint8_t*>(data)[i]);
}
void ConvertBWCursors(PortabilityLayer::ResourceFile *resFile)
{
const PortabilityLayer::ResourceCompiledTypeList *typeList = resFile->GetResourceTypeList('CURS');
if (!typeList)
return;
const size_t numRefs = typeList->m_numRefs;
for (size_t i = 0; i < numRefs; i++)
{
const int resID = typeList->m_firstRef[i].m_resID;
const THandle<void> resHdl = resFile->LoadResource('CURS', resID);
const void *cursorDataBase = *resHdl;
const BWCursor *cursorData = static_cast<const BWCursor *>(cursorDataBase);
char outPathDebug[64];
sprintf_s(outPathDebug, "Packaged\\WinCursors\\b%i.bmp", resID);
char outPath[64];
sprintf_s(outPath, "Packaged\\WinCursors\\b%i.cur", resID);
FILE *outF = nullptr;
errno_t outErr = fopen_s(&outF, outPath, "wb");
if (!outErr)
{
IconDir iconDir;
iconDir.m_reserved = 0;
iconDir.m_type = 2;
iconDir.m_numImages = 1;
IconDirEntry iconDirEntry;
iconDirEntry.m_width = 16;
iconDirEntry.m_height = 16;
iconDirEntry.m_numColors = 0;
iconDirEntry.m_reserved = 0;
iconDirEntry.m_numPlanes_HotSpotX = cursorData->m_hotSpotX;
iconDirEntry.m_bpp_HotSpotY = cursorData->m_hotSpotY;
iconDirEntry.m_imageDataSize = 0;
iconDirEntry.m_imageDataOffset = sizeof(IconDir) + sizeof(IconDirEntry);
fwrite(&iconDir, 1, sizeof(IconDir), outF);
fwrite(&iconDirEntry, 1, sizeof(IconDirEntry), outF);
long imageDataStart = ftell(outF);
PortabilityLayer::BitmapInfoHeader bmpHeader;
bmpHeader.m_thisStructureSize = sizeof(bmpHeader);
bmpHeader.m_width = 16;
bmpHeader.m_height = 32;
bmpHeader.m_planes = 1;
bmpHeader.m_bitsPerPixel = 1;
bmpHeader.m_compression = 0;
bmpHeader.m_imageSize = (16 * 16 / 8);
bmpHeader.m_xPixelsPerMeter = 0;
bmpHeader.m_yPixelsPerMeter = 0;
bmpHeader.m_numColors = 2;
bmpHeader.m_importantColorCount = 2;
fwrite(&bmpHeader, 1, sizeof(bmpHeader), outF);
const uint8_t paletteData[] = {
0, 0, 0, 0,
255, 255, 255, 0 };
fwrite(paletteData, 1, sizeof(paletteData), outF);
uint8_t padding[2] = { 0, 0 };
for (int y = 0; y < 16; y++)
{
const uint8_t *maskRow = cursorData->m_mask + (15 - y) * 2;
const uint8_t *row = cursorData->m_pixels + (15 - y) * 2;
const uint8_t modifiedRow[] = { row[0] ^ maskRow[0], row[1] ^ maskRow[1] };
fwrite(modifiedRow, 1, 2, outF);
fwrite(padding, 1, 2, outF);
}
for (int y = 0; y < 16; y++)
{
const uint8_t *row = cursorData->m_mask + (15 - y) * 2;
const uint8_t modifiedRow[] = { row[0] ^ 255, row[1] ^ 255 };
fwrite(modifiedRow, 1, 2, outF);
fwrite(padding, 1, 2, outF);
}
long imageDataEnd = ftell(outF);
fseek(outF, sizeof(IconDir), SEEK_SET);
iconDirEntry.m_imageDataSize = static_cast<uint32_t>(imageDataEnd - imageDataStart);
fwrite(&iconDirEntry, 1, sizeof(IconDirEntry), outF);
fclose(outF);
}
}
}
void ConvertCursors(PortabilityLayer::ResourceFile *resFile)
{
const PortabilityLayer::ResourceCompiledTypeList *typeList = resFile->GetResourceTypeList('crsr');
@@ -196,7 +308,7 @@ void ConvertCursors(PortabilityLayer::ResourceFile *resFile)
}
char outPath[64];
sprintf_s(outPath, "Packaged\\WinCursors\\%i.cur", resID);
sprintf_s(outPath, "Packaged\\WinCursors\\c%i.cur", resID);
FILE *outF = nullptr;
errno_t outErr = fopen_s(&outF, outPath, "wb");
@@ -335,6 +447,7 @@ int main(int argc, const char **argv)
stream.Close();
ConvertCursors(resFile);
ConvertBWCursors(resFile);
ConvertIconFamily(resFile, 'ics#', 'ics8', "Small", 16);
ConvertIconFamily(resFile, 'ICN#', 'icl8', "Large", 32);

View File

@@ -11,7 +11,7 @@
#include "Externs.h"
#include "Environ.h"
#include "HostDisplayDriver.h"
#include "IGpColorCursor.h"
#include "IGpCursor.h"
#include "IGpDisplayDriver.h"
#include "ResourceManager.h"
@@ -37,7 +37,7 @@ typedef struct
{
struct
{
IGpColorCursor *hwCursor;
IGpCursor *hwCursor;
} frame[1];
} compiledAcurRec;
@@ -61,7 +61,7 @@ compiledAcurHandle compiledAnimCursorH = nil;
Boolean GetColorCursors (acurHandle ballCursH, compiledAcurHandle compiledBallCursH)
{
short i, j;
IGpColorCursor *hwCursor;
IGpCursor *hwCursor;
Boolean result = true;
if (ballCursH)
@@ -70,7 +70,7 @@ Boolean GetColorCursors (acurHandle ballCursH, compiledAcurHandle compiledBallCu
HideCursor(); // Hide the cursor
for (i = 0; i < j; i++) // Walk through the acur resource
{
hwCursor = PortabilityLayer::HostDisplayDriver::GetInstance()->LoadColorCursor((*ballCursH)->frame[i].resID); // Get the cursor
hwCursor = PortabilityLayer::HostDisplayDriver::GetInstance()->LoadCursor(true, (*ballCursH)->frame[i].resID); // Get the cursor
if (hwCursor == nil) // Make sure a real cursor was returned
{ // If not, trash all cursors loaded
for (j = 0; j < i; j++)
@@ -81,7 +81,7 @@ Boolean GetColorCursors (acurHandle ballCursH, compiledAcurHandle compiledBallCu
else // But, if the cursor loaded ok
{ // add it to our list or cursor handles
(*compiledBallCursH)->frame[i].hwCursor = hwCursor;
PortabilityLayer::HostDisplayDriver::GetInstance()->SetColorCursor(hwCursor);
PortabilityLayer::HostDisplayDriver::GetInstance()->SetCursor(hwCursor);
}
}
InitCursor(); // Show the cursor again (as arrow)
@@ -168,10 +168,10 @@ void IncrementCursor (void)
(*animCursorH)->index++;
(*animCursorH)->index %= (*animCursorH)->n;
PortabilityLayer::HostDisplayDriver::GetInstance()->SetColorCursor((*compiledAnimCursorH)->frame[(*animCursorH)->index].hwCursor);
PortabilityLayer::HostDisplayDriver::GetInstance()->SetCursor((*compiledAnimCursorH)->frame[(*animCursorH)->index].hwCursor);
}
else
SetBuiltinCursor(watchCursor);
PortabilityLayer::HostDisplayDriver::GetInstance()->SetStandardCursor(EGpStandardCursors::kWait);
}
//-------------------------------------------------------------- DecrementCursor
@@ -188,10 +188,10 @@ void DecrementCursor (void)
if (((*animCursorH)->index) < 0)
(*animCursorH)->index = ((*animCursorH)->n) - 1;
PortabilityLayer::HostDisplayDriver::GetInstance()->SetColorCursor((*compiledAnimCursorH)->frame[(*animCursorH)->index].hwCursor);
PortabilityLayer::HostDisplayDriver::GetInstance()->SetCursor((*compiledAnimCursorH)->frame[(*animCursorH)->index].hwCursor);
}
else
SetBuiltinCursor(watchCursor);
PortabilityLayer::HostDisplayDriver::GetInstance()->SetStandardCursor(EGpStandardCursors::kWait);
}
//-------------------------------------------------------------- SpinCursor

View File

@@ -127,15 +127,15 @@ void OpenCoordWindow (void)
if (coordWindow == nil)
{
const uint16_t windowStyle = PortabilityLayer::WindowStyleFlags::kTitleBar | PortabilityLayer::WindowStyleFlags::kMiniBar;
const uint16_t windowStyle = PortabilityLayer::WindowStyleFlags::kTitleBar | PortabilityLayer::WindowStyleFlags::kMiniBar | PortabilityLayer::WindowStyleFlags::kCloseBox;
QSetRect(&coordWindowRect, 0, 0, 50, 38);
if (thisMac.hasColor)
coordWindow = NewCWindow(nil, &coordWindowRect,
PSTR("Tools"), false, windowStyle, kPutInFront, true, 0L);
PSTR("Tools"), false, windowStyle, kPutInFront, 0L);
else
coordWindow = NewWindow(nil, &coordWindowRect,
PSTR("Tools"), false, windowStyle, kPutInFront, true, 0L);
PSTR("Tools"), false, windowStyle, kPutInFront, 0L);
if (coordWindow == nil)
RedAlert(kErrNoMemory);

View File

@@ -397,7 +397,9 @@ void GetDialogString (Dialog *theDialog, short item, StringPtr theString)
void SetDialogString (Dialog *theDialog, short item, const PLPasStr &theString)
{
theDialog->GetItems()[item - 1].GetWidget()->SetString(theString);
PortabilityLayer::Widget *widget = theDialog->GetItems()[item - 1].GetWidget();
widget->SetString(theString);
widget->DrawControl(theDialog->GetWindow()->GetDrawSurface());
}
//-------------------------------------------------------------- GetDialogStringLen

View File

@@ -9,6 +9,7 @@
#include "Environ.h"
#include "MainWindow.h"
#include "Objects.h"
#include "QDPixMap.h"
#include "RectUtils.h"
#include "Room.h"
#include "Utilities.h"

View File

@@ -442,7 +442,7 @@ void HandleIdleTask (void)
{
if (theMode == kEditMode)
{
SetPort((GrafPtr)mainWindow);
SetPort(&mainWindow->GetDrawSurface()->m_port);
DoMarquee();
if ((autoRoomEdit) && (newRoomNow))

View File

@@ -69,7 +69,7 @@ void DoHighScores (void)
Rect tempRect;
SpinCursor(3);
SetPort((GrafPtr)workSrcMap);
SetPort(&workSrcMap->m_port);
workSrcMap->FillRect(workSrcRect);
QSetRect(&tempRect, 0, 0, 640, 480);
QOffsetRect(&tempRect, splashOriginH, splashOriginV);

View File

@@ -28,6 +28,8 @@
void UpdateGoToDialog (Dialog *);
Boolean GoToFilter (Dialog *, EventRecord *, short *);
extern PortabilityLayer::ResourceArchive *houseResFork;
houseHand thisHouse;
linksPtr linksList;
@@ -241,11 +243,7 @@ void WhereDoesGliderBegin (Rect *theRect, short mode)
Boolean HouseHasOriginalPicts (void)
{
short nPicts;
PL_NotYetImplemented(); nPicts = 0;
//nPicts = Count1Resources('PICT');
return (nPicts > 0);
return houseResFork->HasAnyResourcesOfType('PICT');
}
//-------------------------------------------------------------- CountHouseLinks

View File

@@ -12,6 +12,8 @@
#include "Externs.h"
#include "DialogManager.h"
#include "DialogUtils.h"
#include "HostDisplayDriver.h"
#include "IGpDisplayDriver.h"
#define kHouseInfoDialogID 1001
@@ -181,7 +183,7 @@ Boolean HouseFilter (Dialog *dial, EventRecord *event, short *item)
{
if (houseCursorIs != kBeamCursor)
{
SetBuiltinCursor(iBeamCursor);
PortabilityLayer::HostDisplayDriver::GetInstance()->SetStandardCursor(EGpStandardCursors::kIBeam);
houseCursorIs = kBeamCursor;
}
}
@@ -231,7 +233,7 @@ void DoHouseInfo (void)
houseInfoDialog = PortabilityLayer::DialogManager::GetInstance()->LoadDialog(kHouseInfoDialogID, kPutInFront, &substitutions);
if (houseInfoDialog == nil)
RedAlert(kErrDialogDidntLoad);
SetPort((GrafPtr)houseInfoDialog);
SetPort(&houseInfoDialog->GetWindow()->GetDrawSurface()->m_port);
ShowWindow(houseInfoDialog->GetWindow());
SetDialogString(houseInfoDialog, kBannerTextItem, banner);

View File

@@ -12,6 +12,7 @@
#include "Externs.h"
#include "InputManager.h"
#include "MainWindow.h"
#include "QDPixMap.h"
#include "RectUtils.h"

View File

@@ -8,6 +8,8 @@
#include "Externs.h"
#include "Environ.h"
#include "HostDisplayDriver.h"
#include "IGpDisplayDriver.h"
#include "Map.h"
#include "MenuManager.h"
#include "PLKeyEncoding.h"
@@ -20,15 +22,14 @@
#define kHoriCursorID 130
#define kDiagCursorID 131
struct IGpCursor;
extern THandle<Rect> mirrorRects;
extern WindowPtr mapWindow, toolsWindow, linkWindow;
extern WindowPtr menuWindow;
extern Rect shieldRect, boardSrcRect, localRoomsDest[];
extern CursHandle handCursorH, vertCursorH, horiCursorH;
extern CursHandle diagCursorH;
extern Cursor handCursor, vertCursor, horiCursor;
extern Cursor diagCursor;
extern IGpCursor *handCursor, *vertCursor, *horiCursor;
extern IGpCursor *diagCursor;
extern MenuHandle appleMenu, gameMenu, optionsMenu, houseMenu;
extern Point shieldPt;
extern long incrementModeTime;
@@ -81,25 +82,21 @@ void InitializeMenus (void)
void GetExtraCursors (void)
{
handCursorH = GetCursor(kHandCursorID);
if (handCursorH == nil)
handCursor = PortabilityLayer::HostDisplayDriver::GetInstance()->LoadCursor(false, kHandCursorID);
if (handCursor == nil)
RedAlert(kErrFailedResourceLoad);
handCursor = **handCursorH;
vertCursorH = GetCursor(kVertCursorID);
if (vertCursorH == nil)
vertCursor = PortabilityLayer::HostDisplayDriver::GetInstance()->LoadCursor(false, kVertCursorID);
if (vertCursor == nil)
RedAlert(kErrFailedResourceLoad);
vertCursor = **vertCursorH;
horiCursorH = GetCursor(kHoriCursorID);
if (horiCursorH == nil)
horiCursor = PortabilityLayer::HostDisplayDriver::GetInstance()->LoadCursor(false, kHoriCursorID);
if (horiCursor == nil)
RedAlert(kErrFailedResourceLoad);
horiCursor = **horiCursorH;
diagCursorH = GetCursor(kDiagCursorID);
if (diagCursorH == nil)
diagCursor = PortabilityLayer::HostDisplayDriver::GetInstance()->LoadCursor(false, kDiagCursorID);
if (diagCursor == nil)
RedAlert(kErrFailedResourceLoad);
diagCursor = **diagCursorH;
}
//-------------------------------------------------------------- VariableInit

View File

@@ -221,15 +221,15 @@ void OpenLinkWindow (void)
if (linkWindow == nil)
{
const uint16_t windowStyle = PortabilityLayer::WindowStyleFlags::kTitleBar | PortabilityLayer::WindowStyleFlags::kMiniBar;
const uint16_t windowStyle = PortabilityLayer::WindowStyleFlags::kTitleBar | PortabilityLayer::WindowStyleFlags::kMiniBar | PortabilityLayer::WindowStyleFlags::kCloseBox;
QSetRect(&linkWindowRect, 0, 0, 129, 30);
if (thisMac.hasColor)
linkWindow = NewCWindow(nil, &linkWindowRect,
PSTR("Link"), false, windowStyle, kPutInFront, true, 0L);
PSTR("Link"), false, windowStyle, kPutInFront, 0L);
else
linkWindow = NewWindow(nil, &linkWindowRect,
PSTR("Link"), false, windowStyle, kPutInFront, true, 0L);
PSTR("Link"), false, windowStyle, kPutInFront, 0L);
MoveWindow(linkWindow, isLinkH, isLinkV, true);

View File

@@ -14,6 +14,7 @@
#include "House.h"
#include "InputManager.h"
#include "MenuManager.h"
#include "QDPixMap.h"
#include "RectUtils.h"
#include "PLKeyEncoding.h"
#include "PLStandardColors.h"
@@ -35,10 +36,8 @@ CTabHandle theCTab;
PixMapHandle thePMap;
ColorSpec * wasColors;
ColorSpec * newColors;
CursHandle handCursorH, vertCursorH, horiCursorH;
CursHandle diagCursorH;
Cursor handCursor, vertCursor, horiCursor;
Cursor diagCursor;
IGpCursor *handCursor, *vertCursor, *horiCursor;
IGpCursor *diagCursor;
Rect workSrcRect;
DrawSurface *workSrcMap;
Rect mainWindowRect;
@@ -209,8 +208,8 @@ void OpenMainWindow (void)
if (OptionKeyDown())
{
isEditH = 3;
isEditV = 41;
isEditH = 10;
isEditV = 46;
}
MoveWindow(mainWindow, isEditH, isEditV, true);
ShowWindow(mainWindow);
@@ -242,7 +241,7 @@ void OpenMainWindow (void)
Rect scorebarRect = thisMac.screen;
scorebarRect.bottom = scorebarRect.top + kScoreboardTall;
PortabilityLayer::WindowDef windowDef = PortabilityLayer::WindowDef::Create(scorebarRect, PortabilityLayer::WindowStyleFlags::kBorderless, true, false, 0, 0, PSTR("Scoreboard"));
PortabilityLayer::WindowDef windowDef = PortabilityLayer::WindowDef::Create(scorebarRect, PortabilityLayer::WindowStyleFlags::kBorderless, true, 0, 0, PSTR("Scoreboard"));
boardWindow = windowManager->CreateWindow(windowDef);
if (boardWindow != nil)
windowManager->PutWindowBehind(boardWindow, PL_GetPutInFrontWindowPtr());

View File

@@ -17,6 +17,7 @@
#include "PLWidgets.h"
#include "WindowDef.h"
#include "WindowManager.h"
#include "QDPixMap.h"
#include "RectUtils.h"
#include "Utilities.h"
@@ -111,8 +112,7 @@ void FlagMapRoomsForUpdate (void)
return;
// SetPortWindowPort(mapWindow);
InvalWindowRect(mapWindow, &wasActiveRoomRect);
InvalWindowRect(mapWindow, &activeRoomRect);
UpdateMapWindow();
}
#endif
@@ -344,7 +344,7 @@ void ResizeMapWindow (short newH, short newV)
mapVScroll->Resize(kMapScrollBarWidth, mapWindowRect.bottom - kMapScrollBarWidth + 3);
mapTopRoom = mapVScroll->GetState();
InvalWindowRect(mapWindow, &mapWindowRect);
UpdateMapWindow();
#endif
}
@@ -362,9 +362,9 @@ void OpenMapWindow (void)
mapRoomsWide * kMapRoomWidth + kMapScrollBarWidth - 2,
mapRoomsHigh * kMapRoomHeight + kMapScrollBarWidth - 2);
const uint16_t windowStyle = PortabilityLayer::WindowStyleFlags::kTitleBar | PortabilityLayer::WindowStyleFlags::kResizable | PortabilityLayer::WindowStyleFlags::kMiniBar;
const uint16_t windowStyle = PortabilityLayer::WindowStyleFlags::kTitleBar | PortabilityLayer::WindowStyleFlags::kResizable | PortabilityLayer::WindowStyleFlags::kMiniBar | PortabilityLayer::WindowStyleFlags::kCloseBox;;
PortabilityLayer::WindowDef wdef = PortabilityLayer::WindowDef::Create(mapWindowRect, windowStyle, false, true, 0, 0, PSTR("Map"));
PortabilityLayer::WindowDef wdef = PortabilityLayer::WindowDef::Create(mapWindowRect, windowStyle, false, 0, 0, PSTR("Map"));
mapWindow = PortabilityLayer::WindowManager::GetInstance()->CreateWindow(wdef);
@@ -386,7 +386,7 @@ void OpenMapWindow (void)
PortabilityLayer::WindowManager::GetInstance()->ShowWindow(mapWindow);
// FlagWindowFloating(mapWindow); TEMP - use flaoting windows
SetPort((GrafPtr)mapWindow);
SetPort(&mapWindow->GetDrawSurface()->m_port);
QSetRect(&mapHScrollRect, -1, mapRoomsHigh * kMapRoomHeight,
mapRoomsWide * kMapRoomWidth + 1,
mapRoomsHigh * kMapRoomHeight + kMapScrollBarWidth);
@@ -425,6 +425,8 @@ void OpenMapWindow (void)
mapWindowRect.bottom + 2);
CenterMapOnRoom(thisRoom->suite, thisRoom->floor);
UpdateMapWindow();
}
UpdateMapCheckmark(true);
@@ -579,7 +581,7 @@ void HandleMapClick (const GpMouseInputEvent &theEvent)
{
#ifndef COMPILEDEMO
Rect aRoom;
ControlHandle whichControl;
PortabilityLayer::Widget *whichControl = nullptr;
Point wherePt, globalWhere;
long controlRef;
short whichPart, localH, localV;
@@ -665,7 +667,7 @@ void HandleMapClick (const GpMouseInputEvent &theEvent)
}
else
{
controlRef = GetControlReference(whichControl);
controlRef = whichControl->GetReferenceConstant();
if (controlRef == kHScrollRef)
{
switch (whichPart)
@@ -683,7 +685,7 @@ void HandleMapClick (const GpMouseInputEvent &theEvent)
case kControlIndicatorPart:
if (TrackControl(whichControl, wherePt, nil))
{
mapLeftRoom = GetControlValue(whichControl);
mapLeftRoom = whichControl->GetState();
RedrawMapContents();
}
break;
@@ -706,7 +708,7 @@ void HandleMapClick (const GpMouseInputEvent &theEvent)
case kControlIndicatorPart:
if (TrackControl(whichControl, wherePt, nil))
{
mapTopRoom = GetControlValue(whichControl);
mapTopRoom = whichControl->GetState();
RedrawMapContents();
}
break;

View File

@@ -6,11 +6,15 @@
#include "Externs.h"
#include "HostDisplayDriver.h"
#include "IGpDisplayDriver.h"
#include "Marquee.h"
#include "Objects.h"
#include "ObjectEdit.h"
#include "RectUtils.h"
#include <assert.h>
#define kMarqueePatListID 128
#define kHandleSideLong 9
@@ -25,7 +29,7 @@ Rect marqueeGliderRect;
Boolean gliderMarqueeUp;
extern Cursor handCursor, vertCursor, horiCursor, diagCursor;
extern IGpCursor *handCursor, *vertCursor, *horiCursor, *diagCursor;
extern Rect leftStartGliderSrc;
@@ -216,7 +220,7 @@ void DragMarqueeRect (DrawSurface *surface, Point start, Rect *theRect, Boolean
Point wasPt, newPt;
short deltaH, deltaV;
SetCursor(&handCursor);
PortabilityLayer::HostDisplayDriver::GetInstance()->SetCursor(handCursor);
StopMarquee();
const uint8_t *pattern = theMarquee.pats[theMarquee.index];
@@ -259,9 +263,9 @@ void DragMarqueeHandle (DrawSurface *surface, Point start, short *dragged)
short deltaH, deltaV;
if ((theMarquee.direction == kAbove) || (theMarquee.direction == kBelow))
SetCursor(&vertCursor);
PortabilityLayer::HostDisplayDriver::GetInstance()->SetCursor(vertCursor);
else
SetCursor(&horiCursor);
PortabilityLayer::HostDisplayDriver::GetInstance()->SetCursor(horiCursor);
StopMarquee();
const uint8_t *pattern = theMarquee.pats[theMarquee.index];
@@ -344,7 +348,7 @@ void DragMarqueeCorner (DrawSurface *surface, Point start, short *hDragged, shor
Point wasPt, newPt;
short deltaH, deltaV;
SetCursor(&diagCursor);
PortabilityLayer::HostDisplayDriver::GetInstance()->SetCursor(diagCursor);
StopMarquee();
const uint8_t *pattern = theMarquee.pats[theMarquee.index];
@@ -428,11 +432,9 @@ Boolean PtInMarqueeHandle (Point where)
void DrawGliderMarquee (void)
{
CopyBits((BitMap *)*GetGWorldPixMap(blowerMaskMap),
GetPortBitMapForCopyBits(GetWindowPort(mainWindow)),
&leftStartGliderSrc,
&marqueeGliderRect,
srcXor);
DrawSurface *surface = GetWindowPort(mainWindow);
ImageInvert(*GetGWorldPixMap(blowerMaskMap), GetPortBitMapForCopyBits(surface), leftStartGliderSrc, marqueeGliderRect);
surface->m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents);
}
//-------------------------------------------------------------- SetMarqueeGliderCenter
@@ -488,7 +490,7 @@ void DrawMarquee (DrawSurface *surface, const uint8_t *pattern)
break;
}
surface->InvertDrawLine(points[0], points[1], pattern);
surface->InvertFillRect(Rect::Create(points[0].v, points[0].h, points[1].v, points[1].h), pattern);
}
if (gliderMarqueeUp)

View File

@@ -747,7 +747,7 @@ short QueryResumeGame (void)
theDial = PortabilityLayer::DialogManager::GetInstance()->LoadDialog(kResumeGameDial, kPutInFront, &substitutions);
if (theDial == nil)
RedAlert(kErrDialogDidntLoad);
SetPort((GrafPtr)theDial);
SetPort(&theDial->GetWindow()->GetDrawSurface()->m_port);
ShowWindow(theDial->GetWindow());
DrawDefaultButton(theDial);

View File

@@ -789,7 +789,7 @@ Boolean AddNewObject (Point where, short what, Boolean showItNow)
ReadyBackground(thisRoom->background, thisRoom->tiles);
GetThisRoomsObjRects();
DrawThisRoomsObjects();
InvalWindowRect(mainWindow, &mainWindowRect);
UpdateMainWindow();
if (handled)
{

View File

@@ -2316,8 +2316,7 @@ void DrawThisRoomsObjects (void)
if (GetNumberOfLights(thisRoomNumber) <= 0)
{
surface->SetMaskMode(true);
surface->SetPattern8x8(*GetQDGlobalsGray(&dummyPattern));
surface->FillRect(backSrcRect);
surface->FillRectWithPattern8x8(backSrcRect, *GetQDGlobalsGray(&dummyPattern));
surface->SetMaskMode(false);
}

View File

@@ -947,7 +947,7 @@ void DoBlowerObjectInfo (short what)
infoDial = PortabilityLayer::DialogManager::GetInstance()->LoadDialog(kBlowerInfoDialogID, kPutInFront, &substitutions);
if (infoDial == nil)
RedAlert(kErrDialogDidntLoad);
SetPort((GrafPtr)infoDial);
SetPort(&infoDial->GetWindow()->GetDrawSurface()->m_port);
newDirection = thisRoom->objects[objActive].data.a.vector & 0x0F;
if (thisRoom->objects[objActive].data.a.initial)
@@ -1544,7 +1544,7 @@ void DoLightObjectInfo (void)
infoDial = PortabilityLayer::DialogManager::GetInstance()->LoadDialog(kLightInfoDialogID, kPutInFront, &substitutions);
if (infoDial == nil)
RedAlert(kErrDialogDidntLoad);
SetPort((GrafPtr)infoDial);
SetPort(&infoDial->GetWindow()->GetDrawSurface()->m_port);
if (thisRoom->objects[objActive].data.f.initial)
SetDialogItemValue(infoDial, kInitialStateCheckbox, 1);

View File

@@ -12,6 +12,7 @@
#include "Objects.h"
#include "Play.h"
#include "Player.h"
#include "QDPixMap.h"
#include "RectUtils.h"
#include "Room.h"
#include "RubberBands.h"
@@ -148,7 +149,7 @@ void DrawReflection (gliderPtr thisGlider, Boolean oneOrTwo)
dest = thisGlider->dest;
QOffsetRect(&dest, playOriginH - 20, playOriginV - 16);
SetPort((GrafPtr)workSrcMap);
SetPort(&workSrcMap->m_port);
long numMirrorRects = GetHandleSize(mirrorRects.StaticCast<void>()) / sizeof(Rect);

View File

@@ -16,6 +16,7 @@
#include "House.h"
#include "InputManager.h"
#include "MainWindow.h"
#include "MemoryManager.h"
#include "RectUtils.h"
@@ -197,13 +198,13 @@ Boolean CreateNewRoom (short h, short v)
if (availableRoom == -1) // found no available rooms
{
howMuch = sizeof(roomType); // add new room to end of house
theErr = PtrAndHand((Ptr)thisRoom, thisHouse.StaticCast<void>(), howMuch);
if (theErr != PLErrors::kNone)
// add new room to end of house
if (!PortabilityLayer::MemoryManager::GetInstance()->ResizeHandle(thisHouse.MMBlock(), thisHouse.MMBlock()->m_size + sizeof(roomType)))
{
YellowAlert(kYellowUnaccounted, theErr);
YellowAlert(kYellowUnaccounted, PLErrors::kOutOfMemory);
return (false);
}
(*thisHouse)->rooms[(*thisHouse)->nRooms] = *thisRoom;
(*thisHouse)->nRooms++; // increment nRooms
numberRooms = (*thisHouse)->nRooms;
previousRoom = thisRoomNumber;
@@ -336,7 +337,7 @@ void ReflectCurrentRoom (Boolean forceMapRedraw)
PL_NotYetImplemented_TODO("FixMe");
DebugPixMap(backSrcMap->m_port.GetPixMap(), "DebugData/EditorSplash6");
//InvalWindowRect(mainWindow, &mainWindowRect);
UpdateMainWindow();
#endif
}

View File

@@ -14,7 +14,11 @@
#include "DialogManager.h"
#include "DialogUtils.h"
#include "Externs.h"
#include "HostDisplayDriver.h"
#include "IGpDisplayDriver.h"
#include "RectUtils.h"
#include "PLTimeTaggedVOSEvent.h"
#include "QDPixMap.h"
#include "ResourceCompiledRef.h"
#include "ResourceManager.h"
#include "Utilities.h"
@@ -41,7 +45,8 @@
void UpdateRoomInfoDialog (Dialog *);
void DragMiniTile (DrawSurface *, Point, short *);
void HiliteTileOver (DrawSurface *, Point);
Boolean RoomFilter (Dialog *, EventRecord *, short *);
int16_t RoomFilter (Dialog *dialog, const TimeTaggedVOSEvent *evt);
short ChooseOriginalArt (short);
void UpdateOriginalArt (Dialog *);
Boolean OriginalArtFilter (Dialog *, EventRecord *, short *);
@@ -58,7 +63,7 @@ short tileOver, tempBack, cursorIs;
Boolean originalLeftOpen, originalTopOpen, originalRightOpen, originalBottomOpen;
Boolean originalFloor;
extern Cursor handCursor;
extern IGpCursor *handCursor;
extern short lastBackground;
@@ -71,7 +76,6 @@ void UpdateRoomInfoDialog (Dialog *theDialog)
Rect src, dest;
short i;
DrawDialog(theDialog);
if (tempBack >= kUserBackground)
SetPopUpMenuValue(theDialog, kRoomPopupItem, kOriginalArtworkItem);
else
@@ -81,7 +85,7 @@ void UpdateRoomInfoDialog (Dialog *theDialog)
CopyBits(GetPortBitMapForCopyBits(tileSrcMap),
GetPortBitMapForCopyBits(GetDialogPort(theDialog)),
GetPortBitMapForCopyBits(theDialog->GetWindow()->GetDrawSurface()),
&tileSrcRect, &tileSrc, srcCopy);
/*
CopyBits(&((GrafPtr)tileSrcMap)->portBits,
@@ -96,7 +100,7 @@ void UpdateRoomInfoDialog (Dialog *theDialog)
QOffsetRect(&src, tempTiles[i] * kMiniTileWide, 0);
CopyBits(GetPortBitMapForCopyBits(tileSrcMap),
GetPortBitMapForCopyBits(GetDialogPort(theDialog)),
GetPortBitMapForCopyBits(theDialog->GetWindow()->GetDrawSurface()),
&src, &dest, srcCopy);
/*
CopyBits(&((GrafPtr)tileSrcMap)->portBits,
@@ -263,7 +267,7 @@ void HiliteTileOver (DrawSurface *surface, Point mouseIs)
{
if (cursorIs != kHandCursor)
{
SetCursor(&handCursor);
PortabilityLayer::HostDisplayDriver::GetInstance()->SetCursor(handCursor);
cursorIs = kHandCursor;
}
@@ -327,7 +331,7 @@ void HiliteTileOver (DrawSurface *surface, Point mouseIs)
{
if (cursorIs != kBeamCursor)
{
SetBuiltinCursor(iBeamCursor);
PortabilityLayer::HostDisplayDriver::GetInstance()->SetStandardCursor(EGpStandardCursors::kIBeam);
cursorIs = kBeamCursor;
}
}
@@ -346,43 +350,44 @@ void HiliteTileOver (DrawSurface *surface, Point mouseIs)
//-------------------------------------------------------------- RoomFilter
#ifndef COMPILEDEMO
Boolean RoomFilter (Dialog *dial, EventRecord *event, short *item)
int16_t RoomFilter(Dialog *dial, const TimeTaggedVOSEvent *evt)
{
Point mouseIs;
short newTileOver;
if (!evt)
return -1;
DrawSurface *surface = dial->GetWindow()->GetDrawSurface();
switch (event->what)
if (evt->IsKeyDownEvent())
{
case keyDown:
switch (event->message)
switch (PackVOSKeyCode(evt->m_vosEvent.m_event.m_keyboardInputEvent))
{
case PL_KEY_SPECIAL(kEnter):
case PL_KEY_NUMPAD_SPECIAL(kEnter):
FlashDialogButton(dial, kOkayButton);
*item = kOkayButton;
return(true);
break;
return kOkayButton;
case PL_KEY_SPECIAL(kEscape):
FlashDialogButton(dial, kCancelButton);
*item = kCancelButton;
return(true);
break;
return kCancelButton;
case PL_KEY_SPECIAL(kTab):
SelectDialogItemText(dial, kRoomNameItem, 0, 1024);
return(true);
break;
return 0;
default:
return(false);
return -1;
}
break;
}
else if (evt->m_vosEvent.m_eventType == GpVOSEventTypes::kMouseInput)
{
const GpMouseInputEvent &mouseEvent = evt->m_vosEvent.m_event.m_mouseInputEvent;
case mouseDown:
mouseIs = event->where;
if (evt->IsLMouseDownEvent())
{
mouseIs = Point::Create(mouseEvent.m_x, mouseEvent.m_y);
mouseIs -= dial->GetWindow()->TopLeftCoord();
if (tileSrc.Contains(mouseIs))
{
@@ -395,29 +400,16 @@ Boolean RoomFilter (Dialog *dial, EventRecord *event, short *item)
UpdateRoomInfoDialog(dial);
}
}
return(true);
return 0;
}
else
return(false);
break;
case mouseUp:
return(false);
break;
case updateEvt:
SetPortDialogPort(dial);
UpdateRoomInfoDialog(dial);
EndUpdate(dial->GetWindow());
event->what = nullEvent;
return(false);
break;
default:
GetMouse(&mouseIs);
return -1;
}
else if (mouseEvent.m_eventType == GpMouseEventTypes::kMove)
{
mouseIs = dial->GetWindow()->MouseToLocal(mouseEvent);
HiliteTileOver(surface, mouseIs);
return(false);
break;
}
}
}
#endif
@@ -470,7 +462,7 @@ void DoRoomInfo (void)
roomInfoDialog = PortabilityLayer::DialogManager::GetInstance()->LoadDialog(kRoomInfoDialogID, kPutInFront, &substitutions);
if (roomInfoDialog == nil)
RedAlert(kErrDialogDidntLoad);
SetPort((GrafPtr)roomInfoDialog);
SetPort(&roomInfoDialog->GetWindow()->GetDrawSurface()->m_port);
// Fix this later. TEMP
// AddMenuToPopUp(roomInfoDialog, kRoomPopupItem, backgroundsMenu);
@@ -498,9 +490,11 @@ void DoRoomInfo (void)
leaving = false;
UpdateRoomInfoDialog(roomInfoDialog);
while (!leaving)
{
ModalDialog(RoomFilter, &item);
item = roomInfoDialog->ExecuteModal(RoomFilter);
if (item == kOkayButton)
{

View File

@@ -11,6 +11,7 @@
#include "Externs.h"
#include "Environ.h"
#include "MenuManager.h"
#include "QDPixMap.h"
#include "QDStandardPalette.h"
#include "RectUtils.h"

View File

@@ -14,6 +14,7 @@
#include "FontFamily.h"
#include "PLWidgets.h"
#include "PLPopupMenuWidget.h"
#include "QDPixMap.h"
#include "RectUtils.h"
#include "Utilities.h"
#include "WindowDef.h"
@@ -199,7 +200,7 @@ void EraseSelectedTool (void)
if (toolsWindow == nil)
return;
SetPort((GrafPtr)toolsWindow);
SetPort(&toolsWindow->GetDrawSurface()->m_port);
toolIcon = toolSelected;
if ((toolMode == kBlowerMode) && (toolIcon >= 7))
@@ -299,9 +300,9 @@ void OpenToolsWindow (void)
QOffsetRect(&toolTextRect, 0, 157 - 15);
{
const uint16_t windowStyle = PortabilityLayer::WindowStyleFlags::kTitleBar | PortabilityLayer::WindowStyleFlags::kMiniBar;
const uint16_t windowStyle = PortabilityLayer::WindowStyleFlags::kTitleBar | PortabilityLayer::WindowStyleFlags::kMiniBar | PortabilityLayer::WindowStyleFlags::kCloseBox;
PortabilityLayer::WindowDef wdef = PortabilityLayer::WindowDef::Create(toolsWindowRect, windowStyle, false, true, 0, 0, PSTR("Tools"));
PortabilityLayer::WindowDef wdef = PortabilityLayer::WindowDef::Create(toolsWindowRect, windowStyle, false, 0, 0, PSTR("Tools"));
toolsWindow = wm->CreateWindow(wdef);
}
@@ -333,6 +334,8 @@ void OpenToolsWindow (void)
classPopUp = PortabilityLayer::PopupMenuWidget::Create(state);
}
toolsWindow->DrawControls();
if (classPopUp == nil)
RedAlert(kErrFailedResourceLoad);
@@ -473,7 +476,7 @@ void HandleToolsClick (Point wherePt)
part = FindControl(wherePt, toolsWindow, &theControl);
if ((theControl != nil) && (part != 0))
{
part = TrackControl(theControl, wherePt, nullptr);
part = theControl->Capture(wherePt, nullptr);
if (part != 0)
{
newMode = theControl->GetState();

View File

@@ -9,6 +9,7 @@
#include "Externs.h"
#include "Environ.h"
#include "MainWindow.h"
#include "QDPixMap.h"
#include "PLQDraw.h"
#include "RectUtils.h"

View File

@@ -108,7 +108,7 @@ void OpenMessageWindow (const PLPasStr &title)
SetRect(&mssgWindowRect, 0, 0, 256, kMessageWindowTall);
const PortabilityLayer::WindowDef wdef = PortabilityLayer::WindowDef::Create(mssgWindowRect, windowStyle, false, false, 0, 0, title);
const PortabilityLayer::WindowDef wdef = PortabilityLayer::WindowDef::Create(mssgWindowRect, windowStyle, false, 0, 0, title);
mssgWindow = PortabilityLayer::WindowManager::GetInstance()->CreateWindow(wdef);

View File

@@ -5,6 +5,8 @@ namespace EGpStandardCursors
enum EGpStandardCursor
{
kArrow,
kIBeam,
kWait,
kHidden,
};
}

View File

@@ -1,10 +1,10 @@
#pragma once
#include "IGpColorCursor_Win32.h"
#include "IGpCursor_Win32.h"
#include "GpWindows.h"
class GpColorCursor_Win32 final : public IGpColorCursor_Win32
class GpCursor_Win32 final : public IGpCursor_Win32
{
public:
void Destroy() override;
@@ -14,11 +14,11 @@ public:
void IncRef() override;
void DecRef() override;
static GpColorCursor_Win32 *Load(const wchar_t *path);
static IGpCursor_Win32 *Load(const wchar_t *path);
private:
GpColorCursor_Win32(HCURSOR cursor);
~GpColorCursor_Win32();
GpCursor_Win32(HCURSOR cursor);
~GpCursor_Win32();
HCURSOR m_cursor;
int m_refCount;

View File

@@ -8,10 +8,11 @@
#undef CreateMutex
#undef DeleteFile
#undef LoadCursor
struct IGpFiber;
struct IGpColorCursor_Win32;
struct IGpBWCursor_Win32;
struct IGpCursor_Win32;
struct IGpVOSEventQueue;
struct GpWindowsGlobals
@@ -23,7 +24,6 @@ struct GpWindowsGlobals
int m_nCmdShow;
IGpFiber *(*m_createFiberFunc)(LPVOID fiber);
IGpColorCursor_Win32 *(*m_loadColorCursorFunc)(const wchar_t *path);
IGpCursor_Win32 *(*m_loadCursorFunc)(const wchar_t *path);
void (*m_translateWindowsMessageFunc)(const MSG *msg, IGpVOSEventQueue *eventQueue);
};

View File

@@ -1,6 +1,6 @@
#pragma once
struct IGpColorCursor
struct IGpCursor
{
virtual void Destroy() = 0;
};

View File

@@ -1,9 +1,9 @@
#pragma once
#include "IGpColorCursor.h"
#include "IGpCursor.h"
#include "GpWindows.h"
struct IGpColorCursor_Win32 : public IGpColorCursor
struct IGpCursor_Win32 : public IGpCursor
{
public:
virtual const HCURSOR &GetHCursor() const = 0;

View File

@@ -4,7 +4,7 @@
#include "EGpStandardCursor.h"
struct IGpDisplayDriverSurface;
struct IGpColorCursor;
struct IGpCursor;
// Display drivers are responsible for timing and calling the game tick function.
struct IGpDisplayDriver
@@ -16,10 +16,10 @@ public:
virtual void GetDisplayResolution(unsigned int *width, unsigned int *height, GpPixelFormat_t *bpp) = 0;
virtual IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, GpPixelFormat_t pixelFormat) = 0;
virtual void DrawSurface(IGpDisplayDriverSurface *surface, size_t x, size_t y, size_t width, size_t height) = 0;
virtual void DrawSurface(IGpDisplayDriverSurface *surface, int32_t x, int32_t y, size_t width, size_t height) = 0;
virtual IGpColorCursor *LoadColorCursor(int cursorID) = 0;
virtual void SetColorCursor(IGpColorCursor *colorCursor) = 0;
virtual IGpCursor *LoadCursor(bool isColor, int cursorID) = 0;
virtual void SetCursor(IGpCursor *cursor) = 0;
virtual void SetStandardCursor(EGpStandardCursor_t standardCursor) = 0;
virtual void UpdatePalette(const void *paletteData) = 0;

View File

@@ -3,7 +3,7 @@
#include "GpDisplayDriverD3D11.h"
#include "GpDisplayDriverSurfaceD3D11.h"
#include "GpWindows.h"
#include "IGpColorCursor_Win32.h"
#include "IGpCursor_Win32.h"
#include "IGpFiber.h"
#include <d3d11.h>
@@ -502,7 +502,7 @@ void GpDisplayDriverD3D11::SynchronizeCursors()
void GpDisplayDriverD3D11::ChangeToCursor(HCURSOR cursor)
{
if (m_mouseIsInClientArea)
SetCursor(cursor);
::SetCursor(cursor);
SetClassLongPtrW(m_hwnd, GCLP_HCURSOR, reinterpret_cast<LONG_PTR>(cursor));
}
@@ -511,6 +511,12 @@ void GpDisplayDriverD3D11::ChangeToStandardCursor(EGpStandardCursor_t cursor)
{
switch (cursor)
{
case EGpStandardCursors::kIBeam:
ChangeToCursor(m_ibeamCursor);
break;
case EGpStandardCursors::kWait:
ChangeToCursor(m_waitCursor);
break;
case EGpStandardCursors::kArrow:
default:
ChangeToCursor(m_arrowCursor);
@@ -624,7 +630,7 @@ IGpDisplayDriverSurface *GpDisplayDriverD3D11::CreateSurface(size_t width, size_
return GpDisplayDriverSurfaceD3D11::Create(m_device, m_deviceContext, width, height, pixelFormat);
}
void GpDisplayDriverD3D11::DrawSurface(IGpDisplayDriverSurface *surface, size_t x, size_t y, size_t width, size_t height)
void GpDisplayDriverD3D11::DrawSurface(IGpDisplayDriverSurface *surface, int32_t x, int32_t y, size_t width, size_t height)
{
ID3D11Buffer *vbPtr = m_quadVertexBuffer;
UINT vbStride = sizeof(float) * 2;
@@ -710,24 +716,30 @@ void GpDisplayDriverD3D11::DrawSurface(IGpDisplayDriverSurface *surface, size_t
m_deviceContext->DrawIndexed(6, 0, 0);
}
IGpColorCursor *GpDisplayDriverD3D11::LoadColorCursor(int cursorID)
IGpCursor *GpDisplayDriverD3D11::LoadCursor(bool isColor, int cursorID)
{
const size_t bufSize = MAX_PATH;
wchar_t path[bufSize];
int sz = _snwprintf(path, bufSize, L"%sPackaged\\WinCursors\\%i.cur", m_osGlobals->m_baseDir, cursorID);
int sz = 0;
if (isColor)
sz = _snwprintf(path, bufSize, L"%sPackaged\\WinCursors\\c%i.cur", m_osGlobals->m_baseDir, cursorID);
else
sz = _snwprintf(path, bufSize, L"%sPackaged\\WinCursors\\b%i.cur", m_osGlobals->m_baseDir, cursorID);
if (sz < 0 || static_cast<size_t>(sz) >= bufSize)
return nullptr;
return m_osGlobals->m_loadColorCursorFunc(path);
return m_osGlobals->m_loadCursorFunc(path);
}
// We can't just set the cursor because we want to post WM_SETCURSOR to keep it limited
// to the game window area, but depending on the fiber implementation, this may not be
// the window thread.
void GpDisplayDriverD3D11::SetColorCursor(IGpColorCursor *colorCursor)
void GpDisplayDriverD3D11::SetCursor(IGpCursor *cursor)
{
IGpColorCursor_Win32 *winCursor = static_cast<IGpColorCursor_Win32*>(colorCursor);
IGpCursor_Win32 *winCursor = static_cast<IGpCursor_Win32*>(cursor);
winCursor->IncRef();
@@ -797,6 +809,8 @@ GpDisplayDriverD3D11::GpDisplayDriverD3D11(const GpDisplayDriverProperties &prop
m_frameTimeSliceSize = m_QPFrequency.QuadPart * static_cast<LONGLONG>(properties.m_frameTimeLockNumerator) / static_cast<LONGLONG>(properties.m_frameTimeLockDenominator);
m_arrowCursor = reinterpret_cast<HCURSOR>(LoadImageW(nullptr, MAKEINTRESOURCEW(OCR_NORMAL), IMAGE_CURSOR, 0, 0, LR_SHARED));
m_ibeamCursor = reinterpret_cast<HCURSOR>(LoadImageW(nullptr, MAKEINTRESOURCEW(OCR_IBEAM), IMAGE_CURSOR, 0, 0, LR_SHARED));
m_waitCursor = reinterpret_cast<HCURSOR>(LoadImageW(nullptr, MAKEINTRESOURCEW(OCR_WAIT), IMAGE_CURSOR, 0, 0, LR_SHARED));
}
GpDisplayDriverD3D11::~GpDisplayDriverD3D11()

View File

@@ -11,7 +11,8 @@
#include "GpPixelFormat.h"
struct GpWindowsGlobals;
struct IGpColorCursor_Win32;
struct IGpCursor_Win32;
struct IGpCursor;
struct IGpFiber;
struct IDXGISwapChain1;
@@ -37,10 +38,10 @@ public:
void GetDisplayResolution(unsigned int *width, unsigned int *height, GpPixelFormat_t *bpp) override;
IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, GpPixelFormat_t pixelFormat) override;
void DrawSurface(IGpDisplayDriverSurface *surface, size_t x, size_t y, size_t width, size_t height) override;
void DrawSurface(IGpDisplayDriverSurface *surface, int32_t x, int32_t y, size_t width, size_t height) override;
IGpColorCursor *LoadColorCursor(int cursorID) override;
void SetColorCursor(IGpColorCursor *colorCursor) override;
IGpCursor *LoadCursor(bool isColor, int cursorID) override;
void SetCursor(IGpCursor *cursor) override;
void SetStandardCursor(EGpStandardCursor_t standardCursor) override;
void UpdatePalette(const void *paletteData) override;
@@ -109,8 +110,8 @@ private:
DWORD m_windowWidth;
DWORD m_windowHeight;
IGpColorCursor_Win32 *m_activeCursor;
IGpColorCursor_Win32 *m_pendingCursor;
IGpCursor_Win32 *m_activeCursor;
IGpCursor_Win32 *m_pendingCursor;
EGpStandardCursor_t m_currentStandardCursor;
EGpStandardCursor_t m_pendingStandardCursor;
bool m_mouseIsInClientArea;
@@ -119,5 +120,7 @@ private:
GpWindowsGlobals *m_osGlobals;
HCURSOR m_arrowCursor;
HCURSOR m_waitCursor;
HCURSOR m_ibeamCursor;
HWND m_hwnd;
};

View File

@@ -328,11 +328,6 @@ namespace PortabilityLayer
if (isVisible)
widget->DrawControl(surface);
else
{
surface->SetForeColor(StdColors::Red());
surface->FrameRect(surface->m_port.GetRect());
}
}
}
@@ -621,7 +616,11 @@ namespace PortabilityLayer
WindowManager *wm = PortabilityLayer::WindowManager::GetInstance();
WindowDef wdef = WindowDef::Create(rect, WindowStyleFlags::kAlert, visible, hasCloseBox, referenceConstant, positionSpec, title);
uint16_t styleFlags = WindowStyleFlags::kAlert;
if (hasCloseBox)
styleFlags |= PortabilityLayer::WindowStyleFlags::kCloseBox;
WindowDef wdef = WindowDef::Create(rect, styleFlags, visible, referenceConstant, positionSpec, title);
Window *window = wm->CreateWindow(wdef);
if (!window)
{

View File

@@ -5,7 +5,7 @@
#include "GpPixelFormat.h"
#include "EGpStandardCursor.h"
struct IGpColorCursor;
struct IGpCursor;
struct IGpDisplayDriver;
namespace PortabilityLayer

View File

@@ -131,6 +131,11 @@ namespace PortabilityLayer
void SetItemChecked(const THandle<Menu> &menu, unsigned int index, bool checked) override;
bool SetItemText(const THandle<Menu> &menu, unsigned int index, const PLPasStr &str) override;
bool GetMenuEnabled(const THandle<Menu> &menuHandle) const override;
bool GetItemEnabled(const THandle<Menu> &menu, unsigned int index) const override;
bool GetItemChecked(const THandle<Menu> &menu, unsigned int index) const override;
PLPasStr GetItemText(const THandle<Menu> &menu, unsigned int index) const override;
bool IsPointInMenuBar(const Vec2i &point) const override;
bool FindMenuShortcut(uint16_t &menuID, uint16_t &itemID, uint8_t shortcutChar) override;
@@ -517,6 +522,42 @@ namespace PortabilityLayer
return true;
}
bool MenuManagerImpl::GetMenuEnabled(const THandle<Menu> &menuHandle) const
{
const Menu *menu = (*menuHandle);
return menu->enabled;
}
bool MenuManagerImpl::GetItemEnabled(const THandle<Menu> &menuHandle, unsigned int index) const
{
const Menu *menu = (*menuHandle);
if (index >= menu->numMenuItems)
return false;
return menu->menuItems[index].enabled;
}
bool MenuManagerImpl::GetItemChecked(const THandle<Menu> &menuHandle, unsigned int index) const
{
const Menu *menu = (*menuHandle);
if (index >= menu->numMenuItems)
return false;
return menu->menuItems[index].checked;
}
PLPasStr MenuManagerImpl::GetItemText(const THandle<Menu> &menuHandle, unsigned int index) const
{
const Menu *menu = (*menuHandle);
if (index >= menu->numMenuItems)
return PSTR("");
const uint32_t nameOffset = menu->menuItems[index].nameOffsetInStringBlob;
const uint8_t *pstr = static_cast<const uint8_t*>(menu->stringBlobHandle->m_contents) + nameOffset;
return PLPasStr(pstr);
}
bool MenuManagerImpl::IsPointInMenuBar(const Vec2i &point) const
{
return point.m_y >= 0 && static_cast<uint32_t>(point.m_y) < kMenuBarHeight;

View File

@@ -34,6 +34,11 @@ namespace PortabilityLayer
virtual void SetItemChecked(const THandle<Menu> &menu, unsigned int index, bool checked) = 0;
virtual bool SetItemText(const THandle<Menu> &menu, unsigned int index, const PLPasStr &str) = 0;
virtual bool GetMenuEnabled(const THandle<Menu> &menuHandle) const = 0;
virtual bool GetItemEnabled(const THandle<Menu> &menu, unsigned int index) const = 0;
virtual bool GetItemChecked(const THandle<Menu> &menu, unsigned int index) const = 0;
virtual PLPasStr GetItemText(const THandle<Menu> &menu, unsigned int index) const = 0;
virtual bool IsPointInMenuBar(const Vec2i &point) const = 0;
virtual bool FindMenuShortcut(uint16_t &menuID, uint16_t &itemID, uint8_t shortcutChar) = 0;

View File

@@ -20,7 +20,7 @@
#include "HostDisplayDriver.h"
#include "HostSystemServices.h"
#include "HostVOSEventQueue.h"
#include "IGpColorCursor.h"
#include "IGpCursor.h"
#include "IGpDisplayDriver.h"
#include "InputManager.h"
#include "ResourceManager.h"
@@ -87,26 +87,11 @@ Rect BERect::ToRect() const
return rect;
}
CursHandle GetCursor(int cursorID)
{
return PortabilityLayer::ResourceManager::GetInstance()->GetAppResource('CURS', cursorID).ReinterpretCast<Cursor>();
}
void HideCursor()
{
PortabilityLayer::HostDisplayDriver::GetInstance()->SetStandardCursor(EGpStandardCursors::kHidden);
}
void SetCursor(CursPtr cursor)
{
PL_NotYetImplemented();
}
void SetBuiltinCursor(int builtinCursor)
{
PL_NotYetImplemented();
}
void Delay(int ticks, UInt32 *endTickCount)
{
PLSysCalls::Sleep(ticks);
@@ -203,13 +188,13 @@ WindowPtr GetNewCWindow(int resID, void *storage, WindowPtr behind)
return window;
}
WindowPtr NewCWindow(void *storage, const Rect *bounds, const PLPasStr &title, Boolean visible, int wdef, WindowPtr behind, Boolean hasCloseBox, long userdata)
WindowPtr NewCWindow(void *storage, const Rect *bounds, const PLPasStr &title, Boolean visible, int wdef, WindowPtr behind, long userdata)
{
PL_NotYetImplemented();
return nullptr;
}
WindowPtr NewWindow(void *storage, const Rect *bounds, const PLPasStr &title, Boolean visible, int wdef, WindowPtr behind, Boolean hasCloseBox, long userdata)
WindowPtr NewWindow(void *storage, const Rect *bounds, const PLPasStr &title, Boolean visible, int wdef, WindowPtr behind, long userdata)
{
PL_NotYetImplemented();
return nullptr;
@@ -616,12 +601,6 @@ long GetHandleSize(Handle handle)
return handle.MMBlock()->m_size;
}
PLError_t PtrAndHand(const void *data, Handle handle, Size size)
{
PL_NotYetImplemented();
return PLErrors::kNone;
}
PLError_t SetHandleSize(Handle hdl, Size newSize)
{
PortabilityLayer::MemoryManager *mm = PortabilityLayer::MemoryManager::GetInstance();
@@ -779,6 +758,19 @@ bool Window::AddWidget(PortabilityLayer::Widget *widget)
return true;
}
ArrayView<PortabilityLayer::Widget*> Window::GetWidgets() const
{
return ArrayView<PortabilityLayer::Widget*>(m_widgets, m_numWidgets);
}
PortabilityLayer::Widget* Window::GetWidgetById() const
{
//for (size_t i = 0; i < m_numWidgets; i++)
// m_widgets[i]->get
//return ArrayView<PortabilityLayer::Widget*>(m_widgets, m_numWidgets);
return nullptr;
}
void Window::FocusWidget(PortabilityLayer::Widget *widget)
{
if (m_widgetWithFocus != widget)
@@ -825,7 +817,7 @@ void Window::OnTick()
m_widgets[i]->OnTick();
}
ArrayView<PortabilityLayer::Widget*> Window::GetWidgets() const
DrawSurface *Window::GetChromeSurface(WindowChromeSide_t aChromeSide) const
{
return ArrayView< PortabilityLayer::Widget*>(m_widgets, m_numWidgets);
return const_cast<DrawSurface*>(m_chromeSurfaces + aChromeSide);
}

View File

@@ -15,7 +15,7 @@
template<class T>
class ArrayView;
struct IGpColorCursor;
struct IGpCursor;
struct GpVOSEvent;
struct GpMouseInputEvent;
struct TimeTaggedVOSEvent;
@@ -71,6 +71,21 @@ struct Cursor
{
};
namespace WindowChromeSides
{
enum WindowChromeSide
{
kTop,
kLeft,
kBottom,
kRight,
kCount
};
}
typedef WindowChromeSides::WindowChromeSide WindowChromeSide_t;
struct Window
{
Window();
@@ -84,6 +99,8 @@ struct Window
Point TopLeftCoord() const;
bool AddWidget(PortabilityLayer::Widget *widget);
ArrayView<PortabilityLayer::Widget*> GetWidgets() const;
PortabilityLayer::Widget* GetWidgetById() const;
void FocusWidget(PortabilityLayer::Widget *widget);
PortabilityLayer::Widget *GetWidgetWithFocus() const;
@@ -93,7 +110,7 @@ struct Window
void OnTick();
ArrayView<PortabilityLayer::Widget*> GetWidgets() const;
DrawSurface *GetChromeSurface(WindowChromeSide_t aChromeSide) const;
DrawSurface m_surface; // Must be the first item until the immediate mode draw API is completely removed
@@ -105,6 +122,8 @@ struct Window
protected:
~Window();
DrawSurface m_chromeSurfaces[WindowChromeSides::kCount];
PortabilityLayer::Widget **m_widgets;
size_t m_numWidgets;
size_t m_numTickReceivingWidgets;
@@ -225,9 +244,6 @@ void InitCursor();
CursHandle GetCursor(int cursorID);
void HideCursor();
void SetCursor(CursPtr cursor);
void SetBuiltinCursor(int builtinCursor);
void Delay(int ticks, UInt32 *endTickCount);
short FindWindow(Point point, WindowPtr *window); // Translates global coordinates to window coordinates, returns a region ID
@@ -243,8 +259,8 @@ void DisposeWindow(WindowPtr window);
void GetWindowBounds(WindowPtr window, WindowRegionType windowRegion, Rect *rect);
WindowPtr GetNewCWindow(int resID, void *storage, WindowPtr behind);
WindowPtr NewCWindow(void *storage, const Rect *bounds, const PLPasStr &title, Boolean visible, int wdef, WindowPtr behind, Boolean hasCloseBox, long userdata);
WindowPtr NewWindow(void *storage, const Rect *bounds, const PLPasStr &title, Boolean visible, int wdef, WindowPtr behind, Boolean hasCloseBox, long userdata);
WindowPtr NewCWindow(void *storage, const Rect *bounds, const PLPasStr &title, Boolean visible, int wdef, WindowPtr behind, long userdata);
WindowPtr NewWindow(void *storage, const Rect *bounds, const PLPasStr &title, Boolean visible, int wdef, WindowPtr behind, long userdata);
void SizeWindow(WindowPtr window, int width, int height, Boolean addToUpdateRegion);
void MoveWindow(WindowPtr window, int x, int y, Boolean moveToFront);
void ShowWindow(WindowPtr window);
@@ -288,7 +304,6 @@ void InvalWindowRect(WindowPtr window, const Rect *rect);
Handle NewHandle(Size size);
long GetHandleSize(Handle handle);
PLError_t PtrAndHand(const void *data, Handle handle, Size size); // Appends data to the end of a handle
PLError_t SetHandleSize(Handle hdl, Size newSize);
void *NewPtr(Size size);

View File

@@ -1,5 +1,11 @@
#include "PLPopupMenuWidget.h"
#include "MenuManager.h"
#include "PLMenus.h"
#include "PLPasStr.h"
#include "PLStandardColors.h"
#include "FontFamily.h"
namespace PortabilityLayer
{
PopupMenuWidget::PopupMenuWidget(const WidgetBasicState &state)
@@ -9,6 +15,53 @@ namespace PortabilityLayer
bool PopupMenuWidget::Init(const WidgetBasicState &state)
{
m_menu = GetMenu(state.m_resID);
if (!m_menu)
return false;
return true;
}
//WidgetHandleState_t PopupMenuWidget::ProcessEvent(const TimeTaggedVOSEvent &evt);
//int16_t PopupMenuWidget::Capture(const Point &pos, WidgetUpdateCallback_t callback);
void PopupMenuWidget::DrawControl(DrawSurface *surface)
{
const Rect rect = m_rect;
const Rect innerRect = rect.Inset(2, 2);
surface->SetForeColor(StdColors::White());
surface->FillRect(m_rect.Inset(1, 1));
surface->SetForeColor(StdColors::Black());
surface->FrameRect(m_rect);
Rect textRect = innerRect;
textRect.right -= 9;
surface->SetSystemFont(12, PortabilityLayer::FontFamilyFlag_Bold);
Point basePoint = Point::Create(textRect.left + 2, (textRect.top + textRect.bottom + surface->MeasureFontAscender() + 1) / 2);
surface->DrawStringConstrained(basePoint, GetString(), true, textRect);
Point arrowMidPoint = Point::Create(textRect.right + 5, (textRect.top + textRect.bottom + 1) / 2);
const Rect arrowRects[3] =
{
Rect::Create(arrowMidPoint.v - 1, arrowMidPoint.h - 2, arrowMidPoint.v, arrowMidPoint.h + 3),
Rect::Create(arrowMidPoint.v, arrowMidPoint.h - 1, arrowMidPoint.v + 1, arrowMidPoint.h + 2),
Rect::Create(arrowMidPoint.v + 1, arrowMidPoint.h, arrowMidPoint.v + 2, arrowMidPoint.h + 1)
};
for (int i = 0; i < 3; i++)
{
const Rect constrainedRect = innerRect.Intersect(arrowRects[i]);
surface->FillRect(constrainedRect);
}
}
PLPasStr PopupMenuWidget::GetString() const
{
const Menu *menu = (*m_menu);
return PortabilityLayer::MenuManager::GetInstance()->GetItemText(m_menu, m_state - 1);
}
}

View File

@@ -3,6 +3,8 @@
#include "PascalStr.h"
#include "PLWidgets.h"
struct Menu;
namespace PortabilityLayer
{
class PopupMenuWidget final : public WidgetSpec<PopupMenuWidget>
@@ -11,5 +13,14 @@ namespace PortabilityLayer
explicit PopupMenuWidget(const WidgetBasicState &state);
bool Init(const WidgetBasicState &state) override;
//WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt);
//int16_t Capture(const Point &pos, WidgetUpdateCallback_t callback);
void DrawControl(DrawSurface *surface) override;
PLPasStr GetString() const override;
private:
THandle<Menu> m_menu;
};
}

View File

@@ -998,7 +998,61 @@ void DrawSurface::FillRect(const Rect &rect)
void DrawSurface::FillRectWithPattern8x8(const Rect &rect, const uint8_t *pattern)
{
PL_NotYetImplemented_TODO("FillWithPattern");
if (!rect.IsValid())
return;
PortabilityLayer::QDPort *qdPort = &m_port;
GpPixelFormat_t pixelFormat = qdPort->GetPixelFormat();
Rect constrainedRect = rect;
const Rect portRect = qdPort->GetRect();
PortabilityLayer::QDState *qdState = qdPort->GetState();
constrainedRect = constrainedRect.Intersect(qdState->m_clipRect);
constrainedRect = constrainedRect.Intersect(qdPort->GetRect());
if (!constrainedRect.IsValid())
return;
assert(portRect.left == 0 && portRect.top == 0);
PortabilityLayer::PixMapImpl *pixMap = static_cast<PortabilityLayer::PixMapImpl*>(*qdPort->GetPixMap());
const size_t pitch = pixMap->GetPitch();
const size_t firstIndex = static_cast<size_t>(constrainedRect.top) * pitch + static_cast<size_t>(constrainedRect.left);
const size_t numLines = static_cast<size_t>(constrainedRect.bottom - constrainedRect.top);
const size_t numCols = static_cast<size_t>(constrainedRect.right - constrainedRect.left);
uint8_t *pixData = static_cast<uint8_t*>(pixMap->GetPixelData());
const int patternFirstRow = (constrainedRect.top & 7);
const int patternFirstCol = (constrainedRect.left & 7);
switch (pixelFormat)
{
case GpPixelFormats::k8BitStandard:
{
const uint8_t color = qdState->ResolveForeColor8(nullptr, 0);
size_t scanlineIndex = 0;
for (size_t ln = 0; ln < numLines; ln++)
{
const int patternRow = static_cast<int>((patternFirstRow + ln) & 7);
const size_t firstLineIndex = firstIndex + ln * pitch;
for (size_t col = 0; col < numCols; col++)
{
const int patternCol = static_cast<int>((patternFirstCol + col) & 7);
if ((pattern[patternRow] >> patternCol) & 1)
pixData[firstLineIndex + col] = color;
}
}
}
break;
default:
PL_NotYetImplemented();
return;
}
m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents);
}
@@ -1238,11 +1292,6 @@ void DrawSurface::DrawLine(const Point &a, const Point &b)
PlotLine(m_port.GetState(), this, PortabilityLayer::Vec2i(a.h, a.v), PortabilityLayer::Vec2i(b.h, b.v));
}
void DrawSurface::InvertDrawLine(const Point &a, const Point &b, const uint8_t *pattern)
{
PL_NotYetImplemented();
}
void GetClip(Rect *rect)
{
PortabilityLayer::QDState *qdState = PortabilityLayer::QDManager::GetInstance()->GetState();
@@ -1301,12 +1350,81 @@ void DrawSurface::FrameRoundRect(const Rect &rect, int quadrantWidth, int quadra
void DrawSurface::InvertFrameRect(const Rect &rect, const uint8_t *pattern)
{
PL_NotYetImplemented();
if (!rect.IsValid())
return;
if (rect.Width() <= 2 || rect.Height() <= 2)
{
InvertFillRect(rect, pattern);
return;
}
else
{
InvertFillRect(Rect::Create(rect.top, rect.left, rect.top + 1, rect.right), pattern);
InvertFillRect(Rect::Create(rect.top + 1, rect.left, rect.bottom - 1, rect.left + 1), pattern);
InvertFillRect(Rect::Create(rect.bottom - 1, rect.left, rect.bottom + 1, rect.right), pattern);
InvertFillRect(Rect::Create(rect.top + 1, rect.right - 1, rect.bottom - 1, rect.right), pattern);
}
}
void DrawSurface::InvertFillRect(const Rect &rect, const uint8_t *pattern)
{
PL_NotYetImplemented_TODO("InvertFillRect");
if (!rect.IsValid())
return;
PortabilityLayer::QDPort *qdPort = &m_port;
GpPixelFormat_t pixelFormat = qdPort->GetPixelFormat();
Rect constrainedRect = rect;
const Rect portRect = qdPort->GetRect();
PortabilityLayer::QDState *qdState = qdPort->GetState();
constrainedRect = constrainedRect.Intersect(qdState->m_clipRect);
constrainedRect = constrainedRect.Intersect(qdPort->GetRect());
if (!constrainedRect.IsValid())
return;
assert(portRect.left == 0 && portRect.top == 0);
PortabilityLayer::PixMapImpl *pixMap = static_cast<PortabilityLayer::PixMapImpl*>(*qdPort->GetPixMap());
const size_t pitch = pixMap->GetPitch();
const size_t firstIndex = static_cast<size_t>(constrainedRect.top) * pitch + static_cast<size_t>(constrainedRect.left);
const size_t numLines = static_cast<size_t>(constrainedRect.bottom - constrainedRect.top);
const size_t numCols = static_cast<size_t>(constrainedRect.right - constrainedRect.left);
uint8_t *pixData = static_cast<uint8_t*>(pixMap->GetPixelData());
const int patternFirstRow = (constrainedRect.top & 7);
const int patternFirstCol = (constrainedRect.left & 7);
switch (pixelFormat)
{
case GpPixelFormats::k8BitStandard:
{
const uint8_t color = qdState->ResolveForeColor8(nullptr, 0);
size_t scanlineIndex = 0;
for (size_t ln = 0; ln < numLines; ln++)
{
const int patternRow = static_cast<int>((patternFirstRow + ln) & 7);
const size_t firstLineIndex = firstIndex + ln * pitch;
for (size_t col = 0; col < numCols; col++)
{
const int patternCol = static_cast<int>((patternFirstCol + col) & 7);
if ((pattern[patternRow] >> patternCol) & 1)
pixData[firstLineIndex + col] = 255 - pixData[firstLineIndex + col];
}
}
}
break;
default:
PL_NotYetImplemented();
return;
}
m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents);
}
void DrawSurface::SetForeColor(const PortabilityLayer::RGBAColor &color)
@@ -1617,6 +1735,63 @@ void CopyMaskConstrained(const BitMap *srcBitmap, const BitMap *maskBitmap, BitM
CopyBitsComplete(srcBitmap, maskBitmap, destBitmap, srcRectBase, maskRectBase, destRectBase, constrainRect);
}
// This doesn't bounds-check the source (because it's only used in one place)
void ImageInvert(const PixMap *invertMask, PixMap *targetBitmap, const Rect &srcRect, const Rect &destRect)
{
assert(srcRect.Width() == destRect.Width());
assert(srcRect.Height() == destRect.Height());
assert(invertMask->m_pixelFormat == GpPixelFormats::kBW1);
const Rect invertBitmapRect = invertMask->m_rect;
const Rect targetBitmapRect = targetBitmap->m_rect;
const Rect constrainedDestRect = targetBitmapRect.Intersect(destRect);
if (!constrainedDestRect.IsValid())
return;
const int32_t leftInset = constrainedDestRect.left - destRect.left;
const int32_t topInset = constrainedDestRect.top - destRect.top;
const int32_t rightInset = destRect.right - constrainedDestRect.right;
const int32_t bottomInset = destRect.bottom - constrainedDestRect.bottom;
const int32_t firstSrcRow = srcRect.top - invertBitmapRect.top + topInset;
const int32_t firstSrcCol = srcRect.left - invertBitmapRect.left + leftInset;
const int32_t firstDestRow = destRect.top - targetBitmapRect.top + topInset;
const int32_t firstDestCol = destRect.left - targetBitmapRect.left + leftInset;
const uint16_t numRows = destRect.Height();
const uint16_t numCols = destRect.Width();
const size_t invertPitch = invertMask->m_pitch;
const uint8_t *invertPixelDataFirstRow = static_cast<const uint8_t*>(invertMask->m_data) + firstSrcRow * invertPitch;
const size_t targetPitch = targetBitmap->m_pitch;
uint8_t *targetPixelDataFirstRow = static_cast<uint8_t*>(targetBitmap->m_data) + firstDestRow * targetPitch;
const GpPixelFormat_t targetPixelFormat = targetBitmap->m_pixelFormat;
for (uint16_t r = 0; r < numRows; r++)
{
const uint8_t *invertRowStart = invertPixelDataFirstRow + r * invertPitch;
uint8_t *targetRowStart = targetPixelDataFirstRow + r * targetPitch;
switch (targetPixelFormat)
{
case GpPixelFormats::k8BitStandard:
for (uint16_t c = 0; c < numCols; c++)
{
const int32_t srcCol = c + firstSrcCol;
const int32_t destCol = c + firstDestCol;
if (invertRowStart[srcCol] != 0)
targetRowStart[destCol] = 255 - targetRowStart[destCol];
}
break;
default:
PL_NotYetImplemented();
break;
}
}
}
bool PointInScanlineMask(Point point, PortabilityLayer::ScanlineMask *scanlineMask)
{
@@ -1629,7 +1804,7 @@ void CopyMask(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBit
CopyBitsComplete(srcBitmap, maskBitmap, destBitmap, srcRectBase, maskRectBase, destRectBase, nullptr);
}
BitMap *GetPortBitMapForCopyBits(DrawSurface *grafPtr)
PixMap *GetPortBitMapForCopyBits(DrawSurface *grafPtr)
{
return *grafPtr->m_port.GetPixMap();
}

View File

@@ -133,9 +133,11 @@ void CopyBitsConstrained(const BitMap *srcBitmap, BitMap *destBitmap, const Rect
void CopyMask(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBitmap, const Rect *srcRect, const Rect *maskRect, const Rect *destRect);
void CopyMaskConstrained(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBitmap, const Rect *srcRectBase, const Rect *maskRectBase, const Rect *destRectBase, const Rect *constraintRect);
void ImageInvert(const PixMap *invertMask, PixMap *targetBitmap, const Rect &srcRect, const Rect &destRect);
bool PointInScanlineMask(Point point, PortabilityLayer::ScanlineMask *scanlineMask);
BitMap *GetPortBitMapForCopyBits(DrawSurface *grafPtr);
PixMap *GetPortBitMapForCopyBits(DrawSurface *grafPtr);
DrawSurface *GetWindowPort(WindowPtr window);
// Computes A - B and returns it packed?

View File

@@ -281,32 +281,41 @@ namespace PortabilityLayer
return GetResource(resTypeID, id, true);
}
bool ResourceArchive::GetResourceSize(const ResTypeID &resTypeID, int id, size_t &outSize)
bool ResourceArchive::GetResourceSize(const ResTypeID &resTypeID, int id, size_t &outSize) const
{
THandle<void> hdl = GetResource(resTypeID, id, false);
if (const PortabilityLayer::MMHandleBlock *hdlBlock = hdl.MMBlock())
{
outSize = hdlBlock->m_rmSelfRef->m_size;
size_t index = 0;
int validationRule = 0;
if (!IndexResource(resTypeID, id, index, validationRule))
return false;
outSize = m_zipFileProxy->GetFileSize(index);
return true;
}
return false;
bool ResourceArchive::HasAnyResourcesOfType(const ResTypeID &resTypeID) const
{
char resPrefix[6];
resTypeID.ExportAsChars(resPrefix);
resPrefix[4] = '/';
resPrefix[5] = '\0';
return m_zipFileProxy->HasPrefix(resPrefix);
}
THandle<void> ResourceArchive::GetResource(const ResTypeID &resTypeID, int id, bool load)
bool ResourceArchive::IndexResource(const ResTypeID &resTypeID, int id, size_t &outIndex, int &outValidationRule) const
{
const char *extension = ".bin";
ResourceValidationRule_t validationRule = ResourceValidationRules::kNone;
outValidationRule = ResourceValidationRules::kNone;
if (resTypeID == ResTypeID('snd '))
{
extension = ".wav";
validationRule = ResourceValidationRules::kWAV;
outValidationRule = ResourceValidationRules::kWAV;
}
else if (resTypeID == ResTypeID('Date') || resTypeID == ResTypeID('PICT'))
{
extension = ".bmp";
validationRule = ResourceValidationRules::kBMP;
outValidationRule = ResourceValidationRules::kBMP;
}
else if (resTypeID == ResTypeID('STR#'))
extension = ".txt";
@@ -320,7 +329,14 @@ namespace PortabilityLayer
snprintf(resourceFile, sizeof(resourceFile) - 1, "%s/%i%s", resTag.m_id, id, extension);
size_t index = 0;
if (!m_zipFileProxy->IndexFile(resourceFile, index))
return m_zipFileProxy->IndexFile(resourceFile, outIndex);
}
THandle<void> ResourceArchive::GetResource(const ResTypeID &resTypeID, int id, bool load)
{
int validationRule = 0;
size_t index = 0;
if (!IndexResource(resTypeID, id, index, validationRule))
return THandle<void>();
ResourceArchiveRef *ref = m_resourceHandles + index;
@@ -348,7 +364,7 @@ namespace PortabilityLayer
handle->m_contents = contents;
handle->m_size = ref->m_size;
if (!m_zipFileProxy->LoadFile(index, contents) || (validationRule != ResourceValidationRules::kNone && !ValidateResource(contents, ref->m_size, validationRule)))
if (!m_zipFileProxy->LoadFile(index, contents) || (validationRule != ResourceValidationRules::kNone && !ValidateResource(contents, ref->m_size, static_cast<ResourceValidationRule_t>(validationRule))))
{
MemoryManager::GetInstance()->Release(contents);
handle->m_contents = nullptr;

View File

@@ -0,0 +1,49 @@
#pragma once
namespace PortabilityLayer
{
template<class T>
class UnalignedPtr
{
public:
UnalignedPtr();
explicit UnalignedPtr(const T *ref);
const T *GetRawPtr() const;
T Get() const;
private:
const T *m_ref;
};
template<class T>
UnalignedPtr<T>::UnalignedPtr()
: m_ref(nullptr)
{
}
template<class T>
UnalignedPtr<T>::UnalignedPtr(const T *ref)
: m_ref(ref)
{
}
}
#include <string.h>
namespace PortabilityLayer
{
template<class T>
const T *UnalignedPtr<T>::GetRawPtr() const
{
return m_ref;
}
template<class T>
T UnalignedPtr<T>::Get() const
{
T result;
memcpy(&result, m_ref, sizeof(T));
return result;
}
}

View File

@@ -22,6 +22,11 @@ namespace PortabilityLayer
return WidgetHandleStates::kIgnored;
}
int16_t Widget::Capture(const Point &pos, WidgetUpdateCallback_t callback)
{
return 0;
}
void Widget::DrawControl(DrawSurface *surface)
{
(void)surface;
@@ -107,6 +112,11 @@ namespace PortabilityLayer
return PSTR("");
}
uint32_t Widget::GetReferenceConstant() const
{
return m_referenceConstant;
}
const Rect &Widget::GetRect() const
{
return m_rect;
@@ -121,6 +131,7 @@ namespace PortabilityLayer
: m_rect(state.m_rect)
, m_window(state.m_window)
, m_enabled(state.m_enabled)
, m_referenceConstant(state.m_refConstant)
, m_state(state.m_state)
, m_visible(true)
{

View File

@@ -10,6 +10,8 @@ struct Window;
namespace PortabilityLayer
{
class Widget;
namespace WidgetHandleStates
{
enum WidgetHandleState
@@ -23,6 +25,8 @@ namespace PortabilityLayer
typedef WidgetHandleStates::WidgetHandleState WidgetHandleState_t;
typedef void (*WidgetUpdateCallback_t)(Widget *control, int part);
struct WidgetBasicState
{
WidgetBasicState();
@@ -44,6 +48,7 @@ namespace PortabilityLayer
virtual bool Init(const WidgetBasicState &state) = 0;
virtual void Destroy() = 0;
virtual WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt);
virtual int16_t Capture(const Point &pos, WidgetUpdateCallback_t callback);
virtual void DrawControl(DrawSurface *surface);
virtual void SetMin(int32_t v);
@@ -62,6 +67,8 @@ namespace PortabilityLayer
virtual void SetString(const PLPasStr &str);
virtual PLPasStr GetString() const;
uint32_t GetReferenceConstant() const;
virtual void SetHighlightStyle(int16_t style);
virtual bool HandlesTickEvents() const;
@@ -87,6 +94,7 @@ namespace PortabilityLayer
Window *m_window;
Rect m_rect;
uint32_t m_referenceConstant;
int16_t m_state;
bool m_enabled;
bool m_visible;

View File

@@ -226,6 +226,7 @@
<ClInclude Include="PLPopupMenuWidget.h" />
<ClInclude Include="PLRadioButtonWidget.h" />
<ClInclude Include="PLScrollBarWidget.h" />
<ClInclude Include="PLUnalignedPtr.h" />
<ClInclude Include="PLWidgets.h" />
<ClInclude Include="UTF8.h" />
<ClInclude Include="ZipFileProxy.h" />

View File

@@ -474,6 +474,9 @@
<ClInclude Include="UTF8.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PLUnalignedPtr.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="CFileStream.cpp">

View File

@@ -71,7 +71,6 @@ struct DrawSurface final
void FillScanlineMask(const PortabilityLayer::ScanlineMask *scanlineMask);
void DrawLine(const Point &a, const Point &b);
void InvertDrawLine(const Point &a, const Point &b, const uint8_t *pattern);
void SetForeColor(const PortabilityLayer::RGBAColor &color);
const PortabilityLayer::RGBAColor &GetForeColor() const;

View File

@@ -31,12 +31,16 @@ namespace PortabilityLayer
void Destroy();
THandle<void> LoadResource(const ResTypeID &resTypeID, int id);
bool GetResourceSize(const ResTypeID &resTypeID, int id, size_t &outSize);
bool GetResourceSize(const ResTypeID &resTypeID, int id, size_t &outSize) const;
bool HasAnyResourcesOfType(const ResTypeID &resTypeID) const;
private:
ResourceArchive(ZipFileProxy *zipFileProxy, IOStream *stream, ResourceArchiveRef *resourceHandles);
~ResourceArchive();
bool IndexResource(const ResTypeID &resTypeID, int id, size_t &outIndex, int &outValidationRule) const;
THandle<void> GetResource(const ResTypeID &resTypeID, int id, bool load);
ZipFileProxy *m_zipFileProxy;

View File

@@ -69,10 +69,12 @@ namespace PortabilityLayer
return false; // Unsupported window style
}
if (wdefPart1.m_hasCloseBox != 0)
styleFlags |= WindowStyleFlags::kCloseBox;
m_initialRect = wdefPart1.m_initialRect.ToRect();
m_styleFlags = styleFlags;
m_visibilityStatus = wdefPart1.m_visibilityStatus;
m_hasCloseBox = wdefPart1.m_hasCloseBox;
m_referenceConstant = wdefPart1.m_referenceConstant;
m_title[0] = wdefPart1.m_titleLength;
@@ -87,17 +89,16 @@ namespace PortabilityLayer
return true;
}
WindowDef WindowDef::Create(const Rect &initialRect, uint16_t styleFlags, bool isVisible, bool hasCloseBox, uint32_t refConstant, uint16_t positionSpec, const PLPasStr &title)
WindowDef WindowDef::Create(const Rect &initialRect, uint16_t styleFlags, bool isVisible, uint32_t refConstant, uint16_t positionSpec, const PLPasStr &title)
{
WindowDef wdef;
wdef.m_initialRect = initialRect;
wdef.m_styleFlags = styleFlags;
wdef.m_visibilityStatus = isVisible ? 1 : 0;
wdef.m_hasCloseBox = hasCloseBox ? 1 : 0;
wdef.m_referenceConstant = refConstant;
wdef.m_positionSpec = positionSpec;
const uint8_t titleLength = static_cast<uint8_t>(std::max<size_t>(255, title.Length()));
const uint8_t titleLength = static_cast<uint8_t>(std::min<size_t>(255, title.Length()));
wdef.m_title[0] = titleLength;
memcpy(wdef.m_title + 1, title.UChars(), titleLength);

View File

@@ -18,6 +18,7 @@ namespace PortabilityLayer
kResizable = 4,
kMiniBar = 8,
kAlert = 16,
kCloseBox = 32,
};
}
@@ -26,13 +27,12 @@ namespace PortabilityLayer
Rect m_initialRect;
uint16_t m_styleFlags;
uint16_t m_visibilityStatus;
uint16_t m_hasCloseBox;
uint32_t m_referenceConstant;
uint16_t m_positionSpec;
uint8_t m_title[256];
bool Deserialize(IOStream *stream);
static WindowDef Create(const Rect &initialRect, uint16_t styleFlags, bool isVisible, bool hasCloseBox, uint32_t refConstant, uint16_t positionSpec, const PLPasStr &title);
static WindowDef Create(const Rect &initialRect, uint16_t styleFlags, bool isVisible, uint32_t refConstant, uint16_t positionSpec, const PLPasStr &title);
};
}

View File

@@ -6,6 +6,8 @@
#include "IGpDisplayDriverSurface.h"
#include "PLCore.h"
#include "PLEventQueue.h"
#include "PLStandardColors.h"
#include "FontFamily.h"
#include "MemoryManager.h"
#include "MenuManager.h"
#include "QDGraf.h"
@@ -19,6 +21,53 @@ struct GDevice;
namespace PortabilityLayer
{
class CGrafImpl;
class WindowImpl;
struct WindowChromeTheme
{
virtual void GetChromePadding(const WindowImpl *window, uint16_t padding[WindowChromeSides::kCount]) const = 0;
virtual void RenderChrome(WindowImpl *window, DrawSurface *surface, WindowChromeSide_t chromeSide) const = 0;
};
template<class T>
struct WindowChromeThemeSingleton : public WindowChromeTheme
{
public:
static T *GetInstance();
private:
static T ms_instance;
};
class SimpleBoxChromeTheme final : public WindowChromeThemeSingleton<SimpleBoxChromeTheme>
{
public:
void GetChromePadding(const WindowImpl *window, uint16_t padding[WindowChromeSides::kCount]) const override;
void RenderChrome(WindowImpl *window, DrawSurface *surface, WindowChromeSide_t chromeSide) const override;
};
class GenericWindowChromeTheme final : public WindowChromeThemeSingleton<GenericWindowChromeTheme>
{
public:
void GetChromePadding(const WindowImpl *window, uint16_t padding[WindowChromeSides::kCount]) const override;
void RenderChrome(WindowImpl *window, DrawSurface *surface, WindowChromeSide_t chromeSide) const override;
private:
void RenderChromeTop(WindowImpl *window, DrawSurface *surface) const;
void RenderChromeLeft(WindowImpl *window, DrawSurface *surface) const;
void RenderChromeBottom(WindowImpl *window, DrawSurface *surface) const;
void RenderChromeRight(WindowImpl *window, DrawSurface *surface) const;
void RenderChromeTopMini(WindowImpl *window, DrawSurface *surface) const;
void RenderChromeLeftMini(WindowImpl *window, DrawSurface *surface) const;
void RenderChromeBottomMini(WindowImpl *window, DrawSurface *surface) const;
void RenderChromeRightMini(WindowImpl *window, DrawSurface *surface) const;
static const int kDarkGray = 85;
static const int kMidGray = 187;
static const int kLightGray = 221;
};
class WindowImpl final : public Window
{
@@ -38,11 +87,22 @@ namespace PortabilityLayer
bool IsVisible() const;
void SetVisible(bool visible);
void GetChromePadding(uint16_t padding[WindowChromeSides::kCount]) const;
void GetChromeDimensions(int width, int height, Rect dimensions[WindowChromeSides::kCount]) const;
bool IsBorderless() const;
uint16_t GetStyleFlags() const;
const PascalStr<255> &GetTitle() const;
private:
WindowImpl *m_windowAbove;
WindowImpl *m_windowBelow;
WindowChromeTheme *m_chromeTheme;
uint16_t m_styleFlags;
bool m_visible;
PascalStr<255> m_title;
};
class WindowManagerImpl final : public WindowManager
@@ -77,10 +137,272 @@ namespace PortabilityLayer
static uint8_t ms_putInFrontSentinel;
};
template<class T>
inline T *WindowChromeThemeSingleton<T>::GetInstance()
{
return &ms_instance;
}
template<class T>
T WindowChromeThemeSingleton<T>::ms_instance;
//---------------------------------------------------------------------------
void SimpleBoxChromeTheme::GetChromePadding(const WindowImpl *window, uint16_t padding[WindowChromeSides::kCount]) const
{
padding[WindowChromeSides::kTop] = 1;
padding[WindowChromeSides::kBottom] = 1;
padding[WindowChromeSides::kLeft] = 1;
padding[WindowChromeSides::kRight] = 1;
}
void SimpleBoxChromeTheme::RenderChrome(WindowImpl *window, DrawSurface *surface, WindowChromeSide_t chromeSide) const
{
surface->SetForeColor(StdColors::Black());
surface->FillRect((*surface->m_port.GetPixMap())->m_rect);
}
//---------------------------------------------------------------------------
void GenericWindowChromeTheme::GetChromePadding(const WindowImpl *window, uint16_t padding[WindowChromeSides::kCount]) const
{
if (window->GetStyleFlags() & WindowStyleFlags::kMiniBar)
{
padding[WindowChromeSides::kTop] = 13;
padding[WindowChromeSides::kBottom] = 1;
padding[WindowChromeSides::kLeft] = 1;
padding[WindowChromeSides::kRight] = 1;
//if (window->GetStyleFlags() & WindowStyleFlags::kResizable)
//{
// padding[WindowChromeSides::kBottom] = 16;
// padding[WindowChromeSides::kRight] = 16;
//}
}
else
{
padding[WindowChromeSides::kTop] = 22;
padding[WindowChromeSides::kBottom] = 6;
padding[WindowChromeSides::kLeft] = 6;
padding[WindowChromeSides::kRight] = 6;
//if (window->GetStyleFlags() & WindowStyleFlags::kResizable)
//{
// padding[WindowChromeSides::kBottom] = 21;
// padding[WindowChromeSides::kRight] = 21;
//}
}
}
void GenericWindowChromeTheme::RenderChrome(WindowImpl *window, DrawSurface *surface, WindowChromeSide_t chromeSide) const
{
if (window->GetStyleFlags() & WindowStyleFlags::kMiniBar)
{
switch (chromeSide)
{
case WindowChromeSides::kTop:
RenderChromeTopMini(window, surface);
break;
case WindowChromeSides::kLeft:
RenderChromeLeftMini(window, surface);
break;
case WindowChromeSides::kBottom:
RenderChromeBottomMini(window, surface);
break;
case WindowChromeSides::kRight:
RenderChromeRightMini(window, surface);
break;
default:
break;
}
}
else
{
switch (chromeSide)
{
case WindowChromeSides::kTop:
RenderChromeTop(window, surface);
break;
case WindowChromeSides::kLeft:
RenderChromeLeft(window, surface);
break;
case WindowChromeSides::kBottom:
RenderChromeBottom(window, surface);
break;
case WindowChromeSides::kRight:
RenderChromeRight(window, surface);
break;
default:
break;
}
}
}
void GenericWindowChromeTheme::RenderChromeTop(WindowImpl *window, DrawSurface *surface) const
{
const Rect rect = (*surface->m_port.GetPixMap())->m_rect;
surface->SetForeColor(PortabilityLayer::RGBAColor::Create(kMidGray, kMidGray, kMidGray, 255));
surface->FillRect(rect);
surface->SetForeColor(StdColors::Black());
surface->FillRect(Rect::Create(rect.top, rect.left, rect.top + 1, rect.right));
surface->FillRect(Rect::Create(rect.top, rect.left, rect.bottom, 1));
surface->FillRect(Rect::Create(rect.top, rect.right - 1, rect.bottom, rect.right));
surface->FillRect(Rect::Create(rect.bottom - 1, rect.left + 5, rect.bottom, rect.right - 5));
surface->SetForeColor(PortabilityLayer::RGBAColor::Create(kDarkGray, kDarkGray, kDarkGray, 255));
surface->FillRect(Rect::Create(rect.bottom - 2, rect.left + 4, rect.bottom - 1, rect.right - 5));
surface->FillRect(Rect::Create(rect.bottom - 2, rect.left + 4, rect.bottom, rect.left + 5));
surface->FillRect(Rect::Create(rect.top + 2, rect.right - 2, rect.bottom, rect.right - 1));
surface->SetForeColor(StdColors::White());
surface->FillRect(Rect::Create(rect.top + 1, rect.left + 1, rect.bottom, rect.left + 2));
surface->FillRect(Rect::Create(rect.top + 1, rect.left + 1, rect.top + 2, rect.right - 2));
surface->FillRect(Rect::Create(rect.bottom - 1, rect.right - 5, rect.bottom, rect.right - 4));
surface->SetForeColor(StdColors::Black());
surface->SetSystemFont(12, PortabilityLayer::FontFamilyFlags::FontFamilyFlag_Bold);
int32_t ascender = surface->MeasureFontAscender();
const PLPasStr titlePStr = window->GetTitle().ToShortStr();
size_t titleWidth = surface->MeasureString(titlePStr);
int32_t titleH = (rect.left + rect.right - static_cast<int32_t>(titleWidth) + 1) / 2;
int32_t titleV = (rect.top + rect.bottom + ascender + 1) / 2;
surface->DrawString(Point::Create(titleH, titleV), titlePStr, true);
}
void GenericWindowChromeTheme::RenderChromeLeft(WindowImpl *window, DrawSurface *surface) const
{
const Rect rect = (*surface->m_port.GetPixMap())->m_rect;
surface->SetForeColor(StdColors::Black());
surface->FillRect(Rect::Create(rect.top, rect.right - 6, rect.bottom, rect.right - 5));
surface->FillRect(Rect::Create(rect.top, rect.right - 1, rect.bottom, rect.right));
surface->SetForeColor(StdColors::White());
surface->FillRect(Rect::Create(rect.top, rect.right - 5, rect.bottom, rect.right - 4));
surface->SetForeColor(PortabilityLayer::RGBAColor::Create(kDarkGray, kDarkGray, kDarkGray, 255));
surface->FillRect(Rect::Create(rect.top, rect.right - 2, rect.bottom, rect.right - 1));
surface->SetForeColor(PortabilityLayer::RGBAColor::Create(kMidGray, kMidGray, kMidGray, 255));
surface->FillRect(Rect::Create(rect.top, rect.right - 4, rect.bottom, rect.right - 2));
}
void GenericWindowChromeTheme::RenderChromeBottom(WindowImpl *window, DrawSurface *surface) const
{
const Rect rect = (*surface->m_port.GetPixMap())->m_rect;
surface->SetForeColor(PortabilityLayer::RGBAColor::Create(kMidGray, kMidGray, kMidGray, 255));
surface->FillRect(Rect::Create(rect.top, rect.left + 1, rect.bottom - 1, rect.left + 5));
surface->FillRect(Rect::Create(rect.bottom - 4, rect.left + 5, rect.bottom - 2, rect.right - 4));
surface->FillRect(Rect::Create(rect.top, rect.right - 4, rect.bottom - 2, rect.right - 2));
surface->SetForeColor(StdColors::Black());
surface->FillRect(Rect::Create(rect.top, rect.left, rect.bottom, rect.left + 1));
surface->FillRect(Rect::Create(rect.bottom - 1, rect.left, rect.bottom, rect.right));
surface->FillRect(Rect::Create(rect.top, rect.right - 1, rect.bottom, rect.right));
surface->FillRect(Rect::Create(rect.top, rect.left + 5, rect.bottom - 5, rect.left + 6));
surface->FillRect(Rect::Create(rect.top, rect.right - 6, rect.bottom - 5, rect.right - 5));
surface->FillRect(Rect::Create(rect.bottom - 6, rect.left + 6, rect.bottom - 5, rect.right - 6));
surface->SetForeColor(StdColors::White());
surface->FillRect(Rect::Create(rect.top, rect.right - 5, rect.bottom - 5, rect.right - 4));
surface->FillRect(Rect::Create(rect.top, rect.left + 1, rect.bottom - 2, rect.left + 2));
surface->FillRect(Rect::Create(rect.bottom - 5, rect.left + 5, rect.bottom - 4, rect.right - 4));
surface->SetForeColor(PortabilityLayer::RGBAColor::Create(kDarkGray, kDarkGray, kDarkGray, 255));
surface->FillRect(Rect::Create(rect.bottom - 2, rect.left + 2, rect.bottom - 1, rect.right - 2));
surface->FillRect(Rect::Create(rect.top, rect.left + 4, rect.bottom - 5, rect.left + 5));
surface->FillRect(Rect::Create(rect.top, rect.right - 2, rect.bottom - 1, rect.right - 1));
}
void GenericWindowChromeTheme::RenderChromeRight(WindowImpl *window, DrawSurface *surface) const
{
const Rect rect = (*surface->m_port.GetPixMap())->m_rect;
surface->SetForeColor(StdColors::Black());
surface->FillRect(Rect::Create(rect.top, rect.right - 6, rect.bottom, rect.right - 5));
surface->FillRect(Rect::Create(rect.top, rect.right - 1, rect.bottom, rect.right));
surface->SetForeColor(StdColors::White());
surface->FillRect(Rect::Create(rect.top, rect.right - 5, rect.bottom, rect.right - 4));
surface->SetForeColor(PortabilityLayer::RGBAColor::Create(kDarkGray, kDarkGray, kDarkGray, 255));
surface->FillRect(Rect::Create(rect.top, rect.right - 2, rect.bottom, rect.right - 1));
surface->SetForeColor(PortabilityLayer::RGBAColor::Create(kMidGray, kMidGray, kMidGray, 255));
surface->FillRect(Rect::Create(rect.top, rect.right - 4, rect.bottom, rect.right - 2));
}
void GenericWindowChromeTheme::RenderChromeTopMini(WindowImpl *window, DrawSurface *surface) const
{
const Rect rect = (*surface->m_port.GetPixMap())->m_rect;
surface->SetForeColor(PortabilityLayer::RGBAColor::Create(kLightGray, kLightGray, kLightGray, 255));
surface->FillRect(rect);
surface->SetForeColor(StdColors::Black());
surface->FillRect(Rect::Create(rect.top, rect.left, rect.top + 1, rect.right));
surface->FillRect(Rect::Create(rect.top, rect.left, rect.bottom, 1));
surface->FillRect(Rect::Create(rect.top, rect.right - 1, rect.bottom, rect.right));
surface->FillRect(Rect::Create(rect.bottom - 1, rect.left + 1, rect.bottom, rect.right - 1));
surface->SetForeColor(PortabilityLayer::RGBAColor::Create(kDarkGray, kDarkGray, kDarkGray, 255));
surface->FillRect(Rect::Create(rect.bottom - 2, rect.left + 2, rect.bottom - 1, rect.right - 2));
surface->FillRect(Rect::Create(rect.top + 2, rect.right - 2, rect.bottom - 1, rect.right - 1));
surface->SetForeColor(StdColors::White());
surface->FillRect(Rect::Create(rect.top + 1, rect.left + 1, rect.bottom - 2, rect.left + 2));
surface->FillRect(Rect::Create(rect.top + 1, rect.left + 1, rect.top + 2, rect.right - 2));
surface->SetForeColor(StdColors::Black());
surface->SetApplicationFont(10, PortabilityLayer::FontFamilyFlags::FontFamilyFlag_Bold);
int32_t ascender = surface->MeasureFontAscender();
const PLPasStr titlePStr = window->GetTitle().ToShortStr();
size_t titleWidth = surface->MeasureString(titlePStr);
int32_t titleH = (rect.left + rect.right - static_cast<int32_t>(titleWidth) + 1) / 2;
int32_t titleV = (rect.top + rect.bottom + ascender + 1) / 2;
surface->DrawString(Point::Create(titleH, titleV), titlePStr, true);
}
void GenericWindowChromeTheme::RenderChromeLeftMini(WindowImpl *window, DrawSurface *surface) const
{
const Rect rect = (*surface->m_port.GetPixMap())->m_rect;
surface->SetForeColor(StdColors::Black());
surface->FillRect(rect);
}
void GenericWindowChromeTheme::RenderChromeBottomMini(WindowImpl *window, DrawSurface *surface) const
{
const Rect rect = (*surface->m_port.GetPixMap())->m_rect;
surface->SetForeColor(StdColors::Black());
surface->FillRect(rect);
}
void GenericWindowChromeTheme::RenderChromeRightMini(WindowImpl *window, DrawSurface *surface) const
{
const Rect rect = (*surface->m_port.GetPixMap())->m_rect;
surface->SetForeColor(StdColors::Black());
surface->FillRect(rect);
}
//---------------------------------------------------------------------------
WindowImpl::WindowImpl()
: m_windowAbove(nullptr)
, m_windowBelow(nullptr)
, m_chromeTheme(nullptr)
, m_visible(true)
, m_styleFlags(0)
{
}
@@ -96,13 +418,37 @@ namespace PortabilityLayer
if (!bounds.IsValid())
return false;
const Rect adjustedBounds = Rect::Create(0, 0, bounds.bottom - bounds.top, bounds.right - bounds.left);
m_styleFlags = windowDef.m_styleFlags;
const Rect adjustedBounds = Rect::Create(0, 0, bounds.Height(), bounds.Width());
GpPixelFormat_t pixelFormat = PortabilityLayer::DisplayDeviceManager::GetInstance()->GetPixelFormat();
if (int errorCode = m_surface.Init(adjustedBounds, pixelFormat))
return false;
m_title.Set(windowDef.m_title[0], reinterpret_cast<const char*>(windowDef.m_title + 1));
// Resolve chrome
if (!IsBorderless())
{
m_chromeTheme = SimpleBoxChromeTheme::GetInstance();
if (m_styleFlags & WindowStyleFlags::kTitleBar)
m_chromeTheme = GenericWindowChromeTheme::GetInstance();
Rect chromeBounds[WindowChromeSides::kCount];
GetChromeDimensions(bounds.Width(), bounds.Height(), chromeBounds);
for (int chromeSide = 0; chromeSide < WindowChromeSides::kCount; chromeSide++)
{
if (int errorCode = m_chromeSurfaces[chromeSide].Init(chromeBounds[chromeSide], pixelFormat))
return false;
m_chromeTheme->RenderChrome(this, m_chromeSurfaces + chromeSide, static_cast<WindowChromeSide_t>(chromeSide));
}
}
return true;
}
@@ -112,7 +458,26 @@ namespace PortabilityLayer
rect.right = rect.left + width;
rect.bottom = rect.top + height;
return m_surface.Resize(rect);
if (!m_surface.Resize(rect))
return false;
if (!IsBorderless())
{
Rect chromeDimensions[WindowChromeSides::kCount];
GetChromeDimensions(width, height, chromeDimensions);
bool resized = true;
for (int i = 0; i < WindowChromeSides::kCount; i++)
{
if (!m_chromeSurfaces[i].Resize(chromeDimensions[i]))
return false;
m_chromeTheme->RenderChrome(this, m_chromeSurfaces + i, static_cast<WindowChromeSide_t>(i));
}
}
return true;
}
WindowImpl *WindowImpl::GetWindowAbove() const
@@ -145,6 +510,40 @@ namespace PortabilityLayer
m_visible = visible;
}
void WindowImpl::GetChromePadding(uint16_t padding[WindowChromeSides::kCount]) const
{
return m_chromeTheme->GetChromePadding(this, padding);
}
void WindowImpl::GetChromeDimensions(int width, int height, Rect dimensions[WindowChromeSides::kCount]) const
{
uint16_t padding[WindowChromeSides::kCount];
GetChromePadding(padding);
int32_t topAndBottomWidth = width + padding[WindowChromeSides::kLeft] + padding[WindowChromeSides::kRight];
int32_t leftAndRightHeight = height;
dimensions[WindowChromeSides::kTop] = Rect::Create(0, 0, padding[WindowChromeSides::kTop], topAndBottomWidth);
dimensions[WindowChromeSides::kBottom] = Rect::Create(0, 0, padding[WindowChromeSides::kBottom], topAndBottomWidth);
dimensions[WindowChromeSides::kLeft] = Rect::Create(0, 0, leftAndRightHeight, padding[WindowChromeSides::kLeft]);
dimensions[WindowChromeSides::kRight] = Rect::Create(0, 0, leftAndRightHeight, padding[WindowChromeSides::kRight]);
}
bool WindowImpl::IsBorderless() const
{
return (m_styleFlags & WindowStyleFlags::kBorderless) != 0;
}
uint16_t WindowImpl::GetStyleFlags() const
{
return m_styleFlags;
}
const PascalStr<255> &WindowImpl::GetTitle() const
{
return m_title;
}
WindowManagerImpl::WindowManagerImpl()
: m_windowStackTop(nullptr)
, m_windowStackBottom(nullptr)
@@ -352,9 +751,37 @@ namespace PortabilityLayer
graf.PushToDDSurface(displayDriver);
const PixMap *pixMap = *graf.m_port.GetPixMap();
const size_t width = pixMap->m_rect.right - pixMap->m_rect.left;
const size_t height = pixMap->m_rect.bottom - pixMap->m_rect.top;
const uint16_t width = pixMap->m_rect.Width();
const uint16_t height = pixMap->m_rect.Height();
displayDriver->DrawSurface(graf.m_ddSurface, window->m_wmX, window->m_wmY, width, height);
if (!window->IsBorderless())
{
uint16_t chromePadding[WindowChromeSides::kCount];
window->GetChromePadding(chromePadding);
Vec2i chromeOrigins[WindowChromeSides::kCount];
chromeOrigins[WindowChromeSides::kTop] = Vec2i(window->m_wmX - chromePadding[WindowChromeSides::kLeft], window->m_wmY - chromePadding[WindowChromeSides::kTop]);
chromeOrigins[WindowChromeSides::kLeft] = Vec2i(window->m_wmX - chromePadding[WindowChromeSides::kLeft], window->m_wmY);
chromeOrigins[WindowChromeSides::kRight] = Vec2i(window->m_wmX + width, window->m_wmY);
chromeOrigins[WindowChromeSides::kBottom] = Vec2i(window->m_wmX - chromePadding[WindowChromeSides::kLeft], window->m_wmY + height);
Vec2i chromeDimensions[WindowChromeSides::kCount];
chromeDimensions[WindowChromeSides::kTop] = Vec2i(chromePadding[WindowChromeSides::kLeft] + chromePadding[WindowChromeSides::kRight] + width, chromePadding[WindowChromeSides::kTop]);
chromeDimensions[WindowChromeSides::kLeft] = Vec2i(chromePadding[WindowChromeSides::kLeft], height);
chromeDimensions[WindowChromeSides::kRight] = Vec2i(chromePadding[WindowChromeSides::kRight], height);
chromeDimensions[WindowChromeSides::kBottom] = Vec2i(chromePadding[WindowChromeSides::kLeft] + chromePadding[WindowChromeSides::kRight] + width, chromePadding[WindowChromeSides::kBottom]);
for (int i = 0; i < WindowChromeSides::kCount; i++)
{
DrawSurface *chromeSurface = window->GetChromeSurface(static_cast<WindowChromeSide_t>(i));
chromeSurface->PushToDDSurface(displayDriver);
displayDriver->DrawSurface(chromeSurface->m_ddSurface, chromeOrigins[i].m_x, chromeOrigins[i].m_y, chromeDimensions[i].m_x, chromeDimensions[i].m_y);
}
}
}
WindowManagerImpl *WindowManagerImpl::GetInstance()

View File

@@ -7,14 +7,18 @@
#include "DeflateCodec.h"
#include <algorithm>
namespace
{
static int ZipDirectorySearchPredicate(const char *path, PortabilityLayer::ZipCentralDirectoryFileHeader *item)
static const char *GetZipItemName(const PortabilityLayer::UnalignedPtr<PortabilityLayer::ZipCentralDirectoryFileHeader> &itemPtr)
{
const uint16_t fnameLength = item->m_fileNameLength;
const char *itemPath = reinterpret_cast<const char*>(item) + sizeof(PortabilityLayer::ZipCentralDirectoryFileHeader);
return reinterpret_cast<const char*>(itemPtr.GetRawPtr()) + sizeof(PortabilityLayer::ZipCentralDirectoryFileHeader);
}
for (size_t i = 0; i < fnameLength; i++)
static int ZipDirectorySearchPredicateResolved(const char *path, const char *itemPath, uint16_t itemPathLength)
{
for (size_t i = 0; i < itemPathLength; i++)
{
const uint8_t pathC = static_cast<uint8_t>(path[i] & 0xff);
@@ -29,12 +33,20 @@ namespace
return 1;
}
if (path[fnameLength] == 0)
if (path[itemPathLength] == 0)
return 0;
else
return 1;
}
static int ZipDirectorySearchPredicate(const char *path, const PortabilityLayer::UnalignedPtr<PortabilityLayer::ZipCentralDirectoryFileHeader> &itemPtr)
{
const uint16_t fnameLength = itemPtr.Get().m_fileNameLength;
const char *itemPath = GetZipItemName(itemPtr);
return ZipDirectorySearchPredicateResolved(path, itemPath, fnameLength);
}
static int ZipDirectorySortPredicate(const void *a, const void *b)
{
const PortabilityLayer::ZipCentralDirectoryFileHeader *typedA = *static_cast<PortabilityLayer::ZipCentralDirectoryFileHeader *const*>(a);
@@ -93,7 +105,7 @@ namespace PortabilityLayer
bool ZipFileProxy::IndexFile(const char *path, size_t &outIndex) const
{
PortabilityLayer::ZipCentralDirectoryFileHeader **indexLoc = BinarySearch(m_sortedFiles, m_sortedFiles + m_numFiles, path, ZipDirectorySearchPredicate);
UnalignedPtr<ZipCentralDirectoryFileHeader> *indexLoc = BinarySearch(m_sortedFiles, m_sortedFiles + m_numFiles, path, ZipDirectorySearchPredicate);
const size_t index = static_cast<size_t>(indexLoc - m_sortedFiles);
if (index == m_numFiles)
@@ -105,11 +117,57 @@ namespace PortabilityLayer
}
}
bool ZipFileProxy::HasPrefix(const char *prefix) const
{
size_t prefixLen = strlen(prefix);
size_t firstFile = 0;
size_t lastFileExclusive = m_numFiles;
size_t midFile = (firstFile + lastFileExclusive) / 2;
while (firstFile != lastFileExclusive)
{
const UnalignedPtr<PortabilityLayer::ZipCentralDirectoryFileHeader> itemPtr = m_sortedFiles[midFile];
const PortabilityLayer::ZipCentralDirectoryFileHeader item = itemPtr.Get();
const uint16_t itemNameLength = item.m_fileNameLength;
const char *itemPath = GetZipItemName(itemPtr);
const int delta = ZipDirectorySearchPredicateResolved(prefix, itemPath, itemNameLength);
// -1 = path precedes item, 1 = path succeeds item
if (delta < 0)
{
lastFileExclusive = midFile;
midFile = (firstFile + lastFileExclusive) / 2;
}
else if (delta > 0)
{
const bool isPathPrefix = ((itemNameLength > prefixLen) && !memcmp(prefix, itemPath, prefixLen));
if (isPathPrefix)
return true;
else
{
firstFile = midFile + 1;
midFile = (firstFile + lastFileExclusive) / 2;
}
}
else //if(delta == 0)
{
// Found the directory
firstFile = midFile + 1;
midFile = (firstFile + lastFileExclusive) / 2;
}
}
return false;
}
bool ZipFileProxy::LoadFile(size_t index, void *outBuffer)
{
ZipCentralDirectoryFileHeader *centralDirHeader = m_sortedFiles[index];
ZipCentralDirectoryFileHeader centralDirHeader = m_sortedFiles[index].Get();
if (!m_stream->SeekStart(centralDirHeader->m_localHeaderOffset))
if (!m_stream->SeekStart(centralDirHeader.m_localHeaderOffset))
return false;
ZipFileLocalHeader localHeader;
@@ -119,15 +177,15 @@ namespace PortabilityLayer
if (!m_stream->SeekCurrent(localHeader.m_fileNameLength + localHeader.m_extraFieldLength))
return false;
if (localHeader.m_compressedSize != centralDirHeader->m_compressedSize || localHeader.m_uncompressedSize != centralDirHeader->m_uncompressedSize || localHeader.m_method != centralDirHeader->m_method)
if (localHeader.m_compressedSize != centralDirHeader.m_compressedSize || localHeader.m_uncompressedSize != centralDirHeader.m_uncompressedSize || localHeader.m_method != centralDirHeader.m_method)
return false;
const size_t uncompressedSize = centralDirHeader->m_uncompressedSize;
const size_t uncompressedSize = centralDirHeader.m_uncompressedSize;
if (localHeader.m_method == PortabilityLayer::ZipConstants::kStoredMethod)
return m_stream->Read(outBuffer, uncompressedSize) == uncompressedSize;
else if (localHeader.m_method == PortabilityLayer::ZipConstants::kDeflatedMethod)
{
const size_t compressedSize = centralDirHeader->m_compressedSize;
const size_t compressedSize = centralDirHeader.m_compressedSize;
return DeflateCodec::DecompressStream(m_stream, compressedSize, outBuffer, uncompressedSize);
}
@@ -142,7 +200,7 @@ namespace PortabilityLayer
size_t ZipFileProxy::GetFileSize(size_t index) const
{
return m_sortedFiles[index]->m_uncompressedSize;
return m_sortedFiles[index].Get().m_uncompressedSize;
}
ZipFileProxy *ZipFileProxy::Create(IOStream *stream)
@@ -164,7 +222,7 @@ namespace PortabilityLayer
const size_t centralDirSize = eocd.m_centralDirectorySizeBytes;
void *centralDirImage = nullptr;
ZipCentralDirectoryFileHeader **centralDirFiles = nullptr;
UnalignedPtr<ZipCentralDirectoryFileHeader> *centralDirFiles = nullptr;
const size_t numFiles = eocd.m_numCentralDirRecords;
@@ -174,7 +232,7 @@ namespace PortabilityLayer
if (!centralDirImage)
return nullptr;
centralDirFiles = static_cast<ZipCentralDirectoryFileHeader **>(mm->Alloc(sizeof(ZipCentralDirectoryFileHeader*) * numFiles));
centralDirFiles = static_cast<UnalignedPtr<ZipCentralDirectoryFileHeader>*>(mm->Alloc(sizeof(UnalignedPtr<ZipCentralDirectoryFileHeader>) * numFiles));
if (!centralDirFiles)
{
mm->Release(centralDirImage);
@@ -203,46 +261,48 @@ namespace PortabilityLayer
break;
}
ZipCentralDirectoryFileHeader *centralDirHeader = reinterpret_cast<ZipCentralDirectoryFileHeader*>(centralDirCursor);
UnalignedPtr<ZipCentralDirectoryFileHeader> centralDirHeaderPtr = UnalignedPtr<ZipCentralDirectoryFileHeader>(reinterpret_cast<ZipCentralDirectoryFileHeader*>(centralDirCursor));
ZipCentralDirectoryFileHeader centralDirHeader = centralDirHeaderPtr.Get();
centralDirCursor += sizeof(ZipCentralDirectoryFileHeader);
if (centralDirHeader->m_signature != ZipCentralDirectoryFileHeader::kSignature)
if (centralDirHeader.m_signature != ZipCentralDirectoryFileHeader::kSignature)
{
failed = true;
break;
}
if (centralDirEnd - centralDirCursor < centralDirHeader->m_fileNameLength)
if (centralDirEnd - centralDirCursor < centralDirHeader.m_fileNameLength)
{
failed = true;
break;
}
if (!CheckAndFixFileName(centralDirCursor, centralDirHeader->m_fileNameLength))
if (!CheckAndFixFileName(centralDirCursor, centralDirHeader.m_fileNameLength))
{
failed = true;
break;
}
centralDirCursor += centralDirHeader->m_fileNameLength;
centralDirCursor += centralDirHeader.m_fileNameLength;
if (centralDirEnd - centralDirCursor < centralDirHeader->m_extraFieldLength)
if (centralDirEnd - centralDirCursor < centralDirHeader.m_extraFieldLength)
{
failed = true;
break;
}
centralDirCursor += centralDirHeader->m_extraFieldLength;
centralDirCursor += centralDirHeader.m_extraFieldLength;
if (centralDirEnd - centralDirCursor < centralDirHeader->m_commentLength)
if (centralDirEnd - centralDirCursor < centralDirHeader.m_commentLength)
{
failed = true;
break;
}
centralDirCursor += centralDirHeader->m_commentLength;
centralDirCursor += centralDirHeader.m_commentLength;
centralDirFiles[i] = centralDirHeader;
centralDirFiles[i] = centralDirHeaderPtr;
}
if (failed)
@@ -277,7 +337,7 @@ namespace PortabilityLayer
return new (storage) ZipFileProxy(stream, centralDirImage, centralDirFiles, numFiles);
}
ZipFileProxy::ZipFileProxy(IOStream *stream, void *centralDirImage, ZipCentralDirectoryFileHeader **sortedFiles, size_t numFiles)
ZipFileProxy::ZipFileProxy(IOStream *stream, void *centralDirImage, UnalignedPtr<ZipCentralDirectoryFileHeader> *sortedFiles, size_t numFiles)
: m_stream(stream)
, m_centralDirImage(centralDirImage)
, m_sortedFiles(sortedFiles)

View File

@@ -1,5 +1,7 @@
#pragma once
#include "PLUnalignedPtr.h"
namespace PortabilityLayer
{
class IOStream;
@@ -13,18 +15,20 @@ namespace PortabilityLayer
bool IndexFile(const char *path, size_t &outIndex) const;
bool LoadFile(size_t index, void *outBuffer);
bool HasPrefix(const char *path) const;
size_t NumFiles() const;
size_t GetFileSize(size_t index) const;
static ZipFileProxy *Create(IOStream *stream);
private:
ZipFileProxy(IOStream *stream, void *centralDirImage, ZipCentralDirectoryFileHeader **sortedFiles, size_t numFiles);
ZipFileProxy(IOStream *stream, void *centralDirImage, UnalignedPtr<ZipCentralDirectoryFileHeader> *sortedFiles, size_t numFiles);
~ZipFileProxy();
IOStream *m_stream;
void *m_centralDirImage;
ZipCentralDirectoryFileHeader **m_sortedFiles;
UnalignedPtr<ZipCentralDirectoryFileHeader> *m_sortedFiles;
size_t m_numFiles;
};
}