nesdev.com's "not" longest thread ever.

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Post Reply
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

nesdev.com's "not" longest thread ever.

Post by Drew Sebastino »

Again, the only reason I am posting this under SNESdev is because it is pretty much my "comfort zone". :oops: I remember looking at a discussion where tepples was showing an example of how to optimize code for the 6502 and the 65c816 and psychopathicteen said that those were the kind of "hardcore optimizations" that Space Megaforce uses and I was wondering how he would even know that. The only two ways I can think of (which are about as hard as mapping DNA) are to either open up a game file with a hex editor and look at the machine code and try to turn it into ASM (I'm sure some of file just codes for thing like the name of the file and other stuff though,) or you could possibly open up the game in a debugging emulator and change different values in ram and see what happens. The first method seems like it would take forever and the second would be way to confusing. (too bad the source code for these games haven't been given out. :roll: )
Last edited by Drew Sebastino on Mon Jan 12, 2015 6:38 pm, edited 2 times in total.
User avatar
bazz
Posts: 476
Joined: Fri Sep 02, 2011 8:34 pm
Contact:

Re: What does it mean to "hack" a game?

Post by bazz »

You just need experience. I'm not really sure what you're looking for, and I don't think you are either.. What does it mean to hack a game??? Um, whatever you want it to.

Some ppl like myself have gone into a game merely to change its color palette and we might call that a hack.. For instance changing a game characters look.. Other people get fancier, and they discover the formats/protocols to parts of the game -- like when someone discovered how the levels to Super Mario World worked, and then they created their own custom level editors and made new "hacks" of Super Mario World with all new levels. That's mega elite. Don't worry about being elite if you're having fun!! :D

Other hacks include figuring out what the game is doing logically and "re-routing" it to do something else.. The smarter you get, the bigger the modifications you can make.. I hope I'm helping you
Last edited by bazz on Wed Dec 31, 2014 4:08 pm, edited 1 time in total.
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: What does it mean to "hack" a game?

Post by lidnariq »

There are automatic disassembly tools; some expensive (IDA Pro); some free (nescom, nesrevplus); some not fully automated (e.g. FCEUX+disasm6)
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: What does it mean to "hack" a game?

Post by Drew Sebastino »

lidnariq wrote:There are automatic disassembly tools; some expensive (IDA Pro); some free (nescom, nesrevplus); some not fully automated (e.g. FCEUX+disasm6)
Based on the titles of these (I haven't looked them up) it looks like they are for the NES, unless the work for both. I have heard that coding for both systems is similar, but I'm not sure because I've never done anything for the NES. (I've always wanted to make a shooter and knew that the NES didn't quite have the "oomph" for what I was trying to do, so the SNES is the first thing I've ever tried programing for.)
bazz wrote:You just need experience. I'm not really sure what you're looking for, and I don't think you are either.. What does it mean to hack a game??? Um, whatever you want it to.

Some ppl like myself have gone into a game merely to change its color palette and we might call that a hack.. For instance changing a game characters look.. Other people get fancier, and they discover the formats/protocols to parts of the game -- like when someone discovered how the levels to Super Mario World worked, and then they created their own custom level editors and made new "hacks" of Super Mario World with all new levels. That's mega elite. Don't worry about being elite if you're having fun!! :D

Other hacks include figuring out what the game is doing logically and "re-routing" it to do something else.. The smarter you get, the bigger the modifications you can make.. I hope I'm helping you
Changing graphics is easy, (Unless they are compressed... :x) as you only need a graphics editor. I am actually more interested as to how a lot of these games run instead of actually modifying them, so I can have a better idea as to how to make a game myself.
User avatar
bazz
Posts: 476
Joined: Fri Sep 02, 2011 8:34 pm
Contact:

Re: What does it mean to "hack" a game?

Post by bazz »

