コード例 #1
0
    def watch(self):
        ov11 = self.rom_data.binaries['overlay/overlay_0011.bin']

        self.register_exec(
            ov11.symbols['GroundMainLoop'].begin_absolute + 0x3C,
            self.hook__ground_start)
        self.register_exec(
            ov11.symbols['GroundMainLoop'].begin_absolute + 0x210,
            self.hook__ground_quit)
        self.register_exec(
            ov11.symbols['GroundMainLoop'].begin_absolute + 0x598,
            self.hook__ground_map_change)
        self.register_exec(ov11.symbols['SsbLoad1'].begin_absolute,
                           self.hook__ssb_load)
        self.register_exec(ov11.symbols['SsbLoad2'].begin_absolute,
                           self.hook__ssb_load)
        self.register_exec(
            ov11.symbols['StationLoadHanger'].begin_absolute + 0xC0,
            self.hook__ssx_load)
        self.register_exec(
            ov11.symbols['ScriptStationLoadTalk'].begin_absolute,
            self.hook__talk_load)
        threadsafe_emu(
            self.emu_thread, lambda: self.emu_thread.emu.memory.register_write(
                self.pnt_unionall_load_addr, self.hook__write_unionall_address,
                4))
コード例 #2
0
    def _queue_variable_write(self, var_id: int, offset: int, value: int):
        threadsafe_emu(
            self.emu_thread,
            lambda: GameVariable.write(self.emu_thread.emu.memory, self.
                                       rom_data, var_id, offset, value))

        # Also update the cached values
        for var in self._variable_cache.keys():
            if var.id == var_id:
                self._variable_cache[var][offset] = value
                break
コード例 #3
0
    def uninit(self):
        notebook: Gtk.Notebook = self.builder.get_object('variables_notebook')
        for _ in range(0, notebook.get_n_pages()):
            # TODO: Do the children need to be destroyed?
            notebook.remove_page(0)

        threadsafe_emu(
            self.emu_thread, lambda: self.emu_thread.emu.memory.register_exec(
                self.rom_data.binaries['arm9.bin'].functions[
                    'SaveScriptVariableValue'].begin_absolute, None))
        threadsafe_emu(
            self.emu_thread, lambda: self.emu_thread.emu.memory.register_exec(
                self.rom_data.binaries['arm9.bin'].functions[
                    'SaveScriptVariableValueWithOffset'].begin_absolute, None))
コード例 #4
0
    def deserialize(self, state: dict):
        """Load a saved state back from a dict"""
        self._running = state['running']
        self._load_ssb_for = state['load_ssb_for']
        self._loaded_ssb_files = [
            SsbFileInRam(fn_and_hash[0], hng, fn_and_hash[1])
            if fn_and_hash is not None else None
            for hng, fn_and_hash in enumerate(state['ssbs'])
        ]
        # - Load SSB file hashes from ground state file, if the hashes don't match on reload with the saved
        #   files, mark them as not up to date in RAM and show warning for affected files.
        were_invalid = []
        for f in self._loaded_ssb_files:
            if f is not None and f.hash != self.ssb_file_manager.hash_for(
                    f.file_name):
                were_invalid.append(f.file_name)
        if len(were_invalid) > 0:
            n = '\n'
            md = self.context.message_dialog_cls(
            )(None,
              Gtk.DialogFlags.DESTROY_WITH_PARENT,
              Gtk.MessageType.WARNING,
              Gtk.ButtonsType.OK,
              f"Some SSB script files that are loaded in RAM were changed. You can not debug "
              f"these files, until they are reloaded:\n{n.join(were_invalid)}",
              title="Warning!")
            md.set_position(Gtk.WindowPosition.CENTER)

            # Some timing issues here.
            def run_and_destroy():
                md.run()
                md.destroy()

            GLib.idle_add(lambda: run_and_destroy())
        for ssb in self._loaded_ssb_files:
            if ssb is not None:
                self.ssb_file_manager.open_in_ground_engine(ssb.file_name)
                if ssb.file_name in were_invalid:
                    self.ssb_file_manager.mark_invalid(ssb.file_name)
        self._loaded_ssx_files = [
            SsxFileInRam(fn, hng) if fn is not None else None
            for hng, fn in enumerate(state['ssxs'])
        ]

        # Also update the load address for unionall
        threadsafe_emu(
            self.emu_thread, lambda: self.unionall_load_addr.set(
                self.emu_thread.emu.memory.unsigned.read_long(
                    self.pnt_unionall_load_addr)))
