mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2024-12-22 11:56:49 +01:00
Removed the UWP platform, as I was never once able to build in last 3 years.
This commit is contained in:
parent
8f2388f9d8
commit
9e0b7c56bb
@ -1,21 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
Import("env")
|
|
||||||
|
|
||||||
files = [
|
|
||||||
"#platform/windows/key_mapping_windows.cpp",
|
|
||||||
"#platform/windows/windows_terminal_logger.cpp",
|
|
||||||
"joypad_uwp.cpp",
|
|
||||||
"power_uwp.cpp",
|
|
||||||
"context_egl_uwp.cpp",
|
|
||||||
"app.cpp",
|
|
||||||
"os_uwp.cpp",
|
|
||||||
]
|
|
||||||
|
|
||||||
if "build_angle" in env and env["build_angle"]:
|
|
||||||
cmd = env.AlwaysBuild(env.ANGLE("libANGLE.lib", None))
|
|
||||||
|
|
||||||
prog = env.add_program("#bin/godot", files)
|
|
||||||
|
|
||||||
if "build_angle" in env and env["build_angle"]:
|
|
||||||
env.Depends(prog, [cmd])
|
|
@ -1,571 +0,0 @@
|
|||||||
/*************************************************************************/
|
|
||||||
/* app.cpp */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* 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. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
//
|
|
||||||
// This file demonstrates how to initialize EGL in a Windows Store app, using ICoreWindow.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "app.h"
|
|
||||||
|
|
||||||
#include "core/os/dir_access.h"
|
|
||||||
#include "core/os/file_access.h"
|
|
||||||
#include "core/os/keyboard.h"
|
|
||||||
#include "main/main.h"
|
|
||||||
|
|
||||||
#include "platform/windows/key_mapping_windows.h"
|
|
||||||
|
|
||||||
#include <collection.h>
|
|
||||||
|
|
||||||
using namespace Windows::ApplicationModel::Core;
|
|
||||||
using namespace Windows::ApplicationModel::Activation;
|
|
||||||
using namespace Windows::UI::Core;
|
|
||||||
using namespace Windows::UI::Input;
|
|
||||||
using namespace Windows::Devices::Input;
|
|
||||||
using namespace Windows::UI::Xaml::Input;
|
|
||||||
using namespace Windows::Foundation;
|
|
||||||
using namespace Windows::Graphics::Display;
|
|
||||||
using namespace Windows::System;
|
|
||||||
using namespace Windows::System::Threading::Core;
|
|
||||||
using namespace Microsoft::WRL;
|
|
||||||
|
|
||||||
using namespace GodotUWP;
|
|
||||||
|
|
||||||
// Helper to convert a length in device-independent pixels (DIPs) to a length in physical pixels.
|
|
||||||
inline float ConvertDipsToPixels(float dips, float dpi) {
|
|
||||||
static const float dipsPerInch = 96.0f;
|
|
||||||
return floor(dips * dpi / dipsPerInch + 0.5f); // Round to nearest integer.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implementation of the IFrameworkViewSource interface, necessary to run our app.
|
|
||||||
ref class GodotUWPViewSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource {
|
|
||||||
public:
|
|
||||||
virtual Windows::ApplicationModel::Core::IFrameworkView ^ CreateView() {
|
|
||||||
return ref new App();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// The main function creates an IFrameworkViewSource for our app, and runs the app.
|
|
||||||
[Platform::MTAThread] int main(Platform::Array<Platform::String ^> ^) {
|
|
||||||
auto godotApplicationSource = ref new GodotUWPViewSource();
|
|
||||||
CoreApplication::Run(godotApplicationSource);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
App::App() :
|
|
||||||
mWindowClosed(false),
|
|
||||||
mWindowVisible(true),
|
|
||||||
mWindowWidth(0),
|
|
||||||
mWindowHeight(0),
|
|
||||||
mEglDisplay(EGL_NO_DISPLAY),
|
|
||||||
mEglContext(EGL_NO_CONTEXT),
|
|
||||||
mEglSurface(EGL_NO_SURFACE) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// The first method called when the IFrameworkView is being created.
|
|
||||||
void App::Initialize(CoreApplicationView ^ applicationView) {
|
|
||||||
// Register event handlers for app lifecycle. This example includes Activated, so that we
|
|
||||||
// can make the CoreWindow active and start rendering on the window.
|
|
||||||
applicationView->Activated +=
|
|
||||||
ref new TypedEventHandler<CoreApplicationView ^, IActivatedEventArgs ^>(this, &App::OnActivated);
|
|
||||||
|
|
||||||
// Logic for other event handlers could go here.
|
|
||||||
// Information about the Suspending and Resuming event handlers can be found here:
|
|
||||||
// http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh994930.aspx
|
|
||||||
|
|
||||||
os = new OS_UWP;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called when the CoreWindow object is created (or re-created).
|
|
||||||
void App::SetWindow(CoreWindow ^ p_window) {
|
|
||||||
window = p_window;
|
|
||||||
window->VisibilityChanged +=
|
|
||||||
ref new TypedEventHandler<CoreWindow ^, VisibilityChangedEventArgs ^>(this, &App::OnVisibilityChanged);
|
|
||||||
|
|
||||||
window->Closed +=
|
|
||||||
ref new TypedEventHandler<CoreWindow ^, CoreWindowEventArgs ^>(this, &App::OnWindowClosed);
|
|
||||||
|
|
||||||
window->SizeChanged +=
|
|
||||||
ref new TypedEventHandler<CoreWindow ^, WindowSizeChangedEventArgs ^>(this, &App::OnWindowSizeChanged);
|
|
||||||
|
|
||||||
#if !(WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
|
||||||
// Disable all pointer visual feedback for better performance when touching.
|
|
||||||
// This is not supported on Windows Phone applications.
|
|
||||||
auto pointerVisualizationSettings = PointerVisualizationSettings::GetForCurrentView();
|
|
||||||
pointerVisualizationSettings->IsContactFeedbackEnabled = false;
|
|
||||||
pointerVisualizationSettings->IsBarrelButtonFeedbackEnabled = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
window->PointerPressed +=
|
|
||||||
ref new TypedEventHandler<CoreWindow ^, PointerEventArgs ^>(this, &App::OnPointerPressed);
|
|
||||||
window->PointerMoved +=
|
|
||||||
ref new TypedEventHandler<CoreWindow ^, PointerEventArgs ^>(this, &App::OnPointerMoved);
|
|
||||||
window->PointerReleased +=
|
|
||||||
ref new TypedEventHandler<CoreWindow ^, PointerEventArgs ^>(this, &App::OnPointerReleased);
|
|
||||||
window->PointerWheelChanged +=
|
|
||||||
ref new TypedEventHandler<CoreWindow ^, PointerEventArgs ^>(this, &App::OnPointerWheelChanged);
|
|
||||||
|
|
||||||
mouseChangedNotifier = SignalNotifier::AttachToEvent(L"os_mouse_mode_changed", ref new SignalHandler(this, &App::OnMouseModeChanged));
|
|
||||||
|
|
||||||
mouseChangedNotifier->Enable();
|
|
||||||
|
|
||||||
window->CharacterReceived +=
|
|
||||||
ref new TypedEventHandler<CoreWindow ^, CharacterReceivedEventArgs ^>(this, &App::OnCharacterReceived);
|
|
||||||
window->KeyDown +=
|
|
||||||
ref new TypedEventHandler<CoreWindow ^, KeyEventArgs ^>(this, &App::OnKeyDown);
|
|
||||||
window->KeyUp +=
|
|
||||||
ref new TypedEventHandler<CoreWindow ^, KeyEventArgs ^>(this, &App::OnKeyUp);
|
|
||||||
|
|
||||||
os->set_window(window);
|
|
||||||
|
|
||||||
unsigned int argc;
|
|
||||||
char **argv = get_command_line(&argc);
|
|
||||||
|
|
||||||
Main::setup("uwp", argc, argv, false);
|
|
||||||
|
|
||||||
UpdateWindowSize(Size(window->Bounds.Width, window->Bounds.Height));
|
|
||||||
|
|
||||||
Main::setup2();
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _get_button(Windows::UI::Input::PointerPoint ^ pt) {
|
|
||||||
using namespace Windows::UI::Input;
|
|
||||||
|
|
||||||
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
|
||||||
return BUTTON_LEFT;
|
|
||||||
#else
|
|
||||||
switch (pt->Properties->PointerUpdateKind) {
|
|
||||||
case PointerUpdateKind::LeftButtonPressed:
|
|
||||||
case PointerUpdateKind::LeftButtonReleased:
|
|
||||||
return BUTTON_LEFT;
|
|
||||||
|
|
||||||
case PointerUpdateKind::RightButtonPressed:
|
|
||||||
case PointerUpdateKind::RightButtonReleased:
|
|
||||||
return BUTTON_RIGHT;
|
|
||||||
|
|
||||||
case PointerUpdateKind::MiddleButtonPressed:
|
|
||||||
case PointerUpdateKind::MiddleButtonReleased:
|
|
||||||
return BUTTON_MIDDLE;
|
|
||||||
|
|
||||||
case PointerUpdateKind::XButton1Pressed:
|
|
||||||
case PointerUpdateKind::XButton1Released:
|
|
||||||
return BUTTON_WHEEL_UP;
|
|
||||||
|
|
||||||
case PointerUpdateKind::XButton2Pressed:
|
|
||||||
case PointerUpdateKind::XButton2Released:
|
|
||||||
return BUTTON_WHEEL_DOWN;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool _is_touch(Windows::UI::Input::PointerPoint ^ pointerPoint) {
|
|
||||||
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
using namespace Windows::Devices::Input;
|
|
||||||
switch (pointerPoint->PointerDevice->PointerDeviceType) {
|
|
||||||
case PointerDeviceType::Touch:
|
|
||||||
case PointerDeviceType::Pen:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static Windows::Foundation::Point _get_pixel_position(CoreWindow ^ window, Windows::Foundation::Point rawPosition, OS *os) {
|
|
||||||
Windows::Foundation::Point outputPosition;
|
|
||||||
|
|
||||||
// Compute coordinates normalized from 0..1.
|
|
||||||
// If the coordinates need to be sized to the SDL window,
|
|
||||||
// we'll do that after.
|
|
||||||
#if 1 || WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
|
|
||||||
outputPosition.X = rawPosition.X / window->Bounds.Width;
|
|
||||||
outputPosition.Y = rawPosition.Y / window->Bounds.Height;
|
|
||||||
#else
|
|
||||||
switch (DisplayProperties::CurrentOrientation) {
|
|
||||||
case DisplayOrientations::Portrait:
|
|
||||||
outputPosition.X = rawPosition.X / window->Bounds.Width;
|
|
||||||
outputPosition.Y = rawPosition.Y / window->Bounds.Height;
|
|
||||||
break;
|
|
||||||
case DisplayOrientations::PortraitFlipped:
|
|
||||||
outputPosition.X = 1.0f - (rawPosition.X / window->Bounds.Width);
|
|
||||||
outputPosition.Y = 1.0f - (rawPosition.Y / window->Bounds.Height);
|
|
||||||
break;
|
|
||||||
case DisplayOrientations::Landscape:
|
|
||||||
outputPosition.X = rawPosition.Y / window->Bounds.Height;
|
|
||||||
outputPosition.Y = 1.0f - (rawPosition.X / window->Bounds.Width);
|
|
||||||
break;
|
|
||||||
case DisplayOrientations::LandscapeFlipped:
|
|
||||||
outputPosition.X = 1.0f - (rawPosition.Y / window->Bounds.Height);
|
|
||||||
outputPosition.Y = rawPosition.X / window->Bounds.Width;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
OS::VideoMode vm = os->get_video_mode();
|
|
||||||
outputPosition.X *= vm.width;
|
|
||||||
outputPosition.Y *= vm.height;
|
|
||||||
|
|
||||||
return outputPosition;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int _get_finger(uint32_t p_touch_id) {
|
|
||||||
return p_touch_id % 31; // for now
|
|
||||||
};
|
|
||||||
|
|
||||||
void App::pointer_event(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args, bool p_pressed, bool p_is_wheel) {
|
|
||||||
Windows::UI::Input::PointerPoint ^ point = args->CurrentPoint;
|
|
||||||
Windows::Foundation::Point pos = _get_pixel_position(window, point->Position, os);
|
|
||||||
int but = _get_button(point);
|
|
||||||
if (_is_touch(point)) {
|
|
||||||
Ref<InputEventScreenTouch> screen_touch;
|
|
||||||
screen_touch.instance();
|
|
||||||
screen_touch->set_device(0);
|
|
||||||
screen_touch->set_pressed(p_pressed);
|
|
||||||
screen_touch->set_position(Vector2(pos.X, pos.Y));
|
|
||||||
screen_touch->set_index(_get_finger(point->PointerId));
|
|
||||||
|
|
||||||
last_touch_x[screen_touch->get_index()] = pos.X;
|
|
||||||
last_touch_y[screen_touch->get_index()] = pos.Y;
|
|
||||||
|
|
||||||
os->input_event(screen_touch);
|
|
||||||
} else {
|
|
||||||
Ref<InputEventMouseButton> mouse_button;
|
|
||||||
mouse_button.instance();
|
|
||||||
mouse_button->set_device(0);
|
|
||||||
mouse_button->set_pressed(p_pressed);
|
|
||||||
mouse_button->set_button_index(but);
|
|
||||||
mouse_button->set_position(Vector2(pos.X, pos.Y));
|
|
||||||
mouse_button->set_global_position(Vector2(pos.X, pos.Y));
|
|
||||||
|
|
||||||
if (p_is_wheel) {
|
|
||||||
if (point->Properties->MouseWheelDelta > 0) {
|
|
||||||
mouse_button->set_button_index(point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_UP);
|
|
||||||
} else if (point->Properties->MouseWheelDelta < 0) {
|
|
||||||
mouse_button->set_button_index(point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_LEFT : BUTTON_WHEEL_DOWN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
last_touch_x[31] = pos.X;
|
|
||||||
last_touch_y[31] = pos.Y;
|
|
||||||
|
|
||||||
os->input_event(mouse_button);
|
|
||||||
|
|
||||||
if (p_is_wheel) {
|
|
||||||
// Send release for mouse wheel
|
|
||||||
mouse_button->set_pressed(false);
|
|
||||||
os->input_event(mouse_button);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void App::OnPointerPressed(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
|
|
||||||
pointer_event(sender, args, true);
|
|
||||||
};
|
|
||||||
|
|
||||||
void App::OnPointerReleased(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
|
|
||||||
pointer_event(sender, args, false);
|
|
||||||
};
|
|
||||||
|
|
||||||
void App::OnPointerWheelChanged(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
|
|
||||||
pointer_event(sender, args, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void App::OnMouseModeChanged(Windows::System::Threading::Core::SignalNotifier ^ signalNotifier, bool timedOut) {
|
|
||||||
OS::MouseMode mode = os->get_mouse_mode();
|
|
||||||
SignalNotifier ^ notifier = mouseChangedNotifier;
|
|
||||||
|
|
||||||
window->Dispatcher->RunAsync(
|
|
||||||
CoreDispatcherPriority::High,
|
|
||||||
ref new DispatchedHandler(
|
|
||||||
[mode, notifier, this]() {
|
|
||||||
if (mode == OS::MOUSE_MODE_CAPTURED) {
|
|
||||||
this->MouseMovedToken = MouseDevice::GetForCurrentView()->MouseMoved +=
|
|
||||||
ref new TypedEventHandler<MouseDevice ^, MouseEventArgs ^>(this, &App::OnMouseMoved);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
MouseDevice::GetForCurrentView()->MouseMoved -= MouseMovedToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
notifier->Enable();
|
|
||||||
}));
|
|
||||||
|
|
||||||
ResetEvent(os->mouse_mode_changed);
|
|
||||||
}
|
|
||||||
|
|
||||||
void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
|
|
||||||
Windows::UI::Input::PointerPoint ^ point = args->CurrentPoint;
|
|
||||||
Windows::Foundation::Point pos = _get_pixel_position(window, point->Position, os);
|
|
||||||
|
|
||||||
if (_is_touch(point)) {
|
|
||||||
Ref<InputEventScreenDrag> screen_drag;
|
|
||||||
screen_drag.instance();
|
|
||||||
screen_drag->set_device(0);
|
|
||||||
screen_drag->set_position(Vector2(pos.X, pos.Y));
|
|
||||||
screen_drag->set_index(_get_finger(point->PointerId));
|
|
||||||
screen_drag->set_relative(Vector2(screen_drag->get_position().x - last_touch_x[screen_drag->get_index()], screen_drag->get_position().y - last_touch_y[screen_drag->get_index()]));
|
|
||||||
|
|
||||||
os->input_event(screen_drag);
|
|
||||||
} else {
|
|
||||||
// In case the mouse grabbed, MouseMoved will handle this
|
|
||||||
if (os->get_mouse_mode() == OS::MouseMode::MOUSE_MODE_CAPTURED)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Ref<InputEventMouseMotion> mouse_motion;
|
|
||||||
mouse_motion.instance();
|
|
||||||
mouse_motion->set_device(0);
|
|
||||||
mouse_motion->set_position(Vector2(pos.X, pos.Y));
|
|
||||||
mouse_motion->set_global_position(Vector2(pos.X, pos.Y));
|
|
||||||
mouse_motion->set_relative(Vector2(pos.X - last_touch_x[31], pos.Y - last_touch_y[31]));
|
|
||||||
|
|
||||||
last_mouse_pos = pos;
|
|
||||||
|
|
||||||
os->input_event(mouse_motion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void App::OnMouseMoved(MouseDevice ^ mouse_device, MouseEventArgs ^ args) {
|
|
||||||
// In case the mouse isn't grabbed, PointerMoved will handle this
|
|
||||||
if (os->get_mouse_mode() != OS::MouseMode::MOUSE_MODE_CAPTURED)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Windows::Foundation::Point pos;
|
|
||||||
pos.X = last_mouse_pos.X + args->MouseDelta.X;
|
|
||||||
pos.Y = last_mouse_pos.Y + args->MouseDelta.Y;
|
|
||||||
|
|
||||||
Ref<InputEventMouseMotion> mouse_motion;
|
|
||||||
mouse_motion.instance();
|
|
||||||
mouse_motion->set_device(0);
|
|
||||||
mouse_motion->set_position(Vector2(pos.X, pos.Y));
|
|
||||||
mouse_motion->set_global_position(Vector2(pos.X, pos.Y));
|
|
||||||
mouse_motion->set_relative(Vector2(args->MouseDelta.X, args->MouseDelta.Y));
|
|
||||||
|
|
||||||
last_mouse_pos = pos;
|
|
||||||
|
|
||||||
os->input_event(mouse_motion);
|
|
||||||
}
|
|
||||||
|
|
||||||
void App::key_event(Windows::UI::Core::CoreWindow ^ sender, bool p_pressed, Windows::UI::Core::KeyEventArgs ^ key_args, Windows::UI::Core::CharacterReceivedEventArgs ^ char_args) {
|
|
||||||
OS_UWP::KeyEvent ke;
|
|
||||||
|
|
||||||
ke.control = sender->GetAsyncKeyState(VirtualKey::Control) == CoreVirtualKeyStates::Down;
|
|
||||||
ke.alt = sender->GetAsyncKeyState(VirtualKey::Menu) == CoreVirtualKeyStates::Down;
|
|
||||||
ke.shift = sender->GetAsyncKeyState(VirtualKey::Shift) == CoreVirtualKeyStates::Down;
|
|
||||||
|
|
||||||
ke.pressed = p_pressed;
|
|
||||||
|
|
||||||
if (key_args != nullptr) {
|
|
||||||
ke.type = OS_UWP::KeyEvent::MessageType::KEY_EVENT_MESSAGE;
|
|
||||||
ke.unicode = 0;
|
|
||||||
ke.scancode = KeyMappingWindows::get_keysym((unsigned int)key_args->VirtualKey);
|
|
||||||
ke.physical_scancode = KeyMappingWindows::get_scansym((unsigned int)key_args->KeyStatus.ScanCode, key_args->KeyStatus.IsExtendedKey);
|
|
||||||
ke.echo = (!p_pressed && !key_args->KeyStatus.IsKeyReleased) || (p_pressed && key_args->KeyStatus.WasKeyDown);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
ke.type = OS_UWP::KeyEvent::MessageType::CHAR_EVENT_MESSAGE;
|
|
||||||
ke.unicode = char_args->KeyCode;
|
|
||||||
ke.scancode = 0;
|
|
||||||
ke.physical_scancode = 0;
|
|
||||||
ke.echo = (!p_pressed && !char_args->KeyStatus.IsKeyReleased) || (p_pressed && char_args->KeyStatus.WasKeyDown);
|
|
||||||
}
|
|
||||||
|
|
||||||
os->queue_key_event(ke);
|
|
||||||
}
|
|
||||||
void App::OnKeyDown(CoreWindow ^ sender, KeyEventArgs ^ args) {
|
|
||||||
key_event(sender, true, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
void App::OnKeyUp(CoreWindow ^ sender, KeyEventArgs ^ args) {
|
|
||||||
key_event(sender, false, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
void App::OnCharacterReceived(CoreWindow ^ sender, CharacterReceivedEventArgs ^ args) {
|
|
||||||
key_event(sender, true, nullptr, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initializes scene resources
|
|
||||||
void App::Load(Platform::String ^ entryPoint) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// This method is called after the window becomes active.
|
|
||||||
void App::Run() {
|
|
||||||
if (Main::start())
|
|
||||||
os->run();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Terminate events do not cause Uninitialize to be called. It will be called if your IFrameworkView
|
|
||||||
// class is torn down while the app is in the foreground.
|
|
||||||
void App::Uninitialize() {
|
|
||||||
Main::cleanup();
|
|
||||||
delete os;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Application lifecycle event handler.
|
|
||||||
void App::OnActivated(CoreApplicationView ^ applicationView, IActivatedEventArgs ^ args) {
|
|
||||||
// Run() won't start until the CoreWindow is activated.
|
|
||||||
CoreWindow::GetForCurrentThread()->Activate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Window event handlers.
|
|
||||||
void App::OnVisibilityChanged(CoreWindow ^ sender, VisibilityChangedEventArgs ^ args) {
|
|
||||||
mWindowVisible = args->Visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
void App::OnWindowClosed(CoreWindow ^ sender, CoreWindowEventArgs ^ args) {
|
|
||||||
mWindowClosed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void App::OnWindowSizeChanged(CoreWindow ^ sender, WindowSizeChangedEventArgs ^ args) {
|
|
||||||
#if (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP)
|
|
||||||
// On Windows 8.1, apps are resized when they are snapped alongside other apps, or when the device is rotated.
|
|
||||||
// The default framebuffer will be automatically resized when either of these occur.
|
|
||||||
// In particular, on a 90 degree rotation, the default framebuffer's width and height will switch.
|
|
||||||
UpdateWindowSize(args->Size);
|
|
||||||
#else if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
|
||||||
// On Windows Phone 8.1, the window size changes when the device is rotated.
|
|
||||||
// The default framebuffer will not be automatically resized when this occurs.
|
|
||||||
// It is therefore up to the app to handle rotation-specific logic in its rendering code.
|
|
||||||
//os->screen_size_changed();
|
|
||||||
UpdateWindowSize(args->Size);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void App::UpdateWindowSize(Size size) {
|
|
||||||
float dpi;
|
|
||||||
#if (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP)
|
|
||||||
DisplayInformation ^ currentDisplayInformation = DisplayInformation::GetForCurrentView();
|
|
||||||
dpi = currentDisplayInformation->LogicalDpi;
|
|
||||||
#else if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
|
||||||
dpi = DisplayProperties::LogicalDpi;
|
|
||||||
#endif
|
|
||||||
Size pixelSize(ConvertDipsToPixels(size.Width, dpi), ConvertDipsToPixels(size.Height, dpi));
|
|
||||||
|
|
||||||
mWindowWidth = static_cast<GLsizei>(pixelSize.Width);
|
|
||||||
mWindowHeight = static_cast<GLsizei>(pixelSize.Height);
|
|
||||||
|
|
||||||
OS::VideoMode vm;
|
|
||||||
vm.width = mWindowWidth;
|
|
||||||
vm.height = mWindowHeight;
|
|
||||||
vm.fullscreen = true;
|
|
||||||
vm.resizable = false;
|
|
||||||
os->set_video_mode(vm);
|
|
||||||
}
|
|
||||||
|
|
||||||
char **App::get_command_line(unsigned int *out_argc) {
|
|
||||||
static char *fail_cl[] = { "--path", "game", NULL };
|
|
||||||
*out_argc = 2;
|
|
||||||
|
|
||||||
FILE *f = _wfopen(L"__cl__.cl", L"rb");
|
|
||||||
|
|
||||||
if (f == NULL) {
|
|
||||||
wprintf(L"Couldn't open command line file.\n");
|
|
||||||
return fail_cl;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define READ_LE_4(v) ((int)(##v[3] & 0xFF) << 24) | ((int)(##v[2] & 0xFF) << 16) | ((int)(##v[1] & 0xFF) << 8) | ((int)(##v[0] & 0xFF))
|
|
||||||
#define CMD_MAX_LEN 65535
|
|
||||||
|
|
||||||
uint8_t len[4];
|
|
||||||
int r = fread(len, sizeof(uint8_t), 4, f);
|
|
||||||
|
|
||||||
Platform::Collections::Vector<Platform::String ^> cl;
|
|
||||||
|
|
||||||
if (r < 4) {
|
|
||||||
fclose(f);
|
|
||||||
wprintf(L"Wrong cmdline length.\n");
|
|
||||||
return (fail_cl);
|
|
||||||
}
|
|
||||||
|
|
||||||
int argc = READ_LE_4(len);
|
|
||||||
|
|
||||||
for (int i = 0; i < argc; i++) {
|
|
||||||
r = fread(len, sizeof(uint8_t), 4, f);
|
|
||||||
|
|
||||||
if (r < 4) {
|
|
||||||
fclose(f);
|
|
||||||
wprintf(L"Wrong cmdline param length.\n");
|
|
||||||
return (fail_cl);
|
|
||||||
}
|
|
||||||
|
|
||||||
int strlen = READ_LE_4(len);
|
|
||||||
|
|
||||||
if (strlen > CMD_MAX_LEN) {
|
|
||||||
fclose(f);
|
|
||||||
wprintf(L"Wrong command length.\n");
|
|
||||||
return (fail_cl);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *arg = new char[strlen + 1];
|
|
||||||
r = fread(arg, sizeof(char), strlen, f);
|
|
||||||
arg[strlen] = '\0';
|
|
||||||
|
|
||||||
if (r == strlen) {
|
|
||||||
int warg_size = MultiByteToWideChar(CP_UTF8, 0, arg, -1, NULL, 0);
|
|
||||||
wchar_t *warg = new wchar_t[warg_size];
|
|
||||||
|
|
||||||
MultiByteToWideChar(CP_UTF8, 0, arg, -1, warg, warg_size);
|
|
||||||
|
|
||||||
cl.Append(ref new Platform::String(warg, warg_size));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
delete[] arg;
|
|
||||||
fclose(f);
|
|
||||||
wprintf(L"Error reading command.\n");
|
|
||||||
return (fail_cl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef READ_LE_4
|
|
||||||
#undef CMD_MAX_LEN
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
char **ret = new char *[cl.Size + 1];
|
|
||||||
|
|
||||||
for (int i = 0; i < cl.Size; i++) {
|
|
||||||
int arg_size = WideCharToMultiByte(CP_UTF8, 0, cl.GetAt(i)->Data(), -1, NULL, 0, NULL, NULL);
|
|
||||||
char *arg = new char[arg_size];
|
|
||||||
|
|
||||||
WideCharToMultiByte(CP_UTF8, 0, cl.GetAt(i)->Data(), -1, arg, arg_size, NULL, NULL);
|
|
||||||
|
|
||||||
ret[i] = arg;
|
|
||||||
}
|
|
||||||
ret[cl.Size] = NULL;
|
|
||||||
*out_argc = cl.Size;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
@ -1,114 +0,0 @@
|
|||||||
/*************************************************************************/
|
|
||||||
/* app.h */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* 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. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <wrl.h>
|
|
||||||
|
|
||||||
// ANGLE doesn't provide a specific lib for GLES3, so we keep using GLES2
|
|
||||||
#include "GLES2/gl2.h"
|
|
||||||
#include "os_uwp.h"
|
|
||||||
|
|
||||||
/** clang-format does not play nice with this C++/CX hybrid, needs investigation. */
|
|
||||||
/* clang-format off */
|
|
||||||
|
|
||||||
namespace GodotUWP
|
|
||||||
{
|
|
||||||
ref class App sealed : public Windows::ApplicationModel::Core::IFrameworkView
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
App();
|
|
||||||
|
|
||||||
// IFrameworkView Methods.
|
|
||||||
virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView);
|
|
||||||
virtual void SetWindow(Windows::UI::Core::CoreWindow^ window);
|
|
||||||
virtual void Load(Platform::String^ entryPoint);
|
|
||||||
virtual void Run();
|
|
||||||
virtual void Uninitialize();
|
|
||||||
|
|
||||||
property Windows::Foundation::EventRegistrationToken MouseMovedToken {
|
|
||||||
Windows::Foundation::EventRegistrationToken get() { return this->mouseMovedToken; }
|
|
||||||
void set(Windows::Foundation::EventRegistrationToken p_token) { this->mouseMovedToken = p_token; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void RecreateRenderer();
|
|
||||||
|
|
||||||
// Application lifecycle event handlers.
|
|
||||||
void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
|
|
||||||
|
|
||||||
// Window event handlers.
|
|
||||||
void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args);
|
|
||||||
void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
|
|
||||||
void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args);
|
|
||||||
|
|
||||||
void pointer_event(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args, bool p_pressed, bool p_is_wheel = false);
|
|
||||||
void OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
|
|
||||||
void OnPointerReleased(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
|
|
||||||
void OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
|
|
||||||
void OnMouseMoved(Windows::Devices::Input::MouseDevice^ mouse_device, Windows::Devices::Input::MouseEventArgs^ args);
|
|
||||||
void OnPointerWheelChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
|
|
||||||
|
|
||||||
Windows::System::Threading::Core::SignalNotifier^ mouseChangedNotifier;
|
|
||||||
Windows::Foundation::EventRegistrationToken mouseMovedToken;
|
|
||||||
void OnMouseModeChanged(Windows::System::Threading::Core::SignalNotifier^ signalNotifier, bool timedOut);
|
|
||||||
|
|
||||||
void key_event(Windows::UI::Core::CoreWindow^ sender, bool p_pressed, Windows::UI::Core::KeyEventArgs^ key_args = nullptr, Windows::UI::Core::CharacterReceivedEventArgs^ char_args = nullptr);
|
|
||||||
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 UpdateWindowSize(Windows::Foundation::Size size);
|
|
||||||
void InitializeEGL(Windows::UI::Core::CoreWindow^ window);
|
|
||||||
void CleanupEGL();
|
|
||||||
|
|
||||||
char** get_command_line(unsigned int* out_argc);
|
|
||||||
|
|
||||||
bool mWindowClosed;
|
|
||||||
bool mWindowVisible;
|
|
||||||
GLsizei mWindowWidth;
|
|
||||||
GLsizei mWindowHeight;
|
|
||||||
|
|
||||||
EGLDisplay mEglDisplay;
|
|
||||||
EGLContext mEglContext;
|
|
||||||
EGLSurface mEglSurface;
|
|
||||||
|
|
||||||
CoreWindow^ window;
|
|
||||||
OS_UWP* os;
|
|
||||||
|
|
||||||
int last_touch_x[32]; // 20 fingers, index 31 reserved for the mouse
|
|
||||||
int last_touch_y[32];
|
|
||||||
Windows::Foundation::Point last_mouse_pos;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clang-format on */
|
|
@ -1,211 +0,0 @@
|
|||||||
/*************************************************************************/
|
|
||||||
/* context_egl_uwp.cpp */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* 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. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#include "context_egl_uwp.h"
|
|
||||||
|
|
||||||
#include "EGL/eglext.h"
|
|
||||||
|
|
||||||
using Platform::Exception;
|
|
||||||
|
|
||||||
void ContextEGL_UWP::release_current() {
|
|
||||||
eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, mEglContext);
|
|
||||||
};
|
|
||||||
|
|
||||||
void ContextEGL_UWP::make_current() {
|
|
||||||
eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext);
|
|
||||||
};
|
|
||||||
|
|
||||||
int ContextEGL_UWP::get_window_width() {
|
|
||||||
return width;
|
|
||||||
};
|
|
||||||
|
|
||||||
int ContextEGL_UWP::get_window_height() {
|
|
||||||
return height;
|
|
||||||
};
|
|
||||||
|
|
||||||
void ContextEGL_UWP::reset() {
|
|
||||||
cleanup();
|
|
||||||
|
|
||||||
window = CoreWindow::GetForCurrentThread();
|
|
||||||
initialize();
|
|
||||||
};
|
|
||||||
|
|
||||||
void ContextEGL_UWP::swap_buffers() {
|
|
||||||
if (eglSwapBuffers(mEglDisplay, mEglSurface) != EGL_TRUE) {
|
|
||||||
cleanup();
|
|
||||||
|
|
||||||
window = CoreWindow::GetForCurrentThread();
|
|
||||||
initialize();
|
|
||||||
|
|
||||||
// tell rasterizer to reload textures and stuff?
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Error ContextEGL_UWP::initialize() {
|
|
||||||
EGLint configAttribList[] = {
|
|
||||||
EGL_RED_SIZE, 8,
|
|
||||||
EGL_GREEN_SIZE, 8,
|
|
||||||
EGL_BLUE_SIZE, 8,
|
|
||||||
EGL_ALPHA_SIZE, 8,
|
|
||||||
EGL_DEPTH_SIZE, 8,
|
|
||||||
EGL_STENCIL_SIZE, 8,
|
|
||||||
EGL_SAMPLE_BUFFERS, 0,
|
|
||||||
EGL_NONE
|
|
||||||
};
|
|
||||||
|
|
||||||
EGLint surfaceAttribList[] = {
|
|
||||||
EGL_NONE, EGL_NONE
|
|
||||||
};
|
|
||||||
|
|
||||||
EGLint numConfigs = 0;
|
|
||||||
EGLint majorVersion = 1;
|
|
||||||
EGLint minorVersion;
|
|
||||||
if (driver == GLES_2_0) {
|
|
||||||
minorVersion = 0;
|
|
||||||
} else {
|
|
||||||
minorVersion = 5;
|
|
||||||
}
|
|
||||||
EGLDisplay display = EGL_NO_DISPLAY;
|
|
||||||
EGLContext context = EGL_NO_CONTEXT;
|
|
||||||
EGLSurface surface = EGL_NO_SURFACE;
|
|
||||||
EGLConfig config = nullptr;
|
|
||||||
EGLint contextAttribs[3];
|
|
||||||
if (driver == GLES_2_0) {
|
|
||||||
contextAttribs[0] = EGL_CONTEXT_CLIENT_VERSION;
|
|
||||||
contextAttribs[1] = 2;
|
|
||||||
contextAttribs[2] = EGL_NONE;
|
|
||||||
} else {
|
|
||||||
contextAttribs[0] = EGL_CONTEXT_CLIENT_VERSION;
|
|
||||||
contextAttribs[1] = 3;
|
|
||||||
contextAttribs[2] = EGL_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const EGLint displayAttributes[] = {
|
|
||||||
/*EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
|
|
||||||
EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9,
|
|
||||||
EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3,
|
|
||||||
EGL_NONE,*/
|
|
||||||
// These are the default display attributes, used to request ANGLE's D3D11 renderer.
|
|
||||||
// eglInitialize will only succeed with these attributes if the hardware supports D3D11 Feature Level 10_0+.
|
|
||||||
EGL_PLATFORM_ANGLE_TYPE_ANGLE,
|
|
||||||
EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
|
|
||||||
|
|
||||||
// EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices.
|
|
||||||
// Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it.
|
|
||||||
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER,
|
|
||||||
EGL_TRUE,
|
|
||||||
|
|
||||||
// EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call
|
|
||||||
// the IDXGIDevice3::Trim method on behalf of the application when it gets suspended.
|
|
||||||
// Calling IDXGIDevice3::Trim when an application is suspended is a Windows Store application certification requirement.
|
|
||||||
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
|
|
||||||
EGL_TRUE,
|
|
||||||
EGL_NONE,
|
|
||||||
};
|
|
||||||
|
|
||||||
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
|
|
||||||
|
|
||||||
if (!eglGetPlatformDisplayEXT) {
|
|
||||||
throw Exception::CreateException(E_FAIL, L"Failed to get function eglGetPlatformDisplayEXT");
|
|
||||||
}
|
|
||||||
|
|
||||||
display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttributes);
|
|
||||||
|
|
||||||
if (display == EGL_NO_DISPLAY) {
|
|
||||||
throw Exception::CreateException(E_FAIL, L"Failed to get default EGL display");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eglInitialize(display, &majorVersion, &minorVersion) == EGL_FALSE) {
|
|
||||||
throw Exception::CreateException(E_FAIL, L"Failed to initialize EGL");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eglGetConfigs(display, NULL, 0, &numConfigs) == EGL_FALSE) {
|
|
||||||
throw Exception::CreateException(E_FAIL, L"Failed to get EGLConfig count");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eglChooseConfig(display, configAttribList, &config, 1, &numConfigs) == EGL_FALSE) {
|
|
||||||
throw Exception::CreateException(E_FAIL, L"Failed to choose first EGLConfig count");
|
|
||||||
}
|
|
||||||
|
|
||||||
surface = eglCreateWindowSurface(display, config, reinterpret_cast<IInspectable *>(window), surfaceAttribList);
|
|
||||||
if (surface == EGL_NO_SURFACE) {
|
|
||||||
throw Exception::CreateException(E_FAIL, L"Failed to create EGL fullscreen surface");
|
|
||||||
}
|
|
||||||
|
|
||||||
context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
|
|
||||||
if (context == EGL_NO_CONTEXT) {
|
|
||||||
throw Exception::CreateException(E_FAIL, L"Failed to create EGL context");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {
|
|
||||||
throw Exception::CreateException(E_FAIL, L"Failed to make fullscreen EGLSurface current");
|
|
||||||
}
|
|
||||||
} catch (...) {
|
|
||||||
return FAILED;
|
|
||||||
};
|
|
||||||
|
|
||||||
mEglDisplay = display;
|
|
||||||
mEglSurface = surface;
|
|
||||||
mEglContext = context;
|
|
||||||
|
|
||||||
eglQuerySurface(display, surface, EGL_WIDTH, &width);
|
|
||||||
eglQuerySurface(display, surface, EGL_HEIGHT, &height);
|
|
||||||
|
|
||||||
return OK;
|
|
||||||
};
|
|
||||||
|
|
||||||
void ContextEGL_UWP::cleanup() {
|
|
||||||
if (mEglDisplay != EGL_NO_DISPLAY && mEglSurface != EGL_NO_SURFACE) {
|
|
||||||
eglDestroySurface(mEglDisplay, mEglSurface);
|
|
||||||
mEglSurface = EGL_NO_SURFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mEglDisplay != EGL_NO_DISPLAY && mEglContext != EGL_NO_CONTEXT) {
|
|
||||||
eglDestroyContext(mEglDisplay, mEglContext);
|
|
||||||
mEglContext = EGL_NO_CONTEXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mEglDisplay != EGL_NO_DISPLAY) {
|
|
||||||
eglTerminate(mEglDisplay);
|
|
||||||
mEglDisplay = EGL_NO_DISPLAY;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ContextEGL_UWP::ContextEGL_UWP(CoreWindow ^ p_window, Driver p_driver) :
|
|
||||||
mEglDisplay(EGL_NO_DISPLAY),
|
|
||||||
mEglContext(EGL_NO_CONTEXT),
|
|
||||||
mEglSurface(EGL_NO_SURFACE),
|
|
||||||
driver(p_driver),
|
|
||||||
window(p_window) {}
|
|
||||||
|
|
||||||
ContextEGL_UWP::~ContextEGL_UWP() {
|
|
||||||
cleanup();
|
|
||||||
};
|
|
@ -1,85 +0,0 @@
|
|||||||
/*************************************************************************/
|
|
||||||
/* context_egl_uwp.h */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* 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. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#ifndef CONTEXT_EGL_UWP_H
|
|
||||||
#define CONTEXT_EGL_UWP_H
|
|
||||||
|
|
||||||
#include <wrl.h>
|
|
||||||
|
|
||||||
#include <EGL/egl.h>
|
|
||||||
|
|
||||||
#include "core/error_list.h"
|
|
||||||
#include "core/os/os.h"
|
|
||||||
|
|
||||||
using namespace Windows::UI::Core;
|
|
||||||
|
|
||||||
class ContextEGL_UWP {
|
|
||||||
public:
|
|
||||||
enum Driver {
|
|
||||||
GLES_2_0,
|
|
||||||
GLES_3_0,
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
CoreWindow ^ window;
|
|
||||||
|
|
||||||
EGLDisplay mEglDisplay;
|
|
||||||
EGLContext mEglContext;
|
|
||||||
EGLSurface mEglSurface;
|
|
||||||
|
|
||||||
EGLint width;
|
|
||||||
EGLint height;
|
|
||||||
|
|
||||||
bool vsync;
|
|
||||||
|
|
||||||
Driver driver;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void release_current();
|
|
||||||
|
|
||||||
void make_current();
|
|
||||||
|
|
||||||
int get_window_width();
|
|
||||||
int get_window_height();
|
|
||||||
void swap_buffers();
|
|
||||||
|
|
||||||
void set_use_vsync(bool use) { vsync = use; }
|
|
||||||
bool is_using_vsync() const { return vsync; }
|
|
||||||
|
|
||||||
Error initialize();
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
void cleanup();
|
|
||||||
|
|
||||||
ContextEGL_UWP(CoreWindow ^ p_window, Driver p_driver);
|
|
||||||
~ContextEGL_UWP();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CONTEXT_EGL_UWP_H
|
|
@ -1,210 +0,0 @@
|
|||||||
import methods
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def is_active():
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def get_name():
|
|
||||||
return "UWP"
|
|
||||||
|
|
||||||
|
|
||||||
def can_build():
|
|
||||||
if os.name == "nt":
|
|
||||||
# building natively on windows!
|
|
||||||
if os.getenv("VSINSTALLDIR"):
|
|
||||||
|
|
||||||
if os.getenv("ANGLE_SRC_PATH") is None:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def get_opts():
|
|
||||||
return [
|
|
||||||
("msvc_version", "MSVC version to use (ignored if the VCINSTALLDIR environment variable is set)", None),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def get_flags():
|
|
||||||
return [
|
|
||||||
("tools", False),
|
|
||||||
("xaudio2", True),
|
|
||||||
("builtin_pcre2_with_jit", False),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def configure(env):
|
|
||||||
env.msvc = True
|
|
||||||
|
|
||||||
if env["bits"] != "default":
|
|
||||||
print("Error: bits argument is disabled for MSVC")
|
|
||||||
print(
|
|
||||||
"""
|
|
||||||
Bits argument is not supported for MSVC compilation. Architecture depends on the Native/Cross Compile Tools Prompt/Developer Console
|
|
||||||
(or Visual Studio settings) that is being used to run SCons. As a consequence, bits argument is disabled. Run scons again without bits
|
|
||||||
argument (example: scons p=uwp) and SCons will attempt to detect what MSVC compiler will be executed and inform you.
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
## Build type
|
|
||||||
|
|
||||||
if env["target"] == "release":
|
|
||||||
env.Append(CCFLAGS=["/MD"])
|
|
||||||
env.Append(LINKFLAGS=["/SUBSYSTEM:WINDOWS"])
|
|
||||||
if env["optimize"] != "none":
|
|
||||||
env.Append(CCFLAGS=["/O2", "/GL"])
|
|
||||||
env.Append(LINKFLAGS=["/LTCG"])
|
|
||||||
|
|
||||||
elif env["target"] == "release_debug":
|
|
||||||
env.Append(CCFLAGS=["/MD"])
|
|
||||||
env.Append(LINKFLAGS=["/SUBSYSTEM:CONSOLE"])
|
|
||||||
if env["optimize"] != "none":
|
|
||||||
env.Append(CCFLAGS=["/O2", "/Zi"])
|
|
||||||
|
|
||||||
elif env["target"] == "debug":
|
|
||||||
env.Append(CCFLAGS=["/Zi"])
|
|
||||||
env.Append(CCFLAGS=["/MDd"])
|
|
||||||
env.Append(LINKFLAGS=["/SUBSYSTEM:CONSOLE"])
|
|
||||||
env.Append(LINKFLAGS=["/DEBUG"])
|
|
||||||
|
|
||||||
## Compiler configuration
|
|
||||||
|
|
||||||
env["ENV"] = os.environ
|
|
||||||
vc_base_path = os.environ["VCTOOLSINSTALLDIR"] if "VCTOOLSINSTALLDIR" in os.environ else os.environ["VCINSTALLDIR"]
|
|
||||||
|
|
||||||
# Force to use Unicode encoding
|
|
||||||
env.AppendUnique(CCFLAGS=["/utf-8"])
|
|
||||||
|
|
||||||
# ANGLE
|
|
||||||
angle_root = os.getenv("ANGLE_SRC_PATH")
|
|
||||||
env.Prepend(CPPPATH=[angle_root + "/include"])
|
|
||||||
jobs = str(env.GetOption("num_jobs"))
|
|
||||||
angle_build_cmd = (
|
|
||||||
"msbuild.exe "
|
|
||||||
+ angle_root
|
|
||||||
+ "/winrt/10/src/angle.sln /nologo /v:m /m:"
|
|
||||||
+ jobs
|
|
||||||
+ " /p:Configuration=Release /p:Platform="
|
|
||||||
)
|
|
||||||
|
|
||||||
if os.path.isfile(str(os.getenv("ANGLE_SRC_PATH")) + "/winrt/10/src/angle.sln"):
|
|
||||||
env["build_angle"] = True
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
arch = ""
|
|
||||||
if str(os.getenv("Platform")).lower() == "arm":
|
|
||||||
|
|
||||||
print("Compiled program architecture will be an ARM executable. (forcing bits=32).")
|
|
||||||
|
|
||||||
arch = "arm"
|
|
||||||
env["bits"] = "32"
|
|
||||||
env.Append(LINKFLAGS=["/MACHINE:ARM"])
|
|
||||||
env.Append(LIBPATH=[vc_base_path + "lib/store/arm"])
|
|
||||||
|
|
||||||
angle_build_cmd += "ARM"
|
|
||||||
|
|
||||||
env.Append(LIBPATH=[angle_root + "/winrt/10/src/Release_ARM/lib"])
|
|
||||||
|
|
||||||
else:
|
|
||||||
compiler_version_str = methods.detect_visual_c_compiler_version(env["ENV"])
|
|
||||||
|
|
||||||
if compiler_version_str == "amd64" or compiler_version_str == "x86_amd64":
|
|
||||||
env["bits"] = "64"
|
|
||||||
print("Compiled program architecture will be a x64 executable (forcing bits=64).")
|
|
||||||
elif compiler_version_str == "x86" or compiler_version_str == "amd64_x86":
|
|
||||||
env["bits"] = "32"
|
|
||||||
print("Compiled program architecture will be a x86 executable. (forcing bits=32).")
|
|
||||||
else:
|
|
||||||
print(
|
|
||||||
"Failed to detect MSVC compiler architecture version... Defaulting to 32-bit executable settings (forcing bits=32). Compilation attempt will continue, but SCons can not detect for what architecture this build is compiled for. You should check your settings/compilation setup."
|
|
||||||
)
|
|
||||||
env["bits"] = "32"
|
|
||||||
|
|
||||||
if env["bits"] == "32":
|
|
||||||
arch = "x86"
|
|
||||||
|
|
||||||
angle_build_cmd += "Win32"
|
|
||||||
|
|
||||||
env.Append(LINKFLAGS=["/MACHINE:X86"])
|
|
||||||
env.Append(LIBPATH=[vc_base_path + "lib/store"])
|
|
||||||
env.Append(LIBPATH=[angle_root + "/winrt/10/src/Release_Win32/lib"])
|
|
||||||
|
|
||||||
else:
|
|
||||||
arch = "x64"
|
|
||||||
|
|
||||||
angle_build_cmd += "x64"
|
|
||||||
|
|
||||||
env.Append(LINKFLAGS=["/MACHINE:X64"])
|
|
||||||
env.Append(LIBPATH=[os.environ["VCINSTALLDIR"] + "lib/store/amd64"])
|
|
||||||
env.Append(LIBPATH=[angle_root + "/winrt/10/src/Release_x64/lib"])
|
|
||||||
|
|
||||||
env["PROGSUFFIX"] = "." + arch + env["PROGSUFFIX"]
|
|
||||||
env["OBJSUFFIX"] = "." + arch + env["OBJSUFFIX"]
|
|
||||||
env["LIBSUFFIX"] = "." + arch + env["LIBSUFFIX"]
|
|
||||||
|
|
||||||
## Compile flags
|
|
||||||
|
|
||||||
env.Prepend(CPPPATH=["#platform/uwp", "#drivers/windows"])
|
|
||||||
env.Append(CPPDEFINES=["UWP_ENABLED", "WINDOWS_ENABLED", "TYPED_METHOD_BIND"])
|
|
||||||
env.Append(CPPDEFINES=["GLES_ENABLED", "GL_GLEXT_PROTOTYPES", "EGL_EGLEXT_PROTOTYPES", "ANGLE_ENABLED"])
|
|
||||||
winver = "0x0602" # Windows 8 is the minimum target for UWP build
|
|
||||||
env.Append(CPPDEFINES=[("WINVER", winver), ("_WIN32_WINNT", winver), "WIN32"])
|
|
||||||
|
|
||||||
env.Append(CPPDEFINES=["__WRL_NO_DEFAULT_LIB__", ("PNG_ABORT", "abort")])
|
|
||||||
|
|
||||||
env.Append(CPPFLAGS=["/AI", vc_base_path + "lib/store/references"])
|
|
||||||
env.Append(CPPFLAGS=["/AI", vc_base_path + "lib/x86/store/references"])
|
|
||||||
|
|
||||||
env.Append(
|
|
||||||
CCFLAGS='/FS /MP /GS /wd"4453" /wd"28204" /wd"4291" /Zc:wchar_t /Gm- /fp:precise /errorReport:prompt /WX- /Zc:forScope /Gd /EHsc /nologo'.split()
|
|
||||||
)
|
|
||||||
env.Append(CPPDEFINES=["_UNICODE", "UNICODE", ("WINAPI_FAMILY", "WINAPI_FAMILY_APP")])
|
|
||||||
env.Append(CXXFLAGS=["/ZW"])
|
|
||||||
env.Append(
|
|
||||||
CCFLAGS=[
|
|
||||||
"/AI",
|
|
||||||
vc_base_path + "\\vcpackages",
|
|
||||||
"/AI",
|
|
||||||
os.environ["WINDOWSSDKDIR"] + "\\References\\CommonConfiguration\\Neutral",
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
## Link flags
|
|
||||||
|
|
||||||
env.Append(
|
|
||||||
LINKFLAGS=[
|
|
||||||
"/MANIFEST:NO",
|
|
||||||
"/NXCOMPAT",
|
|
||||||
"/DYNAMICBASE",
|
|
||||||
"/WINMD",
|
|
||||||
"/APPCONTAINER",
|
|
||||||
"/ERRORREPORT:PROMPT",
|
|
||||||
"/NOLOGO",
|
|
||||||
"/TLBID:1",
|
|
||||||
'/NODEFAULTLIB:"kernel32.lib"',
|
|
||||||
'/NODEFAULTLIB:"ole32.lib"',
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
LIBS = [
|
|
||||||
"WindowsApp",
|
|
||||||
"mincore",
|
|
||||||
"ws2_32",
|
|
||||||
"libANGLE",
|
|
||||||
"libEGL",
|
|
||||||
"libGLESv2",
|
|
||||||
"bcrypt",
|
|
||||||
]
|
|
||||||
env.Append(LINKFLAGS=[p + ".lib" for p in LIBS])
|
|
||||||
|
|
||||||
# Incremental linking fix
|
|
||||||
env["BUILDERS"]["ProgramOriginal"] = env["BUILDERS"]["Program"]
|
|
||||||
env["BUILDERS"]["Program"] = methods.precious_program
|
|
||||||
|
|
||||||
env.Append(BUILDERS={"ANGLE": env.Builder(action=angle_build_cmd)})
|
|
File diff suppressed because it is too large
Load Diff
@ -1,36 +0,0 @@
|
|||||||
/*************************************************************************/
|
|
||||||
/* export.h */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* 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. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#ifndef UWP_EXPORT_H
|
|
||||||
#define UWP_EXPORT_H
|
|
||||||
|
|
||||||
void register_uwp_exporter();
|
|
||||||
|
|
||||||
#endif // UWP_EXPORT_H
|
|
@ -1,170 +0,0 @@
|
|||||||
/*************************************************************************/
|
|
||||||
/* joypad_uwp.cpp */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* 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. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#include "joypad_uwp.h"
|
|
||||||
#include "core/os/os.h"
|
|
||||||
|
|
||||||
using namespace Windows::Gaming::Input;
|
|
||||||
using namespace Windows::Foundation;
|
|
||||||
|
|
||||||
void JoypadUWP::register_events() {
|
|
||||||
Gamepad::GamepadAdded +=
|
|
||||||
ref new EventHandler<Gamepad ^>(this, &JoypadUWP::OnGamepadAdded);
|
|
||||||
Gamepad::GamepadRemoved +=
|
|
||||||
ref new EventHandler<Gamepad ^>(this, &JoypadUWP::OnGamepadRemoved);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JoypadUWP::process_controllers() {
|
|
||||||
for (int i = 0; i < MAX_CONTROLLERS; i++) {
|
|
||||||
ControllerDevice &joy = controllers[i];
|
|
||||||
|
|
||||||
if (!joy.connected)
|
|
||||||
break;
|
|
||||||
|
|
||||||
switch (joy.type) {
|
|
||||||
case ControllerType::GAMEPAD_CONTROLLER: {
|
|
||||||
GamepadReading reading = ((Gamepad ^) joy.controller_reference)->GetCurrentReading();
|
|
||||||
|
|
||||||
int button_mask = (int)GamepadButtons::Menu;
|
|
||||||
for (int j = 0; j < 14; j++) {
|
|
||||||
input->joy_button(joy.id, j, (int)reading.Buttons & button_mask);
|
|
||||||
button_mask *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
input->joy_axis(joy.id, JOY_AXIS_0, axis_correct(reading.LeftThumbstickX));
|
|
||||||
input->joy_axis(joy.id, JOY_AXIS_1, axis_correct(reading.LeftThumbstickY, true));
|
|
||||||
input->joy_axis(joy.id, JOY_AXIS_2, axis_correct(reading.RightThumbstickX));
|
|
||||||
input->joy_axis(joy.id, JOY_AXIS_3, axis_correct(reading.RightThumbstickY, true));
|
|
||||||
input->joy_axis(joy.id, JOY_AXIS_4, axis_correct(reading.LeftTrigger, false, true));
|
|
||||||
input->joy_axis(joy.id, JOY_AXIS_5, axis_correct(reading.RightTrigger, false, true));
|
|
||||||
|
|
||||||
uint64_t timestamp = input->get_joy_vibration_timestamp(joy.id);
|
|
||||||
if (timestamp > joy.ff_timestamp) {
|
|
||||||
Vector2 strength = input->get_joy_vibration_strength(joy.id);
|
|
||||||
float duration = input->get_joy_vibration_duration(joy.id);
|
|
||||||
if (strength.x == 0 && strength.y == 0) {
|
|
||||||
joypad_vibration_stop(i, timestamp);
|
|
||||||
} else {
|
|
||||||
joypad_vibration_start(i, strength.x, strength.y, duration, timestamp);
|
|
||||||
}
|
|
||||||
} else if (joy.vibrating && joy.ff_end_timestamp != 0) {
|
|
||||||
uint64_t current_time = OS::get_singleton()->get_ticks_usec();
|
|
||||||
if (current_time >= joy.ff_end_timestamp)
|
|
||||||
joypad_vibration_stop(i, current_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
JoypadUWP::JoypadUWP() {
|
|
||||||
for (int i = 0; i < MAX_CONTROLLERS; i++)
|
|
||||||
controllers[i].id = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
JoypadUWP::JoypadUWP(InputDefault *p_input) {
|
|
||||||
input = p_input;
|
|
||||||
|
|
||||||
JoypadUWP();
|
|
||||||
}
|
|
||||||
|
|
||||||
void JoypadUWP::OnGamepadAdded(Platform::Object ^ sender, Windows::Gaming::Input::Gamepad ^ value) {
|
|
||||||
short idx = -1;
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_CONTROLLERS; i++) {
|
|
||||||
if (!controllers[i].connected) {
|
|
||||||
idx = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ERR_FAIL_COND(idx == -1);
|
|
||||||
|
|
||||||
controllers[idx].connected = true;
|
|
||||||
controllers[idx].controller_reference = value;
|
|
||||||
controllers[idx].id = idx;
|
|
||||||
controllers[idx].type = ControllerType::GAMEPAD_CONTROLLER;
|
|
||||||
|
|
||||||
input->joy_connection_changed(controllers[idx].id, true, "Xbox Controller", "__UWP_GAMEPAD__");
|
|
||||||
}
|
|
||||||
|
|
||||||
void JoypadUWP::OnGamepadRemoved(Platform::Object ^ sender, Windows::Gaming::Input::Gamepad ^ value) {
|
|
||||||
short idx = -1;
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_CONTROLLERS; i++) {
|
|
||||||
if (controllers[i].controller_reference == value) {
|
|
||||||
idx = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ERR_FAIL_COND(idx == -1);
|
|
||||||
|
|
||||||
controllers[idx] = ControllerDevice();
|
|
||||||
|
|
||||||
input->joy_connection_changed(idx, false, "Xbox Controller");
|
|
||||||
}
|
|
||||||
|
|
||||||
float JoypadUWP::axis_correct(double p_val, bool p_negate, bool p_trigger) const {
|
|
||||||
if (p_trigger) {
|
|
||||||
// Convert to a value between -1.0f and 1.0f.
|
|
||||||
return 2.0f * p_val - 1.0f;
|
|
||||||
}
|
|
||||||
return (float)(p_negate ? -p_val : p_val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JoypadUWP::joypad_vibration_start(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp) {
|
|
||||||
ControllerDevice &joy = controllers[p_device];
|
|
||||||
if (joy.connected) {
|
|
||||||
GamepadVibration vibration;
|
|
||||||
vibration.LeftMotor = p_strong_magnitude;
|
|
||||||
vibration.RightMotor = p_weak_magnitude;
|
|
||||||
((Gamepad ^) joy.controller_reference)->Vibration = vibration;
|
|
||||||
|
|
||||||
joy.ff_timestamp = p_timestamp;
|
|
||||||
joy.ff_end_timestamp = p_duration == 0 ? 0 : p_timestamp + (uint64_t)(p_duration * 1000000.0);
|
|
||||||
joy.vibrating = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JoypadUWP::joypad_vibration_stop(int p_device, uint64_t p_timestamp) {
|
|
||||||
ControllerDevice &joy = controllers[p_device];
|
|
||||||
if (joy.connected) {
|
|
||||||
GamepadVibration vibration;
|
|
||||||
vibration.LeftMotor = 0.0;
|
|
||||||
vibration.RightMotor = 0.0;
|
|
||||||
((Gamepad ^) joy.controller_reference)->Vibration = vibration;
|
|
||||||
|
|
||||||
joy.ff_timestamp = p_timestamp;
|
|
||||||
joy.vibrating = false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
/*************************************************************************/
|
|
||||||
/* joypad_uwp.h */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* 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. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#ifndef JOYPAD_UWP_H
|
|
||||||
#define JOYPAD_UWP_H
|
|
||||||
|
|
||||||
#include "main/input_default.h"
|
|
||||||
|
|
||||||
ref class JoypadUWP sealed {
|
|
||||||
/** clang-format breaks this, it does not understand this token. */
|
|
||||||
/* clang-format off */
|
|
||||||
internal:
|
|
||||||
void register_events();
|
|
||||||
void process_controllers();
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
JoypadUWP();
|
|
||||||
JoypadUWP(InputDefault *p_input);
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum {
|
|
||||||
MAX_CONTROLLERS = 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ControllerType {
|
|
||||||
GAMEPAD_CONTROLLER,
|
|
||||||
ARCADE_STICK_CONTROLLER,
|
|
||||||
RACING_WHEEL_CONTROLLER,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ControllerDevice {
|
|
||||||
Windows::Gaming::Input::IGameController ^ controller_reference;
|
|
||||||
|
|
||||||
int id;
|
|
||||||
bool connected;
|
|
||||||
ControllerType type;
|
|
||||||
float ff_timestamp;
|
|
||||||
float ff_end_timestamp;
|
|
||||||
bool vibrating;
|
|
||||||
|
|
||||||
ControllerDevice() {
|
|
||||||
id = -1;
|
|
||||||
connected = false;
|
|
||||||
type = ControllerType::GAMEPAD_CONTROLLER;
|
|
||||||
ff_timestamp = 0.0f;
|
|
||||||
ff_end_timestamp = 0.0f;
|
|
||||||
vibrating = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ControllerDevice controllers[MAX_CONTROLLERS];
|
|
||||||
|
|
||||||
InputDefault *input;
|
|
||||||
|
|
||||||
void OnGamepadAdded(Platform::Object ^ sender, Windows::Gaming::Input::Gamepad ^ value);
|
|
||||||
void OnGamepadRemoved(Platform::Object ^ sender, Windows::Gaming::Input::Gamepad ^ value);
|
|
||||||
|
|
||||||
float axis_correct(double p_val, bool p_negate = false, bool p_trigger = false) const;
|
|
||||||
void joypad_vibration_start(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp);
|
|
||||||
void joypad_vibration_stop(int p_device, uint64_t p_timestamp);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.5 KiB |
@ -1,856 +0,0 @@
|
|||||||
/*************************************************************************/
|
|
||||||
/* os_uwp.cpp */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* 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. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#include "os_uwp.h"
|
|
||||||
|
|
||||||
#include "core/io/marshalls.h"
|
|
||||||
#include "core/project_settings.h"
|
|
||||||
#include "drivers/gles2/rasterizer_gles2.h"
|
|
||||||
#include "drivers/unix/ip_unix.h"
|
|
||||||
#include "drivers/unix/net_socket_posix.h"
|
|
||||||
#include "drivers/windows/dir_access_windows.h"
|
|
||||||
#include "drivers/windows/file_access_windows.h"
|
|
||||||
#include "main/main.h"
|
|
||||||
#include "platform/windows/windows_terminal_logger.h"
|
|
||||||
#include "servers/audio_server.h"
|
|
||||||
#include "servers/visual/visual_server_raster.h"
|
|
||||||
#include "servers/visual/visual_server_wrap_mt.h"
|
|
||||||
|
|
||||||
#include <ppltasks.h>
|
|
||||||
#include <wrl.h>
|
|
||||||
|
|
||||||
using namespace Windows::ApplicationModel::Core;
|
|
||||||
using namespace Windows::ApplicationModel::Activation;
|
|
||||||
using namespace Windows::UI::Core;
|
|
||||||
using namespace Windows::UI::Input;
|
|
||||||
using namespace Windows::UI::Popups;
|
|
||||||
using namespace Windows::Foundation;
|
|
||||||
using namespace Windows::Graphics::Display;
|
|
||||||
using namespace Microsoft::WRL;
|
|
||||||
using namespace Windows::UI::ViewManagement;
|
|
||||||
using namespace Windows::Devices::Input;
|
|
||||||
using namespace Windows::Devices::Sensors;
|
|
||||||
using namespace Windows::ApplicationModel::DataTransfer;
|
|
||||||
using namespace concurrency;
|
|
||||||
|
|
||||||
int OS_UWP::get_video_driver_count() const {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
Size2 OS_UWP::get_window_size() const {
|
|
||||||
Size2 size;
|
|
||||||
size.width = video_mode.width;
|
|
||||||
size.height = video_mode.height;
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int OS_UWP::get_current_video_driver() const {
|
|
||||||
return video_driver_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::set_window_size(const Size2 p_size) {
|
|
||||||
Windows::Foundation::Size new_size;
|
|
||||||
new_size.Width = p_size.width;
|
|
||||||
new_size.Height = p_size.height;
|
|
||||||
|
|
||||||
ApplicationView ^ view = ApplicationView::GetForCurrentView();
|
|
||||||
|
|
||||||
if (view->TryResizeView(new_size)) {
|
|
||||||
video_mode.width = p_size.width;
|
|
||||||
video_mode.height = p_size.height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::set_window_fullscreen(bool p_enabled) {
|
|
||||||
ApplicationView ^ view = ApplicationView::GetForCurrentView();
|
|
||||||
|
|
||||||
video_mode.fullscreen = view->IsFullScreenMode;
|
|
||||||
|
|
||||||
if (video_mode.fullscreen == p_enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (p_enabled) {
|
|
||||||
video_mode.fullscreen = view->TryEnterFullScreenMode();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
view->ExitFullScreenMode();
|
|
||||||
video_mode.fullscreen = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OS_UWP::is_window_fullscreen() const {
|
|
||||||
return ApplicationView::GetForCurrentView()->IsFullScreenMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::set_keep_screen_on(bool p_enabled) {
|
|
||||||
if (is_keep_screen_on() == p_enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (p_enabled)
|
|
||||||
display_request->RequestActive();
|
|
||||||
else
|
|
||||||
display_request->RequestRelease();
|
|
||||||
|
|
||||||
OS::set_keep_screen_on(p_enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::initialize_core() {
|
|
||||||
last_button_state = 0;
|
|
||||||
|
|
||||||
//RedirectIOToConsole();
|
|
||||||
|
|
||||||
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
|
|
||||||
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA);
|
|
||||||
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_FILESYSTEM);
|
|
||||||
DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_RESOURCES);
|
|
||||||
DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_USERDATA);
|
|
||||||
DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_FILESYSTEM);
|
|
||||||
|
|
||||||
NetSocketPosix::make_default();
|
|
||||||
|
|
||||||
// We need to know how often the clock is updated
|
|
||||||
QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second);
|
|
||||||
QueryPerformanceCounter((LARGE_INTEGER *)&ticks_start);
|
|
||||||
|
|
||||||
IP_Unix::make_default();
|
|
||||||
|
|
||||||
cursor_shape = CURSOR_ARROW;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OS_UWP::can_draw() const {
|
|
||||||
return !minimized;
|
|
||||||
};
|
|
||||||
|
|
||||||
void OS_UWP::set_window(Windows::UI::Core::CoreWindow ^ p_window) {
|
|
||||||
window = p_window;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::screen_size_changed() {
|
|
||||||
gl_context->reset();
|
|
||||||
};
|
|
||||||
|
|
||||||
Error OS_UWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
|
|
||||||
main_loop = NULL;
|
|
||||||
outside = true;
|
|
||||||
|
|
||||||
ContextEGL_UWP::Driver opengl_api_type = ContextEGL_UWP::GLES_2_0;
|
|
||||||
|
|
||||||
//if (p_video_driver == VIDEO_DRIVER_GLES2) {
|
|
||||||
// opengl_api_type = ContextEGL_UWP::GLES_2_0;
|
|
||||||
//}
|
|
||||||
|
|
||||||
bool gl_initialization_error = false;
|
|
||||||
|
|
||||||
gl_context = NULL;
|
|
||||||
while (!gl_context) {
|
|
||||||
gl_context = memnew(ContextEGL_UWP(window, opengl_api_type));
|
|
||||||
|
|
||||||
if (gl_context->initialize() != OK) {
|
|
||||||
memdelete(gl_context);
|
|
||||||
gl_context = NULL;
|
|
||||||
|
|
||||||
if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2")) {
|
|
||||||
if (p_video_driver == VIDEO_DRIVER_GLES2) {
|
|
||||||
gl_initialization_error = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
p_video_driver = VIDEO_DRIVER_GLES2;
|
|
||||||
opengl_api_type = ContextEGL_UWP::GLES_2_0;
|
|
||||||
} else {
|
|
||||||
gl_initialization_error = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if (opengl_api_type == ContextEGL_UWP::GLES_2_0) {
|
|
||||||
if (RasterizerGLES2::is_viable() == OK) {
|
|
||||||
RasterizerGLES2::register_config();
|
|
||||||
RasterizerGLES2::make_current();
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
gl_initialization_error = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gl_initialization_error) {
|
|
||||||
OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n"
|
|
||||||
"Please update your drivers or if you have a very old or integrated GPU, upgrade it.",
|
|
||||||
"Unable to initialize Video driver");
|
|
||||||
return ERR_UNAVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
video_driver_index = p_video_driver;
|
|
||||||
gl_context->make_current();
|
|
||||||
gl_context->set_use_vsync(video_mode.use_vsync);
|
|
||||||
|
|
||||||
VideoMode vm;
|
|
||||||
vm.width = gl_context->get_window_width();
|
|
||||||
vm.height = gl_context->get_window_height();
|
|
||||||
vm.resizable = false;
|
|
||||||
|
|
||||||
ApplicationView ^ view = ApplicationView::GetForCurrentView();
|
|
||||||
vm.fullscreen = view->IsFullScreenMode;
|
|
||||||
|
|
||||||
view->SetDesiredBoundsMode(ApplicationViewBoundsMode::UseVisible);
|
|
||||||
view->PreferredLaunchWindowingMode = ApplicationViewWindowingMode::PreferredLaunchViewSize;
|
|
||||||
|
|
||||||
if (p_desired.fullscreen != view->IsFullScreenMode) {
|
|
||||||
if (p_desired.fullscreen) {
|
|
||||||
vm.fullscreen = view->TryEnterFullScreenMode();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
view->ExitFullScreenMode();
|
|
||||||
vm.fullscreen = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Windows::Foundation::Size desired;
|
|
||||||
desired.Width = p_desired.width;
|
|
||||||
desired.Height = p_desired.height;
|
|
||||||
|
|
||||||
view->PreferredLaunchViewSize = desired;
|
|
||||||
|
|
||||||
if (view->TryResizeView(desired)) {
|
|
||||||
vm.width = view->VisibleBounds.Width;
|
|
||||||
vm.height = view->VisibleBounds.Height;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_video_mode(vm);
|
|
||||||
|
|
||||||
visual_server = memnew(VisualServerRaster);
|
|
||||||
// FIXME: Reimplement threaded rendering
|
|
||||||
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
|
|
||||||
visual_server = memnew(VisualServerWrapMT(visual_server, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
visual_server->init();
|
|
||||||
|
|
||||||
input = memnew(InputDefault);
|
|
||||||
|
|
||||||
joypad = ref new JoypadUWP(input);
|
|
||||||
joypad->register_events();
|
|
||||||
|
|
||||||
AudioDriverManager::initialize(p_audio_driver);
|
|
||||||
|
|
||||||
power_manager = memnew(PowerUWP);
|
|
||||||
|
|
||||||
managed_object->update_clipboard();
|
|
||||||
|
|
||||||
Clipboard::ContentChanged += ref new EventHandler<Platform::Object ^>(managed_object, &ManagedType::on_clipboard_changed);
|
|
||||||
|
|
||||||
accelerometer = Accelerometer::GetDefault();
|
|
||||||
if (accelerometer != nullptr) {
|
|
||||||
// 60 FPS
|
|
||||||
accelerometer->ReportInterval = (1.0f / 60.0f) * 1000;
|
|
||||||
accelerometer->ReadingChanged +=
|
|
||||||
ref new TypedEventHandler<Accelerometer ^, AccelerometerReadingChangedEventArgs ^>(managed_object, &ManagedType::on_accelerometer_reading_changed);
|
|
||||||
}
|
|
||||||
|
|
||||||
magnetometer = Magnetometer::GetDefault();
|
|
||||||
if (magnetometer != nullptr) {
|
|
||||||
// 60 FPS
|
|
||||||
magnetometer->ReportInterval = (1.0f / 60.0f) * 1000;
|
|
||||||
magnetometer->ReadingChanged +=
|
|
||||||
ref new TypedEventHandler<Magnetometer ^, MagnetometerReadingChangedEventArgs ^>(managed_object, &ManagedType::on_magnetometer_reading_changed);
|
|
||||||
}
|
|
||||||
|
|
||||||
gyrometer = Gyrometer::GetDefault();
|
|
||||||
if (gyrometer != nullptr) {
|
|
||||||
// 60 FPS
|
|
||||||
gyrometer->ReportInterval = (1.0f / 60.0f) * 1000;
|
|
||||||
gyrometer->ReadingChanged +=
|
|
||||||
ref new TypedEventHandler<Gyrometer ^, GyrometerReadingChangedEventArgs ^>(managed_object, &ManagedType::on_gyroscope_reading_changed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_keep_screen_on())
|
|
||||||
display_request->RequestActive();
|
|
||||||
|
|
||||||
set_keep_screen_on(GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true));
|
|
||||||
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::set_clipboard(const String &p_text) {
|
|
||||||
DataPackage ^ clip = ref new DataPackage();
|
|
||||||
clip->RequestedOperation = DataPackageOperation::Copy;
|
|
||||||
clip->SetText(ref new Platform::String((const wchar_t *)p_text.c_str()));
|
|
||||||
|
|
||||||
Clipboard::SetContent(clip);
|
|
||||||
};
|
|
||||||
|
|
||||||
String OS_UWP::get_clipboard() const {
|
|
||||||
if (managed_object->clipboard != nullptr)
|
|
||||||
return managed_object->clipboard->Data();
|
|
||||||
else
|
|
||||||
return "";
|
|
||||||
};
|
|
||||||
|
|
||||||
void OS_UWP::input_event(const Ref<InputEvent> &p_event) {
|
|
||||||
input->parse_input_event(p_event);
|
|
||||||
};
|
|
||||||
|
|
||||||
void OS_UWP::delete_main_loop() {
|
|
||||||
if (main_loop)
|
|
||||||
memdelete(main_loop);
|
|
||||||
main_loop = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::set_main_loop(MainLoop *p_main_loop) {
|
|
||||||
input->set_main_loop(p_main_loop);
|
|
||||||
main_loop = p_main_loop;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::finalize() {
|
|
||||||
if (main_loop)
|
|
||||||
memdelete(main_loop);
|
|
||||||
|
|
||||||
main_loop = NULL;
|
|
||||||
|
|
||||||
visual_server->finish();
|
|
||||||
memdelete(visual_server);
|
|
||||||
#ifdef OPENGL_ENABLED
|
|
||||||
if (gl_context)
|
|
||||||
memdelete(gl_context);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memdelete(input);
|
|
||||||
|
|
||||||
joypad = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::finalize_core() {
|
|
||||||
NetSocketPosix::cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::alert(const String &p_alert, const String &p_title) {
|
|
||||||
Platform::String ^ alert = ref new Platform::String(p_alert.c_str());
|
|
||||||
Platform::String ^ title = ref new Platform::String(p_title.c_str());
|
|
||||||
|
|
||||||
MessageDialog ^ msg = ref new MessageDialog(alert, title);
|
|
||||||
|
|
||||||
UICommand ^ close = ref new UICommand("Close", ref new UICommandInvokedHandler(managed_object, &OS_UWP::ManagedType::alert_close));
|
|
||||||
msg->Commands->Append(close);
|
|
||||||
msg->DefaultCommandIndex = 0;
|
|
||||||
|
|
||||||
managed_object->alert_close_handle = true;
|
|
||||||
|
|
||||||
msg->ShowAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::ManagedType::alert_close(IUICommand ^ command) {
|
|
||||||
alert_close_handle = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::ManagedType::on_clipboard_changed(Platform::Object ^ sender, Platform::Object ^ ev) {
|
|
||||||
update_clipboard();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::ManagedType::update_clipboard() {
|
|
||||||
DataPackageView ^ data = Clipboard::GetContent();
|
|
||||||
|
|
||||||
if (data->Contains(StandardDataFormats::Text)) {
|
|
||||||
create_task(data->GetTextAsync()).then([this](Platform::String ^ clipboard_content) {
|
|
||||||
this->clipboard = clipboard_content;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::ManagedType::on_accelerometer_reading_changed(Accelerometer ^ sender, AccelerometerReadingChangedEventArgs ^ args) {
|
|
||||||
AccelerometerReading ^ reading = args->Reading;
|
|
||||||
|
|
||||||
os->input->set_accelerometer(Vector3(
|
|
||||||
reading->AccelerationX,
|
|
||||||
reading->AccelerationY,
|
|
||||||
reading->AccelerationZ));
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::ManagedType::on_magnetometer_reading_changed(Magnetometer ^ sender, MagnetometerReadingChangedEventArgs ^ args) {
|
|
||||||
MagnetometerReading ^ reading = args->Reading;
|
|
||||||
|
|
||||||
os->input->set_magnetometer(Vector3(
|
|
||||||
reading->MagneticFieldX,
|
|
||||||
reading->MagneticFieldY,
|
|
||||||
reading->MagneticFieldZ));
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::ManagedType::on_gyroscope_reading_changed(Gyrometer ^ sender, GyrometerReadingChangedEventArgs ^ args) {
|
|
||||||
GyrometerReading ^ reading = args->Reading;
|
|
||||||
|
|
||||||
os->input->set_magnetometer(Vector3(
|
|
||||||
reading->AngularVelocityX,
|
|
||||||
reading->AngularVelocityY,
|
|
||||||
reading->AngularVelocityZ));
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::set_mouse_mode(MouseMode p_mode) {
|
|
||||||
if (p_mode == MouseMode::MOUSE_MODE_CAPTURED) {
|
|
||||||
CoreWindow::GetForCurrentThread()->SetPointerCapture();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
CoreWindow::GetForCurrentThread()->ReleasePointerCapture();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_mode == MouseMode::MOUSE_MODE_CAPTURED || p_mode == MouseMode::MOUSE_MODE_HIDDEN) {
|
|
||||||
CoreWindow::GetForCurrentThread()->PointerCursor = nullptr;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
CoreWindow::GetForCurrentThread()->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
mouse_mode = p_mode;
|
|
||||||
|
|
||||||
SetEvent(mouse_mode_changed);
|
|
||||||
}
|
|
||||||
|
|
||||||
OS_UWP::MouseMode OS_UWP::get_mouse_mode() const {
|
|
||||||
return mouse_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
Point2 OS_UWP::get_mouse_position() const {
|
|
||||||
return Point2(old_x, old_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
int OS_UWP::get_mouse_button_state() const {
|
|
||||||
return last_button_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::set_window_title(const String &p_title) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::set_video_mode(const VideoMode &p_video_mode, int p_screen) {
|
|
||||||
video_mode = p_video_mode;
|
|
||||||
}
|
|
||||||
OS::VideoMode OS_UWP::get_video_mode(int p_screen) const {
|
|
||||||
return video_mode;
|
|
||||||
}
|
|
||||||
void OS_UWP::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
|
|
||||||
}
|
|
||||||
|
|
||||||
String OS_UWP::get_name() const {
|
|
||||||
return "UWP";
|
|
||||||
}
|
|
||||||
|
|
||||||
OS::Date OS_UWP::get_date(bool utc) const {
|
|
||||||
SYSTEMTIME systemtime;
|
|
||||||
if (utc)
|
|
||||||
GetSystemTime(&systemtime);
|
|
||||||
else
|
|
||||||
GetLocalTime(&systemtime);
|
|
||||||
|
|
||||||
Date date;
|
|
||||||
date.day = systemtime.wDay;
|
|
||||||
date.month = Month(systemtime.wMonth);
|
|
||||||
date.weekday = Weekday(systemtime.wDayOfWeek);
|
|
||||||
date.year = systemtime.wYear;
|
|
||||||
date.dst = false;
|
|
||||||
return date;
|
|
||||||
}
|
|
||||||
OS::Time OS_UWP::get_time(bool utc) const {
|
|
||||||
SYSTEMTIME systemtime;
|
|
||||||
if (utc)
|
|
||||||
GetSystemTime(&systemtime);
|
|
||||||
else
|
|
||||||
GetLocalTime(&systemtime);
|
|
||||||
|
|
||||||
Time time;
|
|
||||||
time.hour = systemtime.wHour;
|
|
||||||
time.min = systemtime.wMinute;
|
|
||||||
time.sec = systemtime.wSecond;
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
OS::TimeZoneInfo OS_UWP::get_time_zone_info() const {
|
|
||||||
TIME_ZONE_INFORMATION info;
|
|
||||||
bool daylight = false;
|
|
||||||
if (GetTimeZoneInformation(&info) == TIME_ZONE_ID_DAYLIGHT)
|
|
||||||
daylight = true;
|
|
||||||
|
|
||||||
TimeZoneInfo ret;
|
|
||||||
if (daylight) {
|
|
||||||
ret.name = info.DaylightName;
|
|
||||||
} else {
|
|
||||||
ret.name = info.StandardName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bias value returned by GetTimeZoneInformation is inverted of what we expect
|
|
||||||
// For example on GMT-3 GetTimeZoneInformation return a Bias of 180, so invert the value to get -180
|
|
||||||
ret.bias = -info.Bias;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t OS_UWP::get_unix_time() const {
|
|
||||||
FILETIME ft;
|
|
||||||
SYSTEMTIME st;
|
|
||||||
GetSystemTime(&st);
|
|
||||||
SystemTimeToFileTime(&st, &ft);
|
|
||||||
|
|
||||||
SYSTEMTIME ep;
|
|
||||||
ep.wYear = 1970;
|
|
||||||
ep.wMonth = 1;
|
|
||||||
ep.wDayOfWeek = 4;
|
|
||||||
ep.wDay = 1;
|
|
||||||
ep.wHour = 0;
|
|
||||||
ep.wMinute = 0;
|
|
||||||
ep.wSecond = 0;
|
|
||||||
ep.wMilliseconds = 0;
|
|
||||||
FILETIME fep;
|
|
||||||
SystemTimeToFileTime(&ep, &fep);
|
|
||||||
|
|
||||||
return (*(uint64_t *)&ft - *(uint64_t *)&fep) / 10000000;
|
|
||||||
};
|
|
||||||
|
|
||||||
void OS_UWP::delay_usec(uint32_t p_usec) const {
|
|
||||||
int msec = p_usec < 1000 ? 1 : p_usec / 1000;
|
|
||||||
|
|
||||||
// no Sleep()
|
|
||||||
WaitForSingleObjectEx(GetCurrentThread(), msec, false);
|
|
||||||
}
|
|
||||||
uint64_t OS_UWP::get_ticks_usec() const {
|
|
||||||
uint64_t ticks;
|
|
||||||
|
|
||||||
// This is the number of clock ticks since start
|
|
||||||
QueryPerformanceCounter((LARGE_INTEGER *)&ticks);
|
|
||||||
// Subtract the ticks at game start to get
|
|
||||||
// the ticks since the game started
|
|
||||||
ticks -= ticks_start;
|
|
||||||
|
|
||||||
// Divide by frequency to get the time in seconds
|
|
||||||
// original calculation shown below is subject to overflow
|
|
||||||
// with high ticks_per_second and a number of days since the last reboot.
|
|
||||||
// time = ticks * 1000000L / ticks_per_second;
|
|
||||||
|
|
||||||
// we can prevent this by either using 128 bit math
|
|
||||||
// or separating into a calculation for seconds, and the fraction
|
|
||||||
uint64_t seconds = ticks / ticks_per_second;
|
|
||||||
|
|
||||||
// compiler will optimize these two into one divide
|
|
||||||
uint64_t leftover = ticks % ticks_per_second;
|
|
||||||
|
|
||||||
// remainder
|
|
||||||
uint64_t time = (leftover * 1000000L) / ticks_per_second;
|
|
||||||
|
|
||||||
// seconds
|
|
||||||
time += seconds * 1000000L;
|
|
||||||
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::process_events() {
|
|
||||||
joypad->process_controllers();
|
|
||||||
process_key_events();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::process_key_events() {
|
|
||||||
for (int i = 0; i < key_event_pos; i++) {
|
|
||||||
KeyEvent &kev = key_event_buffer[i];
|
|
||||||
|
|
||||||
Ref<InputEventKey> key_event;
|
|
||||||
key_event.instance();
|
|
||||||
key_event->set_alt(kev.alt);
|
|
||||||
key_event->set_shift(kev.shift);
|
|
||||||
key_event->set_control(kev.control);
|
|
||||||
key_event->set_echo(kev.echo);
|
|
||||||
key_event->set_scancode(kev.scancode);
|
|
||||||
key_event->set_physical_scancode(kev.physical_scancode);
|
|
||||||
key_event->set_unicode(kev.unicode);
|
|
||||||
key_event->set_pressed(kev.pressed);
|
|
||||||
|
|
||||||
input_event(key_event);
|
|
||||||
}
|
|
||||||
key_event_pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::queue_key_event(KeyEvent &p_event) {
|
|
||||||
// This merges Char events with the previous Key event, so
|
|
||||||
// the unicode can be retrieved without sending duplicate events.
|
|
||||||
if (p_event.type == KeyEvent::MessageType::CHAR_EVENT_MESSAGE && key_event_pos > 0) {
|
|
||||||
KeyEvent &old = key_event_buffer[key_event_pos - 1];
|
|
||||||
ERR_FAIL_COND(old.type != KeyEvent::MessageType::KEY_EVENT_MESSAGE);
|
|
||||||
|
|
||||||
key_event_buffer[key_event_pos - 1].unicode = p_event.unicode;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ERR_FAIL_COND(key_event_pos >= KEY_EVENT_BUFFER_SIZE);
|
|
||||||
|
|
||||||
key_event_buffer[key_event_pos++] = p_event;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::set_cursor_shape(CursorShape p_shape) {
|
|
||||||
ERR_FAIL_INDEX(p_shape, CURSOR_MAX);
|
|
||||||
|
|
||||||
if (cursor_shape == p_shape)
|
|
||||||
return;
|
|
||||||
|
|
||||||
static const CoreCursorType uwp_cursors[CURSOR_MAX] = {
|
|
||||||
CoreCursorType::Arrow,
|
|
||||||
CoreCursorType::IBeam,
|
|
||||||
CoreCursorType::Hand,
|
|
||||||
CoreCursorType::Cross,
|
|
||||||
CoreCursorType::Wait,
|
|
||||||
CoreCursorType::Wait,
|
|
||||||
CoreCursorType::Arrow,
|
|
||||||
CoreCursorType::Arrow,
|
|
||||||
CoreCursorType::UniversalNo,
|
|
||||||
CoreCursorType::SizeNorthSouth,
|
|
||||||
CoreCursorType::SizeWestEast,
|
|
||||||
CoreCursorType::SizeNortheastSouthwest,
|
|
||||||
CoreCursorType::SizeNorthwestSoutheast,
|
|
||||||
CoreCursorType::SizeAll,
|
|
||||||
CoreCursorType::SizeNorthSouth,
|
|
||||||
CoreCursorType::SizeWestEast,
|
|
||||||
CoreCursorType::Help
|
|
||||||
};
|
|
||||||
|
|
||||||
CoreWindow::GetForCurrentThread()->PointerCursor = ref new CoreCursor(uwp_cursors[p_shape], 0);
|
|
||||||
|
|
||||||
cursor_shape = p_shape;
|
|
||||||
}
|
|
||||||
|
|
||||||
OS::CursorShape OS_UWP::get_cursor_shape() const {
|
|
||||||
return cursor_shape;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
Error OS_UWP::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex, bool p_open_console) {
|
|
||||||
return FAILED;
|
|
||||||
};
|
|
||||||
|
|
||||||
Error OS_UWP::kill(const ProcessID &p_pid) {
|
|
||||||
return FAILED;
|
|
||||||
};
|
|
||||||
|
|
||||||
Error OS_UWP::set_cwd(const String &p_cwd) {
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
String OS_UWP::get_executable_path() const {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::set_icon(const Ref<Image> &p_icon) {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OS_UWP::has_environment(const String &p_var) const {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
String OS_UWP::get_environment(const String &p_var) const {
|
|
||||||
return "";
|
|
||||||
};
|
|
||||||
|
|
||||||
bool OS_UWP::set_environment(const String &p_var, const String &p_value) const {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
String OS_UWP::get_stdin_string(bool p_block) {
|
|
||||||
return String();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::move_window_to_foreground() {
|
|
||||||
}
|
|
||||||
|
|
||||||
Error OS_UWP::shell_open(String p_uri) {
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
String OS_UWP::get_locale() const {
|
|
||||||
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP // this should work on phone 8.1, but it doesn't
|
|
||||||
return "en";
|
|
||||||
#else
|
|
||||||
Platform::String ^ language = Windows::Globalization::Language::CurrentInputMethodLanguageTag;
|
|
||||||
return String(language->Data()).replace("-", "_");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::release_rendering_thread() {
|
|
||||||
gl_context->release_current();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::make_rendering_thread() {
|
|
||||||
gl_context->make_current();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::swap_buffers() {
|
|
||||||
gl_context->swap_buffers();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OS_UWP::has_touchscreen_ui_hint() const {
|
|
||||||
TouchCapabilities ^ tc = ref new TouchCapabilities();
|
|
||||||
return tc->TouchPresent != 0 || UIViewSettings::GetForCurrentView()->UserInteractionMode == UserInteractionMode::Touch;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OS_UWP::has_virtual_keyboard() const {
|
|
||||||
return UIViewSettings::GetForCurrentView()->UserInteractionMode == UserInteractionMode::Touch;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
|
|
||||||
InputPane ^ pane = InputPane::GetForCurrentView();
|
|
||||||
pane->TryShow();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::hide_virtual_keyboard() {
|
|
||||||
InputPane ^ pane = InputPane::GetForCurrentView();
|
|
||||||
pane->TryHide();
|
|
||||||
}
|
|
||||||
|
|
||||||
static String format_error_message(DWORD id) {
|
|
||||||
LPWSTR messageBuffer = NULL;
|
|
||||||
size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
||||||
NULL, id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, NULL);
|
|
||||||
|
|
||||||
String msg = "Error " + itos(id) + ": " + String(messageBuffer, size);
|
|
||||||
|
|
||||||
LocalFree(messageBuffer);
|
|
||||||
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
Error OS_UWP::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) {
|
|
||||||
String full_path = "game/" + p_path;
|
|
||||||
p_library_handle = (void *)LoadPackagedLibrary(full_path.c_str(), 0);
|
|
||||||
ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + full_path + ", error: " + format_error_message(GetLastError()) + ".");
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
Error OS_UWP::close_dynamic_library(void *p_library_handle) {
|
|
||||||
if (!FreeLibrary((HMODULE)p_library_handle)) {
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
Error OS_UWP::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional) {
|
|
||||||
p_symbol_handle = (void *)GetProcAddress((HMODULE)p_library_handle, p_name.utf8().get_data());
|
|
||||||
if (!p_symbol_handle) {
|
|
||||||
if (!p_optional) {
|
|
||||||
ERR_FAIL_V_MSG(ERR_CANT_RESOLVE, "Can't resolve symbol " + p_name + ", error: " + String::num(GetLastError()) + ".");
|
|
||||||
} else {
|
|
||||||
return ERR_CANT_RESOLVE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_UWP::run() {
|
|
||||||
if (!main_loop)
|
|
||||||
return;
|
|
||||||
|
|
||||||
main_loop->init();
|
|
||||||
|
|
||||||
uint64_t last_ticks = get_ticks_usec();
|
|
||||||
|
|
||||||
int frames = 0;
|
|
||||||
uint64_t frame = 0;
|
|
||||||
|
|
||||||
while (!force_quit) {
|
|
||||||
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
|
|
||||||
if (managed_object->alert_close_handle)
|
|
||||||
continue;
|
|
||||||
process_events(); // get rid of pending events
|
|
||||||
if (Main::iteration())
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
main_loop->finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
MainLoop *OS_UWP::get_main_loop() const {
|
|
||||||
return main_loop;
|
|
||||||
}
|
|
||||||
|
|
||||||
String OS_UWP::get_user_data_dir() const {
|
|
||||||
Windows::Storage::StorageFolder ^ data_folder = Windows::Storage::ApplicationData::Current->LocalFolder;
|
|
||||||
|
|
||||||
return String(data_folder->Path->Data()).replace("\\", "/");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OS_UWP::_check_internal_feature_support(const String &p_feature) {
|
|
||||||
return p_feature == "pc";
|
|
||||||
}
|
|
||||||
|
|
||||||
OS::PowerState OS_UWP::get_power_state() {
|
|
||||||
return power_manager->get_power_state();
|
|
||||||
}
|
|
||||||
|
|
||||||
int OS_UWP::get_power_seconds_left() {
|
|
||||||
return power_manager->get_power_seconds_left();
|
|
||||||
}
|
|
||||||
|
|
||||||
int OS_UWP::get_power_percent_left() {
|
|
||||||
return power_manager->get_power_percent_left();
|
|
||||||
}
|
|
||||||
|
|
||||||
OS_UWP::OS_UWP() {
|
|
||||||
key_event_pos = 0;
|
|
||||||
force_quit = false;
|
|
||||||
alt_mem = false;
|
|
||||||
gr_mem = false;
|
|
||||||
shift_mem = false;
|
|
||||||
control_mem = false;
|
|
||||||
meta_mem = false;
|
|
||||||
minimized = false;
|
|
||||||
|
|
||||||
pressrc = 0;
|
|
||||||
old_invalid = true;
|
|
||||||
mouse_mode = MOUSE_MODE_VISIBLE;
|
|
||||||
#ifdef STDOUT_FILE
|
|
||||||
stdo = fopen("stdout.txt", "wb");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gl_context = NULL;
|
|
||||||
|
|
||||||
display_request = ref new Windows::System::Display::DisplayRequest();
|
|
||||||
|
|
||||||
managed_object = ref new ManagedType;
|
|
||||||
managed_object->os = this;
|
|
||||||
|
|
||||||
mouse_mode_changed = CreateEvent(NULL, TRUE, FALSE, L"os_mouse_mode_changed");
|
|
||||||
|
|
||||||
AudioDriverManager::add_driver(&audio_driver);
|
|
||||||
|
|
||||||
Vector<Logger *> loggers;
|
|
||||||
loggers.push_back(memnew(WindowsTerminalLogger));
|
|
||||||
_set_logger(memnew(CompositeLogger(loggers)));
|
|
||||||
}
|
|
||||||
|
|
||||||
OS_UWP::~OS_UWP() {
|
|
||||||
#ifdef STDOUT_FILE
|
|
||||||
fclose(stdo);
|
|
||||||
#endif
|
|
||||||
}
|
|
@ -1,262 +0,0 @@
|
|||||||
/*************************************************************************/
|
|
||||||
/* os_uwp.h */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* 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. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#ifndef OS_UWP_H
|
|
||||||
#define OS_UWP_H
|
|
||||||
|
|
||||||
#include "context_egl_uwp.h"
|
|
||||||
#include "core/math/transform_2d.h"
|
|
||||||
#include "core/os/input.h"
|
|
||||||
#include "core/os/os.h"
|
|
||||||
#include "core/ustring.h"
|
|
||||||
#include "drivers/xaudio2/audio_driver_xaudio2.h"
|
|
||||||
#include "joypad_uwp.h"
|
|
||||||
#include "main/input_default.h"
|
|
||||||
#include "power_uwp.h"
|
|
||||||
#include "servers/audio_server.h"
|
|
||||||
#include "servers/visual/rasterizer.h"
|
|
||||||
#include "servers/visual_server.h"
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <io.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
class OS_UWP : public OS {
|
|
||||||
public:
|
|
||||||
struct KeyEvent {
|
|
||||||
enum MessageType {
|
|
||||||
KEY_EVENT_MESSAGE,
|
|
||||||
CHAR_EVENT_MESSAGE
|
|
||||||
};
|
|
||||||
|
|
||||||
bool alt, shift, control;
|
|
||||||
MessageType type;
|
|
||||||
bool pressed;
|
|
||||||
unsigned int scancode;
|
|
||||||
unsigned int physical_scancode;
|
|
||||||
unsigned int unicode;
|
|
||||||
bool echo;
|
|
||||||
CorePhysicalKeyStatus status;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum {
|
|
||||||
JOYPADS_MAX = 8,
|
|
||||||
JOY_AXIS_COUNT = 6,
|
|
||||||
MAX_JOY_AXIS = 32768, // I've no idea
|
|
||||||
KEY_EVENT_BUFFER_SIZE = 512
|
|
||||||
};
|
|
||||||
|
|
||||||
FILE *stdo;
|
|
||||||
|
|
||||||
KeyEvent key_event_buffer[KEY_EVENT_BUFFER_SIZE];
|
|
||||||
int key_event_pos;
|
|
||||||
|
|
||||||
uint64_t ticks_start;
|
|
||||||
uint64_t ticks_per_second;
|
|
||||||
|
|
||||||
bool minimized;
|
|
||||||
bool old_invalid;
|
|
||||||
bool outside;
|
|
||||||
int old_x, old_y;
|
|
||||||
Point2i center;
|
|
||||||
VisualServer *visual_server;
|
|
||||||
int pressrc;
|
|
||||||
|
|
||||||
ContextEGL_UWP *gl_context;
|
|
||||||
Windows::UI::Core::CoreWindow ^ window;
|
|
||||||
|
|
||||||
VideoMode video_mode;
|
|
||||||
int video_driver_index;
|
|
||||||
|
|
||||||
MainLoop *main_loop;
|
|
||||||
|
|
||||||
AudioDriverXAudio2 audio_driver;
|
|
||||||
|
|
||||||
PowerUWP *power_manager;
|
|
||||||
|
|
||||||
MouseMode mouse_mode;
|
|
||||||
bool alt_mem;
|
|
||||||
bool gr_mem;
|
|
||||||
bool shift_mem;
|
|
||||||
bool control_mem;
|
|
||||||
bool meta_mem;
|
|
||||||
bool force_quit;
|
|
||||||
uint32_t last_button_state;
|
|
||||||
|
|
||||||
CursorShape cursor_shape;
|
|
||||||
|
|
||||||
InputDefault *input;
|
|
||||||
|
|
||||||
JoypadUWP ^ joypad;
|
|
||||||
|
|
||||||
Windows::System::Display::DisplayRequest ^ display_request;
|
|
||||||
|
|
||||||
ref class ManagedType {
|
|
||||||
public:
|
|
||||||
property bool alert_close_handle;
|
|
||||||
property Platform::String ^ clipboard;
|
|
||||||
void alert_close(Windows::UI::Popups::IUICommand ^ command);
|
|
||||||
void on_clipboard_changed(Platform::Object ^ sender, Platform::Object ^ ev);
|
|
||||||
void update_clipboard();
|
|
||||||
void on_accelerometer_reading_changed(Windows::Devices::Sensors::Accelerometer ^ sender, Windows::Devices::Sensors::AccelerometerReadingChangedEventArgs ^ args);
|
|
||||||
void on_magnetometer_reading_changed(Windows::Devices::Sensors::Magnetometer ^ sender, Windows::Devices::Sensors::MagnetometerReadingChangedEventArgs ^ args);
|
|
||||||
void on_gyroscope_reading_changed(Windows::Devices::Sensors::Gyrometer ^ sender, Windows::Devices::Sensors::GyrometerReadingChangedEventArgs ^ args);
|
|
||||||
|
|
||||||
/** clang-format breaks this, it does not understand this token. */
|
|
||||||
/* clang-format off */
|
|
||||||
internal:
|
|
||||||
ManagedType() { alert_close_handle = false; }
|
|
||||||
property OS_UWP* os;
|
|
||||||
/* clang-format on */
|
|
||||||
};
|
|
||||||
ManagedType ^ managed_object;
|
|
||||||
Windows::Devices::Sensors::Accelerometer ^ accelerometer;
|
|
||||||
Windows::Devices::Sensors::Magnetometer ^ magnetometer;
|
|
||||||
Windows::Devices::Sensors::Gyrometer ^ gyrometer;
|
|
||||||
|
|
||||||
// functions used by main to initialize/deinitialize the OS
|
|
||||||
protected:
|
|
||||||
virtual int get_video_driver_count() const;
|
|
||||||
virtual int get_current_video_driver() const;
|
|
||||||
|
|
||||||
virtual void initialize_core();
|
|
||||||
virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
|
||||||
|
|
||||||
virtual void set_main_loop(MainLoop *p_main_loop);
|
|
||||||
virtual void delete_main_loop();
|
|
||||||
|
|
||||||
virtual void finalize();
|
|
||||||
virtual void finalize_core();
|
|
||||||
|
|
||||||
void process_events();
|
|
||||||
|
|
||||||
void process_key_events();
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Event to send to the app wrapper
|
|
||||||
HANDLE mouse_mode_changed;
|
|
||||||
|
|
||||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
|
||||||
String get_stdin_string(bool p_block);
|
|
||||||
|
|
||||||
void set_mouse_mode(MouseMode p_mode);
|
|
||||||
MouseMode get_mouse_mode() const;
|
|
||||||
|
|
||||||
virtual Point2 get_mouse_position() const;
|
|
||||||
virtual int get_mouse_button_state() const;
|
|
||||||
virtual void set_window_title(const String &p_title);
|
|
||||||
|
|
||||||
virtual void set_video_mode(const VideoMode &p_video_mode, int p_screen = 0);
|
|
||||||
virtual VideoMode get_video_mode(int p_screen = 0) const;
|
|
||||||
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const;
|
|
||||||
virtual Size2 get_window_size() const;
|
|
||||||
virtual void set_window_size(const Size2 p_size);
|
|
||||||
virtual void set_window_fullscreen(bool p_enabled);
|
|
||||||
virtual bool is_window_fullscreen() const;
|
|
||||||
virtual void set_keep_screen_on(bool p_enabled);
|
|
||||||
|
|
||||||
virtual MainLoop *get_main_loop() const;
|
|
||||||
|
|
||||||
virtual String get_name() const;
|
|
||||||
|
|
||||||
virtual Date get_date(bool utc) const;
|
|
||||||
virtual Time get_time(bool utc) const;
|
|
||||||
virtual TimeZoneInfo get_time_zone_info() const;
|
|
||||||
virtual uint64_t get_unix_time() const;
|
|
||||||
|
|
||||||
virtual bool can_draw() const;
|
|
||||||
virtual Error set_cwd(const String &p_cwd);
|
|
||||||
|
|
||||||
virtual void delay_usec(uint32_t p_usec) const;
|
|
||||||
virtual uint64_t get_ticks_usec() const;
|
|
||||||
|
|
||||||
virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false, Mutex *p_pipe_mutex = NULL, bool p_open_console = false);
|
|
||||||
virtual Error kill(const ProcessID &p_pid);
|
|
||||||
|
|
||||||
virtual bool has_environment(const String &p_var) const;
|
|
||||||
virtual String get_environment(const String &p_var) const;
|
|
||||||
virtual bool set_environment(const String &p_var, const String &p_value) const;
|
|
||||||
|
|
||||||
virtual void set_clipboard(const String &p_text);
|
|
||||||
virtual String get_clipboard() const;
|
|
||||||
|
|
||||||
void set_cursor_shape(CursorShape p_shape);
|
|
||||||
CursorShape get_cursor_shape() const;
|
|
||||||
virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
|
|
||||||
void set_icon(const Ref<Image> &p_icon);
|
|
||||||
|
|
||||||
virtual String get_executable_path() const;
|
|
||||||
|
|
||||||
virtual String get_locale() const;
|
|
||||||
|
|
||||||
virtual void move_window_to_foreground();
|
|
||||||
virtual String get_user_data_dir() const;
|
|
||||||
|
|
||||||
virtual bool _check_internal_feature_support(const String &p_feature);
|
|
||||||
|
|
||||||
void set_window(Windows::UI::Core::CoreWindow ^ p_window);
|
|
||||||
void screen_size_changed();
|
|
||||||
|
|
||||||
virtual void release_rendering_thread();
|
|
||||||
virtual void make_rendering_thread();
|
|
||||||
virtual void swap_buffers();
|
|
||||||
|
|
||||||
virtual bool has_touchscreen_ui_hint() const;
|
|
||||||
|
|
||||||
virtual bool has_virtual_keyboard() const;
|
|
||||||
virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), bool p_multiline = false, int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
|
|
||||||
virtual void hide_virtual_keyboard();
|
|
||||||
|
|
||||||
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
|
|
||||||
virtual Error close_dynamic_library(void *p_library_handle);
|
|
||||||
virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false);
|
|
||||||
|
|
||||||
virtual Error shell_open(String p_uri);
|
|
||||||
|
|
||||||
void run();
|
|
||||||
|
|
||||||
virtual bool get_swap_ok_cancel() { return true; }
|
|
||||||
|
|
||||||
void input_event(const Ref<InputEvent> &p_event);
|
|
||||||
|
|
||||||
virtual OS::PowerState get_power_state();
|
|
||||||
virtual int get_power_seconds_left();
|
|
||||||
virtual int get_power_percent_left();
|
|
||||||
|
|
||||||
void queue_key_event(KeyEvent &p_event);
|
|
||||||
|
|
||||||
OS_UWP();
|
|
||||||
~OS_UWP();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,31 +0,0 @@
|
|||||||
/*************************************************************************/
|
|
||||||
/* platform_config.h */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* 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. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#include <malloc.h>
|
|
@ -1,77 +0,0 @@
|
|||||||
/*************************************************************************/
|
|
||||||
/* power_uwp.cpp */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* 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. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#include "power_uwp.h"
|
|
||||||
|
|
||||||
PowerUWP::PowerUWP() :
|
|
||||||
nsecs_left(-1),
|
|
||||||
percent_left(-1),
|
|
||||||
power_state(OS::POWERSTATE_UNKNOWN) {
|
|
||||||
}
|
|
||||||
|
|
||||||
PowerUWP::~PowerUWP() {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PowerUWP::UpdatePowerInfo() {
|
|
||||||
// TODO, WinRT: Battery info is available on at least one WinRT platform (Windows Phone 8). Implement UpdatePowerInfo as appropriate. */
|
|
||||||
/* Notes from SDL:
|
|
||||||
* - the Win32 function, GetSystemPowerStatus, is not available for use on WinRT
|
|
||||||
* - Windows Phone 8 has a 'Battery' class, which is documented as available for C++
|
|
||||||
* - More info on WP8's Battery class can be found at http://msdn.microsoft.com/library/windowsphone/develop/jj207231
|
|
||||||
*/
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
OS::PowerState PowerUWP::get_power_state() {
|
|
||||||
if (UpdatePowerInfo()) {
|
|
||||||
return power_state;
|
|
||||||
} else {
|
|
||||||
WARN_PRINT("Power management is not implemented on this platform, defaulting to POWERSTATE_UNKNOWN");
|
|
||||||
return OS::POWERSTATE_UNKNOWN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int PowerUWP::get_power_seconds_left() {
|
|
||||||
if (UpdatePowerInfo()) {
|
|
||||||
return nsecs_left;
|
|
||||||
} else {
|
|
||||||
WARN_PRINT("Power management is not implemented on this platform, defaulting to -1");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int PowerUWP::get_power_percent_left() {
|
|
||||||
if (UpdatePowerInfo()) {
|
|
||||||
return percent_left;
|
|
||||||
} else {
|
|
||||||
WARN_PRINT("Power management is not implemented on this platform, defaulting to -1");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
/*************************************************************************/
|
|
||||||
/* power_uwp.h */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/*************************************************************************/
|
|
||||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
|
||||||
/* */
|
|
||||||
/* 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. */
|
|
||||||
/*************************************************************************/
|
|
||||||
|
|
||||||
#ifndef POWER_UWP_H
|
|
||||||
#define POWER_UWP_H
|
|
||||||
|
|
||||||
#include "core/os/dir_access.h"
|
|
||||||
#include "core/os/file_access.h"
|
|
||||||
#include "core/os/os.h"
|
|
||||||
|
|
||||||
class PowerUWP {
|
|
||||||
private:
|
|
||||||
int nsecs_left;
|
|
||||||
int percent_left;
|
|
||||||
OS::PowerState power_state;
|
|
||||||
|
|
||||||
bool UpdatePowerInfo();
|
|
||||||
|
|
||||||
public:
|
|
||||||
PowerUWP();
|
|
||||||
virtual ~PowerUWP();
|
|
||||||
|
|
||||||
OS::PowerState get_power_state();
|
|
||||||
int get_power_seconds_left();
|
|
||||||
int get_power_percent_left();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // POWER_UWP_H
|
|
Loading…
Reference in New Issue
Block a user