Skip to content

Commit

Permalink
headers: export enums into headers
Browse files Browse the repository at this point in the history
  • Loading branch information
bwrsandman committed Sep 28, 2024
1 parent e43e857 commit 179d5b5
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 9 deletions.
65 changes: 57 additions & 8 deletions scripts/headers/bw1_decomp_gen/generate_headers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import time
import shutil
import string
import sys
from typing import Optional
from clang import cindex
from json import load
from pathlib import Path
Expand Down Expand Up @@ -153,23 +155,59 @@ def batched_arg_to_csnake(type_decls):
], remainder_functions)

object_file_base_names = get_object_file_base_names()
object_file_base_names_lower = {str.lower(i): i for i in object_file_base_names}

def is_header_struct_name(type_name) -> bool:
def get_header_struct_name_key(type_name) -> Optional[str]:
roomate_class_name = roomate_classes.get(type_name, type_name)
if roomate_class_name[0] == 'G' and roomate_class_name[1].isupper():
roomate_class_name = roomate_class_name[1:]
if roomate_class_name in object_file_base_names:
return True
return False
result = object_file_base_names_lower.get(roomate_class_name.lower())
if result is not None:
return result
if roomate_class_name[-1].lower() == 's':
result = object_file_base_names_lower.get(roomate_class_name[:-1].lower())
if result is not None:
return result
return None

def is_header_struct(data_type) -> bool:
if type(data_type) is Struct and data_type.members and data_type.members[0].name in ["vftable", "super", "base"]:
return True
if type(data_type) is Struct or type(data_type) is Union:
if is_header_struct_name(data_type.name):
if get_header_struct_name_key(data_type.name) is not None:
return True
return False

def enum_name_to_potential_header_struct_name(type_name: str, num_stripped_suffixes) -> Optional[str]:
if type_name.count("_") < num_stripped_suffixes:
return None
if num_stripped_suffixes == 0:
if type_name in roomate_classes:
return roomate_classes[type_name]
return string.capwords(type_name).replace("_", "")
return "".join(map(string.capwords, type_name.split("_")[:-num_stripped_suffixes]))

def get_enum_header_name_key(data_type) -> Optional[str]:
if type(data_type) is not Enum:
return None

for num_stripped_suffixes in range(0, 3):
camels = list(filter(None, (
enum_name_to_potential_header_struct_name(data_type.name, num_stripped_suffixes),
enum_name_to_potential_header_struct_name(data_type.name.removeprefix("LH_").removeprefix("LH").removesuffix("Enum").removesuffix("_t"), num_stripped_suffixes),
enum_name_to_potential_header_struct_name(f"LH_{data_type.name}", num_stripped_suffixes),
enum_name_to_potential_header_struct_name(f"LH3D_{data_type.name}", num_stripped_suffixes),
enum_name_to_potential_header_struct_name(data_type.name.replace("_TYPE", "_INFO"), num_stripped_suffixes),
enum_name_to_potential_header_struct_name(data_type.name.split("__")[0], num_stripped_suffixes),
)))
if not camels:
break
for camel in camels:
header_name = get_header_struct_name_key(camel)
if header_name is not None:
return header_name
return None

def is_ignore_struct(data_type) -> bool:
if type(data_type) is Struct or type(data_type) is Typedef:
if data_type.name.startswith("RTTI"):
Expand All @@ -185,7 +223,8 @@ def is_ignore_struct(data_type) -> bool:
bases,
vftable_function_prototypes,
header_structs,
enums,
header_enums,
remainder_enums,
lh_linked_pointer_lists,
lh_linked_lists,
lh_list_heads,
Expand All @@ -199,11 +238,12 @@ def is_ignore_struct(data_type) -> bool:
lambda x: type(x) is Union and x.name.endswith('Base'),
lambda x: type(x) is FuncPtr and ('Vftable__' in x.name or x.name.startswith('vt_')),
is_header_struct,
lambda x: type(x) is Enum and get_enum_header_name_key(x) is not None,
lambda x: type(x) is Enum,
lambda x: type(x) is Struct and x.name.startswith("LHLinkedList__p_") or x.name.startswith("LHLinkedNode__p_"),
lambda x: type(x) is Struct and x.name.startswith("LHLinkedList__") or x.name.startswith("LHLinkedNode__"),
lambda x: type(x) is Struct and x.name.startswith("LHListHead__"),
lambda x: type(x) is FuncPtr and "__" in x.name and is_header_struct_name(x.name[::-1].split("__")[-1][::-1]),
lambda x: type(x) is FuncPtr and "__" in x.name and get_header_struct_name_key(x.name[::-1].split("__")[-1][::-1]) is not None,
is_ignore_struct,
lambda x: type(x) is Struct,
], primitives)
Expand Down Expand Up @@ -246,6 +286,14 @@ def get_path(name):
local_header_import_map: dict[str, str] = {}
header_map: dict[Path, Header] = {}

