News:

11 March 2016 - Forum Rules

Main Menu

Q Boy (NES) Level Editor

Started by dekutony, March 07, 2015, 07:35:12 PM

Previous topic - Next topic

dekutony

I love me some Q Boy, by far the best bootleg game I've played. I'm curious though if it is possible to make more levels in the game to make a better experience.
A level editor for this game could be awesome since it has lots of things to work with. I could also check how to make new music for it too. If anyone else is interested, please let me know.  :D

dekutony

Ok, so I really want to start hacking this game... but I'm a noob and I don't even know where to start. Any help on where to start?

Quick Curly

Warning: This is basically just a decent sized data dump. It might seem overwhelming, and it's far from complete, but it's pretty much just a starting point.

There are 2 different versions of the game out there, excluding a UNF file (as opposed to the usual NES file) - I'm not referring to the UNF file at all - so you'll want to find out which one you have first. There are only 4 bytes different between the 2 Q Boy NES ROMs, but 2 of those byte differences are the NES ROM header bytes for the mapper, strangely enough.

Here are the checksums for the 2 different versions.

Q Boy (Asia) (Unl).nes
----------------------
Uses iNES Mapper #141

Checksums:

CRC-16: F93D
CRC-32: 2E12DA89
SHA-1: 03FBC7ED364FEA9B852FEA0800B8BEB2118154D4
SHA-256: 26F2A9912F533B54A684E53FB254598B66704B8BFD09F7631F0E006622D4ACFA
MD-5: 6E48F9D93443B8247337F043A5888520


Q Boy (Sachen) [!].nes
----------------------
Uses iNES Mapper #191

Checksums:

CRC-16: 18B1
CRC-32: AEE6CD20
SHA-1: ED559A03D03B6C8812E359600979C1AE173D86DF
SHA-256: D8BBA179F0D7CD5F6D7A4EEE7C1E8221F684DE0AC5BC6F2A2B366556B7F33E76
MD-5: E408B4A1918F799DCB3D9AD1ED884E41


To find the checksums for your ROM, you can download the HxD hex editor, a pretty handy utility.
In the HxD hex editor, open your ROM file, and under the Analysis menu, select Checksums.
Under "Available algorithms", highlight all the checksums that you want to display. Hold down the left CTRL key to make single selections, or hold down the right SHIFT key to select a range. Select OK. The checksums that you selected will now be displayed.

Knowing the information about the original ROM that you choose to edit is important because people who download your patch to play your hack will need to know the specific ROM to apply it to in order to be able to play your hack. This might seem like it's way too early to be worried about, but come your project's hopeful completion, you might not remember what your original ROM was if you ever even knew.

Sometimes different ROM versions have data and code at different locations in the ROM. However, aside from those 4 different bytes, everything else between the 2 versions is the same, so thankfully any relevant data findings should be the same for whichever version you have.


Hopefully the following findings are generally enough to help you get started with having a better idea of where to look in the ROM for specific variables. Again, I repeat, this is not complete or thorough. I wasn't able to define everything specifically either, mainly with most components of the level data. However, the locations are documented.

Anyone else who is able to further help provide further details, please do!


The following data findings are from using the "Q Boy (Asia) (Unl).nes" ROM.
I used the FCEUX emulator.
-------------------------------------------------------------------------------
0x0824E-0x08275 (0x028) - Pointers for level stuff...

0x0824E-0x0824F (0x002) - BA 83 = $83BA (0x083CA) - Stage 1-1
-------------------------------------------------------------------------------
0x08276-0x0829D (0x028) - Pointers for palette definitions

0x08276-0x08277 (0x002) - 0A 84 = $840A (0x0841A) - Stage 1-1
-------------------------------------------------------------------------------
0x0829E-0x082C5 (0x028) - Pointers for stage TSA

0x0829E-0x0829F (0x002) - 21 9B = $9B21 (0x09B31) - Stage 1-1
0x082A0-0x082A1 (0x002) - 95 9C = $9C95 (0x09CA5) - Stage 1-2
0x082A2-0x082A3 (0x002) - 1D 9D = $9D1D (0x09D2D) - Stage 1-3
0x082A4-0x082A5 (0x002) - 45 9E = $9E45 (0x09E55) - Stage 1-4
-------------------------------------------------------------------------------
0x082C6-0x082ED (0x028) - Pointers for level stuff...

