GithubHelp home page GithubHelp logo

s2disasm's Introduction

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.

s2disasm's People

Contributors

awuwunya avatar brainulator9 avatar caverns4 avatar clownacy avatar devon-artmeier avatar devsarchive avatar flamewing avatar fragag avatar gabrielravier avatar geminicrafterman avatar intelorca avatar kirjavascript avatar mainmemory avatar marzojr avatar minerobber9000 avatar pokepunch avatar seanieb64 avatar sonichachellebee avatar tristanpenman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

s2disasm's Issues

Nameless temporary lables should be banned from s2disasm

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?

  1. They do not obey scope rules quite the same as other labels. Temporary labels are limited within label scope (but may be specially addressed from outside of the scope if needed), while normal labels create a scope between each other, and macros and equates work roughly the same as normal labels as well. Nameless temporary labels do not respect label scope, but also do not create their own scope. This behavior is unusual at the very least.
  2. They promote unmaintainable code. Just even go look at KosDec inside s2.asm. Tell me if you'd enjoy modifying this code in case you needed to add/remove something? You need to read the entire routine just to make sure that the nameless temporary labels match after your alterations - or - not add any new temporary nameless labels or remove existing ones just to be sure it will keep working. Especially for long methods that rely on skipping over these labels, as is the case with KosDec and even worse abominations elsewhere, it becomes very difficult to tell when you have missed something or made a mistake
  3. You lose the assembler's built-in detection for missing or duplicate labels. Although normal temporary labels might not exactly be easy to name or come up with any helpful names, at least if you delete a label another piece of code is using, you will get an assembler error. Similarly, these help catch many other similar issues relating to modifying code, so you are aware of when you actually have made a mistake. This is impossible with nameless temporary labels.
  4. You are promoting poorly documented code to newcomers and possibly even intermediary programmers. Having disassemblies show an example of code that is of poor quality intentionally is not a good way to promote people to pick up good habits such as documentation or making code that is actually maintainable. Although this isn't what disassemblies in their current state can be a gold standard on, can we at least pick out some of the most obvious bad habits we are likely to be teaching newcomers? Temporary labels have the possibility to at least give some hints about how the code flow was intended to function, so its better than just seeing a single symbol appended to a branch instruction.
  5. The purpose of temporary nameless labels are not at all self-explanatory. What does + mean? What does - mean? How does / both work as - and + in a visually confusing manner? Yeah. This is not only a confusing and unconventional manner of defining labels, it straight up can't even follow its own rules in a way that would make it easy to use. / screws up any train of logic you might have, promoting you to make even more mistakes. Again, KosDec.
  6. Nameless temporary labels do not respect label scope. This means a nameless temporary label $1000 bytes and 20 labels later is just as valid of a target as one few instructions away. There is no obvious flow to how they work or what their restrictions are. The system with temporary labels and normal labels works because temporary labels are always within a reaching distance, and normal labels are expected to have a range from few bytes to literally anywhere in the ROM. nameless temporary labels have the expectation of having the same limitations as temporary labels, but actually the assembler doesn't care.
  7. Nameless temporary labels will make effective debugging a pain too because you may be unable to understand how you ended up somewhere, and even if you look upon the code which caused an issue, unless you think about it enough, you may discount the possibility that the amount of +'s doesn't actually match with the routine. These also provide complications with debugging tools, such as listings files and in-ROM debuggers, as these labels are both abundant and completely unhelpful.
  8. Anyone either reading or writing code will find it more difficult to understand code flow that contains nameless temporary labels, because they can't just scan for the appropriate label, but they have to count the amount of symbols in most cases. For some conservative situations, for example jumping past a few lines its fine, but for routines that contain multiple +'s, it adds visual noise and requires more attention on the code flow. This does not actually help however, simply because a lot of the time you aren't reading into routines to understand their specific operation, but skimming over code to understand what it does roughly, or if the code is relevant to the programming question you are researching. It only slows you down and may take your attention away from the problem you are having to counting the +'s.
  9. The only reason to use it is laziness. I said it. You use it because its faster to write and requires less thinking. That attitude for sure isn't going to lead better code be written, or higher quality research to be achieved. The fundamental problems with these nameless temporary labels are to be ignored because its easier? That might be true for individual programmers, and more power to them, but as far as the official disassemblies are concerned? That is a ridiculous ideal to hold..

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

Knuckles in Sonic 2 Broken Jump Sprite when fixBugs is Enabled

image
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.

To reproduce, set the following flags

  1. fixBugs = 1
  2. standaloneKiS2 = 1 (again, this one might not be necessary, but it was how I built it)

Note:

This only appears to happen when fixBugs = 1. Turning it off resolves this issue at the expense of whatever fixes are relevant to KiS2.

Build tools are 64bit only

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?

Remove Sonic Classics (Compilation) modifications from REV02

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 negative size results in invalid behaviour

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?

Sonic 2 ss

might wanna change some subroutines names in s2 ss stages and label them correctly when it comes to Objoff's thank you

Add a 'Knuckles in Sonic 2' branch

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.

The missing instruction in ObjCheckLeftWallDist

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?

RFC: Updated/custom AS builds

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:

  • one commit to get building;
  • one commit to ignore build cruft;
  • one commit to fix a stupid decision of making message useless by suppressing its output in quiet mode;
  • one commit to fix a segfault introduced probably in asl-current-142-bld193 when defining symbols from the command line.

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?

Buiild Failure with Revision 2 and FixBugs Enabled

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

Portable way of checking bit-perfection

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?

Knuckles in Sonic 2: Casino Night Zone object layouts

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.

Split REV00 and REV02 into their own branches

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.

REV02 might be wrong

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.

[enhancment]DAC Sample Names

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.

Various macros break scope

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)

Some labels are *way* too verbose

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.

Broken bugfixes in OptionScreen_Select_Not1P and UpdateWaterSurface

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

knuckles in sonic 2 black screen error

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
Screenshot from 2024-06-02 16-35-42
yeah so can anyone tell me what the HELL is going on??
thanks.

Broken rings effect on the Special Stage.

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.

hidden palace restoration error

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

Timer_frames should be renamed

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

I am trying to restore Wood Zone in a similar manner to Clownacy restoring Hidden Palace Zone and I'm attempting to add an extra slot for Wood Zone's background. How do I add to the Off_Level table? You're cool ;)

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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Remove splitrom?

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?

Inaccurate description of bug in SwScrl_WFZ

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.

Extract objects into individual assembly files.

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.

Convert sprite mappings to assembly(?)

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:

  • Our disassemblies of Sonic 1 and Sonic 3 & Knuckles have their mappings stored as assembly files, leaving this one on its own despite Sonic 1, 2, and 3/K all being based on the same code.
  • The splitting into binary is said in the main disassembly file to have been done to aid external mapping editor programs. This makes sense as far as the splitting goes, but SonMapEd and Flex 2 both support assembly-based mappings.
  • We know the original source code implemented these mappings in assembly (though the details as to how exactly they were implemented are unclear), given that certain mappings are not straightforward as our programs would assume. Some call for an incorrect number of pieces, some are included in the ROM in a different order than they are listed in each offset table, some mappings appear in multiple offset tables, some offset tables draw from multiple mappings lists, some use negative tile offsets, and some refer to the same mapping frame multiple times. In addition, labels found within the Sonic 2 Nick Arcade prototype's leftover data include symbols for the individual frames.
  • There is precedent for converting binary data into assembly data in this disassembly, namely the music and sound effects. Those, too, are known to have been originally assembled, only this time by virtue of released source code for a different version of this game's sound program.

How exactly to implement this, if accepted, may need more discussion.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.