mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-01-05 15:11:16 +00:00
Get GL_LEGACY working again (poorly)
This commit is contained in:
parent
0bb7adfd2d
commit
ab2cbb2dbc
6 changed files with 285 additions and 332 deletions
|
@ -534,17 +534,17 @@ struct PcDebug gPcDebug = {
|
||||||
.tags = {
|
.tags = {
|
||||||
0x0000000000000000,
|
0x0000000000000000,
|
||||||
0x000000000000FFFF,
|
0x000000000000FFFF,
|
||||||
0x440C28A5CC404F11,
|
0x2D1D50FB02617949,
|
||||||
0x2783114DDB90E597,
|
0x8AEB7180FAE739EB,
|
||||||
0x0EF4AF18EEC1303A,
|
0x0CDB1A233CC71057,
|
||||||
0x5E6A9446709E7CFF,
|
0x53D5D9880C8B278E,
|
||||||
0x914FA1C52D410003,
|
0xE8E307BE5802542E,
|
||||||
0xE9A402C28144FD8B,
|
0x8A3ACC4FDB4FFE45,
|
||||||
0x83B8B87B1E6A0B78,
|
0x09046C2BA3C5000D,
|
||||||
0xEE7B0ED661ABA0ED,
|
0xF027964ADE989C29,
|
||||||
0x076CF19655C70007,
|
0x076CF19655C70007,
|
||||||
0x9325E55A037D6511,
|
0x440C28A5CC404F11,
|
||||||
0x77ACD7B422D978A6,
|
0xE9A402C28144FD8B,
|
||||||
0x9A2269E87B26BE68,
|
0x9A2269E87B26BE68,
|
||||||
},
|
},
|
||||||
.id = DEFAULT_ID,
|
.id = DEFAULT_ID,
|
||||||
|
|
|
@ -4,45 +4,43 @@
|
||||||
#include "gfx_pc.h"
|
#include "gfx_pc.h"
|
||||||
|
|
||||||
static u8 sAllowCCPrint = 1;
|
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
|
void gfx_cc_get_features(struct ColorCombiner* cc, struct CCFeatures* ccf) {
|
||||||
for (int32_t i = 0; i < 4; i++) {
|
// DO NOT COMMIT: TODO - need to convert dx and regular gl
|
||||||
cc_features->c[0][i] = (shader_id >> (i * 3)) & 7;
|
|
||||||
cc_features->c[1][i] = (shader_id >> (12 + i * 3)) & 7;
|
// 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;
|
// figure out optimizations
|
||||||
cc_features->opt_fog = (shader_id & SHADER_OPT_FOG) != 0;
|
for (int i = 0; i < 16 / 4; i++) {
|
||||||
cc_features->opt_texture_edge = (shader_id & SHADER_OPT_TEXTURE_EDGE) != 0;
|
u8* c = &cc->shader_commands[i * 4];
|
||||||
cc_features->opt_noise = (shader_id & SHADER_OPT_NOISE) != 0;
|
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;
|
ccf->color_alpha_same[0] = 1;
|
||||||
cc_features->used_textures[1] = false;
|
ccf->color_alpha_same[1] = 1;
|
||||||
cc_features->num_inputs = 0;
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
for (int32_t j = 0; j < 4; j++) {
|
u8* cmd = &cc->shader_commands[i * 8];
|
||||||
if (cc_features->c[i][j] >= SHADER_INPUT_1 && cc_features->c[i][j] <= SHADER_INPUT_8) {
|
for (int j = 0; j < 4; j++) {
|
||||||
if (cc_features->c[i][j] > cc_features->num_inputs) {
|
if (cmd[j] != cmd[j + 4]) {
|
||||||
cc_features->num_inputs = cc_features->c[i][j];
|
ccf->color_alpha_same[i] = 0;
|
||||||
}
|
break;
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
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(0x04060401, 0x05000000, 0x04060402, 0x05000b0b, 0x00000001); // 1d970841b086b2e6
|
||||||
gfx_pc_precomp_shader(0x01000000, 0x04000000, 0x02000000, 0x04000b0b, 0x00000001); // 410000008f86b2e6
|
gfx_pc_precomp_shader(0x01000000, 0x04000000, 0x02000000, 0x04000b0b, 0x00000001); // 410000008f86b2e6
|
||||||
|
|
||||||
|
|
||||||
sAllowCCPrint = 1;
|
sAllowCCPrint = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -48,17 +48,12 @@ enum {
|
||||||
#define SHADER_OPT_NOISE (1 << 27)
|
#define SHADER_OPT_NOISE (1 << 27)
|
||||||
|
|
||||||
struct CCFeatures {
|
struct CCFeatures {
|
||||||
uint8_t c[2][4];
|
|
||||||
bool opt_alpha;
|
|
||||||
bool opt_fog;
|
|
||||||
bool opt_texture_edge;
|
|
||||||
bool opt_noise;
|
|
||||||
bool used_textures[2];
|
bool used_textures[2];
|
||||||
int num_inputs;
|
int num_inputs;
|
||||||
bool do_single[2];
|
bool do_single[4];
|
||||||
bool do_multiply[2];
|
bool do_multiply[4];
|
||||||
bool do_mix[2];
|
bool do_mix[4];
|
||||||
bool color_alpha_same;
|
bool color_alpha_same[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
@ -107,9 +102,11 @@ struct ColorCombiner {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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_print(struct ColorCombiner *cc);
|
||||||
void gfx_cc_precomp(void);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
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_alpha = cc->cm.use_alpha;
|
||||||
bool opt_fog = cc->cm.use_fog;
|
bool opt_fog = cc->cm.use_fog;
|
||||||
bool opt_texture_edge = cc->cm.texture_edge;
|
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;
|
bool opt_noise = cc->cm.use_noise;
|
||||||
#endif
|
#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 vs_buf[1024];
|
||||||
char fs_buf[2048];
|
char fs_buf[2048];
|
||||||
size_t vs_len = 0;
|
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");
|
append_line(vs_buf, &vs_len, "#version 120");
|
||||||
#endif
|
#endif
|
||||||
append_line(vs_buf, &vs_len, "attribute vec4 aVtxPos;");
|
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, "attribute vec2 aTexCoord;");
|
||||||
append_line(vs_buf, &vs_len, "varying vec2 vTexCoord;");
|
append_line(vs_buf, &vs_len, "varying vec2 vTexCoord;");
|
||||||
num_floats += 2;
|
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;");
|
append_line(vs_buf, &vs_len, "varying vec2 vLightMap;");
|
||||||
num_floats += 2;
|
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, "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);
|
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;
|
num_floats += opt_alpha ? 4 : 3;
|
||||||
}
|
}
|
||||||
append_line(vs_buf, &vs_len, "void main() {");
|
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;");
|
append_line(vs_buf, &vs_len, "vTexCoord = aTexCoord;");
|
||||||
}
|
}
|
||||||
if (opt_fog) {
|
if (opt_fog) {
|
||||||
|
@ -326,7 +295,7 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
|
||||||
if (opt_light_map) {
|
if (opt_light_map) {
|
||||||
append_line(vs_buf, &vs_len, "vLightMap = aLightMap;");
|
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);
|
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;");
|
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");
|
append_line(fs_buf, &fs_len, "#version 120");
|
||||||
#endif
|
#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;");
|
append_line(fs_buf, &fs_len, "varying vec2 vTexCoord;");
|
||||||
}
|
}
|
||||||
if (opt_fog) {
|
if (opt_fog) {
|
||||||
|
@ -349,15 +318,15 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
|
||||||
if (opt_light_map) {
|
if (opt_light_map) {
|
||||||
append_line(fs_buf, &fs_len, "varying vec2 vLightMap;");
|
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);
|
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 sampler2D uTex0;");
|
||||||
append_line(fs_buf, &fs_len, "uniform vec2 uTex0Size;");
|
append_line(fs_buf, &fs_len, "uniform vec2 uTex0Size;");
|
||||||
append_line(fs_buf, &fs_len, "uniform bool uTex0Filter;");
|
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 sampler2D uTex1;");
|
||||||
append_line(fs_buf, &fs_len, "uniform vec2 uTex1Size;");
|
append_line(fs_buf, &fs_len, "uniform vec2 uTex1Size;");
|
||||||
append_line(fs_buf, &fs_len, "uniform bool uTex1Filter;");
|
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
|
// Original author: ArthurCarvalho
|
||||||
// Slightly modified GLSL implementation by twinaphex, mupen64plus-libretro project.
|
// 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) {
|
if (configFiltering == 2) {
|
||||||
append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) texture2D(tex, texCoord - (off)/texSize)");
|
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) {");
|
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() {");
|
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);");
|
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) {
|
if (cc->cm.light_map) {
|
||||||
append_line(fs_buf, &fs_len, "vec4 texVal1 = sampleTex(uTex1, vLightMap, uTex1Size, uTex1Filter);");
|
append_line(fs_buf, &fs_len, "vec4 texVal1 = sampleTex(uTex1, vLightMap, uTex1Size, uTex1Filter);");
|
||||||
} else {
|
} 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 = ");
|
append_str(fs_buf, &fs_len, (opt_alpha) ? "vec4 texel = " : "vec3 texel = ");
|
||||||
for (int i = 0; i < (opt_2cycle + 1); i++) {
|
for (int i = 0; i < (opt_2cycle + 1); i++) {
|
||||||
u8* cmd = &cc->shader_commands[i * 8];
|
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_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_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, ")");
|
append_str(fs_buf, &fs_len, ")");
|
||||||
} else {
|
} 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, ";");
|
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;
|
prg->attrib_sizes[cnt] = 4;
|
||||||
++cnt;
|
++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_locations[cnt] = glGetAttribLocation(shader_program, "aTexCoord");
|
||||||
prg->attrib_sizes[cnt] = 2;
|
prg->attrib_sizes[cnt] = 2;
|
||||||
++cnt;
|
++cnt;
|
||||||
|
@ -527,7 +496,7 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC
|
||||||
++cnt;
|
++cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < num_inputs; i++) {
|
for (int i = 0; i < ccf.num_inputs; i++) {
|
||||||
char name[16];
|
char name[16];
|
||||||
sprintf(name, "aInput%d", i + 1);
|
sprintf(name, "aInput%d", i + 1);
|
||||||
prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, name);
|
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->hash = cc->hash;
|
||||||
prg->opengl_program_id = shader_program;
|
prg->opengl_program_id = shader_program;
|
||||||
prg->num_inputs = num_inputs;
|
prg->num_inputs = ccf.num_inputs;
|
||||||
prg->used_textures[0] = used_textures[0];
|
prg->used_textures[0] = ccf.used_textures[0];
|
||||||
prg->used_textures[1] = used_textures[1];
|
prg->used_textures[1] = ccf.used_textures[1];
|
||||||
prg->num_floats = num_floats;
|
prg->num_floats = num_floats;
|
||||||
prg->num_attribs = cnt;
|
prg->num_attribs = cnt;
|
||||||
|
|
||||||
gfx_opengl_load_shader(prg);
|
gfx_opengl_load_shader(prg);
|
||||||
|
|
||||||
if (used_textures[0]) {
|
if (ccf.used_textures[0]) {
|
||||||
GLint sampler_location = glGetUniformLocation(shader_program, "uTex0");
|
GLint sampler_location = glGetUniformLocation(shader_program, "uTex0");
|
||||||
prg->uniform_locations[0] = glGetUniformLocation(shader_program, "uTex0Size");
|
prg->uniform_locations[0] = glGetUniformLocation(shader_program, "uTex0Size");
|
||||||
prg->uniform_locations[1] = glGetUniformLocation(shader_program, "uTex0Filter");
|
prg->uniform_locations[1] = glGetUniformLocation(shader_program, "uTex0Filter");
|
||||||
glUniform1i(sampler_location, 0);
|
glUniform1i(sampler_location, 0);
|
||||||
}
|
}
|
||||||
if (used_textures[1]) {
|
if (ccf.used_textures[1]) {
|
||||||
GLint sampler_location = glGetUniformLocation(shader_program, "uTex1");
|
GLint sampler_location = glGetUniformLocation(shader_program, "uTex1");
|
||||||
prg->uniform_locations[2] = glGetUniformLocation(shader_program, "uTex1Size");
|
prg->uniform_locations[2] = glGetUniformLocation(shader_program, "uTex1Size");
|
||||||
prg->uniform_locations[3] = glGetUniformLocation(shader_program, "uTex1Filter");
|
prg->uniform_locations[3] = glGetUniformLocation(shader_program, "uTex1Filter");
|
||||||
|
|
|
@ -49,8 +49,9 @@ enum MixType {
|
||||||
|
|
||||||
struct ShaderProgram {
|
struct ShaderProgram {
|
||||||
bool enabled;
|
bool enabled;
|
||||||
uint32_t shader_id;
|
uint64_t hash;
|
||||||
struct CCFeatures cc;
|
struct ColorCombiner cc;
|
||||||
|
struct CCFeatures ccf;
|
||||||
enum MixType mix;
|
enum MixType mix;
|
||||||
bool texture_used[2];
|
bool texture_used[2];
|
||||||
int texture_ord[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) {
|
static inline GLenum texenv_set_texture_color(struct ShaderProgram *prg) {
|
||||||
GLenum mode;
|
|
||||||
|
|
||||||
// HACK: lord forgive me for this, but this is easier
|
// HACK: lord forgive me for this, but this is easier
|
||||||
|
if (prg->cc.cm.rgb1 == color_comb_rgb(G_CCMUX_TEXEL0, G_CCMUX_SHADE, G_CCMUX_TEXEL0_ALPHA, G_CCMUX_SHADE, 0)) {
|
||||||
switch (prg->shader_id) {
|
return GL_DECAL;
|
||||||
case 0x0000038D: // mario's eyes
|
} else {
|
||||||
case 0x01045A00: // peach letter
|
return GL_MODULATE;
|
||||||
case 0x01200A00: // intro copyright fade in
|
|
||||||
mode = GL_DECAL;
|
|
||||||
break;
|
|
||||||
case 0x00000551: // goddard
|
|
||||||
mode = GL_BLEND;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
mode = GL_MODULATE;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline GLenum texenv_set_texture_texture(UNUSED struct ShaderProgram *prg) {
|
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);
|
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
|
// blend it on top of normal tris later
|
||||||
cur_fog_ofs = ofs;
|
cur_fog_ofs = ofs;
|
||||||
ofs += 4;
|
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)
|
// 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
|
// 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
|
// 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);
|
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
|
// HACK: when two textures are mixed by vertex color, store the color
|
||||||
// it will be used later when rendering two texture passes
|
// it will be used later when rendering two texture passes
|
||||||
c_mix[0] = *(ofs + hack + 0);
|
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
|
// we only need to do this once
|
||||||
prg->enabled = true;
|
prg->enabled = true;
|
||||||
|
|
||||||
if (prg->shader_id & SHADER_OPT_TEXTURE_EDGE) {
|
if (prg->cc.cm.texture_edge) {
|
||||||
// (horrible) alpha discard
|
// (horrible) alpha discard
|
||||||
glEnable(GL_ALPHA_TEST);
|
glEnable(GL_ALPHA_TEST);
|
||||||
glAlphaFunc(GL_GREATER, 0.666f);
|
glAlphaFunc(GL_GREATER, 0.666f);
|
||||||
|
@ -258,14 +246,15 @@ static void gfx_opengl_load_shader(struct ShaderProgram *new_prg) {
|
||||||
cur_shader->enabled = false;
|
cur_shader->enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(uint32_t shader_id) {
|
static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorCombiner* cc) {
|
||||||
struct CCFeatures ccf;
|
|
||||||
gfx_cc_get_features(shader_id, &ccf);
|
|
||||||
|
|
||||||
struct ShaderProgram *prg = &shader_program_pool[shader_program_pool_size++];
|
struct ShaderProgram *prg = &shader_program_pool[shader_program_pool_size++];
|
||||||
|
|
||||||
prg->shader_id = shader_id;
|
struct CCFeatures ccf = { 0 };
|
||||||
prg->cc = ccf;
|
gfx_cc_get_features(cc, &ccf);
|
||||||
|
|
||||||
|
prg->hash = cc->hash;
|
||||||
|
prg->cc = *cc;
|
||||||
|
prg->ccf = ccf;
|
||||||
prg->num_inputs = ccf.num_inputs;
|
prg->num_inputs = ccf.num_inputs;
|
||||||
prg->texture_used[0] = ccf.used_textures[0];
|
prg->texture_used[0] = ccf.used_textures[0];
|
||||||
prg->texture_used[1] = ccf.used_textures[1];
|
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;
|
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++)
|
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 &shader_program_pool[i];
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
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) {
|
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);
|
//printf(">>> combine: %08x %08x %08x %08x\n", rgb1, alpha1, rgb2, alpha2);
|
||||||
memset(&rdp.combine_mode, 0, sizeof(struct CombineMode));
|
memset(&rdp.combine_mode, 0, sizeof(struct CombineMode));
|
||||||
|
|
Loading…
Reference in a new issue