Hey look, someone ripped off my idea :D

Strictly for discussing ZSNES development and for submitting code. You can also join us on IRC at irc.libera.chat in #zsnes.
Please, no requests here.

Moderator: ZSNES Mods

Post Reply
byuu

Hey look, someone ripped off my idea :D

Post by byuu »

http://ddmyab.com/
We have seen console videogame system emulators improve on their real-life counterparts by way of higher resolutions, fancy graphics blitters and improved audio output. But the latest versions of zSNESXbox for the Microsoft XBox go to show that there’s still room for invention. The hard working author, Nes5602, has recently added a novel implementation of force feedback to the emulator. Far more than just a space-wasting addition, however, the rumble conditions are configurable per game.
Oh well, I'd be interested in looking at his rumble file format. If it isn't too bizarre, I'll support it. I was just planning on using .ups files for this purpose, and patching the actual game code on-the-fly. If a config file can be made to make the rumble addition transparent, even better.

I wonder if he'll add MP3 and MPEG playback next. Or possibly the custom MMC that supports ROMS > 64mbits that I was throwing around.

EDIT:
http://forums.xbox-scene.com/index.php? ... 48488&st=0

Yeah, that approach is no good for me, much better to softpatch the game on load than use GG patch codes and hacks to get it working reasonably well. nes6502's approach is very prone to errors (especially his skip # counter). Much more control when you hack exactly the routine that decrements life instead. Ah well.
snes6502
Rookie
Posts: 21
Joined: Wed Mar 15, 2006 3:37 pm

Post by snes6502 »

No, actually I stole it from the Gens author that added the Streets of Rage 2 force feedback driver. I don't even know how he did it. I read about it a couple years ago and was wondering how this might work. I thought it would be a cool addition to add to ZSNES since everyone using the Xbox port will have a controller with force feedback capability. Then I came up with the idea of monitoring addresses.
nes6502's approach is very prone to errors
How is that?

Seems much harder to patch the game itself. How would you notify the emulator that a rumble needed to occur? It also seems 10 times more difficult to find the actual code in the ROM that decrements life, lives, etc.. I can find the address by searching in 10 seconds or less.

With my apprach I can start and stop the rumble on any of these scenarios:

1) Rumble on value change and stop rumbling when the timer expires
2) Rumble on value decrease and stop rumbling when the timer expires
3) Rumble on value increase and stop rumbling when the timer expires
4) Rumble on value change and stop rumbling when the value changes
5) Rumble on value change and stop rumbling when the value decreases
6) Rumble on value change and stop rumbling when the value increases
7) Rumble on value decrease and stop rumbling when the value changes
8) Rumble on value decrease and stop rumbling when the value decreases
9) Rumble on value decrease and stop rumbling when the value increases
10) Rumble on value increase and stop rumbling when the value changes
11) Rumble on value increase and stop rumbling when the value decreases
12) Rumble on value increase and stop rumbling when the value increases

That will cover virtually any scenario a game can have. Although, there are some situations that I have yet to isolate an address for. Some games use the same address to do lots of things. This can be great in some cases. For example, searching for a rumble for jumping might give you an address that controls jumping, landing, shooting a weapon, and losing energy. I've found a lot of addresses that can be used like this.

Sometimes, however, this is not desirable. For example, I've yet to find a rumble address for going off the track in Super Mario Kart that is used "only" for going off the track. But I did find one for running over the rough spots of the track in F-Zero (starts rumbling as soon as you enter it and stops as soon as you leave it). Add that to the rumble when hitting cars, losing energy, landing from jumps, and using turbos makes for a really cool F-Zero experience.

But in practice, I have been able to make rumbles for 99.9% of anything I've ever wanted (and usually with less than a minutes worth of searching).

I will admit that the rumbles to skip is only really valid when the game is first started. I will sometimes get rumbles between stages, fights, etc... But it doesn't really happen all that much (in fact, almost never).
I wonder if he'll add MP3 and MPEG playback next
No interest in MP3 or MPEG. But I do have a lot of interest in GBS, NSF, GYM, VGM, SPC, and VGZ.
byuu