There's source code to a lot of Anthrox demos.
I have a ported BSNES with debugger for OS X here: https://github.com/bazzinotti/BSNES-0.64-OSX
IT's really useful. If you don't use OSX Get BSNES 0.64 for your OS. compile with DEBUGGER symbol active and whatever other features you need/want.. That debugger is Gold
psycopathicteen
Posts: 3001
Joined: Wed May 19, 2010 6:12 pm

Re: What does it mean to "hack" a game?

Post by psycopathicteen »

Me and Tepples were poking fun at how bad programmers were with the 65816 because they were so used to 68000, and how optimizations are often seen as some kind of rocket science.
User avatar
bazz
Posts: 476
Joined: Fri Sep 02, 2011 8:34 pm
Contact:

Re: What does it mean to "hack" a game?

Post by bazz »

Yes, you and tepples sure do have a taste for technicals.
93143
Posts: 1371
Joined: Fri Jul 04, 2014 9:31 pm

Re: What does it mean to "hack" a game?

Post by 93143 »

Espozo wrote:I have heard that coding for both systems is similar
There's one major difference that's relevant to disassembly - the 65816's status flags can modify the length of instruction operands (e.g. LDA #$xx vs. LDA #$xxxx). If I understand correctly, this means that the disassembler has to be execution-based (ie: it has to step through the code and see what it does) in order to not get out of sync with the opcode/operand sequence.

I've actually had this problem with the no$sns debugger; it seems to disassemble code based on the current state of the status register, which can cause it to output nonsense if you're looking at a section of code that's supposed to happen with different settings.
Last edited by 93143 on Wed Dec 31, 2014 5:31 pm, edited 1 time in total.
User avatar
bazz
Posts: 476
Joined: Fri Sep 02, 2011 8:34 pm
Contact:

Re: What does it mean to "hack" a game?

Post by bazz »

^ ^ ^ precisely.

You won't have that problem with Byuu's BSNES Debugger
User avatar
koitsu
Posts: 4203
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: What does it mean to "hack" a game?

Post by koitsu »

Focusing on just one part:
Espozo wrote:... The only two ways I can think of (which are about as hard as mapping DNA) are to either open up a game file with a hex editor and look at the machine code and try to turn it into ASM (I'm sure some of file just codes for thing like the name of the file and other stuff though,) or you could possibly open up the game in a debugging emulator and change different values in ram and see what happens. The first method seems like it would take forever and the second would be way to confusing. (too bad the source code for these games haven't been given out. :roll: )
The term you're looking for is reverse-engineering. And yes, for commercial games that don't provide source code (such is the case of 98% of SNES/SFC games out there), the options you've listed are all that's available. There isn't any kind of "smart forensics" software that can use heuristics to analyse something and create source code for you, or tell you the hows/whys of a game's design. I'll go out on a limb here and say: the idea in itself (of such analysis software) is preposterous/ridiculous. Computers are only as clever as the human using them, but it becomes a recursive mess when a human tries to write something for a computer that analyses compiled/assembled results for a computer that was written by a human (lost yet?). TL;DR -- humans are clever, computers are not.

Disassembly of a game/program, followed by going through it line by line, is pretty much the only way you'll ever truly know what the game is doing. There are people out there who actually love doing this (psychopathicteen might be one of them); a colleague of mine also loves doing it (for any platform).

Furthermore, even if the source code to said commercial games was released, what makes you think it'd be more easily understood than a disassembly? Sure, now you've got multiple files laying around, probably thousands of labels and variables all with names you yourself have no familiarity with -- you still have to reverse-engineer the code more or less. You know what I'm saying? Just because source code is available to something doesn't mean the person looking at it can easily understand it.

