This commit is contained in:
2025-11-28 23:13:44 +05:30
commit a3a8e79709
7360 changed files with 1156074 additions and 0 deletions

View File

@ -0,0 +1,152 @@
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
#ifndef SAMPLE_PLATFORM_H
#define SAMPLE_PLATFORM_H
#include <RendererDesc.h>
#include <RendererWindow.h>
#include <RendererTexture2D.h>
namespace SampleFramework
{
class SampleApplication;
class SampleUserInput;
/* This class declares and partly implements platform-abstraction level.
Do not use platform-specific types and functions here.
*/
class SamplePlatform
{
protected:
SampleRenderer::RendererWindow* m_app;
SampleApplication* m_sf_app;
static SamplePlatform* m_platform;
public:
// access
static SamplePlatform* platform();
static void setPlatform(SamplePlatform*);
SampleApplication* application();
// creation
explicit SamplePlatform(SampleRenderer::RendererWindow* _app);
virtual ~SamplePlatform() = 0;
// System
virtual void showCursor(bool);
virtual size_t getCWD(char* path, size_t len);
virtual void setCWDToEXE(void);
virtual void popPathSpec(char *path);
virtual bool preOpenWindow(void * ptr);
virtual bool openWindow(physx::PxU32& width,
physx::PxU32& height,
const char* title,
bool fullscreen);
virtual bool useWindow(physx::PxU64 hwnd);
virtual void update();
virtual bool closeWindow();
virtual bool updateWindow();
virtual bool hasFocus() const;
virtual void setFocus(bool b);
virtual bool isOpen();
virtual physx::PxU64 getWindowHandle();
virtual void setWindowSize(physx::PxU32 width,
physx::PxU32 height);
virtual void getWindowSize(physx::PxU32& width, physx::PxU32& height);
virtual void getTitle(char *title, physx::PxU32 maxLength) const;
virtual void setTitle(const char *title);
virtual void setMouseCursorRecentering(bool val) {}
virtual bool getMouseCursorRecentering() const { return false; }
virtual void showMessage(const char* title, const char* message);
virtual bool saveBitmap(const char* fileName,
physx::PxU32 width,
physx::PxU32 height,
physx::PxU32 sizeInBytes,
const void* data);
virtual void* compileProgram(void * context,
const char* assetDir,
const char *programPath,
physx::PxU64 profile,
const char* passString,
const char *entry,
const char **args);
virtual void* initializeD3D9();
virtual void* initializeD3D11();
virtual bool isD3D9ok();
virtual const char* getPathSeparator();
virtual bool isD3D11ok();
// Rendering
virtual void initializeCGRuntimeCompiler();
virtual void initializeOGLDisplay(const SampleRenderer::RendererDesc& desc,
physx::PxU32& width,
physx::PxU32& height);
virtual physx::PxU32 initializeD3D9Display(void * presentParameters,
char* m_deviceName,
physx::PxU32& width,
physx::PxU32& height,
void * m_d3dDevice_out);
virtual physx::PxU32 initializeD3D11Display(void *dxgiSwapChainDesc,
char *m_deviceName,
physx::PxU32& width,
physx::PxU32& height,
void *m_d3dDevice_out,
void *m_d3dDeviceContext_out,
void *m_dxgiSwap_out);
virtual physx::PxU32 D3D9Present();
virtual void D3D9BlockUntilNotBusy(void * resource);
virtual void D3D9DeviceBlockUntilIdle();
virtual physx::PxU64 getD3D9TextureFormat(SampleRenderer::RendererTexture2D::Format format);
virtual physx::PxU32 D3D11Present(bool vsync);
virtual physx::PxU64 getD3D11TextureFormat(SampleRenderer::RendererTexture2D::Format format);
virtual void postInitializeOGLDisplay();
virtual void setOGLVsync(bool on);
virtual bool makeContextCurrent();
virtual bool isContextValid();
virtual void freeDisplay();
virtual void swapBuffers();
virtual void postRendererRelease();
virtual void preRendererSetup();
virtual void postRendererSetup(SampleRenderer::Renderer* renderer);
virtual void setupRendererDescription(SampleRenderer::RendererDesc& renDesc);
// Input
virtual void doInput();
virtual const SampleUserInput* getSampleUserInput() const = 0;
virtual SampleUserInput* getSampleUserInput() = 0;
virtual const char* getPlatformName() const { return NULL; }
// File System
virtual bool makeSureDirectoryPathExists(const char* dirPath);
};
SamplePlatform* createPlatform(SampleRenderer::RendererWindow* _app);
}
#endif

View File

@ -0,0 +1,229 @@
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
#ifndef SAMPLE_USER_INPUT_H
#define SAMPLE_USER_INPUT_H
#include <foundation/PxSimpleTypes.h>
#include <vector>
#include "PsString.h"
#if PX_VC
#pragma warning(push)
#pragma warning(disable:4702)
#include <map>
#pragma warning(pop)
#else
#include <map>
#endif
namespace SampleRenderer
{
class Renderer;
}
namespace SampleFramework
{
class InputEventListener;
struct UserInput
{
physx::PxU16 m_Id;
char m_IdName[256]; // this name is used for mapping (enum name)
char m_Name[256]; // this name is used for help
};
struct InputEvent
{
InputEvent(physx::PxU16 id, bool analog = false, float sens = 1.0f)
:m_Id(id), m_Analog(analog), m_Sensitivity(sens)
{
}
InputEvent(const InputEvent& e)
:m_Id(e.m_Id), m_Analog(e.m_Analog), m_Sensitivity(e.m_Sensitivity)
{
}
InputEvent()
: m_Analog(false), m_Sensitivity(1.0f)
{
}
physx::PxU16 m_Id;
bool m_Analog;
float m_Sensitivity;
};
struct InputEventName
{
char m_Name[256];
};
struct SampleInputData
{
char m_InputEventName[256];
char m_UserInputName[256];
};
struct SampleInputMapping
{
physx::PxU16 m_InputEventId;
size_t m_InputEventIndex;
physx::PxU16 m_UserInputId;
size_t m_UserInputIndex;
};
typedef std::vector<SampleInputData> T_SampleInputData;
enum InputType
{
UNDEFINED_INPUT = 0,
KEYBOARD_INPUT = (1 << 0),
GAMEPAD_INPUT = (1 << 1),
TOUCH_BUTTON_INPUT = (1 << 2),
TOUCH_PAD_INPUT = (1 << 3),
MOUSE_INPUT = (1 << 4),
};
enum InputDataReadState
{
STATE_INPUT_EVENT_ID,
STATE_USER_INPUT_ID,
STATE_DIGITAL,
STATE_INPUT_EVENT_NAME,
};
class SampleUserInput
{
public:
// key codes for console and raw key info
enum KeyCode
{
KEY_UNKNOWN = 0,
KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G,
KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N,
KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U,
KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z,
KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6,
KEY_7, KEY_8, KEY_9,
KEY_SPACE, KEY_RETURN, KEY_SHIFT, KEY_CONTROL, KEY_ESCAPE, KEY_COMMA,
KEY_NUMPAD0, KEY_NUMPAD1, KEY_NUMPAD2, KEY_NUMPAD3, KEY_NUMPAD4, KEY_NUMPAD5, KEY_NUMPAD6, KEY_NUMPAD7, KEY_NUMPAD8, KEY_NUMPAD9,
KEY_MULTIPLY, KEY_ADD, KEY_SEPARATOR, KEY_SUBTRACT, KEY_DECIMAL, KEY_DIVIDE,
KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6,
KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12,
KEY_TAB, KEY_PRIOR, KEY_NEXT,
KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT,
NUM_KEY_CODES,
};
SampleUserInput();
virtual ~SampleUserInput();
void registerUserInput(physx::PxU16 id, const char* idName, const char* name);
virtual const InputEvent* registerInputEvent(const InputEvent& inputEvent, physx::PxU16 userInputId, const char* name);
virtual const InputEvent* registerTouchInputEvent(const InputEvent& inputEvent, physx::PxU16 userInputId, const char* caption, const char* name)
{
PX_UNUSED(inputEvent);
PX_UNUSED(userInputId);
PX_UNUSED(caption);
return NULL;
}
virtual void unregisterInputEvent(physx::PxU16 inputEventId);
virtual void registerInputEvent(const SampleInputMapping& mapping);
virtual bool keyboardSupported() const { return false; }
virtual bool gamepadSupported() const { return false; }
virtual bool mouseSupported() const { return false; }
virtual InputType getInputType(const UserInput& ) const { return UNDEFINED_INPUT; }
void registerInputEventListerner(InputEventListener* listener) { mListener = listener; }
InputEventListener* getInputEventListener() const { return mListener; }
virtual void updateInput();
virtual void shutdown();
virtual void setRenderer(SampleRenderer::Renderer* ) {}
virtual bool getDigitalInputEventState(physx::PxU16 inputEventId ) const = 0;
virtual float getAnalogInputEventState(physx::PxU16 inputEventId ) const = 0;
const std::vector<size_t>* getUserInputs(physx::PxI32 inputEventId) const;
const std::vector<size_t>* getInputEvents(physx::PxU16 userInputId) const;
const std::vector<InputEvent>& getInputEventList() const { return mInputEvents; }
const std::vector<InputEventName>& getInputEventNameList() const { return mInputEventNames; }
const std::vector<UserInput>& getUserInputList() const { return mUserInputs; }
const std::map<physx::PxU16, std::vector<size_t> >& getInputEventUserInputMap() const { return mInputEventUserInputMap; }
physx::PxU16 getUserInputKeys(physx::PxU16 inputEventId, const char* names[], physx::PxU16 maxNames, physx::PxU32 inputTypeMask) const;
physx::PxI32 translateUserInputNameToId(const char* name, size_t& index) const;
physx::PxI32 translateInputEventNameToId(const char* name, size_t& index) const;
const char* translateInputEventIdToName(physx::PxI32 id) const;
const InputEvent* getInputEventSlow(physx::PxU16 inputEventId) const;
protected:
virtual void processGamepads();
std::vector<UserInput> mUserInputs;
std::vector<InputEvent> mInputEvents;
std::vector<InputEventName> mInputEventNames;
private:
InputEventListener* mListener;
std::map<physx::PxU16, std::vector<size_t> > mInputEventUserInputMap;
std::map<physx::PxU16, std::vector<size_t> > mUserInputInputEventMap;
};
class InputEventListener
{
public:
InputEventListener() {}
virtual ~InputEventListener() {}
// special case for text console
virtual void onKeyDownEx(SampleUserInput::KeyCode, physx::PxU32) {}
virtual void onPointerInputEvent(const InputEvent&, physx::PxU32, physx::PxU32, physx::PxReal, physx::PxReal, bool val) {}
virtual void onAnalogInputEvent(const InputEvent& , float val) = 0;
virtual void onDigitalInputEvent(const InputEvent& , bool val) = 0;
};
}
#endif

View File

@ -0,0 +1,42 @@
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
#ifndef SAMPLE_USER_INPUT_IDS_H
#define SAMPLE_USER_INPUT_IDS_H
#if defined (RENDERER_WINDOWS)
#include <windows/WindowsSampleUserInputIds.h>
#elif defined (RENDERER_LINUX)
#include <linux/LinuxSampleUserInputIds.h>
#elif defined (RENDERER_MACOSX)
#include <osx/OSXSampleUserInputIds.h>
#else
#error Unknown platform!
#endif
#endif

View File

@ -0,0 +1,131 @@
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
#ifndef LINUX_SAMPLE_PLATFORM_H
#define LINUX_SAMPLE_PLATFORM_H
#include <SamplePlatform.h>
#include <linux/LinuxSampleUserInput.h>
#include <X11/Xlib.h>
#include <X11/extensions/xf86vmode.h>
#if defined(RENDERER_ENABLE_OPENGL)
#define GLEW_STATIC
#include <GL/glew.h>
#endif
#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/glu.h>
namespace SampleFramework
{
class LinuxPlatform : public SamplePlatform
{
public:
explicit LinuxPlatform(SampleRenderer::RendererWindow* _app);
// System
virtual void showCursor(bool);
virtual void setCWDToEXE(void);
const char* getPathSeparator();
bool makeSureDirectoryPathExists(const char* dirPath);
void showMessage(const char* title, const char* message);
// Rendering
virtual void initializeOGLDisplay(const SampleRenderer::RendererDesc& desc,
physx::PxU32& width,
physx::PxU32& height);
virtual void postInitializeOGLDisplay();
virtual void postRendererSetup(SampleRenderer::Renderer* renderer);
virtual void setupRendererDescription(SampleRenderer::RendererDesc& renDesc);
virtual bool hasFocus() const;
virtual void setFocus(bool b);
virtual void getTitle(char *title, physx::PxU32 maxLength) const;
virtual void setTitle(const char *title);
virtual bool updateWindow();
virtual bool openWindow(physx::PxU32& width,
physx::PxU32& height,
const char* title,
bool fullscreen);
virtual void getWindowSize(physx::PxU32& width, physx::PxU32& height);
virtual void update();
virtual bool closeWindow();
virtual void freeDisplay();
virtual void swapBuffers();
virtual void* compileProgram(void * context,
const char* assetDir,
const char *programPath,
physx::PxU64 profile,
const char* passString,
const char *entry,
const char **args);
// Input
virtual void doInput();
virtual const SampleUserInput* getSampleUserInput() const { return &m_linuxSampleUserInput; }
virtual SampleUserInput* getSampleUserInput() { return &m_linuxSampleUserInput; }
virtual const char* getPlatformName() const { return "linux"; }
virtual void setMouseCursorRecentering(bool val);
virtual bool getMouseCursorRecentering() const;
physx::PxVec2 getMouseCursorPos() const { return m_mouseCursorPos; }
void setMouseCursorPos(const physx::PxVec2& pos) { m_mouseCursorPos = pos; }
void recenterMouseCursor(bool generateEvent);
LinuxSampleUserInput& getLinuxSampleUserInput() { return m_linuxSampleUserInput; }
const LinuxSampleUserInput& getLinuxSampleUserInput() const { return m_linuxSampleUserInput; }
protected:
bool filterKeyRepeat(const XEvent& keyReleaseEvent);
void handleMouseEvent(const XEvent& event);
void showCursorInternal(bool show);
protected:
Display* m_display;
XVisualInfo* m_visualInfo;
Window m_window;
Atom m_wmDelete;
GLXContext m_glxContext;
XF86VidModeModeInfo m_desktopMode;
int m_screen;
bool m_isFullScreen;
bool m_hasFocus;
bool m_hasContentFocus;
physx::PxU32 m_windowWidth;
physx::PxU32 m_windowHeight;
LinuxSampleUserInput m_linuxSampleUserInput;
physx::PxVec2 m_mouseCursorPos;
bool m_recenterMouseCursor;
bool m_showCursor;
};
}
#endif

