sonicretro / s2disasm Goto Github PK
View Code? Open in Web Editor NEWSonic 2 Disassembly
Sonic 2 Disassembly
A disassembly of Sonic the Hedgehog 2 for the Sega Mega Drive/Genesis. To build this, use build.bat if you're a Windows user, or build.lua otherwise. The built ROM will be called 's2built.bin'. DISCLAIMER: Any and all content presented in this repository is presented for informational and educational purposes only. Commercial usage is expressly prohibited. Sonic Retro claims no ownership of any code in these repositories. You assume any and all responsibility for using this content responsibly. Sonic Retro claims no responsibiliy or warranty.
I am going to make the claim that nameless temporary labels are harmful for every single usage this disassembly may have. These are the +, - and / labels, that are littered around the disassembly, and make reading and maintaining code a horrible experience. Why?
I knew I went on lengths about my severe gripes about the nameless temporaries and my problem with them, but having been tasked to maintain code littered with these devils has truly made me hate their use. Although we can't stop people from actually using it, packaging it in as the de-facto style to do temporary labels within disassemblies is absolutely unreasonable and I really think they should be outright banned from s2disasm and any other Sonic Retro disassemblies. I would even be happier with nonsense like .a, .b, .1, .derp, .asdasdsaasd, because it still retains many of the real world usage benefits mentioned above. Nameless temporary labels fail at every level to make any sense for anything but laziness of the user, and I don't think that should be the direction the disassemblies should take for sheer convenience for the submitter. Please discuss below
Hello, I have been toying around with the KiS2 disassembly and making changes to the code, and I have found an issue related to the fixBugs flag.
When jumping, Knuckles' sprite breaks down the middle, and the right side becomes garbled. I have observed this on original hardware via Mega Everdrive Pro, on clownmdemu, and on lr-genesis-plus-gx. I also have standalone KiS2 enabled for emulator compatibility. Not sure if that's also a cause.
This only appears to happen when fixBugs = 1. Turning it off resolves this issue at the expense of whatever fixes are relevant to KiS2.
Had a guy ask for help for building his hack because he's using a 32bit copy of windows 7 still and i'm not really sure why the tools need to be 64bit in the first place. Maybe include 32bit versions just in case?
I compared Sonic Classics' version of S1 to the usual S1REV00, and I think it's safe to say there are some properties of Classics we can set apart from S2REV02. First up, Classics' S1 has no checksum code, its RAM is arranged differently, and it writes 'SEGA' to FFFFFFE4. The copy of S2 in Classics does all of this, too. I'm thinking of removing these from gameRevision 2, to get as accurate a version of S2REV02 as possible. On a similar note, ErrorTrap is different in Classics:
ErrorTrap:
bra.s ErrorTrap
nop
bra.s ErrorTrap
I don't think this was a part of S2REV02; I'm certain S3 was based on S2REV02 (it has the JmpTos removed), and it uses the old ErrorTrap. Based on that, I'm thinking of giving that one the sack as well.
clearRAM does not check if the end address is actually less than the start address, which can cause negative offsets which end up causing strange issues. This can be a problem for people who wish to rearrange RAM and get unintended strange effects after that. It requires some knowledge and luck to find these kind of issues correctly, as the code is abstracted behind a macro. Should the macro cause an error when the length is negative?
might wanna change some subroutines names in s2 ss stages and label them correctly when it comes to Objoff's thank you
I'd like to get around to this sometime. I think I've already got most of the work out of the way, since KiS2 was based on REV02, which had those massive linker data differences that took forever to add.
On paper, all I should have to do is ORG the 68k code to the right location, strip out the sound driver and art/level files, add Knuckles, and then I can get to the good part of finding whatever neat little changes KiS2 contains.
eori.w #$F,d3
I find it odd that in S1 and S2's version of the routine, the function supposedly fixes erratic collision:
; Engine bug: colliding with left walls is erratic with this function.
; The cause is this: a missing instruction to flip collision on the found
; 16x16 block; this one:
;eori.w #$F,d3
Yet in S&K's version of the routine, the line apparently causes a bug:
eori.w #$F,d3 ; this was not here in S1/S2, resulting in a bug
Is there a reason for this?
So, I have decided to fork this repository into this one. I managed to get AS building on Windows with msys2, and I am thinking of setting up some GitHub actions to make Windows/Linux/OSX builds.
So far, the latest branch required:
message
useless by suppressing its output in quiet mode;I can probably also add some improvements and fixes while I am at it; one thing I was thinking of was a way to toggle the zero-offset optimization on or off. I did a quick test on S2 disassembly, and it would require being able to toggle it in code.
Any thoughts?
The disassembly fails to build if the revision is set to 2 and FixBugs is enabled due to a branch at the start of Sonic_CheckGoSuper being pushed out of range, specifically the first instance of bne.s return_1ABA4. I did come up with a conditional that should fix it:
Sonic_CheckGoSuper:
tst.b (Super_Sonic_flag).w ; is Sonic already Super?
if fixBugs
if gameRevision=2
bne.w return_1ABA4 ; if yes, branch
endif
else
bne.s return_1ABA4 ; if yes, branch
endif
Just leaving this here before I forget: I think it's nice that this disasm is portable, but right now checking bit-perfection isn't. Granted, it's something you can do yourself with a hex editor or any assortment of standard Linux utilities, but still, it's a feature that the disasm only provides for Windows users.
I'm wondering if it's worth making a quick hash-verifying tool. Write it in C/C++, and it can be compiled at run-time just like the other tools, so portability's a non-issue.
A hash checker would remove the need for those pre-built ROMs cluttering the main directory, but it wouldn't give the same feedback as the current chkbitperfect, which shows you each differing byte. On the other hand, in the event the ROM is very different, this quickly becomes a downside since it winds up spamming the console for a good minute or two.
A hash-checker can work more like s1disasm's build.py, comparing the ROM against hashes of each revision and telling you which one it matches, instead of the current system of having one script for each revision, and expecting the user to select the right one.
Thoughts?
Exclusively in the Knuckles in Sonic 2 branch, the file containing the compressed graphics for the title screen's "THE ECHIDNA IN" text also include object layout data for both acts of Casino Night Zone. This is actually referenced by the KiS2 object layout jump table located at $DF370 in the Sonic & Knuckles ROM: $33F06E contains Act 1's data while $33F74C contains Act 2's data.
One thing I've heard people really don't like about this disassembly is all the macros and constants. One area I think this can be streamlined is the revision differences:
In order to get three revisions to build from the same codebase, I've had to add some monsterous macros like jmpto/jsrto and rev02even, and they really clutter the code. Not to mention, they're completely unnatural (the original source code sure as heck didn't need these things).
So, I figure, since I was already planning to give Knuckles in Sonic 2 its own branch when I get around to it, because of its massive number of changes, why not do the same for REV00 and REV02?
Admittedly, the other branches (like MapMacros) would become REV01-only. Still, anyone that knows how to use Git can just merge them themselves.
Should we do a branch for the Sonic 2 protos ?
So, I realised there's a chance Sonic Jam's port of Sonic 2 is based on REV02, so I took a look. Long story short, yes, but it's missing a few things. Namely all the mistakes.
It contains all of the bugfixes that we have for REV02, but it's missing the bugs it supposedly introduced like the broken mirroring on Silver Sonic/Grabber's sprites, not being able to spin dash off the Tornado anymore, and the WFZ conveyor belt letting you walk on air. It's also missing the pointless adjustments to HPZ/OOZ's animated art tables.
Note that all of these bugs were introduced by strange issues with what were probably constants in the original source code. For example, here's the code that causes the sprite mirroring bug:
if gameRevision<2
andi.b #$FC,d0
move.b status(a0),d2
andi.b #$FC,d2
move.b render_flags(a1),d1
andi.b #3,d1
else
; Peculiarly, REV02 changes this to only inherit the Y-flip.
; This causes a bug where some sprites are displayed backwards (Silver Sonic's sparks and Grabber's legs).
andi.b #$FD,d0
move.b status(a0),d2
andi.b #$FD,d2
move.b render_flags(a1),d1
andi.b #2,d1
endif
Here's the one for the Tornado:
if gameRevision<2
andi.b #p1_standing,d0 ; 'on object' bit
andi.b #p1_standing,d1 ; 'on object' bit
else
; 'fixes' the player being able to spin dash off the Tornado
andi.b #1,d0 ; 'X-flipped' bit???
andi.b #1,d1 ; 'X-flipped' bit???
endif
And here's the WFZ platform one:
if gameRevision<2
andi.b #standing_mask,d0
else
; I don't know what this change was meant to do, but it causes
; Sonic to not fall off ObjBD's ascending platforms when they retract,
; making him hover.
andi.b #2,d0 ; 'Y-flipped' bit???
endif
Admittedly, there's a chance the devs just fixed these things, but I'm more convinced Sonic Compilation/Classics introduced these issues. Knuckles in Sonic 2 doesn't have any of these issues either, and that was also based on REV02, but came out before Compilation.
So now I'm considering splitting REV02 into a "real" REV02 build, and a Sonic Compilation build, with those extra changes that I removed.
This is an enhancement idea.
DAC Sample Names should not be named Sample 1, Sample 2, and so on, I think they should be named Either their ID's or Their Sound, So Sample 1 could become Kick, and Sample 2 could become Snare, and so on.
Macros, such as org and org0 break the scope, so referencing a local lable after an even will make assembly fail, despite there being no need to. Changing variable names such as paddingSoFar to .paddingSoFar should solve this issue (though, a name collision is of concern here)
Take for example this:
DrawInitialBG_LoadWholeBackground_512x256:
moveq #0,d4 ; Absolute plane Y coordinate.
moveq #256/16-1,d6 ; Height of plane in blocks minus 1.
- movem.l d4-d6,-(sp)
moveq #0,d5
move.w d4,d1
; This is just a fancy efficient way of doing 'if true then call this, else call that'.
pea +(pc)
tst.w (Two_player_mode).w
beq.w CalculateVRAMAddressOfBlockForPlayer1.AbsoluteXAbsoluteY
bra.w CalculateVRAMAddressOfBlockForPlayer1.AbsoluteXAbsoluteY_DoubleResolution
+
move.w d1,d4
moveq #0,d5
moveq #512/16-1,d6 ; Width of plane in blocks minus 1.
move #$2700,sr
bsr.w DrawBlockRow.AbsoluteXAbsoluteYCustomWidth
move #$2300,sr
movem.l (sp)+,d4-d6
addi.w #16,d4
dbf d6,-
rts
This is just downright ridiculous, especially when you are referencing other local labels, like "CalculateVRAMAddressOfBlockForPlayer1.AbsoluteXAbsoluteY_DoubleResolution". Personally, I'd shorten it down to "CalcBlockVRAM.AbsXY2P" or something of that sort.
Especially for bosses, it would be nice to have constants like EHZ_Boss_Pos_X = $29D0, and have all the positions in the code for the object be relative to that.
whenever I try to load in Sonic 2 Sprite maps and pattern cues it just won't load! do you have any advice?
The bugfix in OptionScreen_Select_Not1P is a bit broken. It’s setting the emerald variables to 1 rather than clearing them due to a missing moveq #0,d0
instruction.
OptionScreen_Select_Not1P:
subq.b #1,d0
bne.s OptionScreen_Select_Other
; Start a 2P VS game
moveq #1,d0
move.w d0,(Two_player_mode).w
move.w d0,(Two_player_mode_copy).w
if fixBugs
; There should be a ‘moveq #0,d0’ here!
move.w d0,(Got_Emerald).w
move.l d0,(Got_Emeralds_array).w
move.l d0,(Got_Emeralds_array+4).w
endif
Im a linux user, and i tried building knuckles in sonic 2
i downloaded the zip file and used 'wine cmd' to use build.bat and thats when i got this conformation it says rom is about 40000 bytes (256kb) about 2f2 bytes are padding. and when i tried the rom i see a black screen
yeah so can anyone tell me what the HELL is going on??
thanks.
Hi, Iory90.
I'm using the Sonic 2 Improvement hack v5.1 (it's a fantastic hack, by the way). But it seems there's a bug. When entering into the first Special Stage using Sonic and Tails, or Tails only, the stars effect when you collect rings looks broken. This doesn't happen in the original Sonic 2 Rev A.
ignore this
hello! so i am trying to restore hidden palace zone by clownacys tutorial, all of the stuff i did correctly until this:
i swear i did everything right so what is going on
Basically, Timer_frame and Timer_frames are way too similar in name.
So the readers have easier access to context, Timer_frame is used for the HUD to count the time in-between seconds, and Timer_frames is a frame timer, like what most NES games use for framerules. Both of them are technically frame timers, but Timer_frame is a byte that ends at 60 and Timer_frames an unsigned word (or "short") that overflows back to 0.
Oh, and Timer_frame is never used for anything aside for the timer, while Timer_frames is. One typo can change that. This wasn't really an issue with Timer_centisecond, though that name was just generally inaccurate
Here are a few name suggestions I have:
Frame_timer, Framerule_timer, Level_frame_counter, Runtime_counter
Warning: Table Off_Level has 18 entries, but it should have 17 entries
s2.asm(90184) zoneOffsetTableEntry(1) zoneTableEntry(6):22: error #1820: expression must be evaluatable in first pass
zone_table_addr+zone_id_{cur_zone_str}zone_entry_lenzone_entries
!org zone_table_addr+zone_id_{cur_zone_str}zone_entry_lenzone_entries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Ever since I added REV00, there have been some files in the disassembly that split.bat can't produce, since it depends on a REV01 ROM. I could get creative, and make a second s2.txt specifically for REV00, to get the last few files, but I don't think the thing's worth the maintenance burden anymore.
This disasm already comes with the files pre-split, and the only reason to not include the binaries is as a very weak legal defence.
So, anyone else got any input?
Some confusion expressed by djohe over the fix I wrote for WFZ's cloud scrolling led me to realize that the disasm's comment about this bug is inaccurate: it describes the clouds as moving faster when going right and slower when going left, but that would actually be the 'correct' behavior rather than the bugged one! If nothing else the description should at least be corrected, but ideally a fix should be implemented.
I was wondering whether it is a good idea to extract the objects into an assembly file for each object and include them where they were extracted from in s2.asm, like what was done in the Sonic 1 disassembly. This shouldn't change the resulting binary that is created if order is maintained.
It probably would be easier to do it in stages rather than in one whole go though, unless someone is committed to doing that.
No description as of now...
Probably a noob question, but what software to you use to open and display art? Say if I want to see what this looks like?
This is probably going to be a bit controversial, but I really don't like how most sprite mappings are included as binary files in this disassembly rather than as assembly, for a few reasons:
How exactly to implement this, if accepted, may need more discussion.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.