splat64 0.35.1__py3-none-any.whl → 0.36.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
splat/__init__.py CHANGED
@@ -1,7 +1,7 @@
1
1
  __package_name__ = __name__
2
2
 
3
3
  # Should be synced with pyproject.toml
4
- __version__ = "0.35.1"
4
+ __version__ = "0.36.0"
5
5
  __author__ = "ethteck"
6
6
 
7
7
  from . import util as util
@@ -7,7 +7,7 @@ from typing import Set
7
7
 
8
8
  class SpimdisasmDisassembler(disassembler.Disassembler):
9
9
  # This value should be kept in sync with the version listed on requirements.txt and pyproject.toml
10
- SPIMDISASM_MIN = (1, 36, 0)
10
+ SPIMDISASM_MIN = (1, 36, 1)
11
11
 
12
12
  def configure(self):
13
13
  # Configure spimdisasm
@@ -286,6 +286,7 @@ options:
286
286
 
287
287
  find_file_boundaries: False
288
288
  gp_value: 0x{exe.initial_gp:08X}
289
+ # ld_gp_expression: main_SCOMMON_START + 0x7FF0
289
290
 
290
291
  o_as_suffix: True
291
292
  use_legacy_include_asm: False
@@ -309,6 +310,10 @@ options:
309
310
  data_string_encoding: ASCII
310
311
  rodata_string_guesser_level: 2
311
312
  data_string_guesser_level: 2
313
+
314
+ # Uncomment this line if you need to use the maspsx reorder workaround hack
315
+ # https://github.com/mkst/maspsx?tab=readme-ov-file#include_asm-reordering-workaround-hack
316
+ # include_asm_macro_style: maspsx_hack
312
317
  """
313
318
 
314
319
  segments = f"""\
@@ -1,4 +1,5 @@
1
1
  from pathlib import Path
2
+ import re
2
3
  from typing import Optional, TextIO
3
4
 
4
5
  from ...util import log, options
@@ -75,45 +76,66 @@ class CommonSegTextbin(CommonSegment):
75
76
 
76
77
  f.write(f"{self.get_section_asm_line()}\n\n")
77
78
 
79
+ sym_name = None
80
+ sym_name_end = None
81
+ sym_size_matches = None
82
+
78
83
  # Check if there's a symbol at this address
79
- sym = None
80
84
  vram = self.rom_to_ram(self.rom_start)
81
85
  if vram is not None:
82
86
  sym = self.get_symbol(vram, in_segment=True)
83
-
84
- if sym is not None:
85
- f.write(f"{asm_label} {sym.name}\n")
86
- if asm_label == ".globl":
87
- if self.is_text():
88
- f.write(f".ent {sym.name}\n")
89
- f.write(f"{sym.name}:\n")
90
- sym.defined = True
87
+ if sym is not None:
88
+ sym.defined = True
89
+ sym_name = sym.name
90
+ sym_name_end = sym.given_name_end
91
+ if (
92
+ sym.given_size is None
93
+ or sym.given_size == self.rom_end - self.rom_start
94
+ ):
95
+ sym_size_matches = self.rom_end - self.rom_start
96
+
97
+ if sym_name is None:
98
+ # Normalize stuff like slashes and such.
99
+ n = regex_sym_name_normalizer.sub("_", self.name)
100
+ if self.is_text():
101
+ suffix = "textbin"
102
+ elif self.is_data():
103
+ suffix = "databin"
104
+ elif self.is_rodata():
105
+ suffix = "rodatabin"
106
+ else:
107
+ suffix = "incbin"
108
+ sym_name = f"__{n}_{suffix}"
109
+
110
+ if options.opts.asm_nonmatching_label_macro != "":
111
+ siz = f", 0x{sym_size_matches:X}" if sym_size_matches is not None else ""
112
+ f.write(f"{options.opts.asm_nonmatching_label_macro} {sym_name}{siz}\n\n")
113
+
114
+ f.write(f"{asm_label} {sym_name}\n")
115
+ if asm_label == ".globl":
116
+ if self.is_text():
117
+ f.write(f".ent {sym_name}\n")
118
+ f.write(f"{sym_name}:\n")
91
119
 
92
120
  f.write(f'.incbin "{binpath.as_posix()}"\n')
93
121
 
