News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: Looking for advice on finding GBA code that's triggering a graphics update  (Read 2045 times)

SleepyFist

  • RHDN Patreon Supporter!
  • Hero Member
  • *****
  • Posts: 914
    • View Profile
Hey all, I'm helping sorrow with a modification of the Castlevania Harmony of Dissonance hack Revenge of the Findesicle.

Basically the gist of it is that sorrow wants to add a story mode for the extra characters but to do that we had to enable the Rock Crusher weapon's ability for all characters, this allows them to "charge" and then unleash a wave attack that destroys walls but has the side effect of overwriting character graphics in VRAM causing the animation to become a glitchy mess.

So what I'm asking is, does anybody have any idea how to find the code that's setting these sprites up to be written to VRAM?
All I need to do is stop it from loading/updating those graphics and possibly resize the hitbox to make it look like it's centered on the weapon.
But I got nothin tbh, graphics hacking is definitely not my forte...

FAST6191

  • Hero Member
  • *****
  • Posts: 3100
    • View Profile
Is it not just a minor variation on the basic tracing guide?
https://www.romhacking.net/documents/361/
Though we are generally suggesting no$gba as a debugger
http://problemkaputt.de/gba.htm
Though https://mgba.io/2021/03/28/mgba-0.9.0/ is rapidly rising up in that world.

You presumably can open up the VRAM viewer when the game is working as it should, then after your charge attack and see what changed (presumably the same thing every time). You now know where to stick your break on write (bpw) after you loaded your savestate and thus what to NOP or alter to match the sprites you have.

Hitboxes is a different matter though usually the calculations will be based on OAM interactions or the virtual map of the world and player position the game has. Bit abstract but https://www.pcgamer.com/how-hitboxes-work/ is a nice overview if you are new to it. That said if the thing causes changes on screen for destructible walls then whatever removes that from either the screen or the virtual world map the game operates from for its general calculations will be dealing with it.

SleepyFist

  • RHDN Patreon Supporter!
  • Hero Member
  • *****
  • Posts: 914
    • View Profile
Thanks,I'll have a look at the tracing guide, I've been using N0$GBA, set a breakpoint on the VRAM address, but that leads me back to a bit of code that uses DMA 3 to update the character sprites, I can't disable that without breaking the character graphics completely so I was trying to stop the charge graphics from loading so it wouldn't bother the character sprites.

FAST6191

  • Hero Member
  • *****
  • Posts: 3100
    • View Profile
Something will be slapping the DMA and saying grab this and stick it here, maybe after compression handling or via another step. Tracing is all about going back as many steps as you need to find what you want.

SleepyFist

  • RHDN Patreon Supporter!
  • Hero Member
  • *****
  • Posts: 914
    • View Profile
Thanks I've traced it back a ways, any idea what "sp" means? I'm stuck on this opcode.

ldr r2,[sp,8h]

This seems to get a base address which is then added with an offset and loaded into r6, which, after some register juggling eventually makes it's way into the character graphics loading section.

FAST6191

  • Hero Member
  • *****
  • Posts: 3100
    • View Profile
SP in most assembly languages tends to be short for Stack pointer
http://problemkaputt.de/gbatek.htm#armcpuregisterset

[Unknown]

  • Jr. Member
  • **
  • Posts: 48
    • View Profile
    • PPSSPP
Also, sp + 8 could mean a few different things depending on the shape of the function.

Typically a function generated by a compiler looks like this:

 * Prolog
   * Retrieve extra arguments
   * Save registers (push)
   * Update frame pointer if needed
 * Actual function
   * Series of basic blocks (often with minimal register cross-use in Thumb compilers)
 * Epilog
   * Restore registers
   * pop or bx to end func

If a function doesn't need to save registers (called a "leaf" function), it won't have any push or pop, but likely still will have a bx except in fairly rare cases of tail recursion (I'm not sure if any Thumb compilers did it those days.)

If you're seeing ldr r2,[sp,8h] at the start, it may be reading an argument into r2 from the caller.

More likely, if you're seeing that mid function, it's probably a temporary variable that the function earlier wrote to the stack (this is called "spilling") because it ran out of registers to keep track of all the things on its mind.  GBA Thumb compilers were terrible and often spill registers entirely unnecessarily.

-[Unknown]

SleepyFist

  • RHDN Patreon Supporter!
  • Hero Member
  • *****
  • Posts: 914
    • View Profile
Thanks, I'm finally reading through GBAtek, which is something I should have done a long time ago.

I don't think it's a spill since the value is added with an offset in the next instruction right after, and used soon after that.

FAST6191

  • Hero Member
  • *****
  • Posts: 3100
    • View Profile
In addition to GBAtek then for the sake of having some more links

http://www.coranac.com/tonc/text/asm.htm being the "if you read nothing else" type link. It is about as close as you will get to a gentle but still reasonably comprehensive intro to GBA assembly.

https://www.cs.rit.edu/~tjh8300/CowBite/CowBiteSpec.htm
https://blog.quirk.es/2008/12/things-you-never-wanted-to-know-about.html
https://web.archive.org/web/20120628204500/http://www.reinerziegler.de/GBA/gba.htm
http://www.devrs.com/gba/
http://web.archive.org/web/20130215155212/http://labmaster.bios.net.nz/vba-sdl-h/ and usually combines with https://www.romhacking.net/documents/361/
http://members.iinet.net.au/~freeaxs/gbacomp/ and I usually link https://ece.uwaterloo.ca/~ece611/LempelZiv.pdf for an overview of compression in general.
https://mgba.io/tag/debugging/ has some good stuff.
http://arm.flatassembler.net/ I am not sure why I am linking here but hey. Most would use whatever emulators provide, GCC's stuff via devkitarm/devkitpro or whatever, maybe the ARM-SDT, ARMIPS obviously, might hope crystaltile2 works for them (I tend to use it as a static disassembler, or one that can reach out to emulators)
https://wrongbaud.github.io/posts/ghidra-debugger/ I guess also wants to be linked here, covers using ghidra with a GBA emulator.
https://www.dwedit.org/files/ARM7TDMI.pdf because might as well.
https://heyrick.eu/assembler/ is very old school (as in was ancient when the GBA was current, the web design likely attesting to it) but some like that sort of thing.
https://github.com/gbdev/awesome-gbadev has some good links.
https://gbadev.org/docs.php has some things I should probably grab copies of as well.

SleepyFist

  • RHDN Patreon Supporter!
  • Hero Member
  • *****
  • Posts: 914
    • View Profile
Thanks, I'm gonna bookmark those on my tablet, I've been reading GBAtek and while there's parts I don't get yet, it's been really helpful. I have a pretty OK grasp on most of the common opcodes from working on Final Fight and I can write basic loops, timers, and such but having important addresses and functions laid out and explained is invaluable.