コード例 #1
0
def test_assemble_with_label():
    start_address = 0x80085760 + 0x9C

    patch = [
        ppc.bl(8, relative=True),
        ppc.bl("other"),
        ppc.nop(),
        ppc.nop().with_label("other"),
    ]

    assembled_bytes = list(
        assembler.assemble_instructions(start_address, patch))

    assert assembled_bytes == [
        0x48,
        0x00,
        0x00,
        0x09,
        0x48,
        0x00,
        0x00,
        0x09,
        0x60,
        0x00,
        0x00,
        0x00,
        0x60,
        0x00,
        0x00,
        0x00,
    ]
コード例 #2
0
def test_remote_execution_patch_end():
    # Run
    patch = all_prime_dol_patches.remote_execution_patch_end()
    data = bytes(assembler.assemble_instructions(1000, patch))

    # Assert
    assert data == b"\xbb\xc1\x00\x2c\x80\x01\x00\x38\x7c\x08\x03\xa6\x38\x21\x00\x34\x4e\x80\x00\x20"
コード例 #3
0
def create_remote_execution_body(
        patch_addresses: StringDisplayPatchAddresses,
        instructions: List[BaseInstruction]) -> Tuple[int, bytes]:
    """
    Return the address and the bytes for executing the given instructions via remote code execution.
    """
    update_hint_state = patch_addresses.update_hint_state

    remote_start_instructions = remote_execution_patch_start()
    remote_start_byte_count = assembler.byte_count(remote_start_instructions)

    body_address = update_hint_state + remote_start_byte_count
    body_instructions = list(instructions)
    body_instructions.extend(remote_execution_patch_end())
    body_bytes = bytes(
        assembler.assemble_instructions(body_address, body_instructions))

    if len(body_bytes
           ) > _remote_execution_max_byte_count - remote_start_byte_count:
        raise ValueError(
            f"Received {len(body_instructions)} instructions with total {len(body_bytes)} bytes, "
            f"but limit is {_remote_execution_max_byte_count - remote_start_byte_count}."
        )

    return body_address, body_bytes
コード例 #4
0
def test_remote_execution_clear_pending_op():
    # Run
    patch = all_prime_dol_patches.remote_execution_clear_pending_op()
    data = bytes(assembler.assemble_instructions(1000, patch))

    # Assert
    assert data == b'\x38\xc0\x00\x00\x98\xdf\x00\x02'
コード例 #5
0
    def export_game(self, patch_data: dict, export_params: GameExportParams,
                    progress_update: status_update_lib.ProgressUpdateCallable) -> None:
        assert isinstance(export_params, PrimeGameExportParams)

        input_file = export_params.input_path
        output_file = export_params.output_path

        export_params.cache_path.mkdir(parents=True, exist_ok=True)
        cache_dir = os.fspath(export_params.cache_path)

        symbols = py_randomprime.symbols_for_file(input_file)

        new_config = copy.copy(patch_data)
        has_spoiler = new_config.pop("hasSpoiler")
        room_rando_mode = new_config.pop("roomRandoMode")
        new_config["inputIso"] = os.fspath(input_file)
        new_config["outputIso"] = os.fspath(output_file)
        new_config["gameConfig"]["updateHintStateReplacement"] = list(
            assembler.assemble_instructions(
                symbols["UpdateHintState__13CStateManagerFf"],
                all_prime_dol_patches.remote_execution_patch(),
                symbols=symbols)
        )
        new_config["preferences"]["cacheDir"] = cache_dir

        assets_meta = {}
        updaters = [progress_update]
        if export_params.use_echoes_models:
            assets_path = export_params.asset_cache_path
            asset_conversion_progress = None
            if asset_conversion.get_asset_cache_version(assets_path) != asset_conversion.ECHOES_MODELS_VERSION:
                updaters = status_update_lib.split_progress_update(progress_update, 3)
                asset_conversion_progress = updaters[1]
                from randovania.games.prime2.exporter.game_exporter import extract_and_backup_iso
                extract_and_backup_iso(export_params.echoes_input_path, export_params.echoes_contents_path,
                                       export_params.echoes_backup_path, updaters[0])
            assets_meta = asset_conversion.convert_prime2_pickups(assets_path, asset_conversion_progress)
            new_config["externAssetsDir"] = os.fspath(assets_path)

        # Replace models
        adjust_model_names(new_config, assets_meta, export_params.use_echoes_models)

        patch_as_str = json.dumps(new_config, indent=4, separators=(',', ': '))
        if has_spoiler:
            output_file.with_name(f"{output_file.stem}-patcher.json").write_text(patch_as_str)
            if room_rando_mode != RoomRandoMode.NONE.value:
                self.make_room_rando_maps(output_file, f"{output_file.stem}", new_config["levelData"])

        os.environ["RUST_BACKTRACE"] = "1"

        try:
            py_randomprime.patch_iso_raw(
                patch_as_str,
                py_randomprime.ProgressNotifier(lambda percent, msg: updaters[-1](msg, percent)),
            )
        except BaseException as e:
            if isinstance(e, Exception):
                raise
            else:
                raise RuntimeError(f"randomprime panic: {e}") from e
