psx - hook up a hardcoded dualshock input.. maybe some things are mismapped, dont know yet

This commit is contained in:
zeromus 2014-12-10 23:43:11 +00:00
parent ab312add39
commit 1dc8a00771
7 changed files with 265 additions and 31 deletions

View File

@ -1,6 +1,7 @@
//TODO hook up newer file ID stuff, think about how to combine it with the disc ID
//TODO change display manager to not require 0xFF alpha channel set on videoproviders. check gdi+ and opengl! this will get us a speedup in some places
//TODO Disc.Structure.Sessions[0].length_aba was 0
//TODO disc lights
using System;
using System.Runtime.InteropServices;
@ -22,7 +23,31 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
public unsafe class Octoshock : IEmulator, IVideoProvider, ISoundProvider
{
public string SystemId { get { return "NULL"; } }
public static readonly ControllerDefinition NullController = new ControllerDefinition { Name = "Null Controller" };
public static readonly ControllerDefinition DualShockController = new ControllerDefinition
{
Name = "DualShock Controller",
BoolButtons =
{
"Up", "Down", "Left", "Right",
"Select", "Start",
"Square", "Triangle", "Circle", "Cross",
"L1", "R1", "L2", "R2", "L3", "R3",
"MODE",
},
FloatControls =
{
"LStick X", "LStick Y",
"RStick X", "RStick Y",
},
FloatRanges =
{
new[] {0.0f, 128.0f, 255.0f},
new[] {255.0f, 128.0f, 0.0f},
new[] {0.0f, 128.0f, 255.0f},
new[] {255.0f, 128.0f, 0.0f},
}
};
public string BoardName { get { return null; } }
@ -185,6 +210,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
OctoshockDll.shock_OpenTray(psx);
OctoshockDll.shock_SetDisc(psx, discInterface.OctoshockHandle);
OctoshockDll.shock_CloseTray(psx);
OctoshockDll.shock_Peripheral_Connect(psx, 0x01, OctoshockDll.ePeripheralType.DualShock);
OctoshockDll.shock_PowerOn(psx);
}
@ -219,8 +245,43 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
Frame = 0;
}
void SetInput()
{
uint buttons = 0;
//dualshock style
if(Controller["Select"]) buttons |= 1;
if (Controller["L3"]) buttons |= 2;
if (Controller["R3"]) buttons |= 4;
if (Controller["Start"]) buttons |= 8;
if (Controller["Up"]) buttons |= 16;
if (Controller["Right"]) buttons |= 32;
if (Controller["Down"]) buttons |= 64;
if (Controller["Left"]) buttons |= 128;
if (Controller["L2"]) buttons |= 256;
if (Controller["R2"]) buttons |= 512;
if (Controller["L1"]) buttons |= 1024;
if (Controller["R1"]) buttons |= 2048;
if (Controller["Triangle"]) buttons |= 4096;
if (Controller["Circle"]) buttons |= 8192;
if (Controller["Cross"]) buttons |= 16384;
if (Controller["Square"]) buttons |= 32768;
if (Controller["MODE"]) buttons |= 65536;
byte left_x = (byte)Controller.GetFloat("LStick X");
byte left_y = (byte)Controller.GetFloat("LStick Y");
byte right_x = (byte)Controller.GetFloat("RStick X");
byte right_y = (byte)Controller.GetFloat("RStick Y");
OctoshockDll.shock_Peripheral_SetPadInput(psx, 0x01, buttons, left_x, left_y, right_x, right_y);
}
public void FrameAdvance(bool render, bool rendersound)
{
Frame++;
SetInput();
OctoshockDll.shock_Step(psx, OctoshockDll.eShockStep.Frame);
OctoshockDll.ShockFramebufferInfo fb = new OctoshockDll.ShockFramebufferInfo();
@ -251,10 +312,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
}
}
[FeatureNotImplemented]
public ControllerDefinition ControllerDefinition { get { return NullController; } }
[FeatureNotImplemented]
public ControllerDefinition ControllerDefinition { get { return DualShockController; } }
public IController Controller { get; set; }
public int Frame

View File

@ -1,5 +1,4 @@
//API TODO
//get rid of the 2048 byte reader
//TODO - make sure msvc builds with 32bit enums and get rid of the extra marshalling fluff here
using System;
using System.Runtime.InteropServices;
@ -25,9 +24,21 @@ public unsafe static class OctoshockDll
Normalize = 1
}
public enum ePeripheralType
{
None = 0, //can be used to signify disconnection
Pad = 1, //SCPH-1080
DualShock = 2, //SCPH-1200
DualAnalog = 3, //SCPH-1180
Multitap = 10,
};
public const int SHOCK_OK = 0;
public const int SHOCK_ERROR = -1;
public const int SHOCK_NOCANDO = -2;
public const int SHOCK_INVALID_ADDRESS = -3;
[StructLayout(LayoutKind.Sequential)]
public struct ShockDiscInfo
@ -82,6 +93,17 @@ public unsafe static class OctoshockDll
[DllImport("octoshock.dll")]
public static extern int shock_Destroy(IntPtr psx);
[DllImport("octoshock.dll")]
public static extern int shock_Peripheral_Connect(
IntPtr psx,
int address,
[MarshalAs(UnmanagedType.I4)] ePeripheralType type
);
[DllImport("octoshock.dll")]
public static extern int shock_Peripheral_SetPadInput(IntPtr psx, int address, uint buttons, byte left_x, byte left_y, byte right_x, byte right_y);
[DllImport("octoshock.dll")]
public static extern int shock_PowerOn(IntPtr psx);

