Skip to content

Commit

Permalink
Merge pull request #186 from steven11sjf/version-adapter
Browse files Browse the repository at this point in the history
Version adapter and test fixes
  • Loading branch information
henriquegemignani committed Jul 22, 2024
2 parents 6c0e327 + d0e1b68 commit 600aeed
Show file tree
Hide file tree
Showing 64 changed files with 878 additions and 361 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Construct type definitions for Mercury Engine
| BLSND | ✓ | ✓ | ✓ | ✓ |
| BLUT | Missing | Missing | ✗ | ✗ |
| BMBLS | Missing | Missing | ✓ | ✓ |
| BMDEFS | ✓ | ✓ | ✗ | ✗ |
| BMDEFS | ✓ | ✓ | ✓ | ✓ |
| BMMAP | Missing | Missing | ✓ | ✓ |
| BMMDEF | Missing | Missing | ✓ | ✓ |
| BMSAD | ✓ | ✓ | ✓ | ✓ |
Expand Down
30 changes: 30 additions & 0 deletions src/mercury_engine_data_structures/common_types.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import copy
import functools
import struct
import typing

import construct
Expand All @@ -19,6 +20,35 @@
CVector3D = construct.Array(3, Float)
CVector4D = construct.Array(4, Float)

class VersionAdapter(Adapter):
def __init__(self, value: int | str | tuple[int, int, int] | None = None):
if isinstance(value, str):
value = tuple([int(i) for i in value.split(".")])
elif isinstance(value, int):
value = struct.pack("<I", value)
value = struct.unpack("<HBB", value)

if value is None:
subcon = construct.Struct(major=construct.Int16ul, minor=construct.Int8ul, patch=construct.Int8ul)
else:
major, minor, patch = value
subcon = construct.Struct(
major = construct.Const(major, construct.Int16ul),
minor = construct.Const(minor, construct.Int8ul),
patch = construct.Const(patch, construct.Int8ul)
)
super().__init__(subcon)

def _decode(self, obj, context, path):
return f"{obj.major}.{obj.minor}.{obj.patch}"

def _encode(self, obj, context, path):
lst = [int(i) for i in obj.split(".")]
return {
"major": lst[0],
"minor": lst[1],
"patch": lst[2]
}

def _cvector_emitparse(length: int, code: construct.CodeGen) -> str:
"""Specialized construct compile for CVector2/3/4D"""
Expand Down
10 changes: 10 additions & 0 deletions src/mercury_engine_data_structures/dread_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,13 @@ def all_property_id_to_name() -> Dict[int, str]:
asset_id: name
for name, asset_id in names.items()
}

def all_files_ending_with(ext: str, exclusions: Optional[list[str]] = None) -> list[str]:
if not ext.startswith("."):
ext = "." + ext

if exclusions is None:
exclusions = []

return [name for name in all_name_to_asset_id().keys()
if name.endswith(ext) and name not in exclusions]
2 changes: 1 addition & 1 deletion src/mercury_engine_data_structures/formats/bapd.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from mercury_engine_data_structures.formats.standard_format import game_model
from mercury_engine_data_structures.game_check import Game

BAPD = game_model('sound::CAudioPresets', 0x02030002)
BAPD = game_model('sound::CAudioPresets', "2.3.2")


class Bapd(BaseResource):
Expand Down
2 changes: 1 addition & 1 deletion src/mercury_engine_data_structures/formats/bldef.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class Bldef(BaseResource):
@classmethod
def construct_class(cls, target_game: Game) -> Construct:
return standard_format.game_model('CLightManager', 0x02000001)
return standard_format.game_model('CLightManager', "1.0.2")

@property
def lightdefs(self) -> Container:
Expand Down
7 changes: 3 additions & 4 deletions src/mercury_engine_data_structures/formats/blsnd.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,21 @@
from construct.core import (
Const,
Construct,
Hex,
IfThenElse,
Int32ul,
Struct,
)

from mercury_engine_data_structures.common_types import StrId, make_vector
from mercury_engine_data_structures.common_types import StrId, VersionAdapter, make_vector
from mercury_engine_data_structures.formats.base_resource import BaseResource
from mercury_engine_data_structures.game_check import Game, current_game_at_most

