How to detect transitions?

View previous topic View next topic Go down

How to detect transitions?

Post by helgefmi on Mon 7 Sep 2015 - 12:41

Hi all!

I'm making a ROM hack that would help speedrunners better analyze their execution of screens, find optimal strategies, find how to "save" lag frames, etc.

This has already been done by simply replacing the rupee counter with the $1A (frame counter), and add in lag frames from an NMI hook. However, I'd like to do a better job at showing more information:


  • A normal frame counter ($1A)
  • A frame+lag frame counter
  • A lag frame-only counter
  • A per-room counter (resets every time Link enters a new screen)
  • All counters should go from 0-999 or 0-9999
  • It shouldn't cause much lag, to make the results more reliable/map results from an original cart.
  • The counters does not need to update every frame; it can and should only update on screen transitions.


So, the idea is to somehow "hook" into the "Link just passed through a transition" code, so that I can update the HUD only when there's a screen transition (saving valuable cpu cycles in the previous screen), and so that I have a place to reset the "per-room counter" to 0.

I tried a some approaches:


  • I used RAM watcher through a couple playthroughs of escape with different paths, and collected the memory addresses that changed the exact same amount as the number of transitions that the playthrough had. The results was these three memory addresses: 344E, 391A, 3928. However, moving on to eastern, there was some screen transitions there that did *not* update these memory addresses. So it's not consistent.
  • I tried looking at the X/Y coordinates for scrolling ($0600 and onwards), but there doesn't seem to be a small set of memory addresses that would cover all the types of transitions (e.g. overworld, dungeon, cave, overworld -> dungeon, cave -> overworld, falling in a hole etc.) Maybe I'm wrong on this one, but it's at least not obvious which set I should go for. I *could* compare them all to previous frame's values, but that would of course add a lot of CPU cycles.

  • I tried reading the disassembly to figure out if there was a "global function" that handled transitions. I did not find 1, but 10 functions, that seemed to be involved; 2 for dungeons (inter/intra room transitions) and 8 for overworld. But when I saw there also was "sub game mode" dedicated to transitions when link falls in a hole to enter a dungeon, I kind of stopped there.


There seems to be a lot of special cases when transitions are concerned; all I want is a CPU cycle-friendly way to consistently figure out if a transition from one room to another has occured. "Transition" in this sense is defined as what would be recognized as a transition by a human (e.g. fade to black-transitions or screen wrap transitions when link goes into doors, holes or simply moves out of the bounds of the current screen.)

Any ideas?

helgefmi
Rank: Bee
Rank: Bee

Since : 2015-04-17

Back to top Go down

Re: How to detect transitions?

Post by helgefmi on Mon 7 Sep 2015 - 13:01

Found a couple memory addresses that could be used aswell:


  • $040A[1]: Overworld Area Index. Will update when transitioning in the overworld.
  • $048E[2]: Dungeon Room Index? (Seems to work in caves too.)


It's not enough; two corner cases:

- When going from overworld to a cave/dungeon and back to overworld, the values will only change when entering the cave the first time, but will not update when going back to overworld again, since the values are not STZ'd.

- Since "rooms" are connected in alttp, the Dungeon Room Index will not always update when a human would perceive that a transition has been done (like the first room in eastern; moving up is still concidered the same room even if you entered a door.)

helgefmi
Rank: Bee
Rank: Bee

Since : 2015-04-17

Back to top Go down

Re: How to detect transitions?

Post by Conn on Mon 7 Sep 2015 - 16:18

This is really advanced asm that you need, and the only people I'd know capable of doing it, would be Euclid or MoN as far I know.

I once hacked a clock into my all-in project and it actually counts the frames, since the ram I used to achieve this is incremented with each nmi.
h0e10=d3600 nmi:s are quite accurate 1 minute; at least on sd2snes, emulators differ.
However, I see myself as too exhausted to help in any further hacks and thus retired.
avatar
Conn
Zelda God - Administrator
Zelda God - Administrator

Since : 2013-06-30

Back to top Go down

Re: How to detect transitions?

Post by helgefmi on Mon 7 Sep 2015 - 17:09

Thanks for the reply Conn.

Just to clarify - I don't need help with the counter stuff - that is already done. And the asm I can write myself. But I'm a bit lost on 1. what hooks is needed and/or 2. which memory addresses can be looked at to have a routine when screen transitions happens.

Stupid ideas I've had:

- Count successive lag frames. If >some threshold, and you're not 1. pausing 2. have dialog open 3. etc.. say it's a transition. Smile