View File

@ -0,0 +1,76 @@
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
#ifndef LINUX_SAMPLE_USER_INPUT_H
#define LINUX_SAMPLE_USER_INPUT_H
#include <X11/Xlib.h>
#include <SampleUserInput.h>
#include <linux/LinuxSampleUserInputIds.h>
#include <set>
namespace SampleFramework
{
class LinuxSampleUserInput: public SampleUserInput
{
public:
LinuxSampleUserInput();
~LinuxSampleUserInput();
void doOnMouseMove( physx::PxU32 x, physx::PxU32 y, physx::PxReal dx, physx::PxReal dy, physx::PxU16 button);
void doOnMouseDown( physx::PxU32 x, physx::PxU32 y, physx::PxU16 button);
void doOnMouseUp( physx::PxU32 x, physx::PxU32 y, physx::PxU16 button);
void doOnKeyDown( KeySym keySym, physx::PxU16 keyCode, physx::PxU8 ascii);
void doOnKeyUp( KeySym keySym, physx::PxU16 keyCode, physx::PxU8 ascii);
virtual void updateInput();
virtual void shutdown();
virtual bool keyboardSupported() const { return true; }
virtual bool gamepadSupported() const { return false; }
virtual bool mouseSupported() const { return true; }
virtual bool getDigitalInputEventState(physx::PxU16 inputEventId) const;
virtual float getAnalogInputEventState(physx::PxU16 inputEventId) const;
protected:
void registerScanCode(LinuxSampleUserInputIds scanCodeId, physx::PxU16 scanCode, LinuxSampleUserInputIds nameId, const char* name);
LinuxSampleUserInputIds getInputIdFromKeySym(const KeySym keySym) const;
LinuxSampleUserInputIds getInputIdFromMouseButton(const physx::PxU16 button) const;
const UserInput* getUserInputFromId(LinuxSampleUserInputIds id) const;
std::map<physx::PxU16, physx::PxU16> m_ScanCodesMap;
std::map<physx::PxU16,float> m_AnalogStates;
std::map<physx::PxU16,bool> m_DigitalStates;
};
}
#endif

View File

@ -0,0 +1,141 @@
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
#ifndef LINUX_SAMPLE_USER_INPUT_IDS_H
#define LINUX_SAMPLE_USER_INPUT_IDS_H
namespace SampleFramework
{
enum LinuxSampleUserInputIds
{
LINUXKEY_UNKNOWN = 0,
// the following keys are keyboard layout dependent
// its not a complete list
LINUXKEY_A,
LINUXKEY_B,
LINUXKEY_C,
LINUXKEY_D,
LINUXKEY_E,
LINUXKEY_F,
LINUXKEY_G,
LINUXKEY_H,
LINUXKEY_I,
LINUXKEY_J,
LINUXKEY_K,
LINUXKEY_L,
LINUXKEY_M,
LINUXKEY_N,
LINUXKEY_O,
LINUXKEY_P,
LINUXKEY_Q,
LINUXKEY_R,
LINUXKEY_S,
LINUXKEY_T,
LINUXKEY_U,
LINUXKEY_V,
LINUXKEY_W,
LINUXKEY_X,
LINUXKEY_Y,
LINUXKEY_Z,
LINUXKEY_0,
LINUXKEY_1,
LINUXKEY_2,
LINUXKEY_3,
LINUXKEY_4,
LINUXKEY_5,
LINUXKEY_6,
LINUXKEY_7,
LINUXKEY_8,
LINUXKEY_9,
LINUXKEY_NUMPAD0,
LINUXKEY_NUMPAD1,
LINUXKEY_NUMPAD2,
LINUXKEY_NUMPAD3,
LINUXKEY_NUMPAD4,
LINUXKEY_NUMPAD5,
LINUXKEY_NUMPAD6,
LINUXKEY_NUMPAD7,
LINUXKEY_NUMPAD8,
LINUXKEY_NUMPAD9,
LINUXKEY_SHIFT,
LINUXKEY_CONTROL,
LINUXKEY_SPACE,
LINUXKEY_RETURN,
LINUXKEY_ESCAPE,
LINUXKEY_COMMA,
LINUXKEY_DIVIDE,
LINUXKEY_SUBTRACT,
LINUXKEY_ADD,
LINUXKEY_F1,
LINUXKEY_F2,
LINUXKEY_F3,
LINUXKEY_F4,
LINUXKEY_F5,
LINUXKEY_F6,
LINUXKEY_F7,
LINUXKEY_F8,
LINUXKEY_F9,
LINUXKEY_F10,
LINUXKEY_F11,
LINUXKEY_F12,
LINUXKEY_TAB,
LINUXKEY_BACKSPACE,
LINUXKEY_PRIOR,
LINUXKEY_NEXT,
LINUXKEY_UP,
LINUXKEY_DOWN,
LINUXKEY_LEFT,
LINUXKEY_RIGHT,
MOUSE_BUTTON_LEFT,
MOUSE_BUTTON_RIGHT,
MOUSE_BUTTON_CENTER,
MOUSE_MOVE,
SCAN_CODE_UP ,
SCAN_CODE_DOWN ,
SCAN_CODE_LEFT,
SCAN_CODE_RIGHT,
SCAN_CODE_FORWARD,
SCAN_CODE_BACKWARD,
SCAN_CODE_L,
SCAN_CODE_9,
SCAN_CODE_0,
NUM_KEY_CODES,
};
}
#endif

View File

@ -0,0 +1,164 @@
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
#ifndef WINDOWS_SAMPLE_PLATFORM_H
#define WINDOWS_SAMPLE_PLATFORM_H
#include <SamplePlatform.h>
#include <windows/WindowsSampleUserInput.h>
struct IDirect3D9;
struct IDirect3DDevice9;
struct ID3D11Device;
struct ID3D11DeviceContext;
struct IDXGIFactory1;
struct IDXGISwapChain;
namespace SampleFramework
{
class WindowsPlatform : public SamplePlatform
{
public:
explicit WindowsPlatform(SampleRenderer::RendererWindow* _app);
virtual ~WindowsPlatform();
// System
virtual void showCursor(bool);
virtual void postRendererSetup(SampleRenderer::Renderer* renderer);
virtual size_t getCWD(char* path, size_t len);
virtual void setCWDToEXE(void);
virtual bool openWindow(physx::PxU32& width,
physx::PxU32& height,
const char* title,
bool fullscreen);
virtual bool useWindow(physx::PxU64 hwnd);
virtual void update();
virtual bool isOpen();
virtual bool closeWindow();
virtual bool hasFocus() const;
virtual void getTitle(char *title, physx::PxU32 maxLength) const;
virtual void setTitle(const char *title);
virtual void setFocus(bool b);
virtual physx::PxU64 getWindowHandle();
virtual void setWindowSize(physx::PxU32 width,
physx::PxU32 height);
virtual void getWindowSize(physx::PxU32& width, physx::PxU32& height);
virtual void showMessage(const char* title, const char* message);
virtual bool saveBitmap(const char* fileName,
physx::PxU32 width,
physx::PxU32 height,
physx::PxU32 sizeInBytes,
const void* data);
virtual void* compileProgram(void * context,
const char* assetDir,
const char *programPath,
physx::PxU64 profile,
const char* passString,
const char *entry,
const char **args);
virtual void* initializeD3D9();
virtual bool isD3D9ok();
virtual void* initializeD3D11();
virtual bool isD3D11ok();
// Rendering
virtual void initializeOGLDisplay(const SampleRenderer::RendererDesc& desc,
physx::PxU32& width,
physx::PxU32& height);
virtual void postInitializeOGLDisplay();
virtual void setOGLVsync(bool on);
virtual physx::PxU32 initializeD3D9Display(void * presentParameters,
char* m_deviceName,
physx::PxU32& width,
physx::PxU32& height,
void * m_d3dDevice_out);
virtual physx::PxU32 initializeD3D11Display(void *dxgiSwapChainDesc,
char *m_deviceName,
physx::PxU32& width,
physx::PxU32& height,
void *m_d3dDevice_out,
void *m_d3dDeviceContext_out,
void *m_dxgiSwap_out);
virtual physx::PxU32 D3D9Present();
virtual physx::PxU64 getD3D9TextureFormat(SampleRenderer::RendererTexture2D::Format format);
virtual physx::PxU32 D3D11Present(bool vsync);
virtual physx::PxU64 getD3D11TextureFormat(SampleRenderer::RendererTexture2D::Format format);
virtual bool makeContextCurrent();
virtual void freeDisplay();
virtual bool isContextValid();
virtual void swapBuffers();
virtual void setupRendererDescription(SampleRenderer::RendererDesc& renDesc);
// Input
virtual void doInput();
// File System
virtual bool makeSureDirectoryPathExists(const char* dirPath);
virtual const SampleUserInput* getSampleUserInput() const { return &m_windowsSampleUserInput; }
virtual SampleUserInput* getSampleUserInput() { return &m_windowsSampleUserInput; }
WindowsSampleUserInput& getWindowsSampleUserInput() { return m_windowsSampleUserInput; }
const WindowsSampleUserInput& getWindowsSampleUserInput() const { return m_windowsSampleUserInput; }
virtual const char* getPlatformName() const { return m_platformName; }
virtual void setMouseCursorRecentering(bool val);
virtual bool getMouseCursorRecentering() const;
physx::PxVec2 getMouseCursorPos() const { return m_mouseCursorPos; }
void setMouseCursorPos(const physx::PxVec2& pos) { m_mouseCursorPos = pos; }
void recenterMouseCursor(bool generateEvent);
void setWorkaroundMouseMoved() { m_workaroundMouseMoved = true; }
protected:
IDirect3D9* m_d3d;
IDirect3DDevice9* m_d3dDevice;
IDXGIFactory1* m_dxgiFactory;
IDXGISwapChain* m_dxgiSwap;
ID3D11Device* m_d3d11Device;
ID3D11DeviceContext* m_d3d11DeviceContext;
HWND m_hwnd;
HDC m_hdc;
HGLRC m_hrc;
HMODULE m_library;
HMODULE m_dxgiLibrary;
HMODULE m_d3d11Library;
bool m_ownsWindow;
bool m_isHandlingMessages;
bool m_destroyWindow;
bool m_hasFocus;
bool m_showCursor;
char m_platformName[256];
WindowsSampleUserInput m_windowsSampleUserInput;
physx::PxVec2 m_mouseCursorPos;
bool m_workaroundMouseMoved;
bool m_recenterMouseCursor;
bool m_vsync;
};
}
#endif

View File

@ -0,0 +1,158 @@
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
#ifndef WINDOWS_SAMPLE_USER_INPUT_H
#define WINDOWS_SAMPLE_USER_INPUT_H
#include <SampleUserInput.h>
#include <windows/WindowsSampleUserInputIds.h>
#include <WTypes.h>
#include <XInput.h>
namespace SampleFramework
{
class WindowsSampleUserInput: public SampleUserInput
{
public:
enum KeyEventFlag
{
KEY_EVENT_NONE = 0,
KEY_EVENT_UP,
KEY_EVENT_DOWN,
};
enum MouseButtons
{
LEFT_MOUSE_BUTTON,
RIGHT_MOUSE_BUTTON,
CENTER_MOUSE_BUTTON,
};
struct KeyEvent
{
WPARAM m_Param;
USHORT m_ScanCode;
KeyEventFlag m_Flags;
};
struct InputState
{
InputState()
{
};
InputState(bool val)
{
m_State = val;
};
InputState(float val)
{
m_Value = val;
};
union
{
bool m_State;
float m_Value;
};
};
WindowsSampleUserInput();
~WindowsSampleUserInput();
bool keyCodeToASCII( WindowsSampleUserInputIds code, char& c )
{
if( code >= KEY_A && code <= KEY_Z )
{
c = (char)code + 'A' - 1;
}
else if( code >= KEY_0 && code <= KEY_9 )
{
c = (char)code + '0' - 1;
}
else if( code == KEY_SPACE )
{
c = ' ';
}
else
{
return false;
}
return true;
}
void doOnMouseMove(physx::PxU32 x, physx::PxU32 y, physx::PxReal dx, physx::PxReal dy, WindowsSampleUserInputIds button);
void doOnMouseButton(physx::PxU32 x, physx::PxU32 y, MouseButtons button, bool down);
void onKeyDownEx(WPARAM wParam);
void onKeyDown(WPARAM wParam, LPARAM lParam);
void onKeyUp(WPARAM wParam, LPARAM lParam);
void onKeyEvent(const KeyEvent& keyEvent);
void onGamepadButton(physx::PxU32 buttonIndex, bool buttonDown);
void onGamepadAnalogButton(physx::PxU32 buttonIndex,const BYTE oldValue,const BYTE newValue);
void onGamepadAxis(physx::PxU32 axis, physx::PxReal val);
virtual void updateInput();
virtual void processGamepads();
virtual void shutdown();
virtual bool keyboardSupported() const { return true; }
virtual bool gamepadSupported() const;
virtual bool mouseSupported() const { return true; }
virtual InputType getInputType(const UserInput&) const;
virtual bool getDigitalInputEventState(physx::PxU16 inputEventId ) const;
virtual float getAnalogInputEventState(physx::PxU16 inputEventId ) const;
protected:
WindowsSampleUserInputIds getKeyCode(WPARAM wParam) const;
SampleUserInput::KeyCode getSampleUserInputKeyCode(WPARAM wParam) const;
const UserInput* getUserInputFromId(WindowsSampleUserInputIds id) const;
bool hasXInput() const { return mpXInputGetState && mpXInputGetCapabilities; }
std::map<physx::PxU16, physx::PxU16> mScanCodesMap;
std::map<physx::PxU16,float> mAnalogStates;
std::map<physx::PxU16,bool> mDigitalStates;
bool mGamePadConnected;
physx::PxU32 mConnectedPad;
typedef DWORD (WINAPI *LPXINPUTGETSTATE)(DWORD, XINPUT_STATE*);
typedef DWORD (WINAPI *LPXINPUTGETCAPABILITIES)(DWORD,DWORD,XINPUT_CAPABILITIES*);
HMODULE mXInputLibrary;
LPXINPUTGETSTATE mpXInputGetState;
LPXINPUTGETCAPABILITIES mpXInputGetCapabilities;
};
}
#endif

