summaryrefslogtreecommitdiff
path: root/platform/windows
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2014-02-09 22:10:30 -0300
committerJuan Linietsky <reduzio@gmail.com>2014-02-09 22:10:30 -0300
commit0b806ee0fc9097fa7bda7ac0109191c9c5e0a1ac (patch)
tree276c4d099e178eb67fbd14f61d77b05e3808e9e3 /platform/windows
parent0e49da1687bc8192ed210947da52c9e5c5f301bb (diff)
GODOT IS OPEN SOURCE
Diffstat (limited to 'platform/windows')
-rw-r--r--platform/windows/SCsub13
-rw-r--r--platform/windows/context_gl_win.cpp205
-rw-r--r--platform/windows/context_gl_win.h79
-rw-r--r--platform/windows/ctxgl_procaddr.cpp186
-rw-r--r--platform/windows/ctxgl_procaddr.h38
-rw-r--r--platform/windows/detect.py208
-rw-r--r--platform/windows/export/export.cpp24
-rw-r--r--platform/windows/export/export.h3
-rw-r--r--platform/windows/godot_win.cpp207
-rw-r--r--platform/windows/key_mapping_win.cpp256
-rw-r--r--platform/windows/key_mapping_win.h51
-rw-r--r--platform/windows/lang_table.h190
-rw-r--r--platform/windows/logo.pngbin0 -> 1434 bytes
-rw-r--r--platform/windows/os_windows.cpp1732
-rw-r--r--platform/windows/os_windows.h257
-rw-r--r--platform/windows/platform_config.h35
-rw-r--r--platform/windows/stream_peer_winsock.cpp368
-rw-r--r--platform/windows/stream_peer_winsock.h90
-rw-r--r--platform/windows/tcp_server_winsock.cpp166
-rw-r--r--platform/windows/tcp_server_winsock.h55
20 files changed, 4163 insertions, 0 deletions
diff --git a/platform/windows/SCsub b/platform/windows/SCsub
new file mode 100644
index 0000000000..1d454e40c2
--- /dev/null
+++ b/platform/windows/SCsub
@@ -0,0 +1,13 @@
+Import('env')
+
+
+common_win=[
+ "context_gl_win.cpp",
+ "os_windows.cpp",
+ "ctxgl_procaddr.cpp",
+ "key_mapping_win.cpp",
+ "tcp_server_winsock.cpp",
+ "stream_peer_winsock.cpp",
+]
+
+env.Program('#bin/godot.exe',['godot_win.cpp']+common_win)
diff --git a/platform/windows/context_gl_win.cpp b/platform/windows/context_gl_win.cpp
new file mode 100644
index 0000000000..a8f74fde2c
--- /dev/null
+++ b/platform/windows/context_gl_win.cpp
@@ -0,0 +1,205 @@
+/*************************************************************************/
+/* context_gl_win.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 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. */
+/*************************************************************************/
+#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) || defined(GLES2_ENABLED)
+
+//
+// C++ Implementation: context_gl_x11
+//
+// Description:
+//
+//
+// Author: Juan Linietsky <reduzio@gmail.com>, (C) 2008
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#define WINVER 0x0500
+#include "context_gl_win.h"
+
+//#include "drivers/opengl/glwrapper.h"
+//#include "ctxgl_procaddr.h"
+
+#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define WGL_CONTEXT_FLAGS_ARB 0x2094
+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
+
+typedef HGLRC (APIENTRY* PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC, HGLRC, const int*);
+
+
+void ContextGL_Win::release_current() {
+
+
+ wglMakeCurrent(hDC,NULL);
+
+}
+
+
+void ContextGL_Win::make_current() {
+
+ wglMakeCurrent(hDC,hRC);
+}
+
+int ContextGL_Win::get_window_width() {
+
+ return OS::get_singleton()->get_video_mode().width;
+}
+
+int ContextGL_Win::get_window_height() {
+
+ return OS::get_singleton()->get_video_mode().height;
+}
+
+void ContextGL_Win::swap_buffers() {
+
+ SwapBuffers(hDC);
+}
+
+/*
+static GLWrapperFuncPtr wrapper_get_proc_address(const char* p_function) {
+
+ print_line(String()+"getting proc of: "+p_function);
+ GLWrapperFuncPtr func=(GLWrapperFuncPtr)get_gl_proc_address(p_function);
+ if (!func) {
+ print_line("Couldn't find function: "+String(p_function));
+ print_line("error: "+itos(GetLastError()));
+ }
+ return func;
+
+}
+*/
+
+
+Error ContextGL_Win::initialize() {
+
+ static PIXELFORMATDESCRIPTOR pfd= {
+ sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
+ 1,
+ PFD_DRAW_TO_WINDOW | // Format Must Support Window
+ PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
+ PFD_DOUBLEBUFFER,
+ PFD_TYPE_RGBA,
+ 24,
+ 0, 0, 0, 0, 0, 0, // Color Bits Ignored
+ 0,// No Alpha Buffer
+ 0,// Shift Bit Ignored
+ 0,// No Accumulation Buffer
+ 0, 0, 0, 0,// Accumulation Bits Ignored
+ 24,// 24Bit Z-Buffer (Depth Buffer)
+ 0,// No Stencil Buffer
+ 0,// No Auxiliary Buffer
+ PFD_MAIN_PLANE, // Main Drawing Layer
+ 0,// Reserved
+ 0, 0, 0 // Layer Masks Ignored
+ };
+
+ if (!(hDC=GetDC(hWnd))) {
+ MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
+ return ERR_CANT_CREATE; // Return FALSE
+ }
+
+ if (!(pixel_format=ChoosePixelFormat(hDC,&pfd))) // Did Windows Find A Matching Pixel Format?
+ {
+ MessageBox(NULL,"Can't Find A Suitable pixel_format.","ERROR",MB_OK|MB_ICONEXCLAMATION);
+ return ERR_CANT_CREATE; // Return FALSE
+ }
+
+ if(!SetPixelFormat(hDC,pixel_format,&pfd)) // Are We Able To Set The Pixel Format?
+ {
+ MessageBox(NULL,"Can't Set The pixel_format.","ERROR",MB_OK|MB_ICONEXCLAMATION);
+ return ERR_CANT_CREATE; // Return FALSE
+ }
+
+ if (!(hRC=wglCreateContext(hDC))) // Are We Able To Get A Rendering Context?
+ {
+ MessageBox(NULL,"Can't Create A Temporary GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
+ return ERR_CANT_CREATE; // Return FALSE
+ }
+
+ wglMakeCurrent(hDC,hRC);
+
+ if (opengl_3_context) {
+
+ int attribs[] = {
+ WGL_CONTEXT_MAJOR_VERSION_ARB, 3,//we want a 3.1 context
+ WGL_CONTEXT_MINOR_VERSION_ARB, 2,
+ //and it shall be forward compatible so that we can only use up to date functionality
+ WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+ 0}; //zero indicates the end of the array
+
+ PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL; //pointer to the method
+ wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) wglGetProcAddress("wglCreateContextAttribsARB");
+
+ if(wglCreateContextAttribsARB == NULL) //OpenGL 3.0 is not supported
+ {
+ MessageBox(NULL,"Cannot get Proc Adress for CreateContextAttribs", "ERROR",MB_OK|MB_ICONEXCLAMATION);
+ wglDeleteContext(hRC);
+ return ERR_CANT_CREATE;
+ }
+
+ HGLRC new_hRC;
+ if (!(new_hRC=wglCreateContextAttribsARB(hDC,0, attribs)))
+ {
+ wglDeleteContext(hRC);
+ MessageBox(NULL,"Can't Create An OpenGL 3.1 Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
+ return ERR_CANT_CREATE; // Return false
+ }
+ wglMakeCurrent(hDC,NULL);
+ wglDeleteContext(hRC);
+ hRC=new_hRC;
+
+ if (!wglMakeCurrent(hDC,hRC)) // Try To Activate The Rendering Context
+ {
+ MessageBox(NULL,"Can't Activate The GL 3.1 Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
+ return ERR_CANT_CREATE; // Return FALSE
+ }
+
+ printf("Activated GL 3.1 context");
+ }
+
+
+// glWrapperInit(wrapper_get_proc_address);
+
+ return OK;
+}
+
+ContextGL_Win::ContextGL_Win(HWND hwnd,bool p_opengl_3_context) {
+
+ opengl_3_context=p_opengl_3_context;
+ hWnd=hwnd;
+}
+
+ContextGL_Win::~ContextGL_Win() {
+
+
+}
+
+
+#endif
diff --git a/platform/windows/context_gl_win.h b/platform/windows/context_gl_win.h
new file mode 100644
index 0000000000..6e8d99a5f0
--- /dev/null
+++ b/platform/windows/context_gl_win.h
@@ -0,0 +1,79 @@
+/*************************************************************************/
+/* context_gl_win.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 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. */
+/*************************************************************************/
+#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) || defined(GLES2_ENABLED)
+//
+// C++ Interface: context_gl_x11
+//
+// Description:
+//
+//
+// Author: Juan Linietsky <reduzio@gmail.com>, (C) 2008
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef CONTEXT_GL_WIN_H
+#define CONTEXT_GL_WIN_H
+
+
+#include "os/os.h"
+#include "drivers/gl_context/context_gl.h"
+#include "error_list.h"
+
+#include <windows.h>
+
+class ContextGL_Win : public ContextGL {
+
+ HDC hDC;
+ HGLRC hRC;
+ unsigned int pixel_format;
+ HWND hWnd;
+ bool opengl_3_context;
+public:
+
+
+ virtual void release_current();
+
+ virtual void make_current();
+
+ virtual int get_window_width();
+ virtual int get_window_height();
+ virtual void swap_buffers();
+
+ virtual Error initialize();
+
+
+ ContextGL_Win(HWND hwnd,bool p_opengl_3_context);
+ ~ContextGL_Win();
+
+};
+
+#endif
+#endif
diff --git a/platform/windows/ctxgl_procaddr.cpp b/platform/windows/ctxgl_procaddr.cpp
new file mode 100644
index 0000000000..9715784c32
--- /dev/null
+++ b/platform/windows/ctxgl_procaddr.cpp
@@ -0,0 +1,186 @@
+/*************************************************************************/
+/* ctxgl_procaddr.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 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. */
+/*************************************************************************/
+#ifdef OPENGL_ENABLED
+#include "ctxgl_procaddr.h"
+#include <GL/gl.h>
+#include <stdio.h>
+
+static PROC _gl_procs[]={
+ (PROC)glCullFace,
+ (PROC)glFrontFace,
+ (PROC)glHint,
+ (PROC)glLineWidth,
+ (PROC)glPointSize,
+ (PROC)glPolygonMode,
+ (PROC)glScissor,
+ (PROC)glTexParameterf,
+ (PROC)glTexParameterfv,
+ (PROC)glTexParameteri,
+ (PROC)glTexParameteriv,
+ (PROC)glTexImage1D,
+ (PROC)glTexImage2D,
+ (PROC)glDrawBuffer,
+ (PROC)glClear,
+ (PROC)glClearColor,
+ (PROC)glClearStencil,
+ (PROC)glClearDepth,
+ (PROC)glStencilMask,
+ (PROC)glColorMask,
+ (PROC)glDepthMask,
+ (PROC)glDisable,
+ (PROC)glEnable,
+ (PROC)glFinish,
+ (PROC)glFlush,
+ (PROC)glBlendFunc,
+ (PROC)glLogicOp,
+ (PROC)glStencilFunc,
+ (PROC)glStencilOp,
+ (PROC)glDepthFunc,
+ (PROC)glPixelStoref,
+ (PROC)glPixelStorei,
+ (PROC)glReadBuffer,
+ (PROC)glReadPixels,
+ (PROC)glGetBooleanv,
+ (PROC)glGetDoublev,
+ (PROC)glGetError,
+ (PROC)glGetFloatv,
+ (PROC)glGetIntegerv,
+ (PROC)glGetString,
+ (PROC)glGetTexImage,
+ (PROC)glGetTexParameterfv,
+ (PROC)glGetTexParameteriv,
+ (PROC)glGetTexLevelParameterfv,
+ (PROC)glGetTexLevelParameteriv,
+ (PROC)glIsEnabled,
+ (PROC)glDepthRange,
+ (PROC)glViewport,
+ /* not detected in ATI */
+ (PROC)glDrawArrays,
+ (PROC)glDrawElements,
+ (PROC)glGetPointerv,
+ (PROC)glPolygonOffset,
+ (PROC)glCopyTexImage1D,
+ (PROC)glCopyTexImage2D,
+ (PROC)glCopyTexSubImage1D,
+ (PROC)glCopyTexSubImage2D,
+ (PROC)glTexSubImage1D,
+ (PROC)glTexSubImage2D,
+ (PROC)glBindTexture,
+ (PROC)glDeleteTextures,
+ (PROC)glGenTextures,
+ (PROC)glIsTexture,
+
+ 0
+};
+
+static const char* _gl_proc_names[]={
+ "glCullFace",
+ "glFrontFace",
+ "glHint",
+ "glLineWidth",
+ "glPointSize",
+ "glPolygonMode",
+ "glScissor",
+ "glTexParameterf",
+ "glTexParameterfv",
+ "glTexParameteri",
+ "glTexParameteriv",
+ "glTexImage1D",
+ "glTexImage2D",
+ "glDrawBuffer",
+ "glClear",
+ "glClearColor",
+ "glClearStencil",
+ "glClearDepth",
+ "glStencilMask",
+ "glColorMask",
+ "glDepthMask",
+ "glDisable",
+ "glEnable",
+ "glFinish",
+ "glFlush",
+ "glBlendFunc",
+ "glLogicOp",
+ "glStencilFunc",
+ "glStencilOp",
+ "glDepthFunc",
+ "glPixelStoref",
+ "glPixelStorei",
+ "glReadBuffer",
+ "glReadPixels",
+ "glGetBooleanv",
+ "glGetDoublev",
+ "glGetError",
+ "glGetFloatv",
+ "glGetIntegerv",
+ "glGetString",
+ "glGetTexImage",
+ "glGetTexParameterfv",
+ "glGetTexParameteriv",
+ "glGetTexLevelParameterfv",
+ "glGetTexLevelParameteriv",
+ "glIsEnabled",
+ "glDepthRange",
+ "glViewport",
+ /* not detected in ati */
+ "glDrawArrays",
+ "glDrawElements",
+ "glGetPointerv",
+ "glPolygonOffset",
+ "glCopyTexImage1D",
+ "glCopyTexImage2D",
+ "glCopyTexSubImage1D",
+ "glCopyTexSubImage2D",
+ "glTexSubImage1D",
+ "glTexSubImage2D",
+ "glBindTexture",
+ "glDeleteTextures",
+ "glGenTextures",
+ "glIsTexture",
+
+ 0
+};
+
+PROC get_gl_proc_address(const char* p_address) {
+
+ PROC proc = wglGetProcAddress((const CHAR*)p_address);
+ if (!proc) {
+
+ int i=0;
+ while(_gl_procs[i]) {
+
+ if (strcmp(p_address,_gl_proc_names[i])==0) {
+ return _gl_procs[i];
+ }
+ i++;
+ }
+ }
+ return proc;
+}
+#endif
diff --git a/platform/windows/ctxgl_procaddr.h b/platform/windows/ctxgl_procaddr.h
new file mode 100644
index 0000000000..d3ab20e82d
--- /dev/null
+++ b/platform/windows/ctxgl_procaddr.h
@@ -0,0 +1,38 @@
+/*************************************************************************/
+/* ctxgl_procaddr.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 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 CTXGL_PROCADDR_H
+#define CTXGL_PROCADDR_H
+
+#ifdef OPENGL_ENABLED
+#include <windows.h>
+
+
+PROC get_gl_proc_address(const char* p_address);
+#endif
+#endif // CTXGL_PROCADDR_H
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
new file mode 100644
index 0000000000..1774ba17f8
--- /dev/null
+++ b/platform/windows/detect.py
@@ -0,0 +1,208 @@
+
+
+import os
+
+import sys
+
+
+def is_active():
+ return True
+
+def get_name():
+ return "Windows"
+
+def can_build():
+
+
+ if (os.name=="nt"):
+ #building natively on windows!
+ if (os.getenv("VSINSTALLDIR")):
+ return True
+ else:
+ print("MSVC Not detected, attempting mingw.")
+ return True
+
+
+
+ if (os.name=="posix"):
+
+ if os.system("i586-mingw32msvc-gcc --version") == 0:
+ return True
+
+
+ return False
+
+def get_opts():
+
+ mwp=""
+ mwp64=""
+ if (os.name!="nt"):
+ mwp="i586-mingw32msvc-"
+ mwp64="x86_64-w64-mingw32-"
+
+ return [
+ ('force_64_bits','Force 64 bits binary','no'),
+ ('force_32_bits','Force 32 bits binary','no'),
+ ('mingw_prefix','Mingw Prefix',mwp),
+ ('mingw_prefix_64','Mingw Prefix 64 bits',mwp64),
+ ]
+
+def get_flags():
+
+ return [
+ ('freetype','builtin'), #use builtin freetype
+ ]
+
+
+
+def configure(env):
+
+ if os.name == "posix":
+ env['OBJSUFFIX'] = ".win"+env['OBJSUFFIX']
+ env['LIBSUFFIX'] = ".win"+env['LIBSUFFIX']
+
+ env.Append(CPPPATH=['#platform/windows'])
+
+ if (env["tools"]=="no"):
+ #no tools suffix
+ env['OBJSUFFIX'] = ".nt"+env['OBJSUFFIX']
+ env['LIBSUFFIX'] = ".nt"+env['LIBSUFFIX']
+
+
+ if (os.name=="nt" and os.getenv("VSINSTALLDIR")!=None):
+ #build using visual studio
+ env['ENV']['TMP'] = os.environ['TMP']
+ env.Append(CPPPATH=['#platform/windows/include'])
+ env.Append(LIBPATH=['#platform/windows/lib'])
+
+ if (env["freetype"]!="no"):
+ env.Append(CCFLAGS=['/DFREETYPE_ENABLED'])
+ env.Append(CPPPATH=['#tools/freetype'])
+ env.Append(CPPPATH=['#tools/freetype/freetype/include'])
+
+ if (env["target"]=="release"):
+
+ env.Append(CCFLAGS=['/O2'])
+ env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS'])
+
+ elif (env["target"]=="test"):
+
+ env.Append(CCFLAGS=['/O2','/DDEBUG_ENABLED','/DD3D_DEBUG_INFO'])
+ env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
+
+ elif (env["target"]=="debug"):
+
+ env.Append(CCFLAGS=['/Zi','/DDEBUG_ENABLED','/DD3D_DEBUG_INFO','/O1'])
+ env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
+
+ elif (env["target"]=="profile"):
+
+ env.Append(CCFLAGS=['-g','-pg'])
+ env.Append(LINKFLAGS=['-pg'])
+
+ env.Append(CCFLAGS=['/MT','/Gd','/GR','/nologo'])
+ env.Append(CXXFLAGS=['/TP'])
+ env.Append(CPPFLAGS=['/DMSVC', '/GR', ])
+ env.Append(CCFLAGS=['/I'+os.getenv("WindowsSdkDir")+"/Include"])
+ env.Append(CCFLAGS=['/DWINDOWS_ENABLED'])
+ env.Append(CCFLAGS=['/DRTAUDIO_ENABLED'])
+ env.Append(CCFLAGS=['/DWIN32'])
+ env.Append(CCFLAGS=['/DTYPED_METHOD_BIND'])
+
+ #env.Append(CCFLAGS=['/DLEGACYGL_ENABLED'])
+ env.Append(CCFLAGS=['/DGLES_ENABLED'])
+ #env.Append(CCFLAGS=['/DGLES1_ENABLED'])
+ env.Append(CCFLAGS=['/DGLEW_ENABLED'])
+ env.Append(LIBS=['winmm','opengl32','dsound','kernel32','ole32','user32','gdi32','wsock32'])
+ env.Append(LINKFLAGS=['/DEBUG'])
+
+ env.Append(LIBPATH=[os.getenv("WindowsSdkDir")+"/Lib"])
+ if (os.getenv("DXSDK_DIR")):
+ DIRECTX_PATH=os.getenv("DXSDK_DIR")
+ else:
+ DIRECTX_PATH="C:/Program Files/Microsoft DirectX SDK (March 2009)"
+
+ if (os.getenv("VCINSTALLDIR")):
+ VC_PATH=os.getenv("VCINSTALLDIR")
+ else:
+ VC_PATH=""
+
+ env.Append(CCFLAGS=["/I"+VC_PATH+"/Include"])
+ env.Append(LIBPATH=[VC_PATH+"/Lib"])
+ env.Append(CCFLAGS=["/I"+DIRECTX_PATH+"/Include"])
+ env.Append(LIBPATH=[DIRECTX_PATH+"/Lib/x86"])
+ env['ENV'] = os.environ;
+ else:
+ #build using mingw
+ if (os.name=="nt"):
+ env['ENV']['TMP'] = os.environ['TMP'] #way to go scons, you can be so stupid sometimes
+
+ mingw_prefix=""
+
+ if (env["force_32_bits"]!="no"):
+ env['OBJSUFFIX'] = ".32"+env['OBJSUFFIX']
+ env['LIBSUFFIX'] = ".32"+env['LIBSUFFIX']
+ env.Append(CCFLAGS=['-m32'])
+ env.Append(LINKFLAGS=['-m32'])
+
+
+
+
+ if (env["force_64_bits"]!="no"):
+ mingw_prefix=env["mingw_prefix_64"];
+ env['OBJSUFFIX'] = ".64"+env['OBJSUFFIX']
+ env['LIBSUFFIX'] = ".64"+env['LIBSUFFIX']
+ env.Append(LINKFLAGS=['-static'])
+ else:
+ mingw_prefix=env["mingw_prefix"];
+
+ if (env["target"]=="release"):
+
+ env.Append(CCFLAGS=['-O3','-ffast-math','-fomit-frame-pointer','-msse2'])
+ env['OBJSUFFIX'] = "_opt"+env['OBJSUFFIX']
+ env['LIBSUFFIX'] = "_opt"+env['LIBSUFFIX']
+ elif (env["target"]=="release_debug"):
+
+ env.Append(CCFLAGS=['-O2','-DDEBUG_ENABLED'])
+ env['OBJSUFFIX'] = "_optd"+env['OBJSUFFIX']
+ env['LIBSUFFIX'] = "_optd"+env['LIBSUFFIX']
+
+ elif (env["target"]=="debug"):
+
+ env.Append(CCFLAGS=['-g', '-Wall','-DDEBUG_ENABLED'])
+ elif (env["target"]=="release_tools"):
+
+ env.Append(CCFLAGS=['-O2','-Wall','-DDEBUG_ENABLED'])
+
+
+ if (env["freetype"]!="no"):
+ env.Append(CCFLAGS=['-DFREETYPE_ENABLED'])
+ env.Append(CPPPATH=['#tools/freetype'])
+ env.Append(CPPPATH=['#tools/freetype/freetype/include'])
+
+ env["CC"]=mingw_prefix+"gcc"
+ env['AS']=mingw_prefix+"as"
+ env['CXX'] = mingw_prefix+"g++"
+ env['AR'] = mingw_prefix+"ar"
+ env['RANLIB'] = mingw_prefix+"ranlib"
+ env['LD'] = mingw_prefix+"g++"
+
+ #env['CC'] = "winegcc"
+ #env['CXX'] = "wineg++"
+
+ env.Append(CCFLAGS=['-DWINDOWS_ENABLED','-mwindows'])
+ env.Append(CPPFLAGS=['-DRTAUDIO_ENABLED'])
+ env.Append(CCFLAGS=['-DGLES2_ENABLED','-DGLES1_ENABLED','-DGLEW_ENABLED'])
+ env.Append(LIBS=['mingw32','opengl32', 'dsound', 'ole32', 'd3d9','winmm','gdi32','wsock32','kernel32'])
+ #'d3dx9d'
+ env.Append(CPPFLAGS=['-DMINGW_ENABLED'])
+ env.Append(LINKFLAGS=['-g'])
+
+ 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') } )
+
+
+
diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp
new file mode 100644
index 0000000000..952f51fdd4
--- /dev/null
+++ b/platform/windows/export/export.cpp
@@ -0,0 +1,24 @@
+#include "export.h"
+#include "platform/windows/logo.h"
+#include "tools/editor/editor_import_export.h"
+
+void register_windows_exporter() {
+
+ Image img(_windows_logo);
+ Ref<ImageTexture> logo = memnew( ImageTexture );
+ logo->create_from_image(img);
+
+ {
+ Ref<EditorExportPlatformPC> exporter = Ref<EditorExportPlatformPC>( memnew(EditorExportPlatformPC) );
+ exporter->set_binary_extension("exe");
+ exporter->set_release_binary32("windows_32_release.exe");
+ exporter->set_debug_binary32("windows_32_debug.exe");
+ exporter->set_release_binary64("windows_64_release.exe");
+ exporter->set_debug_binary64("windows_64_debug.exe");
+ exporter->set_name("Windows Desktop");
+ exporter->set_logo(logo);
+ EditorImportExport::get_singleton()->add_export_platform(exporter);
+ }
+
+
+}
diff --git a/platform/windows/export/export.h b/platform/windows/export/export.h
new file mode 100644
index 0000000000..de3dc3fa50
--- /dev/null
+++ b/platform/windows/export/export.h
@@ -0,0 +1,3 @@
+
+void register_windows_exporter();
+
diff --git a/platform/windows/godot_win.cpp b/platform/windows/godot_win.cpp
new file mode 100644
index 0000000000..2999a9beae
--- /dev/null
+++ b/platform/windows/godot_win.cpp
@@ -0,0 +1,207 @@
+/*************************************************************************/
+/* godot_win.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 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 "os_windows.h"
+#include "main/main.h"
+#include <stdio.h>
+
+PCHAR*
+ CommandLineToArgvA(
+ PCHAR CmdLine,
+ int* _argc
+ )
+ {
+ PCHAR* argv;
+ PCHAR _argv;
+ ULONG len;
+ ULONG argc;
+ CHAR a;
+ ULONG i, j;
+
+ BOOLEAN in_QM;
+ BOOLEAN in_TEXT;
+ BOOLEAN in_SPACE;
+
+ len = strlen(CmdLine);
+ i = ((len+2)/2)*sizeof(PVOID) + sizeof(PVOID);
+
+ argv = (PCHAR*)GlobalAlloc(GMEM_FIXED,
+ i + (len+2)*sizeof(CHAR));
+
+ _argv = (PCHAR)(((PUCHAR)argv)+i);
+
+ argc = 0;
+ argv[argc] = _argv;
+ in_QM = FALSE;
+ in_TEXT = FALSE;
+ in_SPACE = TRUE;
+ i = 0;
+ j = 0;
+
+ while( (a = CmdLine[i]) ) {
+ if(in_QM) {
+ if(a == '\"') {
+ in_QM = FALSE;
+ } else {
+ _argv[j] = a;
+ j++;
+ }
+ } else {
+ switch(a) {
+ case '\"':
+ in_QM = TRUE;
+ in_TEXT = TRUE;
+ if(in_SPACE) {
+ argv[argc] = _argv+j;
+ argc++;
+ }
+ in_SPACE = FALSE;
+ break;
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ if(in_TEXT) {
+ _argv[j] = '\0';
+ j++;
+ }
+ in_TEXT = FALSE;
+ in_SPACE = TRUE;
+ break;
+ default:
+ in_TEXT = TRUE;
+ if(in_SPACE) {
+ argv[argc] = _argv+j;
+ argc++;
+ }
+ _argv[j] = a;
+ j++;
+ in_SPACE = FALSE;
+ break;
+ }
+ }
+ i++;
+ }
+ _argv[j] = '\0';
+ argv[argc] = NULL;
+
+ (*_argc) = argc;
+ return argv;
+ }
+
+int main(int argc, char** argv) {
+
+ OS_Windows os(NULL);
+
+ Main::setup(argv[0], argc - 1, &argv[1]);
+ if (Main::start())
+ os.run();
+ Main::cleanup();
+
+ return os.get_exit_code();
+};
+
+HINSTANCE godot_hinstance = NULL;
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
+
+ int argc;
+ char** argv;
+
+ char* arg;
+ int index;
+ int result;
+
+ // count the arguments
+
+ argc = 1;
+ arg = lpCmdLine;
+
+ while (arg[0] != 0) {
+
+ while (arg[0] != 0 && arg[0] == ' ') {
+ arg++;
+ }
+
+ if (arg[0] != 0) {
+
+ argc++;
+
+ while (arg[0] != 0 && arg[0] != ' ') {
+ arg++;
+ }
+
+ }
+
+ }
+
+ // tokenize the arguments
+
+ argv = (char**)malloc(argc * sizeof(char*));
+
+ arg = lpCmdLine;
+ index = 1;
+
+ while (arg[0] != 0) {
+
+ while (arg[0] != 0 && arg[0] == ' ') {
+ arg++;
+ }
+
+ if (arg[0] != 0) {
+
+ argv[index] = arg;
+ index++;
+
+ while (arg[0] != 0 && arg[0] != ' ') {
+ arg++;
+ }
+
+ if (arg[0] != 0) {
+ arg[0] = 0;
+ arg++;
+ }
+
+ }
+
+ }
+
+ // put the program name into argv[0]
+
+ char filename[_MAX_PATH];
+
+ GetModuleFileName(NULL, filename, _MAX_PATH);
+ argv[0] = filename;
+
+ // call the user specified main function
+
+ result = main(argc, argv);
+
+ free(argv);
+ return result;
+}
diff --git a/platform/windows/key_mapping_win.cpp b/platform/windows/key_mapping_win.cpp
new file mode 100644
index 0000000000..bdf3b2a92f
--- /dev/null
+++ b/platform/windows/key_mapping_win.cpp
@@ -0,0 +1,256 @@
+/*************************************************************************/
+/* key_mapping_win.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 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. */
+/*************************************************************************/
+#define WINVER 0x0500
+#include "key_mapping_win.h"
+#include <stdio.h>
+
+struct _WinTranslatePair {
+
+ unsigned int keysym;
+ unsigned int keycode;
+};
+
+
+static _WinTranslatePair _vk_to_keycode[]={
+
+{ KEY_BACKSPACE, VK_BACK },// (0x08) // backspace
+{ KEY_TAB, VK_TAB },//(0x09)
+
+//VK_CLEAR (0x0C)
+
+{ KEY_RETURN, VK_RETURN },//(0x0D)
+
+{ KEY_SHIFT, VK_SHIFT },//(0x10)
+
+{ KEY_CONTROL, VK_CONTROL },//(0x11)
+
+{ KEY_MENU, VK_MENU },//(0x12)
+
+{ KEY_PAUSE, VK_PAUSE },//(0x13)
+
+{ KEY_CAPSLOCK, VK_CAPITAL },//(0x14)
+
+{ KEY_ESCAPE, VK_ESCAPE },//(0x1B)
+
+{ KEY_SPACE, VK_SPACE },//(0x20)
+
+{ KEY_PAGEUP,VK_PRIOR },//(0x21)
+
+{ KEY_PAGEDOWN, VK_NEXT },//(0x22)
+
+{ KEY_END, VK_END },//(0x23)
+
+{ KEY_HOME, VK_HOME },//(0x24)
+
+{ KEY_LEFT, VK_LEFT },//(0x25)
+
+{ KEY_UP, VK_UP },//(0x26)
+
+{ KEY_RIGHT,VK_RIGHT },//(0x27)
+
+{ KEY_DOWN, VK_DOWN},// (0x28)
+
+//VK_SELECT (0x29)
+
+{ KEY_PRINT, VK_PRINT},// (0x2A)
+
+//VK_EXECUTE (0x2B)
+
+{ KEY_PRINT, VK_SNAPSHOT},// (0x2C)
+
+{ KEY_INSERT, VK_INSERT},// (0x2D)
+
+{ KEY_DELETE, VK_DELETE},// (0x2E)
+
+{ KEY_HELP, VK_HELP},// (0x2F)
+
+
+{ KEY_0, (0x30) },////0 key
+{ KEY_1, (0x31) },////1 key
+{ KEY_2, (0x32) },////2 key
+{ KEY_3, (0x33) },////3 key
+{ KEY_4, (0x34) },////4 key
+{ KEY_5, (0x35) },////5 key
+{ KEY_6, (0x36) },////6 key
+{ KEY_7, (0x37) },////7 key
+{ KEY_8, (0x38) },////8 key
+{ KEY_9, (0x39) },////9 key
+{ KEY_A, (0x41) },////A key
+{ KEY_B, (0x42) },////B key
+{ KEY_C, (0x43) },////C key
+{ KEY_D, (0x44) },////D key
+{ KEY_E, (0x45) },////E key
+{ KEY_F, (0x46) },////F key
+{ KEY_G, (0x47) },////G key
+{ KEY_H, (0x48) },////H key
+{ KEY_I, (0x49) },////I key
+{ KEY_J, (0x4A) },////J key
+{ KEY_K, (0x4B) },////K key
+{ KEY_L, (0x4C) },////L key
+{ KEY_M, (0x4D) },////M key
+{ KEY_N, (0x4E) },////N key
+{ KEY_O, (0x4F) },////O key
+{ KEY_P, (0x50) },////P key
+{ KEY_Q, (0x51) },////Q key
+{ KEY_R, (0x52) },////R key
+{ KEY_S, (0x53) },////S key
+{ KEY_T, (0x54) },////T key
+{ KEY_U, (0x55) },////U key
+{ KEY_V, (0x56) },////V key
+{ KEY_W, (0x57) },////W key
+{ KEY_X, (0x58) },////X key
+{ KEY_Y, (0x59) },////Y key
+{ KEY_Z, (0x5A) },////Z key
+
+{ KEY_MASK_META, VK_LWIN },//(0x5B)
+{ KEY_MASK_META, VK_RWIN },//(0x5C)
+//VK_APPS (0x5D)
+{ KEY_STANDBY,VK_SLEEP },//(0x5F)
+{ KEY_KP_0,VK_NUMPAD0 },//(0x60)
+{ KEY_KP_1,VK_NUMPAD1 },//(0x61)
+{ KEY_KP_2,VK_NUMPAD2 },//(0x62)
+{ KEY_KP_3,VK_NUMPAD3 },//(0x63)
+{ KEY_KP_4,VK_NUMPAD4 },//(0x64)
+{ KEY_KP_5,VK_NUMPAD5 },//(0x65)
+{ KEY_KP_6,VK_NUMPAD6 },//(0x66)
+{ KEY_KP_7,VK_NUMPAD7 },//(0x67)
+{ KEY_KP_8,VK_NUMPAD8 },//(0x68)
+{ KEY_KP_9,VK_NUMPAD9 },//(0x69)
+{ KEY_KP_MULTIPLY,VK_MULTIPLY},// (0x6A)
+{ KEY_KP_ADD,VK_ADD},// (0x6B)
+//VK_SEPARATOR (0x6C)
+{ KEY_KP_SUBSTRACT,VK_SUBTRACT},// (0x6D)
+{ KEY_KP_PERIOD,VK_DECIMAL},// (0x6E)
+{ KEY_KP_DIVIDE,VK_DIVIDE},// (0x6F)
+{ KEY_F1,VK_F1},// (0x70)
+{ KEY_F2,VK_F2},// (0x71)
+{ KEY_F3,VK_F3},// (0x72)
+{ KEY_F4,VK_F4},// (0x73)
+{ KEY_F5,VK_F5},// (0x74)
+{ KEY_F6,VK_F6},// (0x75)
+{ KEY_F7,VK_F7},// (0x76)
+{ KEY_F8,VK_F8},// (0x77)
+{ KEY_F9,VK_F9},// (0x78)
+{ KEY_F10,VK_F10},// (0x79)
+{ KEY_F11,VK_F11},// (0x7A)
+{ KEY_F12,VK_F12},// (0x7B)
+{ KEY_F13,VK_F13},// (0x7C)
+{ KEY_F14,VK_F14},// (0x7D)
+{ KEY_F15,VK_F15},// (0x7E)
+{ KEY_F16,VK_F16},// (0x7F)
+{ KEY_NUMLOCK,VK_NUMLOCK},// (0x90)
+{ KEY_SCROLLLOCK,VK_SCROLL},// (0x91)
+{ KEY_SHIFT,VK_LSHIFT},// (0xA0)
+{ KEY_SHIFT,VK_RSHIFT},// (0xA1)
+{ KEY_CONTROL,VK_LCONTROL},// (0xA2)
+{ KEY_CONTROL,VK_RCONTROL},// (0xA3)
+{ KEY_MENU,VK_LMENU},// (0xA4)
+{ KEY_MENU,VK_RMENU},// (0xA5)
+
+
+{ KEY_BACK,VK_BROWSER_BACK},// (0xA6)
+
+{ KEY_FORWARD,VK_BROWSER_FORWARD},// (0xA7)
+
+{ KEY_REFRESH,VK_BROWSER_REFRESH},// (0xA8)
+
+{ KEY_STOP,VK_BROWSER_STOP},// (0xA9)
+
+{ KEY_SEARCH,VK_BROWSER_SEARCH},// (0xAA)
+
+{ KEY_FAVORITES, VK_BROWSER_FAVORITES},// (0xAB)
+
+{ KEY_HOMEPAGE,VK_BROWSER_HOME},// (0xAC)
+
+{ KEY_VOLUMEMUTE,VK_VOLUME_MUTE},// (0xAD)
+
+{ KEY_VOLUMEDOWN,VK_VOLUME_DOWN},// (0xAE)
+
+{ KEY_VOLUMEUP,VK_VOLUME_UP},// (0xAF)
+
+
+{ KEY_MEDIANEXT,VK_MEDIA_NEXT_TRACK},// (0xB0)
+
+{ KEY_MEDIAPREVIOUS,VK_MEDIA_PREV_TRACK},// (0xB1)
+
+{ KEY_MEDIASTOP,VK_MEDIA_STOP},// (0xB2)
+
+//VK_MEDIA_PLAY_PAUSE (0xB3)
+
+{ KEY_LAUNCHMAIL, VK_LAUNCH_MAIL},// (0xB4)
+
+{ KEY_LAUNCHMEDIA,VK_LAUNCH_MEDIA_SELECT},// (0xB5)
+
+{ KEY_LAUNCH0,VK_LAUNCH_APP1},// (0xB6)
+
+{ KEY_LAUNCH1,VK_LAUNCH_APP2},// (0xB7)
+
+{ KEY_SEMICOLON,VK_OEM_1},// (0xBA)
+
+
+{ KEY_EQUAL, VK_OEM_PLUS},// (0xBB) // Windows 2000/XP: For any country/region, the '+' key
+{ KEY_COLON,VK_OEM_COMMA},// (0xBC) // Windows 2000/XP: For any country/region, the ',' key
+{ KEY_MINUS,VK_OEM_MINUS},// (0xBD) // Windows 2000/XP: For any country/region, the '-' key
+{ KEY_PERIOD,VK_OEM_PERIOD},// (0xBE) // Windows 2000/XP: For any country/region, the '.' key
+{ KEY_SLASH,VK_OEM_2},// (0xBF) //Windows 2000/XP: For the US standard keyboard, the '/?' key
+
+{KEY_QUOTELEFT, VK_OEM_3},// (0xC0)
+{KEY_BRACELEFT,VK_OEM_4},// (0xDB)
+{KEY_BACKSLASH,VK_OEM_5},// (0xDC)
+{KEY_BRACERIGHT,VK_OEM_6},// (0xDD)
+{KEY_APOSTROPHE, VK_OEM_7},// (0xDE)
+/*
+{VK_OEM_8 (0xDF)
+{VK_OEM_102 (0xE2) // Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard
+*/
+//{ KEY_PLAY, VK_PLAY},// (0xFA)
+
+{KEY_UNKNOWN, 0} };
+
+/*
+VK_ZOOM (0xFB)
+VK_NONAME (0xFC)
+VK_PA1 (0xFD)
+VK_OEM_CLEAR (0xFE)
+*/
+
+unsigned int KeyMappingWindows::get_keysym(unsigned int p_code) {
+
+ for(int i=0;_vk_to_keycode[i].keysym!=KEY_UNKNOWN;i++) {
+
+ if (_vk_to_keycode[i].keycode==p_code) {
+ //printf("outcode: %x\n",_vk_to_keycode[i].keysym);
+
+ return _vk_to_keycode[i].keysym;
+ }
+ }
+
+
+ return KEY_UNKNOWN;
+}
diff --git a/platform/windows/key_mapping_win.h b/platform/windows/key_mapping_win.h
new file mode 100644
index 0000000000..3e351675b0
--- /dev/null
+++ b/platform/windows/key_mapping_win.h
@@ -0,0 +1,51 @@
+/*************************************************************************/
+/* key_mapping_win.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 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 KEY_MAPPING_WINDOWS_H
+#define KEY_MAPPING_WINDOWS_H
+
+
+#include "os/keyboard.h"
+
+#include <windows.h>
+
+#include <winuser.h>
+
+
+class KeyMappingWindows {
+
+ KeyMappingWindows() {};
+public:
+
+ static unsigned int get_keysym(unsigned int p_code);
+
+};
+
+
+
+#endif
diff --git a/platform/windows/lang_table.h b/platform/windows/lang_table.h
new file mode 100644
index 0000000000..83f3fb52fd
--- /dev/null
+++ b/platform/windows/lang_table.h
@@ -0,0 +1,190 @@
+/*************************************************************************/
+/* lang_table.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 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 LANG_TABLE_H
+#define LANG_TABLE_H
+
+//#include <windows.h>
+
+struct _WinLocale {
+ const char *locale;
+ int main_lang;
+ int sublang;
+};
+
+static const _WinLocale _win_locales[]={
+{"ar", LANG_ARABIC,SUBLANG_NEUTRAL},
+{"ar_AE", LANG_ARABIC,SUBLANG_ARABIC_UAE},
+{"ar_BH", LANG_ARABIC,SUBLANG_ARABIC_BAHRAIN},
+{"ar_DZ", LANG_ARABIC,SUBLANG_ARABIC_ALGERIA},
+{"ar_EG", LANG_ARABIC,SUBLANG_ARABIC_EGYPT},
+{"ar_IQ", LANG_ARABIC,SUBLANG_ARABIC_IRAQ},
+{"ar_JO", LANG_ARABIC,SUBLANG_ARABIC_JORDAN},
+{"ar_KW", LANG_ARABIC,SUBLANG_ARABIC_KUWAIT},
+{"ar_LB", LANG_ARABIC,SUBLANG_ARABIC_LEBANON},
+{"ar_LY", LANG_ARABIC,SUBLANG_ARABIC_LIBYA},
+{"ar_MA", LANG_ARABIC,SUBLANG_ARABIC_MOROCCO},
+{"ar_OM", LANG_ARABIC,SUBLANG_ARABIC_OMAN},
+{"ar_QA", LANG_ARABIC,SUBLANG_ARABIC_QATAR},
+{"ar_SA", LANG_ARABIC,SUBLANG_ARABIC_SAUDI_ARABIA},
+//no sudan
+{"ar_SY", LANG_ARABIC,SUBLANG_ARABIC_SYRIA},
+{"ar_TN", LANG_ARABIC,SUBLANG_ARABIC_TUNISIA},
+{"ar_YE", LANG_ARABIC,SUBLANG_ARABIC_YEMEN},
+{"be", LANG_BELARUSIAN,SUBLANG_NEUTRAL},
+{"be_BY", LANG_BELARUSIAN,SUBLANG_BELARUSIAN_BELARUS},
+{"bg", LANG_BULGARIAN,SUBLANG_NEUTRAL},
+{"bg_BG", LANG_BULGARIAN,SUBLANG_BULGARIAN_BULGARIA},
+{"ca", LANG_CATALAN,SUBLANG_NEUTRAL},
+{"ca_ES", LANG_CATALAN,SUBLANG_CATALAN_CATALAN},
+{"cs", LANG_CZECH,SUBLANG_NEUTRAL},
+{"cs_CZ", LANG_CZECH,SUBLANG_CZECH_CZECH_REPUBLIC},
+{"da", LANG_DANISH,SUBLANG_NEUTRAL},
+{"da_DK", LANG_DANISH,SUBLANG_DANISH_DENMARK},
+{"de", LANG_GERMAN,SUBLANG_NEUTRAL},
+{"de_AT", LANG_GERMAN,SUBLANG_GERMAN_AUSTRIAN},
+{"de_CH", LANG_GERMAN,SUBLANG_GERMAN_SWISS},
+{"de_DE", LANG_GERMAN,SUBLANG_GERMAN},
+{"de_LU", LANG_GERMAN,SUBLANG_GERMAN_LUXEMBOURG},
+{"el", LANG_GREEK,SUBLANG_NEUTRAL},
+{"el_GR", LANG_GREEK,SUBLANG_GREEK_GREECE},
+//{"en_029", LANG_ENGLISH,SUBLANG_ENGLISH_CARIBBEAN},
+{"en", LANG_ENGLISH,SUBLANG_NEUTRAL},
+{"en_AU", LANG_ENGLISH,SUBLANG_ENGLISH_AUS},
+{"en_CA", LANG_ENGLISH,SUBLANG_ENGLISH_CAN},
+{"en_GB", LANG_ENGLISH,SUBLANG_ENGLISH_UK},
+//{"en_IE", LANG_ENGLISH,SUBLANG_ENGLISH_IRELAND},
+{"en_IN", LANG_ENGLISH,SUBLANG_ENGLISH_INDIA},
+//MT
+{"en_NZ", LANG_ENGLISH,SUBLANG_ENGLISH_NZ},
+{"en_PH", LANG_ENGLISH,SUBLANG_ENGLISH_PHILIPPINES},
+{"en_SG", LANG_ENGLISH,SUBLANG_ENGLISH_SINGAPORE},
+{"en_US", LANG_ENGLISH,SUBLANG_ENGLISH_US},
+{"en_ZA", LANG_ENGLISH,SUBLANG_ENGLISH_SOUTH_AFRICA},
+{"es", LANG_SPANISH,SUBLANG_NEUTRAL},
+{"es_AR", LANG_SPANISH,SUBLANG_SPANISH_ARGENTINA},
+{"es_BO", LANG_SPANISH,SUBLANG_SPANISH_BOLIVIA},
+{"es_CL", LANG_SPANISH,SUBLANG_SPANISH_CHILE},
+{"es_CO", LANG_SPANISH,SUBLANG_SPANISH_COLOMBIA},
+{"es_CR", LANG_SPANISH,SUBLANG_SPANISH_COSTA_RICA},
+{"es_DO", LANG_SPANISH,SUBLANG_SPANISH_DOMINICAN_REPUBLIC},
+{"es_EC", LANG_SPANISH,SUBLANG_SPANISH_ECUADOR},
+{"es_ES", LANG_SPANISH,SUBLANG_SPANISH},
+{"es_GT", LANG_SPANISH,SUBLANG_SPANISH_GUATEMALA},
+{"es_HN", LANG_SPANISH,SUBLANG_SPANISH_HONDURAS},
+{"es_MX", LANG_SPANISH,SUBLANG_SPANISH_MEXICAN},
+{"es_NI", LANG_SPANISH,SUBLANG_SPANISH_NICARAGUA},
+{"es_PA", LANG_SPANISH,SUBLANG_SPANISH_PANAMA},
+{"es_PE", LANG_SPANISH,SUBLANG_SPANISH_PERU},
+{"es_PR", LANG_SPANISH,SUBLANG_SPANISH_PUERTO_RICO},
+{"es_PY", LANG_SPANISH,SUBLANG_SPANISH_PARAGUAY},
+{"es_SV", LANG_SPANISH,SUBLANG_SPANISH_EL_SALVADOR},
+{"es_US", LANG_SPANISH,SUBLANG_SPANISH_US},
+{"es_UY", LANG_SPANISH,SUBLANG_SPANISH_URUGUAY},
+{"es_VE", LANG_SPANISH,SUBLANG_SPANISH_VENEZUELA},
+{"et", LANG_ESTONIAN,SUBLANG_NEUTRAL},
+{"et_EE", LANG_ESTONIAN,SUBLANG_ESTONIAN_ESTONIA},
+{"fi", LANG_FINNISH,SUBLANG_NEUTRAL},
+{"fi_FI", LANG_FINNISH,SUBLANG_FINNISH_FINLAND},
+{"fr", LANG_FRENCH,SUBLANG_NEUTRAL},
+{"fr_BE", LANG_FRENCH,SUBLANG_FRENCH_BELGIAN},
+{"fr_CA", LANG_FRENCH,SUBLANG_FRENCH_CANADIAN},
+{"fr_CH", LANG_FRENCH,SUBLANG_FRENCH_SWISS},
+{"fr_FR", LANG_FRENCH,SUBLANG_FRENCH},
+{"fr_LU", LANG_FRENCH,SUBLANG_FRENCH_LUXEMBOURG},
+{"ga", LANG_IRISH,SUBLANG_NEUTRAL},
+{"ga_IE", LANG_IRISH,SUBLANG_IRISH_IRELAND},
+{"hi", LANG_HINDI,SUBLANG_NEUTRAL},
+{"hi_IN", LANG_HINDI,SUBLANG_HINDI_INDIA},
+{"hr", LANG_CROATIAN,SUBLANG_NEUTRAL},
+{"hr_HR", LANG_CROATIAN,SUBLANG_CROATIAN_CROATIA},
+{"hu", LANG_HUNGARIAN,SUBLANG_NEUTRAL},
+{"hu_HU", LANG_HUNGARIAN,SUBLANG_HUNGARIAN_HUNGARY},
+{"in", LANG_ARMENIAN,SUBLANG_NEUTRAL},
+{"in_ID", LANG_INDONESIAN,SUBLANG_INDONESIAN_INDONESIA},
+{"is", LANG_ICELANDIC,SUBLANG_NEUTRAL},
+{"is_IS", LANG_ICELANDIC,SUBLANG_ICELANDIC_ICELAND},
+{"it", LANG_ITALIAN,SUBLANG_NEUTRAL},
+{"it_CH", LANG_ITALIAN,SUBLANG_ITALIAN_SWISS},
+{"it_IT", LANG_ITALIAN,SUBLANG_ITALIAN},
+{"iw", LANG_HEBREW,SUBLANG_NEUTRAL},
+{"iw_IL", LANG_HEBREW,SUBLANG_HEBREW_ISRAEL},
+{"ja", LANG_JAPANESE,SUBLANG_NEUTRAL},
+{"ja_JP", LANG_JAPANESE,SUBLANG_JAPANESE_JAPAN},
+{"ko", LANG_KOREAN,SUBLANG_NEUTRAL},
+{"ko_KR", LANG_KOREAN,SUBLANG_KOREAN},
+{"lt", LANG_LITHUANIAN,SUBLANG_NEUTRAL},
+//{"lt_LT", LANG_LITHUANIAN,SUBLANG_LITHUANIAN_LITHUANIA},
+{"lv", LANG_LATVIAN,SUBLANG_NEUTRAL},
+{"lv_LV", LANG_LATVIAN,SUBLANG_LATVIAN_LATVIA},
+{"mk", LANG_MACEDONIAN,SUBLANG_NEUTRAL},
+{"mk_MK", LANG_MACEDONIAN,SUBLANG_MACEDONIAN_MACEDONIA},
+{"ms", LANG_MALAY,SUBLANG_NEUTRAL},
+{"ms_MY", LANG_MALAY,SUBLANG_MALAY_MALAYSIA},
+{"mt", LANG_MALTESE,SUBLANG_NEUTRAL},
+{"mt_MT", LANG_MALTESE,SUBLANG_MALTESE_MALTA},
+{"nl", LANG_DUTCH,SUBLANG_NEUTRAL},
+{"nl_BE", LANG_DUTCH,SUBLANG_DUTCH_BELGIAN},
+{"nl_NL", LANG_DUTCH,SUBLANG_DUTCH},
+{"no", LANG_NORWEGIAN,SUBLANG_NEUTRAL},
+{"no_NO", LANG_NORWEGIAN,SUBLANG_NORWEGIAN_BOKMAL},
+{"no_NO_NY", LANG_NORWEGIAN,SUBLANG_NORWEGIAN_NYNORSK},
+{"pl", LANG_POLISH,SUBLANG_NEUTRAL},
+{"pl_PL", LANG_POLISH,SUBLANG_POLISH_POLAND},
+{"pt", LANG_PORTUGUESE,SUBLANG_NEUTRAL},
+{"pt_BR", LANG_PORTUGUESE,SUBLANG_PORTUGUESE_BRAZILIAN},
+{"pt_PT", LANG_PORTUGUESE,SUBLANG_PORTUGUESE},
+{"ro", LANG_ROMANIAN,SUBLANG_NEUTRAL},
+{"ro_RO", LANG_ROMANIAN,SUBLANG_ROMANIAN_ROMANIA},
+{"ru", LANG_RUSSIAN,SUBLANG_NEUTRAL},
+{"ru_RU", LANG_RUSSIAN,SUBLANG_RUSSIAN_RUSSIA},
+{"sk", LANG_SLOVAK,SUBLANG_NEUTRAL},
+{"sk_SK", LANG_SLOVAK,SUBLANG_SLOVAK_SLOVAKIA},
+{"sl", LANG_SLOVENIAN,SUBLANG_NEUTRAL},
+{"sl_SI", LANG_SLOVENIAN,SUBLANG_SLOVENIAN_SLOVENIA},
+{"sq", LANG_ALBANIAN,SUBLANG_NEUTRAL},
+{"sq_AL", LANG_ALBANIAN,SUBLANG_ALBANIAN_ALBANIA},
+{"sr", LANG_SERBIAN_NEUTRAL,SUBLANG_NEUTRAL},
+{"sv", LANG_SWEDISH,SUBLANG_NEUTRAL},
+{"sv_SE", LANG_SWEDISH,SUBLANG_SWEDISH},
+{"th", LANG_THAI,SUBLANG_NEUTRAL},
+{"th_TH", LANG_THAI,SUBLANG_THAI_THAILAND},
+{"tr", LANG_TURKISH,SUBLANG_NEUTRAL},
+{"tr_TR", LANG_TURKISH,SUBLANG_TURKISH_TURKEY},
+{"uk", LANG_UKRAINIAN,SUBLANG_NEUTRAL},
+{"uk_UA", LANG_UKRAINIAN,SUBLANG_UKRAINIAN_UKRAINE},
+{"vi", LANG_VIETNAMESE,SUBLANG_NEUTRAL},
+{"vi_VN", LANG_VIETNAMESE,SUBLANG_VIETNAMESE_VIETNAM},
+{"zh", LANG_CHINESE,SUBLANG_NEUTRAL},
+{"zh_CN", LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED},
+{"zh_HK", LANG_CHINESE,SUBLANG_CHINESE_HONGKONG},
+{"zh_SG", LANG_CHINESE,SUBLANG_CHINESE_SINGAPORE},
+{0, 0,0},
+};
+
+#endif // LANG_TABLE_H
diff --git a/platform/windows/logo.png b/platform/windows/logo.png
new file mode 100644
index 0000000000..a27e14dde8
--- /dev/null
+++ b/platform/windows/logo.png
Binary files differ
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
new file mode 100644
index 0000000000..efeb813a2d
--- /dev/null
+++ b/platform/windows/os_windows.cpp
@@ -0,0 +1,1732 @@
+/*************************************************************************/
+/* os_windows.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 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 "drivers/gles2/rasterizer_gles2.h"
+#include "drivers/gles1/rasterizer_gles1.h"
+#include "os_windows.h"
+#include "drivers/nedmalloc/memory_pool_static_nedmalloc.h"
+#include "drivers/unix/memory_pool_static_malloc.h"
+#include "os/memory_pool_dynamic_static.h"
+#include "drivers/windows/thread_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"
+#include "drivers/windows/dir_access_windows.h"
+
+
+#include "servers/visual/visual_server_raster.h"
+#include "servers/audio/audio_server_sw.h"
+#include "servers/visual/visual_server_wrap_mt.h"
+
+#include "tcp_server_winsock.h"
+#include "stream_peer_winsock.h"
+#include "os/pc_joystick_map.h"
+#include "lang_table.h"
+#include "os/memory_pool_dynamic_prealloc.h"
+#include "globals.h"
+#include "io/marshalls.h"
+static const WORD MAX_CONSOLE_LINES = 1500;
+
+//#define STDOUT_FILE
+
+extern HINSTANCE godot_hinstance;
+
+void RedirectIOToConsole() {
+
+ int hConHandle;
+
+ intptr_t lStdHandle;
+
+ CONSOLE_SCREEN_BUFFER_INFO coninfo;
+
+ FILE *fp;
+
+ // allocate a console for this app
+
+ AllocConsole();
+
+ // set the screen buffer to be big enough to let us scroll text
+
+ GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
+
+ &coninfo);
+
+ coninfo.dwSize.Y = MAX_CONSOLE_LINES;
+
+ SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),
+
+ coninfo.dwSize);
+
+ // redirect unbuffered STDOUT to the console
+
+ lStdHandle = (intptr_t)GetStdHandle(STD_OUTPUT_HANDLE);
+
+ hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
+
+ fp = _fdopen( hConHandle, "w" );
+
+ *stdout = *fp;
+
+ setvbuf( stdout, NULL, _IONBF, 0 );
+
+ // redirect unbuffered STDIN to the console
+
+ lStdHandle = (intptr_t)GetStdHandle(STD_INPUT_HANDLE);
+
+ hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
+
+ fp = _fdopen( hConHandle, "r" );
+
+ *stdin = *fp;
+
+ setvbuf( stdin, NULL, _IONBF, 0 );
+
+ // redirect unbuffered STDERR to the console
+
+ lStdHandle = (intptr_t)GetStdHandle(STD_ERROR_HANDLE);
+
+ hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
+
+ fp = _fdopen( hConHandle, "w" );
+
+ *stderr = *fp;
+
+ setvbuf( stderr, NULL, _IONBF, 0 );
+
+ // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
+
+ // point to console as well
+}
+
+int OS_Windows::get_video_driver_count() const {
+
+ return 2;
+}
+const char * OS_Windows::get_video_driver_name(int p_driver) const {
+
+ return p_driver==0?"GLES2":"GLES1";
+}
+
+OS::VideoMode OS_Windows::get_default_video_mode() const {
+
+ return VideoMode(800,600,false);
+}
+
+int OS_Windows::get_audio_driver_count() const {
+
+ return AudioDriverManagerSW::get_driver_count();
+}
+const char * OS_Windows::get_audio_driver_name(int p_driver) const {
+
+ AudioDriverSW* driver = AudioDriverManagerSW::get_driver(p_driver);
+ ERR_FAIL_COND_V( !driver, "" );
+ return AudioDriverManagerSW::get_driver(p_driver)->get_name();
+}
+
+static MemoryPoolStatic *mempool_static=NULL;
+static MemoryPoolDynamic *mempool_dynamic=NULL;
+
+void OS_Windows::initialize_core() {
+
+
+ last_button_state=0;
+
+ //RedirectIOToConsole();
+
+ ThreadWindows::make_default();
+ SemaphoreWindows::make_default();
+ MutexWindows::make_default();
+
+ FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
+ FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA);
+ FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_FILESYSTEM);
+ //FileAccessBufferedFA<FileAccessWindows>::make_default();
+ DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_RESOURCES);
+ DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_USERDATA);
+ DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_FILESYSTEM);
+
+ TCPServerWinsock::make_default();
+ StreamPeerWinsock::make_default();
+
+ mempool_static = new MemoryPoolStaticMalloc;
+#if 1
+ mempool_dynamic = memnew( MemoryPoolDynamicStatic );
+#else
+#define DYNPOOL_SIZE 4*1024*1024
+ void * buffer = malloc( DYNPOOL_SIZE );
+ mempool_dynamic = memnew( MemoryPoolDynamicPrealloc(buffer,DYNPOOL_SIZE) );
+
+#endif
+
+ // We need to know how often the clock is updated
+ if( !QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second) )
+ ticks_per_second = 1000;
+ // If timeAtGameStart is 0 then we get the time since
+ // the start of the computer when we call GetGameTime()
+ ticks_start = 0;
+ ticks_start = get_ticks_usec();
+
+ process_map = memnew((Map<ProcessID, ProcessInfo>));
+
+ IP_Unix::make_default();
+
+ cursor_shape=CURSOR_ARROW;
+
+
+}
+
+bool OS_Windows::can_draw() const {
+
+ return !minimized;
+};
+
+
+LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) {
+
+
+ switch (uMsg) // Check For Windows Messages
+ {
+ case WM_ACTIVATE: // Watch For Window Activate Message
+ {
+ minimized = HIWORD(wParam) != 0;
+ if (!main_loop) {
+ return 0;
+ };
+ if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE) {
+
+ main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
+ alt_mem=false;
+ control_mem=false;
+ shift_mem=false;
+ if (mouse_mode==MOUSE_MODE_CAPTURED) {
+ RECT clipRect;
+ GetClientRect(hWnd, &clipRect);
+ ClientToScreen(hWnd, (POINT*) &clipRect.left);
+ ClientToScreen(hWnd, (POINT*) &clipRect.right);
+ ClipCursor(&clipRect);
+ SetCapture(hWnd);
+
+ }
+ } else {
+ main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
+ alt_mem=false;
+
+ };
+
+ return 0; // Return To The Message Loop
+ }
+
+ case WM_PAINT:
+
+ Main::force_redraw();
+ break;
+
+ case WM_SYSCOMMAND: // Intercept System Commands
+ {
+ switch (wParam) // Check System Calls
+ {
+ case SC_SCREENSAVE: // Screensaver Trying To Start?
+ case SC_MONITORPOWER: // Monitor Trying To Enter Powersave?
+ return 0; // Prevent From Happening
+ case SC_KEYMENU:
+ if ((lParam>>16)<=0)
+ return 0;
+ }
+ break; // Exit
+ }
+
+ case WM_CLOSE: // Did We Receive A Close Message?
+ {
+ if (main_loop)
+ main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST);
+ //force_quit=true;
+ return 0; // Jump Back
+ }
+ case WM_MOUSELEAVE: {
+
+ old_invalid=true;
+ outside=true;
+
+ } break;
+ case WM_MOUSEMOVE: {
+
+ if (outside) {
+
+ CursorShape c=cursor_shape;
+ cursor_shape=CURSOR_MAX;
+ set_cursor_shape(c);
+ outside=false;
+
+ //Once-Off notification, must call again....
+ TRACKMOUSEEVENT tme;
+ tme.cbSize=sizeof(TRACKMOUSEEVENT);
+ tme.dwFlags=TME_LEAVE;
+ tme.hwndTrack=hWnd;
+ tme.dwHoverTime=HOVER_DEFAULT;
+ TrackMouseEvent(&tme);
+
+ }
+ InputEvent event;
+ event.type=InputEvent::MOUSE_MOTION;
+ event.ID=++last_id;
+ InputEventMouseMotion &mm=event.mouse_motion;
+
+ mm.mod.control=(wParam&MK_CONTROL)!=0;
+ mm.mod.shift=(wParam&MK_SHIFT)!=0;
+ mm.mod.alt=alt_mem;
+
+ mm.button_mask|=(wParam&MK_LBUTTON)?(1<<0):0;
+ mm.button_mask|=(wParam&MK_RBUTTON)?(1<<1):0;
+ mm.button_mask|=(wParam&MK_MBUTTON)?(1<<2):0;
+ last_button_state=mm.button_mask;
+ /*mm.button_mask|=(wParam&MK_XBUTTON1)?(1<<5):0;
+ mm.button_mask|=(wParam&MK_XBUTTON2)?(1<<6):0;*/
+ mm.x=GET_X_LPARAM(lParam);
+ mm.y=GET_Y_LPARAM(lParam);
+
+ if (mouse_mode==MOUSE_MODE_CAPTURED) {
+
+ Point2i c(video_mode.width/2,video_mode.height/2);
+ if (Point2i(mm.x,mm.y)==c) {
+ center=c;
+ return 0;
+ }
+
+ Point2i ncenter(mm.x,mm.y);
+ mm.x = old_x + (mm.x-center.x);
+ mm.y = old_y + (mm.y-center.y);
+ center=ncenter;
+ POINT pos = { (int) c.x, (int) c.y };
+ ClientToScreen(hWnd, &pos);
+ SetCursorPos(pos.x, pos.y);
+
+ }
+
+ input->set_mouse_pos(Point2(mm.x,mm.y));
+ mm.speed_x=input->get_mouse_speed().x;
+ mm.speed_y=input->get_mouse_speed().y;
+
+ if (old_invalid) {
+
+ old_x=mm.x;
+ old_y=mm.y;
+ old_invalid=false;
+ }
+
+ mm.relative_x=mm.x-old_x;
+ mm.relative_y=mm.y-old_y;
+ old_x=mm.x;
+ old_y=mm.y;
+ if (main_loop)
+ input->parse_input_event(event);
+
+
+
+ } break;
+ case WM_LBUTTONDOWN:
+ case WM_LBUTTONUP:
+ case WM_MBUTTONDOWN:
+ case WM_MBUTTONUP:
+ case WM_RBUTTONDOWN:
+ case WM_RBUTTONUP:
+ case WM_MOUSEWHEEL:
+ case WM_LBUTTONDBLCLK:
+ /*case WM_XBUTTONDOWN:
+ case WM_XBUTTONUP: */{
+
+ InputEvent event;
+ event.type=InputEvent::MOUSE_BUTTON;
+ event.ID=++last_id;
+ InputEventMouseButton &mb=event.mouse_button;
+
+ switch (uMsg) {
+ case WM_LBUTTONDOWN: {
+ mb.pressed=true;
+ mb.button_index=1;
+ } break;
+ case WM_LBUTTONUP: {
+ mb.pressed=false;
+ mb.button_index=1;
+ } break;
+ case WM_MBUTTONDOWN: {
+ mb.pressed=true;
+ mb.button_index=3;
+
+ } break;
+ case WM_MBUTTONUP: {
+ mb.pressed=false;
+ mb.button_index=3;
+ } break;
+ case WM_RBUTTONDOWN: {
+ mb.pressed=true;
+ mb.button_index=2;
+ } break;
+ case WM_RBUTTONUP: {
+ mb.pressed=false;
+ mb.button_index=2;
+ } break;
+ case WM_LBUTTONDBLCLK: {
+
+ mb.pressed=true;
+ mb.button_index=1;
+ mb.doubleclick = true;
+ } break;
+ case WM_MOUSEWHEEL: {
+
+ mb.pressed=true;
+ int motion = (short)HIWORD(wParam);
+ if (!motion)
+ return 0;
+
+
+ if (motion>0)
+ mb.button_index=4;
+ else
+ mb.button_index=5;
+
+
+ } break;
+ /*
+ case WM_XBUTTONDOWN: {
+ mb.pressed=true;
+ mb.button_index=(HIWORD(wParam)==XBUTTON1)?6:7;
+ } break;
+ case WM_XBUTTONUP:
+ mb.pressed=true;
+ mb.button_index=(HIWORD(wParam)==XBUTTON1)?6:7;
+ } break;*/
+ default: { return 0; }
+ }
+
+
+ mb.mod.control=(wParam&MK_CONTROL)!=0;
+ mb.mod.shift=(wParam&MK_SHIFT)!=0;
+ mb.mod.alt=alt_mem;
+ //mb.mod.alt=(wParam&MK_MENU)!=0;
+ mb.button_mask|=(wParam&MK_LBUTTON)?(1<<0):0;
+ mb.button_mask|=(wParam&MK_RBUTTON)?(1<<1):0;
+ mb.button_mask|=(wParam&MK_MBUTTON)?(1<<2):0;
+
+ last_button_state=mb.button_mask;
+ /*
+ mb.button_mask|=(wParam&MK_XBUTTON1)?(1<<5):0;
+ mb.button_mask|=(wParam&MK_XBUTTON2)?(1<<6):0;*/
+ mb.x=GET_X_LPARAM(lParam);
+ mb.y=GET_Y_LPARAM(lParam);
+
+ if (mouse_mode==MOUSE_MODE_CAPTURED) {
+
+ mb.x=old_x;
+ mb.y=old_y;
+ }
+
+ mb.global_x=mb.x;
+ mb.global_y=mb.y;
+
+
+ if (uMsg != WM_MOUSEWHEEL) {
+ if (mb.pressed) {
+
+ if (++pressrc>0)
+ SetCapture(hWnd);
+ } else {
+
+
+ if (--pressrc<=0) {
+ ReleaseCapture();
+ pressrc=0;
+ }
+
+ }
+ } else if (mouse_mode!=MOUSE_MODE_CAPTURED) {
+ // for reasons unknown to mankind, wheel comes in screen cordinates
+ RECT rect;
+ GetWindowRect(hWnd,&rect);
+ mb.x-=rect.left;
+ mb.y-=rect.top;
+
+ }
+
+ if (main_loop) {
+ input->parse_input_event(event);
+ if (mb.pressed && mb.button_index>3) {
+ //send release for mouse wheel
+ mb.pressed=false;
+ event.ID=++last_id;
+ input->parse_input_event(event);
+
+ }
+ }
+
+
+
+ } break;
+
+ case WM_SIZE: {
+ video_mode.width=LOWORD(lParam);
+ video_mode.height=HIWORD(lParam);
+ //return 0; // Jump Back
+ } break;
+ case WM_SYSKEYDOWN:
+ case WM_SYSKEYUP:
+ case WM_KEYUP:
+ case WM_KEYDOWN: {
+
+
+ if (wParam==VK_SHIFT)
+ shift_mem=uMsg==WM_KEYDOWN;
+ if (wParam==VK_CONTROL)
+ control_mem=uMsg==WM_KEYDOWN;
+ if (wParam==VK_MENU) {
+ alt_mem=(uMsg==WM_KEYDOWN || uMsg==WM_SYSKEYDOWN);
+ if (lParam&(1<<24))
+ gr_mem=alt_mem;
+ }
+
+ //if (wParam==VK_WIN) TODO wtf is this?
+ // meta_mem=uMsg==WM_KEYDOWN;
+
+
+ } //fallthrough
+ case WM_CHAR: {
+
+ ERR_BREAK(key_event_pos >= KEY_EVENT_BUFFER_SIZE);
+
+ KeyEvent ke;
+ ke.mod_state.shift=shift_mem;
+ ke.mod_state.alt=alt_mem;
+ ke.mod_state.control=control_mem;
+ ke.mod_state.meta=meta_mem;
+ ke.uMsg=uMsg;
+
+ if (ke.uMsg==WM_SYSKEYDOWN)
+ ke.uMsg=WM_KEYDOWN;
+ if (ke.uMsg==WM_SYSKEYUP)
+ ke.uMsg=WM_KEYUP;
+
+
+ /*if (ke.uMsg==WM_KEYDOWN && alt_mem && uMsg!=WM_SYSKEYDOWN) {
+ //altgr hack for intl keyboards, not sure how good it is
+ //windows is weeeeird
+ ke.mod_state.alt=false;
+ ke.mod_state.control=false;
+ print_line("")
+ }*/
+
+
+ ke.wParam=wParam;
+ ke.lParam=lParam;
+ key_event_buffer[key_event_pos++]=ke;
+
+ } break;
+ case WM_INPUTLANGCHANGEREQUEST: {
+
+ print_line("input lang change");
+ } break;
+ default: {
+
+ if (user_proc) {
+
+ return CallWindowProcW(user_proc, hWnd, uMsg, wParam, lParam);
+ };
+ };
+ }
+
+ return DefWindowProcW(hWnd,uMsg,wParam,lParam);
+
+}
+
+LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) {
+
+ OS_Windows *os_win = static_cast<OS_Windows*>(OS::get_singleton());
+ if (os_win)
+ return os_win->WndProc(hWnd,uMsg,wParam,lParam);
+ else
+ return DefWindowProcW(hWnd,uMsg,wParam,lParam);
+
+}
+
+void OS_Windows::probe_joysticks() {
+
+ int device_count = joyGetNumDevs();
+
+ JOYINFOEX jinfo;
+ jinfo.dwSize = sizeof(JOYINFOEX);
+ jinfo.dwFlags = JOY_RETURNALL;
+
+ for (int i=0; i<JOYSTICKS_MAX; i++) {
+
+ joysticks[i].attached = (device_count > 0) && (joyGetPosEx(JOYSTICKID1 + i, &jinfo) == JOYERR_NOERROR);
+
+ if (!joysticks[i].attached) {
+
+ continue;
+ };
+
+ joysticks[i].last_buttons = jinfo.dwButtons;
+
+ joysticks[i].last_axis[0] = jinfo.dwXpos;
+ joysticks[i].last_axis[1] = jinfo.dwYpos;
+ joysticks[i].last_axis[2] = jinfo.dwZpos;
+ joysticks[i].last_axis[3] = jinfo.dwRpos;
+ joysticks[i].last_axis[4] = jinfo.dwUpos;
+ joysticks[i].last_axis[5] = jinfo.dwVpos;
+ };
+};
+
+void OS_Windows::process_key_events() {
+
+ for(int i=0;i<key_event_pos;i++) {
+
+ KeyEvent &ke = key_event_buffer[i];
+ switch(ke.uMsg) {
+
+ case WM_CHAR: {
+
+ //do nothing
+ } break;
+ case WM_KEYUP:
+ case WM_KEYDOWN: {
+
+
+ InputEvent event;
+ event.type=InputEvent::KEY;
+ event.ID=++last_id;
+ InputEventKey &k=event.key;
+
+
+ k.mod=ke.mod_state;
+ k.pressed=(ke.uMsg==WM_KEYDOWN);
+
+ k.scancode=KeyMappingWindows::get_keysym(ke.wParam);
+ if (i+1 < key_event_pos && key_event_buffer[i+1].uMsg==WM_CHAR)
+ k.unicode=key_event_buffer[i+1].wParam;
+ if (k.unicode && gr_mem) {
+ k.mod.alt=false;
+ k.mod.control=false;
+ }
+
+ if (k.unicode<32)
+ k.unicode=0;
+
+
+
+ k.echo=(ke.uMsg==WM_KEYDOWN && (ke.lParam&(1<<30)));
+
+ input->parse_input_event(event);
+
+
+ } break;
+ }
+ }
+
+ key_event_pos=0;
+}
+
+void OS_Windows::_post_dpad(DWORD p_dpad, int p_device, bool p_pressed) {
+
+ InputEvent ievent;
+ ievent.device = p_device;
+ ievent.type = InputEvent::JOYSTICK_BUTTON;
+ ievent.joy_button.pressed = p_pressed;
+ ievent.joy_button.pressure = p_pressed ? 1.0 : 0.0;
+
+ if (p_dpad == 0) {
+
+ ievent.joy_button.button_index = JOY_DPAD_UP;
+ ievent.ID = ++last_id;
+ input->parse_input_event(ievent);
+
+ } else if (p_dpad == 4500) {
+
+ ievent.joy_button.button_index = JOY_DPAD_UP;
+ ievent.ID = ++last_id;
+ input->parse_input_event(ievent);
+
+ ievent.joy_button.button_index = JOY_DPAD_RIGHT;
+ ievent.ID = ++last_id;
+ input->parse_input_event(ievent);
+
+ } else if (p_dpad == 9000) {
+
+ ievent.joy_button.button_index = JOY_DPAD_RIGHT;
+ ievent.ID = ++last_id;
+ input->parse_input_event(ievent);
+
+ } else if (p_dpad == 13500) {
+
+ ievent.joy_button.button_index = JOY_DPAD_RIGHT;
+ ievent.ID = ++last_id;
+ input->parse_input_event(ievent);
+
+ ievent.joy_button.button_index = JOY_DPAD_DOWN;
+ ievent.ID = ++last_id;
+ input->parse_input_event(ievent);
+
+ } else if (p_dpad == 18000) {
+
+ ievent.joy_button.button_index = JOY_DPAD_DOWN;
+ ievent.ID = ++last_id;
+ input->parse_input_event(ievent);
+
+ } else if (p_dpad == 22500) {
+
+ ievent.joy_button.button_index = JOY_DPAD_DOWN;
+ ievent.ID = ++last_id;
+ input->parse_input_event(ievent);
+
+ ievent.joy_button.button_index = JOY_DPAD_LEFT;
+ ievent.ID = ++last_id;
+ input->parse_input_event(ievent);
+
+ } else if (p_dpad == 27000) {
+
+ ievent.joy_button.button_index = JOY_DPAD_LEFT;
+ ievent.ID = ++last_id;
+ input->parse_input_event(ievent);
+
+ } else if (p_dpad == 31500) {
+
+ ievent.joy_button.button_index = JOY_DPAD_LEFT;
+ ievent.ID = ++last_id;
+ input->parse_input_event(ievent);
+
+ ievent.joy_button.button_index = JOY_DPAD_UP;
+ ievent.ID = ++last_id;
+ input->parse_input_event(ievent);
+ };
+};
+
+void OS_Windows::process_joysticks() {
+
+ if (!main_loop) {
+ return;
+ };
+
+ InputEvent ievent;
+
+ JOYINFOEX jinfo;
+ jinfo.dwSize = sizeof(JOYINFOEX);
+ jinfo.dwFlags = JOY_RETURNALL;
+
+ for (int i=0; i<JOYSTICKS_MAX; i++) {
+
+ if (!joysticks[i].attached) {
+ continue;
+ };
+
+ if (joyGetPosEx(JOYSTICKID1 + i, &jinfo) != JOYERR_NOERROR) {
+
+ continue;
+ };
+
+ ievent.device = i;
+
+ #define CHECK_AXIS(n, var) \
+ if (joysticks[i].last_axis[n] != var) {\
+ ievent.type = InputEvent::JOYSTICK_MOTION;\
+ ievent.ID = ++last_id;\
+ ievent.joy_motion.axis = n;\
+ ievent.joy_motion.axis_value = (float)((int)var - MAX_JOY_AXIS) / (float)MAX_JOY_AXIS;\
+ joysticks[i].last_axis[n] = var;\
+ input->parse_input_event(ievent);\
+ };
+
+ CHECK_AXIS(0, jinfo.dwXpos);
+ CHECK_AXIS(1, jinfo.dwYpos);
+ CHECK_AXIS(2, jinfo.dwZpos);
+ CHECK_AXIS(3, jinfo.dwRpos);
+ CHECK_AXIS(4, jinfo.dwUpos);
+ CHECK_AXIS(5, jinfo.dwVpos);
+
+ if (joysticks[i].last_pov != jinfo.dwPOV) {
+
+ if (joysticks[i].last_pov != JOY_POVCENTERED)
+ _post_dpad(joysticks[i].last_pov, i, false);
+
+ if (jinfo.dwPOV != JOY_POVCENTERED)
+ _post_dpad(jinfo.dwPOV, i, true);
+
+ joysticks[i].last_pov = jinfo.dwPOV;
+ };
+
+ if (joysticks[i].last_buttons == jinfo.dwButtons) {
+ continue;
+ };
+
+ ievent.type = InputEvent::JOYSTICK_BUTTON;
+ for (int j=0; j<32; j++) {
+
+ if ( (joysticks[i].last_buttons & (1<<j)) != (jinfo.dwButtons & (1<<j)) ) {
+
+ ievent.joy_button.button_index = _pc_joystick_get_native_button(j);
+ ievent.joy_button.pressed = jinfo.dwButtons & 1<<j;
+ ievent.ID = ++last_id;
+ input->parse_input_event(ievent);
+ };
+ };
+
+ joysticks[i].last_buttons = jinfo.dwButtons;
+ };
+};
+
+void OS_Windows::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) {
+
+
+
+ main_loop=NULL;
+ outside=true;
+
+ WNDCLASSEXW wc;
+
+ video_mode=p_desired;
+ //printf("**************** desired %s, mode %s\n", p_desired.fullscreen?"true":"false", video_mode.fullscreen?"true":"false");
+ RECT WindowRect;
+
+ WindowRect.left=0;
+ WindowRect.right=video_mode.width;
+ WindowRect.top=0;
+ WindowRect.bottom=video_mode.height;
+
+ memset(&wc,0,sizeof(WNDCLASSEXW));
+ wc.cbSize=sizeof(WNDCLASSEXW);
+ wc.style= CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
+ wc.lpfnWndProc = (WNDPROC)::WndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra= 0;
+ //wc.hInstance = hInstance;
+ wc.hInstance = godot_hinstance ? godot_hinstance : GetModuleHandle(NULL);
+ wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
+ wc.hCursor = NULL;//LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = NULL;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = L"Engine";
+
+ if (!RegisterClassExW(&wc)) {
+ MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
+ return; // Return
+ }
+
+
+ if (video_mode.fullscreen) {
+
+ DEVMODE current;
+ memset(&current,0,sizeof(current));
+ EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &current);
+
+ DEVMODE dmScreenSettings;
+ memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
+ dmScreenSettings.dmSize=sizeof(dmScreenSettings);
+ dmScreenSettings.dmPelsWidth = video_mode.width;
+ dmScreenSettings.dmPelsHeight = video_mode.height;
+ dmScreenSettings.dmBitsPerPel = current.dmBitsPerPel;
+ dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
+
+ LONG err = ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN);
+ if (err!=DISP_CHANGE_SUCCESSFUL) {
+
+ video_mode.fullscreen=false;
+ }
+ }
+
+ DWORD dwExStyle;
+ DWORD dwStyle;
+
+ if (video_mode.fullscreen) {
+
+ dwExStyle=WS_EX_APPWINDOW;
+ dwStyle=WS_POPUP;
+
+ } else {
+ dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
+ dwStyle=WS_OVERLAPPEDWINDOW;
+ }
+
+ AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);
+
+
+ char* windowid = getenv("GODOT_WINDOWID");
+ if (windowid) {
+
+ // strtoull on mingw
+ #ifdef MINGW_ENABLED
+ hWnd = (HWND)strtoull(windowid, NULL, 0);
+ #else
+ hWnd = (HWND)_strtoui64(windowid, NULL, 0);
+ #endif
+ SetLastError(0);
+ user_proc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_WNDPROC);
+ SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)(WNDPROC)::WndProc);
+ DWORD le = GetLastError();
+ if (user_proc == 0 && le != 0) {
+
+ printf("Error setting WNDPROC: %li\n", le);
+ };
+ LONG_PTR proc = GetWindowLongPtr(hWnd, GWLP_WNDPROC);
+
+ RECT rect;
+ if (!GetClientRect(hWnd, &rect)) {
+ MessageBoxW(NULL,L"Window Creation Error.",L"ERROR",MB_OK|MB_ICONEXCLAMATION);
+ return; // Return FALSE
+ };
+ video_mode.width = rect.right;
+ video_mode.height = rect.bottom;
+ video_mode.fullscreen = false;
+ } else {
+
+ if (!(hWnd=CreateWindowExW(dwExStyle,L"Engine",L"", dwStyle|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, 0, 0,WindowRect.right-WindowRect.left,WindowRect.bottom-WindowRect.top, NULL,NULL, hInstance,NULL))) {
+ MessageBoxW(NULL,L"Window Creation Error.",L"ERROR",MB_OK|MB_ICONEXCLAMATION);
+ return; // Return FALSE
+ }
+
+
+ };
+
+#if defined(OPENGL_ENABLED) || defined(GLES2_ENABLED) || defined(LEGACYGL_ENABLED)
+ gl_context = memnew( ContextGL_Win(hWnd,false) );
+ gl_context->initialize();
+ rasterizer = memnew( RasterizerGLES2 );
+#else
+ #ifdef DX9_ENABLED
+ rasterizer = memnew( RasterizerDX9(hWnd) );
+ #endif
+#endif
+
+ visual_server = memnew( VisualServerRaster(rasterizer) );
+ if (get_render_thread_mode()!=RENDER_THREAD_UNSAFE) {
+
+ visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD));
+ }
+
+ //
+ physics_server = memnew( PhysicsServerSW );
+ physics_server->init();
+
+ physics_2d_server = memnew( Physics2DServerSW );
+ physics_2d_server->init();
+
+ if (!is_no_window_mode_enabled()) {
+ ShowWindow(hWnd,SW_SHOW); // Show The Window
+ SetForegroundWindow(hWnd); // Slightly Higher Priority
+ SetFocus(hWnd); // Sets Keyboard Focus To
+ }
+
+/*
+ DEVMODE dmScreenSettings; // Device Mode
+ memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared
+ dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The Devmode Structure
+ dmScreenSettings.dmPelsWidth = width; // Selected Screen Width
+ dmScreenSettings.dmPelsHeight = height; // Selected Screen Height
+ dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel
+ dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
+ if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
+
+
+
+
+ */
+ visual_server->init();
+
+ input = memnew( InputDefault );
+
+ AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton();
+
+ if (AudioDriverManagerSW::get_driver(p_audio_driver)->init()!=OK) {
+
+ ERR_PRINT("Initializing audio failed.");
+ }
+
+ sample_manager = memnew( SampleManagerMallocSW );
+ audio_server = memnew( AudioServerSW(sample_manager) );
+
+ audio_server->init();
+
+ spatial_sound_server = memnew( SpatialSoundServerSW );
+ spatial_sound_server->init();
+ spatial_sound_2d_server = memnew( SpatialSound2DServerSW );
+ spatial_sound_2d_server->init();
+
+ probe_joysticks();
+
+ TRACKMOUSEEVENT tme;
+ tme.cbSize=sizeof(TRACKMOUSEEVENT);
+ tme.dwFlags=TME_LEAVE;
+ tme.hwndTrack=hWnd;
+ tme.dwHoverTime=HOVER_DEFAULT;
+ TrackMouseEvent(&tme);
+
+
+ _ensure_data_dir();
+
+
+}
+
+void OS_Windows::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();
+};
+
+String OS_Windows::get_clipboard() const {
+
+ String ret;
+ if (!OpenClipboard(hWnd)) {
+ ERR_EXPLAIN("Unable to open clipboard.");
+ ERR_FAIL_V("");
+ };
+
+ if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
+
+ HGLOBAL mem = GetClipboardData(CF_UNICODETEXT);
+ if (mem != NULL) {
+
+ LPWSTR ptr = (LPWSTR)GlobalLock(mem);
+ if (ptr != NULL) {
+
+ ret = String((CharType*)ptr);
+ GlobalUnlock(mem);
+ };
+ };
+
+ } else if (IsClipboardFormatAvailable(CF_TEXT)) {
+
+ HGLOBAL mem = GetClipboardData(CF_UNICODETEXT);
+ if (mem != NULL) {
+
+ LPTSTR ptr = (LPTSTR)GlobalLock(mem);
+ if (ptr != NULL) {
+
+ ret.parse_utf8((const char*)ptr);
+ GlobalUnlock(mem);
+ };
+ };
+ };
+
+ CloseClipboard();
+
+ return ret;
+};
+
+
+void OS_Windows::delete_main_loop() {
+
+ if (main_loop)
+ memdelete(main_loop);
+ main_loop=NULL;
+}
+
+void OS_Windows::set_main_loop( MainLoop * p_main_loop ) {
+
+ input->set_main_loop(p_main_loop);
+ main_loop=p_main_loop;
+}
+
+void OS_Windows::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
+ if (rasterizer)
+ memdelete(rasterizer);
+
+ if (user_proc) {
+ SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)user_proc);
+ };
+
+ spatial_sound_server->finish();
+ memdelete(spatial_sound_server);
+ spatial_sound_2d_server->finish();
+ memdelete(spatial_sound_2d_server);
+
+ //if (debugger_connection_console) {
+// memdelete(debugger_connection_console);
+//}
+
+ audio_server->finish();
+ memdelete(audio_server);
+ memdelete(sample_manager);
+
+ memdelete(input);
+
+ physics_server->finish();
+ memdelete(physics_server);
+
+ physics_2d_server->finish();
+ memdelete(physics_2d_server);
+
+}
+void OS_Windows::finalize_core() {
+
+ memdelete(process_map);
+
+ if (mempool_dynamic)
+ memdelete( mempool_dynamic );
+ if (mempool_static)
+ delete mempool_static;
+
+
+ TCPServerWinsock::cleanup();
+ StreamPeerWinsock::cleanup();
+}
+
+void OS_Windows::vprint(const char* p_format, va_list p_list, bool p_stderr) {
+
+ char buf[16384+1];
+ int len = vsnprintf(buf,16384,p_format,p_list);
+ if (len<=0)
+ return;
+ buf[len]=0;
+
+
+ int wlen = MultiByteToWideChar(CP_UTF8,0,buf,len,NULL,0);
+ if (wlen<0)
+ return;
+
+ wchar_t *wbuf = (wchar_t*)malloc((len+1)*sizeof(wchar_t));
+ MultiByteToWideChar(CP_UTF8,0,buf,len,wbuf,wlen);
+ wbuf[wlen]=0;
+
+ if (p_stderr)
+ fwprintf(stderr,L"%s",wbuf);
+ else
+ wprintf(L"%s",wbuf);
+
+#ifdef STDOUT_FILE
+ //vwfprintf(stdo,p_format,p_list);
+#endif
+ free(wbuf);
+
+ fflush(stdout);
+};
+
+void OS_Windows::alert(const String& p_alert,const String& p_title) {
+
+ if (!is_no_window_mode_enabled())
+ MessageBoxW(NULL,p_alert.c_str(),p_title.c_str(),MB_OK|MB_ICONEXCLAMATION);
+ else
+ print_line("ALERT: "+p_alert);
+}
+
+void OS_Windows::set_mouse_mode(MouseMode p_mode) {
+
+ if (mouse_mode==p_mode)
+ return;
+ ShowCursor(p_mode==MOUSE_MODE_VISIBLE);
+ mouse_mode=p_mode;
+ if (p_mode==MOUSE_MODE_CAPTURED) {
+ RECT clipRect;
+ GetClientRect(hWnd, &clipRect);
+ ClientToScreen(hWnd, (POINT*) &clipRect.left);
+ ClientToScreen(hWnd, (POINT*) &clipRect.right);
+ ClipCursor(&clipRect);
+ SetCapture(hWnd);
+ center=Point2i(video_mode.width/2,video_mode.height/2);
+ POINT pos = { (int) center.x, (int) center.y };
+ ClientToScreen(hWnd, &pos);
+ SetCursorPos(pos.x, pos.y);
+ } else {
+ ReleaseCapture();
+ ClipCursor(NULL);
+ }
+
+}
+
+OS_Windows::MouseMode OS_Windows::get_mouse_mode() const{
+
+ return mouse_mode;
+}
+
+
+
+Point2 OS_Windows::get_mouse_pos() const {
+
+ return Point2(old_x, old_y);
+}
+
+int OS_Windows::get_mouse_button_state() const {
+
+ return last_button_state;
+}
+
+void OS_Windows::set_window_title(const String& p_title) {
+
+ SetWindowTextW(hWnd,p_title.c_str());
+}
+
+void OS_Windows::set_video_mode(const VideoMode& p_video_mode,int p_screen) {
+
+
+}
+OS::VideoMode OS_Windows::get_video_mode(int p_screen) const {
+
+ return video_mode;
+}
+void OS_Windows::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) const {
+
+
+}
+
+void OS_Windows::print_error(const char* p_function,const char* p_file,int p_line,const char *p_code,const char*p_rationale,ErrorType p_type) {
+
+ HANDLE hCon=GetStdHandle(STD_OUTPUT_HANDLE);
+ if (!hCon || hCon==INVALID_HANDLE_VALUE) {
+ if (p_rationale && p_rationale[0]) {
+
+ print("\E[1;31;40mERROR: %s: \E[1;37;40m%s\n",p_function,p_rationale);
+ print("\E[0;31;40m At: %s:%i.\E[0;0;37m\n",p_file,p_line);
+
+ } else {
+ print("\E[1;31;40mERROR: %s: \E[1;37;40m%s\n",p_function,p_code);
+ print("\E[0;31;40m At: %s:%i.\E[0;0;37m\n",p_file,p_line);
+
+ }
+ } else {
+
+ CONSOLE_SCREEN_BUFFER_INFO sbi; //original
+ GetConsoleScreenBufferInfo(hCon,&sbi);
+
+ SetConsoleTextAttribute(hCon,sbi.wAttributes);
+
+
+
+ uint32_t basecol=0;
+ switch(p_type) {
+ case ERR_ERROR: basecol = FOREGROUND_RED; break;
+ case ERR_WARNING: basecol = FOREGROUND_RED|FOREGROUND_GREEN; break;
+ case ERR_SCRIPT: basecol = FOREGROUND_GREEN; break;
+ }
+
+ if (p_rationale && p_rationale[0]) {
+
+ SetConsoleTextAttribute(hCon,basecol|FOREGROUND_INTENSITY);
+
+
+ switch(p_type) {
+ case ERR_ERROR: print("ERROR: "); break;
+ case ERR_WARNING: print("WARNING: "); break;
+ case ERR_SCRIPT: print("SCRIPT ERROR: "); break;
+ }
+
+ SetConsoleTextAttribute(hCon,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY);
+ print(" %s\n",p_rationale);
+ SetConsoleTextAttribute(hCon,basecol);
+ print("At: ");
+ SetConsoleTextAttribute(hCon,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN);
+ print(" %s:%i\n",p_file,p_line);
+
+
+ } else {
+ SetConsoleTextAttribute(hCon,basecol|FOREGROUND_INTENSITY);
+ switch(p_type) {
+ case ERR_ERROR: print("ERROR: %s: ",p_function); break;
+ case ERR_WARNING: print("WARNING: %s: ",p_function); break;
+ case ERR_SCRIPT: print("SCRIPT ERROR: %s: ",p_function); break;
+ }
+ SetConsoleTextAttribute(hCon,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY);
+ print(" %s\n",p_code);
+ SetConsoleTextAttribute(hCon,basecol);
+ print("At: ");
+ SetConsoleTextAttribute(hCon,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN);
+ print(" %s:%i\n",p_file,p_line);
+ }
+
+ SetConsoleTextAttribute(hCon,sbi.wAttributes);
+ }
+
+}
+
+
+String OS_Windows::get_name() {
+
+ return "Windows";
+}
+
+OS::Date OS_Windows::get_date() const {
+
+ SYSTEMTIME systemtime;
+ GetSystemTime(&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_Windows::get_time() const {
+
+ SYSTEMTIME systemtime;
+ GetSystemTime(&systemtime);
+
+ Time time;
+ time.hour=systemtime.wHour;
+ time.min=systemtime.wMinute;
+ time.sec=systemtime.wSecond;
+ return time;
+}
+
+uint64_t OS_Windows::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_Windows::delay_usec(uint32_t p_usec) const {
+
+ if (p_usec < 1000)
+ Sleep(1);
+ else
+ Sleep(p_usec / 1000);
+
+}
+uint64_t OS_Windows::get_ticks_usec() const {
+
+ uint64_t ticks;
+ uint64_t time;
+ // This is the number of clock ticks since start
+ if( !QueryPerformanceCounter((LARGE_INTEGER *)&ticks) )
+ ticks = (UINT64)timeGetTime();
+ // Divide by frequency to get the time in seconds
+ time = ticks * 1000000L / ticks_per_second;
+ // Subtract the time at game start to get
+ // the time since the game started
+ time -= ticks_start;
+ return time;
+}
+
+
+void OS_Windows::process_events() {
+
+ MSG msg;
+
+ process_joysticks();
+
+ while(PeekMessageW(&msg,NULL,0,0,PM_REMOVE)) {
+
+
+ TranslateMessage(&msg);
+ DispatchMessageW(&msg);
+
+ }
+
+ process_key_events();
+
+}
+
+void OS_Windows::set_cursor_shape(CursorShape p_shape) {
+
+ ERR_FAIL_INDEX(p_shape,CURSOR_MAX);
+
+ if (cursor_shape==p_shape)
+ return;
+
+ static const LPCTSTR win_cursors[CURSOR_MAX]={
+ IDC_ARROW,
+ IDC_IBEAM,
+ IDC_HAND,//finger
+ IDC_CROSS,
+ IDC_WAIT,
+ IDC_APPSTARTING,
+ IDC_ARROW,
+ IDC_ARROW,
+ IDC_NO,
+ IDC_SIZENS,
+ IDC_SIZEWE,
+ IDC_SIZENESW,
+ IDC_SIZENWSE,
+ IDC_SIZEALL,
+ IDC_SIZENS,
+ IDC_SIZEWE,
+ IDC_HELP
+ };
+
+ SetCursor(LoadCursor(hInstance,win_cursors[p_shape]));
+ cursor_shape=p_shape;
+}
+
+Error OS_Windows::execute(const String& p_path, const List<String>& p_arguments,bool p_blocking,ProcessID *r_child_id,String* r_pipe,int *r_exitcode) {
+
+ if (p_blocking && r_pipe) {
+
+
+ String argss;
+ argss="\"\""+p_path+"\"";
+
+ for(int i=0;i<p_arguments.size();i++) {
+
+ argss+=String(" \"")+p_arguments[i]+"\"";
+ }
+
+// print_line("ARGS: "+argss);
+ //argss+"\"";
+ //argss+=" 2>nul";
+
+ FILE* f=_wpopen(argss.c_str(),L"r");
+
+ ERR_FAIL_COND_V(!f,ERR_CANT_OPEN);
+
+ char buf[65535];
+ while(fgets(buf,65535,f)) {
+
+ (*r_pipe)+=buf;
+ }
+
+ int rv = _pclose(f);
+ if (r_exitcode)
+ *r_exitcode=rv;
+
+ return OK;
+ }
+
+ String cmdline = "\""+p_path+"\"";
+ const List<String>::Element* I = p_arguments.front();
+ while (I) {
+
+
+ cmdline += " \""+I->get() + "\"";
+
+ I = I->next();
+ };
+
+ //cmdline+="\"";
+
+ ProcessInfo pi;
+ ZeroMemory( &pi.si, sizeof(pi.si) );
+ pi.si.cb = sizeof(pi.si);
+ ZeroMemory( &pi.pi, sizeof(pi.pi) );
+
+ print_line("running cmdline: "+cmdline);
+
+ int ret = CreateProcess(NULL, (LPSTR)cmdline.utf8().get_data(), NULL, NULL, 0, NORMAL_PRIORITY_CLASS, NULL, NULL, &pi.si, &pi.pi);
+ ERR_FAIL_COND_V(ret == 0, ERR_CANT_FORK);
+
+ if (p_blocking) {
+
+ DWORD ret = WaitForSingleObject(pi.pi.hProcess, INFINITE);
+ if (r_exitcode)
+ *r_exitcode=ret;
+
+ } else {
+
+ ProcessID pid = pi.pi.dwProcessId;
+ if (r_child_id) {
+ *r_child_id = pid;
+ };
+ process_map->insert(pid, pi);
+ };
+ return OK;
+};
+
+Error OS_Windows::kill(const ProcessID& p_pid) {
+
+ HANDLE h;
+
+ if (process_map->has(p_pid)) {
+ h = (*process_map)[p_pid].pi.hProcess;
+ process_map->erase(p_pid);
+ } else {
+
+ ERR_FAIL_COND_V(!process_map->has(p_pid), FAILED);
+ };
+
+ int ret = TerminateProcess(h, 0);
+
+ return ret != 0?OK:FAILED;
+};
+
+Error OS_Windows::set_cwd(const String& p_cwd) {
+
+ if (_wchdir(p_cwd.c_str())!=0)
+ return ERR_CANT_OPEN;
+
+ return OK;
+}
+
+void OS_Windows::set_icon(const Image& p_icon) {
+
+
+ Image icon=p_icon;
+ if (icon.get_format()!=Image::FORMAT_RGBA)
+ icon.convert(Image::FORMAT_RGBA);
+ int w = icon.get_width();
+ int h = icon.get_height();
+
+ /* Create temporary bitmap buffer */
+ int icon_len = 40 + h * w * 4;
+ BYTE *icon_bmp = (BYTE*)alloca(icon_len);
+
+ encode_uint32(40,&icon_bmp[0]);
+ encode_uint32(w,&icon_bmp[4]);
+ encode_uint32(h*2,&icon_bmp[8]);
+ encode_uint16(1,&icon_bmp[12]);
+ encode_uint16(32,&icon_bmp[14]);
+ encode_uint32(BI_RGB,&icon_bmp[16]);
+ encode_uint32(w*h*4,&icon_bmp[20]);
+ encode_uint32(0,&icon_bmp[24]);
+ encode_uint32(0,&icon_bmp[28]);
+ encode_uint32(0,&icon_bmp[32]);
+ encode_uint32(0,&icon_bmp[36]);
+
+ uint8_t *wr=&icon_bmp[40];
+ DVector<uint8_t>::Read r= icon.get_data().read();
+
+ for(int i=0;i<h;i++) {
+
+ for(int j=0;j<w;j++) {
+
+ const uint8_t *rpx = &r[((h-i-1)*w+j)*4];
+ uint8_t *wpx = &wr[(i*w+j)*4];
+ wpx[0]=rpx[2];
+ wpx[1]=rpx[1];
+ wpx[2]=rpx[0];
+ wpx[3]=rpx[3];
+ }
+ }
+
+
+ HICON hicon = CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000);
+
+ /* Set the icon for the window */
+ SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon);
+
+ /* Set the icon in the task manager (should we do this?) */
+ SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM) hicon);
+}
+
+
+bool OS_Windows::has_environment(const String& p_var) const {
+
+ return getenv(p_var.utf8().get_data()) != NULL;
+};
+
+String OS_Windows::get_environment(const String& p_var) const {
+
+ return getenv(p_var.utf8().get_data());
+};
+
+String OS_Windows::get_stdin_string(bool p_block) {
+
+ if (p_block) {
+ char buff[1024];
+ return fgets(buff,1024,stdin);
+ };
+
+ return String();
+}
+
+
+void OS_Windows::move_window_to_foreground() {
+
+ SetForegroundWindow(hWnd);
+
+}
+
+String OS_Windows::get_locale() const {
+
+ const _WinLocale *wl = &_win_locales[0];
+
+ LANGID langid = GetUserDefaultUILanguage();
+ String neutral;
+ int lang = langid&((1<<9)-1);
+ int sublang = langid&~((1<<9)-1);
+
+ while(wl->locale) {
+
+ if (wl->main_lang==lang && wl->sublang==SUBLANG_NEUTRAL)
+ neutral=wl->locale;
+
+ if (lang==wl->main_lang && sublang==wl->sublang)
+ return wl->locale;
+
+
+ wl++;
+ }
+
+ if (neutral!="")
+ return neutral;
+
+ return "en";
+}
+
+void OS_Windows::release_rendering_thread() {
+
+ gl_context->release_current();
+
+}
+
+void OS_Windows::make_rendering_thread() {
+
+ gl_context->make_current();
+}
+
+void OS_Windows::swap_buffers() {
+
+ gl_context->swap_buffers();
+}
+
+
+void OS_Windows::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) {
+
+ process_events(); // get rid of pending events
+ if (Main::iteration()==true)
+ break;
+ };
+
+ main_loop->finish();
+
+}
+
+
+
+MainLoop *OS_Windows::get_main_loop() const {
+
+ return main_loop;
+}
+
+
+String OS_Windows::get_data_dir() const {
+
+ String an = Globals::get_singleton()->get("application/name");
+ if (an!="") {
+
+ if (has_environment("APPDATA")) {
+
+ return OS::get_singleton()->get_environment("APPDATA")+"\\"+an;
+ }
+ }
+
+ return Globals::get_singleton()->get_resource_path();
+
+
+}
+
+
+OS_Windows::OS_Windows(HINSTANCE _hInstance) {
+
+ key_event_pos=0;
+ force_quit=false;
+ alt_mem=false;
+ gr_mem=false;
+ shift_mem=false;
+ control_mem=false;
+ meta_mem=false;
+ minimized = false;
+
+ hInstance=_hInstance;
+ pressrc=0;
+ old_invalid=true;
+ last_id=0;
+ mouse_mode=MOUSE_MODE_VISIBLE;
+#ifdef STDOUT_FILE
+ stdo=fopen("stdout.txt","wb");
+#endif
+ user_proc = NULL;
+
+#ifdef RTAUDIO_ENABLED
+ AudioDriverManagerSW::add_driver(&driver_rtaudio);
+#endif
+
+}
+
+
+OS_Windows::~OS_Windows()
+{
+#ifdef STDOUT_FILE
+ fclose(stdo);
+#endif
+}
+
+
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
new file mode 100644
index 0000000000..5587d89763
--- /dev/null
+++ b/platform/windows/os_windows.h
@@ -0,0 +1,257 @@
+/*************************************************************************/
+/* os_windows.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 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 OS_WINDOWS_H
+#define OS_WINDOWS_H
+
+#define WINVER 0x0500
+
+#include "os/input.h"
+#include "os/os.h"
+#include "context_gl_win.h"
+#include "servers/visual_server.h"
+#include "servers/visual/rasterizer.h"
+#include "servers/physics/physics_server_sw.h"
+
+#include "servers/audio/audio_server_sw.h"
+#include "servers/audio/sample_manager_sw.h"
+#include "drivers/rtaudio/audio_driver_rtaudio.h"
+#include "servers/spatial_sound/spatial_sound_server_sw.h"
+#include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h"
+#include "drivers/unix/ip_unix.h"
+#include "servers/physics_2d/physics_2d_server_sw.h"
+
+
+#include <windows.h>
+
+#include "key_mapping_win.h"
+#include <windowsx.h>
+#include <io.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+/**
+ @author Juan Linietsky <reduzio@gmail.com>
+*/
+class OS_Windows : public OS {
+
+ enum {
+ JOYSTICKS_MAX = 8,
+ JOY_AXIS_COUNT = 6,
+ MAX_JOY_AXIS = 32768, // I've no idea
+ KEY_EVENT_BUFFER_SIZE=512
+ };
+
+ 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;
+
+
+ uint64_t ticks_start;
+ uint64_t ticks_per_second;
+
+ bool minimized;
+ bool old_invalid;
+ bool outside;
+ int old_x,old_y;
+ Point2i center;
+ unsigned int last_id;
+#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) || defined(GLES2_ENABLED)
+ ContextGL_Win *gl_context;
+#endif
+ VisualServer *visual_server;
+ Rasterizer *rasterizer;
+ PhysicsServer *physics_server;
+ Physics2DServer *physics_2d_server;
+ int pressrc;
+ HDC hDC; // Private GDI Device Context
+ HINSTANCE hInstance; // Holds The Instance Of The Application
+ HWND hWnd;
+
+ struct Joystick {
+
+ bool attached;
+
+ DWORD last_axis[JOY_AXIS_COUNT];
+ DWORD last_buttons;
+ DWORD last_pov;
+
+ Joystick() {
+ attached = false;
+ for (int i=0; i<JOY_AXIS_COUNT; i++) {
+
+ last_axis[i] = 0;
+ };
+ last_buttons = 0;
+ last_pov = 0;
+ };
+ };
+
+ int joystick_count;
+ Joystick joysticks[JOYSTICKS_MAX];
+
+ VideoMode video_mode;
+
+ MainLoop *main_loop;
+
+ WNDPROC user_proc;
+
+ AudioServerSW *audio_server;
+ SampleManagerMallocSW *sample_manager;
+ SpatialSoundServerSW *spatial_sound_server;
+ SpatialSound2DServerSW *spatial_sound_2d_server;
+
+ 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;
+
+#ifdef RTAUDIO_ENABLED
+ AudioDriverRtAudio driver_rtaudio;
+#endif
+
+ void _post_dpad(DWORD p_dpad, int p_device, bool p_pressed);
+
+ // functions used by main to initialize/deintialize the OS
+protected:
+ virtual int get_video_driver_count() const;
+ virtual const char * get_video_driver_name(int p_driver) const;
+
+ virtual VideoMode get_default_video_mode() const;
+
+ virtual int get_audio_driver_count() const;
+ virtual const char * get_audio_driver_name(int p_driver) const;
+
+ virtual void initialize_core();
+ virtual void 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 probe_joysticks();
+ void process_joysticks();
+ void process_key_events();
+
+ struct ProcessInfo {
+
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ };
+ Map<ProcessID, ProcessInfo>* process_map;
+
+public:
+ LRESULT WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+
+ 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);
+ 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_pos() 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 MainLoop *get_main_loop() const;
+
+ virtual String get_name();
+
+ virtual Date get_date() const;
+ virtual Time get_time() 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,ProcessID *r_child_id=NULL,String* r_pipe=NULL,int *r_exitcode=NULL);
+ 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 void set_clipboard(const String& p_text);
+ virtual String get_clipboard() const;
+
+ void set_cursor_shape(CursorShape p_shape);
+ void set_icon(const Image& p_icon);
+
+
+ virtual String get_locale() const;
+
+ virtual void move_window_to_foreground();
+ virtual String get_data_dir() const;
+
+ virtual void release_rendering_thread();
+ virtual void make_rendering_thread();
+ virtual void swap_buffers();
+
+ void run();
+
+ virtual bool get_swap_ok_cancel() { return true; }
+
+ OS_Windows(HINSTANCE _hInstance);
+ ~OS_Windows();
+
+};
+
+#endif
diff --git a/platform/windows/platform_config.h b/platform/windows/platform_config.h
new file mode 100644
index 0000000000..7bc3e42833
--- /dev/null
+++ b/platform/windows/platform_config.h
@@ -0,0 +1,35 @@
+/*************************************************************************/
+/* platform_config.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 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 <malloc.h>
+//#else
+//#include <alloca.h>
+//#endif
+#define GLES2_INCLUDE_H "gl_context/glew.h"
+#define GLES1_INCLUDE_H "gl_context/glew.h"
+
diff --git a/platform/windows/stream_peer_winsock.cpp b/platform/windows/stream_peer_winsock.cpp
new file mode 100644
index 0000000000..2c3a8db7b1
--- /dev/null
+++ b/platform/windows/stream_peer_winsock.cpp
@@ -0,0 +1,368 @@
+/*************************************************************************/
+/* stream_peer_winsock.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 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. */
+/*************************************************************************/
+#ifdef WINDOWS_ENABLED
+
+#include "stream_peer_winsock.h"
+
+#include <winsock2.h>
+
+int winsock_refcount = 0;
+
+static void set_addr_in(struct sockaddr_in& their_addr, const IP_Address& p_host, uint16_t p_port) {
+
+ their_addr.sin_family = AF_INET; // host byte order
+ their_addr.sin_port = htons(p_port); // short, network byte order
+ their_addr.sin_addr = *((struct in_addr*)&p_host.host);
+ memset(&(their_addr.sin_zero), '\0', 8);
+};
+
+StreamPeerTCP* StreamPeerWinsock::_create() {
+
+ return memnew(StreamPeerWinsock);
+};
+
+void StreamPeerWinsock::make_default() {
+
+ StreamPeerTCP::_create = StreamPeerWinsock::_create;
+
+ if (winsock_refcount == 0) {
+ WSADATA data;
+ WSAStartup(MAKEWORD(2,2), &data);
+ };
+ ++winsock_refcount;
+};
+
+void StreamPeerWinsock::cleanup() {
+
+ --winsock_refcount;
+ if (winsock_refcount == 0) {
+
+ WSACleanup();
+ };
+};
+
+
+Error StreamPeerWinsock::_block(int p_sockfd, bool p_read, bool p_write) const {
+
+ fd_set read, write;
+ FD_ZERO(&read);
+ FD_ZERO(&write);
+
+ if (p_read)
+ FD_SET(p_sockfd, &read);
+ if (p_write)
+ FD_SET(p_sockfd, &write);
+
+ int ret = select(p_sockfd + 1, &read, &write, NULL, NULL); // block forever
+ return ret < 0 ? FAILED : OK;
+};
+
+Error StreamPeerWinsock::_poll_connection(bool p_block) const {
+
+ ERR_FAIL_COND_V(status != STATUS_CONNECTING || sockfd == INVALID_SOCKET, FAILED);
+
+ if (p_block) {
+
+ _block(sockfd, false, true);
+ };
+
+ struct sockaddr_in their_addr;
+ set_addr_in(their_addr, peer_host, peer_port);
+
+ if (::connect(sockfd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == SOCKET_ERROR) {
+
+ int err = WSAGetLastError();
+ if (err == WSAEISCONN) {
+ status = STATUS_CONNECTED;
+ return OK;
+ };
+
+ return OK;
+ } else {
+
+ status = STATUS_CONNECTED;
+ return OK;
+ };
+
+ return OK;
+};
+
+Error StreamPeerWinsock::write(const uint8_t* p_data,int p_bytes, int &r_sent, bool p_block) {
+
+ if (status == STATUS_NONE || status == STATUS_ERROR) {
+
+ return FAILED;
+ };
+
+ if (status != STATUS_CONNECTED) {
+
+ if (_poll_connection(p_block) != OK) {
+
+ return FAILED;
+ };
+
+ if (status != STATUS_CONNECTED) {
+ r_sent = 0;
+ return OK;
+ };
+ };
+
+ int data_to_send = p_bytes;
+ const uint8_t *offset = p_data;
+ if (sockfd == -1) return FAILED;
+ errno = 0;
+ int total_sent = 0;
+
+ while (data_to_send) {
+
+ int sent_amount = send(sockfd, (const char*)offset, data_to_send, 0);
+ //printf("Sent TCP data of %d bytes, errno %d\n", sent_amount, errno);
+
+ if (sent_amount == -1) {
+
+ if (WSAGetLastError() != WSAEWOULDBLOCK) {
+
+ perror("shit?");
+ disconnect();
+ ERR_PRINT("Server disconnected!\n");
+ return FAILED;
+ };
+
+ if (!p_block) {
+ r_sent = total_sent;
+ return OK;
+ };
+
+ _block(sockfd, false, true);
+ } else {
+
+ data_to_send -= sent_amount;
+ offset += sent_amount;
+ total_sent += sent_amount;
+ };
+ }
+
+ r_sent = total_sent;
+
+ return OK;
+};
+
+Error StreamPeerWinsock::read(uint8_t* p_buffer, int p_bytes,int &r_received, bool p_block) {
+
+ if (!is_connected()) {
+
+ return FAILED;
+ };
+
+ if (status != STATUS_CONNECTED) {
+
+ if (_poll_connection(p_block) != OK) {
+
+ return FAILED;
+ };
+
+ if (status != STATUS_CONNECTED) {
+ r_received = 0;
+ return OK;
+ };
+ };
+
+ int to_read = p_bytes;
+ int total_read = 0;
+ errno = 0;
+
+ while (to_read) {
+
+ int read = recv(sockfd, (char*)p_buffer + total_read, to_read, 0);
+
+ if (read == -1) {
+
+ if (WSAGetLastError() != WSAEWOULDBLOCK) {
+
+ perror("shit?");
+ disconnect();
+ ERR_PRINT("Server disconnected!\n");
+ return FAILED;
+ };
+
+ if (!p_block) {
+
+ r_received = total_read;
+ return OK;
+ };
+ _block(sockfd, true, false);
+ } else if (read == 0) {
+ disconnect();
+ return ERR_FILE_EOF;
+ } else {
+
+ to_read -= read;
+ total_read += read;
+ };
+ };
+
+ r_received = total_read;
+
+ return OK;
+};
+
+Error StreamPeerWinsock::put_data(const uint8_t* p_data,int p_bytes) {
+
+ int total;
+ return write(p_data, p_bytes, total, true);
+};
+
+Error StreamPeerWinsock::put_partial_data(const uint8_t* p_data,int p_bytes, int &r_sent) {
+
+ return write(p_data, p_bytes, r_sent, false);
+};
+
+Error StreamPeerWinsock::get_data(uint8_t* p_buffer, int p_bytes) {
+
+ int total;
+ return read(p_buffer, p_bytes, total, true);
+};
+
+Error StreamPeerWinsock::get_partial_data(uint8_t* p_buffer, int p_bytes,int &r_received) {
+
+ return read(p_buffer, p_bytes, r_received, false);
+};
+
+StreamPeerTCP::Status StreamPeerWinsock::get_status() const {
+
+ if (status == STATUS_CONNECTING) {
+ _poll_connection(false);
+ };
+
+ return status;
+};
+
+
+bool StreamPeerWinsock::is_connected() const {
+
+ if (status == STATUS_NONE || status == STATUS_ERROR) {
+
+ return false;
+ };
+ if (status != STATUS_CONNECTED) {
+ return true;
+ };
+
+ return (sockfd!=INVALID_SOCKET);
+};
+
+void StreamPeerWinsock::disconnect() {
+
+ if (sockfd != INVALID_SOCKET)
+ closesocket(sockfd);
+ sockfd=INVALID_SOCKET;
+
+ status = STATUS_NONE;
+
+ peer_host = IP_Address();
+ peer_port = 0;
+};
+
+void StreamPeerWinsock::set_socket(int p_sockfd, IP_Address p_host, int p_port) {
+
+ sockfd = p_sockfd;
+ status = STATUS_CONNECTING;
+ peer_host = p_host;
+ peer_port = p_port;
+};
+
+Error StreamPeerWinsock::connect(const IP_Address& p_host, uint16_t p_port) {
+
+ ERR_FAIL_COND_V( p_host.host == 0, ERR_INVALID_PARAMETER);
+
+ if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
+ ERR_PRINT("Socket creation failed!");
+ disconnect();
+ //perror("socket");
+ return FAILED;
+ };
+
+ unsigned long par = 1;
+ if (ioctlsocket(sockfd, FIONBIO, &par)) {
+ perror("setting non-block mode");
+ disconnect();
+ return FAILED;
+ };
+
+ struct sockaddr_in their_addr;
+ set_addr_in(their_addr, p_host, p_port);
+
+ if (::connect(sockfd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == SOCKET_ERROR) {
+
+ if (WSAGetLastError() != WSAEWOULDBLOCK) {
+ ERR_PRINT("Connection to remote host failed!");
+ disconnect();
+ return FAILED;
+ };
+ status = STATUS_CONNECTING;
+ } else {
+ status = STATUS_CONNECTED;
+ };
+
+ peer_host = p_host;
+ peer_port = p_port;
+
+ return OK;
+};
+
+void StreamPeerWinsock::set_nodelay(bool p_enabled) {
+
+
+}
+
+
+IP_Address StreamPeerWinsock::get_connected_host() const {
+
+ return peer_host;
+};
+
+uint16_t StreamPeerWinsock::get_connected_port() const {
+
+ return peer_port;
+};
+
+StreamPeerWinsock::StreamPeerWinsock() {
+
+ sockfd = INVALID_SOCKET;
+ status = STATUS_NONE;
+ peer_port = 0;
+};
+
+StreamPeerWinsock::~StreamPeerWinsock() {
+
+ disconnect();
+};
+
+
+#endif
diff --git a/platform/windows/stream_peer_winsock.h b/platform/windows/stream_peer_winsock.h
new file mode 100644
index 0000000000..14dd5f0bb1
--- /dev/null
+++ b/platform/windows/stream_peer_winsock.h
@@ -0,0 +1,90 @@
+/*************************************************************************/
+/* stream_peer_winsock.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 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. */
+/*************************************************************************/
+#ifdef WINDOWS_ENABLED
+
+#ifndef STREAM_PEER_WINSOCK_H
+#define STREAM_PEER_WINSOCK_H
+
+#include "error_list.h"
+
+#include "core/io/ip_address.h"
+#include "core/io/stream_peer_tcp.h"
+
+class StreamPeerWinsock : public StreamPeerTCP {
+
+protected:
+
+ mutable Status status;
+
+ int sockfd;
+
+ Error _block(int p_sockfd, bool p_read, bool p_write) const;
+
+ Error _poll_connection(bool p_block) const;
+
+ IP_Address peer_host;
+ int peer_port;
+
+ Error write(const uint8_t* p_data,int p_bytes, int &r_sent, bool p_block);
+ Error read(uint8_t* p_buffer, int p_bytes,int &r_received, bool p_block);
+
+ static StreamPeerTCP* _create();
+
+public:
+
+ virtual Error connect(const IP_Address& p_host, uint16_t p_port);
+
+ virtual Error put_data(const uint8_t* p_data,int p_bytes);
+ virtual Error put_partial_data(const uint8_t* p_data,int p_bytes, int &r_sent);
+
+ virtual Error get_data(uint8_t* p_buffer, int p_bytes);
+ virtual Error get_partial_data(uint8_t* p_buffer, int p_bytes,int &r_received);
+
+ void set_socket(int p_sockfd, IP_Address p_host, int p_port);
+
+ virtual IP_Address get_connected_host() const;
+ virtual uint16_t get_connected_port() const;
+
+ virtual bool is_connected() const;
+ virtual Status get_status() const;
+ virtual void disconnect();
+
+ static void make_default();
+ static void cleanup();
+
+ virtual void set_nodelay(bool p_enabled);
+
+
+ StreamPeerWinsock();
+ ~StreamPeerWinsock();
+};
+
+#endif // TCP_SOCKET_POSIX_H
+
+#endif
diff --git a/platform/windows/tcp_server_winsock.cpp b/platform/windows/tcp_server_winsock.cpp
new file mode 100644
index 0000000000..7b35bcc7ad
--- /dev/null
+++ b/platform/windows/tcp_server_winsock.cpp
@@ -0,0 +1,166 @@
+/*************************************************************************/
+/* tcp_server_winsock.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 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 "tcp_server_winsock.h"
+
+#include "stream_peer_winsock.h"
+
+#include <winsock2.h>
+
+extern int winsock_refcount;
+
+TCP_Server* TCPServerWinsock::_create() {
+
+ return memnew(TCPServerWinsock);
+};
+
+void TCPServerWinsock::make_default() {
+
+ TCP_Server::_create = TCPServerWinsock::_create;
+
+ if (winsock_refcount == 0) {
+ WSADATA data;
+ WSAStartup(MAKEWORD(2,2), &data);
+ };
+ ++winsock_refcount;
+};
+
+void TCPServerWinsock::cleanup() {
+
+ --winsock_refcount;
+ if (winsock_refcount == 0) {
+
+ WSACleanup();
+ };
+};
+
+
+Error TCPServerWinsock::listen(uint16_t p_port,const List<String> *p_accepted_hosts) {
+
+ int sockfd;
+ sockfd = socket(AF_INET, SOCK_STREAM, 0);
+ ERR_FAIL_COND_V(sockfd == INVALID_SOCKET, FAILED);
+
+ unsigned long par = 1;
+ if (ioctlsocket(sockfd, FIONBIO, &par)) {
+ perror("setting non-block mode");
+ stop();
+ return FAILED;
+ };
+
+ struct sockaddr_in my_addr;
+ my_addr.sin_family = AF_INET; // host byte order
+ my_addr.sin_port = htons(p_port); // short, network byte order
+ my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP TODO: use p_accepted_hosts
+ memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);
+
+ if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof my_addr) != SOCKET_ERROR) {
+
+ if (::listen(sockfd, SOMAXCONN) == SOCKET_ERROR) {
+
+ closesocket(sockfd);
+ ERR_FAIL_V(FAILED);
+ };
+ };
+
+ if (listen_sockfd != INVALID_SOCKET) {
+
+ stop();
+ };
+
+ listen_sockfd = sockfd;
+
+ return OK;
+};
+
+bool TCPServerWinsock::is_connection_available() const {
+
+ if (listen_sockfd == -1) {
+ return false;
+ };
+
+ timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+
+ fd_set pfd;
+ FD_ZERO(&pfd);
+ FD_SET(listen_sockfd, &pfd);
+
+ int ret = select(listen_sockfd + 1, &pfd, NULL, NULL, &timeout);
+ ERR_FAIL_COND_V(ret < 0, 0);
+
+ if (ret && (FD_ISSET(listen_sockfd, &pfd))) {
+
+ return true;
+ };
+
+ return false;
+};
+
+
+Ref<StreamPeerTCP> TCPServerWinsock::take_connection() {
+
+ if (!is_connection_available()) {
+ return NULL;
+ };
+
+ struct sockaddr_in their_addr;
+ int sin_size = sizeof(their_addr);
+ int fd = accept(listen_sockfd, (struct sockaddr *)&their_addr, &sin_size);
+ ERR_FAIL_COND_V(fd == INVALID_SOCKET, NULL);
+
+ Ref<StreamPeerWinsock> conn = memnew(StreamPeerWinsock);
+ IP_Address ip;
+ ip.host = (uint32_t)their_addr.sin_addr.s_addr;
+
+ conn->set_socket(fd, ip, ntohs(their_addr.sin_port));
+
+ return conn;
+};
+
+void TCPServerWinsock::stop() {
+
+ if (listen_sockfd != INVALID_SOCKET) {
+ closesocket(listen_sockfd);
+ };
+
+ listen_sockfd = -1;
+};
+
+
+TCPServerWinsock::TCPServerWinsock() {
+
+ listen_sockfd = INVALID_SOCKET;
+};
+
+TCPServerWinsock::~TCPServerWinsock() {
+
+ stop();
+};
+
diff --git a/platform/windows/tcp_server_winsock.h b/platform/windows/tcp_server_winsock.h
new file mode 100644
index 0000000000..2d54b6ce40
--- /dev/null
+++ b/platform/windows/tcp_server_winsock.h
@@ -0,0 +1,55 @@
+/*************************************************************************/
+/* tcp_server_winsock.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 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 TCP_SERVER_WINSOCK_H
+#define TCP_SERVER_WINSOCK_H
+
+#include "core/io/tcp_server.h"
+
+class TCPServerWinsock : public TCP_Server {
+
+ int listen_sockfd;
+
+ static TCP_Server* _create();
+
+public:
+
+ virtual Error listen(uint16_t p_port,const List<String> *p_accepted_hosts=NULL);
+ virtual bool is_connection_available() const;
+ virtual Ref<StreamPeerTCP> take_connection();
+
+ virtual void stop(); //stop listening
+
+ static void make_default();
+ static void cleanup();
+
+ TCPServerWinsock();
+ ~TCPServerWinsock();
+};
+
+#endif