Xeeynamo / sotn-decomp

Decompilation of Castlevania: Symphony of the Night (PSX+Saturn)
https://sotn.xee.dev/
GNU Affero General Public License v3.0
508 stars 55 forks source link

Support Additional Enum Lint Detection #1796

Closed hohle closed 3 weeks ago

hohle commented 4 weeks ago

sotn-lint can now find numeric enum values within equality expressions (==, !=), inside the condition of logical expressions, (if, while, ?:, etc.), within compound statements, and if the numeric value is the starting value of a mixed numeric and enum logical expression (e.g. self->flags = 15 | FLAG_FOO | FLAG_BAR;).

Resolves #1795.

hohle commented 4 weeks ago

Drat. I need to find a way to exclude the Saturn flags that are now being found.

sozud commented 4 weeks ago

The term flags is so generic having a regex that matches it seems off to me, but I don't really have a problem renaming the saturn flags to dma_flags or whatever. When I originally wrote this tool, I knew using regex was wrong for parsing C but gave up on using C parsing libraries because it ended up being way more difficult than I expected and regex got 90% of the result with 1% of the effort.

hohle commented 4 weeks ago

I am not sure how the regex is done (I briefly read your convo on Discord) but just keep in mind that the first 8 bits from the entity ->flags are a timer. So hopefully the linter will not catch those

Each of the individual enum line transformers has the map of name to value (copied from the headers, ugh.). If a value isn't defined in that list, it won't try to replace it. Since the timer fields aren't enumerated, they don't get replaced.

There's tricks in the generic transformer to safely invert the enums as well (e.g. 0xFF7FCFFF becomes ~(FLAG_HAS_PRIMS | FLAG_UNK_2000 | FLAG_UNK_1000)) so even when the immediate value touches those bits, the transformed version won't (at least not directly).