(01-26-2023, 11:55 AM)CLF78 Wrote:(01-25-2023, 10:48 PM)tefo7 Wrote: From what I understood:
1) finding the right bit to enable the minimap
2) modifying the correct property at start (visible = false)
3) turn the property to true when less than 20s
Is that what you meant?
Yes, correct.
(01-25-2023, 10:48 PM)tefo7 Wrote: Would you mind handing me references to the minimap property you were talking about?
What the HideHUD code is doing is very simple: the original instruction simply moves the contents of r3 to r31 for reuse later in the original function. Therefore, i hijacked this spot to disable some bit flags and enable others.
The flags are as follows (you can check the function using them at 0x80857CC0 PAL):
Code:0x2 = Timer
0x4 = Countdown text
0x8 = Minimap
0x10 = Position
0x20 = Lap
0x40 = Item roulette
0x80 = Battle score
0x100 = Ghost race time difference
0x200 = Live view text
0x400 = Mission mode score
0x800 = Item alert
0x1000 = Ghost cannot be saved text (repurposed for Kill Information in HNS)
0x2000 = Another battle score related screen element
So, the rlwinm instruction is turning off the bits for the minimap, the position and the lap, while the ori instruction is turning on the score and the kill info text. Therefore all you have to do is modify the rlwinm instruction to suit your needs. I ported this to C to aid you in editing, so feel free to mess with it: https://godbolt.org/z/73j9EEjsG (just don't forget the result of the rlwinm+ori must go in r31)
Final note: this does not simply hide the elements, it literally prevents their creation, so they don't exist at all if their flag is turned off.
(01-25-2023, 10:48 PM)tefo7 Wrote: I have thought about adding some lines in MainTimerUpdate (timer.c). Can I change the property from within C? If not, how can I do that?
Yes, you should be able to. Unfortunately this is not easy, because the minimap will not be at the same place every time, nor there's a static pointer to it, therefore it has to be saved somewhere or obtained through weird means.
A few hints:
- The minimap is constructed at 0x808581A0 PAL (the pointer to it is being moved from r3 to r14 at this address, so it's a good candidate for a hook)
- The visible attribute is at offset 0x80, is 1 byte big and obviously takes a boolean value (0 = visible, 1 = hidden)
I'll leave the rest for you to figure out
Thank you for the great explanation - it makes now much more sense to me, what the code does and how the mods modifies the original instructions.
You have posted an overview of all the bits concerning element creation. Did you look that up somewhere or did you reverse engineered it yourself? If there's a documentation for the bits, would you mind posting a link to them?
I will try out the approch in the next few days - did you find out the attribute being at 0x80 yourself or did you look that up somewhere? Do you know the offset for the opacity so I could slowly fade in the minimap instead of instantly going from 0 to 1.
You defined a procedure called
Code:
directWriteBranch
What exactly does the last boolean do? For example
Code:
directWriteBranch(HUDEditsHook, HideHUD, true)
EDIT:
This is what I got so far:
Code:
# Turn off position and lap (Minimap = 0x8)
HideHUD:
rlwinm r3, r3, 0, 28, 25
# Enable score + kill info text
ori r31, r3, 0x1400
blr
StoreMinimap:
# original instruction
or r14, r3, r3
# hide minimap
li r4, 1
stb r4, 0x80(r14)
Code:
MinimapHook = 0x808581A0;
Code:
// Store Minimap for enabling later on
directWriteBranch(MinimapHook, StoreMinimap, true);
I was just testing the injected code; Minimap is created and shown at start. I was trying to set the bit at offset 0x80 to 1 but the minimap is still visible. Are the ASM lines correct?