Post by byuu »

No, actually I stole it from the Gens author that added the Streets of Rage 2 force feedback driver.
Ah, that's too bad. I mentioned the idea several months ago, but never got around to it because my gamepad SAYS it supports rumble, but windows drivers don't work with it. The official CD was bad in the box, and the website to get the drivers is dead. So, no rumble for me until I can find a controller that doesn't suck and has rumble. Which, for the PC... I might as well stop looking, it doesn't exist. Saigitech is the only game in town for PC gamepads, excluding console adapters.

Anyway, the idea was a good one, and I thank you for adding it. Hopefully people will really like the idea and it will catch on.
How is that?

Seems much harder to patch the game itself. How would you notify the emulator that a rumble needed to occur? It also seems 10 times more difficult to find the actual code in the ROM that decrements life, lives, etc.. I can find the address by searching in 10 seconds or less.
How? For instance, any event can delay or extend how many "ignore N writes" happen. Such as... looping the opening demo battle, pressing start quickly to get in game, etc.

Harder? Than 10 seconds, yes. For a skilled ROM hacker with a powerful debugger... not much harder to find the routine than cheat searching. And really, cheat searching is pretty much what you'd use here too, just also capture the PC address where the write occurred and log CPU instructions to get the life decrement procedure. Add some hooks into that, and you're good.

How to let the emulator know? A special emulator-only register to control rumble settings. But won't that interfere with other games? Nah, just make something like $4210 require a special string pattern be written to it, such as "SNESEMU\0". The odds of those eight bytes being written to a read only register in a real commercial game are one in a googolplex. After the writes, say... $4018,$4019 become active, and control rumble settings on port1 and 2.

It's really just a matter of polish. Your idea is quick, easy, and works in most cases. Really good for getting most games to have rumble support. My idea would result in a much more polished result that only rumbles when supposed to, 100% of the time, but likely wouldn't get more than 10 or 15 hacks made for it. That is, unless ZSNES and SNES9x added support for it. But that's quite unlikely.
No interest in MP3 or MPEG. But I do have a lot of interest in GBS, NSF, GYM, VGM, SPC, and VGZ.
I think we have a misunderstanding... I was meaning, add special emulator registers to play these files in game. Now your favorite SNES game has redbook audio, FMV animated sequences, and rumble feedback. It's basically a Sega CD class game now.
It sounds like you're meaning just general support for playing those files from within the ZSNES GUI interface as just a standalone audio player. But if you mean add support for SNES games to play all of those formats... hmm. The small filesizes would be nice, at least. Much easier to embed those in ROMs.
snes6502
Rookie
Posts: 21
Joined: Wed Mar 15, 2006 3:37 pm

Post by snes6502 »

Ah, that's a good idea. Not sure how it could be done since it seems few SNES games separate the chanels it uses music and sound effects for. If I could find an approach to keep the sound effects and replace the background music with something else I certainly would (I'd start with Pilotwings. It has some crummy background music).

The MPEG idea is cool as well. That would be a lot easier to do provided I had movies that would be cool to add.

However, both would seem to be hard to locate the "Stage 1 just ended" event (to trigger the playbak of a cutscene and switch background music tracks). Maybe not. Maybe it would be just as easy to find this as it is a decreasing lifebar.
Lord Nightmare
Rookie
Posts: 14
Joined: Fri Nov 26, 2004 7:50 pm
Location: PA, USA
Contact:

Post by Lord Nightmare »

Build an xbox breakaway->usb adapter. Xbox controllers have reasonable rumble, and the xbox controller drivers for windows work pretty well (though they could use some improvement and perhaps a *gasp* source release)
EDIT: Ok, I'm blind, XBCD *DID* release their source, and GPL no less!
I built two already, takes about 20 minutes of preparation and 5-10 minutes of soldering a piece. even the wire colors match the usb spec.
You can also buy premade ones from various places online, and iirc some company made various sized xbox HUBs which allows the whole controller including the breakaway connector to be connected, and may have internal circuitry to 'sanitize' the xbox pad's output to remove the need for that special driver.

