diff --git a/pak2.py b/pak2.py index c448292..f3b1806 100644 --- a/pak2.py +++ b/pak2.py @@ -15,7 +15,7 @@ class pak2_file: char_count: int = 0 slot_count: int = 0 image_count: int = 0 - chunks: pak2_chunks = pak2_chunks() + chunks: pak2_chunks = field(default_factory=pak2_chunks) def get_file_name_noext(path): return os.path.splitext(os.path.basename(path))[0] diff --git a/theirsce.py b/theirsce.py index 2a6937b..f36a87d 100644 --- a/theirsce.py +++ b/theirsce.py @@ -1,3 +1,4 @@ +from itertools import tee, zip_longest from typing import Generator from FileIO import FileIO from dataclasses import dataclass, field @@ -61,11 +62,13 @@ class Theirsce(FileIO): self.seek(start) while self.tell() < end: + opcode = self.read_opcode() pos = self.tell() - yield self.read_opcode() + yield opcode self.seek(pos) def read_opcode(self): + pos = self.tell() opcode = self.read_uint8() # Reference Block @@ -103,11 +106,11 @@ class Theirsce(FileIO): else: scope = ReferenceScope.LOCAL - return TheirsceReferenceInstruction(ref_type=VariableType(var_type), scope=scope, offset=value, shift=shift) + return TheirsceReferenceInstruction(ref_type=VariableType(var_type), scope=scope, offset=value, shift=shift, position=pos) # ALU operations elif opcode < 0xC0: - return TheirsceAluInstruction(operation = AluOperation(opcode & 0x3F)) + return TheirsceAluInstruction(operation = AluOperation(opcode & 0x3F), position=pos) # PUSH block, the amount of bytes depend on encoding elif opcode < 0xE0: @@ -129,29 +132,29 @@ class Theirsce(FileIO): # to signed value = value | (-(value & 0x80000000)) - return TheirscePushInstruction(value=value) + return TheirscePushInstruction(value=value, position=pos) # CALL block, available commands are at 0x1e5300 # first entry is number of parameters then function elif opcode < 0xF0: index = ((opcode & 0xF) << 8) | self.read_uint8() - return TheirsceSyscallInstruction(function_index=index, function_name=SYSCALL_NAMES[index]) + return TheirsceSyscallInstruction(function_index=index, function_name=SYSCALL_NAMES[index], position=pos) # Flow related block elif opcode < 0xF8: if opcode == 0xF0: - return TheirsceReturnInstruction(is_void=True) + return TheirsceReturnInstruction(is_void=True, position=pos) elif opcode == 0xF1: - return TheirsceReturnInstruction(is_void=False) + return TheirsceReturnInstruction(is_void=False, position=pos) # Need to be offsetted to start of code elif opcode >= 0xF2 and opcode < 0xF5: target = self.code_offset + self.read_uint16() - return TheirsceBranchInstruction(branch_type=BranchType(opcode - 0xF2), destination=target) + return TheirsceBranchInstruction(branch_type=BranchType(opcode - 0xF2), destination=target, position=pos) elif opcode == 0xF5: target = self.code_offset + self.read_uint16() reserve = self.read_uint16() - return TheirsceLocalCallInstruction(destination=target, reserve=reserve) + return TheirsceLocalCallInstruction(destination=target, reserve=reserve, position=pos) # ? elif opcode == 0xF6: @@ -163,20 +166,20 @@ class Theirsce(FileIO): else: params.append(self.read_uint8()) - return TheirsceAcquireInstruction(params=params,variables=variables) + return TheirsceAcquireInstruction(params=params,variables=variables, position=pos) elif opcode == 0xF7: param = self.read_uint16() # Type? - return TheirsceBreakInstruction(param=param) + return TheirsceBreakInstruction(param=param, position=pos) # Get string elif opcode < 0xFC: value = ((opcode & 3) << 16) | self.read_uint16() - return TheirsceStringInstruction(offset=value,text="") + return TheirsceStringInstruction(offset=value,text="", position=pos) # ? elif opcode == 0xFE: - return TheirsceSpecialReferenceInstruction() + return TheirsceSpecialReferenceInstruction(position=pos) # Impossible else: diff --git a/theirsce_instructions.py b/theirsce_instructions.py index ba1b569..beb3408 100644 --- a/theirsce_instructions.py +++ b/theirsce_instructions.py @@ -22,6 +22,7 @@ class BranchType(Enum): class InstructionType(Enum): + INVALID = -1 ALU = 0 PUSH = 1 SYSCALL = 2 @@ -90,6 +91,7 @@ class TheirsceBaseInstruction: @dataclass class TheirsceAluInstruction(TheirsceBaseInstruction): operation: AluOperation + position: int mnemonic = "ALU" type = InstructionType.ALU @@ -100,6 +102,7 @@ class TheirsceAluInstruction(TheirsceBaseInstruction): @dataclass class TheirscePushInstruction(TheirsceBaseInstruction): value: int + position: int mnemonic = "PUSH" type = InstructionType.PUSH @@ -108,6 +111,7 @@ class TheirscePushInstruction(TheirsceBaseInstruction): class TheirsceSyscallInstruction(TheirsceBaseInstruction): function_index: int function_name: str + position: int mnemonic = "SYSCALL" type = InstructionType.SYSCALL @@ -116,6 +120,7 @@ class TheirsceSyscallInstruction(TheirsceBaseInstruction): class TheirsceLocalCallInstruction(TheirsceBaseInstruction): destination: int reserve: int + position: int mnemonic = "CALL" type = InstructionType.LOCAL_CALL @@ -124,6 +129,7 @@ class TheirsceLocalCallInstruction(TheirsceBaseInstruction): class TheirsceAcquireInstruction(TheirsceBaseInstruction): params: list[int] variables: int + position: int mnemonic = "ACQUIRE" type = InstructionType.ACQUIRE @@ -131,6 +137,7 @@ class TheirsceAcquireInstruction(TheirsceBaseInstruction): @dataclass class TheirsceBreakInstruction(TheirsceBaseInstruction): param: int + position: int mnemonic = "BREAK" type = InstructionType.BREAK @@ -139,6 +146,7 @@ class TheirsceBreakInstruction(TheirsceBaseInstruction): class TheirsceBranchInstruction(TheirsceBaseInstruction): destination: int branch_type: BranchType + position: int mnemonic = "" type = InstructionType.BRANCH @@ -149,6 +157,7 @@ class TheirsceBranchInstruction(TheirsceBaseInstruction): @dataclass class TheirsceReturnInstruction(TheirsceBaseInstruction): is_void: bool + position: int mnemonic = "RETURN" type = InstructionType.RETURN @@ -161,6 +170,7 @@ class TheirsceReturnInstruction(TheirsceBaseInstruction): class TheirsceStringInstruction(TheirsceBaseInstruction): text: str offset: int + position: int mnemonic = "STRING" type = InstructionType.STRING @@ -171,11 +181,13 @@ class TheirsceReferenceInstruction(TheirsceBaseInstruction): scope: ReferenceScope offset: int shift: int + position: int mnemonic = "REF" type = InstructionType.REFERENCE @dataclass class TheirsceSpecialReferenceInstruction(TheirsceBaseInstruction): + position: int mnemonic = "SP_REF" type = InstructionType.SP_REF \ No newline at end of file