예제 #1
0
 def cardinal(prefix: str) -> None:
     ig.dummy(45, 1)
     ig.same_line()
     binding_button('n64-' + prefix + '^', prefix + '^')
     binding_button('n64-' + prefix + '<', prefix + '<')
     ig.same_line()
     ig.set_cursor_pos((110, ig.get_cursor_pos().y))
     binding_button('n64-' + prefix + '>', prefix + '>')
     ig.dummy(45, 1)
     ig.same_line()
     binding_button('n64-' + prefix + 'v', prefix + 'v')
예제 #2
0
    def render(id: str) -> None:
        nonlocal error

        if error is not None:
            message = error.strip()
            ig.text('Wafel has crashed. Cause:')
            lines = message.split('\n')
            ig.input_text_multiline(
                '##error-msg',
                message,
                len(message) + 1,
                max(map(len, lines)) * 10,
                (len(lines) + 1) * ig.get_text_line_height() + 6,
            )

            ig.dummy(10, 10)

            if ig.button('Exit'):
                log.info('Aborted')
                sys.exit(1)
            ig.same_line()
            if ig.button('Try to save'):
                if view.ask_save_filename():
                    view.save()
            # ig.same_line()
            # if view is not None and ig.button('Try to continue (mad lads only)'):
            #   view.reload_ui()
            #   error = None
            return

        try:
            if hasattr(model, 'pipeline'):
                log.timer.get_num_copies = lambda: model.pipeline.num_copies(
                ) if config.dev_mode else 0
                log.timer.get_num_updates = lambda: model.pipeline.num_advances(
                ) if config.dev_mode else 0

            log.timer.begin_frame()
            ig.try_render(lambda: do_render(id))
        except:
            error = traceback.format_exc()
            log.error('Caught: ' + error)
        finally:
            log.timer.end_frame()
예제 #3
0
def render_controller_settings(id: str) -> None:
    ig.push_id(id)
    begin_binding_form()

    def cardinal(prefix: str) -> None:
        ig.dummy(45, 1)
        ig.same_line()
        binding_button('n64-' + prefix + '^', prefix + '^')
        binding_button('n64-' + prefix + '<', prefix + '<')
        ig.same_line()
        ig.set_cursor_pos((110, ig.get_cursor_pos().y))
        binding_button('n64-' + prefix + '>', prefix + '>')
        ig.dummy(45, 1)
        ig.same_line()
        binding_button('n64-' + prefix + 'v', prefix + 'v')

    binding_button('n64-A', 'A')
    binding_button('n64-B', 'B')
    binding_button('n64-Z', 'Z')

    ig.dummy(1, 5)
    binding_button('n64-L', 'L')
    binding_button('n64-R', 'R')
    binding_button('n64-S', 'S')

    ig.dummy(1, 5)
    cardinal('')

    ig.dummy(1, 15)
    cardinal('C')

    ig.dummy(1, 15)
    cardinal('D')

    ig.dummy(200, 1)
    ig.pop_id()
예제 #4
0
def render_key_binding_settings(id: str) -> None:
    ig.push_id(id)
    begin_binding_form()

    ig.text('Frame advance:')
    button_width = 0
    binding_button('frame-prev-fast', '-10', button_width)
    binding_button('frame-prev', '-1', button_width)
    binding_button('frame-prev-alt', '-1', button_width)
    binding_button('frame-next', '+1', button_width)
    binding_button('frame-next-alt', '+1', button_width)
    binding_button('frame-next-fast', '+10', button_width)

    ig.dummy(1, 5)

    ig.text('3D movement:')
    button_width = 70
    binding_button('3d-camera-move-f', 'Forward', button_width)
    binding_button('3d-camera-move-b', 'Back', button_width)
    binding_button('3d-camera-move-l', 'Left', button_width)
    binding_button('3d-camera-move-r', 'Right', button_width)
    binding_button('3d-camera-move-u', 'Up', button_width)
    binding_button('3d-camera-move-d', 'Down', button_width)

    ig.dummy(1, 5)

    ig.text('Playback:')
    button_width = 90
    binding_button('playback-play', 'Play', button_width)
    binding_button('playback-rewind', 'Rewind', button_width)
    binding_button('playback-speed-up', 'Speed up', button_width)
    binding_button('playback-slow-down', 'Slow down', button_width)
    ig.text_colored(
        'Tip: Use the frame advance keys\nduring playback to change speed\ntemporarily.',
        1.0,
        1.0,
        1.0,
        0.5,
    )

    ig.dummy(200, 1)
    ig.pop_id()
