Level editor work

This commit is contained in:
elasota
2020-02-25 23:09:09 -05:00
parent c78a20dafd
commit d617795591
11 changed files with 152 additions and 29 deletions

View File

@@ -0,0 +1,26 @@
The Room Editor is not yet fully functional.
As with Glider PRO's Room Editor, custom backgrounds, sounds, and TV videos
are supported.
Since Glider PRO used formats that were very Mac-specific, Aerofoil has
replaced most of them with more current formats.
To add resources to a house, create a ZIP file with the extension ".gpa" with
the same name as the .gpd and .gpf files that already exist for the house.
You can add resources by adding them to a folder named as the resource type,
with the appropriate extension.
For example, for a "PICT" resource of ID "3000", create a file named "3000.bmp"
and put it in the "PICT" directory in the .gpa archive.
PICT resources, used for custom decorations and backgrounds, must be BMP files.
Sounds should go in a directory named "snd$20"
Sounds must be WAV format, monaural, 8-bit unsigned PCM, 22255 Hz.
Sounds recorded at a different sample rate will play back at the wrong speed.
Sounds that are not monaural or 8-bit unsigned PCM will fail to load.
Resource IDs must be between -32768 and 32767. Other resource IDs will fail
to load.

View File

@@ -17,6 +17,7 @@
#include "House.h" #include "House.h"
#include "InputManager.h" #include "InputManager.h"
#include "ObjectEdit.h" #include "ObjectEdit.h"
#include "WindowManager.h"
short BitchAboutColorDepth (void); short BitchAboutColorDepth (void);
@@ -80,12 +81,9 @@ void HandleMouseEvent (const GpMouseInputEvent &theEvent, uint32_t tick)
break; break;
case inDrag: case inDrag:
DragWindow(whichWindow, evtPoint, &thisMac.screen); PortabilityLayer::WindowManager::GetInstance()->DragWindow(whichWindow, evtPoint, thisMac.screen);
if (whichWindow == mainWindow) if (whichWindow == mainWindow)
{
SendBehind(mainWindow, (WindowPtr)0L);
GetWindowLeftTop(whichWindow, &isEditH, &isEditV); GetWindowLeftTop(whichWindow, &isEditH, &isEditV);
}
else if (whichWindow == mapWindow) else if (whichWindow == mapWindow)
GetWindowLeftTop(whichWindow, &isMapH, &isMapV); GetWindowLeftTop(whichWindow, &isMapH, &isMapV);
else if (whichWindow == toolsWindow) else if (whichWindow == toolsWindow)

View File

@@ -220,6 +220,8 @@ namespace GpMouseButtons
kRight, kRight,
kX1, kX1,
kX2, kX2,
kCount
}; };
} }

View File

