Main Restorations Software Audio/Jukebox/MP3 Everything Else Buy/Sell/Trade
Project Announcements Monitor/Video GroovyMAME Merit/JVL Touchscreen Meet Up Retail Vendors
Driving & Racing Woodworking Software Support Forums Consoles Project Arcade Reviews
Automated Projects Artwork Frontend Support Forums Pinball Forum Discussion Old Boards
Raspberry Pi & Dev Board controls.dat Linux Miscellaneous Arcade Wiki Discussion Old Archives
Lightguns Arcade1Up Try the site in https mode Site News

Unread posts | New Replies | Recent posts | Rules | Chatroom | Wiki | File Repository | RSS | Submit news

  

Author Topic: Mame hacks that make driving games play better with mouse/spinner/360wheel  (Read 21333 times)

0 Members and 1 Guest are viewing this topic.

isamu

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 807
  • Last login:April 14, 2024, 08:15:07 pm
  • I'm a llama!
Re: Mame hacks that make driving games play better with mouse/spinner/360wheel
« Reply #40 on: December 29, 2017, 07:03:05 pm »
This is cool but what about those of us with 270° wheels that want to play the 360° games?

Marcoqwerty

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 123
  • Last login:March 14, 2024, 02:46:08 pm
Re: Mame hacks that make driving games play better with mouse/spinner/360wheel
« Reply #41 on: December 29, 2017, 08:31:03 pm »
This is cool but what about those of us with 270° wheels that want to play the 360° games?

You should play with mame sensibility and find the right setting "in game test mode"....but if you are on beginning to a new project, better to move on a 360 wheel imho.

Martin0037

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 21
  • Last login:May 11, 2018, 05:47:15 pm
  • I want to build my own arcade controls!
Re: Mame hacks that make driving games play better with mouse/spinner/360wheel
« Reply #42 on: February 27, 2018, 10:49:08 am »
Hi guys.  Great thread this is. Helped me loads so far.  Hope someone can help me here...
Has anyone any idea if a newer version of mame has been released with this sorted or has anyone compiled a newer version of mame with geecabs hack applied?

I’ve tried your mame hack version geecab and it works brilliant,  can’t seem to run newer games on it such as ridge racer or rave racer,  think ridge racer was 0.159 but I might be wrong.

I’m a total noob when it comes to compiling... 


geecab

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 229
  • Last login:Yesterday at 09:49:44 am
Hi there! I think mame's steering wheel code has changed a bit since I last did my hack. I can no longer compile you a new version of mame on windows as I only have a windows XP machine (and it is not possible to build mame on XP anymore). I use Linux Ubuntu now, so I can compile/test the latest version of mame on that. If I get my hack working with the latest sources of mame on Ubuntu, I could send you my Git "diff" file (I'm not sure if you've heard of the Git source control program? but a Git diff file is just a text file generated by Git that clearly details lines of code have been changed/removed/added). If you are able to compile the latest mame sources 'as is' on your windows machine, then you should simply be able to apply my "diff" file to your sources and you should be able to compile will all my code changes (without any manual editing).

Does this sound like a good way forward? I guess first off, are you able to compile the latest mame source 'as is'?


Yolo_Swaggins

  • Trade Count: (0)
  • Jr. Member
  • **
  • Offline Offline
  • Posts: 3
  • Last login:Yesterday at 05:54:38 am
  • I want to build my own arcade controls!
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.

Code: [Select]
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;
}
« Last Edit: April 14, 2024, 11:04:35 pm by Yolo_Swaggins »

geecab

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 229
  • Last login:Yesterday at 09:49:44 am
Hi there!

 Unfortunately, my mind is a bit hazy regarding my hard drivin' fix/hack but will try and help as best I can.

A few things off the top of my head:

1. My fix was to make hard drivin’ play ok with mouse/spinner, rather than a SteeringWheel/Joystick (that has a fixed centre). So I’m a bit concerned that porting whatever I did back in 2013 might not help much.

2. You’re probably already aware of this, but I’ll mention it anyway - My fix only worked for the Compact British version of hard drivin’ roms (That expects optical encoders for steering, and did the weird centre point latching thing). The full cockpit versions of hard drivin’ & race drivin’ used potentiometers for steering. I am guessing when you say hard drivin’ & race drivin’ are working fine for you, that you must be using the cockpit roms? I don’t suppose there are any street drivin’ or airborne roms available for cockpit cabinets are there?

I have to say, I am fascinated to know what’s going on with this steering/latching stuff again, so at some point soon I’ll get building mame again and try to recreate what you are seeing (I’d also like to have go at street drivin’ and airborne too 😊)!

Yolo_Swaggins

  • Trade Count: (0)
  • Jr. Member
  • **
  • Offline Offline
  • Posts: 3
  • Last login:Yesterday at 05:54:38 am
  • I want to build my own arcade controls!
Made some progress. Car seems to not go wonky after crashing in Hard Drivin's Airborne with this code and i can drive around untill the timer runs out and the wheels seem to stay straight  :dunno I've not tested it too much as in crashing with the wheel held all the way around to the left or the right because thats not how i play or anyone else i think? Been keeping my regular play style and if i forget to let go of the wheel when i crash theres a offset applied to the new_wheel output that keeps the centre point lined up with what the game is doing.

Original wheel edge bit latch code from harddriv_m.cpp here

Code: [Select]
uint16_t harddriv_state::hdc68k_wheel_r()
{
/* grab the new wheel value */
uint16_t new_wheel = m_12badc[0].read_safe(0xffff);

/* hack to display the wheel position */
if (machine().input().code_pressed(KEYCODE_LSHIFT))
popmessage("%04X", new_wheel);

/* if we crossed the center line, latch the edge bit */
if ((m_hdc68k_last_wheel / 0xf00) != (new_wheel / 0xf00))
m_hdc68k_wheel_edge = 1;

/* remember the last value and return the low 8 bits */
m_hdc68k_last_wheel = new_wheel;
return (new_wheel << 8) | 0xff;
}

And this is the modification i made for Hard Drivin's Airborne to work better and stop going out of alignment so much.

Code: [Select]
uint16_t harddriv_state::hdc68k_wheel_r()
{
    static const uint16_t g_latchpoint = 0x8000;  // 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) << 4;


    // Apply the cumulative offset to align with the game's perceived center.
    uint16_t new_wheel = new_wheel_raw + wheel_offset;

    // 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) {
        // Calculate the offset adjustment when the wheel is recalibrated.
        int16_t new_offset_adjustment = g_latchpoint - new_wheel_raw;

        // Apply the adjustment based on the current wheel position relative to the center
        if (new_wheel_raw > g_latchpoint) {
            // Wheel is to the left, need to decrease raw value towards the center
            wheel_offset += abs(new_offset_adjustment); // Use addition to adjust back towards the center
        } else {
            // Wheel is to the right, need to increase raw value towards the center
            wheel_offset -= abs(new_offset_adjustment); // Use subtraction if below the center
        }

        new_wheel = new_wheel_raw + wheel_offset; // Reapply the updated offset.
    }

    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: %X",
               new_wheel_raw, new_wheel, m_hdc68k_wheel_edge, wheel_offset);

    // Store the current wheel value for the next comparison.
    m_hdc68k_last_wheel = new_wheel_raw;  // Update last_wheel to the raw value to ensure proper comparison next cycle.

    // Return the processed wheel value, formatted as required.
    return (new_wheel << 4) | 0xff;

}

Seems to work fine in Street Drivin' too but that didn't have a wheel alignment issue after the last patch i did on it anyway and it doesn't set wheel edge to 0 when you crash so not a issue there or in any of the other ones really. This code might not play well with the compact versions because of how they do the wheel alignment I think you can just skip the wheel calibration setup and it should work anyway I applied a overclock in the source code for my own version of mame I'm testing and got the frame rate way higher in every one of them because i exceed the 400% limit on the GSP.

I made a dip switch that can toggle between 6 or 7 different types of wheel/sensitivity. I have my Logitech G923 wheel dialled in on it but not tidied the code up or labelled them appropriately yet i'll finish doing that later today or tomorrow after some sleep.

« Last Edit: Yesterday at 05:54:38 am by Yolo_Swaggins »

geecab

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 229
  • Last login:Yesterday at 09:49:44 am
Sounds good to me, great stuff :)

I'm still catching up. I've managed to get mame built from github and I can run hard drivin' (compact) and airborne. I've just not hacked the code yet (But I think that's what I need to do to get a feel for what is happening). I'll start experimenting with my wheel at the weekend.

Something that has always bugged me with the compact roms, is that it is not possible (yet, I think) to successfully calibrate the wheel using the service menu. I went and did some reading/investigation, trying to work out what values to expect (When viewing the "Control Inputs" service menu) from a successfully calibrated wheel. I didn't get very far. Thought I'd post my notes as they might be of interest/help:-

Code: [Select]
Compact harddrivin service manual (HDC_TM-329_2nd.pdf):
041787-02 Steering Encoder Disk.
043807-02 Centering Encoder Disk.

HDC_TM-329_2nd.pdf, From the "Control Inputs" service menu:
As you turn the steering wheel clockwise, the hexadecimal number should increase and change to zero once every turn.
As you turn the wheel counterclockwise, the number should decrease. Everytime the steering wheel passes the center position,
the words center edge should change from blue to green.

HDC_TM-329_2nd.pdf, from a section near the end about installing a new encoder wheel:
Install the steering wheel with the center spoke down. Make sure the single hole on the centering disk is between the opitcal reader on the centering
PCB so the steering wheel will be correctly centered.

From the Race Drivin' Compact Manual, for the Main Board Memory Map, it says:
OPTO: Optical Steering Wheel Reader
400000 (R) OPTORD Read the Optical Counter
404000 (W) OPTORES Reset the Optical Counter
408000 (W) CENRES Reset the Optical Centre Flag

I found a picture of a 041787-02 Steering Encoder Disk, and counted 72 holes. Based on this, I don't think we should see a steering value (When viewing the "Control Inputs" service menu) reported that exceeds 72 (Or maybe 144 if we are counting teeth passing as well has holes). Thus, when turning clockwise you'll see 0 increase to 72 then back to 0 etc... When turning anticlockwise you'll see 72 decrease 0 then back to 72 etc... In mame, I think we see values much greater than 72, this might cause strangeness. I think I'll try and hack things so that I force these 'ideal' values to occur at calibration.

Something odd I noticed, is that in mame when viewing the "Control Inputs" service menu and turning the wheel clockwise, I see the hexadecimal number decrease, not increase...

:)

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Offline Offline
  • Posts: 9401
  • Last login:Today at 06:46:32 am
  • Designated spam hunter
Something odd I noticed, is that in mame when viewing the "Control Inputs" service menu and turning the wheel clockwise, I see the hexadecimal number decrease, not increase...
Sounds like the optical data lines (A and B) are swapped, which reverses the axis.
- It could be your setup (not likely), settings, the connections in MAME (also not likely), or the axis reversal setting in MAME's Analog menu.   :dunno




Scott
« Last Edit: Yesterday at 11:04:36 am by PL1 »