BC46 / freelancer-hd-edition

Freelancer: HD Edition is a mod that aims to improve every aspect of the game Freelancer (2003) while keeping the look and feel as close to vanilla as possible.
https://www.moddb.com/mods/freelancer-hd-edition
161 stars 14 forks source link

Hard coded weapon group button positions #159

Closed BC46 closed 1 month ago

BC46 commented 1 year ago

In the HDE installer we clearly specified that the weapon group buttons should only be enabled for 4:3 and 16:9 resolutions, since the plugin only uses hard coded positions.

However, recently I've gotten a few insights into how the positions can possibly be made dynamic. In the assembly I found out where the weapon group button positions in HudWeaponGroups.dll are used. From there we could patch some of the instructions and replace the positions with dynamic ones. These would have to come from the HUD Shift plugin, which will have to be modified in order for this to work.

The installer code will also have to be modified if the dynamic positions can be set, since there will no longer be a need to check for the user's aspect ratio.

One small implication I noticed during my assembly peek is that HudWeaponGroups.dll uses twords to store the HUD positions. Therefore, the floating point values from HUD Shift would have to be converted to long doubles.

If for whatever reason it isn't achievable to set the dynamic positions, we should instead opt for this: https://github.com/oliverpechey/Freelancer-hd-edition-install-script/issues/99.

BC46 commented 5 months ago

Ideally we want a full standalone solution, i.e. one that does not require existing DLLs to be recompiled. I came up with the following idea for a plugin:

  1. Check if hudshift.dll and hudweapongroups.dll are both loaded.
  2. Create an instance of std::list<Position>.
  3. Add a Position object to it with addr being a pointer to a float in the current DLL and a scale of 1.0f.
  4. In HudShift.dll locate the void Shift( const LPosition* pos, float delta ) function.
  5. Call the function with the position list and dx = ((float)WIDTH / HEIGHT - 4.0f / 3) * 0.3825f;.
  6. Patch the correct values in hudweapongroup.dll with the local variable (conversion of float to long double). Also patch out any jumps if necessary.
  7. This shifts the weapon group buttons to the correct positions. However, when the resolution is updated, the positions will be incorrect. To fix this, hook Resolution_Hook and re-call void Shift( const LPosition* pos, float delta ).

One downside to this approach is that it does not consider the fact that the weapon list group may be shifted to a different position (not the default one).

BC46 commented 1 month ago

Found an easier solution that requires only the HudWeaponGroups module to be modified. Recompiling wasn't an option since the provided Delphi source code is incomplete. Hence I opted for directly implementing the solution in HudWeaponGroups.dll using asm.