View File

@ -0,0 +1,178 @@
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
#ifndef WINDOWS_SAMPLE_USER_INPUT_IDS_H
#define WINDOWS_SAMPLE_USER_INPUT_IDS_H
namespace SampleFramework
{
enum WindowsSampleUserInputIds
{
WKEY_UNKNOWN = 0,
WKEY_DEFINITION_START,
WKEY_A,
WKEY_B,
WKEY_C,
WKEY_D,
WKEY_E,
WKEY_F,
WKEY_G,
WKEY_H,
WKEY_I,
WKEY_J,
WKEY_K,
WKEY_L,
WKEY_M,
WKEY_N,
WKEY_O,
WKEY_P,
WKEY_Q,
WKEY_R,
WKEY_S,
WKEY_T,
WKEY_U,
WKEY_V,
WKEY_W,
WKEY_X,
WKEY_Y,
WKEY_Z,
WKEY_0,
WKEY_1,
WKEY_2,
WKEY_3,
WKEY_4,
WKEY_5,
WKEY_6,
WKEY_7,
WKEY_8,
WKEY_9,
WKEY_SPACE,
WKEY_RETURN,
WKEY_SHIFT,
WKEY_CONTROL,
WKEY_ESCAPE,
WKEY_COMMA,
WKEY_NUMPAD0,
WKEY_NUMPAD1,
WKEY_NUMPAD2,
WKEY_NUMPAD3,
WKEY_NUMPAD4,
WKEY_NUMPAD5,
WKEY_NUMPAD6,
WKEY_NUMPAD7,
WKEY_NUMPAD8,
WKEY_NUMPAD9,
WKEY_MULTIPLY,
WKEY_ADD,
WKEY_SEPARATOR,
WKEY_SUBTRACT,
WKEY_DECIMAL,
WKEY_DIVIDE,
WKEY_F1,
WKEY_F2,
WKEY_F3,
WKEY_F4,
WKEY_F5,
WKEY_F6,
WKEY_F7,
WKEY_F8,
WKEY_F9,
WKEY_F10,
WKEY_F11,
WKEY_F12,
WKEY_TAB,
WKEY_BACKSPACE,
WKEY_PRIOR,
WKEY_NEXT,
WKEY_UP,
WKEY_DOWN,
WKEY_LEFT,
WKEY_RIGHT,
SCAN_CODE_UP ,
SCAN_CODE_DOWN ,
SCAN_CODE_LEFT,
SCAN_CODE_RIGHT,
SCAN_CODE_FORWARD,
SCAN_CODE_BACKWARD,
SCAN_CODE_LEFT_SHIFT,
SCAN_CODE_SPACE,
SCAN_CODE_L,
SCAN_CODE_9,
SCAN_CODE_0,
WKEY_DEFINITION_END,
MOUSE_DEFINITION_START,
MOUSE_BUTTON_LEFT,
MOUSE_BUTTON_RIGHT,
MOUSE_BUTTON_CENTER,
MOUSE_MOVE,
MOUSE_DEFINITION_END,
GAMEPAD_DEFINITION_START,
GAMEPAD_DIGI_UP,
GAMEPAD_DIGI_DOWN,
GAMEPAD_DIGI_LEFT,
GAMEPAD_DIGI_RIGHT,
GAMEPAD_START,
GAMEPAD_SELECT,
GAMEPAD_LEFT_STICK,
GAMEPAD_RIGHT_STICK,
GAMEPAD_NORTH,
GAMEPAD_SOUTH,
GAMEPAD_WEST,
GAMEPAD_EAST,
GAMEPAD_LEFT_SHOULDER_TOP,
GAMEPAD_RIGHT_SHOULDER_TOP,
GAMEPAD_LEFT_SHOULDER_BOT,
GAMEPAD_RIGHT_SHOULDER_BOT,
GAMEPAD_RIGHT_STICK_X,
GAMEPAD_RIGHT_STICK_Y,
GAMEPAD_LEFT_STICK_X ,
GAMEPAD_LEFT_STICK_Y ,
GAMEPAD_DEFINITION_END,
NUM_KEY_CODES,
};
}
#endif

View File

@ -0,0 +1,316 @@
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
#include <PsString.h>
#include <SamplePlatform.h>
using namespace SampleFramework;
using namespace physx;
SamplePlatform* SamplePlatform::m_platform = NULL;
SamplePlatform* SamplePlatform::platform()
{
RENDERER_ASSERT(SamplePlatform::m_platform, "SamplePlatform was not initialized!");
if(SamplePlatform::m_platform)
{
return SamplePlatform::m_platform;
}
return NULL;
}
SampleApplication* SamplePlatform::application()
{
return m_sf_app;
}
bool SamplePlatform::preOpenWindow(void * ptr)
{
return true;
}
void SamplePlatform::showCursor(bool)
{
}
void SamplePlatform::setPlatform(SamplePlatform* ptr)
{
SamplePlatform::m_platform = ptr;
}
void* SamplePlatform::initializeD3D9()
{
return NULL;
}
bool SamplePlatform::isD3D9ok()
{
return true;
}
void* SamplePlatform::initializeD3D11()
{
return NULL;
}
bool SamplePlatform::isD3D11ok()
{
return true;
}
void* SamplePlatform::compileProgram(void * context,
const char* assetDir,
const char *programPath,
physx::PxU64 profile,
const char* passString,
const char *entry,
const char **args)
{
return NULL;
}
SamplePlatform::SamplePlatform(SampleRenderer::RendererWindow* _app) : m_app(_app)
{
}
SamplePlatform::~SamplePlatform()
{
}
bool SamplePlatform::hasFocus() const
{
return true;
}
void SamplePlatform::setFocus(bool b)
{
}
void SamplePlatform::update()
{
}
void SamplePlatform::setWindowSize(physx::PxU32 width,
physx::PxU32 height)
{
}
void SamplePlatform::getTitle(char *title, PxU32 maxLength) const
{
}
void SamplePlatform::setTitle(const char *title)
{
}
bool SamplePlatform::openWindow(physx::PxU32& width,
physx::PxU32& height,
const char* title,
bool fullscreen)
{
return true;
}
bool SamplePlatform::useWindow(physx::PxU64 hwnd)
{
return false;
}
bool SamplePlatform::isOpen()
{
return true;
}
bool SamplePlatform::closeWindow()
{
return true;
}
bool SamplePlatform::updateWindow()
{
return true;
}
size_t SamplePlatform::getCWD(char* path, size_t len)
{
RENDERER_ASSERT(path && len, "buffer should not be empty!");
*path = '\0';
return 0;
}
void SamplePlatform::setCWDToEXE(void)
{
}
void SamplePlatform::popPathSpec(char *path)
{
char *ls = 0;
while(*path)
{
if(*path == '\\' || *path == '/') ls = path;
path++;
}
if(ls) *ls = 0;
}
void SamplePlatform::preRendererSetup()
{
}
void SamplePlatform::postRendererSetup(SampleRenderer::Renderer* renderer)
{
getSampleUserInput()->setRenderer(renderer);
}
void SamplePlatform::setupRendererDescription(SampleRenderer::RendererDesc& renDesc)
{
renDesc.driver = SampleRenderer::Renderer::DRIVER_OPENGL;
}
void SamplePlatform::doInput()
{
}
void SamplePlatform::postRendererRelease()
{
}
void SamplePlatform::initializeOGLDisplay(const SampleRenderer::RendererDesc& desc,
physx::PxU32& width,
physx::PxU32& height)
{
}
void SamplePlatform::showMessage(const char* title, const char* message)
{
shdfnd::printFormatted("%s: %s\n", title, message);
}
bool SamplePlatform::saveBitmap(const char*, physx::PxU32, physx::PxU32, physx::PxU32, const void*)
{
return false;
}
void SamplePlatform::initializeCGRuntimeCompiler()
{
}
void SamplePlatform::getWindowSize(PxU32& width, PxU32& height)
{
}
void SamplePlatform::freeDisplay()
{
}
bool SamplePlatform::makeContextCurrent()
{
return true;
}
void SamplePlatform::swapBuffers()
{
}
bool SamplePlatform::isContextValid()
{
return true;
}
void SamplePlatform::postInitializeOGLDisplay()
{
}
void SamplePlatform::setOGLVsync(bool on)
{
}
physx::PxU32 SamplePlatform::initializeD3D9Display(void * presentParameters,
char* m_deviceName,
physx::PxU32& width,
physx::PxU32& height,
void * m_d3dDevice_out)
{
return 0;
}
physx::PxU32 SamplePlatform::initializeD3D11Display(void *dxgiSwapChainDesc,
char *m_deviceName,
physx::PxU32& width,
physx::PxU32& height,
void *m_d3dDevice_out,
void *m_d3dDeviceContext_out,
void *m_dxgiSwap_out)
{
return 0;
}
physx::PxU64 SamplePlatform::getWindowHandle()
{
return 0;
}
physx::PxU32 SamplePlatform::D3D9Present()
{
return 0;
}
physx::PxU32 SamplePlatform::D3D11Present(bool vsync)
{
return 0;
}
void SamplePlatform::D3D9BlockUntilNotBusy(void * resource)
{
}
void SamplePlatform::D3D9DeviceBlockUntilIdle()
{
}
physx::PxU64 SamplePlatform::getD3D9TextureFormat(SampleRenderer::RendererTexture2D::Format format)
{
return 0;
}
const char* SamplePlatform::getPathSeparator()
{
return "\\";
}
bool SamplePlatform::makeSureDirectoryPathExists(const char*)
{
return false;
}
physx::PxU64 SamplePlatform::getD3D11TextureFormat(SampleRenderer::RendererTexture2D::Format format)
{
return 0;
}

View File

