Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MAMEHOOKER support (& misc feature requests) #1

Closed
cmjdbb opened this issue Oct 31, 2023 · 59 comments
Closed

MAMEHOOKER support (& misc feature requests) #1

cmjdbb opened this issue Oct 31, 2023 · 59 comments
Labels
enhancement New feature or request

Comments

@cmjdbb
Copy link

cmjdbb commented Oct 31, 2023

I'm glad to see that you're continuing with this project, and hope to add some of the following features so that you can possibly surpass GUN4IR, 1: Add COM to PC communication so that you can use mamehook to synchronize the game's vibration. 2: Add RP2040 save Settings 。
MAMEHOOKER.docx

@cmjdbb cmjdbb changed the title Hope to add some of the following features Hope to add some of the following features. Oct 31, 2023
@SeongGino
Copy link
Owner

Both of these features are on the TODO list, so I hope to have these implemented in the near future.

For RP2040 saving, that's going to be first in line. Though with other obligations at the moment it may be a while before I can focus on figuring that part out.

As for mamehooker, the documentation is appreciated! Albeit, it seems to be written in Spanish? But I can see what needs to be implemented. That'll take a bit longer.

The main issue with mamehooker support, speaking outside of the project, is that it's exclusive to Windows - and as a Linux user, Wine and Serial devices don't seem to play very well together. As of now I only have one device with a Windows 10 partition for testing (and isn't particularly suited to games, either...)

Pinning in case someone else wishes to entertain the idea in the meantime.

@SeongGino SeongGino pinned this issue Nov 1, 2023
@SeongGino
Copy link
Owner

Update: RP2040 can save and load settings now since v1.2, so all boards should be capable of (re)storing calibration profiles.

@cmjdbb
Copy link
Author

cmjdbb commented Nov 2, 2023

Great, I tested it and the settings can be saved. You can also add an automatic switch function. When no infrared point is detected, pressing the trigger button is equivalent to pressing the right mouse button. This way, when you aim the gun outside the screen and pull the trigger, it will automatically switch to the right
mouse button. I wrote a COM port vibration test code myself, which is compatible with MAMEHOOK. I hope it can help you because the functionality of the vibration motor is to produce vibrations when being attacked. With everyone's efforts, I hope this project will become even more perfect.
rumble.txt

@SeongGino
Copy link
Owner

Thank you very much for the test code! It'll help plenty. I'm guessing by "rumble" this is for motor actions? I'll probably have to get another Windows system running to test it proper, which will... be some time, lol.

You can also add an automatic switch function.

That should be easy enough to implement, and I'd be fine with that. Although...
[rant]
Personally speaking I never liked using the right mouse button/first gun aux button as a reload only and making off-screen shots use that button as a parasite reload function; to me, it's functionally incorrect behavior. Emulators and/or games should be able to read the cursor position and determine if a shot is in/out of the screen and determine the behavior from that - RetroArch and MAME does this, as well as PCSX2 (with a 1% vertical shrink).
I know, I know, this is mostly for Model 2, DemulS games or other hacks where they aren't/forgot to be programmed to do this to begin with. I don't personally use the feature, but eh.
[/rant]
I'll spin up an offscreen shot = btnA press in a bit. Thank you for the suggestion. <3

@cmjdbb
Copy link
Author

cmjdbb commented Nov 2, 2023

Sure, "rumble" only activates when being attacked. The screen-Off Reload feature allows you to reload by pointing the gun upwards and pulling the trigger.

@SeongGino
Copy link
Owner

Before I drift off to sleep (it's about 3am here, I spent a few hours on this), I pushed support for offscreen button presses in the current source (but not a formal release yet--will come soon).
It is controlled with offscreenButton which defaults to off; when enabled, any off-screen shots (i.e. when an offscreen rumble event occurs) now sends a right click instead of the normal left click.
Required some working around the normal button polling and essentially have to reimplement checking the state of the trigger button separately in the main code loop, but this means 100% right click vs. left click accuracy. Tested this with Model 2 to be sure, and it works in my testing.

Still don't think it should be normalized behavior, but at least we can work around this now with problem games that need it. At some point later I'll get around to having it toggleable at runtime rather than only at compile.

@cmjdbb
Copy link
Author

cmjdbb commented Nov 2, 2023

Your idea is incorrect. Basically, in most games, reloading is done by pressing the right-click button. Reloading outside the screen will make it more realistic.

@SeongGino
Copy link
Owner

SeongGino commented Nov 2, 2023

Not to spur an argument, but how is my idea wrong?

Reloading outside the screen will make it more realistic.

That is how good implementations of lightgun support is supposed to be done, i.e. in MAME, RetroArch and PCSX2, they handle what the trigger does on their own based on where the cursor is, because that's correctly emulating how the original guns functioned on real hardware (making them more realistic, which I'm not disagreeing with). There shouldn't be a need for an extra button for pressing the trigger in a different state - it's as nasty a hack as mine is in this code, lol.

Most games are doing it wrong as far as I'm concerned. But the workaround is in anyways, so that's neither here nor there really.

@SeongGino
Copy link
Owner

Software toggles have been implemented in v1.3, so the offscreen button functionality implemented can be toggled through that now; as well as fixing keyboard button inputs. I believe that is most of the non-Mamehook features covered now.

@cmjdbb
Copy link
Author

cmjdbb commented Nov 3, 2023

Open source projects, is to everyone to participate in discussions and suggestions, so as to make the project better and better.

@cmjdbb
Copy link
Author

cmjdbb commented Nov 4, 2023

My suggestion: Automatic mode should be like this, hold down the Trigger key, will automatically press the left button 6 times, and then press the right button once to change the cartridge, so that like the Time Crisis-style game, the single shot gun can become the automatic firing gun。Whenever you release the Trigger key, you must press the left button 6 times and the right button once, otherwise the next time you press the Trigger key, it will not be 6 left keys and the right button once

@SeongGino SeongGino changed the title Hope to add some of the following features. MAMEHOOKER support Nov 4, 2023
@SeongGino SeongGino changed the title MAMEHOOKER support MAMEHOOKER support (& misc feature requests) Nov 4, 2023
@SeongGino
Copy link
Owner

Not to worry about the thread name change, it's just to more easily highlight things

Indeed, right now the autofire mode (and even the recently added burst-fire mode) is mostly a cosmetic addition. Since the sketch itself now controls trigger button pulses, it would be possible to do something like that - the only problem is how practical this is... or more accurately, how it isn't.

  • It's a very cheaty function from old world lightguns, and I don't know how the community would react to this being included.
  • While it could work for TC 1/2, it wouldn't work for TC3/4 (multiple weapons toggled by hiding + pressing fire), TC5 and its dual pedal system (for that, we would have to track what button was last pressed, and just adds overall complexity that I'm not comfortable with implementing right now) and be unoptimal for Crisis Zone where machine guns are used and damage per bullet is much less.
  • This would only work for House of the Deads 1-3 - not accounting for 4/Scarlet Dawn (which use machine guns with much larger clip capacities and different reloading methods entirely) and Overkill (which has multiple gun options of different firing modes). Also consider reload times in Overkill as well as Ghost Squad/Operation G.H.O.S.T..
  • Pretty much any mounted turret game ever, which the autofire mode was specifically tailored for (Taito's Operation {thing} series, Midway's T2 Arcade and Revolution X, and on and on) would have unintentional consequences; read, using secondary attack resources which might not be desirable at worst, or the benefits would be negligible at best for others (Sega's Let's Go Series/Transformers, Namco's Deadstorm Pirates).
  • We only have so many buttons used in the already plentiful GunCon 2 spec, and close to using all the available button combos for toggles. Most guns, if they have toggle switches, only have two or three at most without additional shell modification.

It's very not likely that I'll be making this actually cheat-y - it's just a feelie option.

@SeongGino
Copy link
Owner

SeongGino commented Nov 9, 2023

@cmjdbb Hey, sorry to ping you like this. I'm just now getting around to implementing support for MAMEHOOKER on a local build and I plan to make this a feature for the next release (alongside fixing the tracking speed, which is already pushed to the repo).

I'm at the point now where I can read and queue serial input, hand off control of the peripherals from the code to serial, and reading it to control the force feedback directly.

But I only just now realized, um... how is one supposed to setup MAMEHOOKER exactly? There's not exactly many resources I can find on what the heck it communicates with Gun4IR and what inputs it's expecting. Is there a standard for this I should be following? Are there inis setup for compatible games? I frankly didn't expect to find so little about how a user is supposed to even make it work in the first place...

As you might be able to gather, I don't have a Gun4IR so I can't ask them and their locked Discord server - and the Sinden community didn't seem very well receptive to me asking either...

@SeongGino
Copy link
Owner

Unless I'm doing something wrong, Mamehooker isn't seeing the com device.
I only have one native Windows test system to use (because I fucking hate Windows) and even though I can see the arduino responding in the IDE's serial monitor, Mamehooker isn't cooperating and I'm not able to see what its outputs are.

I have seriously no idea what I'm doing here.

Issue stalled until I receive a response here.

@SeongGino
Copy link
Owner

Despite all the hate I have for everything atm, ac7e00e now has some kind of MAMEHooker support... in theory.
As explained in my prior two messages, I currently can't even fathom how exactly it's supposed to work in the first place. It's disabled by default, but can be reenabled by uncommenting #define MAMEHOOKER. We only support a subset of the modes just so I can get a handle on what commands I can use and how exactly I should be handling them.

They at least worked if I sent the serial commands in the Arduino IDE, so iunno. Only thing I couldn't quite test is the "pulse rumble" option, which. . . how exactly is that supposed to work and what exactly constitutes a 'pulse?' I just winged it really with pull-out-of-my-ass-ninjitsu.

(I also copied and pasted the sketch on GH here back into my local copy to MAKE SURE there's no missing endifs, so it should be buildable out of the box again.)

I want this to be finished before pushing the next release, so please get back to me when you're able, @cmjdbb

@cmjdbb
Copy link
Author

cmjdbb commented Nov 10, 2023

I know how it works, but I don't know how to talk to you in private, maybe we need to discuss more aspects. It's troublesome to discuss here

@cmjdbb
Copy link
Author

cmjdbb commented Nov 10, 2023

I will provide a brief explanation on how to use MAMEHOOKER. Firstly, you need to change the serial port number for player 1 to COM1 and player 2 to COM2. Then, start MAMEHOOKER and set the path for MAME. Please note that you cannot find light gun devices in the MAMEHOOKER settings, and you cannot test light gun vibration within MAMEHOOKER. Don't worry about it; it will work. Next, locate the mame.ini file in the MAME folder and open it. Change the parameter after "output" to "windows". Now, you can start using it. Launch MAMEHOOKER first and then start the light gun game in MAME. After entering the game, close it. This will generate an ini file for the game in the MAMEHOOKER\ini\MAME folder. Open the ini file and follow the instructions I provided earlier for MAMEHOOKER file settings. Restart the game, and the shooting vibration will be synchronized with the game. The Flycas ini file can be found in the MAMEHOOKER\ini\presets folder. For detailed instructions, please refer to the MAMEHOOKER document I previously shared.

The Arduino IDE does not send any commands through the serial port. It only works after receiving vibration commands. First, it receives a synchronization command and disables the vibration of the fire button. It only outputs vibration when it receives a vibration code. When the P1_CtmRecoil of MAMEHOOKER sends F0x2x1 via COM1, the light gun vibration pin will output an electromagnet pulse. The width and speed of the pulse are determined by the game or emulator settings. When being attacked, when P1_Damaged of MAMEHOOKER sends F1x2x1 via COM1, the motor pin of the light gun will output a rumble pulse. The length of the pulse is also determined by the game or emulator settings. In other words, when the light gun receives F0x2x1, the electromagnet works, and when it receives F1x2x1, the motor works. When COM1 receives the command M1x2xM3x0EM8m1x, it disables serial port synchronization and enables vibration for the fire button.

@cmjdbb
Copy link
Author

cmjdbb commented Nov 10, 2023

Of course, rumble requires game support, commands are output by the game and MAMEHOOKER, you only need to receive the command, rumble pin output Rumble on the line.

@SeongGino
Copy link
Owner

The only other place to reach me would be my Discord @ThatOneSeong if you want to discuss things in private.

The problem is, I can't even get it to hook into MAME 0.259 in the first place - and any attempts at using a DemulShooter game have also eluded me because it isn't hooking right (even though I set the gun in the DS gui, even though I made sure to check ON the Outputs setting, even though I made sure to click save settings). MAMEHOOKER's running as admin, I set the output in the mame.ini file to windows, I did all of that.

But it's not doing anything. It sees the emulator window, but not the game.

I already got a bunch of prefabbed outputs inis from this thread on AC forums so I know that's covered. But even still.

For detailed instructions, please refer to the MAMEHOOKER document I previously shared.

You do realize that I don't speak en espanol, right? I had to translate the output code chart just to understand what it's trying to say - and even then it's just a loose grasp. Though I understand better what it means from looking at some of the inis...

I know though that the com port is getting read to properly; if I send a test COM port open from mamehooker to port 1, the IDE says that the port is busy now; and if I send an S start code then the gun's native force feedback stops as I told it to do, so I know it should be working.

And as you can tell from here, we already handle parsing the codes and placing them in a commands queue,

char serialInput = Serial.read(); // Read the serial input one byte at a time (we'll read more later)
if(serialInput == 'S') { // Does the command start with an S? (Start)
serialMode = true;
Serial.println("Received serial start pulse, overriding force feedback!");
#ifdef USES_RUMBLE
digitalWrite(rumblePin, LOW);
rumbleHappened = false;
rumbleHappening = false;
#endif // USES_RUMBLE
#ifdef USES_SOLENOID
digitalWrite(solenoidPin, LOW);
solenoidFirstShot = false;
#endif // USES_SOLENOID
triggerHeld = false;
burstFiring = false;
burstFireCount = 0;
} else if(serialInput == 'M') { // Does the command start with an M? (Mode)
serialInput = Serial.read(); // Read the second bit.
if(serialInput == '1') { // Is it M1? (Offscreen button mode)
offscreenButton = true; // Set that if so.
}
} else if(serialInput == 'E') { // Is it an E command? (End)
serialMode = false; // Turn off serial mode then.
Serial.println("Received end serial pulse, releasing FF override.");
} else if(serialInput == 'F') { // Does the command start with an F (force feedback)?
serialInput = Serial.read(); // Alright, read the next bit.
if(serialInput == '0') { // Is it 0 (Sole) or 1 (Rumb)?
serialInput = Serial.read(); // nomf the x since it's meaningless.
serialInput = Serial.read(); // Read the next number.
if(serialInput == '1' || serialInput == '2') { // Is it a non-zero value? (For solenoids, they're the same effectively)
bitWrite(serialQueue, 0, 1); // Queue the solenoid on bit.
} else {
bitWrite(serialQueue, 0, 0); // Queue the solenoid off bit.
}
} else if(serialInput == '1') { // it's rumble then?
serialInput = Serial.read(); // nomf the x since it's meaningless.
serialInput = Serial.read(); // read the next number.
if(serialInput == '1') { // Is it an on signal?
bitWrite(serialQueue, 1, 1); // Queue the rumble on bit.
} else if(serialInput == '2') { // Is it a pulsed on signal?
bitWrite(serialQueue, 2, 1); // Set the rumble pulsed bit.
String serialInputS = Serial.readStringUntil('x'); // Read the rest up until the x padding bit, since it could be either 1 or three characters long.
// TODO: is it always "x"? Or is it a period? We can only do one or the other. :x
serialPulses = serialInputS.toInt(); // This is the amount of rumble pulses queued.
serialPulsesLast = 0; // Reset the serialPulsesLast count.
} else { // Else, it's a rumble off signal.
bitWrite(serialQueue, 1, 0); // Queue both the rumble off bit...
bitWrite(serialQueue, 2, 0); // And the rumble pulsed bit.
}
}
}
}

...And here is where our queue is processed.
void SerialHandling() // Where we let the serial in stream handle things.
{ // As far as I know, DemulShooter/MAMEHOOKER handles all the timing and safety for us.
// So all we have to do is just read and process what it sends us at face value.
// The only exception is rumble PULSE bits, where we actually do need to calculate that ourselves.
// Further MY OWN goals? FURTHER THIS, MOTHERFUCKER:
#ifdef USES_SOLENOID
if(bitRead(serialQueue, 0)) { // If the solenoid bit is on,
digitalWrite(solenoidPin, HIGH); // Make it go!
} else { // or if it's not,
digitalWrite(solenoidPin, LOW); // turn it off!
}
#endif // USES_SOLENOID
#ifdef USES_RUMBLE
if(bitRead(serialQueue, 1)) { // Is the rumble on bit set?
digitalWrite(rumblePin, HIGH); // turn/keep it on.
bitWrite(serialQueue, 2, 0); // If we set a rumble bit on, I guess it should override the rumble pulse bit?
} else if(bitRead(serialQueue, 2)) { // of if the rumble pulse bit is set,
if(!serialPulsesLast) { // is the pulses last bit set to off?
analogWrite(rumblePin, 115); // we're starting fresh, so use the stage 0 value.
serialPulseStage = 0; // Set that we're at stage 0.
serialPulsesLast = 1; // Set that we've started a pulse rumble command, and start counting how many pulses we're doing.
} else if(serialPulsesLast <= serialPulses) { // Have we exceeded the set amount of pulses the rumble command called for?
unsigned long currentMillis = millis(); // Calibrate the timer.
if(currentMillis - serialPulsesLastUpdate > serialPulsesLength) { // have we waited enough time between pulse stages?
switch(serialPulseStage) { // If so, let's start processing.
case 0: // Basically, each case
analogWrite(rumblePin, 175);// bumps up the intensity, (lowest to rising)
serialPulseStage++; // and increments the stage of the pulse.
break; // Then quits the switch.
case 1:
analogWrite(rumblePin, 255);// (rising to peak)
serialPulseStage++;
break;
case 2:
analogWrite(rumblePin, 160);// (peak to falling,)
serialPulseStage++;
break;
case 3:
analogWrite(rumblePin, 120); // (falling to rest,)
serialPulseStage++;
break;
case 4: // For the final case,
analogWrite(rumblePin, 110); // we've set the rumble pin back to the starting value, stage 0.
serialPulseStage = 0; // Reset the counter back to stage 0.
serialPulsesLast++; // We've done a full pulse, so increment the amount we've done so far.
break;
}
}
} else { // ...or the pulses count is complete.
digitalWrite(rumblePin, LOW); // turn off the motor,
bitWrite(serialQueue, 2, 0); // and set the rumble pulses bit off, now that we've completed it.
}
} else { // ...or we're being told to turn it off outright.
digitalWrite(rumblePin, LOW);
}
#endif // USES_RUMBLE
Serial.println(serialQueue, BIN);
}

Now, granted, in hindsight I maybe should be processing the queue every cycle rather than only on every serial receipt, and I'll fix that shortly.

My apologies if I sound really abrasive here - I've gone through enough trouble just to get to this point.

@SeongGino
Copy link
Owner

SeongGino commented Nov 10, 2023

Soooo some time's passed.

Wouldn't you believe that I actually had an easier time getting Mamehooker to work on LINUX than on Windows 10?
Yeah. Fuck Windows.

Anyways--
Now that I got mamehook going on my main/dev system and was able to test it, it seems like the current Mamehook code works. So long as Mamehook is started before demulshooter before the game in question, the codes configured in the individual game inis worked fine when pointing at the right COM port (I have to use COM 2, it's linux shit--regardless!)

From what I can tell, the code responds accordingly to F0 and F1 codes sent to it. I'm also pushing a fix for the serial handover mode to use its own offscreenButton bit so it doesn't interfere with the gun's setting. Otherwise I haven't tested games that use a pulse type bit, but those worked fine in testing as well.

Please do report back what you find, if there are any problems.

Though one thing; is it normal for Mamehook to only be able to send solenoid or rumble event codes at a time? the config I got for Haunted Museum has the recoil working for individual shots and the motor working for damage, but getting damaged always seemed to supercede the solenoid like it's just ignoring that part--despite the code being able to parse both simultaneously, and it isn't clearing commands from the queue until explicitly told to, unless it's a rumble/solenoid pulse bit.

EDIT: Now that I'm going through games to see what works, I would REALLY appreciate if some individuals from the GUN4IR community could offer their config files as well so I could package them all up and make them more accessible for people. The package I got has quite a few game entries that just... don't work for guns because they don't even use COM writes. And with all the other obligations I have, I can not be arsed to configure each and every one of these files to make sure they work (like some use Solenoid pulse requests, but with the pulse counter set to 0, which... what?).

I'm all for Mamehook support as a headlining feature, only so long as it isn't a nightmare to find configs so people in the future won't go through the same headaches as I did. (^^;

@cmjdbb
Copy link
Author

cmjdbb commented Nov 11, 2023

I haven't tested your update yet, so I cannot confirm if there is no motor vibration as you mentioned. It is possible that the ini parameters are not configured correctly. After I have tested your new code, I will check if it is correct or not, and then I will reply to you.

@cmjdbb
Copy link
Author

cmjdbb commented Nov 11, 2023

sdr.txt
This is a complete ini file. Rename it to ini format and other games can directly copy and use it.

@cmjdbb
Copy link
Author

cmjdbb commented Nov 11, 2023

RGB LED.txt
This is an ini file with RGB LED. Please rename it to an ini file.

@cmjdbb
Copy link
Author

cmjdbb commented Nov 11, 2023

I believe that everyone, after reading these ini files and the previous documentation, should be able to use MAMEHOOK. If there are any further questions, please provide a detailed description and I will try my best to provide explanations.

Regarding the automatic mode in the code, as I mentioned earlier, when the fire button is pressed, it will automatically click 6 times and then automatically press the right button once.

Regarding the camera issue you mentioned, DFRobot is using a disassembled camera that has been discontinued. The new camera supports 16 spotlights, has a 140-degree wide-angle lens, does not require an additional lens, uses the SPI interface, and has a resolution of 4098*4098. In theory, it should have faster speed. However, modifying the DFRobotIRPositionEx library and interface would be necessary. Due to a confidentiality agreement regarding the development materials for the new camera, they cannot be shared with everyone.

@SeongGino
Copy link
Owner

Regarding the camera issue you mentioned,

Your mentioning this is literally the first time the word 'camera' has been said in this thread, so I don't even know where this is coming from lol. But uh... good to know?

We'll come back around to that when GUN4IR devs have to change their cameras too. If the stock does ever dry up, I know Wii Cameras can be jerryrigged into effectively the same module (page 14)


Anyways, I've updated the mamehook related stuff a few times since you've commented; having just pushed most of the LED support. Only thing unimplemented there is LED pulse commands, which I'll have to get around to another time.

There might be a slight? possibility that the code may crash under sustained serial communication, which I'm not quite sure the root cause of and how it can be fixed. As a half-measure, I added a 1ms delay at the end of each loop, so it should?? be stable (can only go off my ~15min of Spirits of Zeon testing) but do report if there are problems regarding that.

@cmjdbb
Copy link
Author

cmjdbb commented Nov 11, 2023

I tested your update and encountered the following issues: MAMEHOOK is functioning, but the electromagnet does not output pulses; instead, it maintains a high level of output. There is no motor vibration output when attacked. The light gun in the game quickly loses connection (crashes) and requires exiting the game and restarting in order to use it again. If MAMEHOOK is disabled, compilation will result in errors.

@SeongGino
Copy link
Owner

SeongGino commented Nov 14, 2023

The electromagnet has synchronized vibration signals, but the output pulses are not very good.

I unfortunately can't really fix this, as the PWM timing for the "analog" writes I do to the solenoid when it's pulsing is extremely fickle - the values in the sketch are quite literally the only combination I can use for my setup that gives a desired "pulse" (whatever the heck it's supposed to feel like), but it's entirely possible that it's different for others. But if I change those, then it's too powerful for mine.

For reference, the values in question are at:

if(!serialSolPulsesLast) {
analogWrite(solenoidPin, 178);
serialSolPulseOn = true;
serialSolPulsesLast = 1;
serialSolPulses++; // cheating a bit hehe
} else if(serialSolPulsesLast <= serialSolPulses) {
unsigned long currentMillis = millis();
if(currentMillis - serialSolPulsesLastUpdate > serialSolPulsesLength) {
if(serialSolPulseOn) {
analogWrite(solenoidPin, 122);
serialSolPulseOn = false;
serialSolPulsesLast++;
serialSolPulsesLastUpdate = millis();
} else {
analogWrite(solenoidPin, 178);
serialSolPulseOn = true;
serialSolPulsesLastUpdate = millis();
}

There is still no rumbling sound when being attacked,

Check the ini for your game's FF configuration, because it is definitely working on my end with multiple games.

and it still crashes.

Known issue, no known fix right now as described previously.

The external screen fire has changed to the middle button of the mouse.

This is physically impossible; we only ever press the right mouse button in either normal-off-screen-button or serial-off-screen button mode. I cannot reproduce this locally in either case.

@cmjdbb
Copy link
Author

cmjdbb commented Nov 14, 2023

Comparison has been made, and after the change to dual-core in 2040, there is no change in the delay. If the fire button is not pressed, there will be no crash.

@cmjdbb
Copy link
Author

cmjdbb commented Nov 14, 2023

After the update, the following issues remain: when pressing the fire button outside the screen, both the right click and middle click are triggered simultaneously instead of just the right click. In some games, the middle click is the key for changing weapons, so this will also result in weapon changes during ammunition reloading. I have tested MAMEHOOKE with the original, normal ini parameters, but there is no rumble sound. What should be the correct ini parameters for enabling rumble sound? So far, I haven't encountered any crash issues.
Here are my settings.
#define MAMEHOOKER

//#define USES_SWITCHES
#ifdef USES_SWITCHES
const byte autofireSwitch = 18;
#endif // USES_SWITCHES

#define USES_RUMBLE
#ifdef USES_RUMBLE
bool rumbleActive = true;
#ifdef USES_SWITCHES
const byte rumbleSwitch = 19;
#endif // USES_SWITCHES

// TODO: actually finish this.
//#define RUMBLE_FF
#if defined(RUMBLE_FF) && defined(USES_SOLENOID)
    #error Rumble Force-feedback is incompatible with Solenoids! Use either one or the other.
#endif // RUMBLE_FF && USES_SOLENOID

#endif // USES_RUMBLE

#define USES_SOLENOID
#ifdef USES_SOLENOID
bool solenoidActive = true;
#ifdef USES_SWITCHES
const byte solenoidSwitch = 20;
#endif // USES_SWITCHES

#ifdef USES_TEMP    
    const byte tempPin = A0;                     
    const byte tempNormal = 50;                  
    const byte tempWarning = 60;                 
#endif // USES_TEMP                              

#endif // USES_SOLENOID

bool autofireActive = false;
bool offscreenButton = true;
bool burstFireActive = false;

@SeongGino
Copy link
Owner

SeongGino commented Nov 14, 2023

I had to get the current release fresh off the repo, replace my dev environment with the release version, set my pins and flash one of my guns with that, and I simply can not reproduce any "middle & right click" behavior. Like I said, it is physically impossible for that to happen in this code - or if I'm wrong, please direct me to where in the sketch would there be a magic AbsMouse5.press(MOUSE_MIDDLE); I haven't found with searching in the TriggerFire/NotFire routines. I'm not trying to be condescending here - I'm genuinely curious how this could be happening to you, because that is some scuffed shit going on if it is...

By the by, I said INI settings - as in your MAMEHOOK SETTINGS, not the sketch configuration. And in the future, I advise you to please do not send code without ``` ``` around it. It becomes garbled and unreadable, as is shown. This is common courtesy on GitHub issues, and not following that makes it harder for me, the maintainer, to see what you're posting.

The reason your rumble motor could be not going off is a number of reasons: is the relay for your motor still working? Is it receiving 5V as it should? Is rumblePin not set to the right pin? Is your MAMEHOOK settings actually allowed to send signals when damaged? And if so, what signal is it sending? Does the game even HAVE player damaged support? Does your motor still activate if you simply point the gun off-screen and pull the trigger without any serial comms (so in normal mode)? If it doesn't, that's some fault in your hardware and I have no control over that.

If the fire button is not pressed, there will be no crash.

After testing on my end has shown it could spontaneously crash from moving the mouse, I'm starting to not believe this...
Also the problem is, 9600 baud (if my research comes out correct) is a signal every ~1ms - that is the lowest we can get our USB stack to respond with, and that isn't even the suggested default because lower polling rates = more polling = more resources used on lower end microcontrollers. So we only ever send button signals in that ~1ms rate, which might explain why it's so quick to crash. It is so hard to tell as this particular issue is nearly impossible to debug - I can't hook it up to the IDE for instance and tell where it's crashing. And technically speaking, the RP2040 doesn't even seem to respect the Serial baud rate we set anyways.

@SeongGino
Copy link
Owner

FWIW, I added a couple of 2ms delays in the TriggerFireSimple/TriggerNotFireSimple routines (the trigger operation routines for serial handoff mode) directly prior to the mouse button signals get sent. Do get back to me if the latest code changes anything.

@cmjdbb
Copy link
Author

cmjdbb commented Nov 15, 2023

MAMEHOOK test is invalid, don't know where the settings went wrong. If possible, please upload a version with MAMEHOOK enabled for testing.

@SeongGino
Copy link
Owner

If you don't know where it went wrong, then you'll just have to redownload the project files and start over from scratch. The documentation provided couldn't possibly spell things out any clearer than they are right now. There's not much to go wrong here...

@cmjdbb
Copy link
Author

cmjdbb commented Nov 16, 2023

It's my fault, I forgot to change the COM number. I tested it and the vibration is working fine, but after exiting the game, there is a high probability that the motor will keep outputting continuously.

@SeongGino
Copy link
Owner

SeongGino commented Nov 16, 2023

Thank you for your assistance.

but after exiting the game, there is a high probability that the motor will keep outputting continuously.

Does it now? Interesting! That does sound like a symptom of the board crashing which leads me to ask if that's what happened, but it could also be that mamehook simply didn't send an E command before closing comms (or crashed somewhere along the line, never closing the communication line and leaving that stale command). I've not run into this myself but there is a likelihood of that happening if something along the line doesn't exit cleanly.

If it happens again, I could see about either adding a serial queue clear and forcibly shutting ff periphery to the Endscript detection in the serial processing function 3293d05 added some extra safety to mitigate this; if that doesn't end up helping adequately, I might have to reconsider a serial timeout after all...

@cmjdbb
Copy link
Author

cmjdbb commented Nov 17, 2023

I use LED lights to test electromagnets and motors. It shouldn't be that there is no signal 'E' being sent, because after exiting the game, the electromagnet works normally, but the LED light of the motor stays on continuously without pulling the trigger.

@cmjdbb
Copy link
Author

cmjdbb commented Nov 17, 2023

There is another significant issue. When MAMEHOOK is not enabled, the LED light of the electromagnet flashes normally, turning on and off intermittently. However, when MAMEHOOK is enabled, the LED light of the electromagnet has a high duty cycle and remains constantly on, with only a slight flicker. It is not synchronized with the duty cycle set in the game settings, resulting in the electromagnet continuously being engaged. You can test this with games that have rapid-fire shooting, such as "Transformers: Human Alliance" by JC version.

@SeongGino
Copy link
Owner

SeongGino commented Nov 18, 2023

I use LED lights to test electromagnets and motors. It shouldn't be that there is no signal 'E' being sent, because after exiting the game, the electromagnet works normally, but the LED light of the motor stays on continuously without pulling the trigger.

I see, so you're basically substituting commands that are intended for force feedback for LED triggers instead.

I guess that makes sense, but I'm not sure if that was tested with the current code now as I've put in more stale state cleanup when an E signal is sent.

But wait,

When MAMEHOOK is not enabled, the LED light of the electromagnet flashes normally, turning on and off intermittently.

I never programmed LEDs to go off when serial mode isn't used. I've yet to even implement any user-programmable LED use outside of the board's builtin Adafruit RGB unit. So where is this coming from?

However, when MAMEHOOK is enabled, the LED light of the electromagnet has a high duty cycle and remains constantly on, with only a slight flicker.

Well unfortunately, if you're rewiring devices in a way that I haven't intended them to, this is probably a symptom of using the Adafruit libraries - they aren't exactly fast to respond to signals as surrogate force feedback, so in games like tha where the custom recoil has extremely fast on/off cycling, this is a consequence of that. That is simply the nature of handling LEDs, particularly ones where activation isn't just a simple digitalWrite(ledpin, HIGH/LOW) or something - which is why I've only tested using them as start button or banner lamps, where it's just fine.

If that is not the case, well, I don't know what you wrote then, so that's out of my control and thus I can't help.

FWIW, I have tested this myself (making ctmrecoil address an LED instead of the sol), and indeed it doesn't flicker as fast as you'd expect - because they (particularly a device's built in NeoPixel) aren't made to refresh that much without glitching. There's a lot more to that which I can't get into but it's beyond the scope of this project.

Not much I can solve with that behavior unfortunately, because it's in the hands of a third party library, which is why I don't use them for this lol.

@SeongGino
Copy link
Owner

Otherwise, I'm aware it's still crashing under certain conditions, but still no known solution to this. I thought adding delays to the trigger signal handling might help, but clearly it hasn't, so...

@cmjdbb
Copy link
Author

cmjdbb commented Nov 18, 2023

You might not have understood what I meant. I used the blinking of LED lights to test vibrations. When not using MAMEHOOK, the blinking of the LED lights during vibrations is normal. However, when MAMEHOOK is enabled, the LED lights during vibrations stay continuously on without blinking.

@cmjdbb
Copy link
Author

cmjdbb commented Nov 18, 2023

There is another bug in the game. When the fire button is held down, the gun keeps firing and vibrating even if the muzzle is pointed outside the screen. At this point, the firing and vibrations should be stopped.

@SeongGino
Copy link
Owner

SeongGino commented Nov 19, 2023

You might not have understood what I meant. I used the blinking of LED lights to test vibrations. When not using MAMEHOOK, the blinking of the LED lights during vibrations is normal.

Okay, and how are you making LED lights blink when not using MAMEHOOK if I didn't program any LED blinking when not using mamehook? The circumstances are not very clear at all here, and it makes it sound like you're putting in or replacing extra code that I'm not aware of, which could be causing additional problems in of themselves.

Unless you're talking about using the board's builtin LED for the start button lamp glow, or something to that effect - in which case, things are still in flux but I'm trying to work on one problem at a time here.

There is another bug in the game. When the fire button is held down, the gun keeps firing and vibrating even if the muzzle is pointed outside the screen. At this point, the firing and vibrations should be stopped.

According to what games exactly is this not intended behavior? Because games like Time Crisis 3-onwards absolutely does still allow shooting off the screen--you just shoot at nothing, but that's still shooting. That's up to the individual game to handle dragging shots off-screen. We do in fact handle this fine when not using serial connections. If this is with serial, well... that's what the game sends me, and I'm supposed to be reading the commands I'm sent at face value when using mamehook. 🤷‍♀️

If this is in regards to mounted turret games, well there is no such thing as an off-screen, so this is still technically accurate to what the game does. Again, that's up to the individual game to handle dragging shots off-screen. Unless there is something I'm missing here that GUN4IR does to magically compensate for this, like some unforeseen mode set code that's supposed to make the gun aware of this custom behavior.

I'm still working on serial handoff stability locally in the meantime, and testing that isn't exactly fast or convenient for me. One thing at a time for now.

@SeongGino
Copy link
Owner

SeongGino commented Nov 20, 2023

Update on stability:

Good news, it's a bug in the TinyUSB stack that causes these serial lockups and not the code itself.

Bad news, it requires a patched/third-party version of the RP2040 Arduino core. See more info at #3 (comment)

Hopefully upstream will consider fixing this issue on their end (though it has been a few months stale without a response), but in the meantime I can upload a pre-patched core on its own repository, and adjust the manual appropriately to reduce friction for new users. With that, I'll be adjusting the code as necessary to not rely on waits anymore like I added last night.

Pushed needed updates to the code, also fixes Dual Core w/ Mamehook. The instruction manual has been updated accordingly, to refer to a custom fork of the RP2040 core instead of upstream. Basically, in the IDE's "Additional boards manager URLs", replace:

https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json

with

https://github.com/SeongGino/arduino-pico/releases/download/3.2.2-tri2/package_rp2040_tri_index.json

then remove the existing Earle Philhower RP2040 core and install the Raspberry Pi Pico/RP 2040 (TRI) core. Set the board to the one used in the new dropdown as needed, re-set the build settings, and push it to the board. It should (fingers crossed) resolve the stability problems.

This will solve RP2040, but other boards will need similarly customized cores with a patched TinyUSB until it has been fixed upstream and pushed to downstream cores that utilize it.

@cmjdbb
Copy link
Author

cmjdbb commented Nov 22, 2023

Switching to the Raspberry Pi Pico/RP 2040 (TRI) with version 3.3.2, it will still crash

@SeongGino
Copy link
Owner

SeongGino commented Nov 22, 2023

Seriously?

EDIT: Assuming my patch was bad, I uploaded a new version:

https://github.com/SeongGino/arduino-pico/releases/download/3.6.1-fix/package_rp2040_fix_index.json

Uninstall the core labeled "(TRI)", install the one labeled "Fix", and make sure you're selecting the device in the boards list under the "Raspberry Pi Pico/RP2040 (Fix)" category.

If that doesn't work... Well, can't do much else, other than wait on resolution from upstream (of the Arduino core).

It might be possible to use the Pico USB stack, but it would also necessitate another minor refactoring of the input libraries to make it compatible.

@cmjdbb
Copy link
Author

cmjdbb commented Nov 24, 2023

Compile error with 3.6.1-fix.

@SeongGino
Copy link
Owner

Can't reproduce, please clarify the error you're receiving. Remember that we're still using TinyUSB so you'll have to re-set that setting.

@cmjdbb
Copy link
Author

cmjdbb commented Nov 24, 2023

3.6.1 can be used to compile normally. If 3.6.1-fix is used, error exec: "/bin/arm-none-eabi-g++": file does not exist

@cmjdbb
Copy link
Author

cmjdbb commented Nov 24, 2023

It can be compiled now, but testing still results in crashes.

@SeongGino
Copy link
Owner

If so, then what I said before still stands and it's beyond my control, unfortunately.

How long does it take for the board to lock up for you? And what exactly are you testing it with...?

@cmjdbb
Copy link
Author

cmjdbb commented Nov 25, 2023

I tested Transformers: Human Alliance using Win10 and DemuShooter, and it crashes within two to three minutes.

@SeongGino
Copy link
Owner

This might be a long shot, but have you tried playing with the serial baud rate any? We've been trying 9600 baud, but would say 4800 (~2ms) or 2400 (~4ms) baud be more stable?

I wouldn't prefer doing this as a definitive fix, but it's one way to mitigate potential crashes for the moment.

You would have to tweak the setting for the gun side on the sketch here:

Serial.begin(9600); // 9600 = 1ms data transfer rates, default for MAMEHOOKER COM devices.

And likewise in your MameStart commands on the mamehook side.

@SeongGino SeongGino added the enhancement New feature or request label Dec 25, 2023
@SeongGino
Copy link
Owner

Since the feature (or at least the main one of this issue) has been formally added and the only part of concern left is stability, I'll be closing this in favor of #3 wrt stability

@SeongGino SeongGino unpinned this issue Dec 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants