You're breathtaking!

This commit is contained in:
Wojtek Figat
2020-12-07 23:40:54 +01:00
commit 6fb9eee74c
5143 changed files with 1153594 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#if PLATFORM_ANDROID
#include <../../../../../../../sources/android/native_app_glue/android_native_app_glue.h>
#endif

View File

@@ -0,0 +1,16 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#if PLATFORM_ANDROID
#include "Engine/Engine/Engine.h"
#include "Engine/Platform/Platform.h"
#include <../../../../../../../sources/android/native_app_glue/android_native_app_glue.h>
#include <../../../../../../../sources/android/native_app_glue/android_native_app_glue.c>
void android_main(android_app* app)
{
AndroidPlatform::PreInit(app);
Engine::Main(TEXT(""));
}
#endif

View File

@@ -0,0 +1,24 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#if PLATFORM_LINUX
#include "Engine/Engine/Engine.h"
#include "Engine/Core/Types/StringBuilder.h"
int main(int argc, char* argv[])
{
// Join the arguments
StringBuilder args;
for (int i = 1; i < argc; i++)
{
args.Append(argv[i]);
if (i + 1 != argc)
args.Append(TEXT(' '));
}
args.Append(TEXT('\0'));
return Engine::Main(*args);
}
#endif

View File

@@ -0,0 +1,75 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
using System.Collections.Generic;
using System.IO;
using Flax.Build;
using Flax.Build.NativeCpp;
/// <summary>
/// Application startup module.
/// </summary>
public class Main : EngineModule
{
/// <inheritdoc />
public override void Setup(BuildOptions options)
{
base.Setup(options);
// Use source folder per platform group
options.SourcePaths.Clear();
switch (options.Platform.Target)
{
case TargetPlatform.Windows:
options.SourcePaths.Add(Path.Combine(FolderPath, "Windows"));
// Visual Leak Detector (https://kinddragon.github.io/vld/)
/*{
var vldPath = @"C:\Program Files (x86)\Visual Leak Detector";
var vldBinaries = options.Toolchain.Architecture == TargetArchitecture.x64 ? "Win64" : "Win32";
var vldBinariesPostfix = options.Toolchain.Architecture == TargetArchitecture.x64 ? "x64" : "x86";
options.PrivateDefinitions.Add("USE_VLD_MEM_LEAKS_CHECK");
options.PrivateDefinitions.Add("VLD_FORCE_ENABLE");
options.PrivateIncludePaths.Add(Path.Combine(vldPath, "include"));
options.OutputFiles.Add(Path.Combine(vldPath, "lib", vldBinaries, "vld.lib"));
options.DependencyFiles.Add(Path.Combine(vldPath, "bin", vldBinaries, "vld_" + vldBinariesPostfix + ".dll"));
options.DependencyFiles.Add(Path.Combine(vldPath, "bin", vldBinaries, "vld_" + vldBinariesPostfix + ".pdb"));
options.DependencyFiles.Add(Path.Combine(vldPath, "bin", vldBinaries, "dbghelp.dll"));
options.DependencyFiles.Add(Path.Combine(vldPath, "bin", vldBinaries, "Microsoft.DTfW.DHL.manifest"));
}*/
// Visual Studio memory leaks detection
/*{
options.PrivateDefinitions.Add("USE_VS_MEM_LEAKS_CHECK");
}*/
break;
case TargetPlatform.XboxOne:
case TargetPlatform.UWP:
options.SourcePaths.Add(Path.Combine(FolderPath, "UWP"));
// Use Visual C++ component extensions C++/CX for UWP
options.CompileEnv.WinRTComponentExtensions = true;
options.CompileEnv.GenerateDocumentation = true;
break;
case TargetPlatform.Linux:
options.SourcePaths.Add(Path.Combine(FolderPath, "Linux"));
break;
case TargetPlatform.PS4:
options.SourcePaths.Add(Path.Combine(Globals.EngineRoot, "Source", "Platforms", "PS4", "Engine", "Main"));
break;
case TargetPlatform.XboxScarlett:
options.SourcePaths.Add(Path.Combine(Globals.EngineRoot, "Source", "Platforms", "XboxScarlett", "Engine", "Main"));
break;
case TargetPlatform.Android:
options.SourcePaths.Add(Path.Combine(FolderPath, "Android"));
break;
default: throw new InvalidPlatformException(options.Platform.Target);
}
}
/// <inheritdoc />
public override void GetFilesToDeploy(List<string> files)
{
}
}

