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