int multitap1 = 0;
int multitap2 = 0;
int in_enable_vibration = 1;
+int in_enable_crosshair[2] = { 0, 0 };
// NegCon adjustment parameters
// > The NegCon 'twist' action is somewhat awkward when mapped
}
#endif
+// Function to add crosshairs
+static void addCrosshair(int port, int crosshair_color, unsigned short *buffer, int bufferStride, int pos_x, int pos_y, int thickness, int size_x, int size_y) {
+ for (port = 0; port < 2; port++) {
+ // Draw the horizontal line of the crosshair
+ for (int i = pos_y - thickness / 2; i <= pos_y + thickness / 2; i++) {
+ for (int j = pos_x - size_x / 2; j <= pos_x + size_x / 2; j++) {
+ if ((i + vout_height) >= 0 && (i + vout_height) < bufferStride && j >= 0 && j < bufferStride && in_enable_crosshair[port] > 0)
+ buffer[i * bufferStride + j] = crosshair_color;
+ }
+ }
+
+ // Draw the vertical line of the crosshair
+ for (int i = pos_x - thickness / 2; i <= pos_x + thickness / 2; i++) {
+ for (int j = pos_y - size_y / 2; j <= pos_y + size_y / 2; j++) {
+ if (i >= 0 && i < bufferStride && (j + vout_height) >= 0 && (j + vout_height) < bufferStride && in_enable_crosshair[port] > 0)
+ buffer[j * bufferStride + i] = crosshair_color;
+ }
+ }
+ }
+}
+
+struct CrosshairInfo {
+ int pos_x, pos_y, thickness, size_x, size_y;
+};
+
+// Calculate size and position of crosshairs
+static void CrosshairDimensions(int port, struct CrosshairInfo *info) {
+ int gunx = input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X);
+ int guny = input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y);
+ if (gunx == 32767) // Prevent crosshairs from wrapping around right side of screen to left
+ info->pos_x = (gunx + 32767.0f) * vout_width / 65534.0f - 0.5f;
+ else
+ info->pos_x = (gunx + 32767.0f) * vout_width / 65534.0f;
+ info->pos_y = (guny + 32767.0f) * vout_height / 65534.0f - vout_height;
+ info->thickness = pl_rearmed_cbs.gpu_neon.enhancement_enable ? 4 : 2;
+ info->size_x = psx_w * (pl_rearmed_cbs.gpu_neon.enhancement_enable ? 2 : 1) / 40.0f;
+ info->size_y = psx_h * (pl_rearmed_cbs.gpu_neon.enhancement_enable ? 2 : 1) * (4.0f / 3.0f) / 40.0f;
+}
+
static void vout_flip(const void *vram, int stride, int bgr24,
int x, int y, int w, int h, int dims_changed)
{
unsigned short *dest = vout_buf_ptr;
const unsigned short *src = vram;
int dstride = vout_width, h1 = h;
+ int port = 0;
- if (vram == NULL || dims_changed)
+ if (vram == NULL || dims_changed || (in_enable_crosshair[0] + in_enable_crosshair[1]) > 0)
{
memset(vout_buf_ptr, 0, dstride * vout_height * 2);
// blanking
}
}
+ for (port = 0; port < 2; port++) {
+ if (in_enable_crosshair[port] > 0 && (in_type[port] == PSE_PAD_TYPE_GUNCON || in_type[port] == PSE_PAD_TYPE_GUN))
+ {
+ struct CrosshairInfo crosshairInfo;
+ CrosshairDimensions(port, &crosshairInfo);
+ addCrosshair(port, in_enable_crosshair[port], dest, dstride, crosshairInfo.pos_x, crosshairInfo.pos_y, crosshairInfo.thickness, crosshairInfo.size_x, crosshairInfo.size_y);
+ }
+ }
+
out:
#ifndef FRONTEND_SUPPORTS_RGB565
convert(vout_buf_ptr, vout_width * vout_height * 2);
}
}
+//Percentage distance of screen to adjust for Konami Gun
+static float KonamiGunAdjustX = 0;
+static float KonamiGunAdjustY = 0;
+
void pl_gun_byte2(int port, unsigned char byte)
{
+ int irq_count = 4;
+ float justifier_multiplier = 0;
+ int justifier_width = psx_w;
+ int justifier_height = psx_h;
+ int justifier_offscreen = input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN);
+ int justifier_reload = input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_RELOAD);
+
+ if (justifier_width == 256)
+ justifier_multiplier = is_pal_mode ? .157086f : .158532f;
+ else if (justifier_width == 320)
+ justifier_multiplier = is_pal_mode ? .196358f : .198166f;
+ else if (justifier_width == 384)
+ justifier_multiplier = is_pal_mode ? .224409f : .226475f;
+ else if (justifier_width == 512)
+ justifier_multiplier = is_pal_mode ? .314173f : .317065f;
+ else // (justifier_width == 640)
+ justifier_multiplier = is_pal_mode ? .392717f : .396332f;
+
+ int gunx = input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X);
+ int guny = input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y);
+
+ //Default offset of +105 for X and -12 for Y is chosen to obtain alignment in Die Hard Trilogy, which has no calibration feature
+ int gunx_scaled = ((gunx + 32767.0f) / 65534.0f + KonamiGunAdjustX) * justifier_width / justifier_multiplier + 105.0f;
+ int guny_scaled = ((guny + 32767.0f) / 65534.0f + KonamiGunAdjustY) * justifier_height - 12.0f;
+
+ if ((byte & 0x10) && !justifier_offscreen && !justifier_reload)
+ {
+ psxScheduleIrq10(irq_count, gunx_scaled, guny_scaled);
+ }
}
/* sound calls */
drv->feed = snd_feed;
}
-#define RETRO_DEVICE_PSE_STANDARD RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 0)
-#define RETRO_DEVICE_PSE_ANALOG RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_ANALOG, 0)
-#define RETRO_DEVICE_PSE_DUALSHOCK RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_ANALOG, 1)
-#define RETRO_DEVICE_PSE_NEGCON RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_ANALOG, 2)
-#define RETRO_DEVICE_PSE_GUNCON RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_LIGHTGUN, 0)
-#define RETRO_DEVICE_PSE_MOUSE RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_MOUSE, 0)
+#define RETRO_DEVICE_PSE_STANDARD RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 0)
+#define RETRO_DEVICE_PSE_ANALOG RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_ANALOG, 0)
+#define RETRO_DEVICE_PSE_DUALSHOCK RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_ANALOG, 1)
+#define RETRO_DEVICE_PSE_NEGCON RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_ANALOG, 2)
+#define RETRO_DEVICE_PSE_GUNCON RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_LIGHTGUN, 0)
+#define RETRO_DEVICE_PSE_JUSTIFIER RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_LIGHTGUN, 1)
+#define RETRO_DEVICE_PSE_MOUSE RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_MOUSE, 0)
static char *get_pse_pad_label[] = {
"none", "mouse", "negcon", "konami gun", "standard", "analog", "guncon", "dualshock"
};
-static const struct retro_controller_description pads[7] =
+static const struct retro_controller_description pads[8] =
{
- { "standard", RETRO_DEVICE_JOYPAD },
- { "analog", RETRO_DEVICE_PSE_ANALOG },
- { "dualshock", RETRO_DEVICE_PSE_DUALSHOCK },
- { "negcon", RETRO_DEVICE_PSE_NEGCON },
- { "guncon", RETRO_DEVICE_PSE_GUNCON },
- { "mouse", RETRO_DEVICE_PSE_MOUSE },
+ { "standard", RETRO_DEVICE_JOYPAD },
+ { "analog", RETRO_DEVICE_PSE_ANALOG },
+ { "dualshock", RETRO_DEVICE_PSE_DUALSHOCK },
+ { "negcon", RETRO_DEVICE_PSE_NEGCON },
+ { "guncon", RETRO_DEVICE_PSE_GUNCON },
+ { "konami gun", RETRO_DEVICE_PSE_JUSTIFIER },
+ { "mouse", RETRO_DEVICE_PSE_MOUSE },
{ NULL, 0 },
};
"pcsx_rearmed_negcon_deadzone",
"pcsx_rearmed_negcon_response",
"pcsx_rearmed_input_sensitivity",
+ "pcsx_rearmed_crosshair1",
+ "pcsx_rearmed_crosshair2",
+ "pcsx_rearmed_konamigunadjustx",
+ "pcsx_rearmed_konamigunadjusty",
"pcsx_rearmed_gunconadjustx",
"pcsx_rearmed_gunconadjusty",
"pcsx_rearmed_gunconadjustratiox",
case RETRO_DEVICE_PSE_GUNCON:
in_type[port] = PSE_PAD_TYPE_GUNCON;
break;
+ case RETRO_DEVICE_PSE_JUSTIFIER:
+ in_type[port] = PSE_PAD_TYPE_GUN;
+ break;
case RETRO_DEVICE_NONE:
default:
in_type[port] = PSE_PAD_TYPE_NONE;
{ port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_TRIGGER, "Gun Trigger" }, \
{ port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_RELOAD, "Gun Reload" }, \
{ port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_AUX_A, "Gun Aux A" }, \
- { port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_AUX_B, "Gun Aux B" },
+ { port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_AUX_B, "Gun Aux B" }, \
+ { port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_START, "Gun Start" },
JOYP(0)
JOYP(1)
};
#define RETRO_PSX_MAP_LEN (sizeof(retro_psx_map) / sizeof(retro_psx_map[0]))
-//Percentage distance of screen to adjust
+//Percentage distance of screen to adjust for Guncon
static int GunconAdjustX = 0;
static int GunconAdjustY = 0;
-//Used when out by a percentage
+//Used when out by a percentage with Guncon
static float GunconAdjustRatioX = 1;
static float GunconAdjustRatioY = 1;
}
#endif // GPU_UNAI
+ var.value = NULL;
+ var.key = "pcsx_rearmed_crosshair1";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ in_enable_crosshair[0] = 0;
+ else if (strcmp(var.value, "blue") == 0)
+ in_enable_crosshair[0] = 0x1F;
+ else if (strcmp(var.value, "green") == 0)
+ in_enable_crosshair[0] = 0x7E0;
+ else if (strcmp(var.value, "red") == 0)
+ in_enable_crosshair[0] = 0xF800;
+ else if (strcmp(var.value, "white") == 0)
+ in_enable_crosshair[0] = 0xFFFF;
+ }
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_crosshair2";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ in_enable_crosshair[1] = 0;
+ else if (strcmp(var.value, "blue") == 0)
+ in_enable_crosshair[1] = 0x1F;
+ else if (strcmp(var.value, "green") == 0)
+ in_enable_crosshair[1] = 0x7E0;
+ else if (strcmp(var.value, "red") == 0)
+ in_enable_crosshair[1] = 0xF800;
+ else if (strcmp(var.value, "white") == 0)
+ in_enable_crosshair[1] = 0xFFFF;
+ }
+
//This adjustment process gives the user the ability to manually align the mouse up better
//with where the shots are in the emulator.
+ var.value = NULL;
+ var.key = "pcsx_rearmed_konamigunadjustx";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ KonamiGunAdjustX = atof(var.value) / 100.0f;
+ }
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_konamigunadjusty";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ KonamiGunAdjustY = atof(var.value) / 100.0f;
+ }
+
var.value = NULL;
var.key = "pcsx_rearmed_gunconadjustx";
static void update_input_guncon(int port, int ret)
{
//ToDo:
- //Core option for cursors for both players
//Separate pointer and lightgun control types
//Mouse range is -32767 -> 32767
}
+static void update_input_justifier(int port, int ret)
+{
+ //ToDo:
+ //Separate pointer and lightgun control types
+
+ //RetroArch lightgun range is -32767 -> 32767 on both axes (positive Y is down)
+
+ //JUSTIFIER has 3 controls, Trigger,Special,Start which equal Square,Cross,Start
+
+ // Trigger
+ if (input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_TRIGGER) || input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_RELOAD))
+ in_keystate[port] |= (1 << DKEY_SQUARE);
+
+ // Special
+ if (input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_AUX_A))
+ in_keystate[port] |= (1 << DKEY_CROSS);
+
+ // Start
+ if (input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_START))
+ in_keystate[port] |= (1 << DKEY_START);
+
+}
+
static void update_input_negcon(int port, int ret)
{
int lsx;
case PSE_PAD_TYPE_GUNCON:
update_input_guncon(i, ret);
break;
+ case PSE_PAD_TYPE_GUN:
+ update_input_justifier(i, ret);
+ break;
case PSE_PAD_TYPE_NEGCON:
update_input_negcon(i, ret);
break;