for e in header_enums:
path = get_path(get_enum_header_name_key(e))
header = header_map.get(path)
structs: list[Struct] = header.structs if header is not None else []
structs.append(e)
header = Header(path, [], structs)
header_map[path] = header

for t in member_function_pointers:
struct_name = t.name[::-1].split("__")[-1][::-1]
path = get_path(roomate_classes.get(struct_name, struct_name))
Expand Down Expand Up @@ -354,8 +402,9 @@ def get_path(name):
print(f"Ignored {len(to_ignore)} entries")
print(f"Took {toc - tic:0.4f} seconds")

if len(remainder_functions) + len(remainder_primitives) + len(remainder) > 0:
if len(remainder_functions) + len(remainder_primitives) + len(remainder_enums) + len(remainder) > 0:
print(f"There are still {len(remainder_functions)} orphan functions: [{", ".join([i.name for i in remainder_functions][:10])}{", ..." if len(remainder_functions) > 10 else ""}]")
print(f"There are still {len(remainder_primitives)} orphan structs: [{", ".join([i.name for i in remainder_primitives][:10])}{", ..." if len(remainder_primitives) > 10 else ""}]")
print(f"There are still {len(remainder_enums)} orphan enums: [{", ".join([i.name for i in remainder_enums][:10])}{", ..." if len(remainder_enums) > 10 else ""}]")
print(f"There are still {len(remainder)} orphan entries: [{", ".join([i.name for i in remainder][:10])}{", ..." if len(remainder) > 10 else ""}]")
exit(1)
6 changes: 5 additions & 1 deletion scripts/headers/bw1_decomp_gen/structs.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ class Enum:
def decorated_name(self):
return f"enum {self.name}"

def get_types(self) -> set[str]:
result = {self.name}
return result

@classmethod
def from_json(cls, decl: dict) -> "Enum":
name = extract_type_name(decl['type'])
Expand All @@ -158,7 +162,7 @@ def from_json(cls, decl: dict) -> "Enum":
def to_csnake(self) -> csnake.Enum:
result = csnake.Enum(self.name, typedef=False)
for v in self.values:
result.add_variable(*v)
result.add_value(*v)
return result

def to_code(self, cw: csnake.CodeWriter):
Expand Down
58 changes: 58 additions & 0 deletions scripts/headers/bw1_decomp_gen/vanilla_filepaths.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,8 @@
BWPath(r"C:\dev\Libs\LIONHEAD\LHMultiplayer\VER4.0\LHPacket.h"),

BWPath(r"C:\Dev\Libs\lionhead\lhlib\VER5.0\Name.h"),
BWPath(r"C:\Dev\Libs\lionhead\lhlib\VER5.0\LHKey.h"),
BWPath(r"C:\Dev\Libs\lionhead\lhlib\VER5.0\LHReturn.h"),
BWPath(r"C:\Dev\Libs\lionhead\lhlib\VER5.0\Random.h"),

BWPath(r"C:\DEV\LIBS\LHALL\RELEASED\HEADERS\VisitBlock.h"),
Expand Down Expand Up @@ -630,6 +632,7 @@
BWPath(r"C:\Dev\black\DrawingObject.h"),
BWPath(r"C:\Dev\black\EffectValues.h"),
BWPath(r"C:\Dev\black\EarthQuake.h"),
BWPath(r"C:\Dev\black\Flower.h"),
BWPath(r"C:\Dev\black\FixedObject.h"),
BWPath(r"C:\Dev\black\FrontEnd.h"),
BWPath(r"C:\Dev\black\AbodeInfo.h"),
Expand Down Expand Up @@ -684,6 +687,8 @@
BWPath(r"C:\Dev\black\MobileWallHugInfo.h"),
BWPath(r"C:\Dev\black\MultiMapFixedInfo.h"),
BWPath(r"C:\Dev\black\ObjectInfo.h"),
BWPath(r"C:\Dev\black\PlaytimeInfo.h"),
BWPath(r"C:\Dev\black\Playtime.h"),
BWPath(r"C:\Dev\black\PlayerInfo.h"),
BWPath(r"C:\Dev\black\PrayerIconInfo.h"),
BWPath(r"C:\Dev\black\PuzzleGame.h"),
Expand Down Expand Up @@ -717,6 +722,7 @@
BWPath(r"C:\Dev\black\HandStateTotem.h"),
BWPath(r"C:\Dev\black\HandStateTug.h"),
BWPath(r"C:\Dev\black\HelpTextDataBase.h"),
BWPath(r"C:\Dev\black\HelpSpritesGuidance.h"),
BWPath(r"C:\Dev\black\InnerCamera.h"),
BWPath(r"C:\Dev\black\InterfaceHandState.h"),
BWPath(r"C:\Dev\black\Landscape.h"),
Expand Down Expand Up @@ -770,11 +776,13 @@
BWPath(r"C:\Dev\black\SpellSeedGraphic.h"),
BWPath(r"C:\Dev\black\SpellWater.h"),
BWPath(r"C:\Dev\black\SpellWithObjects.h"),
BWPath(r"C:\dev\black\SpookyVoicesInfo.h"),
BWPath(r"C:\dev\Black\StandardBuildingSite.h"),
BWPath(r"C:\Dev\black\StartGameBox.h"),
BWPath(r"C:\Dev\black\StatsDatabase.h"),
BWPath(r"C:\Dev\black\TerrainMapInfo.h"),
BWPath(r"C:\Dev\black\TerrainMapTypeInfo.h"),
BWPath(r"C:\Dev\black\ToolTipsInfo.h"),
BWPath(r"C:\Dev\black\TownCentreSpellIcon.h"),
BWPath(r"C:\Dev\black\TownDesireFlags.h"),
BWPath(r"C:\Dev\black\TownStats.h"),
Expand Down Expand Up @@ -943,6 +951,56 @@
"LHJoypads": "LHJoypad",
"FrameInfoLinkedList": "LHSystem",
"LHConvert": "LHSystem",
"VORTEX_STAT_TYPE": "LandscapeVortex",
"VORTEX_STATE_TYPE": "LandscapeVortex",
"VORTEX_TYPE": "LandscapeVortex",
"RenderParticle": "PSysRenderParticle",
"PARTICLE_TYPE": "PSysInterface",
"HIGHLIGHT_INFO": "ScriptHighlight",
"RESOURCE_TYPE": "GameThing",
"FOOD_TYPE": "Object",
"SEX_TYPE": "Villager",
"CARRIED_OBJECT": "Villager",
"CARRIED_TREE_TYPE": "Villager",
"DEATH_REASON": "GameThingWithPos",
"DISCRETE_ALIGNMENT_VALUES": "Alignment",
"ObjectCircleIteratorDirection": "Collide",
"HOLD_TYPE": "Object",
"WALL_SECTION_TYPE": "MobileWallHug",
"MOVE_TO_STATES": "MobileWallHug",
"LEADER_ANIMATION": "GroupBehaviour",
"SEASON": "Weather",
"IMPRESSIVE_TYPE": "Reaction",
"DETECTED_PLAYER_ACTION": "Reaction",
"CAST_RULE_TYPE": "Spell",
"AUDIO_SFX_BANK_TYPE": "LHAudioSystem",
"LESSON_TYPE": "CreatureLessonChooser",
"SPEED_THRESHOLD": "Living",
"SPEED_MAX": "Living",
"SPEED_ID": "Living",
"TEXTJUSTIFY": "GatheringText",
"POWER_UP_TYPE": "TownArtifact",
"LANDED_TYPES": "Creature",
"MAGIC_LIVING_INFO": "SpecialVillager",
"GESTURE_TYPE": "GestureSystem",
"CREATURE_ISLES_BUILDINGS_INFO": "Abode",
"SOUND_COLLISION_TYPE": "SpookyVoicesInfo",
"SPOOKY_ENUM": "InterfaceCollide",
"DYK_CATEGORY": "ToolTipsInfo",
"IMMERSION_EFFECT_TYPE": "DialogBoxImmersion",
"TextureFormat_": "LH3DTexture",
"BBSTYLE": "SetupThing",
"CameraHelpReason": "CameraHelp",
"DETAIL_LEVEL": "LH3DRender",
"AnimInfoType": "LH3DAnim",
"LH_SEEK_MODE": "LHFile",
"LH_OPERATING_MODE": "LHLobby",
"LHKeyMod": "LHKey",
"GROUND_INFO": "Landscape",
"COUNTRY_LIST": "Landscape",
"VARIABLES": "Game",
"MISC_INFO": "Game",
"LOADER_VERSIONS": "PCMain",
}

unportable_dev_filepaths = released_filepaths_from_strings.union(guessed_filepaths)
Expand Down

0 comments on commit 179d5b5

Please sign in to comment.