From ab2cbb2dbc70d682fb8a8bae76e212ede305e0b7 Mon Sep 17 00:00:00 2001 From: MysterD Date: Wed, 3 May 2023 13:13:33 -0700 Subject: [PATCH] Get GL_LEGACY working again (poorly) --- src/pc/crash_handler.c | 20 +-- src/pc/gfx/gfx_cc.c | 257 ++++++++++++++++++++++++++++----- src/pc/gfx/gfx_cc.h | 17 +-- src/pc/gfx/gfx_opengl.c | 81 ++++------- src/pc/gfx/gfx_opengl_legacy.c | 51 +++---- src/pc/gfx/gfx_pc.c | 191 ------------------------ 6 files changed, 285 insertions(+), 332 deletions(-) diff --git a/src/pc/crash_handler.c b/src/pc/crash_handler.c index 5d307f7f6..42a957d58 100644 --- a/src/pc/crash_handler.c +++ b/src/pc/crash_handler.c @@ -534,17 +534,17 @@ struct PcDebug gPcDebug = { .tags = { 0x0000000000000000, 0x000000000000FFFF, - 0x440C28A5CC404F11, - 0x2783114DDB90E597, - 0x0EF4AF18EEC1303A, - 0x5E6A9446709E7CFF, - 0x914FA1C52D410003, - 0xE9A402C28144FD8B, - 0x83B8B87B1E6A0B78, - 0xEE7B0ED661ABA0ED, + 0x2D1D50FB02617949, + 0x8AEB7180FAE739EB, + 0x0CDB1A233CC71057, + 0x53D5D9880C8B278E, + 0xE8E307BE5802542E, + 0x8A3ACC4FDB4FFE45, + 0x09046C2BA3C5000D, + 0xF027964ADE989C29, 0x076CF19655C70007, - 0x9325E55A037D6511, - 0x77ACD7B422D978A6, + 0x440C28A5CC404F11, + 0xE9A402C28144FD8B, 0x9A2269E87B26BE68, }, .id = DEFAULT_ID, diff --git a/src/pc/gfx/gfx_cc.c b/src/pc/gfx/gfx_cc.c index 12e4bda0e..20957d013 100644 --- a/src/pc/gfx/gfx_cc.c +++ b/src/pc/gfx/gfx_cc.c @@ -4,45 +4,43 @@ #include "gfx_pc.h" static u8 sAllowCCPrint = 1; -void gfx_cc_get_features(uint32_t shader_id, struct CCFeatures *cc_features) { - // DO NOT COMMIT: TODO - need to fix this - for (int32_t i = 0; i < 4; i++) { - cc_features->c[0][i] = (shader_id >> (i * 3)) & 7; - cc_features->c[1][i] = (shader_id >> (12 + i * 3)) & 7; + +void gfx_cc_get_features(struct ColorCombiner* cc, struct CCFeatures* ccf) { + // DO NOT COMMIT: TODO - need to convert dx and regular gl + + // reset ccf + memset(ccf, 0, sizeof(struct CCFeatures)); + + int cmd_length = cc->cm.use_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_8) { + if (c > ccf->num_inputs) { ccf->num_inputs = c; } + } + ccf->used_textures[0] = ccf->used_textures[0] || c == SHADER_TEXEL0 || c == SHADER_TEXEL0A; + ccf->used_textures[1] = ccf->used_textures[1] || c == SHADER_TEXEL1 || c == SHADER_TEXEL1A; } - cc_features->opt_alpha = (shader_id & SHADER_OPT_ALPHA) != 0; - cc_features->opt_fog = (shader_id & SHADER_OPT_FOG) != 0; - cc_features->opt_texture_edge = (shader_id & SHADER_OPT_TEXTURE_EDGE) != 0; - cc_features->opt_noise = (shader_id & SHADER_OPT_NOISE) != 0; + // figure out optimizations + for (int i = 0; i < 16 / 4; i++) { + u8* c = &cc->shader_commands[i * 4]; + ccf->do_single[i] = (c[2] == 0); + ccf->do_multiply[i] = (c[1] == 0 && c[3] == 0); + ccf->do_mix[i] = (c[1] == c[3]); + } - cc_features->used_textures[0] = false; - cc_features->used_textures[1] = false; - cc_features->num_inputs = 0; + ccf->color_alpha_same[0] = 1; + ccf->color_alpha_same[1] = 1; - 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_8) { - if (cc_features->c[i][j] > cc_features->num_inputs) { - cc_features->num_inputs = cc_features->c[i][j]; - } - } - if (cc_features->c[i][j] == SHADER_TEXEL0 || cc_features->c[i][j] == SHADER_TEXEL0A) { - cc_features->used_textures[0] = true; - } - if (cc_features->c[i][j] == SHADER_TEXEL1 || cc_features->c[i][j] == SHADER_TEXEL1A) { - cc_features->used_textures[1] = true; + for (int i = 0; i < 2; i++) { + u8* cmd = &cc->shader_commands[i * 8]; + for (int j = 0; j < 4; j++) { + if (cmd[j] != cmd[j + 4]) { + ccf->color_alpha_same[i] = 0; + break; } } } - - cc_features->do_single[0] = cc_features->c[0][2] == 0; - cc_features->do_single[1] = cc_features->c[1][2] == 0; - cc_features->do_multiply[0] = cc_features->c[0][1] == 0 && cc_features->c[0][3] == 0; - cc_features->do_multiply[1] = cc_features->c[1][1] == 0 && cc_features->c[1][3] == 0; - cc_features->do_mix[0] = cc_features->c[0][1] == cc_features->c[0][3]; - cc_features->do_mix[1] = cc_features->c[1][1] == cc_features->c[1][3]; - cc_features->color_alpha_same = (shader_id & 0xfff) == ((shader_id >> 12) & 0xfff); } void gfx_cc_print(struct ColorCombiner *cc) { @@ -103,6 +101,197 @@ void gfx_cc_precomp(void) { gfx_pc_precomp_shader(0x04060401, 0x05000000, 0x04060402, 0x05000b0b, 0x00000001); // 1d970841b086b2e6 gfx_pc_precomp_shader(0x01000000, 0x04000000, 0x02000000, 0x04000b0b, 0x00000001); // 410000008f86b2e6 - sAllowCCPrint = 1; -} \ No newline at end of file +} + + +static uint8_t color_comb_component_a(uint32_t v, uint8_t cycle) { + switch (v) { + case G_CCMUX_COMBINED: return cycle ? CC_COMBINED : CC_0; + 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; + + case G_CCMUX_COMBINED_ALPHA: return cycle ? CC_COMBINEDA : CC_0; + 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; + + default: return CC_0; + } +} + +static uint8_t color_comb_component_b(uint32_t v, uint8_t cycle) { + switch (v) { + case G_CCMUX_COMBINED: return cycle ? CC_COMBINED : CC_0; + 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; + + case G_CCMUX_COMBINED_ALPHA: return cycle ? CC_COMBINEDA : CC_0; + 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; + + default: return CC_0; + } +} + +static uint8_t color_comb_component_c(uint32_t v, uint8_t cycle) { + switch (v) { + case G_CCMUX_COMBINED: return cycle ? CC_COMBINED : CC_0; + 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 cycle ? CC_COMBINEDA : CC_0; + case G_CCMUX_TEXEL0_ALPHA: return CC_TEXEL0A; + case G_CCMUX_TEXEL1_ALPHA: return 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_LOD_FRACTION: return CC_LOD; + //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 cycle ? CC_COMBINED : CC_0; + 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; + + 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; + + default: return CC_0; + } +} + +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 cycle ? CC_COMBINEDA : CC_0; + 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_COMBINED: return cycle ? CC_COMBINED : CC_0; + 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; + + 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 cycle ? CC_COMBINEDA : CC_0; + 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_COMBINED: return cycle ? CC_COMBINED : CC_0; + 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; + + 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; + 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 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; + + 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 cycle ? CC_COMBINEDA : CC_0; + 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_COMBINED: return cycle ? CC_COMBINED : CC_0; + 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; + + default: return CC_0; + } +} + +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); +} diff --git a/src/pc/gfx/gfx_cc.h b/src/pc/gfx/gfx_cc.h index 8bb60073b..72b9a1ba2 100644 --- a/src/pc/gfx/gfx_cc.h +++ b/src/pc/gfx/gfx_cc.h @@ -48,17 +48,12 @@ enum { #define SHADER_OPT_NOISE (1 << 27) struct CCFeatures { - uint8_t c[2][4]; - bool opt_alpha; - bool opt_fog; - bool opt_texture_edge; - bool opt_noise; bool used_textures[2]; int num_inputs; - bool do_single[2]; - bool do_multiply[2]; - bool do_mix[2]; - bool color_alpha_same; + bool do_single[4]; + bool do_multiply[4]; + bool do_mix[4]; + bool color_alpha_same[2]; }; #pragma pack(1) @@ -107,9 +102,11 @@ struct ColorCombiner { extern "C" { #endif -void gfx_cc_get_features(uint32_t shader_id, struct CCFeatures *cc_features); +void gfx_cc_get_features(struct ColorCombiner* cc, struct CCFeatures *cc_features); void gfx_cc_print(struct ColorCombiner *cc); void gfx_cc_precomp(void); +uint32_t color_comb_rgb(uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint8_t cycle); +uint32_t color_comb_alpha(uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint8_t cycle); #ifdef __cplusplus } diff --git a/src/pc/gfx/gfx_opengl.c b/src/pc/gfx/gfx_opengl.c index f9eb65290..0a6a4fcba 100644 --- a/src/pc/gfx/gfx_opengl.c +++ b/src/pc/gfx/gfx_opengl.c @@ -237,6 +237,9 @@ static void append_formula(char *buf, size_t *len, uint8_t* cmd, bool do_single, } static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorCombiner* cc) { + struct CCFeatures ccf = { 0 }; + gfx_cc_get_features(cc, &ccf); + bool opt_alpha = cc->cm.use_alpha; bool opt_fog = cc->cm.use_fog; bool opt_texture_edge = cc->cm.texture_edge; @@ -249,40 +252,6 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC bool opt_noise = cc->cm.use_noise; #endif - bool used_textures[2] = { 0 }; - int num_inputs = 0; - 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_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; - } - - // figure out optimizations - bool do_single[4] = { 0 }; - bool do_multiply[4] = { 0 }; - bool do_mix[4] = { 0 }; - for (int i = 0; i < 16 / 4; i++) { - u8* c = &cc->shader_commands[i * 4]; - do_single[i] = (c[2] == 0); - do_multiply[i] = (c[1] == 0 && c[3] == 0); - do_mix[i] = (c[1] == c[3]); - } - - bool color_alpha_same[2] = { 1, 1 }; - for (int i = 0; i < 2; i++) { - u8* cmd = &cc->shader_commands[i * 8]; - for (int j = 0; j < 4; j++) { - if (cmd[j] != cmd[j + 4]) { - color_alpha_same[i] = 0; - break; - } - } - } - char vs_buf[1024]; char fs_buf[2048]; size_t vs_len = 0; @@ -296,7 +265,7 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC append_line(vs_buf, &vs_len, "#version 120"); #endif append_line(vs_buf, &vs_len, "attribute vec4 aVtxPos;"); - if (used_textures[0] || used_textures[1]) { + if (ccf.used_textures[0] || ccf.used_textures[1]) { append_line(vs_buf, &vs_len, "attribute vec2 aTexCoord;"); append_line(vs_buf, &vs_len, "varying vec2 vTexCoord;"); num_floats += 2; @@ -311,13 +280,13 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC append_line(vs_buf, &vs_len, "varying vec2 vLightMap;"); num_floats += 2; } - for (int i = 0; i < num_inputs; i++) { + for (int i = 0; i < ccf.num_inputs; i++) { vs_len += sprintf(vs_buf + vs_len, "attribute vec%d aInput%d;\n", opt_alpha ? 4 : 3, i + 1); vs_len += sprintf(vs_buf + vs_len, "varying vec%d vInput%d;\n", opt_alpha ? 4 : 3, i + 1); num_floats += opt_alpha ? 4 : 3; } append_line(vs_buf, &vs_len, "void main() {"); - if (used_textures[0] || used_textures[1]) { + if (ccf.used_textures[0] || ccf.used_textures[1]) { append_line(vs_buf, &vs_len, "vTexCoord = aTexCoord;"); } if (opt_fog) { @@ -326,7 +295,7 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC if (opt_light_map) { append_line(vs_buf, &vs_len, "vLightMap = aLightMap;"); } - for (int i = 0; i < num_inputs; i++) { + for (int i = 0; i < ccf.num_inputs; i++) { vs_len += sprintf(vs_buf + vs_len, "vInput%d = aInput%d;\n", i + 1, i + 1); } append_line(vs_buf, &vs_len, "gl_Position = aVtxPos;"); @@ -340,7 +309,7 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC append_line(fs_buf, &fs_len, "#version 120"); #endif - if (used_textures[0] || used_textures[1]) { + if (ccf.used_textures[0] || ccf.used_textures[1]) { append_line(fs_buf, &fs_len, "varying vec2 vTexCoord;"); } if (opt_fog) { @@ -349,15 +318,15 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC if (opt_light_map) { append_line(fs_buf, &fs_len, "varying vec2 vLightMap;"); } - for (int i = 0; i < num_inputs; i++) { + for (int i = 0; i < ccf.num_inputs; i++) { fs_len += sprintf(fs_buf + fs_len, "varying vec%d vInput%d;\n", opt_alpha ? 4 : 3, i + 1); } - if (used_textures[0]) { + if (ccf.used_textures[0]) { append_line(fs_buf, &fs_len, "uniform sampler2D uTex0;"); append_line(fs_buf, &fs_len, "uniform vec2 uTex0Size;"); append_line(fs_buf, &fs_len, "uniform bool uTex0Filter;"); } - if (used_textures[1]) { + if (ccf.used_textures[1]) { append_line(fs_buf, &fs_len, "uniform sampler2D uTex1;"); append_line(fs_buf, &fs_len, "uniform vec2 uTex1Size;"); append_line(fs_buf, &fs_len, "uniform bool uTex1Filter;"); @@ -367,7 +336,7 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC // Original author: ArthurCarvalho // Slightly modified GLSL implementation by twinaphex, mupen64plus-libretro project. - if (used_textures[0] || used_textures[1]) { + if (ccf.used_textures[0] || ccf.used_textures[1]) { if (configFiltering == 2) { append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) texture2D(tex, texCoord - (off)/texSize)"); append_line(fs_buf, &fs_len, "vec4 filter3point(in sampler2D tex, in vec2 texCoord, in vec2 texSize) {"); @@ -402,10 +371,10 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC append_line(fs_buf, &fs_len, "void main() {"); - if (used_textures[0]) { + if (ccf.used_textures[0]) { append_line(fs_buf, &fs_len, "vec4 texVal0 = sampleTex(uTex0, vTexCoord, uTex0Size, uTex0Filter);"); } - if (used_textures[1]) { + if (ccf.used_textures[1]) { if (cc->cm.light_map) { append_line(fs_buf, &fs_len, "vec4 texVal1 = sampleTex(uTex1, vLightMap, uTex1Size, uTex1Filter);"); } else { @@ -416,14 +385,14 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC 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] && opt_alpha) { + if (!ccf.color_alpha_same[i] && 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_formula(fs_buf, &fs_len, cmd, ccf.do_single[i*2+0], ccf.do_multiply[i*2+0], ccf.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_formula(fs_buf, &fs_len, cmd, ccf.do_single[i*2+1], ccf.do_multiply[i*2+1], ccf.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_formula(fs_buf, &fs_len, cmd, ccf.do_single[i*2+0], ccf.do_multiply[i*2+0], ccf.do_mix[i*2+0], opt_alpha, false, opt_alpha); } append_line(fs_buf, &fs_len, ";"); @@ -509,7 +478,7 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC prg->attrib_sizes[cnt] = 4; ++cnt; - if (used_textures[0] || used_textures[1]) { + if (ccf.used_textures[0] || ccf.used_textures[1]) { prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, "aTexCoord"); prg->attrib_sizes[cnt] = 2; ++cnt; @@ -527,7 +496,7 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC ++cnt; } - for (int i = 0; i < num_inputs; i++) { + for (int i = 0; i < ccf.num_inputs; i++) { char name[16]; sprintf(name, "aInput%d", i + 1); prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, name); @@ -537,21 +506,21 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC prg->hash = cc->hash; prg->opengl_program_id = shader_program; - prg->num_inputs = num_inputs; - prg->used_textures[0] = used_textures[0]; - prg->used_textures[1] = used_textures[1]; + prg->num_inputs = ccf.num_inputs; + prg->used_textures[0] = ccf.used_textures[0]; + prg->used_textures[1] = ccf.used_textures[1]; prg->num_floats = num_floats; prg->num_attribs = cnt; gfx_opengl_load_shader(prg); - if (used_textures[0]) { + if (ccf.used_textures[0]) { GLint sampler_location = glGetUniformLocation(shader_program, "uTex0"); prg->uniform_locations[0] = glGetUniformLocation(shader_program, "uTex0Size"); prg->uniform_locations[1] = glGetUniformLocation(shader_program, "uTex0Filter"); glUniform1i(sampler_location, 0); } - if (used_textures[1]) { + if (ccf.used_textures[1]) { GLint sampler_location = glGetUniformLocation(shader_program, "uTex1"); prg->uniform_locations[2] = glGetUniformLocation(shader_program, "uTex1Size"); prg->uniform_locations[3] = glGetUniformLocation(shader_program, "uTex1Filter"); diff --git a/src/pc/gfx/gfx_opengl_legacy.c b/src/pc/gfx/gfx_opengl_legacy.c index 2e3f12160..b3153af7f 100644 --- a/src/pc/gfx/gfx_opengl_legacy.c +++ b/src/pc/gfx/gfx_opengl_legacy.c @@ -49,8 +49,9 @@ enum MixType { struct ShaderProgram { bool enabled; - uint32_t shader_id; - struct CCFeatures cc; + uint64_t hash; + struct ColorCombiner cc; + struct CCFeatures ccf; enum MixType mix; bool texture_used[2]; int texture_ord[2]; @@ -140,25 +141,12 @@ static inline GLenum texenv_set_texture(UNUSED struct ShaderProgram *prg) { } static inline GLenum texenv_set_texture_color(struct ShaderProgram *prg) { - GLenum mode; - // HACK: lord forgive me for this, but this is easier - - switch (prg->shader_id) { - case 0x0000038D: // mario's eyes - case 0x01045A00: // peach letter - case 0x01200A00: // intro copyright fade in - mode = GL_DECAL; - break; - case 0x00000551: // goddard - mode = GL_BLEND; - break; - default: - mode = GL_MODULATE; - break; + if (prg->cc.cm.rgb1 == color_comb_rgb(G_CCMUX_TEXEL0, G_CCMUX_SHADE, G_CCMUX_TEXEL0_ALPHA, G_CCMUX_SHADE, 0)) { + return GL_DECAL; + } else { + return GL_MODULATE; } - - return mode; } static inline GLenum texenv_set_texture_texture(UNUSED struct ShaderProgram *prg) { @@ -183,7 +171,7 @@ static void gfx_opengl_apply_shader(struct ShaderProgram *prg) { glDisable(GL_TEXTURE_2D); } - if (prg->shader_id & SHADER_OPT_FOG) { + if (prg->cc.cm.use_fog) { // blend it on top of normal tris later cur_fog_ofs = ofs; ofs += 4; @@ -195,10 +183,10 @@ static void gfx_opengl_apply_shader(struct ShaderProgram *prg) { // HACK: if there's a texture and two colors, one of them is likely for speculars or some shit (see mario head) // if there's two colors but no texture, the real color is likely the second one // HACKHACK: alpha is 0 in the transition shader (0x01A00045), maybe figure out the flags instead - const int vlen = (prg->cc.opt_alpha && prg->shader_id != 0x01A00045) ? 4 : 3; + const int vlen = (prg->cc.cm.use_alpha /*&& prg->shader_id != 0x01A00045*/) ? 4 : 3; const int hack = vlen * (prg->num_inputs > 1); - if (prg->texture_used[1] && prg->cc.do_mix[0]) { + if (prg->texture_used[1] && prg->ccf.do_mix[0]) { // HACK: when two textures are mixed by vertex color, store the color // it will be used later when rendering two texture passes c_mix[0] = *(ofs + hack + 0); @@ -224,7 +212,7 @@ static void gfx_opengl_apply_shader(struct ShaderProgram *prg) { // we only need to do this once prg->enabled = true; - if (prg->shader_id & SHADER_OPT_TEXTURE_EDGE) { + if (prg->cc.cm.texture_edge) { // (horrible) alpha discard glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.666f); @@ -258,14 +246,15 @@ static void gfx_opengl_load_shader(struct ShaderProgram *new_prg) { cur_shader->enabled = false; } -static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(uint32_t shader_id) { - struct CCFeatures ccf; - gfx_cc_get_features(shader_id, &ccf); - +static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorCombiner* cc) { struct ShaderProgram *prg = &shader_program_pool[shader_program_pool_size++]; - prg->shader_id = shader_id; - prg->cc = ccf; + struct CCFeatures ccf = { 0 }; + gfx_cc_get_features(cc, &ccf); + + prg->hash = cc->hash; + prg->cc = *cc; + prg->ccf = ccf; prg->num_inputs = ccf.num_inputs; prg->texture_used[0] = ccf.used_textures[0]; prg->texture_used[1] = ccf.used_textures[1]; @@ -296,9 +285,9 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(uint32_t shad return prg; } -static struct ShaderProgram *gfx_opengl_lookup_shader(uint32_t shader_id) { +static struct ShaderProgram *gfx_opengl_lookup_shader(struct ColorCombiner* cc) { for (size_t i = 0; i < shader_program_pool_size; i++) - if (shader_program_pool[i].shader_id == shader_id) + if (shader_program_pool[i].hash == cc->hash) return &shader_program_pool[i]; return NULL; } diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index cafde71e7..adf58a760 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -1407,197 +1407,6 @@ 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_a(uint32_t v, uint8_t cycle) { - switch (v) { - case G_CCMUX_COMBINED: return cycle ? CC_COMBINED : CC_0; - 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; - - case G_CCMUX_COMBINED_ALPHA: return cycle ? CC_COMBINEDA : CC_0; - 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; - - default: return CC_0; - } -} - -static uint8_t color_comb_component_b(uint32_t v, uint8_t cycle) { - switch (v) { - case G_CCMUX_COMBINED: return cycle ? CC_COMBINED : CC_0; - 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; - - case G_CCMUX_COMBINED_ALPHA: return cycle ? CC_COMBINEDA : CC_0; - 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; - - default: return CC_0; - } -} - -static uint8_t color_comb_component_c(uint32_t v, uint8_t cycle) { - switch (v) { - case G_CCMUX_COMBINED: return cycle ? CC_COMBINED : CC_0; - 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 cycle ? CC_COMBINEDA : CC_0; - case G_CCMUX_TEXEL0_ALPHA: return CC_TEXEL0A; - case G_CCMUX_TEXEL1_ALPHA: return 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_LOD_FRACTION: return CC_LOD; - //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 cycle ? CC_COMBINED : CC_0; - 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; - - 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; - - 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 cycle ? CC_COMBINEDA : CC_0; - 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_COMBINED: return cycle ? CC_COMBINED : CC_0; - 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; - - 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 cycle ? CC_COMBINEDA : CC_0; - 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_COMBINED: return cycle ? CC_COMBINED : CC_0; - 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; - - 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; - 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 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; - - 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 cycle ? CC_COMBINEDA : CC_0; - 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_COMBINED: return cycle ? CC_COMBINED : CC_0; - 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; - - 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); memset(&rdp.combine_mode, 0, sizeof(struct CombineMode));