Lord Nightmare

EDIT: or use an XB360 controller, those supposedly work with windows fine OOTB, but they're a tad expensive.
Last edited by Lord Nightmare on Thu Oct 12, 2006 3:44 am, edited 1 time in total.
"When life gives you zombies... *CHA-CHIK* ...you make zombie-ade!"
snes6502
Rookie
Posts: 21
Joined: Wed Mar 15, 2006 3:37 pm

Post by snes6502 »

I think I was using the smartjoy USB PC adapter. It supported up to 4 Xbox controllers at once and supported the rumble. I had some issues with deadzone calibration for the analog sticks, but overall, it worked really well. However, it didn't seem the N64 plugin would ever send much of a jolt. Or maybe this was an issue with the driver.
tetsuo55
Regular
Posts: 307
Joined: Sat Mar 04, 2006 3:17 pm

Post by tetsuo55 »

Byuu, get an xbox360 pc-edtion controller

these are awesome, work out of the box and even have special drivers if you want to do things differently, might even work on linux with those drivers

pad is really good, if i had the money i would get rid of my smartjoy and buy 4 xbox360 controllers
Jipcy
Veteran
Posts: 768
Joined: Thu Feb 03, 2005 8:18 pm
Contact:

Post by Jipcy »

tetsuo55 wrote:Byuu, get an xbox360 pc-edtion controller
I don't know if there is a difference in price, but there is no difference between the PC-edition and the ones packaged for Xbox 360s. They are identical hardware. Just the one packaged for PCs have drivers included.
[url=http://zsnes-docs.sf.net]Official ZSNES Docs[/url] | [url=http://zsnes-docs.sf.net/nsrt]NSRT Guide[/url] | [url=http://endoftransmission.net/phpBB3/viewtopic.php?t=394]Using a Wiimote w/ emulators[/url]
<_<
Rookie
Posts: 24
Joined: Sat May 07, 2005 12:29 am
Location: A boat.
Contact:

Post by <_< »

Pardon this bump but this idea has me curious. Byuu's method of patching the game seems like the better way to go, but having made hacks for games myself I can tell you this isn't exactly easy in some cases, particularly since you need to find unused space and add your routines in it, and SNES games tend to contain space that looks unused (big blocks of zero or FF) but isn't, use the same bytes as code and data, etc. Super Mario World does both of these for example.

Instead, wouldn't the best solution be a pseudo-patch method, similar to how breakpoints work in most debuggers I've used (read: No$GMB)? Rather than actually modifying the game code, you have a list of addresses that need attention. For example if $123456 is the routine that handles taking damage, then you add $123456 to this list along with some information that says "rumble for 3 seconds at 50% strength". Then whenever the routine runs, it rumbles, but the game's code is not modified at all, preventing any possible reactions by other routines and eliminating the need to actually write and add in rumble code.

I recall hearing Parasyte was working on adding this sort of thing to FCEUXD, but I'm not sure he ever did. It was an advanced breakpoint system in which you actually typed in a bytecode to form a simple series of instructions like "r0 = $123456; r1 = 42; if r0 == r1 then break;" etc. This is a bit complex for just adding rumble support, but it's worth thinking about.

Of course this "pseudo-patching" can be piggybacked onto existing breakpoint code which should already just be a list of addresses to break at and conditions to break on; just add some bytes that tell whether to break or rumble. As a bonus, it could support both Byuu's and nes6502's method at the same time - you could tell it to rumble and/or break when the address is executed, written, read, incremented, etc.

Anyway this is a very cool idea and I might just steal it myself. ;)
It's-a me, Mario! Wait, no it's not.
byuu

Post by byuu »

I've personally hacked and translated to completion at least three (two relatively massive) SNES games, so I do know the difficulty involved in my method. It's the more "correct" version, but I realize there's a severe shortage of people capable of adding such support to games.