View File

@ -629,6 +629,25 @@
"P2 A": "",
"Power": ""
},
"DualShock Controller": {
"Up": "X1 DpadUp,UpArrow",
"Down": "X1 DpadDown,DownArrow",
"Left": "X1 DpadLeft,LeftArrow",
"Right": "X1 DpadRight,RightArrow",
"Select": "X1 Back,Space",
"Start": "X1 Start,Return",
"Square": "X1 X,A",
"Triangle": "X1 Y,S",
"Circle": "X1 B,X",
"Cross": "X1 A,Z",
"L1": "X1 LeftShoulder,Q",
"R1": "X1 RightShoulder,W",
"L2": "X1 LeftTrigger,E",
"R2": "X1 RightTrigger,R",
"L3": "X1 LeftThumb,T",
"R3": "X1 RightThumb,Y",
"MODE": "A"
},
"Lynx Controller": {
"Up": "UpArrow",
"Down": "DownArrow",
@ -942,6 +961,28 @@
}
},
"WonderSwan Controller": {},
"Lynx Controller": {}
"Lynx Controller": {},
"DualShock Controller": {
"LStick X": {
"Value": "X1 LeftThumbX",
"Mult": 1.0,
"Deadzone": 0.1
},
"LStick Y": {
"Value": "X1 LeftThumbY",
"Mult": 1.0,
"Deadzone": 0.1
},
"RStick X": {
"Value": "X1 RightThumbX",
"Mult": 1.0,
"Deadzone": 0.1
},
"RStick Y": {
"Value": "X1 RightThumbY",
"Mult": 1.0,
"Deadzone": 0.1
}
}
}
}

Binary file not shown.

View File

@ -291,19 +291,24 @@ void InputDevice_DualShock::UpdateInput(const void *data)
buttons[1] = d8[1];
cur_ana_button_state = d8[2] & 0x01;
for(int stick = 0; stick < 2; stick++)
{
for(int axis = 0; axis < 2; axis++)
{
const uint8* aba = &d8[3] + stick * 8 + axis * 4;
int32 tmp;
//OCTOSHOCK EDIT - so we can set values directly
//for(int stick = 0; stick < 2; stick++)
//{
// for(int axis = 0; axis < 2; axis++)
// {
// //const uint8* aba = &d8[3] + stick * 8 + axis * 4;
// //int32 tmp;
tmp = 32767 + MDFN_de16lsb(&aba[0]) - MDFN_de16lsb(&aba[2]);
tmp = (tmp * 0x100) / 0xFFFF;
// //tmp = 32767 + MDFN_de16lsb(&aba[0]) - MDFN_de16lsb(&aba[2]);
// //tmp = (tmp * 0x100) / 0xFFFF;
//
// }
//}
axes[0][0] = d8[3];
axes[0][1] = d8[4];
axes[1][0] = d8[5];
axes[1][1] = d8[6];
axes[stick][axis] = tmp;
}
}
//printf("%3d:%3d, %3d:%3d\n", axes[0][0], axes[0][1], axes[1][0], axes[1][1]);

View File

