Removed the UWP platform, as I was never once able to build in last 3 years.

This commit is contained in:
Relintai 2022-03-15 18:29:53 +01:00
parent 8f2388f9d8
commit 9e0b7c56bb
16 changed files with 0 additions and 4247 deletions

View File

@ -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])

View File

@ -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;
}

View File

@ -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 */

View File

@ -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();
};

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}
}

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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>

View File

@ -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;
}
}

View File

@ -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