Reformat Windows (Resharper)

This commit is contained in:
Vladimir Kononovich 2020-12-19 23:33:11 +03:00
parent c0aabf20a1
commit 6c4907ed1d
26 changed files with 6430 additions and 5578 deletions

View file

@ -26,18 +26,23 @@ void DirectInputManager::Initialize()
// Register with the DirectInput subsystem and get a pointer to a IDirectInput interface we can use. // Register with the DirectInput subsystem and get a pointer to a IDirectInput interface we can use.
// Create a DInput object // Create a DInput object
if(FAILED(hr = DirectInput8Create(GetModuleHandle(nullptr), DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&_directInput, nullptr))) { if (FAILED(
hr = DirectInput8Create(GetModuleHandle(nullptr), DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&_directInput,
nullptr)))
{
MessageManager::Log("[DInput] DirectInput8Create failed: " + std::to_string(hr)); MessageManager::Log("[DInput] DirectInput8Create failed: " + std::to_string(hr));
return; return;
} }
IDirectInputJoyConfig8* pJoyConfig = nullptr; IDirectInputJoyConfig8* pJoyConfig = nullptr;
if(FAILED(hr = _directInput->QueryInterface(IID_IDirectInputJoyConfig8, (void**)&pJoyConfig))) { if (FAILED(hr = _directInput->QueryInterface(IID_IDirectInputJoyConfig8, (void**)&pJoyConfig)))
{
MessageManager::Log("[DInput] QueryInterface failed: " + std::to_string(hr)); MessageManager::Log("[DInput] QueryInterface failed: " + std::to_string(hr));
return; return;
} }
if(pJoyConfig) { if (pJoyConfig)
{
pJoyConfig->Release(); pJoyConfig->Release();
} }
@ -48,19 +53,25 @@ bool DirectInputManager::ProcessDevice(const DIDEVICEINSTANCE* pdidInstance)
{ {
const GUID* deviceGuid = &pdidInstance->guidInstance; const GUID* deviceGuid = &pdidInstance->guidInstance;
auto comp = [=](GUID guid) { auto comp = [=](GUID guid)
{
return guid.Data1 == deviceGuid->Data1 && return guid.Data1 == deviceGuid->Data1 &&
guid.Data2 == deviceGuid->Data2 && guid.Data2 == deviceGuid->Data2 &&
guid.Data3 == deviceGuid->Data3 && guid.Data3 == deviceGuid->Data3 &&
memcmp(guid.Data4, deviceGuid->Data4, sizeof(guid.Data4)) == 0; memcmp(guid.Data4, deviceGuid->Data4, sizeof(guid.Data4)) == 0;
}; };
bool wasProcessedBefore = std::find_if(_processedGuids.begin(), _processedGuids.end(), comp) != _processedGuids.end(); bool wasProcessedBefore = std::find_if(_processedGuids.begin(), _processedGuids.end(), comp) != _processedGuids.
if(wasProcessedBefore) { end();
if (wasProcessedBefore)
{
return false; return false;
} else { }
else
{
bool isXInput = IsXInputDevice(&pdidInstance->guidProduct); bool isXInput = IsXInputDevice(&pdidInstance->guidProduct);
if(isXInput) { if (isXInput)
{
_xinputDeviceGuids.push_back(*deviceGuid); _xinputDeviceGuids.push_back(*deviceGuid);
_processedGuids.push_back(*deviceGuid); _processedGuids.push_back(*deviceGuid);
} }
@ -75,26 +86,28 @@ bool DirectInputManager::ProcessDevice(const DIDEVICEINSTANCE* pdidInstance)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool DirectInputManager::IsXInputDevice(const GUID* pGuidProductFromDirectInput) bool DirectInputManager::IsXInputDevice(const GUID* pGuidProductFromDirectInput)
{ {
IWbemLocator* pIWbemLocator = NULL; IWbemLocator* pIWbemLocator = NULL;
IEnumWbemClassObject* pEnumDevices = NULL; IEnumWbemClassObject* pEnumDevices = NULL;
IWbemClassObject* pDevices[20] = { 0 }; IWbemClassObject* pDevices[20] = {0};
IWbemServices* pIWbemServices = NULL; IWbemServices* pIWbemServices = NULL;
BSTR bstrNamespace = NULL; BSTR bstrNamespace = NULL;
BSTR bstrDeviceID = NULL; BSTR bstrDeviceID = NULL;
BSTR bstrClassName = NULL; BSTR bstrClassName = NULL;
DWORD uReturned = 0; DWORD uReturned = 0;
bool bIsXinputDevice = false; bool bIsXinputDevice = false;
UINT iDevice = 0; UINT iDevice = 0;
VARIANT var; VARIANT var;
HRESULT hr; HRESULT hr;
// CoInit if needed // CoInit if needed
hr = CoInitialize(NULL); hr = CoInitialize(NULL);
bool bCleanupCOM = SUCCEEDED(hr); bool bCleanupCOM = SUCCEEDED(hr);
// Create WMI // Create WMI
hr = CoCreateInstance(__uuidof(WbemLocator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IWbemLocator), (LPVOID*)&pIWbemLocator); hr = CoCreateInstance(__uuidof(WbemLocator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IWbemLocator),
if(FAILED(hr) || pIWbemLocator == NULL) { (LPVOID*)&pIWbemLocator);
if (FAILED(hr) || pIWbemLocator == NULL)
{
goto LCleanup; goto LCleanup;
} }
@ -104,47 +117,58 @@ bool DirectInputManager::IsXInputDevice(const GUID* pGuidProductFromDirectInput)
// Connect to WMI // Connect to WMI
hr = pIWbemLocator->ConnectServer(bstrNamespace, NULL, NULL, 0L, 0L, NULL, NULL, &pIWbemServices); hr = pIWbemLocator->ConnectServer(bstrNamespace, NULL, NULL, 0L, 0L, NULL, NULL, &pIWbemServices);
if(FAILED(hr) || pIWbemServices == NULL) { if (FAILED(hr) || pIWbemServices == NULL)
{
goto LCleanup; goto LCleanup;
} }
// Switch security level to IMPERSONATE. // Switch security level to IMPERSONATE.
CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
hr = pIWbemServices->CreateInstanceEnum(bstrClassName, 0, NULL, &pEnumDevices); hr = pIWbemServices->CreateInstanceEnum(bstrClassName, 0, NULL, &pEnumDevices);
if(FAILED(hr) || pEnumDevices == NULL) { if (FAILED(hr) || pEnumDevices == NULL)
{
goto LCleanup; goto LCleanup;
} }
// Loop over all devices // Loop over all devices
for(;; ) { for (;;)
{
// Get 20 at a time // Get 20 at a time
hr = pEnumDevices->Next(10000, 20, pDevices, &uReturned); hr = pEnumDevices->Next(10000, 20, pDevices, &uReturned);
if(FAILED(hr) || uReturned == 0 || bIsXinputDevice) { if (FAILED(hr) || uReturned == 0 || bIsXinputDevice)
{
break; break;
} }
for(iDevice = 0; iDevice < uReturned; iDevice++) { for (iDevice = 0; iDevice < uReturned; iDevice++)
{
// For each device, get its device ID // For each device, get its device ID
hr = pDevices[iDevice]->Get(bstrDeviceID, 0L, &var, NULL, NULL); hr = pDevices[iDevice]->Get(bstrDeviceID, 0L, &var, NULL, NULL);
if(SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != NULL) { if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != NULL)
{
// Check if the device ID contains "IG_". If it does, then it's an XInput device // Check if the device ID contains "IG_". If it does, then it's an XInput device
// This information can not be found from DirectInput // This information can not be found from DirectInput
if(wcsstr(var.bstrVal, L"IG_")) { if (wcsstr(var.bstrVal, L"IG_"))
{
// If it does, then get the VID/PID from var.bstrVal // If it does, then get the VID/PID from var.bstrVal
DWORD dwPid = 0, dwVid = 0; DWORD dwPid = 0, dwVid = 0;
WCHAR* strVid = wcsstr(var.bstrVal, L"VID_"); WCHAR* strVid = wcsstr(var.bstrVal, L"VID_");
if(strVid && swscanf_s(strVid, L"VID_%4X", &dwVid) != 1) { if (strVid && swscanf_s(strVid, L"VID_%4X", &dwVid) != 1)
{
dwVid = 0; dwVid = 0;
} }
WCHAR* strPid = wcsstr(var.bstrVal, L"PID_"); WCHAR* strPid = wcsstr(var.bstrVal, L"PID_");
if(strPid && swscanf_s(strPid, L"PID_%4X", &dwPid) != 1) { if (strPid && swscanf_s(strPid, L"PID_%4X", &dwPid) != 1)
{
dwPid = 0; dwPid = 0;
} }
// Compare the VID/PID to the DInput device // Compare the VID/PID to the DInput device
DWORD dwVidPid = MAKELONG(dwVid, dwPid); DWORD dwVidPid = MAKELONG(dwVid, dwPid);
if(dwVidPid == pGuidProductFromDirectInput->Data1) { if (dwVidPid == pGuidProductFromDirectInput->Data1)
{
bIsXinputDevice = true; bIsXinputDevice = true;
pDevices[iDevice]->Release(); pDevices[iDevice]->Release();
pDevices[iDevice] = nullptr; pDevices[iDevice] = nullptr;
@ -159,31 +183,40 @@ bool DirectInputManager::IsXInputDevice(const GUID* pGuidProductFromDirectInput)
} }
LCleanup: LCleanup:
if(bstrNamespace) { if (bstrNamespace)
{
SysFreeString(bstrNamespace); SysFreeString(bstrNamespace);
} }
if(bstrDeviceID) { if (bstrDeviceID)
{
SysFreeString(bstrDeviceID); SysFreeString(bstrDeviceID);
} }
if(bstrClassName) { if (bstrClassName)
{
SysFreeString(bstrClassName); SysFreeString(bstrClassName);
} }
for(iDevice = 0; iDevice < 20; iDevice++) { for (iDevice = 0; iDevice < 20; iDevice++)
if(pDevices[iDevice]) { {
if (pDevices[iDevice])
{
pDevices[iDevice]->Release(); pDevices[iDevice]->Release();
} }
} }
if(pEnumDevices) { if (pEnumDevices)
{
pEnumDevices->Release(); pEnumDevices->Release();
} }
if(pIWbemLocator) { if (pIWbemLocator)
{
pIWbemLocator->Release(); pIWbemLocator->Release();
} }
if(pIWbemServices) { if (pIWbemServices)
{
pIWbemServices->Release(); pIWbemServices->Release();
} }
if(bCleanupCOM) { if (bCleanupCOM)
{
CoUninitialize(); CoUninitialize();
} }
@ -192,7 +225,8 @@ LCleanup:
void DirectInputManager::UpdateDeviceList() void DirectInputManager::UpdateDeviceList()
{ {
if(_needToUpdate) { if (_needToUpdate)
{
//An update is already pending, skip //An update is already pending, skip
return; return;
} }
@ -200,15 +234,20 @@ void DirectInputManager::UpdateDeviceList()
HRESULT hr; HRESULT hr;
// Enumerate devices // Enumerate devices
if(SUCCEEDED(hr = _directInput->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, nullptr, DIEDFL_ALLDEVICES))) { if (SUCCEEDED(
if(!_joysticksToAdd.empty()) { hr = _directInput->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, nullptr, DIEDFL_ALLDEVICES)))
{
if (!_joysticksToAdd.empty())
{
//Sleeping apparently lets us read accurate "default" values, otherwise a PS4 controller returns all 0s, despite not doing so normally //Sleeping apparently lets us read accurate "default" values, otherwise a PS4 controller returns all 0s, despite not doing so normally
for(DirectInputData &joystick : _joysticksToAdd) { for (DirectInputData& joystick : _joysticksToAdd)
{
UpdateInputState(joystick); UpdateInputState(joystick);
} }
std::this_thread::sleep_for(std::chrono::duration<int, std::milli>(100)); std::this_thread::sleep_for(std::chrono::duration<int, std::milli>(100));
for(DirectInputData &joystick : _joysticksToAdd) { for (DirectInputData& joystick : _joysticksToAdd)
{
UpdateInputState(joystick); UpdateInputState(joystick);
joystick.defaultState = joystick.state; joystick.defaultState = joystick.state;
} }
@ -216,7 +255,8 @@ void DirectInputManager::UpdateDeviceList()
} }
} }
if(_requestUpdate) { if (_requestUpdate)
{
_requestUpdate = false; _requestUpdate = false;
_needToUpdate = true; _needToUpdate = true;
} }
@ -231,38 +271,51 @@ int DirectInputManager::EnumJoysticksCallback(const DIDEVICEINSTANCE* pdidInstan
{ {
HRESULT hr; HRESULT hr;
if(ProcessDevice(pdidInstance)) { if (ProcessDevice(pdidInstance))
{
_processedGuids.push_back(pdidInstance->guidInstance); _processedGuids.push_back(pdidInstance->guidInstance);
// Obtain an interface to the enumerated joystick. // Obtain an interface to the enumerated joystick.
LPDIRECTINPUTDEVICE8 pJoystick = nullptr; LPDIRECTINPUTDEVICE8 pJoystick = nullptr;
hr = _directInput->CreateDevice(pdidInstance->guidInstance, &pJoystick, nullptr); hr = _directInput->CreateDevice(pdidInstance->guidInstance, &pJoystick, nullptr);
if(SUCCEEDED(hr)) { if (SUCCEEDED(hr))
{
DIJOYSTATE2 state; DIJOYSTATE2 state;
memset(&state, 0, sizeof(state)); memset(&state, 0, sizeof(state));
DirectInputData data{ pJoystick, state, state, false }; DirectInputData data{pJoystick, state, state, false};
memcpy(&data.instanceInfo, pdidInstance, sizeof(DIDEVICEINSTANCE)); memcpy(&data.instanceInfo, pdidInstance, sizeof(DIDEVICEINSTANCE));
// Set the data format to "simple joystick" - a predefined data format // Set the data format to "simple joystick" - a predefined data format
// A data format specifies which controls on a device we are interested in, and how they should be reported. // A data format specifies which controls on a device we are interested in, and how they should be reported.
// This tells DInput that we will be passing a DIJOYSTATE2 structure to IDirectInputDevice::GetDeviceState(). // This tells DInput that we will be passing a DIJOYSTATE2 structure to IDirectInputDevice::GetDeviceState().
if(SUCCEEDED(hr = data.joystick->SetDataFormat(&c_dfDIJoystick2))) { if (SUCCEEDED(hr = data.joystick->SetDataFormat(&c_dfDIJoystick2)))
{
// Set the cooperative level to let DInput know how this device should interact with the system and with other DInput applications. // Set the cooperative level to let DInput know how this device should interact with the system and with other DInput applications.
if(SUCCEEDED(hr = data.joystick->SetCooperativeLevel(_hWnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND))) { if (SUCCEEDED(hr = data.joystick->SetCooperativeLevel(_hWnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND)))
{
// Enumerate the joystick objects. The callback function enabled user interface elements for objects that are found, and sets the min/max values property for discovered axes. // Enumerate the joystick objects. The callback function enabled user interface elements for objects that are found, and sets the min/max values property for discovered axes.
if(SUCCEEDED(hr = data.joystick->EnumObjects(EnumObjectsCallback, data.joystick, DIDFT_ALL))) { if (SUCCEEDED(hr = data.joystick->EnumObjects(EnumObjectsCallback, data.joystick, DIDFT_ALL)))
{
_joysticksToAdd.push_back(data); _joysticksToAdd.push_back(data);
} else { }
else
{
MessageManager::Log("[DInput] Failed to enumerate objects: " + std::to_string(hr)); MessageManager::Log("[DInput] Failed to enumerate objects: " + std::to_string(hr));
} }
} else { }
else
{
MessageManager::Log("[DInput] Failed to set cooperative level: " + std::to_string(hr)); MessageManager::Log("[DInput] Failed to set cooperative level: " + std::to_string(hr));
} }
} else { }
else
{
MessageManager::Log("[DInput] Failed to set data format: " + std::to_string(hr)); MessageManager::Log("[DInput] Failed to set data format: " + std::to_string(hr));
} }
} else { }
else
{
MessageManager::Log("[DInput] Failed to create directinput device" + std::to_string(hr)); MessageManager::Log("[DInput] Failed to create directinput device" + std::to_string(hr));
} }
} }
@ -280,7 +333,8 @@ int DirectInputManager::EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* pdidoi
LPDIRECTINPUTDEVICE8 joystick = (LPDIRECTINPUTDEVICE8)pContext; LPDIRECTINPUTDEVICE8 joystick = (LPDIRECTINPUTDEVICE8)pContext;
// For axes that are returned, set the DIPROP_RANGE property for the enumerated axis in order to scale min/max values. // For axes that are returned, set the DIPROP_RANGE property for the enumerated axis in order to scale min/max values.
if(pdidoi->dwType & DIDFT_AXIS) { if (pdidoi->dwType & DIDFT_AXIS)
{
DIPROPRANGE diprg; DIPROPRANGE diprg;
diprg.diph.dwSize = sizeof(DIPROPRANGE); diprg.diph.dwSize = sizeof(DIPROPRANGE);
diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
@ -290,7 +344,8 @@ int DirectInputManager::EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* pdidoi
diprg.lMax = +1000; diprg.lMax = +1000;
// Set the range for the axis // Set the range for the axis
if(FAILED(joystick->SetProperty(DIPROP_RANGE, &diprg.diph))) { if (FAILED(joystick->SetProperty(DIPROP_RANGE, &diprg.diph)))
{
return DIENUM_STOP; return DIENUM_STOP;
} }
} }
@ -301,25 +356,32 @@ int DirectInputManager::EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* pdidoi
void DirectInputManager::RefreshState() void DirectInputManager::RefreshState()
{ {
if(_needToUpdate) { if (_needToUpdate)
{
vector<DirectInputData> joysticks; vector<DirectInputData> joysticks;
//Keep exisiting joysticks, if they still work, otherwise remove them from the list //Keep exisiting joysticks, if they still work, otherwise remove them from the list
for(DirectInputData &joystick : _joysticks) { for (DirectInputData& joystick : _joysticks)
if(joystick.stateValid) { {
if (joystick.stateValid)
{
joysticks.push_back(joystick); joysticks.push_back(joystick);
} else { }
else
{
MessageManager::Log("[DInput] Device lost, trying to reacquire..."); MessageManager::Log("[DInput] Device lost, trying to reacquire...");
//Release the joystick, we'll try to initialize it again if it still exists //Release the joystick, we'll try to initialize it again if it still exists
const GUID* deviceGuid = &joystick.instanceInfo.guidInstance; const GUID* deviceGuid = &joystick.instanceInfo.guidInstance;
auto comp = [=](GUID guid) { auto comp = [=](GUID guid)
{
return guid.Data1 == deviceGuid->Data1 && return guid.Data1 == deviceGuid->Data1 &&
guid.Data2 == deviceGuid->Data2 && guid.Data2 == deviceGuid->Data2 &&
guid.Data3 == deviceGuid->Data3 && guid.Data3 == deviceGuid->Data3 &&
memcmp(guid.Data4, deviceGuid->Data4, sizeof(guid.Data4)) == 0; memcmp(guid.Data4, deviceGuid->Data4, sizeof(guid.Data4)) == 0;
}; };
_processedGuids.erase(std::remove_if(_processedGuids.begin(), _processedGuids.end(), comp), _processedGuids.end()); _processedGuids.erase(std::remove_if(_processedGuids.begin(), _processedGuids.end(), comp),
_processedGuids.end());
joystick.joystick->Unacquire(); joystick.joystick->Unacquire();
joystick.joystick->Release(); joystick.joystick->Release();
@ -327,7 +389,8 @@ void DirectInputManager::RefreshState()
} }
//Add the newly-found joysticks //Add the newly-found joysticks
for(DirectInputData &joystick : _joysticksToAdd) { for (DirectInputData& joystick : _joysticksToAdd)
{
joysticks.push_back(joystick); joysticks.push_back(joystick);
} }
@ -336,7 +399,8 @@ void DirectInputManager::RefreshState()
_needToUpdate = false; _needToUpdate = false;
} }
for(DirectInputData &joystick : _joysticks) { for (DirectInputData& joystick : _joysticks)
{
UpdateInputState(joystick); UpdateInputState(joystick);
} }
} }
@ -348,7 +412,8 @@ int DirectInputManager::GetJoystickCount()
bool DirectInputManager::IsPressed(int port, int button) bool DirectInputManager::IsPressed(int port, int button)
{ {
if(port >= (int)_joysticks.size() || !_joysticks[port].stateValid) { if (port >= (int)_joysticks.size() || !_joysticks[port].stateValid)
{
return false; return false;
} }
@ -359,47 +424,51 @@ bool DirectInputManager::IsPressed(int port, int button)
int povDirection = state.rgdwPOV[0] / 4500; int povDirection = state.rgdwPOV[0] / 4500;
bool povCentered = (LOWORD(state.rgdwPOV[0]) == 0xFFFF) || povDirection >= 8; bool povCentered = (LOWORD(state.rgdwPOV[0]) == 0xFFFF) || povDirection >= 8;
switch(button) { switch (button)
case 0x00: return state.lY - defaultState.lY < -deadRange; {
case 0x01: return state.lY - defaultState.lY > deadRange; case 0x00: return state.lY - defaultState.lY < -deadRange;
case 0x02: return state.lX - defaultState.lX < -deadRange; case 0x01: return state.lY - defaultState.lY > deadRange;
case 0x03: return state.lX - defaultState.lX > deadRange; case 0x02: return state.lX - defaultState.lX < -deadRange;
case 0x04: return state.lRy - defaultState.lRy < -deadRange; case 0x03: return state.lX - defaultState.lX > deadRange;
case 0x05: return state.lRy - defaultState.lRy > deadRange; case 0x04: return state.lRy - defaultState.lRy < -deadRange;
case 0x06: return state.lRx - defaultState.lRx < -deadRange; case 0x05: return state.lRy - defaultState.lRy > deadRange;
case 0x07: return state.lRx - defaultState.lRx > deadRange; case 0x06: return state.lRx - defaultState.lRx < -deadRange;
case 0x08: return state.lZ - defaultState.lZ < -deadRange; case 0x07: return state.lRx - defaultState.lRx > deadRange;
case 0x09: return state.lZ - defaultState.lZ > deadRange; case 0x08: return state.lZ - defaultState.lZ < -deadRange;
case 0x0A: return state.lRz - defaultState.lRz < -deadRange; case 0x09: return state.lZ - defaultState.lZ > deadRange;
case 0x0B: return state.lRz - defaultState.lRz > deadRange; case 0x0A: return state.lRz - defaultState.lRz < -deadRange;
case 0x0C: return !povCentered && (povDirection == 7 || povDirection == 0 || povDirection == 1); case 0x0B: return state.lRz - defaultState.lRz > deadRange;
case 0x0D: return !povCentered && (povDirection >= 3 && povDirection <= 5); case 0x0C: return !povCentered && (povDirection == 7 || povDirection == 0 || povDirection == 1);
case 0x0E: return !povCentered && (povDirection >= 1 && povDirection <= 3); case 0x0D: return !povCentered && (povDirection >= 3 && povDirection <= 5);
case 0x0F: return !povCentered && (povDirection >= 5 && povDirection <= 7); case 0x0E: return !povCentered && (povDirection >= 1 && povDirection <= 3);
default: return state.rgbButtons[button - 0x10] != 0; case 0x0F: return !povCentered && (povDirection >= 5 && povDirection <= 7);
default: return state.rgbButtons[button - 0x10] != 0;
} }
return false; return false;
} }
void DirectInputManager::UpdateInputState(DirectInputData &data) void DirectInputManager::UpdateInputState(DirectInputData& data)
{ {
DIJOYSTATE2 newState; DIJOYSTATE2 newState;
HRESULT hr; HRESULT hr;
// Poll the device to read the current state // Poll the device to read the current state
hr = data.joystick->Poll(); hr = data.joystick->Poll();
if(FAILED(hr)) { if (FAILED(hr))
{
// DInput is telling us that the input stream has been interrupted. We aren't tracking any state between polls, so // DInput is telling us that the input stream has been interrupted. We aren't tracking any state between polls, so
// we don't have any special reset that needs to be done. We just re-acquire and try again. // we don't have any special reset that needs to be done. We just re-acquire and try again.
hr = data.joystick->Acquire(); hr = data.joystick->Acquire();
while(hr == DIERR_INPUTLOST) { while (hr == DIERR_INPUTLOST)
{
hr = data.joystick->Acquire(); hr = data.joystick->Acquire();
} }
// hr may be DIERR_OTHERAPPHASPRIO or other errors. This may occur when the app is minimized or in the process of // hr may be DIERR_OTHERAPPHASPRIO or other errors. This may occur when the app is minimized or in the process of
// switching, so just try again later // switching, so just try again later
if(FAILED(hr)) { if (FAILED(hr))
{
data.stateValid = false; data.stateValid = false;
_requestUpdate = true; _requestUpdate = true;
return; return;
@ -407,7 +476,8 @@ void DirectInputManager::UpdateInputState(DirectInputData &data)
} }
// Get the input's device state // Get the input's device state
if(FAILED(hr = data.joystick->GetDeviceState(sizeof(DIJOYSTATE2), &newState))) { if (FAILED(hr = data.joystick->GetDeviceState(sizeof(DIJOYSTATE2), &newState)))
{
MessageManager::Log("[DInput] Failed to get device state: " + std::to_string(hr)); MessageManager::Log("[DInput] Failed to get device state: " + std::to_string(hr));
data.stateValid = false; data.stateValid = false;
_requestUpdate = true; _requestUpdate = true;
@ -428,7 +498,8 @@ DirectInputManager::DirectInputManager(shared_ptr<Console> console, HWND hWnd)
DirectInputManager::~DirectInputManager() DirectInputManager::~DirectInputManager()
{ {
for(DirectInputData &data: _joysticks) { for (DirectInputData& data : _joysticks)
{
data.joystick->Unacquire(); data.joystick->Unacquire();
data.joystick->Release(); data.joystick->Release();
} }
@ -439,7 +510,8 @@ DirectInputManager::~DirectInputManager()
_processedGuids.clear(); _processedGuids.clear();
_xinputDeviceGuids.clear(); _xinputDeviceGuids.clear();
if(_directInput) { if (_directInput)
{
_directInput->Release(); _directInput->Release();
_directInput = nullptr; _directInput = nullptr;
} }

File diff suppressed because it is too large Load diff

View file

@ -35,47 +35,47 @@
namespace DirectX namespace DirectX
{ {
class CommonStates class CommonStates
{ {
public: public:
explicit CommonStates(_In_ ID3D11Device* device); explicit CommonStates(_In_ ID3D11Device* device);
CommonStates(CommonStates&& moveFrom); CommonStates(CommonStates&& moveFrom);
CommonStates& operator= (CommonStates&& moveFrom); CommonStates& operator=(CommonStates&& moveFrom);
virtual ~CommonStates(); virtual ~CommonStates();
// Blend states. // Blend states.
ID3D11BlendState* __cdecl Opaque() const; ID3D11BlendState* __cdecl Opaque() const;
ID3D11BlendState* __cdecl AlphaBlend() const; ID3D11BlendState* __cdecl AlphaBlend() const;
ID3D11BlendState* __cdecl Additive() const; ID3D11BlendState* __cdecl Additive() const;
ID3D11BlendState* __cdecl NonPremultiplied() const; ID3D11BlendState* __cdecl NonPremultiplied() const;
// Depth stencil states. // Depth stencil states.
ID3D11DepthStencilState* __cdecl DepthNone() const; ID3D11DepthStencilState* __cdecl DepthNone() const;
ID3D11DepthStencilState* __cdecl DepthDefault() const; ID3D11DepthStencilState* __cdecl DepthDefault() const;
ID3D11DepthStencilState* __cdecl DepthRead() const; ID3D11DepthStencilState* __cdecl DepthRead() const;
// Rasterizer states. // Rasterizer states.
ID3D11RasterizerState* __cdecl CullNone() const; ID3D11RasterizerState* __cdecl CullNone() const;
ID3D11RasterizerState* __cdecl CullClockwise() const; ID3D11RasterizerState* __cdecl CullClockwise() const;
ID3D11RasterizerState* __cdecl CullCounterClockwise() const; ID3D11RasterizerState* __cdecl CullCounterClockwise() const;
ID3D11RasterizerState* __cdecl Wireframe() const; ID3D11RasterizerState* __cdecl Wireframe() const;
// Sampler states. // Sampler states.
ID3D11SamplerState* __cdecl PointWrap() const; ID3D11SamplerState* __cdecl PointWrap() const;
ID3D11SamplerState* __cdecl PointClamp() const; ID3D11SamplerState* __cdecl PointClamp() const;
ID3D11SamplerState* __cdecl LinearWrap() const; ID3D11SamplerState* __cdecl LinearWrap() const;
ID3D11SamplerState* __cdecl LinearClamp() const; ID3D11SamplerState* __cdecl LinearClamp() const;
ID3D11SamplerState* __cdecl AnisotropicWrap() const; ID3D11SamplerState* __cdecl AnisotropicWrap() const;
ID3D11SamplerState* __cdecl AnisotropicClamp() const; ID3D11SamplerState* __cdecl AnisotropicClamp() const;
private: private:
// Private implementation. // Private implementation.
class Impl; class Impl;
std::shared_ptr<Impl> pImpl; std::shared_ptr<Impl> pImpl;
// Prevent copying. // Prevent copying.
CommonStates(CommonStates const&) DIRECTX_CTOR_DELETE CommonStates(CommonStates const&) DIRECTX_CTOR_DELETE
CommonStates& operator= (CommonStates const&) DIRECTX_CTOR_DELETE CommonStates& operator=(CommonStates const&) DIRECTX_CTOR_DELETE
}; };
} }

View file

@ -33,128 +33,128 @@
namespace DirectX namespace DirectX
{ {
enum DDS_ALPHA_MODE enum DDS_ALPHA_MODE
{ {
DDS_ALPHA_MODE_UNKNOWN = 0, DDS_ALPHA_MODE_UNKNOWN = 0,
DDS_ALPHA_MODE_STRAIGHT = 1, DDS_ALPHA_MODE_STRAIGHT = 1,
DDS_ALPHA_MODE_PREMULTIPLIED = 2, DDS_ALPHA_MODE_PREMULTIPLIED = 2,
DDS_ALPHA_MODE_OPAQUE = 3, DDS_ALPHA_MODE_OPAQUE = 3,
DDS_ALPHA_MODE_CUSTOM = 4, DDS_ALPHA_MODE_CUSTOM = 4,
}; };
// Standard version // Standard version
HRESULT __cdecl CreateDDSTextureFromMemory( _In_ ID3D11Device* d3dDevice, HRESULT __cdecl CreateDDSTextureFromMemory(_In_ ID3D11Device* d3dDevice,
_In_reads_bytes_(ddsDataSize) const uint8_t* ddsData, _In_reads_bytes_(ddsDataSize) const uint8_t* ddsData,
_In_ size_t ddsDataSize, _In_ size_t ddsDataSize,
_Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11Resource** texture,
_Outptr_opt_ ID3D11ShaderResourceView** textureView, _Outptr_opt_ ID3D11ShaderResourceView** textureView,
_In_ size_t maxsize = 0, _In_ size_t maxsize = 0,
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
); );
HRESULT __cdecl CreateDDSTextureFromFile( _In_ ID3D11Device* d3dDevice, HRESULT __cdecl CreateDDSTextureFromFile(_In_ ID3D11Device* d3dDevice,
_In_z_ const wchar_t* szFileName, _In_z_ const wchar_t* szFileName,
_Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11Resource** texture,
_Outptr_opt_ ID3D11ShaderResourceView** textureView, _Outptr_opt_ ID3D11ShaderResourceView** textureView,
_In_ size_t maxsize = 0, _In_ size_t maxsize = 0,
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
); );
// Standard version with optional auto-gen mipmap support // Standard version with optional auto-gen mipmap support
#if defined(_XBOX_ONE) && defined(_TITLE) #if defined(_XBOX_ONE) && defined(_TITLE)
HRESULT __cdecl CreateDDSTextureFromMemory( _In_ ID3D11DeviceX* d3dDevice, HRESULT __cdecl CreateDDSTextureFromMemory( _In_ ID3D11DeviceX* d3dDevice,
_In_opt_ ID3D11DeviceContextX* d3dContext, _In_opt_ ID3D11DeviceContextX* d3dContext,
#else #else
HRESULT __cdecl CreateDDSTextureFromMemory( _In_ ID3D11Device* d3dDevice, HRESULT __cdecl CreateDDSTextureFromMemory(_In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext, _In_opt_ ID3D11DeviceContext* d3dContext,
#endif #endif
_In_reads_bytes_(ddsDataSize) const uint8_t* ddsData, _In_reads_bytes_(ddsDataSize) const uint8_t* ddsData,
_In_ size_t ddsDataSize, _In_ size_t ddsDataSize,
_Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11Resource** texture,
_Outptr_opt_ ID3D11ShaderResourceView** textureView, _Outptr_opt_ ID3D11ShaderResourceView** textureView,
_In_ size_t maxsize = 0, _In_ size_t maxsize = 0,
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
); );
#if defined(_XBOX_ONE) && defined(_TITLE) #if defined(_XBOX_ONE) && defined(_TITLE)
HRESULT __cdecl CreateDDSTextureFromFile( _In_ ID3D11DeviceX* d3dDevice, HRESULT __cdecl CreateDDSTextureFromFile( _In_ ID3D11DeviceX* d3dDevice,
_In_opt_ ID3D11DeviceContextX* d3dContext, _In_opt_ ID3D11DeviceContextX* d3dContext,
#else #else
HRESULT __cdecl CreateDDSTextureFromFile( _In_ ID3D11Device* d3dDevice, HRESULT __cdecl CreateDDSTextureFromFile(_In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext, _In_opt_ ID3D11DeviceContext* d3dContext,
#endif #endif
_In_z_ const wchar_t* szFileName, _In_z_ const wchar_t* szFileName,
_Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11Resource** texture,
_Outptr_opt_ ID3D11ShaderResourceView** textureView, _Outptr_opt_ ID3D11ShaderResourceView** textureView,
_In_ size_t maxsize = 0, _In_ size_t maxsize = 0,
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
); );
// Extended version // Extended version
HRESULT __cdecl CreateDDSTextureFromMemoryEx( _In_ ID3D11Device* d3dDevice, HRESULT __cdecl CreateDDSTextureFromMemoryEx(_In_ ID3D11Device* d3dDevice,
_In_reads_bytes_(ddsDataSize) const uint8_t* ddsData, _In_reads_bytes_(ddsDataSize) const uint8_t* ddsData,
_In_ size_t ddsDataSize, _In_ size_t ddsDataSize,
_In_ size_t maxsize, _In_ size_t maxsize,
_In_ D3D11_USAGE usage, _In_ D3D11_USAGE usage,
_In_ unsigned int bindFlags, _In_ unsigned int bindFlags,
_In_ unsigned int cpuAccessFlags, _In_ unsigned int cpuAccessFlags,
_In_ unsigned int miscFlags, _In_ unsigned int miscFlags,
_In_ bool forceSRGB, _In_ bool forceSRGB,
_Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11Resource** texture,
_Outptr_opt_ ID3D11ShaderResourceView** textureView, _Outptr_opt_ ID3D11ShaderResourceView** textureView,
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
); );
HRESULT __cdecl CreateDDSTextureFromFileEx( _In_ ID3D11Device* d3dDevice, HRESULT __cdecl CreateDDSTextureFromFileEx(_In_ ID3D11Device* d3dDevice,
_In_z_ const wchar_t* szFileName, _In_z_ const wchar_t* szFileName,
_In_ size_t maxsize, _In_ size_t maxsize,
_In_ D3D11_USAGE usage, _In_ D3D11_USAGE usage,
_In_ unsigned int bindFlags, _In_ unsigned int bindFlags,
_In_ unsigned int cpuAccessFlags, _In_ unsigned int cpuAccessFlags,
_In_ unsigned int miscFlags, _In_ unsigned int miscFlags,
_In_ bool forceSRGB, _In_ bool forceSRGB,
_Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11Resource** texture,
_Outptr_opt_ ID3D11ShaderResourceView** textureView, _Outptr_opt_ ID3D11ShaderResourceView** textureView,
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
); );
// Extended version with optional auto-gen mipmap support // Extended version with optional auto-gen mipmap support
#if defined(_XBOX_ONE) && defined(_TITLE) #if defined(_XBOX_ONE) && defined(_TITLE)
HRESULT __cdecl CreateDDSTextureFromMemoryEx( _In_ ID3D11DeviceX* d3dDevice, HRESULT __cdecl CreateDDSTextureFromMemoryEx( _In_ ID3D11DeviceX* d3dDevice,
_In_opt_ ID3D11DeviceContextX* d3dContext, _In_opt_ ID3D11DeviceContextX* d3dContext,
#else #else
HRESULT __cdecl CreateDDSTextureFromMemoryEx( _In_ ID3D11Device* d3dDevice, HRESULT __cdecl CreateDDSTextureFromMemoryEx(_In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext, _In_opt_ ID3D11DeviceContext* d3dContext,
#endif #endif
_In_reads_bytes_(ddsDataSize) const uint8_t* ddsData, _In_reads_bytes_(ddsDataSize) const uint8_t* ddsData,
_In_ size_t ddsDataSize, _In_ size_t ddsDataSize,
_In_ size_t maxsize, _In_ size_t maxsize,
_In_ D3D11_USAGE usage, _In_ D3D11_USAGE usage,
_In_ unsigned int bindFlags, _In_ unsigned int bindFlags,
_In_ unsigned int cpuAccessFlags, _In_ unsigned int cpuAccessFlags,
_In_ unsigned int miscFlags, _In_ unsigned int miscFlags,
_In_ bool forceSRGB, _In_ bool forceSRGB,
_Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11Resource** texture,
_Outptr_opt_ ID3D11ShaderResourceView** textureView, _Outptr_opt_ ID3D11ShaderResourceView** textureView,
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
); );
#if defined(_XBOX_ONE) && defined(_TITLE) #if defined(_XBOX_ONE) && defined(_TITLE)
HRESULT __cdecl CreateDDSTextureFromFileEx( _In_ ID3D11DeviceX* d3dDevice, HRESULT __cdecl CreateDDSTextureFromFileEx( _In_ ID3D11DeviceX* d3dDevice,
_In_opt_ ID3D11DeviceContextX* d3dContext, _In_opt_ ID3D11DeviceContextX* d3dContext,
#else #else
HRESULT __cdecl CreateDDSTextureFromFileEx( _In_ ID3D11Device* d3dDevice, HRESULT __cdecl CreateDDSTextureFromFileEx(_In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext, _In_opt_ ID3D11DeviceContext* d3dContext,
#endif #endif
_In_z_ const wchar_t* szFileName, _In_z_ const wchar_t* szFileName,
_In_ size_t maxsize, _In_ size_t maxsize,
_In_ D3D11_USAGE usage, _In_ D3D11_USAGE usage,
_In_ unsigned int bindFlags, _In_ unsigned int bindFlags,
_In_ unsigned int cpuAccessFlags, _In_ unsigned int cpuAccessFlags,
_In_ unsigned int miscFlags, _In_ unsigned int miscFlags,
_In_ bool forceSRGB, _In_ bool forceSRGB,
_Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11Resource** texture,
_Outptr_opt_ ID3D11ShaderResourceView** textureView, _Outptr_opt_ ID3D11ShaderResourceView** textureView,
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr
); );
} }

View file

@ -56,95 +56,97 @@
namespace DirectX namespace DirectX
{ {
// simliar to std::lock_guard for exception-safe Direct3D 11 resource locking // simliar to std::lock_guard for exception-safe Direct3D 11 resource locking
class MapGuard : public D3D11_MAPPED_SUBRESOURCE class MapGuard : public D3D11_MAPPED_SUBRESOURCE
{ {
public: public:
MapGuard( _In_ ID3D11DeviceContext* context, MapGuard(_In_ ID3D11DeviceContext* context,
_In_ ID3D11Resource *resource, _In_ ID3D11Resource* resource,
_In_ UINT subresource, _In_ UINT subresource,
_In_ D3D11_MAP mapType, _In_ D3D11_MAP mapType,
_In_ UINT mapFlags ) _In_ UINT mapFlags)
: mContext(context), mResource(resource), mSubresource(subresource) : mContext(context), mResource(resource), mSubresource(subresource)
{ {
HRESULT hr = mContext->Map( resource, subresource, mapType, mapFlags, this ); HRESULT hr = mContext->Map(resource, subresource, mapType, mapFlags, this);
if (FAILED(hr)) if (FAILED(hr))
{ {
throw std::exception(); throw std::exception();
} }
} }
~MapGuard() ~MapGuard()
{ {
mContext->Unmap( mResource, mSubresource ); mContext->Unmap(mResource, mSubresource);
} }
uint8_t* get() const uint8_t* get() const
{ {
return reinterpret_cast<uint8_t*>( pData ); return reinterpret_cast<uint8_t*>(pData);
} }
uint8_t* get(size_t slice) const
{
return reinterpret_cast<uint8_t*>( pData ) + ( slice * DepthPitch );
}
uint8_t* scanline(size_t row) const uint8_t* get(size_t slice) const
{ {
return reinterpret_cast<uint8_t*>( pData ) + ( row * RowPitch ); return reinterpret_cast<uint8_t*>(pData) + (slice * DepthPitch);
} }
uint8_t* scanline(size_t slice, size_t row) const
{
return reinterpret_cast<uint8_t*>( pData ) + ( slice * DepthPitch ) + ( row * RowPitch );
}
private: uint8_t* scanline(size_t row) const
ID3D11DeviceContext* mContext; {
ID3D11Resource* mResource; return reinterpret_cast<uint8_t*>(pData) + (row * RowPitch);
UINT mSubresource; }
MapGuard(MapGuard const&); uint8_t* scanline(size_t slice, size_t row) const
MapGuard& operator= (MapGuard const&); {
}; return reinterpret_cast<uint8_t*>(pData) + (slice * DepthPitch) + (row * RowPitch);
}
private:
ID3D11DeviceContext* mContext;
ID3D11Resource* mResource;
UINT mSubresource;
MapGuard(MapGuard const&);
MapGuard& operator=(MapGuard const&);
};
// Helper sets a D3D resource name string (used by PIX and debug layer leak reporting). // Helper sets a D3D resource name string (used by PIX and debug layer leak reporting).
template<UINT TNameLength> template <UINT TNameLength>
inline void SetDebugObjectName(_In_ ID3D11DeviceChild* resource, _In_z_ const char (&name)[TNameLength]) inline void SetDebugObjectName(_In_ ID3D11DeviceChild* resource, _In_z_ const char (&name)[TNameLength])
{ {
#if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) #if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) )
#if defined(_XBOX_ONE) && defined(_TITLE) #if defined(_XBOX_ONE) && defined(_TITLE)
WCHAR wname[MAX_PATH]; WCHAR wname[MAX_PATH];
int result = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, name, TNameLength, wname, MAX_PATH ); int result = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, name, TNameLength, wname, MAX_PATH );
if ( result > 0 ) if ( result > 0 )
{ {
resource->SetName( wname ); resource->SetName( wname );
} }
#else #else
resource->SetPrivateData(WKPDID_D3DDebugObjectName, TNameLength - 1, name); resource->SetPrivateData(WKPDID_D3DDebugObjectName, TNameLength - 1, name);
#endif #endif
#else #else
UNREFERENCED_PARAMETER(resource); UNREFERENCED_PARAMETER(resource);
UNREFERENCED_PARAMETER(name); UNREFERENCED_PARAMETER(name);
#endif #endif
} }
template<UINT TNameLength> template <UINT TNameLength>
inline void SetDebugObjectName(_In_ ID3D11DeviceChild* resource, _In_z_ const wchar_t (&name)[TNameLength]) inline void SetDebugObjectName(_In_ ID3D11DeviceChild* resource, _In_z_ const wchar_t (&name)[TNameLength])
{ {
#if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) ) #if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) )
#if defined(_XBOX_ONE) && defined(_TITLE) #if defined(_XBOX_ONE) && defined(_TITLE)
resource->SetName( name ); resource->SetName( name );
#else #else
char aname[MAX_PATH]; char aname[MAX_PATH];
int result = WideCharToMultiByte( CP_ACP, 0, name, TNameLength, aname, MAX_PATH, nullptr, nullptr ); int result = WideCharToMultiByte(CP_ACP, 0, name, TNameLength, aname, MAX_PATH, nullptr, nullptr);
if ( result > 0 ) if (result > 0)
{ {
resource->SetPrivateData(WKPDID_D3DDebugObjectName, TNameLength - 1, aname); resource->SetPrivateData(WKPDID_D3DDebugObjectName, TNameLength - 1, aname);
} }
#endif #endif
#else #else
UNREFERENCED_PARAMETER(resource); UNREFERENCED_PARAMETER(resource);
UNREFERENCED_PARAMETER(name); UNREFERENCED_PARAMETER(name);
#endif #endif
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -43,68 +43,107 @@
namespace DirectX namespace DirectX
{ {
#if (DIRECTX_MATH_VERSION < 305) && !defined(XM_CALLCONV) #if (DIRECTX_MATH_VERSION < 305) && !defined(XM_CALLCONV)
#define XM_CALLCONV __fastcall #define XM_CALLCONV __fastcall
typedef const XMVECTOR& HXMVECTOR; typedef const XMVECTOR& HXMVECTOR;
typedef const XMMATRIX& FXMMATRIX; typedef const XMMATRIX& FXMMATRIX;
#endif #endif
class IEffect; class IEffect;
class GeometricPrimitive class GeometricPrimitive
{ {
public: public:
virtual ~GeometricPrimitive(); virtual ~GeometricPrimitive();
// Factory methods. // Factory methods.
static std::unique_ptr<GeometricPrimitive> __cdecl CreateCube (_In_ ID3D11DeviceContext* deviceContext, float size = 1, bool rhcoords = true); static std::unique_ptr<GeometricPrimitive> __cdecl CreateCube(
static std::unique_ptr<GeometricPrimitive> __cdecl CreateBox (_In_ ID3D11DeviceContext* deviceContext, const XMFLOAT3& size, bool rhcoords = true, bool invertn = false); _In_ ID3D11DeviceContext* deviceContext, float size = 1, bool rhcoords = true);
static std::unique_ptr<GeometricPrimitive> __cdecl CreateSphere (_In_ ID3D11DeviceContext* deviceContext, float diameter = 1, size_t tessellation = 16, bool rhcoords = true, bool invertn = false); static std::unique_ptr<GeometricPrimitive> __cdecl CreateBox(_In_ ID3D11DeviceContext* deviceContext,
static std::unique_ptr<GeometricPrimitive> __cdecl CreateGeoSphere (_In_ ID3D11DeviceContext* deviceContext, float diameter = 1, size_t tessellation = 3, bool rhcoords = true); const XMFLOAT3& size, bool rhcoords = true,
static std::unique_ptr<GeometricPrimitive> __cdecl CreateCylinder (_In_ ID3D11DeviceContext* deviceContext, float height = 1, float diameter = 1, size_t tessellation = 32, bool rhcoords = true); bool invertn = false);
static std::unique_ptr<GeometricPrimitive> __cdecl CreateCone (_In_ ID3D11DeviceContext* deviceContext, float diameter = 1, float height = 1, size_t tessellation = 32, bool rhcoords = true); static std::unique_ptr<GeometricPrimitive> __cdecl CreateSphere(
static std::unique_ptr<GeometricPrimitive> __cdecl CreateTorus (_In_ ID3D11DeviceContext* deviceContext, float diameter = 1, float thickness = 0.333f, size_t tessellation = 32, bool rhcoords = true); _In_ ID3D11DeviceContext* deviceContext, float diameter = 1, size_t tessellation = 16, bool rhcoords = true,
static std::unique_ptr<GeometricPrimitive> __cdecl CreateTetrahedron (_In_ ID3D11DeviceContext* deviceContext, float size = 1, bool rhcoords = true); bool invertn = false);
static std::unique_ptr<GeometricPrimitive> __cdecl CreateOctahedron (_In_ ID3D11DeviceContext* deviceContext, float size = 1, bool rhcoords = true); static std::unique_ptr<GeometricPrimitive> __cdecl CreateGeoSphere(
static std::unique_ptr<GeometricPrimitive> __cdecl CreateDodecahedron (_In_ ID3D11DeviceContext* deviceContext, float size = 1, bool rhcoords = true); _In_ ID3D11DeviceContext* deviceContext, float diameter = 1, size_t tessellation = 3, bool rhcoords = true);
static std::unique_ptr<GeometricPrimitive> __cdecl CreateIcosahedron (_In_ ID3D11DeviceContext* deviceContext, float size = 1, bool rhcoords = true); static std::unique_ptr<GeometricPrimitive> __cdecl CreateCylinder(
static std::unique_ptr<GeometricPrimitive> __cdecl CreateTeapot (_In_ ID3D11DeviceContext* deviceContext, float size = 1, size_t tessellation = 8, bool rhcoords = true); _In_ ID3D11DeviceContext* deviceContext, float height = 1, float diameter = 1, size_t tessellation = 32,
static std::unique_ptr<GeometricPrimitive> __cdecl CreateCustom (_In_ ID3D11DeviceContext* deviceContext, const std::vector<VertexPositionNormalTexture>& vertices, const std::vector<uint16_t>& indices); bool rhcoords = true);
static std::unique_ptr<GeometricPrimitive> __cdecl CreateCone(
_In_ ID3D11DeviceContext* deviceContext, float diameter = 1, float height = 1, size_t tessellation = 32,
bool rhcoords = true);
static std::unique_ptr<GeometricPrimitive> __cdecl CreateTorus(
_In_ ID3D11DeviceContext* deviceContext, float diameter = 1, float thickness = 0.333f,
size_t tessellation = 32, bool rhcoords = true);
static std::unique_ptr<GeometricPrimitive> __cdecl CreateTetrahedron(
_In_ ID3D11DeviceContext* deviceContext, float size = 1, bool rhcoords = true);
static std::unique_ptr<GeometricPrimitive> __cdecl CreateOctahedron(
_In_ ID3D11DeviceContext* deviceContext, float size = 1, bool rhcoords = true);
static std::unique_ptr<GeometricPrimitive> __cdecl CreateDodecahedron(
_In_ ID3D11DeviceContext* deviceContext, float size = 1, bool rhcoords = true);
static std::unique_ptr<GeometricPrimitive> __cdecl CreateIcosahedron(
_In_ ID3D11DeviceContext* deviceContext, float size = 1, bool rhcoords = true);
static std::unique_ptr<GeometricPrimitive> __cdecl CreateTeapot(
_In_ ID3D11DeviceContext* deviceContext, float size = 1, size_t tessellation = 8, bool rhcoords = true);
static std::unique_ptr<GeometricPrimitive> __cdecl CreateCustom(
_In_ ID3D11DeviceContext* deviceContext, const std::vector<VertexPositionNormalTexture>& vertices,
const std::vector<uint16_t>& indices);
static void __cdecl CreateCube (std::vector<VertexPositionNormalTexture>& vertices, std::vector<uint16_t>& indices, float size = 1, bool rhcoords = true); static void __cdecl CreateCube(std::vector<VertexPositionNormalTexture>& vertices, std::vector<uint16_t>& indices,
static void __cdecl CreateBox (std::vector<VertexPositionNormalTexture>& vertices, std::vector<uint16_t>& indices, const XMFLOAT3& size, bool rhcoords = true, bool invertn = false); float size = 1, bool rhcoords = true);
static void __cdecl CreateSphere (std::vector<VertexPositionNormalTexture>& vertices, std::vector<uint16_t>& indices, float diameter = 1, size_t tessellation = 16, bool rhcoords = true, bool invertn = false); static void __cdecl CreateBox(std::vector<VertexPositionNormalTexture>& vertices, std::vector<uint16_t>& indices,
static void __cdecl CreateGeoSphere (std::vector<VertexPositionNormalTexture>& vertices, std::vector<uint16_t>& indices, float diameter = 1, size_t tessellation = 3, bool rhcoords = true); const XMFLOAT3& size, bool rhcoords = true, bool invertn = false);
static void __cdecl CreateCylinder (std::vector<VertexPositionNormalTexture>& vertices, std::vector<uint16_t>& indices, float height = 1, float diameter = 1, size_t tessellation = 32, bool rhcoords = true); static void __cdecl CreateSphere(std::vector<VertexPositionNormalTexture>& vertices,
static void __cdecl CreateCone (std::vector<VertexPositionNormalTexture>& vertices, std::vector<uint16_t>& indices, float diameter = 1, float height = 1, size_t tessellation = 32, bool rhcoords = true); std::vector<uint16_t>& indices, float diameter = 1, size_t tessellation = 16,
static void __cdecl CreateTorus (std::vector<VertexPositionNormalTexture>& vertices, std::vector<uint16_t>& indices, float diameter = 1, float thickness = 0.333f, size_t tessellation = 32, bool rhcoords = true); bool rhcoords = true, bool invertn = false);
static void __cdecl CreateTetrahedron (std::vector<VertexPositionNormalTexture>& vertices, std::vector<uint16_t>& indices, float size = 1, bool rhcoords = true); static void __cdecl CreateGeoSphere(std::vector<VertexPositionNormalTexture>& vertices,
static void __cdecl CreateOctahedron (std::vector<VertexPositionNormalTexture>& vertices, std::vector<uint16_t>& indices, float size = 1, bool rhcoords = true); std::vector<uint16_t>& indices, float diameter = 1, size_t tessellation = 3,
static void __cdecl CreateDodecahedron (std::vector<VertexPositionNormalTexture>& vertices, std::vector<uint16_t>& indices, float size = 1, bool rhcoords = true); bool rhcoords = true);
static void __cdecl CreateIcosahedron (std::vector<VertexPositionNormalTexture>& vertices, std::vector<uint16_t>& indices, float size = 1, bool rhcoords = true); static void __cdecl CreateCylinder(std::vector<VertexPositionNormalTexture>& vertices,
static void __cdecl CreateTeapot (std::vector<VertexPositionNormalTexture>& vertices, std::vector<uint16_t>& indices, float size = 1, size_t tessellation = 8, bool rhcoords = true); std::vector<uint16_t>& indices, float height = 1, float diameter = 1,
size_t tessellation = 32, bool rhcoords = true);
static void __cdecl CreateCone(std::vector<VertexPositionNormalTexture>& vertices, std::vector<uint16_t>& indices,
float diameter = 1, float height = 1, size_t tessellation = 32,
bool rhcoords = true);
static void __cdecl CreateTorus(std::vector<VertexPositionNormalTexture>& vertices,
std::vector<uint16_t>& indices, float diameter = 1, float thickness = 0.333f,
size_t tessellation = 32, bool rhcoords = true);
static void __cdecl CreateTetrahedron(std::vector<VertexPositionNormalTexture>& vertices,
std::vector<uint16_t>& indices, float size = 1, bool rhcoords = true);
static void __cdecl CreateOctahedron(std::vector<VertexPositionNormalTexture>& vertices,
std::vector<uint16_t>& indices, float size = 1, bool rhcoords = true);
static void __cdecl CreateDodecahedron(std::vector<VertexPositionNormalTexture>& vertices,
std::vector<uint16_t>& indices, float size = 1, bool rhcoords = true);
static void __cdecl CreateIcosahedron(std::vector<VertexPositionNormalTexture>& vertices,
std::vector<uint16_t>& indices, float size = 1, bool rhcoords = true);
static void __cdecl CreateTeapot(std::vector<VertexPositionNormalTexture>& vertices,
std::vector<uint16_t>& indices, float size = 1, size_t tessellation = 8,
bool rhcoords = true);
// Draw the primitive. // Draw the primitive.
void XM_CALLCONV Draw(FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection, FXMVECTOR color = Colors::White, _In_opt_ ID3D11ShaderResourceView* texture = nullptr, bool wireframe = false, void XM_CALLCONV Draw(FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection, FXMVECTOR color = Colors::White,
_In_opt_ std::function<void DIRECTX_STD_CALLCONV()> setCustomState = nullptr ); _In_opt_ ID3D11ShaderResourceView* texture = nullptr, bool wireframe = false,
_In_opt_ std::function<void DIRECTX_STD_CALLCONV()> setCustomState = nullptr);
// Draw the primitive using a custom effect. // Draw the primitive using a custom effect.
void __cdecl Draw( _In_ IEffect* effect, _In_ ID3D11InputLayout* inputLayout, bool alpha = false, bool wireframe = false, void __cdecl Draw(_In_ IEffect* effect, _In_ ID3D11InputLayout* inputLayout, bool alpha = false,
_In_opt_ std::function<void DIRECTX_STD_CALLCONV()> setCustomState = nullptr ); bool wireframe = false,
_In_opt_ std::function<void DIRECTX_STD_CALLCONV()> setCustomState = nullptr);
// Create input layout for drawing with a custom effect. // Create input layout for drawing with a custom effect.
void __cdecl CreateInputLayout( _In_ IEffect* effect, _Outptr_ ID3D11InputLayout** inputLayout ); void __cdecl CreateInputLayout(_In_ IEffect* effect, _Outptr_ ID3D11InputLayout** inputLayout);
private: private:
GeometricPrimitive(); GeometricPrimitive();
// Private implementation. // Private implementation.
class Impl; class Impl;
std::unique_ptr<Impl> pImpl; std::unique_ptr<Impl> pImpl;
// Prevent copying. // Prevent copying.
GeometricPrimitive(GeometricPrimitive const&) DIRECTX_CTOR_DELETE GeometricPrimitive(GeometricPrimitive const&) DIRECTX_CTOR_DELETE
GeometricPrimitive& operator= (GeometricPrimitive const&) DIRECTX_CTOR_DELETE GeometricPrimitive& operator=(GeometricPrimitive const&) DIRECTX_CTOR_DELETE
}; };
} }

View file

@ -47,117 +47,140 @@
namespace DirectX namespace DirectX
{ {
#if (DIRECTX_MATH_VERSION < 305) && !defined(XM_CALLCONV) #if (DIRECTX_MATH_VERSION < 305) && !defined(XM_CALLCONV)
#define XM_CALLCONV __fastcall #define XM_CALLCONV __fastcall
typedef const XMVECTOR& HXMVECTOR; typedef const XMVECTOR& HXMVECTOR;
typedef const XMMATRIX& FXMMATRIX; typedef const XMMATRIX& FXMMATRIX;
#endif #endif
class IEffect; class IEffect;
class IEffectFactory; class IEffectFactory;
class CommonStates; class CommonStates;
class ModelMesh; class ModelMesh;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Each mesh part is a submesh with a single effect // Each mesh part is a submesh with a single effect
class ModelMeshPart class ModelMeshPart
{ {
public: public:
ModelMeshPart(); ModelMeshPart();
virtual ~ModelMeshPart(); virtual ~ModelMeshPart();
uint32_t indexCount; uint32_t indexCount;
uint32_t startIndex; uint32_t startIndex;
uint32_t vertexOffset; uint32_t vertexOffset;
uint32_t vertexStride; uint32_t vertexStride;
D3D_PRIMITIVE_TOPOLOGY primitiveType; D3D_PRIMITIVE_TOPOLOGY primitiveType;
DXGI_FORMAT indexFormat; DXGI_FORMAT indexFormat;
Microsoft::WRL::ComPtr<ID3D11InputLayout> inputLayout; Microsoft::WRL::ComPtr<ID3D11InputLayout> inputLayout;
Microsoft::WRL::ComPtr<ID3D11Buffer> indexBuffer; Microsoft::WRL::ComPtr<ID3D11Buffer> indexBuffer;
Microsoft::WRL::ComPtr<ID3D11Buffer> vertexBuffer; Microsoft::WRL::ComPtr<ID3D11Buffer> vertexBuffer;
std::shared_ptr<IEffect> effect; std::shared_ptr<IEffect> effect;
std::shared_ptr<std::vector<D3D11_INPUT_ELEMENT_DESC>> vbDecl; std::shared_ptr<std::vector<D3D11_INPUT_ELEMENT_DESC>> vbDecl;
bool isAlpha; bool isAlpha;
typedef std::vector<std::unique_ptr<ModelMeshPart>> Collection; typedef std::vector<std::unique_ptr<ModelMeshPart>> Collection;
// Draw mesh part with custom effect // Draw mesh part with custom effect
void __cdecl Draw( _In_ ID3D11DeviceContext* deviceContext, _In_ IEffect* ieffect, _In_ ID3D11InputLayout* iinputLayout, void __cdecl Draw(_In_ ID3D11DeviceContext* deviceContext, _In_ IEffect* ieffect,
_In_opt_ std::function<void DIRECTX_STD_CALLCONV()> setCustomState = nullptr ) const; _In_ ID3D11InputLayout* iinputLayout,
_In_opt_ std::function<void DIRECTX_STD_CALLCONV()> setCustomState = nullptr) const;
// Create input layout for drawing with a custom effect. // Create input layout for drawing with a custom effect.
void __cdecl CreateInputLayout( _In_ ID3D11Device* d3dDevice, _In_ IEffect* ieffect, _Outptr_ ID3D11InputLayout** iinputLayout ); void __cdecl CreateInputLayout(_In_ ID3D11Device* d3dDevice, _In_ IEffect* ieffect,
_Outptr_ ID3D11InputLayout** iinputLayout);
// Change effect used by part and regenerate input layout (be sure to call Model::Modified as well) // Change effect used by part and regenerate input layout (be sure to call Model::Modified as well)
void __cdecl ModifyEffect( _In_ ID3D11Device* d3dDevice, _In_ std::shared_ptr<IEffect>& ieffect, bool isalpha = false ); void __cdecl ModifyEffect(_In_ ID3D11Device* d3dDevice, _In_ std::shared_ptr<IEffect>& ieffect,
}; bool isalpha = false);
};
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// A mesh consists of one or more model mesh parts // A mesh consists of one or more model mesh parts
class ModelMesh class ModelMesh
{ {
public: public:
ModelMesh(); ModelMesh();
virtual ~ModelMesh(); virtual ~ModelMesh();
BoundingSphere boundingSphere; BoundingSphere boundingSphere;
BoundingBox boundingBox; BoundingBox boundingBox;
ModelMeshPart::Collection meshParts; ModelMeshPart::Collection meshParts;
std::wstring name; std::wstring name;
bool ccw; bool ccw;
bool pmalpha; bool pmalpha;
typedef std::vector<std::shared_ptr<ModelMesh>> Collection; typedef std::vector<std::shared_ptr<ModelMesh>> Collection;
// Setup states for drawing mesh // Setup states for drawing mesh
void __cdecl PrepareForRendering( _In_ ID3D11DeviceContext* deviceContext, CommonStates& states, bool alpha = false, bool wireframe = false ) const; void __cdecl PrepareForRendering(_In_ ID3D11DeviceContext* deviceContext, CommonStates& states,
bool alpha = false, bool wireframe = false) const;
// Draw the mesh // Draw the mesh
void XM_CALLCONV Draw( _In_ ID3D11DeviceContext* deviceContext, FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection, void XM_CALLCONV Draw(_In_ ID3D11DeviceContext* deviceContext, FXMMATRIX world, CXMMATRIX view,
bool alpha = false, _In_opt_ std::function<void DIRECTX_STD_CALLCONV()> setCustomState = nullptr ) const; CXMMATRIX projection,
}; bool alpha = false,
_In_opt_ std::function<void DIRECTX_STD_CALLCONV()> setCustomState = nullptr) const;
};
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// A model consists of one or more meshes // A model consists of one or more meshes
class Model class Model
{ {
public: public:
virtual ~Model(); virtual ~Model();
ModelMesh::Collection meshes; ModelMesh::Collection meshes;
std::wstring name; std::wstring name;
// Draw all the meshes in the model // Draw all the meshes in the model
void XM_CALLCONV Draw( _In_ ID3D11DeviceContext* deviceContext, CommonStates& states, FXMMATRIX world, CXMMATRIX view, CXMMATRIX projection, void XM_CALLCONV Draw(_In_ ID3D11DeviceContext* deviceContext, CommonStates& states, FXMMATRIX world,
bool wireframe = false, _In_opt_ std::function<void DIRECTX_STD_CALLCONV()> setCustomState = nullptr ) const; CXMMATRIX view, CXMMATRIX projection,
bool wireframe = false,
_In_opt_ std::function<void DIRECTX_STD_CALLCONV()> setCustomState = nullptr) const;
// Notify model that effects, parts list, or mesh list has changed // Notify model that effects, parts list, or mesh list has changed
void __cdecl Modified() { mEffectCache.clear(); } void __cdecl Modified() { mEffectCache.clear(); }
// Update all effects used by the model // Update all effects used by the model
void __cdecl UpdateEffects( _In_ std::function<void DIRECTX_STD_CALLCONV(IEffect*)> setEffect ); void __cdecl UpdateEffects(_In_ std::function<void DIRECTX_STD_CALLCONV(IEffect*)> setEffect);
// Loads a model from a Visual Studio Starter Kit .CMO file // Loads a model from a Visual Studio Starter Kit .CMO file
static std::unique_ptr<Model> __cdecl CreateFromCMO( _In_ ID3D11Device* d3dDevice, _In_reads_bytes_(dataSize) const uint8_t* meshData, size_t dataSize, static std::unique_ptr<Model> __cdecl CreateFromCMO(_In_ ID3D11Device* d3dDevice,
_In_ IEffectFactory& fxFactory, bool ccw = true, bool pmalpha = false ); _In_reads_bytes_(dataSize) const uint8_t* meshData,
static std::unique_ptr<Model> __cdecl CreateFromCMO( _In_ ID3D11Device* d3dDevice, _In_z_ const wchar_t* szFileName, size_t dataSize,
_In_ IEffectFactory& fxFactory, bool ccw = true, bool pmalpha = false ); _In_ IEffectFactory& fxFactory, bool ccw = true,
bool pmalpha = false);
static std::unique_ptr<Model> __cdecl CreateFromCMO(_In_ ID3D11Device* d3dDevice,
_In_z_ const wchar_t* szFileName,
_In_ IEffectFactory& fxFactory, bool ccw = true,
bool pmalpha = false);
// Loads a model from a DirectX SDK .SDKMESH file // Loads a model from a DirectX SDK .SDKMESH file
static std::unique_ptr<Model> __cdecl CreateFromSDKMESH( _In_ ID3D11Device* d3dDevice, _In_reads_bytes_(dataSize) const uint8_t* meshData, _In_ size_t dataSize, static std::unique_ptr<Model> __cdecl CreateFromSDKMESH(_In_ ID3D11Device* d3dDevice,
_In_ IEffectFactory& fxFactory, bool ccw = false, bool pmalpha = false ); _In_reads_bytes_(dataSize) const uint8_t* meshData,
static std::unique_ptr<Model> __cdecl CreateFromSDKMESH( _In_ ID3D11Device* d3dDevice, _In_z_ const wchar_t* szFileName, _In_ size_t dataSize,
_In_ IEffectFactory& fxFactory, bool ccw = false, bool pmalpha = false ); _In_ IEffectFactory& fxFactory, bool ccw = false,
bool pmalpha = false);
static std::unique_ptr<Model> __cdecl CreateFromSDKMESH(_In_ ID3D11Device* d3dDevice,
_In_z_ const wchar_t* szFileName,
_In_ IEffectFactory& fxFactory, bool ccw = false,
bool pmalpha = false);
// Loads a model from a .VBO file // Loads a model from a .VBO file
static std::unique_ptr<Model> __cdecl CreateFromVBO( _In_ ID3D11Device* d3dDevice, _In_reads_bytes_(dataSize) const uint8_t* meshData, _In_ size_t dataSize, static std::unique_ptr<Model> __cdecl CreateFromVBO(_In_ ID3D11Device* d3dDevice,
_In_opt_ std::shared_ptr<IEffect> ieffect = nullptr, bool ccw = false, bool pmalpha = false ); _In_reads_bytes_(dataSize) const uint8_t* meshData,
static std::unique_ptr<Model> __cdecl CreateFromVBO( _In_ ID3D11Device* d3dDevice, _In_z_ const wchar_t* szFileName, _In_ size_t dataSize,
_In_opt_ std::shared_ptr<IEffect> ieffect = nullptr, bool ccw = false, bool pmalpha = false ); _In_opt_ std::shared_ptr<IEffect> ieffect = nullptr,
bool ccw = false, bool pmalpha = false);
static std::unique_ptr<Model> __cdecl CreateFromVBO(_In_ ID3D11Device* d3dDevice,
_In_z_ const wchar_t* szFileName,
_In_opt_ std::shared_ptr<IEffect> ieffect = nullptr,
bool ccw = false, bool pmalpha = false);
private: private:
std::set<IEffect*> mEffectCache; std::set<IEffect*> mEffectCache;
}; };
} }

View file

@ -41,118 +41,129 @@
namespace DirectX namespace DirectX
{ {
namespace Internal namespace Internal
{ {
// Base class, not to be used directly: clients should access this via the derived PrimitiveBatch<T>. // Base class, not to be used directly: clients should access this via the derived PrimitiveBatch<T>.
class PrimitiveBatchBase class PrimitiveBatchBase
{ {
protected: protected:
PrimitiveBatchBase(_In_ ID3D11DeviceContext* deviceContext, size_t maxIndices, size_t maxVertices, size_t vertexSize); PrimitiveBatchBase(_In_ ID3D11DeviceContext* deviceContext, size_t maxIndices, size_t maxVertices,
PrimitiveBatchBase(PrimitiveBatchBase&& moveFrom); size_t vertexSize);
PrimitiveBatchBase& operator= (PrimitiveBatchBase&& moveFrom); PrimitiveBatchBase(PrimitiveBatchBase&& moveFrom);
virtual ~PrimitiveBatchBase(); PrimitiveBatchBase& operator=(PrimitiveBatchBase&& moveFrom);
virtual ~PrimitiveBatchBase();
public: public:
// Begin/End a batch of primitive drawing operations. // Begin/End a batch of primitive drawing operations.
void __cdecl Begin(); void __cdecl Begin();
void __cdecl End(); void __cdecl End();
protected: protected:
// Internal, untyped drawing method. // Internal, untyped drawing method.
void __cdecl Draw(D3D11_PRIMITIVE_TOPOLOGY topology, bool isIndexed, _In_opt_count_(indexCount) uint16_t const* indices, size_t indexCount, size_t vertexCount, _Out_ void** pMappedVertices); void __cdecl Draw(D3D11_PRIMITIVE_TOPOLOGY topology, bool isIndexed,
_In_opt_count_(indexCount) uint16_t const* indices, size_t indexCount, size_t vertexCount,
_Out_ void** pMappedVertices);
private: private:
// Private implementation. // Private implementation.
class Impl; class Impl;
std::unique_ptr<Impl> pImpl; std::unique_ptr<Impl> pImpl;
// Prevent copying. // Prevent copying.
PrimitiveBatchBase(PrimitiveBatchBase const&) DIRECTX_CTOR_DELETE PrimitiveBatchBase(PrimitiveBatchBase const&) DIRECTX_CTOR_DELETE
PrimitiveBatchBase& operator= (PrimitiveBatchBase const&) DIRECTX_CTOR_DELETE PrimitiveBatchBase& operator=(PrimitiveBatchBase const&) DIRECTX_CTOR_DELETE
}; };
} }
// Template makes the API typesafe, eg. PrimitiveBatch<VertexPositionColor>. // Template makes the API typesafe, eg. PrimitiveBatch<VertexPositionColor>.
template<typename TVertex> template <typename TVertex>
class PrimitiveBatch : public Internal::PrimitiveBatchBase class PrimitiveBatch : public Internal::PrimitiveBatchBase
{ {
static const size_t DefaultBatchSize = 2048; static const size_t DefaultBatchSize = 2048;
public: public:
PrimitiveBatch(_In_ ID3D11DeviceContext* deviceContext, size_t maxIndices = DefaultBatchSize * 3, size_t maxVertices = DefaultBatchSize) PrimitiveBatch(_In_ ID3D11DeviceContext* deviceContext, size_t maxIndices = DefaultBatchSize * 3,
: PrimitiveBatchBase(deviceContext, maxIndices, maxVertices, sizeof(TVertex)) size_t maxVertices = DefaultBatchSize)
{ } : PrimitiveBatchBase(deviceContext, maxIndices, maxVertices, sizeof(TVertex))
{
}
PrimitiveBatch(PrimitiveBatch&& moveFrom) PrimitiveBatch(PrimitiveBatch&& moveFrom)
: PrimitiveBatchBase(std::move(moveFrom)) : PrimitiveBatchBase(std::move(moveFrom))
{ } {
}
PrimitiveBatch& __cdecl operator= (PrimitiveBatch&& moveFrom) PrimitiveBatch& __cdecl operator=(PrimitiveBatch&& moveFrom)
{ {
PrimitiveBatchBase::operator=(std::move(moveFrom)); PrimitiveBatchBase::operator=(std::move(moveFrom));
return *this; return *this;
} }
// Similar to the D3D9 API DrawPrimitiveUP. // Similar to the D3D9 API DrawPrimitiveUP.
void __cdecl Draw(D3D11_PRIMITIVE_TOPOLOGY topology, _In_reads_(vertexCount) TVertex const* vertices, size_t vertexCount) void __cdecl Draw(D3D11_PRIMITIVE_TOPOLOGY topology, _In_reads_(vertexCount) TVertex const* vertices,
{ size_t vertexCount)
void* mappedVertices; {
void* mappedVertices;
PrimitiveBatchBase::Draw(topology, false, nullptr, 0, vertexCount, &mappedVertices); PrimitiveBatchBase::Draw(topology, false, nullptr, 0, vertexCount, &mappedVertices);
memcpy(mappedVertices, vertices, vertexCount * sizeof(TVertex)); memcpy(mappedVertices, vertices, vertexCount * sizeof(TVertex));
} }
// Similar to the D3D9 API DrawIndexedPrimitiveUP. // Similar to the D3D9 API DrawIndexedPrimitiveUP.
void __cdecl DrawIndexed(D3D11_PRIMITIVE_TOPOLOGY topology, _In_reads_(indexCount) uint16_t const* indices, size_t indexCount, _In_reads_(vertexCount) TVertex const* vertices, size_t vertexCount) void __cdecl DrawIndexed(D3D11_PRIMITIVE_TOPOLOGY topology, _In_reads_(indexCount) uint16_t const* indices,
{ size_t indexCount, _In_reads_(vertexCount) TVertex const* vertices, size_t vertexCount)
void* mappedVertices; {
void* mappedVertices;
PrimitiveBatchBase::Draw(topology, true, indices, indexCount, vertexCount, &mappedVertices); PrimitiveBatchBase::Draw(topology, true, indices, indexCount, vertexCount, &mappedVertices);
memcpy(mappedVertices, vertices, vertexCount * sizeof(TVertex)); memcpy(mappedVertices, vertices, vertexCount * sizeof(TVertex));
} }
void __cdecl DrawLine(TVertex const& v1, TVertex const& v2) void __cdecl DrawLine(TVertex const& v1, TVertex const& v2)
{ {
TVertex* mappedVertices; TVertex* mappedVertices;
PrimitiveBatchBase::Draw(D3D11_PRIMITIVE_TOPOLOGY_LINELIST, false, nullptr, 0, 2, reinterpret_cast<void**>(&mappedVertices)); PrimitiveBatchBase::Draw(D3D11_PRIMITIVE_TOPOLOGY_LINELIST, false, nullptr, 0, 2,
reinterpret_cast<void**>(&mappedVertices));
mappedVertices[0] = v1; mappedVertices[0] = v1;
mappedVertices[1] = v2; mappedVertices[1] = v2;
} }
void __cdecl DrawTriangle(TVertex const& v1, TVertex const& v2, TVertex const& v3) void __cdecl DrawTriangle(TVertex const& v1, TVertex const& v2, TVertex const& v3)
{ {
TVertex* mappedVertices; TVertex* mappedVertices;
PrimitiveBatchBase::Draw(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, false, nullptr, 0, 3, reinterpret_cast<void**>(&mappedVertices)); PrimitiveBatchBase::Draw(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, false, nullptr, 0, 3,
reinterpret_cast<void**>(&mappedVertices));
mappedVertices[0] = v1; mappedVertices[0] = v1;
mappedVertices[1] = v2; mappedVertices[1] = v2;
mappedVertices[2] = v3; mappedVertices[2] = v3;
} }
void __cdecl DrawQuad(TVertex const& v1, TVertex const& v2, TVertex const& v3, TVertex const& v4) void __cdecl DrawQuad(TVertex const& v1, TVertex const& v2, TVertex const& v3, TVertex const& v4)
{ {
static const uint16_t quadIndices[] = { 0, 1, 2, 0, 2, 3 }; static const uint16_t quadIndices[] = {0, 1, 2, 0, 2, 3};
TVertex* mappedVertices; TVertex* mappedVertices;
PrimitiveBatchBase::Draw(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, true, quadIndices, 6, 4, reinterpret_cast<void**>(&mappedVertices)); PrimitiveBatchBase::Draw(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, true, quadIndices, 6, 4,
reinterpret_cast<void**>(&mappedVertices));
mappedVertices[0] = v1; mappedVertices[0] = v1;
mappedVertices[1] = v2; mappedVertices[1] = v2;
mappedVertices[2] = v3; mappedVertices[2] = v3;
mappedVertices[3] = v4; mappedVertices[3] = v4;
} }
}; };
} }

View file

@ -47,18 +47,19 @@
namespace DirectX namespace DirectX
{ {
HRESULT __cdecl SaveDDSTextureToFile( _In_ ID3D11DeviceContext* pContext, HRESULT __cdecl SaveDDSTextureToFile(_In_ ID3D11DeviceContext* pContext,
_In_ ID3D11Resource* pSource, _In_ ID3D11Resource* pSource,
_In_z_ LPCWSTR fileName ); _In_z_ LPCWSTR fileName);
#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (_WIN32_WINNT > _WIN32_WINNT_WIN8) #if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (_WIN32_WINNT > _WIN32_WINNT_WIN8)
HRESULT __cdecl SaveWICTextureToFile( _In_ ID3D11DeviceContext* pContext, HRESULT __cdecl SaveWICTextureToFile(_In_ ID3D11DeviceContext* pContext,
_In_ ID3D11Resource* pSource, _In_ ID3D11Resource* pSource,
_In_ REFGUID guidContainerFormat, _In_ REFGUID guidContainerFormat,
_In_z_ LPCWSTR fileName, _In_z_ LPCWSTR fileName,
_In_opt_ const GUID* targetFormat = nullptr, _In_opt_ const GUID* targetFormat = nullptr,
_In_opt_ std::function<void DIRECTX_STD_CALLCONV(IPropertyBag2*)> setCustomProps = nullptr ); _In_opt_ std::function<void DIRECTX_STD_CALLCONV(IPropertyBag2*)> setCustomProps
= nullptr);
#endif #endif
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -46,76 +46,98 @@
namespace DirectX namespace DirectX
{ {
#if (DIRECTX_MATH_VERSION < 305) && !defined(XM_CALLCONV) #if (DIRECTX_MATH_VERSION < 305) && !defined(XM_CALLCONV)
#define XM_CALLCONV __fastcall #define XM_CALLCONV __fastcall
typedef const XMVECTOR& HXMVECTOR; typedef const XMVECTOR& HXMVECTOR;
typedef const XMMATRIX& FXMMATRIX; typedef const XMMATRIX& FXMMATRIX;
#endif #endif
enum SpriteSortMode enum SpriteSortMode
{ {
SpriteSortMode_Deferred, SpriteSortMode_Deferred,
SpriteSortMode_Immediate, SpriteSortMode_Immediate,
SpriteSortMode_Texture, SpriteSortMode_Texture,
SpriteSortMode_BackToFront, SpriteSortMode_BackToFront,
SpriteSortMode_FrontToBack, SpriteSortMode_FrontToBack,
}; };
enum SpriteEffects enum SpriteEffects
{ {
SpriteEffects_None = 0, SpriteEffects_None = 0,
SpriteEffects_FlipHorizontally = 1, SpriteEffects_FlipHorizontally = 1,
SpriteEffects_FlipVertically = 2, SpriteEffects_FlipVertically = 2,
SpriteEffects_FlipBoth = SpriteEffects_FlipHorizontally | SpriteEffects_FlipVertically, SpriteEffects_FlipBoth = SpriteEffects_FlipHorizontally | SpriteEffects_FlipVertically,
}; };
class SpriteBatch class SpriteBatch
{ {
public: public:
explicit SpriteBatch(_In_ ID3D11DeviceContext* deviceContext); explicit SpriteBatch(_In_ ID3D11DeviceContext* deviceContext);
SpriteBatch(SpriteBatch&& moveFrom); SpriteBatch(SpriteBatch&& moveFrom);
SpriteBatch& operator= (SpriteBatch&& moveFrom); SpriteBatch& operator=(SpriteBatch&& moveFrom);
virtual ~SpriteBatch(); virtual ~SpriteBatch();
// Begin/End a batch of sprite drawing operations. // Begin/End a batch of sprite drawing operations.
void XM_CALLCONV Begin(SpriteSortMode sortMode = SpriteSortMode_Deferred, _In_opt_ ID3D11BlendState* blendState = nullptr, _In_opt_ ID3D11SamplerState* samplerState = nullptr, _In_opt_ ID3D11DepthStencilState* depthStencilState = nullptr, _In_opt_ ID3D11RasterizerState* rasterizerState = nullptr, void XM_CALLCONV Begin(SpriteSortMode sortMode = SpriteSortMode_Deferred,
_In_opt_ std::function<void DIRECTX_STD_CALLCONV()> setCustomShaders = nullptr, FXMMATRIX transformMatrix = MatrixIdentity); _In_opt_ ID3D11BlendState* blendState = nullptr,
void __cdecl End(); _In_opt_ ID3D11SamplerState* samplerState = nullptr,
_In_opt_ ID3D11DepthStencilState* depthStencilState = nullptr,
_In_opt_ ID3D11RasterizerState* rasterizerState = nullptr,
_In_opt_ std::function<void DIRECTX_STD_CALLCONV()> setCustomShaders = nullptr,
FXMMATRIX transformMatrix = MatrixIdentity);
void __cdecl End();
// Draw overloads specifying position, origin and scale as XMFLOAT2. // Draw overloads specifying position, origin and scale as XMFLOAT2.
void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, XMFLOAT2 const& position, FXMVECTOR color = Colors::White); void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, XMFLOAT2 const& position,
void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, XMFLOAT2 const& position, _In_opt_ RECT const* sourceRectangle, FXMVECTOR color = Colors::White, float rotation = 0, XMFLOAT2 const& origin = Float2Zero, float scale = 1, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0); FXMVECTOR color = Colors::White);
void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, XMFLOAT2 const& position, _In_opt_ RECT const* sourceRectangle, FXMVECTOR color, float rotation, XMFLOAT2 const& origin, XMFLOAT2 const& scale, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0); void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, XMFLOAT2 const& position,
_In_opt_ RECT const* sourceRectangle, FXMVECTOR color = Colors::White, float rotation = 0,
XMFLOAT2 const& origin = Float2Zero, float scale = 1,
SpriteEffects effects = SpriteEffects_None, float layerDepth = 0);
void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, XMFLOAT2 const& position,
_In_opt_ RECT const* sourceRectangle, FXMVECTOR color, float rotation,
XMFLOAT2 const& origin, XMFLOAT2 const& scale, SpriteEffects effects = SpriteEffects_None,
float layerDepth = 0);
// Draw overloads specifying position, origin and scale via the first two components of an XMVECTOR. // Draw overloads specifying position, origin and scale via the first two components of an XMVECTOR.
void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, FXMVECTOR position, FXMVECTOR color = Colors::White); void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, FXMVECTOR position,
void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, FXMVECTOR position, _In_opt_ RECT const* sourceRectangle, FXMVECTOR color = Colors::White, float rotation = 0, FXMVECTOR origin = g_XMZero, float scale = 1, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0); FXMVECTOR color = Colors::White);
void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, FXMVECTOR position, _In_opt_ RECT const* sourceRectangle, FXMVECTOR color, float rotation, FXMVECTOR origin, GXMVECTOR scale, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0); void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, FXMVECTOR position,
_In_opt_ RECT const* sourceRectangle, FXMVECTOR color = Colors::White, float rotation = 0,
FXMVECTOR origin = g_XMZero, float scale = 1, SpriteEffects effects = SpriteEffects_None,
float layerDepth = 0);
void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, FXMVECTOR position,
_In_opt_ RECT const* sourceRectangle, FXMVECTOR color, float rotation, FXMVECTOR origin,
GXMVECTOR scale, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0);
// Draw overloads specifying position as a RECT. // Draw overloads specifying position as a RECT.
void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, RECT const& destinationRectangle, FXMVECTOR color = Colors::White); void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, RECT const& destinationRectangle,
void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, RECT const& destinationRectangle, _In_opt_ RECT const* sourceRectangle, FXMVECTOR color = Colors::White, float rotation = 0, XMFLOAT2 const& origin = Float2Zero, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0); FXMVECTOR color = Colors::White);
void XM_CALLCONV Draw(_In_ ID3D11ShaderResourceView* texture, RECT const& destinationRectangle,
_In_opt_ RECT const* sourceRectangle, FXMVECTOR color = Colors::White, float rotation = 0,
XMFLOAT2 const& origin = Float2Zero, SpriteEffects effects = SpriteEffects_None,
float layerDepth = 0);
// Rotation mode to be applied to the sprite transformation // Rotation mode to be applied to the sprite transformation
void __cdecl SetRotation( DXGI_MODE_ROTATION mode ); void __cdecl SetRotation(DXGI_MODE_ROTATION mode);
DXGI_MODE_ROTATION __cdecl GetRotation() const; DXGI_MODE_ROTATION __cdecl GetRotation() const;
// Set viewport for sprite transformation // Set viewport for sprite transformation
void __cdecl SetViewport( const D3D11_VIEWPORT& viewPort ); void __cdecl SetViewport(const D3D11_VIEWPORT& viewPort);
private: private:
// Private implementation. // Private implementation.
class Impl; class Impl;
std::unique_ptr<Impl> pImpl; std::unique_ptr<Impl> pImpl;
static const XMMATRIX MatrixIdentity; static const XMMATRIX MatrixIdentity;
static const XMFLOAT2 Float2Zero; static const XMFLOAT2 Float2Zero;
// Prevent copying. // Prevent copying.
SpriteBatch(SpriteBatch const&) DIRECTX_CTOR_DELETE SpriteBatch(SpriteBatch const&) DIRECTX_CTOR_DELETE
SpriteBatch& operator= (SpriteBatch const&) DIRECTX_CTOR_DELETE SpriteBatch& operator=(SpriteBatch const&) DIRECTX_CTOR_DELETE
}; };
} }

View file

@ -29,61 +29,72 @@
namespace DirectX namespace DirectX
{ {
class SpriteFont class SpriteFont
{ {
public: public:
struct Glyph; struct Glyph;
SpriteFont(_In_ ID3D11Device* device, _In_z_ wchar_t const* fileName); SpriteFont(_In_ ID3D11Device* device, _In_z_ wchar_t const* fileName);
SpriteFont(_In_ ID3D11Device* device, _In_reads_bytes_(dataSize) uint8_t const* dataBlob, _In_ size_t dataSize); SpriteFont(_In_ ID3D11Device* device, _In_reads_bytes_(dataSize) uint8_t const* dataBlob, _In_ size_t dataSize);
SpriteFont(_In_ ID3D11ShaderResourceView* texture, _In_reads_(glyphCount) Glyph const* glyphs, _In_ size_t glyphCount, _In_ float lineSpacing); SpriteFont(_In_ ID3D11ShaderResourceView* texture, _In_reads_(glyphCount) Glyph const* glyphs,
_In_ size_t glyphCount, _In_ float lineSpacing);
SpriteFont(SpriteFont&& moveFrom); SpriteFont(SpriteFont&& moveFrom);
SpriteFont& operator= (SpriteFont&& moveFrom); SpriteFont& operator=(SpriteFont&& moveFrom);
virtual ~SpriteFont(); virtual ~SpriteFont();
void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ wchar_t const* text, XMFLOAT2 const& position, FXMVECTOR color = Colors::White, float rotation = 0, XMFLOAT2 const& origin = Float2Zero, float scale = 1, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0) const; void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ wchar_t const* text, XMFLOAT2 const& position,
void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ wchar_t const* text, XMFLOAT2 const& position, FXMVECTOR color, float rotation, XMFLOAT2 const& origin, XMFLOAT2 const& scale, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0) const; FXMVECTOR color = Colors::White, float rotation = 0,
void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ wchar_t const* text, FXMVECTOR position, FXMVECTOR color = Colors::White, float rotation = 0, FXMVECTOR origin = g_XMZero, float scale = 1, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0) const; XMFLOAT2 const& origin = Float2Zero, float scale = 1,
void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ wchar_t const* text, FXMVECTOR position, FXMVECTOR color, float rotation, FXMVECTOR origin, GXMVECTOR scale, SpriteEffects effects = SpriteEffects_None, float layerDepth = 0) const; SpriteEffects effects = SpriteEffects_None, float layerDepth = 0) const;
void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ wchar_t const* text, XMFLOAT2 const& position,
FXMVECTOR color, float rotation, XMFLOAT2 const& origin, XMFLOAT2 const& scale,
SpriteEffects effects = SpriteEffects_None, float layerDepth = 0) const;
void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ wchar_t const* text, FXMVECTOR position,
FXMVECTOR color = Colors::White, float rotation = 0, FXMVECTOR origin = g_XMZero,
float scale = 1, SpriteEffects effects = SpriteEffects_None,
float layerDepth = 0) const;
void XM_CALLCONV DrawString(_In_ SpriteBatch* spriteBatch, _In_z_ wchar_t const* text, FXMVECTOR position,
FXMVECTOR color, float rotation, FXMVECTOR origin, GXMVECTOR scale,
SpriteEffects effects = SpriteEffects_None, float layerDepth = 0) const;
XMVECTOR XM_CALLCONV MeasureString(_In_z_ wchar_t const* text) const; XMVECTOR XM_CALLCONV MeasureString(_In_z_ wchar_t const* text) const;
// Spacing properties // Spacing properties
float __cdecl GetLineSpacing() const; float __cdecl GetLineSpacing() const;
void __cdecl SetLineSpacing(float spacing); void __cdecl SetLineSpacing(float spacing);
// Font properties // Font properties
wchar_t __cdecl GetDefaultCharacter() const; wchar_t __cdecl GetDefaultCharacter() const;
void __cdecl SetDefaultCharacter(wchar_t character); void __cdecl SetDefaultCharacter(wchar_t character);
bool __cdecl ContainsCharacter(wchar_t character) const; bool __cdecl ContainsCharacter(wchar_t character) const;
// Custom layout/rendering // Custom layout/rendering
Glyph const* __cdecl FindGlyph(wchar_t character) const; Glyph const* __cdecl FindGlyph(wchar_t character) const;
void GetSpriteSheet( ID3D11ShaderResourceView** texture ) const; void GetSpriteSheet(ID3D11ShaderResourceView** texture) const;
// Describes a single character glyph. // Describes a single character glyph.
struct Glyph struct Glyph
{ {
uint32_t Character; uint32_t Character;
RECT Subrect; RECT Subrect;
float XOffset; float XOffset;
float YOffset; float YOffset;
float XAdvance; float XAdvance;
}; };
private: private:
// Private implementation. // Private implementation.
class Impl; class Impl;
std::unique_ptr<Impl> pImpl; std::unique_ptr<Impl> pImpl;
static const XMFLOAT2 Float2Zero; static const XMFLOAT2 Float2Zero;
// Prevent copying. // Prevent copying.
SpriteFont(SpriteFont const&) DIRECTX_CTOR_DELETE SpriteFont(SpriteFont const&) DIRECTX_CTOR_DELETE
SpriteFont& operator= (SpriteFont const&) DIRECTX_CTOR_DELETE SpriteFont& operator=(SpriteFont const&) DIRECTX_CTOR_DELETE
}; };
} }

View file

@ -35,299 +35,318 @@
namespace DirectX namespace DirectX
{ {
#if (DIRECTX_MATH_VERSION < 305) && !defined(XM_CALLCONV) #if (DIRECTX_MATH_VERSION < 305) && !defined(XM_CALLCONV)
#define XM_CALLCONV __fastcall #define XM_CALLCONV __fastcall
typedef const XMVECTOR& HXMVECTOR; typedef const XMVECTOR& HXMVECTOR;
typedef const XMMATRIX& FXMMATRIX; typedef const XMMATRIX& FXMMATRIX;
#endif #endif
// Vertex struct holding position and color information. // Vertex struct holding position and color information.
struct VertexPositionColor struct VertexPositionColor
{ {
VertexPositionColor() DIRECTX_CTOR_DEFAULT VertexPositionColor() DIRECTX_CTOR_DEFAULT
VertexPositionColor(XMFLOAT3 const& position, XMFLOAT4 const& color) VertexPositionColor(XMFLOAT3 const& position, XMFLOAT4 const& color)
: position(position), : position(position),
color(color) color(color)
{ } {
}
VertexPositionColor(FXMVECTOR position, FXMVECTOR color) VertexPositionColor(FXMVECTOR position, FXMVECTOR color)
{ {
XMStoreFloat3(&this->position, position); XMStoreFloat3(&this->position, position);
XMStoreFloat4(&this->color, color); XMStoreFloat4(&this->color, color);
} }
XMFLOAT3 position; XMFLOAT3 position;
XMFLOAT4 color; XMFLOAT4 color;
static const int InputElementCount = 2; static const int InputElementCount = 2;
static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount];
}; };
// Vertex struct holding position and texture mapping information. // Vertex struct holding position and texture mapping information.
struct VertexPositionTexture struct VertexPositionTexture
{ {
VertexPositionTexture() DIRECTX_CTOR_DEFAULT VertexPositionTexture() DIRECTX_CTOR_DEFAULT
VertexPositionTexture(XMFLOAT3 const& position, XMFLOAT2 const& textureCoordinate) VertexPositionTexture(XMFLOAT3 const& position, XMFLOAT2 const& textureCoordinate)
: position(position), : position(position),
textureCoordinate(textureCoordinate) textureCoordinate(textureCoordinate)
{ } {
}
VertexPositionTexture(FXMVECTOR position, FXMVECTOR textureCoordinate) VertexPositionTexture(FXMVECTOR position, FXMVECTOR textureCoordinate)
{ {
XMStoreFloat3(&this->position, position); XMStoreFloat3(&this->position, position);
XMStoreFloat2(&this->textureCoordinate, textureCoordinate); XMStoreFloat2(&this->textureCoordinate, textureCoordinate);
} }
XMFLOAT3 position; XMFLOAT3 position;
XMFLOAT2 textureCoordinate; XMFLOAT2 textureCoordinate;
static const int InputElementCount = 2; static const int InputElementCount = 2;
static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount];
}; };
// Vertex struct holding position and normal vector. // Vertex struct holding position and normal vector.
struct VertexPositionNormal struct VertexPositionNormal
{ {
VertexPositionNormal() DIRECTX_CTOR_DEFAULT VertexPositionNormal() DIRECTX_CTOR_DEFAULT
VertexPositionNormal(XMFLOAT3 const& position, XMFLOAT3 const& normal) VertexPositionNormal(XMFLOAT3 const& position, XMFLOAT3 const& normal)
: position(position), : position(position),
normal(normal) normal(normal)
{ } {
}
VertexPositionNormal(FXMVECTOR position, FXMVECTOR normal) VertexPositionNormal(FXMVECTOR position, FXMVECTOR normal)
{ {
XMStoreFloat3(&this->position, position); XMStoreFloat3(&this->position, position);
XMStoreFloat3(&this->normal, normal); XMStoreFloat3(&this->normal, normal);
} }
XMFLOAT3 position; XMFLOAT3 position;
XMFLOAT3 normal; XMFLOAT3 normal;
static const int InputElementCount = 2; static const int InputElementCount = 2;
static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount];
}; };
// Vertex struct holding position, color, and texture mapping information. // Vertex struct holding position, color, and texture mapping information.
struct VertexPositionColorTexture struct VertexPositionColorTexture
{ {
VertexPositionColorTexture() DIRECTX_CTOR_DEFAULT VertexPositionColorTexture() DIRECTX_CTOR_DEFAULT
VertexPositionColorTexture(XMFLOAT3 const& position, XMFLOAT4 const& color, XMFLOAT2 const& textureCoordinate) VertexPositionColorTexture(XMFLOAT3 const& position, XMFLOAT4 const& color, XMFLOAT2 const& textureCoordinate)
: position(position), : position(position),
color(color), color(color),
textureCoordinate(textureCoordinate) textureCoordinate(textureCoordinate)
{ } {
}
VertexPositionColorTexture(FXMVECTOR position, FXMVECTOR color, FXMVECTOR textureCoordinate) VertexPositionColorTexture(FXMVECTOR position, FXMVECTOR color, FXMVECTOR textureCoordinate)
{ {
XMStoreFloat3(&this->position, position); XMStoreFloat3(&this->position, position);
XMStoreFloat4(&this->color, color); XMStoreFloat4(&this->color, color);
XMStoreFloat2(&this->textureCoordinate, textureCoordinate); XMStoreFloat2(&this->textureCoordinate, textureCoordinate);
} }
XMFLOAT3 position; XMFLOAT3 position;
XMFLOAT4 color; XMFLOAT4 color;
XMFLOAT2 textureCoordinate; XMFLOAT2 textureCoordinate;
static const int InputElementCount = 3; static const int InputElementCount = 3;
static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount];
}; };
// Vertex struct holding position, normal vector, and color information. // Vertex struct holding position, normal vector, and color information.
struct VertexPositionNormalColor struct VertexPositionNormalColor
{ {
VertexPositionNormalColor() DIRECTX_CTOR_DEFAULT VertexPositionNormalColor() DIRECTX_CTOR_DEFAULT
VertexPositionNormalColor(XMFLOAT3 const& position, XMFLOAT3 const& normal, XMFLOAT4 const& color) VertexPositionNormalColor(XMFLOAT3 const& position, XMFLOAT3 const& normal, XMFLOAT4 const& color)
: position(position), : position(position),
normal(normal), normal(normal),
color(color) color(color)
{ } {
}
VertexPositionNormalColor(FXMVECTOR position, FXMVECTOR normal, FXMVECTOR color) VertexPositionNormalColor(FXMVECTOR position, FXMVECTOR normal, FXMVECTOR color)
{ {
XMStoreFloat3(&this->position, position); XMStoreFloat3(&this->position, position);
XMStoreFloat3(&this->normal, normal); XMStoreFloat3(&this->normal, normal);
XMStoreFloat4(&this->color, color); XMStoreFloat4(&this->color, color);
} }
XMFLOAT3 position; XMFLOAT3 position;
XMFLOAT3 normal; XMFLOAT3 normal;
XMFLOAT4 color; XMFLOAT4 color;
static const int InputElementCount = 3; static const int InputElementCount = 3;
static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount];
}; };
// Vertex struct holding position, normal vector, and texture mapping information. // Vertex struct holding position, normal vector, and texture mapping information.
struct VertexPositionNormalTexture struct VertexPositionNormalTexture
{ {
VertexPositionNormalTexture() DIRECTX_CTOR_DEFAULT VertexPositionNormalTexture() DIRECTX_CTOR_DEFAULT
VertexPositionNormalTexture(XMFLOAT3 const& position, XMFLOAT3 const& normal, XMFLOAT2 const& textureCoordinate) VertexPositionNormalTexture(XMFLOAT3 const& position, XMFLOAT3 const& normal, XMFLOAT2 const& textureCoordinate)
: position(position), : position(position),
normal(normal), normal(normal),
textureCoordinate(textureCoordinate) textureCoordinate(textureCoordinate)
{ } {
}
VertexPositionNormalTexture(FXMVECTOR position, FXMVECTOR normal, FXMVECTOR textureCoordinate) VertexPositionNormalTexture(FXMVECTOR position, FXMVECTOR normal, FXMVECTOR textureCoordinate)
{ {
XMStoreFloat3(&this->position, position); XMStoreFloat3(&this->position, position);
XMStoreFloat3(&this->normal, normal); XMStoreFloat3(&this->normal, normal);
XMStoreFloat2(&this->textureCoordinate, textureCoordinate); XMStoreFloat2(&this->textureCoordinate, textureCoordinate);
} }
XMFLOAT3 position; XMFLOAT3 position;
XMFLOAT3 normal; XMFLOAT3 normal;
XMFLOAT2 textureCoordinate; XMFLOAT2 textureCoordinate;
static const int InputElementCount = 3; static const int InputElementCount = 3;
static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount];
}; };
// Vertex struct holding position, normal vector, color, and texture mapping information. // Vertex struct holding position, normal vector, color, and texture mapping information.
struct VertexPositionNormalColorTexture struct VertexPositionNormalColorTexture
{ {
VertexPositionNormalColorTexture() DIRECTX_CTOR_DEFAULT VertexPositionNormalColorTexture() DIRECTX_CTOR_DEFAULT
VertexPositionNormalColorTexture(XMFLOAT3 const& position, XMFLOAT3 const& normal, XMFLOAT4 const& color, XMFLOAT2 const& textureCoordinate) VertexPositionNormalColorTexture(XMFLOAT3 const& position, XMFLOAT3 const& normal, XMFLOAT4 const& color,
: position(position), XMFLOAT2 const& textureCoordinate)
normal(normal), : position(position),
color(color), normal(normal),
textureCoordinate(textureCoordinate) color(color),
{ } textureCoordinate(textureCoordinate)
{
}
VertexPositionNormalColorTexture(FXMVECTOR position, FXMVECTOR normal, FXMVECTOR color, CXMVECTOR textureCoordinate) VertexPositionNormalColorTexture(FXMVECTOR position, FXMVECTOR normal, FXMVECTOR color,
{ CXMVECTOR textureCoordinate)
XMStoreFloat3(&this->position, position); {
XMStoreFloat3(&this->normal, normal); XMStoreFloat3(&this->position, position);
XMStoreFloat4(&this->color, color); XMStoreFloat3(&this->normal, normal);
XMStoreFloat2(&this->textureCoordinate, textureCoordinate); XMStoreFloat4(&this->color, color);
} XMStoreFloat2(&this->textureCoordinate, textureCoordinate);
}
XMFLOAT3 position; XMFLOAT3 position;
XMFLOAT3 normal; XMFLOAT3 normal;
XMFLOAT4 color; XMFLOAT4 color;
XMFLOAT2 textureCoordinate; XMFLOAT2 textureCoordinate;
static const int InputElementCount = 4; static const int InputElementCount = 4;
static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount];
}; };
// Vertex struct for Visual Studio Shader Designer (DGSL) holding position, normal, // Vertex struct for Visual Studio Shader Designer (DGSL) holding position, normal,
// tangent, color (RGBA), and texture mapping information // tangent, color (RGBA), and texture mapping information
struct VertexPositionNormalTangentColorTexture struct VertexPositionNormalTangentColorTexture
{ {
VertexPositionNormalTangentColorTexture() DIRECTX_CTOR_DEFAULT VertexPositionNormalTangentColorTexture() DIRECTX_CTOR_DEFAULT
XMFLOAT3 position; XMFLOAT3 position;
XMFLOAT3 normal; XMFLOAT3 normal;
XMFLOAT4 tangent; XMFLOAT4 tangent;
uint32_t color; uint32_t color;
XMFLOAT2 textureCoordinate; XMFLOAT2 textureCoordinate;
VertexPositionNormalTangentColorTexture(XMFLOAT3 const& position, XMFLOAT3 const& normal, XMFLOAT4 const& tangent, uint32_t rgba, XMFLOAT2 const& textureCoordinate) VertexPositionNormalTangentColorTexture(XMFLOAT3 const& position, XMFLOAT3 const& normal, XMFLOAT4 const& tangent,
: position(position), uint32_t rgba, XMFLOAT2 const& textureCoordinate)
normal(normal), : position(position),
tangent(tangent), normal(normal),
color(rgba), tangent(tangent),
textureCoordinate(textureCoordinate) color(rgba),
{ textureCoordinate(textureCoordinate)
} {
}
VertexPositionNormalTangentColorTexture(FXMVECTOR position, FXMVECTOR normal, FXMVECTOR tangent, uint32_t rgba, CXMVECTOR textureCoordinate) VertexPositionNormalTangentColorTexture(FXMVECTOR position, FXMVECTOR normal, FXMVECTOR tangent, uint32_t rgba,
: color(rgba) CXMVECTOR textureCoordinate)
{ : color(rgba)
XMStoreFloat3(&this->position, position); {
XMStoreFloat3(&this->normal, normal); XMStoreFloat3(&this->position, position);
XMStoreFloat4(&this->tangent, tangent); XMStoreFloat3(&this->normal, normal);
XMStoreFloat2(&this->textureCoordinate, textureCoordinate); XMStoreFloat4(&this->tangent, tangent);
} XMStoreFloat2(&this->textureCoordinate, textureCoordinate);
}
VertexPositionNormalTangentColorTexture(XMFLOAT3 const& position, XMFLOAT3 const& normal, XMFLOAT4 const& tangent, XMFLOAT4 const& color, XMFLOAT2 const& textureCoordinate) VertexPositionNormalTangentColorTexture(XMFLOAT3 const& position, XMFLOAT3 const& normal, XMFLOAT4 const& tangent,
: position(position), XMFLOAT4 const& color, XMFLOAT2 const& textureCoordinate)
normal(normal), : position(position),
tangent(tangent), normal(normal),
textureCoordinate(textureCoordinate) tangent(tangent),
{ textureCoordinate(textureCoordinate)
SetColor( color ); {
} SetColor(color);
}
VertexPositionNormalTangentColorTexture(FXMVECTOR position, FXMVECTOR normal, FXMVECTOR tangent, CXMVECTOR color, CXMVECTOR textureCoordinate) VertexPositionNormalTangentColorTexture(FXMVECTOR position, FXMVECTOR normal, FXMVECTOR tangent, CXMVECTOR color,
{ CXMVECTOR textureCoordinate)
XMStoreFloat3(&this->position, position); {
XMStoreFloat3(&this->normal, normal); XMStoreFloat3(&this->position, position);
XMStoreFloat4(&this->tangent, tangent); XMStoreFloat3(&this->normal, normal);
XMStoreFloat2(&this->textureCoordinate, textureCoordinate); XMStoreFloat4(&this->tangent, tangent);
XMStoreFloat2(&this->textureCoordinate, textureCoordinate);
SetColor( color ); SetColor(color);
} }
void __cdecl SetColor( XMFLOAT4 const& icolor ) { SetColor( XMLoadFloat4( &icolor ) ); } void __cdecl SetColor(XMFLOAT4 const& icolor) { SetColor(XMLoadFloat4(&icolor)); }
void XM_CALLCONV SetColor( FXMVECTOR icolor ); void XM_CALLCONV SetColor(FXMVECTOR icolor);
static const int InputElementCount = 5; static const int InputElementCount = 5;
static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount];
}; };
// Vertex struct for Visual Studio Shader Designer (DGSL) holding position, normal, // Vertex struct for Visual Studio Shader Designer (DGSL) holding position, normal,
// tangent, color (RGBA), texture mapping information, and skinning weights // tangent, color (RGBA), texture mapping information, and skinning weights
struct VertexPositionNormalTangentColorTextureSkinning : public VertexPositionNormalTangentColorTexture struct VertexPositionNormalTangentColorTextureSkinning : public VertexPositionNormalTangentColorTexture
{ {
VertexPositionNormalTangentColorTextureSkinning() DIRECTX_CTOR_DEFAULT VertexPositionNormalTangentColorTextureSkinning() DIRECTX_CTOR_DEFAULT
uint32_t indices; uint32_t indices;
uint32_t weights; uint32_t weights;
VertexPositionNormalTangentColorTextureSkinning(XMFLOAT3 const& position, XMFLOAT3 const& normal, XMFLOAT4 const& tangent, uint32_t rgba, VertexPositionNormalTangentColorTextureSkinning(XMFLOAT3 const& position, XMFLOAT3 const& normal,
XMFLOAT2 const& textureCoordinate, XMUINT4 const& indices, XMFLOAT4 const& weights) XMFLOAT4 const& tangent, uint32_t rgba,
: VertexPositionNormalTangentColorTexture(position,normal,tangent,rgba,textureCoordinate) XMFLOAT2 const& textureCoordinate, XMUINT4 const& indices,
{ XMFLOAT4 const& weights)
SetBlendIndices( indices ); : VertexPositionNormalTangentColorTexture(position, normal, tangent, rgba, textureCoordinate)
SetBlendWeights( weights ); {
} SetBlendIndices(indices);
SetBlendWeights(weights);
}
VertexPositionNormalTangentColorTextureSkinning(FXMVECTOR position, FXMVECTOR normal, FXMVECTOR tangent, uint32_t rgba, CXMVECTOR textureCoordinate, VertexPositionNormalTangentColorTextureSkinning(FXMVECTOR position, FXMVECTOR normal, FXMVECTOR tangent,
XMUINT4 const& indices, CXMVECTOR weights) uint32_t rgba, CXMVECTOR textureCoordinate,
: VertexPositionNormalTangentColorTexture(position,normal,tangent,rgba,textureCoordinate) XMUINT4 const& indices, CXMVECTOR weights)
{ : VertexPositionNormalTangentColorTexture(position, normal, tangent, rgba, textureCoordinate)
SetBlendIndices( indices ); {
SetBlendWeights( weights ); SetBlendIndices(indices);
} SetBlendWeights(weights);
}
VertexPositionNormalTangentColorTextureSkinning(XMFLOAT3 const& position, XMFLOAT3 const& normal, XMFLOAT4 const& tangent, XMFLOAT4 const& color, VertexPositionNormalTangentColorTextureSkinning(XMFLOAT3 const& position, XMFLOAT3 const& normal,
XMFLOAT2 const& textureCoordinate, XMUINT4 const& indices, XMFLOAT4 const& weights) XMFLOAT4 const& tangent, XMFLOAT4 const& color,
: VertexPositionNormalTangentColorTexture(position,normal,tangent,color,textureCoordinate) XMFLOAT2 const& textureCoordinate, XMUINT4 const& indices,
{ XMFLOAT4 const& weights)
SetBlendIndices( indices ); : VertexPositionNormalTangentColorTexture(position, normal, tangent, color, textureCoordinate)
SetBlendWeights( weights ); {
} SetBlendIndices(indices);
SetBlendWeights(weights);
}
VertexPositionNormalTangentColorTextureSkinning(FXMVECTOR position, FXMVECTOR normal, FXMVECTOR tangent, CXMVECTOR color, CXMVECTOR textureCoordinate, VertexPositionNormalTangentColorTextureSkinning(FXMVECTOR position, FXMVECTOR normal, FXMVECTOR tangent,
XMUINT4 const& indices, CXMVECTOR weights) CXMVECTOR color, CXMVECTOR textureCoordinate,
: VertexPositionNormalTangentColorTexture(position,normal,tangent,color,textureCoordinate) XMUINT4 const& indices, CXMVECTOR weights)
{ : VertexPositionNormalTangentColorTexture(position, normal, tangent, color, textureCoordinate)
SetBlendIndices( indices ); {
SetBlendWeights( weights ); SetBlendIndices(indices);
} SetBlendWeights(weights);
}
void __cdecl SetBlendIndices( XMUINT4 const& iindices ); void __cdecl SetBlendIndices(XMUINT4 const& iindices);
void __cdecl SetBlendWeights( XMFLOAT4 const& iweights ) { SetBlendWeights( XMLoadFloat4( &iweights ) ); } void __cdecl SetBlendWeights(XMFLOAT4 const& iweights) { SetBlendWeights(XMLoadFloat4(&iweights)); }
void XM_CALLCONV SetBlendWeights( FXMVECTOR iweights ); void XM_CALLCONV SetBlendWeights(FXMVECTOR iweights);
static const int InputElementCount = 7; static const int InputElementCount = 7;
static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount]; static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount];
}; };
} }

View file

@ -44,111 +44,111 @@
namespace DirectX namespace DirectX
{ {
// Standard version // Standard version
HRESULT __cdecl CreateWICTextureFromMemory( _In_ ID3D11Device* d3dDevice, HRESULT __cdecl CreateWICTextureFromMemory(_In_ ID3D11Device* d3dDevice,
_In_reads_bytes_(wicDataSize) const uint8_t* wicData, _In_reads_bytes_(wicDataSize) const uint8_t* wicData,
_In_ size_t wicDataSize, _In_ size_t wicDataSize,
_Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11Resource** texture,
_Out_opt_ ID3D11ShaderResourceView** textureView, _Out_opt_ ID3D11ShaderResourceView** textureView,
_In_ size_t maxsize = 0 _In_ size_t maxsize = 0
); );
HRESULT __cdecl CreateWICTextureFromFile( _In_ ID3D11Device* d3dDevice, HRESULT __cdecl CreateWICTextureFromFile(_In_ ID3D11Device* d3dDevice,
_In_z_ const wchar_t* szFileName, _In_z_ const wchar_t* szFileName,
_Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11Resource** texture,
_Out_opt_ ID3D11ShaderResourceView** textureView, _Out_opt_ ID3D11ShaderResourceView** textureView,
_In_ size_t maxsize = 0 _In_ size_t maxsize = 0
); );
// Standard version with optional auto-gen mipmap support // Standard version with optional auto-gen mipmap support
#if defined(_XBOX_ONE) && defined(_TITLE) #if defined(_XBOX_ONE) && defined(_TITLE)
HRESULT __cdecl CreateWICTextureFromMemory( _In_ ID3D11DeviceX* d3dDevice, HRESULT __cdecl CreateWICTextureFromMemory( _In_ ID3D11DeviceX* d3dDevice,
_In_opt_ ID3D11DeviceContextX* d3dContext, _In_opt_ ID3D11DeviceContextX* d3dContext,
#else #else
HRESULT __cdecl CreateWICTextureFromMemory( _In_ ID3D11Device* d3dDevice, HRESULT __cdecl CreateWICTextureFromMemory(_In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext, _In_opt_ ID3D11DeviceContext* d3dContext,
#endif #endif
_In_reads_bytes_(wicDataSize) const uint8_t* wicData, _In_reads_bytes_(wicDataSize) const uint8_t* wicData,
_In_ size_t wicDataSize, _In_ size_t wicDataSize,
_Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11Resource** texture,
_Out_opt_ ID3D11ShaderResourceView** textureView, _Out_opt_ ID3D11ShaderResourceView** textureView,
_In_ size_t maxsize = 0 _In_ size_t maxsize = 0
); );
#if defined(_XBOX_ONE) && defined(_TITLE) #if defined(_XBOX_ONE) && defined(_TITLE)
HRESULT __cdecl CreateWICTextureFromFile( _In_ ID3D11DeviceX* d3dDevice, HRESULT __cdecl CreateWICTextureFromFile( _In_ ID3D11DeviceX* d3dDevice,
_In_opt_ ID3D11DeviceContextX* d3dContext, _In_opt_ ID3D11DeviceContextX* d3dContext,
#else #else
HRESULT __cdecl CreateWICTextureFromFile( _In_ ID3D11Device* d3dDevice, HRESULT __cdecl CreateWICTextureFromFile(_In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext, _In_opt_ ID3D11DeviceContext* d3dContext,
#endif #endif
_In_z_ const wchar_t* szFileName, _In_z_ const wchar_t* szFileName,
_Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11Resource** texture,
_Out_opt_ ID3D11ShaderResourceView** textureView, _Out_opt_ ID3D11ShaderResourceView** textureView,
_In_ size_t maxsize = 0 _In_ size_t maxsize = 0
); );
// Extended version // Extended version
HRESULT __cdecl CreateWICTextureFromMemoryEx( _In_ ID3D11Device* d3dDevice, HRESULT __cdecl CreateWICTextureFromMemoryEx(_In_ ID3D11Device* d3dDevice,
_In_reads_bytes_(wicDataSize) const uint8_t* wicData, _In_reads_bytes_(wicDataSize) const uint8_t* wicData,
_In_ size_t wicDataSize, _In_ size_t wicDataSize,
_In_ size_t maxsize, _In_ size_t maxsize,
_In_ D3D11_USAGE usage, _In_ D3D11_USAGE usage,
_In_ unsigned int bindFlags, _In_ unsigned int bindFlags,
_In_ unsigned int cpuAccessFlags, _In_ unsigned int cpuAccessFlags,
_In_ unsigned int miscFlags, _In_ unsigned int miscFlags,
_In_ bool forceSRGB, _In_ bool forceSRGB,
_Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11Resource** texture,
_Out_opt_ ID3D11ShaderResourceView** textureView _Out_opt_ ID3D11ShaderResourceView** textureView
); );
HRESULT __cdecl CreateWICTextureFromFileEx( _In_ ID3D11Device* d3dDevice, HRESULT __cdecl CreateWICTextureFromFileEx(_In_ ID3D11Device* d3dDevice,
_In_z_ const wchar_t* szFileName, _In_z_ const wchar_t* szFileName,
_In_ size_t maxsize, _In_ size_t maxsize,
_In_ D3D11_USAGE usage, _In_ D3D11_USAGE usage,
_In_ unsigned int bindFlags, _In_ unsigned int bindFlags,
_In_ unsigned int cpuAccessFlags, _In_ unsigned int cpuAccessFlags,
_In_ unsigned int miscFlags, _In_ unsigned int miscFlags,
_In_ bool forceSRGB, _In_ bool forceSRGB,
_Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11Resource** texture,
_Out_opt_ ID3D11ShaderResourceView** textureView _Out_opt_ ID3D11ShaderResourceView** textureView
); );
// Extended version with optional auto-gen mipmap support // Extended version with optional auto-gen mipmap support
#if defined(_XBOX_ONE) && defined(_TITLE) #if defined(_XBOX_ONE) && defined(_TITLE)
HRESULT __cdecl CreateWICTextureFromMemoryEx( _In_ ID3D11DeviceX* d3dDevice, HRESULT __cdecl CreateWICTextureFromMemoryEx( _In_ ID3D11DeviceX* d3dDevice,
_In_opt_ ID3D11DeviceContextX* d3dContext, _In_opt_ ID3D11DeviceContextX* d3dContext,
#else #else
HRESULT __cdecl CreateWICTextureFromMemoryEx( _In_ ID3D11Device* d3dDevice, HRESULT __cdecl CreateWICTextureFromMemoryEx(_In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext, _In_opt_ ID3D11DeviceContext* d3dContext,
#endif #endif
_In_reads_bytes_(wicDataSize) const uint8_t* wicData, _In_reads_bytes_(wicDataSize) const uint8_t* wicData,
_In_ size_t wicDataSize, _In_ size_t wicDataSize,
_In_ size_t maxsize, _In_ size_t maxsize,
_In_ D3D11_USAGE usage, _In_ D3D11_USAGE usage,
_In_ unsigned int bindFlags, _In_ unsigned int bindFlags,
_In_ unsigned int cpuAccessFlags, _In_ unsigned int cpuAccessFlags,
_In_ unsigned int miscFlags, _In_ unsigned int miscFlags,
_In_ bool forceSRGB, _In_ bool forceSRGB,
_Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11Resource** texture,
_Out_opt_ ID3D11ShaderResourceView** textureView _Out_opt_ ID3D11ShaderResourceView** textureView
); );
#if defined(_XBOX_ONE) && defined(_TITLE) #if defined(_XBOX_ONE) && defined(_TITLE)
HRESULT __cdecl CreateWICTextureFromFileEx( _In_ ID3D11DeviceX* d3dDevice, HRESULT __cdecl CreateWICTextureFromFileEx( _In_ ID3D11DeviceX* d3dDevice,
_In_opt_ ID3D11DeviceContextX* d3dContext, _In_opt_ ID3D11DeviceContextX* d3dContext,
#else #else
HRESULT __cdecl CreateWICTextureFromFileEx( _In_ ID3D11Device* d3dDevice, HRESULT __cdecl CreateWICTextureFromFileEx(_In_ ID3D11Device* d3dDevice,
_In_opt_ ID3D11DeviceContext* d3dContext, _In_opt_ ID3D11DeviceContext* d3dContext,
#endif #endif
_In_z_ const wchar_t* szFileName, _In_z_ const wchar_t* szFileName,
_In_ size_t maxsize, _In_ size_t maxsize,
_In_ D3D11_USAGE usage, _In_ D3D11_USAGE usage,
_In_ unsigned int bindFlags, _In_ unsigned int bindFlags,
_In_ unsigned int cpuAccessFlags, _In_ unsigned int cpuAccessFlags,
_In_ unsigned int miscFlags, _In_ unsigned int miscFlags,
_In_ bool forceSRGB, _In_ bool forceSRGB,
_Out_opt_ ID3D11Resource** texture, _Out_opt_ ID3D11Resource** texture,
_Out_opt_ ID3D11ShaderResourceView** textureView _Out_opt_ ID3D11ShaderResourceView** textureView
); );
} }

View file

@ -31,31 +31,31 @@
namespace Xbox namespace Xbox
{ {
enum DDS_ALPHA_MODE enum DDS_ALPHA_MODE
{ {
DDS_ALPHA_MODE_UNKNOWN = 0, DDS_ALPHA_MODE_UNKNOWN = 0,
DDS_ALPHA_MODE_STRAIGHT = 1, DDS_ALPHA_MODE_STRAIGHT = 1,
DDS_ALPHA_MODE_PREMULTIPLIED = 2, DDS_ALPHA_MODE_PREMULTIPLIED = 2,
DDS_ALPHA_MODE_OPAQUE = 3, DDS_ALPHA_MODE_OPAQUE = 3,
DDS_ALPHA_MODE_CUSTOM = 4, DDS_ALPHA_MODE_CUSTOM = 4,
}; };
HRESULT __cdecl CreateDDSTextureFromMemory( _In_ ID3D11DeviceX* d3dDevice, HRESULT __cdecl CreateDDSTextureFromMemory(_In_ ID3D11DeviceX* d3dDevice,
_In_reads_bytes_(ddsDataSize) const uint8_t* ddsData, _In_reads_bytes_(ddsDataSize) const uint8_t* ddsData,
_In_ size_t ddsDataSize, _In_ size_t ddsDataSize,
_Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11Resource** texture,
_Outptr_opt_ ID3D11ShaderResourceView** textureView, _Outptr_opt_ ID3D11ShaderResourceView** textureView,
_Outptr_ void** grfxMemory, _Outptr_ void** grfxMemory,
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr, _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr,
_In_ bool forceSRGB = false _In_ bool forceSRGB = false
); );
HRESULT __cdecl CreateDDSTextureFromFile( _In_ ID3D11DeviceX* d3dDevice, HRESULT __cdecl CreateDDSTextureFromFile(_In_ ID3D11DeviceX* d3dDevice,
_In_z_ const wchar_t* szFileName, _In_z_ const wchar_t* szFileName,
_Outptr_opt_ ID3D11Resource** texture, _Outptr_opt_ ID3D11Resource** texture,
_Outptr_opt_ ID3D11ShaderResourceView** textureView, _Outptr_opt_ ID3D11ShaderResourceView** textureView,
_Outptr_ void** grfxMemory, _Outptr_ void** grfxMemory,
_Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr, _Out_opt_ DDS_ALPHA_MODE* alphaMode = nullptr,
_In_ bool forceSRGB = false _In_ bool forceSRGB = false
); );
} }

View file

@ -13,7 +13,8 @@
using namespace DirectX; using namespace DirectX;
Renderer::Renderer(shared_ptr<Console> console, HWND hWnd, bool registerAsMessageManager) : BaseRenderer(console, registerAsMessageManager) Renderer::Renderer(shared_ptr<Console> console, HWND hWnd, bool registerAsMessageManager) : BaseRenderer(
console, registerAsMessageManager)
{ {
_hWnd = hWnd; _hWnd = hWnd;
@ -23,7 +24,8 @@ Renderer::Renderer(shared_ptr<Console> console, HWND hWnd, bool registerAsMessag
Renderer::~Renderer() Renderer::~Renderer()
{ {
shared_ptr<VideoRenderer> videoRenderer = _console->GetVideoRenderer(); shared_ptr<VideoRenderer> videoRenderer = _console->GetVideoRenderer();
if(videoRenderer) { if (videoRenderer)
{
videoRenderer->UnregisterRenderingDevice(this); videoRenderer->UnregisterRenderingDevice(this);
} }
CleanupDevice(); CleanupDevice();
@ -31,7 +33,8 @@ Renderer::~Renderer()
void Renderer::SetFullscreenMode(bool fullscreen, void* windowHandle, uint32_t monitorWidth, uint32_t monitorHeight) void Renderer::SetFullscreenMode(bool fullscreen, void* windowHandle, uint32_t monitorWidth, uint32_t monitorHeight)
{ {
if(fullscreen != _fullscreen || _hWnd != (HWND)windowHandle) { if (fullscreen != _fullscreen || _hWnd != (HWND)windowHandle)
{
_hWnd = (HWND)windowHandle; _hWnd = (HWND)windowHandle;
_monitorWidth = monitorWidth; _monitorWidth = monitorWidth;
_monitorHeight = monitorHeight; _monitorHeight = monitorHeight;
@ -43,21 +46,29 @@ void Renderer::SetScreenSize(uint32_t width, uint32_t height)
{ {
ScreenSize screenSize = _console->GetVideoDecoder()->GetScreenSize(false); ScreenSize screenSize = _console->GetVideoDecoder()->GetScreenSize(false);
VideoConfig cfg = _console->GetSettings()->GetVideoConfig(); VideoConfig cfg = _console->GetSettings()->GetVideoConfig();
if(_screenHeight != screenSize.Height || _screenWidth != screenSize.Width || _nesFrameHeight != height || _nesFrameWidth != width || _newFullscreen != _fullscreen || _useBilinearInterpolation != cfg.UseBilinearInterpolation) { if (_screenHeight != screenSize.Height || _screenWidth != screenSize.Width || _nesFrameHeight != height ||
_nesFrameWidth != width || _newFullscreen != _fullscreen || _useBilinearInterpolation != cfg.
UseBilinearInterpolation)
{
auto frameLock = _frameLock.AcquireSafe(); auto frameLock = _frameLock.AcquireSafe();
auto textureLock = _textureLock.AcquireSafe(); auto textureLock = _textureLock.AcquireSafe();
screenSize = _console->GetVideoDecoder()->GetScreenSize(false); screenSize = _console->GetVideoDecoder()->GetScreenSize(false);
if(_screenHeight != screenSize.Height || _screenWidth != screenSize.Width || _nesFrameHeight != height || _nesFrameWidth != width || _newFullscreen != _fullscreen || _useBilinearInterpolation != cfg.UseBilinearInterpolation) { if (_screenHeight != screenSize.Height || _screenWidth != screenSize.Width || _nesFrameHeight != height ||
_nesFrameWidth != width || _newFullscreen != _fullscreen || _useBilinearInterpolation != cfg.
UseBilinearInterpolation)
{
_nesFrameHeight = height; _nesFrameHeight = height;
_nesFrameWidth = width; _nesFrameWidth = width;
_newFrameBufferSize = width*height; _newFrameBufferSize = width * height;
bool needReset = _fullscreen != _newFullscreen || _useBilinearInterpolation != cfg.UseBilinearInterpolation; bool needReset = _fullscreen != _newFullscreen || _useBilinearInterpolation != cfg.UseBilinearInterpolation;
bool fullscreenResizeMode = _fullscreen && _newFullscreen; bool fullscreenResizeMode = _fullscreen && _newFullscreen;
if(_pSwapChain && _fullscreen && !_newFullscreen) { if (_pSwapChain && _fullscreen && !_newFullscreen)
{
HRESULT hr = _pSwapChain->SetFullscreenState(FALSE, NULL); HRESULT hr = _pSwapChain->SetFullscreenState(FALSE, NULL);
if(FAILED(hr)) { if (FAILED(hr))
{
MessageManager::Log("SetFullscreenState(FALSE) failed - Error:" + std::to_string(hr)); MessageManager::Log("SetFullscreenState(FALSE) failed - Error:" + std::to_string(hr));
} }
} }
@ -67,21 +78,26 @@ void Renderer::SetScreenSize(uint32_t width, uint32_t height)
_screenHeight = screenSize.Height; _screenHeight = screenSize.Height;
_screenWidth = screenSize.Width; _screenWidth = screenSize.Width;
if(_fullscreen) { if (_fullscreen)
{
_realScreenHeight = _monitorHeight; _realScreenHeight = _monitorHeight;
_realScreenWidth = _monitorWidth; _realScreenWidth = _monitorWidth;
//Ensure the screen width/height is smaller or equal to the fullscreen resolution, no matter the requested scale //Ensure the screen width/height is smaller or equal to the fullscreen resolution, no matter the requested scale
if(_monitorHeight < _screenHeight || _monitorWidth < _screenWidth) { if (_monitorHeight < _screenHeight || _monitorWidth < _screenWidth)
{
double scale = (double)screenSize.Width / (double)screenSize.Height; double scale = (double)screenSize.Width / (double)screenSize.Height;
_screenHeight = _monitorHeight; _screenHeight = _monitorHeight;
_screenWidth = (uint32_t)(scale * _screenHeight); _screenWidth = (uint32_t)(scale * _screenHeight);
if(_monitorWidth < _screenWidth) { if (_monitorWidth < _screenWidth)
{
_screenWidth = _monitorWidth; _screenWidth = _monitorWidth;
_screenHeight = (uint32_t)(_screenWidth / scale); _screenHeight = (uint32_t)(_screenWidth / scale);
} }
} }
} else { }
else
{
_realScreenHeight = screenSize.Height; _realScreenHeight = screenSize.Height;
_realScreenWidth = screenSize.Width; _realScreenWidth = screenSize.Width;
} }
@ -89,15 +105,21 @@ void Renderer::SetScreenSize(uint32_t width, uint32_t height)
_leftMargin = (_realScreenWidth - _screenWidth) / 2; _leftMargin = (_realScreenWidth - _screenWidth) / 2;
_topMargin = (_realScreenHeight - _screenHeight) / 2; _topMargin = (_realScreenHeight - _screenHeight) / 2;
_screenBufferSize = _realScreenHeight*_realScreenWidth; _screenBufferSize = _realScreenHeight * _realScreenWidth;
if(!_pSwapChain || needReset) { if (!_pSwapChain || needReset)
{
Reset(); Reset();
} else { }
if(fullscreenResizeMode) { else
{
if (fullscreenResizeMode)
{
ResetNesBuffers(); ResetNesBuffers();
CreateNesBuffers(); CreateNesBuffers();
} else { }
else
{
ResetNesBuffers(); ResetNesBuffers();
ReleaseRenderTargetView(); ReleaseRenderTargetView();
_pSwapChain->ResizeBuffers(1, _realScreenWidth, _realScreenHeight, DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, 0); _pSwapChain->ResizeBuffers(1, _realScreenWidth, _realScreenHeight, DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, 0);
@ -113,9 +135,12 @@ void Renderer::Reset()
{ {
auto lock = _frameLock.AcquireSafe(); auto lock = _frameLock.AcquireSafe();
CleanupDevice(); CleanupDevice();
if(FAILED(InitDevice())) { if (FAILED(InitDevice()))
{
CleanupDevice(); CleanupDevice();
} else { }
else
{
_console->GetVideoRenderer()->RegisterRenderingDevice(this); _console->GetVideoRenderer()->RegisterRenderingDevice(this);
} }
} }
@ -124,28 +149,34 @@ void Renderer::CleanupDevice()
{ {
ResetNesBuffers(); ResetNesBuffers();
ReleaseRenderTargetView(); ReleaseRenderTargetView();
if(_pAlphaEnableBlendingState) { if (_pAlphaEnableBlendingState)
{
_pAlphaEnableBlendingState->Release(); _pAlphaEnableBlendingState->Release();
_pAlphaEnableBlendingState = nullptr; _pAlphaEnableBlendingState = nullptr;
} }
if(_pDepthDisabledStencilState) { if (_pDepthDisabledStencilState)
{
_pDepthDisabledStencilState->Release(); _pDepthDisabledStencilState->Release();
_pDepthDisabledStencilState = nullptr; _pDepthDisabledStencilState = nullptr;
} }
if(_samplerState) { if (_samplerState)
{
_samplerState->Release(); _samplerState->Release();
_samplerState = nullptr; _samplerState = nullptr;
} }
if(_pSwapChain) { if (_pSwapChain)
{
_pSwapChain->SetFullscreenState(false, nullptr); _pSwapChain->SetFullscreenState(false, nullptr);
_pSwapChain->Release(); _pSwapChain->Release();
_pSwapChain = nullptr; _pSwapChain = nullptr;
} }
if(_pDeviceContext) { if (_pDeviceContext)
{
_pDeviceContext->Release(); _pDeviceContext->Release();
_pDeviceContext = nullptr; _pDeviceContext = nullptr;
} }
if(_pd3dDevice) { if (_pd3dDevice)
{
_pd3dDevice->Release(); _pd3dDevice->Release();
_pd3dDevice = nullptr; _pd3dDevice = nullptr;
} }
@ -153,19 +184,23 @@ void Renderer::CleanupDevice()
void Renderer::ResetNesBuffers() void Renderer::ResetNesBuffers()
{ {
if(_pTexture) { if (_pTexture)
{
_pTexture->Release(); _pTexture->Release();
_pTexture = nullptr; _pTexture = nullptr;
} }
if(_overlayTexture) { if (_overlayTexture)
{
_overlayTexture->Release(); _overlayTexture->Release();
_overlayTexture = nullptr; _overlayTexture = nullptr;
} }
if(_pTextureSrv) { if (_pTextureSrv)
{
_pTextureSrv->Release(); _pTextureSrv->Release();
_pTextureSrv = nullptr; _pTextureSrv = nullptr;
} }
if(_pOverlaySrv) { if (_pOverlaySrv)
{
_pOverlaySrv->Release(); _pOverlaySrv->Release();
_pOverlaySrv = nullptr; _pOverlaySrv = nullptr;
} }
@ -178,7 +213,8 @@ void Renderer::ResetNesBuffers()
void Renderer::ReleaseRenderTargetView() void Renderer::ReleaseRenderTargetView()
{ {
if(_pRenderTargetView) { if (_pRenderTargetView)
{
_pRenderTargetView->Release(); _pRenderTargetView->Release();
_pRenderTargetView = nullptr; _pRenderTargetView = nullptr;
} }
@ -189,14 +225,16 @@ HRESULT Renderer::CreateRenderTargetView()
// Create a render target view // Create a render target view
ID3D11Texture2D* pBackBuffer = nullptr; ID3D11Texture2D* pBackBuffer = nullptr;
HRESULT hr = _pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); HRESULT hr = _pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
if(FAILED(hr)) { if (FAILED(hr))
{
MessageManager::Log("SwapChain::GetBuffer() failed - Error:" + std::to_string(hr)); MessageManager::Log("SwapChain::GetBuffer() failed - Error:" + std::to_string(hr));
return hr; return hr;
} }
hr = _pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &_pRenderTargetView); hr = _pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &_pRenderTargetView);
pBackBuffer->Release(); pBackBuffer->Release();
if(FAILED(hr)) { if (FAILED(hr))
{
MessageManager::Log("D3DDevice::CreateRenderTargetView() failed - Error:" + std::to_string(hr)); MessageManager::Log("D3DDevice::CreateRenderTargetView() failed - Error:" + std::to_string(hr));
return hr; return hr;
} }
@ -218,25 +256,29 @@ HRESULT Renderer::CreateNesBuffers()
vp.TopLeftY = 0; vp.TopLeftY = 0;
_pDeviceContext->RSSetViewports(1, &vp); _pDeviceContext->RSSetViewports(1, &vp);
_textureBuffer[0] = new uint8_t[_nesFrameWidth*_nesFrameHeight * 4]; _textureBuffer[0] = new uint8_t[_nesFrameWidth * _nesFrameHeight * 4];
_textureBuffer[1] = new uint8_t[_nesFrameWidth*_nesFrameHeight * 4]; _textureBuffer[1] = new uint8_t[_nesFrameWidth * _nesFrameHeight * 4];
memset(_textureBuffer[0], 0, _nesFrameWidth*_nesFrameHeight * 4); memset(_textureBuffer[0], 0, _nesFrameWidth * _nesFrameHeight * 4);
memset(_textureBuffer[1], 0, _nesFrameWidth*_nesFrameHeight * 4); memset(_textureBuffer[1], 0, _nesFrameWidth * _nesFrameHeight * 4);
_pTexture = CreateTexture(_nesFrameWidth, _nesFrameHeight); _pTexture = CreateTexture(_nesFrameWidth, _nesFrameHeight);
if(!_pTexture) { if (!_pTexture)
{
return S_FALSE; return S_FALSE;
} }
_overlayTexture = CreateTexture(8, 8); _overlayTexture = CreateTexture(8, 8);
if(!_overlayTexture) { if (!_overlayTexture)
{
return S_FALSE; return S_FALSE;
} }
_pTextureSrv = GetShaderResourceView(_pTexture); _pTextureSrv = GetShaderResourceView(_pTexture);
if(!_pTextureSrv) { if (!_pTextureSrv)
{
return S_FALSE; return S_FALSE;
} }
_pOverlaySrv = GetShaderResourceView(_overlayTexture); _pOverlaySrv = GetShaderResourceView(_overlayTexture);
if(!_pOverlaySrv) { if (!_pOverlaySrv)
{
return S_FALSE; return S_FALSE;
} }
@ -296,38 +338,49 @@ HRESULT Renderer::InitDevice()
D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_NULL; D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_NULL;
D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_1; D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_1;
for(UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++) { for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++)
{
driverType = driverTypes[driverTypeIndex]; driverType = driverTypes[driverTypeIndex];
featureLevel = D3D_FEATURE_LEVEL_11_1; featureLevel = D3D_FEATURE_LEVEL_11_1;
hr = D3D11CreateDeviceAndSwapChain(nullptr, driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &sd, &_pSwapChain, &_pd3dDevice, &featureLevel, &_pDeviceContext); hr = D3D11CreateDeviceAndSwapChain(nullptr, driverType, nullptr, createDeviceFlags, featureLevels,
numFeatureLevels, D3D11_SDK_VERSION, &sd, &_pSwapChain, &_pd3dDevice,
&featureLevel, &_pDeviceContext);
/*if(FAILED(hr)) { /*if(FAILED(hr)) {
MessageManager::Log("D3D11CreateDeviceAndSwapChain() failed - Error:" + std::to_string(hr)); MessageManager::Log("D3D11CreateDeviceAndSwapChain() failed - Error:" + std::to_string(hr));
}*/ }*/
if(hr == E_INVALIDARG) { if (hr == E_INVALIDARG)
{
// DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it
featureLevel = D3D_FEATURE_LEVEL_11_0; featureLevel = D3D_FEATURE_LEVEL_11_0;
hr = D3D11CreateDeviceAndSwapChain(nullptr, driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1, D3D11_SDK_VERSION, &sd, &_pSwapChain, &_pd3dDevice, &featureLevel, &_pDeviceContext); hr = D3D11CreateDeviceAndSwapChain(nullptr, driverType, nullptr, createDeviceFlags, &featureLevels[1],
numFeatureLevels - 1, D3D11_SDK_VERSION, &sd, &_pSwapChain, &_pd3dDevice,
&featureLevel, &_pDeviceContext);
} }
if(SUCCEEDED(hr)) { if (SUCCEEDED(hr))
{
break; break;
} }
} }
if(FAILED(hr)) { if (FAILED(hr))
{
MessageManager::Log("D3D11CreateDeviceAndSwapChain() failed - Error:" + std::to_string(hr)); MessageManager::Log("D3D11CreateDeviceAndSwapChain() failed - Error:" + std::to_string(hr));
return hr; return hr;
} }
if(_fullscreen) { if (_fullscreen)
{
hr = _pSwapChain->SetFullscreenState(TRUE, NULL); hr = _pSwapChain->SetFullscreenState(TRUE, NULL);
if(FAILED(hr)) { if (FAILED(hr))
{
MessageManager::Log("SetFullscreenState(true) failed - Error:" + std::to_string(hr)); MessageManager::Log("SetFullscreenState(true) failed - Error:" + std::to_string(hr));
MessageManager::Log("Switching back to windowed mode"); MessageManager::Log("Switching back to windowed mode");
hr = _pSwapChain->SetFullscreenState(FALSE, NULL); hr = _pSwapChain->SetFullscreenState(FALSE, NULL);
if(FAILED(hr)) { if (FAILED(hr))
{
MessageManager::Log("SetFullscreenState(false) failed - Error:" + std::to_string(hr)); MessageManager::Log("SetFullscreenState(false) failed - Error:" + std::to_string(hr));
return hr; return hr;
} }
@ -335,7 +388,8 @@ HRESULT Renderer::InitDevice()
} }
hr = CreateRenderTargetView(); hr = CreateRenderTargetView();
if(FAILED(hr)) { if (FAILED(hr))
{
return hr; return hr;
} }
@ -358,7 +412,8 @@ HRESULT Renderer::InitDevice()
// Create the state using the device. // Create the state using the device.
hr = _pd3dDevice->CreateDepthStencilState(&depthDisabledStencilDesc, &_pDepthDisabledStencilState); hr = _pd3dDevice->CreateDepthStencilState(&depthDisabledStencilDesc, &_pDepthDisabledStencilState);
if(FAILED(hr)) { if (FAILED(hr))
{
MessageManager::Log("D3DDevice::CreateDepthStencilState() failed - Error:" + std::to_string(hr)); MessageManager::Log("D3DDevice::CreateDepthStencilState() failed - Error:" + std::to_string(hr));
return hr; return hr;
} }
@ -379,7 +434,8 @@ HRESULT Renderer::InitDevice()
// Create the blend state using the description. // Create the blend state using the description.
hr = _pd3dDevice->CreateBlendState(&blendStateDescription, &_pAlphaEnableBlendingState); hr = _pd3dDevice->CreateBlendState(&blendStateDescription, &_pAlphaEnableBlendingState);
if(FAILED(hr)) { if (FAILED(hr))
{
MessageManager::Log("D3DDevice::CreateBlendState() failed - Error:" + std::to_string(hr)); MessageManager::Log("D3DDevice::CreateBlendState() failed - Error:" + std::to_string(hr));
return hr; return hr;
} }
@ -394,12 +450,14 @@ HRESULT Renderer::InitDevice()
_pDeviceContext->OMSetDepthStencilState(_pDepthDisabledStencilState, 1); _pDeviceContext->OMSetDepthStencilState(_pDepthDisabledStencilState, 1);
hr = CreateNesBuffers(); hr = CreateNesBuffers();
if(FAILED(hr)) { if (FAILED(hr))
{
return hr; return hr;
} }
hr = CreateSamplerState(); hr = CreateSamplerState();
if(FAILED(hr)) { if (FAILED(hr))
{
return hr; return hr;
} }
@ -425,7 +483,8 @@ HRESULT Renderer::CreateSamplerState()
samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
HRESULT hr = _pd3dDevice->CreateSamplerState(&samplerDesc, &_samplerState); HRESULT hr = _pd3dDevice->CreateSamplerState(&samplerDesc, &_samplerState);
if(FAILED(hr)) { if (FAILED(hr))
{
MessageManager::Log("D3DDevice::CreateSamplerState() failed - Error:" + std::to_string(hr)); MessageManager::Log("D3DDevice::CreateSamplerState() failed - Error:" + std::to_string(hr));
} }
@ -452,7 +511,8 @@ ID3D11Texture2D* Renderer::CreateTexture(uint32_t width, uint32_t height)
desc.MiscFlags = 0; desc.MiscFlags = 0;
HRESULT hr = _pd3dDevice->CreateTexture2D(&desc, nullptr, &texture); HRESULT hr = _pd3dDevice->CreateTexture2D(&desc, nullptr, &texture);
if(FAILED(hr)) { if (FAILED(hr))
{
MessageManager::Log("D3DDevice::CreateTexture() failed - Error:" + std::to_string(hr)); MessageManager::Log("D3DDevice::CreateTexture() failed - Error:" + std::to_string(hr));
return nullptr; return nullptr;
} }
@ -461,9 +521,10 @@ ID3D11Texture2D* Renderer::CreateTexture(uint32_t width, uint32_t height)
ID3D11ShaderResourceView* Renderer::GetShaderResourceView(ID3D11Texture2D* texture) ID3D11ShaderResourceView* Renderer::GetShaderResourceView(ID3D11Texture2D* texture)
{ {
ID3D11ShaderResourceView *shaderResourceView = nullptr; ID3D11ShaderResourceView* shaderResourceView = nullptr;
HRESULT hr = _pd3dDevice->CreateShaderResourceView(texture, nullptr, &shaderResourceView); HRESULT hr = _pd3dDevice->CreateShaderResourceView(texture, nullptr, &shaderResourceView);
if(FAILED(hr)) { if (FAILED(hr))
{
MessageManager::Log("D3DDevice::CreateShaderResourceView() failed - Error:" + std::to_string(hr)); MessageManager::Log("D3DDevice::CreateShaderResourceView() failed - Error:" + std::to_string(hr));
return nullptr; return nullptr;
} }
@ -477,25 +538,29 @@ void Renderer::DrawString(string message, float x, float y, DirectX::FXMVECTOR c
DrawString(textStr, x, y, color, scale, font); DrawString(textStr, x, y, color, scale, font);
} }
void Renderer::DrawString(std::wstring message, float x, float y, DirectX::FXMVECTOR color, float scale, SpriteFont* font) void Renderer::DrawString(std::wstring message, float x, float y, DirectX::FXMVECTOR color, float scale,
SpriteFont* font)
{ {
const wchar_t *text = message.c_str(); const wchar_t* text = message.c_str();
if(font == nullptr) { if (font == nullptr)
{
font = _font.get(); font = _font.get();
} }
font->DrawString(_spriteBatch.get(), text, XMFLOAT2(x+_leftMargin, y+_topMargin), color, 0.0f, XMFLOAT2(0, 0), scale); font->DrawString(_spriteBatch.get(), text, XMFLOAT2(x + _leftMargin, y + _topMargin), color, 0.0f, XMFLOAT2(0, 0),
scale);
} }
void Renderer::UpdateFrame(void *frameBuffer, uint32_t width, uint32_t height) void Renderer::UpdateFrame(void* frameBuffer, uint32_t width, uint32_t height)
{ {
SetScreenSize(width, height); SetScreenSize(width, height);
uint32_t bpp = 4; uint32_t bpp = 4;
auto lock = _textureLock.AcquireSafe(); auto lock = _textureLock.AcquireSafe();
if(_textureBuffer[0]) { if (_textureBuffer[0])
{
//_textureBuffer[0] may be null if directx failed to initialize properly //_textureBuffer[0] may be null if directx failed to initialize properly
memcpy(_textureBuffer[0], frameBuffer, width*height*bpp); memcpy(_textureBuffer[0], frameBuffer, width * height * bpp);
_needFlip = true; _needFlip = true;
_frameChanged = true; _frameChanged = true;
} }
@ -504,14 +569,16 @@ void Renderer::UpdateFrame(void *frameBuffer, uint32_t width, uint32_t height)
void Renderer::DrawScreen() void Renderer::DrawScreen()
{ {
//Swap buffers - emulator always writes to _textureBuffer[0], screen always draws _textureBuffer[1] //Swap buffers - emulator always writes to _textureBuffer[0], screen always draws _textureBuffer[1]
if(_needFlip) { if (_needFlip)
{
auto lock = _textureLock.AcquireSafe(); auto lock = _textureLock.AcquireSafe();
uint8_t* textureBuffer = _textureBuffer[0]; uint8_t* textureBuffer = _textureBuffer[0];
_textureBuffer[0] = _textureBuffer[1]; _textureBuffer[0] = _textureBuffer[1];
_textureBuffer[1] = textureBuffer; _textureBuffer[1] = textureBuffer;
_needFlip = false; _needFlip = false;
if(_frameChanged) { if (_frameChanged)
{
_frameChanged = false; _frameChanged = false;
_renderedFrameCount++; _renderedFrameCount++;
} }
@ -522,13 +589,15 @@ void Renderer::DrawScreen()
uint32_t rowPitch = _nesFrameWidth * bpp; uint32_t rowPitch = _nesFrameWidth * bpp;
D3D11_MAPPED_SUBRESOURCE dd; D3D11_MAPPED_SUBRESOURCE dd;
HRESULT hr = _pDeviceContext->Map(_pTexture, 0, D3D11_MAP_WRITE_DISCARD, 0, &dd); HRESULT hr = _pDeviceContext->Map(_pTexture, 0, D3D11_MAP_WRITE_DISCARD, 0, &dd);
if(FAILED(hr)) { if (FAILED(hr))
{
MessageManager::Log("DeviceContext::Map() failed - Error:" + std::to_string(hr)); MessageManager::Log("DeviceContext::Map() failed - Error:" + std::to_string(hr));
return; return;
} }
uint8_t* surfacePointer = (uint8_t*)dd.pData; uint8_t* surfacePointer = (uint8_t*)dd.pData;
uint8_t* videoBuffer = _textureBuffer[1]; uint8_t* videoBuffer = _textureBuffer[1];
for(uint32_t i = 0, iMax = _nesFrameHeight; i < iMax; i++) { for (uint32_t i = 0, iMax = _nesFrameHeight; i < iMax; i++)
{
memcpy(surfacePointer, videoBuffer, rowPitch); memcpy(surfacePointer, videoBuffer, rowPitch);
videoBuffer += rowPitch; videoBuffer += rowPitch;
surfacePointer += dd.RowPitch; surfacePointer += dd.RowPitch;
@ -538,15 +607,15 @@ void Renderer::DrawScreen()
RECT destRect; RECT destRect;
destRect.left = _leftMargin; destRect.left = _leftMargin;
destRect.top = _topMargin; destRect.top = _topMargin;
destRect.right = _screenWidth+_leftMargin; destRect.right = _screenWidth + _leftMargin;
destRect.bottom = _screenHeight+_topMargin; destRect.bottom = _screenHeight + _topMargin;
_spriteBatch->Draw(_pTextureSrv, destRect); _spriteBatch->Draw(_pTextureSrv, destRect);
} }
void Renderer::DrawPauseScreen() void Renderer::DrawPauseScreen()
{ {
const static XMVECTORF32 transparentBlue = { { { 1.0f, 0.6f, 0.0f, 0.66f } } }; const static XMVECTORF32 transparentBlue = {{{1.0f, 0.6f, 0.0f, 0.66f}}};
DrawString("I", 15, 15, transparentBlue, 2.0f, _font.get()); DrawString("I", 15, 15, transparentBlue, 2.0f, _font.get());
DrawString("I", 32, 15, transparentBlue, 2.0f, _font.get()); DrawString("I", 32, 15, transparentBlue, 2.0f, _font.get());
} }
@ -555,18 +624,22 @@ void Renderer::Render()
{ {
bool paused = _console->IsPaused(); bool paused = _console->IsPaused();
if(_noUpdateCount > 10 || _frameChanged || paused || IsMessageShown()) { if (_noUpdateCount > 10 || _frameChanged || paused || IsMessageShown())
{
_noUpdateCount = 0; _noUpdateCount = 0;
auto lock = _frameLock.AcquireSafe(); auto lock = _frameLock.AcquireSafe();
if(_newFullscreen != _fullscreen) { if (_newFullscreen != _fullscreen)
{
SetScreenSize(_nesFrameWidth, _nesFrameHeight); SetScreenSize(_nesFrameWidth, _nesFrameHeight);
} }
if(_pDeviceContext == nullptr) { if (_pDeviceContext == nullptr)
{
//DirectX failed to initialize, try to init //DirectX failed to initialize, try to init
Reset(); Reset();
if(_pDeviceContext == nullptr) { if (_pDeviceContext == nullptr)
{
//Can't init, prevent crash //Can't init, prevent crash
return; return;
} }
@ -580,8 +653,10 @@ void Renderer::Render()
//Draw screen //Draw screen
DrawScreen(); DrawScreen();
if(_console->IsRunning()) { if (_console->IsRunning())
if(paused) { {
if (paused)
{
DrawPauseScreen(); DrawPauseScreen();
} }
DrawCounters(); DrawCounters();
@ -595,23 +670,29 @@ void Renderer::Render()
bool waitVSync = _console->GetSettings()->GetVideoConfig().VerticalSync; bool waitVSync = _console->GetSettings()->GetVideoConfig().VerticalSync;
HRESULT hr = _pSwapChain->Present(waitVSync ? 1 : 0, 0); HRESULT hr = _pSwapChain->Present(waitVSync ? 1 : 0, 0);
if(FAILED(hr)) { if (FAILED(hr))
{
MessageManager::Log("SwapChain::Present() failed - Error:" + std::to_string(hr)); MessageManager::Log("SwapChain::Present() failed - Error:" + std::to_string(hr));
if(hr == DXGI_ERROR_DEVICE_REMOVED) { if (hr == DXGI_ERROR_DEVICE_REMOVED)
MessageManager::Log("D3DDevice: GetDeviceRemovedReason: " + std::to_string(_pd3dDevice->GetDeviceRemovedReason())); {
MessageManager::Log(
"D3DDevice: GetDeviceRemovedReason: " + std::to_string(_pd3dDevice->GetDeviceRemovedReason()));
} }
MessageManager::Log("Trying to reset DX..."); MessageManager::Log("Trying to reset DX...");
Reset(); Reset();
} }
} else { }
else
{
_noUpdateCount++; _noUpdateCount++;
} }
} }
void Renderer::DrawString(std::wstring message, int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t opacity) void Renderer::DrawString(std::wstring message, int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t opacity)
{ {
XMVECTORF32 color = { (float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, (float)opacity / 255.0f }; XMVECTORF32 color = {(float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, (float)opacity / 255.0f};
_font->DrawString(_spriteBatch.get(), message.c_str(), XMFLOAT2((float)x+_leftMargin, (float)y+_topMargin), color); _font->DrawString(_spriteBatch.get(), message.c_str(), XMFLOAT2((float)x + _leftMargin, (float)y + _topMargin),
color);
} }
float Renderer::MeasureString(std::wstring text) float Renderer::MeasureString(std::wstring text)

View file

@ -12,7 +12,8 @@ using namespace DirectX;
class Console; class Console;
namespace DirectX { namespace DirectX
{
class SpriteBatch; class SpriteBatch;
class SpriteFont; class SpriteFont;
} }
@ -20,32 +21,32 @@ namespace DirectX {
class Renderer : public BaseRenderer, public IRenderingDevice class Renderer : public BaseRenderer, public IRenderingDevice
{ {
private: private:
HWND _hWnd = nullptr; HWND _hWnd = nullptr;
ID3D11Device* _pd3dDevice = nullptr; ID3D11Device* _pd3dDevice = nullptr;
ID3D11DeviceContext* _pDeviceContext = nullptr; ID3D11DeviceContext* _pDeviceContext = nullptr;
IDXGISwapChain* _pSwapChain = nullptr; IDXGISwapChain* _pSwapChain = nullptr;
ID3D11RenderTargetView* _pRenderTargetView = nullptr; ID3D11RenderTargetView* _pRenderTargetView = nullptr;
ID3D11DepthStencilState* _pDepthDisabledStencilState = nullptr; ID3D11DepthStencilState* _pDepthDisabledStencilState = nullptr;
ID3D11BlendState* _pAlphaEnableBlendingState = nullptr; ID3D11BlendState* _pAlphaEnableBlendingState = nullptr;
ID3D11SamplerState* _samplerState = nullptr; ID3D11SamplerState* _samplerState = nullptr;
atomic<bool> _needFlip = false; atomic<bool> _needFlip = false;
uint8_t* _textureBuffer[2] = { nullptr, nullptr }; uint8_t* _textureBuffer[2] = {nullptr, nullptr};
ID3D11Texture2D* _pTexture = nullptr; ID3D11Texture2D* _pTexture = nullptr;
ID3D11ShaderResourceView* _pTextureSrv = nullptr; ID3D11ShaderResourceView* _pTextureSrv = nullptr;
ID3D11Texture2D* _overlayTexture = nullptr; ID3D11Texture2D* _overlayTexture = nullptr;
ID3D11ShaderResourceView* _pOverlaySrv = nullptr; ID3D11ShaderResourceView* _pOverlaySrv = nullptr;
bool _frameChanged = true; bool _frameChanged = true;
SimpleLock _frameLock; SimpleLock _frameLock;
SimpleLock _textureLock; SimpleLock _textureLock;
bool _useBilinearInterpolation = false; bool _useBilinearInterpolation = false;
unique_ptr<SpriteFont> _font; unique_ptr<SpriteFont> _font;
unique_ptr<SpriteFont> _largeFont; unique_ptr<SpriteFont> _largeFont;
unique_ptr<SpriteBatch> _spriteBatch; unique_ptr<SpriteBatch> _spriteBatch;
@ -79,7 +80,8 @@ private:
void DrawPauseScreen(); void DrawPauseScreen();
void DrawString(string message, float x, float y, DirectX::FXMVECTOR color, float scale, SpriteFont* font = nullptr); void DrawString(string message, float x, float y, DirectX::FXMVECTOR color, float scale, SpriteFont* font = nullptr);
void DrawString(std::wstring message, float x, float y, DirectX::FXMVECTOR color, float scale, SpriteFont* font = nullptr); void DrawString(std::wstring message, float x, float y, DirectX::FXMVECTOR color, float scale,
SpriteFont* font = nullptr);
void DrawString(std::wstring message, int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t opacity); void DrawString(std::wstring message, int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t opacity);
float MeasureString(std::wstring text); float MeasureString(std::wstring text);
@ -100,5 +102,5 @@ public:
void Reset(); void Reset();
void Render(); void Render();
void UpdateFrame(void *frameBuffer, uint32_t width, uint32_t height); void UpdateFrame(void* frameBuffer, uint32_t width, uint32_t height);
}; };

View file

@ -15,16 +15,20 @@ SoundManager::SoundManager(shared_ptr<Console> console, HWND hwnd)
memset(&_audioDeviceID, 0, sizeof(_audioDeviceID)); memset(&_audioDeviceID, 0, sizeof(_audioDeviceID));
if(InitializeDirectSound(44100, true)) { if (InitializeDirectSound(44100, true))
{
_console->GetSoundMixer()->RegisterAudioDevice(this); _console->GetSoundMixer()->RegisterAudioDevice(this);
} else { }
else
{
MessageManager::DisplayMessage("Error", "CouldNotInitializeAudioSystem"); MessageManager::DisplayMessage("Error", "CouldNotInitializeAudioSystem");
} }
} }
SoundManager::~SoundManager() SoundManager::~SoundManager()
{ {
if(_console && _console->GetSoundMixer()) { if (_console && _console->GetSoundMixer())
{
_console->GetSoundMixer()->RegisterAudioDevice(nullptr); _console->GetSoundMixer()->RegisterAudioDevice(nullptr);
} }
Release(); Release();
@ -32,13 +36,16 @@ SoundManager::~SoundManager()
bool CALLBACK SoundManager::DirectSoundEnumProc(LPGUID lpGUID, LPCWSTR lpszDesc, LPCSTR lpszDrvName, LPVOID lpContext) bool CALLBACK SoundManager::DirectSoundEnumProc(LPGUID lpGUID, LPCWSTR lpszDesc, LPCSTR lpszDrvName, LPVOID lpContext)
{ {
vector<SoundDeviceInfo> *devices = (vector<SoundDeviceInfo>*)lpContext; vector<SoundDeviceInfo>* devices = (vector<SoundDeviceInfo>*)lpContext;
SoundDeviceInfo deviceInfo; SoundDeviceInfo deviceInfo;
deviceInfo.description = utf8::utf8::encode(lpszDesc); deviceInfo.description = utf8::utf8::encode(lpszDesc);
if(lpGUID != nullptr) { if (lpGUID != nullptr)
{
memcpy((void*)&deviceInfo.guid, lpGUID, 16); memcpy((void*)&deviceInfo.guid, lpGUID, 16);
} else { }
else
{
memset((void*)&deviceInfo.guid, 0, 16); memset((void*)&deviceInfo.guid, 0, 16);
} }
devices->push_back(deviceInfo); devices->push_back(deviceInfo);
@ -56,7 +63,8 @@ vector<SoundDeviceInfo> SoundManager::GetAvailableDeviceInfo()
string SoundManager::GetAvailableDevices() string SoundManager::GetAvailableDevices()
{ {
string deviceString; string deviceString;
for(SoundDeviceInfo device : GetAvailableDeviceInfo()) { for (SoundDeviceInfo device : GetAvailableDeviceInfo())
{
deviceString += device.description + "||"s; deviceString += device.description + "||"s;
} }
return deviceString; return deviceString;
@ -64,11 +72,15 @@ string SoundManager::GetAvailableDevices()
void SoundManager::SetAudioDevice(string deviceName) void SoundManager::SetAudioDevice(string deviceName)
{ {
if(_audioDeviceName != deviceName) { if (_audioDeviceName != deviceName)
for(SoundDeviceInfo device : GetAvailableDeviceInfo()) { {
if(device.description.compare(deviceName) == 0) { for (SoundDeviceInfo device : GetAvailableDeviceInfo())
{
if (device.description.compare(deviceName) == 0)
{
_audioDeviceName = deviceName; _audioDeviceName = deviceName;
if(memcmp(&_audioDeviceID, &device.guid, 16) != 0) { if (memcmp(&_audioDeviceID, &device.guid, 16) != 0)
{
memcpy(&_audioDeviceID, &device.guid, 16); memcpy(&_audioDeviceID, &device.guid, 16);
_needReset = true; _needReset = true;
} }
@ -86,14 +98,16 @@ bool SoundManager::InitializeDirectSound(uint32_t sampleRate, bool isStereo)
// Initialize the direct sound interface pointer for the default sound device. // Initialize the direct sound interface pointer for the default sound device.
result = DirectSoundCreate8(&_audioDeviceID, &_directSound, NULL); result = DirectSoundCreate8(&_audioDeviceID, &_directSound, NULL);
if(FAILED(result)) { if (FAILED(result))
{
MessageManager::Log("[Audio] Failed to create direct sound device."); MessageManager::Log("[Audio] Failed to create direct sound device.");
return false; return false;
} }
// Set the cooperative level to priority so the format of the primary sound buffer can be modified. // Set the cooperative level to priority so the format of the primary sound buffer can be modified.
result = _directSound->SetCooperativeLevel(_hWnd, DSSCL_PRIORITY); result = _directSound->SetCooperativeLevel(_hWnd, DSSCL_PRIORITY);
if(FAILED(result)) { if (FAILED(result))
{
MessageManager::Log("[Audio] Failed to set cooperative level."); MessageManager::Log("[Audio] Failed to set cooperative level.");
return false; return false;
} }
@ -108,7 +122,8 @@ bool SoundManager::InitializeDirectSound(uint32_t sampleRate, bool isStereo)
// Get control of the primary sound buffer on the default sound device. // Get control of the primary sound buffer on the default sound device.
result = _directSound->CreateSoundBuffer(&bufferDesc, &_primaryBuffer, NULL); result = _directSound->CreateSoundBuffer(&bufferDesc, &_primaryBuffer, NULL);
if(FAILED(result)) { if (FAILED(result))
{
MessageManager::Log("[Audio] Failed to create primary sound buffer."); MessageManager::Log("[Audio] Failed to create primary sound buffer.");
return false; return false;
} }
@ -127,7 +142,8 @@ bool SoundManager::InitializeDirectSound(uint32_t sampleRate, bool isStereo)
// Set the primary buffer to be the wave format specified. // Set the primary buffer to be the wave format specified.
result = _primaryBuffer->SetFormat(&waveFormat); result = _primaryBuffer->SetFormat(&waveFormat);
if(FAILED(result)) { if (FAILED(result))
{
MessageManager::Log("[Audio] Failed to set the sound format."); MessageManager::Log("[Audio] Failed to set the sound format.");
return false; return false;
} }
@ -138,7 +154,8 @@ bool SoundManager::InitializeDirectSound(uint32_t sampleRate, bool isStereo)
// Set the buffer description of the secondary sound buffer that the wave file will be loaded onto. // Set the buffer description of the secondary sound buffer that the wave file will be loaded onto.
bufferDesc.dwSize = sizeof(DSBUFFERDESC); bufferDesc.dwSize = sizeof(DSBUFFERDESC);
bufferDesc.dwFlags = DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS | DSBCAPS_LOCSOFTWARE | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; bufferDesc.dwFlags = DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS |
DSBCAPS_LOCSOFTWARE | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY;
bufferDesc.dwBufferBytes = _bufferSize; bufferDesc.dwBufferBytes = _bufferSize;
bufferDesc.dwReserved = 0; bufferDesc.dwReserved = 0;
bufferDesc.lpwfxFormat = &waveFormat; bufferDesc.lpwfxFormat = &waveFormat;
@ -147,21 +164,24 @@ bool SoundManager::InitializeDirectSound(uint32_t sampleRate, bool isStereo)
// Create a temporary sound buffer with the specific buffer settings. // Create a temporary sound buffer with the specific buffer settings.
IDirectSoundBuffer* tempBuffer; IDirectSoundBuffer* tempBuffer;
result = _directSound->CreateSoundBuffer(&bufferDesc, &tempBuffer, NULL); result = _directSound->CreateSoundBuffer(&bufferDesc, &tempBuffer, NULL);
if(FAILED(result)) { if (FAILED(result))
{
MessageManager::Log("[Audio] Failed to create temporary sound buffer."); MessageManager::Log("[Audio] Failed to create temporary sound buffer.");
return false; return false;
} }
// Test the buffer format against the direct sound 8 interface and create the secondary buffer. // Test the buffer format against the direct sound 8 interface and create the secondary buffer.
result = tempBuffer->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&_secondaryBuffer); result = tempBuffer->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&_secondaryBuffer);
if(FAILED(result)) { if (FAILED(result))
{
MessageManager::Log("[Audio] Failed to obtain secondary sound buffer."); MessageManager::Log("[Audio] Failed to obtain secondary sound buffer.");
return false; return false;
} }
// Set volume of the buffer to 100%. // Set volume of the buffer to 100%.
result = _secondaryBuffer->SetVolume(DSBVOLUME_MAX); result = _secondaryBuffer->SetVolume(DSBVOLUME_MAX);
if(FAILED(result)) { if (FAILED(result))
{
MessageManager::Log("[Audio] Failed to set volume of the secondary sound buffer."); MessageManager::Log("[Audio] Failed to set volume of the secondary sound buffer.");
return false; return false;
} }
@ -180,17 +200,20 @@ void SoundManager::Release()
_needReset = false; _needReset = false;
_lastWriteOffset = 0; _lastWriteOffset = 0;
if(_secondaryBuffer) { if (_secondaryBuffer)
{
_secondaryBuffer->Release(); _secondaryBuffer->Release();
_secondaryBuffer = nullptr; _secondaryBuffer = nullptr;
} }
if(_primaryBuffer) { if (_primaryBuffer)
{
_primaryBuffer->Release(); _primaryBuffer->Release();
_primaryBuffer = nullptr; _primaryBuffer = nullptr;
} }
if(_directSound) { if (_directSound)
{
_directSound->Release(); _directSound->Release();
_directSound = nullptr; _directSound = nullptr;
} }
@ -208,18 +231,20 @@ void SoundManager::ClearSecondaryBuffer()
_lastWriteOffset = 0; _lastWriteOffset = 0;
} }
void SoundManager::CopyToSecondaryBuffer(uint8_t *data, uint32_t size) void SoundManager::CopyToSecondaryBuffer(uint8_t* data, uint32_t size)
{ {
uint8_t* bufferPtrA; uint8_t* bufferPtrA;
uint8_t* bufferPtrB; uint8_t* bufferPtrB;
DWORD bufferASize; DWORD bufferASize;
DWORD bufferBSize; DWORD bufferBSize;
_secondaryBuffer->Lock(_lastWriteOffset, size, (void**)&bufferPtrA, (DWORD*)&bufferASize, (void**)&bufferPtrB, (DWORD*)&bufferBSize, 0); _secondaryBuffer->Lock(_lastWriteOffset, size, (void**)&bufferPtrA, (DWORD*)&bufferASize, (void**)&bufferPtrB,
(DWORD*)&bufferBSize, 0);
_lastWriteOffset = (_lastWriteOffset + size) % _bufferSize; _lastWriteOffset = (_lastWriteOffset + size) % _bufferSize;
memcpy(bufferPtrA, data, bufferASize); memcpy(bufferPtrA, data, bufferASize);
if(bufferPtrB && bufferBSize > 0) { if (bufferPtrB && bufferBSize > 0)
{
memcpy(bufferPtrB, data + bufferASize, bufferBSize); memcpy(bufferPtrB, data + bufferASize, bufferBSize);
} }
@ -228,7 +253,8 @@ void SoundManager::CopyToSecondaryBuffer(uint8_t *data, uint32_t size)
void SoundManager::Pause() void SoundManager::Pause()
{ {
if(_secondaryBuffer) { if (_secondaryBuffer)
{
_secondaryBuffer->Stop(); _secondaryBuffer->Stop();
} }
_playing = false; _playing = false;
@ -236,7 +262,8 @@ void SoundManager::Pause()
void SoundManager::Stop() void SoundManager::Stop()
{ {
if(_secondaryBuffer) { if (_secondaryBuffer)
{
_secondaryBuffer->Stop(); _secondaryBuffer->Stop();
ClearSecondaryBuffer(); ClearSecondaryBuffer();
} }
@ -247,7 +274,8 @@ void SoundManager::Stop()
void SoundManager::Play() void SoundManager::Play()
{ {
if(_secondaryBuffer) { if (_secondaryBuffer)
{
_secondaryBuffer->Play(0, 0, DSBPLAY_LOOPING); _secondaryBuffer->Play(0, 0, DSBPLAY_LOOPING);
_playing = true; _playing = true;
} }
@ -256,9 +284,12 @@ void SoundManager::Play()
void SoundManager::ValidateWriteCursor(DWORD safeWriteCursor) void SoundManager::ValidateWriteCursor(DWORD safeWriteCursor)
{ {
int32_t writeGap = _lastWriteOffset - safeWriteCursor; int32_t writeGap = _lastWriteOffset - safeWriteCursor;
if(writeGap < -10000) { if (writeGap < -10000)
{
writeGap += _bufferSize; writeGap += _bufferSize;
} else if(writeGap < 0) { }
else if (writeGap < 0)
{
_bufferUnderrunEventCount++; _bufferUnderrunEventCount++;
_lastWriteOffset = safeWriteCursor; _lastWriteOffset = safeWriteCursor;
} }
@ -273,7 +304,8 @@ void SoundManager::ProcessEndOfFrame()
uint32_t emulationSpeed = _console->GetSettings()->GetEmulationSpeed(); uint32_t emulationSpeed = _console->GetSettings()->GetEmulationSpeed();
uint32_t targetRate = _sampleRate; uint32_t targetRate = _sampleRate;
if(emulationSpeed > 0 && emulationSpeed < 100) { if (emulationSpeed > 0 && emulationSpeed < 100)
{
//Slow down playback when playing at less than 100% //Slow down playback when playing at less than 100%
targetRate = (uint32_t)(targetRate * ((double)emulationSpeed / 100.0)); targetRate = (uint32_t)(targetRate * ((double)emulationSpeed / 100.0));
} }
@ -284,17 +316,20 @@ void SoundManager::ProcessEndOfFrame()
AudioConfig cfg = _console->GetSettings()->GetAudioConfig(); AudioConfig cfg = _console->GetSettings()->GetAudioConfig();
SetAudioDevice(cfg.AudioDevice); SetAudioDevice(cfg.AudioDevice);
if(_averageLatency > 0 && emulationSpeed <= 100 && emulationSpeed > 0 && std::abs(_averageLatency - cfg.AudioLatency) > 50) { if (_averageLatency > 0 && emulationSpeed <= 100 && emulationSpeed > 0 && std::abs(
_averageLatency - cfg.AudioLatency) > 50)
{
//Latency is way off (over 50ms gap), stop audio & start again //Latency is way off (over 50ms gap), stop audio & start again
Stop(); Stop();
} }
} }
void SoundManager::PlayBuffer(int16_t *soundBuffer, uint32_t sampleCount, uint32_t sampleRate, bool isStereo) void SoundManager::PlayBuffer(int16_t* soundBuffer, uint32_t sampleCount, uint32_t sampleRate, bool isStereo)
{ {
uint32_t bytesPerSample = 2 * (isStereo ? 2 : 1); uint32_t bytesPerSample = 2 * (isStereo ? 2 : 1);
uint32_t latency = _console->GetSettings()->GetAudioConfig().AudioLatency; uint32_t latency = _console->GetSettings()->GetAudioConfig().AudioLatency;
if(_sampleRate != sampleRate || _isStereo != isStereo || _needReset || latency != _previousLatency) { if (_sampleRate != sampleRate || _isStereo != isStereo || _needReset || latency != _previousLatency)
{
_previousLatency = latency; _previousLatency = latency;
Release(); Release();
InitializeDirectSound(sampleRate, isStereo); InitializeDirectSound(sampleRate, isStereo);
@ -308,9 +343,11 @@ void SoundManager::PlayBuffer(int16_t *soundBuffer, uint32_t sampleCount, uint32
uint32_t soundBufferSize = sampleCount * bytesPerSample; uint32_t soundBufferSize = sampleCount * bytesPerSample;
CopyToSecondaryBuffer((uint8_t*)soundBuffer, soundBufferSize); CopyToSecondaryBuffer((uint8_t*)soundBuffer, soundBufferSize);
if(!_playing) { if (!_playing)
{
DWORD byteLatency = (int32_t)((float)(sampleRate * latency) / 1000.0f * bytesPerSample); DWORD byteLatency = (int32_t)((float)(sampleRate * latency) / 1000.0f * bytesPerSample);
if(_lastWriteOffset >= byteLatency / 2) { if (_lastWriteOffset >= byteLatency / 2)
{
Play(); Play();
} }
} }

View file

@ -19,7 +19,7 @@ public:
void Release(); void Release();
void ProcessEndOfFrame(); void ProcessEndOfFrame();
void PlayBuffer(int16_t *soundBuffer, uint32_t bufferSize, uint32_t sampleRate, bool isStereo); void PlayBuffer(int16_t* soundBuffer, uint32_t bufferSize, uint32_t sampleRate, bool isStereo);
void Play(); void Play();
void Pause(); void Pause();
void Stop(); void Stop();
@ -32,7 +32,7 @@ private:
static bool CALLBACK DirectSoundEnumProc(LPGUID lpGUID, LPCWSTR lpszDesc, LPCSTR lpszDrvName, LPVOID lpContext); static bool CALLBACK DirectSoundEnumProc(LPGUID lpGUID, LPCWSTR lpszDesc, LPCSTR lpszDrvName, LPVOID lpContext);
bool InitializeDirectSound(uint32_t sampleRate, bool isStereo); bool InitializeDirectSound(uint32_t sampleRate, bool isStereo);
void ClearSecondaryBuffer(); void ClearSecondaryBuffer();
void CopyToSecondaryBuffer(uint8_t *data, uint32_t size); void CopyToSecondaryBuffer(uint8_t* data, uint32_t size);
void ValidateWriteCursor(DWORD safeWriteCursor); void ValidateWriteCursor(DWORD safeWriteCursor);
private: private:

View file

@ -4,199 +4,207 @@
static vector<KeyDefinition> _keyDefinitions = { static vector<KeyDefinition> _keyDefinitions = {
//{ "VK_LBUTTON", 0x01, "Left mouse button", "" }, //{ "VK_LBUTTON", 0x01, "Left mouse button", "" },
//{ "VK_RBUTTON", 0x02, "Right mouse button", "" }, //{ "VK_RBUTTON", 0x02, "Right mouse button", "" },
{ "VK_CANCEL", 0x03, "Control-break processing", "" }, {"VK_CANCEL", 0x03, "Control-break processing", ""},
//{ "VK_MBUTTON", 0x04, "Middle mouse button (three-button mouse)", "" }, //{ "VK_MBUTTON", 0x04, "Middle mouse button (three-button mouse)", "" },
//{ "VK_XBUTTON1", 0x05, "X1 mouse button", "" }, //{ "VK_XBUTTON1", 0x05, "X1 mouse button", "" },
//{ "VK_XBUTTON2", 0x06, "X2 mouse button", "" }, //{ "VK_XBUTTON2", 0x06, "X2 mouse button", "" },
{ "-", 0x07, "Undefined", "" }, {"-", 0x07, "Undefined", ""},
{ "VK_BACK", 0x08, "Backspace", "" }, {"VK_BACK", 0x08, "Backspace", ""},
{ "VK_TAB", 0x09, "Tab", "" }, {"VK_TAB", 0x09, "Tab", ""},
//{ "-", 0x0A - 0B, "Reserved", "" }, //{ "-", 0x0A - 0B, "Reserved", "" },
{ "VK_CLEAR", 0x0C, "Numpad 5", "" }, {"VK_CLEAR", 0x0C, "Numpad 5", ""},
{ "VK_RETURN", 0x0D, "Enter", "Numpad Enter" }, {"VK_RETURN", 0x0D, "Enter", "Numpad Enter"},
//{ "-", 0x0E - 0F, "Undefined", "" }, //{ "-", 0x0E - 0F, "Undefined", "" },
{ "VK_SHIFT", 0x10, "Shift", "" }, {"VK_SHIFT", 0x10, "Shift", ""},
{ "VK_CONTROL", 0x11, "Ctrl", "" }, {"VK_CONTROL", 0x11, "Ctrl", ""},
{ "VK_MENU", 0x12, "Alt", "" }, {"VK_MENU", 0x12, "Alt", ""},
{ "VK_PAUSE", 0x13, "Pause", "" }, {"VK_PAUSE", 0x13, "Pause", ""},
{ "VK_CAPITAL", 0x14, "Caps Lock", "" }, {"VK_CAPITAL", 0x14, "Caps Lock", ""},
{ "VK_KANA", 0x15, "IME Kana mode", "" }, {"VK_KANA", 0x15, "IME Kana mode", ""},
{ "VK_HANGUEL", 0x15, "IME Hanguel mode", "" }, {"VK_HANGUEL", 0x15, "IME Hanguel mode", ""},
{ "VK_HANGUL", 0x15, "IME Hangul mode", "" }, {"VK_HANGUL", 0x15, "IME Hangul mode", ""},
//{ "-", 0x16, "Undefined", "" }, //{ "-", 0x16, "Undefined", "" },
{ "VK_JUNJA", 0x17, "IME Junja mode", "" }, {"VK_JUNJA", 0x17, "IME Junja mode", ""},
{ "VK_FINAL", 0x18, "IME final mode", "" }, {"VK_FINAL", 0x18, "IME final mode", ""},
{ "VK_HANJA", 0x19, "IME Hanja mode", "" }, {"VK_HANJA", 0x19, "IME Hanja mode", ""},
{ "VK_KANJI", 0x19, "IME Kanji mode", "" }, {"VK_KANJI", 0x19, "IME Kanji mode", ""},
//{ "-", 0x1A, "Undefined", "" }, //{ "-", 0x1A, "Undefined", "" },
{ "VK_ESCAPE", 0x1B, "Esc", "" }, {"VK_ESCAPE", 0x1B, "Esc", ""},
{ "VK_CONVERT", 0x1C, "IME convert", "" }, {"VK_CONVERT", 0x1C, "IME convert", ""},
{ "VK_NONCONVERT", 0x1D, "IME nonconvert", "" }, {"VK_NONCONVERT", 0x1D, "IME nonconvert", ""},
{ "VK_ACCEPT", 0x1E, "IME accept", "" }, {"VK_ACCEPT", 0x1E, "IME accept", ""},
{ "VK_MODECHANGE", 0x1F, "IME mode change request", "" }, {"VK_MODECHANGE", 0x1F, "IME mode change request", ""},
{ "VK_SPACE", 0x20, "Spacebar", "" }, {"VK_SPACE", 0x20, "Spacebar", ""},
{ "VK_PRIOR", 0x21, "Numpad 9", "Page Up" }, {"VK_PRIOR", 0x21, "Numpad 9", "Page Up"},
{ "VK_NEXT", 0x22, "Numpad 3", "Page Down" }, {"VK_NEXT", 0x22, "Numpad 3", "Page Down"},
{ "VK_END", 0x23, "Numpad 1", "End" }, {"VK_END", 0x23, "Numpad 1", "End"},
{ "VK_HOME", 0x24, "Numpad 7", "Home" }, {"VK_HOME", 0x24, "Numpad 7", "Home"},
{ "VK_LEFT", 0x25, "Numpad 4", "Left Arrow" }, {"VK_LEFT", 0x25, "Numpad 4", "Left Arrow"},
{ "VK_UP", 0x26, "Numpad 8", "Up Arrow" }, {"VK_UP", 0x26, "Numpad 8", "Up Arrow"},
{ "VK_RIGHT", 0x27, "Numpad 6", "Right Arrow" }, {"VK_RIGHT", 0x27, "Numpad 6", "Right Arrow"},
{ "VK_DOWN", 0x28, "Numpad 2", "Down Arrow" }, {"VK_DOWN", 0x28, "Numpad 2", "Down Arrow"},
{ "VK_SELECT", 0x29, "Select", "" }, {"VK_SELECT", 0x29, "Select", ""},
{ "VK_PRINT", 0x2A, "Print", "" }, {"VK_PRINT", 0x2A, "Print", ""},
{ "VK_EXECUTE", 0x2B, "Execute", "" }, {"VK_EXECUTE", 0x2B, "Execute", ""},
{ "VK_SNAPSHOT", 0x2C, "Print Screen", "" }, {"VK_SNAPSHOT", 0x2C, "Print Screen", ""},
{ "VK_INSERT", 0x2D, "Numpad 0", "Insert" }, {"VK_INSERT", 0x2D, "Numpad 0", "Insert"},
{ "VK_DELETE", 0x2E, "Numpad .", "Delete" }, {"VK_DELETE", 0x2E, "Numpad .", "Delete"},
{ "VK_HELP", 0x2F, "Help", "" }, {"VK_HELP", 0x2F, "Help", ""},
{ "0", 0x30, "0", "" }, {"0", 0x30, "0", ""},
{ "1", 0x31, "1", "" }, {"1", 0x31, "1", ""},
{ "2", 0x32, "2", "" }, {"2", 0x32, "2", ""},
{ "3", 0x33, "3", "" }, {"3", 0x33, "3", ""},
{ "4", 0x34, "4", "" }, {"4", 0x34, "4", ""},
{ "5", 0x35, "5", "" }, {"5", 0x35, "5", ""},
{ "6", 0x36, "6", "" }, {"6", 0x36, "6", ""},
{ "7", 0x37, "7", "" }, {"7", 0x37, "7", ""},
{ "8", 0x38, "8", "" }, {"8", 0x38, "8", ""},
{ "9", 0x39, "9", "" }, {"9", 0x39, "9", ""},
//{ "undefined", 0x3A - 40, "undefined", "" }, //{ "undefined", 0x3A - 40, "undefined", "" },
{ "A", 0x41, "A", "" }, {"A", 0x41, "A", ""},
{ "B", 0x42, "B", "" }, {"B", 0x42, "B", ""},
{ "C", 0x43, "C", "" }, {"C", 0x43, "C", ""},
{ "D", 0x44, "D", "" }, {"D", 0x44, "D", ""},
{ "E", 0x45, "E", "" }, {"E", 0x45, "E", ""},
{ "F", 0x46, "F", "" }, {"F", 0x46, "F", ""},
{ "G", 0x47, "G", "" }, {"G", 0x47, "G", ""},
{ "H", 0x48, "H", "" }, {"H", 0x48, "H", ""},
{ "I", 0x49, "I", "" }, {"I", 0x49, "I", ""},
{ "J", 0x4A, "J", "" }, {"J", 0x4A, "J", ""},
{ "K", 0x4B, "K", "" }, {"K", 0x4B, "K", ""},
{ "L", 0x4C, "L", "" }, {"L", 0x4C, "L", ""},
{ "M", 0x4D, "M", "" }, {"M", 0x4D, "M", ""},
{ "N", 0x4E, "N", "" }, {"N", 0x4E, "N", ""},
{ "O", 0x4F, "O", "" }, {"O", 0x4F, "O", ""},
{ "P", 0x50, "P", "" }, {"P", 0x50, "P", ""},
{ "Q", 0x51, "Q", "" }, {"Q", 0x51, "Q", ""},
{ "R", 0x52, "R", "" }, {"R", 0x52, "R", ""},
{ "S", 0x53, "S", "" }, {"S", 0x53, "S", ""},
{ "T", 0x54, "T", "" }, {"T", 0x54, "T", ""},
{ "U", 0x55, "U", "" }, {"U", 0x55, "U", ""},
{ "V", 0x56, "V", "" }, {"V", 0x56, "V", ""},
{ "W", 0x57, "W", "" }, {"W", 0x57, "W", ""},
{ "X", 0x58, "X", "" }, {"X", 0x58, "X", ""},
{ "Y", 0x59, "Y", "" }, {"Y", 0x59, "Y", ""},
{ "Z", 0x5A, "Z", "" }, {"Z", 0x5A, "Z", ""},
{ "VK_LWIN", 0x5B, "Left Windows", "" }, {"VK_LWIN", 0x5B, "Left Windows", ""},
{ "VK_RWIN", 0x5C, "Right Windows", "" }, {"VK_RWIN", 0x5C, "Right Windows", ""},
{ "VK_APPS", 0x5D, "Applications Key", "" }, {"VK_APPS", 0x5D, "Applications Key", ""},
//{ "-", 0x5E, "Reserved", "" }, //{ "-", 0x5E, "Reserved", "" },
{ "VK_SLEEP", 0x5F, "Computer Sleep", "" }, {"VK_SLEEP", 0x5F, "Computer Sleep", ""},
{ "VK_NUMPAD0", 0x60, "Keypad 0", "" }, {"VK_NUMPAD0", 0x60, "Keypad 0", ""},
{ "VK_NUMPAD1", 0x61, "Keypad 1", "" }, {"VK_NUMPAD1", 0x61, "Keypad 1", ""},
{ "VK_NUMPAD2", 0x62, "Keypad 2", "" }, {"VK_NUMPAD2", 0x62, "Keypad 2", ""},
{ "VK_NUMPAD3", 0x63, "Keypad 3", "" }, {"VK_NUMPAD3", 0x63, "Keypad 3", ""},
{ "VK_NUMPAD4", 0x64, "Keypad 4", "" }, {"VK_NUMPAD4", 0x64, "Keypad 4", ""},
{ "VK_NUMPAD5", 0x65, "Keypad 5", "" }, {"VK_NUMPAD5", 0x65, "Keypad 5", ""},
{ "VK_NUMPAD6", 0x66, "Keypad 6", "" }, {"VK_NUMPAD6", 0x66, "Keypad 6", ""},
{ "VK_NUMPAD7", 0x67, "Keypad 7", "" }, {"VK_NUMPAD7", 0x67, "Keypad 7", ""},
{ "VK_NUMPAD8", 0x68, "Keypad 8", "" }, {"VK_NUMPAD8", 0x68, "Keypad 8", ""},
{ "VK_NUMPAD9", 0x69, "Keypad 9", "" }, {"VK_NUMPAD9", 0x69, "Keypad 9", ""},
{ "VK_MULTIPLY", 0x6A, "Numpad *", "" }, {"VK_MULTIPLY", 0x6A, "Numpad *", ""},
{ "VK_ADD", 0x6B, "Numpad +", "" }, {"VK_ADD", 0x6B, "Numpad +", ""},
{ "VK_SEPARATOR", 0x6C, "Separator", "" }, {"VK_SEPARATOR", 0x6C, "Separator", ""},
{ "VK_SUBTRACT", 0x6D, "Numpad -", "" }, {"VK_SUBTRACT", 0x6D, "Numpad -", ""},
{ "VK_DECIMAL", 0x6E, "Decimal", "" }, {"VK_DECIMAL", 0x6E, "Decimal", ""},
{ "VK_DIVIDE", 0x6F, "Numpad /", "" }, {"VK_DIVIDE", 0x6F, "Numpad /", ""},
{ "VK_F1", 0x70, "F1", "" }, {"VK_F1", 0x70, "F1", ""},
{ "VK_F2", 0x71, "F2", "" }, {"VK_F2", 0x71, "F2", ""},
{ "VK_F3", 0x72, "F3", "" }, {"VK_F3", 0x72, "F3", ""},
{ "VK_F4", 0x73, "F4", "" }, {"VK_F4", 0x73, "F4", ""},
{ "VK_F5", 0x74, "F5", "" }, {"VK_F5", 0x74, "F5", ""},
{ "VK_F6", 0x75, "F6", "" }, {"VK_F6", 0x75, "F6", ""},
{ "VK_F7", 0x76, "F7", "" }, {"VK_F7", 0x76, "F7", ""},
{ "VK_F8", 0x77, "F8", "" }, {"VK_F8", 0x77, "F8", ""},
{ "VK_F9", 0x78, "F9", "" }, {"VK_F9", 0x78, "F9", ""},
{ "VK_F10", 0x79, "F10", "" }, {"VK_F10", 0x79, "F10", ""},
{ "VK_F11", 0x7A, "F11", "" }, {"VK_F11", 0x7A, "F11", ""},
{ "VK_F12", 0x7B, "F12", "" }, {"VK_F12", 0x7B, "F12", ""},
{ "VK_F13", 0x7C, "F13", "" }, {"VK_F13", 0x7C, "F13", ""},
{ "VK_F14", 0x7D, "F14", "" }, {"VK_F14", 0x7D, "F14", ""},
{ "VK_F15", 0x7E, "F15", "" }, {"VK_F15", 0x7E, "F15", ""},
{ "VK_F16", 0x7F, "F16", "" }, {"VK_F16", 0x7F, "F16", ""},
{ "VK_F17", 0x80, "F17", "" }, {"VK_F17", 0x80, "F17", ""},
{ "VK_F18", 0x81, "F18", "" }, {"VK_F18", 0x81, "F18", ""},
{ "VK_F19", 0x82, "F19", "" }, {"VK_F19", 0x82, "F19", ""},
{ "VK_F20", 0x83, "F20", "" }, {"VK_F20", 0x83, "F20", ""},
{ "VK_F21", 0x84, "F21", "" }, {"VK_F21", 0x84, "F21", ""},
{ "VK_F22", 0x85, "F22", "" }, {"VK_F22", 0x85, "F22", ""},
{ "VK_F23", 0x86, "F23", "" }, {"VK_F23", 0x86, "F23", ""},
{ "VK_F24", 0x87, "F24", "" }, {"VK_F24", 0x87, "F24", ""},
//{ "-", 0x88 - 8F, "Unassigned", "" }, //{ "-", 0x88 - 8F, "Unassigned", "" },
{ "VK_NUMLOCK", 0x90, "Pause", "Num Lock" }, {"VK_NUMLOCK", 0x90, "Pause", "Num Lock"},
{ "VK_SCROLL", 0x91, "Scroll Lock", "" }, {"VK_SCROLL", 0x91, "Scroll Lock", ""},
//{"-", 0x92-96,"OEM specific"}, //{"-", 0x92-96,"OEM specific"},
//{ "-", 0x97 - 9F, "Unassigned", "" }, //{ "-", 0x97 - 9F, "Unassigned", "" },
{ "VK_LSHIFT", 0xA0, "Left Shift", "" }, {"VK_LSHIFT", 0xA0, "Left Shift", ""},
{ "VK_RSHIFT", 0xA1, "Right Shift", "" }, {"VK_RSHIFT", 0xA1, "Right Shift", ""},
{ "VK_LCONTROL", 0xA2, "Left Control", "" }, {"VK_LCONTROL", 0xA2, "Left Control", ""},
{ "VK_RCONTROL", 0xA3, "Right Control", "" }, {"VK_RCONTROL", 0xA3, "Right Control", ""},
{ "VK_LMENU", 0xA4, "Left Menu", "" }, {"VK_LMENU", 0xA4, "Left Menu", ""},
{ "VK_RMENU", 0xA5, "Right Menu", "" }, {"VK_RMENU", 0xA5, "Right Menu", ""},
{ "VK_BROWSER_BACK", 0xA6, "Browser Back", "" }, {"VK_BROWSER_BACK", 0xA6, "Browser Back", ""},
{ "VK_BROWSER_FORWARD", 0xA7, "Browser Forward", "" }, {"VK_BROWSER_FORWARD", 0xA7, "Browser Forward", ""},
{ "VK_BROWSER_REFRESH", 0xA8, "Browser Refresh", "" }, {"VK_BROWSER_REFRESH", 0xA8, "Browser Refresh", ""},
{ "VK_BROWSER_STOP", 0xA9, "Browser Stop", "" }, {"VK_BROWSER_STOP", 0xA9, "Browser Stop", ""},
{ "VK_BROWSER_SEARCH", 0xAA, "Browser Search", "" }, {"VK_BROWSER_SEARCH", 0xAA, "Browser Search", ""},
{ "VK_BROWSER_FAVORITES", 0xAB, "Browser Favorites", "" }, {"VK_BROWSER_FAVORITES", 0xAB, "Browser Favorites", ""},
{ "VK_BROWSER_HOME", 0xAC, "Browser Start and Home", "" }, {"VK_BROWSER_HOME", 0xAC, "Browser Start and Home", ""},
{ "VK_VOLUME_MUTE", 0xAD, "Volume Mute", "" }, {"VK_VOLUME_MUTE", 0xAD, "Volume Mute", ""},
{ "VK_VOLUME_DOWN", 0xAE, "Volume Down", "" }, {"VK_VOLUME_DOWN", 0xAE, "Volume Down", ""},
{ "VK_VOLUME_UP", 0xAF, "Volume Up", "" }, {"VK_VOLUME_UP", 0xAF, "Volume Up", ""},
{ "VK_MEDIA_NEXT_TRACK", 0xB0, "Next Track", "" }, {"VK_MEDIA_NEXT_TRACK", 0xB0, "Next Track", ""},
{ "VK_MEDIA_PREV_TRACK", 0xB1, "Previous Track", "" }, {"VK_MEDIA_PREV_TRACK", 0xB1, "Previous Track", ""},
{ "VK_MEDIA_STOP", 0xB2, "Stop Media", "" }, {"VK_MEDIA_STOP", 0xB2, "Stop Media", ""},
{ "VK_MEDIA_PLAY_PAUSE", 0xB3, "Play/Pause Media", "" }, {"VK_MEDIA_PLAY_PAUSE", 0xB3, "Play/Pause Media", ""},
{ "VK_LAUNCH_MAIL", 0xB4, "Start Mail", "" }, {"VK_LAUNCH_MAIL", 0xB4, "Start Mail", ""},
{ "VK_LAUNCH_MEDIA_SELECT", 0xB5, "Select Media", "" }, {"VK_LAUNCH_MEDIA_SELECT", 0xB5, "Select Media", ""},
{ "VK_LAUNCH_APP1", 0xB6, "Start Application 1", "" }, {"VK_LAUNCH_APP1", 0xB6, "Start Application 1", ""},
{ "VK_LAUNCH_APP2", 0xB7, "Start Application 2", "" }, {"VK_LAUNCH_APP2", 0xB7, "Start Application 2", ""},
//{ "-", 0xB8 - B9, "Reserved", "" }, //{ "-", 0xB8 - B9, "Reserved", "" },
{ "VK_OEM_1", 0xBA, ";", "" }, {"VK_OEM_1", 0xBA, ";", ""},
{ "VK_OEM_PLUS", 0xBB, "=", "" }, {"VK_OEM_PLUS", 0xBB, "=", ""},
{ "VK_OEM_COMMA", 0xBC, ",", "" }, {"VK_OEM_COMMA", 0xBC, ",", ""},
{ "VK_OEM_MINUS", 0xBD, "-", "" }, {"VK_OEM_MINUS", 0xBD, "-", ""},
{ "VK_OEM_PERIOD", 0xBE, ".", "" }, {"VK_OEM_PERIOD", 0xBE, ".", ""},
{ "VK_OEM_2", 0xBF, "/", "Numpad /" }, {"VK_OEM_2", 0xBF, "/", "Numpad /"},
{ "VK_OEM_3", 0xC0, "`", "" }, {"VK_OEM_3", 0xC0, "`", ""},
//{ "-", 0xC1 - D7, "Reserved", "" }, //{ "-", 0xC1 - D7, "Reserved", "" },
//{ "-", 0xD8 - DA, "Unassigned", "" }, //{ "-", 0xD8 - DA, "Unassigned", "" },
{ "VK_OEM_4", 0xDB, "[", "" }, {"VK_OEM_4", 0xDB, "[", ""},
{ "VK_OEM_5", 0xDC, "\\", "" }, {"VK_OEM_5", 0xDC, "\\", ""},
{ "VK_OEM_6", 0xDD, "]", "" }, {"VK_OEM_6", 0xDD, "]", ""},
{ "VK_OEM_7", 0xDE, "'", "" }, {"VK_OEM_7", 0xDE, "'", ""},
{ "VK_OEM_8", 0xDF, "Used for miscellaneous characters; it can vary by keyboard.", "" }, {"VK_OEM_8", 0xDF, "Used for miscellaneous characters; it can vary by keyboard.", ""},
//{ "-", 0xE0, "Reserved", "" }, //{ "-", 0xE0, "Reserved", "" },
//{ "-", 0xE1, "OEM specific", "" }, //{ "-", 0xE1, "OEM specific", "" },
{ "VK_OEM_102", 0xE2, "Pipe", "" }, {"VK_OEM_102", 0xE2, "Pipe", ""},
//{ "-", 0xE3 - E4, "OEM specific", "" }, //{ "-", 0xE3 - E4, "OEM specific", "" },
{ "VK_PROCESSKEY", 0xE5, "IME PROCESS", "" }, {"VK_PROCESSKEY", 0xE5, "IME PROCESS", ""},
//{ "-", 0xE6, "OEM specific", "" }, //{ "-", 0xE6, "OEM specific", "" },
{ "VK_PACKET", 0xE7, "Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP", "" }, {
"VK_PACKET", 0xE7,
"Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP",
""
},
//{ "-", 0xE8, "Unassigned", "" }, //{ "-", 0xE8, "Unassigned", "" },
// {"-",0xE6,"OEM specific"}, // {"-",0xE6,"OEM specific"},
{ "VK_PACKET", 0xE7, "Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP", "" }, {
"VK_PACKET", 0xE7,
"Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP",
""
},
// {"-",0xE8,"Unassigned"}, // {"-",0xE8,"Unassigned"},
//{ "-", 0xE9 - F5, "OEM specific", "" }, //{ "-", 0xE9 - F5, "OEM specific", "" },
{ "VK_ATTN", 0xF6, "Attn", "" }, {"VK_ATTN", 0xF6, "Attn", ""},
{ "VK_CRSEL", 0xF7, "CrSel", "" }, {"VK_CRSEL", 0xF7, "CrSel", ""},
{ "VK_EXSEL", 0xF8, "ExSel", "" }, {"VK_EXSEL", 0xF8, "ExSel", ""},
{ "VK_EREOF", 0xF9, "Erase EOF", "Menu" }, {"VK_EREOF", 0xF9, "Erase EOF", "Menu"},
{ "VK_PLAY", 0xFA, "Play", "" }, {"VK_PLAY", 0xFA, "Play", ""},
{ "VK_ZOOM", 0xFB, "Zoom", "" }, {"VK_ZOOM", 0xFB, "Zoom", ""},
{ "VK_NONAME", 0xFC, "Reserved", "" }, {"VK_NONAME", 0xFC, "Reserved", ""},
{ "VK_PA1", 0xFD, "PA1", "" }, {"VK_PA1", 0xFD, "PA1", ""},
{ "VK_OEM_CLEAR", 0xFE, "Clear", "" } {"VK_OEM_CLEAR", 0xFE, "Clear", ""}
}; };
WindowsKeyManager::WindowsKeyManager(shared_ptr<Console> console, HWND hWnd) WindowsKeyManager::WindowsKeyManager(shared_ptr<Console> console, HWND hWnd)
@ -207,31 +215,53 @@ WindowsKeyManager::WindowsKeyManager(shared_ptr<Console> console, HWND hWnd)
ResetKeyState(); ResetKeyState();
//Init XInput buttons //Init XInput buttons
vector<string> buttonNames = { "Up", "Down", "Left", "Right", "Start", "Back", "L3", "R3", "L1", "R1", "?", "?", "A", "B", "X", "Y", "L2", "R2", "RT Up", "RT Down", "RT Left", "RT Right", "LT Up", "LT Down", "LT Left", "LT Right" }; vector<string> buttonNames = {
for(int i = 0; i < 4; i++) { "Up", "Down", "Left", "Right", "Start", "Back", "L3", "R3", "L1", "R1", "?", "?", "A", "B", "X", "Y", "L2", "R2",
for(int j = 0; j < (int)buttonNames.size(); j++) { "RT Up", "RT Down", "RT Left", "RT Right", "LT Up", "LT Down", "LT Left", "LT Right"
_keyDefinitions.push_back({ "", (uint32_t)(0xFFFF + i * 0x100 + j + 1), "Pad" + std::to_string(i + 1) + " " + buttonNames[j] }); };
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < (int)buttonNames.size(); j++)
{
_keyDefinitions.push_back({
"", (uint32_t)(0xFFFF + i * 0x100 + j + 1), "Pad" + std::to_string(i + 1) + " " + buttonNames[j]
});
} }
} }
//Init DirectInput buttons //Init DirectInput buttons
vector<string> diButtonNames = { "Y+", "Y-", "X-", "X+", "Y2+", "Y2-", "X2-", "X2+", "Z+", "Z-", "Z2+", "Z2-", "DPad Up", "DPad Down", "DPad Right", "DPad Left" }; vector<string> diButtonNames = {
for(int i = 0; i < 16; i++) { "Y+", "Y-", "X-", "X+", "Y2+", "Y2-", "X2-", "X2+", "Z+", "Z-", "Z2+", "Z2-", "DPad Up", "DPad Down",
for(int j = 0; j < (int)diButtonNames.size(); j++) { "DPad Right", "DPad Left"
_keyDefinitions.push_back({ "", (uint32_t)(0x11000 + i * 0x100 + j), "Joy" + std::to_string(i + 1) + " " + diButtonNames[j] }); };
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < (int)diButtonNames.size(); j++)
{
_keyDefinitions.push_back({
"", (uint32_t)(0x11000 + i * 0x100 + j), "Joy" + std::to_string(i + 1) + " " + diButtonNames[j]
});
} }
for(int j = 0; j < 128; j++) { for (int j = 0; j < 128; j++)
_keyDefinitions.push_back({ "", (uint32_t)(0x11000 + i * 0x100 + j + 0x10), "Joy" + std::to_string(i + 1) + " But" + std::to_string(j+1)}); {
_keyDefinitions.push_back({
"", (uint32_t)(0x11000 + i * 0x100 + j + 0x10),
"Joy" + std::to_string(i + 1) + " But" + std::to_string(j + 1)
});
} }
} }
for(KeyDefinition& keyDef : _keyDefinitions) { for (KeyDefinition& keyDef : _keyDefinitions)
{
_keyNames[keyDef.keyCode] = keyDef.description; _keyNames[keyDef.keyCode] = keyDef.description;
_keyExtendedNames[keyDef.keyCode | 0x100] = keyDef.extDescription.empty() ? "Ext " + keyDef.description : keyDef.extDescription; _keyExtendedNames[keyDef.keyCode | 0x100] = keyDef.extDescription.empty()
? "Ext " + keyDef.description
: keyDef.extDescription;
_keyCodes[keyDef.description] = keyDef.keyCode; _keyCodes[keyDef.description] = keyDef.keyCode;
if(!keyDef.extDescription.empty()) { if (!keyDef.extDescription.empty())
{
_keyCodes[keyDef.extDescription] = 0x100 | (keyDef.keyCode); _keyCodes[keyDef.extDescription] = 0x100 | (keyDef.keyCode);
} }
} }
@ -248,14 +278,17 @@ WindowsKeyManager::~WindowsKeyManager()
void WindowsKeyManager::StartUpdateDeviceThread() void WindowsKeyManager::StartUpdateDeviceThread()
{ {
_updateDeviceThread = std::thread([=]() { _updateDeviceThread = std::thread([=]()
{
_xInput.reset(new XInputManager(_console)); _xInput.reset(new XInputManager(_console));
_directInput.reset(new DirectInputManager(_console, _hWnd)); _directInput.reset(new DirectInputManager(_console, _hWnd));
while(!_stopUpdateDeviceThread) { while (!_stopUpdateDeviceThread)
{
//Check for newly plugged in XInput controllers every 5 secs //Check for newly plugged in XInput controllers every 5 secs
//Do not check for DirectInput controllers because this takes more time and sometimes causes issues/freezes //Do not check for DirectInput controllers because this takes more time and sometimes causes issues/freezes
if(_xInput->NeedToUpdate()) { if (_xInput->NeedToUpdate())
{
_xInput->UpdateDeviceList(); _xInput->UpdateDeviceList();
} }
_stopSignal.Wait(5000); _stopSignal.Wait(5000);
@ -265,7 +298,8 @@ void WindowsKeyManager::StartUpdateDeviceThread()
void WindowsKeyManager::RefreshState() void WindowsKeyManager::RefreshState()
{ {
if(!_xInput || !_directInput) { if (!_xInput || !_directInput)
{
return; return;
} }
@ -275,27 +309,35 @@ void WindowsKeyManager::RefreshState()
bool WindowsKeyManager::IsKeyPressed(uint32_t key) bool WindowsKeyManager::IsKeyPressed(uint32_t key)
{ {
if(_disableAllKeys) { if (_disableAllKeys)
{
return false; return false;
} }
if(key >= 0x10000) { if (key >= 0x10000)
if(!_xInput || !_directInput) { {
if (!_xInput || !_directInput)
{
return false; return false;
} }
if(key >= 0x11000) { if (key >= 0x11000)
{
//Directinput key //Directinput key
uint8_t gamepadPort = (key - 0x11000) / 0x100; uint8_t gamepadPort = (key - 0x11000) / 0x100;
uint8_t gamepadButton = (key - 0x11000) % 0x100; uint8_t gamepadButton = (key - 0x11000) % 0x100;
return _directInput->IsPressed(gamepadPort, gamepadButton); return _directInput->IsPressed(gamepadPort, gamepadButton);
} else { }
else
{
//XInput key //XInput key
uint8_t gamepadPort = (key - 0xFFFF) / 0x100; uint8_t gamepadPort = (key - 0xFFFF) / 0x100;
uint8_t gamepadButton = (key - 0xFFFF) % 0x100; uint8_t gamepadButton = (key - 0xFFFF) % 0x100;
return _xInput->IsPressed(gamepadPort, gamepadButton); return _xInput->IsPressed(gamepadPort, gamepadButton);
} }
} else if(key < 0x200) { }
else if (key < 0x200)
{
return _keyState[key] != 0; return _keyState[key] != 0;
} }
return false; return false;
@ -303,10 +345,11 @@ bool WindowsKeyManager::IsKeyPressed(uint32_t key)
bool WindowsKeyManager::IsMouseButtonPressed(MouseButton button) bool WindowsKeyManager::IsMouseButtonPressed(MouseButton button)
{ {
switch(button) { switch (button)
case MouseButton::LeftButton: return _mouseState[0]; {
case MouseButton::RightButton: return _mouseState[1]; case MouseButton::LeftButton: return _mouseState[0];
case MouseButton::MiddleButton: return _mouseState[2]; case MouseButton::RightButton: return _mouseState[1];
case MouseButton::MiddleButton: return _mouseState[2];
} }
return false; return false;
@ -315,30 +358,39 @@ bool WindowsKeyManager::IsMouseButtonPressed(MouseButton button)
vector<uint32_t> WindowsKeyManager::GetPressedKeys() vector<uint32_t> WindowsKeyManager::GetPressedKeys()
{ {
vector<uint32_t> result; vector<uint32_t> result;
if(!_xInput || !_directInput) { if (!_xInput || !_directInput)
{
return result; return result;
} }
_xInput->RefreshState(); _xInput->RefreshState();
for(int i = 0; i < XUSER_MAX_COUNT; i++) { for (int i = 0; i < XUSER_MAX_COUNT; i++)
for(int j = 1; j <= 26; j++) { {
if(_xInput->IsPressed(i, j)) { for (int j = 1; j <= 26; j++)
{
if (_xInput->IsPressed(i, j))
{
result.push_back(0xFFFF + i * 0x100 + j); result.push_back(0xFFFF + i * 0x100 + j);
} }
} }
} }
_directInput->RefreshState(); _directInput->RefreshState();
for(int i = _directInput->GetJoystickCount() - 1; i >= 0; i--) { for (int i = _directInput->GetJoystickCount() - 1; i >= 0; i--)
for(int j = 0; j < 16+128; j++) { {
if(_directInput->IsPressed(i, j)) { for (int j = 0; j < 16 + 128; j++)
{
if (_directInput->IsPressed(i, j))
{
result.push_back(0x11000 + i * 0x100 + j); result.push_back(0x11000 + i * 0x100 + j);
} }
} }
} }
for(int i = 0; i < 0x200; i++) { for (int i = 0; i < 0x200; i++)
if(_keyState[i]) { {
if (_keyState[i])
{
result.push_back(i); result.push_back(i);
} }
} }
@ -349,7 +401,8 @@ string WindowsKeyManager::GetKeyName(uint32_t keyCode)
{ {
bool extendedKey = (keyCode <= 0xFFFF && (keyCode & 0x100)); bool extendedKey = (keyCode <= 0xFFFF && (keyCode & 0x100));
auto keyDef = (extendedKey ? _keyExtendedNames : _keyNames).find(keyCode); auto keyDef = (extendedKey ? _keyExtendedNames : _keyNames).find(keyCode);
if(keyDef != (extendedKey ? _keyExtendedNames : _keyNames).end()) { if (keyDef != (extendedKey ? _keyExtendedNames : _keyNames).end())
{
return keyDef->second; return keyDef->second;
} }
return ""; return "";
@ -358,7 +411,8 @@ string WindowsKeyManager::GetKeyName(uint32_t keyCode)
uint32_t WindowsKeyManager::GetKeyCode(string keyName) uint32_t WindowsKeyManager::GetKeyCode(string keyName)
{ {
auto keyDef = _keyCodes.find(keyName); auto keyDef = _keyCodes.find(keyName);
if(keyDef != _keyCodes.end()) { if (keyDef != _keyCodes.end())
{
return keyDef->second; return keyDef->second;
} }
return 0; return 0;
@ -366,7 +420,8 @@ uint32_t WindowsKeyManager::GetKeyCode(string keyName)
void WindowsKeyManager::UpdateDevices() void WindowsKeyManager::UpdateDevices()
{ {
if(!_xInput || !_directInput) { if (!_xInput || !_directInput)
{
return; return;
} }
@ -376,11 +431,15 @@ void WindowsKeyManager::UpdateDevices()
void WindowsKeyManager::SetKeyState(uint16_t scanCode, bool state) void WindowsKeyManager::SetKeyState(uint16_t scanCode, bool state)
{ {
if(scanCode > 0x1FF) { if (scanCode > 0x1FF)
{
_mouseState[scanCode & 0x03] = state; _mouseState[scanCode & 0x03] = state;
} else { }
else
{
uint32_t keyCode = MapVirtualKeyEx(scanCode & 0xFF, MAPVK_VSC_TO_VK, GetKeyboardLayout(0)); uint32_t keyCode = MapVirtualKeyEx(scanCode & 0xFF, MAPVK_VSC_TO_VK, GetKeyboardLayout(0));
if(keyCode >= 0x10 && keyCode <= 0x12) { if (keyCode >= 0x10 && keyCode <= 0x12)
{
//Ignore "ext" flag for alt, ctrl & shift //Ignore "ext" flag for alt, ctrl & shift
scanCode = MapVirtualKeyEx(keyCode, MAPVK_VK_TO_VSC, GetKeyboardLayout(0)); scanCode = MapVirtualKeyEx(keyCode, MAPVK_VK_TO_VSC, GetKeyboardLayout(0));
} }

View file

@ -8,7 +8,8 @@
#include "XInputManager.h" #include "XInputManager.h"
#include "DirectInputManager.h" #include "DirectInputManager.h"
struct KeyDefinition { struct KeyDefinition
{
string name; string name;
uint32_t keyCode; uint32_t keyCode;
string description; string description;
@ -19,40 +20,40 @@ class Console;
class WindowsKeyManager : public IKeyManager class WindowsKeyManager : public IKeyManager
{ {
private: private:
HWND _hWnd; HWND _hWnd;
shared_ptr<Console> _console; shared_ptr<Console> _console;
bool _keyState[0x200]; bool _keyState[0x200];
bool _mouseState[0x03]; bool _mouseState[0x03];
unique_ptr<DirectInputManager> _directInput; unique_ptr<DirectInputManager> _directInput;
unique_ptr<XInputManager> _xInput; unique_ptr<XInputManager> _xInput;
std::unordered_map<uint32_t, string> _keyNames; std::unordered_map<uint32_t, string> _keyNames;
std::unordered_map<uint32_t, string> _keyExtendedNames; std::unordered_map<uint32_t, string> _keyExtendedNames;
std::unordered_map<string, uint32_t> _keyCodes; std::unordered_map<string, uint32_t> _keyCodes;
AutoResetEvent _stopSignal; AutoResetEvent _stopSignal;
std::thread _updateDeviceThread; std::thread _updateDeviceThread;
atomic<bool> _stopUpdateDeviceThread = false; atomic<bool> _stopUpdateDeviceThread = false;
bool _disableAllKeys = false; bool _disableAllKeys = false;
void StartUpdateDeviceThread(); void StartUpdateDeviceThread();
public: public:
WindowsKeyManager(shared_ptr<Console> console, HWND hWnd); WindowsKeyManager(shared_ptr<Console> console, HWND hWnd);
~WindowsKeyManager(); ~WindowsKeyManager();
void RefreshState(); void RefreshState();
bool IsKeyPressed(uint32_t key); bool IsKeyPressed(uint32_t key);
bool IsMouseButtonPressed(MouseButton button); bool IsMouseButtonPressed(MouseButton button);
vector<uint32_t> GetPressedKeys(); vector<uint32_t> GetPressedKeys();
string GetKeyName(uint32_t key); string GetKeyName(uint32_t key);
uint32_t GetKeyCode(string keyName); uint32_t GetKeyCode(string keyName);
void SetKeyState(uint16_t scanCode, bool state); void SetKeyState(uint16_t scanCode, bool state);
void ResetKeyState(); void ResetKeyState();
void SetDisabled(bool disabled); void SetDisabled(bool disabled);
void UpdateDevices(); void UpdateDevices();
}; };

View file

@ -6,7 +6,8 @@
XInputManager::XInputManager(shared_ptr<Console> console) XInputManager::XInputManager(shared_ptr<Console> console)
{ {
_console = console; _console = console;
for(int i = 0; i < XUSER_MAX_COUNT; i++) { for (int i = 0; i < XUSER_MAX_COUNT; i++)
{
_gamePadStates.push_back(shared_ptr<XINPUT_STATE>(new XINPUT_STATE())); _gamePadStates.push_back(shared_ptr<XINPUT_STATE>(new XINPUT_STATE()));
_gamePadConnected.push_back(true); _gamePadConnected.push_back(true);
} }
@ -15,13 +16,18 @@ XInputManager::XInputManager(shared_ptr<Console> console)
void XInputManager::RefreshState() void XInputManager::RefreshState()
{ {
XINPUT_STATE state; XINPUT_STATE state;
for(DWORD i = 0; i < XUSER_MAX_COUNT; i++) { for (DWORD i = 0; i < XUSER_MAX_COUNT; i++)
if(_gamePadConnected[i]) { {
if(XInputGetState(i, &state) != ERROR_SUCCESS) { if (_gamePadConnected[i])
{
if (XInputGetState(i, &state) != ERROR_SUCCESS)
{
//XInputGetState is incredibly slow when no controller is plugged in //XInputGetState is incredibly slow when no controller is plugged in
ZeroMemory(_gamePadStates[i].get(), sizeof(XINPUT_STATE)); ZeroMemory(_gamePadStates[i].get(), sizeof(XINPUT_STATE));
_gamePadConnected[i] = false; _gamePadConnected[i] = false;
} else { }
else
{
*_gamePadStates[i] = state; *_gamePadStates[i] = state;
} }
} }
@ -30,10 +36,13 @@ void XInputManager::RefreshState()
bool XInputManager::NeedToUpdate() bool XInputManager::NeedToUpdate()
{ {
for(int i = 0; i < XUSER_MAX_COUNT; i++) { for (int i = 0; i < XUSER_MAX_COUNT; i++)
if(!_gamePadConnected[i]) { {
if (!_gamePadConnected[i])
{
XINPUT_STATE state; XINPUT_STATE state;
if(XInputGetState(i, &state) == ERROR_SUCCESS) { if (XInputGetState(i, &state) == ERROR_SUCCESS)
{
return true; return true;
} }
} }
@ -44,32 +53,38 @@ bool XInputManager::NeedToUpdate()
void XInputManager::UpdateDeviceList() void XInputManager::UpdateDeviceList()
{ {
//Periodically detect if a controller has been plugged in to allow controllers to be plugged in after the emu is started //Periodically detect if a controller has been plugged in to allow controllers to be plugged in after the emu is started
for(int i = 0; i < XUSER_MAX_COUNT; i++) { for (int i = 0; i < XUSER_MAX_COUNT; i++)
{
_gamePadConnected[i] = true; _gamePadConnected[i] = true;
} }
} }
bool XInputManager::IsPressed(uint8_t gamepadPort, uint8_t button) bool XInputManager::IsPressed(uint8_t gamepadPort, uint8_t button)
{ {
if(_gamePadConnected[gamepadPort]) { if (_gamePadConnected[gamepadPort])
XINPUT_GAMEPAD &gamepad = _gamePadStates[gamepadPort]->Gamepad; {
if(button <= 16) { XINPUT_GAMEPAD& gamepad = _gamePadStates[gamepadPort]->Gamepad;
if (button <= 16)
{
WORD xinputButton = 1 << (button - 1); WORD xinputButton = 1 << (button - 1);
return (_gamePadStates[gamepadPort]->Gamepad.wButtons & xinputButton) != 0; return (_gamePadStates[gamepadPort]->Gamepad.wButtons & xinputButton) != 0;
} else { }
else
{
double ratio = _console->GetSettings()->GetControllerDeadzoneRatio() * 2; double ratio = _console->GetSettings()->GetControllerDeadzoneRatio() * 2;
switch(button) { switch (button)
case 17: return gamepad.bLeftTrigger > (XINPUT_GAMEPAD_TRIGGER_THRESHOLD * ratio); {
case 18: return gamepad.bRightTrigger > (XINPUT_GAMEPAD_TRIGGER_THRESHOLD * ratio); case 17: return gamepad.bLeftTrigger > (XINPUT_GAMEPAD_TRIGGER_THRESHOLD * ratio);
case 19: return gamepad.sThumbRY > (XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE * ratio); case 18: return gamepad.bRightTrigger > (XINPUT_GAMEPAD_TRIGGER_THRESHOLD * ratio);
case 20: return gamepad.sThumbRY < -(XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE * ratio); case 19: return gamepad.sThumbRY > (XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE * ratio);
case 21: return gamepad.sThumbRX < -(XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE * ratio); case 20: return gamepad.sThumbRY < -(XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE * ratio);
case 22: return gamepad.sThumbRX > (XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE * ratio); case 21: return gamepad.sThumbRX < -(XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE * ratio);
case 23: return gamepad.sThumbLY > (XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE * ratio); case 22: return gamepad.sThumbRX > (XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE * ratio);
case 24: return gamepad.sThumbLY < -(XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE * ratio); case 23: return gamepad.sThumbLY > (XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE * ratio);
case 25: return gamepad.sThumbLX < -(XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE * ratio); case 24: return gamepad.sThumbLY < -(XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE * ratio);
case 26: return gamepad.sThumbLX > (XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE * ratio); case 25: return gamepad.sThumbLX < -(XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE * ratio);
case 26: return gamepad.sThumbLX > (XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE * ratio);
} }
} }
} }

View file

@ -7,16 +7,16 @@ class Console;
class XInputManager class XInputManager
{ {
private: private:
shared_ptr<Console> _console; shared_ptr<Console> _console;
vector<shared_ptr<XINPUT_STATE>> _gamePadStates; vector<shared_ptr<XINPUT_STATE>> _gamePadStates;
vector<uint8_t> _gamePadConnected; vector<uint8_t> _gamePadConnected;
public: public:
XInputManager(shared_ptr<Console> console); XInputManager(shared_ptr<Console> console);
bool NeedToUpdate(); bool NeedToUpdate();
void UpdateDeviceList(); void UpdateDeviceList();
void RefreshState(); void RefreshState();
bool IsPressed(uint8_t gamepadPort, uint8_t button); bool IsPressed(uint8_t gamepadPort, uint8_t button);
}; };