splat64 0.34.2__py3-none-any.whl → 0.35.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/util/n64/rominfo.py CHANGED
@@ -11,7 +11,7 @@ import zlib
11
11
  from dataclasses import dataclass
12
12
 
13
13
  from pathlib import Path
14
- from typing import Optional
14
+ from typing import Optional, List
15
15
 
16
16
  import rabbitizer
17
17
  import spimdisasm
@@ -69,18 +69,43 @@ crc_to_cic = {
69
69
  unknown_cic = CIC("unknown", "unknown", 0x0000000)
70
70
 
71
71
 
72
+ @dataclass
73
+ class EntryAddressInfo:
74
+ value: int
75
+ rom_hi: int
76
+ rom_lo: int
77
+
78
+ @staticmethod
79
+ def new(
80
+ value: Optional[int], hi: Optional[int], lo: Optional[int]
81
+ ) -> Optional["EntryAddressInfo"]:
82
+ if value is not None and hi is not None and lo is not None:
83
+ return EntryAddressInfo(value, hi, lo)
84
+ return None
85
+
86
+
72
87
  @dataclass
73
88
  class N64EntrypointInfo:
74
89
  entry_size: int
75
- data_size: int
76
- bss_start_address: Optional[int]
77
- bss_size: Optional[int]
78
- main_address: Optional[int]
79
- stack_top: int
90
+ data_size: Optional[int]
91
+ bss_start_address: Optional[EntryAddressInfo]
92
+ bss_size: Optional[EntryAddressInfo]
93
+ bss_end_address: Optional[EntryAddressInfo]
94
+ main_address: Optional[EntryAddressInfo]
95
+ stack_top: Optional[EntryAddressInfo]
80
96
  traditional_entrypoint: bool
81
97
 
82
98
  def segment_size(self) -> int:
83
- return self.entry_size + self.data_size
99
+ if self.data_size is not None:
100
+ return self.entry_size + self.data_size
101
+ return self.entry_size
102
+
103
+ def get_bss_size(self) -> Optional[int]:
104
+ if self.bss_size is not None:
105
+ return self.bss_size.value
106
+ if self.bss_start_address is not None and self.bss_end_address is not None:
107
+ return self.bss_end_address.value - self.bss_start_address.value
108
+ return None
84
109
 
85
110
  @staticmethod
86
111
  def parse_rom_bytes(
@@ -93,23 +118,27 @@ class N64EntrypointInfo:
93
118
 
94
119
  register_values = [0 for _ in range(32)]
95
120
  completed_pair = [False for _ in range(32)]
121
+ hi_assignments: List[Optional[int]] = [None for _ in range(32)]
122
+ lo_assignments: List[Optional[int]] = [None for _ in range(32)]
96
123
 
97
124
  register_bss_address: Optional[int] = None
98
125
  register_bss_size: Optional[int] = None
99
126
  register_main_address: Optional[int] = None
100
127
 
101
- bss_address: Optional[int] = None
102
- bss_size: Optional[int] = None
128
+ bss_address: Optional[EntryAddressInfo] = None
129
+ bss_size: Optional[EntryAddressInfo] = None
130
+ bss_end_address: Optional[EntryAddressInfo] = None
103
131
 
104
132
  traditional_entrypoint = True
105
133
  decrementing_bss_routine = True
106
- data_size = 0
107
- func_call_target: Optional[int] = None
134
+ data_size: Optional[int] = None
135
+ func_call_target: Optional[EntryAddressInfo] = None
108
136
 
109
137
  size = 0
110
138
  i = 0
111
139
  while i < len(word_list):
112
140
  word = word_list[i]
141
+ current_rom = offset + i * 4
113
142
  insn = rabbitizer.Instruction(word, vram)
114
143
  if not insn.isValid():
115
144
  break
@@ -121,6 +150,7 @@ class N64EntrypointInfo:
121
150
  elif insn.canBeHi():
122
151
  register_values[insn.rt.value] = insn.getProcessedImmediate() << 16
123
152
  completed_pair[insn.rt.value] = False
153
+ hi_assignments[insn.rt.value] = current_rom
124
154
  elif insn.canBeLo():
125
155
  if insn.isLikelyHandwritten():
126
156
  # Try to skip these instructions:
@@ -132,6 +162,8 @@ class N64EntrypointInfo:
132
162
  register_values[insn.rs.value] + insn.getProcessedImmediate()
133
163
  )
134
164
  completed_pair[insn.rt.value] = True
165
+ if not insn.isUnsigned():
166
+ lo_assignments[insn.rt.value] = current_rom
135
167
  elif insn.doesStore():
136
168
  if insn.rt == rabbitizer.RegGprO32.zero:
137
169
  # Try to detect the zero-ing bss algorithm
@@ -173,16 +205,25 @@ class N64EntrypointInfo:
173
205
  # bnez $at, .clear_bss
174
206
  # sw $zero, -0x4($t0)
175
207
  if bss_address is None and bss_size is None:
176
- bss_address = register_values[insn.rs.value]
177
- bss_end_address = register_values[insn.rt.value]
178
- bss_size = bss_end_address - bss_address
208
+ bss_address = EntryAddressInfo.new(
209
+ register_values[insn.rs.value],
210
+ hi_assignments[insn.rs.value],
211
+ lo_assignments[insn.rs.value],
212
+ )
213
+ bss_end_address = EntryAddressInfo.new(
214
+ register_values[insn.rt.value],
215
+ hi_assignments[insn.rt.value],
216
+ lo_assignments[insn.rt.value],
217
+ )
179
218
 
180
219
  elif insn.isFunctionCall():
181
220
  # Some games don't follow the usual pattern for entrypoints.
182
221
  # Those usually use `jal` instead of `jr` to jump out of the
183
222
  # entrypoint to actual code.
184
223
  traditional_entrypoint = False
185
- func_call_target = insn.getInstrIndexAsVram()
224
+ func_call_target = EntryAddressInfo(
225
+ insn.getInstrIndexAsVram(), current_rom, current_rom
226
+ )
186
227
 
187
228
  elif insn.uniqueId == rabbitizer.InstrId.cpu_break:
188
229
  traditional_entrypoint = False
@@ -209,27 +250,38 @@ class N64EntrypointInfo:
209
250
  # print(i, f"{val:08X}")
210
251
 
211
252
  if decrementing_bss_routine:
212
- bss_address = (
213
- register_values[register_bss_address]
214
- if register_bss_address is not None
215
- else None
253
+ if register_bss_address is not None:
254
+ bss_address = EntryAddressInfo.new(
255
+ register_values[register_bss_address],
256
+ hi_assignments[register_bss_address],
257
+ lo_assignments[register_bss_address],
258
+ )
259
+ if register_bss_size is not None:
260
+ bss_size = EntryAddressInfo.new(
261
+ register_values[register_bss_size],
262
+ hi_assignments[register_bss_size],
263
+ lo_assignments[register_bss_size],
264
+ )
265
+
266
+ if register_main_address is not None:
267
+ main_address = EntryAddressInfo.new(
268
+ register_values[register_main_address],
269
+ hi_assignments[register_main_address],
270
+ lo_assignments[register_main_address],
216
271
  )
217
- bss_size = (
218
- register_values[register_bss_size]
219
- if register_bss_size is not None
220
- else None
221
- )
222
- main_address = (
223
- register_values[register_main_address]
224
- if register_main_address is not None
225
- else None
272
+ else:
273
+ main_address = None
274
+
275
+ stack_top = EntryAddressInfo.new(
276
+ register_values[rabbitizer.RegGprO32.sp.value],
277
+ hi_assignments[rabbitizer.RegGprO32.sp.value],
278
+ lo_assignments[rabbitizer.RegGprO32.sp.value],
226
279
  )
227
- stack_top = register_values[rabbitizer.RegGprO32.sp.value]
228
280
 
229
281
  if not traditional_entrypoint:
230
282
  if func_call_target is not None:
231
283
  main_address = func_call_target
232
- if func_call_target > vram:
284
+ if func_call_target.value > vram:
233
285
  # Some weird-entrypoint games have non-code between the
234
286
  # entrypoint and the actual user code.
235
287
  # We try to find where actual code may begin, and tag
@@ -244,6 +296,7 @@ class N64EntrypointInfo:
244
296
  data_size,
245
297
  bss_address,
246
298
  bss_size,
299
+ bss_end_address,
247
300
  main_address,
248
301
  stack_top,
249
302
  traditional_entrypoint,
splat/util/options.py CHANGED
@@ -35,6 +35,9 @@ class SplatOpts:
35
35
  generated_c_preamble: str
36
36
  # Determines the code that is inserted by default in generated .s files
37
37
  generated_s_preamble: str
38
+ # Determines any extra content to be added in the generated macro.inc file
39
+ generated_macro_inc_content: Optional[str]
40
+ generate_asm_macros_files: bool
38
41
  # Determines whether to use .o as the suffix for all binary files?... TODO document
39
42
  use_o_as_suffix: bool
40
43
  # the value of the $gp register to correctly calculate offset to %gp_rel relocs
@@ -187,8 +190,12 @@ class SplatOpts:
187
190
  asm_data_macro: str
188
191
  # Determines the macro used at the end of a function, such as endlabel or .end
189
192
  asm_end_label: str
193
+ # Determines the macro used at the end of a data symbol, such as enddlabel
194
+ asm_data_end_label: str
190
195
  # Determines the macro used to declare ehtable labels in asm files
191
196
  asm_ehtable_label_macro: str
197
+ # Determines the macro used to declare the given symbol is a non matching one.
198
+ asm_nonmatching_label_macro: str
192
199
  # Toggles the .size directive emitted by the disassembler
193
200
  asm_emit_size_directive: Optional[bool]
194
201
  # Determines the number of characters to left align before the TODO finish documenting
@@ -420,6 +427,10 @@ def _parse_yaml(
420
427
  "generated_c_preamble", str, '#include "common.h"'
421
428
  ),
422
429
  generated_s_preamble=p.parse_opt("generated_s_preamble", str, ""),
430
+ generated_macro_inc_content=p.parse_optional_opt(
431
+ "generated_macro_inc_content", str
432
+ ),
433
+ generate_asm_macros_files=p.parse_opt("generate_asm_macros_files", bool, True),
423
434
  use_o_as_suffix=p.parse_opt("o_as_suffix", bool, False),
424
435
  gp=p.parse_optional_opt("gp_value", int),
425
436
  check_consecutive_segment_types=p.parse_opt(
@@ -523,9 +534,15 @@ def _parse_yaml(
523
534
  ),
524
535
  asm_data_macro=p.parse_opt("asm_data_macro", str, comp.asm_data_macro),
525
536
  asm_end_label=p.parse_opt("asm_end_label", str, comp.asm_end_label),
537
+ asm_data_end_label=p.parse_opt(
538
+ "asm_data_end_label", str, comp.asm_data_end_label
539
+ ),
526
540
  asm_ehtable_label_macro=p.parse_opt(
527
541
  "asm_ehtable_label_macro", str, comp.asm_ehtable_label_macro
528
542
  ),
543
+ asm_nonmatching_label_macro=p.parse_opt(
544
+ "asm_nonmatching_label_macro", str, comp.asm_nonmatching_label_macro
545
+ ),
529
546
  asm_emit_size_directive=asm_emit_size_directive,
530
547
  mnemonic_ljust=p.parse_opt("mnemonic_ljust", int, 11),
531
548
  rom_address_padding=p.parse_opt("rom_address_padding", bool, False),
splat/util/relocs.py CHANGED
@@ -38,10 +38,8 @@ def initialize():
38
38
  prog_bar.set_description(f"Loading relocs ({path.stem})")
39
39
  line: str
40
40
  for line_num, line in enumerate(prog_bar):
41
- line = line.strip()
42
41
  # Allow comments
43
- line = line.split("//")[0]
44
- line = line.strip()
42
+ line = line.split("//")[0].strip()
45
43
 
46
44
  if line == "":
47
45
  continue
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: splat64
3
- Version: 0.34.2
3
+ Version: 0.35.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
@@ -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.34.2,<1.0.0
79
+ splat64[mips]>=0.35.0,<1.0.0
80
80
  ```
81
81
 
82
82
  ### Optional dependencies
@@ -1,4 +1,4 @@
1
- splat/__init__.py,sha256=IrNBs4z5PshShOZJ2rWshns8vP39aL7U8wl3c3bkpiE,291
1
+ splat/__init__.py,sha256=tcpQ8WekepdS0S7Aj4YCScLZqmoGaESYrKYng4wJRPI,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=Lj6zp2g7Jo4sRlZ7CavLb7qM4alzEG1n7AhFYLiskqU,5685
9
+ splat/disassembler/spimdisasm_disassembler.py,sha256=raJaya8QVw90mhtISf-atp0fLnc-IkciRbLIVRqdPx4,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,11 +14,11 @@ 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=nFwIt1UWzlWE9C3i-2dGsVyGX2cuXzIqkp2kur2-pdE,7670
18
- splat/scripts/split.py,sha256=pzNPJRy11YwIA_2wbRYU2m-zIfBRpo2RySJ9nKVBqRI,19433
17
+ splat/scripts/create_config.py,sha256=nWLqbvjZW7LCQsJvvsxEWgnCfN-A_WDwxpV7VlRE-4I,11520
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=e2IzjAWC1B_JCx5pxBdKJrzOCse4SYUBrLHM8l3AR3o,24765
21
- splat/segtypes/segment.py,sha256=UByBPNSNb5AThjx2J9PspeQALobc-4_jh0qKQ9ycEjg,30281
20
+ splat/segtypes/linker_entry.py,sha256=vr8OSC0cnsaNIsePgBMqcHlCLtr2mdZz0jflYT3t3UY,24780
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
24
24
  splat/segtypes/common/asmtu.py,sha256=C52kKh-8YeDHu0EucEfQ-tQMtDgfKfwAJ6wwiW6nOBU,354
@@ -32,7 +32,7 @@ splat/segtypes/common/data.py,sha256=r9G_vYieNlRze-5wGOKFazvFjpuodfSLad6iCNsBOAU
32
32
  splat/segtypes/common/databin.py,sha256=ucbbsc_M1332KifjExuDsf1wqm4-GZAiLqOwwrUwUpQ,1194
33
33
  splat/segtypes/common/eh_frame.py,sha256=MzL373ej2E38leM47py3T5beLq2IolsYszLZM8PYS2Y,913
34
34
  splat/segtypes/common/gcc_except_table.py,sha256=-ZrQL5dCcRu7EPFFPgL8lIJwWL5FsEeeQoSUVfTkyIg,2112
35
- splat/segtypes/common/group.py,sha256=4g8jrpUjlsvxFuFRauS4rdxTvAAePebc941fQj96qEA,6197
35
+ splat/segtypes/common/group.py,sha256=wSrNQXWJpRZl8-cHtdlFy08TQDI_n7QAsYhUsCRb7Bs,7125
36
36
  splat/segtypes/common/hasm.py,sha256=3mr8k8SNLGD7r0nBU3o6AQ05tnsD-skg9mdVap0kH38,782
37
37
  splat/segtypes/common/header.py,sha256=NspQdk-L69j9dOBzBtDKb7bc11Gwa0WDWIVCd2P4mfE,1257
38
38
  splat/segtypes/common/lib.py,sha256=WaJH0DH0B8iJvhYQWYBjThbNeEXz3Yh7E8ZyONe5JtQ,2349
@@ -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=Xj-PxEDTN8f0DLgdZ2uA26SYCcXD3rqqr2r6-pEiA4Y,4578
47
+ splat/segtypes/common/textbin.py,sha256=kC0m9RDxavpQt2WAYnXQVUzLlIZUvd9hqC3KEz7CUKs,5239
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
@@ -75,27 +75,28 @@ splat/segtypes/ps2/vtables.py,sha256=c8weQcbQ0-KkjkLHUXViTWkEaJ6LNR8jBUMV-0t0m4o
75
75
  splat/segtypes/psp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
76
  splat/segtypes/psx/__init__.py,sha256=tn0oDYUPtF0PfC8I4G23nPvH_JAcuLGxOCvYN1SE3Dc,31
77
77
  splat/segtypes/psx/header.py,sha256=2S8XG_6zfLGzmEA0XpFqs0-4nf52YD9Erk6SbMUlVzo,2639
78
- splat/util/__init__.py,sha256=3-jgYUssL84IgaR_JF1hSb-lN4ru0gJQTrjP_UGEWu8,470
78
+ splat/util/__init__.py,sha256=rsnoPNjNVbu9j_yxoubyq8Pf-clIbOHk2vQyuKSmxyI,513
79
79
  splat/util/cache_handler.py,sha256=N0SggmvYwh0k-0fngHXoHG1CosC2rCsnlCTDsG8z5aE,1852
80
80
  splat/util/color.py,sha256=FSmy0dAQJ9FzRBc99Yt4kBEyB62MC_YiVkqoWgPMsRU,371
81
- splat/util/compiler.py,sha256=xDDNdnutmkB7T21j-BccBMdkA2leU3GzXuTYEWgVgNw,1530
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=6GLLNUQ_Gpi7tZUYdtfU-3pVcjkAJeByMtFZRmDqjEg,16735
83
84
  splat/util/log.py,sha256=aJA1rg8IirJu1wGzjNuATHvepYvD3k5CtEyMasyJWxI,1193
84
- splat/util/options.py,sha256=iIwI3ZVbwWNIK4_0BIe3Iu9NxhEfIoXyjVGWgjPmG-Q,29157
85
+ splat/util/options.py,sha256=KqNjeB2mSwuB09H3uylfZ9PU7GlCZDYhkhfCLAGYSQE,30005
85
86
  splat/util/palettes.py,sha256=d3KoZnwt-zunI9eNwb3txysXg4DY3xnF0O5aQRxM4so,2920
86
87
  splat/util/progress_bar.py,sha256=41VehpIFK1cphENaXV_Aq6_3mFx25eQ8V7Z51SKFPeM,166
87
- splat/util/relocs.py,sha256=cgQYSaAtNpLlUZQdhEfa7ZpI8i0HqoDhwB88QtFqdJs,4212
88
+ splat/util/relocs.py,sha256=rVkPGUXzGZUyY_z7oaCTUxaZH1-lPxxiZwSJvLA0JB0,4156
88
89
  splat/util/statistics.py,sha256=8C88vLW8q4Xd4i1Crz8X24NLoraLyKd0lw3ebbeonSo,1906
89
90
  splat/util/symbols.py,sha256=CMYn6dQDJJEx6bd6IHai8jnqkRwC3EkLdtvMJWz4AlM,29688
90
91
  splat/util/utils.py,sha256=EtuU2f7S3vI8kH9C9KaIpjANsUCUkoFz4VBNLWK9lQY,187
91
92
  splat/util/vram_classes.py,sha256=UH4rkugEwoec_-alJ4smNOcnU51G-V5OG7Pfsj47eaM,3491
92
93
  splat/util/n64/__init__.py,sha256=hsBkPh6NUz-bW7HVspcNZ0mCxBhdfcPC07_7gbga95o,84
93
94
  splat/util/n64/find_code_length.py,sha256=uUoPoUORAjsAvH8oGqwnGvw6j8I_NnSrZtA-x9h9h7E,1414
94
- splat/util/n64/rominfo.py,sha256=U6TieblUAmxhZsn7u8nbjOKkbC6ygsC_7IiLLaOWwUE,14646
95
+ splat/util/n64/rominfo.py,sha256=s13r4pDPH9Mc43ZGpomPnLZPWchhbv0kIjDoM0B3Ong,16963
95
96
  splat/util/psx/__init__.py,sha256=kCCaR-KB1mNlIcXB4OuuSQ2zVLbWg_SnIZIUeyjeBBI,39
96
97
  splat/util/psx/psxexeinfo.py,sha256=MrxY28nes0uzpFmCz0o9JFbF8s1eQRQNOpC_82wsMVI,5725
97
- splat64-0.34.2.dist-info/METADATA,sha256=iZ1tPzIOR4OIj8wVR5nxgMuniEL0hkBPONWgIAlHxM8,3830
98
- splat64-0.34.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
99
- splat64-0.34.2.dist-info/entry_points.txt,sha256=O7Xy-qNOHcI87-OQrWJ-OhRDws74SuwVb_4rtnp0eLo,52
100
- splat64-0.34.2.dist-info/licenses/LICENSE,sha256=97VMVzjG8yQvsf8NG2M9IFSbh7R8cifJnc6QK1cZqj8,1070
101
- splat64-0.34.2.dist-info/RECORD,,
98
+ splat64-0.35.0.dist-info/METADATA,sha256=C9xglffpmD6eI4pgKFqTAa_g8zhMnORj-N7puPU62RU,3830
99
+ splat64-0.35.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
100
+ splat64-0.35.0.dist-info/entry_points.txt,sha256=O7Xy-qNOHcI87-OQrWJ-OhRDws74SuwVb_4rtnp0eLo,52
101
+ splat64-0.35.0.dist-info/licenses/LICENSE,sha256=97VMVzjG8yQvsf8NG2M9IFSbh7R8cifJnc6QK1cZqj8,1070
102
+ splat64-0.35.0.dist-info/RECORD,,