Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Widescreen HUD Hack Patch for Echoes #108

Open
wants to merge 36 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
4d778fb
WidescreenHUD Patch
Nystrata Apr 25, 2024
f7c4210
Renamed FRME files to match names in PWE
Nystrata Apr 25, 2024
47dcc7f
Summary (Required)
Nystrata May 16, 2024
74e913e
Update dol_patches.py
Nystrata May 16, 2024
5b77a25
Update dol_patches.py
Nystrata May 16, 2024
1b5a9eb
Summary (required)
Nystrata May 18, 2024
7e8cf3e
Summary (required)
Nystrata May 18, 2024
3ba54eb
Merge branch 'main' into WidescreenHUDPatch
Nystrata Jul 27, 2024
336a29d
Seperate out apply_widescreen_hack_patch into it's own function
Nystrata Jul 27, 2024
2e60b8e
Remove prints from widescreen_hud\__init__
Nystrata Jul 27, 2024
dc07441
Clean up
Nystrata Jul 27, 2024
9a37e80
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 27, 2024
892cf34
Make configurable via EchoesDolPatchesData
Nystrata Jul 27, 2024
c195eeb
Merge branch 'WidescreenHUDPatch' of https://github.com/Nystrata/open…
Nystrata Jul 27, 2024
cf03ff1
Add docstrings, pass version.description instead of the entire versio…
Nystrata Jul 28, 2024
55320f8
Restore vanila instructions when widescreen hack is disabled
Nystrata Jul 31, 2024
1ae075a
Merge branch 'randovania:main' into WidescreenHUDPatch
Nystrata Jul 31, 2024
432fc18
Merge branch 'main' into WidescreenHUDPatch
Nystrata Oct 12, 2024
a5544d5
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 12, 2024
9b3ad55
Merge branch 'randovania:main' into WidescreenHUDPatch
Nystrata Oct 26, 2024
f531082
Merge branch 'randovania:main' into WidescreenHUDPatch
Nystrata Oct 26, 2024
1a1af32
Update __init__.py - Fixed comment typo
Nystrata Oct 29, 2024
807463b
Move addresses to dol_versions.py
Nystrata Oct 30, 2024
ac0461b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 30, 2024
9a15c3d
Fixed variable typos
Nystrata Oct 30, 2024
27a8e76
Add comment explaining manual version detection
Nystrata Oct 31, 2024
a7be495
Comment typo fix
Nystrata Oct 31, 2024
6dfe945
Check if asset exists, instead of needing to deal with game versions
Nystrata Nov 1, 2024
eaa0d5d
Merge branch 'randovania:main' into WidescreenHUDPatch
Nystrata Nov 13, 2024
fb4896b
Merge branch 'randovania:main' into WidescreenHUDPatch
Nystrata Dec 5, 2024
20dc608
Update __init__.py
Nystrata Dec 5, 2024
0ec11ad
Rename variables to be more accurate, added comments
Nystrata Dec 6, 2024
377549c
Replace culling section with a simple float value change, updated com…
Nystrata Dec 7, 2024
579ae9f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 7, 2024
7e91bd9
Remove usage of storing to r2
Nystrata Dec 8, 2024
bda18b6
Rework culling code, rename variables for clarity
Nystrata Dec 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/open_prime_rando/dol_patching/echoes/dol_patcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class EchoesDolPatchesData:
unvisited_room_names: bool
teleporter_sounds: bool
dangerous_energy_tank: bool
widescreen_hack: bool

@classmethod
def from_json(cls, data: dict):
Expand All @@ -33,6 +34,7 @@ def from_json(cls, data: dict):
unvisited_room_names=data["unvisited_room_names"],
teleporter_sounds=data["teleporter_sounds"],
dangerous_energy_tank=data["dangerous_energy_tank"],
widescreen_hack=data["widescreen_hack"],
)


Expand Down Expand Up @@ -67,4 +69,6 @@ def apply_patches(dol_file: DolFile, patches_data: EchoesDolPatchesData):
version.safe_zone, version.sda2_base, patches_data.safe_zone_heal_per_second, dol_file
)
dol_patches.apply_starting_visor_patch(version.starting_beam_visor, patches_data.default_items, dol_file)

dol_patches.apply_map_door_changes(version.map_door_types, dol_file)
dol_patches.apply_widescreen_hack(version.widescreen_render, dol_file, patches_data.widescreen_hack)
46 changes: 46 additions & 0 deletions src/open_prime_rando/dol_patching/echoes/dol_patches.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ class StartingBeamVisorAddresses:
reset_visor: int


@dataclasses.dataclass(frozen=True)
class WidescreenRenderAddresses:
culling_replacement: int
culling_insertion: int
viewport_replacement: int
viewport_insertion: int


