diff options
author | Brad Davis <[email protected]> | 2013-07-03 09:16:03 -0700 |
---|---|---|
committer | Brad Davis <[email protected]> | 2013-07-03 09:16:03 -0700 |
commit | d46694c91c2bec4eb1e282c0c0101e6dab26e082 (patch) | |
tree | eb5fba71edf1aedc0d6af9406881004289433b20 /Samples/CommonSrc/Platform | |
parent | 7fa8be4bc565adc9911c95c814480cc48bf2d13c (diff) |
SDK 0.2.3
Diffstat (limited to 'Samples/CommonSrc/Platform')
18 files changed, 2971 insertions, 2190 deletions
diff --git a/Samples/CommonSrc/Platform/Gamepad.h b/Samples/CommonSrc/Platform/Gamepad.h index 01eaab4..f32effc 100644 --- a/Samples/CommonSrc/Platform/Gamepad.h +++ b/Samples/CommonSrc/Platform/Gamepad.h @@ -1,102 +1,102 @@ -/************************************************************************************
-
-Filename : Gamepad.h
-Content : Cross platform Gamepad interface.
-Created : May 6, 2013
-Authors : Lee Cooper
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-************************************************************************************/
-
-#ifndef OVR_Gamepad_h
-#define OVR_Gamepad_h
-
-#include "OVR.h"
-
-namespace OVR { namespace Platform {
-
-// Buttons on a typical gamepad controller.
-enum GamepadButtons
-{
- Gamepad_A = 0x1000,
- Gamepad_CROSS = 0x1000,
- Gamepad_B = 0x2000,
- Gamepad_CIRCLE = 0x2000,
- Gamepad_X = 0x4000,
- Gamepad_SQUARE = 0x4000,
- Gamepad_Y = 0x8000,
- Gamepad_TRIANGLE = 0x8000,
- Gamepad_Up = 0x0001,
- Gamepad_Down = 0x0002,
- Gamepad_Left = 0x0004,
- Gamepad_Right = 0x0008,
- Gamepad_Start = 0x0010,
- Gamepad_Back = 0x0020,
- Gamepad_LStick = 0x0040,
- Gamepad_RStick = 0x0080,
- Gamepad_L1 = 0x0100,
- Gamepad_R1 = 0x0200,
-};
-
-//-------------------------------------------------------------------------------------
-// ***** GamepadState
-
-// Describes the state of the controller buttons and analog inputs.
-struct GamepadState
-{
- UInt32 Buttons; // Bitfield representing button state.
- float LX; // Left stick X axis [-1,1]
- float LY; // Left stick Y axis [-1,1]
- float RX; // Right stick X axis [-1,1]
- float RY; // Right stick Y axis [-1,1]
- float LT; // Left trigger [0,1]
- float RT; // Right trigger [0,1]
-
- GamepadState() : Buttons(0), LX(0), LY(0), RX(0), RY(0), LT(0), RT(0) {}
-
- bool operator==(const GamepadState& b) const
- {
- return Buttons == b.Buttons && LX == b.LX && LY == b.LY && RX == b.RX && RY == b.RY && LT == b.LT && RT == b.RT;
- }
- bool operator!=(const GamepadState& b) const
- {
- return !(*this == b);
- }
- void Debug()
- {
- OVR_DEBUG_LOG(("Buttons:0x%4x LX:%.2f LY:%.2f RX:%.2f RY:%.2f LT:%.2f RT:%.2f", Buttons, LX, LY, RX, RY, LT, RT));
- }
-};
-
-//-------------------------------------------------------------------------------------
-// ***** GamepadManager
-
-// GamepadManager provides a cross platform interface for accessing gamepad controller
-// state.
-class GamepadManager : public RefCountBase<GamepadManager>
-{
-public:
-
- // Get the number of connected gamepads.
- virtual UInt32 GetGamepadCount() = 0;
-
- // Get the state of the gamepad with a given index.
- virtual bool GetGamepadState(UInt32 index, GamepadState* pState) = 0;
-};
-
-}} // OVR::Platform
-
-#endif // OVR_Gamepad_h
+/************************************************************************************ + +Filename : Gamepad.h +Content : Cross platform Gamepad interface. +Created : May 6, 2013 +Authors : Lee Cooper + +Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Gamepad_h +#define OVR_Gamepad_h + +#include <OVR.h> + +namespace OVR { namespace Platform { + +// Buttons on a typical gamepad controller. +enum GamepadButtons +{ + Gamepad_A = 0x1000, + Gamepad_CROSS = 0x1000, + Gamepad_B = 0x2000, + Gamepad_CIRCLE = 0x2000, + Gamepad_X = 0x4000, + Gamepad_SQUARE = 0x4000, + Gamepad_Y = 0x8000, + Gamepad_TRIANGLE = 0x8000, + Gamepad_Up = 0x0001, + Gamepad_Down = 0x0002, + Gamepad_Left = 0x0004, + Gamepad_Right = 0x0008, + Gamepad_Start = 0x0010, + Gamepad_Back = 0x0020, + Gamepad_LStick = 0x0040, + Gamepad_RStick = 0x0080, + Gamepad_L1 = 0x0100, + Gamepad_R1 = 0x0200, +}; + +//------------------------------------------------------------------------------------- +// ***** GamepadState + +// Describes the state of the controller buttons and analog inputs. +struct GamepadState +{ + UInt32 Buttons; // Bitfield representing button state. + float LX; // Left stick X axis [-1,1] + float LY; // Left stick Y axis [-1,1] + float RX; // Right stick X axis [-1,1] + float RY; // Right stick Y axis [-1,1] + float LT; // Left trigger [0,1] + float RT; // Right trigger [0,1] + + GamepadState() : Buttons(0), LX(0), LY(0), RX(0), RY(0), LT(0), RT(0) {} + + bool operator==(const GamepadState& b) const + { + return Buttons == b.Buttons && LX == b.LX && LY == b.LY && RX == b.RX && RY == b.RY && LT == b.LT && RT == b.RT; + } + bool operator!=(const GamepadState& b) const + { + return !(*this == b); + } + void Debug() + { + OVR_DEBUG_LOG(("Buttons:0x%4x LX:%.2f LY:%.2f RX:%.2f RY:%.2f LT:%.2f RT:%.2f", Buttons, LX, LY, RX, RY, LT, RT)); + } +}; + +//------------------------------------------------------------------------------------- +// ***** GamepadManager + +// GamepadManager provides a cross platform interface for accessing gamepad controller +// state. +class GamepadManager : public RefCountBase<GamepadManager> +{ +public: + + // Get the number of connected gamepads. + virtual UInt32 GetGamepadCount() = 0; + + // Get the state of the gamepad with a given index. + virtual bool GetGamepadState(UInt32 index, GamepadState* pState) = 0; +}; + +}} // OVR::Platform + +#endif // OVR_Gamepad_h diff --git a/Samples/CommonSrc/Platform/Linux_Gamepad.cpp b/Samples/CommonSrc/Platform/Linux_Gamepad.cpp new file mode 100644 index 0000000..9370120 --- /dev/null +++ b/Samples/CommonSrc/Platform/Linux_Gamepad.cpp @@ -0,0 +1,48 @@ +/************************************************************************************ + +Filename : Linux_Gamepad.cpp +Content : Linux implementation of Platform app infrastructure +Created : May 6, 2013 +Authors : Lee Cooper + +Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "Linux_Gamepad.h" + +namespace OVR { namespace Platform { namespace Linux { + +GamepadManager::GamepadManager() +{ + +} + +GamepadManager::~GamepadManager() +{ + +} + +UInt32 GamepadManager::GetGamepadCount() +{ + return 1; +} + +bool GamepadManager::GetGamepadState(UInt32 index, GamepadState* pState) +{ + return false; +} + +}}} // OVR::Platform::Linux diff --git a/Samples/CommonSrc/Platform/Linux_Gamepad.h b/Samples/CommonSrc/Platform/Linux_Gamepad.h new file mode 100644 index 0000000..9e6413d --- /dev/null +++ b/Samples/CommonSrc/Platform/Linux_Gamepad.h @@ -0,0 +1,51 @@ +/************************************************************************************ + +Filename : Linux_Gamepad.h +Content : Linux implementation of Gamepad functionality. +Created : May 6, 2013 +Authors : Lee Cooper + +Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Linux_Gamepad_h +#define OVR_Linux_Gamepad_h + +#include "Gamepad.h" + +namespace OVR { namespace Platform { namespace Linux { + +class GamepadManager : public Platform::GamepadManager +{ +public: + GamepadManager(); + ~GamepadManager(); + + virtual UInt32 GetGamepadCount(); + virtual bool GetGamepadState(UInt32 index, GamepadState* pState); + +private: + // Dynamically ink to XInput to simplify projects. + //HMODULE hXInputModule; + //typedef DWORD (WINAPI *PFn_XInputGetState)(DWORD dwUserIndex, XINPUT_STATE* pState); + //PFn_XInputGetState pXInputGetState; + + //UInt32 LastPadPacketNo; +}; + +}}} + +#endif // OVR_Linux_Gamepad_h diff --git a/Samples/CommonSrc/Platform/Linux_Platform.cpp b/Samples/CommonSrc/Platform/Linux_Platform.cpp new file mode 100644 index 0000000..c9d3e40 --- /dev/null +++ b/Samples/CommonSrc/Platform/Linux_Platform.cpp @@ -0,0 +1,563 @@ +/************************************************************************************ + +Filename : Platform_Linux.cpp +Content : Linux (X11) implementation of Platform app infrastructure +Created : September 6, 2012 +Authors : Andrew Reisse + +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. + +Use of this software is subject to the terms of the Oculus LLC license +agreement provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +************************************************************************************/ + +#include "Kernel/OVR_System.h" +#include "Kernel/OVR_Array.h" +#include "Kernel/OVR_String.h" +#include "Kernel/OVR_Timer.h" + +#include "Linux_Platform.h" +#include "Linux_Gamepad.h" + +// Renderers +#include "../Render/Render_GL_Device.h" + +#include <X11/extensions/Xinerama.h> + + +namespace OVR { namespace Platform { namespace Linux { + +static const char *AtomNames[] = {"WM_PROTOCOLS", "WM_DELETE_WINDOW"}; + +PlatformCore::PlatformCore(Application* app) + : Platform::PlatformCore(app), Disp(NULL), Win(0), Vis(NULL), Quit(0), MMode(Mouse_Normal) +{ + pGamepadManager = *new Linux::GamepadManager(); +} +PlatformCore::~PlatformCore() +{ + XFreeCursor(Disp, InvisibleCursor); + + if (Disp) + XCloseDisplay(Disp); +} + +// Setup an X11 window in windowed mode. +bool PlatformCore::SetupWindow(int w, int h) +{ + + if (!Disp) + { + XInitThreads(); + + Disp = XOpenDisplay(NULL); + if (!Disp) + { + OVR_DEBUG_LOG(("XOpenDisplay failed.")); + return false; + } + + XInternAtoms(Disp, const_cast<char**>(AtomNames), NumAtoms, false, Atoms); + } + + XSetWindowAttributes winattr; + unsigned attrmask = CWEventMask | CWBorderPixel; + + winattr.event_mask = ButtonPressMask|ButtonReleaseMask|KeyPressMask|KeyReleaseMask|ButtonMotionMask|PointerMotionMask| + /*PointerMotionHintMask|*/StructureNotifyMask;//|ExposureMask; + winattr.border_pixel = 0; + + int screenNumber = DefaultScreen(Disp); + + if (!Vis) + { + int attr[16]; + int nattr = 2; + + attr[0] = GLX_RGBA; + attr[1] = GLX_DOUBLEBUFFER; + attr[nattr++] = GLX_DEPTH_SIZE; + attr[nattr++] = 24; + attr[nattr] = 0; + + Vis = glXChooseVisual(Disp, screenNumber, attr); + + if (!Vis) + { + OVR_DEBUG_LOG(("glXChooseVisual failed.")); + return false; + } + } + + Window rootWindow = XRootWindow(Disp, Vis->screen); + + winattr.colormap = XCreateColormap(Disp, rootWindow, Vis->visual, AllocNone); + attrmask |= CWColormap; + + + Win = XCreateWindow(Disp, rootWindow, 0, 0, w, h, 0, Vis->depth, + InputOutput, Vis->visual, attrmask, &winattr); + + if (!Win) + { + OVR_DEBUG_LOG(("XCreateWindow failed.")); + return false; + } + + + XStoreName(Disp, Win, "OVR App"); + XSetWMProtocols(Disp, Win, &Atoms[WM_DELETE_WINDOW], 1); + + // Intialize empty cursor for show/hide. + XColor black; + static char noData[] = { 0,0,0,0,0,0,0,0 }; + black.red = black.green = black.blue = 0; + + Pixmap bitmapNoData = XCreateBitmapFromData(Disp, Win, noData, 8, 8); + InvisibleCursor = XCreatePixmapCursor(Disp, bitmapNoData, bitmapNoData, + &black, &black, 0, 0); + XDefineCursor(Disp, Win, InvisibleCursor); + + Width = w; + Height = h; + + return true; +} + +void PlatformCore::SetMouseMode(MouseMode mm) +{ + if (mm == MMode) + return; + + if (Win) + { + if (mm == Mouse_Relative) + { + XWarpPointer(Disp, Win, Win, 0,0,Width,Height, Width/2, Height/2); + } + else + { + //if (MMode == Mouse_Relative) + // ShowCursor(TRUE); + } + } + MMode = mm; +} + +void PlatformCore::GetWindowSize(int* w, int* h) const +{ + *w = Width; + *h = Height; +} + +void PlatformCore::SetWindowTitle(const char* title) +{ + XStoreName(Disp, Win, title); +} + +void PlatformCore::ShowWindow(bool show) +{ + if (show) + XRaiseWindow(Disp, Win); + else + XIconifyWindow(Disp, Win, 0); +} + +void PlatformCore::DestroyWindow() +{ + if (Win) + XDestroyWindow(Disp, Win); + Win = 0; +} + + +static int KeyMap[][2] = +{ + { XK_BackSpace, Key_Backspace }, + { XK_Tab, Key_Tab }, + { XK_Clear, Key_Clear }, + { XK_Return, Key_Return }, + { XK_Shift_L, Key_Shift }, + { XK_Control_L, Key_Control }, + { XK_Alt_L, Key_Alt }, + { XK_Shift_R, Key_Shift }, + { XK_Control_R, Key_Control }, + { XK_Alt_R, Key_Alt }, + { XK_Pause, Key_Pause }, + { XK_Caps_Lock, Key_CapsLock }, + { XK_Escape, Key_Escape }, + { XK_space, Key_Space }, + { XK_Page_Up, Key_PageUp }, + { XK_Page_Down, Key_PageDown }, + { XK_Prior, Key_PageUp }, + { XK_Next, Key_PageDown }, + { XK_End, Key_End }, + { XK_Home, Key_Home }, + { XK_Left, Key_Left }, + { XK_Up, Key_Up }, + { XK_Right, Key_Right }, + { XK_Down, Key_Down }, + { XK_Insert, Key_Insert }, + { XK_Delete, Key_Delete }, + { XK_Help, Key_Help }, + { XK_Num_Lock, Key_NumLock }, + { XK_Scroll_Lock, Key_ScrollLock }, +}; + + +static KeyCode MapXKToKeyCode(unsigned vk) +{ + unsigned key = Key_None; + + if ((vk >= 'a') && (vk <= 'z')) + { + key = vk - 'a' + Key_A; + } + else if ((vk >= ' ') && (vk <= '~')) + { + key = vk; + } + else if ((vk >= XK_KP_0) && (vk <= XK_KP_9)) + { + key = vk - XK_KP_0 + Key_KP_0; + } + else if ((vk >= XK_F1) && (vk <= XK_F15)) + { + key = vk - XK_F1 + Key_F1; + } + else + { + for (unsigned i = 0; i< (sizeof(KeyMap) / sizeof(KeyMap[1])); i++) + { + if (vk == KeyMap[i][0]) + { + key = KeyMap[i][1]; + break; + } + } + } + + return (KeyCode)key; +} + +static int MapModifiers(int xmod) +{ + int mod = 0; + if (xmod & ShiftMask) + mod |= Mod_Shift; + if (xmod & ControlMask) + mod |= Mod_Control; + if (xmod & Mod1Mask) + mod |= Mod_Alt; + if (xmod & Mod4Mask) + mod |= Mod_Meta; + return mod; +} + +void PlatformCore::processEvent(XEvent& event) +{ + switch (event.xany.type) + { + case ConfigureNotify: + if (event.xconfigure.width != Width || event.xconfigure.height != Height) + { + Width = event.xconfigure.width; + Height = event.xconfigure.height; + pApp->OnResize(Width, Height); + + if (pRender) + pRender->SetWindowSize(Width, Height); + } + break; + + case KeyPress: + case KeyRelease: + { + char chars[8] = {0}; + KeySym xk; + XComposeStatus comp; + XLookupString(&event.xkey, chars, sizeof(chars), &xk, &comp); + if (xk != XK_VoidSymbol) + pApp->OnKey(MapXKToKeyCode((unsigned)xk), chars[0], event.xany.type == KeyPress, MapModifiers(event.xkey.state)); + if (xk == XK_Escape && MMode == Mouse_Relative) + { + //ungrab + MMode = Mouse_RelativeEscaped; + showCursor(true); + } + } + break; + + case MotionNotify: + if (MMode == Mouse_Relative) + { + int dx = event.xmotion.x - Width/2; + int dy = event.xmotion.y - Height/2; + + // do not remove this check, WarpPointer generates events too. + if (dx == 0 && dy == 0) + break; + + XWarpPointer(Disp, Win, Win, 0,0,Width,Height, Width/2, Height/2); + pApp->OnMouseMove(dx, dy, Mod_MouseRelative|MapModifiers(event.xmotion.state)); + } + else + { + pApp->OnMouseMove(event.xmotion.x, event.xmotion.y, MapModifiers(event.xmotion.state)); + } + break; + + case MapNotify: + if (MMode == Mouse_Relative) + { + XWarpPointer(Disp, Win, Win, 0,0,Width,Height, Width/2, Height/2); + showCursor(false); + } + break; + + case ButtonPress: + if (event.xbutton.button == 1) + { + //grab + + if (MMode == Mouse_RelativeEscaped) + { + XWarpPointer(Disp, Win, Win, 0,0,Width,Height, Width/2, Height/2); + showCursor(false); + MMode = Mouse_Relative; + } + } + break; + + case FocusOut: + if (MMode == Mouse_Relative) + { + MMode = Mouse_RelativeEscaped; + showCursor(true); + } + break; + + case ClientMessage: + if (event.xclient.message_type == Atoms[WM_PROTOCOLS] && + Atom(event.xclient.data.l[0]) == Atoms[WM_DELETE_WINDOW]) + pApp->OnQuitRequest(); + break; + } +} + +int PlatformCore::Run() +{ + while (!Quit) + { + if (XPending(Disp)) + { + XEvent event; + XNextEvent(Disp, &event); + + if (pApp && event.xany.window == Win) + processEvent(event); + } + else + { + pApp->OnIdle(); + } + } + + return ExitCode; +} + +bool PlatformCore::determineScreenOffset(int screenId, int* screenOffsetX, int* screenOffsetY) +{ + Display* display = XOpenDisplay(NULL); + + bool foundScreen = false; + + if (display) + { + int numberOfScreens; + XineramaScreenInfo* screens = XineramaQueryScreens(display, &numberOfScreens); + + if (screenId < numberOfScreens) + { + XineramaScreenInfo screenInfo = screens[screenId]; + *screenOffsetX = screenInfo.x_org; + *screenOffsetY = screenInfo.y_org; + + foundScreen = true; + } + + XFree(screens); + } + + return foundScreen; +} + +void PlatformCore::showWindowDecorations(bool show) +{ + // Declaration of 'MOTIF_WM_HINTS' struct and flags can be found at: + // https://people.gnome.org/~tthurman/docs/metacity/xprops_8h-source.html + typedef struct WMHints + { + unsigned long flags; + unsigned long functions; + unsigned long decorations; + long inputMode; + unsigned long status; + } Hints; + + #define MWM_DECOR_ALL (1L << 0) + #define MWM_DECOR_BORDER (1L << 1) + #define MWM_DECOR_RESIZEH (1L << 2) + #define MWM_DECOR_TITLE (1L << 3) + #define MWM_DECOR_MENU (1L << 4) + #define MWM_DECOR_MINIMIZE (1L << 5) + #define MWM_DECOR_MAXIMIZE (1L << 6) + + Atom property = XInternAtom(Disp, "_MOTIF_WM_HINTS", true); + + Hints hints; + hints.flags = 2; // We only want to specify decoration. + + if (show) + { + hints.decorations = MWM_DECOR_BORDER | MWM_DECOR_TITLE | MWM_DECOR_MENU | MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE; + } + else + { + // Remove all window border items. + hints.decorations = 0; + } + + XChangeProperty(Disp,Win,property,property,32,PropModeReplace,(unsigned char *)&hints,5); +} + +bool PlatformCore::SetFullscreen(const Render::RendererParams& rp, int fullscreen) +{ + if (rp.Fullscreen == Render::Display_Window && fullscreen == Render::Display_FakeFullscreen) + { + // Transitioning from windowed to fake fullscreen. + int xOffset; + int yOffset; + + if (!determineScreenOffset(rp.Display.CgDisplayId, &xOffset, &yOffset)) + { + return false; + } + + showWindowDecorations(false); + + XMoveWindow(Disp, Win, xOffset, yOffset); + XMapRaised(Disp, Win); + + Platform::PlatformCore::SetFullscreen(rp, fullscreen); + return true; + } + else if (rp.Fullscreen == Render::Display_FakeFullscreen && fullscreen == Render::Display_Window) + { + // Transitioning from fake fullscreen to windowed. + showWindowDecorations(true); + + XMoveWindow(Disp, Win, 0, 0); + XMapRaised(Disp, Win); + + Platform::PlatformCore::SetFullscreen(rp, fullscreen); + return true; + } + else if (fullscreen == Render::Display_Fullscreen) + { + return false; + } +} + +RenderDevice* PlatformCore::SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc, + const char* type, const Render::RendererParams& rp) +{ + const SetupGraphicsDeviceSet* setupDesc = setupGraphicsDesc.PickSetupDevice(type); + OVR_ASSERT(setupDesc); + + pRender = *setupDesc->pCreateDevice(rp, this); + if (pRender) + pRender->SetWindowSize(Width, Height); + + return pRender.GetPtr(); +} + +void PlatformCore::showCursor(bool show) +{ + if (show) + { + XUndefineCursor(Disp, Win); + } + else + { + XDefineCursor(Disp, Win, InvisibleCursor); + } +} + +}} + +// GL +namespace Render { namespace GL { namespace Linux { + +Render::RenderDevice* RenderDevice::CreateDevice(const RendererParams& rp, void* oswnd) +{ + Platform::Linux::PlatformCore* PC = (Platform::Linux::PlatformCore*)oswnd; + + GLXContext context = glXCreateContext(PC->Disp, PC->Vis, 0, GL_TRUE); + + if (!context) + return NULL; + + if (!glXMakeCurrent(PC->Disp, PC->Win, context)) + { + glXDestroyContext(PC->Disp, context); + return NULL; + } + + XMapRaised(PC->Disp, PC->Win); + + return new Render::GL::Linux::RenderDevice(rp, PC->Disp, PC->Win, context); +} + +void RenderDevice::Present() +{ + glXSwapBuffers(Disp, Win); +} + +void RenderDevice::Shutdown() +{ + if (Context) + { + glXMakeCurrent(Disp, 0, NULL); + glXDestroyContext(Disp, Context); + Context = NULL; + Win = 0; + } +} + +}}}} + + +int main(int argc, const char* argv[]) +{ + using namespace OVR; + using namespace OVR::Platform; + + // CreateApplication must be the first call since it does OVR::System::Initialize. + Application* app = Application::CreateApplication(); + Linux::PlatformCore* platform = new Linux::PlatformCore(app); + // The platform attached to an app will be deleted by DestroyApplication. + app->SetPlatformCore(platform); + + int exitCode = app->OnStartup(argc, argv); + if (!exitCode) + exitCode = platform->Run(); + + // No OVR functions involving memory are allowed after this. + Application::DestroyApplication(app); + app = 0; + + return exitCode; +} diff --git a/Samples/CommonSrc/Platform/Linux_Platform.h b/Samples/CommonSrc/Platform/Linux_Platform.h new file mode 100644 index 0000000..7fbb220 --- /dev/null +++ b/Samples/CommonSrc/Platform/Linux_Platform.h @@ -0,0 +1,120 @@ +/************************************************************************************ + +Filename : Platform_Linux.h +Content : Linux (X11) implementation of Platform app infrastructure +Created : September 6, 2012 +Authors : Andrew Reisse + +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. + +Use of this software is subject to the terms of the Oculus LLC license +agreement provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +************************************************************************************/ + +#ifndef OVR_Platform_Linux_h +#define OVR_Platform_Linux_h + +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <GL/glx.h> + +#include "Platform.h" +#include "../Render/Render_GL_Device.h" + +namespace OVR { namespace Render { + class RenderDevice; +}} + +namespace OVR { namespace Platform { namespace Linux { + +class PlatformCore : public Platform::PlatformCore +{ +public: + Display* Disp; + XVisualInfo* Vis; + Window Win; + + bool Quit; + int ExitCode; + int Width, Height; + + MouseMode MMode; + Cursor InvisibleCursor; + + enum + { + WM_PROTOCOLS, + WM_DELETE_WINDOW, + NumAtoms + }; + Atom Atoms[NumAtoms]; + + void processEvent(XEvent& event); + + Render::RenderDevice* SetupGraphics_GL(const Render::RendererParams& rp); + + void showCursor(bool show); + bool determineScreenOffset(int screenId, int* screenOffsetX, int* screenOffsetY); + void showWindowDecorations(bool show); + +public: + PlatformCore(Application* app); + ~PlatformCore(); + + bool SetupWindow(int w, int h); + void Exit(int exitcode) { Quit = 1; ExitCode = exitcode; } + + RenderDevice* SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc, + const char* gtype, const Render::RendererParams& rp); + + void SetMouseMode(MouseMode mm); + void GetWindowSize(int* w, int* h) const; + + void SetWindowTitle(const char*title); + + void ShowWindow(bool show); + void DestroyWindow(); + bool SetFullscreen(const Render::RendererParams& rp, int fullscreen); + int Run(); +}; + +}} +namespace Render { namespace GL { namespace Linux { + +class RenderDevice : public Render::GL::RenderDevice +{ + Display* Disp; + Window Win; + GLXContext Context; + +public: + RenderDevice(const Render::RendererParams& p, Display* disp, Window w, GLXContext gl) + : GL::RenderDevice(p), Disp(disp), Win(w), Context(gl) {} + + virtual void Shutdown(); + virtual void Present(); + + // oswnd = Linux::PlatformCore* + static Render::RenderDevice* CreateDevice(const RendererParams& rp, void* oswnd); +}; + +}}}} + + +// OVR_PLATFORM_APP_ARGS specifies the Application class to use for startup, +// providing it with startup arguments. +#define OVR_PLATFORM_APP_ARGS(AppClass, args) \ + OVR::Platform::Application* OVR::Platform::Application::CreateApplication() \ + { OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All)); \ + return new AppClass args; } \ + void OVR::Platform::Application::DestroyApplication(OVR::Platform::Application* app) \ + { OVR::Platform::PlatformCore* platform = app->pPlatform; \ + delete app; delete platform; OVR::System::Destroy(); }; + +// OVR_PLATFORM_APP_ARGS specifies the Application startup class with no args. +#define OVR_PLATFORM_APP(AppClass) OVR_PLATFORM_APP_ARGS(AppClass, ()) + + +#endif diff --git a/Samples/CommonSrc/Platform/OSX_Gamepad.cpp b/Samples/CommonSrc/Platform/OSX_Gamepad.cpp index 3ac53ab..934319b 100644 --- a/Samples/CommonSrc/Platform/OSX_Gamepad.cpp +++ b/Samples/CommonSrc/Platform/OSX_Gamepad.cpp @@ -1,424 +1,424 @@ -/************************************************************************************
-
-Filename : OSX_Gamepad.cpp
-Content : OSX implementation of Gamepad functionality.
-Created : May 6, 2013
-Authors : Lee Cooper
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-************************************************************************************/
-
-#include "OSX_Gamepad.h"
-
-
-static const UInt32 Logitech_F710_VendorID = 0x046D;
-static const UInt32 Logitech_F710_ProductID = 0xC219;
-
-static const UInt32 Sony_DualShock3_VendorID = 0x054C;
-static const UInt32 Sony_DualShock3_ProductID = 0x0268;
-
-
-namespace OVR { namespace Platform { namespace OSX {
-
-
-GamepadManager::GamepadManager()
- : bStateChanged(false)
-{
-
- HidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
- IOHIDManagerOpen(HidManager, kIOHIDOptionsTypeNone);
- IOHIDManagerScheduleWithRunLoop(HidManager,
- CFRunLoopGetCurrent(),
- kCFRunLoopDefaultMode);
-
-
- // Setup device matching.
- CFStringRef keys[] = { CFSTR(kIOHIDDeviceUsagePageKey),
- CFSTR(kIOHIDDeviceUsageKey)};
-
- int value;
- CFNumberRef values[2];
- CFDictionaryRef dictionaries[2];
-
- // Match joysticks.
- value = kHIDPage_GenericDesktop;
- values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
-
- value = kHIDUsage_GD_Joystick;
- values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
-
- dictionaries[0] = CFDictionaryCreate(kCFAllocatorDefault,
- (const void **) keys,
- (const void **) values,
- 2,
- &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- CFRelease(values[0]);
- CFRelease(values[1]);
-
- // Match gamepads.
- value = kHIDPage_GenericDesktop;
- values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
-
- value = kHIDUsage_GD_GamePad;
- values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
-
- dictionaries[1] = CFDictionaryCreate(kCFAllocatorDefault,
- (const void **) keys,
- (const void **) values,
- 2,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- CFRelease(values[0]);
- CFRelease(values[1]);
-
- CFArrayRef array = CFArrayCreate( kCFAllocatorDefault,
- (const void **) dictionaries,
- 2,
- &kCFTypeArrayCallBacks);
- CFRelease(dictionaries[0]);
- CFRelease(dictionaries[1]);
-
- IOHIDManagerSetDeviceMatchingMultiple(HidManager, array);
-
- CFRelease(array);
-
-
- IOHIDManagerRegisterDeviceMatchingCallback(HidManager, staticOnDeviceMatched, this);
- IOHIDManagerRegisterDeviceRemovalCallback(HidManager, staticOnDeviceRemoved, this);
-
-}
-
-GamepadManager::~GamepadManager()
-{
- CFRelease(HidManager);
-}
-
-UInt32 GamepadManager::GetGamepadCount()
-{
- return 1;
-}
-
-bool GamepadManager::GetGamepadState(UInt32 index, GamepadState* pState)
-{
- // For now we just support one gamepad.
- OVR_UNUSED(index);
-
- if (!bStateChanged)
- {
- return false;
- }
-
- bStateChanged = false;
-// State.Debug();
-
- *pState = State;
- return true;
-}
-
-int GamepadManager::getIntDeviceProperty(IOHIDDeviceRef device, CFStringRef key)
-{
- CFTypeRef type = IOHIDDeviceGetProperty(device, key);
- OVR_ASSERT(type != NULL && CFGetTypeID(type) == CFNumberGetTypeID());
-
- int value;
- CFNumberGetValue((CFNumberRef) type, kCFNumberSInt32Type, &value);
-
- return value;
-}
-
-void GamepadManager::staticOnDeviceMatched(void* context, IOReturn result, void* sender, IOHIDDeviceRef device)
-{
- GamepadManager* pManager = (GamepadManager*) context;
- pManager->onDeviceMatched(device);
-}
-
-void GamepadManager::onDeviceMatched(IOHIDDeviceRef device)
-{
- IOHIDDeviceRegisterInputValueCallback(device, staticOnDeviceValueChanged, this);
-}
-
-void GamepadManager::staticOnDeviceRemoved(void* context, IOReturn result, void* sender, IOHIDDeviceRef device)
-{
- GamepadManager* pManager = (GamepadManager*) context;
- pManager->onDeviceRemoved(device);
-}
-
-void GamepadManager::onDeviceRemoved(IOHIDDeviceRef device)
-{
- IOHIDDeviceRegisterInputValueCallback(device, NULL, NULL);
-}
-
-void GamepadManager::staticOnDeviceValueChanged(void* context, IOReturn result, void* sender, IOHIDValueRef value)
-{
- GamepadManager* pManager = (GamepadManager*) context;
- pManager->onDeviceValueChanged(value);
-}
-
-float GamepadManager::mapAnalogAxis(IOHIDValueRef value, IOHIDElementRef element)
-{
-
- CFIndex val = IOHIDValueGetIntegerValue(value);
- CFIndex min = IOHIDElementGetLogicalMin(element);
- CFIndex max = IOHIDElementGetLogicalMax(element);
-
- float v = (float) (val - min) / (float) (max - min);
- v = v * 2.0f - 1.0f;
-
- // Dead zone.
- if (v < 0.1f && v > -0.1f)
- {
- v = 0.0f;
- }
-
- return v;
-}
-
-bool GamepadManager::setStateIfDifferent(float& state, float newState)
-{
- if (state == newState)
- return false;
-
- state = newState;
-
- return true;
-}
-
-void GamepadManager::onDeviceValueChanged(IOHIDValueRef value)
-{
-
- IOHIDElementRef element = IOHIDValueGetElement(value);
- IOHIDDeviceRef device = IOHIDElementGetDevice(element);
-
- int vendorID = getIntDeviceProperty(device, CFSTR(kIOHIDVendorIDKey));
- int productID = getIntDeviceProperty(device, CFSTR(kIOHIDProductIDKey));
- OVR_UNUSED(productID);
-
- uint32_t usagePage = IOHIDElementGetUsagePage(element);
- uint32_t usage = IOHIDElementGetUsage(element);
-
- // The following controller mapping is based on the Logitech F710, however we use it for
- // all Logitech devices on the assumption that they're likely to share the same mapping.
- if (vendorID == Logitech_F710_VendorID)
- {
- // Logitech F710 mapping.
- if (usagePage == kHIDPage_Button)
- {
- bool buttonState = IOHIDValueGetIntegerValue(value);
-
- switch(usage)
- {
- case kHIDUsage_Button_1:
- manipulateBitField(State.Buttons, Gamepad_X, buttonState);
- break;
- case kHIDUsage_Button_2:
- manipulateBitField(State.Buttons, Gamepad_A, buttonState);
- break;
- case kHIDUsage_Button_3:
- manipulateBitField(State.Buttons, Gamepad_B, buttonState);
- break;
- case kHIDUsage_Button_4:
- manipulateBitField(State.Buttons, Gamepad_Y, buttonState);
- break;
- case 0x05:
- manipulateBitField(State.Buttons, Gamepad_L1, buttonState);
- break;
- case 0x06:
- manipulateBitField(State.Buttons, Gamepad_R1, buttonState);
- break;
- case 0x07:
- State.LT = buttonState ? 1.0f:0.0f;
- break;
- case 0x08:
- State.RT = buttonState ? 1.0f:0.0f;
- break;
- case 0x09:
- manipulateBitField(State.Buttons, Gamepad_Back, buttonState);
- break;
- case 0x0A:
- manipulateBitField(State.Buttons, Gamepad_Start, buttonState);
- break;
- case 0x0B:
- manipulateBitField(State.Buttons, Gamepad_LStick, buttonState);
- break;
- case 0x0C:
- manipulateBitField(State.Buttons, Gamepad_RStick, buttonState);
- break;
- default:
- return;
- }
- }
- else if (usagePage == kHIDPage_GenericDesktop)
- {
- float v;
- switch(usage)
- {
- case kHIDUsage_GD_X:
- v = mapAnalogAxis(value, element);
- if (!setStateIfDifferent(State.LX, v))
- return;
- break;
- case kHIDUsage_GD_Y:
- v = mapAnalogAxis(value, element);
- if (!setStateIfDifferent(State.LY, -v))
- return;
- break;
- case kHIDUsage_GD_Z:
- v = mapAnalogAxis(value, element);
- if (!setStateIfDifferent(State.RX, v))
- return;
- break;
- case kHIDUsage_GD_Rz:
- v = mapAnalogAxis(value, element);
- if (!setStateIfDifferent(State.RY, -v))
- return;
- break;
- case kHIDUsage_GD_Hatswitch:
- {
- CFIndex integerValue = IOHIDValueGetIntegerValue(value);
-
- manipulateBitField(State.Buttons,
- Gamepad_Up,
- integerValue == 7 || integerValue == 0 || integerValue == 1);
- manipulateBitField(State.Buttons,
- Gamepad_Down,
- integerValue == 3 || integerValue == 4 || integerValue == 5);
- manipulateBitField(State.Buttons,
- Gamepad_Left,
- integerValue == 5 || integerValue == 6 || integerValue == 7);
- manipulateBitField(State.Buttons,
- Gamepad_Right,
- integerValue == 1 || integerValue == 2 || integerValue == 3);
- }
- break;
- default:
- return;
- }
- }
- }
- // The following controller mapping is based on the Sony DualShock3, however we use it for
- // all Sony devices on the assumption that they're likely to share the same mapping.
- else if (vendorID == Sony_DualShock3_VendorID)
- {
- // PS3 Controller.
- if (usagePage == kHIDPage_Button)
- {
- bool buttonState = IOHIDValueGetIntegerValue(value);
-
- switch(usage)
- {
- case kHIDUsage_Button_1:
- manipulateBitField(State.Buttons, Gamepad_Back, buttonState);
- break;
- case kHIDUsage_Button_2:
- manipulateBitField(State.Buttons, Gamepad_LStick, buttonState);
- break;
- case kHIDUsage_Button_3:
- manipulateBitField(State.Buttons, Gamepad_RStick, buttonState);
- break;
- case kHIDUsage_Button_4:
- manipulateBitField(State.Buttons, Gamepad_Start, buttonState);
- break;
- case 0x05:
- manipulateBitField(State.Buttons, Gamepad_Up, buttonState);
- break;
- case 0x06:
- manipulateBitField(State.Buttons, Gamepad_Right, buttonState);
- break;
- case 0x07:
- manipulateBitField(State.Buttons, Gamepad_Down, buttonState);
- break;
- case 0x08:
- manipulateBitField(State.Buttons, Gamepad_Left, buttonState);
- break;
- case 0x09:
- State.LT = buttonState ? 1.0f:0.0f;
- break;
- case 0x0A:
- State.RT = buttonState ? 1.0f:0.0f;
- break;
- case 0x0B:
- manipulateBitField(State.Buttons, Gamepad_L1, buttonState);
- break;
- case 0x0C:
- manipulateBitField(State.Buttons, Gamepad_R1, buttonState);
- break;
- case 0x0D:
- // PS3 Triangle.
- manipulateBitField(State.Buttons, Gamepad_TRIANGLE, buttonState);
- break;
- case 0x0E:
- // PS3 Circle
- manipulateBitField(State.Buttons, Gamepad_CIRCLE, buttonState);
- break;
- case 0x0F:
- // PS3 Cross
- manipulateBitField(State.Buttons, Gamepad_CROSS, buttonState);
- break;
- case 0x10:
- // PS3 Square
- manipulateBitField(State.Buttons, Gamepad_SQUARE, buttonState);
- break;
- default:
- return;
- }
- }
- else if (usagePage == kHIDPage_GenericDesktop)
- {
- float v;
- switch(usage)
- {
- case kHIDUsage_GD_X:
- v = mapAnalogAxis(value, element);
- if (!setStateIfDifferent(State.LX, v))
- return;
- break;
- case kHIDUsage_GD_Y:
- v = mapAnalogAxis(value, element);
- if (!setStateIfDifferent(State.LY, -v))
- return;
- break;
- case kHIDUsage_GD_Z:
- v = mapAnalogAxis(value, element);
- if (!setStateIfDifferent(State.RX, v))
- return;
- break;
- case kHIDUsage_GD_Rz:
- v = mapAnalogAxis(value, element);
- if (!setStateIfDifferent(State.RY, -v))
- return;
- break;
- default:
- return;
- }
- }
- }
-
- bStateChanged = true;
-}
-
-void GamepadManager::manipulateBitField(unsigned int& bitfield, unsigned int mask, bool val)
-{
- if (val)
- {
- bitfield |= mask;
- }
- else
- {
- bitfield &= ~mask;
- }
-}
-
-}}} // OVR::Platform::OSX
+/************************************************************************************ + +Filename : OSX_Gamepad.cpp +Content : OSX implementation of Gamepad functionality. +Created : May 6, 2013 +Authors : Lee Cooper + +Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OSX_Gamepad.h" + + +static const UInt32 Logitech_F710_VendorID = 0x046D; +static const UInt32 Logitech_F710_ProductID = 0xC219; + +static const UInt32 Sony_DualShock3_VendorID = 0x054C; +static const UInt32 Sony_DualShock3_ProductID = 0x0268; + + +namespace OVR { namespace Platform { namespace OSX { + + +GamepadManager::GamepadManager() + : bStateChanged(false) +{ + + HidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); + IOHIDManagerOpen(HidManager, kIOHIDOptionsTypeNone); + IOHIDManagerScheduleWithRunLoop(HidManager, + CFRunLoopGetCurrent(), + kCFRunLoopDefaultMode); + + + // Setup device matching. + CFStringRef keys[] = { CFSTR(kIOHIDDeviceUsagePageKey), + CFSTR(kIOHIDDeviceUsageKey)}; + + int value; + CFNumberRef values[2]; + CFDictionaryRef dictionaries[2]; + + // Match joysticks. + value = kHIDPage_GenericDesktop; + values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); + + value = kHIDUsage_GD_Joystick; + values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); + + dictionaries[0] = CFDictionaryCreate(kCFAllocatorDefault, + (const void **) keys, + (const void **) values, + 2, + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFRelease(values[0]); + CFRelease(values[1]); + + // Match gamepads. + value = kHIDPage_GenericDesktop; + values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); + + value = kHIDUsage_GD_GamePad; + values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); + + dictionaries[1] = CFDictionaryCreate(kCFAllocatorDefault, + (const void **) keys, + (const void **) values, + 2, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFRelease(values[0]); + CFRelease(values[1]); + + CFArrayRef array = CFArrayCreate( kCFAllocatorDefault, + (const void **) dictionaries, + 2, + &kCFTypeArrayCallBacks); + CFRelease(dictionaries[0]); + CFRelease(dictionaries[1]); + + IOHIDManagerSetDeviceMatchingMultiple(HidManager, array); + + CFRelease(array); + + + IOHIDManagerRegisterDeviceMatchingCallback(HidManager, staticOnDeviceMatched, this); + IOHIDManagerRegisterDeviceRemovalCallback(HidManager, staticOnDeviceRemoved, this); + +} + +GamepadManager::~GamepadManager() +{ + CFRelease(HidManager); +} + +UInt32 GamepadManager::GetGamepadCount() +{ + return 1; +} + +bool GamepadManager::GetGamepadState(UInt32 index, GamepadState* pState) +{ + // For now we just support one gamepad. + OVR_UNUSED(index); + + if (!bStateChanged) + { + return false; + } + + bStateChanged = false; +// State.Debug(); + + *pState = State; + return true; +} + +int GamepadManager::getIntDeviceProperty(IOHIDDeviceRef device, CFStringRef key) +{ + CFTypeRef type = IOHIDDeviceGetProperty(device, key); + OVR_ASSERT(type != NULL && CFGetTypeID(type) == CFNumberGetTypeID()); + + int value; + CFNumberGetValue((CFNumberRef) type, kCFNumberSInt32Type, &value); + + return value; +} + +void GamepadManager::staticOnDeviceMatched(void* context, IOReturn result, void* sender, IOHIDDeviceRef device) +{ + GamepadManager* pManager = (GamepadManager*) context; + pManager->onDeviceMatched(device); +} + +void GamepadManager::onDeviceMatched(IOHIDDeviceRef device) +{ + IOHIDDeviceRegisterInputValueCallback(device, staticOnDeviceValueChanged, this); +} + +void GamepadManager::staticOnDeviceRemoved(void* context, IOReturn result, void* sender, IOHIDDeviceRef device) +{ + GamepadManager* pManager = (GamepadManager*) context; + pManager->onDeviceRemoved(device); +} + +void GamepadManager::onDeviceRemoved(IOHIDDeviceRef device) +{ + IOHIDDeviceRegisterInputValueCallback(device, NULL, NULL); +} + +void GamepadManager::staticOnDeviceValueChanged(void* context, IOReturn result, void* sender, IOHIDValueRef value) +{ + GamepadManager* pManager = (GamepadManager*) context; + pManager->onDeviceValueChanged(value); +} + +float GamepadManager::mapAnalogAxis(IOHIDValueRef value, IOHIDElementRef element) +{ + + CFIndex val = IOHIDValueGetIntegerValue(value); + CFIndex min = IOHIDElementGetLogicalMin(element); + CFIndex max = IOHIDElementGetLogicalMax(element); + + float v = (float) (val - min) / (float) (max - min); + v = v * 2.0f - 1.0f; + + // Dead zone. + if (v < 0.1f && v > -0.1f) + { + v = 0.0f; + } + + return v; +} + +bool GamepadManager::setStateIfDifferent(float& state, float newState) +{ + if (state == newState) + return false; + + state = newState; + + return true; +} + +void GamepadManager::onDeviceValueChanged(IOHIDValueRef value) +{ + + IOHIDElementRef element = IOHIDValueGetElement(value); + IOHIDDeviceRef device = IOHIDElementGetDevice(element); + + int vendorID = getIntDeviceProperty(device, CFSTR(kIOHIDVendorIDKey)); + int productID = getIntDeviceProperty(device, CFSTR(kIOHIDProductIDKey)); + OVR_UNUSED(productID); + + uint32_t usagePage = IOHIDElementGetUsagePage(element); + uint32_t usage = IOHIDElementGetUsage(element); + + // The following controller mapping is based on the Logitech F710, however we use it for + // all Logitech devices on the assumption that they're likely to share the same mapping. + if (vendorID == Logitech_F710_VendorID) + { + // Logitech F710 mapping. + if (usagePage == kHIDPage_Button) + { + bool buttonState = IOHIDValueGetIntegerValue(value); + + switch(usage) + { + case kHIDUsage_Button_1: + manipulateBitField(State.Buttons, Gamepad_X, buttonState); + break; + case kHIDUsage_Button_2: + manipulateBitField(State.Buttons, Gamepad_A, buttonState); + break; + case kHIDUsage_Button_3: + manipulateBitField(State.Buttons, Gamepad_B, buttonState); + break; + case kHIDUsage_Button_4: + manipulateBitField(State.Buttons, Gamepad_Y, buttonState); + break; + case 0x05: + manipulateBitField(State.Buttons, Gamepad_L1, buttonState); + break; + case 0x06: + manipulateBitField(State.Buttons, Gamepad_R1, buttonState); + break; + case 0x07: + State.LT = buttonState ? 1.0f:0.0f; + break; + case 0x08: + State.RT = buttonState ? 1.0f:0.0f; + break; + case 0x09: + manipulateBitField(State.Buttons, Gamepad_Back, buttonState); + break; + case 0x0A: + manipulateBitField(State.Buttons, Gamepad_Start, buttonState); + break; + case 0x0B: + manipulateBitField(State.Buttons, Gamepad_LStick, buttonState); + break; + case 0x0C: + manipulateBitField(State.Buttons, Gamepad_RStick, buttonState); + break; + default: + return; + } + } + else if (usagePage == kHIDPage_GenericDesktop) + { + float v; + switch(usage) + { + case kHIDUsage_GD_X: + v = mapAnalogAxis(value, element); + if (!setStateIfDifferent(State.LX, v)) + return; + break; + case kHIDUsage_GD_Y: + v = mapAnalogAxis(value, element); + if (!setStateIfDifferent(State.LY, -v)) + return; + break; + case kHIDUsage_GD_Z: + v = mapAnalogAxis(value, element); + if (!setStateIfDifferent(State.RX, v)) + return; + break; + case kHIDUsage_GD_Rz: + v = mapAnalogAxis(value, element); + if (!setStateIfDifferent(State.RY, -v)) + return; + break; + case kHIDUsage_GD_Hatswitch: + { + CFIndex integerValue = IOHIDValueGetIntegerValue(value); + + manipulateBitField(State.Buttons, + Gamepad_Up, + integerValue == 7 || integerValue == 0 || integerValue == 1); + manipulateBitField(State.Buttons, + Gamepad_Down, + integerValue == 3 || integerValue == 4 || integerValue == 5); + manipulateBitField(State.Buttons, + Gamepad_Left, + integerValue == 5 || integerValue == 6 || integerValue == 7); + manipulateBitField(State.Buttons, + Gamepad_Right, + integerValue == 1 || integerValue == 2 || integerValue == 3); + } + break; + default: + return; + } + } + } + // The following controller mapping is based on the Sony DualShock3, however we use it for + // all Sony devices on the assumption that they're likely to share the same mapping. + else if (vendorID == Sony_DualShock3_VendorID) + { + // PS3 Controller. + if (usagePage == kHIDPage_Button) + { + bool buttonState = IOHIDValueGetIntegerValue(value); + + switch(usage) + { + case kHIDUsage_Button_1: + manipulateBitField(State.Buttons, Gamepad_Back, buttonState); + break; + case kHIDUsage_Button_2: + manipulateBitField(State.Buttons, Gamepad_LStick, buttonState); + break; + case kHIDUsage_Button_3: + manipulateBitField(State.Buttons, Gamepad_RStick, buttonState); + break; + case kHIDUsage_Button_4: + manipulateBitField(State.Buttons, Gamepad_Start, buttonState); + break; + case 0x05: + manipulateBitField(State.Buttons, Gamepad_Up, buttonState); + break; + case 0x06: + manipulateBitField(State.Buttons, Gamepad_Right, buttonState); + break; + case 0x07: + manipulateBitField(State.Buttons, Gamepad_Down, buttonState); + break; + case 0x08: + manipulateBitField(State.Buttons, Gamepad_Left, buttonState); + break; + case 0x09: + State.LT = buttonState ? 1.0f:0.0f; + break; + case 0x0A: + State.RT = buttonState ? 1.0f:0.0f; + break; + case 0x0B: + manipulateBitField(State.Buttons, Gamepad_L1, buttonState); + break; + case 0x0C: + manipulateBitField(State.Buttons, Gamepad_R1, buttonState); + break; + case 0x0D: + // PS3 Triangle. + manipulateBitField(State.Buttons, Gamepad_TRIANGLE, buttonState); + break; + case 0x0E: + // PS3 Circle + manipulateBitField(State.Buttons, Gamepad_CIRCLE, buttonState); + break; + case 0x0F: + // PS3 Cross + manipulateBitField(State.Buttons, Gamepad_CROSS, buttonState); + break; + case 0x10: + // PS3 Square + manipulateBitField(State.Buttons, Gamepad_SQUARE, buttonState); + break; + default: + return; + } + } + else if (usagePage == kHIDPage_GenericDesktop) + { + float v; + switch(usage) + { + case kHIDUsage_GD_X: + v = mapAnalogAxis(value, element); + if (!setStateIfDifferent(State.LX, v)) + return; + break; + case kHIDUsage_GD_Y: + v = mapAnalogAxis(value, element); + if (!setStateIfDifferent(State.LY, -v)) + return; + break; + case kHIDUsage_GD_Z: + v = mapAnalogAxis(value, element); + if (!setStateIfDifferent(State.RX, v)) + return; + break; + case kHIDUsage_GD_Rz: + v = mapAnalogAxis(value, element); + if (!setStateIfDifferent(State.RY, -v)) + return; + break; + default: + return; + } + } + } + + bStateChanged = true; +} + +void GamepadManager::manipulateBitField(unsigned int& bitfield, unsigned int mask, bool val) +{ + if (val) + { + bitfield |= mask; + } + else + { + bitfield &= ~mask; + } +} + +}}} // OVR::Platform::OSX diff --git a/Samples/CommonSrc/Platform/OSX_Gamepad.h b/Samples/CommonSrc/Platform/OSX_Gamepad.h index 6d3344c..335a512 100644 --- a/Samples/CommonSrc/Platform/OSX_Gamepad.h +++ b/Samples/CommonSrc/Platform/OSX_Gamepad.h @@ -1,67 +1,66 @@ -/************************************************************************************
-
-Filename : OSX_Gamepad.h
-Content : OSX implementation of Gamepad functionality.
-Created : May 6, 2013
-Authors : Lee Cooper
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-************************************************************************************/
-
-#ifndef OVR_OSX_Gamepad_h
-#define OVR_OSX_Gamepad_h
-
-#include "Gamepad.h"
-
-#include <IOKit/IOKitLib.h>
-#include <IOKit/hid/IOHIDManager.h>
-
-
-namespace OVR { namespace Platform { namespace OSX {
-
-
-class GamepadManager : public Platform::GamepadManager
-{
-public:
- GamepadManager();
- ~GamepadManager();
-
- virtual UInt32 GetGamepadCount();
- virtual bool GetGamepadState(UInt32 index, GamepadState* pState);
-
-private:
- static void staticOnDeviceMatched(void* context, IOReturn result, void* sender, IOHIDDeviceRef device);
- void onDeviceMatched(IOHIDDeviceRef device);
-
- static void staticOnDeviceRemoved(void* context, IOReturn result, void* sender, IOHIDDeviceRef device);
- void onDeviceRemoved(IOHIDDeviceRef device);
-
- static void staticOnDeviceValueChanged(void* context, IOReturn result, void* sender, IOHIDValueRef value);
- void onDeviceValueChanged(IOHIDValueRef value);
-
- int getIntDeviceProperty(IOHIDDeviceRef device, CFStringRef key);
- float mapAnalogAxis(IOHIDValueRef value, IOHIDElementRef element);
- void manipulateBitField(unsigned int& bitfield, unsigned int mask, bool val);
- bool setStateIfDifferent(float& state, float newState);
-
- IOHIDManagerRef HidManager;
- GamepadState State;
- bool bStateChanged;
-};
-
-}}}
-
-#endif // OVR_OSX_Gamepad_h
+/************************************************************************************ + +Filename : OSX_Gamepad.h +Content : OSX implementation of Gamepad functionality. +Created : May 6, 2013 +Authors : Lee Cooper + +Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_OSX_Gamepad_h +#define OVR_OSX_Gamepad_h + +#include <IOKit/IOKitLib.h> +#include <IOKit/hid/IOHIDManager.h> + +#include "Gamepad.h" + +namespace OVR { namespace Platform { namespace OSX { + + +class GamepadManager : public Platform::GamepadManager +{ +public: + GamepadManager(); + ~GamepadManager(); + + virtual UInt32 GetGamepadCount(); + virtual bool GetGamepadState(UInt32 index, GamepadState* pState); + +private: + static void staticOnDeviceMatched(void* context, IOReturn result, void* sender, IOHIDDeviceRef device); + void onDeviceMatched(IOHIDDeviceRef device); + + static void staticOnDeviceRemoved(void* context, IOReturn result, void* sender, IOHIDDeviceRef device); + void onDeviceRemoved(IOHIDDeviceRef device); + + static void staticOnDeviceValueChanged(void* context, IOReturn result, void* sender, IOHIDValueRef value); + void onDeviceValueChanged(IOHIDValueRef value); + + int getIntDeviceProperty(IOHIDDeviceRef device, CFStringRef key); + float mapAnalogAxis(IOHIDValueRef value, IOHIDElementRef element); + void manipulateBitField(unsigned int& bitfield, unsigned int mask, bool val); + bool setStateIfDifferent(float& state, float newState); + + IOHIDManagerRef HidManager; + GamepadState State; + bool bStateChanged; +}; + +}}} + +#endif // OVR_OSX_Gamepad_h diff --git a/Samples/CommonSrc/Platform/OSX_Platform.h b/Samples/CommonSrc/Platform/OSX_Platform.h index 748c5fa..11d4279 100644 --- a/Samples/CommonSrc/Platform/OSX_Platform.h +++ b/Samples/CommonSrc/Platform/OSX_Platform.h @@ -1,80 +1,80 @@ -
-#include "../Platform/Platform.h"
-#include "../Render/Render_GL_Device.h"
-
-namespace OVR { namespace Platform { namespace OSX {
-
-class PlatformCore : public Platform::PlatformCore
-{
-public:
- void* Win;
- void* View;
- void* NsApp;
- bool Quit;
- int ExitCode;
- int Width, Height;
- MouseMode MMode;
-
- void RunIdle();
-
-public:
- PlatformCore(Application* app, void* nsapp);
- ~PlatformCore();
-
- bool SetupWindow(int w, int h);
- void Exit(int exitcode);
-
- RenderDevice* SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc,
- const char* gtype, const Render::RendererParams& rp);
-
- void SetMouseMode(MouseMode mm);
- void GetWindowSize(int* w, int* h) const;
-
- void SetWindowTitle(const char*title);
-
- void ShowWindow(bool show);
- void DestroyWindow();
- bool SetFullscreen(const Render::RendererParams& rp, int fullscreen);
- int GetDisplayCount();
- Render::DisplayId GetDisplay(int screen);
-
- String GetContentDirectory() const;
-};
-
-}}
-namespace Render { namespace GL { namespace OSX {
-
-class RenderDevice : public Render::GL::RenderDevice
-{
-public:
- void* Context;
-
- RenderDevice(const Render::RendererParams& p, void* context)
- : GL::RenderDevice(p), Context(context) {}
-
- virtual void Shutdown();
- virtual void Present();
-
- virtual bool SetFullscreen(DisplayMode fullscreen);
-
- // oswnd = X11::PlatformCore*
- static Render::RenderDevice* CreateDevice(const RendererParams& rp, void* oswnd);
-};
-
-}}}}
-
-
-// OVR_PLATFORM_APP_ARGS specifies the Application class to use for startup,
-// providing it with startup arguments.
-#define OVR_PLATFORM_APP_ARGS(AppClass, args) \
-OVR::Platform::Application* OVR::Platform::Application::CreateApplication() \
-{ OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All)); \
-return new AppClass args; } \
-void OVR::Platform::Application::DestroyApplication(OVR::Platform::Application* app) \
-{ OVR::Platform::PlatformCore* platform = app->pPlatform; \
-delete app; delete platform; OVR::System::Destroy(); };
-
-// OVR_PLATFORM_APP_ARGS specifies the Application startup class with no args.
-#define OVR_PLATFORM_APP(AppClass) OVR_PLATFORM_APP_ARGS(AppClass, ())
-
-
+ +#include "../Platform/Platform.h" +#include "../Render/Render_GL_Device.h" + +namespace OVR { namespace Platform { namespace OSX { + +class PlatformCore : public Platform::PlatformCore +{ +public: + void* Win; + void* View; + void* NsApp; + bool Quit; + int ExitCode; + int Width, Height; + MouseMode MMode; + + void RunIdle(); + +public: + PlatformCore(Application* app, void* nsapp); + ~PlatformCore(); + + bool SetupWindow(int w, int h); + void Exit(int exitcode); + + RenderDevice* SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc, + const char* gtype, const Render::RendererParams& rp); + + void SetMouseMode(MouseMode mm); + void GetWindowSize(int* w, int* h) const; + + void SetWindowTitle(const char*title); + + void ShowWindow(bool show); + void DestroyWindow(); + bool SetFullscreen(const Render::RendererParams& rp, int fullscreen); + int GetDisplayCount(); + Render::DisplayId GetDisplay(int screen); + + String GetContentDirectory() const; +}; + +}} +namespace Render { namespace GL { namespace OSX { + +class RenderDevice : public Render::GL::RenderDevice +{ +public: + void* Context; + + RenderDevice(const Render::RendererParams& p, void* context) + : GL::RenderDevice(p), Context(context) {} + + virtual void Shutdown(); + virtual void Present(); + + virtual bool SetFullscreen(DisplayMode fullscreen); + + // oswnd = X11::PlatformCore* + static Render::RenderDevice* CreateDevice(const RendererParams& rp, void* oswnd); +}; + +}}}} + + +// OVR_PLATFORM_APP_ARGS specifies the Application class to use for startup, +// providing it with startup arguments. +#define OVR_PLATFORM_APP_ARGS(AppClass, args) \ +OVR::Platform::Application* OVR::Platform::Application::CreateApplication() \ +{ OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All)); \ +return new AppClass args; } \ +void OVR::Platform::Application::DestroyApplication(OVR::Platform::Application* app) \ +{ OVR::Platform::PlatformCore* platform = app->pPlatform; \ +delete app; delete platform; OVR::System::Destroy(); }; + +// OVR_PLATFORM_APP_ARGS specifies the Application startup class with no args. +#define OVR_PLATFORM_APP(AppClass) OVR_PLATFORM_APP_ARGS(AppClass, ()) + + diff --git a/Samples/CommonSrc/Platform/OSX_PlatformObjc.h b/Samples/CommonSrc/Platform/OSX_PlatformObjc.h index 7e69a4d..7d195eb 100644 --- a/Samples/CommonSrc/Platform/OSX_PlatformObjc.h +++ b/Samples/CommonSrc/Platform/OSX_PlatformObjc.h @@ -1,31 +1,31 @@ -
-#import <Cocoa/Cocoa.h>
-#import "OSX_Platform.h"
-#import "OSX_Gamepad.h"
-
-#import <CoreGraphics/CoreGraphics.h>
-#import <CoreGraphics/CGDirectDisplay.h>
-
-@interface OVRApp : NSApplication
-
-@property (assign) IBOutlet NSWindow* win;
-@property (assign) OVR::Platform::OSX::PlatformCore* Platform;
-@property (assign) OVR::Platform::Application* App;
-
--(void) run;
-
-@end
-
-@interface OVRView : NSOpenGLView <NSWindowDelegate>
-
-@property (assign) OVR::Platform::OSX::PlatformCore* Platform;
-@property (assign) OVR::Platform::Application* App;
-@property unsigned long Modifiers;
-
--(void)ProcessMouse:(NSEvent*)event;
--(void)warpMouseToCenter;
-
-+(CGDirectDisplayID) displayFromScreen:(NSScreen*)s;
-
-@end
-
+ +#import <Cocoa/Cocoa.h> +#import "OSX_Platform.h" +#import "OSX_Gamepad.h" + +#import <CoreGraphics/CoreGraphics.h> +#import <CoreGraphics/CGDirectDisplay.h> + +@interface OVRApp : NSApplication + +@property (assign) IBOutlet NSWindow* win; +@property (assign) OVR::Platform::OSX::PlatformCore* Platform; +@property (assign) OVR::Platform::Application* App; + +-(void) run; + +@end + +@interface OVRView : NSOpenGLView <NSWindowDelegate> + +@property (assign) OVR::Platform::OSX::PlatformCore* Platform; +@property (assign) OVR::Platform::Application* App; +@property unsigned long Modifiers; + +-(void)ProcessMouse:(NSEvent*)event; +-(void)warpMouseToCenter; + ++(CGDirectDisplayID) displayFromScreen:(NSScreen*)s; + +@end + diff --git a/Samples/CommonSrc/Platform/OSX_WavPlayer.cpp b/Samples/CommonSrc/Platform/OSX_WavPlayer.cpp index 6119888..a6cb937 100644 --- a/Samples/CommonSrc/Platform/OSX_WavPlayer.cpp +++ b/Samples/CommonSrc/Platform/OSX_WavPlayer.cpp @@ -1,242 +1,242 @@ -/************************************************************************************
-
-Filename : WavPlayer_OSX.cpp
-Content : An Apple OSX audio handler.
-Created : March 5, 2013
-Authors : Robotic Arm Software - Peter Hoff, Dan Goodman, Bryan Croteau
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Use of this software is subject to the terms of the Oculus LLC license
-agreement provided at the time of installation or download, or which
-otherwise accompanies this software in either electronic or hard copy form.
-
-************************************************************************************/
-
-#include "OSX_WavPlayer.h"
-
-namespace OVR { namespace Platform { namespace OSX {
-
-WavPlayer::WavPlayer(const char* fileName)
-{
- FileName = fileName;
-}
-
-bool WavPlayer::isDataChunk(unsigned char* buffer, int index)
-{
- unsigned char a = buffer[index];
- unsigned char b = buffer[index + 1];
- unsigned char c = buffer[index + 2];
- unsigned char d = buffer[index + 3];
- return (a == 'D' || a == 'd') && (b == 'A' || b == 'a') &&
- (c == 'T' || c == 't') && (d == 'A' || d == 'a');
-}
-
-int WavPlayer::getWord(unsigned char* buffer, int index)
-{
- unsigned char a = buffer[index];
- unsigned char b = buffer[index + 1];
- unsigned char c = buffer[index + 2];
- unsigned char d = buffer[index + 3];
- int result = 0;
- result |= a;
- result |= b << 8;
- result |= c << 16;
- result |= d << 24;
- return result;
-}
-
-short WavPlayer::getHalf(unsigned char* buffer, int index)
-{
- unsigned char a = buffer[index];
- unsigned char b = buffer[index + 1];
- short result = 0;
- result |= a;
- result |= b << 8;
- return result;
-}
-
-void *WavPlayer::LoadPCM(const char *filename, unsigned long *len)
-{
- FILE *file;
- struct stat s;
- void *pcm;
-
- if(stat(filename, &s))
- {
- return NULL;
- }
- *len = s.st_size;
- pcm = (void *) malloc(s.st_size);
- if(!pcm)
- {
- return NULL;
- }
- file = fopen(filename, "rb");
- if(!file)
- {
- free(pcm);
- return NULL;
- }
- fread(pcm, s.st_size, 1, file);
- fclose(file);
- return pcm;
-}
-
-int WavPlayer::PlayBuffer(void *pcmbuffer, unsigned long len)
-{
- AQCallbackStruct aqc;
- UInt32 err, bufferSize;
- int i;
-
- aqc.DataFormat.mSampleRate = SampleRate;
- aqc.DataFormat.mFormatID = kAudioFormatLinearPCM;
- if(BitsPerSample == 16)
- {
- aqc.DataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger
- | kAudioFormatFlagIsPacked;
- }
- aqc.DataFormat.mBytesPerPacket = NumChannels * (BitsPerSample / 8);
- aqc.DataFormat.mFramesPerPacket = 1;
- aqc.DataFormat.mBytesPerFrame = NumChannels * (BitsPerSample / 8);
- aqc.DataFormat.mChannelsPerFrame = NumChannels;
- aqc.DataFormat.mBitsPerChannel = BitsPerSample;
- aqc.FrameCount = SampleRate / 60;
- aqc.SampleLen = (UInt32)(len);
- aqc.PlayPtr = 0;
- aqc.PCMBuffer = static_cast<unsigned char*>(pcmbuffer);
-
- err = AudioQueueNewOutput(&aqc.DataFormat,
- aqBufferCallback,
- &aqc,
- NULL,
- kCFRunLoopCommonModes,
- 0,
- &aqc.Queue);
- if(err)
- {
- return err;
- }
-
- aqc.FrameCount = SampleRate / 60;
- bufferSize = aqc.FrameCount * aqc.DataFormat.mBytesPerPacket;
-
- for(i = 0; i < AUDIO_BUFFERS; i++)
- {
- err = AudioQueueAllocateBuffer(aqc.Queue, bufferSize,
- &aqc.Buffers[i]);
- if(err)
- {
- return err;
- }
- aqBufferCallback(&aqc, aqc.Queue, aqc.Buffers[i]);
- }
-
- err = AudioQueueStart(aqc.Queue, NULL);
- if(err)
- {
- return err;
- }
-
- while(true)
- {
- }
- sleep(1);
- return 0;
-}
-
-void WavPlayer::aqBufferCallback(void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB)
-{
- AQCallbackStruct *aqc;
- unsigned char *coreAudioBuffer;
-
- aqc = (AQCallbackStruct *) in;
- coreAudioBuffer = (unsigned char*) outQB->mAudioData;
-
- printf("Sync: %u / %u\n", aqc->PlayPtr, aqc->SampleLen);
-
- if(aqc->FrameCount > 0)
- {
- outQB->mAudioDataByteSize = aqc->DataFormat.mBytesPerFrame * aqc->FrameCount;
- for(int i = 0; i < aqc->FrameCount * aqc->DataFormat.mBytesPerFrame; i++)
- {
- if(aqc->PlayPtr > aqc->SampleLen)
- {
- aqc->PlayPtr = 0;
- i = 0;
- }
- coreAudioBuffer[i] = aqc->PCMBuffer[aqc->PlayPtr];
- aqc->PlayPtr++;
- }
- AudioQueueEnqueueBuffer(inQ, outQB, 0, NULL);
- }
-}
-
-int WavPlayer::PlayAudio()
-{
- unsigned long len;
- void *pcmbuffer;
- int ret;
-
- pcmbuffer = LoadPCM(FileName, &len);
- if(!pcmbuffer)
- {
- fprintf(stderr, "%s: %s\n", FileName, strerror(errno));
- exit(EXIT_FAILURE);
- }
-
- unsigned char* bytes = (unsigned char*)pcmbuffer;
- int index = 0;
-
- // 'RIFF'
- getWord(bytes, index);
- index += 4;
- // int Length
- getWord(bytes, index);
- index += 4;
- // 'WAVE'
- getWord(bytes, index);
- index += 4;
- // 'fmt '
- getWord(bytes, index);
- index += 4;
-
- // int Format Length
- int fmtLen = getWord(bytes, index);
- index += 4;
- AudioFormat = getHalf(bytes, index);
- index += 2;
- NumChannels = getHalf(bytes, index);
- index += 2;
- SampleRate = getWord(bytes, index);
- index += 4;
- ByteRate = getWord(bytes, index);
- index += 4;
- BlockAlign = getHalf(bytes, index);
- index += 2;
- BitsPerSample = getHalf(bytes, index);
- index += 2;
- index += fmtLen - 16;
- while(!isDataChunk(bytes, index))
- {
- // Any Chunk
- getWord(bytes, index);
- index += 4;
- // Any Chunk Length
- int anyChunkLen = getWord(bytes, index);
- index += 4 + anyChunkLen;
- }
- // 'data'
- getWord(bytes, index);
- index += 4;
- // int Data Length
- unsigned long dataLen = getWord(bytes, index);
- index += 4;
- unsigned char* target = &bytes[index];
-
- ret = PlayBuffer((void *)target, dataLen);
- free(pcmbuffer);
- return ret;
-}
-
-}}}
+/************************************************************************************ + +Filename : WavPlayer_OSX.cpp +Content : An Apple OSX audio handler. +Created : March 5, 2013 +Authors : Robotic Arm Software - Peter Hoff, Dan Goodman, Bryan Croteau + +Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. + +Use of this software is subject to the terms of the Oculus LLC license +agreement provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +************************************************************************************/ + +#include "OSX_WavPlayer.h" + +namespace OVR { namespace Platform { namespace OSX { + +WavPlayer::WavPlayer(const char* fileName) +{ + FileName = fileName; +} + +bool WavPlayer::isDataChunk(unsigned char* buffer, int index) +{ + unsigned char a = buffer[index]; + unsigned char b = buffer[index + 1]; + unsigned char c = buffer[index + 2]; + unsigned char d = buffer[index + 3]; + return (a == 'D' || a == 'd') && (b == 'A' || b == 'a') && + (c == 'T' || c == 't') && (d == 'A' || d == 'a'); +} + +int WavPlayer::getWord(unsigned char* buffer, int index) +{ + unsigned char a = buffer[index]; + unsigned char b = buffer[index + 1]; + unsigned char c = buffer[index + 2]; + unsigned char d = buffer[index + 3]; + int result = 0; + result |= a; + result |= b << 8; + result |= c << 16; + result |= d << 24; + return result; +} + +short WavPlayer::getHalf(unsigned char* buffer, int index) +{ + unsigned char a = buffer[index]; + unsigned char b = buffer[index + 1]; + short result = 0; + result |= a; + result |= b << 8; + return result; +} + +void *WavPlayer::LoadPCM(const char *filename, unsigned long *len) +{ + FILE *file; + struct stat s; + void *pcm; + + if(stat(filename, &s)) + { + return NULL; + } + *len = s.st_size; + pcm = (void *) malloc(s.st_size); + if(!pcm) + { + return NULL; + } + file = fopen(filename, "rb"); + if(!file) + { + free(pcm); + return NULL; + } + fread(pcm, s.st_size, 1, file); + fclose(file); + return pcm; +} + +int WavPlayer::PlayBuffer(void *pcmbuffer, unsigned long len) +{ + AQCallbackStruct aqc; + UInt32 err, bufferSize; + int i; + + aqc.DataFormat.mSampleRate = SampleRate; + aqc.DataFormat.mFormatID = kAudioFormatLinearPCM; + if(BitsPerSample == 16) + { + aqc.DataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger + | kAudioFormatFlagIsPacked; + } + aqc.DataFormat.mBytesPerPacket = NumChannels * (BitsPerSample / 8); + aqc.DataFormat.mFramesPerPacket = 1; + aqc.DataFormat.mBytesPerFrame = NumChannels * (BitsPerSample / 8); + aqc.DataFormat.mChannelsPerFrame = NumChannels; + aqc.DataFormat.mBitsPerChannel = BitsPerSample; + aqc.FrameCount = SampleRate / 60; + aqc.SampleLen = (UInt32)(len); + aqc.PlayPtr = 0; + aqc.PCMBuffer = static_cast<unsigned char*>(pcmbuffer); + + err = AudioQueueNewOutput(&aqc.DataFormat, + aqBufferCallback, + &aqc, + NULL, + kCFRunLoopCommonModes, + 0, + &aqc.Queue); + if(err) + { + return err; + } + + aqc.FrameCount = SampleRate / 60; + bufferSize = aqc.FrameCount * aqc.DataFormat.mBytesPerPacket; + + for(i = 0; i < AUDIO_BUFFERS; i++) + { + err = AudioQueueAllocateBuffer(aqc.Queue, bufferSize, + &aqc.Buffers[i]); + if(err) + { + return err; + } + aqBufferCallback(&aqc, aqc.Queue, aqc.Buffers[i]); + } + + err = AudioQueueStart(aqc.Queue, NULL); + if(err) + { + return err; + } + + while(true) + { + } + sleep(1); + return 0; +} + +void WavPlayer::aqBufferCallback(void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB) +{ + AQCallbackStruct *aqc; + unsigned char *coreAudioBuffer; + + aqc = (AQCallbackStruct *) in; + coreAudioBuffer = (unsigned char*) outQB->mAudioData; + + printf("Sync: %u / %u\n", aqc->PlayPtr, aqc->SampleLen); + + if(aqc->FrameCount > 0) + { + outQB->mAudioDataByteSize = aqc->DataFormat.mBytesPerFrame * aqc->FrameCount; + for(int i = 0; i < aqc->FrameCount * aqc->DataFormat.mBytesPerFrame; i++) + { + if(aqc->PlayPtr > aqc->SampleLen) + { + aqc->PlayPtr = 0; + i = 0; + } + coreAudioBuffer[i] = aqc->PCMBuffer[aqc->PlayPtr]; + aqc->PlayPtr++; + } + AudioQueueEnqueueBuffer(inQ, outQB, 0, NULL); + } +} + +int WavPlayer::PlayAudio() +{ + unsigned long len; + void *pcmbuffer; + int ret; + + pcmbuffer = LoadPCM(FileName, &len); + if(!pcmbuffer) + { + fprintf(stderr, "%s: %s\n", FileName, strerror(errno)); + exit(EXIT_FAILURE); + } + + unsigned char* bytes = (unsigned char*)pcmbuffer; + int index = 0; + + // 'RIFF' + getWord(bytes, index); + index += 4; + // int Length + getWord(bytes, index); + index += 4; + // 'WAVE' + getWord(bytes, index); + index += 4; + // 'fmt ' + getWord(bytes, index); + index += 4; + + // int Format Length + int fmtLen = getWord(bytes, index); + index += 4; + AudioFormat = getHalf(bytes, index); + index += 2; + NumChannels = getHalf(bytes, index); + index += 2; + SampleRate = getWord(bytes, index); + index += 4; + ByteRate = getWord(bytes, index); + index += 4; + BlockAlign = getHalf(bytes, index); + index += 2; + BitsPerSample = getHalf(bytes, index); + index += 2; + index += fmtLen - 16; + while(!isDataChunk(bytes, index)) + { + // Any Chunk + getWord(bytes, index); + index += 4; + // Any Chunk Length + int anyChunkLen = getWord(bytes, index); + index += 4 + anyChunkLen; + } + // 'data' + getWord(bytes, index); + index += 4; + // int Data Length + unsigned long dataLen = getWord(bytes, index); + index += 4; + unsigned char* target = &bytes[index]; + + ret = PlayBuffer((void *)target, dataLen); + free(pcmbuffer); + return ret; +} + +}}} diff --git a/Samples/CommonSrc/Platform/OSX_WavPlayer.h b/Samples/CommonSrc/Platform/OSX_WavPlayer.h index 1b88b8c..4aaba10 100644 --- a/Samples/CommonSrc/Platform/OSX_WavPlayer.h +++ b/Samples/CommonSrc/Platform/OSX_WavPlayer.h @@ -1,64 +1,64 @@ -/************************************************************************************
-
-Filename : WavPlayer_OSX.h
-Content : An Apple OSX audio handler.
-Created : March 5, 2013
-Authors : Robotic Arm Software - Peter Hoff, Dan Goodman, Bryan Croteau
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Use of this software is subject to the terms of the Oculus LLC license
-agreement provided at the time of installation or download, or which
-otherwise accompanies this software in either electronic or hard copy form.
-
-************************************************************************************/
-
-#ifndef OVR_WavPlayer_h
-#define OVR_WavPlayer_h
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <AudioToolbox/AudioQueue.h>
-
-#define AUDIO_BUFFERS 4
-
-namespace OVR { namespace Platform { namespace OSX {
-
-typedef struct AQCallbackStruct
-{
- AudioQueueRef Queue;
- UInt32 FrameCount;
- AudioQueueBufferRef Buffers[AUDIO_BUFFERS];
- AudioStreamBasicDescription DataFormat;
- UInt32 PlayPtr;
- UInt32 SampleLen;
- unsigned char* PCMBuffer;
-} AQCallbackStruct;
-
-class WavPlayer
-{
-public:
- WavPlayer(const char* fileName);
- int PlayAudio();
-private:
- bool isDataChunk(unsigned char* buffer, int index);
- int getWord(unsigned char* buffer, int index);
- short getHalf(unsigned char* buffer, int index);
- void *LoadPCM(const char *filename, unsigned long *len);
- int PlayBuffer(void *pcm, unsigned long len);
- static void aqBufferCallback(void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB);
-
- short AudioFormat;
- short NumChannels;
- int SampleRate;
- int ByteRate;
- short BlockAlign;
- short BitsPerSample;
- const char* FileName;
-};
-
-}}}
-
-#endif
+/************************************************************************************ + +Filename : WavPlayer_OSX.h +Content : An Apple OSX audio handler. +Created : March 5, 2013 +Authors : Robotic Arm Software - Peter Hoff, Dan Goodman, Bryan Croteau + +Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. + +Use of this software is subject to the terms of the Oculus LLC license +agreement provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +************************************************************************************/ + +#ifndef OVR_WavPlayer_h +#define OVR_WavPlayer_h + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/stat.h> +#include <AudioToolbox/AudioQueue.h> + +#define AUDIO_BUFFERS 4 + +namespace OVR { namespace Platform { namespace OSX { + +typedef struct AQCallbackStruct +{ + AudioQueueRef Queue; + UInt32 FrameCount; + AudioQueueBufferRef Buffers[AUDIO_BUFFERS]; + AudioStreamBasicDescription DataFormat; + UInt32 PlayPtr; + UInt32 SampleLen; + unsigned char* PCMBuffer; +} AQCallbackStruct; + +class WavPlayer +{ +public: + WavPlayer(const char* fileName); + int PlayAudio(); +private: + bool isDataChunk(unsigned char* buffer, int index); + int getWord(unsigned char* buffer, int index); + short getHalf(unsigned char* buffer, int index); + void *LoadPCM(const char *filename, unsigned long *len); + int PlayBuffer(void *pcm, unsigned long len); + static void aqBufferCallback(void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB); + + short AudioFormat; + short NumChannels; + int SampleRate; + int ByteRate; + short BlockAlign; + short BitsPerSample; + const char* FileName; +}; + +}}} + +#endif diff --git a/Samples/CommonSrc/Platform/Platform.cpp b/Samples/CommonSrc/Platform/Platform.cpp index bf5b8a5..c0e4438 100644 --- a/Samples/CommonSrc/Platform/Platform.cpp +++ b/Samples/CommonSrc/Platform/Platform.cpp @@ -1,75 +1,75 @@ -/************************************************************************************
-
-Filename : Platform.cpp
-Content : Platform-independent app framework for Oculus samples
-Created : September 6, 2012
-Authors : Andrew Reisse
-
-Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-************************************************************************************/
-
-
-
-#include "Platform.h"
-#include <Kernel/OVR_Std.h>
-#include <Kernel/OVR_Timer.h>
-#include "../Render/Render_Device.h"
-#include "Gamepad.h"
-
-namespace OVR { namespace Platform {
-
-
-const SetupGraphicsDeviceSet* SetupGraphicsDeviceSet::PickSetupDevice(const char* typeArg) const
-{
- // Search for graphics creation object that matches type arg.
- if (typeArg)
- {
- for (const SetupGraphicsDeviceSet* p = this; p != 0; p = p->pNext)
- {
- if (!OVR_stricmp(p->pTypeArg, typeArg))
- return p;
- }
- }
- return this;
-}
-
-//-------------------------------------------------------------------------------------
-
-PlatformCore::PlatformCore(Application *app)
-{
- pApp = app;
- pApp->SetPlatformCore(this);
- StartupTicks = OVR::Timer::GetTicks();
-}
-
-double PlatformCore::GetAppTime() const
-{
- return (OVR::Timer::GetTicks() - StartupTicks) * (1.0 / (double)OVR::Timer::MksPerSecond);
-}
-
-bool PlatformCore::SetFullscreen(const Render::RendererParams&, int fullscreen)
-{
- if (pRender)
- return pRender->SetFullscreen((Render::DisplayMode)fullscreen);
- return 0;
-}
-
-Render::DisplayId PlatformCore::GetDisplay(int screen)
-{
- OVR_UNUSED(screen); return Render::DisplayId();
-}
-
-}}
+/************************************************************************************ + +Filename : Platform.cpp +Content : Platform-independent app framework for Oculus samples +Created : September 6, 2012 +Authors : Andrew Reisse + +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + + + +#include "Platform.h" +#include <Kernel/OVR_Std.h> +#include <Kernel/OVR_Timer.h> +#include "../Render/Render_Device.h" +#include "Gamepad.h" + +namespace OVR { namespace Platform { + + +const SetupGraphicsDeviceSet* SetupGraphicsDeviceSet::PickSetupDevice(const char* typeArg) const +{ + // Search for graphics creation object that matches type arg. + if (typeArg) + { + for (const SetupGraphicsDeviceSet* p = this; p != 0; p = p->pNext) + { + if (!OVR_stricmp(p->pTypeArg, typeArg)) + return p; + } + } + return this; +} + +//------------------------------------------------------------------------------------- + +PlatformCore::PlatformCore(Application *app) +{ + pApp = app; + pApp->SetPlatformCore(this); + StartupTicks = OVR::Timer::GetTicks(); +} + +double PlatformCore::GetAppTime() const +{ + return (OVR::Timer::GetTicks() - StartupTicks) * (1.0 / (double)OVR::Timer::MksPerSecond); +} + +bool PlatformCore::SetFullscreen(const Render::RendererParams&, int fullscreen) +{ + if (pRender) + return pRender->SetFullscreen((Render::DisplayMode)fullscreen); + return 0; +} + +Render::DisplayId PlatformCore::GetDisplay(int screen) +{ + OVR_UNUSED(screen); return Render::DisplayId(); +} + +}} diff --git a/Samples/CommonSrc/Platform/Platform.h b/Samples/CommonSrc/Platform/Platform.h index 8ef4593..201aad6 100644 --- a/Samples/CommonSrc/Platform/Platform.h +++ b/Samples/CommonSrc/Platform/Platform.h @@ -1,190 +1,190 @@ -/************************************************************************************
-
-Filename : Platform.h
-Content : Platform-independent app and rendering framework for Oculus samples
-Created : September 6, 2012
-Authors : Andrew Reisse
-
-Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-************************************************************************************/
-
-#ifndef OVR_Platform_h
-#define OVR_Platform_h
-
-#include "OVR.h"
-
-#include "Kernel/OVR_KeyCodes.h"
-
-namespace OVR { namespace Render {
- class RenderDevice;
- struct DisplayId;
- struct RendererParams;
-}}
-
-namespace OVR { namespace Platform {
-
-using Render::RenderDevice;
-
-class PlatformCore;
-class Application;
-class GamepadManager;
-
-// MouseMode configures mouse input behavior of the app. Three states are
-// currently supported:
-// Normal - Reports absolute coordinates with cursor shown.
-// Relative - Reports relative delta coordinates with cursor hidden
-// until 'Esc' key is pressed or window loses focus.
-// RelativeEscaped - Relative input is desired, but has been escaped until
-// mouse is clicked in the window, which will return the state
-// to relative. Absolute coordinates are reported.
-
-enum MouseMode
-{
- Mouse_Normal,
- Mouse_Relative, // Cursor hidden, mouse grab, OnMouseMove reports relative deltas.
- Mouse_RelativeEscaped, // Clicking in window will return to Relative state.
-};
-
-
-enum Modifiers
-{
- Mod_Shift = 0x001,
- Mod_Control = 0x002,
- Mod_Meta = 0x004,
- Mod_Alt = 0x008,
-
- // Set for input Mouse_Relative mode, indicating that x,y are relative deltas.
- Mod_MouseRelative = 0x100,
-};
-
-//-------------------------------------------------------------------------------------
-// ***** SetupGraphicsDeviceSet
-
-typedef RenderDevice* (*RenderDeviceCreateFunc)(const Render::RendererParams&, void*);
-
-// SetupGraphicsDeviceSet is a PlatformCore::SetupGraphics initialization helper class,
-// used to build up a list of RenderDevices that can be used for rendering.
-// Specifying a smaller set allows application to avoid linking unused graphics devices.
-struct SetupGraphicsDeviceSet
-{
- SetupGraphicsDeviceSet(const char* typeArg, RenderDeviceCreateFunc createFunc)
- : pTypeArg(typeArg), pCreateDevice(createFunc), pNext(0) { }
- SetupGraphicsDeviceSet(const char* typeArg, RenderDeviceCreateFunc createFunc,
- const SetupGraphicsDeviceSet& next)
- : pTypeArg(typeArg), pCreateDevice(createFunc), pNext(&next) { }
-
- // Selects graphics object based on type string; returns 'this' if not found.
- const SetupGraphicsDeviceSet* PickSetupDevice(const char* typeArg) const;
-
- const char* pTypeArg;
- RenderDeviceCreateFunc pCreateDevice;
-
-private:
- const SetupGraphicsDeviceSet* pNext;
-};
-
-//-------------------------------------------------------------------------------------
-// ***** PlatformCore
-
-// PlatformCore defines abstract system window/viewport setup functionality and
-// maintains a renderer. This class is separated from Application because it can have
-// derived platform-specific implementations.
-// Specific implementation classes are hidden within platform-specific versions
-// such as Win32::PlatformCore.
-
-class PlatformCore : public NewOverrideBase
-{
-protected:
- Application* pApp;
- Ptr<RenderDevice> pRender;
- Ptr<GamepadManager> pGamepadManager;
- UInt64 StartupTicks;
-
-public:
- PlatformCore(Application *app);
- virtual ~PlatformCore() { }
- Application* GetApp() { return pApp; }
- RenderDevice* GetRenderer() const { return pRender; }
- GamepadManager* GetGamepadManager() const { return pGamepadManager; }
-
- virtual bool SetupWindow(int w, int h) = 0;
- // Destroys window and also releases renderer.
- virtual void DestroyWindow() = 0;
- virtual void Exit(int exitcode) = 0;
-
- virtual void ShowWindow(bool visible) = 0;
-
- virtual bool SetFullscreen(const Render::RendererParams& rp, int fullscreen);
-
- // Search for a matching graphics renderer based on type argument and initializes it.
- virtual RenderDevice* SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc,
- const char* gtype,
- const Render::RendererParams& rp) = 0;
-
- virtual void SetMouseMode(MouseMode mm) { OVR_UNUSED(mm); }
-
- virtual void GetWindowSize(int* w, int* h) const = 0;
-
- virtual void SetWindowTitle(const char*title) = 0;
- virtual void PlayMusicFile(const char *fileName) { OVR_UNUSED(fileName); }
- virtual int GetDisplayCount() { return 0; }
- virtual Render::DisplayId GetDisplay(int screen);
-
- // Get time since start of application in seconds.
- double GetAppTime() const;
-
- virtual String GetContentDirectory() const { return "."; }
-};
-
-//-------------------------------------------------------------------------------------
-// PlatformApp is a base application class from which end-user application
-// classes derive.
-
-class Application : public NewOverrideBase
-{
-protected:
- class PlatformCore* pPlatform;
-
-public:
- virtual ~Application() { }
-
- virtual int OnStartup(int argc, const char** argv) = 0;
- virtual void OnQuitRequest() { pPlatform->Exit(0); }
-
- virtual void OnIdle() {}
-
- virtual void OnKey(KeyCode key, int chr, bool down, int modifiers)
- { OVR_UNUSED4(key, chr, down, modifiers); }
- virtual void OnMouseMove(int x, int y, int modifiers)
- { OVR_UNUSED3(x, y, modifiers); }
-
- virtual void OnResize(int width, int height)
- { OVR_UNUSED2(width, height); }
-
- void SetPlatformCore(PlatformCore* p) { pPlatform = p; }
- PlatformCore* GetPlatformCore() const { return pPlatform; }
-
-
- // Static functions defined by OVR_PLATFORM_APP and used to initialize and
- // shut down the application class.
- static Application* CreateApplication();
- static void DestroyApplication(Application* app);
-};
-
-
-}}
-
-#endif
+/************************************************************************************ + +Filename : Platform.h +Content : Platform-independent app and rendering framework for Oculus samples +Created : September 6, 2012 +Authors : Andrew Reisse + +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Platform_h +#define OVR_Platform_h + +#include "OVR.h" + +#include "Kernel/OVR_KeyCodes.h" + +namespace OVR { namespace Render { + class RenderDevice; + struct DisplayId; + struct RendererParams; +}} + +namespace OVR { namespace Platform { + +using Render::RenderDevice; + +class PlatformCore; +class Application; +class GamepadManager; + +// MouseMode configures mouse input behavior of the app. Three states are +// currently supported: +// Normal - Reports absolute coordinates with cursor shown. +// Relative - Reports relative delta coordinates with cursor hidden +// until 'Esc' key is pressed or window loses focus. +// RelativeEscaped - Relative input is desired, but has been escaped until +// mouse is clicked in the window, which will return the state +// to relative. Absolute coordinates are reported. + +enum MouseMode +{ + Mouse_Normal, + Mouse_Relative, // Cursor hidden, mouse grab, OnMouseMove reports relative deltas. + Mouse_RelativeEscaped, // Clicking in window will return to Relative state. +}; + + +enum Modifiers +{ + Mod_Shift = 0x001, + Mod_Control = 0x002, + Mod_Meta = 0x004, + Mod_Alt = 0x008, + + // Set for input Mouse_Relative mode, indicating that x,y are relative deltas. + Mod_MouseRelative = 0x100, +}; + +//------------------------------------------------------------------------------------- +// ***** SetupGraphicsDeviceSet + +typedef RenderDevice* (*RenderDeviceCreateFunc)(const Render::RendererParams&, void*); + +// SetupGraphicsDeviceSet is a PlatformCore::SetupGraphics initialization helper class, +// used to build up a list of RenderDevices that can be used for rendering. +// Specifying a smaller set allows application to avoid linking unused graphics devices. +struct SetupGraphicsDeviceSet +{ + SetupGraphicsDeviceSet(const char* typeArg, RenderDeviceCreateFunc createFunc) + : pTypeArg(typeArg), pCreateDevice(createFunc), pNext(0) { } + SetupGraphicsDeviceSet(const char* typeArg, RenderDeviceCreateFunc createFunc, + const SetupGraphicsDeviceSet& next) + : pTypeArg(typeArg), pCreateDevice(createFunc), pNext(&next) { } + + // Selects graphics object based on type string; returns 'this' if not found. + const SetupGraphicsDeviceSet* PickSetupDevice(const char* typeArg) const; + + const char* pTypeArg; + RenderDeviceCreateFunc pCreateDevice; + +private: + const SetupGraphicsDeviceSet* pNext; +}; + +//------------------------------------------------------------------------------------- +// ***** PlatformCore + +// PlatformCore defines abstract system window/viewport setup functionality and +// maintains a renderer. This class is separated from Application because it can have +// derived platform-specific implementations. +// Specific implementation classes are hidden within platform-specific versions +// such as Win32::PlatformCore. + +class PlatformCore : public NewOverrideBase +{ +protected: + Application* pApp; + Ptr<RenderDevice> pRender; + Ptr<GamepadManager> pGamepadManager; + UInt64 StartupTicks; + +public: + PlatformCore(Application *app); + virtual ~PlatformCore() { } + Application* GetApp() { return pApp; } + RenderDevice* GetRenderer() const { return pRender; } + GamepadManager* GetGamepadManager() const { return pGamepadManager; } + + virtual bool SetupWindow(int w, int h) = 0; + // Destroys window and also releases renderer. + virtual void DestroyWindow() = 0; + virtual void Exit(int exitcode) = 0; + + virtual void ShowWindow(bool visible) = 0; + + virtual bool SetFullscreen(const Render::RendererParams& rp, int fullscreen); + + // Search for a matching graphics renderer based on type argument and initializes it. + virtual RenderDevice* SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc, + const char* gtype, + const Render::RendererParams& rp) = 0; + + virtual void SetMouseMode(MouseMode mm) { OVR_UNUSED(mm); } + + virtual void GetWindowSize(int* w, int* h) const = 0; + + virtual void SetWindowTitle(const char*title) = 0; + virtual void PlayMusicFile(const char *fileName) { OVR_UNUSED(fileName); } + virtual int GetDisplayCount() { return 0; } + virtual Render::DisplayId GetDisplay(int screen); + + // Get time since start of application in seconds. + double GetAppTime() const; + + virtual String GetContentDirectory() const { return "."; } +}; + +//------------------------------------------------------------------------------------- +// PlatformApp is a base application class from which end-user application +// classes derive. + +class Application : public NewOverrideBase +{ +protected: + class PlatformCore* pPlatform; + +public: + virtual ~Application() { } + + virtual int OnStartup(int argc, const char** argv) = 0; + virtual void OnQuitRequest() { pPlatform->Exit(0); } + + virtual void OnIdle() {} + + virtual void OnKey(KeyCode key, int chr, bool down, int modifiers) + { OVR_UNUSED4(key, chr, down, modifiers); } + virtual void OnMouseMove(int x, int y, int modifiers) + { OVR_UNUSED3(x, y, modifiers); } + + virtual void OnResize(int width, int height) + { OVR_UNUSED2(width, height); } + + void SetPlatformCore(PlatformCore* p) { pPlatform = p; } + PlatformCore* GetPlatformCore() const { return pPlatform; } + + + // Static functions defined by OVR_PLATFORM_APP and used to initialize and + // shut down the application class. + static Application* CreateApplication(); + static void DestroyApplication(Application* app); +}; + + +}} + +#endif diff --git a/Samples/CommonSrc/Platform/Platform_Default.h b/Samples/CommonSrc/Platform/Platform_Default.h index d82be10..e4fecf2 100644 --- a/Samples/CommonSrc/Platform/Platform_Default.h +++ b/Samples/CommonSrc/Platform/Platform_Default.h @@ -1,59 +1,59 @@ -/************************************************************************************
-
-Filename : Platform_Default.h
-Content : Default Platform class and RenderDevice selection file
-Created : October 4, 2012
-Authors :
-
-Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-*************************************************************************************/
-
-#ifndef OVR_Platform_Default_h
-#define OVR_Platform_Default_h
-
-// This should select proper header file for the platform/compiler.
-#include <Kernel/OVR_Types.h>
-
-#if defined(OVR_OS_WIN32)
- #include "Win32_Platform.h"
-
- #include "../Render/Render_D3D11_Device.h"
- #undef OVR_D3D_VERSION
- #include "../Render/Render_D3D10_Device.h"
-// #include "../Render/Render_GL_Win32_Device.h"
-
-// Modify this list or pass a smaller set to select a specific render device,
-// while avoiding linking extra classes.
- #define OVR_DEFAULT_RENDER_DEVICE_SET \
- SetupGraphicsDeviceSet("D3D11", &OVR::Render::D3D11::RenderDevice::CreateDevice, \
- SetupGraphicsDeviceSet("D3D10", &OVR::Render::D3D10::RenderDevice::CreateDevice) )
-
-#elif defined(OVR_OS_MAC) && !defined(OVR_MAC_X11)
- #include "OSX_Platform.h"
-
- #define OVR_DEFAULT_RENDER_DEVICE_SET \
- SetupGraphicsDeviceSet("GL", &OVR::Render::GL::OSX::RenderDevice::CreateDevice)
-
-#else
-
- #include "X11_Platform.h"
-
- #define OVR_DEFAULT_RENDER_DEVICE_SET \
- SetupGraphicsDeviceSet("GL", &OVR::Render::GL::X11::RenderDevice::CreateDevice)
-
-#endif
-
-#endif // OVR_Platform_Default_h
+/************************************************************************************ + +Filename : Platform_Default.h +Content : Default Platform class and RenderDevice selection file +Created : October 4, 2012 +Authors : + +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Platform_Default_h +#define OVR_Platform_Default_h + +// This should select proper header file for the platform/compiler. +#include <Kernel/OVR_Types.h> + +#if defined(OVR_OS_WIN32) + #include "Win32_Platform.h" + + #include "../Render/Render_D3D11_Device.h" + #undef OVR_D3D_VERSION + #include "../Render/Render_D3D10_Device.h" +// #include "../Render/Render_GL_Win32_Device.h" + +// Modify this list or pass a smaller set to select a specific render device, +// while avoiding linking extra classes. + #define OVR_DEFAULT_RENDER_DEVICE_SET \ + SetupGraphicsDeviceSet("D3D11", &OVR::Render::D3D11::RenderDevice::CreateDevice, \ + SetupGraphicsDeviceSet("D3D10", &OVR::Render::D3D10::RenderDevice::CreateDevice) ) + +#elif defined(OVR_OS_MAC) && !defined(OVR_MAC_X11) + #include "OSX_Platform.h" + + #define OVR_DEFAULT_RENDER_DEVICE_SET \ + SetupGraphicsDeviceSet("GL", &OVR::Render::GL::OSX::RenderDevice::CreateDevice) + +#else + + #include "Linux_Platform.h" + + #define OVR_DEFAULT_RENDER_DEVICE_SET \ + SetupGraphicsDeviceSet("GL", &OVR::Render::GL::Linux::RenderDevice::CreateDevice) + +#endif + +#endif // OVR_Platform_Default_h diff --git a/Samples/CommonSrc/Platform/Win32_Gamepad.cpp b/Samples/CommonSrc/Platform/Win32_Gamepad.cpp index db6524a..9b8793f 100644 --- a/Samples/CommonSrc/Platform/Win32_Gamepad.cpp +++ b/Samples/CommonSrc/Platform/Win32_Gamepad.cpp @@ -1,101 +1,101 @@ -/************************************************************************************
-
-Filename : Win32_Gamepad.cpp
-Content : Win32 implementation of Platform app infrastructure
-Created : May 6, 2013
-Authors : Lee Cooper
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-************************************************************************************/
-
-#include "Win32_Gamepad.h"
-
-namespace OVR { namespace Platform { namespace Win32 {
-
-GamepadManager::GamepadManager()
-{
- hXInputModule = ::LoadLibraryA("Xinput9_1_0.dll");
- if (hXInputModule)
- {
- pXInputGetState = (PFn_XInputGetState)
- ::GetProcAddress(hXInputModule, "XInputGetState");
- }
-}
-
-GamepadManager::~GamepadManager()
-{
- if (hXInputModule)
- ::FreeLibrary(hXInputModule);
-}
-
-static inline float GamepadStick(short in)
-{
- float v;
- if (abs(in) < 9000)
- return 0;
- else if (in > 9000)
- v = (float) in - 9000;
- else
- v = (float) in + 9000;
- return v / (32767 - 9000);
-}
-
-static inline float GamepadTrigger(BYTE in)
-{
- if (in < 30)
- return 0;
- else
- return float(in-30) / 225;
-}
-
-UInt32 GamepadManager::GetGamepadCount()
-{
- return 1;
-}
-
-bool GamepadManager::GetGamepadState(UInt32 index, GamepadState* pState)
-{
- // For now we just support one gamepad.
- OVR_UNUSED(index);
-
- if (pXInputGetState)
- {
- XINPUT_STATE xis;
-
- if (pXInputGetState(0, &xis))
- return false;
-
- if (xis.dwPacketNumber == LastPadPacketNo)
- return false;
-
- // State changed.
- pState->Buttons = xis.Gamepad.wButtons; // Currently matches Xinput
- pState->LT = GamepadTrigger(xis.Gamepad.bLeftTrigger);
- pState->RT = GamepadTrigger(xis.Gamepad.bRightTrigger);
- pState->LX = GamepadStick(xis.Gamepad.sThumbLX);
- pState->LY = GamepadStick(xis.Gamepad.sThumbLY);
- pState->RX = GamepadStick(xis.Gamepad.sThumbRX);
- pState->RY = GamepadStick(xis.Gamepad.sThumbRY);
-
- LastPadPacketNo = xis.dwPacketNumber;
-
- return true;
- }
-
- return false;
-}
-
-}}} // OVR::Platform::Win32
+/************************************************************************************ + +Filename : Win32_Gamepad.cpp +Content : Win32 implementation of Platform app infrastructure +Created : May 6, 2013 +Authors : Lee Cooper + +Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "Win32_Gamepad.h" + +namespace OVR { namespace Platform { namespace Win32 { + +GamepadManager::GamepadManager() +{ + hXInputModule = ::LoadLibraryA("Xinput9_1_0.dll"); + if (hXInputModule) + { + pXInputGetState = (PFn_XInputGetState) + ::GetProcAddress(hXInputModule, "XInputGetState"); + } +} + +GamepadManager::~GamepadManager() +{ + if (hXInputModule) + ::FreeLibrary(hXInputModule); +} + +static inline float GamepadStick(short in) +{ + float v; + if (abs(in) < 9000) + return 0; + else if (in > 9000) + v = (float) in - 9000; + else + v = (float) in + 9000; + return v / (32767 - 9000); +} + +static inline float GamepadTrigger(BYTE in) +{ + if (in < 30) + return 0; + else + return float(in-30) / 225; +} + +UInt32 GamepadManager::GetGamepadCount() +{ + return 1; +} + +bool GamepadManager::GetGamepadState(UInt32 index, GamepadState* pState) +{ + // For now we just support one gamepad. + OVR_UNUSED(index); + + if (pXInputGetState) + { + XINPUT_STATE xis; + + if (pXInputGetState(0, &xis)) + return false; + + if (xis.dwPacketNumber == LastPadPacketNo) + return false; + + // State changed. + pState->Buttons = xis.Gamepad.wButtons; // Currently matches Xinput + pState->LT = GamepadTrigger(xis.Gamepad.bLeftTrigger); + pState->RT = GamepadTrigger(xis.Gamepad.bRightTrigger); + pState->LX = GamepadStick(xis.Gamepad.sThumbLX); + pState->LY = GamepadStick(xis.Gamepad.sThumbLY); + pState->RX = GamepadStick(xis.Gamepad.sThumbRX); + pState->RY = GamepadStick(xis.Gamepad.sThumbRY); + + LastPadPacketNo = xis.dwPacketNumber; + + return true; + } + + return false; +} + +}}} // OVR::Platform::Win32 diff --git a/Samples/CommonSrc/Platform/Win32_Gamepad.h b/Samples/CommonSrc/Platform/Win32_Gamepad.h index 9066798..09815ae 100644 --- a/Samples/CommonSrc/Platform/Win32_Gamepad.h +++ b/Samples/CommonSrc/Platform/Win32_Gamepad.h @@ -1,54 +1,54 @@ -/************************************************************************************
-
-Filename : Win32_Gamepad.h
-Content : Win32 implementation of Gamepad functionality.
-Created : May 6, 2013
-Authors : Lee Cooper
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-************************************************************************************/
-
-#ifndef OVR_Win32_Gamepad_h
-#define OVR_Win32_Gamepad_h
-
-#include "Gamepad.h"
-
-#include <windows.h>
-#include <xinput.h>
-
-namespace OVR { namespace Platform { namespace Win32 {
-
-class GamepadManager : public Platform::GamepadManager
-{
-public:
- GamepadManager();
- ~GamepadManager();
-
- virtual UInt32 GetGamepadCount();
- virtual bool GetGamepadState(UInt32 index, GamepadState* pState);
-
-private:
- // Dynamically ink to XInput to simplify projects.
- HMODULE hXInputModule;
- typedef DWORD (WINAPI *PFn_XInputGetState)(DWORD dwUserIndex, XINPUT_STATE* pState);
- PFn_XInputGetState pXInputGetState;
-
- UInt32 LastPadPacketNo;
-};
-
-}}}
-
-#endif // OVR_Win32_Gamepad_h
+/************************************************************************************ + +Filename : Win32_Gamepad.h +Content : Win32 implementation of Gamepad functionality. +Created : May 6, 2013 +Authors : Lee Cooper + +Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Win32_Gamepad_h +#define OVR_Win32_Gamepad_h + +#include "Gamepad.h" + +#include <windows.h> +#include <xinput.h> + +namespace OVR { namespace Platform { namespace Win32 { + +class GamepadManager : public Platform::GamepadManager +{ +public: + GamepadManager(); + ~GamepadManager(); + + virtual UInt32 GetGamepadCount(); + virtual bool GetGamepadState(UInt32 index, GamepadState* pState); + +private: + // Dynamically ink to XInput to simplify projects. + HMODULE hXInputModule; + typedef DWORD (WINAPI *PFn_XInputGetState)(DWORD dwUserIndex, XINPUT_STATE* pState); + PFn_XInputGetState pXInputGetState; + + UInt32 LastPadPacketNo; +}; + +}}} + +#endif // OVR_Win32_Gamepad_h diff --git a/Samples/CommonSrc/Platform/Win32_Platform.cpp b/Samples/CommonSrc/Platform/Win32_Platform.cpp index cdd1e1f..9be7196 100644 --- a/Samples/CommonSrc/Platform/Win32_Platform.cpp +++ b/Samples/CommonSrc/Platform/Win32_Platform.cpp @@ -1,600 +1,600 @@ -/************************************************************************************
-
-Filename : Win32_Platform.cpp
-Content : Win32 implementation of Platform app infrastructure
-Created : September 6, 2012
-Authors : Andrew Reisse
-
-Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-************************************************************************************/
-
-#include "Kernel/OVR_System.h"
-#include "Kernel/OVR_Array.h"
-#include "Kernel/OVR_String.h"
-
-#include "Win32_Platform.h"
-#include "Win32_Gamepad.h"
-#include "../Render/Render_Device.h"
-
-namespace OVR { namespace Platform { namespace Win32 {
-
-
-PlatformCore::PlatformCore(Application* app, HINSTANCE hinst)
- : Platform::PlatformCore(app), hWnd(NULL), hInstance(hinst), Quit(0), MMode(Mouse_Normal),
- Cursor(0), Modifiers(0), WindowTitle("App")
-{
- pGamepadManager = *new Win32::GamepadManager();
-}
-
-PlatformCore::~PlatformCore()
-{
-}
-
-bool PlatformCore::SetupWindow(int w, int h)
-{
- WNDCLASS wc;
- memset(&wc, 0, sizeof(wc));
- wc.lpszClassName = L"OVRAppWindow";
- wc.style = CS_OWNDC;
- wc.lpfnWndProc = systemWindowProc;
- wc.cbWndExtra = sizeof(PlatformCore*);
-
- RegisterClass(&wc);
-
- Width = w;
- Height = h;
- RECT winSize;
- winSize.left = winSize.top = 0;
- winSize.right = Width;
- winSize.bottom = Height;
- AdjustWindowRect(&winSize, WS_OVERLAPPEDWINDOW, false);
- hWnd = CreateWindowA("OVRAppWindow", WindowTitle.ToCStr(), WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT,
- // 1950, 10,
- winSize.right-winSize.left, winSize.bottom-winSize.top,
- NULL, NULL, hInstance, (LPVOID)this);
- Modifiers = 0;
-
- Cursor = LoadCursor(NULL, IDC_CROSS);
-
- // Initialize Window center in screen coordinates
- POINT center = { Width / 2, Height / 2 };
- ::ClientToScreen(hWnd, ¢er);
- WindowCenter = center;
-
- if (MMode == Mouse_Relative)
- {
- ::SetCursorPos(WindowCenter.x, WindowCenter.y);
- ShowCursor(FALSE);
- }
- ::SetFocus(hWnd);
-
- return (hWnd != NULL);
-}
-
-void PlatformCore::DestroyWindow()
-{
- // Release renderer.
- pRender.Clear();
-
- // Release gamepad.
- pGamepadManager.Clear();
-
- // Release window resources.
- ::DestroyWindow(hWnd);
- UnregisterClass(L"OVRAppWindow", hInstance);
- hWnd = 0;
- Width = Height = 0;
-
- //DestroyCursor(Cursor);
- Cursor = 0;
-}
-
-void PlatformCore::ShowWindow(bool visible)
-{
- ::ShowWindow(hWnd, visible ? SW_SHOW : SW_HIDE);
-}
-
-void PlatformCore::SetMouseMode(MouseMode mm)
-{
- if (mm == MMode)
- return;
-
- if (hWnd)
- {
- if (mm == Mouse_Relative)
- {
- ShowCursor(FALSE);
- ::SetCursorPos(WindowCenter.x, WindowCenter.y);
- }
- else
- {
- if (MMode == Mouse_Relative)
- ShowCursor(TRUE);
- }
- }
- MMode = mm;
-}
-
-void PlatformCore::GetWindowSize(int* w, int* h) const
-{
- *w = Width;
- *h = Height;
-}
-
-
-void PlatformCore::SetWindowTitle(const char* title)
-{
- WindowTitle = title;
- if (hWnd)
- ::SetWindowTextA(hWnd, title);
-}
-
-static UByte KeyMap[][2] =
-{
- { VK_BACK, Key_Backspace },
- { VK_TAB, Key_Tab },
- { VK_CLEAR, Key_Clear },
- { VK_RETURN, Key_Return },
- { VK_SHIFT, Key_Shift },
- { VK_CONTROL, Key_Control },
- { VK_MENU, Key_Alt },
- { VK_PAUSE, Key_Pause },
- { VK_CAPITAL, Key_CapsLock },
- { VK_ESCAPE, Key_Escape },
- { VK_SPACE, Key_Space },
- { VK_PRIOR, Key_PageUp },
- { VK_NEXT, Key_PageDown },
- { VK_END, Key_End },
- { VK_HOME, Key_Home },
- { VK_LEFT, Key_Left },
- { VK_UP, Key_Up },
- { VK_RIGHT, Key_Right },
- { VK_DOWN, Key_Down },
- { VK_INSERT, Key_Insert },
- { VK_DELETE, Key_Delete },
- { VK_HELP, Key_Help },
-
- { VK_NUMLOCK, Key_NumLock },
- { VK_SCROLL, Key_ScrollLock },
-
- { VK_OEM_1, Key_Semicolon },
- { VK_OEM_PLUS, Key_Equal },
- { VK_OEM_COMMA, Key_Comma },
- { VK_OEM_MINUS, Key_Minus },
- { VK_OEM_PERIOD,Key_Period },
- { VK_OEM_2, Key_Slash },
- { VK_OEM_3, Key_Bar },
- { VK_OEM_4, Key_BracketLeft },
- { VK_OEM_5, Key_Backslash },
- { VK_OEM_6, Key_BracketRight },
- { VK_OEM_7, Key_Quote },
-
- { VK_OEM_AX, Key_OEM_AX }, // 'AX' key on Japanese AX keyboard.
- { VK_OEM_102, Key_OEM_102 }, // "<>" or "\|" on RT 102-key keyboard.
- { VK_ICO_HELP, Key_ICO_HELP },
- { VK_ICO_00, Key_ICO_00 }
-};
-
-
-KeyCode MapVKToKeyCode(unsigned vk)
-{
- unsigned key = Key_None;
-
- if ((vk >= '0') && (vk <= '9'))
- {
- key = vk - '0' + Key_Num0;
- }
- else if ((vk >= 'A') && (vk <= 'Z'))
- {
- key = vk - 'A' + Key_A;
- }
- else if ((vk >= VK_NUMPAD0) && (vk <= VK_DIVIDE))
- {
- key = vk - VK_NUMPAD0 + Key_KP_0;
- }
- else if ((vk >= VK_F1) && (vk <= VK_F15))
- {
- key = vk - VK_F1 + Key_F1;
- }
- else
- {
- for (unsigned i = 0; i< (sizeof(KeyMap) / sizeof(KeyMap[1])); i++)
- {
- if (vk == KeyMap[i][0])
- {
- key = KeyMap[i][1];
- break;
- }
- }
- }
-
- return (KeyCode)key;
-}
-
-
-
-LRESULT CALLBACK PlatformCore::systemWindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
-{
- PlatformCore* self;
-
- // WM_NCCREATE should be the first message to come it; use it to set class pointer.
- if (msg == WM_NCCREATE)
- {
- self = static_cast<PlatformCore*>(((LPCREATESTRUCT)lp)->lpCreateParams);
-
- if (self)
- {
- SetWindowLongPtr(hwnd, 0, (LONG_PTR)self);
- self->hWnd = hwnd;
- }
- }
- else
- {
- self = (PlatformCore*)(UPInt)GetWindowLongPtr(hwnd, 0);
- }
-
- return self ? self->WindowProc(msg, wp, lp) :
- DefWindowProc(hwnd, msg, wp, lp);
-}
-
-
-LRESULT PlatformCore::WindowProc(UINT msg, WPARAM wp, LPARAM lp)
-{
- KeyCode keyCode;
-
- switch (msg)
- {
- case WM_PAINT:
- {
- PAINTSTRUCT ps;
- BeginPaint(hWnd, &ps);
- EndPaint(hWnd, &ps);
- }
- return 0;
-
- case WM_SETCURSOR:
- ::SetCursor(Cursor);
- return 0;
-
- case WM_MOUSEMOVE:
- if (MMode == Mouse_Relative)
- {
- POINT newPos = { LOWORD(lp), HIWORD(lp) };
- ::ClientToScreen(hWnd, &newPos);
- if ((newPos.x == WindowCenter.x) && (newPos.y == WindowCenter.y))
- break;
- ::SetCursorPos(WindowCenter.x, WindowCenter.y);
-
- LONG dx = newPos.x - WindowCenter.x;
- LONG dy = newPos.y - WindowCenter.y;
-
- pApp->OnMouseMove(dx, dy, Mod_MouseRelative);
- }
- else
- {
- pApp->OnMouseMove(LOWORD(lp), HIWORD(lp), 0);
- }
- break;
-
- case WM_MOVE:
- {
- RECT r;
- GetClientRect(hWnd, &r);
- WindowCenter.x = r.right/2;
- WindowCenter.y = r.bottom/2;
- ::ClientToScreen(hWnd, &WindowCenter);
- }
- break;
-
- case WM_KEYDOWN:
- switch (wp)
- {
- case VK_CONTROL: Modifiers |= Mod_Control; break;
- case VK_MENU: Modifiers |= Mod_Alt; break;
- case VK_SHIFT: Modifiers |= Mod_Shift; break;
- case VK_LWIN:
- case VK_RWIN: Modifiers |= Mod_Meta; break;
- }
- if ((keyCode = MapVKToKeyCode((unsigned)wp)) != Key_None)
- pApp->OnKey(keyCode, 0, true, Modifiers);
-
- if (keyCode == Key_Escape && MMode == Mouse_Relative)
- {
- MMode = Mouse_RelativeEscaped;
- ShowCursor(TRUE);
- }
- break;
-
- case WM_KEYUP:
- if ((keyCode = MapVKToKeyCode((unsigned)wp)) != Key_None)
- pApp->OnKey(keyCode, 0, false, Modifiers);
- switch (wp)
- {
- case VK_CONTROL: Modifiers &= ~Mod_Control; break;
- case VK_MENU: Modifiers &= ~Mod_Alt; break;
- case VK_SHIFT: Modifiers &= ~Mod_Shift; break;
- case VK_LWIN:
- case VK_RWIN: Modifiers &= ~Mod_Meta; break;
- }
- break;
-
- case WM_LBUTTONDOWN:
- //App->OnMouseButton(0,
-
- ::SetCapture(hWnd);
-
- if (MMode == Mouse_RelativeEscaped)
- {
- ::SetCursorPos(WindowCenter.x, WindowCenter.y);
- ::ShowCursor(FALSE);
- MMode = Mouse_Relative;
- }
- break;
-
- case WM_LBUTTONUP:
- ReleaseCapture();
- break;
-
- case WM_SETFOCUS:
- // Do NOT restore the Relative mode here, since calling SetCursorPos
- // would screw up titlebar window dragging.
- // Let users click in the center instead to resume.
- break;
-
- case WM_KILLFOCUS:
- if (MMode == Mouse_Relative)
- {
- MMode = Mouse_RelativeEscaped;
- ShowCursor(TRUE);
- }
- break;
-
- case WM_SIZE:
- // Change window size as long as we're not being minimized.
- if (wp != SIZE_MINIMIZED)
- {
- Width = LOWORD(lp);
- Height = HIWORD(lp);
- if (pRender)
- pRender->SetWindowSize(Width, Height);
- pApp->OnResize(Width,Height);
- }
- break;
-
- case WM_STYLECHANGING:
- // Resize the window. This is needed because the size includes any present system controls, and
- // windows does not adjust it when changing to fullscreen.
- {
- STYLESTRUCT* pss = (STYLESTRUCT*)lp;
- RECT winSize;
- winSize.left = winSize.top = 0;
- winSize.right = Width;
- winSize.bottom = Height;
- int w = winSize.right-winSize.left;
- int h = winSize.bottom-winSize.top;
- AdjustWindowRect(&winSize, pss->styleNew, false);
- ::SetWindowPos(hWnd, NULL, 0, 0, w, h, SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
- }
- break;
-
- case WM_QUIT:
- case WM_CLOSE:
- pApp->OnQuitRequest();
- return false;
- }
-
- return DefWindowProc(hWnd, msg, wp, lp);
-}
-
-int PlatformCore::Run()
-{
- while (!Quit)
- {
- MSG msg;
- if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- else
- {
- pApp->OnIdle();
-
- // Keep sleeping when we're minimized.
- if (IsIconic(hWnd))
- {
- Sleep(10);
- }
- }
- }
-
- return ExitCode;
-}
-
-
-RenderDevice* PlatformCore::SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc,
- const char* type, const Render::RendererParams& rp)
-{
- const SetupGraphicsDeviceSet* setupDesc = setupGraphicsDesc.PickSetupDevice(type);
- OVR_ASSERT(setupDesc);
-
- pRender = *setupDesc->pCreateDevice(rp, (void*)hWnd);
- if (pRender)
- pRender->SetWindowSize(Width, Height);
-
- ::ShowWindow(hWnd, SW_RESTORE);
- return pRender.GetPtr();
-}
-
-
-void PlatformCore::PlayMusicFile(const char *fileName)
-{
- PlaySoundA(fileName, NULL, SND_FILENAME | SND_LOOP | SND_ASYNC);
-}
-
-
-//-----------------------------------------------------------------------------
-
-// Used to capture all the active monitor handles
-struct MonitorSet
-{
- enum { MaxMonitors = 8 };
- HMONITOR Monitors[MaxMonitors];
- int MonitorCount;
- int PrimaryCount;
-};
-
-
-BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData)
-{
- MonitorSet* monitorSet = (MonitorSet*)dwData;
- if (monitorSet->MonitorCount > MonitorSet::MaxMonitors)
- return FALSE;
-
- monitorSet->Monitors[monitorSet->MonitorCount] = hMonitor;
- monitorSet->MonitorCount++;
- return TRUE;
-};
-
-
-// Returns the number of active screens for extended displays and 1 for mirrored display
-int PlatformCore::GetDisplayCount()
-{
- // Get all the monitor handles
- MonitorSet monitors;
- monitors.MonitorCount = 0;
- EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&monitors);
-
- // Count the primary monitors
- int primary = 0;
- MONITORINFOEX info;
- for (int m=0; m < monitors.MonitorCount; m++)
- {
- info.cbSize = sizeof(MONITORINFOEX);
- GetMonitorInfo(monitors.Monitors[m], &info);
-
- if (info.dwFlags & MONITORINFOF_PRIMARY)
- primary++;
- }
-
- if (primary > 1)
- return 1; // Regard mirrored displays as a single screen
- else
- return monitors.MonitorCount; // Return all extended displays
-}
-
-//-----------------------------------------------------------------------------
-// Returns the device name for the given screen index or empty string for invalid index
-// The zero index will always return the primary screen name
-Render::DisplayId PlatformCore::GetDisplay(int screen)
-{
- // Get all the monitor handles
- MonitorSet monitors;
- monitors.MonitorCount = 0;
- EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&monitors);
-
- String screen_name;
-
- // Get the name of the suppled screen index with the requirement
- // that screen 0 is the primary monitor
- int non_primary_count = 0;
- MONITORINFOEX info;
- for (int m=0; m < monitors.MonitorCount; m++)
- {
- info.cbSize = sizeof(MONITORINFOEX);
- GetMonitorInfo(monitors.Monitors[m], &info);
-
- if (info.dwFlags & MONITORINFOF_PRIMARY)
- {
- if (screen == 0)
- {
- screen_name = info.szDevice;
- break;
- }
- }
- else
- {
- non_primary_count++;
- if (screen == non_primary_count)
- {
- screen_name = info.szDevice;
- break;
- }
- }
- }
-
- return screen_name;
-}
-
-
-}}}
-
-
-int WINAPI WinMain(HINSTANCE hinst, HINSTANCE prevInst, LPSTR inArgs, int show)
-{
- using namespace OVR;
- using namespace OVR::Platform;
-
- OVR_UNUSED2(prevInst, show);
-
- // CreateApplication must be the first call since it does OVR::System::Initialize.
- Application* app = Application::CreateApplication();
- Win32::PlatformCore* platform = new Win32::PlatformCore(app, hinst);
- // The platform attached to an app will be deleted by DestroyApplication.
- app->SetPlatformCore(platform);
-
- int exitCode = 0;
-
- // Nested scope for container destructors to shutdown before DestroyApplication.
- {
- Array<String> args;
- Array<const char*> argv;
- argv.PushBack("app");
-
- const char* p = inArgs;
- const char* pstart = inArgs;
- while (*p)
- {
- if (*p == ' ')
- {
- args.PushBack(String(pstart, p - pstart));
- while (*p == ' ')
- p++;
- pstart = p;
- }
- else
- {
- p++;
- }
- }
- if (p != pstart)
- args.PushBack(String(pstart, p - pstart));
- for (UPInt i = 0; i < args.GetSize(); i++)
- argv.PushBack(args[i].ToCStr());
-
- exitCode = app->OnStartup((int)argv.GetSize(), &argv[0]);
- if (!exitCode)
- exitCode = platform->Run();
- }
-
- // No OVR functions involving memory are allowed after this.
- Application::DestroyApplication(app);
- app = 0;
-
- OVR_DEBUG_STATEMENT(_CrtDumpMemoryLeaks());
- return exitCode;
-}
+/************************************************************************************ + +Filename : Win32_Platform.cpp +Content : Win32 implementation of Platform app infrastructure +Created : September 6, 2012 +Authors : Andrew Reisse + +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "Kernel/OVR_System.h" +#include "Kernel/OVR_Array.h" +#include "Kernel/OVR_String.h" + +#include "Win32_Platform.h" +#include "Win32_Gamepad.h" +#include "../Render/Render_Device.h" + +namespace OVR { namespace Platform { namespace Win32 { + + +PlatformCore::PlatformCore(Application* app, HINSTANCE hinst) + : Platform::PlatformCore(app), hWnd(NULL), hInstance(hinst), Quit(0), MMode(Mouse_Normal), + Cursor(0), Modifiers(0), WindowTitle("App") +{ + pGamepadManager = *new Win32::GamepadManager(); +} + +PlatformCore::~PlatformCore() +{ +} + +bool PlatformCore::SetupWindow(int w, int h) +{ + WNDCLASS wc; + memset(&wc, 0, sizeof(wc)); + wc.lpszClassName = L"OVRAppWindow"; + wc.style = CS_OWNDC; + wc.lpfnWndProc = systemWindowProc; + wc.cbWndExtra = sizeof(PlatformCore*); + + RegisterClass(&wc); + + Width = w; + Height = h; + RECT winSize; + winSize.left = winSize.top = 0; + winSize.right = Width; + winSize.bottom = Height; + AdjustWindowRect(&winSize, WS_OVERLAPPEDWINDOW, false); + hWnd = CreateWindowA("OVRAppWindow", WindowTitle.ToCStr(), WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, + // 1950, 10, + winSize.right-winSize.left, winSize.bottom-winSize.top, + NULL, NULL, hInstance, (LPVOID)this); + Modifiers = 0; + + Cursor = LoadCursor(NULL, IDC_CROSS); + + // Initialize Window center in screen coordinates + POINT center = { Width / 2, Height / 2 }; + ::ClientToScreen(hWnd, ¢er); + WindowCenter = center; + + if (MMode == Mouse_Relative) + { + ::SetCursorPos(WindowCenter.x, WindowCenter.y); + ShowCursor(FALSE); + } + ::SetFocus(hWnd); + + return (hWnd != NULL); +} + +void PlatformCore::DestroyWindow() +{ + // Release renderer. + pRender.Clear(); + + // Release gamepad. + pGamepadManager.Clear(); + + // Release window resources. + ::DestroyWindow(hWnd); + UnregisterClass(L"OVRAppWindow", hInstance); + hWnd = 0; + Width = Height = 0; + + //DestroyCursor(Cursor); + Cursor = 0; +} + +void PlatformCore::ShowWindow(bool visible) +{ + ::ShowWindow(hWnd, visible ? SW_SHOW : SW_HIDE); +} + +void PlatformCore::SetMouseMode(MouseMode mm) +{ + if (mm == MMode) + return; + + if (hWnd) + { + if (mm == Mouse_Relative) + { + ShowCursor(FALSE); + ::SetCursorPos(WindowCenter.x, WindowCenter.y); + } + else + { + if (MMode == Mouse_Relative) + ShowCursor(TRUE); + } + } + MMode = mm; +} + +void PlatformCore::GetWindowSize(int* w, int* h) const +{ + *w = Width; + *h = Height; +} + + +void PlatformCore::SetWindowTitle(const char* title) +{ + WindowTitle = title; + if (hWnd) + ::SetWindowTextA(hWnd, title); +} + +static UByte KeyMap[][2] = +{ + { VK_BACK, Key_Backspace }, + { VK_TAB, Key_Tab }, + { VK_CLEAR, Key_Clear }, + { VK_RETURN, Key_Return }, + { VK_SHIFT, Key_Shift }, + { VK_CONTROL, Key_Control }, + { VK_MENU, Key_Alt }, + { VK_PAUSE, Key_Pause }, + { VK_CAPITAL, Key_CapsLock }, + { VK_ESCAPE, Key_Escape }, + { VK_SPACE, Key_Space }, + { VK_PRIOR, Key_PageUp }, + { VK_NEXT, Key_PageDown }, + { VK_END, Key_End }, + { VK_HOME, Key_Home }, + { VK_LEFT, Key_Left }, + { VK_UP, Key_Up }, + { VK_RIGHT, Key_Right }, + { VK_DOWN, Key_Down }, + { VK_INSERT, Key_Insert }, + { VK_DELETE, Key_Delete }, + { VK_HELP, Key_Help }, + + { VK_NUMLOCK, Key_NumLock }, + { VK_SCROLL, Key_ScrollLock }, + + { VK_OEM_1, Key_Semicolon }, + { VK_OEM_PLUS, Key_Equal }, + { VK_OEM_COMMA, Key_Comma }, + { VK_OEM_MINUS, Key_Minus }, + { VK_OEM_PERIOD,Key_Period }, + { VK_OEM_2, Key_Slash }, + { VK_OEM_3, Key_Bar }, + { VK_OEM_4, Key_BracketLeft }, + { VK_OEM_5, Key_Backslash }, + { VK_OEM_6, Key_BracketRight }, + { VK_OEM_7, Key_Quote }, + + { VK_OEM_AX, Key_OEM_AX }, // 'AX' key on Japanese AX keyboard. + { VK_OEM_102, Key_OEM_102 }, // "<>" or "\|" on RT 102-key keyboard. + { VK_ICO_HELP, Key_ICO_HELP }, + { VK_ICO_00, Key_ICO_00 } +}; + + +KeyCode MapVKToKeyCode(unsigned vk) +{ + unsigned key = Key_None; + + if ((vk >= '0') && (vk <= '9')) + { + key = vk - '0' + Key_Num0; + } + else if ((vk >= 'A') && (vk <= 'Z')) + { + key = vk - 'A' + Key_A; + } + else if ((vk >= VK_NUMPAD0) && (vk <= VK_DIVIDE)) + { + key = vk - VK_NUMPAD0 + Key_KP_0; + } + else if ((vk >= VK_F1) && (vk <= VK_F15)) + { + key = vk - VK_F1 + Key_F1; + } + else + { + for (unsigned i = 0; i< (sizeof(KeyMap) / sizeof(KeyMap[1])); i++) + { + if (vk == KeyMap[i][0]) + { + key = KeyMap[i][1]; + break; + } + } + } + + return (KeyCode)key; +} + + + +LRESULT CALLBACK PlatformCore::systemWindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) +{ + PlatformCore* self; + + // WM_NCCREATE should be the first message to come it; use it to set class pointer. + if (msg == WM_NCCREATE) + { + self = static_cast<PlatformCore*>(((LPCREATESTRUCT)lp)->lpCreateParams); + + if (self) + { + SetWindowLongPtr(hwnd, 0, (LONG_PTR)self); + self->hWnd = hwnd; + } + } + else + { + self = (PlatformCore*)(UPInt)GetWindowLongPtr(hwnd, 0); + } + + return self ? self->WindowProc(msg, wp, lp) : + DefWindowProc(hwnd, msg, wp, lp); +} + + +LRESULT PlatformCore::WindowProc(UINT msg, WPARAM wp, LPARAM lp) +{ + KeyCode keyCode; + + switch (msg) + { + case WM_PAINT: + { + PAINTSTRUCT ps; + BeginPaint(hWnd, &ps); + EndPaint(hWnd, &ps); + } + return 0; + + case WM_SETCURSOR: + ::SetCursor(Cursor); + return 0; + + case WM_MOUSEMOVE: + if (MMode == Mouse_Relative) + { + POINT newPos = { LOWORD(lp), HIWORD(lp) }; + ::ClientToScreen(hWnd, &newPos); + if ((newPos.x == WindowCenter.x) && (newPos.y == WindowCenter.y)) + break; + ::SetCursorPos(WindowCenter.x, WindowCenter.y); + + LONG dx = newPos.x - WindowCenter.x; + LONG dy = newPos.y - WindowCenter.y; + + pApp->OnMouseMove(dx, dy, Mod_MouseRelative); + } + else + { + pApp->OnMouseMove(LOWORD(lp), HIWORD(lp), 0); + } + break; + + case WM_MOVE: + { + RECT r; + GetClientRect(hWnd, &r); + WindowCenter.x = r.right/2; + WindowCenter.y = r.bottom/2; + ::ClientToScreen(hWnd, &WindowCenter); + } + break; + + case WM_KEYDOWN: + switch (wp) + { + case VK_CONTROL: Modifiers |= Mod_Control; break; + case VK_MENU: Modifiers |= Mod_Alt; break; + case VK_SHIFT: Modifiers |= Mod_Shift; break; + case VK_LWIN: + case VK_RWIN: Modifiers |= Mod_Meta; break; + } + if ((keyCode = MapVKToKeyCode((unsigned)wp)) != Key_None) + pApp->OnKey(keyCode, 0, true, Modifiers); + + if (keyCode == Key_Escape && MMode == Mouse_Relative) + { + MMode = Mouse_RelativeEscaped; + ShowCursor(TRUE); + } + break; + + case WM_KEYUP: + if ((keyCode = MapVKToKeyCode((unsigned)wp)) != Key_None) + pApp->OnKey(keyCode, 0, false, Modifiers); + switch (wp) + { + case VK_CONTROL: Modifiers &= ~Mod_Control; break; + case VK_MENU: Modifiers &= ~Mod_Alt; break; + case VK_SHIFT: Modifiers &= ~Mod_Shift; break; + case VK_LWIN: + case VK_RWIN: Modifiers &= ~Mod_Meta; break; + } + break; + + case WM_LBUTTONDOWN: + //App->OnMouseButton(0, + + ::SetCapture(hWnd); + + if (MMode == Mouse_RelativeEscaped) + { + ::SetCursorPos(WindowCenter.x, WindowCenter.y); + ::ShowCursor(FALSE); + MMode = Mouse_Relative; + } + break; + + case WM_LBUTTONUP: + ReleaseCapture(); + break; + + case WM_SETFOCUS: + // Do NOT restore the Relative mode here, since calling SetCursorPos + // would screw up titlebar window dragging. + // Let users click in the center instead to resume. + break; + + case WM_KILLFOCUS: + if (MMode == Mouse_Relative) + { + MMode = Mouse_RelativeEscaped; + ShowCursor(TRUE); + } + break; + + case WM_SIZE: + // Change window size as long as we're not being minimized. + if (wp != SIZE_MINIMIZED) + { + Width = LOWORD(lp); + Height = HIWORD(lp); + if (pRender) + pRender->SetWindowSize(Width, Height); + pApp->OnResize(Width,Height); + } + break; + + case WM_STYLECHANGING: + // Resize the window. This is needed because the size includes any present system controls, and + // windows does not adjust it when changing to fullscreen. + { + STYLESTRUCT* pss = (STYLESTRUCT*)lp; + RECT winSize; + winSize.left = winSize.top = 0; + winSize.right = Width; + winSize.bottom = Height; + int w = winSize.right-winSize.left; + int h = winSize.bottom-winSize.top; + AdjustWindowRect(&winSize, pss->styleNew, false); + ::SetWindowPos(hWnd, NULL, 0, 0, w, h, SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER); + } + break; + + case WM_QUIT: + case WM_CLOSE: + pApp->OnQuitRequest(); + return false; + } + + return DefWindowProc(hWnd, msg, wp, lp); +} + +int PlatformCore::Run() +{ + while (!Quit) + { + MSG msg; + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + else + { + pApp->OnIdle(); + + // Keep sleeping when we're minimized. + if (IsIconic(hWnd)) + { + Sleep(10); + } + } + } + + return ExitCode; +} + + +RenderDevice* PlatformCore::SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc, + const char* type, const Render::RendererParams& rp) +{ + const SetupGraphicsDeviceSet* setupDesc = setupGraphicsDesc.PickSetupDevice(type); + OVR_ASSERT(setupDesc); + + pRender = *setupDesc->pCreateDevice(rp, (void*)hWnd); + if (pRender) + pRender->SetWindowSize(Width, Height); + + ::ShowWindow(hWnd, SW_RESTORE); + return pRender.GetPtr(); +} + + +void PlatformCore::PlayMusicFile(const char *fileName) +{ + PlaySoundA(fileName, NULL, SND_FILENAME | SND_LOOP | SND_ASYNC); +} + + +//----------------------------------------------------------------------------- + +// Used to capture all the active monitor handles +struct MonitorSet +{ + enum { MaxMonitors = 8 }; + HMONITOR Monitors[MaxMonitors]; + int MonitorCount; + int PrimaryCount; +}; + + +BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) +{ + MonitorSet* monitorSet = (MonitorSet*)dwData; + if (monitorSet->MonitorCount > MonitorSet::MaxMonitors) + return FALSE; + + monitorSet->Monitors[monitorSet->MonitorCount] = hMonitor; + monitorSet->MonitorCount++; + return TRUE; +}; + + +// Returns the number of active screens for extended displays and 1 for mirrored display +int PlatformCore::GetDisplayCount() +{ + // Get all the monitor handles + MonitorSet monitors; + monitors.MonitorCount = 0; + EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&monitors); + + // Count the primary monitors + int primary = 0; + MONITORINFOEX info; + for (int m=0; m < monitors.MonitorCount; m++) + { + info.cbSize = sizeof(MONITORINFOEX); + GetMonitorInfo(monitors.Monitors[m], &info); + + if (info.dwFlags & MONITORINFOF_PRIMARY) + primary++; + } + + if (primary > 1) + return 1; // Regard mirrored displays as a single screen + else + return monitors.MonitorCount; // Return all extended displays +} + +//----------------------------------------------------------------------------- +// Returns the device name for the given screen index or empty string for invalid index +// The zero index will always return the primary screen name +Render::DisplayId PlatformCore::GetDisplay(int screen) +{ + // Get all the monitor handles + MonitorSet monitors; + monitors.MonitorCount = 0; + EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&monitors); + + String screen_name; + + // Get the name of the suppled screen index with the requirement + // that screen 0 is the primary monitor + int non_primary_count = 0; + MONITORINFOEX info; + for (int m=0; m < monitors.MonitorCount; m++) + { + info.cbSize = sizeof(MONITORINFOEX); + GetMonitorInfo(monitors.Monitors[m], &info); + + if (info.dwFlags & MONITORINFOF_PRIMARY) + { + if (screen == 0) + { + screen_name = info.szDevice; + break; + } + } + else + { + non_primary_count++; + if (screen == non_primary_count) + { + screen_name = info.szDevice; + break; + } + } + } + + return screen_name; +} + + +}}} + + +int WINAPI WinMain(HINSTANCE hinst, HINSTANCE prevInst, LPSTR inArgs, int show) +{ + using namespace OVR; + using namespace OVR::Platform; + + OVR_UNUSED2(prevInst, show); + + // CreateApplication must be the first call since it does OVR::System::Initialize. + Application* app = Application::CreateApplication(); + Win32::PlatformCore* platform = new Win32::PlatformCore(app, hinst); + // The platform attached to an app will be deleted by DestroyApplication. + app->SetPlatformCore(platform); + + int exitCode = 0; + + // Nested scope for container destructors to shutdown before DestroyApplication. + { + Array<String> args; + Array<const char*> argv; + argv.PushBack("app"); + + const char* p = inArgs; + const char* pstart = inArgs; + while (*p) + { + if (*p == ' ') + { + args.PushBack(String(pstart, p - pstart)); + while (*p == ' ') + p++; + pstart = p; + } + else + { + p++; + } + } + if (p != pstart) + args.PushBack(String(pstart, p - pstart)); + for (UPInt i = 0; i < args.GetSize(); i++) + argv.PushBack(args[i].ToCStr()); + + exitCode = app->OnStartup((int)argv.GetSize(), &argv[0]); + if (!exitCode) + exitCode = platform->Run(); + } + + // No OVR functions involving memory are allowed after this. + Application::DestroyApplication(app); + app = 0; + + OVR_DEBUG_STATEMENT(_CrtDumpMemoryLeaks()); + return exitCode; +} diff --git a/Samples/CommonSrc/Platform/Win32_Platform.h b/Samples/CommonSrc/Platform/Win32_Platform.h index 5d40861..6081968 100644 --- a/Samples/CommonSrc/Platform/Win32_Platform.h +++ b/Samples/CommonSrc/Platform/Win32_Platform.h @@ -1,101 +1,101 @@ -/************************************************************************************
-
-Filename : Win32_Platform.h
-Content : Win32 implementation of Platform app infrastructure
-Created : September 6, 2012
-Authors : Andrew Reisse
-
-Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-************************************************************************************/
-
-#ifndef OVR_Win32_Platform_h
-#define OVR_Win32_Platform_h
-
-#include "Platform.h"
-#include <windows.h>
-
-
-namespace OVR { namespace Render {
- class RenderDevice;
- struct DisplayId;
-}}
-
-namespace OVR { namespace Platform { namespace Win32 {
-
-class PlatformCore : public Platform::PlatformCore
-{
- HWND hWnd;
- HINSTANCE hInstance;
- bool Quit;
- int ExitCode;
- int Width, Height;
-
- MouseMode MMode;
- POINT WindowCenter; // In desktop coordinates
- HCURSOR Cursor;
- int Modifiers;
- String WindowTitle;
-
- // Win32 static function that delegates to WindowProc member function.
- static LRESULT CALLBACK systemWindowProc(HWND window, UINT msg, WPARAM wp, LPARAM lp);
-
- LRESULT WindowProc(UINT msg, WPARAM wp, LPARAM lp);
-
-public:
- PlatformCore(Application* app, HINSTANCE hinst);
- ~PlatformCore();
-
- bool SetupWindow(int w, int h);
- void DestroyWindow();
- void ShowWindow(bool visible);
- void Exit(int exitcode) { Quit = 1; ExitCode = exitcode; }
-
- RenderDevice* SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc,
- const char* type,
- const Render::RendererParams& rp);
-
- void SetMouseMode(MouseMode mm);
- void GetWindowSize(int* w, int* h) const;
-
- void SetWindowTitle(const char*title);
- void PlayMusicFile(const char *fileName);
- int GetDisplayCount();
- Render::DisplayId GetDisplay(int screen);
-
- int Run();
-};
-
-
-// Win32 key conversion helper.
-KeyCode MapVKToKeyCode(unsigned vk);
-
-}}}
-
-
-// OVR_PLATFORM_APP_ARGS specifies the Application class to use for startup,
-// providing it with startup arguments.
-#define OVR_PLATFORM_APP_ARGS(AppClass, args) \
- OVR::Platform::Application* OVR::Platform::Application::CreateApplication() \
- { OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All)); \
- return new AppClass args; } \
- void OVR::Platform::Application::DestroyApplication(OVR::Platform::Application* app) \
- { OVR::Platform::PlatformCore* platform = app->pPlatform; \
- delete app; delete platform; OVR::System::Destroy(); };
-
-// OVR_PLATFORM_APP_ARGS specifies the Application startup class with no args.
-#define OVR_PLATFORM_APP(AppClass) OVR_PLATFORM_APP_ARGS(AppClass, ())
-
-#endif // OVR_Win32_Platform_h
+/************************************************************************************ + +Filename : Win32_Platform.h +Content : Win32 implementation of Platform app infrastructure +Created : September 6, 2012 +Authors : Andrew Reisse + +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Win32_Platform_h +#define OVR_Win32_Platform_h + +#include "Platform.h" +#include <windows.h> + + +namespace OVR { namespace Render { + class RenderDevice; + struct DisplayId; +}} + +namespace OVR { namespace Platform { namespace Win32 { + +class PlatformCore : public Platform::PlatformCore +{ + HWND hWnd; + HINSTANCE hInstance; + bool Quit; + int ExitCode; + int Width, Height; + + MouseMode MMode; + POINT WindowCenter; // In desktop coordinates + HCURSOR Cursor; + int Modifiers; + String WindowTitle; + + // Win32 static function that delegates to WindowProc member function. + static LRESULT CALLBACK systemWindowProc(HWND window, UINT msg, WPARAM wp, LPARAM lp); + + LRESULT WindowProc(UINT msg, WPARAM wp, LPARAM lp); + +public: + PlatformCore(Application* app, HINSTANCE hinst); + ~PlatformCore(); + + bool SetupWindow(int w, int h); + void DestroyWindow(); + void ShowWindow(bool visible); + void Exit(int exitcode) { Quit = 1; ExitCode = exitcode; } + + RenderDevice* SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc, + const char* type, + const Render::RendererParams& rp); + + void SetMouseMode(MouseMode mm); + void GetWindowSize(int* w, int* h) const; + + void SetWindowTitle(const char*title); + void PlayMusicFile(const char *fileName); + int GetDisplayCount(); + Render::DisplayId GetDisplay(int screen); + + int Run(); +}; + + +// Win32 key conversion helper. +KeyCode MapVKToKeyCode(unsigned vk); + +}}} + + +// OVR_PLATFORM_APP_ARGS specifies the Application class to use for startup, +// providing it with startup arguments. +#define OVR_PLATFORM_APP_ARGS(AppClass, args) \ + OVR::Platform::Application* OVR::Platform::Application::CreateApplication() \ + { OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All)); \ + return new AppClass args; } \ + void OVR::Platform::Application::DestroyApplication(OVR::Platform::Application* app) \ + { OVR::Platform::PlatformCore* platform = app->pPlatform; \ + delete app; delete platform; OVR::System::Destroy(); }; + +// OVR_PLATFORM_APP_ARGS specifies the Application startup class with no args. +#define OVR_PLATFORM_APP(AppClass) OVR_PLATFORM_APP_ARGS(AppClass, ()) + +#endif // OVR_Win32_Platform_h |