- Look at links X/Y coordinates and see if it jumps "too much" (doesn't work as in the transition he moves at 4px/f I think.)

- See if Link moves while a certain threshold of successive lag frames is occuring (this I just thought about now, though probably won't work)

Like, I don't think it should be advanced, I just haven't had that creative thought yet. Smile

helgefmi
Rank: Bee
Rank: Bee

Since : 2015-04-17

Back to top Go down

Re: How to detect transitions?

Post by Conn on Mon 7 Sep 2015 - 19:36

I suggest you take a close look into MoN's disassembly docs:
[You must be registered and logged in to see this link.]

Check out Zelda_3_Ram.log (at the very end of the files list). The most important ram spots are usually in the first $100 bytes.

Maybe you need the following?

$8A[0x02] - Overworld Screen Index (2 bytes!)
$A0[0x02] - The index used for loading a dungeon room. There are 296 rooms all in all. (mirrored in other variables).(2 bytes!)

I assume you are familiar with geiger? Just set a breakpoint when these addresses are written to (7e00a0 for dungeon or 7e008a for overworld) - that's where you want to hook Wink

- When going from overworld to a cave/dungeon and back to overworld, the values will only change when entering the cave the first time, but will not update when going back to overworld again, since the values are not STZ'd.
Sure, when entering a dungeon $A0 will be written to, when leaving $8A. You can tinker with two hooks here I guess.If not, you may can work with $1b here (this flag is set unset in dependence of entering/leaving a dungeon).
$1B[0x01] - (Dungeon, Overworld) Flag that is set to 1 if the player is in indoors and 0 otherwise.
avatar
Conn
Zelda God - Administrator
Zelda God - Administrator

Since : 2013-06-30

Back to top Go down

Re: How to detect transitions?

Post by helgefmi on Tue 8 Sep 2015 - 2:30

Thanks again for the response, Conn. Smile

Yes, $8A and $A0 seems to the same thing as the ones I talked above in my previous replay ($040A and $048E), or at least they behave similar.

I tried geiger - did not know about that (I'm completely new to rom hacking). It was a great tool for setting breakpoints, but too bad it doesn't seem to have the "Memory Watch" function that the 1.51 rerecording version does.

I tried setting breakpoints on the zero page addresses you provided, and it still seems to be a bit too "complicated" to easily be done. There seems to be different places in the ROM that sets these memory addresses - one for when going from links house to overworld, one from moving around on overworld (I'm betting in some instances there might be more than one for that too - I only tested around links house), one from moving from overworld into castle hole, and there's at least two from moving around in the castle (sometime the dungeon index is INC'd, other times it's STA'd).

It also doesn't solve the problem of "connected screens"; after the first key guard in escape (then one you need to kill to get the key to move on), no breakpoints were hit after transitioning to the room outside. These screen are "connected" and share the same room id. Alttp is full of these rooms, as I'm sure you know. So that means even more special handling.

It is possible though, but I think I'd need 6-10 hooks to "cover them all". So I guess I'm still looking for alternative ways. It doesn't even need to be a hook. I think I'd rather write a routine that compares $8A and $A0 to previous values to see if they changed, than to hook into the breakpoints I mentioned above.

helgefmi
Rank: Bee
Rank: Bee

Since : 2015-04-17

Back to top Go down

Re: How to detect transitions?

Post by helgefmi on Tue 8 Sep 2015 - 2:45

Perhaps it would be more easy to hook into these three places:

- Auto scrolling initiated (when moving around in ow or sometimes in dungeons)

- Fade to black initiated

- Mirror effect initiated

I think those three "effects" should cover all inter/intra-room/overworld/cave transitions, and they shouldn't be initiated when not related to transitions. And the chances that the development team duplicated code for fading to black or auto scrolling into multiple places is probably slim too ;-)..

I'll look into these things, and I guess I'll thoroughly read through the RAM mappings too, later today.

helgefmi
Rank: Bee
Rank: Bee

Since : 2015-04-17

Back to top Go down

Re: How to detect transitions?

Post by Conn on Tue 8 Sep 2015 - 4:24

mh, what you could also try to do is watching the ram with geiger (show hex -> ram). e.g., $11 is changing in every transition, but unfortunately also when into the start or select menu, so you'd need to exclude the values #$01 and #$0b (start and select) as well as #$02 (dialogue). Maybe even more. Maybe you can find even a better address through observing the ram.
avatar
Conn
Zelda God - Administrator
Zelda God - Administrator

Since : 2013-06-30

Back to top Go down

Re: How to detect transitions?

Post by helgefmi on Tue 8 Sep 2015 - 4:37

Yeah I was thinking that when I was reading through some disassembly just now. I could look at $10 and $11 and see when the game changes to one of the following specific values:

- $10: 0x07 $11: 0x01 or 0x02 (dungeon intern/intra room transition)

- $10: 0x09 $11: 0x01 (overworld load transition graphics)

- $10: 0x08 or 0x06 (Pre Overworld/Dungeon modules)

I think I'll write some code to update the bomb counter every time this happens and just play through the game a bit to see if it works or not.

helgefmi
Rank: Bee
Rank: Bee

Since : 2015-04-17

Back to top Go down

Re: How to detect transitions?

Post by helgefmi on Mon 30 Nov 2015 - 3:26

I spent some time last week working on this again. Here's the final product, in case someone is wondering how to do something similar: [You must be registered and logged in to see this link.] (code can be seen at [You must be registered and logged in to see this link.] )

helgefmi
Rank: Bee
Rank: Bee

Since : 2015-04-17

Back to top Go down

View previous topic View next topic Back to top


 
Permissions in this forum:
You cannot reply to topics in this forum