From 08df8a3c17bd2328ae4e8d9fba9d5a146df8556f Mon Sep 17 00:00:00 2001 From: MysterD Date: Wed, 26 Apr 2023 23:12:22 -0700 Subject: [PATCH] Support more color combiners --- src/pc/gfx/gfx_cc.c | 2 +- src/pc/gfx/gfx_cc.h | 4 + src/pc/gfx/gfx_direct3d_common.cpp | 26 +++- src/pc/gfx/gfx_opengl.c | 56 ++++++-- src/pc/gfx/gfx_pc.c | 216 ++++++++++++++++++++++++----- 5 files changed, 251 insertions(+), 53 deletions(-) diff --git a/src/pc/gfx/gfx_cc.c b/src/pc/gfx/gfx_cc.c index 408e56f04..7785e2b4b 100644 --- a/src/pc/gfx/gfx_cc.c +++ b/src/pc/gfx/gfx_cc.c @@ -17,7 +17,7 @@ void gfx_cc_get_features(uint32_t shader_id, struct CCFeatures *cc_features) { for (int32_t i = 0; i < 2; i++) { for (int32_t j = 0; j < 4; j++) { - if (cc_features->c[i][j] >= SHADER_INPUT_1 && cc_features->c[i][j] <= SHADER_INPUT_4) { + if (cc_features->c[i][j] >= SHADER_INPUT_1 && cc_features->c[i][j] <= SHADER_INPUT_8) { if (cc_features->c[i][j] > cc_features->num_inputs) { cc_features->num_inputs = cc_features->c[i][j]; } diff --git a/src/pc/gfx/gfx_cc.h b/src/pc/gfx/gfx_cc.h index abf5ccd6a..5d0d9bfb8 100644 --- a/src/pc/gfx/gfx_cc.h +++ b/src/pc/gfx/gfx_cc.h @@ -26,6 +26,10 @@ enum { SHADER_INPUT_2, SHADER_INPUT_3, SHADER_INPUT_4, + SHADER_INPUT_5, + SHADER_INPUT_6, + SHADER_INPUT_7, + SHADER_INPUT_8, SHADER_TEXEL0, SHADER_TEXEL0A, SHADER_TEXEL1, diff --git a/src/pc/gfx/gfx_direct3d_common.cpp b/src/pc/gfx/gfx_direct3d_common.cpp index c4e4da6d6..a5ab4171b 100644 --- a/src/pc/gfx/gfx_direct3d_common.cpp +++ b/src/pc/gfx/gfx_direct3d_common.cpp @@ -22,7 +22,7 @@ void get_cc_features(uint32_t shader_id, CCFeatures *cc_features) { for (int32_t i = 0; i < 2; i++) { for (int32_t j = 0; j < 4; j++) { - if (cc_features->c[i][j] >= SHADER_INPUT_1 && cc_features->c[i][j] <= SHADER_INPUT_4) { + if (cc_features->c[i][j] >= SHADER_INPUT_1 && cc_features->c[i][j] <= SHADER_INPUT_8) { if (cc_features->c[i][j] > cc_features->num_inputs) { cc_features->num_inputs = cc_features->c[i][j]; } @@ -71,6 +71,14 @@ static const char *shader_item_to_str(int32_t item, bool with_alpha, bool only_a return with_alpha || !inputs_have_alpha ? "input.input3" : "input.input3.rgb"; case SHADER_INPUT_4: return with_alpha || !inputs_have_alpha ? "input.input4" : "input.input4.rgb"; + case SHADER_INPUT_5: + return with_alpha || !inputs_have_alpha ? "input.input4" : "input.input5.rgb"; + case SHADER_INPUT_6: + return with_alpha || !inputs_have_alpha ? "input.input4" : "input.input6.rgb"; + case SHADER_INPUT_7: + return with_alpha || !inputs_have_alpha ? "input.input4" : "input.input7.rgb"; + case SHADER_INPUT_8: + return with_alpha || !inputs_have_alpha ? "input.input4" : "input.input8.rgb"; case SHADER_TEXEL0: return with_alpha ? "texVal0" : "texVal0.rgb"; case SHADER_TEXEL0A: @@ -79,6 +87,10 @@ static const char *shader_item_to_str(int32_t item, bool with_alpha, bool only_a return with_alpha ? "texVal1" : "texVal1.rgb"; case SHADER_TEXEL1A: return hint_single_element ? "texVal1.a" : (with_alpha ? "float4(texVal1.a, texVal1.a, texVal1.a, texVal1.a)" : "float3(texVal1.a, texVal1.a, texVal1.a)"); + case SHADER_COMBINED: + return with_alpha ? "texel" : "texel.rgb"; + case SHADER_COMBINEDA: + return hint_single_element ? "texel.a" : (with_alpha ? "float4(texel.a, texel.a, texel.a, texel.a)" : "float3(texel.a, texel.a, texel.a)"); } } else { switch (item) { @@ -95,6 +107,14 @@ static const char *shader_item_to_str(int32_t item, bool with_alpha, bool only_a return "input.input3.a"; case SHADER_INPUT_4: return "input.input4.a"; + case SHADER_INPUT_5: + return "input.input5.a"; + case SHADER_INPUT_6: + return "input.input6.a"; + case SHADER_INPUT_7: + return "input.input7.a"; + case SHADER_INPUT_8: + return "input.input8.a"; case SHADER_TEXEL0: return "texVal0.a"; case SHADER_TEXEL0A: @@ -103,6 +123,10 @@ static const char *shader_item_to_str(int32_t item, bool with_alpha, bool only_a return "texVal1.a"; case SHADER_TEXEL1A: return "texVal1.a"; + case SHADER_COMBINED: + return "texel.a"; + case SHADER_COMBINEDA: + return "texel.a"; } } } diff --git a/src/pc/gfx/gfx_opengl.c b/src/pc/gfx/gfx_opengl.c index 9021b5beb..8c2a1ecfc 100644 --- a/src/pc/gfx/gfx_opengl.c +++ b/src/pc/gfx/gfx_opengl.c @@ -146,6 +146,14 @@ static const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_ return with_alpha || !inputs_have_alpha ? "vInput3" : "vInput3.rgb"; case SHADER_INPUT_4: return with_alpha || !inputs_have_alpha ? "vInput4" : "vInput4.rgb"; + case SHADER_INPUT_5: + return with_alpha || !inputs_have_alpha ? "vInput4" : "vInput5.rgb"; + case SHADER_INPUT_6: + return with_alpha || !inputs_have_alpha ? "vInput4" : "vInput6.rgb"; + case SHADER_INPUT_7: + return with_alpha || !inputs_have_alpha ? "vInput4" : "vInput7.rgb"; + case SHADER_INPUT_8: + return with_alpha || !inputs_have_alpha ? "vInput4" : "vInput8.rgb"; case SHADER_TEXEL0: return with_alpha ? "texVal0" : "texVal0.rgb"; case SHADER_TEXEL0A: @@ -156,6 +164,11 @@ static const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_ case SHADER_TEXEL1A: return hint_single_element ? "texVal1.a" : (with_alpha ? "vec4(texelVal1.a, texelVal1.a, texelVal1.a, texelVal1.a)" : "vec3(texelVal1.a, texelVal1.a, texelVal1.a)"); + case SHADER_COMBINED: + return with_alpha ? "texel" : "texel.rgb"; + case SHADER_COMBINEDA: + return hint_single_element ? "texel.a" : + (with_alpha ? "vec4(texel.a, texel.a, texel.a, texel.a)" : "vec3(texel.a, texel.a, texel.a)"); } } else { switch (item) { @@ -171,6 +184,14 @@ static const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_ return "vInput3.a"; case SHADER_INPUT_4: return "vInput4.a"; + case SHADER_INPUT_5: + return "vInput5.a"; + case SHADER_INPUT_6: + return "vInput6.a"; + case SHADER_INPUT_7: + return "vInput7.a"; + case SHADER_INPUT_8: + return "vInput8.a"; case SHADER_TEXEL0: return "texVal0.a"; case SHADER_TEXEL0A: @@ -179,6 +200,10 @@ static const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_ return "texVal1.a"; case SHADER_TEXEL1A: return "texVal1.a"; + case SHADER_COMBINED: + return "texel.a"; + case SHADER_COMBINEDA: + return "texel.a"; } } return "unknown"; @@ -227,15 +252,13 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC int cmd_length = opt_2cycle ? 16 : 8; for (int i = 0; i < cmd_length; i++) { u8 c = cc->shader_commands[i]; - if (c >= SHADER_INPUT_1 && c <= SHADER_INPUT_4) { + if (c >= SHADER_INPUT_1 && c <= SHADER_INPUT_8) { if (c > num_inputs) { num_inputs = c; } } used_textures[0] = used_textures[0] || c == SHADER_TEXEL0 || c == SHADER_TEXEL0A; used_textures[1] = used_textures[1] || c == SHADER_TEXEL1 || c == SHADER_TEXEL1A; } - u8* cmd = cc->shader_commands; - // figure out optimizations bool do_single[4] = { 0 }; bool do_multiply[4] = { 0 }; @@ -363,17 +386,24 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC append_line(fs_buf, &fs_len, "vec4 texVal1 = sampleTex(uTex1, vTexCoord, uTex1Size, uTex1Filter);"); } - append_str(fs_buf, &fs_len, opt_alpha ? "vec4 texel = " : "vec3 texel = "); - if (!color_alpha_same[0] && opt_alpha) { - append_str(fs_buf, &fs_len, "vec4("); - append_formula(fs_buf, &fs_len, cmd, do_single[0], do_multiply[0], do_mix[0], false, false, true); - append_str(fs_buf, &fs_len, ", "); - append_formula(fs_buf, &fs_len, cmd, do_single[1], do_multiply[1], do_mix[1], true, true, true); - append_str(fs_buf, &fs_len, ")"); - } else { - append_formula(fs_buf, &fs_len, cmd, do_single[0], do_multiply[0], do_mix[0], opt_alpha, false, opt_alpha); + append_str(fs_buf, &fs_len, (opt_alpha) ? "vec4 texel = " : "vec3 texel = "); + for (int i = 0; i < (opt_2cycle + 1); i++) { + u8* cmd = &cc->shader_commands[i * 8]; + if (!color_alpha_same[i*2] && opt_alpha) { + append_str(fs_buf, &fs_len, "vec4("); + append_formula(fs_buf, &fs_len, cmd, do_single[i*2+0], do_multiply[i*2+0], do_mix[i*2+0], false, false, true); + append_str(fs_buf, &fs_len, ", "); + append_formula(fs_buf, &fs_len, cmd, do_single[i*2+1], do_multiply[i*2+1], do_mix[i*2+1], true, true, true); + append_str(fs_buf, &fs_len, ")"); + } else { + append_formula(fs_buf, &fs_len, cmd, do_single[i*2+0], do_multiply[i*2+0], do_mix[i*2+0], opt_alpha, false, opt_alpha); + } + append_line(fs_buf, &fs_len, ";"); + + if (i == 0 && opt_2cycle) { + append_str(fs_buf, &fs_len, "texel = "); + } } - append_line(fs_buf, &fs_len, ";"); if (opt_texture_edge && opt_alpha) { append_line(fs_buf, &fs_len, "if (texel.a > 0.3) texel.a = 1.0; else discard;"); diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index 047c7c03d..d25205184 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -287,10 +287,10 @@ static void gfx_generate_cc(struct ColorCombiner *cc) { shader_cmd = SHADER_TEXEL1A; break; case CC_COMBINED: - shader_cmd = SHADER_COMBINED; + shader_cmd = cc->cm.use_2cycle ? SHADER_COMBINED : SHADER_0; break; case CC_COMBINEDA: - shader_cmd = SHADER_COMBINEDA; + shader_cmd = cc->cm.use_2cycle ? SHADER_COMBINEDA : SHADER_0; break; case CC_PRIM: case CC_SHADE: @@ -1368,48 +1368,180 @@ static void gfx_dp_load_tile(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t rdp.texture_tile.lrt = lrt; } -static uint8_t color_comb_component(uint32_t v) { +static uint8_t color_comb_component_a(uint32_t v, uint8_t cycle) { switch (v) { - case G_CCMUX_TEXEL0: - return CC_TEXEL0; - case G_CCMUX_TEXEL1: - return CC_TEXEL1; - case G_CCMUX_PRIMITIVE: - return CC_PRIM; - case G_CCMUX_SHADE: - return CC_SHADE; - case G_CCMUX_ENVIRONMENT: - return CC_ENV; - case G_CCMUX_TEXEL0_ALPHA: - return CC_TEXEL0A; - /*case G_CCMUX_TEXEL1_ALPHA: - return CC_TEXEL1A;*/ - case G_CCMUX_LOD_FRACTION: - return CC_LOD; - /*case G_CCMUX_1: - return CC_1; - case G_CCMUX_COMBINED: - return CC_0; // return CC_COMBINED; TODO - case G_CCMUX_COMBINED_ALPHA: - return CC_0; //return CC_COMBINEDA; TODO*/ - default: - return CC_0; + case G_CCMUX_COMBINED: return CC_COMBINED; + case G_CCMUX_TEXEL0: return cycle ? CC_TEXEL1 : CC_TEXEL0; + case G_CCMUX_TEXEL1: return cycle ? CC_TEXEL0 : CC_TEXEL1; + case G_CCMUX_PRIMITIVE: return CC_PRIM; + case G_CCMUX_SHADE: return CC_SHADE; + case G_CCMUX_ENVIRONMENT: return CC_ENV; + case G_CCMUX_1: return CC_1; + //case G_CCMUX_NOISE: return CC_NOISE; + case G_CCMUX_0: return CC_0; + default: return CC_0; } } -static inline uint32_t color_comb(uint32_t a, uint32_t b, uint32_t c, uint32_t d) { - return color_comb_component(a) - | (color_comb_component(b) << 8) - | (color_comb_component(c) << 16) - | (color_comb_component(d) << 24); +static uint8_t color_comb_component_b(uint32_t v, uint8_t cycle) { + switch (v) { + case G_CCMUX_COMBINED: return CC_COMBINED; + case G_CCMUX_TEXEL0: return cycle ? CC_TEXEL1 : CC_TEXEL0; + case G_CCMUX_TEXEL1: return cycle ? CC_TEXEL0 : CC_TEXEL1; + case G_CCMUX_PRIMITIVE: return CC_PRIM; + case G_CCMUX_SHADE: return CC_SHADE; + case G_CCMUX_ENVIRONMENT: return CC_ENV; + //case G_CCMUX_CENTER: return CC_CENTER; // is this correct for "Chrome Key Center"? + //case G_CCMUX_K4: return CC_K4; + case G_CCMUX_0: return CC_0; + default: return CC_0; + } +} + +static uint8_t color_comb_component_c(uint32_t v, uint8_t cycle) { + switch (v) { + case G_CCMUX_COMBINED: return CC_COMBINED; + case G_CCMUX_TEXEL0: return cycle ? CC_TEXEL1 : CC_TEXEL0; + case G_CCMUX_TEXEL1: return cycle ? CC_TEXEL0 : CC_TEXEL1; + case G_CCMUX_PRIMITIVE: return CC_PRIM; + case G_CCMUX_SHADE: return CC_SHADE; + case G_CCMUX_ENVIRONMENT: return CC_ENV; + //case G_CCMUX_CENTER: return CC_CENTER; // is this correct for "Chrome Key Center"? + case G_CCMUX_COMBINED_ALPHA: return CC_COMBINEDA; + case G_CCMUX_TEXEL0_ALPHA: return CC_TEXEL0A; + case G_CCMUX_TEXEL1_ALPHA: return CC_TEXEL1A; + //case G_CCMUX_PRIMITIVE_ALPHA: return CC_PRIMAA; + //case G_CCMUX_SHADE_ALPHA: return CC_SHADEA; + //case G_CCMUX_ENV_ALPHA: return CC_ENVA; + //case G_CCMUX_LOD_FRACTION: return CC_LOD_FRACTION; + //case G_CCMUX_PRIM_LOD_FRAC: return CC_PRIM_LOD_FRACTION; + //case G_CCMUX_K5: return CC_K5; + case G_CCMUX_0: return CC_0; + default: return CC_0; + } +} + +static uint8_t color_comb_component_d(uint32_t v, uint8_t cycle) { + switch (v) { + case G_CCMUX_COMBINED: return CC_COMBINED; + case G_CCMUX_TEXEL0: return cycle ? CC_TEXEL1 : CC_TEXEL0; + case G_CCMUX_TEXEL1: return cycle ? CC_TEXEL0 : CC_TEXEL1; + case G_CCMUX_PRIMITIVE: return CC_PRIM; + case G_CCMUX_SHADE: return CC_SHADE; + case G_CCMUX_ENVIRONMENT: return CC_ENV; + case G_CCMUX_1: return CC_1; + case G_CCMUX_0: return CC_0; + default: return CC_0; + } +} + +static inline uint32_t color_comb_rgb(uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint8_t cycle) { + return color_comb_component_a(a, cycle) + | (color_comb_component_b(b, cycle) << 8) + | (color_comb_component_c(c, cycle) << 16) + | (color_comb_component_d(d, cycle) << 24); +} + +static uint8_t color_comb_component_a_alpha(uint32_t v, uint8_t cycle) { + switch (v) { + case G_CCMUX_COMBINED_ALPHA: return CC_COMBINEDA; + case G_CCMUX_TEXEL0_ALPHA: return cycle ? CC_TEXEL1A : CC_TEXEL0A; + case G_CCMUX_TEXEL1_ALPHA: return cycle ? CC_TEXEL0A : CC_TEXEL1A; + //case G_CCMUX_PRIMITIVE_ALPHA: return CC_PRIMA; + //case G_CCMUX_SHADE_ALPHA: return CC_SHADEA; + //case G_CCMUX_ENV_ALPHA: return CC_ENVA; + case G_CCMUX_1: return CC_1; + case G_CCMUX_0: return CC_0; + + case G_CCMUX_TEXEL0: return CC_TEXEL0; + case G_CCMUX_TEXEL1: return CC_TEXEL1; + case G_CCMUX_PRIMITIVE: return CC_PRIM; + case G_CCMUX_SHADE: return CC_SHADE; + case G_CCMUX_ENVIRONMENT: return CC_ENV; + + default: return CC_0; + } +} + +static uint8_t color_comb_component_b_alpha(uint32_t v, uint8_t cycle) { + switch (v) { + case G_CCMUX_COMBINED_ALPHA: return CC_COMBINEDA; + case G_CCMUX_TEXEL0_ALPHA: return cycle ? CC_TEXEL1A : CC_TEXEL0A; + case G_CCMUX_TEXEL1_ALPHA: return cycle ? CC_TEXEL0A : CC_TEXEL1A; + //case G_CCMUX_PRIMITIVE_ALPHA: return CC_PRIMA; + //case G_CCMUX_SHADE_ALPHA: return CC_SHADEA; + //case G_CCMUX_ENV_ALPHA: return CC_ENVA; + case G_CCMUX_1: return CC_1; + case G_CCMUX_0: return CC_0; + + case G_CCMUX_TEXEL0: return CC_TEXEL0; + case G_CCMUX_TEXEL1: return CC_TEXEL1; + case G_CCMUX_PRIMITIVE: return CC_PRIM; + case G_CCMUX_SHADE: return CC_SHADE; + case G_CCMUX_ENVIRONMENT: return CC_ENV; + + default: return CC_0; + } +} + +static uint8_t color_comb_component_c_alpha(uint32_t v, uint8_t cycle) { + switch (v) { + //case G_CCMUX_LOD_FRACTION: return CC_LOD_FRACTION; + case G_CCMUX_TEXEL0_ALPHA: return cycle ? CC_TEXEL1A : CC_TEXEL0A; + case G_CCMUX_TEXEL1_ALPHA: return cycle ? CC_TEXEL1A : CC_TEXEL1A; + //case G_CCMUX_PRIMITIVE_ALPHA: return CC_PRIMA; + //case G_CCMUX_SHADE_ALPHA: return CC_SHADEA; + //case G_CCMUX_ENV_ALPHA: return CC_ENVA; + //case G_CCMUX_PRIM_LOD_FRAC: return CC_PRIM_LOD_FRACTION; + case G_CCMUX_0: return CC_0; + + case G_CCMUX_TEXEL0: return CC_TEXEL0; + case G_CCMUX_TEXEL1: return CC_TEXEL1; + case G_CCMUX_PRIMITIVE: return CC_PRIM; + case G_CCMUX_SHADE: return CC_SHADE; + case G_CCMUX_ENVIRONMENT: return CC_ENV; + + default: return CC_0; + } +} + +static uint8_t color_comb_component_d_alpha(uint32_t v, uint8_t cycle) { + switch (v) { + case G_CCMUX_COMBINED_ALPHA: return CC_COMBINEDA; + case G_CCMUX_TEXEL0_ALPHA: return cycle ? CC_TEXEL1A : CC_TEXEL0A; + case G_CCMUX_TEXEL1_ALPHA: return cycle ? CC_TEXEL0A : CC_TEXEL1A; + //case G_CCMUX_PRIMITIVE_ALPHA: return CC_PRIMA; + //case G_CCMUX_SHADE_ALPHA: return CC_SHADEA; + //case G_CCMUX_ENV_ALPHA: return CC_ENVA; + case G_CCMUX_1: return CC_1; + case G_CCMUX_0: return CC_0; + + case G_CCMUX_TEXEL0: return CC_TEXEL0; + case G_CCMUX_TEXEL1: return CC_TEXEL1; + case G_CCMUX_PRIMITIVE: return CC_PRIM; + case G_CCMUX_SHADE: return CC_SHADE; + case G_CCMUX_ENVIRONMENT: return CC_ENV; + + default: return CC_0; + } +} + +static inline uint32_t color_comb_alpha(uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint8_t cycle) { + return color_comb_component_a_alpha(a, cycle) + | (color_comb_component_b_alpha(b, cycle) << 8) + | (color_comb_component_c_alpha(c, cycle) << 16) + | (color_comb_component_d_alpha(d, cycle) << 24); } static void gfx_dp_set_combine_mode(uint32_t rgb1, uint32_t alpha1, uint32_t rgb2, uint32_t alpha2) { + //printf(">>> combine: %08x %08x %08x %08x\n", rgb1, alpha1, rgb2, alpha2); rdp.combine_mode.rgb1 = rgb1; rdp.combine_mode.alpha1 = alpha1; rdp.combine_mode.rgb2 = rgb2; rdp.combine_mode.alpha2 = alpha2; + + rdp.combine_mode.flags = 0; } static void gfx_dp_set_env_color(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { @@ -1521,7 +1653,11 @@ static void gfx_dp_texture_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int3 dsdx >>= 2; // Color combiner is turned off in copy mode - gfx_dp_set_combine_mode(color_comb(0, 0, 0, G_CCMUX_TEXEL0), color_comb(0, 0, 0, G_ACMUX_TEXEL0), color_comb(0, 0, 0, G_CCMUX_TEXEL0), color_comb(0, 0, 0, G_ACMUX_TEXEL0)); + gfx_dp_set_combine_mode( + color_comb_rgb (G_CCMUX_0, G_CCMUX_0, G_CCMUX_0, G_CCMUX_TEXEL0, 0), + color_comb_alpha(G_CCMUX_0, G_CCMUX_0, G_CCMUX_0, G_ACMUX_TEXEL0, 0), + color_comb_rgb (G_CCMUX_0, G_CCMUX_0, G_CCMUX_0, G_CCMUX_TEXEL0, 1), + color_comb_alpha(G_CCMUX_0, G_CCMUX_0, G_CCMUX_0, G_ACMUX_TEXEL0, 1)); // Per documentation one extra pixel is added in this modes to each edge lrx += 1 << 2; @@ -1587,7 +1723,11 @@ static void gfx_dp_fill_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int32_t } struct CombineMode saved_combine_mode = rdp.combine_mode; - gfx_dp_set_combine_mode(color_comb(0, 0, 0, G_CCMUX_SHADE), color_comb(0, 0, 0, G_ACMUX_SHADE), color_comb(0, 0, 0, G_CCMUX_SHADE), color_comb(0, 0, 0, G_ACMUX_SHADE)); + gfx_dp_set_combine_mode( + color_comb_rgb (G_CCMUX_0, G_CCMUX_0, G_CCMUX_0, G_CCMUX_SHADE, 0), + color_comb_alpha(G_CCMUX_0, G_CCMUX_0, G_CCMUX_0, G_ACMUX_SHADE, 0), + color_comb_rgb (G_CCMUX_0, G_CCMUX_0, G_CCMUX_0, G_CCMUX_SHADE, 1), + color_comb_alpha(G_CCMUX_0, G_CCMUX_0, G_CCMUX_0, G_ACMUX_SHADE, 1)); gfx_draw_rectangle(ulx, uly, lrx, lry); u32 cflags = rdp.combine_mode.flags; @@ -1759,10 +1899,10 @@ static void OPTIMIZE_O3 gfx_run_dl(Gfx* cmd) { break; case G_SETCOMBINE: gfx_dp_set_combine_mode( - color_comb(C0(20, 4), C1(28, 4), C0(15, 5), C1(15, 3)), - color_comb(C0(12, 3), C1(12, 3), C0(9, 3), C1(9, 3)), - color_comb(C0(5, 4), C1(24, 4), C0(0, 5), C1(6, 3)), - color_comb(C1(21, 3), C1(3, 3), C1(18, 3), C1(0, 3))); + color_comb_rgb (C0(20, 4), C1(28, 4), C0(15, 5), C1(15, 3), 0), + color_comb_alpha(C0(12, 3), C1(12, 3), C0(9, 3), C1(9, 3), 0), + color_comb_rgb (C0(5, 4), C1(24, 4), C0(0, 5), C1(6, 3), 1), + color_comb_alpha(C1(21, 3), C1(3, 3), C1(18, 3), C1(0, 3), 1)); break; // G_SETPRIMCOLOR, G_CCMUX_PRIMITIVE, G_ACMUX_PRIMITIVE, is used by Goddard // G_CCMUX_TEXEL1, LOD_FRACTION is used in Bowser room 1