Hey, I made an app this week. It can convert an image into a 4 color NES palette image. It can also save as CHR and do different levels of dithering. It runs on Windows computers. It should run on non-Windows computers with MONO.
Load an image from file, or paste from the clipboard (should be 256×256 or smaller).
Press Auto Generate Palette (or select colors from the NES palette)…(or select colors directly from the image).
Then press “convert”. This is with dithering set to Floyd Steinberg.
And below is Bayer 8×8 positioned dithering.
You can also convert to grayscale first (press the “grayscale” button).
Above is the image converted and dithered in gray.
Sometimes the Auto Generate won’t give the colors you want. You will have to manually change one of the colors. (click on the NES palette, then a box).
And you can save this as an image or as a CHR file for NES game development (nesdev). You can open the CHR file with a CHR editor, like YY-CHR.
You don’t need to use “auto generate palette”. You can click on the NES palette, then a box. You can click on the image itself to pick a color, then a box. You can load a palette from file (12 byte RGB or 4 byte NES).
My kids were in love with Minecraft. I bought them Terraria for Wii U because it’s sort of similar. After months of playing they finally got to hard mode (beating the wall of Flesh) but it was immediately way too hard for them and due to loss of data from unknown bugs… we gave up on that. But I decided to try the Nintendo Switch version. After about 6 months, we finally defeated the Moon Lord (final boss) this week.
My thoughts. It’s a very creative game. You can build your houses any way you want. Paint blocks different colors. Make your avatar look a 1000 different ways. Dye your armor different colors. Just endless customizations.
Gameplay is very fun, but hard. Many of the events are just 100s of enemies spawning endlessly. I did not like that. In other games there are a few well designed enemies that you have to learn their AI to defeat. This game is just “lets dump 100 pirates on you randomly”. And I mean randomly. Any random day could trigger these events. There is no way to trigger them or avoid them. The randomness is a bit frustrating.
Also frustrating is that there are always too many enemies on screen… all the time. You will be trying to build a sky bridge or dig for ore, and you can’t go 5 seconds without some thing annoying you. No matter how many harpies you kill.. you try to go back to building the bridge and 5 seconds later the screen is filled with damn harpies again.
Music. Decent. Sets the mood. Never annoying. I would call the regular BG music relaxing and peaceful.
Graphics. A bit underwhelming. They intentionally went with pixelated look, but some things look like too simple, and it comes across as mediocre.
Would I recommend the game? Yes if you have lots of time and like sandbox style building crafting games. Not recommended for kids under 10. It’s very hard at times. And there is teenage level humor. There is a fishing item called Master Bait. There is a magic book called the Golden Shower, that literally looks like a yellow stream of liquid. This is a game that will require lots of reading of wiki and watching YouTube tutorials to complete.
Game Tips
When the kids played on the Wii U, they had a hard time because they didn’t do any fishing, didn’t craft any potions, and didn’t build very good arenas. Boss fights are enormously easier if you do lots of preparations beforehand. You should always have regeneration potions, which you craft from mushrooms, daybloom, and bottled water. All easily obtainable at the start of the game, and can be crafted with a placed bottle (just an empty bottle placed on a table or platform). Also easy to make is ironskin potion…iron ore, daybloom, and bottled water.
Before every boss fight, take those potions, and eat some food (buy from traveling merchant) to get a well fed buff. Build an arena (big flat area with some platforms going accross) filled with campfires and heart lanterns and sunflowers and maybe a pool of honey. All for regeneration and sunflowers for speed boost. Also, have a stack of the best healing potions you can find.
Try to build the arena near the nurse. You can even build a little house next to the arena just for the nurse. She can heal you to full. But I’m getting ahead of myself…start over.
First priorities are to build the basic crafting stuff, and build some rooms to get NPCs to move in. Anvil. Workbench. Furnace. Wood and stone houses are easy to make. Then dig for hearts during the day and mana stars at night. While you are digging around get ores, make weapons, armor, etc. Tungsten and Silver is probably fine now. Then, once you have full hearts, start building a tower up to look for sky islands. You should have found a ton of rope (in chests) while looking for hearts, just build a big rope tower every 1/8th of the world and find the island with the Starfury sword. That will take you 90% through easy mode.
Go to the dungeon at night, fight the Skeletron (build an arena right there, and a house for the nurse). Now you can go in the dungeon, but it’s going to be hard. There are really good items in the chests here.
Go to the corruption / crimson and break 2 orbs (or hearts) and get the meteorite to fall. You can craft excellent easy mode armor with metorite, and a space gun.
The eye of Cthulhu will probably randomly show up some night. If not, you can find Suspicious Eyes in underground chests to spawn him (at night). Have an arena set up near your base for that.
You should fight the Eater of Worlds (easy) or Brain of Cthulhu (a bit hard) by breaking a 3rd orb / heart. The ore it drops and make a good pickax.
Immediately make a hellivator straight down the middle of the world, and dig for hellstone and obsidian and grab a hell forge. Make the best pre-hardmode weapons / armor / and pickax. If you found an Enchanted Boomerang, you can make a Flamarang with hellstone bars, which is nice. Or just a Flaming Greatsword is good.
Now sit back and build a nice house, go fishing, explore at a leisurely pace. The King Slime might show up, optional and easy boss. Goblins might attack, no problem. If you defeat them the Goblin Tinkerer will show up and you can buy Rocket Boots from him and the Tinkerer’s Workshop. When you get bored of Easy Mode, you can kill the Wall of Flesh to trigger hardmode to start. The Wall of Flesh shows up if a guide voodoo doll drops in the lava.
To defeat the Wall of Flesh, get 100+ beenades from fighting queen bees in the Jungle. You will probably have to make abeenimations to spawn queen bees and maybe do that 8-10 times. Also make a huge (half the world wide) platform all the way across the underworld. You will spend the entire fight running away from the wall of flesh.
Hardmode
The wall of flesh drops a Pwnhammer. Go to the Crimson / corruption and break as many altars as you can (12 or more). This will spawn hardmode ores. If you killed a nymph, you should have a metal detector to help you find them. Spend a lot of time getting hardmode ores. Build more houses for NPCs. Go fishing for hardmode ores in crates. You need to make full titanium armor and weapons (or adamantium). Craft a hardmode anvil. Make a Titanium Forge from a Hell Forge and Titanium Ore.
Now fight Wyverns and harpies forever until you can craft wings.
Pirates will show up some day, if you have full hearts. They are a pain in the ass. I like the Cutlass sword that the Captain drops, but it’s not useful against bosses (too short).
Now, the hardmode bosses are just insanely hard. Get a Daedalus Stormbow (Hallowed Mimics) and craft a ton of Holy Arrows 1000+. The Destroyer is the easiest. Key to that is to make a tall arena with several screens tall of platforms and have campfires and heart lanterns and sunflowers. Take a bunch of debuff potions and eat Pho before boss fights. Stay just out of range and shoot arrows. No problem.
The Twins and Skeletron Prime are very hard. Same arena and same weapon, Daedalus Stormbow, just move up and down and shoot arrows, and heal up, keep moving to avoid getting hit. Skeletron Prime… just avoid that spinning head of spikes. The Twins, kill the laser eye first. Try to avoid getting hit with the green vomit from the other eye.
Now Plantera bulbs will start to form. Make an arena in the jungle and a house for the nurse. Keep moving in circles and be aggressive. Once Plantera is killed, Cholophyte will start growing a lot more. Collect a ton of it and make armor. If you are lucky, you can get turtle shells from Giant Tortoises and make turtle armor, later converted to beetle armor (you get beetle shells dropped from the Golem). Also grab heart fruit to get max health.
Plantera should drop a temple key. Go in the Golem Temple and defeat Golem (probably the easiest hardmode boss fight). This triggers the Lunatic Cultists to spawn at the dungeon entrance. This is a much harder fight. You need a really good arena with a house for the nurse. The Golem Temple had solar tablet fragments in chests, you should trigger several solar eclipse events and get Death Sickles from Reapers which I think is excellent against the Lunatic Cultists. You can get Broken Hero Swords from Mothrons too, and craft a Terra Blade. There is a very complicated crafting tree for the Terra Blade, so you could skip this altogether.
Make sure you reforge these weapons from the Goblin Tinkerer. Solar Eclipse events are great for getting gold to do that.
Fight the Cultists and win. They drop the ancient manipulator crafting station (very important). Defeating the Cultists spawns 4 celestial pillars in the world. Go for the solar one (red). Kill 100 solar enemies and the pillar, and get the solar fragments. You can now make the weapon you need to defeat the Moon Lord, the Solar Eruption. Save up the rest of the pillar drops to make super healing potions. Also make a Stardust Dragon Staff with the stardust fragments. This summons an excellent minion that helps fight the Moon Lord.
Once the 4th pillar is defeated, the Moon Lord will spawn in 1 minute. Wait until you have everything you can imagine set up before defeating this last pillar. I had a very small arena with a pool of honey, and with 2 heart statues (I found them in the dungeon) set up with timers. Heart lantern and campfire. Took a bunch of potions – regeneration, ironskin, wrath, etc. Ate some Pho to get well fed buff. In the end, I just stood still and wacked away with the Solar Eruption (Demonic modifier) and healed (I had the Charm of Myths to reduce potion sickness time). Moon Lord is dead.
I guess I never fought Duke Fishron. I don’t really want to. You can also summon special Halloween and Christmas events (optional) and the Old Ones Army event (also optional). It’s just more “dump 100 enemies on you at once” things. Not my thing.
I probably forgot a whole bunch of things. This post was off the top of my head and not planned out.
Anyway, since I am an amateur game designer, I was planning on making a game inspired by Terraria. But, 2020 has been insane, so maybe in 2021 or 2022 I will get started on that. One thing’s for sure, my version will have less random enemies bothering you. That pirate attack is just awful. Don’t get me started.
Other great weapons… Star Cannon. Minishark and Megashark. Anything from the Celestial Pillars and Moon Lord Fight are great. Oh, I did forget the Alien Invasion (Martian Madness) event. It can happen if you defeated the Golem, and get scanned by an alien ship. That drops some great items, like a Spaceship mount (Cosmic Car Key). I don’t know. Maybe I should do the Halloween and Christmas events and see if they drop anything cool.
I am frequently looking this stuff up, so I decided to just post the lists here. Sources BootGod and Wikipedia.
US NES games
(minus the prototypes and duplicates)
10-Yard Fight 1942 1943: The Battle of Midway 3-D Battles of Worldrunner, The 6 in 1 720° 8 Eyes Abadox: The Deadly Inner War Action 52 Addams Family, The Addams Family, The: Pugsley’s Scavenger Hunt Adventure Island Adventure Island II Adventure Island III Adventures in the Magic Kingdom, Disney’s Adventures of Bayou Billy, The Adventures of Dino Riki Adventures of Gilligan’s Island, The Adventures of Lolo Adventures of Lolo 2 Adventures of Lolo 3 Adventures of Rad Gravity, The Adventures of Rocky and Bullwinkle and Friends, The Adventures of Tom Sawyer After Burner Air Fortress Airwolf Al Unser Jr. Turbo Racing Alfred Chicken Alien Syndrome Alien³ All-Pro Basketball Alpha Mission Amagon American Gladiators Anticipation Arch Rivals: A Basketbrawl! Archon Arkanoid Arkista’s Ring Astyanax Athena Athletic World Attack of the Killer Tomatoes Baby Boomer Back to the Future Back to the Future II & III Bad Dudes Bad News Baseball Bad Street Brawler Balloon Fight Bandai Golf: Challenge Pebble Beach Bandit Kings of Ancient China Barbie (RevA) Bard’s Tale, The: Tales of the Unknown Barker Bill’s Trick Shooting Base Wars: Cyber Stadium Series Baseball Baseball Simulator 1.000 Baseball Stars Baseball Stars II Bases Loaded (RevA) Bases Loaded 3, Ryne Sandberg Plays Bases Loaded 4 Bases Loaded II: Second Season Batman Batman Returns Batman: Return of the Joker Battle Chess Battle of Olympus, The Battle Tank, Garry Kitchen’s Battleship Battletoads Battletoads & Double Dragon: The Ultimate Team Bee 52 Beetlejuice Best of the Best: Championship Karate Bible Adventures (Ver1.4) Bible Buffet (Ver6.0) Big Nose Freaks Out Big Nose the Caveman Bigfoot Bill & Ted’s Excellent Video Game Adventure Bill Elliott’s NASCAR Challenge Bionic Commando Black Bass, The Blackjack Blades of Steel Blaster Master Blue Marlin, The Blues Brothers, The Bo Jackson Baseball Bomberman Bomberman II Bonk’s Adventure Boulder Dash Boy and His Blob, A: Trouble on Blobolonia, David Crane’s Bram Stoker’s Dracula Break Time: The National Pool Tour BreakThru Bubble Bath Babes Bubble Bobble Bubble Bobble: Part 2 Bucky O’Hare Bugs Bunny Birthday Blowout, The Bugs Bunny Crazy Castle, The Bump ‘n’ Jump Burai Fighter BurgerTime Cabal Caesars Palace California Games Capcom’s Gold Medal Challenge ’92 Captain America and the Avengers Captain Comic: The Adventure Captain Planet and the Planeteers Captain SkyHawk Casino Kid Casino Kid II Castelian Castle of Deceit Castle of Dragon Castlequest Castlevania Castlevania II: Simon’s Quest Castlevania III: Dracula’s Curse Caveman Games Challenge of the Dragon Championship Bowling Championship Pool Chessmaster, The Chiller (CHR-CB55) Chip ‘n Dale Rescue Rangers 2, Disney’s Chip ‘n Dale Rescue Rangers, Disney’s Chubby Cherub Circus Caper City Connection Clash At Demonhead Classic Concentration Cliffhanger Clu Clu Land Cobra Command Cobra Triangle Code Name: Viper Color A Dinosaur Commando Conan Conflict Conquest of the Crystal Palace Contra Contra Force Cool World Cowboy Kid Crash ‘n The Boys: Street Challenge Crystal Mines Crystalis Cyberball Cybernoid: The Fighting Machine Dance Aerobics Darkman Darkwing Duck, Disney’s Dash Galaxy in the Alien Asylum Day Dreamin’ Davey Days of Thunder Deadly Towers Death Race Deathbots Defender II Defender of the Crown Defenders of Dynatron City Déjà Vu Demon Sword Desert Commander Destination Earthstar Destiny of an Emperor Dick Tracy Die Hard Dig Dug II: Trouble in Paradise Digger T. Rock: The Legend of the Lost City Dirty Harry Dizzy The Adventurer Donkey Kong (RevA) Donkey Kong 3 Donkey Kong Classics Donkey Kong Jr. (RevA) Donkey Kong Jr. Math Double Dare Double Dragon Double Dragon II: The Revenge (RevA) Double Dragon III: The Sacred Stones Double Dribble (RevA) Double Strike (Ver1.1) Dr. Chaos Dr. Jekyll and Mr. Hyde Dr. Mario Dragon Fighter Dragon Power Dragon Spirit: The New Legend Dragon Warrior (RevA) Dragon Warrior II Dragon Warrior III (Rev0B) Dragon Warrior IV Dragon’s Lair DragonStrike, Advanced Dungeons & Dragons Duck Hunt DuckTales 2, Disney’s DuckTales, Disney’s Dudes with Attitude Dungeon Magic: Sword of the Elements Dusty Diamond’s All-Star Softball Dynowarz: The Destruction of Spondylus Elevator Action Eliminator Boat Duel Excitebike Exodus: Journey to the Promised Land (Ver4.0) F-117a Stealth Fighter F-15 City War (Ver1.1) F-15 Strike Eagle Family Feud, The All New Fantastic Adventures of Dizzy, The Fantasy Zone Faria Faxanadu (RevA) Felix the Cat Ferrari Grand Prix Challenge Fester’s Quest Final Fantasy Fire Hawk Fire’n Ice Fisher-Price: Firehouse Rescue Fisher-Price: I Can Remember Fisher-Price: Perfect Fit Fist of the North Star Flight of the Intruder Flintstones, The: The Rescue of Dino & Hoppy Flintstones, The: The Surprise at Dinosaur Peak! Flying Dragon: The Secret Scroll Flying Warriors Formula One: Built to Win Fox’s Peter Pan & The Pirates: The Revenge of Captain Hook Frankenstein: The Monster Returns Freedom Force Friday the 13th Fun House G.I. Joe G.I. Joe: The Atlantis Factor Galactic Crusader Galaga: Demons of Death Galaxy 5000: Racing in the 51st Century Game Genie (Rev1.5A) Gargoyle’s Quest II Gauntlet Gauntlet II Gemfire Genghis Khan George Foreman’s KO Boxing Ghostbusters Ghostbusters II Ghosts ‘n Goblins Ghoul School Goal! Goal! Two Godzilla 2: War of the Monsters Godzilla: Monster of Monsters! Golf Golf Grand Slam Golgo 13: The Mafat Conspiracy Golgo 13: Top Secret Episode Goonies II, The Gotcha! The Sport! Gradius Great Waldo Search, The Greg Norman’s Golf Power Gremlins 2: The New Batch Guardian Legend, The Guerrilla War Gumshoe Gun Nac Gun.Smoke Gyromite Gyruss Harlem Globetrotters Hatris Heavy Barrel Heavy Shreddin’ Heroes of the Lance, Advanced Dungeons & Dragons High Speed Hillsfar, Advanced Dungeons & Dragons Hogan’s Alley Hollywood Squares Home Alone (RevA) Home Alone 2: Lost in New York Hook Hoops Hudson Hawk Hunt for Red October, The (RevA) Hydlide Ice Climber Ice Hockey Ikari Warriors Ikari Warriors II: Victory Road Ikari Warriors III: The Rescue Image Fight Immortal, Will Harvey Presents The Impossible Mission-II Incredible Crash Dummies, The Indiana Jones and The Last Crusade (Taito) Indiana Jones and The Last Crusade (UBI Soft) Indiana Jones and the Temple of Doom (Mindscape) Indiana Jones and the Temple of Doom (Tengen) Indy Heat, Danny Sullivan’s Infiltrator Iron Tank: The Invasion of Normandy IronSword: Wizards & Warriors II Isolated Warrior Jack Nicklaus’ Greatest 18 Holes of Major Championship Golf Jackal Jackie Chan’s Action Kung Fu James Bond Jr. Jaws Jeopardy! (RevA) Jeopardy!: 25th Anniversary Edition Jeopardy!: Junior Edition Jetsons, The: Cogswell’s Caper Jimmy Connors Tennis Joe & Mac John Elway’s Quarterback Jordan vs. Bird: One on One Joshua & the Battle of Jericho (Ver6.0) Journey to Silius Joust Jungle Book, Disney’s The Jurassic Park Kabuki: Quantum Fighter Karate Champ (RevA) Karate Kid, The Karnov Kick Master Kickle Cubicle Kid Icarus Kid Klown in Night Mayor World Kid Kool and the Quest for the Seven Wonder Herbs Kid Niki: Radical Ninja (RevA) King Neptune’s Adventure King of Kings, The: The Early Years (Ver1.2) King’s Knight King’s Quest V Kings of the Beach Kirby’s Adventure (RevA) Kiwi Kraze: A Bird-Brained Adventure! KlashBall Klax Knight Rider Krazy Kreatures (Ver1.1) Krion Conquest, The Krusty’s Fun House Kung Fu Kung-Fu Heroes L’Empereur Laser Invasion Last Action Hero Last Ninja, The Last Starfighter, The Lee Trevino’s Fighting Golf Legacy of the Wizard Legend of Kage, The Legend of the Ghost Lion Legend of Zelda, The (RevA) Legendary Wings Legends of the Diamond: The Baseball Championship Game Lemmings Lethal Weapon Life Force (Rev0A) Linus Spacehead’s Cosmic Crusade Little League Baseball Championship Series Little Mermaid, Disney’s The Little Nemo: The Dream Master Little Ninja Brothers Little Samson Lode Runner Lone Ranger, The Loopz Low G Man: The Low Gravity Man Lunar Pool M.C. Kids M.U.L.E. M.U.S.C.L.E.: Tag Team Match Mach Rider Mad Max Magic Darts Magic Johnson’s Fast Break Magic of Scheherazade, The Magician Magmax Major League Baseball (RevA) Maniac Mansion Mappy-Land Marble Madness Mario Bros. Mario Is Missing! Mario’s Time Machine Master Chu and the Drunkard Hu Maxi 15 Mechanized Attack Mega Man Mega Man 2 Mega Man 3 Mega Man 4 (RevA) Mega Man 5 Mega Man 6 Menace Beach Mendel Palace Mermaids of Atlantis: The Riddle of the Magic Bubble Metal Fighter Metal Gear Metal Mech: Man & Machine Metal Storm Metroid Michael Andretti’s World GP Mickey Mousecapade Mickey’s Adventure in Numberland Mickey’s Safari in Letterland Micro Machines MIG-29 Soviet Fighter Might and Magic: Secret of the Inner Sanctum Mighty Bomb Jack Mighty Final Fight Mike Tyson’s Punch-Out!! (RevA) Millipede Milon’s Secret Castle Miracle Piano Teaching System, The Mission Cobra Mission: Impossible Monopoly Monster In My Pocket Monster Party Monster Truck Rally Moon Ranger Motor City Patrol Ms. Pac-Man (Namco) Ms. Pac-Man (Tengen) MTV’s Remote Control Muppet Adventure: Chaos at the Carnival Mutant Virus, The: Crisis in a Computer World Mystery Quest NARC NES Open Tournament Golf NES Play Action Football NFL Nigel Mansell’s World Championship Racing Nightmare on Elm Street, A Nightshade Ninja Crusaders Ninja Gaiden Ninja Gaiden II: The Dark Sword of Chaos Ninja Gaiden III: The Ancient Ship of Doom Ninja Kid Nintendo World Championships 1990 Nintendo World Cup Nobunaga’s Ambition Nobunaga’s Ambition II North & South NTF2 System Cartridge Operation Secret Storm Operation Wolf: Take no Prisoners (Rev0A) Orb 3-D Othello Overlord P’radikus Conflict P.O.W.: Prisoners of War Pac-Man (Tengen) Pac-Man (Namco) Pac-Mania Palamedes Panic Restaurant Paperboy Paperboy 2 Pesterminator Phantom Fighter Pictionary Pin-Bot Pinball Pinball Quest Pipe Dream Pirates! Platoon (RevA) Pool of Radiance, Advanced Dungeons & Dragons Popeye (RevA) Power Blade Power Blade 2 Power Punch II Predator Prince of Persia Princess Tomato in the Salad Kingdom Pro Sport Hockey Pro Wrestling (RevA) Punch-Out!! Punisher, The Puss ‘n Boots: Pero’s Great Adventure Puzzle Puzznic Pyramid Q*bert Qix Quattro Adventure Quattro Arcade Quattro Sports R.B.I. Baseball R.B.I. Baseball 2 R.B.I. Baseball 3 R.C. Pro-Am (RevA) R.C. Pro-Am II Race America, Alex DeMeo’s RacerMate Challenge II (9.03.128) Racket Attack Rad Racer Rad Racer II Rad Racket: Deluxe Tennis II Raid 2020 Raid on Bungeling Bay Rainbow Islands Rally Bike Rambo Rampage Rampart Ren & Stimpy Show, The: Buckeroo$! Renegade Rescue: The Embassy Mission Ring King River City Ransom Road Runner RoadBlasters Robin Hood: Prince of Thieves Robo Warrior RoboCop RoboCop 2 (RevA) RoboCop 3 Robodemons Rock’n’ Ball Rocket Ranger Rocketeer, The Rockin’ Kats Roger Clemens’ MVP Baseball Rollerball Rollerblade Racer Rollergames Rolling Thunder Romance of the Three Kingdoms Romance of the Three Kingdoms II Roundball: 2-on-2 Challenge Rush’n Attack Rygar (RevA) S.C.A.T.: Special Cybernetic Attack Team Secret Scout in the Temple of Demise Section Z Seicross Sesame Street 123 Sesame Street ABC Sesame Street ABC & 123 Sesame Street Countdown Sesame Street: Big Bird’s Hide and Speak Shadow of the Ninja Shadowgate Shatterhand Shingen The Ruler Shinobi Shockwave Shooting Range Short Order / Eggsplode! Side Pocket Silent Assault Silent Service (RevA) Silkworm Silver Surfer Simpsons, The: Bart vs. The Space Mutants Simpsons, The: Bart vs. The World Simpsons, The: Bartman Meets Radioactive Man Skate or Die 2: The Search for Double Trouble Skate or Die! Ski or Die Skull & Crossbones Sky Kid Sky Shark (Rev0A) Slalom Smash T.V. Snake Rattle ‘n Roll Snake’s Revenge Snoopy’s Silly Sports Spectacular! Snow Brothers Soccer Solar Jetman: Hunt for the Golden Warpship Solitaire (Ver1.1) Solomon’s Key Solstice: The Quest for the Staff of Demnos Space Shuttle Project Spelunker Spider-Man: Return of the Sinister Six Spiritual Warfare (Ver6.1) Spot Spy Hunter Spy vs. Spy Sqoon Stack-Up Stadium Events Stanley: The Search for Dr. Livingston Star Force Star Soldier Star Trek: 25th Anniversary Star Trek: The Next Generation Star Voyager Star Wars Star Wars: The Empire Strikes Back Starship Hector StarTropics Stealth ATF Stinger Street Cop Street Fighter 2010: The Final Fight Strider Stunt Kids Sunday Funday: The Ride Super C Super Cars Super Dodge Ball Super Glove Ball Super Jeopardy! Super Mario Bros. Super Mario Bros. / Duck Hunt Super Mario Bros. / Duck Hunt / World Class Track Meet Super Mario Bros. 2 (RevA) Super Mario Bros. 3 Super Off Road, Ivan “Ironman” Stewart’s Super Pitfall Super Spike V’Ball Super Spike V’Ball / Nintendo World Cup Super Sprint Super Spy Hunter Super Team Games Superman Swamp Thing Sword Master Swords and Serpents T&C Surf Designs 2: Thrilla’s Surfari T&C Surf Designs: Wood and Water Rage T2: Terminator 2: Judgment Day Taboo: The Sixth Sense Tag Team Wrestling Tagin’ Dragon TaleSpin, Disney’s Target: Renegade Tecmo Baseball Tecmo Bowl Tecmo Cup: Soccer Game Tecmo NBA Basketball Tecmo Super Bowl Tecmo World Wrestling Teenage Mutant Ninja Turtles Teenage Mutant Ninja Turtles II: The Arcade Game Teenage Mutant Ninja Turtles III: The Manhattan Project Teenage Mutant Ninja Turtles: Tournament Fighters Tennis Terminator, The Terra Cresta Tetris (Nintendo) Tetris (Tengen) Tetris 2 Three Stooges, The Thunder & Lightning Thunderbirds Thundercade Tiger-Heli Tiles of Fate Time Lord Times of Lore Tiny Toon Adventures Tiny Toon Adventures 2: Trouble in Wackyland Tiny Toon Adventures: Cartoon Workshop To The Earth Toki Tom & Jerry Tombs and Treasure Toobin’ Top Gun Top Gun: The Second Mission Top Players’ Tennis, Chris Evert & Ivan Lendl in Total Recall Totally Rad Touchdown Fever Toxic Crusaders Track & Field Track & Field II (RevA) Treasure Master Trog! Trojan Trolls on Treasure Island Twin Cobra Twin Eagle Ultima: Exodus Ultima: Quest of the Avatar Ultima: Warriors of Destiny Ultimate Air Combat Ultimate Basketball Ultimate League Soccer Ultimate Stuntman, The Uncanny X-Men, The Uncharted Waters Uninvited Untouchables, The (RevA) Urban Champion Vegas Dream Venice Beach Volleyball Vice: Project Doom Videomation Vindicators Volleyball Wacky Races Wall Street Kid Wally Bear and the No! Gang Wario’s Woods Wayne Gretzky Hockey Wayne’s World WCW World Championship Wrestling Werewolf: The Last Warrior Wheel of Fortune Wheel of Fortune featuring Vanna White Wheel of Fortune: Family Edition Wheel of Fortune: Junior Edition Where in Time is Carmen Sandiego? Where’s Waldo? Who Framed Roger Rabbit Whomp ‘Em Widget Wild Gunman Willow Win, Lose or Draw Winter Games (RevA) Wizardry: Knight of Diamonds Wizardry: Proving Grounds of the Mad Overlord Wizards & Warriors Wizards & Warriors III Wolverine World Champ World Class Track Meet World Games Wrath of the Black Manta (RevA) Wrecking Crew WURM: Journey to the Center of the Earth WWF King of the Ring WWF WrestleMania WWF WrestleMania Challenge WWF WrestleMania: Steel Cage Challenge Xenophobe Xevious: The Avenger Xexyz Yo! Noid Yoshi Yoshi’s Cookie Young Indiana Jones Chronicles, The Zanac Zelda II: The Adventure of Link Zen: Intergalactic Ninja Zoda’s Revenge: StarTropics II Zombie Nation
European PAL Exclusive NES Games
Asterix Aussie Rules Footy Banana Prince Championship Rally Crackout Devil World Disney’s Aladdin Disney’s Beauty and the Beast Disney’s The Lion King Dropzone Elite Formula One Sensation Hammerin’ Harry International Cricket Kick Off Konami Hyper Soccer The Legend of Prince Valiant Les Chevaliers du Zodiaque : La Légende d’or Mario Bros. (Classic Series) Mr. Gimmick! New Ghostbusters II Noah’s Ark Over Horizon Parasol Stars: Rainbow Islands II Parodius Rackets & Rivals Rainbow Islands: Bubble Bobble 2 Road Fighter Rod Land The Smurfs Super Mario Bros./Tetris/Nintendo World Cup Super Turrican Tecmo World Cup Soccer The Trolls in Crazyland Ufouria: The Saga
Japanese / Famicom Games
Note: Airwolf, Star Wars, and Tetris are different from the US versions.
’89 Dennou Kyuusei Uranai 10-Yard Fight 1942 1943: The Battle of Valhalla 2010 Street Fighter 4 Nin Uchi Mahjong 8 Eyes A Ressha de Ikou A Week of Garfield Aa Yakyu Jinsei Itchokusen Abadox Abarenbou Tengu Aces: Iron Eagle III Advanced Dungeons & Dragons: Dragons of Flame Advanced Dungeons & Dragons: Heroes of the Lance Advanced Dungeons & Dragons: Hillsfar Advanced Dungeons & Dragons: Pool of Radiance Adventures of Lolo Adventures of Lolo 2 After Burner Ai Sensei no Oshiete: Watashi no Hoshi Aigiina no Yogen: From the Legend of Balubalouk Air Fortress Airwolf Akagawa Jirou no Yuurei Ressha Akira Akuma no Shoutaijou Akuma-kun: Makai no Wana Akumajou Densetsu Akumajou Dracula Akumajou Special: Boku Dracula Kun Alien Syndrome America Daitoryo Senkyo America Oudan Ultra Quiz: Shijou Saidai no Tatakai American Dream Ankoku Shinwa: Yamato Takeru Densetsu Antarctic Adventure Aoki Ookami to Shiroki Mejika: Genchou Hishi Aoki Ookami to Shiroki Mejika: Genghis Khan Arabian Dream Scheherazade Arctic Argos no Senshi Argus Arkanoid Arkanoid II Armadillo Artelius Asmik-kun Land ASO: Armored Scrum Object Astro Fang: Super Machine Astro Robo Sasa Athena Atlantis no Nazo Attack Animal Gakuen B-Wings Babel no Tou Baken Hisshou Gaku: Gate In Bakusho! Ai no Gekijo Bakushou!! Jinsei Gekijou Bakushou!! Jinsei Gekijou 2 Bakushou!! Jinsei Gekijou 3 Bakusho! Star Monomane Shitenno Ballblazer Balloon Fight Baltron Banana Bananan Ouji no Daibouken Barcode World Bard’s Tale: Tales of the Unknown The Bard’s Tale II: The Destiny Knight Baseball Baseball Fighter Baseball Stars: Mezase Sankanou!! Batman Bats & Terry Battle Baseball Battle City Battle Fleet Battle Formula Datach: Battle Rush: Build Up Robot Tournament Battle Stadium: Senbatsu Pro Yakyuu Battle Storm Battletoads Be-Bop High School: Koukousei Gokuraku Densetsu Best Keiba: Derby Stallion Best Play Pro Yakyuu Best Play Pro Yakyuu II Best Play Pro Yakyuu ’90 Best Play Pro Yakyuu Shin Data Best Play Pro Yakyuu Special Bikkuri Nekketsu Shin Kiroku! Harukanaru Kin Medal Bikkuriman World: Gekitou Sei Senshi Binary Land Bio Miracle Bokutte Upa Bio Senshi Dan: Increaser to no Tatakai Bird Week The Black Bass The Black Bass 2 Block Set (Rob the Robot and Stack-Up “Block”) Blodia Land: Puzzle Quest Bloody Warriors: Shan-Go no Gyakushuu Blue Marlin, The Bokosuka Wars Bomber King Bomberman Bomberman II Booby Kids Boulder Dash Bubble Bobble 2 Bucky O’Hare Buggy Popper Burai Fighter BurgerTime Business Wars Cadillac Capcom Barcelona ’92 Captain Ed Captain Saver Captain Silver Captain Tsubasa Captain Tsubasa Vol. II: Super Striker Casino Derby & Super Bingo Castle Excellent Castle Quest Chack’n Pop Challenger Championship Bowling Championship Lode Runner Chaos World Chester Field: Ankoku Shin e no Chosen Chibi Maruko-Chan: Uki Uki Shopping Chiisana Obake: Achhi Sochhi Kocchi Chiki Chiki Machine Mou Race Chip to Dale no Daisakusen Chip to Dale no Daisakusen 2 Chitei Senkou Bazolder Chiyonofuji no Oicho Choplifter Chou-Wakusei Senki MetaFight Choujikuu Yousai Macross Chojin Sentai Jetman Choujin Ultra Baseball Choujinrou Senki Warwolf Chuugoku Janshi Story: Tonpuu Chuugoku Senseijutsu Chuuka Taisen Circus Charlie City Adventure Touch: Mystery of Triangle City Connection Clu Clu Land Cobra Command Cocoron Columbus: Ougon no Yoake Conflict Contra Cosmic Epsilon Cosmic Wars Cosmo Genesis Cosmo Police Galivan Crayon Shin-Chan: Ora to Poi Poi Crazy Climber Crisis Force Cross Fire Cycle Race: Road Man Dai-2-Ji Super Robot Taisen Daikaijyu Deburasu Daikoukai Jidai Daiku no Gen-San Daiku no Gen-San 2 Dai Meiro – Meikyuu no Tatsujin Daisenryaku Daiva Dark Lord Dash Yarou Datach Crayon Shin-Chan: Ora to Poi Poi Datsugoku De-Block Deep Dungeon III Deep Dungeon IV Deja Vu Dengeki Big Bang! Densetsu no Kishi Elrond Derby Stallion Zengokuban Devilman Devil World Dezaemon Die Hard Dig Dug Dig Dug II Digital Devil Monogatari Megami Tensei Digital Devil Monogatari: Megami Tensei II Doki! Doki! Yuenchi: Crazy Land Daisakusen Dokuganryu Masamune Don Doko Don Don Doko Don 2 Donald Duck Donald Land Donkey Kong Donkey Kong 3 Donkey Kong Jr. Math Donkey Kong Jr. Door Door Doraemon Doraemon: Giga Zombie no Gyakushu Double Dragon Double Dragon II: The Revenge Double Dragon III: The Rosetta Stone Double Moon Densetsu Dough Boy Downtown Nekketsu Koushinkyoku: Soreyuke Daiundoukai Downtown Nekketsu Monogatari Downtown Special: Kunio-kun no Jidaigeki Dayo Zenin Shuugou! Dr. Mario Dragon Ball 3: Gokuuden Dragon Ball Z Dragon Ball Z Side Story: Plan to Eradicate the Saiyans Dragon Ball Z II: Gekishin Freeza Dragon Ball Z III: Ressen Jinzou Ningen Datach: Dragon Ball Z: Gekitou Tenkaichi Budokai Dragon Ball: Daimaou Fukkatsu Dragon Ball: Shenron no Nazo Dragon Buster Dragon Buster II Dragon Fighter Dragon Ninja Dragon Quest Dragon Quest II: Gods of the Evil Spirits Dragon Quest III: And thus into Legend… Dragon Quest IV: The Guided Ones Dragon Scroll Dragon Slayer IV: Drasle Family Dragon Slayer Jr.: Romancia Dragon Spirit: Aratanaru Densetsu Dragon Unit Dragon Wars Dragon’s Lair Dream Master Duck Hunt DuckTales 2 Dungeon Kid Dungeon & Magic: Sword of Element Dynamite Batman Dynamite Bowl Eggerland: Meikyu no Fukkatsu Egypt Elevator Action Elnark no Zaihou Elysion Emoyan no 10-bai Pro Yakyuu Erika to Satoru no Yume Boken Esper Boukentai Esper Dream 2 Excitebike Exciting Boxing Exciting Rally Exed Exes Exerion F-1 Hero 2, Nakajima Satoru Kanshuu F1 Circus F-1 Sensation F-1 Race Famicom Igo Nyuumon Famicom Jump: Hero Retsuden Famicom Jump II: The Strongest Seven Famicom Meijinsen Famicom Shougi: Ryuu-Ou-Sen Famicom Top Management Famicom Wars Famicom Yakyuuban Family Block Family Boxing Family Circuit Family Circuit ’91 Family Computer Othello Family Jockey Family Mahjong Family Mahjong II: Shanghai he no Michi Family Pinball Family Quiz Family Tennis Family Trainer: Aerobics Studio Family Trainer: Athletic World Family Trainer: Daiundokai Family Trainer: Fuuun! Takeshi Shiro 2 Family Trainer: Jogging Race Family Trainer: Manhattan Police Family Trainer: Meiro Daisakusen Family Trainer: Rai Rai! Kyonshizu: Baby Kyonshi no Amida Daibouken Family Trainer: Running Stadium Family Trainer: Totsugeki! Fuuun Takeshi Shiro Famista ’89 Kaimaku Ban!! Famista ’90 Famista ’91 Famista ’92 Famista ’93 Famista ’94 Fantasy Zone Fantasy Zone 2: The Teardrop of Opa-Opa Faria Fuuin no Tsurugi Faxanadu FC Genjin Ferrari Field Combat Fighting Golf Fighting Road Final Fantasy Final Fantasy I+II Final Fantasy II Final Fantasy III Final Lap Final Mission Fire Emblem: Shadow Dragon and the Blade of Light Fire Emblem Gaiden Flappy Fleet Commander Flintstones: The Rescue of Dino and Hoppy Flipull Flying Hero Formation Z Front Line Fudou Myououden Fushigi na Blobby Fushigi no Umi no Nadia Fuzzical Fighter Galaga Galaxian Gambler Jiko Chuushinha Gambler Jiko Chuushinha 2 Game Party Ganbare Goemon! Karakuri Dochu Ganbare Goemon 2 Ganbare Goemon Gaiden: Kieta Ougon Kiseru Ganbare Goemon Gaiden 2 Ganbare Pennant Race! Ganso Saiyuki: Super Monkey Daiboken Gegege no Kitaro: Youkai Daimakyou Gegege no Kitaro 2 Geimos Gekikame Ninja Den (= TMNT) Gekitotsu Shiku Battle Gekitou Pro Wrestling!! Toukon Densetsu Gekitou!! Stadium Genpei Toma Den Getsu Fuma Den Ghostbusters Gimme a Break: Shijou Saikyou no Quiz Ou Ketteisen Gimme a Break: Shijou Saikyou no Quiz Ou Ketteisen 2 Gimmick! Ginga Eiyuu Densetsu Ginga no Sannin Goal !! God Slayer: Haruka Tenku no Sonata Gojira (Godzilla) Golf The Golf ’92 Golf Club: Birdie Rush Golf Grand Slam Golf-kko Open Golgo 13: Kamigami no Koukon Golgo 13 II Gomoku Narabe Renju Goonies Goonies II: Fratelli Saigo no Chousen Gorby no Pipeline Daisakusen Gorilla Man Gozonji Yajikitatin Douchuu Gradius Gradius II Grand Master Great Battle Cyber Great Boxing – Rush Up Great Deal Great Tank Gremlins 2: The New Batch Guardic Gaiden Guevara GunHed: Aratanaru Tatakai Gun-Nac Gun Sight Gun-Dec Gyro (Gyromite) Gyrodine Haja No Fuuin: Miracle Warriors Hana no Star Kaidou Hanjuku Hero Happy Birthday Bugs Hatris Hayauchi Super Igo Heavy Barrel Hebereke Hector ’87 Heisei Tensai Bakabon Hello Kitty no Hanabatake Hello Kitty World Heracles no Eikou: Toujin Makyouden Heracles no Eikou II: Titan no Metsubou Hi no Tori Hououhen: Gaou no Bouken Higemaru Makaijima – Nanatsu no Shima Daiboken Highway Star Hirake! Ponkikki Hiryu no Ken Hiryu no Ken II Hiryu no Ken III: 5 Nin no Ryuu Senshi Hiryu no Ken Special: Fighting Wars Hissatsu Doujou Yaburi Hissatsu Shigotojin Hitler no Fukkatsu: Top Secret Hogan’s Alley Hokkaidou Rensa Satsujin: Ohotsuku ni Kiyu Hokuto no Ken Hokuto no Ken 2 Hokuto no Ken 3 Hokuto no Ken 4 Holy Diver Home Run Night Home Run Night ’90 Honmei Honoo no Doukyuuji: Dodge Danpei Honoo no Doukyuuji: Dodge Danpei 2 Honshougi: Naitou Kudan Shougi Hiden Hook Hoshi no Kirby: Yume no Izumi no Monogatari Hoshi wo Miru Hito Hostages Hototogisu Hottaman no Chitei Tanken Houma ga Koku Hudson Hawk Hyakkiyakou Hyaku no Sekai no Monogatari Hydlide Special Hydlide 3 Hyokkori Hyoutan Shima: Nazo no Kaizokusen Hyper Olympic Hyper Sports I Love Softball Ice Climber Idemitsu – Space College – Kikenbutsu no Yasashii Butsuri to Kagaku[7] Ide Yosuke Meijin no Jissen Mahjong Ide Yosuke Meijin no Jissen Mahjong II Idol Hakkenden Igo Meikan Igo Shinan Igo Shinan ’91 Igo Shinan ’92 Igo Shinan ’93 Igo Shinan ’94 Igo: Kyu Roban Taikyoku Ikari Ikari II Ikari III IkeIke! Nekketsu Hockey-bu Ikinari Musician Ikki Image Fight Inbou no Wakusei: Shankara Indora no Hikari Insector X Ishin no Arashi Itadaki Street: Watashi no Oten Niyottete Izaki Shuugorou no Keiba Hisshougaku J-League Fighting Soccer: The King of Ace Strikers Datach: J. League Super Top Players J-League Winning Goal Jackie Chan Jajamaru Gekimaden Jajamaru Ninpou Chou JaJaMaru no Daibouken Jangou Jarin-Ko Chie Jesus: Kyofu no Bio Monster The Jetsons: Cogswell’s Caper! Jigoku Gokuraku Maru Jikuu (Toki) no Tabibito Jikuu Yuten Debias Jongbou Joust Joy Mech Fight JuJu Densetsu Jumbo Ozaki no Hole in One Professional Jumpin’ Kid: Jack to Mame no Ki Monogatari Just Breed Juuryoku Soukou Metal Storm Juvei Quest Jyuouki Kabushiki Doujou Kage Kage no Densetsu Kagerou Densetsu Kaguya Hime Densetsu Kai no Bouken: The Quest of Ki Kaijuu Monogatari Kaiketsu Yancha Maru Kaiketsu Yancha Maru 2: Karakuri Land Kaiketsu Yanchamaru 3: Taiketsu! Zouringen Kakefu Kimi no Jump Tengoku Kame no Ongaeshi Kamen no Ninja Akakage Kamen no Ninja Hamaru Kamen Rider Club Kamen Rider SD Karakuri Kengoden Musashi Lord: Karakuri Jin Shissouru Karaoke Studio Karaoke Studio Senyou Cassette Vol. 1 Karaoke Studio Senyou Cassette Vol. 2 Karateka Karnov Katte ni Shirokuma Kawa no Nushi Tsuri Kekkyoku Nankyoku Daibouken Kero Kero Keroppi no Daibouken Kero Kero Keroppi no Daibouken 2 Keroppi to Keroriinu no Splash Bomb Kido Senshi Z-Gundam: Hot Scramble King Kong 2: Ikari no Megaton Punch King of Kings King’s Knight Kinnikuman: Muscle Tag Match Kiteretsu Daihyakka Kitte Rai Da! Gunjin Shougi Nanya Sore? Klax Knight Rider Konami Sports in Seoul Koufuku o Yobu Game: Dora Dora Dora Koryu Densetsu Villgust Gaiden Koshien Kujaku Ou Kujaku Ou II Kunio-Kun no Jidaigeki dayo Zenin Shuugou: Downtown Special Kunio-Kun no Nekketsu Soccer League Kurogane Hiroshi no Yosou Daisuki! Kachiuma Densetsu Kyatto Ninden Teyandee Kyonshis 2 Kyorochan Land Kyoryu Sentai Zyuranger Kyouto Hana no Misshitsu Satsujin Jiken – Yamamura Misa Suspense Kyouto Ryuu no Tera Satsujin Jiken – Yamamura Misa Suspense Kyouto Zaiteku Satsujin Jiken Yamamura Misa Suspense Kyuukyoku Harikiri Koshien Kyuukyoku Harikiri Stadium Kyuukyoku Harikiri Stadium ’88 Kyuukyoku Harikiri Stadium Heisei Gannenhan Kyuukyoku Harikiri Stadium III Kyuukyoku Tiger L’Empereur Labyrinth Lagrange Point Last Armageddon Law of the West Layla Little Magic Little Mermaid Lode Runner Lord of King Lost Word of Jenny Lot Lot Lunar Ball Lupin III Sansei: Pandora No Isan Mach Rider Mad City Magic Candle Magic Darts Magic John Magical Taruruto-Kun: Fantastic World!! Magical Taruruto-Kun 2: Magical Adventure Magical Kids Doropi MagMax Magnum Kiki Ippatsu: Empire City 1931 MahaRaja Mahjong Mahjong Club Nagatacho: Sousaisen Mahjong Taikai Mahjong Taisen Mahou no Princess Minkiimomo Remember Dream Maison Ikkoku Majaventure – Mahjong Senki Majou Densetsu II: The Maze of Galious Major League Makai-Mura Maniac Mansion Mappy Mappy Kids Mappy-Land Mario Bros. Mario Open Golf Marusa no Onna Mashin Eiyuden Wataru Gaiden Mashou Masuzoe Kaname Icchou Made Famicom Matendo Douji Matsumoto Akira no Kabushiki Hisshougaku Matsumoto Akira no Kabushiki Hisshougaku II Max Warrior Meiji Ishin Meikyuu Kumikyoku Meikyuu Shima Meimon! Daisan Yakyuubu Meimon! Tako Nishiouendan Meitantei Holmes: Kiri no London Satsujin Jiken Meitantei Holmes: M-Kara no Chousenjou Melville no Honoo Metal Flame: Psybuster Metal Gear Metal Max Metal Slader Glory Metro Cross Mezase! Top Pro: Green ni Kakeru Yume Mickey Mouse Mickey Mouse III: Yume Fuusen Might and Magic Book One: The Secret of the Inner Sanctum Mighty Bomb Jack Mighty Final Fight Millipede Mindseeker Minelvaton Saga: Ragon no Fukkatsu Mini-Putt Minna no Tabou no Nakayoshi Daisakusen Miracle Ropitt: 2100-Nen no Daiboken Mirai Senshi Raios Mirai Shinwa Jarvas Mississippi Satsujin Jiken Mitokoumon Mitokoumon II: Sekai Manyuuki Mitsume ga Tooru Mizushima Shinji no Daikoushien Moai-Kun Moe-Pro! Saikyou Hen Moero TwinBee Moero!! Judo Warriors Moero!! Junior Basket Moero!! Pro Soccer Moero!! Pro Tennis Moero!! Pro Yakyuu Moero!! Pro Yakyuu ’88 Moero!! Pro Yakyuu ’90: Kandouhen Moeru! Oniisan Mokushi Pachi Pro: Pachi Otto-Kun Momotaro Densetsu Momotarou Densetsu Gaiden Momotaro Dentetsu Money Game Money Game II: Kabutochou no Kiseki Monopoly Monster Maker: Nanatsu no Hiho Moon Crystal Morita Shougi Mother Motocross Champion Mottomo Abunai Deka Mouryou Senki Madara Murder Club Musashi no Boken Musashi no Ken – Tadaima Shugyo Chu My Life My Love: Boku no Yume: Watashi no Negai Nagagutsu o Haita Neko: Sekai Isshu 80 Nichi Dai Boken Nakajima Satoru: F-1 Hero Nakajima Satoru F-1 Hero 2 Nakayo Shito Issho Namco Classic Namco Classic II Namco Mahjong III: Mahjong Tengoku Nantettatte!! Baseball Nantettatte Baseball KO Game Cassette ’91 Kaimakuban Nantettatte Baseball KO Game Set OB All Star Hen Napoleon Senki Navy Blue Nekketsu Kakutou Densetsu Nekketsu Kouha Kunio Kun Nekketsu Koukou Dodge Ball Bu Nekketsu Koukou Dodgeball-bu Soccer-hen Nekketsu Street Basket: Ganbare Dunk Heroes New Ghostbusters 2 New York Nyankies NHK Gakuen – Space School – Sansu 4 Nen (Ge)[8][9][10] NHK Gakuen – Space School – Sansu 4 Nen (Jou) NHK Gakuen – Space School – Sansu 5 Nen (Ge) NHK Gakuen – Space School – Sansu 5 Nen (Jou) NHK Gakuen – Space School – Sansu 6 Nen (Ge) NHK Gakuen – Space School – Sansu 6 Nen (Jou) Nichibutsu Mahjong III Niji no Silkroad Ningen Heiki Dead Fox Ninja Cop Saizou Ninja Crusaders Ninja Hattori-kun Ninja JaJaMaru-kun Ninja Jajamaru: Ginga Daisakusen Ninja Kun Ninja Kun: Ashura no Shou Ninja Ra Hoi! Ninja Ryuukenden Ninja Ryuukenden II Ninja Ryuukenden III Nippon Ichi no Meikantoku Nishimura Kyoutarou Mystery: Blue Train Satsujin Jiken Nishimura Kyoutarou Mystery: Super Express Satsujin Jiken Nobunaga no Yabou: Bushou Fuuunroku Nobunaga no Yabou: Sengouku Gunyuuden Nobunaga no Yabou: Zenkokuban North and South Nuts & Milk Obake no Q Tarou: Wan Wan Panic Obocchamakun Ochinnitoshi Puzzle Tonjan!? Oeka Kids – Anpanman no Hiragana Daisuki Oeka Kids – Anpanman to Oekaki Shiyou Oishinbo: Kyukyoku no Menu 3bon Syoubu Olympus no Tatakai Onyanko Town Operation Wolf Osomatsu-Kun: Back to Zami no Deppa Otaku no Seiza Outlanders Over Horizon Paaman Paaman Part 2 Pac-Land Pac-Man Pachicom Pachi-Slot Adventure 2 Pachi-Slot Adventure 3: Bitaoshii 7 Kenzan! Pachinko Daisakusen Pachinko Daisakusen 2 Pachiokun 2 Pachiokun 3 Pachiokun 4 Pachiokun 5 Palamedes Palamedes 2 Paperboy Parareru World Parasol Henbee Paris-Dakar Rally Special Parodius Da! -Shinwa kara Owarai e- Peepar Time Penguin-Kun Wars Perfect Bowling Photon: The Ultimate Game on Planet Earth Pinball Pinball Quest Pizza Pop Plasma Ball Pocket Zaurus: Ju Ouken no Nazo Pooyan Popeye Popeye no Eigo Asobi Portopia Renzoku Satsujin Jiken Power Blazer Power Soccer Predator President no Sentaku Pro Yakyuu Family Stadium Pro Yakyuu Family Stadium ’87 Pro Yakyuu Family Stadium ’88 Pro Yakyuu Satsujin Jiken! Punch-Out!! Puyo Puyo Puzslot Puzznic Pajama Hero Nemo Pyokotan no Daimeiro Quarterback Scramble Quarth Quinty Quiz Project Q: Cutie Project & Battle 1000 Racer Mini Yonku: Japan Cup Radia Senki: Reimeihen Raf World Raid on Bungeling Bay Rainbow Island: The Story of Bubble Bobble 2 Rambo Rampart Rasaru Ishii no Childs Quest Recca – Summer Carnival ’92 Red Arremer II Reigen Doushi Ripple Island Road Fighter Robocco Wars RoboCop RoboCop 2 Robot Block Robot Gyro Rockman Rockman 2: Dr. Wily no Nazo Rockman 3: Dr. Wily no Saigo!? Rockman 4: Aratanaru Yabo!! Rockman 5: Blues no Wana!? Rockman 6: Shijo Saidai no Tatakai!! Rokudenashi Blues Rollerball Rolling Thunder Route 16 Turbo Royal Blood RPG Jinsei Game Sensha Senryaku: Sabaku no Kitsune Saikoushi Sedi Saint Seiya Saint Seiya 2 Saiyuuki World Saiyuuki World 2 Sakigake!! Otokojuku Salad no Kuni no Tomato Hime Salamander San Goku Shi San Goku Shi II San Goku Shi: Chuugen no Hasha San Goku Shi II: Haou no Tairiku Sanada Juu Yuushi Sanma no Meitantei Sanrio Carnival Sanrio Carnival 2 Sanrio Cup: Pon Pon Volley Sansara Naga Sansu 1-nen: Keisan Game Sansu 2-nen: Keisan Game Sansu 3-nen: Keisan Game Sansu 4-nen: Keisan Game Sansu 5+6-nen: Keisan Game Satomi Hakkenden Satsui no Kaisou SD Battle Oozumou SD Gundam Gachapon Senshi 2: Capsule Senki SD Gundam Gachapon Senshi 3: Eiyuu Senki SD Gundam Gachapon Senshi 4: New Type Story SD Gundam Gachapon Senshi 5: Battle of Universal Century SD Gundam Gaiden: Knight Gundam Monogatari SD Gundam Gaiden: Knight Gundam Monogatari 2: Hikari no Kishi SD Gundam Gaiden: Knight Gundam Monogatari 3 Datach: SD Gundam: Gundam Wars SD Hero Soukessen: Taose! Aku no Gundan SD Keiji Blader SD Sengoku Bushou Retsuden: Rekka no Gotoku Tenka o Nusure! Seicross Seikima II Akuma no Gyakushu! Seirei Densetsu Lickle Seirei Gari Sekiryuou Senjo no Ookami Shadow Brain Shadowgate Shanghai Shanghai II Sherlock Holmes: Hakushaku Reijo Yukai Jiken Shikinjo Shin 4-Jin Uchi Mahjong: Yakuman Tengoku Shin Moero!! Pro Yakyuu Shin Satomi Hakken-Den – Hikari to Yami no Tatakai Shinjinrui Shinsenden Shougi Meikan ’92 Shougi Meikan ’93 Shogun Shonen Ashibe Nepal Daibouken no Maki Shuffle Fight Shufflepuck Café Side Pocket Silva Saga Sky Destroyer Sky Kid Snow Bros. Soccer Softball Tengoku Solomon no Kagi Solomon no Kagi 2 Solstice SonSon Soreike! Anapanman Minna de Hiking Game Space Harrier Space Hunter Space Invaders Space Shadow Spartan X Spartan X 2 Spelunker Spelunker II: Yusha e no Chosen Splatterhouse: Wanpaku Graffiti Spot Spy vs. Spy Spy vs. Spy II: Nankoku Shirei!! Sqoon Square no Tom Sawyer Star Force Star Luster Star Soldier Star Wars Star Wars Star Wars: Teikoku no Gyakushuu Stargate STED: Iseki Wakusei no Yabou Stick Hunter Sugoro Quest: Dice no Senshi Tachi Suikoden: Tenmei no Chikai Sukeban Deka III Super Arabian Super Black Onyx Super Chinese Super Chinese 2 Super Chinese 3 Super Contra Super Dynamix Badminton Super Mario Bros. Super Mario Bros. 3 Super Mario USA Super Mogura Tataki!! Pokkun Mogura Super Momotaro Dentetsu Super Pinball Super Pitfall Super Real Baseball ’88 Super Rugby Super Sprint Super Star Force: Jikureki no Himitsu Super Star Pro Wrestling Super Xevious: GAMP no Nazo Superman SWAT: Special Weapons and Tactics Sweet Home Sword Master Tag Team Pro Wrestling Taito Basketball Taito Chase H.Q. Taito Grand Prix: Eikou heno License Taiyou no Shinden Asteka II Taiyou no Yuusha Firebird Takahashi Meijin no Boken Jima Takahashi Meijin no Boken Jima II Takahashi Meijin no Boken Jima III Master Takahashi’s Adventure Island IV Takahashi Meijin no Bug-tte Honey Takeda Shingen Takeda Shingen II Takeshi no Chosenjo Takeshi no Sengoku Fuunji Tamura Teruaki no Mahjong Seminar Tanigawa Koji no Shougi Shinan II Tanigawa Koji no Shougi Shinan III Tantei Jinguji Saburo: Yokohamakou Renzoku Satsujin Jiken Tantei Jinguji Saburo: Toki no Sugiyuku Mama Ni Tao Tashiro Masashi no Princess ga Ippai Tatakae! Cho Robot Seimeitai Transformers: Convoy no Nazo Tatakai no Banka Tatake!! Ramen-Man Tecmo Bowl Tecmo Super Bowl Tecmo World Cup Soccer r (for TMNT 1, see Gekikame Ninja Den) Teenage Mutant Ninja Turtles: Super Kame Ninja (= TMNT 2) Teenage Mutant Ninja Turtles 2: The Manhattan Project (= TMNT 3) Tenchi o Kurau Tenchi o Kurau II Tenkaichi Bushi Keru Naguuru Tennis Terao no Dosukoi Oozumou Terminator 2 Terra Cresta Tetra Star Tetris Tetris 2 + Bombliss Tetris Flash Tetsudou-Oh Tetsuwan Atom Thexder Thunderbirds Tiger-Heli Time Zone Times of Lore Tiny Toon Adventures Tiny Toon Adventures 2: Montana Land e Yokoso Titan TM Network: Live in Power Bowl Tobidase Daisakusen 2: JJ Tokkyu Shirei Solbrain Tokoro-san no Mamoru mo Semeru mo Tokyo Pachi-Slot Adventure Tom & Jerry Tom Sawyer no Bouken Top Gun Top Gun: Dual Fighters Top Rider Top Striker Totsuzen! Macho Man Touch Down Fever: American Football Touhou Kenbunku Tokaido Gojusan-tsugi Toukon Club The Tower of Druaga The Triathlon Tsuppari Oozumou Tsuppari Wars Tsurikichi Sanpei Tsuru Pikahage Maru: Mezase! Tsuruseko no Akashi Twin Eagle: Revenge Joe’s Brother TwinBee TwinBee 3 Uchuu Keibitai SDF Uchusen: Cosmo Carrier Ultima Ultima: Seisha he no Michi Ultraman Club Kaijuu Dai Kessen!! Datach: Ultraman Club: Supokon Fight! Ultraman Club 2: Kaettekita Ultraman Club Ultraman Club 3 The Untouchables Urban Champion Urusei Yatsura: Lum’s Wedding Bell US Championship V’Ball USA Ice Hockey in FC Ushio to Tora: Shin’en no Daiyo Utsurun Desu.: Kawauso Hawaii e Iku!!! Valkyrie no Boken: Toki no Kagi Densetsu Valis: The Fantasm Soldier Vegas Connection: Casino Kara Ai wo Komete Venus Senki Viva Las Vegas Volguard II Wagyan Land Wagyan Land 2 Wagyan Land 3 Wai Wai World Wai Wai World 2: SOS!! Parsley Jo Wanpaku Duck Yume Bouken Wanpaku Kokkun no Gourmet World Wario no Mori Warpman Western Kids White Lion Densetsu Wild Gunman Willow Wily & Right no RockBoard: That’s Paradise Wing of Madoola Winners Cup Wit’s Wizardry: Proving Grounds of the Mad Overlord Wizardry II: Legacy of Llylgamyn – The Third Scenario Wizardry III: Knight of Diamonds – The Second Scenario Woody Poko World Boxing World Grand-Prix – Pole To Finish World Super Tennis Wrecking Crew WWF WrestleMania Challenge Xevious Yie Ar Kung Fu Yoshi no Cookie Yoshi no Tamago Yokai Dochuki Youkai Club Yousei Monogatari RodLand Ys Ys II Ys III: Wanderers from Ys Yume Penguin Monogatari Datach: YuYu Hakusho: Bakuto Ankoku Bujutsu Kai Zelda no Densetsu 1 Zenbei!! Pro Basketball
Famicom Disk System (FDS) Games
19 – Neunzehn Adian no Tsue Ai Senshi Nicol Akumajōu Dracula Akū Senki Raijin All Night Nippon Super Mario Bros. All One Apple Town Story The Miracle of Almana Aspic – Majaō no Noroi Backgammon Bakutōshi Patton-Kun Baseball Big Challenge! Dogfight Spirit Big Challenge! Go! Go! Bowling Big Challenge! Gun Fighter Big Challenge! Judo Senshuken Bio Miracle-I’m Upa Bio Miracle Bokutte Upa Bomberman Breeder Bubble Bobble BurgerTime Chitei Tairiku Ordola Cursed Treasure of Cleopatra Clox Clu Clu Land: Welcome to New Clu Clu Land Cocona World Dandy: Zeuon No Fukkatsu Dead Zone Deep Dungeon Dig Dug Dig Dug II Dirty Pair: Project Eden Donkey Kong Donkey Kong Jr. Doremikko Dr. Chaos Dracula II: Noroi no Fūin Druid: Kyōfu no Tobira Eggerland Eggerland – Departure to Creation Electrician Esper Dream Exciting Baseball Exciting Basketball Exciting Billiard Exciting Soccer: Konami Cup Fairytale Falsion Famicom Grand Prix: F-1 Race Famicom Grand Prix II: 3D Hot Rally Famicom Detective Club: The Missing Heir (first part) Famicom Detective Club: The Missing Heir (second part) Famicom Detective Club Part II: The Girl who Stands Behind (first part) Famicom Detective Club Part II: The Girl who Stands Behind (second part) Family Composer Family Computer Othello Final Command: The Red Fortress Fire Bam Fire Rock Fūun Shōrin Ken Fūun Shōrin Ken: Ankoku no Maō Gall Force: Eternal Story Galaga Galaxian German Tanteidan: Marine-gumi Jaaman Tanteidan: Matonarikumi Jaaman Tanteidan Marine Kumi: Maruhi Jigoma Sousa File Ginga Denshō: Galaxy Odyssey Gokuraku Yūgi: Game Tengoku Golf Golf Japan Course Golf U.S. Course The Goonies Green Beret Gun.Smoke Gyruss Halley Wars Hao’s Mysterious Journey Hikari Genji: Roller Panic Hikari Shinwa: Palthena no Kagami Hong Kong I am a Teacher: Super Mario no Sweater I am a Teacher: Teami no Kiso Ice Climber Ice Hockey Igo: Kyū Roban Taikyoku Ishido: The Way of Stones Janken Disk Jō Jikai Shounen Mettomag The Return of Mario Bros. Kamen Rider Black: Taiketsu Shadow Moon Karate Champ Kattobi! Dōji Kick and Run Kick Challenger: Air Foot Kidō Keisatsu Patlabor Kiki Kaikai: Dotō Hen Kieta Princess Kinnikuman: Kinniku-Sei Ōi Sōdatsusen Knight Lore Knight Move Konami Ice Hockey Konami Tennis A Kitten’s Story: The Adventures of Chatran The Legend of Zelda The Legend of Zelda 2: The Adventure of Link Lutter Magma Project: Hacker Mahjong Mahjong Kazoku Märchen Veil Matō no Hōkai: The Hero of Babel Meikyū Jiin Dababa Metroid Michael English Daibōken Moero Twinbee: Cinnamon Hakase wo Sukue! Monitor Puzzle, The: Kineco – Kinetic Connection Monitor Puzzle, The: Kineco Vol. II – Kinetic Connection Monty no Doki Doki Daisassō: Monty on the Run Moonball Magic Mr. Gold: Tōyama no Kinsan in Space Nakayama Miho no Tokimeki High School Namida no Sōkoban Special Nanking no Adventure Nazo no Kabe: Block Kuzushi Nazo no Murasame Jō Nazoler Land Nazoler Land Dai 2 Gō Nazoler Land Dai 3 Gō Nazoler Land Special Omoikkiri Tanteidan Haado Gumi: Matenrō no Chōsenjō Otocky Pac-Man Pachicom Pachinko Grand Prix Panic Space Pinball Pro Golfer Saru: Kage no Tournament Professional Mahjong Goku Pulsar no Hikari: Space Wars Simulation Pro Wrestling: Famicom Wrestling Association Putt Putt Golf Puyo Puyo Puzzle Boys Radical Bomber!! Jirai Kun Reflect World Relics: Ankoku Yōsai Replicart Risa no Yōsei Densetsu: Risa Tachibana Roger Rabbit Samurai Sword Santa Claus no Takarabako SD Gundam World: Gachapon Senshi – Scramble Wars SD Gundam World: Gachapon Senshi – Scramble Wars Map Collection Section Z Seiken: Psycho Calibur Shin Onigashima (Disk 1) Shin Onigashima (Disk 2) Smash Ping Pong Soccer Solomon no Kagi Suishō no Dragon Super Boy Allan Super Lode Runner Super Lode Runner II Super Mario Bros. Super Mario Bros. 2 (different from US version) Sword of Kalin Silviana Tama & Friends: Great 3rd Street Adventure Tanigawa Kōji no Shōgi Shinan II Tanigawa Kōji no Shōgi Shinan II – Shinban Tantei Jingūji Saburo: Kiken na Ninin (first part) Tantei Jingūji Saburo: Kiken na Ninin (second part) Tantei Jingūji Saburo: Shinjuku Chūō Kōen Satsujin Jiken Tarot Tennis Time Twist: Rekishi no Katasumi de… (first part) Time Twist: Rekishi no Katasumi de… (second part) Titanic Mystery (Ao no Senritsu) Tobidase Daisakusen Topple Zip Transformers: The Headmasters TwinBee Ultraman: Kaijū Teikoku no Gyakushū Ultraman 2: Shutsugeki Katoku Tai Ultraman Club: Chikyū Dakkan Sakusen Volleyball Vs. Excitebike Wardner no Mori Winter Games Wrecking Crew Xevious Yōkai Yashiki Yume Kōjō: Doki Doki Panic Yū Maze Yūshi no Monshō Yūyūki (first part) Yūyūki (second part) Zanac
There are so many topics to discuss. It would be very difficult to cover 100%. Let’s briefly mention a few of the things I forgot to mention.
Multiplication and Division
SNES has hardware to perform multiplication and division. Actually, it has 2 ways to do multiplication. You can look at my EasySNES code to find examples of these (link below, search for multiply: and divide:). They are a little slow, so you can’t expect to do this 100x a frame. You have to wait a several cycles before you get a result for the regular multipy and divide functions (see the NOP opcodes, which do nothing but wait).
If you aren’t using Mode 7, there is a second multiply function (signed) which is much faster. It’s called multiply_fast: in this link.
Well, this one is over $200 US, but the basic model is less than $100, and it is well worth it. It works great. It uses a MicroSD card to hold the game ROMs.
Mode 7
This is the big enchilada, but I haven’t quite figured out this mode. Especially, setting up a tool chain for editing. Mode 7 can stretch and zoom and rotate. Many of the coolest SNES games use this in some way. It’s just currently above my skill level.
I do plan to work on this in the future. I might even make my own tools. But, that might be months, or even years from now.
IRQ Timers
This is for timing mid screen events. You should try to use HDMA instead. If all 8 HDMA channels are being used, you could do a 9th thing with IRQ timers.
You need to enable IRQ timers (probably just the V timer). and CLI to enable IRQs on the CPU. And you need to add code to the IRQ handler. Once set, the counter will trigger an IRQ signal once the PPU reaches a specific scanline. H counter would fire an IRQ signal every scanline, and you probably don’t want that.
Enhancement Chips
Another thing that is a bit over my head. The SA-1 chip is just a much faster 65816 chip, and that might be the easiest to use.
enemy AI functions (probably wouldn’t be useful to you)
.
The cool chip is the SuperFX chip (GSU). That’s what StarFox used. It would be nice if I could figure it out, and explain it. But, I can not.
Other Modes
Hi resolution. Modes 5 and 6 are double horizontal resolution. They can also, optionally, do an interlaced mode which doubles vertical resolution. Very few games used hi resolution.
Offset per tile Modes 2 and 4. I need to investigate these a bit more. I don’t want to put incorrect information here.
SRAM
For LoROM, SRAM is mapped to banks $70–$7D in the $0000-$7FFF addresses. And also in the $FE-$FF banks in the $0000-$7FFF addresses. (7e and 7f banks are the WRAM, so that couldn’t be used for SRAM). That gives a total possible 512kB SRAM (battery backed save RAM).
You will also need to indicate in the header that the ROM is using SRAM. I think that’s mapped to $FFD7, but it’s this line in the header.asm file
.byte $00 ; backup RAM size
The value is (2^# in kB). 3 is 8kB, 4 is 16kB, 5 is 32kB, 6 is 64kB, 7 is 128 kB, 8 is 256kB, and 9 is 512kB. 0 means 0kB.
Oh, and the previous line, mapped to $FFD6, should have the d1 bit (0000 0010) set. To indicate a battery for the SRAM.
Once you have correctly set this, the emulator should automatically be creating SRAM save files, that persist after power off. You can freely read and write to this anytime, and you can save your game by keeping the progress stored in the SRAM.
What is color math? If you’ve ever worked with Photoshop, it would be like blending 2 different layers. In this case the layers are the MAIN screen and the SUB screen. Everything we have done so far deals with the MAIN screen. So let me try to explain the SUB screen.
All that stuff that the SNES does to produce a picture, putting layers on top of each other, tile priorities, sprite priorities, etc… it does all that TWICE. If you set the settings for the MAIN screen exactly the same as the settings for the SUB screen, it would produce the exact same picture TWICE… with 1 difference. The main screen uses color index zero as the backdrop color (any pixel that is transparent), and the sub screen uses the “fixed color” as the backdrop color (register $2132).
You would never see the SUB screen, unless you turned on the color math registers, which would then blend the 2 pictures together, using either addition or subtraction. And then there is an optional halving step after that. Each pixel on the screen, the R values are added or subtracted, and the G value, then the B value. That value is clamped to the max and min without overflow. (each RBG value is 0-31)
Let’s say we have it set to ADD. And the main screen pixel is gray 15,15,15, and the sub screen pixel is dark red 10,0,0. The final pixel would be 25,15,15.
If we added the HALF option, each value would shift right once (rounding down), giving a final pixel of 12,7,7.
If we set the color math to SUBTRACT (no halving), the final pixel would be 5,15,15. The RGB values of the sub screen are subtracted from the RBG values on the main screen.
If we added the HALF option, each value would shift right once (rounding down), giving a final pixel of 2,7,7.
Note, any pixel in the sub screen that is transparent will not be halved.
The main use for Color Math is for transparency effects. You will want Adding and Halving. That would equally blend the main and sub screen.
The least useful setting is the subtract and halving. That would just produce a very dark picture, and almost no games used this.
.
There is a completely different kind of color math operation, that uses ONLY the fixed color. That color is applied to the entire MAIN screen, and if halving is set, it will work for the whole screen. If you set the fixed color register to green, and had the color math set to ADD, it would add a green tint to the screen.
The fixed color register is weird. The wiki example suggest writing each color separately to it (3 writes for R,B, and G). However, you could set them all to a specific value with 1 write. Such as LDA #$E0, STA $2132 would set all fixed colors to zero.
Before we dive into the code, here’s a video. You can probably skip most of this video, which goes into too many details about how the 2 different screens are generated.
Example ROM
I put BG1 on the main screen (gray rocks) and BG2 on the sub screen (color bars).
No effect. Color Math disabled.
Just the Sub screen. (seen by setting the “clipping always to black” bits in the color math logic, and adding the sub screen).
Note, the top left is black (non-zero index). The bottom left is zero index (transparent). The sub screen will show the “fixed color” (register 2132) where there is transparent. Right now the fixed color is black. Color halving will not work for a transparent pixel on the sub screen. If you notice, the bottom left square will not change at all for these examples, even when halving is indicated.
Color Math Adding.
Color Math Adding and Halving.
Color Math Subtracting.
Color Math Subtracting and Halving.
Fixed color only (red at 50%), Color Math Adding.
Here’s a YouTube video of the Example code.
Example Code
$2130
ccmm--sd
cc = main screen black if... *
--mm---- = prevent color math if... *
------0- = fixed color
------1- = sub screen
d is for an unrelated thing
* 00 => Never
01 => Outside Color Window only
10 => Inside Color Window only
11 => Always
$2131
shbo4321
0------- add
1------- subtract
-0------ normal
-1------ result is halved
b = backdrop, o = sprites, 4321 = layers enabled for color math
So let’s go over each examples.
1- no effect, turn off color math
lda #$30 ; = off
sta color_add_sel ; $2130
;and make sure fixed color is black
lda #$e0 ; RGB, value = 0
sta color_fixed ; $2132
2- adding
lda #$02 ; color math with subscreen
sta color_add_sel ; $2130
;adding, not half, affect all layers
lda #$3f
sta color_add_des ; $2131
3- adding and half, same as last one, just add one bit to the 2131 write
;adding, half, affect all layers
lda #$7f
sta color_add_des ; $2131
4- subtracting
lda #$02 ; color math with subscreen
sta color_add_sel ; $2130
;subtracting, not half, affect all layers
lda #$bf
sta color_add_des ; $2131
5- subtracting and half. Same as last one, but add one bit to the 2131 write
;subtract, half, affect all layers
lda #$ff
sta color_add_des ; $2131
6- fixed color only
;turn on color math, fixed color mode
lda #$00
sta color_add_sel ; $2130
;adding, not half, affect all layers
lda #$3f
sta color_add_des ; $2131
;set the fixed color to red 50%
lda #$2f ;red at 50%
sta color_fixed ; $2132
We could have also set half mode.
7- see just the sub screen. We did this by setting the “always clip main screen to black” bits in 2130, and then adding the sub screen to the now completely black main screen.
lda #$c2 ;= clip main always to black
sta color_add_sel ; $2130
;adding, not half, affect all layers
lda #$3f
sta color_add_des ; $2131
Other examples
Color math only affects some sprites. Only sprites that use palettes 4-7 are affected by color math. That is why Mario (and the little ghosts) are solid.
Windowing can affect where the color math applies. With HDMA adjusting the window, you can make some cool effects.
Tint the whole screen (adding a fixed color)… actually, upon further investigation, this is subtracting, which makes the screen slightly darker than the original. Also, the COLOR MATH is not in fixed color mode, it’s in subscreen mode, but NOTHING is enabled on the subscreen, so the subscreen is filled with the backdrop color (which for the sub screen is the fixed color). I guess that works too.
Smooth Transparencies (add and halving). This is the most common transparency effect on the SNES.
Sparkster, the water.
And creating shadows (subtracting) Mortal Kombat II. It’s hard to tell, but their shadows are created by color math subtraction. You could also give the appearance of clouds moving overhead by subtracting a cloud shape and having it scroll.
HDMA is a way to write to PPU registers while the screen is drawing. You can change values at specific scanlines, to create unique effects.
The H is for H-Blank. Remember before, when we talked about V-blank (vertical blank), where the PPU isn’t doing anything for a short while after drawing each screen? Well, it also pauses a VERY SHORT time after drawing each horizontal line. Just long enough for the 8 HDMA channels to quickly change a register or send data, before the screen goes to write the next line.
They work in order, 1,2,3,4,5,6,7,8. They can all write 1 thing (1,2 or 4 bytes) per line. Or you can set them to wait a specific number of lines before changing a value.
HDMA uses the same registers as the DMA registers, and you shouldn’t use both at the same time. You should write zero to HDMA enable ($420c) before performing a DMA. Because the oldest revision of the SNES has a bug where it can crash if they both happen at the same time.
Here’s an interesting video on DMA and HDMA.
Examples
Here’s some things you can do with HDMA.
Changing the BG color with HDMA, to create a color gradient.
Changing the Window (there are 2 windows) with HDMA, to block off portions of the screen. The windows have left and right registers, which need to be written every scanline to create these shapes.
Mode 7 parameters. (lots of registers to change hundreds of times a frame).
When you look at the HDMA registers, it looks like you need to put MORE values than a DMA (DMA uses 4300-4305 for channel 0 and HDMA uses 4300-430a)… but you actually write LESS values. Let’s go over them briefly, then in detail. For channel 0.
4300 – yes
4301 – yes
4302-4 – yes
4305-6 – no
4307 – yes, only if using Indirect Mode.
4308-a – no
4300 - Control Register. da---ttt
D=direction, probably want 0, from CPU to PPU.
A=HDMA mode. 0 for direct, 1 for indirect. More on this later.
TTT = transfer mode, which will vary by which register we use.
4301 – the PPU destination register. 21xx. So if you write $22 here, the HDMA will write to the $2122, the CGRAM Data Register.
4302-4 – the address of the HDMA table. 2=low, 3=middle, 4=upper/bank #.
4307 – if using Indirect HDMA, this is the bank # of the Indirect Addresses.
Anything marked “no”, don’t touch them. They are used by the HDMA hardware.
Then you write the channel (bitfield, each bit represents a channel, 1 for ch0, 2 for ch1, 4 for ch2, 8 for ch3, etc) to $420c, the HDMA enable register. Presumably, you would do this each frame during v-blank.
.
OK, so we are pointing the HDMA registers to a table (byte array). For a direct mode, the table would be a scanline count, then (depending on the TTT mode) 1,2, or 4 bytes to be written. Then another scanline count, then more bytes. Scanline count, bytes. Scanline count, bytes. Etc, until it sees a zero in the scanline count slot. From my own examples…
That reads 32 lines, value $0f. 32 lines, value $1f. 32 lines… etc down to the terminating 0. One interesting thing is that the $0f is written immediately at the very top of the screen. THEN it waits 32 lines.
Here’s another example, when the transfer mode is “1 register write twice”.
10 is the scanline count. Then 2 bytes to write. Then 10 scanline count. Then 2 bytes. Etc.
Indirect Mode
43×0 register, we can set it to Indirect. Only with indirect do you need to write to 43×7, the bank of the indirect address. The table will always be sets of 3s. First the scanline count, then an indirect address (ie. pointer) to where our data is. I wrote the HDMA table like this…
The .addr directive outputs a 16 bit value, low byte then high byte. I think you could have also used the .word directive. So, 8 is the scanline count, then an indirect address. Our bank byte is $7e, so the first one points to WRAM $7e1000. The second one points to $7e1002. Etc.
One of the advantages of the indirect system is that you can have a repeated pattern that changes.
I had copied the Indirect Table to $7e1000. It looks like this.
All of these are values to be written with HDMA to a PPU register. In this case, a horizontal scroll register, which is write twice (low then high bytes).
This is example 3. I am also shuffling these values every 4 frames, which causes the movement of the the sine wave.
Example Code
No effect. HDMA is turned off by writing zero to $420c.
Example 1. Changing the BG color.
I’m actually setting up 2 separate HDMA transfers. First to set the CG address to zero. Second to write 2 bytes to change the #0 color. You have to rewrite the address each time, because it auto-increments when writing a color.
stz $4300 ;1 register, write once
lda #$21 ;pal_addr
sta $4301 ;destination
ldx #.loword(H_TABLE1)
stx $4302 ;address
lda #^H_TABLE1
sta $4304 ;address
lda #2
sta $4310 ;1 register, write twice
lda #$22 ;pal_data
sta $4311 ;destination
ldx #.loword(H_TABLE2)
stx $4312 ;address
lda #^H_TABLE2
sta $4314 ;address
lda #3 ;channels 1 and 2
sta hdma_enable ;$420c
And we have 2 HDMA tables (see the example code). Each time we are waiting 10 scanlines between changes. Each time, adding a little more red.
On a side note, you could set this up as a single HDMA channel. With a “2 registers write twice each” mode. You would be doing double writes to the CG address, and you would need 4 bytes after each scanline count.
Example 2. Changing window 1 left and right positions.
A window punches a hole in one or more layer. There are 2 windows, but we only need 1 for this example. The only parameters you can set are left and right (and inverse, and combinations with the other window). But with HDMA, you can adjust the window parameters as the screen draws, and draw a shape. Circle shapes are very popular.
If the left position is > than the right position, the window will not appear. That is what we are doing for the top and the bottom of the screen. You also have to tell it which layers are affected with the $212e (window for main screen) and with the $2123-5 registers.
I’m using 2 HDMA channels, and writing 1 byte to 1 register. To 2126 and 2127.
(Again this could have been done with 1 channel with a 2 register transfer mode).
This example shows the Multi Single Scanline feature. If the scanline count is >128 (not including 128), it signals a series of single scanline writes. You can omit the scanline count for a number of lines (ie. subtract 128 from the scanline count number).
.byte 60, $ff ;first we wait 60 scanlines
.byte $c0 ;192-128 = 64 lines of single entries
.byte $7f ;1st write value
.byte $7e ;2nd write value
.byte $7d ;3rd write value
.byte $7c ;4th write value
...etc...64 lines.
.byte 0 ;end
It waits 1 scanline between each write.
Each line, I am moving the left position and right position further apart, and then closer together, which forms a diamond shape.
Example 3. Changing BG1 horizontal scrolling position.
This was already discussed above, in the Indirect Mode section. We are using a sine wave pattern to create a wave in the picture, writing twice to 1 register, the horizontal scroll of BG1.
I wanted to include at least 1 example of indirect mode. I copied the value table to the RAM, so I was able to change the values to make the pattern move. See the Shuffle_f3 function in the HMDA3.asm file. The table of Indirect Addresses points to the RAM where our actual values are stored.
This example would have been even nicer if we wrote new values every scanline. Currently, we are only changing values every 8 scanlines (to make the table simpler / smaller). Maybe even every 2 scanlines would have been enough.
Example 4. Changing the Mosaic filter.
This is the simplest example. A single write to a single register. I haven’t discussed the Mosaic filter before, $2106 . The upper nibble is the mosaic amount (0 = normal, 1 = 2×2, etc up to $f = 16×16), and the lower nibble says which layers are affected. Sprites are never affected.
stz $4300 ;1 register, write once
lda #$06 ;mosaic
sta $4301 ;destination
ldx #.loword(H_TABLE6)
stx $4302 ;address
lda #^H_TABLE6
sta $4304 ;address
lda #1 ;channel 1
sta hdma_enable ;$420c
It waits 32 lines before increasing the mosaic value. There are bigger squares at the bottom. You probably wouldn’t use this exact HDMA effect in a game, but it is just an example of what is possible. You can change so many settings, even the BG mode $2105, which layers are active, change the location of a tilemap or tileset. I think you can even write new data to the VRAM (a little bit at a time).
Here’s a YouTube video of these examples.
Caution
Because HDMA settings need to be rewritten every frame, this code example would break in a lag frame… like if our game logic ran so long that it took 2 frames to complete one loop. You would have half of the frames missing the HDMA effect.
Therefore, you should put HDMA code inside the NMI code. NMI code is guaranteed to execute every frame, during v-blank. You should also put your DMA code here (copying bytes to the VRAM or OAM). Some games have very elaborate NMI code. I don’t currently have a proper example with HDMA in the NMI code. I’ll put that on my TODO list.
Here’s an interesting video on the SPC700 and SNES audio.
Today, we are going to talk about SNES music. The APU (Sony SPC700) is a different chip entirely, and has its own 64k of RAM. At the beginning of our program, we need to load the APU with our SPC file. It is an audio program that runs automatically.
The APU is connected to an 8 channel DSP (digital sound processor). The song will direct the DSP to play different sound samples at different rates to make tones. If you are familiar with MIDI, it is similar. The samples can be looped or not. The samples are compressed into a native compression called BRR (bit rate reduction).
BRR samples are very large, and you will probably be only able to fit 10-15 samples. Each will have to be edited (perhaps with Audacity) to less than a second each, and at a reduced sample rate. We are going to work with SNESGSS (written by Shiru). I got the files from here, and from the source code for one of Shiru’s SNES projects.
However, don’t use the .exe here. Apparently, there is a bug in the SNES hardware, where if the APU reads a value at the exact moment it is changed, it sometimes reads the wrong value. This can cause the game to crash. See the discussion here…
and also grab the music.asm file. You will need it.
Anyway, the patch works, but it forced me to overwrite something, and I chose to disable the streaming function. I tested this on a real SNES dozens of times with no problems.
.
SNESGSS prefers to have 16-bit MONO WAV samples at sample rate 32000 or 16000. I have tried 8000, but there is no improvement.
There seems to be a bug in Audacity, when you resample to another rate (Tracks/Resample), it seems to work, but then saves it to the original rate. But if you resample it, cut it, and then open a new window and start a new project at the target rate, and then paste it and then save it, it works. I don’t know what’s up with that.
Recording at the desired rate has no problems. 16000 seems to be a nice sweet spot on audio quality and file size.
SNESGSS also suggests tuning the samples to B +21 cents. I did not. I left all my samples at C. They are not in tune with the samples provided with SNESGSS, which I did not use. I think those are tuned to B +21.
Hit the WAV button near the middle of the screen to load your samples. Setting the envelopes similar to this seems good (15, 1, 7, 16) You can press the 2x or 4x buttons if you run out of room for files, to downsample by half. You can set a Loop, and adjust the numbers in “from” and “to”… which I find incredibly difficult to use.
I wouldn’t mess with the volume or EQ settings. That is something you should have done in Audacity while editing. Just keep in mind that the SNES tends to weaken the upper range and make bright sounds feel dull. You might have to do a treble boost for the lead instruments.
This tracker will convert our samples to BRR, but not until your final export. Unfortunately, you can’t import BRR samples to it from other sources. You could use other SNESGSS instruments (the ones that Shiru provided, for example).
Here you can check the size of all the files. Obliviously, you can’t have a bigger SPC file than 64k, the size of the APU RAM.
I should note, that we only load 1 song in the APU RAM at a time. Staring a new song will load a new song (over the previous song), so that only one song is loaded at any time. That should give you a little flexibility on overall size.
Here is the main editor. You type Z-M keys for lower octave, Q-P keys for upper octave. You can change the octave by pressing the octave button. So, this is a standard tracker, it goes downward as the song plays.
You can toggle channels on and off by clicking on the word “channel 1”, etc. You can divide things into sections. Press the spacebar to mark the end of a section. Then you can repeat the previous section with an R00 command.
The order of things is Note, Instrument, Volume 0-99, and Special effects. The SP column is for song speed (smaller is faster). You can scroll up and down with PgUp and PgDn keys, and also Home and End goes to the next section.
CTRL+End marks the end of the song, and CTRL+Home marks the loop back point.
You can import Famitracker and MIDI files (notes only), but I haven’t tried.
On this page, you can mark a song as a “Sound effect”.
Once the songs are done, you File/Export. And that will produce several files.
spc700.bin is our main SPC file. It holds the program and the samples and the sound effects data.
music_1.bin (one file per song) is the song data.
sounds.asm and sounds.h we don’t need. Don’t include them. This was for a different assembler / C compiler. You might want to look at it to find the value of each sound effect.
.define SFX_DING 0
…tells us that the DING sound effect is called with the value zero.
you will see a file called Split.py. This is a python script to split the SPC file into 2 pieces if needed. Let me explain that a bit. We are mapping our SNES game as LoROM, which means that our banks are only 32k. The SPC file could be 64k in size. It needs to be split up to be included without editing the linker file.
Also the music loader function will fail to load correctly if it is >32k. Because of that, I have been copying the SPC file to the 7f0000-7fffff WRAM first, and then calling the INIT function (which copies the SPC file to the APU RAM).
The example code, however, is smaller than 32k, so this step is unnecessary.
CODE
Let’s go over the music.asm file, which you should have grabbed from one of my example folders. I had to modify the original code to work with ca65.
spc_init – should be called at the start of the game, with interrupts off (NMI, IRQ, controllers). With AXY16 you load A with the address of the of SPC file (spc700.bin) and X with the bank of the SPC file, and JSL to spc_init.
This is all well and good if the SPC file is < 32k, but if it’s over 32k, and we are mapped as LoROM (ROM banks of 32k), I have had to first copy all the SPC files to $7f0000-7fffff WRAM and then load A with 0000 and X with $7f and then JSL to spc_init.
spc_init expects the SPC file to be contiguous.
SPC file > 32k also means I need to either modify the linker script, or split the SPC file into 2 chunks, and include them into 2 different banks. I decided on the later. You could do this in a hex editor. I wrote a little python script to do the same (Split.py). If you had python3 installed, you would call a command line promt and type “Split.py spc700.bin” and it would split it into 2 files (smaller than 32k).
By the way. Running this function takes a long time. It could take 2 seconds or more.
spc_load_data is an internal function, for loading data to the APU RAM.
spc_play_song loads a song (data) to the APU RAM and then starts playing it. This also should be done with interrupts off. Note that this system only loads one song at a time to the APU RAM. If you have a song in and then load another song, it overwrites the first song.
With AXY16 load A with the address of the song data (ike music_1.bin) and load X with the bank of the song, then JSL to spc_play_song. Once it’s done, it will begin playing the song automatically.
spc_command_asm is an internal function. It’s what sends signals to the APU.
spc_stereo is to set mono (default) or stereo audio. Load A (8 or 16) with 0 for mono, 1 for stereo. Audio channels can be panned left or right.
spc_global_volume is to set the max volume, 0-127. It can also be used to fade in or fade out. One of the variables is called speed, and it is the step value, to go from previous volume to the new volume. 255 is the default speed, which is instant change (any value >= 127 would be instant). Speed of 7 seems nice for a fade, and will take 2 seconds to transition. Don’t give it a speed of zero, the volume won’t change.
AXY8 or AXY16, load A with the speed of volume change (1-255), and load X with the new volume (0-127), then jJSL spc_global_volume.
The SNES has a master volume variable, which affects all channels. That’s what this sets, and doesn’t affect individual channel volumes.
spc_channel_volume sets the max volume for an individual audio channel. AXY8 or AXY16, load A with the channels and load X with the volume (0-127) and the JSL to spc_channel_volume. I’m not sure what circumstances I would use this. Maybe to silence or dim a lead instrument, for a change in dramatic tone.
Note, the channel here is a bitfield, with each bit representing a channel.
For example, LDA #$42 (0100 0010) would effect channels 2 and 7.
music_stop stops the song. JSL here.
music_pause will pause and unpause the song (and not effect the sound effects that are playing). Load A (8 or 16) with 1 for pause and 0 for unpause, then JSL here.
sound_stop_all stops all sounds, song and sound effects. JSL here.
sfx_play_center plays a sound effect, pan center. With AXY8 or AXY16, load A with the # of the sound effect, load X with the max volume of the sound effect (0-127), and load Y with the channel (0-7), the sound effect should play. Channel needs to be higher than the max channel for the song playing. Therefore, you must reserve some empty channels in the song, if you want sound effects to play with it.
sfx_play_left, is the same, but pan left.
sfx_play_right, is the same, but pan right.
sfx_play is an internal function that the 3 above functions call.
Streaming has been removed.
EXAMPLE CODE
This is the audio loading code from the example. It was for an SPC file smaller than 32k.
AXY16
;copy music to 7f0000
BLOCK_MOVE (music_code_end-music_code), music_code, $7f0000
;copy the music code and samples to the Audio RAM
lda #0000
ldx #$7f ;address 7f0000
jsl spc_init
AXY16
lda #$0001
jsl spc_stereo
And the copying to the APU RAM was the same, except that I had 2 move instructions to copy to $7f0000.
;copy music to 7f0000
BLOCK_MOVE $8000, music_code, $7f0000
BLOCK_MOVE (music_code2_end-music_code2), music_code2, $7f8000
;copy the music code and samples to the Audio RAM
lda #0000
ldx #$7f ;address 7f0000
jsl spc_init
…so that spc_init could load the entire SPC file as one contiguous chunk.
.
Then I load the song, and start it playing (before I turn on NMI interrupts).
By the way “.loword()” gets a 16 bit value from a 24 bit label. ^ gets the bank of a label.
.
Now I just need to set up a trigger for the sound effect. We already have that yellow block triggering the screen to go dark, so I just snuck in a little more code there. I didn’t want it re-starting the same sound effect over and over and over each frame, so I added a variable to remember the LAST FRAME, if we were over the yellow block, and skip a trigger in that case.
cmp bright_var2 ;compare to last frame
beq Past_Yellow ;skip if last frame is true
AXY8
lda #0 ;= ding
ldx #127 ;= volume
ldy #6 ; = channel
jsl sfx_play_center
Our song plays from channels 1-4 (ie. 0-3), and our sound effect uses 2 channels, so we could have set this to 4,5, or 6. This function is zero based index, ie. values 0-7. So 6 means it will play on channels 7 and 8. Sorry for flip flopping between zero based and one based numbers. Hope this isn’t too confusing.
However, if we loaded X with 0,1,2, or 3. It would not play. If we loaded X with 7, only the first channel of the sound effect would play.
Here’s a picture of the demo again. It looks the same as the previous example.
There are other programs for getting music onto a Super Nintendo.
You could use SNESMOD with OpenMPT. I still need to research this more before I can recommend it. I have heard that a version of SNESMOD by AugustusBlackheart and KungFuFurby is good. Sorry I can’t be more informative here.
Another program, BRRTools, can convert audio files to BRR. I haven’t used it, but the SNESGSS tool uses the same code. It says you can turn BRR samples into WAV and WAV into BRR. This could be a way to use existing BRR samples in our SNESGSS projects (by using this tool to convert them into WAV files first).
This time we are going to make a collision map, and make a sprite collide with the background. The actual graphics are not that important.
I took some pictures of some blocks (and a sketch of a cube with eyes) and Photoshopped them (GIMP) into 16×16 sized PNG (indexed 16 colors) and converted them to SNES .chr files with Superfamiconv. Actually, I expanded them to 32×16, with the left just filled with black. I thought that would give us a consistent zero index color of black, and it seems to have worked. Then I loaded everything into my M1TE tool.
I made the BG map in M1TE. It would have been nice if it supported 16×16 tiles, (all of our blocks are 16×16) but I didn’t program in 16×16 tile mode yet. I can load this into the game, no problem, but there is no easy way to make a collision map out of this. I could type one by hand. It would be an array of numbers 16×14 (224 total). Zero for blank, 1 for wall. Each number would represent a 16×16 square area of the screen.
This time I used Tiled Map Editor to make a collision map. I loaded a picture of my 3 tiles as the tileset (see right side), and recreated the BG map that I had made in M1TE. The entire purpose of this is to export a .csv file of our collision map… which is that collision array I was talking about.
The CSV file exported from Tiled.
I added some .byte directives so it can be loaded as a byte array into the asm code. 0 is blank, 1 is red wall, 2 is the yellow square. Maybe in the future I will program some clever app or tool to speed this up. This time I just copy and pasted the word “.byte” to each line and resaved it.
Our code calculates where our guy is on the map, and prevents movements if it’s over a 1 (wall). We now collide with the red walls.
How does it do that? Let’s go over the code. So our byte array has each block 16×16. We need to divide x and y pixel coordinates by 16 (the same as shift right 4x). But we also need to multiply the y by 16 to get to the correct row in our array, which cancels out the divide 16. So the algorithm is (Y & 0xf0) + (X >> 4). If we look at that index in the byte array, it will tell us if a point is in a wall or not. This is the code, with X and Y registers holding the X and Y coordinates…
tya
and #$f0
sta temp1
txa
lsr a
lsr a
lsr a
lsr a
ora temp1
tax
lda HIT_MAP, x
rts
I handled each direction separately. First do the X move, then see if any of the corners of our sprite are inside a wall. If yes, revert to previous X position. Then do the Y move, see if any of the corners of our sprite are inside a wall. If yes, revert to previous Y position.
This code would need to be a little more complex if we move more than 1 pixel per frame. If we are moving 2-3 pixels per frame, and the distance to the wall is 1 pixel, we should allow 1 pixel movement toward the wall… and not be stuck 1 pixel away from the wall. So, this code will need to be improved.
.
Touching the yellow square will darken the screen. We are just looking if 1 point (the middle of our guy) is over a 2 in the collision map, and changing the screen brightness variable. Remember that the $2100 register is the screen brightness. I am writing to it every frame, during v-blank. Full brightness is $0f. Half brightness is $07.
If we were scrolling in a larger world, the collision map would have to be the size of the world. You could have it compressed, and decompress it to the WRAM. You would have to keep track of X and Y movements with 2 byte variables. One thing I would not recommend is trying to read from the VRAM to see what kind of tile you are standing over. The visuals of the level should probably be separate from the collision map.
One more thing. It wouldn’t be too much trouble to turn this simple example into a platformer. You would just need to add gravity, which is adding a little bit to the Y speed every frame, and then cancelling that if your feet touch the floor. Jumping would be a sudden negative Y speed.
This is a really cool page that explains collision maps in more detail.
So, this isn’t so complicated. I’m using the Example 4 backgrounds, and scrolling them with the controllers. I’m not going to go over the process of making backgrounds again. We will just talk about the scrolling code.
If you press A, B, X, or Y, you will toggle which background is selected. Visible by the sprite in the corner (1,2,3). This is the map_selected variable, which has a value 0-2.
The up/down/left/right functions will do a case switch style check on the map_selected variable. Normally, you would do CMP #1, CMP #2, CMP #3, etc. But you don’t actually need to do a CMP #0. This is something I see new 6502/65816 programmers do. The previous line “lda map_selected” already sets the z flag if map_selected is zero. Lot’s of instructions set the z (zero) and n (negative) flags. LDA, LDX, LDY, TAX, TXA, TXY, PLA, PLX, PLY, etc. If a register is loaded with zero, the z flag is set and BEQ will work.
Right_Handler:
.a16
.i16
php
A8
lda map_selected
bne @1or2
@0: ;BG1
dec bg1_x
bra @end
@1or2:
cmp #1
bne @2
@1: ;BG2
dec bg2_x
bra @end
@2: ;BG3
dec bg3_x
@end:
plp
rts
Let’s follow this for each value. If map_selected is zero, the BNE won’t branch, it goes to the @0, dec bg1_x and then exits. If map_selected is 1, the first BNE will branch to @1or2. A is still loaded with map_selected, we compare it to #1, the BNE won’t branch, so we do @1, dec bg2_x and exit. If map_selected is 2, the first BNE branches to @1or2, cmp #1 is false, so the bne @2 branches us to th @2 dec bg3_x line.
Notice, moving the map right means decreasing the horizontal scroll variable. Moving it left means increasing it. Likewise, moving a screen down is decreasing the vertical scroll, and moving it up is increasing it.
Scrolling registers are write twice (8 bit) each. Always write twice. You can actually write to these registers any time, but we want to do it during v-blank so we don’t get any shearing of the background in the middle for 1 frame. Near the top of the game loop, we have jsr set_scroll. Let’s look at set_scroll.
lda bg1_x
sta bg1_scroll_x ;$210d
stz bg1_scroll_x
lda bg1_y
sta bg1_scroll_y ;$210e
stz bg1_scroll_y
lda bg2_x
sta bg2_scroll_x ;$210f
stz bg2_scroll_x
lda bg2_y
sta bg2_scroll_y ;$2110
stz bg2_scroll_y
lda bg3_x
sta bg3_scroll_x ;$2111
stz bg3_scroll_x
lda bg3_y
sta bg3_scroll_y ;$2112
stz bg3_scroll_y
bg1_x is a 1 byte variable, because our maps are set to 1 screen only (32×32 map and 8×8 tiles). If you made the tilemap bigger (or made the tile size larger), you would need 2 bytes for each scroll variable. With 64×32 our x needs 9 bits. If you also increase tilesize to 16×16 then we need 10 bits.
You can move each layer independently. Usually, you would have BG1 be the foreground and BG2 be the background and BG3 be either the far background or the HUD (scoreboard) always fixed in one place in the front.
I made a simple Pong demo to show sprite collisions.
Well… I was trying to keep it simple, but I decided to use some of the more complicated code I have previously written. Copied to the library.asm file from some of the EasySNES files. oam_spr (copies one sprite to the buffer), oam_meta_spr (copies multiple sprites to the buffer), oam_clear (clears the buffer), map_offset (gets an address from a specific x/y coordinate in a map). I did change the return from these functions from RTL to RTS, because all of our code is in the same bank.
These functions are complex, and you don’t really need to understand them right now. Just focus on the sprite collision code and drawing numbers to the scoreboard.
check_collision is new. I will discuss that a bit later.
Let’s talk about the process of making this. I made a circle gradient in GIMP for the background, and converted to indexed 4 color (with dithering). Sized 256×192 (it won’t cover the entire screen).
Saved as uncompressed PNG. Converted to .chr .map .pal with superfamiconv. Loaded the background in M1TE (my tile/map editor).
Then I drew some numbers for BG3, and filled a little on the top and bottom.
Clicked the priority checkbox for this map.
Saved all the maps and tiles and palette. Pretty much the same as previous examples of loading a background.
Now I opened SPEZ (my sprite editor) and drew some simple box shapes for the ball and paddle. Saved them as metasprites.asm and saved their tiles (chr) and palette.
Everything is .incbin -ed in the main.asm file. We are loading everything just like the previous examples, with DMAs to the VRAM. One difference is that I wrote a macro for DMAs to the VRAM. This made the code a little easier to read and write. Let’s look at an example…
DMA_VRAM $700, Map1, $6000
This is the DMA_VRAM macro definition…
.macro DMA_VRAM length, src_addr, dst_addr
;dst is address in the VRAM
;a should be 8 bit, xy should be 16 bit
ldx #dst_addr
stx vram_addr
lda #1
sta $4300 ; transfer mode, 2 registers 1 write
; $2118 and $2119 are a pair Low/High
lda #$18 ; $2118
sta $4301 ; destination, vram data
ldx #.loword(src_addr)
stx $4302 ; source
lda #^src_addr
sta $4304 ; bank
ldx #length
stx $4305 ; length
lda #1
sta $420b ; start dma, channel 0
.endmacro
So where it says length, the macro will insert the $700 bytes (not $800, because the screen is only 224 pixels high, so I’m not filling the entire 256 pixel high map). Where it says src_addr, it replaces it with Map1. Where it says dst_addr, it replaces it with VRAM address $6000. All that code could be written in one line.
DMA_VRAM $700, Map1, $6000
Doesn’t this look nicer though? Simple. Elegant. Easy to read. Macros are your friends.
Everything between InfiniteLoop and line 426 jmp InfiniteLoop is the game loop. Every frame we wait till v-blank. Copy the OAM_BUFFER to the OAM. Print the score to the top of the screen. Read the controllers. Move the paddles if up or down are pressed.
lda pad1
and #KEY_UP
beq @not_up
@up:
A8
lda paddle1_y
cmp #$20 ;max up
beq @not_up ;too far up
bcc @not_up
dec paddle1_y
dec paddle1_y
dec paddle2_y
dec paddle2_y
@not_up:
This code is moving both paddles, because this is just example code. You could modify it, so that controller2 moves the paddle on the right. Copy this whole thing, and replace pad1 with pad2, and only move paddle2. Also change the label names, so you don’t have duplicates.
We are only moving the ball while it is “active”. Press START to make it active, and choose a random direction to go (based on a frame counter).
lda #1
sta ball_active
ball_x_speed and ball_y_speed are the directions of the ball. Either 1 or -1 ($ff). Every frame we are adding the speed variable to the position variable. If speed is 1, we add 1 and it moves it to the right 1 pixel.
If the ball is active, it moves up/down until it reaches the ceiling or floor.
;bounce off ceilings
cmp #$20
bcs @above20
…
lda #1
sta ball_y_speed
;bounce off floor
lda ball_y
cmp #$c7
bcc @ball_done
…
lda #$ff ; -1
sta ball_y_speed
Sprite Collisions
It moves left/right until it reaches the end of the room. But we want it to bounce off the paddles, so we need to check collisions with hitboxes. I wrote this a long time ago (modified slightly). It’s the check_collision function in the library.asm file.
So we need the dimensions and location of the 4 sides of both boxes. That’s 8 numbers, that I copy to these variables…
obj1x, obj1w, obj1y, obj1h
obj2x, obj2w, obj2y, obj2h
x = left side of sprite object
w = width (minus 1), added to x to get the right side
y = top side of the sprite object
h = height (minus 1) , added to y to get the bottom side
I defined some of these with constants at the top of main.asm
BALL_SIZE = 7
PADDLE_W = 7
PADDLE_H = 47
Of course, the x and y values are changing. Those are defined as variables in the zero page (direct page).
I copy these to the obj1 obj2 stuff, and then call check_collision, which sets the “collision” variable to 0 or 1. If collision is true, we bounce the ball. This collision check is for 8 bit positions only, and assumes that no object goes off the screen at all. The code won’t work right at the very edges of the screen.
Here’s what the collision code is doing, under the hood, in some optimized ASM.
I’m also drawing the sprites each frame. That uses the oam_meta_spr library function to read from a metasprite data set in metasprites.asm. I used SPEZ (my sprite editor tool) to generate this file.
Each sprite needs x, y, tile, attributes (flipping and palette), and size. The byte arrays listed in metasprites.asm provides all that. We just need to give it the starting x and y positions.
So, copy the x to spr_x, and the y to spr_y, and then loading A and X with the address of the metasprite data, and call our function. Remember ^ is for bank number.
A16
lda #.loword(Meta_00) ;left paddle
ldx #^Meta_00
jsr oam_meta_spr
And this will automatically put all the data in the OAM_BUFFER at the correct x and y positions. It also adjusts the high table bit shifting and keeps track of exactly how many sprites have been added (sprid).
*spr_x is 9 bits (uses 2 bytes). If the sprite never leaves the screen, just leave the upper byte of spr_x as zero. If you pass it more than 9 bits, it will ignore the extra bits.
The ball uses another function, oam_spr. This is for putting 1 sprite in the OAM BUFFER. You have to provide all the details of the sprite. Pass the x (9 bits) to spr_x, the y to spr_y, the tile # to spr_c, the attributes to spr_a, and set the size with spr_sz. spr_sz needs to be either 0 (small) or 2 (large). Then jsr oam_spr.
The metasprite function is actually easier to use, so you may choose to just use that every time. You just need to make a byte array of each sprite object.
Writing to the background
The print_score function always runs during v-blank. It has to, because it is writing to the VRAM. I’m using this map_offset function (in library.asm). It wants you to load X with the tile’s x position 0-31 and load Y with the tile’s y position 0-31. If you only have pixel X and Y, just shift right (lsr a) 3 times to get the 0-255 value to 0-31 (tile) for 8×8 tiles.
map_offset does some bit shifting to convert that to a VRAM address. It returns A16 = the offset. You add that to the base address (our BG3 map is at $7000).
and then copying 2 values per number on screen. We are writing with the VRAM increment set to +32. That means that the second write will go below the first one.
lda #V_INC_32
sta vram_inc ;$2115
Some of these values might be hard to understand, like, why are we adding $10 to the points_L? Our tiles for numbers begins at $10. 0 is at $10. 1 is at $11, etc. Anyway, here’s our finished program. Press START to get it going.
.
Try to make this into a game by having controller 2 to move the right paddle.
The ball is a bit slow, though. Moving 2 pixels per frame might be too fast. It would be best to use “fixed point” math, that’s a 16-bit variable for ball speed and position, where the upper byte refers to a pixel position, and the lower byte is a sub-pixel position (and speed). Then we could have 1 1/2 pixel per frame movement.
I wish we had some sound effects too. Maybe a little later for that.