Main > Main Forum
720 Real/Joystick/Spinner Test
(1/30) > >>
Derrick Renaud:
I already mentioned I thought it would be neat to control 720 with just a spinner.  I have to report that it seems to work quite well.  Unfortunately adding another hacked input device is not going to be acceptable.  So I had to break down and add Real/Fake handling.

http://rapidshare.com/files/443684040/mame.zip

(edit) use the official MAME 141u1 for testing instead.

Please try it and let me know if the 3 types of input (Real; Joystick; Spinner) work as expected.  There is a new menu item when Real/Fake controls are found called "Controller Type."  There you can select to use 1 of the 3 types.  The player controls will then be updated in the "Input (This Game)" menu.

So for those of you with the Real control, hook it up and let me know how it works.  Let me know what interface you are using.  No mouse hacks please.

Those of you with a spinner, try it out and give me your comments.  Spinner automatically sends the alignment pulses.  You can try your spinner on the Real setting and see how bad it is without the fake Spinner handling.  Set the sensitivity using the standard formula.
real_full_turn_count / actual_spinner_used_count * 100
For a 1200 count spinner ->  144 / 1200 * 100 = 12%

The setting is not saved in the cfg file yet, but will be.

Also I need opinions on what controls to output in the XML file for front ends.  Just the real?  Real and Fake?  The selected control? Both but with "Fake" added to fake ports?  Something else?

For those of you interested in how it works:
PORT_REAL specifies a group name and a handler.  The group name groups all the ports with the same name together under the new "Controller Type" menu.
If Real is selected then the current port is used unmodified.

PORT_FAKE specifies a group name and a controller name.  The controller name will add itself to the "Controller Type" menu.  If selected in the menu, the PORT_REAL port will call the handler to process the selected fake port data and return it as real.


--- Code: ---/* Center disc */
/* X1, X2 LETA inputs */
PORT_MODIFY("LETA0")
PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_REAL("Rotation", fake_leta_r) PORT_NAME("Center")

/* Rotate disc */
/* Y1, Y2 LETA inputs */
/* The disc has 72 teeth which are read by the hardware at 2x */
/* Computer hardware reads at 4x, so we set the sensitivity to 50% */
PORT_MODIFY("LETA1")
PORT_BIT( 0xff, 0x00, IPT_DIAL_V ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_FULL_TURN_COUNT(144) PORT_REAL("Rotation", fake_leta_r) PORT_NAME("Rotate")

PORT_START("FAKE_JOY_X") /* not direct mapped */
PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_FAKE("Rotation", "Joystick")

PORT_START("FAKE_JOY_Y") /* not direct mapped */
PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_REVERSE PORT_FAKE("Rotation", "Joystick")

/* Let's assume we are using a 1200 count spinner.  We scale to get a 144 count.
 * 144/1200 = 0.12 = 12% */
PORT_START("FAKE_SPINNER") /* not direct mapped */
PORT_BIT( 0xffff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(12) PORT_KEYDELTA(10) PORT_FAKE("Rotation", "Spinner")
--- End code ---


--- Code: ---static FAKE_INPUT( fake_leta_r )
{
if (!strcmp(current_controller, "Joystick"))
{
/* special thanks to MAME Analog+ for the mapping code */
static double last_angle;
static int rotations;

int analogx = input_port_read(field->port->machine, "FAKE_JOY_X") - 128;
int analogy = input_port_read(field->port->machine, "FAKE_JOY_Y") - 128;
double angle;

/* if the joystick is centered, leave the rest of this alone */
angle = last_angle;
if (analogx < -32 || analogx > 32 || analogy < -32 || analogy > 32)
angle = atan2((double)analogx, (double)analogy) * 360 / (2 * M_PI);

/* detect when we pass the 0 point in either direction */
if (last_angle < -90 && angle > 90)
rotations--;
else if (last_angle > 90 && angle < -90)
rotations++;
last_angle = angle;

/* LETA0 returns 0xff when the controller blocks one of two gaps */
if (!strcmp(tag, "LETA0"))
{
/* original controller had two gaps 10 degrees apart, each 2.5 degrees wide */
/* we fake it a little to make it possible to hit the zeroed state with a digital controller */
return (angle >= -5.0 && angle <= 5.0) ? 0xff : 0x00;
}

/* LETA1 returns dial value; 144 units = 1 full rotation */
else
{
/* take the rotations * 144 plus the current angle */
return (rotations * 144 + (int)(angle * 144.0 / 360.0)) & 0xff;
}
}
else if (!strcmp(current_controller, "Spinner"))
{
static UINT32 last_in;
static INT32  center_count;
UINT32 in = input_port_read(field->port->machine, "FAKE_SPINNER") & 0xffff;
INT32 diff;
UINT32 temp;

int flag = 0;

/* see if count rolled between 0xffff and 0x0000 */
if ((last_in > 0xc000) && (in < 0x03ff))
flag = 1;
if ((in > 0xc000) && (last_in < 0x03ff))
flag = -1;

if (flag == -1)
{
temp = 0xffff - in;
diff = last_in - temp - 1;
}
else if (flag == 0)
{
temp = in - last_in;
diff = temp;
}
else
{
temp = 0xffff - last_in;
diff = in + temp + 1;
}

last_in = in;

center_count += diff;
while (center_count < 0)
center_count += 144;
while (center_count >= 144)
center_count -= 144;

if (!strcmp(tag, "LETA0"))
{
/* for now just return 0xff at rotation 0 */
return (center_count == 0) ? 0xff : 0x00;
}
else
return in & 0xff;
}

return 0xff;
}

--- End code ---
Derrick Renaud:
I should mention that, No, this will not be used for adding shifters.   IPT_GEARSHIFT code is needed.  Not a bunch of fake handers.

This is for use in games like 720, and those fighting/punching weird games mentioned.
ahofle:
 :notworthy:

I will check this out when I get back from travel.  
PS. Thanks for being a true developer and taking this on as a puzzle while avoiding the annoying human factors involved.
abaraba:

--- Quote from: Derrick Renaud ---There is a new menu item when Real/Fake controls are found called "Controller Type."  There you can select to use 1 of the 3 types.

--- End quote ---

a.) Changing MAME core engine functionality to suit only one game, or very small and specific group of games, is no good.


b.) You have not submitted all the changes, not even complete "atarisy2.c", but more importantly you forgot to mention what other files you modified.