@@ -15,6 +15,7 @@ namespace PortabilityLayer
const KeyDownStates *GetKeys() const override; const KeyDownStates *GetKeys() const override;
void ApplyKeyboardEvent(const GpKeyboardInputEvent &vosEvent) override; void ApplyKeyboardEvent(const GpKeyboardInputEvent &vosEvent) override;
void ApplyGamepadEvent(const GpGamepadInputEvent &vosEvent) override; void ApplyGamepadEvent(const GpGamepadInputEvent &vosEvent) override;
void ApplyMouseEvent(const GpMouseInputEvent &vosEvent) override;
int16_t GetGamepadAxis(unsigned int playerNum, GpGamepadAxis_t gamepadAxis) override; int16_t GetGamepadAxis(unsigned int playerNum, GpGamepadAxis_t gamepadAxis) override;
void ClearState() override; void ClearState() override;
@@ -22,6 +23,7 @@ namespace PortabilityLayer
private: private:
void ApplyEventAsKey(const GpKeyboardInputEvent &vosEvent, bool bit); void ApplyEventAsKey(const GpKeyboardInputEvent &vosEvent, bool bit);
void ApplyEventAsMouseButton(const GpMouseInputEvent &vosEvent, bool bit);
void ApplyAnalogAxisEvent(const GpGamepadAnalogAxisEvent &axisEvent); void ApplyAnalogAxisEvent(const GpGamepadAnalogAxisEvent &axisEvent);
KeyDownStates m_keyMap; KeyDownStates m_keyMap;
@@ -49,6 +51,14 @@ namespace PortabilityLayer
ApplyAnalogAxisEvent(vosEvent.m_event.m_analogAxisEvent); ApplyAnalogAxisEvent(vosEvent.m_event.m_analogAxisEvent);
} }
void InputManagerImpl::ApplyMouseEvent(const GpMouseInputEvent &vosEvent)
{
if (vosEvent.m_eventType == GpMouseEventTypes::kUp || vosEvent.m_eventType == GpMouseEventTypes::kLeave)
this->ApplyEventAsMouseButton(vosEvent, false);
else if (vosEvent.m_eventType == GpMouseEventTypes::kDown)
this->ApplyEventAsMouseButton(vosEvent, true);
}
int16_t InputManagerImpl::GetGamepadAxis(unsigned int playerNum, GpGamepadAxis_t gamepadAxis) int16_t InputManagerImpl::GetGamepadAxis(unsigned int playerNum, GpGamepadAxis_t gamepadAxis)
{ {
assert(playerNum < PL_INPUT_MAX_PLAYERS); assert(playerNum < PL_INPUT_MAX_PLAYERS);
@@ -105,6 +115,11 @@ namespace PortabilityLayer
} }
} }
void InputManagerImpl::ApplyEventAsMouseButton(const GpMouseInputEvent &vosEvent, bool bit)
{
m_keyMap.m_mouse.Set(vosEvent.m_button, bit);
}
void InputManagerImpl::ApplyAnalogAxisEvent(const GpGamepadAnalogAxisEvent &axisEvent) void InputManagerImpl::ApplyAnalogAxisEvent(const GpGamepadAnalogAxisEvent &axisEvent)
{ {
if (axisEvent.m_player < PL_INPUT_MAX_PLAYERS) if (axisEvent.m_player < PL_INPUT_MAX_PLAYERS)

View File

@@ -2,8 +2,9 @@
#include "GpVOSEvent.h" #include "GpVOSEvent.h"
struct GpKeyboardInputEvent;
struct GpGamepadInputEvent; struct GpGamepadInputEvent;
struct GpKeyboardInputEvent;
struct GpMouseInputEvent;
struct KeyDownStates; struct KeyDownStates;
namespace PortabilityLayer namespace PortabilityLayer
@@ -14,6 +15,7 @@ namespace PortabilityLayer
virtual const KeyDownStates *GetKeys() const = 0; virtual const KeyDownStates *GetKeys() const = 0;
virtual void ApplyKeyboardEvent(const GpKeyboardInputEvent &vosEvent) = 0; virtual void ApplyKeyboardEvent(const GpKeyboardInputEvent &vosEvent) = 0;
virtual void ApplyGamepadEvent(const GpGamepadInputEvent &vosEvent) = 0; virtual void ApplyGamepadEvent(const GpGamepadInputEvent &vosEvent) = 0;
virtual void ApplyMouseEvent(const GpMouseInputEvent &vosEvent) = 0;
virtual int16_t GetGamepadAxis(unsigned int playerNum, GpGamepadAxis_t gamepadAxis) = 0; virtual int16_t GetGamepadAxis(unsigned int playerNum, GpGamepadAxis_t gamepadAxis) = 0;
virtual void ClearState() = 0; virtual void ClearState() = 0;

View File

@@ -108,16 +108,6 @@ short FindWindow(Point point, WindowPtr *window)
return part; return part;
} }
void DragWindow(WindowPtr window, Point start, Rect *bounds)
{
PL_NotYetImplemented();
}
void SendBehind(WindowPtr window, WindowPtr behind)
{
PL_NotYetImplemented();
}
void BringToFront(WindowPtr window) void BringToFront(WindowPtr window)
{ {
PL_NotYetImplemented(); PL_NotYetImplemented();
@@ -519,14 +509,12 @@ Boolean Button()
Boolean StillDown() Boolean StillDown()
{ {
PL_NotYetImplemented(); return PortabilityLayer::InputManager::GetInstance()->GetKeys()->m_mouse.Get(GpMouseButtons::kLeft);
return false;
} }
Boolean WaitMouseUp() Boolean WaitMouseUp()
{ {
PL_NotYetImplemented(); return StillDown();
return false;
} }
short Random() short Random()

View File

@@ -247,8 +247,6 @@ void HideCursor();
void Delay(int ticks, UInt32 *endTickCount); void Delay(int ticks, UInt32 *endTickCount);
short FindWindow(Point point, WindowPtr *window); // Translates global coordinates to window coordinates, returns a region ID short FindWindow(Point point, WindowPtr *window); // Translates global coordinates to window coordinates, returns a region ID
void DragWindow(WindowPtr window, Point start, Rect *bounds); // Drags the window (probably not implemented)
void SendBehind(WindowPtr window, WindowPtr behind);
void BringToFront(WindowPtr window); void BringToFront(WindowPtr window);
bool TrackGoAway(WindowPtr window, Point point); // Returns true if the close box was actually clicked (?) bool TrackGoAway(WindowPtr window, Point point); // Returns true if the close box was actually clicked (?)
Int32 GrowWindow(WindowPtr window, Point start, Rect *size); Int32 GrowWindow(WindowPtr window, Point start, Rect *size);

View File

@@ -60,6 +60,7 @@ struct KeyDownStates
GpBitfield<GpNumPadSpecials::kCount> m_numPadSpecial; GpBitfield<GpNumPadSpecials::kCount> m_numPadSpecial;
GpBitfield<GpFKeyMaximumInclusive> m_fKey; GpBitfield<GpFKeyMaximumInclusive> m_fKey;
GpBitfield<GpGamepadButtons::kCount> m_gamepadButtons[PL_INPUT_MAX_PLAYERS]; GpBitfield<GpGamepadButtons::kCount> m_gamepadButtons[PL_INPUT_MAX_PLAYERS];
GpBitfield<GpMouseButtons::kCount> m_mouse;
bool IsSet(intptr_t packedVOSCode) const; bool IsSet(intptr_t packedVOSCode) const;
}; };

