summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main/input_default.cpp4
-rwxr-xr-xmethods.py69
-rw-r--r--platform/windows/detect.py78
-rw-r--r--platform/winrt/SCsub12
-rw-r--r--platform/winrt/app.cpp302
-rw-r--r--platform/winrt/app.h53
-rw-r--r--platform/winrt/audio_driver_winrt.cpp244
-rw-r--r--platform/winrt/audio_driver_winrt.h109
-rw-r--r--platform/winrt/detect.py175
-rw-r--r--platform/winrt/gl_context_egl.cpp15
-rw-r--r--platform/winrt/gl_context_egl.h5
-rw-r--r--platform/winrt/joystick_winrt.cpp146
-rw-r--r--platform/winrt/joystick_winrt.h81
-rw-r--r--platform/winrt/os_winrt.cpp444
-rw-r--r--platform/winrt/os_winrt.h108
-rw-r--r--platform/winrt/thread_winrt.cpp4
16 files changed, 1548 insertions, 301 deletions
diff --git a/main/input_default.cpp b/main/input_default.cpp
index f93a142c54..5bd277044a 100644
--- a/main/input_default.cpp
+++ b/main/input_default.cpp
@@ -660,6 +660,10 @@ static const char *s_ControllerMappings [] =
"303534632d303563342d576972656c65,PS4 Controller USB/Win,leftx:a0,lefty:a1,dpdown:b15,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a5,lefttrigger:a3,x:b0,dpup:b14,dpleft:b16,dpright:b17,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b1,righttrigger:b7,b:b2,",
"c2a94d6963726f736f66742058626f78,Wireless X360 Controller,leftx:a0,lefty:a1,dpdown:b14,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:b11,lefttrigger:a2,x:b2,dpup:b13,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:b12,righttrigger:a5,b:b1,",
#endif
+
+ #ifdef WINRT_ENABLED
+ "__WINRT_GAMEPAD__,Xbox Controller,a:b2,b:b3,x:b4,y:b5,start:b0,back:b1,leftstick:b12,rightstick:b13,leftshoulder:b10,rightshoulder:b11,dpup:b6,dpdown:b7,dpleft:b8,dpright:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,",
+ #endif
NULL
};
diff --git a/methods.py b/methods.py
index e29fd760ba..8c99794d7a 100755
--- a/methods.py
+++ b/methods.py
@@ -1450,3 +1450,72 @@ def colored(sys,env):
env.Append( JARCOMSTR=[java_library_message] )
env.Append( JAVACCOMSTR=[java_compile_source_message] )
+def detect_visual_c_compiler_version(tools_env):
+ # tools_env is the variable scons uses to call tools that execute tasks, SCons's env['ENV'] that executes tasks...
+ # (see the SCons documentation for more information on what it does)...
+ # in order for this function to be well encapsulated i choose to force it to recieve SCons's TOOLS env (env['ENV']
+ # and not scons setup environment (env)... so make sure you call the right environment on it or it will fail to detect
+ # the propper vc version that will be called
+
+ # These is no flag to give to visual c compilers to set the architecture, ie scons bits argument (32,64,ARM etc)
+ # There are many different cl.exe files that are run, and each one compiles & links to a different architecture
+ # As far as I know, the only way to figure out what compiler will be run when Scons calls cl.exe via Program()
+ # is to check the PATH varaible and figure out which one will be called first. Code bellow does that and returns:
+ # the following string values:
+
+ # "" Compiler not detected
+ # "amd64" Native 64 bit compiler
+ # "amd64_x86" 64 bit Cross Compiler for 32 bit
+ # "x86" Native 32 bit compiler
+ # "x86_amd64" 32 bit Cross Compiler for 64 bit
+
+ # There are other architectures, but Godot does not support them currently, so this function does not detect arm/amd64_arm
+ # and similar architectures/compilers
+
+ # Set chosen compiler to "not detected"
+ vc_chosen_compiler_index = -1
+ vc_chosen_compiler_str = ""
+
+ # find() works with -1 so big ifs bellow are needed... the simplest solution, in fact
+ # First test if amd64 and amd64_x86 compilers are present in the path
+ vc_amd64_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"]+"BIN\\amd64;")
+ if(vc_amd64_compiler_detection_index > -1):
+ vc_chosen_compiler_index = vc_amd64_compiler_detection_index
+ vc_chosen_compiler_str = "amd64"
+
+ vc_amd64_x86_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"]+"BIN\\amd64_x86;")
+ if(vc_amd64_x86_compiler_detection_index > -1
+ and (vc_chosen_compiler_index == -1
+ or vc_chosen_compiler_index > vc_amd64_x86_compiler_detection_index)):
+ vc_chosen_compiler_index = vc_amd64_x86_compiler_detection_index
+ vc_chosen_compiler_str = "amd64_x86"
+
+
+ # Now check the 32 bit compilers
+ vc_x86_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"]+"BIN;")
+ if(vc_x86_compiler_detection_index > -1
+ and (vc_chosen_compiler_index == -1
+ or vc_chosen_compiler_index > vc_x86_compiler_detection_index)):
+ vc_chosen_compiler_index = vc_x86_compiler_detection_index
+ vc_chosen_compiler_str = "x86"
+
+ vc_x86_amd64_compiler_detection_index = tools_env["PATH"].find(tools_env['VCINSTALLDIR']+"BIN\\x86_amd64;")
+ if(vc_x86_amd64_compiler_detection_index > -1
+ and (vc_chosen_compiler_index == -1
+ or vc_chosen_compiler_index > vc_x86_amd64_compiler_detection_index)):
+ vc_chosen_compiler_index = vc_x86_amd64_compiler_detection_index
+ vc_chosen_compiler_str = "x86_amd64"
+
+ # debug help
+ #print vc_amd64_compiler_detection_index
+ #print vc_amd64_x86_compiler_detection_index
+ #print vc_x86_compiler_detection_index
+ #print vc_x86_amd64_compiler_detection_index
+ #print "chosen "+str(vc_chosen_compiler_index)+ " | "+str(vc_chosen_compiler_str)
+
+ return vc_chosen_compiler_str
+
+def precious_program(env, program, sources, **args):
+ program = env.ProgramOriginal(program, sources, **args)
+ env.Precious(program)
+ return program
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 2414cee57e..0548b84cfa 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -90,6 +90,7 @@ import os
import sys
+import methods
def is_active():
return True
@@ -258,7 +259,7 @@ def configure(env):
env['ENV'] = os.environ;
# This detection function needs the tools env (that is env['ENV'], not SCons's env), and that is why it's this far bellow in the code
- compiler_version_str = detect_visual_c_compiler_version(env['ENV'])
+ compiler_version_str = methods.detect_visual_c_compiler_version(env['ENV'])
# Note: this detection/override code from here onward should be here instead of in SConstruct because it's platform and compiler specific (MSVC/Windows)
if(env["bits"] != "default"):
@@ -272,7 +273,7 @@ def configure(env):
# that decide the architecture that is build for. Scons can only detect the os.getenviron (because vsvarsall.bat sets a lot of stuff for cl.exe to work with)
env["bits"]="32"
env["x86_opt_vc"]=True
-
+
print "Detected MSVC compiler: "+compiler_version_str
# If building for 64bit architecture, disable assembly optimisations for 32 bit builds (theora as of writting)... vc compiler for 64bit can not compile _asm
if(compiler_version_str == "amd64" or compiler_version_str == "x86_amd64"):
@@ -282,9 +283,14 @@ def configure(env):
elif (compiler_version_str=="x86" or compiler_version_str == "amd64_x86"):
print "Compiled program architecture will be a 32 bit executable. (forcing bits=32)."
else:
- print "Failed to detect MSVC compiler architecture version... Defaulting to 32bit 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."
+ print "Failed to detect MSVC compiler architecture version... Defaulting to 32bit 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."
if env["bits"]=="64":
env.Append(CCFLAGS=['/D_WIN64'])
+
+ # Incremental linking fix
+ env['BUILDERS']['ProgramOriginal'] = env['BUILDERS']['Program']
+ env['BUILDERS']['Program'] = methods.precious_program
+
else:
# Workaround for MinGW. See:
@@ -379,73 +385,7 @@ def configure(env):
env['is_mingw']=True
env.Append( BUILDERS = { 'RES' : env.Builder(action = build_res_file, suffix = '.o',src_suffix = '.rc') } )
- import methods
env.Append( BUILDERS = { 'GLSL120' : env.Builder(action = methods.build_legacygl_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
env.Append( BUILDERS = { 'GLSL' : env.Builder(action = methods.build_glsl_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
env.Append( BUILDERS = { 'HLSL9' : env.Builder(action = methods.build_hlsl_dx9_headers, suffix = 'hlsl.h',src_suffix = '.hlsl') } )
env.Append( BUILDERS = { 'GLSL120GLES' : env.Builder(action = methods.build_gles2_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
-
-def detect_visual_c_compiler_version(tools_env):
- # tools_env is the variable scons uses to call tools that execute tasks, SCons's env['ENV'] that executes tasks...
- # (see the SCons documentation for more information on what it does)...
- # in order for this function to be well encapsulated i choose to force it to recieve SCons's TOOLS env (env['ENV']
- # and not scons setup environment (env)... so make sure you call the right environment on it or it will fail to detect
- # the propper vc version that will be called
-
- # These is no flag to give to visual c compilers to set the architecture, ie scons bits argument (32,64,ARM etc)
- # There are many different cl.exe files that are run, and each one compiles & links to a different architecture
- # As far as I know, the only way to figure out what compiler will be run when Scons calls cl.exe via Program()
- # is to check the PATH varaible and figure out which one will be called first. Code bellow does that and returns:
- # the following string values:
-
- # "" Compiler not detected
- # "amd64" Native 64 bit compiler
- # "amd64_x86" 64 bit Cross Compiler for 32 bit
- # "x86" Native 32 bit compiler
- # "x86_amd64" 32 bit Cross Compiler for 64 bit
-
- # There are other architectures, but Godot does not support them currently, so this function does not detect arm/amd64_arm
- # and similar architectures/compilers
-
- # Set chosen compiler to "not detected"
- vc_chosen_compiler_index = -1
- vc_chosen_compiler_str = ""
-
- # find() works with -1 so big ifs bellow are needed... the simplest solution, in fact
- # First test if amd64 and amd64_x86 compilers are present in the path
- vc_amd64_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"]+"BIN\\amd64;")
- if(vc_amd64_compiler_detection_index > -1):
- vc_chosen_compiler_index = vc_amd64_compiler_detection_index
- vc_chosen_compiler_str = "amd64"
-
- vc_amd64_x86_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"]+"BIN\\amd64_x86;")
- if(vc_amd64_x86_compiler_detection_index > -1
- and (vc_chosen_compiler_index == -1
- or vc_chosen_compiler_index > vc_amd64_x86_compiler_detection_index)):
- vc_chosen_compiler_index = vc_amd64_x86_compiler_detection_index
- vc_chosen_compiler_str = "amd64_x86"
-
-
- # Now check the 32 bit compilers
- vc_x86_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"]+"BIN;")
- if(vc_x86_compiler_detection_index > -1
- and (vc_chosen_compiler_index == -1
- or vc_chosen_compiler_index > vc_x86_compiler_detection_index)):
- vc_chosen_compiler_index = vc_x86_compiler_detection_index
- vc_chosen_compiler_str = "x86"
-
- vc_x86_amd64_compiler_detection_index = tools_env["PATH"].find(tools_env['VCINSTALLDIR']+"BIN\\x86_amd64;")
- if(vc_x86_amd64_compiler_detection_index > -1
- and (vc_chosen_compiler_index == -1
- or vc_chosen_compiler_index > vc_x86_amd64_compiler_detection_index)):
- vc_chosen_compiler_index = vc_x86_amd64_compiler_detection_index
- vc_chosen_compiler_str = "x86_amd64"
-
- # debug help
- #print vc_amd64_compiler_detection_index
- #print vc_amd64_x86_compiler_detection_index
- #print vc_x86_compiler_detection_index
- #print vc_x86_amd64_compiler_detection_index
- #print "chosen "+str(vc_chosen_compiler_index)+ " | "+str(vc_chosen_compiler_str)
-
- return vc_chosen_compiler_str
diff --git a/platform/winrt/SCsub b/platform/winrt/SCsub
index 2ea8cbd0de..ef7a653d53 100644
--- a/platform/winrt/SCsub
+++ b/platform/winrt/SCsub
@@ -2,10 +2,18 @@ Import('env')
files = [
'thread_winrt.cpp',
-# '#platform/windows/stream_peer_winsock.cpp',
+ '#platform/windows/tcp_server_winsock.cpp',
+ '#platform/windows/packet_peer_udp_winsock.cpp',
+ '#platform/windows/stream_peer_winsock.cpp',
+ '#platform/windows/key_mapping_win.cpp',
+ 'joystick_winrt.cpp',
'gl_context_egl.cpp',
+ 'audio_driver_winrt.cpp',
'app.cpp',
'os_winrt.cpp',
]
-env.Program('#bin/godot', files)
+cmd = env.AlwaysBuild(env.ANGLE('libANGLE.lib', None))
+
+prog = env.Program('#bin/godot', files)
+env.Depends(prog, [cmd])
diff --git a/platform/winrt/app.cpp b/platform/winrt/app.cpp
index ea7619a64b..c2b7ba0641 100644
--- a/platform/winrt/app.cpp
+++ b/platform/winrt/app.cpp
@@ -1,4 +1,32 @@
-//
+/*************************************************************************/
+/* app.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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.
//
@@ -7,17 +35,25 @@
#include "main/main.h"
#include "core/os/dir_access.h"
#include "core/os/file_access.h"
+#include "core/os/keyboard.h"
+
+#include "platform/windows/key_mapping_win.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 Platform;
-using namespace $ext_safeprojectname$;
+using namespace GodotWinRT;
// Helper to convert a length in device-independent pixels (DIPs) to a length in physical pixels.
inline float ConvertDipsToPixels(float dips, float dpi)
@@ -27,7 +63,7 @@ inline float ConvertDipsToPixels(float dips, float dpi)
}
// Implementation of the IFrameworkViewSource interface, necessary to run our app.
-ref class HelloTriangleApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
+ref class GodotWinrtViewSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
{
public:
virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView()
@@ -40,8 +76,8 @@ public:
[Platform::MTAThread]
int main(Platform::Array<Platform::String^>^)
{
- auto helloTriangleApplicationSource = ref new HelloTriangleApplicationSource();
- CoreApplication::Run(helloTriangleApplicationSource);
+ auto godotApplicationSource = ref new GodotWinrtViewSource();
+ CoreApplication::Run(godotApplicationSource);
return 0;
}
@@ -52,7 +88,8 @@ App::App() :
mWindowHeight(0),
mEglDisplay(EGL_NO_DISPLAY),
mEglContext(EGL_NO_CONTEXT),
- mEglSurface(EGL_NO_SURFACE)
+ mEglSurface(EGL_NO_SURFACE),
+ number_of_contacts(0)
{
}
@@ -69,6 +106,7 @@ void App::Initialize(CoreApplicationView^ applicationView)
// http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh994930.aspx
os = new OSWinrt;
+
}
// Called when the CoreWindow object is created (or re-created).
@@ -95,20 +133,31 @@ void App::SetWindow(CoreWindow^ p_window)
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
+ ));
- //window->PointerWheelChanged +=
- // ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &App::OnPointerWheelChanged);
+ 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);
- char* args[] = {"-path", "game", NULL};
- Main::setup("winrt", 2, args, false);
+ unsigned int argc;
+ char** argv = get_command_line(&argc);
+
+ Main::setup("winrt", argc, argv, false);
// The CoreWindow has been created, so EGL can be initialized.
ContextEGL* context = memnew(ContextEGL(window));
@@ -217,7 +266,7 @@ 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) {
+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);
@@ -236,7 +285,7 @@ void App::pointer_event(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core
last_touch_y[event.screen_touch.index] = pos.Y;
os->input_event(event);
- if (event.screen_touch.index != 0)
+ if (number_of_contacts > 1)
return;
}; // fallthrought of sorts
@@ -251,6 +300,14 @@ void App::pointer_event(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core
event.mouse_button.global_x = pos.X;
event.mouse_button.global_y = pos.Y;
+ if (p_is_wheel) {
+ if (point->Properties->MouseWheelDelta > 0) {
+ event.mouse_button.button_index = point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_UP;
+ } else if (point->Properties->MouseWheelDelta < 0) {
+ event.mouse_button.button_index = point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_LEFT : BUTTON_WHEEL_DOWN;
+ }
+ }
+
last_touch_x[31] = pos.X;
last_touch_y[31] = pos.Y;
@@ -260,21 +317,56 @@ void App::pointer_event(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core
void App::OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) {
+ number_of_contacts++;
pointer_event(sender, args, true);
};
void App::OnPointerReleased(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args) {
+ number_of_contacts--;
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)) {
+ if (point->IsInContact && _is_touch(point)) {
InputEvent event;
event.type = InputEvent::SCREEN_DRAG;
@@ -286,11 +378,15 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Cor
event.screen_drag.relative_y = event.screen_drag.y - last_touch_y[event.screen_drag.index];
os->input_event(event);
- if (event.screen_drag.index != 0)
+ if (number_of_contacts > 1)
return;
}; // fallthrought of sorts
+ // In case the mouse grabbed, MouseMoved will handle this
+ if (os->get_mouse_mode() == OS::MouseMode::MOUSE_MODE_CAPTURED)
+ return;
+
InputEvent event;
event.type = InputEvent::MOUSE_MOTION;
event.device = 0;
@@ -301,16 +397,90 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Cor
event.mouse_motion.relative_x = pos.X - last_touch_x[31];
event.mouse_motion.relative_y = pos.Y - last_touch_y[31];
+ last_mouse_pos = pos;
+
os->input_event(event);
-};
+}
+
+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;
+
+ InputEvent event;
+ event.type = InputEvent::MOUSE_MOTION;
+ event.device = 0;
+ event.mouse_motion.x = pos.X;
+ event.mouse_motion.y = pos.Y;
+ event.mouse_motion.global_x = pos.X;
+ event.mouse_motion.global_y = pos.Y;
+ event.mouse_motion.relative_x = args->MouseDelta.X;
+ event.mouse_motion.relative_y = args->MouseDelta.Y;
+
+ last_mouse_pos = pos;
+
+ os->input_event(event);
+}
+
+void App::key_event(Windows::UI::Core::CoreWindow^ sender, bool p_pressed, Windows::UI::Core::KeyEventArgs^ key_args, Windows::UI::Core::CharacterReceivedEventArgs^ char_args)
+{
+
+ OSWinrt::KeyEvent ke;
+
+ InputModifierState mod;
+ mod.meta = false;
+ mod.command = false;
+ mod.control = sender->GetAsyncKeyState(VirtualKey::Control) == CoreVirtualKeyStates::Down;
+ mod.alt = sender->GetAsyncKeyState(VirtualKey::Menu) == CoreVirtualKeyStates::Down;
+ mod.shift = sender->GetAsyncKeyState(VirtualKey::Shift) == CoreVirtualKeyStates::Down;
+ ke.mod_state = mod;
+
+ ke.pressed = p_pressed;
+
+ if (key_args != nullptr) {
+
+ ke.type = OSWinrt::KeyEvent::MessageType::KEY_EVENT_MESSAGE;
+ ke.unicode = 0;
+ ke.scancode = KeyMappingWindows::get_keysym((unsigned int)key_args->VirtualKey);
+ ke.echo = (!p_pressed && !key_args->KeyStatus.IsKeyReleased) || (p_pressed && key_args->KeyStatus.WasKeyDown);
+
+ } else {
+
+ ke.type = OSWinrt::KeyEvent::MessageType::CHAR_EVENT_MESSAGE;
+ ke.unicode = char_args->KeyCode;
+ ke.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)
{
- //char* args[] = {"-test", "render", NULL};
- //Main::setup("winrt", 2, args);
+
}
// This method is called after the window becomes active.
@@ -383,3 +553,95 @@ void App::UpdateWindowSize(Size size)
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.");
+ 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.");
+ 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.");
+ return(fail_cl);
+ }
+
+ int strlen = READ_LE_4(len);
+
+ if (strlen > CMD_MAX_LEN) {
+ fclose(f);
+ wprintf(L"Wrong command length.");
+ 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.");
+ 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;
+}
diff --git a/platform/winrt/app.h b/platform/winrt/app.h
index 25b0d524ae..652ec86e1f 100644
--- a/platform/winrt/app.h
+++ b/platform/winrt/app.h
@@ -1,4 +1,32 @@
-#pragma once
+/*************************************************************************/
+/* app.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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>
@@ -7,7 +35,7 @@
#include "os_winrt.h"
#include "GLES2/gl2.h"
-namespace $ext_safeprojectname$
+namespace GodotWinRT
{
ref class App sealed : public Windows::ApplicationModel::Core::IFrameworkView
{
@@ -21,6 +49,11 @@ namespace $ext_safeprojectname$
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();
@@ -32,16 +65,28 @@ namespace $ext_safeprojectname$
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);
+ 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;
@@ -56,6 +101,8 @@ namespace $ext_safeprojectname$
int last_touch_x[32]; // 20 fingers, index 31 reserved for the mouse
int last_touch_y[32];
+ int number_of_contacts;
+ Windows::Foundation::Point last_mouse_pos;
};
}
diff --git a/platform/winrt/audio_driver_winrt.cpp b/platform/winrt/audio_driver_winrt.cpp
new file mode 100644
index 0000000000..ff46244ac3
--- /dev/null
+++ b/platform/winrt/audio_driver_winrt.cpp
@@ -0,0 +1,244 @@
+/*************************************************************************/
+/* audio_driver_winrt.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 "audio_driver_winrt.h"
+
+#include "globals.h"
+#include "os/os.h"
+
+using namespace Windows::Media;
+using namespace Windows::Media::Core;
+using namespace Windows::Media::MediaProperties;
+using namespace Windows::Media::Editing;
+using namespace Windows::Foundation;
+
+const char * AudioDriverWinRT::get_name() const
+{
+ return "WinRT";
+}
+
+Error AudioDriverWinRT::init() {
+
+ active = false;
+ thread_exited = false;
+ exit_thread = false;
+ pcm_open = false;
+ samples_in = NULL;
+
+
+ mix_rate = 48000;
+ output_format = OUTPUT_STEREO;
+ channels = 2;
+
+ int latency = GLOBAL_DEF("audio/output_latency", 25);
+ buffer_size = nearest_power_of_2(latency * mix_rate / 1000);
+
+ samples_in = memnew_arr(int32_t, buffer_size*channels);
+ for (int i = 0; i < AUDIO_BUFFERS; i++) {
+ samples_out[i] = memnew_arr(int16_t, buffer_size*channels);
+ xaudio_buffer[i].AudioBytes = buffer_size * channels * sizeof(int16_t);
+ xaudio_buffer[i].pAudioData = (const BYTE*)(samples_out[i]);
+ xaudio_buffer[i].Flags = 0;
+ }
+
+ HRESULT hr;
+ hr = XAudio2Create(&xaudio, 0, XAUDIO2_DEFAULT_PROCESSOR);
+ if (hr != S_OK) {
+ ERR_EXPLAIN("Error creating XAudio2 engine.");
+ ERR_FAIL_V(ERR_UNAVAILABLE);
+ }
+ hr = xaudio->CreateMasteringVoice(&mastering_voice);
+ if (hr != S_OK) {
+ ERR_EXPLAIN("Error creating XAudio2 mastering voice.");
+ ERR_FAIL_V(ERR_UNAVAILABLE);
+ }
+
+ wave_format.nChannels = channels;
+ wave_format.cbSize = 0;
+ wave_format.nSamplesPerSec = mix_rate;
+ wave_format.wFormatTag = WAVE_FORMAT_PCM;
+ wave_format.wBitsPerSample = 16;
+ wave_format.nBlockAlign = channels * wave_format.wBitsPerSample >> 3;
+ wave_format.nAvgBytesPerSec = mix_rate * wave_format.nBlockAlign;
+
+ voice_callback = memnew(XAudio2DriverVoiceCallback);
+
+ hr = xaudio->CreateSourceVoice(&source_voice, &wave_format, 0, XAUDIO2_MAX_FREQ_RATIO, voice_callback);
+ if (hr != S_OK) {
+ ERR_EXPLAIN("Error creating XAudio2 source voice. " + itos(hr));
+ ERR_FAIL_V(ERR_UNAVAILABLE);
+ }
+
+ mutex = Mutex::create();
+ thread = Thread::create(AudioDriverWinRT::thread_func, this);
+
+ return OK;
+};
+
+void AudioDriverWinRT::thread_func(void* p_udata) {
+
+ AudioDriverWinRT* ad = (AudioDriverWinRT*)p_udata;
+
+ uint64_t usdelay = (ad->buffer_size / float(ad->mix_rate)) * 1000000;
+
+ while (!ad->exit_thread) {
+
+
+ if (!ad->active) {
+
+ for (int i = 0; i < AUDIO_BUFFERS; i++) {
+ ad->xaudio_buffer[i].Flags = XAUDIO2_END_OF_STREAM;
+ }
+
+ } else {
+
+ ad->lock();
+
+ ad->audio_server_process(ad->buffer_size, ad->samples_in);
+
+ ad->unlock();
+
+ for (unsigned int i = 0;i < ad->buffer_size*ad->channels;i++) {
+
+ ad->samples_out[ad->current_buffer][i] = ad->samples_in[i] >> 16;
+ }
+
+ ad->xaudio_buffer[ad->current_buffer].Flags = 0;
+ ad->xaudio_buffer[ad->current_buffer].AudioBytes = ad->buffer_size * ad->channels * sizeof(int16_t);
+ ad->xaudio_buffer[ad->current_buffer].pAudioData = (const BYTE*)(ad->samples_out[ad->current_buffer]);
+ ad->xaudio_buffer[ad->current_buffer].PlayBegin = 0;
+ ad->source_voice->SubmitSourceBuffer(&(ad->xaudio_buffer[ad->current_buffer]));
+
+ ad->current_buffer = (ad->current_buffer + 1) % AUDIO_BUFFERS;
+
+ XAUDIO2_VOICE_STATE state;
+ while (ad->source_voice->GetState(&state), state.BuffersQueued > AUDIO_BUFFERS - 1)
+ {
+ WaitForSingleObject(ad->voice_callback->buffer_end_event, INFINITE);
+ }
+ }
+
+ };
+
+ ad->thread_exited = true;
+
+};
+
+void AudioDriverWinRT::start() {
+
+ active = true;
+ HRESULT hr = source_voice->Start(0);
+ if (hr != S_OK) {
+ ERR_EXPLAIN("XAudio2 start error " + itos(hr));
+ ERR_FAIL();
+ }
+};
+
+int AudioDriverWinRT::get_mix_rate() const {
+
+ return mix_rate;
+};
+
+AudioDriverSW::OutputFormat AudioDriverWinRT::get_output_format() const {
+
+ return output_format;
+};
+
+float AudioDriverWinRT::get_latency() {
+
+ XAUDIO2_PERFORMANCE_DATA perf_data;
+ xaudio->GetPerformanceData(&perf_data);
+ if (perf_data.CurrentLatencyInSamples) {
+ return (float)(perf_data.CurrentLatencyInSamples / ((float)mix_rate));
+ } else {
+ return 0;
+ }
+}
+
+void AudioDriverWinRT::lock() {
+
+ if (!thread || !mutex)
+ return;
+ mutex->lock();
+};
+void AudioDriverWinRT::unlock() {
+
+ if (!thread || !mutex)
+ return;
+ mutex->unlock();
+};
+
+void AudioDriverWinRT::finish() {
+
+ if (!thread)
+ return;
+
+ exit_thread = true;
+ Thread::wait_to_finish(thread);
+
+ if (source_voice) {
+ source_voice->Stop(0);
+ memdelete(source_voice);
+ }
+
+ if (samples_in) {
+ memdelete_arr(samples_in);
+ };
+ if (samples_out[0]) {
+ for (int i = 0; i < AUDIO_BUFFERS; i++) {
+ memdelete_arr(samples_out[i]);
+ }
+ };
+
+ memdelete(voice_callback);
+ memdelete(mastering_voice);
+
+ memdelete(thread);
+ if (mutex)
+ memdelete(mutex);
+ thread = NULL;
+};
+
+AudioDriverWinRT::AudioDriverWinRT() {
+
+ mutex = NULL;
+ thread = NULL;
+ wave_format = { 0 };
+ for (int i = 0; i < AUDIO_BUFFERS; i++) {
+ xaudio_buffer[i] = { 0 };
+ samples_out[i] = 0;
+ }
+ current_buffer = 0;
+};
+
+AudioDriverWinRT::~AudioDriverWinRT() {
+
+
+};
+
+
diff --git a/platform/winrt/audio_driver_winrt.h b/platform/winrt/audio_driver_winrt.h
new file mode 100644
index 0000000000..d7a69994f8
--- /dev/null
+++ b/platform/winrt/audio_driver_winrt.h
@@ -0,0 +1,109 @@
+/*************************************************************************/
+/* audio_driver_winrt.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 AUDIO_DRIVER_WINRT_H
+#define AUDIO_DRIVER_WINRT_H
+
+#include "servers/audio/audio_server_sw.h"
+
+#include "core/os/thread.h"
+#include "core/os/mutex.h"
+
+#include <windows.h>
+#include <mmsystem.h>
+#include <mmreg.h>
+#include <xaudio2.h>
+#include <wrl/client.h>
+
+class AudioDriverWinRT : public AudioDriverSW {
+
+ enum {
+ AUDIO_BUFFERS = 2
+ };
+
+ struct XAudio2DriverVoiceCallback : public IXAudio2VoiceCallback {
+
+ HANDLE buffer_end_event;
+ XAudio2DriverVoiceCallback() : buffer_end_event(CreateEvent(NULL, FALSE, FALSE, NULL)) {}
+ void STDMETHODCALLTYPE OnBufferEnd(void* pBufferContext) { /*print_line("buffer ended");*/ SetEvent(buffer_end_event); }
+
+ //Unused methods are stubs
+ void STDMETHODCALLTYPE OnStreamEnd() { }
+ void STDMETHODCALLTYPE OnVoiceProcessingPassEnd() { }
+ void STDMETHODCALLTYPE OnVoiceProcessingPassStart(UINT32 SamplesRequired) { }
+ void STDMETHODCALLTYPE OnBufferStart(void * pBufferContext) { }
+ void STDMETHODCALLTYPE OnLoopEnd(void * pBufferContext) { }
+ void STDMETHODCALLTYPE OnVoiceError(void * pBufferContext, HRESULT Error) { }
+
+ };
+
+ Thread* thread;
+ Mutex* mutex;
+
+ int32_t* samples_in;
+ int16_t* samples_out[AUDIO_BUFFERS];
+
+ static void thread_func(void* p_udata);
+ int buffer_size;
+
+ unsigned int mix_rate;
+ OutputFormat output_format;
+
+ int channels;
+
+ bool active;
+ bool thread_exited;
+ mutable bool exit_thread;
+ bool pcm_open;
+
+ WAVEFORMATEX wave_format;
+ Microsoft::WRL::ComPtr<IXAudio2> xaudio;
+ int current_buffer;
+ IXAudio2MasteringVoice* mastering_voice;
+ XAUDIO2_BUFFER xaudio_buffer[AUDIO_BUFFERS];
+ IXAudio2SourceVoice* source_voice;
+ XAudio2DriverVoiceCallback* voice_callback;
+
+public:
+
+ const char* get_name() const;
+
+ virtual Error init();
+ virtual void start();
+ virtual int get_mix_rate() const;
+ virtual OutputFormat get_output_format() const;
+ virtual float get_latency();
+ virtual void lock();
+ virtual void unlock();
+ virtual void finish();
+
+ AudioDriverWinRT();
+ ~AudioDriverWinRT();
+};
+
+#endif
diff --git a/platform/winrt/detect.py b/platform/winrt/detect.py
index 86028d3af8..6ba4cf5cbc 100644
--- a/platform/winrt/detect.py
+++ b/platform/winrt/detect.py
@@ -1,9 +1,8 @@
-
-
import os
import sys
import string
+import methods
def is_active():
@@ -16,6 +15,15 @@ def can_build():
if (os.name=="nt"):
#building natively on windows!
if (os.getenv("VSINSTALLDIR")):
+
+ if (os.getenv("ANGLE_SRC_PATH") == None):
+ print("You need to define ANGLE_SRC_PATH to the path of ANGLE source root.")
+ return False
+
+ if not os.path.isfile(str(os.getenv("ANGLE_SRC_PATH")) + "/winrt/10/src/angle.sln"):
+ print ("Couldn't find the ANGLE solution. Is ANGLE_SRC_PATH configured to the right path?")
+ return False
+
return True
return False
@@ -24,133 +32,136 @@ def get_opts():
def get_flags():
- return []
+ return [
+ ('tools', 'no'),
+ ('openssl', 'builtin'),
+ ]
def configure(env):
- env.Append(CPPPATH=['#platform/winrt', '#platform/winrt/include'])
- arch = ""
-
- if os.getenv('PLATFORM') == "ARM":
-
- # compiler commandline
- # debug: /Yu"pch.h" /MP /GS /analyze- /W3 /wd"4453" /wd"28204" /Zc:wchar_t /I"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\App2\App2.WindowsPhone\" /I"Generated Files\" /I"ARM\Debug\" /I"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\App2\App2.Shared\" /ZW:nostdlib /Zi /Gm- /Od /sdl /Fd"ARM\Debug\vc120.pdb" /fp:precise /D "PSAPI_VERSION=2" /D "WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP" /D "_UITHREADCTXT_SUPPORT=0" /D "_UNICODE" /D "UNICODE" /D "_DEBUG" /errorReport:prompt /WX- /Zc:forScope /RTC1 /ZW /Gd /Oy- /MDd /Fa"ARM\Debug\" /EHsc /nologo /Fo"ARM\Debug\" /Fp"ARM\Debug\App2.WindowsPhone.pch"
- # release: /Yu"pch.h" /MP /GS /GL /analyze- /W3 /wd"4453" /wd"28204" /Gy /Zc:wchar_t /I"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\App2\App2.WindowsPhone\" /I"Generated Files\" /I"ARM\Release\" /I"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\App2\App2.Shared\" /ZW:nostdlib /Zi /Gm- /O2 /sdl /Fd"ARM\Release\vc120.pdb" /fp:precise /D "PSAPI_VERSION=2" /D "WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP" /D "_UITHREADCTXT_SUPPORT=0" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /ZW /Gd /Oy- /Oi /MD /Fa"ARM\Release\" /EHsc /nologo /Fo"ARM\Release\" /Fp"ARM\Release\App2.WindowsPhone.pch"
-
- # linker commandline
- # debug: /OUT:"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\ARM\Debug\App2.WindowsPhone\App2.WindowsPhone.exe" /MANIFEST:NO /NXCOMPAT /PDB:"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\ARM\Debug\App2.WindowsPhone\App2.WindowsPhone.pdb" /DYNAMICBASE "WindowsPhoneCore.lib" "RuntimeObject.lib" "PhoneAppModelHost.lib" /DEBUG /MACHINE:ARM /NODEFAULTLIB:"kernel32.lib" /NODEFAULTLIB:"ole32.lib" /WINMD /APPCONTAINER /INCREMENTAL /PGD:"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\ARM\Debug\App2.WindowsPhone\App2.WindowsPhone.pgd" /WINMDFILE:"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\ARM\Debug\App2.WindowsPhone\App2.winmd" /SUBSYSTEM:WINDOWS /MANIFESTUAC:NO /ManifestFile:"ARM\Debug\App2.WindowsPhone.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /TLBID:1
- # release: /OUT:"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\ARM\Release\App2.WindowsPhone\App2.WindowsPhone.exe" /MANIFEST:NO /LTCG /NXCOMPAT /PDB:"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\ARM\Release\App2.WindowsPhone\App2.WindowsPhone.pdb" /DYNAMICBASE "WindowsPhoneCore.lib" "RuntimeObject.lib" "PhoneAppModelHost.lib" /DEBUG /MACHINE:ARM /NODEFAULTLIB:"kernel32.lib" /NODEFAULTLIB:"ole32.lib" /WINMD /APPCONTAINER /OPT:REF /PGD:"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\ARM\Release\App2.WindowsPhone\App2.WindowsPhone.pgd" /WINMDFILE:"C:\Users\ariel\Documents\Visual Studio 2013\Projects\App2\ARM\Release\App2.WindowsPhone\App2.winmd" /SUBSYSTEM:WINDOWS /MANIFESTUAC:NO /ManifestFile:"ARM\Release\App2.WindowsPhone.exe.intermediate.manifest" /OPT:ICF /ERRORREPORT:PROMPT /NOLOGO /TLBID:1
-
- arch = "arm"
+ 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=winrt) and SCons will attempt to detect what MSVC compiler"
+ +" will be executed and inform you.")
+ sys.exit()
- env.Append(LINKFLAGS=['/INCREMENTAL:NO', '/MANIFEST:NO', '/NXCOMPAT', '/DYNAMICBASE', "WindowsPhoneCore.lib", "RuntimeObject.lib", "PhoneAppModelHost.lib", "/DEBUG", "/MACHINE:ARM", '/NODEFAULTLIB:"kernel32.lib"', '/NODEFAULTLIB:"ole32.lib"', '/WINMD', '/APPCONTAINER', '/MANIFESTUAC:NO', '/ERRORREPORT:PROMPT', '/NOLOGO', '/TLBID:1'])
- env.Append(LIBPATH=['#platform/winrt/ARM/lib'])
-
- env.Append(CCFLAGS=string.split('/MP /GS /wd"4453" /wd"28204" /analyze- /Zc:wchar_t /Zi /Gm- /Od /fp:precise /fp:precise /D "PSAPI_VERSION=2" /D "WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP" /DWINDOWSPHONE_ENABLED /D "_UITHREADCTXT_SUPPORT=0" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oy- /Oi /MD /RTC1 /Gd /EHsc /nologo'))
- env.Append(CXXFLAGS=string.split('/ZW'))
+ arch = ""
+ env['ENV'] = os.environ;
- if (env["target"]=="release"):
+ # ANGLE
+ angle_root = os.getenv("ANGLE_SRC_PATH")
+ env.Append(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="
- env.Append(CCFLAGS=['/O2'])
- env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS'])
+ if os.getenv('Platform') == "ARM":
- elif (env["target"]=="test"):
+ print "Compiled program architecture will be an ARM executable. (forcing bits=32)."
- env.Append(CCFLAGS=['/O2','/DDEBUG_ENABLED','/DD3D_DEBUG_INFO'])
- env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
+ arch="arm"
+ env["bits"]="32"
+ env.Append(LINKFLAGS=['/MACHINE:ARM'])
+ env.Append(LIBPATH=[os.environ['VCINSTALLDIR'] + 'lib/store/arm'])
- elif (env["target"]=="debug"):
+ angle_build_cmd += "ARM"
- env.Append(CCFLAGS=['/Zi','/DDEBUG_ENABLED','/DD3D_DEBUG_INFO'])
- env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
- env.Append(LINKFLAGS=['/DEBUG', '/D_DEBUG'])
+ env.Append(LIBPATH=[angle_root + '/winrt/10/src/Release_ARM/lib'])
- elif (env["target"]=="profile"):
+ else:
- env.Append(CCFLAGS=['-g','-pg'])
- env.Append(LINKFLAGS=['-pg'])
+ 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 32bit 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"
- env['ENV'] = os.environ;
- # fix environment for windows phone 8.1
- env['ENV']['WINDOWSPHONEKITDIR'] = env['ENV']['WINDOWSPHONEKITDIR'].replace("8.0", "8.1") # wtf
- env['ENV']['INCLUDE'] = env['ENV']['INCLUDE'].replace("8.0", "8.1")
- env['ENV']['LIB'] = env['ENV']['LIB'].replace("8.0", "8.1")
- env['ENV']['PATH'] = env['ENV']['PATH'].replace("8.0", "8.1")
- env['ENV']['LIBPATH'] = env['ENV']['LIBPATH'].replace("8.0\\Windows Metadata", "8.1\\References\\CommonConfiguration\\Neutral")
+ if (env["bits"] == "32"):
+ arch = "x86"
- else:
+ angle_build_cmd += "Win32"
- arch = "x64"
- env.Append(LINKFLAGS=['/MANIFEST:NO', '/NXCOMPAT', '/DYNAMICBASE', "kernel32.lib", '/MACHINE:X64', '/WINMD', '/APPCONTAINER', '/MANIFESTUAC:NO', '/ERRORREPORT:PROMPT', '/NOLOGO', '/TLBID:1'])
+ env.Append(CPPFLAGS=['/DPNG_ABORT=abort'])
+ env.Append(LINKFLAGS=['/MACHINE:X86'])
+ env.Append(LIBPATH=[os.environ['VCINSTALLDIR'] + 'lib/store'])
+ env.Append(LIBPATH=[angle_root + '/winrt/10/src/Release_Win32/lib'])
- env.Append(LIBPATH=['#platform/winrt/x64/lib'])
+ else:
+ arch = "x64"
+ angle_build_cmd += "x64"
- if (env["target"]=="release"):
+ 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.Append(CCFLAGS=['/O2'])
- env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS'])
- env.Append(LINKFLAGS=['/ENTRY:mainCRTStartup'])
+ env.Append(CPPPATH=['#platform/winrt','#drivers/windows'])
+ env.Append(LINKFLAGS=['/MANIFEST:NO', '/NXCOMPAT', '/DYNAMICBASE', '/WINMD', '/APPCONTAINER', '/ERRORREPORT:PROMPT', '/NOLOGO', '/TLBID:1', '/NODEFAULTLIB:"kernel32.lib"', '/NODEFAULTLIB:"ole32.lib"'])
+ env.Append(CPPFLAGS=['/D','__WRL_NO_DEFAULT_LIB__','/D','WIN32'])
+ env.Append(CPPFLAGS=['/FU', os.environ['VCINSTALLDIR'] + 'lib/store/references/platform.winmd'])
+ env.Append(CPPFLAGS=['/AI', os.environ['VCINSTALLDIR'] + 'lib/store/references'])
- elif (env["target"]=="test"):
+ env.Append(LIBPATH=[os.environ['VCINSTALLDIR'] + 'lib/store/references'])
- env.Append(CCFLAGS=['/O2','/DDEBUG_ENABLED','/DD3D_DEBUG_INFO'])
- env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
+ if (env["target"]=="release"):
- elif (env["target"]=="debug"):
+ env.Append(CPPFLAGS=['/O2', '/GL'])
+ env.Append(CPPFLAGS=['/MD'])
+ env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS', '/LTCG'])
- env.Append(CCFLAGS=['/Zi','/DDEBUG_ENABLED','/DD3D_DEBUG_INFO'])
- env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
- env.Append(LINKFLAGS=['/DEBUG', '/D_DEBUG'])
+ elif (env["target"]=="release_debug"):
- elif (env["target"]=="profile"):
+ env.Append(CCFLAGS=['/O2','/Zi','/DDEBUG_ENABLED'])
+ env.Append(CPPFLAGS=['/MD'])
+ env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
- env.Append(CCFLAGS=['-g','-pg'])
- env.Append(LINKFLAGS=['-pg'])
+ elif (env["target"]=="debug"):
+ env.Append(CCFLAGS=['/Zi','/DDEBUG_ENABLED','/DDEBUG_MEMORY_ENABLED'])
+ env.Append(CPPFLAGS=['/MDd'])
+ env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
+ env.Append(LINKFLAGS=['/DEBUG'])
- env.Append(CCFLAGS=string.split('/MP /GS /wd"4453" /wd"28204" /Zc:wchar_t /Gm- /Od /fp:precise /D "_UNICODE" /D "UNICODE" /D "WINAPI_FAMILY=WINAPI_FAMILY_APP" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /EHsc /nologo'))
- env.Append(CXXFLAGS=string.split('/ZW'))
- env.Append(CCFLAGS=['/AI', os.environ['VCINSTALLDIR']+'\\vcpackages', '/AI', os.environ['WINDOWSSDKDIR']+'\\References\\CommonConfiguration\\Neutral'])
- env.Append(CCFLAGS=['/DWINAPI_FAMILY=WINAPI_FAMILY_APP', '/D_WIN32_WINNT=0x0603', '/DNTDDI_VERSION=0x06030000'])
- env['ENV'] = os.environ;
+ env.Append(CCFLAGS=string.split('/FS /MP /GS /wd"4453" /wd"28204" /wd"4291" /Zc:wchar_t /Gm- /fp:precise /D "_UNICODE" /D "UNICODE" /D "WINAPI_FAMILY=WINAPI_FAMILY_APP" /errorReport:prompt /WX- /Zc:forScope /Gd /EHsc /nologo'))
+ env.Append(CXXFLAGS=string.split('/ZW /FS'))
+ env.Append(CCFLAGS=['/AI', os.environ['VCINSTALLDIR']+'\\vcpackages', '/AI', os.environ['WINDOWSSDKDIR']+'\\References\\CommonConfiguration\\Neutral'])
env["PROGSUFFIX"]="."+arch+env["PROGSUFFIX"]
env["OBJSUFFIX"]="."+arch+env["OBJSUFFIX"]
env["LIBSUFFIX"]="."+arch+env["LIBSUFFIX"]
-
- #env.Append(CCFLAGS=['/Gd','/GR','/nologo', '/EHsc'])
- #env.Append(CXXFLAGS=['/TP', '/ZW'])
- #env.Append(CPPFLAGS=['/DMSVC', '/GR', ])
- ##env.Append(CCFLAGS=['/I'+os.getenv("WindowsSdkDir")+"/Include"])
env.Append(CCFLAGS=['/DWINRT_ENABLED'])
env.Append(CCFLAGS=['/DWINDOWS_ENABLED'])
- env.Append(CCFLAGS=['/DRTAUDIO_ENABLED'])
- #env.Append(CCFLAGS=['/DWIN32'])
env.Append(CCFLAGS=['/DTYPED_METHOD_BIND'])
- env.Append(CCFLAGS=['/DGLES2_ENABLED'])
- #env.Append(CCFLAGS=['/DGLES1_ENABLED'])
+ env.Append(CCFLAGS=['/DGLES2_ENABLED','/DGL_GLEXT_PROTOTYPES','/DEGL_EGLEXT_PROTOTYPES','/DANGLE_ENABLED'])
- LIBS=[
- #'winmm',
+ LIBS = [
+ 'xaudio2',
+ 'WindowsApp',
+ 'mincore',
+ 'libANGLE',
'libEGL',
'libGLESv2',
- 'libANGLE',
- #'kernel32','ole32','user32', 'advapi32'
]
env.Append(LINKFLAGS=[p+".lib" for p in LIBS])
- import methods
+ # 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) } )
+
env.Append( BUILDERS = { 'GLSL120' : env.Builder(action = methods.build_legacygl_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
env.Append( BUILDERS = { 'GLSL' : env.Builder(action = methods.build_glsl_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
env.Append( BUILDERS = { 'HLSL9' : env.Builder(action = methods.build_hlsl_dx9_headers, suffix = 'hlsl.h',src_suffix = '.hlsl') } )
env.Append( BUILDERS = { 'GLSL120GLES' : env.Builder(action = methods.build_gles2_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
-
-
-#/c/Program Files (x86)/Windows Phone Kits/8.1/lib/ARM/WindowsPhoneCore.lib
diff --git a/platform/winrt/gl_context_egl.cpp b/platform/winrt/gl_context_egl.cpp
index 12ccd404a9..f7b514b3c0 100644
--- a/platform/winrt/gl_context_egl.cpp
+++ b/platform/winrt/gl_context_egl.cpp
@@ -103,9 +103,22 @@ Error ContextEGL::initialize() {
const EGLint displayAttributes[] =
{
- EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
+ /*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,
};
diff --git a/platform/winrt/gl_context_egl.h b/platform/winrt/gl_context_egl.h
index 68dcdd5035..8124c2903d 100644
--- a/platform/winrt/gl_context_egl.h
+++ b/platform/winrt/gl_context_egl.h
@@ -49,6 +49,8 @@ class ContextEGL : public ContextGL {
EGLint width;
EGLint height;
+ bool vsync;
+
public:
virtual void release_current();
@@ -59,6 +61,9 @@ public:
virtual int get_window_height();
virtual void swap_buffers();
+ void set_use_vsync(bool use) { vsync = use; }
+ bool is_using_vsync() const { return vsync; }
+
virtual Error initialize();
void reset();
diff --git a/platform/winrt/joystick_winrt.cpp b/platform/winrt/joystick_winrt.cpp
new file mode 100644
index 0000000000..4816e9c831
--- /dev/null
+++ b/platform/winrt/joystick_winrt.cpp
@@ -0,0 +1,146 @@
+/*************************************************************************/
+/* joystick.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 "joystick_winrt.h"
+
+using namespace Windows::Gaming::Input;
+using namespace Windows::Foundation;
+
+void JoystickWinrt::register_events() {
+
+ Gamepad::GamepadAdded +=
+ ref new EventHandler<Gamepad^>(this, &JoystickWinrt::OnGamepadAdded);
+ Gamepad::GamepadRemoved +=
+ ref new EventHandler<Gamepad^>(this, &JoystickWinrt::OnGamepadRemoved);
+}
+
+uint32_t JoystickWinrt::process_controllers(uint32_t p_last_id) {
+
+ for (int i = 0; i < MAX_CONTROLLERS; i++) {
+
+ if (!controllers[i].connected) break;
+
+ switch (controllers[i].type) {
+
+ case ControllerType::GAMEPAD_CONTROLLER: {
+
+ GamepadReading reading = ((Gamepad^)controllers[i].controller_reference)->GetCurrentReading();
+
+ int button_mask = (int)GamepadButtons::Menu;
+ for (int j = 0; j < 14; j++) {
+
+ p_last_id = input->joy_button(p_last_id, controllers[i].id, j,(int)reading.Buttons & button_mask);
+ button_mask *= 2;
+ }
+
+ p_last_id = input->joy_axis(p_last_id, controllers[i].id, JOY_AXIS_0, axis_correct(reading.LeftThumbstickX));
+ p_last_id = input->joy_axis(p_last_id, controllers[i].id, JOY_AXIS_1, axis_correct(reading.LeftThumbstickY, true));
+ p_last_id = input->joy_axis(p_last_id, controllers[i].id, JOY_AXIS_2, axis_correct(reading.RightThumbstickX));
+ p_last_id = input->joy_axis(p_last_id, controllers[i].id, JOY_AXIS_3, axis_correct(reading.RightThumbstickY, true));
+ p_last_id = input->joy_axis(p_last_id, controllers[i].id, JOY_AXIS_4, axis_correct(reading.LeftTrigger, false, true));
+ p_last_id = input->joy_axis(p_last_id, controllers[i].id, JOY_AXIS_5, axis_correct(reading.RightTrigger, false, true));
+
+ break;
+ }
+ }
+ }
+
+ return p_last_id;
+}
+
+JoystickWinrt::JoystickWinrt() {
+
+ for (int i = 0; i < MAX_CONTROLLERS; i++)
+ controllers[i].id = i;
+}
+
+JoystickWinrt::JoystickWinrt(InputDefault * p_input) {
+
+ input = p_input;
+
+ JoystickWinrt();
+}
+
+void JoystickWinrt::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].type = ControllerType::GAMEPAD_CONTROLLER;
+
+ input->joy_connection_changed(idx, true, "Xbox Controller", "__WINRT_GAMEPAD__");
+}
+
+void JoystickWinrt::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);
+
+ for (int i = idx + 1; i < MAX_CONTROLLERS - 1; i++) {
+
+ if (!controllers[i].connected) {
+ break;
+ }
+
+ controllers[i - 1] = controllers[i];
+ }
+ controllers[MAX_CONTROLLERS - 1] = ControllerDevice();
+
+ input->joy_connection_changed(idx, false, "Xbox Controller");
+}
+
+InputDefault::JoyAxis JoystickWinrt::axis_correct(double p_val, bool p_negate, bool p_trigger) const {
+
+ InputDefault::JoyAxis jx;
+
+ jx.min = p_trigger ? 0 : -1;
+ jx.value = (float)(p_negate ? -p_val : p_val);
+
+ return jx;
+}
diff --git a/platform/winrt/joystick_winrt.h b/platform/winrt/joystick_winrt.h
new file mode 100644
index 0000000000..17f9565708
--- /dev/null
+++ b/platform/winrt/joystick_winrt.h
@@ -0,0 +1,81 @@
+/*************************************************************************/
+/* joystick.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 JOYSTICK_WINRT_H
+#define JOYSTICK_WINRT_H
+
+#include "main/input_default.h"
+
+ref class JoystickWinrt sealed {
+
+internal:
+
+ void register_events();
+ uint32_t process_controllers(uint32_t p_last_id);
+
+ JoystickWinrt();
+ JoystickWinrt(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;
+
+ ControllerDevice() {
+ id = -1;
+ connected = false;
+ type = ControllerType::GAMEPAD_CONTROLLER;
+ }
+ };
+
+ 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);
+
+ InputDefault::JoyAxis axis_correct(double p_val, bool p_negate = false, bool p_trigger = false) const;
+};
+
+#endif
diff --git a/platform/winrt/os_winrt.cpp b/platform/winrt/os_winrt.cpp
index f045f54bf6..0ce561f88a 100644
--- a/platform/winrt/os_winrt.cpp
+++ b/platform/winrt/os_winrt.cpp
@@ -32,7 +32,7 @@
#include "drivers/unix/memory_pool_static_malloc.h"
#include "os/memory_pool_dynamic_static.h"
#include "thread_winrt.h"
-//#include "drivers/windows/semaphore_windows.h"
+#include "drivers/windows/semaphore_windows.h"
#include "drivers/windows/mutex_windows.h"
#include "main/main.h"
#include "drivers/windows/file_access_windows.h"
@@ -47,15 +47,27 @@
#include "globals.h"
#include "io/marshalls.h"
+#include "platform/windows/packet_peer_udp_winsock.h"
+#include "platform/windows/stream_peer_winsock.h"
+#include "platform/windows/tcp_server_winsock.h"
+#include "drivers/unix/ip_unix.h"
+
#include <wrl.h>
+#include <ppltasks.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 OSWinrt::get_video_driver_count() const {
@@ -72,6 +84,66 @@ OS::VideoMode OSWinrt::get_default_video_mode() const {
return video_mode;
}
+Size2 OSWinrt::get_window_size() const {
+ Size2 size;
+ size.width = video_mode.width;
+ size.height = video_mode.height;
+ return size;
+}
+
+void OSWinrt::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 OSWinrt::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 OSWinrt::is_window_fullscreen() const {
+
+ return ApplicationView::GetForCurrentView()->IsFullScreenMode;
+}
+
+void OSWinrt::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);
+}
+
int OSWinrt::get_audio_driver_count() const {
return AudioDriverManagerSW::get_driver_count();
@@ -94,7 +166,7 @@ void OSWinrt::initialize_core() {
//RedirectIOToConsole();
ThreadWinrt::make_default();
- //SemaphoreWindows::make_default();
+ SemaphoreWindows::make_default();
MutexWindows::make_default();
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
@@ -108,6 +180,10 @@ void OSWinrt::initialize_core() {
//TCPServerWinsock::make_default();
//StreamPeerWinsock::make_default();
+ TCPServerWinsock::make_default();
+ StreamPeerWinsock::make_default();
+ PacketPeerUDPWinsock::make_default();
+
mempool_static = new MemoryPoolStaticMalloc;
#if 1
mempool_dynamic = memnew( MemoryPoolDynamicStatic );
@@ -126,6 +202,8 @@ void OSWinrt::initialize_core() {
ticks_start = 0;
ticks_start = get_ticks_usec();
+ IP_Unix::make_default();
+
cursor_shape=CURSOR_ARROW;
}
@@ -154,9 +232,38 @@ void OSWinrt::initialize(const VideoMode& p_desired,int p_video_driver,int p_aud
VideoMode vm;
vm.width = gl_context->get_window_width();
vm.height = gl_context->get_window_height();
- vm.fullscreen = true;
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);
gl_context->make_current();
@@ -179,6 +286,9 @@ void OSWinrt::initialize(const VideoMode& p_desired,int p_video_driver,int p_aud
input = memnew( InputDefault );
+ joystick = ref new JoystickWinrt(input);
+ joystick->register_events();
+
AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton();
if (AudioDriverManagerSW::get_driver(p_audio_driver)->init()!=OK) {
@@ -196,96 +306,77 @@ void OSWinrt::initialize(const VideoMode& p_desired,int p_video_driver,int p_aud
spatial_sound_2d_server = memnew( SpatialSound2DServerSW );
spatial_sound_2d_server->init();
+ managed_object->update_clipboard();
- _ensure_data_dir();
-}
-
-void OSWinrt::set_clipboard(const String& p_text) {
-
- /*
- if (!OpenClipboard(hWnd)) {
- ERR_EXPLAIN("Unable to open clipboard.");
- ERR_FAIL();
- };
- EmptyClipboard();
-
- HGLOBAL mem = GlobalAlloc(GMEM_MOVEABLE, (p_text.length() + 1) * sizeof(CharType));
- if (mem == NULL) {
- ERR_EXPLAIN("Unable to allocate memory for clipboard contents.");
- ERR_FAIL();
- };
- LPWSTR lptstrCopy = (LPWSTR)GlobalLock(mem);
- memcpy(lptstrCopy, p_text.c_str(), (p_text.length() + 1) * sizeof(CharType));
- //memset((lptstrCopy + p_text.length()), 0, sizeof(CharType));
- GlobalUnlock(mem);
-
- SetClipboardData(CF_UNICODETEXT, mem);
-
- // set the CF_TEXT version (not needed?)
- CharString utf8 = p_text.utf8();
- mem = GlobalAlloc(GMEM_MOVEABLE, utf8.length() + 1);
- if (mem == NULL) {
- ERR_EXPLAIN("Unable to allocate memory for clipboard contents.");
- ERR_FAIL();
- };
- LPTSTR ptr = (LPTSTR)GlobalLock(mem);
- memcpy(ptr, utf8.get_data(), utf8.length());
- ptr[utf8.length()] = 0;
- GlobalUnlock(mem);
-
- SetClipboardData(CF_TEXT, mem);
-
- CloseClipboard();
- */
-};
+ Clipboard::ContentChanged += ref new EventHandler<Platform::Object^>(managed_object, &ManagedType::on_clipboard_changed);
-String OSWinrt::get_clipboard() const {
+ 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);
+ }
- /*
- String ret;
- if (!OpenClipboard(hWnd)) {
- ERR_EXPLAIN("Unable to open clipboard.");
- ERR_FAIL_V("");
- };
+ 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);
+ }
- if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
+ 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);
+ }
- HGLOBAL mem = GetClipboardData(CF_UNICODETEXT);
- if (mem != NULL) {
+ _ensure_data_dir();
- LPWSTR ptr = (LPWSTR)GlobalLock(mem);
- if (ptr != NULL) {
+ if (is_keep_screen_on())
+ display_request->RequestActive();
- ret = String((CharType*)ptr);
- GlobalUnlock(mem);
- };
- };
+ set_keep_screen_on(GLOBAL_DEF("display/keep_screen_on", true));
- } else if (IsClipboardFormatAvailable(CF_TEXT)) {
+}
- HGLOBAL mem = GetClipboardData(CF_UNICODETEXT);
- if (mem != NULL) {
+void OSWinrt::set_clipboard(const String& p_text) {
- LPTSTR ptr = (LPTSTR)GlobalLock(mem);
- if (ptr != NULL) {
+ DataPackage^ clip = ref new DataPackage();
+ clip->RequestedOperation = DataPackageOperation::Copy;
+ clip->SetText(ref new Platform::String((const wchar_t*)p_text.c_str()));
- ret.parse_utf8((const char*)ptr);
- GlobalUnlock(mem);
- };
- };
- };
+ Clipboard::SetContent(clip);
+};
- CloseClipboard();
+String OSWinrt::get_clipboard() const {
- return ret;
- */
- return "";
+ if (managed_object->clipboard != nullptr)
+ return managed_object->clipboard->Data();
+ else
+ return "";
};
void OSWinrt::input_event(InputEvent &p_event) {
+
p_event.ID = ++last_id;
+
input->parse_input_event(p_event);
+
+ if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed && p_event.mouse_button.button_index>3) {
+
+ //send release for mouse wheel
+ p_event.mouse_button.pressed = false;
+ p_event.ID = ++last_id;
+ input->parse_input_event(p_event);
+ }
};
void OSWinrt::delete_main_loop() {
@@ -339,6 +430,8 @@ void OSWinrt::finalize() {
physics_2d_server->finish();
memdelete(physics_2d_server);
+ joystick = nullptr;
+
}
void OSWinrt::finalize_core() {
@@ -370,9 +463,6 @@ void OSWinrt::vprint(const char* p_format, va_list p_list, bool p_stderr) {
else
wprintf(L"%s",wbuf);
-#ifdef STDOUT_FILE
- //vwfprintf(stdo,p_format,p_list);
-#endif
free(wbuf);
fflush(stdout);
@@ -380,11 +470,101 @@ void OSWinrt::vprint(const char* p_format, va_list p_list, bool p_stderr) {
void OSWinrt::alert(const String& p_alert,const String& p_title) {
- print_line("ALERT: "+p_alert);
+ 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, &OSWinrt::ManagedType::alert_close));
+ msg->Commands->Append(close);
+ msg->DefaultCommandIndex = 0;
+
+ managed_object->alert_close_handle = true;
+
+ msg->ShowAsync();
+}
+
+void OSWinrt::ManagedType::alert_close(IUICommand^ command) {
+
+ alert_close_handle = false;
+}
+
+void OSWinrt::ManagedType::on_clipboard_changed(Platform::Object ^ sender, Platform::Object ^ ev) {
+
+ update_clipboard();
+}
+
+void OSWinrt::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 OSWinrt::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 OSWinrt::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 OSWinrt::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 OSWinrt::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);
}
OSWinrt::MouseMode OSWinrt::get_mouse_mode() const{
@@ -482,7 +662,7 @@ OS::Time OSWinrt::get_time(bool utc) const {
return time;
}
-OS::TimeZoneInfo OS_Windows::get_time_zone_info() const {
+OS::TimeZoneInfo OSWinrt::get_time_zone_info() const {
TIME_ZONE_INFORMATION info;
bool daylight = false;
if (GetTimeZoneInformation(&info) == TIME_ZONE_ID_DAYLIGHT)
@@ -503,7 +683,7 @@ uint64_t OSWinrt::get_unix_time() const {
FILETIME ft;
SYSTEMTIME st;
- GetSystemTime(&systemtime);
+ GetSystemTime(&st);
SystemTimeToFileTime(&st, &ft);
SYSTEMTIME ep;
@@ -546,10 +726,79 @@ uint64_t OSWinrt::get_ticks_usec() const {
void OSWinrt::process_events() {
+ last_id = joystick->process_controllers(last_id);
+ process_key_events();
+}
+
+void OSWinrt::process_key_events()
+{
+
+ for (int i = 0; i < key_event_pos; i++) {
+
+ KeyEvent &kev = key_event_buffer[i];
+ InputEvent iev;
+
+ iev.type = InputEvent::KEY;
+ iev.key.mod = kev.mod_state;
+ iev.key.echo = kev.echo;
+ iev.key.scancode = kev.scancode;
+ iev.key.unicode = kev.unicode;
+ iev.key.pressed = kev.pressed;
+
+ input_event(iev);
+
+ }
+ key_event_pos = 0;
+}
+
+void OSWinrt::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 OSWinrt::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;
}
Error OSWinrt::execute(const String& p_path, const List<String>& p_arguments,bool p_blocking,ProcessID *r_child_id,String* r_pipe,int *r_exitcode) {
@@ -609,7 +858,7 @@ String OSWinrt::get_locale() const {
return "en";
#else
Platform::String ^language = Windows::Globalization::Language::CurrentInputMethodLanguageTag;
- return language->Data();
+ return String(language->Data()).replace("-", "_");
#endif
}
@@ -628,6 +877,29 @@ void OSWinrt::swap_buffers() {
gl_context->swap_buffers();
}
+bool OSWinrt::has_touchscreen_ui_hint() const {
+
+ TouchCapabilities^ tc = ref new TouchCapabilities();
+ return tc->TouchPresent != 0 || UIViewSettings::GetForCurrentView()->UserInteractionMode == UserInteractionMode::Touch;
+}
+
+bool OSWinrt::has_virtual_keyboard() const {
+
+ return UIViewSettings::GetForCurrentView()->UserInteractionMode == UserInteractionMode::Touch;
+}
+
+void OSWinrt::show_virtual_keyboard(const String & p_existing_text, const Rect2 & p_screen_rect) {
+
+ InputPane^ pane = InputPane::GetForCurrentView();
+ pane->TryShow();
+}
+
+void OSWinrt::hide_virtual_keyboard() {
+
+ InputPane^ pane = InputPane::GetForCurrentView();
+ pane->TryHide();
+}
+
void OSWinrt::run() {
@@ -644,6 +916,7 @@ void OSWinrt::run() {
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()==true)
break;
@@ -665,7 +938,7 @@ String OSWinrt::get_data_dir() const {
Windows::Storage::StorageFolder ^data_folder = Windows::Storage::ApplicationData::Current->LocalFolder;
- return data_folder->Path->Data();
+ return String(data_folder->Path->Data()).replace("\\", "/");
}
@@ -690,6 +963,13 @@ OSWinrt::OSWinrt() {
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");
+
AudioDriverManagerSW::add_driver(&audio_driver);
}
diff --git a/platform/winrt/os_winrt.h b/platform/winrt/os_winrt.h
index 145ccf0f7a..1816e0cec7 100644
--- a/platform/winrt/os_winrt.h
+++ b/platform/winrt/os_winrt.h
@@ -40,10 +40,13 @@
#include "servers/spatial_sound/spatial_sound_server_sw.h"
#include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h"
#include "servers/physics_2d/physics_2d_server_sw.h"
-#include "servers/audio/audio_driver_dummy.h"
+#include "audio_driver_winrt.h"
#include "gl_context_egl.h"
+#include "core/math/math_2d.h"
+#include "core/ustring.h"
+
#include <windows.h>
#include <io.h>
@@ -52,11 +55,35 @@
#include <stdio.h>
#include "main/input_default.h"
+#include "joystick_winrt.h"
+
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
class OSWinrt : public OS {
+public:
+
+ struct KeyEvent {
+
+ enum MessageType
+ {
+ KEY_EVENT_MESSAGE,
+ CHAR_EVENT_MESSAGE
+ };
+
+ InputModifierState mod_state;
+ MessageType type;
+ bool pressed;
+ unsigned int scancode;
+ unsigned int unicode;
+ bool echo;
+ CorePhysicalKeyStatus status;
+
+ };
+
+private:
+
enum {
JOYSTICKS_MAX = 8,
JOY_AXIS_COUNT = 6,
@@ -66,16 +93,6 @@ class OSWinrt : public OS {
FILE *stdo;
-
- struct KeyEvent {
-
- InputModifierState mod_state;
- UINT uMsg;
- WPARAM wParam;
- LPARAM lParam;
-
- };
-
KeyEvent key_event_buffer[KEY_EVENT_BUFFER_SIZE];
int key_event_pos;
@@ -97,37 +114,11 @@ class OSWinrt : public OS {
ContextEGL* gl_context;
- struct Joystick {
-
- int id;
- bool attached;
-
- DWORD last_axis[JOY_AXIS_COUNT];
- DWORD last_buttons;
- DWORD last_pov;
- String name;
-
- Joystick() {
- id = -1;
- attached = false;
- for (int i=0; i<JOY_AXIS_COUNT; i++) {
-
- last_axis[i] = 0;
- };
- last_buttons = 0;
- last_pov = 0;
- };
- };
-
- List<Joystick> joystick_change_queue;
- int joystick_count;
- Joystick joysticks[JOYSTICKS_MAX];
-
VideoMode video_mode;
MainLoop *main_loop;
- AudioDriverDummy audio_driver;
+ AudioDriverWinRT audio_driver;
AudioServerSW *audio_server;
SampleManagerMallocSW *sample_manager;
SpatialSoundServerSW *spatial_sound_server;
@@ -146,11 +137,34 @@ class OSWinrt : public OS {
InputDefault *input;
+ JoystickWinrt^ joystick;
+
+ Windows::System::Display::DisplayRequest^ display_request;
+
void _post_dpad(DWORD p_dpad, int p_device, bool p_pressed);
void _drag_event(int idx,UINT uMsg, WPARAM wParam, LPARAM lParam);
void _touch_event(int idx, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ 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);
+
+ internal:
+ ManagedType() { alert_close_handle = false; }
+ property OSWinrt* os;
+ };
+ ManagedType^ managed_object;
+ Windows::Devices::Sensors::Accelerometer^ accelerometer;
+ Windows::Devices::Sensors::Magnetometer^ magnetometer;
+ Windows::Devices::Sensors::Gyrometer^ gyrometer;
// functions used by main to initialize/deintialize the OS
protected:
@@ -173,12 +187,13 @@ protected:
void process_events();
- void probe_joysticks();
- void process_joysticks();
void process_key_events();
public:
+ // Event to send to the app wrapper
+ HANDLE mouse_mode_changed;
+
void print_error(const char* p_function,const char* p_file,int p_line,const char *p_code,const char*p_rationale,ErrorType p_type);
virtual void vprint(const char *p_format, va_list p_list, bool p_stderr=false);
@@ -195,6 +210,11 @@ public:
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;
@@ -237,7 +257,11 @@ public:
virtual void make_rendering_thread();
virtual void swap_buffers();
- virtual bool has_touchscreen_ui_hint() const { return true; };
+ 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());
+ virtual void hide_virtual_keyboard();
virtual Error shell_open(String p_uri);
@@ -247,6 +271,8 @@ public:
void input_event(InputEvent &p_event);
+ void queue_key_event(KeyEvent &p_event);
+
OSWinrt();
~OSWinrt();
diff --git a/platform/winrt/thread_winrt.cpp b/platform/winrt/thread_winrt.cpp
index e7028bd9dc..8e3e0d5bef 100644
--- a/platform/winrt/thread_winrt.cpp
+++ b/platform/winrt/thread_winrt.cpp
@@ -59,7 +59,9 @@ Thread::ID ThreadWinrt::get_ID() const {
};
void ThreadWinrt::make_default() {
-
+ create_func = create_func_winrt;
+ get_thread_ID_func = get_thread_ID_func_winrt;
+ wait_to_finish_func = wait_to_finish_func_winrt;
};
ThreadWinrt::ThreadWinrt() {