But there is something that's kind of in-between these two things though: romhacking. It's hard to explain tersely, because the methodology varies per skill set of the person doing the romhacking. A lot of folks do Japanese-to-English translations of games this way, despite not knowing any 6502/65816 (really!). It greatly depends on the game though, as I'm sure you know. And a lot of the time, the romhacker (who has no assembly knowledge) gets stuck in their effort, and has to find someone who DOES know assembly to reverse-engineer part of the text drawing routine, or graphics routine, etc. and modify the code there so that it'll work with the desired goal. I've done romhacking stuff for a while now (usually helping out other romhackers), but I've never actually completed a project fully on my own. (I have two in progress -- one is massively insanely complex (god damn you Chun Soft!), and the other is less complex and doable but requires a lot of uninterrupted attention and is still complex in its own right (god damn you Konami!))

If you want to get into romhacking, there is an entire site and forum filled with people doing just that: http://www.romhacking.net/ (we used to host them at Parodius). Gideon Zhi also occasionally does Twitch streaming of his romhacking + debugging sessions, so you can watch/listen to him and what he's doing plus chat with him in real-time.

Anyway, all that leads to ask something..

You seem to do a lot of complaining about the state of programming (particularly in assembly) in these parts, and I get the impression you are very frustrated with the nature of the beast. Is that the case? Before responding -- I politely ask that you to read what I've said and sleep on it (trust me!). I need you to be introspective on this one. Know that I'm not attacking you (honest!), it's just that many of your posts have a strenuous/stress-induced nature to them, like you're frustrated about development on classic consoles. If you aren't? Cool/great! And if you are? Then that's okay too, but you should decide how you want to deal with that frustration. Starting out is difficult; none of this stuff is easy. But then again, think back to a subject in school (say, mathematics) that you had trouble understanding and got frustrated with (for me that would be advanced algebra, calculus, chemistry, and biology). As an adult nobody is forcing you to learn anything, so you can go at your own pace, or even simply say "Nah, I don't wanna do this any more". There's no shame in any of that! Don't let anyone tell you otherwise.

There is nothing easy about video game development on any system. Programming in itself is not easy, and game development adds a whole new layer of "omfg" to the picture. And don't even get me started on 3D stuff (I'll NEVER understand it, I find it all ridiculously complex and insane compared to 2D platforms). I've been doing what I do (with 65xxx and consoles both) since the mid-to-late 80s, and despite all that time I've never written a game. And there's a reason for that: I've spent so much time working "on" consoles (but not as low-level as guys like, say, lidnariq or kevtris) that my gut says "don't attempt a game, dude. You will get very very irritated and angry", so I don't. I've done a small little demo on the SNES included with my SNES docs (includes source), and also did the FF2e (NES) intro for Neo Demiforce in their translation project (and that had wonderful bugs due to us not knowing how the PPU fully worked at the time). Yet, on the flip side, guys like tepples are able to churn out a game in a few months (depends on how simple/complex) -- we're just different people.

I'll note that I did work for a few months on an Apple IIGS game, inspired by Gradius 3 and Space Megaforce (first time I've heard that game mentioned in years is in this thread, how funny!) but gave up because the IIGS's graphical capabilities were simply too limited -- mainly full-screen panning/scrolling wasn't possible (and not enough CPU time to do it all via software in one frame). My SNES sat next to me the entire time, taunting me. "Psst... you have 4 overlayed backgrounds here... you can set background X/Y positions for panning in only a few cycles... psst..." I guess the only "claim to fame" I have is doing an Apple IIGS demo along with a friend of mine.

I share these stories as a way to say it's okay to be frustrated (if you are), but that you may want to dig deeper to figure out how to leverage that frustration.
User avatar
koitsu
Posts: 4203
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: What does it mean to "hack" a game?

Post by koitsu »

93143 wrote:There's one major difference that's relevant to disassembly - the 65816's status flags can modify the length of instruction operands (e.g. LDA #$xx vs. LDA #$xxxx). If I understand correctly, this means that the disassembler has to be execution-based (ie: it has to step through the code and see what it does) in order to not get out of sync with the opcode/operand sequence.

