RetroAchievements / rcheevos

Library to parse and evaluate achievements and leaderboards for RetroAchievements
MIT License
90 stars 34 forks source link

Add support for hashing DOSZ parent files #352

Closed schellingb closed 3 months ago

schellingb commented 4 months ago

Hello

This PR adds parent DOSZ support on top of what was contributed at the end of last year in #304.

To better accommodate packaging of certain DOS games, parent/child related packages were added to the DOSZ spec. An example would be a custom DOOM WAD, for which standalone DOOM can be used as a parent of a simpler child package that only contains the custom WAD.

This was implemented without too much complications by introducing a special empty file named <base>.dosz.parent inside a child-DOSZ ZIP file. So when an emulator, while loading a DOSZ file encounters such a file, it will load <base>.dosz as the parent, and treat the child-DOSZ file as an overlay onto that. This avoids needing a way of attaching meta data to a DOSZ file, the relationship is entirely defined by having an empty file in the ZIP. It also nicely works how an end-user will build their DOSZ files, because already available ROM management tools will happily generate this empty file as needed according to a DAT file.

As mentioned in the PR #304 which added DOSZ hashing:

A .dosz file can be paired with an optional .dosc filesystem overlay file (which simplifies game launching by containing premade game config files and copy protection scheme removal patches).

This now means that a file with a parent can result in hashing of the file listings of up to 4 ZIP files:

While a parent itself can have another parent, a child can not have multiple parents. Hashing will abort with an error if it encounters multiple .parent files. Hashing also aborts if it finds itself in a recursive loop (child being parent of child).

Because we're only accessing very small amounts of (uncompressed) data in a ZIP files' content directory, this still is a very quick process. File system access might very well be the slowest part of it.