View File

@@ -32,6 +32,10 @@ static void TranslateMouseInputEvent(const GpVOSEvent &vosEventBase, uint32_t ti
if (TimeTaggedVOSEvent *evt = queue->Enqueue()) if (TimeTaggedVOSEvent *evt = queue->Enqueue())
*evt = TimeTaggedVOSEvent::Create(vosEventBase, timestamp); *evt = TimeTaggedVOSEvent::Create(vosEventBase, timestamp);
} }
PortabilityLayer::InputManager *inputManager = PortabilityLayer::InputManager::GetInstance();
inputManager->ApplyMouseEvent(vosEvent);
} }
static void TranslateGamepadInputEvent(const GpGamepadInputEvent &vosEvent, PortabilityLayer::EventQueue *queue) static void TranslateGamepadInputEvent(const GpGamepadInputEvent &vosEvent, PortabilityLayer::EventQueue *queue)

View File

@@ -13,6 +13,7 @@
#include "QDGraf.h" #include "QDGraf.h"
#include "QDManager.h" #include "QDManager.h"
#include "QDPixMap.h" #include "QDPixMap.h"
#include "PLTimeTaggedVOSEvent.h"
#include "Vec2i.h" #include "Vec2i.h"
#include "WindowDef.h" #include "WindowDef.h"
@@ -27,6 +28,7 @@ namespace PortabilityLayer
{ {
virtual void GetChromePadding(const WindowImpl *window, uint16_t padding[WindowChromeSides::kCount]) const = 0; virtual void GetChromePadding(const WindowImpl *window, uint16_t padding[WindowChromeSides::kCount]) const = 0;
virtual void RenderChrome(WindowImpl *window, DrawSurface *surface, WindowChromeSide_t chromeSide) const = 0; virtual void RenderChrome(WindowImpl *window, DrawSurface *surface, WindowChromeSide_t chromeSide) const = 0;
virtual bool GetChromeInteractionZone(const WindowImpl *window, const Vec2i &point, RegionID &outRegion) const = 0;
}; };
template<class T> template<class T>
@@ -44,6 +46,7 @@ namespace PortabilityLayer
public: public:
void GetChromePadding(const WindowImpl *window, uint16_t padding[WindowChromeSides::kCount]) const override; void GetChromePadding(const WindowImpl *window, uint16_t padding[WindowChromeSides::kCount]) const override;
void RenderChrome(WindowImpl *window, DrawSurface *surface, WindowChromeSide_t chromeSide) const override; void RenderChrome(WindowImpl *window, DrawSurface *surface, WindowChromeSide_t chromeSide) const override;
bool GetChromeInteractionZone(const WindowImpl *window, const Vec2i &point, RegionID &outRegion) const override;
}; };
class GenericWindowChromeTheme final : public WindowChromeThemeSingleton<GenericWindowChromeTheme> class GenericWindowChromeTheme final : public WindowChromeThemeSingleton<GenericWindowChromeTheme>
@@ -51,6 +54,7 @@ namespace PortabilityLayer
public: public:
void GetChromePadding(const WindowImpl *window, uint16_t padding[WindowChromeSides::kCount]) const override; void GetChromePadding(const WindowImpl *window, uint16_t padding[WindowChromeSides::kCount]) const override;
void RenderChrome(WindowImpl *window, DrawSurface *surface, WindowChromeSide_t chromeSide) const override; void RenderChrome(WindowImpl *window, DrawSurface *surface, WindowChromeSide_t chromeSide) const override;
bool GetChromeInteractionZone(const WindowImpl *window, const Vec2i &point, RegionID &outRegion) const override;
private: private:
void RenderChromeTop(WindowImpl *window, DrawSurface *surface) const; void RenderChromeTop(WindowImpl *window, DrawSurface *surface) const;
@@ -89,6 +93,7 @@ namespace PortabilityLayer
void GetChromePadding(uint16_t padding[WindowChromeSides::kCount]) const; void GetChromePadding(uint16_t padding[WindowChromeSides::kCount]) const;
void GetChromeDimensions(int width, int height, Rect dimensions[WindowChromeSides::kCount]) const; void GetChromeDimensions(int width, int height, Rect dimensions[WindowChromeSides::kCount]) const;
bool GetChromeInteractionZone(const Vec2i &point, RegionID &outRegion) const;
bool IsBorderless() const; bool IsBorderless() const;
uint16_t GetStyleFlags() const; uint16_t GetStyleFlags() const;
@@ -118,6 +123,7 @@ namespace PortabilityLayer
void HideWindow(Window *window) override; void HideWindow(Window *window) override;
void FindWindow(const Point &point, Window **outWindow, short *outRegion) const override; void FindWindow(const Point &point, Window **outWindow, short *outRegion) const override;
void DestroyWindow(Window *window) override; void DestroyWindow(Window *window) override;
void DragWindow(Window *window, const Point &startPoint, const Rect &constraintRect) override;
void RenderFrame(IGpDisplayDriver *displayDriver) override; void RenderFrame(IGpDisplayDriver *displayDriver) override;
@@ -157,6 +163,11 @@ namespace PortabilityLayer
padding[WindowChromeSides::kRight] = 1; padding[WindowChromeSides::kRight] = 1;
} }
bool SimpleBoxChromeTheme::GetChromeInteractionZone(const WindowImpl *window, const Vec2i &point, RegionID &outRegion) const
{
return false;
}
void SimpleBoxChromeTheme::RenderChrome(WindowImpl *window, DrawSurface *surface, WindowChromeSide_t chromeSide) const void SimpleBoxChromeTheme::RenderChrome(WindowImpl *window, DrawSurface *surface, WindowChromeSide_t chromeSide) const
{ {
surface->SetForeColor(StdColors::Black()); surface->SetForeColor(StdColors::Black());
@@ -194,6 +205,31 @@ namespace PortabilityLayer
} }
} }
bool GenericWindowChromeTheme::GetChromeInteractionZone(const WindowImpl *window, const Vec2i &point, RegionID &outRegion) const
{
const DrawSurface *surface = window->GetDrawSurface();
const Rect rect = (*surface->m_port.GetPixMap())->m_rect;
if (window->GetStyleFlags() & WindowStyleFlags::kMiniBar)
{
if (point.m_x >= 0 && point.m_x < rect.Width() && point.m_y < 0 && point.m_y >= -13)
{
outRegion = RegionID::inDrag;
return true;
}
}
else
{
if (point.m_x >= 0 && point.m_x < rect.Width() && point.m_y < 0 && point.m_y >= -17)
{
outRegion = RegionID::inDrag;
return true;
}
}
return false;
}
void GenericWindowChromeTheme::RenderChrome(WindowImpl *window, DrawSurface *surface, WindowChromeSide_t chromeSide) const void GenericWindowChromeTheme::RenderChrome(WindowImpl *window, DrawSurface *surface, WindowChromeSide_t chromeSide) const
{ {
if (window->GetStyleFlags() & WindowStyleFlags::kMiniBar) if (window->GetStyleFlags() & WindowStyleFlags::kMiniBar)
@@ -529,6 +565,11 @@ namespace PortabilityLayer
dimensions[WindowChromeSides::kRight] = Rect::Create(0, 0, leftAndRightHeight, padding[WindowChromeSides::kRight]); dimensions[WindowChromeSides::kRight] = Rect::Create(0, 0, leftAndRightHeight, padding[WindowChromeSides::kRight]);
} }
bool WindowImpl::GetChromeInteractionZone(const Vec2i &point, RegionID &outRegion) const
{
return m_chromeTheme->GetChromeInteractionZone(this, point, outRegion);
}
bool WindowImpl::IsBorderless() const bool WindowImpl::IsBorderless() const
{ {
return (m_styleFlags & WindowStyleFlags::kBorderless) != 0; return (m_styleFlags & WindowStyleFlags::kBorderless) != 0;
@@ -658,6 +699,14 @@ namespace PortabilityLayer
const int32_t localX = point.h - window->m_wmX; const int32_t localX = point.h - window->m_wmX;
const int32_t localY = point.v - window->m_wmY; const int32_t localY = point.v - window->m_wmY;
RegionID chromeInteractionZone = inContent;
if (window->GetChromeInteractionZone(Vec2i(localX, localY), chromeInteractionZone))
{
*outRegion = chromeInteractionZone;
*outWindow = window;
return;
}
if (localX >= 0 && localY >= 0 && localX < windowRect.right && localY < windowRect.bottom) if (localX >= 0 && localY >= 0 && localX < windowRect.right && localY < windowRect.bottom)
{ {
if (outWindow) if (outWindow)
@@ -692,6 +741,44 @@ namespace PortabilityLayer
PortabilityLayer::MemoryManager::GetInstance()->Release(windowImpl); PortabilityLayer::MemoryManager::GetInstance()->Release(windowImpl);
} }
void WindowManagerImpl::DragWindow(Window *window, const Point &startPointRef, const Rect &constraintRect)
{
int32_t baseX = startPointRef.h;
int32_t baseY = startPointRef.v;
for (;;)
{
TimeTaggedVOSEvent evt;
if (WaitForEvent(&evt, 1))
{
if (evt.m_vosEvent.m_eventType == GpVOSEventTypes::kMouseInput)
{
const GpMouseInputEvent &mouseEvent = evt.m_vosEvent.m_event.m_mouseInputEvent;
int32_t x = mouseEvent.m_x;
int32_t y = mouseEvent.m_y;
if (x < constraintRect.left)
x = constraintRect.left;
if (x >= constraintRect.right)
x = constraintRect.right - 1;
if (y < constraintRect.top)
y = constraintRect.top;
if (y >= constraintRect.bottom)
y = constraintRect.bottom - 1;
window->m_wmX += x - baseX;
window->m_wmY += y - baseY;
baseX = x;
baseY = y;
if (mouseEvent.m_eventType == GpMouseEventTypes::kUp)
break;
}
}
}
}
void WindowManagerImpl::RenderFrame(IGpDisplayDriver *displayDriver) void WindowManagerImpl::RenderFrame(IGpDisplayDriver *displayDriver)
{ {
PortabilityLayer::DisplayDeviceManager *dd = PortabilityLayer::DisplayDeviceManager::GetInstance(); PortabilityLayer::DisplayDeviceManager *dd = PortabilityLayer::DisplayDeviceManager::GetInstance();

View File

@@ -5,6 +5,7 @@ struct DrawSurface;
struct GDevice; struct GDevice;
struct IGpDisplayDriver; struct IGpDisplayDriver;
struct Point; struct Point;
struct Rect;
struct Window; struct Window;
namespace PortabilityLayer namespace PortabilityLayer
@@ -23,6 +24,7 @@ namespace PortabilityLayer
virtual void HideWindow(Window *window) = 0; virtual void HideWindow(Window *window) = 0;
virtual void FindWindow(const Point &point, Window **outWindow, short *outRegion) const = 0; virtual void FindWindow(const Point &point, Window **outWindow, short *outRegion) const = 0;
virtual void DestroyWindow(Window *window) = 0; virtual void DestroyWindow(Window *window) = 0;
virtual void DragWindow(Window *window, const Point &startPoint, const Rect &constraintRect) = 0;
virtual void RenderFrame(IGpDisplayDriver *displayDriver) = 0; virtual void RenderFrame(IGpDisplayDriver *displayDriver) = 0;