Exemple #1
0
def shift_all_colors_in_mat3(self, file_name, j3d_file, h_shift, v_shift):
    for i, color in enumerate(j3d_file.mat3.reg_colors):
        r, g, b, a = color
        if r < 0 or g < 0 or b < 0:
            # Negative color? Skip it to avoid errors.
            continue
        r, g, b = texture_utils.hsv_shift_color((r, g, b), h_shift, v_shift)
        j3d_file.mat3.reg_colors[i] = (r, g, b, a)

    for i, color in enumerate(j3d_file.mat3.konst_colors):
        r, g, b, a = color
        r, g, b = texture_utils.hsv_shift_color((r, g, b), h_shift, v_shift)
        j3d_file.mat3.konst_colors[i] = (r, g, b, a)
def shift_hardcoded_color_in_rel(rel, offset, h_shift, v_shift):
    r = rel.read_data(read_u8, offset + 0)
    g = rel.read_data(read_u8, offset + 1)
    b = rel.read_data(read_u8, offset + 2)
    r, g, b = texture_utils.hsv_shift_color((r, g, b), h_shift, v_shift)
    rel.write_data(write_u8, offset + 0, r)
    rel.write_data(write_u8, offset + 1, g)
    rel.write_data(write_u8, offset + 2, b)
def shift_all_colors_in_particle(self, particle, h_shift, v_shift):
    #print("%04X" % particle_id)
    #print(particle.tdb1.texture_filenames)

    # Changing value/saturation of particle colors can sometimes make them disappear or be bigger/smaller than in vanilla if the changes are too extreme, so limit to hue shifting only for particles.
    v_shift = 0

    r, g, b, a = particle.bsp1.color_prm
    r, g, b = texture_utils.hsv_shift_color((r, g, b), h_shift, v_shift)
    particle.bsp1.color_prm = (r, g, b, a)

    r, g, b, a = particle.bsp1.color_env
    r, g, b = texture_utils.hsv_shift_color((r, g, b), h_shift, v_shift)
    particle.bsp1.color_env = (r, g, b, a)

    #print(particle.bsp1.color_prm_anm_data_count)
    for keyframe in particle.bsp1.color_prm_anm_table:
        r, g, b, a = keyframe.color
        r, g, b = texture_utils.hsv_shift_color((r, g, b), h_shift, v_shift)
        keyframe.color = (r, g, b, a)

    #print(particle.bsp1.color_env_anm_data_count)
    for keyframe in particle.bsp1.color_env_anm_table:
        r, g, b, a = keyframe.color
        r, g, b = texture_utils.hsv_shift_color((r, g, b), h_shift, v_shift)
        keyframe.color = (r, g, b, a)

    if hasattr(particle, "ssp1"):
        r, g, b, a = particle.ssp1.color_prm
        r, g, b = texture_utils.hsv_shift_color((r, g, b), h_shift, v_shift)
        particle.ssp1.color_prm = (r, g, b, a)

        r, g, b, a = particle.ssp1.color_env
        r, g, b = texture_utils.hsv_shift_color((r, g, b), h_shift, v_shift)
        particle.ssp1.color_env = (r, g, b, a)
def shift_hardcoded_puppet_ganon_colors(self, h_shift, v_shift):
    # Puppet ganon's strings
    rel = self.get_rel("files/rels/d_a_bgn.rel")
    offset = 0xF0A8
    shift_hardcoded_color_in_rel(rel, offset, h_shift, v_shift)
    offset = 0xF0B0
    shift_hardcoded_color_in_rel(rel, offset, h_shift, v_shift)

    rel = self.get_rel("files/rels/d_a_bgn3.rel")
    r = rel.read_data(read_u8, 0x2CF)
    g = rel.read_data(read_u8, 0x2D7)
    b = rel.read_data(read_u8, 0x2DF)
    r, g, b = texture_utils.hsv_shift_color((r, g, b), h_shift, v_shift)
    rel.write_data(write_u8, 0x2CF, r)
    rel.write_data(write_u8, 0x2D7, g)
    rel.write_data(write_u8, 0x2DF, b)
Exemple #5
0
def shift_all_colors_in_mdl3(self, file_name, j3d_file, h_shift, v_shift):
    for entry in j3d_file.mdl3.entries:
        tev_color_commands = [
            com for com in entry.bp_commands
            if com.register >= BPRegister.TEV_REGISTERL_0.value
            and com.register <= BPRegister.TEV_REGISTERH_3.value
        ]
        assert len(tev_color_commands
                   ) % 2 == 0  # They should come in pairs of low and high

        last_hi_command = None
        last_hi_command_orig_value = None
        for i in range(0, len(tev_color_commands), 2):
            lo_command = tev_color_commands[i + 0]
            hi_command = tev_color_commands[i + 1]

            if hi_command.register != lo_command.register + 1:
                # The only time they're not properly paired is when the hi command gets duplicated an additional 2 times.
                assert last_hi_command is not None
                assert last_hi_command.register == hi_command.register == lo_command.register
                assert last_hi_command_orig_value == hi_command.value == lo_command.value

                # Update the color here too
                hi_command.value = last_hi_command.value
                lo_command.value = last_hi_command.value

                continue

            last_hi_command = hi_command
            last_hi_command_orig_value = hi_command.value

            r = (lo_command.value & 0x0007FF)
            g = (hi_command.value & 0x7FF000) >> 12
            b = (hi_command.value & 0x0007FF)
            a = (lo_command.value & 0x7FF000) >> 12

            r, g, b = texture_utils.hsv_shift_color((r, g, b), h_shift,
                                                    v_shift)

            lo_command.value &= ~0x7FF7FF
            hi_command.value &= ~0x7FF7FF
            lo_command.value |= ((r << 0) & 0x0007FF)
            hi_command.value |= ((g << 12) & 0x7FF000)
            hi_command.value |= ((b << 0) & 0x0007FF)
            lo_command.value |= ((a << 12) & 0x7FF000)
