I’ve started to wikify (not that it existed in the first place) some documentation for the NES Emulator. I promise I’ll post the code, but I’d rather not shame myself so I’d prefer to clean it up a bit 🙂 However, if you’re interested just pop me some mail to firstname.lastname@example.org (bring on the SPAM…)
In other news, my wife bought me a Garmin eTrex Venture GPS system that I can’t wait to play with when we vacation in Europe this July with her family.
Based the the level of service I sometimes get, I’ve been convinced that many of the restaurants I frequent here in the UK don’t actually exist until I get there. Apparently I (may be partially) right!
As my wife is probably tired of hearing from me… it honestly feels like sometimes that as I walk in the front door of a place, the waiters are walking in through the back for the first time. It’s not that they are not nice, they just often seem so… lost. It’s not even bad service per se, so much as if though they’ve just now memorized the types of things that they should say and ask and so are just going from a script. Perhaps there are crucial aspects of ordering food in Great Britain that I haven’t yet grasped.
The hilarious part is that I am probably one of the least picky people food-wise (you could give me the completely wrong order and unless it turns out to be pile of mushrooms covered in mayo, odds are I won’t send it back) but for some reason I continuously find myself amazed by the restaurant service.
Usually they will have no idea what the specials are or, if they do, what they might contain. Sometimes we’ll order one or two things from the Appetizers section and then be asked “Any starters?”
In the States, the restaurant service is really based on tips, so they have huge personal incentive to give excellent service. While “service charges” are becoming more common, in general it’s still only 10% and gets distributed to the whole staff as far as I know. I wouldn’t be surprised if this is a large component of the whole situation… they can go on auto-pilot and it won’t affect them much either way financially.
Anyone else notice this?
Perhaps I’m just delirious from lack of sleep but given that you can have “perfect information” from within an emulator, it should be possible create Mario, Zelda, Contra, etc playing “bots”!
If you don’t want to “cheat”, it can be based on the screen image (like a human would get) but this would be significantly more difficult. I’d be really impressed if you could make something that navigates a signal level through “vision”.
That would make a damn good master’s thesis/senior project I think.
Some quick googling didn’t turn up anything, but I wouldn’t be surprised if such a thing already exists. Any takers?
Quick update because I can’t sleep (4:15am my time)
Once I got the LWJGL (specifically using the JInput stuff built into it), it only took me about 30 minutes to get the emulator to work with a gamepad controller! I just set up a thread that continously hits Controller.poll() to find out what’s currently being pressed. I will probably slow it down and only poll after the controller has been “strobed” by the game (by writing a 1 to $4016).
I bought a dual PS2->USB adapter from Amazon and my only complaint is that both controllers show up with the same name. I just hardcoded the code to use the second one, but I’ll add a configuration screen for that. They show up as joysticks, and the digital pad ends up mapping to the “Point of View” hat. Thankfully it maps fairly well, with discreet values of 0,-1.0 and 1.0.
It’s so much more fun playing Mario with a controller and not going ghetto-style with the keyboard. Of course since the emulator is still glitchy, when my wife was playing on World 4-1, she was getting killed by invisible tube plants. I don’t really have any idea why it’s happening, as far as I know the sprite rendering is working quite well… so the only thing I can think of is that there are some off-screen sprites that the code things are visible and so get added into the 8-sprite-per-line limit when they are in fact invisible. And that could be happening because there’s a setting to not draw the left/right 8 pixels on the screen and I’m completely ignoring that currently.
First off the weather here in my neck of England has been amazing. Haven’t really needed any warm gear and there’s been absolutely no rain. Of course as I write this it’s a bit cloudy but, no matter, it’s been amazing. Rachel and I made good use of this weather on Saturday and had a great time walking around Notting Hill. I’ve never seen so many antique stands/shops in my life. Naturally we hit the first book store we found, Notting Hill Book and Comic Exchange on Pembridge Road. Ended up getting about 20 books between us for the equivalent of $2 a book (some only 10p!). In my haste I didn’t notice that one of the Len Deighton books I’d grabbed didn’t have the second half of the book contained within it. Such is life.
Super Mario Brothers 3
On Saturday and Sunday I did some more work on my Java-based NES emulator and on Saturday managed to get Super Mario Brothers 3 and Zelda both working in fully playable states. I think this is something of a Holy Grail for me and in fact when I started this in January, my wife said all she wanted to play was her favorite game (Super Mario Brothers 3) so that has kept the drive. She had beat it already on the real system and still loved it. So it made me enormously proud when she asked excitedly if she could play it (she had seen that it looked decent). Quickly into playing as reality hit, we both wanted to have a tad more lives (how about infinite?) and to use an actual controller. Had to spend an hour or so figuring out how the Game Genie worked (more on that in a bit). Yesterday she was able to turn that on and played for 4 hours and got through most of World 3. Will have to use the GG again to get her back there (SMB3 doesn’t have save game feature and I haven’t implemented state dumping, doh!). Have also ordered an adapter for my PS2 controllers so we can hook it up, that turned out to be cheaper than getting a modified NES controller (although that would have been more authentic, but ah well). Rachel has apparently never played the NES version of Legend of Zelda, so she’ll be trying that next.
I fixed a lot of bugs in getting SMB3 to look and play decently. I had about halfway understood the documentation around rendering 8×16 sprites but managed to combine the PPU documentation from Everything2 (btw that’s one of the greatest sites ever, easy to spend hours on) in the 2c02 Technical Reference. My predecessors have spent an amazing amount of time accurately documenting things on the real NES/Famicom and have produced awesome documentation for it. Most larger NES cartridges use circuitry-based “mappers” which handle the requests for Program ROM and Character/Pattern ROM to serve out the correct data based on internal state. So a note for people writing NES emulators is don’t make the assumption that the cartridge (or whatever your representation of it) is necessarily read-only (the Character ROM is) because writes can be performed to the registers of the mapper. They will look like writes to the program address space (0x8000 – 0xFFFF) because that’s all the NES’s CPU knows about. Anyhow, Super Mario Brothers 3 uses the MMC3 mapper and there a few documents out there but the one I found the most useful was Kevin Horton’s MMC3 guide. It looks like he has physical ones that he tests for their behavior. I actually learned that I completely wasn’t even thinking about or emulating the built-in timer of the 2A03 (The NES’s modified 6502). Thankfully SMB3 doesn’t seem to need it, as it uses raster counting from the mapper intercepting read calls from the 2c02 PPU (Picture Processing Unit). I’ve got loads of other documentation but I think those were the main ones for getting that game working (as well as tons of other things). Kevin Horton has documented some of the other mappers as well (I used his MMC1 guide for Zelda). I almost forgot, throughout I’ve used Nestopia as my “reference” emulator for how things should look and behave. It’s an open source project, but I never looked at the code.
As I’ve mentioned before, I may be dense but when looking for documentation on the Game Genie I wanted something that actually said “this is how it works.” All the documentation was really around how to translate the Game Genie codes into memory address + value + check value. So what I ended up doing is loading the Game Genie as a normal game and handing it the game’s ROM. Once a write of 0x00 occurred to address 0 (0x8000 to the CPU) then I put the genie in “passthrough” mode and reset the CPU. Now any reads that occurred would be checked against what was stored in the codes and if they didn’t match it would just pass through. My holdup was that I was somehow thinking that the ROM would actually do this (but of course that’s impossible since it’s being emulated and is just a bunch of instructions to the CPU and so won’t be able to make “real” reads to the cartridge on it’s own). Once it clicked that I had to do the final step of actually checking the addresses, it all came together. I guess when I just plug in my own Game Genie it just works and so I expected this too as well 🙂
I still need to get sound working. Didn’t ever do that on the C64 but I want to do that on this one definitely. After that I will probably move on to another system. Writing hardware emulators is really fun, but I actually don’t care too much about playing with them. However I do have that option now and I’m sure I will take it up. When I started my Commodore 64 Emulator I had really never dealt with machine architecture except in some basic classes at University. Perhaps surprisingly, it will still take me quite a while to write anything in Assembly (at least I think so, I haven’t tried or needed to). When you are the machine you get to be “dumb” and only worry about things at the level of each instruction and store some state in registers. It’s actually up to the programmer to be “smart” and make use of those registers and instructions in a smart way, especially on the older 8-bit machines. So I really have to hand it to those who can crank out beautiful and complex programs written in 6502 Assembler. My job is actually fairly easy here, it’s all been documented by people before me and each part does one thing. I’ve learned a lot more about sprite rendering and double buffering and “interface-based” OO development than I ever really had to before. It’s been a great experience. You put it all together and you have…
- Giant bug-eye sunglasses.
- Belts that clearly aren’t meant to actually hold the wearer’s pants up
- Pink shirts on guys (well, the ones that are worn specifically as “Hey, I’m wearing a pink shirt. And I’m a guy. Yeah that’s right.”)
- Ludicrously pre-ripped/faded jeans (I’ve accepted that it’s nearly impossible to find jeans in an un-damaged state)
- Dining establishments that do not accept credit or debit cards (just charge me a bit extra!)
- Businesses that don’t accept debit or credit cards but will happily point you to the $3 a transaction ATM on the premises.
- Things are meant to”Better serving me” shouldn’t annoy me. Apparently I’m not alone.
- As Raymond Chen says: “Whenever you hear this phrase, you are pretty much guaranteed that whatever follows will in fact not serve you better at all.”
- Brent Ashley: “You absolutely know what follows is going to be something that reduces your choices, infringes on your rights, or costs you money.”
- Marylaine Block has to say: The phrase is “among the great lies of business, along with ‘the check is in the mail.'”
- And, finally, Candice.
- Bad grammar and/or spelling on notices posted on a business’ window (come on, take a couple of minutes!)
- Commercials (not trailers/previews) at the beginning of a theater movie (except the Orange UK one with Michael Madsen playing here in the UK but I’m starting to get tired of it)
- Stopping right in front of me while in a mass of foot traffic and looking around aimlessly (I myself have been guilty of this of course)
- Extra points if you manage to stop at the intersection of multiple paths
I will fully acknowledge that when it comes to fashion, I’m not what you’d call “an expert” or “at all knowledgeable” so these are clearly subjective personal opinions and not objective statements of fact. I’ve asked my wife multiple times “do people actually set out to look like idiots?” with the response being obviously “no, it’s trendy and they like it.” I’m not so sure about the latter, but no doubt the former is true. My theory is that the really cool people do wake up every once in a while and ask themselves “What ridiculous look can I try and actually have other people follow it?” Those people, my friend, are the true geniuses (genii?).
Quick update. Finally managed to get Super Mario Brothers to start on the NES emulator without having cheat in the debugger. Turns out that I had misread some documentation and so I was sending hex 0x42 to represented the unconnected controller #2. After running through the debugger over and over I’m pretty sure it was getting interpreted as every key being pressed on that second controller. In any case, it was definitely interfering with the START key detection (since the actual game played fine once started).
Moral of the story is the 42 is not always the answer especially if, as a co-worker said today, you’re not asking the right question.
So I managed to find a disassembly of Super Mario Brothers 1 as part of my attempts to figure out why I couldn’t start the game. I still don’t know why it doesn’t work, but I was able to find a spot where I could trick it into thinking that I was past the demo mode. So I’m probably the first person to have every controlled Mario while the “1 Player or 2 Player” menu was still on the screen. I’m hoping to use it to find out what’s wrong with the one I have. Interestingly, when I use Nestopia, it warns that the ROM is bad and ends up starting on a different level (0-1 instead of 1-1). That could be part of the problem perhaps?
So, yeah, I’m just now able to get it to play and I’m already cheating:
|Writing ‘1’ to address 1904 (decimal) puts it into “Game Mode” rather than “Demo Mode”. Writing a value to address 1882 (decimal) adds as many lives as I want (up to 256 or 255, haven’t tried)
But whatever, I got to actually play! And I couldn’t wait to shoot fire, one of the more fun things to do in Mario. The weird color on the blocks is because they actually flash and the screenshot caught it at a weird time.
I cannot seem to get past this point. Every time I jump I just hit my head on the tall “tree” and fall down. *sigh* Good thing I can give myself as many lives as I want!
The emulator actually runs a little too fast, so the time counts down pretty quick, but not double time thankfully.
Did a couple of hours of hacking on the NES emulator and managed to get the color to (mostly) look right. I had multiple little issues in the way I was handling the Name Table Attributes and palettes. I had misunderstood the documentation and that there was only one 16 byte set of palette data (that was mirrored) but there is actually 2 16-byte ones (which gets mirrored a few times). This allows for a separate set of background and sprite palettes. However, even after fixing that, I still had whacky reddish clouds! Thankfully that was a simple fix, I had swapped the two blocks of memory and was using the background Attribute Table as the sprite’s and vice versa. Naturally as is the case with this project, things still aren’t quite right. Namely the screen should be blue, rather than black, and there are lines where the sprites aren’t being fully read. In addition, the plant that is supposed to come out one of the tubes doesn’t show up.
No doubt I’m making this project harder than it necessarily needs to be, but I’m having fun doing it (when I actually work on it). I’m always getting distracted with other little hobby projects, especially when the “going gets rough”. I’ve been playing around with the proverbial Ant simulation that is always popular among us geeks… it’s amazing to watch emergent behavior come out of simple rules. Of course, mine isn’t working quite right.