The first line I understand, we're just 'mapping' X_INPUT_... to call the Windows function, [...]
No, it's a macro that just saves us some typing in the following lines.
The second line I think is a function pointer?
xinput_get_state is a typedef for the type of the function pointer. Imagine what the preprocessor makes out of this line. It takes the macro from the first line and basically replaces line 2 with this:
| typedef DWORD WINAPI xinput_get_state(DWORD dwUserIndex, XINPUT_STATE *pState)
|
That's how you typedef a function pointer type (important distinction between function pointer and its type here). Sometimes, you also see this form:
| typedef DWORD WINAPI (*xinput_get_state)(DWORD dwUserIndex, XINPUT_STATE *pState)
|
The difference is that with the former, you need to declare function pointer variables like this:
| x_input_get_state* functionPointer;
|
With the latter, you can declare them like this (note the lacking asterisk):
| x_input_get_state functionPointer;
|
The asterisk is basically "baked in".
Onto line 3, the stub. Note again the use of our X_INPUT_GET_STATE stub so we don't have to type that function signature again. Write out what the preprocessor makes out of this line and it will be clear, I hope.
The stub is there to have something to call when the DLL can not be loaded (or it doesn't contain an XInputGetState symbol). Instead of a stub, you could also wrap all calls to XInputGetState like this:
| if (XInputGetState) {
XInputGetState(...);
}
|
Using a stub makes the control flow in the main function a little clearer, though.
This line:
| global_variable x_input_get_state *XInputGetState_ = XInputGetStateStub;
|
Defines a global variable of type x_input_get_state* (our typedef), called XInputGetState_ (underscore to not collide with the real XInputGetState from the XInput.h header) and initializes it to the stub.
And finally, to save us from having to type that underscore all the time:
#define XInputGetState XInputGetState_
We tell the preprocessor to replace all occurences of XInputGetState below this line by XInputGetState_ so that it calls our function pointer instead of the one declared in XInput.h.