mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-26 07:35:40 +00:00
464 lines
12 KiB
C
464 lines
12 KiB
C
|
/*
|
||
|
* Sega Model 3 Emulator
|
||
|
* Copyright (C) 2003 Bart Trzynadlowski, Ville Linde, Stefano Teso
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or modify it
|
||
|
* under the terms of the GNU General Public License Version 2 as published
|
||
|
* by the Free Software Foundation.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful, but
|
||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||
|
* for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License along
|
||
|
* with this program (license.txt); if not, write to the Free Software
|
||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
*/
|
||
|
|
||
|
/******************************************************************/
|
||
|
/* XInput for Xbox360 controller */
|
||
|
/******************************************************************/
|
||
|
|
||
|
#include "MODEL3.H"
|
||
|
#include <dinput.h>
|
||
|
#include <xinput.h>
|
||
|
|
||
|
static LPDIRECTINPUT8 dinput;
|
||
|
static LPDIRECTINPUTDEVICE8 keyboard;
|
||
|
static LPDIRECTINPUTDEVICE8 mouse;
|
||
|
|
||
|
static CHAR keyboard_buffer[256];
|
||
|
static DIMOUSESTATE mouse_state;
|
||
|
|
||
|
extern HWND main_window;
|
||
|
|
||
|
static OSD_CONTROLS controls;
|
||
|
|
||
|
static int xbox_controllers[4];
|
||
|
|
||
|
|
||
|
static int analog_axis[8];
|
||
|
static BOOL button_state[16];
|
||
|
|
||
|
static struct
|
||
|
{
|
||
|
BOOL up, down, left, right;
|
||
|
} joystick[4];
|
||
|
|
||
|
BOOL osd_input_init(void)
|
||
|
{
|
||
|
HINSTANCE hinstance;
|
||
|
HRESULT hr;
|
||
|
|
||
|
DWORD result;
|
||
|
XINPUT_STATE state;
|
||
|
|
||
|
atexit(osd_input_shutdown);
|
||
|
|
||
|
hinstance = GetModuleHandle(NULL);
|
||
|
hr = DirectInput8Create( hinstance, DIRECTINPUT_VERSION, &IID_IDirectInput8,
|
||
|
(void**)&dinput, NULL );
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
message(0, "DirectInput8Create failed.");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// Create keyboard device
|
||
|
hr = IDirectInput8_CreateDevice( dinput, &GUID_SysKeyboard, &keyboard, NULL );
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
message(0, "IDirectInput8_CreateDevice failed.");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
hr = IDirectInputDevice8_SetDataFormat( keyboard, &c_dfDIKeyboard );
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
message(0, "IDirectInputDevice8_SetDataFormat failed.");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
hr = IDirectInputDevice8_SetCooperativeLevel( keyboard, main_window, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE );
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
message(0, "IDirectInputDevice8_SetCooperativeLevel failed.");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if (keyboard)
|
||
|
{
|
||
|
IDirectInputDevice8_Acquire( keyboard );
|
||
|
}
|
||
|
|
||
|
// Create mouse device
|
||
|
hr = IDirectInput8_CreateDevice( dinput, &GUID_SysMouse, &mouse, NULL );
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
message(0, "IDirectInput8_CreateDevice failed.");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
hr = IDirectInputDevice8_SetDataFormat( mouse, &c_dfDIMouse );
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
message(0, "IDirectInputDevice8_SetDataFormat failed.");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
hr = IDirectInputDevice8_SetCooperativeLevel( mouse, main_window, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE );
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
message(0, "IDirectInputDevice8_SetCooperativeLevel failed.");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// Init Xbox360 controllers
|
||
|
ZeroMemory(&state, sizeof(XINPUT_STATE));
|
||
|
|
||
|
// Simply get the state of the controller from XInput.
|
||
|
result = XInputGetState(0, &state);
|
||
|
|
||
|
if (result == ERROR_SUCCESS)
|
||
|
{
|
||
|
// Controller is connected
|
||
|
xbox_controllers[0] = 1;
|
||
|
message(0, "Xbox360 controller found!");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Controller is not connected
|
||
|
xbox_controllers[0] = 0;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
void osd_input_shutdown(void)
|
||
|
{
|
||
|
if(dinput)
|
||
|
{
|
||
|
if(keyboard)
|
||
|
{
|
||
|
IDirectInputDevice8_Unacquire( keyboard );
|
||
|
IDirectInputDevice8_Release( keyboard );
|
||
|
keyboard = NULL;
|
||
|
}
|
||
|
if(mouse)
|
||
|
{
|
||
|
IDirectInputDevice8_Unacquire( mouse );
|
||
|
IDirectInputDevice8_Release( mouse );
|
||
|
mouse = NULL;
|
||
|
}
|
||
|
IDirectInput8_Release( dinput );
|
||
|
dinput = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void input_update(void)
|
||
|
{
|
||
|
/* updates the input buffer */
|
||
|
if(dinput)
|
||
|
{
|
||
|
// Get keyboard state
|
||
|
IDirectInputDevice8_GetDeviceState( keyboard, sizeof(keyboard_buffer), &keyboard_buffer );
|
||
|
// Get mouse state
|
||
|
IDirectInputDevice8_Acquire( mouse );
|
||
|
IDirectInputDevice8_GetDeviceState( mouse, sizeof(mouse_state), &mouse_state );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static BOOL keyboard_get_key(UINT8 key)
|
||
|
{
|
||
|
if (keyboard_buffer[key] & 0x80)
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static BOOL mouse_get_button(UINT8 button)
|
||
|
{
|
||
|
if (mouse_state.rgbButtons[button] & 0x80)
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void mouse_get_position(INT32* xposition, INT32* yposition)
|
||
|
{
|
||
|
POINT mouse_pos;
|
||
|
|
||
|
GetCursorPos( &mouse_pos );
|
||
|
ScreenToClient( main_window, &mouse_pos );
|
||
|
|
||
|
*xposition = mouse_pos.x;
|
||
|
*yposition = mouse_pos.y;
|
||
|
}
|
||
|
|
||
|
static void update_controls_keyboard(void)
|
||
|
{
|
||
|
memset(button_state, 0, sizeof(button_state));
|
||
|
memset(joystick, 0, sizeof(joystick));
|
||
|
|
||
|
if (keyboard_get_key(DIK_A)) button_state[0] = 1;
|
||
|
if (keyboard_get_key(DIK_S)) button_state[1] = 1;
|
||
|
if (keyboard_get_key(DIK_D)) button_state[2] = 1;
|
||
|
if (keyboard_get_key(DIK_F)) button_state[3] = 1;
|
||
|
if (keyboard_get_key(DIK_Z)) button_state[4] = 1;
|
||
|
if (keyboard_get_key(DIK_X)) button_state[5] = 1;
|
||
|
if (keyboard_get_key(DIK_C)) button_state[6] = 1;
|
||
|
if (keyboard_get_key(DIK_V)) button_state[7] = 1;
|
||
|
|
||
|
if (keyboard_get_key(DIK_LEFT)) joystick[0].left = TRUE;
|
||
|
if (keyboard_get_key(DIK_RIGHT)) joystick[0].right = TRUE;
|
||
|
if (keyboard_get_key(DIK_UP)) joystick[0].up = TRUE;
|
||
|
if (keyboard_get_key(DIK_DOWN)) joystick[0].down = TRUE;
|
||
|
|
||
|
if (keyboard_get_key(DIK_LEFT)) analog_axis[0] -= 16;
|
||
|
if (keyboard_get_key(DIK_RIGHT)) analog_axis[0] += 16;
|
||
|
if (keyboard_get_key(DIK_UP)) analog_axis[1] -= 16;
|
||
|
if (keyboard_get_key(DIK_DOWN)) analog_axis[1] += 16;
|
||
|
|
||
|
if (analog_axis[0] < -128) analog_axis[0] = -128;
|
||
|
if (analog_axis[0] > 127) analog_axis[0] = 127;
|
||
|
if (analog_axis[1] < -128) analog_axis[1] = -128;
|
||
|
if (analog_axis[1] > 127) analog_axis[1] = 127;
|
||
|
}
|
||
|
|
||
|
static void update_controls_xbox(void)
|
||
|
{
|
||
|
XINPUT_STATE state;
|
||
|
DWORD res;
|
||
|
|
||
|
memset(button_state, 0, sizeof(button_state));
|
||
|
memset(analog_axis, 0, sizeof(analog_axis));
|
||
|
memset(joystick, 0, sizeof(joystick));
|
||
|
|
||
|
res = XInputGetState(0, &state);
|
||
|
if (res == ERROR_SUCCESS)
|
||
|
{
|
||
|
// Zero value if thumbsticks are within the dead zone
|
||
|
if ((state.Gamepad.sThumbLX < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE &&
|
||
|
state.Gamepad.sThumbLX > -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE))
|
||
|
{
|
||
|
state.Gamepad.sThumbLX = 0;
|
||
|
}
|
||
|
if ((state.Gamepad.sThumbLY < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE &&
|
||
|
state.Gamepad.sThumbLY > -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE))
|
||
|
{
|
||
|
|
||
|
state.Gamepad.sThumbLY = 0;
|
||
|
}
|
||
|
|
||
|
if ((state.Gamepad.sThumbRX < XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE &&
|
||
|
state.Gamepad.sThumbRX > -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE))
|
||
|
{
|
||
|
state.Gamepad.sThumbRX = 0;
|
||
|
}
|
||
|
if ((state.Gamepad.sThumbRY < XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE &&
|
||
|
state.Gamepad.sThumbRY > -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE))
|
||
|
{
|
||
|
state.Gamepad.sThumbRY = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_A) button_state[0] = TRUE;
|
||
|
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_B) button_state[1] = TRUE;
|
||
|
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_X) button_state[2] = TRUE;
|
||
|
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_Y) button_state[3] = TRUE;
|
||
|
|
||
|
if (state.Gamepad.sThumbLX < 0) joystick[0].left = TRUE;
|
||
|
if (state.Gamepad.sThumbLX > 0) joystick[0].right = TRUE;
|
||
|
if (state.Gamepad.sThumbLY < 0) joystick[0].up = TRUE;
|
||
|
if (state.Gamepad.sThumbLY > 0) joystick[0].down = TRUE;
|
||
|
|
||
|
analog_axis[0] = state.Gamepad.sThumbLX / 256;
|
||
|
analog_axis[1] = state.Gamepad.sThumbLY / 256;
|
||
|
analog_axis[2] = state.Gamepad.bRightTrigger;
|
||
|
analog_axis[3] = state.Gamepad.bLeftTrigger;
|
||
|
analog_axis[4] = state.Gamepad.sThumbRX;
|
||
|
analog_axis[5] = state.Gamepad.sThumbRY;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static int get_analog_axis(GAME_ANALOG axis)
|
||
|
{
|
||
|
switch (axis)
|
||
|
{
|
||
|
case ANALOG_AXIS_1: return analog_axis[0];
|
||
|
case ANALOG_AXIS_2: return analog_axis[1];
|
||
|
case ANALOG_AXIS_3: return analog_axis[2];
|
||
|
case ANALOG_AXIS_4: return analog_axis[3];
|
||
|
case ANALOG_AXIS_5: return analog_axis[4];
|
||
|
case ANALOG_AXIS_6: return analog_axis[5];
|
||
|
case ANALOG_AXIS_7: return analog_axis[6];
|
||
|
case ANALOG_AXIS_8: return analog_axis[7];
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static BOOL is_button_pressed(GAME_BUTTON button)
|
||
|
{
|
||
|
switch (button)
|
||
|
{
|
||
|
case P1_BUTTON_1: return button_state[0];
|
||
|
case P1_BUTTON_2: return button_state[1];
|
||
|
case P1_BUTTON_3: return button_state[2];
|
||
|
case P1_BUTTON_4: return button_state[3];
|
||
|
case P1_BUTTON_5: return button_state[4];
|
||
|
case P1_BUTTON_6: return button_state[5];
|
||
|
case P1_BUTTON_7: return button_state[6];
|
||
|
case P1_BUTTON_8: return button_state[7];
|
||
|
case P2_BUTTON_1: return button_state[8];
|
||
|
case P2_BUTTON_2: return button_state[9];
|
||
|
case P2_BUTTON_3: return button_state[10];
|
||
|
case P2_BUTTON_4: return button_state[11];
|
||
|
case P2_BUTTON_5: return button_state[12];
|
||
|
case P2_BUTTON_6: return button_state[13];
|
||
|
case P2_BUTTON_7: return button_state[14];
|
||
|
case P2_BUTTON_8: return button_state[15];
|
||
|
case P1_JOYSTICK_UP: return joystick[0].up;
|
||
|
case P1_JOYSTICK_DOWN: return joystick[0].down;
|
||
|
case P1_JOYSTICK_LEFT: return joystick[0].left;
|
||
|
case P1_JOYSTICK_RIGHT: return joystick[0].right;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
OSD_CONTROLS* osd_input_update_controls(void)
|
||
|
{
|
||
|
int i;
|
||
|
INT32 mouse_x, mouse_y;
|
||
|
input_update();
|
||
|
|
||
|
controls.game_controls[0] = 0xFF;
|
||
|
controls.game_controls[1] = 0xFF;
|
||
|
controls.system_controls[0] = 0xFF;
|
||
|
controls.system_controls[1] = 0xFF;
|
||
|
|
||
|
// Lightgun
|
||
|
if(mouse_get_button(0))
|
||
|
controls.game_controls[0] &= ~0x01;
|
||
|
|
||
|
if(mouse_get_button(1))
|
||
|
controls.gun_acquired[0] = TRUE;
|
||
|
else
|
||
|
controls.gun_acquired[0] = FALSE;
|
||
|
|
||
|
mouse_get_position(&mouse_x, &mouse_y);
|
||
|
if (!m3_config.fullscreen)
|
||
|
{
|
||
|
controls.gun_x[0] = mouse_x + (400 - (MODEL3_SCREEN_WIDTH / 2));
|
||
|
controls.gun_y[0] = mouse_y + (272 - (MODEL3_SCREEN_HEIGHT / 2));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (m3_config.stretch)
|
||
|
{
|
||
|
mouse_x = (mouse_x * 496) / m3_config.width;
|
||
|
mouse_y = (mouse_y * 384) / m3_config.height;
|
||
|
}
|
||
|
|
||
|
controls.gun_x[0] = mouse_x + (400 - (MODEL3_SCREEN_WIDTH / 2));
|
||
|
controls.gun_y[0] = mouse_y + (272 - (MODEL3_SCREEN_HEIGHT / 2));
|
||
|
}
|
||
|
|
||
|
// Game controls
|
||
|
if (xbox_controllers[0])
|
||
|
{
|
||
|
update_controls_xbox();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
update_controls_keyboard();
|
||
|
}
|
||
|
|
||
|
// update button states
|
||
|
for (i=0; i < 16; i++)
|
||
|
{
|
||
|
if (m3_config.controls.button[i].enabled)
|
||
|
{
|
||
|
if (is_button_pressed(m3_config.controls.button[i].mapping))
|
||
|
{
|
||
|
int set = m3_config.controls.button[i].control_set;
|
||
|
controls.game_controls[set] &= ~m3_config.controls.button[i].control_bit;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// update analog controls
|
||
|
for (i=0; i < 8; i++)
|
||
|
{
|
||
|
if (m3_config.controls.analog_axis[i].enabled)
|
||
|
{
|
||
|
int value = get_analog_axis(m3_config.controls.analog_axis[i].mapping);
|
||
|
value += m3_config.controls.analog_axis[i].center;
|
||
|
controls.analog_axis[i] = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Lightgun hack for Star Wars Trilogy
|
||
|
if (stricmp(m3_config.game_id, "swtrilgy") == 0)
|
||
|
{
|
||
|
mouse_get_position(&mouse_x, &mouse_y);
|
||
|
|
||
|
mouse_x = (mouse_x * 256) / ((m3_config.fullscreen) ? m3_config.width : 496);
|
||
|
mouse_y = (mouse_y * 256) / ((m3_config.fullscreen) ? m3_config.height : 384);
|
||
|
|
||
|
controls.analog_axis[0] = mouse_y;
|
||
|
controls.analog_axis[1] = mouse_x;
|
||
|
|
||
|
if (mouse_get_button(1))
|
||
|
controls.game_controls[0] &= ~0x01;
|
||
|
if (mouse_get_button(0))
|
||
|
controls.game_controls[0] &= ~0x20;
|
||
|
}
|
||
|
|
||
|
// System controls
|
||
|
if (keyboard_get_key(DIK_F1)) // Service button
|
||
|
{
|
||
|
controls.system_controls[0] &= ~0x08;
|
||
|
}
|
||
|
if (keyboard_get_key(DIK_F2)) // Test button
|
||
|
{
|
||
|
controls.system_controls[0] &= ~0x04;
|
||
|
}
|
||
|
if (keyboard_get_key(DIK_F3)) // Service button B
|
||
|
{
|
||
|
controls.system_controls[1] &= ~0x40;
|
||
|
}
|
||
|
if (keyboard_get_key(DIK_F4)) // Test button B
|
||
|
{
|
||
|
controls.system_controls[1] &= ~0x80;
|
||
|
}
|
||
|
if (keyboard_get_key(DIK_1)) // Start button 1
|
||
|
{
|
||
|
controls.system_controls[0] &= ~0x10;
|
||
|
}
|
||
|
if (keyboard_get_key(DIK_2)) // Start button 2
|
||
|
{
|
||
|
controls.system_controls[0] &= ~0x20;
|
||
|
}
|
||
|
if (keyboard_get_key(DIK_5)) // Coin #1
|
||
|
{
|
||
|
controls.system_controls[0] &= ~0x01;
|
||
|
}
|
||
|
if (keyboard_get_key(DIK_6)) // Coin #2
|
||
|
{
|
||
|
controls.system_controls[0] &= ~0x02;
|
||
|
}
|
||
|
|
||
|
return &controls;
|
||
|
}
|