BLSND = Struct(
"_magic" / Const(b"LSND"),
"version" / IfThenElse(
current_game_at_most(Game.SAMUS_RETURNS),
Const(0x000B0001, Hex(Int32ul)),
Const(0x000C0001, Hex(Int32ul))
VersionAdapter("1.11.0"),
VersionAdapter("1.12.0")
),
"unk" / Int32ul,
"sound_limits" / make_vector(Struct(
Expand Down
2 changes: 1 addition & 1 deletion src/mercury_engine_data_structures/formats/bmbls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from mercury_engine_data_structures.formats.base_resource import BaseResource
from mercury_engine_data_structures.game_check import Game

BMBLS = standard_format.create('base::animation::CBlendSpaceResource', 0x02020001)
BMBLS = standard_format.create('base::animation::CBlendSpaceResource', "1.2.2")


class Bmbls(BaseResource):
Expand Down
12 changes: 7 additions & 5 deletions src/mercury_engine_data_structures/formats/bmdefs.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
Construct,
Flag,
Float32l,
Int16ul,
Int32ul,
Struct,
)

from mercury_engine_data_structures.common_types import StrId, make_vector
from mercury_engine_data_structures.common_types import StrId, VersionAdapter, make_vector
from mercury_engine_data_structures.formats import standard_format
from mercury_engine_data_structures.formats.base_resource import BaseResource
from mercury_engine_data_structures.game_check import Game

Expand Down Expand Up @@ -67,8 +67,7 @@

BMDEFS = Struct(
_magic=Const(b"MDEF"),
major_version=Int16ul,
minor_version=Int16ul,
version=VersionAdapter("1.5.0"),
unk1=Int32ul,
sounds=make_vector(Struct(
"sound_name" / StrId,
Expand All @@ -92,4 +91,7 @@
class Bmdefs(BaseResource):
@classmethod
def construct_class(cls, target_game: Game) -> Construct:
return BMDEFS
if target_game == Game.SAMUS_RETURNS:
return BMDEFS
else:
return standard_format.game_model("sound::CMusicManager", "4.0.2")
2 changes: 1 addition & 1 deletion src/mercury_engine_data_structures/formats/bmmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from mercury_engine_data_structures.formats.base_resource import BaseResource
from mercury_engine_data_structures.game_check import Game

BMMAP = standard_format.create('CMinimapData', 0x02000001)
BMMAP = standard_format.create('CMinimapData', "1.0.2")


class Bmmap(BaseResource):
Expand Down
2 changes: 1 addition & 1 deletion src/mercury_engine_data_structures/formats/bmmdef.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from mercury_engine_data_structures.formats.base_resource import BaseResource
from mercury_engine_data_structures.game_check import Game

BMMDEF = standard_format.create('CMinimapDef', 0x02000001)
BMMDEF = standard_format.create('CMinimapDef', "1.0.2")


class Bmmdef(BaseResource):
Expand Down
14 changes: 11 additions & 3 deletions src/mercury_engine_data_structures/formats/bmsad.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,15 @@
from construct.lib.containers import Container, ListContainer

from mercury_engine_data_structures import common_types, type_lib
from mercury_engine_data_structures.common_types import Char, CVector3D, Float, StrId, make_dict, make_vector
from mercury_engine_data_structures.common_types import (
Char,
CVector3D,
Float,
StrId,
VersionAdapter,
make_dict,
make_vector,
)
from mercury_engine_data_structures.construct_extensions.alignment import PrefixedAllowZeroLen
from mercury_engine_data_structures.construct_extensions.function_complex import ComplexIf, SwitchComplexKey
from mercury_engine_data_structures.construct_extensions.misc import ErrorWithMessage
Expand Down Expand Up @@ -320,7 +328,7 @@ def _not_implemented(code):
# BMSAD
BMSAD_SR = Struct(
"_magic" / Const(b"MSAD"),
"version" / Const(0x002C0001, Hex(Int32ul)),
"version" / VersionAdapter("1.44.0"),

"name" / StrId,

Expand Down Expand Up @@ -349,7 +357,7 @@ def _not_implemented(code):

BMSAD_Dread = Struct(
"_magic" / Const(b"MSAD"),
"version" / Const(0x0200000F, Hex(Int32ul)),
"version" / VersionAdapter("15.0.2"),

"name" / StrId,
"type" / StrId,
Expand Down
4 changes: 2 additions & 2 deletions src/mercury_engine_data_structures/formats/bmsas.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
Switch,
)

from mercury_engine_data_structures.common_types import Char, CVector3D, DictAdapter, Float, make_vector
from mercury_engine_data_structures.common_types import Char, CVector3D, DictAdapter, Float, VersionAdapter, make_vector
from mercury_engine_data_structures.common_types import StrId as StrIdSR
from mercury_engine_data_structures.construct_extensions.strings import PascalStringRobust
from mercury_engine_data_structures.formats.base_resource import BaseResource
Expand Down Expand Up @@ -266,7 +266,7 @@ def build_arg_list_sr(obj_data: dict, io, this):

BMSAS_Dread = Struct(
_magic=Const(b"MSAS"),
_version=Const(0x00170003, Hex(Int32ul)),
_version=VersionAdapter("3.23.0"),
name=StrId,
unk=Hex(Int32ul),
animations=make_vector(AnimationDread),
Expand Down
5 changes: 2 additions & 3 deletions src/mercury_engine_data_structures/formats/bmsbk.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@
Container,
Flag,
Float32l,
Hex,
Int32ul,
Rebuild,
Struct,
Terminated,
)

from mercury_engine_data_structures.common_types import CVector3D, StrId, make_vector
from mercury_engine_data_structures.common_types import CVector3D, StrId, VersionAdapter, make_vector
from mercury_engine_data_structures.formats.base_resource import BaseResource
from mercury_engine_data_structures.game_check import Game

Expand Down Expand Up @@ -45,7 +44,7 @@ def _rebuild_types(ctx: Container) -> int:

BMSBK = Struct(
"magic" / Const(b"MSBK"),
"version" / Hex(Int32ul),
"version" / VersionAdapter(),
"block_groups" / make_vector(BlockGroup),
"collision_cameras" / make_vector(Struct(
"name" / StrId,
Expand Down
7 changes: 3 additions & 4 deletions src/mercury_engine_data_structures/formats/bmscc.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
Const,
Construct,
GreedyBytes,
Hex,
IfThenElse,
Int8ul,
Int16ul,
Expand All @@ -12,7 +11,7 @@
)

from mercury_engine_data_structures import game_check
from mercury_engine_data_structures.common_types import StrId, UInt, make_vector
from mercury_engine_data_structures.common_types import StrId, VersionAdapter, make_vector
from mercury_engine_data_structures.construct_extensions.misc import ErrorWithMessage
from mercury_engine_data_structures.formats.base_resource import BaseResource
from mercury_engine_data_structures.formats.collision import collision_formats
Expand Down Expand Up @@ -47,8 +46,8 @@
_magic=Const(b"MSCD"),
_version=IfThenElse(
game_check.current_game_at_most(Game.SAMUS_RETURNS),
Const(0x000D0001, Hex(UInt)),
Const(0x00100001, Hex(UInt)),
VersionAdapter("1.14.0"),
VersionAdapter("1.16.0"),
),
layers=make_vector(CollisionLayer),
eof=GreedyBytes,
Expand Down
2 changes: 1 addition & 1 deletion src/mercury_engine_data_structures/formats/bmscu.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from mercury_engine_data_structures.formats.base_resource import BaseResource
from mercury_engine_data_structures.game_check import Game

BMSCU = standard_format.create('CCutSceneDef', 0x02030008)
BMSCU = standard_format.create('CCutSceneDef', "8.3.2")


class Bmscu(BaseResource):
Expand Down
5 changes: 2 additions & 3 deletions src/mercury_engine_data_structures/formats/bmsem.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@
Const,
Construct,
Float32l,
Hex,
Int32ul,
Struct,
)

from mercury_engine_data_structures.common_types import StrId, make_vector
from mercury_engine_data_structures.common_types import StrId, VersionAdapter, make_vector
from mercury_engine_data_structures.formats.base_resource import BaseResource
from mercury_engine_data_structures.game_check import Game

BMSEM = Struct(
_magic=Const(b"MSEM"),
_version=Const(0x00030001, Hex(Int32ul)),
_version=VersionAdapter("1.3.0"),
groups=make_vector(Struct(
"group_name" / StrId,
"layers" / make_vector(Struct(
Expand Down
6 changes: 2 additions & 4 deletions src/mercury_engine_data_structures/formats/bmses.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,17 @@
Const,
Construct,
Float32l,
Hex,
Int32sl,
Int32ul,
Struct,
)

from mercury_engine_data_structures.common_types import StrId, make_vector
from mercury_engine_data_structures.common_types import StrId, VersionAdapter, make_vector
from mercury_engine_data_structures.formats.base_resource import BaseResource
from mercury_engine_data_structures.game_check import Game

BMSES = Struct(
"_magic" / Const(b"MSES"),
"version" / Const(0x00050001, Hex(Int32ul)),
"version" / VersionAdapter("1.5.0"),
"sounds" / make_vector(Struct(
"name" / StrId,
"sound_file" / StrId,
Expand Down
4 changes: 2 additions & 2 deletions src/mercury_engine_data_structures/formats/bmsld.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import construct
from construct import Const, Construct, Container, Flag, Float32l, Hex, Int32ul, Struct, Switch

from mercury_engine_data_structures.common_types import CVector3D, Float, StrId, make_dict, make_vector
from mercury_engine_data_structures.common_types import CVector3D, Float, StrId, VersionAdapter, make_dict, make_vector
from mercury_engine_data_structures.construct_extensions.misc import ErrorWithMessage
from mercury_engine_data_structures.construct_extensions.strings import StaticPaddedString
from mercury_engine_data_structures.crc import crc32
Expand Down Expand Up @@ -81,7 +81,7 @@

BMSLD = Struct(
_magic=Const(b"MSLD"),
version=Const(0x00140001, Hex(Int32ul)),
version=VersionAdapter("1.20.0"),

unk1=Int32ul,
unk2=Int32ul,
Expand Down
2 changes: 1 addition & 1 deletion src/mercury_engine_data_structures/formats/bmslgroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from mercury_engine_data_structures.formats.base_resource import BaseResource
from mercury_engine_data_structures.game_check import Game

BMSLGROUP = standard_format.create('navmesh::CDynamicSmartLinkGroup', 0x02000001)
BMSLGROUP = standard_format.create('navmesh::CDynamicSmartLinkGroup', "1.0.2")


class Bmslgroup(BaseResource):
Expand Down
5 changes: 2 additions & 3 deletions src/mercury_engine_data_structures/formats/bmslink.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
from construct.core import (
Byte,
Const,
Hex,
Int32ul,
LazyBound,
PrefixedArray,
Struct,
)

from mercury_engine_data_structures.common_types import Float, StrId
from mercury_engine_data_structures.common_types import Float, StrId, VersionAdapter
from mercury_engine_data_structures.formats.base_resource import BaseResource
from mercury_engine_data_structures.game_check import Game

Expand Down Expand Up @@ -54,7 +53,7 @@

BMSLINK = Struct(
_magic = Const(b"LINK"),
version = Const(0x001F0001, Hex(Int32ul)),
version = VersionAdapter("1.31.0"),

unk_bool = Byte,
location = LocationStruct,
Expand Down
4 changes: 2 additions & 2 deletions src/mercury_engine_data_structures/formats/bmsmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
Struct,
)

from mercury_engine_data_structures.common_types import StrId, make_vector
from mercury_engine_data_structures.common_types import StrId, VersionAdapter, make_vector
from mercury_engine_data_structures.formats.base_resource import BaseResource
from mercury_engine_data_structures.game_check import Game

BMSMD = Struct(
"_magic" / Const(b"MSMD"),
"version" / Const(0x000D0001, Hex(Int32ul)),
"version" / VersionAdapter("1.13.0"),
"map_data" / make_vector(Struct(
"icon" / StrId,
"scenarios" / make_vector(Struct(
Expand Down
Loading

0 comments on commit 600aeed

Please sign in to comment.