mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-09-23 06:53:43 +00:00
Compare commits
32 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
3c5dd5f562 | ||
|
5bb6b074f0 | ||
|
ea217285c0 | ||
|
cd4e0ae8de | ||
|
c357ca2b7c | ||
|
b5a3db860f | ||
|
69e3fb3023 | ||
|
94f26d0be1 | ||
|
d893b356f1 | ||
|
c3f3fb4621 | ||
|
0335dd7786 | ||
|
ffd9d9cc1f | ||
|
f46ae55d62 | ||
|
5c1aacc268 | ||
|
d7353ff6ed | ||
|
b827048c36 | ||
|
f56d879d12 | ||
|
1269294d28 | ||
|
643bc7b761 | ||
|
2f663646f5 | ||
|
f4a57dba6e | ||
|
7404c60a96 | ||
|
805638f2c9 | ||
|
59e9a9480e | ||
|
49d1d6124a | ||
|
129396ef53 | ||
|
1cdd372e35 | ||
|
9a4f3f0e67 | ||
|
db89bf178c | ||
|
793822fbb4 | ||
|
66a709ad2a | ||
|
6326a0b2d9 |
@@ -94,6 +94,11 @@ void GpAppEnvironment::Render()
|
||||
GpAppInterface_Get()->PL_Render(m_displayDriver);
|
||||
}
|
||||
|
||||
bool GpAppEnvironment::AdjustRequestedResolution(uint32_t &physicalWidth, uint32_t &physicalHeight, uint32_t &virtualWidth, uint32_t &virtualheight, float &pixelScaleX, float &pixelScaleY)
|
||||
{
|
||||
return GpAppInterface_Get()->PL_AdjustRequestedResolution(physicalWidth, physicalHeight, virtualWidth, virtualheight, pixelScaleX, pixelScaleY);
|
||||
}
|
||||
|
||||
void GpAppEnvironment::SetDisplayDriver(IGpDisplayDriver *displayDriver)
|
||||
{
|
||||
m_displayDriver = displayDriver;
|
||||
@@ -170,6 +175,10 @@ void GpAppEnvironment::DispatchSystemCall(PortabilityLayer::HostSuspendCallID ca
|
||||
m_applicationState = ApplicationState_TimedSuspend;
|
||||
m_delaySuspendTicks = args[0].m_uint;
|
||||
break;
|
||||
case PortabilityLayer::HostSuspendCallID_CallOnVOSThread:
|
||||
args[0].m_functionPtr(static_cast<const PortabilityLayer::HostSuspendCallArgument*>(args[1].m_constPointer), static_cast<PortabilityLayer::HostSuspendCallArgument*>(args[2].m_pointer));
|
||||
m_applicationState = ApplicationState_Running;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
@@ -28,6 +28,7 @@ public:
|
||||
|
||||
GpDisplayDriverTickStatus_t Tick(IGpFiber *vosFiber);
|
||||
void Render();
|
||||
bool AdjustRequestedResolution(uint32_t &physicalWidth, uint32_t &physicalHeight, uint32_t &virtualWidth, uint32_t &virtualheight, float &pixelScaleX, float &pixelScaleY);
|
||||
|
||||
void SetDisplayDriver(IGpDisplayDriver *displayDriver);
|
||||
void SetAudioDriver(IGpAudioDriver *audioDriver);
|
||||
|
@@ -13,6 +13,8 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
extern GpWindowsGlobals g_gpWindowsGlobals;
|
||||
|
||||
class GpDirectoryCursor_Win32 final : public PortabilityLayer::HostDirectoryCursor
|
||||
{
|
||||
public:
|
||||
@@ -307,6 +309,7 @@ bool GpFileSystem_Win32::PromptSaveFile(PortabilityLayer::VirtualDirectory_t vir
|
||||
ofn.nMaxFile = MAX_PATH;
|
||||
ofn.lpstrInitialDir = baseDir;
|
||||
ofn.Flags = OFN_EXPLORER | OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT;
|
||||
ofn.hwndOwner = g_gpWindowsGlobals.m_hwnd;
|
||||
|
||||
if (!GetSaveFileNameW(&ofn))
|
||||
return false;
|
||||
@@ -387,6 +390,7 @@ bool GpFileSystem_Win32::PromptOpenFile(PortabilityLayer::VirtualDirectory_t vir
|
||||
ofn.nMaxFile = MAX_PATH;
|
||||
ofn.lpstrInitialDir = baseDir;
|
||||
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST;
|
||||
ofn.hwndOwner = g_gpWindowsGlobals.m_hwnd;
|
||||
|
||||
if (!GetOpenFileNameW(&ofn))
|
||||
return false;
|
||||
|
@@ -27,6 +27,11 @@ namespace
|
||||
{
|
||||
static_cast<GpAppEnvironment*>(context)->Render();
|
||||
}
|
||||
|
||||
bool AdjustRequestedResolution(void *context, uint32_t &physicalWidth, uint32_t &physicalHeight, uint32_t &virtualWidth, uint32_t &virtualheight, float &pixelScaleX, float &pixelScaleY)
|
||||
{
|
||||
return static_cast<GpAppEnvironment*>(context)->AdjustRequestedResolution(physicalWidth, physicalHeight, virtualWidth, virtualheight, pixelScaleX, pixelScaleY);
|
||||
}
|
||||
}
|
||||
|
||||
int GpMain::Run()
|
||||
@@ -52,6 +57,9 @@ int GpMain::Run()
|
||||
ddProps.m_renderFunc = RenderAppEnvironment;
|
||||
ddProps.m_renderFuncContext = appEnvironment;
|
||||
|
||||
ddProps.m_adjustRequestedResolutionFunc = AdjustRequestedResolution;
|
||||
ddProps.m_adjustRequestedResolutionFuncContext = appEnvironment;
|
||||
|
||||
ddProps.m_type = g_gpGlobalConfig.m_displayDriverType;
|
||||
ddProps.m_osGlobals = g_gpGlobalConfig.m_osGlobals;
|
||||
ddProps.m_eventQueue = eventQueue;
|
||||
|
@@ -24,7 +24,7 @@ extern "C" __declspec(dllimport) IGpAudioDriver *GpDriver_CreateAudioDriver_XAud
|
||||
extern "C" __declspec(dllimport) IGpDisplayDriver *GpDriver_CreateDisplayDriver_D3D11(const GpDisplayDriverProperties &properties);
|
||||
extern "C" __declspec(dllimport) IGpInputDriver *GpDriver_CreateInputDriver_XInput(const GpInputDriverProperties &properties);
|
||||
|
||||
static void PostMouseEvent(IGpVOSEventQueue *eventQueue, GpMouseEventType_t eventType, GpMouseButton_t button, int32_t x, int32_t y)
|
||||
static void PostMouseEvent(IGpVOSEventQueue *eventQueue, GpMouseEventType_t eventType, GpMouseButton_t button, int32_t x, int32_t y, float pixelScaleX, float pixelScaleY)
|
||||
{
|
||||
if (GpVOSEvent *evt = eventQueue->QueueEvent())
|
||||
{
|
||||
@@ -35,6 +35,12 @@ static void PostMouseEvent(IGpVOSEventQueue *eventQueue, GpMouseEventType_t even
|
||||
mEvent.m_x = x;
|
||||
mEvent.m_y = y;
|
||||
mEvent.m_eventType = eventType;
|
||||
|
||||
if (pixelScaleX != 1.0f)
|
||||
mEvent.m_x = static_cast<int32_t>(static_cast<float>(x) / pixelScaleX);
|
||||
|
||||
if (pixelScaleY != 1.0f)
|
||||
mEvent.m_y = static_cast<int32_t>(static_cast<float>(y) / pixelScaleX);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,7 +297,7 @@ static void PostKeyboardEvent(IGpVOSEventQueue *eventQueue, GpKeyboardInputEvent
|
||||
}
|
||||
}
|
||||
|
||||
static void TranslateWindowsMessage(const MSG *msg, IGpVOSEventQueue *eventQueue)
|
||||
static void TranslateWindowsMessage(const MSG *msg, IGpVOSEventQueue *eventQueue, float pixelScaleX, float pixelScaleY)
|
||||
{
|
||||
WPARAM wParam = msg->wParam;
|
||||
LPARAM lParam = msg->lParam;
|
||||
@@ -299,40 +305,40 @@ static void TranslateWindowsMessage(const MSG *msg, IGpVOSEventQueue *eventQueue
|
||||
switch (msg->message)
|
||||
{
|
||||
case WM_LBUTTONDOWN:
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kLeft, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kLeft, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kLeft, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kLeft, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
|
||||
break;
|
||||
case WM_MBUTTONDOWN:
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kMiddle, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kMiddle, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
|
||||
break;
|
||||
case WM_MBUTTONUP:
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kMiddle, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kMiddle, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kRight, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kRight, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
|
||||
break;
|
||||
case WM_RBUTTONUP:
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kRight, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kRight, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
|
||||
break;
|
||||
case WM_XBUTTONDOWN:
|
||||
if (GET_XBUTTON_WPARAM(wParam) == XBUTTON1)
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kX1, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kX1, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
|
||||
else if (GET_XBUTTON_WPARAM(wParam) == XBUTTON2)
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kX2, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kDown, GpMouseButtons::kX2, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
|
||||
break;
|
||||
case WM_XBUTTONUP:
|
||||
if (GET_XBUTTON_WPARAM(wParam) == XBUTTON1)
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kX1, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kX1, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
|
||||
else if (GET_XBUTTON_WPARAM(wParam) == XBUTTON2)
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kX2, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kUp, GpMouseButtons::kX2, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kMove, GpMouseButtons::kNone, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kMove, GpMouseButtons::kNone, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), pixelScaleX, pixelScaleY);
|
||||
break;
|
||||
case WM_MOUSELEAVE:
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kLeave, GpMouseButtons::kNone, 0, 0);
|
||||
PostMouseEvent(eventQueue, GpMouseEventTypes::kLeave, GpMouseButtons::kNone, 0, 0, pixelScaleX, pixelScaleY);
|
||||
break;
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYDOWN:
|
||||
@@ -373,6 +379,12 @@ static void TranslateWindowsMessage(const MSG *msg, IGpVOSEventQueue *eventQueue
|
||||
PostKeyboardEvent(eventQueue, keyEventType, subset, key, (lParam & 0xffff));
|
||||
}
|
||||
break;
|
||||
case WM_QUIT:
|
||||
{
|
||||
if (GpVOSEvent *evt = eventQueue->QueueEvent())
|
||||
evt->m_eventType = GpVOSEventTypes::kQuit;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -388,6 +400,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
g_gpWindowsGlobals.m_cmdLine = lpCmdLine;
|
||||
g_gpWindowsGlobals.m_nCmdShow = nCmdShow;
|
||||
g_gpWindowsGlobals.m_baseDir = GpFileSystem_Win32::GetInstance()->GetBasePath();
|
||||
g_gpWindowsGlobals.m_hwnd = nullptr;
|
||||
|
||||
g_gpWindowsGlobals.m_createFiberFunc = GpFiber_Win32::Create;
|
||||
g_gpWindowsGlobals.m_loadCursorFunc = GpCursor_Win32::Load;
|
||||
|
@@ -52,6 +52,14 @@ const CompileJob kCompileJobs[] =
|
||||
drawQuadDefs,
|
||||
"PSMain",
|
||||
"ps_4_0"
|
||||
},
|
||||
{
|
||||
L"ShaderSrc\\ScaleQuadP.hlsl",
|
||||
L"GpDisplayDriver_D3D11\\CompiledShaders\\ScaleQuadP_D3D11.cpp",
|
||||
"g_scaleQuadP_D3D11",
|
||||
drawQuadDefs,
|
||||
"PSMain",
|
||||
"ps_4_0"
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -149,10 +149,10 @@ static void UpdateMainPict (Dialog *theDial)
|
||||
DrawDialogUserText2(theDial, 7, theStr);
|
||||
|
||||
PasStringCopy(PSTR("Screen: "), theStr); // display screen size/depth
|
||||
NumToString((long)(thisMac.screen.right - thisMac.screen.left), theStr2);
|
||||
NumToString((long)(thisMac.fullScreen.right - thisMac.fullScreen.left), theStr2);
|
||||
PasStringConcat(theStr, theStr2);
|
||||
PasStringConcat(theStr, PSTR("x"));
|
||||
NumToString((long)(thisMac.screen.bottom - thisMac.screen.top), theStr2);
|
||||
NumToString((long)(thisMac.fullScreen.bottom - thisMac.fullScreen.top), theStr2);
|
||||
PasStringConcat(theStr, theStr2);
|
||||
PasStringConcat(theStr, PSTR("x"));
|
||||
NumToString((long)thisMac.isDepth, theStr2);
|
||||
|
@@ -7,6 +7,7 @@
|
||||
|
||||
|
||||
#include "PLAppleEvents.h"
|
||||
#include "AppEventHandler.h"
|
||||
#include "DialogManager.h"
|
||||
#include "Externs.h"
|
||||
#include "House.h"
|
||||
@@ -168,12 +169,38 @@ PLError_t MyGotRequiredParams (const AppleEvent *theAE)
|
||||
PLErrors::kInvalidParameter;
|
||||
}
|
||||
|
||||
class SystemEventHandlerImpl : public PortabilityLayer::IAppEventHandler
|
||||
{
|
||||
public:
|
||||
void OnQuit() override;
|
||||
|
||||
static SystemEventHandlerImpl *GetInstance();
|
||||
|
||||
private:
|
||||
static SystemEventHandlerImpl ms_instance;
|
||||
};
|
||||
|
||||
void SystemEventHandlerImpl::OnQuit()
|
||||
{
|
||||
quitting = true;
|
||||
}
|
||||
|
||||
|
||||
SystemEventHandlerImpl *SystemEventHandlerImpl::GetInstance()
|
||||
{
|
||||
return &ms_instance;
|
||||
}
|
||||
|
||||
SystemEventHandlerImpl SystemEventHandlerImpl::ms_instance;
|
||||
|
||||
//-------------------------------------------------------------- SetUpAppleEvents
|
||||
// Initializes all handlers, etc. for dealing with Apple Events.
|
||||
|
||||
void SetUpAppleEvents (void)
|
||||
{
|
||||
PLError_t theErr;
|
||||
|
||||
PortabilityLayer::AppEventHandler::SetInstance(SystemEventHandlerImpl::GetInstance());
|
||||
|
||||
openAppAEUPP = NewAEEventHandlerProc(DoOpenAppAE);
|
||||
openDocAEUPP = NewAEEventHandlerProc(DoOpenDocAE);
|
||||
|
@@ -50,7 +50,7 @@ void DrawBanner (Point *topLeft)
|
||||
PLError_t theErr;
|
||||
|
||||
QSetRect(&wholePage, 0, 0, 330, 220);
|
||||
mapBounds = thisMac.screen;
|
||||
mapBounds = thisMac.fullScreen;
|
||||
ZeroRectCorner(&mapBounds);
|
||||
CenterRectInRect(&wholePage, &mapBounds);
|
||||
topLeft->h = wholePage.left;
|
||||
@@ -203,8 +203,8 @@ void DisplayStarsRemaining (void)
|
||||
DrawSurface *surface = mainWindow->GetDrawSurface();
|
||||
|
||||
QSetRect(&bounds, 0, 0, 256, 64);
|
||||
CenterRectInRect(&bounds, &thisMac.screen);
|
||||
QOffsetRect(&bounds, -thisMac.screen.left, -thisMac.screen.top);
|
||||
CenterRectInRect(&bounds, &thisMac.fullScreen);
|
||||
QOffsetRect(&bounds, -thisMac.fullScreen.left, -thisMac.fullScreen.top);
|
||||
src = bounds;
|
||||
InsetRect(&src, 64, 32);
|
||||
|
||||
|
@@ -5,6 +5,7 @@
|
||||
//============================================================================
|
||||
|
||||
|
||||
#include "ArrayTools.h"
|
||||
#include "Externs.h"
|
||||
#include "Environ.h"
|
||||
#include "MainWindow.h"
|
||||
@@ -58,6 +59,7 @@ void NilSavedMaps (void)
|
||||
}
|
||||
savedMaps[i].where = -1;
|
||||
savedMaps[i].who = -1;
|
||||
savedMaps[i].component = -1;
|
||||
}
|
||||
numSavedMaps = 0;
|
||||
}
|
||||
@@ -68,7 +70,7 @@ void NilSavedMaps (void)
|
||||
// room that it obscured so that, should the player get the object,<2C>
|
||||
// it can be made to "disappear".
|
||||
|
||||
short BackUpToSavedMap (Rect *theRect, short where, short who)
|
||||
short BackUpToSavedMap (Rect *theRect, SInt16 where, SInt16 who, SInt16 component)
|
||||
{
|
||||
Rect mapRect;
|
||||
PLError_t theErr;
|
||||
@@ -88,6 +90,7 @@ short BackUpToSavedMap (Rect *theRect, short where, short who)
|
||||
|
||||
savedMaps[numSavedMaps].where = where;
|
||||
savedMaps[numSavedMaps].who = who;
|
||||
savedMaps[numSavedMaps].component = component;
|
||||
numSavedMaps++;
|
||||
|
||||
return (numSavedMaps - 1); // return array index
|
||||
@@ -98,7 +101,7 @@ short BackUpToSavedMap (Rect *theRect, short where, short who)
|
||||
// a slot in the pixmap array for the object. It re-copies the background<6E>
|
||||
// and is needed when the lights in the room go on or off.
|
||||
|
||||
short ReBackUpSavedMap (Rect *theRect, short where, short who)
|
||||
SInt16 ReBackUpSavedMap (Rect *theRect, SInt16 where, SInt16 who, SInt16 component)
|
||||
{
|
||||
Rect mapRect;
|
||||
short i, foundIndex;
|
||||
@@ -107,11 +110,13 @@ short ReBackUpSavedMap (Rect *theRect, short where, short who)
|
||||
|
||||
for (i = 0; i < numSavedMaps; i++)
|
||||
{
|
||||
if ((savedMaps[i].where == where) && (savedMaps[i].who == who))
|
||||
if ((savedMaps[i].where == where) && (savedMaps[i].who == who) && (savedMaps[i].component == component))
|
||||
{
|
||||
foundIndex = i;
|
||||
mapRect = *theRect;
|
||||
ZeroRectCorner(&mapRect);
|
||||
|
||||
savedMaps[foundIndex].dest = *theRect;
|
||||
|
||||
CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap),
|
||||
GetPortBitMapForCopyBits(savedMaps[foundIndex].map),
|
||||
@@ -121,7 +126,54 @@ short ReBackUpSavedMap (Rect *theRect, short where, short who)
|
||||
}
|
||||
}
|
||||
|
||||
return (foundIndex);
|
||||
return BackUpToSavedMap(theRect, where, who, component);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- RemoveFromSavedMap
|
||||
template<class T>
|
||||
void RemapDynamicObject(T *arr, short &count, int removedIndex, int substituteIndex)
|
||||
{
|
||||
short countCopy = count;
|
||||
for (int i = 0; i < countCopy; i++)
|
||||
{
|
||||
if (arr[i].who == removedIndex)
|
||||
{
|
||||
PortabilityLayer::ArrayTools::RemoveFromArray(arr, countCopy, i);
|
||||
i--;
|
||||
}
|
||||
else if (arr[i].who == substituteIndex)
|
||||
arr[i].who = removedIndex;
|
||||
}
|
||||
|
||||
count = countCopy;
|
||||
}
|
||||
|
||||
SInt16 RemoveFromSavedMap (SInt16 index)
|
||||
{
|
||||
int swappedIn = numSavedMaps - 1;
|
||||
RemapDynamicObject(flames, numFlames, index, swappedIn);
|
||||
RemapDynamicObject(tikiFlames, numTikiFlames, index, swappedIn);
|
||||
RemapDynamicObject(bbqCoals, numCoals, index, swappedIn);
|
||||
RemapDynamicObject(pendulums, numPendulums, index, swappedIn);
|
||||
RemapDynamicObject(theStars, numStars, index, swappedIn);
|
||||
|
||||
RemapGreaseSavedMap(index, swappedIn);
|
||||
|
||||
// Have to do this explicitly so we don't trash the draw surface pointer
|
||||
if (swappedIn != index)
|
||||
{
|
||||
savedType &dest = savedMaps[index];
|
||||
savedType &src = savedMaps[swappedIn];
|
||||
|
||||
DisposeGWorld(dest.map);
|
||||
dest = src;
|
||||
|
||||
src.map = nil;
|
||||
}
|
||||
|
||||
numSavedMaps--;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- RestoreFromSavedMap
|
||||
@@ -129,14 +181,14 @@ short ReBackUpSavedMap (Rect *theRect, short where, short who)
|
||||
// This copies the saved background swatch to the screen - effectively<6C>
|
||||
// covering up or "erasing" the object.
|
||||
|
||||
void RestoreFromSavedMap (short where, short who, Boolean doSparkle)
|
||||
void RestoreFromSavedMap (SInt16 where, SInt16 who, SInt16 component, Boolean doSparkle)
|
||||
{
|
||||
Rect mapRect, bounds;
|
||||
short i;
|
||||
|
||||
for (i = 0; i < numSavedMaps; i++)
|
||||
{
|
||||
if ((savedMaps[i].where == where) && (savedMaps[i].who == who) &&
|
||||
if ((savedMaps[i].where == where) && (savedMaps[i].who == who) && (savedMaps[i].component == component) &&
|
||||
(savedMaps[i].map != nil))
|
||||
{
|
||||
mapRect = savedMaps[i].dest;
|
||||
@@ -290,7 +342,7 @@ void BackUpFlames (Rect *src, short index)
|
||||
// Like the above function but this is called when the lighting changes<65>
|
||||
// in a room (lights go on or off).
|
||||
|
||||
void ReBackUpFlames (short where, short who)
|
||||
Boolean ReBackUpFlames (short where, short who, short h, short v)
|
||||
{
|
||||
short i, f;
|
||||
|
||||
@@ -302,19 +354,22 @@ void ReBackUpFlames (short where, short who)
|
||||
{
|
||||
if (flames[f].who == i)
|
||||
{
|
||||
QOffsetRect(&flames[f].dest, h - 8 - flames[f].dest.left, v - 15 - flames[f].dest.top);
|
||||
BackUpFlames(&flames[f].dest, i);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- AddCandleFlame
|
||||
|
||||
// This adds a candle flame to tha array of flames.
|
||||
|
||||
void AddCandleFlame (short where, short who, short h, short v)
|
||||
void AddCandleFlame (SInt16 where, SInt16 who, SInt16 h, SInt16 v)
|
||||
{
|
||||
Rect src, bounds;
|
||||
short savedNum;
|
||||
@@ -331,7 +386,7 @@ void AddCandleFlame (short where, short who, short h, short v)
|
||||
QOffsetRect(&src, 2, 0);
|
||||
}
|
||||
QSetRect(&bounds, 0, 0, 16, 15 * kNumCandleFlames);
|
||||
savedNum = BackUpToSavedMap(&bounds, where, who);
|
||||
savedNum = BackUpToSavedMap(&bounds, where, who, kCandleFlameComponent);
|
||||
if (savedNum != -1)
|
||||
{
|
||||
BackUpFlames(&src, savedNum);
|
||||
@@ -374,7 +429,7 @@ void BackUpTikiFlames (Rect *src, short index)
|
||||
|
||||
// This is like the function ReBackUpFlames() but customized for Tiki torches.
|
||||
|
||||
void ReBackUpTikiFlames (short where, short who)
|
||||
Boolean ReBackUpTikiFlames (short where, short who, short h, short v)
|
||||
{
|
||||
short i, f;
|
||||
|
||||
@@ -386,12 +441,15 @@ void ReBackUpTikiFlames (short where, short who)
|
||||
{
|
||||
if (tikiFlames[f].who == i)
|
||||
{
|
||||
QOffsetRect(&tikiFlames[f].dest, h - tikiFlames[f].dest.left, v - tikiFlames[f].dest.top);
|
||||
BackUpTikiFlames(&tikiFlames[f].dest, i);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- AddTikiFlame
|
||||
@@ -415,7 +473,7 @@ void AddTikiFlame (short where, short who, short h, short v)
|
||||
}
|
||||
QOffsetRect(&src, h, v);
|
||||
QSetRect(&bounds, 0, 0, 8, 10 * kNumTikiFlames);
|
||||
savedNum = BackUpToSavedMap(&bounds, where, who);
|
||||
savedNum = BackUpToSavedMap(&bounds, where, who, kTikiFlamesComponent);
|
||||
if (savedNum != -1)
|
||||
{
|
||||
BackUpTikiFlames(&src, savedNum);
|
||||
@@ -460,7 +518,7 @@ void BackUpBBQCoals (Rect *src, short index)
|
||||
|
||||
// Sense a pattern here?
|
||||
|
||||
void ReBackUpBBQCoals (short where, short who)
|
||||
Boolean ReBackUpBBQCoals (short where, short who, short h, short v)
|
||||
{
|
||||
short i, f;
|
||||
|
||||
@@ -472,12 +530,15 @@ void ReBackUpBBQCoals (short where, short who)
|
||||
{
|
||||
if (bbqCoals[f].who == i)
|
||||
{
|
||||
QOffsetRect(&bbqCoals[f].dest, h - bbqCoals[f].dest.left, v - bbqCoals[f].dest.top);
|
||||
BackUpBBQCoals(&bbqCoals[f].dest, i);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- AddBBQCoals
|
||||
@@ -501,7 +562,7 @@ void AddBBQCoals (short where, short who, short h, short v)
|
||||
}
|
||||
QOffsetRect(&src, h, v);
|
||||
QSetRect(&bounds, 0, 0, 32, 9 * kNumBBQCoals);
|
||||
savedNum = BackUpToSavedMap(&bounds, where, who);
|
||||
savedNum = BackUpToSavedMap(&bounds, where, who, kBBQCoalsComponent);
|
||||
if (savedNum != -1)
|
||||
{
|
||||
BackUpBBQCoals(&src, savedNum);
|
||||
@@ -544,7 +605,7 @@ void BackUpPendulum (Rect *src, short index)
|
||||
|
||||
// Backs up the pendulums in the event of lights going on or off.
|
||||
|
||||
void ReBackUpPendulum (short where, short who)
|
||||
Boolean ReBackUpPendulum (short where, short who, short h, short v)
|
||||
{
|
||||
short i, f;
|
||||
|
||||
@@ -556,19 +617,26 @@ void ReBackUpPendulum (short where, short who)
|
||||
{
|
||||
if (pendulums[f].who == i)
|
||||
{
|
||||
BackUpPendulum(&pendulums[f].dest, i);
|
||||
return;
|
||||
Rect &pendulumDest = pendulums[f].dest;
|
||||
pendulumDest.right += h - pendulumDest.left;
|
||||
pendulumDest.bottom += v - pendulumDest.top;
|
||||
pendulumDest.left = h;
|
||||
pendulumDest.top = v;
|
||||
BackUpPendulum(&pendulumDest, i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- AddPendulum
|
||||
|
||||
// Adds a pendulum to the array of pendulums.
|
||||
|
||||
void AddPendulum (short where, short who, short h, short v)
|
||||
void AddPendulum (SInt16 where, SInt16 who, SInt16 h, SInt16 v)
|
||||
{
|
||||
Rect src, bounds;
|
||||
short savedNum;
|
||||
@@ -578,7 +646,7 @@ void AddPendulum (short where, short who, short h, short v)
|
||||
|
||||
clockFrame = 10;
|
||||
QSetRect(&bounds, 0, 0, 32, 28 * kNumPendulums);
|
||||
savedNum = BackUpToSavedMap(&bounds, where, who);
|
||||
savedNum = BackUpToSavedMap(&bounds, where, who, kPendulumComponent);
|
||||
if (savedNum != -1)
|
||||
{
|
||||
QSetRect(&src, 0, 0, 32, 28);
|
||||
@@ -636,7 +704,7 @@ void BackUpStar (Rect *src, short index)
|
||||
|
||||
// Re-backs up the stars - in the event of lighting switch.
|
||||
|
||||
void ReBackUpStar (short where, short who)
|
||||
void ReBackUpStar (short where, short who, short h, short v)
|
||||
{
|
||||
short i, f;
|
||||
|
||||
@@ -648,6 +716,7 @@ void ReBackUpStar (short where, short who)
|
||||
{
|
||||
if (theStars[f].who == i)
|
||||
{
|
||||
QOffsetRect(&theStars[f].dest, h - theStars[f].dest.left, v - theStars[f].dest.top);
|
||||
BackUpStar(&theStars[f].dest, i);
|
||||
return;
|
||||
}
|
||||
@@ -678,7 +747,7 @@ void AddStar (short where, short who, short h, short v)
|
||||
QOffsetRect(&src, h, v);
|
||||
|
||||
QSetRect(&bounds, 0, 0, 32, 31 * 6);
|
||||
savedNum = BackUpToSavedMap(&bounds, where, who);
|
||||
savedNum = BackUpToSavedMap(&bounds, where, who, kStarComponent);
|
||||
if (savedNum != -1)
|
||||
{
|
||||
BackUpStar(&src, savedNum);
|
||||
@@ -797,3 +866,14 @@ void ZeroFlamesAndTheLike (void)
|
||||
numChimes = 0;
|
||||
}
|
||||
|
||||
void RemoveSavedMapsNotInRoom(SInt16 where)
|
||||
{
|
||||
for (int i = 0; i < numSavedMaps; i++)
|
||||
{
|
||||
if (savedMaps[i].where != where)
|
||||
{
|
||||
RemoveFromSavedMap(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -153,6 +153,48 @@ void RenderDynamics (void)
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- ZeroDinah
|
||||
|
||||
void ZeroDinah(dynaType &dinah)
|
||||
{
|
||||
dinah.type = kObjectIsEmpty;
|
||||
QSetRect(&dinah.dest, 0, 0, 0, 0);
|
||||
QSetRect(&dinah.whole, 0, 0, 0, 0);
|
||||
dinah.hVel = 0;
|
||||
dinah.vVel = 0;
|
||||
dinah.count = 0;
|
||||
dinah.frame = 0;
|
||||
dinah.timer = 0;
|
||||
dinah.position = 0;
|
||||
dinah.room = 0;
|
||||
dinah.byte0 = 0;
|
||||
dinah.active = false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- ZeroDinahsNotInRoom
|
||||
void ZeroDinahsNotInRoom (SInt16 room)
|
||||
{
|
||||
short i;
|
||||
short newNumDynamics = 0;
|
||||
|
||||
for (i = 0; i < numDynamics; i++)
|
||||
{
|
||||
dynaType &dinah = dinahs[i];
|
||||
if (dinah.room == room)
|
||||
{
|
||||
if (newNumDynamics != numDynamics)
|
||||
memcpy(&dinahs[newNumDynamics], &dinahs[i], sizeof(dynaType));
|
||||
|
||||
newNumDynamics++;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = newNumDynamics; i < kMaxDynamicObs; i++)
|
||||
ZeroDinah(dinahs[i]);
|
||||
|
||||
numDynamics = newNumDynamics;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- ZeroDinahs
|
||||
|
||||
// This clears all dynamics - zeros them all out. Used to initialize them.
|
||||
@@ -162,20 +204,8 @@ void ZeroDinahs (void)
|
||||
short i;
|
||||
|
||||
for (i = 0; i < kMaxDynamicObs; i++)
|
||||
{
|
||||
dinahs[i].type = kObjectIsEmpty;
|
||||
QSetRect(&dinahs[i].dest, 0, 0, 0, 0);
|
||||
QSetRect(&dinahs[i].whole, 0, 0, 0, 0);
|
||||
dinahs[i].hVel = 0;
|
||||
dinahs[i].vVel = 0;
|
||||
dinahs[i].count = 0;
|
||||
dinahs[i].frame = 0;
|
||||
dinahs[i].timer = 0;
|
||||
dinahs[i].position = 0;
|
||||
dinahs[i].room = 0;
|
||||
dinahs[i].byte0 = 0;
|
||||
dinahs[i].active = false;
|
||||
}
|
||||
ZeroDinah(dinahs[i]);
|
||||
|
||||
numDynamics = 0;
|
||||
}
|
||||
|
||||
@@ -185,371 +215,494 @@ void ZeroDinahs (void)
|
||||
// This function sets up the structures to handle them.
|
||||
|
||||
short AddDynamicObject (short what, Rect *where, objectType *who,
|
||||
short room, short index, Boolean isOn)
|
||||
short room, short index, Boolean isOn, Boolean keepExisting)
|
||||
{
|
||||
short position, velocity;
|
||||
Boolean lilFrame;
|
||||
|
||||
if (numDynamics >= kMaxDynamicObs)
|
||||
return (-1);
|
||||
|
||||
dinahs[numDynamics].type = what;
|
||||
switch (what)
|
||||
|
||||
short dynIndex = -1;
|
||||
|
||||
if (!keepExisting)
|
||||
{
|
||||
case kSparkle:
|
||||
dinahs[numDynamics].dest = sparkleSrc[0];
|
||||
ZeroRectCorner(&dinahs[numDynamics].dest);
|
||||
QOffsetRect(&dinahs[numDynamics].dest, where->left, where->top);
|
||||
dinahs[numDynamics].whole = dinahs[numDynamics].dest;
|
||||
dinahs[numDynamics].hVel = 0;
|
||||
dinahs[numDynamics].vVel = 0;
|
||||
dinahs[numDynamics].count = 0;
|
||||
dinahs[numDynamics].frame = 0;
|
||||
dinahs[numDynamics].timer = RandomInt(60) + 15;
|
||||
dinahs[numDynamics].position = 0;
|
||||
dinahs[numDynamics].room = room;
|
||||
dinahs[numDynamics].byte0 = (Byte)index;
|
||||
dinahs[numDynamics].byte1 = 0;
|
||||
dinahs[numDynamics].moving = false;
|
||||
dinahs[numDynamics].active = isOn;
|
||||
break;
|
||||
|
||||
case kToaster:
|
||||
dinahs[numDynamics].dest = breadSrc[0];
|
||||
CenterRectInRect(&dinahs[numDynamics].dest, where);
|
||||
VOffsetRect(&dinahs[numDynamics].dest,
|
||||
where->top - dinahs[numDynamics].dest.top);
|
||||
dinahs[numDynamics].whole = dinahs[numDynamics].dest;
|
||||
dinahs[numDynamics].hVel = where->top + 2; // hVel used as clip
|
||||
position = who->data.g.height; // reverse engineer init. vel.
|
||||
velocity = 0;
|
||||
do
|
||||
if (numDynamics >= kMaxDynamicObs)
|
||||
return (-1);
|
||||
|
||||
dynIndex = numDynamics;
|
||||
numDynamics++;
|
||||
|
||||
dinahs[dynIndex].type = what;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < numDynamics; i++)
|
||||
{
|
||||
velocity++;
|
||||
position -= velocity;
|
||||
if (dinahs[i].type == what && dinahs[i].room == room && dinahs[i].byte0 == index)
|
||||
{
|
||||
dynIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (position > 0);
|
||||
dinahs[numDynamics].vVel = -velocity;
|
||||
dinahs[numDynamics].count = velocity; // count = initial velocity
|
||||
dinahs[numDynamics].frame = (short)who->data.g.delay * 3;
|
||||
dinahs[numDynamics].timer = dinahs[numDynamics].frame;
|
||||
dinahs[numDynamics].position = 0; // launch/idle state
|
||||
dinahs[numDynamics].room = room;
|
||||
dinahs[numDynamics].byte0 = (Byte)index;
|
||||
dinahs[numDynamics].byte1 = 0;
|
||||
dinahs[numDynamics].moving = false;
|
||||
dinahs[numDynamics].active = isOn;
|
||||
break;
|
||||
|
||||
case kMacPlus:
|
||||
dinahs[numDynamics].dest = plusScreen1;
|
||||
ZeroRectCorner(&dinahs[numDynamics].dest);
|
||||
QOffsetRect(&dinahs[numDynamics].dest,
|
||||
where->left + playOriginH + 10,
|
||||
where->top + playOriginV + 7);
|
||||
dinahs[numDynamics].whole = dinahs[numDynamics].dest;
|
||||
dinahs[numDynamics].hVel = 0;
|
||||
dinahs[numDynamics].vVel = 0;
|
||||
dinahs[numDynamics].count = 0;
|
||||
dinahs[numDynamics].frame = 0;
|
||||
dinahs[numDynamics].timer = 0;
|
||||
dinahs[numDynamics].position = 0;
|
||||
dinahs[numDynamics].room = room;
|
||||
dinahs[numDynamics].byte0 = (Byte)index;
|
||||
dinahs[numDynamics].byte1 = 0;
|
||||
dinahs[numDynamics].moving = false;
|
||||
dinahs[numDynamics].active = isOn;
|
||||
break;
|
||||
|
||||
case kTV:
|
||||
dinahs[numDynamics].dest = tvScreen1;
|
||||
ZeroRectCorner(&dinahs[numDynamics].dest);
|
||||
QOffsetRect(&dinahs[numDynamics].dest,
|
||||
where->left + playOriginH + 17,
|
||||
where->top + playOriginV + 10);
|
||||
dinahs[numDynamics].whole = dinahs[numDynamics].dest;
|
||||
dinahs[numDynamics].hVel = 0;
|
||||
dinahs[numDynamics].vVel = 0;
|
||||
dinahs[numDynamics].count = 0;
|
||||
dinahs[numDynamics].frame = 0;
|
||||
dinahs[numDynamics].timer = 0;
|
||||
dinahs[numDynamics].position = 0;
|
||||
dinahs[numDynamics].room = room;
|
||||
dinahs[numDynamics].byte0 = (Byte)index;
|
||||
dinahs[numDynamics].byte1 = 0;
|
||||
dinahs[numDynamics].moving = false;
|
||||
dinahs[numDynamics].active = isOn;
|
||||
break;
|
||||
|
||||
case kCoffee:
|
||||
dinahs[numDynamics].dest = coffeeLight1;
|
||||
ZeroRectCorner(&dinahs[numDynamics].dest);
|
||||
QOffsetRect(&dinahs[numDynamics].dest,
|
||||
where->left + playOriginH + 32,
|
||||
where->top + playOriginV + 57);
|
||||
dinahs[numDynamics].whole = dinahs[numDynamics].dest;
|
||||
dinahs[numDynamics].hVel = 0;
|
||||
dinahs[numDynamics].vVel = 0;
|
||||
dinahs[numDynamics].count = 0;
|
||||
dinahs[numDynamics].frame = 0;
|
||||
if (isOn)
|
||||
dinahs[numDynamics].timer = 200;
|
||||
else
|
||||
dinahs[numDynamics].timer = 0;
|
||||
dinahs[numDynamics].position = 0;
|
||||
dinahs[numDynamics].room = room;
|
||||
dinahs[numDynamics].byte0 = (Byte)index;
|
||||
dinahs[numDynamics].byte1 = 0;
|
||||
dinahs[numDynamics].moving = false;
|
||||
dinahs[numDynamics].active = isOn;
|
||||
break;
|
||||
|
||||
case kOutlet:
|
||||
dinahs[numDynamics].dest = outletSrc[0];
|
||||
ZeroRectCorner(&dinahs[numDynamics].dest);
|
||||
QOffsetRect(&dinahs[numDynamics].dest,
|
||||
where->left + playOriginH,
|
||||
where->top + playOriginV);
|
||||
dinahs[numDynamics].whole = dinahs[numDynamics].dest;
|
||||
dinahs[numDynamics].hVel = numLights;
|
||||
dinahs[numDynamics].vVel = 0;
|
||||
dinahs[numDynamics].count = ((short)who->data.g.delay * 6) / kTicksPerFrame;
|
||||
dinahs[numDynamics].frame = 0;
|
||||
dinahs[numDynamics].timer = dinahs[numDynamics].count;
|
||||
dinahs[numDynamics].position = 0; // launch/idle state
|
||||
dinahs[numDynamics].room = room;
|
||||
dinahs[numDynamics].byte0 = (Byte)index;
|
||||
dinahs[numDynamics].byte1 = 0;
|
||||
dinahs[numDynamics].moving = false;
|
||||
dinahs[numDynamics].active = isOn;
|
||||
break;
|
||||
|
||||
case kVCR:
|
||||
dinahs[numDynamics].dest = vcrTime1;
|
||||
ZeroRectCorner(&dinahs[numDynamics].dest);
|
||||
QOffsetRect(&dinahs[numDynamics].dest,
|
||||
where->left + playOriginH + 64,
|
||||
where->top + playOriginV + 6);
|
||||
dinahs[numDynamics].whole = dinahs[numDynamics].dest;
|
||||
dinahs[numDynamics].hVel = 0;
|
||||
dinahs[numDynamics].vVel = 0;
|
||||
dinahs[numDynamics].count = 0;
|
||||
dinahs[numDynamics].frame = 0;
|
||||
if (isOn)
|
||||
dinahs[numDynamics].timer = 115;
|
||||
else
|
||||
dinahs[numDynamics].timer = 0;
|
||||
dinahs[numDynamics].position = 0;
|
||||
dinahs[numDynamics].room = room;
|
||||
dinahs[numDynamics].byte0 = (Byte)index;
|
||||
dinahs[numDynamics].byte1 = 0;
|
||||
dinahs[numDynamics].moving = false;
|
||||
dinahs[numDynamics].active = isOn;
|
||||
break;
|
||||
|
||||
case kStereo:
|
||||
dinahs[numDynamics].dest = stereoLight1;
|
||||
ZeroRectCorner(&dinahs[numDynamics].dest);
|
||||
QOffsetRect(&dinahs[numDynamics].dest,
|
||||
where->left + playOriginH + 56,
|
||||
where->top + playOriginV + 20);
|
||||
dinahs[numDynamics].whole = dinahs[numDynamics].dest;
|
||||
dinahs[numDynamics].hVel = 0;
|
||||
dinahs[numDynamics].vVel = 0;
|
||||
dinahs[numDynamics].count = 0;
|
||||
dinahs[numDynamics].frame = 0;
|
||||
dinahs[numDynamics].timer = 0;
|
||||
dinahs[numDynamics].position = 0;
|
||||
dinahs[numDynamics].room = room;
|
||||
dinahs[numDynamics].byte0 = (Byte)index;
|
||||
dinahs[numDynamics].byte1 = 0;
|
||||
dinahs[numDynamics].moving = false;
|
||||
dinahs[numDynamics].active = isOn;
|
||||
break;
|
||||
|
||||
case kMicrowave:
|
||||
dinahs[numDynamics].dest = microOn;
|
||||
ZeroRectCorner(&dinahs[numDynamics].dest);
|
||||
QOffsetRect(&dinahs[numDynamics].dest,
|
||||
where->left + playOriginH + 14,
|
||||
where->top + playOriginV + 13);
|
||||
dinahs[numDynamics].dest.right = dinahs[numDynamics].dest.left + 48;
|
||||
dinahs[numDynamics].whole = dinahs[numDynamics].dest;
|
||||
dinahs[numDynamics].hVel = 0;
|
||||
dinahs[numDynamics].vVel = 0;
|
||||
dinahs[numDynamics].count = 0;
|
||||
dinahs[numDynamics].frame = 0;
|
||||
dinahs[numDynamics].timer = 0;
|
||||
dinahs[numDynamics].position = 0;
|
||||
dinahs[numDynamics].room = room;
|
||||
dinahs[numDynamics].byte0 = (Byte)index;
|
||||
dinahs[numDynamics].byte1 = 0;
|
||||
dinahs[numDynamics].moving = false;
|
||||
dinahs[numDynamics].active = isOn;
|
||||
break;
|
||||
|
||||
case kBalloon:
|
||||
dinahs[numDynamics].dest = balloonSrc[0];
|
||||
ZeroRectCorner(&dinahs[numDynamics].dest);
|
||||
QOffsetRect(&dinahs[numDynamics].dest, where->left, 0);
|
||||
dinahs[numDynamics].dest.bottom = kBalloonStart;
|
||||
dinahs[numDynamics].dest.top = dinahs[numDynamics].dest.bottom -
|
||||
RectTall(&balloonSrc[0]);
|
||||
dinahs[numDynamics].whole = dinahs[numDynamics].dest;
|
||||
dinahs[numDynamics].hVel = 0;
|
||||
dinahs[numDynamics].vVel = -2;
|
||||
dinahs[numDynamics].count = ((short)who->data.h.delay * 6) / kTicksPerFrame;
|
||||
dinahs[numDynamics].frame = 0;
|
||||
dinahs[numDynamics].timer = dinahs[numDynamics].count;
|
||||
dinahs[numDynamics].position = 0;
|
||||
dinahs[numDynamics].room = room;
|
||||
dinahs[numDynamics].byte0 = (Byte)index;
|
||||
dinahs[numDynamics].byte1 = 0;
|
||||
dinahs[numDynamics].moving = false;
|
||||
dinahs[numDynamics].active = isOn; // initially idle
|
||||
break;
|
||||
|
||||
case kCopterLf:
|
||||
case kCopterRt:
|
||||
dinahs[numDynamics].dest = copterSrc[0];
|
||||
ZeroRectCorner(&dinahs[numDynamics].dest);
|
||||
QOffsetRect(&dinahs[numDynamics].dest, where->left, 0);
|
||||
dinahs[numDynamics].dest.top = kCopterStart;
|
||||
dinahs[numDynamics].dest.bottom = dinahs[numDynamics].dest.top +
|
||||
RectTall(&copterSrc[0]);
|
||||
dinahs[numDynamics].whole = dinahs[numDynamics].dest;
|
||||
if (what == kCopterLf)
|
||||
dinahs[numDynamics].hVel = -1;
|
||||
else
|
||||
dinahs[numDynamics].hVel = 1;
|
||||
dinahs[numDynamics].vVel = 2;
|
||||
dinahs[numDynamics].count = ((short)who->data.h.delay * 6) / kTicksPerFrame;
|
||||
dinahs[numDynamics].frame = 0;
|
||||
dinahs[numDynamics].timer = dinahs[numDynamics].count;
|
||||
dinahs[numDynamics].position = dinahs[numDynamics].dest.left;
|
||||
dinahs[numDynamics].room = room;
|
||||
dinahs[numDynamics].byte0 = (Byte)index;
|
||||
dinahs[numDynamics].byte1 = 0;
|
||||
dinahs[numDynamics].moving = false;
|
||||
dinahs[numDynamics].active = isOn; // initially idle
|
||||
break;
|
||||
|
||||
case kDartLf:
|
||||
case kDartRt:
|
||||
dinahs[numDynamics].dest = dartSrc[0];
|
||||
ZeroRectCorner(&dinahs[numDynamics].dest);
|
||||
if (what == kDartLf)
|
||||
{
|
||||
QOffsetRect(&dinahs[numDynamics].dest,
|
||||
kRoomWide - RectWide(&dartSrc[0]), where->top);
|
||||
dinahs[numDynamics].hVel = -kDartVelocity;
|
||||
dinahs[numDynamics].frame = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
QOffsetRect(&dinahs[numDynamics].dest, 0, where->top);
|
||||
dinahs[numDynamics].hVel = kDartVelocity;
|
||||
dinahs[numDynamics].frame = 2;
|
||||
}
|
||||
dinahs[numDynamics].whole = dinahs[numDynamics].dest;
|
||||
dinahs[numDynamics].vVel = 2;
|
||||
dinahs[numDynamics].count = ((short)who->data.h.delay * 6) / kTicksPerFrame;
|
||||
dinahs[numDynamics].timer = dinahs[numDynamics].count;
|
||||
dinahs[numDynamics].position = dinahs[numDynamics].dest.top;
|
||||
dinahs[numDynamics].byte0 = (Byte)index;
|
||||
dinahs[numDynamics].byte1 = 0;
|
||||
dinahs[numDynamics].moving = false;
|
||||
dinahs[numDynamics].active = isOn; // initially idle
|
||||
break;
|
||||
|
||||
case kBall:
|
||||
dinahs[numDynamics].dest = ballSrc[0];
|
||||
ZeroRectCorner(&dinahs[numDynamics].dest);
|
||||
QOffsetRect(&dinahs[numDynamics].dest,
|
||||
where->left, where->top);
|
||||
dinahs[numDynamics].whole = dinahs[numDynamics].dest;
|
||||
dinahs[numDynamics].hVel = 0;
|
||||
position = who->data.h.length; // reverse engineer init. vel.
|
||||
velocity = 0;
|
||||
evenFrame = true;
|
||||
lilFrame = true;
|
||||
do
|
||||
{
|
||||
if (lilFrame)
|
||||
velocity++;
|
||||
lilFrame = !lilFrame;
|
||||
position -= velocity;
|
||||
}
|
||||
while (position > 0);
|
||||
dinahs[numDynamics].vVel = -velocity;
|
||||
dinahs[numDynamics].moving = false;
|
||||
dinahs[numDynamics].count = -velocity; // count = initial velocity
|
||||
dinahs[numDynamics].frame = 0;
|
||||
dinahs[numDynamics].timer = 0;
|
||||
dinahs[numDynamics].position = dinahs[numDynamics].dest.bottom;
|
||||
dinahs[numDynamics].room = room;
|
||||
dinahs[numDynamics].byte0 = (Byte)index;
|
||||
dinahs[numDynamics].byte1 = 0;
|
||||
dinahs[numDynamics].active = isOn;
|
||||
break;
|
||||
|
||||
case kDrip:
|
||||
dinahs[numDynamics].dest = dripSrc[0];
|
||||
CenterRectInRect(&dinahs[numDynamics].dest, where);
|
||||
VOffsetRect(&dinahs[numDynamics].dest,
|
||||
where->top - dinahs[numDynamics].dest.top);
|
||||
dinahs[numDynamics].whole = dinahs[numDynamics].dest;
|
||||
dinahs[numDynamics].hVel = dinahs[numDynamics].dest.top; // remember
|
||||
dinahs[numDynamics].vVel = 0;
|
||||
dinahs[numDynamics].count = ((short)who->data.h.delay * 6) / kTicksPerFrame;
|
||||
dinahs[numDynamics].frame = 3;
|
||||
dinahs[numDynamics].timer = dinahs[numDynamics].count;
|
||||
dinahs[numDynamics].position = dinahs[numDynamics].dest.top +
|
||||
who->data.h.length;
|
||||
dinahs[numDynamics].room = room;
|
||||
dinahs[numDynamics].byte0 = (Byte)index;
|
||||
dinahs[numDynamics].byte1 = 0;
|
||||
dinahs[numDynamics].moving = false;
|
||||
dinahs[numDynamics].active = isOn;
|
||||
break;
|
||||
|
||||
case kFish:
|
||||
dinahs[numDynamics].dest = fishSrc[0];
|
||||
QOffsetRect(&dinahs[numDynamics].dest,
|
||||
where->left + 10, where->top + 8);
|
||||
dinahs[numDynamics].whole = dinahs[numDynamics].dest;
|
||||
dinahs[numDynamics].hVel = ((short)who->data.h.delay * 6) / kTicksPerFrame;
|
||||
position = who->data.g.height; // reverse engineer init. vel.
|
||||
velocity = 0;
|
||||
evenFrame = true;
|
||||
lilFrame = true;
|
||||
do
|
||||
{
|
||||
if (lilFrame)
|
||||
velocity++;
|
||||
lilFrame = !lilFrame;
|
||||
position -= velocity;
|
||||
}
|
||||
while (position > 0);
|
||||
dinahs[numDynamics].vVel = -velocity;
|
||||
dinahs[numDynamics].count = -velocity; // count = initial velocity
|
||||
dinahs[numDynamics].frame = 0;
|
||||
dinahs[numDynamics].timer = dinahs[numDynamics].hVel;
|
||||
dinahs[numDynamics].position = dinahs[numDynamics].dest.bottom;
|
||||
dinahs[numDynamics].room = room;
|
||||
dinahs[numDynamics].byte0 = (Byte)index;
|
||||
dinahs[numDynamics].byte1 = 0;
|
||||
dinahs[numDynamics].moving = false;
|
||||
dinahs[numDynamics].active = isOn;
|
||||
break;
|
||||
|
||||
default:
|
||||
return (-1);
|
||||
break;
|
||||
|
||||
if (dynIndex == -1)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
numDynamics++;
|
||||
|
||||
return (numDynamics - 1);
|
||||
}
|
||||
switch (what)
|
||||
{
|
||||
case kSparkle:
|
||||
dinahs[dynIndex].dest = sparkleSrc[0];
|
||||
ZeroRectCorner(&dinahs[dynIndex].dest);
|
||||
QOffsetRect(&dinahs[dynIndex].dest, where->left, where->top);
|
||||
dinahs[dynIndex].whole = dinahs[dynIndex].dest;
|
||||
|
||||
if (!keepExisting)
|
||||
{
|
||||
dinahs[dynIndex].hVel = 0;
|
||||
dinahs[dynIndex].vVel = 0;
|
||||
dinahs[dynIndex].count = 0;
|
||||
dinahs[dynIndex].frame = 0;
|
||||
dinahs[dynIndex].timer = RandomInt(60) + 15;
|
||||
dinahs[dynIndex].position = 0;
|
||||
dinahs[dynIndex].room = room;
|
||||
dinahs[dynIndex].byte0 = (Byte)index;
|
||||
dinahs[dynIndex].byte1 = 0;
|
||||
dinahs[dynIndex].moving = false;
|
||||
dinahs[dynIndex].active = isOn;
|
||||
}
|
||||
break;
|
||||
|
||||
case kToaster:
|
||||
{
|
||||
short baselineDelta = 0;
|
||||
if (keepExisting)
|
||||
baselineDelta = dinahs[dynIndex].dest.top - (where->top - 2);
|
||||
|
||||
dinahs[dynIndex].dest = breadSrc[0];
|
||||
CenterRectInRect(&dinahs[dynIndex].dest, where);
|
||||
VOffsetRect(&dinahs[dynIndex].dest,
|
||||
where->top - dinahs[dynIndex].dest.top + baselineDelta);
|
||||
|
||||
dinahs[dynIndex].whole = dinahs[dynIndex].dest;
|
||||
dinahs[dynIndex].hVel = where->top + 2; // hVel used as clip
|
||||
|
||||
if (!keepExisting)
|
||||
{
|
||||
position = who->data.g.height; // reverse engineer init. vel.
|
||||
velocity = 0;
|
||||
do
|
||||
{
|
||||
velocity++;
|
||||
position -= velocity;
|
||||
} while (position > 0);
|
||||
dinahs[dynIndex].vVel = -velocity;
|
||||
dinahs[dynIndex].count = velocity; // count = initial velocity
|
||||
dinahs[dynIndex].frame = (short)who->data.g.delay * 3;
|
||||
dinahs[dynIndex].timer = dinahs[dynIndex].frame;
|
||||
dinahs[dynIndex].position = 0; // launch/idle state
|
||||
dinahs[dynIndex].room = room;
|
||||
dinahs[dynIndex].byte0 = (Byte)index;
|
||||
dinahs[dynIndex].byte1 = 0;
|
||||
dinahs[dynIndex].moving = false;
|
||||
dinahs[dynIndex].active = isOn;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kMacPlus:
|
||||
dinahs[dynIndex].dest = plusScreen1;
|
||||
ZeroRectCorner(&dinahs[dynIndex].dest);
|
||||
QOffsetRect(&dinahs[dynIndex].dest,
|
||||
where->left + playOriginH + 10,
|
||||
where->top + playOriginV + 7);
|
||||
dinahs[dynIndex].whole = dinahs[dynIndex].dest;
|
||||
if (!keepExisting)
|
||||
{
|
||||
dinahs[dynIndex].hVel = 0;
|
||||
dinahs[dynIndex].vVel = 0;
|
||||
dinahs[dynIndex].count = 0;
|
||||
dinahs[dynIndex].frame = 0;
|
||||
dinahs[dynIndex].timer = 0;
|
||||
dinahs[dynIndex].position = 0;
|
||||
dinahs[dynIndex].room = room;
|
||||
dinahs[dynIndex].byte0 = (Byte)index;
|
||||
dinahs[dynIndex].byte1 = 0;
|
||||
dinahs[dynIndex].moving = false;
|
||||
dinahs[dynIndex].active = isOn;
|
||||
}
|
||||
break;
|
||||
|
||||
case kTV:
|
||||
dinahs[dynIndex].dest = tvScreen1;
|
||||
ZeroRectCorner(&dinahs[dynIndex].dest);
|
||||
QOffsetRect(&dinahs[dynIndex].dest,
|
||||
where->left + playOriginH + 17,
|
||||
where->top + playOriginV + 10);
|
||||
dinahs[dynIndex].whole = dinahs[dynIndex].dest;
|
||||
if (!keepExisting)
|
||||
{
|
||||
dinahs[dynIndex].hVel = 0;
|
||||
dinahs[dynIndex].vVel = 0;
|
||||
dinahs[dynIndex].count = 0;
|
||||
dinahs[dynIndex].frame = 0;
|
||||
dinahs[dynIndex].timer = 0;
|
||||
dinahs[dynIndex].position = 0;
|
||||
dinahs[dynIndex].room = room;
|
||||
dinahs[dynIndex].byte0 = (Byte)index;
|
||||
dinahs[dynIndex].byte1 = 0;
|
||||
dinahs[dynIndex].moving = false;
|
||||
dinahs[dynIndex].active = isOn;
|
||||
}
|
||||
break;
|
||||
|
||||
case kCoffee:
|
||||
dinahs[dynIndex].dest = coffeeLight1;
|
||||
ZeroRectCorner(&dinahs[dynIndex].dest);
|
||||
QOffsetRect(&dinahs[dynIndex].dest,
|
||||
where->left + playOriginH + 32,
|
||||
where->top + playOriginV + 57);
|
||||
dinahs[dynIndex].whole = dinahs[dynIndex].dest;
|
||||
|
||||
if (!keepExisting)
|
||||
{
|
||||
dinahs[dynIndex].hVel = 0;
|
||||
dinahs[dynIndex].vVel = 0;
|
||||
dinahs[dynIndex].count = 0;
|
||||
dinahs[dynIndex].frame = 0;
|
||||
if (isOn)
|
||||
dinahs[dynIndex].timer = 200;
|
||||
else
|
||||
dinahs[dynIndex].timer = 0;
|
||||
dinahs[dynIndex].position = 0;
|
||||
dinahs[dynIndex].room = room;
|
||||
dinahs[dynIndex].byte0 = (Byte)index;
|
||||
dinahs[dynIndex].byte1 = 0;
|
||||
dinahs[dynIndex].moving = false;
|
||||
dinahs[dynIndex].active = isOn;
|
||||
}
|
||||
break;
|
||||
|
||||
case kOutlet:
|
||||
dinahs[dynIndex].dest = outletSrc[0];
|
||||
ZeroRectCorner(&dinahs[dynIndex].dest);
|
||||
QOffsetRect(&dinahs[dynIndex].dest,
|
||||
where->left + playOriginH,
|
||||
where->top + playOriginV);
|
||||
dinahs[dynIndex].whole = dinahs[dynIndex].dest;
|
||||
|
||||
if (!keepExisting)
|
||||
{
|
||||
dinahs[dynIndex].hVel = numLights;
|
||||
dinahs[dynIndex].vVel = 0;
|
||||
dinahs[dynIndex].count = ((short)who->data.g.delay * 6) / kTicksPerFrame;
|
||||
dinahs[dynIndex].frame = 0;
|
||||
dinahs[dynIndex].timer = dinahs[dynIndex].count;
|
||||
dinahs[dynIndex].position = 0; // launch/idle state
|
||||
dinahs[dynIndex].room = room;
|
||||
dinahs[dynIndex].byte0 = (Byte)index;
|
||||
dinahs[dynIndex].byte1 = 0;
|
||||
dinahs[dynIndex].moving = false;
|
||||
dinahs[dynIndex].active = isOn;
|
||||
}
|
||||
break;
|
||||
|
||||
case kVCR:
|
||||
dinahs[dynIndex].dest = vcrTime1;
|
||||
ZeroRectCorner(&dinahs[dynIndex].dest);
|
||||
QOffsetRect(&dinahs[dynIndex].dest,
|
||||
where->left + playOriginH + 64,
|
||||
where->top + playOriginV + 6);
|
||||
dinahs[dynIndex].whole = dinahs[dynIndex].dest;
|
||||
|
||||
if (!keepExisting)
|
||||
{
|
||||
dinahs[dynIndex].hVel = 0;
|
||||
dinahs[dynIndex].vVel = 0;
|
||||
dinahs[dynIndex].count = 0;
|
||||
dinahs[dynIndex].frame = 0;
|
||||
if (isOn)
|
||||
dinahs[dynIndex].timer = 115;
|
||||
else
|
||||
dinahs[dynIndex].timer = 0;
|
||||
dinahs[dynIndex].position = 0;
|
||||
dinahs[dynIndex].room = room;
|
||||
dinahs[dynIndex].byte0 = (Byte)index;
|
||||
dinahs[dynIndex].byte1 = 0;
|
||||
dinahs[dynIndex].moving = false;
|
||||
dinahs[dynIndex].active = isOn;
|
||||
}
|
||||
break;
|
||||
|
||||
case kStereo:
|
||||
dinahs[dynIndex].dest = stereoLight1;
|
||||
ZeroRectCorner(&dinahs[dynIndex].dest);
|
||||
QOffsetRect(&dinahs[dynIndex].dest,
|
||||
where->left + playOriginH + 56,
|
||||
where->top + playOriginV + 20);
|
||||
dinahs[dynIndex].whole = dinahs[dynIndex].dest;
|
||||
|
||||
if (!keepExisting)
|
||||
{
|
||||
dinahs[dynIndex].hVel = 0;
|
||||
dinahs[dynIndex].vVel = 0;
|
||||
dinahs[dynIndex].count = 0;
|
||||
dinahs[dynIndex].frame = 0;
|
||||
dinahs[dynIndex].timer = 0;
|
||||
dinahs[dynIndex].position = 0;
|
||||
dinahs[dynIndex].room = room;
|
||||
dinahs[dynIndex].byte0 = (Byte)index;
|
||||
dinahs[dynIndex].byte1 = 0;
|
||||
dinahs[dynIndex].moving = false;
|
||||
dinahs[dynIndex].active = isOn;
|
||||
}
|
||||
break;
|
||||
|
||||
case kMicrowave:
|
||||
dinahs[dynIndex].dest = microOn;
|
||||
ZeroRectCorner(&dinahs[dynIndex].dest);
|
||||
QOffsetRect(&dinahs[dynIndex].dest,
|
||||
where->left + playOriginH + 14,
|
||||
where->top + playOriginV + 13);
|
||||
dinahs[dynIndex].dest.right = dinahs[dynIndex].dest.left + 48;
|
||||
dinahs[dynIndex].whole = dinahs[dynIndex].dest;
|
||||
|
||||
if (!keepExisting)
|
||||
{
|
||||
dinahs[dynIndex].hVel = 0;
|
||||
dinahs[dynIndex].vVel = 0;
|
||||
dinahs[dynIndex].count = 0;
|
||||
dinahs[dynIndex].frame = 0;
|
||||
dinahs[dynIndex].timer = 0;
|
||||
dinahs[dynIndex].position = 0;
|
||||
dinahs[dynIndex].room = room;
|
||||
dinahs[dynIndex].byte0 = (Byte)index;
|
||||
dinahs[dynIndex].byte1 = 0;
|
||||
dinahs[dynIndex].moving = false;
|
||||
dinahs[dynIndex].active = isOn;
|
||||
}
|
||||
break;
|
||||
|
||||
case kBalloon:
|
||||
{
|
||||
short baselineDelta = 0;
|
||||
if (keepExisting)
|
||||
baselineDelta = dinahs[dynIndex].dest.bottom - kBalloonStart;
|
||||
|
||||
dinahs[dynIndex].dest = balloonSrc[0];
|
||||
ZeroRectCorner(&dinahs[dynIndex].dest);
|
||||
QOffsetRect(&dinahs[dynIndex].dest, where->left, 0);
|
||||
dinahs[dynIndex].dest.bottom = kBalloonStart + baselineDelta;
|
||||
dinahs[dynIndex].dest.top = dinahs[dynIndex].dest.bottom -
|
||||
RectTall(&balloonSrc[0]);
|
||||
dinahs[dynIndex].whole = dinahs[dynIndex].dest;
|
||||
|
||||
if (!keepExisting)
|
||||
{
|
||||
dinahs[dynIndex].hVel = 0;
|
||||
dinahs[dynIndex].vVel = -2;
|
||||
dinahs[dynIndex].count = ((short)who->data.h.delay * 6) / kTicksPerFrame;
|
||||
dinahs[dynIndex].frame = 0;
|
||||
dinahs[dynIndex].timer = dinahs[dynIndex].count;
|
||||
dinahs[dynIndex].position = 0;
|
||||
dinahs[dynIndex].room = room;
|
||||
dinahs[dynIndex].byte0 = (Byte)index;
|
||||
dinahs[dynIndex].byte1 = 0;
|
||||
dinahs[dynIndex].moving = false;
|
||||
dinahs[dynIndex].active = isOn; // initially idle
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kCopterLf:
|
||||
case kCopterRt:
|
||||
{
|
||||
short baselineDeltaH = 0;
|
||||
short baselineDeltaV = 0;
|
||||
|
||||
if (keepExisting)
|
||||
{
|
||||
baselineDeltaH = dinahs[dynIndex].dest.left - dinahs[dynIndex].position;
|
||||
baselineDeltaV = dinahs[dynIndex].dest.top - kCopterStart;
|
||||
}
|
||||
|
||||
dinahs[dynIndex].dest = copterSrc[0];
|
||||
ZeroRectCorner(&dinahs[dynIndex].dest);
|
||||
QOffsetRect(&dinahs[dynIndex].dest, where->left, 0);
|
||||
dinahs[dynIndex].dest.top = kCopterStart + baselineDeltaV;
|
||||
dinahs[dynIndex].dest.bottom = dinahs[dynIndex].dest.top +
|
||||
RectTall(&copterSrc[0]);
|
||||
dinahs[dynIndex].whole = dinahs[dynIndex].dest;
|
||||
|
||||
if (!keepExisting)
|
||||
{
|
||||
dinahs[dynIndex].position = dinahs[dynIndex].dest.left;
|
||||
|
||||
if (what == kCopterLf)
|
||||
dinahs[dynIndex].hVel = -1;
|
||||
else
|
||||
dinahs[dynIndex].hVel = 1;
|
||||
dinahs[dynIndex].vVel = 2;
|
||||
dinahs[dynIndex].count = ((short)who->data.h.delay * 6) / kTicksPerFrame;
|
||||
dinahs[dynIndex].frame = 0;
|
||||
dinahs[dynIndex].timer = dinahs[dynIndex].count;
|
||||
dinahs[dynIndex].room = room;
|
||||
dinahs[dynIndex].byte0 = (Byte)index;
|
||||
dinahs[dynIndex].byte1 = 0;
|
||||
dinahs[dynIndex].moving = false;
|
||||
dinahs[dynIndex].active = isOn; // initially idle
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kDartLf:
|
||||
case kDartRt:
|
||||
dinahs[dynIndex].dest = dartSrc[0];
|
||||
ZeroRectCorner(&dinahs[dynIndex].dest);
|
||||
if (what == kDartLf)
|
||||
{
|
||||
QOffsetRect(&dinahs[dynIndex].dest,
|
||||
kRoomWide - RectWide(&dartSrc[0]), where->top);
|
||||
dinahs[dynIndex].hVel = -kDartVelocity;
|
||||
dinahs[dynIndex].frame = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
QOffsetRect(&dinahs[dynIndex].dest, 0, where->top);
|
||||
dinahs[dynIndex].hVel = kDartVelocity;
|
||||
dinahs[dynIndex].frame = 2;
|
||||
}
|
||||
dinahs[dynIndex].whole = dinahs[dynIndex].dest;
|
||||
dinahs[dynIndex].position = dinahs[dynIndex].dest.top;
|
||||
|
||||
if (!keepExisting)
|
||||
{
|
||||
dinahs[dynIndex].vVel = 2;
|
||||
dinahs[dynIndex].count = ((short)who->data.h.delay * 6) / kTicksPerFrame;
|
||||
dinahs[dynIndex].timer = dinahs[dynIndex].count;
|
||||
dinahs[dynIndex].byte0 = (Byte)index;
|
||||
dinahs[dynIndex].byte1 = 0;
|
||||
dinahs[dynIndex].moving = false;
|
||||
dinahs[dynIndex].active = isOn; // initially idle
|
||||
}
|
||||
break;
|
||||
|
||||
case kBall:
|
||||
{
|
||||
short baselineDelta = 0;
|
||||
|
||||
if (keepExisting)
|
||||
baselineDelta = dinahs[dynIndex].dest.bottom - dinahs[dynIndex].position;
|
||||
|
||||
dinahs[dynIndex].dest = ballSrc[0];
|
||||
ZeroRectCorner(&dinahs[dynIndex].dest);
|
||||
QOffsetRect(&dinahs[dynIndex].dest,
|
||||
where->left, where->top + baselineDelta);
|
||||
dinahs[dynIndex].whole = dinahs[dynIndex].dest;
|
||||
|
||||
if (!keepExisting)
|
||||
{
|
||||
dinahs[dynIndex].position = dinahs[dynIndex].dest.bottom;
|
||||
|
||||
dinahs[dynIndex].hVel = 0;
|
||||
position = who->data.h.length; // reverse engineer init. vel.
|
||||
velocity = 0;
|
||||
evenFrame = true;
|
||||
lilFrame = true;
|
||||
do
|
||||
{
|
||||
if (lilFrame)
|
||||
velocity++;
|
||||
lilFrame = !lilFrame;
|
||||
position -= velocity;
|
||||
} while (position > 0);
|
||||
dinahs[dynIndex].vVel = -velocity;
|
||||
dinahs[dynIndex].moving = false;
|
||||
dinahs[dynIndex].count = -velocity; // count = initial velocity
|
||||
dinahs[dynIndex].frame = 0;
|
||||
dinahs[dynIndex].timer = 0;
|
||||
dinahs[dynIndex].room = room;
|
||||
dinahs[dynIndex].byte0 = (Byte)index;
|
||||
dinahs[dynIndex].byte1 = 0;
|
||||
dinahs[dynIndex].active = isOn;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kDrip:
|
||||
{
|
||||
short baselineDelta = 0;
|
||||
|
||||
if (keepExisting)
|
||||
baselineDelta = dinahs[dynIndex].dest.top - dinahs[dynIndex].hVel;
|
||||
|
||||
dinahs[dynIndex].dest = dripSrc[0];
|
||||
CenterRectInRect(&dinahs[dynIndex].dest, where);
|
||||
VOffsetRect(&dinahs[dynIndex].dest,
|
||||
where->top - dinahs[dynIndex].dest.top + baselineDelta);
|
||||
dinahs[dynIndex].whole = dinahs[dynIndex].dest;
|
||||
|
||||
if (!keepExisting)
|
||||
{
|
||||
dinahs[dynIndex].hVel = dinahs[dynIndex].dest.top; // remember
|
||||
dinahs[dynIndex].position = dinahs[dynIndex].dest.top +
|
||||
who->data.h.length;
|
||||
|
||||
dinahs[dynIndex].vVel = 0;
|
||||
dinahs[dynIndex].count = ((short)who->data.h.delay * 6) / kTicksPerFrame;
|
||||
dinahs[dynIndex].frame = 3;
|
||||
dinahs[dynIndex].timer = dinahs[dynIndex].count;
|
||||
dinahs[dynIndex].room = room;
|
||||
dinahs[dynIndex].byte0 = (Byte)index;
|
||||
dinahs[dynIndex].byte1 = 0;
|
||||
dinahs[dynIndex].moving = false;
|
||||
dinahs[dynIndex].active = isOn;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kFish:
|
||||
{
|
||||
short baselineDelta = 0;
|
||||
|
||||
if (keepExisting)
|
||||
baselineDelta = dinahs[dynIndex].dest.bottom - dinahs[dynIndex].position;
|
||||
|
||||
dinahs[dynIndex].dest = fishSrc[0];
|
||||
QOffsetRect(&dinahs[dynIndex].dest,
|
||||
where->left + 10, where->top + 8 + baselineDelta);
|
||||
dinahs[dynIndex].whole = dinahs[dynIndex].dest;
|
||||
|
||||
if (!keepExisting)
|
||||
{
|
||||
dinahs[dynIndex].position = dinahs[dynIndex].dest.bottom;
|
||||
|
||||
dinahs[dynIndex].hVel = ((short)who->data.h.delay * 6) / kTicksPerFrame;
|
||||
position = who->data.g.height; // reverse engineer init. vel.
|
||||
velocity = 0;
|
||||
evenFrame = true;
|
||||
lilFrame = true;
|
||||
do
|
||||
{
|
||||
if (lilFrame)
|
||||
velocity++;
|
||||
lilFrame = !lilFrame;
|
||||
position -= velocity;
|
||||
} while (position > 0);
|
||||
dinahs[dynIndex].vVel = -velocity;
|
||||
dinahs[dynIndex].count = -velocity; // count = initial velocity
|
||||
dinahs[dynIndex].frame = 0;
|
||||
dinahs[dynIndex].timer = dinahs[dynIndex].hVel;
|
||||
dinahs[dynIndex].room = room;
|
||||
dinahs[dynIndex].byte0 = (Byte)index;
|
||||
dinahs[dynIndex].byte1 = 0;
|
||||
dinahs[dynIndex].moving = false;
|
||||
dinahs[dynIndex].active = isOn;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return dynIndex;
|
||||
}
|
||||
|
@@ -8,12 +8,16 @@
|
||||
|
||||
#include "PLResources.h"
|
||||
#include "PLPasStr.h"
|
||||
#include "DisplayDeviceManager.h"
|
||||
#include "Externs.h"
|
||||
#include "Environ.h"
|
||||
#include "HostDisplayDriver.h"
|
||||
#include "HostSystemServices.h"
|
||||
#include "MenuManager.h"
|
||||
#include "IGpDisplayDriver.h"
|
||||
#include "WindowManager.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#define kSwitchDepthAlert 130
|
||||
#define kSetMemoryAlert 180
|
||||
@@ -272,6 +276,30 @@ short HowManyUsableScreens (Boolean use1Bit, Boolean use4Bit, Boolean use8Bit)
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- FlushResolutionChange
|
||||
void FlushResolutionChange(void)
|
||||
{
|
||||
if (thisMac.isResolutionDirty)
|
||||
{
|
||||
GetDeviceRect(&thisMac.fullScreen);
|
||||
thisMac.constrainedScreen = thisMac.fullScreen;
|
||||
if (thisMac.constrainedScreen.Width() > kMaxViewWidth)
|
||||
{
|
||||
thisMac.constrainedScreen.left = 0;
|
||||
thisMac.constrainedScreen.right = kMaxViewWidth;
|
||||
}
|
||||
if (thisMac.constrainedScreen.Height() > kMaxViewHeight)
|
||||
{
|
||||
thisMac.constrainedScreen.top = 0;
|
||||
thisMac.constrainedScreen.bottom = kMaxViewHeight;
|
||||
}
|
||||
|
||||
thisMac.gray = thisMac.fullScreen;
|
||||
thisMac.gray.top = 20;
|
||||
thisMac.isResolutionDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- CheckOurEnvirons
|
||||
// Calls all the above functions in order to fill out a sort of "spec sheet"<22>
|
||||
// for the current Mac.
|
||||
@@ -293,10 +321,65 @@ void CheckOurEnvirons (void)
|
||||
thisMac.can4Bit = true;
|
||||
thisMac.can8Bit = true;
|
||||
thisMac.numScreens = HowManyUsableScreens(false, true, true);
|
||||
GetDeviceRect(&thisMac.screen);
|
||||
|
||||
thisMac.wasDepth = WhatsOurDepth();
|
||||
thisMac.wasColorOrGray = AreWeColorOrGrayscale();
|
||||
|
||||
thisMac.isResolutionDirty = true;
|
||||
FlushResolutionChange();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- HandleResolutionChange
|
||||
// Installs handler
|
||||
void HandleResolutionChange(uint32_t prevWidth, uint32_t prevHeight, uint32_t newWidth, uint32_t newHeight)
|
||||
{
|
||||
PortabilityLayer::WindowManager::GetInstance()->HandleScreenResolutionChange(prevWidth, prevHeight, newWidth, newHeight);
|
||||
PortabilityLayer::MenuManager::GetInstance()->DrawMenuBar();
|
||||
thisMac.isResolutionDirty = true; // Because of legacy code, we don't want to update thisMac.screen immediately, but rather, let the editor or game pick it up
|
||||
}
|
||||
|
||||
class GpAppResolutionChangeHandler final : public PortabilityLayer::DisplayDeviceManager::IResolutionChangeHandler
|
||||
{
|
||||
public:
|
||||
void OnResolutionChanged(uint32_t prevWidth, uint32_t prevHeight, uint32_t newWidth, uint32_t newHeight) override
|
||||
{
|
||||
HandleResolutionChange(prevWidth, prevHeight, newWidth, newHeight);
|
||||
}
|
||||
|
||||
void AdjustRequestedResolution(uint32_t &physicalWidth, uint32_t &physicalHeight, uint32_t &virtualWidth, uint32_t &virtualHeight, float &pixelScaleX, float &pixelScaleY) override
|
||||
{
|
||||
if (physicalWidth < 640)
|
||||
physicalWidth = 640;
|
||||
|
||||
if (physicalHeight < 480)
|
||||
physicalHeight = 480;
|
||||
|
||||
double xMul = static_cast<double>(physicalWidth) / 640;
|
||||
double yMul = static_cast<double>(physicalHeight) / 480;
|
||||
|
||||
double granularity = 2.0;
|
||||
|
||||
xMul = floor(xMul * granularity) / granularity;
|
||||
yMul = floor(yMul * granularity) / granularity;
|
||||
|
||||
double minMul = std::max<double>(1.0, std::min(xMul, yMul));
|
||||
|
||||
virtualWidth = physicalWidth / minMul;
|
||||
virtualHeight = physicalHeight / minMul;
|
||||
pixelScaleX = static_cast<float>(minMul);
|
||||
pixelScaleY = static_cast<float>(minMul);
|
||||
}
|
||||
|
||||
static GpAppResolutionChangeHandler ms_instance;
|
||||
};
|
||||
|
||||
GpAppResolutionChangeHandler GpAppResolutionChangeHandler::ms_instance;
|
||||
|
||||
//-------------------------------------------------------------- InstallResolutionHandler
|
||||
// Installs handler
|
||||
void InstallResolutionHandler(void)
|
||||
{
|
||||
PortabilityLayer::DisplayDeviceManager::GetInstance()->SetResolutionChangeHandler(&GpAppResolutionChangeHandler::ms_instance);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- ReflectMonitor2Environs
|
||||
@@ -410,7 +493,7 @@ void CheckMemorySize (void)
|
||||
RedAlert(kErrNoMemory);
|
||||
else
|
||||
bytesNeeded += musicBytes;
|
||||
bytesNeeded += 4L * (long)thisMac.screen.bottom; // main screen
|
||||
bytesNeeded += 4L * (long)thisMac.constrainedScreen.bottom; // main screen
|
||||
bytesNeeded += (((long)houseRect.right - (long)houseRect.left) *
|
||||
((long)houseRect.bottom + 1 - (long)houseRect.top) *
|
||||
(long)thisMac.isDepth) / 8L; // work map
|
||||
|
@@ -10,7 +10,7 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Rect screen, gray;
|
||||
Rect fullScreen, constrainedScreen, gray;
|
||||
long dirID;
|
||||
short wasDepth, isDepth;
|
||||
short numScreens;
|
||||
@@ -28,9 +28,10 @@ typedef struct
|
||||
Boolean hasSM3;
|
||||
Boolean hasQT;
|
||||
Boolean hasDrag;
|
||||
Boolean isResolutionDirty;
|
||||
} macEnviron;
|
||||
|
||||
|
||||
extern macEnviron thisMac;
|
||||
|
||||
|
||||
void FlushResolutionChange(void);
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#include "House.h"
|
||||
#include "InputManager.h"
|
||||
#include "ObjectEdit.h"
|
||||
#include "Rect2i.h"
|
||||
#include "WindowManager.h"
|
||||
|
||||
|
||||
@@ -30,6 +31,7 @@ void HandleIdleTask (void);
|
||||
void IncrementMode (void);
|
||||
|
||||
|
||||
|
||||
long lastUp, incrementModeTime;
|
||||
UInt32 doubleTime;
|
||||
Point lastWhere;
|
||||
@@ -81,7 +83,7 @@ void HandleMouseEvent (const GpMouseInputEvent &theEvent, uint32_t tick)
|
||||
break;
|
||||
|
||||
case RegionIDs::kTitleBar:
|
||||
PortabilityLayer::WindowManager::GetInstance()->DragWindow(whichWindow, evtPoint, thisMac.screen);
|
||||
PortabilityLayer::WindowManager::GetInstance()->DragWindow(whichWindow, evtPoint, thisMac.fullScreen);
|
||||
if (whichWindow == mainWindow)
|
||||
GetWindowLeftTop(whichWindow, &isEditH, &isEditV);
|
||||
else if (whichWindow == mapWindow)
|
||||
@@ -349,11 +351,6 @@ void HandleUpdateEvent (EventRecord *theEvent)
|
||||
UpdateCoordWindow();
|
||||
EndUpdate(coordWindow);
|
||||
}
|
||||
else if ((WindowPtr)theEvent->message == menuWindow)
|
||||
{
|
||||
UpdateMenuBarWindow(menuWindow->GetDrawSurface());
|
||||
EndUpdate(menuWindow);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- HandleOSEvent
|
||||
@@ -426,6 +423,68 @@ void HandleHighLevelEvent (EventRecord *theEvent)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//-------------------------------------------------------------- HandleSplashResolutionChange
|
||||
void HandleSplashResolutionChange(void)
|
||||
{
|
||||
FlushResolutionChange();
|
||||
|
||||
RecomputeInterfaceRects();
|
||||
RecreateOffscreens();
|
||||
CloseMainWindow();
|
||||
OpenMainWindow();
|
||||
|
||||
UpdateMainWindow();
|
||||
|
||||
//ResetLocale(true);
|
||||
InitScoreboardMap();
|
||||
//RefreshScoreboard(wasScoreboardTitleMode);
|
||||
//DumpScreenOn(&justRoomsRect);
|
||||
}
|
||||
|
||||
void KeepWindowInBounds(Window *window)
|
||||
{
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
PortabilityLayer::Rect2i windowRect = PortabilityLayer::WindowManager::GetInstance()->GetWindowFullRect(window);
|
||||
|
||||
int32_t topNudge = std::max<int32_t>(kScoreboardTall - windowRect.Top(), 0);
|
||||
int32_t bottomNudge = std::min<int32_t>(thisMac.fullScreen.bottom - windowRect.Bottom(), 0);
|
||||
int32_t leftNudge = std::max<int32_t>(-windowRect.Left(), 0);
|
||||
int32_t rightNudge = std::min<int32_t>(thisMac.fullScreen.right - windowRect.Right(), 0);
|
||||
|
||||
window->m_wmX += leftNudge + rightNudge;
|
||||
window->m_wmY += topNudge + bottomNudge;
|
||||
}
|
||||
|
||||
void HandleEditorResolutionChange(void)
|
||||
{
|
||||
FlushResolutionChange();
|
||||
|
||||
RecomputeInterfaceRects();
|
||||
RecreateOffscreens();
|
||||
CloseMainWindow();
|
||||
OpenMainWindow();
|
||||
|
||||
UpdateMainWindow();
|
||||
|
||||
//ResetLocale(true);
|
||||
InitScoreboardMap();
|
||||
//RefreshScoreboard(wasScoreboardTitleMode);
|
||||
//DumpScreenOn(&justRoomsRect);
|
||||
|
||||
if (toolsWindow)
|
||||
PortabilityLayer::WindowManager::GetInstance()->PutWindowBehind(toolsWindow, PortabilityLayer::WindowManager::GetInstance()->GetPutInFrontSentinel());
|
||||
|
||||
if (mapWindow)
|
||||
PortabilityLayer::WindowManager::GetInstance()->PutWindowBehind(mapWindow, PortabilityLayer::WindowManager::GetInstance()->GetPutInFrontSentinel());
|
||||
|
||||
KeepWindowInBounds(mainWindow);
|
||||
KeepWindowInBounds(toolsWindow);
|
||||
KeepWindowInBounds(mapWindow);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- HandleIdleTask
|
||||
// Handle some processing during event lulls.
|
||||
|
||||
@@ -433,6 +492,11 @@ void HandleIdleTask (void)
|
||||
{
|
||||
if (theMode == kEditMode)
|
||||
{
|
||||
if (thisMac.isResolutionDirty)
|
||||
{
|
||||
HandleEditorResolutionChange();
|
||||
}
|
||||
|
||||
SetPort(&mainWindow->GetDrawSurface()->m_port);
|
||||
DoMarquee();
|
||||
|
||||
@@ -443,6 +507,14 @@ void HandleIdleTask (void)
|
||||
newRoomNow = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (theMode == kSplashMode)
|
||||
{
|
||||
if (thisMac.isResolutionDirty)
|
||||
{
|
||||
HandleSplashResolutionChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- HandleEvent
|
||||
|
@@ -167,6 +167,7 @@ void IgnoreThisClick (void);
|
||||
short WhatsOurDepth (void); // --- Environs.c
|
||||
void SwitchToDepth (short, Boolean);
|
||||
void CheckOurEnvirons (void);
|
||||
void InstallResolutionHandler (void);
|
||||
//void ReflectSecondMonitorEnvirons (Boolean, Boolean, Boolean);
|
||||
void HandleDepthSwitching (void);
|
||||
void RestoreColorDepth (void);
|
||||
|
@@ -102,10 +102,10 @@ void SetUpFinalScreen (void)
|
||||
do
|
||||
{
|
||||
GetLineOfText(tempStr, count, subStr);
|
||||
offset = ((thisMac.screen.right - thisMac.screen.left) -
|
||||
surface->MeasureString(subStr)) / 2;
|
||||
|
||||
surface->SetApplicationFont(12, PortabilityLayer::FontFamilyFlag_Bold);
|
||||
offset = ((thisMac.constrainedScreen.right - thisMac.constrainedScreen.left) -
|
||||
surface->MeasureString(subStr)) / 2;
|
||||
|
||||
surface->SetForeColor(PortabilityLayer::RGBAColor::Create(0, 0, 0, 255));
|
||||
const Point textShadowPos = Point::Create(offset + 1, textDown + 33 + (count * 20));
|
||||
@@ -146,6 +146,12 @@ void DoGameOverStarAnimation (void)
|
||||
long nextLoop;
|
||||
short which, i, count, pass;
|
||||
Boolean noInteruption;
|
||||
|
||||
short starFallSpeed = kStarFalls;
|
||||
const int kStarSpacing = 32;
|
||||
const int kAngelSpeed = 2;
|
||||
const int kStarsReserved = 5;
|
||||
const int kMaxFramesAlive = (kStarSpacing * kStarsReserved + kAngelSpeed - 1) / kAngelSpeed;
|
||||
|
||||
angelDest = angelSrcRect;
|
||||
QOffsetRect(&angelDest, -96, 0);
|
||||
@@ -154,14 +160,19 @@ void DoGameOverStarAnimation (void)
|
||||
count = 0;
|
||||
pass = 0;
|
||||
FlushEvents(everyEvent, 0);
|
||||
|
||||
if (workSrcRect.bottom - angelDest.bottom > kMaxFramesAlive * starFallSpeed)
|
||||
starFallSpeed = (workSrcRect.bottom - angelDest.bottom + kMaxFramesAlive - 1) / kMaxFramesAlive;
|
||||
|
||||
while (noInteruption)
|
||||
{
|
||||
if ((angelDest.left % 32) == 0) // add a star
|
||||
if ((angelDest.left % kStarSpacing) == 0) // add a star
|
||||
{
|
||||
PlayPrioritySound(kMysticSound, kMysticPriority);
|
||||
which = angelDest.left / 32;
|
||||
which = which % 5;
|
||||
which = angelDest.left / kStarSpacing;
|
||||
which = which % kStarsReserved;
|
||||
if (which < 0)
|
||||
which += kStarsReserved;
|
||||
ZeroRectCorner(&pages[which].dest);
|
||||
QOffsetRect(&pages[which].dest, angelDest.left, angelDest.bottom);
|
||||
if (count < (which + 1))
|
||||
@@ -182,13 +193,13 @@ void DoGameOverStarAnimation (void)
|
||||
&pages[i].dest);
|
||||
|
||||
pages[i].was = pages[i].dest;
|
||||
pages[i].was.top -= kStarFalls;
|
||||
pages[i].was.top -= starFallSpeed;
|
||||
|
||||
AddRectToWorkRectsWhole(&pages[i].was);
|
||||
AddRectToBackRects(&pages[i].dest);
|
||||
|
||||
if (pages[i].dest.top < workSrcRect.bottom)
|
||||
QOffsetRect(&pages[i].dest, 0, kStarFalls);
|
||||
QOffsetRect(&pages[i].dest, 0, starFallSpeed);
|
||||
}
|
||||
|
||||
if (angelDest.left <= (workSrcRect.right + 2))
|
||||
@@ -197,11 +208,11 @@ void DoGameOverStarAnimation (void)
|
||||
(BitMap *)*GetGWorldPixMap(angelMaskMap),
|
||||
(BitMap *)*GetGWorldPixMap(workSrcMap),
|
||||
&angelSrcRect, &angelSrcRect, &angelDest);
|
||||
angelDest.left -= 2;
|
||||
angelDest.left -= kAngelSpeed;
|
||||
AddRectToWorkRectsWhole(&angelDest);
|
||||
angelDest.left += 2;
|
||||
angelDest.left += kAngelSpeed;
|
||||
AddRectToBackRects(&angelDest);
|
||||
QOffsetRect(&angelDest, 2, 0);
|
||||
QOffsetRect(&angelDest, kAngelSpeed, 0);
|
||||
pass = 0;
|
||||
}
|
||||
|
||||
@@ -283,14 +294,14 @@ void InitDiedGameOver (void)
|
||||
for (i = 0; i < 8; i++) // initialize dest page rects
|
||||
{
|
||||
QSetRect(&pages[i].dest, 0, 0, 32, 32);
|
||||
CenterRectInRect(&pages[i].dest, &thisMac.screen);
|
||||
QOffsetRect(&pages[i].dest, -thisMac.screen.left, -thisMac.screen.top);
|
||||
CenterRectInRect(&pages[i].dest, &thisMac.constrainedScreen);
|
||||
QOffsetRect(&pages[i].dest, -thisMac.constrainedScreen.left, -thisMac.constrainedScreen.top);
|
||||
if (i < 4)
|
||||
QOffsetRect(&pages[i].dest, -kPageSpacing * (4 - i), 0);
|
||||
else
|
||||
QOffsetRect(&pages[i].dest, kPageSpacing * (i - 3), 0);
|
||||
QOffsetRect(&pages[i].dest, (thisMac.screen.right - thisMac.screen.left) / -2,
|
||||
(thisMac.screen.right - thisMac.screen.left) / -2);
|
||||
QOffsetRect(&pages[i].dest, (thisMac.constrainedScreen.right - thisMac.constrainedScreen.left) / -2,
|
||||
(thisMac.constrainedScreen.right - thisMac.constrainedScreen.left) / -2);
|
||||
if (pages[i].dest.left % 2 == 1)
|
||||
QOffsetRect(&pages[i].dest, 1, 0);
|
||||
pages[i].was = pages[i].dest;
|
||||
@@ -306,7 +317,7 @@ void InitDiedGameOver (void)
|
||||
}
|
||||
|
||||
pagesStuck = 0;
|
||||
stopPages = ((thisMac.screen.bottom - thisMac.screen.top) / 2) - 16;
|
||||
stopPages = ((thisMac.constrainedScreen.bottom - thisMac.constrainedScreen.top) / 2) - 16;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- HandlePages
|
||||
|
@@ -265,7 +265,7 @@
|
||||
#define kMaxDynamicObs 18
|
||||
#define kMaxMasterObjects 216 // kMaxRoomObs * 9
|
||||
#define kMaxViewWidth 1536
|
||||
#define kMaxViewHeight 1026
|
||||
#define kMaxViewHeight (kTileHigh*3+20)
|
||||
|
||||
#define kSelectTool 0
|
||||
|
||||
@@ -510,8 +510,6 @@
|
||||
#define kNoCeilingLimit -10
|
||||
#define kNoFloorLimit 332
|
||||
|
||||
#define kScoreboardHigh 0
|
||||
#define kScoreboardLow 1
|
||||
#define kScoreboardTall 20
|
||||
|
||||
#define kHouseVersion 0x0200
|
||||
@@ -623,3 +621,10 @@ static const Boolean kFaceLeft = FALSE; // Conflicts with GP input driver
|
||||
#define kDemoLength 6702
|
||||
|
||||
#define kGamepadDeadzone 4096 // Out of 32768
|
||||
|
||||
#define kDefaultComponent 0
|
||||
#define kCandleFlameComponent 1
|
||||
#define kTikiFlamesComponent 1
|
||||
#define kBBQCoalsComponent 1
|
||||
#define kPendulumComponent 1
|
||||
#define kStarComponent 1
|
||||
|
@@ -23,26 +23,28 @@ void CloseCoordWindow (void);
|
||||
void ToggleCoordinateWindow (void);
|
||||
|
||||
void NilSavedMaps (void); // --- DynamicMaps.c
|
||||
SInt16 BackUpToSavedMap (Rect *, SInt16, SInt16);
|
||||
SInt16 ReBackUpSavedMap (Rect *, SInt16, SInt16);
|
||||
void RestoreFromSavedMap (SInt16, SInt16, Boolean);
|
||||
SInt16 BackUpToSavedMap (Rect *theRect, SInt16 where, SInt16 who, SInt16 component);
|
||||
SInt16 ReBackUpSavedMap (Rect *theRect, SInt16 where, SInt16 who, SInt16 component);
|
||||
SInt16 RemoveFromSavedMap(SInt16);
|
||||
void RestoreFromSavedMap (SInt16 where, SInt16 who, SInt16 component, Boolean doSparkle);
|
||||
void AddSparkle (Rect *);
|
||||
void AddFlyingPoint (Rect *, SInt16, SInt16, SInt16);
|
||||
void ReBackUpFlames (SInt16, SInt16);
|
||||
Boolean ReBackUpFlames (SInt16, SInt16, SInt16, SInt16);
|
||||
void AddCandleFlame (SInt16, SInt16, SInt16, SInt16);
|
||||
void ReBackUpTikiFlames (SInt16, SInt16);
|
||||
Boolean ReBackUpTikiFlames (SInt16, SInt16, SInt16, SInt16);
|
||||
void AddTikiFlame (SInt16, SInt16, SInt16, SInt16);
|
||||
void ReBackUpBBQCoals (SInt16, SInt16);
|
||||
Boolean ReBackUpBBQCoals (SInt16, SInt16, SInt16, SInt16);
|
||||
void AddBBQCoals (SInt16, SInt16, SInt16, SInt16);
|
||||
void ReBackUpPendulum (SInt16, SInt16);
|
||||
Boolean ReBackUpPendulum (SInt16, SInt16, SInt16, SInt16);
|
||||
void AddPendulum (SInt16, SInt16, SInt16, SInt16);
|
||||
void ReBackUpStar (SInt16, SInt16);
|
||||
void ReBackUpStar (SInt16, SInt16, SInt16, SInt16);
|
||||
void AddStar (SInt16, SInt16, SInt16, SInt16);
|
||||
void StopPendulum (SInt16, SInt16);
|
||||
void StopStar (SInt16, SInt16);
|
||||
void AddAShreddedGlider (Rect *);
|
||||
void RemoveShreds (void);
|
||||
void ZeroFlamesAndTheLike (void);
|
||||
void RemoveSavedMapsNotInRoom (SInt16);
|
||||
|
||||
void CheckDynamicCollision (SInt16, gliderPtr, Boolean); // --- Dynamics.c
|
||||
Boolean DidBandHitDynamic (SInt16);
|
||||
@@ -73,17 +75,21 @@ void HandleFish (SInt16);
|
||||
void HandleDynamics (void); // --- Dynamics3.c
|
||||
void RenderDynamics (void);
|
||||
void ZeroDinahs (void);
|
||||
SInt16 AddDynamicObject (SInt16, Rect *, objectType *, SInt16, SInt16, Boolean);
|
||||
void ZeroDinahsNotInRoom (SInt16);
|
||||
|
||||
SInt16 AddDynamicObject(SInt16 what, Rect *where, objectType *who, SInt16 room, SInt16 index, Boolean isOn, Boolean keepExisting);
|
||||
|
||||
void DoGameOver (void); // --- GameOver.c
|
||||
void FlagGameOver (void);
|
||||
void DoDiedGameOver (void);
|
||||
|
||||
void HandleGrease (void); // --- Grease.c
|
||||
SInt16 ReBackUpGrease (SInt16, SInt16);
|
||||
SInt16 ReBackUpGrease (SInt16 where, SInt16 who, SInt16 h, SInt16 v);
|
||||
SInt16 AddGrease (SInt16, SInt16, SInt16, SInt16, SInt16, Boolean);
|
||||
void SpillGrease (SInt16, SInt16);
|
||||
void RedrawAllGrease (void);
|
||||
void FixupFallenGrease(SInt16 where, SInt16 who, SInt16 h, SInt16 v, Boolean *isDynamic);
|
||||
void RemapGreaseSavedMap(SInt16 removedItem, SInt16 substituteItem);
|
||||
|
||||
void DoHighScores (void); // --- HighScores.c
|
||||
void SortHighScores (void);
|
||||
@@ -132,6 +138,7 @@ void FlagStillOvers (gliderPtr);
|
||||
|
||||
void InitializeMenus (void); // --- InterfaceInit.c
|
||||
void GetExtraCursors (void);
|
||||
void RecomputeInterfaceRects (void);
|
||||
void VariableInit (void);
|
||||
|
||||
void GetDemoInput (gliderPtr); // --- Input.c
|
||||
@@ -147,7 +154,6 @@ void HandleLinkClick (Point);
|
||||
|
||||
void RedrawSplashScreen (void); // --- MainWindow.c
|
||||
void UpdateMainWindow (void);
|
||||
void UpdateMenuBarWindow (DrawSurface *surface);
|
||||
void OpenMainWindow (void);
|
||||
void CloseMainWindow (void);
|
||||
void ZoomBetweenWindows (void);
|
||||
@@ -257,8 +263,8 @@ void DrawBlueClock (Rect *);
|
||||
void DrawYellowClock (Rect *);
|
||||
void DrawCuckoo (Rect *);
|
||||
void DrawSimplePrizes (SInt16, Rect *);
|
||||
void DrawGreaseRt (Rect *, SInt16, Boolean);
|
||||
void DrawGreaseLf (Rect *, SInt16, Boolean);
|
||||
void DrawGreaseRt (Rect *, SInt16, Boolean, Boolean);
|
||||
void DrawGreaseLf (Rect *, SInt16, Boolean, Boolean);
|
||||
void DrawFoil (Rect *);
|
||||
void DrawInvisBonus (Rect *);
|
||||
void DrawSlider (Rect *);
|
||||
@@ -407,7 +413,8 @@ Boolean DoesRoomHaveFloor (void);
|
||||
Boolean DoesRoomHaveCeiling (void);
|
||||
|
||||
void ReadyLevel (void); // --- RoomGraphics.c
|
||||
void DrawLocale (void);
|
||||
void ResetLocale (Boolean soft);
|
||||
void DrawLocale (Boolean soft);
|
||||
void RedrawRoomLighting (void);
|
||||
|
||||
Boolean PictIDExists (SInt16); // --- RoomInfo.c
|
||||
@@ -428,8 +435,6 @@ void QuickBatteryRefresh (Boolean);
|
||||
void QuickBandsRefresh (Boolean);
|
||||
void QuickFoilRefresh (Boolean);
|
||||
void HandleScore (void);
|
||||
void AdjustScoreboardHeight (void);
|
||||
void BlackenScoreboard (DrawSurface *);
|
||||
|
||||
//void PutRoomScrap (void); // --- Scrap.c
|
||||
//void PutObjectScrap (void);
|
||||
@@ -470,6 +475,7 @@ void InitEnemies (void);
|
||||
void CreateOffscreens (void); // --- StructuresInit2.c
|
||||
void CreatePointers (void);
|
||||
void InitSrcRects (void);
|
||||
PLError_t RecreateOffscreens (void);
|
||||
|
||||
void UpdateToolsWindow (void); // --- Tools.c
|
||||
void EraseSelectedTool (void);
|
||||
|
@@ -241,6 +241,7 @@ typedef struct
|
||||
DrawSurface *map;
|
||||
short where;
|
||||
short who;
|
||||
short component;
|
||||
} savedType, *savedPtr;
|
||||
|
||||
typedef struct
|
||||
|
@@ -25,6 +25,7 @@ public:
|
||||
void PL_HostFontHandler_SetInstance(PortabilityLayer::HostFontHandler *instance) override;
|
||||
void PL_HostVOSEventQueue_SetInstance(PortabilityLayer::HostVOSEventQueue *instance) override;
|
||||
void PL_InstallHostSuspendHook(PortabilityLayer::HostSuspendHook_t hook, void *context) override;
|
||||
bool PL_AdjustRequestedResolution(uint32_t &physicalWidth, uint32_t &physicalHeight, uint32_t &virtualWidth, uint32_t &virtualheight, float &pixelScaleX, float &pixelScaleY) override;
|
||||
};
|
||||
|
||||
|
||||
@@ -79,6 +80,19 @@ void GpAppInterfaceImpl::PL_InstallHostSuspendHook(PortabilityLayer::HostSuspend
|
||||
PortabilityLayer::InstallHostSuspendHook(hook, context);
|
||||
}
|
||||
|
||||
bool GpAppInterfaceImpl::PL_AdjustRequestedResolution(uint32_t &physicalWidth, uint32_t &physicalHeight, uint32_t &virtualWidth, uint32_t &virtualheight, float &pixelScaleX, float &pixelScaleY)
|
||||
{
|
||||
PortabilityLayer::DisplayDeviceManager::IResolutionChangeHandler *handler = PortabilityLayer::DisplayDeviceManager::GetInstance()->GetResolutionChangeHandler();
|
||||
|
||||
if (!handler)
|
||||
return false;
|
||||
|
||||
handler->AdjustRequestedResolution(physicalWidth, physicalHeight, virtualWidth, virtualheight, pixelScaleX, pixelScaleY);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static GpAppInterfaceImpl gs_application;
|
||||
|
||||
|
||||
|
@@ -28,8 +28,7 @@ short numGrease;
|
||||
|
||||
extern hotPtr hotSpots;
|
||||
extern savedType savedMaps[];
|
||||
extern Point shieldPt;
|
||||
extern Rect greaseSrcRt[], greaseSrcLf[], shieldRect;
|
||||
extern Rect greaseSrcRt[], greaseSrcLf[];
|
||||
|
||||
|
||||
//============================================================== Functions
|
||||
@@ -168,7 +167,7 @@ void BackupGrease (Rect *src, short index, Boolean isRight)
|
||||
// off or on the lights). It assumes certain data strucutures are<72>
|
||||
// already declared from an earlier call to the above funciton.
|
||||
|
||||
short ReBackUpGrease (short where, short who)
|
||||
short ReBackUpGrease (short where, short who, short h, short v)
|
||||
{
|
||||
Rect src;
|
||||
short i;
|
||||
@@ -179,6 +178,13 @@ short ReBackUpGrease (short where, short who)
|
||||
{
|
||||
if ((grease[i].mode == kGreaseIdle) || (grease[i].mode == kGreaseFalling))
|
||||
{
|
||||
greasePtr greaseItem = &grease[i];
|
||||
const short hDelta = h - grease[i].dest.left;
|
||||
const short vDelta = v - grease[i].dest.top;
|
||||
QOffsetRect(&greaseItem->dest, hDelta, vDelta);
|
||||
greaseItem->start += hDelta;
|
||||
greaseItem->stop += hDelta;
|
||||
|
||||
src = grease[i].dest;
|
||||
BackupGrease(&src, grease[i].mapNum, grease[i].isRight);
|
||||
}
|
||||
@@ -207,7 +213,7 @@ short AddGrease (short where, short who, short h, short v,
|
||||
QOffsetRect(&src, h, v);
|
||||
|
||||
QSetRect(&bounds, 0, 0, 32, 27 * 4);
|
||||
savedNum = BackUpToSavedMap(&bounds, where, who);
|
||||
savedNum = BackUpToSavedMap(&bounds, where, who, kDefaultComponent);
|
||||
if (savedNum != -1)
|
||||
{
|
||||
BackupGrease (&src, savedNum, isRight);
|
||||
@@ -269,10 +275,12 @@ void RedrawAllGrease (void)
|
||||
|
||||
for (i = 0; i < numGrease; i++)
|
||||
{
|
||||
if (grease[i].mode == kGreaseIdle)
|
||||
continue;
|
||||
|
||||
src = hotSpots[grease[i].hotNum].bounds;
|
||||
if ((grease[i].where == thisRoomNumber) &&
|
||||
((src.bottom - src.top) == 2) &&
|
||||
(grease[i].mode != kGreaseIdle))
|
||||
((src.bottom - src.top) == 2))
|
||||
{
|
||||
QOffsetRect(&src, playOriginH, playOriginV);
|
||||
|
||||
@@ -288,3 +296,41 @@ void RedrawAllGrease (void)
|
||||
}
|
||||
}
|
||||
|
||||
void FixupFallenGrease(SInt16 where, SInt16 who, SInt16 h, SInt16 v, Boolean *isDynamic)
|
||||
{
|
||||
short i;
|
||||
|
||||
for (i = 0; i < numGrease; i++)
|
||||
{
|
||||
greasePtr greaseItem = grease + i;
|
||||
if ((greaseItem->where == where) && (greaseItem->who == who))
|
||||
{
|
||||
short hDelta = h - greaseItem->dest.left;
|
||||
short vDelta = v - greaseItem->dest.top;
|
||||
QOffsetRect(&greaseItem->dest, hDelta, vDelta);
|
||||
greaseItem->start += hDelta;
|
||||
greaseItem->stop += hDelta;
|
||||
if (greaseItem->mode != kGreaseIdle)
|
||||
{
|
||||
hotPtr hotSpot = &hotSpots[greaseItem->hotNum];
|
||||
//QOffsetRect(&hotSpot->bounds, hDelta, vDelta);
|
||||
}
|
||||
*isDynamic = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*isDynamic = false;
|
||||
}
|
||||
|
||||
void RemapGreaseSavedMap(SInt16 removedItem, SInt16 substituteItem)
|
||||
{
|
||||
for (int i = 0; i < numGrease; i++)
|
||||
{
|
||||
if (grease[i].mapNum == substituteItem)
|
||||
{
|
||||
grease[i].mapNum = removedItem;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include "IOStream.h"
|
||||
#include "MainWindow.h"
|
||||
#include "RectUtils.h"
|
||||
#include "PLStandardColors.h"
|
||||
#include "PLTimeTaggedVOSEvent.h"
|
||||
#include "Utilities.h"
|
||||
|
||||
@@ -70,6 +71,7 @@ void DoHighScores (void)
|
||||
|
||||
SpinCursor(3);
|
||||
SetPort(&workSrcMap->m_port);
|
||||
workSrcMap->SetForeColor(StdColors::Black());
|
||||
workSrcMap->FillRect(workSrcRect);
|
||||
QSetRect(&tempRect, 0, 0, 640, 480);
|
||||
QOffsetRect(&tempRect, splashOriginH, splashOriginV);
|
||||
@@ -123,7 +125,7 @@ void DrawHighScores (DrawSurface *surface)
|
||||
PortabilityLayer::RGBAColor whiteColor = PortabilityLayer::RGBAColor::Create(255, 255, 255, 255);
|
||||
PortabilityLayer::RGBAColor blueColor = PortabilityLayer::RGBAColor::Create(0, 0, 255, 255);
|
||||
|
||||
scoreLeft = ((thisMac.screen.right - thisMac.screen.left) - kScoreWide) / 2;
|
||||
scoreLeft = ((thisMac.constrainedScreen.right - thisMac.constrainedScreen.left) - kScoreWide) / 2;
|
||||
dropIt = 129 + splashOriginV;
|
||||
|
||||
QSetRect(&tempRect, 0, 0, 332, 30);
|
||||
|
@@ -769,7 +769,7 @@ void HandleRewards (gliderPtr thisGlider, hotPtr who)
|
||||
{
|
||||
PlayPrioritySound(kBeepsSound, kBeepsPriority);
|
||||
RestoreFromSavedMap(thisRoomNumber,
|
||||
masterObjects[whoLinked].objectNum, false);
|
||||
masterObjects[whoLinked].objectNum, kDefaultComponent, false);
|
||||
AddFlyingPoint(&bounds, 100, thisGlider->hVel / 2, thisGlider->vVel / 2);
|
||||
thisGlider->hVel /= 4;
|
||||
thisGlider->vVel /= 4;
|
||||
@@ -785,7 +785,7 @@ void HandleRewards (gliderPtr thisGlider, hotPtr who)
|
||||
{
|
||||
PlayPrioritySound(kBuzzerSound, kBuzzerPriority);
|
||||
RestoreFromSavedMap(thisRoomNumber,
|
||||
masterObjects[whoLinked].objectNum, false);
|
||||
masterObjects[whoLinked].objectNum, kDefaultComponent, false);
|
||||
AddFlyingPoint(&bounds, 300, thisGlider->hVel / 2, thisGlider->vVel / 2);
|
||||
thisGlider->hVel /= 4;
|
||||
thisGlider->vVel /= 4;
|
||||
@@ -801,7 +801,7 @@ void HandleRewards (gliderPtr thisGlider, hotPtr who)
|
||||
{
|
||||
PlayPrioritySound(kDingSound, kDingPriority);
|
||||
RestoreFromSavedMap(thisRoomNumber,
|
||||
masterObjects[whoLinked].objectNum, false);
|
||||
masterObjects[whoLinked].objectNum, kDefaultComponent, false);
|
||||
AddFlyingPoint(&bounds, 500, thisGlider->hVel / 2, thisGlider->vVel / 2);
|
||||
thisGlider->hVel /= 4;
|
||||
thisGlider->vVel /= 4;
|
||||
@@ -817,7 +817,7 @@ void HandleRewards (gliderPtr thisGlider, hotPtr who)
|
||||
{
|
||||
PlayPrioritySound(kCuckooSound, kCuckooPriority);
|
||||
RestoreFromSavedMap(thisRoomNumber,
|
||||
masterObjects[whoLinked].objectNum, false);
|
||||
masterObjects[whoLinked].objectNum, kDefaultComponent, false);
|
||||
StopPendulum(thisRoomNumber, masterObjects[whoLinked].objectNum);
|
||||
AddFlyingPoint(&bounds, 1000, thisGlider->hVel / 2, thisGlider->vVel / 2);
|
||||
thisGlider->hVel /= 4;
|
||||
@@ -834,7 +834,7 @@ void HandleRewards (gliderPtr thisGlider, hotPtr who)
|
||||
{
|
||||
PlayPrioritySound(kEnergizeSound, kEnergizePriority);
|
||||
RestoreFromSavedMap(thisRoomNumber,
|
||||
masterObjects[whoLinked].objectNum, false);
|
||||
masterObjects[whoLinked].objectNum, kDefaultComponent, false);
|
||||
AddSparkle(&bounds);
|
||||
thisGlider->hVel /= 2;
|
||||
thisGlider->vVel /= 2;
|
||||
@@ -853,7 +853,7 @@ void HandleRewards (gliderPtr thisGlider, hotPtr who)
|
||||
{
|
||||
PlayPrioritySound(kEnergizeSound, kEnergizePriority);
|
||||
RestoreFromSavedMap(thisRoomNumber,
|
||||
masterObjects[whoLinked].objectNum, false);
|
||||
masterObjects[whoLinked].objectNum, kDefaultComponent, false);
|
||||
AddSparkle(&bounds);
|
||||
thisGlider->hVel /= 2;
|
||||
thisGlider->vVel /= 2;
|
||||
@@ -875,7 +875,7 @@ void HandleRewards (gliderPtr thisGlider, hotPtr who)
|
||||
{
|
||||
PlayPrioritySound(kEnergizeSound, kEnergizePriority);
|
||||
RestoreFromSavedMap(thisRoomNumber,
|
||||
masterObjects[whoLinked].objectNum, false);
|
||||
masterObjects[whoLinked].objectNum, kDefaultComponent, false);
|
||||
AddSparkle(&bounds);
|
||||
thisGlider->hVel /= 2;
|
||||
thisGlider->vVel /= 2;
|
||||
@@ -903,7 +903,7 @@ void HandleRewards (gliderPtr thisGlider, hotPtr who)
|
||||
{
|
||||
PlayPrioritySound(kEnergizeSound, kEnergizePriority);
|
||||
RestoreFromSavedMap(thisRoomNumber,
|
||||
masterObjects[whoLinked].objectNum, false);
|
||||
masterObjects[whoLinked].objectNum, kDefaultComponent, false);
|
||||
AddSparkle(&bounds);
|
||||
thisGlider->hVel /= 2;
|
||||
thisGlider->vVel /= 2;
|
||||
@@ -936,7 +936,7 @@ void HandleRewards (gliderPtr thisGlider, hotPtr who)
|
||||
{
|
||||
PlayPrioritySound(kEnergizeSound, kEnergizePriority);
|
||||
RestoreFromSavedMap(thisRoomNumber,
|
||||
masterObjects[whoLinked].objectNum, false);
|
||||
masterObjects[whoLinked].objectNum, kDefaultComponent, false);
|
||||
AddSparkle(&bounds);
|
||||
StopStar(thisRoomNumber, masterObjects[whoLinked].objectNum);
|
||||
numStarsRemaining--;
|
||||
@@ -959,7 +959,7 @@ void HandleRewards (gliderPtr thisGlider, hotPtr who)
|
||||
{
|
||||
PlayPrioritySound(kEnergizeSound, kEnergizePriority);
|
||||
RestoreFromSavedMap(thisRoomNumber,
|
||||
masterObjects[whoLinked].objectNum, false);
|
||||
masterObjects[whoLinked].objectNum, kDefaultComponent, false);
|
||||
AddSparkle(&bounds);
|
||||
thisGlider->hVel /= 2;
|
||||
thisGlider->vVel /= 2;
|
||||
@@ -1050,12 +1050,12 @@ void HandleSwitches (hotPtr who)
|
||||
case kFoil:
|
||||
case kStar:
|
||||
case kHelium:
|
||||
RestoreFromSavedMap(roomLinked, objectLinked, true);
|
||||
RestoreFromSavedMap(roomLinked, objectLinked, kDefaultComponent, true);
|
||||
AddSparkle(&bounds);
|
||||
break;
|
||||
|
||||
case kCuckoo:
|
||||
RestoreFromSavedMap(roomLinked, objectLinked, true);
|
||||
RestoreFromSavedMap(roomLinked, objectLinked, kDefaultComponent, true);
|
||||
StopPendulum(roomLinked, objectLinked);
|
||||
break;
|
||||
|
||||
|
@@ -26,12 +26,10 @@ struct IGpCursor;
|
||||
|
||||
extern THandle<Rect> mirrorRects;
|
||||
extern WindowPtr mapWindow, toolsWindow, linkWindow;
|
||||
extern WindowPtr menuWindow;
|
||||
extern Rect shieldRect, boardSrcRect, localRoomsDest[];
|
||||
extern Rect boardSrcRect, localRoomsDest[];
|
||||
extern IGpCursor *handCursor, *vertCursor, *horiCursor;
|
||||
extern IGpCursor *diagCursor;
|
||||
extern MenuHandle appleMenu, gameMenu, optionsMenu, houseMenu;
|
||||
extern Point shieldPt;
|
||||
extern long incrementModeTime;
|
||||
extern UInt32 doubleTime;
|
||||
extern short fadeInSequence[], idleMode;
|
||||
@@ -99,6 +97,40 @@ void GetExtraCursors (void)
|
||||
RedAlert(kErrFailedResourceLoad);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- RecomputeScreenRects
|
||||
void RecomputeInterfaceRects (void)
|
||||
{
|
||||
houseRect = thisMac.constrainedScreen;
|
||||
houseRect.bottom -= kScoreboardTall;
|
||||
if (houseRect.right > kMaxViewWidth)
|
||||
houseRect.right = kMaxViewWidth;
|
||||
if (houseRect.bottom > kMaxViewHeight)
|
||||
houseRect.bottom = kMaxViewHeight;
|
||||
|
||||
// NOTE: This is actually buggy, since the visible area is houseRect, not screen.
|
||||
// We preserve the buggy behavior for authenticity unless the window is very tall.
|
||||
short poHeight = RectTall(&thisMac.constrainedScreen);
|
||||
if (poHeight > kMaxViewHeight - kScoreboardTall)
|
||||
poHeight = kMaxViewHeight - kScoreboardTall;
|
||||
|
||||
playOriginH = (RectWide(&thisMac.constrainedScreen) - kRoomWide) / 2;
|
||||
playOriginV = (poHeight - kTileHigh) / 2;
|
||||
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
QSetRect(&localRoomsDest[i], 0, 0, kRoomWide, kTileHigh);
|
||||
QOffsetRect(&localRoomsDest[i], playOriginH, playOriginV);
|
||||
}
|
||||
QOffsetRect(&localRoomsDest[kNorthRoom], 0, -kVertLocalOffset);
|
||||
QOffsetRect(&localRoomsDest[kNorthEastRoom], kRoomWide, -kVertLocalOffset);
|
||||
QOffsetRect(&localRoomsDest[kEastRoom], kRoomWide, 0);
|
||||
QOffsetRect(&localRoomsDest[kSouthEastRoom], kRoomWide, kVertLocalOffset);
|
||||
QOffsetRect(&localRoomsDest[kSouthRoom], 0, kVertLocalOffset);
|
||||
QOffsetRect(&localRoomsDest[kSouthWestRoom], -kRoomWide, kVertLocalOffset);
|
||||
QOffsetRect(&localRoomsDest[kWestRoom], -kRoomWide, 0);
|
||||
QOffsetRect(&localRoomsDest[kNorthWestRoom], -kRoomWide, -kVertLocalOffset);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- VariableInit
|
||||
|
||||
// All the simple interface variables are intialized here - Booleans,<2C>
|
||||
@@ -108,10 +140,6 @@ void VariableInit (void)
|
||||
{
|
||||
short i;
|
||||
|
||||
shieldPt.h = 0;
|
||||
shieldPt.v = 0;
|
||||
shieldRect = thisMac.screen;
|
||||
|
||||
menusUp = false;
|
||||
quitting = false;
|
||||
houseOpen = false;
|
||||
@@ -184,30 +212,6 @@ void VariableInit (void)
|
||||
coordWindow = nil;
|
||||
toolSrcMap = nil;
|
||||
nailSrcMap = nil;
|
||||
menuWindow = nil;
|
||||
|
||||
houseRect = thisMac.screen;
|
||||
houseRect.bottom -= kScoreboardTall;
|
||||
if (houseRect.right > kMaxViewWidth)
|
||||
houseRect.right = kMaxViewWidth;
|
||||
if (houseRect.bottom > kMaxViewHeight)
|
||||
houseRect.bottom = kMaxViewHeight;
|
||||
|
||||
playOriginH = (RectWide(&thisMac.screen) - kRoomWide) / 2;
|
||||
playOriginV = (RectTall(&thisMac.screen) - kTileHigh) / 2;
|
||||
|
||||
for (i = 0; i < 9; i++)
|
||||
{
|
||||
QSetRect(&localRoomsDest[i], 0, 0, kRoomWide, kTileHigh);
|
||||
QOffsetRect(&localRoomsDest[i], playOriginH, playOriginV);
|
||||
}
|
||||
QOffsetRect(&localRoomsDest[kNorthRoom], 0, -kVertLocalOffset);
|
||||
QOffsetRect(&localRoomsDest[kNorthEastRoom], kRoomWide, -kVertLocalOffset);
|
||||
QOffsetRect(&localRoomsDest[kEastRoom], kRoomWide, 0);
|
||||
QOffsetRect(&localRoomsDest[kSouthEastRoom], kRoomWide, kVertLocalOffset);
|
||||
QOffsetRect(&localRoomsDest[kSouthRoom], 0, kVertLocalOffset);
|
||||
QOffsetRect(&localRoomsDest[kSouthWestRoom], -kRoomWide, kVertLocalOffset);
|
||||
QOffsetRect(&localRoomsDest[kWestRoom], -kRoomWide, 0);
|
||||
QOffsetRect(&localRoomsDest[kNorthWestRoom], -kRoomWide, -kVertLocalOffset);
|
||||
RecomputeInterfaceRects();
|
||||
}
|
||||
|
||||
|
@@ -204,7 +204,7 @@ void ReadInPrefs (void)
|
||||
doBitchDialogs = true;
|
||||
}
|
||||
|
||||
if ((numNeighbors > 1) && (thisMac.screen.right <= 512))
|
||||
if ((numNeighbors > 1) && (thisMac.constrainedScreen.right <= 512))
|
||||
numNeighbors = 1;
|
||||
|
||||
UnivGetSoundVolume(&wasVolume, thisMac.hasSM3);
|
||||
@@ -315,6 +315,7 @@ int gpAppMain()
|
||||
|
||||
ToolBoxInit();
|
||||
CheckOurEnvirons();
|
||||
InstallResolutionHandler();
|
||||
if (!thisMac.hasColor)
|
||||
RedAlert(kErrNeedColorQD);
|
||||
if (!thisMac.hasSystem7)
|
||||
|
@@ -11,7 +11,9 @@
|
||||
#include "Externs.h"
|
||||
#include "Environ.h"
|
||||
#include "FontFamily.h"
|
||||
#include "HostDisplayDriver.h"
|
||||
#include "House.h"
|
||||
#include "IGpDisplayDriver.h"
|
||||
#include "InputManager.h"
|
||||
#include "MenuManager.h"
|
||||
#include "QDPixMap.h"
|
||||
@@ -30,7 +32,7 @@
|
||||
void DrawOnSplash (DrawSurface *surface);
|
||||
void SetPaletteToGrays (void);
|
||||
void HardDrawMainWindow (void);
|
||||
|
||||
void KeepWindowInBounds(Window *window);
|
||||
|
||||
CTabHandle theCTab;
|
||||
PixMapHandle thePMap;
|
||||
@@ -41,7 +43,7 @@ IGpCursor *diagCursor;
|
||||
Rect workSrcRect;
|
||||
DrawSurface *workSrcMap;
|
||||
Rect mainWindowRect;
|
||||
WindowPtr mainWindow, menuWindow, boardWindow;
|
||||
WindowPtr mainWindow, boardWindow;
|
||||
short isEditH, isEditV;
|
||||
short playOriginH, playOriginV;
|
||||
short splashOriginH, splashOriginV;
|
||||
@@ -165,22 +167,6 @@ void UpdateMainWindow (void)
|
||||
splashDrawn = true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- UpdateMenuBarWindow
|
||||
// Ugly kludge to cover over the menu bar when playing game on 2nd monitor.
|
||||
|
||||
void UpdateMenuBarWindow (DrawSurface *surface)
|
||||
{
|
||||
Rect bounds;
|
||||
|
||||
if (menuWindow == nil)
|
||||
return;
|
||||
|
||||
GetLocalWindowRect(menuWindow, &bounds);
|
||||
|
||||
surface->SetForeColor(StdColors::Black());
|
||||
surface->FillRect(bounds);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- OpenMainWindow
|
||||
// Opens up the main window (how it does this depends on mode were in).
|
||||
|
||||
@@ -197,10 +183,8 @@ void OpenMainWindow (void)
|
||||
|
||||
if (theMode == kEditMode)
|
||||
{
|
||||
if (menuWindow != nil)
|
||||
PortabilityLayer::WindowManager::GetInstance()->DestroyWindow(menuWindow);
|
||||
menuWindow = nil;
|
||||
|
||||
PortabilityLayer::HostDisplayDriver::GetInstance()->SetBackgroundColor(51, 51, 102, 255);
|
||||
|
||||
QSetRect(&mainWindowRect, 0, 0, 512, 322);
|
||||
mainWindow = GetNewCWindow(kEditWindowID, nil, kPutInFront);
|
||||
SizeWindow(mainWindow, mainWindowRect.right,
|
||||
@@ -223,22 +207,22 @@ void OpenMainWindow (void)
|
||||
whichRoom = GetFirstRoomNumber();
|
||||
CopyRoomToThisRoom(whichRoom);
|
||||
ReflectCurrentRoom(false);
|
||||
|
||||
KeepWindowInBounds(mainWindow);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (menuWindow == nil)
|
||||
{
|
||||
menuWindow = GetNewCWindow(kMenuWindowID, nil, kPutInFront);
|
||||
SizeWindow(menuWindow, RectWide(&thisMac.screen), 20, false);
|
||||
MoveWindow(menuWindow, thisMac.screen.left,
|
||||
thisMac.screen.top, true);
|
||||
ShowWindow(menuWindow);
|
||||
}
|
||||
#ifdef NDEBUG
|
||||
PortabilityLayer::HostDisplayDriver::GetInstance()->SetBackgroundColor(0, 0, 0, 255);
|
||||
#else
|
||||
PortabilityLayer::HostDisplayDriver::GetInstance()->SetBackgroundColor(51, 0, 0, 255);
|
||||
#endif
|
||||
|
||||
if (boardWindow == nil)
|
||||
{
|
||||
PortabilityLayer::WindowManager *windowManager = PortabilityLayer::WindowManager::GetInstance();
|
||||
|
||||
Rect scorebarRect = thisMac.screen;
|
||||
Rect scorebarRect = thisMac.constrainedScreen;
|
||||
scorebarRect.bottom = scorebarRect.top + kScoreboardTall;
|
||||
|
||||
PortabilityLayer::WindowDef windowDef = PortabilityLayer::WindowDef::Create(scorebarRect, PortabilityLayer::WindowStyleFlags::kBorderless, true, 0, 0, PSTR("Scoreboard"));
|
||||
@@ -248,14 +232,18 @@ void OpenMainWindow (void)
|
||||
else
|
||||
PL_NotYetImplemented_TODO("Errors");
|
||||
}
|
||||
mainWindowRect = thisMac.screen;
|
||||
mainWindowRect = thisMac.constrainedScreen;
|
||||
ZeroRectCorner(&mainWindowRect);
|
||||
mainWindowRect.bottom -= 20; // thisMac.menuHigh
|
||||
mainWindowRect.bottom -= kScoreboardTall; // thisMac.menuHigh
|
||||
mainWindow = GetNewCWindow(kMainWindowID, nil, kPutInFront);
|
||||
SizeWindow(mainWindow, mainWindowRect.right - mainWindowRect.left,
|
||||
mainWindowRect.bottom - mainWindowRect.top, false);
|
||||
MoveWindow(mainWindow, thisMac.screen.left,
|
||||
thisMac.screen.top + 20, true); // thisMac.menuHigh
|
||||
|
||||
const short mainWindowLeft = (thisMac.fullScreen.left + thisMac.fullScreen.right + thisMac.constrainedScreen.left - thisMac.constrainedScreen.right) / 2;
|
||||
const short mainWindowTop = (thisMac.fullScreen.top + thisMac.fullScreen.bottom + thisMac.constrainedScreen.top - thisMac.constrainedScreen.bottom) / 2 + kScoreboardTall;
|
||||
|
||||
MoveWindow(boardWindow, mainWindowLeft, 0, true);
|
||||
MoveWindow(mainWindow, mainWindowLeft, mainWindowTop, true); // thisMac.menuHigh
|
||||
ShowWindow(mainWindow);
|
||||
SetPortWindowPort(mainWindow);
|
||||
|
||||
@@ -267,15 +255,14 @@ void OpenMainWindow (void)
|
||||
mainWindowSurface->SetBackColor(StdColors::White());
|
||||
mainWindowSurface->FillRect(mainWindowRect);
|
||||
|
||||
splashOriginH = ((thisMac.screen.right - thisMac.screen.left) - 640) / 2;
|
||||
splashOriginH = ((thisMac.constrainedScreen.right - thisMac.constrainedScreen.left) - 640) / 2;
|
||||
if (splashOriginH < 0)
|
||||
splashOriginH = 0;
|
||||
splashOriginV = ((thisMac.screen.bottom - thisMac.screen.top) - 480) / 2;
|
||||
splashOriginV = ((thisMac.constrainedScreen.bottom - thisMac.constrainedScreen.top) - 480) / 2;
|
||||
if (splashOriginV < 0)
|
||||
splashOriginV = 0;
|
||||
|
||||
workSrcMap->FillRect(workSrcRect);
|
||||
LoadGraphic(workSrcMap, kSplash8BitPICT);
|
||||
|
||||
// if ((fadeGraysOut) && (isDoColorFade))
|
||||
// {
|
||||
@@ -288,6 +275,7 @@ void OpenMainWindow (void)
|
||||
// }
|
||||
|
||||
SetPortWindowPort(mainWindow);
|
||||
UpdateMainWindow();
|
||||
}
|
||||
|
||||
CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap),
|
||||
|
@@ -40,6 +40,7 @@ void LiveVScrollAction (ControlHandle, short);
|
||||
Boolean QueryNewRoom (void);
|
||||
void CreateNailOffscreen (void);
|
||||
void KillNailOffscreen (void);
|
||||
void KeepWindowInBounds (Window *window);
|
||||
|
||||
Rect nailSrcRect, activeRoomRect, wasActiveRoomRect;
|
||||
Rect mapHScrollRect, mapVScrollRect, mapCenterRect;
|
||||
@@ -430,6 +431,8 @@ void OpenMapWindow (void)
|
||||
CenterMapOnRoom(thisRoom->suite, thisRoom->floor);
|
||||
|
||||
UpdateMapWindow();
|
||||
|
||||
KeepWindowInBounds(mapWindow);
|
||||
}
|
||||
|
||||
UpdateMapCheckmark(true);
|
||||
|
@@ -1224,7 +1224,7 @@ void DrawSimplePrizes (short what, Rect *theRect)
|
||||
|
||||
//-------------------------------------------------------------- DrawGreaseRt
|
||||
|
||||
void DrawGreaseRt (Rect *theRect, short distance, Boolean state)
|
||||
void DrawGreaseRt (Rect *theRect, short distance, Boolean state, Boolean drawSpill)
|
||||
{
|
||||
Rect spill, dest;
|
||||
|
||||
@@ -1243,18 +1243,21 @@ void DrawGreaseRt (Rect *theRect, short distance, Boolean state)
|
||||
(BitMap *)*GetGWorldPixMap(bonusMaskMap),
|
||||
(BitMap *)*GetGWorldPixMap(backSrcMap),
|
||||
&greaseSrcRt[3], &greaseSrcRt[3], &dest);
|
||||
|
||||
QSetRect(&spill, 0, -2, distance - 5, 0);
|
||||
QOffsetRect(&spill, dest.right - 1, dest.bottom);
|
||||
|
||||
backSrcMap->SetForeColor(PortabilityLayer::RGBAColor::Create(0, 0, 0, 255));
|
||||
backSrcMap->FillRect(spill);
|
||||
if (drawSpill)
|
||||
{
|
||||
QSetRect(&spill, 0, -2, distance - 5, 0);
|
||||
QOffsetRect(&spill, dest.right - 1, dest.bottom);
|
||||
|
||||
backSrcMap->SetForeColor(PortabilityLayer::RGBAColor::Create(0, 0, 0, 255));
|
||||
backSrcMap->FillRect(spill);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- DrawGreaseLf
|
||||
|
||||
void DrawGreaseLf (Rect *theRect, short distance, Boolean state)
|
||||
void DrawGreaseLf (Rect *theRect, short distance, Boolean state, Boolean drawSpill)
|
||||
{
|
||||
Rect spill, dest;
|
||||
DrawSurface *wasCPort;
|
||||
@@ -1275,11 +1278,14 @@ void DrawGreaseLf (Rect *theRect, short distance, Boolean state)
|
||||
(BitMap *)*GetGWorldPixMap(backSrcMap),
|
||||
&greaseSrcLf[3], &greaseSrcLf[3], &dest);
|
||||
|
||||
backSrcMap->SetForeColor(PortabilityLayer::RGBAColor::Create(0, 0, 0, 255));
|
||||
if (drawSpill)
|
||||
{
|
||||
backSrcMap->SetForeColor(PortabilityLayer::RGBAColor::Create(0, 0, 0, 255));
|
||||
|
||||
QSetRect(&spill, -distance + 5, -2, 0, 0);
|
||||
QOffsetRect(&spill, dest.left + 1, dest.bottom);
|
||||
backSrcMap->FillRect(spill);
|
||||
QSetRect(&spill, -distance + 5, -2, 0, 0);
|
||||
QOffsetRect(&spill, dest.left + 1, dest.bottom);
|
||||
backSrcMap->FillRect(spill);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -73,11 +73,13 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
DrawSimpleBlowers(thisObject.what, &itsRect);
|
||||
if (neighbor == kCentralRoom)
|
||||
{
|
||||
const short h = itsRect.left + 10;
|
||||
const short v = itsRect.top + 7;
|
||||
if (redraw)
|
||||
ReBackUpFlames(localNumbers[neighbor], i);
|
||||
ReBackUpFlames(localNumbers[neighbor], i, h, v);
|
||||
else
|
||||
AddCandleFlame(localNumbers[neighbor], i,
|
||||
itsRect.left + 10, itsRect.top + 7);
|
||||
h, v);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -88,11 +90,13 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
rectB.bottom += kFloorSupportTall;
|
||||
if (!SectRect(&rectA, &rectB, &whoCares))
|
||||
{
|
||||
const short h = itsRect.left + 10;
|
||||
const short v = itsRect.top + 7;
|
||||
if (redraw)
|
||||
ReBackUpFlames(localNumbers[neighbor], i);
|
||||
ReBackUpFlames(localNumbers[neighbor], i, h, v);
|
||||
else
|
||||
AddCandleFlame(localNumbers[neighbor], i,
|
||||
itsRect.left + 10, itsRect.top + 7);
|
||||
h, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,11 +111,13 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
DrawSimpleBlowers(thisObject.what, &itsRect);
|
||||
if (neighbor == kCentralRoom)
|
||||
{
|
||||
const short h = itsRect.left + 14;
|
||||
const short v = itsRect.top + 7;
|
||||
if (redraw)
|
||||
ReBackUpFlames(localNumbers[neighbor], i);
|
||||
ReBackUpFlames(localNumbers[neighbor], i, h, v);
|
||||
else
|
||||
AddCandleFlame(localNumbers[neighbor], i,
|
||||
itsRect.left + 14, itsRect.top + 7);
|
||||
h, v);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -122,11 +128,13 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
rectB.bottom += kFloorSupportTall;
|
||||
if (!SectRect(&rectA, &rectB, &whoCares))
|
||||
{
|
||||
const short h = itsRect.left + 14;
|
||||
const short v = itsRect.top + 7;
|
||||
if (redraw)
|
||||
ReBackUpFlames(localNumbers[neighbor], i);
|
||||
ReBackUpFlames(localNumbers[neighbor], i, h, v);
|
||||
else
|
||||
AddCandleFlame(localNumbers[neighbor], i,
|
||||
itsRect.left + 14, itsRect.top + 7);
|
||||
h, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,11 +149,13 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
DrawSimpleBlowers(thisObject.what, &itsRect);
|
||||
if (neighbor == kCentralRoom)
|
||||
{
|
||||
const short h = itsRect.left + 9;
|
||||
const short v = itsRect.top + 7;
|
||||
if (redraw)
|
||||
ReBackUpFlames(localNumbers[neighbor], i);
|
||||
ReBackUpFlames(localNumbers[neighbor], i, h, v);
|
||||
else
|
||||
AddCandleFlame(localNumbers[neighbor], i,
|
||||
itsRect.left + 9, itsRect.top + 7);
|
||||
h, v);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -156,26 +166,31 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
rectB.bottom += kFloorSupportTall;
|
||||
if (!SectRect(&rectA, &rectB, &whoCares))
|
||||
{
|
||||
const short h = itsRect.left + 9;
|
||||
const short v = itsRect.top + 7;
|
||||
if (redraw)
|
||||
ReBackUpFlames(localNumbers[neighbor], i);
|
||||
ReBackUpFlames(localNumbers[neighbor], i, h, v);
|
||||
else
|
||||
AddCandleFlame(localNumbers[neighbor], i,
|
||||
itsRect.left + 9, itsRect.top + 7);
|
||||
h, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kTiki:
|
||||
GetObjectRect(&thisObject, &itsRect);
|
||||
OffsetRectRoomRelative(&itsRect, neighbor);
|
||||
if (isLit)
|
||||
DrawTiki(&itsRect, playOriginV + VerticalRoomOffset(neighbor));
|
||||
if (redraw)
|
||||
ReBackUpTikiFlames(localNumbers[neighbor], i);
|
||||
else
|
||||
AddTikiFlame(localNumbers[neighbor], i,
|
||||
itsRect.left + 10, itsRect.top - 9);
|
||||
{
|
||||
GetObjectRect(&thisObject, &itsRect);
|
||||
OffsetRectRoomRelative(&itsRect, neighbor);
|
||||
const short h = itsRect.left + 10;
|
||||
const short v = itsRect.top - 9;
|
||||
if (isLit)
|
||||
DrawTiki(&itsRect, playOriginV + VerticalRoomOffset(neighbor));
|
||||
if (redraw)
|
||||
ReBackUpTikiFlames(localNumbers[neighbor], i, h, v);
|
||||
else
|
||||
AddTikiFlame(localNumbers[neighbor], i, h, v);
|
||||
}
|
||||
break;
|
||||
|
||||
case kBBQ:
|
||||
@@ -183,13 +198,14 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
OffsetRectRoomRelative(&itsRect, neighbor);
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
const short h = itsRect.left + 16;
|
||||
const short v = itsRect.top + 9;
|
||||
if (isLit)
|
||||
DrawPictSansWhiteObject(thisObject.what, &itsRect);
|
||||
if (redraw)
|
||||
ReBackUpBBQCoals(localNumbers[neighbor], i);
|
||||
ReBackUpBBQCoals(localNumbers[neighbor], i, h, v);
|
||||
else
|
||||
AddBBQCoals(localNumbers[neighbor], i,
|
||||
itsRect.left + 16, itsRect.top + 9);
|
||||
AddBBQCoals(localNumbers[neighbor], i, h, v);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -285,9 +301,9 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
if (redraw)
|
||||
legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i);
|
||||
legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i, kDefaultComponent);
|
||||
else
|
||||
legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i);
|
||||
legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i, kDefaultComponent);
|
||||
if (legit != -1)
|
||||
DrawRedClock(&itsRect);
|
||||
}
|
||||
@@ -299,9 +315,9 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
if (redraw)
|
||||
legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i);
|
||||
legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i, kDefaultComponent);
|
||||
else
|
||||
legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i);
|
||||
legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i, kDefaultComponent);
|
||||
if (legit != -1)
|
||||
DrawBlueClock(&itsRect);
|
||||
}
|
||||
@@ -313,9 +329,9 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
if (redraw)
|
||||
legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i);
|
||||
legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i, kDefaultComponent);
|
||||
else
|
||||
legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i);
|
||||
legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i, kDefaultComponent);
|
||||
if (legit != -1)
|
||||
DrawYellowClock(&itsRect);
|
||||
}
|
||||
@@ -327,14 +343,16 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
if (redraw)
|
||||
legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i);
|
||||
legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i, kDefaultComponent);
|
||||
else
|
||||
legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i);
|
||||
legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i, kDefaultComponent);
|
||||
if (legit != -1)
|
||||
{
|
||||
DrawCuckoo(&itsRect);
|
||||
short pendulumH = itsRect.left + 4;
|
||||
short pendulumV = itsRect.top + 46;
|
||||
if (redraw)
|
||||
ReBackUpPendulum(localNumbers[neighbor], i);
|
||||
ReBackUpPendulum(localNumbers[neighbor], i, pendulumH, pendulumV);
|
||||
else
|
||||
AddPendulum(localNumbers[neighbor], i,
|
||||
itsRect.left + 4, itsRect.top + 46);
|
||||
@@ -351,9 +369,9 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
if (redraw)
|
||||
legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i);
|
||||
legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i, kDefaultComponent);
|
||||
else
|
||||
legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i);
|
||||
legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i, kDefaultComponent);
|
||||
if (legit != -1)
|
||||
DrawSimplePrizes(thisObject.what, &itsRect);
|
||||
}
|
||||
@@ -367,17 +385,22 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
if (redraw)
|
||||
dynamicNum = ReBackUpGrease(localNumbers[neighbor], i);
|
||||
dynamicNum = ReBackUpGrease(localNumbers[neighbor], i, itsRect.left, itsRect.top);
|
||||
else
|
||||
dynamicNum = AddGrease(localNumbers[neighbor], i,
|
||||
itsRect.left, itsRect.top,
|
||||
thisObject.data.c.length, true);
|
||||
if (dynamicNum != -1)
|
||||
DrawGreaseRt(&itsRect, thisObject.data.c.length, true);
|
||||
DrawGreaseRt(&itsRect, thisObject.data.c.length, true, false);
|
||||
}
|
||||
}
|
||||
else // fallen
|
||||
DrawGreaseRt(&itsRect, thisObject.data.c.length, false);
|
||||
{
|
||||
Boolean isDynamic = false;
|
||||
if (redraw)
|
||||
FixupFallenGrease(localNumbers[neighbor], i, itsRect.left, itsRect.top, &isDynamic);
|
||||
DrawGreaseRt(&itsRect, thisObject.data.c.length, false, !isDynamic);
|
||||
}
|
||||
break;
|
||||
|
||||
case kGreaseLf:
|
||||
@@ -388,17 +411,22 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
if (redraw)
|
||||
dynamicNum = ReBackUpGrease(localNumbers[neighbor], i);
|
||||
dynamicNum = ReBackUpGrease(localNumbers[neighbor], i, itsRect.left, itsRect.top);
|
||||
else
|
||||
dynamicNum = AddGrease(localNumbers[neighbor], i,
|
||||
itsRect.left, itsRect.top,
|
||||
thisObject.data.c.length, false);
|
||||
if (dynamicNum != -1)
|
||||
DrawGreaseLf(&itsRect, thisObject.data.c.length, true);
|
||||
DrawGreaseLf(&itsRect, thisObject.data.c.length, true, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
DrawGreaseLf(&itsRect, thisObject.data.c.length, false);
|
||||
{
|
||||
Boolean isDynamic = false;
|
||||
if (redraw)
|
||||
FixupFallenGrease(localNumbers[neighbor], i, itsRect.left, itsRect.top, &isDynamic);
|
||||
DrawGreaseLf(&itsRect, thisObject.data.c.length, false, !isDynamic);
|
||||
}
|
||||
break;
|
||||
|
||||
case kFoil:
|
||||
@@ -407,9 +435,9 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
if (redraw)
|
||||
legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i);
|
||||
legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i, kDefaultComponent);
|
||||
else
|
||||
legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i);
|
||||
legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i, kDefaultComponent);
|
||||
if (legit != -1)
|
||||
DrawFoil(&itsRect);
|
||||
}
|
||||
@@ -425,13 +453,13 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
if (redraw)
|
||||
legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i);
|
||||
legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i, kDefaultComponent);
|
||||
else
|
||||
legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i);
|
||||
legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i, kDefaultComponent);
|
||||
if (legit != -1)
|
||||
{
|
||||
if (redraw)
|
||||
ReBackUpStar(localNumbers[neighbor], i);
|
||||
ReBackUpStar(localNumbers[neighbor], i, itsRect.left, itsRect.top);
|
||||
else
|
||||
AddStar(localNumbers[neighbor], i, itsRect.left,
|
||||
itsRect.top);
|
||||
@@ -445,12 +473,12 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
OffsetRectRoomRelative(&itsRect, neighbor);
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
if ((!redraw) && (neighbor == kCentralRoom))
|
||||
if (neighbor == kCentralRoom)
|
||||
{
|
||||
rectA = itsRect;
|
||||
QOffsetRect(&rectA, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kSparkle, &rectA, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.c.state);
|
||||
localNumbers[neighbor], i, thisObject.data.c.state, redraw);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -641,12 +669,12 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
DrawSimpleAppliance(thisObject.what, &itsRect);
|
||||
if ((!redraw) && (neighbor == kCentralRoom))
|
||||
if (neighbor == kCentralRoom)
|
||||
{
|
||||
rectA = itsRect;
|
||||
QOffsetRect(&rectA, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kToaster, &rectA, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.g.state);
|
||||
localNumbers[neighbor], i, thisObject.data.g.state, redraw);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -657,13 +685,10 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
DrawMacPlus(&itsRect, thisObject.data.g.state, isLit);
|
||||
if (!redraw)
|
||||
{
|
||||
rectA = itsRect;
|
||||
QOffsetRect(&rectA, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kMacPlus, &rectA, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.g.state);
|
||||
}
|
||||
rectA = itsRect;
|
||||
QOffsetRect(&rectA, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kMacPlus, &rectA, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.g.state, redraw);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -673,8 +698,7 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
#ifdef COMPILEQT
|
||||
if ((thisMac.hasQT) && (hasMovie) && (neighbor == kCentralRoom) &&
|
||||
(!tvInRoom))
|
||||
if ((thisMac.hasQT) && (hasMovie) && (neighbor == kCentralRoom))
|
||||
{
|
||||
whoCares = tvScreen1;
|
||||
ZeroRectCorner(&whoCares);
|
||||
@@ -683,16 +707,18 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
CenterRectInRect(&movieRect, &whoCares);
|
||||
theMovie.m_renderRect = movieRect;
|
||||
theMovie.m_constrainRect = whoCares;
|
||||
tvOn = thisObject.data.g.state;
|
||||
|
||||
if (!tvInRoom)
|
||||
tvOn = thisObject.data.g.state;
|
||||
}
|
||||
#endif
|
||||
DrawTV(&itsRect, thisObject.data.g.state, isLit);
|
||||
rectA = itsRect;
|
||||
QOffsetRect(&rectA, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kTV, &rectA, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.g.state, redraw);
|
||||
if (!redraw)
|
||||
{
|
||||
rectA = itsRect;
|
||||
QOffsetRect(&rectA, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kTV, &rectA, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.g.state);
|
||||
#ifdef COMPILEQT
|
||||
if ((thisMac.hasQT) && (hasMovie) && (neighbor == kCentralRoom) &&
|
||||
(!tvInRoom))
|
||||
@@ -711,13 +737,10 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
DrawCoffee(&itsRect, thisObject.data.g.state, isLit);
|
||||
if (!redraw)
|
||||
{
|
||||
rectA = itsRect;
|
||||
QOffsetRect(&rectA, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kCoffee, &rectA, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.g.state);
|
||||
}
|
||||
rectA = itsRect;
|
||||
QOffsetRect(&rectA, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kCoffee, &rectA, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.g.state, redraw);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -728,13 +751,10 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
{
|
||||
if (isLit)
|
||||
DrawOutlet(&itsRect);
|
||||
if (!redraw)
|
||||
{
|
||||
rectA = itsRect;
|
||||
QOffsetRect(&rectA, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kOutlet, &rectA, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.g.state);
|
||||
}
|
||||
rectA = itsRect;
|
||||
QOffsetRect(&rectA, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kOutlet, &rectA, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.g.state, redraw);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -744,13 +764,10 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
DrawVCR(&itsRect, thisObject.data.g.state, isLit);
|
||||
if (!redraw)
|
||||
{
|
||||
rectA = itsRect;
|
||||
QOffsetRect(&rectA, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kVCR, &rectA, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.g.state);
|
||||
}
|
||||
rectA = itsRect;
|
||||
QOffsetRect(&rectA, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kVCR, &rectA, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.g.state, redraw);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -760,13 +777,10 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
DrawStereo(&itsRect, isPlayMusicGame, isLit);
|
||||
if (!redraw)
|
||||
{
|
||||
rectA = itsRect;
|
||||
QOffsetRect(&rectA, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kStereo, &rectA, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.g.state);
|
||||
}
|
||||
rectA = itsRect;
|
||||
QOffsetRect(&rectA, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kStereo, &rectA, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.g.state, redraw);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -776,79 +790,76 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
DrawMicrowave(&itsRect, thisObject.data.g.state, isLit);
|
||||
if (!redraw)
|
||||
{
|
||||
rectA = itsRect;
|
||||
QOffsetRect(&rectA, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kMicrowave, &rectA, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.g.state);
|
||||
}
|
||||
rectA = itsRect;
|
||||
QOffsetRect(&rectA, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kMicrowave, &rectA, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.g.state, redraw);
|
||||
}
|
||||
break;
|
||||
|
||||
case kBalloon:
|
||||
if ((neighbor == kCentralRoom) && (!redraw))
|
||||
if (neighbor == kCentralRoom)
|
||||
{
|
||||
GetObjectRect(&thisObject, &itsRect);
|
||||
OffsetRectRoomRelative(&itsRect, neighbor);
|
||||
QOffsetRect(&itsRect, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kBalloon, &itsRect, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.h.state);
|
||||
localNumbers[neighbor], i, thisObject.data.h.state, redraw);
|
||||
}
|
||||
break;
|
||||
|
||||
case kCopterLf:
|
||||
if ((neighbor == kCentralRoom) && (!redraw))
|
||||
if (neighbor == kCentralRoom)
|
||||
{
|
||||
GetObjectRect(&thisObject, &itsRect);
|
||||
OffsetRectRoomRelative(&itsRect, neighbor);
|
||||
QOffsetRect(&itsRect, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kCopterLf, &itsRect, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.h.state);
|
||||
localNumbers[neighbor], i, thisObject.data.h.state, redraw);
|
||||
}
|
||||
break;
|
||||
|
||||
case kCopterRt:
|
||||
if ((neighbor == kCentralRoom) && (!redraw))
|
||||
if (neighbor == kCentralRoom)
|
||||
{
|
||||
GetObjectRect(&thisObject, &itsRect);
|
||||
OffsetRectRoomRelative(&itsRect, neighbor);
|
||||
QOffsetRect(&itsRect, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kCopterRt, &itsRect, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.h.state);
|
||||
localNumbers[neighbor], i, thisObject.data.h.state, redraw);
|
||||
}
|
||||
break;
|
||||
|
||||
case kDartLf:
|
||||
if ((neighbor == kCentralRoom) && (!redraw))
|
||||
if (neighbor == kCentralRoom)
|
||||
{
|
||||
GetObjectRect(&thisObject, &itsRect);
|
||||
OffsetRectRoomRelative(&itsRect, neighbor);
|
||||
QOffsetRect(&itsRect, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kDartLf, &itsRect, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.h.state);
|
||||
localNumbers[neighbor], i, thisObject.data.h.state, redraw);
|
||||
}
|
||||
break;
|
||||
|
||||
case kDartRt:
|
||||
if ((neighbor == kCentralRoom) && (!redraw))
|
||||
if (neighbor == kCentralRoom)
|
||||
{
|
||||
GetObjectRect(&thisObject, &itsRect);
|
||||
OffsetRectRoomRelative(&itsRect, neighbor);
|
||||
QOffsetRect(&itsRect, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kDartRt, &itsRect, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.h.state);
|
||||
localNumbers[neighbor], i, thisObject.data.h.state, redraw);
|
||||
}
|
||||
break;
|
||||
|
||||
case kBall:
|
||||
if ((neighbor == kCentralRoom) && (!redraw))
|
||||
if (neighbor == kCentralRoom)
|
||||
{
|
||||
GetObjectRect(&thisObject, &itsRect);
|
||||
OffsetRectRoomRelative(&itsRect, neighbor);
|
||||
QOffsetRect(&itsRect, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kBall, &itsRect, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.h.state);
|
||||
localNumbers[neighbor], i, thisObject.data.h.state, redraw);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -858,12 +869,12 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
DrawDrip(&itsRect);
|
||||
if ((!redraw) && (neighbor == kCentralRoom))
|
||||
if (neighbor == kCentralRoom)
|
||||
{
|
||||
rectA = itsRect;
|
||||
QOffsetRect(&rectA, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kDrip, &rectA, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.h.state);
|
||||
localNumbers[neighbor], i, thisObject.data.h.state, redraw);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -874,12 +885,12 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
if (SectRect(&itsRect, &testRect, &whoCares))
|
||||
{
|
||||
DrawFish(thisObject.what, &itsRect);
|
||||
if ((!redraw) && (neighbor == kCentralRoom))
|
||||
if (neighbor == kCentralRoom)
|
||||
{
|
||||
rectA = itsRect;
|
||||
QOffsetRect(&rectA, -playOriginH, -playOriginV);
|
||||
dynamicNum = AddDynamicObject(kFish, &rectA, &thisObject,
|
||||
localNumbers[neighbor], i, thisObject.data.h.state);
|
||||
localNumbers[neighbor], i, thisObject.data.h.state, redraw);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -897,7 +908,7 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
OffsetRectRoomRelative(&itsRect, neighbor);
|
||||
if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit)
|
||||
DrawMirror(&itsRect);
|
||||
if ((neighbor == kCentralRoom) && (!redraw))
|
||||
if (neighbor == kCentralRoom)
|
||||
{
|
||||
InsetRect(&itsRect, 4, 4);
|
||||
AddToMirrorRegion(&itsRect);
|
||||
@@ -942,15 +953,12 @@ void DrawARoomsObjects (short neighbor, Boolean redraw)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!redraw) // set up links
|
||||
|
||||
for (n = 0; n < numMasterObjects; n++)
|
||||
{
|
||||
for (n = 0; n < numMasterObjects; n++)
|
||||
{
|
||||
if ((masterObjects[n].objectNum == i) &&
|
||||
(masterObjects[n].roomNum == localNumbers[neighbor]))
|
||||
masterObjects[n].dynaNum = dynamicNum;
|
||||
}
|
||||
if ((masterObjects[n].objectNum == i) &&
|
||||
(masterObjects[n].roomNum == localNumbers[neighbor]))
|
||||
masterObjects[n].dynaNum = dynamicNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -2388,7 +2388,7 @@ void DrawThisRoomsObjects (void)
|
||||
if (!thisRoom->objects[i].data.c.initial)
|
||||
QOffsetRect(&tempRect, -8, 0);
|
||||
DrawGreaseRt(&tempRect, thisRoom->objects[i].data.c.length,
|
||||
thisRoom->objects[i].data.c.initial);
|
||||
thisRoom->objects[i].data.c.initial, true);
|
||||
break;
|
||||
|
||||
case kGreaseLf:
|
||||
@@ -2396,7 +2396,7 @@ void DrawThisRoomsObjects (void)
|
||||
if (!thisRoom->objects[i].data.c.initial)
|
||||
QOffsetRect(&tempRect, 8, 0);
|
||||
DrawGreaseLf(&tempRect, thisRoom->objects[i].data.c.length,
|
||||
thisRoom->objects[i].data.c.initial);
|
||||
thisRoom->objects[i].data.c.initial, true);
|
||||
break;
|
||||
|
||||
case kFoil:
|
||||
|
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "PLResources.h"
|
||||
#include "PLStandardColors.h"
|
||||
#include "DisplayDeviceManager.h"
|
||||
#include "Externs.h"
|
||||
#include "Environ.h"
|
||||
#include "House.h"
|
||||
@@ -53,7 +54,6 @@ short batteryTotal, bandsTotal, foilTotal, mortals;
|
||||
Boolean playing, evenFrame, twoPlayerGame, showFoil, demoGoing;
|
||||
Boolean doBackground, playerSuicide, phoneBitSet, tvOn;
|
||||
|
||||
extern WindowPtr menuWindow;
|
||||
extern VFileSpec *theHousesSpecs;
|
||||
extern demoPtr demoData;
|
||||
extern gameType smallGame;
|
||||
@@ -66,6 +66,7 @@ extern short numStarsRemaining, numChimes, saidFollow;
|
||||
extern Boolean quitting, isMusicOn, gameOver, hasMirror, onePlayerLeft;
|
||||
extern Boolean isPlayMusicIdle, failedMusic, quickerTransitions;
|
||||
extern Boolean switchedOut;
|
||||
extern short wasScoreboardTitleMode;
|
||||
|
||||
|
||||
//============================================================== Functions
|
||||
@@ -77,7 +78,6 @@ void NewGame (short mode)
|
||||
PLError_t theErr;
|
||||
Boolean wasPlayMusicPref;
|
||||
|
||||
AdjustScoreboardHeight();
|
||||
gameOver = false;
|
||||
theMode = kPlayMode;
|
||||
if (isPlayMusicGame)
|
||||
@@ -136,7 +136,7 @@ void NewGame (short mode)
|
||||
|
||||
DrawSurface *mainWindowSurface = mainWindow->GetDrawSurface();
|
||||
|
||||
tempRect = thisMac.screen;
|
||||
tempRect = thisMac.constrainedScreen;
|
||||
tempRect.top = tempRect.bottom - 20; // thisMac.menuHigh
|
||||
mainWindowSurface->FillRect(tempRect);
|
||||
|
||||
@@ -156,7 +156,7 @@ void NewGame (short mode)
|
||||
|
||||
// DebugStr("\pIf screen isn't black, exit to shell."); // TEMP TEMP TEMP
|
||||
|
||||
DrawLocale();
|
||||
ResetLocale(false);
|
||||
RefreshScoreboard(kNormalTitleMode);
|
||||
// if (quickerTransitions)
|
||||
// DissBitsChunky(&justRoomsRect);
|
||||
@@ -362,12 +362,37 @@ void SetHouseToSavedRoom (void)
|
||||
ForceThisRoom(smallGame.roomNumber);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- HandleGameResolutionChange
|
||||
|
||||
void HandleGameResolutionChange(void)
|
||||
{
|
||||
FlushResolutionChange();
|
||||
|
||||
RecomputeInterfaceRects();
|
||||
RecreateOffscreens();
|
||||
CloseMainWindow();
|
||||
OpenMainWindow();
|
||||
|
||||
if (hasMovie)
|
||||
theMovie.m_surface = &mainWindow->m_surface;
|
||||
|
||||
ResetLocale(true);
|
||||
InitScoreboardMap();
|
||||
RefreshScoreboard(wasScoreboardTitleMode);
|
||||
DumpScreenOn(&justRoomsRect);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- PlayGame
|
||||
|
||||
void PlayGame (void)
|
||||
{
|
||||
while ((playing) && (!quitting))
|
||||
{
|
||||
if (thisMac.isResolutionDirty)
|
||||
{
|
||||
HandleGameResolutionChange();
|
||||
}
|
||||
|
||||
gameFrame++;
|
||||
evenFrame = !evenFrame;
|
||||
|
||||
@@ -725,12 +750,12 @@ void RestoreEntireGameScreen (void)
|
||||
#endif
|
||||
|
||||
DrawSurface *surface = mainWindow->GetDrawSurface();
|
||||
tempRect = thisMac.screen;
|
||||
tempRect = thisMac.constrainedScreen;
|
||||
|
||||
surface->SetForeColor(StdColors::Black());
|
||||
surface->FillRect(tempRect);
|
||||
|
||||
DrawLocale();
|
||||
ResetLocale(false);
|
||||
RefreshScoreboard(kNormalTitleMode);
|
||||
// if (quickerTransitions)
|
||||
// DissBitsChunky(&justRoomsRect);
|
||||
|
@@ -34,9 +34,7 @@ void CopyRectsQD (void);
|
||||
|
||||
Rect work2MainRects[kMaxGarbageRects];
|
||||
Rect back2WorkRects[kMaxGarbageRects];
|
||||
Rect shieldRect;
|
||||
THandle<Rect> mirrorRects;
|
||||
Point shieldPt;
|
||||
long nextFrame;
|
||||
short numWork2Main, numBack2Work;
|
||||
Boolean hasMirror;
|
||||
|
@@ -42,33 +42,45 @@ extern Boolean shadowVisible, takingTheStairs;
|
||||
//============================================================== Functions
|
||||
//-------------------------------------------------------------- DrawLocale
|
||||
|
||||
void DrawLocale (void)
|
||||
void ResetLocale (Boolean soft)
|
||||
{
|
||||
short i, roomV;
|
||||
char wasState;
|
||||
DrawSurface *wasCPort;
|
||||
|
||||
ZeroFlamesAndTheLike();
|
||||
ZeroDinahs();
|
||||
KillAllBands();
|
||||
ZeroMirrorRegion();
|
||||
ZeroTriggers();
|
||||
numTempManholes = 0;
|
||||
FlushAnyTriggerPlaying();
|
||||
DumpTriggerSound();
|
||||
tvInRoom = false;
|
||||
tvWithMovieNumber = -1;
|
||||
|
||||
roomV = (*thisHouse)->rooms[thisRoomNumber].floor;
|
||||
|
||||
for (i = 0; i < 9; i++)
|
||||
|
||||
if (soft)
|
||||
{
|
||||
localNumbers[i] = GetNeighborRoomNumber(i);
|
||||
isStructure[i] = IsRoomAStructure(localNumbers[i]);
|
||||
RemoveSavedMapsNotInRoom(localNumbers[kCentralRoom]);
|
||||
ZeroDinahsNotInRoom(localNumbers[kCentralRoom]);
|
||||
|
||||
// Clear all dinah indexes, they'll be remapped
|
||||
for (int i = 0; i < numMasterObjects; i++)
|
||||
masterObjects[i].dynaNum = -1;
|
||||
}
|
||||
ListAllLocalObjects();
|
||||
|
||||
wasCPort = GetGraphicsPort();
|
||||
else
|
||||
{
|
||||
ZeroFlamesAndTheLike();
|
||||
ZeroDinahs();
|
||||
KillAllBands();
|
||||
ZeroTriggers();
|
||||
numTempManholes = 0;
|
||||
FlushAnyTriggerPlaying();
|
||||
DumpTriggerSound();
|
||||
tvInRoom = false;
|
||||
tvWithMovieNumber = -1;
|
||||
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
localNumbers[i] = GetNeighborRoomNumber(i);
|
||||
isStructure[i] = IsRoomAStructure(localNumbers[i]);
|
||||
}
|
||||
ListAllLocalObjects();
|
||||
}
|
||||
|
||||
ZeroMirrorRegion();
|
||||
|
||||
takingTheStairs = false;
|
||||
|
||||
DrawSurface *wasCPort = GetGraphicsPort();
|
||||
const short roomV = (*thisHouse)->rooms[thisRoomNumber].floor;
|
||||
|
||||
backSrcMap->SetForeColor(StdColors::Black());
|
||||
backSrcMap->FillRect(backSrcRect);
|
||||
@@ -115,14 +127,16 @@ void DrawLocale (void)
|
||||
|
||||
numLights = GetNumberOfLights(localNumbers[kCentralRoom]);
|
||||
DrawRoomBackground(localNumbers[kCentralRoom], kCentralRoom, roomV);
|
||||
DrawARoomsObjects(kCentralRoom, false);
|
||||
DrawARoomsObjects(kCentralRoom, soft);
|
||||
DrawLighting();
|
||||
|
||||
if (numNeighbors > 3)
|
||||
DrawFloorSupport();
|
||||
RestoreWorkMap();
|
||||
shadowVisible = IsShadowVisible();
|
||||
takingTheStairs = false;
|
||||
|
||||
if (soft)
|
||||
RedrawAllGrease();
|
||||
|
||||
SetGraphicsPort(wasCPort);
|
||||
}
|
||||
@@ -385,7 +399,7 @@ void ReadyLevel (void)
|
||||
#endif
|
||||
|
||||
DetermineRoomOpenings();
|
||||
DrawLocale();
|
||||
ResetLocale(false);
|
||||
InitGarbageRects();
|
||||
}
|
||||
|
||||
@@ -418,9 +432,10 @@ void RedrawRoomLighting (void)
|
||||
{
|
||||
DrawRoomBackground(localNumbers[kCentralRoom], kCentralRoom, roomV);
|
||||
DrawARoomsObjects(kCentralRoom, true);
|
||||
RedrawAllGrease();
|
||||
DrawLighting();
|
||||
UpdateOutletsLighting(localNumbers[kCentralRoom], numLights);
|
||||
|
||||
|
||||
if (numNeighbors > 3)
|
||||
DrawFloorSupport();
|
||||
RestoreWorkMap();
|
||||
|
@@ -42,7 +42,7 @@ Rect badgesBlankRects[4], badgesBadgesRects[4];
|
||||
Rect badgesDestRects[4];
|
||||
DrawSurface *boardPSrcMap;
|
||||
long displayedScore;
|
||||
short wasScoreboardMode;
|
||||
short wasScoreboardTitleMode;
|
||||
Boolean doRollScore;
|
||||
|
||||
extern Rect localRoomsDest[], justRoomsRect;
|
||||
@@ -63,6 +63,7 @@ void MarkScoreboardPortDirty(void)
|
||||
|
||||
void RefreshScoreboard (SInt16 mode)
|
||||
{
|
||||
wasScoreboardTitleMode = mode;
|
||||
doRollScore = true;
|
||||
|
||||
RefreshRoomTitle(mode);
|
||||
@@ -407,52 +408,3 @@ void QuickFoilRefresh (Boolean flash)
|
||||
|
||||
MarkScoreboardPortDirty();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- AdjustScoreboardHeight
|
||||
|
||||
void AdjustScoreboardHeight (void)
|
||||
{
|
||||
short offset, newMode;
|
||||
|
||||
if (numNeighbors == 9)
|
||||
newMode = kScoreboardHigh;
|
||||
else
|
||||
newMode = kScoreboardLow;
|
||||
|
||||
if (wasScoreboardMode != newMode)
|
||||
{
|
||||
switch (newMode)
|
||||
{
|
||||
case kScoreboardHigh: // 9 neighbors
|
||||
offset = localRoomsDest[kCentralRoom].top;
|
||||
offset = -offset;
|
||||
justRoomsRect = workSrcRect;
|
||||
break;
|
||||
|
||||
case kScoreboardLow: // 1 or 3 neighbors
|
||||
offset = localRoomsDest[kCentralRoom].top;
|
||||
justRoomsRect = workSrcRect;
|
||||
justRoomsRect.top = localRoomsDest[kCentralRoom].top;
|
||||
justRoomsRect.bottom = localRoomsDest[kCentralRoom].bottom;
|
||||
break;
|
||||
}
|
||||
|
||||
QOffsetRect(&boardDestRect, 0, offset);
|
||||
QOffsetRect(&boardGQDestRect, 0, offset);
|
||||
QOffsetRect(&boardPQDestRect, 0, offset);
|
||||
QOffsetRect(&badgesDestRects[kBatteryBadge], 0, offset);
|
||||
QOffsetRect(&badgesDestRects[kBandsBadge], 0, offset);
|
||||
QOffsetRect(&badgesDestRects[kFoilBadge], 0, offset);
|
||||
QOffsetRect(&badgesDestRects[kHeliumBadge], 0, offset);
|
||||
|
||||
wasScoreboardMode = newMode;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- BlackenScoreboard
|
||||
|
||||
void BlackenScoreboard (DrawSurface *surface)
|
||||
{
|
||||
UpdateMenuBarWindow(surface);
|
||||
}
|
||||
|
||||
|
@@ -1031,7 +1031,7 @@ void DoDisplayPrefs (void)
|
||||
break;
|
||||
|
||||
case kDisplay3Item:
|
||||
if (thisMac.screen.right > 512)
|
||||
if (thisMac.constrainedScreen.right > 512)
|
||||
{
|
||||
FrameDisplayIcon(prefDlg, StdColors::White());
|
||||
numNeighbors = 3;
|
||||
@@ -1040,7 +1040,7 @@ void DoDisplayPrefs (void)
|
||||
break;
|
||||
|
||||
case kDisplay9Item:
|
||||
if (thisMac.screen.right > 512)
|
||||
if (thisMac.constrainedScreen.right > 512)
|
||||
{
|
||||
FrameDisplayIcon(prefDlg, StdColors::White());
|
||||
numNeighbors = 9;
|
||||
|
@@ -52,7 +52,6 @@ extern Rect boardPQDestRect, boardGQDestRect, badgesBlankRects[];
|
||||
extern Rect badgesBadgesRects[], badgesDestRects[];
|
||||
extern Rect nailSrcRect, sparkleSrc[];
|
||||
extern Rect pointsSrc[], breadSrc[];
|
||||
extern short wasScoreboardMode;
|
||||
|
||||
|
||||
//============================================================== Functions
|
||||
@@ -60,20 +59,22 @@ extern short wasScoreboardMode;
|
||||
// Any graphics and structures relating to the scoreboard that appears<72>
|
||||
// across the top of the game are initialized and loaded up here.
|
||||
|
||||
void InitScoreboardMap (void)
|
||||
void InitScoreboardMap(void)
|
||||
{
|
||||
Rect bounds;
|
||||
THandle<BitmapImage> thePicture;
|
||||
DrawSurface *wasCPort;
|
||||
PLError_t theErr;
|
||||
short hOffset;
|
||||
|
||||
wasScoreboardMode = kScoreboardHigh;
|
||||
|
||||
if (boardSrcMap)
|
||||
DisposeGWorld(boardSrcMap);
|
||||
|
||||
boardSrcRect = houseRect;
|
||||
ZeroRectCorner(&boardSrcRect);
|
||||
boardSrcRect.bottom = kScoreboardTall;
|
||||
theErr = CreateOffScreenGWorld(&boardSrcMap, &boardSrcRect, kPreferredPixelFormat);
|
||||
|
||||
|
||||
if (boardSrcRect.right >= 640)
|
||||
hOffset = (RectWide(&boardSrcRect) - kMaxViewWidth) / 2;
|
||||
else
|
||||
@@ -86,40 +87,50 @@ void InitScoreboardMap (void)
|
||||
QOffsetRect(&bounds, hOffset, 0);
|
||||
boardSrcMap->DrawPicture(thePicture, bounds);
|
||||
thePicture.Dispose();
|
||||
|
||||
|
||||
QSetRect(&badgeSrcRect, 0, 0, 32, 66); // 2144 pixels
|
||||
theErr = CreateOffScreenGWorld(&badgeSrcMap, &badgeSrcRect, kPreferredPixelFormat);
|
||||
LoadGraphic(badgeSrcMap, kBadgePictID);
|
||||
|
||||
if (!badgeSrcMap)
|
||||
{
|
||||
theErr = CreateOffScreenGWorld(&badgeSrcMap, &badgeSrcRect, kPreferredPixelFormat);
|
||||
LoadGraphic(badgeSrcMap, kBadgePictID);
|
||||
}
|
||||
|
||||
boardDestRect = boardSrcRect;
|
||||
|
||||
|
||||
hOffset = (RectWide(&houseRect) - 640) / 2;
|
||||
if (hOffset < 0)
|
||||
hOffset = -128;
|
||||
|
||||
|
||||
QSetRect(&boardTSrcRect, 0, 0, 256, 12); // room title
|
||||
theErr = CreateOffScreenGWorld(&boardTSrcMap, &boardTSrcRect, kPreferredPixelFormat);
|
||||
if (!boardTSrcMap)
|
||||
{
|
||||
theErr = CreateOffScreenGWorld(&boardTSrcMap, &boardTSrcRect, kPreferredPixelFormat);
|
||||
boardTSrcMap->SetApplicationFont(12, PortabilityLayer::FontFamilyFlag_Bold);
|
||||
}
|
||||
boardTDestRect = boardTSrcRect;
|
||||
QOffsetRect(&boardTDestRect, 137 + hOffset, 5);
|
||||
|
||||
boardTSrcMap->SetApplicationFont(12, PortabilityLayer::FontFamilyFlag_Bold);
|
||||
|
||||
QSetRect(&boardGSrcRect, 0, 0, 20, 10); // # gliders
|
||||
theErr = CreateOffScreenGWorld(&boardGSrcMap, &boardGSrcRect, kPreferredPixelFormat);
|
||||
if (!boardGSrcMap)
|
||||
{
|
||||
theErr = CreateOffScreenGWorld(&boardGSrcMap, &boardGSrcRect, kPreferredPixelFormat);
|
||||
boardGSrcMap->SetApplicationFont(12, PortabilityLayer::FontFamilyFlag_Bold);
|
||||
}
|
||||
boardGDestRect = boardGSrcRect;
|
||||
QOffsetRect(&boardGDestRect, 526 + hOffset, 5);
|
||||
|
||||
boardGSrcMap->SetApplicationFont(12, PortabilityLayer::FontFamilyFlag_Bold);
|
||||
|
||||
|
||||
QSetRect(&boardPSrcRect, 0, 0, 64, 10); // points
|
||||
theErr = CreateOffScreenGWorld(&boardPSrcMap, &boardPSrcRect, kPreferredPixelFormat);
|
||||
if (!boardPSrcMap)
|
||||
{
|
||||
theErr = CreateOffScreenGWorld(&boardPSrcMap, &boardPSrcRect, kPreferredPixelFormat);
|
||||
boardPSrcMap->SetApplicationFont(12, PortabilityLayer::FontFamilyFlag_Bold);
|
||||
}
|
||||
boardPDestRect = boardPSrcRect;
|
||||
QOffsetRect(&boardPDestRect, 570 + hOffset, 5); // total = 6396 pixels
|
||||
boardPQDestRect = boardPDestRect;
|
||||
boardGQDestRect = boardGDestRect;
|
||||
|
||||
boardPSrcMap->SetApplicationFont(12, PortabilityLayer::FontFamilyFlag_Bold);
|
||||
|
||||
QSetRect(&badgesBlankRects[0], 0, 0, 16, 16); // foil
|
||||
QOffsetRect(&badgesBlankRects[0], 0, 0);
|
||||
QSetRect(&badgesBlankRects[1], 0, 0, 16, 16); // rubber bands
|
||||
|
@@ -11,6 +11,7 @@
|
||||
#include "GameOver.h"
|
||||
#include "MainWindow.h"
|
||||
#include "Objects.h"
|
||||
#include "QDManager.h"
|
||||
#include "RectUtils.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "Room.h"
|
||||
@@ -112,6 +113,34 @@ void InitAngel (void)
|
||||
LoadGraphic(angelMaskMap, kAngelPictID + 1);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- RecreateOffscreens
|
||||
// Recreates resolution-dependent offscreen work
|
||||
PLError_t RecreateOffscreens(void)
|
||||
{
|
||||
PLError_t theErr;
|
||||
|
||||
PortabilityLayer::QDManager::GetInstance()->SetPort(nullptr);
|
||||
|
||||
if (workSrcMap)
|
||||
DisposeGWorld(workSrcMap);
|
||||
|
||||
if (backSrcMap)
|
||||
DisposeGWorld(backSrcMap);
|
||||
|
||||
justRoomsRect = houseRect;
|
||||
ZeroRectCorner(&justRoomsRect);
|
||||
|
||||
workSrcRect = houseRect; // Set up work map
|
||||
ZeroRectCorner(&workSrcRect);
|
||||
theErr = CreateOffScreenGWorld(&workSrcMap, &workSrcRect, kPreferredPixelFormat);
|
||||
|
||||
backSrcRect = houseRect; // Set up background map
|
||||
ZeroRectCorner(&backSrcRect);
|
||||
theErr = CreateOffScreenGWorld(&backSrcMap, &backSrcRect, kPreferredPixelFormat);
|
||||
|
||||
return PLErrors::kNone;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------- CreateOffscreens
|
||||
// All "utility" or "work" offscreen pix/bit maps are created here.
|
||||
// These would be offscreens that are reused throughout a game - they<65>
|
||||
@@ -121,17 +150,8 @@ void InitAngel (void)
|
||||
void CreateOffscreens (void)
|
||||
{
|
||||
PLError_t theErr;
|
||||
|
||||
justRoomsRect = houseRect;
|
||||
ZeroRectCorner(&justRoomsRect);
|
||||
|
||||
workSrcRect = houseRect; // Set up work map
|
||||
ZeroRectCorner(&workSrcRect);
|
||||
theErr = CreateOffScreenGWorld(&workSrcMap, &workSrcRect, kPreferredPixelFormat);
|
||||
|
||||
backSrcRect = houseRect; // Set up background map
|
||||
ZeroRectCorner(&backSrcRect);
|
||||
theErr = CreateOffScreenGWorld(&backSrcMap, &backSrcRect, kPreferredPixelFormat);
|
||||
|
||||
theErr = RecreateOffscreens();
|
||||
|
||||
InitScoreboardMap(); SpinCursor(1);
|
||||
InitGliderMap(); SpinCursor(1);
|
||||
|
@@ -61,6 +61,7 @@ void FrameSelectedTool (DrawSurface *);
|
||||
void DrawToolName (DrawSurface *);
|
||||
void DrawToolTiles (DrawSurface *);
|
||||
void SwitchToolModes (short);
|
||||
void KeepWindowInBounds (Window *window);
|
||||
|
||||
|
||||
Rect toolsWindowRect, toolSrcRect, toolTextRect;
|
||||
@@ -350,6 +351,8 @@ void OpenToolsWindow (void)
|
||||
|
||||
SwitchToolModes(toolMode);
|
||||
toolSelected = kSelectTool;
|
||||
|
||||
KeepWindowInBounds(toolsWindow);
|
||||
}
|
||||
|
||||
UpdateToolsCheckmark(true);
|
||||
|
@@ -109,7 +109,7 @@ void OpenMessageWindow (const PLPasStr &title)
|
||||
SetRect(&mssgWindowRect, 0, 0, 256, kMessageWindowTall);
|
||||
|
||||
Rect placementRect = mssgWindowRect;
|
||||
CenterRectInRect(&placementRect, &thisMac.screen);
|
||||
CenterRectInRect(&placementRect, &thisMac.fullScreen);
|
||||
|
||||
const PortabilityLayer::WindowDef wdef = PortabilityLayer::WindowDef::Create(placementRect, windowStyle, false, 0, 0, title);
|
||||
|
||||
|
@@ -3,6 +3,8 @@
|
||||
#include "EGpDisplayDriverType.h"
|
||||
#include "GpDisplayDriverTickStatus.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct IGpDisplayDriver;
|
||||
struct IGpFiber;
|
||||
struct IGpVOSEventQueue;
|
||||
@@ -11,6 +13,7 @@ struct GpDisplayDriverProperties
|
||||
{
|
||||
typedef GpDisplayDriverTickStatus_t (*TickFunc_t)(void *context, IGpFiber *vosFiber);
|
||||
typedef void(*RenderFunc_t)(void *context);
|
||||
typedef bool(*AdjustRequestedResolutionFunc_t)(void *context, uint32_t &physicalWidth, uint32_t &physicalHeight, uint32_t &virtualWidth, uint32_t &virtualheight, float &pixelScaleX, float &pixelScaleY);
|
||||
|
||||
EGpDisplayDriverType m_type;
|
||||
|
||||
@@ -32,5 +35,8 @@ struct GpDisplayDriverProperties
|
||||
RenderFunc_t m_renderFunc;
|
||||
void *m_renderFuncContext;
|
||||
|
||||
AdjustRequestedResolutionFunc_t m_adjustRequestedResolutionFunc;
|
||||
void *m_adjustRequestedResolutionFuncContext;
|
||||
|
||||
IGpVOSEventQueue *m_eventQueue;
|
||||
};
|
||||
|
@@ -235,6 +235,14 @@ struct GpMouseInputEvent
|
||||
GpMouseButton_t m_button;
|
||||
};
|
||||
|
||||
struct GpVideoResolutionChangedEvent
|
||||
{
|
||||
uint32_t m_prevWidth;
|
||||
uint32_t m_prevHeight;
|
||||
uint32_t m_newWidth;
|
||||
uint32_t m_newHeight;
|
||||
};
|
||||
|
||||
namespace GpVOSEventTypes
|
||||
{
|
||||
enum GpVOSEventType
|
||||
@@ -242,6 +250,8 @@ namespace GpVOSEventTypes
|
||||
kKeyboardInput,
|
||||
kMouseInput,
|
||||
kGamepadInput,
|
||||
kVideoResolutionChanged,
|
||||
kQuit
|
||||
};
|
||||
}
|
||||
|
||||
@@ -254,6 +264,7 @@ struct GpVOSEvent
|
||||
GpKeyboardInputEvent m_keyboardInputEvent;
|
||||
GpMouseInputEvent m_mouseInputEvent;
|
||||
GpGamepadInputEvent m_gamepadInputEvent;
|
||||
GpVideoResolutionChangedEvent m_resolutionChangedEvent;
|
||||
};
|
||||
|
||||
EventUnion m_event;
|
||||
|
@@ -21,9 +21,10 @@ struct GpWindowsGlobals
|
||||
HINSTANCE m_hPrevInstance;
|
||||
LPCSTR m_cmdLine;
|
||||
LPCWSTR m_baseDir;
|
||||
HWND m_hwnd;
|
||||
int m_nCmdShow;
|
||||
|
||||
IGpFiber *(*m_createFiberFunc)(LPVOID fiber);
|
||||
IGpCursor_Win32 *(*m_loadCursorFunc)(const wchar_t *path);
|
||||
void (*m_translateWindowsMessageFunc)(const MSG *msg, IGpVOSEventQueue *eventQueue);
|
||||
void (*m_translateWindowsMessageFunc)(const MSG *msg, IGpVOSEventQueue *eventQueue, float pixelScaleX, float pixelScaleY);
|
||||
};
|
||||
|
@@ -23,4 +23,8 @@ public:
|
||||
virtual void SetStandardCursor(EGpStandardCursor_t standardCursor) = 0;
|
||||
|
||||
virtual void UpdatePalette(const void *paletteData) = 0;
|
||||
|
||||
virtual void SetBackgroundColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a) = 0;
|
||||
|
||||
virtual void RequestToggleFullScreen(uint32_t timestamp) = 0;
|
||||
};
|
||||
|
@@ -1,8 +1,8 @@
|
||||
static unsigned char gs_shaderData[] = {
|
||||
68, 88, 66, 67, 96, 46, 192, 91, 73, 216, 92, 145, 77, 166, 215,
|
||||
215, 59, 255, 4, 67, 1, 0, 0, 0, 240, 2, 0, 0, 5, 0,
|
||||
68, 88, 66, 67, 75, 29, 59, 91, 67, 226, 130, 211, 218, 1, 246,
|
||||
35, 4, 77, 147, 90, 1, 0, 0, 0, 4, 3, 0, 0, 5, 0,
|
||||
0, 0, 52, 0, 0, 0, 224, 0, 0, 0, 56, 1, 0, 0, 108,
|
||||
1, 0, 0, 116, 2, 0, 0, 82, 68, 69, 70, 164, 0, 0, 0,
|
||||
1, 0, 0, 136, 2, 0, 0, 82, 68, 69, 70, 164, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0,
|
||||
0, 0, 4, 255, 255, 0, 137, 0, 0, 122, 0, 0, 0, 92, 0,
|
||||
0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 255,
|
||||
@@ -23,33 +23,34 @@ static unsigned char gs_shaderData[] = {
|
||||
78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0,
|
||||
0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69,
|
||||
84, 0, 171, 171, 83, 72, 68, 82, 0, 1, 0, 0, 64, 0, 0,
|
||||
0, 64, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0,
|
||||
84, 0, 171, 171, 83, 72, 68, 82, 20, 1, 0, 0, 64, 0, 0,
|
||||
0, 69, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0,
|
||||
0, 0, 68, 68, 0, 0, 88, 16, 0, 4, 0, 112, 16, 0, 1,
|
||||
0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0,
|
||||
1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0,
|
||||
0, 104, 0, 0, 2, 1, 0, 0, 0, 27, 0, 0, 5, 50, 0,
|
||||
16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 54,
|
||||
0, 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0,
|
||||
0, 104, 0, 0, 2, 1, 0, 0, 0, 65, 0, 0, 5, 50, 0,
|
||||
16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 27,
|
||||
0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0,
|
||||
0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 0, 0, 0,
|
||||
0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0,
|
||||
0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0,
|
||||
0, 0, 0, 0, 54, 0, 0, 8, 226, 0, 16, 0, 0, 0, 0,
|
||||
0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0,
|
||||
0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0,
|
||||
1, 0, 0, 0, 54, 0, 0, 5, 114, 32, 16, 0, 0, 0, 0,
|
||||
0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32,
|
||||
16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62,
|
||||
0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0,
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14,
|
||||
16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54,
|
||||
0, 0, 8, 226, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0,
|
||||
0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14,
|
||||
16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 1, 0, 0, 0, 54,
|
||||
0, 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0,
|
||||
0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0,
|
||||
0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84,
|
||||
65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0,
|
||||
0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
namespace GpBinarizedShaders
|
||||
|
@@ -1,49 +1,46 @@
|
||||
static unsigned char gs_shaderData[] = {
|
||||
68, 88, 66, 67, 181, 133, 124, 121, 179, 141, 64, 216, 166, 21, 153,
|
||||
10, 33, 21, 80, 169, 1, 0, 0, 0, 152, 2, 0, 0, 5, 0,
|
||||
0, 0, 52, 0, 0, 0, 224, 0, 0, 0, 56, 1, 0, 0, 108,
|
||||
1, 0, 0, 28, 2, 0, 0, 82, 68, 69, 70, 164, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0,
|
||||
0, 0, 4, 255, 255, 0, 137, 0, 0, 122, 0, 0, 0, 92, 0,
|
||||
0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
|
||||
107, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0,
|
||||
0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0,
|
||||
0, 0, 115, 117, 114, 102, 97, 99, 101, 83, 97, 109, 112, 108, 101,
|
||||
114, 0, 115, 117, 114, 102, 97, 99, 101, 84, 101, 120, 116, 117, 114,
|
||||
101, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41,
|
||||
32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111,
|
||||
109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 73,
|
||||
83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0,
|
||||
56, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0,
|
||||
0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3,
|
||||
3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0,
|
||||
84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71,
|
||||
78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0,
|
||||
0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69,
|
||||
84, 0, 171, 171, 83, 72, 68, 82, 168, 0, 0, 0, 64, 0, 0,
|
||||
0, 42, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0,
|
||||
68, 88, 66, 67, 196, 70, 6, 103, 19, 68, 64, 241, 205, 255, 73,
|
||||
188, 120, 217, 29, 231, 1, 0, 0, 0, 116, 2, 0, 0, 5, 0,
|
||||
0, 0, 52, 0, 0, 0, 176, 0, 0, 0, 8, 1, 0, 0, 60,
|
||||
1, 0, 0, 248, 1, 0, 0, 82, 68, 69, 70, 116, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0,
|
||||
0, 0, 4, 255, 255, 0, 137, 0, 0, 75, 0, 0, 0, 60, 0,
|
||||
0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255,
|
||||
255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 9, 0, 0, 0,
|
||||
115, 117, 114, 102, 97, 99, 101, 84, 101, 120, 116, 117, 114, 101, 0,
|
||||
77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72,
|
||||
76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112,
|
||||
105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 73, 83, 71, 78,
|
||||
80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0,
|
||||
0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0,
|
||||
0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0,
|
||||
83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88,
|
||||
67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0,
|
||||
0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
|
||||
15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171,
|
||||
171, 83, 72, 68, 82, 180, 0, 0, 0, 64, 0, 0, 0, 45, 0,
|
||||
0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85,
|
||||
85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0,
|
||||
101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0,
|
||||
2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0,
|
||||
0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0,
|
||||
0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5,
|
||||
18, 32, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0,
|
||||
0, 54, 0, 0, 5, 98, 32, 16, 0, 0, 0, 0, 0, 6, 17,
|
||||
16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0,
|
||||
0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1,
|
||||
83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
2, 1, 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0,
|
||||
0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 8, 194,
|
||||
0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0,
|
||||
7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0,
|
||||
0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 114,
|
||||
32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0,
|
||||
54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0,
|
||||
0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0,
|
||||
0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
namespace GpBinarizedShaders
|
||||
|
101
GpDisplayDriver_D3D11/CompiledShaders/ScaleQuadP_D3D11.cpp
Normal file
101
GpDisplayDriver_D3D11/CompiledShaders/ScaleQuadP_D3D11.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
static unsigned char gs_shaderData[] = {
|
||||
68, 88, 66, 67, 232, 177, 184, 42, 191, 44, 237, 186, 185, 1, 42,
|
||||
67, 157, 207, 200, 70, 1, 0, 0, 0, 116, 5, 0, 0, 5, 0,
|
||||
0, 0, 52, 0, 0, 0, 52, 1, 0, 0, 140, 1, 0, 0, 192,
|
||||
1, 0, 0, 248, 4, 0, 0, 82, 68, 69, 70, 248, 0, 0, 0,
|
||||
1, 0, 0, 0, 132, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0,
|
||||
0, 0, 4, 255, 255, 0, 137, 0, 0, 208, 0, 0, 0, 92, 0,
|
||||
0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255,
|
||||
255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 9, 0, 0, 0,
|
||||
107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0,
|
||||
0, 0, 115, 117, 114, 102, 97, 99, 101, 84, 101, 120, 116, 117, 114,
|
||||
101, 0, 83, 83, 99, 97, 108, 101, 81, 117, 97, 100, 80, 105, 120,
|
||||
101, 108, 67, 111, 110, 115, 116, 97, 110, 116, 115, 0, 107, 0, 0,
|
||||
0, 1, 0, 0, 0, 156, 0, 0, 0, 16, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 16,
|
||||
0, 0, 0, 2, 0, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0,
|
||||
100, 120, 100, 121, 95, 85, 110, 117, 115, 101, 100, 0, 1, 0, 3,
|
||||
0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105,
|
||||
99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83,
|
||||
76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108,
|
||||
101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 80, 0, 0,
|
||||
0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0,
|
||||
0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15,
|
||||
0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, 83, 86, 95,
|
||||
80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79,
|
||||
82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1,
|
||||
0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0,
|
||||
0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72,
|
||||
68, 82, 48, 3, 0, 0, 64, 0, 0, 0, 204, 0, 0, 0, 89,
|
||||
0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0,
|
||||
88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0,
|
||||
0, 98, 16, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0, 101, 0,
|
||||
0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 5,
|
||||
0, 0, 0, 51, 0, 0, 11, 50, 0, 16, 0, 0, 0, 0, 0,
|
||||
70, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0,
|
||||
0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 50, 0, 0, 14, 194, 0, 16, 0, 0, 0, 0, 0, 6,
|
||||
132, 32, 128, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
63, 0, 0, 0, 63, 6, 20, 16, 0, 1, 0, 0, 0, 52, 0,
|
||||
0, 10, 194, 0, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 0,
|
||||
0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 50, 0, 16,
|
||||
0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 230, 10,
|
||||
16, 0, 0, 0, 0, 0, 65, 0, 0, 5, 194, 0, 16, 0, 0,
|
||||
0, 0, 0, 166, 14, 16, 0, 0, 0, 0, 0, 27, 0, 0, 5,
|
||||
50, 0, 16, 0, 1, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0,
|
||||
0, 65, 0, 0, 5, 194, 0, 16, 0, 0, 0, 0, 0, 6, 4,
|
||||
16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 50, 0, 16, 0, 0,
|
||||
0, 0, 0, 230, 10, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0,
|
||||
70, 0, 16, 0, 0, 0, 0, 0, 27, 0, 0, 5, 50, 0, 16,
|
||||
0, 2, 0, 0, 0, 230, 10, 16, 0, 0, 0, 0, 0, 14, 32,
|
||||
0, 8, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0,
|
||||
0, 0, 0, 70, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
54, 0, 0, 5, 66, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0,
|
||||
0, 0, 0, 0, 0, 54, 0, 0, 5, 194, 0, 16, 0, 2, 0,
|
||||
0, 0, 86, 9, 16, 0, 1, 0, 0, 0, 45, 0, 0, 7, 242,
|
||||
0, 16, 0, 3, 0, 0, 0, 70, 15, 16, 0, 2, 0, 0, 0,
|
||||
70, 126, 16, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16,
|
||||
0, 4, 0, 0, 0, 134, 15, 16, 0, 2, 0, 0, 0, 70, 126,
|
||||
16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 1,
|
||||
0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 45, 0, 0, 7,
|
||||
242, 0, 16, 0, 2, 0, 0, 0, 198, 10, 16, 0, 1, 0, 0,
|
||||
0, 70, 126, 16, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0,
|
||||
16, 0, 1, 0, 0, 0, 70, 10, 16, 0, 1, 0, 0, 0, 70,
|
||||
126, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0,
|
||||
4, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16,
|
||||
0, 4, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 3, 0,
|
||||
0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 3,
|
||||
0, 0, 0, 0, 0, 0, 11, 82, 0, 16, 0, 0, 0, 0, 0,
|
||||
6, 1, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0,
|
||||
0, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0,
|
||||
0, 0, 50, 0, 0, 9, 114, 0, 16, 0, 2, 0, 0, 0, 6,
|
||||
0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 2, 0, 0, 0,
|
||||
70, 2, 16, 0, 3, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16,
|
||||
0, 2, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 70, 2,
|
||||
16, 0, 2, 0, 0, 0, 50, 0, 0, 9, 178, 0, 16, 0, 0,
|
||||
0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 8, 16, 0,
|
||||
1, 0, 0, 0, 70, 8, 16, 0, 4, 0, 0, 0, 50, 0, 0,
|
||||
9, 114, 32, 16, 0, 0, 0, 0, 0, 166, 10, 16, 0, 0, 0,
|
||||
0, 0, 70, 3, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 2,
|
||||
0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0,
|
||||
1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65,
|
||||
84, 116, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 0, 0,
|
||||
0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
};
|
||||
|
||||
namespace GpBinarizedShaders
|
||||
{
|
||||
const unsigned char *g_scaleQuadP_D3D11[2] = { gs_shaderData, gs_shaderData + sizeof(gs_shaderData) };
|
||||
};
|
@@ -2,9 +2,11 @@
|
||||
#include "GpApplicationName.h"
|
||||
#include "GpDisplayDriverD3D11.h"
|
||||
#include "GpDisplayDriverSurfaceD3D11.h"
|
||||
#include "GpVOSEvent.h"
|
||||
#include "GpWindows.h"
|
||||
#include "IGpCursor_Win32.h"
|
||||
#include "IGpFiber.h"
|
||||
#include "IGpVOSEventQueue.h"
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <dxgi1_2.h>
|
||||
@@ -21,6 +23,7 @@ namespace GpBinarizedShaders
|
||||
extern const unsigned char *g_drawQuadV_D3D11[2];
|
||||
extern const unsigned char *g_drawQuadPaletteP_D3D11[2];
|
||||
extern const unsigned char *g_drawQuadRGBP_D3D11[2];
|
||||
extern const unsigned char *g_scaleQuadP_D3D11[2];
|
||||
extern const unsigned char *g_drawQuad15BitP_D3D11[2];
|
||||
}
|
||||
|
||||
@@ -54,6 +57,7 @@ LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
switch (message)
|
||||
{
|
||||
case WM_DESTROY:
|
||||
case WM_CLOSE:
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
@@ -64,8 +68,10 @@ LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
void StartD3DForWindow(HWND hWnd, GpComPtr<IDXGISwapChain1>& outSwapChain, GpComPtr<ID3D11Device>& outDevice, GpComPtr<ID3D11DeviceContext>& outContext)
|
||||
bool InitSwapChainForWindow(HWND hWnd, ID3D11Device *device, GpComPtr<IDXGISwapChain1>& outSwapChain)
|
||||
{
|
||||
outSwapChain = nullptr;
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC1 swapChainDesc;
|
||||
|
||||
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
|
||||
@@ -76,6 +82,50 @@ void StartD3DForWindow(HWND hWnd, GpComPtr<IDXGISwapChain1>& outSwapChain, GpCom
|
||||
swapChainDesc.SampleDesc.Count = 1;
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||
|
||||
HRESULT result;
|
||||
|
||||
IDXGIDevice2 *dxgiDevice = nullptr;
|
||||
result = device->QueryInterface(__uuidof(IDXGIDevice2), reinterpret_cast<void**>(&dxgiDevice));
|
||||
if (result != S_OK)
|
||||
return false;
|
||||
|
||||
IDXGIAdapter *dxgiAdapter = nullptr;
|
||||
result = dxgiDevice->GetAdapter(&dxgiAdapter);
|
||||
if (result != S_OK)
|
||||
return false;
|
||||
|
||||
IDXGIFactory2 *dxgiFactory = nullptr;
|
||||
result = dxgiAdapter->GetParent(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory));
|
||||
if (result != S_OK)
|
||||
return false;
|
||||
|
||||
IDXGISwapChain1 *swapChain = nullptr;
|
||||
result = dxgiFactory->CreateSwapChainForHwnd(device, hWnd, &swapChainDesc, nullptr, nullptr, &swapChain);
|
||||
if (result != S_OK)
|
||||
return false;
|
||||
|
||||
result = dxgiFactory->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER);
|
||||
if (result != S_OK)
|
||||
return false;
|
||||
|
||||
outSwapChain = swapChain;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ResizeSwapChain(IDXGISwapChain1 *swapChain, UINT width, UINT height)
|
||||
{
|
||||
HRESULT result;
|
||||
|
||||
result = swapChain->ResizeBuffers(0, width, height, DXGI_FORMAT_R8G8B8A8_UNORM, 0);
|
||||
if (result != S_OK)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void StartD3DForWindow(HWND hWnd, GpComPtr<IDXGISwapChain1>& outSwapChain, GpComPtr<ID3D11Device>& outDevice, GpComPtr<ID3D11DeviceContext>& outContext)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_FULLSCREEN_DESC swapChainFullscreenDesc;
|
||||
|
||||
ZeroMemory(&swapChainFullscreenDesc, sizeof(swapChainFullscreenDesc));
|
||||
@@ -90,7 +140,9 @@ void StartD3DForWindow(HWND hWnd, GpComPtr<IDXGISwapChain1>& outSwapChain, GpCom
|
||||
D3D_FEATURE_LEVEL_10_0
|
||||
};
|
||||
|
||||
#ifndef NDEBUG
|
||||
flags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
#endif
|
||||
|
||||
ID3D11Device *device = NULL;
|
||||
ID3D11DeviceContext *context = NULL;
|
||||
@@ -100,27 +152,57 @@ void StartD3DForWindow(HWND hWnd, GpComPtr<IDXGISwapChain1>& outSwapChain, GpCom
|
||||
HRESULT result = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, featureLevels, sizeof(featureLevels) / sizeof(featureLevels[0]),
|
||||
D3D11_SDK_VERSION, &device, &selectedFeatureLevel, &context);
|
||||
|
||||
IDXGIDevice2 *dxgiDevice = nullptr;
|
||||
result = device->QueryInterface(__uuidof(IDXGIDevice2), reinterpret_cast<void**>(&dxgiDevice));
|
||||
|
||||
IDXGIAdapter *dxgiAdapter = nullptr;
|
||||
result = dxgiDevice->GetAdapter(&dxgiAdapter);
|
||||
|
||||
IDXGIFactory2 *dxgiFactory = nullptr;
|
||||
result = dxgiAdapter->GetParent(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory));
|
||||
|
||||
IDXGISwapChain1 *swapChain = nullptr;
|
||||
result = dxgiFactory->CreateSwapChainForHwnd(device, hWnd, &swapChainDesc, nullptr, nullptr, &swapChain);
|
||||
InitSwapChainForWindow(hWnd, device, outSwapChain);
|
||||
|
||||
// GP TODO: Fix the error handling here, it's bad...
|
||||
outSwapChain = swapChain;
|
||||
outDevice = device;
|
||||
outContext = context;
|
||||
}
|
||||
|
||||
bool GpDisplayDriverD3D11::InitResources()
|
||||
bool ResizeD3DWindow(HWND hWnd, DWORD &windowWidth, DWORD &windowHeight, LONG desiredWidth, LONG desiredHeight, DWORD windowStyle, HMENU menus)
|
||||
{
|
||||
if (desiredWidth < 640)
|
||||
desiredWidth = 640;
|
||||
else if (desiredWidth > MAXDWORD)
|
||||
desiredWidth = MAXDWORD;
|
||||
|
||||
if (desiredHeight < 480)
|
||||
desiredHeight = 480;
|
||||
else if (desiredHeight > MAXDWORD)
|
||||
desiredHeight = MAXDWORD;
|
||||
|
||||
RECT windowRect;
|
||||
GetClientRect(hWnd, &windowRect);
|
||||
windowRect.right = windowRect.left + desiredWidth;
|
||||
windowRect.bottom = windowRect.top + desiredHeight;
|
||||
|
||||
LONG_PTR style = GetWindowLongPtrA(hWnd, GWL_STYLE);
|
||||
|
||||
if (!AdjustWindowRect(&windowRect, static_cast<DWORD>(style), menus != nullptr))
|
||||
return false;
|
||||
|
||||
SetWindowPos(hWnd, HWND_TOP, windowRect.left, windowRect.top, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_NOZORDER | SWP_NOMOVE);
|
||||
|
||||
windowWidth = desiredWidth;
|
||||
windowHeight = desiredHeight;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GpDisplayDriverD3D11::DetachSwapChain()
|
||||
{
|
||||
m_deviceContext->OMSetRenderTargets(0, nullptr, nullptr);
|
||||
m_backBufferRTV = nullptr;
|
||||
m_backBufferTexture = nullptr;
|
||||
|
||||
m_deviceContext->ClearState();
|
||||
m_deviceContext->Flush();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GpDisplayDriverD3D11::InitBackBuffer(uint32_t virtualWidth, uint32_t virtualHeight)
|
||||
{
|
||||
// Fetch back buffer
|
||||
m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<LPVOID*>(m_backBufferTexture.GetMutablePtr()));
|
||||
|
||||
{
|
||||
@@ -132,10 +214,63 @@ bool GpDisplayDriverD3D11::InitResources()
|
||||
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||
rtvDesc.Texture2D.MipSlice = 0;
|
||||
|
||||
m_backBufferRTV = nullptr;
|
||||
if (m_device->CreateRenderTargetView(m_backBufferTexture, &rtvDesc, m_backBufferRTV.GetMutablePtr()) != S_OK)
|
||||
return false;
|
||||
}
|
||||
|
||||
DXGI_FORMAT vbbFormat = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
|
||||
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC vbbTextureDesc;
|
||||
vbbTextureDesc.Width = static_cast<UINT>(virtualWidth);
|
||||
vbbTextureDesc.Height = static_cast<UINT>(virtualHeight);
|
||||
vbbTextureDesc.MipLevels = 1;
|
||||
vbbTextureDesc.ArraySize = 1;
|
||||
vbbTextureDesc.Format = vbbFormat;
|
||||
vbbTextureDesc.SampleDesc.Count = 1;
|
||||
vbbTextureDesc.SampleDesc.Quality = 0;
|
||||
vbbTextureDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||
vbbTextureDesc.BindFlags = (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
|
||||
vbbTextureDesc.CPUAccessFlags = 0;
|
||||
vbbTextureDesc.MiscFlags = 0;
|
||||
|
||||
m_virtualScreenTexture = nullptr;
|
||||
if (m_device->CreateTexture2D(&vbbTextureDesc, nullptr, m_virtualScreenTexture.GetMutablePtr()) != S_OK)
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
|
||||
rtvDesc.Format = vbbFormat;
|
||||
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||
rtvDesc.Texture2D.MipSlice = 0;
|
||||
|
||||
m_virtualScreenTextureRTV = nullptr;
|
||||
if (m_device->CreateRenderTargetView(m_virtualScreenTexture, &rtvDesc, m_virtualScreenTextureRTV.GetMutablePtr()) != S_OK)
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||
srvDesc.Format = vbbFormat;
|
||||
srvDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D;
|
||||
srvDesc.Texture2D.MipLevels = 1;
|
||||
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||
|
||||
m_virtualScreenTextureSRV = nullptr;
|
||||
if (m_device->CreateShaderResourceView(m_virtualScreenTexture, &srvDesc, m_virtualScreenTextureSRV.GetMutablePtr()) != S_OK)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GpDisplayDriverD3D11::InitResources(uint32_t virtualWidth, uint32_t virtualHeight)
|
||||
{
|
||||
if (!InitBackBuffer(virtualWidth, virtualHeight))
|
||||
return false;
|
||||
|
||||
// Quad vertex constant buffer
|
||||
{
|
||||
D3D11_BUFFER_DESC bufferDesc;
|
||||
@@ -198,15 +333,30 @@ bool GpDisplayDriverD3D11::InitResources()
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
D3D11_BUFFER_DESC bufferDesc;
|
||||
bufferDesc.ByteWidth = sizeof(ScaleQuadPixelConstants);
|
||||
bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
bufferDesc.MiscFlags = 0;
|
||||
bufferDesc.StructureByteStride = 0;
|
||||
|
||||
if (m_device->CreateBuffer(&bufferDesc, nullptr, m_scaleQuadPixelConstantBuffer.GetMutablePtr()) != S_OK)
|
||||
return false;
|
||||
}
|
||||
|
||||
const GpShaderCodeBlob drawQuadVBlob = GetBinarizedShader(GpBinarizedShaders::g_drawQuadV_D3D11);
|
||||
const GpShaderCodeBlob drawQuadPalettePBlob = GetBinarizedShader(GpBinarizedShaders::g_drawQuadPaletteP_D3D11);
|
||||
const GpShaderCodeBlob drawQuadRGBPBlob = GetBinarizedShader(GpBinarizedShaders::g_drawQuadRGBP_D3D11);
|
||||
const GpShaderCodeBlob drawQuad15BitPBlob = GetBinarizedShader(GpBinarizedShaders::g_drawQuad15BitP_D3D11);
|
||||
const GpShaderCodeBlob scaleQuadPBlob = GetBinarizedShader(GpBinarizedShaders::g_scaleQuadP_D3D11);
|
||||
|
||||
m_device->CreateVertexShader(drawQuadVBlob.m_data, drawQuadVBlob.m_size, nullptr, m_drawQuadVertexShader.GetMutablePtr());
|
||||
m_device->CreatePixelShader(drawQuadPalettePBlob.m_data, drawQuadPalettePBlob.m_size, nullptr, m_drawQuadPalettePixelShader.GetMutablePtr());
|
||||
m_device->CreatePixelShader(drawQuadRGBPBlob.m_data, drawQuadRGBPBlob.m_size, nullptr, m_drawQuadRGBPixelShader.GetMutablePtr());
|
||||
m_device->CreatePixelShader(drawQuad15BitPBlob.m_data, drawQuad15BitPBlob.m_size, nullptr, m_drawQuad15BitPixelShader.GetMutablePtr());
|
||||
m_device->CreatePixelShader(scaleQuadPBlob.m_data, scaleQuadPBlob.m_size, nullptr, m_scaleQuadPixelShader.GetMutablePtr());
|
||||
|
||||
// Quad input layout
|
||||
{
|
||||
@@ -314,19 +464,18 @@ GpDisplayDriverTickStatus_t GpDisplayDriverD3D11::PresentFrameAndSync()
|
||||
{
|
||||
SynchronizeCursors();
|
||||
|
||||
float clearColor[4] = { 0.2f, 0.2f, 0.4f, 1.0f };
|
||||
m_deviceContext->ClearRenderTargetView(m_virtualScreenTextureRTV, m_bgColor);
|
||||
|
||||
m_deviceContext->ClearRenderTargetView(m_backBufferRTV, clearColor);
|
||||
|
||||
ID3D11RenderTargetView *const rtv = m_backBufferRTV;
|
||||
m_deviceContext->OMSetRenderTargets(1, &rtv, nullptr);
|
||||
//ID3D11RenderTargetView *const rtv = m_backBufferRTV;
|
||||
ID3D11RenderTargetView *const vsRTV = m_virtualScreenTextureRTV;
|
||||
m_deviceContext->OMSetRenderTargets(1, &vsRTV, nullptr);
|
||||
|
||||
{
|
||||
D3D11_VIEWPORT viewport;
|
||||
viewport.TopLeftX = 0;
|
||||
viewport.TopLeftY = 0;
|
||||
viewport.Width = static_cast<FLOAT>(m_windowWidth);
|
||||
viewport.Height = static_cast<FLOAT>(m_windowHeight);
|
||||
viewport.Width = static_cast<FLOAT>(m_windowWidthVirtual);
|
||||
viewport.Height = static_cast<FLOAT>(m_windowHeightVirtual);
|
||||
viewport.MinDepth = 0.0f;
|
||||
viewport.MaxDepth = 1.0f;
|
||||
|
||||
@@ -335,6 +484,8 @@ GpDisplayDriverTickStatus_t GpDisplayDriverD3D11::PresentFrameAndSync()
|
||||
|
||||
m_properties.m_renderFunc(m_properties.m_renderFuncContext);
|
||||
|
||||
ScaleVirtualScreen();
|
||||
|
||||
DXGI_PRESENT_PARAMETERS presentParams;
|
||||
|
||||
ZeroMemory(&presentParams, sizeof(presentParams));
|
||||
@@ -452,6 +603,101 @@ GpDisplayDriverTickStatus_t GpDisplayDriverD3D11::PresentFrameAndSync()
|
||||
return GpDisplayDriverTickStatuses::kOK;
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::ScaleVirtualScreen()
|
||||
{
|
||||
{
|
||||
D3D11_VIEWPORT viewport;
|
||||
viewport.TopLeftX = 0;
|
||||
viewport.TopLeftY = 0;
|
||||
viewport.Width = static_cast<FLOAT>(m_windowWidthPhysical);
|
||||
viewport.Height = static_cast<FLOAT>(m_windowHeightPhysical);
|
||||
viewport.MinDepth = 0.0f;
|
||||
viewport.MaxDepth = 1.0f;
|
||||
|
||||
m_deviceContext->RSSetViewports(1, &viewport);
|
||||
}
|
||||
|
||||
|
||||
ID3D11Buffer *vbPtr = m_quadVertexBuffer;
|
||||
UINT vbStride = sizeof(float) * 2;
|
||||
UINT zero = 0;
|
||||
|
||||
ID3D11RenderTargetView *const rtv = m_backBufferRTV;
|
||||
m_deviceContext->OMSetRenderTargets(1, &rtv, nullptr);
|
||||
|
||||
//m_deviceContext->OMSetDepthStencilState(m_drawQuadDepthStencilState, 0);
|
||||
|
||||
{
|
||||
const float twoDivWidth = 2.0f / static_cast<float>(m_windowWidthPhysical);
|
||||
const float negativeTwoDivHeight = -2.0f / static_cast<float>(m_windowHeightPhysical);
|
||||
|
||||
DrawQuadVertexConstants vConstantsData;
|
||||
vConstantsData.m_ndcOriginX = -1.0f;
|
||||
vConstantsData.m_ndcOriginY = 1.0f;
|
||||
vConstantsData.m_ndcWidth = 2.0f;
|
||||
vConstantsData.m_ndcHeight = -2.0f;
|
||||
|
||||
vConstantsData.m_surfaceDimensionX = static_cast<float>(m_windowWidthVirtual);
|
||||
vConstantsData.m_surfaceDimensionY = static_cast<float>(m_windowHeightVirtual);
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mappedVConstants;
|
||||
if (m_deviceContext->Map(m_drawQuadVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedVConstants) == S_OK)
|
||||
{
|
||||
memcpy(mappedVConstants.pData, &vConstantsData, sizeof(vConstantsData));
|
||||
m_deviceContext->Unmap(m_drawQuadVertexConstantBuffer, 0);
|
||||
}
|
||||
|
||||
ScaleQuadPixelConstants pConstantsData;
|
||||
pConstantsData.m_dx = static_cast<float>(static_cast<double>(m_windowWidthVirtual) / static_cast<double>(m_windowWidthPhysical));
|
||||
pConstantsData.m_dy = static_cast<float>(static_cast<double>(m_windowHeightVirtual) / static_cast<double>(m_windowHeightPhysical));
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mappedPConstants;
|
||||
if (m_deviceContext->Map(m_scaleQuadPixelConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedPConstants) == S_OK)
|
||||
{
|
||||
memcpy(mappedPConstants.pData, &pConstantsData, sizeof(pConstantsData));
|
||||
m_deviceContext->Unmap(m_scaleQuadPixelConstantBuffer, 0);
|
||||
}
|
||||
}
|
||||
|
||||
m_deviceContext->IASetVertexBuffers(0, 1, &vbPtr, &vbStride, &zero);
|
||||
m_deviceContext->IASetIndexBuffer(m_quadIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
|
||||
m_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
m_deviceContext->IASetInputLayout(m_drawQuadInputLayout);
|
||||
|
||||
ID3D11Buffer *vsConstants = m_drawQuadVertexConstantBuffer;
|
||||
m_deviceContext->VSSetShader(m_drawQuadVertexShader, nullptr, 0);
|
||||
m_deviceContext->VSSetConstantBuffers(0, 1, &vsConstants);
|
||||
|
||||
ID3D11SamplerState *samplerStates[] =
|
||||
{
|
||||
m_nearestNeighborSamplerState,
|
||||
};
|
||||
m_deviceContext->PSSetSamplers(0, sizeof(samplerStates) / sizeof(samplerStates[0]), samplerStates);
|
||||
|
||||
|
||||
ID3D11ShaderResourceView *psResourceViews[] =
|
||||
{
|
||||
m_virtualScreenTextureSRV,
|
||||
};
|
||||
|
||||
ID3D11Buffer *psConstants = m_scaleQuadPixelConstantBuffer;
|
||||
|
||||
m_deviceContext->PSSetShader(m_scaleQuadPixelShader, nullptr, 0);
|
||||
m_deviceContext->PSSetShaderResources(0, sizeof(psResourceViews) / sizeof(psResourceViews[0]), psResourceViews);
|
||||
m_deviceContext->PSSetConstantBuffers(0, 1, &psConstants);
|
||||
|
||||
m_deviceContext->DrawIndexed(6, 0, 0);
|
||||
|
||||
ID3D11ShaderResourceView *unbindPSResourceViews[] =
|
||||
{
|
||||
0,
|
||||
};
|
||||
m_deviceContext->PSSetShaderResources(0, sizeof(unbindPSResourceViews) / sizeof(unbindPSResourceViews[0]), unbindPSResourceViews);
|
||||
|
||||
ID3D11Buffer *clearBuffer = nullptr;
|
||||
m_deviceContext->PSSetConstantBuffers(0, 1, &clearBuffer);
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::SynchronizeCursors()
|
||||
{
|
||||
HCURSOR replacementCursor = nullptr;
|
||||
@@ -504,7 +750,7 @@ void GpDisplayDriverD3D11::ChangeToCursor(HCURSOR cursor)
|
||||
if (m_mouseIsInClientArea)
|
||||
::SetCursor(cursor);
|
||||
|
||||
SetClassLongPtrW(m_hwnd, GCLP_HCURSOR, reinterpret_cast<LONG_PTR>(cursor));
|
||||
SetClassLongPtrW(m_osGlobals->m_hwnd, GCLP_HCURSOR, reinterpret_cast<LONG_PTR>(cursor));
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::ChangeToStandardCursor(EGpStandardCursor_t cursor)
|
||||
@@ -524,6 +770,105 @@ void GpDisplayDriverD3D11::ChangeToStandardCursor(EGpStandardCursor_t cursor)
|
||||
}
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::BecomeFullScreen(LONG &windowStyle)
|
||||
{
|
||||
assert(!m_isFullScreen);
|
||||
|
||||
RECT windowRect;
|
||||
if (!GetWindowRect(m_osGlobals->m_hwnd, &windowRect))
|
||||
return; // ???
|
||||
|
||||
HMONITOR monitor = MonitorFromRect(&windowRect, MONITOR_DEFAULTTONULL);
|
||||
if (!monitor)
|
||||
{
|
||||
// If the window is off-screen, use the primary monitor
|
||||
monitor = MonitorFromRect(&windowRect, MONITOR_DEFAULTTOPRIMARY);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, use the nearest
|
||||
monitor = MonitorFromRect(&windowRect, MONITOR_DEFAULTTONEAREST);
|
||||
}
|
||||
|
||||
if (!monitor)
|
||||
return; // No monitor?
|
||||
|
||||
MONITORINFO monitorInfo;
|
||||
monitorInfo.cbSize = sizeof(monitorInfo);
|
||||
if (!GetMonitorInfoA(monitor, &monitorInfo))
|
||||
return;
|
||||
|
||||
m_windowModeRevertRect = windowRect;
|
||||
SetWindowLongPtr(m_osGlobals->m_hwnd, GWL_STYLE, WS_VISIBLE | WS_POPUP);
|
||||
|
||||
SetWindowPos(m_osGlobals->m_hwnd, HWND_TOP, monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top, monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top, SWP_FRAMECHANGED);
|
||||
|
||||
m_isFullScreen = true;
|
||||
windowStyle = (WS_VISIBLE | WS_POPUP);
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::BecomeWindowed(LONG &windowStyle)
|
||||
{
|
||||
assert(m_isFullScreen);
|
||||
|
||||
RECT revertRect = m_windowModeRevertRect;
|
||||
|
||||
HMONITOR monitor = MonitorFromRect(&m_windowModeRevertRect, MONITOR_DEFAULTTONULL);
|
||||
if (!monitor)
|
||||
{
|
||||
// If the window is off-screen, use the primary monitor
|
||||
monitor = MonitorFromRect(&revertRect, MONITOR_DEFAULTTOPRIMARY);
|
||||
if (!monitor)
|
||||
return;
|
||||
|
||||
MONITORINFO monitorInfo;
|
||||
monitorInfo.cbSize = sizeof(monitorInfo);
|
||||
if (!GetMonitorInfoA(monitor, &monitorInfo))
|
||||
return;
|
||||
|
||||
RECT monitorRect = monitorInfo.rcWork;
|
||||
LONG monitorWidth = monitorRect.right - monitorRect.left;
|
||||
LONG monitorHeight = monitorRect.bottom - monitorRect.top;
|
||||
|
||||
LONG revertHeight = revertRect.bottom - revertRect.top;
|
||||
LONG revertWidth = revertRect.right - revertRect.left;
|
||||
|
||||
if (revertWidth > monitorWidth)
|
||||
revertWidth = monitorWidth;
|
||||
|
||||
if (revertHeight > monitorHeight)
|
||||
revertHeight = monitorHeight;
|
||||
|
||||
revertRect.bottom = revertRect.top + revertHeight;
|
||||
revertRect.right = revertRect.right + revertWidth;
|
||||
|
||||
LONG xDelta = 0;
|
||||
if (revertRect.right > monitorRect.right)
|
||||
xDelta = monitorRect.right - revertRect.right;
|
||||
else if (revertRect.left < monitorRect.left)
|
||||
xDelta = monitorRect.left - revertRect.left;
|
||||
|
||||
LONG yDelta = 0;
|
||||
if (revertRect.bottom > monitorRect.bottom)
|
||||
yDelta = monitorRect.bottom - revertRect.bottom;
|
||||
else if (revertRect.top < monitorRect.top)
|
||||
yDelta = monitorRect.top - revertRect.top;
|
||||
|
||||
|
||||
revertRect.left = revertRect.left + xDelta;
|
||||
revertRect.top = revertRect.top + yDelta;
|
||||
revertRect.bottom = revertRect.top + revertHeight;
|
||||
revertRect.right = revertRect.right + revertWidth;
|
||||
}
|
||||
|
||||
SetWindowLongPtr(m_osGlobals->m_hwnd, GWL_STYLE, WS_VISIBLE | WS_OVERLAPPEDWINDOW);
|
||||
|
||||
SetWindowPos(m_osGlobals->m_hwnd, HWND_TOP, revertRect.left, revertRect.top, revertRect.right - revertRect.left, revertRect.bottom - revertRect.top, SWP_FRAMECHANGED);
|
||||
|
||||
m_isFullScreen = false;
|
||||
windowStyle = (WS_VISIBLE | WS_OVERLAPPEDWINDOW);
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::Run()
|
||||
{
|
||||
WNDCLASSEX wc;
|
||||
@@ -550,16 +895,16 @@ void GpDisplayDriverD3D11::Run()
|
||||
HMENU menus = NULL;
|
||||
|
||||
// TODO: Fix the resolution here
|
||||
RECT wr = { 0, 0, m_windowWidth, m_windowHeight };
|
||||
RECT wr = { 0, 0, m_windowWidthPhysical, m_windowHeightPhysical };
|
||||
AdjustWindowRect(&wr, windowStyle, menus != NULL);
|
||||
|
||||
m_hwnd = CreateWindowExW(NULL, L"GPD3D11WindowClass", GP_APPLICATION_NAME_W L" (Direct3D 11)", WS_OVERLAPPEDWINDOW, 300, 300, wr.right - wr.left, wr.bottom - wr.top, NULL, menus, m_osGlobals->m_hInstance, NULL);
|
||||
m_osGlobals->m_hwnd = CreateWindowExW(NULL, L"GPD3D11WindowClass", GP_APPLICATION_NAME_W L" (Direct3D 11)", WS_OVERLAPPEDWINDOW, 300, 300, wr.right - wr.left, wr.bottom - wr.top, NULL, menus, m_osGlobals->m_hInstance, NULL);
|
||||
|
||||
ShowWindow(m_hwnd, m_osGlobals->m_nCmdShow);
|
||||
ShowWindow(m_osGlobals->m_hwnd, m_osGlobals->m_nCmdShow);
|
||||
|
||||
StartD3DForWindow(m_hwnd, m_swapChain, m_device, m_deviceContext);
|
||||
StartD3DForWindow(m_osGlobals->m_hwnd, m_swapChain, m_device, m_deviceContext);
|
||||
|
||||
InitResources();
|
||||
InitResources(m_windowWidthVirtual, m_windowHeightVirtual);
|
||||
|
||||
LARGE_INTEGER lastTimestamp;
|
||||
memset(&lastTimestamp, 0, sizeof(lastTimestamp));
|
||||
@@ -571,9 +916,6 @@ void GpDisplayDriverD3D11::Run()
|
||||
{
|
||||
DispatchMessage(&msg);
|
||||
|
||||
if (msg.message == WM_QUIT)
|
||||
break;
|
||||
else
|
||||
{
|
||||
if (msg.message == WM_MOUSEMOVE)
|
||||
{
|
||||
@@ -586,7 +928,7 @@ void GpDisplayDriverD3D11::Run()
|
||||
|
||||
tme.cbSize = sizeof(tme);
|
||||
tme.dwFlags = TME_LEAVE;
|
||||
tme.hwndTrack = m_hwnd;
|
||||
tme.hwndTrack = m_osGlobals->m_hwnd;
|
||||
tme.dwHoverTime = HOVER_DEFAULT;
|
||||
TrackMouseEvent(&tme);
|
||||
}
|
||||
@@ -594,11 +936,59 @@ void GpDisplayDriverD3D11::Run()
|
||||
else if (msg.message == WM_MOUSELEAVE)
|
||||
m_mouseIsInClientArea = false;
|
||||
|
||||
m_osGlobals->m_translateWindowsMessageFunc(&msg, m_properties.m_eventQueue);
|
||||
m_osGlobals->m_translateWindowsMessageFunc(&msg, m_properties.m_eventQueue, m_pixelScaleX, m_pixelScaleY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_isFullScreen != m_isFullScreenDesired)
|
||||
{
|
||||
if (m_isFullScreenDesired)
|
||||
BecomeFullScreen(windowStyle);
|
||||
else
|
||||
BecomeWindowed(windowStyle);
|
||||
}
|
||||
|
||||
RECT clientRect;
|
||||
GetClientRect(m_osGlobals->m_hwnd, &clientRect);
|
||||
|
||||
unsigned int desiredWidth = clientRect.right - clientRect.left;
|
||||
unsigned int desiredHeight = clientRect.bottom - clientRect.top;
|
||||
if (clientRect.right - clientRect.left != m_windowWidthPhysical || clientRect.bottom - clientRect.top != m_windowHeightPhysical)
|
||||
{
|
||||
uint32_t prevWidth = m_windowWidthPhysical;
|
||||
uint32_t prevHeight = m_windowHeightPhysical;
|
||||
uint32_t virtualWidth = m_windowWidthVirtual;
|
||||
uint32_t virtualHeight = m_windowHeightVirtual;
|
||||
float pixelScaleX = 1.0f;
|
||||
float pixelScaleY = 1.0f;
|
||||
|
||||
if (m_properties.m_adjustRequestedResolutionFunc(m_properties.m_adjustRequestedResolutionFuncContext, desiredWidth, desiredHeight, virtualWidth, virtualHeight, pixelScaleX, pixelScaleY))
|
||||
{
|
||||
bool resizedOK = ResizeD3DWindow(m_osGlobals->m_hwnd, m_windowWidthPhysical, m_windowHeightPhysical, desiredWidth, desiredHeight, windowStyle, menus);
|
||||
resizedOK = resizedOK && DetachSwapChain();
|
||||
resizedOK = resizedOK && ResizeSwapChain(m_swapChain, m_windowWidthPhysical, m_windowHeightPhysical);
|
||||
resizedOK = resizedOK && InitBackBuffer(virtualWidth, virtualHeight);
|
||||
|
||||
if (!resizedOK)
|
||||
break; // Critical video driver error, exit
|
||||
|
||||
m_windowWidthVirtual = virtualWidth;
|
||||
m_windowHeightVirtual = virtualHeight;
|
||||
m_pixelScaleX = pixelScaleX;
|
||||
m_pixelScaleY = pixelScaleY;
|
||||
|
||||
if (GpVOSEvent *resizeEvent = m_properties.m_eventQueue->QueueEvent())
|
||||
{
|
||||
resizeEvent->m_eventType = GpVOSEventTypes::kVideoResolutionChanged;
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_prevWidth = prevWidth;
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_prevHeight = prevHeight;
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_newWidth = m_windowWidthVirtual;
|
||||
resizeEvent->m_event.m_resolutionChangedEvent.m_newHeight = m_windowHeightVirtual;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GpDisplayDriverTickStatus_t tickStatus = PresentFrameAndSync();
|
||||
if (tickStatus == GpDisplayDriverTickStatuses::kFatalFault || tickStatus == GpDisplayDriverTickStatuses::kApplicationTerminated)
|
||||
break;
|
||||
@@ -618,9 +1008,9 @@ void GpDisplayDriverD3D11::Shutdown()
|
||||
void GpDisplayDriverD3D11::GetDisplayResolution(unsigned int *width, unsigned int *height, GpPixelFormat_t *pixelFormat)
|
||||
{
|
||||
if (width)
|
||||
*width = m_windowWidth;
|
||||
*width = m_windowWidthVirtual;
|
||||
if (height)
|
||||
*height = m_windowHeight;
|
||||
*height = m_windowHeightVirtual;
|
||||
if (pixelFormat)
|
||||
*pixelFormat = GpPixelFormats::k8BitStandard;
|
||||
}
|
||||
@@ -641,8 +1031,8 @@ void GpDisplayDriverD3D11::DrawSurface(IGpDisplayDriverSurface *surface, int32_t
|
||||
//m_deviceContext->OMSetDepthStencilState(m_drawQuadDepthStencilState, 0);
|
||||
|
||||
{
|
||||
const float twoDivWidth = 2.0f / static_cast<float>(m_windowWidth);
|
||||
const float negativeTwoDivHeight = -2.0f / static_cast<float>(m_windowHeight);
|
||||
const float twoDivWidth = 2.0f / static_cast<float>(m_windowWidthVirtual);
|
||||
const float negativeTwoDivHeight = -2.0f / static_cast<float>(m_windowHeightVirtual);
|
||||
|
||||
DrawQuadVertexConstants constantsData;
|
||||
constantsData.m_ndcOriginX = static_cast<float>(x) * twoDivWidth - 1.0f;
|
||||
@@ -779,6 +1169,23 @@ void GpDisplayDriverD3D11::UpdatePalette(const void *paletteData)
|
||||
m_deviceContext->Unmap(m_paletteTexture, 0);
|
||||
}
|
||||
}
|
||||
void GpDisplayDriverD3D11::SetBackgroundColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||
{
|
||||
m_bgColor[0] = static_cast<float>(r) / 255.0f;
|
||||
m_bgColor[1] = static_cast<float>(g) / 255.0f;
|
||||
m_bgColor[2] = static_cast<float>(b) / 255.0f;
|
||||
m_bgColor[3] = static_cast<float>(a) / 255.0f;
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::RequestToggleFullScreen(uint32_t timestamp)
|
||||
{
|
||||
// Alt-Enter gets re-sent after a full-screen toggle, so we ignore toggle requests until half a second has seconds have elapsed
|
||||
if (timestamp > m_lastFullScreenToggleTimeStamp + 30)
|
||||
{
|
||||
m_isFullScreenDesired = !m_isFullScreenDesired;
|
||||
m_lastFullScreenToggleTimeStamp = timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
GpDisplayDriverD3D11 *GpDisplayDriverD3D11::Create(const GpDisplayDriverProperties &properties)
|
||||
{
|
||||
@@ -792,8 +1199,12 @@ GpDisplayDriverD3D11 *GpDisplayDriverD3D11::Create(const GpDisplayDriverProperti
|
||||
GpDisplayDriverD3D11::GpDisplayDriverD3D11(const GpDisplayDriverProperties &properties)
|
||||
: m_properties(properties)
|
||||
, m_frameTimeAccumulated(0)
|
||||
, m_windowWidth(640)
|
||||
, m_windowHeight(480)
|
||||
, m_windowWidthPhysical(640)
|
||||
, m_windowHeightPhysical(480)
|
||||
, m_windowWidthVirtual(640)
|
||||
, m_windowHeightVirtual(480)
|
||||
, m_pixelScaleX(1.0f)
|
||||
, m_pixelScaleY(1.0f)
|
||||
, m_vosFiber(nullptr)
|
||||
, m_osGlobals(static_cast<GpWindowsGlobals*>(properties.m_osGlobals))
|
||||
, m_pendingCursor(nullptr)
|
||||
@@ -801,8 +1212,12 @@ GpDisplayDriverD3D11::GpDisplayDriverD3D11(const GpDisplayDriverProperties &prop
|
||||
, m_currentStandardCursor(EGpStandardCursors::kArrow)
|
||||
, m_pendingStandardCursor(EGpStandardCursors::kArrow)
|
||||
, m_mouseIsInClientArea(false)
|
||||
, m_isFullScreen(false)
|
||||
, m_isFullScreenDesired(false)
|
||||
, m_lastFullScreenToggleTimeStamp(0)
|
||||
{
|
||||
memset(&m_syncTimeBase, 0, sizeof(m_syncTimeBase));
|
||||
memset(&m_windowModeRevertRect, 0, sizeof(m_windowModeRevertRect));
|
||||
|
||||
QueryPerformanceFrequency(&m_QPFrequency);
|
||||
|
||||
@@ -811,6 +1226,11 @@ GpDisplayDriverD3D11::GpDisplayDriverD3D11(const GpDisplayDriverProperties &prop
|
||||
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));
|
||||
|
||||
m_bgColor[0] = 0;
|
||||
m_bgColor[1] = 0;
|
||||
m_bgColor[2] = 0;
|
||||
m_bgColor[3] = 255;
|
||||
}
|
||||
|
||||
GpDisplayDriverD3D11::~GpDisplayDriverD3D11()
|
||||
|
@@ -46,6 +46,10 @@ public:
|
||||
|
||||
void UpdatePalette(const void *paletteData) override;
|
||||
|
||||
void SetBackgroundColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a) override;
|
||||
|
||||
void RequestToggleFullScreen(uint32_t timestamp) override;
|
||||
|
||||
static GpDisplayDriverD3D11 *Create(const GpDisplayDriverProperties &properties);
|
||||
|
||||
private:
|
||||
@@ -61,6 +65,13 @@ private:
|
||||
float m_unused[2];
|
||||
};
|
||||
|
||||
struct ScaleQuadPixelConstants
|
||||
{
|
||||
float m_dx;
|
||||
float m_dy;
|
||||
float m_unused[2];
|
||||
};
|
||||
|
||||
struct CompactedPresentHistoryItem
|
||||
{
|
||||
LARGE_INTEGER m_timestamp;
|
||||
@@ -70,13 +81,19 @@ private:
|
||||
GpDisplayDriverD3D11(const GpDisplayDriverProperties &properties);
|
||||
~GpDisplayDriverD3D11();
|
||||
|
||||
bool InitResources();
|
||||
bool DetachSwapChain();
|
||||
bool InitBackBuffer(uint32_t virtualWidth, uint32_t virtualHeight);
|
||||
bool InitResources(uint32_t virtualWidth, uint32_t virtualHeight);
|
||||
GpDisplayDriverTickStatus_t PresentFrameAndSync();
|
||||
void ScaleVirtualScreen();
|
||||
|
||||
void SynchronizeCursors();
|
||||
void ChangeToCursor(HCURSOR cursor);
|
||||
void ChangeToStandardCursor(EGpStandardCursor_t cursor);
|
||||
|
||||
void BecomeFullScreen(LONG &windowStyle);
|
||||
void BecomeWindowed(LONG &windowStyle);
|
||||
|
||||
GpComPtr<IDXGISwapChain1> m_swapChain;
|
||||
GpComPtr<ID3D11Device> m_device;
|
||||
GpComPtr<ID3D11DeviceContext> m_deviceContext;
|
||||
@@ -87,7 +104,9 @@ private:
|
||||
GpComPtr<ID3D11PixelShader> m_drawQuadPalettePixelShader;
|
||||
GpComPtr<ID3D11PixelShader> m_drawQuad15BitPixelShader;
|
||||
GpComPtr<ID3D11PixelShader> m_drawQuadRGBPixelShader;
|
||||
GpComPtr<ID3D11PixelShader> m_scaleQuadPixelShader;
|
||||
GpComPtr<ID3D11Buffer> m_drawQuadVertexConstantBuffer;
|
||||
GpComPtr<ID3D11Buffer> m_scaleQuadPixelConstantBuffer;
|
||||
GpComPtr<ID3D11DepthStencilState> m_drawQuadDepthStencilState;
|
||||
GpComPtr<ID3D11SamplerState> m_nearestNeighborSamplerState;
|
||||
GpComPtr<ID3D11Texture1D> m_paletteTexture;
|
||||
@@ -96,6 +115,10 @@ private:
|
||||
GpComPtr<ID3D11Texture2D> m_backBufferTexture;
|
||||
GpComPtr<ID3D11RenderTargetView> m_backBufferRTV;
|
||||
|
||||
GpComPtr<ID3D11Texture2D> m_virtualScreenTexture;
|
||||
GpComPtr<ID3D11RenderTargetView> m_virtualScreenTextureRTV;
|
||||
GpComPtr<ID3D11ShaderResourceView> m_virtualScreenTextureSRV;
|
||||
|
||||
GpRingBuffer<CompactedPresentHistoryItem, 60> m_presentHistory;
|
||||
GpDisplayDriverProperties m_properties;
|
||||
|
||||
@@ -104,11 +127,20 @@ private:
|
||||
UINT m_expectedSyncDelta;
|
||||
bool m_isResettingSwapChain;
|
||||
|
||||
bool m_isFullScreen;
|
||||
bool m_isFullScreenDesired;
|
||||
RECT m_windowModeRevertRect;
|
||||
uint32_t m_lastFullScreenToggleTimeStamp;
|
||||
|
||||
LONGLONG m_frameTimeAccumulated;
|
||||
LONGLONG m_frameTimeSliceSize;
|
||||
|
||||
DWORD m_windowWidth;
|
||||
DWORD m_windowHeight;
|
||||
DWORD m_windowWidthPhysical; // Physical resolution is the resolution of the actual window
|
||||
DWORD m_windowHeightPhysical;
|
||||
DWORD m_windowWidthVirtual; // Virtual resolution is the resolution reported to teh game
|
||||
DWORD m_windowHeightVirtual;
|
||||
float m_pixelScaleX;
|
||||
float m_pixelScaleY;
|
||||
|
||||
IGpCursor_Win32 *m_activeCursor;
|
||||
IGpCursor_Win32 *m_pendingCursor;
|
||||
@@ -122,5 +154,6 @@ private:
|
||||
HCURSOR m_arrowCursor;
|
||||
HCURSOR m_waitCursor;
|
||||
HCURSOR m_ibeamCursor;
|
||||
HWND m_hwnd;
|
||||
|
||||
float m_bgColor[4];
|
||||
};
|
||||
|
@@ -127,6 +127,7 @@
|
||||
<ClCompile Include="CompiledShaders\DrawQuadPaletteP_D3D11.cpp" />
|
||||
<ClCompile Include="CompiledShaders\DrawQuadRGBP_D3D11.cpp" />
|
||||
<ClCompile Include="CompiledShaders\DrawQuadV_D3D11.cpp" />
|
||||
<ClCompile Include="CompiledShaders\ScaleQuadP_D3D11.cpp" />
|
||||
<ClCompile Include="GpDisplayDriverD3D11.cpp" />
|
||||
<ClCompile Include="GpDisplayDriverFactoryD3D11.cpp" />
|
||||
<ClCompile Include="GpDisplayDriverSurfaceD3D11.cpp" />
|
||||
|
@@ -39,6 +39,9 @@
|
||||
<ClCompile Include="CompiledShaders\DrawQuadV_D3D11.cpp">
|
||||
<Filter>Source Files\CompiledShaders</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CompiledShaders\ScaleQuadP_D3D11.cpp">
|
||||
<Filter>Source Files\CompiledShaders</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="GpDisplayDriverD3D11.h">
|
||||
|
339
LICENSE-GPL2.txt
339
LICENSE-GPL2.txt
@@ -1,339 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
@@ -1,19 +0,0 @@
|
||||
GlidePort copyright (c)2019 Eric Lasota
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
356
LICENSE.txt
356
LICENSE.txt
@@ -1,17 +1,339 @@
|
||||
Aerofoil is (c)2019-2020 Eric Lasota
|
||||
|
||||
Based on Glider PRO by John Calhoun
|
||||
|
||||
Aerofoil is made available under the following dual-license terms:
|
||||
|
||||
- You may use any portion of the Aerofoil project's source code under the
|
||||
conditions of the GNU General Public License version 2, as published in the
|
||||
included LICENSE-GPL2.txt file.
|
||||
|
||||
- If you obtain a license to use the Glider PRO source code under terms other
|
||||
than the terms of the GNU General Public License version 2, or if you do not
|
||||
require a license (i.e. because you hold the copyright), or if you are are
|
||||
permitted to use Glider PRO's source code under different terms for any
|
||||
other reason, you may use any new source code and modifications in the
|
||||
Aerofoil source code under the conditions of the MIT license, as published
|
||||
in the included LICENSE-MIT.txt file.
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
16
PortabilityLayer/AppEventHandler.cpp
Normal file
16
PortabilityLayer/AppEventHandler.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "AppEventHandler.h"
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
IAppEventHandler *AppEventHandler::ms_instance;
|
||||
|
||||
IAppEventHandler *AppEventHandler::GetInstance()
|
||||
{
|
||||
return ms_instance;
|
||||
}
|
||||
|
||||
void AppEventHandler::SetInstance(IAppEventHandler *instance)
|
||||
{
|
||||
ms_instance = instance;
|
||||
}
|
||||
}
|
19
PortabilityLayer/AppEventHandler.h
Normal file
19
PortabilityLayer/AppEventHandler.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
struct IAppEventHandler
|
||||
{
|
||||
virtual void OnQuit() = 0;
|
||||
};
|
||||
|
||||
class AppEventHandler
|
||||
{
|
||||
public:
|
||||
static IAppEventHandler *GetInstance();
|
||||
static void SetInstance(IAppEventHandler *instance);
|
||||
|
||||
private:
|
||||
static IAppEventHandler *ms_instance;
|
||||
};
|
||||
}
|
21
PortabilityLayer/ArrayTools.h
Normal file
21
PortabilityLayer/ArrayTools.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
class ArrayTools
|
||||
{
|
||||
public:
|
||||
template<class T, class TSize, class TIndex>
|
||||
static void RemoveFromArray(T *arr, TSize &count, TIndex index)
|
||||
{
|
||||
TSize countCopy = count;
|
||||
countCopy--;
|
||||
if (countCopy != index)
|
||||
arr[index] = arr[countCopy];
|
||||
|
||||
count = static_cast<TSize>(countCopy);
|
||||
}
|
||||
};
|
||||
}
|
@@ -22,6 +22,9 @@ namespace PortabilityLayer
|
||||
void IncrementTickCount(uint32_t count) override;
|
||||
uint32_t GetTickCount() override;
|
||||
|
||||
void SetResolutionChangeHandler(IResolutionChangeHandler *handler) override;
|
||||
IResolutionChangeHandler *GetResolutionChangeHandler() const override;
|
||||
|
||||
static DisplayDeviceManagerImpl *GetInstance();
|
||||
|
||||
private:
|
||||
@@ -29,6 +32,8 @@ namespace PortabilityLayer
|
||||
GpPixelFormat_t m_pixelFormat;
|
||||
bool m_paletteIsDirty;
|
||||
|
||||
IResolutionChangeHandler *m_resChangeHandler;
|
||||
|
||||
PortabilityLayer::RGBAColor *m_palette;
|
||||
uint8_t m_paletteStorage[256 * sizeof(PortabilityLayer::RGBAColor) + GP_SYSTEM_MEMORY_ALIGNMENT];
|
||||
|
||||
@@ -39,6 +44,7 @@ namespace PortabilityLayer
|
||||
: m_tickCount(1)
|
||||
, m_paletteIsDirty(true)
|
||||
, m_pixelFormat(GpPixelFormats::k8BitStandard)
|
||||
, m_resChangeHandler(nullptr)
|
||||
{
|
||||
uint8_t *paletteStorage = m_paletteStorage;
|
||||
while (reinterpret_cast<intptr_t>(paletteStorage) % GP_SYSTEM_MEMORY_ALIGNMENT != 0)
|
||||
@@ -93,6 +99,15 @@ namespace PortabilityLayer
|
||||
return m_tickCount;
|
||||
}
|
||||
|
||||
void DisplayDeviceManagerImpl::SetResolutionChangeHandler(IResolutionChangeHandler *handler)
|
||||
{
|
||||
m_resChangeHandler = handler;
|
||||
}
|
||||
|
||||
DisplayDeviceManagerImpl::IResolutionChangeHandler *DisplayDeviceManagerImpl::GetResolutionChangeHandler() const
|
||||
{
|
||||
return m_resChangeHandler;
|
||||
}
|
||||
|
||||
DisplayDeviceManagerImpl *DisplayDeviceManagerImpl::GetInstance()
|
||||
{
|
||||
|
@@ -1,28 +1,39 @@
|
||||
#pragma once
|
||||
#ifndef __PL_DEVICE_MANAGER_H__
|
||||
#define __PL_DEVICE_MANAGER_H__
|
||||
|
||||
#pragma once
|
||||
#ifndef __PL_DEVICE_MANAGER_H__
|
||||
#define __PL_DEVICE_MANAGER_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "GpPixelFormat.h"
|
||||
|
||||
struct IGpDisplayDriver;
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
class DisplayDeviceManager
|
||||
{
|
||||
public:
|
||||
virtual void Init() = 0;
|
||||
struct IGpDisplayDriver;
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
class DisplayDeviceManager
|
||||
{
|
||||
public:
|
||||
struct IResolutionChangeHandler
|
||||
{
|
||||
virtual void OnResolutionChanged(uint32_t prevWidth, uint32_t prevHeight, uint32_t newWidth, uint32_t newHeight) = 0;
|
||||
virtual void AdjustRequestedResolution(uint32_t &physicalWidth, uint32_t &physicalHeight, uint32_t &virtualWidth, uint32_t &virtualheight, float &pixelScaleX, float &pixelScaleY) = 0;
|
||||
};
|
||||
|
||||
virtual void Init() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
virtual GpPixelFormat_t GetPixelFormat() const = 0;
|
||||
virtual void SyncPalette(IGpDisplayDriver *displayDriver) = 0;
|
||||
|
||||
virtual void IncrementTickCount(uint32_t count) = 0;
|
||||
virtual uint32_t GetTickCount() = 0;
|
||||
|
||||
static DisplayDeviceManager *GetInstance();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
virtual void SyncPalette(IGpDisplayDriver *displayDriver) = 0;
|
||||
|
||||
virtual void IncrementTickCount(uint32_t count) = 0;
|
||||
virtual uint32_t GetTickCount() = 0;
|
||||
|
||||
virtual void SetResolutionChangeHandler(IResolutionChangeHandler *handler) = 0;
|
||||
virtual IResolutionChangeHandler *GetResolutionChangeHandler() const = 0;
|
||||
|
||||
static DisplayDeviceManager *GetInstance();
|
||||
|
||||
public:
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -6,6 +6,7 @@
|
||||
#include "MacFileMem.h"
|
||||
#include "PLPasStr.h"
|
||||
#include "PLErrorCodes.h"
|
||||
#include "PLSysCalls.h"
|
||||
#include "ResTypeID.h"
|
||||
#include "HostSystemServices.h"
|
||||
|
||||
@@ -184,7 +185,7 @@ namespace PortabilityLayer
|
||||
|
||||
bool FileManagerImpl::PromptOpenFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity)
|
||||
{
|
||||
return PortabilityLayer::HostFileSystem::GetInstance()->PromptOpenFile(dirID, path, outPathLength, pathCapacity);
|
||||
return PLSysCalls::PromptOpenFile(dirID, path, outPathLength, pathCapacity);
|
||||
}
|
||||
|
||||
FileManagerImpl *FileManagerImpl::GetInstance()
|
||||
|
@@ -38,14 +38,15 @@ public:
|
||||
virtual int ApplicationMain() = 0;
|
||||
virtual void PL_IncrementTickCounter(uint32_t count) = 0;
|
||||
virtual void PL_Render(IGpDisplayDriver *displayDriver) = 0;
|
||||
virtual void PL_HostAudioDriver_SetInstance(IGpAudioDriver *instance) = 0;
|
||||
virtual void PL_HostFileSystem_SetInstance(PortabilityLayer::HostFileSystem *instance) = 0;
|
||||
virtual void PL_HostDisplayDriver_SetInstance(IGpDisplayDriver *instance) = 0;
|
||||
virtual void PL_HostSystemServices_SetInstance(PortabilityLayer::HostSystemServices *instance) = 0;
|
||||
virtual void PL_HostFontHandler_SetInstance(PortabilityLayer::HostFontHandler *instance) = 0;
|
||||
virtual void PL_HostVOSEventQueue_SetInstance(PortabilityLayer::HostVOSEventQueue *instance) = 0;
|
||||
virtual void PL_InstallHostSuspendHook(PortabilityLayer::HostSuspendHook_t hook, void *context) = 0;
|
||||
|
||||
virtual void PL_HostAudioDriver_SetInstance(IGpAudioDriver *instance) = 0;
|
||||
virtual void PL_InstallHostSuspendHook(PortabilityLayer::HostSuspendHook_t hook, void *context) = 0;
|
||||
virtual bool PL_AdjustRequestedResolution(uint32_t &physicalWidth, uint32_t &physicalHeight, uint32_t &virtualWidth, uint32_t &virtualheight, float &pixelScaleX, float &pixelScaleY) = 0;
|
||||
};
|
||||
|
||||
GP_APP_DLL_EXPORT_API GpAppInterface *GpAppInterface_Get();
|
||||
|
@@ -12,6 +12,7 @@ namespace PortabilityLayer
|
||||
int32_t m_int;
|
||||
size_t m_size;
|
||||
void *m_pointer;
|
||||
const void *m_constPointer;
|
||||
const void *m_constPointer;
|
||||
void (*m_functionPtr)(const HostSuspendCallArgument *args, HostSuspendCallArgument *returnValue);
|
||||
};
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@ namespace PortabilityLayer
|
||||
HostSuspendCallID_Unknown,
|
||||
|
||||
HostSuspendCallID_Delay,
|
||||
HostSuspendCallID_CallOnVOSThread,
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -145,6 +145,7 @@ namespace PortabilityLayer
|
||||
PLPasStr GetItemText(const THandle<Menu> &menu, unsigned int index) const override;
|
||||
|
||||
bool IsPointInMenuBar(const Vec2i &point) const override;
|
||||
uint16_t GetMenuBarHeight() const override;
|
||||
|
||||
bool FindMenuShortcut(uint16_t &menuID, uint16_t &itemID, uint8_t shortcutChar) override;
|
||||
void MenuSelect(const Vec2i &initialPoint, int16_t *outMenu, uint16_t *outItem) override;
|
||||
@@ -598,6 +599,10 @@ namespace PortabilityLayer
|
||||
return point.m_y >= 0 && static_cast<uint32_t>(point.m_y) < kMenuBarHeight;
|
||||
}
|
||||
|
||||
uint16_t MenuManagerImpl::GetMenuBarHeight() const
|
||||
{
|
||||
return kMenuBarHeight;
|
||||
}
|
||||
|
||||
bool MenuManagerImpl::FindMenuShortcut(uint16_t &menuID, uint16_t &itemID, uint8_t shortcutChar)
|
||||
{
|
||||
|
@@ -40,6 +40,7 @@ namespace PortabilityLayer
|
||||
virtual PLPasStr GetItemText(const THandle<Menu> &menu, unsigned int index) const = 0;
|
||||
|
||||
virtual bool IsPointInMenuBar(const Vec2i &point) const = 0;
|
||||
virtual uint16_t GetMenuBarHeight() const = 0;
|
||||
|
||||
virtual bool FindMenuShortcut(uint16_t &menuID, uint16_t &itemID, uint8_t shortcutChar) = 0;
|
||||
virtual void MenuSelect(const Vec2i &initialPoint, int16_t *outMenu, uint16_t *outItem) = 0;
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#include "PLCore.h"
|
||||
#include "AppEventHandler.h"
|
||||
#include "PLEventQueue.h"
|
||||
#include "PLKeyEncoding.h"
|
||||
#include "PLMovies.h"
|
||||
@@ -6,7 +7,10 @@
|
||||
#include "PLTimeTaggedVOSEvent.h"
|
||||
#include "DisplayDeviceManager.h"
|
||||
#include "GpVOSEvent.h"
|
||||
#include "IGpDisplayDriver.h"
|
||||
#include "InputManager.h"
|
||||
#include "HostDisplayDriver.h"
|
||||
#include "HostFileSystem.h"
|
||||
#include "HostSuspendCallArgument.h"
|
||||
#include "HostSuspendHook.h"
|
||||
#include "HostVOSEventQueue.h"
|
||||
@@ -47,6 +51,13 @@ static void TranslateGamepadInputEvent(const GpGamepadInputEvent &vosEvent, Port
|
||||
PL_DEAD(queue);
|
||||
}
|
||||
|
||||
static void TranslateVideoResolutionChangedEvent(const GpVideoResolutionChangedEvent &evt)
|
||||
{
|
||||
PortabilityLayer::DisplayDeviceManager::IResolutionChangeHandler *chgHandler = PortabilityLayer::DisplayDeviceManager::GetInstance()->GetResolutionChangeHandler();
|
||||
if (chgHandler)
|
||||
chgHandler->OnResolutionChanged(evt.m_prevWidth, evt.m_prevHeight, evt.m_newWidth, evt.m_newHeight);
|
||||
}
|
||||
|
||||
static void TranslateKeyboardInputEvent(const GpVOSEvent &vosEventBase, uint32_t timestamp, PortabilityLayer::EventQueue *queue)
|
||||
{
|
||||
const GpKeyboardInputEvent &vosEvent = vosEventBase.m_event.m_keyboardInputEvent;
|
||||
@@ -59,6 +70,20 @@ static void TranslateKeyboardInputEvent(const GpVOSEvent &vosEventBase, uint32_t
|
||||
if (vosEvent.m_eventType == GpKeyboardInputEventTypes::kUp || vosEvent.m_eventType == GpKeyboardInputEventTypes::kDown)
|
||||
inputManager->ApplyKeyboardEvent(vosEvent);
|
||||
|
||||
// Special handling of alt-enter, redirect to display driver
|
||||
if (vosEventBase.m_eventType == GpKeyboardInputEventTypes::kDown &&
|
||||
vosEventBase.m_event.m_keyboardInputEvent.m_keyIDSubset == GpKeyIDSubsets::kSpecial &&
|
||||
vosEventBase.m_event.m_keyboardInputEvent.m_key.m_specialKey == GpKeySpecials::kEnter)
|
||||
{
|
||||
const KeyDownStates *keyStates = inputManager->GetKeys();
|
||||
if (keyStates->m_special.Get(GpKeySpecials::kLeftAlt) || keyStates->m_special.Get(GpKeySpecials::kRightAlt))
|
||||
{
|
||||
IGpDisplayDriver *dd = PortabilityLayer::HostDisplayDriver::GetInstance();
|
||||
if (dd)
|
||||
dd->RequestToggleFullScreen(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
if (TimeTaggedVOSEvent *evt = queue->Enqueue())
|
||||
*evt = TimeTaggedVOSEvent::Create(vosEventBase, timestamp);
|
||||
}
|
||||
@@ -108,6 +133,17 @@ static void TranslateVOSEvent(const GpVOSEvent *vosEvent, uint32_t timestamp, Po
|
||||
case GpVOSEventTypes::kGamepadInput:
|
||||
TranslateGamepadInputEvent(vosEvent->m_event.m_gamepadInputEvent, queue);
|
||||
break;
|
||||
case GpVOSEventTypes::kVideoResolutionChanged:
|
||||
TranslateVideoResolutionChangedEvent(vosEvent->m_event.m_resolutionChangedEvent);
|
||||
break;
|
||||
case GpVOSEventTypes::kQuit:
|
||||
if (TimeTaggedVOSEvent *evt = queue->Enqueue())
|
||||
*evt = TimeTaggedVOSEvent::Create(*vosEvent, timestamp);
|
||||
|
||||
if (PortabilityLayer::IAppEventHandler *appHandler = PortabilityLayer::AppEventHandler::GetInstance())
|
||||
appHandler->OnQuit();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,4 +175,63 @@ namespace PLSysCalls
|
||||
AnimationManager::GetInstance()->TickPlayers(ticks);
|
||||
}
|
||||
}
|
||||
|
||||
static void PromptOpenFileCallback(const PortabilityLayer::HostSuspendCallArgument *args, PortabilityLayer::HostSuspendCallArgument *returnValue)
|
||||
{
|
||||
bool result = PortabilityLayer::HostFileSystem::GetInstance()->PromptOpenFile(static_cast<PortabilityLayer::VirtualDirectory_t>(args[0].m_int), static_cast<char*>(args[1].m_pointer), *static_cast<size_t*>(args[2].m_pointer), args[3].m_uint);
|
||||
returnValue->m_uint = (result ? 1 : 0);
|
||||
}
|
||||
|
||||
bool PromptOpenFile(PortabilityLayer::VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity)
|
||||
{
|
||||
PortabilityLayer::HostSuspendCallArgument cbArgs[4];
|
||||
cbArgs[0].m_int = static_cast<int32_t>(dirID);
|
||||
cbArgs[1].m_pointer = path;
|
||||
cbArgs[2].m_pointer = &outPathLength;
|
||||
cbArgs[3].m_size = pathCapacity;
|
||||
|
||||
PortabilityLayer::HostSuspendCallArgument cbReturnValue;
|
||||
|
||||
PortabilityLayer::HostSuspendCallArgument dispatchArgs[3];
|
||||
dispatchArgs[0].m_functionPtr = PromptOpenFileCallback;
|
||||
dispatchArgs[1].m_constPointer = cbArgs;
|
||||
dispatchArgs[2].m_pointer = &cbReturnValue;
|
||||
|
||||
PortabilityLayer::SuspendApplication(PortabilityLayer::HostSuspendCallID_CallOnVOSThread, dispatchArgs, nullptr);
|
||||
|
||||
return cbReturnValue.m_uint != 0;
|
||||
}
|
||||
|
||||
static void PromptSaveFileCallback(const PortabilityLayer::HostSuspendCallArgument *args, PortabilityLayer::HostSuspendCallArgument *returnValue)
|
||||
{
|
||||
bool result = PortabilityLayer::HostFileSystem::GetInstance()->PromptSaveFile(
|
||||
static_cast<PortabilityLayer::VirtualDirectory_t>(args[0].m_int),
|
||||
static_cast<char*>(args[1].m_pointer),
|
||||
*static_cast<size_t*>(args[2].m_pointer),
|
||||
args[3].m_uint,
|
||||
static_cast<const char*>(args[4].m_constPointer));
|
||||
|
||||
returnValue->m_uint = (result ? 1 : 0);
|
||||
}
|
||||
|
||||
bool PromptSaveFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, char *path, size_t &outPathLength, size_t pathCapacity, const char *initialFileName)
|
||||
{
|
||||
PortabilityLayer::HostSuspendCallArgument cbArgs[5];
|
||||
cbArgs[0].m_int = static_cast<int32_t>(virtualDirectory);
|
||||
cbArgs[1].m_pointer = path;
|
||||
cbArgs[2].m_pointer = &outPathLength;
|
||||
cbArgs[3].m_size = pathCapacity;
|
||||
cbArgs[3].m_constPointer = initialFileName;
|
||||
|
||||
PortabilityLayer::HostSuspendCallArgument cbReturnValue;
|
||||
|
||||
PortabilityLayer::HostSuspendCallArgument dispatchArgs[3];
|
||||
dispatchArgs[0].m_functionPtr = PromptSaveFileCallback;
|
||||
dispatchArgs[1].m_constPointer = cbArgs;
|
||||
dispatchArgs[2].m_pointer = &cbReturnValue;
|
||||
|
||||
PortabilityLayer::SuspendApplication(PortabilityLayer::HostSuspendCallID_CallOnVOSThread, dispatchArgs, nullptr);
|
||||
|
||||
return cbReturnValue.m_uint != 0;
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "VirtualDirectory.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace PLSysCalls
|
||||
{
|
||||
{
|
||||
void Sleep(uint32_t ticks);
|
||||
bool PromptOpenFile(PortabilityLayer::VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity);
|
||||
bool PromptSaveFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, char *path, size_t &outPathLength, size_t pathCapacity, const char *initialFileName);
|
||||
}
|
||||
|
@@ -146,6 +146,8 @@
|
||||
<ClInclude Include="AEHandlerDesc.h" />
|
||||
<ClInclude Include="AEManager.h" />
|
||||
<ClInclude Include="AntiAliasTable.h" />
|
||||
<ClInclude Include="AppEventHandler.h" />
|
||||
<ClInclude Include="ArrayTools.h" />
|
||||
<ClInclude Include="BinarySearch.h" />
|
||||
<ClInclude Include="BinHex4.h" />
|
||||
<ClInclude Include="BitmapImage.h" />
|
||||
@@ -302,6 +304,7 @@
|
||||
<ClCompile Include="..\stb\stb_image_write.c" />
|
||||
<ClCompile Include="AEManager.cpp" />
|
||||
<ClCompile Include="AntiAliasTable.cpp" />
|
||||
<ClCompile Include="AppEventHandler.cpp" />
|
||||
<ClCompile Include="BinHex4.cpp" />
|
||||
<ClCompile Include="BitmapImage.cpp" />
|
||||
<ClCompile Include="ByteSwap.cpp" />
|
||||
|
@@ -480,6 +480,12 @@
|
||||
<ClInclude Include="TextPlacer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ArrayTools.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="AppEventHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CFileStream.cpp">
|
||||
@@ -755,5 +761,8 @@
|
||||
<ClCompile Include="TextPlacer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="AppEventHandler.cpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@@ -14,9 +14,12 @@
|
||||
#include "QDManager.h"
|
||||
#include "QDPixMap.h"
|
||||
#include "PLTimeTaggedVOSEvent.h"
|
||||
#include "Rect2i.h"
|
||||
#include "Vec2i.h"
|
||||
#include "WindowDef.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
struct GDevice;
|
||||
|
||||
namespace PortabilityLayer
|
||||
@@ -127,9 +130,12 @@ namespace PortabilityLayer
|
||||
void DestroyWindow(Window *window) override;
|
||||
void DragWindow(Window *window, const Point &startPoint, const Rect &constraintRect) override;
|
||||
void SetWindowTitle(Window *window, const PLPasStr &title) override;
|
||||
Rect2i GetWindowFullRect(Window *window) const override;
|
||||
|
||||
void RenderFrame(IGpDisplayDriver *displayDriver) override;
|
||||
|
||||
void HandleScreenResolutionChange(uint32_t prevWidth, uint32_t prevHeight, uint32_t newWidth, uint32_t newHeight) override;
|
||||
|
||||
Window *GetPutInFrontSentinel() const override;
|
||||
|
||||
static WindowManagerImpl *GetInstance();
|
||||
@@ -553,7 +559,13 @@ namespace PortabilityLayer
|
||||
|
||||
void WindowImpl::GetChromePadding(uint16_t padding[WindowChromeSides::kCount]) const
|
||||
{
|
||||
return m_chromeTheme->GetChromePadding(this, padding);
|
||||
if (m_chromeTheme)
|
||||
m_chromeTheme->GetChromePadding(this, padding);
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < WindowChromeSides::kCount; i++)
|
||||
padding[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void WindowImpl::GetChromeDimensions(int width, int height, Rect dimensions[WindowChromeSides::kCount]) const
|
||||
@@ -572,6 +584,9 @@ namespace PortabilityLayer
|
||||
|
||||
bool WindowImpl::GetChromeInteractionZone(const Vec2i &point, RegionID_t &outRegion) const
|
||||
{
|
||||
if (!m_chromeTheme)
|
||||
return false;
|
||||
|
||||
return m_chromeTheme->GetChromeInteractionZone(this, point, outRegion);
|
||||
}
|
||||
|
||||
@@ -784,6 +799,18 @@ namespace PortabilityLayer
|
||||
static_cast<WindowImpl*>(window)->SetTitle(title);
|
||||
}
|
||||
|
||||
Rect2i WindowManagerImpl::GetWindowFullRect(Window *window) const
|
||||
{
|
||||
WindowImpl *windowImpl = static_cast<WindowImpl*>(window);
|
||||
|
||||
uint16_t padding[WindowChromeSides::kCount];
|
||||
windowImpl->GetChromePadding(padding);
|
||||
|
||||
const Rect portRect = windowImpl->m_surface.m_port.GetRect();
|
||||
|
||||
return Rect2i(window->m_wmY - padding[WindowChromeSides::kTop], window->m_wmX - padding[WindowChromeSides::kLeft], window->m_wmY + portRect.Height() + padding[WindowChromeSides::kBottom], window->m_wmX + portRect.Width() + padding[WindowChromeSides::kRight]);
|
||||
}
|
||||
|
||||
void WindowManagerImpl::RenderFrame(IGpDisplayDriver *displayDriver)
|
||||
{
|
||||
PortabilityLayer::DisplayDeviceManager *dd = PortabilityLayer::DisplayDeviceManager::GetInstance();
|
||||
@@ -798,6 +825,53 @@ namespace PortabilityLayer
|
||||
}
|
||||
}
|
||||
|
||||
void WindowManagerImpl::HandleScreenResolutionChange(uint32_t prevWidth, uint32_t prevHeight, uint32_t newWidth, uint32_t newHeight)
|
||||
{
|
||||
const uint32_t menuBarHeight = PortabilityLayer::MenuManager::GetInstance()->GetMenuBarHeight();
|
||||
|
||||
for (PortabilityLayer::WindowImpl *window = m_windowStackTop; window != nullptr; window = window->GetWindowBelow())
|
||||
{
|
||||
uint16_t chromePadding[WindowChromeSides::kCount];
|
||||
window->GetChromePadding(chromePadding);
|
||||
|
||||
const Rect surfaceRect = window->GetDrawSurface()->m_port.GetRect();
|
||||
|
||||
uint32_t paddedWidth = surfaceRect.Width() + chromePadding[WindowChromeSides::kLeft] + chromePadding[WindowChromeSides::kRight];
|
||||
uint32_t paddedHeight = surfaceRect.Height() + chromePadding[WindowChromeSides::kTop] + chromePadding[WindowChromeSides::kBottom];
|
||||
|
||||
int64_t newX = 0;
|
||||
if (newWidth <= paddedWidth || prevWidth <= paddedWidth)
|
||||
newX = (static_cast<int64_t>(newWidth) - paddedWidth) / 2;
|
||||
else
|
||||
{
|
||||
uint32_t prevClearanceX = prevWidth - paddedWidth;
|
||||
uint32_t newClearanceX = newWidth - paddedWidth;
|
||||
newX = static_cast<int64_t>(window->m_wmX) * static_cast<int64_t>(newClearanceX) / static_cast<int64_t>(prevClearanceX);
|
||||
}
|
||||
|
||||
int64_t newY = 0;
|
||||
if (window->m_wmY < static_cast<int32_t>(menuBarHeight))
|
||||
newY = window->m_wmY;
|
||||
else
|
||||
{
|
||||
if (newHeight <= (paddedHeight + menuBarHeight) || prevHeight <= paddedHeight + menuBarHeight)
|
||||
newY = (static_cast<int64_t>(newHeight) - paddedHeight - menuBarHeight) / 2 + menuBarHeight;
|
||||
else
|
||||
{
|
||||
uint32_t prevClearanceY = prevHeight - paddedHeight - menuBarHeight;
|
||||
uint32_t newClearanceY = newHeight - paddedHeight - menuBarHeight;
|
||||
newY = (static_cast<int64_t>(window->m_wmY) - static_cast<int64_t>(menuBarHeight) - chromePadding[WindowChromeSides::kTop]) * static_cast<int64_t>(newClearanceY) / static_cast<int64_t>(prevClearanceY) + menuBarHeight + chromePadding[WindowChromeSides::kTop];
|
||||
}
|
||||
}
|
||||
|
||||
newX = std::max<int64_t>(0, std::min<int64_t>(newX, newWidth - 1));
|
||||
newY = std::max<int64_t>(0, std::min<int64_t>(newY, newHeight - 1));
|
||||
|
||||
window->m_wmX = static_cast<int32_t>(newX);
|
||||
window->m_wmY = static_cast<int32_t>(newY);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowManagerImpl::ResizeWindow(Window *window, int width, int height)
|
||||
{
|
||||
static_cast<WindowImpl*>(window)->Resize(width, height);
|
||||
|
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct Window;
|
||||
struct DrawSurface;
|
||||
struct GDevice;
|
||||
@@ -12,6 +14,7 @@ struct Window;
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
struct WindowDef;
|
||||
struct Rect2i;
|
||||
|
||||
class WindowManager
|
||||
{
|
||||
@@ -27,9 +30,12 @@ namespace PortabilityLayer
|
||||
virtual void DestroyWindow(Window *window) = 0;
|
||||
virtual void DragWindow(Window *window, const Point &startPoint, const Rect &constraintRect) = 0;
|
||||
virtual void SetWindowTitle(Window *window, const PLPasStr &title) = 0;
|
||||
virtual Rect2i GetWindowFullRect(Window *window) const = 0;
|
||||
|
||||
virtual void RenderFrame(IGpDisplayDriver *displayDriver) = 0;
|
||||
|
||||
virtual void HandleScreenResolutionChange(uint32_t prevWidth, uint32_t prevHeight, uint32_t newWidth, uint32_t newHeight) = 0;
|
||||
|
||||
static WindowManager *GetInstance();
|
||||
};
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ namespace PortabilityLayer
|
||||
{
|
||||
class IOStream;
|
||||
struct ZipCentralDirectoryFileHeader;
|
||||
|
||||
|
||||
class ZipFileProxy
|
||||
{
|
||||
public:
|
||||
|
@@ -9,14 +9,16 @@ struct SDrawQuadPixelOutput
|
||||
float4 color : SV_TARGET;
|
||||
};
|
||||
|
||||
float3 SamplePixel(int2 texCoord)
|
||||
{
|
||||
uint surfaceColor = surfaceTexture.Load(int3(texCoord, 0)).r;
|
||||
return paletteTexture.Load(int2(surfaceColor, 0)).rgb;
|
||||
}
|
||||
|
||||
SDrawQuadPixelOutput PSMain(SDrawQuadPixelInput input)
|
||||
{
|
||||
int2 texCoord = input.texCoord.xy;
|
||||
|
||||
uint surfaceColor = surfaceTexture.Load(int3(texCoord, 0)).r;
|
||||
float3 paletteColor = paletteTexture.Load(int2(surfaceColor, 0)).rgb;
|
||||
|
||||
SDrawQuadPixelOutput result;
|
||||
result.color = float4(paletteColor.rgb, 1.0);
|
||||
result.color = float4(SamplePixel(int2(floor(input.texCoord.xy))), 1.0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#include "DrawQuad.h"
|
||||
|
||||
SamplerState surfaceSampler : register(s0);
|
||||
Texture2D<float> surfaceTexture : register(t0);
|
||||
Texture2D<float3> surfaceTexture : register(t0);
|
||||
|
||||
struct SDrawQuadPixelOutput
|
||||
{
|
||||
@@ -10,9 +10,9 @@ struct SDrawQuadPixelOutput
|
||||
|
||||
SDrawQuadPixelOutput PSMain(SDrawQuadPixelInput input)
|
||||
{
|
||||
float surfaceColor = surfaceTexture.Sample(surfaceSampler, input.texCoord.xy).r;
|
||||
float3 surfaceColor = surfaceTexture.Load(int3(input.texCoord.xy, 0)).rgb;
|
||||
|
||||
SDrawQuadPixelOutput result;
|
||||
result.color = float4(surfaceColor, input.texCoord.x, input.texCoord.y, 1.0);
|
||||
result.color = float4(surfaceColor, 1.0);
|
||||
return result;
|
||||
}
|
||||
|
47
ShaderSrc/ScaleQuadP.hlsl
Normal file
47
ShaderSrc/ScaleQuadP.hlsl
Normal file
@@ -0,0 +1,47 @@
|
||||
#include "DrawQuad.h"
|
||||
|
||||
SamplerState surfaceSampler : register(s0);
|
||||
Texture2D<float3> surfaceTexture : register(t0);
|
||||
|
||||
cbuffer SScaleQuadPixelConstants : register(b0)
|
||||
{
|
||||
float4 dxdy_Unused;
|
||||
};
|
||||
|
||||
struct SDrawQuadPixelOutput
|
||||
{
|
||||
float4 color : SV_TARGET;
|
||||
};
|
||||
|
||||
float3 SamplePixel(int2 coord)
|
||||
{
|
||||
return surfaceTexture.Load(int3(coord, 0)).rgb;
|
||||
}
|
||||
|
||||
SDrawQuadPixelOutput PSMain(SDrawQuadPixelInput input)
|
||||
{
|
||||
float dx = dxdy_Unused.x;
|
||||
float dy = dxdy_Unused.y;
|
||||
|
||||
float2 pixelTopLeftCoord = max(0.0, input.texCoord.xy - float2(dx, dy) * 0.5);
|
||||
float2 pixelBottomRightCoord = pixelTopLeftCoord + min(float2(1.0, 1.0), float2(dx, dy));
|
||||
|
||||
int2 topLeftCoordInteger = int2(floor(pixelTopLeftCoord));
|
||||
int2 bottomRightCoordInteger = int2(floor(pixelBottomRightCoord));
|
||||
|
||||
float2 interpolators = saturate((pixelBottomRightCoord - float2(bottomRightCoordInteger)) / float2(dx, dy));
|
||||
|
||||
float3 topLeftColor = SamplePixel(topLeftCoordInteger);
|
||||
float3 topRightColor = SamplePixel(int2(bottomRightCoordInteger.x, topLeftCoordInteger.y));
|
||||
float3 bottomLeftColor = SamplePixel(int2(topLeftCoordInteger.x, bottomRightCoordInteger.y));
|
||||
float3 bottomRightColor = SamplePixel(bottomRightCoordInteger);
|
||||
|
||||
float3 topColor = (1.0 - interpolators.x) * topLeftColor + interpolators.x * topRightColor;
|
||||
float3 bottomColor = (1.0 - interpolators.x) * bottomLeftColor + interpolators.x * bottomRightColor;
|
||||
float3 interpolatedColor = (1.0 - interpolators.y) * topColor + interpolators.y * bottomColor;
|
||||
|
||||
SDrawQuadPixelOutput result;
|
||||
result.color = float4(interpolatedColor, 1.0);
|
||||
|
||||
return result;
|
||||
}
|
Reference in New Issue
Block a user