94
- if sym is not None:
95
- if options.opts.asm_emit_size_directive:
96
- f.write(f".size {sym.name}, . - {sym.name}\n")
122
+ if options.opts.asm_emit_size_directive:
123
+ f.write(f".size {sym_name}, . - {sym_name}\n")
97
124
 
98
- if self.is_text() and options.opts.asm_end_label != "":
99
- f.write(f"{options.opts.asm_end_label} {sym.name}\n")
100
- elif self.is_data() and options.opts.asm_data_end_label != "":
101
- f.write(f"{options.opts.asm_data_end_label} {sym.name}\n")
125
+ if self.is_text() and options.opts.asm_end_label != "":
126
+ f.write(f"{options.opts.asm_end_label} {sym_name}\n")
127
+ elif options.opts.asm_data_end_label != "":
128
+ f.write(f"{options.opts.asm_data_end_label} {sym_name}\n")
102
129
 
103
- if sym.given_name_end is not None:
104
- if (
105
- sym.given_size is None
106
- or sym.given_size == self.rom_end - self.rom_start
107
- ):
108
- f.write(f"{asm_label} {sym.given_name_end}\n")
109
- if asm_label == ".globl":
110
- f.write(f"{sym.given_name_end}:\n")
111
- if self.is_text() and options.opts.asm_end_label != "":
112
- f.write(f"{options.opts.asm_end_label} {sym.given_name_end}\n")
113
- elif self.is_data() and options.opts.asm_data_end_label != "":
114
- f.write(
115
- f"{options.opts.asm_data_end_label} {sym.given_name_end}\n"
116
- )
130
+ if sym_name_end is not None and sym_size_matches is not None:
131
+ f.write(f"{asm_label} {sym_name_end}\n")
132
+ if asm_label == ".globl":
133
+ f.write(f"{sym_name_end}:\n")
134
+
135
+ if self.is_text() and options.opts.asm_end_label != "":
136
+ f.write(f"{options.opts.asm_end_label} {sym_name_end}\n")
137
+ elif options.opts.asm_data_end_label != "":
138
+ f.write(f"{options.opts.asm_data_end_label} {sym_name_end}\n")
117
139
 
118
140
  def split(self, rom_bytes):
119
141
  if self.rom_end is None:
@@ -159,3 +181,6 @@ class CommonSegTextbin(CommonSegment):
159
181
  return (
160
182
  self.extract and self.should_scan()
161
183
  ) # only split if the segment was scanned first
184
+
185
+
186
+ regex_sym_name_normalizer = re.compile(r"[^0-9a-zA-Z_]")
@@ -204,8 +204,10 @@ class LinkerWriter:
204
204
  if not self.is_partial:
205
205
  self._writeln(f"__romPos = {options.opts.ld_rom_start};")
206
206
 
207
- if options.opts.gp is not None:
208
- self._writeln("_gp = " + f"0x{options.opts.gp:X};")
207
+ if options.opts.ld_gp_expression is not None:
208
+ self._writeln(f"_gp = {options.opts.ld_gp_expression};")
209
+ elif options.opts.gp is not None:
210
+ self._writeln(f"_gp = 0x{options.opts.gp:X};")
209
211
 
210
212
  # Write a series of statements which compute a symbol that represents the highest address among a list of segments' end addresses
211
213
  def write_max_vram_end_sym(self, symbol: str, overlays: List[Segment]):
splat/segtypes/n64/i1.py CHANGED
@@ -1,9 +1,9 @@
1
- import n64img.image
2
-
3
- from .img import N64SegImg
4
-
5
-
6
- class N64SegI1(N64SegImg):
7
- def __init__(self, *args, **kwargs):
8
- kwargs["img_cls"] = n64img.image.I1
9
- super().__init__(*args, **kwargs)
1
+ import n64img.image
2
+
3
+ from .img import N64SegImg
4
+
5
+
6
+ class N64SegI1(N64SegImg):
7
+ def __init__(self, *args, **kwargs):
8
+ kwargs["img_cls"] = n64img.image.I1
9
+ super().__init__(*args, **kwargs)
@@ -14,6 +14,9 @@ from . import options, log
14
14
 
15
15
 
16
16
  def write_all_files():
17
+ if not options.opts.generate_asm_macros_files:
18
+ return
19
+
17
20
  write_include_asm_h()
18
21
  write_assembly_inc_files()