0x082C6-0x082C7 (0x002) - C6 85 = $85C6 (0x085D6) - Stage 1-1
-------------------------------------------------------------------------------
0x082EE-0x08315 (0x028) - Pointers for level stuff...

0x082EE-0x082EF (0x002) - CE 85 = $85CE (0x085DE) - Stage 1-1
-------------------------------------------------------------------------------
0x08316-0x0833D (0x028) - Pointers for object data

0x08316-0x08317 (0x002) - E0 85 = $85E0 (0x085F0) - Stage 1-1
-------------------------------------------------------------------------------
0x0833E-0x08351 (0x014) - How many bytes for length of data relevant to next two sets of pointers...

0x0833E (0x001) - 03 - Stage 1-1
0x0833F (0x001) - 01 - Stage 1-2
0x08340 (0x001) - 04 - Stage 1-3
0x08341 (0x001) - 04 - Stage 1-4
-------------------------------------------------------------------------------
0x08352-0x08379 (0x028) - Pointers for level stuff...

0x08352-0x08353 (0x002) - 32 89 = $8932 (0x08942) - Stage 1-1
-------------------------------------------------------------------------------
0x0837A-0x083A1 (0x028) - Pointers for level stuff...

0x0837A-0x0837B (0x002) - 35 89 = $8935 (0x08945) - Stage 1-1
-------------------------------------------------------------------------------
0x083A2-0x083C9 (0x028) - Pointers for level stuff...

0x083A2-0x083A3 (0x002) - D5 89 = $89D5 (0x089E5) - Stage 1-1
-------------------------------------------------------------------------------
0x083CA-0x08419 (0x050) - Stage 1-1
0x0841A-0x085D5 (0x1BC) - Stage 1-1 palette definitions
0x085D6-0x085DD (0x008) - Stage 1-1
0x085DE-0x085EF (0x012) - Stage 1-1
0x085F0-0x08941 (0x352) - Stage 1-1 object data
0x08942-0x08944 (0x003) - Stage 1-1
0x08945-0x089E4 (0x0A0) - Stage 1-1
0x089E5-0x08A41 (0x05D) - Stage 1-1
0x09B31-0x09CA4 (0x174) - Stage 1-1 TSA
-------------------------------------------------------------------------------
0x1002E-0x101FD (0x1D0) - Title screen
0x106D3-0x106F2 (0x020) - Title screen palettes (0E for black instead of 0F - oh boy!)
0x106F3-0x10A12 (0x320) - Other palettes, including for stages
-------------------------------------------------------------------------------
0x10D46-0x10D59 (0x014) - Number of bytes for items + 01

0x10D46 (0x001) - 2D - Stage 1-1
0x10D47 (0x001) - 29 - Stage 1-2
0x10D48 (0x001) - 19 - Stage 1-3
0x10D49 (0x001) - 1C - Stage 1-4
-------------------------------------------------------------------------------
0x10D5A-0x10D81 (0x028) - Pointers for Y-coordinates of items

0x10D5A-0x10D5A (0x002) - C2 8D = $8DC2 (0x10DD2)
-------------------------------------------------------------------------------
0x10D82-0x10DA9 (0x028) - Pointers for item types (stars, Q blocks, etc.)

0x10D82-0x10D83 (0x002) - FC 8E = $8EFC (0x10F0C)
-------------------------------------------------------------------------------
0x10DAA-0x10DD1 (0x028) - Pointers for X-coordinates of items

0x10DAA-0x10DAB (0x002) - 35 90 = $9035 (0x11045)
-------------------------------------------------------------------------------
0x10DD2-0x10DFD (0x02C) - Stage 1-1 Items (Y-coordinates)
0x10F0C-0x10F37 (0x02C) - Stage 1-1 Items (Types)
0x11045-0x11070 (0x02C) - Stage 1-1 Items (X-coordinates)
-------------------------------------------------------------------------------
0x11188-0x1119B (0x014) - Number of bytes for enemies

