Merge pull request #10 from RetroView/windows

Windows refactors
This commit is contained in:
Jack Andersen 2015-08-30 20:33:40 -10:00
commit de51c2dcc5
13 changed files with 263 additions and 194 deletions

View File

@ -9,9 +9,9 @@ if(WIN32)
list(APPEND PLAT_SRCS
lib/win/ApplicationWin32.cpp
lib/win/WindowWin32.cpp
lib/win/GraphicsContextWin32.cpp
lib/inputdev/HIDListenerWinUSB.cpp
lib/inputdev/HIDDeviceWinUSB.cpp)
list(APPEND _BOO_SYS_LIBS Winusb)
elseif(APPLE)
list(APPEND PLAT_SRCS
lib/mac/ApplicationCocoa.mm
@ -93,6 +93,7 @@ add_library(Boo
include/boo/IGraphicsContext.hpp
include/boo/IWindow.hpp
include/boo/IApplication.hpp
include/boo/System.hpp
include/boo/boo.hpp
InputDeviceClasses.cpp
${PLAT_SRCS})

View File

@ -1,5 +1,5 @@
#ifndef IRUNLOOP_HPP
#define IRUNLOOP_HPP
#ifndef IAPPLICATION_HPP
#define IAPPLICATION_HPP
#include <memory>
#include <string>
@ -15,7 +15,7 @@ class IApplication;
struct IApplicationCallback
{
virtual void appQuitting(IApplication*) {}
virtual void appFilesOpen(IApplication*, const std::vector<std::string>&) {}
virtual void appFilesOpen(IApplication*, const std::vector<SystemString>&) {}
};
class IApplication
@ -44,37 +44,37 @@ public:
virtual EPlatformType getPlatformType() const=0;
virtual void pump()=0;
virtual const std::string& getUniqueName() const=0;
virtual const std::string& getFriendlyName() const=0;
virtual const std::string& getProcessName() const=0;
virtual const std::vector<std::string>& getArgs() const=0;
virtual const SystemString& getUniqueName() const=0;
virtual const SystemString& getFriendlyName() const=0;
virtual const SystemString& getProcessName() const=0;
virtual const std::vector<SystemString>& getArgs() const=0;
/* Constructors/initializers for sub-objects */
virtual IWindow* newWindow(const std::string& title)=0;
virtual IWindow* newWindow(const SystemString& title)=0;
};
std::unique_ptr<IApplication>
ApplicationBootstrap(IApplication::EPlatformType platform,
IApplicationCallback& cb,
const std::string& uniqueName,
const std::string& friendlyName,
const std::string& pname,
const std::vector<std::string>& args,
const SystemString& uniqueName,
const SystemString& friendlyName,
const SystemString& pname,
const std::vector<SystemString>& args,
bool singleInstance=true);
extern IApplication* APP;
static inline std::unique_ptr<IApplication>
ApplicationBootstrap(IApplication::EPlatformType platform,
IApplicationCallback& cb,
const std::string& uniqueName,
const std::string& friendlyName,
int argc, const char** argv,
const SystemString& uniqueName,
const SystemString& friendlyName,
int argc, const SystemChar** argv,
bool singleInstance=true)
{
if (APP)
return std::unique_ptr<IApplication>();
std::vector<std::string> args;
std::vector<SystemString> args;
for (int i=1 ; i<argc ; ++i)
args.push_back(argv[i]);
return ApplicationBootstrap(platform, cb, uniqueName, friendlyName, argv[0], args, singleInstance);
@ -82,4 +82,4 @@ ApplicationBootstrap(IApplication::EPlatformType platform,
}
#endif // IRUNLOOP_HPP
#endif // IAPPLICATION_HPP

View File

@ -1,7 +1,7 @@
#ifndef IWINDOW_HPP
#define IWINDOW_HPP
#include <string>
#include "System.hpp"
namespace boo
{
@ -123,8 +123,8 @@ public:
virtual void showWindow()=0;
virtual void hideWindow()=0;
virtual std::string getTitle()=0;
virtual void setTitle(const std::string& title)=0;
virtual SystemString getTitle()=0;
virtual void setTitle(const SystemString& title)=0;
virtual void setWindowFrameDefault()=0;
virtual void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const=0;

25
include/boo/System.hpp Normal file
View File

@ -0,0 +1,25 @@
#ifndef BOO_SYSTEM_HPP
#define BOO_SYSTEM_HPP
#include <string>
namespace boo
{
#ifdef _WIN32
using SystemString = std::wstring;
using SystemChar = wchar_t;
# ifndef _S
# define _S(val) L ## val
# endif
#else
using SystemString = std::string;
using SystemChar = char;
# ifndef _S
# define _S(val) val
# endif
#endif
}
#endif

View File

@ -11,7 +11,9 @@
#include <stdio.h>
#ifdef _WIN32
#define _WIN32_LEAN_AND_MEAN 1
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
#include <Dbt.h>
#endif
@ -163,7 +165,7 @@ public:
{
PDEV_BROADCAST_HDR dbh = (PDEV_BROADCAST_HDR)lParam;
PDEV_BROADCAST_DEVICEINTERFACE dbhi = (PDEV_BROADCAST_DEVICEINTERFACE)lParam;
CDeviceFinder* finder = instance();
DeviceFinder* finder = instance();
if (!finder)
return 0;

View File

@ -1,10 +1,18 @@
#include "boo/inputdev/DualshockPad.hpp"
#define _USE_MATH_DEFINES
#include <math.h>
#include <iostream>
#include <stdio.h>
#include <endian.h>
#include <memory.h>
#ifdef _WIN32
static inline uint16_t bswap16(uint16_t val) {return _byteswap_ushort(val);}
#elif __GNUC__
static inline uint16_t bswap16(uint16_t val) {return __builtin_bswap16(val); }
#else
static inline uint16_t bswap16(uint16_t val) {return __builtin_byteswap(val);}
#endif
#define RAD_TO_DEG (180.0/M_PI)
void hexdump(void *ptr, int buflen) {
@ -80,9 +88,9 @@ void DualshockPad::transferCycle()
return;
for (int i = 0; i < 3; i++)
state.m_accelerometer[i] = be16toh(state.m_accelerometer[i]);
state.m_accelerometer[i] = bswap16(state.m_accelerometer[i]);
state.m_gyrometerZ = be16toh(state.m_gyrometerZ);
state.m_gyrometerZ = bswap16(state.m_gyrometerZ);
if (m_callback)
m_callback->controllerUpdate(state);

View File

@ -1,14 +1,16 @@
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
#include "IHIDDevice.hpp"
#include "inputdev/CDeviceToken.hpp"
#include "inputdev/CDeviceBase.hpp"
#include "boo/inputdev/DeviceToken.hpp"
#include "boo/inputdev/DeviceBase.hpp"
#include <thread>
#include <mutex>
#include <condition_variable>
#include <string.h>
#include <stdio.h>
#define _WIN32_LEAN_AND_MEAN 1
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
#include <winusb.h>
#include <usb100.h>
@ -17,10 +19,10 @@
namespace boo
{
class CHIDDeviceWinUSB final : public IHIDDevice
class HIDDeviceWinUSB final : public IHIDDevice
{
CDeviceToken& m_token;
CDeviceBase& m_devImp;
DeviceToken& m_token;
DeviceBase& m_devImp;
HANDLE m_devHandle = 0;
WINUSB_INTERFACE_HANDLE m_usbHandle = NULL;
@ -60,7 +62,7 @@ class CHIDDeviceWinUSB final : public IHIDDevice
return 0;
}
static void _threadProcUSBLL(CHIDDeviceWinUSB* device)
static void _threadProcUSBLL(HIDDeviceWinUSB* device)
{
unsigned i;
char errStr[256];
@ -141,7 +143,7 @@ class CHIDDeviceWinUSB final : public IHIDDevice
}
static void _threadProcBTLL(CHIDDeviceWinUSB* device)
static void _threadProcBTLL(HIDDeviceWinUSB* device)
{
std::unique_lock<std::mutex> lk(device->m_initMutex);
@ -158,7 +160,7 @@ class CHIDDeviceWinUSB final : public IHIDDevice
}
static void _threadProcHID(CHIDDeviceWinUSB* device)
static void _threadProcHID(HIDDeviceWinUSB* device)
{
std::unique_lock<std::mutex> lk(device->m_initMutex);
@ -187,26 +189,26 @@ class CHIDDeviceWinUSB final : public IHIDDevice
public:
CHIDDeviceWinUSB(CDeviceToken& token, CDeviceBase& devImp)
HIDDeviceWinUSB(DeviceToken& token, DeviceBase& devImp)
: m_token(token),
m_devImp(devImp),
m_devPath(token.getDevicePath())
{
devImp.m_hidDev = this;
std::unique_lock<std::mutex> lk(m_initMutex);
CDeviceToken::TDeviceType dType = token.getDeviceType();
if (dType == CDeviceToken::DEVTYPE_USB)
DeviceToken::TDeviceType dType = token.getDeviceType();
if (dType == DeviceToken::DEVTYPE_USB)
m_thread = new std::thread(_threadProcUSBLL, this);
else if (dType == CDeviceToken::DEVTYPE_BLUETOOTH)
else if (dType == DeviceToken::DEVTYPE_BLUETOOTH)
m_thread = new std::thread(_threadProcBTLL, this);
else if (dType == CDeviceToken::DEVTYPE_GENERICHID)
else if (dType == DeviceToken::DEVTYPE_GENERICHID)
m_thread = new std::thread(_threadProcHID, this);
else
throw std::runtime_error("invalid token supplied to device constructor");
m_initCond.wait(lk);
}
~CHIDDeviceWinUSB()
~HIDDeviceWinUSB()
{
m_runningTransferLoop = false;
m_thread->join();
@ -216,9 +218,9 @@ public:
};
IHIDDevice* IHIDDeviceNew(CDeviceToken& token, CDeviceBase& devImp)
IHIDDevice* IHIDDeviceNew(DeviceToken& token, DeviceBase& devImp)
{
return new CHIDDeviceWinUSB(token, devImp);
return new HIDDeviceWinUSB(token, devImp);
}
}

View File

@ -1,10 +1,12 @@
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
#include "inputdev/IHIDListener.hpp"
#include "inputdev/CDeviceFinder.hpp"
#include "boo/inputdev/IHIDListener.hpp"
#include "boo/inputdev/DeviceFinder.hpp"
#include <string.h>
#include <thread>
#define _WIN32_LEAN_AND_MEAN 1
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
#include <initguid.h>
@ -16,9 +18,9 @@
namespace boo
{
class CHIDListenerWinUSB final : public IHIDListener
class HIDListenerWinUSB final : public IHIDListener
{
CDeviceFinder& m_finder;
DeviceFinder& m_finder;
bool m_scanningEnabled;
@ -140,9 +142,9 @@ class CHIDListenerWinUSB final : public IHIDListener
/* Whew!! that's a single device enumerated!! */
if (!m_finder._hasToken(DeviceInterfaceDetailData.wtf.DevicePath))
m_finder._insertToken(CDeviceToken(CDeviceToken::DEVTYPE_USB,
vid, pid, manuf, product,
DeviceInterfaceDetailData.wtf.DevicePath));
m_finder._insertToken(DeviceToken(DeviceToken::DEVTYPE_USB,
vid, pid, manuf, product,
DeviceInterfaceDetailData.wtf.DevicePath));
}
@ -151,14 +153,14 @@ class CHIDListenerWinUSB final : public IHIDListener
}
public:
CHIDListenerWinUSB(CDeviceFinder& finder)
HIDListenerWinUSB(DeviceFinder& finder)
: m_finder(finder)
{
/* Initial HID Device Add */
_pollDevices(NULL);
}
~CHIDListenerWinUSB()
~HIDListenerWinUSB()
{}
/* Automatic device scanning */
@ -201,9 +203,9 @@ public:
};
IHIDListener* IHIDListenerNew(CDeviceFinder& finder)
IHIDListener* IHIDListenerNew(DeviceFinder& finder)
{
return new CHIDListenerWinUSB(finder);
return new HIDListenerWinUSB(finder);
}
}

View File

@ -13,7 +13,7 @@ class IHIDDevice
virtual bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length)=0;
virtual size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length)=0;
virtual bool _sendHIDReport(const uint8_t* data, size_t length, uint16_t message)=0;
virtual size_t _recieveReport(const uint8_t* data, size_t length, uint16_t message){}
virtual size_t _recieveReport(const uint8_t* data, size_t length, uint16_t message) {return 0;}
public:
inline virtual ~IHIDDevice() {}
};