19
22
 
@@ -30,13 +33,23 @@ def write_include_asm_h():
30
33
  # These compilers do not use the `INCLUDE_ASM` macro.
31
34
  return
32
35
 
33
- file_data = """\
34
- #ifndef INCLUDE_ASM_H
35
- #define INCLUDE_ASM_H
36
-
37
- #if !defined(M2CTX) && !defined(PERMUTER)
38
-
39
- #ifndef INCLUDE_ASM
36
+ if options.opts.include_asm_macro_style == "maspsx_hack":
37
+ include_asm_macro = """\
38
+ #define INCLUDE_ASM(FOLDER, NAME) \\
39
+ void __maspsx_include_asm_hack_##NAME() { \\
40
+ __asm__( \\
41
+ ".text # maspsx-keep \\n" \\
42
+ " .align 2 # maspsx-keep\\n" \\
43
+ " .set noat # maspsx-keep\\n" \\
44
+ " .set noreorder # maspsx-keep\\n" \\
45
+ " .include \\"" FOLDER "/" #NAME ".s\\" # maspsx-keep\\n" \\
46
+ " .set reorder # maspsx-keep\\n" \\
47
+ " .set at # maspsx-keep\\n" \\
48
+ ); \\
49
+ }
50
+ """
51
+ else: # default
52
+ include_asm_macro = """\
40
53
  #define INCLUDE_ASM(FOLDER, NAME) \\
41
54
  __asm__( \\
42
55
  ".section .text\\n" \\
@@ -46,14 +59,28 @@ def write_include_asm_h():
46
59
  " .set reorder\\n" \\
47
60
  " .set at\\n" \\
48
61
  )
49
- #endif
50
- #ifndef INCLUDE_RODATA
62
+ """
63
+
64
+ include_rodata_macro = """\
51
65
  #define INCLUDE_RODATA(FOLDER, NAME) \\
52
66
  __asm__( \\
53
67
  ".section .rodata\\n" \\
54
68
  " .include \\"" FOLDER "/" #NAME ".s\\"\\n" \\
55
69
  ".section .text" \\
56
70
  )
71
+ """
72
+
73
+ file_data = f"""\
74
+ #ifndef INCLUDE_ASM_H
75
+ #define INCLUDE_ASM_H
76
+
77
+ #if !defined(M2CTX) && !defined(PERMUTER)
78
+
79
+ #ifndef INCLUDE_ASM
80
+ {include_asm_macro}\
81
+ #endif
82
+ #ifndef INCLUDE_RODATA
83
+ {include_rodata_macro}\
57
84
  #endif
58
85
  __asm__(".include \\"include/labels.inc\\"\\n");
59
86
 
@@ -126,14 +153,14 @@ def write_assembly_inc_files():
126
153
  # A label referenced by a jumptable.
127
154
  .macro {options.opts.asm_jtbl_label_macro} label, visibility=global
128
155
  .\\visibility \\label
129
- .type \\label, @function
130
156
  \\label:
131
157
  .endm
132
158
  """
133
159
  if options.opts.migrate_rodata_to_functions:
134
160
  jlabel_macro_labelsinc = f"""
135
161
  # A label referenced by a jumptable.
136
- .macro {options.opts.asm_jtbl_label_macro} label, visibility=global
162
+ .macro {options.opts.asm_jtbl_label_macro} label, visibility=local
163
+ .\\visibility \\label
137
164
  \\label:
138
165
  .endm
139
166
  """
@@ -176,12 +203,6 @@ def write_assembly_inc_files():
176
203
  .endm
177
204
  """
178
205
 
