Points of Required Attention™
Please chime in on a proposed restructuring of the ROM hacking sections.
Views: 88,438,650
Main | FAQ | Uploader | IRC chat | Radio | Memberlist | Active users | Latest posts | Calendar | Stats | Online users | Search 04-19-24 09:07 PM
Guest: Register | Login

0 users currently in ROM Hacking | 4 guests | 1 bot

Main - ROM Hacking - Mega Man IV SNES/MSU-1 by infidelity New thread | New reply


infidelity
Posted on 08-22-21 11:11 PM (rev. 6 of 12-15-21 10:38 PM) Link | Quote | ID: 167790


Fuzz Ball
Level: 66

Posts: 967/968
EXP: 2366794
Next: 95057

Since: 05-24-07

Last post: 952 days
Last view: 808 days
Soooo, i've been busy since February 2021. The following 6 months I began working on my very first port of a game, from the NES to the SNES. Cover art concept by @TheJohnPerry via Twitter.

Mega-Man-IV-SNES

2015
Back in 2015 I started feeling the itch to begin working on the SNES, after my 2 MMC5 projects I had previously finished. The only debugger that I knew of then, was called bsnes but I didn't like the memory viewer's state it was in (and still is in), where you cant refresh what is currently being read as code/data, and what no longer is. I made a couple requests here and there to the one who was in charge of the debugger, but they were never accepted. So i pushed off the idea working on the SNES, and started doing other NES projects, and doing upkeep on my other releases.

2018
In 2018, I started getting the SNES coding itch again, i went to snesdev and began asking questions about the differences from SNES to NES. A member by the name of koitsu, was gracious enough to show me the ropes of how to work the CGRAM, and also taught me how to convert NES colors to SNES colors (8-bit to 16-bit), here is my very first attempt back in 2018 showing my manual edits within bsnes.

helloworld

But, again I was put off from the bsnes debugger, and i went back to NES.

Then 2020 happened...

Yeah.

2020
I was laid off for 2 months during the pandemic, during that free time I began working on a new massive MMC5 project. This was going to be my "Goodbye, NES" project. This will probably never see the light of day, I say that because it was in a theoretical state from a hardware perspective, i was working on a new rom hack that would utilize 1024kb/1mb of SRAM. I contacted zeromus who deals with the source code of FCEUX, and had him show me how to manually edit the source files, so that I could get my theoretical idea working via emulation. Ben Boldt was even going to assist with the hardware as well. I spent those 2 months working on my idea, I got everything working, but then never implemented the GUI I was going to have in the romhack, but I got sidetracked towards the end with different things, and I never got to the GUI, and started getting glitched results from pushing the code/machine further than it could go. Maybe one day I'll release it purely for pc emulation, it was a cool idea imo.

2020 - 2021
Throughout the latter half of 2020 I started getting the itch again for SNES coding. After losing motivation from my failed MMC5 release, i decided to make the leap. Early in 2021 I began asking questions again on snesdev, seeking any and all information on how the SNES operates. I started compiling notes on how the NES operates, and how that would apply to the SNES.

Where do I begin?
SNES rom hacking, from the outside looking in, always scared me, because there is so much involved when hacking any of the great games for that system. When I do these projects, I have in the past, it has to be something that stops me in my tracks, and intrigues me, haunts me, makes the hair on my arms stand on end. I've always wanted to do a port, but was to afraid to. I started looking up ports of NES games to the SNES, and I saw one of Super Mario Bros., using SMAS soundtrack, i thought it was the coolest thing. But the ports i've been finding were alot of NROM games, games that don't do bankswitching, games that only have CHR-RAM. And when it comes to doing projects, I like to do things that haven't been done, that are challenging. So I decided to go with the MMC3/Mapper 004, since that mapper is the one i've modified and worked on the most.

Thus the super port Mega Man IV was born
When considering a port, it was ALWAYS going to be a Mega Man game. It was a toss-up between Mega Man 3 & Mega Man 4. I decided on 4 because of these factors.

1: MM4 use CHR-RAM & the SNES only does CHR-RAM, so i didn't want to do anything major with ROM to RAM conversions with gfx.

2: I knew I'd be implementing MSU-1, and my favorite Complete Works soundtrack is from Rockman 4

3: I've worked with MM4 before, when I was working on Megaman Ultra 2 - The Rise of X. Matrixz created the MEGAMAN 4 COMPREHENSIVE DOCUMENT, and I used that as a guide for when things went wrong in the porting process, that was crucial in helping me.