View File

@ -1,41 +1,47 @@
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
#define _WIN32_LEAN_AND_MEAN 1
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
#include <shellapi.h>
#include <initguid.h>
#include <Usbiodef.h>
#include <unordered_map>
#include "IRunLoop.hpp"
#include "inputdev/CDeviceFinder.hpp"
#include "boo/IApplication.hpp"
#include "boo/inputdev/DeviceFinder.hpp"
namespace boo
{
IWindow* _CWindowWin32New(const std::string& title);
IWindow* _WindowWin32New(const SystemString& title);
class CApplicationWin32 final : public IApplication
class ApplicationWin32 final : public IApplication
{
const IApplicationCallback& m_callback;
const std::string m_friendlyName;
const std::string m_pname;
const std::vector<std::string> m_args;
const SystemString m_uniqueName;
const SystemString m_friendlyName;
const SystemString m_pname;
const std::vector<SystemString> m_args;
std::unordered_map<HWND, IWindow*> m_allWindows;
bool m_singleInstance;
void _deletedWindow(IWindow* window)
{
m_allWindows.erase(window);
m_allWindows.erase(HWND(window->getPlatformHandle()));
}
public:
CApplicationWin32(const IApplicationCallback& callback,
const std::string& friendlyName,
const std::string& pname,
const std::vector<std::string>& args,
bool singleInstance)
ApplicationWin32(const IApplicationCallback& callback,
const SystemString& uniqueName,
const SystemString& friendlyName,
const SystemString& pname,
const std::vector<SystemString>& args,
bool singleInstance)
: m_callback(callback),
m_uniqueName(uniqueName),
m_friendlyName(friendlyName),
m_pname(pname),
m_args(args),
@ -57,14 +63,14 @@ public:
return 0;
case WM_DEVICECHANGE:
return CDeviceFinder::winDevChangedHandler(wParam, lParam);
return DeviceFinder::winDevChangedHandler(wParam, lParam);
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
void run()
void pump()
{
/* Pump messages */
MSG msg = {0};
@ -75,40 +81,53 @@ public:
}
}
const std::string& getProcessName() const
const SystemString& getUniqueName() const
{
return m_uniqueName;
}
const SystemString& getFriendlyName() const
{
return m_friendlyName;
}
const SystemString& getProcessName() const
{
return m_pname;
}
const std::vector<std::string>& getArgs() const
const std::vector<SystemString>& getArgs() const
{
return m_args;
}
IWindow* newWindow(const std::string& title)
IWindow* newWindow(const SystemString& title)
{
IWindow* window = _CWindowWin32New(title);
HWND hwnd = window->getPlatformHandle();
IWindow* window = _WindowWin32New(title);
HWND hwnd = HWND(window->getPlatformHandle());
m_allWindows[hwnd] = window;
return window;
}
};
IApplication* APP = NULL;
IApplication* IApplicationBootstrap(IApplication::EPlatformType platform,
IApplicationCallback& cb,
const std::string& friendlyName,
const std::string& pname,
const std::vector<std::string>& args,
bool singleInstance)
std::unique_ptr<IApplication>
ApplicationBootstrap(IApplication::EPlatformType platform,
IApplicationCallback& cb,
const SystemString& uniqueName,
const SystemString& friendlyName,
const SystemString& pname,
const std::vector<SystemString>& args,
bool singleInstance)
{
if (!APP)
{
if (platform != IApplication::PLAT_WIN32 &&
platform != IApplication::PLAT_AUTO)
return NULL;
APP = new CApplicationWin32(cb, friendlyName, pname, args, singleInstance);
APP = new ApplicationWin32(cb, uniqueName, friendlyName, pname, args, singleInstance);
}
return APP;
return std::unique_ptr<IApplication>(APP);
}
}
@ -123,16 +142,17 @@ static const DEV_BROADCAST_DEVICEINTERFACE_A HOTPLUG_CONF =
static bool HOTPLUG_REGISTERED = false;
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (!HOTPLUG_REGISTERED && hwnd == WM_CREATE)
if (!HOTPLUG_REGISTERED && uMsg == WM_CREATE)
{
/* Register hotplug notification with windows */
RegisterDeviceNotificationA(hwnd, (LPVOID)&HOTPLUG_CONF, DEVICE_NOTIFY_WINDOW_HANDLE);
HOTPLUG_REGISTERED = true;
}
return IRunLoopInstance()->winHwndHandler(hwnd, uMsg, wParam, lParam);
return static_cast<boo::ApplicationWin32*>(boo::APP)->winHwndHandler(hwnd, uMsg, wParam, lParam);
}
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPCWSTR lpCmdLine, int)
int wmain(int argc, wchar_t** argv);
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int)
{
#if DEBUG
/* Debug console */
@ -161,6 +181,6 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, LPCWSTR lpCmdLine, int)
LPWSTR* argv = CommandLineToArgvW(lpCmdLine, &argc);
/* Call into the 'proper' entry point */
return main(argc, argv);
return wmain(argc, argv);
}