コード例 #5
0
    def init(self, rom_data: Pmd2Data):
        if not self.emu_thread:
            return
        self.rom_data = rom_data
        self.var_form_elements = [
            None for _ in range(0, len(rom_data.script_data.game_variables))
        ]
        notebook: Gtk.Notebook = self.builder.get_object('variables_notebook')

        # Build the GTK form
        for category, items in self.CATEGORIES.items():
            tab_label = Gtk.Label.new(category)
            tab_label.show()
            sw: Gtk.ScrolledWindow = Gtk.ScrolledWindow.new()
            page_grid: Gtk.Grid = Gtk.Grid.new()
            page_grid.set_margin_bottom(5)
            page_grid.set_margin_left(5)
            page_grid.set_margin_top(5)
            page_grid.set_margin_right(5)
            sw.add(page_grid)
            notebook.append_page(sw, tab_label)
            row = 0
            for item in items:
                var: Pmd2ScriptGameVar = rom_data.script_data.game_variables__by_name[
                    item]
                self.var_form_elements[var.id] = [
                    None for _ in range(0, var.nbvalues)
                ]
                label: Gtk.Label = Gtk.Label.new(item)
                label.set_valign(Gtk.Align.START)
                label.set_markup(f'<b>{item}</b>')
                label.set_halign(Gtk.Align.START)
                label.set_margin_top(8)
                label.set_margin_bottom(4)
                page_grid.attach(label, 0, row, 1, 1)
                if var.nbvalues == 1:
                    page_grid.attach(
                        self.create_var_form_element(var, 0, no_label=True), 0,
                        row + 1, 1, 1)
                elif var.name.startswith(
                        'SCENARIO_'
                ) and var.nbvalues == 2 and var.type == GameVariableType.UINT8:
                    sub_box: Gtk.Box = Gtk.Box.new(Gtk.Orientation.VERTICAL, 5)
                    sub_box.set_margin_bottom(2)
                    page_grid.attach(sub_box, 0, row + 1, 1, 1)
                    sub_box.pack_start(
                        self.create_var_form_element(var, 0, label='Scenario'),
                        True, True, 0)
                    sub_box.pack_start(
                        self.create_var_form_element(var, 1, label='Level'),
                        True, True, 0)
                elif var.type == GameVariableType.BIT:
                    sub_grid: Gtk.Grid = Gtk.Grid.new()
                    sub_grid.set_margin_bottom(2)
                    page_grid.attach(sub_grid, 0, row + 1, 1, 1)
                    for i in range(0, var.nbvalues):
                        x = i % 3
                        y = math.floor(i / 3)
                        sub_grid.attach(self.create_var_form_element(var, i),
                                        x, y, 1, 1)
                else:
                    sub_box: Gtk.Box = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0)
                    sub_box.set_margin_bottom(2)
                    page_grid.attach(sub_box, 0, row + 1, 1, 1)
                    for i in range(0, var.nbvalues):
                        sub_box.pack_start(
                            self.create_var_form_element(var, i), True, True,
                            0)
                row += 2

        notebook.show_all()
        self.sync()

        threadsafe_emu(
            self.emu_thread, lambda: self.emu_thread.emu.memory.register_exec(
                self.rom_data.binaries['arm9.bin'].functions[
                    'SaveScriptVariableValue'].begin_absolute, self.
                hook__variable_set))
        threadsafe_emu(
            self.emu_thread, lambda: self.emu_thread.emu.memory.register_exec(
                self.rom_data.binaries['arm9.bin'].functions[
                    'SaveScriptVariableValueWithOffset'].begin_absolute, self.
                hook__variable_set_with_offset))
コード例 #6
0
 def debug_dungeon_skip(self, value: bool):
     self._debug_dungeon_skip = value
     if self.rom_data and (not self.ground_engine_state
                           or not self.ground_engine_state.running):
         threadsafe_emu(self.emu_thread,
                        lambda: self._set_dungeon_debug_skip())
コード例 #7
0
 def register_write(self, pnt, cb):
     threadsafe_emu(
         self.emu_thread,
         lambda: self.emu_thread.emu.memory.register_write(pnt, cb))
コード例 #8
0
 def pnt(self):
     return threadsafe_emu(
         self.emu_thread, lambda: self.emu_thread.emu.memory.unsigned.read_long(self.pnt_to_block_start)
     )