View File

@@ -0,0 +1,443 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#if PLATFORM_UWP
// @formatter:off
#include "main.h"
#include <sal.h>
// Use better GPU
extern "C" {
_declspec(dllexport) unsigned int NvOptimusEnablement = 0x00000001;
}
extern "C" {
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}
using namespace Windows::ApplicationModel;
using namespace Windows::ApplicationModel::Activation;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::Foundation;
using namespace Windows::Graphics::Display;
using namespace Windows::UI;
using namespace Windows::UI::Core;
using namespace Windows::UI::Input;
using namespace Windows::UI::ViewManagement;
using namespace Windows::Devices::Input;
using namespace Windows::Gaming::Input;
using namespace Windows::System;
using namespace Platform;
using namespace FlaxEngine;
Game::Game()
{
PlatformImpl::Init();
}
void Game::Initialize(CoreApplicationView^ applicationView)
{
applicationView->Activated += ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &Game::OnActivated);
CoreApplication::Suspending += ref new EventHandler<SuspendingEventArgs^>(this, &Game::OnSuspending);
CoreApplication::Resuming += ref new EventHandler<Platform::Object^>(this, &Game::OnResuming);
}
void Game::SetWindow(Windows::UI::Core::CoreWindow^ window)
{
PlatformImpl::InitWindow(window);
PointerVisualizationSettings^ visualizationSettings = PointerVisualizationSettings::GetForCurrentView();
visualizationSettings->IsContactFeedbackEnabled = false;
visualizationSettings->IsBarrelButtonFeedbackEnabled = false;
}
void Game::Run()
{
RunUWP();
}
void Game::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
{
CoreWindow^ window = CoreWindow::GetForCurrentThread();
window->Activate();
}
void Game::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
{
/*
// Save app state asynchronously after requesting a deferral. Holding a deferral
// indicates that the application is busy performing suspending operations. Be
// aware that a deferral may not be held indefinitely. After about five seconds,
// the app will be forced to exit.
SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
create_task([this, deferral]()
{
m_deviceResources->Trim();
m_main->Suspend();
deferral->Complete();
});
*/
}
void Game::OnResuming(Platform::Object^ sender, Platform::Object^ args)
{
// Restore any data or state that was unloaded on suspend. By default, data
// and state are persisted when resuming from suspend. Note that this event
// does not occur if the app was previously terminated.
// TODO: m_main->Resume();
}
PlatformImpl MainPlatform;
WindowImpl MainWindow;
void WindowEvents::Register(WindowImpl* win)
{
_win = win;
auto window = win->Window;
window->Activated += ref new TypedEventHandler<CoreWindow^, WindowActivatedEventArgs^>(this, &WindowEvents::OnActivationChanged);
window->SizeChanged += ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &WindowEvents::OnSizeChanged);
window->Closed += ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &WindowEvents::OnClosed);
window->VisibilityChanged += ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &WindowEvents::OnVisibilityChanged);
window->PointerPressed += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &WindowEvents::OnPointerPressed);
window->PointerMoved += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &WindowEvents::OnPointerMoved);
window->PointerWheelChanged += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &WindowEvents::OnPointerWheelChanged);
window->PointerReleased += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &WindowEvents::OnPointerReleased);
window->PointerExited += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &WindowEvents::OnPointerExited);
window->KeyDown += ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &WindowEvents::OnKeyDown);
window->KeyUp += ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &WindowEvents::OnKeyUp);
window->CharacterReceived += ref new TypedEventHandler<CoreWindow^, CharacterReceivedEventArgs^>(this, &WindowEvents::OnCharacterReceived);
MouseDevice::GetForCurrentView()->MouseMoved += ref new TypedEventHandler<MouseDevice^, MouseEventArgs^>(this, &WindowEvents::OnMouseMoved);
DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView();
currentDisplayInformation->DpiChanged += ref new TypedEventHandler<DisplayInformation^, Platform::Object^>(this, &WindowEvents::OnDisplayDpiChanged);
currentDisplayInformation->OrientationChanged += ref new TypedEventHandler<DisplayInformation^, Object^>(this, &WindowEvents::OnOrientationChanged);
currentDisplayInformation->StereoEnabledChanged += ref new TypedEventHandler<DisplayInformation^, Platform::Object^>(this, &WindowEvents::OnStereoEnabledChanged);
DisplayInformation::DisplayContentsInvalidated += ref new TypedEventHandler<DisplayInformation^, Platform::Object^>(this, &WindowEvents::OnDisplayContentsInvalidated);
// Detect gamepad connection and disconnection events
Gamepad::GamepadAdded += ref new EventHandler<Gamepad^>(this, &WindowEvents::OnGamepadAdded);
Gamepad::GamepadRemoved += ref new EventHandler<Gamepad^>(this, &WindowEvents::OnGamepadRemoved);
}
void WindowEvents::OnActivationChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowActivatedEventArgs^ args)
{
bool hasFocus;
if (args->WindowActivationState == Windows::UI::Core::CoreWindowActivationState::Deactivated)
hasFocus = false;
else if (args->WindowActivationState == Windows::UI::Core::CoreWindowActivationState::CodeActivated
|| args->WindowActivationState == Windows::UI::Core::CoreWindowActivationState::PointerActivated)
hasFocus = true;
if (_win->FocusChanged)
_win->FocusChanged(hasFocus, _win->UserData);
}
void WindowEvents::OnSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args)
{
if (_win->SizeChanged)
_win->SizeChanged(args->Size.Width, args->Size.Height, _win->UserData);
}
void WindowEvents::OnClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args)
{
if (_win->Closed)
_win->Closed(_win->UserData);
}
void WindowEvents::OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args)
{
if (_win->VisibilityChanged)
_win->VisibilityChanged(args->Visible, _win->UserData);
}
void WindowEvents::OnStereoEnabledChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args)
{
//m_deviceResources->UpdateStereoState();
//m_main->CreateWindowSizeDependentResources();
}
void WindowEvents::OnDisplayDpiChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args)
{
if (_win->DpiChanged)
_win->DpiChanged(sender->LogicalDpi, _win->UserData);
}
void WindowEvents::OnOrientationChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args)
{
//m_deviceResources->SetCurrentOrientation(sender->CurrentOrientation);
//m_main->CreateWindowSizeDependentResources();
}
void WindowEvents::OnDisplayContentsInvalidated(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args)
{
//m_deviceResources->ValidateDevice();
}
void WindowEvents::OnGamepadAdded(Object^ sender, Gamepad^ gamepad)
{
//_win->GamepadsChanged = true;
}
void WindowEvents::OnGamepadRemoved(Object^ sender, Gamepad^ gamepad)
{
//_win->GamepadsChanged = true;
}
void GetPointerData(UWPWindowImpl::PointerData & data, PointerEventArgs^ args)
{
PointerPoint^ point = args->CurrentPoint;
Point pointerPosition = point->Position;
PointerPointProperties^ pointProperties = point->Properties;
auto pointerDevice = point->PointerDevice;
auto pointerDeviceType = pointerDevice->PointerDeviceType;
data.PointerId = point->PointerId;
data.PositionX = pointerPosition.X;
data.PositionY = pointerPosition.Y;
data.MouseWheelDelta = pointProperties->MouseWheelDelta;
data.IsLeftButtonPressed = pointProperties->IsLeftButtonPressed;
data.IsMiddleButtonPressed = pointProperties->IsMiddleButtonPressed;
data.IsRightButtonPressed = pointProperties->IsRightButtonPressed;
data.IsXButton1Pressed = pointProperties->IsXButton1Pressed;
data.IsXButton2Pressed = pointProperties->IsXButton2Pressed;
data.IsMouse = pointerDeviceType == PointerDeviceType::Mouse;
data.IsPen = pointerDeviceType == PointerDeviceType::Pen;
data.IsTouch = pointerDeviceType == PointerDeviceType::Touch;
args->Handled = true;
}
void WindowEvents::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
{
if (_win->PointerPressed)
{
UWPWindowImpl::PointerData data;
GetPointerData(data, args);
_win->PointerPressed(&data, _win->UserData);
}
}
void WindowEvents::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args)
{
if (_win->PointerMoved)
{
UWPWindowImpl::PointerData data;
GetPointerData(data, args);
_win->PointerMoved(&data, _win->UserData);
}
}
void WindowEvents::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args)
{
if (_win->PointerWheelChanged)
{
UWPWindowImpl::PointerData data;
GetPointerData(data, args);
_win->PointerWheelChanged(&data, _win->UserData);
}
}
void WindowEvents::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args)
{
if (_win->PointerReleased)
{
UWPWindowImpl::PointerData data;
GetPointerData(data, args);
_win->PointerReleased(&data, _win->UserData);
}
}
void WindowEvents::OnPointerExited(CoreWindow^ sender, PointerEventArgs^ args)
{
if (_win->PointerExited)
{
UWPWindowImpl::PointerData data;
GetPointerData(data, args);
_win->PointerExited(&data, _win->UserData);
}
}
void WindowEvents::OnKeyDown(CoreWindow^ sender, KeyEventArgs^ args)
{
if (_win->KeyDown)
{
_win->KeyDown((int)args->VirtualKey, _win->UserData);
}
}
void WindowEvents::OnKeyUp(CoreWindow^ sender, KeyEventArgs^ args)
{
if (_win->KeyUp)
{
_win->KeyUp((int)args->VirtualKey, _win->UserData);
args->Handled = true;
}
}
void WindowEvents::OnCharacterReceived(CoreWindow^ sender, CharacterReceivedEventArgs^ args)
{
if (_win->CharacterReceived)
{
_win->CharacterReceived(args->KeyCode, _win->UserData);
args->Handled = true;
}
}
void WindowEvents::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args)
{
if (_win->MouseMoved)
{
Point point = _win->Window->PointerPosition;
_win->MouseMoved(point.X, point.Y, _win->UserData);
}
}
void WindowImpl::Init(CoreWindow^ window)
{
Window = window;
Events = ref new WindowEvents();
window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0);
PointerVisualizationSettings^ visualizationSettings = PointerVisualizationSettings::GetForCurrentView();
visualizationSettings->IsContactFeedbackEnabled = false;
visualizationSettings->IsBarrelButtonFeedbackEnabled = false;
Events->Register(this);
}
void WindowImpl::SetGamepadVibration(const int index, UWPGamepadStateVibration& vibration)
{
auto gamepads = Gamepad::Gamepads;
if (index >= (int)gamepads->Size)
return;
auto gamepad = gamepads->GetAt(index);
GamepadVibration gamepadVibration;
gamepadVibration.LeftMotor = vibration.LeftLarge;
gamepadVibration.RightMotor = vibration.RightLarge;
gamepadVibration.LeftTrigger = vibration.LeftSmall;
gamepadVibration.RightTrigger = vibration.RightSmall;
gamepad->Vibration = gamepadVibration;
}
void WindowImpl::GetGamepadState(const int index, UWPGamepadState& state)
{
auto gamepads = Gamepad::Gamepads;
if (index >= (int)gamepads->Size)
return;
auto gamepad = gamepads->GetAt(index);
GamepadReading reading = gamepad->GetCurrentReading();
state.Buttons = (int)reading.Buttons;
state.LeftThumbstickX = (float)reading.LeftThumbstickX;
state.LeftThumbstickY = (float)reading.LeftThumbstickY;
state.RightThumbstickX = (float)reading.RightThumbstickX;
state.RightThumbstickY = (float)reading.RightThumbstickY;
state.LeftTrigger = (float)reading.LeftTrigger;
state.RightTrigger = (float)reading.LeftTrigger;
}
void PlatformImpl::Init()
{
// Register UWP platform implementation for the FlaxEngine API
CUWPPlatform = &MainPlatform;
}
void PlatformImpl::InitWindow(Windows::UI::Core::CoreWindow^ window)
{
MainWindow.Init(window);
}
UWPWindowImpl* PlatformImpl::GetMainWindowImpl()
{
return &MainWindow;
}
void PlatformImpl::Tick()
{
CoreWindow^ window = CoreWindow::GetForCurrentThread();
window->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
}
int PlatformImpl::GetDpi()
{
auto currentDisplayInformation = Windows::Graphics::Display::DisplayInformation::GetForCurrentView();
return (int)currentDisplayInformation->LogicalDpi;
}
int PlatformImpl::GetSpecialFolderPath(const SpecialFolder type, wchar_t* buffer, int bufferLength)
{
String^ path = nullptr;
switch (type)
{
case SpecialFolder::Desktop:
path = Windows::Storage::KnownFolders::DocumentsLibrary->Path + "/../Desktop";
break;
case SpecialFolder::Documents:
path = Windows::Storage::KnownFolders::DocumentsLibrary->Path;
break;
case SpecialFolder::Pictures:
path = Windows::Storage::KnownFolders::PicturesLibrary->Path;
break;
case SpecialFolder::AppData:
path = Windows::Storage::ApplicationData::Current->RoamingFolder->Path;
break;
case SpecialFolder::LocalAppData:
path = Windows::Storage::ApplicationData::Current->LocalFolder->Path;
break;
case SpecialFolder::ProgramData:
break;
//case SpecialFolder::Temporary: path = Windows::Storage::ApplicationData::Current->TemporaryFolder->Path; break;
case SpecialFolder::Temporary:
path = Windows::Storage::ApplicationData::Current->LocalFolder->Path;
break;
}
if (path != nullptr)
{
int length = path->Length();
if (length >= bufferLength)
length = bufferLength - 1;
const wchar_t* data = path->Data();
for (int i = 0; i<length; i++)
buffer[i] = data[i];
buffer[length] = 0;
return length;
}
return 0;
}
void PlatformImpl::GetDisplaySize(float* width, float* height)
{
auto bounds = ApplicationView::GetForCurrentView()->VisibleBounds;
auto scaleFactor = DisplayInformation::GetForCurrentView()->RawPixelsPerViewPixel;
*width = (float)(bounds.Width * scaleFactor);
*height = (float)(bounds.Height * scaleFactor);
}
UWPPlatformImpl::DialogResult PlatformImpl::ShowMessageDialog(UWPWindowImpl* window, const wchar_t* text, const wchar_t* caption, MessageBoxButtons buttons, MessageBoxIcon icon)
{
Platform::String^ content = ref new Platform::String(text);
Platform::String^ title = ref new Platform::String(caption);
Windows::UI::Popups::MessageDialog^ msg = ref new Windows::UI::Popups::MessageDialog(content, title);
// TODO: implement buttons
// TODO: gather result
msg->ShowAsync();
return DialogResult::OK;
}
#endif

