UsernameFodder / pmdsky-debug

Debug info for reverse engineering PMD: Explorers of Sky
GNU General Public License v3.0
38 stars 20 forks source link

Add some documentation on the window system #210

Closed UsernameFodder closed 11 months ago

UsernameFodder commented 11 months ago

Unifies menus, dboxes, and portrait boxes into a single generic graphical window system. The central object in this system is the "window", which can be specialized into menus, text boxes, portraits, and more.

On top of the previously known specializations, these additions identify many more window types. The full list (see window.h comments for in-game examples of the more esoteric types):

The above list of window types should hopefully be exhaustive. They were tracked down by looking at all callers to the NewWindowScreenCheck function across all binaries, which also reveal the update function and the size of the contents structure stored in struct window_params. By looking at the update function pointer addresses in active windows in the WINDOW_LIST, and twiddling some data to observe live changes, it's possible to correlate different update functions with examples, which in turn allows the general purpose of each window type to be inferred.

All windows share similar APIs for general manipulation (though each type may have additional specialized methods, which remain mostly undocumented):

  1. A new window is create with the corresponding Create* function, which takes a window_params struct specifying generic parameters like the window position and size. A new window is added to the global WINDOW_LIST with a newly allocated window-type-dependent contents structure to hold all specialized data, and a corresponding update function to manage the data structure. The function returns a window ID (an index into WINDOW_LIST), which is used as a handle for all future manipulation.
  2. The corresponding Update* function is (presumably periodically?) called to update the contents of the active window, if needed. This update function operates on the contents structure that was allocated when the window was created.
  3. Presumably the code managing the window also does other stuff with the window, such as reading menu selections? The function GetWindowContents retrieves the specialized contents structure for an active window given its ID, and is used in many places.
  4. There are presumably more functions for generic manipulation, like something to close a window, but these remain unknown for now.

As part of unification under the generic window system, some old terminology has been changed. Among the most important:

Frostbyte0x70 commented 11 months ago

Wow, this is very detailed! Imagine creating custom menus with ASM patches. It could be used to add new in-game config options, which is something I always thought would be cool for patches (no need to configure them when applying the patch, you would be able to change the settings in-game).

Just the other day, during my last info dump, I was checking if we had any structs with flags that are passed to menus, because PlayMenuOptionSound contains this check the start of the function: if [r0+0x10] & 0x10 == 0, return. Seems like one of the flags might be used to silence menu sounds.

UsernameFodder commented 11 months ago

Wow, this is very detailed! Imagine creating custom menus with ASM patches. It could be used to add new in-game config options, which is something I always thought would be cool for patches (no need to configure them when applying the patch, you would be able to change the settings in-game).

Just the other day, during my last info dump, I was checking if we had any structs with flags that are passed to menus, because PlayMenuOptionSound contains this check the start of the function: if [r0+0x10] & 0x10 == 0, return. Seems like one of the flags might be used to silence menu sounds.

Glad I'm not the only one that sees potential here. Though, I'm not sure how usable this stuff is for patching in its current state, seeing as there's still a lot of missing info. Probably needs more research before it really becomes powerful.

tech-ticks commented 11 months ago

Thanks, all this new documentation will be really useful. If you need some examples for custom advanced menus, refer to https://github.com/tech-ticks/strung-up-by-patches (e.g. the Ether in https://github.com/tech-ticks/strung-up-by-patches/blob/main/src/item_effects.c). I think most (or all) structs and functions are already documented here, but it might help understand which calls are required for a working menu.