Main > Driving & Racing Cabinets

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

<< < (14/22) > >>

Yolo_Swaggins:

--- Quote from: geecab on April 24, 2024, 06:34:27 am ---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

--- End quote ---

 
Thats why i only have it set high for racedrivc the others i left alone. It just makes the game playable. My feeling is that those functions you sent from the hard drivin' compact manual with memory addresses 404000,404000 and 408000 are not being used properly........i think that the devs have made the game only use one of them to do a job that the other one is meant to carry out when it reaches the centerpoint?


--- Code: ---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
--- End code ---

I have a hunch that only the middle one is being set or the last one? In mame when we press that wheel edge button to manually activate it the counter suddenly becomes 0000.........that sounds like it's activating the middle function which kinda makes it seem like it's doing it's job because suddenly the wheel will think thats the centerpoint?  Shouldn't it be activating the last one to be setting in stone what the actual centerpoint is? Where in the mame code is the other function? I only see the one wheel edge function mentioned in mame driver code? What if the wheel edge in mame is linked to the wrong operation in that manual? Wouldn't that be the cause of it all? I think theres meant to be 2 flags or operations working together and from what i see in the mame driver code is only one operation/flag being used. I might be completely wrong but it's all my brain can come up with.

Yolo_Swaggins:
Hard Drivin'/Race Drivin' cockpit in the mame driver only has this.


--- Code: --- PORT_START("mainpcb:a80000")
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_START2 ) PORT_NAME("Abort")    /* abort */
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_START1 ) PORT_NAME("Key")  /* key */
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_COIN3 )    /* aux coin */
PORT_BIT( 0xfff8, IP_ACTIVE_LOW, IPT_UNUSED )

--- End code ---

But all the rest have this?


--- Code: --- PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_CUSTOM )  PORT_TOGGLE PORT_NAME("Center Wheel Edge")  /* center edge on steering wheel */
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )

--- End code ---

I notice the highest memory address for these operations is on the steel talons/stun runner board that has this


--- Code: --- PORT_BIT( 0xfff0, IP_ACTIVE_LOW, IPT_UNUSED )

--- End code ---

Maybe the other function that could potentially be missing is lurking around within the 0x8000 to 0xfff0 range?

PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )  actually is used in Airborne in the debug menu..........

Wonder what 0x9000, 0xa000,0xb000 etc would do? :dunno

geecab:
Hi Yolo,

I think I might now have something that shows the centre latching stuff working... I'm tentative saying this in case I'm talking rubbish and I've just been lucky running a few tests lol! But its looking reasonable so far :)

I'll explain how (I think) its working in the next post, but first here's the diff of my changes:-


--- Code: ---diff --git a/src/mame/atari/harddriv.cpp b/src/mame/atari/harddriv.cpp
index e0b25440ad7..2ff020056b9 100644
--- a/src/mame/atari/harddriv.cpp
+++ b/src/mame/atari/harddriv.cpp
@@ -1041,8 +1041,8 @@ static INPUT_PORTS_START( racedrivc )
  PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON4 )  PORT_NAME("3rd Gear")
  PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_BUTTON5 )  PORT_NAME("4th Gear")
  PORT_BIT( 0x3000, IP_ACTIVE_LOW, IPT_UNUSED )
- PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_CUSTOM )  /* center edge on steering wheel */
- PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_CUSTOM )  PORT_NAME("Encoder Reset") /* center edge on steering wheel */
+ PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_CUSTOM )  PORT_NAME("Center Reset") /* center edge on steering wheel */
 
  PORT_START("mainpcb:8BADC.0")        /* b00000 - 8 bit ADC 0 - gas pedal */
  PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_SENSITIVITY(25) PORT_KEYDELTA(20) PORT_NAME("Gas Pedal")
@@ -1069,7 +1069,7 @@ static INPUT_PORTS_START( racedrivc )
  PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
 
  PORT_START("mainpcb:12BADC.0")       /* 400000 - steering wheel */
- PORT_BIT(0xfff, 0x800, IPT_PADDLE) PORT_MINMAX(0x010, 0xff0) PORT_SENSITIVITY(400) PORT_KEYDELTA(5) PORT_NAME("Steering Wheel")
+ PORT_BIT( 0xfff, 0x800, IPT_DIAL ) PORT_SENSITIVITY(400) PORT_KEYDELTA(5) PORT_NAME("Steering Wheel")
 
  /* dummy ADC ports to end up with the same number as the full version */
  PORT_START("mainpcb:12BADC.1")
diff --git a/src/mame/atari/harddriv_m.cpp b/src/mame/atari/harddriv_m.cpp
index 856783e2fb6..e17d54bc4d6 100644
--- a/src/mame/atari/harddriv_m.cpp
+++ b/src/mame/atari/harddriv_m.cpp
@@ -9,7 +9,6 @@
 #include "emu.h"
 #include "harddriv.h"
 