コード例 #6
0
 def write_instructions(self, address_or_symbol: Union[int, str],
                        instructions: List[assembler.BaseInstruction]):
     address = self.resolve_symbol(address_or_symbol)
     self.write(
         address,
         assembler.assemble_instructions(address,
                                         instructions,
                                         symbols=self.symbols))
コード例 #7
0
def test_give_item_patch(powerup_address: all_prime_dol_patches.PowerupFunctionsAddresses):
    # Run
    patch = all_prime_dol_patches.adjust_item_amount_and_capacity_patch(powerup_address,
                                                                        RandovaniaGame.METROID_PRIME_ECHOES, 10, 5)
    data = bytes(assembler.assemble_instructions(0x80008020, patch))

    # Assert
    assert data == (b"\x80\x7f\x15\x0c\x38\x80\x00\x0a\x38\xa0\x00\x05\x48\x06\xd8\xc5\x80\x7f\x15\x0c"
                    b"\x38\x80\x00\x0a\x38\xa0\x00\x05\x48\x06\xd7\x25")
コード例 #8
0
def test_call_display_hud_patch(string_display: all_prime_dol_patches.StringDisplayPatchAddresses):
    # Run
    patch = all_prime_dol_patches.call_display_hud_patch(string_display)
    data = bytes(assembler.assemble_instructions(string_display.update_hint_state, patch))

    # Assert
    assert data == (b"\x3c\xa0\x41\x00\x38\xc0\x00\x00\x38\xe0\x00\x01\x39\x20\x00\x09\x90\xa1\x00\x10"
                    b"\x98\xe1\x00\x14\x98\xc1\x00\x15\x98\xc1\x00\x16\x98\xe1\x00\x17\x91\x21\x00\x18"
                    b"\x38\x61\x00\x1c\x3c\x80\x00\x00\x60\x84\x90\x00\x48\x2c\x73\x89\x38\x81\x00\x10"
                    b"\x48\x03\x33\x6d")
コード例 #9
0
def test_remote_execution_patch_start():
    # Run
    patch = all_prime_dol_patches.remote_execution_patch_start()
    data = bytes(assembler.assemble_instructions(0x80008020, patch))

    # Assert
    assert data == (b'\x94\x21\xff\xcc\x7c\x08\x02\xa6\x90\x01\x00\x38\xbf\xc1\x00\x2c\x7c\x7f\x1b\x78'
                    b'\x88\x9f\x00\x02\x2c\x04\x00\x00\x40\x82\x00\x18\xbb\xc1\x00\x2c\x80\x01\x00\x38'
                    b'\x7c\x08\x03\xa6\x38\x21\x00\x34\x4e\x80\x00\x20\x3f\xc0\x80\x00\x63\xde\x80\x74'
                    b'\x38\x80\x01\x80\x7c\x04\xf7\xac\x2c\x04\x00\x00\x38\x84\xff\xe0\x40\x82\xff\xf4'
                    b'\x7c\x00\x04\xac\x4c\x00\x01\x2c')
コード例 #10
0
def test_composite_bl_double():
    target_address = 0x80085760
    start_address = 0x80085760 + 0x9C

    inc = ppc.bl(target_address)
    comp = custom_ppc.CompositeInstruction((inc, inc))

    composite_bytes = list(comp.bytes_for(start_address, symbols={}))
    assembled_bytes = list(
        assembler.assemble_instructions(start_address, [inc, inc]))

    assert composite_bytes == [0x4b, 0xff, 0xff, 0x65, 0x4b, 0xff, 0xff, 0x61]
    assert composite_bytes == assembled_bytes
コード例 #11
0
 def write_instructions(self, address: int, instructions: Iterable[assembler.BaseInstruction]):
     self.write(address, assembler.assemble_instructions(address, instructions))