Skip to content
This repository has been archived by the owner on Oct 11, 2020. It is now read-only.

Commit

Permalink
Properly fix Dualshock & Digital Pad issues in games.
Browse files Browse the repository at this point in the history
Also allows games that don't require the Dualshock to make
use of the analog stick.
Hopefully it should work OK now...
  • Loading branch information
gameblabla committed Oct 7, 2019
1 parent 198ebfc commit 14eac42
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 28 deletions.
83 changes: 58 additions & 25 deletions src/pad.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@
#include "psxmem.h"
#include "r3000a.h"

unsigned char CurPad = 0, CurCmd = 0;
unsigned char configmode[2] = {0, 0}, padmode[2] = {0, 0};
unsigned char padid[2] = {0x41, 0x41};
uint8_t CurPad = 0, CurCmd = 0;
uint8_t configmode[2] = {0, 0}, padmode[2] = {0, 0}, pad_controllertype[2] = {0, 0};
uint8_t Vib[2][2];
uint8_t VibF[2][2];

typedef struct tagGlobalData
{
Expand Down Expand Up @@ -82,53 +83,48 @@ static uint8_t unk4d[8] = {0xFF, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

unsigned char PAD1_poll(unsigned char value) {
static uint8_t buf[8] = {0xFF, 0x5A, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80};
uint32_t size_buf = 8;
uint8_t changed = 0;
uint8_t i;

if (g.CurByte1 == 0) {
uint16_t n;
g.CurByte1++;

n = pad_read(0);

g.CmdLen1 = 8;

// Don't enable Analog/Vibration for a standard pad
if (player_controller[0].id == 0x41) {
if (player_controller[0].id == 0x41)
{
CurCmd = CMD_READ_DATA_AND_VIBRATE;
g.CmdLen1 = 4;
}
else
{
CurCmd = value;
}



switch (CurCmd)
{
case CMD_SET_MODE_AND_LOCK:
memcpy(buf, stdmode, 8);
return 0xF3;
return 0xF3;
case CMD_QUERY_MODEL_AND_MODE:
memcpy(buf, stdmodel, 8);
buf[4] = 0x01;
return 0xF3;
return 0xF3;
case CMD_QUERY_ACT:
memcpy(buf, unk46, 8);
return 0xF3;

case CMD_QUERY_COMB:
memcpy(buf, unk47, 8);
return 0xF3;

case CMD_QUERY_MODE:
memcpy(buf, unk4c, 8);
return 0xF3;

case CMD_VIBRATION_TOGGLE:
memcpy(buf, unk4d, 8);
return 0xF3;

case CMD_CONFIG_MODE:
if (configmode[0]) {
memcpy(buf, stdcfg, 8);
Expand All @@ -137,20 +133,25 @@ unsigned char PAD1_poll(unsigned char value) {
// else FALLTHROUGH
case CMD_READ_DATA_AND_VIBRATE:
default:

buf[2] = n & 0xFF;
buf[3] = n >> 8;
if (padmode[0] == 1)

/* Make sure that in Digital mode that lengh is 4, not 8 for the 2 analogs.
* This must be done here and not before otherwise, it might not enter the switch loop
* and Dualshock features won't work.
* */
if (pad_controllertype[0] == 0) g.CmdLen1 = 4;

if (g.CmdLen1 > 4)
{
buf[4] = player_controller[0].joy_right_ax0;
buf[5] = player_controller[0].joy_right_ax1;
buf[6] = player_controller[0].joy_left_ax0;
buf[7] = player_controller[0].joy_left_ax1;
}
break;
}
return pad_controllertype[0] ? player_controller[0].id : 0x41;
}

return padid[0];

}

if (g.CurByte1 >= g.CmdLen1)
Expand All @@ -166,8 +167,7 @@ unsigned char PAD1_poll(unsigned char value) {

case CMD_SET_MODE_AND_LOCK:
padmode[0] = value;
/* Required to fix games that don't properly support the Dualshock */
padid[0] = value ? 0x73 : 0x41;
player_controller[0].id = value ? 0x73 : 0x41;
break;

case CMD_QUERY_ACT:
Expand All @@ -188,16 +188,49 @@ unsigned char PAD1_poll(unsigned char value) {
case CMD_QUERY_MODE:
switch (value) {
case 0: // mode 0 - digital mode
buf[5] = PSE_PAD_TYPE_STANDARD;
pad_controllertype[0] = buf[5] = PSE_PAD_TYPE_STANDARD;
break;

case 1: // mode 1 - analog mode
buf[5] = PSE_PAD_TYPE_ANALOGPAD;
pad_controllertype[0] = buf[5] = PSE_PAD_TYPE_ANALOGPAD;
break;
}
break;
}
}

if (pad_controllertype[0] == PSE_PAD_TYPE_ANALOGPAD)
{
switch (CurCmd)
{
case CMD_READ_DATA_AND_VIBRATE:
for (i = 0; i < 2; i++) {
if (Vib[0][i] == g.CurByte1
&& VibF[0][i] != value) {
VibF[0][i] = value;
changed = 1;
}
}

/* Could be used later if Rumble is fixed later on. */
/*if (!in_enable_vibration || !changed)
break;
plat_trigger_vibrate(CurPad, VibF[0][0], VibF[0][1]);*/
break;
case CMD_VIBRATION_TOGGLE:
for (i = 0; i < 2; i++) {
if (Vib[0][i] == g.CurByte1)
buf[g.CurByte1] = 0;
}
if (value < 2) {
Vib[0][value] = g.CurByte1;
if((player_controller[0].id & 0x0f) < (g.CurByte1 - 1) / 2) {
player_controller[0].id = (player_controller[0].id & 0xf0) + (g.CurByte1 - 1) / 2;
}
}
break;
}
}

return buf[g.CurByte1++];
}
Expand Down
12 changes: 9 additions & 3 deletions src/port/sdl/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,11 @@ void config_load()
sscanf(arg, "%d", &value);
Config.AnalogArrow = value;
}
else if (!strcmp(line, "Analog_Mode"))
{
sscanf(arg, "%d", &value);
Config.Analog_Mode = value;
}
#ifdef SPU_PCSXREARMED
else if (!strcmp(line, "SpuUseInterpolation"))
{
Expand Down Expand Up @@ -441,12 +446,13 @@ void config_save()
"ShowFps %d\n"
"FrameLimit %d\n"
"FrameSkip %d\n"
"AnalogArrow %d\n",
"AnalogArrow %d\n"
"Analog_Mode %d\n",
CONFIG_VERSION, Config.Xa, Config.Mdec, Config.PsxAuto,
Config.Cdda, Config.HLE, Config.RCntFix, Config.VSyncWA,
Config.Cpu, Config.PsxType, Config.SpuIrq, Config.SyncAudio,
Config.SpuUpdateFreq, Config.ForcedXAUpdates, Config.ShowFps, Config.FrameLimit,
Config.FrameSkip, Config.AnalogArrow);
Config.FrameSkip, Config.AnalogArrow, Config.Analog_Mode);

#ifdef SPU_PCSXREARMED
fprintf(f, "SpuUseInterpolation %d\n", spu_config.iUseInterpolation);
Expand Down Expand Up @@ -489,6 +495,7 @@ void config_save()
fprintf(f, "Bios %s\n", Config.Bios);
}

fsync(f);
fclose(f);
}

Expand Down Expand Up @@ -550,7 +557,6 @@ static unsigned short analog1 = 0,tmp_axis=0;
static int menu_check = 0;
static int select_count = 0;
uint8_t use_speedup = 0;
static uint16_t id=0x5A41,joy_l = 0x8080,joy_r = 0x8080;
SDL_Joystick * sdl_joy[2];
#define joy_commit_range 2048
enum
Expand Down

0 comments on commit 14eac42

Please sign in to comment.