Thanks for your replies Badmouth, really great 'Driving Cab Information' thread by the way. Really helped me out a lot when I was putting my cab together. I think I have read about that glovepie fix you mentioned, but I just fancied modifying the mame source rather than having other stuff running in the background. I think I will submit something to MAMEDev at some point, but to be honest, these are pretty nasty hacks at the moment, am just enjoying messing around with the source code. I haven't even made my modifications command line configurable either so while it will make outrun etc play better, it could well break other games.
Getting hard drivin' going was tricky, I don't think that multiple turning pot thing (with some strange latching bit when the wheel turns 360 degrees past the central point) has ever been emulated correctly. My hack for hard drivin is different to my outrun/hang-on/weclemans hack, I shall post the hack I made specifically for hard drivin in another post a little later on.
So regarding the outrun/hang-on/weclemans change, you don't have to change all the individual game driver files, just one file (found in src/emu/ioport.c). Also, I'm editing mame source version 0145. You are looking for a function called "apply_analog_min_max", below is what the function looked like originally (before my hack):-
INLINE INT32 apply_analog_min_max(const analog_field_state *analog, INT32 value)
{
/* take the analog minimum and maximum values and apply the inverse of the */
/* sensitivity so that we can clamp against them before applying sensitivity */
INT32 adjmin = APPLY_INVERSE_SENSITIVITY(analog->minimum, analog->sensitivity);
INT32 adjmax = APPLY_INVERSE_SENSITIVITY(analog->maximum, analog->sensitivity);
/* for absolute devices, clamp to the bounds absolutely */
if (!analog->wraps)
{
if (value > adjmax)
value = adjmax;
else if (value < adjmin)
value = adjmin;
}
/* for relative devices, wrap around when we go past the edge */
else
{
INT32 range = adjmax - adjmin;
/* rolls to other end when 1 position past end. */
value = (value - adjmin) % range;
if (value < 0)
value += range;
value += adjmin;
}
return value;
}
Now, outrun/hang-on/weclemans used an absolute device for steering. 'value' is passed into the function as the position of where your mouse x axis is. 'value' is limited to adjmax or adjmin if you moved your mouse further than the arcade game allowed.
So now onto my fix, basically, if 'value' is limited by adjmax or adjmin, I make a note of the difference (I called it "spin_history" for some reason). Then the next time I'm in the apply_analog_min_max, I add the spin_history (which maybe positive or negative depending on which way the wheel was turned) to the 'value' passed in, which then may be limited again, which I then save the spin_history again, etc.. etc... Finally, I only want this to happen for the IPT_PADDLE type because that is the steering wheel device, other devices also go through this function too (IPT_PEDALS for example) which I don't want to alter:-
INT32 spin_history = 0;
INLINE INT32 apply_analog_min_max(const analog_field_state *analog, INT32 value)
{
/* take the analog minimum and maximum values and apply the inverse of the */
/* sensitivity so that we can clamp against them before applying sensitivity */
INT32 adjmin = APPLY_INVERSE_SENSITIVITY(analog->minimum, analog->sensitivity);
INT32 adjmax = APPLY_INVERSE_SENSITIVITY(analog->maximum, analog->sensitivity);
/* for absolute devices, clamp to the bounds absolutely */
if (!analog->wraps)
{
if(analog->field->type == IPT_PADDLE)
{
value = value + spin_history;
spin_history = 0;
if(value > adjmax)
{
spin_history = value - adjmax;
value = adjmax;
}
else if(value < adjmin)
{
spin_history = value - adjmin;
value = adjmin;
}
}
else
{
if (value > adjmax)
value = adjmax;
else if (value < adjmin)
value = adjmin;
}
}
/* for relative devices, wrap around when we go past the edge */
else
{
INT32 range = adjmax - adjmin;
/* rolls to other end when 1 position past end. */
value = (value - adjmin) % range;
if (value < 0)
value += range;
value += adjmin;
}
return value;
}
There is an obvious bug with this, like if you span your wheel enough (moved you mouse in one direction enough) spin_history would get so large (or so small) that it too would wrap around. I could sort this out at some point though.
Anyways, I think that's it for now as I think I'm going on a bit, hope some of this made sense