View File

@ -1,83 +0,0 @@
#include "windowsys/IGraphicsContext.hpp"
#include "windowsys/IWindow.hpp"
namespace boo
{
class CGraphicsContextWin32 final : public IGraphicsContext
{
EGraphicsAPI m_api;
EPixelFormat m_pf;
IWindow* m_parentWindow;
public:
IWindowCallback* m_callback;
CGraphicsContextWin32(EGraphicsAPI api, IWindow* parentWindow)
: m_api(api),
m_pf(PF_RGBA8),
m_parentWindow(parentWindow)
{}
~CGraphicsContextWin32()
{
}
void _setCallback(IWindowCallback* cb)
{
m_callback = cb;
}
EGraphicsAPI getAPI() const
{
return m_api;
}
EPixelFormat getPixelFormat() const
{
return m_pf;
}
void setPixelFormat(EPixelFormat pf)
{
if (pf > PF_RGBAF32_Z24)
return;
m_pf = pf;
}
void initializeContext()
{
}
IGraphicsContext* makeShareContext() const
{
}
void makeCurrent()
{
}
void clearCurrent()
{
}
void swapBuffer()
{
}
};
IGraphicsContext* _CGraphicsContextWin32New(IGraphicsContext::EGraphicsAPI api,
IWindow* parentWindow)
{
}
}