@ -0,0 +1,344 @@
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
#include <SampleUserInput.h>
#include <SamplePlatform.h>
#if defined(RENDERER_LINUX)
#include <stdio.h>
#endif
using namespace SampleFramework;
namespace Ps = physx::shdfnd;
// this will prepare the input events vector, its not resize-able
static const size_t NUM_INPUT_EVENTS = 256;
SampleUserInput::SampleUserInput()
: mListener(NULL)
{
mUserInputs.reserve(128);
mInputEvents.reserve(NUM_INPUT_EVENTS);
mInputEventNames.reserve(NUM_INPUT_EVENTS);
}
SampleUserInput::~SampleUserInput()
{
mUserInputs.clear();
}
void SampleUserInput::registerUserInput(physx::PxU16 id,const char* idName ,const char* name)
{
UserInput ui;
ui.m_Id = id;
strcpy(ui.m_Name , name);
strcpy(ui.m_IdName, idName);
mUserInputs.push_back(ui);
}
const InputEvent* SampleUserInput::registerInputEvent(const InputEvent& inputEvent, physx::PxU16 userInputId, const char* name)
{
size_t ieId = 0;
const InputEvent* retIe = NULL;
std::map<physx::PxU16, std::vector<size_t> >::iterator fit = mInputEventUserInputMap.find(inputEvent.m_Id);
if(fit != mInputEventUserInputMap.end())
{
for (size_t i = mInputEvents.size(); i--;)
{
if(mInputEvents[i].m_Id == inputEvent.m_Id)
{
// the analog has a priority
if(inputEvent.m_Analog == true)
{
mInputEvents[i].m_Analog = true;
}
ieId = i;
break;
}
}
}
else
{
ieId = mInputEvents.size();
if(ieId == NUM_INPUT_EVENTS - 1)
{
// increase the num input events please
PX_ASSERT(0);
return NULL;
}
else
{
mInputEvents.push_back(inputEvent);
mInputEventNames.resize(mInputEventNames.size()+1);
Ps::strlcpy(mInputEventNames.back().m_Name, sizeof(mInputEventNames.back().m_Name), name);
retIe = &mInputEvents[ieId];
PX_ASSERT(mInputEventNames.size() == mInputEvents.size());
}
}
bool found = false;
size_t uiId = 0;
for (size_t i = mUserInputs.size(); i--; )
{
const UserInput& ui = mUserInputs[i];
if(ui.m_Id == userInputId)
{
uiId = i;
found = true;
break;
}
}
if(found)
{
mInputEventUserInputMap[inputEvent.m_Id].push_back(uiId);
mUserInputInputEventMap[userInputId].push_back(ieId);
//if(mUserInputInputEventMap[userInputId].size() > 1)
//{
// char msg[256];
// sprintf(msg,"Key %s used multiple times",mUserInputs[uiId].m_Name);
// SampleFramework::SamplePlatform::platform()->showMessage("SampleUserInput warning: ",msg);
//}
}
return retIe;
}
void SampleUserInput::registerInputEvent(const SampleInputMapping& mapping)
{
std::map<physx::PxU16, std::vector<size_t> >::iterator fit = mInputEventUserInputMap.find(mapping.m_InputEventId);
if(fit != mInputEventUserInputMap.end())
{
std::vector<size_t>& userInputVector = fit->second;
bool found = false;
for (size_t i = userInputVector.size(); i--;)
{
if(userInputVector[i] == mapping.m_UserInputIndex)
{
found = true;
}
}
if(!found)
{
userInputVector.push_back(mapping.m_UserInputIndex);
}
}
else
{
mInputEventUserInputMap[mapping.m_InputEventId].push_back(mapping.m_UserInputIndex);
}
fit = mUserInputInputEventMap.find(mapping.m_UserInputId);
if(fit != mUserInputInputEventMap.end())
{
std::vector<size_t>& inputEventVector = fit->second;
bool found = false;
for (size_t i = inputEventVector.size(); i--;)
{
if(inputEventVector[i] == mapping.m_InputEventIndex)
{
found = true;
}
}
if(!found)
{
inputEventVector.push_back(mapping.m_InputEventIndex);
}
}
else
{
mUserInputInputEventMap[mapping.m_UserInputId].push_back(mapping.m_InputEventIndex);
}
}
void SampleUserInput::unregisterInputEvent(physx::PxU16 inputEventId)
{
std::map<physx::PxU16, std::vector<size_t> >::iterator fit = mInputEventUserInputMap.find(inputEventId);
if(fit != mInputEventUserInputMap.end())
{
const std::vector<size_t>& userInputs = fit->second;
for (size_t j = userInputs.size(); j--;)
{
const UserInput& ui = mUserInputs[userInputs[j]];
std::map<physx::PxU16, std::vector<size_t> >::iterator uifit = mUserInputInputEventMap.find(ui.m_Id);
if(uifit != mUserInputInputEventMap.end())
{
std::vector<size_t>& inputEvents = uifit->second;
for (size_t u = inputEvents.size(); u--;)
{
if(mInputEvents[inputEvents[u]].m_Id == inputEventId)
{
inputEvents[u] = inputEvents.back();
inputEvents.pop_back();
}
}
}
}
mInputEventUserInputMap.erase(fit);
}
}
void SampleUserInput::updateInput()
{
}
void SampleUserInput::processGamepads()
{
}
const InputEvent* SampleUserInput::getInputEventSlow(physx::PxU16 inputEventId) const
{
for (size_t i = mInputEvents.size(); i--;)
{
if(mInputEvents[i].m_Id == inputEventId)
{
return &mInputEvents[i];
}
}
return NULL;
}
const std::vector<size_t>* SampleUserInput::getUserInputs(physx::PxI32 inputEventId) const
{
if(inputEventId < 0)
return NULL;
std::map<physx::PxU16, std::vector<size_t> >::const_iterator fit = mInputEventUserInputMap.find((physx::PxU16)inputEventId);
if(fit != mInputEventUserInputMap.end())
{
return &fit->second;
}
else
{
return NULL;
}
}
const std::vector<size_t>* SampleUserInput::getInputEvents(physx::PxU16 userInputId) const
{
std::map<physx::PxU16, std::vector<size_t> >::const_iterator fit = mUserInputInputEventMap.find(userInputId);
if(fit != mUserInputInputEventMap.end())
{
return &fit->second;
}
else
{
return NULL;
}
}
physx::PxI32 SampleUserInput::translateInputEventNameToId(const char* name, size_t& index) const
{
PX_ASSERT(mInputEvents.size() == mInputEventNames.size());
for (size_t i = mInputEventNames.size(); i--;)
{
if(!strcmp(mInputEventNames[i].m_Name, name))
{
index = i;
return mInputEvents[i].m_Id;
}
}
return -1;
}
const char* SampleUserInput::translateInputEventIdToName(physx::PxI32 id) const
{
PX_ASSERT(mInputEvents.size() == mInputEventNames.size());
for (size_t i = mInputEvents.size(); i--;)
{
if(mInputEvents[i].m_Id == id)
{
return mInputEventNames[i].m_Name;
}
}
return NULL;
}
physx::PxI32 SampleUserInput::translateUserInputNameToId(const char* name, size_t& index) const
{
for (size_t i = mUserInputs.size(); i--;)
{
if(!strcmp(mUserInputs[i].m_IdName, name))
{
index = i;
return mUserInputs[i].m_Id;
}
}
return -1;
}
void SampleUserInput::shutdown()
{
mInputEvents.clear();
mInputEventNames.clear();
mUserInputInputEventMap.clear();
mInputEventUserInputMap.clear();
}
physx::PxU16 SampleUserInput::getUserInputKeys(physx::PxU16 inputEventId, const char* names[], physx::PxU16 maxNames, physx::PxU32 inputTypeMask) const
{
physx::PxU16 retVal = 0;
const std::vector<size_t>* uis = getUserInputs(inputEventId);
if(uis)
{
for (size_t i = uis->size(); i--;)
{
if(retVal < maxNames)
{
const UserInput& ie = mUserInputs[(*uis)[i]];
InputType it = getInputType(ie);
if(it)
{
if(it & inputTypeMask)
{
names[retVal] = ie.m_Name;
retVal++;
}
}
else
{
names[retVal] = ie.m_Name;
retVal++;
}
}
}
}
return retVal;
}

View File