_PREFERENCES_ORDER = (
"sound_mode",
"screen_brightness",
Expand Down Expand Up @@ -388,6 +396,7 @@ class EchoesDolVersion(BasePrimeDolVersion):
powerup_should_persist: int
map_door_types: MapDoorTypeAddresses
double_damage_vfx: int
widescreen_render: WidescreenRenderAddresses


def apply_fixes(version: EchoesDolVersion, dol_file: DolFile):
Expand Down Expand Up @@ -500,3 +509,40 @@ def apply_map_door_changes(door_symbols: MapDoorTypeAddresses, dol_file: DolFile

dol_file.symbols["CTweakAutoMapper::GetDoorColor::DoorColorArray"] = door_color_array
dol_file.write("CTweakAutoMapper::GetDoorColor::DoorColorArray", DoorMapIcon.get_surface_colors_as_bytes())


def apply_widescreen_hack(widescreen_render_symbols: WidescreenRenderAddresses, dol_file: DolFile, enabled: bool):
"""
Apply widescreen render hack to render the game in 16:9
"""
culling_replacement = widescreen_render_symbols.culling_replacement
culling_insertion = widescreen_render_symbols.culling_insertion
viewport_replacement = widescreen_render_symbols.viewport_replacement
viewport_insertion = widescreen_render_symbols.viewport_insertion

if enabled:
dol_file.write_instructions(culling_replacement, [bl(culling_insertion, relative=False)])
dol_file.write_instructions(culling_insertion, [lis(r14, 0x4000), stw(r14, 0, r2), lfs(f26, 0, r2), blr()])

dol_file.write_instructions(viewport_replacement, [b(viewport_insertion, relative=False)])
dol_file.write_instructions(
viewport_insertion,
[
lis(r14, 0x3FAA),
Nystrata marked this conversation as resolved.
Show resolved Hide resolved
ori(r14, r14, 0xAAAB),
stw(r14, 0, r2),
lfs(f19, 0, r2),
fmuls(f9, f19, 0, f9),
fdivs(f11, f10, f9, 0),
b(viewport_replacement + 0x4, relative=False),
],
)

return

# Restore vanilla behavior when widescreen hack is disabled
# To be removed when RDV is updated to no longer cache patched DOL files
dol_file.write(culling_replacement, [0xFF, 0x40, 0x10, 0x90])
dol_file.write(culling_insertion, (b"\0" * 16))
dol_file.write(viewport_replacement, [0xED, 0x6A, 0x48, 0x24])
dol_file.write(viewport_insertion, (b"\0" * 28))
13 changes: 13 additions & 0 deletions src/open_prime_rando/dol_patching/echoes/dol_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
MapDoorTypeAddresses,
SafeZoneAddresses,
StartingBeamVisorAddresses,
WidescreenRenderAddresses,
)

ALL_VERSIONS = [
Expand Down Expand Up @@ -85,6 +86,12 @@
map_icon_jumptable=0x803B3638,
),
double_damage_vfx=0x80017F28,
widescreen_render=WidescreenRenderAddresses(
culling_replacement=0x8030256C,
culling_insertion=0x80418E8C,
viewport_replacement=0x8036D684,
viewport_insertion=0x80003748,
),
),
EchoesDolVersion(
game=Game.ECHOES,
Expand Down Expand Up @@ -155,5 +162,11 @@
map_icon_jumptable=0x803B4A80,
),
double_damage_vfx=0x80017FC4,
widescreen_render=WidescreenRenderAddresses(
culling_replacement=0x803029E0,
culling_insertion=0x803C6C30,
viewport_replacement=0x8036DAA0,
viewport_insertion=0x803B1D60,
),
),
]
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
5 changes: 5 additions & 0 deletions src/open_prime_rando/echoes/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@
"description": "Set elevators to be activated on room load",
"default": false
},
"widescreen_hud": {
"type": "boolean",
"description": "Enable 16:9 widescreen HUD patch",
"default": false
},
"cosmetics": {
"type": "object",
"properties": {
Expand Down
18 changes: 18 additions & 0 deletions src/open_prime_rando/echoes/widescreen_hud/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from retro_data_structures.base_resource import RawResource

from open_prime_rando.echoes.custom_assets import custom_asset_path
from open_prime_rando.echoes.widescreen_hud.asset_map import WIDESCREEN_HUD_ASSETS
from open_prime_rando.patcher_editor import PatcherEditor


def apply_widescreen_hud(editor: PatcherEditor):
"""
Replaces certain FRME files to adjust HUD/Visor widgets to better fit a 16:9 screen aspect ratio
"""
for asset_id, filename in WIDESCREEN_HUD_ASSETS.items():
widescreen_assets = custom_asset_path().joinpath("widescreen_hud")
Nystrata marked this conversation as resolved.
Show resolved Hide resolved
asset = widescreen_assets.joinpath(filename)
if not editor.does_asset_exists(asset_id):
continue
res = RawResource(type="FRME", data=asset.read_bytes())
editor.replace_asset(asset_id, res)
14 changes: 14 additions & 0 deletions src/open_prime_rando/echoes/widescreen_hud/asset_map.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# https://github.com/Nystrata/EchoesWidescreenHUD/wiki#gguisyspak
from retro_data_structures.base_resource import AssetId

WIDESCREEN_HUD_ASSETS: dict[AssetId, str] = {
# Common
0xE6F37215: "FRME_Helmet.FRME",
0x88738D60: "FRME_SamusHud1Ball.FRME",
# NTSC-U
0xEEF43AA1: "FRME_SamusHud1Combat.FRME",
0xF7EC0850: "FRME_ScanHudFlat_0.FRME",
# PAL
0xB5CF0C19: "FRME_SamusHud1Combat_0.FRME",
0xD9D58FA5: "FRME_ScanHudFlat_1.FRME",
}
4 changes: 4 additions & 0 deletions src/open_prime_rando/echoes_patcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from open_prime_rando.echoes.inverted import apply_inverted
from open_prime_rando.echoes.small_randomizations import apply_small_randomizations
from open_prime_rando.echoes.suit_cosmetics import apply_custom_suits
from open_prime_rando.echoes.widescreen_hud import apply_widescreen_hud
from open_prime_rando.patcher_editor import PatcherEditor
from open_prime_rando.validator_with_default import DefaultValidatingDraft7Validator

Expand Down Expand Up @@ -192,6 +193,9 @@ def patch_paks(

apply_custom_suits(editor, configuration["cosmetics"]["suits"])

if configuration["widescreen_hud"]:
apply_widescreen_hud(editor)

# Save our changes
editor.flush_modified_assets()

Expand Down