shonumi / gbe-plus

DMG/GBC/GBA emulator and experimental NDS emulator.
GNU General Public License v2.0
501 stars 79 forks source link

IR support for Devil Children Kuro no Sho #168

Open cmccord-dev opened 4 days ago

cmccord-dev commented 4 days ago

So I've been trying to get IR working for Devil Children Kuro no Sho. When doing a fusion there's a chance for a mutation to occur whenever IR is present, but the TV remote option isn't quite good enough.
At first I was wondering if the pulse lengths were too slow. I haven't spent a lot of time looking at the code, but it checks 24 pulses and needs at least 17 high to register a "high" pulse. The main loop is ~7 instructions long but I'm not quite sure how that translates into cycles. Either way I'm pretty sure it's at least 7 cycles, if not more. At 7 cycles it's quite unlikely a pulse will get registered, and the game checks for several on off pulses in a loop. Another issue is it seems the game wants a either a specific or variable number of IR pulses. the default 64 pulses always fail even with a longer pulse time. I managed to get it working by also randomizing the number of on off pulses every time the IR transmission is started.
I can do some more digging to find out the exact mechanics if you'd like. If the number of pulses needed to trigger the mutation event isn't random, then it should be possible to let players choose how likely or unlikely the event should be.

shonumi commented 4 days ago

Thanks for the issue report! If I had to guess, I'd say this game is probably like Doraemon Memories, which means it needs IR input that follows the NEC protocol for a TV remote. It could also be another common protocol, but NEC seems like the most likely target.

The current implementation of GBE+'s TV remote option just blasts a random series of IR pulses. This method works for some games (such as Bomberman Max, Chee Chai Alien, and Pokemon Breeder Mini), but not for these types of games. Check out Issue #160 for more details. Back when the TV remote option was added, it was assumed all games were like this.

In hindsight, I think GBC games like Bomberman Max is more receptive to random IR noise since they were released internationally and probably couldn't rely on protocols that might be less common outside of Japan. Also, detecting IR noise would be easier than supporting multiple protocols or changing NA releases to support specific protocols.

Anyway, it's definitely on my radar. Hopefully I'll get around to it soon-ish.

cmccord-dev commented 3 days ago

I saw that issue before I posted but assumed it wasn't related. The code I was looking at definitely doesn't seem to be trying to actually decode the signal, just check that pulses exist or not. there's nothing even close to resembling proper timing and NEC Also, we have a GBC and haven't been able to trigger it using any of our IR remotes, though come to think if it I'm not sure what protocol they use. it is a bit tedious to test, and I should probably write a rom to check if the IR is actually functioning or not on this unit. it could just be that the timing window is obnoxiously short. even if IR is present it's not guaranteed.
I'd be more than happy to test if your implementation works for the game when you get around to it though! I'll let you know if I discover anything else.

shonumi commented 3 days ago

Can you send me your save file? I'm not too familiar with this game, so I'd rather not have to play all the way from the beginning for testing. Thanks in advance!

cmccord-dev commented 2 days ago

Sure, here you go: dcwhite.zip

Immediately to the right is an NPC you can talk to. Select the first option. It'll bring up a list of demons you can fuse. Don't choose the first one since it's special. After selecting you'll select a second, it'll show a preview and ask you to confirm. Then an animation will play where the sprites move towards each other. There's a flash and that's about when the IR is checked. You can tell if it worked if there's a sort of wavy effect.
The relevant function is at 06:7090. If this function returns 1, a mutation event happens, otherwise it's a normal fusion.
IR is read in the function at 06:721f, though it's called from a few places in the aforementioned function. Feel free to let me know if you have any questions!