-
 /*************************************
  *
  *  Constants and macros
@@ -246,42 +245,68 @@ uint16_t harddriv_state::hdc68k_port1_r()
  result = (result | 0x0f00) ^ (m_hdc68k_shifter_state << 8);
 
  /* merge in the wheel edge latch bit */
- if (m_hdc68k_wheel_edge)
- result ^= 0x4000;
+    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;
+    m_hdc68k_last_port1 = result;
+    return result;
 }
 
 
 uint16_t harddriv_state::hda68k_port1_r()
 {
- uint16_t result = m_a80000->read();
+    uint16_t result = m_a80000->read();
 
- /* merge in the wheel edge latch bit */
- if (m_hdc68k_wheel_edge)
- result ^= 0x4000;
+    /* merge in the wheel edge latch bit */
+    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;
+    return result;
 }
 
 
 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;
+    // 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("wheel new=%04X", new_wheel);
+    }
+
+    if ((m_hdc68k_last_wheel & 0x0C00) != (new_wheel & 0x0C00))
+    {
+        /*
+        Why the 0x0C00 mask? It checks if the new wheel position has moved into a new range.
+        NNNN 00NN NNNN NNNN     Thus range 0x0000 to 0x03FF
+        NNNN 01NN NNNN NNNN     Thus range 0x0400 to 0x07FF
+        NNNN 10NN NNNN NNNN     Thus range 0x0800 to 0x0BFF
+        NNNN 11NN NNNN NNNN     Thus range 0x0C00 to 0x0FFF
+        */
+        if(m_hdc68k_wheel_edge == 1)
+        {
+            //Already pending a latch. There is no point in doing 2 really quick latches,
+            //do nothing for the same effect.
+            m_hdc68k_wheel_edge = 0;
+        }
+        else
+        {
+            m_hdc68k_wheel_edge = 1;
+        }
+    }
+
+    m_hdc68k_last_wheel = new_wheel;
+    return (new_wheel << 8) | 0xff;
 }
 
 
@@ -445,11 +470,10 @@ void harddriv_state::hd68k_nwr_w(offs_t offset, uint16_t data)
 void harddriv_state::hdc68k_wheel_edge_reset_w(uint16_t data)
 {
  /* reset the edge latch */
- m_hdc68k_wheel_edge = 0;
+ //m_hdc68k_wheel_edge = 1;
 }
 
 
-
 /*************************************
  *
  *  68000 ZRAM access

--- End code ---

geecab:
So after implementing my code in the previous post, if you run the hard drivin compact roms, you should be able to successfully calibrate the wheel, but you must use a mouse. Moving the mouse for ages to the right will simulate 4 wheel rotations and after completing the calibration you want to see:
    NEW CNTSPTRN 1024 PATCEN 0

Which indicates one complete wheel rotation (CNTSPTRN) amounts to 1024 (0x400) encoder values and the wheel is currently in its centre position (PATCEN 0).

Note. You will want to hold the left shift key to get the encoder value spot on at the end of the calibration (When its working out the PATCEN thing).

In the game, the centre edge bit (That "result ^= 0x4000" stuff in hdc68k_port1_r()) will 'latch' each time the wheel does a full rotation (Hitting the wheel's centre point). The encoder wheel value at these centre points will be 0x000, 0x400, 0x800 or 0xC00. So say the centre edge bit is 0 between range 0x000 to 0x3FF, this means in the 0x400 to 0x7FF range the centre edge bit will be 1, in the 0x800 to 0xBFF range the centre edge bit will be 0, and in the 0xC00 to 0xFFF range the centre edge bit will be 1.

Note. I believe incorrect calibration and incorrect centre edit bit latching were the main reasons why the old code didn't work. The old code would set m_hdc68k_wheel_edge to 1 when it wanted to latch the centre edge bit. In hdc68k_port1_r(), because m_hdc68k_wheel_edge was set it would toggle the centre edge bit. The problem is, during the game, you don't always get a hdc68k_wheel_edge_reset_w() acknowledgement for changing the centre edge bit (You do in service mode, but not  always during the game), and the code relied on that to set m_hdc68k_wheel_edge back to 0. The result is, during the game you can get into a state where the centre edit bit toggles repeatedly because  m_hdc68k_wheel_edge it left set to 1 for ages (Until such a time when hdc68k_wheel_edge_reset_w() is called (After the car re-spawns is one of those times)).

I think that just as your car re-spawns is the moment when the game works out which one of the centre points is the most appropriate (nearest). Let say you started the game around the 0x800 position, then you crash after turning hard right (and say the encoder at that moment is 0xD50). Then once you re-spawn, the game doesn't expect you to wind back the steering all the way to the 0x800 centre point (0xD50-0x550 encoder values), you'll only be expected to wind back the steering to the 0xC00 centre point (0xD50-0x150 encoder values).

So now after you crash, when you get the car to go in a straight forwards direction and observe the encoder value (left shift), you should notice it'll always be around one of those those centre points (0x000, 0x400, 0x800, 0xC00).

:)

Yolo_Swaggins:
Hi geecab i got the code you posted working but the mouse thing was annoying me so i added a dip switch that lets you select a "Calibration Wheel" so that you can 100% accurately set it up using the Keyboard then you switch it back to the "Game Wheel 1" or "Game Wheel 2" setting and the game works fine. I added "Game Wheel 2" because it's a custom PORT_MINMAX that makes the steering less twitchy on a Logitech G932 wheel but still gives you the full range of motion in the car.

To get it 100% accurate all you do is set "Calibration Wheel" in the dip switch menu then in the input assignment menu you just map "Calibration Wheel Analogue Inc" to the Kbd Right (right key on keyboard) and hold it down untill it reaches 4 turns (it takes about 10 seconds), let go of the button and turn the Key and you get CNTSPTRN 1024, PATCEN 0.

Virtual DIP Switches for Wheel selection.




--- Code: ---
PORT_START("mainpcb:SW1")       /* 60c002 */
// Virtual DIP switches here
PORT_DIPNAME( 0x700, 0x100, "Toggle Calibration Wheel or Game Wheel 1-2" )
PORT_DIPSETTING(    0x100, "Game Wheel 1" )
PORT_DIPSETTING(    0x300, "Game Wheel 2" )
PORT_DIPSETTING(    0x400, "Calibration Wheel" )