View File

@@ -0,0 +1,266 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#pragma once
#if PLATFORM_UWP
#include "Engine/Platform/UWP/UWPPlatformImpl.h"
// @formatter:off
class WindowImpl;
namespace FlaxEngine
{
/// <summary>
/// The helper bridge interface to initialize and run a game.
/// </summary>
public ref class Game sealed
{
public:
/// <summary>
/// Initializes a new instance of the <see cref="Game"/> class.
/// </summary>
Game();
public:
/// <summary>
/// A method for app view initialization, which is called when an app object is launched.
/// </summary>
/// <param name="applicationView">The default view provided by the app object. You can use this instance in your implementation to obtain the CoreWindow created by the app object, and register callbacks for the Activated event.</param>
void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView);
/// <summary>
/// A method that sets the current window for the game rendering output.
/// </summary>
/// <param name="window">The current window for the app object.</param>
void SetWindow(Windows::UI::Core::CoreWindow^ window);
/// <summary>
/// A method that starts the game.
/// </summary>
void Run();
private:
// Application lifecycle event handlers
void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ args);
void OnResuming(Platform::Object^ sender, Platform::Object^ args);
};
}
namespace FlaxEngine
{
private ref class WindowEvents sealed
{
friend WindowImpl;
private:
WindowImpl* _win;
private:
void Register(WindowImpl* win);
private:
void OnActivationChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowActivatedEventArgs^ args);
void OnSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args);
void OnClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args);
void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
void OnStereoEnabledChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
void OnDisplayDpiChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
void OnOrientationChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
void OnDisplayContentsInvalidated(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
void OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
void OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
void OnPointerWheelChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
void OnPointerReleased(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
void OnPointerExited(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
void OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
void OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args);
void OnCharacterReceived(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CharacterReceivedEventArgs^ args);
void OnMouseMoved(Windows::Devices::Input::MouseDevice^ mouseDevice, Windows::Devices::Input::MouseEventArgs^ args);
void OnGamepadAdded(Platform::Object^ sender, Windows::Gaming::Input::Gamepad^ gamepad);
void OnGamepadRemoved(Platform::Object^ sender, Windows::Gaming::Input::Gamepad^ gamepad);
};
}
class WindowImpl : public UWPWindowImpl
{
public:
//Platform::Agile<Windows::UI::Core::CoreWindow> Window
Windows::UI::Core::CoreWindow^ Window;
FlaxEngine::WindowEvents^ Events;
public:
void Init(Windows::UI::Core::CoreWindow^ window);
public:
// [UWPWindowImpl]
void* GetHandle() const override
{
//return (void*)reinterpret_cast<IUnknown*>(Window.Get());
//return (void*)reinterpret_cast<IUnknown*>(Window);
return reinterpret_cast<void*>(Window);
}
void SetMousePosition(float x, float y) override
{
Window->PointerPosition = Windows::Foundation::Point(x, y);
}
void GetMousePosition(float* x, float* y) override
{
Windows::Foundation::Point point = Window->PointerPosition;
*x = point.X;
*y = point.Y;
}
void SetCursor(CursorType type) override
{
auto window = Windows::UI::Core::CoreWindow::GetForCurrentThread();
if (window == nullptr)
return;
if (type == CursorType::Hidden)
{
// TODO: use custom cursor with empty image, when PointerCursor is null mouse events are not passed to the window events
window->PointerCursor = ref new Windows::UI::Core::CoreCursor(Windows::UI::Core::CoreCursorType::Arrow, 0);
}
else
{
Windows::UI::Core::CoreCursorType uwpType;
switch (type)
{
case CursorType::Cross:
uwpType = Windows::UI::Core::CoreCursorType::Cross;
break;
case CursorType::Hand:
uwpType = Windows::UI::Core::CoreCursorType::Hand;
break;
case CursorType::Help:
uwpType = Windows::UI::Core::CoreCursorType::Help;
break;
case CursorType::IBeam:
uwpType = Windows::UI::Core::CoreCursorType::IBeam;
break;
case CursorType::No:
uwpType = Windows::UI::Core::CoreCursorType::UniversalNo;
break;
case CursorType::Wait:
uwpType = Windows::UI::Core::CoreCursorType::Wait;
break;
case CursorType::SizeAll:
uwpType = Windows::UI::Core::CoreCursorType::SizeAll;
break;
case CursorType::SizeNESW:
uwpType = Windows::UI::Core::CoreCursorType::SizeNortheastSouthwest;
break;
case CursorType::SizeNS:
uwpType = Windows::UI::Core::CoreCursorType::SizeNorthSouth;
break;
case CursorType::SizeNWSE:
uwpType = Windows::UI::Core::CoreCursorType::SizeNorthwestSoutheast;
break;
case CursorType::SizeWE:
uwpType = Windows::UI::Core::CoreCursorType::SizeWestEast;
break;
default:
uwpType = Windows::UI::Core::CoreCursorType::Arrow;
break;
}
window->PointerCursor = ref new Windows::UI::Core::CoreCursor(uwpType, 0);
}
}
void GetBounds(float* x, float* y, float* width, float* height) override
{
auto bounds = Window->Bounds;
*x = bounds.X;
*y = bounds.Y;
*width = bounds.Width;
*height = bounds.Height;
}
void GetDpi(float* dpi) override
{
auto currentDisplayInformation = Windows::Graphics::Display::DisplayInformation::GetForCurrentView();
*dpi = currentDisplayInformation->LogicalDpi;
}
void GetTitle(wchar_t* buffer, int bufferLength) override
{
auto appView = Windows::UI::ViewManagement::ApplicationView::GetForCurrentView();
auto title = appView->Title;
if (title)
{
int length = title->Length();
if (length >= bufferLength)
length = bufferLength - 1;
const wchar_t* data = title->Data();
for (int i = 0; i < length; i++)
buffer[i] = data[i];
buffer[length] = 0;
}
else
{
buffer[0] = 0;
}
}
void SetTitle(const wchar_t* title) override
{
auto appView = Windows::UI::ViewManagement::ApplicationView::GetForCurrentView();
appView->Title = ref new Platform::String(title);
}
int GetGamepadsCount()
{
return Windows::Gaming::Input::Gamepad::Gamepads->Size;
}
void SetGamepadVibration(const int index, UWPGamepadStateVibration& vibration) override;
void GetGamepadState(const int index, UWPGamepadState& state) override;
void Activate() override
{
Window->Activate();
}
void Close() override
{
Window->Close();
}
};
class PlatformImpl : public UWPPlatformImpl
{
public:
/// <summary>
/// Registers platform.
/// </summary>
static void Init();
static void InitWindow(Windows::UI::Core::CoreWindow^ window);
public:
// [UWPPlatformImpl]
UWPWindowImpl* GetMainWindowImpl() override;
void Tick() override;
int GetDpi() override;
int GetSpecialFolderPath(const SpecialFolder type, wchar_t* buffer, int bufferLength) override;
void GetDisplaySize(float* width, float* height) override;
DialogResult ShowMessageDialog(UWPWindowImpl* window, const wchar_t* text, const wchar_t* caption, MessageBoxButtons buttons, MessageBoxIcon icon) override;
};
#endif