179
- labels_inc = f"""\
180
- {func_macros}
181
- {jlabel_macro_labelsinc}
182
- {data_macros}
183
- {nm_macros}\
184
- """
185
206
  macros_inc = f"""\
186
207
  {func_macros}
187
208
  {jlabel_macro_macroinc}
@@ -195,7 +216,15 @@ def write_assembly_inc_files():
195
216
 
196
217
  if options.opts.platform == "psx":
197
218
  preamble += '\n.include "gte_macros.inc"\n'
198
- _write("include/labels.inc", f"{preamble}\n{labels_inc}")
219
+
220
+ labels_inc = f"""\
221
+ {preamble}
222
+ {func_macros}
223
+ {jlabel_macro_labelsinc}
224
+ {data_macros}
225
+ {nm_macros}\
226
+ """
227
+ _write("include/labels.inc", labels_inc)
199
228
 
200
229
  if options.opts.platform in {"n64", "psx"}:
201
230
  gas = macros_inc
@@ -294,6 +323,15 @@ def write_assembly_inc_files():
294
323
  preamble = (
295
324
  "# This file is used by modern gas.\n# Defines the expected assembly macros\n"
296
325
  )
326
+ gas = f"""\
327
+ # Evaluate this file only once in case it's included more than once
328
+ .ifndef _MACRO_INC_GUARD
329
+ .internal _MACRO_INC_GUARD
330
+ .set _MACRO_INC_GUARD, 1
331
+
332
+ {gas}
333
+ .endif
334
+ """
297
335
  _write("include/macro.inc", f"{preamble}\n{gas}")
298
336
 
299
337
 
splat/util/options.py CHANGED
@@ -37,7 +37,12 @@ class SplatOpts:
37
37
  generated_s_preamble: str
38
38
  # Determines any extra content to be added in the generated macro.inc file
39
39
  generated_macro_inc_content: Optional[str]
40
+ # Determines if files related to assembly macros should be regenerated by splat
40
41
  generate_asm_macros_files: bool
42
+ # Changes the definition of the generated `INCLUDE_ASM`.
43
+ # default: The default one.
44
+ # maspsx_hack: Use the maspsx hack workaround definition https://github.com/mkst/maspsx?tab=readme-ov-file#include_asm-reordering-workaround-hack
45
+ include_asm_macro_style: Literal["default", "maspsx_hack"]
41
46
  # Determines whether to use .o as the suffix for all binary files?... TODO document
42
47
  use_o_as_suffix: bool
43
48
  # the value of the $gp register to correctly calculate offset to %gp_rel relocs
@@ -150,6 +155,8 @@ class SplatOpts:
150
155
  ld_generate_symbol_per_data_segment: bool
151
156
  # Sets the default option for the `bss_contains_common` attribute of all segments.
152
157
  ld_bss_contains_common: bool
158
+ # Specify an expression to be used for the `_gp` symbol in the generated linker script instead of a hardcoded value.
159
+ ld_gp_expression: Optional[str]
153
160
 
154
161
  ################################################################################
155
162
  # C file options
@@ -400,6 +407,21 @@ def _parse_yaml(
400
407
  else:
401
408
  raise ValueError(f"Invalid endianness: {endianness}")
402
409
 
410
+ def parse_include_asm_macro_style() -> Literal["default", "maspsx_hack"]:
411
+ include_asm_macro_style = p.parse_opt_within(
412
+ "include_asm_macro_style",
413
+ str,
414
+ ["default", "maspsx_hack"],
415
+ "default",
416
+ )
417
+
418
+ if include_asm_macro_style == "default":
419
+ return "default"
420
+ elif include_asm_macro_style == "maspsx_hack":
421
+ return "maspsx_hack"
422
+ else:
423
+ raise ValueError(f"Invalid endianness: {include_asm_macro_style}")
424
+
403
425
  default_ld_bss_is_noload = True
404
426
  if platform == "psx":
405
427
  default_ld_bss_is_noload = False
@@ -431,6 +453,7 @@ def _parse_yaml(
431
453
  "generated_macro_inc_content", str
432
454
  ),
433
455
  generate_asm_macros_files=p.parse_opt("generate_asm_macros_files", bool, True),
456
+ include_asm_macro_style=parse_include_asm_macro_style(),
434
457
  use_o_as_suffix=p.parse_opt("o_as_suffix", bool, False),
435
458
  gp=p.parse_optional_opt("gp_value", int),
436
459
  check_consecutive_segment_types=p.parse_opt(
@@ -507,6 +530,9 @@ def _parse_yaml(
507
530
  "ld_generate_symbol_per_data_segment", bool, False
508
531
  ),
509
532
  ld_bss_contains_common=p.parse_opt("ld_bss_contains_common", bool, False),
533
+ ld_gp_expression=p.parse_optional_opt_with_default(
534
+ "ld_gp_expression", str, None
535
+ ),
510
536
  create_c_files=p.parse_opt("create_c_files", bool, True),
511
537
  auto_decompile_empty_functions=p.parse_opt(
512
538
  "auto_decompile_empty_functions", bool, True
splat/util/symbols.py CHANGED
@@ -192,6 +192,28 @@ def handle_sym_addrs(
192
192
  if attr_name == "function_owner":
193
193
  sym.function_owner = attr_val
194
194
  continue
195
+ if attr_name == "align":
196
+ align = int(attr_val, 0)
197
+
198
+ if align < 0:
199
+ log.parsing_error_preamble(path, line_num, line)
200
+ log.error(
201
+ f"The given alignment for '{sym.name}' (0x{sym.vram_start:08X}) is negative."
202
+ )
203
+ align_shift = (align & (-align)).bit_length() - 1
204
+ if (1 << align_shift) != align:
205
+ log.parsing_error_preamble(path, line_num, line)
206
+ log.error(
207
+ f"The given alignment '0x{align:X}' for symbol '{sym.name}' (0x{sym.vram_start:08X}) is not a power of two."
208
+ )
209
+ if sym.vram_start % align != 0:
210
+ log.parsing_error_preamble(path, line_num, line)
211
+ log.error(
212
+ f"The symbol '{sym.name}' (0x{sym.vram_start:08X}) is not aligned already to the given alignment '0x{align:X}'."
213
+ )
214
+
215
+ sym.given_align = align
216
+ continue
195
217
  except:
196
218
  log.parsing_error_preamble(path, line_num, line)
197
219
  log.write(
@@ -520,6 +542,8 @@ def add_symbol_to_spim_segment(
520
542
  context_sym.nameEnd = sym.given_name_end
521
543
  if sym.given_visibility:
522
544
  context_sym.visibility = sym.given_visibility
545
+ if sym.given_align:
546
+ context_sym.setAlignment(sym.given_align)
523
547
 
524
548
  return context_sym
525
549
 
@@ -568,6 +592,8 @@ def add_symbol_to_spim_section(
568
592
  context_sym.nameEnd = sym.given_name_end
569
593
  if sym.given_visibility:
570
594
  context_sym.visibility = sym.given_visibility
595
+ if sym.given_align:
596
+ context_sym.setAlignment(sym.given_align)
571
597
 
572
598
  return context_sym
573
599
 
@@ -667,6 +693,8 @@ class Symbol:
667
693
  given_filename: Optional[str] = None
668
694
  given_visibility: Optional[str] = None
669
695
 
696
+ given_align: Optional[int] = None
697
+
670
698
  _generated_default_name: Optional[str] = None
671
699
  _last_type: Optional[str] = None
672
700
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: splat64
3
- Version: 0.35.1
3
+ Version: 0.36.0
4
4
  Summary: A binary splitting tool to assist with decompilation and modding projects
5
5
  Project-URL: Repository, https://github.com/ethteck/splat
6
6
  Project-URL: Issues, https://github.com/ethteck/splat/issues
@@ -42,7 +42,7 @@ Requires-Dist: mypy; extra == 'dev'
42
42
  Requires-Dist: n64img>=0.3.3; extra == 'dev'
43
43
  Requires-Dist: pygfxd; extra == 'dev'
44
44
  Requires-Dist: rabbitizer<2.0.0,>=1.12.0; extra == 'dev'
45
- Requires-Dist: spimdisasm<2.0.0,>=1.32.0; extra == 'dev'
45
+ Requires-Dist: spimdisasm<2.0.0,>=1.36.1; extra == 'dev'
46
46
  Requires-Dist: types-colorama; extra == 'dev'
47
47
  Requires-Dist: types-pyyaml; extra == 'dev'
48
48
  Provides-Extra: mips
@@ -50,7 +50,7 @@ Requires-Dist: crunch64<1.0.0,>=0.5.1; extra == 'mips'
50
50
  Requires-Dist: n64img>=0.3.3; extra == 'mips'
51
51
  Requires-Dist: pygfxd; extra == 'mips'
52
52
  Requires-Dist: rabbitizer<2.0.0,>=1.12.0; extra == 'mips'
53
- Requires-Dist: spimdisasm<2.0.0,>=1.32.0; extra == 'mips'
53
+ Requires-Dist: spimdisasm<2.0.0,>=1.36.1; extra == 'mips'
54
54
  Description-Content-Type: text/markdown
55
55
 
56
56
  # splat
@@ -76,7 +76,7 @@ The brackets corresponds to the optional dependencies to install while installin
76
76
  If you use a `requirements.txt` file in your repository, then you can add this library with the following line:
77
77
 
78
78
  ```txt
79
- splat64[mips]>=0.35.1,<1.0.0
79
+ splat64[mips]>=0.36.0,<1.0.0
80
80
  ```
81
81
 
82
82
  ### Optional dependencies
@@ -1,4 +1,4 @@
1
- splat/__init__.py,sha256=EqcKb5RaJAqZuKezUzsW4SkiCT7ysMS7MCKmP1MfPU0,291
1
+ splat/__init__.py,sha256=s7EjnCDYNumj0mjJ61zphGBrpzgBbAehfamCJ9R0EJ8,291
2
2
  splat/__main__.py,sha256=T333dHDgr-2HYYhtARnYMEjdECnYiNIKfcXDD99o22A,732
3
3
  splat/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  splat/disassembler/__init__.py,sha256=IubLMnm_F5cZ7WUPBfk1VJ7vdj6i1if5GG6RBvEoBEA,226
@@ -6,7 +6,7 @@ splat/disassembler/disassembler.py,sha256=2ynehZRz1P6UnaBk6DWRy4c3ynRnnWApMhf0K9
6
6
  splat/disassembler/disassembler_instance.py,sha256=09GW7QYoNolgE2wnO7ALngw_CxgF-mfyLiXBsyv22jA,916
7
7
  splat/disassembler/disassembler_section.py,sha256=J9jtplQVDVeGBmyEOcMpC3Hv3DyecqaNjlYc7zqEqDI,7459
8
8
  splat/disassembler/null_disassembler.py,sha256=jYuDMtfPiBifwz0H-ZHLMWtpGa19X_iLgy4K-dQhPYY,328
9
- splat/disassembler/spimdisasm_disassembler.py,sha256=raJaya8QVw90mhtISf-atp0fLnc-IkciRbLIVRqdPx4,5920
9
+ splat/disassembler/spimdisasm_disassembler.py,sha256=BPeWrTIla14DtkDl3apHxoMkd26mhkJPJndwSX-MpF0,5920
10
10
  splat/platforms/__init__.py,sha256=qjqKi63k5N3DUdILNfuk6qpJJkVeAWpjAs36L97vvP4,100
11
11
  splat/platforms/n64.py,sha256=kgWr6nesGC0X-qVydmu8tSq48NbqVf9mF6EyqvUuoUM,421
12
12
  splat/platforms/ps2.py,sha256=QI_8Ve43LZeNqpuk8_CFxIqsNJpMTacRHXdZVh3iY6c,336
@@ -14,10 +14,10 @@ splat/platforms/psp.py,sha256=rCr_uf1SuHNaMUXjIC0GyoA_463OQZv0se2KMarWry0,125
14
14
  splat/platforms/psx.py,sha256=YxQERdOBr4p3ab9Wk80FNhVYi-uvmh7p_jeykSFp23M,40
15
15
  splat/scripts/__init__.py,sha256=OY0nHg6a7JB437Sb96qLbZ_7ByVsal1gStj35wJAI_Y,101
16
16
  splat/scripts/capy.py,sha256=svbOfLO34-QN3xLiBy9vk2RGs_To8TWMWEKBw6yx2xQ,3674
17
- splat/scripts/create_config.py,sha256=nWLqbvjZW7LCQsJvvsxEWgnCfN-A_WDwxpV7VlRE-4I,11520
17
+ splat/scripts/create_config.py,sha256=ZQrqdewjR2poVhlvoa0CVZMfr9vnupYGouaAn2MLph4,11783
18
18
  splat/scripts/split.py,sha256=081pZYN34iriEhMmDBDxxLrDkSKkAksHJydzQ0VAEGk,21933
19
19
  splat/segtypes/__init__.py,sha256=-upUw_4JGQtvyp6IfTMzOq_CK3xvVaT_0K0_EipHyOo,208
20
- splat/segtypes/linker_entry.py,sha256=vr8OSC0cnsaNIsePgBMqcHlCLtr2mdZz0jflYT3t3UY,24780
20
+ splat/segtypes/linker_entry.py,sha256=oTpt9Iw9ybrmwrkacyH5RYzj01wGTT7vjeE3xE1Og38,24908
21
21
  splat/segtypes/segment.py,sha256=-wc5xpWMN8AO8S3rrtibJgw0MMk2Dm1lZSI8dQj-H20,30625
22
22
  splat/segtypes/common/__init__.py,sha256=mnq0acScilSCCo6q2PvkDk0Or3V8qitA7I8QMVw8haI,631
23
23
  splat/segtypes/common/asm.py,sha256=k3p4vgbQJP40iyTgQkIci1j3CpKkWksqoWBx2Pb2oh8,703
@@ -44,7 +44,7 @@ splat/segtypes/common/rodatabin.py,sha256=uqp60QuwHwvlMwHq0nZrU3y3yYcHbv2twT0PID
44
44
  splat/segtypes/common/sbss.py,sha256=blIEuVYie4qNEOYMmlSdltn5f4MvgJu3AV8vqVD8Nh4,131
45
45
  splat/segtypes/common/sdata.py,sha256=dnLzNSNtSyclLZiNUmFTv0e0BWN8glxB1km1MSRq6xY,136
46
46
  splat/segtypes/common/segment.py,sha256=vVFyFjs-gS5qIWO8Pd0pMJYxboP-iBRKvxcDV8YxdYM,94
47
- splat/segtypes/common/textbin.py,sha256=kC0m9RDxavpQt2WAYnXQVUzLlIZUvd9hqC3KEz7CUKs,5239
47
+ splat/segtypes/common/textbin.py,sha256=PXEb1JQB2NEqVDLg5KW2vI0NLSqrROJvCOifxB0NUms,5994
48
48
  splat/segtypes/n64/__init__.py,sha256=tf2yWlijeKmOp1OhEEL-aW88mU-mWQRC2lSjQ5Ww1eI,569
49
49
  splat/segtypes/n64/ci.py,sha256=An7wIHcoZ89KiGCKpCRbM7IrmDNYBidXT-6kjKn2vH0,2400
50
50
  splat/segtypes/n64/ci4.py,sha256=ZP8e12CpV8U7r8oLnb9uHc-MkmBbxjXBbJxROFvOjiM,184
@@ -52,7 +52,7 @@ splat/segtypes/n64/ci8.py,sha256=tS4USmp0LuJnP-UlgaOYoxvYxBKgE67wYCz-KeRLlFk,184
52
52
  splat/segtypes/n64/decompressor.py,sha256=YuKo-PS_S2-Ow1Zw8QTO70NWlSYTY79JZN0kUQB7T0U,1779
53
53
  splat/segtypes/n64/gfx.py,sha256=f22_P8aXjQ0PiWf3iLztfERfmvRfDBcA00CBIwKutvw,8395
54
54
  splat/segtypes/n64/header.py,sha256=7Ubmvs49FTK1h4GX58XHOa922bbmjpOJCY3QXvd9078,2018
55
- splat/segtypes/n64/i1.py,sha256=tnYXJxyM802jJ6OFBLJK9FGfWLaMg0UqTqZeascnAxw,213
55
+ splat/segtypes/n64/i1.py,sha256=Mr7YRdKpvuTGu7P5QZPo6PF1XOcVy4W6_zthcRkLKps,204
56
56
  splat/segtypes/n64/i4.py,sha256=wPYCGNa4dQHKf8lbDijSD80_yOt9kQIgOQO6ZOB_pGA,204
57
57
  splat/segtypes/n64/i8.py,sha256=5zqYmpmuXprEzwidVQTknSKqMuu0C1Izk4t5ILoTPf4,204
58
58
  splat/segtypes/n64/ia16.py,sha256=y1uLVuh72HTmyAEK90R67vftp-X4LDgRxgJyU8EAnH0,208
@@ -80,14 +80,14 @@ splat/util/cache_handler.py,sha256=N0SggmvYwh0k-0fngHXoHG1CosC2rCsnlCTDsG8z5aE,1
80
80
  splat/util/color.py,sha256=FSmy0dAQJ9FzRBc99Yt4kBEyB62MC_YiVkqoWgPMsRU,371
81
81
  splat/util/compiler.py,sha256=uXShMm49380ENecSFlsi75LWI45yakWkExZX8NT5pOU,1778
82
82
  splat/util/conf.py,sha256=aM6O2QikosjL95pCxI2FcCxrwDsLP8T8sRf2Uev_Pac,3236
83
- splat/util/file_presets.py,sha256=LGNOz2Mvbt8UndNOglGKqVzGi06c_HPWJb1I8wt6PGo,17184
83
+ splat/util/file_presets.py,sha256=eOoVkLIgz1txIw9gAF75Bm6qllqNZiccOyeSDtM8WvU,18154
84
84
  splat/util/log.py,sha256=aJA1rg8IirJu1wGzjNuATHvepYvD3k5CtEyMasyJWxI,1193
85
- splat/util/options.py,sha256=KqNjeB2mSwuB09H3uylfZ9PU7GlCZDYhkhfCLAGYSQE,30005
85
+ splat/util/options.py,sha256=bXFruGE-tcqsdM0nYNqf_IQIiqxFCxn7NWEo_igOZIc,31252
86
86
  splat/util/palettes.py,sha256=d3KoZnwt-zunI9eNwb3txysXg4DY3xnF0O5aQRxM4so,2920
87
87
  splat/util/progress_bar.py,sha256=41VehpIFK1cphENaXV_Aq6_3mFx25eQ8V7Z51SKFPeM,166
88
88
  splat/util/relocs.py,sha256=rVkPGUXzGZUyY_z7oaCTUxaZH1-lPxxiZwSJvLA0JB0,4156
89
89
  splat/util/statistics.py,sha256=8C88vLW8q4Xd4i1Crz8X24NLoraLyKd0lw3ebbeonSo,1906
90
- splat/util/symbols.py,sha256=CMYn6dQDJJEx6bd6IHai8jnqkRwC3EkLdtvMJWz4AlM,29688
90
+ splat/util/symbols.py,sha256=VNTTTLKQFMx6y1XfmK95cwUzKuAtFPTh-MjxfXbV-aw,31270
91
91
  splat/util/utils.py,sha256=EtuU2f7S3vI8kH9C9KaIpjANsUCUkoFz4VBNLWK9lQY,187
92
92
  splat/util/vram_classes.py,sha256=UH4rkugEwoec_-alJ4smNOcnU51G-V5OG7Pfsj47eaM,3491
93
93
  splat/util/n64/__init__.py,sha256=hsBkPh6NUz-bW7HVspcNZ0mCxBhdfcPC07_7gbga95o,84
@@ -95,8 +95,8 @@ splat/util/n64/find_code_length.py,sha256=uUoPoUORAjsAvH8oGqwnGvw6j8I_NnSrZtA-x9
95
95
  splat/util/n64/rominfo.py,sha256=s13r4pDPH9Mc43ZGpomPnLZPWchhbv0kIjDoM0B3Ong,16963
96
96
  splat/util/psx/__init__.py,sha256=kCCaR-KB1mNlIcXB4OuuSQ2zVLbWg_SnIZIUeyjeBBI,39
97
97
  splat/util/psx/psxexeinfo.py,sha256=MrxY28nes0uzpFmCz0o9JFbF8s1eQRQNOpC_82wsMVI,5725
98
- splat64-0.35.1.dist-info/METADATA,sha256=vi5oDgh5LujnaB0jDM5ql_MwxpdBKSsRZ7Ig02wEaY0,3830
99
- splat64-0.35.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
100
- splat64-0.35.1.dist-info/entry_points.txt,sha256=O7Xy-qNOHcI87-OQrWJ-OhRDws74SuwVb_4rtnp0eLo,52
101
- splat64-0.35.1.dist-info/licenses/LICENSE,sha256=97VMVzjG8yQvsf8NG2M9IFSbh7R8cifJnc6QK1cZqj8,1070
102
- splat64-0.35.1.dist-info/RECORD,,
98
+ splat64-0.36.0.dist-info/METADATA,sha256=33Sj7uaKkZ2Qf_WYIdcVBcPdr46pUVMmd92Rc-HNpjQ,3830
99
+ splat64-0.36.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
100
+ splat64-0.36.0.dist-info/entry_points.txt,sha256=O7Xy-qNOHcI87-OQrWJ-OhRDws74SuwVb_4rtnp0eLo,52
101
+ splat64-0.36.0.dist-info/licenses/LICENSE,sha256=97VMVzjG8yQvsf8NG2M9IFSbh7R8cifJnc6QK1cZqj8,1070
102
+ splat64-0.36.0.dist-info/RECORD,,