//Hardware DIP switches continue here
PORT_DIPNAME( 0x01, 0x01, "SW1:8" )
PORT_DIPSETTING(    0x01, DEF_STR( Off ) )
PORT_DIPSETTING(    0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x02, "SW1:7" )

--- End code ---

Message in the Input Assignment menu to remind users how to calibrate wheel.




--- Code: --- PORT_START("mainpcb:a80000")
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_START2 ) PORT_NAME("Abort")
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_START1 ) PORT_NAME("Key")
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_COIN3 )    /* aux coin */
PORT_BIT( 0x00f8, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 )  PORT_NAME("1st Gear")
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON3 )  PORT_NAME("2nd Gear")
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON4 )  PORT_NAME("3rd Gear")
PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_BUTTON5 )  PORT_NAME("4th Gear")
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_CUSTOM ) /* center edge on steering wheel */
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x3000, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_NAME("1: Use DIP Switch & choose calibration wheel to calibrate wheel in test menu!")
PORT_BIT(0x10000, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_NAME("2: Map Calibration Wheel Analogue Inc to Kbd Right!")
PORT_BIT(0x20000, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_NAME("3: Hold down Kbd Right until you reach 4 turns!")
PORT_BIT(0x40000, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_NAME("4: Let go of Kbd Right and turn key!")
PORT_BIT(0x80000, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_NAME("5: Switch back to Game Wheel 1 or 2 after Test Menu calibration complete!")

--- End code ---

The different Wheel setups selectable in DIP Switch menu.


--- Code: --- PORT_START("mainpcb:12BADC.0")       /* b80000 - 12 bit ADC 0 - steering wheel */
/* Game Steering Wheel 1 */
PORT_BIT(0xfff, 0x800, IPT_PADDLE) PORT_CONDITION("mainpcb:SW1", 0x700, EQUALS, 0x100) PORT_MINMAX(0x010, 0xff0) PORT_SENSITIVITY(1) PORT_KEYDELTA(0) PORT_NAME("Game Wheel 1")

/* Game Steering Wheel 2 */
PORT_BIT(0xffff, 0x0800, IPT_PADDLE) PORT_CONDITION("mainpcb:SW1", 0x700, EQUALS, 0x300) PORT_MINMAX(0x0440, 0x0bc0) PORT_SENSITIVITY(1) PORT_KEYDELTA(0) PORT_NAME("Game Wheel 2")

/* Calibration Wheel */
PORT_BIT(0xffff, 0x0000, IPT_PADDLE) PORT_CONDITION("mainpcb:SW1", 0x700, EQUALS, 0x400) PORT_MINMAX(0x0000, 0x2800) PORT_SENSITIVITY(1) PORT_KEYDELTA(0) PORT_NAME("Calibration Wheel")
--- End code ---



Game wheel 1 is the original mame PORT_MINMAX of 0x010, 0xff0 and Game Wheel 2 is the one i tweaked for my Logitech G932 with a PORT_MINMAX of  0x0440, 0x0bc0. Calibration Wheel has a PORT_MINMAX of 0x0000, 0x2800 and thats why it calibrates the machine perfectly but it's way too high to actually use it as a wheel because of how sensitive it is. It's only useful for calibrating the game.



Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version