@ -0,0 +1,577 @@
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
#include <RendererMemoryMacros.h>
#include <linux/LinuxSamplePlatform.h>
#include <SampleApplication.h>
#include <Cg/cg.h>
#include <stdio.h>
#include <Ps.h>
#include <PsString.h>
//#include <PsFile.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
using namespace SampleFramework;
using SampleRenderer::RendererWindow;
namespace Ps = physx::shdfnd;
// filters OS key auto repeat, otherwise you get repeatedly key released and pressed events
// returns true if the supplied event was a auto repeat one.
// XAutoRepeatOff(m_display); does change the behaviour for the entire display.
// So you see the effect also in other apps while the samples are running, which is bad.
bool LinuxPlatform::filterKeyRepeat(const XEvent& keyReleaseEvent)
{
if(keyReleaseEvent.type == KeyRelease && XEventsQueued(m_display, QueuedAfterReading))
{
XEvent nev;
XPeekEvent(m_display, &nev);
if (nev.type == KeyPress &&
nev.xkey.time == keyReleaseEvent.xkey.time &&
nev.xkey.keycode == keyReleaseEvent.xkey.keycode)
{
// Key wasn't actually released, eat event
XNextEvent(m_display, &nev);
return true;
}
}
return false;
}
SamplePlatform* SampleFramework::createPlatform(SampleRenderer::RendererWindow* _app)
{
printf("Creating linux platform abstraction.\n");
SamplePlatform::setPlatform(new LinuxPlatform(_app));
return SamplePlatform::platform();
}
void* LinuxPlatform::compileProgram(void * context,
const char* assetDir,
const char *programPath,
physx::PxU64 profile,
const char* passString,
const char *entry,
const char **args)
{
char fullpath[1024];
Ps::strlcpy(fullpath, 1024, assetDir);
Ps::strlcat(fullpath, 1024, "shaders/");
Ps::strlcat(fullpath, 1024, programPath);
CGprogram program = cgCreateProgramFromFile(static_cast<CGcontext>(context), CG_SOURCE, fullpath, static_cast<CGprofile>(profile), entry, args);
return program;
}
static PxI32 errorHandler(Display* d, XErrorEvent* e)
{
printf("Xerror!\n");
return 0;
}
static PxI32 errorHandlerIO(Display* d)
{
printf("X IO error!\n");
return 0;
}
LinuxPlatform::LinuxPlatform(SampleRenderer::RendererWindow* _app)
: SamplePlatform(_app)
, m_display(NULL)
, m_visualInfo(NULL)
, m_hasFocus(false)
, m_hasContentFocus(false)
, m_isFullScreen(false)
, m_screen(0)
, m_mouseCursorPos(0)
, m_recenterMouseCursor(false)
, m_showCursor(true)
{
XInitThreads();
XSetIOErrorHandler(errorHandlerIO);
XSetErrorHandler(errorHandler);
}
void LinuxPlatform::setCWDToEXE(void)
{
char exepath[1024] = {0};
if(getcwd(exepath, 1024))
{
if(chdir(exepath) != 0)
{
printf("LinuxPlatform::setCWDToEXE chdir failed!\n");
}
}
}
void LinuxPlatform::setupRendererDescription(SampleRenderer::RendererDesc& renDesc)
{
renDesc.driver = SampleRenderer::Renderer::DRIVER_OPENGL;
renDesc.windowHandle = 0;
}
void LinuxPlatform::postRendererSetup(SampleRenderer::Renderer* renderer)
{
if(!renderer)
{
// quit if no renderer was created. Nothing else to do.
// error was output in createRenderer.
exit(1);
}
char windowTitle[1024] = {0};
m_app->getTitle(windowTitle, 1024);
strcat(windowTitle, " : ");
strcat(windowTitle, SampleRenderer::Renderer::getDriverTypeName(renderer->getDriverType()));
m_app->setTitle(windowTitle);
}
void LinuxPlatform::setMouseCursorRecentering(bool val)
{
if (m_recenterMouseCursor != val)
{
m_recenterMouseCursor = val;
if (m_recenterMouseCursor)
recenterMouseCursor(false);
}
}
bool LinuxPlatform::getMouseCursorRecentering() const
{
return m_recenterMouseCursor;
}
void LinuxPlatform::recenterMouseCursor(bool generateEvent)
{
if (m_recenterMouseCursor && m_hasContentFocus)
{
// returns relative window coordinates, opposed to absolute ones!
// different than on other platforms.
PxI32 x, y, xtmp, ytmp;
PxU32 mtmp;
Window root, child;
XQueryPointer(m_display, m_window, &root, &child, &xtmp, &ytmp, &x, &y, &mtmp);
PxVec2 current(static_cast<PxReal>(x), static_cast<PxReal>(m_windowHeight - y));
PxI32 linuxCenterX = m_windowWidth >> 1;
PxI32 linuxCenterY = m_windowHeight >> 1;
XWarpPointer(m_display, 0, m_window, 0, 0, 0, 0, linuxCenterX, linuxCenterY);
// sync here needed, otherwise the deltas will be (almost) zero
XSync(m_display, false);
if (generateEvent)
{
PxVec2 diff = current - PxVec2(static_cast<PxReal>(linuxCenterX), static_cast<PxReal>(m_windowHeight - linuxCenterY));
getLinuxSampleUserInput().doOnMouseMove(linuxCenterX, m_windowHeight - linuxCenterY, diff.x, diff.y, MOUSE_MOVE);
}
m_mouseCursorPos = current;
}
}
void LinuxPlatform::showCursorInternal(bool show)
{
if(show)
{
XUndefineCursor(m_display, m_window);
}
else
{
Pixmap bm_no;
Colormap cmap;
Cursor no_ptr;
XColor black, dummy;
static char bm_no_data[] = {0, 0, 0, 0, 0, 0, 0, 0};
cmap = DefaultColormap(m_display, DefaultScreen(m_display));
XAllocNamedColor(m_display, cmap, "black", &black, &dummy);
bm_no = XCreateBitmapFromData(m_display, m_window, bm_no_data, 8, 8);
no_ptr = XCreatePixmapCursor(m_display, bm_no, bm_no, &black, &black, 0, 0);
XDefineCursor(m_display, m_window, no_ptr);
XFreeCursor(m_display, no_ptr);
if(bm_no != None)
XFreePixmap(m_display, bm_no);
XFreeColors(m_display, cmap, &black.pixel, 1, 0);
}
}
void LinuxPlatform::showCursor(bool show)
{
if(m_showCursor == show)
return;
m_showCursor = show;
showCursorInternal(show);
}
void LinuxPlatform::doInput()
{
/* do nothing */
}
bool LinuxPlatform::openWindow(physx::PxU32& width, physx::PxU32& height,const char* title, bool fullscreen)
{
Window rootWindow;
GLint attributes[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
Colormap colorMap;
XSetWindowAttributes setWindowAttributes;
XWindowAttributes xWindowAttributes;
XEvent xEvent;
int glxMajor, glxMinor, vmMajor, vmMinor;
XF86VidModeModeInfo** modes;
int modeNum;
int bestMode = 0; // set best mode to current
m_display = XOpenDisplay(NULL);
m_screen = DefaultScreen(m_display);
if(!m_display)
{
printf("Cannot connect to X server!\n");
closeWindow();
return false;
}
XF86VidModeQueryVersion(m_display, &vmMajor, &vmMinor);
printf("XF86 VideoMode extension version %d.%d\n", vmMajor, vmMinor);
glXQueryVersion(m_display, &glxMajor, &glxMinor);
printf("GLX-Version %d.%d\n", glxMajor, glxMinor);
rootWindow = RootWindow(m_display, m_screen);
m_visualInfo = glXChooseVisual(m_display, m_screen, attributes);
if(!m_visualInfo)
{
printf("no appropriate visual found!\n");
closeWindow();
return false;
}
colorMap = XCreateColormap(m_display, rootWindow, m_visualInfo->visual, AllocNone);
setWindowAttributes.colormap = colorMap;
setWindowAttributes.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask;
m_windowWidth = width;
m_windowHeight = height;
//fullscreen = true;
m_isFullScreen = fullscreen;
int windowFlags = CWColormap | CWEventMask;
if(fullscreen)
{
XF86VidModeGetAllModeLines(m_display, m_screen, &modeNum, &modes);
// save desktop-resolution before switching modes
m_desktopMode = *modes[0];
// look for mode with requested resolution
for (PxU32 i = 0; i < modeNum; i++)
{
if ((modes[i]->hdisplay == width) && (modes[i]->vdisplay == height))
bestMode = i;
}
// switch to fullscreen
XF86VidModeSwitchToMode(m_display, m_screen, modes[bestMode]);
XF86VidModeSetViewPort(m_display, m_screen, 0, 0);
m_windowWidth = modes[bestMode]->hdisplay;
m_windowHeight = modes[bestMode]->vdisplay;
printf("switched to fullscreen resolution %dx%d\n", m_windowWidth, m_windowHeight);
XFree(modes);
setWindowAttributes.override_redirect = True;
windowFlags |= CWBorderPixel | CWOverrideRedirect;
}
m_window = XCreateWindow(m_display, rootWindow, 0, 0, m_windowWidth, m_windowHeight, 0, m_visualInfo->depth, InputOutput, m_visualInfo->visual, windowFlags, &setWindowAttributes);
XMapRaised(m_display, m_window);
XStoreName(m_display, m_window, title);
if(fullscreen)
{
XWarpPointer(m_display, None, m_window, 0, 0, 0, 0, 0, 0);
XGrabKeyboard(m_display, m_window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
XGrabPointer(m_display, m_window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, m_window, None, CurrentTime);
}
else
{
m_wmDelete = XInternAtom(m_display, "WM_DELETE_WINDOW", True);
XSetWMProtocols(m_display, m_window, &m_wmDelete, 1);
XMapWindow(m_display, m_window);
}
m_hasContentFocus = true;
m_showCursor = true;
recenterMouseCursor(false);
return true;
}
void LinuxPlatform::initializeOGLDisplay(const SampleRenderer::RendererDesc& desc,
physx::PxU32& width,
physx::PxU32& height)
{
m_glxContext = glXCreateContext(m_display, m_visualInfo, NULL, GL_TRUE);
glXMakeCurrent(m_display, m_window, m_glxContext);
getWindowSize(width, height);
}
void LinuxPlatform::postInitializeOGLDisplay()
{
glewInit();
}
bool LinuxPlatform::closeWindow()
{
if(m_glxContext)
{
glXMakeCurrent(m_display, None, NULL);
glXDestroyContext(m_display, m_glxContext);
m_glxContext = 0;
XDestroyWindow(m_display, m_window);
if(m_isFullScreen)
{
XF86VidModeSwitchToMode(m_display, m_screen, &m_desktopMode);
XF86VidModeSetViewPort(m_display, m_screen, 0, 0);
}
if(m_visualInfo)
XFree(m_visualInfo);
m_visualInfo = NULL;
if(m_display)
XCloseDisplay(m_display);
m_display = NULL;
}
return true;
}
void LinuxPlatform::freeDisplay()
{
}
void LinuxPlatform::getWindowSize(PxU32& width, PxU32& height)
{
if(!m_display)
return;
XWindowAttributes attr;
XGetWindowAttributes(m_display, m_window, &attr);
width = attr.width;
height = attr.height;
}
void LinuxPlatform::setFocus(bool b)
{
m_hasFocus = b;
}
bool LinuxPlatform::hasFocus() const
{
return m_hasContentFocus;
}
void LinuxPlatform::getTitle(char *title, physx::PxU32 maxLength) const
{
if(!m_display)
return;
char* t;
XFetchName(m_display, m_window, &t);
strncpy(title, t, maxLength);
XFree(t);
}
void LinuxPlatform::setTitle(const char *title)
{
// unsafe!
if(m_display && title)
XStoreName(m_display, m_window, title);
}
bool LinuxPlatform::updateWindow()
{
return true;
}
void LinuxPlatform::handleMouseEvent(const XEvent& event)
{
PxU32 x = event.xbutton.x;
PxU32 y = m_windowHeight - event.xbutton.y;
PxVec2 current(static_cast<PxReal>(x), static_cast<PxReal>(y));
setMouseCursorPos(current);
switch (event.type)
{
case ButtonPress:
{
m_linuxSampleUserInput.doOnMouseDown(x, y, event.xbutton.button);
}
break;
case ButtonRelease:
{
m_linuxSampleUserInput.doOnMouseUp(x, y, event.xbutton.button);
}
break;
case MotionNotify:
{
if (!getMouseCursorRecentering())
{
PxVec2 diff = current - getMouseCursorPos();
m_linuxSampleUserInput.doOnMouseMove(x, y, diff.x, diff.y, MOUSE_MOVE);
}
}
break;
}
}
void LinuxPlatform::update()
{
XEvent event;
bool close = false;
if(!m_display || !m_app || !m_app->isOpen())
return;
// handle the events in the queue
while (m_display && !close && m_app->isOpen() && (XPending(m_display) > 0))
{
XNextEvent(m_display, &event);
switch (event.type)
{
case Expose:
if (event.xexpose.count == 0)
{
PxU32 width, height;
getWindowSize(width, height);
m_app->onResize(width, height);
m_windowWidth = width;
m_windowHeight = height;
}
break;
case FocusIn:
m_app->setFocus(true);
break;
case FocusOut:
m_app->setFocus(false);
m_hasContentFocus = false;
break;
case ButtonPress:
// fixes recentering issue: jumping window with first context switch.
if(!m_hasContentFocus)
{
m_hasContentFocus = true;
recenterMouseCursor(false);
}
else
handleMouseEvent(event);
break;
case ButtonRelease:
handleMouseEvent(event);
break;
case MotionNotify:
handleMouseEvent(event);
break;
case KeyPress:
case KeyRelease:
{
// and now some code to filter out the key releases
// which are generated by auto repeat
if(filterKeyRepeat(event))
break;
char keyName;
KeySym keySym;
XLookupString(&event.xkey, &keyName, 1, &keySym, NULL);
bool keyDown = (event.type == KeyPress);
if(keyDown)
m_linuxSampleUserInput.doOnKeyDown(keySym, event.xkey.keycode, keyName);
else
m_linuxSampleUserInput.doOnKeyUp(keySym, event.xkey.keycode, keyName);
}
break;
case ClientMessage:
if((Atom)event.xclient.data.l[0] == m_wmDelete)
close = true;
break;
default:
printf("unhandled event type: %d\n", event.type);
break;
}
}
recenterMouseCursor(true);
if(close)
m_app->close();
}
void LinuxPlatform::swapBuffers()
{
if(m_display)
glXSwapBuffers(m_display, m_window);
}
const char* LinuxPlatform::getPathSeparator()
{
return "/";
}
static bool doesDirectoryExist(const char* path)
{
bool exists = false;
DIR* dir = NULL;
dir = opendir(path);
if(dir)
{
closedir(dir);
exists = true;
}
return exists;
}
bool LinuxPlatform::makeSureDirectoryPathExists(const char* dirPath)
{
bool ok = doesDirectoryExist(dirPath);
if (!ok)
ok = mkdir(dirPath, S_IRWXU|S_IRWXG|S_IRWXO) == 0;
return ok;
}
void LinuxPlatform::showMessage(const char* title, const char* message)
{
printf("%s: %s\n", title, message);
}

View File

@ -0,0 +1,398 @@
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
#include <linux/LinuxSampleUserInput.h>
#include <X11/keysym.h>
#include <stdio.h>
static bool gTimeInit=false;
using namespace SampleFramework;
using namespace physx;
LinuxSampleUserInput::LinuxSampleUserInput()
{
// register all user inputs for linux platform
registerUserInput(LINUXKEY_1,"KEY_1", "1");
registerUserInput(LINUXKEY_2,"KEY_2", "2");
registerUserInput(LINUXKEY_3,"KEY_3", "3");
registerUserInput(LINUXKEY_4,"KEY_4", "4");
registerUserInput(LINUXKEY_5,"KEY_5", "5");
registerUserInput(LINUXKEY_6,"KEY_6", "6");
registerUserInput(LINUXKEY_7,"KEY_7", "7");
registerUserInput(LINUXKEY_8,"KEY_8", "8");
registerUserInput(LINUXKEY_9,"KEY_9", "9");
registerUserInput(LINUXKEY_0,"KEY_0", "0");
registerUserInput(LINUXKEY_A,"KEY_A", "A");
registerUserInput(LINUXKEY_B,"KEY_B", "B");
registerUserInput(LINUXKEY_C,"KEY_C", "C");
registerUserInput(LINUXKEY_D,"KEY_D", "D");
registerUserInput(LINUXKEY_E,"KEY_E", "E");
registerUserInput(LINUXKEY_F,"KEY_F", "F");
registerUserInput(LINUXKEY_G,"KEY_G", "G");
registerUserInput(LINUXKEY_H,"KEY_H", "H");
registerUserInput(LINUXKEY_I,"KEY_I", "I");
registerUserInput(LINUXKEY_J,"KEY_J", "J");
registerUserInput(LINUXKEY_K,"KEY_K", "K");
registerUserInput(LINUXKEY_L,"KEY_L", "L");
registerUserInput(LINUXKEY_M,"KEY_M", "M");
registerUserInput(LINUXKEY_N,"KEY_N", "N");
registerUserInput(LINUXKEY_O,"KEY_O", "O");
registerUserInput(LINUXKEY_P,"KEY_P", "P");
registerUserInput(LINUXKEY_Q,"KEY_Q", "Q");
registerUserInput(LINUXKEY_R,"KEY_R", "R");
registerUserInput(LINUXKEY_S,"KEY_S", "S");
registerUserInput(LINUXKEY_T,"KEY_T", "T");
registerUserInput(LINUXKEY_U,"KEY_U", "U");
registerUserInput(LINUXKEY_V,"KEY_V", "V");
registerUserInput(LINUXKEY_W,"KEY_W", "W");
registerUserInput(LINUXKEY_X,"KEY_X", "X");
registerUserInput(LINUXKEY_Y,"KEY_Y", "Y");
registerUserInput(LINUXKEY_Z,"KEY_Z", "Z");
registerUserInput(LINUXKEY_SPACE ,"KEY_SPACE","Space");
registerUserInput(LINUXKEY_RETURN ,"KEY_RETURN","Enter");
registerUserInput(LINUXKEY_SHIFT ,"KEY_SHIFT","Shift");
registerUserInput(LINUXKEY_CONTROL ,"KEY_CONTROL","Control");
registerUserInput(LINUXKEY_ESCAPE ,"KEY_ESCAPE","Escape");
registerUserInput(LINUXKEY_COMMA ,"KEY_COMMA",",");
registerUserInput(LINUXKEY_NUMPAD0 ,"KEY_NUMPAD0","Numpad0");
registerUserInput(LINUXKEY_NUMPAD1 ,"KEY_NUMPAD1","Numpad1");
registerUserInput(LINUXKEY_NUMPAD2 ,"KEY_NUMPAD2","Numpad2");
registerUserInput(LINUXKEY_NUMPAD3 ,"KEY_NUMPAD3","Numpad3");
registerUserInput(LINUXKEY_NUMPAD4 ,"KEY_NUMPAD4","Numpad4");
registerUserInput(LINUXKEY_NUMPAD5 ,"KEY_NUMPAD5","Numpad5");
registerUserInput(LINUXKEY_NUMPAD6 ,"KEY_NUMPAD6","Numpad6");
registerUserInput(LINUXKEY_NUMPAD7 ,"KEY_NUMPAD7","Numpad7");
registerUserInput(LINUXKEY_NUMPAD8 ,"KEY_NUMPAD8","Numpad8");
registerUserInput(LINUXKEY_NUMPAD9 ,"KEY_NUMPAD9","Numpad9");
registerUserInput(LINUXKEY_ADD ,"KEY_ADD","+");
registerUserInput(LINUXKEY_SUBTRACT ,"KEY_SUBTRACT","-");
registerUserInput(LINUXKEY_COMMA ,"KEY_COMMM",", on keypad");
registerUserInput(LINUXKEY_DIVIDE ,"KEY_DIVIDE","/");
registerUserInput(LINUXKEY_F1 ,"KEY_F1","F1");
registerUserInput(LINUXKEY_F2 ,"KEY_F2","F2");
registerUserInput(LINUXKEY_F3 ,"KEY_F3","F3");
registerUserInput(LINUXKEY_F4 ,"KEY_F4","F4");
registerUserInput(LINUXKEY_F5 ,"KEY_F5","F5");
registerUserInput(LINUXKEY_F6 ,"KEY_F6","F6");
registerUserInput(LINUXKEY_F7 ,"KEY_F7","F7");
registerUserInput(LINUXKEY_F8 ,"KEY_F8","F8");
registerUserInput(LINUXKEY_F9 ,"KEY_F9","F9");
registerUserInput(LINUXKEY_F10 ,"KEY_F10","F10");
registerUserInput(LINUXKEY_F11 ,"KEY_F11","F11");
registerUserInput(LINUXKEY_F12 ,"KEY_F12","F12");
registerUserInput(LINUXKEY_TAB ,"KEY_TAB","Tab");
registerUserInput(LINUXKEY_BACKSPACE ,"KEY_BACKSPACE","Backspace");
registerUserInput(LINUXKEY_PRIOR ,"KEY_PRIOR","PgUp");
registerUserInput(LINUXKEY_NEXT ,"KEY_NEXT","PgDn");
registerUserInput(LINUXKEY_UP ,"KEY_UP","Up Arrow");
registerUserInput(LINUXKEY_DOWN ,"KEY_DOWN","Down Arrow");
registerUserInput(LINUXKEY_LEFT ,"KEY_LEFT","Left Arrow");
registerUserInput(LINUXKEY_RIGHT ,"KEY_RIGHT","Right Arrow");
// mouse
registerUserInput(MOUSE_BUTTON_LEFT ,"MOUSE_BUTTON_LEFT","Left Mouse Button");
registerUserInput(MOUSE_BUTTON_RIGHT ,"MOUSE_BUTTON_RIGHT","Right Mouse Button");
registerUserInput(MOUSE_BUTTON_CENTER ,"MOUSE_BUTTON_CENTER","Middle Mouse Button");
registerUserInput(MOUSE_MOVE,"MOUSE_MOVE", "Mouse Move");
// scan codes
registerScanCode(SCAN_CODE_UP, 26, LINUXKEY_E, "SCAN_CODE_E");
registerScanCode(SCAN_CODE_DOWN, 54, LINUXKEY_C, "SCAN_CODE_C");
registerScanCode(SCAN_CODE_LEFT, 38, LINUXKEY_A, "SCAN_CODE_A");
registerScanCode(SCAN_CODE_RIGHT, 40, LINUXKEY_D, "SCAN_CODE_D");
registerScanCode(SCAN_CODE_FORWARD, 25, LINUXKEY_W, "SCAN_CODE_W");
registerScanCode(SCAN_CODE_BACKWARD, 39, LINUXKEY_S, "SCAN_CODE_S");
registerScanCode(SCAN_CODE_L, 46, LINUXKEY_L, "SCAN_CODE_L");
registerScanCode(SCAN_CODE_9, 18, LINUXKEY_9, "SCAN_CODE_9");
registerScanCode(SCAN_CODE_0, 19, LINUXKEY_0, "SCAN_CODE_0");
}
void LinuxSampleUserInput::registerScanCode(LinuxSampleUserInputIds scanCodeId, physx::PxU16 scanCode, LinuxSampleUserInputIds nameId, const char* name)
{
const UserInput* ui = getUserInputFromId(nameId);
if(ui)
{
registerUserInput(scanCodeId, name, ui->m_Name);
m_ScanCodesMap[scanCode] = scanCodeId;
}
}
const UserInput* LinuxSampleUserInput::getUserInputFromId(LinuxSampleUserInputIds id) const
{
for (size_t i = mUserInputs.size(); i--;)
{
if(mUserInputs[i].m_Id == id)
{
return &mUserInputs[i];
}
}
return NULL;
}
LinuxSampleUserInput::~LinuxSampleUserInput()
{
m_ScanCodesMap.clear();
m_AnalogStates.clear();
m_DigitalStates.clear();
}
LinuxSampleUserInputIds LinuxSampleUserInput::getInputIdFromMouseButton(const physx::PxU16 b) const
{
if (b == Button1) return MOUSE_BUTTON_LEFT;
else if (b == Button2) return MOUSE_BUTTON_CENTER;
else if (b == Button3) return MOUSE_BUTTON_RIGHT;
else return LINUXKEY_UNKNOWN;
}
LinuxSampleUserInputIds LinuxSampleUserInput::getInputIdFromKeySym(const KeySym keySym) const
{
LinuxSampleUserInputIds id = LINUXKEY_UNKNOWN;
if(keySym >= XK_A && keySym <= XK_Z) id = (LinuxSampleUserInputIds)((keySym - XK_A)+LINUXKEY_A);
else if(keySym >= XK_a && keySym <= XK_z) id = (LinuxSampleUserInputIds)((keySym - XK_a)+LINUXKEY_A);
else if(keySym >= XK_0 && keySym <= XK_9) id = (LinuxSampleUserInputIds)((keySym - XK_0)+LINUXKEY_0);
else if(keySym >= XK_KP_0 && keySym <= XK_KP_9) id = (LinuxSampleUserInputIds)((keySym - XK_KP_0)+LINUXKEY_NUMPAD0);
else if(keySym == XK_Shift_L || keySym == XK_Shift_R) id = LINUXKEY_SHIFT;
else if(keySym == XK_Control_L || keySym == XK_Control_R) id = LINUXKEY_CONTROL;
else if(keySym == XK_space) id = LINUXKEY_SPACE;
else if(keySym == XK_Return) id = LINUXKEY_RETURN;
else if(keySym == XK_Escape) id = LINUXKEY_ESCAPE;
else if(keySym == XK_KP_Separator) id = LINUXKEY_COMMA;
else if(keySym == XK_KP_Divide) id = LINUXKEY_DIVIDE;
else if(keySym == XK_KP_Subtract) id = LINUXKEY_SUBTRACT;
else if(keySym == XK_KP_Add) id = LINUXKEY_ADD;
//
else if(keySym == XK_F1) id = LINUXKEY_F1;
else if(keySym == XK_F2) id = LINUXKEY_F2;
else if(keySym == XK_F3) id = LINUXKEY_F3;
else if(keySym == XK_F4) id = LINUXKEY_F4;
else if(keySym == XK_F5) id = LINUXKEY_F5;
else if(keySym == XK_F6) id = LINUXKEY_F6;
else if(keySym == XK_F7) id = LINUXKEY_F7;
else if(keySym == XK_F8) id = LINUXKEY_F8;
else if(keySym == XK_F9) id = LINUXKEY_F9;
else if(keySym == XK_F10) id = LINUXKEY_F10;
else if(keySym == XK_F11) id = LINUXKEY_F11;
else if(keySym == XK_F12) id = LINUXKEY_F12;
//
else if(keySym == XK_Tab) id = LINUXKEY_TAB;
//
else if(keySym == XK_BackSpace) id = LINUXKEY_BACKSPACE;
else if(keySym == XK_Prior) id = LINUXKEY_PRIOR;
else if(keySym == XK_Next) id = LINUXKEY_NEXT;
//
else if(keySym == XK_Up) id = LINUXKEY_UP;
else if(keySym == XK_Down) id = LINUXKEY_DOWN;
else if(keySym == XK_Left) id = LINUXKEY_LEFT;
else if(keySym == XK_Right) id = LINUXKEY_RIGHT;
return id;
}
void LinuxSampleUserInput::doOnMouseMove(physx::PxU32 x, physx::PxU32 y, physx::PxReal dx, physx::PxReal dy, physx::PxU16 button)
{
const std::vector<size_t>* events = getInputEvents(button);
if(events)
{
for (size_t i = events->size(); i--;)
{
const InputEvent& ie = mInputEvents[(*events)[i]];
if(getInputEventListener())
{
getInputEventListener()->onPointerInputEvent(ie, x, y, dx, dy, false);
}
}
}
}
void LinuxSampleUserInput::doOnMouseDown(physx::PxU32 x, physx::PxU32 y, physx::PxU16 button)
{
const std::vector<size_t>* events = getInputEvents(getInputIdFromMouseButton(button));
if(events)
{
for (size_t i = events->size(); i--;)
{
const InputEvent& ie = mInputEvents[(*events)[i]];
m_DigitalStates[ie.m_Id] = true;
if(getInputEventListener())
{
getInputEventListener()->onPointerInputEvent(ie, x, y, 0, 0, true);
}
}
}
}
void LinuxSampleUserInput::doOnMouseUp(physx::PxU32 x, physx::PxU32 y, physx::PxU16 button)
{
const std::vector<size_t>* events = getInputEvents(getInputIdFromMouseButton(button));
if(events)
{
for (size_t i = events->size(); i--;)
{
const InputEvent& ie = mInputEvents[(*events)[i]];
m_DigitalStates[ie.m_Id] = false;
if(getInputEventListener())
{
getInputEventListener()->onPointerInputEvent(ie, x, y, 0, 0, false);
}
}
}
}
void LinuxSampleUserInput::doOnKeyDown(KeySym keySym, physx::PxU16 keyCode, physx::PxU8 ascii)
{
const std::vector<size_t>* events = NULL;
if(getInputEventListener())
{
//raw ASCII printable characters get sent to the console
if (ascii >= 'a' && ascii <= 'z')
{
getInputEventListener()->onKeyDownEx(static_cast<KeyCode>(ascii - 'a' + KEY_A), ascii);
}
else if (ascii >= 'A' && ascii <= 'Z')
{
getInputEventListener()->onKeyDownEx(static_cast<KeyCode>(ascii - 'A' + KEY_A), ascii);
}
else if (ascii >= '0' && ascii <= '9')
{
getInputEventListener()->onKeyDownEx(static_cast<KeyCode>(ascii - 'A' + KEY_A), ascii);
}
else if (ascii == ' ')
{
getInputEventListener()->onKeyDownEx(static_cast<KeyCode>(ascii - ' ' + KEY_SPACE), ascii);
}
else if (ascii == '.')
{
getInputEventListener()->onKeyDownEx(static_cast<KeyCode>(ascii - '.' + KEY_DECIMAL), ascii);
}
std::map<physx::PxU16, physx::PxU16>::iterator fit = m_ScanCodesMap.find(keyCode);
if(fit != m_ScanCodesMap.end())
{
events = getInputEvents(fit->second);
}
if(!events)
{
LinuxSampleUserInputIds id = getInputIdFromKeySym(keySym);
events = getInputEvents(id);
}
if(!events || !getInputEventListener())
return;
for (size_t i = events->size(); i--;)
{
const InputEvent& ie = mInputEvents[(*events)[i]];
m_DigitalStates[ie.m_Id] = true;
getInputEventListener()->onDigitalInputEvent(ie, true);
}
}
}
void LinuxSampleUserInput::doOnKeyUp( KeySym keySym, physx::PxU16 keyCode, physx::PxU8 ascii)
{
const std::vector<size_t>* events = NULL;
std::map<physx::PxU16, physx::PxU16>::iterator fit = m_ScanCodesMap.find(keyCode);
if(fit != m_ScanCodesMap.end())
{
events = getInputEvents(fit->second);
}
if(!events)
{
LinuxSampleUserInputIds id = getInputIdFromKeySym(keySym);
events = getInputEvents(id);
}
if(!events || !getInputEventListener())
return;
for (size_t i = events->size(); i--;)
{
const InputEvent& ie = mInputEvents[(*events)[i]];
m_DigitalStates[ie.m_Id] = false;
getInputEventListener()->onDigitalInputEvent(ie, false);
}
}
bool LinuxSampleUserInput::getDigitalInputEventState(physx::PxU16 inputEventId ) const
{
std::map<physx::PxU16,bool>::const_iterator fit = m_DigitalStates.find(inputEventId);
if(fit != m_DigitalStates.end())
{
return fit->second;
}
else
{
return false;
}
}
float LinuxSampleUserInput::getAnalogInputEventState(physx::PxU16 inputEventId ) const
{
std::map<physx::PxU16,float>::const_iterator fit = m_AnalogStates.find(inputEventId);
if(fit != m_AnalogStates.end())
{
return fit->second;
}
else
{
return 0.0f;
}
}
void LinuxSampleUserInput::shutdown()
{
m_AnalogStates.clear();
m_DigitalStates.clear();
SampleUserInput::shutdown();
}
void LinuxSampleUserInput::updateInput()
{
SampleUserInput::updateInput();
processGamepads();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,825 @@
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
#include <windows/WindowsSampleUserInput.h>
#include <foundation/PxAssert.h>
#include <stdio.h>
#include <direct.h>
static bool gTimeInit=false;
// PT: TODO: share this with PxApplication
static const unsigned int MAX_GAMEPADS = 4;
static const unsigned int MAX_GAMEPAD_AXES = 4;
static XINPUT_STATE m_lastInputState[MAX_GAMEPADS];
static int m_lastAxisData[MAX_GAMEPADS][MAX_GAMEPAD_AXES];
using namespace SampleFramework;
using namespace physx;
WindowsSampleUserInput::WindowsSampleUserInput()
{
mXInputLibrary = 0;
mpXInputGetState = 0;
mpXInputGetCapabilities = 0;
static const unsigned int xInputLibCount = 4;
static const char* xInputLibs[xInputLibCount] = { "xinput1_4.dll" ,
"xinput1_3.dll",
"xinput1_2.dll",
"xinput1_1.dll" };
for (unsigned int i = 0; i < xInputLibCount; ++i)
{
mXInputLibrary = LoadLibraryA(xInputLibs[i]);
if(mXInputLibrary)
break;
}
PX_ASSERT(mXInputLibrary && "Could not load XInput library.");
if (mXInputLibrary)
{
mpXInputGetState = (LPXINPUTGETSTATE)GetProcAddress(mXInputLibrary, "XInputGetState");
mpXInputGetCapabilities = (LPXINPUTGETCAPABILITIES)GetProcAddress(mXInputLibrary, "XInputGetCapabilities");
PX_ASSERT(mpXInputGetState && "Error loading XInputGetState function.");
PX_ASSERT(mpXInputGetCapabilities && "Error loading XInputGetCapabilities function.");
}
mGamePadConnected = false;
mConnectedPad = 0;
// register all user inputs for windows platform
registerUserInput(WKEY_1,"KEY_1", "1");
registerUserInput(WKEY_2,"KEY_2", "2");
registerUserInput(WKEY_3,"KEY_3", "3");
registerUserInput(WKEY_4,"KEY_4", "4");
registerUserInput(WKEY_5,"KEY_5", "5");
registerUserInput(WKEY_6,"KEY_6", "6");
registerUserInput(WKEY_7,"KEY_7", "7");
registerUserInput(WKEY_8,"KEY_8", "8");
registerUserInput(WKEY_9,"KEY_9", "9");
registerUserInput(WKEY_0,"KEY_0", "0");
registerUserInput(WKEY_A,"KEY_A", "A");
registerUserInput(WKEY_B,"KEY_B", "B");
registerUserInput(WKEY_C,"KEY_C", "C");
registerUserInput(WKEY_D,"KEY_D", "D");
registerUserInput(WKEY_E,"KEY_E", "E");
registerUserInput(WKEY_F,"KEY_F", "F");
registerUserInput(WKEY_G,"KEY_G", "G");
registerUserInput(WKEY_H,"KEY_H", "H");
registerUserInput(WKEY_I,"KEY_I", "I");
registerUserInput(WKEY_J,"KEY_J", "J");
registerUserInput(WKEY_K,"KEY_K", "K");
registerUserInput(WKEY_L,"KEY_L", "L");
registerUserInput(WKEY_M,"KEY_M", "M");
registerUserInput(WKEY_N,"KEY_N", "N");
registerUserInput(WKEY_O,"KEY_O", "O");
registerUserInput(WKEY_P,"KEY_P", "P");
registerUserInput(WKEY_Q,"KEY_Q", "Q");
registerUserInput(WKEY_R,"KEY_R", "R");
registerUserInput(WKEY_S,"KEY_S", "S");
registerUserInput(WKEY_T,"KEY_T", "T");
registerUserInput(WKEY_U,"KEY_U", "U");
registerUserInput(WKEY_V,"KEY_V", "V");
registerUserInput(WKEY_W,"KEY_W", "W");
registerUserInput(WKEY_X,"KEY_X", "X");
registerUserInput(WKEY_Y,"KEY_Y", "Y");
registerUserInput(WKEY_Z,"KEY_Z", "Z");
registerUserInput(WKEY_SPACE ,"KEY_SPACE","Space");
registerUserInput(WKEY_RETURN ,"KEY_RETURN","Enter");
registerUserInput(WKEY_SHIFT ,"KEY_SHIFT","Shift");
registerUserInput(WKEY_CONTROL ,"KEY_CONTROL","Control");
registerUserInput(WKEY_ESCAPE ,"KEY_ESCAPE","Escape");
registerUserInput(WKEY_COMMA ,"KEY_COMMA",",");
registerUserInput(WKEY_NUMPAD0 ,"KEY_NUMPAD0","Numpad 0");
registerUserInput(WKEY_NUMPAD1 ,"KEY_NUMPAD1","Numpad 1");
registerUserInput(WKEY_NUMPAD2 ,"KEY_NUMPAD2","Numpad 2");
registerUserInput(WKEY_NUMPAD3 ,"KEY_NUMPAD3","Numpad 3");
registerUserInput(WKEY_NUMPAD4 ,"KEY_NUMPAD4","Numpad 4");
registerUserInput(WKEY_NUMPAD5 ,"KEY_NUMPAD5","Numpad 5");
registerUserInput(WKEY_NUMPAD6 ,"KEY_NUMPAD6","Numpad 6");
registerUserInput(WKEY_NUMPAD7 ,"KEY_NUMPAD7","Numpad 7");
registerUserInput(WKEY_NUMPAD8 ,"KEY_NUMPAD8","Numpad 8");
registerUserInput(WKEY_NUMPAD9 ,"KEY_NUMPAD9","Numpad 9");
registerUserInput(WKEY_MULTIPLY ,"KEY_MULTIPLY","*");
registerUserInput(WKEY_ADD ,"KEY_ADD","+");
registerUserInput(WKEY_SEPARATOR ,"KEY_SEPARATOR","Separator");
registerUserInput(WKEY_SUBTRACT ,"KEY_SUBTRACT","-");
registerUserInput(WKEY_DECIMAL ,"KEY_DECIMAL",".");
registerUserInput(WKEY_DIVIDE ,"KEY_DIVIDE","/");
registerUserInput(WKEY_F1 ,"KEY_F1","F1");
registerUserInput(WKEY_F2 ,"KEY_F2","F2");
registerUserInput(WKEY_F3 ,"KEY_F3","F3");
registerUserInput(WKEY_F4 ,"KEY_F4","F4");
registerUserInput(WKEY_F5 ,"KEY_F5","F5");
registerUserInput(WKEY_F6 ,"KEY_F6","F6");
registerUserInput(WKEY_F7 ,"KEY_F7","F7");
registerUserInput(WKEY_F8 ,"KEY_F8","F8");
registerUserInput(WKEY_F9 ,"KEY_F9","F9");
registerUserInput(WKEY_F10 ,"KEY_F10","F10");
registerUserInput(WKEY_F11 ,"KEY_F11","F11");
registerUserInput(WKEY_F12 ,"KEY_F12","F12");
registerUserInput(WKEY_TAB ,"KEY_TAB","Tab");
registerUserInput(WKEY_BACKSPACE,"KEY_BACKSPACE","Backspace");
registerUserInput(WKEY_PRIOR ,"KEY_PRIOR","PgUp");
registerUserInput(WKEY_NEXT ,"KEY_NEXT","PgDn");
registerUserInput(WKEY_UP ,"KEY_UP","Up Arrow");
registerUserInput(WKEY_DOWN ,"KEY_DOWN","Down Arrow");
registerUserInput(WKEY_LEFT ,"KEY_LEFT","Left Arrow");
registerUserInput(WKEY_RIGHT ,"KEY_RIGHT","Right Arrow");
// mouse
registerUserInput(MOUSE_BUTTON_LEFT ,"MOUSE_BUTTON_LEFT","Left Mouse Button");
registerUserInput(MOUSE_BUTTON_RIGHT ,"MOUSE_BUTTON_RIGHT","Right Mouse Button");
registerUserInput(MOUSE_BUTTON_CENTER ,"MOUSE_BUTTON_CENTER","Middle Mouse Button");
registerUserInput(MOUSE_MOVE,"MOUSE_MOVE", "Mouse Move");
//assumes the pad naming conventions of xbox
registerUserInput(GAMEPAD_DIGI_UP,"GAMEPAD_DIGI_UP", "gpad UP");
registerUserInput(GAMEPAD_DIGI_DOWN,"GAMEPAD_DIGI_DOWN", "gpad DOWN");
registerUserInput(GAMEPAD_DIGI_LEFT,"GAMEPAD_DIGI_LEFT", "gpad LEFT");
registerUserInput(GAMEPAD_DIGI_RIGHT,"GAMEPAD_DIGI_RIGHT", "gpad RIGHT");
registerUserInput(GAMEPAD_START ,"GAMEPAD_START", "gpad START");
registerUserInput(GAMEPAD_SELECT ,"GAMEPAD_SELECT", "gpad BACK");
registerUserInput(GAMEPAD_LEFT_STICK ,"GAMEPAD_LEFT_STICK", "gpad LSTICK");
registerUserInput(GAMEPAD_RIGHT_STICK ,"GAMEPAD_RIGHT_STICK", "gpad RSTICK");
registerUserInput(GAMEPAD_NORTH ,"GAMEPAD_NORTH", "gpad Y");
registerUserInput(GAMEPAD_SOUTH ,"GAMEPAD_SOUTH", "gpad A");
registerUserInput(GAMEPAD_WEST ,"GAMEPAD_WEST", "gpad X");
registerUserInput(GAMEPAD_EAST ,"GAMEPAD_EAST", "gpad B");
registerUserInput(GAMEPAD_LEFT_SHOULDER_TOP ,"GAMEPAD_LEFT_SHOULDER_TOP", "gpad LB");
registerUserInput(GAMEPAD_RIGHT_SHOULDER_TOP ,"GAMEPAD_RIGHT_SHOULDER_TOP", "gpad RB");
registerUserInput(GAMEPAD_LEFT_SHOULDER_BOT ,"GAMEPAD_LEFT_SHOULDER_BOT", "gpad LT");
registerUserInput(GAMEPAD_RIGHT_SHOULDER_BOT ,"GAMEPAD_RIGHT_SHOULDER_BOT", "gpad RT");
registerUserInput(GAMEPAD_RIGHT_STICK_X,"GAMEPAD_RIGHT_STICK_X", "gpad RSTICK");
registerUserInput(GAMEPAD_RIGHT_STICK_Y,"GAMEPAD_RIGHT_STICK_Y", "gpad RSTICK");
registerUserInput(GAMEPAD_LEFT_STICK_X,"GAMEPAD_LEFT_STICK_X", "gpad LSTICK");
registerUserInput(GAMEPAD_LEFT_STICK_Y,"GAMEPAD_LEFT_STICK_Y", "gpad LSTICK");
// use scan codes for movement
PxU16 vkey = (PxU16) MapVirtualKey(18, MAPVK_VSC_TO_VK);
WindowsSampleUserInputIds getId = getKeyCode(vkey);
const UserInput* ui = getUserInputFromId(getId);
if(ui)
{
registerUserInput(SCAN_CODE_UP,"SCAN_CODE_E", ui->m_Name);
mScanCodesMap[18] = SCAN_CODE_UP;
}
vkey = (PxU16)MapVirtualKey(46, MAPVK_VSC_TO_VK);
getId = getKeyCode(vkey);
ui = getUserInputFromId(getId);
if(ui)
{
registerUserInput(SCAN_CODE_DOWN,"SCAN_CODE_C", ui->m_Name);
mScanCodesMap[46] = SCAN_CODE_DOWN;
}
vkey = (PxU16) MapVirtualKey(30, MAPVK_VSC_TO_VK);
getId = getKeyCode(vkey);
ui = getUserInputFromId(getId);
if(ui)
{
registerUserInput(SCAN_CODE_LEFT,"SCAN_CODE_A", ui->m_Name);
mScanCodesMap[30] = SCAN_CODE_LEFT;
}
vkey = (PxU16) MapVirtualKey(32, MAPVK_VSC_TO_VK);
getId = getKeyCode(vkey);
ui = getUserInputFromId(getId);
if(ui)
{
registerUserInput(SCAN_CODE_RIGHT,"SCAN_CODE_D", ui->m_Name);
mScanCodesMap[32] = SCAN_CODE_RIGHT;
}
vkey = (PxU16) MapVirtualKey(17, MAPVK_VSC_TO_VK);
getId = getKeyCode(vkey);
ui = getUserInputFromId(getId);
if(ui)
{
registerUserInput(SCAN_CODE_FORWARD,"SCAN_CODE_W", ui->m_Name);
mScanCodesMap[17] = SCAN_CODE_FORWARD;
}
vkey = (PxU16) MapVirtualKey(31, MAPVK_VSC_TO_VK);
getId = getKeyCode(vkey);
ui = getUserInputFromId(getId);
if(ui)
{
registerUserInput(SCAN_CODE_BACKWARD,"SCAN_CODE_S", ui->m_Name);
mScanCodesMap[31] = SCAN_CODE_BACKWARD;
}
vkey = (PxU16) MapVirtualKey(42, MAPVK_VSC_TO_VK);
getId = getKeyCode(vkey);
ui = getUserInputFromId(getId);
if(ui)
{
registerUserInput(SCAN_CODE_LEFT_SHIFT,"SCAN_CODE_LEFT_SHIFT", ui->m_Name);
mScanCodesMap[42] = SCAN_CODE_LEFT_SHIFT;
}
vkey = (PxU16) MapVirtualKey(57, MAPVK_VSC_TO_VK);
getId = getKeyCode(vkey);
ui = getUserInputFromId(getId);
if(ui)
{
registerUserInput(SCAN_CODE_SPACE,"SCAN_CODE_SPACE", ui->m_Name);
mScanCodesMap[57] = SCAN_CODE_SPACE;
}
vkey =(PxU16) MapVirtualKey(38, MAPVK_VSC_TO_VK);
getId = getKeyCode(vkey);
ui = getUserInputFromId(getId);
if(ui)
{
registerUserInput(SCAN_CODE_L,"SCAN_CODE_L", ui->m_Name);
mScanCodesMap[38] = SCAN_CODE_L;
}
vkey = (PxU16)MapVirtualKey(10, MAPVK_VSC_TO_VK);
getId = getKeyCode(vkey);
ui = getUserInputFromId(getId);
if(ui)
{
registerUserInput(SCAN_CODE_9,"SCAN_CODE_9", ui->m_Name);
mScanCodesMap[10] = SCAN_CODE_9;
}
vkey = (PxU16)MapVirtualKey(11, MAPVK_VSC_TO_VK);
getId = getKeyCode(vkey);
ui = getUserInputFromId(getId);
if(ui)
{
registerUserInput(SCAN_CODE_0,"SCAN_CODE_0", ui->m_Name);
mScanCodesMap[11] = SCAN_CODE_0;
}
}
const UserInput* WindowsSampleUserInput::getUserInputFromId(WindowsSampleUserInputIds id) const
{
for (size_t i = mUserInputs.size(); i--;)
{
if(mUserInputs[i].m_Id == id)
{
return &mUserInputs[i];
}
}
return NULL;
}
WindowsSampleUserInput::~WindowsSampleUserInput()
{
mScanCodesMap.clear();
mAnalogStates.clear();
mDigitalStates.clear();
if (mXInputLibrary)
{
FreeLibrary(mXInputLibrary);
mXInputLibrary = 0;
}
}
WindowsSampleUserInputIds WindowsSampleUserInput::getKeyCode(WPARAM wParam) const
{
WindowsSampleUserInputIds keyCode = WKEY_UNKNOWN;
const int keyparam = (int)wParam;
if(keyparam >= 'A' && keyparam <= 'Z') keyCode = (WindowsSampleUserInputIds)((keyparam - 'A')+WKEY_A);
else if(keyparam >= '0' && keyparam <= '9') keyCode = (WindowsSampleUserInputIds)((keyparam - '0')+WKEY_0);
else if(keyparam >= VK_NUMPAD0 && keyparam <= VK_DIVIDE) keyCode = (WindowsSampleUserInputIds)((keyparam - VK_NUMPAD0)+WKEY_NUMPAD0);
else if(keyparam == VK_SHIFT) keyCode = WKEY_SHIFT;
else if(keyparam == VK_CONTROL) keyCode = WKEY_CONTROL;
else if(keyparam == VK_SPACE) keyCode = WKEY_SPACE;
else if(keyparam == VK_RETURN) keyCode = WKEY_RETURN;
else if(keyparam == VK_ESCAPE) keyCode = WKEY_ESCAPE;
else if(keyparam == VK_OEM_COMMA) keyCode = WKEY_COMMA;
else if(keyparam == VK_OEM_2) keyCode = WKEY_DIVIDE;
else if(keyparam == VK_OEM_MINUS) keyCode = WKEY_SUBTRACT;
else if(keyparam == VK_OEM_PLUS) keyCode = WKEY_ADD;
//
else if(keyparam == VK_F1) keyCode = WKEY_F1;
else if(keyparam == VK_F2) keyCode = WKEY_F2;
else if(keyparam == VK_F3) keyCode = WKEY_F3;
else if(keyparam == VK_F4) keyCode = WKEY_F4;
else if(keyparam == VK_F5) keyCode = WKEY_F5;
else if(keyparam == VK_F6) keyCode = WKEY_F6;
else if(keyparam == VK_F7) keyCode = WKEY_F7;
else if(keyparam == VK_F8) keyCode = WKEY_F8;
else if(keyparam == VK_F9) keyCode = WKEY_F9;
else if(keyparam == VK_F10) keyCode = WKEY_F10;
else if(keyparam == VK_F11) keyCode = WKEY_F11;
else if(keyparam == VK_F12) keyCode = WKEY_F12;
//
else if(keyparam == VK_TAB) keyCode = WKEY_TAB;
else if(keyparam == VK_BACK) keyCode = WKEY_BACKSPACE;
//
else if(keyparam == VK_PRIOR) keyCode = WKEY_PRIOR;
else if(keyparam == VK_NEXT) keyCode = WKEY_NEXT;
//
else if(keyparam == VK_UP) keyCode = WKEY_UP;
else if(keyparam == VK_DOWN) keyCode = WKEY_DOWN;
else if(keyparam == VK_LEFT) keyCode = WKEY_LEFT;
else if(keyparam == VK_RIGHT) keyCode = WKEY_RIGHT;
return keyCode;
}
SampleUserInput::KeyCode WindowsSampleUserInput::getSampleUserInputKeyCode(WPARAM wParam) const
{
SampleUserInput::KeyCode keyCode = KEY_UNKNOWN;
const int keyparam = (int)wParam;
// PT: TODO: the comment below is of course wrong. You just need to use the proper event code (WM_CHAR)
//there are no lowercase virtual key codes!!
//if( keyparam >= 'a' && keyparam <= 'z') keyCode = (RendererWindow::KeyCode)((keyparam - 'a')+KEY_A); else
if(keyparam >= 'A' && keyparam <= 'Z') keyCode = (SampleUserInput::KeyCode)((keyparam - 'A')+KEY_A);
else if(keyparam >= '0' && keyparam <= '9') keyCode = (SampleUserInput::KeyCode)((keyparam - '0')+KEY_0);
else if(keyparam >= VK_NUMPAD0 && keyparam <= VK_DIVIDE) keyCode = (SampleUserInput::KeyCode)((keyparam - VK_NUMPAD0)+KEY_NUMPAD0);
else if(keyparam == VK_SHIFT) keyCode = KEY_SHIFT;
else if(keyparam == VK_CONTROL) keyCode = KEY_CONTROL;
else if(keyparam == VK_SPACE) keyCode = KEY_SPACE;
else if(keyparam == VK_RETURN) keyCode = KEY_RETURN;
else if(keyparam == VK_ESCAPE) keyCode = KEY_ESCAPE;
else if(keyparam == VK_OEM_COMMA) keyCode = KEY_COMMA;
else if(keyparam == VK_OEM_2) keyCode = KEY_DIVIDE;
else if(keyparam == VK_OEM_MINUS) keyCode = KEY_SUBTRACT;
else if(keyparam == VK_OEM_PLUS) keyCode = KEY_ADD;
//
else if(keyparam == VK_F1) keyCode = KEY_F1;
else if(keyparam == VK_F2) keyCode = KEY_F2;
else if(keyparam == VK_F3) keyCode = KEY_F3;
else if(keyparam == VK_F4) keyCode = KEY_F4;
else if(keyparam == VK_F5) keyCode = KEY_F5;
else if(keyparam == VK_F6) keyCode = KEY_F6;
else if(keyparam == VK_F7) keyCode = KEY_F7;
else if(keyparam == VK_F8) keyCode = KEY_F8;
else if(keyparam == VK_F9) keyCode = KEY_F9;
else if(keyparam == VK_F10) keyCode = KEY_F10;
else if(keyparam == VK_F11) keyCode = KEY_F11;
else if(keyparam == VK_F12) keyCode = KEY_F12;
//
else if(keyparam == VK_TAB) keyCode = KEY_TAB;
//
else if(keyparam == VK_PRIOR) keyCode = KEY_PRIOR;
else if(keyparam == VK_NEXT) keyCode = KEY_NEXT;
//
else if(keyparam == VK_UP) keyCode = KEY_UP;
else if(keyparam == VK_DOWN) keyCode = KEY_DOWN;
else if(keyparam == VK_LEFT) keyCode = KEY_LEFT;
else if(keyparam == VK_RIGHT) keyCode = KEY_RIGHT;
return keyCode;
}
void WindowsSampleUserInput::doOnMouseMove(physx::PxU32 x, physx::PxU32 y, physx::PxReal dx, physx::PxReal dy, WindowsSampleUserInputIds button)
{
const std::vector<size_t>* events = getInputEvents((PxU16)button);
if(events)
{
for (size_t i = events->size(); i--;)
{
const InputEvent& ie = mInputEvents[(*events)[i]];
if(getInputEventListener())
{
getInputEventListener()->onPointerInputEvent(ie, x, y, dx, dy, false);
}
}
}
}
void WindowsSampleUserInput::doOnMouseButton(physx::PxU32 x, physx::PxU32 y , MouseButtons button, bool down)
{
WindowsSampleUserInputIds buttonId = WKEY_UNKNOWN;
WindowsSampleUserInputIds buttonIdOpposite = WKEY_UNKNOWN;
switch (button)
{
case LEFT_MOUSE_BUTTON:
buttonId = MOUSE_BUTTON_LEFT;
break;
case RIGHT_MOUSE_BUTTON:
buttonId = MOUSE_BUTTON_RIGHT;
break;
case CENTER_MOUSE_BUTTON:
buttonId = MOUSE_BUTTON_CENTER;
break;
}
const std::vector<size_t>* events = getInputEvents((PxU16)buttonId);
if(events)
{
for (size_t i = events->size(); i--;)
{
const InputEvent& ie = mInputEvents[(*events)[i]];
mDigitalStates[ie.m_Id] = down;
if(getInputEventListener())
{
getInputEventListener()->onPointerInputEvent(ie, x, y, 0, 0, down);
}
}
}
}
void WindowsSampleUserInput::onKeyDownEx(WPARAM wParam)
{
if(getInputEventListener())
{
KeyCode keyCode = getSampleUserInputKeyCode(wParam);
getInputEventListener()->onKeyDownEx(keyCode, (PxU32)wParam);
}
}
void WindowsSampleUserInput::onKeyDown(WPARAM wParam, LPARAM lParam)
{
PxU16 scanCode = (lParam >> 16) & 0xFF;
const std::vector<size_t>* events = NULL;
std::map<physx::PxU16, physx::PxU16>::iterator fit = mScanCodesMap.find(scanCode);
if(fit != mScanCodesMap.end())
{
events = getInputEvents(fit->second);
}
if(!events)
{
WindowsSampleUserInputIds keyCode = getKeyCode(wParam);
events = getInputEvents((PxU16)keyCode);
}
if(!events || !getInputEventListener())
return;
for (size_t i = events->size(); i--;)
{
const InputEvent& ie = mInputEvents[(*events)[i]];
mDigitalStates[ie.m_Id] = true;
getInputEventListener()->onDigitalInputEvent(ie, true);
}
}
void WindowsSampleUserInput::onKeyUp(WPARAM wParam, LPARAM lParam)
{
PxU16 scanCode = (lParam >> 16) & 0xFF;
const std::vector<size_t>* events = NULL;
std::map<physx::PxU16, physx::PxU16>::iterator fit = mScanCodesMap.find(scanCode);
if(fit != mScanCodesMap.end())
{
events = getInputEvents(fit->second);
}
if(!events)
{
WindowsSampleUserInputIds keyCode = getKeyCode(wParam);
events = getInputEvents((PxU16)keyCode);
}
if(!events || !getInputEventListener())
return;
for (size_t i = events->size(); i--;)
{
const InputEvent& ie = mInputEvents[(*events)[i]];
mDigitalStates[ie.m_Id] = false;
getInputEventListener()->onDigitalInputEvent(ie, false);
}
}
void WindowsSampleUserInput::onKeyEvent(const KeyEvent& keyEvent)
{
WindowsSampleUserInputIds keyCode = getKeyCode(keyEvent.m_Param);
const std::vector<size_t>* events = getInputEvents((PxU16)keyCode);
if(!events || !getInputEventListener())
return;
for (size_t i = events->size(); i--;)
{
const InputEvent& ie = mInputEvents[(*events)[i]];
if(keyEvent.m_Flags == KEY_EVENT_UP)
{
mDigitalStates[ie.m_Id] = false;
getInputEventListener()->onDigitalInputEvent(ie, false);
}
if(keyEvent.m_Flags == KEY_EVENT_DOWN)
{
mDigitalStates[ie.m_Id] = true;
getInputEventListener()->onDigitalInputEvent(ie, true);
}
}
}
bool WindowsSampleUserInput::getDigitalInputEventState(physx::PxU16 inputEventId ) const
{
std::map<physx::PxU16,bool>::const_iterator fit = mDigitalStates.find(inputEventId);
if(fit != mDigitalStates.end())
{
return fit->second;
}
else
{
return false;
}
}
float WindowsSampleUserInput::getAnalogInputEventState(physx::PxU16 inputEventId ) const
{
std::map<physx::PxU16,float>::const_iterator fit = mAnalogStates.find(inputEventId);
if(fit != mAnalogStates.end())
{
return fit->second;
}
else
{
return 0.0f;
}
}
void WindowsSampleUserInput::onGamepadAnalogButton(physx::PxU32 buttonIndex,const BYTE oldValue,const BYTE newValue)
{
const std::vector<size_t>* events = getInputEvents((PxU16)buttonIndex);
if(!events || !getInputEventListener())
return;
bool newUp = false;
bool newDown = false;
if( !oldValue && newValue )
{
newUp = true;
}
else if( oldValue && !newValue )
{
newDown = true;
}
for (size_t i = events->size(); i--;)
{
const InputEvent& ie = mInputEvents[(*events)[i]];
if(ie.m_Analog)
{
mAnalogStates[ie.m_Id] = newValue/255.0f;
getInputEventListener()->onAnalogInputEvent(ie, newValue/255.0f);
}
else
{
if(newUp)
{
mDigitalStates[ie.m_Id] = true;
getInputEventListener()->onDigitalInputEvent(ie, true);
}
if(newDown)
{
mDigitalStates[ie.m_Id] = false;
getInputEventListener()->onDigitalInputEvent(ie, false);
}
}
}
}
void WindowsSampleUserInput::onGamepadButton(physx::PxU32 buttonIndex, bool buttonDown)
{
PxU16 userInput = (PxU16) (GAMEPAD_DIGI_UP + buttonIndex);
const std::vector<size_t>* events = getInputEvents(userInput);
if(!events || !getInputEventListener())
return;
for (size_t i = 0; i < events->size(); i++)
{
const InputEvent& ie = mInputEvents[(*events)[i]];
mDigitalStates[ie.m_Id] = buttonDown;
getInputEventListener()->onDigitalInputEvent(ie, buttonDown);
}
}
void WindowsSampleUserInput::onGamepadAxis(physx::PxU32 axis, physx::PxReal val)
{
PxU16 userInput = (PxU16)(GAMEPAD_RIGHT_STICK_X + axis);
const std::vector<size_t>* events = getInputEvents(userInput);
if(!events || !getInputEventListener())
return;
for (size_t i = events->size(); i--;)
{
const InputEvent& ie = mInputEvents[(*events)[i]];
mAnalogStates[ie.m_Id] = val;
getInputEventListener()->onAnalogInputEvent(ie, val);
}
}
void WindowsSampleUserInput::shutdown()
{
mAnalogStates.clear();
mDigitalStates.clear();
SampleUserInput::shutdown();
}
void WindowsSampleUserInput::updateInput()
{
SampleUserInput::updateInput();
processGamepads();
}
void WindowsSampleUserInput::processGamepads()
{
SampleUserInput::processGamepads();
if(!gTimeInit)
{
gTimeInit=true;
for(PxU32 p=0;p<MAX_GAMEPADS;p++)
{
memset(&m_lastInputState[p], 0, sizeof(XINPUT_STATE));
for(PxU32 i=0;i<MAX_GAMEPAD_AXES;i++)
{
m_lastAxisData[p][i]=0;
}
}
}
static PxI32 disConnected[4] = {1, 2, 3, 4};
if (!hasXInput())
return;
// PT: TODO: share this with PxApplication
for(PxU32 p=0;p<MAX_GAMEPADS;p++)
{
if((--disConnected[p]) == 0)
{
XINPUT_STATE inputState;
DWORD state = mpXInputGetState(p, &inputState);
if(state == ERROR_DEVICE_NOT_CONNECTED)
{
disConnected[p] = 4;
if(mGamePadConnected && (mConnectedPad == p))
{
mGamePadConnected = false;
mConnectedPad = 0;
for (PxU32 k=0;k<MAX_GAMEPADS;k++)
{
XINPUT_STATE inputStateDisc;
DWORD stateDisc = mpXInputGetState(k, &inputStateDisc);
if(stateDisc == ERROR_SUCCESS)
{
mConnectedPad = k;
mGamePadConnected = true;
break;
}
}
}
}
else if(state == ERROR_SUCCESS)
{
if(!mGamePadConnected)
{
mGamePadConnected = true;
mConnectedPad = p;
}
disConnected[p] = 1; //force to test next time
XINPUT_CAPABILITIES caps;
mpXInputGetCapabilities(p, XINPUT_FLAG_GAMEPAD, &caps);
//gamepad
{
// Process buttons
const WORD lastWButtons = m_lastInputState[p].Gamepad.wButtons;
const WORD currWButtons = inputState.Gamepad.wButtons;
const WORD buttonsDown = currWButtons & ~lastWButtons;
const WORD buttonsUp = ~currWButtons & lastWButtons;
// const WORD buttonsHeld = currWButtons & lastWButtons;
for(int i=0;i<14;i++)
{
// order has to match struct GamepadControls
static const WORD buttonMasks[]={
XINPUT_GAMEPAD_DPAD_UP,
XINPUT_GAMEPAD_DPAD_DOWN,
XINPUT_GAMEPAD_DPAD_LEFT,
XINPUT_GAMEPAD_DPAD_RIGHT,
XINPUT_GAMEPAD_START,
XINPUT_GAMEPAD_BACK,
XINPUT_GAMEPAD_LEFT_THUMB,
XINPUT_GAMEPAD_RIGHT_THUMB,
XINPUT_GAMEPAD_Y,
XINPUT_GAMEPAD_A,
XINPUT_GAMEPAD_X,
XINPUT_GAMEPAD_B,
XINPUT_GAMEPAD_LEFT_SHOULDER,
XINPUT_GAMEPAD_RIGHT_SHOULDER,
};
if (buttonsDown & buttonMasks[i])
onGamepadButton(i, true);
else if(buttonsUp & buttonMasks[i])
onGamepadButton(i, false);
}
// PT: I think we do the 2 last ones separately because they're listed in GamepadControls but not in buttonMasks...
{
const BYTE oldTriggerVal = m_lastInputState[p].Gamepad.bRightTrigger;
const BYTE newTriggerVal = inputState.Gamepad.bRightTrigger;
onGamepadAnalogButton(GAMEPAD_RIGHT_SHOULDER_BOT, oldTriggerVal, newTriggerVal);
}
{
const BYTE oldTriggerVal = m_lastInputState[p].Gamepad.bLeftTrigger;
const BYTE newTriggerVal = inputState.Gamepad.bLeftTrigger;
onGamepadAnalogButton(GAMEPAD_LEFT_SHOULDER_BOT, oldTriggerVal, newTriggerVal);
}
}
// Gamepad
const int axisData[] = {inputState.Gamepad.sThumbRX, inputState.Gamepad.sThumbRY, inputState.Gamepad.sThumbLX, inputState.Gamepad.sThumbLY };
for(PxU32 i=0;i<MAX_GAMEPAD_AXES;i++)
{
if(axisData[i] != m_lastAxisData[p][i])
{
int data = axisData[i];
if(abs(data) < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
{
data = 0;
}
onGamepadAxis( i, ((float)data)/SHRT_MAX);
}
m_lastAxisData[p][i] = axisData[i];
}
m_lastInputState[p] = inputState;
}
}
}
}
bool WindowsSampleUserInput::gamepadSupported() const
{
return mGamePadConnected;
}
InputType WindowsSampleUserInput::getInputType(const UserInput& ui) const
{
if(ui.m_Id > WKEY_DEFINITION_START && ui.m_Id < WKEY_DEFINITION_END)
{
return KEYBOARD_INPUT;
}
if(ui.m_Id > GAMEPAD_DEFINITION_START && ui.m_Id < GAMEPAD_DEFINITION_END)
{
return GAMEPAD_INPUT;
}
if(ui.m_Id > MOUSE_DEFINITION_START && ui.m_Id < MOUSE_DEFINITION_END)
{
return MOUSE_INPUT;
}
return UNDEFINED_INPUT;
}