View File

@ -1,27 +1,98 @@
#include "windowsys/IWindow.hpp"
#include "windowsys/IGraphicsContext.hpp"
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <Windows.h>
#include "boo/IWindow.hpp"
#include "boo/IGraphicsContext.hpp"
namespace boo
{
IGraphicsContext* _CGraphicsContextWin32New(IGraphicsContext::EGraphicsAPI api,
IWindow* parentWindow);
struct GraphicsContextWin32 : IGraphicsContext
{
EGraphicsAPI m_api;
EPixelFormat m_pf;
IWindow* m_parentWindow;
public:
IWindowCallback* m_callback;
GraphicsContextWin32(EGraphicsAPI api, IWindow* parentWindow)
: m_api(api),
m_pf(PF_RGBA8),
m_parentWindow(parentWindow)
{}
~GraphicsContextWin32()
{
}
void _setCallback(IWindowCallback* cb)
{
m_callback = cb;
}
EGraphicsAPI getAPI() const
{
return m_api;
}
EPixelFormat getPixelFormat() const
{
return m_pf;
}
void setPixelFormat(EPixelFormat pf)
{
if (pf > PF_RGBAF32_Z24)
return;
m_pf = pf;
}
void initializeContext()
{
}
IGraphicsContext* makeShareContext() const
{
}
void makeCurrent()
{
}
void clearCurrent()
{
}
void swapBuffer()
{
}
};
class CWindowWin32 final : public IWindow
class WindowWin32 : public IWindow
{
HWND m_hwnd;
public:
CWindowWin32(const std::string& title)
WindowWin32(const SystemString& title)
{
m_hwnd = CreateWindowW(L"BooWindow", L"BooTest", WS_OVERLAPPEDWINDOW,
m_hwnd = CreateWindowW(L"BooWindow", title.c_str(), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
NULL, NULL, NULL, NULL);
}
~CWindowWin32()
~WindowWin32()
{
}
@ -41,14 +112,16 @@ public:
}
std::string getTitle()
SystemString getTitle()
{
wchar_t title[256];
int c = GetWindowTextW(m_hwnd, title, 256);
return SystemString(title, c);
}
void setTitle(const std::string& title)
void setTitle(const SystemString& title)
{
SetWindowTextW(m_hwnd, title.c_str());
}
void setWindowFrameDefault()
@ -68,29 +141,38 @@ public:
float getVirtualPixelFactor() const
{
return 1.0;
}
bool isFullscreen() const
{
return false;
}
void setFullscreen(bool fs)
{
}
void waitForRetrace()
{
}
uintptr_t getPlatformHandle() const
{
return uintptr_t(m_hwnd);
}
ETouchType getTouchType() const
{
return TOUCH_NONE;
}
};
IWindow* _CWindowWin32New(const std::string& title)
IWindow* _WindowWin32New(const SystemString& title)
{
return new CWindowWin32(title);
return new WindowWin32(title);
}
}