View File

@@ -0,0 +1,54 @@
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
#if PLATFORM_WINDOWS
#ifdef USE_VLD_MEM_LEAKS_CHECK
#include <vld.h>
#endif
#ifdef USE_VS_MEM_LEAKS_CHECK
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#else
#include <stdlib.h>
#endif
#include "Engine/Engine/Engine.h"
#include "Engine/Platform/Win32/IncludeWindowsHeaders.h"
// Favor the high performance NVIDIA GPU if there are multiple GPUs
extern "C" {
_declspec(dllexport) uint32 NvOptimusEnablement = 0x00000001;
}
// Favor the high performance AMD GPU if there are multiple GPUs
extern "C" {
__declspec(dllexport) int32 AmdPowerXpressRequestHighPerformance = 1;
}
extern LONG CALLBACK SehExceptionHandler(EXCEPTION_POINTERS* ep);
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR lpCmdLine, int nCmdShow)
{
#ifdef USE_VS_MEM_LEAKS_CHECK
// Memory leaks detect inside VS
int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
flag |= _CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF;
_CrtSetDbgFlag(flag);
#endif
#ifdef USE_VLD_MEM_LEAKS_CHECK
VLDGlobalEnable();
#endif
Platform::PreInit(hInstance);
__try
{
return Engine::Main(lpCmdLine);
}
__except (SehExceptionHandler(GetExceptionInformation()))
{
return -1;
}
}
#endif