diff --git a/DanBias.sln b/DanBias.sln
new file mode 100644
index 00000000..bf7eb41b
--- /dev/null
+++ b/DanBias.sln
@@ -0,0 +1,165 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OysterGraphics", "OysterGraphics\OysterGraphics.vcxproj", "{0EC83E64-230E-48EF-B08C-6AC9651B4F82}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OysterMath", "OysterMath\OysterMath.vcxproj", "{F10CBC03-9809-4CBA-95D8-327C287B18EE}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OysterPhysics3D", "OysterPhysics3D\OysterPhysics3D.vcxproj", "{4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Sound", "Sound\Sound.vcxproj", "{34D6295A-00DD-4B1A-8258-97DA2818EC26}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowManager", "WindowManager\WindowManager.vcxproj", "{35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Input", "Input\Input.vcxproj", "{7E3990D2-3D94-465C-B58D-64A74B3ECF9B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Misc", "Misc\Misc.vcxproj", "{2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Network", "Network", "{C27B926E-B3EF-4990-8822-47580E43A0BE}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OysterNetworkClient", "Network\OysterNetworkClient\OysterNetworkClient.vcxproj", "{838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OysterNetworkServer", "Network\OysterNetworkServer\OysterNetworkServer.vcxproj", "{6A066806-F43F-4B31-A4E3-57179674F460}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NetworkDependencies", "Network\NetworkDependencies\NetworkDependencies.vcxproj", "{C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Mixed Platforms = Debug|Mixed Platforms
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Mixed Platforms = Release|Mixed Platforms
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+ {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+ {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|Win32.Build.0 = Debug|Win32
+ {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|x64.ActiveCfg = Debug|x64
+ {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Debug|x64.Build.0 = Debug|x64
+ {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|Mixed Platforms.Build.0 = Release|Win32
+ {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|Win32.ActiveCfg = Release|Win32
+ {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|Win32.Build.0 = Release|Win32
+ {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|x64.ActiveCfg = Release|x64
+ {0EC83E64-230E-48EF-B08C-6AC9651B4F82}.Release|x64.Build.0 = Release|x64
+ {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+ {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+ {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|Win32.Build.0 = Debug|Win32
+ {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|x64.ActiveCfg = Debug|x64
+ {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Debug|x64.Build.0 = Debug|x64
+ {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|Mixed Platforms.Build.0 = Release|Win32
+ {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|Win32.ActiveCfg = Release|Win32
+ {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|Win32.Build.0 = Release|Win32
+ {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|x64.ActiveCfg = Release|x64
+ {F10CBC03-9809-4CBA-95D8-327C287B18EE}.Release|x64.Build.0 = Release|x64
+ {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+ {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+ {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|Win32.Build.0 = Debug|Win32
+ {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|x64.ActiveCfg = Debug|x64
+ {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Debug|x64.Build.0 = Debug|x64
+ {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|Mixed Platforms.Build.0 = Release|Win32
+ {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|Win32.ActiveCfg = Release|Win32
+ {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|Win32.Build.0 = Release|Win32
+ {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|x64.ActiveCfg = Release|x64
+ {4285BD3F-3C6C-4670-B7AF-A29AFEF5F6A8}.Release|x64.Build.0 = Release|x64
+ {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+ {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+ {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|Win32.ActiveCfg = Debug|Win32
+ {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|Win32.Build.0 = Debug|Win32
+ {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|x64.ActiveCfg = Debug|x64
+ {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Debug|x64.Build.0 = Debug|x64
+ {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|Mixed Platforms.Build.0 = Release|Win32
+ {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|Win32.ActiveCfg = Release|Win32
+ {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|Win32.Build.0 = Release|Win32
+ {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|x64.ActiveCfg = Release|x64
+ {34D6295A-00DD-4B1A-8258-97DA2818EC26}.Release|x64.Build.0 = Release|x64
+ {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+ {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+ {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|Win32.ActiveCfg = Debug|Win32
+ {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|Win32.Build.0 = Debug|Win32
+ {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|x64.ActiveCfg = Debug|x64
+ {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Debug|x64.Build.0 = Debug|x64
+ {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|Mixed Platforms.Build.0 = Release|Win32
+ {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|Win32.ActiveCfg = Release|Win32
+ {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|Win32.Build.0 = Release|Win32
+ {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|x64.ActiveCfg = Release|x64
+ {35AEA3C0-E0A7-4E1E-88CD-514AA5A442B1}.Release|x64.Build.0 = Release|x64
+ {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+ {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+ {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|Win32.Build.0 = Debug|Win32
+ {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|x64.ActiveCfg = Debug|x64
+ {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Debug|x64.Build.0 = Debug|x64
+ {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|Mixed Platforms.Build.0 = Release|Win32
+ {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|Win32.ActiveCfg = Release|Win32
+ {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|Win32.Build.0 = Release|Win32
+ {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|x64.ActiveCfg = Release|x64
+ {7E3990D2-3D94-465C-B58D-64A74B3ECF9B}.Release|x64.Build.0 = Release|x64
+ {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+ {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+ {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|Win32.Build.0 = Debug|Win32
+ {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|x64.ActiveCfg = Debug|x64
+ {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Debug|x64.Build.0 = Debug|x64
+ {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|Mixed Platforms.Build.0 = Release|Win32
+ {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|Win32.ActiveCfg = Release|Win32
+ {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|Win32.Build.0 = Release|Win32
+ {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|x64.ActiveCfg = Release|x64
+ {2EC4DDED-8F75-4C86-A10B-E1E8EB29F3EE}.Release|x64.Build.0 = Release|x64
+ {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+ {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+ {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|Win32.ActiveCfg = Debug|Win32
+ {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|Win32.Build.0 = Debug|Win32
+ {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|x64.ActiveCfg = Debug|x64
+ {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Debug|x64.Build.0 = Debug|x64
+ {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|Mixed Platforms.Build.0 = Release|Win32
+ {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|Win32.ActiveCfg = Release|Win32
+ {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|Win32.Build.0 = Release|Win32
+ {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|x64.ActiveCfg = Release|x64
+ {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8}.Release|x64.Build.0 = Release|x64
+ {6A066806-F43F-4B31-A4E3-57179674F460}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+ {6A066806-F43F-4B31-A4E3-57179674F460}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+ {6A066806-F43F-4B31-A4E3-57179674F460}.Debug|Win32.ActiveCfg = Debug|Win32
+ {6A066806-F43F-4B31-A4E3-57179674F460}.Debug|Win32.Build.0 = Debug|Win32
+ {6A066806-F43F-4B31-A4E3-57179674F460}.Debug|x64.ActiveCfg = Debug|x64
+ {6A066806-F43F-4B31-A4E3-57179674F460}.Debug|x64.Build.0 = Debug|x64
+ {6A066806-F43F-4B31-A4E3-57179674F460}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {6A066806-F43F-4B31-A4E3-57179674F460}.Release|Mixed Platforms.Build.0 = Release|Win32
+ {6A066806-F43F-4B31-A4E3-57179674F460}.Release|Win32.ActiveCfg = Release|Win32
+ {6A066806-F43F-4B31-A4E3-57179674F460}.Release|Win32.Build.0 = Release|Win32
+ {6A066806-F43F-4B31-A4E3-57179674F460}.Release|x64.ActiveCfg = Release|x64
+ {6A066806-F43F-4B31-A4E3-57179674F460}.Release|x64.Build.0 = Release|x64
+ {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+ {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+ {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|Win32.Build.0 = Debug|Win32
+ {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|x64.ActiveCfg = Debug|x64
+ {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Debug|x64.Build.0 = Debug|x64
+ {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|Mixed Platforms.Build.0 = Release|Win32
+ {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|Win32.ActiveCfg = Release|Win32
+ {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|Win32.Build.0 = Release|Win32
+ {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|x64.ActiveCfg = Release|x64
+ {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {838B25C2-D19E-49FE-8CB0-9A977CA3C7E8} = {C27B926E-B3EF-4990-8822-47580E43A0BE}
+ {6A066806-F43F-4B31-A4E3-57179674F460} = {C27B926E-B3EF-4990-8822-47580E43A0BE}
+ {C5AA09D0-6594-4CD3-BD92-1D380C7B3B50} = {C27B926E-B3EF-4990-8822-47580E43A0BE}
+ EndGlobalSection
+EndGlobal
diff --git a/Dokumentation/Danbias Structure.uxf b/Dokumentation/Danbias Structure.uxf
new file mode 100644
index 00000000..f4c57a75
--- /dev/null
+++ b/Dokumentation/Danbias Structure.uxf
@@ -0,0 +1,428 @@
+
+
+ 9
+
+ com.umlet.element.Class
+
+ 675
+ 342
+ 108
+ 27
+
+ Graphics
+
+
+
+ com.umlet.element.Class
+
+ 441
+ 342
+ 108
+ 27
+
+ Sound
+
+
+
+ com.umlet.element.Class
+
+ 531
+ 279
+ 108
+ 27
+
+ Physics / Math
+
+
+
+ com.umlet.element.Class
+
+ 684
+ 153
+ 99
+ 27
+
+ Game client
+
+
+
+ com.umlet.element.Class
+
+ 351
+ 279
+ 126
+ 27
+
+ Gamelogic
+
+
+
+ com.umlet.element.Class
+
+ 369
+ 153
+ 99
+ 27
+
+ Game server
+
+
+
+ com.umlet.element.Class
+
+ 531
+ 207
+ 108
+ 27
+
+ Network
+
+
+
+ com.umlet.element.Class
+
+ 558
+ 342
+ 108
+ 27
+
+ Input
+
+
+
+ com.umlet.element.Class
+
+ 531
+ 243
+ 108
+ 27
+
+ Threading
+
+
+
+ com.umlet.element.Class
+
+ 531
+ 90
+ 108
+ 36
+
+ DanBias
+bg=green
+
+
+
+ com.umlet.element.Relation
+
+ 702
+ 153
+ 44
+ 206
+
+ lt=<-
+ 27;189;27;171;27;27
+
+
+ com.umlet.element.Relation
+
+ 459
+ 153
+ 287
+ 206
+
+ lt=<-
+ 27;189;27;171;270;171;270;27
+
+
+ com.umlet.element.Relation
+
+ 387
+ 153
+ 44
+ 143
+
+ lt=<-
+ 27;126;27;27
+
+
+ com.umlet.element.Relation
+
+ 612
+ 153
+ 134
+ 152
+
+ lt=<-
+ 27;135;117;135;117;27
+
+
+ com.umlet.element.Relation
+
+ 387
+ 153
+ 161
+ 80
+
+ lt=<-
+ 144;63;27;63;27;27
+
+
+ com.umlet.element.Relation
+
+ 450
+ 261
+ 98
+ 44
+
+ lt=<-
+ 81;27;27;27
+
+
+ com.umlet.element.Relation
+
+ 585
+ 153
+ 161
+ 206
+
+ lt=<-
+ 27;189;27;171;144;171;144;27
+
+
+ com.umlet.element.Relation
+
+ 387
+ 153
+ 161
+ 116
+
+ lt=<-
+ 144;99;27;99;27;27
+
+
+ com.umlet.element.Relation
+
+ 612
+ 153
+ 134
+ 116
+
+ lt=<-
+ 27;99;117;99;117;27
+
+
+ com.umlet.element.Relation
+
+ 612
+ 153
+ 134
+ 80
+
+ lt=<-
+ 27;63;117;63;117;27
+
+
+ com.umlet.element.Relation
+
+ 612
+ 72
+ 134
+ 98
+
+ lt=>-
+ 27;27;117;27;117;81
+
+
+ com.umlet.element.Relation
+
+ 387
+ 72
+ 161
+ 98
+
+ lt=>-
+ 144;27;27;27;27;81
+
+
+ com.umlet.element.Package
+
+ 342
+ 54
+ 450
+ 333
+
+ Game
+
+
+
+ com.umlet.element.Relation
+
+ 702
+ 342
+ 44
+ 134
+
+ lt=<<.
+ 27;27;27;117
+
+
+ com.umlet.element.Package
+
+ 711
+ 459
+ 261
+ 180
+
+ Graphics
+
+
+
+ com.umlet.element.Class
+
+ 720
+ 486
+ 243
+ 144
+
+ <<interface>>
+OysterGfx
+--
+Init(InitData :struct) :enum state
+NewFrame(FrameConstant :struct) :void
+GatherData(Model :struct) :void
+Render() :void
+SetOptions(Options :struct) :void
+LoadModel(file :const wchar[]) :Model*
+Release(resource :Model*) :void
+
+
+
+ com.umlet.element.Package
+
+ 441
+ 459
+ 252
+ 198
+
+ Input
+
+
+
+ com.umlet.element.Relation
+
+ 513
+ 342
+ 116
+ 143
+
+ lt=<<.
+ 99;27;99;126;27;126
+
+
+ com.umlet.element.Class
+
+ 450
+ 486
+ 234
+ 162
+
+ <<interface>>
+RawInput
+--
+Self() :RawInput*
+Destroy() :void
+QueryInput(Key :enum state(RIK)) :void
+Subscribe(Callback :function) :void
+Unsubscribe(Calback :function) :void
+GetError() const :const wchar*
+AddDevice(Data :struct) :enum state
+Enable(Enable :bool) :void
+
+
+
+ com.umlet.element.Class
+
+ 351
+ 342
+ 81
+ 27
+
+ Window API
+
+
+
+ com.umlet.element.Relation
+
+ 360
+ 153
+ 386
+ 206
+
+ lt=<-
+ 27;189;27;171;369;171;369;27
+
+
+ com.umlet.element.Package
+
+ 126
+ 459
+ 306
+ 198
+
+ Sound
+
+
+
+ com.umlet.element.Class
+
+ 135
+ 486
+ 288
+ 99
+
+ <<interface>>
+SoundWrapper
+--
+LoadResource(file :const char*) :ResoureHandle*
+Play(PlayData :struct) :InstanceID
+Stop(InstanceID :int) :void
+Release(Resource :ResourceHandle*) :void
+
+
+
+ com.umlet.element.Class
+
+ 135
+ 612
+ 288
+ 36
+
+ <<API>>
+--
+FMOD
+
+
+
+ com.umlet.element.Relation
+
+ 252
+ 558
+ 44
+ 71
+
+ lt=<<.
+ 27;54;27;27
+
+
+ com.umlet.element.Relation
+
+ 216
+ 342
+ 296
+ 143
+
+ lt=<<.
+ 279;27;279;72;207;72;207;126;27;126
+
+
diff --git a/Dokumentation/Other/FustrumCornerNormalsPseudoCode.txt b/Dokumentation/Other/FustrumCornerNormalsPseudoCode.txt
new file mode 100644
index 00000000..348798f1
--- /dev/null
+++ b/Dokumentation/Other/FustrumCornerNormalsPseudoCode.txt
@@ -0,0 +1,16 @@
+float3 func( in float3 normalA, in float3 normalB, in float3 normalC )
+{
+ return normalize( lerp( lerp(normalA, normalB, 0.5f), lerp(normalA, normalC, 0.5f), 0.5f ) );
+
+}
+
+float3 nearTopLeft = func( f.topPlane.normal, f.leftPlane.normal, f.nearPlane.normal );
+float3 nearTopRight = func( f.topPlane.normal, f.rightPlane.normal, f.nearPlane.normal );
+float3 nearBottomLeft = func( f.bottomPlane.normal, f.leftPlane.normal, f.nearPlane.normal );
+float3 nearBottomRight = func( f.bottomPlane.normal, f.rightPlane.normal, f.nearPlane.normal );
+
+
+float3 farTopLeft = func( f.topPlane.normal, f.leftPlane.normal, f.farPlane.normal );
+float3 farTopRight = func( f.topPlane.normal, f.rightPlane.normal, f.farPlane.normal );
+float3 farBottomLeft = func( f.bottomPlane.normal, f.leftPlane.normal, f.farPlane.normal );
+float3 farBottomRight = func( f.bottomPlane.normal, f.rightPlane.normal, f.farPlane.normal );
diff --git a/Input/Dennis Input/InputCallbackHandler.cpp b/Input/Dennis Input/InputCallbackHandler.cpp
new file mode 100644
index 00000000..be504df2
--- /dev/null
+++ b/Input/Dennis Input/InputCallbackHandler.cpp
@@ -0,0 +1,193 @@
+#include"RawInput.h"
+
+
+//DefRawInputProc
+//GetRawInputDeviceList
+//GetRegisteredRawInputDevices
+
+
+
+LRESULT CALLBACK RawInput::WM_INPUT_TRANSLATE (int nCode, WPARAM wParam, LPARAM lparam)
+{
+ if (nCode < 0) return CallNextHookEx(RawInput::Self()->_msgHook, nCode, wParam, lparam);
+
+
+ MSG *m = (MSG*)lparam;
+
+ if(m->message == WM_INPUT)
+ {
+ RAWINPUT* raw = RawInput::Self()->_TranslateRawInput(m->lParam);
+
+ if(!raw) goto nextHook;
+ if(!RawInput::Self()->Self()->_enabled)
+ {
+ if(FAILED ( DefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER)) ) )
+ RawInput::Self()->_errorMsg = L"Failed to proccess default raw input";
+ goto _final;
+ }
+ // if(raw->header.dwType == RIM_TYPEMOUSE) RawInput::Self()->_idleMouseData.insert(raw->data.mouse);
+ //else if(raw->header.dwType == RIM_TYPEKEYBOARD) RawInput::Self()->_proccessRawKeyboardData(raw->data.keyboard);
+
+
+ _final:
+
+ //if(FAILED ( DefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER)) ) )
+ // RawInput::Self()->_errorMsg = L"Failed to proccess default raw input";
+
+ delete raw;
+ }
+ else if (m->message == WM_QUIT)
+ {
+ if(UnhookWindowsHookEx(RawInput::Self()->_msgHook) == FALSE)
+ {
+ RawInput::Self()->_errorMsg = L"Failed to unhook message hook!";
+ }
+ }
+
+
+ nextHook:
+ return CallNextHookEx(RawInput::Self()->_msgHook, nCode, wParam, lparam);
+}
+
+
+RAWINPUT* RawInput::_TranslateRawInput (LPARAM l)
+{
+ //Get The size of the raw data buffer
+ UINT bufferSize;
+ GetRawInputData((HRAWINPUT)l, RID_INPUT, NULL, &bufferSize, sizeof(RAWINPUTHEADER));
+ if (bufferSize < 1)
+ {
+ //Something went wrong
+ RawInput::Self()->_errorMsg = L"Failed to read raw buffer data in input class";
+ return 0;
+ }
+
+ //Create and read the raw input data
+ LPBYTE rawBufferIn = new BYTE[bufferSize];
+ UINT readBytes = GetRawInputData((HRAWINPUT)l, RID_INPUT, rawBufferIn, &bufferSize, sizeof(RAWINPUTHEADER));
+ if ( readBytes != bufferSize )
+ {
+ RawInput::Self()->_errorMsg = L"Could not read raw input data";
+ delete [] rawBufferIn;
+ return 0;
+ }
+
+ return (RAWINPUT*)rawBufferIn;
+}
+void RawInput::_proccessRawKeyboardData (RAWKEYBOARD& k)
+{
+ if(!this->_KeyboardEnabled) return;
+
+ //The key is released.
+ if(k.Flags == RI_KEY_BREAK || k.Flags == (RI_KEY_BREAK | RI_KEY_E0) || k.Flags == (RI_KEY_BREAK | RI_KEY_E1))
+ {
+ if(k.Message == WM_SYSKEYUP)
+ {
+ // if(k.VKey == VK_CONTROL) this->_procCollection.skd.ctrl = false;
+ //else if(k.VKey == VK_MENU) this->_procCollection.skd.alt = false;
+ //else if(k.VKey == VK_SHIFT) this->_procCollection.skd.shift = false;
+ }
+ else if(k.Message == WM_KEYUP)
+ {
+ //this->_procCollection.kd.key = (RIK)k.VKey;
+ //this->_procCollection.kd.released = true;
+ }
+ }
+ //The key is pressed.
+ else if (k.Flags == RI_KEY_MAKE || k.Flags == (RI_KEY_MAKE | RI_KEY_E0) || k.Flags == (RI_KEY_MAKE | RI_KEY_E1))
+ {
+ if(k.Message == WM_SYSKEYDOWN)
+ {
+ // if(k.VKey == VK_CONTROL) this->_procCollection.skd.ctrl = true;
+ //else if(k.VKey == VK_MENU) this->_procCollection.skd.alt = true;
+ //else if(k.VKey == VK_SHIFT) this->_procCollection.skd.shift = true;
+ }
+ else if(k.Message == WM_KEYDOWN)
+ {
+ //this->_procCollection.kd.key = (RIK)k.VKey;
+ //this->_procCollection.kd.released = false;
+ }
+ }
+}
+void RawInput::_proccessRawMouseData (RAWMOUSE& m)
+{
+ if(!this->_mouseEnabled) return;
+
+ if(m.lLastX != 0 || m.lLastY != 0)
+ {
+ //this->_procCollection.mmd.MousePos_X += m.lLastX;
+ //this->_procCollection.mmd.MousePos_Y += m.lLastY;
+ }
+ if( m.usButtonFlags > 0 )
+ {
+
+ switch (m.usButtonFlags)
+ {
+ //Mouse button pressed
+ case RI_MOUSE_LEFT_BUTTON_DOWN:
+ case RI_MOUSE_RIGHT_BUTTON_DOWN:
+ case RI_MOUSE_MIDDLE_BUTTON_DOWN:
+ {
+ if(m.usButtonFlags == RI_MOUSE_LEFT_BUTTON_DOWN)
+ {
+ //MOUSE_INPUT_btnData.key = RIK_LeftBtn;
+ //LBTNDOWN = true;
+ }
+ else if(m.usButtonFlags == RI_MOUSE_MIDDLE_BUTTON_DOWN)
+ {
+ //MOUSE_INPUT_btnData.key = RIK_MiddleBtn;
+ //MBTNDOWN = true;
+ }
+ else if(m.usButtonFlags == RI_MOUSE_RIGHT_BUTTON_DOWN)
+ {
+ //MOUSE_INPUT_btnData.key = RIK_RightBtn;
+ //RBTNDOWN = true;
+ }
+ }
+ break;
+
+ //Mouse button Released
+ case RI_MOUSE_LEFT_BUTTON_UP:
+ case RI_MOUSE_RIGHT_BUTTON_UP:
+ case RI_MOUSE_MIDDLE_BUTTON_UP:
+ {
+ if(m.usButtonFlags == RI_MOUSE_LEFT_BUTTON_UP)
+ {
+ //MOUSE_INPUT_btnData.key = RIK_LeftBtn;
+ //LBTNDOWN = false;
+ }
+ else if(m.usButtonFlags == RI_MOUSE_MIDDLE_BUTTON_UP)
+ {
+ //MOUSE_INPUT_btnData.key = RIK_MiddleBtn;
+ //MBTNDOWN = false;
+ }
+ else if(m.usButtonFlags == RI_MOUSE_RIGHT_BUTTON_UP)
+ {
+ //MOUSE_INPUT_btnData.key = RIK_RightBtn;
+ //RBTNDOWN = false;
+ }
+ }
+ break;
+
+ case RI_MOUSE_WHEEL:
+ {
+ int d = ((int)m.usButtonData);
+
+ if(d > 120) d = -1;
+ else d = 1;
+
+ //this->_procCollection.wd = d;
+ }
+ break;
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
diff --git a/Input/Dennis Input/InputDeviceControll.cpp b/Input/Dennis Input/InputDeviceControll.cpp
new file mode 100644
index 00000000..eb81da10
--- /dev/null
+++ b/Input/Dennis Input/InputDeviceControll.cpp
@@ -0,0 +1,57 @@
+#include "RawInput.h"
+
+void RawInput::Mouse_Show()
+{
+
+}
+void RawInput::Mouse_Hide()
+{
+
+}
+void RawInput::Mouse_Lock()
+{
+
+}
+void RawInput::Mouse_Unlock()
+{
+
+}
+void RawInput::Mouse_IsBtnPressed(IN RIK)
+{
+
+}
+int RawInput::Mouse_WheelDelta()
+{
+ return 0;
+}
+POINT RawInput::Mouse_Position()
+{
+ POINT p = {0, 0};
+ //POINT p = { this->_activeInputData.data.MOUSE_DATA.MousePos_X, this->_activeInputData.data.MOUSE_DATA.MousePos_Y };
+ return p;
+}
+
+void RawInput::Mouse_Enable()
+{
+ this->_mouseEnabled = true;
+}
+void RawInput::Mouse_Disable()
+{
+ this->_mouseEnabled = false;
+}
+bool RawInput::Keyboard_KeyUp(IN RIK key)
+{
+ return false;
+}
+bool RawInput::Keyboard_KeyDown(IN RIK key)
+{
+ return false;
+}
+void RawInput::Keyboard_Enable()
+{
+ this->_KeyboardEnabled = true;
+}
+void RawInput::Keyboard_Disable()
+{
+ this->_KeyboardEnabled = false;
+}
\ No newline at end of file
diff --git a/Input/Dennis Input/InputSubscribe.cpp b/Input/Dennis Input/InputSubscribe.cpp
new file mode 100644
index 00000000..6b59c090
--- /dev/null
+++ b/Input/Dennis Input/InputSubscribe.cpp
@@ -0,0 +1,142 @@
+#include "RawInput.h"
+
+
+template
+void SUBSCRIBE(SubscribeList* l, FNC _fnc, OBJECT_PARAM p)
+{
+ SubscribeList* t = new SubscribeList();
+
+ t->param = p;
+ t->fnc = _fnc;
+ t->next = l;
+ l = t;
+}
+template
+void UNSUBSCRIBE(SubscribeList* l, FNC fnc)
+{
+ SubscribeList* w = l;
+ SubscribeList* p = 0;
+ while (w)
+ {
+ if(w->fnc == fnc)
+ {
+ if(p)
+ p->next = w->next;
+
+ delete w;
+ w = 0;
+ }
+ else
+ {
+ p = w;
+ w = w->next;
+ }
+ }
+}
+
+
+void RawInput::Input_Subscribe (IN INPUT_CALLBACK fnc)
+{
+ //SUBSCRIBE(this->_procInput, fnc, &this->_procCollection.id);
+}
+void RawInput::Input_Unsubscribe (IN INPUT_CALLBACK fnc)
+{
+ //UNSUBSCRIBE(this->_procSystemKey, fnc);
+}
+
+
+
+
+
+
+
+
+
+
+/*
+void RawInput::Subscribe (RAW_KEY_PROC fnc)
+{
+ KeyboardProcList* t = new KeyboardProcList();
+ t->fnc = fnc;
+ t->next = 0;
+
+ KeyboardProcList* w = this->_keyProcList;
+ KeyboardProcList* prev = this->_keyProcList;
+
+ while (w)
+ {
+ prev = w;
+ w = w->next;
+ }
+
+ prev->next = t;
+}
+void RawInput::Subscribe (RAW_MOUSE_PROC fnc)
+{
+ MouseProcList* t = new MouseProcList();
+ t->fnc = fnc;
+ t->next = 0;
+
+ MouseProcList* w = this->_mouseProcList;
+ MouseProcList* prev = this->_mouseProcList;
+
+ while (w)
+ {
+ prev = w;
+ w = w->next;
+ }
+
+ prev->next = t;
+}
+void RawInput::Unsubscribe (RAW_KEY_PROC fnc)
+{
+ KeyboardProcList* w = this->_keyProcList;
+ KeyboardProcList* prev = 0;
+
+ while (w)
+ {
+ if(w->fnc == fnc)
+ {
+ if(prev)
+ prev->next = w->next;
+
+ delete w;
+ w = 0;
+ }
+ else
+ {
+ prev = w;
+ w = w->next;
+ }
+ }
+}
+void RawInput::Unsubscribe (RAW_MOUSE_PROC fnc)
+{
+ MouseProcList* w = this->_mouseProcList;
+ MouseProcList* prev = 0;
+
+ while (w)
+ {
+ if(w->fnc == fnc)
+ {
+ if(prev)
+ prev->next = w->next;
+
+ delete w;
+ w = 0;
+ }
+ else
+ {
+ prev = w;
+ w = w->next;
+ }
+ }
+}
+*/
+
+
+
+
+
+
+
diff --git a/Input/Dennis Input/InputSystem.cpp b/Input/Dennis Input/InputSystem.cpp
new file mode 100644
index 00000000..77f5389c
--- /dev/null
+++ b/Input/Dennis Input/InputSystem.cpp
@@ -0,0 +1,182 @@
+#include "RawInput.h"
+#include
+#include
+#include
+
+#include
+#include
+
+
+static RawInput* gInstance = 0;
+
+template void DESTROY_LIST(SubscribeList* l)
+{
+ SubscribeList* w = l;
+ SubscribeList* p = 0;
+
+ while (w)
+ {
+ p = w;
+ w = w->next;
+ delete p;
+ }
+}
+template void PROCESS_SUBSCRIBERS(SubscribeList* l)
+{
+ while (l)
+ {
+ l->fnc(l->param);
+ l = l->next;
+ }
+}
+
+
+
+
+
+
+
+
+RawInputWrapper* RawInputWrapper::Self ()
+{
+ return (RawInputWrapper*)RawInput::Self();
+}
+void RawInputWrapper::Destroy ()
+{
+ RawInput::Destroy();
+}
+RawInput* RawInput::Self ()
+{
+ if(!gInstance)
+ gInstance = new RawInput();
+
+ return gInstance;
+}
+void RawInput::Destroy ()
+{
+/************************ Delete subscribers ****************************/
+ DESTROY_LIST(RawInput::Self()->_procInput);
+
+/************************ Delete Other stuff ****************************/
+ ShowCursor(true);
+ RECT r;
+ GetWindowRect(GetDesktopWindow(), &r);
+ ClipCursor(&r);
+
+/************************ Delete instance ****************************/
+ delete gInstance;
+ gInstance = NULL;
+}
+
+
+
+
+
+RawInput::RawInput ()
+ : _procInput(0)
+ , _enabled(1)
+ , _mouseEnabled(1)
+ , _KeyboardEnabled(1)
+ , _exclusive(0)
+ , _errorMsg(0)
+ , _msgHook(SetWindowsHookEx(WH_GETMESSAGE, WM_INPUT_TRANSLATE, (HINSTANCE)0, GetCurrentThreadId()))
+{
+ if(!_msgHook) this->_errorMsg = L"Failed to initiate window message hook";
+}
+RawInput::~RawInput ()
+{}
+
+
+const wchar_t* RawInput::Input_GetError() const
+{
+ return this->_errorMsg;
+}
+
+bool RawInput::Input_AddDevice(IN const HWND& targetApplication)
+{
+ assert(targetApplication != 0);
+ static const UINT c = 2;
+ RAWINPUTDEVICE devices[c] =
+ {
+ { 0x01, RawInput_Usage_keyboard, RIDEV_NOLEGACY, targetApplication },
+ { 0x01, RawInput_Usage_mouse, RIDEV_NOLEGACY | RIDEV_CAPTUREMOUSE, targetApplication }
+ };
+
+ if(! _addDevice( devices , c ) ) return false;
+
+ ShowCursor(FALSE);
+ //RECT r;
+ //GetWindow
+ //GetWindowRect(
+
+ return true;
+}
+bool RawInput::Input_AddDevice(IN const RAWINPUTDEVICE* d, const int& count)
+{
+ for (int i = 0; i < count; i++)
+ if(!d[i].hwndTarget)
+ {
+ this->_errorMsg = L"Must specify target application";
+ return false;
+ }
+ if(! _addDevice( d, count ) ) return false;
+
+ return true;
+}
+
+//RAWINPUTDEVICE d = { 0x01, type, RIDEV_REMOVE, NULL };
+//this->_errorMsg = L"Failed to unregister device";
+
+
+void RawInput::Input_Disable()
+{
+ this->_enabled = false;
+}
+void RawInput::Input_Enable()
+{
+ this->_enabled = true;
+}
+
+void RawInput::Input_Read()
+{
+ //for (int i = 0; i < this->_idleKeyData.size(); i++)
+ // this->_proccessRawKeyboardData(this->_idleKeyData.pop());
+ //for (int i = 0; i < this->_idleMouseData.size(); i++)
+ // this->_proccessRawMouseData(this->_idleMouseData.pop());
+ //
+ //this->_idleKeyData.clear();
+ //this->_idleMouseData.clear();
+}
+
+
+
+
+
+
+bool RawInput::_addDevice (const RAWINPUTDEVICE* k, const int& count)
+{
+ if(RegisterRawInputDevices(k, count, sizeof(RAWINPUTDEVICE)) == FALSE)
+ {
+ DWORD h = GetLastError();
+ this->_errorMsg = L"Failed to register device";
+ return false;
+ }
+
+ for (int q = 0; q < count; q++)
+ {
+ RawInputDeviceInstance i;
+ memcpy(&i.description, &k[q], sizeof(RAWINPUTDEVICE));
+ this->_deviceList.push(i);
+ }
+
+ return true;
+}
+
+
+
+
+
+
+
+
+
diff --git a/Input/Dennis Input/Main.cpp b/Input/Dennis Input/Main.cpp
new file mode 100644
index 00000000..bb355a6d
--- /dev/null
+++ b/Input/Dennis Input/Main.cpp
@@ -0,0 +1,102 @@
+#include "RawInputWrapper.h"
+// include the basic windows header file
+#include
+#include
+#include
+#include
+
+
+HWND hWnd;
+// this is the main message handler for the program
+LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ // sort through and find what code to run for the message given
+ switch(message)
+ {
+ // this message is read when the window is closed
+ case WM_DESTROY:
+ {
+ // close the application entirely
+ PostQuitMessage(0);
+ return 0;
+ } break;
+ case WM_KEYUP:
+ MessageBox(0, L"WM_KEYUP", L"", 0);
+ break;
+ case WM_KEYDOWN:
+ MessageBox(0, L"WM_KEYDOWN", L"", 0);
+ break;
+ //case WM_INPUT:
+ // MessageBox(0, L"WM_INPUT_MAIN", L"", 0);
+ //break;
+ }
+
+ // Handle any messages the switch statement didn't
+ return DefWindowProc (hWnd, message, wParam, lParam);
+}
+void initWindow(HINSTANCE h, int i)
+{
+ // this struct holds information for the window class
+ WNDCLASSEX wc;
+
+ // clear out the window class for use
+ ZeroMemory(&wc, sizeof(WNDCLASSEX));
+
+ // fill in the struct with the needed information
+ wc.cbSize = sizeof(WNDCLASSEX);
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = WindowProc;
+ wc.hInstance = h;
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
+ wc.lpszClassName = L"WindowClass1";
+
+ // register the window class
+ RegisterClassEx(&wc);
+
+ // create the window and use the result as the handle
+ hWnd = CreateWindowEx(NULL,
+ L"WindowClass1", // name of the window class
+ L"Our First Windowed Program", // title of the window
+ WS_OVERLAPPEDWINDOW, // window style
+ 300, // x-position of the window
+ 300, // y-position of the window
+ 500, // width of the window
+ 400, // height of the window
+ NULL, // we have no parent window, NULL
+ NULL, // we aren't using menus, NULL
+ h, // application handle
+ NULL); // used with multiple windows, NULL
+
+ // display the window on the screen
+ ShowWindow(hWnd, i);
+}
+void initRaw()
+{
+ RawInputWrapper::Self()->Input_AddDevice(hWnd);
+}
+// the entry point for any Windows program
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
+{
+ initWindow(hInstance, nCmdShow);
+ initRaw();
+
+
+ // this struct holds Windows event messages
+ MSG msg;
+
+ // wait for the next message in the queue, store the result in 'msg'
+ while(GetMessage(&msg, NULL, 0, 0))
+ {
+ // translate keystroke messages into the right format
+ TranslateMessage(&msg);
+ // send the message to the WindowProc function
+ DispatchMessage(&msg);
+
+ RawInputWrapper::Self()->Input_Read();
+ }
+
+ RawInputWrapper::Destroy();
+
+ return msg.wParam;
+}
\ No newline at end of file
diff --git a/Input/Dennis Input/RawInput.h b/Input/Dennis Input/RawInput.h
new file mode 100644
index 00000000..7f10a878
--- /dev/null
+++ b/Input/Dennis Input/RawInput.h
@@ -0,0 +1,104 @@
+#ifndef INCLUDE_GUARD_RAW_INPUT_H
+#define INCLUDE_GUARD_RAW_INPUT_H
+
+#include "RawInputWrapper.h"
+#include "misc.h"
+#include
+
+/**
+* TODO:
+* 1. Origo in middle of the screen (-1 to 1)
+*/
+
+
+//dx = +2*(x/w) -1
+//dx = -2*(y/h) +1
+
+template
+struct SubscribeList
+{
+ FNC fnc;
+ PARAM param;
+ SubscribeList* next;
+};
+struct RawInputDeviceInstance
+{
+ RAWINPUTDEVICE description;
+};
+
+
+enum RawInput_Usage
+{
+ RawInput_Usage_pointer = 1,
+ RawInput_Usage_mouse = 2,
+ RawInput_Usage_joystick = 4,
+ RawInput_Usage_gamepad = 5,
+ RawInput_Usage_keyboard = 6,
+ RawInput_Usage_keypad = 7,
+ RawInput_Usage_multiAxisController = 8,
+ RawInput_Usage_TabletPCcontrols = 9,
+};
+
+class RawInput :public RawInputWrapper
+{
+ private:
+ SubscribeList* _procInput;
+
+ bool _enabled;
+ bool _mouseEnabled;
+ bool _KeyboardEnabled;
+ bool _exclusive;
+ const wchar_t* _errorMsg;
+ List _deviceList;
+
+ List _mouseInput;
+ List _keyboardInput;
+
+ HHOOK _msgHook;
+
+ private:
+ RawInput ();
+ ~RawInput ();
+
+ bool _addDevice (const RAWINPUTDEVICE* k, const int& count);
+ RAWINPUT*_TranslateRawInput (LPARAM l);
+ void _proccessRawMouseData (RAWMOUSE&);
+ void _proccessRawKeyboardData (RAWKEYBOARD&);
+
+ static LRESULT CALLBACK WM_INPUT_TRANSLATE (int nCode, WPARAM wParam, LPARAM lParam);
+
+ public:
+
+ static RawInput* Self ();
+ static void Destroy ();
+
+ const wchar_t* Input_GetError () const;
+
+ bool Input_AddDevice (IN const HWND& targetApplication);
+ bool Input_AddDevice (IN const RAWINPUTDEVICE*, IN const int&);
+
+ void Input_Subscribe (IN INPUT_CALLBACK fnc);
+ void Input_Unsubscribe (IN INPUT_CALLBACK fnc);
+
+ void Input_Disable ();
+ void Input_Enable ();
+
+ void Input_Read ();
+
+ void Mouse_Show ();
+ void Mouse_Hide ();
+ void Mouse_Lock ();
+ void Mouse_Unlock ();
+ void Mouse_IsBtnPressed (IN RIK);
+ int Mouse_WheelDelta ();
+ POINT Mouse_Position ();
+ void Mouse_Enable ();
+ void Mouse_Disable ();
+
+ bool Keyboard_KeyUp (IN RIK key);
+ bool Keyboard_KeyDown (IN RIK key);
+ void Keyboard_Enable ();
+ void Keyboard_Disable ();
+};
+#endif
+
diff --git a/Input/Dennis Input/RawInputWrapper.h b/Input/Dennis Input/RawInputWrapper.h
new file mode 100644
index 00000000..67389c89
--- /dev/null
+++ b/Input/Dennis Input/RawInputWrapper.h
@@ -0,0 +1,215 @@
+#ifndef RAW_INPUT_H
+#define RAW_INPUT_H
+
+#include
+
+
+
+/*********************************************************************/
+/***************************** Keycodes ******************************/
+/*********************************************************************/
+//! Contains keycodes
+enum RIK
+{
+ RIK_Backspace = 0x08,
+ RIK_Tab = 0x09,
+ RIK_Enter = 0x0D,
+ RIK_Shift = 0x10,
+ RIK_Ctrl = 0x11,
+ RIK_Alt = 0x12,
+ RIK_Pause = 0x13,
+ RIK_CapsLock = 0x14,
+ RIK_Escape = 0x1B,
+ RIK_Space = 0x20,
+ RIK_PgUp = 0x21,
+ RIK_PgDown = 0x22,
+ RIK_End = 0x23,
+ RIK_Home = 0x24,
+ RIK_Left = 0x25,
+ RIK_Up = 0x26,
+ RIK_Right = 0x27,
+ RIK_Down = 0x28,
+ RIK_PrintScreen = 0x2C,
+ RIK_Insert = 0x2D,
+ RIK_Delete = 0x2E,
+ RIK_0 = 0x30,
+ RIK_1 = 0x31,
+ RIK_2 = 0x32,
+ RIK_3 = 0x33,
+ RIK_4 = 0x34,
+ RIK_5 = 0x35,
+ RIK_6 = 0x36,
+ RIK_7 = 0x37,
+ RIK_8 = 0x38,
+ RIK_9 = 0x39,
+ RIK_A = 0x41,
+ RIK_B = 0x42,
+ RIK_C = 0x43,
+ RIK_D = 0x44,
+ RIK_E = 0x45,
+ RIK_F = 0x46,
+ RIK_G = 0x47,
+ RIK_H = 0x48,
+ RIK_I = 0x49,
+ RIK_J = 0x4A,
+ RIK_K = 0x4B,
+ RIK_L = 0x4C,
+ RIK_M = 0x4D,
+ RIK_N = 0x4E,
+ RIK_O = 0x4F,
+ RIK_P = 0x50,
+ RIK_Q = 0x51,
+ RIK_R = 0x52,
+ RIK_S = 0x53,
+ RIK_T = 0x54,
+ RIK_U = 0x55,
+ RIK_V = 0x56,
+ RIK_W = 0x57,
+ RIK_X = 0x58,
+ RIK_Y = 0x59,
+ RIK_Z = 0x5A,
+ RIK_LeftWindows = 0x5B,
+ RIK_RightWindows = 0x5C,
+ RIK_Numpad0 = 0x60,
+ RIK_Numpad1 = 0x61,
+ RIK_Numpad2 = 0x62,
+ RIK_Numpad3 = 0x63,
+ RIK_Numpad4 = 0x64,
+ RIK_Numpad5 = 0x65,
+ RIK_Numpad6 = 0x66,
+ RIK_Numpad7 = 0x67,
+ RIK_Numpad8 = 0x68,
+ RIK_Numpad9 = 0x69,
+ RIK_Multiply = 0x6A,
+ RIK_Plus = 0x6B,
+ RIK_Subtract = 0x6D,
+ RIK_Decimal = 0x6E,
+ RIK_Divide = 0x6F,
+ RIK_F1 = 0x70,
+ RIK_F2 = 0x71,
+ RIK_F3 = 0x72,
+ RIK_F4 = 0x73,
+ RIK_F5 = 0x74,
+ RIK_F6 = 0x75,
+ RIK_F7 = 0x76,
+ RIK_F8 = 0x77,
+ RIK_F9 = 0x78,
+ RIK_F10 = 0x79,
+ RIK_F11 = 0x7A,
+ RIK_F12 = 0x7B,
+ RIK_F13 = 0x7C,
+ RIK_F14 = 0x7D,
+ RIK_F15 = 0x7E,
+ RIK_F16 = 0x7F,
+ RIK_F17 = 0x80,
+ RIK_F18 = 0x81,
+ RIK_F19 = 0x82,
+ RIK_F20 = 0x83,
+ RIK_F21 = 0x84,
+ RIK_F22 = 0x85,
+ RIK_F23 = 0x86,
+ RIK_F24 = 0x87,
+ RIK_Numlock = 0x90,
+ RIK_ScrlLock = 0x91,
+ RIK_LeftShift = 0xA0,
+ RIK_RightShift = 0xA1,
+ RIK_LeftCtrl = 0xA2,
+ RIK_RightCtrl = 0xA3,
+
+ COUNT
+};
+enum RIM
+{
+ RIM_LeftBtn = 0x02,
+ RIM_MiddleBtn = 0x10,
+ RIM_RightBtn = 0x04,
+ RIM_Scroll = 0x0400,
+};
+/*********************************************************************/
+
+
+/**************************************************************************/
+/***************************** Callback data ******************************/
+/**************************************************************************/
+enum InputType
+{
+ InputType_Keyboard,
+ InputType_Mouse,
+ InputType_HID,
+};
+struct RawMouseData
+{
+ bool shift;
+ bool alt;
+ bool ctrl;
+
+ RIM key;
+ bool pressed;
+
+ int MousePos_X;
+ int MousePos_Y;
+
+ int delta;
+};
+struct RawKeyData
+{
+ bool shift;
+ bool alt;
+ bool ctrl;
+
+ RIK key;
+ bool released;
+};
+struct RawInputData
+{
+ InputType type;
+ union
+ {
+ RawMouseData MOUSE_DATA;
+ RawKeyData KEYBOARD_DATA;
+ RAWHID HID_DATA;
+ } data;
+};
+typedef void(*INPUT_CALLBACK)(const RawInputData*);
+/*********************************************************************/
+
+class RawInputWrapper
+{
+ public:
+ static RawInputWrapper* Self ();
+ static void Destroy ();
+
+ virtual const wchar_t* Input_GetError () const PURE;
+
+ virtual bool Input_AddDevice (IN const HWND& targetApplication) PURE;
+ virtual bool Input_AddDevice (IN const RAWINPUTDEVICE* d, IN const int& count) PURE;
+
+ virtual void Input_Subscribe (IN INPUT_CALLBACK fnc) PURE;
+ virtual void Input_Unsubscribe (IN INPUT_CALLBACK fnc) PURE;
+
+ virtual void Input_Disable () PURE;
+ virtual void Input_Enable () PURE;
+
+ virtual void Input_Read () PURE;
+
+ virtual void Mouse_Show () PURE;
+ virtual void Mouse_Hide () PURE;
+ virtual void Mouse_Lock () PURE;
+ virtual void Mouse_Unlock () PURE;
+ virtual void Mouse_IsBtnPressed (IN RIK key) PURE;
+ virtual int Mouse_WheelDelta () PURE;
+ virtual POINT Mouse_Position () PURE;
+ virtual void Mouse_Enable () PURE;
+ virtual void Mouse_Disable () PURE;
+
+ virtual bool Keyboard_KeyUp (IN RIK key) PURE;
+ virtual bool Keyboard_KeyDown (IN RIK key) PURE;
+ virtual void Keyboard_Enable () PURE;
+ virtual void Keyboard_Disable () PURE;
+
+
+};
+
+
+#endif
+
diff --git a/Input/Dennis Input/misc.h b/Input/Dennis Input/misc.h
new file mode 100644
index 00000000..f9c76deb
--- /dev/null
+++ b/Input/Dennis Input/misc.h
@@ -0,0 +1,120 @@
+#ifndef MISC_H
+#define MISC_H
+
+
+#include
+
+
+template
+class List
+{
+ private:
+ class Node
+ {
+ public:
+ T value;
+ Node *next;
+ Node(T value){ this->value = value; this->next = NULL; }
+ ~Node() {}
+ };
+
+ Node *first;
+ int nrOfNodes;
+
+ public:
+ List::List()
+ {
+ this->first = NULL;
+ this->nrOfNodes = 0;
+ }
+
+ List::~List()
+ {
+ Node *walker = this->first;
+
+ for(int i = 0; inrOfNodes; i++)
+ {
+ walker = walker->next;
+ delete this->first;
+ this->first = walker;
+ }
+ }
+
+ List& List::operator=(const List& origObj)
+ {
+ if(this->nrOfNodes > 0)
+ {
+ Node *walker = this->first;
+
+ for(int i = 0; inrOfNodes; i++)
+ {
+ walker = walker->next;
+ delete this->first;
+ this->first = walker;
+ }
+ }
+
+ this->nrOfNodes = 0;
+ if(origObj.nrOfNodes > 0)
+ {
+ Node *walker = origObj.first;
+
+ for(int i = 0; ivalue);
+ walker = walker->next;
+ }
+ }
+
+ return *this;
+ }
+
+ void List::push(T value)
+ {
+ Node *e = new Node(value);
+ e->next = this->first;
+ this->first = e;
+ e = NULL;
+ this->nrOfNodes++;
+ }
+
+ T List::pop()
+ {
+ T removed;
+ memset(&removed, 0, sizeof(T));
+
+ if(this->nrOfNodes > 0)
+ {
+ Node *temp = first;
+ this->first = first->next;
+ memcpy(&removed, &temp->value, sizeof(T));
+ delete temp;
+ this->nrOfNodes--;
+ }
+
+ return removed;
+ }
+
+ int List::size() const
+ {
+ return this->nrOfNodes;
+ }
+
+ void clear()
+ {
+ Node *w = this->first;
+ Node *p = 0;
+ while (w)
+ {
+ p = w;
+ w = w->next;
+ delete p;
+ }
+
+ this->first = 0;
+ }
+
+};
+
+
+#endif
diff --git a/Input/InputController.cpp b/Input/InputController.cpp
new file mode 100644
index 00000000..d534a073
--- /dev/null
+++ b/Input/InputController.cpp
@@ -0,0 +1,284 @@
+#include "InputController.h"
+using namespace Oyster::Input;
+
+namespace
+{
+ bool keys[256] = {0};
+ bool prevs[256]= {0};
+ bool mouse[5] = {0};
+ bool mPrev[5] = {0};
+ int XPos,YPos,PrevX,PrevY,DeltaX,DeltaY;
+}
+
+void Controller::KeyPressed(const WPARAM &Key)
+{
+ prevs[Key]=false;
+ keys[Key]=true;
+}
+
+void Controller::KeyReleased(const WPARAM &Key)
+{
+ prevs[Key]=true;
+ keys[Key] = false;
+}
+
+bool Controller::isKeyDown(const WPARAM &Key)
+{
+ return keys[Key];
+}
+
+bool Controller::isKeyPressed(const WPARAM &Key)
+{
+ if(keys[Key] && !prevs[Key])
+ {
+ prevs[Key] = keys[Key];
+ return true;
+ }
+ return false;
+}
+
+bool Controller::isKeyReleased(const WPARAM &Key)
+{
+ if(!keys[Key] && prevs[Key])
+ {
+ prevs[Key] = keys[Key];
+ return true;
+ }
+ return false;
+}
+
+void Controller::MouseBtnPressed(const WPARAM &btn)
+{
+ switch(btn)
+ {
+ case MK_LBUTTON:
+ mouse[0] = true;
+ mPrev[0] = false;
+ break;
+ case MK_RBUTTON:
+ mouse[1] = true;
+ mPrev[1] = false;
+ break;
+ case MK_MBUTTON:
+ mouse[2] = true;
+ mPrev[2] = false;
+ break;
+ case MK_XBUTTON1:
+ mouse[3] = true;
+ mPrev[3] = false;
+ break;
+ case MK_XBUTTON2:
+ mouse[4] = true;
+ mPrev[4] = false;
+ break;
+ }
+}
+
+void Controller::MouseBtnReleased(const WPARAM &btn)
+{
+ switch(btn)
+ {
+ case MK_LBUTTON:
+ mouse[0] = false;
+ mPrev[0] = true;
+ break;
+ case MK_RBUTTON:
+ mouse[1] = false;
+ mPrev[1] = true;
+ break;
+ case MK_MBUTTON:
+ mouse[2] = false;
+ mPrev[2] = true;
+ break;
+ case MK_XBUTTON1:
+ mouse[3] = false;
+ mPrev[3] = true;
+ break;
+ case MK_XBUTTON2:
+ mouse[4] = false;
+ mPrev[4] = true;
+ break;
+ }
+}
+
+
+bool Controller::isMouseBtnDown(const WPARAM &Btn)
+{
+ switch(Btn)
+ {
+ case MK_LBUTTON:
+ return mouse[0];
+ case MK_RBUTTON:
+ return mouse[1];
+ case MK_MBUTTON:
+ return mouse[2];
+ case MK_XBUTTON1:
+ return mouse[3];
+ case MK_XBUTTON2:
+ return mouse[4];
+ }
+
+ return false;
+}
+
+bool Controller::isMouseBtnPressed(const WPARAM &Btn)
+{
+ switch(Btn)
+ {
+ case MK_LBUTTON:
+ if(mouse[0] && !mPrev[0])
+ {
+ mPrev[0] = mouse[0];
+ return true;
+ }
+ return false;
+ case MK_RBUTTON:
+ if(mouse[1] && !mPrev[1])
+ {
+ mPrev[1] = mouse[1];
+ return true;
+ }
+ return false;
+ case MK_MBUTTON:
+ if(mouse[2] && !mPrev[2])
+ {
+ mPrev[2] = mouse[2];
+ return true;
+ }
+ return false;
+ case MK_XBUTTON1:
+ if(mouse[3] && !mPrev[3])
+ {
+ mPrev[3] = mouse[3];
+ return true;
+ }
+ return false;
+ case MK_XBUTTON2:
+ if(mouse[4] && !mPrev[4])
+ {
+ mPrev[4] = mouse[4];
+ return true;
+ }
+ return false;
+ }
+
+ return false;
+}
+
+bool Controller::isMouseBtnReleased(const WPARAM &Btn)
+{
+ switch(Btn)
+ {
+ case MK_LBUTTON:
+ if(!mouse[0] && mPrev[0])
+ {
+ mPrev[0] = mouse[0];
+ return true;
+ }
+ return false;
+ case MK_RBUTTON:
+ if(!mouse[1] && mPrev[1])
+ {
+ mPrev[1] = mouse[1];
+ return true;
+ }
+ return false;
+ case MK_MBUTTON:
+ if(!mouse[2] && mPrev[2])
+ {
+ mPrev[2] = mouse[2];
+ return true;
+ }
+ return false;
+ case MK_XBUTTON1:
+ if(!mouse[3] && mPrev[3])
+ {
+ mPrev[3] = mouse[3];
+ return true;
+ }
+ return false;
+ case MK_XBUTTON2:
+ if(!mouse[4] && mPrev[4])
+ {
+ mPrev[4] = mouse[4];
+ return true;
+ }
+ return false;
+ }
+
+ return false;
+}
+
+void Controller::MouseMove(int x,int y)
+{
+ PrevY = YPos;
+ PrevX = XPos;
+ XPos = x;
+ YPos = y;
+ DeltaY = YPos - PrevY;
+ DeltaX = XPos - PrevX;
+}
+
+int Controller::GetY()
+{
+ return YPos;
+}
+
+int Controller::GetX()
+{
+ return XPos;
+}
+
+float Controller::GetAnalogX()
+{
+ float f = (float)XPos;
+ f /=( Window::Size.left/2);
+ return f;
+}
+
+float Controller::GetAnalogY()
+{
+ float f = (float)YPos;
+ f /=( Window::Size.top/2);
+ return f;
+}
+
+int Controller::GetDeltaY()
+{
+ return DeltaY;
+}
+
+int Controller::GetDeltaX()
+{
+ return DeltaX;
+}
+
+void Controller::ResetDeltaX()
+{
+ DeltaX = 0;
+}
+
+void Controller::ResetDeltaY()
+{
+ DeltaY = 0;
+}
+
+void Controller::RestrictMouse(bool restrict)
+{
+ Oyster::Window::CaptureMouse(restrict);
+}
+
+//sets x=0,y=0 to be the center oc the client area
+void Controller::OrigoCenter()
+{
+ int x = Window::Size.left/2;
+ int y = Window::Size.top/2;
+
+ Window::SetMouseOffset(-x,-y);
+}
+
+//default
+void Controller::OrigoTopLeft()
+{
+ Oyster::Window::SetMouseOffset(0,0);
+}
\ No newline at end of file
diff --git a/Input/InputController.h b/Input/InputController.h
new file mode 100644
index 00000000..5b4292c6
--- /dev/null
+++ b/Input/InputController.h
@@ -0,0 +1,63 @@
+#pragma once
+
+#ifndef InputController_H
+#define InputController_H
+
+#include "../Window/Window.h"
+//READ http://msdn.microsoft.com/en-us/library/windows/desktop/ms648380(v=vs.85).aspx#_win32_Confining_a_Cursor
+
+namespace Oyster
+{
+ class Window;
+ namespace Input
+ {
+ class Controller
+ {
+ friend class ::Oyster::Window;
+ private:
+ //Keybord events from Oyster::Window
+ static void KeyPressed(const WPARAM &Key);
+ //Keybord events from Oyster::Window
+ static void KeyReleased(const WPARAM &Key);
+
+
+ //Mouse events from Oyster::Window
+ static void MouseMove(int x,int y);
+ //Mouse events from Oyster::Window
+ static void MouseBtnPressed(const WPARAM &Btn);
+ static void MouseBtnReleased(const WPARAM &Btn);
+ public:
+ //Polling Functions
+ static bool isKeyDown(const WPARAM &Key);
+ static bool isKeyPressed(const WPARAM &Key);
+ static bool isKeyReleased(const WPARAM &Key);
+
+ static bool isMouseBtnDown(const WPARAM &Btn);
+ static bool isMouseBtnPressed(const WPARAM &Btn);
+ static bool isMouseBtnReleased(const WPARAM &Btn);
+
+ static int GetX();
+ static int GetY();
+
+ static float GetAnalogX();
+ static float GetAnalogY();
+
+ static int GetDeltaX();
+ static int GetDeltaY();
+
+ //Controll Functions
+ static void ResetDeltaX();
+ static void ResetDeltaY();
+
+ //off by default
+ static void RestrictMouse(bool b = true);
+
+ //sets x=0,y=0 to be the center oc the client area
+ static void OrigoCenter();
+
+ //default
+ static void OrigoTopLeft();
+ };
+ }
+}
+#endif
\ No newline at end of file
diff --git a/Misc/Utilities.cpp b/Misc/Utilities.cpp
new file mode 100644
index 00000000..c3046aeb
--- /dev/null
+++ b/Misc/Utilities.cpp
@@ -0,0 +1,216 @@
+/////////////////////////////////////////////////////////////////////
+// Utility Collection of Miscellanious Handy Functions
+// © Dan Andersson 2013
+/////////////////////////////////////////////////////////////////////
+
+#include "Utilities.h"
+#include
+#include
+
+using ::std::vector;
+using ::std::string;
+
+namespace Utility
+{
+// PRIVATE STATIC ////////////////////////////////////////////////////
+ namespace PrivateStatic
+ {
+ const ::std::locale systemDefaultLocale = ::std::locale();
+ }
+
+// STRING ////////////////////////////////////////////////////////////
+ namespace String
+ {
+ vector & split( vector &output, const string &str, char delim, string::size_type offset )
+ {
+ if( str.length() > 0 )
+ {
+ while( offset < str.length() ) // trim
+ {
+ if( str[offset] == delim )
+ ++offset;
+ else break;
+ }
+
+ string::size_type delimPos = str.find_first_of( delim, offset );
+ if( delimPos == string::npos )
+ {
+ if( str.length() > offset )
+ output.push_back( str.substr( offset, str.length() - offset ) );
+ }
+ else
+ {
+ if( delimPos > offset )
+ output.push_back( str.substr( offset, delimPos - offset ) );
+ String::split( output, str, delim, delimPos + 1 );
+ }
+ }
+ return output;
+ }
+
+ vector & split( vector &output, const string &str, const string &delim, string::size_type offset )
+ {
+ if( str.length() > 0 )
+ {
+ string::size_type delimPos = str.find_first_of( delim, offset );
+ if( delimPos == string::npos )
+ {
+ if( str.length() > offset )
+ output.push_back( str.substr( offset, str.length() - offset ) );
+ }
+ else
+ {
+ if( delimPos > offset )
+ output.push_back( str.substr( offset, delimPos - offset ) );
+ String::split( output, str, delim, delimPos + delim.length() );
+ }
+ }
+ return output;
+ }
+
+ vector & split( vector &output, const string &str, const vector &delim, string::size_type offset )
+ {
+ if( str.length() > 0 )
+ {
+ string::size_type firstDelimPos = str.length(), delimPos;
+
+ vector::size_type numDelims = delim.size(), delimRef = 0;
+ for( vector::size_type i = 0; i < numDelims ; ++i )
+ {
+ delimPos = str.find_first_of( delim[i], offset );
+ if( delimPos != string::npos ) if( delimPos < firstDelimPos )
+ {
+ delimRef = i;
+ firstDelimPos = delimPos;
+ }
+ }
+
+ if( firstDelimPos == str.length() )
+ {
+ if( str.length() > offset )
+ output.push_back( str.substr( offset, str.length() - offset ) );
+ }
+ else
+ {
+ if( firstDelimPos > offset )
+ output.push_back( str.substr( offset, firstDelimPos - offset ) );
+ String::split( output, str, delim, firstDelimPos + delim[delimRef].length() );
+ }
+ }
+ return output;
+ }
+
+ string trim( const string &str )
+ {
+ string::size_type first = 0,
+ last = str.length();
+
+ if( last == 0 ) return str;
+
+ while( first < last )
+ {
+ if( str[first] == ' ' || str[first] == '\t' || str[first] == '\r' || str[first] == '\n' )
+ ++first;
+ else break;
+ }
+
+ --last;
+ while( last > first )
+ {
+ if( str[last] == ' ' || str[last] == '\t' || str[last] == '\r' || str[last] == '\n' )
+ --last;
+ else break;
+ }
+
+ if( first == last ) if( str[first] == ' ' || str[first] == '\t' || str[first] == '\r' || str[first] == '\n' )
+ return "";
+
+ return str.substr( first, (++last) - first );
+ }
+
+ string & toLowerCase( string &output, const string &str )
+ {
+ int length = (int)str.length();
+ output.resize( length );
+ for( int i = 0; i < length; ++i )
+ output[i] = ::std::tolower( str[i], ::std::locale() );
+ return output;
+ }
+
+ string & toLowerCase( string &str )
+ {
+ int length = (int)str.length();
+ for( int i = 0; i < length; ++i )
+ str[i] = ::std::tolower( str[i], ::std::locale() );
+ return str;
+ }
+
+ string & toUpperCase( string &output, const string &str )
+ {
+ int length = (int)str.length();
+ output.resize( length );
+ for( int i = 0; i < length; ++i )
+ output[i] = ::std::toupper( str[i], ::std::locale() );
+ return output;
+ }
+
+ string & toUpperCase( string &str )
+ {
+ int length = (int)str.length();
+ for( int i = 0; i < length; ++i )
+ str[i] = ::std::toupper( str[i], ::std::locale() );
+ return str;
+ }
+
+ string & extractDirPath( string &output, const string &file, char dirDelimeter )
+ {
+ string d = " ";
+ d[0] = dirDelimeter;
+ return String::extractDirPath( output, file, d );
+ }
+
+ string & extractDirPath( string &output, const string &file, const string &dirDelimeter )
+ {
+ string::size_type end = file.find_last_of( dirDelimeter );
+ if( end == string::npos )
+ output = "";
+ else
+ {
+ ++end;
+ output.resize( end );
+ for( string::size_type i = 0; i < end; ++i )
+ output[i] = file[i];
+ }
+
+ return output;
+ }
+
+ string & replaceCharacters( string &str, char characterToReplace, char newCharacter, const string::size_type &offset, const string::size_type &end )
+ {
+ string::size_type i = offset;
+ while( true )
+ {
+ i = str.find_first_of( characterToReplace, i );
+ if( i >= end ) break;
+
+ str[i++] = newCharacter;
+ }
+ return str;
+ }
+ }
+
+ // STREAM ////////////////////////////////////////////////////////////
+ namespace Stream
+ {
+ float* readFloats( float *output, ::std::istream &input, unsigned int numFloats )
+ {
+ string str;
+ for( unsigned int i = 0; i < numFloats; ++i )
+ {
+ input >> str;
+ output[i] = (float)::std::atof( str.c_str() );
+ }
+ return output;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Misc/Utilities.h b/Misc/Utilities.h
new file mode 100644
index 00000000..aa9128c3
--- /dev/null
+++ b/Misc/Utilities.h
@@ -0,0 +1,80 @@
+/////////////////////////////////////////////////////////////////////
+// Utility Collection of Miscellanious Handy Functions
+// © Dan Andersson 2013
+/////////////////////////////////////////////////////////////////////
+
+#pragma once
+#ifndef UTILITIES_H
+#define UTILITIES_H
+
+#include
+#include
+#include
+#include
+
+namespace Utility
+{
+ namespace String
+ {
+ // note to self: add a whitespaceSplit method?
+ ::std::vector<::std::string> & split( ::std::vector<::std::string> &output, const ::std::string &str, char delim, ::std::string::size_type offset = 0 );
+ ::std::vector<::std::string> & split( ::std::vector<::std::string> &output, const ::std::string &str, const ::std::string &delim, ::std::string::size_type offset = 0 );
+ ::std::vector<::std::string> & split( ::std::vector<::std::string> &output, const ::std::string &str, const ::std::vector<::std::string> &delim, ::std::string::size_type offset = 0 );
+ ::std::string trim( const ::std::string &str );
+ ::std::string & toLowerCase( ::std::string &output, const ::std::string &str );
+ ::std::string & toLowerCase( ::std::string &str );
+ ::std::string & toUpperCase( ::std::string &output, const ::std::string &str );
+ ::std::string & toUpperCase( ::std::string &str );
+ ::std::string & extractDirPath( ::std::string &output, const ::std::string &file, char dirDelimeter );
+ ::std::string & extractDirPath( ::std::string &output, const ::std::string &file, const ::std::string &dirDelimeter );
+ ::std::string & replaceCharacters( ::std::string &str, char characterToReplace, char newCharacter, const ::std::string::size_type &offset = 0, const ::std::string::size_type &end = ::std::string::npos );
+ }
+
+ namespace Stream
+ {
+ float* readFloats( float *output, ::std::istream &input, unsigned int numFloats );
+ }
+
+ namespace StaticArray
+ {
+ template
+ inline unsigned int numElementsOf( const ElementType(&)[num] )
+ { return num; }
+ }
+
+ namespace Element
+ {
+ template
+ inline void swap( ElementType &elementA, ElementType &elementB, ElementType &swapSpace )
+ { swapSpace = elementA; elementA = elementB; elementB = swapSpace; }
+
+ template
+ inline void swap( ElementType &elementA, ElementType &elementB )
+ { ElementType swapSpace; swap( elementA, elementB, swapSpace ); }
+ }
+
+ namespace Value
+ {
+ template
+ inline ValueType abs( const ValueType &value )
+ { return value < 0 ? value * -1 : value; }
+
+ template
+ inline ValueType max( const ValueType &valueA, const ValueType &valueB )
+ { return valueA > valueB ? valueA : valueB; }
+
+ template
+ inline ValueType min( const ValueType &valueA, const ValueType &valueB )
+ { return valueA < valueB ? valueA : valueB; }
+
+ template
+ inline ValueType radian( const ValueType °ree )
+ { return degree * (3.1415926535897932384626433832795f / 180.0f); }
+
+ template
+ inline ValueType degree( const ValueType &radian )
+ { return radian * (180.0f / 3.1415926535897932384626433832795f); }
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/Misc/WinTimer.cpp b/Misc/WinTimer.cpp
new file mode 100644
index 00000000..d8ccfbb2
--- /dev/null
+++ b/Misc/WinTimer.cpp
@@ -0,0 +1,75 @@
+#include "WinTimer.h"
+
+using namespace ::Utility;
+
+namespace PrivateStatic
+{
+ LARGE_INTEGER ticksPerSecond = { 0 };
+ double secondsPerTick = 0.0f;
+
+ class WatchDog
+ {
+ public:
+ WatchDog( )
+ {
+ if( QueryPerformanceFrequency( &ticksPerSecond ) > 0 )
+ secondsPerTick = ((double)1.0f) / (double) ticksPerSecond.QuadPart;
+ }
+ } watchDog;
+}
+
+WinTimer::WinTimer( ) : isPaused(false)
+{ this->reset(); }
+
+void WinTimer::reset( )
+{
+ this->isPaused = false;
+ this->pauseCount.QuadPart = 0;
+ QueryPerformanceCounter( &this->startTick );
+}
+
+void WinTimer::pause( )
+{
+ if( !this->isPaused )
+ {
+ this->isPaused = true;
+ QueryPerformanceCounter( &this->pauseStart );
+ }
+}
+
+void WinTimer::resume( )
+{
+ if( this->isPaused )
+ {
+ this->isPaused = false;
+ LARGE_INTEGER currentTick;
+ QueryPerformanceCounter( ¤tTick );
+ this->pauseCount.QuadPart += currentTick.QuadPart - this->pauseStart.QuadPart;
+ }
+}
+
+double WinTimer::getElapsedSeconds( ) const
+{
+ if( this->isPaused )
+ {
+ LARGE_INTEGER totalTick = this->pauseStart;
+ totalTick.QuadPart -= this->startTick.QuadPart;
+ totalTick.QuadPart -= this->pauseCount.QuadPart;
+ return PrivateStatic::secondsPerTick * (double)totalTick.QuadPart;
+ }
+ else
+ {
+ LARGE_INTEGER currentTick;
+ QueryPerformanceCounter( ¤tTick );
+ currentTick.QuadPart -= this->startTick.QuadPart;
+ currentTick.QuadPart -= this->pauseCount.QuadPart;
+ return PrivateStatic::secondsPerTick * (double)currentTick.QuadPart;
+ }
+}
+
+LARGE_INTEGER WinTimer::getCurrentTick( ) const
+{
+ LARGE_INTEGER currentTick;
+ QueryPerformanceCounter( ¤tTick );
+ return currentTick;
+}
\ No newline at end of file
diff --git a/Misc/WinTimer.h b/Misc/WinTimer.h
new file mode 100644
index 00000000..73e9091f
--- /dev/null
+++ b/Misc/WinTimer.h
@@ -0,0 +1,32 @@
+/////////////////////////////////////////////////////////////////////
+// Instanciable Timer class for windows
+// © Dan Andersson 2013
+/////////////////////////////////////////////////////////////////////
+
+#pragma once
+#ifndef WINTIMER_H
+#define WINTIMER_H
+
+#include
+
+namespace Utility
+{
+ class WinTimer
+ {
+ public:
+ WinTimer( );
+
+ void reset( );
+ void pause( );
+ void resume( );
+
+ double getElapsedSeconds( ) const;
+ LARGE_INTEGER getCurrentTick( ) const;
+
+ private:
+ LARGE_INTEGER startTick, pauseStart, pauseCount;
+ bool isPaused;
+ };
+}
+
+#endif
\ No newline at end of file
diff --git a/Network/NetworkDependencies/Event.cpp b/Network/NetworkDependencies/Event.cpp
new file mode 100644
index 00000000..33e92bbf
--- /dev/null
+++ b/Network/NetworkDependencies/Event.cpp
@@ -0,0 +1,262 @@
+#include "Event.h"
+using namespace Event;
+
+
+//----------------------------
+// BulletCreated class definitions
+BulletCreated::BulletCreated(int ownerID, Float3 position, Float3 direction)
+ :
+ GameEvent()
+{
+ data.owner=ownerID;
+ data.head=direction;
+}
+void BulletCreated::LoadRawData(char* d)
+{
+ memcpy(&data, d, GetSize());
+ /*int offset=0;
+ memcpy(&data.position, data, sizeof(Float3));
+ offset+=sizeof(Float3);
+
+ memcpy(&data.head, d+offset, sizeof(Float3));
+ offset+=sizeof(Float3);
+ memcpy(&data.owner, d+offset, sizeof(int));*/
+}
+void BulletCreated::SaveRawData(char* d)
+{
+ memcpy(d, &data, GetSize());
+}
+
+//----------------------------
+// BulletHit class definitions
+BulletHit::BulletHit(int attacker, int hitPlayer)
+ :
+ GameEvent()
+{
+ data.hitTarget=hitPlayer;
+ data.attackingTarget=attacker;
+ //this->hpLeft=hl;
+ //this->shieldLeft=sl;
+}
+void BulletHit::LoadRawData(char* d)
+{
+ memcpy(&data, d, GetSize());
+}
+void BulletHit::SaveRawData(char* d)
+{
+ memcpy(d, &data, GetSize());
+}
+
+ScoreUpdate::ScoreUpdate(Score* scores)
+{
+ for (int i=0; iGetSize());
+ /*int offset=0;
+ memcpy(&data.position, data, sizeof(Float3));
+ offset+=sizeof(Float3);
+
+ memcpy(&playerID, data+offset, sizeof(int));*/
+}
+void ShipSpawned::SaveRawData(char* d)
+{
+ memcpy(d, &data, GetSize());
+}
+
+
+//----------------------------
+// GameEnded class definitions
+GameEnded::GameEnded()
+ :
+ GameEvent()
+{
+}
+GameEnded::GameEnded(int winner)
+ :
+ GameEvent()
+{
+ data.winningTeam=winner;
+}
+void GameEnded::LoadRawData(char* d)
+{
+ memcpy(&data, d, GetSize());
+ /*int offset=0;
+ memcpy(&eventPosition, data, sizeof(Float3));
+ offset+=sizeof(Float3);
+
+ memcpy(&winningTeam, data+offset, sizeof(int));
+ offset+=sizeof(int);
+
+ for (int i=0; i
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "OysterMath.h"
+using namespace Oyster::Math;
+
+//ws2_32.lib is a lib file the linker requires for winsock compilation
+#pragma comment(lib, "Ws2_32.lib")
+#endif
\ No newline at end of file
diff --git a/Network/NetworkDependencies/NetworkInitStructs.h b/Network/NetworkDependencies/NetworkInitStructs.h
new file mode 100644
index 00000000..7ef04ed1
--- /dev/null
+++ b/Network/NetworkDependencies/NetworkInitStructs.h
@@ -0,0 +1,70 @@
+#ifndef NET_INIT_STRUCTS_H
+#define NET_INIT_STRUCTS_H
+#include "NetworkIncludes.h"
+#include "NetworkConstants.h"
+struct PlayerInitStruct
+{
+ INT8 pid;
+ int teamid;
+ Oyster::Math::Float4x4 position;
+ PlayerInitStruct()
+ {
+ pid=0;
+ //position=Oyster::Math::Float4x4::identity;
+ }
+};
+
+struct GameInitData
+{
+ INT8 pid;
+ //std::string playerNames[PLAYER_MAX_COUNT];
+ PlayerInitStruct player[PLAYER_MAX_COUNT];
+};
+
+struct LobbyUserStruct
+{
+ INT8 pid;
+ INT8 shipID;
+ char usrName[15];
+ LobbyUserStruct()
+ {
+ pid=0;
+ shipID=0;
+ usrName[0]='\0';
+ }
+ void setName(const char* n)
+ {
+ strcpy_s(usrName, n);
+ }
+ int size()
+ {
+ int sz=sizeof(pid);
+ sz+=sizeof(shipID);
+ int tmp=(int)strlen(usrName);
+ sz+=(int)strlen(usrName);
+ return sz;
+ }
+};
+struct LobbyInitData
+{
+ INT8 pid;
+ INT8 playerCount;
+ int timer;
+ LobbyUserStruct players[PLAYER_MAX_COUNT];
+ LobbyInitData()
+ {
+ pid=0;
+ for (int i=0; i splitString(const char* p_inStr, char p_delim)
+{
+ std::stringstream ss(p_inStr);
+ std::vector elems;
+ std::string item;
+ while(std::getline(ss, item, p_delim))
+ {
+ elems.push_back(item);
+ }
+ return elems;
+}
\ No newline at end of file
diff --git a/Network/NetworkDependencies/NetworkMiscFunctions.h b/Network/NetworkDependencies/NetworkMiscFunctions.h
new file mode 100644
index 00000000..a6959020
--- /dev/null
+++ b/Network/NetworkDependencies/NetworkMiscFunctions.h
@@ -0,0 +1,9 @@
+#ifndef NET_MISC_FNC_H
+#define NET_MISC_FNC_H
+#include
+#include
+#include
+std::vector splitString(const char* p_inStr, char p_delim);
+#define SSTR( x ) dynamic_cast< std::ostringstream & >( \
+ ( std::ostringstream() << std::dec << x ) ).str()
+#endif
\ No newline at end of file
diff --git a/Network/NetworkDependencies/NetworkTimer.cpp b/Network/NetworkDependencies/NetworkTimer.cpp
new file mode 100644
index 00000000..42b8a143
--- /dev/null
+++ b/Network/NetworkDependencies/NetworkTimer.cpp
@@ -0,0 +1,85 @@
+#include "NetworkTimer.h"
+NetworkTimer::NetworkTimer()
+ :
+ c_SecondsPerCount(0.0),
+ c_DeltaTime(-1.0),
+ c_BaseTime(0),
+ c_PausedTime(0),
+ c_PrevTime(0),
+ c_CurrTime(0),
+ c_Stopped(false)
+{
+ __int64 countsPerSec;
+ QueryPerformanceFrequency((LARGE_INTEGER*)&countsPerSec);
+ c_SecondsPerCount =1.0 / (double)countsPerSec;
+
+ QueryPerformanceCounter((LARGE_INTEGER*)&c_PrevTime);
+}
+
+void NetworkTimer::start()
+{
+ __int64 p_StartTime;
+ QueryPerformanceCounter((LARGE_INTEGER*)&p_StartTime);
+ if(c_Stopped)
+ {
+ c_PausedTime += (p_StartTime-c_StopTime);
+ c_PrevTime = p_StartTime;
+ c_StopTime = 0;
+ c_Stopped = false;
+ }
+}
+__int64 NetworkTimer::getTime()
+{
+ __int64 testInt;
+ return QueryPerformanceCounter((LARGE_INTEGER*)&testInt);
+ return testInt;
+}
+
+void NetworkTimer::stop()
+{
+ if(!c_Stopped)
+ {
+ __int64 p_CurrTime;
+ QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
+ c_StopTime = p_CurrTime;
+ c_Stopped = true;
+ }
+}
+void NetworkTimer::reset()
+{
+ __int64 p_CurrTime;
+ QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
+ c_BaseTime = p_CurrTime;
+ c_PrevTime = p_CurrTime;
+ c_StopTime = 0;
+ c_Stopped = false;
+}
+void NetworkTimer::tick()
+{
+ if (c_Stopped)
+ {
+ c_DeltaTime= 0.0;
+ return;
+ }
+ __int64 p_CurrTime;
+ QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
+ c_CurrTime=p_CurrTime;
+
+ c_DeltaTime=(c_CurrTime-c_PrevTime)*c_SecondsPerCount;
+ c_PrevTime=c_CurrTime;
+ if(c_DeltaTime<0.0) c_DeltaTime=0.0;
+}
+float NetworkTimer::getGameTime() const
+{
+ if(c_Stopped)
+ {
+ return (float)((c_StopTime-c_BaseTime)*c_SecondsPerCount);
+ } else
+ {
+ return (float)(((c_CurrTime-c_PausedTime)-c_BaseTime)*c_SecondsPerCount);
+ }
+}
+float NetworkTimer::getDeltaTime() const
+{
+ return (float)c_DeltaTime;
+}
\ No newline at end of file
diff --git a/Network/NetworkDependencies/NetworkTimer.h b/Network/NetworkDependencies/NetworkTimer.h
new file mode 100644
index 00000000..c4581c50
--- /dev/null
+++ b/Network/NetworkDependencies/NetworkTimer.h
@@ -0,0 +1,25 @@
+#include "NetworkIncludes.h"
+#ifndef _NET_TIMER_H
+#define _NET_TIMER_H
+class NetworkTimer
+{
+private:
+ double c_SecondsPerCount;
+ double c_DeltaTime;
+ __int64 c_BaseTime;
+ __int64 c_PausedTime;
+ __int64 c_StopTime;
+ __int64 c_PrevTime;
+ __int64 c_CurrTime;
+ bool c_Stopped;
+public:
+ NetworkTimer();
+ __int64 getTime();
+ void start();
+ void stop();
+ void reset();
+ void tick();
+ float getGameTime() const;
+ float getDeltaTime() const;
+};
+#endif
\ No newline at end of file
diff --git a/Network/NetworkDependencies/NetworkUpdateStructs.h b/Network/NetworkDependencies/NetworkUpdateStructs.h
new file mode 100644
index 00000000..97f2037d
--- /dev/null
+++ b/Network/NetworkDependencies/NetworkUpdateStructs.h
@@ -0,0 +1,62 @@
+#ifndef NET_UPD_STRUCTS_H
+#define NET_UPD_STRUCTS_H
+#include "NetworkIncludes.h"
+namespace Network
+{
+ struct EffectData
+ {
+ int identifier;
+ Float3 head;
+ Float3 tail;
+ };
+ struct ServerToClientUpdateData
+ {
+ int pid;
+ Oyster::Math::Float4x4 position;
+ float dirVecLen;
+ int hp;
+ int shield;
+ long updateCount;
+ ServerToClientUpdateData()
+ {
+ pid=0;
+ updateCount=0;
+ hp=0;
+ shield=0;
+ }
+ };
+ const int SERVER_PLAYER_DATA_SIZE = 84;
+ struct ClientToServerUpdateData
+ {
+ __int8 pid;
+ //Oyster::Math::Float4x4 position;
+ __int8 forward;
+ __int8 roll;
+ __int8 straferight;
+ __int8 strafeup;
+ bool firePrim;
+ bool fireSecond;
+ bool fireSpecial;
+ long updateCount;
+ bool braking;
+ float TurnHor;
+ float TurnVer;
+ ClientToServerUpdateData()
+ {
+ pid=0;
+ forward=0;
+ roll=0;
+ straferight=0;
+ strafeup=0;
+ firePrim=false;
+ fireSecond=false;
+ fireSpecial=false;
+ updateCount=0;
+ braking=false;
+ TurnHor= 0.0f;
+ TurnVer= 0.0f;
+ }
+ };
+ const int CLIENT_PLAYER_DATA_SIZE = sizeof(ClientToServerUpdateData);
+}
+#endif
\ No newline at end of file
diff --git a/Network/NetworkDependencies/UpdateStructs.cpp b/Network/NetworkDependencies/UpdateStructs.cpp
new file mode 100644
index 00000000..05209a9c
--- /dev/null
+++ b/Network/NetworkDependencies/UpdateStructs.cpp
@@ -0,0 +1 @@
+#include "NetworkUpdateStructs.h"
\ No newline at end of file
diff --git a/Network/OysterNetworkClient/ClientDataHandler.cpp b/Network/OysterNetworkClient/ClientDataHandler.cpp
new file mode 100644
index 00000000..52d0f2ff
--- /dev/null
+++ b/Network/OysterNetworkClient/ClientDataHandler.cpp
@@ -0,0 +1,112 @@
+#include "SocketClient.h"
+
+#pragma once
+#ifndef SOCKET_DATA_CPP
+#define SOCKET_DATA_CPP
+
+/*std::vector splitString(char* p_inStr, char p_delim)
+{
+std::stringstream ss(p_inStr);
+std::vector elems;
+std::string item;
+while(std::getline(ss, item, p_delim))
+{
+elems.push_back(item);
+}
+return elems;
+}*/
+
+void SocketClient::parseReceivedData(/*char* data, int size*/)
+{
+ switch (recvBuffer[0]) // TODO: runtime error occured here when shutting down client. recvBuffer invalid pointer. ~Dan 2013-05-14
+ {
+ case 1://It's data
+ parseData();
+ break;
+ case 2://For the moment, this is only for init data
+ parseGameInitData();
+ break;
+ case 3://It's a chat message
+ parseMessage();
+ break;
+ case 4://It's a server message
+ parseServermessage();
+ break;
+ case 5://Player has been connected to a game lobby
+ parseLobbyInitData();
+ break;
+ case 6://It's an event
+ parseReceivedEvent();
+ break;
+ case 7:
+ parseReceivedEffect();
+ break;
+ case 8:
+ parseRenderData();
+ break;
+ default:
+ int a=0;
+
+ }
+}
+void SocketClient::parseRenderData()
+{
+ receiveRenderData(recvBuffer+1, recvBufLen-1);
+}
+void SocketClient::parseReceivedEffect()
+{
+ receiveEffectData(recvBuffer+1, recvBufLen-1);
+}
+void SocketClient::parseReceivedEvent()
+{
+ receiveEvent(recvBuffer+1);
+}
+void SocketClient::parseGameInitData()
+{
+ receiveGameInitData(recvBuffer+1);
+ connectStatus=true;
+}
+
+void SocketClient::parseLobbyInitData()
+{
+ receiveLobbyInitData(recvBuffer+1, recvBufLen-1);
+ connectStatus=true;
+}
+
+void SocketClient::parseServermessage()
+{
+ recvBuffer[recvBufLen]='\0';
+ if(!strcmp(recvBuffer+1, "connected"))
+ {
+ connectStatus=true;
+ connStatus=ONLINE_MAINMENU;
+ receiveConnStatus(ONLINE_MAINMENU);
+ }
+ else if(!strcmp(recvBuffer+1, "qst"))
+ {
+ connStatus=ONLINE_QUEUEING;
+ receiveConnStatus(ONLINE_QUEUEING);
+ }
+ else if(!strcmp(recvBuffer+1, "qed"))
+ {
+ connStatus=ONLINE_MAINMENU;
+ receiveConnStatus(ONLINE_MAINMENU);
+ }
+ //Server message of some sort
+}
+
+void SocketClient::parseData()
+{
+ //memcpy(&tmpPlayer,buffer+1,playerDataSize);
+ //playerContPtr->setPlayerStruct(tmpPlayer);
+ receivePlayerUpdate(recvBuffer+1, recvBufLen-1);
+}
+
+void SocketClient::parseMessage()
+{
+ //std::string message;
+ //message="[Chat] "+users[pid].getUsername()+": "+(buffer+1);
+ printf("%s\n",recvBuffer+1);
+}
+
+#endif
diff --git a/Network/OysterNetworkClient/ClientInitFunctions.cpp b/Network/OysterNetworkClient/ClientInitFunctions.cpp
new file mode 100644
index 00000000..e2c4b920
--- /dev/null
+++ b/Network/OysterNetworkClient/ClientInitFunctions.cpp
@@ -0,0 +1,79 @@
+#include "SocketClient.h"
+
+#pragma once
+#ifndef SOCKET_INIT_CPP
+#define SOCKET_INIT_CPP
+
+bool SocketClient::startReceiveThread()
+{
+ threadhandle[0]=CreateThread(
+ NULL,
+ 0,
+ (LPTHREAD_START_ROUTINE)&receiveDataThreadV,
+ (LPVOID) this,
+ 0,
+ NULL);
+ return true;
+}
+
+bool SocketClient::startSendDataThread()
+{
+ threadhandle[1]=CreateThread(
+ NULL,
+ 0,
+ (LPTHREAD_START_ROUTINE)&receiveDataThreadV,
+ (LPVOID) this,
+ 0,
+ NULL);
+ return true;
+}
+bool SocketClient::init(int listenPort)
+{
+ return initUDPSocket(listenPort);
+}
+bool SocketClient::connectToIP(const char* ip, int listenPort, char* initData, int initDataSize)
+{
+ init(listenPort);
+ //---------------------------------------------
+ // Set up the port and IP of the server
+ //Port starts up as a different one from when connected, it changes once the server has exchanged some info with the client
+
+ UDPsendAddr.sin_family = AF_INET;
+ UDPsendAddr.sin_port = htons(UDPSendPort);
+ UDPsendAddr.sin_addr.s_addr = inet_addr(ip);
+
+ TCPsendAddr.sin_family = AF_INET;
+ TCPsendAddr.sin_port = htons(TCPSendPort);
+ TCPsendAddr.sin_addr.s_addr = inet_addr(ip);
+ /*iResult=connect(connTCP, (SOCKADDR *) &TCPsendAddr, addrSize);
+ if (iResult == SOCKET_ERROR) {
+ int test=WSAGetLastError();
+ wprintf(L"connect failed with error: %d\n", WSAGetLastError());
+ //closesocket(connTCP);
+ //WSACleanup();
+ return false;
+ }/*
+ iResult=send(connTCP, initData, initDataSize, 0);
+ if (iResult == SOCKET_ERROR) {
+ int test=WSAGetLastError();
+ wprintf(L"connect failed with error: %d\n", WSAGetLastError());
+ //closesocket(connTCP);
+ //WSACleanup();
+ return false;
+ }*/
+
+ iResult = sendto(connUDP,
+ initData, initDataSize, 0, (SOCKADDR *) & UDPsendAddr, addrSize);
+ if (iResult == SOCKET_ERROR) {
+ wprintf(L"Client UDP sendto failed with error: %d\n", WSAGetLastError());
+ //closesocket(connUDP);
+ //WSACleanup();
+ return false;
+ }
+ //connectStatus=true;
+ connectStatus=false;
+ return true;
+}
+
+
+#endif
diff --git a/Network/OysterNetworkClient/ClientMain.cpp b/Network/OysterNetworkClient/ClientMain.cpp
new file mode 100644
index 00000000..5c297686
--- /dev/null
+++ b/Network/OysterNetworkClient/ClientMain.cpp
@@ -0,0 +1,79 @@
+#include "SocketClient.h"
+const int maxThreadCount=2;
+bool validateIpAddress(const std::string ipAddress)
+{
+ struct sockaddr_in sa;
+ int result = inet_pton(AF_INET, ipAddress.c_str(), &(sa.sin_addr));
+ return result != 0;
+}
+/*int main(int argc, char *argv[])
+{
+ std::string tst;
+ bool test=true;
+ //Multithreading variables
+ //int nThreads = 0;
+ //DWORD dwThreadId[maxThreadCount];
+ //HANDLE threadhandle;
+
+ GameClass game;
+ SocketClient client;
+ //Sets up the link to the GameClass class.
+ client.setPlayerContPtr(&game);
+ //This is the loop which makes the user enter the server address.
+ while (!client.isReady());
+ do
+ {
+ if (!test)
+ {
+ printf("Could not connect to server. Try another IP.\n");
+ }
+ else
+ {
+ printf("Enter the server ip. \n");
+ }
+ getline(std::cin, tst);
+ if (tst.length()==0)
+ {
+ tst="127.0.0.1";
+ }
+ if (validateIpAddress(tst))
+ {
+ //Tmp init connection message: set username
+ char* tmp=new char[30];
+ printf("What is your desired username?\n");
+ std::cin.getline(tmp,30);
+ if (strlen(tmp)==0)
+ {
+ tmp="Anonymous";
+ }
+ printf("Username set to %s\n", tmp);
+
+ test=client.connectToIP(tst.c_str(), tmp, strlen(tmp));
+ }
+ else
+ {
+ printf("Invalid IPaddress. Please enter a new IPaddress.\n");
+ test=false;
+ }
+ } while (!test);
+ while (!client.isConnected());
+ Sleep(1000);
+ //Starts the receive loop
+ //threadhandle=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&client.receiveDataThreadV,(LPVOID) &client,0,&dwThreadId[0]);
+ client.startReceiveThread();
+ //GetExitCodeThread(threadhandle, eCode);
+ //This is just a loop to receive user input which creates a natural delay for sendUserData.
+ printf("Write what you want to send\n");
+ tst="tmp init message";
+ while (tst.length()>0)
+ {
+ client.sendMessage(tst);
+ client.sendUserData();
+ getline(std::cin, tst);
+ }
+ //Kills off the thread and connection
+ //DWORD eCode=0;
+ //TerminateThread(threadhandle, eCode);
+ client.closeConnection();
+ return 0;
+}*/
\ No newline at end of file
diff --git a/Network/OysterNetworkClient/ClientTCPSpecific.cpp b/Network/OysterNetworkClient/ClientTCPSpecific.cpp
new file mode 100644
index 00000000..1e8b7216
--- /dev/null
+++ b/Network/OysterNetworkClient/ClientTCPSpecific.cpp
@@ -0,0 +1,39 @@
+#include "SocketClient.h"
+
+bool SocketClient::initTCPSocket(int listenPort)
+{
+ TCPrecvAddr.sin_family = AF_INET;
+ TCPrecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ TCPrecvAddr.sin_port = htons(/*TCPRecvPort*/listenPort);
+
+ connTCP = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (connTCP == INVALID_SOCKET)
+ {
+ wprintf(L"socket function failed with error: %ld\n", WSAGetLastError());
+ WSACleanup();
+ return false;
+ }
+
+ iResult = bind(connTCP, (SOCKADDR *) & TCPrecvAddr, addrSize);
+ if (iResult == SOCKET_ERROR)
+ {
+ int tst=WSAGetLastError();
+ wprintf(L"bind function failed with error %d\n", WSAGetLastError());
+ iResult = closesocket(connTCP);
+ if (iResult == SOCKET_ERROR)
+ wprintf(L"closesocket function failed with error %d\n", WSAGetLastError());
+ //WSACleanup();
+ return false;
+ }
+ return true;
+}
+bool SocketClient::sendDataTCP(const char* data, int size)
+{
+ iResult = sendto(connTCP,
+ data, size, 0, (SOCKADDR *) & TCPsendAddr, addrSize);
+ if (iResult == SOCKET_ERROR) {
+ wprintf(L"TCP sendto failed with error: %d\n", WSAGetLastError());
+ return false;
+ }
+ return true;
+}
\ No newline at end of file
diff --git a/Network/OysterNetworkClient/ClientUDPSpecific.cpp b/Network/OysterNetworkClient/ClientUDPSpecific.cpp
new file mode 100644
index 00000000..9cab63ae
--- /dev/null
+++ b/Network/OysterNetworkClient/ClientUDPSpecific.cpp
@@ -0,0 +1,39 @@
+#include "SocketClient.h"
+bool SocketClient::initUDPSocket(int listenPort)
+{
+ UDPrecvAddr.sin_family = AF_INET;
+ UDPrecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ UDPrecvAddr.sin_port = htons(listenPort);
+ //---------------------------------------------
+ // Create a socket for sending data
+ connUDP = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (connUDP == INVALID_SOCKET)
+ {
+ wprintf(L"socket failed with error: %ld\n", WSAGetLastError());
+ WSACleanup();
+ return false;
+ }
+ iResult = bind(connUDP, (SOCKADDR *) & UDPrecvAddr, addrSize);
+ if (iResult == SOCKET_ERROR)
+ {
+ wprintf(L"bind function failed with error %d\n", WSAGetLastError());
+ iResult = closesocket(connUDP);
+ if (iResult == SOCKET_ERROR)
+ wprintf(L"closesocket function failed with error %d\n", WSAGetLastError());
+ WSACleanup();
+ return false;
+ }
+ return true;
+}
+bool SocketClient::sendDataUDP(const char* data, int size)
+{
+ iResult = sendto(connUDP,
+ data, size, 0, (SOCKADDR *) & UDPsendAddr, addrSize);
+ if (iResult == SOCKET_ERROR) {
+ wprintf(L"sendto failed with error: %d\n", WSAGetLastError());
+ //closesocket(connUDP);
+ //WSACleanup();
+ return false;
+ }
+ return true;
+}
\ No newline at end of file
diff --git a/Network/OysterNetworkClient/SocketClient.cpp b/Network/OysterNetworkClient/SocketClient.cpp
new file mode 100644
index 00000000..cde039cf
--- /dev/null
+++ b/Network/OysterNetworkClient/SocketClient.cpp
@@ -0,0 +1,133 @@
+#include "SocketClient.h"
+#pragma once
+#ifndef SOCKET_CLIENT_CPP
+#define SOCKET_CLIENT_CPP
+
+SocketClient::SocketClient()
+{
+ playerDataSize=Network::CLIENT_PLAYER_DATA_SIZE;
+ sendDelayMS=10;
+ connUDP = INVALID_SOCKET;
+ connTCP = INVALID_SOCKET;
+ //sendBuffer=new char[BUFFER_MAX_SIZE];
+ //sendBufLen=BUFFER_MAX_SIZE;
+ //ZeroMemory(sendBuffer,sendBufLen);
+ recvBuffer=new char[BUFFER_MAX_SIZE];
+ recvBufLen=BUFFER_MAX_SIZE;
+ ZeroMemory(recvBuffer,recvBufLen);
+
+ dataBuf=new char[playerDataSize+1];
+ dataBuf[0]=1;
+ //ZeroMemory(b,sizeof(buffer));
+ //----------------------
+ // Initialize Winsock
+ iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
+ if (iResult != NO_ERROR) {
+ printf("WSAStartup failed with error: %d\n", iResult);
+ }
+
+
+
+ addrSize=sizeof(sockaddr_in);
+ connectStatus=false;
+}
+
+
+
+bool SocketClient::sendUserData()
+{
+ //memcpy(dataBuf+1,&playerContPtr->getPlayerData(),playerDataSize);
+ //return sendData(dataBuf, playerDataSize+1);
+ printf("NOT YET IMPLEMENTED");
+ return false;
+}
+
+bool SocketClient::sendUserData(char* data, int size)
+{
+ memcpy(dataBuf+1,data,size);
+ return sendDataUDP(dataBuf, size+1);
+}
+
+bool SocketClient::sendMessage(std::string msg)
+{
+ if (msg[0]=='/')
+ {
+ //Server command
+ msg[0]=2;
+
+ }
+ else
+ {
+ //Chat message
+ msg='1'+msg;
+ msg[0]=3;
+ }
+ return sendDataUDP(msg.c_str(), (int)msg.size());
+}
+
+bool SocketClient::closeConnection()
+{
+ connectStatus=false;
+ Sleep(5);
+ //Give the threads 5 ms to quit themselves before terminating them
+ DWORD eCode=0;
+ TerminateThread(threadhandle[0], eCode);
+ TerminateThread(threadhandle[1], eCode);
+ //---------------------------------------------
+ // When the application is finished sending, close the socket.
+ setupStatus=false;
+ printf("Finished sending. Closing socket.\n");
+ iResult = closesocket(connUDP);
+ if (iResult == SOCKET_ERROR)
+ {
+ wprintf(L"closesocket failed with error: %d\n", WSAGetLastError());
+ WSACleanup();
+ return false;
+ }
+ //---------------------------------------------
+ // Clean up and quit.
+ printf("Exiting.\n");
+ WSACleanup();
+ return true;
+}
+
+void SocketClient::receiveDataThreadV(SocketClient* ptr)
+{
+ while(true)
+ {
+ ptr->recvBufLen=recvfrom(ptr->connUDP, ptr->recvBuffer, BUFFER_MAX_SIZE, 0, (SOCKADDR *) & ptr->UDPsendAddr, &ptr->addrSize);
+ if (ptr->recvBufLen == SOCKET_ERROR)
+ {
+ wprintf(L"recv failed with error %d\n", WSAGetLastError());
+ }
+ //ptr->buffer[ptr->iResult]='\0';
+ else
+ ptr->parseReceivedData();
+ }
+}
+
+
+void SocketClient::receiveDataWaitOnResponse()
+{
+ recvBufLen=recvfrom(connUDP, recvBuffer, BUFFER_MAX_SIZE, 0, (SOCKADDR *) & UDPsendAddr, &addrSize);
+ if (recvBufLen == SOCKET_ERROR)
+ {
+ wprintf(L"recv failed with error %d\n", WSAGetLastError());
+ }
+ //buffer[iResult]='\0';
+ else
+ parseReceivedData();
+}
+
+void SocketClient::sendDataThreadV(SocketClient* ptr)
+{
+ printf("NOT YET IMPLEMENTED");
+ /*while(ptr->connectStatus)
+ {
+ memcpy(ptr->dataBuf+1,&ptr->playerContPtr->getPlayerData(),playerDataSize);
+ ptr->sendData(ptr->dataBuf, playerDataSize+1);
+ Sleep(ptr->sendDelayMS);
+ }*/
+}
+
+#endif
\ No newline at end of file
diff --git a/Network/OysterNetworkClient/SocketClient.h b/Network/OysterNetworkClient/SocketClient.h
new file mode 100644
index 00000000..46c57d8d
--- /dev/null
+++ b/Network/OysterNetworkClient/SocketClient.h
@@ -0,0 +1,147 @@
+#pragma once
+//Start by defining unicode
+//#ifndef UNICODE
+//#define UNICODE
+//#endif
+//defining WIN32_LEAN_AND_MEAN this early is REQUIRED if you want to avoid a certain winsock error.
+//#define WIN32_LEAN_AND_MEAN
+//#define NOMINMAX
+//#include
+//#include "GameClassExample.h"
+//These includes are required for winsock
+#include "Network.h"
+//#include
+//#include
+//#include
+//#include
+//#include "OysterMath.h"
+//These are optional includes for various useful features
+#include
+#include
+#include
+#include
+
+//ws2_32.lib is a lib file the linker requires for winsock compilation
+#pragma comment(lib, "Ws2_32.lib")
+
+//constants used by the socket client to avoid hard coding and/or mass variable declaration
+const short TCPSendPort = 11110;
+const short TCPRecvPort = 11111;
+const short UDPSendPort = 11000;
+const short UDPRecvPort = 11001;
+const int BUFFER_MAX_SIZE = 4096;
+
+enum ConnectionStatus
+{
+ OFFLINE,
+ ONLINE_MAINMENU,
+ ONLINE_QUEUEING,
+ ONLINE_INLOBBY,
+ ONLINE_INGAME
+};
+class SocketClient
+{
+private:
+ HANDLE threadhandle[2];
+ int sendDelayMS;
+
+ //2 bools used to verify the activation of the client so threads can't start too early
+ ConnectionStatus connStatus;
+ bool setupStatus;
+ bool connectStatus;
+
+ //iResult is used to check error codes
+ int iResult;
+ //wsaData records error messages and errors which winsock might encounter
+ WSADATA wsaData;
+
+ //Main socket
+ SOCKET connUDP;
+ SOCKET connTCP;
+
+ //Addresses used for data transfer
+ sockaddr_in TCPrecvAddr;
+ sockaddr_in TCPsendAddr;
+ //UDPrecvAddr marks the port and IP adress the server is supposed to return data to.
+ sockaddr_in UDPrecvAddr;
+ //UDPsendAddr marks which IP and port the client is supposed to send data to.
+ sockaddr_in UDPsendAddr;
+ //size of a sockaddr_in. This might as well be a constant, but i'm keeping it in the class for performance reasons.
+ int addrSize;
+
+ //buffer which is filled when data receive happens.
+ char* recvBuffer;
+ //this variable tracks the buffer length.
+ int recvBufLen;
+
+ //dataBuf is a buffer solely for sending your own user data. It never changes size in order to increase performance.
+ //char* sendBuffer;
+ //int sendBufLen;
+ //PlayerStruct tmpPlayer;
+ char* dataBuf;
+ int playerDataSize;
+public:
+ void setPlayerDataSize(int pds){playerDataSize=pds;}
+ //Constructor
+ SocketClient();
+
+ //Initiation for sockets.
+ bool init(int listenPort);
+ bool initTCPSocket(int listenPort);
+ bool initUDPSocket(int listenPort);
+ //Connects to a server of a user-defined IP. Can only be called after an initXSocket has gone through.
+ //The 2 remaining variables are init data and size of said data. Currently username.
+ bool connectToIP(const char* ip, int listenPort, char* initData, int initDataSize);
+ //sends an undefined data type of (variable#2) size to the server.
+ bool sendDataUDP(const char*, int);
+ bool sendDataTCP(const char*, int);
+ //sends a text string to the server.
+ bool sendMessage(std::string str);
+ bool sendServerMessage(std::string str);
+ //sends user data to the server
+ bool sendUserData();
+ bool sendUserData(char* data, int size);
+
+ //Closes connection, kills off the socket.
+ bool closeConnection();
+
+ //Simple ifBoolIsTrue checks
+ bool isReady() const {return setupStatus;}
+ bool isConnected() const {return connectStatus;}
+ void receiveDataWaitOnResponse();
+ //Sends data periodically
+ static void sendDataThreadV(SocketClient* ptr);
+ //Receive loop. This is event-based and is on its own thread.
+ static void receiveDataThreadV(SocketClient* ptr);
+ //Once data is received, it calls on the parseReceivedData function.
+ void parseReceivedData();
+ //void parseReceivedKeyframe();
+ //If an event is called from the server, this function will be called.
+ void parseReceivedEvent();
+ void parseReceivedEffect();
+ //It is then sent to one of the following functions based on the first byte of the buffer.
+
+ //Servermessage
+ void parseServermessage();
+ //single user data
+ void parseData();
+ //string (character data)
+ void parseMessage();
+ //init data which sets the start position etc of all characters.
+ void parseLobbyInitData();
+ void parseGameInitData();
+ void parseRenderData();
+
+ bool startReceiveThread();
+ bool startSendDataThread();
+ void setSendDelay(int ms){sendDelayMS=ms;}
+
+ //virtual functions
+ virtual void receiveGameInitData(char*)=0;
+ virtual void receiveLobbyInitData(char*, int)=0;
+ virtual void receivePlayerUpdate(char*, int)=0;
+ virtual void receiveRenderData(char*, int)=0;
+ virtual void receiveEffectData(char*, int)=0;
+ virtual void receiveConnStatus(ConnectionStatus)=0;
+ virtual void receiveEvent(char*)=0;
+};
\ No newline at end of file
diff --git a/Network/OysterNetworkServer/Game.cpp b/Network/OysterNetworkServer/Game.cpp
new file mode 100644
index 00000000..7948603d
--- /dev/null
+++ b/Network/OysterNetworkServer/Game.cpp
@@ -0,0 +1,113 @@
+#include "Game.h"
+Game::Game()
+{
+ playerCount=0;
+ started=false;
+ for (int i=0; i usr, int nrOfPlayers)
+{
+ /*for (int i=0; isetGame(2);
+ //init.players[i]=players[i];
+ }
+ return init;
+}
+void Game::addUser(int uid)
+{
+ userID[playerCount++]=uid;
+}
+bool Game::startGame()
+{
+ started=true;
+ return started;
+}
+void Game::update(float dt)
+{
+
+}
\ No newline at end of file
diff --git a/Network/OysterNetworkServer/Game.h b/Network/OysterNetworkServer/Game.h
new file mode 100644
index 00000000..d162a322
--- /dev/null
+++ b/Network/OysterNetworkServer/Game.h
@@ -0,0 +1,51 @@
+#pragma once
+#ifndef GAME_H
+#define GAME_H
+#include "User.h"
+#include "ServerInclude.h"
+const int MUTEX_COUNT =2;
+//Mutex #0=playerPos setGet
+//Mutex #1=
+
+//#include "Session.h"
+
+class Game
+{
+private:
+ bool started;
+ //ClientToServerUpdateData players[PLAYER_MAX_COUNT];
+ User* users[PLAYER_MAX_COUNT];
+ int userID[PLAYER_MAX_COUNT];
+ bool ready[PLAYER_MAX_COUNT];
+ int playerCount;
+
+ //Tracks which ship each user has
+ int shipID[PLAYER_MAX_COUNT];
+ HANDLE mutex[MUTEX_COUNT];
+ //::Game::Session *session;
+ int sessionID;
+public:
+ //Will reset all data
+ //playerIDs is an array of int which points toward each users connection.
+ void setReady(int pid, bool rdy){ready[pid]=rdy;}
+ bool allReady(){for (int i=0; i players, int nrOfPlayers);
+ GameInitData getInitData();
+ bool startGame();
+ bool isStarted(){return started;}
+ Game();
+ //Float4x4 getPlayerPos(int id);
+ //void setPlayerPos(int id, Float4x4 pos);
+ //bool checkMoveValidity(ClientToServerUpdateData plr);
+ //ClientToServerUpdateData getPlayerData(int id);
+ //void setPlayerData(int id, ClientToServerUpdateData ps);
+
+ int getPlayerCount() {return playerCount;}
+ int getUserID(int i) {return userID[i];}
+
+ void initLUA(char* file);
+ void update(float dt);
+ void addUser(int uid);
+ void removeUser(int uid){playerCount--;}
+};
+#endif
\ No newline at end of file
diff --git a/Network/OysterNetworkServer/Lobby.cpp b/Network/OysterNetworkServer/Lobby.cpp
new file mode 100644
index 00000000..ade4b120
--- /dev/null
+++ b/Network/OysterNetworkServer/Lobby.cpp
@@ -0,0 +1,73 @@
+#include "Lobby.h"
+
+Lobby::Lobby()
+{
+ timerStarted=false;
+ nrUsers=0;
+ timerMutex = CreateMutex(
+ NULL, // default security attributes
+ FALSE, // initially not owned
+ NULL); // unnamed mutex
+
+ if (timerMutex == NULL)
+ {
+ printf("CreateMutex error: %d\n", GetLastError());
+ }
+ for(int i=0; i0)
+ return timeLeft;
+ else
+ return 0;
+ }
+ ReleaseMutex(timerMutex);
+}
\ No newline at end of file
diff --git a/Network/OysterNetworkServer/Lobby.h b/Network/OysterNetworkServer/Lobby.h
new file mode 100644
index 00000000..a17e771c
--- /dev/null
+++ b/Network/OysterNetworkServer/Lobby.h
@@ -0,0 +1,27 @@
+#include "ServerInclude.h"
+#include "User.h"
+#ifndef LOBBY_H
+#define LOBBY_H
+class Lobby
+{
+private:
+ int nrUsers;
+ int userID[PLAYER_MAX_COUNT];
+ ServerTimer countdownTimer;
+ float countdownLimit;
+ LobbyUserStruct userData[PLAYER_MAX_COUNT];
+ bool timerStarted;
+ HANDLE timerMutex;
+public:
+ Lobby();
+ void addUser(User usr, int i);
+ int getUserID(int i) const {return userID[i];}
+ int getNrPlayers() const {return nrUsers;}
+ void removeUser();
+ void updateUserData(LobbyUserStruct);
+ LobbyInitData getLobbyInitData();
+ void startLobbyCountdown(float seconds);
+ float timeLeft();
+
+};
+#endif
\ No newline at end of file
diff --git a/Network/OysterNetworkServer/ServerDataHandler.cpp b/Network/OysterNetworkServer/ServerDataHandler.cpp
new file mode 100644
index 00000000..55c36a02
--- /dev/null
+++ b/Network/OysterNetworkServer/ServerDataHandler.cpp
@@ -0,0 +1,219 @@
+#include "SocketServer.h"
+
+
+
+void SocketServer::parseReceivedData(int threadID/*char* data, int size*/)
+{
+ bool test=false;
+ for(unsigned int i=0; isrcAddr);
+ data->buffer[data->dataSize]='\0';
+ usr.setUsername(data->buffer);
+ users.push_back(usr);
+ sendData(((int)users.size())-1, "\4connected",10);
+ std::string asd=users[users.size()-1].getUsername();
+ printf("Username:%s, IP:%s\n",users[users.size()-1].getUsername().c_str(), inet_ntoa(users[users.size()-1].getAddr().sin_addr));
+}
+void SocketServer::removeUser(int id)
+{
+ games[users[id].getGame()].removeUser(id);
+ users.erase(users.begin()+id);
+}
+void SocketServer::parseServercommand(int pid, int threadID)
+{
+ connData[threadID].buffer[connData[threadID].dataSize]='\0';
+ wprintf(L"User %d sent a server command.\n", pid);
+ printf("The command is the following:%s.\n", connData[threadID].buffer+1);
+ std::vector list=splitString(connData[threadID].buffer+1, ' ');
+ bool validcommand=false;
+ if(list.size()==0)
+ {
+ //Ignore case 1, to avoid vector subscript out of range errors
+ }
+ //First variable: Command
+ else if(!list[0].compare(" "))
+ {
+ //Add rest ignore cases here
+ }
+ else if(!list[0].compare("help"))
+ {
+ validcommand=true;
+ }
+ //else if(!list[0].compare("startgame"))
+ //{
+ //validcommand=true;
+ //Do more than just sending init data here
+ //sendInitData();
+ //}
+ else if (!list[0].compare("exit"))
+ {
+ validcommand=true;
+ //User #pid needs to be removed here, and data needs to be sorted accordingly.
+ }
+ else if (!list[0].compare("qst"))
+ {
+ validcommand=true;
+ if (users[pid].getState()==ONLINE)
+ {
+ sendData(pid, "\4qst",4);
+ users[pid].setState(ONLINE_QUEUEING);
+ }
+ }
+ else if (!list[0].compare("qed"))
+ {
+ validcommand=true;
+ if (users[pid].getState()==ONLINE_QUEUEING)
+ {
+ sendData(pid, "\4qed",4);
+ users[pid].setState(ONLINE);
+ }
+ }
+ else if (!list[0].compare("rdy"))
+ {
+ if (users[pid].getState()==ONLINE_INGAME)
+ {
+ games[users[pid].getGame()].setReady(pid, true);
+ }
+ }
+ else if (!list[0].compare("dc"))
+ {
+ validcommand=true;
+ printf("User %s (ID:%d) has disconnected.",users[pid].getUsername().c_str(), pid);
+ users[pid].setState(OFFLINE);
+ removeUser(pid);
+ //Tell games that he might be in here taht he's down
+ //users.erase(users.begin()
+ }
+ else if((!list[0].compare("w")||!list[0].compare("whisper")||!list[0].compare("msg")) && list.size()>2)
+ {
+ validcommand=true;
+ for(unsigned int i=0; i1)
+ {
+ users[pid].setUsername(list[1]);
+ //list[1]="\3Your username has been changed to "+list[1];
+ //sendData(pid,list[1].c_str(), list[1].length());
+ validcommand=true;
+ }
+ }
+ if(!validcommand)
+ {
+ int a=0;
+ //sendData(pid, "\3Invalid server command.", 24);
+ //Tell user that the server command was invalid
+ }
+}
+void SocketServer::parseData(int pid, int gid, int threadID)
+{
+ memcpy(&connData[threadID].tmpdata,connData[threadID].buffer+1,CLIENT_PLAYER_DATA_SIZE);
+ //No old packets
+ if (users[pid].getLastUpdate()accessPlayer(pid),connData[threadID].tmpdata);
+ }
+}
+void SocketServer::parseMessage(int pid, int threadID)
+{
+ std::string message;
+ message="\3[Chat] "+users[pid].getUsername()+": "+(connData[threadID].buffer+1);
+ sendData(-1,message.c_str(), (int)message.length());
+}
+void SocketServer::sendInitData(int gid)
+{
+ GameInitData init=games[gid].getInitData();
+ //int test=session->getNumPlayers(); // getNumPlayers is removed
+ for (int i=0; iaccessPlayer(i).getOrientation();
+ }
+ char* gd=new char[sizeof(init)+1];
+ gd[0]=2;
+ for (int i=0; i
+#define DEBUG_NEW new(_NORMAL_BLOCK ,__FILE__, __LINE__)
+#else
+#define DEBUG_NEW new
+#endif
+
+#include
+#include
+#include
+#include
+#include "OysterMath.h"
+#include "Session.h"
+#include "ServerTimer.h"
+using namespace Network;
+
+const float GAME_UPDATEDELAY=1.0f/120.0f;
diff --git a/Network/OysterNetworkServer/ServerMain.cpp b/Network/OysterNetworkServer/ServerMain.cpp
new file mode 100644
index 00000000..6c3d7f56
--- /dev/null
+++ b/Network/OysterNetworkServer/ServerMain.cpp
@@ -0,0 +1,47 @@
+#include
+#include "SocketServer.h"
+#include "ServerTimer.h"
+#include
+#include
+#include
+//#ifdef WINDOWS
+#include
+#include "ServerInclude.h"
+#define GetCurrentDir _getcwd
+//#else
+ //For other OS than windows; can't be found on
+ //all windows setups so it's commented for now
+ //#include
+ //#define GetCurrentDir getcwd
+ //#endif
+
+char* getCurDir()
+{
+ char* cCurrentPath;
+ cCurrentPath=new char[FILENAME_MAX];
+ int test=sizeof(cCurrentPath);
+ if (!GetCurrentDir(cCurrentPath, FILENAME_MAX))
+ {
+ return "ERROR";
+ }
+ cCurrentPath[FILENAME_MAX - 1] = '\0';
+ return cCurrentPath;
+}
+int main(int argc, char *argv[])
+{
+ srand((unsigned int)time(0));
+ ::Oyster::Game::MoveAble::setDiscreteTimeSlice( GAME_UPDATEDELAY );
+
+ SocketServer server;
+ server.loadMapList("..\\Content\\Maplist.txt");
+ while (!server.isReady());
+ server.startThreads();
+ GameLogic::Object::init("NOT_IMPLEMENTED");
+ server.startGameCreateLoop(50);
+ while(true)
+ {
+ server.updateServers();
+ }
+ server.closeConnection();
+ return 0;
+}
\ No newline at end of file
diff --git a/Network/OysterNetworkServer/ServerTCPSpecific.cpp b/Network/OysterNetworkServer/ServerTCPSpecific.cpp
new file mode 100644
index 00000000..eb6987c9
--- /dev/null
+++ b/Network/OysterNetworkServer/ServerTCPSpecific.cpp
@@ -0,0 +1,66 @@
+#include "SocketServer.h"
+bool SocketServer::initTCPSocket()
+{
+ //----------------------
+ // Create a SOCKET for listening for incoming connection requests.
+ TCPSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (TCPSocket == INVALID_SOCKET) {
+ wprintf(L"TCP socket function failed with error: %ld\n", WSAGetLastError());
+ WSACleanup();
+ return false;
+ }
+
+ iResult = bind(TCPSocket, (SOCKADDR *) & TCPRecvAddr, addrSize);
+ if (iResult == SOCKET_ERROR) {
+ wprintf(L"TCP bind function failed with error %d\n", WSAGetLastError());
+ iResult = closesocket(TCPSocket);
+ if (iResult == SOCKET_ERROR)
+ wprintf(L"TCP closesocket function failed with error %d\n", WSAGetLastError());
+ WSACleanup();
+ return false;
+ }
+ return true;
+}
+DWORD SocketServer::activateTCPConnectLoop(ThreadArguments* tra)
+{
+ while (true)
+ {
+ (tra->ptr)->receiveConnection(tra->threadID);
+ }
+}
+void SocketServer::receiveConnection(int threadID)
+{
+ User tmp;
+ //----------------------
+ // Listen for incoming connection requests
+ // on the created socket
+ if (listen(TCPSocket, SOMAXCONN) == SOCKET_ERROR)
+ {
+ wprintf(L"listen function failed with error: %d\n", WSAGetLastError());
+ return;
+ }
+
+ printf("Starting TCP connection loop.\n");
+ int a=0;
+ while(a==0)
+ {
+ a=1;
+ tmp.connection=accept(TCPSocket, (struct sockaddr*)&TCPRecvAddr, &addrSize);
+ printf("Accepted a TCP connection from IP %s.\n", inet_ntoa(TCPRecvAddr.sin_addr));
+ tcpData[threadID].dataSize=recv(
+ tmp.connection,
+ tcpData[threadID].buffer,
+ tcpData[threadID].bufLen,
+ 0);
+ connData[threadID].buffer[connData[threadID].dataSize]='\0';
+ tmp.setUsername(tcpData[threadID].buffer);
+ if (tcpData[threadID].dataSize == SOCKET_ERROR)
+ {
+ wprintf(L"TCP recv failed with error %d\n", WSAGetLastError());
+ }
+ printf("TCP Thread #%d received connData from %s\n", threadID, inet_ntoa(tcpData[threadID].srcAddr.sin_addr));
+ //connData[threadID].buffer[connData[threadID].dataSize]='\0';
+ //AddUser(&tcpData[threadID]);
+ //parseReceivedData(threadID);
+ }
+}
\ No newline at end of file
diff --git a/Network/OysterNetworkServer/ServerTimer.cpp b/Network/OysterNetworkServer/ServerTimer.cpp
new file mode 100644
index 00000000..4dc3d286
--- /dev/null
+++ b/Network/OysterNetworkServer/ServerTimer.cpp
@@ -0,0 +1,85 @@
+#include "ServerTimer.h"
+ServerTimer::ServerTimer()
+ :
+ c_SecondsPerCount(0.0),
+ c_DeltaTime(-1.0),
+ c_BaseTime(0),
+ c_PausedTime(0),
+ c_PrevTime(0),
+ c_CurrTime(0),
+ c_Stopped(false)
+{
+ __int64 countsPerSec;
+ QueryPerformanceFrequency((LARGE_INTEGER*)&countsPerSec);
+ c_SecondsPerCount =1.0 / (double)countsPerSec;
+
+ QueryPerformanceCounter((LARGE_INTEGER*)&c_PrevTime);
+}
+
+void ServerTimer::start()
+{
+ __int64 p_StartTime;
+ QueryPerformanceCounter((LARGE_INTEGER*)&p_StartTime);
+ if(c_Stopped)
+ {
+ c_PausedTime += (p_StartTime-c_StopTime);
+ c_PrevTime = p_StartTime;
+ c_StopTime = 0;
+ c_Stopped = false;
+ }
+}
+__int64 ServerTimer::getTime()
+{
+ __int64 testInt;
+ return QueryPerformanceCounter((LARGE_INTEGER*)&testInt);
+ return testInt;
+}
+
+void ServerTimer::stop()
+{
+ if(!c_Stopped)
+ {
+ __int64 p_CurrTime;
+ QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
+ c_StopTime = p_CurrTime;
+ c_Stopped = true;
+ }
+}
+void ServerTimer::reset()
+{
+ __int64 p_CurrTime;
+ QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
+ c_BaseTime = p_CurrTime;
+ c_PrevTime = p_CurrTime;
+ c_StopTime = 0;
+ c_Stopped = false;
+}
+void ServerTimer::tick()
+{
+ if (c_Stopped)
+ {
+ c_DeltaTime= 0.0;
+ return;
+ }
+ __int64 p_CurrTime;
+ QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
+ c_CurrTime=p_CurrTime;
+
+ c_DeltaTime=(c_CurrTime-c_PrevTime)*c_SecondsPerCount;
+ c_PrevTime=c_CurrTime;
+ if(c_DeltaTime<0.0) c_DeltaTime=0.0;
+}
+float ServerTimer::getGameTime() const
+{
+ if(c_Stopped)
+ {
+ return (float)((c_StopTime-c_BaseTime)*c_SecondsPerCount);
+ } else
+ {
+ return (float)(((c_CurrTime-c_PausedTime)-c_BaseTime)*c_SecondsPerCount);
+ }
+}
+float ServerTimer::getDeltaTime() const
+{
+ return (float)c_DeltaTime;
+}
\ No newline at end of file
diff --git a/Network/OysterNetworkServer/ServerTimer.h b/Network/OysterNetworkServer/ServerTimer.h
new file mode 100644
index 00000000..660c1799
--- /dev/null
+++ b/Network/OysterNetworkServer/ServerTimer.h
@@ -0,0 +1,25 @@
+#include "ServerInclude.h"
+#ifndef _GAME_TIMER_H
+#define _GAME_TIMER_H
+class ServerTimer
+{
+private:
+ double c_SecondsPerCount;
+ double c_DeltaTime;
+ __int64 c_BaseTime;
+ __int64 c_PausedTime;
+ __int64 c_StopTime;
+ __int64 c_PrevTime;
+ __int64 c_CurrTime;
+ bool c_Stopped;
+public:
+ ServerTimer();
+ __int64 getTime();
+ void start();
+ void stop();
+ void reset();
+ void tick();
+ float getGameTime() const;
+ float getDeltaTime() const;
+};
+#endif
\ No newline at end of file
diff --git a/Network/OysterNetworkServer/ServerUDPSpecific.cpp b/Network/OysterNetworkServer/ServerUDPSpecific.cpp
new file mode 100644
index 00000000..1ffdf624
--- /dev/null
+++ b/Network/OysterNetworkServer/ServerUDPSpecific.cpp
@@ -0,0 +1,55 @@
+#include "SocketServer.h"
+bool SocketServer::initUDPSocket()
+{
+ //---------------------------------------------
+ // Create a socket for sending data
+ UDPSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (UDPSocket == INVALID_SOCKET) {
+ wprintf(L"UDP socket failed with error: %ld\n", WSAGetLastError());
+ WSACleanup();
+ return false;
+ }
+ //---------------------------------------------
+ // Bind socket to IP
+ iResult = bind(UDPSocket, (SOCKADDR *) & UDPRecvAddr, addrSize);
+ if (iResult == SOCKET_ERROR) {
+ wprintf(L"UDP bind failed with error: %d\n", WSAGetLastError());
+ closesocket(UDPSocket);
+ WSACleanup();
+ return false;
+ }
+ return true;
+}
+DWORD SocketServer::activateUDPReceiveLoop(ThreadArguments* tra)
+{
+ (tra->ptr)->serverUDPReceiveLoopActive=true;//weird crash //PAR
+ (tra->ptr)->receiveDataUDP(tra->threadID);
+ return 0;
+}
+void SocketServer::stopUDPReceiveLoops()
+{
+ serverUDPReceiveLoopActive=false;
+ WaitForMultipleObjects(NR_CONNECTTHREADS, udpDataHandle, true, INFINITE);
+ printf("All UDP data recv threads stopped.\n");
+}
+void SocketServer::receiveDataUDP(int threadID)
+{
+ while(serverUDPReceiveLoopActive)
+ {
+ connData[threadID].dataSize=recvfrom(
+ UDPSocket,
+ connData[threadID].buffer,
+ connData[threadID].bufLen,
+ 0,
+ (SOCKADDR *)&connData[threadID].srcAddr,
+ &addrSize);
+ if (connData[threadID].dataSize == SOCKET_ERROR)
+ {
+ wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
+ }
+ //printf("Thread #%d received data from %s\n", threadID, inet_ntoa(connData[threadID].srcAddr.sin_addr));
+ //connData[threadID].buffer[connData[threadID].dataSize]='\0';
+ else
+ parseReceivedData(threadID);
+ }
+}
\ No newline at end of file
diff --git a/Network/OysterNetworkServer/Servercore.cpp b/Network/OysterNetworkServer/Servercore.cpp
new file mode 100644
index 00000000..6dd855fd
--- /dev/null
+++ b/Network/OysterNetworkServer/Servercore.cpp
@@ -0,0 +1,420 @@
+#include "SocketServer.h"
+#include
+bool SocketServer::loadMapList(char* maploc)
+{
+ ::std::string workDir;
+ ::Utility::String::extractDirPath( workDir, maploc, '\\' );
+
+ //maploc is the filename of the list which contains all maps
+ //load all map file names into the server, but don't load the maps themselves.
+ std::ifstream file;
+ file.open(maploc);
+ if (!file.is_open())
+ return false;
+ ::std::string str;
+ while(!file.eof())
+ {
+ ::std::getline( file, str );
+ maps.push_back( workDir + str );
+ }
+
+ /*
+ maps.push_back("map1test.map");
+ maps.push_back("map2 test.map");
+ */
+ return true;
+}
+bool SocketServer::LoadInitData(char* maploc)
+{
+ std::vector cont;
+ char* in=new char[100];
+ std::ifstream ifs;
+ ifs.open(maploc);
+ if(!ifs.is_open())
+ {
+ return false;
+ }
+ while(!ifs.eof())
+ {
+ ifs.getline(in, 100);
+ cont=splitString(in, '=');
+ if (cont.size()==2)
+ {
+ if(!strcmp("nr_players_per_session", cont[0].c_str()))
+ {
+ playersPerSessionCount=atoi(cont[1].c_str());
+ }
+ else if(!strcmp("nr_kills_to_win", cont[0].c_str()))
+ {
+ killsRequiredPerSession=atoi(cont[1].c_str());
+ }
+ else if(!strcmp("match_type", cont[0].c_str()))
+ {
+ //Isn't used
+ }
+ }
+
+ }
+ ifs.close();
+}
+SocketServer::~SocketServer()
+{
+ serverTCPConnectionLoopActive=false;
+ serverUDPReceiveLoopActive=false;
+ serverTCPReceiveLoopActive=false;
+ for (int i=0; iptr)->serverGameCreationLoop(tra->threadID);
+ return 0;
+}
+bool SocketServer::serverGameCreationLoop(int delay)
+{ // TODO: Mem access Violoation Crash 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ... delay = -858993460
+ //Mem access violation in a thread can also be caused by failure from something else instead of it,
+ //it still breaks at header even if, for example, server->load or lobby.startLobbyCountdown breaks it
+ //If you get an error here, make sure that isn't the problem.
+ int count;
+ while(serverGameCreationActive)
+ {
+ if (nrActiveSessions==0)
+ {
+ count=0;
+ for (unsigned int i=0; i=playersPerSessionCount)
+ {
+ games.resize(1);
+ //lobby.resize(games.size()+1);
+ session =new GameLogic::Session();
+ lobby = Lobby();
+ timer.resize(1);
+ timeTillUpdate.resize(1);
+ timeTillUpdate[0]=GAME_UPDATEDELAY;
+ updateCount.resize(1);
+ updateCount[0]=0;
+ int curID=(int)games.size()-1;
+ int mapid=rand()%maps.size();
+ session->setNrPlayers(playersPerSessionCount);
+ session->setKillsRequired(killsRequiredPerSession);
+ session->load(maps[mapid]);
+ printf("Map nr %d loaded, name %s.\n",mapid, maps[mapid].c_str());
+ count=0;
+ for (unsigned int i=0; countaccessPlayer(i).spawn();
+ count++;
+ }
+ }
+ lobbyActive=true;
+ sendLobbyInitData(curID);
+ lobby.startLobbyCountdown(LOBBY_WAIT_TIME);
+ sendRenderData(curID);
+ //return true;
+ }
+ if(lobbyActive)
+ {
+ for (int i=0; i<1; i++)
+ {
+ float ttimer=lobby.timeLeft();
+ if (ttimer==0)
+ {
+ printf("Starting game.\n");
+ games[i].initGame(users,playersPerSessionCount);
+ sendInitData(i);
+ nrActiveSessions++;
+ lobbyActive=false;
+ //serverGameCreationActive=false;
+ }
+ }
+ }
+ }
+ Sleep(delay);
+ }
+ printf("Maximum server count reached, shutting down the sever creation thread.\n");
+ return false;
+}
+SocketServer::SocketServer()
+{
+ UDPSocket = INVALID_SOCKET;
+ nrActiveSessions=0;
+ serverGameCreationActive=false;
+ serverTCPConnectionLoopActive=false;
+ serverTCPReceiveLoopActive=false;
+ serverUDPReceiveLoopActive=false;
+ killsRequiredPerSession=10;
+ playersPerSessionCount=1;
+ LoadInitData("../ServerData.dat");
+ //---------------------------------------------
+ // Set up the port and IP of the server
+ //Port starts up as a different one from when UDPSocketected, it changes once the server has exchanged some info with the client
+ UDPRecvAddr.sin_family = AF_INET;
+ UDPRecvAddr.sin_port = htons(UDPRecvPort);
+ UDPRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ sessionEvents=std::vector(0);
+ sessionEffects=std::vector(0);
+ TCPRecvAddr.sin_family = AF_INET;
+ TCPRecvAddr.sin_port = htons(TCPRecvPort);
+ TCPRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ addrSize=sizeof(sockaddr_in);
+ for (int i=0; i=users.size())
+ {
+ //User doesn't exist
+ printf("UDP sendData(%d) sendto failed because the specified user does not exist\n", uid);
+ }
+ else
+ {
+ iResult = sendto(UDPSocket, data, size, 0, (SOCKADDR *) & users[uid].getAddr(), addrSize);
+ if (iResult == SOCKET_ERROR)
+ {
+ wprintf(L"UDP sendData(%d) sendto failed with error: %d\n", uid, WSAGetLastError());
+ closesocket(UDPSocket);
+ WSACleanup();
+ return false;
+ }
+ }
+ }
+ return true;
+}
+bool SocketServer::sendKeyFrameData(int size, const char* data)
+{
+ for (int i=0; i
+#include
+namespace Benchmark
+{
+ struct
+ {
+ double averageTime, totalTime, minTime, maxTime; unsigned int numSamples;
+ } timerData[10] = { 0.0f, 0.0f, ::std::numeric_limits::max(), -::std::numeric_limits::max(), 0 };
+
+ void sampleTime( const ::Utility::WinTimer &timer, unsigned char ref )
+ {
+ double elapsedTime = timer.getElapsedSeconds();
+ timerData[ref].totalTime += elapsedTime;
+ timerData[ref].minTime = ::Utility::Value::min( timerData[ref].minTime, elapsedTime );
+ timerData[ref].maxTime = ::Utility::Value::max( timerData[ref].maxTime, elapsedTime );
+ ++timerData[ref].numSamples;
+ timerData[ref].averageTime = timerData[ref].totalTime / (double) timerData[ref].numSamples;
+ }
+
+ void print( )
+ {
+ ::std::ofstream file;
+ file.open( "BenchMarkData.txt", ::std::ios_base::app | ::std::ios_base::out );
+
+ if( file.is_open() )
+ {
+ file << "minTime\t\t: maxTime\t: averageTime\t\ttotalTime\tnumSamples\n";
+ for( unsigned char i = 0; i < 1; ++i )
+ file << timerData[i].minTime << (timerData[i].minTime == 0.0f ? "\t\t: " : "\t: ") << timerData[i].maxTime << "\t: " << timerData[i].averageTime << "\t\t" << timerData[i].totalTime << '\t' << timerData[i].numSamples <<'\n';
+ file << ::std::endl;
+ file.close();
+ ::std::cout << "Benchmark data saved." << ::std::endl;
+ }
+ }
+}
+// END BENCHMARK BLOCK/**/
+
+void SocketServer::updateServers()
+{
+ for(int i=0; iupdate( timer[i].getDeltaTime() ) )
+ {
+ case ::GameLogic::Session::Updated:
+ // BENCHMARK BLOCK
+ //processTimer.reset();
+ // END BENCHMARK BLOCK
+
+ processSessionPlayerData(i);
+ processAllSessionEvents(i);
+ processAllSessionEffects(i);
+
+ // BENCHMARK BLOCK
+ //Benchmark::sampleTime( processTimer, 0 );
+ // END BENCHMARK BLOCK
+
+ DEBUGCTR=0;
+ updateCount[i]++;
+ default:
+ break;
+ case ::GameLogic::Session::Over:
+ processAllSessionEvents(i);
+ nrActiveSessions=0;
+ if(users.size()==0)
+ {
+ printf("Game with id %d done, shutting down the game.\n", 0);
+ Sleep(10);
+
+ }
+ break;
+ }
+
+ // BENCHMARK BLOCK
+ //if( Benchmark::timerData[0].numSamples % 1000 == 1 )
+ // Benchmark::print();
+ // END BENCHMARK BLOCK
+ }
+ }
+ if(nrActiveSessions==0)
+ {
+ Sleep(50);
+ }
+}
+void SocketServer::processSessionPlayerData(int serverID)
+{
+ sendGameDataStruct.updateCount=updateCount[serverID];
+ int offset=1;
+ for (int i=0; iaccessPlayer(i).getOrientation();
+ sendGameDataStruct.hp=session->accessPlayer(i).getHullPoints();
+ sendGameDataStruct.shield=session->accessPlayer(i).getShieldPoints();
+ sendGameDataStruct.dirVecLen=session->accessPlayer(i).getMovement().length();
+ sendGameDataStruct.pid=i;
+ memcpy(sendGameDataBuffer+offset, &sendGameDataStruct, SERVER_PLAYER_DATA_SIZE);
+ offset+=SERVER_PLAYER_DATA_SIZE;
+ }
+ sendData(-1,sendGameDataBuffer, sendGameDataBufferSize);
+}
+void SocketServer::processAllSessionEvents(int serverID)
+{
+ session->fetchEvents(sessionEvents);
+ for (int i=0; i<(int)sessionEvents.size(); i++)
+ {
+ sendEventData(serverID, i);
+ delete sessionEvents[i];
+ }
+ sessionEvents.resize(0);
+}
+bool SocketServer::sendGameData(int serverID)
+{
+ //data[0]=1;
+ for (int i=0; iGetSize();
+ int size1=sizeof(Event::BulletCreated);
+ int tst=sizeof(Event::Type);
+ char* ed=new char[size+1+tst];
+ ed[0]=6;
+ sessionEvents[sid]->SaveRawData(ed+(1+tst));
+
+ Event::Type eTest=Event::getEventType(sessionEvents[sid]);
+ memcpy(ed+1, &eTest, sizeof(Event::Type));
+
+ sendData(-1, ed, size+1+tst);
+ delete ed;
+}
+void SocketServer::sendRenderData(int gid)
+{
+ Protocol::RenderData data;
+ session->writeToRenderResourceData(data);
+ int size=data.getRequiredBufferSize()+1;
+ char* sendChar=new char[size];
+ data.fillBuffer(sendChar+1);
+ sendChar[0]=8;
+ sendData(-1, sendChar, size);
+ delete sendChar;
+}
+void SocketServer::processAllSessionEffects(int gid)
+{
+ session->fetchEffectData(sessionEffects);
+
+ if (sessionEffects.size()>0)
+ {
+ int size=(int)sessionEffects.size()*sizeof(Network::EffectData) + 1;
+ delete sendEffectDataBuffer;
+ sendEffectDataBuffer=new char[size];
+ for (size_t i=0; i0)
+ p.thrustForward();
+ if(update.forward<0)
+ p.thrustBackward();
+
+ if(update.straferight>0)
+ p.strafeRight();
+ if(update.straferight<0)
+ p.strafeLeft();
+
+ if(update.strafeup>0)
+ p.climb();
+ if(update.strafeup<0)
+ p.dive();
+
+ if(update.roll>0)
+ {
+ ::Oyster::Math::Float baseAcceleration = p.rotationProperty.acceleration.roll;
+ p.rotationProperty.acceleration.roll /= ::Oyster::Game::MoveAble::getDiscreteTimeSlice();
+
+ p.rollLeft();
+ p.rotationProperty.acceleration.roll = baseAcceleration;
+ }
+ if(update.roll<0)
+ {
+ ::Oyster::Math::Float baseAcceleration = p.rotationProperty.acceleration.roll;
+ p.rotationProperty.acceleration.roll /= ::Oyster::Game::MoveAble::getDiscreteTimeSlice();
+ p.rollRight();
+ p.rotationProperty.acceleration.roll = baseAcceleration;
+ }
+ if(update.roll==0)
+ {
+ p.stopRotation();
+ }
+
+ if(update.TurnVer!=0.0f)
+ {
+ ::Oyster::Math::Float baseAcceleration = p.rotationProperty.acceleration.pitch;
+ p.rotationProperty.acceleration.pitch *= -update.TurnVer / ::Oyster::Game::MoveAble::getDiscreteTimeSlice();
+ p.pitchUp( );
+ p.disableRotationReduction();
+ p.rotationProperty.acceleration.pitch = baseAcceleration;
+ }
+
+ if(update.TurnHor!=0.0f)
+ {
+ ::Oyster::Math::Float baseAcceleration = p.rotationProperty.acceleration.yaw;
+ p.rotationProperty.acceleration.yaw *= -update.TurnHor / ::Oyster::Game::MoveAble::getDiscreteTimeSlice();
+ p.yawLeft( );
+ p.disableRotationReduction();
+ p.rotationProperty.acceleration.yaw = baseAcceleration;
+ }
+ if(update.firePrim)
+ p.firePrimaryWeapon();
+}
+
diff --git a/Network/OysterNetworkServer/SocketServer.h b/Network/OysterNetworkServer/SocketServer.h
new file mode 100644
index 00000000..28c19058
--- /dev/null
+++ b/Network/OysterNetworkServer/SocketServer.h
@@ -0,0 +1,126 @@
+#include "Game.h"
+#include "Lobby.h"
+void ControlPlayer( GameLogic::Player& p,const ClientToServerUpdateData &update);
+const int NR_CONNECTTHREADS=1;
+const int NR_SIMULTCPCONNECTS=1;
+//threads can only take 1 argument
+struct ThreadArguments;
+struct ConnThreadData
+{
+ sockaddr_in srcAddr;
+
+ ClientToServerUpdateData tmpdata;
+ char* buffer;
+ int bufLen;
+ int dataSize;
+};
+// Link with ws2_32.lib
+#pragma comment(lib, "Ws2_32.lib")
+const short TCPSendPort = 11111;
+const short TCPRecvPort = 11110;
+const short UDPSendPort = 11001;
+const short UDPRecvPort = 11000;
+
+class SocketServer
+{
+private:
+ bool serverGameCreationActive;
+ HANDLE gameCreateHandle;
+ bool serverTCPConnectionLoopActive;
+ bool serverUDPReceiveLoopActive;
+ bool serverTCPReceiveLoopActive;
+ bool setupStatus;
+ int iResult;
+ WSADATA wsaData;
+
+ SOCKET UDPSocket;
+ SOCKET TCPSocket;
+
+ sockaddr_in TCPRecvAddr;
+ sockaddr_in UDPRecvAddr;
+
+ int addrSize;
+
+ HANDLE tcpDataHandle[NR_SIMULTCPCONNECTS];
+ ConnThreadData tcpData[NR_SIMULTCPCONNECTS];
+
+ HANDLE udpDataHandle[NR_CONNECTTHREADS];
+ ConnThreadData connData[NR_CONNECTTHREADS];
+
+ int dataSize;
+
+
+ char* sendEffectDataBuffer;
+ char* sendGameDataBuffer;
+ int sendGameDataBufferSize;
+ ServerToClientUpdateData sendGameDataStruct;
+ std::vector users;
+ std::vector games;
+ Lobby lobby;
+ int nrActiveSessions;
+ std::vector sessionEvents;
+ std::vector sessionEffects;
+ GameLogic::Session* session;
+ std::vector timer;
+ int DEBUGCTR;
+ std::vector updateCount;
+ std::vector timeTillUpdate;
+ std::vector<::std::string> maps;
+ std::string text;
+ int playersPerSessionCount;
+ int killsRequiredPerSession;
+ bool lobbyActive;
+public:
+ virtual ~SocketServer();
+ //Debug force modify functions
+ void processAllSessionEvents(int serverID);
+ void processAllSessionEffects(int gid);
+ void processSessionPlayerData(int serverID);
+ //End of debug items
+ void updateServers();
+ SocketServer();
+ bool checkConnection(int userID);
+ bool initUDPSocket();
+ bool initTCPSocket();
+ //void firstTimeConnect();
+ bool loadMapList(char* map);
+ bool serverGameCreationLoop(int delay);
+ bool startThreads();
+ static DWORD activateUDPReceiveLoop(ThreadArguments* tra);
+ void stopUDPReceiveLoops();
+ //TCP functions
+ static DWORD activateTCPConnectLoop(ThreadArguments* tra);
+ void receiveConnection(int threadID);
+ //End of TCP functions
+ bool sendData(int uid, const char*, int);
+ bool sendGameData(int serverID);
+ bool sendKeyFrameData(int size, const char* data);
+ void sendInitData(int gid);
+ void sendRenderData(int gid);
+ void sendEventData(int gid, int size);
+ void sendLobbyInitData(int lid);
+ bool closeConnection();
+ void receiveDataUDP(int threadID);
+
+ static DWORD activateServerGameLoop(ThreadArguments* tra);
+ void startGameCreateLoop(int delay);
+ void stopGameCreateLoop();
+ void parseReceivedData(int threadID/*char*, int*/);//char and int required if i don't want to use the class buffer
+ void ParseReceivedData(ConnThreadData* data);
+
+ void parseServercommand(int pid, int threadID);
+ void parseData(int pid, int gid, int threadID);
+ void parseMessage(int pid, int threadID);
+
+ void addUser(int threadID);
+ void AddUser(ConnThreadData* data);
+ void removeUser(int id);
+
+ bool isReady() const {return setupStatus;}
+ bool LoadInitData(char* maploc);
+};
+struct ThreadArguments
+{
+ SocketServer* ptr;
+ int threadID;
+};
\ No newline at end of file
diff --git a/Network/OysterNetworkServer/User.cpp b/Network/OysterNetworkServer/User.cpp
new file mode 100644
index 00000000..5dcbdf8d
--- /dev/null
+++ b/Network/OysterNetworkServer/User.cpp
@@ -0,0 +1,50 @@
+#include "User.h"
+User::User(int i, sockaddr_in add, std::string usr)
+{
+ addr=add;
+ username=usr;
+ curGame=-1;
+ connection=NULL;
+ state=ONLINE;
+ lastUpdate=-1;
+ updMutex = CreateMutex(
+ NULL, // default security attributes
+ FALSE, // initially not owned
+ NULL); // unnamed mutex
+
+ if (updMutex == NULL)
+ {
+ printf("CreateMutex error: %d\n", GetLastError());
+ }
+}
+User::User()
+{
+ username="";
+ curGame=-1;
+ connection=NULL;
+ state=ONLINE;
+ lastUpdate=-1;
+ updMutex = CreateMutex(
+ NULL, // default security attributes
+ FALSE, // initially not owned
+ NULL); // unnamed mutex
+
+ if (updMutex == NULL)
+ {
+ printf("CreateMutex error: %d\n", GetLastError());
+ }
+ lastUpdateData.pid=-1;
+}
+void User::setLastUpdateData(Network::ClientToServerUpdateData data)
+{
+ WaitForSingleObject(updMutex, INFINITE);
+ lastUpdateData=data;
+ ReleaseMutex(updMutex);
+}
+Network::ClientToServerUpdateData User::getLastUpdateData()
+{
+ WaitForSingleObject(updMutex, INFINITE);
+ Network::ClientToServerUpdateData data=lastUpdateData;
+ ReleaseMutex(updMutex);
+ return data;
+}
\ No newline at end of file
diff --git a/Network/OysterNetworkServer/User.h b/Network/OysterNetworkServer/User.h
new file mode 100644
index 00000000..1a68b950
--- /dev/null
+++ b/Network/OysterNetworkServer/User.h
@@ -0,0 +1,42 @@
+#include "ServerInclude.h"
+#ifndef USER_H
+#define USER_H
+enum UserState
+{
+ OFFLINE,
+ OFFLINE_INGAME,
+ ONLINE,
+ ONLINE_QUEUEING,
+ ONLINE_INLOBBY,
+ ONLINE_INGAME
+};
+class User
+{
+private:
+ std::string username;
+ int curGame;
+ sockaddr_in addr;
+ UserState state;
+ long lastUpdate;
+ HANDLE updMutex;
+ Network::ClientToServerUpdateData lastUpdateData;
+public:
+ void setLastUpdateData(Network::ClientToServerUpdateData data);
+ Network::ClientToServerUpdateData getLastUpdateData();
+ void setLastUpdate(long upd){lastUpdate=upd;}
+ long getLastUpdate() {return lastUpdate;}
+ HANDLE threadHandle;
+ SOCKET connection;
+ User();
+ User(int id, sockaddr_in addr, std::string usr="Unknown");
+ //SOCKET getTCPSocket() const {return connection;}
+ sockaddr_in getAddr() const {return addr;}
+ std::string getUsername() const {return username;}
+ void setUsername(std::string usr){username=usr;}
+ void setState(UserState st){state=st;}
+ UserState getState(){return state;}
+ void setGame(int gid){curGame=gid;}
+ bool isIngame() {return state==ONLINE_INGAME;}
+ int getGame(){return curGame;}
+};
+#endif
\ No newline at end of file
diff --git a/OysterGraphics/Core/Buffer.cpp b/OysterGraphics/Core/Buffer.cpp
new file mode 100644
index 00000000..50759848
--- /dev/null
+++ b/OysterGraphics/Core/Buffer.cpp
@@ -0,0 +1,202 @@
+#include "Buffer.h"
+#include "Core.h"
+using namespace Oyster;
+
+Buffer::Buffer()
+{
+ mBuffer = NULL;
+}
+
+Buffer::~Buffer()
+{
+ SAFE_RELEASE(mBuffer);
+}
+
+HRESULT Buffer::Apply(UINT32 misc) const
+{
+ HRESULT hr = S_OK;
+
+ switch(mType)
+ {
+ case VERTEX_BUFFER:
+ {
+ UINT32 vertexSize = mElementSize;
+ UINT32 offset = 0;
+ Oyster::Core::DeviceContext->IASetVertexBuffers(misc, 1, &mBuffer, &vertexSize, &offset );
+ }
+ break;
+ case INDEX_BUFFER:
+ {
+ Oyster::Core::DeviceContext->IASetIndexBuffer(mBuffer, DXGI_FORMAT_R32_UINT, 0);
+ }
+ break;
+ case CONSTANT_BUFFER_VS:
+ {
+ Oyster::Core::DeviceContext->VSSetConstantBuffers(misc, 1, &mBuffer);
+ }
+ break;
+ case CONSTANT_BUFFER_GS:
+ {
+ Oyster::Core::DeviceContext->GSSetConstantBuffers(misc, 1, &mBuffer);
+ }
+ break;
+ case CONSTANT_BUFFER_PS:
+ {
+ Oyster::Core::DeviceContext->PSSetConstantBuffers(misc, 1, &mBuffer);
+ }
+ break;
+ case CONSTANT_BUFFER_CS:
+ {
+ Oyster::Core::DeviceContext->CSSetConstantBuffers(misc,1,&mBuffer);
+ }
+ break;
+ default:
+ hr = E_FAIL;
+ break;
+ };
+
+ return hr;
+}
+
+HRESULT Buffer::Init(const BUFFER_INIT_DESC& initDesc)
+{
+ D3D11_BUFFER_DESC bufferDesc;
+
+ mType = initDesc.Type;
+ switch(mType)
+ {
+ case VERTEX_BUFFER:
+ {
+ bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+
+ if(initDesc.Usage == BUFFER_STREAM_OUT_TARGET)
+ bufferDesc.BindFlags |= D3D11_BIND_STREAM_OUTPUT;
+ }
+ break;
+ case INDEX_BUFFER:
+ {
+ bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
+ }
+ break;
+ case STRUCTURED_BUFFER:
+ {
+ bufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+ }
+ break;
+ case CONSTANT_BUFFER_CS:
+ case CONSTANT_BUFFER_VS:
+ case CONSTANT_BUFFER_GS:
+ case CONSTANT_BUFFER_PS:
+ {
+ bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ }
+ break;
+ default:
+ return E_FAIL;
+ break;
+ };
+
+ mUsage = initDesc.Usage;
+ mElementSize = initDesc.ElementSize;
+ mElementCount = initDesc.NumElements;
+
+ bufferDesc.CPUAccessFlags = 0;
+ bufferDesc.Usage = D3D11_USAGE_DEFAULT;
+
+ if(mUsage == BUFFER_CPU_READ)
+ {
+ bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+ bufferDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_READ;
+ }
+ else if(mUsage == BUFFER_CPU_WRITE)
+ {
+ bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+ bufferDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE;
+ }
+ else if(mUsage == BUFFER_CPU_WRITE_DISCARD)
+ {
+ bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+ bufferDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE;
+ }
+
+ //Desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.ByteWidth = initDesc.NumElements * initDesc.ElementSize;
+ bufferDesc.StructureByteStride=0;
+ if(mType== STRUCTURED_BUFFER)
+ {
+ bufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
+ bufferDesc.StructureByteStride=initDesc.ElementSize;
+ }
+ //set at least 16 bytes
+ if(bufferDesc.ByteWidth < 16)
+ bufferDesc.ByteWidth = 16;
+
+ HRESULT hr = S_OK;
+ if(initDesc.InitData)
+ {
+ D3D11_SUBRESOURCE_DATA data;
+ data.pSysMem = initDesc.InitData;
+ data.SysMemPitch=0;
+ data.SysMemSlicePitch = 0;
+ hr = Oyster::Core::Device->CreateBuffer(&bufferDesc, &data, &mBuffer);
+ }
+ else
+ {
+ hr = Oyster::Core::Device->CreateBuffer(&bufferDesc, NULL, &mBuffer);
+ }
+
+ if(FAILED(hr))
+ {
+ MessageBox(NULL, "Unable to create buffer.", "Slenda Error", MB_ICONERROR | MB_OK);
+ }
+
+ return hr;
+}
+
+void* Buffer::Map()
+{
+ void* ret = NULL;
+ if(mUsage == BUFFER_CPU_WRITE || mUsage == BUFFER_CPU_READ || mUsage == BUFFER_CPU_WRITE_DISCARD)
+ {
+ D3D11_MAPPED_SUBRESOURCE MappedResource;
+ UINT32 mapType = 0;
+
+ if(mUsage == BUFFER_CPU_READ) mapType = D3D11_MAP_READ;
+ else if(mUsage == BUFFER_CPU_WRITE) mapType = D3D11_MAP_WRITE;
+ else if(mUsage == BUFFER_CPU_WRITE_DISCARD) mapType = D3D11_MAP_WRITE_DISCARD;
+
+ HRESULT hr = S_OK;
+ if(FAILED(hr = Oyster::Core::DeviceContext->Map(
+ mBuffer,
+ 0,
+ (D3D11_MAP)mapType,
+ 0,
+ &MappedResource)))
+ {
+ ret = NULL;
+ }
+ else
+ {
+ ret = MappedResource.pData;
+ }
+ }
+
+ return ret;
+
+}
+
+void Buffer::Unmap()
+{
+ Oyster::Core::DeviceContext->Unmap( mBuffer, 0 );
+}
+
+Buffer::operator ID3D11Buffer *()
+{
+ return this->mBuffer;
+}
+
+Buffer::operator const ID3D11Buffer *() const
+{
+ return this->mBuffer;
+}
\ No newline at end of file
diff --git a/OysterGraphics/Core/Buffer.h b/OysterGraphics/Core/Buffer.h
new file mode 100644
index 00000000..712c7ac4
--- /dev/null
+++ b/OysterGraphics/Core/Buffer.h
@@ -0,0 +1,76 @@
+#pragma once
+#ifndef CoreBuffer
+#define CoreBuffer
+
+#include "Core.h"
+
+namespace Oyster
+{
+ class Buffer
+ {
+ public:
+ enum BUFFER_TYPE
+ {
+ VERTEX_BUFFER,
+ INDEX_BUFFER,
+ CONSTANT_BUFFER_VS,
+ CONSTANT_BUFFER_GS,
+ CONSTANT_BUFFER_PS,
+ CONSTANT_BUFFER_CS,
+ STRUCTURED_BUFFER,
+ BUFFER_TYPE_COUNT
+ };
+
+ enum BUFFER_USAGE
+ {
+ BUFFER_DEFAULT,
+ BUFFER_STREAM_OUT_TARGET,
+ BUFFER_CPU_WRITE,
+ BUFFER_CPU_WRITE_DISCARD,
+ BUFFER_CPU_READ,
+ BUFFER_USAGE_COUNT
+ };
+
+ struct BUFFER_INIT_DESC
+ {
+ BUFFER_TYPE Type;
+ UINT32 NumElements;
+ UINT32 ElementSize;
+ BUFFER_USAGE Usage;
+ void* InitData;
+
+ BUFFER_INIT_DESC()
+ {
+ InitData = NULL;
+ Usage = BUFFER_DEFAULT;
+ }
+ };
+ protected:
+ ID3D11Buffer* mBuffer;
+ BUFFER_TYPE mType;
+ BUFFER_USAGE mUsage;
+
+ UINT32 mElementSize;
+ UINT32 mElementCount;
+ public:
+ Buffer();
+ virtual ~Buffer();
+
+ HRESULT Init(const BUFFER_INIT_DESC& initDesc);
+
+ void* Map();
+ void Unmap();
+
+ operator ID3D11Buffer*();
+ operator const ID3D11Buffer*() const;
+
+ HRESULT Apply(UINT32 misc = 0) const;
+
+ ID3D11Buffer* GetBufferPointer();
+ UINT32 GetVertexSize();
+ UINT32 GetElementCount();
+ };
+
+}
+
+#endif
\ No newline at end of file
diff --git a/OysterGraphics/Core/Core.cpp b/OysterGraphics/Core/Core.cpp
new file mode 100644
index 00000000..feb7a65c
--- /dev/null
+++ b/OysterGraphics/Core/Core.cpp
@@ -0,0 +1,164 @@
+#include "Core.h"
+#include "..\Window\Window.h"
+
+using namespace Oyster;
+using std::string;
+
+//GPU
+ID3D11Device *Core::Device = NULL;
+
+//API
+ID3D11DeviceContext *Core::DeviceContext = NULL;
+
+//SwapChain
+IDXGISwapChain* Core::SwapChain = NULL;
+
+std::stringstream Log;
+
+inline std::stringstream* AccesLog(){return &Log;}
+
+bool Core::Init(bool SingleThreaded, bool Reference,bool ForceDX11)
+{
+ UINT createDeviceFlags = 0;
+
+ if( SingleThreaded )
+ createDeviceFlags = ::D3D11_CREATE_DEVICE_SINGLETHREADED;
+
+ ::D3D_DRIVER_TYPE driverType = ::D3D_DRIVER_TYPE_HARDWARE;
+
+ if(Reference)
+ driverType = D3D_DRIVER_TYPE_REFERENCE;
+
+ /*#if defined(DEBUG) || defined(_DEBUG)
+ Log << "DirectX running in debug mode.\n";
+ createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
+ #endif*/
+
+
+ D3D_FEATURE_LEVEL featureLevelsToTry[] =
+ {
+ D3D_FEATURE_LEVEL_11_0,
+ D3D_FEATURE_LEVEL_10_1,
+ D3D_FEATURE_LEVEL_10_0
+ };
+ D3D_FEATURE_LEVEL initiatedFeatureLevel;
+
+ if( FAILED( ::D3D11CreateDevice( NULL, // default adapter
+ driverType,
+ NULL, // no software device
+ createDeviceFlags,
+ featureLevelsToTry, 3, // default feature level array. DX11 support assumed
+ D3D11_SDK_VERSION,
+ &Device, // device
+ &initiatedFeatureLevel,
+ &DeviceContext ) ) ) // context
+ { // if failed
+ if( DeviceContext ) { DeviceContext->Release(); DeviceContext = NULL; } // safe cleanup
+ if( Device ) { Device->Release(); Device = NULL; } // safe cleanup
+ }
+
+ if( driverType == ::D3D_DRIVER_TYPE_HARDWARE )
+ Log << "D3D_DRIVER_TYPE_HARDWARE support discovered.\n";
+ else
+ Log << "D3D_DRIVER_TYPE_REFERENCE support discovered.\n";
+
+ if( initiatedFeatureLevel == ::D3D_FEATURE_LEVEL_11_0 )
+ {
+ Log << "DirectX Featurelevel 11.0 supported.\n";
+ }
+ else
+ {
+ if(ForceDX11)
+ return false;
+ if( initiatedFeatureLevel == ::D3D_FEATURE_LEVEL_10_1 )
+ {
+ Log << "DirectX Featurelevel 10.1 supported.\n";
+ }
+ else
+ {
+ if( initiatedFeatureLevel == ::D3D_FEATURE_LEVEL_10_0 )
+ {
+ Log << "DirectX Featurelevel 10.0 supported.\n";
+ }
+ }
+ }
+ if(Device)
+ return true;
+
+ return false;
+}
+
+bool Core::CreateSwapChain(HWND Window, int NrofBuffers,bool MSAA_Quality,bool Fullscreen)
+{
+ //generate static Swapchain Desc
+ DXGI_SWAP_CHAIN_DESC desc;
+ desc.OutputWindow=Window;
+ desc.BufferCount=NrofBuffers;
+ desc.Windowed=!Fullscreen;
+ desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_UNORDERED_ACCESS;
+ desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+ desc.Flags=0;
+ desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+ desc.BufferDesc.Scaling = DXGI_MODE_SCALING_CENTERED;
+ desc.BufferDesc.RefreshRate.Denominator=1;
+ desc.BufferDesc.RefreshRate.Numerator=60;
+ desc.BufferDesc.Height = Window::Size.bottom;
+ desc.BufferDesc.Width = Window::Size.left;
+
+ //Check and Set multiSampling
+ if(MSAA_Quality)
+ {
+ if(FAILED(Device->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM,4,&desc.SampleDesc.Quality)))
+ {
+ Log<< "Failed to check multisample quality levels (MSAAQuality).\n";
+ return false;
+ }
+ desc.SampleDesc.Count=4;
+ --desc.SampleDesc.Quality;
+ Log << "Supported multisample quality levels (MSAAQuality): " << desc.SampleDesc.Quality+1 << "x\n";
+ }
+ else
+ {
+ desc.SampleDesc.Count=1;
+ desc.SampleDesc.Quality=0;
+ }
+
+ //Get Device Factory
+ ::IDXGIDevice *dxgiDevice = NULL;
+ if( FAILED( Device->QueryInterface( __uuidof( IDXGIDevice ), (void**)&dxgiDevice ) ) )
+ {
+ Log << "Failed to Query for the GPU's dxgiDevice.\nFailed to create swapChain for the GPU.\n";
+ return false;
+ }
+
+ ::IDXGIAdapter *dxgiAdapter = NULL;
+ if( FAILED( dxgiDevice->GetParent( __uuidof( IDXGIAdapter ), (void**)&dxgiAdapter ) ) )
+ {
+ dxgiDevice->Release();
+ Log << "Failed to get GPU's parent dxgiAdapter.\nFailed to create swapChain for the GPU.\n";
+ return false;
+ }
+ dxgiDevice->Release();
+
+ ::IDXGIFactory *dxgiFactory = NULL;
+ if( FAILED( dxgiAdapter->GetParent( __uuidof( IDXGIFactory ), (void**)&dxgiFactory ) ) )
+ {
+ dxgiAdapter->Release();
+ Log << "Failed to get GPU's parent dxgiFactory.\nFailed to create swapChain for the GPU.\n";
+ return false;
+ }
+ dxgiAdapter->Release();
+
+ //Create SwapChain
+ if( FAILED( dxgiFactory->CreateSwapChain( Device, &desc, &SwapChain ) ) )
+ {
+ dxgiFactory->Release();
+ Log << "Failed to create swapChain for the GPU.\n";
+ return false;
+ }
+
+ dxgiFactory->Release();
+
+ return true;
+}
\ No newline at end of file
diff --git a/OysterGraphics/Core/Core.h b/OysterGraphics/Core/Core.h
new file mode 100644
index 00000000..7cca37fb
--- /dev/null
+++ b/OysterGraphics/Core/Core.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#ifndef Core_h
+#define Core_h
+
+
+#include "CoreIncludes.h"
+#include
+namespace Oyster
+{
+ class Core
+ {
+ public:
+
+ static ID3D11Device* Device;
+
+ static ID3D11DeviceContext* DeviceContext;
+
+ static IDXGISwapChain* SwapChain;
+
+ static std::stringstream* AccesLog();
+
+ static bool Init(bool SingleThreaded,bool Reference,bool ForceDX11);
+
+ static bool CreateSwapChain(HWND Window, int NrofBuffers,bool MSAA_Quality,bool Fullscreen);
+ };
+}
+
+
+#endif
\ No newline at end of file
diff --git a/OysterGraphics/Core/CoreIncludes.h b/OysterGraphics/Core/CoreIncludes.h
new file mode 100644
index 00000000..68a0c683
--- /dev/null
+++ b/OysterGraphics/Core/CoreIncludes.h
@@ -0,0 +1,40 @@
+#pragma once
+#ifndef CORE_INCLUDE
+#define CORE_INCLUDE
+
+#define NOMINMAX // Because I hate Microsoft now. ~Angry Dan.
+// http://lolengine.net/blog/2011/3/4/fuck-you-microsoft-near-far-macros
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include