def encode_sir0_pointer_offsets(buffer: bytearray, pointer_offsets: Sequence[int], relative=True) -> u32: cursor = 0 # used to add up the sum of all the offsets up to the current one offset_so_far = 0 for offset in pointer_offsets: if relative: offset_to_encode = offset - offset_so_far else: # If we are not working relative, we can just use the offset directly. offset_to_encode = offset # This tells the loop whether it needs to encode null bytes, if at least one higher byte was non-zero has_higher_non_zero = False # Set the value to the latest offset, so we can properly subtract it from the next offset. offset_so_far = offset # Encode every bytes of the 4 bytes integer we have to for i in range(4, 0, -1): currentbyte = (offset_to_encode >> (7 * (i - 1))) & 0x7F # the lowest byte to encode is special if i == 1: # If its the last byte to append, leave the highest bit to 0 ! buffer[cursor] = currentbyte cursor += 1 elif currentbyte != 0 or has_higher_non_zero: # if any bytes but the lowest one! If not null OR if we have encoded a higher non-null byte before! buffer[cursor] = currentbyte | 0x80 cursor += 1 has_higher_non_zero = True return u32(cursor + 1)
def _rebuild_egg(self): store: Gtk.ListStore = self.builder.get_object('egg_store') learn_set = self._waza_p.learnsets[self.item_id] learn_set.egg_moves = [] for row in store: learn_set.egg_moves.append(u32(int(row[0]))) self._mark_moves_as_modified()
def on_list_store_row_changed(self, store, path, l_iter): """Propagate changes to list store entries to the lists.""" if self._loading: return name_string_id, name_string, points_needed_next, storage_capacity, item_id, item_name, idx = store[ path][:] self._rank_up_table[idx] = Rank(u32(name_string_id), u32(int(points_needed_next)), u32(int(storage_capacity)), u32(item_id)) # Update the actual name_string sp = self.module.project.get_string_provider() sp.get_model().strings[sp.get_index(StringType.RANK_NAMES, idx)] = name_string sp.mark_as_modified() logger.debug(f"Updated list entry {idx}: {self._rank_up_table[idx]}") self.module.set_rank_list(self._rank_up_table)
def read_u32(data: ByteReadable, start: int = 0, *, big_endian: bool = False) -> u32: """Returns an unsigned 32-bit integer from the bytes-like object at the given position.""" return u32( int.from_bytes(data[start:(start + 4)], byteorder='big' if big_endian else 'little', signed=False))
def _save_guest_pokemon_data(self): store: Gtk.ListStore = self.builder.get_object( 'store_tree_guest_pokemon_data') guest_pokemon_list = [] for i, row in enumerate(store): guest_pokemon_list.append( GuestPokemon( u32(int(row[1])), u16(self._get_monster_id_from_display_name(row[2])), u16(int(row[3])), [ u16(self._get_move_id_from_display_name(row[4])), u16(self._get_move_id_from_display_name(row[5])), u16(self._get_move_id_from_display_name(row[6])), u16(self._get_move_id_from_display_name(row[7])) ], u16(int(row[8])), u16(int(row[9])), u16(int(row[10])), u16(int(row[11])), u16(int(row[12])), u16(int(row[13])), u16(int(row[14])), u16(int(row[15])), u32(int(row[16])))) self.module.set_guest_pokemon_data(guest_pokemon_list) # Update our copy of the binary self.arm9 = self.module.project.get_binary(BinaryName.ARM9)
def _save_td(self): self._dungeon_tilesets.clear() for row in self.builder.get_object('dungeon_tileset_store'): self._dungeon_tilesets.append( GroundTilesetMapping( row[1], row[2], u8(int(row[5])), u32(0), )) self.module.save_dungeon_tilesets(self._dungeon_tilesets)
def on_import_clicked(self, *args): dialog: Gtk.Dialog = self.builder.get_object('dialog_import_settings') self.builder.get_object('image_path_setting').unselect_all() # Init available categories cb_store: Gtk.ListStore = self.builder.get_object('image_type_store') cb: Gtk.ComboBoxText = self.builder.get_object('image_type_setting') self._fill_available_image_types_into_store(cb_store) # Set current WTE file settings by default for i, depth in enumerate(cb_store): if self.wte.image_type.value == depth[0]: cb.set_active(i) self.builder.get_object('chk_discard_palette').set_active( not self.wte.has_palette()) dialog.set_attached_to(MainController.window()) dialog.set_transient_for(MainController.window()) resp = dialog.run() dialog.hide() if resp == ResponseType.OK: img_fn: str = self.builder.get_object( 'image_path_setting').get_filename() try: img_pil = Image.open(img_fn, 'r') except Exception as err: display_error(sys.exc_info(), str(err), _("Filename not specified.")) if img_fn is not None: depth = cb_store[cb.get_active_iter()][0] discard: bool = self.builder.get_object( 'chk_discard_palette').get_active() try: self.wte.from_pil( img_pil, WteImageType(depth), # type: ignore discard) except ValueError as err: display_error(sys.exc_info(), str(err), _("Imported image size too big.")) except AttributeError as err: display_error(sys.exc_info(), str(err), _("Not an indexed image.")) self.module.mark_wte_as_modified(self.item, self.wte, self.wtu) self._init_wte() self._reinit_image() if self.wtu: self.wtu.image_mode = u32(self.wte.get_mode())