예제 #5
0
    def render_frame_log_tab(self) -> None:
        frame_offset = use_state('frame-offset', 1)
        round_numbers = use_state('round-numbers', True)

        ig.push_item_width(210)
        _, frame_offset.value = ig.combo(
            '##frame-offset',
            frame_offset.value,
            ['previous -> current frame', 'current -> next frame'],
        )
        ig.pop_item_width()
        _, round_numbers.value = ig.checkbox('Round##round-numbers',
                                             round_numbers.value)
        ig.dummy(1, 10)

        events = self.model.pipeline.frame_log(self.model.selected_frame +
                                               frame_offset.value)

        def string(addr: object) -> str:
            return self.model.pipeline.read_string(0,
                                                   dcast(Address,
                                                         addr)).decode('utf-8')

        def f32(number: object) -> str:
            assert isinstance(number, float)
            if round_numbers.value:
                return '%.3f' % number
            else:
                return str(number)

        def vec3f(vector: object) -> str:
            return '(' + ', '.join(map(f32, dcast(list, vector))) + ')'

        def action(action: object) -> str:
            return self.model.action_names[dcast(int, action)]

        indent = 0
        action_indent = 0

        def show_text(text: str) -> None:
            ig.text('    ' * indent + text)

        for event in events:
            if event['type'] == 'FLT_CHANGE_ACTION':
                show_text(
                    f'change action: {action(event["from"])} -> {action(event["to"])}'
                )
            elif event['type'] == 'FLT_CHANGE_FORWARD_VEL':
                show_text(
                    f'change f vel: {f32(event["from"])} -> {f32(event["to"])} ({string(event["reason"])})'
                )
            elif event['type'] == 'FLT_WALL_PUSH':
                show_text(
                    f'wall push: {vec3f(event["from"])} -> {vec3f(event["to"])} (surface {event["surface"]})'
                )
            elif event['type'] == 'FLT_BEGIN_MOVEMENT_STEP':
                type_ = {1: 'air', 2: 'ground', 3: 'water'}[event['stepType']]
                show_text(f'{type_} step {event["stepNum"]}:')
                indent += 1
            elif event['type'] == 'FLT_END_MOVEMENT_STEP':
                indent -= 1
            elif event['type'] == 'FLT_EXECUTE_ACTION':
                indent -= action_indent
                action_indent = 0
                show_text(f'execute action: {action(event["action"])}')
                indent += 1
                action_indent += 1
            else:
                sorted_event = {'type': event['type']}
                sorted_event.update(sorted(event.items()))
                show_text(str(sorted_event))
예제 #6
0
    def render_input_tab(self, tab: TabId) -> None:
        column_sizes = [170, 370, 200]

        ig.set_next_window_content_size(sum(column_sizes), 0)
        ig.begin_child('##input', flags=ig.WINDOW_HORIZONTAL_SCROLLING_BAR)
        ig.columns(3)

        for i, w in enumerate(column_sizes):
            ig.set_column_width(i, w)

        def render_button(button: str) -> None:
            self.render_variable(
                tab,
                Variable('input-button-' + button).with_frame(
                    self.model.selected_frame),
                10,
                25,
            )

        ig.dummy(1, 3)
        render_button('a')
        ig.same_line()
        render_button('b')
        ig.same_line()
        render_button('z')
        ig.dummy(1, 5)
        render_button('s')
        ig.same_line()
        ig.dummy(43, 1)
        ig.same_line()
        render_button('r')
        ig.dummy(1, 5)
        ig.dummy(43, 1)
        ig.same_line()
        render_button('cu')
        ig.dummy(17, 1)
        ig.same_line()
        render_button('cl')
        ig.same_line()
        render_button('cr')
        ig.dummy(43, 1)
        ig.same_line()
        render_button('cd')

        ig.next_column()
        self.render_intended_stick_control('intended')
        ig.next_column()
        self.render_stick_control('joystick', tab)

        ig.columns(1)
        ig.end_child()
