def _rearrange_textures(self, new_order_dict): texture_count = 0 next_texture_start = 0 for text_header_index in range(self._texture_setup_offset + 8, self._texture_setup_offset + 8 + (self._texture_count*16), 16): if(texture_count in new_order_dict): curr_info = self._texture_list[new_order_dict[texture_count]] image_num = leading_zeros(str(new_order_dict[texture_count]), 3) else: curr_info = self._texture_list[texture_count] image_num = leading_zeros(str(texture_count), 3) texture_start = leading_zeros(next_texture_start, 8) self.mm[text_header_index] = int(texture_start[:2], 16) self.mm[text_header_index + 1] = int(texture_start[2:4], 16) self.mm[text_header_index + 2] = int(texture_start[4:6], 16) self.mm[text_header_index + 3] = int(texture_start[6:], 16) self.mm[text_header_index + 5] = curr_info["Texture_Type"] self.mm[text_header_index + 8] = curr_info["X_Length"] self.mm[text_header_index + 9] = curr_info["Y_Length"] next_texture_start = next_texture_start + (curr_info["X_Length"] * curr_info["Y_Length"])//2 + 0x20 with open(f"{self._file_dir}Randomized_ROM/{self._address}-Texture_{image_num}.bin", "r+b") as texture_file: mm_texture = mmap(texture_file.fileno(), 0) index_count = 0 for index in range(self._texture_list[texture_count]["Texture_Start"], self._texture_list[texture_count]["Texture_Start"] + (curr_info["X_Length"] * curr_info["Y_Length"])//2 + 0x20): self.mm[index] = mm_texture[index_count] index_count += 1 texture_count += 1
def _starting_health(self, health_val): '''Sets how much health the player has to begin with; Unused''' # Starting Health # 24 0E 00 [05] life_count_str = leading_zeros(health_val, 4) self.mm[0xBF516] = int(life_count_str[:2], 16) self.mm[0xBF517] = int(life_count_str[2:], 16)
def _starting_lives(self, life_count): '''Sets the starting life count''' # 0xBF51A & 0xBF51B # Default is 3 lives # 24 18 00 [03] life_count_str = leading_zeros(life_count, 4) self.mm[0xBF51A] = int(life_count_str[:2], 16) self.mm[0xBF51B] = int(life_count_str[2:], 16)
def _extract_texture_setup_info(self): self._texture_list = [] texture_count = 0 for text_header_index in range(self._texture_setup_offset + 8, self._texture_setup_offset + 8 + (self._texture_count*16), 16): self._texture_list.append({ "Texture_Start": int(leading_zeros(self.mm[text_header_index], 2) + leading_zeros(self.mm[text_header_index + 1], 2) + leading_zeros(self.mm[text_header_index + 2], 2) + leading_zeros(self.mm[text_header_index + 3], 2), 16) + self._textures_offset, "Texture_Type": self.mm[text_header_index + 5], "X_Length": self.mm[text_header_index + 8], "Y_Length": self.mm[text_header_index + 9], }) with open(f"{self._file_dir}Randomized_ROM\\{self._address}-Texture_{leading_zeros(str(texture_count), 3)}.bin", "w+b") as texture_file: for index in range(self._texture_list[-1]["Texture_Start"], self._texture_list[-1]["Texture_Start"] + (self._texture_list[-1]["X_Length"] * self._texture_list[-1]["Y_Length"])//2 + 0x20): texture_file.write(bytes.fromhex(leading_zeros(self.mm[index], 2))) texture_count += 1
def _convert_32_to_16(self, _32_bit_color): red = int(_32_bit_color[0:2], 16) green = int(_32_bit_color[2:4], 16) blue = int(_32_bit_color[4:6], 16) alpha = int(_32_bit_color[6:8], 16) r = (red >> 3) g = (green >> 3) b = (blue >> 3) a = (alpha >> 7) _16_bit_color = (r << 11) | (g << 6) | (b << 1) | (a) return leading_zeros(_16_bit_color, 4)
def _place_compressed_files(self): '''Replaces the model pointers with the new model file''' for pointer in range(self._pointers_start, self._pointers_end + 0x08, 0x08): # print("~~~~") pointer_str = str(hex(pointer)) pointer_dec = int(pointer_str[2:], 16) curr_pointer_file = self._model_address_dict[pointer_str] with open(f"{self._file_dir}Randomized_ROM/{curr_pointer_file}", "r+b") as comp_file: pointer_content = comp_file.read() with open( f"{self._file_dir}Randomized_ROM/Banjo-Kazooie_Randomized_Seed_{self._seed_val}.z64", "r+b") as rom_file: mm_rand_rom = mmap(rom_file.fileno(), 0) # print(f"Pointer Str: {pointer_str} Pointer File: {curr_pointer_file}") # Find The Pointer Start pointer_start = "" for offset in range(4): pointer_start += leading_zeros( mm_rand_rom[pointer_dec + offset], 2) address_start = int("0x" + pointer_start, 16) + int( "0x10CD0", 16) # print(f"Start: {hex(address_start)} End: {hex(address_start + len(pointer_content))}") curr_pointer_index = 0 for index in range(address_start, address_start + len(pointer_content)): mm_rand_rom[index] = pointer_content[curr_pointer_index] curr_pointer_index += 1 if (pointer < self._pointers_end): address_end = address_start + len(pointer_content) - int( "0x10CD0", 16) address_end_hex = leading_zeros(address_end, 8) mm_rand_rom[pointer_dec + 8] = int(address_end_hex[:2], 16) mm_rand_rom[pointer_dec + 9] = int(address_end_hex[2:4], 16) mm_rand_rom[pointer_dec + 10] = int( address_end_hex[4:6], 16) mm_rand_rom[pointer_dec + 11] = int( address_end_hex[6:], 16)
def _flip_texture(self, rgba_index_list, x_axis=True, y_axis=True): if(x_axis): for rgba_index in rgba_index_list: v_value = 0x10000 - int(leading_zeros(self.mm[rgba_index + 0xA], 2) + leading_zeros(self.mm[rgba_index + 0xB], 2), 16) if(v_value == 0x10000): v_str = "0000" else: v_str = leading_zeros(v_value, 4) self.mm[rgba_index + 0xA] = int(v_str[:2], 16) self.mm[rgba_index + 0xB] = int(v_str[2:], 16) # self.mm[rgba_index + 0xC] = 0 # self.mm[rgba_index + 0xD] = 0 # self.mm[rgba_index + 0xE] = 0 if(y_axis): for rgba_index in rgba_index_list: v_value = 0x10000 - int(leading_zeros(self.mm[rgba_index + 0x8], 2) + leading_zeros(self.mm[rgba_index + 0x9], 2), 16) if(v_value == 0x10000): v_str = "0000" else: v_str = leading_zeros(v_value, 4) self.mm[rgba_index + 0x8] = int(v_str[:2], 16) self.mm[rgba_index + 0x9] = int(v_str[2:], 16)
def _random_hex(self, digit_len, increment=0): '''Randomly generates hex values for the colors in BK''' self.grandmaster.logger.debug("Random Hex") seed(a=(self._seed_val + increment)) max_num = "F" * digit_len random_hex_val = leading_zeros(randint(0, int(max_num, 16)), digit_len).upper() if (digit_len == 4): choices = [ str(hex(num))[2:].upper() for num in range(0x1, 0xF, 0x2) ] seed(a=(self._seed_val + increment)) new_end_val = choice(choices) random_hex_val = random_hex_val[:-1] + new_end_val elif (digit_len == 6): random_hex_val = random_hex_val + "FF" return random_hex_val
def _change_floor_type_by_vert(self, vert_condition, new_bytes): '''Changes the collision type per vertex''' for curr_index in range(self._collision_info_start, self._geometry_layout_offset, 12): Vert1 = int( leading_zeros(self.mm[curr_index], 2) + leading_zeros(self.mm[curr_index + 1], 2), 16) Vert2 = int( leading_zeros(self.mm[curr_index + 2], 2) + leading_zeros(self.mm[curr_index + 3], 2), 16) Vert3 = int( leading_zeros(self.mm[curr_index + 4], 2) + leading_zeros(self.mm[curr_index + 5], 2), 16) if (vert_condition(Vert1, Vert2, Vert3)): self.mm[curr_index + 6] = new_bytes[0] self.mm[curr_index + 7] = new_bytes[1] self.mm[curr_index + 8] = new_bytes[2] self.mm[curr_index + 9] = new_bytes[3] self.mm[curr_index + 10] = new_bytes[4] self.mm[curr_index + 11] = new_bytes[5]
def _extract_header_info(self): self._texture_setup_offset = int(leading_zeros(self.mm[8], 2) + leading_zeros(self.mm[9], 2), 16) self._texture_count = self.mm[self._texture_setup_offset + 5] self._textures_offset = self._texture_setup_offset + (0x10 * self._texture_count) + 0x8