diff --git a/build/vs2010/Lol.sln b/build/vs2010/Lol.sln
index 40a0b4fa..91e445af 100644
--- a/build/vs2010/Lol.sln
+++ b/build/vs2010/Lol.sln
@@ -152,6 +152,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Demos", "Demos", "{E5C5E320
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lol.js", "Lol.js", "{F7D4A671-612F-4FF4-883F-2097697694B7}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "07_input", "..\..\demos\tutorial\07_input.vcxproj", "{572E5B9C-7E19-489C-BD8A-E8401CFBBC47}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "06_sprite", "..\..\demos\tutorial\06_sprite.vcxproj", "{E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -941,6 +945,46 @@ Global
{AA376B9B-484B-4DC4-982F-6CFA645E441E}.Release|Xbox 360.ActiveCfg = Release|Xbox 360
{AA376B9B-484B-4DC4-982F-6CFA645E441E}.Release|Xbox 360.Build.0 = Release|Xbox 360
{AA376B9B-484B-4DC4-982F-6CFA645E441E}.Release|Xbox 360.Deploy.0 = Release|Xbox 360
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Debug|ORBIS.ActiveCfg = Debug|x64
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Debug|PS3.ActiveCfg = Debug|x64
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Debug|Win32.ActiveCfg = Debug|Win32
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Debug|Win32.Build.0 = Debug|Win32
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Debug|x64.ActiveCfg = Debug|x64
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Debug|x64.Build.0 = Debug|x64
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Debug|Xbox 360.ActiveCfg = Debug|x64
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Release|Any CPU.ActiveCfg = Release|x64
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Release|Mixed Platforms.Build.0 = Release|Win32
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Release|ORBIS.ActiveCfg = Release|x64
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Release|PS3.ActiveCfg = Release|x64
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Release|Win32.ActiveCfg = Release|Win32
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Release|Win32.Build.0 = Release|Win32
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Release|x64.ActiveCfg = Release|x64
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Release|x64.Build.0 = Release|x64
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}.Release|Xbox 360.ActiveCfg = Release|x64
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Debug|Mixed Platforms.ActiveCfg = Debug|x64
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Debug|Mixed Platforms.Build.0 = Debug|x64
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Debug|ORBIS.ActiveCfg = Debug|x64
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Debug|PS3.ActiveCfg = Debug|x64
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Debug|Win32.ActiveCfg = Debug|Win32
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Debug|Win32.Build.0 = Debug|Win32
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Debug|x64.ActiveCfg = Debug|x64
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Debug|x64.Build.0 = Debug|x64
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Debug|Xbox 360.ActiveCfg = Debug|x64
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Release|Any CPU.ActiveCfg = Release|x64
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Release|Mixed Platforms.ActiveCfg = Release|x64
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Release|Mixed Platforms.Build.0 = Release|x64
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Release|ORBIS.ActiveCfg = Release|x64
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Release|PS3.ActiveCfg = Release|x64
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Release|Win32.ActiveCfg = Release|Win32
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Release|Win32.Build.0 = Release|Win32
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Release|x64.ActiveCfg = Release|x64
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Release|x64.Build.0 = Release|x64
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}.Release|Xbox 360.ActiveCfg = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -965,7 +1009,8 @@ Global
{80F81C11-8DA2-4990-91CB-9807783BA46E} = {E0491194-35E3-4513-9D31-608EA3165ECF}
{EE203B88-44CF-4859-9D42-7A1F43FECB52} = {E0491194-35E3-4513-9D31-608EA3165ECF}
{7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E} = {E0491194-35E3-4513-9D31-608EA3165ECF}
- {B92ABADC-45BE-4CC5-B724-9426053123A1} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04}
+ {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04} = {E5C5E320-C077-4362-9A3F-3920C6447601}
+ {F7D4A671-612F-4FF4-883F-2097697694B7} = {E5C5E320-C077-4362-9A3F-3920C6447601}
{7B083DA2-FE08-4F6D-BFDD-195D5C2783EB} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04}
{1C5B8702-290C-42DA-AA9E-671348F5B747} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04}
{6BF81B39-EDC2-4227-9992-C2D8ABEA95AF} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04}
@@ -973,6 +1018,9 @@ Global
{B0A53D75-CBB4-4FDF-93AC-2D12A79ADA0E} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04}
{834852DB-EDB6-4FD0-BCF9-45CD01126962} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04}
{6BF81B39-EDC2-4227-9982-C2D8ABEA95AF} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04}
+ {B92ABADC-45BE-4CC5-B724-9426053123A1} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04}
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04}
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04}
{32F3F8CF-D22E-45E4-BEB8-AD909E8C5515} = {33704AA4-F2B5-4138-A40D-E3E77F89ED46}
{EE203B88-44CF-4859-9D42-7A5F40FECB52} = {8C77EAA8-1077-4EF7-AE53-97C6C60A3601}
{B357514A-7881-422D-8358-161B689E7620} = {3D341D8A-E400-4B1D-BC05-B5C35487D9B5}
@@ -986,8 +1034,6 @@ Global
{C2E01551-B636-4324-8461-71811DF6FBB5} = {E27FDF36-50C4-4ED2-8CF5-A20FED016910}
{58922993-9830-4A40-B462-0326342F69ED} = {9CC50C06-DF5E-41A7-AD90-04F05386E081}
{FAF82AD2-D9F4-4694-9A01-103BC5B771B4} = {B583BBFF-BE97-4F4E-BA1E-1F978A31EAB0}
- {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04} = {E5C5E320-C077-4362-9A3F-3920C6447601}
- {F7D4A671-612F-4FF4-883F-2097697694B7} = {E5C5E320-C077-4362-9A3F-3920C6447601}
{AA376B9B-484B-4DC4-982F-6CFA645E441E} = {F7D4A671-612F-4FF4-883F-2097697694B7}
EndGlobalSection
EndGlobal
diff --git a/demos/tutorial/06_sprite.vcxproj b/demos/tutorial/06_sprite.vcxproj
index 961cdca4..d8dbc8b6 100644
--- a/demos/tutorial/06_sprite.vcxproj
+++ b/demos/tutorial/06_sprite.vcxproj
@@ -1,71 +1,71 @@
-
-
-
-
- Debug
- PS3
-
-
- Debug
- Win32
-
-
- Debug
- x64
-
-
- Debug
- Xbox 360
-
-
- Release
- PS3
-
-
- Release
- Win32
-
-
- Release
- x64
-
-
- Release
- Xbox 360
-
-
-
-
-
-
-
- {9e62f2fe-3408-4eae-8238-fd84238ceeda}
-
-
- {83d3b207-c601-4025-8f41-01dedc354661}
-
-
- {d84021ca-b233-4e0f-8a52-071b83bbccc4}
-
-
-
- {1c5b8702-290c-42da-aa9e-671348f5b747}
- Application
- Win32Proj
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Debug
+ PS3
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Debug
+ Xbox 360
+
+
+ Release
+ PS3
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+ Release
+ Xbox 360
+
+
+
+
+
+
+
+ {9e62f2fe-3408-4eae-8238-fd84238ceeda}
+
+
+ {83d3b207-c601-4025-8f41-01dedc354661}
+
+
+ {d84021ca-b233-4e0f-8a52-071b83bbccc4}
+
+
+
+ {E05E23A5-67DE-42B5-98A3-E63CCE0CC0AF}
+ Application
+ Win32Proj
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/tutorial/07_input.cpp b/demos/tutorial/07_input.cpp
new file mode 100644
index 00000000..a3dc46fe
--- /dev/null
+++ b/demos/tutorial/07_input.cpp
@@ -0,0 +1,230 @@
+//
+// Lol Engine - Cube tutorial
+//
+// Copyright: (c) 2011-2013 Sam Hocevar
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the Do What The Fuck You Want To
+// Public License, Version 2, as published by Sam Hocevar. See
+// http://www.wtfpl.net/ for more details.
+//
+
+#define LOL_INPUT_V2
+
+#if defined HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "core.h"
+#include "loldebug.h"
+
+using namespace std;
+using namespace lol;
+
+LOLFX_RESOURCE_DECLARE(07_input);
+
+enum
+{
+ KEY_MANUAL_ROTATION,
+ KEY_DRAG_MESH,
+ KEY_MAX
+};
+
+enum
+{
+ AXIS_DRAG_PITCH,
+ AXIS_DRAG_YAW,
+ AXIS_PITCH,
+ AXIS_YAW,
+ AXIS_MAX
+};
+
+Controller* controller;
+
+class Cube : public WorldEntity
+{
+public:
+ Cube()
+ {
+ m_pitch_angle = 0;
+ m_yaw_angle = 0;
+ m_autorot = true;
+
+ /* Front vertices/colors */
+ m_mesh.Push(vec3(-1.0, -1.0, 1.0), vec3(1.0, 0.0, 1.0));
+ m_mesh.Push(vec3( 1.0, -1.0, 1.0), vec3(0.0, 1.0, 0.0));
+ m_mesh.Push(vec3( 1.0, 1.0, 1.0), vec3(1.0, 0.5, 0.0));
+ m_mesh.Push(vec3(-1.0, 1.0, 1.0), vec3(1.0, 1.0, 0.0));
+ /* Back */
+ m_mesh.Push(vec3(-1.0, -1.0, -1.0), vec3(1.0, 0.0, 0.0));
+ m_mesh.Push(vec3( 1.0, -1.0, -1.0), vec3(0.0, 0.5, 0.0));
+ m_mesh.Push(vec3( 1.0, 1.0, -1.0), vec3(0.0, 0.5, 1.0));
+ m_mesh.Push(vec3(-1.0, 1.0, -1.0), vec3(0.0, 0.0, 1.0));
+
+ m_faces_indices << 0 << 1 << 2 << 2 << 3 << 0;
+ m_faces_indices << 1 << 5 << 6 << 6 << 2 << 1;
+ m_faces_indices << 7 << 6 << 5 << 5 << 4 << 7;
+ m_faces_indices << 4 << 0 << 3 << 3 << 7 << 4;
+ m_faces_indices << 4 << 5 << 1 << 1 << 0 << 4;
+ m_faces_indices << 3 << 2 << 6 << 6 << 7 << 3;
+
+ m_lines_indices << 0 << 1 << 1 << 2 << 2 << 3 << 3 << 0;
+ m_lines_indices << 4 << 5 << 5 << 6 << 6 << 7 << 7 << 4;
+ m_lines_indices << 0 << 4 << 1 << 5 << 2 << 6 << 3 << 7;
+
+ m_text = new Text(NULL, "data/font/ascii.png");
+ m_text->SetPos(ivec3(5, 5, 1));
+ Ticker::Ref(m_text);
+
+ m_ready = false;
+ }
+
+ ~Cube()
+ {
+ Ticker::Unref(m_text);
+ }
+
+ virtual void TickGame(float seconds)
+ {
+ WorldEntity::TickGame(seconds);
+
+ if (controller->GetKey(KEY_MANUAL_ROTATION).IsPressed())
+ m_autorot = !m_autorot;
+
+ if (controller->GetKey(KEY_DRAG_MESH).IsDown())
+ {
+ InputDevice::CaptureMouse(true);
+ m_pitch_angle -= controller->GetAxis(AXIS_DRAG_PITCH).GetValue() * seconds * 100;
+ m_yaw_angle += controller->GetAxis(AXIS_DRAG_YAW).GetValue() * seconds * 100;
+ }
+ else
+ {
+ InputDevice::CaptureMouse(false);
+ if (m_autorot)
+ m_yaw_angle += seconds * 20;
+ }
+ if (lol::abs(controller->GetAxis(AXIS_PITCH).GetValue()) > 0.2f)
+ m_pitch_angle -= controller->GetAxis(AXIS_PITCH).GetValue() * seconds * 100;
+ if (lol::abs(controller->GetAxis(AXIS_YAW).GetValue()) > 1.0f)
+ m_yaw_angle += controller->GetAxis(AXIS_YAW).GetValue() * seconds * 100;
+
+ InputDevice* mouse = InputDevice::Get("Mouse");
+ if (mouse)
+ {
+ char buf[128];
+ std::sprintf(buf, "cursor: (%0.3f, %0.3f) - pixel (%d, %d)",
+ mouse->GetCursor(0).x, mouse->GetCursor(0).y,
+ mouse->GetCursorPixel(0).x, mouse->GetCursorPixel(0).y);
+ m_text->SetText(buf);
+ }
+ else
+ {
+ m_text->SetText("no mouse detected");
+ }
+
+ mat4 anim = mat4::rotate(m_yaw_angle, vec3(0, 1, 0)) * mat4::rotate(m_pitch_angle, vec3(1, 0, 0));
+ mat4 model = mat4::translate(vec3(0, 0, -4.5));
+ mat4 view = mat4::lookat(vec3(0, 2, 0), vec3(0, 0, -4), vec3(0, 1, 0));
+ mat4 proj = mat4::perspective(45.0f, 640.0f, 480.0f, 0.1f, 10.0f);
+
+ m_matrix = proj * view * model * anim;
+ }
+
+ virtual void TickDraw(float seconds)
+ {
+ WorldEntity::TickDraw(seconds);
+
+ if (!m_ready)
+ {
+ m_shader = Shader::Create(LOLFX_RESOURCE_NAME(07_input));
+
+ m_mvp = m_shader->GetUniformLocation("in_Matrix");
+ m_coord = m_shader->GetAttribLocation("in_Vertex",
+ VertexUsage::Position, 0);
+ m_color = m_shader->GetAttribLocation("in_Color",
+ VertexUsage::Color, 0);
+
+ m_vdecl =
+ new VertexDeclaration(VertexStream(VertexUsage::Position,
+ VertexUsage::Color));
+
+ m_vbo = new VertexBuffer(m_mesh.Bytes());
+ void *mesh = m_vbo->Lock(0, 0);
+ memcpy(mesh, &m_mesh[0], m_mesh.Bytes());
+ m_vbo->Unlock();
+
+ m_lines_ibo = new IndexBuffer(m_lines_indices.Bytes());
+ void *indices = m_lines_ibo->Lock(0, 0);
+ memcpy(indices, &m_lines_indices[0], m_lines_indices.Bytes());
+ m_lines_ibo->Unlock();
+
+ m_faces_ibo = new IndexBuffer(m_faces_indices.Bytes());
+ indices = m_faces_ibo->Lock(0, 0);
+ memcpy(indices, &m_faces_indices[0], m_faces_indices.Bytes());
+ m_faces_ibo->Unlock();
+
+ /* FIXME: this object never cleans up */
+ m_ready = true;
+ }
+
+ g_renderer->SetClearColor(vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
+ m_shader->Bind();
+ m_vdecl->SetStream(m_vbo, m_coord, m_color);
+ m_vdecl->Bind();
+
+ m_shader->SetUniform(m_mvp, m_matrix);
+ m_lines_ibo->Bind();
+ m_vdecl->DrawIndexedElements(MeshPrimitive::Lines, 0, 0,
+ m_mesh.Count(), 0, m_lines_indices.Count());
+ m_lines_ibo->Unbind();
+
+ m_shader->SetUniform(m_mvp, m_matrix * mat4::scale(0.5f));
+ m_faces_ibo->Bind();
+ m_vdecl->DrawIndexedElements(MeshPrimitive::Triangles, 0, 0,
+ m_mesh.Count(), 0, m_faces_indices.Count());
+ m_faces_ibo->Unbind();
+
+ m_vdecl->Unbind();
+ }
+
+private:
+ bool m_autorot;
+ float m_pitch_angle;
+ float m_yaw_angle;
+ mat4 m_matrix;
+ Array m_mesh;
+ Array m_lines_indices, m_faces_indices;
+
+ Shader *m_shader;
+ ShaderAttrib m_coord, m_color;
+ ShaderUniform m_mvp;
+ VertexDeclaration *m_vdecl;
+ VertexBuffer *m_vbo;
+ IndexBuffer *m_lines_ibo, *m_faces_ibo;
+
+ Text *m_text;
+ bool m_ready;
+};
+
+int main(int argc, char **argv)
+{
+ System::Init(argc, argv);
+
+ Application app("Tutorial 7: Input", ivec2(640, 480), 60.0f);
+
+ new DebugFps(5, 5);
+ new Cube();
+
+ controller = new Controller(KEY_MAX, AXIS_MAX);
+ controller->GetKey(KEY_MANUAL_ROTATION).Bind("Keyboard", "Space");
+ controller->GetKey(KEY_DRAG_MESH).Bind("Mouse", "ButtonLeft");
+ controller->GetAxis(AXIS_DRAG_PITCH).Bind("Mouse", "Y");
+ controller->GetAxis(AXIS_DRAG_YAW).Bind("Mouse", "X");
+ controller->GetAxis(AXIS_PITCH).Bind("Joystick1", "Axis2");
+ controller->GetAxis(AXIS_YAW).Bind("Joystick1", "Axis1");
+
+ app.Run();
+
+ return EXIT_SUCCESS;
+}
+
diff --git a/demos/tutorial/07_input.lolfx b/demos/tutorial/07_input.lolfx
new file mode 100644
index 00000000..8e1ae04f
--- /dev/null
+++ b/demos/tutorial/07_input.lolfx
@@ -0,0 +1,50 @@
+[vert.glsl]
+
+#version 120
+
+attribute vec3 in_Vertex;
+attribute vec3 in_Color;
+uniform mat4 in_Matrix;
+varying vec3 pass_Color;
+
+void main(void)
+{
+ gl_Position = in_Matrix * vec4(in_Vertex, 1.0);
+ pass_Color = in_Color;
+}
+
+[frag.glsl]
+
+#version 120
+
+#if defined GL_ES
+precision highp float;
+#endif
+
+varying vec3 pass_Color;
+
+void main(void)
+{
+ gl_FragColor = vec4(pass_Color, 1.0);
+}
+
+[vert.hlsl]
+
+void main(float3 in_Vertex : POSITION,
+ float3 in_Color : COLOR,
+ uniform float4x4 in_Matrix,
+ out float4 out_Position : POSITION,
+ out float3 pass_Color : COLOR)
+{
+ pass_Color = in_Color;
+ out_Position = mul(in_Matrix, float4(in_Vertex, 1.0));
+}
+
+[frag.hlsl]
+
+void main(float3 pass_Color : COLOR,
+ out float4 out_FragColor : COLOR)
+{
+ out_FragColor = float4(pass_Color, 1.0);
+}
+
diff --git a/demos/tutorial/07_input.vcxproj b/demos/tutorial/07_input.vcxproj
new file mode 100644
index 00000000..5da93262
--- /dev/null
+++ b/demos/tutorial/07_input.vcxproj
@@ -0,0 +1,82 @@
+
+
+
+
+ Debug
+ ORBIS
+
+
+ Debug
+ PS3
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Debug
+ Xbox 360
+
+
+ Release
+ ORBIS
+
+
+ Release
+ PS3
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+ Release
+ Xbox 360
+
+
+
+
+
+
+
+
+
+
+ {9e62f2fe-3408-4eae-8238-fd84238ceeda}
+
+
+ {83d3b207-c601-4025-8f41-01dedc354661}
+
+
+ {d84021ca-b233-4e0f-8a52-071b83bbccc4}
+
+
+
+ {572E5B9C-7E19-489C-BD8A-E8401CFBBC47}
+ Application
+ Win32Proj
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demos/tutorial/11_fractal.cpp b/demos/tutorial/11_fractal.cpp
index 0380e39b..e40b7272 100644
--- a/demos/tutorial/11_fractal.cpp
+++ b/demos/tutorial/11_fractal.cpp
@@ -120,7 +120,7 @@ public:
m_position = ivec3(0, 0, 0);
m_bbox[0] = m_position;
m_bbox[1] = ivec3(m_window_size, 0);
- Input::TrackMouse(this);
+ //Input::TrackMouse(this);
#if LOL_FEATURE_THREADS
/* Spawn worker threads and wait for their readiness. */
@@ -142,7 +142,7 @@ public:
m_donequeue.Pop();
#endif
- Input::UntrackMouse(this);
+ //Input::UntrackMouse(this);
#if !defined __native_client__
Ticker::Unref(m_centertext);
Ticker::Unref(m_mousetext);
@@ -175,7 +175,8 @@ public:
rcmplx worldmouse = m_center + rcmplx(ScreenToWorldOffset(m_mousepos));
- uint32_t buttons = Input::GetMouseButtons();
+ uint32_t buttons = 0;
+ //uint32_t buttons = Input::GetMouseButtons();
#if !defined __CELLOS_LV2__ && !defined _XBOX
if (buttons & 0x2)
{
diff --git a/demos/tutorial/Makefile.am b/demos/tutorial/Makefile.am
index dfb0a477..b4b206e6 100644
--- a/demos/tutorial/Makefile.am
+++ b/demos/tutorial/Makefile.am
@@ -33,6 +33,10 @@ if USE_EMSCRIPTEN
06_sprite_LDFLAGS += --preload-file 06_sprite.png
endif
+07_input_SOURCES = 07_input.cpp 07_input.lolfx
+07_input_CPPFLAGS = $(AM_CPPFLAGS)
+07_input_DEPENDENCIES = @LOL_DEPS@
+
08_fbo_SOURCES = 08_fbo.cpp 08_fbo.lolfx
08_fbo_CPPFLAGS = $(AM_CPPFLAGS)
08_fbo_DEPENDENCIES = @LOL_DEPS@
diff --git a/src/core.h b/src/core.h
index 8c514d6a..af3f158c 100644
--- a/src/core.h
+++ b/src/core.h
@@ -129,6 +129,11 @@ static inline int isnan(float f)
#include "input/stick.h"
#include "profiler.h"
+// Input (v2)
+#include "input/input.h"
+#include "input/inputdevice.h"
+#include "input/controller.h"
+
// Entities
#include "entity.h"
#include "worldentity.h"
diff --git a/src/input/controller.cpp b/src/input/controller.cpp
new file mode 100644
index 00000000..abf91d26
--- /dev/null
+++ b/src/input/controller.cpp
@@ -0,0 +1,147 @@
+//
+// Lol Engine
+//
+// Copyright: (c) 2010-2013 Benjamin Litzelmann
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the Do What The Fuck You Want To
+// Public License, Version 2, as published by Sam Hocevar. See
+// http://www.wtfpl.net/ for more details.
+//
+
+#ifdef LOL_INPUT_V2
+
+#if defined HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "core.h"
+
+namespace lol
+{
+
+///////////////////////////////////////////////////////////////////////////////
+// KeyBinding
+
+void KeyBinding::Bind(const char* device_name, const char* key_name)
+{
+ m_device = InputDevice::Get(device_name);
+ if (!m_device)
+ {
+ Log::Warn("Trying to bind controller to device %s which doesn't exist", device_name);
+ return;
+ }
+
+ m_keyindex = m_device->GetKeyIndex(key_name);
+
+ if (m_keyindex < 0)
+ {
+ Log::Warn("Trying to bind controller to key %s.%s which doesn't exist", device_name, key_name);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// AxisBinding
+
+void AxisBinding::Bind(const char* device_name, const char* axis_name)
+{
+ m_device = InputDevice::Get(device_name);
+ if (!m_device)
+ {
+ Log::Warn("Trying to bind controller to device %s which doesn't exist", device_name);
+ return;
+ }
+
+ m_axisindex = m_device->GetAxisIndex(axis_name);
+
+ if (m_axisindex < 0)
+ {
+ Log::Warn("Trying to bind controller to axis %s.%s which doesn't exist", device_name, axis_name);
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Controller
+
+Array Controller::controllers;
+
+Controller::Controller(int nb_keys, int nb_axis)
+{
+ m_gamegroup = GAMEGROUP_BEFORE;
+ m_nb_keys = nb_keys;
+ m_nb_axis = nb_axis;
+ m_keys = new KeyBinding[m_nb_keys];
+ m_axis = new AxisBinding[m_nb_axis];
+ m_activate_nextframe = false;
+ m_deactivate_nextframe = false;
+ m_active = false;
+ controllers.Push(this);
+}
+
+Controller::~Controller()
+{
+ for (int i = 0; i < controllers.Count(); ++i)
+ {
+ if (controllers[i] == this)
+ {
+ controllers.Remove(i);
+ break;
+ }
+ }
+}
+
+void Controller::TickGame(float seconds)
+{
+ Entity::TickGame(seconds);
+
+ for (int i = 0; i < m_nb_keys; ++i)
+ {
+ m_keys[i].Update();
+ }
+
+ for (int i = 0; i < m_nb_axis; ++i)
+ {
+ m_axis[i].Update();
+ }
+
+ if (m_activate_nextframe)
+ m_active = true;
+
+ if (m_deactivate_nextframe)
+ m_active = false;
+
+ m_activate_nextframe = false;
+ m_deactivate_nextframe = false;
+}
+
+void Controller::Activate()
+{
+ m_activate_nextframe = true;
+ m_deactivate_nextframe = false;
+}
+
+void Controller::Deactivate()
+{
+ m_deactivate_nextframe = true;
+ m_activate_nextframe = false;
+}
+
+Array Controller::DeactivateAll()
+{
+ Array result;
+
+ for (int i = 0; i < controllers.Count(); ++i)
+ {
+ if (controllers[i]->m_active || controllers[i]->m_activate_nextframe)
+ {
+ result.Push(controllers[i]);
+ controllers[i]->Deactivate();
+ }
+ }
+
+ return result;
+}
+
+} /* namespace lol */
+
+#endif // LOL_INPUT_V2
diff --git a/src/input/controller.h b/src/input/controller.h
new file mode 100644
index 00000000..71cfe703
--- /dev/null
+++ b/src/input/controller.h
@@ -0,0 +1,102 @@
+//
+// Lol Engine
+//
+// Copyright: (c) 2010-2013 Benjamin Litzelmann
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the Do What The Fuck You Want To
+// Public License, Version 2, as published by Sam Hocevar. See
+// http://www.wtfpl.net/ for more details.
+//
+
+#if !defined __LOL_INPUT_CONTROLLER_H__
+#define __LOL_INPUT_CONTROLLER_H__
+
+#if defined LOL_INPUT_V2
+
+#include "core.h"
+
+namespace lol
+{
+
+class KeyBinding
+{
+public:
+ KeyBinding() : m_current(false), m_previous(false), m_device(nullptr) {}
+
+ bool IsDown() const { return m_current; }
+ bool IsUp() const { return !m_current; }
+ bool IsPressed() const { return m_current && !m_previous; }
+ bool IsReleased() const { return !m_current && m_previous; }
+
+ void Bind(const char* device_name, const char* key_name);
+
+protected:
+ void Update() { m_previous = m_current; m_current = m_device ? m_device->GetKey(m_keyindex) : false; }
+
+ const InputDevice* m_device;
+ int m_keyindex;
+ bool m_current;
+ bool m_previous;
+
+ friend class Controller;
+};
+
+class AxisBinding
+{
+public:
+ AxisBinding() : m_current(0.0f), m_previous(0.0f), m_device(nullptr) {}
+
+ float GetValue() const { return m_current; }
+ float GetDelta() const { return m_current - m_previous; }
+
+ void Bind(const char* device_name, const char* axis_name);
+
+protected:
+ void Update() { m_previous = m_current; m_current = m_device ? m_device->GetAxis(m_axisindex) : 0.0f; }
+
+ const InputDevice* m_device;
+ int m_axisindex;
+ float m_current;
+ float m_previous;
+
+ friend class Controller;
+};
+
+
+class Controller : Entity
+{
+public:
+ Controller(int nb_keys, int nb_axis);
+ ~Controller();
+
+ virtual void TickGame(float seconds);
+
+ /** Activate the controller on next frame */
+ void Activate();
+ /** Deactivate the controller on next frame */
+ void Deactivate();
+ /** Deactivate every active controller on next frame and return an array of deactivated (previously active) controllers */
+ static Array DeactivateAll();
+
+ KeyBinding& GetKey(int index) { ASSERT(index >= 0 && index < m_nb_keys); return m_keys[index]; }
+ AxisBinding& GetAxis(int index) { ASSERT(index >= 0 && index < m_nb_axis); return m_axis[index]; }
+
+protected:
+ KeyBinding* m_keys;
+ AxisBinding* m_axis;
+ int m_nb_keys;
+ int m_nb_axis;
+
+private:
+ static Array controllers;
+ bool m_activate_nextframe;
+ bool m_deactivate_nextframe;
+ bool m_active;
+};
+
+} /* namespace lol */
+
+#endif // LOL_INPUT_V2
+
+#endif // __LOL_INPUT_CONTROLLER_H__
+
diff --git a/src/input/input.cpp b/src/input/input.cpp
index a319e645..4dbeb228 100644
--- a/src/input/input.cpp
+++ b/src/input/input.cpp
@@ -8,6 +8,8 @@
// http://www.wtfpl.net/ for more details.
//
+#ifndef LOL_INPUT_V2
+
#if defined HAVE_CONFIG_H
# include "config.h"
#endif
@@ -478,3 +480,4 @@ void Input::UntrackStick(Stick *stick)
} /* namespace lol */
+#endif // !LOL_INPUT_V2
diff --git a/src/input/input.h b/src/input/input.h
index bd7f5b47..5eb3b3d2 100644
--- a/src/input/input.h
+++ b/src/input/input.h
@@ -16,6 +16,8 @@
#if !defined __LOL_INPUT_INPUT_H__
#define __LOL_INPUT_INPUT_H__
+#ifndef LOL_INPUT_V2
+
#include
#include
@@ -456,5 +458,7 @@ public:
} /* namespace lol */
+#endif // !LOL_INPUT_V2
+
#endif // __LOL_INPUT_INPUT_H__
diff --git a/src/input/inputdevice.cpp b/src/input/inputdevice.cpp
new file mode 100644
index 00000000..7ff3e4cc
--- /dev/null
+++ b/src/input/inputdevice.cpp
@@ -0,0 +1,72 @@
+//
+// Lol Engine
+//
+// Copyright: (c) 2010-2013 Benjamin Litzelmann
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the Do What The Fuck You Want To
+// Public License, Version 2, as published by Sam Hocevar. See
+// http://www.wtfpl.net/ for more details.
+//
+
+#ifdef LOL_INPUT_V2
+
+#if defined HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "core.h"
+
+#include "input/inputdevice_internal.h"
+
+namespace lol
+{
+
+Array InputDevice::devices;
+bool InputDevice::m_capturemouse;
+
+void InputDeviceInternal::AddKey(const char* name)
+{
+ m_keynames.Push(name);
+ m_keys.Push(false);
+}
+
+void InputDeviceInternal::AddAxis(const char* name, float sensitivity)
+{
+ m_axisnames.Push(name);
+ m_axis.Push(0.0f, sensitivity);
+}
+
+void InputDeviceInternal::AddCursor(const char* name)
+{
+ m_cursornames.Push(name);
+ m_cursors.Push(vec2(0.0), ivec2(0));
+}
+
+InputDeviceInternal* InputDeviceInternal::CreateStandardKeyboard()
+{
+ InputDeviceInternal* keyboard = new InputDeviceInternal("Keyboard");
+# define KEY_FUNC(key, value) keyboard->AddKey(#key);
+# include "input/keys.h"
+# undef KEY_FUNC
+ return keyboard;
+}
+
+InputDeviceInternal* InputDeviceInternal::CreateStandardMouse()
+{
+ InputDeviceInternal* mouse = new InputDeviceInternal("Mouse");
+ mouse->AddKey("ButtonLeft");
+ mouse->AddKey("ButtonMiddle");
+ mouse->AddKey("ButtonRight");
+
+ mouse->AddAxis("X");
+ mouse->AddAxis("Y");
+
+ mouse->AddCursor("Cursor");
+
+ // TODO: extended button, and wheel (as axis or as buttons? or both?)
+ return mouse;
+}
+
+} /* namespace lol */
+
+#endif // LOL_INPUT_V2
diff --git a/src/input/inputdevice.h b/src/input/inputdevice.h
new file mode 100644
index 00000000..f382ef65
--- /dev/null
+++ b/src/input/inputdevice.h
@@ -0,0 +1,126 @@
+//
+// Lol Engine
+//
+// Copyright: (c) 2010-2013 Benjamin Litzelmann
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the Do What The Fuck You Want To
+// Public License, Version 2, as published by Sam Hocevar. See
+// http://www.wtfpl.net/ for more details.
+//
+
+#if !defined __LOL_INPUT_DEVICE_H__
+#define __LOL_INPUT_DEVICE_H__
+
+#if defined LOL_INPUT_V2
+
+#include "core.h"
+
+namespace lol
+{
+
+class InputDevice
+{
+public:
+ /** Get the name of this input device */
+ const String& GetName();
+
+ /** Get the index of the corresponding key, needed to call GetKey */
+ int GetKeyIndex(const char* name) const { return GetItemIndex(name, m_keynames); }
+ /** Get the index of the corresponding axis, needed to call GetAxis */
+ int GetAxisIndex(const char* name) const { return GetItemIndex(name, m_axisnames); }
+ /** Get the index of the corresponding cursor, needed to call GetCursor */
+ int GetCursorIndex(const char* name) const { return GetItemIndex(name, m_cursornames); }
+
+ /** Get the current state of the given key, true being pressed and false being released */
+ bool GetKey(int index) const { return m_keys[index]; }
+ /** Get the current value of the given axis. Devices should cap this value between -1 and 1 as much as possible, through it is not guaranteed */
+ float GetAxis(int index) const { return m_axis[index].m1 * m_axis[index].m2; }
+ /** Get the current value of the given cursor, 0,0 being the bottom-left corner and 1,1 being the top-right corner */
+ vec2 GetCursor(int index) const { return m_cursors[index].m1; }
+ /** Get the coordinate of the pixel the cursor is currently over, 0,0 being the bottom-left corner. */
+ ivec2 GetCursorPixel(int index) const { return m_cursors[index].m2; }
+
+
+ /** Set a per-device-axis sensitivity factor. The value returned by the operating system will be multiplied by this value before being returned by GetAxis */
+ void SetAxisSensitivity(int index, float sensitivity) { m_axis[index].m2 = sensitivity; }
+ /** Get the per-device-axis sensitivity factor. The value returned by the operating system will be multiplied by this value before being returned by GetAxis */
+ float GetAxisSensitivity(int index) const { return m_axis[index].m2; }
+
+ /** Get a list of the name of all available keys in this device */
+ const Array& GetAllKeys() const { return m_keynames; }
+ /** Get a list of the name of all available axis in this device */
+ const Array& GetAllAxis() const { return m_axisnames; }
+ /** Get a list of the name of all available cursors in this device */
+ const Array& GetAllCursors() const { return m_cursornames; }
+
+ /** Get an input device by its name */
+ static InputDevice* Get(const char* name) { return GetDevice(name); }
+ /** Set whether the mouse cursor should be captured. */
+ static void CaptureMouse(bool activated) { m_capturemouse = activated; }
+
+protected:
+ // TODO: hide all of this in a InputDeviceData?
+
+ String m_name;
+
+ Array m_keynames;
+ Array m_axisnames;
+ Array m_cursornames;
+
+ /** key states (pressed/released) */
+ Array m_keys;
+ /** axis states (value and sensitivity) */
+ Array m_axis;
+ /** cursor position */
+ Array m_cursors;
+
+ static bool m_capturemouse;
+
+ InputDevice(const char* name) : m_name(name)
+ {
+ devices.Push(this);
+ }
+
+ ~InputDevice()
+ {
+ for (int i = 0; i < devices.Count(); ++i)
+ {
+ if (devices[i] == this)
+ {
+ devices.Remove(i);
+ return;
+ }
+ }
+ }
+
+private:
+ static Array devices;
+
+ template
+ int GetItemIndex(const char* name, const Array& Array) const
+ {
+ for (int i = 0; i < Array.Count(); ++i)
+ {
+ if (Array[i] == name)
+ return i;
+ }
+ return -1;
+ }
+
+ static InputDevice* GetDevice(const char* name)
+ {
+ for (int i = 0; i < devices.Count(); ++i)
+ {
+ if (devices[i]->m_name == name)
+ return devices[i];
+ }
+ return nullptr;
+ }
+};
+
+} /* namespace lol */
+
+#endif // LOL_INPUT_V2
+
+#endif // __LOL_INPUT_DEVICE_H__
+
diff --git a/src/input/inputdevice_internal.h b/src/input/inputdevice_internal.h
new file mode 100644
index 00000000..b1b91e3c
--- /dev/null
+++ b/src/input/inputdevice_internal.h
@@ -0,0 +1,46 @@
+//
+// Lol Engine
+//
+// Copyright: (c) 2010-2013 Benjamin Litzelmann
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the Do What The Fuck You Want To
+// Public License, Version 2, as published by Sam Hocevar. See
+// http://www.wtfpl.net/ for more details.
+//
+
+#if !defined __LOL_INPUT_DEVICE_INTERNAL_H__
+#define __LOL_INPUT_DEVICE_H__
+
+#if defined LOL_INPUT_V2
+
+#include "core.h"
+
+namespace lol
+{
+
+/** Internal class (not public) that allows to construct an InputDevice dynamically, when the keys, axis and cursors are not known at compile time */
+class InputDeviceInternal : InputDevice
+{
+public:
+ InputDeviceInternal(const char* name) : InputDevice(name) { }
+
+ void AddKey(const char* name);
+ void AddAxis(const char* name, float sensitivity = 1.0f);
+ void AddCursor(const char* name);
+
+ void SetKey(int index, bool state) { m_keys[index] = state; }
+ void SetAxis(int index, float value) { m_axis[index].m1 = value; }
+ void SetCursor(int index, const vec2& position, const ivec2& pixel) { m_cursors[index].m1 = position; m_cursors[index].m2 = pixel; }
+
+ static bool GetMouseCapture() { return m_capturemouse; }
+
+ static InputDeviceInternal* CreateStandardKeyboard();
+ static InputDeviceInternal* CreateStandardMouse();
+};
+
+} /* namespace lol */
+
+#endif // LOL_INPUT_V2
+
+#endif // __LOL_INPUT_DEVICE_INTERNAL_H__
+
diff --git a/src/input/keyboard.cpp b/src/input/keyboard.cpp
index 42a6e2b8..b2b384d3 100644
--- a/src/input/keyboard.cpp
+++ b/src/input/keyboard.cpp
@@ -8,6 +8,8 @@
// http://www.wtfpl.net/ for more details.
//
+#ifndef LOL_INPUT_V2
+
#if defined HAVE_CONFIG_H
# include "config.h"
#endif
@@ -66,3 +68,4 @@ uint32_t Keyboard::PopChar()
} /* namespace lol */
+#endif // !LOL_INPUT_V2
diff --git a/src/input/keyboard.h b/src/input/keyboard.h
index 31ba0c7f..e9e8358c 100644
--- a/src/input/keyboard.h
+++ b/src/input/keyboard.h
@@ -16,6 +16,8 @@
#if !defined __LOL_INPUT_KEYBOARD_H__
#define __LOL_INPUT_KEYBOARD_H__
+#ifndef LOL_INPUT_V2
+
#include "entity.h"
namespace lol
@@ -39,5 +41,7 @@ private:
} /* namespace lol */
+#endif // !LOL_INPUT_V2
+
#endif // __LOL_INPUT_KEYBOARD_H__
diff --git a/src/input/keys.h b/src/input/keys.h
new file mode 100644
index 00000000..cc75db42
--- /dev/null
+++ b/src/input/keys.h
@@ -0,0 +1,266 @@
+//
+// Lol Engine
+//
+// Copyright: (c) 2010-2013 Benjamin Litzelmann
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the Do What The Fuck You Want To
+// Public License) Version 2) as published by Sam Hocevar. See
+// http://www.wtfpl.net/ for more details.
+//
+
+#if defined KEY_FUNC
+
+/* ASCII mapped keys */
+KEY_FUNC(Unknown, 0)
+KEY_FUNC(First, 0)
+KEY_FUNC(Backspace, 8)
+KEY_FUNC(Tab, (int)'\t')
+KEY_FUNC(Clear, 12)
+KEY_FUNC(Return, 13)
+KEY_FUNC(Pause, 19)
+KEY_FUNC(Escape, 27)
+KEY_FUNC(Space, (int)' ')
+KEY_FUNC(Exclaim, (int)'!')
+KEY_FUNC(DoubleQuote, (int)'"')
+KEY_FUNC(Hash, (int)'#')
+KEY_FUNC(Dollar, (int)'$')
+KEY_FUNC(Ampersand, (int)'&')
+KEY_FUNC(Quote, (int)'\'')
+KEY_FUNC(LeftParen, (int)'(')
+KEY_FUNC(RightParen, (int)')')
+KEY_FUNC(Asterisk, (int)'*')
+KEY_FUNC(Plus, (int)'+')
+KEY_FUNC(Comma, (int)')')
+KEY_FUNC(Minus, (int)'-')
+KEY_FUNC(Period, (int)'.')
+KEY_FUNC(Slash, (int)'/')
+KEY_FUNC(K0, (int)'0')
+KEY_FUNC(K1, (int)'1')
+KEY_FUNC(K2, (int)'2')
+KEY_FUNC(K3, (int)'3')
+KEY_FUNC(K4, (int)'4')
+KEY_FUNC(K5, (int)'5')
+KEY_FUNC(K6, (int)'6')
+KEY_FUNC(K7, (int)'7')
+KEY_FUNC(K8, (int)'8')
+KEY_FUNC(K9, (int)'9')
+KEY_FUNC(Colon, (int)':')
+KEY_FUNC(Semicolon, (int)';')
+KEY_FUNC(Less, (int)'<')
+KEY_FUNC(Equals, (int)'=')
+KEY_FUNC(Greater, (int)'>')
+KEY_FUNC(Question, (int)'?')
+KEY_FUNC(At, (int)'@')
+/* XXX: SDL decides to skip uppercase characters */
+KEY_FUNC(LeftBracket, (int)'[')
+KEY_FUNC(BackSlash, (int)'\\')
+KEY_FUNC(RightBracket, (int)']')
+KEY_FUNC(Caret, (int)'^')
+KEY_FUNC(Underscore, (int)'_')
+KEY_FUNC(Backquote, (int)'`')
+KEY_FUNC(A, (int)'a')
+KEY_FUNC(B, (int)'b')
+KEY_FUNC(C, (int)'c')
+KEY_FUNC(D, (int)'d')
+KEY_FUNC(E, (int)'e')
+KEY_FUNC(F, (int)'f')
+KEY_FUNC(G, (int)'g')
+KEY_FUNC(H, (int)'h')
+KEY_FUNC(I, (int)'i')
+KEY_FUNC(J, (int)'j')
+KEY_FUNC(K, (int)'k')
+KEY_FUNC(L, (int)'l')
+KEY_FUNC(M, (int)'m')
+KEY_FUNC(N, (int)'n')
+KEY_FUNC(O, (int)'o')
+KEY_FUNC(P, (int)'p')
+KEY_FUNC(Q, (int)'q')
+KEY_FUNC(R, (int)'r')
+KEY_FUNC(S, (int)'s')
+KEY_FUNC(T, (int)'t')
+KEY_FUNC(U, (int)'u')
+KEY_FUNC(V, (int)'v')
+KEY_FUNC(W, (int)'w')
+KEY_FUNC(X, (int)'x')
+KEY_FUNC(Y, (int)'y')
+KEY_FUNC(Z, (int)'z')
+KEY_FUNC(Delete, 127)
+
+/* International keyboard syms */
+#ifndef KEY_DISABLE_WORLD
+KEY_FUNC(World0, 160) /* 0xA0 */
+KEY_FUNC(World1, 161)
+KEY_FUNC(World2, 162)
+KEY_FUNC(World3, 163)
+KEY_FUNC(World4, 164)
+KEY_FUNC(World5, 165)
+KEY_FUNC(World6, 166)
+KEY_FUNC(World7, 167)
+KEY_FUNC(World8, 168)
+KEY_FUNC(World9, 169)
+KEY_FUNC(World10, 170)
+KEY_FUNC(World11, 171)
+KEY_FUNC(World12, 172)
+KEY_FUNC(World13, 173)
+KEY_FUNC(World14, 174)
+KEY_FUNC(World15, 175)
+KEY_FUNC(World16, 176)
+KEY_FUNC(World17, 177)
+KEY_FUNC(World18, 178)
+KEY_FUNC(World19, 179)
+KEY_FUNC(World20, 180)
+KEY_FUNC(World21, 181)
+KEY_FUNC(World22, 182)
+KEY_FUNC(World23, 183)
+KEY_FUNC(World24, 184)
+KEY_FUNC(World25, 185)
+KEY_FUNC(World26, 186)
+KEY_FUNC(World27, 187)
+KEY_FUNC(World28, 188)
+KEY_FUNC(World29, 189)
+KEY_FUNC(World30, 190)
+KEY_FUNC(World31, 191)
+KEY_FUNC(World32, 192)
+KEY_FUNC(World33, 193)
+KEY_FUNC(World34, 194)
+KEY_FUNC(World35, 195)
+KEY_FUNC(World36, 196)
+KEY_FUNC(World37, 197)
+KEY_FUNC(World38, 198)
+KEY_FUNC(World39, 199)
+KEY_FUNC(World40, 200)
+KEY_FUNC(World41, 201)
+KEY_FUNC(World42, 202)
+KEY_FUNC(World43, 203)
+KEY_FUNC(World44, 204)
+KEY_FUNC(World45, 205)
+KEY_FUNC(World46, 206)
+KEY_FUNC(World47, 207)
+KEY_FUNC(World48, 208)
+KEY_FUNC(World49, 209)
+KEY_FUNC(World50, 210)
+KEY_FUNC(World51, 211)
+KEY_FUNC(World52, 212)
+KEY_FUNC(World53, 213)
+KEY_FUNC(World54, 214)
+KEY_FUNC(World55, 215)
+KEY_FUNC(World56, 216)
+KEY_FUNC(World57, 217)
+KEY_FUNC(World58, 218)
+KEY_FUNC(World59, 219)
+KEY_FUNC(World60, 220)
+KEY_FUNC(World61, 221)
+KEY_FUNC(World62, 222)
+KEY_FUNC(World63, 223)
+KEY_FUNC(World64, 224)
+KEY_FUNC(World65, 225)
+KEY_FUNC(World66, 226)
+KEY_FUNC(World67, 227)
+KEY_FUNC(World68, 228)
+KEY_FUNC(World69, 229)
+KEY_FUNC(World70, 230)
+KEY_FUNC(World71, 231)
+KEY_FUNC(World72, 232)
+KEY_FUNC(World73, 233)
+KEY_FUNC(World74, 234)
+KEY_FUNC(World75, 235)
+KEY_FUNC(World76, 236)
+KEY_FUNC(World77, 237)
+KEY_FUNC(World78, 238)
+KEY_FUNC(World79, 239)
+KEY_FUNC(World80, 240)
+KEY_FUNC(World81, 241)
+KEY_FUNC(World82, 242)
+KEY_FUNC(World83, 243)
+KEY_FUNC(World84, 244)
+KEY_FUNC(World85, 245)
+KEY_FUNC(World86, 246)
+KEY_FUNC(World87, 247)
+KEY_FUNC(World88, 248)
+KEY_FUNC(World89, 249)
+KEY_FUNC(World90, 250)
+KEY_FUNC(World91, 251)
+KEY_FUNC(World92, 252)
+KEY_FUNC(World93, 253)
+KEY_FUNC(World94, 254)
+KEY_FUNC(World95, 255) /* 0xFF */
+#endif // !KEY_DISABLE_WORLD
+
+/* Numeric keypad */
+KEY_FUNC(KP0, 256)
+KEY_FUNC(KP1, 257)
+KEY_FUNC(KP2, 258)
+KEY_FUNC(KP3, 259)
+KEY_FUNC(KP4, 260)
+KEY_FUNC(KP5, 261)
+KEY_FUNC(KP6, 262)
+KEY_FUNC(KP7, 263)
+KEY_FUNC(KP8, 264)
+KEY_FUNC(KP9, 265)
+KEY_FUNC(KPPeriod, 266)
+KEY_FUNC(KPDivide, 267)
+KEY_FUNC(KPMultiply, 268)
+KEY_FUNC(KPMinus, 269)
+KEY_FUNC(KPPlus, 270)
+KEY_FUNC(KPEnter, 271)
+KEY_FUNC(KPEquals, 272)
+
+/* Arrows + Home/End pad */
+KEY_FUNC(Up, 273)
+KEY_FUNC(Down, 274)
+KEY_FUNC(Right, 275)
+KEY_FUNC(Left, 276)
+KEY_FUNC(Insert, 277)
+KEY_FUNC(Home, 278)
+KEY_FUNC(End, 279)
+KEY_FUNC(PageUp, 280)
+KEY_FUNC(PageDown, 281)
+
+/* Function keys */
+KEY_FUNC(F1, 282)
+KEY_FUNC(F2, 283)
+KEY_FUNC(F3, 284)
+KEY_FUNC(F4, 285)
+KEY_FUNC(F5, 286)
+KEY_FUNC(F6, 287)
+KEY_FUNC(F7, 288)
+KEY_FUNC(F8, 289)
+KEY_FUNC(F9, 290)
+KEY_FUNC(F10, 291)
+KEY_FUNC(F11, 292)
+KEY_FUNC(F12, 293)
+KEY_FUNC(F13, 294)
+KEY_FUNC(F14, 295)
+KEY_FUNC(F15, 296)
+
+/* Modifier keys */
+KEY_FUNC(NumLock, 300)
+KEY_FUNC(CapsLock, 301)
+KEY_FUNC(ScrollLock, 302)
+KEY_FUNC(RightShift, 303)
+KEY_FUNC(LeftShift, 304)
+KEY_FUNC(RightCtrl, 305)
+KEY_FUNC(LeftCtrl, 306)
+KEY_FUNC(RightAlt, 307)
+KEY_FUNC(LeftAlt, 308)
+KEY_FUNC(RightMeta, 309)
+KEY_FUNC(LeftMeta, 310)
+KEY_FUNC(LeftSuper, 311) /* Left "Windows" key */
+KEY_FUNC(RightSuper, 312) /* Right "Windows" key */
+KEY_FUNC(Mode, 313) /* "Alt Gr" key */
+KEY_FUNC(Compose, 314) /* Multi-key compose key */
+
+/* Miscellaneous function keys */
+KEY_FUNC(Help, 315)
+KEY_FUNC(Print, 316)
+KEY_FUNC(SysReq, 317)
+KEY_FUNC(Break, 318)
+KEY_FUNC(Menu, 319)
+KEY_FUNC(Power, 320) /* Power Macintosh power key */
+KEY_FUNC(Euro, 321) /* Some european keyboards */
+KEY_FUNC(Undo, 322) /* Atari keyboard has Undo */
+
+/* Add any other keys here, but ensure Last value matches the last + 1 */
+KEY_FUNC(Last, 323)
+
+#endif // KEY_FUNC
diff --git a/src/input/stick.cpp b/src/input/stick.cpp
index 65140acf..05fee2d4 100644
--- a/src/input/stick.cpp
+++ b/src/input/stick.cpp
@@ -8,6 +8,8 @@
// http://www.wtfpl.net/ for more details.
//
+#ifndef LOL_INPUT_V2
+
#if defined HAVE_CONFIG_H
# include "config.h"
#endif
@@ -107,3 +109,4 @@ int Stick::GetButton(int n)
} /* namespace lol */
+#endif // !LOL_INPUT_V2
diff --git a/src/input/stick.h b/src/input/stick.h
index c3f95787..da5c64a4 100644
--- a/src/input/stick.h
+++ b/src/input/stick.h
@@ -16,6 +16,8 @@
#if !defined __LOL_INPUT_STICK_H__
#define __LOL_INPUT_STICK_H__
+#ifndef LOL_INPUT_V2
+
#include "entity.h"
namespace lol
@@ -48,5 +50,7 @@ private:
} /* namespace lol */
+#endif // !LOL_INPUT_V2
+
#endif // __LOL_INPUT_STICK_H__
diff --git a/src/lolcore.vcxproj b/src/lolcore.vcxproj
index 16300ed1..cec031dc 100644
--- a/src/lolcore.vcxproj
+++ b/src/lolcore.vcxproj
@@ -144,7 +144,9 @@
+
+
@@ -205,8 +207,12 @@
+
+
+
+
diff --git a/src/lolcore.vcxproj.filters b/src/lolcore.vcxproj.filters
index 565d851f..811ab416 100644
--- a/src/lolcore.vcxproj.filters
+++ b/src/lolcore.vcxproj.filters
@@ -312,6 +312,12 @@
debug
+
+ input
+
+
+ input
+
@@ -608,6 +614,18 @@
lol\image
+
+ input
+
+
+ input
+
+
+ input
+
+
+ input
+
diff --git a/src/platform/d3d9/d3d9input.cpp b/src/platform/d3d9/d3d9input.cpp
index a9809278..23d99dcc 100644
--- a/src/platform/d3d9/d3d9input.cpp
+++ b/src/platform/d3d9/d3d9input.cpp
@@ -20,6 +20,10 @@
#include "core.h"
#include "d3d9input.h"
+#ifdef LOL_INPUT_V2
+#include "input/inputdevice_internal.h"
+#endif // LOL_INPUT_V2
+
namespace lol
{
@@ -33,8 +37,12 @@ class D3d9InputData
private:
#if defined USE_XINPUT
+#if defined LOL_INPUT_V2
+ Array m_joysticks;
+#else
Array m_joysticks;
-#endif
+#endif // LOL_INPUT_V2
+#endif // USE_XINPUT
};
/*
@@ -50,11 +58,21 @@ D3d9Input::D3d9Input()
XINPUT_STATE state;
if (XInputGetState(i, &state) != ERROR_SUCCESS)
continue;
-
+#if defined LOL_INPUT_V2
+ // TODO: we can put more friendly name here, such as LeftAxisX, ButtonX...
+ InputDeviceInternal* stick = new InputDeviceInternal(String::Printf("Joystick%d", i+1).C());
+ for (int j = 0; j < 4; ++j)
+ stick->AddAxis(String::Printf("Axis%d", j+1).C());
+ for (int j = 0; j < 16; ++j)
+ stick->AddKey(String::Printf("Button%d", j+1).C());
+
+ m_data->m_joysticks.Push(i, stick);
+#else
Stick *stick = Input::CreateStick();
stick->SetAxisCount(4);
stick->SetButtonCount(16);
m_data->m_joysticks.Push(i, stick);
+#endif // LOL_INPUT_V2
}
#endif
@@ -67,8 +85,12 @@ D3d9Input::~D3d9Input()
/* Unregister all the joysticks we added */
while (m_data->m_joysticks.Count())
{
- Input::DestroyStick(m_data->m_joysticks[0].m2);
- m_data->m_joysticks.Remove(0);
+#if defined LOL_INPUT_V2
+ delete m_data->m_joysticks[0].m2;
+#else
+ Input::DestroyStick(m_data->m_joysticks[0].m2);
+#endif // LOL_INPUT_V2
+ m_data->m_joysticks.Remove(0);
}
#endif
delete m_data;
@@ -96,8 +118,12 @@ void D3d9Input::TickDraw(float seconds)
m_data->m_joysticks[i].m2->SetAxis(3, -(float)state.Gamepad.sThumbRY / 32768.f);
for (int b = 0; b < 16; b++)
- m_data->m_joysticks[i].m2->SetButton(b, ((uint16_t)(state.Gamepad.wButtons) >> b) & 1);
- }
+#if defined LOL_INPUT_V2
+ m_data->m_joysticks[i].m2->SetKey(b, ((uint16_t)(state.Gamepad.wButtons) >> b) & 1);
+#else
+ m_data->m_joysticks[i].m2->SetButton(b, ((uint16_t)(state.Gamepad.wButtons) >> b) & 1);
+#endif // LOL_INPUT_V2
+ }
#endif
}
diff --git a/src/platform/sdl/sdlapp.cpp b/src/platform/sdl/sdlapp.cpp
index 57289083..bbd93a00 100644
--- a/src/platform/sdl/sdlapp.cpp
+++ b/src/platform/sdl/sdlapp.cpp
@@ -66,6 +66,12 @@ SdlApp::SdlApp(char const *title, ivec2 res, float fps) :
exit(EXIT_FAILURE);
}
+# ifdef LOL_INPUT_V2
+ const SDL_VideoInfo* vidinfo = SDL_GetVideoInfo();
+ int screen_w = vidinfo->current_w;
+ int screen_h = vidinfo->current_h;
+# endif
+
# if defined USE_D3D9
SDL_Surface *video = SDL_SetVideoMode(res.x, res.y, 16, 0);
SDL_SysWMinfo wminfo;
@@ -77,6 +83,9 @@ SdlApp::SdlApp(char const *title, ivec2 res, float fps) :
# else
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
+# ifdef LOL_INPUT_V2
+ // TODO: when implementing fullscreen, be sure to overwrite screen_w and screen_h with the value of vidinfo after the call to SDL_SetVideoMode
+# endif
SDL_Surface *video = SDL_SetVideoMode(res.x, res.y, 0, SDL_OPENGL);
# endif
if (!video)
@@ -100,7 +109,11 @@ SdlApp::SdlApp(char const *title, ivec2 res, float fps) :
new D3d9Input();
# endif
- new SdlInput();
+# ifdef LOL_INPUT_V2
+ new SdlInput(video->w, video->h, screen_w, screen_h);
+# else
+ new SdlInput();
+# endif
#endif
}
diff --git a/src/platform/sdl/sdlinput.cpp b/src/platform/sdl/sdlinput.cpp
index 5022c1a0..54378ebd 100644
--- a/src/platform/sdl/sdlinput.cpp
+++ b/src/platform/sdl/sdlinput.cpp
@@ -23,6 +23,10 @@
#include "core.h"
#include "sdlinput.h"
+#ifdef LOL_INPUT_V2
+#include "input/inputdevice_internal.h"
+#endif // LOL_INPUT_V2
+
/* We force joystick polling because no events are received when
* there is no SDL display (eg. on the Raspberry Pi). */
#define SDL_FORCE_POLL_JOYSTICK 1
@@ -42,17 +46,44 @@ private:
void Tick(float seconds);
static ivec2 GetMousePos();
+ static void SetMousePos(ivec2 position);
+
#if USE_SDL
+# ifdef LOL_INPUT_V2
+ SdlInputData(int app_w, int app_h, int screen_w, int screen_h) :
+ m_prevmouse(ivec2(0)),
+ m_app_w((float)app_w),
+ m_app_h((float)app_h),
+ m_screen_w((float)screen_w),
+ m_screen_h((float)screen_h)
+ { }
+
+ Array m_joysticks;
+ InputDeviceInternal* m_mouse;
+ InputDeviceInternal* m_keyboard;
+ ivec2 m_prevmouse;
+ float m_app_w;
+ float m_app_h;
+ float m_screen_w;
+ float m_screen_h;
+ bool m_mousecapture;
+# else
Array m_joysticks;
-#endif
+# endif // LOL_INPUT_V2
+#endif // USE_SDL
};
/*
* Public SdlInput class
*/
+#ifdef LOL_INPUT_V2
+SdlInput::SdlInput(int app_w, int app_h, int screen_w, int screen_h)
+ : m_data(new SdlInputData(app_w, app_h, screen_w, screen_h))
+#else
SdlInput::SdlInput()
: m_data(new SdlInputData())
+#endif
{
#if USE_SDL
/* Enable Unicode translation of keyboard events */
@@ -67,6 +98,11 @@ SdlInput::SdlInput()
SDL_JoystickEventState(SDL_ENABLE);
# endif
+#ifdef LOL_INPUT_V2
+ m_data->m_keyboard = InputDeviceInternal::CreateStandardKeyboard();
+ m_data->m_mouse = InputDeviceInternal::CreateStandardMouse();
+#endif
+
/* Register all the joysticks we can find, and let the input
* system decide what it wants to track. */
for (int i = 0; i < SDL_NumJoysticks(); i++)
@@ -88,6 +124,15 @@ SdlInput::SdlInput()
continue;
}
+# ifdef LOL_INPUT_V2
+ InputDeviceInternal* stick = new InputDeviceInternal(String::Printf("Joystick%d", i+1).C());
+ for (int i = 0; i < SDL_JoystickNumAxes(sdlstick); ++i)
+ stick->AddAxis(String::Printf("Axis%d", i+1).C());
+ for (int i = 0; i < SDL_JoystickNumButtons(sdlstick); ++i)
+ stick->AddKey(String::Printf("Button%d", i+1).C());
+
+ m_data->m_joysticks.Push(sdlstick, stick);
+# else // !LOL_INPUT_V2
Stick *stick = Input::CreateStick();
stick->SetAxisCount(SDL_JoystickNumAxes(sdlstick));
stick->SetButtonCount(SDL_JoystickNumButtons(sdlstick));
@@ -97,6 +142,7 @@ SdlInput::SdlInput()
//stick->RemapAxis(2, 4);
m_data->m_joysticks.Push(sdlstick, stick);
+# endif
}
# endif
#endif
@@ -111,7 +157,11 @@ SdlInput::~SdlInput()
while (m_data->m_joysticks.Count())
{
SDL_JoystickClose(m_data->m_joysticks[0].m1);
+# ifdef LOL_INPUT_V2
+ delete m_data->m_joysticks[0].m2;
+# else
Input::DestroyStick(m_data->m_joysticks[0].m2);
+# endif
m_data->m_joysticks.Remove(0);
}
#endif
@@ -139,19 +189,23 @@ void SdlInput::TickDraw(float seconds)
void SdlInputData::Tick(float seconds)
{
#if USE_SDL
- /* Handle mouse input */
- ivec2 mouse = SdlInputData::GetMousePos();;
- Input::SetMousePos(mouse);
-
/* Pump all joystick events because no event is coming to us. */
# if SDL_FORCE_POLL_JOYSTICK && !EMSCRIPTEN
SDL_JoystickUpdate();
for (int j = 0; j < m_joysticks.Count(); j++)
{
+# ifdef LOL_INPUT_V2
+ for (int i = 0; i < SDL_JoystickNumButtons(m_joysticks[j].m1); i++)
+ m_joysticks[j].m2->SetKey(i, SDL_JoystickGetButton(m_joysticks[j].m1, i) != 0);
+ for (int i = 0; i < SDL_JoystickNumAxes(m_joysticks[j].m1); i++)
+ m_joysticks[j].m2->SetAxis(i, (float)SDL_JoystickGetAxis(m_joysticks[j].m1, i) / 32768.f);
+# else // !LOL_INPUT_V2
for (int i = 0; i < SDL_JoystickNumButtons(m_joysticks[j].m1); i++)
m_joysticks[j].m2->SetButton(i, SDL_JoystickGetButton(m_joysticks[j].m1, i));
for (int i = 0; i < SDL_JoystickNumAxes(m_joysticks[j].m1); i++)
m_joysticks[j].m2->SetAxis(i, (float)SDL_JoystickGetAxis(m_joysticks[j].m1, i) / 32768.f);
+
+# endif
}
# endif
@@ -173,17 +227,28 @@ void SdlInputData::Tick(float seconds)
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
{
- ivec2 newmouse = SdlInputData::GetMousePos();
- if (newmouse != mouse)
- Input::SetMousePos(mouse = newmouse);
+#ifdef LOL_INPUT_V2
+ m_mouse->SetKey(event.button.button - 1, event.type == SDL_MOUSEBUTTONDOWN);
+#else // !LOL_INPUT_V2
if (event.type == SDL_MOUSEBUTTONDOWN)
Input::SetMouseButton(event.button.button - 1);
else
Input::UnsetMouseButton(event.button.button - 1);
+#endif // LOL_INPUT_V2
break;
}
# if !SDL_FORCE_POLL_JOYSTICK
+# ifdef LOL_INPUT_V2
+ case SDL_JOYAXISMOTION:
+ m_joysticks[event.jaxis.which].m2->SetAxis(event.jaxis.axis, (float)event.jaxis.value / 32768.f);
+ break;
+
+ case SDL_JOYBUTTONUP:
+ case SDL_JOYBUTTONDOWN:
+ m_joysticks[event.jbutton.which].m2->SetKey(event.jbutton.button, event.jbutton.state);
+ break;
+# else // !LOL_INPUT_V2
case SDL_JOYAXISMOTION:
m_joysticks[event.jaxis.which].m2->SetAxis(event.jaxis.axis, (float)event.jaxis.value / 32768.f);
break;
@@ -192,12 +257,40 @@ void SdlInputData::Tick(float seconds)
case SDL_JOYBUTTONDOWN:
m_joysticks[event.jbutton.which].m2->SetButton(event.jbutton.button, event.jbutton.state);
break;
+# endif // LOL_INPUT_V2
# endif
}
}
- /* Send the whole keyboard state to the input system */
- Array &lolstate = Input::GetKeyboardState();
+ /* Handle mouse input */
+ ivec2 mouse = SdlInputData::GetMousePos();
+# ifdef LOL_INPUT_V2
+ if (InputDeviceInternal::GetMouseCapture() != m_mousecapture)
+ {
+ m_mousecapture = InputDeviceInternal::GetMouseCapture();
+ SDL_WM_GrabInput(m_mousecapture ? SDL_GRAB_ON : SDL_GRAB_OFF);
+ //SDL_ShowCursor(m_mousecapture ? SDL_DISABLE : SDL_ENABLE);
+ }
+
+ if (mouse.x >= 0 && mouse.x < m_app_w && mouse.y >= 0 && mouse.y < m_app_h)
+ {
+ m_mouse->SetCursor(0, vec2((float)(mouse.x) / m_app_w, (float)(mouse.y) / m_app_h), mouse);
+ // Note: 100.0f is an arbitrary value that makes it feel about the same than an xbox controller joystick
+ m_mouse->SetAxis(0, (float)(mouse.x - m_prevmouse.x) * 100.0f / m_screen_w);
+ m_mouse->SetAxis(1, (float)(mouse.y - m_prevmouse.y) * 100.0f / m_screen_h);
+ }
+
+ if (m_mousecapture)
+ {
+ mouse = ivec2((int)m_app_w / 2, (int)m_app_h / 2);
+ SdlInputData::SetMousePos(mouse);
+ }
+
+ m_prevmouse = mouse;
+
+# else // !LOL_INPUT_V2
+ Input::SetMousePos(mouse);
+# endif // LOL_INPUT_V2
# if SDL_VERSION_ATLEAST(1,3,0)
Uint8 *sdlstate = SDL_GetKeyboardState(nullptr);
@@ -205,6 +298,19 @@ void SdlInputData::Tick(float seconds)
Uint8 *sdlstate = SDL_GetKeyState(nullptr);
# endif
+ int keyindex = 0;
+# ifdef LOL_INPUT_V2
+# define KEY_FUNC(name, index) m_keyboard->SetKey(keyindex++, sdlstate[index] != 0);
+# if !defined SDLK_WORLD_0
+# define KEY_DISABLE_WORLD
+# endif // !SDLK_WORLD_0
+# include "input/keys.h"
+# undef KEY_FUNC
+# else // !LOL_INPUT_V2
+
+ /* Send the whole keyboard state to the input system */
+ Array &lolstate = Input::GetKeyboardState();
+
lolstate[Key::Unknown] = sdlstate[SDLK_UNKNOWN];
lolstate[Key::Backspace] = sdlstate[SDLK_BACKSPACE];
lolstate[Key::Tab] = sdlstate[SDLK_TAB];
@@ -376,7 +482,7 @@ void SdlInputData::Tick(float seconds)
lolstate[Key::World93] = sdlstate[SDLK_WORLD_93];
lolstate[Key::World94] = sdlstate[SDLK_WORLD_94];
lolstate[Key::World95] = sdlstate[SDLK_WORLD_95];
-#endif
+#endif // SDLK_WORLD_0
lolstate[Key::KP0] = sdlstate[SDLK_KP0];
lolstate[Key::KP1] = sdlstate[SDLK_KP1];
@@ -448,7 +554,9 @@ void SdlInputData::Tick(float seconds)
lolstate[Key::Undo] = sdlstate[SDLK_UNDO];
UNUSED(seconds);
-#endif
+# endif // LOL_INPUT_V2
+
+#endif // USE_SDL
}
ivec2 SdlInputData::GetMousePos()
@@ -467,5 +575,10 @@ ivec2 SdlInputData::GetMousePos()
return ret;
}
+void SdlInputData::SetMousePos(ivec2 position)
+{
+ SDL_WarpMouse((uint16_t)position.x, (uint16_t)position.y);
+}
+
} /* namespace lol */
diff --git a/src/platform/sdl/sdlinput.h b/src/platform/sdl/sdlinput.h
index 56feb041..50f360db 100644
--- a/src/platform/sdl/sdlinput.h
+++ b/src/platform/sdl/sdlinput.h
@@ -26,8 +26,14 @@ class SdlInputData;
class SdlInput : public Entity
{
public:
+#ifdef LOL_INPUT_V2
+ /** passing the screen resolution (note: not the windowed app resolution!) allows to make the mouse axis resolution-independent */
+ SdlInput(int app_w, int app_h, int screen_w, int screen_h);
+#else
SdlInput();
+#endif
virtual ~SdlInput();
+ void SetScreenResolution();
protected:
virtual void TickGame(float seconds);