0x11188 (0x001) - 17 - Stage 1-1
0x11189 (0x001) - 20 - Stage 1-2
0x1118A (0x001) - 2F - Stage 1-3
0x1118B (0x001) - 25 - Stage 1-4
0x1118C (0x001) - 23 - Stage 2-1
0x1118D (0x001) - 23 - Stage 2-2
0x1118E (0x001) - 22 - Stage 2-3
0x1118F (0x001) - 14 - Stage 2-4
0x11190 (0x001) - 1E - Stage 3-1
0x11191 (0x001) - 22 - Stage 3-2
0x11192 (0x001) - 1E - Stage 3-3
0x11193 (0x001) - 22 - Stage 3-4
0x11194 (0x001) - 17 - Stage 4-1
0x11195 (0x001) - 14 - Stage 4-2
0x11196 (0x001) - 15 - Stage 4-3
0x11197 (0x001) - 00 - Stage 4-4
0x11198 (0x001) - 11 - Stage 5-1
0x11199 (0x001) - 0D - Stage 5-2
0x1119A (0x001) - 08 - Stage 5-3
0x1119B (0x001) - 0E - Stage 5-4
-------------------------------------------------------------------------------
0x1119C-0x111C3 (0x028) - Pointers for Y-coordinates of enemies

0x1119C-0x1119D (0x002) - 32 92 = $9232 (0x11242)
0x1119E-0x1119F (0x002) - 49 92 = $9249 (0x11259)
0x111A0-0x111A1 (0x002) - A9 92 = $92A9 (0x112B9)
0x111A2-0x111A3 (0x002) - 36 93 = $9336 (0x11346)
-------------------------------------------------------------------------------
0x111C4-0x111EB (0x028) - Pointers for enemy types

0x111C4-0x111C5 (0x002) - 1B 92 = $921B (0x1122B)
0x111C6-0x111C7 (0x002) - 69 92 = $9269 (0x11279)
0x111C8-0x111C9 (0x002) - D8 92 = $92D8 (0x112E8)
0x111CA-0x111CB (0x002) - 5B 93 = $935B (0x1136B)
-------------------------------------------------------------------------------
0x111EC-0x11213 (0x028) - Pointers for X-coordinates of enemies

0x111EC-0x111ED (0x002) - 04 92 = $9204 (0x11214)
0x111EE-0x111EF (0x002) - 89 92 = $9289 (0x11299)
0x111F0-0x111F1 (0x002) - 07 93 = $9307 (0x11317)
0x111F2-0x111F3 (0x002) - 80 93 = $9380 (0x11390)
-------------------------------------------------------------------------------
0x11214-0x1122A (0x017) - Stage 1-1 Enemies (X-coordinates)
0x1122B-0x11241 (0x017) - Stage 1-1 Enemies (Types)
0x11242-0x11258 (0x017) - Stage 1-1 Enemies (Y-coordinates)
-------------------------------------------------------------------------------
0x11259-0x11278 (0x020) - Stage 1-2 Enemies (Y-coordinates)
0x11279-0x11298 (0x020) - Stage 1-2 Enemies (Types)
0x11299-0x112B8 (0x020) - Stage 1-2 Enemies (X-coordinates)
-------------------------------------------------------------------------------
0x112B9-0x112E7 (0x02F) - Stage 1-3 Enemies (Y-coordinates)
0x112E8-0x11316 (0x02F) - Stage 1-3 Enemies (Types)
0x11317-0x11345 (0x02F) - Stage 1-3 Enemies (X-coordinates)
-------------------------------------------------------------------------------
0x11346-0x1136A (0x025) - Stage 1-4 Enemies (Y-coordinates)
0x1136B-0x1138F (0x025) - Stage 1-4 Enemies (Types)
0x11390-0x113B4 (0x025) - Stage 1-4 Enemies (X-coordinates)
-------------------------------------------------------------------------------
Stage 1-1 TSA

Generally, the TSA for the graphics that make up the objects seems to be ordered as the blocks appear in the stage.

1st byte: Top-left corner tile
2nd byte: Top-right corner tile
3rd byte: Bottom-left corner tile
4th byte: Bottom-right corner tile