I've actually had this problem with the no$sns debugger; it seems to disassemble code based on the current state of the status register, which can cause it to output nonsense if you're looking at a section of code that's supposed to happen with different settings.
Random tidbit point, but for the 6502/NES, specifically FCEUX: its real-time debugger does stupid shit like this:

Code: Select all

$E322:85 DD     STA $00DD = #$00           A:01 X:00 Y:06 S:F2 P:nvUbdIzc
$E324:A6 DE     LDX $00DE = #$01           A:01 X:00 Y:06 S:F2 P:nvUbdIzc
$E326:E6 DE     INC $00DE = #$01           A:01 X:01 Y:06 S:F2 P:nvUbdIzc
$E328:A5 DF     LDA $00DF = #$05           A:01 X:01 Y:06 S:F2 P:nvUbdIzc
Look very closely at the instructions here -- these are opcodes which use ZP addressing, yet the addresses shown in the disassembly are full 16-bit absolute addresses (which use a completely different opcode). Ignore the = #$xxx stuff (that's just showing you, at that moment in time, what the contents of the effective address contained). Those instructions should read STA $DD, LDX $DE, INC $DE, LDA $DF, but don't.

I can't tell you how many times this has confused me / caused me issues / pissed me off. It's almost like someone is just doing printf("$%04X", address) for all addresses, no matter the opcode used. It drives me insane.
User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Re: What does it mean to "hack" a game?

Post by Kasumi »

Man... Koitsu ninjaing me. Still posting.
or you could possibly open up the game in a debugging emulator and change different values in ram and see what happens.
The first step is usually finding RAM, which is pretty easy with a debugging emulator. The process is not changing values randomly, there's a method. You have a goal in mind.

A very common feature in debuggers allows you to narrow down RAM locations based on conditions. Say I'm playing a platformer, I want to find out which RAM value represents the player's X speed. If I stand still, it's probably gonna be zero.

So I eliminate every single piece of RAM that's not zero.
Then, I press right for a few frames to accelerate.
I now eliminate every single piece of RAM that either hasn't changed, or decreased.

Maybe there's only about three to four bytes of RAM it could be at this point. So I play in real time and watch to see which one corresponds to my movements.

Or... if there's still like sixty bytes of RAM, you let the player come to a stop completely. Then eliminate all RAM that isn't zero from your list.

Then press left and eliminate all RAM that either hasn't changed or increased.

(Just to note, the debugger keeps track of this RAM, and narrows it down. It's not like you've got a notepad file of what RAM it could be, and then have to verify each. You say, "Get rid of RAM that's not zero." And all RAM that's not zero is instantly gone from that list. You keep doing this until you've found what you're looking for.)

By now you've probably found X speed. Now, the above makes a few assumptions. It's not necessarily guaranteed that the RAM representing X speed is 0 when the player is standing still. And it's not necessarily true that the speed increases when you hold right. It could decrease (or do something weirder). But... you think what you'd do as a programmer and look for that.

After finding RAM, it's really easy to start to look into code. You can break on read and writes of the X speed variable, which will let you see how the game's acceleration works. Because the very code that is changing the variable is right there once the break happens! A good debugger will break the moment a write or read is detected, and show you the code around it. From there you could figure out what other RAM might represent in the context of code, again just thinking how you'd do it as a programmer.

As far as modifying the program, it's a lot like writing a regular program. The thing to understand is that every assembly instruction is represented by an "opcode". Which is a byte (or some bytes) that tells the CPU what to do. When an NES (or SNES) encounters $18, it clears the carry flag. If you were writing a program and typed CLC, it would become $18 once assembled. If you programmed for either console, you know what CLC does.

If you know how to program in the assembly language you're reading, you could look at the code the debugger broke on for X speed. (Which again, a good debugger would display as code and not hex. See what Koitsu posted from FCEUX's debugger.) You'd then figure out what changes you wanted to make, just like if it was your own program. And then you'd look up the opcodes for what you want to do and change what's there. (Or ignore opcodes entirely, and assemble a code snippet and paste the block there.)