@ -1323,6 +1323,98 @@ struct ShockState
bool power;
} s_ShockState;
struct ShockPeripheral
{
ePeripheralType type;
u8 buffer[16];
};
struct {
ShockPeripheral ports[2];
void Initialize()
{
for(int i=0;i<2;i++)
{
ports[i].type = ePeripheralType_None;
memset(ports[i].buffer,0,sizeof(ports[i].buffer));
}
}
s32 Connect(s32 address, s32 type)
{
//check the port address
int portnum = address&1;
if(portnum != 1 && portnum != 2)
return SHOCK_INVALID_ADDRESS;
portnum--;
//check whats already there
if(ports[portnum].type == ePeripheralType_None && type == ePeripheralType_None) return SHOCK_OK; //NOP
if(ports[portnum].type != ePeripheralType_None && type != ePeripheralType_None) return SHOCK_NOCANDO; //cant re-connect something without disconnecting first
//disconnecting:
if(type == ePeripheralType_None) {
ports[portnum].type = ePeripheralType_None;
memset(ports[portnum].buffer,0,sizeof(ports[portnum].buffer));
FIO->SetInput(portnum, "none", ports[portnum].buffer);
return SHOCK_OK;
}
//connecting:
const char* name = NULL;
switch(type)
{
case ePeripheralType_Pad: name = "gamepad"; break;
case ePeripheralType_DualShock: name = "dualshock"; break;
case ePeripheralType_DualAnalog: name = "dualanalog"; break;
default:
return SHOCK_ERROR;
}
ports[portnum].type = (ePeripheralType)type;
memset(ports[portnum].buffer,0,sizeof(ports[portnum].buffer));
FIO->SetInput(portnum, name, ports[portnum].buffer);
return SHOCK_OK;
}
s32 SetPadInput(s32 address, u32 buttons, u8 left_x, u8 left_y, u8 right_x, u8 right_y)
{
//check the port address
int portnum = address&1;
if(portnum != 1 && portnum != 2)
return SHOCK_INVALID_ADDRESS;
portnum--;
u8* buf = ports[portnum].buffer;
switch(ports[portnum].type)
{
case ePeripheralType_DualShock:
buf[0] = (buttons>>0)&0xFF;
buf[1] = (buttons>>8)&0xFF;
buf[2] = (buttons>>16)&0xFF; //this is only the analog mode button
buf[3] = left_x;
buf[4] = left_y;
buf[3] = right_x;
buf[4] = right_y;
break;
}
}
} s_ShockPeripheralState;
EW_EXPORT s32 shock_Peripheral_Connect(void* psx, s32 address, s32 type)
{
return s_ShockPeripheralState.Connect(address,type);
}
EW_EXPORT s32 shock_Peripheral_SetPadInput(void* psx, s32 address, u32 buttons, u8 left_x, u8 left_y, u8 right_x, u8 right_y)
{
return s_ShockPeripheralState.SetPadInput(address, buttons, left_x, left_y, right_x, right_y);
}
static void MountCPUAddressSpace()
{
for(uint32 ma = 0x00000000; ma < 0x00800000; ma += 2048 * 1024)
@ -1350,7 +1442,7 @@ static bool s_FramebufferNormalized;
static int s_FramebufferCurrent;
static int s_FramebufferCurrentWidth;
EW_EXPORT s32 shock_Create(void** psx, eRegion region, void* firmware512k)
EW_EXPORT s32 shock_Create(void** psx, s32 region, void* firmware512k)
{
//NEW
*psx = NULL;
@ -1413,6 +1505,7 @@ EW_EXPORT s32 shock_Create(void** psx, eRegion region, void* firmware512k)
static bool emulate_memcard[8] = {0};
static bool emulate_multitap[2] = {0};
FIO = new FrontIO(emulate_memcard, emulate_multitap);
s_ShockPeripheralState.Initialize();
MountCPUAddressSpace();
@ -2188,15 +2281,6 @@ static void CloseGame(void)
Cleanup();
}
static void SetInput(int port, const char *type, void *ptr)
{
if(psf_loader)
FIO->SetInput(port, "none", NULL);
else
FIO->SetInput(port, type, ptr);
}
static int StateAction(StateMem *sm, int load, int data_only)
{
@ -3080,4 +3164,4 @@ s32 ShockDiscRef::ReadLBA2048(s32 lba, void* dst2048)
memcpy(dst2048,xasector.form1.data2048,2048);
return sector.mode;
}
}

View File

@ -131,6 +131,17 @@ enum eShockFramebufferFlags
eShockFramebufferFlags_Normalize = 1
};
enum ePeripheralType
{
ePeripheralType_None = 0, //can be used to signify disconnection
ePeripheralType_Pad = 1, //SCPH-1080
ePeripheralType_DualShock = 2, //SCPH-1200
ePeripheralType_DualAnalog = 3, //SCPH-1180
ePeripheralType_Multitap = 10,
};
enum eShockSetting
{
REGION_AUTODETECT = 0,
@ -152,6 +163,7 @@ int shock_GetSetting(eShockSetting setting);
#define SHOCK_OK 0
#define SHOCK_ERROR -1
#define SHOCK_NOCANDO -2
#define SHOCK_INVALID_ADDRESS -3
struct ShockTOCTrack
{
@ -230,11 +242,23 @@ EW_EXPORT s32 shock_AnalyzeDisc(ShockDiscRef* disc, ShockDiscInfo* info);
//Creates the psx instance as a console of the specified region.
//Additionally mounts the firmware from the provided buffer (the contents are copied)
//TODO - receive a model number parameter instead
EW_EXPORT s32 shock_Create(void** psx, eRegion region, void* firmware512k);
EW_EXPORT s32 shock_Create(void** psx, s32 region, void* firmware512k);
//Frees the psx instance created with shock_Create
EW_EXPORT s32 shock_Destroy(void* psx);
//Attaches (or detaches) a peripheral at the given address.
//Send ePeripheralType_None to detach.
//Do not attach when something is already attached.
//You can detach when nothing is attached.
//Returns SHOCK_NOCANDO if something inappropriate is done.
//Presently this has only been validated as functioning correctly before the initial PowerOn, but we would like to use it other times.
EW_EXPORT s32 shock_Peripheral_Connect(void* psx, s32 address, s32 type);
//Sets pad-type input (pad,dualshock,dualanalog) on the specified address;
//Read more about the input format (buttons, analog range) here: TBD
EW_EXPORT s32 shock_Peripheral_SetPadInput(void* psx, s32 address, u32 buttons, u8 left_x, u8 left_y, u8 right_x, u8 right_y);
//Sets the power to ON. Returns SHOCK_NOCANDO if already on.
EW_EXPORT s32 shock_PowerOn(void* psx);