boring svn:eol-style native again...

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5771 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Shawn Hoffman 2010-06-22 23:45:56 +00:00
parent 58f42414ba
commit 5e81298ef0
8 changed files with 1147 additions and 1147 deletions

View File

@ -1,187 +1,187 @@
#include "../ControllerInterface.h" #include "../ControllerInterface.h"
#ifdef CIFACE_USE_DIRECTINPUT_KEYBOARD #ifdef CIFACE_USE_DIRECTINPUT_KEYBOARD
#include "DirectInputKeyboard.h" #include "DirectInputKeyboard.h"
#include "DirectInput.h" #include "DirectInput.h"
// TODO: maybe add a ClearInputState function to this device // TODO: maybe add a ClearInputState function to this device
namespace ciface namespace ciface
{ {
namespace DirectInput namespace DirectInput
{ {
struct struct
{ {
const BYTE code; const BYTE code;
const char* const name; const char* const name;
} named_keys[] = } named_keys[] =
{ {
#include "NamedKeys.h" #include "NamedKeys.h"
}; };
struct struct
{ {
const BYTE code; const BYTE code;
const char* const name; const char* const name;
} named_lights[] = } named_lights[] =
{ {
{ VK_NUMLOCK, "NUM LOCK" }, { VK_NUMLOCK, "NUM LOCK" },
{ VK_CAPITAL, "CAPS LOCK" }, { VK_CAPITAL, "CAPS LOCK" },
{ VK_SCROLL, "SCROLL LOCK" } { VK_SCROLL, "SCROLL LOCK" }
}; };
void InitKeyboard(IDirectInput8* const idi8, std::vector<ControllerInterface::Device*>& devices) void InitKeyboard(IDirectInput8* const idi8, std::vector<ControllerInterface::Device*>& devices)
{ {
LPDIRECTINPUTDEVICE8 kb_device; LPDIRECTINPUTDEVICE8 kb_device;
unsigned int kb_count = 0; unsigned int kb_count = 0;
std::list<DIDEVICEINSTANCE> keyboards; std::list<DIDEVICEINSTANCE> keyboards;
idi8->EnumDevices(DI8DEVCLASS_KEYBOARD, DIEnumDevicesCallback, (LPVOID)&keyboards, DIEDFL_ATTACHEDONLY); idi8->EnumDevices(DI8DEVCLASS_KEYBOARD, DIEnumDevicesCallback, (LPVOID)&keyboards, DIEDFL_ATTACHEDONLY);
// add other keyboard devices // add other keyboard devices
std::list<DIDEVICEINSTANCE>::iterator std::list<DIDEVICEINSTANCE>::iterator
i = keyboards.begin(), i = keyboards.begin(),
e = keyboards.end(); e = keyboards.end();
for (; i!=e; ++i) for (; i!=e; ++i)
{ {
if (SUCCEEDED(idi8->CreateDevice(i->guidInstance, &kb_device, NULL))) if (SUCCEEDED(idi8->CreateDevice(i->guidInstance, &kb_device, NULL)))
{ {
if (SUCCEEDED(kb_device->SetDataFormat(&c_dfDIKeyboard))) if (SUCCEEDED(kb_device->SetDataFormat(&c_dfDIKeyboard)))
if (SUCCEEDED(kb_device->SetCooperativeLevel(NULL, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) if (SUCCEEDED(kb_device->SetCooperativeLevel(NULL, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)))
{ {
devices.push_back(new Keyboard(kb_device, kb_count++)); devices.push_back(new Keyboard(kb_device, kb_count++));
return; return;
} }
} }
kb_device->Release(); kb_device->Release();
} }
} }
Keyboard::~Keyboard() Keyboard::~Keyboard()
{ {
// kb // kb
m_kb_device->Unacquire(); m_kb_device->Unacquire();
m_kb_device->Release(); m_kb_device->Release();
} }
Keyboard::Keyboard(const LPDIRECTINPUTDEVICE8 kb_device, const int index) Keyboard::Keyboard(const LPDIRECTINPUTDEVICE8 kb_device, const int index)
: m_kb_device(kb_device) : m_kb_device(kb_device)
, m_index(index) , m_index(index)
{ {
m_kb_device->Acquire(); m_kb_device->Acquire();
ZeroMemory(&m_state_in, sizeof(m_state_in)); ZeroMemory(&m_state_in, sizeof(m_state_in));
ZeroMemory(m_state_out, sizeof(m_state_out)); ZeroMemory(m_state_out, sizeof(m_state_out));
ZeroMemory(&m_current_state_out, sizeof(m_current_state_out)); ZeroMemory(&m_current_state_out, sizeof(m_current_state_out));
// KEYBOARD // KEYBOARD
// add keys // add keys
for (unsigned int i = 0; i < sizeof(named_keys)/sizeof(*named_keys); ++i) for (unsigned int i = 0; i < sizeof(named_keys)/sizeof(*named_keys); ++i)
AddInput(new Key(i)); AddInput(new Key(i));
// add lights // add lights
for (unsigned int i = 0; i < sizeof(named_lights)/sizeof(*named_lights); ++i) for (unsigned int i = 0; i < sizeof(named_lights)/sizeof(*named_lights); ++i)
AddOutput(new Light(i)); AddOutput(new Light(i));
} }
bool Keyboard::UpdateInput() bool Keyboard::UpdateInput()
{ {
HRESULT hr = m_kb_device->GetDeviceState(sizeof(m_state_in), m_state_in); HRESULT hr = m_kb_device->GetDeviceState(sizeof(m_state_in), m_state_in);
if (DIERR_INPUTLOST == hr || DIERR_NOTACQUIRED == hr) if (DIERR_INPUTLOST == hr || DIERR_NOTACQUIRED == hr)
m_kb_device->Acquire(); m_kb_device->Acquire();
return SUCCEEDED(hr); return SUCCEEDED(hr);
} }
bool Keyboard::UpdateOutput() bool Keyboard::UpdateOutput()
{ {
class KInput : public INPUT class KInput : public INPUT
{ {
public: public:
KInput( const unsigned char key, const bool up = false ) KInput( const unsigned char key, const bool up = false )
{ {
memset( this, 0, sizeof(*this) ); memset( this, 0, sizeof(*this) );
type = INPUT_KEYBOARD; type = INPUT_KEYBOARD;
ki.wVk = key; ki.wVk = key;
if (up) ki.dwFlags = KEYEVENTF_KEYUP; if (up) ki.dwFlags = KEYEVENTF_KEYUP;
} }
}; };
std::vector< KInput > kbinputs; std::vector< KInput > kbinputs;
for ( unsigned int i = 0; i < sizeof(m_state_out)/sizeof(*m_state_out); ++i ) for ( unsigned int i = 0; i < sizeof(m_state_out)/sizeof(*m_state_out); ++i )
{ {
bool want_on = false; bool want_on = false;
if ( m_state_out[i] ) if ( m_state_out[i] )
want_on = m_state_out[i] > wxGetLocalTimeMillis() % 255 ; // light should flash when output is 0.5 want_on = m_state_out[i] > wxGetLocalTimeMillis() % 255 ; // light should flash when output is 0.5
// lights are set to their original state when output is zero // lights are set to their original state when output is zero
if ( want_on ^ m_current_state_out[i] ) if ( want_on ^ m_current_state_out[i] )
{ {
kbinputs.push_back( KInput( named_lights[i].code ) ); // press kbinputs.push_back( KInput( named_lights[i].code ) ); // press
kbinputs.push_back( KInput( named_lights[i].code, true ) ); // release kbinputs.push_back( KInput( named_lights[i].code, true ) ); // release
m_current_state_out[i] ^= 1; m_current_state_out[i] ^= 1;
} }
} }
if (kbinputs.size()) if (kbinputs.size())
return ( kbinputs.size() == SendInput( (UINT)kbinputs.size(), &kbinputs[0], sizeof( kbinputs[0] ) ) ); return ( kbinputs.size() == SendInput( (UINT)kbinputs.size(), &kbinputs[0], sizeof( kbinputs[0] ) ) );
else else
return true; return true;
} }
std::string Keyboard::GetName() const std::string Keyboard::GetName() const
{ {
return "Keyboard"; return "Keyboard";
} }
int Keyboard::GetId() const int Keyboard::GetId() const
{ {
return m_index; return m_index;
} }
std::string Keyboard::GetSource() const std::string Keyboard::GetSource() const
{ {
return DINPUT_SOURCE_NAME; return DINPUT_SOURCE_NAME;
} }
ControlState Keyboard::GetInputState(const ControllerInterface::Device::Input* const input) const ControlState Keyboard::GetInputState(const ControllerInterface::Device::Input* const input) const
{ {
return (((Input*)input)->GetState(m_state_in)); return (((Input*)input)->GetState(m_state_in));
} }
void Keyboard::SetOutputState(const ControllerInterface::Device::Output* const output, const ControlState state) void Keyboard::SetOutputState(const ControllerInterface::Device::Output* const output, const ControlState state)
{ {
((Output*)output)->SetState(state, m_state_out); ((Output*)output)->SetState(state, m_state_out);
} }
// names // names
std::string Keyboard::Key::GetName() const std::string Keyboard::Key::GetName() const
{ {
return named_keys[m_index].name; return named_keys[m_index].name;
} }
std::string Keyboard::Light::GetName() const std::string Keyboard::Light::GetName() const
{ {
return named_lights[ m_index ].name; return named_lights[ m_index ].name;
} }
// get/set state // get/set state
ControlState Keyboard::Key::GetState(const BYTE keys[]) const ControlState Keyboard::Key::GetState(const BYTE keys[]) const
{ {
return (keys[named_keys[m_index].code] != 0); return (keys[named_keys[m_index].code] != 0);
} }
void Keyboard::Light::SetState( const ControlState state, unsigned char* const state_out ) void Keyboard::Light::SetState( const ControlState state, unsigned char* const state_out )
{ {
state_out[m_index] = state * 255; state_out[m_index] = state * 255;
} }
} }
} }
#endif #endif

View File

@ -1,99 +1,99 @@
#ifndef _CIFACE_DIRECTINPUT_KEYBOARD_H_ #ifndef _CIFACE_DIRECTINPUT_KEYBOARD_H_
#define _CIFACE_DIRECTINPUT_KEYBOARD_H_ #define _CIFACE_DIRECTINPUT_KEYBOARD_H_
#include "../ControllerInterface.h" #include "../ControllerInterface.h"
#define DIRECTINPUT_VERSION 0x0800 #define DIRECTINPUT_VERSION 0x0800
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#define NOMINMAX #define NOMINMAX
#include <Windows.h> #include <Windows.h>
#include <dinput.h> #include <dinput.h>
#include <wx/stopwatch.h> #include <wx/stopwatch.h>
#include <wx/utils.h> #include <wx/utils.h>
namespace ciface namespace ciface
{ {
namespace DirectInput namespace DirectInput
{ {
void InitKeyboard(IDirectInput8* const idi8, std::vector<ControllerInterface::Device*>& devices); void InitKeyboard(IDirectInput8* const idi8, std::vector<ControllerInterface::Device*>& devices);
class Keyboard : public ControllerInterface::Device class Keyboard : public ControllerInterface::Device
{ {
friend class ControllerInterface; friend class ControllerInterface;
friend class ControllerInterface::ControlReference; friend class ControllerInterface::ControlReference;
protected: protected:
struct State struct State
{ {
}; };
class Input : public ControllerInterface::Device::Input class Input : public ControllerInterface::Device::Input
{ {
friend class Keyboard; friend class Keyboard;
protected: protected:
virtual ControlState GetState(const BYTE keys[]) const = 0; virtual ControlState GetState(const BYTE keys[]) const = 0;
}; };
class Output : public ControllerInterface::Device::Output class Output : public ControllerInterface::Device::Output
{ {
friend class Keyboard; friend class Keyboard;
protected: protected:
virtual void SetState(const ControlState state, unsigned char* const state_out) = 0; virtual void SetState(const ControlState state, unsigned char* const state_out) = 0;
}; };
class Key : public Input class Key : public Input
{ {
friend class Keyboard; friend class Keyboard;
public: public:
std::string GetName() const; std::string GetName() const;
protected: protected:
Key(const unsigned int index) : m_index(index) {} Key(const unsigned int index) : m_index(index) {}
ControlState GetState(const BYTE keys[]) const; ControlState GetState(const BYTE keys[]) const;
private: private:
const unsigned int m_index; const unsigned int m_index;
}; };
class Light : public Output class Light : public Output
{ {
friend class Keyboard; friend class Keyboard;
public: public:
std::string GetName() const; std::string GetName() const;
protected: protected:
Light(const unsigned int index) : m_index(index) {} Light(const unsigned int index) : m_index(index) {}
void SetState(const ControlState state, unsigned char* const state_out); void SetState(const ControlState state, unsigned char* const state_out);
private: private:
const unsigned int m_index; const unsigned int m_index;
}; };
bool UpdateInput(); bool UpdateInput();
bool UpdateOutput(); bool UpdateOutput();
ControlState GetInputState( const ControllerInterface::Device::Input* const input ) const; ControlState GetInputState( const ControllerInterface::Device::Input* const input ) const;
void SetOutputState( const ControllerInterface::Device::Output* const input, const ControlState state ); void SetOutputState( const ControllerInterface::Device::Output* const input, const ControlState state );
public: public:
Keyboard(const LPDIRECTINPUTDEVICE8 kb_device, const int index); Keyboard(const LPDIRECTINPUTDEVICE8 kb_device, const int index);
~Keyboard(); ~Keyboard();
std::string GetName() const; std::string GetName() const;
int GetId() const; int GetId() const;
std::string GetSource() const; std::string GetSource() const;
private: private:
const LPDIRECTINPUTDEVICE8 m_kb_device; const LPDIRECTINPUTDEVICE8 m_kb_device;
const int m_index; const int m_index;
wxLongLong m_last_update; wxLongLong m_last_update;
BYTE m_state_in[256]; BYTE m_state_in[256];
unsigned char m_state_out[3]; // NUM CAPS SCROLL unsigned char m_state_out[3]; // NUM CAPS SCROLL
bool m_current_state_out[3]; // NUM CAPS SCROLL bool m_current_state_out[3]; // NUM CAPS SCROLL
}; };
} }
} }
#endif #endif

View File

@ -1,175 +1,175 @@
#include "../ControllerInterface.h" #include "../ControllerInterface.h"
#ifdef CIFACE_USE_DIRECTINPUT_MOUSE #ifdef CIFACE_USE_DIRECTINPUT_MOUSE
#include "DirectInputMouse.h" #include "DirectInputMouse.h"
#include "DirectInput.h" #include "DirectInput.h"
// TODO: maybe add a ClearInputState function to this device // TODO: maybe add a ClearInputState function to this device
// (lower would be more sensitive) user can lower sensitivity by setting range // (lower would be more sensitive) user can lower sensitivity by setting range
// seems decent here ( at 8 ), I dont think anyone would need more sensitive than this // seems decent here ( at 8 ), I dont think anyone would need more sensitive than this
// and user can lower it much farther than they would want to with the range // and user can lower it much farther than they would want to with the range
#define MOUSE_AXIS_SENSITIVITY 8 #define MOUSE_AXIS_SENSITIVITY 8
// if input hasn't been received for this many ms, mouse input will be skipped // if input hasn't been received for this many ms, mouse input will be skipped
// otherwise it is just some crazy value // otherwise it is just some crazy value
#define DROP_INPUT_TIME 250 #define DROP_INPUT_TIME 250
namespace ciface namespace ciface
{ {
namespace DirectInput namespace DirectInput
{ {
void InitMouse( IDirectInput8* const idi8, std::vector<ControllerInterface::Device*>& devices ) void InitMouse( IDirectInput8* const idi8, std::vector<ControllerInterface::Device*>& devices )
{ {
LPDIRECTINPUTDEVICE8 mo_device; LPDIRECTINPUTDEVICE8 mo_device;
unsigned int mo_count = 0; unsigned int mo_count = 0;
std::list<DIDEVICEINSTANCE> mice; std::list<DIDEVICEINSTANCE> mice;
idi8->EnumDevices(DI8DEVCLASS_POINTER, DIEnumDevicesCallback, (LPVOID)&mice, DIEDFL_ATTACHEDONLY); idi8->EnumDevices(DI8DEVCLASS_POINTER, DIEnumDevicesCallback, (LPVOID)&mice, DIEDFL_ATTACHEDONLY);
// add other keyboard devices // add other keyboard devices
std::list<DIDEVICEINSTANCE>::iterator std::list<DIDEVICEINSTANCE>::iterator
i = mice.begin(), i = mice.begin(),
e = mice.end(); e = mice.end();
for (; i!=e; ++i) for (; i!=e; ++i)
{ {
if (SUCCEEDED(idi8->CreateDevice(i->guidInstance, &mo_device, NULL))) if (SUCCEEDED(idi8->CreateDevice(i->guidInstance, &mo_device, NULL)))
{ {
if (SUCCEEDED(mo_device->SetDataFormat(&c_dfDIMouse2))) if (SUCCEEDED(mo_device->SetDataFormat(&c_dfDIMouse2)))
if (SUCCEEDED(mo_device->SetCooperativeLevel(NULL, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) if (SUCCEEDED(mo_device->SetCooperativeLevel(NULL, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)))
{ {
devices.push_back(new Mouse(mo_device, mo_count++)); devices.push_back(new Mouse(mo_device, mo_count++));
return; return;
} }
} }
mo_device->Release(); mo_device->Release();
} }
} }
Mouse::~Mouse() Mouse::~Mouse()
{ {
// mouse // mouse
m_mo_device->Unacquire(); m_mo_device->Unacquire();
m_mo_device->Release(); m_mo_device->Release();
} }
Mouse::Mouse(const LPDIRECTINPUTDEVICE8 mo_device, const int index) Mouse::Mouse(const LPDIRECTINPUTDEVICE8 mo_device, const int index)
: m_mo_device(mo_device) : m_mo_device(mo_device)
, m_index(index) , m_index(index)
{ {
m_mo_device->Acquire(); m_mo_device->Acquire();
m_last_update = GetTickCount(); m_last_update = GetTickCount();
ZeroMemory(&m_state_in, sizeof(m_state_in)); ZeroMemory(&m_state_in, sizeof(m_state_in));
// MOUSE // MOUSE
// get caps // get caps
DIDEVCAPS mouse_caps; DIDEVCAPS mouse_caps;
ZeroMemory( &mouse_caps, sizeof(mouse_caps) ); ZeroMemory( &mouse_caps, sizeof(mouse_caps) );
mouse_caps.dwSize = sizeof(mouse_caps); mouse_caps.dwSize = sizeof(mouse_caps);
m_mo_device->GetCapabilities(&mouse_caps); m_mo_device->GetCapabilities(&mouse_caps);
// mouse buttons // mouse buttons
for (unsigned int i = 0; i < mouse_caps.dwButtons; ++i) for (unsigned int i = 0; i < mouse_caps.dwButtons; ++i)
AddInput(new Button(i)); AddInput(new Button(i));
// mouse axes // mouse axes
for (unsigned int i = 0; i < mouse_caps.dwAxes; ++i) for (unsigned int i = 0; i < mouse_caps.dwAxes; ++i)
{ {
// each axis gets a negative and a positive input instance associated with it // each axis gets a negative and a positive input instance associated with it
AddInput(new Axis(i, (2==i) ? -1 : -MOUSE_AXIS_SENSITIVITY)); AddInput(new Axis(i, (2==i) ? -1 : -MOUSE_AXIS_SENSITIVITY));
AddInput(new Axis(i, -(2==i) ? 1 : MOUSE_AXIS_SENSITIVITY)); AddInput(new Axis(i, -(2==i) ? 1 : MOUSE_AXIS_SENSITIVITY));
} }
} }
bool Mouse::UpdateInput() bool Mouse::UpdateInput()
{ {
DIMOUSESTATE2 tmp_mouse; DIMOUSESTATE2 tmp_mouse;
HRESULT hr = m_mo_device->GetDeviceState(sizeof(tmp_mouse), &tmp_mouse); HRESULT hr = m_mo_device->GetDeviceState(sizeof(tmp_mouse), &tmp_mouse);
// if mouse position hasn't been updated in a short while, skip a dev state // if mouse position hasn't been updated in a short while, skip a dev state
const DWORD cur_time = GetTickCount(); const DWORD cur_time = GetTickCount();
if (cur_time - m_last_update > DROP_INPUT_TIME) if (cur_time - m_last_update > DROP_INPUT_TIME)
{ {
// set buttons/axes to zero // set buttons/axes to zero
// skip this input state // skip this input state
ZeroMemory(&m_state_in, sizeof(m_state_in)); ZeroMemory(&m_state_in, sizeof(m_state_in));
} }
else if (SUCCEEDED(hr)) else if (SUCCEEDED(hr))
{ {
// need to smooth out the axes, otherwise it doesnt work for shit // need to smooth out the axes, otherwise it doesnt work for shit
for (unsigned int i = 0; i < 3; ++i) for (unsigned int i = 0; i < 3; ++i)
((&m_state_in.lX)[i] += (&tmp_mouse.lX)[i]) /= 2; ((&m_state_in.lX)[i] += (&tmp_mouse.lX)[i]) /= 2;
// copy over the buttons // copy over the buttons
memcpy(m_state_in.rgbButtons, tmp_mouse.rgbButtons, sizeof(m_state_in.rgbButtons)); memcpy(m_state_in.rgbButtons, tmp_mouse.rgbButtons, sizeof(m_state_in.rgbButtons));
} }
m_last_update = cur_time; m_last_update = cur_time;
if (DIERR_INPUTLOST == hr || DIERR_NOTACQUIRED == hr) if (DIERR_INPUTLOST == hr || DIERR_NOTACQUIRED == hr)
m_mo_device->Acquire(); m_mo_device->Acquire();
return SUCCEEDED(hr); return SUCCEEDED(hr);
} }
bool Mouse::UpdateOutput() bool Mouse::UpdateOutput()
{ {
return true; return true;
} }
std::string Mouse::GetName() const std::string Mouse::GetName() const
{ {
return "Mouse"; return "Mouse";
} }
int Mouse::GetId() const int Mouse::GetId() const
{ {
return m_index; return m_index;
} }
std::string Mouse::GetSource() const std::string Mouse::GetSource() const
{ {
return DINPUT_SOURCE_NAME; return DINPUT_SOURCE_NAME;
} }
ControlState Mouse::GetInputState( const ControllerInterface::Device::Input* const input ) const ControlState Mouse::GetInputState( const ControllerInterface::Device::Input* const input ) const
{ {
return (((Input*)input)->GetState(&m_state_in)); return (((Input*)input)->GetState(&m_state_in));
} }
void Mouse::SetOutputState(const ControllerInterface::Device::Output* const output, const ControlState state) void Mouse::SetOutputState(const ControllerInterface::Device::Output* const output, const ControlState state)
{ {
return; return;
} }
// names // names
std::string Mouse::Button::GetName() const std::string Mouse::Button::GetName() const
{ {
return std::string("Button ") + char('0'+m_index); return std::string("Button ") + char('0'+m_index);
} }
std::string Mouse::Axis::GetName() const std::string Mouse::Axis::GetName() const
{ {
std::string tmpstr("Axis "); std::string tmpstr("Axis ");
tmpstr += "XYZ"[m_index]; tmpstr += ( m_range>0 ? '+' : '-' ); tmpstr += "XYZ"[m_index]; tmpstr += ( m_range>0 ? '+' : '-' );
return tmpstr; return tmpstr;
} }
// get/set state // get/set state
ControlState Mouse::Button::GetState(const DIMOUSESTATE2* const state) const ControlState Mouse::Button::GetState(const DIMOUSESTATE2* const state) const
{ {
return (state->rgbButtons[m_index] != 0); return (state->rgbButtons[m_index] != 0);
} }
ControlState Mouse::Axis::GetState(const DIMOUSESTATE2* const state) const ControlState Mouse::Axis::GetState(const DIMOUSESTATE2* const state) const
{ {
return std::max(0.0f, ControlState((&state->lX)[m_index]) / m_range); return std::max(0.0f, ControlState((&state->lX)[m_index]) / m_range);
} }
} }
} }
#endif #endif

View File

@ -1,83 +1,83 @@
#ifndef _CIFACE_DIRECTINPUT_MOUSE_H_ #ifndef _CIFACE_DIRECTINPUT_MOUSE_H_
#define _CIFACE_DIRECTINPUT_MOUSE_H_ #define _CIFACE_DIRECTINPUT_MOUSE_H_
#include "../ControllerInterface.h" #include "../ControllerInterface.h"
#define DIRECTINPUT_VERSION 0x0800 #define DIRECTINPUT_VERSION 0x0800
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#define NOMINMAX #define NOMINMAX
#include <Windows.h> #include <Windows.h>
#include <dinput.h> #include <dinput.h>
namespace ciface namespace ciface
{ {
namespace DirectInput namespace DirectInput
{ {
void InitMouse(IDirectInput8* const idi8, std::vector<ControllerInterface::Device*>& devices); void InitMouse(IDirectInput8* const idi8, std::vector<ControllerInterface::Device*>& devices);
class Mouse : public ControllerInterface::Device class Mouse : public ControllerInterface::Device
{ {
friend class ControllerInterface; friend class ControllerInterface;
friend class ControllerInterface::ControlReference; friend class ControllerInterface::ControlReference;
protected: protected:
class Input : public ControllerInterface::Device::Input class Input : public ControllerInterface::Device::Input
{ {
friend class Mouse; friend class Mouse;
protected: protected:
virtual ControlState GetState(const DIMOUSESTATE2* const boardstate) const = 0; virtual ControlState GetState(const DIMOUSESTATE2* const boardstate) const = 0;
}; };
class Button : public Input class Button : public Input
{ {
friend class Mouse; friend class Mouse;
public: public:
std::string GetName() const; std::string GetName() const;
protected: protected:
Button(const unsigned int index) : m_index(index) {} Button(const unsigned int index) : m_index(index) {}
ControlState GetState(const DIMOUSESTATE2* const state) const; ControlState GetState(const DIMOUSESTATE2* const state) const;
private: private:
const unsigned int m_index; const unsigned int m_index;
}; };
class Axis : public Input class Axis : public Input
{ {
friend class Mouse; friend class Mouse;
public: public:
std::string GetName() const; std::string GetName() const;
protected: protected:
Axis(const unsigned int index, const LONG range) : m_index(index), m_range(range) {} Axis(const unsigned int index, const LONG range) : m_index(index), m_range(range) {}
ControlState GetState(const DIMOUSESTATE2* const state) const; ControlState GetState(const DIMOUSESTATE2* const state) const;
private: private:
const unsigned int m_index; const unsigned int m_index;
const LONG m_range; const LONG m_range;
}; };
bool UpdateInput(); bool UpdateInput();
bool UpdateOutput(); bool UpdateOutput();
ControlState GetInputState( const ControllerInterface::Device::Input* const input ) const; ControlState GetInputState( const ControllerInterface::Device::Input* const input ) const;
void SetOutputState( const ControllerInterface::Device::Output* const input, const ControlState state ); void SetOutputState( const ControllerInterface::Device::Output* const input, const ControlState state );
public: public:
Mouse(const LPDIRECTINPUTDEVICE8 mo_device, const int index); Mouse(const LPDIRECTINPUTDEVICE8 mo_device, const int index);
~Mouse(); ~Mouse();
std::string GetName() const; std::string GetName() const;
int GetId() const; int GetId() const;
std::string GetSource() const; std::string GetSource() const;
private: private:
const LPDIRECTINPUTDEVICE8 m_mo_device; const LPDIRECTINPUTDEVICE8 m_mo_device;
const int m_index; const int m_index;
DWORD m_last_update; DWORD m_last_update;
DIMOUSESTATE2 m_state_in; DIMOUSESTATE2 m_state_in;
}; };
} }
} }
#endif #endif

View File

@ -1,63 +1,63 @@
// Copyright (C) 2003 Dolphin Project. // Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "D3DBlob.h" #include "D3DBlob.h"
D3DBlob::D3DBlob(unsigned int blob_size, const u8* init_data) : ref(1), size(blob_size), blob(NULL) D3DBlob::D3DBlob(unsigned int blob_size, const u8* init_data) : ref(1), size(blob_size), blob(NULL)
{ {
data = new u8[blob_size]; data = new u8[blob_size];
if (init_data) memcpy(data, init_data, size); if (init_data) memcpy(data, init_data, size);
} }
D3DBlob::D3DBlob(ID3D10Blob* d3dblob) : ref(1) D3DBlob::D3DBlob(ID3D10Blob* d3dblob) : ref(1)
{ {
blob = d3dblob; blob = d3dblob;
data = (u8*)blob->GetBufferPointer(); data = (u8*)blob->GetBufferPointer();
size = blob->GetBufferSize(); size = blob->GetBufferSize();
d3dblob->AddRef(); d3dblob->AddRef();
} }
D3DBlob::~D3DBlob() D3DBlob::~D3DBlob()
{ {
if (blob) blob->Release(); if (blob) blob->Release();
else delete[] data; else delete[] data;
} }
void D3DBlob::AddRef() void D3DBlob::AddRef()
{ {
++ref; ++ref;
} }
unsigned int D3DBlob::Release() unsigned int D3DBlob::Release()
{ {
if (--ref == 0) if (--ref == 0)
{ {
delete this; delete this;
return 0; return 0;
} }
return ref; return ref;
} }
unsigned int D3DBlob::Size() unsigned int D3DBlob::Size()
{ {
return size; return size;
} }
u8* D3DBlob::Data() u8* D3DBlob::Data()
{ {
return data; return data;
} }

View File

@ -1,47 +1,47 @@
// Copyright (C) 2003 Dolphin Project. // Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#pragma once #pragma once
#include <d3d11.h> #include <d3d11.h>
#include "Common.h" #include "Common.h"
// use this class instead ID3D10Blob or ID3D11Blob whenever possible // use this class instead ID3D10Blob or ID3D11Blob whenever possible
class D3DBlob class D3DBlob
{ {
public: public:
// memory will be copied into an own buffer // memory will be copied into an own buffer
D3DBlob(unsigned int blob_size, const u8* init_data = NULL); D3DBlob(unsigned int blob_size, const u8* init_data = NULL);
// d3dblob will be AddRef'd // d3dblob will be AddRef'd
D3DBlob(ID3D10Blob* d3dblob); D3DBlob(ID3D10Blob* d3dblob);
void AddRef(); void AddRef();
unsigned int Release(); unsigned int Release();
unsigned int Size(); unsigned int Size();
u8* Data(); u8* Data();
private: private:
~D3DBlob(); ~D3DBlob();
unsigned int ref; unsigned int ref;
unsigned int size; unsigned int size;
u8* data; u8* data;
ID3D10Blob* blob; ID3D10Blob* blob;
}; };

View File

@ -1,361 +1,361 @@
// Copyright (C) 2003 Dolphin Project. // Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "VideoConfig.h" #include "VideoConfig.h"
#include "GfxState.h" #include "GfxState.h"
namespace D3D namespace D3D
{ {
EmuGfxState* gfxstate; EmuGfxState* gfxstate;
StateManager* stateman; StateManager* stateman;
EmuGfxState::EmuGfxState() : vertexshader(NULL), vsbytecode(NULL), pixelshader(NULL), psbytecode(NULL), apply_called(false) EmuGfxState::EmuGfxState() : vertexshader(NULL), vsbytecode(NULL), pixelshader(NULL), psbytecode(NULL), apply_called(false)
{ {
for (unsigned int k = 0;k < 8;k++) for (unsigned int k = 0;k < 8;k++)
{ {
float border[4] = {0.f, 0.f, 0.f, 0.f}; float border[4] = {0.f, 0.f, 0.f, 0.f};
shader_resources[k] = NULL; shader_resources[k] = NULL;
samplerdesc[k] = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_CLAMP, 0.f, 16, D3D11_COMPARISON_ALWAYS, border, -D3D11_FLOAT32_MAX, D3D11_FLOAT32_MAX); samplerdesc[k] = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_CLAMP, 0.f, 16, D3D11_COMPARISON_ALWAYS, border, -D3D11_FLOAT32_MAX, D3D11_FLOAT32_MAX);
if(g_ActiveConfig.iMaxAnisotropy > 1) samplerdesc[k].Filter = D3D11_FILTER_ANISOTROPIC; if(g_ActiveConfig.iMaxAnisotropy > 1) samplerdesc[k].Filter = D3D11_FILTER_ANISOTROPIC;
} }
blenddesc.AlphaToCoverageEnable = FALSE; blenddesc.AlphaToCoverageEnable = FALSE;
blenddesc.IndependentBlendEnable = FALSE; blenddesc.IndependentBlendEnable = FALSE;
blenddesc.RenderTarget[0].BlendEnable = FALSE; blenddesc.RenderTarget[0].BlendEnable = FALSE;
blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
blenddesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; blenddesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
blenddesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO; blenddesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
blenddesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; blenddesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blenddesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
depthdesc.DepthEnable = TRUE; depthdesc.DepthEnable = TRUE;
depthdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
depthdesc.DepthFunc = D3D11_COMPARISON_LESS; depthdesc.DepthFunc = D3D11_COMPARISON_LESS;
depthdesc.StencilEnable = FALSE; depthdesc.StencilEnable = FALSE;
depthdesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; depthdesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
depthdesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; depthdesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
// this probably must be changed once multisampling support gets added // this probably must be changed once multisampling support gets added
rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, 0, 0.f, 0, false, true, false, false); rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, 0, 0.f, 0, false, true, false, false);
pscbuf = NULL; pscbuf = NULL;
vscbuf = NULL; vscbuf = NULL;
vshaderchanged = false; vshaderchanged = false;
inp_layout = NULL; inp_layout = NULL;
num_inp_elems = 0; num_inp_elems = 0;
pscbufchanged = false; pscbufchanged = false;
vscbufchanged = false; vscbufchanged = false;
} }
EmuGfxState::~EmuGfxState() EmuGfxState::~EmuGfxState()
{ {
for (unsigned int k = 0;k < 8;k++) for (unsigned int k = 0;k < 8;k++)
SAFE_RELEASE(shader_resources[k]) SAFE_RELEASE(shader_resources[k])
SAFE_RELEASE(vsbytecode); SAFE_RELEASE(vsbytecode);
SAFE_RELEASE(psbytecode); SAFE_RELEASE(psbytecode);
SAFE_RELEASE(vertexshader); SAFE_RELEASE(vertexshader);
SAFE_RELEASE(pixelshader); SAFE_RELEASE(pixelshader);
SAFE_RELEASE(pscbuf); SAFE_RELEASE(pscbuf);
SAFE_RELEASE(vscbuf); SAFE_RELEASE(vscbuf);
SAFE_RELEASE(inp_layout); SAFE_RELEASE(inp_layout);
} }
// TODO: No need to store the whole bytecode, signature might be enough (?) // TODO: No need to store the whole bytecode, signature might be enough (?)
void EmuGfxState::SetVShader(ID3D11VertexShader* shader, D3DBlob* bcode) void EmuGfxState::SetVShader(ID3D11VertexShader* shader, D3DBlob* bcode)
{ {
// TODO: vshaderchanged actually just needs to be true if the signature changed // TODO: vshaderchanged actually just needs to be true if the signature changed
if (bcode && vsbytecode != bcode) vshaderchanged = true; if (bcode && vsbytecode != bcode) vshaderchanged = true;
SAFE_RELEASE(vsbytecode); SAFE_RELEASE(vsbytecode);
SAFE_RELEASE(vertexshader); SAFE_RELEASE(vertexshader);
if (shader && bcode) if (shader && bcode)
{ {
vertexshader = shader; vertexshader = shader;
shader->AddRef(); shader->AddRef();
vsbytecode = bcode; vsbytecode = bcode;
bcode->AddRef(); bcode->AddRef();
} }
else if (shader || bcode) else if (shader || bcode)
{ {
PanicAlert("Invalid parameters!\n"); PanicAlert("Invalid parameters!\n");
} }
} }
void EmuGfxState::SetPShader(ID3D11PixelShader* shader) void EmuGfxState::SetPShader(ID3D11PixelShader* shader)
{ {
if (pixelshader) pixelshader->Release(); if (pixelshader) pixelshader->Release();
pixelshader = shader; pixelshader = shader;
if (shader) shader->AddRef(); if (shader) shader->AddRef();
} }
void EmuGfxState::SetInputElements(const D3D11_INPUT_ELEMENT_DESC* elems, UINT num) void EmuGfxState::SetInputElements(const D3D11_INPUT_ELEMENT_DESC* elems, UINT num)
{ {
num_inp_elems = num; num_inp_elems = num;
memcpy(inp_elems, elems, num*sizeof(D3D11_INPUT_ELEMENT_DESC)); memcpy(inp_elems, elems, num*sizeof(D3D11_INPUT_ELEMENT_DESC));
} }
void EmuGfxState::SetShaderResource(unsigned int stage, ID3D11ShaderResourceView* srv) void EmuGfxState::SetShaderResource(unsigned int stage, ID3D11ShaderResourceView* srv)
{ {
if (shader_resources[stage]) shader_resources[stage]->Release(); if (shader_resources[stage]) shader_resources[stage]->Release();
shader_resources[stage] = srv; shader_resources[stage] = srv;
if (srv) srv->AddRef(); if (srv) srv->AddRef();
} }
void EmuGfxState::ApplyState() void EmuGfxState::ApplyState()
{ {
HRESULT hr; HRESULT hr;
// input layout (only needs to be updated if the vertex shader signature changed) // input layout (only needs to be updated if the vertex shader signature changed)
if (vshaderchanged) if (vshaderchanged)
{ {
if (inp_layout) inp_layout->Release(); if (inp_layout) inp_layout->Release();
hr = D3D::device->CreateInputLayout(inp_elems, num_inp_elems, vsbytecode->Data(), vsbytecode->Size(), &inp_layout); hr = D3D::device->CreateInputLayout(inp_elems, num_inp_elems, vsbytecode->Data(), vsbytecode->Size(), &inp_layout);
if (FAILED(hr)) PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__); if (FAILED(hr)) PanicAlert("Failed to create input layout, %s %d\n", __FILE__, __LINE__);
SetDebugObjectName((ID3D11DeviceChild*)inp_layout, "an input layout of EmuGfxState"); SetDebugObjectName((ID3D11DeviceChild*)inp_layout, "an input layout of EmuGfxState");
vshaderchanged = false; vshaderchanged = false;
} }
D3D::context->IASetInputLayout(inp_layout); D3D::context->IASetInputLayout(inp_layout);
// vertex shader // vertex shader
// TODO: divide the global variables of the generated shaders into about 5 constant buffers // TODO: divide the global variables of the generated shaders into about 5 constant buffers
// TODO: improve interaction between EmuGfxState and global state management, so that we don't need to set the constant buffers every time // TODO: improve interaction between EmuGfxState and global state management, so that we don't need to set the constant buffers every time
if (!vscbuf) if (!vscbuf)
{ {
unsigned int size = ((sizeof(vsconstants))&(~0xf))+0x10; // must be a multiple of 16 unsigned int size = ((sizeof(vsconstants))&(~0xf))+0x10; // must be a multiple of 16
D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(size, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(size, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
hr = device->CreateBuffer(&cbdesc, NULL, &vscbuf); hr = device->CreateBuffer(&cbdesc, NULL, &vscbuf);
CHECK(hr==S_OK, "Create vertex shader constant buffer (size=%u)", size); CHECK(hr==S_OK, "Create vertex shader constant buffer (size=%u)", size);
SetDebugObjectName((ID3D11DeviceChild*)vscbuf, "a vertex shader constant buffer of EmuGfxState"); SetDebugObjectName((ID3D11DeviceChild*)vscbuf, "a vertex shader constant buffer of EmuGfxState");
} }
if (vscbufchanged) if (vscbufchanged)
{ {
D3D11_MAPPED_SUBRESOURCE map; D3D11_MAPPED_SUBRESOURCE map;
context->Map(vscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); context->Map(vscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
memcpy(map.pData, vsconstants, sizeof(vsconstants)); memcpy(map.pData, vsconstants, sizeof(vsconstants));
context->Unmap(vscbuf, 0); context->Unmap(vscbuf, 0);
} }
D3D::context->VSSetConstantBuffers(0, 1, &vscbuf); D3D::context->VSSetConstantBuffers(0, 1, &vscbuf);
// pixel shader // pixel shader
if (!pscbuf) if (!pscbuf)
{ {
unsigned int size = ((sizeof(psconstants))&(~0xf))+0x10; // must be a multiple of 16 unsigned int size = ((sizeof(psconstants))&(~0xf))+0x10; // must be a multiple of 16
D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(size, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(size, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
device->CreateBuffer(&cbdesc, NULL, &pscbuf); device->CreateBuffer(&cbdesc, NULL, &pscbuf);
CHECK(hr==S_OK, "Create pixel shader constant buffer (size=%u)", size); CHECK(hr==S_OK, "Create pixel shader constant buffer (size=%u)", size);
SetDebugObjectName((ID3D11DeviceChild*)pscbuf, "a pixel shader constant buffer of EmuGfxState"); SetDebugObjectName((ID3D11DeviceChild*)pscbuf, "a pixel shader constant buffer of EmuGfxState");
} }
if (pscbufchanged) if (pscbufchanged)
{ {
D3D11_MAPPED_SUBRESOURCE map; D3D11_MAPPED_SUBRESOURCE map;
context->Map(pscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); context->Map(pscbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
memcpy(map.pData, psconstants, sizeof(psconstants)); memcpy(map.pData, psconstants, sizeof(psconstants));
context->Unmap(pscbuf, 0); context->Unmap(pscbuf, 0);
pscbufchanged = false; pscbufchanged = false;
} }
D3D::context->PSSetConstantBuffers(0, 1, &pscbuf); D3D::context->PSSetConstantBuffers(0, 1, &pscbuf);
ID3D11SamplerState* samplerstate[8]; ID3D11SamplerState* samplerstate[8];
for (unsigned int stage = 0; stage < 8; stage++) for (unsigned int stage = 0; stage < 8; stage++)
{ {
if (shader_resources[stage]) if (shader_resources[stage])
{ {
if(g_ActiveConfig.iMaxAnisotropy > 1) samplerdesc[stage].Filter = D3D11_FILTER_ANISOTROPIC; if(g_ActiveConfig.iMaxAnisotropy > 1) samplerdesc[stage].Filter = D3D11_FILTER_ANISOTROPIC;
hr = D3D::device->CreateSamplerState(&samplerdesc[stage], &samplerstate[stage]); hr = D3D::device->CreateSamplerState(&samplerdesc[stage], &samplerstate[stage]);
if (FAILED(hr)) PanicAlert("Fail %s %d, stage=%d\n", __FILE__, __LINE__, stage); if (FAILED(hr)) PanicAlert("Fail %s %d, stage=%d\n", __FILE__, __LINE__, stage);
else SetDebugObjectName((ID3D11DeviceChild*)samplerstate[stage], "a sampler state of EmuGfxState"); else SetDebugObjectName((ID3D11DeviceChild*)samplerstate[stage], "a sampler state of EmuGfxState");
} }
else samplerstate[stage] = NULL; else samplerstate[stage] = NULL;
} }
D3D::context->PSSetSamplers(0, 8, samplerstate); D3D::context->PSSetSamplers(0, 8, samplerstate);
for (unsigned int stage = 0; stage < 8; stage++) for (unsigned int stage = 0; stage < 8; stage++)
SAFE_RELEASE(samplerstate[stage]); SAFE_RELEASE(samplerstate[stage]);
ID3D11BlendState* blstate; ID3D11BlendState* blstate;
hr = device->CreateBlendState(&blenddesc, &blstate); hr = device->CreateBlendState(&blenddesc, &blstate);
if (FAILED(hr)) PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__); if (FAILED(hr)) PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__);
stateman->PushBlendState(blstate); stateman->PushBlendState(blstate);
SetDebugObjectName((ID3D11DeviceChild*)blstate, "a blend state of EmuGfxState"); SetDebugObjectName((ID3D11DeviceChild*)blstate, "a blend state of EmuGfxState");
blstate->Release(); blstate->Release();
rastdesc.FillMode = (g_ActiveConfig.bWireFrame) ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID; rastdesc.FillMode = (g_ActiveConfig.bWireFrame) ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID;
ID3D11RasterizerState* raststate; ID3D11RasterizerState* raststate;
hr = device->CreateRasterizerState(&rastdesc, &raststate); hr = device->CreateRasterizerState(&rastdesc, &raststate);
if (FAILED(hr)) PanicAlert("Failed to create rasterizer state at %s %d\n", __FILE__, __LINE__); if (FAILED(hr)) PanicAlert("Failed to create rasterizer state at %s %d\n", __FILE__, __LINE__);
SetDebugObjectName((ID3D11DeviceChild*)raststate, "a rasterizer state of EmuGfxState"); SetDebugObjectName((ID3D11DeviceChild*)raststate, "a rasterizer state of EmuGfxState");
stateman->PushRasterizerState(raststate); stateman->PushRasterizerState(raststate);
raststate->Release(); raststate->Release();
ID3D11DepthStencilState* depth_state; ID3D11DepthStencilState* depth_state;
hr = device->CreateDepthStencilState(&depthdesc, &depth_state); hr = device->CreateDepthStencilState(&depthdesc, &depth_state);
if (SUCCEEDED(hr)) SetDebugObjectName((ID3D11DeviceChild*)depth_state, "a depth-stencil state of EmuGfxState"); if (SUCCEEDED(hr)) SetDebugObjectName((ID3D11DeviceChild*)depth_state, "a depth-stencil state of EmuGfxState");
else PanicAlert("Failed to create depth state at %s %d\n", __FILE__, __LINE__); else PanicAlert("Failed to create depth state at %s %d\n", __FILE__, __LINE__);
D3D::stateman->PushDepthState(depth_state); D3D::stateman->PushDepthState(depth_state);
depth_state->Release(); depth_state->Release();
context->PSSetShader(pixelshader, NULL, 0); context->PSSetShader(pixelshader, NULL, 0);
context->VSSetShader(vertexshader, NULL, 0); context->VSSetShader(vertexshader, NULL, 0);
context->PSSetShaderResources(0, 8, shader_resources); context->PSSetShaderResources(0, 8, shader_resources);
stateman->Apply(); stateman->Apply();
apply_called = true; apply_called = true;
} }
void EmuGfxState::AlphaPass() void EmuGfxState::AlphaPass()
{ {
if (!apply_called) ERROR_LOG(VIDEO, "EmuGfxState::AlphaPass called without having called ApplyState before!") if (!apply_called) ERROR_LOG(VIDEO, "EmuGfxState::AlphaPass called without having called ApplyState before!")
else stateman->PopBlendState(); else stateman->PopBlendState();
// pixel shader for alpha pass is different, so update it // pixel shader for alpha pass is different, so update it
context->PSSetShader(pixelshader, NULL, 0); context->PSSetShader(pixelshader, NULL, 0);
ID3D11BlendState* blstate; ID3D11BlendState* blstate;
D3D11_BLEND_DESC desc = blenddesc; D3D11_BLEND_DESC desc = blenddesc;
desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALPHA; desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALPHA;
desc.RenderTarget[0].BlendEnable = FALSE; desc.RenderTarget[0].BlendEnable = FALSE;
HRESULT hr = device->CreateBlendState(&desc, &blstate); HRESULT hr = device->CreateBlendState(&desc, &blstate);
if (FAILED(hr)) PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__); if (FAILED(hr)) PanicAlert("Failed to create blend state at %s %d\n", __FILE__, __LINE__);
SetDebugObjectName((ID3D11DeviceChild*)blstate, "a blend state of EmuGfxState (created during alpha pass)"); SetDebugObjectName((ID3D11DeviceChild*)blstate, "a blend state of EmuGfxState (created during alpha pass)");
stateman->PushBlendState(blstate); stateman->PushBlendState(blstate);
blstate->Release(); blstate->Release();
stateman->Apply(); stateman->Apply();
} }
void EmuGfxState::Reset() void EmuGfxState::Reset()
{ {
for (unsigned int k = 0;k < 8;k++) for (unsigned int k = 0;k < 8;k++)
SAFE_RELEASE(shader_resources[k]); SAFE_RELEASE(shader_resources[k]);
if (apply_called) if (apply_called)
{ {
stateman->PopBlendState(); stateman->PopBlendState();
stateman->PopDepthState(); stateman->PopDepthState();
stateman->PopRasterizerState(); stateman->PopRasterizerState();
apply_called = false; apply_called = false;
} }
} }
void EmuGfxState::SetAlphaBlendEnable(bool enable) void EmuGfxState::SetAlphaBlendEnable(bool enable)
{ {
blenddesc.RenderTarget[0].BlendEnable = enable; blenddesc.RenderTarget[0].BlendEnable = enable;
} }
void EmuGfxState::SetRenderTargetWriteMask(UINT8 mask) void EmuGfxState::SetRenderTargetWriteMask(UINT8 mask)
{ {
blenddesc.RenderTarget[0].RenderTargetWriteMask = mask; blenddesc.RenderTarget[0].RenderTargetWriteMask = mask;
} }
void EmuGfxState::SetSrcBlend(D3D11_BLEND val) void EmuGfxState::SetSrcBlend(D3D11_BLEND val)
{ {
// TODO: Check whether e.g. the dest color check is needed here // TODO: Check whether e.g. the dest color check is needed here
blenddesc.RenderTarget[0].SrcBlend = val; blenddesc.RenderTarget[0].SrcBlend = val;
if (val == D3D11_BLEND_SRC_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; if (val == D3D11_BLEND_SRC_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
else if (val == D3D11_BLEND_INV_SRC_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; else if (val == D3D11_BLEND_INV_SRC_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
else if (val == D3D11_BLEND_DEST_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_DEST_ALPHA; else if (val == D3D11_BLEND_DEST_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_DEST_ALPHA;
else if (val == D3D11_BLEND_INV_DEST_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA; else if (val == D3D11_BLEND_INV_DEST_COLOR) blenddesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA;
else blenddesc.RenderTarget[0].SrcBlendAlpha = val; else blenddesc.RenderTarget[0].SrcBlendAlpha = val;
} }
void EmuGfxState::SetDestBlend(D3D11_BLEND val) void EmuGfxState::SetDestBlend(D3D11_BLEND val)
{ {
// TODO: Check whether e.g. the source color check is needed here // TODO: Check whether e.g. the source color check is needed here
blenddesc.RenderTarget[0].DestBlend = val; blenddesc.RenderTarget[0].DestBlend = val;
if (val == D3D11_BLEND_SRC_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_SRC_ALPHA; if (val == D3D11_BLEND_SRC_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_SRC_ALPHA;
else if (val == D3D11_BLEND_INV_SRC_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; else if (val == D3D11_BLEND_INV_SRC_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
else if (val == D3D11_BLEND_DEST_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_DEST_ALPHA; else if (val == D3D11_BLEND_DEST_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_DEST_ALPHA;
else if (val == D3D11_BLEND_INV_DEST_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA; else if (val == D3D11_BLEND_INV_DEST_COLOR) blenddesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA;
else blenddesc.RenderTarget[0].DestBlendAlpha = val; else blenddesc.RenderTarget[0].DestBlendAlpha = val;
} }
void EmuGfxState::SetBlendOp(D3D11_BLEND_OP val) void EmuGfxState::SetBlendOp(D3D11_BLEND_OP val)
{ {
blenddesc.RenderTarget[0].BlendOp = val; blenddesc.RenderTarget[0].BlendOp = val;
blenddesc.RenderTarget[0].BlendOpAlpha = val; blenddesc.RenderTarget[0].BlendOpAlpha = val;
} }
void EmuGfxState::SetSamplerFilter(DWORD stage, D3D11_FILTER filter) void EmuGfxState::SetSamplerFilter(DWORD stage, D3D11_FILTER filter)
{ {
samplerdesc[stage].Filter = filter; samplerdesc[stage].Filter = filter;
} }
template<typename T> AutoState<T>::AutoState(const T* object) : state(object) template<typename T> AutoState<T>::AutoState(const T* object) : state(object)
{ {
((IUnknown*)state)->AddRef(); ((IUnknown*)state)->AddRef();
} }
template<typename T> AutoState<T>::AutoState(const AutoState<T> &source) template<typename T> AutoState<T>::AutoState(const AutoState<T> &source)
{ {
state = source.GetPtr(); state = source.GetPtr();
((IUnknown*)state)->AddRef(); ((IUnknown*)state)->AddRef();
} }
template<typename T> AutoState<T>::~AutoState() template<typename T> AutoState<T>::~AutoState()
{ {
((IUnknown*)state)->Release(); ((IUnknown*)state)->Release();
} }
StateManager::StateManager() : cur_blendstate(NULL), cur_depthstate(NULL), cur_raststate(NULL) {} StateManager::StateManager() : cur_blendstate(NULL), cur_depthstate(NULL), cur_raststate(NULL) {}
void StateManager::PushBlendState(const ID3D11BlendState* state) { blendstates.push(AutoBlendState(state));} void StateManager::PushBlendState(const ID3D11BlendState* state) { blendstates.push(AutoBlendState(state));}
void StateManager::PushDepthState(const ID3D11DepthStencilState* state) { depthstates.push(AutoDepthStencilState(state));} void StateManager::PushDepthState(const ID3D11DepthStencilState* state) { depthstates.push(AutoDepthStencilState(state));}
void StateManager::PushRasterizerState(const ID3D11RasterizerState* state) { raststates.push(AutoRasterizerState(state));} void StateManager::PushRasterizerState(const ID3D11RasterizerState* state) { raststates.push(AutoRasterizerState(state));}
void StateManager::PopBlendState() { blendstates.pop(); } void StateManager::PopBlendState() { blendstates.pop(); }
void StateManager::PopDepthState() { depthstates.pop(); } void StateManager::PopDepthState() { depthstates.pop(); }
void StateManager::PopRasterizerState() { raststates.pop(); } void StateManager::PopRasterizerState() { raststates.pop(); }
void StateManager::Apply() void StateManager::Apply()
{ {
if (!blendstates.empty()) if (!blendstates.empty())
{ {
if (cur_blendstate != blendstates.top().GetPtr()) if (cur_blendstate != blendstates.top().GetPtr())
{ {
cur_blendstate = (ID3D11BlendState*)blendstates.top().GetPtr(); cur_blendstate = (ID3D11BlendState*)blendstates.top().GetPtr();
D3D::context->OMSetBlendState(cur_blendstate, NULL, 0xFFFFFFFF); D3D::context->OMSetBlendState(cur_blendstate, NULL, 0xFFFFFFFF);
} }
} }
else D3D::context->OMSetBlendState(NULL, NULL, 0xFFFFFFFF); else D3D::context->OMSetBlendState(NULL, NULL, 0xFFFFFFFF);
if (!depthstates.empty()) if (!depthstates.empty())
{ {
if (cur_depthstate != depthstates.top().GetPtr()) if (cur_depthstate != depthstates.top().GetPtr())
{ {
cur_depthstate = (ID3D11DepthStencilState*)depthstates.top().GetPtr(); cur_depthstate = (ID3D11DepthStencilState*)depthstates.top().GetPtr();
D3D::context->OMSetDepthStencilState(cur_depthstate, 0); D3D::context->OMSetDepthStencilState(cur_depthstate, 0);
} }
} }
else D3D::context->OMSetDepthStencilState(NULL, 0); else D3D::context->OMSetDepthStencilState(NULL, 0);
if (!raststates.empty()) if (!raststates.empty())
{ {
if (cur_raststate != raststates.top().GetPtr()) if (cur_raststate != raststates.top().GetPtr())
{ {
cur_raststate = (ID3D11RasterizerState*)raststates.top().GetPtr(); cur_raststate = (ID3D11RasterizerState*)raststates.top().GetPtr();
D3D::context->RSSetState(cur_raststate); D3D::context->RSSetState(cur_raststate);
} }
} }
else D3D::context->RSSetState(NULL); else D3D::context->RSSetState(NULL);
} }
} // namespace } // namespace

View File

@ -1,132 +1,132 @@
// Copyright (C) 2003 Dolphin Project. // Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#pragma once #pragma once
#include "D3DBase.h" #include "D3DBase.h"
#include <stack> #include <stack>
using std::stack; using std::stack;
namespace D3D namespace D3D
{ {
// stores the pipeline state to use when calling VertexManager::Flush() // stores the pipeline state to use when calling VertexManager::Flush()
class EmuGfxState class EmuGfxState
{ {
public: public:
EmuGfxState(); EmuGfxState();
~EmuGfxState(); ~EmuGfxState();
void SetVShader(ID3D11VertexShader* shader, D3DBlob* bcode); void SetVShader(ID3D11VertexShader* shader, D3DBlob* bcode);
void SetPShader(ID3D11PixelShader* shader); void SetPShader(ID3D11PixelShader* shader);
void SetInputElements(const D3D11_INPUT_ELEMENT_DESC* elems, UINT num); void SetInputElements(const D3D11_INPUT_ELEMENT_DESC* elems, UINT num);
void SetShaderResource(unsigned int stage, ID3D11ShaderResourceView* srv); void SetShaderResource(unsigned int stage, ID3D11ShaderResourceView* srv);
void ApplyState(); // apply current state void ApplyState(); // apply current state
void AlphaPass(); // only modify the current state to enable the alpha pass void AlphaPass(); // only modify the current state to enable the alpha pass
void Reset(); void Reset();
// blend state // blend state
void SetAlphaBlendEnable(bool enable); void SetAlphaBlendEnable(bool enable);
void SetRenderTargetWriteMask(UINT8 mask); void SetRenderTargetWriteMask(UINT8 mask);
void SetSrcBlend(D3D11_BLEND val); void SetSrcBlend(D3D11_BLEND val);
void SetDestBlend(D3D11_BLEND val); void SetDestBlend(D3D11_BLEND val);
void SetBlendOp(D3D11_BLEND_OP val); void SetBlendOp(D3D11_BLEND_OP val);
// sampler states // sampler states
void SetSamplerFilter(DWORD stage, D3D11_FILTER filter); void SetSamplerFilter(DWORD stage, D3D11_FILTER filter);
// TODO: add methods for changing the other states instead of modifying them directly // TODO: add methods for changing the other states instead of modifying them directly
D3D11_SAMPLER_DESC samplerdesc[8]; D3D11_SAMPLER_DESC samplerdesc[8];
D3D11_RASTERIZER_DESC rastdesc; D3D11_RASTERIZER_DESC rastdesc;
D3D11_DEPTH_STENCIL_DESC depthdesc; D3D11_DEPTH_STENCIL_DESC depthdesc;
float psconstants[116]; float psconstants[116];
float vsconstants[952]; float vsconstants[952];
bool vscbufchanged; bool vscbufchanged;
bool pscbufchanged; bool pscbufchanged;
private: private:
ID3D11VertexShader* vertexshader; ID3D11VertexShader* vertexshader;
D3DBlob* vsbytecode; D3DBlob* vsbytecode;
ID3D11PixelShader* pixelshader; ID3D11PixelShader* pixelshader;
D3DBlob* psbytecode; D3DBlob* psbytecode;
bool vshaderchanged; bool vshaderchanged;
ID3D11Buffer* vscbuf; ID3D11Buffer* vscbuf;
ID3D11Buffer* pscbuf; ID3D11Buffer* pscbuf;
ID3D11InputLayout* inp_layout; ID3D11InputLayout* inp_layout;
D3D11_INPUT_ELEMENT_DESC inp_elems[32]; D3D11_INPUT_ELEMENT_DESC inp_elems[32];
int num_inp_elems; int num_inp_elems;
ID3D11ShaderResourceView* shader_resources[8]; ID3D11ShaderResourceView* shader_resources[8];
D3D11_BLEND_DESC blenddesc; D3D11_BLEND_DESC blenddesc;
bool apply_called; bool apply_called;
}; };
template<typename T> class AutoState template<typename T> class AutoState
{ {
public: public:
AutoState(const T* object); AutoState(const T* object);
AutoState(const AutoState<T> &source); AutoState(const AutoState<T> &source);
~AutoState(); ~AutoState();
const inline T* GetPtr() const { return state; } const inline T* GetPtr() const { return state; }
private: private:
const T* state; const T* state;
}; };
typedef AutoState<ID3D11BlendState> AutoBlendState; typedef AutoState<ID3D11BlendState> AutoBlendState;
typedef AutoState<ID3D11DepthStencilState> AutoDepthStencilState; typedef AutoState<ID3D11DepthStencilState> AutoDepthStencilState;
typedef AutoState<ID3D11RasterizerState> AutoRasterizerState; typedef AutoState<ID3D11RasterizerState> AutoRasterizerState;
class StateManager class StateManager
{ {
public: public:
StateManager(); StateManager();
// call any of these to change the affected states // call any of these to change the affected states
void PushBlendState(const ID3D11BlendState* state); void PushBlendState(const ID3D11BlendState* state);
void PushDepthState(const ID3D11DepthStencilState* state); void PushDepthState(const ID3D11DepthStencilState* state);
void PushRasterizerState(const ID3D11RasterizerState* state); void PushRasterizerState(const ID3D11RasterizerState* state);
// call these after drawing // call these after drawing
void PopBlendState(); void PopBlendState();
void PopDepthState(); void PopDepthState();
void PopRasterizerState(); void PopRasterizerState();
// call this before any drawing operation if states could have changed meanwhile // call this before any drawing operation if states could have changed meanwhile
void Apply(); void Apply();
private: private:
stack<AutoBlendState> blendstates; stack<AutoBlendState> blendstates;
stack<AutoDepthStencilState> depthstates; stack<AutoDepthStencilState> depthstates;
stack<AutoRasterizerState> raststates; stack<AutoRasterizerState> raststates;
ID3D11BlendState* cur_blendstate; ID3D11BlendState* cur_blendstate;
ID3D11DepthStencilState* cur_depthstate; ID3D11DepthStencilState* cur_depthstate;
ID3D11RasterizerState* cur_raststate; ID3D11RasterizerState* cur_raststate;
}; };
extern EmuGfxState* gfxstate; extern EmuGfxState* gfxstate;
extern StateManager* stateman; extern StateManager* stateman;
} // namespace } // namespace