Hi geecab i managed to combine your code with my code so that my mods only get applied if airborne is loaded up in mame but all the others will use your code. I'm wondering if i should maybe add street drivin' to it because it kinda had a similar issue but not as bad. I notice if i only shift the output left by 7 bits instead of 8 the steering in airborne becomes more like the original games and you can get away with using a port_minmax of 0x000, 0x7ff with a center point of 0x400 or 0x400, 0xbff with a center point of 0x800. It applied EMA smoothing to the wheel output so that it doesn't fluctuate too wildly when turning the wheel and seems to make the wheel stay in alignment when driving for long periods but crashing and holding the wheel left or right or staying offroad until the timer runs out with the wheel held left or right will knock the centerpoint out of place even if you have the wheel only turned a little bit.
Code: [Select]
// Merge in the wheel edge latch bit
if (m_hdc68k_wheel_edge)
{
result ^= 0x4000;
printf("hdc68k_port1_r: merge latch result=%04X m_hdc68k_last_wheel=%04X\n", result, m_hdc68k_last_wheel);
m_hdc68k_wheel_edge = 0;
}
m_hdc68k_last_port1 = result;
return result;
}
uint16_t harddriv_state::hda68k_port1_r()
{
uint16_t result = m_a80000->read();
if (m_hdc68k_wheel_edge)
{
result ^= 0x4000;
printf("hda68k_port1_r: merge latch result=%04X m_hdc68k_last_wheel=%04X\n", result, m_hdc68k_last_wheel);
m_hdc68k_wheel_edge = 0;
}
return result;
}
uint16_t harddriv_state::hdc68k_wheel_r()
{
static float ema_wheel = 0.0f; // Persistent storage of EMA across calls
static const float alpha = 0.05f; // Smoothing factor for EMA, adjustable
static bool initialized = false; // To check if ema_wheel is initialized
uint16_t new_wheel = m_12badc[0].read_safe(0xffff);
// Display the wheel position when left shift is pressed
if (machine().input().code_pressed(KEYCODE_LSHIFT))
{
popmessage("wheel new=%04X", new_wheel);
}
// Determine if the current game is Hard Drivin's Airborne
bool is_hdrivair = (machine().system().name == std::string("hdrivair"));
// Edge detection logic with condition for Hard Drivin's Airborne
if (is_hdrivair)
{
// Use a specific mask for Hard Drivin's Airborne
if ((m_hdc68k_last_wheel & 0x0c00) != (new_wheel & 0x0c00))
{
m_hdc68k_wheel_edge = m_hdc68k_wheel_edge == 0 ? 1 : 0;
}
}
else
{
// Use the default mask for other games
if ((m_hdc68k_last_wheel & 0x0c00) != (new_wheel & 0x0c00))
{
m_hdc68k_wheel_edge = m_hdc68k_wheel_edge == 0 ? 1 : 0;
}
}
if (is_hdrivair)
{
// EMA calculation only for Hard Drivin's Airborne
if (!initialized)
{
ema_wheel = new_wheel; // Initialize EMA with the first reading
initialized = true;
}
else
{
ema_wheel = alpha * new_wheel + (1 - alpha) * ema_wheel; // Update EMA
}
}
else
{
// For other games, use the raw wheel data without EMA
ema_wheel = new_wheel;
}
m_hdc68k_last_wheel = new_wheel;
// Calculate the output based on whether Hard Drivin's Airborne is being played
uint16_t ema_output;
if (is_hdrivair)
{
// Shift left by 7 for hdrivair
ema_output = static_cast<uint16_t>(ema_wheel) << 7;
}
else
{
// Shift left by 8 for other games
ema_output = static_cast<uint16_t>(ema_wheel) << 8;
}
ema_output &= 0xFFF0; // Mask to clear the last hexadecimal digit
// Return the EMA-adjusted wheel value, with the last digit zeroed
return ema_output;
// return (static_cast<uint16_t>(ema_wheel) << 8) & 0xFF00; /* << 8) | 0xff; */
}