mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-01-03 14:11:10 +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 = {
|
||||
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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in a new issue