I really like your breakpoint idea, and in fact I really wanted to add breakpoints like that to bsnes' debugger when it existed. The problem with a complex breakpoint system is that all active breakpoints have to be evaluated at every opcode edge. Not a problem for programmers wanting to test their code / track bugs in a specialized emulator debug mode, but a huge problem for end users who just want to play games.

It's easy to test for 20 chained conditions. But doing so for 12 separate breakpoints, 2.68 million times a second, will take an absolutely massive speedhit. Sure, you can short circuit logical ands/ors and failed if conditional statements, but even then it can be quite complex. As slow as bsnes is, even adding in another counter that's a simple addition on every single opcode edge will take away another ~2% of its overall speed.
PHoNyMiKe
Retrosexual
Posts: 1011
Joined: Wed Jul 28, 2004 2:09 am
Location: Rapture

Post by PHoNyMiKe »

it think it's an awesome idea. it's easy as hell to find an address that does something, and the address can be compared to values found. so lots of people can contribute like par codes.

you'd only need to check these values 60 maybe even 30 times a second, which should do like no performance hit.

now I just need an xbox.
[url=http://www.alexchiu.com/affiliates/clickthru.cgi?id=phonymike]ultimate immortality[/url]
[url=http://www.sloganizer.net/en/][img]http://www.sloganizer.net/en/image,zsnes,white,purple.png[/img][/url]
d4s
Rookie
Posts: 28
Joined: Wed Sep 08, 2004 12:05 pm

Post by d4s »

phOnYmIkE wrote:it think it's an awesome idea.
seconded.
byuu wrote: How to let the emulator know? A special emulator-only register to control rumble settings. But won't that interfere with other games? Nah, just make something like $4210 require a special string pattern be written to it, such as "SNESEMU\0". The odds of those eight bytes being written to a read only register in a real commercial game are one in a googolplex. After the writes, say... $4018,$4019 become active, and control rumble settings on port1 and 2.
you just got me into thinking...
the idea alone is already awesome, but did you ever think about adding this rumble support to an actual snes and its controllers?
now THAT would rock!

this might very well be feasible by using the i/o port that connects to both joypad ports pin6, a cell phone vibration motor and some very simple logic.
would break multitap compatiblity and probably cause problems with games that use the h/v latch on joypad port 2, but apart from that should be fine.
gotta try that out soon!
blargg
Regular
Posts: 327
Joined: Thu Jun 30, 2005 1:54 pm
Location: USA
Contact:

Post by blargg »

I just skimmed the thread and thought I'd throw in an idea. The goal is to call an action function when the program counter is at any one of a set of particular bytes in ROM, without impacting performance. The implementation simply places one of the 65816 "halt" opcodes there (assuming there are any; if not, some other rarely used opcode). On executing this opcode, the CPU emulator calls the action function with the current program counter, then gets the original opcode and executes it normally. This could be made more compatible by having the modified ROM data only used during opcode reading, but not for any other reading (implemented by having two sets of memory mapping tables). So if you want to modify a byte on a particular page of ROM, you make a copy of that page, modify the copy, and map this into program space but not data space.
byuu

Post by byuu »

That would indeed be a good idea for a program breakpoint, similar to int 3h on the x86 platform. I'd believe "wdm" would be best (you can ignore storing the signature byte if it's just for a breakpoint, anyway). I wonder if that would be enough, or if other things would need to be tested as well (eg data values and such).
blargg
Regular
Posts: 327
Joined: Thu Jun 30, 2005 1:54 pm
Location: USA
Contact:

Post by blargg »

byuu wrote:I wonder if that would be enough, or if other things would need to be tested as well (eg data values and such).
The mechanism I described would simply be a way to narrow down the amount of condition checking. Once the altered opcode was encountered, the program counter would be used to look up the particular conditions to check for. Since these would only be checked at these specific locations, the efficiency wouldn't be of much importance (unless you mark a location which is executed very often).
Post Reply