Hi, sorry for replying to such a old thread but i have been trying to make a steering wheel hack for hard drivin's airborne i managed to stop the bug in the new version of mame that made the car do donuts and the same for street drivin' and i managed to get the brake input working on it so it's now playable but hard Drivin's Airborne does this weird thing where the steering goes out of alignment when you crash the car and hold the wheel left or right untill the car respawns. When you crash the car the wheel edge value gets reset to =0 and the game seems to use the position the wheel was in at that moment to set a new center point.
I was able to make a code mod that applied a offset to recenter it when this happens but once the offset is greater than 127 the wheel starts pulling to one side badly again. I tried forcing the center value of the wheels port_minmax to be sent as the wheel position at the exact moment that wheel edge =0 and then watches for wheel movement going past the center point to set it to 1 again as usual but that code doesnt seem to work maybe because the game reads the wheel positions value too fast before the mame driver can intercept it? I've been told that Hard Drivin's Airborne uses a spinner wheel in the original prototype hardware and that this is the reason why only this game has this behaviour. All the other hard drivin's/race drivin's are working fine.
Street drivin would make the car go in circles and i modded the code for that and i fixed the brake input being mapped to the wrong 8 bit ADC channel and the steering fix works on airborne to stop the car going in circles too and it's been merged into the latest version of the mame source code on github but i've been trying now for a couple of weeks to fix this bug in airborne and cannot get my code to work it's close but the maths behind it just doesn't work. I googled some keywords to see if i could find more info and found this post from 2013 where you seem to have basically made a fix for the old version of mame that im sure could fix the wheel alignment problem in Hard Drivin's Airborne. I cannot work out how to get your older code to be modified correctly to work in the latest version of mame and was wondering if you could maybe have a look at it again?
I'll post my almost working code below. It's replacing the wheel latch code in the harddriv.cpp file. I'm using a Logitech G923 wheel.
uint16_t harddriv_state::hdc68k_wheel_r()
{
static const uint16_t g_latchpoint = 0x800; // Central point for wheel detection.
static int16_t wheel_offset = 0; // Cumulative offset to adjust the wheel position based on game events.
static bool last_wheel_edge = false; // To track the last state of crossing the center.
// Read the current wheel position from the 12-bit ADC port.
uint16_t new_wheel_raw = m_12badc[0].read_safe(0xffff);
// Apply the cumulative offset to align with the game's perceived center.
int16_t new_wheel = static_cast<int16_t>(new_wheel_raw) + wheel_offset;
// Clamping the wheel position to avoid overflow and keep it within expected range. I found out that this helped stop the steering drifting off center when you hit the 2nd last checkpoint on the mountain track.
const uint16_t min_clamp_value = 0x063A; // Observed minimum value when wheel is turned all the way to the right
const uint16_t max_clamp_value = 0x09C6; // Observed maximum value when wheel is turned all the way to the left
if (new_wheel < min_clamp_value) new_wheel = min_clamp_value;
if (new_wheel > max_clamp_value) new_wheel = max_clamp_value;
// Edge detection logic to detect being at or crossing the center point using raw ADC data.
if ((m_hdc68k_last_wheel < g_latchpoint && new_wheel_raw >= g_latchpoint) ||
(m_hdc68k_last_wheel > g_latchpoint && new_wheel_raw <= g_latchpoint) ||
new_wheel_raw == g_latchpoint) {
m_hdc68k_wheel_edge = 1; // Set edge flag when at or crossing the center based on raw input.
}
// Check if the wheel edge flag has changed from 1 to 0, as reset by the game.
if (last_wheel_edge && !m_hdc68k_wheel_edge) {
int16_t new_offset_adjustment = g_latchpoint - new_wheel_raw; // Calculate the offset adjustment
new_offset_adjustment /= 1; // Significantly reduce the impact of each adjustment
wheel_offset += (new_wheel_raw > g_latchpoint) ? -new_offset_adjustment : new_offset_adjustment;
wheel_offset = std::clamp(wheel_offset, static_cast<int16_t>(-0xfff), static_cast<int16_t>(0xfff)); // Cap the offset to 3-digit hex range
new_wheel = static_cast<int16_t>(new_wheel_raw) + wheel_offset; // Reapply the updated offset.
// Re-clamp the wheel after offset adjustment
if (new_wheel < min_clamp_value) new_wheel = min_clamp_value;
if (new_wheel > max_clamp_value) new_wheel = max_clamp_value;
}
last_wheel_edge = m_hdc68k_wheel_edge; // Store the last known state of the wheel edge flag.
// Display current wheel information for debugging.
popmessage("Wheel Raw: %04X, Wheel Adjusted: %04X, Edge: %d, Offset: %04X (Hex), %d (Dec)",
new_wheel_raw, new_wheel, m_hdc68k_wheel_edge, static_cast<uint16_t>(wheel_offset & 0xFFFF), wheel_offset);
// Store the current wheel value for the next comparison.
m_hdc68k_last_wheel = new_wheel_raw;
// Return the processed wheel value, formatted as required.
return (static_cast<uint16_t>(new_wheel) << 8) | 0xff;
}