0x09B31-0x09B34 (01 01 01 01) - 00: Empty sky
0x09B35-0x09B38 (01 10 0E 0F) - 01: Part of large background hill
0x09B39-0x09B3C (08 09 0A 0B) - 02: Trees
0x09B3D-0x09B40 (0C 0D 06 07) - 03: Bushes
0x09B41-0x09B44 (02 03 04 05) - 04: Ground
0x09B45-0x09B48 (21 22 25 26) - 05: Left half of cloud
0x09B49-0x09B4C (01 01 01 13) - 06: Part of large background hill
0x09B4D-0x09B50 (11 12 1B 1B) - 07: Part of large background hill
0x09B51-0x09B54 (23 24 27 28) - 08: Right half of cloud
0x09B55-0x09B58 (01 01 14 15) - 09: Top part of large background hill
0x09B59-0x09B5C (1B 16 1B 1B) - 0A: Part of large background hill
0x09B5D-0x09B60 (17 18 1B 19) - 0B: Part of large background hill
0x09B61-0x09B64 (4A 4B 55 77) - 0C: Bottom part of background platform sticking out of ground
0x09B65-0x09B68 (01 01 21 22) - 0D: Sky and top-left quarter of cloud
0x09B69-0x09B6C (25 26 01 01) - 0E: Sky and bottom-left quarter of cloud
0x09B6D-0x09B70 (01 01 1A 1C) - 0F: Part of small background hill
0x09B71-0x09B74 (01 01 23 24) - 10: Sky and top-right quarter of cloud
0x09B75-0x09B78 (27 28 01 01) - 11: Sky and bottom-right quarter of cloud
0x09B79-0x09B7C (4A 4B 4A 4B) - 12: Upper layers of background platform sticking out of ground
0x09B7D-0x09B80 (29 2A 2B 2C) - 13: Top part of log
0x09B81-0x09B84 (2B 2C 2B 2C) - 14: Middle layers of log
0x09B85-0x09B88 (2F 2C 2B 2C) - 15: Section of log with hole
0x09B89-0x09B8C (01 01 FF 01) - 16: Right side shadow of top of log
0x09B8D-0x09B90 (FF 01 FF 01) - 17: Right side shadow of log
0x09B91-0x09B94 (FF 01 FF 1C) - 18: Right side shadow of log by small background hill
0x09B95-0x09B98 (FF 09 FF 0B) - 19: Right side shadow of log by trees
0x09B99-0x09B9C (FF 0D FF 07) - 1A: Right side shadow of log by bushes
Etc.
0x09CA1-0x09CA4 (56 57 58 59) - 5C: Background wall at end of stage
-------------------------------------------------------------------------------
Items (Stars, Q Blocks, Etc.)

Types
-----
00: Star
01: Heart
02: Life
03: P Icon
04: Shield
05: Q block

Y-coordinates should be between values of 00-AF. If higher, they appear within bottom status bar.
-------------------------------------------------------------------------------
Enemies

Some values seem to produce glitchy versions of enemies. The stage seems to make a difference in enemy graphics.

Types - Stage 1-1
-----------------
00: Nothing
01: Little Purple/Koopa
02: Fox
03: Speedy Purple/Buzzy Beetle
04: Orange Rolling Ball/Black Spiny
05: Purple Block

Types - Stage 1-2
-----------------
00: Nothing
01: Little Purple/Koopa
02: Fox
03: Speedy Purple/Buzzy Beetle
04: Orange Rolling Ball/Black Spiny
05: Little Red Dinosaur/Red Goomba
06: Purple Block
-------------------------------------------------------------------------------

That's all that I found and documented for now. This seems like a pretty neat game, and the "Mario Mode" easter egg is very cool!
I hope that you're able to find this post useful and can figure out things from here. Best of luck! :)
As for any other things that you're uncertain about, it's helpful when you ask specific questions about what you're looking for and/or what you aim to do, and hopefully someone knowledgeable and capable will take their time to help you out.
I realize that this topic is already over 4 months old, but I do hope that you'll be able to find other help and have success with this. However, it's much more difficult to pursue a hacking project when there is not much documentation on a game.

M-Tee

Boss move, QC. I love Q-Boy. Will be rad if something comes of this.

dougeff

#4
Great work Quick Curly. Hey, what's your methodology for figuring this stuff out, I wonder?

I use FCEUX. I like to play the game with the code/data log running, start it at the point where it loads data, stop it. Review it. Then create a save state just before new level info is loaded, then load the save state over and over and watch the zeropage ram, indirect addresses (ie pointers) use the zero page. Then write down addresses I think are useful. Open the hex editor, look at the ROM, go to the address, and start changing numbers at that address (use similar ones to the ones there), then reload the save state, and see if things changed during the loading. If not, try the next data set, etc.
Alternatively, you can open the name table viewer, and write down the tile numbers of specific tiles on the screen, and search the ROM for those numbers. Change the number, reload the save state from just before it loaded the level, and see if it changed.