def shift_hardcoded_chuchu_colors(self, h_shift, v_shift):
    # ChuChu particles
    rel = self.get_rel("files/rels/d_a_cc.rel")
    offset = 0x7F88
    for i in range(5):
        shift_hardcoded_color_in_rel(rel, offset + i * 4, h_shift, v_shift)

    # The particles that come off of Dark ChuChus when attacked where they temporarily break apart and reform are tricky.
    # That RGB value is stored as three multiplier floats instead of three bytes, and the red multiplier in the float constant bank is coincidentally reused by other things in the ChuChu code unrelated to color so we can't change that.
    # So we change the asm code to read the red multiplier from elsewhere, and then modify that instead.
    r = int(rel.read_data(read_float, 0x7E9C))
    g = int(rel.read_data(read_float, 0x7EBC))
    b = int(rel.read_data(read_float, 0x7EC0))
    assert r != 0  # Make sure the asm patch was applied
    r, g, b = texture_utils.hsv_shift_color((r, g, b), h_shift, v_shift)
    rel.write_data(write_float, 0x7E9C, r)
    rel.write_data(write_float, 0x7EBC, g)
    rel.write_data(write_float, 0x7EC0, b)
def shift_all_colors_in_trk1(self, file_name, j3d_file, h_shift, v_shift):
    animations = []
    for mat_name, anims in j3d_file.trk1.mat_name_to_reg_anims.items():
        animations += anims
    for mat_name, anims in j3d_file.trk1.mat_name_to_konst_anims.items():
        animations += anims

    for anim_index, anim in enumerate(animations):
        if file_name == "cc.brk" and anim_index == 1:
            # ChuChu eyes material animation, doesn't look right recolored so we just recolor the texture instead
            continue

        assert len(anim.r.keyframes) > 0 and len(anim.g.keyframes) > 0 and len(
            anim.b.keyframes) > 0

        # In some cases (specifically Gohma), there won't be an equal number of keyframes for R G and B, so we can't simply iterate over the list.

        # First make a list of what times are present on the timeline for this animation.
        unique_keyframe_times = []
        for keyframe in (anim.r.keyframes + anim.g.keyframes +
                         anim.b.keyframes):
            if keyframe.time not in unique_keyframe_times:
                unique_keyframe_times.append(keyframe.time)
        unique_keyframe_times.sort()

        def get_keyframe_by_closest_time(keyframes, keyframe_time):
            return min(keyframes, key=lambda kf: abs(kf.time - keyframe_time))

        def get_keyframe_by_exact_time(keyframes, keyframe_time):
            return next((kf for kf in keyframes if kf.time == keyframe_time),
                        None)

        # Then make a list of what the modified colors at each time will be, but don't actually modify them yet since we may need to re-read the values of previous times if the next time is missing a channel.
        modified_colors_by_time = {}
        for keyframe_time in unique_keyframe_times:
            #print("  %d" % keyframe_time)
            r = get_keyframe_by_closest_time(anim.r.keyframes,
                                             keyframe_time).value & 0xFF
            g = get_keyframe_by_closest_time(anim.g.keyframes,
                                             keyframe_time).value & 0xFF
            b = get_keyframe_by_closest_time(anim.b.keyframes,
                                             keyframe_time).value & 0xFF
            #print("    %d %d %d" % (r, g, b))
            r, g, b = texture_utils.hsv_shift_color((r, g, b), h_shift,
                                                    v_shift)
            modified_colors_by_time[keyframe_time] = (r, g, b)

        # Then actually modify the colors.
        for keyframe_time in unique_keyframe_times:
            r, g, b = modified_colors_by_time[keyframe_time]
            r_keyframe = get_keyframe_by_exact_time(anim.r.keyframes,
                                                    keyframe_time)
            if r_keyframe:
                r_keyframe.value = r
            g_keyframe = get_keyframe_by_exact_time(anim.g.keyframes,
                                                    keyframe_time)
            if g_keyframe:
                g_keyframe.value = g
            b_keyframe = get_keyframe_by_exact_time(anim.b.keyframes,
                                                    keyframe_time)
            if b_keyframe:
                b_keyframe.value = b