View File

@ -174,7 +174,7 @@ struct TestApplicationCallback : IApplicationCallback
CTestWindowCallback windowCallback;
void appLaunched(IApplication* app)
{
mainWindow = app->newWindow("YAY!");
mainWindow = app->newWindow(_S("YAY!"));
mainWindow->setCallback(&windowCallback);
mainWindow->showWindow();
devFinder.startScanning();
@ -183,23 +183,33 @@ struct TestApplicationCallback : IApplicationCallback
{
delete mainWindow;
}
void appFilesOpen(IApplication*, const std::vector<std::string>& paths)
void appFilesOpen(IApplication*, const std::vector<SystemString>& paths)
{
fprintf(stderr, "OPENING: ");
for (const std::string& path : paths)
for (const SystemString& path : paths)
{
#if _WIN32
fwprintf(stderr, L"%s ", path.c_str());
#else
fprintf(stderr, "%s ", path.c_str());
#endif
}
fprintf(stderr, "\n");
}
};
}
#ifdef _WIN32
int wmain(int argc, const wchar_t** argv)
#else
int main(int argc, const char** argv)
#endif
{
boo::TestApplicationCallback appCb;
std::unique_ptr<boo::IApplication> app =
ApplicationBootstrap(boo::IApplication::PLAT_AUTO,
appCb, "rwk", "RWK", argc, argv);
appCb, _S("rwk"), _S("RWK"), argc, argv);
printf("IM DYING!!\n");
return 0;
}