July 22, 2015, 08:42:42 PM - (Auto Merged - Double Posts are not allowed before 7 days.)

Then the process is working backwards until you find the data set. If the corner tile is $54, set a breakpoint in debugger for writes to 2007, with condition A==#54. Use that and figure out where it's loading A from, probably a buffer in the RAM. Then set a new breakpoint for writes to that RAM buffer, with condition A==#54. Break. Scroll up to see where its loading A from, etc.
nesdoug.com -- blog/tutorial on programming for the NES

Quick Curly

Quote from: M-Tee on July 22, 2015, 08:19:29 AM
Boss move, QC. I love Q-Boy. Will be rad if something comes of this.
Thank you, M-Tee. :) It's encouraging when discovered information proves to be useful. I messaged the topic creator to let them know that I made the post in hopes that they receive a notification about it, and if they require more help, they'll be able to ask for it, knowing that there is at least something more to go on now compared to months ago.

However, unfortunately, I only invested so much time that day in documenting what I did find, and I wasn't able to specifically define all of the multiple level variables and their purposes. The only thought that I've had since I made that post is whether or not one of those components could potentially be a repeating background that the game draws every certain section, similar to how Super Mario Bros. was said to in some documentation that I read somewhere years ago, if I remember correctly (maybe not). Although, it's just a random thought, and probably not the case. I haven't bothered to check, and honestly, I probably won't, unless a reason comes along to attempt to look and study further.

Quote from: dougeff on July 22, 2015, 07:41:40 PM
Great work Quick Curly. Hey, what's your methodology for figuring this stuff out, I wonder?
Thank you, Doug. :)

Pretty much what I've always done when exploring something new is use a combination of most of the built-in tools of FCEUXD, and in the case of this game, FCEUX, since FCEUXD doesn't emulate the mappers used by Q Boy correctly. However, I tend to use FCEUXD over FCEUX simply to avoid those DEB files from being created after using the tools in FCEUX, which seems silly, but generally I've been able to do what I want/need to do with FCEUXD. However, while using the Debugger, conditional breakpoints work in FCEUX, so if I need the option, then I'll act accordingly.

As for logging bytes as opposed to referring to the stack to find all the roots of code flow and sources of potential variables, generally, thorough tests with the Code/Data Logger tend to ultimately work for me. I'll seek out groups of data that seem to fit what I feel I'm looking for, and will test for successful changes accordingly.

Pretty much, we all have our methods that work for us, and there are methods that work more effectively in different situations.
However, these game searches are all possible thanks to the handy, multiple purpose utilities that we use. Really, my recent data dumps are nothing compared to the dedicated efforts of the master programmers whose work we all benefit from everyday. :)

dekutony

Wow... Thanks for all that data man, I really really appreciate it!!!  :D
You know, this can be useful for a level editor, but ALSO for certain other things like TASing and such. I hope we can collab to make an awesome hack one day.  :thumbsup:

Quick Curly

You're welcome. :) It's interesting to look at how different games work when I have the time.
The information there is far from complete, but it's a starting point.
If you have anymore questions, please feel free to post them here, and I or someone else will hopefully help figure out any information that we possibly can.
Do you have any specific ideas for new levels and the direction that you would want to take a potential hack?

dekutony

Quote from: Quick Curly on August 16, 2015, 01:30:09 PM
Do you have any specific ideas for new levels and the direction that you would want to take a potential hack?

Actually, now that you ask...
I would want to make longer levels that fits in with the controls and the character's abilities, like vertical scrolling and more warps like Stage 4-4 from the original game. Also making a more understandable plot and expand the original to it's fullest one would be very cool.

Thanks again for the help!  :)

dekutony

So I had a bit of an idea with this, but I don't know if this is possible or not.
I've been wondering for a while if a hack that replaced the current mappers of the game to a more common mapper (like MMC3 for example), could be possible, since the mappers are based on the original MMC3/they're clones.
Why? Well, to make the game more compatible on other emulators of course, like Rocknes or Nintendo's Virtual Console on the Wii/Wii U/3DS.
I've seen mapper hacks on this site before so I think it's not THAT insane of an idea... I think.

Googie

I gave this game a shot and I really like it, I'd love to see a level editor for this game.  :thumbsup: