From 7aeffc76ff637c64eb444902925cfe0f2c993128 Mon Sep 17 00:00:00 2001 From: Jeod <47716344+JeodC@users.noreply.github.com> Date: Sat, 10 Jan 2026 09:30:03 -0500 Subject: [PATCH 1/2] Find audiogroups by filename in AGRP chunk In later GM versions, audiogroup filenames can be customized. For example, in MADHOUSE the audiogroups are named agBGM.dat, agSFX.dat, etc. --- Klib/GMblob.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/Klib/GMblob.py b/Klib/GMblob.py index 9b2f854..093e238 100644 --- a/Klib/GMblob.py +++ b/Klib/GMblob.py @@ -120,6 +120,8 @@ def _get_padding(self, alignement = 16): padding = alignement - misalignement return padding + + return self.get_str(name_str_offset) def _write_to_file_otherchunk(self,token): self.filein.seek(self.chunk_list[token]["offset"]) @@ -446,6 +448,32 @@ def get_str(self, str_offset): size = unpack('= nb_entries: + return None + + # Jump to the offset of the specific audiogroup entry + # AGRP Chunk: [4B Count] [4B Offset0] [4B Offset1] ... + self.filein.seek(self.chunk_list["AGRP"]["offset"] + 12 + (audiogroup_id * 4)) + entry_offset = unpack(' self.filein_size: + return None + + return self.get_str(name_str_offset) def __init_sond(self): self.filein.seek(self.chunk_list["SOND"]["offset"] + 8) @@ -512,7 +540,31 @@ def __init_sond(self): def __init_audiogroup_dat(self, audiogroup): if audiogroup > 0 and not f"{audiogroup}" in self.audiogroup_dat.keys(): - self.audiogroup_dat[f"{audiogroup}"] = GMaudiogroup(self.filein_path.parents[0] / f"audiogroup{audiogroup}.dat" , self.verbose, self.audiosettings, audiogroup) + # Get the real name from the AGRP chunk + ag_name = self.__get_audiogroup_filename(audiogroup) + + if not ag_name: + self._vprint(f"Warning: Could not resolve name for Audiogroup ID {audiogroup}") + return + + base_path = self.filein_path.parents[0] + # Some versions include the extension in the string, others don't. + # We check for both. + ag_path = base_path / ag_name + + if not ag_path.exists(): + # Try adding .dat if the string didn't have it + ag_path = base_path / f"{ag_name}.dat" + + if ag_path.exists(): + self.audiogroup_dat[f"{audiogroup}"] = GMaudiogroup( + ag_path, + self.verbose, + self.audiosettings, + audiogroup + ) + else: + self._vprint(f"Warning: File {ag_path.name} not found for group {ag_name}") def __sond_get_raw_entry(self,key): From f8d78a3d36bcad6e1f58810a3b829e2275415fc3 Mon Sep 17 00:00:00 2001 From: Jeod <47716344+JeodC@users.noreply.github.com> Date: Wed, 28 Jan 2026 07:14:04 -0500 Subject: [PATCH 2/2] Fallback to audiogroup idx if friendly name is not found --- Klib/GMblob.py | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/Klib/GMblob.py b/Klib/GMblob.py index 093e238..f922bee 100644 --- a/Klib/GMblob.py +++ b/Klib/GMblob.py @@ -540,23 +540,26 @@ def __init_sond(self): def __init_audiogroup_dat(self, audiogroup): if audiogroup > 0 and not f"{audiogroup}" in self.audiogroup_dat.keys(): - # Get the real name from the AGRP chunk + # 1. Get the internal friendly name ag_name = self.__get_audiogroup_filename(audiogroup) - - if not ag_name: - self._vprint(f"Warning: Could not resolve name for Audiogroup ID {audiogroup}") - return - base_path = self.filein_path.parents[0] - # Some versions include the extension in the string, others don't. - # We check for both. - ag_path = base_path / ag_name - if not ag_path.exists(): - # Try adding .dat if the string didn't have it - ag_path = base_path / f"{ag_name}.dat" - - if ag_path.exists(): + # Define potential filenames + potential_names = [ + ag_name, # Friendly name (e.g., Aud_SFX_Weapons) + f"{ag_name}.dat", # Friendly name + .dat + f"audiogroup{audiogroup}.dat" # Indexed name (e.g., audiogroup1.dat) + ] + + ag_path = None + for name in potential_names: + test_path = base_path / name + if test_path.exists(): + ag_path = test_path + break + + if ag_path: + self._vprint(f"[AGRP {audiogroup}] Found asset file: {ag_path.name}") self.audiogroup_dat[f"{audiogroup}"] = GMaudiogroup( ag_path, self.verbose, @@ -564,7 +567,8 @@ def __init_audiogroup_dat(self, audiogroup): audiogroup ) else: - self._vprint(f"Warning: File {ag_path.name} not found for group {ag_name}") + self._vprint(f"Warning: Could not find audio file for group '{ag_name}' " + f"(Tried: {', '.join(potential_names)})") def __sond_get_raw_entry(self,key):