Let's do this!
The members at snesdev really helped me understand how things are supposed to operate in the SNES. I presented to them a list of my NES to SNES equivalents, and I was pretty much on the mark, some were off and I was told what those incorrect ones were. I kept my idea of which game I was working on a secret, because I knew this was going to be something special, and I wanted this to be a surprise at the very end. So I kept saying that what I was working on was, an MMC3 title.

Vertical scrolling
I was warned that there were going to be issues that would pop up, since the way the screen is drawn on the NES & SNES are different. The NES draws 30 tiles top to bottom on 1 nametable, but the SNES draws 32 tiles top to bottom on 1 tilemap, aka, like the SNES version of an NES nametable.

What that meant, was that my vertical portions of the screens would not be seamless during a vertical scroll transition, they won't look connected. So I was told very early on that I would need to implement HDMA, to pull off the look of the 2 separated tilemaps, look connected.

Here are 2 video examples of how my vertical scrolls looked before HDMA, and after I implemented HDMA.

https://youtu.be/tA8rsIFIq14
https://youtu.be/sKB1y1GCWs0

30 vertical tiles, vs 32 vertical tiles
The NES doesn't display the very top of the Nametable during gameplay. For those that don't know the ppu of the NES, the top of the nametable that is currently displayed is 20/24/28/2C00_ppu, but you typically only see from 20/24/28/2C20. That means the top 8x8 pixels are off screen. But, the SNES does display the very top of the tilemap during gameplay. I was told to combat this, I would need to use a feature called offset per column, which is used in Yoshi's Island. I was able to do this, raising the entire screen up 8 pixels, but then came the issue of rearranging every single sprite position in the entire game. I was creating a routine before my NMI would exit, that would adjust all my sprite dma's Y positions by a decrement of 08, but this proved to be an issue with sprite positions that were NOT consistantlly written to the buffer, so those sprites would just continuously move vertically, so i decided to keep everything the way it was. Here are 2 examples of how the game looks on the NES, and the SNES. I used Drill Man's stage as a perfect example.

nes-height

snes-height

The sound engine
My original idea was to use the sound engine from Mega Man X, since it's very similar to the Capcom 6C80 sound engine Mega Man IV uses. I was going to convert the BGM & SFX, but then I found out about someone called Memblers, who created a 2A03 sound emulator for the SNES, where you could listen to the NES 8-bit music on the SNES. Back at snesdev, a member by the name of Myself086, taught me how to upload Membler's 2A03 sound emulator, into the SPC700 of the SNES, and then showed me where I could find Membler's source code, and even shared some of his source code, and I wrote from the source files in hex. The triangle (bass) output in my port is horrifically low, idk if this is from my doing/missing something, but I haven't been able to get this figured out. The notes register when viewing a sound viewer in emulators, it's just the actual volume output is low to non existent.

IRQ/split screens
This wasn't as bad as I was originally fearing, but still took some tweaking with different values for various split screens. If you pay close attention to various split screen sections from the original game, you'll notice sometimes the entire floor will rise up a bit. My port, I made sure that wouldn't happen on the NES. There are some instances where I did have to keep the appearance of a singular scanline missing from the irq splits, this was needed for actual hardware. When I coded this in bsnes, I made it so no scanlines were missing, no tears were present. But when it came time to test on an actual SNES, I got bad tears in places, just like you would get with an MMC3 irq on the NES. So I had to modify every single IRQ to adjust their tearing on screen, it's a trick that kuja killer taught me many many years ago, and it's so cool that it can be applied to the SNES too.

Sprites
I had to convert the way the original sprites are stored into OAM, so that they would appear correctly in the SNES's OAM. Palette attributes in NES go from 00,01,02,03. But for the SNES graphical mode i was working in, palette attributes for sprites go from 00,02,04,06. And for sprites to have priority over a BG tile, you need to take that previous palette attribute byte, and add 30 to it so that those sprites are front and center, so the 00,02,04,06 would look like 30,32,34,36. NOW, I had to include sub routines to take into account when Mega Man or other sprites were behind BG tiles, like in Pharaoah Man's stage with the quicksand, so I had to find out how the original game handled that, and then implement my exceptions to it, to further modify the sprite attribute byte.

CHR-RAM
Another first for me. Those that know my projects, know that I loooooooooove CHR-ROM. But there was nothing I could do about that, so I studied how Mega Man 4 handled it's CHR-RAM uploads to the ppu. Before any of that, I used YY-CHR- to convert the gfx from 2bpp to 4bpp, and stored them as far back towards the end of the rom file I was working on as I could. What I should have done, was keep the gfx together the same way as they were in the original game, cause this would've been soooo much easier for me to implement a universal routine to find the correct addresses for all the gfx to load. But since I kind of scattered the latter half of the gfx to a tiny degree, I had to manually edit every single CHR-RAM data string that gets called, so that it would get to it's correct destination for loading.

