Main > Driving & Racing Cabinets

Mame hacks that make driving games play better with mouse/spinner/360wheel

<< < (13/22) > >>

geecab:
Wow! Well done Yolo, sounds like progress at last!! :) Can't wait to see the changes :)

Yolo_Swaggins:

--- Quote from: geecab on April 23, 2024, 05:40:25 am ---Wow! Well done Yolo, sounds like progress at last!! :) Can't wait to see the changes :)

--- End quote ---

I still haven't got round to using the info you gave me on Airborne im using my older hack to get that working and added differennt wheel sensitivities /port_minmax's through a dip switch menu that changes your wheel to a different calibration and goes through EMA filtering. The fix for the compact version of race drivin' was easier than i thought lol. The test menu calibration is still gimped but you can just skip it.

https://github.com/Madcadden/mame/tree/Madcadden-Hard-Drivin-Race-Drivin-MAME-Build


--- Code: ---PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_CUSTOM )  PORT_TOGGLE PORT_NAME("Center Wheel Edge")  /* center edge on steering wheel, IPT_ACTIVE_HIGH fixes the steering alignment in game! */

--- End code ---


--- Code: ---#include <numeric>  // For std::accumulate

// Function to calculate the Exponential Moving Average (EMA)
uint16_t harddriv_state::calculate_ema(uint16_t new_value) {
    static float ema_wheel = 0.0;  // Persistent storage of EMA across calls
    static bool ema_initialized = false;  // To check if ema_wheel is initialized
    static const float alpha = 0.082;  // Smoothing constant

    if (!ema_initialized) {
        ema_wheel = new_value;  // Initialize EMA with the first raw value
        ema_initialized = true;
    } else {
        ema_wheel = alpha * new_value + (1 - alpha) * ema_wheel;
    }

    // Ensure the last digit of the EMA output is always zero
    return static_cast<uint16_t>(ema_wheel) & 0xFFF0;
}

// Main function to handle wheel input and apply adjustments
uint16_t harddriv_state::hdc68k_wheel_r() {
    static const uint16_t g_latchpoint = 0x8000;  // Center point for wheel edge detection
    static bool initialized = false;  // To ensure the initial setup is done only once
    static int16_t last_offset = 0;   // To store the last offset applied
    static int wheel_edge_zero_count = 0;  // Counter for how many times wheel edge has been set to 0
    static int resets_recorded = 0;   // Counter to delay offset recording

    // Initial setup
    if (!initialized) {
        m_hdc68k_wheel_edge = 1;  // Set the edge to 1 at the start of the game
        initialized = true;  // Prevent further initialization
    }

    uint16_t new_wheel_raw = m_12badc[0].read_safe(0xffff) << 4;
    uint16_t ema_wheel = calculate_ema(new_wheel_raw) << 3;

    // If the game has reset the wheel edge to 0, handle the deviation
    if (m_hdc68k_wheel_edge == 0) {
        wheel_edge_zero_count++;  // Increment the counter each time wheel edge is 0

        // Record adjustment only after the first reset is recorded
        if (resets_recorded > 0) {
            // Check for deviation from the center point
            if (ema_wheel != g_latchpoint) {
                int16_t adjustment = g_latchpoint - ema_wheel;  // Calculate the necessary adjustment
                ema_wheel += adjustment;  // Correct the EMA to the center point
                last_offset = adjustment;  // Store the last offset applied
            } else {
                last_offset = 0;  // No offset needed if already at center
            }
        }

        resets_recorded++;  // Increment resets recorded after processing
        m_hdc68k_wheel_edge = 1;  // Set the wheel edge back to 1 after handling the adjustment
    }

    // Debugging output
    popmessage("Wheel Raw: %04X, EMA Wheel: %04X, Last Offset: %d, Edge: %d, Edge 0 Count: %d, Resets Recorded: %d",
               new_wheel_raw, ema_wheel, last_offset, m_hdc68k_wheel_edge, wheel_edge_zero_count, resets_recorded);

    return ema_wheel;  // Use the adjusted EMA directly
}

--- End code ---



--- Code: ---    // Handlers for the wheel and port inputs
    m_maincpu->space(AS_PROGRAM).install_read_handler(0x400000, 0x400001, read16smo_delegate(*this, FUNC(harddriv_state::hdc68k_wheel_r)));
    m_maincpu->space(AS_PROGRAM).install_write_handler(0x408000, 0x408001, write16smo_delegate(*this, FUNC(harddriv_state::hdc68k_wheel_edge_reset_w)));
    m_maincpu->space(AS_PROGRAM).install_read_handler(0xa80000, 0xafffff, read16smo_delegate(*this, FUNC(harddriv_state::hda68k_port1_r)));
--- End code ---