The caveat with hacking (without a disassembly) is that you cannot simply add instructions in the middle of a routine that's already there, because it would break a bunch of branches and things. So you find some free space in the rom (depending on the rom, this can be tough) to add your new routine. And then you replace a few instructions in the area you want to add something to with a jump to that free space. You put your routine in the free space(with the instructions you just replaced with the jmp before the new routine so the program still executes them). At the end, you jump back. (Or just return.)

If you truly understand how to program with a given assembly language for a given system, hacking is not a lot of new knowledge. It can certainly be challenging... but probably not like mapping DNA. If I wanted to find out how other games optimized say... their graphics, I'd break on writes to the system in question's graphics registers.

Find how what's put there. Trace how THAT got there. Trace how THAT got there. Until I found it. Whee, crash course on executable hacking. You have the start with a goal, rather than, "I'm gonna read through this entire game line by line." Even if your goal is eventually making a disassembly, you break it up into smaller parts. First identifying what the RAM is used for, maybe.

tl;dr: Learning to program first is highly recommended. If hacking still seems difficult, keep practicing straight programming. I never learned to hack. One day, my friend asked me to make a small hack and I realized I totally could. I've never read anything on the subject.

A named edit (though I anticipate doing a few more to fix lots of typos: Knowing if something is hardcore optimized is again, just knowing the language. Sometimes you look at code in a game and just say, "Damn. This is REALLY clever."
Last edited by Kasumi on Wed Dec 31, 2014 6:24 pm, edited 1 time in total.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: What does it mean to "hack" a game?

Post by tepples »

Kasumi wrote:The first step is usually finding RAM, which is pretty easy with a debugging emulator. The process is not changing values randomly, there's a method. You have a goal in mind.

A very common feature in debuggers allows you to narrow down RAM locations based on conditions.
This "cheat finder" is good for some use cases. But if you're aiming to completely understand a game engine, you can start by putting breakpoints on its input and output (I/O). On the NES and Super NES, I/O is done by writing to memory-mapped ports in $2xxx and $4xxx. This lets you find the code that performs I/O, and then you can discover data structures related to what the I/O does.
Say I'm playing a platformer, I want to find out which RAM value represents the player's X speed. If I stand still, it's probably gonna be zero.

So I eliminate every single piece of RAM that's not zero.
Then, I press right for a few frame to accelerate.
I now eliminate every single piece of RAM that either hasn't changed, or decreased.

Maybe at there's only about three to four bytes of RAM it could be. So I play in real time and watch to see which corresponds to my movements.
Or come at it from the other direction. Look for the part that reads the controller, which should be easy with a write breakpoint on $4016 and (in the Super NES's case) read breakpoints on $4218-$421F. This will show you where the game reads the controllers, and watching it read the controllers will show you the RAM address where the game stashes button states. Then you can put a read breakpoint on that address and see where the game makes decisions based on these button states. You'll eventually end up discovering the code that causes movement and jumping.
If I wanted to find out how other games optimized say... their graphics, I'd break on writes to the system in question's graphics registers.

Find how what's put there. Trace how THAT got there. Trace how THAT got there. Until I found it. Whee, crash course on executable hacking. You have the start with a goal, rather than, "I'm gonna read through this entire game line by line." Even if your goal is eventually making a disassembly, you break it up into smaller parts. First identifying what the RAM is used for, maybe.
Heck, you can find the character's position in RAM (and thus the movement code) by looking at the sprite display lists sent to the PPU. Put a write breakpoint on DMA registers ($4014 on NES, $43xx on Super NES) and find copies to OAM. This will give you the address of the buffer that the game uses for the display list. With a write breakpoint on the display list, you can find the sprite drawing routines. Look at what those read from, and you'll know where the position is. Look for what modifies that, and you have movement code.

Image
Toady artwork from Yoshi's Island


Just keep in mind what Tim Toady says: There is more than one way to do it.
User avatar
bazz
Posts: 476
Joined: Fri Sep 02, 2011 8:34 pm
Contact:

Re: What does it mean to "hack" a game?

Post by bazz »

koitsu you are so well spoken, today :P (hhahaa!)
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: What does it mean to "hack" a game?

Post by Drew Sebastino »

Now to reply to koitsu monster post... Don't worry I'm not angry at you. :wink: (Why would I be anyway?)
koitsu wrote:You seem to do a lot of complaining about the state of programming (particularly in assembly) in these parts, and I get the impression you are very frustrated with the nature of the beast. Is that the case?
To be honest with you, I've never done any programing with anything but assembly. The thought of writing code that you know isn't going to be very optimized kind of disgusts me and I like to know exactly what I am doing.
koitsu wrote:many of your posts have a strenuous/stress-induced nature to them, like you're frustrated about development on classic consoles.
Yes, mostly because I almost don't see why I have so much difficulty programing and it seems like everyone else doesn't. (I know I really sounded like a looser there.) It would be like If you took Spanish class and you made terrible grades and everyone else made hundreds all the time even if you did your best. Incase you haven't noticed, I'm a bit of a perfectionist. (I'm sure my OCD doesn't help.) What I think is one of my main flaws is that I like to get ahead of myself. I was originally thought about programing for the NES, but I didn't even do anything for it before I decided that I wanted to work with the SNES, which was the first system I ever programmed for. Heck, I just got into programing a little over four months ago. It seems like most of the people on this website are either in college or are college graduates while I just graduated middle school about a year a go. I should probably slow down a bit... The other thing that I think gets my frustrated is how the SNES was made. Don't get me wrong, It's a great system (my favorite, actually) but I feel like some of the design choices were a bit strange. (Not saying I could have done better, of course.) I do always hear people complain about the CPU speed and that leads to one question... Why didn't Nintendo overclock it? I'm no hardware expert, but I always thought you could keep increasing CPU speed until the CPU melted, which the SNES CPU is far from doing as the console doesn't even generate a half a degree of heat. Heck, isn't the SA-1 just a 65c816 running at 10 megahertz? If it is, that just shows it can be done.

Now for the less-personal stuff...
koitsu wrote:even if the source code to said commercial games was released, what makes you think it'd be more easily understood than a disassembly? Sure, now you've got multiple files laying around, probably thousands of labels and variables all with names you yourself have no familiarity with -- you still have to reverse-engineer the code more or less. You know what I'm saying? Just because source code is available to something doesn't mean the person looking at it can easily understand it.
I know what you mean. I just figured that it would still be easier to figure out how game works this way than trying to make a code from looking at the machine code and still having to figure out what it means without having any notes written on the side (If the people write any) or having any of the registers given names that say what they are being used for. (Even if the names are not that clear.)

And now for the random stuff...

I tried the snes demo you made but it didn't work. I looked at vram, cgram, oam, and work ram and they were all blank. I looked at the source code, (not to hard) but from the looks of it, it doesn't look like something I wouldn't be able to make.
koitsu wrote:I'll note that I did work for a few months on an Apple IIGS game, inspired by Gradius 3 and Space Megaforce (first time I've heard that game mentioned in years is in this thread, how funny!)
Really? people seem to act like it's the holly grail or something with many people calling it the "best shooter ever". I'm not saying it's a bad game by any means, but it's just not my cup of tea. I think you can probably guess what my favorite shooter franchise is. (Hint: by the same company that made my profile picture!)
koitsu wrote: My SNES sat next to me the entire time, taunting me. "Psst... you have 4 overlayed backgrounds here...
And then your GBA said, "Psst... you have 4 actually useful backgrounds here".

Lastly, what the heck is this? I'm guessing C?

printf("$%04X", address)
Last edited by Drew Sebastino on Wed Dec 31, 2014 11:09 pm, edited 5 times in total.
Post Reply