CGRAM
This was pretty easy, I took my converted table of NES to SNES palettes, and injected them into CGRAM via the SNES'S DMA. In Mega Man IV, the game stores it's palettes in 2 buffered sections in ram, $600-$61F & $620-$63F. When it came time for the game to read from those buffers to get the colors to the nes ppu, I created a routine where it would load the currently loaded NES palette color, use that as a Y index to load a pointer table, so that it would get the correct address within my 60 byte cgram palette table, and then I would take that new 16-bit/2 byte value(s) and store them into a new CGRAM buffer table in the snes wram, then I would call that with DMA and store that table directly into CGRAM. So that is how I am using the original games color values ;-)
*for those that wish to graphically modify this game to look 16-bit, i left the correct amount of space for those that wish to do so, you'll need to do some modification to how I load from my 60 byte table, if you know asm, it wont be hard at all to tweak it to how you need it.

32x32 block attribute color byte, vs 8x8 tile attribute color byte
Another thing I needed to figure out, was how Mega Man 4 constructed it's attributes for a 32x32 grid. The original game thankfully already has the correct attribute value ready, when it's drawing an 8x8 tile to the screen for that 16x16 block. The game draws from top to bottom 40 times, every odd number is when the attribute value would get it's bit stored to the byte. Here is a diagram for how the NES reads a singular attribute byte. These are the bit setups for a 16x16 block.

00,01,02,03|00,04,08,0C
-----------------------------
00,10,20,30|00,40,80,C0


Now for the graphical mode I'm using in my port on the SNES, the BG gfx are known as 00,04,08,0C, so what I did was take original value of 00,01,02,03, and use that as a Y index to load a table that has 00,04,08,0C to use that value as the attribute color for the 8x8 tile.

So for my port, I need to break those bytes down to work for 8x8 individual tiles. There are 2 ways that I do this in my port, depending on the amount that i need. If it's a small amount, I simply take the byte I need from an attribute buffer the game uses, and break it down. Let's say the attribute is AA, and let's say I dont need to backup Y.

[code]
example 1, A is AA, and im getting a value for the top left 16x16 block, and the bottom left 16x16 block

48 29F0 2903 A8 B9#### 8D#### 68 290F 4A 4A 4A 4A 2903 A8 B9#### 8D####

example 2, A is AA, and im getting a value for the top right 16x16 block, and the bottom right 16x16 block

48 29F0 8D#### 68 290F 4A 4A 4A 4A 8D####
[\code]

So when the game is drawing from the top down, i have to copy that new attribute twice, since two 8x8 tiles going down is 16, so i made a diagram for myself looking like this.

00,01,02,03|00,04,08,0C
00,01,02,03|00,04,08,0C
-----------------------------
00,10,20,30|00,40,80,C0
00,10,20,30|00,40,80,C0

So I had to set aside a new vram buffer table that uses 16-bits, and i would hijack where the game would send it's tile data to the old vram buffer, to my new vram buffer, and create asm to inject those tiles proper attribute bytes that i obtained. My vram table is located at 7E:0800, and the original table which sometimes still gets stuff sent to it, is at 7E:0780

Progress
Just wanted to show my progression via snapshots of my backup folder

bkup1
bkup2
bkup3
bkup4
bkup5
bkup6
bkup7
bkup8

Googie
Posted on 09-16-21 02:23 AM Link | Quote | ID: 167812


Giant Red Paratroopa
Level: 77

Posts: 1399/1407
EXP: 4178907
Next: 12222

Since: 02-19-07
From: Brooklyn, NY

Last post: 2 days
Last view: 2 days
I'm gonna have to try this out when I get some free time tonight, congrats!

____________________
My Linktree

dreamerman
Posted on 09-19-21 10:50 PM Link | Quote | ID: 167816


Red Paragoomba
Level: 18

Posts: 52/52
EXP: 27074
Next: 2823

Since: 01-10-10
From: Santiago

Last post: 942 days
Last view: 942 days
Amazing bro!

I loved.

Any question. Is possible convert MegaMan World (GB) for Nes? Same with Megaman 4 nes for Snes?

Main - ROM Hacking - Mega Man IV SNES/MSU-1 by infidelity New thread | New reply

Acmlmboard 2.1+4δ (2023-01-15)
© 2005-2023 Acmlm, blackhole89, Xkeeper et al.

Page rendered in 0.018 seconds. (351KB of memory used)
MySQL - queries: 47, rows: 70/70, time: 0.014 seconds.