--- Code: ---class harddriv_state : public device_t
{
public:

void reset_wheel_offset();  // Function to reset the wheel offset


harddriv_state(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);

void driver_msp(machine_config &config);
@@ -98,8 +102,21 @@ class harddriv_state : public device_t
void video_int_write_line(int state);
void sound_int_write_line(int state);

//New method declarations for steering logic
uint16_t hdc68k_wheel_r();  // Ensure this is declared only once
uint16_t custom_steering_logic();
uint16_t original_steering_logic();

// Add your EMA function declaration here
uint16_t calculate_ema(uint16_t new_value); // Corrected declaration


protected:

 int16_t wheel_offset = 0;  // Make wheel_offset a member variable

void init_video();

INTERRUPT_GEN_MEMBER(hd68k_irq_gen);
TIMER_CALLBACK_MEMBER(deferred_adsp_bank_switch);
TIMER_CALLBACK_MEMBER(rddsp32_sync_cb);
@@ -122,7 +139,7 @@ class harddriv_state : public device_t
uint16_t hd68k_adc12_r();
uint16_t hdc68k_port1_r();
uint16_t hda68k_port1_r();
// uint16_t hdc68k_wheel_r();
uint16_t hd68k_sound_reset_r();

void hd68k_adc_control_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
--- End code ---

geecab:

--- Code: ---PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_CUSTOM )  PORT_TOGGLE PORT_NAME("Center Wheel Edge")  /* center edge on steering wheel, IPT_ACTIVE_HIGH fixes the steering alignment in game! */

--- End code ---

OMG lol! I didn't try IP_ACTIVE_HIGH on 0x4000, only on 0x8000. I didn't change it on 0x4000 because it looked like it was doing the right thing in the service menu :p I honestly can't wait to try this later, nice one Yolo and well found! :)

Yolo_Swaggins:

--- Quote from: geecab on April 23, 2024, 10:27:55 am ---
--- Code: ---PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_CUSTOM )  PORT_TOGGLE PORT_NAME("Center Wheel Edge")  /* center edge on steering wheel, IPT_ACTIVE_HIGH fixes the steering alignment in game! */

--- End code ---

OMG lol! I didn't try IP_ACTIVE_HIGH on 0x4000, only on 0x8000. I didn't change it on 0x4000 because it looked like it was doing the right thing in the service menu :p I honestly can't wait to try this later, nice one Yolo and well found! :)

--- End quote ---

I didn't try it either because i already tried it on Airborne and it didnt fix that or stop the behaviour that makes the wheel center get reset, but because i had made that button to activate it i noticed in the reacedrivc level select and car select screen that if i held the button down the wheel would follow my logitech g932 like it should so i just changed it to high to keep it on all the time lol

Another thing i will mention because it might help out in fixing airborne etc is that my wheel EMA code didnt work on street drivin'............i had to start the game then hit f3 to reset the machine and suddenly it would work fine.....i made a change to the code so that it would not send the EMA wheel info when the game boots up, it sends the unprocessed wheel info to the game and then switches to the EMA wheel. When i made this change it worked fine again. I have to change the port_minmax for all of the games for it to work with my code so to me it seems like all these different version of the game have slightly different ways or reading and calibrating the wheel positions which makes finding a fix for airborne maybe harder but as i said before i haven't had a proper look at the info you sent earlier as in i haven't actualy tried to use it yet.......i should give that a go today too once i have a few coffees in me  ;D

The EMA wheel code can be manipulated to make the smoothing more or less aggressive and more aggressive will mean more lag between you moving the wheel IRL and it moving in game. The setting i have it set to in the code snippet below seems to be perfect and stops the wheel going out of alignment in airborne when you make erratic/fast movements. The lower the number the more EMA smoothing/latency is applied and the closer it gets to 1 the more responsive/less smoothing it will have. A EMA setting that works for a port_minmax range might not work if you adjust the port_minmax range to be more sensitive, you'll need to readjust the EMA to compensate for it so there is a balancing act in working out whats best.


--- Code: --- static const float alpha = 0.082;  // Smoothing constant
--- End code ---

I noticed that Hard Drivin' Compact has an other issue that it doesn't fix........the wheel seems to every so often try to go to another position for a split second and sems to make the car skid sometimes for no reason? I'll have another look at it today.

geecab:
Oh man... I'm not sure we are out of the woods yet.

Last night I played about with setting IP_ACTIVE_HIGH for the Compact Hard Drivin' roms yesterday. I have to say, I kind of think the correct thing to do is leave it at  IP_ACTIVE_LOW...

Setting it active high means the 'Centre Edge' thing (Seen in the Service Menu) is constantly on (Green), the 'Steering Wheel' value is held at 0x0000, and steering calibration is not possible (Which can't be correct). While you can skip the service menu to play the game, and observe the car re-spawns always with centred steering (which is very good to know and well found by yourself), it feels to me like we are building on a side effect of doing something that we shouldn't be doing. Without fully understanding what should be happening...

Another spanner in the works is that I also think for these compact roms, the steering control should probably be an IPT_DIAL (which has unlimited rotation) rather than an IPT_PADDLE (that has limited rotation), to reflect the actual arcade hardware.

 :dunno

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version