c.) As other similar menu options this should then also be accompanied with a new command line switch, and as anything 'unnecessary' this is also no good.


d.) You have only TWO types of devices there, not three. Arcade spinner can be mapped to "720 spinner" with no problems. No need for "real" and "fake" when we already have "mouse" and "analog", where analog stick maps to analog axes and both 'arcade spinner' and '720 spinner' map to mouse axes.



--- Code: ---PORT_MODIFY("LETA0")
PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10)
PORT_REAL("Rotation", fake_leta_r) PORT_NAME("Center")

PORT_MODIFY("LETA1")
PORT_BIT( 0xff, 0x00, IPT_DIAL_V ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10)
PORT_FULL_TURN_COUNT(144) PORT_REAL("Rotation", fake_leta_r) PORT_NAME("Rotate")

--- End code ---

Addition of "PORT_REAL", "PORT_FAKE", "PORT_FULL_TURN_COUNT(144)" is unnecessary and involves changes to core MAME engine, like modification of "inptport.c", and who knows what else.

It's nice to see you too named calibration port as "IPT_DIAL_V", but Mouse_Y and Mouse_X data seem to be swapped around in "REAL_FUNCTION", which is one of those things you did not show us.



--- Code: ---PORT_START("FAKE_JOY_X") /* not direct mapped */
PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(10)
PORT_FAKE("Rotation", "Joystick")

PORT_START("FAKE_JOY_Y") /* not direct mapped */
PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(10)
PORT_REVERSE PORT_FAKE("Rotation", "Joystick")

--- End code ---

Now that I know there is such thing as "PORT_START" I can add a 3rd variant to the list of my beautiful solutions, which generally is to any PC game developer just a very common and standard way to handle different input devices.



--- Code: ---PORT_START("FAKE_SPINNER") /* not direct mapped */
PORT_BIT( 0xffff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(12) PORT_KEYDELTA(10)
PORT_FAKE("Rotation", "Spinner")

--- End code ---

You do not need this, 'arcade spinner' maps to '720 spinner' very well. If you are doing it just to set different sensitivity then you shouldn't as various types of 'arcade spinners' would require different settings anyway, and their full rotation does not need to equal 720's full rotation, so the sensitivity of arcade spinners in this case is more a matter of personal preference, plus it can always be adjusted from the menu. Gameplay with an arcade spinner is much like gameplay with a mouse where you rotate the character by moving the mouse left-right, calibration at "360 degrees" in not necessary or better to say it's inapplicable.



--- Code: ---static FAKE_INPUT( fake_leta_r )

--- End code ---

You show us "FAKE_INPUT", but not "REAL_INPUT" function, nor where is the branching instruction to decide which one of them to execute. Without you submitting complete, and all the files you have modified no one will able to compile your changes, try to improve, learn from it, play with it, or anything.



--- Code: ---if (!strcmp(current_controller, "Joystick"))

--- End code ---

Finally we know what was the mysterious variable in infamous "Step 2", it's a bloody STRING?! Are you mad, comparing strings in a core function that you execute at least once per frame? So, you were not happy with all the unnecessary bloat introduced for this simple thing, now you also have to make it run slower, sheesh!



--- Code: ---int analogx = input_port_read(field->port->machine, "FAKE_JOY_X") - 128;
int analogy = input_port_read(field->port->machine, "FAKE_JOY_Y") - 128;

--- End code ---

Should be "- 127", not "- 128". I suggest you try to monitor what kind of data is incoming to those variables. Something seem wrong there as it gets clamped to min and max when stick retains in constant position, only when actually being moved, I suppose when there is a difference between immediate data packets - deltaX and deltaY, only then we can read actual position of the stick, which might have to do with why anal_hack rotation is not smooth but flickers and jitters.



--- Code: ---else if (!strcmp(current_controller, "Spinner"))

--- End code ---

It makes me puke just to look at the word - "strcmp". Anyway, "else" will do here, you do not need that second comparison until you decide to add keyboard hack too. But, the thing is, you do not need that whole part at all, the real input function can handle 'arcade spinner' as it is, without any hacks, changes or additions - it's still just a "mouse input" in either case.
Derrick Renaud:
 :troll:

Ignoring troll post that yet again does not contain any truth or understanding.

(Edit) Well accept for the fact that I did not post the rest of the code.  There is no need for something I just posted as a pre-compiled test program.  Code will be submitted when the 2 issues I mentioned are complete.  CFG and XML handling.  Which there is no need to do until the program completes the testing phase.
Navigation
Message Index
Next page

Go to full version