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 "InputManager.h"
#include "ObjectEdit.h"
#include "WindowManager.h"
short BitchAboutColorDepth (void);
@@ -74,18 +75,15 @@ void HandleMouseEvent (const GpMouseInputEvent &theEvent, uint32_t tick)
switch (thePart)
{
case inMenuBar:
case inMenuBar:
menuChoice = MenuSelect(evtPoint);
DoMenuChoice(menuChoice);
break;
case inDrag:
DragWindow(whichWindow, evtPoint, &thisMac.screen);
case inDrag:
PortabilityLayer::WindowManager::GetInstance()->DragWindow(whichWindow, evtPoint, thisMac.screen);
if (whichWindow == mainWindow)
{
SendBehind(mainWindow, (WindowPtr)0L);
GetWindowLeftTop(whichWindow, &isEditH, &isEditV);
}
else if (whichWindow == mapWindow)
GetWindowLeftTop(whichWindow, &isMapH, &isMapV);
else if (whichWindow == toolsWindow)
@@ -97,7 +95,7 @@ void HandleMouseEvent (const GpMouseInputEvent &theEvent, uint32_t tick)
HiliteAllWindows();
break;
case inGoAway:
case inGoAway:
if (TrackGoAway(whichWindow, evtPoint))
{
if (whichWindow == mapWindow)
@@ -111,7 +109,7 @@ void HandleMouseEvent (const GpMouseInputEvent &theEvent, uint32_t tick)
}
break;
case inGrow:
case inGrow:
if (whichWindow == mapWindow)
{
newSize = GrowWindow(mapWindow, evtPoint, &thisMac.gray);
@@ -119,13 +117,13 @@ void HandleMouseEvent (const GpMouseInputEvent &theEvent, uint32_t tick)
}
break;
case inZoomIn:
case inZoomOut:
case inZoomIn:
case inZoomOut:
if (TrackBox(whichWindow, evtPoint, thePart))
ZoomWindow(whichWindow, thePart, true);
break;
case inContent:
case inContent:
if (whichWindow == mainWindow)
{
hDelta = evtPoint.h - lastWhere.h;
@@ -153,7 +151,7 @@ void HandleMouseEvent (const GpMouseInputEvent &theEvent, uint32_t tick)
HandleLinkClick(evtPoint);
break;
default:
default:
break;
}
}

View File

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

View File

@@ -15,6 +15,7 @@ namespace PortabilityLayer
const KeyDownStates *GetKeys() const override;
void ApplyKeyboardEvent(const GpKeyboardInputEvent &vosEvent) override;
void ApplyGamepadEvent(const GpGamepadInputEvent &vosEvent) override;
void ApplyMouseEvent(const GpMouseInputEvent &vosEvent) override;
int16_t GetGamepadAxis(unsigned int playerNum, GpGamepadAxis_t gamepadAxis) override;
void ClearState() override;
@@ -22,6 +23,7 @@ namespace PortabilityLayer
private:
void ApplyEventAsKey(const GpKeyboardInputEvent &vosEvent, bool bit);
void ApplyEventAsMouseButton(const GpMouseInputEvent &vosEvent, bool bit);
void ApplyAnalogAxisEvent(const GpGamepadAnalogAxisEvent &axisEvent);
KeyDownStates m_keyMap;
@@ -49,6 +51,14 @@ namespace PortabilityLayer
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)
{
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)
{
if (axisEvent.m_player < PL_INPUT_MAX_PLAYERS)

View File

@@ -2,8 +2,9 @@
#include "GpVOSEvent.h"
struct GpKeyboardInputEvent;
struct GpGamepadInputEvent;
struct GpKeyboardInputEvent;
struct GpMouseInputEvent;
struct KeyDownStates;
namespace PortabilityLayer
@@ -14,6 +15,7 @@ namespace PortabilityLayer
virtual const KeyDownStates *GetKeys() const = 0;
virtual void ApplyKeyboardEvent(const GpKeyboardInputEvent &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 void ClearState() = 0;

View File

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

View File

@@ -247,8 +247,6 @@ void HideCursor();
void Delay(int ticks, UInt32 *endTickCount);
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);
bool TrackGoAway(WindowPtr window, Point point); // Returns true if the close box was actually clicked (?)
Int32 GrowWindow(WindowPtr window, Point start, Rect *size);

View File

@@ -60,6 +60,7 @@ struct KeyDownStates
GpBitfield<GpNumPadSpecials::kCount> m_numPadSpecial;
GpBitfield<GpFKeyMaximumInclusive> m_fKey;
GpBitfield<GpGamepadButtons::kCount> m_gamepadButtons[PL_INPUT_MAX_PLAYERS];
GpBitfield<GpMouseButtons::kCount> m_mouse;
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())
*evt = TimeTaggedVOSEvent::Create(vosEventBase, timestamp);
}
PortabilityLayer::InputManager *inputManager = PortabilityLayer::InputManager::GetInstance();
inputManager->ApplyMouseEvent(vosEvent);
}
static void TranslateGamepadInputEvent(const GpGamepadInputEvent &vosEvent, PortabilityLayer::EventQueue *queue)

View File

@@ -13,6 +13,7 @@
#include "QDGraf.h"
#include "QDManager.h"
#include "QDPixMap.h"
#include "PLTimeTaggedVOSEvent.h"
#include "Vec2i.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 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>
@@ -44,6 +46,7 @@ namespace PortabilityLayer
public:
void GetChromePadding(const WindowImpl *window, uint16_t padding[WindowChromeSides::kCount]) 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>
@@ -51,6 +54,7 @@ namespace PortabilityLayer
public:
void GetChromePadding(const WindowImpl *window, uint16_t padding[WindowChromeSides::kCount]) 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:
void RenderChromeTop(WindowImpl *window, DrawSurface *surface) const;
@@ -89,6 +93,7 @@ namespace PortabilityLayer
void GetChromePadding(uint16_t padding[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;
uint16_t GetStyleFlags() const;
@@ -118,6 +123,7 @@ namespace PortabilityLayer
void HideWindow(Window *window) override;
void FindWindow(const Point &point, Window **outWindow, short *outRegion) const override;
void DestroyWindow(Window *window) override;
void DragWindow(Window *window, const Point &startPoint, const Rect &constraintRect) override;
void RenderFrame(IGpDisplayDriver *displayDriver) override;
@@ -157,6 +163,11 @@ namespace PortabilityLayer
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
{
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
{
if (window->GetStyleFlags() & WindowStyleFlags::kMiniBar)
@@ -529,6 +565,11 @@ namespace PortabilityLayer
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
{
return (m_styleFlags & WindowStyleFlags::kBorderless) != 0;
@@ -658,6 +699,14 @@ namespace PortabilityLayer
const int32_t localX = point.h - window->m_wmX;
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 (outWindow)
@@ -692,6 +741,44 @@ namespace PortabilityLayer
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)
{
PortabilityLayer::DisplayDeviceManager *dd = PortabilityLayer::DisplayDeviceManager::GetInstance();

View File

@@ -5,6 +5,7 @@ struct DrawSurface;
struct GDevice;
struct IGpDisplayDriver;
struct Point;
struct Rect;
struct Window;
namespace PortabilityLayer
@@ -23,6 +24,7 @@ namespace PortabilityLayer
virtual void HideWindow(Window *window) = 0;
virtual void FindWindow(const Point &point, Window **outWindow, short *outRegion) const = 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;