예제 #7
0
    def render_intended_stick_control(self, id: str) -> None:
        up_options = ['3d view', 'mario yaw', 'stick y', 'world x']
        up_option = use_state('up-option', 0)

        ig.text('up =')
        ig.same_line()
        ig.push_item_width(100)
        _, up_option.value = ig.combo('##up-option', up_option.value,
                                      up_options)
        ig.pop_item_width()
        ig.dummy(1, 10)

        stick_x_var = Variable('input-stick-x').with_frame(
            self.model.selected_frame)
        stick_y_var = Variable('input-stick-y').with_frame(
            self.model.selected_frame)

        face_yaw = dcast(
            int,
            self.model.get(
                Variable('mario-face-yaw').with_frame(
                    self.model.selected_frame)))
        camera_yaw = dcast(
            int,
            self.model.get(
                Variable('camera-yaw').with_frame(self.model.selected_frame))
            or 0)
        squish_timer = dcast(
            int,
            self.model.get(self.model.selected_frame,
                           'gMarioState->squishTimer'))
        active_face_yaw = face_yaw

        events = self.model.pipeline.frame_log(self.model.selected_frame + 1)

        active_face_yaw_action = None
        for event in events:
            if event['type'] == 'FLT_EXECUTE_ACTION':
                action_name = self.model.action_names[event['action']]
                active_face_yaw = event['faceAngle'][1]
                active_face_yaw_action = action_name
                if action_name == 'idle':
                    break

        up_angle = {
            'mario yaw': active_face_yaw,
            'stick y': camera_yaw + 0x8000,
            'world x': 0x4000,
            '3d view': self.model.rotational_camera_yaw,
        }[up_options[up_option.value]]
        self.model.input_up_yaw = up_angle

        raw_stick_x = dcast(int, self.model.get(stick_x_var))
        raw_stick_y = dcast(int, self.model.get(stick_y_var))

        adjusted = stick_raw_to_adjusted(raw_stick_x, raw_stick_y)
        intended = stick_adjusted_to_intended(
            adjusted,
            face_yaw,
            camera_yaw,
            squish_timer != 0,
        )

        def render_value(label: str, value: object,
                         formatter: VariableFormatter) -> Optional[Any]:
            label_width = 60
            value_size = (
                60 if label == 'dyaw' else 80,
                ig.get_text_line_height() +
                2 * ig.get_style().frame_padding[1],
            )
            ig.push_item_width(label_width)
            ig.selectable(label, width=label_width)
            ig.pop_item_width()
            ig.same_line()
            new_value, _, _ = ui.render_variable_value('value-' + label, value,
                                                       formatter, value_size)
            return None if new_value is None else new_value.value

        target_yaw: Optional[int] = None
        target_dyaw: Optional[int] = None
        target_mag: Optional[float] = None

        target_mag = render_value('int mag', intended.mag, FloatFormatter())
        target_yaw = render_value('int yaw', intended.yaw,
                                  DecimalIntFormatter())
        dyaw = intended.yaw - active_face_yaw
        target_dyaw = render_value('dyaw', dyaw, DecimalIntFormatter())

        ig.same_line()
        if ig.button('?'):
            ig.open_popup('active-yaw-expl')
        if ig.begin_popup('active-yaw-expl'):
            ig.text(f'{intended.yaw} - {active_face_yaw} = {dyaw}')
            ig.text(f'intended yaw = {intended.yaw}')
            if active_face_yaw == face_yaw:
                ig.text(f'face yaw = {face_yaw}')
            if active_face_yaw != face_yaw:
                ig.text(
                    f'face yaw = {active_face_yaw} at start of {active_face_yaw_action} action'
                )
                ig.text(f'(face yaw = {face_yaw} at start of frame)')
            ig.end_popup()

        if dyaw not in range(0, 16):
            if ig.button('dyaw = 0'):
                target_dyaw = 0

        if target_yaw is not None or target_dyaw is not None or target_mag is not None:
            relative_to = 0 if target_yaw is not None else active_face_yaw
            if target_dyaw is not None:
                target_yaw = active_face_yaw + target_dyaw
            if target_yaw is None:
                target_yaw = intended.yaw
            if target_mag is None:
                target_mag = intended.mag

            new_raw_stick_x, new_raw_stick_y = intended_to_raw(
                face_yaw, camera_yaw, squish_timer, target_yaw, target_mag,
                relative_to)

            self.model.set(stick_x_var, new_raw_stick_x)
            self.model.set(stick_y_var, new_raw_stick_y)

        n_a = intended.yaw - up_angle
        n_x = intended.mag / 32 * math.sin(-n_a * math.pi / 0x8000)
        n_y = intended.mag / 32 * math.cos(n_a * math.pi / 0x8000)

        ig.set_cursor_pos((ig.get_cursor_pos().x + 155, 0))
        new_n = ui.render_joystick_control(id, n_x, n_y, 'circle')

        if new_n is not None:
            new_n_a = int(math.atan2(-new_n[0], new_n[1]) * 0x8000 / math.pi)
            new_intended_yaw = up_angle + new_n_a
            new_intended_mag = 32 * math.sqrt(new_n[0]**2 + new_n[1]**2)

            new_raw_stick_x, new_raw_stick_y = intended_to_raw(
                face_yaw,
                camera_yaw,
                squish_timer,
                new_intended_yaw,
                new_intended_mag,
                relative_to=0)

            self.model.set(stick_x_var, new_raw_stick_x)
            self.model.set(stick_y_var, new_raw_stick_y)